aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r--drivers/usb/storage/initializers.c14
-rw-r--r--drivers/usb/storage/option_ms.c124
-rw-r--r--drivers/usb/storage/sierra_ms.c2
-rw-r--r--drivers/usb/storage/unusual_devs.h2
4 files changed, 81 insertions, 61 deletions
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c
index 2dd9bd4bff56..ec17c96371af 100644
--- a/drivers/usb/storage/initializers.c
+++ b/drivers/usb/storage/initializers.c
@@ -52,7 +52,7 @@ int usb_stor_euscsi_init(struct us_data *us)
52 us->iobuf[0] = 0x1; 52 us->iobuf[0] = 0x1;
53 result = usb_stor_control_msg(us, us->send_ctrl_pipe, 53 result = usb_stor_control_msg(us, us->send_ctrl_pipe,
54 0x0C, USB_RECIP_INTERFACE | USB_TYPE_VENDOR, 54 0x0C, USB_RECIP_INTERFACE | USB_TYPE_VENDOR,
55 0x01, 0x0, us->iobuf, 0x1, 5*HZ); 55 0x01, 0x0, us->iobuf, 0x1, 5000);
56 US_DEBUGP("-- result is %d\n", result); 56 US_DEBUGP("-- result is %d\n", result);
57 57
58 return 0; 58 return 0;
@@ -80,14 +80,16 @@ int usb_stor_ucr61s2b_init(struct us_data *us)
80 80
81 res = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, 81 res = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb,
82 US_BULK_CB_WRAP_LEN, &partial); 82 US_BULK_CB_WRAP_LEN, &partial);
83 if(res) 83 if (res)
84 return res; 84 return -EIO;
85 85
86 US_DEBUGP("Getting status packet...\n"); 86 US_DEBUGP("Getting status packet...\n");
87 res = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, 87 res = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
88 US_BULK_CS_WRAP_LEN, &partial); 88 US_BULK_CS_WRAP_LEN, &partial);
89 if (res)
90 return -EIO;
89 91
90 return (res ? -1 : 0); 92 return 0;
91} 93}
92 94
93/* This places the HUAWEI E220 devices in multi-port mode */ 95/* This places the HUAWEI E220 devices in multi-port mode */
@@ -99,6 +101,6 @@ int usb_stor_huawei_e220_init(struct us_data *us)
99 USB_REQ_SET_FEATURE, 101 USB_REQ_SET_FEATURE,
100 USB_TYPE_STANDARD | USB_RECIP_DEVICE, 102 USB_TYPE_STANDARD | USB_RECIP_DEVICE,
101 0x01, 0x0, NULL, 0x0, 1000); 103 0x01, 0x0, NULL, 0x0, 1000);
102 US_DEBUGP("usb_control_msg performing result is %d\n", result); 104 US_DEBUGP("Huawei mode set result is %d\n", result);
103 return (result ? 0 : -1); 105 return (result ? 0 : -ENODEV);
104} 106}
diff --git a/drivers/usb/storage/option_ms.c b/drivers/usb/storage/option_ms.c
index 353f922939a4..d41cc0a970f7 100644
--- a/drivers/usb/storage/option_ms.c
+++ b/drivers/usb/storage/option_ms.c
@@ -37,7 +37,7 @@ MODULE_PARM_DESC(option_zero_cd, "ZeroCD mode (1=Force Modem (default),"
37 37
38#define RESPONSE_LEN 1024 38#define RESPONSE_LEN 1024
39 39
40static int option_rezero(struct us_data *us, int ep_in, int ep_out) 40static int option_rezero(struct us_data *us)
41{ 41{
42 const unsigned char rezero_msg[] = { 42 const unsigned char rezero_msg[] = {
43 0x55, 0x53, 0x42, 0x43, 0x78, 0x56, 0x34, 0x12, 43 0x55, 0x53, 0x42, 0x43, 0x78, 0x56, 0x34, 0x12,
@@ -54,10 +54,10 @@ static int option_rezero(struct us_data *us, int ep_in, int ep_out)
54 if (buffer == NULL) 54 if (buffer == NULL)
55 return USB_STOR_TRANSPORT_ERROR; 55 return USB_STOR_TRANSPORT_ERROR;
56 56
57 memcpy(buffer, rezero_msg, sizeof (rezero_msg)); 57 memcpy(buffer, rezero_msg, sizeof(rezero_msg));
58 result = usb_stor_bulk_transfer_buf(us, 58 result = usb_stor_bulk_transfer_buf(us,
59 usb_sndbulkpipe(us->pusb_dev, ep_out), 59 us->send_bulk_pipe,
60 buffer, sizeof (rezero_msg), NULL); 60 buffer, sizeof(rezero_msg), NULL);
61 if (result != USB_STOR_XFER_GOOD) { 61 if (result != USB_STOR_XFER_GOOD) {
62 result = USB_STOR_XFER_ERROR; 62 result = USB_STOR_XFER_ERROR;
63 goto out; 63 goto out;
@@ -66,9 +66,15 @@ static int option_rezero(struct us_data *us, int ep_in, int ep_out)
66 /* Some of the devices need to be asked for a response, but we don't 66 /* Some of the devices need to be asked for a response, but we don't
67 * care what that response is. 67 * care what that response is.
68 */ 68 */
69 result = usb_stor_bulk_transfer_buf(us, 69 usb_stor_bulk_transfer_buf(us,
70 usb_sndbulkpipe(us->pusb_dev, ep_out), 70 us->recv_bulk_pipe,
71 buffer, RESPONSE_LEN, NULL); 71 buffer, RESPONSE_LEN, NULL);
72
73 /* Read the CSW */
74 usb_stor_bulk_transfer_buf(us,
75 us->recv_bulk_pipe,
76 buffer, 13, NULL);
77
72 result = USB_STOR_XFER_GOOD; 78 result = USB_STOR_XFER_GOOD;
73 79
74out: 80out:
@@ -76,63 +82,75 @@ out:
76 return result; 82 return result;
77} 83}
78 84
79int option_ms_init(struct us_data *us) 85static int option_inquiry(struct us_data *us)
80{ 86{
81 struct usb_device *udev; 87 const unsigned char inquiry_msg[] = {
82 struct usb_interface *intf; 88 0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78,
83 struct usb_host_interface *iface_desc; 89 0x24, 0x00, 0x00, 0x00, 0x80, 0x00, 0x06, 0x12,
84 struct usb_endpoint_descriptor *endpoint = NULL; 90 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00,
85 u8 ep_in = 0, ep_out = 0; 91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
86 int ep_in_size = 0, ep_out_size = 0; 92 };
87 int i, result; 93 char *buffer;
88 94 int result;
89 udev = us->pusb_dev;
90 intf = us->pusb_intf;
91
92 /* Ensure it's really a ZeroCD device; devices that are already
93 * in modem mode return 0xFF for class, subclass, and protocol.
94 */
95 if (udev->descriptor.bDeviceClass != 0 ||
96 udev->descriptor.bDeviceSubClass != 0 ||
97 udev->descriptor.bDeviceProtocol != 0)
98 return USB_STOR_TRANSPORT_GOOD;
99 95
100 US_DEBUGP("Option MS: option_ms_init called\n"); 96 US_DEBUGP("Option MS: %s", "device inquiry for vendor name\n");
101 97
102 /* Find the right mass storage interface */ 98 buffer = kzalloc(0x24, GFP_KERNEL);
103 iface_desc = intf->cur_altsetting; 99 if (buffer == NULL)
104 if (iface_desc->desc.bInterfaceClass != 0x8 || 100 return USB_STOR_TRANSPORT_ERROR;
105 iface_desc->desc.bInterfaceSubClass != 0x6 ||
106 iface_desc->desc.bInterfaceProtocol != 0x50) {
107 US_DEBUGP("Option MS: mass storage interface not found, no action "
108 "required\n");
109 return USB_STOR_TRANSPORT_GOOD;
110 }
111 101
112 /* Find the mass storage bulk endpoints */ 102 memcpy(buffer, inquiry_msg, sizeof(inquiry_msg));
113 for (i = 0; i < iface_desc->desc.bNumEndpoints && (!ep_in_size || !ep_out_size); ++i) { 103 result = usb_stor_bulk_transfer_buf(us,
114 endpoint = &iface_desc->endpoint[i].desc; 104 us->send_bulk_pipe,
115 105 buffer, sizeof(inquiry_msg), NULL);
116 if (usb_endpoint_is_bulk_in(endpoint)) { 106 if (result != USB_STOR_XFER_GOOD) {
117 ep_in = usb_endpoint_num(endpoint); 107 result = USB_STOR_XFER_ERROR;
118 ep_in_size = le16_to_cpu(endpoint->wMaxPacketSize); 108 goto out;
119 } else if (usb_endpoint_is_bulk_out(endpoint)) {
120 ep_out = usb_endpoint_num(endpoint);
121 ep_out_size = le16_to_cpu(endpoint->wMaxPacketSize);
122 }
123 } 109 }
124 110
125 /* Can't find the mass storage endpoints */ 111 result = usb_stor_bulk_transfer_buf(us,
126 if (!ep_in_size || !ep_out_size) { 112 us->recv_bulk_pipe,
127 US_DEBUGP("Option MS: mass storage endpoints not found, no action " 113 buffer, 0x24, NULL);
128 "required\n"); 114 if (result != USB_STOR_XFER_GOOD) {
129 return USB_STOR_TRANSPORT_GOOD; 115 result = USB_STOR_XFER_ERROR;
116 goto out;
130 } 117 }
131 118
119 result = memcmp(buffer+8, "Option", 6);
120
121 /* Read the CSW */
122 usb_stor_bulk_transfer_buf(us,
123 us->recv_bulk_pipe,
124 buffer, 13, NULL);
125
126out:
127 kfree(buffer);
128 return result;
129}
130
131
132int option_ms_init(struct us_data *us)
133{
134 int result;
135
136 US_DEBUGP("Option MS: option_ms_init called\n");
137
138 /* Additional test for vendor information via INQUIRY,
139 * because some vendor/product IDs are ambiguous
140 */
141 result = option_inquiry(us);
142 if (result != 0) {
143 US_DEBUGP("Option MS: vendor is not Option or not determinable,"
144 " no action taken\n");
145 return 0;
146 } else
147 US_DEBUGP("Option MS: this is a genuine Option device,"
148 " proceeding\n");
149
132 /* Force Modem mode */ 150 /* Force Modem mode */
133 if (option_zero_cd == ZCD_FORCE_MODEM) { 151 if (option_zero_cd == ZCD_FORCE_MODEM) {
134 US_DEBUGP("Option MS: %s", "Forcing Modem Mode\n"); 152 US_DEBUGP("Option MS: %s", "Forcing Modem Mode\n");
135 result = option_rezero(us, ep_in, ep_out); 153 result = option_rezero(us);
136 if (result != USB_STOR_XFER_GOOD) 154 if (result != USB_STOR_XFER_GOOD)
137 US_DEBUGP("Option MS: Failed to switch to modem mode.\n"); 155 US_DEBUGP("Option MS: Failed to switch to modem mode.\n");
138 return -EIO; 156 return -EIO;
@@ -142,6 +160,6 @@ int option_ms_init(struct us_data *us)
142 " requests it\n"); 160 " requests it\n");
143 } 161 }
144 162
145 return USB_STOR_TRANSPORT_GOOD; 163 return 0;
146} 164}
147 165
diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c
index 4359a2cb42df..4395c4100ec2 100644
--- a/drivers/usb/storage/sierra_ms.c
+++ b/drivers/usb/storage/sierra_ms.c
@@ -202,6 +202,6 @@ int sierra_ms_init(struct us_data *us)
202complete: 202complete:
203 result = device_create_file(&us->pusb_intf->dev, &dev_attr_truinst); 203 result = device_create_file(&us->pusb_intf->dev, &dev_attr_truinst);
204 204
205 return USB_STOR_TRANSPORT_GOOD; 205 return 0;
206} 206}
207 207
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 4b8b69045fe6..1b9c5dd0fb27 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1385,7 +1385,7 @@ UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100,
1385UNUSUAL_DEV( 0x1186, 0x3e04, 0x0000, 0x0000, 1385UNUSUAL_DEV( 0x1186, 0x3e04, 0x0000, 0x0000,
1386 "D-Link", 1386 "D-Link",
1387 "USB Mass Storage", 1387 "USB Mass Storage",
1388 US_SC_DEVICE, US_PR_DEVICE, option_ms_init, 0), 1388 US_SC_DEVICE, US_PR_DEVICE, option_ms_init, US_FL_IGNORE_DEVICE),
1389 1389
1390/* Reported by Kevin Lloyd <linux@sierrawireless.com> 1390/* Reported by Kevin Lloyd <linux@sierrawireless.com>
1391 * Entry is needed for the initializer function override, 1391 * Entry is needed for the initializer function override,