Linux USB子系统

参考文章:
USB底层协议

相关数据如下:

//这里数据成员并没有完全列出
struct usb_device{                      //usb设备
    struct device dev;
    char        devpath[16];
    u8 portnum;
    struct usb_host_endpoint ep0;
    struct usb_host_endpoint *ep_in[16];
    struct usb_host_endpoint *ep_out[16];
    struct usb_bus *bus;
    struct usb_device *parent;
    struct list_head filelist;  
};
struct usb_host_endpoint{               //usb端点
    struct usb_endpoint_descriptor      desc;
    struct list_head        urb_list;
    void                *hcpriv;
}
struct usb_hcd{                         //usb主机控制器驱动
    struct usb_bus      self;           //usb主机控制器对应的usb总线
    struct kref         kref;           //引用计数
};
struct usb_bus{                         //usb总线
    struct device *controller;      /* host/master side hardware */
    int busnum; 
};
struct usb_ctrlrequest{             //usb 控制请求
    //bit7:data transaction 阶段的方向bit6-bit5:request type bit1-bit0:请求针对是设备,接口还是端点
    __u8 bRequestType;
    __u8 bRequest;
    __le16 wValue;
    __le16 wIndex;
    __le16 wLength;
}__attribute((packed));
static inline struct usb_hcd *bus_to_hcd(struct usb_bus *bus)
{
    return container_of(bus, struct usb_hcd, self);
}
//增加usb主机控制器的引用计数
struct usb_hcd *usb_get_hcd (struct usb_hcd *hcd)
{
    if (hcd)
        kref_get (&hcd->kref);
    return hcd;
}
struct usb_device *usb_alloc_dev(struct usb_device *parent, \
                                            struct usb_bus *bus,        \
                                            unsigned portl)
{
    struct usb_device *dev;
    dev = kzalloc(sizeof(*dev),GFP_KERNEL);

    if(!usb_get_hcd(bus_to_hcd(bus))){};

    device_initialize(&dev->dev);
    dev->dev.bus = & usb_bus_type;//总线类型
    dev->dev.type = & usb_device_type;
    dev->dev.dma_mask = bus->controller->dma_mask;
    dev->state = USB_STATE_ATTACHED;

    INIT_LIST_HEAD(&dev->ep0.urb_list);
    dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
    dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
    dev->ep_in[0] = dev->ep_out[0] = &dev->ep0;

    if (unlikely(!parent)) {//根集线器与
        dev->devpath[0] = '0';
        dev->dev.parent = bus->controller;
        sprintf(dev->dev.bus_id,"usb%d",bus->busnum);
    }
    else{
        if (parent->devpath[0] == '0') {  //插在根集线器
            snprintf(dev->devpath, sizeof dev->devpath,
                "%d", port1);
        }else{
            snprintf(dev->devpath, sizeof dev->devpath,
                "%s.%d", parent->devpath, port1);
        }
        dev->dev.parent = &parent->dev;
        sprintf(dev->dev.bus_id[0],"%d-%s",bus->busnum,dev->devpath);
    }
    dev->portnum = port1;
    dev->bus = bus;
    dev->parent = parent;
    INIT_LIST_HEAD(&dev->filelist);
    //电源管理暂时忽略
    return dev;
}

设备连接上之后hub设置状态(Powered),hub会发出reset信号,复位usb设备使其进入Default状态。这是hub会获得设备的速度与端点0的处理的最大数据长度,对于高速时64字节,对于低速8 字节全速是8,16,32,64中的一个。此时开始设置地址。给设备发出SET_ADDRESS请求调用函数usb_control_msg

int usb_control_msg(struct usb_device *dev,unsigned pipe,__u8 request \
                        __u8 requesttype,__u16 value,__u16 index,\
                        void *data,__u16 size,int timeout)
{
    struct usb_ctrlrequest *dr;

    dr = kmalloc(sizeof(struct usb_ctrlrequest),GFP_NOIO);

    dr->bRequestType = requesttype;
    dr->bRequest = request;
    dr->wValue = cpu_to_le16(value);
    dr->wIndex = cpu_to_le16(index);
    dr->wLength = cpu_to_le16(size);

    ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);

    kfree(dr);

    return ret;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值