The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/storage/ustorage_fs.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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
   73 static int ustorage_fs_debug = 0;
   74 
   75 SYSCTL_NODE(_hw_usb, OID_AUTO, ustorage_fs, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
   76     "USB ustorage_fs");
   77 SYSCTL_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 
  114 static 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 */
  137 typedef 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 */
  154 typedef 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 
  167 struct ustorage_fs_lun {
  168         uint8_t *memory_image;
  169 
  170         uint32_t num_sectors;
  171         uint32_t sense_data;
  172         uint32_t sense_data_info;
  173         uint32_t unit_attention_data;
  174 
  175         uint8_t read_only:1;
  176         uint8_t prevent_medium_removal:1;
  177         uint8_t info_valid:1;
  178         uint8_t removable:1;
  179 };
  180 
  181 struct ustorage_fs_softc {
  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 
  188         struct ustorage_fs_lun sc_lun[USTORAGE_FS_MAX_LUN];
  189 
  190         struct {
  191                 uint8_t *data_ptr;
  192                 struct ustorage_fs_lun *currlun;
  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;
  204         }       sc_transfer;
  205 
  206         device_t sc_dev;
  207         struct usb_device *sc_udev;
  208         struct usb_xfer *sc_xfer[USTORAGE_FS_T_BBB_MAX];
  209 
  210         uint8_t sc_iface_no;            /* interface number */
  211         uint8_t sc_last_lun;
  212         uint8_t sc_last_xfer_index;
  213         uint8_t sc_qdata[USTORAGE_QDATA_MAX];
  214 };
  215 
  216 /* prototypes */
  217 
  218 static device_probe_t ustorage_fs_probe;
  219 static device_attach_t ustorage_fs_attach;
  220 static device_detach_t ustorage_fs_detach;
  221 static device_suspend_t ustorage_fs_suspend;
  222 static device_resume_t ustorage_fs_resume;
  223 static usb_handle_request_t ustorage_fs_handle_request;
  224 
  225 static usb_callback_t ustorage_fs_t_bbb_command_callback;
  226 static usb_callback_t ustorage_fs_t_bbb_data_dump_callback;
  227 static usb_callback_t ustorage_fs_t_bbb_data_read_callback;
  228 static usb_callback_t ustorage_fs_t_bbb_data_write_callback;
  229 static usb_callback_t ustorage_fs_t_bbb_status_callback;
  230 
  231 static void ustorage_fs_transfer_start(struct ustorage_fs_softc *sc, uint8_t xfer_index);
  232 static void ustorage_fs_transfer_stop(struct ustorage_fs_softc *sc);
  233 
  234 static uint8_t ustorage_fs_verify(struct ustorage_fs_softc *sc);
  235 static uint8_t ustorage_fs_inquiry(struct ustorage_fs_softc *sc);
  236 static uint8_t ustorage_fs_request_sense(struct ustorage_fs_softc *sc);
  237 static uint8_t ustorage_fs_read_capacity(struct ustorage_fs_softc *sc);
  238 static uint8_t ustorage_fs_mode_sense(struct ustorage_fs_softc *sc);
  239 static uint8_t ustorage_fs_start_stop(struct ustorage_fs_softc *sc);
  240 static uint8_t ustorage_fs_prevent_allow(struct ustorage_fs_softc *sc);
  241 static uint8_t ustorage_fs_read_format_capacities(struct ustorage_fs_softc *sc);
  242 static uint8_t ustorage_fs_mode_select(struct ustorage_fs_softc *sc);
  243 static uint8_t ustorage_fs_min_len(struct ustorage_fs_softc *sc, uint32_t len, uint32_t mask);
  244 static uint8_t ustorage_fs_read(struct ustorage_fs_softc *sc);
  245 static uint8_t ustorage_fs_write(struct ustorage_fs_softc *sc);
  246 static uint8_t ustorage_fs_check_cmd(struct ustorage_fs_softc *sc, uint8_t cmd_size, uint16_t mask, uint8_t needs_medium);
  247 static uint8_t ustorage_fs_do_cmd(struct ustorage_fs_softc *sc);
  248 
  249 static device_method_t ustorage_fs_methods[] = {
  250         /* USB interface */
  251         DEVMETHOD(usb_handle_request, ustorage_fs_handle_request),
  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 
  263 static driver_t ustorage_fs_driver = {
  264         .name = "ustorage_fs",
  265         .methods = ustorage_fs_methods,
  266         .size = sizeof(struct ustorage_fs_softc),
  267 };
  268 
  269 DRIVER_MODULE(ustorage_fs, uhub, ustorage_fs_driver, NULL, NULL);
  270 MODULE_VERSION(ustorage_fs, 0);
  271 MODULE_DEPEND(ustorage_fs, usb, 1, 1, 1);
  272 
  273 static struct usb_config ustorage_fs_bbb_config[USTORAGE_FS_T_BBB_MAX] = {
  274         [USTORAGE_FS_T_BBB_COMMAND] = {
  275                 .type = UE_BULK,
  276                 .endpoint = UE_ADDR_ANY,
  277                 .direction = UE_DIR_OUT,
  278                 .bufsize = sizeof(ustorage_fs_bbb_cbw_t),
  279                 .callback = &ustorage_fs_t_bbb_command_callback,
  280                 .usb_mode = USB_MODE_DEVICE,
  281         },
  282 
  283         [USTORAGE_FS_T_BBB_DATA_DUMP] = {
  284                 .type = UE_BULK,
  285                 .endpoint = UE_ADDR_ANY,
  286                 .direction = UE_DIR_OUT,
  287                 .bufsize = 0,   /* use wMaxPacketSize */
  288                 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,},
  289                 .callback = &ustorage_fs_t_bbb_data_dump_callback,
  290                 .usb_mode = USB_MODE_DEVICE,
  291         },
  292 
  293         [USTORAGE_FS_T_BBB_DATA_READ] = {
  294                 .type = UE_BULK,
  295                 .endpoint = UE_ADDR_ANY,
  296                 .direction = UE_DIR_OUT,
  297                 .bufsize = USTORAGE_FS_BULK_SIZE,
  298                 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1},
  299                 .callback = &ustorage_fs_t_bbb_data_read_callback,
  300                 .usb_mode = USB_MODE_DEVICE,
  301         },
  302 
  303         [USTORAGE_FS_T_BBB_DATA_WRITE] = {
  304                 .type = UE_BULK,
  305                 .endpoint = UE_ADDR_ANY,
  306                 .direction = UE_DIR_IN,
  307                 .bufsize = USTORAGE_FS_BULK_SIZE,
  308                 .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer = 1},
  309                 .callback = &ustorage_fs_t_bbb_data_write_callback,
  310                 .usb_mode = USB_MODE_DEVICE,
  311         },
  312 
  313         [USTORAGE_FS_T_BBB_STATUS] = {
  314                 .type = UE_BULK,
  315                 .endpoint = UE_ADDR_ANY,
  316                 .direction = UE_DIR_IN,
  317                 .bufsize = sizeof(ustorage_fs_bbb_csw_t),
  318                 .flags = {.short_xfer_ok = 1},
  319                 .callback = &ustorage_fs_t_bbb_status_callback,
  320                 .usb_mode = USB_MODE_DEVICE,
  321         },
  322 };
  323 
  324 /*
  325  * USB device probe/attach/detach
  326  */
  327 
  328 static int
  329 ustorage_fs_probe(device_t dev)
  330 {
  331         struct usb_attach_arg *uaa = device_get_ivars(dev);
  332         struct usb_interface_descriptor *id;
  333 
  334         if (uaa->usb_mode != USB_MODE_DEVICE) {
  335                 return (ENXIO);
  336         }
  337         /* Check for a standards compliant device */
  338         id = usbd_get_interface_descriptor(uaa->iface);
  339         if ((id == NULL) ||
  340             (id->bInterfaceClass != UICLASS_MASS) ||
  341             (id->bInterfaceSubClass != UISUBCLASS_SCSI) ||
  342             (id->bInterfaceProtocol != UIPROTO_MASS_BBB)) {
  343                 return (ENXIO);
  344         }
  345         return (BUS_PROBE_GENERIC);
  346 }
  347 
  348 static int
  349 ustorage_fs_attach(device_t dev)
  350 {
  351         struct ustorage_fs_softc *sc = device_get_softc(dev);
  352         struct usb_attach_arg *uaa = device_get_ivars(dev);
  353         struct usb_interface_descriptor *id;
  354         int err;
  355         int unit;
  356 
  357         /*
  358          * NOTE: the softc struct is cleared in device_set_driver.
  359          * We can safely call ustorage_fs_detach without specifically
  360          * initializing the struct.
  361          */
  362 
  363         sc->sc_dev = dev;
  364         sc->sc_udev = uaa->device;
  365         unit = device_get_unit(dev);
  366 
  367         /* enable power saving mode */
  368         usbd_set_power_mode(uaa->device, USB_POWER_MODE_SAVE);
  369 
  370         if (unit == 0) {
  371                 if (ustorage_fs_ramdisk == NULL) {
  372                         /*
  373                          * allocate a memory image for our ramdisk until
  374                          * further
  375                          */
  376                         ustorage_fs_ramdisk =
  377                             malloc(USTORAGE_FS_RAM_SECT << 9, M_USB,
  378                             M_ZERO | M_WAITOK);
  379                 }
  380                 sc->sc_lun[0].memory_image = ustorage_fs_ramdisk;
  381                 sc->sc_lun[0].num_sectors = USTORAGE_FS_RAM_SECT;
  382                 sc->sc_lun[0].removable = 1;
  383         }
  384 
  385         device_set_usb_desc(dev);
  386 
  387         mtx_init(&sc->sc_mtx, "USTORAGE_FS lock",
  388             NULL, (MTX_DEF | MTX_RECURSE));
  389 
  390         /* get interface index */
  391 
  392         id = usbd_get_interface_descriptor(uaa->iface);
  393         if (id == NULL) {
  394                 device_printf(dev, "failed to get "
  395                     "interface number\n");
  396                 goto detach;
  397         }
  398         sc->sc_iface_no = id->bInterfaceNumber;
  399 
  400         err = usbd_transfer_setup(uaa->device,
  401             &uaa->info.bIfaceIndex, sc->sc_xfer, ustorage_fs_bbb_config,
  402             USTORAGE_FS_T_BBB_MAX, sc, &sc->sc_mtx);
  403         if (err) {
  404                 device_printf(dev, "could not setup required "
  405                     "transfers, %s\n", usbd_errstr(err));
  406                 goto detach;
  407         }
  408 
  409         sc->sc_cbw = usbd_xfer_get_frame_buffer(sc->sc_xfer[
  410             USTORAGE_FS_T_BBB_COMMAND], 0);
  411         sc->sc_csw = usbd_xfer_get_frame_buffer(sc->sc_xfer[
  412             USTORAGE_FS_T_BBB_STATUS], 0);
  413         sc->sc_dma_ptr = usbd_xfer_get_frame_buffer(sc->sc_xfer[
  414             USTORAGE_FS_T_BBB_DATA_READ], 0);
  415 
  416         /* start Mass Storage State Machine */
  417 
  418         mtx_lock(&sc->sc_mtx);
  419         ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_COMMAND);
  420         mtx_unlock(&sc->sc_mtx);
  421 
  422         return (0);                     /* success */
  423 
  424 detach:
  425         ustorage_fs_detach(dev);
  426         return (ENXIO);                 /* failure */
  427 }
  428 
  429 static int
  430 ustorage_fs_detach(device_t dev)
  431 {
  432         struct ustorage_fs_softc *sc = device_get_softc(dev);
  433 
  434         /* teardown our statemachine */
  435 
  436         usbd_transfer_unsetup(sc->sc_xfer, USTORAGE_FS_T_BBB_MAX);
  437 
  438         mtx_destroy(&sc->sc_mtx);
  439 
  440         return (0);                     /* success */
  441 }
  442 
  443 static int
  444 ustorage_fs_suspend(device_t dev)
  445 {
  446         device_printf(dev, "suspending\n");
  447         return (0);                     /* success */
  448 }
  449 
  450 static int
  451 ustorage_fs_resume(device_t dev)
  452 {
  453         device_printf(dev, "resuming\n");
  454         return (0);                     /* success */
  455 }
  456 
  457 /*
  458  * Generic functions to handle transfers
  459  */
  460 
  461 static void
  462 ustorage_fs_transfer_start(struct ustorage_fs_softc *sc, uint8_t xfer_index)
  463 {
  464         if (sc->sc_xfer[xfer_index]) {
  465                 sc->sc_last_xfer_index = xfer_index;
  466                 usbd_transfer_start(sc->sc_xfer[xfer_index]);
  467         }
  468 }
  469 
  470 static void
  471 ustorage_fs_transfer_stop(struct ustorage_fs_softc *sc)
  472 {
  473         usbd_transfer_stop(sc->sc_xfer[sc->sc_last_xfer_index]);
  474         mtx_unlock(&sc->sc_mtx);
  475         usbd_transfer_drain(sc->sc_xfer[sc->sc_last_xfer_index]);
  476         mtx_lock(&sc->sc_mtx);
  477 }
  478 
  479 static int
  480 ustorage_fs_handle_request(device_t dev,
  481     const void *preq, void **pptr, uint16_t *plen,
  482     uint16_t offset, uint8_t *pstate)
  483 {
  484         struct ustorage_fs_softc *sc = device_get_softc(dev);
  485         const struct usb_device_request *req = preq;
  486         uint8_t is_complete = *pstate;
  487 
  488         if (!is_complete) {
  489                 if ((req->bmRequestType == UT_WRITE_CLASS_INTERFACE) &&
  490                     (req->bRequest == UR_BBB_RESET)) {
  491                         *plen = 0;
  492                         mtx_lock(&sc->sc_mtx);
  493                         ustorage_fs_transfer_stop(sc);
  494                         sc->sc_transfer.data_error = 1;
  495                         ustorage_fs_transfer_start(sc,
  496                             USTORAGE_FS_T_BBB_COMMAND);
  497                         mtx_unlock(&sc->sc_mtx);
  498                         return (0);
  499                 } else if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) &&
  500                            (req->bRequest == UR_BBB_GET_MAX_LUN)) {
  501                         if (offset == 0) {
  502                                 *plen = 1;
  503                                 *pptr = &sc->sc_last_lun;
  504                         } else {
  505                                 *plen = 0;
  506                         }
  507                         return (0);
  508                 }
  509         }
  510         return (ENXIO);                 /* use builtin handler */
  511 }
  512 
  513 static void
  514 ustorage_fs_t_bbb_command_callback(struct usb_xfer *xfer, usb_error_t error)
  515 {
  516         struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer);
  517         uint32_t tag;
  518         uint8_t err = 0;
  519 
  520         DPRINTF("\n");
  521 
  522         switch (USB_GET_STATE(xfer)) {
  523         case USB_ST_TRANSFERRED:
  524 
  525                 tag = UGETDW(sc->sc_cbw->dCBWSignature);
  526 
  527                 if (tag != CBWSIGNATURE) {
  528                         /* do nothing */
  529                         DPRINTF("invalid signature 0x%08x\n", tag);
  530                         break;
  531                 }
  532                 tag = UGETDW(sc->sc_cbw->dCBWTag);
  533 
  534                 /* echo back tag */
  535                 USETDW(sc->sc_csw->dCSWTag, tag);
  536 
  537                 /* reset status */
  538                 sc->sc_csw->bCSWStatus = 0;
  539 
  540                 /* reset data offset, data length and data remainder */
  541                 sc->sc_transfer.offset = 0;
  542                 sc->sc_transfer.data_rem =
  543                     UGETDW(sc->sc_cbw->dCBWDataTransferLength);
  544 
  545                 /* reset data flags */
  546                 sc->sc_transfer.data_short = 0;
  547 
  548                 /* extract LUN */
  549                 sc->sc_transfer.lun = sc->sc_cbw->bCBWLUN;
  550 
  551                 if (sc->sc_transfer.data_rem == 0) {
  552                         sc->sc_transfer.cbw_dir = DIR_NONE;
  553                 } else {
  554                         if (sc->sc_cbw->bCBWFlags & CBWFLAGS_IN) {
  555                                 sc->sc_transfer.cbw_dir = DIR_WRITE;
  556                         } else {
  557                                 sc->sc_transfer.cbw_dir = DIR_READ;
  558                         }
  559                 }
  560 
  561                 sc->sc_transfer.cmd_len = sc->sc_cbw->bCDBLength;
  562                 if ((sc->sc_transfer.cmd_len > sizeof(sc->sc_cbw->CBWCDB)) ||
  563                     (sc->sc_transfer.cmd_len == 0)) {
  564                         /* just halt - this is invalid */
  565                         DPRINTF("invalid command length %d bytes\n",
  566                             sc->sc_transfer.cmd_len);
  567                         break;
  568                 }
  569 
  570                 err = ustorage_fs_do_cmd(sc);
  571                 if (err) {
  572                         /* got an error */
  573                         DPRINTF("command failed\n");
  574                         break;
  575                 }
  576                 if ((sc->sc_transfer.data_rem > 0) &&
  577                     (sc->sc_transfer.cbw_dir != sc->sc_transfer.cmd_dir)) {
  578                         /* contradicting data transfer direction */
  579                         err = 1;
  580                         DPRINTF("data direction mismatch\n");
  581                         break;
  582                 }
  583                 switch (sc->sc_transfer.cbw_dir) {
  584                 case DIR_READ:
  585                         ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_DATA_READ);
  586                         break;
  587                 case DIR_WRITE:
  588                         ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_DATA_WRITE);
  589                         break;
  590                 default:
  591                         ustorage_fs_transfer_start(sc,
  592                             USTORAGE_FS_T_BBB_STATUS);
  593                         break;
  594                 }
  595                 break;
  596 
  597         case USB_ST_SETUP:
  598 tr_setup:
  599                 if (sc->sc_transfer.data_error) {
  600                         sc->sc_transfer.data_error = 0;
  601                         usbd_xfer_set_stall(xfer);
  602                         DPRINTF("stall pipe\n");
  603                 }
  604                 usbd_xfer_set_frame_len(xfer, 0,
  605                     sizeof(ustorage_fs_bbb_cbw_t));
  606                 usbd_transfer_submit(xfer);
  607                 break;
  608 
  609         default:                        /* Error */
  610                 DPRINTF("error\n");
  611                 if (error == USB_ERR_CANCELLED) {
  612                         break;
  613                 }
  614                 /* If the pipe is already stalled, don't do another stall */
  615                 if (!usbd_xfer_is_stalled(xfer))
  616                         sc->sc_transfer.data_error = 1;
  617 
  618                 /* try again */
  619                 goto tr_setup;
  620         }
  621         if (err) {
  622                 if (sc->sc_csw->bCSWStatus == 0) {
  623                         /* set some default error code */
  624                         sc->sc_csw->bCSWStatus = CSWSTATUS_FAILED;
  625                 }
  626                 if (sc->sc_transfer.cbw_dir == DIR_READ) {
  627                         /* dump all data */
  628                         ustorage_fs_transfer_start(sc,
  629                             USTORAGE_FS_T_BBB_DATA_DUMP);
  630                         return;
  631                 }
  632                 if (sc->sc_transfer.cbw_dir == DIR_WRITE) {
  633                         /* need to stall before status */
  634                         sc->sc_transfer.data_error = 1;
  635                 }
  636                 ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_STATUS);
  637         }
  638 }
  639 
  640 static void
  641 ustorage_fs_t_bbb_data_dump_callback(struct usb_xfer *xfer, usb_error_t error)
  642 {
  643         struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer);
  644         uint32_t max_bulk = usbd_xfer_max_len(xfer);
  645         int actlen, sumlen;
  646 
  647         usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
  648 
  649         DPRINTF("\n");
  650 
  651         switch (USB_GET_STATE(xfer)) {
  652         case USB_ST_TRANSFERRED:
  653                 sc->sc_transfer.data_rem -= actlen;
  654                 sc->sc_transfer.offset += actlen;
  655 
  656                 if (actlen != sumlen || sc->sc_transfer.data_rem == 0) {
  657                         /* short transfer or end of data */
  658                         ustorage_fs_transfer_start(sc,
  659                             USTORAGE_FS_T_BBB_STATUS);
  660                         break;
  661                 }
  662                 /* Fallthrough */
  663 
  664         case USB_ST_SETUP:
  665 tr_setup:
  666                 if (max_bulk > sc->sc_transfer.data_rem) {
  667                         max_bulk = sc->sc_transfer.data_rem;
  668                 }
  669                 if (sc->sc_transfer.data_error) {
  670                         sc->sc_transfer.data_error = 0;
  671                         usbd_xfer_set_stall(xfer);
  672                 }
  673                 usbd_xfer_set_frame_len(xfer, 0, max_bulk);
  674                 usbd_transfer_submit(xfer);
  675                 break;
  676 
  677         default:                        /* Error */
  678                 if (error == USB_ERR_CANCELLED) {
  679                         break;
  680                 }
  681                 /*
  682                  * If the pipe is already stalled, don't do another stall:
  683                  */
  684                 if (!usbd_xfer_is_stalled(xfer))
  685                         sc->sc_transfer.data_error = 1;
  686 
  687                 /* try again */
  688                 goto tr_setup;
  689         }
  690 }
  691 
  692 static void
  693 ustorage_fs_t_bbb_data_read_callback(struct usb_xfer *xfer, usb_error_t error)
  694 {
  695         struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer);
  696         uint32_t max_bulk = usbd_xfer_max_len(xfer);
  697         int actlen, sumlen;
  698 
  699         usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
  700 
  701         DPRINTF("\n");
  702 
  703         switch (USB_GET_STATE(xfer)) {
  704         case USB_ST_TRANSFERRED:
  705                 /* XXX copy data from DMA buffer */
  706                 memcpy(sc->sc_transfer.data_ptr, sc->sc_dma_ptr, actlen);
  707 
  708                 sc->sc_transfer.data_rem -= actlen;
  709                 sc->sc_transfer.data_ptr += actlen;
  710                 sc->sc_transfer.offset += actlen;
  711 
  712                 if (actlen != sumlen || sc->sc_transfer.data_rem == 0) {
  713                         /* short transfer or end of data */
  714                         ustorage_fs_transfer_start(sc,
  715                             USTORAGE_FS_T_BBB_STATUS);
  716                         break;
  717                 }
  718                 /* Fallthrough */
  719 
  720         case USB_ST_SETUP:
  721 tr_setup:
  722                 if (max_bulk > sc->sc_transfer.data_rem) {
  723                         max_bulk = sc->sc_transfer.data_rem;
  724                 }
  725                 if (sc->sc_transfer.data_error) {
  726                         sc->sc_transfer.data_error = 0;
  727                         usbd_xfer_set_stall(xfer);
  728                 }
  729 
  730                 usbd_xfer_set_frame_data(xfer, 0, sc->sc_dma_ptr, max_bulk);
  731                 usbd_transfer_submit(xfer);
  732                 break;
  733 
  734         default:                        /* Error */
  735                 if (error == USB_ERR_CANCELLED) {
  736                         break;
  737                 }
  738                 /* If the pipe is already stalled, don't do another stall */
  739                 if (!usbd_xfer_is_stalled(xfer))
  740                         sc->sc_transfer.data_error = 1;
  741 
  742                 /* try again */
  743                 goto tr_setup;
  744         }
  745 }
  746 
  747 static void
  748 ustorage_fs_t_bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error)
  749 {
  750         struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer);
  751         uint32_t max_bulk = usbd_xfer_max_len(xfer);
  752         int actlen, sumlen;
  753 
  754         usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
  755 
  756         DPRINTF("\n");
  757 
  758         switch (USB_GET_STATE(xfer)) {
  759         case USB_ST_TRANSFERRED:
  760                 sc->sc_transfer.data_rem -= actlen;
  761                 sc->sc_transfer.data_ptr += actlen;
  762                 sc->sc_transfer.offset += actlen;
  763 
  764                 if (actlen != sumlen || sc->sc_transfer.data_rem == 0) {
  765                         /* short transfer or end of data */
  766                         ustorage_fs_transfer_start(sc,
  767                             USTORAGE_FS_T_BBB_STATUS);
  768                         break;
  769                 }
  770         case USB_ST_SETUP:
  771 tr_setup:
  772                 if (max_bulk >= sc->sc_transfer.data_rem) {
  773                         max_bulk = sc->sc_transfer.data_rem;
  774                         if (sc->sc_transfer.data_short)
  775                                 usbd_xfer_set_flag(xfer, USB_FORCE_SHORT_XFER);
  776                         else
  777                                 usbd_xfer_clr_flag(xfer, USB_FORCE_SHORT_XFER);
  778                 } else
  779                         usbd_xfer_clr_flag(xfer, USB_FORCE_SHORT_XFER);
  780 
  781                 if (sc->sc_transfer.data_error) {
  782                         sc->sc_transfer.data_error = 0;
  783                         usbd_xfer_set_stall(xfer);
  784                 }
  785 
  786                 /* XXX copy data to DMA buffer */
  787                 memcpy(sc->sc_dma_ptr, sc->sc_transfer.data_ptr, max_bulk);
  788 
  789                 usbd_xfer_set_frame_data(xfer, 0, sc->sc_dma_ptr, max_bulk);
  790                 usbd_transfer_submit(xfer);
  791                 break;
  792 
  793         default:                        /* Error */
  794                 if (error == USB_ERR_CANCELLED) {
  795                         break;
  796                 }
  797                 /*
  798                  * If the pipe is already stalled, don't do another
  799                  * stall
  800                  */
  801                 if (!usbd_xfer_is_stalled(xfer))
  802                         sc->sc_transfer.data_error = 1;
  803 
  804                 /* try again */
  805                 goto tr_setup;
  806         }
  807 }
  808 
  809 static void
  810 ustorage_fs_t_bbb_status_callback(struct usb_xfer *xfer, usb_error_t error)
  811 {
  812         struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer);
  813 
  814         DPRINTF("\n");
  815 
  816         switch (USB_GET_STATE(xfer)) {
  817         case USB_ST_TRANSFERRED:
  818                 ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_COMMAND);
  819                 break;
  820 
  821         case USB_ST_SETUP:
  822 tr_setup:
  823                 USETDW(sc->sc_csw->dCSWSignature, CSWSIGNATURE);
  824                 USETDW(sc->sc_csw->dCSWDataResidue, sc->sc_transfer.data_rem);
  825 
  826                 if (sc->sc_transfer.data_error) {
  827                         sc->sc_transfer.data_error = 0;
  828                         usbd_xfer_set_stall(xfer);
  829                 }
  830                 usbd_xfer_set_frame_len(xfer, 0,
  831                     sizeof(ustorage_fs_bbb_csw_t));
  832                 usbd_transfer_submit(xfer);
  833                 break;
  834 
  835         default:
  836                 if (error == USB_ERR_CANCELLED) {
  837                         break;
  838                 }
  839                 /* If the pipe is already stalled, don't do another stall */
  840                 if (!usbd_xfer_is_stalled(xfer))
  841                         sc->sc_transfer.data_error = 1;
  842 
  843                 /* try again */
  844                 goto tr_setup;
  845         }
  846 }
  847 
  848 /* SCSI commands that we recognize */
  849 #define SC_FORMAT_UNIT                  0x04
  850 #define SC_INQUIRY                      0x12
  851 #define SC_MODE_SELECT_6                0x15
  852 #define SC_MODE_SELECT_10               0x55
  853 #define SC_MODE_SENSE_6                 0x1a
  854 #define SC_MODE_SENSE_10                0x5a
  855 #define SC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
  856 #define SC_READ_6                       0x08
  857 #define SC_READ_10                      0x28
  858 #define SC_READ_12                      0xa8
  859 #define SC_READ_CAPACITY                0x25
  860 #define SC_READ_FORMAT_CAPACITIES       0x23
  861 #define SC_RELEASE                      0x17
  862 #define SC_REQUEST_SENSE                0x03
  863 #define SC_RESERVE                      0x16
  864 #define SC_SEND_DIAGNOSTIC              0x1d
  865 #define SC_START_STOP_UNIT              0x1b
  866 #define SC_SYNCHRONIZE_CACHE            0x35
  867 #define SC_TEST_UNIT_READY              0x00
  868 #define SC_VERIFY                       0x2f
  869 #define SC_WRITE_6                      0x0a
  870 #define SC_WRITE_10                     0x2a
  871 #define SC_WRITE_12                     0xaa
  872 
  873 /* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
  874 #define SS_NO_SENSE                             0
  875 #define SS_COMMUNICATION_FAILURE                0x040800
  876 #define SS_INVALID_COMMAND                      0x052000
  877 #define SS_INVALID_FIELD_IN_CDB                 0x052400
  878 #define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE   0x052100
  879 #define SS_LOGICAL_UNIT_NOT_SUPPORTED           0x052500
  880 #define SS_MEDIUM_NOT_PRESENT                   0x023a00
  881 #define SS_MEDIUM_REMOVAL_PREVENTED             0x055302
  882 #define SS_NOT_READY_TO_READY_TRANSITION        0x062800
  883 #define SS_RESET_OCCURRED                       0x062900
  884 #define SS_SAVING_PARAMETERS_NOT_SUPPORTED      0x053900
  885 #define SS_UNRECOVERED_READ_ERROR               0x031100
  886 #define SS_WRITE_ERROR                          0x030c02
  887 #define SS_WRITE_PROTECTED                      0x072700
  888 
  889 #define SK(x)           ((uint8_t) ((x) >> 16)) /* Sense Key byte, etc. */
  890 #define ASC(x)          ((uint8_t) ((x) >> 8))
  891 #define ASCQ(x)         ((uint8_t) (x))
  892 
  893 /* Routines for unaligned data access */
  894 
  895 static uint16_t
  896 get_be16(uint8_t *buf)
  897 {
  898         return ((uint16_t)buf[0] << 8) | ((uint16_t)buf[1]);
  899 }
  900 
  901 static uint32_t
  902 get_be32(uint8_t *buf)
  903 {
  904         return ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
  905         ((uint32_t)buf[2] << 8) | ((uint32_t)buf[3]);
  906 }
  907 
  908 static void
  909 put_be16(uint8_t *buf, uint16_t val)
  910 {
  911         buf[0] = val >> 8;
  912         buf[1] = val;
  913 }
  914 
  915 static void
  916 put_be32(uint8_t *buf, uint32_t val)
  917 {
  918         buf[0] = val >> 24;
  919         buf[1] = val >> 16;
  920         buf[2] = val >> 8;
  921         buf[3] = val & 0xff;
  922 }
  923 
  924 /*------------------------------------------------------------------------*
  925  *      ustorage_fs_verify
  926  *
  927  * Returns:
  928  *    0: Success
  929  * Else: Failure
  930  *------------------------------------------------------------------------*/
  931 static uint8_t
  932 ustorage_fs_verify(struct ustorage_fs_softc *sc)
  933 {
  934         struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
  935         uint32_t lba;
  936         uint32_t vlen;
  937 
  938         /*
  939          * Get the starting Logical Block Address
  940          */
  941         lba = get_be32(&sc->sc_cbw->CBWCDB[2]);
  942 
  943         /*
  944          * We allow DPO (Disable Page Out = don't save data in the cache)
  945          * but we don't implement it.
  946          */
  947         if ((sc->sc_cbw->CBWCDB[1] & ~0x10) != 0) {
  948                 currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
  949                 return (1);
  950         }
  951         vlen = get_be16(&sc->sc_cbw->CBWCDB[7]);
  952         if (vlen == 0) {
  953                 goto done;
  954         }
  955         /* No default reply */
  956 
  957         /* Range check */
  958         vlen += lba;
  959 
  960         if ((vlen < lba) ||
  961             (vlen > currlun->num_sectors) ||
  962             (lba >= currlun->num_sectors)) {
  963                 currlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
  964                 return (1);
  965         }
  966         /* XXX TODO: verify that data is readable */
  967 done:
  968         return (ustorage_fs_min_len(sc, 0, -1U));
  969 }
  970 
  971 /*------------------------------------------------------------------------*
  972  *      ustorage_fs_inquiry
  973  *
  974  * Returns:
  975  *    0: Success
  976  * Else: Failure
  977  *------------------------------------------------------------------------*/
  978 static uint8_t
  979 ustorage_fs_inquiry(struct ustorage_fs_softc *sc)
  980 {
  981         uint8_t *buf = sc->sc_transfer.data_ptr;
  982 
  983         struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
  984 
  985         if (!sc->sc_transfer.currlun) {
  986                 /* Unsupported LUNs are okay */
  987                 memset(buf, 0, 36);
  988                 buf[0] = 0x7f;
  989                 /* Unsupported, no device - type */
  990                 return (ustorage_fs_min_len(sc, 36, -1U));
  991         }
  992         memset(buf, 0, 8);
  993         /* Non - removable, direct - access device */
  994         if (currlun->removable)
  995                 buf[1] = 0x80;
  996         buf[2] = 2;
  997         /* ANSI SCSI level 2 */
  998         buf[3] = 2;
  999         /* SCSI - 2 INQUIRY data format */
 1000         buf[4] = 31;
 1001         /* Additional length */
 1002         /* No special options */
 1003         /* Copy in ID string */
 1004         memcpy(buf + 8, USTORAGE_FS_ID_STRING, 28);
 1005 
 1006 #if (USTORAGE_QDATA_MAX < 36)
 1007 #error "(USTORAGE_QDATA_MAX < 36)"
 1008 #endif
 1009         return (ustorage_fs_min_len(sc, 36, -1U));
 1010 }
 1011 
 1012 /*------------------------------------------------------------------------*
 1013  *      ustorage_fs_request_sense
 1014  *
 1015  * Returns:
 1016  *    0: Success
 1017  * Else: Failure
 1018  *------------------------------------------------------------------------*/
 1019 static uint8_t
 1020 ustorage_fs_request_sense(struct ustorage_fs_softc *sc)
 1021 {
 1022         uint8_t *buf = sc->sc_transfer.data_ptr;
 1023         struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
 1024         uint32_t sd;
 1025         uint32_t sdinfo;
 1026         uint8_t valid;
 1027 
 1028         /*
 1029          * From the SCSI-2 spec., section 7.9 (Unit attention condition):
 1030          *
 1031          * If a REQUEST SENSE command is received from an initiator
 1032          * with a pending unit attention condition (before the target
 1033          * generates the contingent allegiance condition), then the
 1034          * target shall either:
 1035          *   a) report any pending sense data and preserve the unit
 1036          *      attention condition on the logical unit, or,
 1037          *   b) report the unit attention condition, may discard any
 1038          *      pending sense data, and clear the unit attention
 1039          *      condition on the logical unit for that initiator.
 1040          *
 1041          * FSG normally uses option a); enable this code to use option b).
 1042          */
 1043 #if 0
 1044         if (currlun && currlun->unit_attention_data != SS_NO_SENSE) {
 1045                 currlun->sense_data = currlun->unit_attention_data;
 1046                 currlun->unit_attention_data = SS_NO_SENSE;
 1047         }
 1048 #endif
 1049 
 1050         if (!currlun) {
 1051                 /* Unsupported LUNs are okay */
 1052                 sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
 1053                 sdinfo = 0;
 1054                 valid = 0;
 1055         } else {
 1056                 sd = currlun->sense_data;
 1057                 sdinfo = currlun->sense_data_info;
 1058                 valid = currlun->info_valid << 7;
 1059                 currlun->sense_data = SS_NO_SENSE;
 1060                 currlun->sense_data_info = 0;
 1061                 currlun->info_valid = 0;
 1062         }
 1063 
 1064         memset(buf, 0, 18);
 1065         buf[0] = valid | 0x70;
 1066         /* Valid, current error */
 1067         buf[2] = SK(sd);
 1068         put_be32(&buf[3], sdinfo);
 1069         /* Sense information */
 1070         buf[7] = 18 - 8;
 1071         /* Additional sense length */
 1072         buf[12] = ASC(sd);
 1073         buf[13] = ASCQ(sd);
 1074 
 1075 #if (USTORAGE_QDATA_MAX < 18)
 1076 #error "(USTORAGE_QDATA_MAX < 18)"
 1077 #endif
 1078         return (ustorage_fs_min_len(sc, 18, -1U));
 1079 }
 1080 
 1081 /*------------------------------------------------------------------------*
 1082  *      ustorage_fs_read_capacity
 1083  *
 1084  * Returns:
 1085  *    0: Success
 1086  * Else: Failure
 1087  *------------------------------------------------------------------------*/
 1088 static uint8_t
 1089 ustorage_fs_read_capacity(struct ustorage_fs_softc *sc)
 1090 {
 1091         uint8_t *buf = sc->sc_transfer.data_ptr;
 1092         struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
 1093         uint32_t lba = get_be32(&sc->sc_cbw->CBWCDB[2]);
 1094         uint8_t pmi = sc->sc_cbw->CBWCDB[8];
 1095 
 1096         /* Check the PMI and LBA fields */
 1097         if ((pmi > 1) || ((pmi == 0) && (lba != 0))) {
 1098                 currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
 1099                 return (1);
 1100         }
 1101         /* Max logical block */
 1102         put_be32(&buf[0], currlun->num_sectors - 1);
 1103         /* Block length */
 1104         put_be32(&buf[4], 512);
 1105 
 1106 #if (USTORAGE_QDATA_MAX < 8)
 1107 #error "(USTORAGE_QDATA_MAX < 8)"
 1108 #endif
 1109         return (ustorage_fs_min_len(sc, 8, -1U));
 1110 }
 1111 
 1112 /*------------------------------------------------------------------------*
 1113  *      ustorage_fs_mode_sense
 1114  *
 1115  * Returns:
 1116  *    0: Success
 1117  * Else: Failure
 1118  *------------------------------------------------------------------------*/
 1119 static uint8_t
 1120 ustorage_fs_mode_sense(struct ustorage_fs_softc *sc)
 1121 {
 1122         uint8_t *buf = sc->sc_transfer.data_ptr;
 1123         struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
 1124         uint8_t *buf0;
 1125         uint16_t len;
 1126         uint16_t limit;
 1127         uint8_t mscmnd = sc->sc_cbw->CBWCDB[0];
 1128         uint8_t pc;
 1129         uint8_t page_code;
 1130         uint8_t changeable_values;
 1131         uint8_t all_pages;
 1132 
 1133         buf0 = buf;
 1134 
 1135         if ((sc->sc_cbw->CBWCDB[1] & ~0x08) != 0) {
 1136                 /* Mask away DBD */
 1137                 currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
 1138                 return (1);
 1139         }
 1140         pc = sc->sc_cbw->CBWCDB[2] >> 6;
 1141         page_code = sc->sc_cbw->CBWCDB[2] & 0x3f;
 1142         if (pc == 3) {
 1143                 currlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED;
 1144                 return (1);
 1145         }
 1146         changeable_values = (pc == 1);
 1147         all_pages = (page_code == 0x3f);
 1148 
 1149         /*
 1150          * Write the mode parameter header.  Fixed values are: default
 1151          * medium type, no cache control (DPOFUA), and no block descriptors.
 1152          * The only variable value is the WriteProtect bit.  We will fill in
 1153          * the mode data length later.
 1154          */
 1155         memset(buf, 0, 8);
 1156         if (mscmnd == SC_MODE_SENSE_6) {
 1157                 buf[2] = (currlun->read_only ? 0x80 : 0x00);
 1158                 /* WP, DPOFUA */
 1159                 buf += 4;
 1160                 limit = 255;
 1161         } else {
 1162                 /* SC_MODE_SENSE_10 */
 1163                 buf[3] = (currlun->read_only ? 0x80 : 0x00);
 1164                 /* WP, DPOFUA */
 1165                 buf += 8;
 1166                 limit = 65535;
 1167                 /* Should really be mod_data.buflen */
 1168         }
 1169 
 1170         /* No block descriptors */
 1171 
 1172         /*
 1173          * The mode pages, in numerical order.
 1174          */
 1175         if ((page_code == 0x08) || all_pages) {
 1176                 buf[0] = 0x08;
 1177                 /* Page code */
 1178                 buf[1] = 10;
 1179                 /* Page length */
 1180                 memset(buf + 2, 0, 10);
 1181                 /* None of the fields are changeable */
 1182 
 1183                 if (!changeable_values) {
 1184                         buf[2] = 0x04;
 1185                         /* Write cache enable, */
 1186                         /* Read cache not disabled */
 1187                         /* No cache retention priorities */
 1188                         put_be16(&buf[4], 0xffff);
 1189                         /* Don 't disable prefetch */
 1190                         /* Minimum prefetch = 0 */
 1191                         put_be16(&buf[8], 0xffff);
 1192                         /* Maximum prefetch */
 1193                         put_be16(&buf[10], 0xffff);
 1194                         /* Maximum prefetch ceiling */
 1195                 }
 1196                 buf += 12;
 1197         }
 1198         /*
 1199          * Check that a valid page was requested and the mode data length
 1200          * isn't too long.
 1201          */
 1202         len = buf - buf0;
 1203         if (len > limit) {
 1204                 currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
 1205                 return (1);
 1206         }
 1207         /* Store the mode data length */
 1208         if (mscmnd == SC_MODE_SENSE_6)
 1209                 buf0[0] = len - 1;
 1210         else
 1211                 put_be16(buf0, len - 2);
 1212 
 1213 #if (USTORAGE_QDATA_MAX < 24)
 1214 #error "(USTORAGE_QDATA_MAX < 24)"
 1215 #endif
 1216         return (ustorage_fs_min_len(sc, len, -1U));
 1217 }
 1218 
 1219 /*------------------------------------------------------------------------*
 1220  *      ustorage_fs_start_stop
 1221  *
 1222  * Returns:
 1223  *    0: Success
 1224  * Else: Failure
 1225  *------------------------------------------------------------------------*/
 1226 static uint8_t
 1227 ustorage_fs_start_stop(struct ustorage_fs_softc *sc)
 1228 {
 1229         struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
 1230         uint8_t loej;
 1231         uint8_t start;
 1232         uint8_t immed;
 1233 
 1234         if (!currlun->removable) {
 1235                 currlun->sense_data = SS_INVALID_COMMAND;
 1236                 return (1);
 1237         }
 1238         immed = sc->sc_cbw->CBWCDB[1] & 0x01;
 1239         loej = sc->sc_cbw->CBWCDB[4] & 0x02;
 1240         start = sc->sc_cbw->CBWCDB[4] & 0x01;
 1241 
 1242         if (immed || loej || start) {
 1243                 /* compile fix */
 1244         }
 1245         return (0);
 1246 }
 1247 
 1248 /*------------------------------------------------------------------------*
 1249  *      ustorage_fs_prevent_allow
 1250  *
 1251  * Returns:
 1252  *    0: Success
 1253  * Else: Failure
 1254  *------------------------------------------------------------------------*/
 1255 static uint8_t
 1256 ustorage_fs_prevent_allow(struct ustorage_fs_softc *sc)
 1257 {
 1258         struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
 1259         uint8_t prevent;
 1260 
 1261         if (!currlun->removable) {
 1262                 currlun->sense_data = SS_INVALID_COMMAND;
 1263                 return (1);
 1264         }
 1265         prevent = sc->sc_cbw->CBWCDB[4] & 0x01;
 1266         if ((sc->sc_cbw->CBWCDB[4] & ~0x01) != 0) {
 1267                 /* Mask away Prevent */
 1268                 currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
 1269                 return (1);
 1270         }
 1271         if (currlun->prevent_medium_removal && !prevent) {
 1272                 //fsync_sub(currlun);
 1273         }
 1274         currlun->prevent_medium_removal = prevent;
 1275         return (0);
 1276 }
 1277 
 1278 /*------------------------------------------------------------------------*
 1279  *      ustorage_fs_read_format_capacities
 1280  *
 1281  * Returns:
 1282  *    0: Success
 1283  * Else: Failure
 1284  *------------------------------------------------------------------------*/
 1285 static uint8_t
 1286 ustorage_fs_read_format_capacities(struct ustorage_fs_softc *sc)
 1287 {
 1288         uint8_t *buf = sc->sc_transfer.data_ptr;
 1289         struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
 1290 
 1291         buf[0] = buf[1] = buf[2] = 0;
 1292         buf[3] = 8;
 1293         /* Only the Current / Maximum Capacity Descriptor */
 1294         buf += 4;
 1295 
 1296         /* Number of blocks */
 1297         put_be32(&buf[0], currlun->num_sectors);
 1298         /* Block length */
 1299         put_be32(&buf[4], 512);
 1300         /* Current capacity */
 1301         buf[4] = 0x02;
 1302 
 1303 #if (USTORAGE_QDATA_MAX < 12)
 1304 #error "(USTORAGE_QDATA_MAX < 12)"
 1305 #endif
 1306         return (ustorage_fs_min_len(sc, 12, -1U));
 1307 }
 1308 
 1309 /*------------------------------------------------------------------------*
 1310  *      ustorage_fs_mode_select
 1311  *
 1312  * Return values:
 1313  *    0: Success
 1314  * Else: Failure
 1315  *------------------------------------------------------------------------*/
 1316 static uint8_t
 1317 ustorage_fs_mode_select(struct ustorage_fs_softc *sc)
 1318 {
 1319         struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
 1320 
 1321         /* We don't support MODE SELECT */
 1322         currlun->sense_data = SS_INVALID_COMMAND;
 1323         return (1);
 1324 }
 1325 
 1326 /*------------------------------------------------------------------------*
 1327  *      ustorage_fs_synchronize_cache
 1328  *
 1329  * Return values:
 1330  *    0: Success
 1331  * Else: Failure
 1332  *------------------------------------------------------------------------*/
 1333 static uint8_t
 1334 ustorage_fs_synchronize_cache(struct ustorage_fs_softc *sc)
 1335 {
 1336 #if 0
 1337         struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
 1338         uint8_t rc;
 1339 
 1340         /*
 1341          * We ignore the requested LBA and write out all dirty data buffers.
 1342          */
 1343         rc = 0;
 1344         if (rc) {
 1345                 currlun->sense_data = SS_WRITE_ERROR;
 1346         }
 1347 #endif
 1348         return (0);
 1349 }
 1350 
 1351 /*------------------------------------------------------------------------*
 1352  *      ustorage_fs_read - read data from disk
 1353  *
 1354  * Return values:
 1355  *    0: Success
 1356  * Else: Failure
 1357  *------------------------------------------------------------------------*/
 1358 static uint8_t
 1359 ustorage_fs_read(struct ustorage_fs_softc *sc)
 1360 {
 1361         struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
 1362         uint64_t file_offset;
 1363         uint32_t lba;
 1364         uint32_t len;
 1365 
 1366         /*
 1367          * Get the starting Logical Block Address and check that it's not
 1368          * too big
 1369          */
 1370         if (sc->sc_cbw->CBWCDB[0] == SC_READ_6) {
 1371                 lba = (((uint32_t)sc->sc_cbw->CBWCDB[1]) << 16) |
 1372                     get_be16(&sc->sc_cbw->CBWCDB[2]);
 1373         } else {
 1374                 lba = get_be32(&sc->sc_cbw->CBWCDB[2]);
 1375 
 1376                 /*
 1377                  * We allow DPO (Disable Page Out = don't save data in the
 1378                  * cache) and FUA (Force Unit Access = don't read from the
 1379                  * cache), but we don't implement them.
 1380                  */
 1381                 if ((sc->sc_cbw->CBWCDB[1] & ~0x18) != 0) {
 1382                         currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
 1383                         return (1);
 1384                 }
 1385         }
 1386         len = sc->sc_transfer.data_rem >> 9;
 1387         len += lba;
 1388 
 1389         if ((len < lba) ||
 1390             (len > currlun->num_sectors) ||
 1391             (lba >= currlun->num_sectors)) {
 1392                 currlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
 1393                 return (1);
 1394         }
 1395         file_offset = lba;
 1396         file_offset <<= 9;
 1397 
 1398         sc->sc_transfer.data_ptr = currlun->memory_image + file_offset;
 1399 
 1400         return (0);
 1401 }
 1402 
 1403 /*------------------------------------------------------------------------*
 1404  *      ustorage_fs_write - write data to disk
 1405  *
 1406  * Return values:
 1407  *    0: Success
 1408  * Else: Failure
 1409  *------------------------------------------------------------------------*/
 1410 static uint8_t
 1411 ustorage_fs_write(struct ustorage_fs_softc *sc)
 1412 {
 1413         struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun;
 1414         uint64_t file_offset;
 1415         uint32_t lba;
 1416         uint32_t len;
 1417 
 1418         if (currlun->read_only) {
 1419                 currlun->sense_data = SS_WRITE_PROTECTED;
 1420                 return (1);
 1421         }
 1422         /* XXX clear SYNC */
 1423 
 1424         /*
 1425          * Get the starting Logical Block Address and check that it's not
 1426          * too big.
 1427          */
 1428         if (sc->sc_cbw->CBWCDB[0] == SC_WRITE_6)
 1429                 lba = (((uint32_t)sc->sc_cbw->CBWCDB[1]) << 16) |
 1430                     get_be16(&sc->sc_cbw->CBWCDB[2]);
 1431         else {
 1432                 lba = get_be32(&sc->sc_cbw->CBWCDB[2]);
 1433 
 1434                 /*
 1435                  * We allow DPO (Disable Page Out = don't save data in the
 1436                  * cache) and FUA (Force Unit Access = write directly to the
 1437                  * medium).  We don't implement DPO; we implement FUA by
 1438                  * performing synchronous output.
 1439                  */
 1440                 if ((sc->sc_cbw->CBWCDB[1] & ~0x18) != 0) {
 1441                         currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
 1442                         return (1);
 1443                 }
 1444                 if (sc->sc_cbw->CBWCDB[1] & 0x08) {
 1445                         /* FUA */
 1446                         /* XXX set SYNC flag here */
 1447                 }
 1448         }
 1449 
 1450         len = sc->sc_transfer.data_rem >> 9;
 1451         len += lba;
 1452 
 1453         if ((len < lba) ||
 1454             (len > currlun->num_sectors) ||
 1455             (lba >= currlun->num_sectors)) {
 1456                 currlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
 1457                 return (1);
 1458         }
 1459         file_offset = lba;
 1460         file_offset <<= 9;
 1461 
 1462         sc->sc_transfer.data_ptr = currlun->memory_image + file_offset;
 1463 
 1464         return (0);
 1465 }
 1466 
 1467 /*------------------------------------------------------------------------*
 1468  *      ustorage_fs_min_len
 1469  *
 1470  * Return values:
 1471  *    0: Success
 1472  * Else: Failure
 1473  *------------------------------------------------------------------------*/
 1474 static uint8_t
 1475 ustorage_fs_min_len(struct ustorage_fs_softc *sc, uint32_t len, uint32_t mask)
 1476 {
 1477         if (len != sc->sc_transfer.data_rem) {
 1478                 if (sc->sc_transfer.cbw_dir == DIR_READ) {
 1479                         /*
 1480                          * there must be something wrong about this SCSI
 1481                          * command
 1482                          */
 1483                         sc->sc_csw->bCSWStatus = CSWSTATUS_PHASE;
 1484                         return (1);
 1485                 }
 1486                 /* compute the minimum length */
 1487 
 1488                 if (sc->sc_transfer.data_rem > len) {
 1489                         /* data ends prematurely */
 1490                         sc->sc_transfer.data_rem = len;
 1491                         sc->sc_transfer.data_short = 1;
 1492                 }
 1493                 /* check length alignment */
 1494 
 1495                 if (sc->sc_transfer.data_rem & ~mask) {
 1496                         /* data ends prematurely */
 1497                         sc->sc_transfer.data_rem &= mask;
 1498                         sc->sc_transfer.data_short = 1;
 1499                 }
 1500         }
 1501         return (0);
 1502 }
 1503 
 1504 /*------------------------------------------------------------------------*
 1505  *      ustorage_fs_check_cmd - check command routine
 1506  *
 1507  * Check whether the command is properly formed and whether its data
 1508  * size and direction agree with the values we already have.
 1509  *
 1510  * Return values:
 1511  *    0: Success
 1512  * Else: Failure
 1513  *------------------------------------------------------------------------*/
 1514 static uint8_t
 1515 ustorage_fs_check_cmd(struct ustorage_fs_softc *sc, uint8_t min_cmd_size,
 1516     uint16_t mask, uint8_t needs_medium)
 1517 {
 1518         struct ustorage_fs_lun *currlun;
 1519         uint8_t lun = (sc->sc_cbw->CBWCDB[1] >> 5);
 1520         uint8_t i;
 1521 
 1522         /* Verify the length of the command itself */
 1523         if (min_cmd_size > sc->sc_transfer.cmd_len) {
 1524                 DPRINTF("%u > %u\n",
 1525                     min_cmd_size, sc->sc_transfer.cmd_len);
 1526                 sc->sc_csw->bCSWStatus = CSWSTATUS_PHASE;
 1527                 return (1);
 1528         }
 1529         /* Mask away the LUN */
 1530         sc->sc_cbw->CBWCDB[1] &= 0x1f;
 1531 
 1532         /* Check if LUN is correct */
 1533         if (lun != sc->sc_transfer.lun) {
 1534         }
 1535         /* Check the LUN */
 1536         if (sc->sc_transfer.lun <= sc->sc_last_lun) {
 1537                 sc->sc_transfer.currlun = currlun =
 1538                     sc->sc_lun + sc->sc_transfer.lun;
 1539                 if (sc->sc_cbw->CBWCDB[0] != SC_REQUEST_SENSE) {
 1540                         currlun->sense_data = SS_NO_SENSE;
 1541                         currlun->sense_data_info = 0;
 1542                         currlun->info_valid = 0;
 1543                 }
 1544                 /*
 1545                  * If a unit attention condition exists, only INQUIRY
 1546                  * and REQUEST SENSE commands are allowed. Anything
 1547                  * else must fail!
 1548                  */
 1549                 if ((currlun->unit_attention_data != SS_NO_SENSE) &&
 1550                     (sc->sc_cbw->CBWCDB[0] != SC_INQUIRY) &&
 1551                     (sc->sc_cbw->CBWCDB[0] != SC_REQUEST_SENSE)) {
 1552                         currlun->sense_data = currlun->unit_attention_data;
 1553                         currlun->unit_attention_data = SS_NO_SENSE;
 1554                         return (1);
 1555                 }
 1556         } else {
 1557                 sc->sc_transfer.currlun = currlun = NULL;
 1558 
 1559                 /*
 1560                  * INQUIRY and REQUEST SENSE commands are explicitly allowed
 1561                  * to use unsupported LUNs; all others may not.
 1562                  */
 1563                 if ((sc->sc_cbw->CBWCDB[0] != SC_INQUIRY) &&
 1564                     (sc->sc_cbw->CBWCDB[0] != SC_REQUEST_SENSE)) {
 1565                         return (1);
 1566                 }
 1567         }
 1568 
 1569         /*
 1570          * Check that only command bytes listed in the mask are
 1571          * non-zero.
 1572          */
 1573         for (i = 0; i != min_cmd_size; i++) {
 1574                 if (sc->sc_cbw->CBWCDB[i] && !(mask & (1UL << i))) {
 1575                         if (currlun) {
 1576                                 currlun->sense_data = SS_INVALID_FIELD_IN_CDB;
 1577                         }
 1578                         return (1);
 1579                 }
 1580         }
 1581 
 1582         /*
 1583          * If the medium isn't mounted and the command needs to access
 1584          * it, return an error.
 1585          */
 1586         if (currlun && (!currlun->memory_image) && needs_medium) {
 1587                 currlun->sense_data = SS_MEDIUM_NOT_PRESENT;
 1588                 return (1);
 1589         }
 1590         return (0);
 1591 }
 1592 
 1593 /*------------------------------------------------------------------------*
 1594  *      ustorage_fs_do_cmd - do command
 1595  *
 1596  * Return values:
 1597  *    0: Success
 1598  * Else: Failure
 1599  *------------------------------------------------------------------------*/
 1600 static uint8_t
 1601 ustorage_fs_do_cmd(struct ustorage_fs_softc *sc)
 1602 {
 1603         uint8_t error = 1;
 1604         uint8_t i;
 1605         uint32_t temp;
 1606         const uint32_t mask9 = (0xFFFFFFFFUL >> 9) << 9;
 1607 
 1608         /* set default data transfer pointer */
 1609         sc->sc_transfer.data_ptr = sc->sc_qdata;
 1610 
 1611         DPRINTF("cmd_data[0]=0x%02x, data_rem=0x%08x\n",
 1612             sc->sc_cbw->CBWCDB[0], sc->sc_transfer.data_rem);
 1613 
 1614         switch (sc->sc_cbw->CBWCDB[0]) {
 1615         case SC_INQUIRY:
 1616                 sc->sc_transfer.cmd_dir = DIR_WRITE;
 1617                 error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U);
 1618                 if (error) {
 1619                         break;
 1620                 }
 1621                 error = ustorage_fs_check_cmd(sc, 6,
 1622                     (1UL << 4) | 1, 0);
 1623                 if (error) {
 1624                         break;
 1625                 }
 1626                 error = ustorage_fs_inquiry(sc);
 1627 
 1628                 break;
 1629 
 1630         case SC_MODE_SELECT_6:
 1631                 sc->sc_transfer.cmd_dir = DIR_READ;
 1632                 error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U);
 1633                 if (error) {
 1634                         break;
 1635                 }
 1636                 error = ustorage_fs_check_cmd(sc, 6,
 1637                     (1UL << 1) | (1UL << 4) | 1, 0);
 1638                 if (error) {
 1639                         break;
 1640                 }
 1641                 error = ustorage_fs_mode_select(sc);
 1642 
 1643                 break;
 1644 
 1645         case SC_MODE_SELECT_10:
 1646                 sc->sc_transfer.cmd_dir = DIR_READ;
 1647                 error = ustorage_fs_min_len(sc,
 1648                     get_be16(&sc->sc_cbw->CBWCDB[7]), -1U);
 1649                 if (error) {
 1650                         break;
 1651                 }
 1652                 error = ustorage_fs_check_cmd(sc, 10,
 1653                     (1UL << 1) | (3UL << 7) | 1, 0);
 1654                 if (error) {
 1655                         break;
 1656                 }
 1657                 error = ustorage_fs_mode_select(sc);
 1658 
 1659                 break;
 1660 
 1661         case SC_MODE_SENSE_6:
 1662                 sc->sc_transfer.cmd_dir = DIR_WRITE;
 1663                 error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U);
 1664                 if (error) {
 1665                         break;
 1666                 }
 1667                 error = ustorage_fs_check_cmd(sc, 6,
 1668                     (1UL << 1) | (1UL << 2) | (1UL << 4) | 1, 0);
 1669                 if (error) {
 1670                         break;
 1671                 }
 1672                 error = ustorage_fs_mode_sense(sc);
 1673 
 1674                 break;
 1675 
 1676         case SC_MODE_SENSE_10:
 1677                 sc->sc_transfer.cmd_dir = DIR_WRITE;
 1678                 error = ustorage_fs_min_len(sc,
 1679                     get_be16(&sc->sc_cbw->CBWCDB[7]), -1U);
 1680                 if (error) {
 1681                         break;
 1682                 }
 1683                 error = ustorage_fs_check_cmd(sc, 10,
 1684                     (1UL << 1) | (1UL << 2) | (3UL << 7) | 1, 0);
 1685                 if (error) {
 1686                         break;
 1687                 }
 1688                 error = ustorage_fs_mode_sense(sc);
 1689 
 1690                 break;
 1691 
 1692         case SC_PREVENT_ALLOW_MEDIUM_REMOVAL:
 1693                 error = ustorage_fs_min_len(sc, 0, -1U);
 1694                 if (error) {
 1695                         break;
 1696                 }
 1697                 error = ustorage_fs_check_cmd(sc, 6,
 1698                     (1UL << 4) | 1, 0);
 1699                 if (error) {
 1700                         break;
 1701                 }
 1702                 error = ustorage_fs_prevent_allow(sc);
 1703 
 1704                 break;
 1705 
 1706         case SC_READ_6:
 1707                 i = sc->sc_cbw->CBWCDB[4];
 1708                 sc->sc_transfer.cmd_dir = DIR_WRITE;
 1709                 temp = ((i == 0) ? 256UL : i);
 1710                 error = ustorage_fs_min_len(sc, temp << 9, mask9);
 1711                 if (error) {
 1712                         break;
 1713                 }
 1714                 error = ustorage_fs_check_cmd(sc, 6,
 1715                     (7UL << 1) | (1UL << 4) | 1, 1);
 1716                 if (error) {
 1717                         break;
 1718                 }
 1719                 error = ustorage_fs_read(sc);
 1720 
 1721                 break;
 1722 
 1723         case SC_READ_10:
 1724                 sc->sc_transfer.cmd_dir = DIR_WRITE;
 1725                 temp = get_be16(&sc->sc_cbw->CBWCDB[7]);
 1726                 error = ustorage_fs_min_len(sc, temp << 9, mask9);
 1727                 if (error) {
 1728                         break;
 1729                 }
 1730                 error = ustorage_fs_check_cmd(sc, 10,
 1731                     (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1);
 1732                 if (error) {
 1733                         break;
 1734                 }
 1735                 error = ustorage_fs_read(sc);
 1736 
 1737                 break;
 1738 
 1739         case SC_READ_12:
 1740                 sc->sc_transfer.cmd_dir = DIR_WRITE;
 1741                 temp = get_be32(&sc->sc_cbw->CBWCDB[6]);
 1742                 if (temp >= (1UL << (32 - 9))) {
 1743                         /* numerical overflow */
 1744                         sc->sc_csw->bCSWStatus = CSWSTATUS_FAILED;
 1745                         error = 1;
 1746                         break;
 1747                 }
 1748                 error = ustorage_fs_min_len(sc, temp << 9, mask9);
 1749                 if (error) {
 1750                         break;
 1751                 }
 1752                 error = ustorage_fs_check_cmd(sc, 12,
 1753                     (1UL << 1) | (0xfUL << 2) | (0xfUL << 6) | 1, 1);
 1754                 if (error) {
 1755                         break;
 1756                 }
 1757                 error = ustorage_fs_read(sc);
 1758 
 1759                 break;
 1760 
 1761         case SC_READ_CAPACITY:
 1762                 sc->sc_transfer.cmd_dir = DIR_WRITE;
 1763                 error = ustorage_fs_check_cmd(sc, 10,
 1764                     (0xfUL << 2) | (1UL << 8) | 1, 1);
 1765                 if (error) {
 1766                         break;
 1767                 }
 1768                 error = ustorage_fs_read_capacity(sc);
 1769 
 1770                 break;
 1771 
 1772         case SC_READ_FORMAT_CAPACITIES:
 1773                 sc->sc_transfer.cmd_dir = DIR_WRITE;
 1774                 error = ustorage_fs_min_len(sc,
 1775                     get_be16(&sc->sc_cbw->CBWCDB[7]), -1U);
 1776                 if (error) {
 1777                         break;
 1778                 }
 1779                 error = ustorage_fs_check_cmd(sc, 10,
 1780                     (3UL << 7) | 1, 1);
 1781                 if (error) {
 1782                         break;
 1783                 }
 1784                 error = ustorage_fs_read_format_capacities(sc);
 1785 
 1786                 break;
 1787 
 1788         case SC_REQUEST_SENSE:
 1789                 sc->sc_transfer.cmd_dir = DIR_WRITE;
 1790                 error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U);
 1791                 if (error) {
 1792                         break;
 1793                 }
 1794                 error = ustorage_fs_check_cmd(sc, 6,
 1795                     (1UL << 4) | 1, 0);
 1796                 if (error) {
 1797                         break;
 1798                 }
 1799                 error = ustorage_fs_request_sense(sc);
 1800 
 1801                 break;
 1802 
 1803         case SC_START_STOP_UNIT:
 1804                 error = ustorage_fs_min_len(sc, 0, -1U);
 1805                 if (error) {
 1806                         break;
 1807                 }
 1808                 error = ustorage_fs_check_cmd(sc, 6,
 1809                     (1UL << 1) | (1UL << 4) | 1, 0);
 1810                 if (error) {
 1811                         break;
 1812                 }
 1813                 error = ustorage_fs_start_stop(sc);
 1814 
 1815                 break;
 1816 
 1817         case SC_SYNCHRONIZE_CACHE:
 1818                 error = ustorage_fs_min_len(sc, 0, -1U);
 1819                 if (error) {
 1820                         break;
 1821                 }
 1822                 error = ustorage_fs_check_cmd(sc, 10,
 1823                     (0xfUL << 2) | (3UL << 7) | 1, 1);
 1824                 if (error) {
 1825                         break;
 1826                 }
 1827                 error = ustorage_fs_synchronize_cache(sc);
 1828 
 1829                 break;
 1830 
 1831         case SC_TEST_UNIT_READY:
 1832                 error = ustorage_fs_min_len(sc, 0, -1U);
 1833                 if (error) {
 1834                         break;
 1835                 }
 1836                 error = ustorage_fs_check_cmd(sc, 6,
 1837                     0 | 1, 1);
 1838                 break;
 1839 
 1840                 /*
 1841                  * Although optional, this command is used by MS-Windows.
 1842                  * We support a minimal version: BytChk must be 0.
 1843                  */
 1844         case SC_VERIFY:
 1845                 error = ustorage_fs_min_len(sc, 0, -1U);
 1846                 if (error) {
 1847                         break;
 1848                 }
 1849                 error = ustorage_fs_check_cmd(sc, 10,
 1850                     (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1);
 1851                 if (error) {
 1852                         break;
 1853                 }
 1854                 error = ustorage_fs_verify(sc);
 1855 
 1856                 break;
 1857 
 1858         case SC_WRITE_6:
 1859                 i = sc->sc_cbw->CBWCDB[4];
 1860                 sc->sc_transfer.cmd_dir = DIR_READ;
 1861                 temp = ((i == 0) ? 256UL : i);
 1862                 error = ustorage_fs_min_len(sc, temp << 9, mask9);
 1863                 if (error) {
 1864                         break;
 1865                 }
 1866                 error = ustorage_fs_check_cmd(sc, 6,
 1867                     (7UL << 1) | (1UL << 4) | 1, 1);
 1868                 if (error) {
 1869                         break;
 1870                 }
 1871                 error = ustorage_fs_write(sc);
 1872 
 1873                 break;
 1874 
 1875         case SC_WRITE_10:
 1876                 sc->sc_transfer.cmd_dir = DIR_READ;
 1877                 temp = get_be16(&sc->sc_cbw->CBWCDB[7]);
 1878                 error = ustorage_fs_min_len(sc, temp << 9, mask9);
 1879                 if (error) {
 1880                         break;
 1881                 }
 1882                 error = ustorage_fs_check_cmd(sc, 10,
 1883                     (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1);
 1884                 if (error) {
 1885                         break;
 1886                 }
 1887                 error = ustorage_fs_write(sc);
 1888 
 1889                 break;
 1890 
 1891         case SC_WRITE_12:
 1892                 sc->sc_transfer.cmd_dir = DIR_READ;
 1893                 temp = get_be32(&sc->sc_cbw->CBWCDB[6]);
 1894                 if (temp > (mask9 >> 9)) {
 1895                         /* numerical overflow */
 1896                         sc->sc_csw->bCSWStatus = CSWSTATUS_FAILED;
 1897                         error = 1;
 1898                         break;
 1899                 }
 1900                 error = ustorage_fs_min_len(sc, temp << 9, mask9);
 1901                 if (error) {
 1902                         break;
 1903                 }
 1904                 error = ustorage_fs_check_cmd(sc, 12,
 1905                     (1UL << 1) | (0xfUL << 2) | (0xfUL << 6) | 1, 1);
 1906                 if (error) {
 1907                         break;
 1908                 }
 1909                 error = ustorage_fs_write(sc);
 1910 
 1911                 break;
 1912 
 1913                 /*
 1914                  * Some mandatory commands that we recognize but don't
 1915                  * implement.  They don't mean much in this setting.
 1916                  * It's left as an exercise for anyone interested to
 1917                  * implement RESERVE and RELEASE in terms of Posix
 1918                  * locks.
 1919                  */
 1920         case SC_FORMAT_UNIT:
 1921         case SC_RELEASE:
 1922         case SC_RESERVE:
 1923         case SC_SEND_DIAGNOSTIC:
 1924                 /* Fallthrough */
 1925 
 1926         default:
 1927                 error = ustorage_fs_min_len(sc, 0, -1U);
 1928                 if (error) {
 1929                         break;
 1930                 }
 1931                 error = ustorage_fs_check_cmd(sc, sc->sc_transfer.cmd_len,
 1932                     0xff, 0);
 1933                 if (error) {
 1934                         break;
 1935                 }
 1936                 sc->sc_transfer.currlun->sense_data =
 1937                     SS_INVALID_COMMAND;
 1938                 error = 1;
 1939 
 1940                 break;
 1941         }
 1942         return (error);
 1943 }

Cache object: 76b75974620309b921f3878bd4e66bf9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.