ustorage_fs.c revision 244503
1217806Slstewart/* $FreeBSD: head/sys/dev/usb/storage/ustorage_fs.c 244503 2012-12-20 18:38:02Z hselasky $ */ 2217806Slstewart/*- 3217806Slstewart * Copyright (C) 2003-2005 Alan Stern 4217806Slstewart * Copyright (C) 2008 Hans Petter Selasky 5217806Slstewart * All rights reserved. 6217806Slstewart * 7217806Slstewart * Redistribution and use in source and binary forms, with or without 8217806Slstewart * modification, are permitted provided that the following conditions 9220560Slstewart * are met: 10220560Slstewart * 1. Redistributions of source code must retain the above copyright 11220560Slstewart * notice, this list of conditions, and the following disclaimer, 12217806Slstewart * without modification. 13217806Slstewart * 2. Redistributions in binary form must reproduce the above copyright 14217806Slstewart * notice, this list of conditions and the following disclaimer in the 15217806Slstewart * documentation and/or other materials provided with the distribution. 16217806Slstewart * 3. The names of the above-listed copyright holders may not be used 17217806Slstewart * to endorse or promote products derived from this software without 18217806Slstewart * specific prior written permission. 19217806Slstewart * 20217806Slstewart * 21217806Slstewart * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22217806Slstewart * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23217806Slstewart * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24217806Slstewart * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 25217806Slstewart * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26217806Slstewart * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27217806Slstewart * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28217806Slstewart * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29217806Slstewart * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30217806Slstewart * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31217806Slstewart * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32217806Slstewart */ 33217806Slstewart 34217806Slstewart/* 35217806Slstewart * NOTE: Much of the SCSI statemachine handling code derives from the 36217806Slstewart * Linux USB gadget stack. 37217806Slstewart */ 38217806Slstewart 39217806Slstewart#include <sys/stdint.h> 40217806Slstewart#include <sys/stddef.h> 41217806Slstewart#include <sys/param.h> 42217806Slstewart#include <sys/queue.h> 43217806Slstewart#include <sys/types.h> 44217806Slstewart#include <sys/systm.h> 45217806Slstewart#include <sys/kernel.h> 46217806Slstewart#include <sys/bus.h> 47217806Slstewart#include <sys/module.h> 48217806Slstewart#include <sys/lock.h> 49217806Slstewart#include <sys/mutex.h> 50217806Slstewart#include <sys/condvar.h> 51217806Slstewart#include <sys/sysctl.h> 52217806Slstewart#include <sys/sx.h> 53217806Slstewart#include <sys/unistd.h> 54217806Slstewart#include <sys/callout.h> 55217806Slstewart#include <sys/malloc.h> 56217806Slstewart#include <sys/priv.h> 57217806Slstewart 58217806Slstewart#include <dev/usb/usb.h> 59217806Slstewart#include <dev/usb/usbdi.h> 60217806Slstewart#include "usbdevs.h" 61217806Slstewart#include "usb_if.h" 62217806Slstewart 63217806Slstewart#define USB_DEBUG_VAR ustorage_fs_debug 64217806Slstewart#include <dev/usb/usb_debug.h> 65217806Slstewart 66217806Slstewart#ifdef USB_DEBUG 67217806Slstewartstatic int ustorage_fs_debug = 0; 68217806Slstewart 69217806SlstewartSYSCTL_NODE(_hw_usb, OID_AUTO, ustorage_fs, CTLFLAG_RW, 0, "USB ustorage_fs"); 70217806SlstewartSYSCTL_INT(_hw_usb_ustorage_fs, OID_AUTO, debug, CTLFLAG_RW, 71217806Slstewart &ustorage_fs_debug, 0, "ustorage_fs debug level"); 72217806Slstewart#endif 73217806Slstewart 74217806Slstewart/* Define some limits */ 75217806Slstewart 76217806Slstewart#ifndef USTORAGE_FS_BULK_SIZE 77217806Slstewart#define USTORAGE_FS_BULK_SIZE (1U << 17) /* bytes */ 78217806Slstewart#endif 79217806Slstewart 80217806Slstewart#ifndef USTORAGE_FS_MAX_LUN 81217806Slstewart#define USTORAGE_FS_MAX_LUN 8 /* units */ 82217806Slstewart#endif 83217806Slstewart 84217806Slstewart#ifndef USTORAGE_QDATA_MAX 85217806Slstewart#define USTORAGE_QDATA_MAX 40 /* bytes */ 86217806Slstewart#endif 87217806Slstewart 88217806Slstewart/* 89217806Slstewart * The SCSI ID string must be exactly 28 characters long 90217806Slstewart * exluding the terminating zero. 91217806Slstewart */ 92217806Slstewart#ifndef USTORAGE_FS_ID_STRING 93217806Slstewart#define USTORAGE_FS_ID_STRING \ 94217806Slstewart "FreeBSD " /* 8 */ \ 95217806Slstewart "File-Stor Gadget" /* 16 */ \ 96217806Slstewart "0101" /* 4 */ 97217806Slstewart#endif 98217806Slstewart 99217806Slstewart/* 100217806Slstewart * The following macro defines the number of 101217806Slstewart * sectors to be allocated for the RAM disk: 102217806Slstewart */ 103217806Slstewart#ifndef USTORAGE_FS_RAM_SECT 104217806Slstewart#define USTORAGE_FS_RAM_SECT (1UL << 13) 105217806Slstewart#endif 106217806Slstewart 107217806Slstewartstatic uint8_t *ustorage_fs_ramdisk; 108217806Slstewart 109217806Slstewart/* USB transfer definitions */ 110217806Slstewart 111217806Slstewart#define USTORAGE_FS_T_BBB_COMMAND 0 112217806Slstewart#define USTORAGE_FS_T_BBB_DATA_DUMP 1 113217806Slstewart#define USTORAGE_FS_T_BBB_DATA_READ 2 114217806Slstewart#define USTORAGE_FS_T_BBB_DATA_WRITE 3 115217806Slstewart#define USTORAGE_FS_T_BBB_STATUS 4 116217806Slstewart#define USTORAGE_FS_T_BBB_MAX 5 117217806Slstewart 118217806Slstewart/* USB data stage direction */ 119217806Slstewart 120217806Slstewart#define DIR_NONE 0 121217806Slstewart#define DIR_READ 1 122217806Slstewart#define DIR_WRITE 2 123217806Slstewart 124217806Slstewart/* USB interface specific control request */ 125217806Slstewart 126217806Slstewart#define UR_BBB_RESET 0xff /* Bulk-Only reset */ 127217806Slstewart#define UR_BBB_GET_MAX_LUN 0xfe /* Get maximum lun */ 128217806Slstewart 129217806Slstewart/* Command Block Wrapper */ 130217806Slstewarttypedef struct { 131217806Slstewart uDWord dCBWSignature; 132217806Slstewart#define CBWSIGNATURE 0x43425355 133217806Slstewart uDWord dCBWTag; 134217806Slstewart uDWord dCBWDataTransferLength; 135217806Slstewart uByte bCBWFlags; 136217806Slstewart#define CBWFLAGS_OUT 0x00 137217806Slstewart#define CBWFLAGS_IN 0x80 138217806Slstewart uByte bCBWLUN; 139217806Slstewart uByte bCDBLength; 140217806Slstewart#define CBWCDBLENGTH 16 141217806Slstewart uByte CBWCDB[CBWCDBLENGTH]; 142217806Slstewart} __packed ustorage_fs_bbb_cbw_t; 143217806Slstewart 144217806Slstewart#define USTORAGE_FS_BBB_CBW_SIZE 31 145217806Slstewart 146217806Slstewart/* Command Status Wrapper */ 147217806Slstewarttypedef struct { 148217806Slstewart uDWord dCSWSignature; 149217806Slstewart#define CSWSIGNATURE 0x53425355 150217806Slstewart uDWord dCSWTag; 151217806Slstewart uDWord dCSWDataResidue; 152217806Slstewart uByte bCSWStatus; 153217806Slstewart#define CSWSTATUS_GOOD 0x0 154239346Slstewart#define CSWSTATUS_FAILED 0x1 155239346Slstewart#define CSWSTATUS_PHASE 0x2 156217806Slstewart} __packed ustorage_fs_bbb_csw_t; 157217806Slstewart 158217806Slstewart#define USTORAGE_FS_BBB_CSW_SIZE 13 159239346Slstewart 160239346Slstewartstruct ustorage_fs_lun { 161217806Slstewart 162217806Slstewart uint8_t *memory_image; 163217806Slstewart 164217806Slstewart uint32_t num_sectors; 165217806Slstewart uint32_t sense_data; 166217806Slstewart uint32_t sense_data_info; 167217806Slstewart uint32_t unit_attention_data; 168217806Slstewart 169217806Slstewart uint8_t read_only:1; 170217806Slstewart uint8_t prevent_medium_removal:1; 171217806Slstewart uint8_t info_valid:1; 172217806Slstewart uint8_t removable:1; 173217806Slstewart}; 174217806Slstewart 175217806Slstewartstruct ustorage_fs_softc { 176217806Slstewart 177217806Slstewart ustorage_fs_bbb_cbw_t *sc_cbw; /* Command Wrapper Block */ 178217806Slstewart ustorage_fs_bbb_csw_t *sc_csw; /* Command Status Block */ 179217806Slstewart void *sc_dma_ptr; /* Main data buffer */ 180217806Slstewart 181217806Slstewart struct mtx sc_mtx; 182217806Slstewart 183217806Slstewart struct ustorage_fs_lun sc_lun[USTORAGE_FS_MAX_LUN]; 184217806Slstewart 185217806Slstewart struct { 186217806Slstewart uint8_t *data_ptr; 187217806Slstewart struct ustorage_fs_lun *currlun; 188217806Slstewart 189217806Slstewart uint32_t data_rem; /* bytes, as reported by the command 190217806Slstewart * block wrapper */ 191217806Slstewart uint32_t offset; /* bytes */ 192217806Slstewart 193217806Slstewart uint8_t cbw_dir; 194217806Slstewart uint8_t cmd_dir; 195217806Slstewart uint8_t lun; 196217806Slstewart uint8_t cmd_len; 197217806Slstewart uint8_t data_short:1; 198217806Slstewart uint8_t data_error:1; 199217806Slstewart } sc_transfer; 200217806Slstewart 201217806Slstewart device_t sc_dev; 202217806Slstewart struct usb_device *sc_udev; 203217806Slstewart struct usb_xfer *sc_xfer[USTORAGE_FS_T_BBB_MAX]; 204217806Slstewart 205217806Slstewart uint8_t sc_iface_no; /* interface number */ 206217806Slstewart uint8_t sc_last_lun; 207217806Slstewart uint8_t sc_last_xfer_index; 208217806Slstewart uint8_t sc_qdata[USTORAGE_QDATA_MAX]; 209217806Slstewart}; 210217806Slstewart 211217806Slstewart/* prototypes */ 212217806Slstewart 213217806Slstewartstatic device_probe_t ustorage_fs_probe; 214217806Slstewartstatic device_attach_t ustorage_fs_attach; 215217806Slstewartstatic device_detach_t ustorage_fs_detach; 216217806Slstewartstatic device_suspend_t ustorage_fs_suspend; 217217806Slstewartstatic device_resume_t ustorage_fs_resume; 218217806Slstewartstatic usb_handle_request_t ustorage_fs_handle_request; 219217806Slstewart 220217806Slstewartstatic usb_callback_t ustorage_fs_t_bbb_command_callback; 221217806Slstewartstatic usb_callback_t ustorage_fs_t_bbb_data_dump_callback; 222217806Slstewartstatic usb_callback_t ustorage_fs_t_bbb_data_read_callback; 223217806Slstewartstatic usb_callback_t ustorage_fs_t_bbb_data_write_callback; 224217806Slstewartstatic usb_callback_t ustorage_fs_t_bbb_status_callback; 225217806Slstewart 226217806Slstewartstatic void ustorage_fs_transfer_start(struct ustorage_fs_softc *sc, uint8_t xfer_index); 227217806Slstewartstatic void ustorage_fs_transfer_stop(struct ustorage_fs_softc *sc); 228217806Slstewart 229217806Slstewartstatic uint8_t ustorage_fs_verify(struct ustorage_fs_softc *sc); 230217806Slstewartstatic uint8_t ustorage_fs_inquiry(struct ustorage_fs_softc *sc); 231217806Slstewartstatic uint8_t ustorage_fs_request_sense(struct ustorage_fs_softc *sc); 232217806Slstewartstatic uint8_t ustorage_fs_read_capacity(struct ustorage_fs_softc *sc); 233217806Slstewartstatic uint8_t ustorage_fs_mode_sense(struct ustorage_fs_softc *sc); 234217806Slstewartstatic uint8_t ustorage_fs_start_stop(struct ustorage_fs_softc *sc); 235217806Slstewartstatic uint8_t ustorage_fs_prevent_allow(struct ustorage_fs_softc *sc); 236217806Slstewartstatic uint8_t ustorage_fs_read_format_capacities(struct ustorage_fs_softc *sc); 237217806Slstewartstatic uint8_t ustorage_fs_mode_select(struct ustorage_fs_softc *sc); 238217806Slstewartstatic uint8_t ustorage_fs_min_len(struct ustorage_fs_softc *sc, uint32_t len, uint32_t mask); 239217806Slstewartstatic uint8_t ustorage_fs_read(struct ustorage_fs_softc *sc); 240217806Slstewartstatic uint8_t ustorage_fs_write(struct ustorage_fs_softc *sc); 241217806Slstewartstatic uint8_t ustorage_fs_check_cmd(struct ustorage_fs_softc *sc, uint8_t cmd_size, uint16_t mask, uint8_t needs_medium); 242217806Slstewartstatic uint8_t ustorage_fs_do_cmd(struct ustorage_fs_softc *sc); 243217806Slstewart 244217806Slstewartstatic device_method_t ustorage_fs_methods[] = { 245217806Slstewart /* USB interface */ 246217806Slstewart DEVMETHOD(usb_handle_request, ustorage_fs_handle_request), 247217806Slstewart 248217806Slstewart /* Device interface */ 249217806Slstewart DEVMETHOD(device_probe, ustorage_fs_probe), 250217806Slstewart DEVMETHOD(device_attach, ustorage_fs_attach), 251217806Slstewart DEVMETHOD(device_detach, ustorage_fs_detach), 252217806Slstewart DEVMETHOD(device_suspend, ustorage_fs_suspend), 253217806Slstewart DEVMETHOD(device_resume, ustorage_fs_resume), 254217806Slstewart 255217806Slstewart {0, 0} 256217806Slstewart}; 257217806Slstewart 258217806Slstewartstatic driver_t ustorage_fs_driver = { 259217806Slstewart .name = "ustorage_fs", 260217806Slstewart .methods = ustorage_fs_methods, 261217806Slstewart .size = sizeof(struct ustorage_fs_softc), 262217806Slstewart}; 263217806Slstewart 264217806Slstewartstatic devclass_t ustorage_fs_devclass; 265217806Slstewart 266217806SlstewartDRIVER_MODULE(ustorage_fs, uhub, ustorage_fs_driver, ustorage_fs_devclass, NULL, 0); 267217806SlstewartMODULE_VERSION(ustorage_fs, 0); 268217806SlstewartMODULE_DEPEND(ustorage_fs, usb, 1, 1, 1); 269217806Slstewart 270217806Slstewartstatic struct usb_config ustorage_fs_bbb_config[USTORAGE_FS_T_BBB_MAX] = { 271217806Slstewart 272217806Slstewart [USTORAGE_FS_T_BBB_COMMAND] = { 273217806Slstewart .type = UE_BULK, 274217806Slstewart .endpoint = UE_ADDR_ANY, 275217806Slstewart .direction = UE_DIR_OUT, 276217806Slstewart .bufsize = sizeof(ustorage_fs_bbb_cbw_t), 277217806Slstewart .callback = &ustorage_fs_t_bbb_command_callback, 278217806Slstewart .usb_mode = USB_MODE_DEVICE, 279217806Slstewart }, 280217806Slstewart 281217806Slstewart [USTORAGE_FS_T_BBB_DATA_DUMP] = { 282217806Slstewart .type = UE_BULK, 283217806Slstewart .endpoint = UE_ADDR_ANY, 284217806Slstewart .direction = UE_DIR_OUT, 285217806Slstewart .bufsize = 0, /* use wMaxPacketSize */ 286217806Slstewart .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,}, 287217806Slstewart .callback = &ustorage_fs_t_bbb_data_dump_callback, 288217806Slstewart .usb_mode = USB_MODE_DEVICE, 289217806Slstewart }, 290217806Slstewart 291217806Slstewart [USTORAGE_FS_T_BBB_DATA_READ] = { 292217806Slstewart .type = UE_BULK, 293217806Slstewart .endpoint = UE_ADDR_ANY, 294217806Slstewart .direction = UE_DIR_OUT, 295217806Slstewart .bufsize = USTORAGE_FS_BULK_SIZE, 296217806Slstewart .flags = {.proxy_buffer = 1,.short_xfer_ok = 1}, 297217806Slstewart .callback = &ustorage_fs_t_bbb_data_read_callback, 298217806Slstewart .usb_mode = USB_MODE_DEVICE, 299217806Slstewart }, 300217806Slstewart 301217806Slstewart [USTORAGE_FS_T_BBB_DATA_WRITE] = { 302217806Slstewart .type = UE_BULK, 303217806Slstewart .endpoint = UE_ADDR_ANY, 304217806Slstewart .direction = UE_DIR_IN, 305217806Slstewart .bufsize = USTORAGE_FS_BULK_SIZE, 306217806Slstewart .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer = 1}, 307217806Slstewart .callback = &ustorage_fs_t_bbb_data_write_callback, 308217806Slstewart .usb_mode = USB_MODE_DEVICE, 309217806Slstewart }, 310217806Slstewart 311217806Slstewart [USTORAGE_FS_T_BBB_STATUS] = { 312217806Slstewart .type = UE_BULK, 313217806Slstewart .endpoint = UE_ADDR_ANY, 314217806Slstewart .direction = UE_DIR_IN, 315217806Slstewart .bufsize = sizeof(ustorage_fs_bbb_csw_t), 316217806Slstewart .flags = {.short_xfer_ok = 1}, 317217806Slstewart .callback = &ustorage_fs_t_bbb_status_callback, 318217806Slstewart .usb_mode = USB_MODE_DEVICE, 319217806Slstewart }, 320217806Slstewart}; 321217806Slstewart 322217806Slstewart/* 323217806Slstewart * USB device probe/attach/detach 324217806Slstewart */ 325217806Slstewart 326217806Slstewartstatic int 327217806Slstewartustorage_fs_probe(device_t dev) 328217806Slstewart{ 329217806Slstewart struct usb_attach_arg *uaa = device_get_ivars(dev); 330217806Slstewart struct usb_interface_descriptor *id; 331217806Slstewart 332217806Slstewart if (uaa->usb_mode != USB_MODE_DEVICE) { 333217806Slstewart return (ENXIO); 334217806Slstewart } 335217806Slstewart /* Check for a standards compliant device */ 336217806Slstewart id = usbd_get_interface_descriptor(uaa->iface); 337217806Slstewart if ((id == NULL) || 338217806Slstewart (id->bInterfaceClass != UICLASS_MASS) || 339217806Slstewart (id->bInterfaceSubClass != UISUBCLASS_SCSI) || 340217806Slstewart (id->bInterfaceProtocol != UIPROTO_MASS_BBB)) { 341217806Slstewart return (ENXIO); 342217806Slstewart } 343217806Slstewart return (BUS_PROBE_GENERIC); 344217806Slstewart} 345217806Slstewart 346217806Slstewartstatic int 347217806Slstewartustorage_fs_attach(device_t dev) 348217806Slstewart{ 349217806Slstewart struct ustorage_fs_softc *sc = device_get_softc(dev); 350217806Slstewart struct usb_attach_arg *uaa = device_get_ivars(dev); 351217806Slstewart struct usb_interface_descriptor *id; 352217806Slstewart int err; 353217806Slstewart int unit; 354239346Slstewart 355217806Slstewart /* 356217806Slstewart * NOTE: the softc struct is cleared in device_set_driver. 357217806Slstewart * We can safely call ustorage_fs_detach without specifically 358217806Slstewart * initializing the struct. 359217806Slstewart */ 360217806Slstewart 361217806Slstewart sc->sc_dev = dev; 362217806Slstewart sc->sc_udev = uaa->device; 363217806Slstewart unit = device_get_unit(dev); 364217806Slstewart 365217806Slstewart /* enable power saving mode */ 366217806Slstewart usbd_set_power_mode(uaa->device, USB_POWER_MODE_SAVE); 367217806Slstewart 368217806Slstewart if (unit == 0) { 369217806Slstewart if (ustorage_fs_ramdisk == NULL) { 370217806Slstewart /* 371217806Slstewart * allocate a memory image for our ramdisk until 372217806Slstewart * further 373217806Slstewart */ 374217806Slstewart ustorage_fs_ramdisk = 375217806Slstewart malloc(USTORAGE_FS_RAM_SECT << 9, M_USB, 376217806Slstewart M_ZERO | M_WAITOK); 377217806Slstewart 378217806Slstewart if (ustorage_fs_ramdisk == NULL) { 379217806Slstewart return (ENOMEM); 380217806Slstewart } 381217806Slstewart } 382217806Slstewart sc->sc_lun[0].memory_image = ustorage_fs_ramdisk; 383217806Slstewart sc->sc_lun[0].num_sectors = USTORAGE_FS_RAM_SECT; 384217806Slstewart sc->sc_lun[0].removable = 1; 385217806Slstewart } 386217806Slstewart 387217806Slstewart device_set_usb_desc(dev); 388217806Slstewart 389217806Slstewart mtx_init(&sc->sc_mtx, "USTORAGE_FS lock", 390217806Slstewart NULL, (MTX_DEF | MTX_RECURSE)); 391217806Slstewart 392217806Slstewart /* get interface index */ 393217806Slstewart 394217806Slstewart id = usbd_get_interface_descriptor(uaa->iface); 395217806Slstewart if (id == NULL) { 396217806Slstewart device_printf(dev, "failed to get " 397217806Slstewart "interface number\n"); 398217806Slstewart goto detach; 399217806Slstewart } 400217806Slstewart sc->sc_iface_no = id->bInterfaceNumber; 401217806Slstewart 402217806Slstewart err = usbd_transfer_setup(uaa->device, 403217806Slstewart &uaa->info.bIfaceIndex, sc->sc_xfer, ustorage_fs_bbb_config, 404217806Slstewart USTORAGE_FS_T_BBB_MAX, sc, &sc->sc_mtx); 405217806Slstewart if (err) { 406217806Slstewart device_printf(dev, "could not setup required " 407217806Slstewart "transfers, %s\n", usbd_errstr(err)); 408217806Slstewart goto detach; 409217806Slstewart } 410217806Slstewart 411217806Slstewart sc->sc_cbw = usbd_xfer_get_frame_buffer(sc->sc_xfer[ 412217806Slstewart USTORAGE_FS_T_BBB_COMMAND], 0); 413217806Slstewart sc->sc_csw = usbd_xfer_get_frame_buffer(sc->sc_xfer[ 414217806Slstewart USTORAGE_FS_T_BBB_STATUS], 0); 415217806Slstewart sc->sc_dma_ptr = usbd_xfer_get_frame_buffer(sc->sc_xfer[ 416217806Slstewart USTORAGE_FS_T_BBB_DATA_READ], 0); 417217806Slstewart 418217806Slstewart /* start Mass Storage State Machine */ 419217806Slstewart 420217806Slstewart mtx_lock(&sc->sc_mtx); 421217806Slstewart ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_COMMAND); 422217806Slstewart mtx_unlock(&sc->sc_mtx); 423217806Slstewart 424217806Slstewart return (0); /* success */ 425217806Slstewart 426217806Slstewartdetach: 427217806Slstewart ustorage_fs_detach(dev); 428217806Slstewart return (ENXIO); /* failure */ 429217806Slstewart} 430217806Slstewart 431217806Slstewartstatic int 432217806Slstewartustorage_fs_detach(device_t dev) 433217806Slstewart{ 434217806Slstewart struct ustorage_fs_softc *sc = device_get_softc(dev); 435217806Slstewart 436217806Slstewart /* teardown our statemachine */ 437217806Slstewart 438217806Slstewart usbd_transfer_unsetup(sc->sc_xfer, USTORAGE_FS_T_BBB_MAX); 439217806Slstewart 440217806Slstewart mtx_destroy(&sc->sc_mtx); 441217806Slstewart 442217806Slstewart return (0); /* success */ 443217806Slstewart} 444217806Slstewart 445217806Slstewartstatic int 446217806Slstewartustorage_fs_suspend(device_t dev) 447217806Slstewart{ 448217806Slstewart device_printf(dev, "suspending\n"); 449217806Slstewart return (0); /* success */ 450217806Slstewart} 451217806Slstewart 452217806Slstewartstatic int 453217806Slstewartustorage_fs_resume(device_t dev) 454217806Slstewart{ 455217806Slstewart device_printf(dev, "resuming\n"); 456217806Slstewart return (0); /* success */ 457217806Slstewart} 458217806Slstewart 459217806Slstewart/* 460217806Slstewart * Generic functions to handle transfers 461217806Slstewart */ 462217806Slstewart 463217806Slstewartstatic void 464217806Slstewartustorage_fs_transfer_start(struct ustorage_fs_softc *sc, uint8_t xfer_index) 465217806Slstewart{ 466217806Slstewart if (sc->sc_xfer[xfer_index]) { 467217806Slstewart sc->sc_last_xfer_index = xfer_index; 468217806Slstewart usbd_transfer_start(sc->sc_xfer[xfer_index]); 469217806Slstewart } 470217806Slstewart} 471217806Slstewart 472217806Slstewartstatic void 473217806Slstewartustorage_fs_transfer_stop(struct ustorage_fs_softc *sc) 474217806Slstewart{ 475217806Slstewart usbd_transfer_stop(sc->sc_xfer[sc->sc_last_xfer_index]); 476217806Slstewart mtx_unlock(&sc->sc_mtx); 477217806Slstewart usbd_transfer_drain(sc->sc_xfer[sc->sc_last_xfer_index]); 478217806Slstewart mtx_lock(&sc->sc_mtx); 479217806Slstewart} 480217806Slstewart 481217806Slstewartstatic int 482239346Slstewartustorage_fs_handle_request(device_t dev, 483217806Slstewart const void *preq, void **pptr, uint16_t *plen, 484217806Slstewart uint16_t offset, uint8_t *pstate) 485217806Slstewart{ 486217806Slstewart struct ustorage_fs_softc *sc = device_get_softc(dev); 487217806Slstewart const struct usb_device_request *req = preq; 488217806Slstewart uint8_t is_complete = *pstate; 489217806Slstewart 490217806Slstewart if (!is_complete) { 491217806Slstewart if ((req->bmRequestType == UT_WRITE_CLASS_INTERFACE) && 492217806Slstewart (req->bRequest == UR_BBB_RESET)) { 493217806Slstewart *plen = 0; 494217806Slstewart mtx_lock(&sc->sc_mtx); 495217806Slstewart ustorage_fs_transfer_stop(sc); 496217806Slstewart sc->sc_transfer.data_error = 1; 497217806Slstewart ustorage_fs_transfer_start(sc, 498217806Slstewart USTORAGE_FS_T_BBB_COMMAND); 499217806Slstewart mtx_unlock(&sc->sc_mtx); 500217806Slstewart return (0); 501217806Slstewart } else if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) && 502217806Slstewart (req->bRequest == UR_BBB_GET_MAX_LUN)) { 503217806Slstewart if (offset == 0) { 504217806Slstewart *plen = 1; 505217806Slstewart *pptr = &sc->sc_last_lun; 506217806Slstewart } else { 507217806Slstewart *plen = 0; 508217806Slstewart } 509217806Slstewart return (0); 510217806Slstewart } 511217806Slstewart } 512217806Slstewart return (ENXIO); /* use builtin handler */ 513217806Slstewart} 514217806Slstewart 515217806Slstewartstatic void 516217806Slstewartustorage_fs_t_bbb_command_callback(struct usb_xfer *xfer, usb_error_t error) 517217806Slstewart{ 518217806Slstewart struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer); 519217806Slstewart uint32_t tag; 520217806Slstewart uint8_t err = 0; 521217806Slstewart 522217806Slstewart DPRINTF("\n"); 523217806Slstewart 524217806Slstewart switch (USB_GET_STATE(xfer)) { 525217806Slstewart case USB_ST_TRANSFERRED: 526217806Slstewart 527217806Slstewart tag = UGETDW(sc->sc_cbw->dCBWSignature); 528217806Slstewart 529217806Slstewart if (tag != CBWSIGNATURE) { 530217806Slstewart /* do nothing */ 531217806Slstewart DPRINTF("invalid signature 0x%08x\n", tag); 532217806Slstewart break; 533217806Slstewart } 534217806Slstewart tag = UGETDW(sc->sc_cbw->dCBWTag); 535217806Slstewart 536217806Slstewart /* echo back tag */ 537217806Slstewart USETDW(sc->sc_csw->dCSWTag, tag); 538217806Slstewart 539217806Slstewart /* reset status */ 540217806Slstewart sc->sc_csw->bCSWStatus = 0; 541217806Slstewart 542217806Slstewart /* reset data offset, data length and data remainder */ 543217806Slstewart sc->sc_transfer.offset = 0; 544217806Slstewart sc->sc_transfer.data_rem = 545217806Slstewart UGETDW(sc->sc_cbw->dCBWDataTransferLength); 546217806Slstewart 547217806Slstewart /* reset data flags */ 548 sc->sc_transfer.data_short = 0; 549 550 /* extract LUN */ 551 sc->sc_transfer.lun = sc->sc_cbw->bCBWLUN; 552 553 if (sc->sc_transfer.data_rem == 0) { 554 sc->sc_transfer.cbw_dir = DIR_NONE; 555 } else { 556 if (sc->sc_cbw->bCBWFlags & CBWFLAGS_IN) { 557 sc->sc_transfer.cbw_dir = DIR_WRITE; 558 } else { 559 sc->sc_transfer.cbw_dir = DIR_READ; 560 } 561 } 562 563 sc->sc_transfer.cmd_len = sc->sc_cbw->bCDBLength; 564 if ((sc->sc_transfer.cmd_len > sizeof(sc->sc_cbw->CBWCDB)) || 565 (sc->sc_transfer.cmd_len == 0)) { 566 /* just halt - this is invalid */ 567 DPRINTF("invalid command length %d bytes\n", 568 sc->sc_transfer.cmd_len); 569 break; 570 } 571 572 err = ustorage_fs_do_cmd(sc); 573 if (err) { 574 /* got an error */ 575 DPRINTF("command failed\n"); 576 break; 577 } 578 if ((sc->sc_transfer.data_rem > 0) && 579 (sc->sc_transfer.cbw_dir != sc->sc_transfer.cmd_dir)) { 580 /* contradicting data transfer direction */ 581 err = 1; 582 DPRINTF("data direction mismatch\n"); 583 break; 584 } 585 switch (sc->sc_transfer.cbw_dir) { 586 case DIR_READ: 587 ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_DATA_READ); 588 break; 589 case DIR_WRITE: 590 ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_DATA_WRITE); 591 break; 592 default: 593 ustorage_fs_transfer_start(sc, 594 USTORAGE_FS_T_BBB_STATUS); 595 break; 596 } 597 break; 598 599 case USB_ST_SETUP: 600tr_setup: 601 if (sc->sc_transfer.data_error) { 602 sc->sc_transfer.data_error = 0; 603 usbd_xfer_set_stall(xfer); 604 DPRINTF("stall pipe\n"); 605 } 606 usbd_transfer_submit(xfer); 607 break; 608 609 default: /* Error */ 610 DPRINTF("error\n"); 611 if (error == USB_ERR_CANCELLED) { 612 break; 613 } 614 /* If the pipe is already stalled, don't do another stall */ 615 if (!usbd_xfer_is_stalled(xfer)) 616 sc->sc_transfer.data_error = 1; 617 618 /* try again */ 619 goto tr_setup; 620 } 621 if (err) { 622 if (sc->sc_csw->bCSWStatus == 0) { 623 /* set some default error code */ 624 sc->sc_csw->bCSWStatus = CSWSTATUS_FAILED; 625 } 626 if (sc->sc_transfer.cbw_dir == DIR_READ) { 627 /* dump all data */ 628 ustorage_fs_transfer_start(sc, 629 USTORAGE_FS_T_BBB_DATA_DUMP); 630 return; 631 } 632 if (sc->sc_transfer.cbw_dir == DIR_WRITE) { 633 /* need to stall before status */ 634 sc->sc_transfer.data_error = 1; 635 } 636 ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_STATUS); 637 } 638} 639 640static void 641ustorage_fs_t_bbb_data_dump_callback(struct usb_xfer *xfer, usb_error_t error) 642{ 643 struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer); 644 uint32_t max_bulk = usbd_xfer_max_len(xfer); 645 int actlen, sumlen; 646 647 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); 648 649 DPRINTF("\n"); 650 651 switch (USB_GET_STATE(xfer)) { 652 case USB_ST_TRANSFERRED: 653 sc->sc_transfer.data_rem -= actlen; 654 sc->sc_transfer.offset += actlen; 655 656 if (actlen != sumlen || sc->sc_transfer.data_rem == 0) { 657 /* short transfer or end of data */ 658 ustorage_fs_transfer_start(sc, 659 USTORAGE_FS_T_BBB_STATUS); 660 break; 661 } 662 /* Fallthrough */ 663 664 case USB_ST_SETUP: 665tr_setup: 666 if (max_bulk > sc->sc_transfer.data_rem) { 667 max_bulk = sc->sc_transfer.data_rem; 668 } 669 if (sc->sc_transfer.data_error) { 670 sc->sc_transfer.data_error = 0; 671 usbd_xfer_set_stall(xfer); 672 } 673 usbd_xfer_set_frame_len(xfer, 0, max_bulk); 674 usbd_transfer_submit(xfer); 675 break; 676 677 default: /* Error */ 678 if (error == USB_ERR_CANCELLED) { 679 break; 680 } 681 /* 682 * If the pipe is already stalled, don't do another stall: 683 */ 684 if (!usbd_xfer_is_stalled(xfer)) 685 sc->sc_transfer.data_error = 1; 686 687 /* try again */ 688 goto tr_setup; 689 } 690} 691 692static void 693ustorage_fs_t_bbb_data_read_callback(struct usb_xfer *xfer, usb_error_t error) 694{ 695 struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer); 696 uint32_t max_bulk = usbd_xfer_max_len(xfer); 697 int actlen, sumlen; 698 699 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); 700 701 DPRINTF("\n"); 702 703 switch (USB_GET_STATE(xfer)) { 704 case USB_ST_TRANSFERRED: 705 /* XXX copy data from DMA buffer */ 706 memcpy(sc->sc_transfer.data_ptr, sc->sc_dma_ptr, actlen); 707 708 sc->sc_transfer.data_rem -= actlen; 709 sc->sc_transfer.data_ptr += actlen; 710 sc->sc_transfer.offset += actlen; 711 712 if (actlen != sumlen || sc->sc_transfer.data_rem == 0) { 713 /* short transfer or end of data */ 714 ustorage_fs_transfer_start(sc, 715 USTORAGE_FS_T_BBB_STATUS); 716 break; 717 } 718 /* Fallthrough */ 719 720 case USB_ST_SETUP: 721tr_setup: 722 if (max_bulk > sc->sc_transfer.data_rem) { 723 max_bulk = sc->sc_transfer.data_rem; 724 } 725 if (sc->sc_transfer.data_error) { 726 sc->sc_transfer.data_error = 0; 727 usbd_xfer_set_stall(xfer); 728 } 729 730 usbd_xfer_set_frame_data(xfer, 0, sc->sc_dma_ptr, max_bulk); 731 usbd_transfer_submit(xfer); 732 break; 733 734 default: /* Error */ 735 if (error == USB_ERR_CANCELLED) { 736 break; 737 } 738 /* If the pipe is already stalled, don't do another stall */ 739 if (!usbd_xfer_is_stalled(xfer)) 740 sc->sc_transfer.data_error = 1; 741 742 /* try again */ 743 goto tr_setup; 744 } 745} 746 747static void 748ustorage_fs_t_bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error) 749{ 750 struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer); 751 uint32_t max_bulk = usbd_xfer_max_len(xfer); 752 int actlen, sumlen; 753 754 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); 755 756 DPRINTF("\n"); 757 758 switch (USB_GET_STATE(xfer)) { 759 case USB_ST_TRANSFERRED: 760 sc->sc_transfer.data_rem -= actlen; 761 sc->sc_transfer.data_ptr += actlen; 762 sc->sc_transfer.offset += actlen; 763 764 if (actlen != sumlen || sc->sc_transfer.data_rem == 0) { 765 /* short transfer or end of data */ 766 ustorage_fs_transfer_start(sc, 767 USTORAGE_FS_T_BBB_STATUS); 768 break; 769 } 770 case USB_ST_SETUP: 771tr_setup: 772 if (max_bulk >= sc->sc_transfer.data_rem) { 773 max_bulk = sc->sc_transfer.data_rem; 774 if (sc->sc_transfer.data_short) 775 usbd_xfer_set_flag(xfer, USB_FORCE_SHORT_XFER); 776 else 777 usbd_xfer_clr_flag(xfer, USB_FORCE_SHORT_XFER); 778 } else 779 usbd_xfer_clr_flag(xfer, USB_FORCE_SHORT_XFER); 780 781 if (sc->sc_transfer.data_error) { 782 sc->sc_transfer.data_error = 0; 783 usbd_xfer_set_stall(xfer); 784 } 785 786 /* XXX copy data to DMA buffer */ 787 memcpy(sc->sc_dma_ptr, sc->sc_transfer.data_ptr, max_bulk); 788 789 usbd_xfer_set_frame_data(xfer, 0, sc->sc_dma_ptr, max_bulk); 790 usbd_transfer_submit(xfer); 791 break; 792 793 default: /* Error */ 794 if (error == USB_ERR_CANCELLED) { 795 break; 796 } 797 /* 798 * If the pipe is already stalled, don't do another 799 * stall 800 */ 801 if (!usbd_xfer_is_stalled(xfer)) 802 sc->sc_transfer.data_error = 1; 803 804 /* try again */ 805 goto tr_setup; 806 } 807} 808 809static void 810ustorage_fs_t_bbb_status_callback(struct usb_xfer *xfer, usb_error_t error) 811{ 812 struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer); 813 814 DPRINTF("\n"); 815 816 switch (USB_GET_STATE(xfer)) { 817 case USB_ST_TRANSFERRED: 818 ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_COMMAND); 819 break; 820 821 case USB_ST_SETUP: 822tr_setup: 823 USETDW(sc->sc_csw->dCSWSignature, CSWSIGNATURE); 824 USETDW(sc->sc_csw->dCSWDataResidue, sc->sc_transfer.data_rem); 825 826 if (sc->sc_transfer.data_error) { 827 sc->sc_transfer.data_error = 0; 828 usbd_xfer_set_stall(xfer); 829 } 830 usbd_transfer_submit(xfer); 831 break; 832 833 default: 834 if (error == USB_ERR_CANCELLED) { 835 break; 836 } 837 /* If the pipe is already stalled, don't do another stall */ 838 if (!usbd_xfer_is_stalled(xfer)) 839 sc->sc_transfer.data_error = 1; 840 841 /* try again */ 842 goto tr_setup; 843 } 844} 845 846/* SCSI commands that we recognize */ 847#define SC_FORMAT_UNIT 0x04 848#define SC_INQUIRY 0x12 849#define SC_MODE_SELECT_6 0x15 850#define SC_MODE_SELECT_10 0x55 851#define SC_MODE_SENSE_6 0x1a 852#define SC_MODE_SENSE_10 0x5a 853#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e 854#define SC_READ_6 0x08 855#define SC_READ_10 0x28 856#define SC_READ_12 0xa8 857#define SC_READ_CAPACITY 0x25 858#define SC_READ_FORMAT_CAPACITIES 0x23 859#define SC_RELEASE 0x17 860#define SC_REQUEST_SENSE 0x03 861#define SC_RESERVE 0x16 862#define SC_SEND_DIAGNOSTIC 0x1d 863#define SC_START_STOP_UNIT 0x1b 864#define SC_SYNCHRONIZE_CACHE 0x35 865#define SC_TEST_UNIT_READY 0x00 866#define SC_VERIFY 0x2f 867#define SC_WRITE_6 0x0a 868#define SC_WRITE_10 0x2a 869#define SC_WRITE_12 0xaa 870 871/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */ 872#define SS_NO_SENSE 0 873#define SS_COMMUNICATION_FAILURE 0x040800 874#define SS_INVALID_COMMAND 0x052000 875#define SS_INVALID_FIELD_IN_CDB 0x052400 876#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100 877#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500 878#define SS_MEDIUM_NOT_PRESENT 0x023a00 879#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302 880#define SS_NOT_READY_TO_READY_TRANSITION 0x062800 881#define SS_RESET_OCCURRED 0x062900 882#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900 883#define SS_UNRECOVERED_READ_ERROR 0x031100 884#define SS_WRITE_ERROR 0x030c02 885#define SS_WRITE_PROTECTED 0x072700 886 887#define SK(x) ((uint8_t) ((x) >> 16)) /* Sense Key byte, etc. */ 888#define ASC(x) ((uint8_t) ((x) >> 8)) 889#define ASCQ(x) ((uint8_t) (x)) 890 891/* Routines for unaligned data access */ 892 893static uint16_t 894get_be16(uint8_t *buf) 895{ 896 return ((uint16_t)buf[0] << 8) | ((uint16_t)buf[1]); 897} 898 899static uint32_t 900get_be32(uint8_t *buf) 901{ 902 return ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) | 903 ((uint32_t)buf[2] << 8) | ((uint32_t)buf[3]); 904} 905 906static void 907put_be16(uint8_t *buf, uint16_t val) 908{ 909 buf[0] = val >> 8; 910 buf[1] = val; 911} 912 913static void 914put_be32(uint8_t *buf, uint32_t val) 915{ 916 buf[0] = val >> 24; 917 buf[1] = val >> 16; 918 buf[2] = val >> 8; 919 buf[3] = val & 0xff; 920} 921 922/*------------------------------------------------------------------------* 923 * ustorage_fs_verify 924 * 925 * Returns: 926 * 0: Success 927 * Else: Failure 928 *------------------------------------------------------------------------*/ 929static uint8_t 930ustorage_fs_verify(struct ustorage_fs_softc *sc) 931{ 932 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 933 uint32_t lba; 934 uint32_t vlen; 935 uint64_t file_offset; 936 uint64_t amount_left; 937 938 /* 939 * Get the starting Logical Block Address 940 */ 941 lba = get_be32(&sc->sc_cbw->CBWCDB[2]); 942 943 /* 944 * We allow DPO (Disable Page Out = don't save data in the cache) 945 * but we don't implement it. 946 */ 947 if ((sc->sc_cbw->CBWCDB[1] & ~0x10) != 0) { 948 currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 949 return (1); 950 } 951 vlen = get_be16(&sc->sc_cbw->CBWCDB[7]); 952 if (vlen == 0) { 953 goto done; 954 } 955 /* No default reply */ 956 957 /* Prepare to carry out the file verify */ 958 amount_left = vlen; 959 amount_left <<= 9; 960 file_offset = lba; 961 file_offset <<= 9; 962 963 /* Range check */ 964 vlen += lba; 965 966 if ((vlen < lba) || 967 (vlen > currlun->num_sectors) || 968 (lba >= currlun->num_sectors)) { 969 currlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 970 return (1); 971 } 972 /* XXX TODO: verify that data is readable */ 973done: 974 return (ustorage_fs_min_len(sc, 0, -1U)); 975} 976 977/*------------------------------------------------------------------------* 978 * ustorage_fs_inquiry 979 * 980 * Returns: 981 * 0: Success 982 * Else: Failure 983 *------------------------------------------------------------------------*/ 984static uint8_t 985ustorage_fs_inquiry(struct ustorage_fs_softc *sc) 986{ 987 uint8_t *buf = sc->sc_transfer.data_ptr; 988 989 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 990 991 if (!sc->sc_transfer.currlun) { 992 /* Unsupported LUNs are okay */ 993 memset(buf, 0, 36); 994 buf[0] = 0x7f; 995 /* Unsupported, no device - type */ 996 return (ustorage_fs_min_len(sc, 36, -1U)); 997 } 998 memset(buf, 0, 8); 999 /* Non - removable, direct - access device */ 1000 if (currlun->removable) 1001 buf[1] = 0x80; 1002 buf[2] = 2; 1003 /* ANSI SCSI level 2 */ 1004 buf[3] = 2; 1005 /* SCSI - 2 INQUIRY data format */ 1006 buf[4] = 31; 1007 /* Additional length */ 1008 /* No special options */ 1009 /* Copy in ID string */ 1010 memcpy(buf + 8, USTORAGE_FS_ID_STRING, 28); 1011 1012#if (USTORAGE_QDATA_MAX < 36) 1013#error "(USTORAGE_QDATA_MAX < 36)" 1014#endif 1015 return (ustorage_fs_min_len(sc, 36, -1U)); 1016} 1017 1018/*------------------------------------------------------------------------* 1019 * ustorage_fs_request_sense 1020 * 1021 * Returns: 1022 * 0: Success 1023 * Else: Failure 1024 *------------------------------------------------------------------------*/ 1025static uint8_t 1026ustorage_fs_request_sense(struct ustorage_fs_softc *sc) 1027{ 1028 uint8_t *buf = sc->sc_transfer.data_ptr; 1029 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1030 uint32_t sd; 1031 uint32_t sdinfo; 1032 uint8_t valid; 1033 1034 /* 1035 * From the SCSI-2 spec., section 7.9 (Unit attention condition): 1036 * 1037 * If a REQUEST SENSE command is received from an initiator 1038 * with a pending unit attention condition (before the target 1039 * generates the contingent allegiance condition), then the 1040 * target shall either: 1041 * a) report any pending sense data and preserve the unit 1042 * attention condition on the logical unit, or, 1043 * b) report the unit attention condition, may discard any 1044 * pending sense data, and clear the unit attention 1045 * condition on the logical unit for that initiator. 1046 * 1047 * FSG normally uses option a); enable this code to use option b). 1048 */ 1049#if 0 1050 if (currlun && currlun->unit_attention_data != SS_NO_SENSE) { 1051 currlun->sense_data = currlun->unit_attention_data; 1052 currlun->unit_attention_data = SS_NO_SENSE; 1053 } 1054#endif 1055 1056 if (!currlun) { 1057 /* Unsupported LUNs are okay */ 1058 sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; 1059 sdinfo = 0; 1060 valid = 0; 1061 } else { 1062 sd = currlun->sense_data; 1063 sdinfo = currlun->sense_data_info; 1064 valid = currlun->info_valid << 7; 1065 currlun->sense_data = SS_NO_SENSE; 1066 currlun->sense_data_info = 0; 1067 currlun->info_valid = 0; 1068 } 1069 1070 memset(buf, 0, 18); 1071 buf[0] = valid | 0x70; 1072 /* Valid, current error */ 1073 buf[2] = SK(sd); 1074 put_be32(&buf[3], sdinfo); 1075 /* Sense information */ 1076 buf[7] = 18 - 8; 1077 /* Additional sense length */ 1078 buf[12] = ASC(sd); 1079 buf[13] = ASCQ(sd); 1080 1081#if (USTORAGE_QDATA_MAX < 18) 1082#error "(USTORAGE_QDATA_MAX < 18)" 1083#endif 1084 return (ustorage_fs_min_len(sc, 18, -1U)); 1085} 1086 1087/*------------------------------------------------------------------------* 1088 * ustorage_fs_read_capacity 1089 * 1090 * Returns: 1091 * 0: Success 1092 * Else: Failure 1093 *------------------------------------------------------------------------*/ 1094static uint8_t 1095ustorage_fs_read_capacity(struct ustorage_fs_softc *sc) 1096{ 1097 uint8_t *buf = sc->sc_transfer.data_ptr; 1098 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1099 uint32_t lba = get_be32(&sc->sc_cbw->CBWCDB[2]); 1100 uint8_t pmi = sc->sc_cbw->CBWCDB[8]; 1101 1102 /* Check the PMI and LBA fields */ 1103 if ((pmi > 1) || ((pmi == 0) && (lba != 0))) { 1104 currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1105 return (1); 1106 } 1107 /* Max logical block */ 1108 put_be32(&buf[0], currlun->num_sectors - 1); 1109 /* Block length */ 1110 put_be32(&buf[4], 512); 1111 1112#if (USTORAGE_QDATA_MAX < 8) 1113#error "(USTORAGE_QDATA_MAX < 8)" 1114#endif 1115 return (ustorage_fs_min_len(sc, 8, -1U)); 1116} 1117 1118/*------------------------------------------------------------------------* 1119 * ustorage_fs_mode_sense 1120 * 1121 * Returns: 1122 * 0: Success 1123 * Else: Failure 1124 *------------------------------------------------------------------------*/ 1125static uint8_t 1126ustorage_fs_mode_sense(struct ustorage_fs_softc *sc) 1127{ 1128 uint8_t *buf = sc->sc_transfer.data_ptr; 1129 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1130 uint8_t *buf0; 1131 uint16_t len; 1132 uint16_t limit; 1133 uint8_t mscmnd = sc->sc_cbw->CBWCDB[0]; 1134 uint8_t pc; 1135 uint8_t page_code; 1136 uint8_t changeable_values; 1137 uint8_t all_pages; 1138 1139 buf0 = buf; 1140 1141 if ((sc->sc_cbw->CBWCDB[1] & ~0x08) != 0) { 1142 /* Mask away DBD */ 1143 currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1144 return (1); 1145 } 1146 pc = sc->sc_cbw->CBWCDB[2] >> 6; 1147 page_code = sc->sc_cbw->CBWCDB[2] & 0x3f; 1148 if (pc == 3) { 1149 currlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED; 1150 return (1); 1151 } 1152 changeable_values = (pc == 1); 1153 all_pages = (page_code == 0x3f); 1154 1155 /* 1156 * Write the mode parameter header. Fixed values are: default 1157 * medium type, no cache control (DPOFUA), and no block descriptors. 1158 * The only variable value is the WriteProtect bit. We will fill in 1159 * the mode data length later. 1160 */ 1161 memset(buf, 0, 8); 1162 if (mscmnd == SC_MODE_SENSE_6) { 1163 buf[2] = (currlun->read_only ? 0x80 : 0x00); 1164 /* WP, DPOFUA */ 1165 buf += 4; 1166 limit = 255; 1167 } else { 1168 /* SC_MODE_SENSE_10 */ 1169 buf[3] = (currlun->read_only ? 0x80 : 0x00); 1170 /* WP, DPOFUA */ 1171 buf += 8; 1172 limit = 65535; 1173 /* Should really be mod_data.buflen */ 1174 } 1175 1176 /* No block descriptors */ 1177 1178 /* 1179 * The mode pages, in numerical order. 1180 */ 1181 if ((page_code == 0x08) || all_pages) { 1182 buf[0] = 0x08; 1183 /* Page code */ 1184 buf[1] = 10; 1185 /* Page length */ 1186 memset(buf + 2, 0, 10); 1187 /* None of the fields are changeable */ 1188 1189 if (!changeable_values) { 1190 buf[2] = 0x04; 1191 /* Write cache enable, */ 1192 /* Read cache not disabled */ 1193 /* No cache retention priorities */ 1194 put_be16(&buf[4], 0xffff); 1195 /* Don 't disable prefetch */ 1196 /* Minimum prefetch = 0 */ 1197 put_be16(&buf[8], 0xffff); 1198 /* Maximum prefetch */ 1199 put_be16(&buf[10], 0xffff); 1200 /* Maximum prefetch ceiling */ 1201 } 1202 buf += 12; 1203 } 1204 /* 1205 * Check that a valid page was requested and the mode data length 1206 * isn't too long. 1207 */ 1208 len = buf - buf0; 1209 if (len > limit) { 1210 currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1211 return (1); 1212 } 1213 /* Store the mode data length */ 1214 if (mscmnd == SC_MODE_SENSE_6) 1215 buf0[0] = len - 1; 1216 else 1217 put_be16(buf0, len - 2); 1218 1219#if (USTORAGE_QDATA_MAX < 24) 1220#error "(USTORAGE_QDATA_MAX < 24)" 1221#endif 1222 return (ustorage_fs_min_len(sc, len, -1U)); 1223} 1224 1225/*------------------------------------------------------------------------* 1226 * ustorage_fs_start_stop 1227 * 1228 * Returns: 1229 * 0: Success 1230 * Else: Failure 1231 *------------------------------------------------------------------------*/ 1232static uint8_t 1233ustorage_fs_start_stop(struct ustorage_fs_softc *sc) 1234{ 1235 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1236 uint8_t loej; 1237 uint8_t start; 1238 uint8_t immed; 1239 1240 if (!currlun->removable) { 1241 currlun->sense_data = SS_INVALID_COMMAND; 1242 return (1); 1243 } 1244 immed = sc->sc_cbw->CBWCDB[1] & 0x01; 1245 loej = sc->sc_cbw->CBWCDB[4] & 0x02; 1246 start = sc->sc_cbw->CBWCDB[4] & 0x01; 1247 1248 if (immed || loej || start) { 1249 /* compile fix */ 1250 } 1251 return (0); 1252} 1253 1254/*------------------------------------------------------------------------* 1255 * ustorage_fs_prevent_allow 1256 * 1257 * Returns: 1258 * 0: Success 1259 * Else: Failure 1260 *------------------------------------------------------------------------*/ 1261static uint8_t 1262ustorage_fs_prevent_allow(struct ustorage_fs_softc *sc) 1263{ 1264 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1265 uint8_t prevent; 1266 1267 if (!currlun->removable) { 1268 currlun->sense_data = SS_INVALID_COMMAND; 1269 return (1); 1270 } 1271 prevent = sc->sc_cbw->CBWCDB[4] & 0x01; 1272 if ((sc->sc_cbw->CBWCDB[4] & ~0x01) != 0) { 1273 /* Mask away Prevent */ 1274 currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1275 return (1); 1276 } 1277 if (currlun->prevent_medium_removal && !prevent) { 1278 //fsync_sub(currlun); 1279 } 1280 currlun->prevent_medium_removal = prevent; 1281 return (0); 1282} 1283 1284/*------------------------------------------------------------------------* 1285 * ustorage_fs_read_format_capacities 1286 * 1287 * Returns: 1288 * 0: Success 1289 * Else: Failure 1290 *------------------------------------------------------------------------*/ 1291static uint8_t 1292ustorage_fs_read_format_capacities(struct ustorage_fs_softc *sc) 1293{ 1294 uint8_t *buf = sc->sc_transfer.data_ptr; 1295 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1296 1297 buf[0] = buf[1] = buf[2] = 0; 1298 buf[3] = 8; 1299 /* Only the Current / Maximum Capacity Descriptor */ 1300 buf += 4; 1301 1302 /* Number of blocks */ 1303 put_be32(&buf[0], currlun->num_sectors); 1304 /* Block length */ 1305 put_be32(&buf[4], 512); 1306 /* Current capacity */ 1307 buf[4] = 0x02; 1308 1309#if (USTORAGE_QDATA_MAX < 12) 1310#error "(USTORAGE_QDATA_MAX < 12)" 1311#endif 1312 return (ustorage_fs_min_len(sc, 12, -1U)); 1313} 1314 1315/*------------------------------------------------------------------------* 1316 * ustorage_fs_mode_select 1317 * 1318 * Return values: 1319 * 0: Success 1320 * Else: Failure 1321 *------------------------------------------------------------------------*/ 1322static uint8_t 1323ustorage_fs_mode_select(struct ustorage_fs_softc *sc) 1324{ 1325 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1326 1327 /* We don't support MODE SELECT */ 1328 currlun->sense_data = SS_INVALID_COMMAND; 1329 return (1); 1330} 1331 1332/*------------------------------------------------------------------------* 1333 * ustorage_fs_synchronize_cache 1334 * 1335 * Return values: 1336 * 0: Success 1337 * Else: Failure 1338 *------------------------------------------------------------------------*/ 1339static uint8_t 1340ustorage_fs_synchronize_cache(struct ustorage_fs_softc *sc) 1341{ 1342#if 0 1343 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1344 uint8_t rc; 1345 1346 /* 1347 * We ignore the requested LBA and write out all dirty data buffers. 1348 */ 1349 rc = 0; 1350 if (rc) { 1351 currlun->sense_data = SS_WRITE_ERROR; 1352 } 1353#endif 1354 return (0); 1355} 1356 1357/*------------------------------------------------------------------------* 1358 * ustorage_fs_read - read data from disk 1359 * 1360 * Return values: 1361 * 0: Success 1362 * Else: Failure 1363 *------------------------------------------------------------------------*/ 1364static uint8_t 1365ustorage_fs_read(struct ustorage_fs_softc *sc) 1366{ 1367 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1368 uint64_t file_offset; 1369 uint32_t lba; 1370 uint32_t len; 1371 1372 /* 1373 * Get the starting Logical Block Address and check that it's not 1374 * too big 1375 */ 1376 if (sc->sc_cbw->CBWCDB[0] == SC_READ_6) { 1377 lba = (((uint32_t)sc->sc_cbw->CBWCDB[1]) << 16) | 1378 get_be16(&sc->sc_cbw->CBWCDB[2]); 1379 } else { 1380 lba = get_be32(&sc->sc_cbw->CBWCDB[2]); 1381 1382 /* 1383 * We allow DPO (Disable Page Out = don't save data in the 1384 * cache) and FUA (Force Unit Access = don't read from the 1385 * cache), but we don't implement them. 1386 */ 1387 if ((sc->sc_cbw->CBWCDB[1] & ~0x18) != 0) { 1388 currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1389 return (1); 1390 } 1391 } 1392 len = sc->sc_transfer.data_rem >> 9; 1393 len += lba; 1394 1395 if ((len < lba) || 1396 (len > currlun->num_sectors) || 1397 (lba >= currlun->num_sectors)) { 1398 currlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 1399 return (1); 1400 } 1401 file_offset = lba; 1402 file_offset <<= 9; 1403 1404 sc->sc_transfer.data_ptr = currlun->memory_image + file_offset; 1405 1406 return (0); 1407} 1408 1409/*------------------------------------------------------------------------* 1410 * ustorage_fs_write - write data to disk 1411 * 1412 * Return values: 1413 * 0: Success 1414 * Else: Failure 1415 *------------------------------------------------------------------------*/ 1416static uint8_t 1417ustorage_fs_write(struct ustorage_fs_softc *sc) 1418{ 1419 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1420 uint64_t file_offset; 1421 uint32_t lba; 1422 uint32_t len; 1423 1424 if (currlun->read_only) { 1425 currlun->sense_data = SS_WRITE_PROTECTED; 1426 return (1); 1427 } 1428 /* XXX clear SYNC */ 1429 1430 /* 1431 * Get the starting Logical Block Address and check that it's not 1432 * too big. 1433 */ 1434 if (sc->sc_cbw->CBWCDB[0] == SC_WRITE_6) 1435 lba = (((uint32_t)sc->sc_cbw->CBWCDB[1]) << 16) | 1436 get_be16(&sc->sc_cbw->CBWCDB[2]); 1437 else { 1438 lba = get_be32(&sc->sc_cbw->CBWCDB[2]); 1439 1440 /* 1441 * We allow DPO (Disable Page Out = don't save data in the 1442 * cache) and FUA (Force Unit Access = write directly to the 1443 * medium). We don't implement DPO; we implement FUA by 1444 * performing synchronous output. 1445 */ 1446 if ((sc->sc_cbw->CBWCDB[1] & ~0x18) != 0) { 1447 currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1448 return (1); 1449 } 1450 if (sc->sc_cbw->CBWCDB[1] & 0x08) { 1451 /* FUA */ 1452 /* XXX set SYNC flag here */ 1453 } 1454 } 1455 1456 len = sc->sc_transfer.data_rem >> 9; 1457 len += lba; 1458 1459 if ((len < lba) || 1460 (len > currlun->num_sectors) || 1461 (lba >= currlun->num_sectors)) { 1462 currlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 1463 return (1); 1464 } 1465 file_offset = lba; 1466 file_offset <<= 9; 1467 1468 sc->sc_transfer.data_ptr = currlun->memory_image + file_offset; 1469 1470 return (0); 1471} 1472 1473/*------------------------------------------------------------------------* 1474 * ustorage_fs_min_len 1475 * 1476 * Return values: 1477 * 0: Success 1478 * Else: Failure 1479 *------------------------------------------------------------------------*/ 1480static uint8_t 1481ustorage_fs_min_len(struct ustorage_fs_softc *sc, uint32_t len, uint32_t mask) 1482{ 1483 if (len != sc->sc_transfer.data_rem) { 1484 1485 if (sc->sc_transfer.cbw_dir == DIR_READ) { 1486 /* 1487 * there must be something wrong about this SCSI 1488 * command 1489 */ 1490 sc->sc_csw->bCSWStatus = CSWSTATUS_PHASE; 1491 return (1); 1492 } 1493 /* compute the minimum length */ 1494 1495 if (sc->sc_transfer.data_rem > len) { 1496 /* data ends prematurely */ 1497 sc->sc_transfer.data_rem = len; 1498 sc->sc_transfer.data_short = 1; 1499 } 1500 /* check length alignment */ 1501 1502 if (sc->sc_transfer.data_rem & ~mask) { 1503 /* data ends prematurely */ 1504 sc->sc_transfer.data_rem &= mask; 1505 sc->sc_transfer.data_short = 1; 1506 } 1507 } 1508 return (0); 1509} 1510 1511/*------------------------------------------------------------------------* 1512 * ustorage_fs_check_cmd - check command routine 1513 * 1514 * Check whether the command is properly formed and whether its data 1515 * size and direction agree with the values we already have. 1516 * 1517 * Return values: 1518 * 0: Success 1519 * Else: Failure 1520 *------------------------------------------------------------------------*/ 1521static uint8_t 1522ustorage_fs_check_cmd(struct ustorage_fs_softc *sc, uint8_t min_cmd_size, 1523 uint16_t mask, uint8_t needs_medium) 1524{ 1525 struct ustorage_fs_lun *currlun; 1526 uint8_t lun = (sc->sc_cbw->CBWCDB[1] >> 5); 1527 uint8_t i; 1528 1529 /* Verify the length of the command itself */ 1530 if (min_cmd_size > sc->sc_transfer.cmd_len) { 1531 DPRINTF("%u > %u\n", 1532 min_cmd_size, sc->sc_transfer.cmd_len); 1533 sc->sc_csw->bCSWStatus = CSWSTATUS_PHASE; 1534 return (1); 1535 } 1536 /* Mask away the LUN */ 1537 sc->sc_cbw->CBWCDB[1] &= 0x1f; 1538 1539 /* Check if LUN is correct */ 1540 if (lun != sc->sc_transfer.lun) { 1541 1542 } 1543 /* Check the LUN */ 1544 if (sc->sc_transfer.lun <= sc->sc_last_lun) { 1545 sc->sc_transfer.currlun = currlun = 1546 sc->sc_lun + sc->sc_transfer.lun; 1547 if (sc->sc_cbw->CBWCDB[0] != SC_REQUEST_SENSE) { 1548 currlun->sense_data = SS_NO_SENSE; 1549 currlun->sense_data_info = 0; 1550 currlun->info_valid = 0; 1551 } 1552 /* 1553 * If a unit attention condition exists, only INQUIRY 1554 * and REQUEST SENSE commands are allowed. Anything 1555 * else must fail! 1556 */ 1557 if ((currlun->unit_attention_data != SS_NO_SENSE) && 1558 (sc->sc_cbw->CBWCDB[0] != SC_INQUIRY) && 1559 (sc->sc_cbw->CBWCDB[0] != SC_REQUEST_SENSE)) { 1560 currlun->sense_data = currlun->unit_attention_data; 1561 currlun->unit_attention_data = SS_NO_SENSE; 1562 return (1); 1563 } 1564 } else { 1565 sc->sc_transfer.currlun = currlun = NULL; 1566 1567 /* 1568 * INQUIRY and REQUEST SENSE commands are explicitly allowed 1569 * to use unsupported LUNs; all others may not. 1570 */ 1571 if ((sc->sc_cbw->CBWCDB[0] != SC_INQUIRY) && 1572 (sc->sc_cbw->CBWCDB[0] != SC_REQUEST_SENSE)) { 1573 return (1); 1574 } 1575 } 1576 1577 /* 1578 * Check that only command bytes listed in the mask are 1579 * non-zero. 1580 */ 1581 for (i = 0; i != min_cmd_size; i++) { 1582 if (sc->sc_cbw->CBWCDB[i] && !(mask & (1UL << i))) { 1583 if (currlun) { 1584 currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1585 } 1586 return (1); 1587 } 1588 } 1589 1590 /* 1591 * If the medium isn't mounted and the command needs to access 1592 * it, return an error. 1593 */ 1594 if (currlun && (!currlun->memory_image) && needs_medium) { 1595 currlun->sense_data = SS_MEDIUM_NOT_PRESENT; 1596 return (1); 1597 } 1598 return (0); 1599} 1600 1601/*------------------------------------------------------------------------* 1602 * ustorage_fs_do_cmd - do command 1603 * 1604 * Return values: 1605 * 0: Success 1606 * Else: Failure 1607 *------------------------------------------------------------------------*/ 1608static uint8_t 1609ustorage_fs_do_cmd(struct ustorage_fs_softc *sc) 1610{ 1611 uint8_t error = 1; 1612 uint8_t i; 1613 uint32_t temp; 1614 const uint32_t mask9 = (0xFFFFFFFFUL >> 9) << 9; 1615 1616 /* set default data transfer pointer */ 1617 sc->sc_transfer.data_ptr = sc->sc_qdata; 1618 1619 DPRINTF("cmd_data[0]=0x%02x, data_rem=0x%08x\n", 1620 sc->sc_cbw->CBWCDB[0], sc->sc_transfer.data_rem); 1621 1622 switch (sc->sc_cbw->CBWCDB[0]) { 1623 case SC_INQUIRY: 1624 sc->sc_transfer.cmd_dir = DIR_WRITE; 1625 error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U); 1626 if (error) { 1627 break; 1628 } 1629 error = ustorage_fs_check_cmd(sc, 6, 1630 (1UL << 4) | 1, 0); 1631 if (error) { 1632 break; 1633 } 1634 error = ustorage_fs_inquiry(sc); 1635 1636 break; 1637 1638 case SC_MODE_SELECT_6: 1639 sc->sc_transfer.cmd_dir = DIR_READ; 1640 error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U); 1641 if (error) { 1642 break; 1643 } 1644 error = ustorage_fs_check_cmd(sc, 6, 1645 (1UL << 1) | (1UL << 4) | 1, 0); 1646 if (error) { 1647 break; 1648 } 1649 error = ustorage_fs_mode_select(sc); 1650 1651 break; 1652 1653 case SC_MODE_SELECT_10: 1654 sc->sc_transfer.cmd_dir = DIR_READ; 1655 error = ustorage_fs_min_len(sc, 1656 get_be16(&sc->sc_cbw->CBWCDB[7]), -1U); 1657 if (error) { 1658 break; 1659 } 1660 error = ustorage_fs_check_cmd(sc, 10, 1661 (1UL << 1) | (3UL << 7) | 1, 0); 1662 if (error) { 1663 break; 1664 } 1665 error = ustorage_fs_mode_select(sc); 1666 1667 break; 1668 1669 case SC_MODE_SENSE_6: 1670 sc->sc_transfer.cmd_dir = DIR_WRITE; 1671 error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U); 1672 if (error) { 1673 break; 1674 } 1675 error = ustorage_fs_check_cmd(sc, 6, 1676 (1UL << 1) | (1UL << 2) | (1UL << 4) | 1, 0); 1677 if (error) { 1678 break; 1679 } 1680 error = ustorage_fs_mode_sense(sc); 1681 1682 break; 1683 1684 case SC_MODE_SENSE_10: 1685 sc->sc_transfer.cmd_dir = DIR_WRITE; 1686 error = ustorage_fs_min_len(sc, 1687 get_be16(&sc->sc_cbw->CBWCDB[7]), -1U); 1688 if (error) { 1689 break; 1690 } 1691 error = ustorage_fs_check_cmd(sc, 10, 1692 (1UL << 1) | (1UL << 2) | (3UL << 7) | 1, 0); 1693 if (error) { 1694 break; 1695 } 1696 error = ustorage_fs_mode_sense(sc); 1697 1698 break; 1699 1700 case SC_PREVENT_ALLOW_MEDIUM_REMOVAL: 1701 error = ustorage_fs_min_len(sc, 0, -1U); 1702 if (error) { 1703 break; 1704 } 1705 error = ustorage_fs_check_cmd(sc, 6, 1706 (1UL << 4) | 1, 0); 1707 if (error) { 1708 break; 1709 } 1710 error = ustorage_fs_prevent_allow(sc); 1711 1712 break; 1713 1714 case SC_READ_6: 1715 i = sc->sc_cbw->CBWCDB[4]; 1716 sc->sc_transfer.cmd_dir = DIR_WRITE; 1717 temp = ((i == 0) ? 256UL : i); 1718 error = ustorage_fs_min_len(sc, temp << 9, mask9); 1719 if (error) { 1720 break; 1721 } 1722 error = ustorage_fs_check_cmd(sc, 6, 1723 (7UL << 1) | (1UL << 4) | 1, 1); 1724 if (error) { 1725 break; 1726 } 1727 error = ustorage_fs_read(sc); 1728 1729 break; 1730 1731 case SC_READ_10: 1732 sc->sc_transfer.cmd_dir = DIR_WRITE; 1733 temp = get_be16(&sc->sc_cbw->CBWCDB[7]); 1734 error = ustorage_fs_min_len(sc, temp << 9, mask9); 1735 if (error) { 1736 break; 1737 } 1738 error = ustorage_fs_check_cmd(sc, 10, 1739 (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1); 1740 if (error) { 1741 break; 1742 } 1743 error = ustorage_fs_read(sc); 1744 1745 break; 1746 1747 case SC_READ_12: 1748 sc->sc_transfer.cmd_dir = DIR_WRITE; 1749 temp = get_be32(&sc->sc_cbw->CBWCDB[6]); 1750 if (temp >= (1UL << (32 - 9))) { 1751 /* numerical overflow */ 1752 sc->sc_csw->bCSWStatus = CSWSTATUS_FAILED; 1753 error = 1; 1754 break; 1755 } 1756 error = ustorage_fs_min_len(sc, temp << 9, mask9); 1757 if (error) { 1758 break; 1759 } 1760 error = ustorage_fs_check_cmd(sc, 12, 1761 (1UL << 1) | (0xfUL << 2) | (0xfUL << 6) | 1, 1); 1762 if (error) { 1763 break; 1764 } 1765 error = ustorage_fs_read(sc); 1766 1767 break; 1768 1769 case SC_READ_CAPACITY: 1770 sc->sc_transfer.cmd_dir = DIR_WRITE; 1771 error = ustorage_fs_check_cmd(sc, 10, 1772 (0xfUL << 2) | (1UL << 8) | 1, 1); 1773 if (error) { 1774 break; 1775 } 1776 error = ustorage_fs_read_capacity(sc); 1777 1778 break; 1779 1780 case SC_READ_FORMAT_CAPACITIES: 1781 sc->sc_transfer.cmd_dir = DIR_WRITE; 1782 error = ustorage_fs_min_len(sc, 1783 get_be16(&sc->sc_cbw->CBWCDB[7]), -1U); 1784 if (error) { 1785 break; 1786 } 1787 error = ustorage_fs_check_cmd(sc, 10, 1788 (3UL << 7) | 1, 1); 1789 if (error) { 1790 break; 1791 } 1792 error = ustorage_fs_read_format_capacities(sc); 1793 1794 break; 1795 1796 case SC_REQUEST_SENSE: 1797 sc->sc_transfer.cmd_dir = DIR_WRITE; 1798 error = ustorage_fs_min_len(sc, sc->sc_cbw->CBWCDB[4], -1U); 1799 if (error) { 1800 break; 1801 } 1802 error = ustorage_fs_check_cmd(sc, 6, 1803 (1UL << 4) | 1, 0); 1804 if (error) { 1805 break; 1806 } 1807 error = ustorage_fs_request_sense(sc); 1808 1809 break; 1810 1811 case SC_START_STOP_UNIT: 1812 error = ustorage_fs_min_len(sc, 0, -1U); 1813 if (error) { 1814 break; 1815 } 1816 error = ustorage_fs_check_cmd(sc, 6, 1817 (1UL << 1) | (1UL << 4) | 1, 0); 1818 if (error) { 1819 break; 1820 } 1821 error = ustorage_fs_start_stop(sc); 1822 1823 break; 1824 1825 case SC_SYNCHRONIZE_CACHE: 1826 error = ustorage_fs_min_len(sc, 0, -1U); 1827 if (error) { 1828 break; 1829 } 1830 error = ustorage_fs_check_cmd(sc, 10, 1831 (0xfUL << 2) | (3UL << 7) | 1, 1); 1832 if (error) { 1833 break; 1834 } 1835 error = ustorage_fs_synchronize_cache(sc); 1836 1837 break; 1838 1839 case SC_TEST_UNIT_READY: 1840 error = ustorage_fs_min_len(sc, 0, -1U); 1841 if (error) { 1842 break; 1843 } 1844 error = ustorage_fs_check_cmd(sc, 6, 1845 0 | 1, 1); 1846 break; 1847 1848 /* 1849 * Although optional, this command is used by MS-Windows. 1850 * We support a minimal version: BytChk must be 0. 1851 */ 1852 case SC_VERIFY: 1853 error = ustorage_fs_min_len(sc, 0, -1U); 1854 if (error) { 1855 break; 1856 } 1857 error = ustorage_fs_check_cmd(sc, 10, 1858 (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1); 1859 if (error) { 1860 break; 1861 } 1862 error = ustorage_fs_verify(sc); 1863 1864 break; 1865 1866 case SC_WRITE_6: 1867 i = sc->sc_cbw->CBWCDB[4]; 1868 sc->sc_transfer.cmd_dir = DIR_READ; 1869 temp = ((i == 0) ? 256UL : i); 1870 error = ustorage_fs_min_len(sc, temp << 9, mask9); 1871 if (error) { 1872 break; 1873 } 1874 error = ustorage_fs_check_cmd(sc, 6, 1875 (7UL << 1) | (1UL << 4) | 1, 1); 1876 if (error) { 1877 break; 1878 } 1879 error = ustorage_fs_write(sc); 1880 1881 break; 1882 1883 case SC_WRITE_10: 1884 sc->sc_transfer.cmd_dir = DIR_READ; 1885 temp = get_be16(&sc->sc_cbw->CBWCDB[7]); 1886 error = ustorage_fs_min_len(sc, temp << 9, mask9); 1887 if (error) { 1888 break; 1889 } 1890 error = ustorage_fs_check_cmd(sc, 10, 1891 (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1); 1892 if (error) { 1893 break; 1894 } 1895 error = ustorage_fs_write(sc); 1896 1897 break; 1898 1899 case SC_WRITE_12: 1900 sc->sc_transfer.cmd_dir = DIR_READ; 1901 temp = get_be32(&sc->sc_cbw->CBWCDB[6]); 1902 if (temp > (mask9 >> 9)) { 1903 /* numerical overflow */ 1904 sc->sc_csw->bCSWStatus = CSWSTATUS_FAILED; 1905 error = 1; 1906 break; 1907 } 1908 error = ustorage_fs_min_len(sc, temp << 9, mask9); 1909 if (error) { 1910 break; 1911 } 1912 error = ustorage_fs_check_cmd(sc, 12, 1913 (1UL << 1) | (0xfUL << 2) | (0xfUL << 6) | 1, 1); 1914 if (error) { 1915 break; 1916 } 1917 error = ustorage_fs_write(sc); 1918 1919 break; 1920 1921 /* 1922 * Some mandatory commands that we recognize but don't 1923 * implement. They don't mean much in this setting. 1924 * It's left as an exercise for anyone interested to 1925 * implement RESERVE and RELEASE in terms of Posix 1926 * locks. 1927 */ 1928 case SC_FORMAT_UNIT: 1929 case SC_RELEASE: 1930 case SC_RESERVE: 1931 case SC_SEND_DIAGNOSTIC: 1932 /* Fallthrough */ 1933 1934 default: 1935 error = ustorage_fs_min_len(sc, 0, -1U); 1936 if (error) { 1937 break; 1938 } 1939 error = ustorage_fs_check_cmd(sc, sc->sc_transfer.cmd_len, 1940 0xff, 0); 1941 if (error) { 1942 break; 1943 } 1944 sc->sc_transfer.currlun->sense_data = 1945 SS_INVALID_COMMAND; 1946 error = 1; 1947 1948 break; 1949 } 1950 return (error); 1951} 1952