Rename __attribute__((packed)) --> __packed
[coreboot.git] / payloads / libpayload / drivers / usb / usbmsc.c
blob2c7cbe5ef285e12dd4f5ab0598a5b753ee2000a0
1 /*
2 * This file is part of the libpayload project.
4 * Copyright (C) 2008 coresystems GmbH
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.
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.
30 //#define USB_DEBUG
31 #include <endian.h>
32 #include <usb/usb.h>
33 #include <usb/usbmsc.h>
34 #include <usb/usbdisk.h>
36 enum {
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
45 static const char *msc_subclass_strings[7] = {
46 "(none)",
47 "RBC",
48 "MMC-2",
49 "QIC-157",
50 "UFI",
51 "SFF-8070i",
52 "SCSI transparent"
54 enum {
55 msc_proto_cbi_wcomp = 0x0,
56 msc_proto_cbi_wocomp = 0x1,
57 msc_proto_bulk_only = 0x50
59 static 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"
70 static void
71 usb_msc_create_disk (usbdev_t *dev)
73 if (usbdisk_create) {
74 usbdisk_create (dev);
75 MSC_INST (dev)->usbdisk_created = 1;
79 static void
80 usb_msc_remove_disk (usbdev_t *dev)
82 if (MSC_INST (dev)->usbdisk_created && usbdisk_remove)
83 usbdisk_remove (dev);
86 static void
87 usb_msc_destroy (usbdev_t *dev)
89 if (dev->data) {
90 usb_msc_remove_disk (dev);
91 free (dev->data);
93 dev->data = 0;
96 const int DEV_RESET = 0xff;
97 const int GET_MAX_LUN = 0xfe;
98 /* Many USB3 devices do not work with large transfer requests.
99 * Limit the request size to 64KB chunks to ensure maximum compatibility. */
100 const int MAX_CHUNK_BYTES = 1024 * 64;
102 const unsigned int cbw_signature = 0x43425355;
103 const unsigned int csw_signature = 0x53425355;
105 typedef 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];
115 } __packed cbw_t;
117 typedef struct {
118 unsigned int dCSWSignature;
119 unsigned int dCSWTag;
120 unsigned int dCSWDataResidue;
121 unsigned char bCSWStatus;
122 } __packed csw_t;
124 enum {
126 * MSC commands can be
127 * successful,
128 * fail with proper response or
129 * fail totally, which results in detaching of the usb device
130 * and immediate cleanup of the usbdev_t structure.
131 * In the latter case the caller has to make sure, that he won't
132 * use the device any more.
134 MSC_COMMAND_OK = 0, MSC_COMMAND_FAIL, MSC_COMMAND_DETACHED
137 static int
138 request_sense (usbdev_t *dev);
139 static int
140 request_sense_no_media (usbdev_t *dev);
141 static void
142 usb_msc_poll (usbdev_t *dev);
144 static int
145 reset_transport (usbdev_t *dev)
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;
160 /* if any of these fails, detach device, as we are lost */
161 if (dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0) < 0 ||
162 clear_stall (MSC_INST (dev)->bulk_in) ||
163 clear_stall (MSC_INST (dev)->bulk_out)) {
164 usb_debug ("Detaching unresponsive device.\n");
165 usb_detach_device (dev->controller, dev->address);
166 return MSC_COMMAND_DETACHED;
168 /* return fail as we are only called in case of failure */
169 return MSC_COMMAND_FAIL;
172 /* device may stall this command, so beware! */
173 static void
174 initialize_luns (usbdev_t *dev)
176 usbmsc_inst_t *msc = MSC_INST (dev);
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;
188 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;
195 unsigned int tag;
197 static void
198 wrap_cbw (cbw_t *cbw, int datalen, cbw_direction dir, const u8 *cmd,
199 int cmdlen, u8 lun)
201 memset (cbw, 0, sizeof (cbw_t));
203 /* commands are typically shorter, but we don't want overflows */
204 if (cmdlen > sizeof(cbw->CBWCB)) {
205 cmdlen = sizeof(cbw->CBWCB);
208 cbw->dCBWSignature = cbw_signature;
209 cbw->dCBWTag = ++tag;
210 cbw->bCBWLUN = lun;
212 cbw->dCBWDataTransferLength = datalen;
213 cbw->bmCBWFlags = dir;
214 memcpy (cbw->CBWCB, cmd, cmdlen);
215 cbw->bCBWCBLength = cmdlen;
218 static int
219 get_csw (endpoint_t *ep, csw_t *csw)
221 if (ep->dev->controller->bulk (ep, sizeof (csw_t), (u8 *) csw, 1) < 0) {
222 clear_stall (ep);
223 if (ep->dev->controller->bulk
224 (ep, sizeof (csw_t), (u8 *) csw, 1) < 0) {
225 return reset_transport (ep->dev);
228 if (csw->dCSWTag != tag) {
229 return reset_transport (ep->dev);
231 return MSC_COMMAND_OK;
234 static int
235 execute_command (usbdev_t *dev, cbw_direction dir, const u8 *cb, int cblen,
236 u8 *buf, int buflen, int residue_ok)
238 cbw_t cbw;
239 csw_t csw;
241 int always_succeed = 0;
242 if ((cb[0] == 0x1b) && (cb[4] == 1)) { //start command, always succeed
243 always_succeed = 1;
245 wrap_cbw (&cbw, buflen, dir, cb, cblen, MSC_INST (dev)->lun);
246 if (dev->controller->
247 bulk (MSC_INST (dev)->bulk_out, sizeof (cbw), (u8 *) &cbw, 0) < 0) {
248 return reset_transport (dev);
250 if (buflen > 0) {
251 if (dir == cbw_direction_data_in) {
252 if (dev->controller->
253 bulk (MSC_INST (dev)->bulk_in, buflen, buf, 0) < 0)
254 clear_stall (MSC_INST (dev)->bulk_in);
255 } else {
256 if (dev->controller->
257 bulk (MSC_INST (dev)->bulk_out, buflen, buf, 0) < 0)
258 clear_stall (MSC_INST (dev)->bulk_out);
261 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;
281 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);
286 /* 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;
293 typedef 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
299 unsigned char control; //9 - the block is 10 bytes long
300 } __packed cmdblock_t;
302 typedef struct {
303 unsigned char command; //0
304 unsigned char res1; //1
305 unsigned char res2; //2
306 unsigned char res3; //3
307 union { //4
308 struct {
309 unsigned long start:1; // for START STOP UNIT
310 unsigned long:7;
312 unsigned char length; // for REQUEST SENSE
314 unsigned char control; //5
315 } __packed cmdblock6_t;
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.
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
331 readwrite_blocks_512 (usbdev_t *dev, int start, int n,
332 cbw_direction dir, u8 *buf)
334 int blocksize_divider = MSC_INST(dev)->blocksize / 512;
335 return readwrite_blocks (dev, start / blocksize_divider,
336 n / blocksize_divider, dir, buf);
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.
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
348 * @param buf buffer to read into or write from. Must be at least n*sectorsize bytes
349 * @return 0 on success, 1 on failure
351 static int
352 readwrite_chunk (usbdev_t *dev, int start, int n, cbw_direction dir, u8 *buf)
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;
363 cb.block = htonl (start);
364 cb.numblocks = htonw (n);
366 return execute_command (dev, dir, (u8 *) &cb, sizeof (cb), buf,
367 n * MSC_INST(dev)->blocksize, 0)
368 != MSC_COMMAND_OK ? 1 : 0;
372 * Reads or writes a number of sequential blocks on a USB storage device
373 * that is split into MAX_CHUNK_BYTES size requests.
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.
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
388 readwrite_blocks (usbdev_t *dev, int start, int n, cbw_direction dir, u8 *buf)
390 int chunk_size = MAX_CHUNK_BYTES / MSC_INST(dev)->blocksize;
391 int chunk;
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;
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;
411 return 0;
414 /* 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" */
417 static int
418 request_sense (usbdev_t *dev)
420 u8 buf[19];
421 cmdblock6_t cb;
422 memset (&cb, 0, sizeof (cb));
423 cb.command = 0x3;
424 cb.length = sizeof (buf);
426 return execute_command (dev, cbw_direction_data_in, (u8 *) &cb,
427 sizeof (cb), buf, sizeof (buf), 1);
430 static int request_sense_no_media (usbdev_t *dev)
432 u8 buf[19];
433 int ret;
434 cmdblock6_t cb;
435 memset (&cb, 0, sizeof (cb));
436 cb.command = 0x3;
437 cb.length = sizeof (buf);
439 ret = execute_command (dev, cbw_direction_data_in, (u8 *) &cb,
440 sizeof (cb), buf, sizeof (buf), 1);
442 if (ret)
443 return ret;
445 /* Check if sense key is set to NOT READY. */
446 if ((buf[2] & 0xf) != 2)
447 return MSC_COMMAND_FAIL;
449 /* Check if additional sense code is 0x3a. */
450 if (buf[12] != 0x3a)
451 return MSC_COMMAND_FAIL;
453 /* No media is present. Return MSC_COMMAND_OK while marking the disk
454 * not ready. */
455 usb_debug ("Empty media found.\n");
456 MSC_INST (dev)->ready = USB_MSC_NOT_READY;
457 return MSC_COMMAND_OK;
460 static int
461 test_unit_ready (usbdev_t *dev)
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,
466 sizeof (cb), 0, 0, 0);
469 static int
470 spin_up (usbdev_t *dev)
472 cmdblock6_t cb;
473 memset (&cb, 0, sizeof (cb));
474 cb.command = 0x1b;
475 cb.start = 1;
476 return execute_command (dev, cbw_direction_data_out, (u8 *) &cb,
477 sizeof (cb), 0, 0, 0);
480 static int
481 read_capacity (usbdev_t *dev)
483 cmdblock_t cb;
484 memset (&cb, 0, sizeof (cb));
485 cb.command = 0x25; // read capacity
486 u32 buf[2];
488 usb_debug ("Reading capacity of mass storage device.\n");
489 int count = 0, ret;
490 while (count++ < 20) {
491 switch (ret = execute_command
492 (dev, cbw_direction_data_in, (u8 *) &cb,
493 sizeof (cb), (u8 *)buf, 8, 0)) {
494 case MSC_COMMAND_OK:
495 break;
496 case MSC_COMMAND_FAIL:
497 continue;
498 default: /* if it's worse return */
499 return ret;
501 break;
503 if (count >= 20) {
504 // still not successful, assume 2tb in 512byte sectors, which is just the same garbage as any other number, but probably more usable.
505 usb_debug (" assuming 2 TB with 512-byte sectors as READ CAPACITY didn't answer.\n");
506 MSC_INST (dev)->numblocks = 0xffffffff;
507 MSC_INST (dev)->blocksize = 512;
508 } else {
509 MSC_INST (dev)->numblocks = ntohl(buf[0]) + 1;
510 MSC_INST (dev)->blocksize = ntohl(buf[1]);
512 usb_debug (" %d %d-byte sectors (%d MB)\n", MSC_INST (dev)->numblocks,
513 MSC_INST (dev)->blocksize,
514 /* 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 :
517 MSC_INST (dev)->numblocks * MSC_INST (dev)->blocksize / 1000 / 1000);
518 return MSC_COMMAND_OK;
521 static int
522 usb_msc_test_unit_ready (usbdev_t *dev)
524 int i;
525 time_t start_time_secs;
526 struct timeval tv;
527 /* 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;
532 usb_debug (" Waiting for device to become ready...");
534 /* Initially mark the device ready. */
535 MSC_INST (dev)->ready = USB_MSC_READY;
536 gettimeofday (&tv, NULL);
537 start_time_secs = tv.tv_sec;
539 while (tv.tv_sec - start_time_secs < timeout_secs) {
540 switch (test_unit_ready (dev)) {
541 case MSC_COMMAND_OK:
542 break;
543 case MSC_COMMAND_FAIL:
544 mdelay (100);
545 usb_debug (".");
546 gettimeofday (&tv, NULL);
547 continue;
548 default:
549 /* Device detached, return immediately */
550 return USB_MSC_DETACHED;
552 break;
554 if (!(tv.tv_sec - start_time_secs < timeout_secs)) {
555 usb_debug ("timeout. Device not ready.\n");
556 MSC_INST (dev)->ready = USB_MSC_NOT_READY;
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. */
562 if (!MSC_INST (dev)->ready)
563 return MSC_INST (dev)->ready;
565 usb_debug ("ok.\n");
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:
578 /* Device detached, return immediately */
579 return USB_MSC_DETACHED;
581 break;
583 usb_debug ("\n");
585 if (read_capacity (dev) == MSC_COMMAND_DETACHED)
586 return USB_MSC_DETACHED;
588 return MSC_INST (dev)->ready;
591 void
592 usb_msc_init (usbdev_t *dev)
594 int i;
596 /* init .data before setting .destroy */
597 dev->data = NULL;
599 dev->destroy = usb_msc_destroy;
600 dev->poll = usb_msc_poll;
602 configuration_descriptor_t *cd =
603 (configuration_descriptor_t *) dev->configuration;
604 interface_descriptor_t *interface =
605 (interface_descriptor_t *) (((char *) cd) + cd->bLength);
607 usb_debug (" it uses %s command set\n",
608 msc_subclass_strings[interface->bInterfaceSubClass]);
609 usb_debug (" it uses %s protocol\n",
610 msc_protocol_strings[interface->bInterfaceProtocol]);
613 if (interface->bInterfaceProtocol != 0x50) {
614 usb_debug (" Protocol not supported.\n");
615 usb_detach_device (dev->controller, dev->address);
616 return;
619 if ((interface->bInterfaceSubClass != 2) && // ATAPI 8020
620 (interface->bInterfaceSubClass != 5) && // ATAPI 8070
621 (interface->bInterfaceSubClass != 6)) { // SCSI
622 /* Other protocols, such as ATAPI don't seem to be very popular. looks like ATAPI would be really easy to add, if necessary. */
623 usb_debug (" Interface SubClass not supported.\n");
624 usb_detach_device (dev->controller, dev->address);
625 return;
628 dev->data = malloc (sizeof (usbmsc_inst_t));
629 if (!dev->data)
630 fatal("Not enough memory for USB MSC device.\n");
632 MSC_INST (dev)->bulk_in = 0;
633 MSC_INST (dev)->bulk_out = 0;
634 MSC_INST (dev)->usbdisk_created = 0;
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];
649 if (MSC_INST (dev)->bulk_in == 0) {
650 usb_debug("couldn't find bulk-in endpoint.\n");
651 usb_detach_device (dev->controller, dev->address);
652 return;
654 if (MSC_INST (dev)->bulk_out == 0) {
655 usb_debug("couldn't find bulk-out endpoint.\n");
656 usb_detach_device (dev->controller, dev->address);
657 return;
659 usb_debug (" using endpoint %x as in, %x as out\n",
660 MSC_INST (dev)->bulk_in->endpoint,
661 MSC_INST (dev)->bulk_out->endpoint);
663 /* Some sticks need a little more time to get ready after SET_CONFIG. */
664 udelay(50);
666 initialize_luns (dev);
667 usb_debug (" has %d luns\n", MSC_INST (dev)->num_luns);
669 /* Test if unit is ready (nothing to do if it isn't). */
670 if (usb_msc_test_unit_ready (dev) != USB_MSC_READY)
671 return;
673 /* Create the disk. */
674 usb_msc_create_disk (dev);
677 static void
678 usb_msc_poll (usbdev_t *dev)
680 usbmsc_inst_t *msc = MSC_INST (dev);
681 int prev_ready = msc->ready;
683 if (usb_msc_test_unit_ready (dev) == USB_MSC_DETACHED)
684 return;
686 if (!prev_ready && msc->ready) {
687 usb_debug ("usb msc: not ready -> ready (lun %d)\n", msc->lun);
688 usb_msc_create_disk (dev);
689 } else if (prev_ready && !msc->ready) {
690 usb_debug ("usb msc: ready -> not ready (lun %d)\n", msc->lun);
691 usb_msc_remove_disk (dev);
692 } 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;