代码: 全选
#define USB_INTERFACE_INFO(cl,sc,pr) \
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO, .bInterfaceClass = (cl), .bInterfaceSubClass = (sc), .bInterfaceProtocol = (pr)
static struct usb_device_id storage_usb_ids [] = {
# include "unusual_devs.h"
#undef UNUSUAL_DEV
/* Control/Bulk transport for all SubClass values */
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CB) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CB) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CB) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CB) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CB) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CB) },
/* Control/Bulk/Interrupt transport for all SubClass values */
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CBI) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CBI) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CBI) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CBI) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CBI) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CBI) },
/* Bulk-only transport for all SubClass values */
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_BULK) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_BULK) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_BULK) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_BULK) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_BULK) },
#if !defined(CONFIG_BLK_DEV_UB) && !defined(CONFIG_BLK_DEV_UB_MODULE)
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
#endif
/* Terminating entry */
{ }
};
/* Probe to see if we can drive a newly-connected USB device */
static int storage_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct us_data *us;
[b][color=#FF0000]const int id_index = id - storage_usb_ids; [/color][/b]
int result;
US_DEBUGP("USB Mass Storage device detected\n");
/* Allocate the us_data structure and initialize the mutexes */
us = (struct us_data *) kmalloc(sizeof(*us), GFP_KERNEL);
if (!us) {
printk(KERN_WARNING USB_STORAGE "Out of memory\n");
return -ENOMEM;
}
memset(us, 0, sizeof(struct us_data));
init_MUTEX(&(us->dev_semaphore));
init_MUTEX_LOCKED(&(us->sema));
init_completion(&(us->notify));
init_waitqueue_head(&us->dev_reset_wait);
init_waitqueue_head(&us->scsi_scan_wait);
init_completion(&us->scsi_scan_done);
/* Associate the us_data structure with the USB device */
result = associate_dev(us, intf);
if (result)
goto BadDevice;
/*
* Get the unusual_devs entries and the descriptors
*
* id_index is calculated in the declaration to be the index number
* of the match from the usb_device_id table, so we can find the
* corresponding entry in the private table.
*/
get_device_info(us, id_index);
#ifdef CONFIG_USB_STORAGE_SDDR09
if (us->protocol == US_PR_EUSB_SDDR09 ||
us->protocol == US_PR_DPCM_USB) {
/* set the configuration -- STALL is an acceptable response here */
if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) {
US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev
->actconfig->desc.bConfigurationValue);
goto BadDevice;
}
result = usb_reset_configuration(us->pusb_dev);
US_DEBUGP("Result of usb_reset_configuration is %d\n", result);
if (result == -EPIPE) {
US_DEBUGP("-- stall on control interface\n");
} else if (result != 0) {
/* it's not a stall, but another error -- time to bail */
US_DEBUGP("-- Unknown error. Rejecting device\n");
goto BadDevice;
}
}
#endif
/* Get the transport, protocol, and pipe settings */
result = get_transport(us);
if (result)
goto BadDevice;
result = get_protocol(us);
if (result)
goto BadDevice;
result = get_pipes(us);
if (result)
goto BadDevice;
/* Acquire all the other resources and add the host */
result = usb_stor_acquire_resources(us);
if (result)
goto BadDevice;
result = scsi_add_host(us->host, &intf->dev);
if (result) {
printk(KERN_WARNING USB_STORAGE
"Unable to add the scsi host\n");
goto BadDevice;
}
/* Start up the thread for delayed SCSI-device scanning */
result = kernel_thread(usb_stor_scan_thread, us, CLONE_VM);
if (result < 0) {
printk(KERN_WARNING USB_STORAGE
"Unable to start the device-scanning thread\n");
scsi_remove_host(us->host);
goto BadDevice;
}
return 0;
/* We come here if there are any problems */
BadDevice:
US_DEBUGP("storage_probe() failed\n");
usb_stor_release_resources(us);
dissociate_dev(us);
return result;
}