diff --git a/examples/device/nrf52840/src/msc_device_app.c b/examples/device/nrf52840/src/msc_device_app.c index 75d33d72..e20ad45f 100644 --- a/examples/device/nrf52840/src/msc_device_app.c +++ b/examples/device/nrf52840/src/msc_device_app.c @@ -46,15 +46,6 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -scsi_sense_fixed_data_t mscd_sense_data = -{ - .response_code = 0x70, - .valid = 1, - - .sense_key = 0, // no errors - .add_sense_len = sizeof(scsi_sense_fixed_data_t) - 8 -}; - static scsi_mode_parameters_t const msc_dev_mode_para = { .mode_data_length = 3, @@ -88,11 +79,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, switch (scsi_cmd[0]) { - case SCSI_CMD_REQUEST_SENSE: - ptr = &mscd_sense_data; - len = sizeof(scsi_sense_fixed_data_t); - break; - case SCSI_CMD_MODE_SENSE_6: ptr = &msc_dev_mode_para; len = sizeof(msc_dev_mode_para); @@ -133,14 +119,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, } } - //------------- clear sense data if it is not request sense command -------------// - if ( SCSI_CMD_REQUEST_SENSE != scsi_cmd[0] ) - { - mscd_sense_data.sense_key = SCSI_SENSEKEY_NONE; - mscd_sense_data.add_sense_code = 0; - mscd_sense_data.add_sense_qualifier = 0; - } - return len; } diff --git a/examples/device/nrf52840/src/msc_device_app.h b/examples/device/nrf52840/src/msc_device_app.h index 0ed04d28..cc3caa10 100644 --- a/examples/device/nrf52840/src/msc_device_app.h +++ b/examples/device/nrf52840/src/msc_device_app.h @@ -75,8 +75,6 @@ void msc_app_task(void* param); void msc_app_mount(uint8_t rhport); void msc_app_umount(uint8_t rhport); -extern scsi_sense_fixed_data_t mscd_sense_data; - #else #define msc_app_init() diff --git a/src/class/msc/msc.h b/src/class/msc/msc.h index 290ee255..630f4e7b 100644 --- a/src/class/msc/msc.h +++ b/src/class/msc/msc.h @@ -240,7 +240,7 @@ typedef struct ATTR_PACKED uint8_t response_code : 7; ///< 70h - current errors, Fixed Format 71h - deferred errors, Fixed Format uint8_t valid : 1; - uint8_t TU_RESERVED; + uint8_t reserved; uint8_t sense_key : 4; uint8_t : 1; diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 488c9d41..ef8a45bc 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -72,9 +72,15 @@ typedef struct { uint8_t ep_in; uint8_t ep_out; + // Bulk Only Transfer (BOT) Protocol uint8_t stage; uint32_t data_len; uint32_t xferred_len; // numbered of bytes transferred so far in the Data Stage + + // Sense Response Data + uint8_t sense_key; + uint8_t add_sense_code; + uint8_t add_sense_qualifier; }mscd_interface_t; CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN static mscd_interface_t _mscd_itf; @@ -173,6 +179,91 @@ tusb_error_t mscd_control_request_st(uint8_t rhport, tusb_control_request_t cons OSAL_SUBTASK_END } +// return length of response (copied to buffer), -1 if it is not an built-in commands +int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t bufsize) +{ + int32_t ret; + + switch ( p_cbw->command[0] ) + { + case SCSI_CMD_READ_CAPACITY_10: + { + scsi_read_capacity10_data_t read_capa10 = + { + .last_lba = ENDIAN_BE(CFG_TUD_MSC_BLOCK_NUM-1), // read capacity + .block_size = ENDIAN_BE(CFG_TUD_MSC_BLOCK_SZ) + }; + + ret = sizeof(read_capa10); + memcpy(buffer, &read_capa10, ret); + } + break; + + case SCSI_CMD_READ_FORMAT_CAPACITY: + { + scsi_read_format_capacity_data_t read_fmt_capa = + { + .list_length = 8, + .block_num = ENDIAN_BE(CFG_TUD_MSC_BLOCK_NUM), // write capacity + .descriptor_type = 2, // formatted media + .block_size_u16 = ENDIAN_BE16(CFG_TUD_MSC_BLOCK_SZ) + }; + + ret = sizeof(read_fmt_capa); + memcpy(buffer, &read_fmt_capa, ret); + } + break; + + case SCSI_CMD_INQUIRY: + { + scsi_inquiry_data_t inquiry_rsp = + { + .is_removable = 1, + .version = 2, + .response_data_format = 2, + .vendor_id = "Adafruit", + .product_id = "Feather52840", + .product_rev = "1.0" + }; + + strncpy((char*) inquiry_rsp.vendor_id , CFG_TUD_MSC_VENDOR , sizeof(inquiry_rsp.vendor_id)); + strncpy((char*) inquiry_rsp.product_id , CFG_TUD_MSC_PRODUCT , sizeof(inquiry_rsp.product_id)); + strncpy((char*) inquiry_rsp.product_rev, CFG_TUD_MSC_PRODUCT_REV, sizeof(inquiry_rsp.product_rev)); + + ret = sizeof(inquiry_rsp); + memcpy(buffer, &inquiry_rsp, ret); + } + break; + + case SCSI_CMD_REQUEST_SENSE: + { + scsi_sense_fixed_data_t sense_rsp = + { + .response_code = 0x70, + .valid = 1 + }; + + sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_data_t) - 8; + + ret = sizeof(sense_rsp); + memcpy(buffer, &sense_rsp, ret); + } + break; + + default: ret = -1; break; + } + + //------------- clear sense data if it is not request sense command -------------// +// if ( SCSI_CMD_REQUEST_SENSE != p_cbw->command[0]) +// { +// sense_rsp.sense_key = SCSI_SENSEKEY_NONE; +// sense_rsp.add_sense_code = 0; +// sense_rsp.add_sense_qualifier = 0; +// } + + return ret; +} + tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, uint32_t xferred_bytes) { mscd_interface_t* p_msc = &_mscd_itf; @@ -232,51 +323,11 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, u // IN Transfer int32_t cb_result; - // TODO refactor later - if (SCSI_CMD_READ_CAPACITY_10 == p_cbw->command[0]) - { - scsi_read_capacity10_data_t read_capa10 = - { - .last_lba = ENDIAN_BE(CFG_TUD_MSC_BLOCK_NUM-1), // read capacity - .block_size = ENDIAN_BE(CFG_TUD_MSC_BLOCK_SZ) - }; + // first process if it is a built-in commands + cb_result = proc_builtin_scsi(p_cbw, _mscd_buf, sizeof(_mscd_buf)); - cb_result = sizeof(read_capa10); - memcpy(_mscd_buf, &read_capa10, cb_result); - } - else if (SCSI_CMD_READ_FORMAT_CAPACITY == p_cbw->command[0]) - { - scsi_read_format_capacity_data_t read_fmt_capa = - { - .list_length = 8, - .block_num = ENDIAN_BE(CFG_TUD_MSC_BLOCK_NUM), // write capacity - .descriptor_type = 2, // formatted media - .block_size_u16 = ENDIAN_BE16(CFG_TUD_MSC_BLOCK_SZ) - }; - - cb_result = sizeof(read_fmt_capa); - memcpy(_mscd_buf, &read_fmt_capa, cb_result); - } - else if (SCSI_CMD_INQUIRY == p_cbw->command[0]) - { - scsi_inquiry_data_t inquiry_rsp = - { - .is_removable = 1, - .version = 2, - .response_data_format = 2, - .vendor_id = "Adafruit", - .product_id = "Feather52840", - .product_rev = "1.0" - }; - - strncpy((char*) inquiry_rsp.vendor_id , CFG_TUD_MSC_VENDOR , sizeof(inquiry_rsp.vendor_id)); - strncpy((char*) inquiry_rsp.product_id , CFG_TUD_MSC_PRODUCT , sizeof(inquiry_rsp.product_id)); - strncpy((char*) inquiry_rsp.product_rev, CFG_TUD_MSC_PRODUCT_REV, sizeof(inquiry_rsp.product_rev)); - - cb_result = sizeof(inquiry_rsp); - memcpy(_mscd_buf, &inquiry_rsp, cb_result); - } - else + // Not an built-in command, invoke user callback + if ( cb_result < 0 ) { cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->data_len); }