phân tích mã nguồn driver usb mouse

Upload: thanh-nien-cung

Post on 02-Mar-2016

35 views

Category:

Documents


0 download

DESCRIPTION

Phân tích mã nguồn driver usb mouseCơ chế quản lý usb driver trong Linux

TRANSCRIPT

TRNG I HC BCH KHOA H NIVIN IN T - VIN THNG

BO CO BI TP LN Mn: H iu hnh

ti: Vit driver chut usb cho Linux

Gio vin hng dn: Phm Don TnhSinh vin:MSSVTrn Sn Tng20102506Trn Tin Thnh20102170

5/2014

Li m uHin nay, vi s pht trin ngy cng nhanh ca h thng nhng p ng li nhu cu th trng, d dng c th thy h iu hnh Linux xut hin hu ht cc thit b c phc tp cng nh kh nng p ng cao. Vic tch hp h iu hnh ln h thng nhng gip n gin ha qu trnh thit k sn phm, rt ngn thi gian cng nh chi ph xy dng h thng v cc ng dng ny c k tha s u vit ca mt h iu hnh ni chung v Linux ni ring. l s nh gn, n nh, thc thi nhanh, n gin ha v kh nng can thip su vo phn cng. Hn th na, cng vi cng ng s dng Linux rng ln trn khp th gii v cc phn mm m ngun m a dng lm cho vic pht trin h thng Linux nhng tr thnh mt chin lc c cc cng ty la chn hng u.Mt khc, chun giao tip USB (Universal Series Bus) v ang tr thnh mt trong nhng chun giao tip ph bin nht. Hin ti, USB tr thnh chun kt ni cng nh phng thc truyn d liu thn thuc vi ngi dng cng ngh nh vo s thun tin, bn v gi thnh hp l ca n. Do chng em quyt nh chn ti Vit driver chut USB cho h iu hnh Linux lm bi tp ln cho mn hc H iu hnh. V y l mt ti tng i phc tp v thi gian thc hin c hn, nn nhm chng em ch dng li mc i su phn tch m ngun ca h iu hnh nhm tm hiu c ch qun l giao tip USB ca Linux. Phn code c s dng nm trong file /drivers/hid/usbhid/usbmouse.c ca Linux kernel v3.13.6

I. Khi qut v giao thc USB

Mt thit b giao tip bng chun USB thc ra rt phc tp. Nhng may mn l h iu hnh Linux cung cp cho ta nhng th vin h tr kh y , v iu gip tit kim c rt nhiu thi gian, cng sc cng nh chi ph xy dng mt thit b nh th. a phn s phc tp ca USB c h tr bi USB Core ca Linux.

1. Cc thnh phn c bn ca giao thc USB

a. Endpoint: Thnh phn c bn nht trong chun giao tip USB. USB Endpoint truyn d liu theo mt hng duy nht, t host n device (gi l OUT Endpoint) hoc ngc li (In Endpoint). C 4 loi endpoint:

Controll: Controll endpoint dng truy cp cc phn khc nhau trong thit b USB. Chng thng c dng ci t thit b, ly thng tin thit b, gi lnh n thit b, hoc ly bo co trng thi ca thit b. Interupt: Interupt endpoint dng truyn d liu dung lng nh mi khi my ch truy vn d liu t thit b. Loi endpoint ny hay c s dng vi nhng thit b nh chut hay bn phm. Chng cng hay c dng gi d liu gia cc thit b vi nhau, nhng lng d liu truyn i thng khng ln. Giao thc USB lun m bo c bng thng d phng cho loi endpoint ny. Bulk: Bulk endpoint dng truyn d liu c dung lng ln. Loi endpoint ny c kch thc ln hn nhiu so vi interupt. Chng c dng cho loi thit b yu cu truyn dn d liu kch thc ln m khng c xy ra mt mt d liu. Chng cng khng c bng thng d tr ging nh interupt endpoint. Nu khng c bng thng truyn c gi tin i, d liu s c chia nh. Loi endpoint ny c s dng cho cc thit b nh my in, nh flash Isochorous: Isochorous endpoint dng truyn d liu kch thc ln, nhng khng yu cu s m bo d liu ton vn. Chng c dng cho cc thit b chp nhn s mt mt trong truyn d liu, i li s m bo qu trnh c lin tc, nh cc thit b truyn dn thi gian thc nh video v audio

Cu trc d liu ca endpoint c nh ngha trong struct usb_host_endpoint ca Linux kernel. Trong thng tin thc s ca endpoint c cha trong struct usb_endpoint_descriptor.

struct usb_host_endpoint { struct usb_endpoint_descriptor desc; struct usb_ss_ep_comp_descriptor ss_ep_comp; struct list_head urb_list; void * hcpriv; struct ep_device * ep_dev; unsigned char * extra; int extralen; int enabled; int streams;};

Cc thng s cn quan tm:

bEndpointAddress: a ch ca endpoint, trong c 8 bit dng m ha hng ca endpoint l IN hay OUT. bmAttributes: Dng nh ngha loi endpoint l kiu no trong 4 kiu controll, bulk, interupt hay isochorous. wMaxPacketSize: Kch thc ti a gi tin m endpoint c th chuyn i. Nu gi tin cn chuyn ln hn gi tr ny th n s b chia thnh cc gi c kch thc tng ng. bInterval: Nu endpoint l loi interupt th bin ny s xc nh khong thi gian gia cc ln gi request t host n device (o bng mili giy).

b. Interface: Tp hp cc endpoint gi l interface. Mi interface th hin mt chc nng c bn duy nht ca thit b, v d nh flash, hay bn phm. Mt thit b c th c nhiu interface. Mt interface c nhiu thit lp, vi thit lp ban u c nh s 0. Thit lp khc nhau c th dng iu khuyn endpoint theo cc cch khc nhau

Interface c nh ngha trong Linux kernel bng struct usb_interface.

struct usb_interface { struct usb_host_interface * altsetting; struct usb_host_interface * cur_altsetting; unsigned num_altsetting; struct usb_interface_assoc_descriptor * intf_assoc; int minor; enum usb_interface_condition condition; unsigned sysfs_files_created:1; unsigned ep_devs_created:1; unsigned unregistering:1; unsigned needs_remote_wakeup:1; unsigned needs_altsetting0:1; unsigned needs_binding:1; unsigned reset_running:1; unsigned resetting_device:1; struct device dev; struct device * usb_dev; atomic_t pm_usage_cnt; struct work_struct reset_ws;};

Cc thng s cn quan tm: struct usb_host_interface *altsetting: Mt mng cha cc phn t kiu interface tng ng vi mi thit lp khc nhau. Mi struct usb_host_interface cha mt tp hp cc endpoint c nh ngha trong usb_host_endpoint. unsigned num_altsetting: s thit lp khc nhau ca interface, c tr n bi con tr *altsetting. struct usb_host_interface *cur_altsetting: con tr tr n thit lp hin ti ca interface. int minor: Thit b trong h thng c truy cp bng tn. Tn thit b bao gm 2 phn l major v minor. major dng xc nh driver cho thit b, cn minor dng xc nh chnh xc thit b ang xt.

c. Configuration: l tp hp cc interface. Mt thit b c th c nhiu configuration v chuyn i qua li gia chng. Ch c mt configuration c php s dng ti mi thi im. Linux khng th h tr cc thit b s dng ng thi nhiu configuration (tuy nhin cc thit b rt him).

Tm li: Mt thit b c th c nhiu configuration. Mt configuration c th c nhiu interface. Mt interface c th c nhiu setting. Interface khng c hoc c th c nhiu endpoint.

d. Sysfs: do tnh phc tp trong cu trc vt l ca thit b USB, vic m t thit b trong lp trnh cng khng n gin. Sysfs c s dng nh mt trnh qun l d liu ca Linux gip vic qun l nhng thit b nh th ny c n gin hn. M t vt l thit b USB cng nh interface ca n c m t nh nhng thit b c lp trong sysfs.

2. M hnh giao thc USB

a. Chun tn hiu

Chun USB s dng 4 ng tn hiu trong c 2 ng cp ngun DC (VBUS-5V v GND). 2 ng cn li l mt cp tn hiu vi sai (D+ v D-) cho php truyn d liu. Cp dy tn hiu ny c ni xon bn trong nn c kh nng chng nhiu tt.

b. M hnh mng

Cc thit b hot ng theo chun USB c kt ni vi nhau theo hnh mng hnh sao phn cp. Trung tm ca mi hnh sao ny l cc Hub. Trong hnh nh vy, cc thit b USB c chia lm 3 loi chnh: USB Host: thit b ng vai tr iu khin ton b mng USB (c th ln ti ti a 126 thit b). V d nh trn my tnh, USB Host c gn trn mainboard. giao tip v iu khin cc USB device, USB Host controller cn c thit k tch hp vi USB RootHub (Hub mc cao nht). Vai tr ca thit b USB Host: Trao i d liu vi cc USB Device iu khin USB Bus: Qun l cc thit b cm vo hay rt ra khi Bus USB qua qu trnh im danh (Enumeration) Phn x, qun l lung d liu trn Bus, m bo cc thit b u c c hi trao i d liu ty thuc vo cu hnh ca mi thit b. USB Device: l cc thit b ng vai tr nh cc slave giao tip vi USB Host. Xin lu mt iu ht sc quan trng l cc thit b ny hon ton ng vai tr b ng, khng bao gi c t gi gi tin ln USB Host hay gi gi tin gia cc USB Device vi nhau, tt c u phi thng qua qu trnh iu phi ca USB Host. Cc bn s hiu c ch ny r hn trong phn truyn thng ca chun USB. Chc nng ca thit b USB Device:

Trao i d liu vi USB Host Pht hin gi tin hay yu cu t USB Host theo giao thc USB. USB Hub: ng vai tr nh cc Hub trong mng Ethernet ca chng ta. Cp ngun cho cc thit b USB

c. Host view:

d. Device view:

e. Kch bn hot ngQu trnh hot ng ca chun USB c th c chia lm hai giai on chnh: Qu trnh im danh: l qu trnh USB Host pht hin cc thit b cm vo v rt ra khi ng USB Bus. Mi khi mt thit b tham gia vo Bus USB, USB Host s tin hnh c cc thng tin m t (Description) ca USB Device, t thit lp a ch (NodeID) v ch hot ng tng ng cho thit b USB Device. Cc a ch s c nh t 1->126 nn v l thuyt, chun USB cho php kt ni 126 thit b vo ng Bus. Khi thit b rt ra khi ng Bus, a ch ny s c thu hi. Qu trnh truyn d liu: ng gc mc h thng, cc Interface chnh l cc dch v khc nhau m thit b cung cp cn cc Endpoint chnh l cc cng cn thit cho mi dch v. Tng ng vi khi nim trong kin trc TCP/IP, v d giao thc FTP l giao thc s dng truyn file s s dng hai cng 20,21. Trong khi giao thc HTTP li s dng port 80, giao thc Telnet s dng port 23.Thc t cc Endpoint cng nh cc Port trong chun TCP/IP ng vai tr nh cc b m truyn/nhn d liu. Nh vic s dng nhiu b m m cc qu trnh truyn thng c tin hnh song song v cho tc cao hn, bn cnh gip cho vic phn tch cc dch v khc nhau. Vi chun USB, cc thit b c thit k vi ti a l 16 Endpoint.

II. USB driver1. struct usb_ {};/* Cha thng tin thit b */static struct usb_device_id _table [] = { { USB_DEVICE(ML_VENDOR_ID, ML_PRODUCT_ID) }, { }};/* Cha id thit b*/static int

_open(struct inode *inode, struct file *file){ /* open syscall */}static int

_release(struct inode *inode, struct file *file){ /* close syscall */}static ssize_t ml_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos);{ /* write syscall */}static struct file_operations ml_fops = { .owner = THIS_MODULE, .write = ml_write, .open = ml_open, .release = ml_release,};static int ml_probe(struct usb_interface *interface, const struct usb_device_id *id){ /* hm ny c gi khi thit b c kt ni vi my tnh */}Khung chng trnh ca mt USB driver bt k

static ssize_t

_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos);{ /* write syscall */}static struct file_operations _fops = { .owner = THIS_MODULE, .write = ml_write, .open = ml_open, .release = ml_release,};static int

_probe(struct usb_interface *interface, const struct usb_device_id *id){ /* hm ny c gi khi thit b c kt ni vi my tnh */}static void

_disconnect(struct usb_interface *interface){ /* hm ny c gi khi thit b c rt khi my tnh */}static struct usb_driver ml_driver = { .name = "missile_launcher", .id_table = ml_table, .probe = ml_probe, .disconnect = ml_disconnect,};static int __init usb_

_init(void){ /* Khi to */}static void __exit usb_

_exit(void){ /* Gii phng ti nguyn */ }module_init(usb_

_init);module_exit(usb_

_exit);2. Xy dng driver cho chut USB

a. #include

#include

#include

#include

#include

#include Th vin

b. Khi to

struct usb_mouse {char name[128];char phys[64];struct usb_device *usbdev;struct input_dev *dev;struct urb *irq;signed char *data;dma_addr_t data_dma;};Cu trc sau y dng m t thit b chut USB l 1 input device giao tip bng urb.

Name: tn thit b Phys: chui nh danh thit b *usbdev: con tr dng tr ti thit b gi urb i. *dev: con tr dng m t 1 thit b u vo. *irq: con tr kiu urb USB request block. USB code dng urb giao tip vi cc thit b USB. Urb c dng gi i cng nh nhn d liu t endpoint ca thit b theo phng thc khng ng b. Chu k ca 1 urb nh sau: c to bi usb device driver c gn vo mt endpoint ca driver c gi ti USB core bi driver c gi ti host controller driver bi core c x l bi host controller driver ri thc hin truyn d liu v device Khi hon tt th tc request, host controller driver s gi thng bo n device. *data: bin d liu. *data_dma: bin d liu theo c ch DMA (Direct Memory Access)

c. Interupt

static void usb_mouse_irq(struct urb *urb){struct usb_mouse *mouse = urb->context;signed char *data = mouse->data;struct input_dev *dev = mouse->dev;int status;switch (urb->status) {case 0:/* success */break;case -ECONNRESET:/* unlink */case -ENOENT:case -ESHUTDOWN:return;/* -EPIPE: should clear the halt */default:/* error */goto resubmit;}Hm sau y c gi x l ngt. *mouse: con tr m t thit b kiu mouse nh c nh ngha khi to. *data: con tr d liu. *dev: con tr kiu input device. status l 1 bin kiu nguyn thuc struct urb. Khi urb c x l hoc hon tt, status s c cp nht gi tr tng ng vi trng thi hin ti ca urb. Gi tr bin status sau s c truyn vo hm x l ngt. 1 cu trc iu kin s kim tra gi tr bin ny. TH1: Nu status = 0, tc l qu trnh truyn urb thnh cng. TH2: Nu status = ESHUTDOWN, tc l xy ra li vi USB host controller driver khin cho n b v hiu ha, hoc l do urb c gi sau khi thit b ngt kt ni. Li ny cng xy ra nu configuration b thay i khi urb ang c gi. TH3: Nu status = ECONNRESET, th urb b ngt kt ni bi hm usb_unlink_urb, bin transfer_flags trong urb c set gi tr bng URB_ASYNC_UNLINK. TH4: Nu status = ENOENT, th urb b dng li bi hm usb_kill_urb. Nu status ri vo 3 trng hp li th chng trnh s thot khi hm ngt. input_report_key(dev, BTN_LEFT, data[0] & 0x01);//chut triinput_report_key(dev, BTN_RIGHT, data[0] & 0x02);//chut phiinput_report_key(dev, BTN_MIDDLE, data[0] & 0x04);//chut giainput_report_key(dev, BTN_SIDE, data[0] & 0x08);//chut bninput_report_key(dev, BTN_EXTRA, data[0] & 0x10);//chut phinput_report_rel(dev, REL_X, data[1]);//honh input_report_rel(dev, REL_Y, data[2]);//tung input_report_rel(dev, REL_WHEEL, data[3]);//ta nm xoayinput_sync(dev);//ng b d liu vi input deviceNu status ri vo trng hp u tin, chng trnh s thot khi cu trc switch v nhy n khi lnh tip theo: Cc lnh trn gi cc tn hiu ngt khi cc nt tng ng c bm, hoc ly ta tng i ca chut. resubmit:status = usb_submit_urb (urb, GFP_ATOMIC);if (status)dev_err(&mouse->usbdev->dev,"can't resubmit intr, %s-%s/input0, status %d\n",mouse->usbdev->bus->bus_name, mouse->usbdev->devpath, status); Nu status khng ri vo bt k trng hp no, n s nhy n nhn resubmit:

y urb s c chuyn thnh trng thi gi, bng cch gi n hm int usb_submit_urb(struct urb *urb, int mem_flags); ti y c mem_flags c s dng thit lp phng thc phn b b nh m cho USB core. Khi urb c gi, chng ta khng c php truy nhp vo bt c mt trng no ca struct urb, cho n khi urb c hon tt. Mt khc usb_submit_urb c th c gi bt c lc no, do c mem_flags c s dng nhm trnh xung t. i vi trng hp usb_submit_urb c gi trong hm x l ngt, th mem_flags s c gn bng GFP_ATOMIC.Phn code bn di khi code s in ra thng bo li nu urb b li.

d. static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id){struct usb_device *dev = interface_to_usbdev(intf);struct usb_host_interface *interface;struct usb_endpoint_descriptor *endpoint;struct usb_mouse *mouse;struct input_dev *input_dev;int pipe, maxp;int error = -ENOMEM;interface = intf->cur_altsetting;ProbeHm sau y dng pht hin nu chut c kt ni, v thc hin gi urb: *dev: con tr kiu thit b USB. Mt USB driver thng phi chuyn nh dng d liu khi d liu c truyn t struct usb_interface sang struct usb_device thun tin cho USB core khi gi hm. lm vic ta s dng hm interface_to_usbdevkhi chuyn d liu t intf sang dev. *interface: Con tr kiu con tr trung gian dng load thng s ca *altsetting v *cur_altsetting. *endpoint: con tr cha thng tin cc endpoint. *mouse: con tr kiu thit b chut. *input_dev: con tr kiu thit b u vo. pipe: ng ng lnh. maxp: kch thc ti a gi tin. error = -ENOMEM: li trn b nh.

interface = intf->cur_altsetting;if (interface->desc.bNumEndpoints != 1)return -ENODEV;Con tr interface lc ny s tr n setting hin ti ca n. bNumEndpoints l 1 bin ca struct usb_interface_descriptor thuc struct usb_host_interface, c gi tr bng s endpoint ca interface ang xt. endpoint = &interface->endpoint[0].desc;if (!usb_endpoint_is_int_in(endpoint))return -ENODEV;Nu khng c hoc c nhiu hn 1 endpoint, s tr v li ENODEV (khng tn ti thit b no nh th - do chut ch c 1 endpoint duy nht) pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);Hm usb_endpoint_is_int_in(endpoint) kim tra nu endpoint ny l interupt IN-endpoint. N s tr v true nu ng, v false nu sai. Li ENODEV s c tr v nu kt qu tr v khng phi l true. Lnh u tin s to mt ng ng nhn lnh. input_dev = input_allocate_device();//(1)if (!mouse || !input_dev)goto fail1;mouse->data = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &mouse->data_dma); //(2)if (!mouse->data)goto fail1;fail1:input_free_device(input_dev);kfree(mouse); return error;Lnh th 2 thit lp kch thc gi tin ti a cho endpoint Lnh th 3 phn b b nh thit b, kch thc b nh bng kch thc urb ca chut. Vng nh c cp c lm rng.

Lnh (1) thc hin phn b b nh cho thit b u vo Lnh (2) thc hin phn b b nh m theo c ch DMA cho chut. Chng trnh s nhy n fail1 nu khng khng th cp pht b nh hoc b m cho chut hoc thit b u vo. mouse->irq = usb_alloc_urb(0, GFP_KERNEL);if (!mouse->irq)goto fail2;fail2:usb_free_coherent(dev, 8, mouse->data, mouse->data_dma);fail1: gii phng b nh dnh cho thit b u vo cng nh chut, v tr v li ENOMEM. Bt u to mt urb mi cho chut s dng mouse->usbdev = dev;mouse->dev = input_dev;if (dev->manufacturer)strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));if (dev->product) {if (dev->manufacturer)strlcat(mouse->name, " ", sizeof(mouse->name));strlcat(mouse->name, dev->product, sizeof(mouse->name));}if (!strlen(mouse->name))snprintf(mouse->name, sizeof(mouse->name), "USB HIDBP Mouse %04x:%04x", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct));usb_make_path(dev, mouse->phys, sizeof(mouse->phys));strlcat(mouse->phys, "/input0", sizeof(mouse->phys)); input_dev->name = mouse->name;input_dev->phys = mouse->phys;usb_to_input_id(dev, &input_dev->id);input_dev->dev.parent = &intf->dev;input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |BIT_MASK(BTN_EXTRA);input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);input_set_drvdata(input_dev, mouse);Nu urb khng th c to do cha c cp pht b nh m, th khi lnh s nhy n fail2 gii phng b nh m c cp pht bi hm usb_alloc_coherent trc . Khi lnh trn bao gm: Ly thng tin thit b nh productID, vendorID, tn sn phm, nh sn xut. To ng dn ti sysfs. input_dev->open = usb_mouse_open; input_dev->close = usb_mouse_close;Hon tt khi to thit b u vo kiu chut. usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data, (maxp > 8 ? 8 : maxp), usb_mouse_irq, mouse, endpoint->bInterval);mouse->irq->transfer_dma = mouse->data_dma;mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;error = input_register_device(mouse->dev);if (error)goto fail3;fail3:usb_free_urb(mouse->irq); Khai bo cc li gi h thng. Hm usb_fill_int_urb khi to d liu cho interupt urb trc khi c gi ti USB core. Thit lp kiu truyn d liu trc tip (DMA) usb_set_intfdata(intf, mouse);return 0;Nu b li khng th ng k thit b vi sysfs, chng trnh s nhy n fail3, ti y chng trnh s gii phng b nh cp pht cho urb Lnh trn s thu hi d liu t cu trc d liu c lu trong usb_interface, nh du chm dt urb .

e. Open syscall

static int usb_mouse_open(struct input_dev *dev){struct usb_mouse *mouse = input_get_drvdata(dev);mouse->irq->dev = mouse->usbdev;if (usb_submit_urb(mouse->irq, GFP_KERNEL))return -EIO;return 0;}L 1 li gi h thng USB core gi khi cn.Chc nng li gi ny l ly d liu ca thit b v gi i cng vi urb.

f. Close syscall

static void usb_mouse_close(struct input_dev *dev){struct usb_mouse *mouse = input_get_drvdata(dev);usb_kill_urb(mouse->irq);}L 1 li gi h thng tng t Open syscall.Chc nng li gi ny l ly d liu ca thit b v hy truyn urb.

g. Disconnect

static void usb_mouse_disconnect(struct usb_interface *intf){struct usb_mouse *mouse = usb_get_intfdata (intf);usb_set_intfdata(intf, NULL);if (mouse) {usb_kill_urb(mouse->irq);input_unregister_device(mouse->dev);usb_free_urb(mouse->irq);usb_free_coherent(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);kfree(mouse);}}Hm ny c gi khi chut c ngt kt ni vi my tnh. Khi thit b c ngt kt ni th vic ly li d liu t interface l rt cn thit. Hm usb_get_intfdata c chc nng nh th, n s ly li nhng d liu c cp pht trc bi hm usb_set_intfdata. Sau khi ly li d liu, hm usb_set_intfdata s thit lp d liu v mc NULL nhm trnh nhng sai st pht sinh trong qu trnh truy nhp d liu. Khi lnh tip theo s gii phng ti nguyn cho thit b. Bao gm: Hy urb Hy ng k thit b Gii phng ti nguyn urb. Khi lnh usb_free_urb c gi ra, struct urb s b xa v driver s khng th truy nhp urb c na. Gii phng b nh v b m c cp pht.

Trn y chng ta trnh by tt c cc cu trc v hm c bn phc v cho chng trnh ca driver. Ngoi ra 1 s hm cng nh cu trc ph cng c dng nhm khai bo thng tin driver phc v cho vic qun l trong sysfs.

static struct usb_device_id usb_mouse_id_table [] = {{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE) },{ }/* Terminating entry */};MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);static struct usb_driver usb_mouse_driver = {.name= "usbmouse",.probe= usb_mouse_probe,.disconnect= usb_mouse_disconnect,.id_table= usb_mouse_id_table,};module_usb_driver(usb_mouse_driver);

Ti liu tham kho(1) Jonathan Corbet, Alessandro Rubini, Greg Kroah-Hartman. Linux Device Drivers(2) http://matthias.vallentin.net/blog/2007/04/writing-a-linux-kernel-driver-for-an-unknown-usb-device/(3) https://sites.google.com/site/embedded247/embedded_system/usbprotocol/