blob: 62428b6ebef766feb6c488b0a9edbc4a6f0ba107 [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
203 cbw->dCBWSignature = cbw_signature;
Nico Huber43b9f322012-05-21 14:05:41 +0200204 cbw->dCBWTag = ++tag;
Julius Wernere30e4e72014-05-02 16:35:50 -0700205 cbw->bCBWLUN = lun;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000206
207 cbw->dCBWDataTransferLength = datalen;
208 cbw->bmCBWFlags = dir;
Julius Werner71247882014-05-02 14:51:03 -0700209 memcpy (cbw->CBWCB, cmd, cmdlen);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000210 cbw->bCBWCBLength = cmdlen;
211}
212
Nico Huber43b9f322012-05-21 14:05:41 +0200213static int
Patrick Georgid21f68b2008-09-02 16:06:22 +0000214get_csw (endpoint_t *ep, csw_t *csw)
215{
Julius Wernere9738db2013-02-21 13:41:40 -0800216 if (ep->dev->controller->bulk (ep, sizeof (csw_t), (u8 *) csw, 1) < 0) {
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000217 clear_stall (ep);
Nico Huber43b9f322012-05-21 14:05:41 +0200218 if (ep->dev->controller->bulk
Julius Wernere9738db2013-02-21 13:41:40 -0800219 (ep, sizeof (csw_t), (u8 *) csw, 1) < 0) {
Nico Huber79e1f2f2012-06-01 09:50:11 +0200220 return reset_transport (ep->dev);
Nico Huber43b9f322012-05-21 14:05:41 +0200221 }
222 }
223 if (csw->dCSWTag != tag) {
Nico Huber79e1f2f2012-06-01 09:50:11 +0200224 return reset_transport (ep->dev);
Nico Huber43b9f322012-05-21 14:05:41 +0200225 }
Nico Huber79e1f2f2012-06-01 09:50:11 +0200226 return MSC_COMMAND_OK;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000227}
228
229static int
230execute_command (usbdev_t *dev, cbw_direction dir, const u8 *cb, int cblen,
Nico Huber79e1f2f2012-06-01 09:50:11 +0200231 u8 *buf, int buflen, int residue_ok)
Patrick Georgid21f68b2008-09-02 16:06:22 +0000232{
233 cbw_t cbw;
234 csw_t csw;
235
236 int always_succeed = 0;
237 if ((cb[0] == 0x1b) && (cb[4] == 1)) { //start command, always succeed
238 always_succeed = 1;
239 }
Julius Wernere30e4e72014-05-02 16:35:50 -0700240 wrap_cbw (&cbw, buflen, dir, cb, cblen, MSC_INST (dev)->lun);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000241 if (dev->controller->
Julius Wernere9738db2013-02-21 13:41:40 -0800242 bulk (MSC_INST (dev)->bulk_out, sizeof (cbw), (u8 *) &cbw, 0) < 0) {
Nico Huber79e1f2f2012-06-01 09:50:11 +0200243 return reset_transport (dev);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000244 }
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000245 if (buflen > 0) {
246 if (dir == cbw_direction_data_in) {
247 if (dev->controller->
Julius Wernere9738db2013-02-21 13:41:40 -0800248 bulk (MSC_INST (dev)->bulk_in, buflen, buf, 0) < 0)
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000249 clear_stall (MSC_INST (dev)->bulk_in);
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000250 } else {
251 if (dev->controller->
Julius Wernere9738db2013-02-21 13:41:40 -0800252 bulk (MSC_INST (dev)->bulk_out, buflen, buf, 0) < 0)
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000253 clear_stall (MSC_INST (dev)->bulk_out);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000254 }
255 }
Nico Huber79e1f2f2012-06-01 09:50:11 +0200256 int ret = get_csw (MSC_INST (dev)->bulk_in, &csw);
257 if (ret) {
258 return ret;
259 } else if (always_succeed == 1) {
260 /* return success, regardless of message */
261 return MSC_COMMAND_OK;
262 } else if (csw.bCSWStatus == 2) {
263 /* phase error, reset transport */
264 return reset_transport (dev);
265 } else if (csw.bCSWStatus == 0) {
266 if ((csw.dCSWDataResidue == 0) || residue_ok)
267 /* no error, exit */
268 return MSC_COMMAND_OK;
269 else
270 /* missed some bytes */
271 return MSC_COMMAND_FAIL;
272 } else {
273 if (cb[0] == 0x03)
274 /* requesting sense failed, that's bad */
275 return MSC_COMMAND_FAIL;
Aaron Durbina967f412013-06-06 16:14:21 -0500276 else if (cb[0] == 0)
277 /* If command was TEST UNIT READY determine if the
278 * device is of removable type indicating no media
279 * found. */
280 return request_sense_no_media (dev);
Nico Huber79e1f2f2012-06-01 09:50:11 +0200281 /* error "check condition" or reserved error */
282 ret = request_sense (dev);
283 /* return fail or the status of request_sense if it's worse */
284 return ret ? ret : MSC_COMMAND_FAIL;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000285 }
Patrick Georgid21f68b2008-09-02 16:06:22 +0000286}
287
288typedef struct {
289 unsigned char command; //0
290 unsigned char res1; //1
291 unsigned int block; //2-5
292 unsigned char res2; //6
293 unsigned short numblocks; //7-8
Julius Werner71247882014-05-02 14:51:03 -0700294 unsigned char control; //9 - the block is 10 bytes long
Patrick Georgid21f68b2008-09-02 16:06:22 +0000295} __attribute__ ((packed)) cmdblock_t;
296
297typedef struct {
298 unsigned char command; //0
299 unsigned char res1; //1
300 unsigned char res2; //2
301 unsigned char res3; //3
Julius Werner71247882014-05-02 14:51:03 -0700302 union { //4
303 struct {
304 unsigned long start:1; // for START STOP UNIT
305 unsigned long:7;
306 };
307 unsigned char length; // for REQUEST SENSE
308 };
309 unsigned char control; //5
Patrick Georgid21f68b2008-09-02 16:06:22 +0000310} __attribute__ ((packed)) cmdblock6_t;
311
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000312/**
313 * Like readwrite_blocks, but for soft-sectors of 512b size. Converts the
314 * start and count from 512b units.
315 * Start and count must be aligned so that they match the native
316 * sector size.
317 *
318 * @param dev device to access
319 * @param start first sector to access
320 * @param n number of sectors to access
321 * @param dir direction of access: cbw_direction_data_in == read, cbw_direction_data_out == write
322 * @param buf buffer to read into or write from. Must be at least n*512 bytes
323 * @return 0 on success, 1 on failure
324 */
325int
326readwrite_blocks_512 (usbdev_t *dev, int start, int n,
327 cbw_direction dir, u8 *buf)
328{
329 int blocksize_divider = MSC_INST(dev)->blocksize / 512;
330 return readwrite_blocks (dev, start / blocksize_divider,
331 n / blocksize_divider, dir, buf);
332}
Patrick Georgid21f68b2008-09-02 16:06:22 +0000333
334/**
335 * Reads or writes a number of sequential blocks on a USB storage device.
336 * As it uses the READ(10) SCSI-2 command, it's limited to storage devices
337 * of at most 2TB. It assumes sectors of 512 bytes.
338 *
339 * @param dev device to access
340 * @param start first sector to access
341 * @param n number of sectors to access
342 * @param dir direction of access: cbw_direction_data_in == read, cbw_direction_data_out == write
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000343 * @param buf buffer to read into or write from. Must be at least n*sectorsize bytes
Patrick Georgid21f68b2008-09-02 16:06:22 +0000344 * @return 0 on success, 1 on failure
345 */
Gabe Blacke8eb86f2013-09-18 05:37:20 -0700346static int
Duncan Laurie3a65d852013-09-12 13:27:15 -0700347readwrite_chunk (usbdev_t *dev, int start, int n, cbw_direction dir, u8 *buf)
Patrick Georgid21f68b2008-09-02 16:06:22 +0000348{
349 cmdblock_t cb;
350 memset (&cb, 0, sizeof (cb));
351 if (dir == cbw_direction_data_in) {
352 // read
353 cb.command = 0x28;
354 } else {
355 // write
356 cb.command = 0x2a;
357 }
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000358 cb.block = htonl (start);
359 cb.numblocks = htonw (n);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000360
Patrick Georgid21f68b2008-09-02 16:06:22 +0000361 return execute_command (dev, dir, (u8 *) &cb, sizeof (cb), buf,
Nico Huber79e1f2f2012-06-01 09:50:11 +0200362 n * MSC_INST(dev)->blocksize, 0)
363 != MSC_COMMAND_OK ? 1 : 0;
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000364}
365
Duncan Laurie3a65d852013-09-12 13:27:15 -0700366/**
367 * Reads or writes a number of sequential blocks on a USB storage device
368 * that is split into MAX_CHUNK_BYTES size requests.
369 *
370 * As it uses the READ(10) SCSI-2 command, it's limited to storage devices
371 * of at most 2TB. It assumes sectors of 512 bytes.
372 *
373 * @param dev device to access
374 * @param start first sector to access
375 * @param n number of sectors to access
376 * @param dir direction of access: cbw_direction_data_in == read,
377 * cbw_direction_data_out == write
378 * @param buf buffer to read into or write from.
379 * Must be at least n*sectorsize bytes
380 * @return 0 on success, 1 on failure
381 */
382int
383readwrite_blocks (usbdev_t *dev, int start, int n, cbw_direction dir, u8 *buf)
384{
385 int chunk_size = MAX_CHUNK_BYTES / MSC_INST(dev)->blocksize;
386 int chunk;
387
388 /* Read as many full chunks as needed. */
389 for (chunk = 0; chunk < (n / chunk_size); chunk++) {
390 if (readwrite_chunk (dev, start + (chunk * chunk_size),
391 chunk_size, dir,
392 buf + (chunk * MAX_CHUNK_BYTES))
393 != MSC_COMMAND_OK)
394 return 1;
395 }
396
397 /* Read any remaining partial chunk at the end. */
398 if (n % chunk_size) {
399 if (readwrite_chunk (dev, start + (chunk * chunk_size),
400 n % chunk_size, dir,
401 buf + (chunk * MAX_CHUNK_BYTES))
402 != MSC_COMMAND_OK)
403 return 1;
404 }
405
406 return 0;
407}
408
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000409/* Only request it, we don't interpret it.
410 On certain errors, that's necessary to get devices out of
411 a special state called "Contingent Allegiance Condition" */
412static int
413request_sense (usbdev_t *dev)
414{
415 u8 buf[19];
416 cmdblock6_t cb;
417 memset (&cb, 0, sizeof (cb));
418 cb.command = 0x3;
Julius Werner71247882014-05-02 14:51:03 -0700419 cb.length = sizeof (buf);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000420
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000421 return execute_command (dev, cbw_direction_data_in, (u8 *) &cb,
Julius Werner71247882014-05-02 14:51:03 -0700422 sizeof (cb), buf, sizeof (buf), 1);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000423}
424
Aaron Durbin1c20e382013-06-07 12:31:21 -0500425static int request_sense_no_media (usbdev_t *dev)
Aaron Durbina967f412013-06-06 16:14:21 -0500426{
427 u8 buf[19];
428 int ret;
429 cmdblock6_t cb;
430 memset (&cb, 0, sizeof (cb));
431 cb.command = 0x3;
Julius Werner71247882014-05-02 14:51:03 -0700432 cb.length = sizeof (buf);
Aaron Durbina967f412013-06-06 16:14:21 -0500433
434 ret = execute_command (dev, cbw_direction_data_in, (u8 *) &cb,
Julius Werner71247882014-05-02 14:51:03 -0700435 sizeof (cb), buf, sizeof (buf), 1);
Aaron Durbina967f412013-06-06 16:14:21 -0500436
437 if (ret)
438 return ret;
439
440 /* Check if sense key is set to NOT READY. */
441 if ((buf[2] & 0xf) != 2)
442 return MSC_COMMAND_FAIL;
443
444 /* Check if additional sense code is 0x3a. */
445 if (buf[12] != 0x3a)
446 return MSC_COMMAND_FAIL;
447
Aaron Durbin1c20e382013-06-07 12:31:21 -0500448 /* No media is present. Return MSC_COMMAND_OK while marking the disk
449 * not ready. */
450 usb_debug ("Empty media found.\n");
Julius Wernerb59e8502013-09-25 13:54:57 -0700451 MSC_INST (dev)->ready = USB_MSC_NOT_READY;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500452 return MSC_COMMAND_OK;
Aaron Durbina967f412013-06-06 16:14:21 -0500453}
454
Patrick Georgid21f68b2008-09-02 16:06:22 +0000455static int
456test_unit_ready (usbdev_t *dev)
457{
458 cmdblock6_t cb;
459 memset (&cb, 0, sizeof (cb)); // full initialization for T-U-R
460 return execute_command (dev, cbw_direction_data_out, (u8 *) &cb,
Nico Huber79e1f2f2012-06-01 09:50:11 +0200461 sizeof (cb), 0, 0, 0);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000462}
463
464static int
465spin_up (usbdev_t *dev)
466{
467 cmdblock6_t cb;
468 memset (&cb, 0, sizeof (cb));
469 cb.command = 0x1b;
Julius Werner71247882014-05-02 14:51:03 -0700470 cb.start = 1;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000471 return execute_command (dev, cbw_direction_data_out, (u8 *) &cb,
Nico Huber79e1f2f2012-06-01 09:50:11 +0200472 sizeof (cb), 0, 0, 0);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000473}
474
Nico Huber79e1f2f2012-06-01 09:50:11 +0200475static int
Patrick Georgid21f68b2008-09-02 16:06:22 +0000476read_capacity (usbdev_t *dev)
477{
478 cmdblock_t cb;
479 memset (&cb, 0, sizeof (cb));
480 cb.command = 0x25; // read capacity
Gabe Black2c2c4fa2013-01-15 16:22:04 -0800481 u32 buf[2];
Stefan Reinauerd233f362009-04-30 16:46:12 +0000482
Gabe Black93ded592012-11-01 15:44:10 -0700483 usb_debug ("Reading capacity of mass storage device.\n");
Nico Huber79e1f2f2012-06-01 09:50:11 +0200484 int count = 0, ret;
485 while (count++ < 20) {
486 switch (ret = execute_command
487 (dev, cbw_direction_data_in, (u8 *) &cb,
Gabe Black2c2c4fa2013-01-15 16:22:04 -0800488 sizeof (cb), (u8 *)buf, 8, 0)) {
Nico Huber79e1f2f2012-06-01 09:50:11 +0200489 case MSC_COMMAND_OK:
490 break;
491 case MSC_COMMAND_FAIL:
492 continue;
493 default: /* if it's worse return */
494 return ret;
495 }
496 break;
497 }
Patrick Georgid21f68b2008-09-02 16:06:22 +0000498 if (count >= 20) {
Stefan Reinauerd233f362009-04-30 16:46:12 +0000499 // 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 -0700500 usb_debug (" assuming 2 TB with 512-byte sectors as READ CAPACITY didn't answer.\n");
Patrick Georgid21f68b2008-09-02 16:06:22 +0000501 MSC_INST (dev)->numblocks = 0xffffffff;
502 MSC_INST (dev)->blocksize = 512;
503 } else {
Gabe Black2c2c4fa2013-01-15 16:22:04 -0800504 MSC_INST (dev)->numblocks = ntohl(buf[0]) + 1;
505 MSC_INST (dev)->blocksize = ntohl(buf[1]);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000506 }
Dave Frodin6bf11cf2012-12-11 13:08:07 -0700507 usb_debug (" %d %d-byte sectors (%d MB)\n", MSC_INST (dev)->numblocks,
Mathias Krausec4716b42011-06-08 15:36:55 +0200508 MSC_INST (dev)->blocksize,
Nico Huberc43e7362012-05-21 13:59:43 +0200509 /* round down high block counts to avoid integer overflow */
510 MSC_INST (dev)->numblocks > 1000000
511 ? (MSC_INST (dev)->numblocks / 1000) * MSC_INST (dev)->blocksize / 1000 :
Mathias Krausec4716b42011-06-08 15:36:55 +0200512 MSC_INST (dev)->numblocks * MSC_INST (dev)->blocksize / 1000 / 1000);
Nico Huber79e1f2f2012-06-01 09:50:11 +0200513 return MSC_COMMAND_OK;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000514}
515
Julius Wernerb59e8502013-09-25 13:54:57 -0700516static int
Aaron Durbin1c20e382013-06-07 12:31:21 -0500517usb_msc_test_unit_ready (usbdev_t *dev)
518{
519 int i;
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700520 time_t start_time_secs;
521 struct timeval tv;
Shawn Nematbakhshdf6d09d2013-09-12 18:23:09 -0700522 /* SCSI/ATA specs say we have to wait up to 30s, but most devices
523 * are ready much sooner. Use a 5 sec timeout to better accomodate
524 * devices which fail to respond. */
525 const int timeout_secs = 5;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500526
527 usb_debug (" Waiting for device to become ready...");
528
529 /* Initially mark the device ready. */
Julius Wernerb59e8502013-09-25 13:54:57 -0700530 MSC_INST (dev)->ready = USB_MSC_READY;
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700531 gettimeofday (&tv, NULL);
532 start_time_secs = tv.tv_sec;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500533
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700534 while (tv.tv_sec - start_time_secs < timeout_secs) {
Aaron Durbin1c20e382013-06-07 12:31:21 -0500535 switch (test_unit_ready (dev)) {
536 case MSC_COMMAND_OK:
537 break;
538 case MSC_COMMAND_FAIL:
539 mdelay (100);
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700540 usb_debug (".");
541 gettimeofday (&tv, NULL);
Aaron Durbin1c20e382013-06-07 12:31:21 -0500542 continue;
543 default:
Julius Wernerb59e8502013-09-25 13:54:57 -0700544 /* Device detached, return immediately */
545 return USB_MSC_DETACHED;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500546 }
547 break;
548 }
Shawn Nematbakhsh7ecc9122013-09-12 18:09:39 -0700549 if (!(tv.tv_sec - start_time_secs < timeout_secs)) {
Aaron Durbin1c20e382013-06-07 12:31:21 -0500550 usb_debug ("timeout. Device not ready.\n");
Julius Wernerb59e8502013-09-25 13:54:57 -0700551 MSC_INST (dev)->ready = USB_MSC_NOT_READY;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500552 }
553
554 /* Don't bother spinning up the stroage device if the device is not
555 * ready. This can happen when empty card readers are present.
556 * Polling will pick it back up if readiness changes. */
Julius Wernerb59e8502013-09-25 13:54:57 -0700557 if (!MSC_INST (dev)->ready)
558 return MSC_INST (dev)->ready;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500559
560 usb_debug ("ok.\n");
561
562 usb_debug (" spin up");
563 for (i = 0; i < 30; i++) {
564 usb_debug (".");
565 switch (spin_up (dev)) {
566 case MSC_COMMAND_OK:
567 usb_debug (" OK.");
568 break;
569 case MSC_COMMAND_FAIL:
570 mdelay (100);
571 continue;
572 default:
Julius Wernerb59e8502013-09-25 13:54:57 -0700573 /* Device detached, return immediately */
574 return USB_MSC_DETACHED;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500575 }
576 break;
577 }
578 usb_debug ("\n");
579
Julius Wernerb59e8502013-09-25 13:54:57 -0700580 if (read_capacity (dev) == MSC_COMMAND_DETACHED)
581 return USB_MSC_DETACHED;
582
583 return MSC_INST (dev)->ready;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500584}
585
Patrick Georgid21f68b2008-09-02 16:06:22 +0000586void
587usb_msc_init (usbdev_t *dev)
588{
Aaron Durbin1c20e382013-06-07 12:31:21 -0500589 int i;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000590
Nico Huber445a3a02012-06-21 10:52:49 +0200591 /* init .data before setting .destroy */
592 dev->data = NULL;
593
Patrick Georgid21f68b2008-09-02 16:06:22 +0000594 dev->destroy = usb_msc_destroy;
595 dev->poll = usb_msc_poll;
596
597 configuration_descriptor_t *cd =
598 (configuration_descriptor_t *) dev->configuration;
599 interface_descriptor_t *interface =
600 (interface_descriptor_t *) (((char *) cd) + cd->bLength);
601
Gabe Black93ded592012-11-01 15:44:10 -0700602 usb_debug (" it uses %s command set\n",
Patrick Georgid21f68b2008-09-02 16:06:22 +0000603 msc_subclass_strings[interface->bInterfaceSubClass]);
Gabe Black93ded592012-11-01 15:44:10 -0700604 usb_debug (" it uses %s protocol\n",
Patrick Georgid21f68b2008-09-02 16:06:22 +0000605 msc_protocol_strings[interface->bInterfaceProtocol]);
606
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000607
608 if (interface->bInterfaceProtocol != 0x50) {
Dave Frodin6bf11cf2012-12-11 13:08:07 -0700609 usb_debug (" Protocol not supported.\n");
Julius Wernerd609e892013-09-25 12:30:07 -0700610 usb_detach_device (dev->controller, dev->address);
Stefan Reinauerb56f2d02010-03-25 22:17:36 +0000611 return;
612 }
613
614 if ((interface->bInterfaceSubClass != 2) && // ATAPI 8020
615 (interface->bInterfaceSubClass != 5) && // ATAPI 8070
616 (interface->bInterfaceSubClass != 6)) { // SCSI
Patrick Georgid21f68b2008-09-02 16:06:22 +0000617 /* 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 -0700618 usb_debug (" Interface SubClass not supported.\n");
Julius Wernerd609e892013-09-25 12:30:07 -0700619 usb_detach_device (dev->controller, dev->address);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000620 return;
621 }
622
623 dev->data = malloc (sizeof (usbmsc_inst_t));
Stefan Reinauer5fe6e232009-07-31 11:39:55 +0000624 if (!dev->data)
Patrick Georgi2e768e72011-11-04 11:50:03 +0100625 fatal("Not enough memory for USB MSC device.\n");
Stefan Reinauer5fe6e232009-07-31 11:39:55 +0000626
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
Julius Wernere30e4e72014-05-02 16:35:50 -0700658 initialize_luns (dev);
659 usb_debug (" has %d luns\n", MSC_INST (dev)->num_luns);
Patrick Georgid21f68b2008-09-02 16:06:22 +0000660
Julius Wernerb59e8502013-09-25 13:54:57 -0700661 /* Test if unit is ready (nothing to do if it isn't). */
662 if (usb_msc_test_unit_ready (dev) != USB_MSC_READY)
Aaron Durbin1c20e382013-06-07 12:31:21 -0500663 return;
Patrick Georgid21f68b2008-09-02 16:06:22 +0000664
Aaron Durbin1c20e382013-06-07 12:31:21 -0500665 /* Create the disk. */
666 usb_msc_create_disk (dev);
667}
668
669static void
670usb_msc_poll (usbdev_t *dev)
671{
Julius Wernere30e4e72014-05-02 16:35:50 -0700672 usbmsc_inst_t *msc = MSC_INST (dev);
673 int prev_ready = msc->ready;
Aaron Durbin1c20e382013-06-07 12:31:21 -0500674
Julius Wernerb59e8502013-09-25 13:54:57 -0700675 if (usb_msc_test_unit_ready (dev) == USB_MSC_DETACHED)
Aaron Durbin1c20e382013-06-07 12:31:21 -0500676 return;
677
Julius Wernere30e4e72014-05-02 16:35:50 -0700678 if (!prev_ready && msc->ready) {
679 usb_debug ("usb msc: not ready -> ready (lun %d)\n", msc->lun);
Aaron Durbin1c20e382013-06-07 12:31:21 -0500680 usb_msc_create_disk (dev);
Julius Wernere30e4e72014-05-02 16:35:50 -0700681 } else if (prev_ready && !msc->ready) {
682 usb_debug ("usb msc: ready -> not ready (lun %d)\n", msc->lun);
Aaron Durbin1c20e382013-06-07 12:31:21 -0500683 usb_msc_remove_disk (dev);
Julius Wernere30e4e72014-05-02 16:35:50 -0700684 } else if (!prev_ready && !msc->ready) {
685 u8 new_lun = (msc->lun + 1) % msc->num_luns;
686 usb_debug("usb msc: not ready (lun %d) -> lun %d\n", msc->lun,
687 new_lun);
688 msc->lun = new_lun;
Nico Huber445a3a02012-06-21 10:52:49 +0200689 }
Patrick Georgid21f68b2008-09-02 16:06:22 +0000690}