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