Top Banner

of 21

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

Mar 02, 2016

Download

Documents

Phân tích mã nguồn driver usb mouse
Cơ chế quản lý usb driver trong Linux
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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/