Skip to content

Commit 480ee0b

Browse files
tmon-nordicrlubos
authored andcommitted
[nrf fromtree] usb: device_next: msc: Reduce memory usage
MSC BOT can work with just one buffer because buffer to receive CBW is never queued at the same time as CSW. SCSI buffer needs to be multiple of bulk endpoint wMaxPacketSize and therefore is suitable for handling both CBW and CSW. Take advantage of this to reduce memory usage. Signed-off-by: Tomasz Moń <[email protected]> (cherry picked from commit 7e11bc5)
1 parent 00c190c commit 480ee0b

File tree

1 file changed

+20
-20
lines changed

1 file changed

+20
-20
lines changed

subsys/usb/device_next/class/usbd_msc.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
6569
UDC_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

6872
struct 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-
144132
static 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,
648642
static 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

Comments
 (0)