struct usb_host_config
--276-->软件config对象包含的硬件config对象
--278-->config的名称
--282-->这个config上关联的Interface Association Descriptor
--283-->这个config上关联的下一级的软件interface数组,
下面这个就是与驱动直接匹配的描述
160 struct usb_interface { 163 struct usb_host_interface *altsetting; 165 struct usb_host_interface *cur_altsetting; 167 unsigned num_altsetting; /* number of alternate settings */ 171 struct usb_interface_assoc_descriptor *intf_assoc; 173 int minor; 175 enum usb_interface_condition condition; /* state of binding */ 176 unsigned sysfs_files_created:1; /* the sysfs attributes exist */ 177 unsigned ep_devs_created:1; /* endpoint "devices" exist */ 178 unsigned unregistering:1; /* unregistration is in progress */ 179 unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */ 180 unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ 181 unsigned needs_binding:1; /* needs delayed unbind/rebind */ 182 unsigned reset_running:1; 183 unsigned resetting_device:1; /* true: bandwidth alloc after reset */ 185 struct device dev; /* interface specific device info */ 186 struct device *usb_dev; 187 atomic_t pm_usage_cnt; /* usage counter for autosuspend */ 188 struct work_struct reset_ws; /* for resets in atomic context */ 189 };struct usb_interface
--163-->这个interface包含的所有的setting
--164-->这个interface当前正在使用的setting
--165-->如果这个interface与一个使用了主设备号的驱动绑定了, 这个域就是interface的次设备号; 反之则没用. 驱动应该在probe中设置这个参数
struct usb_host_interface
--78-->这个interface对应的硬件interface对象
--86-->拥有的描述软件endpoint信息的usb_host_endpoint数组
--88-->interface名称
endpoint是USB设备IO的基本单元
64 struct usb_host_endpoint { 65 struct usb_endpoint_descriptor desc; 66 struct usb_ss_ep_comp_descriptor ss_ep_comp; 67 struct list_head urb_list; 68 void *hcpriv; 69 struct ep_device *ep_dev; /* For sysfs info */ 71 unsigned char *extra; /* Extra descriptors */ 72 int extralen; 73 int enabled; 74 };struct usb_host_endpoint
--65-->这个usb_host_endpoint对应的硬件endpoint信息
--67-->读写这个endpoint的usb链表, 由usb核心层(drivers/usb/core/file.c)维护
--73-->这个endpoint是否被使能了
每一个硬件信息对象都包含在一个软件信息对象中, 而软件信息对象是层层包含的, 所以虽然驱动是基于interface描述的, 但是我们可以使用"list_entry()"很容易的向上找到config和device描述, 使用其中的域很容易的找到endpoint描述, 这9个描述设备的结构关系如下图所示:
urb与platform或i2c总线不同的是,usb总线不允许设备发起通信,所以作为设备驱动, 只有将需要的"材料"准备好经由核心层提交到usb控制器驱动,让控制器驱动带着这些"材料"去轮询设备并将应答带回。这些"材料"就是urb和相应的注册参数。当usb_driver和usb设备匹配上后,我们准备一个urb对象通过usb_fill_int_urb()/_bulk_/_control_注册到总线,并在合适的时机通过usb_submit_urb向控制器驱动发出发送这个urb对象的命令,总线的控制器驱动收到我们的发送命令之后,会根据我们注册时设置的周期不断向匹配的设备发送请求,如果子设备响应了我们的请求,控制器驱动就会将我们注册的urb对象填充好,并回调我们的注册函数。
对于海量存储USB设备,如果要让设备正常工作, 除了这些流程,还需要加上对缓存区的管理,这部分我们下篇说。