add tud_msc_request_sense_cb() as weak callback

set default error sense to NOT READY, Medium not present
This commit is contained in:
hathach 2022-02-14 18:17:49 +07:00
parent ffb257ac17
commit 456c06aa5e
2 changed files with 38 additions and 24 deletions

View File

@ -239,6 +239,12 @@ bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, u
return true; return true;
} }
static inline void set_default_error_sense(uint8_t lun)
{
// default sense is NOT READY, MEDIUM NOT PRESENT
tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3A, 0x00);
}
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// USBD Driver API // USBD Driver API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@ -406,7 +412,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
return false; return false;
} }
TU_LOG(MSC_DEBUG, " SCSI Command: %s\r\n", tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0])); TU_LOG(MSC_DEBUG, " SCSI Command [Lun%u]: %s\r\n", p_cbw->lun, tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0]));
//TU_LOG_MEM(MSC_DEBUG, p_cbw, xferred_bytes, 2); //TU_LOG_MEM(MSC_DEBUG, p_cbw, xferred_bytes, 2);
p_csw->signature = MSC_CSW_SIGNATURE; p_csw->signature = MSC_CSW_SIGNATURE;
@ -473,7 +479,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
if ( resplen < 0 ) if ( resplen < 0 )
{ {
// unsupported command // unsupported command
TU_LOG(MSC_DEBUG, " SCSI unsupported command\r\n"); TU_LOG(MSC_DEBUG, " SCSI unsupported or failed command\r\n");
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
} }
else if (resplen == 0) else if (resplen == 0)
@ -508,7 +514,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
break; break;
case MSC_STAGE_DATA: case MSC_STAGE_DATA:
TU_LOG(MSC_DEBUG, " SCSI Data\r\n"); TU_LOG(MSC_DEBUG, " SCSI Data [Lun%u]\r\n", p_cbw->lun);
//TU_LOG_MEM(MSC_DEBUG, _mscd_buf, xferred_bytes, 2); //TU_LOG_MEM(MSC_DEBUG, _mscd_buf, xferred_bytes, 2);
if (SCSI_CMD_READ_10 == p_cbw->command[0]) if (SCSI_CMD_READ_10 == p_cbw->command[0])
@ -569,7 +575,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
// Wait for the Status phase to complete // Wait for the Status phase to complete
if( (ep_addr == p_msc->ep_in) && (xferred_bytes == sizeof(msc_csw_t)) ) if( (ep_addr == p_msc->ep_in) && (xferred_bytes == sizeof(msc_csw_t)) )
{ {
TU_LOG(MSC_DEBUG, " SCSI Status = %u\r\n", p_csw->status); TU_LOG(MSC_DEBUG, " SCSI Status [Lun%u] = %u\r\n", p_cbw->lun, p_csw->status);
// TU_LOG_MEM(MSC_DEBUG, p_csw, xferred_bytes, 2); // TU_LOG_MEM(MSC_DEBUG, p_csw, xferred_bytes, 2);
// Invoke complete callback if defined // Invoke complete callback if defined
@ -654,8 +660,8 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
// Failed status response // Failed status response
resplen = - 1; resplen = - 1;
// If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable // set default sense if not set by callback
if ( p_msc->sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); if ( p_msc->sense_key == 0 ) set_default_error_sense(lun);
} }
break; break;
@ -670,8 +676,8 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
// Failed status response // Failed status response
resplen = - 1; resplen = - 1;
// If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable // set default sense if not set by callback
if ( p_msc->sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); if ( p_msc->sense_key == 0 ) set_default_error_sense(lun);
} }
} }
break; break;
@ -691,13 +697,13 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
{ {
resplen = -1; resplen = -1;
// If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable // set default sense if not set by callback
if ( p_msc->sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); if ( p_msc->sense_key == 0 ) set_default_error_sense(lun);
}else }else
{ {
scsi_read_capacity10_resp_t read_capa10; scsi_read_capacity10_resp_t read_capa10;
read_capa10.last_lba = tu_htonl(block_count-1); read_capa10.last_lba = tu_htonl(block_count-1);
read_capa10.block_size = tu_htonl(block_size); read_capa10.block_size = tu_htonl(block_size);
resplen = sizeof(read_capa10); resplen = sizeof(read_capa10);
@ -727,8 +733,8 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
{ {
resplen = -1; resplen = -1;
// If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable // set default sense if not set by callback
if ( p_msc->sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); if ( p_msc->sense_key == 0 ) set_default_error_sense(lun);
}else }else
{ {
read_fmt_capa.block_num = tu_htonl(block_count); read_fmt_capa.block_num = tu_htonl(block_count);
@ -765,10 +771,10 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
{ {
scsi_mode_sense6_resp_t mode_resp = scsi_mode_sense6_resp_t mode_resp =
{ {
.data_len = 3, .data_len = 3,
.medium_type = 0, .medium_type = 0,
.write_protected = false, .write_protected = false,
.reserved = 0, .reserved = 0,
.block_descriptor_len = 0 // no block descriptor are included .block_descriptor_len = 0 // no block descriptor are included
}; };
@ -789,12 +795,11 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
{ {
scsi_sense_fixed_resp_t sense_rsp = scsi_sense_fixed_resp_t sense_rsp =
{ {
.response_code = 0x70, .response_code = 0x70, // current, fixed format
.valid = 1 .valid = 1
}; };
sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_resp_t) - 8; sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_resp_t) - 8;
sense_rsp.sense_key = p_msc->sense_key; sense_rsp.sense_key = p_msc->sense_key;
sense_rsp.add_sense_code = p_msc->add_sense_code; sense_rsp.add_sense_code = p_msc->add_sense_code;
sense_rsp.add_sense_qualifier = p_msc->add_sense_qualifier; sense_rsp.add_sense_qualifier = p_msc->add_sense_qualifier;
@ -802,6 +807,12 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_
resplen = sizeof(sense_rsp); resplen = sizeof(sense_rsp);
memcpy(buffer, &sense_rsp, resplen); memcpy(buffer, &sense_rsp, resplen);
// request sense callback could overwrite the sense data
if (tud_msc_request_sense_cb)
{
resplen = tud_msc_request_sense_cb(lun, buffer, bufsize);
}
// Clear sense data after copy // Clear sense data after copy
tud_msc_set_sense(lun, 0, 0, 0); tud_msc_set_sense(lun, 0, 0, 0);
} }
@ -835,8 +846,8 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
// negative means error -> endpoint is stalled & status in CSW set to failed // negative means error -> endpoint is stalled & status in CSW set to failed
TU_LOG(MSC_DEBUG, " tud_msc_read10_cb() return -1\r\n"); TU_LOG(MSC_DEBUG, " tud_msc_read10_cb() return -1\r\n");
// Sense = Flash not ready for access // set sense
tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_MEDIUM_ERROR, 0x33, 0x00); set_default_error_sense(p_cbw->lun);
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
} }
@ -900,8 +911,8 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3
// update actual byte before failed // update actual byte before failed
p_msc->xferred_len += xferred_bytes; p_msc->xferred_len += xferred_bytes;
// Sense = Flash not ready for access // Set sense
tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_MEDIUM_ERROR, 0x33, 0x00); set_default_error_sense(p_cbw->lun);
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
}else }else

View File

@ -131,6 +131,9 @@ TU_ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void);
// - Start = 1 : active mode, if load_eject = 1 : load disk storage // - Start = 1 : active mode, if load_eject = 1 : load disk storage
TU_ATTR_WEAK bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject); TU_ATTR_WEAK bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject);
// Invoked when received REQUEST_SENSE
TU_ATTR_WEAK int32_t tud_msc_request_sense_cb(uint8_t lun, void* buffer, uint16_t bufsize);
// Invoked when Read10 command is complete // Invoked when Read10 command is complete
TU_ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun); TU_ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun);