diff --git a/arch/arm/src/lpc17xx/lpc17_usbhost.c b/arch/arm/src/lpc17xx/lpc17_usbhost.c index 7546fea889..bcfbad225b 100644 --- a/arch/arm/src/lpc17xx/lpc17_usbhost.c +++ b/arch/arm/src/lpc17xx/lpc17_usbhost.c @@ -166,7 +166,6 @@ struct lpc17_usbhost_s volatile bool change; /* Connection change */ volatile bool connected; /* Connected to device */ - volatile bool lowspeed; /* Low speed device attached. */ volatile bool pscwait; /* TRUE: Thread is waiting for a port status change */ #ifndef CONFIG_USBHOST_INT_DISABLE @@ -1612,8 +1611,16 @@ static int lpc17_usbinterrupt(int irq, void *context) * when CCS == 1. */ - priv->lowspeed = (rhportst1 & OHCI_RHPORTST_LSDA) != 0; - ullvdbg("Speed:%s\n", priv->lowspeed ? "LOW" : "FULL"); + if ((rhportst1 & OHCI_RHPORTST_LSDA) != 0) + { + priv->rhport.hport.speed = USB_SPEED_LOW; + } + else + { + priv->rhport.hport.speed = USB_SPEED_FULL; + } + + ullvdbg("Speed:%d\n", priv->rhport.hport.speed); } /* Check if we are now disconnected */ @@ -1623,9 +1630,9 @@ static int lpc17_usbinterrupt(int irq, void *context) /* Yes.. disconnect the device */ ullvdbg("Disconnected\n"); - priv->connected = false; - priv->change = true; - priv->lowspeed = false; + priv->connected = false; + priv->change = true; + priv->rhport.hport.speed = USB_SPEED_FULL; /* Are we bound to a class instance? */ @@ -1985,7 +1992,7 @@ static int lpc17_ep0configure(struct usbhost_driver_s *drvr, ed->hw.ctrl = (uint32_t)funcaddr << ED_CONTROL_FA_SHIFT | (uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT; - if (priv->lowspeed) + if (priv->rhport.hport.speed == USB_SPEED_LOW) { ed->hw.ctrl |= ED_CONTROL_S; } @@ -2078,7 +2085,7 @@ static int lpc17_epalloc(struct usbhost_driver_s *drvr, /* Check for a low-speed device */ - if (priv->lowspeed) + if (priv->rhport.hport.speed == USB_SPEED_LOW) { ed->hw.ctrl |= ED_CONTROL_S; } diff --git a/arch/arm/src/sama5/sam_ohci.c b/arch/arm/src/sama5/sam_ohci.c index c251dcb416..cf8d0a8673 100644 --- a/arch/arm/src/sama5/sam_ohci.c +++ b/arch/arm/src/sama5/sam_ohci.c @@ -355,6 +355,9 @@ static void sam_tbfree(uint8_t *buffer); /* ED list helper functions ****************************************************/ +static inline int sam_addctrled(struct sam_ed_s *ed); +static inline int sam_remctrled(struct sam_ed_s *ed); + static inline int sam_addbulked(struct sam_ed_s *ed); static inline int sam_rembulked(struct sam_ed_s *ed); @@ -834,6 +837,34 @@ static inline int sam_addbulked(struct sam_ed_s *ed) #endif } +/******************************************************************************* + * Name: sam_addctrled + * + * Description: + * Helper function to add an ED to the control list. + * + *******************************************************************************/ + +static inline int sam_addctrled(struct sam_ed_s *ed) +{ +#error Not Implemented + return -ENOSYS; +} + +/******************************************************************************* + * Name: sam_remctrled + * + * Description: + * Helper function remove an ED from the control list. + * + *******************************************************************************/ + +static inline int sam_remctrled(struct sam_ed_s *ed) +{ +#error Not Implemented + return -ENOSYS; +} + /******************************************************************************* * Name: sam_rembulked * @@ -2454,9 +2485,15 @@ static int sam_epalloc(FAR struct usbhost_driver_s *drvr, (uint32_t)(epdesc->addr) << ED_CONTROL_EN_SHIFT | (uint32_t)(epdesc->mxpacketsize) << ED_CONTROL_MPS_SHIFT; - /* Get the direction of the endpoint */ + /* Get the direction of the endpoint. For control endpoints, the + * direction is in the TD. + */ - if (epdesc->in) + if (epdesc->xfrtype == USB_EP_ATTR_XFER_CONTROL) + { + ed->hw.ctrl |= ED_CONTROL_D_TD1; + } + else if (epdesc->in) { ed->hw.ctrl |= ED_CONTROL_D_IN; } @@ -2510,6 +2547,10 @@ static int sam_epalloc(FAR struct usbhost_driver_s *drvr, switch (ed->xfrtype) { + case USB_EP_ATTR_XFER_CONTROL: + ret = sam_addctrled(ed); + break; + case USB_EP_ATTR_XFER_BULK: ret = sam_addbulked(ed); break; @@ -2522,7 +2563,6 @@ static int sam_epalloc(FAR struct usbhost_driver_s *drvr, ret = sam_addisoced(epdesc, ed); break; - case USB_EP_ATTR_XFER_CONTROL: default: ret = -EINVAL; break; @@ -2601,6 +2641,10 @@ static int sam_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) switch (ed->xfrtype) { + case USB_EP_ATTR_XFER_CONTROL: + ret = sam_remctrled(eplist->ed); + break; + case USB_EP_ATTR_XFER_BULK: ret = sam_rembulked(eplist->ed); break; @@ -2613,7 +2657,6 @@ static int sam_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) ret = sam_remisoced(eplist->ed); break; - case USB_EP_ATTR_XFER_CONTROL: default: ret = -EINVAL; break;