aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage/usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/storage/usb.c')
-rw-r--r--drivers/usb/storage/usb.c106
1 files changed, 92 insertions, 14 deletions
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 27016fd2cad1..4becf495ca2d 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -75,9 +75,6 @@
75#ifdef CONFIG_USB_STORAGE_SDDR55 75#ifdef CONFIG_USB_STORAGE_SDDR55
76#include "sddr55.h" 76#include "sddr55.h"
77#endif 77#endif
78#ifdef CONFIG_USB_STORAGE_DPCM
79#include "dpcm.h"
80#endif
81#ifdef CONFIG_USB_STORAGE_FREECOM 78#ifdef CONFIG_USB_STORAGE_FREECOM
82#include "freecom.h" 79#include "freecom.h"
83#endif 80#endif
@@ -103,6 +100,7 @@
103#include "cypress_atacb.h" 100#include "cypress_atacb.h"
104#endif 101#endif
105#include "sierra_ms.h" 102#include "sierra_ms.h"
103#include "option_ms.h"
106 104
107/* Some informational data */ 105/* Some informational data */
108MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); 106MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
@@ -113,6 +111,10 @@ static unsigned int delay_use = 5;
113module_param(delay_use, uint, S_IRUGO | S_IWUSR); 111module_param(delay_use, uint, S_IRUGO | S_IWUSR);
114MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); 112MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device");
115 113
114static char quirks[128];
115module_param_string(quirks, quirks, sizeof(quirks), S_IRUGO | S_IWUSR);
116MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks");
117
116 118
117/* 119/*
118 * The entries in this table correspond, line for line, 120 * The entries in this table correspond, line for line,
@@ -126,6 +128,8 @@ MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device");
126{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ 128{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
127 .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } 129 .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
128 130
131#define COMPLIANT_DEV UNUSUAL_DEV
132
129#define USUAL_DEV(useProto, useTrans, useType) \ 133#define USUAL_DEV(useProto, useTrans, useType) \
130{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ 134{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
131 .driver_info = (USB_US_TYPE_STOR<<24) } 135 .driver_info = (USB_US_TYPE_STOR<<24) }
@@ -134,6 +138,7 @@ static struct usb_device_id storage_usb_ids [] = {
134 138
135# include "unusual_devs.h" 139# include "unusual_devs.h"
136#undef UNUSUAL_DEV 140#undef UNUSUAL_DEV
141#undef COMPLIANT_DEV
137#undef USUAL_DEV 142#undef USUAL_DEV
138 /* Terminating entry */ 143 /* Terminating entry */
139 { } 144 { }
@@ -164,6 +169,8 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
164 .initFunction = init_function, \ 169 .initFunction = init_function, \
165} 170}
166 171
172#define COMPLIANT_DEV UNUSUAL_DEV
173
167#define USUAL_DEV(use_protocol, use_transport, use_type) \ 174#define USUAL_DEV(use_protocol, use_transport, use_type) \
168{ \ 175{ \
169 .useProtocol = use_protocol, \ 176 .useProtocol = use_protocol, \
@@ -173,6 +180,7 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids);
173static struct us_unusual_dev us_unusual_dev_list[] = { 180static struct us_unusual_dev us_unusual_dev_list[] = {
174# include "unusual_devs.h" 181# include "unusual_devs.h"
175# undef UNUSUAL_DEV 182# undef UNUSUAL_DEV
183# undef COMPLIANT_DEV
176# undef USUAL_DEV 184# undef USUAL_DEV
177 185
178 /* Terminating entry */ 186 /* Terminating entry */
@@ -464,13 +472,83 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf)
464 US_DEBUGP("I/O buffer allocation failed\n"); 472 US_DEBUGP("I/O buffer allocation failed\n");
465 return -ENOMEM; 473 return -ENOMEM;
466 } 474 }
475 return 0;
476}
467 477
468 us->sensebuf = kmalloc(US_SENSE_SIZE, GFP_KERNEL); 478/* Works only for digits and letters, but small and fast */
469 if (!us->sensebuf) { 479#define TOLOWER(x) ((x) | 0x20)
470 US_DEBUGP("Sense buffer allocation failed\n"); 480
471 return -ENOMEM; 481/* Adjust device flags based on the "quirks=" module parameter */
482static void adjust_quirks(struct us_data *us)
483{
484 char *p;
485 u16 vid = le16_to_cpu(us->pusb_dev->descriptor.idVendor);
486 u16 pid = le16_to_cpu(us->pusb_dev->descriptor.idProduct);
487 unsigned f = 0;
488 unsigned int mask = (US_FL_SANE_SENSE | US_FL_FIX_CAPACITY |
489 US_FL_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE |
490 US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 |
491 US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE |
492 US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT);
493
494 p = quirks;
495 while (*p) {
496 /* Each entry consists of VID:PID:flags */
497 if (vid == simple_strtoul(p, &p, 16) &&
498 *p == ':' &&
499 pid == simple_strtoul(p+1, &p, 16) &&
500 *p == ':')
501 break;
502
503 /* Move forward to the next entry */
504 while (*p) {
505 if (*p++ == ',')
506 break;
507 }
472 } 508 }
473 return 0; 509 if (!*p) /* No match */
510 return;
511
512 /* Collect the flags */
513 while (*++p && *p != ',') {
514 switch (TOLOWER(*p)) {
515 case 'a':
516 f |= US_FL_SANE_SENSE;
517 break;
518 case 'c':
519 f |= US_FL_FIX_CAPACITY;
520 break;
521 case 'h':
522 f |= US_FL_CAPACITY_HEURISTICS;
523 break;
524 case 'i':
525 f |= US_FL_IGNORE_DEVICE;
526 break;
527 case 'l':
528 f |= US_FL_NOT_LOCKABLE;
529 break;
530 case 'm':
531 f |= US_FL_MAX_SECTORS_64;
532 break;
533 case 'o':
534 f |= US_FL_CAPACITY_OK;
535 break;
536 case 'r':
537 f |= US_FL_IGNORE_RESIDUE;
538 break;
539 case 's':
540 f |= US_FL_SINGLE_LUN;
541 break;
542 case 'w':
543 f |= US_FL_NO_WP_DETECT;
544 break;
545 /* Ignore unrecognized flag characters */
546 }
547 }
548 us->fflags = (us->fflags & ~mask) | f;
549 dev_info(&us->pusb_intf->dev, "Quirks match for "
550 "vid %04x pid %04x: %x\n",
551 vid, pid, f);
474} 552}
475 553
476/* Find an unusual_dev descriptor (always succeeds in the current code) */ 554/* Find an unusual_dev descriptor (always succeeds in the current code) */
@@ -497,6 +575,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id)
497 idesc->bInterfaceProtocol : 575 idesc->bInterfaceProtocol :
498 unusual_dev->useTransport; 576 unusual_dev->useTransport;
499 us->fflags = USB_US_ORIG_FLAGS(id->driver_info); 577 us->fflags = USB_US_ORIG_FLAGS(id->driver_info);
578 adjust_quirks(us);
500 579
501 if (us->fflags & US_FL_IGNORE_DEVICE) { 580 if (us->fflags & US_FL_IGNORE_DEVICE) {
502 printk(KERN_INFO USB_STORAGE "device ignored\n"); 581 printk(KERN_INFO USB_STORAGE "device ignored\n");
@@ -562,7 +641,7 @@ static int get_transport(struct us_data *us)
562 641
563 case US_PR_CBI: 642 case US_PR_CBI:
564 us->transport_name = "Control/Bulk/Interrupt"; 643 us->transport_name = "Control/Bulk/Interrupt";
565 us->transport = usb_stor_CBI_transport; 644 us->transport = usb_stor_CB_transport;
566 us->transport_reset = usb_stor_CB_reset; 645 us->transport_reset = usb_stor_CB_reset;
567 us->max_lun = 7; 646 us->max_lun = 7;
568 break; 647 break;
@@ -675,19 +754,19 @@ static int get_protocol(struct us_data *us)
675 754
676 case US_SC_8020: 755 case US_SC_8020:
677 us->protocol_name = "8020i"; 756 us->protocol_name = "8020i";
678 us->proto_handler = usb_stor_ATAPI_command; 757 us->proto_handler = usb_stor_pad12_command;
679 us->max_lun = 0; 758 us->max_lun = 0;
680 break; 759 break;
681 760
682 case US_SC_QIC: 761 case US_SC_QIC:
683 us->protocol_name = "QIC-157"; 762 us->protocol_name = "QIC-157";
684 us->proto_handler = usb_stor_qic157_command; 763 us->proto_handler = usb_stor_pad12_command;
685 us->max_lun = 0; 764 us->max_lun = 0;
686 break; 765 break;
687 766
688 case US_SC_8070: 767 case US_SC_8070:
689 us->protocol_name = "8070i"; 768 us->protocol_name = "8070i";
690 us->proto_handler = usb_stor_ATAPI_command; 769 us->proto_handler = usb_stor_pad12_command;
691 us->max_lun = 0; 770 us->max_lun = 0;
692 break; 771 break;
693 772
@@ -840,8 +919,6 @@ static void dissociate_dev(struct us_data *us)
840{ 919{
841 US_DEBUGP("-- %s\n", __func__); 920 US_DEBUGP("-- %s\n", __func__);
842 921
843 kfree(us->sensebuf);
844
845 /* Free the device-related DMA-mapped buffers */ 922 /* Free the device-related DMA-mapped buffers */
846 if (us->cr) 923 if (us->cr)
847 usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr, 924 usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr,
@@ -1064,6 +1141,7 @@ static struct usb_driver usb_storage_driver = {
1064static int __init usb_stor_init(void) 1141static int __init usb_stor_init(void)
1065{ 1142{
1066 int retval; 1143 int retval;
1144
1067 printk(KERN_INFO "Initializing USB Mass Storage driver...\n"); 1145 printk(KERN_INFO "Initializing USB Mass Storage driver...\n");
1068 1146
1069 /* register the driver, return usb_register return code if error */ 1147 /* register the driver, return usb_register return code if error */