blob: 6640803643daa4553df2846d1d415c454327e39b [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SYSROOT_ZIRCON_HW_USB_UMS_H_
#define SYSROOT_ZIRCON_HW_USB_UMS_H_
// clang-format off
// SCSI commands
#define UMS_TEST_UNIT_READY 0x00
#define UMS_REQUEST_SENSE 0x03
#define UMS_INQUIRY 0x12
#define UMS_MODE_SELECT6 0x15
#define UMS_MODE_SENSE6 0x1A
#define UMS_START_STOP_UNIT 0x1B
#define UMS_TOGGLE_REMOVABLE 0x1E
#define UMS_READ_FORMAT_CAPACITIES 0x23
#define UMS_READ_CAPACITY10 0x25
#define UMS_READ10 0x28
#define UMS_WRITE10 0x2A
#define UMS_SYNCHRONIZE_CACHE 0x35
#define UMS_MODE_SELECT10 0x55
#define UMS_MODE_SENSE10 0x5A
#define UMS_READ16 0x88
#define UMS_WRITE16 0x8A
#define UMS_READ_CAPACITY16 0x9E
#define UMS_READ12 0xA8
#define UMS_WRITE12 0xAA
// control request values
#define USB_REQ_RESET 0xFF
#define USB_REQ_GET_MAX_LUN 0xFE
// error codes for CSW processing
typedef uint32_t csw_status_t;
#define CSW_SUCCESS ((csw_status_t)0)
#define CSW_FAILED ((csw_status_t)1)
#define CSW_PHASE_ERROR ((csw_status_t)2)
#define CSW_INVALID ((csw_status_t)3)
#define CSW_TAG_MISMATCH ((csw_status_t)4)
// signatures in header and status
#define CBW_SIGNATURE 0x43425355
#define CSW_SIGNATURE 0x53425355
// transfer lengths
#define UMS_INQUIRY_TRANSFER_LENGTH 0x24
#define UMS_REQUEST_SENSE_TRANSFER_LENGTH 0x12
#define UMS_READ_FORMAT_CAPACITIES_TRANSFER_LENGTH 0xFC
// 6 Byte SCSI command
// This is big endian
typedef struct {
uint8_t opcode;
uint8_t misc;
uint16_t lba; // logical block address
uint8_t length;
uint8_t control;
} __PACKED scsi_command6_t;
static_assert(sizeof(scsi_command6_t) == 6, "");
// 10 Byte SCSI command
// This is big endian
typedef struct {
uint8_t opcode;
uint8_t misc;
uint32_t lba; // logical block address
uint8_t misc2;
uint8_t length_hi; // break length into two pieces to avoid odd alignment
uint8_t length_lo;
uint8_t control;
} __PACKED scsi_command10_t;
static_assert(sizeof(scsi_command10_t) == 10, "");
// 12 Byte SCSI command
// This is big endian
typedef struct {
uint8_t opcode;
uint8_t misc;
uint32_t lba; // logical block address
uint32_t length;
uint8_t misc2;
uint8_t control;
} __PACKED scsi_command12_t;
static_assert(sizeof(scsi_command12_t) == 12, "");
// 16 Byte SCSI command
// This is big endian
typedef struct {
uint8_t opcode;
uint8_t misc;
uint64_t lba; // logical block address
uint32_t length;
uint8_t misc2;
uint8_t control;
} __PACKED scsi_command16_t;
static_assert(sizeof(scsi_command16_t) == 16, "");
// SCSI Read Capacity 10 payload
// This is big endian
typedef struct {
uint32_t lba;
uint32_t block_length;
} __PACKED scsi_read_capacity_10_t;
static_assert(sizeof(scsi_read_capacity_10_t) == 8, "");
// SCSI Read Capacity 16 payload
// This is big endian
typedef struct {
uint64_t lba;
uint32_t block_length;
uint8_t ptype_prot_en; // bit 0: PROT_EN, bits 1-3: P_TYPE
uint8_t resesrved[19];
} __PACKED scsi_read_capacity_16_t;
static_assert(sizeof(scsi_read_capacity_16_t) == 32, "");
// SCSI Mode Sense 6 command
typedef struct {
uint8_t opcode; // UMS_MODE_SENSE6
uint8_t disable_block_desc;
uint8_t page;
uint8_t subpage;
uint8_t allocation_length;
uint8_t control;
} __PACKED scsi_mode_sense_6_command_t;
static_assert(sizeof(scsi_mode_sense_6_command_t) == 6, "");
// SCSI Mode Sense 6 data response
typedef struct {
uint8_t mode_data_length;
uint8_t medium_type;
uint8_t device_specific_param;
uint8_t block_desc_length;
} __PACKED scsi_mode_sense_6_data_t;
#define MODE_SENSE_DSP_RO 0x80 // bit 7 of device_specific_param: read-only
// Command Block Wrapper
typedef struct {
uint32_t dCBWSignature; // CBW_SIGNATURE
uint32_t dCBWTag;
uint32_t dCBWDataTransferLength;
uint8_t bmCBWFlags;
uint8_t bCBWLUN;
uint8_t bCBWCBLength;
uint8_t CBWCB[16];
} __PACKED ums_cbw_t;
static_assert(sizeof(ums_cbw_t) == 31, "");
// Command Status Wrapper
typedef struct {
uint32_t dCSWSignature; // CSW_SIGNATURE
uint32_t dCSWTag;
uint32_t dCSWDataResidue;
uint8_t bmCSWStatus;
} __PACKED ums_csw_t;
static_assert(sizeof(ums_csw_t) == 13, "");
#endif // SYSROOT_ZIRCON_HW_USB_UMS_H_