??????????usb_device????????????????????usb_skel????????????????????????????????????????usb_skel????usb?豸?????????????????????Щ????usb_interface_descriptor??????????????????y??????????????????????2??????usb_host_interface???????????usb_interface_descriptor????desc???????????????????????interface???Щ?????????bNumEndpoints?????8λ??b for byte?????????????????y?????????probe?????????е???????????????????????usb_skel?С?

 

/* set up the endpoint information */
/* use only the first bulk-in and bulk-out endpoints */
iface_desc = interface->cur_altsetting;
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
if ( !dev->bulk_in_endpointAddr &&
((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) = = USB_DIR_IN) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) = = USB_ENDPOINT_XFER_BULK)) {
/* we found a bulk in endpoint */
buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
dev->bulk_in_size = buffer_size;
dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
dev->bulk_in_buffer = kmalloc(buffer_size?? GFP_KERNEL);
if (!dev->bulk_in_buffer) {
err("Could not allocate bulk_in_buffer");
goto error;
}
}
if (!dev->bulk_out_endpointAddr &&
((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)= =USB_DIR_OUT) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)= = USB_ENDPOINT_XFER_BULK)) {
/* we found a bulk out endpoint */
dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
}
}
if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
err("Could not find both bulk-in and bulk-out endpoints");
goto error;
}

????Linux USB?????????????壩
?????????????????????????Щ?????????????????????????????usb_set_intfdata()???????????????data?????data?????????????????γ????????????????usb_skel?????????????????????????????????data???????????usb_get_intfdata???????
????usb_set_intfdata(interface?? dev);
????retval = usb_register_dev(interface?? &skel_class);
????????????????interface??????skel_class??????????????????????????????????????????
????static struct usb_class_driver skel_class = {
????.name =       "skel%d"??
????.fops =       &skel_fops??
????.minor_base = USB_SKEL_MINOR_BASE??
????};
????????????????????????????????????????????????????廹????????豸?????????????????????? ?????????豸IO???????????????????????????????skel_fops?????????Щ?????????????usb?豸?????ж??interface?????interface???????IO??????????????????????????usb_class_driver??????????interface????????device??????usb_register_dev??????????????interface???????????????????usb_class_driver?????????£?linux???????豸???????????豸??????????????豸?????????????豸???????????????????豸?????????????豸??????????????豸???????????????????interface??????????????????????interface??????????????????????
????static struct file_operations skel_fops = {
????.owner = THIS_MODULE??
????.read =       skel_read??
????.write =   skel_write??
????.open =       skel_open??
????.release =    skel_release??
????};
?????????????????ж???????豸???д??????????USB?豸?????????????release???????????????????????skel_read??skel_write??skel_open??skel_release????????????????????????п?????????????
???????豸???γ??????????usb??????????????disconnect???????????鯔????????????class_driver?????????豸?????interface??data:
????dev = usb_get_intfdata(interface);
????usb_set_intfdata(interface?? NULL);
????/* give back our minor */
????usb_deregister_dev(interface?? &skel_class);
?????????????kref_put(&dev->kref?? skel_delete)?????????kref_put?????μ?????
?????????????????????????usb?????????????????????????????????????????USB?豸??IO??????