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