《Linux那些事儿之我是USB》我是U盘(16)冰冻三尺非一日之寒--总结

(1)
int usb_stor_probe1(struct us_data **pus,struct usb_interface *intf,const struct usb_device_id *id, struct us_unusual_dev *unusual_dev){
     
      result = associate_dev(us, intf);
       result = get_device_info(us, id, unusual_dev);
}


/* Associate our private data with the USB device */
static int associate_dev(struct us_data *us, struct usb_interface *intf)
{
    /* Fill in the device-related fields */
    us->pusb_dev = interface_to_usbdev(intf);
    us->pusb_intf = intf;
    us->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
    usb_stor_dbg(us, "Vendor: 0x%04x, Product: 0x%04x, Revision: 0x%04x\n",
             le16_to_cpu(us->pusb_dev->descriptor.idVendor),
             le16_to_cpu(us->pusb_dev->descriptor.idProduct),
             le16_to_cpu(us->pusb_dev->descriptor.bcdDevice));
    usb_stor_dbg(us, "Interface Subclass: 0x%02x, Protocol: 0x%02x\n",
             intf->cur_altsetting->desc.bInterfaceSubClass,
             intf->cur_altsetting->desc.bInterfaceProtocol);

    /* Store our private data in the interface */
    usb_set_intfdata(intf, us);  //&intf->dev->driver_data=us 保存私有数据到interface

    /* Allocate the control/setup and DMA-mapped buffers */
    us->cr = kmalloc(sizeof(*us->cr), GFP_KERNEL);
    if (!us->cr)
        return -ENOMEM;

    us->iobuf = usb_alloc_coherent(us->pusb_dev, US_IOBUF_SIZE,
            GFP_KERNEL, &us->iobuf_dma); // 申请内存 us->cr和us->iobuf都是指针,指向两段内存空间
    if (!us->iobuf) {
        usb_stor_dbg(us, "I/O buffer allocation failed\n");
        return -ENOMEM;
    }    
    return 0;
}

//&us->iobuf_dma,dma传输.此前我们都没有赋过值,这个函数调用之后被赋上值的,是dma_addr_t类型的变量,这个数据类型是Linux内核中专门为dma传输而准备的.为了支持dma传输,usb_alloc_coherent不仅仅是申请了地址,并且建立了dma映射,iobuf_dma就是记录着cr和iobuf的dma地址.


struct usb_interface {
     struct usb_host_interface *cur_altsetting; //设置
}

struct usb_host_interface {
    struct usb_interface_descriptor desc;
    int extralen;
    unsigned char *extra;   /* Extra descriptors */ 
    /* array of desc.bNumEndpoint endpoints associated with this
     * interface setting.  these will be in no particular order.
     */
    struct usb_host_endpoint *endpoint;  
    char *string;       /* iInterface string, if present */
}; 

struct usb_interface_descriptor {
    __u8  bLength;
    __u8  bDescriptorType;
    __u8  bInterfaceNumber; //bInterfaceNumber,一个设备可以有多个Interface,于是每一个Interface就有编号
    __u8  bAlternateSetting;
    __u8  bNumEndpoints;
    __u8  bInterfaceClass;
    __u8  bInterfaceSubClass;
    __u8  bInterfaceProtocol;
    __u8  iInterface;
} __attribute__ ((packed)); 
#define USB_DT_INTERFACE_SIZE       9

static inline void usb_set_intfdata(struct usb_interface *intf, void *data)
{   
    dev_set_drvdata(&intf->dev, data);
}

void *dev_get_drvdata(const struct device *dev)
{   
    if (dev && dev->p)
        return dev->p->driver_data;
    return NULL;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux技术芯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值