From 397f31f061e6a682c60efd8c1ed7d9e1e6df17c2 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 26 Apr 2015 09:53:43 -0600 Subject: [PATCH] Another hub-related interface change: Need to pass speed to EP0 --- arch/arm/src/lpc17xx/lpc17_usbhost.c | 23 ++++++++++++++--------- arch/arm/src/sama5/sam_ehci.c | 5 +++-- arch/arm/src/sama5/sam_ohci.c | 27 ++++++++++++++++++--------- configs/olimex-lpc1766stk/README.txt | 3 +++ drivers/usbhost/usbhost_devaddr.c | 11 +++++++++++ drivers/usbhost/usbhost_enumerate.c | 9 ++++++--- include/nuttx/usb/usbhost.h | 13 +++++++++---- 7 files changed, 64 insertions(+), 27 deletions(-) diff --git a/arch/arm/src/lpc17xx/lpc17_usbhost.c b/arch/arm/src/lpc17xx/lpc17_usbhost.c index 4b49701858..67e98d8559 100644 --- a/arch/arm/src/lpc17xx/lpc17_usbhost.c +++ b/arch/arm/src/lpc17xx/lpc17_usbhost.c @@ -347,7 +347,7 @@ static int lpc17_enumerate(struct usbhost_connection_s *conn, struct usbhost_hubport_s *hport); static int lpc17_ep0configure(struct usbhost_driver_s *drvr, - usbhost_ep_t ep0, uint8_t funcaddr, + usbhost_ep_t ep0, uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize); static int lpc17_epalloc(struct usbhost_driver_s *drvr, const struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep); @@ -1979,6 +1979,7 @@ static int lpc17_enumerate(FAR struct usbhost_connection_s *conn, * ep0 - The (opaque) EP0 endpoint instance * funcaddr - The USB address of the function containing the endpoint that EP0 * controls + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH * mps (maxpacketsize) - The maximum number of bytes that can be sent to or * received from the endpoint in a single data packet * @@ -1991,9 +1992,8 @@ static int lpc17_enumerate(FAR struct usbhost_connection_s *conn, * ************************************************************************************/ -static int lpc17_ep0configure(struct usbhost_driver_s *drvr, - usbhost_ep_t ep0, uint8_t funcaddr, - uint16_t maxpacketsize) +static int lpc17_ep0configure(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize) { struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; struct lpc17_ed_s *ed; @@ -2006,12 +2006,17 @@ static int lpc17_ep0configure(struct usbhost_driver_s *drvr, lpc17_takesem(&priv->exclsem); - /* Set the EP0 ED control word (preserving only speed) */ + /* Set the EP0 ED control word */ + + hwctrl = (uint32_t)funcaddr << ED_CONTROL_FA_SHIFT | + (uint32_t)ED_CONTROL_D_TD1 | + (uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT; + + if (speed == USB_SPEED_LOW) + { + hwctrl |= ED_CONTROL_S; + } - hwctrl = ed->hw.ctrl & ED_CONTROL_S; - hwctrl |= (uint32_t)funcaddr << ED_CONTROL_FA_SHIFT | - (uint32_t)ED_CONTROL_D_TD1 | - (uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT; ed->hw.ctrl = hwctrl; lpc17_givesem(&priv->exclsem); diff --git a/arch/arm/src/sama5/sam_ehci.c b/arch/arm/src/sama5/sam_ehci.c index 3f70852f43..d4c6e8a2f4 100644 --- a/arch/arm/src/sama5/sam_ehci.c +++ b/arch/arm/src/sama5/sam_ehci.c @@ -381,7 +381,7 @@ static int sam_enumerate(FAR struct usbhost_connection_s *conn, FAR struct usbhost_hubport_s *hport); static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, - uint8_t funcaddr, uint16_t maxpacketsize); + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize); static int sam_epalloc(FAR struct usbhost_driver_s *drvr, const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep); static int sam_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); @@ -3384,6 +3384,7 @@ static int sam_enumerate(FAR struct usbhost_connection_s *conn, * funcaddr - The USB address of the function containing the endpoint that EP0 * controls. A funcaddr of zero will be received if no address is yet assigned * to the device. + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH * maxpacketsize - The maximum number of bytes that can be sent to or * received from the endpoint in a single data packet * @@ -3397,7 +3398,7 @@ static int sam_enumerate(FAR struct usbhost_connection_s *conn, ************************************************************************************/ static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, - uint8_t funcaddr, uint16_t maxpacketsize) + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize) { struct sam_epinfo_s *epinfo = (struct sam_epinfo_s *)ep0; diff --git a/arch/arm/src/sama5/sam_ohci.c b/arch/arm/src/sama5/sam_ohci.c index 1538f2bf23..7f2596cf57 100644 --- a/arch/arm/src/sama5/sam_ohci.c +++ b/arch/arm/src/sama5/sam_ohci.c @@ -400,8 +400,9 @@ static int sam_rh_enumerate(FAR struct usbhost_connection_s *conn, static int sam_enumerate(FAR struct usbhost_connection_s *conn, FAR struct usbhost_hubport_s *hport); -static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, - uint8_t funcaddr, uint16_t maxpacketsize); +static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, + usbhost_ep_t ep0, uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize); static int sam_epalloc(FAR struct usbhost_driver_s *drvr, const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep); static int sam_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); @@ -1476,7 +1477,9 @@ static int sam_ep0enqueue(struct sam_rhport_s *rhport) */ memset(edctrl, 0, sizeof(struct sam_ed_s)); - (void)sam_ep0configure(&rhport->drvr, &rhport->ep0, 0, 8); + (void)sam_ep0configure(&rhport->drvr, &rhport->ep0, 0, + rhport->hport.speed, 8); + edctrl->hw.ctrl |= ED_CONTROL_K; edctrl->eplist = &rhport->ep0; edctrl->xfrtype = USB_EP_ATTR_XFER_CONTROL; @@ -2344,6 +2347,7 @@ static int sam_enumerate(FAR struct usbhost_connection_s *conn, * funcaddr - The USB address of the function containing the endpoint that EP0 * controls. A funcaddr of zero will be received if no address is yet assigned * to the device. + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH * maxpacketsize - The maximum number of bytes that can be sent to or * received from the endpoint in a single data packet * @@ -2356,8 +2360,8 @@ static int sam_enumerate(FAR struct usbhost_connection_s *conn, * ************************************************************************************/ -static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, - uint8_t funcaddr, uint16_t maxpacketsize) +static int sam_ep0configure(struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize) { struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr; struct sam_eplist_s *ep0list = (struct sam_eplist_s *)ep0; @@ -2374,10 +2378,15 @@ static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, /* Set the EP0 ED control word (preserving only speed) */ - hwctrl = ed->hw.ctrl & ED_CONTROL_S; - hwctrl |= (uint32_t)funcaddr << ED_CONTROL_FA_SHIFT | - (uint32_t)ED_CONTROL_D_TD1 | - (uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT; + hwctrl = (uint32_t)funcaddr << ED_CONTROL_FA_SHIFT | + (uint32_t)ED_CONTROL_D_TD1 | + (uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT; + + if (speed == USB_SPEED_LOW) + { + hwctrl |= ED_CONTROL_S; + } + ed->hw.ctrl = hwctrl; /* Flush the modified control ED to RAM */ diff --git a/configs/olimex-lpc1766stk/README.txt b/configs/olimex-lpc1766stk/README.txt index 5a9952ccfd..bb329b9aa1 100644 --- a/configs/olimex-lpc1766stk/README.txt +++ b/configs/olimex-lpc1766stk/README.txt @@ -977,6 +977,9 @@ Configuration Sub-Directories crash seems seems to be due to a corrupt addess in the callback from the new asynchronous I/O. Should not be too hard to fix. + Also, the code does not enumerat the hub if it is connected at the + time of power up. + hidmouse: This configuration directory supports a variant of an NSH configution. It is set up to perform the touchscreen test at apps/examples/touchscreen diff --git a/drivers/usbhost/usbhost_devaddr.c b/drivers/usbhost/usbhost_devaddr.c index c7bf5e249c..a36f7a4f1a 100644 --- a/drivers/usbhost/usbhost_devaddr.c +++ b/drivers/usbhost/usbhost_devaddr.c @@ -177,10 +177,21 @@ static void usbhost_devaddr_free(FAR struct usbhost_devaddr_s *devgen, static inline FAR struct usbhost_roothubport_s * usbhost_roothubport(FAR struct usbhost_hubport_s *hport) { +#ifdef CONFIG_USBHOST_HUB + /* If this is a root hub port then the parent port pointer will be NULL. + * Otherwise, we need to traverse the parent pointer list until we find the + * root hub port. + */ + while (hport->parent != NULL) { + /* This is not a root hub port. It is a port on a hub. Try the port of + * the parent hub that supports this port. + */ + hport = hport->parent; } +#endif return (FAR struct usbhost_roothubport_s *)hport; } diff --git a/drivers/usbhost/usbhost_enumerate.c b/drivers/usbhost/usbhost_enumerate.c index a95d84f971..8f60e5c085 100644 --- a/drivers/usbhost/usbhost_enumerate.c +++ b/drivers/usbhost/usbhost_enumerate.c @@ -367,7 +367,8 @@ int usbhost_enumerate(FAR struct usbhost_hubport_s *hport, /* Configure EP0 with the initial maximum packet size */ - DRVR_EP0CONFIGURE(hport->drvr, hport->ep0, 0, maxpacketsize); + DRVR_EP0CONFIGURE(hport->drvr, hport->ep0, 0, hport->speed, + maxpacketsize); /* Read first bytes of the device descriptor */ @@ -392,7 +393,8 @@ int usbhost_enumerate(FAR struct usbhost_hubport_s *hport, /* And reconfigure EP0 with the correct maximum packet size */ - DRVR_EP0CONFIGURE(hport->drvr, hport->ep0, 0, maxpacketsize); + DRVR_EP0CONFIGURE(hport->drvr, hport->ep0, 0, hport->speed, + maxpacketsize); /* Now read the full device descriptor (if we have not already done so) */ @@ -454,7 +456,8 @@ int usbhost_enumerate(FAR struct usbhost_hubport_s *hport, /* And reconfigure EP0 with the correct address */ - DRVR_EP0CONFIGURE(hport->drvr, hport->ep0, hport->funcaddr, maxpacketsize); + DRVR_EP0CONFIGURE(hport->drvr, hport->ep0, hport->funcaddr, + hport->speed, maxpacketsize); /* Get the configuration descriptor (only), index == 0. Should not be * hard-coded! More logic is needed in order to handle devices with diff --git a/include/nuttx/usb/usbhost.h b/include/nuttx/usb/usbhost.h index 6347477edd..81c4efda66 100644 --- a/include/nuttx/usb/usbhost.h +++ b/include/nuttx/usb/usbhost.h @@ -67,7 +67,11 @@ * ************************************************************************************/ -#define ROOTHUB(hub) ((hub)->parent == NULL) +#ifdef CONFIG_USBHOST_HUB +# define ROOTHUB(hub) ((hub)->parent == NULL) +#else +# define ROOTHUB(hub) true +#endif /************************************************************************************ * Name: CLASS_CREATE @@ -230,6 +234,7 @@ * ep0 - The (opaque) EP0 endpoint instance * funcaddr - The USB address of the function containing the endpoint that EP0 * controls + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH * mps (maxpacketsize) - The maximum number of bytes that can be sent to or * received from the endpoint in a single data packet * @@ -242,8 +247,8 @@ * ************************************************************************************/ -#define DRVR_EP0CONFIGURE(drvr,ep0,funcaddr,mps) \ - ((drvr)->ep0configure(drvr,ep0,funcaddr,mps)) +#define DRVR_EP0CONFIGURE(drvr,ep0,funcaddr,speed,mps) \ + ((drvr)->ep0configure(drvr,ep0,funcaddr,speed,mps)) /************************************************************************************ * Name: DRVR_GETDEVINFO @@ -771,7 +776,7 @@ struct usbhost_driver_s */ int (*ep0configure)(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, - uint8_t funcaddr, uint16_t maxpacketsize); + uint8_t funcaddr, uint8_t speed, uint16_t maxpacketsize); /* Allocate and configure an endpoint. */