(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){
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;
}