|
@@ -112,49 +112,33 @@ static atomic_t total_threads = ATOMIC_INIT(0);
|
|
static DECLARE_COMPLETION(threads_gone);
|
|
static DECLARE_COMPLETION(threads_gone);
|
|
|
|
|
|
|
|
|
|
-/* The entries in this table, except for final ones here
|
|
|
|
- * (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
|
|
|
|
- * line for line with the entries of us_unsuaul_dev_list[].
|
|
|
|
|
|
+/*
|
|
|
|
+ * The entries in this table correspond, line for line,
|
|
|
|
+ * with the entries of us_unusual_dev_list[].
|
|
*/
|
|
*/
|
|
|
|
+#ifndef CONFIG_USB_LIBUSUAL
|
|
|
|
|
|
#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
|
|
#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
|
|
vendorName, productName,useProtocol, useTransport, \
|
|
vendorName, productName,useProtocol, useTransport, \
|
|
initFunction, flags) \
|
|
initFunction, flags) \
|
|
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax) }
|
|
|
|
|
|
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
|
|
|
|
+ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
|
|
|
|
+
|
|
|
|
+#define USUAL_DEV(useProto, useTrans, useType) \
|
|
|
|
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
|
|
|
|
+ .driver_info = (USB_US_TYPE_STOR<<24) }
|
|
|
|
|
|
static struct usb_device_id storage_usb_ids [] = {
|
|
static struct usb_device_id storage_usb_ids [] = {
|
|
|
|
|
|
# include "unusual_devs.h"
|
|
# include "unusual_devs.h"
|
|
#undef UNUSUAL_DEV
|
|
#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) },
|
|
|
|
- { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
|
|
|
|
-
|
|
|
|
|
|
+#undef USUAL_DEV
|
|
/* Terminating entry */
|
|
/* Terminating entry */
|
|
{ }
|
|
{ }
|
|
};
|
|
};
|
|
|
|
|
|
MODULE_DEVICE_TABLE (usb, storage_usb_ids);
|
|
MODULE_DEVICE_TABLE (usb, storage_usb_ids);
|
|
|
|
+#endif /* CONFIG_USB_LIBUSUAL */
|
|
|
|
|
|
/* This is the list of devices we recognize, along with their flag data */
|
|
/* This is the list of devices we recognize, along with their flag data */
|
|
|
|
|
|
@@ -167,7 +151,6 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
|
|
* are free to use as many characters as you like.
|
|
* are free to use as many characters as you like.
|
|
*/
|
|
*/
|
|
|
|
|
|
-#undef UNUSUAL_DEV
|
|
|
|
#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
|
|
#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
|
|
vendor_name, product_name, use_protocol, use_transport, \
|
|
vendor_name, product_name, use_protocol, use_transport, \
|
|
init_function, Flags) \
|
|
init_function, Flags) \
|
|
@@ -177,53 +160,18 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
|
|
.useProtocol = use_protocol, \
|
|
.useProtocol = use_protocol, \
|
|
.useTransport = use_transport, \
|
|
.useTransport = use_transport, \
|
|
.initFunction = init_function, \
|
|
.initFunction = init_function, \
|
|
- .flags = Flags, \
|
|
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define USUAL_DEV(use_protocol, use_transport, use_type) \
|
|
|
|
+{ \
|
|
|
|
+ .useProtocol = use_protocol, \
|
|
|
|
+ .useTransport = use_transport, \
|
|
}
|
|
}
|
|
|
|
|
|
static struct us_unusual_dev us_unusual_dev_list[] = {
|
|
static struct us_unusual_dev us_unusual_dev_list[] = {
|
|
# include "unusual_devs.h"
|
|
# include "unusual_devs.h"
|
|
# undef UNUSUAL_DEV
|
|
# undef UNUSUAL_DEV
|
|
- /* Control/Bulk transport for all SubClass values */
|
|
|
|
- { .useProtocol = US_SC_RBC,
|
|
|
|
- .useTransport = US_PR_CB},
|
|
|
|
- { .useProtocol = US_SC_8020,
|
|
|
|
- .useTransport = US_PR_CB},
|
|
|
|
- { .useProtocol = US_SC_QIC,
|
|
|
|
- .useTransport = US_PR_CB},
|
|
|
|
- { .useProtocol = US_SC_UFI,
|
|
|
|
- .useTransport = US_PR_CB},
|
|
|
|
- { .useProtocol = US_SC_8070,
|
|
|
|
- .useTransport = US_PR_CB},
|
|
|
|
- { .useProtocol = US_SC_SCSI,
|
|
|
|
- .useTransport = US_PR_CB},
|
|
|
|
-
|
|
|
|
- /* Control/Bulk/Interrupt transport for all SubClass values */
|
|
|
|
- { .useProtocol = US_SC_RBC,
|
|
|
|
- .useTransport = US_PR_CBI},
|
|
|
|
- { .useProtocol = US_SC_8020,
|
|
|
|
- .useTransport = US_PR_CBI},
|
|
|
|
- { .useProtocol = US_SC_QIC,
|
|
|
|
- .useTransport = US_PR_CBI},
|
|
|
|
- { .useProtocol = US_SC_UFI,
|
|
|
|
- .useTransport = US_PR_CBI},
|
|
|
|
- { .useProtocol = US_SC_8070,
|
|
|
|
- .useTransport = US_PR_CBI},
|
|
|
|
- { .useProtocol = US_SC_SCSI,
|
|
|
|
- .useTransport = US_PR_CBI},
|
|
|
|
-
|
|
|
|
- /* Bulk-only transport for all SubClass values */
|
|
|
|
- { .useProtocol = US_SC_RBC,
|
|
|
|
- .useTransport = US_PR_BULK},
|
|
|
|
- { .useProtocol = US_SC_8020,
|
|
|
|
- .useTransport = US_PR_BULK},
|
|
|
|
- { .useProtocol = US_SC_QIC,
|
|
|
|
- .useTransport = US_PR_BULK},
|
|
|
|
- { .useProtocol = US_SC_UFI,
|
|
|
|
- .useTransport = US_PR_BULK},
|
|
|
|
- { .useProtocol = US_SC_8070,
|
|
|
|
- .useTransport = US_PR_BULK},
|
|
|
|
- { .useProtocol = US_SC_SCSI,
|
|
|
|
- .useTransport = US_PR_BULK},
|
|
|
|
|
|
+# undef USUAL_DEV
|
|
|
|
|
|
/* Terminating entry */
|
|
/* Terminating entry */
|
|
{ NULL }
|
|
{ NULL }
|
|
@@ -484,14 +432,20 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* Find an unusual_dev descriptor (always succeeds in the current code) */
|
|
|
|
+static struct us_unusual_dev *find_unusual(const struct usb_device_id *id)
|
|
|
|
+{
|
|
|
|
+ const int id_index = id - storage_usb_ids;
|
|
|
|
+ return &us_unusual_dev_list[id_index];
|
|
|
|
+}
|
|
|
|
+
|
|
/* Get the unusual_devs entries and the string descriptors */
|
|
/* Get the unusual_devs entries and the string descriptors */
|
|
-static void get_device_info(struct us_data *us, int id_index)
|
|
|
|
|
|
+static void get_device_info(struct us_data *us, const struct usb_device_id *id)
|
|
{
|
|
{
|
|
struct usb_device *dev = us->pusb_dev;
|
|
struct usb_device *dev = us->pusb_dev;
|
|
struct usb_interface_descriptor *idesc =
|
|
struct usb_interface_descriptor *idesc =
|
|
&us->pusb_intf->cur_altsetting->desc;
|
|
&us->pusb_intf->cur_altsetting->desc;
|
|
- struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index];
|
|
|
|
- struct usb_device_id *id = &storage_usb_ids[id_index];
|
|
|
|
|
|
+ struct us_unusual_dev *unusual_dev = find_unusual(id);
|
|
|
|
|
|
/* Store the entries */
|
|
/* Store the entries */
|
|
us->unusual_dev = unusual_dev;
|
|
us->unusual_dev = unusual_dev;
|
|
@@ -501,7 +455,7 @@ static void get_device_info(struct us_data *us, int id_index)
|
|
us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ?
|
|
us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ?
|
|
idesc->bInterfaceProtocol :
|
|
idesc->bInterfaceProtocol :
|
|
unusual_dev->useTransport;
|
|
unusual_dev->useTransport;
|
|
- us->flags = unusual_dev->flags;
|
|
|
|
|
|
+ us->flags = USB_US_ORIG_FLAGS(id->driver_info);
|
|
|
|
|
|
/*
|
|
/*
|
|
* This flag is only needed when we're in high-speed, so let's
|
|
* This flag is only needed when we're in high-speed, so let's
|
|
@@ -529,7 +483,7 @@ static void get_device_info(struct us_data *us, int id_index)
|
|
if (unusual_dev->useTransport != US_PR_DEVICE &&
|
|
if (unusual_dev->useTransport != US_PR_DEVICE &&
|
|
us->protocol == idesc->bInterfaceProtocol)
|
|
us->protocol == idesc->bInterfaceProtocol)
|
|
msg += 2;
|
|
msg += 2;
|
|
- if (msg >= 0 && !(unusual_dev->flags & US_FL_NEED_OVERRIDE))
|
|
|
|
|
|
+ if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE))
|
|
printk(KERN_NOTICE USB_STORAGE "This device "
|
|
printk(KERN_NOTICE USB_STORAGE "This device "
|
|
"(%04x,%04x,%04x S %02x P %02x)"
|
|
"(%04x,%04x,%04x S %02x P %02x)"
|
|
" has %s in unusual_devs.h\n"
|
|
" has %s in unusual_devs.h\n"
|
|
@@ -921,10 +875,12 @@ static int storage_probe(struct usb_interface *intf,
|
|
{
|
|
{
|
|
struct Scsi_Host *host;
|
|
struct Scsi_Host *host;
|
|
struct us_data *us;
|
|
struct us_data *us;
|
|
- const int id_index = id - storage_usb_ids;
|
|
|
|
int result;
|
|
int result;
|
|
struct task_struct *th;
|
|
struct task_struct *th;
|
|
|
|
|
|
|
|
+ if (usb_usual_check_type(id, USB_US_TYPE_STOR))
|
|
|
|
+ return -ENXIO;
|
|
|
|
+
|
|
US_DEBUGP("USB Mass Storage device detected\n");
|
|
US_DEBUGP("USB Mass Storage device detected\n");
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -957,7 +913,7 @@ static int storage_probe(struct usb_interface *intf,
|
|
* of the match from the usb_device_id table, so we can find the
|
|
* of the match from the usb_device_id table, so we can find the
|
|
* corresponding entry in the private table.
|
|
* corresponding entry in the private table.
|
|
*/
|
|
*/
|
|
- get_device_info(us, id_index);
|
|
|
|
|
|
+ get_device_info(us, id);
|
|
|
|
|
|
#ifdef CONFIG_USB_STORAGE_SDDR09
|
|
#ifdef CONFIG_USB_STORAGE_SDDR09
|
|
if (us->protocol == US_PR_EUSB_SDDR09 ||
|
|
if (us->protocol == US_PR_EUSB_SDDR09 ||
|
|
@@ -1062,9 +1018,10 @@ static int __init usb_stor_init(void)
|
|
|
|
|
|
/* register the driver, return usb_register return code if error */
|
|
/* register the driver, return usb_register return code if error */
|
|
retval = usb_register(&usb_storage_driver);
|
|
retval = usb_register(&usb_storage_driver);
|
|
- if (retval == 0)
|
|
|
|
|
|
+ if (retval == 0) {
|
|
printk(KERN_INFO "USB Mass Storage support registered.\n");
|
|
printk(KERN_INFO "USB Mass Storage support registered.\n");
|
|
-
|
|
|
|
|
|
+ usb_usual_set_present(USB_US_TYPE_STOR);
|
|
|
|
+ }
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1088,6 +1045,8 @@ static void __exit usb_stor_exit(void)
|
|
wait_for_completion(&threads_gone);
|
|
wait_for_completion(&threads_gone);
|
|
atomic_dec(&total_threads);
|
|
atomic_dec(&total_threads);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ usb_usual_clear_present(USB_US_TYPE_STOR);
|
|
}
|
|
}
|
|
|
|
|
|
module_init(usb_stor_init);
|
|
module_init(usb_stor_init);
|