4444//--------------------------------------------------------------------+
4545// MACRO CONSTANT TYPEDEF
4646//--------------------------------------------------------------------+
47- enum
48- {
47+ enum {
4948 MSC_STAGE_CMD = 0 ,
5049 MSC_STAGE_DATA ,
5150 MSC_STAGE_STATUS ,
5251 MSC_STAGE_STATUS_SENT ,
5352 MSC_STAGE_NEED_RESET ,
5453};
5554
56- typedef struct
57- {
58- // TODO optimize alignment
59- CFG_TUSB_MEM_ALIGN msc_cbw_t cbw ;
60- CFG_TUSB_MEM_ALIGN msc_csw_t csw ;
55+ typedef struct {
56+ union {
57+ CFG_TUD_MEM_ALIGN msc_cbw_t cbw ;
58+ TUD_DCACHE_PADDING ;
59+ };
60+ union {
61+ CFG_TUD_MEM_ALIGN msc_csw_t csw ;
62+ TUD_DCACHE_PADDING ;
63+ };
64+ union {
65+ CFG_TUD_MEM_ALIGN uint8_t ep_buf [CFG_TUD_MSC_EP_BUFSIZE ];
66+ TUD_DCACHE_PADDING ;
67+ };
6168
6269 uint8_t itf_num ;
6370 uint8_t ep_in ;
@@ -74,8 +81,7 @@ typedef struct
7481 uint8_t add_sense_qualifier ;
7582}mscd_interface_t ;
7683
77- CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static mscd_interface_t _mscd_itf ;
78- CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t _mscd_buf [CFG_TUD_MSC_EP_BUFSIZE ];
84+ CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN static mscd_interface_t _mscd_itf ;
7985
8086//--------------------------------------------------------------------+
8187// INTERNAL OBJECT & FUNCTION DECLARATION
@@ -86,28 +92,24 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc);
8692static void proc_write10_cmd (uint8_t rhport , mscd_interface_t * p_msc );
8793static void proc_write10_new_data (uint8_t rhport , mscd_interface_t * p_msc , uint32_t xferred_bytes );
8894
89- TU_ATTR_ALWAYS_INLINE static inline bool is_data_in (uint8_t dir )
90- {
95+ TU_ATTR_ALWAYS_INLINE static inline bool is_data_in (uint8_t dir ) {
9196 return tu_bit_test (dir , 7 );
9297}
9398
94- static inline bool send_csw (uint8_t rhport , mscd_interface_t * p_msc )
95- {
99+ static inline bool send_csw (uint8_t rhport , mscd_interface_t * p_msc ) {
96100 // Data residue is always = host expect - actual transferred
97101 p_msc -> csw .data_residue = p_msc -> cbw .total_bytes - p_msc -> xferred_len ;
98102
99103 p_msc -> stage = MSC_STAGE_STATUS_SENT ;
100104 return usbd_edpt_xfer (rhport , p_msc -> ep_in , (uint8_t * ) & p_msc -> csw , sizeof (msc_csw_t ));
101105}
102106
103- static inline bool prepare_cbw (uint8_t rhport , mscd_interface_t * p_msc )
104- {
107+ static inline bool prepare_cbw (uint8_t rhport , mscd_interface_t * p_msc ) {
105108 p_msc -> stage = MSC_STAGE_CMD ;
106109 return usbd_edpt_xfer (rhport , p_msc -> ep_out , (uint8_t * ) & p_msc -> cbw , sizeof (msc_cbw_t ));
107110}
108111
109- static void fail_scsi_op (uint8_t rhport , mscd_interface_t * p_msc , uint8_t status )
110- {
112+ static void fail_scsi_op (uint8_t rhport , mscd_interface_t * p_msc , uint8_t status ) {
111113 msc_cbw_t const * p_cbw = & p_msc -> cbw ;
112114 msc_csw_t * p_csw = & p_msc -> csw ;
113115
@@ -116,39 +118,34 @@ static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status
116118 p_msc -> stage = MSC_STAGE_STATUS ;
117119
118120 // failed but sense key is not set: default to Illegal Request
119- if ( p_msc -> sense_key == 0 ) tud_msc_set_sense (p_cbw -> lun , SCSI_SENSE_ILLEGAL_REQUEST , 0x20 , 0x00 );
121+ if (p_msc -> sense_key == 0 ) {
122+ tud_msc_set_sense (p_cbw -> lun , SCSI_SENSE_ILLEGAL_REQUEST , 0x20 , 0x00 );
123+ }
120124
121125 // If there is data stage and not yet complete, stall it
122- if ( p_cbw -> total_bytes && p_csw -> data_residue )
123- {
124- if ( is_data_in (p_cbw -> dir ) )
125- {
126+ if (p_cbw -> total_bytes && p_csw -> data_residue ) {
127+ if (is_data_in (p_cbw -> dir )) {
126128 usbd_edpt_stall (rhport , p_msc -> ep_in );
127- }
128- else
129- {
129+ } else {
130130 usbd_edpt_stall (rhport , p_msc -> ep_out );
131131 }
132132 }
133133}
134134
135- static inline uint32_t rdwr10_get_lba (uint8_t const command [])
136- {
135+ static inline uint32_t rdwr10_get_lba (uint8_t const command []) {
137136 // use offsetof to avoid pointer to the odd/unaligned address
138137 uint32_t const lba = tu_unaligned_read32 (command + offsetof(scsi_write10_t , lba ));
139138
140139 // lba is in Big Endian
141140 return tu_ntohl (lba );
142141}
143142
144- static inline uint16_t rdwr10_get_blockcount (msc_cbw_t const * cbw )
145- {
143+ static inline uint16_t rdwr10_get_blockcount (msc_cbw_t const * cbw ) {
146144 uint16_t const block_count = tu_unaligned_read16 (cbw -> command + offsetof(scsi_write10_t , block_count ));
147145 return tu_ntohs (block_count );
148146}
149147
150- static inline uint16_t rdwr10_get_blocksize (msc_cbw_t const * cbw )
151- {
148+ static inline uint16_t rdwr10_get_blocksize (msc_cbw_t const * cbw ) {
152149 // first extract block count in the command
153150 uint16_t const block_count = rdwr10_get_blockcount (cbw );
154151
@@ -158,40 +155,28 @@ static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw)
158155 return (uint16_t ) (cbw -> total_bytes / block_count );
159156}
160157
161- uint8_t rdwr10_validate_cmd (msc_cbw_t const * cbw )
162- {
158+ uint8_t rdwr10_validate_cmd (msc_cbw_t const * cbw ) {
163159 uint8_t status = MSC_CSW_STATUS_PASSED ;
164160 uint16_t const block_count = rdwr10_get_blockcount (cbw );
165161
166- if ( cbw -> total_bytes == 0 )
167- {
168- if ( block_count )
169- {
162+ if (cbw -> total_bytes == 0 ) {
163+ if (block_count ) {
170164 TU_LOG_DRV (" SCSI case 2 (Hn < Di) or case 3 (Hn < Do) \r\n" );
171165 status = MSC_CSW_STATUS_PHASE_ERROR ;
172- }else
173- {
166+ } else {
174167 // no data transfer, only exist in complaint test suite
175168 }
176- }else
177- {
178- if ( SCSI_CMD_READ_10 == cbw -> command [0 ] && !is_data_in (cbw -> dir ) )
179- {
169+ } else {
170+ if (SCSI_CMD_READ_10 == cbw -> command [0 ] && !is_data_in (cbw -> dir )) {
180171 TU_LOG_DRV (" SCSI case 10 (Ho <> Di)\r\n" );
181172 status = MSC_CSW_STATUS_PHASE_ERROR ;
182- }
183- else if ( SCSI_CMD_WRITE_10 == cbw -> command [0 ] && is_data_in (cbw -> dir ) )
184- {
173+ } else if (SCSI_CMD_WRITE_10 == cbw -> command [0 ] && is_data_in (cbw -> dir )) {
185174 TU_LOG_DRV (" SCSI case 8 (Hi <> Do)\r\n" );
186175 status = MSC_CSW_STATUS_PHASE_ERROR ;
187- }
188- else if ( 0 == block_count )
189- {
176+ } else if (0 == block_count ) {
190177 TU_LOG_DRV (" SCSI case 4 Hi > Dn (READ10) or case 9 Ho > Dn (WRITE10) \r\n" );
191- status = MSC_CSW_STATUS_FAILED ;
192- }
193- else if ( cbw -> total_bytes / block_count == 0 )
194- {
178+ status = MSC_CSW_STATUS_FAILED ;
179+ } else if (cbw -> total_bytes / block_count == 0 ) {
195180 TU_LOG_DRV (" Computed block size = 0. SCSI case 7 Hi < Di (READ10) or case 13 Ho < Do (WRIT10)\r\n" );
196181 status = MSC_CSW_STATUS_PHASE_ERROR ;
197182 }
@@ -205,8 +190,7 @@ uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw)
205190//--------------------------------------------------------------------+
206191#if CFG_TUSB_DEBUG >= CFG_TUD_MSC_LOG_LEVEL
207192
208- TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup [] =
209- {
193+ TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup [] = {
210194 { .key = SCSI_CMD_TEST_UNIT_READY , .data = "Test Unit Ready" },
211195 { .key = SCSI_CMD_INQUIRY , .data = "Inquiry" },
212196 { .key = SCSI_CMD_MODE_SELECT_6 , .data = "Mode_Select 6" },
@@ -220,8 +204,7 @@ TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] =
220204 { .key = SCSI_CMD_WRITE_10 , .data = "Write10" }
221205};
222206
223- TU_ATTR_UNUSED tu_static tu_lookup_table_t const _msc_scsi_cmd_table =
224- {
207+ TU_ATTR_UNUSED tu_static tu_lookup_table_t const _msc_scsi_cmd_table = {
225208 .count = TU_ARRAY_SIZE (_msc_scsi_cmd_lookup ),
226209 .items = _msc_scsi_cmd_lookup
227210};
@@ -462,25 +445,25 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
462445 // 2. IN & Zero: Process if is built-in, else Invoke app callback. Skip DATA if zero length
463446 if ( (p_cbw -> total_bytes > 0 ) && !is_data_in (p_cbw -> dir ) )
464447 {
465- if (p_cbw -> total_bytes > sizeof ( _mscd_buf ) )
448+ if (p_cbw -> total_bytes > CFG_TUD_MSC_EP_BUFSIZE )
466449 {
467450 TU_LOG_DRV (" SCSI reject non READ10/WRITE10 with large data\r\n" );
468451 fail_scsi_op (rhport , p_msc , MSC_CSW_STATUS_FAILED );
469452 }else
470453 {
471454 // Didn't check for case 9 (Ho > Dn), which requires examining scsi command first
472455 // but it is OK to just receive data then responded with failed status
473- TU_ASSERT ( usbd_edpt_xfer (rhport , p_msc -> ep_out , _mscd_buf , (uint16_t ) p_msc -> total_len ) );
456+ TU_ASSERT ( usbd_edpt_xfer (rhport , p_msc -> ep_out , p_msc -> ep_buf , (uint16_t ) p_msc -> total_len ) );
474457 }
475458 }else
476459 {
477460 // First process if it is a built-in commands
478- int32_t resplen = proc_builtin_scsi (p_cbw -> lun , p_cbw -> command , _mscd_buf , sizeof ( _mscd_buf ) );
461+ int32_t resplen = proc_builtin_scsi (p_cbw -> lun , p_cbw -> command , p_msc -> ep_buf , CFG_TUD_MSC_EP_BUFSIZE );
479462
480463 // Invoke user callback if not built-in
481464 if ( (resplen < 0 ) && (p_msc -> sense_key == 0 ) )
482465 {
483- resplen = tud_msc_scsi_cb (p_cbw -> lun , p_cbw -> command , _mscd_buf , (uint16_t ) p_msc -> total_len );
466+ resplen = tud_msc_scsi_cb (p_cbw -> lun , p_cbw -> command , p_msc -> ep_buf , (uint16_t ) p_msc -> total_len );
484467 }
485468
486469 if ( resplen < 0 )
@@ -513,7 +496,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
513496 {
514497 // cannot return more than host expect
515498 p_msc -> total_len = tu_min32 ((uint32_t ) resplen , p_cbw -> total_bytes );
516- TU_ASSERT ( usbd_edpt_xfer (rhport , p_msc -> ep_in , _mscd_buf , (uint16_t ) p_msc -> total_len ) );
499+ TU_ASSERT ( usbd_edpt_xfer (rhport , p_msc -> ep_in , p_msc -> ep_buf , (uint16_t ) p_msc -> total_len ) );
517500 }
518501 }
519502 }
@@ -522,7 +505,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
522505
523506 case MSC_STAGE_DATA :
524507 TU_LOG_DRV (" SCSI Data [Lun%u]\r\n" , p_cbw -> lun );
525- //TU_LOG_MEM(MSC_DEBUG, _mscd_buf , xferred_bytes, 2);
508+ //TU_LOG_MEM(MSC_DEBUG, p_msc->ep_buf , xferred_bytes, 2);
526509
527510 if (SCSI_CMD_READ_10 == p_cbw -> command [0 ])
528511 {
@@ -548,7 +531,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
548531 // OUT transfer, invoke callback if needed
549532 if ( !is_data_in (p_cbw -> dir ) )
550533 {
551- int32_t cb_result = tud_msc_scsi_cb (p_cbw -> lun , p_cbw -> command , _mscd_buf , (uint16_t ) p_msc -> total_len );
534+ int32_t cb_result = tud_msc_scsi_cb (p_cbw -> lun , p_cbw -> command , p_msc -> ep_buf , (uint16_t ) p_msc -> total_len );
552535
553536 if ( cb_result < 0 )
554537 {
@@ -861,11 +844,11 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
861844 uint32_t const lba = rdwr10_get_lba (p_cbw -> command ) + (p_msc -> xferred_len / block_sz );
862845
863846 // remaining bytes capped at class buffer
864- int32_t nbytes = (int32_t ) tu_min32 (sizeof ( _mscd_buf ) , p_cbw -> total_bytes - p_msc -> xferred_len );
847+ int32_t nbytes = (int32_t ) tu_min32 (CFG_TUD_MSC_EP_BUFSIZE , p_cbw -> total_bytes - p_msc -> xferred_len );
865848
866849 // Application can consume smaller bytes
867850 uint32_t const offset = p_msc -> xferred_len % block_sz ;
868- nbytes = tud_msc_read10_cb (p_cbw -> lun , lba , offset , _mscd_buf , (uint32_t ) nbytes );
851+ nbytes = tud_msc_read10_cb (p_cbw -> lun , lba , offset , p_msc -> ep_buf , (uint32_t ) nbytes );
869852
870853 if ( nbytes < 0 )
871854 {
@@ -884,7 +867,7 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
884867 }
885868 else
886869 {
887- TU_ASSERT ( usbd_edpt_xfer (rhport , p_msc -> ep_in , _mscd_buf , (uint16_t ) nbytes ), );
870+ TU_ASSERT ( usbd_edpt_xfer (rhport , p_msc -> ep_in , p_msc -> ep_buf , (uint16_t ) nbytes ), );
888871 }
889872}
890873
@@ -908,10 +891,10 @@ static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
908891 }
909892
910893 // remaining bytes capped at class buffer
911- uint16_t nbytes = (uint16_t ) tu_min32 (sizeof ( _mscd_buf ) , p_cbw -> total_bytes - p_msc -> xferred_len );
894+ uint16_t nbytes = (uint16_t ) tu_min32 (CFG_TUD_MSC_EP_BUFSIZE , p_cbw -> total_bytes - p_msc -> xferred_len );
912895
913896 // Write10 callback will be called later when usb transfer complete
914- TU_ASSERT ( usbd_edpt_xfer (rhport , p_msc -> ep_out , _mscd_buf , nbytes ), );
897+ TU_ASSERT ( usbd_edpt_xfer (rhport , p_msc -> ep_out , p_msc -> ep_buf , nbytes ), );
915898}
916899
917900// process new data arrived from WRITE10
@@ -927,7 +910,7 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3
927910
928911 // Invoke callback to consume new data
929912 uint32_t const offset = p_msc -> xferred_len % block_sz ;
930- int32_t nbytes = tud_msc_write10_cb (p_cbw -> lun , lba , offset , _mscd_buf , xferred_bytes );
913+ int32_t nbytes = tud_msc_write10_cb (p_cbw -> lun , lba , offset , p_msc -> ep_buf , xferred_bytes );
931914
932915 if ( nbytes < 0 )
933916 {
@@ -950,7 +933,7 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3
950933 if ( nbytes > 0 )
951934 {
952935 p_msc -> xferred_len += (uint16_t ) nbytes ;
953- memmove (_mscd_buf , _mscd_buf + nbytes , left_over );
936+ memmove (p_msc -> ep_buf , p_msc -> ep_buf + nbytes , left_over );
954937 }
955938
956939 // simulate an transfer complete with adjusted parameters --> callback will be invoked with adjusted parameter
0 commit comments