blob: 17313cf88eee74b7f0ccd7f4c880a1ecab949207 [file] [log] [blame]
Patrick Georgid21f68b2008-09-02 16:06:22 +00001/*
2 * This file is part of the libpayload project.
3 *
4 * Copyright (C) 2008 coresystems GmbH
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
Stefan Reinauer8992e532013-05-02 16:16:41 -070030//#define USB_DEBUG
Gabe Black0af03d22012-03-19 03:06:46 -070031#include <endian.h>
Jordan Crouse29061a52008-09-11 17:29:00 +000032#include <usb/usb.h>
33#include <usb/usbmsc.h>
34#include <usb/usbdisk.h>
Patrick Georgid21f68b2008-09-02 16:06:22 +000035
36enum {
37 msc_subclass_rbc = 0x1,
38 msc_subclass_mmc2 = 0x2,
39 msc_subclass_qic157 = 0x3,
40 msc_subclass_ufi = 0x4,
41 msc_subclass_sff8070i = 0x5,
42 msc_subclass_scsitrans = 0x6
43};
Stefan Reinauerb56f2d02010-03-25 22:17:36 +000044
Patrick Georgid21f68b2008-09-02 16:06:22 +000045static const char *msc_subclass_strings[7] = {
46 "(none)",
47 "RBC",
48 "MMC-2",
49 "QIC-157",
50 "UFI",
51 "SFF-8070i",
52 "SCSI transparent"
53};
54enum {
55 msc_proto_cbi_wcomp = 0x0,
56 msc_proto_cbi_wocomp = 0x1,
57 msc_proto_bulk_only = 0x50
58};
59static const char *msc_protocol_strings[0x51] = {
60 "Control/Bulk/Interrupt protocol (with command completion interrupt)",
61 "Control/Bulk/Interrupt protocol (with no command completion interrupt)",
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
67 "Bulk-Only Transport"
68};
69
Aaron Durbin1c20e382013-06-07 12:31:21 -050070static void
71usb_msc_create_disk (usbdev_t *dev)
72{
73 if (usbdisk_create) {
74 usbdisk_create (dev);
75 MSC_INST (dev)->usbdisk_created = 1;
76 }
77}
78
79static void
80usb_msc_remove_disk (usbdev_t *dev)
81{
82 if (MSC_INST (dev)->usbdisk_created && usbdisk_remove)
83 usbdisk_remove (dev);
84}
Patrick Georgid21f68b2008-09-02 16:06:22 +000085
86static void
87usb_msc_destroy (usbdev_t *dev)
88{
Nico Huber445a3a02012-06-21 10:52:49 +020089 if (dev->data) {
Aaron Durbin1c20e382013-06-07 12:31:21 -050090 usb_msc_remove_disk (dev);
Nico Huber445a3a02012-06-21 10:52:49 +020091 free (dev->data);
92 }
Patrick Georgid21f68b2008-09-02 16:06:22 +000093 dev->data = 0;
94}
95
Patrick Georgid21f68b2008-09-02 16:06:22 +000096const int DEV_RESET = 0xff;
97const int GET_MAX_LUN = 0xfe;
Duncan Laurie3a65d852013-09-12 13:27:15 -070098/* Many USB3 devices do not work with large transfer requests.
99 * Limit the request size to 64KB chunks to ensure maximum compatibility. */
100const int MAX_CHUNK_BYTES = 1024 * 64;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000101
102const unsigned int cbw_signature = 0x43425355;
103const unsigned int csw_signature = 0x53425355;
104
105typedef struct {
106 unsigned int dCBWSignature;
107 unsigned int dCBWTag;
108 unsigned int dCBWDataTransferLength;
109 unsigned char bmCBWFlags;
110 unsigned long bCBWLUN:4;
111 unsigned long:4;
112 unsigned long bCBWCBLength:5;
113 unsigned long:3;
114 unsigned char CBWCB[31 - 15];
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000115} __attribute__ ((packed)) cbw_t;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000116
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000117typedef struct {
118 unsigned int dCSWSignature;
119 unsigned int dCSWTag;
120 unsigned int dCSWDataResidue;
121 unsigned char bCSWStatus;
122} __attribute__ ((packed)) csw_t;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000123
Nico Huber79e1f2f2012-06-01 09:50:11 +0200124enum {
125 /*
126 * MSC commands can be
127 * successful,
128 * fail with proper response or
Julius Wernerb59e8502013-09-25 13:54:57 -0700129 * fail totally, which results in detaching of the usb device
130 * and immediate cleanup of the usbdev_t structure.
Nico Huber79e1f2f2012-06-01 09:50:11 +0200131 * In the latter case the caller has to make sure, that he won't
132 * use the device any more.
133 */
134 MSC_COMMAND_OK = 0, MSC_COMMAND_FAIL, MSC_COMMAND_DETACHED
135};
136
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000137static int
138request_sense (usbdev_t *dev);
Aaron Durbina967f412013-06-06 16:14:21 -0500139static int
140request_sense_no_media (usbdev_t *dev);
Aaron Durbin1c20e382013-06-07 12:31:21 -0500141static void
142usb_msc_poll (usbdev_t *dev);
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000143
Nico Huber79e1f2f2012-06-01 09:50:11 +0200144static int
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000145reset_transport (usbdev_t *dev)
Patrick Georgid21f68b2008-09-02 16:06:22 +0000146{
147 dev_req_t dr;
148 memset (&dr, 0, sizeof (dr));
149 dr.bmRequestType = 0;
150 dr.data_dir = host_to_device;
151#ifndef QEMU
152 dr.req_type = class_type;
153 dr.req_recp = iface_recp;
154#endif
155 dr.bRequest = DEV_RESET;
156 dr.wValue = 0;
157 dr.wIndex = 0;
158 dr.wLength = 0;
Nico Huber79e1f2f2012-06-01 09:50:11 +0200159
160 /* if any of these fails, detach device, as we are lost */
Julius Wernere9738db2013-02-21 13:41:40 -0800161 if (dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0) < 0 ||
Nico Huber79e1f2f2012-06-01 09:50:11 +0200162 clear_stall (MSC_INST (dev)->bulk_in) ||
163 clear_stall (MSC_INST (dev)->bulk_out)) {
Dave Frodin6bf11cf2012-12-11 13:08:07 -0700164 usb_debug ("Detaching unresponsive device.\n");
Nico Huber79e1f2f2012-06-01 09:50:11 +0200165 usb_detach_device (dev->controller, dev->address);
166 return MSC_COMMAND_DETACHED;
167 }
168 /* return fail as we are only called in case of failure */
169 return MSC_COMMAND_FAIL;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000170}
171
172/* device may stall this command, so beware! */
Julius Wernere30e4e72014-05-02 16:35:50 -0700173static void
174initialize_luns (usbdev_t *dev)
Patrick Georgid21f68b2008-09-02 16:06:22 +0000175{
Julius Wernere30e4e72014-05-02 16:35:50 -0700176 usbmsc_inst_t *msc = MSC_INST (dev);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000177 dev_req_t dr;
178 dr.bmRequestType = 0;
179 dr.data_dir = device_to_host;
180#ifndef QEMU
181 dr.req_type = class_type;
182 dr.req_recp = iface_recp;
183#endif
184 dr.bRequest = GET_MAX_LUN;
185 dr.wValue = 0;
186 dr.wIndex = 0;
187 dr.wLength = 1;
Julius Wernere30e4e72014-05-02 16:35:50 -0700188 if (dev->controller->control (dev, IN, sizeof (dr), &dr,
189 sizeof (msc->num_luns), &msc->num_luns) < 0)
190 msc->num_luns = 0; /* assume only 1 lun if req fails */
191 msc->num_luns++; /* Get Max LUN returns number of last LUN */
192 msc->lun = 0;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000193}
194
Nico Huber43b9f322012-05-21 14:05:41 +0200195unsigned int tag;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000196
197static void
198wrap_cbw (cbw_t *cbw, int datalen, cbw_direction dir, const u8 *cmd,
Julius Wernere30e4e72014-05-02 16:35:50 -0700199 int cmdlen, u8 lun)
Patrick Georgid21f68b2008-09-02 16:06:22 +0000200{
201 memset (cbw, 0, sizeof (cbw_t));
202
Patrick Georgi3cb56e92014-12-29 20:37:45 +0100203 /* commands are typically shorter, but we don't want overflows */
204 if (cmdlen > sizeof(cbw->CBWCB)) {
205 cmdlen = sizeof(cbw->CBWCB);
206 }
207
Patrick Georgid21f68b2008-09-02 16:06:22 +0000208 cbw->dCBWSignature = cbw_signature;
Nico Huber43b9f322012-05-21 14:05:41 +0200209 cbw->dCBWTag = ++tag;
Julius Wernere30e4e72014-05-02 16:35:50 -0700210 cbw->bCBWLUN = lun;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000211
212 cbw->dCBWDataTransferLength = datalen;
213 cbw->bmCBWFlags = dir;
Julius Werner71247882014-05-02 14:51:03 -0700214 memcpy (cbw->CBWCB, cmd, cmdlen);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000215 cbw->bCBWCBLength = cmdlen;
216}
217
Nico Huber43b9f322012-05-21 14:05:41 +0200218static int
Patrick Georgid21f68b2008-09-02 16:06:22 +0000219get_csw (endpoint_t *ep, csw_t *csw)
220{
Julius Wernere9738db2013-02-21 13:41:40 -0800221 if (ep->dev->controller->bulk (ep, sizeof (csw_t), (u8 *) csw, 1) < 0) {
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000222 clear_stall (ep);
Nico Huber43b9f322012-05-21 14:05:41 +0200223 if (ep->dev->controller->bulk
Julius Wernere9738db2013-02-21 13:41:40 -0800224 (ep, sizeof (csw_t), (u8 *) csw, 1) < 0) {
Nico Huber79e1f2f2012-06-01 09:50:11 +0200225 return reset_transport (ep->dev);
Nico Huber43b9f322012-05-21 14:05:41 +0200226 }
227 }
228 if (csw->dCSWTag != tag) {
Nico Huber79e1f2f2012-06-01 09:50:11 +0200229 return reset_transport (ep->dev);
Nico Huber43b9f322012-05-21 14:05:41 +0200230 }
Nico Huber79e1f2f2012-06-01 09:50:11 +0200231 return MSC_COMMAND_OK;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000232}
233
234static int
235execute_command (usbdev_t *dev, cbw_direction dir, const u8 *cb, int cblen,
Nico Huber79e1f2f2012-06-01 09:50:11 +0200236 u8 *buf, int buflen, int residue_ok)
Patrick Georgid21f68b2008-09-02 16:06:22 +0000237{
238 cbw_t cbw;
239 csw_t csw;
240
241 int always_succeed = 0;
242 if ((cb[0] == 0x1b) && (cb[4] == 1)) { //start command, always succeed
243 always_succeed = 1;
244 }
Julius Wernere30e4e72014-05-02 16:35:50 -0700245 wrap_cbw (&cbw, buflen, dir, cb, cblen, MSC_INST (dev)->lun);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000246 if (dev->controller->
Julius Wernere9738db2013-02-21 13:41:40 -0800247 bulk (MSC_INST (dev)->bulk_out, sizeof (cbw), (u8 *) &cbw, 0) < 0) {
Nico Huber79e1f2f2012-06-01 09:50:11 +0200248 return reset_transport (dev);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000249 }
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000250 if (buflen > 0) {
251 if (dir == cbw_direction_data_in) {
252 if (dev->controller->
Julius Wernere9738db2013-02-21 13:41:40 -0800253 bulk (MSC_INST (dev)->bulk_in, buflen, buf, 0) < 0)
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000254 clear_stall (MSC_INST (dev)->bulk_in);
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000255 } else {
256 if (dev->controller->
Julius Wernere9738db2013-02-21 13:41:40 -0800257 bulk (MSC_INST (dev)->bulk_out, buflen, buf, 0) < 0)
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000258 clear_stall (MSC_INST (dev)->bulk_out);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000259 }
260 }
Nico Huber79e1f2f2012-06-01 09:50:11 +0200261 int ret = get_csw (MSC_INST (dev)->bulk_in, &csw);
262 if (ret) {
263 return ret;
264 } else if (always_succeed == 1) {
265 /* return success, regardless of message */
266 return MSC_COMMAND_OK;
267 } else if (csw.bCSWStatus == 2) {
268 /* phase error, reset transport */
269 return reset_transport (dev);
270 } else if (csw.bCSWStatus == 0) {
271 if ((csw.dCSWDataResidue == 0) || residue_ok)
272 /* no error, exit */
273 return MSC_COMMAND_OK;
274 else
275 /* missed some bytes */
276 return MSC_COMMAND_FAIL;
277 } else {
278 if (cb[0] == 0x03)
279 /* requesting sense failed, that's bad */
280 return MSC_COMMAND_FAIL;
Aaron Durbina967f412013-06-06 16:14:21 -0500281 else if (cb[0] == 0)
282 /* If command was TEST UNIT READY determine if the
283 * device is of removable type indicating no media
284 * found. */
285 return request_sense_no_media (dev);
Nico Huber79e1f2f2012-06-01 09:50:11 +0200286 /* error "check condition" or reserved error */
287 ret = request_sense (dev);
288 /* return fail or the status of request_sense if it's worse */
289 return ret ? ret : MSC_COMMAND_FAIL;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000290 }
Patrick Georgid21f68b2008-09-02 16:06:22 +0000291}
292
293typedef struct {
294 unsigned char command; //0
295 unsigned char res1; //1
296 unsigned int block; //2-5
297 unsigned char res2; //6
298 unsigned short numblocks; //7-8
Julius Werner71247882014-05-02 14:51:03 -0700299 unsigned char control; //9 - the block is 10 bytes long
Patrick Georgid21f68b2008-09-02 16:06:22 +0000300} __attribute__ ((packed)) cmdblock_t;
301
302typedef struct {
303 unsigned char command; //0
304 unsigned char res1; //1
305 unsigned char res2; //2
306 unsigned char res3; //3
Julius Werner71247882014-05-02 14:51:03 -0700307 union { //4
308 struct {
309 unsigned long start:1; // for START STOP UNIT
310 unsigned long:7;
311 };
312 unsigned char length; // for REQUEST SENSE
313 };
314 unsigned char control; //5
Patrick Georgid21f68b2008-09-02 16:06:22 +0000315} __attribute__ ((packed)) cmdblock6_t;
316
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000317/**
318 * Like readwrite_blocks, but for soft-sectors of 512b size. Converts the
319 * start and count from 512b units.
320 * Start and count must be aligned so that they match the native
321 * sector size.
322 *
323 * @param dev device to access
324 * @param start first sector to access
325 * @param n number of sectors to access
326 * @param dir direction of access: cbw_direction_data_in == read, cbw_direction_data_out == write
327 * @param buf buffer to read into or write from. Must be at least n*512 bytes
328 * @return 0 on success, 1 on failure
329 */
330int
331readwrite_blocks_512 (usbdev_t *dev, int start, int n,
332 cbw_direction dir, u8 *buf)
333{
334 int blocksize_divider = MSC_INST(dev)->blocksize / 512;
335 return readwrite_blocks (dev, start / blocksize_divider,
336 n / blocksize_divider, dir, buf);
337}
Patrick Georgid21f68b2008-09-02 16:06:22 +0000338
339/**
340 * Reads or writes a number of sequential blocks on a USB storage device.
341 * As it uses the READ(10) SCSI-2 command, it's limited to storage devices
342 * of at most 2TB. It assumes sectors of 512 bytes.
343 *
344 * @param dev device to access
345 * @param start first sector to access
346 * @param n number of sectors to access
347 * @param dir direction of access: cbw_direction_data_in == read, cbw_direction_data_out == write
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000348 * @param buf buffer to read into or write from. Must be at least n*sectorsize bytes
Patrick Georgid21f68b2008-09-02 16:06:22 +0000349 * @return 0 on success, 1 on failure
350 */
Gabe Blacke8eb86f2013-09-18 05:37:20 -0700351static int
Duncan Laurie3a65d852013-09-12 13:27:15 -0700352readwrite_chunk (usbdev_t *dev, int start, int n, cbw_direction dir, u8 *buf)
Patrick Georgid21f68b2008-09-02 16:06:22 +0000353{
354 cmdblock_t cb;
355 memset (&cb, 0, sizeof (cb));
356 if (dir == cbw_direction_data_in) {
357 // read
358 cb.command = 0x28;
359 } else {
360 // write
361 cb.command = 0x2a;
362 }
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000363 cb.block = htonl (start);
364 cb.numblocks = htonw (n);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000365
Patrick Georgid21f68b2008-09-02 16:06:22 +0000366 return execute_command (dev, dir, (u8 *) &cb, sizeof (cb), buf,
Nico Huber79e1f2f2012-06-01 09:50:11 +0200367 n * MSC_INST(dev)->blocksize, 0)
368 != MSC_COMMAND_OK ? 1 : 0;
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000369}
370
Duncan Laurie3a65d852013-09-12 13:27:15 -0700371/**
372 * Reads or writes a number of sequential blocks on a USB storage device
373 * that is split into MAX_CHUNK_BYTES size requests.
374 *
375 * As it uses the READ(10) SCSI-2 command, it's limited to storage devices
376 * of at most 2TB. It assumes sectors of 512 bytes.
377 *
378 * @param dev device to access
379 * @param start first sector to access
380 * @param n number of sectors to access
381 * @param dir direction of access: cbw_direction_data_in == read,
382 * cbw_direction_data_out == write
383 * @param buf buffer to read into or write from.
384 * Must be at least n*sectorsize bytes
385 * @return 0 on success, 1 on failure
386 */
387int
388readwrite_blocks (usbdev_t *dev, int start, int n, cbw_direction dir, u8 *buf)
389{
390 int chunk_size = MAX_CHUNK_BYTES / MSC_INST(dev)->blocksize;
391 int chunk;
392
393 /* Read as many full chunks as needed. */
394 for (chunk = 0; chunk < (n / chunk_size); chunk++) {
395 if (readwrite_chunk (dev, start + (chunk * chunk_size),
396 chunk_size, dir,
397 buf + (chunk * MAX_CHUNK_BYTES))
398 != MSC_COMMAND_OK)
399 return 1;
400 }
401
402 /* Read any remaining partial chunk at the end. */
403 if (n % chunk_size) {
404 if (readwrite_chunk (dev, start + (chunk * chunk_size),
405 n % chunk_size, dir,
406 buf + (chunk * MAX_CHUNK_BYTES))
407 != MSC_COMMAND_OK)
408 return 1;
409 }
410
411 return 0;
412}
413
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000414/* Only request it, we don't interpret it.
415 On certain errors, that's necessary to get devices out of
416 a special state called "Contingent Allegiance Condition" */
417static int
418request_sense (usbdev_t *dev)
419{
420 u8 buf[19];
421 cmdblock6_t cb;
422 memset (&cb, 0, sizeof (cb));
423 cb.command = 0x3;
Julius Werner71247882014-05-02 14:51:03 -0700424 cb.length = sizeof (buf);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000425
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000426 return execute_command (dev, cbw_direction_data_in, (u8 *) &cb,
Julius Werner71247882014-05-02 14:51:03 -0700427 sizeof (cb), buf, sizeof (buf), 1);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000428}
429
Aaron Durbin1c20e382013-06-07 12:31:21 -0500430static int request_sense_no_media (usbdev_t *dev)
Aaron Durbina967f412013-06-06 16:14:21 -0500431{
432 u8 buf[19];
433 int ret;
434 cmdblock6_t cb;
435 memset (&cb, 0, sizeof (cb));
436 cb.command = 0x3;
Julius Werner71247882014-05-02 14:51:03 -0700437 cb.length = sizeof (buf);
Aaron Durbina967f412013-06-06 16:14:21 -0500438
439 ret = execute_command (dev, cbw_direction_data_in, (u8 *) &cb,
Julius Werner71247882014-05-02 14:51:03 -0700440 sizeof (cb), buf, sizeof (buf), 1);
Aaron Durbina967f412013-06-06 16:14:21 -0500441
442 if (ret)
443 return ret;
444
445 /* Check if sense key is set to NOT READY. */
446 if ((buf[2] & 0xf) != 2)
447 return MSC_COMMAND_FAIL;
448
449 /* Check if additional sense code is 0x3a. */
450 if (buf[12] != 0x3a)
451 return MSC_COMMAND_FAIL;
452
Aaron Durbin1c20e382013-06-07 12:31:21 -0500453 /* No media is present. Return MSC_COMMAND_OK while marking the disk
454 * not ready. */
455 usb_debug ("Empty media found.\n");
Julius Wernerb59e8502013-09-25 13:54:57 -0700456 MSC_INST (dev)->ready = USB_MSC_NOT_READY;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500457 return MSC_COMMAND_OK;
Aaron Durbina967f412013-06-06 16:14:21 -0500458}
459
Patrick Georgid21f68b2008-09-02 16:06:22 +0000460static int
461test_unit_ready (usbdev_t *dev)
462{
463 cmdblock6_t cb;
464 memset (&cb, 0, sizeof (cb)); // full initialization for T-U-R
465 return execute_command (dev, cbw_direction_data_out, (u8 *) &cb,
Nico Huber79e1f2f2012-06-01 09:50:11 +0200466 sizeof (cb), 0, 0, 0);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000467}
468
469static int
470spin_up (usbdev_t *dev)
471{
472 cmdblock6_t cb;
473 memset (&cb, 0, sizeof (cb));
474 cb.command = 0x1b;
Julius Werner71247882014-05-02 14:51:03 -0700475 cb.start = 1;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000476 return execute_command (dev, cbw_direction_data_out, (u8 *) &cb,
Nico Huber79e1f2f2012-06-01 09:50:11 +0200477 sizeof (cb), 0, 0, 0);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000478}
479
Nico Huber79e1f2f2012-06-01 09:50:11 +0200480static int
Patrick Georgid21f68b2008-09-02 16:06:22 +0000481read_capacity (usbdev_t *dev)
482{
483 cmdblock_t cb;
484 memset (&cb, 0, sizeof (cb));
485 cb.command = 0x25; // read capacity
Gabe Black2c2c4fa2013-01-15 16:22:04 -0800486 u32 buf[2];
Stefan Reinauerd233f362009-04-30 16:46:12 +0000487
Gabe Black93ded592012-11-01 15:44:10 -0700488 usb_debug ("Reading capacity of mass storage device.\n");
Nico Huber79e1f2f2012-06-01 09:50:11 +0200489 int count = 0, ret;
490 while (count++ < 20) {
491 switch (ret = execute_command
492 (dev, cbw_direction_data_in, (u8 *) &cb,
Gabe Black2c2c4fa2013-01-15 16:22:04 -0800493 sizeof (cb), (u8 *)buf, 8, 0)) {
Nico Huber79e1f2f2012-06-01 09:50:11 +0200494 case MSC_COMMAND_OK:
495 break;
496 case MSC_COMMAND_FAIL:
497 continue;
498 default: /* if it's worse return */
499 return ret;
500 }
501 break;
502 }
Patrick Georgid21f68b2008-09-02 16:06:22 +0000503 if (count >= 20) {
Stefan Reinauerd233f362009-04-30 16:46:12 +0000504 // still not successful, assume 2tb in 512byte sectors, which is just the same garbage as any other number, but probably more usable.
Dave Frodin6bf11cf2012-12-11 13:08:07 -0700505 usb_debug (" assuming 2 TB with 512-byte sectors as READ CAPACITY didn't answer.\n");
Patrick Georgid21f68b2008-09-02 16:06:22 +0000506 MSC_INST (dev)->numblocks = 0xffffffff;
507 MSC_INST (dev)->blocksize = 512;
508 } else {
Gabe Black2c2c4fa2013-01-15 16:22:04 -0800509 MSC_INST (dev)->numblocks = ntohl(buf[0]) + 1;
510 MSC_INST (dev)->blocksize = ntohl(buf[1]);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000511 }
Dave Frodin6bf11cf2012-12-11 13:08:07 -0700512 usb_debug (" %d %d-byte sectors (%d MB)\n", MSC_INST (dev)->numblocks,
Mathias Krausec4716b42011-06-08 15:36:55 +0200513 MSC_INST (dev)->blocksize,
Nico Huberc43e7362012-05-21 13:59:43 +0200514 /* round down high block counts to avoid integer overflow */
515 MSC_INST (dev)->numblocks > 1000000
516 ? (MSC_INST (dev)->numblocks / 1000) * MSC_INST (dev)->blocksize / 1000 :
Mathias Krausec4716b42011-06-08 15:36:55 +0200517 MSC_INST (dev)->numblocks * MSC_INST (dev)->blocksize / 1000 / 1000);
Nico Huber79e1f2f2012-06-01 09:50:11 +0200518 return MSC_COMMAND_OK;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000519}
520
Julius Wernerb59e8502013-09-25 13:54:57 -0700521static int
Aaron Durbin1c20e382013-06-07 12:31:21 -0500522usb_msc_test_unit_ready (usbdev_t *dev)
523{
524 int i;
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700525 time_t start_time_secs;
526 struct timeval tv;
Shawn Nematbakhshdf6d09d2013-09-12 18:23:09 -0700527 /* SCSI/ATA specs say we have to wait up to 30s, but most devices
528 * are ready much sooner. Use a 5 sec timeout to better accomodate
529 * devices which fail to respond. */
530 const int timeout_secs = 5;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500531
532 usb_debug (" Waiting for device to become ready...");
533
534 /* Initially mark the device ready. */
Julius Wernerb59e8502013-09-25 13:54:57 -0700535 MSC_INST (dev)->ready = USB_MSC_READY;
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700536 gettimeofday (&tv, NULL);
537 start_time_secs = tv.tv_sec;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500538
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700539 while (tv.tv_sec - start_time_secs < timeout_secs) {
Aaron Durbin1c20e382013-06-07 12:31:21 -0500540 switch (test_unit_ready (dev)) {
541 case MSC_COMMAND_OK:
542 break;
543 case MSC_COMMAND_FAIL:
544 mdelay (100);
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700545 usb_debug (".");
546 gettimeofday (&tv, NULL);
Aaron Durbin1c20e382013-06-07 12:31:21 -0500547 continue;
548 default:
Julius Wernerb59e8502013-09-25 13:54:57 -0700549 /* Device detached, return immediately */
550 return USB_MSC_DETACHED;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500551 }
552 break;
553 }
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700554 if (!(tv.tv_sec - start_time_secs < timeout_secs)) {
Aaron Durbin1c20e382013-06-07 12:31:21 -0500555 usb_debug ("timeout. Device not ready.\n");
Julius Wernerb59e8502013-09-25 13:54:57 -0700556 MSC_INST (dev)->ready = USB_MSC_NOT_READY;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500557 }
558
559 /* Don't bother spinning up the stroage device if the device is not
560 * ready. This can happen when empty card readers are present.
561 * Polling will pick it back up if readiness changes. */
Julius Wernerb59e8502013-09-25 13:54:57 -0700562 if (!MSC_INST (dev)->ready)
563 return MSC_INST (dev)->ready;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500564
565 usb_debug ("ok.\n");
566
567 usb_debug (" spin up");
568 for (i = 0; i < 30; i++) {
569 usb_debug (".");
570 switch (spin_up (dev)) {
571 case MSC_COMMAND_OK:
572 usb_debug (" OK.");
573 break;
574 case MSC_COMMAND_FAIL:
575 mdelay (100);
576 continue;
577 default:
Julius Wernerb59e8502013-09-25 13:54:57 -0700578 /* Device detached, return immediately */
579 return USB_MSC_DETACHED;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500580 }
581 break;
582 }
583 usb_debug ("\n");
584
Julius Wernerb59e8502013-09-25 13:54:57 -0700585 if (read_capacity (dev) == MSC_COMMAND_DETACHED)
586 return USB_MSC_DETACHED;
587
588 return MSC_INST (dev)->ready;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500589}
590
Patrick Georgid21f68b2008-09-02 16:06:22 +0000591void
592usb_msc_init (usbdev_t *dev)
593{
Aaron Durbin1c20e382013-06-07 12:31:21 -0500594 int i;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000595
Nico Huber445a3a02012-06-21 10:52:49 +0200596 /* init .data before setting .destroy */
597 dev->data = NULL;
598
Patrick Georgid21f68b2008-09-02 16:06:22 +0000599 dev->destroy = usb_msc_destroy;
600 dev->poll = usb_msc_poll;
601
602 configuration_descriptor_t *cd =
603 (configuration_descriptor_t *) dev->configuration;
604 interface_descriptor_t *interface =
605 (interface_descriptor_t *) (((char *) cd) + cd->bLength);
606
Gabe Black93ded592012-11-01 15:44:10 -0700607 usb_debug (" it uses %s command set\n",
Patrick Georgid21f68b2008-09-02 16:06:22 +0000608 msc_subclass_strings[interface->bInterfaceSubClass]);
Gabe Black93ded592012-11-01 15:44:10 -0700609 usb_debug (" it uses %s protocol\n",
Patrick Georgid21f68b2008-09-02 16:06:22 +0000610 msc_protocol_strings[interface->bInterfaceProtocol]);
611
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000612
613 if (interface->bInterfaceProtocol != 0x50) {
Dave Frodin6bf11cf2012-12-11 13:08:07 -0700614 usb_debug (" Protocol not supported.\n");
Julius Wernerd609e892013-09-25 12:30:07 -0700615 usb_detach_device (dev->controller, dev->address);
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000616 return;
617 }
618
619 if ((interface->bInterfaceSubClass != 2) && // ATAPI 8020
620 (interface->bInterfaceSubClass != 5) && // ATAPI 8070
621 (interface->bInterfaceSubClass != 6)) { // SCSI
Patrick Georgid21f68b2008-09-02 16:06:22 +0000622 /* Other protocols, such as ATAPI don't seem to be very popular. looks like ATAPI would be really easy to add, if necessary. */
Dave Frodin6bf11cf2012-12-11 13:08:07 -0700623 usb_debug (" Interface SubClass not supported.\n");
Julius Wernerd609e892013-09-25 12:30:07 -0700624 usb_detach_device (dev->controller, dev->address);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000625 return;
626 }
627
628 dev->data = malloc (sizeof (usbmsc_inst_t));
Stefan Reinauer5fe6e232009-07-31 11:39:55 +0000629 if (!dev->data)
Patrick Georgi2e768e72011-11-04 11:50:03 +0100630 fatal("Not enough memory for USB MSC device.\n");
Stefan Reinauer5fe6e232009-07-31 11:39:55 +0000631
Patrick Georgid21f68b2008-09-02 16:06:22 +0000632 MSC_INST (dev)->bulk_in = 0;
633 MSC_INST (dev)->bulk_out = 0;
Nico Huber445a3a02012-06-21 10:52:49 +0200634 MSC_INST (dev)->usbdisk_created = 0;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000635
636 for (i = 1; i <= dev->num_endp; i++) {
637 if (dev->endpoints[i].endpoint == 0)
638 continue;
639 if (dev->endpoints[i].type != BULK)
640 continue;
641 if ((dev->endpoints[i].direction == IN)
642 && (MSC_INST (dev)->bulk_in == 0))
643 MSC_INST (dev)->bulk_in = &dev->endpoints[i];
644 if ((dev->endpoints[i].direction == OUT)
645 && (MSC_INST (dev)->bulk_out == 0))
646 MSC_INST (dev)->bulk_out = &dev->endpoints[i];
647 }
648
Nico Huber445a3a02012-06-21 10:52:49 +0200649 if (MSC_INST (dev)->bulk_in == 0) {
Julius Wernerd609e892013-09-25 12:30:07 -0700650 usb_debug("couldn't find bulk-in endpoint.\n");
651 usb_detach_device (dev->controller, dev->address);
Nico Huber445a3a02012-06-21 10:52:49 +0200652 return;
653 }
654 if (MSC_INST (dev)->bulk_out == 0) {
Julius Wernerd609e892013-09-25 12:30:07 -0700655 usb_debug("couldn't find bulk-out endpoint.\n");
656 usb_detach_device (dev->controller, dev->address);
Nico Huber445a3a02012-06-21 10:52:49 +0200657 return;
658 }
Gabe Black93ded592012-11-01 15:44:10 -0700659 usb_debug (" using endpoint %x as in, %x as out\n",
Patrick Georgid21f68b2008-09-02 16:06:22 +0000660 MSC_INST (dev)->bulk_in->endpoint,
661 MSC_INST (dev)->bulk_out->endpoint);
662
Julius Werner8db7e672015-10-26 11:44:00 -0700663 /* Some sticks need a little more time to get ready after SET_CONFIG. */
664 udelay(50);
665
Julius Wernere30e4e72014-05-02 16:35:50 -0700666 initialize_luns (dev);
667 usb_debug (" has %d luns\n", MSC_INST (dev)->num_luns);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000668
Julius Wernerb59e8502013-09-25 13:54:57 -0700669 /* Test if unit is ready (nothing to do if it isn't). */
670 if (usb_msc_test_unit_ready (dev) != USB_MSC_READY)
Aaron Durbin1c20e382013-06-07 12:31:21 -0500671 return;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000672
Aaron Durbin1c20e382013-06-07 12:31:21 -0500673 /* Create the disk. */
674 usb_msc_create_disk (dev);
675}
676
677static void
678usb_msc_poll (usbdev_t *dev)
679{
Julius Wernere30e4e72014-05-02 16:35:50 -0700680 usbmsc_inst_t *msc = MSC_INST (dev);
681 int prev_ready = msc->ready;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500682
Julius Wernerb59e8502013-09-25 13:54:57 -0700683 if (usb_msc_test_unit_ready (dev) == USB_MSC_DETACHED)
Aaron Durbin1c20e382013-06-07 12:31:21 -0500684 return;
685
Julius Wernere30e4e72014-05-02 16:35:50 -0700686 if (!prev_ready && msc->ready) {
687 usb_debug ("usb msc: not ready -> ready (lun %d)\n", msc->lun);
Aaron Durbin1c20e382013-06-07 12:31:21 -0500688 usb_msc_create_disk (dev);
Julius Wernere30e4e72014-05-02 16:35:50 -0700689 } else if (prev_ready && !msc->ready) {
690 usb_debug ("usb msc: ready -> not ready (lun %d)\n", msc->lun);
Aaron Durbin1c20e382013-06-07 12:31:21 -0500691 usb_msc_remove_disk (dev);
Julius Wernere30e4e72014-05-02 16:35:50 -0700692 } else if (!prev_ready && !msc->ready) {
693 u8 new_lun = (msc->lun + 1) % msc->num_luns;
694 usb_debug("usb msc: not ready (lun %d) -> lun %d\n", msc->lun,
695 new_lun);
696 msc->lun = new_lun;
Nico Huber445a3a02012-06-21 10:52:49 +0200697 }
Patrick Georgid21f68b2008-09-02 16:06:22 +0000698}