forked from nuttx/nuttx-update
USB hub: Fixes for some port status change handling
This commit is contained in:
parent
c9da86b4f0
commit
2768f13153
2 changed files with 133 additions and 148 deletions
|
@ -2439,13 +2439,13 @@ static int lpc17_transfer_common(struct lpc17_usbhost_s *priv,
|
|||
bool in;
|
||||
int ret;
|
||||
|
||||
in = (ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN;
|
||||
uvdbg("EP%d %s toggle:%d maxpacket:%d buflen:%d\n",
|
||||
in = (ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN;
|
||||
uvdbg("EP%u %s toggle:%u maxpacket:%u buflen:%lu\n",
|
||||
(ed->hw.ctrl & ED_CONTROL_EN_MASK) >> ED_CONTROL_EN_SHIFT,
|
||||
in ? "IN" : "OUT",
|
||||
(ed->hw.headp & ED_HEADP_C) != 0 ? 1 : 0,
|
||||
(ed->hw.ctrl & ED_CONTROL_MPS_MASK) >> ED_CONTROL_MPS_SHIFT,
|
||||
buflen);
|
||||
(unsigned long)buflen);
|
||||
|
||||
/* Get the direction of the endpoint */
|
||||
|
||||
|
|
|
@ -94,6 +94,10 @@
|
|||
#define USBHOST_EPINFOUND 0x02 /* Required interrupt IN EP descriptor found */
|
||||
#define USBHOST_ALLFOUND (USBHOST_IFFOUND | USBHOST_EPINFOUND)
|
||||
|
||||
/* Maximum size of an interrupt IN transfer */
|
||||
|
||||
#define INTIN_BUFSIZE ((USBHUB_MAX_PORTS + 8) >> 3)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
@ -139,10 +143,6 @@ struct usbhost_hubclass_s
|
|||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Worker thread actions */
|
||||
|
||||
static void usbhost_destroy(FAR void *arg);
|
||||
|
||||
/* Helpers for usbhost_connect() */
|
||||
|
||||
static inline int usbhost_cfgdesc(FAR struct usbhost_class_s *hubclass,
|
||||
|
@ -281,75 +281,6 @@ static int usbhost_hport_activate(FAR struct usbhost_hubport_s *hport)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbhost_destroy
|
||||
*
|
||||
* Description:
|
||||
* The USB mass storage device has been disconnected and the reference
|
||||
* count on the USB host class instance has gone to 1.. Time to destroy
|
||||
* the USB host class instance.
|
||||
*
|
||||
* Input Parameters:
|
||||
* arg - A reference to the class instance to be destroyed.
|
||||
*
|
||||
* Returned Values:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void usbhost_destroy(FAR void *arg)
|
||||
{
|
||||
FAR struct usbhost_class_s *hubclass = (FAR struct usbhost_class_s *)arg;
|
||||
FAR struct usbhost_hubpriv_s *priv;
|
||||
FAR struct usbhost_hubport_s *hport;
|
||||
FAR struct usbhost_hubport_s *child;
|
||||
int port;
|
||||
|
||||
DEBUGASSERT(hubclass != NULL && hubclass->hport != NULL);
|
||||
priv = &((FAR struct usbhost_hubclass_s *)hubclass)->hubpriv;
|
||||
hport = hubclass->hport;
|
||||
|
||||
uvdbg("Destroying hub on port %d\n", hport->port);
|
||||
|
||||
/* Destroy the interrupt IN endpoint */
|
||||
|
||||
if (priv->intin)
|
||||
{
|
||||
DRVR_EPFREE(hport->drvr, priv->intin);
|
||||
priv->intin = NULL;
|
||||
}
|
||||
|
||||
/* Release per-per resource */
|
||||
|
||||
for (port = 0; port < USBHUB_MAX_PORTS; port++)
|
||||
{
|
||||
/* Free any devices classes connect on this hub port */
|
||||
|
||||
child = &priv->hport[port];
|
||||
if (child->devclass != NULL)
|
||||
{
|
||||
CLASS_DISCONNECTED(child->devclass);
|
||||
}
|
||||
|
||||
/* Free any resources used by the hub port */
|
||||
|
||||
usbhost_hport_deactivate(child);
|
||||
}
|
||||
|
||||
/* Destroy the semaphores */
|
||||
|
||||
sem_destroy(&priv->exclsem);
|
||||
|
||||
/* Deactivate the parent hub port (unless it is the root hub port) */
|
||||
|
||||
usbhost_hport_deactivate(hport);
|
||||
|
||||
/* Free the class instance */
|
||||
|
||||
kmm_free(hubclass);
|
||||
hport->devclass = NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbhost_cfgdesc
|
||||
*
|
||||
|
@ -452,9 +383,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_class_s *hubclass,
|
|||
}
|
||||
break;
|
||||
|
||||
/* Endpoint descriptor. Here, we expect two bulk endpoints, an IN
|
||||
* and an OUT.
|
||||
*/
|
||||
/* Endpoint descriptor. Here, we expect one interrupt IN endpoints. */
|
||||
|
||||
case USB_DESC_TYPE_ENDPOINT:
|
||||
{
|
||||
|
@ -475,7 +404,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_class_s *hubclass,
|
|||
{
|
||||
/* It is an OUT interrupt endpoint. Ignore */
|
||||
|
||||
uvdbg("Bulk OUT EP addr:%d mxpacketsize:%d\n",
|
||||
uvdbg("Interrupt OUT EP addr:%d mxpacketsize:%d\n",
|
||||
(epdesc->addr & USB_EP_ADDR_NUMBER_MASK),
|
||||
usbhost_getle16(epdesc->mxpacketsize));
|
||||
}
|
||||
|
@ -532,7 +461,7 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_class_s *hubclass,
|
|||
/* We are good... Allocate the interrupt IN endpoint */
|
||||
|
||||
ret = DRVR_EPALLOC(hport->drvr, &intindesc, &priv->intin);
|
||||
if (ret != OK)
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("ERROR: Failed to allocate Interrupt IN endpoint: %d\n", ret);
|
||||
(void)DRVR_EPFREE(hport->drvr, priv->intin);
|
||||
|
@ -593,7 +522,7 @@ static inline int usbhost_hubdesc(FAR struct usbhost_class_s *hubclass)
|
|||
usbhost_putle16(ctrlreq->len, USB_SIZEOF_HUBDESC);
|
||||
|
||||
ret = DRVR_CTRLIN(hport->drvr, hport->ep0, ctrlreq, (FAR uint8_t *)&hubdesc);
|
||||
if (ret != OK)
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("ERROR: Failed to read hub descriptor: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -700,7 +629,7 @@ static int usbhost_hubpwr(FAR struct usbhost_hubpriv_s *priv,
|
|||
usbhost_putle16(ctrlreq->len, 0);
|
||||
|
||||
ret = DRVR_CTRLOUT(hport->drvr, hport->ep0, ctrlreq, NULL);
|
||||
if (ret != OK)
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("ERROR: Failed to power %s port %d: %d\n",
|
||||
on ? "UP" : "DOWN", port, ret);
|
||||
|
@ -740,7 +669,7 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
uint16_t change;
|
||||
uint16_t mask;
|
||||
uint16_t feat;
|
||||
uint8_t statusmap;
|
||||
uint8_t statuschange;
|
||||
int port;
|
||||
int ret;
|
||||
|
||||
|
@ -754,20 +683,25 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
DEBUGASSERT(hubclass->hport);
|
||||
hport = hubclass->hport;
|
||||
|
||||
statusmap = priv->buffer[0];
|
||||
statuschange = priv->buffer[0];
|
||||
uvdbg("StatusChange: %02x\n", statuschange);
|
||||
|
||||
/* Check for status change on any port */
|
||||
|
||||
for (port = 1; port <= priv->nports; port++)
|
||||
{
|
||||
/* Check if port status has changed */
|
||||
|
||||
if (!(statusmap & (0x1 << port)))
|
||||
if ((statuschange & (1 << port)) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
uvdbg("Port %d status change\n", port);
|
||||
|
||||
/* Port status changed, check what happened */
|
||||
|
||||
statusmap &= (~(0x1 << port));
|
||||
statuschange &= ~(1 << port);
|
||||
|
||||
/* Read hub port status */
|
||||
|
||||
|
@ -779,7 +713,7 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
|
||||
ret = DRVR_CTRLIN(hport->drvr, hport->ep0, ctrlreq,
|
||||
(FAR uint8_t *)&portstatus);
|
||||
if (ret != OK)
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("ERROR: Failed to read port %d status: %d\n", port, ret);
|
||||
continue;
|
||||
|
@ -790,7 +724,7 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
|
||||
/* First, clear all change bits */
|
||||
|
||||
mask = 0x1;
|
||||
mask = 1;
|
||||
feat = USBHUB_PORT_FEAT_CCONNECTION;
|
||||
while (change)
|
||||
{
|
||||
|
@ -798,12 +732,12 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
{
|
||||
ctrlreq->type = USBHUB_REQ_TYPE_PORT;
|
||||
ctrlreq->req = USB_REQ_CLEARFEATURE;
|
||||
usbhost_putle16(ctrlreq->value, (feat << 8));
|
||||
usbhost_putle16(ctrlreq->value, feat);
|
||||
usbhost_putle16(ctrlreq->index, port);
|
||||
usbhost_putle16(ctrlreq->len, 0);
|
||||
|
||||
ret = DRVR_CTRLOUT(hport->drvr, hport->ep0, ctrlreq, NULL);
|
||||
if (ret != OK)
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("ERROR: Failed to clear port %d change mask %x: %d\n",
|
||||
port, mask, ret);
|
||||
|
@ -820,13 +754,13 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
|
||||
/* Handle connect or disconnect, no power management */
|
||||
|
||||
if (change & USBHUB_PORT_STAT_CCONNECTION)
|
||||
if ((change & USBHUB_PORT_STAT_CCONNECTION) != 0)
|
||||
{
|
||||
uint16_t debouncetime = 0;
|
||||
uint16_t debouncestable = 0;
|
||||
uint16_t connection = 0xffff;
|
||||
|
||||
uvdbg("port %d status %x change %x\n", port, status, change);
|
||||
uvdbg("Port %d status %x change %x\n", port, status, change);
|
||||
|
||||
/* Debounce */
|
||||
|
||||
|
@ -840,7 +774,7 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
|
||||
ret = DRVR_CTRLIN(hport->drvr, hport->ep0, ctrlreq,
|
||||
(FAR uint8_t *)&portstatus);
|
||||
if (ret != OK)
|
||||
if (ret < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -848,8 +782,8 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
status = usbhost_getle16(portstatus.status);
|
||||
change = usbhost_getle16(portstatus.change);
|
||||
|
||||
if (!(change & USBHUB_PORT_STAT_CCONNECTION) &&
|
||||
((status & USBHUB_PORT_STAT_CONNECTION) == connection))
|
||||
if ((change & USBHUB_PORT_STAT_CCONNECTION) == 0 &&
|
||||
(status & USBHUB_PORT_STAT_CONNECTION) == connection)
|
||||
{
|
||||
debouncestable += 25;
|
||||
if (debouncestable >= 100)
|
||||
|
@ -863,11 +797,11 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
connection = status & USBHUB_PORT_STAT_CONNECTION;
|
||||
}
|
||||
|
||||
if (change & USBHUB_PORT_STAT_CCONNECTION)
|
||||
if ((change & USBHUB_PORT_STAT_CCONNECTION) != 0)
|
||||
{
|
||||
ctrlreq->type = USBHUB_REQ_TYPE_PORT;
|
||||
ctrlreq->req = USB_REQ_CLEARFEATURE;
|
||||
usbhost_putle16(ctrlreq->value, (USBHUB_PORT_FEAT_CCONNECTION << 8));
|
||||
usbhost_putle16(ctrlreq->value, USBHUB_PORT_FEAT_CCONNECTION);
|
||||
usbhost_putle16(ctrlreq->index, port);
|
||||
usbhost_putle16(ctrlreq->len, 0);
|
||||
|
||||
|
@ -878,13 +812,13 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
up_mdelay(25);
|
||||
}
|
||||
|
||||
if ((ret != OK) || (debouncetime >= 1500))
|
||||
if (ret < 0 || debouncetime >= 1500)
|
||||
{
|
||||
udbg("ERROR: Failed to debounce port %d: %d\n", port, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (status & USBHUB_PORT_STAT_CONNECTION)
|
||||
if ((status & USBHUB_PORT_STAT_CONNECTION) != 0)
|
||||
{
|
||||
/* Connect */
|
||||
|
||||
|
@ -895,7 +829,7 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
usbhost_putle16(ctrlreq->len, 0);
|
||||
|
||||
ret = DRVR_CTRLOUT(hport->drvr, hport->ep0, ctrlreq, NULL);
|
||||
if (ret != OK)
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("ERROR: ailed to reset port %d: %d\n", port, ret);
|
||||
continue;
|
||||
|
@ -911,7 +845,7 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
|
||||
ret = DRVR_CTRLIN(hport->drvr, hport->ep0, ctrlreq,
|
||||
(FAR uint8_t *)&portstatus);
|
||||
if (ret != OK)
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("ERROR: Failed to reset port %d: %d\n", port, ret);
|
||||
continue;
|
||||
|
@ -923,16 +857,16 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
uvdbg("port %d status %x change %x after reset\n",
|
||||
port, status, change);
|
||||
|
||||
if (!(status & USBHUB_PORT_STAT_RESET) &&
|
||||
(status & USBHUB_PORT_STAT_ENABLE))
|
||||
if ((status & USBHUB_PORT_STAT_RESET) == 0 &&
|
||||
(status & USBHUB_PORT_STAT_ENABLE) != 0)
|
||||
{
|
||||
FAR struct usbhost_hubport_s *connport;
|
||||
|
||||
if (change & USBHUB_PORT_STAT_CRESET)
|
||||
if ((change & USBHUB_PORT_STAT_CRESET) != 0)
|
||||
{
|
||||
ctrlreq->type = USBHUB_REQ_TYPE_PORT;
|
||||
ctrlreq->req = USB_REQ_CLEARFEATURE;
|
||||
usbhost_putle16(ctrlreq->value, (USBHUB_PORT_FEAT_CRESET << 8));
|
||||
usbhost_putle16(ctrlreq->value, USBHUB_PORT_FEAT_CRESET);
|
||||
usbhost_putle16(ctrlreq->index, port);
|
||||
usbhost_putle16(ctrlreq->len, 0);
|
||||
|
||||
|
@ -940,11 +874,11 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
}
|
||||
|
||||
connport = &priv->hport[port];
|
||||
if (status & USBHUB_PORT_STAT_HIGH_SPEED)
|
||||
if ((status & USBHUB_PORT_STAT_HIGH_SPEED) != 0)
|
||||
{
|
||||
connport->speed = USB_SPEED_HIGH;
|
||||
}
|
||||
else if (status & USBHUB_PORT_STAT_LOW_SPEED)
|
||||
else if ((status & USBHUB_PORT_STAT_LOW_SPEED) != 0)
|
||||
{
|
||||
connport->speed = USB_SPEED_LOW;
|
||||
}
|
||||
|
@ -989,19 +923,20 @@ static void usbhost_hub_event(FAR void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
if (statusmap & 0x1)
|
||||
/* Check for hub status change */
|
||||
|
||||
if ((statuschange & 1) != 0)
|
||||
{
|
||||
/* Hub status changed */
|
||||
|
||||
udbg("WARNING: Hub status changed, not handled\n");
|
||||
}
|
||||
|
||||
/* Get the number hub event */
|
||||
/* Wait for the next hub event */
|
||||
|
||||
ret = DRVR_ASYNCH(hport->drvr, priv->intin, (FAR uint8_t *)priv->ctrlreq,
|
||||
sizeof(struct usb_ctrlreq_s), usbhost_callback,
|
||||
hubclass);
|
||||
if (ret != OK)
|
||||
ret = DRVR_ASYNCH(hport->drvr, priv->intin, (FAR uint8_t *)priv->buffer,
|
||||
INTIN_BUFSIZE, usbhost_callback, hubclass);
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("ERROR: Failed to queue interrupt endpoint: %d\n", ret);
|
||||
}
|
||||
|
@ -1033,14 +968,16 @@ static void usbhost_disconnect_event(FAR void *arg)
|
|||
FAR struct usbhost_class_s *hubclass = (FAR struct usbhost_class_s *)arg;
|
||||
FAR struct usbhost_hubpriv_s *priv;
|
||||
FAR struct usbhost_hubport_s *hport;
|
||||
FAR struct usbhost_hubport_s *child;
|
||||
irqstate_t flags;
|
||||
int port;
|
||||
|
||||
DEBUGASSERT(hubclass != NULL);
|
||||
priv = &((FAR struct usbhost_hubclass_s *)hubclass)->hubpriv;
|
||||
|
||||
DEBUGASSERT(hubclass->hport);
|
||||
DEBUGASSERT(hubclass != NULL && hubclass->hport != NULL);
|
||||
priv = &((FAR struct usbhost_hubclass_s *)hubclass)->hubpriv;
|
||||
hport = hubclass->hport;
|
||||
|
||||
uvdbg("Destroying hub on port %d\n", hport->port);
|
||||
|
||||
/* Set an indication to any users of the device that the device is no
|
||||
* longer available.
|
||||
*/
|
||||
|
@ -1048,17 +985,55 @@ static void usbhost_disconnect_event(FAR void *arg)
|
|||
flags = irqsave();
|
||||
priv->disconnected = true;
|
||||
|
||||
/* Free buffer for status change (INT) endpoint */
|
||||
|
||||
DRVR_IOFREE(hport->drvr, priv->buffer);
|
||||
|
||||
/* Disable power to all downstream ports */
|
||||
|
||||
(void)usbhost_hubpwr(priv, hport, false);
|
||||
|
||||
/* Destroy the class instance */
|
||||
/* Free the allocated control request */
|
||||
|
||||
usbhost_destroy(hubclass);
|
||||
DRVR_FREE(hport->drvr, (FAR uint8_t *)priv->ctrlreq);
|
||||
|
||||
/* Free buffer for status change (INT) endpoint */
|
||||
|
||||
DRVR_IOFREE(hport->drvr, priv->buffer);
|
||||
|
||||
/* Destroy EP0 */
|
||||
|
||||
DRVR_EPFREE(hport->drvr, priv->intin);
|
||||
|
||||
/* Destroy the interrupt IN endpoint */
|
||||
|
||||
DRVR_EPFREE(hport->drvr, priv->intin);
|
||||
|
||||
/* Release per-port resources */
|
||||
|
||||
for (port = 0; port < USBHUB_MAX_PORTS; port++)
|
||||
{
|
||||
/* Free any devices classes connect on this hub port */
|
||||
|
||||
child = &priv->hport[port];
|
||||
if (child->devclass != NULL)
|
||||
{
|
||||
CLASS_DISCONNECTED(child->devclass);
|
||||
}
|
||||
|
||||
/* Free any resources used by the hub port */
|
||||
|
||||
usbhost_hport_deactivate(child);
|
||||
}
|
||||
|
||||
/* Destroy the semaphores */
|
||||
|
||||
sem_destroy(&priv->exclsem);
|
||||
|
||||
/* Deactivate the parent hub port (unless it is the root hub port) */
|
||||
|
||||
usbhost_hport_deactivate(hport);
|
||||
|
||||
/* Free the class instance */
|
||||
|
||||
kmm_free(hubclass);
|
||||
hport->devclass = NULL;
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
|
@ -1230,18 +1205,18 @@ static FAR struct usbhost_class_s *
|
|||
/* Allocate memory for control requests */
|
||||
|
||||
ret = DRVR_ALLOC(hport->drvr, (FAR uint8_t **)&priv->ctrlreq, &maxlen);
|
||||
if (ret != OK)
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("DRVR_ALLOC failed: %d\n", ret);
|
||||
udbg("ERROR: DRVR_ALLOC failed: %d\n", ret);
|
||||
goto errout_with_hub;
|
||||
}
|
||||
|
||||
/* Allocate buffer for status change (INT) endpoint */
|
||||
/* Allocate buffer for status change (INT) endpoint. */
|
||||
|
||||
ret = DRVR_IOALLOC(hport->drvr, &priv->buffer, 1);
|
||||
if (ret != OK)
|
||||
ret = DRVR_IOALLOC(hport->drvr, &priv->buffer, INTIN_BUFSIZE);
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("DRVR_ALLOC failed: %d\n", ret);
|
||||
udbg("ERROR: DRVR_IOALLOC failed: %d\n", ret);
|
||||
goto errout_with_ctrlreq;
|
||||
}
|
||||
|
||||
|
@ -1328,33 +1303,43 @@ static int usbhost_connect(FAR struct usbhost_class_s *hubclass,
|
|||
/* Parse the configuration descriptor to get the endpoints */
|
||||
|
||||
ret = usbhost_cfgdesc(hubclass, configdesc, desclen);
|
||||
if (ret != OK)
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("ERROR: Failed to parse config descriptor: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
|
||||
/* Read the hub descriptor */
|
||||
|
||||
ret = usbhost_hubdesc(hubclass);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* Read the hub descriptor */
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = usbhost_hubdesc(hubclass);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (priv->nports > USBHUB_MAX_PORTS)
|
||||
{
|
||||
udbg("ERROR: too many downstream ports: %d\n", priv->nports);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/* Enable power to all downstream ports */
|
||||
/* Enable power to all downstream ports */
|
||||
|
||||
ret = usbhost_hubpwr(priv, hport, true);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
ret = usbhost_hubpwr(priv, hport, true);
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("ERROR: usbhost_hubpwr failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Enable monitoring of port status change events */
|
||||
/* Begin monitoring of port status change events */
|
||||
|
||||
ret = DRVR_ASYNCH(hport->drvr, priv->intin, (FAR uint8_t *)priv->ctrlreq,
|
||||
sizeof(struct usb_ctrlreq_s), usbhost_callback,
|
||||
hubclass);
|
||||
ret = DRVR_ASYNCH(hport->drvr, priv->intin, (FAR uint8_t *)priv->buffer,
|
||||
INTIN_BUFSIZE, usbhost_callback, hubclass);
|
||||
if (ret < 0)
|
||||
{
|
||||
udbg("ERROR: DRVR_ASYNCH failed: %d\n", ret);
|
||||
(void)usbhost_hubpwr(priv, hport, false);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue