summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2023-12-05 21:34:51 +0800
committersakumisu <[email protected]>2023-12-05 21:34:51 +0800
commitb1e95f0ca3fc1940b0cfc71a8e593964826b34a4 (patch)
treea53861c40704799ef450e6d074c64fe3a4bb61a6
parent14f1f597f11f55e943ee35a3a3c842217a29f142 (diff)
update hc template
-rw-r--r--class/template/usbd_xxx.c4
-rw-r--r--class/template/usbd_xxx.h2
-rw-r--r--class/template/usbh_xxx.c12
-rw-r--r--class/template/usbh_xxx.h9
-rw-r--r--port/template/usb_hc.c163
5 files changed, 79 insertions, 111 deletions
diff --git a/class/template/usbd_xxx.c b/class/template/usbd_xxx.c
index f35911c5..68348ff9 100644
--- a/class/template/usbd_xxx.c
+++ b/class/template/usbd_xxx.c
@@ -28,12 +28,12 @@ static void xxx_notify_handler(uint8_t event, void *arg)
}
}
-void usbd_xxx_add_interface(usbd_class_t *devclass, usbd_interface_t *intf)
+struct usbd_interface *usbd_xxx_init_intf(struct usbd_interface *intf)
{
intf->class_interface_handler = xxx_class_interface_request_handler;
intf->class_endpoint_handler = NULL;
intf->vendor_handler = NULL;
intf->notify_handler = xxx_notify_handler;
- usbd_class_add_interface(devclass, intf);
+ return intf;
}
diff --git a/class/template/usbd_xxx.h b/class/template/usbd_xxx.h
index 26f4b279..e77856e8 100644
--- a/class/template/usbd_xxx.h
+++ b/class/template/usbd_xxx.h
@@ -7,7 +7,7 @@
extern "C" {
#endif
-void usbd_xxx_add_interface(usbd_class_t *devclass, usbd_interface_t *intf);
+struct usbd_interface *usbd_xxx_init_intf(struct usbd_interface *intf);
#ifdef __cplusplus
}
diff --git a/class/template/usbh_xxx.c b/class/template/usbh_xxx.c
index ae177983..1f792ae2 100644
--- a/class/template/usbh_xxx.c
+++ b/class/template/usbh_xxx.c
@@ -3,6 +3,7 @@
#define DEV_FORMAT "/dev/xxx"
+#define CONFIG_USBHOST_MAX_CUSTOM_CLASS 1
static struct usbh_xxx g_xxx_class[CONFIG_USBHOST_MAX_CUSTOM_CLASS];
static uint32_t g_devinuse = 0;
@@ -33,14 +34,13 @@ static void usbh_xxx_class_free(struct usbh_xxx *xxx_class)
static int usbh_xxx_connect(struct usbh_hubport *hport, uint8_t intf)
{
- struct usbh_endpoint_cfg ep_cfg = { 0 };
struct usb_endpoint_descriptor *ep_desc;
int ret;
struct usbh_xxx *xxx_class = usbh_xxx_class_alloc();
if (xxx_class == NULL) {
USB_LOG_ERR("Fail to alloc xxx_class\r\n");
- return -ENOMEM;
+ return -USB_ERR_NOMEM;
}
return ret;
@@ -54,12 +54,12 @@ static int usbh_xxx_disconnect(struct usbh_hubport *hport, uint8_t intf)
struct usbh_xxx *xxx_class = (struct usbh_xxx *)hport->config.intf[intf].priv;
if (xxx_class) {
- if (xxx_class->bulkin) {
- usbh_pipe_free(xxx_class->bulkin);
+ if (xxx_class->xxxin) {
+ usbh_kill_urb(&xxx_class->xxxin_urb);
}
- if (xxx_class->bulkout) {
- usbh_pipe_free(xxx_class->bulkout);
+ if (xxx_class->xxxout) {
+ usbh_kill_urb(&xxx_class->xxxout_urb);
}
if (hport->config.intf[intf].devname[0] != '\0') {
diff --git a/class/template/usbh_xxx.h b/class/template/usbh_xxx.h
index 75b0bf26..655d5e8e 100644
--- a/class/template/usbh_xxx.h
+++ b/class/template/usbh_xxx.h
@@ -5,11 +5,16 @@
struct usbh_xxx {
struct usbh_hubport *hport;
+ struct usb_endpoint_descriptor *xxxin;
+ struct usb_endpoint_descriptor *xxxout;
+ struct usbh_urb xxxin_urb;
+ struct usbh_urb xxxout_urb;
uint8_t intf; /* interface number */
uint8_t minor;
- usbh_pipe_t bulkin; /* bulk IN endpoint */
- usbh_pipe_t bulkout; /* bulk OUT endpoint */
};
+void usbh_xxx_run(struct usbh_xxx *xxx_class);
+void usbh_xxx_stop(struct usbh_xxx *xxx_class);
+
#endif \ No newline at end of file
diff --git a/port/template/usb_hc.c b/port/template/usb_hc.c
index 2bc8ce07..c8258582 100644
--- a/port/template/usb_hc.c
+++ b/port/template/usb_hc.c
@@ -16,12 +16,6 @@
#endif
struct dwc2_pipe {
- uint8_t dev_addr;
- uint8_t ep_addr;
- uint8_t ep_type;
- uint8_t ep_interval;
- uint8_t speed;
- uint16_t ep_mps;
bool inuse;
uint32_t xfrd;
volatile bool waiter;
@@ -34,7 +28,7 @@ struct dwc2_hcd {
struct dwc2_pipe pipe_pool[CONFIG_USBHOST_PIPE_NUM];
} g_dwc2_hcd;
-static int dwc2_pipe_alloc(void)
+static int dwc2_chan_alloc(void)
{
int chidx;
@@ -48,7 +42,7 @@ static int dwc2_pipe_alloc(void)
return -1;
}
-static void dwc2_pipe_free(struct dwc2_pipe *pipe)
+static void dwc2_chan_free(struct dwc2_pipe *pipe)
{
pipe->inuse = false;
}
@@ -104,7 +98,7 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
case HUB_FEATURE_HUB_C_OVERCURRENT:
break;
default:
- return -EPIPE;
+ return -USB_ERR_NOTSUPP;
}
break;
case HUB_REQUEST_SET_FEATURE:
@@ -114,7 +108,7 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
case HUB_FEATURE_HUB_C_OVERCURRENT:
break;
default:
- return -EPIPE;
+ return -USB_ERR_NOTSUPP;
}
break;
case HUB_REQUEST_GET_DESCRIPTOR:
@@ -129,7 +123,7 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
switch (setup->bRequest) {
case HUB_REQUEST_CLEAR_FEATURE:
if (!port || port > nports) {
- return -EPIPE;
+ return -USB_ERR_INVAL;
}
switch (setup->wValue) {
@@ -150,12 +144,12 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
case HUB_PORT_FEATURE_C_RESET:
break;
default:
- return -EPIPE;
+ return -USB_ERR_NOTSUPP;
}
break;
case HUB_REQUEST_SET_FEATURE:
if (!port || port > nports) {
- return -EPIPE;
+ return -USB_ERR_INVAL;
}
switch (setup->wValue) {
@@ -168,12 +162,12 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
break;
default:
- return -EPIPE;
+ return -USB_ERR_NOTSUPP;
}
break;
case HUB_REQUEST_GET_STATUS:
if (!port || port > nports) {
- return -EPIPE;
+ return -USB_ERR_INVAL;
}
memcpy(buf, &status, 4);
@@ -185,96 +179,44 @@ int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
return 0;
}
-int usbh_ep_pipe_reconfigure(usbh_pipe_t pipe, uint8_t dev_addr, uint8_t ep_mps, uint8_t mult)
-{
- struct dwc2_pipe *chan;
-
- chan = (struct dwc2_pipe *)pipe;
-
- chan->dev_addr = dev_addr;
- chan->ep_mps = ep_mps;
-
- return 0;
-}
-
-int usbh_pipe_alloc(usbh_pipe_t *pipe, const struct usbh_endpoint_cfg *ep_cfg)
-{
- struct dwc2_pipe *chan;
- int chidx;
- usb_osal_sem_t waitsem;
-
- chidx = dwc2_pipe_alloc();
- if (chidx == -1) {
- return -ENOMEM;
- }
-
- chan = &g_dwc2_hcd.pipe_pool[chidx];
-
- /* store variables */
- waitsem = chan->waitsem;
-
- memset(chan, 0, sizeof(struct dwc2_pipe));
-
- chan->ep_addr = ep_cfg->ep_addr;
- chan->ep_type = ep_cfg->ep_type;
- chan->ep_mps = ep_cfg->ep_mps;
- chan->ep_interval = ep_cfg->ep_interval;
- chan->speed = ep_cfg->hport->speed;
- chan->dev_addr = ep_cfg->hport->dev_addr;
- chan->hport = ep_cfg->hport;
-
- /* restore variables */
- chan->inuse = true;
- chan->waitsem = waitsem;
-
- *pipe = (usbh_pipe_t)chan;
-
- return 0;
-}
-
-int usbh_pipe_free(usbh_pipe_t pipe)
-{
- return 0;
-}
-
int usbh_submit_urb(struct usbh_urb *urb)
{
- struct dwc2_pipe *chan;
+ struct dwc2_chan *chan;
size_t flags;
int ret = 0;
+ int chidx;
- if (!urb) {
- return -EINVAL;
- }
-
- chan = urb->pipe;
-
- if (!chan) {
- return -EINVAL;
+ if (!urb || !urb->hport || !urb->ep) {
+ return -USB_ERR_INVAL;
}
- if (!chan->hport->connected) {
- return -ENODEV;
+ if (!urb->hport->connected) {
+ return -USB_ERR_NOTCONN;
}
- if (chan->urb) {
- return -EBUSY;
+ if (urb->errorcode == -USB_ERR_BUSY) {
+ return -USB_ERR_BUSY;
}
flags = usb_osal_enter_critical_section();
- chan->waiter = false;
- chan->xfrd = 0;
+ chidx = dwc2_chan_alloc();
+ if (chidx == -1) {
+ usb_osal_leave_critical_section(flags);
+ return -USB_ERR_NOMEM;
+ }
+
+ chan = &g_dwc2_hcd.chan_pool[chidx];
+ chan->chidx = chidx;
chan->urb = urb;
- urb->errorcode = -EBUSY;
+
+ urb->hcpriv = chan;
+ urb->errorcode = -USB_ERR_BUSY;
urb->actual_length = 0;
- if (urb->timeout > 0) {
- chan->waiter = true;
- }
usb_osal_leave_critical_section(flags);
- switch (chan->ep_type) {
+ switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
case USB_ENDPOINT_TYPE_CONTROL:
break;
case USB_ENDPOINT_TYPE_BULK:
@@ -286,46 +228,67 @@ int usbh_submit_urb(struct usbh_urb *urb)
default:
break;
}
+
if (urb->timeout > 0) {
/* wait until timeout or sem give */
ret = usb_osal_sem_take(chan->waitsem, urb->timeout);
if (ret < 0) {
goto errout_timeout;
}
-
+ urb->timeout = 0;
ret = urb->errorcode;
+ /* we can free chan when waitsem is done */
+ dwc2_chan_free(chan);
}
return ret;
errout_timeout:
- chan->waiter = false;
+ urb->timeout = 0;
usbh_kill_urb(urb);
return ret;
}
int usbh_kill_urb(struct usbh_urb *urb)
{
- struct dwc2_pipe *pipe;
+ struct dwc2_chan *chan;
size_t flags;
- pipe = urb->pipe;
+ if (!urb || !urb->hcpriv) {
+ return -USB_ERR_INVAL;
+ }
+
+ flags = usb_osal_enter_critical_section();
- if (!urb || !pipe) {
- return -EINVAL;
+ chan = (struct dwc2_chan *)urb->hcpriv;
+
+ chan->urb = NULL;
+ urb->hcpriv = NULL;
+
+ if (urb->timeout) {
+ urb->timeout = 0;
+ urb->errorcode = -USB_ERR_SHUTDOWN;
+ usb_osal_sem_give(chan->waitsem);
+ } else {
+ dwc2_chan_free(chan);
}
+ usb_osal_leave_critical_section(flags);
+
return 0;
}
-static inline void dwc2_pipe_waitup(struct dwc2_pipe *pipe)
+static inline void dwc2_urb_waitup(struct usbh_urb *urb)
{
- struct usbh_urb *urb;
+ struct dwc2_chan *chan;
- urb = pipe->urb;
- pipe->urb = NULL;
+ chan = (struct dwc2_chan *)urb->hcpriv;
+ chan->urb = NULL;
+ urb->hcpriv = NULL;
- if (pipe->waiter) {
- pipe->waiter = false;
- usb_osal_sem_give(pipe->waitsem);
+ if (urb->timeout) {
+ urb->timeout = 0;
+ usb_osal_sem_give(chan->waitsem);
+ } else {
+ dwc2_chan_free(chan);
}
if (urb->complete) {