diff options
author | Anton Staaf <robotboy@chromium.org> | 2015-01-05 14:42:25 -0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-01-08 00:37:46 +0000 |
commit | b1f0a4ca4e99930f0c602a740000787cbd8bfd8a (patch) | |
tree | 0fbb82a824575140000eb09afe4efe4accc705e5 | |
parent | 0825fdf352d29430c8a3415f80371e0d8dacd20e (diff) | |
download | chrome-ec-b1f0a4ca4e99930f0c602a740000787cbd8bfd8a.tar.gz |
USB: Delete mass storage driver
This was an attempt at providing support for flashing a
SPI flash device over USB, but it suffered from being
rather complex and large. A simpler solution of bridging
SPI over USB directly and writing a SPI over USB driver
for flashrom is being used instead.
Signed-off-by: Anton Staaf <robotboy@chromium.org>
BRANCH=None
BUG=None
TEST=make buildall -j
Change-Id: I0d1ef8f17f5d6a4de46003096a8bff4a33b41cb7
Reviewed-on: https://chromium-review.googlesource.com/238763
Tested-by: Anton Staaf <robotboy@chromium.org>
Reviewed-by: David Schneider <dnschneid@chromium.org>
Reviewed-by: Vic Yang <victoryang@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Commit-Queue: Anton Staaf <robotboy@chromium.org>
Trybot-Ready: Anton Staaf <robotboy@chromium.org>
-rw-r--r-- | board/fruitpie/board.h | 2 | ||||
-rw-r--r-- | board/fruitpie/ec.tasklist | 1 | ||||
-rw-r--r-- | chip/stm32/build.mk | 1 | ||||
-rw-r--r-- | chip/stm32/usb_ms.c | 318 | ||||
-rw-r--r-- | chip/stm32/usb_ms_scsi.c | 795 | ||||
-rw-r--r-- | include/config.h | 9 | ||||
-rw-r--r-- | include/usb_ms.h | 63 | ||||
-rw-r--r-- | include/usb_ms_scsi.h | 110 |
8 files changed, 0 insertions, 1299 deletions
diff --git a/board/fruitpie/board.h b/board/fruitpie/board.h index a79c9f580c..8df61be852 100644 --- a/board/fruitpie/board.h +++ b/board/fruitpie/board.h @@ -18,8 +18,6 @@ /* Optional features */ #define CONFIG_STM_HWTIMER32 #define CONFIG_USB -#define CONFIG_USB_MS -#define CONFIG_USB_MS_BUFFER_SIZE SPI_FLASH_MAX_WRITE_SIZE #define CONFIG_USB_POWER_DELIVERY #define CONFIG_USB_PD_ALT_MODE #define CONFIG_USB_PD_ALT_MODE_DFP diff --git a/board/fruitpie/ec.tasklist b/board/fruitpie/ec.tasklist index 4690fb49cb..a8250d57c1 100644 --- a/board/fruitpie/ec.tasklist +++ b/board/fruitpie/ec.tasklist @@ -19,5 +19,4 @@ #define CONFIG_TASK_LIST \ TASK_ALWAYS(HOOKS, hook_task, NULL, TASK_STACK_SIZE) \ TASK_ALWAYS(CONSOLE, console_task, NULL, LARGER_TASK_STACK_SIZE) \ - TASK_ALWAYS(USB_MS, ms_task, NULL, TASK_STACK_SIZE) \ TASK_ALWAYS(PD, pd_task, NULL, TASK_STACK_SIZE) diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk index c2577fe34a..f2cb2d9983 100644 --- a/chip/stm32/build.mk +++ b/chip/stm32/build.mk @@ -52,6 +52,5 @@ chip-$(CONFIG_USB)+=usb.o usb-$(CHIP_FAMILY).o usb_endpoints.o chip-$(CONFIG_USB_CONSOLE)+=usb_console.o chip-$(CONFIG_USB_GPIO)+=usb_gpio.o chip-$(CONFIG_USB_HID)+=usb_hid.o -chip-$(CONFIG_USB_MS)+=usb_ms.o usb_ms_scsi.o chip-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_phy.o chip-$(CONFIG_USB_SPI)+=usb_spi.o diff --git a/chip/stm32/usb_ms.c b/chip/stm32/usb_ms.c deleted file mode 100644 index 329f80e8a1..0000000000 --- a/chip/stm32/usb_ms.c +++ /dev/null @@ -1,318 +0,0 @@ -/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "clock.h" -#include "common.h" -#include "config.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "link_defs.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "util.h" -#include "usb.h" -#include "usb_ms.h" -#include "usb_ms_scsi.h" - -/* - * Implements the USB Mass Storage Class specification using the - * Bulk-Only Transport (BBB) protocol with the transparent SCSI command set. - */ - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_USBMS, outstr) -#define CPRINTF(format, args...) cprintf(CC_USBMS, format, ## args) - -/* Mass storage descriptors */ -const struct usb_interface_descriptor USB_IFACE_DESC(USB_IFACE_MS) = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = USB_IFACE_MS, - .bAlternateSetting = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_MASS_STORAGE, - .bInterfaceSubClass = USB_MS_SUBCLASS_SCSI, - .bInterfaceProtocol = USB_MS_PROTOCOL_BBB, - .iInterface = 0, -}; -const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_MS, USB_EP_MS_TX) = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_IN | USB_EP_MS_TX, - .bmAttributes = 0x02 /* Bulk */, - .wMaxPacketSize = USB_MS_PACKET_SIZE, - .bInterval = 0, -}; -const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_MS, USB_EP_MS_RX) = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_EP_MS_RX, - .bmAttributes = 0x02 /* Bulk */, - .wMaxPacketSize = USB_MS_PACKET_SIZE, - .bInterval = 0, -}; - -/* USB mass storage state machine */ -static enum usb_ms_state { - USB_MS_STATE_IDLE, - USB_MS_STATE_BUSY, - USB_MS_STATE_ERROR, /* received an invalid CBW */ - USB_MS_STATE_PHASE_ERROR, -} ms_state = USB_MS_STATE_IDLE; - -/* Hardware buffers for USB endpoints */ -usb_uint ms_ep_tx[USB_MS_PACKET_SIZE] __usb_ram; -usb_uint ms_ep_rx[USB_MS_PACKET_SIZE] __usb_ram; - -static void ms_tx_reset(void) -{ - btable_ep[USB_EP_MS_TX].tx_addr = usb_sram_addr(ms_ep_tx); - btable_ep[USB_EP_MS_TX].tx_count = 0; - btable_ep[USB_EP_MS_TX].rx_count = 0; - - STM32_USB_EP(USB_EP_MS_TX) = - (USB_EP_MS_TX << 0) /* Endpoint Address */ | - (2 << 4) /* TX NAK */ | - (0 << 9) /* Bulk EP */ | - (0 << 12) /* RX Disabled */; - - ms_state = USB_MS_STATE_IDLE; - scsi_reset(); -} - -static void ms_rx_reset(void) -{ - btable_ep[USB_EP_MS_RX].rx_addr = usb_sram_addr(ms_ep_rx); - btable_ep[USB_EP_MS_RX].rx_count = 0x8000 | - ((USB_MS_PACKET_SIZE/32-1) << 10); - btable_ep[USB_EP_MS_RX].tx_count = 0; - - STM32_USB_EP(USB_EP_MS_RX) = - (USB_EP_MS_RX << 0) /* Endpoint Address */ | - (0 << 4) /* TX Disabled */ | - (0 << 9) /* Bulk EP */ | - (3 << 12) /* RX VALID */; - - ms_state = USB_MS_STATE_IDLE; - scsi_reset(); -} - -/* - * Construct and send a CSW. - */ -static void ms_send_csw(int ms_tag, int ms_xfer_len, - int scsi_rv, int scsi_xfer_len) -{ - struct usb_ms_csw *resp = (struct usb_ms_csw *) ms_ep_tx; - - /* construct CSW response */ - resp->signature = UBS_MS_CSW_SIGNATURE; - resp->tag = ms_tag; - resp->data_residue = (ms_xfer_len > scsi_xfer_len) ? - (ms_xfer_len - scsi_xfer_len) : - (scsi_xfer_len - ms_xfer_len); - if (scsi_rv != SCSI_SENSE_HARDWARE_ERROR) - resp->status = (scsi_rv == SCSI_SENSE_NO_SENSE) ? - USB_MS_CSW_CMD_PASSED : - USB_MS_CSW_CMD_FAILED; - else { - ms_state = USB_MS_STATE_PHASE_ERROR; - resp->status = USB_MS_CSW_CMD_PHASE_ERR; - } - - /* set CSW response length */ - btable_ep[USB_EP_MS_TX].tx_count = USB_MS_CSW_LENGTH; - - /* wait for data to be read */ - STM32_TOGGLE_EP(USB_EP_MS_TX, EP_TX_MASK, EP_TX_VALID, 0); -} - -/* - * Send data already in the output buffer. - */ -static void ms_send_data(int ms_xfer_len, int *scsi_xfer_len) -{ - /* truncate if necessary */ - if (btable_ep[USB_EP_MS_TX].tx_count > ms_xfer_len) - btable_ep[USB_EP_MS_TX].tx_count = ms_xfer_len; - - /* increment sent data counter with actual length */ - *scsi_xfer_len += btable_ep[USB_EP_MS_TX].tx_count; - - /* wait for data to be read */ - STM32_TOGGLE_EP(USB_EP_MS_TX, EP_TX_MASK, EP_TX_VALID, 0); -} - -static void ms_tx(void) -{ - task_set_event(TASK_ID_USB_MS, TASK_EVENT_CUSTOM(USB_MS_EVENT_TX), 0); - - STM32_USB_EP(USB_EP_MS_TX) &= EP_MASK; -} - -static void ms_rx(void) -{ - task_set_event(TASK_ID_USB_MS, TASK_EVENT_CUSTOM(USB_MS_EVENT_RX), 0); - - STM32_USB_EP(USB_EP_MS_RX) &= EP_MASK; -} -USB_DECLARE_EP(USB_EP_MS_TX, ms_tx, ms_tx, ms_tx_reset); -USB_DECLARE_EP(USB_EP_MS_RX, ms_rx, ms_rx, ms_rx_reset); - -static int ms_iface_request(usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx) -{ - uint16_t *req = (uint16_t *) ep0_buf_rx; - - if ((req[0] & (USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS)) != - (USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS)) - return 1; - - switch (req[0] >> 8) { - case USB_MS_REQ_RESET: - if (req[1] == 0 && req[2] == USB_IFACE_MS && - req[3] == 0) { - ms_rx_reset(); - } - break; - case USB_MS_REQ_GET_MAX_LUN: - if (req[1] == 0 && req[2] == USB_IFACE_MS && - req[3] == 1) { - ep0_buf_tx[0] = SCSI_MAX_LUN; - btable_ep[0].tx_count = sizeof(uint8_t); - STM32_TOGGLE_EP(USB_EP_CONTROL, EP_TX_RX_MASK, - EP_TX_RX_VALID, 0); - } - break; - } - - return 0; -} -USB_DECLARE_IFACE(USB_IFACE_MS, ms_iface_request); - -void ms_task(void) -{ - struct usb_ms_cbw *req = (struct usb_ms_cbw *) ms_ep_rx; - int scsi_rv, scsi_xfer_len = 0; - uint32_t ms_xfer_len = 0, ms_tag = 0; - uint8_t ms_dir = 0, evt; - - while (1) { - /* wait for event or usb reset */ - evt = (task_wait_event(-1) & 0xff); - - switch (ms_state) { - case USB_MS_STATE_IDLE: - /* receiving data */ - if (evt & USB_MS_EVENT_RX) { - /* CBW is not valid or meaningful */ - if ((btable_ep[USB_EP_MS_RX].rx_count & 0x3ff) - != USB_MS_CBW_LENGTH || - req->signature - != USB_MS_CBW_SIGNATURE || - req->LUN & 0xf0 || - req->length & 0xe0 || - req->LUN > SCSI_MAX_LUN) { - - ms_state = USB_MS_STATE_ERROR; - STM32_TOGGLE_EP(USB_EP_MS_TX, - EP_TX_MASK, EP_TX_STALL, 0); - STM32_TOGGLE_EP(USB_EP_MS_RX, - EP_RX_MASK, EP_RX_STALL, 0); - break; - } - - /* have new packet */ - ms_state = USB_MS_STATE_BUSY; - - /* record packet details */ - ms_tag = req->tag; - ms_xfer_len = req->data_transfer_length; - ms_dir = req->flags; - scsi_xfer_len = 0; - - /* parse message and get next state */ - scsi_rv = scsi_parse(req->command_block, - req->length); - if (scsi_rv == SCSI_STATUS_CONTINUE) { - if (ms_dir & USB_MS_CBW_DATA_IN) - /* send out data */ - ms_send_data(ms_xfer_len, - &scsi_xfer_len); - else - /* receive more data */ - STM32_TOGGLE_EP(USB_EP_MS_RX, - EP_RX_MASK, EP_RX_VALID, 0); - } else { - /* send message response */ - ms_state = USB_MS_STATE_IDLE; - ms_send_csw(ms_tag, ms_xfer_len, - scsi_rv, scsi_xfer_len); - } - } else if (evt & USB_MS_EVENT_TX) { - /* just sent CSW, wait for next CBW */ - STM32_TOGGLE_EP(USB_EP_MS_RX, EP_RX_MASK, - EP_RX_VALID, 0); - } - break; - case USB_MS_STATE_BUSY: - /* receiving data */ - if (evt & USB_MS_EVENT_RX) { - /* - * received at least two CBW's in a row, - * go to error state - */ - if (ms_dir & USB_MS_CBW_DATA_IN) { - ms_state = USB_MS_STATE_ERROR; - STM32_TOGGLE_EP(USB_EP_MS_TX, - EP_TX_MASK, EP_TX_STALL, 0); - STM32_TOGGLE_EP(USB_EP_MS_RX, - EP_RX_MASK, EP_RX_STALL, 0); - break; - } - /* receive data */ - scsi_xfer_len += - (btable_ep[USB_EP_MS_RX].rx_count & 0x3ff); - scsi_rv = scsi_parse(NULL, 0); - if (scsi_rv != SCSI_STATUS_CONTINUE) { - ms_state = USB_MS_STATE_IDLE; - ms_send_csw(ms_tag, ms_xfer_len, - scsi_rv, scsi_xfer_len); - } - - /* wait for more data */ - STM32_TOGGLE_EP(USB_EP_MS_RX, - EP_RX_MASK, EP_RX_VALID, 0); - } else if (evt & USB_MS_EVENT_TX) { - /* reparse message and get next state */ - scsi_rv = scsi_parse(req->command_block, - req->length); - if (scsi_rv == SCSI_STATUS_CONTINUE) { - ms_send_data(ms_xfer_len, - &scsi_xfer_len); - } else { - ms_state = USB_MS_STATE_IDLE; - ms_send_csw(ms_tag, ms_xfer_len, - scsi_rv, scsi_xfer_len); - } - } - break; - case USB_MS_STATE_ERROR: - /* maintain error state until reset recovery */ - break; - case USB_MS_STATE_PHASE_ERROR: - CPUTS("phase error!\n"); - - STM32_TOGGLE_EP(USB_EP_MS_TX, EP_TX_MASK, - EP_TX_STALL, 0); - STM32_TOGGLE_EP(USB_EP_MS_RX, EP_RX_MASK, - EP_RX_STALL, 0); - break; - default: - break; - } - } -} diff --git a/chip/stm32/usb_ms_scsi.c b/chip/stm32/usb_ms_scsi.c deleted file mode 100644 index feaf38e557..0000000000 --- a/chip/stm32/usb_ms_scsi.c +++ /dev/null @@ -1,795 +0,0 @@ -/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "clock.h" -#include "common.h" -#include "config.h" -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "link_defs.h" -#include "registers.h" -#include "task.h" -#include "timer.h" -#include "spi.h" -#include "spi_flash.h" -#include "util.h" -#include "usb.h" -#include "usb_ms.h" -#include "usb_ms_scsi.h" - -/* - * Implements the SCSI-3 Block Commands (SBC-3) standard for - * Direct Access Block Devices with respect to the - * SCSI Primary Commands - 4 (SPC-4) standard. - * - * Note: Not all SPC-4 mandatory commands implemented; only LUN 0 supported. - */ - -/* Command operation codes */ -#define SCSI_INQUIRY 0x12 -#define SCSI_MODE_SENSE6 0x1a -#define SCSI_READ10 0x28 -#define SCSI_READ_CAPACITY10 0x25 -#define SCSI_READ_FORMAT_CAPACITIES 0x23 -#define SCSI_REPORT_LUNS 0xa0 -#define SCSI_REQUEST_SENSE 0x03 -#define SCSI_START_STOP_UNIT 0x1b -#define SCSI_SYNCHRONIZE_CACHE10 0x35 -#define SCSI_TEST_UNIT_READY 0x00 -#define SCSI_WRITE10 0x2a - -#define SCSI_STANDARD_INQUIRY_SIZE 62 -/* Standard inquiry response */ -static const uint8_t scsi_standard_inquiry[] = { - 0x00, /* Peripheral Qualifier | Peripheral Device Type (SBC-3) */ - (1 << 7), /* RMB | LU_CONG | Reserved */ - 0x06, /* Version (SPC-4) */ - 0x02, /* Reserved | Reserved | NormACA | HiSup | Response Data Format */ - (SCSI_STANDARD_INQUIRY_SIZE - 5), /* Additional Length */ - 0x00, /* SCCS | ACC | TPGS | 3PC | Reserved | Protect */ - 0x00, /* Obsolete | EncServ | VS | MultiP | - Obsolete | Reserved | Reserved | Addr16 */ - 0x00, /* Obsolete | Reserved | WBUS16 | Syncs | - Obsolete | Reserved | CmdQue | VS */ - 'G', 'O', 'O', 'G', 'L', 'E', '\0', '\0', /* Vendor ID */ - 'S', 'P', 'I', 'F', 'l', 'a', 's', 'h', /* Product ID */ - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', /* Lot Number */ - '1', '.', '0' , '0', /* Product Revision Level */ - '\0', '\0', '\0', '\0', /* Vendor Specific */ - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', /* Vendor Specific */ - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', /* Vendor Specific */ - 0x00, /* Reserved | Clocking | QAS | IUS */ - 0x00, /* Reserved */ - SCSI_VERSION_SBC3, /* Version 1 */ - SCSI_VERSION_SPC4, /* Version 2 */ -}; -BUILD_ASSERT(sizeof(scsi_standard_inquiry) == SCSI_STANDARD_INQUIRY_SIZE); - -#define SCSI_VPD_SUPPORTED_PAGES_SIZE 7 -/* Vital product data (VPD) response for supported VPD pages */ -static const uint8_t scsi_vpd_supported_pages[] = { - 0x00, /* Peripheral Qualifier | Peripheral Device Type (SBC-3) */ - SCSI_VPD_CODE_SUPPORTED_PAGES, /* Page Code */ - 0x00, /* Page Length */ - (SCSI_VPD_SUPPORTED_PAGES_SIZE - 4), /* Page Length */ - SCSI_VPD_CODE_SUPPORTED_PAGES, /* Supported VPD Pages */ - SCSI_VPD_CODE_SERIAL_NUMBER, /* Serial Number Page */ - SCSI_VPD_CODE_DEVICE_ID, /* Device ID Page */ -}; -BUILD_ASSERT(sizeof(scsi_vpd_supported_pages) == SCSI_VPD_SUPPORTED_PAGES_SIZE); - -#define SCSI_VPD_SERIAL_NUMBER_SIZE 17 -/* Vital product data (VPD) response for serial number page */ -static const uint8_t scsi_vpd_serial_number[] = { - 0x00, /* Peripheral Qualifier | Peripheral Device Type (SBC-3) */ - SCSI_VPD_CODE_SERIAL_NUMBER, /* Page Code */ - 0x00, /* Page Length */ - (SCSI_VPD_SERIAL_NUMBER_SIZE - 4), /* Page Length */ - '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', /* Serial Number */ - '\0', '\0', '\0', '\0', /* Serial Number */ - '\0', /* Serial Number */ -}; -BUILD_ASSERT(sizeof(scsi_vpd_serial_number) == SCSI_VPD_SERIAL_NUMBER_SIZE); - -#define SCSI_VPD_DESIGNATOR_LENGTH 21 -#define SCSI_VPD_DEVICE_ID_SIZE (SCSI_VPD_DESIGNATOR_LENGTH + 4) -/* Vital product data (VPD) response for device ID page */ -static const uint8_t scsi_vpd_device_id[] = { - 0x00, /* Peripheral Qualifier | Peripheral Device Type (SBC-3) */ - SCSI_VPD_CODE_DEVICE_ID, /* Page Code */ - 0x00, /* Designation Descriptor Length */ - (SCSI_VPD_DEVICE_ID_SIZE - 3), /* Designation Descriptor Length */ - 0x02, /* Protocol Identifier | Code Set (ASCII) */ - 0x01, /* PIV | Reserved | Association | Designator Type (T10) */ - 0x00, /* Reserved */ - (SCSI_VPD_DESIGNATOR_LENGTH - 3), /* Designator Length */ - 'G', 'O', 'O', 'G', 'L', 'E', '\0', '\0', /* Vendor ID */ - 'S', 'P', 'I', 'F', 'l', 'a', 's', 'h', /* Vendor Specific ID */ - '\0', /* Vendor Specific ID */ -}; -BUILD_ASSERT(sizeof(scsi_vpd_device_id) == SCSI_VPD_DEVICE_ID_SIZE); - -/* Capacity list response for read format capacities */ -static const struct scsi_capacity_list_response scsi_capacity_list = { - .header = 0x08, /* Reserved | List Length */ - /* Number of Blocks */ - .blocks = (CONFIG_SPI_FLASH_SIZE / SCSI_BLOCK_SIZE_BYTES), - /* Reserved | Descriptor Code | Block Length */ - .block_length = (0x02 << 24) | SCSI_BLOCK_SIZE_BYTES, -}; - -/* Current state of SCSI state machine */ -static enum usb_ms_scsi_state state = USB_MS_SCSI_STATE_IDLE; -static int buffer; -static int offset; -static int bytes; -static uint8_t op; - -/* Current sense key */ -static struct scsi_sense_entry scsi_sense_data; - -/* Local buffer for caching */ -static uint8_t temp_buf[CONFIG_USB_MS_BUFFER_SIZE]; - -static void scsi_sense_code(uint8_t sense, uint16_t code) -{ - scsi_sense_data.key = sense; - scsi_sense_data.ASC = SCSI_SENSE_CODE_ASC(code); - scsi_sense_data.ASCQ = SCSI_SENSE_CODE_ASCQ(code); -} - -static int scsi_verify_cdb6(uint8_t *block, uint8_t in_len) -{ - /* message too short */ - if (in_len < SCSI_CDB6_SIZE) { - scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_NONE); - return -1; - } - - /* NACA bit not supported */ - if (block[5] & 0x4) { - scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_INVALID_FIELD_IN_CDB); - return -1; - } - - return 0; -} - -static int scsi_verify_cdb10(uint8_t *block, uint8_t in_len) -{ - /* message too short */ - if (in_len < SCSI_CDB10_SIZE) { - scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_NONE); - return -1; - } - - /* NACA bit not supported */ - if (block[9] & 0x4) { - scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_INVALID_FIELD_IN_CDB); - return -1; - } - - return 0; -} - -/* - * Required by SPC-4. - */ -static void scsi_inquiry(uint8_t *block, uint8_t in_len) -{ - if (state == USB_MS_SCSI_STATE_PARSE) { - state = USB_MS_SCSI_STATE_DATA_OUT; - - /* terminate if fail to verify */ - if (scsi_verify_cdb6(block, in_len)) - return; - - /* EVPD bit set */ - if (block[1] & 0x1) { - /* lookup VPD page */ - switch (block[2]) { - case SCSI_VPD_CODE_SUPPORTED_PAGES: - /* return supported pages */ - memcpy_usbram(ms_ep_tx, - scsi_vpd_supported_pages, - sizeof(scsi_vpd_supported_pages)); - /* truncate response */ - btable_ep[USB_EP_MS_TX].tx_count = - MIN(block[3] << 8 | block[4], - sizeof(scsi_vpd_supported_pages)); - break; - case SCSI_VPD_CODE_SERIAL_NUMBER: - /* return serial number response */ - memcpy_usbram(ms_ep_tx, - scsi_vpd_serial_number, - sizeof(scsi_vpd_serial_number)); - - /* copy STM32 LOT_NUM for serial number */ - memcpy(temp_buf, - ((uint8_t *) STM32_UNIQUE_ID) + 4 + 1, - 7 * sizeof(uint8_t)); - /* copy STM32 WAF_NUM for serial number */ - temp_buf[7] = ((uint8_t *) STM32_UNIQUE_ID)[4]; - /* copy STM32 UID for serial number */ - memcpy(temp_buf + 8, - ((uint8_t *) STM32_UNIQUE_ID), - 4 * sizeof(uint8_t)); - - /* copy actual serial number */ - memcpy_usbram((usb_uint *) - (((uint8_t *) ms_ep_tx) + 4), - temp_buf, - 12 * sizeof(uint8_t)); - - /* truncate response */ - btable_ep[USB_EP_MS_TX].tx_count = - MIN(block[3] << 8 | block[4], - sizeof(scsi_vpd_serial_number)); - break; - case SCSI_VPD_CODE_DEVICE_ID: - /* return device id */ - memcpy_usbram(ms_ep_tx, - scsi_vpd_device_id, - sizeof(scsi_vpd_device_id)); - /* truncate response */ - btable_ep[USB_EP_MS_TX].tx_count = - MIN(block[3] << 8 | block[4], - sizeof(scsi_vpd_device_id)); - break; - default: - /* not supported */ - return scsi_sense_code( - SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_INVALID_FIELD_IN_CDB); - break; - } - /* EVPD not set but page code set */ - } else if (block[2]) { - return scsi_sense_code( - SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_INVALID_FIELD_IN_CDB); - } else { - /* return standard inquiry data */ - memcpy_usbram(ms_ep_tx, scsi_standard_inquiry, - sizeof(scsi_standard_inquiry)); - - /* copy STM32 LOT_NUM for vendor specific id */ - memcpy_usbram((usb_uint *) - (((uint8_t *) ms_ep_tx) + 24), - ((uint8_t *) STM32_UNIQUE_ID) + 4 + 1, - 7 * sizeof(uint8_t)); - - /* truncate response */ - btable_ep[USB_EP_MS_TX].tx_count = - MIN(block[3] << 8 | block[4], - sizeof(scsi_standard_inquiry)); - } - - } else if (state == USB_MS_SCSI_STATE_DATA_OUT) - state = USB_MS_SCSI_STATE_REPLY; - - return scsi_sense_code(SCSI_SENSE_NO_SENSE, - SCSI_SENSE_CODE_NONE); -} - -static void scsi_mode_sense6(uint8_t *block, uint8_t in_len) -{ - uint8_t response[4]; - - if (state == USB_MS_SCSI_STATE_PARSE) { - state = USB_MS_SCSI_STATE_DATA_OUT; - - /* terminate if fail to verify */ - if (scsi_verify_cdb6(block, in_len)) - return; - - /* response exceeds allocation length */ - if (block[4] < sizeof(response)) - return scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_INVALID_FIELD_IN_CDB); - - memset(response, 0, sizeof(response)); - /* set WP bit if necessary */ - response[2] = spi_flash_check_protect(0, - CONFIG_SPI_FLASH_SIZE) ? - (1 << 7) : 0; - - memcpy_usbram(ms_ep_tx, (uint8_t *) response, - sizeof(response)); - btable_ep[USB_EP_MS_TX].tx_count = sizeof(response); - } else if (state == USB_MS_SCSI_STATE_DATA_OUT) - state = USB_MS_SCSI_STATE_REPLY; - - return scsi_sense_code(SCSI_SENSE_NO_SENSE, - SCSI_SENSE_CODE_NONE); -} - -/* - * Required by SPC-4. - */ -static void scsi_read10(uint8_t *block, uint8_t in_len) -{ - int rv; - int read_len; - - if (state == USB_MS_SCSI_STATE_PARSE) { - state = USB_MS_SCSI_STATE_DATA_OUT; - - /* terminate if fail to verify */ - if (scsi_verify_cdb10(block, in_len)) - return; - - /* RELADR bit not supported */ - if (block[1] & 0x1) - return scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_INVALID_FIELD_IN_CDB); - - offset = SCSI_BLOCK_SIZE_BYTES * - (block[2] << 24 | block[3] << 16 - | block[4] << 8 | block[5]); - bytes = SCSI_BLOCK_SIZE_BYTES * - (block[7] << 8 | block[8]); - - /* Wait for any previous operation to complete */ - rv = spi_flash_wait(); - if (rv == EC_ERROR_TIMEOUT) - return scsi_sense_code( - SCSI_SENSE_HARDWARE_ERROR, - SCSI_SENSE_CODE_TIMEOUT); - } - - if (state == USB_MS_SCSI_STATE_DATA_OUT) { - /* nothing left to read */ - if (!bytes) { - state = USB_MS_SCSI_STATE_REPLY; - return scsi_sense_code(SCSI_SENSE_NO_SENSE, - SCSI_SENSE_CODE_NONE); - } - - /* read in multiples of USB_MS_PACKET_SIZE, then bytes */ - read_len = MIN(bytes, USB_MS_PACKET_SIZE); - - rv = spi_flash_read(temp_buf, offset, read_len); - /* invalid address */ - if (rv == EC_ERROR_INVAL) - return scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_LBA_OUT_OF_RANGE); - else if (rv != EC_SUCCESS) - return scsi_sense_code(SCSI_SENSE_HARDWARE_ERROR, - SCSI_SENSE_CODE_UNRECOVERED_READ_ERROR); - - /* temp buffer for chip addressing issues */ - memcpy_usbram(ms_ep_tx, temp_buf, read_len); - offset += read_len; - bytes -= read_len; - - btable_ep[USB_EP_MS_TX].tx_count = read_len; - } - - return scsi_sense_code(SCSI_SENSE_NO_SENSE, - SCSI_SENSE_CODE_NONE); -} - -/* - * Required by SPC-4. - */ -static void scsi_read_capacity10(uint8_t *block, uint8_t in_len) -{ - uint32_t response[2]; - - if (state == USB_MS_SCSI_STATE_PARSE) { - state = USB_MS_SCSI_STATE_DATA_OUT; - - /* terminate if fail to verify */ - if (scsi_verify_cdb10(block, in_len)) - return; - - /* RELADR bit not supported */ - if (block[1] & 0x1) - return scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_INVALID_FIELD_IN_CDB); - - /* PMI bit or LBA not supported */ - if (block[2] | block[3] | block[4] | - block[5] | (block[8] & 0x1)) - return scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_INVALID_FIELD_IN_CDB); - - /* compute LBA and block size, send in big endian */ - response[0] = __builtin_bswap32((CONFIG_SPI_FLASH_SIZE / - SCSI_BLOCK_SIZE_BYTES) - 1); - response[1] = __builtin_bswap32(SCSI_BLOCK_SIZE_BYTES); - - memcpy_usbram(ms_ep_tx, (uint8_t *) response, - sizeof(response)); - btable_ep[USB_EP_MS_TX].tx_count = sizeof(response); - } else if (state == USB_MS_SCSI_STATE_DATA_OUT) - state = USB_MS_SCSI_STATE_REPLY; - - return scsi_sense_code(SCSI_SENSE_NO_SENSE, - SCSI_SENSE_CODE_NONE); -} - -/* - * Used by UFI. Required by Windows XP. - */ -static void scsi_read_format_capacities(uint8_t *block, uint8_t in_len) -{ - if (state == USB_MS_SCSI_STATE_PARSE) { - state = USB_MS_SCSI_STATE_DATA_OUT; - - /* terminate if fail to verify */ - if (scsi_verify_cdb10(block, in_len)) - return; - - memcpy_usbram(ms_ep_tx, (uint8_t *) &scsi_capacity_list, - sizeof(scsi_capacity_list)); - btable_ep[USB_EP_MS_TX].tx_count = sizeof(scsi_capacity_list); - } else if (state == USB_MS_SCSI_STATE_DATA_OUT) - state = USB_MS_SCSI_STATE_REPLY; - - return scsi_sense_code(SCSI_SENSE_NO_SENSE, - SCSI_SENSE_CODE_NONE); -} - -/* - * Required by SPC-4. - */ -static void scsi_report_luns(uint8_t *block, uint8_t in_len) -{ - uint32_t response[16]; - - if (state == USB_MS_SCSI_STATE_PARSE) { - state = USB_MS_SCSI_STATE_DATA_OUT; - - /* terminate if fail to verify */ - if (scsi_verify_cdb6(block, in_len)) - return; - - /* response exceeds allocation length */ - if ((block[3] << 8 | block[4]) < sizeof(response)) - return scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_INVALID_FIELD_IN_CDB); - - memset(response, 0, sizeof(response)); - /* one LUN in the list */ - response[3] = 1; - - /* return response */ - memcpy_usbram(ms_ep_tx, (uint8_t *) response, - sizeof(response)); - btable_ep[USB_EP_MS_TX].tx_count = sizeof(response); - } else if (state == USB_MS_SCSI_STATE_DATA_OUT) - state = USB_MS_SCSI_STATE_REPLY; - - return scsi_sense_code(SCSI_SENSE_NO_SENSE, SCSI_SENSE_CODE_NONE); -} - -/* - * Required by SPC-4. - */ -static void scsi_request_sense(uint8_t *block, uint8_t in_len) -{ - uint8_t response[18]; - - if (state == USB_MS_SCSI_STATE_PARSE) { - state = USB_MS_SCSI_STATE_DATA_OUT; - - /* terminate if fail to verify */ - if (scsi_verify_cdb6(block, in_len)) - return; - - /* response exceeds allocation length */ - if (block[4] < sizeof(response)) - return scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_INVALID_FIELD_IN_CDB); - - memset(response, 0, sizeof(response)); - /* Valid | Response Code */ - response[0] = SCSI_SENSE_RESPONSE_CURRENT; - /* Filemark | EOM | ILI | SDAT_OVFL | Sense Key */ - response[2] = scsi_sense_data.key; - /* Additional Sense Length */ - response[7] = ARRAY_SIZE(response) - 7; - /* Additional Sense Code */ - response[12] = scsi_sense_data.ASC; - /* Additional Sense Code Qualifier */ - response[13] = scsi_sense_data.ASCQ; - - /* return fixed format sense data */ - memcpy_usbram(ms_ep_tx, response, sizeof(response)); - btable_ep[USB_EP_MS_TX].tx_count = sizeof(response); - } else if (state == USB_MS_SCSI_STATE_DATA_OUT) - state = USB_MS_SCSI_STATE_REPLY; - - return scsi_sense_code(SCSI_SENSE_NO_SENSE, SCSI_SENSE_CODE_NONE); -} - -static void scsi_start_stop_unit(uint8_t *block, uint8_t in_len) -{ - state = USB_MS_SCSI_STATE_REPLY; - - /* terminate if fail to verify */ - if (scsi_verify_cdb6(block, in_len)) - return; - - /* do nothing */ - - return scsi_sense_code(SCSI_SENSE_NO_SENSE, SCSI_SENSE_CODE_NONE); -} - -static void scsi_synchronize_cache10(uint8_t *block, uint8_t in_len) -{ - state = USB_MS_SCSI_STATE_REPLY; - - /* terminate if fail to verify */ - if (scsi_verify_cdb10(block, in_len)) - return; - - /* nothing to synchronize, return success */ - return scsi_sense_code(SCSI_SENSE_NO_SENSE, SCSI_SENSE_CODE_NONE); -} - -/* - * Required by SPC-4. - */ -static void scsi_test_unit_ready(uint8_t *block, uint8_t in_len) -{ - state = USB_MS_SCSI_STATE_REPLY; - - /* terminate if fail to verify */ - if (scsi_verify_cdb6(block, in_len)) - return; - - if (spi_enable(1)) - return scsi_sense_code(SCSI_SENSE_NOT_READY, - SCSI_SENSE_CODE_NOT_READY); - - return scsi_sense_code(SCSI_SENSE_NO_SENSE, SCSI_SENSE_CODE_NONE); -} - -/* - * Required by SPC-4. - */ -static void scsi_write10(uint8_t *block, uint8_t in_len) -{ - int rv; - int write_len; - - if (state == USB_MS_SCSI_STATE_PARSE) { - state = USB_MS_SCSI_STATE_DATA_IN; - - /* terminate if fail to verify */ - if (scsi_verify_cdb10(block, in_len)) - return; - - /* RELADR bit not supported */ - if (block[1] & 0x1) - return scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_INVALID_FIELD_IN_CDB); - - buffer = 0; - offset = SCSI_BLOCK_SIZE_BYTES * - (block[2] << 24 | block[3] << 16 | - block[4] << 8 | block[5]); - bytes = SCSI_BLOCK_SIZE_BYTES * (block[7] << 8 | block[8]); - - /* Chip has protection */ - if (spi_flash_check_protect(offset, bytes)) - return scsi_sense_code(SCSI_SENSE_DATA_PROTECT, - SCSI_SENSE_CODE_WRITE_PROTECTED); - - /* Wait for any previous operation to complete */ - rv = spi_flash_wait(); - if (rv == EC_ERROR_TIMEOUT) - return scsi_sense_code( - SCSI_SENSE_HARDWARE_ERROR, - SCSI_SENSE_CODE_TIMEOUT); - - rv = spi_flash_erase(offset, bytes); - /* invalid address */ - if (rv == EC_ERROR_INVAL) - return scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_LBA_OUT_OF_RANGE); - else if (rv != EC_SUCCESS) - return scsi_sense_code(SCSI_SENSE_HARDWARE_ERROR, - SCSI_SENSE_CODE_UNRECOVERED_READ_ERROR); - } else if (state == USB_MS_SCSI_STATE_DATA_IN) { - /* write whatever was received */ - write_len = MIN(bytes, - btable_ep[USB_EP_MS_RX].rx_count & 0x3ff); - ASSERT(write_len <= SPI_FLASH_MAX_WRITE_SIZE); - -#if CONFIG_USB_MS_BUFFER_SIZE != USB_MS_PACKET_SIZE - /* perform write only when local buffer is over full */ - if (buffer + write_len > CONFIG_USB_MS_BUFFER_SIZE) { - /* Wait for previous operation to complete */ - rv = spi_flash_wait(); - if (rv == EC_ERROR_TIMEOUT) - return scsi_sense_code( - SCSI_SENSE_HARDWARE_ERROR, - SCSI_SENSE_CODE_TIMEOUT); - - rv = spi_flash_write(offset, - CONFIG_USB_MS_BUFFER_SIZE, temp_buf); - if (rv == EC_ERROR_INVAL) - return scsi_sense_code( - SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_LBA_OUT_OF_RANGE); - else if (rv != EC_SUCCESS) - return scsi_sense_code( - SCSI_SENSE_HARDWARE_ERROR, - SCSI_SENSE_CODE_UNRECOVERED_READ_ERROR); - - offset += buffer; - bytes -= buffer; - - buffer = 0; - } - - /* copy data to local buffer */ - memcpy(temp_buf + buffer, (uint8_t *) ms_ep_rx, write_len); - buffer += write_len; - - /* on last write */ - if (bytes == buffer) { - /* Wait for previous operation to complete */ - rv = spi_flash_wait(); - if (rv == EC_ERROR_TIMEOUT) - return scsi_sense_code( - SCSI_SENSE_HARDWARE_ERROR, - SCSI_SENSE_CODE_TIMEOUT); - - rv = spi_flash_write(offset, buffer, temp_buf); - if (rv == EC_ERROR_INVAL) - return scsi_sense_code( - SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_LBA_OUT_OF_RANGE); - else if (rv == EC_ERROR_ACCESS_DENIED) - return scsi_sense_code(SCSI_SENSE_DATA_PROTECT, - SCSI_SENSE_CODE_WRITE_PROTECTED); - else if (rv != EC_SUCCESS) - return scsi_sense_code( - SCSI_SENSE_HARDWARE_ERROR, - SCSI_SENSE_CODE_UNRECOVERED_READ_ERROR); - - /* Wait for last write to complete */ - rv = spi_flash_wait(); - if (rv == EC_ERROR_TIMEOUT) - return scsi_sense_code( - SCSI_SENSE_HARDWARE_ERROR, - SCSI_SENSE_CODE_TIMEOUT); - - offset += buffer; - bytes -= buffer; - - buffer = 0; - /* received too much data */ - } else if (bytes < buffer) - return scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_LBA_OUT_OF_RANGE); -#else - memcpy(temp_buf, (uint8_t *) ms_ep_rx, write_len); - - /* Wait for previous operation to complete */ - rv = spi_flash_wait(); - if (rv == EC_ERROR_TIMEOUT) - return scsi_sense_code( - SCSI_SENSE_HARDWARE_ERROR, - SCSI_SENSE_CODE_TIMEOUT); - - rv = spi_flash_write(offset, write_len, temp_buf); - if (rv == EC_ERROR_INVAL) - return scsi_sense_code( - SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_LBA_OUT_OF_RANGE); - else if (rv == EC_ERROR_ACCESS_DENIED) - return scsi_sense_code(SCSI_SENSE_DATA_PROTECT, - SCSI_SENSE_CODE_WRITE_PROTECTED); - else if (rv != EC_SUCCESS) - return scsi_sense_code( - SCSI_SENSE_HARDWARE_ERROR, - SCSI_SENSE_CODE_UNRECOVERED_READ_ERROR); - - offset += write_len; - bytes -= write_len; -#endif - - /* nothing left to write */ - if (!bytes) - state = USB_MS_SCSI_STATE_REPLY; - } - return scsi_sense_code(SCSI_SENSE_NO_SENSE, SCSI_SENSE_CODE_NONE); -} - -void scsi_reset(void) -{ - op = 0; - - offset = 0; - bytes = 0; - buffer = 0; - - state = USB_MS_SCSI_STATE_IDLE; - /* set status to success by default */ - scsi_sense_code(SCSI_SENSE_NO_SENSE, SCSI_SENSE_CODE_NONE); -} - -int scsi_parse(uint8_t *block, uint8_t in_len) -{ - /* set new operation */ - if (state == USB_MS_SCSI_STATE_IDLE) { - state = USB_MS_SCSI_STATE_PARSE; - - op = block[0]; - } - - /* skip operation if sending reply */ - if (state != USB_MS_SCSI_STATE_REPLY) { - switch (op) { - case SCSI_INQUIRY: - scsi_inquiry(block, in_len); - break; - case SCSI_MODE_SENSE6: - scsi_mode_sense6(block, in_len); - break; - case SCSI_READ10: - scsi_read10(block, in_len); - break; - case SCSI_READ_CAPACITY10: - scsi_read_capacity10(block, in_len); - break; - case SCSI_READ_FORMAT_CAPACITIES: - scsi_read_format_capacities(block, in_len); - break; - case SCSI_REPORT_LUNS: - scsi_report_luns(block, in_len); - break; - case SCSI_REQUEST_SENSE: - scsi_request_sense(block, in_len); - break; - case SCSI_START_STOP_UNIT: - scsi_start_stop_unit(block, in_len); - break; - case SCSI_SYNCHRONIZE_CACHE10: - scsi_synchronize_cache10(block, in_len); - break; - case SCSI_TEST_UNIT_READY: - scsi_test_unit_ready(block, in_len); - break; - case SCSI_WRITE10: - scsi_write10(block, in_len); - break; - default: - state = USB_MS_SCSI_STATE_REPLY; - scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, - SCSI_SENSE_CODE_INVALID_COMMAND_OPERATION_CODE); - break; - } - } - - /* error during data rx/tx */ - if (((state == USB_MS_SCSI_STATE_DATA_OUT) || - (state == USB_MS_SCSI_STATE_DATA_IN)) && - scsi_sense_data.key) { - btable_ep[USB_EP_MS_TX].tx_count = 0; - state = USB_MS_SCSI_STATE_REPLY; - return SCSI_STATUS_CONTINUE; - } - - /* done sending data */ - if (state == USB_MS_SCSI_STATE_REPLY) { - state = USB_MS_SCSI_STATE_IDLE; - return scsi_sense_data.key; - } - - /* still sending/receiving data and no error has occurred */ - return SCSI_STATUS_CONTINUE; -} diff --git a/include/config.h b/include/config.h index 118d0fe74f..852ebf7e19 100644 --- a/include/config.h +++ b/include/config.h @@ -1190,15 +1190,6 @@ #undef CONFIG_USB_BCD_DEV /*****************************************************************************/ -/* USB interfaces config */ - -/* USB mass storage interface */ -#undef CONFIG_USB_MS - -/* USB mass storage local buffer size */ -#undef CONFIG_USB_MS_BUFFER_SIZE - -/*****************************************************************************/ /* Compile chip support for the USB device controller */ #undef CONFIG_USB diff --git a/include/usb_ms.h b/include/usb_ms.h deleted file mode 100644 index f7cbbe3e77..0000000000 --- a/include/usb_ms.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * USB mass storage definitions. - */ - -#ifndef USB_MS_H -#define USB_MS_H - -#define USB_MS_SUBCLASS_RBC 0x01 -#define USB_MS_SUBCLASS_MMC5 0x02 -#define USB_MS_SUBCLASS_UFI 0x04 -#define USB_MS_SUBCLASS_SCSI 0x06 -#define USB_MS_SUBCLASS_LSDFS 0x07 -#define USB_MS_SUBCLASS_IEEE1667 0x08 - -#define USB_MS_PROTOCOL_CBI_INTERRUPT 0x00 -#define USB_MS_PROTOCOL_CBI 0x01 -#define USB_MS_PROTOCOL_BBB 0x50 -#define USB_MS_PROTOCOL_UAS 0x62 - -#define USB_MS_PACKET_SIZE (USB_MAX_PACKET_SIZE) - -/* USB Mass Storage Command Block Wrapper */ -struct usb_ms_cbw { - uint32_t signature; - uint32_t tag; - uint32_t data_transfer_length; - uint8_t flags; - uint8_t LUN; - uint8_t length; - uint8_t command_block[16]; -} __packed; -#define USB_MS_CBW_LENGTH 31 - -#define USB_MS_CBW_SIGNATURE 0x43425355 -#define USB_MS_CBW_DATA_IN (1 << 7) - -/* USB Mass Storage Command Status Wrapper */ -struct usb_ms_csw { - uint32_t signature; - uint32_t tag; - uint32_t data_residue; - uint8_t status; -} __packed; -#define USB_MS_CSW_LENGTH 13 - -#define UBS_MS_CSW_SIGNATURE 0x53425355 -#define USB_MS_CSW_CMD_PASSED 0x0 -#define USB_MS_CSW_CMD_FAILED 0x1 -#define USB_MS_CSW_CMD_PHASE_ERR 0x2 - -#define USB_MS_REQ_RESET 0xff -#define USB_MS_REQ_GET_MAX_LUN 0xfe - -#define USB_MS_EVENT_TX (1 << 0) -#define USB_MS_EVENT_RX (1 << 1) - -/* Maximum number of supported LUN's, defined in SCSI file */ -extern const uint8_t max_lun; - -#endif /* USB_MS_H */ diff --git a/include/usb_ms_scsi.h b/include/usb_ms_scsi.h deleted file mode 100644 index 72d5ee322d..0000000000 --- a/include/usb_ms_scsi.h +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * SCSI definitions. - */ - -#ifndef USB_MS_SCSI_H -#define USB_MS_SCSI_H - -#define SCSI_MAX_LUN 0 - -/* Status values */ -#define SCSI_STATUS_GOOD 0x00 -#define SCSI_STATUS_CHECK_CONDITION 0x02 -#define SCSI_STATUS_CONDITION_MET 0x04 -#define SCSI_STATUS_BUSY 0x08 -#define SCSI_STATUS_RESERVATION_CONFLICT 0x18 -#define SCSI_STATUS_TASK_SET_FULL 0x28 -#define SCSI_STATUS_ACA_ACTIVE 0x30 -#define SCSI_STATUS_TASK_ABORTED 0x40 - -/* Not part of standard, indicates operation not complete*/ -#define SCSI_STATUS_CONTINUE 0xFF - -/* Sense key values */ -#define SCSI_SENSE_NO_SENSE 0x0 -#define SCSI_SENSE_RECOVERED_ERROR 0x1 -#define SCSI_SENSE_NOT_READY 0x2 -#define SCSI_SENSE_MEDIUM_ERROR 0x3 -#define SCSI_SENSE_HARDWARE_ERROR 0x4 -#define SCSI_SENSE_ILLEGAL_REQUEST 0x5 -#define SCSI_SENSE_UNIT_ATTENTION 0x6 -#define SCSI_SENSE_DATA_PROTECT 0x7 -#define SCSI_SENSE_BLANK_CHECK 0x8 -#define SCSI_SENSE_VENDOR_SPECIFIC 0x9 -#define SCSI_SENSE_COPY_ABORTED 0xa -#define SCSI_SENSE_ABORTED_COMMAND 0xb -#define SCSI_SENSE_VOLUME_OVERFLOW 0xd -#define SCSI_SENSE_MISCOMPARE 0xe -#define SCSI_SENSE_COMPLETED 0xf - -/* Additional sense code (ASC) and additional sense code qualifier (ASCQ) - * fields. Stored as ASC | ACSQ */ -#define SCSI_SENSE_CODE_NONE ((0x00 << 4) | 0x00) -#define SCSI_SENSE_CODE_INVALID_COMMAND_OPERATION_CODE ((0x20 << 4) | 0x00) -#define SCSI_SENSE_CODE_INVALID_FIELD_IN_CDB ((0x24 << 4) | 0x00) -#define SCSI_SENSE_CODE_UNRECOVERED_READ_ERROR ((0x11 << 4) | 0x00) -#define SCSI_SENSE_CODE_NOT_READY ((0x04 << 4) | 0x00) -#define SCSI_SENSE_CODE_COMMAND_TO_LUN_FAILED ((0x6e << 4) | 0x00) -#define SCSI_SENSE_CODE_LBA_OUT_OF_RANGE ((0x21 << 4) | 0x00) -#define SCSI_SENSE_CODE_WRITE_PROTECTED ((0x27 << 4) | 0x00) -#define SCSI_SENSE_CODE_TIMEOUT ((0x3e) | 0x02) -#define SCSI_SENSE_CODE_ASC(x) ((x & 0xf0) >> 8) -#define SCSI_SENSE_CODE_ASCQ(x) (x & 0x0f) - -/* Version descriptor values */ -#define SCSI_VERSION_SBC3 0x04, 0xc0 -#define SCSI_VERSION_SPC4 0x04, 0x60 - -/* Vital product data page codes */ -#define SCSI_VPD_CODE_SUPPORTED_PAGES 0x00 -#define SCSI_VPD_CODE_SERIAL_NUMBER 0x80 -#define SCSI_VPD_CODE_DEVICE_ID 0x83 - -/* Mode pages */ -#define SCSI_MODE_PAGE_ALL 0x3f -/* Response values for fixed-format sense data */ -#define SCSI_SENSE_RESPONSE_CURRENT 0x70 -#define SCSI_SENSE_RESPONSE_DEFERRED 0x71 - -/* Size of various SCSI data structures */ -#define SCSI_CDB6_SIZE 6 -#define SCSI_CDB10_SIZE 10 -#define SCSI_CDB12_SIZE 12 - -/* Block size for LBA addressing */ -#define SCSI_BLOCK_SIZE_BYTES (4 * 1024) - -/* USB mass storage SCSI state machine */ -enum usb_ms_scsi_state { - USB_MS_SCSI_STATE_IDLE, - USB_MS_SCSI_STATE_PARSE, - USB_MS_SCSI_STATE_DATA_IN, - USB_MS_SCSI_STATE_DATA_OUT, - USB_MS_SCSI_STATE_REPLY, -}; - -/* Structure defining sense key entry */ -struct scsi_sense_entry { - uint8_t key; /* Sense Key */ - uint8_t ASC; /* Additional Sense Code */ - uint8_t ASCQ; /* Additional Sense Qualifier */ -}; - -/* Structure defining read format capacities response */ -struct scsi_capacity_list_response { - uint32_t header; /* Reserved | List Length */ - uint32_t blocks; /* Number of Blocks */ - uint32_t block_length; /* Reserved | Descriptor Code | Block Length */ -}; - -/* USB endpoint buffers */ -extern usb_uint ms_ep_tx[USB_MS_PACKET_SIZE] __usb_ram; -extern usb_uint ms_ep_rx[USB_MS_PACKET_SIZE] __usb_ram; - -int scsi_parse(uint8_t *block, uint8_t length); -void scsi_reset(void); - -#endif /* USB_MS_SCSI_H */ |