[PATCH] USB: drivers/usb/storage/libusual

This patch adds a shim driver libusual, which routes devices between
usb-storage and ub according to the common table, based on unusual_devs.h.
The help and example syntax is in Kconfig.

Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Pete Zaitcev
2005-10-22 20:15:09 -07:00
committed by Greg Kroah-Hartman
parent 1c50c317e2
commit a00828e9ac
12 changed files with 486 additions and 167 deletions

View File

@@ -112,49 +112,33 @@ static atomic_t total_threads = ATOMIC_INIT(0);
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, \
vendorName, productName,useProtocol, useTransport, \
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 [] = {
# 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) },
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
#undef USUAL_DEV
/* Terminating entry */
{ }
};
MODULE_DEVICE_TABLE (usb, storage_usb_ids);
#endif /* CONFIG_USB_LIBUSUAL */
/* 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.
*/
#undef UNUSUAL_DEV
#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
vendor_name, product_name, use_protocol, use_transport, \
init_function, Flags) \
@@ -177,53 +160,18 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
.useProtocol = use_protocol, \
.useTransport = use_transport, \
.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[] = {
# include "unusual_devs.h"
# 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 */
{ NULL }
@@ -484,14 +432,20 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf)
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 */
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_interface_descriptor *idesc =
&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 */
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) ?
idesc->bInterfaceProtocol :
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
@@ -529,7 +483,7 @@ static void get_device_info(struct us_data *us, int id_index)
if (unusual_dev->useTransport != US_PR_DEVICE &&
us->protocol == idesc->bInterfaceProtocol)
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 "
"(%04x,%04x,%04x S %02x P %02x)"
" has %s in unusual_devs.h\n"
@@ -921,10 +875,12 @@ static int storage_probe(struct usb_interface *intf,
{
struct Scsi_Host *host;
struct us_data *us;
const int id_index = id - storage_usb_ids;
int result;
struct task_struct *th;
if (usb_usual_check_type(id, USB_US_TYPE_STOR))
return -ENXIO;
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
* corresponding entry in the private table.
*/
get_device_info(us, id_index);
get_device_info(us, id);
#ifdef CONFIG_USB_STORAGE_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 */
retval = usb_register(&usb_storage_driver);
if (retval == 0)
if (retval == 0) {
printk(KERN_INFO "USB Mass Storage support registered.\n");
usb_usual_set_present(USB_US_TYPE_STOR);
}
return retval;
}
@@ -1088,6 +1045,8 @@ static void __exit usb_stor_exit(void)
wait_for_completion(&threads_gone);
atomic_dec(&total_threads);
}
usb_usual_clear_present(USB_US_TYPE_STOR);
}
module_init(usb_stor_init);