Linux USB 鼠標(biāo)驅(qū)動(dòng)程序詳解-2_第1頁
Linux USB 鼠標(biāo)驅(qū)動(dòng)程序詳解-2_第2頁
Linux USB 鼠標(biāo)驅(qū)動(dòng)程序詳解-2_第3頁
Linux USB 鼠標(biāo)驅(qū)動(dòng)程序詳解-2_第4頁
Linux USB 鼠標(biāo)驅(qū)動(dòng)程序詳解-2_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論