Anexa - Plug and Play

32
Anexa - Plug and Play Cuprins 1 Noţiuni teoretice 2 Plug and Play în Linux 2.1 Linux Device Model 2.1.1 Sysfs 2.1.2 Structuri de bază în modelul de dispozitiv Linux 2.1.2.1 Structura kobject 2.1.2.2 Magistrale 2.1.2.3 Dispozitive 2.1.2.4 Drivere 2.1.2.5 Clase 2.2 Hotplug 2.3 Linux Device Model în kernel 2.3.1 Magistrala PNP 2.4 Operaţii plug and play 2.4.1 Adăugarea unui driver 2.4.2 Eliminarea unui driver 2.4.3 Adăugarea unui dispozitiv 2.4.4 Eliminarea unui dispozitiv 3 Plug and Play în Windows 3.1 Windows Driver Model (WDM) 3.2 Funcţionarea unui driver plug and play şi stările unui dispozitiv 3.3 Iniţializarea driver-ului (DriverEntry) 3.4 Iniţializarea dispozitivului (AddDevice) 3.5 Funcţie de dispatch pentru drivere WDM (IRP_MJ_PNP) 3.5.1 Transmiterea cererilor plug and play în stiva de dispozitive 3.5.2 Pornirea dispozitivului (IRP_MN_START_DEVICE) 3.5.3 Oprirea dispozitivului (IRP_MN_STOP_DEVICE) 3.5.4 Eliminarea dispozitivului (IRP_MN_REMOVE_DEVICE) 4 Quiz 5 Exerciţii 5.1 Linux 5.2 Windows 5.2.1 Pentru acasă 5.3 Soluţii 6 Resurse utile 6.1 Linux 6.2 Windows 7 Note Noţiuni teoretice Plug and Play este o tehnologie care oferă suport pentru adăugarea şi eliminarea automată a dispozitivelor în sistem. În acest mod se reduc conflictele legate de resursele folosite de acestea prin configurare automată la pornirea sistemului. Pentru a îndeplini aceste scopuri, sunt necesare următoarele caracteristici: Anexa - Plug and Play 1

description

Tutorial Utilizare Plug and Play Sistem

Transcript of Anexa - Plug and Play

  • Anexa - Plug and PlayCuprins

    1 Noiuni teoretice 2 Plug and Play n Linux

    2.1 Linux Device Model2.1.1 Sysfs 2.1.2 Structuri de baz n modelul de dispozitiv Linux

    2.1.2.1 Structura kobject 2.1.2.2 Magistrale 2.1.2.3 Dispozitive 2.1.2.4 Drivere 2.1.2.5 Clase

    2.2 Hotplug 2.3 Linux Device Model n kernel

    2.3.1 Magistrala PNP

    2.4 Operaii plug and play2.4.1 Adugarea unui driver 2.4.2 Eliminarea unui driver 2.4.3 Adugarea unui dispozitiv 2.4.4 Eliminarea unui dispozitiv

    3 Plug and Play n Windows3.1 Windows Driver Model (WDM) 3.2 Funcionarea unui driver plug and play i strile unui dispozitiv 3.3 Iniializarea driver-ului (DriverEntry) 3.4 Iniializarea dispozitivului (AddDevice) 3.5 Funcie de dispatch pentru drivere WDM (IRP_MJ_PNP)

    3.5.1 Transmiterea cererilor plug and play n stiva de dispozitive 3.5.2 Pornirea dispozitivului (IRP_MN_START_DEVICE) 3.5.3 Oprirea dispozitivului (IRP_MN_STOP_DEVICE) 3.5.4 Eliminarea dispozitivului (IRP_MN_REMOVE_DEVICE)

    4 Quiz 5 Exerciii

    5.1 Linux 5.2 Windows

    5.2.1 Pentru acas

    5.3 Soluii

    6 Resurse utile6.1 Linux 6.2 Windows

    7 Note

    Noiuni teoreticePlug and Play este o tehnologie care ofer suport pentru adugarea i eliminarea automat a dispozitivelor nsistem. n acest mod se reduc conflictele legate de resursele folosite de acestea prin configurare automat lapornirea sistemului. Pentru a ndeplini aceste scopuri, sunt necesare urmtoarele caracteristici:

    Anexa - Plug and Play 1

  • detectarea automat a adaugrii i eliminrii dispozitivelor din sistem (dispozitivul i magistralaacestuia trebuie sa anune driver-ul corespunztor c a aprut o modificare n configuraie)

    managementul resurselor (adrese, linii irq, canale DMA, zone de memorie), ce include alocarearesurselor ctre dispozitive i rezolvarea conflictelor ce pot aprea

    dispozitivele trebuie s permit configurarea software (resursele dispozitivului porturi, ntreruperi,resurse DMA trebuie s permit atribuirea din partea driver-ului)

    driver-ele necesare pentru dispozitive noi trebuie s fie ncarcate automat de sistemul de operareatunci cnd este nevoie

    atunci cnd dispozitivul i magistrala acestuia permit, sistemul ar trebui s poat aduga sau eliminadispozitivul din sistem n timp ce acesta ruleaz, fr a fi necesar repornirea sistemului (hotplug).

    Pentru ca un sistem s suporte plug and play trebuie ca BIOS-ul, sistemul de operare i dispozitivul s suporteaceast tehnologie. Dispozitivul trebuie s dein un ID pe care s l ofere driver-ului pentru identificare, iarsistemul de operare trebuie s poat s identifice aceste modificri n configuraie pe msur ce ele apar.

    Dispozitive care suport plug and play sunt: dispozitivele PCI (plci de reea), USB (tastatur, mouse,imprimant), FireWire, etc.

    Plug and Play n LinuxSistemul de operare Linux nu a fost de la nceput un sistem plug and play, dar n prezent aceste probleme aufost rezolvate. La pornirea sistemului, BIOS-ul realizeaz plug and play i configureaz dispozitivele dinsistem. Linux, la pornire poate reconfigura aceste setri sau le poate accepta.

    n Linux fiecare driver realizeaz propria configurare a dispozitivelor. Aceasta era un lucru dificil, dar acums-au pus la dispoziia driverelor mecanisme din kernel pentru a realiza mare parte din aceste operaii. Deci,ntr-un fel, si acum tot driverele realizeaz configurarea dispozitivelor, numai c realizeaz acest lucru prininstruirea kernel-ului asupra operaiilor pe care trebuie s le execute.

    Tehnologia plug and play n Linux se bazeaz n principal pe Linux Device Model, care include sistemul defiiere sysfs i hotplug, alturi de mecanisme din user-mode, cum ar fi udev.

    Linux Device Model

    nainte de versiunea 2.6, kernel-ul nu dispunea de un model unificat prin care s se obin informaii despreacesta. Din acest motiv s-a realizat un model pentru dispozitivele din Linux, Linux Device Model.

    Scopul principal al acestui modelul este de a menine structuri de date interne care s reflecte starea istructura sistemului. Astfel de infomaii includ ce dispozitive exist n sistem, n ce stare se afl din punct devedere al managementului consumului (power management), la ce magistral sunt ataate, ce drivere auasociate, alturi de structura magistralelor, dispozitivelor, driverelor din sistem.

    Pentru a menine aceste informaii, kernel-ul folosete urmtoarele entiti:

    dispozitiv - un dispozitiv fizic care este ataat unei magistrale driver o entitate software care poate fi asociat unui dispozitiv si execut operaii cu acesta magistral (bus) un dispozitiv la care se pot ataa alte dispozitive

    Noiuni teoretice 2

  • clas un tip de dispozitive care au o comportare similar; exist o clas pentru discuri, partiii, porturiseriale, etc.

    subsistem o vedere asupra structurii sistemului; subsistemele din kernel includ dispozitive(devices - o vedere ierarhic asupra tuturor dispozitivelor din sistem), magistrale (bus - o vedere adispozitivelor n funcie de cum sunt ataate la magistrale), clase, etc.

    Sysfs

    Kernel-ul ofer o reprezentare a modelului su n userspace prin intermediul sistemului virtual de fiiere sysfs.Acesta este de obicei montat n directorul /sys i conine urmtoarele subdirectoare:

    block - toate dispozitivele de tip bloc disponibile n sistem (discuri, partiii) bus - tipuri de magistrale la care se conecteaz dispozitivele fizice (pci, ide, usb) class - clase de drivere care sunt disponibile n sistem (net, sound, usb) devices - structura ierarhica a dispozitivelor conectate n sistem firmware - informaii obinute de la firmware-ul sistemului (ACPI) fs - informaii legate de sistemele de fiiere montate kernel - informaii legate de starea kernel-ului (utilizatorii logai, hotplug) module - lista modulelor ncarcate la momentul curent power - informaii legate de subsistemul de power management

    Dup cum se poate observa, exist o coresponden ntre structurile de date din kernel n cadrul modeluluidescris i subdirectoarele din sistemul virtual de fiiere sysfs. Dei aceast asemnare poate duce laconfundarea celor dou concepte, ele sunt diferite. Modelul pentru dispozitive n kernel poate funciona i farasistemul de fiiere sysfs, dar reciproca nu este adevrat.

    Informaia din sysfs se gsete in fiiere ce conin cte un atribut. Cteva atribute standard (reprezentate defiiere sau directoare cu acelai nume) sunt urmtoarele:

    dev - identificatorul major i minor al dispozitivului; acesta poate fi folosit pentru a crea automatintrrile n directorul /dev

    device - o legtur simbolic spre directorul ce conine dispozitive; acesta poate fi folosit pentru adescoperi dispozitivele hardware care ofer un anumit serviciu (spre exemplu dispozitivul PCI alplcii de reea eth0)

    driver - o legtur simbolic spre directorul ce conine drivere (care se afl n/sys/bus/*/drivers)

    Sunt disponibile i alte atribute, n funcie de magistrala i driverul folosit.

    Linux Device Model 3

  • Structuri de baz n modelul de dispozitiv Linux

    Linux Device Model ofer o serie de structuri care s asigure interaciunea ntre un dispozitiv hardware i undevice driver. ntreg modelul are la baz structuri struct kobject. Cu ajutorul acestei structuri suntconstruite ierarhii i sunt implementate urmtoarele structuri: struct bus_type, struct device istruct device_driver.

    Structura kobject

    O structur kobject nu ndeplinete o funcie de una singur. O astfel de structur este de obicei integratntr-o structur mai mare. O structur kobject incorporeaz de fapt un set de faciliti care vor fi oferiteunui obiect de nivel de abstracie mai nalt n ierarhia Linux Device Model.

    Spre exemplu, structura cdev are urmtoarea definiie:

    Sysfs 4

  • struct cdev {struct kobject kobj;struct module *owner;const struct file_operations *ops;struct list_head list;

    dev_t dev;unsigned int count;

    };

    Se observ c aceast structur include un cmp de tipul struct kobject.

    O structur struct kobject este definit astfel:

    struct kobject {const char * k_name;struct kref kref;struct list_head entry;struct kobject * parent;struct kset * kset;struct kobj_type * ktype;struct sysfs_dirent * sd;

    };

    Dup cum se observ, structurile kobject sunt ntr-o ierarhie: un obiect are un printe i deine un membrukset, care cuprinde obiecte de pe acelai nivel.

    Lucrul cu structura presupune iniializarea ei, cu ajutorul funciei kobject_init. Tot n procesul deiniializare este necesar stabilirea numelui structurii kobject, care va aprea n sysfs, cu ajutorul funcieikobject_set_name.

    Orice operaie asupra unui kobject se realizeaz prin incrementarea contorului intern al acestuia cukobject_get, sau decrementarea n cazul n care nu se mai folosete cu kobject_put. Astfel, un obiectde tip kobject nu va fi eliberat dect n momentul n care contorul intern al acestuia ajunge la valoarea 0.Este nevoie de o metod de notificare a acestui lucru, pentru ca, apoi, s fie eliberate resursele asociatestructurii de dispozitiv care includea struct kobject (spre exemplu struct cdev). Metoda senumete release i este asociat obiectului prin intermediul cmpului ktype (de tip struct kobj_type).

    Structura struct kobject este structura de baz din Linux Device Model. Structurile din nivelurile mainalte ale modelului sunt struct bus_type, struct device i struct device_driver.

    Magistrale

    O magistral este un canal de comunicaie ntre procesor i un dispozitiv de intrare/ieire. Pentru asigurareagenericitii modelului, toate dispozitivele de intrare/ieire sunt conectate la procesor prin intermediul uneiastfel de magistrale (chiar dac aceasta poate fi una virtual fr un corespondent fizic hardware).

    La adugarea unei magistrale n sistem, aceasta va aprea n sistemul de fiiere sysfs, n /sys/bus. Ca ila structurile kobjects, magistralele pot fi organizate n ierarhii i vor fi reprezentate astfel i n sysfs.

    n Linux Device Model, o magistral este reprezentat de structura struct bus_type:

    struct bus_type {

    Structura kobject 5

  • const char * name;struct module * owner;

    struct kset subsys;struct kset drivers;struct kset devices;struct klist klist_devices;struct klist klist_drivers;//...int (*match)(struct device * dev, struct device_driver * drv);int (*uevent)(struct device *dev, struct kobj_uevent_env *env);int (*probe)(struct device * dev);int (*remove)(struct device * dev);//...

    };

    Se observ c unei magistrale i este asociat un nume, o list de drivere, o list de dispozitive i o serie defuncii specifice. Funcia uevent (fost hotplug), este folosit n cazul dispozitivelor hotplug.

    Operaiile cu magistrala sunt operaii de nregistrare, implementarea operaiilor descrise n structura structbus_type i operaii de parcurgere i inspecie a dispozitivelor conectate la magistral.

    nregistrarea unei magistrale se realizeaz folosind bus_register, iar denregistrarea folosind bus_unregister:

    #include /* mybus.c */

    //bus typestruct bus_type my_bus_type = { .name= "mybus", .match= my_match, .uevent= my_uevent,};

    static int __init my_bus_init (void){int err;

    //... err = bus_register (&my_bus_type);if (err)return err;//...}

    static void __exit my_bus_exit (void){//... bus_unregister (&my_bus_type);//...}

    Funciile care vor fi iniializate uzual n cadrul unei structuri struct bus_type sunt match i uevent:

    #include #include /* mybus.c */

    Magistrale 6

  • // match devices to drivers; just do a simple name test static int my_match (struct device *dev, struct device_driver *driver){return !strncmp (dev->bus_id, driver->name, strlen (driver->name));}

    // respond to hotplug user events; add environment variable BUS_IDstatic int my_uevent (struct device *dev, struct kobj_uevent_env *env)

    { add_uevent_var(env, "BUS_ID=%s", dev->bus_id);return 0;}

    Funcia match este utilizat n momentul n care se adaug la magistral un nou dispozitiv sau un nou driver.Rolul ei este de a realiza comparaia ntre identificatorul dispozitivului i cel al driverului. Funcia ueventeste apelat nainte de generarea unui eveniment de tip hotplug n user-space i are drept rol adugarea devariabile de mediu.

    Alte operaii posibile n cazul unei magistrale sunt parcurgerea driverelor sau dispozitivelor ataate acesteia cuajutorul macrodefiniiilor bus_for_each_dev i bus_for_each_drv.

    Interfaa Linux Device Model permite crearea de atribute pentru obiectele asociate. Aceste atribute vor aveadrept corespondent un fiier n subdirectorul magistralei din sysfs. Atributele asociate unei magistrale suntdescrise de structura bus_attribute:

    struct bus_attribute {struct attribute attr;

    ssize_t (*show)(struct bus_type *, char * buf); ssize_t (*store)(struct bus_type *, const char * buf, size_t count);};

    De obicei, un atribut se definete cu ajutorul macrodefiniiei BUS_ATTR. Pentru adugarea/tergerea unuiatribut din cadrul structurii de magistral se folosesc funciile bus_create_file i bus_remove_file.

    Un exemplu de definire a unui atribut pentru magistrala my_bus este prezentat n continuare:

    /* mybus.c */

    #define MY_BUS_DESCR "PSO rules forever"

    // export a simple bus attributestatic ssize_t my_show_bus_descr (struct bus_type *bus, char *buf){

    return snprintf (buf, PAGE_SIZE, "%s\n", MY_BUS_DESCR);}

    /* * define attribute - attribute name is descr; * full name is bus_attr_descr; * sysfs entry should be /sys/bus/mybus/descr */BUS_ATTR (descr, 0444, my_show_bus_descr , NULL);

    // specify attribute - in module init functionstatic int __init my_bus_init (void){

    int err;

    Magistrale 7

  • //... err = bus_create_file (&my_bus_type, &bus_attr_descr);

    if(err) {/* handle error */

    }//...

    }

    static void __exit my_bus_exit (void){

    //... bus_remove_file (&my_bus_type, &bus_attr_descr);

    //...}

    Magistrala este reprezentat att de un obiect bus_type, ct i de un obiect device, aa cum vom vedea ncontinuare (magistrala este i ea un dispozitiv).

    Dispozitive

    Orice dispozitiv din sistem are asociat o structur struct device. Dispozitivele sunt descoperite prindiferite metode de kernel (hotplug, de ctre device drivere, la iniializarea sistemului) i sunt nregistrate nsistem.

    Toate dispozitivele prezente n kernel au cte o intrare n /sys/devices.

    La cel mai jos nivel, un dispozitiv n Linux Device Model este reprezentat de o structur struct device:struct device {

    //...struct device * parent;

    struct kobject kobj;char bus_id[BUS_ID_SIZE]; /* position on parent bus *///...struct bus_type * bus; /* type of bus device is on */struct device_driver *driver; /* which driver has allocated this

    device */void *driver_data; /* data private to the driver *///...void (*release)(struct device * dev);

    };

    Printre cmpurile structurii se numr dispozitivul printe care este de obicei un controller, obiectulkobject asociat, un identificator unic care l identific n cadrul magistralei, magistrala pe care se gsete,driverul care se ocup de dispozitiv i o funcie apelat n momentul n care contorul dispozitivului ajunge la0.

    Ca de obicei, avem funcii de nregistrare/denregistrare device_register i device_unregister .

    Pentru lucrul cu atributele avem structura struct device_attribute, macrodefiniia DEVICE_ATTRpentru definire i funciile device_create_file i device_remove_file pentru adugareaatributului la dispozitiv.

    Dispozitive 8

  • Un lucru important de notat este faptul c, de obicei, nu se lucreaz direct cu o structur de tip structdevice, ci cu o structur care o conine pe aceasta, de forma:

    // my device typestruct my_device {char *name;struct my_driver *driver;struct device dev;};

    De obicei, un modul va exporta funcii de nregistrare/denregistrare ale unui astfel de dispozitiv, dupmodelul prezentat mai jos:/* mybus.c */

    /* BUS DEVICE (parent) */

    // parent device releasestatic void my_bus_device_release (struct device *dev){}

    // parent devicestatic struct device my_bus_device = { .bus_id = "mybus0", .release = my_bus_device_release};

    /* DEVICE */

    /* * as we are not using the reference count, we use a no-op * release function */static void my_dev_release (struct device *dev){}

    int my_register_device (struct my_device *mydev){ mydev->dev.bus = &my_bus_type; mydev->dev.parent = &my_bus_device; mydev->dev.release = my_dev_release;strncpy(mydev->dev.bus_id, mydev->name, BUS_ID_SIZE);

    return device_register (&mydev->dev);}

    void my_unregister_device (struct my_device * mydev){ device_unregister (&mydev->dev);}

    /* export register/unregister device functions */EXPORT_SYMBOL (my_register_device);EXPORT_SYMBOL (my_unregister_device);

    Dup cum se poate observa, funciile my_register_device i my_unregister_device deadugare, respectiv scoatere a unui device de pe o magistral sunt definite n fiierul n care este definitmagistrala. Nu se iniializeaz obiecte de tip dispozitiv; acestea se vor inializa n momentul n care vor fi

    Dispozitive 9

  • descoperite n sistem (prin hotplug sau nregistrare direct din driver) i se va apela funciamy_register_device pentru adugarea la magistral.

    Pentru utilizare (n implementarea driver-ului), trebuie declarat o structur de tipul celei exportate,iniializat i nregistrat cu metoda exportata de magistral:

    /* mydriver.c */

    static struct my_device mydev;char devname[20];//...

    //registerint err;

    sprintf(devname, "mydev0");mydev.name = devname;mydev.driver = &mydriver;mydev.dev.driver_data = &mydev;err = my_register_device(&mydev);if (err < 0) {/*handle error */}

    //..

    //unregistermy_unregister_device(&mydev);

    Drivere

    Linux Device Model este folosit pentru a permite asocierea foarte uoar ntre dispozitivele sistemului idrivere. Driverele pot exporta informaii independente de dispozitivul fizic din spate.

    n sysfs informaiile despre drivere nu au asociate un singur subdirector; ele se pot gsi n structura dedirectoare, n diferite locuri: n /sys/module se gsete modulul ncrcat, n devices se poate gsidriverul asociat fiecrui device, n classes driverele care aparin unei clase, n /sys/bus drivereleasociate fiecrei magistrale.

    Un device driver este identificat prin structura struct device_driver:

    struct device_driver {const char * name;struct bus_type * bus;

    struct kobject kobj;struct klist klist_devices;struct klist_node knode_bus;

    struct module * owner;const char * mod_name; /* used for built-in modules */struct module_kobject * mkobj;

    int (*probe) (struct device * dev);int (*remove) (struct device * dev);void (*shutdown) (struct device * dev);int (*suspend) (struct device * dev, pm_message_t state);

    Drivere 10

  • int (*resume) (struct device * dev);};

    Printre cmpurile structurii regsim numele driver-ului (apare n sysfs), magistrala cu care driverullucreaz, obiectul asociat, lista de dispozitive controlate de driver, funcii apelate n diverse momente dinfuncionarea unui dispozitiv.

    Ca i pn acum, avem funciile de nregistrare/denregistrare driver_register idriver_unregister.

    Pentru lucrul cu atributele avem structura struct driver _attribute, macrodefiniiaDRIVER_ATTR pentru definire i funciile driver_create_file i driver_remove_file pentruadugarea atributului la dispozitiv.

    Ca i n cazul dispozitivelor, structura struct device_driver este, de obicei, incorporat n cadrul uneialte structuri specifice unei anumite magistrale (PCI, USB, etc.):

    /* mybus.c */

    // my driver typestruct my_driver {

    struct module *module;struct device_driver driver;};

    #define to_my_driver(drv) container_of(drv, struct my_driver, driver);

    int my_register_driver (struct my_driver *driver){int err;

    driver->driver.bus = &my_bus_type; err= driver_register (&driver->driver);if (err)return err;return 0;}

    void my_unregister_driver (struct my_driver *driver){ driver_unregister (&driver->driver);}

    /* export register/unregister driver functions */EXPORT_SYMBOL (my_register_driver);EXPORT_SYMBOL (my_unregister_driver);

    Se observ c se export operaiile de nregistrare/denregistrare de driver pentru folosire n cadrul altormodule.

    Ca i n cazul dispozitivelor, i operaiile cu drivere sunt definite la iniializarea magistralei, i sunt exportatepentru a putea fi folosite de drivere. n momentul n care se implementeaz un driver ce lucreaz cudispozitive ataate la aceast magistral, acesta va apela funciile my_register_driver imy_unregister_driver pentru a se asocia cu aceasta.

    Pentru utilizare (n implementarea driver-ului), trebuie declarat o structur de tipul celei exportate,

    Drivere 11

  • iniializat i nregistrat cu metoda exportata de magistral:

    /* mydriver.c */

    static struct my_driver mydriver = { .module = THIS_MODULE, .driver = { .name = "mydriver",},};//...

    //registerint err;err = my_register_driver(&mydriver);if (err < 0) {/*handle error */}//..

    //unregistermy_unregister_driver(&mydriver);

    Clase

    O clas este o vedere de nivel nalt asupra Linux Device Model, care abstractizeaz detaliile de implementare.Spre exemplu, exist drivere pentru discurile SCSI i drivere pentru discurile ATA, dar toate aparin claseidiscuri. Clasele asigur o grupare a dispozitivelor bazat pe funcionalitate, nu pe modul n care sunt conectatesau cum funcioneaz.

    Clasele au corespondent n /sys/classes.

    Exist doua structuri principale care descriu clasele: struct class i struct class_device.Structura class descrie o clasa generic, n timp ce structura struct class_device descrie o clasasociat unui dispozitiv. Exist funcii pentru iniializare/deiniializare i adugare de atribute pentru fiecaredintre acestea, descrise n include/linux/device.h.

    Avantajul folosirii claselor este c programul udev din userspace, despre care vom discuta n continuare,permite crearea automat a dispozitivelor n directorul /dev pe baza informaiilor clasei.

    Din acest motiv, vom prezenta n continuare un set restrns de funcii care lucreaz cu clasele pentru asimplifica folosirea mecanismului de plug and play.

    O clas generic este descris de structura struct class:

    struct class {const char * name;struct module * owner;

    struct kset subsys;struct list_head children;struct list_head devices;struct list_head interfaces;struct kset class_dirs;struct semaphore sem; /* locks both the children and interfaces lists */

    Clase 12

  • struct class_attribute * class_attrs;struct class_device_attribute * class_dev_attrs;struct device_attribute * dev_attrs;

    int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env);int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);

    void (*release)(struct class_device *dev);void (*class_release)(struct class *class);void (*dev_release)(struct device *dev);//...

    };

    Pentru iniializare/deiniializare exist funciile class_register i class_unregister:

    static struct class my_class = { .name = "myclass",};

    static int __init my_init(void){

    int err;//...

    err = class_register(&my_class);if (err < 0) {

    /* handle error */}//...

    }

    static void __exit my_cleanup (void){

    //... class_unregister(&my_class);

    //...}

    O clas asociat unui dispozitiv este descris de structura struct class_device:

    struct class_device {struct list_head node;

    struct kobject kobj;struct class * class; /* required */

    dev_t devt; /* dev_t, creates the sysfs "dev" */struct device * dev; /* not necessary, but nice to have */void * class_data; /* class-specific data */struct class_device *parent; /* parent of this child device, if there is one */struct attribute_group ** groups; /* optional groups */

    void (*release)(struct class_device *dev);int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env);char class_id[BUS_ID_SIZE]; /* unique to this class */

    };

    Pentru iniializare/deiniializare exist funciile class_device_create i class_device destroy.Funcia class_device_create iniializeaz stuctura class_device, i asociaz structura genericclass i dispozitivul primite ca parametru; n plus, va crea un atribut al clasei, dev, care conine minorul i

    Clase 13

  • majorul dispozitivului (minor:major). Astfel, utilitarul udev din usermode poate citi datele necesare dinacest fiier atribut pentru a crea un nod n directorul /dev apelnd makenod.

    Un exemplu de iniializare:

    struct class_device* my_classdev;struct cdev cdev;struct device dev;

    //...

    //init class for device cdev.devmy_classdev = class_device_create(&my_class, NULL, cdev.dev, &dev, "myclass0");

    //...

    //destroy class for device cdev.devclass_device_destroy(&my_class, cdev.dev);

    n momentul n care un nou dispozitiv va fi descoperit, i se va asocia o clas i un nod n directorul /dev.Pentru exemplul de mai sus, se va genera un nod /dev/myclass0.

    Hotplug

    Hotplug descrie mecanismul de adugare sau eliminare a unui dispozitiv din sistem n timp ce acesta ruleaz,fr a fi necesar repornirea sistemului.

    Un eveniment hotplug este o notificare din partea kernel-ului ctre user-space atunci cnd se modific ceva nconfiguraia sistemului. Aceste evenimente sunt generate la crearea sau eliminarea unui obiect kobject dinkernel. ntruct aceste obiecte stau la baza Linux Device Model, fiind incluse n toate structurile (structbus_type, struct device, struct device_driver, struct class, structclass_device, etc.), se va genera un eveniment hotplug la crearea sau eliminarea oricreia dintre acestestructuri

    [uevent].

    n momentul n care un dispozitiv este descoperit n sistem, se genereaz un eveniment. n funcie de punctuln care se afl n Linux Device Model, se vor apela funciile corespunztoare apariiei unui eveniment (deobicei, este cazul funciei uevent a magistralei sau clasei). Driverul are posibilitatea, prin intermediulacestor funcii, s seteze variabile de sistem pentru user-space. Evenimentul generat ajunge n user-space apoi.Aici exist utilitarul udev, care captureaz aceste evenimente. n directorul /etc/udev/ exist fiierele deconfigurare pentru acest utilitar. Se pot specifica diferite reguli pentru a captura numai anumite evenimente ia executa anumite aciuni, n funcie de variabilele de sistem setate din kernel sau n funciile uevent.

    O consecin important este c n acest mod se poate realiza mecanismul plug and play; cu ajutorul lui udevsi a claselor, descrise anterior, se pot crea automat intrrile n directorul /dev pentru dispozitive, iar cuajutorul udev se pot ncrca automat driverele necesare pentru un dispozitiv. n acest fel, ntreg procesul esteautomatizat.

    Regulile pentru udev sunt localizate n /etc/udev/rules.d. Orice fiier de aici care se termin cu.conf va fi parsat la apariia unui eveniment. Pentru mai multe detalii despre cum se scriu regulile n aceste

    Hotplug 14

  • fiiere consultai Writing udev rules. Pentru testare, exist utilitarele udevmonitor, udevinfo iudevtest.

    Pentru un scurt exemplu, sa consideram situaia n care dorim sa ncarcm automat un driver pentru undispozitiv n momentul apariiei unui eveniment. Putem crea un nou fiier/etc/udev/rules.d/myrules.rules, n care vom avea urmtoarea linie:

    SUBSYSTEM=="pnp", ATTRS{id}=="PNP0400", RUN+="/sbin/insmod /root/pso/mydriver.ko"

    Astfel, se vor alege dintre evenimentele generate doar cele care aparin subsistemului pnp (sunt conectate lamagistrala PNP) i au un atribut id cu valoarea PNP0400. n momentul n care se va gsi aceast regul, seva executa comanda ce insereaz driverul corespunztor n kernel.

    Linux Device Model n kernel

    Dup cum s-a specificat mai sus, n Linux Device Model toate dispozitivele sunt conectate printr-o magistral,chiar dac are corespondent fizic hardware sau este virtual.

    n kernel, exist deja implementate majoritatea magistralelor prin definirea unei structuri bus_type i afunciilor de nregistrare/denregistrare a driverelor i dispozitivelor asociate. Pentru implementarea unuidriver trebuie determinat magistrala la care se ataeaz dispozitivele suportate i trebuiesc folosite funciile istructurile acesteia. Principalele magistrale sunt PCI, USB, PNP, IDE, SCSI, platform, ACPI, etc.

    Magistrala PNP

    Mecanismul plug and play ofer un mijloc de detectarea i setare a resurselor pentru drivere legacy sau carenu pot fi configurate n alt mod. Toate driverele plug and play, protocoalele, serviciile au la baz nivelul Plugand Play. Acesta este responsabil cu schimbul de informaie ntre drivere i protocoale. Urmtoareleprotocoale sunt disponibile:

    PNPBIOS, folosite pentru sisteme cum ar fi porturile seriale i paralele ISAPNP, ofer suport pentru magistrala ISA ACPI, care ofer, printre altele, informaii despre dispozitivele la nivel de sistem

    n kernel exist o magistrala pnp_bus, care este folosit pentru conectare de multe drivere. Implementarea imodul de lucru cu aceast magistral respect modelul Linux Device Model i este foarte asemnatoare cu ces-a prezentat pn acum.

    Principalele funcii i structuri exportate de aceast magistral, i care pot fi folosite de ctre drivere sunt:

    pnp_driver, tipul de driver asociat magistralei pnp_register_driver, pentru a nregistra un driver pnp n sistem pnp_unregister_driver, pentru a denregistra un driver pnp din sistem

    Dup cum am observat n seciunile anterioare, magistrala are o funcie match cu ajutorul creai asociazadispozitive cu driverele corespunztoare. Spre exemplu, n cazul descoperirii unui dispozitiv, se va cutadriver-ul care ndeplinete condiia dat de aceast funcie relativ la dispozitiv. De obicei, aceast condiiereprezint o comparaie de id-uri ale driverului i dispozitivului. Un mecanism rspndit este folosirea uneitabele statice n fiecare driver, ce conine informaii despre dispozitivele suportate de driver i vor fi folosite

    Linux Device Model n kernel 15

  • de magistral la comparaie. Spre exemplu, pentru un driver de port paralel vom avea tabelaparport_pc_pnp_tbl:

    static const struct pnp_device_id parport_pc_pnp_tbl[] = {/* Standard LPT Printer Port */{.id = "PNP0400", .driver_data = 0},/* ECP Printer Port */{.id = "PNP0401", .driver_data = 0},{ }

    };

    MODULE_DEVICE_TABLE(pnp,parport_pc_pnp_tbl);

    Se declar i iniializeaz o structur pnp_driver, cum ar fi parport_pc_pnp_driver:

    static int parport_pc_pnp_probe (struct pnp_dev * dev, const struct pnp_id *card_id, const struct pnp_id *dev_id);

    static void parport_pc_pnp_remove(struct pnp_dev * dev);

    static struct pnp_driver parport_pc_pnp_driver = { .name = "parport_pc", .id_table = parport_pc_pnp_tbl, .probe = parport_pc_pnp_probe, .remove = parport_pc_pnp_remove,};

    Dup cum se poate observa, structura are ca parametri un pointer ctre tabela declarat mai sus dou funciicare se apeleaz la detectarea unui dispozitiv, respectiv la eliminarea lui din sistem.

    La fel ca toate structurile prezentate, driver-ul trebuie nregistrat n sistem:

    static int __init parport_pc_init(void){

    //... err = pnp_register_driver (&parport_pc_pnp_driver);

    if (err < 0) {/* handle error */

    }//...

    }

    static void __exit parport_pc_exit(void){

    //... pnp_unregister_driver (&parport_pc_pnp_driver);

    //...}

    Operaii plug and playPn acum am discutat despre modelul Linux Device Model i API-ul folosit. Pentru a implementa un driverplug and play, trebuie respectat modelul Linux Device Model.

    De cele mai multe ori, adugarea unei magistrale n kernel nu este necesar

    [bus]

    Magistrala PNP 16

  • , ntruct deja sunt implementate majoritatea magistralelor (PCI, USB, etc.). Astfel, mai nti trebuieidentificat magistrala la care se ataeaz dispozitivul. n exemplele de mai jos, vom considera c aceastmagistral este magistrala PNP. Astfel, se vor folosi structurile i funciile prezentate mai sus.

    Adugarea unui driver

    Pe lng operaiile uzuale, un driver trebuie s respecte modelul Linux Device Model. Astfel, se va nregistran sistem folosind funciile puse la dispoziie de magistral n acest scop. De obicei, magistrala pune ladispoziie o structur particular de driver, ce conine o structur device_driver, pe care driverul trebuies o iniializeze i s o nregistreze cu o funcie *_register_driver. Spre exemplu, pentru magistralaPNP, driverul trebuie s declare i s iniializeze o structur de tipul pnp_driver, pe care s o nregistrezecu pnp_register_driver:

    static struct pnp_driver my_pnp_driver = { .name = "mydriver", .id_table = my_pnp_tbl, .probe = my_pnp_probe, .remove = my_pnp_remove,};

    static int __init my_init(void){

    //... err = pnp_register_driver (&my_pnp_driver);

    //...}

    Operaii plug and play 17

  • Spre deosebire de driverele legacy, driverele plug and play nu nregistreaz dispozitivele la iniializare, nfuncia my_init

    [register_device].

    Dup cum s-a descris mai sus, fiecare magistral are o funcie match care se apeleaz la detectarea unuidispozitv pentru a determina driverul asociat acestuia. Prin urmare, trebuie s existe o modalitate ca fiecaredriver s exporte informaii despre ce dispozitive suport, pentru a putea trece de aceast comparaie i pentrua fi apelate funciile sale. n exemplele prezentate n laborator, se face o simpl comparaie ntreidentificatorul dispozitivului i numele driver-ului. Cele mai multe drivere folosesc o tabel cu informaiidespre dispozitiv, pentru care au un pointer n structura driver-ului. Spre exemplu, un driver asociat cu omagistral PNP, declar o tabel de tipul pnp_device_id, i iniializeaz cmpul id_table din structurapnp_driver cu un pointer ctre aceasta:

    static const struct pnp_device_id my_pnp_tbl[] = {/* Standard LPT Printer Port */{.id = "PNP0400", .driver_data = 0},/* ECP Printer Port */{.id = "PNP0401", .driver_data = 0},{ }

    };

    MODULE_DEVICE_TABLE(pnp,my_pnp_tbl);

    static struct pnp_driver my_pnp_driver = {//...

    .id_table = my_pnp_tbl,//...

    };

    n exemplul de mai sus driver-ul suport operaii pentru portul paralel. Aceaste informaii sunt folosite demagistral, n funcia match_device.

    La adugarea unui driver, se va asocia driverul magistralei i se vor crea intrri n sysfs bazate pe numeledriver-ului. Apoi se va apela funcia match a magistralei pentru toate dispozitivele asociate, pentru a asociadriver-ul cu orice dispozitiv conectat pe care l suport.

    Eliminarea unui driver

    Pentru a elimina un driver din kernel, pe lng operaiile necesare unui driver legacy, trebuie denregistratstructura device_driver. n cazul unui driver pentru un dispozitiv asociat magistralei PNP, trebuiedenregistrat structura pnp_driver cu ajutorul funciei pnp_unregister_driver:static struct pnp_driver my_pnp_driver;

    static void __exit my_exit(void){

    //... pnp_unregister_driver (&my_pnp_driver);

    //...}

    Adugarea unui driver 18

  • Spre deosebire de driverele legacy, driverele plug and play nu denregistreaz dispozitivele la denregistrareadriver-ului, n funcia my_exit

    [unregister_device].

    La eliminarea unui driver, se vor elimina toate referinele ctre el pentru toate dispozitivele pe care le suporti se vor terge intrrile din sysfs.

    Adugarea unui dispozitiv

    Dupa cum am vzut mai sus, driverele plug and play nu nregistreaz dispozitivele la iniializare. Aceastoperaie se va realiza n funcia probe, care se va apela la detectarea unui dispozitiv. n cazul unui driverpentru un dispozitiv ataat la magistrala PNP, adugarea se va realiza n funcia probe din structurapnp_driver:

    static int my_pnp_probe (struct pnp_dev * dev, const struct pnp_id *card_id, const struct pnp_id *dev_id) {

    int err, iobase, nr_ports, irq;

    if (pnp_irq_valid(dev, 0)) //get irq & ports irq = pnp_irq(dev, 0);

    if (pnp_port_valid(dev, 0)) { iobase = pnp_port_start(dev, 0);

    } elsereturn -ENODEV;

    nr_ports = pnp_port_len(dev, 0);

    /* register device dev */}

    static struct pnp_driver my_pnp_driver = {//...

    .probe = my_pnp_probe,//...

    };

    La detectarea unui dispozitiv n kernel (n procesul de boot sau la adugarea dispozitivului prin hotplug), setransmite o ntrerupere n sistem care ajunge la magistral. Dispozitivul este nregistrat cu ajutorul funcieidevice_register i este ataat magistralei (i se va genera un apel n userspace, care poate fi detectat deudev). Apoi se va parcurge lista de drivere a magistralei i se va apela funcia match pentru fiecare dintreele. Funcia match ncearc s asocieze un driver cu un dispozitiv. Dup ce a fost determinat driverul asociatdispozitivului, se va apela funcia probe a driver-ului. Dac funcia se termin cu succes, dispozitivul esteadugat n lista de dispozitive a driver-ului i se creeaz intrrile corespunztoare n sysfs bazate pe numeledispozitivului.

    Eliminarea unui dispozitiv

    Dupa cum am vzut mai sus, driverele plug and play nu denregistreaz dispozitivele la denregistrareadriver-ului. Aceast operaie se va realiza n funcia remove, care se va apela la detectarea eliminrii unuidispozitiv din kernel. n cazul unui driver pentru un dispozitiv ataat la magistrala PNP, adugarea se varealiza n funcia remove din structura pnp_driver:

    Eliminarea unui driver 19

  • static void my_pnp_remove(struct pnp_dev * dev) {/* unregister device dev */

    }

    static struct pnp_driver my_pnp_driver = {//...

    .remove = my_pnp_remove,};

    Dup cum se poate observa, la detectarea eliminrii unui dispozitiv din sistem, se va apela funcia remove adriver-ului, se va genera un apel n user-space, ce poate fi detectat de udev i se vor elimina intrrile dinsysfs.

    Plug and Play n WindowsSistemul de operare Windows este un sistem plug and play. ncepnd de la Windows 95, modelul pentrudrivere-ele din Windows a suportat plug and play, dar acesta a fost revizuit ncepnd cu Windows 2000. Acestnou model se numete Windows Driver Model.

    Spre deosebire de Linux, n Windows kernel-ul de ocup de configurarea dispozitivelor i n acest sens este cuadevrat un sistem plug and play. Dispozitivele sunt descoperite automat n timpul secvenei de boot sau lainserare (hotplug), determinnd ncrcarea automat a driver-elor corespunztoare.

    n primul rand, aa cum s-a precizat mai sus, tehnologia plug and play se ocup cu descoperirea siconfigurarea automat a dispozitivelor fizice. Spre deosebire de Linux, n Windows se aplic un algoritm derezolvare a conflictelor ce apar la alocarea de resurse (rebalansare) . n modelul anterior din Windows (legacydrivers), era necesar ncarcarea explicit a driver-elor i iniializarea dispozitivelor asociate acestuia lancarcare (n funcia DriverEntry). Folosind plug and play, acest lucru nu mai este necesar, ntructsistemul de operare se ocup de aceste operaii (la detectarea unui dispozitiv se va apela o metod special adriver-ului care va aduga dispozitivul).

    n Windows, implementarea plug and play are mai multe componente software:

    managerul plug and play are o parte n user-mode i o parte n kernel-mode i se ocup cu detectareai configurarea dispozitivelor fizice

    managerul de consum (power manager) se ocup cu managementul consumului (pentru a reduceconsumul de energie al sistemului, anumite dispozitive pot fi eliminate temporar din sistem dac nusunt folosite o perioad lung de timp)

    regitrii (registry) conin o baz de date a componentelor harware i software instalate n sistem isunt folosii la identificarea i localizarea resurselor de ctre dispozitive[registry]

    fiierele .inf (INF file) descriu un dispozitiv, fiind necesar cte un astfel de fiier pentru fiecaredispozitiv la instalarea driver-ului; fiecare pereche dispozitiv/driver trebuie s aib un astfel de fiier[.inf]

    drivere plug and play dei exist drivere care folosesc doar parial arhitectura plug and play, serecomand implementarea de drivere WDM (care respect modelul Windows Driver Model) i caresuport complet arhitectura plug and play

    Eliminarea unui dispozitiv 20

  • Windows Driver Model (WDM)Windows Driver Model este un model unificat, ce permite scrierea de drivere al cror cod surs estecompatibil pentru toate platformele Windows. Un driver WDM (care respect modelul Windows DriverModel) are urmtoarele caracteristici:

    trebuie s aib unul din tipurile de drivere WDM (bus driver, function driver, filter driver) i s creezedispozitive cu unul din tipurile WDM (Physical Device Object, Functional Device Object, FilterDevice Object)

    trebuie s suporte plug and play trebuie s suporte managementul consumului (power management)[power management]

    trebuie s suporte WMI (Windows Management Instrumentation); WMI este un mecanism prin carekernel-ul pune la dispozitia aplicaiilor din user-mode informaii (permite publicarea informaiilor,configurarea dispozitivelor, un mecanism de notificri, logarea evenimentelor, etc.)

    Modelul WDM organizeaz driverele i dispozitivele ntr-o stiv.

    Astfel, driver-ele sunt mparite n trei categorii:

    bus drivers drivere asociate magistralelor din sistem; este obligatoriu s existe un astfel de driverpentru fiecare tip de magistrala din sistem; pot avea alte dispozitive conectate la magistral; se afl lacel mai jos nivel n stiva de drivere

    function drivers drivere pentru un dispozitiv individual; se afl deasupra driverelor pentru magistraln stiva de drivere

    filter drivers drivere care filtreaz cererile pentru un dispozitiv, o clas de dispozitive sau omagistral; se pot afla deasupra unui driver de magistral (modific n acest caz comportamentuldispozitivului) sau deasupra unui driver funcional (adaug funcionaliti suplimentare)

    n strns legtur cu tipurile de drivere, WDM definete i tipul de obiecte ce descriu dispozitivele asociatefiecrui driver din stiv (DEVICE_OBJECT):

    Physical Device Object (PDO) - reprezint un dispozitiv pe o magistral pentru un driver demagistral; exista cte un astfel de obiect pentru fiecare tip de dispozitiv fizic i este responsabil cucontrolul la nivel low-level al dispozitivului

    Functional Device Object (FDO) - reprezint un dispozitiv pentru un driver funcional; exist cte unastfel de obiect pentru fiecare funcie logic sau abstract care este oferit nivelului superior

    Filter Device Object (filter DO) - reprezint un dispozitiv pentru un driver de tip filtru; pot existafiltre att pentru obiectele dispozitiv de tip fizic ct i pentru cele de tip funcional

    Spre exemplu, s considerm un disc fizic i driverul acestuia. Va fi reprezentat de un PDO careimplementeaz funcionalitile adaptorului de magistral (spre exemplu, adaptarea unei magistrale IDEpentru disc la o magistral PCI). Odat ce PDO-ul este realizat, un FDO se ocup cu operaiile funcionale cudiscul (acesta poate realiza anumite cereri I/O direct, prin citirea unui sector de pe disc, sau poate transmitecererea dispozitivului de pe nivel mai jos, adic PDO-ului).

    Funcionarea unui driver plug and play i strile unui dispozitivModelul WDM este o extensie a modelului anterior, NT. Astfel, DriverEntry rmne funcia de

    Windows Driver Model (WDM) 21

  • iniializare a driverului, numai ca dup cum s-a precizat, nu se vor mai iniializa dispozitivele asociate aici.Pentru aceasta, va exista o alt funcie AddDevice, care va fi apelat de Plug and Play Manager pentrufiecare dispozitiv asociat. Operaiile legate de dispozitiv sunt iniiate de Plug and Play Manager printransmiterea unui mesaj IRP_MJ_PNP (MajorFunction). Pentru a diferenia operaiile efectuate asupradispozitivului se folosete codul minor (MinorFunction). Acest cod poate avea una din urmtoarelevalori:

    IRP_MN_START_DEVICE pentru iniializarea sau reiniializarea dispozitivului cu resurselespecificate

    IRP_MN_QUERY_STOP_DEVICE pentru a verifica dac dispozitivul poate fi oprit in vederearebalansrii resurselor

    IRP_MN_STOP_DEVICE pentru a opri dispozitivul (pentru a fi repornit sau eliminat) IRP_MN_CANCEL_STOP_DEVICE pentru a informa c nu se va opri dispozitivul, dupa o operaieIRP_MN_QUERY_STOP_DEVICE

    IRP_MN_QUERY_REMOVE_DEVICE pentru a verifica dac dispozitivul poate fi eliminat din sistem IRP_MN_REMOVE_DEVICE pentru a elimina dispozitivul din sistem (operaiile care deiniializeazresursele iniializate n funcia AddDevice)

    IRP_MN_CANCEL_REMOVE_DEVICE pentru a informa c nu se va elimina dispozitivul din sistem,dupa o operatie IRP_MN_QUERY_REMOVE_DEVICE

    IRP_MN_SURPRISE_REMOVAL pentru a informa c dispozitivul a fost eliminat din sistem frnotificare in prealabil

    Aceste coduri sunt valabile pentru toate driverele WDM. Pentru anumite tipuri de drivere (spre exemplupentru driverele de tip magistral sau pentru cele care au asociat un device de tip fizic i se ocup cumanagementul controlului la nivel low-level) sunt definite coduri suplimentare (spre exemplu, pentru aflareacapabilitilor unui dispozitiv, pentru aflarea interfeei acestuia, aflarea resurselor conectate la o magistral,etc.). Pentru detalii asupra acestor conduri consultai Plug and Play Minor IRPs.

    Dup cum se poate observa din operaiile de mai sus, un dispozitiv trece prin diferite stri, n timp ce esteconfigurat, pornit, eventual oprit pentru rebalansarea resurselor i posibil eliminat. Aceste stri se pot mprin dou categorii: strile prin care dispozitivul trece atunci cnd este adugat n sistem i strile prin care trecedup ce este adugat. O diagram detaliat i explicaii despre aceste stri i codurile pentru care se factranziiile gsii la State Transitions for PnP Devices.

    Iniializarea driver-ului (DriverEntry)La fel ca i n cazul modelului NT, driverele WDM se iniializeaz n rutina DriverEntry. Spre deosebirede aceasta, iniializeaz dispozitivele fizice (nu se mai apeleaz IoCreateDevice), ci doar se iniializeazfunciile driver-ului.

    Funciile ce trebuiesc iniializate includ funciile prezentate n Laboratorul 5, i reprezint funciile dedispatch pentru operaii de deschidere, scriere, citire, control, nchidere dispozitiv. Pe lng acestea, maitrebuie iniializat funcia pentru iniializarea dispozitivelor AddDevice) i funcia pentru mesajele plug andplay IRP_MJ_PNP).

    O funcie DriverEntry pentru un driver plug and play va arta n modul urmtor:

    NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING registry) {

    Funcionarea unui driver plug and play i strile unui dispozitiv 22

  • driver->DriverUnload = DriverUnload; driver->MajorFunction[ IRP_MJ_CREATE ] = Open; driver->MajorFunction[ IRP_MJ_READ ]= Read; driver->MajorFunction[ IRP_MJ_WRITE ] = Write; driver->MajorFunction[ IRP_MJ_CLEANUP ] = Cleanup; driver->MajorFunction[ IRP_MJ_CLOSE ] = Close;

    driver->DriverExtension->AddDevice = AddDevice; /* PNP */ driver->MajorFunction[ IRP_MJ_PNP ] = DispatchPnp; /* PNP */}

    Iniializarea dispozitivului (AddDevice)Dup cum s-a observat mai sus, pentru iniializarea dispozitivului exist o funcie AddDevice, care va fiapelat de Plug and Play Manager n momentul descoperirii dispozitivului. Aceast funcie va prelua sarcinafunciei DriverEntry din modelul NT i va iniializa dispozitivul.

    Prototipul acestei funcii este urmtorul:

    NTSTATUS AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject );

    unde DriverObject este un pointer ctre obiectul asociat driver-ului, iar PhysicalDeviceObjecteste un pointer ctre dispozitivul fizic (PDO), creat de un driver de nivel mai jos.

    Iniializarea dispozitivului se realizeaz cum a fost prezentat n Laboratorul 5: se creeaz o legtur internpentru dispozitiv printr-un apel al funciei IoCreateDevice, se creeaza o legtur simbolic pentruuserspace printr-un apel al funciei IoCreateSymbolicLink i se iniializeaz datele private aledispozitivului.

    Pe lng aceste operaii, funcia AddDevice mai trebuie s adauge obiectul asociat driverului n stiva deobiecte. Aceast operaie se realizeaz printr-un apel al funciei IoAttachDeviceToDeviceStack:

    PDEVICE_OBJECT IoAttachDeviceToDeviceStack ( IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice);

    unde SourceDevice este un pointer ctre obiectul asociat dispozitivului care apeleaz funcia (noul vrf alstivei dup apel), iar TargetDevice este un pointer ctre obiectul asociat altui dispozitiv (pointer ctrePDO-ul stivei). Funcia ntoarce un pointer ctre vechiul vrf al stivei, deci un pointer ctre dispozitivul situatsub dispozitivul apelant n stiva.

    ntruct obiectul a fost iniializat n afara funciei DriverEntry, este necesar resetarea bit-ului pentruiniializarea dispozitivului:

    device->Flags &= ~DO_DEVICE_INITIALIZING;

    Un exemplu de funcie AddDevice:

    #define DEVICE_NAME L"\\Device\\MyDevice"

    Iniializarea driver-ului (DriverEntry) 23

  • #define DEVICE_LINK L"\\??\\MyDevice"

    struct my_data { PDEVICE_OBJECT pLowerDevice; /* PNP */ UNICODE_STRING linkName;

    /* ... */};

    NTSTATUS AddDevice(IN PDRIVER_OBJECT driver, IN PDEVICE_OBJECT physicalDeviceObject) {

    struct my_data * myData; DEVICE_OBJECT *device; NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING devUnicodeName, linkUnicodeName;

    RtlInitUnicodeString(&devUnicodeName, DEVICE_NAME); RtlInitUnicodeString(&linkUnicodeName, DEVICE_LINK);

    if ( (status = IoCreateDevice(driver, sizeof(struct my_data), &devUnicodeName, FILE_DEVICE_UNKNOWN, 0, FALSE,&device) ) != STATUS_SUCCESS)

    return status;if ( (status = IoCreateSymbolicLink(&linkUnicodeName,

    &devUnicodeName)) != STATUS_SUCCESS) { IoDeleteDevice(device);

    return status;}

    device->Flags |= DO_BUFFERED_IO; device->Flags &= ~DO_DEVICE_INITIALIZING; /* PNP */ myData = (struct my_data *) device->DeviceExtension; RtlInitUnicodeString(&myData->linkName, DEVICE_LINK); myData->pLowerDevice = IoAttachDeviceToDeviceStack(device, physicalDeviceObject); /* PNP */

    return status;}

    Funcie de dispatch pentru drivere WDM (IRP_MJ_PNP)Dup cum s-a observat, funcia AddDevice doar iniializeaz dispozitivul i datele sale private, fr a realizaoperaii legate de dispozitivul fizic. Astfel, mai trebuie rezervat, iniializat si configurat dispozitivul fizic. nacest scop, exist o nou funcie de dispatch, IRP_MJ_PNP. Un IRP corepunztor este creat la iniializareadispozitivului, eliminarea sa sau cnd se primesc cereri din partea acestuia. Plug and Play Manager-ul va apelafuncia de dispatch corespunztoare (nregistrat n DriverEntry care trebuie s trateze aceste cazuri).ntruct sunt mai multe operaii, diferenierea ntre acestea se realizeaz prin codul minor al IRP-ului. Acestecoduri au fost prezentate mai sus, la Funcionarea unui driver plug and play i strile unui dispozitiv.

    O astfel de funcie de dispatch va diferenia ntre aceste coduri i va avea urmtoarea structur:

    NTSTATUS DispatchPnp(IN PDEVICE_OBJECT device, IN PIRP irp) { PIO_STACK_LOCATION irpStack; irpStack = IoGetCurrentIrpStackLocation(irp);

    switch (irpStack->MinorFunction) {case IRP_MN_START_DEVICE:

    return HandleStartDevice(device,irp);case IRP_MN_STOP_DEVICE:

    return HandleStopDevice(device,irp);

    Iniializarea dispozitivului (AddDevice) 24

  • case IRP_MN_REMOVE_DEVICE:return HandleRemoveDevice(device,irp);

    default:return PassDownPnP(device,irp);

    }}

    Dup cum se poate observa, pentru fiecare din operaii se apeleaz o funcie (ce va fi discutat n continuare),iar n cazul n care codul minor primit nu este suportat de driverul curent, este trimis urmtorului dispozitivdin stiv.

    Transmiterea cererilor plug and play n stiva de dispozitive

    Toate cererile plug and play sunt iniiate de Plug and Play Manager i sunt transmise driver-ului care se afl nvrful stivei de dispozitive. Indiferent ce coduri minore ale IRP-urilor sunt tratate de ctre un driver, cele carenu sunt tratate de ctre acesta trebuie trimise mai departe n stiva de dispozitive, la driverele de pe niveluri maijoase, care ar putea trata acele coduri. Aceast operaie este necesar, ntruct un driver se bazeaz pedriverele de pe nivele mai joase pentru realizarea anumitor operaii (spre exemplu, un driver funcional FDOse bazeaz pe driverul fizic - PDO). De asemenea, exist cereri care intereseaz toate driverele din stiv (cumar fi informarea asupra opririi dispozitivului).

    Pentru cererile care sunt tratate de driver, trebuie completat informaia IRP-ului legat de status(IoStatus) i apelat funcia IoCompleteRequest (dup cum este descris n Laboratorul 5). Pentru atransmite o cerere plug and play n jos pe stiva, fr a atepta ca aceste pachete s fie tratate de un driver[dispatch], se apeleaz funcia IoSkipCurrentIrpStackLocation, care elimin intrarea pentru stiva driver-uluicurent din IRP i apoi IoCallDriver pentru a transmite IRP-ul driver-ului de la nivel inferior. Pointerulctre driverul de sub cel curent n stiv a fost obinut n urma apeluluiIoAttachDeviceToDeviceStack de la iniializarea dispozitivului.

    Funcia PassDownPnP, care realizeaz aceste operaii i este apelat n funcia de dispatch de mai sus areurmtoarea implementare:

    NTSTATUS PassDownPnP( IN PDEVICE_OBJECT device, IN PIRP irp ) {struct my_data * myData = (struct my_data *) device-> DeviceExtension;

    IoSkipCurrentIrpStackLocation(irp);return IoCallDriver(myData->pLowerDevice, irp);

    }

    Pornirea dispozitivului (IRP_MN_START_DEVICE)

    Plug and Play Manager-ul, la boot sau n momentul conectrii unui dispozitiv, le identific i transmite un IRPcu codul minor IRP_MN_START_DEVICE driver-ului corespunztor. Pe msur ce identific dispozitivele,Plug and Play Managerul le atribuie resursele cerute, cu evitarea pe ct posibil a conflictelor. Atunci cndtransmite driver-ului IRP-ul, i transmite i o list cu resursele asociate dispozitivului fizic, n cmpurileParameters.StartDevice.AllocatedResourcesTranslated iParameters.StartDevice.AllocatedResources ale acestuia. Aceste cmpuri conin mai multeniveluri de vectori, i n final structura CM_PARTIAL_RESOURCE_DESCRIPTOR ce descrie resursele,care pot fi de patru tipuri: porturi, ntreruperi, memorie i dma.

    Funcie de dispatch pentru drivere WDM (IRP_MJ_PNP) 25

  • Resursele prezentate sunt de doua tipuri: raw (Parameters.StartDevice.AllocatedResources)i translated (Parameters.StartDevice.AllocatedResourcesTranslated). Resursele rawsunt cele ntlnite n driverele din modelul NT i pentru care trebuiau realizate operaii de translatare. Dinacest motiv, se vor folosi resursele translatate.

    Funcia HandleStartDevice, care realizeaz aceste operaii i este apelat n funcia de dispatch de maisus are urmtoarea structur:

    struct my_data {//...

    PKINTERRUPT pIntObj; //Interrupt KIRQL IRQL; ULONG Vector; KAFFINITY Affinity; ULONG portLength; //Port PUCHAR portBase; ULONG Channel; //Dma ULONG Port;

    //...};

    NTSTATUS HandleStartDevice(IN PDEVICE_OBJECT device, IN PIRP irp) {struct my_data * myData = (struct my_data *) device-> DeviceExtension;

    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(irp); PCM_RESOURCE_LIST pResourceList; PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor; PCM_PARTIAL_RESOURCE_LIST pPartialList; PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialDescriptor;

    int i; NTSTATUS status = STATUS_SUCCESS;

    pResourceList = irpStack->Parameters.StartDevice.AllocatedResourcesTranslated; pFullDescriptor = pResourceList->List; pPartialList = &pFullDescriptor->PartialResourceList;

    for (i=0; iCount; i++) { pPartialDescriptor = &pPartialList->PartialDescriptors[i];

    switch (pPartialDescriptor->Type) {case CmResourceTypeInterrupt: /* Interrupt */

    Pornirea dispozitivului (IRP_MN_START_DEVICE) 26

  • myData->IRQL = (KIRQL) pPartialDescriptor->u.Interrupt.Level; myData->Vector = pPartialDescriptor->u.Interrupt.Vector; myData->Affinity = pPartialDescriptor->u.Interrupt.Affinity; status = IoConnectInterrupt (

    &myData->pIntObj, // the Interrupt object myIsr, // our ISR myData, // Service Context

    NULL, // no spin lock myData->Vector, // vector myData->IRQL, // DIRQL myData->IRQL, // DIRQL Latched, // Latched or LevelSensitive

    TRUE, // Shared? myData->Affinity, // processors in an MP set

    FALSE ); // save FP registers? break;

    case CmResourceTypeDma: /* Dma */ myData->Channel = pPartialDescriptor->u.Dma.Channel; myData->Port = pPartialDescriptor->u.Dma.Port;

    /* IoGetDmaAdapter(...); */ break;

    case CmResourceTypePort: /* Port */ myData->portBase = (PUCHAR) pPartialDescriptor->u.Port.Start.LowPart; myData->portLength = pPartialDescriptor->u.Port.Length; break;

    case CmResourceTypeMemory: /* Memory *//* MmMapIoSpace(...); */

    break;}

    }

    return PassDownPnP(device, irp);}

    [HandleStartDevice]

    Oprirea dispozitivului (IRP_MN_STOP_DEVICE)

    La primirea unui IRP cu codul minor IRP_MN_STOP_DEVICE, se vor executa operaii pentru oprireadispozitivului. Aceste operaii sunt complementare celor executate n funcia HandleStartDevice, laprimirea unui IRP cu codul IRP_MN_START_DEVICE. Prin urmare, codul acestei funcii este dependent detipul de resurse deinute de dispozitiv.

    Funcia HandleStopDevice, care realizeaz aceste operaii i este apelat n funcia de dispatch de maisus are urmtoarea implementare:

    NTSTATUS HandleStopDevice(IN PDEVICE_OBJECT device, IN PIRP irp ) {struct my_data * myData = (struct my_data *) device-> DeviceExtension;/* IoDisconnectInterrupt(myData->pIntObj ); */return PassDownPnP(device, irp);

    }

    [IoDisconnectInterrupt]

    Eliminarea dispozitivului (IRP_MN_REMOVE_DEVICE)

    La primirea unui IRP cu codul minor IRP_MN_REMOVE_DEVICE, se vor executa operaii pentru eliminareadispozitivului din sistem. Aceste operaii sunt complementare celor executate n funcia AddDevice i sunt

    Oprirea dispozitivului (IRP_MN_STOP_DEVICE) 27

  • aceleai cu cele din DriverUnload, doar c pentru un singur dispozitiv (cel dat ca parametru). Funcia vadeiniializa resursele, va terge legturile pentru dispozitiv i va transmite IRP-ul n jos pe stiv.

    n plus fa de operaiile cunoscute, apare deataarea dispozitivului din stiv, printr-un apel al funcieiIoDetachDevice.

    Funcia HandleRemoveDevice, care realizeaz aceste operaii i este apelat n funcia de dispatch de maisus are urmtoarea implementare:

    NTSTATUS HandleRemoveDevice(IN PDEVICE_OBJECT device, IN PIRP irp ) {struct my_data * myData = (struct my_data *) device->DeviceExtension;/* IoDisconnectInterrupt(myData->pIntObj); */

    IoDeleteSymbolicLink(&myData->linkName); IoDetachDevice(myData->pLowerDevice); IoDeleteDevice(device);

    return PassDownPnP(device, irp);}

    QuizPentru auto-evaluare nainte de laborator rspundei la ntrebrile din quiz.

    ExerciiiFolosii arhiva de sarcini a laboratorului. Punctaj total: 15 puncte Punctajul maxim se ia cu 10 puncte. Bonusul poate recupera lipsa de activitate de la alte laboratoare.

    Linux

    Folosii directorul lin/ din arhiva de sarcini a laboratorului. Punctaj total: 10 puncte

    (1 punct). Intrai n directorul lin/virtual_bus/mybus, unde gsii implementarea uneimagistrale mybus, aa cum este descris n laborator.

    Analizai coninutul fiierelor mybus/mybus.c i include/virtual_bus.h. De ce senregistreaz o structur bus_type i o structur device pentru magistral?

    Compilai i inserai modulul. Unde sunt intrrile corespunztoare n sistemul de fiieresysfs?

    Scoatei modulul. Mai gsii intrrile n sysfs? De ce? Modificai sursa astfel nct intrrile pentru magistral i dispozitivul asociat s fie virtualbus,respectiv virtualbus0.

    Hints:Citii seciunile Magistrale i Dispozitive din laborator.

    1.

    (2 puncte). Intrai n directorul lin/virtual_bus/mydriver, unde gsii implementarea uneidevice driver de tip caracter similar celui din laboratorul 4.

    2.

    Eliminarea dispozitivului (IRP_MN_REMOVE_DEVICE) 28

  • Modificai sursa astfel nct s respecte modelul Linux Device Model. Dispozitivul echo se vaconecta la magistrala virtualbus de la exerciiul anterior, avnd un driver asociat echo.

    Ce intrri noi avei n sysfs? De ce este nevoie ca numele driverului i dispozitivului s fieidentice?

    Hints:Pentru a v conecta la magistrala virtualbus, va trebui s folosii funciile i tipurilede driver/device exportate de aceasta:

    va trebui s declarai i iniializai o structur my_device i o structurmy_driver

    va trebui s nregistrai/denregistrai aceste structuri cu funciilemy_register_driver/my_unregister_driver, respectivmy_register_device/my_unregister_device n funcia deinit/exit a modulului

    Pentru a elimina warning-urile legate de nedefinirea funciilor denregistrare/denregistrare de dispozitiv, compilai ambele module din directorulprinte

    Nu uitai s inserai modulul de la pasul anterior naintea inserarii modulului curent. Citii seciunile Magistrale, Dispozitive i Drivere din laborator.

    (2 puncte). Extindei driverul echo de la exerciiul anterior prin adugarea unui atribut dev pentrudispozitivul creat, ce va conine majorul i minorul dispozitivului (major:minor).

    Unde apare acest atribut n sysfs? Dar valoarea acestuia?Hints:Va trebui s declarai i s nregistrai o structur device_attributes. Pentru aflarea majorului i minorului din structura cdev.dev putei folosimacrodefiniiile MAJOR i MINOR

    Citii seciunile Magistrale i Dispozitive din laborator.

    3.

    (2 puncte). Intrai n directorul lin/parallel, unde gsii implementarea unui driver simplupentru portul paralel.

    Analizai coninutul fiierului parallel.c Modificai sursa astfel nct s respecte modelul Linux Device Model i plug and play.Dispozitivul se va conecta la magistrala PNP.

    Ce se ntmpl la inserarea modulului n sistem? De ce?Hints:nregistrai/denregistrai structura pnp_driver la ncrcarea/descrcareamodulului cu ajutorul funciilor pnp_register_driver, respectivpnp_unregister_driver.

    Pentru a fi un driver plug and play, iniializarea dispozitivelor trebuie fcut nmomentul n care acestea apar n sistem (la execuia funcieiparallel_pnp_probe), iar denregistrarea n momentul n care dispar din sistem(la execuia funciei parallel_pnp_remove).

    Citii seciunile Magistrala PNP i Operaii plug and play din laborator.

    4.

    (2 puncte). Pornind de la modulul anterior, adugai informaiile pentru o nou clas parclass, de careaparine modulul paralel.

    Ce se ntmpl acum la ncrcarea modulului? Cutai fiierul /dev/parclassHints:Definii o structur class i o structur class_device. Structura class trebuie iniializat odat cu resursele driver-ului (la execuiafunciei parallel_init), iar pentru fiecare dispozitiv trebuie iniializat ostructur class_device i nregistrat cu class_device_create (la execuiafunciei parallel_pnp_probe).

    Citii seciunea Clase din laborator.

    5.

    Linux 29

  • (1 punct). Creai un fiier de reguli pentru udev n /etc/udev/rules.d/parallel.rules,pentru a ncrca driverul de la exerciiul anterior n momentul detectrii dispozitivului n kernel.

    Repornii sistemul. Ce se ntmpla? Verificai log-urile de la boot.Hints:Identificai evenimentul n funcie de subsistem i de atributul id, care este generatautomat de clas. Pentru portul paralel acest atribut trebuie s aib valoareaPNP0400, iar subsistemul va fi pnp.

    Citii seciunea Hotplug din laborator.

    6.

    Windows

    Folosii directorul win/ din arhiva de sarcini a laboratorului. Punctaj total: 5 puncte

    (5 puncte). Intrai n directorul win/lpt/driver, unde gsii un driver legacy simplu pentruportul paralel.

    Modificai driver-ul existent pentru a obine un driver plug and play. Pentru a instala driver-ul n sistem, trebuie s nlocuii driverul curent pentru portul paralel:Device Manager -> Ports (COM & LPT) -> Printer Port (LPT1) ->Update Driver -> No, not at this time -> Install from a listor specific location -> Dont search. I will choose the driverto install -> Have disk -> alegei directorul n care se afl fiierullptdriver.inf; dac fiierul lpt.sys nu se alf n acelai director cu fiierullptdriver.inf, vi se va cere s specificai calea ctre acesta

    Pentru testare folosii testul din win/lpt/testHints:Citii seciunea Plug and play n Windows din laborator.

    1.

    Pentru acas

    Intrai n directorul win/acasa/buffer/driver, unde gsii un driver legacy pentru undispozitiv virtual, care pstreaz un mesaj scris pe dispozitiv i l returneaz la citire.

    Modificai driver-ul existent pentru a obine un driver plug and play. Pentru a instala driver-ul n sistem, trebuie s instalai un nou dispozitiv fizic: ControlPanel -> AddHardware -> Yes, I have already connected thehardware -> Add a new hardware device -> Install the hardwarethat i manually select from a list (Advanced) -> Show alldevices -> Have disk -> alegei directorul n care se afl fiierul buffer.inf;dac fiierul buffer.sys nu se alf n acelai director cu fiierul buffer.inf, vi se vacere s specificai calea ctre acesta

    Dac driver-ul a fost instalat corect, va aprea n Device Manager, la SystemDevices sub numele PSO Virtual Buffer; testai funcionalitatea acestuia prinoperaiile de Disable, Enable, Uninstall din Device Manager.

    Pentru testare folosii testul din win/acasa/buffer/test

    1.

    Windows 30

  • Hints:Pentru ca lucrai cu un dispozitiv virtual, nu avei cui s trimitei n jos pe stivcererile din partea Plug and Play Manager-ului; deci nu va trebui s apelai funciaPassDownPnP pentru codurile minore pe care le tratai (adic n funciileHandleStartDevice, HandleStopDevice i HandleRemoveDevice); naceste funcii ns va trebui s marcai terminarea IRP-ului

    ntruct dispozitivul este virtual, nu folosete resurse i nu trebuie implementatfuncionalitatea de la HandleStartDevice.

    Citii seciunea Plug and play n Windows din laborator.

    SoluiiSoluii exerciii laborator 12

    Resurse utile

    Linux

    Linux Device Drivers, 3rd edition Chapter 14. The Linux Device Model1. Porting device drivers to the 2.6 kernel Device Model2. The Driver Model Core, Part I3. Driving Me Nuts - Device Classes4. Plug and Play HOWTO5. Plug 'n Play progress in Linux6. Linux Hotplugging7. udev8. Kernel Korner - udevPersistent Device Naming in User Space9. Dynamic device management in Udev10. Recent Changes to /sbin/hotplug11. Writing udev rules12. Documentatie pentru sursele kernel-ului

    Documentation/driver-model Documentation/pnp.txt Documentation/filesystems/sysfs.txt Documentation/kobject.txt

    13.

    Sursele kernel-uluiDriver pentru porturi seriale tip 8250/16550 ISAPNP Driver pentru portul paralel Driver pentru PC87307/PC97307 WDT

    14.

    Windows

    The Windows 2000 Device Driver Book, Second Edition Chapter 9. Hardware Initialization1. Programming the Microsoft Windows Driver Model, Second Edition - Chapter 2. Basic Structure of aWDM Driver, Chapter 6. Plug and Play for Function Drivers, Chapter 15. Distributing Device Drivers

    2.

    Pentru acas 31

  • Plug and Play3. A simple demo for WDM Driver development4. Plug and Play - Architecture and Driver Support5.

    Notebus

    cum s-a prezentat n seciunea Magistrale1. device

    vom vedea cum se realizeaz nregistrarea dispozitivelor n seciunea Adugarea unui dispozitiv2. device

    vom vedea cum se realizeaz denregistrarea dispozitivelor n seciunea Eliminarea unuidispozitiv

    3.

    uevent i se vor apela funciile kset_uevent_ops din kobject->kset->uevent_ops4.

    registry i la ncrcarea unui driver se completeaz informaii n regitrii5.

    .inf pentru crearea unui fiier .inf, se poate folosi utilitarul geninf.exe, pus la dispoziie de DDK

    (Driver Development Kit) (este disponibil n subdirectorul /tools al directorului n care este instalatDDK)

    6.

    power management pentru un exemplu de implementare a managementului consumului n driver consultai

    The Windows 2000 Device Driver Book, Second Edition Chapter 10. Power Management7.

    dispatch pentru a atepta ca cererile s fie tratate de un driver de pe un nivel mai jos, se va folosi funcia

    IoCopyCurrentIrpStackLocationToNext i se va seta o funcie ce va fi apelat atunci cndse va termina procesarea IRP-ului, cu funcia IoSetCompletionRoutine; pentru mai multedetalii, consultai The Windows 2000 Device Driver Book, Second Edition Chapter 9. HardwareInitialization - The New WDM IRP Dispatch Functions

    8.

    HandleStartDevice funcia HandleStartDevice este un model pentru accesarea tuturor tipurilor de

    resurse; pentru fiecare dispozitiv, numai o parte din acestea pot fi reprezentative9.

    IoDisconnectInterrupt funcia IoDisconnectInterrupt se va apela numai pentru dispozitive care au

    resurse de tipul ntrerupere10.

    Windows 32