乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Linux設(shè)備驅(qū)動(dòng)程序?qū)W習(xí)(17)-USB 驅(qū)動(dòng)程序(二)

       lchjczw 2012-03-19
      Linux設(shè)備驅(qū)動(dòng)程序?qū)W習(xí)(17)-USB 驅(qū)動(dòng)程序(二)
      內(nèi)核使用2.6.29.4
      USB設(shè)備其實(shí)很復(fù)雜,但是Linux內(nèi)核提供了一個(gè)稱(chēng)為USB core的子系統(tǒng)來(lái)處理了大部分的復(fù)雜工作,所以這里所描述的是驅(qū)動(dòng)程序和USB core之間的接口。
      在USB設(shè)備組織結(jié)構(gòu)中,從上到下分為設(shè)備(device)、配置(config)、接口(interface)和端點(diǎn)(endpoint)四個(gè)層次。
      對(duì)于這四個(gè)層次的簡(jiǎn)單描述如下:
          設(shè)備通常具有一個(gè)或多個(gè)的配置
          配置經(jīng)常具有一個(gè)或多個(gè)的接口
          接口通常具有一個(gè)或多個(gè)的設(shè)置
          接口沒(méi)有或具有一個(gè)以上的端點(diǎn)

      設(shè)備
        很明顯,地代表了一個(gè)插入的USB設(shè)備,在內(nèi)核使用數(shù)據(jù)結(jié)構(gòu) struct usb_device來(lái)描述整個(gè)USB設(shè)備。(include/linux/usb.h)
        struct usb_device {
         int devnum; //設(shè)備號(hào),是在USB總線(xiàn)的地址
         char devpath [16]; //用于消息的設(shè)備ID字符串
         enum usb_device_state state; //設(shè)備狀態(tài):已配置、未連接等等
         enum usb_device_speed speed; //設(shè)備速度:高速、全速、低速或錯(cuò)誤
        
         struct usb_tt *tt; //處理傳輸者信息;用于低速、全速設(shè)備和高速HUB
         int ttport; //位于tt HUB的設(shè)備口
        
         unsigned int toggle[2]; //每個(gè)端點(diǎn)的占一位,表明端點(diǎn)的方向([0] = IN, [1] = OUT)  
         struct usb_device *parent; //上一級(jí)HUB指針
         struct usb_bus *bus; //總線(xiàn)指針
         struct usb_host_endpoint ep0; //端點(diǎn)0數(shù)據(jù)
         struct device dev; //一般的設(shè)備接口數(shù)據(jù)結(jié)構(gòu)
       
         struct usb_device_descriptor descriptor; //USB設(shè)備描述符
         struct usb_host_config *config; //設(shè)備的所有配置
         struct usb_host_config *actconfig; //被激活的設(shè)備配置
         struct usb_host_endpoint *ep_in[16]; //輸入端點(diǎn)數(shù)組
         struct usb_host_endpoint *ep_out[16]; //輸出端點(diǎn)數(shù)組
        
         char **rawdescriptors; //每個(gè)配置的raw描述符
        
         unsigned short bus_mA; //可使用的總線(xiàn)電流
         u8 portnum; //父端口號(hào)
         u8 level; //USB HUB的層數(shù)
        
         unsigned can_submit:1; //URB可被提交標(biāo)志
         unsigned discon_suspended:1; //暫停時(shí)斷開(kāi)標(biāo)志
         unsigned persist_enabled:1; //USB_PERSIST使能標(biāo)志
         unsigned have_langid:1; //string_langid存在標(biāo)志
         unsigned authorized:1;
         unsigned authenticated:1;
         unsigned wusb:1; //無(wú)線(xiàn)USB標(biāo)志
         int string_langid; //字符串語(yǔ)言ID
        
         /* static strings from the device */ //設(shè)備的靜態(tài)字符串
         char *product; //產(chǎn)品名
         char *manufacturer; //廠商名
         char *serial; //產(chǎn)品串號(hào)
        
         struct list_head filelist; //此設(shè)備打開(kāi)的usbfs文件
        #ifdef CONFIG_USB_DEVICE_CLASS
         struct device *usb_classdev; //用戶(hù)空間訪(fǎng)問(wèn)的為usbfs設(shè)備創(chuàng)建的USB類(lèi)設(shè)備
        #endif
        #ifdef CONFIG_USB_DEVICEFS
         struct dentry *usbfs_dentry; //設(shè)備的usbfs入口
        #endif
        
         int maxchild; //(若為HUB)接口數(shù)
         struct usb_device *children[USB_MAXCHILDREN];//連接在這個(gè)HUB上的子設(shè)備
         int pm_usage_cnt; //自動(dòng)掛起的使用計(jì)數(shù)
         u32 quirks;
         atomic_t urbnum; //這個(gè)設(shè)備所提交的URB計(jì)數(shù)
        
         unsigned long active_duration; //激活后使用計(jì)時(shí)
        #ifdef CONFIG_PM //電源管理相關(guān)
         struct delayed_work autosuspend; //自動(dòng)掛起的延時(shí)
         struct work_struct autoresume; //(中斷的)自動(dòng)喚醒需求
         struct mutex pm_mutex; //PM的互斥鎖 
       
         unsigned long last_busy; //最后使用的時(shí)間
         int autosuspend_delay;
         unsigned long connect_time; //第一次連接的時(shí)間
        
         unsigned auto_pm:1; //自動(dòng)掛起/喚醒
         unsigned do_remote_wakeup:1; //遠(yuǎn)程喚醒
         unsigned reset_resume:1; //使用復(fù)位替代喚醒
         unsigned autosuspend_disabled:1; //掛起關(guān)閉
         unsigned autoresume_disabled:1; //喚醒關(guān)閉
         unsigned skip_sys_resume:1; //跳過(guò)下個(gè)系統(tǒng)喚醒
        #endif
         struct wusb_dev *wusb_dev; //(如果為無(wú)線(xiàn)USB)連接到WUSB特定的數(shù)據(jù)結(jié)構(gòu)
        };
      配置
        
      一個(gè)USB設(shè)備可以有多個(gè)配置,并可在它們之間轉(zhuǎn)換以改變?cè)O(shè)備的狀態(tài)。比如一個(gè)設(shè)備可以通過(guò)下載固件(firmware)的方式改變?cè)O(shè)備的使用狀態(tài)(我
      感覺(jué)類(lèi)似FPGA或CPLD),那么USB設(shè)備就要切換配置,來(lái)完成這個(gè)工作。一個(gè)時(shí)刻只能有一個(gè)配置可以被激活。Linux使用結(jié)構(gòu) struct
      usb_host_config
      來(lái)描述USB配置。我們編寫(xiě)的USB設(shè)備驅(qū)動(dòng)通常不需要讀寫(xiě)這些結(jié)構(gòu)的任何值??稍趦?nèi)核源碼的文件include/linux/usb.h中找到對(duì)它們的
      描述。
      struct usb_host_config {
          struct usb_config_descriptor desc; //配置描述符
          char *string; /* 配置的字符串指針(如果存在) */
          struct usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS]; //配置的接口聯(lián)合描述符鏈表
          struct usb_interface *interface[USB_MAXINTERFACES]; //接口描述符鏈表
          struct usb_interface_cache *intf_cache[USB_MAXINTERFACES];
          unsigned char *extra; /* 額外的描述符 */
          int extralen;
      };
      接口
      USB
      端點(diǎn)被綁為接口,USB接口只處理一種USB邏輯連接。一個(gè)USB接口代表一個(gè)基本功能,每個(gè)USB驅(qū)動(dòng)控制一個(gè)接口。所以一個(gè)物理上的硬件設(shè)備可能需要
      一個(gè)以上的驅(qū)動(dòng)程序。這可以在“暈到死 差屁”系統(tǒng)中看出,有時(shí)插入一個(gè)USB設(shè)備后,系統(tǒng)會(huì)識(shí)別出多個(gè)設(shè)備,并安裝相應(yīng)多個(gè)的驅(qū)動(dòng)。
      USB 接口可以有其他的設(shè)置,它是對(duì)接口參數(shù)的不同選擇. 接口的初始化的狀態(tài)是第一個(gè)設(shè)置,編號(hào)為0。 其他的設(shè)置可以以不同方式控制獨(dú)立的端點(diǎn)。
      USB接口在內(nèi)核中使用 struct usb_interface 來(lái)描述。USB 核心將其傳遞給USB驅(qū)動(dòng),并由USB驅(qū)動(dòng)負(fù)責(zé)后續(xù)的控制。
      struct usb_interface {
          struct usb_host_interface *altsetting; /* 包含所有可用于該接口的可選設(shè)置的接口結(jié)構(gòu)數(shù)組。每個(gè) struct usb_host_interface 包含一套端點(diǎn)配置(即struct usb_host_endpoint結(jié)構(gòu)所定義的端點(diǎn)配置。這些接口結(jié)構(gòu)沒(méi)有特別的順序。*/
          struct usb_host_interface *cur_altsetting; /* 指向altsetting內(nèi)部的指針,表示當(dāng)前激活的接口配置*/
          unsigned num_altsetting; /* 可選設(shè)置的數(shù)量*/
          /* If there is an interface association descriptor then it will list the associated interfaces */
          struct usb_interface_assoc_descriptor *intf_assoc;
          int minor; /* 如果綁定到這個(gè)接口的 USB 驅(qū)動(dòng)使用 USB 主設(shè)備號(hào), 這個(gè)變量包含由 USB 核心分配給接口的次設(shè)備號(hào). 這只在一個(gè)成功的調(diào)用 usb_register_dev后才有效。*/
          /*以下的數(shù)據(jù)在我們寫(xiě)的驅(qū)動(dòng)中基本不用考慮,系統(tǒng)會(huì)自動(dòng)設(shè)置*/
          enum usb_interface_condition condition; /* state of binding */
          unsigned is_active:1; /* the interface is not suspended */
          unsigned sysfs_files_created:1; /* the sysfs attributes exist */
          unsigned ep_devs_created:1; /* endpoint "devices" exist */
          unsigned unregistering:1; /* unregistration is in progress */
          unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
          unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */
          unsigned needs_binding:1; /* needs delayed unbind/rebind */
          unsigned reset_running:1;
          struct device dev; /* 接口特定的設(shè)備信息 */
          struct device *usb_dev;
          int pm_usage_cnt; /* usage counter for autosuspend */
          struct work_struct reset_ws; /* for resets in atomic context */
      };
      struct usb_host_interface {
          struct usb_interface_descriptor desc; //接口描述符
          struct usb_host_endpoint *endpoint; /* 這個(gè)接口的所有端點(diǎn)結(jié)構(gòu)體的聯(lián)合數(shù)組*/
          char *string; /* 接口描述字符串 */
          unsigned char *extra; /* 額外的描述符 */
          int extralen;
      };
      端點(diǎn)
      USB 通訊的最基本形式是通過(guò)一個(gè)稱(chēng)為端點(diǎn)的東西。一個(gè)USB端點(diǎn)只能向一個(gè)方向傳輸數(shù)據(jù)(從主機(jī)到設(shè)備(稱(chēng)為輸出端點(diǎn))或者從設(shè)備到主機(jī)(稱(chēng)為輸入端點(diǎn)))。端點(diǎn)可被看作一個(gè)單向的管道。
      一個(gè) USB 端點(diǎn)有 4 種不同類(lèi)型, 分別具有不同的數(shù)據(jù)傳送方式:
      控制CONTROL

      制端點(diǎn)被用來(lái)控制對(duì) USB 設(shè)備的不同部分訪(fǎng)問(wèn). 通常用作配置設(shè)備、獲取設(shè)備信息、發(fā)送命令到設(shè)備或獲取設(shè)備狀態(tài)報(bào)告。這些端點(diǎn)通常較小。每個(gè)
      USB 設(shè)備都有一個(gè)控制端點(diǎn)稱(chēng)為"端點(diǎn) 0", 被 USB 核心用來(lái)在插入時(shí)配置設(shè)備。USB協(xié)議保證總有足夠的帶寬留給控制端點(diǎn)傳送數(shù)據(jù)到設(shè)備.
      中斷INTERRUPT
      每當(dāng) USB 主機(jī)向設(shè)備請(qǐng)求數(shù)據(jù)時(shí),中斷端點(diǎn)以固定的速率傳送小量的數(shù)據(jù)。此為USB 鍵盤(pán)和鼠標(biāo)的主要的數(shù)據(jù)傳送方法。它還用以傳送數(shù)據(jù)到 USB 設(shè)備來(lái)控制設(shè)備。通常不用來(lái)傳送大量數(shù)據(jù)。USB協(xié)議保證總有足夠的帶寬留給中斷端點(diǎn)傳送數(shù)據(jù)到設(shè)備.
      批量BULK

      量端點(diǎn)用以傳送大量數(shù)據(jù)。這些端點(diǎn)常比中斷端點(diǎn)大得多. 它們普遍用于不能有任何數(shù)據(jù)丟失的數(shù)據(jù)。USB
      協(xié)議不保證傳輸在特定時(shí)間范圍內(nèi)完成。如果總線(xiàn)上沒(méi)有足夠的空間來(lái)發(fā)送整個(gè)BULK包,它被分為多個(gè)包進(jìn)行傳輸。這些端點(diǎn)普遍用于打印機(jī)、USB
      Mass Storage和USB網(wǎng)絡(luò)設(shè)備上。
      等時(shí)ISOCHRONOUS
      等時(shí)端點(diǎn)也批量傳送大量數(shù)據(jù), 但是這個(gè)數(shù)據(jù)不被保證能送達(dá)。這些端點(diǎn)用在可以處理數(shù)據(jù)丟失的設(shè)備中,并且更多依賴(lài)于保持持續(xù)的數(shù)據(jù)流。如音頻和視頻設(shè)備等等。
      控制和批量端點(diǎn)用于異步數(shù)據(jù)傳送,而中斷和同步端點(diǎn)是周期性的。這意味著這些端點(diǎn)被設(shè)置來(lái)在固定的時(shí)間連續(xù)傳送數(shù)據(jù),USB 核心為它們保留了相應(yīng)的帶寬。
      端點(diǎn)在內(nèi)核中使用結(jié)構(gòu) struct usb_host_endpoint 來(lái)描述,它所包含的真實(shí)端點(diǎn)信息在另一個(gè)結(jié)構(gòu)中:struct usb_endpoint_descriptor(端點(diǎn)描述符,包含所有的USB特定數(shù)據(jù))。
      struct usb_host_endpoint {
          struct usb_endpoint_descriptor desc; //端點(diǎn)描述符
          struct list_head urb_list; //此端點(diǎn)的URB對(duì)列,由USB核心維護(hù)
          void *hcpriv;
          struct ep_device *ep_dev; /* For sysfs info */
          unsigned char *extra; /* Extra descriptors */
          int extralen;
          int enabled;
      };
      /*-------------------------------------------------------------------------*/
      /* USB_DT_ENDPOINT: Endpoint descriptor */
      struct usb_endpoint_descriptor {
          __u8 bLength;
          __u8 bDescriptorType;
          __u8 bEndpointAddress; /*這個(gè)特定端點(diǎn)的 USB 地址,這個(gè)8位數(shù)據(jù)包含端點(diǎn)的方向,結(jié)合位掩碼 USB_DIR_OUT 和 USB_DIR_IN 使用, 確定這個(gè)端點(diǎn)的數(shù)據(jù)方向。*/
          __u8 bmAttributes; //這是端點(diǎn)的類(lèi)型,位掩碼如下
          __le16 wMaxPacketSize; /*端點(diǎn)可以一次處理的最大字節(jié)數(shù)。驅(qū)動(dòng)可以發(fā)送比這個(gè)值大的數(shù)據(jù)量到端點(diǎn), 但是當(dāng)真正傳送到設(shè)備時(shí),數(shù)據(jù)會(huì)被分為 wMaxPakcetSize 大小的塊。對(duì)于高速設(shè)備, 通過(guò)使用高位部分幾個(gè)額外位,可用來(lái)支持端點(diǎn)的高帶寬模式。*/
          __u8 bInterval; //如果端點(diǎn)是中斷類(lèi)型,該值是端點(diǎn)的間隔設(shè)置,即端點(diǎn)的中斷請(qǐng)求間的間隔時(shí)間,以毫秒為單位
          /* NOTE: these two are _only_ in audio endpoints. */
          /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
          __u8 bRefresh;
          __u8 bSynchAddress;
      } __attribute__ ((packed));
      #define USB_DT_ENDPOINT_SIZE 7
      #define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
      /*
      * Endpoints
      */
      #define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress 端點(diǎn)的 USB 地址掩碼 */
      #define USB_ENDPOINT_DIR_MASK 0x80 /* in bEndpointAddress 數(shù)據(jù)方向掩碼 */
      #define USB_DIR_OUT 0 /* to device */
      #define USB_DIR_IN 0x80 /* to host */
      #define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* bmAttributes 的位掩碼*/
      #define USB_ENDPOINT_XFER_CONTROL 0
      #define USB_ENDPOINT_XFER_ISOC 1
      #define USB_ENDPOINT_XFER_BULK 2
      #define USB_ENDPOINT_XFER_INT 3
      #define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
      /*-------------------------------------------------------------------------*/
      USB 和 sysfs
      由于單個(gè) USB 物理設(shè)備的復(fù)雜性,設(shè)備在 sysfs 中的表示也非常復(fù)雜。物理 USB 設(shè)備(通過(guò) struct usb_device 表示)和單個(gè) USB 接口(由 struct usb_interface 表示)都作為單個(gè)設(shè)備出現(xiàn)在 sysfs 中,這是因?yàn)檫@兩個(gè)結(jié)構(gòu)都包含一個(gè) struct device結(jié)構(gòu)。以下內(nèi)容是我的USB鼠標(biāo)在 sysfs 中的目錄樹(shù):   
      /sys/devices/pci0000:00/0000:00:1a.0/usb3/3-1 表示 usb_device 結(jié)構(gòu))
      .
      |-- 3-1:1.0 (鼠標(biāo)所對(duì)應(yīng)的usb_interface)
      | |-- 0003:046D:C018.0003
      | | |-- driver -> ../../../../../../../bus/hid/drivers/generic-usb
      | | |-- power
      | | | `-- wakeup
      | | |-- subsystem -> ../../../../../../../bus/hid
      | | `-- uevent
      | |-- bAlternateSetting
      | |-- bInterfaceClass
      | |-- bInterfaceNumber
      | |-- bInterfaceProtocol
      | |-- bInterfaceSubClass
      | |-- bNumEndpoints
      | |-- driver -> ../../../../../../bus/usb/drivers/usbhid
      | |-- ep_81 -> usb_endpoint/usbdev3.4_ep81
      | |-- input
      | | `-- input6
      | | |-- capabilities
      | | | |-- abs
      | | | |-- ev
      | | | |-- ff
      | | | |-- key
      | | | |-- led
      | | | |-- msc
      | | | |-- rel
      | | | |-- snd
      | | | `-- sw
      | | |-- device -> ../../../3-1:1.0
      | | |-- event3
      | | | |-- dev
      | | | |-- device -> ../../input6
      | | | |-- power
      | | | | `-- wakeup
      | | | |-- subsystem -> ../../../../../../../../../class/input
      | | | `-- uevent
      | | |-- id
      | | | |-- bustype
      | | | |-- product
      | | | |-- vendor
      | | | `-- version
      | | |-- modalias
      | | |-- mouse1
      | | | |-- dev
      | | | |-- device -> ../../input6
      | | | |-- power
      | | | | `-- wakeup
      | | | |-- subsystem -> ../../../../../../../../../class/input
      | | | `-- uevent
      | | |-- name
      | | |-- phys
      | | |-- power
      | | | `-- wakeup
      | | |-- subsystem -> ../../../../../../../../class/input
      | | |-- uevent
      | | `-- uniq
      | |-- modalias
      | |-- power
      | | `-- wakeup
      | |-- subsystem -> ../../../../../../bus/usb
      | |-- supports_autosuspend
      | |-- uevent
      | `-- usb_endpoint
      | `-- usbdev3.4_ep81
      | |-- bEndpointAddress
      | |-- bInterval
      | |-- bLength
      | |-- bmAttributes
      | |-- dev
      | |-- device -> ../../../3-1:1.0
      | |-- direction
      | |-- interval
      | |-- power
      | | `-- wakeup
      | |-- subsystem -> ../../../../../../../../class/usb_endpoint
      | |-- type
      | |-- uevent
      | `-- wMaxPacketSize
      |-- authorized
      |-- bConfigurationValue
      |-- bDeviceClass
      |-- bDeviceProtocol
      |-- bDeviceSubClass
      |-- bMaxPacketSize0
      |-- bMaxPower
      |-- bNumConfigurations
      |-- bNumInterfaces
      |-- bcdDevice
      |-- bmAttributes
      |-- busnum
      |-- configuration
      |-- descriptors
      |-- dev
      |-- devnum
      |-- driver -> ../../../../../bus/usb/drivers/usb
      |-- ep_00 -> usb_endpoint/usbdev3.4_ep00
      |-- idProduct
      |-- idVendor
      |-- manufacturer
      |-- maxchild
      |-- power
      | |-- active_duration
      | |-- autosuspend
      | |-- connected_duration
      | |-- level
      | |-- persist
      | `-- wakeup
      |-- product
      |-- quirks
      |-- speed
      |-- subsystem -> ../../../../../bus/usb
      |-- uevent
      |-- urbnum
      |-- usb_endpoint
      | `-- usbdev3.4_ep00
      | |-- bEndpointAddress
      | |-- bInterval
      | |-- bLength
      | |-- bmAttributes
      | |-- dev
      | |-- device -> ../../../3-1
      | |-- direction
      | |-- interval
      | |-- power
      | | `-- wakeup
      | |-- subsystem -> ../../../../../../../class/usb_endpoint
      | |-- type
      | |-- uevent
      | `-- wMaxPacketSize
      `-- version
      38 directories, 91 files
          USB sysfs 設(shè)備命名方法是: root_hub-hub_port:config.interface
          隨著USB集線(xiàn)器層次的增加, 集線(xiàn)器端口號(hào)被添加到字符串中緊隨著鏈中之前的集線(xiàn)器端口號(hào)。對(duì)一個(gè) 2 層的樹(shù), 設(shè)備為: root_hub-hub_port-hub_port:config.interface ,以此類(lèi)推。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多