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 17f1ae232919..2d8d83519090 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | */ | 49 | */ |
| 50 | 50 | ||
| 51 | #include <linux/errno.h> | 51 | #include <linux/errno.h> |
| 52 | #include <linux/module.h> | ||
| 52 | #include <linux/slab.h> | 53 | #include <linux/slab.h> |
| 53 | 54 | ||
| 54 | #include <scsi/scsi.h> | 55 | #include <scsi/scsi.h> |
| @@ -58,12 +59,61 @@ | |||
| 58 | #include "transport.h" | 59 | #include "transport.h" |
| 59 | #include "protocol.h" | 60 | #include "protocol.h" |
| 60 | #include "debug.h" | 61 | #include "debug.h" |
| 61 | #include "datafab.h" | 62 | |
| 63 | struct datafab_info { | ||
| 64 | unsigned long sectors; /* total sector count */ | ||
| 65 | unsigned long ssize; /* sector size in bytes */ | ||
| 66 | signed char lun; /* used for dual-slot readers */ | ||
| 67 | |||
| 68 | /* the following aren't used yet */ | ||
| 69 | unsigned char sense_key; | ||
| 70 | unsigned long sense_asc; /* additional sense code */ | ||
| 71 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
| 72 | }; | ||
| 62 | 73 | ||
| 63 | static int datafab_determine_lun(struct us_data *us, | 74 | static int datafab_determine_lun(struct us_data *us, |
| 64 | struct datafab_info *info); | 75 | struct datafab_info *info); |
| 65 | 76 | ||
| 66 | 77 | ||
| 78 | /* | ||
| 79 | * The table of devices | ||
| 80 | */ | ||
| 81 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 82 | vendorName, productName, useProtocol, useTransport, \ | ||
| 83 | initFunction, flags) \ | ||
| 84 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 85 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 86 | |||
| 87 | struct usb_device_id datafab_usb_ids[] = { | ||
| 88 | # include "unusual_datafab.h" | ||
| 89 | { } /* Terminating entry */ | ||
| 90 | }; | ||
| 91 | MODULE_DEVICE_TABLE(usb, datafab_usb_ids); | ||
| 92 | |||
| 93 | #undef UNUSUAL_DEV | ||
| 94 | |||
| 95 | /* | ||
| 96 | * The flags table | ||
| 97 | */ | ||
| 98 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
| 99 | vendor_name, product_name, use_protocol, use_transport, \ | ||
| 100 | init_function, Flags) \ | ||
| 101 | { \ | ||
| 102 | .vendorName = vendor_name, \ | ||
| 103 | .productName = product_name, \ | ||
| 104 | .useProtocol = use_protocol, \ | ||
| 105 | .useTransport = use_transport, \ | ||
| 106 | .initFunction = init_function, \ | ||
| 107 | } | ||
| 108 | |||
| 109 | static struct us_unusual_dev datafab_unusual_dev_list[] = { | ||
| 110 | # include "unusual_datafab.h" | ||
| 111 | { } /* Terminating entry */ | ||
| 112 | }; | ||
| 113 | |||
| 114 | #undef UNUSUAL_DEV | ||
| 115 | |||
| 116 | |||
| 67 | static inline int | 117 | static inline int |
| 68 | datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) { | 118 | datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) { |
| 69 | if (len == 0) | 119 | if (len == 0) |
| @@ -500,7 +550,7 @@ static void datafab_info_destructor(void *extra) | |||
| 500 | 550 | ||
| 501 | // Transport for the Datafab MDCFE-B | 551 | // Transport for the Datafab MDCFE-B |
| 502 | // | 552 | // |
| 503 | int datafab_transport(struct scsi_cmnd * srb, struct us_data *us) | 553 | static int datafab_transport(struct scsi_cmnd *srb, struct us_data *us) |
| 504 | { | 554 | { |
| 505 | struct datafab_info *info; | 555 | struct datafab_info *info; |
| 506 | int rc; | 556 | int rc; |
| @@ -665,3 +715,49 @@ int datafab_transport(struct scsi_cmnd * srb, struct us_data *us) | |||
| 665 | info->sense_ascq = 0x00; | 715 | info->sense_ascq = 0x00; |
| 666 | return USB_STOR_TRANSPORT_FAILED; | 716 | return USB_STOR_TRANSPORT_FAILED; |
| 667 | } | 717 | } |
| 718 | |||
| 719 | static int datafab_probe(struct usb_interface *intf, | ||
| 720 | const struct usb_device_id *id) | ||
| 721 | { | ||
| 722 | struct us_data *us; | ||
| 723 | int result; | ||
| 724 | |||
| 725 | result = usb_stor_probe1(&us, intf, id, | ||
| 726 | (id - datafab_usb_ids) + datafab_unusual_dev_list); | ||
| 727 | if (result) | ||
| 728 | return result; | ||
| 729 | |||
| 730 | us->transport_name = "Datafab Bulk-Only"; | ||
| 731 | us->transport = datafab_transport; | ||
| 732 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 733 | us->max_lun = 1; | ||
| 734 | |||
| 735 | result = usb_stor_probe2(us); | ||
| 736 | return result; | ||
| 737 | } | ||
| 738 | |||
| 739 | static struct usb_driver datafab_driver = { | ||
| 740 | .name = "ums-datafab", | ||
| 741 | .probe = datafab_probe, | ||
| 742 | .disconnect = usb_stor_disconnect, | ||
| 743 | .suspend = usb_stor_suspend, | ||
| 744 | .resume = usb_stor_resume, | ||
| 745 | .reset_resume = usb_stor_reset_resume, | ||
| 746 | .pre_reset = usb_stor_pre_reset, | ||
| 747 | .post_reset = usb_stor_post_reset, | ||
| 748 | .id_table = datafab_usb_ids, | ||
| 749 | .soft_unbind = 1, | ||
| 750 | }; | ||
| 751 | |||
| 752 | static int __init datafab_init(void) | ||
| 753 | { | ||
| 754 | return usb_register(&datafab_driver); | ||
| 755 | } | ||
| 756 | |||
| 757 | static void __exit datafab_exit(void) | ||
| 758 | { | ||
| 759 | usb_deregister(&datafab_driver); | ||
| 760 | } | ||
| 761 | |||
| 762 | module_init(datafab_init); | ||
| 763 | module_exit(datafab_exit); | ||
