Skip to content

Commit 8321de5

Browse files
tmon-nordicrlubos
authored andcommitted
[nrf fromtree] usb: device_next: msc: stall endpoints on enqueue error
When endpoint enqueue fails the device has no reliable means of recovery other than a reset. Implement 6.6.2 Internal Device Error handling on failed enqueue. Signed-off-by: Tomasz Moń <[email protected]> (cherry picked from commit 78291d4)
1 parent 47a5d74 commit 8321de5

File tree

1 file changed

+34
-22
lines changed

1 file changed

+34
-22
lines changed

subsys/usb/device_next/class/usbd_msc.c

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,31 @@ static uint8_t msc_get_bulk_out(struct usbd_class_data *const c_data)
214214
return desc->if0_out_ep.bEndpointAddress;
215215
}
216216

217+
static void msc_stall_bulk_out_ep(struct usbd_class_data *const c_data)
218+
{
219+
uint8_t ep;
220+
221+
ep = msc_get_bulk_out(c_data);
222+
usbd_ep_set_halt(usbd_class_get_ctx(c_data), ep);
223+
}
224+
225+
static void msc_stall_bulk_in_ep(struct usbd_class_data *const c_data)
226+
{
227+
uint8_t ep;
228+
229+
ep = msc_get_bulk_in(c_data);
230+
usbd_ep_set_halt(usbd_class_get_ctx(c_data), ep);
231+
}
232+
233+
static void msc_stall_and_wait_for_recovery(struct msc_bot_ctx *ctx)
234+
{
235+
atomic_set_bit(&ctx->bits, MSC_BULK_IN_WEDGED);
236+
atomic_set_bit(&ctx->bits, MSC_BULK_OUT_WEDGED);
237+
msc_stall_bulk_in_ep(ctx->class_node);
238+
msc_stall_bulk_out_ep(ctx->class_node);
239+
ctx->state = MSC_BBB_WAIT_FOR_RESET_RECOVERY;
240+
}
241+
217242
static void msc_queue_bulk_out_ep(struct usbd_class_data *const c_data, bool data)
218243
{
219244
struct msc_bot_ctx *ctx = usbd_class_get_private(c_data);
@@ -246,25 +271,11 @@ static void msc_queue_bulk_out_ep(struct usbd_class_data *const c_data, bool dat
246271
LOG_ERR("Failed to enqueue net_buf for 0x%02x", ep);
247272
net_buf_unref(buf);
248273
atomic_clear_bit(&ctx->bits, MSC_BULK_OUT_QUEUED);
274+
/* 6.6.2 Internal Device Error */
275+
msc_stall_and_wait_for_recovery(ctx);
249276
}
250277
}
251278

252-
static void msc_stall_bulk_out_ep(struct usbd_class_data *const c_data)
253-
{
254-
uint8_t ep;
255-
256-
ep = msc_get_bulk_out(c_data);
257-
usbd_ep_set_halt(usbd_class_get_ctx(c_data), ep);
258-
}
259-
260-
static void msc_stall_bulk_in_ep(struct usbd_class_data *const c_data)
261-
{
262-
uint8_t ep;
263-
264-
ep = msc_get_bulk_in(c_data);
265-
usbd_ep_set_halt(usbd_class_get_ctx(c_data), ep);
266-
}
267-
268279
static void msc_reset_handler(struct usbd_class_data *c_data)
269280
{
270281
struct msc_bot_ctx *ctx = usbd_class_get_private(c_data);
@@ -343,6 +354,8 @@ static void msc_process_read(struct msc_bot_ctx *ctx)
343354
LOG_ERR("Failed to enqueue net_buf for 0x%02x", ep);
344355
net_buf_unref(buf);
345356
atomic_clear_bit(&ctx->bits, MSC_BULK_IN_QUEUED);
357+
/* 6.6.2 Internal Device Error */
358+
msc_stall_and_wait_for_recovery(ctx);
346359
}
347360
}
348361

@@ -500,11 +513,7 @@ static void msc_handle_bulk_out(struct msc_bot_ctx *ctx,
500513
} else {
501514
/* 6.6.1 CBW Not Valid */
502515
LOG_INF("Invalid CBW");
503-
atomic_set_bit(&ctx->bits, MSC_BULK_IN_WEDGED);
504-
atomic_set_bit(&ctx->bits, MSC_BULK_OUT_WEDGED);
505-
msc_stall_bulk_in_ep(ctx->class_node);
506-
msc_stall_bulk_out_ep(ctx->class_node);
507-
ctx->state = MSC_BBB_WAIT_FOR_RESET_RECOVERY;
516+
msc_stall_and_wait_for_recovery(ctx);
508517
}
509518
} else if (ctx->state == MSC_BBB_PROCESS_WRITE) {
510519
msc_process_write(ctx, buf, len);
@@ -567,8 +576,11 @@ static void msc_send_csw(struct msc_bot_ctx *ctx)
567576
LOG_ERR("Failed to enqueue net_buf for 0x%02x", ep);
568577
net_buf_unref(buf);
569578
atomic_clear_bit(&ctx->bits, MSC_BULK_IN_QUEUED);
579+
/* 6.6.2 Internal Device Error */
580+
msc_stall_and_wait_for_recovery(ctx);
581+
} else {
582+
ctx->state = MSC_BBB_WAIT_FOR_CSW_SENT;
570583
}
571-
ctx->state = MSC_BBB_WAIT_FOR_CSW_SENT;
572584
}
573585

574586
static void usbd_msc_handle_request(struct usbd_class_data *c_data,

0 commit comments

Comments
 (0)