msc clean up

This commit is contained in:
hathach 2018-03-22 16:46:14 +07:00
parent e2739bb785
commit 974e3865e8
6 changed files with 53 additions and 49 deletions

View File

@ -111,6 +111,15 @@
#endif
// LPC11uxx and LPC13uxx requires each buffer has to be 64-byte alignment
#if TUSB_CFG_MCU == MCU_LPC11UXX || TUSB_CFG_MCU == MCU_LPC13UXX
#define ATTR_USB_MIN_ALIGNMENT ATTR_ALIGNED(64)
#elif defined NRF52840_XXAA
#define ATTR_USB_MIN_ALIGNMENT ATTR_ALIGNED(4)
#else
#define ATTR_USB_MIN_ALIGNMENT
#endif
#ifdef __cplusplus
}

View File

@ -107,9 +107,9 @@ typedef struct ATTR_PACKED
uint8_t lun ; ///< The device Logical Unit Number (LUN) to which the command block is being sent. For devices that support multiple LUNs, the host shall place into this field the LUN to which this command block is addressed. Otherwise, the host shall set this field to zero.
uint8_t cmd_len ; ///< The valid length of the CBWCBin bytes. This defines the valid length of the command block. The only legal values are 1 through 16
uint8_t command[16] ; ///< The command block to be executed by the device. The device shall interpret the first cmd_len bytes in this field as a command block
}msc_cmd_block_wrapper_t;
}msc_cbw_t;
STATIC_ASSERT(sizeof(msc_cmd_block_wrapper_t) == 31, "size is not correct");
STATIC_ASSERT(sizeof(msc_cbw_t) == 31, "size is not correct");
/// Command Status Wrapper
typedef struct ATTR_PACKED
@ -118,9 +118,9 @@ typedef struct ATTR_PACKED
uint32_t tag ; ///< The device shall set this field to the value received in the dCBWTag of the associated CBW.
uint32_t data_residue ; ///< For Data-Out the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLength, and the actual amount of data processed by the device. For Data-In the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLengthand the actual amount of relevant data sent by the device
uint8_t status ; ///< indicates the success or failure of the command. Values from \ref msc_csw_status_t
}msc_cmd_status_wrapper_t;
}msc_csw_t;
STATIC_ASSERT(sizeof(msc_cmd_status_wrapper_t) == 13, "size is not correct");
STATIC_ASSERT(sizeof(msc_csw_t) == 13, "size is not correct");
//--------------------------------------------------------------------+
// SCSI Constant

View File

@ -53,17 +53,18 @@
//--------------------------------------------------------------------+
typedef struct {
uint8_t scsi_data[64]; // buffer for scsi's response other than read10 & write10. NOTE should be multiple of 64 to be compatible with lpc11/13u
ATTR_USB_MIN_ALIGNMENT msc_cmd_block_wrapper_t cbw;
ATTR_USB_MIN_ALIGNMENT msc_cbw_t cbw;
#if defined (__ICCARM__) && (TUSB_CFG_MCU == MCU_LPC11UXX || TUSB_CFG_MCU == MCU_LPC13UXX)
uint8_t padding1[64-sizeof(msc_cmd_block_wrapper_t)]; // IAR cannot align struct's member
uint8_t padding1[64-sizeof(msc_cbw_t)]; // IAR cannot align struct's member
#endif
ATTR_USB_MIN_ALIGNMENT msc_cmd_status_wrapper_t csw;
ATTR_USB_MIN_ALIGNMENT msc_csw_t csw;
uint8_t max_lun;
uint8_t interface_number;
uint8_t edpt_in, edpt_out;
uint8_t interface_num;
uint8_t ep_in, ep_out;
}mscd_interface_t;
TUSB_CFG_ATTR_USBRAM STATIC_VAR mscd_interface_t mscd_data;
@ -94,30 +95,30 @@ tusb_error_t mscd_open(uint8_t port, tusb_descriptor_interface_t const * p_inter
//------------- Open Data Pipe -------------//
tusb_descriptor_endpoint_t const *p_endpoint = (tusb_descriptor_endpoint_t const *) descriptor_next( (uint8_t const*) p_interface_desc );
for(uint32_t i=0; i<2; i++)
for(int i=0; i<2; i++)
{
TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint->bDescriptorType &&
TUSB_XFER_BULK == p_endpoint->bmAttributes.xfer, TUSB_ERROR_DESCRIPTOR_CORRUPTED);
TUSB_XFER_BULK == p_endpoint->bmAttributes.xfer, TUSB_ERROR_DESCRIPTOR_CORRUPTED);
TU_ASSERT( tusb_dcd_edpt_open(port, p_endpoint), TUSB_ERROR_DCD_FAILED );
if ( p_endpoint->bEndpointAddress & TUSB_DIR_IN_MASK )
{
p_msc->edpt_in = p_endpoint->bEndpointAddress;
p_msc->ep_in = p_endpoint->bEndpointAddress;
}else
{
p_msc->edpt_out = p_endpoint->bEndpointAddress;
p_msc->ep_out = p_endpoint->bEndpointAddress;
}
p_endpoint = (tusb_descriptor_endpoint_t const *) descriptor_next( (uint8_t const*) p_endpoint );
}
p_msc->interface_number = p_interface_desc->bInterfaceNumber;
p_msc->interface_num = p_interface_desc->bInterfaceNumber;
(*p_length) += sizeof(tusb_descriptor_interface_t) + 2*sizeof(tusb_descriptor_endpoint_t);
//------------- Queue Endpoint OUT for Command Block Wrapper -------------//
TU_ASSERT( tusb_dcd_edpt_xfer(port, p_msc->edpt_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cmd_block_wrapper_t), true), TUSB_ERROR_DCD_EDPT_XFER );
TU_ASSERT( tusb_dcd_edpt_xfer(port, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t), true), TUSB_ERROR_DCD_EDPT_XFER );
return TUSB_ERROR_NONE;
}
@ -152,25 +153,25 @@ tusb_error_t mscd_control_request_st(uint8_t port, tusb_control_request_t const
//--------------------------------------------------------------------+
// MSCD APPLICATION CALLBACK
//--------------------------------------------------------------------+
tusb_error_t mscd_xfer_cb(uint8_t port, uint8_t edpt_addr, tusb_event_t event, uint32_t xferred_bytes)
tusb_error_t mscd_xfer_cb(uint8_t port, uint8_t ep_addr, tusb_event_t event, uint32_t xferred_bytes)
{
static bool is_waiting_read10_write10 = false; // indicate we are transferring data in READ10, WRITE10 command
mscd_interface_t * const p_msc = &mscd_data;
msc_cmd_block_wrapper_t * const p_cbw = &p_msc->cbw;
msc_cmd_status_wrapper_t * const p_csw = &p_msc->csw;
msc_cbw_t * const p_cbw = &p_msc->cbw;
msc_csw_t * const p_csw = &p_msc->csw;
VERIFY( (edpt_addr == p_msc->edpt_out) || (edpt_addr == p_msc->edpt_in), TUSB_ERROR_INVALID_PARA);
VERIFY( (ep_addr == p_msc->ep_out) || (ep_addr == p_msc->ep_in), TUSB_ERROR_INVALID_PARA);
//------------- new CBW received -------------//
if ( !is_waiting_read10_write10 )
{
// if ( edpt_addr == p_msc->edpt_in ) return TUSB_ERROR_NONE; // bulk in interrupt for dcd to clean up
// if ( ep_addr == p_msc->edpt_in ) return TUSB_ERROR_NONE; // bulk in interrupt for dcd to clean up
ASSERT( (edpt_addr == p_msc->edpt_out) &&
xferred_bytes == sizeof(msc_cmd_block_wrapper_t) &&
event == TUSB_EVENT_XFER_COMPLETE &&
p_cbw->signature == MSC_CBW_SIGNATURE, TUSB_ERROR_INVALID_PARA );
TU_ASSERT( (ep_addr == p_msc->ep_out) &&
event == TUSB_EVENT_XFER_COMPLETE &&
xferred_bytes == sizeof(msc_cbw_t) &&
p_cbw->signature == MSC_CBW_SIGNATURE, TUSB_ERROR_INVALID_PARA );
p_csw->signature = MSC_CSW_SIGNATURE;
p_csw->tag = p_cbw->tag;
@ -192,7 +193,7 @@ tusb_error_t mscd_xfer_cb(uint8_t port, uint8_t edpt_addr, tusb_event_t event, u
ASSERT( p_cbw->xfer_bytes >= actual_length, TUSB_ERROR_INVALID_PARA );
ASSERT( sizeof(p_msc->scsi_data) >= actual_length, TUSB_ERROR_NOT_ENOUGH_MEMORY); // needs to increase size for scsi_data
uint8_t const edpt_data = BIT_TEST_(p_cbw->dir, 7) ? p_msc->edpt_in : p_msc->edpt_out;
uint8_t const edpt_data = BIT_TEST_(p_cbw->dir, 7) ? p_msc->ep_in : p_msc->ep_out;
if ( p_buffer == NULL || actual_length == 0 )
{ // application does not provide data to response --> possibly unsupported SCSI command
@ -217,10 +218,10 @@ tusb_error_t mscd_xfer_cb(uint8_t port, uint8_t edpt_addr, tusb_event_t event, u
// Either bulk in & out can be stalled in the data phase, dcd must make sure these queued transfer will be resumed after host clear stall
if (!is_waiting_read10_write10)
{
TU_ASSERT( tusb_dcd_edpt_xfer(port, p_msc->edpt_in , (uint8_t*) p_csw, sizeof(msc_cmd_status_wrapper_t), false), TUSB_ERROR_DCD_EDPT_XFER );
TU_ASSERT( tusb_dcd_edpt_xfer(port, p_msc->ep_in , (uint8_t*) p_csw, sizeof(msc_csw_t), false), TUSB_ERROR_DCD_EDPT_XFER );
//------------- Queue the next CBW -------------//
TU_ASSERT( tusb_dcd_edpt_xfer(port, p_msc->edpt_out, (uint8_t*) p_cbw, sizeof(msc_cmd_block_wrapper_t), true), TUSB_ERROR_DCD_EDPT_XFER );
TU_ASSERT( tusb_dcd_edpt_xfer(port, p_msc->ep_out, (uint8_t*) p_cbw, sizeof(msc_cbw_t), true), TUSB_ERROR_DCD_EDPT_XFER );
}
return TUSB_ERROR_NONE;
@ -229,12 +230,12 @@ tusb_error_t mscd_xfer_cb(uint8_t port, uint8_t edpt_addr, tusb_event_t event, u
// return true if data phase is complete, false if not yet complete
static bool read10_write10_data_xfer(uint8_t port, mscd_interface_t* p_msc)
{
msc_cmd_block_wrapper_t * const p_cbw = &p_msc->cbw;
msc_cmd_status_wrapper_t * const p_csw = &p_msc->csw;
msc_cbw_t* const p_cbw = &p_msc->cbw;
msc_csw_t* const p_csw = &p_msc->csw;
scsi_read10_t* p_readwrite = (scsi_read10_t*) &p_cbw->command; // read10 & write10 has the same format
uint8_t const edpt_addr = BIT_TEST_(p_cbw->dir, 7) ? p_msc->edpt_in : p_msc->edpt_out;
uint8_t const ep_addr = BIT_TEST_(p_cbw->dir, 7) ? p_msc->ep_in : p_msc->ep_out;
uint32_t const lba = __be2n(p_readwrite->lba);
uint16_t const block_count = __be2n_16(p_readwrite->block_count);
@ -251,12 +252,12 @@ static bool read10_write10_data_xfer(uint8_t port, mscd_interface_t* p_msc)
p_csw->data_residue = p_cbw->xfer_bytes;
p_csw->status = MSC_CSW_STATUS_FAILED;
tusb_dcd_edpt_stall(port, edpt_addr);
tusb_dcd_edpt_stall(port, ep_addr);
return true;
} else if (xferred_block < block_count)
{
TU_ASSERT( tusb_dcd_edpt_xfer(port, edpt_addr, p_buffer, xferred_byte, true), TUSB_ERROR_DCD_EDPT_XFER );
TU_ASSERT( tusb_dcd_edpt_xfer(port, ep_addr, p_buffer, xferred_byte, true), TUSB_ERROR_DCD_EDPT_XFER );
// adjust lba, block_count, xfer_bytes for the next call
p_readwrite->lba = __n2be(lba+xferred_block);
@ -267,7 +268,7 @@ static bool read10_write10_data_xfer(uint8_t port, mscd_interface_t* p_msc)
}else
{
p_csw->status = MSC_CSW_STATUS_PASSED;
TU_ASSERT( tusb_dcd_edpt_queue_xfer(port, edpt_addr, p_buffer, xferred_byte), TUSB_ERROR_DCD_EDPT_XFER );
TU_ASSERT( tusb_dcd_edpt_queue_xfer(port, ep_addr, p_buffer, xferred_byte), TUSB_ERROR_DCD_EDPT_XFER );
return true;
}
}

View File

@ -102,7 +102,7 @@ tusb_error_t tuh_msc_get_capacity(uint8_t dev_addr, uint32_t* p_last_lba, uint32
//--------------------------------------------------------------------+
// PUBLIC API: SCSI COMMAND
//--------------------------------------------------------------------+
static inline void msc_cbw_add_signature(msc_cmd_block_wrapper_t *p_cbw, uint8_t lun)
static inline void msc_cbw_add_signature(msc_cbw_t *p_cbw, uint8_t lun)
{
p_cbw->signature = MSC_CBW_SIGNATURE;
p_cbw->tag = 0xCAFECAFE;
@ -116,16 +116,16 @@ static tusb_error_t msch_command_xfer(msch_interface_t * p_msch, void* p_buffer)
{ // there is data phase
if (p_msch->cbw.dir & TUSB_DIR_IN_MASK)
{
ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cmd_block_wrapper_t), false) );
ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t), false) );
ASSERT_STATUS( hcd_pipe_queue_xfer(p_msch->bulk_in , p_buffer, p_msch->cbw.xfer_bytes) );
}else
{
ASSERT_STATUS( hcd_pipe_queue_xfer(p_msch->bulk_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cmd_block_wrapper_t)) );
ASSERT_STATUS( hcd_pipe_queue_xfer(p_msch->bulk_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t)) );
ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_out , p_buffer, p_msch->cbw.xfer_bytes, false) );
}
}
ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_in , (uint8_t*) &p_msch->csw, sizeof(msc_cmd_status_wrapper_t), true) );
ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_in , (uint8_t*) &p_msch->csw, sizeof(msc_csw_t), true) );
return TUSB_ERROR_NONE;
}
@ -204,7 +204,7 @@ tusb_error_t tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, uint8_t *p_dat
return TUSB_ERROR_NONE;
}
tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_cmd_status_wrapper_t * p_csw)
tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_csw_t * p_csw)
{
msch_interface_t* p_msch = &msch_data[dev_addr-1];
@ -225,8 +225,8 @@ tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_cmd_sta
memcpy(p_msch->cbw.command, &cmd_test_unit_ready, p_msch->cbw.cmd_len);
// TODO MSCH refractor test uinit ready
ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cmd_block_wrapper_t), false) );
ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_in , (uint8_t*) p_csw, sizeof(msc_cmd_status_wrapper_t), true) );
ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t), false) );
ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_in , (uint8_t*) p_csw, sizeof(msc_csw_t), true) );
return TUSB_ERROR_NONE;
}

View File

@ -150,7 +150,7 @@ tusb_error_t tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, uint8_t *p_dat
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
*/
tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_cmd_status_wrapper_t * p_csw) ATTR_WARN_UNUSED_RESULT; // TODO to be refractor
tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_csw_t * p_csw) ATTR_WARN_UNUSED_RESULT; // TODO to be refractor
//tusb_error_t tusbh_msc_scsi_send(uint8_t dev_addr, uint8_t lun, bool is_direction_in,
// uint8_t const * p_command, uint8_t cmd_len,
@ -199,8 +199,8 @@ typedef struct {
uint8_t vendor_id[8];
uint8_t product_id[16];
msc_cmd_block_wrapper_t cbw;
msc_cmd_status_wrapper_t csw;
msc_cbw_t cbw;
msc_csw_t csw;
}msch_interface_t;
void msch_init(void);

View File

@ -56,12 +56,6 @@
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
// LPC11uxx and LPC13uxx requires each buffer has to be 64-byte alignment
#if TUSB_CFG_MCU == MCU_LPC11UXX || TUSB_CFG_MCU == MCU_LPC13UXX
#define ATTR_USB_MIN_ALIGNMENT ATTR_ALIGNED(64)
#else
#define ATTR_USB_MIN_ALIGNMENT
#endif
/// \brief Descriptor pointer collector to all the needed.
typedef struct {