usb: host: allow status stage to be omitted

For testing purposes, allow the status stage to be omitted.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This commit is contained in:
Johann Fischer 2025-06-05 15:35:38 +02:00 committed by Dan Kalowsky
parent 49e2630531
commit 5ba44ffd3e
4 changed files with 28 additions and 3 deletions

View File

@ -295,7 +295,11 @@ static void vrt_hrslt_success(const struct device *dev,
if (xfer->buf != NULL) {
xfer->stage = UHC_CONTROL_STAGE_DATA;
} else {
xfer->stage = UHC_CONTROL_STAGE_STATUS;
if (xfer->no_status) {
finished = true;
} else {
xfer->stage = UHC_CONTROL_STAGE_STATUS;
}
}
break;
@ -311,7 +315,7 @@ static void vrt_hrslt_success(const struct device *dev,
net_buf_pull(buf, length);
LOG_DBG("OUT chunk %zu out of %u", length, buf->len);
if (buf->len == 0) {
if (pkt->ep == USB_CONTROL_EP_OUT) {
if (pkt->ep == USB_CONTROL_EP_OUT && !xfer->no_status) {
xfer->stage = UHC_CONTROL_STAGE_STATUS;
} else {
finished = true;
@ -327,7 +331,7 @@ static void vrt_hrslt_success(const struct device *dev,
LOG_DBG("IN chunk %zu out of %zu", length, net_buf_tailroom(buf));
if (pkt->length < xfer->mps || !net_buf_tailroom(buf)) {
if (pkt->ep == USB_CONTROL_EP_IN) {
if (pkt->ep == USB_CONTROL_EP_IN && !xfer->no_status) {
xfer->stage = UHC_CONTROL_STAGE_STATUS;
} else {
finished = true;

View File

@ -130,6 +130,11 @@ struct uhc_transfer {
unsigned int queued : 1;
/** Control stage status, up to the driver to use it or not */
unsigned int stage : 2;
/**
* The status stage of the control transfer will be omitted.
* This flag is optional and is mainly used for testing.
*/
unsigned int no_status : 1;
/** Pointer to USB device */
struct usb_device *udev;
/** Pointer to transfer completion callback (opaque for the UHC) */

View File

@ -25,6 +25,7 @@ LOG_MODULE_REGISTER(usbh_ch9, CONFIG_USBH_LOG_LEVEL);
#define SETUP_REQ_TIMEOUT 5000U
K_SEM_DEFINE(ch9_req_sync, 0, 1);
static bool ctrl_req_no_status;
static int ch9_req_cb(struct usb_device *const udev, struct uhc_transfer *const xfer)
{
@ -41,6 +42,11 @@ static int ch9_req_cb(struct usb_device *const udev, struct uhc_transfer *const
return 0;
}
void usbh_req_omit_status(const bool omit)
{
ctrl_req_no_status = omit;
}
int usbh_req_setup(struct usb_device *const udev,
const uint8_t bmRequestType,
const uint8_t bRequest,
@ -76,6 +82,10 @@ int usbh_req_setup(struct usb_device *const udev,
}
}
if (IS_ENABLED(CONFIG_ZTEST) && ctrl_req_no_status) {
xfer->no_status = true;
}
ret = usbh_xfer_enqueue(udev, xfer);
if (ret) {
goto buf_alloc_err;

View File

@ -12,6 +12,12 @@
#include "usbh_device.h"
/*
* Mainly used for testing, and driver support is optional. Use it to
* enable or disable omitting the status stage for all requests.
*/
void usbh_req_omit_status(const bool omit);
int usbh_req_setup(struct usb_device *const udev,
const uint8_t bmRequestType,
const uint8_t bRequest,