ustorage_fs.c revision 235000
1139743Simp/* $FreeBSD: stable/9/sys/dev/usb/storage/ustorage_fs.c 235000 2012-05-04 15:05:30Z hselasky $ */ 265577Sdes/*- 365577Sdes * Copyright (C) 2003-2005 Alan Stern 459412Smsmith * Copyright (C) 2008 Hans Petter Selasky 559412Smsmith * All rights reserved. 659412Smsmith * 759412Smsmith * Redistribution and use in source and binary forms, with or without 859412Smsmith * modification, are permitted provided that the following conditions 959412Smsmith * are met: 1059412Smsmith * 1. Redistributions of source code must retain the above copyright 1159412Smsmith * notice, this list of conditions, and the following disclaimer, 1259412Smsmith * without modification. 1359412Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1459412Smsmith * notice, this list of conditions and the following disclaimer in the 1559412Smsmith * documentation and/or other materials provided with the distribution. 1659412Smsmith * 3. The names of the above-listed copyright holders may not be used 1759412Smsmith * to endorse or promote products derived from this software without 1859412Smsmith * specific prior written permission. 1959412Smsmith * 2059412Smsmith * 2159412Smsmith * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 2259412Smsmith * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 2359412Smsmith * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2459412Smsmith * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 2559412Smsmith * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2659412Smsmith * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2759412Smsmith * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2859412Smsmith * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2959412Smsmith * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3059412Smsmith * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3159412Smsmith * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3259412Smsmith */ 3359412Smsmith 3459412Smsmith/* 3559412Smsmith * NOTE: Much of the SCSI statemachine handling code derives from the 3659412Smsmith * Linux USB gadget stack. 3759412Smsmith */ 3859412Smsmith 3959412Smsmith#include <sys/stdint.h> 4059412Smsmith#include <sys/stddef.h> 4159412Smsmith#include <sys/param.h> 42116173Sobrien#include <sys/queue.h> 43116173Sobrien#include <sys/types.h> 44116173Sobrien#include <sys/systm.h> 4559412Smsmith#include <sys/kernel.h> 4683926Sdes#include <sys/bus.h> 4776166Smarkm#include <sys/module.h> 4874135Sjlemon#include <sys/lock.h> 4983926Sdes#include <sys/mutex.h> 50119911Sdes#include <sys/condvar.h> 5176166Smarkm#include <sys/sysctl.h> 5265633Sdes#include <sys/sx.h> 5383926Sdes#include <sys/unistd.h> 5476166Smarkm#include <sys/callout.h> 5574135Sjlemon#include <sys/malloc.h> 5678025Sdes#include <sys/priv.h> 57168067Sjkim 5876827Salfred#include <dev/usb/usb.h> 5985289Sdes#include <dev/usb/usbdi.h> 6065633Sdes#include "usbdevs.h" 6165633Sdes#include "usb_if.h" 6269995Sdes 63168067Sjkim#define USB_DEBUG_VAR ustorage_fs_debug 64123246Sdes#include <dev/usb/usb_debug.h> 6583926Sdes 6676839Sjlemon#ifdef USB_DEBUG 6783926Sdesstatic int ustorage_fs_debug = 0; 68159995Snetchild 6965633SdesSYSCTL_NODE(_hw_usb, OID_AUTO, ustorage_fs, CTLFLAG_RW, 0, "USB ustorage_fs"); 7083926SdesSYSCTL_INT(_hw_usb_ustorage_fs, OID_AUTO, debug, CTLFLAG_RW, 7183926Sdes &ustorage_fs_debug, 0, "ustorage_fs debug level"); 7259412Smsmith#endif 7359412Smsmith 7483926Sdes/* Define some limits */ 7583926Sdes 7659412Smsmith#ifndef USTORAGE_FS_BULK_SIZE 7759412Smsmith#define USTORAGE_FS_BULK_SIZE (1UL << 17) /* bytes */ 7867588Sdes#endif 7959412Smsmith 8060860Sdes#ifndef USTORAGE_FS_MAX_LUN 8159412Smsmith#define USTORAGE_FS_MAX_LUN 8 /* units */ 8269799Sdes#endif 8367589Sdes 8478113Sdes#ifndef USTORAGE_QDATA_MAX 85133822Stjr#define USTORAGE_QDATA_MAX 40 /* bytes */ 8667589Sdes#endif 8759412Smsmith 88133822Stjr#define sc_cmd_data sc_cbw.CBWCDB 8959412Smsmith 90133822Stjr/* 91140214Sobrien * The SCSI ID string must be exactly 28 characters long 92140214Sobrien * exluding the terminating zero. 93140214Sobrien */ 9487275Srwatson#ifndef USTORAGE_FS_ID_STRING 95133822Stjr#define USTORAGE_FS_ID_STRING \ 9685129Sdes "FreeBSD " /* 8 */ \ 9769995Sdes "File-Stor Gadget" /* 16 */ \ 9885289Sdes "0101" /* 4 */ 9978025Sdes#endif 10084248Sdes 10159412Smsmith/* 10267588Sdes * The following macro defines the number of 10367588Sdes * sectors to be allocated for the RAM disk: 10467588Sdes */ 10576405Sdes#ifndef USTORAGE_FS_RAM_SECT 10667588Sdes#define USTORAGE_FS_RAM_SECT (1UL << 13) 10767588Sdes#endif 10869799Sdes 10967588Sdesstatic uint8_t *ustorage_fs_ramdisk; 11067588Sdes 11174135Sjlemon/* USB transfer definitions */ 112159995Snetchild 113159995Snetchild#define USTORAGE_FS_T_BBB_COMMAND 0 114159995Snetchild#define USTORAGE_FS_T_BBB_DATA_DUMP 1 115159995Snetchild#define USTORAGE_FS_T_BBB_DATA_READ 2 116159995Snetchild#define USTORAGE_FS_T_BBB_DATA_WRITE 3 117159995Snetchild#define USTORAGE_FS_T_BBB_STATUS 4 118159995Snetchild#define USTORAGE_FS_T_BBB_MAX 5 119159995Snetchild 120159995Snetchild/* USB data stage direction */ 121159995Snetchild 122159995Snetchild#define DIR_NONE 0 123159995Snetchild#define DIR_READ 1 124159995Snetchild#define DIR_WRITE 2 125159995Snetchild 126166140Snetchild/* USB interface specific control request */ 127159995Snetchild 12878113Sdes#define UR_BBB_RESET 0xff /* Bulk-Only reset */ 12978113Sdes#define UR_BBB_GET_MAX_LUN 0xfe /* Get maximum lun */ 13078113Sdes 13178025Sdes/* Command Block Wrapper */ 13278025Sdestypedef struct { 13359412Smsmith uDWord dCBWSignature; 13459412Smsmith#define CBWSIGNATURE 0x43425355 13559412Smsmith uDWord dCBWTag; 13659412Smsmith uDWord dCBWDataTransferLength; 13759412Smsmith uByte bCBWFlags; 13859412Smsmith#define CBWFLAGS_OUT 0x00 139113574Sjhb#define CBWFLAGS_IN 0x80 140113574Sjhb uByte bCBWLUN; 141113574Sjhb uByte bCDBLength; 14260860Sdes#define CBWCDBLENGTH 16 143117723Sphk uByte CBWCDB[CBWCDBLENGTH]; 14459412Smsmith} __packed ustorage_fs_bbb_cbw_t; 14559412Smsmith 14659412Smsmith#define USTORAGE_FS_BBB_CBW_SIZE 31 14759412Smsmith 14859412Smsmith/* Command Status Wrapper */ 149170170Sattiliotypedef struct { 15059412Smsmith uDWord dCSWSignature; 15159412Smsmith#define CSWSIGNATURE 0x53425355 15259412Smsmith uDWord dCSWTag; 15359412Smsmith uDWord dCSWDataResidue; 15459412Smsmith uByte bCSWStatus; 15559412Smsmith#define CSWSTATUS_GOOD 0x0 156170170Sattilio#define CSWSTATUS_FAILED 0x1 15759412Smsmith#define CSWSTATUS_PHASE 0x2 158117723Sphk} __packed ustorage_fs_bbb_csw_t; 159153310Smlaier 160153310Smlaier#define USTORAGE_FS_BBB_CSW_SIZE 13 161117723Sphk 16260860Sdesstruct ustorage_fs_lun { 163124082Salc 16471471Sjhb uint8_t *memory_image; 16560860Sdes 16660860Sdes uint32_t num_sectors; 167124082Salc uint32_t sense_data; 16860860Sdes uint32_t sense_data_info; 16959412Smsmith uint32_t unit_attention_data; 17059412Smsmith 17159412Smsmith uint8_t read_only:1; 17259412Smsmith uint8_t prevent_medium_removal:1; 17359412Smsmith uint8_t info_valid:1; 17459412Smsmith uint8_t removable:1; 17559412Smsmith}; 17659412Smsmith 17759412Smsmithstruct ustorage_fs_softc { 178170170Sattilio 17959412Smsmith ustorage_fs_bbb_cbw_t sc_cbw; /* Command Wrapper Block */ 18078025Sdes ustorage_fs_bbb_csw_t sc_csw; /* Command Status Block */ 18178031Sdes 18269799Sdes struct mtx sc_mtx; 18376839Sjlemon 18469799Sdes struct ustorage_fs_lun sc_lun[USTORAGE_FS_MAX_LUN]; 18569799Sdes 18669799Sdes struct { 18769799Sdes uint8_t *data_ptr; 18869799Sdes struct ustorage_fs_lun *currlun; 18976839Sjlemon 19076839Sjlemon uint32_t data_rem; /* bytes, as reported by the command 19169799Sdes * block wrapper */ 19269799Sdes uint32_t offset; /* bytes */ 19369799Sdes 19469799Sdes uint8_t cbw_dir; 19569799Sdes uint8_t cmd_dir; 19659412Smsmith uint8_t lun; 19778025Sdes uint8_t cmd_len; 19859412Smsmith uint8_t data_short:1; 19959412Smsmith uint8_t data_error:1; 200133822Stjr } sc_transfer; 20178113Sdes 202133822Stjr device_t sc_dev; 20378113Sdes struct usb_device *sc_udev; 20478113Sdes struct usb_xfer *sc_xfer[USTORAGE_FS_T_BBB_MAX]; 20578113Sdes 20678113Sdes uint8_t sc_iface_no; /* interface number */ 207159544Sdes uint8_t sc_last_lun; 208159544Sdes uint8_t sc_last_xfer_index; 209159544Sdes uint8_t sc_qdata[USTORAGE_QDATA_MAX]; 210123246Sdes}; 211118421Sdes 21259412Smsmith/* prototypes */ 21369799Sdes 21478031Sdesstatic device_probe_t ustorage_fs_probe; 21578031Sdesstatic device_attach_t ustorage_fs_attach; 21669799Sdesstatic device_detach_t ustorage_fs_detach; 21778031Sdesstatic device_suspend_t ustorage_fs_suspend; 21878031Sdesstatic device_resume_t ustorage_fs_resume; 21978031Sdesstatic usb_handle_request_t ustorage_fs_handle_request; 22078031Sdes 22178031Sdesstatic usb_callback_t ustorage_fs_t_bbb_command_callback; 22278031Sdesstatic usb_callback_t ustorage_fs_t_bbb_data_dump_callback; 22378031Sdesstatic usb_callback_t ustorage_fs_t_bbb_data_read_callback; 22467589Sdesstatic usb_callback_t ustorage_fs_t_bbb_data_write_callback; 22567589Sdesstatic usb_callback_t ustorage_fs_t_bbb_status_callback; 22667589Sdes 22759412Smsmithstatic void ustorage_fs_transfer_start(struct ustorage_fs_softc *sc, uint8_t xfer_index); 228133822Stjrstatic void ustorage_fs_transfer_stop(struct ustorage_fs_softc *sc); 22959412Smsmith 23067589Sdesstatic uint8_t ustorage_fs_verify(struct ustorage_fs_softc *sc); 23159412Smsmithstatic uint8_t ustorage_fs_inquiry(struct ustorage_fs_softc *sc); 23259412Smsmithstatic uint8_t ustorage_fs_request_sense(struct ustorage_fs_softc *sc); 23367589Sdesstatic uint8_t ustorage_fs_read_capacity(struct ustorage_fs_softc *sc); 23459412Smsmithstatic uint8_t ustorage_fs_mode_sense(struct ustorage_fs_softc *sc); 23559412Smsmithstatic uint8_t ustorage_fs_start_stop(struct ustorage_fs_softc *sc); 23667589Sdesstatic uint8_t ustorage_fs_prevent_allow(struct ustorage_fs_softc *sc); 23759412Smsmithstatic uint8_t ustorage_fs_read_format_capacities(struct ustorage_fs_softc *sc); 23859412Smsmithstatic uint8_t ustorage_fs_mode_select(struct ustorage_fs_softc *sc); 23967589Sdesstatic uint8_t ustorage_fs_min_len(struct ustorage_fs_softc *sc, uint32_t len, uint32_t mask); 24059412Smsmithstatic uint8_t ustorage_fs_read(struct ustorage_fs_softc *sc); 24159412Smsmithstatic uint8_t ustorage_fs_write(struct ustorage_fs_softc *sc); 24267589Sdesstatic uint8_t ustorage_fs_check_cmd(struct ustorage_fs_softc *sc, uint8_t cmd_size, uint16_t mask, uint8_t needs_medium); 24359412Smsmithstatic uint8_t ustorage_fs_do_cmd(struct ustorage_fs_softc *sc); 24459412Smsmith 24578031Sdesstatic device_method_t ustorage_fs_methods[] = { 24659412Smsmith /* USB interface */ 247159170Sdes DEVMETHOD(usb_handle_request, ustorage_fs_handle_request), 248133822Stjr 249159170Sdes /* Device interface */ 250133822Stjr DEVMETHOD(device_probe, ustorage_fs_probe), 251133822Stjr DEVMETHOD(device_attach, ustorage_fs_attach), 25259412Smsmith DEVMETHOD(device_detach, ustorage_fs_detach), 25359412Smsmith DEVMETHOD(device_suspend, ustorage_fs_suspend), 254159544Sdes DEVMETHOD(device_resume, ustorage_fs_resume), 255159544Sdes 256159544Sdes {0, 0} 257159544Sdes}; 258159544Sdes 259159544Sdesstatic driver_t ustorage_fs_driver = { 260123246Sdes .name = "ustorage_fs", 261118421Sdes .methods = ustorage_fs_methods, 262118421Sdes .size = sizeof(struct ustorage_fs_softc), 263118421Sdes}; 264118421Sdes 265118421Sdesstatic devclass_t ustorage_fs_devclass; 266159544Sdes 267118421SdesDRIVER_MODULE(ustorage_fs, uhub, ustorage_fs_driver, ustorage_fs_devclass, NULL, 0); 268159544SdesMODULE_VERSION(ustorage_fs, 0); 269159544SdesMODULE_DEPEND(ustorage_fs, usb, 1, 1, 1); 270118421Sdes 27159412Smsmithstatic struct usb_config ustorage_fs_bbb_config[USTORAGE_FS_T_BBB_MAX] = { 27278031Sdes 27378031Sdes [USTORAGE_FS_T_BBB_COMMAND] = { 27467589Sdes .type = UE_BULK, 27578031Sdes .endpoint = UE_ADDR_ANY, 27667589Sdes .direction = UE_DIR_OUT, 27778031Sdes .bufsize = sizeof(ustorage_fs_bbb_cbw_t), 27867589Sdes .flags = {.ext_buffer = 1,}, 27978031Sdes .callback = &ustorage_fs_t_bbb_command_callback, 280119068Sdes .usb_mode = USB_MODE_DEVICE, 28178031Sdes }, 28267589Sdes 28378025Sdes [USTORAGE_FS_T_BBB_DATA_DUMP] = { 28478025Sdes .type = UE_BULK, 28578031Sdes .endpoint = UE_ADDR_ANY, 28669799Sdes .direction = UE_DIR_OUT, 28769799Sdes .bufsize = 0, /* use wMaxPacketSize */ 28878025Sdes .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,}, 28969799Sdes .callback = &ustorage_fs_t_bbb_data_dump_callback, 29069799Sdes .usb_mode = USB_MODE_DEVICE, 29169799Sdes }, 29278031Sdes 29369995Sdes [USTORAGE_FS_T_BBB_DATA_READ] = { 29478025Sdes .type = UE_BULK, 29559412Smsmith .endpoint = UE_ADDR_ANY, 296133822Stjr .direction = UE_DIR_OUT, 29765633Sdes .bufsize = USTORAGE_FS_BULK_SIZE, 29878113Sdes .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer = 1}, 29985289Sdes .callback = &ustorage_fs_t_bbb_data_read_callback, 30085289Sdes .usb_mode = USB_MODE_DEVICE, 30185289Sdes }, 30285289Sdes 30385289Sdes [USTORAGE_FS_T_BBB_DATA_WRITE] = { 30485289Sdes .type = UE_BULK, 30585289Sdes .endpoint = UE_ADDR_ANY, 30685289Sdes .direction = UE_DIR_IN, 30785289Sdes .bufsize = USTORAGE_FS_BULK_SIZE, 30885289Sdes .flags = {.proxy_buffer = 1,.short_xfer_ok = 1,.ext_buffer = 1}, 30991334Sjulian .callback = &ustorage_fs_t_bbb_data_write_callback, 31091334Sjulian .usb_mode = USB_MODE_DEVICE, 31185289Sdes }, 31285289Sdes 31385289Sdes [USTORAGE_FS_T_BBB_STATUS] = { 31485289Sdes .type = UE_BULK, 315168942Sdes .endpoint = UE_ADDR_ANY, 31685289Sdes .direction = UE_DIR_IN, 317168942Sdes .bufsize = sizeof(ustorage_fs_bbb_csw_t), 318168942Sdes .flags = {.short_xfer_ok = 1,.ext_buffer = 1,}, 319168942Sdes .callback = &ustorage_fs_t_bbb_status_callback, 32085289Sdes .usb_mode = USB_MODE_DEVICE, 32191334Sjulian }, 32291334Sjulian}; 32385289Sdes 324119068Sdes/* 32585289Sdes * USB device probe/attach/detach 32685289Sdes */ 32785289Sdes 32885289Sdesstatic int 32985289Sdesustorage_fs_probe(device_t dev) 330119068Sdes{ 33185289Sdes struct usb_attach_arg *uaa = device_get_ivars(dev); 33285289Sdes struct usb_interface_descriptor *id; 33385289Sdes 33485289Sdes if (uaa->usb_mode != USB_MODE_DEVICE) { 33585289Sdes return (ENXIO); 33685289Sdes } 33785289Sdes /* Check for a standards compliant device */ 33885289Sdes id = usbd_get_interface_descriptor(uaa->iface); 33985289Sdes if ((id == NULL) || 34085289Sdes (id->bInterfaceClass != UICLASS_MASS) || 34185289Sdes (id->bInterfaceSubClass != UISUBCLASS_SCSI) || 34285289Sdes (id->bInterfaceProtocol != UIPROTO_MASS_BBB)) { 343119068Sdes return (ENXIO); 344158311Sambrisko } 345158311Sambrisko return (BUS_PROBE_GENERIC); 346158311Sambrisko} 347158311Sambrisko 348158311Sambriskostatic int 349158311Sambriskoustorage_fs_attach(device_t dev) 350158311Sambrisko{ 35185289Sdes struct ustorage_fs_softc *sc = device_get_softc(dev); 35285289Sdes struct usb_attach_arg *uaa = device_get_ivars(dev); 35385289Sdes struct usb_interface_descriptor *id; 35485289Sdes int err; 35585289Sdes int unit; 35685289Sdes 35785289Sdes /* 35885289Sdes * NOTE: the softc struct is cleared in device_set_driver. 35985289Sdes * We can safely call ustorage_fs_detach without specifically 36085289Sdes * initializing the struct. 36185289Sdes */ 36285289Sdes 36385289Sdes sc->sc_dev = dev; 36485289Sdes sc->sc_udev = uaa->device; 36585289Sdes unit = device_get_unit(dev); 36685289Sdes 36785289Sdes /* enable power saving mode */ 36885289Sdes usbd_set_power_mode(uaa->device, USB_POWER_MODE_SAVE); 36985289Sdes 37085289Sdes if (unit == 0) { 37185289Sdes if (ustorage_fs_ramdisk == NULL) { 37278113Sdes /* 37378113Sdes * allocate a memory image for our ramdisk until 37478025Sdes * further 37578025Sdes */ 37665633Sdes ustorage_fs_ramdisk = 377123246Sdes malloc(USTORAGE_FS_RAM_SECT << 9, M_USB, 378120339Sdes M_ZERO | M_WAITOK); 379120339Sdes 380120339Sdes if (ustorage_fs_ramdisk == NULL) { 381120339Sdes return (ENOMEM); 382120339Sdes } 383120339Sdes } 384143194Ssobomax sc->sc_lun[0].memory_image = ustorage_fs_ramdisk; 385143194Ssobomax sc->sc_lun[0].num_sectors = USTORAGE_FS_RAM_SECT; 386143194Ssobomax sc->sc_lun[0].removable = 1; 387143194Ssobomax } 388143194Ssobomax 389143194Ssobomax device_set_usb_desc(dev); 39078025Sdes 39169799Sdes mtx_init(&sc->sc_mtx, "USTORAGE_FS lock", 39269799Sdes NULL, (MTX_DEF | MTX_RECURSE)); 39369799Sdes 39469799Sdes /* get interface index */ 39569799Sdes 39685657Sdillon id = usbd_get_interface_descriptor(uaa->iface); 397170170Sattilio if (id == NULL) { 398170170Sattilio device_printf(dev, "failed to get " 399170170Sattilio "interface number\n"); 400170170Sattilio goto detach; 401170170Sattilio } 402170170Sattilio sc->sc_iface_no = id->bInterfaceNumber; 403113574Sjhb 40478025Sdes err = usbd_transfer_setup(uaa->device, 40565633Sdes &uaa->info.bIfaceIndex, sc->sc_xfer, ustorage_fs_bbb_config, 40665633Sdes USTORAGE_FS_T_BBB_MAX, sc, &sc->sc_mtx); 40778113Sdes if (err) { 40878113Sdes device_printf(dev, "could not setup required " 40978113Sdes "transfers, %s\n", usbd_errstr(err)); 41078025Sdes goto detach; 41178025Sdes } 41265633Sdes /* start Mass Storage State Machine */ 41365633Sdes 41465633Sdes mtx_lock(&sc->sc_mtx); 41565633Sdes ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_COMMAND); 41685657Sdillon mtx_unlock(&sc->sc_mtx); 417113574Sjhb 41869799Sdes return (0); /* success */ 41978025Sdes 42065633Sdesdetach: 42165633Sdes ustorage_fs_detach(dev); 42278113Sdes return (ENXIO); /* failure */ 423167159Sjkim} 424167159Sjkim 425167159Sjkimstatic int 426167159Sjkimustorage_fs_detach(device_t dev) 427167159Sjkim{ 428167159Sjkim struct ustorage_fs_softc *sc = device_get_softc(dev); 429167159Sjkim 430167159Sjkim /* teardown our statemachine */ 431167159Sjkim 432167159Sjkim usbd_transfer_unsetup(sc->sc_xfer, USTORAGE_FS_T_BBB_MAX); 433167159Sjkim 434167159Sjkim mtx_destroy(&sc->sc_mtx); 435167159Sjkim 436167159Sjkim return (0); /* success */ 437167159Sjkim} 438167159Sjkim 439167159Sjkimstatic int 440167159Sjkimustorage_fs_suspend(device_t dev) 441167159Sjkim{ 442167159Sjkim device_printf(dev, "suspending\n"); 443167159Sjkim return (0); /* success */ 444167159Sjkim} 445167159Sjkim 446167159Sjkimstatic int 447167159Sjkimustorage_fs_resume(device_t dev) 448167159Sjkim{ 449167159Sjkim device_printf(dev, "resuming\n"); 450167159Sjkim return (0); /* success */ 451167159Sjkim} 452167159Sjkim 453167159Sjkim/* 454168762Sdes * Generic functions to handle transfers 455167159Sjkim */ 456167159Sjkim 457167159Sjkimstatic void 458167159Sjkimustorage_fs_transfer_start(struct ustorage_fs_softc *sc, uint8_t xfer_index) 459167159Sjkim{ 460167159Sjkim if (sc->sc_xfer[xfer_index]) { 461167159Sjkim sc->sc_last_xfer_index = xfer_index; 462167159Sjkim usbd_transfer_start(sc->sc_xfer[xfer_index]); 463167159Sjkim } 464167159Sjkim} 465167159Sjkim 466167159Sjkimstatic void 467167159Sjkimustorage_fs_transfer_stop(struct ustorage_fs_softc *sc) 468167159Sjkim{ 469168762Sdes usbd_transfer_stop(sc->sc_xfer[sc->sc_last_xfer_index]); 470167159Sjkim mtx_unlock(&sc->sc_mtx); 471167159Sjkim usbd_transfer_drain(sc->sc_xfer[sc->sc_last_xfer_index]); 472167159Sjkim mtx_lock(&sc->sc_mtx); 473167159Sjkim} 47478113Sdes 47578113Sdesstatic int 47678025Sdesustorage_fs_handle_request(device_t dev, 47778025Sdes const void *preq, void **pptr, uint16_t *plen, 47865633Sdes uint16_t offset, uint8_t *pstate) 47987275Srwatson{ 48087275Srwatson struct ustorage_fs_softc *sc = device_get_softc(dev); 48187275Srwatson const struct usb_device_request *req = preq; 482112206Sjhb uint8_t is_complete = *pstate; 483112206Sjhb 484167159Sjkim if (!is_complete) { 485167159Sjkim if ((req->bmRequestType == UT_WRITE_CLASS_INTERFACE) && 486167159Sjkim (req->bRequest == UR_BBB_RESET)) { 487167159Sjkim *plen = 0; 488167159Sjkim mtx_lock(&sc->sc_mtx); 48987275Srwatson ustorage_fs_transfer_stop(sc); 49078025Sdes sc->sc_transfer.data_error = 1; 49165633Sdes ustorage_fs_transfer_start(sc, 49265633Sdes USTORAGE_FS_T_BBB_COMMAND); 49378113Sdes mtx_unlock(&sc->sc_mtx); 49478113Sdes return (0); 49578113Sdes } else if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) && 49678025Sdes (req->bRequest == UR_BBB_GET_MAX_LUN)) { 49778025Sdes if (offset == 0) { 49876839Sjlemon *plen = 1; 499168762Sdes *pptr = &sc->sc_last_lun; 50078025Sdes } else { 50176839Sjlemon *plen = 0; 50276839Sjlemon } 50376839Sjlemon return (0); 50476839Sjlemon } 50576839Sjlemon } 50676839Sjlemon return (ENXIO); /* use builtin handler */ 50776839Sjlemon} 50876839Sjlemon 50976839Sjlemonstatic void 51078116Sdesustorage_fs_t_bbb_command_callback(struct usb_xfer *xfer, usb_error_t error) 51176839Sjlemon{ 51278025Sdes struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer); 51376839Sjlemon uint32_t tag; 51476839Sjlemon uint8_t err = 0; 51578113Sdes 51678113Sdes DPRINTF("\n"); 51778113Sdes 51878025Sdes switch (USB_GET_STATE(xfer)) { 51978025Sdes case USB_ST_TRANSFERRED: 52067588Sdes 52169995Sdes tag = UGETDW(sc->sc_cbw.dCBWSignature); 522166140Snetchild 523166140Snetchild if (tag != CBWSIGNATURE) { 52467588Sdes /* do nothing */ 52594307Sjhb DPRINTF("invalid signature 0x%08x\n", tag); 52669995Sdes break; 52778025Sdes } 52878025Sdes tag = UGETDW(sc->sc_cbw.dCBWTag); 52967588Sdes 530166140Snetchild /* echo back tag */ 531166140Snetchild USETDW(sc->sc_csw.dCSWTag, tag); 532166140Snetchild 533166141Snetchild /* reset status */ 534166162Snetchild sc->sc_csw.bCSWStatus = 0; 535166162Snetchild 536166141Snetchild /* reset data offset, data length and data remainder */ 537166141Snetchild sc->sc_transfer.offset = 0; 538166140Snetchild sc->sc_transfer.data_rem = 539166140Snetchild UGETDW(sc->sc_cbw.dCBWDataTransferLength); 540166140Snetchild 54173923Sjhb /* reset data flags */ 54267588Sdes sc->sc_transfer.data_short = 0; 54367588Sdes 54491140Stanimura /* extract LUN */ 54567588Sdes sc->sc_transfer.lun = sc->sc_cbw.bCBWLUN; 546159995Snetchild 54767588Sdes if (sc->sc_transfer.data_rem == 0) { 548159995Snetchild sc->sc_transfer.cbw_dir = DIR_NONE; 549159995Snetchild } else { 550159995Snetchild if (sc->sc_cbw.bCBWFlags & CBWFLAGS_IN) { 551159995Snetchild sc->sc_transfer.cbw_dir = DIR_WRITE; 552159995Snetchild } else { 553159995Snetchild sc->sc_transfer.cbw_dir = DIR_READ; 554159995Snetchild } 555159995Snetchild } 556159995Snetchild 557159995Snetchild sc->sc_transfer.cmd_len = sc->sc_cbw.bCDBLength; 558159995Snetchild if ((sc->sc_transfer.cmd_len > sizeof(sc->sc_cbw.CBWCDB)) || 559159995Snetchild (sc->sc_transfer.cmd_len == 0)) { 560159995Snetchild /* just halt - this is invalid */ 561159995Snetchild DPRINTF("invalid command length %d bytes\n", 562159995Snetchild sc->sc_transfer.cmd_len); 563159995Snetchild break; 564159995Snetchild } 565159995Snetchild 566159995Snetchild err = ustorage_fs_do_cmd(sc); 56769995Sdes if (err) { 56867588Sdes /* got an error */ 56967588Sdes DPRINTF("command failed\n"); 570159995Snetchild break; 571159995Snetchild } 572159995Snetchild if ((sc->sc_transfer.data_rem > 0) && 573159995Snetchild (sc->sc_transfer.cbw_dir != sc->sc_transfer.cmd_dir)) { 574159995Snetchild /* contradicting data transfer direction */ 575159995Snetchild err = 1; 57667588Sdes DPRINTF("data direction mismatch\n"); 577159995Snetchild break; 578159995Snetchild } 57969799Sdes switch (sc->sc_transfer.cbw_dir) { 580159995Snetchild case DIR_READ: 581159995Snetchild ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_DATA_READ); 582159995Snetchild break; 58367588Sdes case DIR_WRITE: 58478025Sdes ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_DATA_WRITE); 585119068Sdes break; 58678025Sdes default: 58767588Sdes ustorage_fs_transfer_start(sc, 58867588Sdes USTORAGE_FS_T_BBB_STATUS); 58967588Sdes break; 590119911Sdes } 591119911Sdes break; 592119911Sdes 593119911Sdes case USB_ST_SETUP: 594119911Sdestr_setup: 595119911Sdes if (sc->sc_transfer.data_error) { 596119911Sdes sc->sc_transfer.data_error = 0; 597120340Sdes usbd_xfer_set_stall(xfer); 598119911Sdes DPRINTF("stall pipe\n"); 599119911Sdes } 600119911Sdes 601119911Sdes usbd_xfer_set_frame_data(xfer, 0, &sc->sc_cbw, 602119911Sdes sizeof(sc->sc_cbw)); 603119911Sdes usbd_transfer_submit(xfer); 604119911Sdes break; 605119911Sdes 606119911Sdes default: /* Error */ 607119911Sdes DPRINTF("error\n"); 608119911Sdes if (error == USB_ERR_CANCELLED) { 609119911Sdes break; 610119911Sdes } 611119911Sdes /* If the pipe is already stalled, don't do another stall */ 612119911Sdes if (!usbd_xfer_is_stalled(xfer)) 613119911Sdes sc->sc_transfer.data_error = 1; 614119911Sdes 615119911Sdes /* try again */ 616119911Sdes goto tr_setup; 617119911Sdes } 618119911Sdes if (err) { 619119911Sdes if (sc->sc_csw.bCSWStatus == 0) { 620119911Sdes /* set some default error code */ 62178113Sdes sc->sc_csw.bCSWStatus = CSWSTATUS_FAILED; 62278113Sdes } 62378025Sdes if (sc->sc_transfer.cbw_dir == DIR_READ) { 62478025Sdes /* dump all data */ 62567588Sdes ustorage_fs_transfer_start(sc, 62669995Sdes USTORAGE_FS_T_BBB_DATA_DUMP); 62767588Sdes return; 62869799Sdes } 62999072Sjulian if (sc->sc_transfer.cbw_dir == DIR_WRITE) { 630114983Sjhb /* need to stall before status */ 63174135Sjlemon sc->sc_transfer.data_error = 1; 63267588Sdes } 633113611Sjhb ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_STATUS); 63499072Sjulian } 63599072Sjulian} 63699072Sjulian 63799072Sjulianstatic void 63899072Sjulianustorage_fs_t_bbb_data_dump_callback(struct usb_xfer *xfer, usb_error_t error) 639113611Sjhb{ 64099072Sjulian struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer); 64199072Sjulian uint32_t max_bulk = usbd_xfer_max_len(xfer); 64299072Sjulian int actlen, sumlen; 64399072Sjulian 64499072Sjulian usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); 64599072Sjulian 64699072Sjulian DPRINTF("\n"); 64799072Sjulian 64899072Sjulian switch (USB_GET_STATE(xfer)) { 64999072Sjulian case USB_ST_TRANSFERRED: 650103216Sjulian sc->sc_transfer.data_rem -= actlen; 65199072Sjulian sc->sc_transfer.offset += actlen; 65299072Sjulian 65399072Sjulian if (actlen != sumlen || sc->sc_transfer.data_rem == 0) { 65499072Sjulian /* short transfer or end of data */ 65599072Sjulian ustorage_fs_transfer_start(sc, 65699072Sjulian USTORAGE_FS_T_BBB_STATUS); 65799072Sjulian break; 65899072Sjulian } 65999072Sjulian /* Fallthrough */ 66099072Sjulian 66199072Sjulian case USB_ST_SETUP: 66299072Sjuliantr_setup: 66399072Sjulian if (max_bulk > sc->sc_transfer.data_rem) { 66499072Sjulian max_bulk = sc->sc_transfer.data_rem; 66599072Sjulian } 66699072Sjulian if (sc->sc_transfer.data_error) { 66799072Sjulian sc->sc_transfer.data_error = 0; 66899072Sjulian usbd_xfer_set_stall(xfer); 669113611Sjhb } 67099072Sjulian usbd_xfer_set_frame_len(xfer, 0, max_bulk); 67167588Sdes usbd_transfer_submit(xfer); 67269995Sdes break; 67378025Sdes 67478031Sdes default: /* Error */ 67567588Sdes if (error == USB_ERR_CANCELLED) { 67667588Sdes break; 67767588Sdes } 67867588Sdes /* 67978025Sdes * If the pipe is already stalled, don't do another stall: 68078025Sdes */ 68173923Sjhb if (!usbd_xfer_is_stalled(xfer)) 68278031Sdes sc->sc_transfer.data_error = 1; 68378031Sdes 68478031Sdes /* try again */ 68578031Sdes goto tr_setup; 68678031Sdes } 68778031Sdes} 68878031Sdes 68978031Sdesstatic void 69078031Sdesustorage_fs_t_bbb_data_read_callback(struct usb_xfer *xfer, usb_error_t error) 69178031Sdes{ 69278025Sdes struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer); 69367588Sdes uint32_t max_bulk = usbd_xfer_max_len(xfer); 69478031Sdes int actlen, sumlen; 69571471Sjhb 69678025Sdes usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); 697119068Sdes 69867588Sdes DPRINTF("\n"); 69967588Sdes 70069799Sdes switch (USB_GET_STATE(xfer)) { 70169799Sdes case USB_ST_TRANSFERRED: 70269799Sdes sc->sc_transfer.data_rem -= actlen; 70369799Sdes sc->sc_transfer.data_ptr += actlen; 70469799Sdes sc->sc_transfer.offset += actlen; 70569799Sdes 70669799Sdes if (actlen != sumlen || sc->sc_transfer.data_rem == 0) { 70769799Sdes /* short transfer or end of data */ 70867588Sdes ustorage_fs_transfer_start(sc, 709113574Sjhb USTORAGE_FS_T_BBB_STATUS); 71078025Sdes break; 711113574Sjhb } 712113574Sjhb /* Fallthrough */ 713113574Sjhb 714113574Sjhb case USB_ST_SETUP: 71569995Sdestr_setup: 71669995Sdes if (max_bulk > sc->sc_transfer.data_rem) { 717113574Sjhb max_bulk = sc->sc_transfer.data_rem; 71867588Sdes } 71967588Sdes if (sc->sc_transfer.data_error) { 72067588Sdes sc->sc_transfer.data_error = 0; 72167588Sdes usbd_xfer_set_stall(xfer); 72267588Sdes } 72367588Sdes 72467588Sdes usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr, 72567588Sdes max_bulk); 72667588Sdes usbd_transfer_submit(xfer); 72767588Sdes break; 72867588Sdes 72967588Sdes default: /* Error */ 73071471Sjhb if (error == USB_ERR_CANCELLED) { 731104306Sjmallett break; 73269799Sdes } 73369799Sdes /* If the pipe is already stalled, don't do another stall */ 73469799Sdes if (!usbd_xfer_is_stalled(xfer)) 73569799Sdes sc->sc_transfer.data_error = 1; 73678025Sdes 737114983Sjhb /* try again */ 738114983Sjhb goto tr_setup; 739114983Sjhb } 740114983Sjhb} 741114983Sjhb 74271471Sjhbstatic void 743119068Sdesustorage_fs_t_bbb_data_write_callback(struct usb_xfer *xfer, usb_error_t error) 74467588Sdes{ 74567588Sdes struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer); 74667588Sdes uint32_t max_bulk = usbd_xfer_max_len(xfer); 74767588Sdes int actlen, sumlen; 74867588Sdes 74978025Sdes usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); 75078025Sdes 75178025Sdes DPRINTF("\n"); 752119068Sdes 75378025Sdes switch (USB_GET_STATE(xfer)) { 75467588Sdes case USB_ST_TRANSFERRED: 75574135Sjlemon sc->sc_transfer.data_rem -= actlen; 756119911Sdes sc->sc_transfer.data_ptr += actlen; 75778113Sdes sc->sc_transfer.offset += actlen; 758119911Sdes 759119911Sdes if (actlen != sumlen || sc->sc_transfer.data_rem == 0) { 760119911Sdes /* short transfer or end of data */ 761119911Sdes ustorage_fs_transfer_start(sc, 762119911Sdes USTORAGE_FS_T_BBB_STATUS); 763119911Sdes break; 764119911Sdes } 765119911Sdes case USB_ST_SETUP: 766119911Sdestr_setup: 767119911Sdes if (max_bulk >= sc->sc_transfer.data_rem) { 768119911Sdes max_bulk = sc->sc_transfer.data_rem; 769119911Sdes if (sc->sc_transfer.data_short) 770119911Sdes usbd_xfer_set_flag(xfer, USB_FORCE_SHORT_XFER); 771119911Sdes else 772119911Sdes usbd_xfer_clr_flag(xfer, USB_FORCE_SHORT_XFER); 773119911Sdes } else 774119911Sdes usbd_xfer_clr_flag(xfer, USB_FORCE_SHORT_XFER); 775119911Sdes 776119911Sdes if (sc->sc_transfer.data_error) { 777119911Sdes sc->sc_transfer.data_error = 0; 778119911Sdes usbd_xfer_set_stall(xfer); 779119911Sdes } 780119911Sdes 781119911Sdes usbd_xfer_set_frame_data(xfer, 0, sc->sc_transfer.data_ptr, 782119911Sdes max_bulk); 783119911Sdes usbd_transfer_submit(xfer); 784119911Sdes break; 785119911Sdes 786119911Sdes default: /* Error */ 787119911Sdes if (error == USB_ERR_CANCELLED) { 788119911Sdes break; 789119911Sdes } 790119911Sdes /* 791119911Sdes * If the pipe is already stalled, don't do another 79278113Sdes * stall 79378113Sdes */ 79478025Sdes if (!usbd_xfer_is_stalled(xfer)) 79578113Sdes sc->sc_transfer.data_error = 1; 79678113Sdes 79778113Sdes /* try again */ 798138281Scperciva goto tr_setup; 79978113Sdes } 80078113Sdes} 80178113Sdes 80278113Sdesstatic void 80378113Sdesustorage_fs_t_bbb_status_callback(struct usb_xfer *xfer, usb_error_t error) 80478113Sdes{ 80578113Sdes struct ustorage_fs_softc *sc = usbd_xfer_softc(xfer); 80678113Sdes 80778113Sdes DPRINTF("\n"); 80878113Sdes 80978113Sdes switch (USB_GET_STATE(xfer)) { 81078113Sdes case USB_ST_TRANSFERRED: 81194620Sjhb ustorage_fs_transfer_start(sc, USTORAGE_FS_T_BBB_COMMAND); 812127694Spjd break; 81394620Sjhb 81494620Sjhb case USB_ST_SETUP: 81594620Sjhbtr_setup: 81694620Sjhb USETDW(sc->sc_csw.dCSWSignature, CSWSIGNATURE); 81794620Sjhb USETDW(sc->sc_csw.dCSWDataResidue, sc->sc_transfer.data_rem); 81894620Sjhb 81994620Sjhb if (sc->sc_transfer.data_error) { 820103767Sjake sc->sc_transfer.data_error = 0; 821103767Sjake usbd_xfer_set_stall(xfer); 82294620Sjhb } 82394620Sjhb 824138281Scperciva usbd_xfer_set_frame_data(xfer, 0, &sc->sc_csw, 825138281Scperciva sizeof(sc->sc_csw)); 826138281Scperciva usbd_transfer_submit(xfer); 827138281Scperciva break; 828138281Scperciva 829138281Scperciva default: 830138281Scperciva if (error == USB_ERR_CANCELLED) { 831138281Scperciva break; 832138281Scperciva } 833138281Scperciva /* If the pipe is already stalled, don't do another stall */ 83494620Sjhb if (!usbd_xfer_is_stalled(xfer)) 835138281Scperciva sc->sc_transfer.data_error = 1; 83694620Sjhb 83778113Sdes /* try again */ 838138281Scperciva goto tr_setup; 83978113Sdes } 84078113Sdes} 84178113Sdes 84278113Sdes/* SCSI commands that we recognize */ 84378113Sdes#define SC_FORMAT_UNIT 0x04 84478113Sdes#define SC_INQUIRY 0x12 845116173Sobrien#define SC_MODE_SELECT_6 0x15 846116173Sobrien#define SC_MODE_SELECT_10 0x55 847116173Sobrien#define SC_MODE_SENSE_6 0x1a 848116173Sobrien#define SC_MODE_SENSE_10 0x5a 849116173Sobrien#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e 850168762Sdes#define SC_READ_6 0x08 851116173Sobrien#define SC_READ_10 0x28 852116173Sobrien#define SC_READ_12 0xa8 853116173Sobrien#define SC_READ_CAPACITY 0x25 854116173Sobrien#define SC_READ_FORMAT_CAPACITIES 0x23 855116173Sobrien#define SC_RELEASE 0x17 856116173Sobrien#define SC_REQUEST_SENSE 0x03 857116173Sobrien#define SC_RESERVE 0x16 858116173Sobrien#define SC_SEND_DIAGNOSTIC 0x1d 859116173Sobrien#define SC_START_STOP_UNIT 0x1b 860116173Sobrien#define SC_SYNCHRONIZE_CACHE 0x35 861121265Scognet#define SC_TEST_UNIT_READY 0x00 862121246Scognet#define SC_VERIFY 0x2f 863169156Salc#define SC_WRITE_6 0x0a 864121265Scognet#define SC_WRITE_10 0x2a 865169156Salc#define SC_WRITE_12 0xaa 866121265Scognet 867121265Scognet/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */ 868121265Scognet#define SS_NO_SENSE 0 869121265Scognet#define SS_COMMUNICATION_FAILURE 0x040800 870169156Salc#define SS_INVALID_COMMAND 0x052000 871121265Scognet#define SS_INVALID_FIELD_IN_CDB 0x052400 872121265Scognet#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100 873137507Sphk#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500 874137507Sphk#define SS_MEDIUM_NOT_PRESENT 0x023a00 875161094Skib#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302 876168762Sdes#define SS_NOT_READY_TO_READY_TRANSITION 0x062800 877121246Scognet#define SS_RESET_OCCURRED 0x062900 878121246Scognet#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900 879121246Scognet#define SS_UNRECOVERED_READ_ERROR 0x031100 880121246Scognet#define SS_WRITE_ERROR 0x030c02 881121246Scognet#define SS_WRITE_PROTECTED 0x072700 882168762Sdes 883121246Scognet#define SK(x) ((uint8_t) ((x) >> 16)) /* Sense Key byte, etc. */ 884121246Scognet#define ASC(x) ((uint8_t) ((x) >> 8)) 885168762Sdes#define ASCQ(x) ((uint8_t) (x)) 886121246Scognet 887121246Scognet/* Routines for unaligned data access */ 888168762Sdes 889121246Scognetstatic uint16_t 890169156Salcget_be16(uint8_t *buf) 891168762Sdes{ 892121246Scognet return ((uint16_t)buf[0] << 8) | ((uint16_t)buf[1]); 893121246Scognet} 894121265Scognet 895121265Scognetstatic uint32_t 896121246Scognetget_be32(uint8_t *buf) 897121246Scognet{ 898169156Salc return ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) | 899121246Scognet ((uint32_t)buf[2] << 8) | ((uint32_t)buf[3]); 900169156Salc} 901169156Salc 902169156Salcstatic void 903169156Salcput_be16(uint8_t *buf, uint16_t val) 904121246Scognet{ 905169156Salc buf[0] = val >> 8; 906121246Scognet buf[1] = val; 907121246Scognet} 908121246Scognet 909161094Skibstatic void 910161094Skibput_be32(uint8_t *buf, uint32_t val) 911161094Skib{ 912161094Skib buf[0] = val >> 24; 913121246Scognet buf[1] = val >> 16; 914161094Skib buf[2] = val >> 8; 915161094Skib buf[3] = val & 0xff; 916169156Salc} 917169156Salc 918121246Scognet/*------------------------------------------------------------------------* 919121246Scognet * ustorage_fs_verify 920121246Scognet * 921169156Salc * Returns: 922161094Skib * 0: Success 923161094Skib * Else: Failure 924161094Skib *------------------------------------------------------------------------*/ 925161094Skibstatic uint8_t 926161094Skibustorage_fs_verify(struct ustorage_fs_softc *sc) 927161094Skib{ 928161094Skib struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 929161094Skib uint32_t lba; 930161094Skib uint32_t vlen; 931121246Scognet uint64_t file_offset; 932121246Scognet uint64_t amount_left; 933121246Scognet 934121246Scognet /* 935121246Scognet * Get the starting Logical Block Address 936168762Sdes */ 937121246Scognet lba = get_be32(&sc->sc_cmd_data[2]); 938168762Sdes 939121246Scognet /* 940121246Scognet * We allow DPO (Disable Page Out = don't save data in the cache) 941121246Scognet * but we don't implement it. 942121246Scognet */ 943121246Scognet if ((sc->sc_cmd_data[1] & ~0x10) != 0) { 944121246Scognet currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 945121246Scognet return (1); 946121246Scognet } 947121246Scognet vlen = get_be16(&sc->sc_cmd_data[7]); 948121265Scognet if (vlen == 0) { 949121246Scognet goto done; 950121246Scognet } 951121265Scognet /* No default reply */ 952121246Scognet 953121246Scognet /* Prepare to carry out the file verify */ 954121246Scognet amount_left = vlen; 955121246Scognet amount_left <<= 9; 956121246Scognet file_offset = lba; 957121246Scognet file_offset <<= 9; 958121246Scognet 959121246Scognet /* Range check */ 960121246Scognet vlen += lba; 961121246Scognet 962121246Scognet if ((vlen < lba) || 963169156Salc (vlen > currlun->num_sectors) || 964169156Salc (lba >= currlun->num_sectors)) { 965121246Scognet currlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 966169156Salc return (1); 967121246Scognet } 968121246Scognet /* XXX TODO: verify that data is readable */ 969169156Salcdone: 970169156Salc return (ustorage_fs_min_len(sc, 0, -1U)); 971169156Salc} 972169156Salc 973169156Salc/*------------------------------------------------------------------------* 974169156Salc * ustorage_fs_inquiry 975169156Salc * 976169156Salc * Returns: 977169156Salc * 0: Success 978121246Scognet * Else: Failure 979169156Salc *------------------------------------------------------------------------*/ 980168762Sdesstatic uint8_t 981121246Scognetustorage_fs_inquiry(struct ustorage_fs_softc *sc) 982168762Sdes{ 983168762Sdes uint8_t *buf = sc->sc_transfer.data_ptr; 984116173Sobrien 98578113Sdes struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 98678113Sdes 98778025Sdes if (!sc->sc_transfer.currlun) { 98878025Sdes /* Unsupported LUNs are okay */ 98974135Sjlemon memset(buf, 0, 36); 99085129Sdes buf[0] = 0x7f; 99174135Sjlemon /* Unsupported, no device - type */ 99274135Sjlemon return (ustorage_fs_min_len(sc, 36, -1U)); 99385129Sdes } 99483926Sdes memset(buf, 0, 8); 99585129Sdes /* Non - removable, direct - access device */ 99683926Sdes if (currlun->removable) 99774135Sjlemon buf[1] = 0x80; 998108172Shsu buf[2] = 2; 99974135Sjlemon /* ANSI SCSI level 2 */ 100085129Sdes buf[3] = 2; 100185129Sdes /* SCSI - 2 INQUIRY data format */ 100283926Sdes buf[4] = 31; 100383926Sdes /* Additional length */ 100483926Sdes /* No special options */ 100583926Sdes /* Copy in ID string */ 100674135Sjlemon memcpy(buf + 8, USTORAGE_FS_ID_STRING, 28); 1007108172Shsu 1008119068Sdes#if (USTORAGE_QDATA_MAX < 36) 100978025Sdes#error "(USTORAGE_QDATA_MAX < 36)" 101074135Sjlemon#endif 101174135Sjlemon return (ustorage_fs_min_len(sc, 36, -1U)); 1012158311Sambrisko} 1013167159Sjkim 1014167159Sjkim/*------------------------------------------------------------------------* 1015167159Sjkim * ustorage_fs_request_sense 1016167159Sjkim * 1017167159Sjkim * Returns: 1018167159Sjkim * 0: Success 1019167159Sjkim * Else: Failure 1020167159Sjkim *------------------------------------------------------------------------*/ 1021167159Sjkimstatic uint8_t 1022167159Sjkimustorage_fs_request_sense(struct ustorage_fs_softc *sc) 1023167159Sjkim{ 1024167159Sjkim uint8_t *buf = sc->sc_transfer.data_ptr; 1025167159Sjkim struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1026167159Sjkim uint32_t sd; 1027167159Sjkim uint32_t sdinfo; 1028167159Sjkim uint8_t valid; 1029167159Sjkim 1030167159Sjkim /* 1031167159Sjkim * From the SCSI-2 spec., section 7.9 (Unit attention condition): 1032167159Sjkim * 1033167159Sjkim * If a REQUEST SENSE command is received from an initiator 1034167159Sjkim * with a pending unit attention condition (before the target 1035167159Sjkim * generates the contingent allegiance condition), then the 1036167159Sjkim * target shall either: 1037167159Sjkim * a) report any pending sense data and preserve the unit 1038167159Sjkim * attention condition on the logical unit, or, 1039167159Sjkim * b) report the unit attention condition, may discard any 1040167159Sjkim * pending sense data, and clear the unit attention 1041167159Sjkim * condition on the logical unit for that initiator. 1042167159Sjkim * 1043167159Sjkim * FSG normally uses option a); enable this code to use option b). 1044167159Sjkim */ 1045167159Sjkim#if 0 1046168762Sdes if (currlun && currlun->unit_attention_data != SS_NO_SENSE) { 1047167159Sjkim currlun->sense_data = currlun->unit_attention_data; 1048167159Sjkim currlun->unit_attention_data = SS_NO_SENSE; 1049167159Sjkim } 1050167159Sjkim#endif 1051167159Sjkim 1052167159Sjkim if (!currlun) { 1053164692Sjkim /* Unsupported LUNs are okay */ 1054164692Sjkim sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; 1055164692Sjkim sdinfo = 0; 1056164692Sjkim valid = 0; 1057164692Sjkim } else { 1058164692Sjkim sd = currlun->sense_data; 1059168067Sjkim sdinfo = currlun->sense_data_info; 1060164692Sjkim valid = currlun->info_valid << 7; 1061164692Sjkim currlun->sense_data = SS_NO_SENSE; 1062164692Sjkim currlun->sense_data_info = 0; 1063164692Sjkim currlun->info_valid = 0; 1064163251Skeramida } 1065163129Snetchild 1066163129Snetchild memset(buf, 0, 18); 1067163129Snetchild buf[0] = valid | 0x70; 1068163129Snetchild /* Valid, current error */ 1069163757Snetchild buf[2] = SK(sd); 1070163129Snetchild put_be32(&buf[3], sdinfo); 1071163129Snetchild /* Sense information */ 1072163129Snetchild buf[7] = 18 - 8; 1073163129Snetchild /* Additional sense length */ 1074163129Snetchild buf[12] = ASC(sd); 1075164692Sjkim buf[13] = ASCQ(sd); 1076164692Sjkim 1077164692Sjkim#if (USTORAGE_QDATA_MAX < 18) 1078164692Sjkim#error "(USTORAGE_QDATA_MAX < 18)" 1079164692Sjkim#endif 1080164692Sjkim return (ustorage_fs_min_len(sc, 18, -1U)); 1081168067Sjkim} 1082168067Sjkim 1083164692Sjkim/*------------------------------------------------------------------------* 1084164692Sjkim * ustorage_fs_read_capacity 1085164692Sjkim * 1086164692Sjkim * Returns: 1087158311Sambrisko * 0: Success 1088158311Sambrisko * Else: Failure 1089158311Sambrisko *------------------------------------------------------------------------*/ 1090158311Sambriskostatic uint8_t 1091158311Sambriskoustorage_fs_read_capacity(struct ustorage_fs_softc *sc) 1092168762Sdes{ 1093158311Sambrisko uint8_t *buf = sc->sc_transfer.data_ptr; 1094158311Sambrisko struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1095158311Sambrisko uint32_t lba = get_be32(&sc->sc_cmd_data[2]); 1096158311Sambrisko uint8_t pmi = sc->sc_cmd_data[8]; 1097158311Sambrisko 1098158311Sambrisko /* Check the PMI and LBA fields */ 1099158311Sambrisko if ((pmi > 1) || ((pmi == 0) && (lba != 0))) { 1100158311Sambrisko currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1101158311Sambrisko return (1); 1102168762Sdes } 1103158311Sambrisko /* Max logical block */ 1104158311Sambrisko put_be32(&buf[0], currlun->num_sectors - 1); 1105158311Sambrisko /* Block length */ 110685538Sphk put_be32(&buf[4], 512); 110785538Sphk 110878113Sdes#if (USTORAGE_QDATA_MAX < 8) 110978113Sdes#error "(USTORAGE_QDATA_MAX < 8)" 111078113Sdes#endif 111178025Sdes return (ustorage_fs_min_len(sc, 8, -1U)); 111278025Sdes} 111374135Sjlemon 1114158311Sambrisko/*------------------------------------------------------------------------* 111578025Sdes * ustorage_fs_mode_sense 111674135Sjlemon * 1117158311Sambrisko * Returns: 1118158311Sambrisko * 0: Success 1119158311Sambrisko * Else: Failure 112074135Sjlemon *------------------------------------------------------------------------*/ 112178025Sdesstatic uint8_t 1122119068Sdesustorage_fs_mode_sense(struct ustorage_fs_softc *sc) 112378025Sdes{ 112474135Sjlemon uint8_t *buf = sc->sc_transfer.data_ptr; 112574135Sjlemon struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 112678113Sdes uint8_t *buf0; 112778113Sdes uint16_t len; 112878113Sdes uint16_t limit; 112978025Sdes uint8_t mscmnd = sc->sc_cmd_data[0]; 113078025Sdes uint8_t pc; 113174135Sjlemon uint8_t page_code; 1132168762Sdes uint8_t changeable_values; 113378025Sdes uint8_t all_pages; 113478025Sdes 113578025Sdes buf0 = buf; 113678025Sdes 113774135Sjlemon if ((sc->sc_cmd_data[1] & ~0x08) != 0) { 113883926Sdes /* Mask away DBD */ 113978025Sdes currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 114083926Sdes return (1); 114183926Sdes } 114283926Sdes pc = sc->sc_cmd_data[2] >> 6; 114383926Sdes page_code = sc->sc_cmd_data[2] & 0x3f; 114483926Sdes if (pc == 3) { 114583926Sdes currlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED; 1146119068Sdes return (1); 114783926Sdes } 114883926Sdes changeable_values = (pc == 1); 114983926Sdes all_pages = (page_code == 0x3f); 115083926Sdes 115183926Sdes /* 115283926Sdes * Write the mode parameter header. Fixed values are: default 115383926Sdes * medium type, no cache control (DPOFUA), and no block descriptors. 115483926Sdes * The only variable value is the WriteProtect bit. We will fill in 115583926Sdes * the mode data length later. 115685129Sdes */ 115778025Sdes memset(buf, 0, 8); 115885129Sdes if (mscmnd == SC_MODE_SENSE_6) { 115985129Sdes buf[2] = (currlun->read_only ? 0x80 : 0x00); 116085129Sdes /* WP, DPOFUA */ 116185129Sdes buf += 4; 116285129Sdes limit = 255; 116374135Sjlemon } else { 116485129Sdes /* SC_MODE_SENSE_10 */ 116578025Sdes buf[3] = (currlun->read_only ? 0x80 : 0x00); 1166119923Sdes /* WP, DPOFUA */ 1167119911Sdes buf += 8; 1168167482Sdes limit = 65535; 1169119911Sdes /* Should really be mod_data.buflen */ 1170167482Sdes } 1171119911Sdes 1172167482Sdes /* No block descriptors */ 1173119911Sdes 1174167482Sdes /* 1175119911Sdes * The mode pages, in numerical order. 1176167482Sdes */ 117783926Sdes if ((page_code == 0x08) || all_pages) { 1178119911Sdes buf[0] = 0x08; 1179167482Sdes /* Page code */ 118083926Sdes buf[1] = 10; 1181158311Sambrisko /* Page length */ 1182167482Sdes memset(buf + 2, 0, 10); 1183119911Sdes /* None of the fields are changeable */ 1184167482Sdes 118587543Sdes if (!changeable_values) { 1186167482Sdes buf[2] = 0x04; 1187119911Sdes /* Write cache enable, */ 1188167482Sdes /* Read cache not disabled */ 1189119911Sdes /* No cache retention priorities */ 1190167482Sdes put_be16(&buf[4], 0xffff); 1191119911Sdes /* Don 't disable prefetch */ 1192167482Sdes /* Minimum prefetch = 0 */ 119378025Sdes put_be16(&buf[8], 0xffff); 1194119923Sdes /* Maximum prefetch */ 1195167482Sdes put_be16(&buf[10], 0xffff); 119685129Sdes /* Maximum prefetch ceiling */ 1197167482Sdes } 119878025Sdes buf += 12; 1199119923Sdes } 1200167482Sdes /* 120185129Sdes * Check that a valid page was requested and the mode data length 1202167482Sdes * isn't too long. 1203119911Sdes */ 1204167482Sdes len = buf - buf0; 1205116173Sobrien if (len > limit) { 1206167482Sdes currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 120787543Sdes return (1); 1208167482Sdes } 1209116173Sobrien /* Store the mode data length */ 1210167482Sdes if (mscmnd == SC_MODE_SENSE_6) 121185129Sdes buf0[0] = len - 1; 1212167482Sdes else 1213119911Sdes put_be16(buf0, len - 2); 1214167482Sdes 121585129Sdes#if (USTORAGE_QDATA_MAX < 24) 1216167482Sdes#error "(USTORAGE_QDATA_MAX < 24)" 1217119911Sdes#endif 1218167482Sdes return (ustorage_fs_min_len(sc, len, -1U)); 121985129Sdes} 1220167482Sdes 122185129Sdes/*------------------------------------------------------------------------* 1222158311Sambrisko * ustorage_fs_start_stop 1223167482Sdes * 1224158311Sambrisko * Returns: 1225167482Sdes * 0: Success 1226158311Sambrisko * Else: Failure 1227167482Sdes *------------------------------------------------------------------------*/ 1228163129Snetchildstatic uint8_t 1229163129Snetchildustorage_fs_start_stop(struct ustorage_fs_softc *sc) 1230167482Sdes{ 1231163129Snetchild struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1232167482Sdes uint8_t loej; 1233167159Sjkim uint8_t start; 1234167482Sdes uint8_t immed; 1235167159Sjkim 1236167482Sdes if (!currlun->removable) { 1237167159Sjkim currlun->sense_data = SS_INVALID_COMMAND; 1238167482Sdes return (1); 1239164692Sjkim } 1240167482Sdes immed = sc->sc_cmd_data[1] & 0x01; 1241163129Snetchild loej = sc->sc_cmd_data[4] & 0x02; 1242167482Sdes start = sc->sc_cmd_data[4] & 0x01; 1243164692Sjkim 1244167482Sdes if (immed || loej || start) { 1245163129Snetchild /* compile fix */ 124685129Sdes } 124785129Sdes return (0); 124885129Sdes} 124985129Sdes 125085129Sdes/*------------------------------------------------------------------------* 125185129Sdes * ustorage_fs_prevent_allow 125285129Sdes * 125385129Sdes * Returns: 125485129Sdes * 0: Success 125585129Sdes * Else: Failure 125685129Sdes *------------------------------------------------------------------------*/ 125785129Sdesstatic uint8_t 125885129Sdesustorage_fs_prevent_allow(struct ustorage_fs_softc *sc) 125985129Sdes{ 126085129Sdes struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 126178025Sdes uint8_t prevent; 126278025Sdes 1263168440Sjkim if (!currlun->removable) { 1264168440Sjkim currlun->sense_data = SS_INVALID_COMMAND; 1265 return (1); 1266 } 1267 prevent = sc->sc_cmd_data[4] & 0x01; 1268 if ((sc->sc_cmd_data[4] & ~0x01) != 0) { 1269 /* Mask away Prevent */ 1270 currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1271 return (1); 1272 } 1273 if (currlun->prevent_medium_removal && !prevent) { 1274 //fsync_sub(currlun); 1275 } 1276 currlun->prevent_medium_removal = prevent; 1277 return (0); 1278} 1279 1280/*------------------------------------------------------------------------* 1281 * ustorage_fs_read_format_capacities 1282 * 1283 * Returns: 1284 * 0: Success 1285 * Else: Failure 1286 *------------------------------------------------------------------------*/ 1287static uint8_t 1288ustorage_fs_read_format_capacities(struct ustorage_fs_softc *sc) 1289{ 1290 uint8_t *buf = sc->sc_transfer.data_ptr; 1291 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1292 1293 buf[0] = buf[1] = buf[2] = 0; 1294 buf[3] = 8; 1295 /* Only the Current / Maximum Capacity Descriptor */ 1296 buf += 4; 1297 1298 /* Number of blocks */ 1299 put_be32(&buf[0], currlun->num_sectors); 1300 /* Block length */ 1301 put_be32(&buf[4], 512); 1302 /* Current capacity */ 1303 buf[4] = 0x02; 1304 1305#if (USTORAGE_QDATA_MAX < 12) 1306#error "(USTORAGE_QDATA_MAX < 12)" 1307#endif 1308 return (ustorage_fs_min_len(sc, 12, -1U)); 1309} 1310 1311/*------------------------------------------------------------------------* 1312 * ustorage_fs_mode_select 1313 * 1314 * Return values: 1315 * 0: Success 1316 * Else: Failure 1317 *------------------------------------------------------------------------*/ 1318static uint8_t 1319ustorage_fs_mode_select(struct ustorage_fs_softc *sc) 1320{ 1321 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1322 1323 /* We don't support MODE SELECT */ 1324 currlun->sense_data = SS_INVALID_COMMAND; 1325 return (1); 1326} 1327 1328/*------------------------------------------------------------------------* 1329 * ustorage_fs_synchronize_cache 1330 * 1331 * Return values: 1332 * 0: Success 1333 * Else: Failure 1334 *------------------------------------------------------------------------*/ 1335static uint8_t 1336ustorage_fs_synchronize_cache(struct ustorage_fs_softc *sc) 1337{ 1338#if 0 1339 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1340 uint8_t rc; 1341 1342 /* 1343 * We ignore the requested LBA and write out all dirty data buffers. 1344 */ 1345 rc = 0; 1346 if (rc) { 1347 currlun->sense_data = SS_WRITE_ERROR; 1348 } 1349#endif 1350 return (0); 1351} 1352 1353/*------------------------------------------------------------------------* 1354 * ustorage_fs_read - read data from disk 1355 * 1356 * Return values: 1357 * 0: Success 1358 * Else: Failure 1359 *------------------------------------------------------------------------*/ 1360static uint8_t 1361ustorage_fs_read(struct ustorage_fs_softc *sc) 1362{ 1363 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1364 uint64_t file_offset; 1365 uint32_t lba; 1366 uint32_t len; 1367 1368 /* 1369 * Get the starting Logical Block Address and check that it's not 1370 * too big 1371 */ 1372 if (sc->sc_cmd_data[0] == SC_READ_6) { 1373 lba = (((uint32_t)sc->sc_cmd_data[1]) << 16) | 1374 get_be16(&sc->sc_cmd_data[2]); 1375 } else { 1376 lba = get_be32(&sc->sc_cmd_data[2]); 1377 1378 /* 1379 * We allow DPO (Disable Page Out = don't save data in the 1380 * cache) and FUA (Force Unit Access = don't read from the 1381 * cache), but we don't implement them. 1382 */ 1383 if ((sc->sc_cmd_data[1] & ~0x18) != 0) { 1384 currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1385 return (1); 1386 } 1387 } 1388 len = sc->sc_transfer.data_rem >> 9; 1389 len += lba; 1390 1391 if ((len < lba) || 1392 (len > currlun->num_sectors) || 1393 (lba >= currlun->num_sectors)) { 1394 currlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 1395 return (1); 1396 } 1397 file_offset = lba; 1398 file_offset <<= 9; 1399 1400 sc->sc_transfer.data_ptr = currlun->memory_image + file_offset; 1401 1402 return (0); 1403} 1404 1405/*------------------------------------------------------------------------* 1406 * ustorage_fs_write - write data to disk 1407 * 1408 * Return values: 1409 * 0: Success 1410 * Else: Failure 1411 *------------------------------------------------------------------------*/ 1412static uint8_t 1413ustorage_fs_write(struct ustorage_fs_softc *sc) 1414{ 1415 struct ustorage_fs_lun *currlun = sc->sc_transfer.currlun; 1416 uint64_t file_offset; 1417 uint32_t lba; 1418 uint32_t len; 1419 1420 if (currlun->read_only) { 1421 currlun->sense_data = SS_WRITE_PROTECTED; 1422 return (1); 1423 } 1424 /* XXX clear SYNC */ 1425 1426 /* 1427 * Get the starting Logical Block Address and check that it's not 1428 * too big. 1429 */ 1430 if (sc->sc_cmd_data[0] == SC_WRITE_6) 1431 lba = (((uint32_t)sc->sc_cmd_data[1]) << 16) | 1432 get_be16(&sc->sc_cmd_data[2]); 1433 else { 1434 lba = get_be32(&sc->sc_cmd_data[2]); 1435 1436 /* 1437 * We allow DPO (Disable Page Out = don't save data in the 1438 * cache) and FUA (Force Unit Access = write directly to the 1439 * medium). We don't implement DPO; we implement FUA by 1440 * performing synchronous output. 1441 */ 1442 if ((sc->sc_cmd_data[1] & ~0x18) != 0) { 1443 currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1444 return (1); 1445 } 1446 if (sc->sc_cmd_data[1] & 0x08) { 1447 /* FUA */ 1448 /* XXX set SYNC flag here */ 1449 } 1450 } 1451 1452 len = sc->sc_transfer.data_rem >> 9; 1453 len += lba; 1454 1455 if ((len < lba) || 1456 (len > currlun->num_sectors) || 1457 (lba >= currlun->num_sectors)) { 1458 currlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; 1459 return (1); 1460 } 1461 file_offset = lba; 1462 file_offset <<= 9; 1463 1464 sc->sc_transfer.data_ptr = currlun->memory_image + file_offset; 1465 1466 return (0); 1467} 1468 1469/*------------------------------------------------------------------------* 1470 * ustorage_fs_min_len 1471 * 1472 * Return values: 1473 * 0: Success 1474 * Else: Failure 1475 *------------------------------------------------------------------------*/ 1476static uint8_t 1477ustorage_fs_min_len(struct ustorage_fs_softc *sc, uint32_t len, uint32_t mask) 1478{ 1479 if (len != sc->sc_transfer.data_rem) { 1480 1481 if (sc->sc_transfer.cbw_dir == DIR_READ) { 1482 /* 1483 * there must be something wrong about this SCSI 1484 * command 1485 */ 1486 sc->sc_csw.bCSWStatus = CSWSTATUS_PHASE; 1487 return (1); 1488 } 1489 /* compute the minimum length */ 1490 1491 if (sc->sc_transfer.data_rem > len) { 1492 /* data ends prematurely */ 1493 sc->sc_transfer.data_rem = len; 1494 sc->sc_transfer.data_short = 1; 1495 } 1496 /* check length alignment */ 1497 1498 if (sc->sc_transfer.data_rem & ~mask) { 1499 /* data ends prematurely */ 1500 sc->sc_transfer.data_rem &= mask; 1501 sc->sc_transfer.data_short = 1; 1502 } 1503 } 1504 return (0); 1505} 1506 1507/*------------------------------------------------------------------------* 1508 * ustorage_fs_check_cmd - check command routine 1509 * 1510 * Check whether the command is properly formed and whether its data 1511 * size and direction agree with the values we already have. 1512 * 1513 * Return values: 1514 * 0: Success 1515 * Else: Failure 1516 *------------------------------------------------------------------------*/ 1517static uint8_t 1518ustorage_fs_check_cmd(struct ustorage_fs_softc *sc, uint8_t min_cmd_size, 1519 uint16_t mask, uint8_t needs_medium) 1520{ 1521 struct ustorage_fs_lun *currlun; 1522 uint8_t lun = (sc->sc_cmd_data[1] >> 5); 1523 uint8_t i; 1524 1525 /* Verify the length of the command itself */ 1526 if (min_cmd_size > sc->sc_transfer.cmd_len) { 1527 DPRINTF("%u > %u\n", 1528 min_cmd_size, sc->sc_transfer.cmd_len); 1529 sc->sc_csw.bCSWStatus = CSWSTATUS_PHASE; 1530 return (1); 1531 } 1532 /* Mask away the LUN */ 1533 sc->sc_cmd_data[1] &= 0x1f; 1534 1535 /* Check if LUN is correct */ 1536 if (lun != sc->sc_transfer.lun) { 1537 1538 } 1539 /* Check the LUN */ 1540 if (sc->sc_transfer.lun <= sc->sc_last_lun) { 1541 sc->sc_transfer.currlun = currlun = 1542 sc->sc_lun + sc->sc_transfer.lun; 1543 if (sc->sc_cmd_data[0] != SC_REQUEST_SENSE) { 1544 currlun->sense_data = SS_NO_SENSE; 1545 currlun->sense_data_info = 0; 1546 currlun->info_valid = 0; 1547 } 1548 /* 1549 * If a unit attention condition exists, only INQUIRY 1550 * and REQUEST SENSE commands are allowed. Anything 1551 * else must fail! 1552 */ 1553 if ((currlun->unit_attention_data != SS_NO_SENSE) && 1554 (sc->sc_cmd_data[0] != SC_INQUIRY) && 1555 (sc->sc_cmd_data[0] != SC_REQUEST_SENSE)) { 1556 currlun->sense_data = currlun->unit_attention_data; 1557 currlun->unit_attention_data = SS_NO_SENSE; 1558 return (1); 1559 } 1560 } else { 1561 sc->sc_transfer.currlun = currlun = NULL; 1562 1563 /* 1564 * INQUIRY and REQUEST SENSE commands are explicitly allowed 1565 * to use unsupported LUNs; all others may not. 1566 */ 1567 if ((sc->sc_cmd_data[0] != SC_INQUIRY) && 1568 (sc->sc_cmd_data[0] != SC_REQUEST_SENSE)) { 1569 return (1); 1570 } 1571 } 1572 1573 /* 1574 * Check that only command bytes listed in the mask are 1575 * non-zero. 1576 */ 1577 for (i = 0; i != min_cmd_size; i++) { 1578 if (sc->sc_cmd_data[i] && !(mask & (1UL << i))) { 1579 if (currlun) { 1580 currlun->sense_data = SS_INVALID_FIELD_IN_CDB; 1581 } 1582 return (1); 1583 } 1584 } 1585 1586 /* 1587 * If the medium isn't mounted and the command needs to access 1588 * it, return an error. 1589 */ 1590 if (currlun && (!currlun->memory_image) && needs_medium) { 1591 currlun->sense_data = SS_MEDIUM_NOT_PRESENT; 1592 return (1); 1593 } 1594 return (0); 1595} 1596 1597/*------------------------------------------------------------------------* 1598 * ustorage_fs_do_cmd - do command 1599 * 1600 * Return values: 1601 * 0: Success 1602 * Else: Failure 1603 *------------------------------------------------------------------------*/ 1604static uint8_t 1605ustorage_fs_do_cmd(struct ustorage_fs_softc *sc) 1606{ 1607 uint8_t error = 1; 1608 uint8_t i; 1609 uint32_t temp; 1610 const uint32_t mask9 = (0xFFFFFFFFUL >> 9) << 9; 1611 1612 /* set default data transfer pointer */ 1613 sc->sc_transfer.data_ptr = sc->sc_qdata; 1614 1615 DPRINTF("cmd_data[0]=0x%02x, data_rem=0x%08x\n", 1616 sc->sc_cmd_data[0], sc->sc_transfer.data_rem); 1617 1618 switch (sc->sc_cmd_data[0]) { 1619 case SC_INQUIRY: 1620 sc->sc_transfer.cmd_dir = DIR_WRITE; 1621 error = ustorage_fs_min_len(sc, sc->sc_cmd_data[4], -1U); 1622 if (error) { 1623 break; 1624 } 1625 error = ustorage_fs_check_cmd(sc, 6, 1626 (1UL << 4) | 1, 0); 1627 if (error) { 1628 break; 1629 } 1630 error = ustorage_fs_inquiry(sc); 1631 1632 break; 1633 1634 case SC_MODE_SELECT_6: 1635 sc->sc_transfer.cmd_dir = DIR_READ; 1636 error = ustorage_fs_min_len(sc, sc->sc_cmd_data[4], -1U); 1637 if (error) { 1638 break; 1639 } 1640 error = ustorage_fs_check_cmd(sc, 6, 1641 (1UL << 1) | (1UL << 4) | 1, 0); 1642 if (error) { 1643 break; 1644 } 1645 error = ustorage_fs_mode_select(sc); 1646 1647 break; 1648 1649 case SC_MODE_SELECT_10: 1650 sc->sc_transfer.cmd_dir = DIR_READ; 1651 error = ustorage_fs_min_len(sc, 1652 get_be16(&sc->sc_cmd_data[7]), -1U); 1653 if (error) { 1654 break; 1655 } 1656 error = ustorage_fs_check_cmd(sc, 10, 1657 (1UL << 1) | (3UL << 7) | 1, 0); 1658 if (error) { 1659 break; 1660 } 1661 error = ustorage_fs_mode_select(sc); 1662 1663 break; 1664 1665 case SC_MODE_SENSE_6: 1666 sc->sc_transfer.cmd_dir = DIR_WRITE; 1667 error = ustorage_fs_min_len(sc, sc->sc_cmd_data[4], -1U); 1668 if (error) { 1669 break; 1670 } 1671 error = ustorage_fs_check_cmd(sc, 6, 1672 (1UL << 1) | (1UL << 2) | (1UL << 4) | 1, 0); 1673 if (error) { 1674 break; 1675 } 1676 error = ustorage_fs_mode_sense(sc); 1677 1678 break; 1679 1680 case SC_MODE_SENSE_10: 1681 sc->sc_transfer.cmd_dir = DIR_WRITE; 1682 error = ustorage_fs_min_len(sc, 1683 get_be16(&sc->sc_cmd_data[7]), -1U); 1684 if (error) { 1685 break; 1686 } 1687 error = ustorage_fs_check_cmd(sc, 10, 1688 (1UL << 1) | (1UL << 2) | (3UL << 7) | 1, 0); 1689 if (error) { 1690 break; 1691 } 1692 error = ustorage_fs_mode_sense(sc); 1693 1694 break; 1695 1696 case SC_PREVENT_ALLOW_MEDIUM_REMOVAL: 1697 error = ustorage_fs_min_len(sc, 0, -1U); 1698 if (error) { 1699 break; 1700 } 1701 error = ustorage_fs_check_cmd(sc, 6, 1702 (1UL << 4) | 1, 0); 1703 if (error) { 1704 break; 1705 } 1706 error = ustorage_fs_prevent_allow(sc); 1707 1708 break; 1709 1710 case SC_READ_6: 1711 i = sc->sc_cmd_data[4]; 1712 sc->sc_transfer.cmd_dir = DIR_WRITE; 1713 temp = ((i == 0) ? 256UL : i); 1714 error = ustorage_fs_min_len(sc, temp << 9, mask9); 1715 if (error) { 1716 break; 1717 } 1718 error = ustorage_fs_check_cmd(sc, 6, 1719 (7UL << 1) | (1UL << 4) | 1, 1); 1720 if (error) { 1721 break; 1722 } 1723 error = ustorage_fs_read(sc); 1724 1725 break; 1726 1727 case SC_READ_10: 1728 sc->sc_transfer.cmd_dir = DIR_WRITE; 1729 temp = get_be16(&sc->sc_cmd_data[7]); 1730 error = ustorage_fs_min_len(sc, temp << 9, mask9); 1731 if (error) { 1732 break; 1733 } 1734 error = ustorage_fs_check_cmd(sc, 10, 1735 (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1); 1736 if (error) { 1737 break; 1738 } 1739 error = ustorage_fs_read(sc); 1740 1741 break; 1742 1743 case SC_READ_12: 1744 sc->sc_transfer.cmd_dir = DIR_WRITE; 1745 temp = get_be32(&sc->sc_cmd_data[6]); 1746 if (temp >= (1UL << (32 - 9))) { 1747 /* numerical overflow */ 1748 sc->sc_csw.bCSWStatus = CSWSTATUS_FAILED; 1749 error = 1; 1750 break; 1751 } 1752 error = ustorage_fs_min_len(sc, temp << 9, mask9); 1753 if (error) { 1754 break; 1755 } 1756 error = ustorage_fs_check_cmd(sc, 12, 1757 (1UL << 1) | (0xfUL << 2) | (0xfUL << 6) | 1, 1); 1758 if (error) { 1759 break; 1760 } 1761 error = ustorage_fs_read(sc); 1762 1763 break; 1764 1765 case SC_READ_CAPACITY: 1766 sc->sc_transfer.cmd_dir = DIR_WRITE; 1767 error = ustorage_fs_check_cmd(sc, 10, 1768 (0xfUL << 2) | (1UL << 8) | 1, 1); 1769 if (error) { 1770 break; 1771 } 1772 error = ustorage_fs_read_capacity(sc); 1773 1774 break; 1775 1776 case SC_READ_FORMAT_CAPACITIES: 1777 sc->sc_transfer.cmd_dir = DIR_WRITE; 1778 error = ustorage_fs_min_len(sc, 1779 get_be16(&sc->sc_cmd_data[7]), -1U); 1780 if (error) { 1781 break; 1782 } 1783 error = ustorage_fs_check_cmd(sc, 10, 1784 (3UL << 7) | 1, 1); 1785 if (error) { 1786 break; 1787 } 1788 error = ustorage_fs_read_format_capacities(sc); 1789 1790 break; 1791 1792 case SC_REQUEST_SENSE: 1793 sc->sc_transfer.cmd_dir = DIR_WRITE; 1794 error = ustorage_fs_min_len(sc, sc->sc_cmd_data[4], -1U); 1795 if (error) { 1796 break; 1797 } 1798 error = ustorage_fs_check_cmd(sc, 6, 1799 (1UL << 4) | 1, 0); 1800 if (error) { 1801 break; 1802 } 1803 error = ustorage_fs_request_sense(sc); 1804 1805 break; 1806 1807 case SC_START_STOP_UNIT: 1808 error = ustorage_fs_min_len(sc, 0, -1U); 1809 if (error) { 1810 break; 1811 } 1812 error = ustorage_fs_check_cmd(sc, 6, 1813 (1UL << 1) | (1UL << 4) | 1, 0); 1814 if (error) { 1815 break; 1816 } 1817 error = ustorage_fs_start_stop(sc); 1818 1819 break; 1820 1821 case SC_SYNCHRONIZE_CACHE: 1822 error = ustorage_fs_min_len(sc, 0, -1U); 1823 if (error) { 1824 break; 1825 } 1826 error = ustorage_fs_check_cmd(sc, 10, 1827 (0xfUL << 2) | (3UL << 7) | 1, 1); 1828 if (error) { 1829 break; 1830 } 1831 error = ustorage_fs_synchronize_cache(sc); 1832 1833 break; 1834 1835 case SC_TEST_UNIT_READY: 1836 error = ustorage_fs_min_len(sc, 0, -1U); 1837 if (error) { 1838 break; 1839 } 1840 error = ustorage_fs_check_cmd(sc, 6, 1841 0 | 1, 1); 1842 break; 1843 1844 /* 1845 * Although optional, this command is used by MS-Windows. 1846 * We support a minimal version: BytChk must be 0. 1847 */ 1848 case SC_VERIFY: 1849 error = ustorage_fs_min_len(sc, 0, -1U); 1850 if (error) { 1851 break; 1852 } 1853 error = ustorage_fs_check_cmd(sc, 10, 1854 (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1); 1855 if (error) { 1856 break; 1857 } 1858 error = ustorage_fs_verify(sc); 1859 1860 break; 1861 1862 case SC_WRITE_6: 1863 i = sc->sc_cmd_data[4]; 1864 sc->sc_transfer.cmd_dir = DIR_READ; 1865 temp = ((i == 0) ? 256UL : i); 1866 error = ustorage_fs_min_len(sc, temp << 9, mask9); 1867 if (error) { 1868 break; 1869 } 1870 error = ustorage_fs_check_cmd(sc, 6, 1871 (7UL << 1) | (1UL << 4) | 1, 1); 1872 if (error) { 1873 break; 1874 } 1875 error = ustorage_fs_write(sc); 1876 1877 break; 1878 1879 case SC_WRITE_10: 1880 sc->sc_transfer.cmd_dir = DIR_READ; 1881 temp = get_be16(&sc->sc_cmd_data[7]); 1882 error = ustorage_fs_min_len(sc, temp << 9, mask9); 1883 if (error) { 1884 break; 1885 } 1886 error = ustorage_fs_check_cmd(sc, 10, 1887 (1UL << 1) | (0xfUL << 2) | (3UL << 7) | 1, 1); 1888 if (error) { 1889 break; 1890 } 1891 error = ustorage_fs_write(sc); 1892 1893 break; 1894 1895 case SC_WRITE_12: 1896 sc->sc_transfer.cmd_dir = DIR_READ; 1897 temp = get_be32(&sc->sc_cmd_data[6]); 1898 if (temp > (mask9 >> 9)) { 1899 /* numerical overflow */ 1900 sc->sc_csw.bCSWStatus = CSWSTATUS_FAILED; 1901 error = 1; 1902 break; 1903 } 1904 error = ustorage_fs_min_len(sc, temp << 9, mask9); 1905 if (error) { 1906 break; 1907 } 1908 error = ustorage_fs_check_cmd(sc, 12, 1909 (1UL << 1) | (0xfUL << 2) | (0xfUL << 6) | 1, 1); 1910 if (error) { 1911 break; 1912 } 1913 error = ustorage_fs_write(sc); 1914 1915 break; 1916 1917 /* 1918 * Some mandatory commands that we recognize but don't 1919 * implement. They don't mean much in this setting. 1920 * It's left as an exercise for anyone interested to 1921 * implement RESERVE and RELEASE in terms of Posix 1922 * locks. 1923 */ 1924 case SC_FORMAT_UNIT: 1925 case SC_RELEASE: 1926 case SC_RESERVE: 1927 case SC_SEND_DIAGNOSTIC: 1928 /* Fallthrough */ 1929 1930 default: 1931 error = ustorage_fs_min_len(sc, 0, -1U); 1932 if (error) { 1933 break; 1934 } 1935 error = ustorage_fs_check_cmd(sc, sc->sc_transfer.cmd_len, 1936 0xff, 0); 1937 if (error) { 1938 break; 1939 } 1940 sc->sc_transfer.currlun->sense_data = 1941 SS_INVALID_COMMAND; 1942 error = 1; 1943 1944 break; 1945 } 1946 return (error); 1947} 1948