mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-17 05:32:55 +08:00
Merge pull request #1327 from hathach/msc-request-sense
Add msc request sense callback
This commit is contained in:
commit
fcca8bb4ca
@ -243,11 +243,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
|
|||||||
|
|
||||||
switch (scsi_cmd[0])
|
switch (scsi_cmd[0])
|
||||||
{
|
{
|
||||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
|
||||||
// Host is about to read/write etc ... better not to disconnect disk
|
|
||||||
resplen = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Set Sense = Invalid Command Operation
|
// Set Sense = Invalid Command Operation
|
||||||
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
||||||
|
@ -221,11 +221,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
|
|||||||
|
|
||||||
switch (scsi_cmd[0])
|
switch (scsi_cmd[0])
|
||||||
{
|
{
|
||||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
|
||||||
// Host is about to read/write etc ... better not to disconnect disk
|
|
||||||
resplen = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Set Sense = Invalid Command Operation
|
// Set Sense = Invalid Command Operation
|
||||||
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
||||||
|
@ -221,11 +221,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
|
|||||||
|
|
||||||
switch (scsi_cmd[0])
|
switch (scsi_cmd[0])
|
||||||
{
|
{
|
||||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
|
||||||
// Host is about to read/write etc ... better not to disconnect disk
|
|
||||||
resplen = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Set Sense = Invalid Command Operation
|
// Set Sense = Invalid Command Operation
|
||||||
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
||||||
|
@ -28,6 +28,9 @@
|
|||||||
|
|
||||||
#if CFG_TUD_MSC
|
#if CFG_TUD_MSC
|
||||||
|
|
||||||
|
// When button is pressed, LUN1 will be set to not ready to simulate
|
||||||
|
// medium not present (e.g SD card removed)
|
||||||
|
|
||||||
// Some MCU doesn't have enough 8KB SRAM to store the whole disk
|
// Some MCU doesn't have enough 8KB SRAM to store the whole disk
|
||||||
// We will use Flash as read-only disk with board that has
|
// We will use Flash as read-only disk with board that has
|
||||||
// CFG_EXAMPLE_MSC_READONLY defined
|
// CFG_EXAMPLE_MSC_READONLY defined
|
||||||
@ -227,7 +230,7 @@ void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16
|
|||||||
// return true allowing host to read/write this LUN e.g SD card inserted
|
// return true allowing host to read/write this LUN e.g SD card inserted
|
||||||
bool tud_msc_test_unit_ready_cb(uint8_t lun)
|
bool tud_msc_test_unit_ready_cb(uint8_t lun)
|
||||||
{
|
{
|
||||||
(void) lun;
|
if ( lun == 1 && board_button_read() ) return false;
|
||||||
|
|
||||||
return true; // RAM disk is always ready
|
return true; // RAM disk is always ready
|
||||||
}
|
}
|
||||||
@ -320,23 +323,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
|
|||||||
|
|
||||||
switch (scsi_cmd[0])
|
switch (scsi_cmd[0])
|
||||||
{
|
{
|
||||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
|
||||||
// Host is about to read/write etc ... better not to disconnect disk
|
|
||||||
resplen = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCSI_CMD_START_STOP_UNIT:
|
|
||||||
// Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power
|
|
||||||
/* scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd;
|
|
||||||
// Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well
|
|
||||||
// Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage
|
|
||||||
start_stop->start;
|
|
||||||
start_stop->load_eject;
|
|
||||||
*/
|
|
||||||
resplen = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Set Sense = Invalid Command Operation
|
// Set Sense = Invalid Command Operation
|
||||||
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
||||||
|
@ -209,7 +209,7 @@ TU_ATTR_UNUSED static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] =
|
|||||||
{ .key = SCSI_CMD_MODE_SELECT_6 , .data = "Mode_Select 6" },
|
{ .key = SCSI_CMD_MODE_SELECT_6 , .data = "Mode_Select 6" },
|
||||||
{ .key = SCSI_CMD_MODE_SENSE_6 , .data = "Mode_Sense 6" },
|
{ .key = SCSI_CMD_MODE_SENSE_6 , .data = "Mode_Sense 6" },
|
||||||
{ .key = SCSI_CMD_START_STOP_UNIT , .data = "Start Stop Unit" },
|
{ .key = SCSI_CMD_START_STOP_UNIT , .data = "Start Stop Unit" },
|
||||||
{ .key = SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL , .data = "Prevent Allow Medium Removal" },
|
{ .key = SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL , .data = "Prevent/Allow Medium Removal" },
|
||||||
{ .key = SCSI_CMD_READ_CAPACITY_10 , .data = "Read Capacity10" },
|
{ .key = SCSI_CMD_READ_CAPACITY_10 , .data = "Read Capacity10" },
|
||||||
{ .key = SCSI_CMD_REQUEST_SENSE , .data = "Request Sense" },
|
{ .key = SCSI_CMD_REQUEST_SENSE , .data = "Request Sense" },
|
||||||
{ .key = SCSI_CMD_READ_FORMAT_CAPACITY , .data = "Read Format Capacity" },
|
{ .key = SCSI_CMD_READ_FORMAT_CAPACITY , .data = "Read Format Capacity" },
|
||||||
@ -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_sense_medium_not_present(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_sense_medium_not_present(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_sense_medium_not_present(lun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -691,8 +697,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_sense_medium_not_present(lun);
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
scsi_read_capacity10_resp_t read_capa10;
|
scsi_read_capacity10_resp_t 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_sense_medium_not_present(lun);
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
read_fmt_capa.block_num = tu_htonl(block_count);
|
read_fmt_capa.block_num = tu_htonl(block_count);
|
||||||
@ -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_sense_medium_not_present(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_sense_medium_not_present(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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user