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