142 lines
4.5 KiB
C
142 lines
4.5 KiB
C
|
|
#define USB_MS_DATA_EP 1
|
|
/*
|
|
#define USB_MS_DATA_IN_EP 1
|
|
#define USB_MS_DATA_OUT_EP 2*/
|
|
#define USB_MS_EP_SIZE 64
|
|
|
|
#define MSD_REQ_RESET 0xFF
|
|
#define MSD_GET_MAX_LUN 0xFE
|
|
#define MSD_CBW_SIGNATURE 0x43425355
|
|
#define MSD_CSW_SIGNATURE 0x53425355
|
|
/** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */
|
|
#define MSD_COMMAND_DIR_DATA_OUT (0 << 7)
|
|
|
|
/** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */
|
|
#define MSD_COMMAND_DIR_DATA_IN (1 << 7)
|
|
|
|
#define MSD_SETUP_WORD(setup, index) (uint16_t)(((uint16_t)setup[index+1] << 8) | (setup[index] & 0x00FF))
|
|
|
|
#define MSD_SETUP_VALUE(setup) MSD_SETUP_WORD(setup, 2)
|
|
#define MSD_SETUP_INDEX(setup) MSD_SETUP_WORD(setup, 4)
|
|
#define MSD_SETUP_LENGTH(setup) MSD_SETUP_WORD(setup, 6)
|
|
|
|
#define SCSI_CMD_INQUIRY 0x12
|
|
#define SCSI_CMD_REQUEST_SENSE 0x03
|
|
#define SCSI_CMD_READ_CAPACITY_10 0x25
|
|
#define SCSI_CMD_READ_10 0x28
|
|
#define SCSI_CMD_WRITE_10 0x2A
|
|
#define SCSI_CMD_TEST_UNIT_READY 0x00
|
|
#define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E
|
|
#define SCSI_CMD_VERIFY_10 0x2F
|
|
#define SCSI_CMD_SEND_DIAGNOSTIC 0x1D
|
|
#define SCSI_CMD_MODE_SENSE_6 0x1A
|
|
|
|
#define MSD_COMMAND_PASSED 0x00
|
|
#define MSD_COMMAND_FAILED 0x01
|
|
#define MSD_COMMAND_PHASE_ERROR 0x02
|
|
|
|
#define SCSI_SENSE_KEY_GOOD 0x00
|
|
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
|
|
#define SCSI_SENSE_KEY_NOT_READY 0x02
|
|
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
|
|
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
|
|
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
|
|
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
|
|
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07
|
|
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08
|
|
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
|
|
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
|
|
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
|
|
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
|
|
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E
|
|
#define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00
|
|
#define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04
|
|
#define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24
|
|
#define SCSI_ASENSE_NOT_READY_TO_READY_CHANGE 0x28
|
|
#define SCSI_ASENSE_WRITE_PROTECTED 0x27
|
|
#define SCSI_ASENSE_FORMAT_ERROR 0x31
|
|
#define SCSI_ASENSE_INVALID_COMMAND 0x20
|
|
#define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21
|
|
#define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A
|
|
#define SCSI_ASENSEQ_NO_QUALIFIER 0x00
|
|
#define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01
|
|
#define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02
|
|
#define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07
|
|
|
|
typedef struct {
|
|
/**
|
|
* @brief USB driver to use.
|
|
*/
|
|
USBDriver *usbp;
|
|
/**
|
|
* @brief USB driver configuration structure.
|
|
*/
|
|
USBConfig usb_config;
|
|
} USBMassStorageDeviceConfig;
|
|
|
|
|
|
PACK_STRUCT_BEGIN typedef struct {
|
|
uint32_t signature;
|
|
uint32_t tag;
|
|
uint32_t data_len;
|
|
uint8_t flags;
|
|
uint8_t lun;
|
|
uint8_t scsi_cmd_len;
|
|
uint8_t scsi_cmd_data[16];
|
|
} PACK_STRUCT_STRUCT msd_cbw_t PACK_STRUCT_END;
|
|
|
|
PACK_STRUCT_BEGIN typedef struct {
|
|
uint32_t signature;
|
|
uint32_t tag;
|
|
uint32_t data_residue;
|
|
uint8_t status;
|
|
} PACK_STRUCT_STRUCT msd_csw_t PACK_STRUCT_END;
|
|
|
|
typedef struct {
|
|
uint8_t byte[18];
|
|
} __attribute__ ((packed)) scsi_sense_response_t;
|
|
|
|
PACK_STRUCT_BEGIN typedef struct
|
|
{
|
|
uint8_t peripheral;
|
|
uint8_t removable;
|
|
uint8_t version;
|
|
uint8_t response_data_format;
|
|
uint8_t additional_length;
|
|
uint8_t sccstp;
|
|
uint8_t bqueetc;
|
|
uint8_t cmdque;
|
|
uint8_t vendorID[8];
|
|
uint8_t productID[16];
|
|
uint8_t productRev[4];
|
|
} PACK_STRUCT_STRUCT scsi_inquiry_response_t PACK_STRUCT_END;
|
|
|
|
PACK_STRUCT_BEGIN typedef struct {
|
|
uint32_t last_block_addr;
|
|
uint32_t block_size;
|
|
} PACK_STRUCT_STRUCT SCSIReadCapacity10Response_t PACK_STRUCT_END;
|
|
|
|
typedef struct USBMassStorageDriver USBMassStorageDriver;
|
|
|
|
typedef enum { idle, read_cmd_block, send_csw, reading, writing} msd_state_t;
|
|
|
|
struct USBMassStorageDriver {
|
|
USBDriver *usbp;
|
|
BaseBlockDevice *bbdp;
|
|
BlockDeviceInfo block_dev_info;
|
|
msd_state_t state;
|
|
msd_cbw_t cbw;
|
|
msd_csw_t csw;
|
|
scsi_sense_response_t sense;
|
|
bool_t result;
|
|
};
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
void msdInit(USBDriver *usbp, BaseBlockDevice *bdp);
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|