From fa7752494d368f7c489b37524b1716be07eb4fd6 Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Tue, 7 Jan 2025 15:39:56 +0100 Subject: [PATCH] usb: host: rework usbh_xfer_alloc() parameters The transfers require enpoint MPS for proper transaction handling, assign it in the common place during transfer allsocation so that it can be reused. Some users, such as USBIP, may need to keep a reference to private data, add a parameter for completion callback data. Signed-off-by: Johann Fischer --- drivers/usb/uhc/uhc_common.c | 36 +++++++++++++++++++++++++------- include/zephyr/drivers/usb/uhc.h | 20 ++++++++++-------- subsys/usb/host/usbh_ch9.c | 2 +- subsys/usb/host/usbh_device.h | 6 +++--- subsys/usb/host/usbh_shell.c | 2 +- 5 files changed, 45 insertions(+), 21 deletions(-) diff --git a/drivers/usb/uhc/uhc_common.c b/drivers/usb/uhc/uhc_common.c index 16a6ab3b640..097d4a01457 100644 --- a/drivers/usb/uhc/uhc_common.c +++ b/drivers/usb/uhc/uhc_common.c @@ -93,12 +93,14 @@ void uhc_xfer_buf_free(const struct device *dev, struct net_buf *const buf) struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, const uint8_t ep, - const uint16_t mps, - void *const udev, - void *const cb) + struct usb_device *const udev, + void *const cb, + void *const cb_priv) { + uint8_t ep_idx = USB_EP_GET_IDX(ep) & 0xF; const struct uhc_api *api = dev->api; struct uhc_transfer *xfer = NULL; + uint16_t mps; api->lock(dev); @@ -106,7 +108,26 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, goto xfer_alloc_error; } - LOG_DBG("Allocate xfer, ep 0x%02x cb %p", ep, cb); + if (ep_idx == 0) { + mps = udev->dev_desc.bMaxPacketSize0; + } else { + struct usb_ep_descriptor *ep_desc; + + if (USB_EP_DIR_IS_IN(ep)) { + ep_desc = udev->ep_in[ep_idx].desc; + } else { + ep_desc = udev->ep_out[ep_idx].desc; + } + + if (ep_desc == NULL) { + LOG_ERR("Endpoint 0x%02x is not configured", ep); + goto xfer_alloc_error; + } + + mps = ep_desc->wMaxPacketSize; + } + + LOG_DBG("Allocate xfer, ep 0x%02x mps %u cb %p", ep, mps, cb); if (k_mem_slab_alloc(&uhc_xfer_pool, (void **)&xfer, K_NO_WAIT)) { LOG_ERR("Failed to allocate transfer"); @@ -118,6 +139,7 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, xfer->mps = mps; xfer->udev = udev; xfer->cb = cb; + xfer->priv = cb_priv; xfer_alloc_error: api->unlock(dev); @@ -127,9 +149,9 @@ xfer_alloc_error: struct uhc_transfer *uhc_xfer_alloc_with_buf(const struct device *dev, const uint8_t ep, - const uint16_t mps, - void *const udev, + struct usb_device *const udev, void *const cb, + void *const cb_priv, size_t size) { struct uhc_transfer *xfer; @@ -140,7 +162,7 @@ struct uhc_transfer *uhc_xfer_alloc_with_buf(const struct device *dev, return NULL; } - xfer = uhc_xfer_alloc(dev, ep, mps, udev, cb); + xfer = uhc_xfer_alloc(dev, ep, udev, cb, cb_priv); if (xfer == NULL) { net_buf_unref(buf); return NULL; diff --git a/include/zephyr/drivers/usb/uhc.h b/include/zephyr/drivers/usb/uhc.h index a8ffcc642f0..3d7db75d3c1 100644 --- a/include/zephyr/drivers/usb/uhc.h +++ b/include/zephyr/drivers/usb/uhc.h @@ -93,6 +93,8 @@ struct uhc_transfer { struct usb_device *udev; /** Pointer to transfer completion callback (opaque for the UHC) */ void *cb; + /** Pointer to completion callback private data */ + void *priv; /** Transfer result, 0 on success, other values on error */ int err; }; @@ -361,17 +363,17 @@ static inline int uhc_bus_resume(const struct device *dev) * * @param[in] dev Pointer to device struct of the driver instance * @param[in] ep Endpoint address - * @param[in] mps Maximum packet size of the endpoint - * @param[in] udev Opaque pointer to USB device + * @param[in] udev Pointer to USB device * @param[in] cb Transfer completion callback + * @param[in] cb_priv Completion callback callback private data * * @return pointer to allocated transfer or NULL on error. */ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, const uint8_t ep, - const uint16_t mps, - void *const udev, - void *const cb); + struct usb_device *const udev, + void *const cb, + void *const cb_priv); /** * @brief Allocate UHC transfer with buffer @@ -380,18 +382,18 @@ struct uhc_transfer *uhc_xfer_alloc(const struct device *dev, * * @param[in] dev Pointer to device struct of the driver instance * @param[in] ep Endpoint address - * @param[in] mps Maximum packet size of the endpoint - * @param[in] udev Opaque pointer to USB device + * @param[in] udev Pointer to USB device * @param[in] cb Transfer completion callback + * @param[in] cb_priv Completion callback callback private data * @param[in] size Size of the buffer * * @return pointer to allocated transfer or NULL on error. */ struct uhc_transfer *uhc_xfer_alloc_with_buf(const struct device *dev, const uint8_t ep, - const uint16_t mps, - void *const udev, + struct usb_device *const udev, void *const cb, + void *const cb_priv, size_t size); /** diff --git a/subsys/usb/host/usbh_ch9.c b/subsys/usb/host/usbh_ch9.c index 378d56377fd..ab5e089a4c6 100644 --- a/subsys/usb/host/usbh_ch9.c +++ b/subsys/usb/host/usbh_ch9.c @@ -60,7 +60,7 @@ int usbh_req_setup(struct usb_device *const udev, uint8_t ep = usb_reqtype_is_to_device(&req) ? 0x00 : 0x80; int ret; - xfer = usbh_xfer_alloc(udev, ep, 64, ch9_req_cb); + xfer = usbh_xfer_alloc(udev, ep, ch9_req_cb, NULL); if (!xfer) { return -ENOMEM; } diff --git a/subsys/usb/host/usbh_device.h b/subsys/usb/host/usbh_device.h index ac8ffed481e..df1391c5784 100644 --- a/subsys/usb/host/usbh_device.h +++ b/subsys/usb/host/usbh_device.h @@ -24,12 +24,12 @@ struct usb_device *usbh_device_get_any(struct usbh_contex *const ctx); /* Wrappers around to avoid glue UHC calls. */ static inline struct uhc_transfer *usbh_xfer_alloc(struct usb_device *udev, const uint8_t ep, - const uint16_t mps, - usbh_udev_cb_t cb) + usbh_udev_cb_t cb, + void *const cb_priv) { struct usbh_contex *const ctx = udev->ctx; - return uhc_xfer_alloc(ctx->dev, ep, mps, udev, cb); + return uhc_xfer_alloc(ctx->dev, ep, udev, cb, cb_priv); } static inline int usbh_xfer_buf_add(const struct usb_device *udev, diff --git a/subsys/usb/host/usbh_shell.c b/subsys/usb/host/usbh_shell.c index 6bda97debb6..c151daa27b2 100644 --- a/subsys/usb/host/usbh_shell.c +++ b/subsys/usb/host/usbh_shell.c @@ -87,7 +87,7 @@ static int cmd_bulk(const struct shell *sh, size_t argc, char **argv) ep = strtol(argv[1], NULL, 16); len = MIN(sizeof(vreq_test_buf), strtol(argv[2], NULL, 10)); - xfer = usbh_xfer_alloc(udev, ep, 512, bulk_req_cb); + xfer = usbh_xfer_alloc(udev, ep, bulk_req_cb, NULL); if (!xfer) { shell_error(sh, "host: Failed to allocate transfer"); return -ENOMEM;