diff options
Diffstat (limited to 'drivers/usb/storage/datafab.c')
-rw-r--r-- | drivers/usb/storage/datafab.c | 100 |
1 files changed, 98 insertions, 2 deletions
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index 17f1ae23291..2d8d8351909 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c @@ -49,6 +49,7 @@ */ #include <linux/errno.h> +#include <linux/module.h> #include <linux/slab.h> #include <scsi/scsi.h> @@ -58,12 +59,61 @@ #include "transport.h" #include "protocol.h" #include "debug.h" -#include "datafab.h" + +struct datafab_info { + unsigned long sectors; /* total sector count */ + unsigned long ssize; /* sector size in bytes */ + signed char lun; /* used for dual-slot readers */ + + /* the following aren't used yet */ + unsigned char sense_key; + unsigned long sense_asc; /* additional sense code */ + unsigned long sense_ascq; /* additional sense code qualifier */ +}; static int datafab_determine_lun(struct us_data *us, struct datafab_info *info); +/* + * The table of devices + */ +#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ + vendorName, productName, useProtocol, useTransport, \ + initFunction, flags) \ +{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ + .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } + +struct usb_device_id datafab_usb_ids[] = { +# include "unusual_datafab.h" + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, datafab_usb_ids); + +#undef UNUSUAL_DEV + +/* + * The flags table + */ +#define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ + vendor_name, product_name, use_protocol, use_transport, \ + init_function, Flags) \ +{ \ + .vendorName = vendor_name, \ + .productName = product_name, \ + .useProtocol = use_protocol, \ + .useTransport = use_transport, \ + .initFunction = init_function, \ +} + +static struct us_unusual_dev datafab_unusual_dev_list[] = { +# include "unusual_datafab.h" + { } /* Terminating entry */ +}; + +#undef UNUSUAL_DEV + + static inline int datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) { if (len == 0) @@ -500,7 +550,7 @@ static void datafab_info_destructor(void *extra) // Transport for the Datafab MDCFE-B // -int datafab_transport(struct scsi_cmnd * srb, struct us_data *us) +static int datafab_transport(struct scsi_cmnd *srb, struct us_data *us) { struct datafab_info *info; int rc; @@ -665,3 +715,49 @@ int datafab_transport(struct scsi_cmnd * srb, struct us_data *us) info->sense_ascq = 0x00; return USB_STOR_TRANSPORT_FAILED; } + +static int datafab_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct us_data *us; + int result; + + result = usb_stor_probe1(&us, intf, id, + (id - datafab_usb_ids) + datafab_unusual_dev_list); + if (result) + return result; + + us->transport_name = "Datafab Bulk-Only"; + us->transport = datafab_transport; + us->transport_reset = usb_stor_Bulk_reset; + us->max_lun = 1; + + result = usb_stor_probe2(us); + return result; +} + +static struct usb_driver datafab_driver = { + .name = "ums-datafab", + .probe = datafab_probe, + .disconnect = usb_stor_disconnect, + .suspend = usb_stor_suspend, + .resume = usb_stor_resume, + .reset_resume = usb_stor_reset_resume, + .pre_reset = usb_stor_pre_reset, + .post_reset = usb_stor_post_reset, + .id_table = datafab_usb_ids, + .soft_unbind = 1, +}; + +static int __init datafab_init(void) +{ + return usb_register(&datafab_driver); +} + +static void __exit datafab_exit(void) +{ + usb_deregister(&datafab_driver); +} + +module_init(datafab_init); +module_exit(datafab_exit); |