blob: 3b5206ef85cc404836e5e58b6f8407cc8bc7ea91 [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! */
173static int
174get_max_luns (usbdev_t *dev)
175{
176 unsigned char luns = 75;
177 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 Wernere9738db2013-02-21 13:41:40 -0800188 if (dev->controller->control (dev, IN, sizeof (dr), &dr, 1, &luns) < 0)
Patrick Georgid21f68b2008-09-02 16:06:22 +0000189 luns = 0; // assume only 1 lun if req fails
Patrick Georgid21f68b2008-09-02 16:06:22 +0000190 return luns;
191}
192
Nico Huber43b9f322012-05-21 14:05:41 +0200193unsigned int tag;
194unsigned char lun = 0;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000195
196static void
197wrap_cbw (cbw_t *cbw, int datalen, cbw_direction dir, const u8 *cmd,
198 int cmdlen)
199{
200 memset (cbw, 0, sizeof (cbw_t));
201
202 cbw->dCBWSignature = cbw_signature;
Nico Huber43b9f322012-05-21 14:05:41 +0200203 cbw->dCBWTag = ++tag;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000204 cbw->bCBWLUN = lun; // static value per device
205
206 cbw->dCBWDataTransferLength = datalen;
207 cbw->bmCBWFlags = dir;
Julius Werner71247882014-05-02 14:51:03 -0700208 memcpy (cbw->CBWCB, cmd, cmdlen);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000209 cbw->bCBWCBLength = cmdlen;
210}
211
Nico Huber43b9f322012-05-21 14:05:41 +0200212static int
Patrick Georgid21f68b2008-09-02 16:06:22 +0000213get_csw (endpoint_t *ep, csw_t *csw)
214{
Julius Wernere9738db2013-02-21 13:41:40 -0800215 if (ep->dev->controller->bulk (ep, sizeof (csw_t), (u8 *) csw, 1) < 0) {
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000216 clear_stall (ep);
Nico Huber43b9f322012-05-21 14:05:41 +0200217 if (ep->dev->controller->bulk
Julius Wernere9738db2013-02-21 13:41:40 -0800218 (ep, sizeof (csw_t), (u8 *) csw, 1) < 0) {
Nico Huber79e1f2f2012-06-01 09:50:11 +0200219 return reset_transport (ep->dev);
Nico Huber43b9f322012-05-21 14:05:41 +0200220 }
221 }
222 if (csw->dCSWTag != tag) {
Nico Huber79e1f2f2012-06-01 09:50:11 +0200223 return reset_transport (ep->dev);
Nico Huber43b9f322012-05-21 14:05:41 +0200224 }
Nico Huber79e1f2f2012-06-01 09:50:11 +0200225 return MSC_COMMAND_OK;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000226}
227
228static int
229execute_command (usbdev_t *dev, cbw_direction dir, const u8 *cb, int cblen,
Nico Huber79e1f2f2012-06-01 09:50:11 +0200230 u8 *buf, int buflen, int residue_ok)
Patrick Georgid21f68b2008-09-02 16:06:22 +0000231{
232 cbw_t cbw;
233 csw_t csw;
234
235 int always_succeed = 0;
236 if ((cb[0] == 0x1b) && (cb[4] == 1)) { //start command, always succeed
237 always_succeed = 1;
238 }
239 wrap_cbw (&cbw, buflen, dir, cb, cblen);
240 if (dev->controller->
Julius Wernere9738db2013-02-21 13:41:40 -0800241 bulk (MSC_INST (dev)->bulk_out, sizeof (cbw), (u8 *) &cbw, 0) < 0) {
Nico Huber79e1f2f2012-06-01 09:50:11 +0200242 return reset_transport (dev);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000243 }
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000244 if (buflen > 0) {
245 if (dir == cbw_direction_data_in) {
246 if (dev->controller->
Julius Wernere9738db2013-02-21 13:41:40 -0800247 bulk (MSC_INST (dev)->bulk_in, buflen, buf, 0) < 0)
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000248 clear_stall (MSC_INST (dev)->bulk_in);
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000249 } else {
250 if (dev->controller->
Julius Wernere9738db2013-02-21 13:41:40 -0800251 bulk (MSC_INST (dev)->bulk_out, buflen, buf, 0) < 0)
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000252 clear_stall (MSC_INST (dev)->bulk_out);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000253 }
254 }
Nico Huber79e1f2f2012-06-01 09:50:11 +0200255 int ret = get_csw (MSC_INST (dev)->bulk_in, &csw);
256 if (ret) {
257 return ret;
258 } else if (always_succeed == 1) {
259 /* return success, regardless of message */
260 return MSC_COMMAND_OK;
261 } else if (csw.bCSWStatus == 2) {
262 /* phase error, reset transport */
263 return reset_transport (dev);
264 } else if (csw.bCSWStatus == 0) {
265 if ((csw.dCSWDataResidue == 0) || residue_ok)
266 /* no error, exit */
267 return MSC_COMMAND_OK;
268 else
269 /* missed some bytes */
270 return MSC_COMMAND_FAIL;
271 } else {
272 if (cb[0] == 0x03)
273 /* requesting sense failed, that's bad */
274 return MSC_COMMAND_FAIL;
Aaron Durbina967f412013-06-06 16:14:21 -0500275 else if (cb[0] == 0)
276 /* If command was TEST UNIT READY determine if the
277 * device is of removable type indicating no media
278 * found. */
279 return request_sense_no_media (dev);
Nico Huber79e1f2f2012-06-01 09:50:11 +0200280 /* error "check condition" or reserved error */
281 ret = request_sense (dev);
282 /* return fail or the status of request_sense if it's worse */
283 return ret ? ret : MSC_COMMAND_FAIL;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000284 }
Patrick Georgid21f68b2008-09-02 16:06:22 +0000285}
286
287typedef struct {
288 unsigned char command; //0
289 unsigned char res1; //1
290 unsigned int block; //2-5
291 unsigned char res2; //6
292 unsigned short numblocks; //7-8
Julius Werner71247882014-05-02 14:51:03 -0700293 unsigned char control; //9 - the block is 10 bytes long
Patrick Georgid21f68b2008-09-02 16:06:22 +0000294} __attribute__ ((packed)) cmdblock_t;
295
296typedef struct {
297 unsigned char command; //0
298 unsigned char res1; //1
299 unsigned char res2; //2
300 unsigned char res3; //3
Julius Werner71247882014-05-02 14:51:03 -0700301 union { //4
302 struct {
303 unsigned long start:1; // for START STOP UNIT
304 unsigned long:7;
305 };
306 unsigned char length; // for REQUEST SENSE
307 };
308 unsigned char control; //5
Patrick Georgid21f68b2008-09-02 16:06:22 +0000309} __attribute__ ((packed)) cmdblock6_t;
310
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000311/**
312 * Like readwrite_blocks, but for soft-sectors of 512b size. Converts the
313 * start and count from 512b units.
314 * Start and count must be aligned so that they match the native
315 * sector size.
316 *
317 * @param dev device to access
318 * @param start first sector to access
319 * @param n number of sectors to access
320 * @param dir direction of access: cbw_direction_data_in == read, cbw_direction_data_out == write
321 * @param buf buffer to read into or write from. Must be at least n*512 bytes
322 * @return 0 on success, 1 on failure
323 */
324int
325readwrite_blocks_512 (usbdev_t *dev, int start, int n,
326 cbw_direction dir, u8 *buf)
327{
328 int blocksize_divider = MSC_INST(dev)->blocksize / 512;
329 return readwrite_blocks (dev, start / blocksize_divider,
330 n / blocksize_divider, dir, buf);
331}
Patrick Georgid21f68b2008-09-02 16:06:22 +0000332
333/**
334 * Reads or writes a number of sequential blocks on a USB storage device.
335 * As it uses the READ(10) SCSI-2 command, it's limited to storage devices
336 * of at most 2TB. It assumes sectors of 512 bytes.
337 *
338 * @param dev device to access
339 * @param start first sector to access
340 * @param n number of sectors to access
341 * @param dir direction of access: cbw_direction_data_in == read, cbw_direction_data_out == write
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000342 * @param buf buffer to read into or write from. Must be at least n*sectorsize bytes
Patrick Georgid21f68b2008-09-02 16:06:22 +0000343 * @return 0 on success, 1 on failure
344 */
Gabe Blacke8eb86f2013-09-18 05:37:20 -0700345static int
Duncan Laurie3a65d852013-09-12 13:27:15 -0700346readwrite_chunk (usbdev_t *dev, int start, int n, cbw_direction dir, u8 *buf)
Patrick Georgid21f68b2008-09-02 16:06:22 +0000347{
348 cmdblock_t cb;
349 memset (&cb, 0, sizeof (cb));
350 if (dir == cbw_direction_data_in) {
351 // read
352 cb.command = 0x28;
353 } else {
354 // write
355 cb.command = 0x2a;
356 }
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000357 cb.block = htonl (start);
358 cb.numblocks = htonw (n);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000359
Patrick Georgid21f68b2008-09-02 16:06:22 +0000360 return execute_command (dev, dir, (u8 *) &cb, sizeof (cb), buf,
Nico Huber79e1f2f2012-06-01 09:50:11 +0200361 n * MSC_INST(dev)->blocksize, 0)
362 != MSC_COMMAND_OK ? 1 : 0;
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000363}
364
Duncan Laurie3a65d852013-09-12 13:27:15 -0700365/**
366 * Reads or writes a number of sequential blocks on a USB storage device
367 * that is split into MAX_CHUNK_BYTES size requests.
368 *
369 * As it uses the READ(10) SCSI-2 command, it's limited to storage devices
370 * of at most 2TB. It assumes sectors of 512 bytes.
371 *
372 * @param dev device to access
373 * @param start first sector to access
374 * @param n number of sectors to access
375 * @param dir direction of access: cbw_direction_data_in == read,
376 * cbw_direction_data_out == write
377 * @param buf buffer to read into or write from.
378 * Must be at least n*sectorsize bytes
379 * @return 0 on success, 1 on failure
380 */
381int
382readwrite_blocks (usbdev_t *dev, int start, int n, cbw_direction dir, u8 *buf)
383{
384 int chunk_size = MAX_CHUNK_BYTES / MSC_INST(dev)->blocksize;
385 int chunk;
386
387 /* Read as many full chunks as needed. */
388 for (chunk = 0; chunk < (n / chunk_size); chunk++) {
389 if (readwrite_chunk (dev, start + (chunk * chunk_size),
390 chunk_size, dir,
391 buf + (chunk * MAX_CHUNK_BYTES))
392 != MSC_COMMAND_OK)
393 return 1;
394 }
395
396 /* Read any remaining partial chunk at the end. */
397 if (n % chunk_size) {
398 if (readwrite_chunk (dev, start + (chunk * chunk_size),
399 n % chunk_size, dir,
400 buf + (chunk * MAX_CHUNK_BYTES))
401 != MSC_COMMAND_OK)
402 return 1;
403 }
404
405 return 0;
406}
407
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000408/* Only request it, we don't interpret it.
409 On certain errors, that's necessary to get devices out of
410 a special state called "Contingent Allegiance Condition" */
411static int
412request_sense (usbdev_t *dev)
413{
414 u8 buf[19];
415 cmdblock6_t cb;
416 memset (&cb, 0, sizeof (cb));
417 cb.command = 0x3;
Julius Werner71247882014-05-02 14:51:03 -0700418 cb.length = sizeof (buf);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000419
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000420 return execute_command (dev, cbw_direction_data_in, (u8 *) &cb,
Julius Werner71247882014-05-02 14:51:03 -0700421 sizeof (cb), buf, sizeof (buf), 1);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000422}
423
Aaron Durbin1c20e382013-06-07 12:31:21 -0500424static int request_sense_no_media (usbdev_t *dev)
Aaron Durbina967f412013-06-06 16:14:21 -0500425{
426 u8 buf[19];
427 int ret;
428 cmdblock6_t cb;
429 memset (&cb, 0, sizeof (cb));
430 cb.command = 0x3;
Julius Werner71247882014-05-02 14:51:03 -0700431 cb.length = sizeof (buf);
Aaron Durbina967f412013-06-06 16:14:21 -0500432
433 ret = execute_command (dev, cbw_direction_data_in, (u8 *) &cb,
Julius Werner71247882014-05-02 14:51:03 -0700434 sizeof (cb), buf, sizeof (buf), 1);
Aaron Durbina967f412013-06-06 16:14:21 -0500435
436 if (ret)
437 return ret;
438
439 /* Check if sense key is set to NOT READY. */
440 if ((buf[2] & 0xf) != 2)
441 return MSC_COMMAND_FAIL;
442
443 /* Check if additional sense code is 0x3a. */
444 if (buf[12] != 0x3a)
445 return MSC_COMMAND_FAIL;
446
Aaron Durbin1c20e382013-06-07 12:31:21 -0500447 /* No media is present. Return MSC_COMMAND_OK while marking the disk
448 * not ready. */
449 usb_debug ("Empty media found.\n");
Julius Wernerb59e8502013-09-25 13:54:57 -0700450 MSC_INST (dev)->ready = USB_MSC_NOT_READY;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500451 return MSC_COMMAND_OK;
Aaron Durbina967f412013-06-06 16:14:21 -0500452}
453
Patrick Georgid21f68b2008-09-02 16:06:22 +0000454static int
455test_unit_ready (usbdev_t *dev)
456{
457 cmdblock6_t cb;
458 memset (&cb, 0, sizeof (cb)); // full initialization for T-U-R
459 return execute_command (dev, cbw_direction_data_out, (u8 *) &cb,
Nico Huber79e1f2f2012-06-01 09:50:11 +0200460 sizeof (cb), 0, 0, 0);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000461}
462
463static int
464spin_up (usbdev_t *dev)
465{
466 cmdblock6_t cb;
467 memset (&cb, 0, sizeof (cb));
468 cb.command = 0x1b;
Julius Werner71247882014-05-02 14:51:03 -0700469 cb.start = 1;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000470 return execute_command (dev, cbw_direction_data_out, (u8 *) &cb,
Nico Huber79e1f2f2012-06-01 09:50:11 +0200471 sizeof (cb), 0, 0, 0);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000472}
473
Nico Huber79e1f2f2012-06-01 09:50:11 +0200474static int
Patrick Georgid21f68b2008-09-02 16:06:22 +0000475read_capacity (usbdev_t *dev)
476{
477 cmdblock_t cb;
478 memset (&cb, 0, sizeof (cb));
479 cb.command = 0x25; // read capacity
Gabe Black2c2c4fa2013-01-15 16:22:04 -0800480 u32 buf[2];
Stefan Reinauerd233f362009-04-30 16:46:12 +0000481
Gabe Black93ded592012-11-01 15:44:10 -0700482 usb_debug ("Reading capacity of mass storage device.\n");
Nico Huber79e1f2f2012-06-01 09:50:11 +0200483 int count = 0, ret;
484 while (count++ < 20) {
485 switch (ret = execute_command
486 (dev, cbw_direction_data_in, (u8 *) &cb,
Gabe Black2c2c4fa2013-01-15 16:22:04 -0800487 sizeof (cb), (u8 *)buf, 8, 0)) {
Nico Huber79e1f2f2012-06-01 09:50:11 +0200488 case MSC_COMMAND_OK:
489 break;
490 case MSC_COMMAND_FAIL:
491 continue;
492 default: /* if it's worse return */
493 return ret;
494 }
495 break;
496 }
Patrick Georgid21f68b2008-09-02 16:06:22 +0000497 if (count >= 20) {
Stefan Reinauerd233f362009-04-30 16:46:12 +0000498 // 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 -0700499 usb_debug (" assuming 2 TB with 512-byte sectors as READ CAPACITY didn't answer.\n");
Patrick Georgid21f68b2008-09-02 16:06:22 +0000500 MSC_INST (dev)->numblocks = 0xffffffff;
501 MSC_INST (dev)->blocksize = 512;
502 } else {
Gabe Black2c2c4fa2013-01-15 16:22:04 -0800503 MSC_INST (dev)->numblocks = ntohl(buf[0]) + 1;
504 MSC_INST (dev)->blocksize = ntohl(buf[1]);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000505 }
Dave Frodin6bf11cf2012-12-11 13:08:07 -0700506 usb_debug (" %d %d-byte sectors (%d MB)\n", MSC_INST (dev)->numblocks,
Mathias Krausec4716b42011-06-08 15:36:55 +0200507 MSC_INST (dev)->blocksize,
Nico Huberc43e7362012-05-21 13:59:43 +0200508 /* round down high block counts to avoid integer overflow */
509 MSC_INST (dev)->numblocks > 1000000
510 ? (MSC_INST (dev)->numblocks / 1000) * MSC_INST (dev)->blocksize / 1000 :
Mathias Krausec4716b42011-06-08 15:36:55 +0200511 MSC_INST (dev)->numblocks * MSC_INST (dev)->blocksize / 1000 / 1000);
Nico Huber79e1f2f2012-06-01 09:50:11 +0200512 return MSC_COMMAND_OK;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000513}
514
Julius Wernerb59e8502013-09-25 13:54:57 -0700515static int
Aaron Durbin1c20e382013-06-07 12:31:21 -0500516usb_msc_test_unit_ready (usbdev_t *dev)
517{
518 int i;
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700519 time_t start_time_secs;
520 struct timeval tv;
Shawn Nematbakhshdf6d09d2013-09-12 18:23:09 -0700521 /* SCSI/ATA specs say we have to wait up to 30s, but most devices
522 * are ready much sooner. Use a 5 sec timeout to better accomodate
523 * devices which fail to respond. */
524 const int timeout_secs = 5;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500525
526 usb_debug (" Waiting for device to become ready...");
527
528 /* Initially mark the device ready. */
Julius Wernerb59e8502013-09-25 13:54:57 -0700529 MSC_INST (dev)->ready = USB_MSC_READY;
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700530 gettimeofday (&tv, NULL);
531 start_time_secs = tv.tv_sec;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500532
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700533 while (tv.tv_sec - start_time_secs < timeout_secs) {
Aaron Durbin1c20e382013-06-07 12:31:21 -0500534 switch (test_unit_ready (dev)) {
535 case MSC_COMMAND_OK:
536 break;
537 case MSC_COMMAND_FAIL:
538 mdelay (100);
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700539 usb_debug (".");
540 gettimeofday (&tv, NULL);
Aaron Durbin1c20e382013-06-07 12:31:21 -0500541 continue;
542 default:
Julius Wernerb59e8502013-09-25 13:54:57 -0700543 /* Device detached, return immediately */
544 return USB_MSC_DETACHED;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500545 }
546 break;
547 }
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700548 if (!(tv.tv_sec - start_time_secs < timeout_secs)) {
Aaron Durbin1c20e382013-06-07 12:31:21 -0500549 usb_debug ("timeout. Device not ready.\n");
Julius Wernerb59e8502013-09-25 13:54:57 -0700550 MSC_INST (dev)->ready = USB_MSC_NOT_READY;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500551 }
552
553 /* Don't bother spinning up the stroage device if the device is not
554 * ready. This can happen when empty card readers are present.
555 * Polling will pick it back up if readiness changes. */
Julius Wernerb59e8502013-09-25 13:54:57 -0700556 if (!MSC_INST (dev)->ready)
557 return MSC_INST (dev)->ready;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500558
559 usb_debug ("ok.\n");
560
561 usb_debug (" spin up");
562 for (i = 0; i < 30; i++) {
563 usb_debug (".");
564 switch (spin_up (dev)) {
565 case MSC_COMMAND_OK:
566 usb_debug (" OK.");
567 break;
568 case MSC_COMMAND_FAIL:
569 mdelay (100);
570 continue;
571 default:
Julius Wernerb59e8502013-09-25 13:54:57 -0700572 /* Device detached, return immediately */
573 return USB_MSC_DETACHED;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500574 }
575 break;
576 }
577 usb_debug ("\n");
578
Julius Wernerb59e8502013-09-25 13:54:57 -0700579 if (read_capacity (dev) == MSC_COMMAND_DETACHED)
580 return USB_MSC_DETACHED;
581
582 return MSC_INST (dev)->ready;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500583}
584
Patrick Georgid21f68b2008-09-02 16:06:22 +0000585void
586usb_msc_init (usbdev_t *dev)
587{
Aaron Durbin1c20e382013-06-07 12:31:21 -0500588 int i;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000589
Nico Huber445a3a02012-06-21 10:52:49 +0200590 /* init .data before setting .destroy */
591 dev->data = NULL;
592
Patrick Georgid21f68b2008-09-02 16:06:22 +0000593 dev->destroy = usb_msc_destroy;
594 dev->poll = usb_msc_poll;
595
596 configuration_descriptor_t *cd =
597 (configuration_descriptor_t *) dev->configuration;
598 interface_descriptor_t *interface =
599 (interface_descriptor_t *) (((char *) cd) + cd->bLength);
600
Gabe Black93ded592012-11-01 15:44:10 -0700601 usb_debug (" it uses %s command set\n",
Patrick Georgid21f68b2008-09-02 16:06:22 +0000602 msc_subclass_strings[interface->bInterfaceSubClass]);
Gabe Black93ded592012-11-01 15:44:10 -0700603 usb_debug (" it uses %s protocol\n",
Patrick Georgid21f68b2008-09-02 16:06:22 +0000604 msc_protocol_strings[interface->bInterfaceProtocol]);
605
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000606
607 if (interface->bInterfaceProtocol != 0x50) {
Dave Frodin6bf11cf2012-12-11 13:08:07 -0700608 usb_debug (" Protocol not supported.\n");
Julius Wernerd609e892013-09-25 12:30:07 -0700609 usb_detach_device (dev->controller, dev->address);
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000610 return;
611 }
612
613 if ((interface->bInterfaceSubClass != 2) && // ATAPI 8020
614 (interface->bInterfaceSubClass != 5) && // ATAPI 8070
615 (interface->bInterfaceSubClass != 6)) { // SCSI
Patrick Georgid21f68b2008-09-02 16:06:22 +0000616 /* 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 -0700617 usb_debug (" Interface SubClass not supported.\n");
Julius Wernerd609e892013-09-25 12:30:07 -0700618 usb_detach_device (dev->controller, dev->address);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000619 return;
620 }
621
622 dev->data = malloc (sizeof (usbmsc_inst_t));
Stefan Reinauer5fe6e232009-07-31 11:39:55 +0000623 if (!dev->data)
Patrick Georgi2e768e72011-11-04 11:50:03 +0100624 fatal("Not enough memory for USB MSC device.\n");
Stefan Reinauer5fe6e232009-07-31 11:39:55 +0000625
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000626 MSC_INST (dev)->protocol = interface->bInterfaceSubClass;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000627 MSC_INST (dev)->bulk_in = 0;
628 MSC_INST (dev)->bulk_out = 0;
Nico Huber445a3a02012-06-21 10:52:49 +0200629 MSC_INST (dev)->usbdisk_created = 0;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000630
631 for (i = 1; i <= dev->num_endp; i++) {
632 if (dev->endpoints[i].endpoint == 0)
633 continue;
634 if (dev->endpoints[i].type != BULK)
635 continue;
636 if ((dev->endpoints[i].direction == IN)
637 && (MSC_INST (dev)->bulk_in == 0))
638 MSC_INST (dev)->bulk_in = &dev->endpoints[i];
639 if ((dev->endpoints[i].direction == OUT)
640 && (MSC_INST (dev)->bulk_out == 0))
641 MSC_INST (dev)->bulk_out = &dev->endpoints[i];
642 }
643
Nico Huber445a3a02012-06-21 10:52:49 +0200644 if (MSC_INST (dev)->bulk_in == 0) {
Julius Wernerd609e892013-09-25 12:30:07 -0700645 usb_debug("couldn't find bulk-in endpoint.\n");
646 usb_detach_device (dev->controller, dev->address);
Nico Huber445a3a02012-06-21 10:52:49 +0200647 return;
648 }
649 if (MSC_INST (dev)->bulk_out == 0) {
Julius Wernerd609e892013-09-25 12:30:07 -0700650 usb_debug("couldn't find bulk-out endpoint.\n");
651 usb_detach_device (dev->controller, dev->address);
Nico Huber445a3a02012-06-21 10:52:49 +0200652 return;
653 }
Gabe Black93ded592012-11-01 15:44:10 -0700654 usb_debug (" using endpoint %x as in, %x as out\n",
Patrick Georgid21f68b2008-09-02 16:06:22 +0000655 MSC_INST (dev)->bulk_in->endpoint,
656 MSC_INST (dev)->bulk_out->endpoint);
657
Gabe Black93ded592012-11-01 15:44:10 -0700658 usb_debug (" has %d luns\n", get_max_luns (dev) + 1);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000659
Julius Wernerb59e8502013-09-25 13:54:57 -0700660 /* Test if unit is ready (nothing to do if it isn't). */
661 if (usb_msc_test_unit_ready (dev) != USB_MSC_READY)
Aaron Durbin1c20e382013-06-07 12:31:21 -0500662 return;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000663
Aaron Durbin1c20e382013-06-07 12:31:21 -0500664 /* Create the disk. */
665 usb_msc_create_disk (dev);
666}
667
668static void
669usb_msc_poll (usbdev_t *dev)
670{
Julius Wernerb59e8502013-09-25 13:54:57 -0700671 int prev_ready = MSC_INST (dev)->ready;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500672
Julius Wernerb59e8502013-09-25 13:54:57 -0700673 if (usb_msc_test_unit_ready (dev) == USB_MSC_DETACHED)
Aaron Durbin1c20e382013-06-07 12:31:21 -0500674 return;
675
Julius Wernerb59e8502013-09-25 13:54:57 -0700676 if (!prev_ready && MSC_INST (dev)->ready) {
Aaron Durbin1c20e382013-06-07 12:31:21 -0500677 usb_debug ("usb msc: not ready -> ready\n");
678 usb_msc_create_disk (dev);
Julius Wernerb59e8502013-09-25 13:54:57 -0700679 } else if (prev_ready && !MSC_INST (dev)->ready) {
Aaron Durbin1c20e382013-06-07 12:31:21 -0500680 usb_debug ("usb msc: ready -> not ready\n");
681 usb_msc_remove_disk (dev);
Nico Huber445a3a02012-06-21 10:52:49 +0200682 }
Patrick Georgid21f68b2008-09-02 16:06:22 +0000683}