FreeBSD kernel usb device Code
ustorage_fs.c
Go to the documentation of this file.
1/* $FreeBSD$ */
2/*-
3 * SPDX-License-Identifier: BSD-3-Clause
4 *
5 * Copyright (C) 2003-2005 Alan Stern
6 * Copyright (C) 2008 Hans Petter Selasky
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer,
14 * without modification.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The names of the above-listed copyright holders may not be used
19 * to endorse or promote products derived from this software without
20 * specific prior written permission.
21 *
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36/*
37 * NOTE: Much of the SCSI statemachine handling code derives from the
38 * Linux USB gadget stack.
39 */
40
41#ifdef USB_GLOBAL_INCLUDE_FILE
42#include USB_GLOBAL_INCLUDE_FILE
43#else
44#include <sys/stdint.h>
45#include <sys/stddef.h>
46#include <sys/param.h>
47#include <sys/queue.h>
48#include <sys/types.h>
49#include <sys/systm.h>
50#include <sys/kernel.h>
51#include <sys/bus.h>
52#include <sys/module.h>
53#include <sys/lock.h>
54#include <sys/mutex.h>
55#include <sys/condvar.h>
56#include <sys/sysctl.h>
57#include <sys/sx.h>
58#include <sys/unistd.h>
59#include <sys/callout.h>
60#include <sys/malloc.h>
61#include <sys/priv.h>
62
63#include <dev/usb/usb.h>
64#include <dev/usb/usbdi.h>
65#include "usbdevs.h"
66#include "usb_if.h"
67
68#define USB_DEBUG_VAR ustorage_fs_debug
69#include <dev/usb/usb_debug.h>
70#endif /* USB_GLOBAL_INCLUDE_FILE */
71
72#ifdef USB_DEBUG
73static int ustorage_fs_debug = 0;
74
75SYSCTL_NODE(_hw_usb, OID_AUTO, ustorage_fs, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
76 "USB ustorage_fs");
77SYSCTL_INT(_hw_usb_ustorage_fs, OID_AUTO, debug, CTLFLAG_RWTUN,
78 &ustorage_fs_debug, 0, "ustorage_fs debug level");
79#endif
80
81/* Define some limits */
82
83#ifndef USTORAGE_FS_BULK_SIZE
84#define USTORAGE_FS_BULK_SIZE (1U << 17) /* bytes */
85#endif
86
87#ifndef USTORAGE_FS_MAX_LUN
88#define USTORAGE_FS_MAX_LUN 8 /* units */
89#endif
90
91#ifndef USTORAGE_QDATA_MAX
92#define USTORAGE_QDATA_MAX 40 /* bytes */
93#endif
94
95/*
96 * The SCSI ID string must be exactly 28 characters long
97 * exluding the terminating zero.
98 */
99#ifndef USTORAGE_FS_ID_STRING
100#define USTORAGE_FS_ID_STRING \
101 "FreeBSD " /* 8 */ \
102 "File-Stor Gadget" /* 16 */ \
103 "0101" /* 4 */
104#endif
105
106/*
107 * The following macro defines the number of
108 * sectors to be allocated for the RAM disk:
109 */
110#ifndef USTORAGE_FS_RAM_SECT
111#define USTORAGE_FS_RAM_SECT (1UL << 13)
112#endif
113
114static uint8_t *ustorage_fs_ramdisk;
115
116/* USB transfer definitions */
117
118#define USTORAGE_FS_T_BBB_COMMAND 0
119#define USTORAGE_FS_T_BBB_DATA_DUMP 1
120#define USTORAGE_FS_T_BBB_DATA_READ 2
121#define USTORAGE_FS_T_BBB_DATA_WRITE 3
122#define USTORAGE_FS_T_BBB_STATUS 4
123#define USTORAGE_FS_T_BBB_MAX 5
124
125/* USB data stage direction */
126
127#define DIR_NONE 0
128#define DIR_READ 1
129#define DIR_WRITE 2
130
131/* USB interface specific control request */
132
133#define UR_BBB_RESET 0xff /* Bulk-Only reset */
134#define UR_BBB_GET_MAX_LUN 0xfe /* Get maximum lun */
135
136/* Command Block Wrapper */
137typedef struct {
138 uDWord dCBWSignature;
139#define CBWSIGNATURE 0x43425355
140 uDWord dCBWTag;
141 uDWord dCBWDataTransferLength;
142 uByte bCBWFlags;
143#define CBWFLAGS_OUT 0x00
144#define CBWFLAGS_IN 0x80
145 uByte bCBWLUN;
146 uByte bCDBLength;
147#define CBWCDBLENGTH 16
148 uByte CBWCDB[CBWCDBLENGTH];
149} __packed ustorage_fs_bbb_cbw_t;
150
151#define USTORAGE_FS_BBB_CBW_SIZE 31
152
153/* Command Status Wrapper */
154typedef struct {
155 uDWord dCSWSignature;
156#define CSWSIGNATURE 0x53425355
157 uDWord dCSWTag;
158 uDWord dCSWDataResidue;
159 uByte bCSWStatus;
160#define CSWSTATUS_GOOD 0x0
161#define CSWSTATUS_FAILED 0x1
162#define CSWSTATUS_PHASE 0x2
163} __packed ustorage_fs_bbb_csw_t;
164
165#define USTORAGE_FS_BBB_CSW_SIZE 13
166
168 uint8_t *memory_image;
169
170 uint32_t num_sectors;
171 uint32_t sense_data;
174
175 uint8_t read_only:1;
177 uint8_t info_valid:1;
178 uint8_t removable:1;
179};
180
182 ustorage_fs_bbb_cbw_t *sc_cbw; /* Command Wrapper Block */
183 ustorage_fs_bbb_csw_t *sc_csw; /* Command Status Block */
184 void *sc_dma_ptr; /* Main data buffer */
185
186 struct mtx sc_mtx;
187
189
190 struct {
191 uint8_t *data_ptr;
193
194 uint32_t data_rem; /* bytes, as reported by the command
195 * block wrapper */
196 uint32_t offset; /* bytes */
197
198 uint8_t cbw_dir;
199 uint8_t cmd_dir;
200 uint8_t lun;
201 uint8_t cmd_len;
202 uint8_t data_short:1;
203 uint8_t data_error:1;
205
206 device_t sc_dev;
209
210 uint8_t sc_iface_no; /* interface number */
211 uint8_t sc_last_lun;
214};
215
216/* prototypes */
217
218static device_probe_t ustorage_fs_probe;
219static device_attach_t ustorage_fs_attach;
220static device_detach_t ustorage_fs_detach;
221static device_suspend_t ustorage_fs_suspend;
222static device_resume_t ustorage_fs_resume;
223static usb_handle_request_t ustorage_fs_handle_request;
224
230
231static void ustorage_fs_transfer_start(struct ustorage_fs_softc *sc, uint8_t xfer_index);
232static void ustorage_fs_transfer_stop(struct ustorage_fs_softc *sc);
233
234static uint8_t ustorage_fs_verify(struct ustorage_fs_softc *sc);
235static uint8_t ustorage_fs_inquiry(struct ustorage_fs_softc *sc);
236static uint8_t ustorage_fs_request_sense(struct ustorage_fs_softc *sc);
237static uint8_t ustorage_fs_read_capacity(struct ustorage_fs_softc *sc);
238static uint8_t ustorage_fs_mode_sense(struct ustorage_fs_softc *sc);
239static uint8_t ustorage_fs_start_stop(struct ustorage_fs_softc *sc);
240static uint8_t ustorage_fs_prevent_allow(struct ustorage_fs_softc *sc);
242static uint8_t ustorage_fs_mode_select(struct ustorage_fs_softc *sc);
243static uint8_t ustorage_fs_min_len(struct ustorage_fs_softc *sc, uint32_t len, uint32_t mask);
244static uint8_t ustorage_fs_read(struct ustorage_fs_softc *sc);
245static uint8_t ustorage_fs_write(struct ustorage_fs_softc *sc);
246static uint8_t ustorage_fs_check_cmd(struct ustorage_fs_softc *sc, uint8_t cmd_size, uint16_t mask, uint8_t needs_medium);
247static uint8_t ustorage_fs_do_cmd(struct ustorage_fs_softc *sc);
248
249static device_method_t ustorage_fs_methods[] = {
250 /* USB interface */
252
253 /* Device interface */
254 DEVMETHOD(device_probe, ustorage_fs_probe),
255 DEVMETHOD(device_attach, ustorage_fs_attach),
256 DEVMETHOD(device_detach, ustorage_fs_detach),
257 DEVMETHOD(device_suspend, ustorage_fs_suspend),
258 DEVMETHOD(device_resume, ustorage_fs_resume),
259
260 DEVMETHOD_END
261};
262
263static driver_t ustorage_fs_driver = {
264 .name = "ustorage_fs",
265 .methods = ustorage_fs_methods,
266 .size = sizeof(struct ustorage_fs_softc),
267};
268
269static devclass_t ustorage_fs_devclass;
270
272MODULE_VERSION(ustorage_fs, 0);
273MODULE_DEPEND(ustorage_fs, usb, 1, 1, 1);
274
277 .type = UE_BULK,
278 .endpoint = UE_ADDR_ANY,
279 .direction = UE_DIR_OUT,
280 .bufsize = sizeof(ustorage_fs_bbb_cbw_t),
283 },
284
286 .type = UE_BULK,
287 .endpoint = UE_ADDR_ANY,
288 .direction = UE_DIR_OUT,
289 .bufsize = 0, /* use wMaxPacketSize */
290 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
292 .usb_mode = USB_MODE_DEVICE,
293 },
294
296 .type = UE_BULK,
297 .endpoint = UE_ADDR_ANY,
298 .direction = UE_DIR_OUT,
299 .bufsize = USTORAGE_FS_BULK_SIZE,
300 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1},
302 .usb_mode = USB_MODE_DEVICE,
303 },
304
306 .type = UE_BULK,
307 .endpoint = UE_ADDR_ANY,
308 .direction = UE_DIR_IN,
309 .bufsize = USTORAGE_FS_BULK_SIZE,
310 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer = 1},
312 .usb_mode = USB_MODE_DEVICE,
313 },
314
316 .type = UE_BULK,
317 .endpoint = UE_ADDR_ANY,
318 .direction = UE_DIR_IN,
319 .bufsize = sizeof(ustorage_fs_bbb_csw_t),
320 .flags = {.short_xfer_ok = 1},
322 .usb_mode = USB_MODE_DEVICE,
323 },
324};
325
326/*
327 * USB device probe/attach/detach
328 */
329
330static int
331ustorage_fs_probe(device_t dev)
332{
333 struct usb_attach_arg *uaa = device_get_ivars(dev);
335
336 if (uaa->usb_mode != USB_MODE_DEVICE) {
337 return (ENXIO);
338 }
339 /* Check for a standards compliant device */
341 if ((id == NULL) ||
342 (id->bInterfaceClass != UICLASS_MASS) ||
343 (id->bInterfaceSubClass != UISUBCLASS_SCSI) ||
344 (id->bInterfaceProtocol != UIPROTO_MASS_BBB)) {
345 return (ENXIO);
346 }
347 return (BUS_PROBE_GENERIC);
348}
349
350static int
352{
353 struct ustorage_fs_softc *sc = device_get_softc(dev);
354 struct usb_attach_arg *uaa = device_get_ivars(dev);
356 int err;
357 int unit;
358
359 /*
360 * NOTE: the softc struct is cleared in device_set_driver.
361 * We can safely call ustorage_fs_detach without specifically
362 * initializing the struct.
363 */
364
365 sc->sc_dev = dev;
366 sc->sc_udev = uaa->device;
367 unit = device_get_unit(dev);
368
369 /* enable power saving mode */
371
372 if (unit == 0) {
373 if (ustorage_fs_ramdisk == NULL) {
374 /*
375 * allocate a memory image for our ramdisk until
376 * further
377 */
379 malloc(USTORAGE_FS_RAM_SECT << 9, M_USB,
380 M_ZERO | M_WAITOK);
381 }
384 sc->sc_lun[0].removable = 1;
385 }
386
388
389 mtx_init(&sc->sc_mtx, "USTORAGE_FS lock",
390 NULL, (MTX_DEF | MTX_RECURSE));
391
392 /* get interface index */
393
395 if (id == NULL) {
396 device_printf(dev, "failed to get "
397 "interface number\n");
398 goto detach;
399 }
400 sc->sc_iface_no = id->bInterfaceNumber;
401
402 err = usbd_transfer_setup(uaa->device,
404 USTORAGE_FS_T_BBB_MAX, sc, &sc->sc_mtx);
405 if (err) {
406 device_printf(dev, "could not setup required "
407 "transfers, %s\n", usbd_errstr(err));
408 goto detach;
409 }
410
417
418 /* start Mass Storage State Machine */
419
420 mtx_lock(&sc->sc_mtx);
422 mtx_unlock(&sc->sc_mtx);
423
424 return (0); /* success */
425
426detach:
428 return (ENXIO); /* failure */
429}
430
431static int
433{
434 struct ustorage_fs_softc *sc = device_get_softc(dev);
435
436 /* teardown our statemachine */
437
439
440 mtx_destroy(&sc->sc_mtx);
441
442 return (0); /* success */
443}
444
445static int
447{
448 device_printf(dev, "suspending\n");
449 return (0); /* success */
450}
451
452static int
454{
455 device_printf(dev, "resuming\n");
456 return (0); /* success */
457}
458
459/*
460 * Generic functions to handle transfers
461 */
462
463static void
464ustorage_fs_transfer_start(struct ustorage_fs_softc *sc, uint8_t xfer_index)
465{
466 if (sc->sc_xfer[xfer_index]) {
467 sc->sc_last_xfer_index = xfer_index;
468 usbd_transfer_start(sc->sc_xfer[xfer_index]);
469 }
470}
471
472static void
474{
476 mtx_unlock(&sc->sc_mtx);
478 mtx_lock(&sc->sc_mtx);
479}
480
481static int
483 const void *preq, void **pptr, uint16_t *plen,
484 uint16_t offset, uint8_t *pstate)
485{
486 struct ustorage_fs_softc *sc = device_get_softc(dev);
487 const struct usb_device_request *req = preq;
488 uint8_t is_complete = *pstate;
489
490 if (!is_complete) {
491 if ((req->bmRequestType == UT_WRITE_CLASS_INTERFACE) &&
492 (req->bRequest == UR_BBB_RESET)) {
493 *plen = 0;
494 mtx_lock(&sc->sc_mtx);
496 sc->sc_transfer.data_error = 1;
499 mtx_unlock(&sc->sc_mtx);
500 return (0);
501 } else if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) &&
502 (req->bRequest == UR_BBB_GET_MAX_LUN)) {
503 if (offset == 0) {
504 *plen = 1;
505 *pptr = &sc->sc_last_lun;
506 } else {
507 *plen = 0;
508 }
509 return (0);
510 }
511 }
512 return (ENXIO); /* use builtin handler */
513}
514
515static void
517{
518 struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer);
519 uint32_t tag;
520 uint8_t err = 0;
521
522 DPRINTF("\n");
523
524 switch (USB_GET_STATE(xfer)) {
526
527 tag = UGETDW(sc->sc_cbw->dCBWSignature);
528
529 if (tag != CBWSIGNATURE) {
530 /* do nothing */
531 DPRINTF("invalid signature 0x%08x\n", tag);
532 break;
533 }
534 tag = UGETDW(sc->sc_cbw->dCBWTag);
535
536 /* echo back tag */
537 USETDW(sc->sc_csw->dCSWTag, tag);
538
539 /* reset status */
540 sc->sc_csw->bCSWStatus = 0;
541
542 /* reset data offset, data length and data remainder */
543 sc->sc_transfer.offset = 0;
545 UGETDW(sc->sc_cbw->dCBWDataTransferLength);
546
547 /* reset data flags */
548 sc->sc_transfer.data_short = 0;
549
550 /* extract LUN */
551 sc->sc_transfer.lun = sc->sc_cbw->bCBWLUN;
552
553 if (sc->sc_transfer.data_rem == 0) {
555 } else {
556 if (sc->sc_cbw->bCBWFlags & CBWFLAGS_IN) {
558 } else {
560 }
561 }
562
563 sc->sc_transfer.cmd_len = sc->sc_cbw->bCDBLength;
564 if ((sc->sc_transfer.cmd_len > sizeof(sc->sc_cbw->CBWCDB)) ||
565 (sc->sc_transfer.cmd_len == 0)) {
566 /* just halt - this is invalid */
567 DPRINTF("invalid command length %d bytes\n",
568 sc->sc_transfer.cmd_len);
569 break;
570 }
571
572 err = ustorage_fs_do_cmd(sc);
573 if (err) {
574 /* got an error */
575 DPRINTF("command failed\n");
576 break;
577 }
578 if ((sc->sc_transfer.data_rem > 0) &&
579 (sc->sc_transfer.cbw_dir != sc->sc_transfer.cmd_dir)) {
580 /* contradicting data transfer direction */
581 err = 1;
582 DPRINTF("data direction mismatch\n");
583 break;
584 }
585 switch (sc->sc_transfer.cbw_dir) {
586 case DIR_READ:
588 break;
589 case DIR_WRITE:
591 break;
592 default:
595 break;
596 }
597 break;
598
599 case USB_ST_SETUP:
600tr_setup:
601 if (sc->sc_transfer.data_error) {
602 sc->sc_transfer.data_error = 0;
604 DPRINTF("stall pipe\n");
605 }
607 sizeof(ustorage_fs_bbb_cbw_t));
609 break;
610
611 default: /* Error */
612 DPRINTF("error\n");
613 if (error == USB_ERR_CANCELLED) {
614 break;
615 }
616 /* If the pipe is already stalled, don't do another stall */
617 if (!usbd_xfer_is_stalled(xfer))
618 sc->sc_transfer.data_error = 1;
619
620 /* try again */
621 goto tr_setup;
622 }
623 if (err) {
624 if (sc->sc_csw->bCSWStatus == 0) {
625 /* set some default error code */
626 sc->sc_csw->bCSWStatus = CSWSTATUS_FAILED;
627 }
628 if (sc->sc_transfer.cbw_dir == DIR_READ) {
629 /* dump all data */
632 return;
633 }
634 if (sc->sc_transfer.cbw_dir == DIR_WRITE) {
635 /* need to stall before status */
636 sc->sc_transfer.data_error = 1;
637 }
639 }
640}
641
642static void
644{
645 struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer);
646 uint32_t max_bulk = usbd_xfer_max_len(xfer);
647 int actlen, sumlen;
648
649 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
650
651 DPRINTF("\n");
652
653 switch (USB_GET_STATE(xfer)) {
655 sc->sc_transfer.data_rem -= actlen;
656 sc->sc_transfer.offset += actlen;
657
658 if (actlen != sumlen || sc->sc_transfer.data_rem == 0) {
659 /* short transfer or end of data */
662 break;
663 }
664 /* Fallthrough */
665
666 case USB_ST_SETUP:
667tr_setup:
668 if (max_bulk > sc->sc_transfer.data_rem) {
669 max_bulk = sc->sc_transfer.data_rem;
670 }
671 if (sc->sc_transfer.data_error) {
672 sc->sc_transfer.data_error = 0;
674 }
675 usbd_xfer_set_frame_len(xfer, 0, max_bulk);
677 break;
678
679 default: /* Error */
680 if (error == USB_ERR_CANCELLED) {
681 break;
682 }
683 /*
684 * If the pipe is already stalled, don't do another stall:
685 */
686 if (!usbd_xfer_is_stalled(xfer))
687 sc->sc_transfer.data_error = 1;
688
689 /* try again */
690 goto tr_setup;
691 }
692}
693
694static void
696{
697 struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer);
698 uint32_t max_bulk = usbd_xfer_max_len(xfer);
699 int actlen, sumlen;
700
701 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
702
703 DPRINTF("\n");
704
705 switch (USB_GET_STATE(xfer)) {
707 /* XXX copy data from DMA buffer */
708 memcpy(sc->sc_transfer.data_ptr, sc->sc_dma_ptr, actlen);
709
710 sc->sc_transfer.data_rem -= actlen;
711 sc->sc_transfer.data_ptr += actlen;
712 sc->sc_transfer.offset += actlen;
713
714 if (actlen != sumlen || sc->sc_transfer.data_rem == 0) {
715 /* short transfer or end of data */
718 break;
719 }
720 /* Fallthrough */
721
722 case USB_ST_SETUP:
723tr_setup:
724 if (max_bulk > sc->sc_transfer.data_rem) {
725 max_bulk = sc->sc_transfer.data_rem;
726 }
727 if (sc->sc_transfer.data_error) {
728 sc->sc_transfer.data_error = 0;
730 }
731
732 usbd_xfer_set_frame_data(xfer, 0, sc->sc_dma_ptr, max_bulk);
734 break;
735
736 default: /* Error */
737 if (error == USB_ERR_CANCELLED) {
738 break;
739 }
740 /* If the pipe is already stalled, don't do another stall */
741 if (!usbd_xfer_is_stalled(xfer))
742 sc->sc_transfer.data_error = 1;
743
744 /* try again */
745 goto tr_setup;
746 }
747}
748
749static void
751{
752 struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer);
753 uint32_t max_bulk = usbd_xfer_max_len(xfer);
754 int actlen, sumlen;
755
756 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
757
758 DPRINTF("\n");
759
760 switch (USB_GET_STATE(xfer)) {
762 sc->sc_transfer.data_rem -= actlen;
763 sc->sc_transfer.data_ptr += actlen;
764 sc->sc_transfer.offset += actlen;
765
766 if (actlen != sumlen || sc->sc_transfer.data_rem == 0) {
767 /* short transfer or end of data */
770 break;
771 }
772 case USB_ST_SETUP:
773tr_setup:
774 if (max_bulk >= sc->sc_transfer.data_rem) {
775 max_bulk = sc->sc_transfer.data_rem;
776 if (sc->sc_transfer.data_short)
778 else
780 } else
782
783 if (sc->sc_transfer.data_error) {
784 sc->sc_transfer.data_error = 0;
786 }
787
788 /* XXX copy data to DMA buffer */
789 memcpy(sc->sc_dma_ptr, sc->sc_transfer.data_ptr, max_bulk);
790
791 usbd_xfer_set_frame_data(xfer, 0, sc->sc_dma_ptr, max_bulk);
793 break;
794
795 default: /* Error */
796 if (error == USB_ERR_CANCELLED) {
797 break;
798 }
799 /*
800 * If the pipe is already stalled, don't do another
801 * stall
802 */
803 if (!usbd_xfer_is_stalled(xfer))
804 sc->sc_transfer.data_error = 1;
805
806 /* try again */
807 goto tr_setup;
808 }
809}
810
811static void
813{
814 struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer);
815
816 DPRINTF("\n");
817
818 switch (USB_GET_STATE(xfer)) {
821 break;
822
823 case USB_ST_SETUP:
824tr_setup:
825 USETDW(sc->sc_csw->dCSWSignature, CSWSIGNATURE);
826 USETDW(sc->sc_csw->dCSWDataResidue, sc->sc_transfer.data_rem);
827
828 if (sc->sc_transfer.data_error) {
829 sc->sc_transfer.data_error = 0;
831 }
833 sizeof(ustorage_fs_bbb_csw_t));
835 break;
836
837 default:
838 if (error == USB_ERR_CANCELLED) {
839 break;
840 }
841 /* If the pipe is already stalled, don't do another stall */
842 if (!usbd_xfer_is_stalled(xfer))
843 sc->sc_transfer.data_error = 1;
844
845 /* try again */
846 goto tr_setup;
847 }
848}
849
850/* SCSI commands that we recognize */
851#define SC_FORMAT_UNIT 0x04
852#define SC_INQUIRY 0x12
853#define SC_MODE_SELECT_6 0x15
854#define SC_MODE_SELECT_10 0x55
855#define SC_MODE_SENSE_6 0x1a
856#define SC_MODE_SENSE_10 0x5a
857#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
858#define SC_READ_6 0x08
859#define SC_READ_10 0x28
860#define SC_READ_12 0xa8
861#define SC_READ_CAPACITY 0x25
862#define SC_READ_FORMAT_CAPACITIES 0x23
863#define SC_RELEASE 0x17
864#define SC_REQUEST_SENSE 0x03
865#define SC_RESERVE 0x16
866#define SC_SEND_DIAGNOSTIC 0x1d
867#define SC_START_STOP_UNIT 0x1b
868#define SC_SYNCHRONIZE_CACHE 0x35
869#define SC_TEST_UNIT_READY 0x00
870#define SC_VERIFY 0x2f
871#define SC_WRITE_6 0x0a
872#define SC_WRITE_10 0x2a
873#define SC_WRITE_12 0xaa
874
875/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
876#define SS_NO_SENSE 0
877#define SS_COMMUNICATION_FAILURE 0x040800
878#define SS_INVALID_COMMAND 0x052000
879#define SS_INVALID_FIELD_IN_CDB 0x052400
880#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
881#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500
882#define SS_MEDIUM_NOT_PRESENT 0x023a00
883#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302
884#define SS_NOT_READY_TO_READY_TRANSITION 0x062800
885#define SS_RESET_OCCURRED 0x062900
886#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900
887#define SS_UNRECOVERED_READ_ERROR 0x031100
888#define SS_WRITE_ERROR 0x030c02
889#define SS_WRITE_PROTECTED 0x072700
890
891#define SK(x) ((uint8_t) ((x) >> 16)) /* Sense Key byte, etc. */
892#define ASC(x) ((uint8_t) ((x) >> 8))
893#define ASCQ(x) ((uint8_t) (x))
894
895/* Routines for unaligned data access */
896
897static uint16_t
898get_be16(uint8_t *buf)
899{
900 return ((uint16_t)buf[0] << 8) | ((uint16_t)buf[1]);
901}
902
903static uint32_t
904get_be32(uint8_t *buf)
905{
906 return ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
907 ((uint32_t)buf[2] << 8) | ((uint32_t)buf[3]);
908}
909
910static void
911put_be16(uint8_t *buf, uint16_t val)
912{
913 buf[0] = val >> 8;
914 buf[1] = val;
915}
916
917static void
918put_be32(uint8_t *buf, uint32_t val)
919{
920 buf[0] = val >> 24;
921 buf[1] = val >> 16;
922 buf[2] = val >> 8;
923 buf[3] = val & 0xff;
924}
925
926/*------------------------------------------------------------------------*
927 * ustorage_fs_verify
928 *
929 * Returns:
930 * 0: Success
931 * Else: Failure
932 *------------------------------------------------------------------------*/
933static uint8_t
935{
936 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
937 uint32_t lba;
938 uint32_t vlen;
939 uint64_t file_offset;
940 uint64_t amount_left;
941
942 /*
943 * Get the starting Logical Block Address
944 */
945 lba = get_be32(&sc->sc_cbw->CBWCDB[2]);
946
947 /*
948 * We allow DPO (Disable Page Out = don't save data in the cache)
949 * but we don't implement it.
950 */
951 if ((sc->sc_cbw->CBWCDB[1] & ~0x10) != 0) {
953 return (1);
954 }
955 vlen = get_be16(&sc->sc_cbw->CBWCDB[7]);
956 if (vlen == 0) {
957 goto done;
958 }
959 /* No default reply */
960
961 /* Prepare to carry out the file verify */
962 amount_left = vlen;
963 amount_left <<= 9;
964 file_offset = lba;
965 file_offset <<= 9;
966
967 /* Range check */
968 vlen += lba;
969
970 if ((vlen < lba) ||
971 (vlen > currlun->num_sectors) ||
972 (lba >= currlun->num_sectors)) {
974 return (1);
975 }
976 /* XXX TODO: verify that data is readable */
977done:
978 return (ustorage_fs_min_len(sc, 0, -1U));
979}
980
981/*------------------------------------------------------------------------*
982 * ustorage_fs_inquiry
983 *
984 * Returns:
985 * 0: Success
986 * Else: Failure
987 *------------------------------------------------------------------------*/
988static uint8_t
990{
991 uint8_t *buf = sc->sc_transfer.data_ptr;
992
993 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
994
995 if (!sc->sc_transfer.currlun) {
996 /* Unsupported LUNs are okay */
997 memset(buf, 0, 36);
998 buf[0] = 0x7f;
999 /* Unsupported, no device - type */
1000 return (ustorage_fs_min_len(sc, 36, -1U));
1001 }
1002 memset(buf, 0, 8);
1003 /* Non - removable, direct - access device */
1004 if (currlun->removable)
1005 buf[1] = 0x80;
1006 buf[2] = 2;
1007 /* ANSI SCSI level 2 */
1008 buf[3] = 2;
1009 /* SCSI - 2 INQUIRY data format */
1010 buf[4] = 31;
1011 /* Additional length */
1012 /* No special options */
1013 /* Copy in ID string */
1014 memcpy(buf + 8, USTORAGE_FS_ID_STRING, 28);
1015
1016#if (USTORAGE_QDATA_MAX < 36)
1017#error "(USTORAGE_QDATA_MAX < 36)"
1018#endif
1019 return (ustorage_fs_min_len(sc, 36, -1U));
1020}
1021
1022/*------------------------------------------------------------------------*
1023 * ustorage_fs_request_sense
1024 *
1025 * Returns:
1026 * 0: Success
1027 * Else: Failure
1028 *------------------------------------------------------------------------*/
1029static uint8_t
1031{
1032 uint8_t *buf = sc->sc_transfer.data_ptr;
1033 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
1034 uint32_t sd;
1035 uint32_t sdinfo;
1036 uint8_t valid;
1037
1038 /*
1039 * From the SCSI-2 spec., section 7.9 (Unit attention condition):
1040 *
1041 * If a REQUEST SENSE command is received from an initiator
1042 * with a pending unit attention condition (before the target
1043 * generates the contingent allegiance condition), then the
1044 * target shall either:
1045 * a) report any pending sense data and preserve the unit
1046 * attention condition on the logical unit, or,
1047 * b) report the unit attention condition, may discard any
1048 * pending sense data, and clear the unit attention
1049 * condition on the logical unit for that initiator.
1050 *
1051 * FSG normally uses option a); enable this code to use option b).
1052 */
1053#if 0
1054 if (currlun && currlun->unit_attention_data != SS_NO_SENSE) {
1055 currlun->sense_data = currlun->unit_attention_data;
1057 }
1058#endif
1059
1060 if (!currlun) {
1061 /* Unsupported LUNs are okay */
1063 sdinfo = 0;
1064 valid = 0;
1065 } else {
1066 sd = currlun->sense_data;
1067 sdinfo = currlun->sense_data_info;
1068 valid = currlun->info_valid << 7;
1069 currlun->sense_data = SS_NO_SENSE;
1070 currlun->sense_data_info = 0;
1071 currlun->info_valid = 0;
1072 }
1073
1074 memset(buf, 0, 18);
1075 buf[0] = valid | 0x70;
1076 /* Valid, current error */
1077 buf[2] = SK(sd);
1078 put_be32(&buf[3], sdinfo);
1079 /* Sense information */
1080 buf[7] = 18 - 8;
1081 /* Additional sense length */
1082 buf[12] = ASC(sd);
1083 buf[13] = ASCQ(sd);
1084
1085#if (USTORAGE_QDATA_MAX < 18)
1086#error "(USTORAGE_QDATA_MAX < 18)"
1087#endif
1088 return (ustorage_fs_min_len(sc, 18, -1U));
1089}
1090
1091/*------------------------------------------------------------------------*
1092 * ustorage_fs_read_capacity
1093 *
1094 * Returns:
1095 * 0: Success
1096 * Else: Failure
1097 *------------------------------------------------------------------------*/
1098static uint8_t
1100{
1101 uint8_t *buf = sc->sc_transfer.data_ptr;
1102 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
1103 uint32_t lba = get_be32(&sc->sc_cbw->CBWCDB[2]);
1104 uint8_t pmi = sc->sc_cbw->CBWCDB[8];
1105
1106 /* Check the PMI and LBA fields */
1107 if ((pmi > 1) || ((pmi == 0) && (lba != 0))) {
1109 return (1);
1110 }
1111 /* Max logical block */
1112 put_be32(&buf[0], currlun->num_sectors - 1);
1113 /* Block length */
1114 put_be32(&buf[4], 512);
1115
1116#if (USTORAGE_QDATA_MAX < 8)
1117#error "(USTORAGE_QDATA_MAX < 8)"
1118#endif
1119 return (ustorage_fs_min_len(sc, 8, -1U));
1120}
1121
1122/*------------------------------------------------------------------------*
1123 * ustorage_fs_mode_sense
1124 *
1125 * Returns:
1126 * 0: Success
1127 * Else: Failure
1128 *------------------------------------------------------------------------*/
1129static uint8_t
1131{
1132 uint8_t *buf = sc->sc_transfer.data_ptr;
1133 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
1134 uint8_t *buf0;
1135 uint16_t len;
1136 uint16_t limit;
1137 uint8_t mscmnd = sc->sc_cbw->CBWCDB[0];
1138 uint8_t pc;
1139 uint8_t page_code;
1140 uint8_t changeable_values;
1141 uint8_t all_pages;
1142
1143 buf0 = buf;
1144
1145 if ((sc->sc_cbw->CBWCDB[1] & ~0x08) != 0) {
1146 /* Mask away DBD */
1148 return (1);
1149 }
1150 pc = sc->sc_cbw->CBWCDB[2] >> 6;
1151 page_code = sc->sc_cbw->CBWCDB[2] & 0x3f;
1152 if (pc == 3) {
1154 return (1);
1155 }
1156 changeable_values = (pc == 1);
1157 all_pages = (page_code == 0x3f);
1158
1159 /*
1160 * Write the mode parameter header. Fixed values are: default
1161 * medium type, no cache control (DPOFUA), and no block descriptors.
1162 * The only variable value is the WriteProtect bit. We will fill in
1163 * the mode data length later.
1164 */
1165 memset(buf, 0, 8);
1166 if (mscmnd == SC_MODE_SENSE_6) {
1167 buf[2] = (currlun->read_only ? 0x80 : 0x00);
1168 /* WP, DPOFUA */
1169 buf += 4;
1170 limit = 255;
1171 } else {
1172 /* SC_MODE_SENSE_10 */
1173 buf[3] = (currlun->read_only ? 0x80 : 0x00);
1174 /* WP, DPOFUA */
1175 buf += 8;
1176 limit = 65535;
1177 /* Should really be mod_data.buflen */
1178 }
1179
1180 /* No block descriptors */
1181
1182 /*
1183 * The mode pages, in numerical order.
1184 */
1185 if ((page_code == 0x08) || all_pages) {
1186 buf[0] = 0x08;
1187 /* Page code */
1188 buf[1] = 10;
1189 /* Page length */
1190 memset(buf + 2, 0, 10);
1191 /* None of the fields are changeable */
1192
1193 if (!changeable_values) {
1194 buf[2] = 0x04;
1195 /* Write cache enable, */
1196 /* Read cache not disabled */
1197 /* No cache retention priorities */
1198 put_be16(&buf[4], 0xffff);
1199 /* Don 't disable prefetch */
1200 /* Minimum prefetch = 0 */
1201 put_be16(&buf[8], 0xffff);
1202 /* Maximum prefetch */
1203 put_be16(&buf[10], 0xffff);
1204 /* Maximum prefetch ceiling */
1205 }
1206 buf += 12;
1207 }
1208 /*
1209 * Check that a valid page was requested and the mode data length
1210 * isn't too long.
1211 */
1212 len = buf - buf0;
1213 if (len > limit) {
1215 return (1);
1216 }
1217 /* Store the mode data length */
1218 if (mscmnd == SC_MODE_SENSE_6)
1219 buf0[0] = len - 1;
1220 else
1221 put_be16(buf0, len - 2);
1222
1223#if (USTORAGE_QDATA_MAX < 24)
1224#error "(USTORAGE_QDATA_MAX < 24)"
1225#endif
1226 return (ustorage_fs_min_len(sc, len, -1U));
1227}
1228
1229/*------------------------------------------------------------------------*
1230 * ustorage_fs_start_stop
1231 *
1232 * Returns:
1233 * 0: Success
1234 * Else: Failure
1235 *------------------------------------------------------------------------*/
1236static uint8_t
1238{
1239 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
1240 uint8_t loej;
1241 uint8_t start;
1242 uint8_t immed;
1243
1244 if (!currlun->removable) {
1245 currlun->sense_data = SS_INVALID_COMMAND;
1246 return (1);
1247 }
1248 immed = sc->sc_cbw->CBWCDB[1] & 0x01;
1249 loej = sc->sc_cbw->CBWCDB[4] & 0x02;
1250 start = sc->sc_cbw->CBWCDB[4] & 0x01;
1251
1252 if (immed || loej || start) {
1253 /* compile fix */
1254 }
1255 return (0);
1256}
1257
1258/*------------------------------------------------------------------------*
1259 * ustorage_fs_prevent_allow
1260 *
1261 * Returns:
1262 * 0: Success
1263 * Else: Failure
1264 *------------------------------------------------------------------------*/
1265static uint8_t
1267{
1268 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
1269 uint8_t prevent;
1270
1271 if (!currlun->removable) {
1272 currlun->sense_data = SS_INVALID_COMMAND;
1273 return (1);
1274 }
1275 prevent = sc->sc_cbw->CBWCDB[4] & 0x01;
1276 if ((sc->sc_cbw->CBWCDB[4] & ~0x01) != 0) {
1277 /* Mask away Prevent */
1279 return (1);
1280 }
1281 if (currlun->prevent_medium_removal && !prevent) {
1282 //fsync_sub(currlun);
1283 }
1284 currlun->prevent_medium_removal = prevent;
1285 return (0);
1286}
1287
1288/*------------------------------------------------------------------------*
1289 * ustorage_fs_read_format_capacities
1290 *
1291 * Returns:
1292 * 0: Success
1293 * Else: Failure
1294 *------------------------------------------------------------------------*/
1295static uint8_t
1297{
1298 uint8_t *buf = sc->sc_transfer.data_ptr;
1299 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
1300
1301 buf[0] = buf[1] = buf[2] = 0;
1302 buf[3] = 8;
1303 /* Only the Current / Maximum Capacity Descriptor */
1304 buf += 4;
1305
1306 /* Number of blocks */
1307 put_be32(&buf[0], currlun->num_sectors);
1308 /* Block length */
1309 put_be32(&buf[4], 512);
1310 /* Current capacity */
1311 buf[4] = 0x02;
1312
1313#if (USTORAGE_QDATA_MAX < 12)
1314#error "(USTORAGE_QDATA_MAX < 12)"
1315#endif
1316 return (ustorage_fs_min_len(sc, 12, -1U));
1317}
1318
1319/*------------------------------------------------------------------------*
1320 * ustorage_fs_mode_select
1321 *
1322 * Return values:
1323 * 0: Success
1324 * Else: Failure
1325 *------------------------------------------------------------------------*/
1326static uint8_t
1328{
1329 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
1330
1331 /* We don't support MODE SELECT */
1332 currlun->sense_data = SS_INVALID_COMMAND;
1333 return (1);
1334}
1335
1336/*------------------------------------------------------------------------*
1337 * ustorage_fs_synchronize_cache
1338 *
1339 * Return values:
1340 * 0: Success
1341 * Else: Failure
1342 *------------------------------------------------------------------------*/
1343static uint8_t
1345{
1346#if 0
1347 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
1348 uint8_t rc;
1349
1350 /*
1351 * We ignore the requested LBA and write out all dirty data buffers.
1352 */
1353 rc = 0;
1354 if (rc) {
1355 currlun->sense_data = SS_WRITE_ERROR;
1356 }
1357#endif
1358 return (0);
1359}
1360
1361/*------------------------------------------------------------------------*
1362 * ustorage_fs_read - read data from disk
1363 *
1364 * Return values:
1365 * 0: Success
1366 * Else: Failure
1367 *------------------------------------------------------------------------*/
1368static uint8_t
1370{
1371 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
1372 uint64_t file_offset;
1373 uint32_t lba;
1374 uint32_t len;
1375
1376 /*
1377 * Get the starting Logical Block Address and check that it's not
1378 * too big
1379 */
1380 if (sc->sc_cbw->CBWCDB[0] == SC_READ_6) {
1381 lba = (((uint32_t)sc->sc_cbw->CBWCDB[1]) << 16) |
1382 get_be16(&sc->sc_cbw->CBWCDB[2]);
1383 } else {
1384 lba = get_be32(&sc->sc_cbw->CBWCDB[2]);
1385
1386 /*
1387 * We allow DPO (Disable Page Out = don't save data in the
1388 * cache) and FUA (Force Unit Access = don't read from the
1389 * cache), but we don't implement them.
1390 */
1391 if ((sc->sc_cbw->CBWCDB[1] & ~0x18) != 0) {
1393 return (1);
1394 }
1395 }
1396 len = sc->sc_transfer.data_rem >> 9;
1397 len += lba;
1398
1399 if ((len < lba) ||
1400 (len > currlun->num_sectors) ||
1401 (lba >= currlun->num_sectors)) {
1403 return (1);
1404 }
1405 file_offset = lba;
1406 file_offset <<= 9;
1407
1408 sc->sc_transfer.data_ptr = currlun->memory_image + file_offset;
1409
1410 return (0);
1411}
1412
1413/*------------------------------------------------------------------------*
1414 * ustorage_fs_write - write data to disk
1415 *
1416 * Return values:
1417 * 0: Success
1418 * Else: Failure
1419 *------------------------------------------------------------------------*/
1420static uint8_t
1422{
1423 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
1424 uint64_t file_offset;
1425 uint32_t lba;
1426 uint32_t len;
1427
1428 if (currlun->read_only) {
1429 currlun->sense_data = SS_WRITE_PROTECTED;
1430 return (1);
1431 }
1432 /* XXX clear SYNC */
1433
1434 /*
1435 * Get the starting Logical Block Address and check that it's not
1436 * too big.
1437 */
1438 if (sc->sc_cbw->CBWCDB[0] == SC_WRITE_6)
1439 lba = (((uint32_t)sc->sc_cbw->CBWCDB[1]) << 16) |
1440 get_be16(&sc->sc_cbw->CBWCDB[2]);
1441 else {
1442 lba = get_be32(&sc->sc_cbw->CBWCDB[2]);
1443
1444 /*
1445 * We allow DPO (Disable Page Out = don't save data in the
1446 * cache) and FUA (Force Unit Access = write directly to the
1447 * medium). We don't implement DPO; we implement FUA by
1448 * performing synchronous output.
1449 */
1450 if ((sc->sc_cbw->CBWCDB[1] & ~0x18) != 0) {
1452 return (1);
1453 }
1454 if (sc->sc_cbw->CBWCDB[1] & 0x08) {
1455 /* FUA */
1456 /* XXX set SYNC flag here */
1457 }
1458 }
1459
1460 len = sc->sc_transfer.data_rem >> 9;
1461 len += lba;
1462
1463 if ((len < lba) ||
1464 (len > currlun->num_sectors) ||
1465 (lba >= currlun->num_sectors)) {
1467 return (1);
1468 }
1469 file_offset = lba;
1470 file_offset <<= 9;
1471
1472 sc->sc_transfer.data_ptr = currlun->memory_image + file_offset;
1473
1474 return (0);
1475}
1476
1477/*------------------------------------------------------------------------*
1478 * ustorage_fs_min_len
1479 *
1480 * Return values:
1481 * 0: Success
1482 * Else: Failure
1483 *------------------------------------------------------------------------*/
1484static uint8_t
1485ustorage_fs_min_len(struct ustorage_fs_softc *sc, uint32_t len, uint32_t mask)
1486{
1487 if (len != sc->sc_transfer.data_rem) {
1488 if (sc->sc_transfer.cbw_dir == DIR_READ) {
1489 /*
1490 * there must be something wrong about this SCSI
1491 * command
1492 */
1493 sc->sc_csw->bCSWStatus = CSWSTATUS_PHASE;
1494 return (1);
1495 }
1496 /* compute the minimum length */
1497
1498 if (sc->sc_transfer.data_rem > len) {
1499 /* data ends prematurely */
1500 sc->sc_transfer.data_rem = len;
1501 sc->sc_transfer.data_short = 1;
1502 }
1503 /* check length alignment */
1504
1505 if (sc->sc_transfer.data_rem & ~mask) {
1506 /* data ends prematurely */
1507 sc->sc_transfer.data_rem &= mask;
1508 sc->sc_transfer.data_short = 1;
1509 }
1510 }
1511 return (0);
1512}
1513
1514/*------------------------------------------------------------------------*
1515 * ustorage_fs_check_cmd - check command routine
1516 *
1517 * Check whether the command is properly formed and whether its data
1518 * size and direction agree with the values we already have.
1519 *
1520 * Return values:
1521 * 0: Success
1522 * Else: Failure
1523 *------------------------------------------------------------------------*/
1524static uint8_t
1525ustorage_fs_check_cmd(struct ustorage_fs_softc *sc, uint8_t min_cmd_size,
1526 uint16_t mask, uint8_t needs_medium)
1527{
1528 struct ustorage_fs_lun *currlun;
1529 uint8_t lun = (sc->sc_cbw->CBWCDB[1] >> 5);
1530 uint8_t i;
1531
1532 /* Verify the length of the command itself */
1533 if (min_cmd_size > sc->sc_transfer.cmd_len) {
1534 DPRINTF("%u > %u\n",
1535 min_cmd_size, sc->sc_transfer.cmd_len);
1536 sc->sc_csw->bCSWStatus = CSWSTATUS_PHASE;
1537 return (1);
1538 }
1539 /* Mask away the LUN */
1540 sc->sc_cbw->CBWCDB[1] &= 0x1f;
1541
1542 /* Check if LUN is correct */
1543 if (lun != sc->sc_transfer.lun) {
1544 }
1545 /* Check the LUN */
1546 if (sc->sc_transfer.lun <= sc->sc_last_lun) {
1547 sc->sc_transfer.currlun = currlun =
1548 sc->sc_lun + sc->sc_transfer.lun;
1549 if (sc->sc_cbw->CBWCDB[0] != SC_REQUEST_SENSE) {
1550 currlun->sense_data = SS_NO_SENSE;
1551 currlun->sense_data_info = 0;
1552 currlun->info_valid = 0;
1553 }
1554 /*
1555 * If a unit attention condition exists, only INQUIRY
1556 * and REQUEST SENSE commands are allowed. Anything
1557 * else must fail!
1558 */
1559 if ((currlun->unit_attention_data != SS_NO_SENSE) &&
1560 (sc->sc_cbw->CBWCDB[0] != SC_INQUIRY) &&
1561 (sc->sc_cbw->CBWCDB[0] != SC_REQUEST_SENSE)) {
1562 currlun->sense_data = currlun->unit_attention_data;
1564 return (1);
1565 }
1566 } else {
1567 sc->sc_transfer.currlun = currlun = NULL;
1568
1569 /*
1570 * INQUIRY and REQUEST SENSE commands are explicitly allowed
1571 * to use unsupported LUNs; all others may not.
1572 */
1573 if ((sc->sc_cbw->CBWCDB[0] != SC_INQUIRY) &&
1574 (sc->sc_cbw->CBWCDB[0] != SC_REQUEST_SENSE)) {
1575 return (1);
1576 }
1577 }
1578
1579 /*
1580 * Check that only command bytes listed in the mask are
1581 * non-zero.
1582 */
1583 for (i = 0; i != min_cmd_size; i++) {
1584 if (sc->sc_cbw->CBWCDB[i] && !(mask & (1UL << i))) {
1585 if (currlun) {
1587 }
1588 return (1);
1589 }
1590 }
1591
1592 /*
1593 * If the medium isn't mounted and the command needs to access
1594 * it, return an error.
1595 */
1596 if (currlun && (!currlun->memory_image) && needs_medium) {
1598 return (1);
1599 }
1600 return (0);
1601}
1602
1603/*------------------------------------------------------------------------*
1604 * ustorage_fs_do_cmd - do command
1605 *
1606 * Return values:
1607 * 0: Success
1608 * Else: Failure
1609 *------------------------------------------------------------------------*/
1610static uint8_t
1612{
1613 uint8_t error = 1;
1614 uint8_t i;
1615 uint32_t temp;
1616 const uint32_t mask9 = (0xFFFFFFFFUL >> 9) << 9;
1617
1618 /* set default data transfer pointer */
1619 sc->sc_transfer.data_ptr = sc->sc_qdata;
1620
1621 DPRINTF("cmd_data[0]=0x%02x, data_rem=0x%08x\n",
1622 sc->sc_cbw->CBWCDB[0], sc->sc_transfer.data_rem);
1623
1624 switch (sc->sc_cbw->CBWCDB[0]) {
1625 case SC_INQUIRY:
1627 error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U);
1628 if (error) {
1629 break;
1630 }
1632 (1UL << 4) | 1, 0);
1633 if (error) {
1634 break;
1635 }
1637
1638 break;
1639
1640 case SC_MODE_SELECT_6:
1642 error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U);
1643 if (error) {
1644 break;
1645 }
1647 (1UL << 1) | (1UL << 4) | 1, 0);
1648 if (error) {
1649 break;
1650 }
1652
1653 break;
1654
1655 case SC_MODE_SELECT_10:
1658 get_be16(&sc->sc_cbw->CBWCDB[7]), -1U);
1659 if (error) {
1660 break;
1661 }
1663 (1UL << 1) | (3UL << 7) | 1, 0);
1664 if (error) {
1665 break;
1666 }
1668
1669 break;
1670
1671 case SC_MODE_SENSE_6:
1673 error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U);
1674 if (error) {
1675 break;
1676 }
1678 (1UL << 1) | (1UL << 2) | (1UL << 4) | 1, 0);
1679 if (error) {
1680 break;
1681 }
1683
1684 break;
1685
1686 case SC_MODE_SENSE_10:
1689 get_be16(&sc->sc_cbw->CBWCDB[7]), -1U);
1690 if (error) {
1691 break;
1692 }
1694 (1UL << 1) | (1UL << 2) | (3UL << 7) | 1, 0);
1695 if (error) {
1696 break;
1697 }
1699
1700 break;
1701
1703 error = ustorage_fs_min_len(sc, 0, -1U);
1704 if (error) {
1705 break;
1706 }
1708 (1UL << 4) | 1, 0);
1709 if (error) {
1710 break;
1711 }
1713
1714 break;
1715
1716 case SC_READ_6:
1717 i = sc->sc_cbw->CBWCDB[4];
1719 temp = ((i == 0) ? 256UL : i);
1720 error = ustorage_fs_min_len(sc, temp << 9, mask9);
1721 if (error) {
1722 break;
1723 }
1725 (7UL << 1) | (1UL << 4) | 1, 1);
1726 if (error) {
1727 break;
1728 }
1729 error = ustorage_fs_read(sc);
1730
1731 break;
1732
1733 case SC_READ_10:
1735 temp = get_be16(&sc->sc_cbw->CBWCDB[7]);
1736 error = ustorage_fs_min_len(sc, temp << 9, mask9);
1737 if (error) {
1738 break;
1739 }
1741 (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1);
1742 if (error) {
1743 break;
1744 }
1745 error = ustorage_fs_read(sc);
1746
1747 break;
1748
1749 case SC_READ_12:
1751 temp = get_be32(&sc->sc_cbw->CBWCDB[6]);
1752 if (temp >= (1UL << (32 - 9))) {
1753 /* numerical overflow */
1754 sc->sc_csw->bCSWStatus = CSWSTATUS_FAILED;
1755 error = 1;
1756 break;
1757 }
1758 error = ustorage_fs_min_len(sc, temp << 9, mask9);
1759 if (error) {
1760 break;
1761 }
1763 (1UL << 1) | (0xfUL << 2) | (0xfUL << 6) | 1, 1);
1764 if (error) {
1765 break;
1766 }
1767 error = ustorage_fs_read(sc);
1768
1769 break;
1770
1771 case SC_READ_CAPACITY:
1774 (0xfUL << 2) | (1UL << 8) | 1, 1);
1775 if (error) {
1776 break;
1777 }
1779
1780 break;
1781
1785 get_be16(&sc->sc_cbw->CBWCDB[7]), -1U);
1786 if (error) {
1787 break;
1788 }
1790 (3UL << 7) | 1, 1);
1791 if (error) {
1792 break;
1793 }
1795
1796 break;
1797
1798 case SC_REQUEST_SENSE:
1800 error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U);
1801 if (error) {
1802 break;
1803 }
1805 (1UL << 4) | 1, 0);
1806 if (error) {
1807 break;
1808 }
1810
1811 break;
1812
1813 case SC_START_STOP_UNIT:
1814 error = ustorage_fs_min_len(sc, 0, -1U);
1815 if (error) {
1816 break;
1817 }
1819 (1UL << 1) | (1UL << 4) | 1, 0);
1820 if (error) {
1821 break;
1822 }
1824
1825 break;
1826
1828 error = ustorage_fs_min_len(sc, 0, -1U);
1829 if (error) {
1830 break;
1831 }
1833 (0xfUL << 2) | (3UL << 7) | 1, 1);
1834 if (error) {
1835 break;
1836 }
1838
1839 break;
1840
1841 case SC_TEST_UNIT_READY:
1842 error = ustorage_fs_min_len(sc, 0, -1U);
1843 if (error) {
1844 break;
1845 }
1847 0 | 1, 1);
1848 break;
1849
1850 /*
1851 * Although optional, this command is used by MS-Windows.
1852 * We support a minimal version: BytChk must be 0.
1853 */
1854 case SC_VERIFY:
1855 error = ustorage_fs_min_len(sc, 0, -1U);
1856 if (error) {
1857 break;
1858 }
1860 (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1);
1861 if (error) {
1862 break;
1863 }
1865
1866 break;
1867
1868 case SC_WRITE_6:
1869 i = sc->sc_cbw->CBWCDB[4];
1871 temp = ((i == 0) ? 256UL : i);
1872 error = ustorage_fs_min_len(sc, temp << 9, mask9);
1873 if (error) {
1874 break;
1875 }
1877 (7UL << 1) | (1UL << 4) | 1, 1);
1878 if (error) {
1879 break;
1880 }
1882
1883 break;
1884
1885 case SC_WRITE_10:
1887 temp = get_be16(&sc->sc_cbw->CBWCDB[7]);
1888 error = ustorage_fs_min_len(sc, temp << 9, mask9);
1889 if (error) {
1890 break;
1891 }
1893 (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1);
1894 if (error) {
1895 break;
1896 }
1898
1899 break;
1900
1901 case SC_WRITE_12:
1903 temp = get_be32(&sc->sc_cbw->CBWCDB[6]);
1904 if (temp > (mask9 >> 9)) {
1905 /* numerical overflow */
1906 sc->sc_csw->bCSWStatus = CSWSTATUS_FAILED;
1907 error = 1;
1908 break;
1909 }
1910 error = ustorage_fs_min_len(sc, temp << 9, mask9);
1911 if (error) {
1912 break;
1913 }
1915 (1UL << 1) | (0xfUL << 2) | (0xfUL << 6) | 1, 1);
1916 if (error) {
1917 break;
1918 }
1920
1921 break;
1922
1923 /*
1924 * Some mandatory commands that we recognize but don't
1925 * implement. They don't mean much in this setting.
1926 * It's left as an exercise for anyone interested to
1927 * implement RESERVE and RELEASE in terms of Posix
1928 * locks.
1929 */
1930 case SC_FORMAT_UNIT:
1931 case SC_RELEASE:
1932 case SC_RESERVE:
1933 case SC_SEND_DIAGNOSTIC:
1934 /* Fallthrough */
1935
1936 default:
1937 error = ustorage_fs_min_len(sc, 0, -1U);
1938 if (error) {
1939 break;
1940 }
1942 0xff, 0);
1943 if (error) {
1944 break;
1945 }
1948 error = 1;
1949
1950 break;
1951 }
1952 return (error);
1953}
static int debug
Definition: cfumass.c:73
static SYSCTL_NODE(_hw_usb, OID_AUTO, dwc_otg, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "USB DWC OTG")
SYSCTL_INT(_hw_usb_dwc_otg, OID_AUTO, phy_type, CTLFLAG_RDTUN, &dwc_otg_phy_type, 0, "DWC OTG PHY TYPE - 0/1/2/3 - ULPI/HSIC/INTERNAL/UTMI+")
uint16_t len
Definition: ehci.h:41
uint32_t val
Definition: if_rum.c:284
struct @109 error
uint8_t id
Definition: if_usievar.h:4
bool start
device_t dev
enum usb_hc_mode usb_mode
Definition: usbdi.h:432
struct usbd_lookup_info info
Definition: usbdi.h:426
struct usb_interface * iface
Definition: usbdi.h:431
struct usb_device * device
Definition: usbdi.h:430
struct usb_xfer_flags flags
Definition: usbdi.h:235
enum usb_hc_mode usb_mode
Definition: usbdi.h:237
uint8_t type
Definition: usbdi.h:238
usb_callback_t * callback
Definition: usbdi.h:229
uint8_t short_xfer_ok
Definition: usbdi.h:198
uint8_t bIfaceIndex
Definition: usbdi.h:417
uint8_t removable
Definition: ustorage_fs.c:178
uint32_t sense_data
Definition: ustorage_fs.c:171
uint32_t unit_attention_data
Definition: ustorage_fs.c:173
uint32_t sense_data_info
Definition: ustorage_fs.c:172
uint32_t num_sectors
Definition: ustorage_fs.c:170
uint8_t * memory_image
Definition: ustorage_fs.c:168
uint8_t prevent_medium_removal
Definition: ustorage_fs.c:176
uint8_t info_valid
Definition: ustorage_fs.c:177
uint8_t read_only
Definition: ustorage_fs.c:175
ustorage_fs_bbb_cbw_t * sc_cbw
Definition: ustorage_fs.c:182
struct mtx sc_mtx
Definition: ustorage_fs.c:186
struct ustorage_fs_softc::@72 sc_transfer
uint8_t * data_ptr
Definition: ustorage_fs.c:191
struct usb_device * sc_udev
Definition: ustorage_fs.c:207
uint8_t sc_last_xfer_index
Definition: ustorage_fs.c:212
struct ustorage_fs_lun sc_lun[USTORAGE_FS_MAX_LUN]
Definition: ustorage_fs.c:188
ustorage_fs_bbb_csw_t * sc_csw
Definition: ustorage_fs.c:183
struct ustorage_fs_lun * currlun
Definition: ustorage_fs.c:192
uint8_t sc_qdata[USTORAGE_QDATA_MAX]
Definition: ustorage_fs.c:213
struct usb_xfer * sc_xfer[USTORAGE_FS_T_BBB_MAX]
Definition: ustorage_fs.c:208
#define DPRINTF(...)
Definition: umass.c:179
#define UIPROTO_MASS_BBB
Definition: usb.h:477
#define UE_ADDR_ANY
Definition: usb.h:537
#define UE_BULK
Definition: usb.h:543
#define UISUBCLASS_SCSI
Definition: usb.h:473
#define UT_READ_CLASS_INTERFACE
Definition: usb.h:173
#define UE_DIR_IN
Definition: usb.h:531
#define USB_POWER_MODE_SAVE
Definition: usb.h:98
#define UE_DIR_OUT
Definition: usb.h:532
@ USB_MODE_DEVICE
Definition: usb.h:779
#define UT_WRITE_CLASS_INTERFACE
Definition: usb.h:177
#define UICLASS_MASS
Definition: usb.h:467
struct usb_interface_descriptor * usbd_get_interface_descriptor(struct usb_interface *iface)
Definition: usb_device.c:2654
uint8_t uByte
Definition: usb_endian.h:41
#define USETDW(w, v)
Definition: usb_endian.h:82
#define UGETDW(w)
Definition: usb_endian.h:57
uint8_t uDWord[4]
Definition: usb_endian.h:43
const char * usbd_errstr(usb_error_t err)
Definition: usb_error.c:93
static usb_error_t usb_handle_request(struct usb_xfer *)
void usbd_set_power_mode(struct usb_device *udev, uint8_t power_mode)
Definition: usb_hub.c:2896
void ** pptr
Definition: usb_if.m:52
uint8_t * pstate
Definition: usb_if.m:55
uint16_t * plen
Definition: usb_if.m:53
uint16_t offset
Definition: usb_if.m:54
const void * req
Definition: usb_if.m:51
INTERFACE usb
Definition: usb_if.m:35
void usbd_xfer_set_flag(struct usb_xfer *xfer, int flag)
void usbd_transfer_submit(struct usb_xfer *xfer)
void usbd_transfer_unsetup(struct usb_xfer **pxfer, uint16_t n_setup)
void usbd_xfer_set_frame_data(struct usb_xfer *xfer, usb_frcount_t frindex, void *ptr, usb_frlength_t len)
void usbd_xfer_set_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex, usb_frlength_t len)
void * usbd_xfer_get_frame_buffer(struct usb_xfer *xfer, usb_frcount_t frindex)
usb_error_t usbd_transfer_setup(struct usb_device *udev, const uint8_t *ifaces, struct usb_xfer **ppxfer, const struct usb_config *setup_start, uint16_t n_setup, void *priv_sc, struct mtx *xfer_mtx)
Definition: usb_transfer.c:987
void usbd_transfer_start(struct usb_xfer *xfer)
int usbd_xfer_is_stalled(struct usb_xfer *xfer)
void usbd_transfer_drain(struct usb_xfer *xfer)
void usbd_xfer_clr_flag(struct usb_xfer *xfer, int flag)
void * usbd_xfer_softc(struct usb_xfer *xfer)
void usbd_xfer_set_stall(struct usb_xfer *xfer)
void usbd_transfer_stop(struct usb_xfer *xfer)
void usbd_xfer_status(struct usb_xfer *xfer, int *actlen, int *sumlen, int *aframes, int *nframes)
usb_frlength_t usbd_xfer_max_len(struct usb_xfer *xfer)
void device_set_usb_desc(device_t dev)
Definition: usb_util.c:73
#define USB_ST_SETUP
Definition: usbdi.h:502
#define USB_FORCE_SHORT_XFER
Definition: usbdi.h:81
usb_error_t
Definition: usbdi.h:45
@ USB_ERR_CANCELLED
Definition: usbdi.h:51
#define USB_ST_TRANSFERRED
Definition: usbdi.h:503
void() usb_callback_t(struct usb_xfer *, usb_error_t)
Definition: usbdi.h:94
#define USB_GET_STATE(xfer)
Definition: usbdi.h:515
#define CSWSTATUS_PHASE
Definition: ustorage_fs.c:162
static device_method_t ustorage_fs_methods[]
Definition: ustorage_fs.c:249
#define USTORAGE_FS_T_BBB_STATUS
Definition: ustorage_fs.c:122
static device_attach_t ustorage_fs_attach
Definition: ustorage_fs.c:219
static driver_t ustorage_fs_driver
Definition: ustorage_fs.c:263
#define SS_INVALID_COMMAND
Definition: ustorage_fs.c:878
#define SS_NO_SENSE
Definition: ustorage_fs.c:876
#define SC_TEST_UNIT_READY
Definition: ustorage_fs.c:869
#define SC_READ_12
Definition: ustorage_fs.c:860
#define SC_RESERVE
Definition: ustorage_fs.c:865
#define CBWSIGNATURE
Definition: ustorage_fs.c:139
#define SC_READ_6
Definition: ustorage_fs.c:858
static uint8_t ustorage_fs_read_capacity(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:1099
static uint8_t ustorage_fs_start_stop(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:1237
static devclass_t ustorage_fs_devclass
Definition: ustorage_fs.c:269
static struct usb_config ustorage_fs_bbb_config[USTORAGE_FS_T_BBB_MAX]
Definition: ustorage_fs.c:275
#define USTORAGE_FS_T_BBB_DATA_DUMP
Definition: ustorage_fs.c:119
#define USTORAGE_FS_MAX_LUN
Definition: ustorage_fs.c:88
static void ustorage_fs_transfer_start(struct ustorage_fs_softc *sc, uint8_t xfer_index)
Definition: ustorage_fs.c:464
static uint8_t ustorage_fs_write(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:1421
#define CBWCDBLENGTH
Definition: ustorage_fs.c:147
#define SC_MODE_SENSE_6
Definition: ustorage_fs.c:855
#define ASC(x)
Definition: ustorage_fs.c:892
static void put_be32(uint8_t *buf, uint32_t val)
Definition: ustorage_fs.c:918
static usb_handle_request_t ustorage_fs_handle_request
Definition: ustorage_fs.c:223
static uint8_t ustorage_fs_do_cmd(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:1611
#define SS_SAVING_PARAMETERS_NOT_SUPPORTED
Definition: ustorage_fs.c:886
static uint8_t ustorage_fs_request_sense(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:1030
#define USTORAGE_FS_T_BBB_DATA_WRITE
Definition: ustorage_fs.c:121
static uint8_t ustorage_fs_inquiry(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:989
static uint8_t ustorage_fs_read_format_capacities(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:1296
#define USTORAGE_FS_ID_STRING
Definition: ustorage_fs.c:100
MODULE_VERSION(ustorage_fs, 0)
MODULE_DEPEND(ustorage_fs, usb, 1, 1, 1)
static void ustorage_fs_transfer_stop(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:473
static void put_be16(uint8_t *buf, uint16_t val)
Definition: ustorage_fs.c:911
static uint8_t ustorage_fs_read(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:1369
static uint8_t ustorage_fs_synchronize_cache(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:1344
#define USTORAGE_QDATA_MAX
Definition: ustorage_fs.c:92
#define SC_MODE_SENSE_10
Definition: ustorage_fs.c:856
#define SC_READ_FORMAT_CAPACITIES
Definition: ustorage_fs.c:862
#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL
Definition: ustorage_fs.c:857
#define DIR_READ
Definition: ustorage_fs.c:128
#define DIR_NONE
Definition: ustorage_fs.c:127
#define SC_WRITE_10
Definition: ustorage_fs.c:872
#define UR_BBB_GET_MAX_LUN
Definition: ustorage_fs.c:134
static uint8_t ustorage_fs_prevent_allow(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:1266
#define SC_WRITE_12
Definition: ustorage_fs.c:873
#define CSWSIGNATURE
Definition: ustorage_fs.c:156
static usb_callback_t ustorage_fs_t_bbb_command_callback
Definition: ustorage_fs.c:225
#define SC_FORMAT_UNIT
Definition: ustorage_fs.c:851
static uint8_t ustorage_fs_check_cmd(struct ustorage_fs_softc *sc, uint8_t cmd_size, uint16_t mask, uint8_t needs_medium)
Definition: ustorage_fs.c:1525
#define ASCQ(x)
Definition: ustorage_fs.c:893
#define SC_WRITE_6
Definition: ustorage_fs.c:871
DRIVER_MODULE(ustorage_fs, uhub, ustorage_fs_driver, ustorage_fs_devclass, NULL, 0)
#define SK(x)
Definition: ustorage_fs.c:891
#define SS_WRITE_PROTECTED
Definition: ustorage_fs.c:889
#define USTORAGE_FS_RAM_SECT
Definition: ustorage_fs.c:111
static device_probe_t ustorage_fs_probe
Definition: ustorage_fs.c:218
static uint16_t get_be16(uint8_t *buf)
Definition: ustorage_fs.c:898
#define SC_MODE_SELECT_10
Definition: ustorage_fs.c:854
#define USTORAGE_FS_T_BBB_MAX
Definition: ustorage_fs.c:123
#define USTORAGE_FS_BULK_SIZE
Definition: ustorage_fs.c:84
#define SS_LOGICAL_UNIT_NOT_SUPPORTED
Definition: ustorage_fs.c:881
static device_detach_t ustorage_fs_detach
Definition: ustorage_fs.c:220
#define SC_INQUIRY
Definition: ustorage_fs.c:852
#define UR_BBB_RESET
Definition: ustorage_fs.c:133
static device_suspend_t ustorage_fs_suspend
Definition: ustorage_fs.c:221
static usb_callback_t ustorage_fs_t_bbb_data_write_callback
Definition: ustorage_fs.c:228
#define SC_VERIFY
Definition: ustorage_fs.c:870
#define SC_MODE_SELECT_6
Definition: ustorage_fs.c:853
#define DIR_WRITE
Definition: ustorage_fs.c:129
#define SC_READ_CAPACITY
Definition: ustorage_fs.c:861
#define USTORAGE_FS_T_BBB_COMMAND
Definition: ustorage_fs.c:118
#define SC_READ_10
Definition: ustorage_fs.c:859
static uint8_t * ustorage_fs_ramdisk
Definition: ustorage_fs.c:114
#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE
Definition: ustorage_fs.c:880
#define SC_START_STOP_UNIT
Definition: ustorage_fs.c:867
#define USTORAGE_FS_T_BBB_DATA_READ
Definition: ustorage_fs.c:120
static uint8_t ustorage_fs_mode_sense(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:1130
static uint8_t ustorage_fs_min_len(struct ustorage_fs_softc *sc, uint32_t len, uint32_t mask)
Definition: ustorage_fs.c:1485
#define SS_WRITE_ERROR
Definition: ustorage_fs.c:888
#define SC_REQUEST_SENSE
Definition: ustorage_fs.c:864
#define SS_INVALID_FIELD_IN_CDB
Definition: ustorage_fs.c:879
#define CBWFLAGS_IN
Definition: ustorage_fs.c:144
static uint32_t get_be32(uint8_t *buf)
Definition: ustorage_fs.c:904
#define SS_MEDIUM_NOT_PRESENT
Definition: ustorage_fs.c:882
#define CSWSTATUS_FAILED
Definition: ustorage_fs.c:161
static uint8_t ustorage_fs_mode_select(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:1327
static usb_callback_t ustorage_fs_t_bbb_data_dump_callback
Definition: ustorage_fs.c:226
static uint8_t ustorage_fs_verify(struct ustorage_fs_softc *sc)
Definition: ustorage_fs.c:934
static usb_callback_t ustorage_fs_t_bbb_data_read_callback
Definition: ustorage_fs.c:227
#define SC_RELEASE
Definition: ustorage_fs.c:863
#define SC_SYNCHRONIZE_CACHE
Definition: ustorage_fs.c:868
static usb_callback_t ustorage_fs_t_bbb_status_callback
Definition: ustorage_fs.c:229
static device_resume_t ustorage_fs_resume
Definition: ustorage_fs.c:222
#define SC_SEND_DIAGNOSTIC
Definition: ustorage_fs.c:866