启动主机控制器和根集线器之后,现在来注册根集线器
register_root_hub负责根集线器的注册
register_root_hub在/drivers/usb/core/hcd.c中
static int register_root_hub(struct usb_hcd *hcd)
{
struct device *parent_dev = hcd->self.controller;
struct usb_device *usb_dev = hcd->self.root_hub;
const int devnum = 1;
int retval;
//设置设备的设备号为1
usb_dev->devnum = devnum;
//uhci总线的设备计数器+1
usb_dev->bus->devnum_next = devnum + 1;
//初始化设备位表
memset (&usb_dev->bus->devmap.devicemap, 0,sizeof usb_dev->bus->devmap.devicemap);
//占用设备表的第1位
set_bit (devnum, usb_dev->bus->devmap.devicemap);
//设置设备状态为USB_STATE_ADDRESS
usb_set_device_state(usb_dev, USB_STATE_ADDRESS);
mutex_lock(&usb_bus_list_lock);
//设置端点0包的最大值
usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
//取得设备描述符
retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
//检测返回的描述符大小和设备描述符的大小是否一致
if (retval != sizeof usb_dev->descriptor)
{
mutex_unlock(&usb_bus_list_lock);
dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
usb_dev->dev.bus_id, retval);
return (retval < 0) ? retval : -EMSGSIZE;
}
//建立设备
retval = usb_new_device (usb_dev);
if (retval)
{
dev_err (parent_dev, "can't register root hub for %s, %d\n",usb_dev->dev.bus_id, retval);
}
mutex_unlock(&usb_bus_list_lock);
if (retval == 0)
{
spin_lock_irq (&hcd_root_hub_lock);
//设置注册标识为1
hcd->rh_registered = 1;
spin_unlock_irq (&hcd_root_hub_lock);
/* Did the HC die before the root hub was registered? */
if (hcd->state == HC_STATE_HALT)
usb_hc_died (hcd); /* This time clean up */
}
return retval;
}
usb_get_device_descriptor负责取得设备的设备描述符,设备描述符的结构如下
struct usb_device_descriptor {
__u8 bLength; //描述符的长度
__u8 bDescriptorType; //描述符的类型
__le16 bcdUSB; //表示usb设备所遵循的usb规范
__u8 bDeviceClass; //表示usb设备所属的标准设备类
__u8 bDeviceSubClass; //表示usb设备所属的标准设备子类
__u8 bDeviceProtocol; //表示usb设备所使用的设备类协议
__u8 bMaxPacketSize0; //表示0号端点包的最大大小
__le16 idVendor; //表示usb设备的生厂商id
__le16 idProduct; //表示usb设备的产品id
__le16 bcdDevice; //表示usb设备的版本号
__u8 iManufacturer; //表示生产商字符串描述符的索引值
__u8 iProduct; //表示产品字符串描述符的索引值
__u8 iSerialNumber; //表示设备序列号字符串描述符的索引值
__u8 bNumConfigurations; //表示usb设备的配置数
} __attribute__ ((packed));
usb_get_device_descriptor在/drivers/usb/core/messgae.c中
int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)
{
struct usb_device_descriptor *desc;
int ret;
if (size > sizeof(*desc))
return -EINVAL;
//分配设备描述符所需要的空间
desc = kmalloc(sizeof(*desc), GFP_NOIO);
if (!desc)
return -ENOMEM;
//取得描述符,类型为设备
ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);
if (ret >= 0)
//拷贝设备描述符到usb_device中
memcpy(&dev->descriptor, desc, size);
kfree(desc);
return ret;
}
usb_get_descripto的用途为取得描述符
usb_get_descriptor在/drivers/usb/core/messgae.c中
int usb_get_descriptor(struct usb_device *dev, unsigned char type,
unsigned char index, void *buf, int size)
{
int i;
int result;
//buf清0
memset(buf, 0, size); /* Make sure we parse really received data */
//重试3次
for (i = 0; i < 3; ++i)
{
/* retry on length 0 or error; some devices are flakey */
//发送控制消息
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(type << 8) + index, 0, buf, size,
USB_CTRL_GET_TIMEOUT);
if (result <= 0 && result != -ETIMEDOUT)
continue;
if (result > 1 && ((u8 *)buf)[1] != type)
{
result = -EPROTO;
continue;
}
break;
}
return result;
}
usb_control_msg的用途为发送控制消息
usb_control_msg在/drivers/usb/core/messgae.c中
int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
__u8 requesttype, __u16 value, __u16 index, void *data,
__u16 size, int timeout)
{
struct usb_ctrlrequest *dr;
int ret;
//为控制请求结构分配空间
dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
if (!dr)
return -ENOMEM;
//组建8字节的控制请求字段
dr->bRequestType = requesttype;
dr->bRequest = request;
dr->wValue = cpu_to_le16p(&value);
dr->wIndex = cpu_to_le16p(&index);
dr->wLength = cpu_to_le16p(&size);
/* dbg("usb_control_msg"); */
//发送控制消息
ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
kfree(dr);
return ret;
}
这8字节的数据眼熟么?~ 还记得在前面提到的setup事务中的数据包的内容么? 正是这8字节的数据,眼泪啊,到了这里,终于接触到传输了
usb_internal_control_msg的用途为组建一个urb结构并发送他,urb这个结构在usb设备插入前都不会讲解,因为在host自己对自己的访问中,urb只起到了一个花瓶的作用,走走过场,并没有真正发送出去
usb_internal_control_msg在/drivers/usb/core/messgae.c中
static int usb_internal_control_msg(struct usb_device *usb_dev,
unsigned int pipe,
struct usb_ctrlrequest *cmd,
void *data, int len, int timeout)
{
struct urb *urb;
int retv;