版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
LinuxUSB鼠標(biāo)驅(qū)動(dòng)程序詳解入U(xiǎn)SB總線引出兩個(gè)重要的鏈表!A一個(gè)USB總線引出兩個(gè)重要的鏈表,一個(gè)為USB設(shè)備鏈表,一個(gè)為USB驅(qū)動(dòng)鏈表。設(shè)備鏈表包含各種系統(tǒng)中的USB設(shè)備以及這些設(shè)備的所有接口,驅(qū)動(dòng)鏈表包含USB設(shè)備驅(qū)動(dòng)程序(usbdevicedriver)和USB驅(qū)動(dòng)程序(usbdriver)。AUSB設(shè)備驅(qū)動(dòng)程序(usbdevicedriver)和USB驅(qū)動(dòng)程序(usbdriver)的區(qū)別是什么?AUSB設(shè)備驅(qū)動(dòng)程序包含USB設(shè)備的一些通用特性,將與所有USB設(shè)備相匹配。在USBcore定義了:structusb_device_driverusb_generic_driver。usb_generic_driver是USB子系統(tǒng)中唯一的一個(gè)設(shè)備驅(qū)動(dòng)程序?qū)ο?。而USB驅(qū)動(dòng)程序則是與接口相匹配,接口是一個(gè)完成特定功能的端點(diǎn)的集合。A設(shè)備是如何添加到設(shè)備鏈表上去的?入在設(shè)備插入U(xiǎn)SB控制器之后,USBcore即會(huì)將設(shè)備在系統(tǒng)中注冊(cè),添加到USB設(shè)備鏈表上去。AUSB設(shè)備驅(qū)動(dòng)程序(usbdevicedriver)是如何添加到驅(qū)動(dòng)鏈表上去的?入在系統(tǒng)啟動(dòng)注冊(cè)USBcore時(shí),USB設(shè)備驅(qū)動(dòng)程序即將被注冊(cè),也就添加到驅(qū)動(dòng)鏈表上去了。A接口是如何添加到設(shè)備鏈表上去的?A在USB設(shè)備驅(qū)動(dòng)程序和USB設(shè)備的匹配之后,USBcore會(huì)對(duì)設(shè)備進(jìn)行配置,分析設(shè)備的結(jié)構(gòu)之后會(huì)將設(shè)備所有接口都添加到設(shè)備鏈表上去。比如鼠標(biāo)設(shè)備中有一個(gè)接口,USBcore對(duì)鼠標(biāo)設(shè)備配置后,會(huì)將這個(gè)接口添加到設(shè)備鏈表上去。AUSB驅(qū)動(dòng)程序(usbdriver)是如何添加到驅(qū)動(dòng)鏈表上去的?A在每個(gè)USB驅(qū)動(dòng)程序的被注冊(cè)時(shí),USB驅(qū)動(dòng)程序即會(huì)添加到驅(qū)動(dòng)鏈表上去。比如鼠標(biāo)驅(qū)動(dòng)程序,usb_mouse_init函數(shù)將通過usb_register(&usb_mouse_driver)將鼠標(biāo)驅(qū)動(dòng)程序注冊(cè)到USBcore中,然后就添加到驅(qū)動(dòng)鏈表中去了。其中usb_mouse_driver是描述鼠標(biāo)驅(qū)動(dòng)程序的結(jié)構(gòu)體。A已配置狀態(tài)(configuredstatus)之后話A當(dāng)鼠標(biāo)的設(shè)備、接口都添加到設(shè)備鏈表,并且鼠標(biāo)驅(qū)動(dòng)程序也添加到驅(qū)動(dòng)鏈表上去了,系統(tǒng)就進(jìn)入一種叫做已配置(configured)的狀態(tài)。要達(dá)到已配置狀態(tài),將經(jīng)歷復(fù)雜的過程,USBcore為USB設(shè)備奉獻(xiàn)著無怨無悔。在這個(gè)過程中,系統(tǒng)將會(huì)建立起該設(shè)備的的設(shè)備、配置、接口、設(shè)置、端點(diǎn)的描述信息,它們分別被usb_device、usb_configuration、usb_interface、usb_host_interfacesb_host_endpoin結(jié)構(gòu)體描述。設(shè)備達(dá)到已配置狀態(tài)后,首先當(dāng)然就要進(jìn)行USB驅(qū)動(dòng)程序和相應(yīng)接□的配對(duì),對(duì)于鼠標(biāo)設(shè)備來說則是鼠標(biāo)驅(qū)動(dòng)程序和鼠標(biāo)中的接□的配對(duì)OUSBcore會(huì)調(diào)用usb_device_match函數(shù),通過比較設(shè)備中的接□信息和USB驅(qū)動(dòng)程序中的id_table來初步?jīng)Q定該USB驅(qū)動(dòng)程序是不是跟相應(yīng)接□相匹配。通過這一道關(guān)卡后,USBcore會(huì)認(rèn)為這個(gè)設(shè)備應(yīng)該由這個(gè)驅(qū)動(dòng)程序負(fù)責(zé)。然而,僅僅這一步是不夠的,接著,將會(huì)調(diào)用USB驅(qū)動(dòng)程序中的probe函數(shù)對(duì)相應(yīng)接口進(jìn)行進(jìn)一步檢查。如果該驅(qū)動(dòng)程序確實(shí)適合設(shè)備接□,對(duì)設(shè)備做一些初始化工作,分配urb準(zhǔn)備數(shù)據(jù)傳輸。當(dāng)鼠標(biāo)設(shè)備在用戶空間打開時(shí),將提交probe函數(shù)構(gòu)建的urb請(qǐng)求塊,urb將開始為傳送數(shù)據(jù)而忙碌了。urb請(qǐng)求塊就像一個(gè)裝東西的袋子”USB驅(qū)動(dòng)程序把空袋子”是交給USBcore,然后再交給主控制器,主控制器把數(shù)據(jù)放入這個(gè)袋子”后再將裝滿數(shù)據(jù)的袋子”通過USBcore交還給USB驅(qū)動(dòng)程序,這樣一次數(shù)據(jù)傳輸就完成了。以下是完全注釋后的鼠標(biāo)驅(qū)動(dòng)程序代碼usbmouse.cviewplaincopytoclipboardprint?/* *$Id:usbmouse.c,v1.152001/12/2710:37:41vojtechExp$ * * Copyright(c)1999-200bjUechPavlik * * USBHIDBPMousesupport */ #include #include #include #include A#include A#include 入 入/* A*VersionInformation A*/ A#defineDRIVER_VERSION"vl.6" A#defineDRIVER_AUTHOR"VojtechPavlik" A#defineDRIVER_DESC"USBHIDBootProtocolmousedriver" A#defineDRIVER_LICENSE"GPL" 入 入MODULE_AUTHOR(DRIVER_AUTHOR); 入MODULE_DESCRIPTION(DRIVER_DESC); AMODULE_LICENSE(DRIVER_LICENSE); 入 入/* A*鼠標(biāo)結(jié)構(gòu)體,用于描述鼠標(biāo)設(shè)備。 A*/ Astructusb_mouse 入{ 入 /*鼠標(biāo)設(shè)備的名稱,包括生產(chǎn)廠商、產(chǎn)品類別、產(chǎn)品等信息*/ 入 charname[128]; 入 /*設(shè)備節(jié)點(diǎn)名稱*/ 入 charphys[64]; 入 /*USB鼠標(biāo)是一種USB設(shè)備,需要內(nèi)嵌一個(gè)USB設(shè)備結(jié)構(gòu)體來描述其USB屬性*/ 入 structusb_device*usbdev; 入 /*USB鼠標(biāo)同時(shí)又是一種輸入設(shè)備,需要內(nèi)嵌一個(gè)輸入設(shè)備結(jié)構(gòu)體來描述其輸入設(shè)備的屬性*/ 入 structinput_dev*dev; 入 /*URB請(qǐng)求包結(jié)構(gòu)體,用于傳送數(shù)據(jù)*/ 入 structurb*irq; 入 /*普通傳輸用的地址*/ 入 signedchar*data; 入 /*dma傳輸用的地址*/ 入 dma_addr_tdata_dma; Aj; 入 入/* A*urb回調(diào)函數(shù),在完成提交urb后,urb回調(diào)函數(shù)將被調(diào)用。 A*此函數(shù)作為usb_fill_int_urb函數(shù)的形參,為構(gòu)建的urb制定的回調(diào)函數(shù)。 A*/ Astaticvoidusb_mouse_irq(structurb*urb) 入{ 入 /* 入 *urb中的context指針用于為USB驅(qū)動(dòng)程序保存一些數(shù)據(jù)。比如在這個(gè)回調(diào)函數(shù)的形參沒有傳遞在probe 入 *中為mouse結(jié)構(gòu)體分配的那塊內(nèi)存的地址指針,而又需要用到那塊內(nèi)存區(qū)域中的數(shù)據(jù),context指針則幫了 入 *大忙了! 入 *在填充urb時(shí)將context指針指向mouse結(jié)構(gòu)體數(shù)據(jù)區(qū),在這又創(chuàng)建一個(gè)局部mouse指針指向在probe 入 *函數(shù)中為mouse申請(qǐng)的那塊內(nèi)存,那塊內(nèi)存保存著非常重要數(shù)據(jù)。 入 *當(dāng)urb通過USBcore提交給he之后,如果結(jié)果正常,mouse->data指向的內(nèi)存區(qū)域?qū)⒈4嬷髽?biāo)的按鍵 入 *和移動(dòng)坐標(biāo)信息,系統(tǒng)則依靠這些信息對(duì)鼠標(biāo)的行為作出反應(yīng)。 入 *mouse中內(nèi)嵌的dev指針,指向input_dev所屬于的內(nèi)存區(qū)域。 入 */ 入 structusb_mouse*mouse=urb->context; 入 signedchar*data=mouse->data; 入 structinput_dev*dev=mouse->dev; 入 intstatus; 入 入 /* 入 *status值為0表示urb成功返回,直接跳出循環(huán)把鼠標(biāo)事件報(bào)告給輸入子系統(tǒng)。 入 *ECONNRESET出錯(cuò)信息表示urb被usb_unlink_urb函數(shù)給unlink了,ENOENT出錯(cuò)信息表示urb被 入 *usb_kill_urb函數(shù)給kill了。usb_kill_urb表示徹底結(jié)束urb的生命周期,而usb_unlink_urb則 入 *是停止urb,這個(gè)函數(shù)不等urb完全終止就會(huì)返回給回調(diào)函數(shù)。這在運(yùn)行中斷處理程序時(shí)或者等待某自旋鎖 入 *時(shí)非常有用,在這兩種情況下是不能睡眠的,而等待一個(gè)urb完全停止很可能會(huì)出現(xiàn)睡眠的情況。 入 *ESHUTDOWN這種錯(cuò)誤表示USB主控制器驅(qū)動(dòng)程序發(fā)生了嚴(yán)重的錯(cuò)誤,或者提交完urb的一瞬間設(shè)備被拔出。 入 *遇見除了以上三種錯(cuò)誤以外的錯(cuò)誤,將申請(qǐng)重傳urb。 入 */ 入 switch(urb->status) 入 { 入 case0: /*success*/ 入 break; 入 case-ECONNRESET: /*unlink*/ 入 case-ENOENT: 入 case-ESHUTDOWN: 入 return; 入 /*-EPIPE: shouldclearthehalt*/ 入 default: /*error*/ 入 gotoresubmit; 入 } 入 入 /* 入 *向輸入子系統(tǒng)匯報(bào)鼠標(biāo)事件情況,以便作出反應(yīng)。 入 *data數(shù)組的第0個(gè)字節(jié):bit0、1、2、3、4分別代表左、右、中、SIDE、EXTRA鍵的按下情況; 入 *data數(shù)組的第1個(gè)字節(jié):表示鼠標(biāo)的水平位移; 入 *data數(shù)組的第2個(gè)字節(jié):表示鼠標(biāo)的垂直位移; 入 *data數(shù)組的第3個(gè)字節(jié):REL_WHEEL位移。 入 */ 入 input_report_key(dev,BTN_LEFT, data[0]&0x01); 入 input_report_key(dev,BTN_RIGHT, data[0]&0x02); 入 input_report_key(dev,BTN_MIDDLE,data[0]&0x04); 入 input_report_key(dev,BTN_SIDE, data[0]&0x08); 入 input_report_key(dev,BTN_EXTRA, data[0]&0x10); 入 input_report_rel(dev,REL_X, data[1]); 入 input_report_rel(dev,REL_Y, data[2]); 入 input_report_rel(dev,REL_WHEEL,data[3]); 入 入 /* 入 *這里是用于事件同步。上面幾行是一次完整的鼠標(biāo)事件,包括按鍵信息、絕對(duì)坐標(biāo)信息和滾輪信息,輸入子 入 *系統(tǒng)正是通過這個(gè)同步信號(hào)來在多個(gè)完整事件報(bào)告中區(qū)分每一次完整事件報(bào)告。示意如下: 入 *按鍵信息坐標(biāo)位移信息滾輪信息EV_SYCI按鍵信息坐標(biāo)位移信息滾輪信息EV_SYC... 入 */ 入 input_sync(dev); 入 入 /* 入 *系統(tǒng)需要周期性不斷地獲取鼠標(biāo)的事件信息,因此在urb回調(diào)函數(shù)的末尾再次提交urb請(qǐng)求塊,這樣又會(huì) 入 *調(diào)用新的回調(diào)函數(shù),周而復(fù)始。 入 *在回調(diào)函數(shù)中提交urb一定只能是GFP_ATOMIC優(yōu)先級(jí)的,因?yàn)閡rb回調(diào)函數(shù)運(yùn)行于中斷上下文中,在提 入 *交urb過程中可能會(huì)需要申請(qǐng)內(nèi)存、保持信號(hào)量,這些操作或許會(huì)導(dǎo)致USBcore睡眠,一切導(dǎo)致睡眠的行 入 *為都是不允許的。 入 */ Aresubmit: 入 status=usb_submit_urb(urb,GFP_ATOMIC); 入 if(status) A err("can'tresubmitintr,%s-%s/inputO,status%d", 入 mouse->usbdev->bus->bus_name, 入 mouse->usbdev->devpath,status); Aj 入 入/* A*打開鼠標(biāo)設(shè)備時(shí),開始提交在probe函數(shù)中構(gòu)建的urb,進(jìn)入urb周期。 A*/ Astaticintusb_mouse_open(structinput_dev*dev) 入{ 入 structusb_mouse*mouse=dev->private; 入 入 mouse->irq->dev=mouse->usbdev; 入 if(usb_submit_urb(mouse->irq,GFP_KERNEL)) 入 return-EI0; 入 入 return0; Aj 入 入/* A*關(guān)閉鼠標(biāo)設(shè)備時(shí),結(jié)束urb生命周期。 A*/ Astaticvoidusb_mouse_close(structinput_dev*dev) 入{ 入 structusb_mouse*mouse=dev->private; 入 入 usb_kill_urb(mouse->irq); Aj 入 入/* A*驅(qū)動(dòng)程序的探測(cè)函數(shù) A*/ Astaticintusb_mouse_probe(structusb_interface*intf,conststructusb_device_id*id) 入{ 入 /* 入 *接口結(jié)構(gòu)體包含于設(shè)備結(jié)構(gòu)體中,interface_to_usbdev是通過接口結(jié)構(gòu)體獲得它的設(shè)備結(jié)構(gòu)體。 入 *usb_host_interface是用于描述接口設(shè)置的結(jié)構(gòu)體,內(nèi)嵌在接口結(jié)構(gòu)體usb_interface中。 入 *usb_endpoint_descriptor是端點(diǎn)描述符結(jié)構(gòu)體,內(nèi)嵌在端點(diǎn)結(jié)構(gòu)體usb_host_endpoint中,而端點(diǎn) 入 *結(jié)構(gòu)體內(nèi)嵌在接口設(shè)置結(jié)構(gòu)體中。 入 */ 入 structusb_device*dev=interface_to_usbdev(intf); 入 structusb_host_interface*interface; 入 structusb_endpoint_descriptor*endpoint; 入 structusb_mouse*mouse; 入 structinput_dev*input_dev; 入 intpipe,maxp; 入 入 interface=intf->cur_altsetting; 入 入 /*鼠標(biāo)僅有一個(gè)interrupt類型的in端點(diǎn),不滿足此要求的設(shè)備均報(bào)錯(cuò)*/ 入 if(interface->desc.bNumEndpoints!=l) 入 return-ENODEV; 入 入 endpoint=&interface->endpoint[0].desc; 入 if(!usb_endpoint_is_int_in(endpoint)) 入 return-ENODEV; 入 入 /* 入 *返回對(duì)應(yīng)端點(diǎn)能夠傳輸?shù)淖畲蟮臄?shù)據(jù)包,鼠標(biāo)的返回的最大數(shù)據(jù)包為4個(gè)字節(jié),數(shù)據(jù)包具體內(nèi)容在urb 入 *回調(diào)函數(shù)中有詳細(xì)說明。 入 */ 入 pipe=usb_rcvintpipe(dev,endpoint->bEndpointAddress); 入 maxp=usb_maxpacket(dev,pipe,usb_pipeout(pipe)); 入 入 /*為mouse設(shè)備結(jié)構(gòu)體分配內(nèi)存*/ 入 mouse=kzalloc(sizeof(structusb_mouse),GFP_KERNEL); 入 /*input_dev*/ 入 input_dev=input_allocate_device(); 入 if(!mouseII!input_dev) 入 gotofaill; 入 入 /* 入 *申請(qǐng)內(nèi)存空間用于數(shù)據(jù)傳輸,data為指向該空間的地址,data_dma則是這塊內(nèi)存空間的dma映射, 入 *即這塊內(nèi)存空間對(duì)應(yīng)的dma地址。在使用dma傳輸?shù)那闆r下,則使用data_dma指向的dma區(qū)域, 入 *否則使用data指向的普通內(nèi)存區(qū)域進(jìn)行傳輸。 入 *GFP_ATOMIC表示不等待,GFP_KERNEL是普通的優(yōu)先級(jí),可以睡眠等待,由于鼠標(biāo)使用中斷傳輸方式, 入 *不允許睡眠狀態(tài),data又是周期性獲取鼠標(biāo)事件的存儲(chǔ)區(qū),因此使用GFP_ATOMIC優(yōu)先級(jí),如果不能 入 *分配到內(nèi)存則立即返回0。 入 */ 入 mouse->data=usb_buffer_alloc(dev,8,GFP_ATOMIC,&mouse->data_dma); 入 if(!mouse->data) 入 gotofaill; 入 入 /* 入 *為urb結(jié)構(gòu)體申請(qǐng)內(nèi)存空間,第一個(gè)參數(shù)表示等時(shí)傳輸時(shí)需要傳送包的數(shù)量,其它傳輸方式則為0。 入 *申請(qǐng)的內(nèi)存將通過下面即將見到的usb_fill_int_urb函數(shù)進(jìn)行填充。 入 */ 入 mouse->irq=usb_alloc_urb(0,GFP_KERNEL); 入 if(!mouse->irq) 入 gotofail2; 入 入 /*填充usb設(shè)備結(jié)構(gòu)體和輸入設(shè)備結(jié)構(gòu)體*/ 入 mouse->usbdev=dev; 入 mouse->dev=input_dev; 入 入 /*獲取鼠標(biāo)設(shè)備的名稱*/ 入 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), 入 "USBHIDBPMouse%04x:%04x", 入 lel6_to_cpu(dev->descriptor.idVendor), 入 le16_to_cpu(dev->descriptor.idProduct)); 入 入 /* 入 *填充鼠標(biāo)設(shè)備結(jié)構(gòu)體中的節(jié)點(diǎn)名。usb_make_path用來獲取USB設(shè)備在Sysfs中的路徑,格式 入 *為:usb-usb總線號(hào)-路徑名。 入 */ 入 usb_make_path(dev,mouse->phys,sizeof(mouse->phys)); 入 strlcat(mouse->phys,"/input0",sizeof(mouse->phys)); 入 入 /*將鼠標(biāo)設(shè)備的名稱賦給鼠標(biāo)設(shè)備內(nèi)嵌的輸入子系統(tǒng)結(jié)構(gòu)體*/ 入 input_dev->name=mouse->name; 入 /*將鼠標(biāo)設(shè)備的設(shè)備節(jié)點(diǎn)名賦給鼠標(biāo)設(shè)備內(nèi)嵌的輸入子系統(tǒng)結(jié)構(gòu)體*/ 入 input_dev->phys=mouse->phys; 入 /* 入 *input_dev中的input_id結(jié)構(gòu)體,用來存儲(chǔ)廠商、設(shè)備類型和設(shè)備的編號(hào),這個(gè)函數(shù)是將設(shè)備描述符 入 *中的編號(hào)賦給內(nèi)嵌的輸入子系統(tǒng)結(jié)構(gòu)體 入 */ 入 usb_to_input_id(dev,&input_dev->id); 入 /*cdev是設(shè)備所屬類別(classdevice)*/ 入 input_dev->cdev.dev=&intf->dev; 入 入 /*evbit用來描述事件,EV_KEY是按鍵事件,EV_REL是相對(duì)坐標(biāo)事件*/ 入 input_dev->evbit[O]=BIT(EV_KEY)IBIT(EV_REL); 入 /*keybit表示鍵值,包括左鍵、右鍵和中鍵*/ 入 input_dev->keybit[LONG(BTN_MOUSE)]=BIT(BTN_LEFT)IBIT(BTN_RIGHT)IBIT(BTN_MIDDLE); 入 /*relbit用于表示相對(duì)坐標(biāo)值*/ 入 input_dev->relbit[O]=BIT(REL_X)IBIT(REL_Y); 入 /*有的鼠標(biāo)還有其它按鍵*/ 入 input_dev->keybit[LONG(BTN_MOUSE)]I=BIT(BTN_SIDE)IBIT(BTN_EXTRA); 入 /*中鍵滾輪的滾動(dòng)值*/ 入 input_dev->relbit[O]I=BIT(REL_WHEEL); 入 入 /*input_dev的private數(shù)據(jù)項(xiàng)用于表示當(dāng)前輸入設(shè)備的種類,這里將鼠標(biāo)結(jié)構(gòu)體對(duì)象賦給它*/ 入 input_dev->private=mouse; 入 /*填充輸入設(shè)備打開函數(shù)指針*/ 入 input_dev->open=usb_mouse_open; 入 /*填充輸入設(shè)備關(guān)閉函數(shù)指針*/ 入 input_dev->close=usb_mouse_close; 入 入 /* 入 *填充構(gòu)建urb,將剛才填充好的mouse結(jié)構(gòu)體的數(shù)據(jù)填充進(jìn)urb結(jié)構(gòu)體中,在open中遞交urb。 入 *當(dāng)urb包含一個(gè)即將傳輸?shù)腄MA緩沖區(qū)時(shí)應(yīng)該設(shè)置URB_NO_TRANSFER_DMA_MAP。USB核心使用 入 *transfer_dma變量所指向的緩沖區(qū),而不是transfer_buffer變量所指向的。 入 *URB_NO_SETUP_DMA_MAP用于Setup包,URB_NO_TRANSFER_DMA_MAP用于所有Data包。 入 */ 入 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_flags1=URB_NO_TRANSFER_DMA_MAP; 入 入 /*向系統(tǒng)注冊(cè)輸入設(shè)備*/ 入 input_register_device(mouse->dev); 入 入 /* 入 *—般在probe函數(shù)中,都需要將設(shè)備相關(guān)信息保存在一個(gè)usb_interface結(jié)構(gòu)體中,以便以后通過 入 *usb_get_intfdata獲取使用。這里鼠標(biāo)設(shè)備結(jié)構(gòu)體信息將保存在intf接口結(jié)構(gòu)體內(nèi)嵌的設(shè)備結(jié)構(gòu)體中 入 *的driver_data數(shù)據(jù)成員中,即intf->dev->dirver_data=mouse。 入 */ 入 usb_set_intfdata(intf,mouse); 入 return0; 入 Afail2: usb_buffer_free(dev,8,mouse->data,mouse->data_dma); 入faill: input_free_device(input_dev); 入 kfree(mouse); 入 return-ENOMEM; Aj 入 入/* A*鼠標(biāo)設(shè)備拔出時(shí)的處理函數(shù) A*/ Astaticvoidusb_mouse_disconnect(structusb_interface*intf) 入{ 入 /*獲取鼠標(biāo)設(shè)備結(jié)構(gòu)體*/ 入 structusb_mouse*mouse=usb_get_intfdata(intf); 入 入 /*intf->dev->dirver_data=NULL,將接口結(jié)構(gòu)體中的鼠標(biāo)設(shè)備指針置空。*/ 入 usb_set_intfdata(intf,NULL); 入 if(mouse) 入 { 入 /*結(jié)束urb生命周期*/ 入 usb_kill_urb(mouse->irq); 入 /*將鼠標(biāo)設(shè)備從輸入子系統(tǒng)中注銷*/ 入 input_unregister_device(mouse->dev); 入 /*釋放urb存儲(chǔ)空間*/ 入 usb_free_urb(mouse->irq); 入 /*釋放存放鼠標(biāo)事件的data存儲(chǔ)空間*/ 入 usb_buffer_free(interface_to_usbdev(intf),8,mouse->data,mouse->data_dma); 入 /*釋放存放鼠標(biāo)結(jié)構(gòu)體的存儲(chǔ)空間*/ 入 kfree(mouse); 入 } Aj 入 入/* A*usb_device_id結(jié)構(gòu)體用于表示該驅(qū)動(dòng)程序所支
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 國(guó)內(nèi)擔(dān)保貸款合同示范
- 企業(yè)承包經(jīng)營(yíng)合同的環(huán)保要求
- 2024公眾號(hào)搭建合同
- 2024融資服務(wù)合同范文
- 集體土地上房屋拆遷補(bǔ)償標(biāo)準(zhǔn)
- 2024終止合同協(xié)議書
- 2024水馬購買協(xié)議合同
- 建筑項(xiàng)目施工管理協(xié)議書
- 2024年企業(yè)知識(shí)產(chǎn)權(quán)歸屬協(xié)議書
- 資金管理與賬戶監(jiān)督合同
- 2021年大唐集團(tuán)招聘筆試試題及答案
- DBJ53/T-39-2020 云南省民用建筑節(jié)能設(shè)計(jì)標(biāo)準(zhǔn)
- 2022版義務(wù)教育數(shù)學(xué)課程標(biāo)準(zhǔn)解讀課件PPT模板
- 實(shí)驗(yàn)五 PCR擴(kuò)增課件
- 馬拉松運(yùn)動(dòng)醫(yī)療支援培訓(xùn)課件
- 中醫(yī)藥宣傳手冊(cè)
- 不良資產(chǎn)處置盡職指引
- 人教部編版七年級(jí)歷史上冊(cè)第19課 北魏政治和北方民族大交融課件(23張PPT)
- 機(jī)械設(shè)備定期檢查維修保養(yǎng)使用臺(tái)賬
- 麗聲北極星分級(jí)繪本第四級(jí)上 Stop!Everyone Stop!教學(xué)設(shè)計(jì)
- 小學(xué)科學(xué)教育科學(xué)三年級(jí)上冊(cè)天氣《認(rèn)識(shí)氣溫計(jì)》教學(xué)設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論