@@ -62,8 +62,12 @@ struct CSW {
6262
6363#define MSC_NUM_BUFFERS UTIL_INC(IS_ENABLED(CONFIG_USBD_MSC_DOUBLE_BUFFERING))
6464
65+ #if USBD_MAX_BULK_MPS > CONFIG_USBD_MSC_SCSI_BUFFER_SIZE
66+ #error "SCSI buffer must be at least USB bulk endpoint wMaxPacketSize"
67+ #endif
68+
6569UDC_BUF_POOL_DEFINE (msc_ep_pool , MSC_NUM_INSTANCES * (1 + MSC_NUM_BUFFERS ),
66- USBD_MAX_BULK_MPS , sizeof (struct udc_buf_info ), NULL );
70+ 0 , sizeof (struct udc_buf_info ), NULL );
6771
6872struct msc_event {
6973 struct usbd_class_data * c_data ;
@@ -125,22 +129,6 @@ struct msc_bot_ctx {
125129 size_t scsi_bytes ;
126130};
127131
128- static struct net_buf * msc_buf_alloc (const uint8_t ep )
129- {
130- struct net_buf * buf = NULL ;
131- struct udc_buf_info * bi ;
132-
133- buf = net_buf_alloc (& msc_ep_pool , K_NO_WAIT );
134- if (!buf ) {
135- return NULL ;
136- }
137-
138- bi = udc_get_buf_info (buf );
139- bi -> ep = ep ;
140-
141- return buf ;
142- }
143-
144132static struct net_buf * msc_buf_alloc_data (const uint8_t ep , uint8_t * data , size_t len )
145133{
146134 struct net_buf * buf = NULL ;
@@ -334,6 +322,7 @@ static void msc_queue_cbw(struct usbd_class_data *const c_data)
334322{
335323 struct msc_bot_ctx * ctx = usbd_class_get_private (c_data );
336324 struct net_buf * buf ;
325+ uint8_t * scsi_buf ;
337326 uint8_t ep ;
338327 int ret ;
339328
@@ -342,9 +331,13 @@ static void msc_queue_cbw(struct usbd_class_data *const c_data)
342331 return ;
343332 }
344333
334+ __ASSERT (ctx -> scsi_bufs_used == 0 ,
335+ "CBW can only be queued when SCSI buffers are free" );
336+
345337 LOG_DBG ("Queuing OUT" );
346338 ep = msc_get_bulk_out (c_data );
347- buf = msc_buf_alloc (ep );
339+ scsi_buf = msc_alloc_scsi_buf (ctx );
340+ buf = msc_buf_alloc_data (ep , scsi_buf , USBD_MAX_BULK_MPS );
348341
349342 /* The pool is large enough to support all allocations. Failing alloc
350343 * indicates either a memory leak or logic error.
@@ -355,6 +348,7 @@ static void msc_queue_cbw(struct usbd_class_data *const c_data)
355348 if (ret ) {
356349 LOG_ERR ("Failed to enqueue net_buf for 0x%02x" , ep );
357350 net_buf_unref (buf );
351+ msc_free_scsi_buf (ctx , scsi_buf );
358352 /* 6.6.2 Internal Device Error */
359353 msc_stall_and_wait_for_recovery (ctx );
360354 } else {
@@ -648,6 +642,7 @@ static void msc_handle_bulk_in(struct msc_bot_ctx *ctx,
648642static void msc_send_csw (struct msc_bot_ctx * ctx )
649643{
650644 struct net_buf * buf ;
645+ uint8_t * scsi_buf ;
651646 uint8_t ep ;
652647 int ret ;
653648
@@ -657,20 +652,25 @@ static void msc_send_csw(struct msc_bot_ctx *ctx)
657652 return ;
658653 }
659654
655+ __ASSERT (ctx -> scsi_bufs_used == 0 ,
656+ "CSW can be sent only if SCSI buffers are free" );
657+
660658 /* Convert dCSWDataResidue to LE, other fields are already set */
661659 ctx -> csw .dCSWDataResidue = sys_cpu_to_le32 (ctx -> csw .dCSWDataResidue );
662660 ep = msc_get_bulk_in (ctx -> class_node );
663- buf = msc_buf_alloc (ep );
661+ scsi_buf = msc_alloc_scsi_buf (ctx );
662+ memcpy (scsi_buf , & ctx -> csw , sizeof (ctx -> csw ));
663+ buf = msc_buf_alloc_data (ep , scsi_buf , sizeof (ctx -> csw ));
664664 /* The pool is large enough to support all allocations. Failing alloc
665665 * indicates either a memory leak or logic error.
666666 */
667667 __ASSERT_NO_MSG (buf );
668668
669- net_buf_add_mem (buf , & ctx -> csw , sizeof (ctx -> csw ));
670669 ret = usbd_ep_enqueue (ctx -> class_node , buf );
671670 if (ret ) {
672671 LOG_ERR ("Failed to enqueue net_buf for 0x%02x" , ep );
673672 net_buf_unref (buf );
673+ msc_free_scsi_buf (ctx , scsi_buf );
674674 /* 6.6.2 Internal Device Error */
675675 msc_stall_and_wait_for_recovery (ctx );
676676 } else {
0 commit comments