diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-08-12 14:44:06 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-08-12 14:44:06 -0600 |
commit | 3b04d08043742b9e65cf38d45988b35bff91daed (patch) | |
tree | ca74e5710a1564da64e94e52b34210f6d8401947 | |
parent | d5cee29af56c68dceeb8e26f6f4081c9d3c66988 (diff) | |
download | px4-nuttx-3b04d08043742b9e65cf38d45988b35bff91daed.tar.gz px4-nuttx-3b04d08043742b9e65cf38d45988b35bff91daed.tar.bz2 px4-nuttx-3b04d08043742b9e65cf38d45988b35bff91daed.zip |
First of several changes needed to support multiple USB host root hubs
20 files changed, 314 insertions, 211 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 6ee8926fe..689c64d28 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -5369,4 +5369,12 @@ * arch/arm/src/sama5/sam_ohci.c and sam_usbhost.h (was sam_ohci.h), and configs/sama5d3x-ek/src/sam_usb.c, and sama5d3x-ek.h: Add controls to enable VBUS power in OHCI host most (2013-8-12). - + * includes/nuttx/usb/usbhost.h, all USB host drivers in arch/, and all + USB host-side connection monitoring threads in configs/*/src: The + SAMA5 has three downstream ports; all of the other USB host + implementations have only one. This will require significant changes + to the USB host interfaces starting with these chnages to monitor + connections on a port-by-port basis. This effects a lot of files and + more changes are coming for this issues. Changes are being blindly + incorporated into other architrectures. I am being careful to avoid + breakage, but I expect some (2013-8-12). diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html index a77df7f0f..71bb5842c 100644 --- a/nuttx/Documentation/NuttxPortingGuide.html +++ b/nuttx/Documentation/NuttxPortingGuide.html @@ -12,7 +12,7 @@ <h1><big><font color="#3c34ec"> <i>NuttX RTOS Porting Guide</i> </font></big></h1> - <p>Last Updated: July 26, 2013</p> + <p>Last Updated: August 12, 2013</p> </td> </tr> </table> @@ -3433,6 +3433,8 @@ extern void up_ledoff(int led); <p> <b>Examples</b>: <code>arch/arm/src/lpc17xx/lpc17_usbhost.c</code>. + <code>arch/arm/src/stm32/stm32_otgfshost.c</code>. + <code>arch/arm/src/sama5/sam_ohci.c</code>. </p> </li> <li> @@ -3469,7 +3471,7 @@ extern void up_ledoff(int led); <ul> <li> <p> - <code>int (*wait)(FAR struct usbhost_driver_s *drvr, bool connected);</code> + <code>int (*wait)(FAR struct usbhost_driver_s *drvr, FAR const bool *connected);</code> </p> <p> Wait for a device to be connected or disconnected. @@ -3477,10 +3479,10 @@ extern void up_ledoff(int led); </li> <li> <p> - <code>int (*enumerate)(FAR struct usbhost_driver_s *drvr);</code> + <code>int (*enumerate)(FAR struct usbhost_driver_s *drvr, int rhpndx);</code> </p> <p> - Enumerate the connected device. + Enumerate the device connected to a root hub port. As part of this enumeration process, the driver will (1) get the device's configuration descriptor, (2) extract the class ID info from the configuration descriptor, diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c b/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c index b0e9958e9..2fb5eb34c 100644 --- a/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c +++ b/nuttx/arch/arm/src/lpc17xx/lpc17_usbhost.c @@ -294,8 +294,8 @@ static int lpc17_usbinterrupt(int irq, FAR void *context); /* USB host controller operations **********************************************/ -static int lpc17_wait(FAR struct usbhost_driver_s *drvr, bool connected); -static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr); +static int lpc17_wait(FAR struct usbhost_driver_s *drvr, FAR bool *connected); +static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr, int rhpndx); static int lpc17_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr, uint16_t maxpacketsize); static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr, @@ -1518,8 +1518,8 @@ static int lpc17_usbinterrupt(int irq, FAR void *context) * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call to * the class create() method. - * connected - TRUE: Wait for device to be connected; FALSE: wait for device - * to be disconnected + * connected - A pointer to a boolean value: TRUE: Wait for device to be + * connected; FALSE: wait for device to be disconnected * * Returned Values: * Zero (OK) is returned when a device in connected. This function will not @@ -1533,7 +1533,7 @@ static int lpc17_usbinterrupt(int irq, FAR void *context) * *******************************************************************************/ -static int lpc17_wait(FAR struct usbhost_driver_s *drvr, bool connected) +static int lpc17_wait(FAR struct usbhost_driver_s *drvr, FAR bool *connected) { struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; irqstate_t flags; @@ -1541,13 +1541,14 @@ static int lpc17_wait(FAR struct usbhost_driver_s *drvr, bool connected) /* Are we already connected? */ flags = irqsave(); - while (priv->connected == connected) + while (priv->connected == *connected) { /* No... wait for the connection/disconnection */ priv->rhswait = true; lpc17_takesem(&priv->rhssem); } + irqrestore(flags); udbg("Connected:%s\n", priv->connected ? "YES" : "NO"); @@ -1570,6 +1571,7 @@ static int lpc17_wait(FAR struct usbhost_driver_s *drvr, bool connected) * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call to * the class create() method. + * rphndx - Root hub port index. 0-(n-1) corresponds to root hub port 1-n. * * Returned Values: * On success, zero (OK) is returned. On a failure, a negated errno value is @@ -1582,9 +1584,10 @@ static int lpc17_wait(FAR struct usbhost_driver_s *drvr, bool connected) * *******************************************************************************/ -static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr) +static int lpc17_enumerate(FAR struct usbhost_driver_s *drvr, int rphndx) { struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; + DEBUGASSERT(priv && rhpndx == 0); /* Are we connected to a device? The caller should have called the wait() * method first to be assured that a device is connected. diff --git a/nuttx/arch/arm/src/sama5/chip/sam_ohci.h b/nuttx/arch/arm/src/sama5/chip/sam_ohci.h index f784b929d..9a1d72900 100644 --- a/nuttx/arch/arm/src/sama5/chip/sam_ohci.h +++ b/nuttx/arch/arm/src/sama5/chip/sam_ohci.h @@ -49,45 +49,50 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ - +/* The SAMA5 supports 3 root hub ports */ + +#define SAM_USBHOST_NRHPORT 3 + /* Register offsets *********************************************************/ /* See nuttx/usb/ohci.h */ /* Register addresses *******************************************************/ -#define SAM_USBHOST_HCIREV (SAM_UHPOHCI_VSECTION+OHCI_HCIREV_OFFSET) -#define SAM_USBHOST_CTRL (SAM_UHPOHCI_VSECTION+OHCI_CTRL_OFFSET) -#define SAM_USBHOST_CMDST (SAM_UHPOHCI_VSECTION+OHCI_CMDST_OFFSET) -#define SAM_USBHOST_INTST (SAM_UHPOHCI_VSECTION+OHCI_INTST_OFFSET) -#define SAM_USBHOST_INTEN (SAM_UHPOHCI_VSECTION+OHCI_INTEN_OFFSET) -#define SAM_USBHOST_INTDIS (SAM_UHPOHCI_VSECTION+OHCI_INTDIS_OFFSET) +#define SAM_USBHOST_HCIREV (SAM_UHPOHCI_VSECTION+OHCI_HCIREV_OFFSET) +#define SAM_USBHOST_CTRL (SAM_UHPOHCI_VSECTION+OHCI_CTRL_OFFSET) +#define SAM_USBHOST_CMDST (SAM_UHPOHCI_VSECTION+OHCI_CMDST_OFFSET) +#define SAM_USBHOST_INTST (SAM_UHPOHCI_VSECTION+OHCI_INTST_OFFSET) +#define SAM_USBHOST_INTEN (SAM_UHPOHCI_VSECTION+OHCI_INTEN_OFFSET) +#define SAM_USBHOST_INTDIS (SAM_UHPOHCI_VSECTION+OHCI_INTDIS_OFFSET) /* Memory pointers (section 7.2) */ -#define SAM_USBHOST_HCCA (SAM_UHPOHCI_VSECTION+OHCI_HCCA_OFFSET) -#define SAM_USBHOST_PERED (SAM_UHPOHCI_VSECTION+OHCI_PERED_OFFSET) -#define SAM_USBHOST_CTRLHEADED (SAM_UHPOHCI_VSECTION+OHCI_CTRLHEADED_OFFSET) -#define SAM_USBHOST_CTRLED (SAM_UHPOHCI_VSECTION+OHCI_CTRLED_OFFSET) -#define SAM_USBHOST_BULKHEADED (SAM_UHPOHCI_VSECTION+OHCI_BULKHEADED_OFFSET) -#define SAM_USBHOST_BULKED (SAM_UHPOHCI_VSECTION+OHCI_BULKED_OFFSET) -#define SAM_USBHOST_DONEHEAD (SAM_UHPOHCI_VSECTION+OHCI_DONEHEAD_OFFSET) +#define SAM_USBHOST_HCCA (SAM_UHPOHCI_VSECTION+OHCI_HCCA_OFFSET) +#define SAM_USBHOST_PERED (SAM_UHPOHCI_VSECTION+OHCI_PERED_OFFSET) +#define SAM_USBHOST_CTRLHEADED (SAM_UHPOHCI_VSECTION+OHCI_CTRLHEADED_OFFSET) +#define SAM_USBHOST_CTRLED (SAM_UHPOHCI_VSECTION+OHCI_CTRLED_OFFSET) +#define SAM_USBHOST_BULKHEADED (SAM_UHPOHCI_VSECTION+OHCI_BULKHEADED_OFFSET) +#define SAM_USBHOST_BULKED (SAM_UHPOHCI_VSECTION+OHCI_BULKED_OFFSET) +#define SAM_USBHOST_DONEHEAD (SAM_UHPOHCI_VSECTION+OHCI_DONEHEAD_OFFSET) /* Frame counters (section 7.3) */ -#define SAM_USBHOST_FMINT (SAM_UHPOHCI_VSECTION+OHCI_FMINT_OFFSET) -#define SAM_USBHOST_FMREM (SAM_UHPOHCI_VSECTION+OHCI_FMREM_OFFSET) -#define SAM_USBHOST_FMNO (SAM_UHPOHCI_VSECTION+OHCI_FMNO_OFFSET) -#define SAM_USBHOST_PERSTART (SAM_UHPOHCI_VSECTION+OHCI_PERSTART_OFFSET) +#define SAM_USBHOST_FMINT (SAM_UHPOHCI_VSECTION+OHCI_FMINT_OFFSET) +#define SAM_USBHOST_FMREM (SAM_UHPOHCI_VSECTION+OHCI_FMREM_OFFSET) +#define SAM_USBHOST_FMNO (SAM_UHPOHCI_VSECTION+OHCI_FMNO_OFFSET) +#define SAM_USBHOST_PERSTART (SAM_UHPOHCI_VSECTION+OHCI_PERSTART_OFFSET) /* Root hub ports (section 7.4) */ -#define SAM_USBHOST_LSTHRES (SAM_UHPOHCI_VSECTION+OHCI_LSTHRES_OFFSET) -#define SAM_USBHOST_RHDESCA (SAM_UHPOHCI_VSECTION+OHCI_RHDESCA_OFFSET) -#define SAM_USBHOST_RHDESCB (SAM_UHPOHCI_VSECTION+OHCI_RHDESCB_OFFSET) -#define SAM_USBHOST_RHSTATUS (SAM_UHPOHCI_VSECTION+OHCI_RHSTATUS_OFFSET) -#define SAM_USBHOST_RHPORTST1 (SAM_UHPOHCI_VSECTION+OHCI_RHPORTST1_OFFSET) -#define SAM_USBHOST_RHPORTST2 (SAM_UHPOHCI_VSECTION+OHCI_RHPORTST2_OFFSET) -#define SAM_USBHOST_MODID (SAM_UHPOHCI_VSECTION+SAM_USBHOST_MODID_OFFSET) +#define SAM_USBHOST_LSTHRES (SAM_UHPOHCI_VSECTION+OHCI_LSTHRES_OFFSET) +#define SAM_USBHOST_RHDESCA (SAM_UHPOHCI_VSECTION+OHCI_RHDESCA_OFFSET) +#define SAM_USBHOST_RHDESCB (SAM_UHPOHCI_VSECTION+OHCI_RHDESCB_OFFSET) +#define SAM_USBHOST_RHSTATUS (SAM_UHPOHCI_VSECTION+OHCI_RHSTATUS_OFFSET) + +#define SAM_USBHOST_RHPORTST(n) (SAM_UHPOHCI_VSECTION+OHCI_RHPORTST_OFFSET(n)) +#define SAM_USBHOST_RHPORTST1 (SAM_UHPOHCI_VSECTION+OHCI_RHPORTST1_OFFSET) +#define SAM_USBHOST_RHPORTST2 (SAM_UHPOHCI_VSECTION+OHCI_RHPORTST2_OFFSET) +#define SAM_USBHOST_RHPORTST3 (SAM_UHPOHCI_VSECTION+OHCI_RHPORTST3_OFFSET) /* Register bit definitions *************************************************/ /* See include/nuttx/usb/ohci.h */ diff --git a/nuttx/arch/arm/src/sama5/sam_ohci.c b/nuttx/arch/arm/src/sama5/sam_ohci.c index 40ff3dea0..10c75558a 100644 --- a/nuttx/arch/arm/src/sama5/sam_ohci.c +++ b/nuttx/arch/arm/src/sama5/sam_ohci.c @@ -176,6 +176,13 @@ /******************************************************************************* * Private Types *******************************************************************************/ +/* This structure retins the state of one root hub port */ + +struct sam_rhport_s +{ + volatile bool connected; /* Connected to device */ + volatile bool lowspeed; /* Low speed device attached. */ +}; /* This structure retains the state of the USB host controller */ @@ -194,9 +201,8 @@ struct sam_ohci_s /* Driver status */ - volatile bool connected; /* Connected to device */ - volatile bool lowspeed; /* Low speed device attached. */ volatile bool rhswait; /* TRUE: Thread is waiting for Root Hub Status change */ + #ifndef CONFIG_USBHOST_INT_DISABLE uint8_t ininterval; /* Minimum periodic IN EP polling interval: 2, 4, 6, 16, or 32 */ uint8_t outinterval; /* Minimum periodic IN EP polling interval: 2, 4, 6, 16, or 32 */ @@ -204,6 +210,10 @@ struct sam_ohci_s sem_t exclsem; /* Support mutually exclusive access */ sem_t rhssem; /* Semaphore to wait Writeback Done Head event */ + /* Root hub ports */ + + struct sam_rhport_s rhport[SAM_USBHOST_NRHPORT]; + /* Debug stuff */ #ifdef CONFIG_SAMA5_SPI_REGDEBUG @@ -337,8 +347,8 @@ static int sam_ohci_interrupt(int irq, FAR void *context); /* USB host controller operations **********************************************/ -static int sam_wait(FAR struct usbhost_driver_s *drvr, bool connected); -static int sam_enumerate(FAR struct usbhost_driver_s *drvr); +static int sam_wait(FAR struct usbhost_driver_s *drvr, FAR const bool *connected); +static int sam_enumerate(FAR struct usbhost_driver_s *drvr, int rhpndx); static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr, uint16_t maxpacketsize); static int sam_epalloc(FAR struct usbhost_driver_s *drvr, @@ -1231,7 +1241,9 @@ static int sam_wdhwait(struct sam_ohci_s *priv, struct sam_ed_s *ed) /* Is the device still connected? */ +#if 0 /* REVISIT */ if (priv->connected) +#endif { /* Yes.. then set wdhwait to indicate that we expect to be informed when * either (1) the device is disconnected, or (2) the transfer completed. @@ -1339,6 +1351,8 @@ static int sam_ohci_interrupt(int irq, FAR void *context) uint32_t intst; uint32_t pending; uint32_t regval; + uint32_t regaddr; + int rhpndx; /* Read Interrupt Status and mask out interrupts that are not enabled. */ @@ -1353,105 +1367,125 @@ static int sam_ohci_interrupt(int irq, FAR void *context) if ((pending & OHCI_INT_RHSC) != 0) { - uint32_t rhportst1 = sam_getreg(SAM_USBHOST_RHPORTST1); - ullvdbg("Root Hub Status Change, RHPORTST1: %08x\n", rhportst1); + /* Hand root hub status change on each root port */ - if ((rhportst1 & OHCI_RHPORTST_CSC) != 0) + ullvdbg("Root Hub Status Change\n"); + for (rhpndx = 0; rhpndx < SAM_USBHOST_NRHPORT; rhpndx++) { - uint32_t rhstatus = sam_getreg(SAM_USBHOST_RHSTATUS); - ullvdbg("Connect Status Change, RHSTATUS: %08x\n", rhstatus); + uint32_t rhportst; + + regaddr = SAM_USBHOST_RHPORTST(rhpndx+1); + rhportst = sam_getreg(regaddr); - /* If DRWE is set, Connect Status Change indicates a remote wake-up event */ + ullvdbg("RHPORTST%d: %08x\n", + rhpndx + 1, rhportst); - if (rhstatus & OHCI_RHSTATUS_DRWE) + if ((rhportst & OHCI_RHPORTST_CSC) != 0) { - ullvdbg("DRWE: Remote wake-up\n"); - } + uint32_t rhstatus = sam_getreg(SAM_USBHOST_RHSTATUS); + ullvdbg("Connect Status Change, RHSTATUS: %08x\n", rhstatus); - /* Otherwise... Not a remote wake-up event */ + /* If DRWE is set, Connect Status Change indicates a remote + * wake-up event + */ - else - { - /* Check current connect status */ + if (rhstatus & OHCI_RHSTATUS_DRWE) + { + ullvdbg("DRWE: Remote wake-up\n"); + } - if ((rhportst1 & OHCI_RHPORTST_CCS) != 0) + /* Otherwise... Not a remote wake-up event */ + + else { - /* Connected ... Did we just become connected? */ + /* Check current connect status */ - if (!priv->connected) + if ((rhportst & OHCI_RHPORTST_CCS) != 0) { - /* Yes.. connected. */ + /* Connected ... Did we just become connected? */ - ullvdbg("Connected\n"); - priv->connected = true; + if (!priv->rhport[rhpndx].connected) + { + /* Yes.. connected. */ - /* Notify any waiters */ + priv->rhport[rhpndx].connected = true; - if (priv->rhswait) + ullvdbg("RHPort%d connected, rhswait: %d\n", + rhpndx + 1, priv->rhswait); + + /* Notify any waiters */ + + if (priv->rhswait) + { + sam_givesem(&priv->rhssem); + priv->rhswait = false; + } + } + else { - sam_givesem(&priv->rhssem); - priv->rhswait = false; + ulldbg("Spurious status change (connected)\n"); } - } - else - { - ulldbg("Spurious status change (connected)\n"); - } - /* The LSDA (Low speed device attached) bit is valid - * when CCS == 1. - */ + /* The LSDA (Low speed device attached) bit is valid + * when CCS == 1. + */ - priv->lowspeed = (rhportst1 & OHCI_RHPORTST_LSDA) != 0; - ullvdbg("Speed:%s\n", priv->lowspeed ? "LOW" : "FULL"); - } + priv->rhport[rhpndx].lowspeed = + (rhportst & OHCI_RHPORTST_LSDA) != 0; - /* Check if we are now disconnected */ + ullvdbg("Speed: %s\n", + priv->rhport[rhpndx].lowspeed ? "LOW" : "FULL"); + } - else if (priv->connected) - { - /* Yes.. disconnect the device */ + /* Check if we are now disconnected */ - ullvdbg("Disconnected\n"); - priv->connected = false; - priv->lowspeed = false; + else if (priv->rhport[rhpndx].connected) + { + /* Yes.. disconnect the device */ - /* Are we bound to a class instance? */ + ullvdbg("RHport%d disconnected\n", rhpndx+1); + priv->rhport[rhpndx].connected = false; + priv->rhport[rhpndx].lowspeed = false; - if (priv->class) - { - /* Yes.. Disconnect the class */ + /* Are we bound to a class instance? */ - CLASS_DISCONNECTED(priv->class); - priv->class = NULL; - } + if (priv->class) + { + /* Yes.. Disconnect the class */ + + CLASS_DISCONNECTED(priv->class); + priv->class = NULL; + } - /* Notify any waiters for the Root Hub Status change event */ + /* Notify any waiters for the Root Hub Status change + * event. + */ - if (priv->rhswait) + if (priv->rhswait) + { + sam_givesem(&priv->rhssem); + priv->rhswait = false; + } + } + else { - sam_givesem(&priv->rhssem); - priv->rhswait = false; + ulldbg("Spurious status change (disconnected)\n"); } } - else - { - ulldbg("Spurious status change (disconnected)\n"); - } - } - /* Clear the status change interrupt */ + /* Clear the status change interrupt */ - sam_putreg(OHCI_RHPORTST_CSC, SAM_USBHOST_RHPORTST1); - } + sam_putreg(OHCI_RHPORTST_CSC, regaddr); + } - /* Check for port reset status change */ + /* Check for port reset status change */ - if ((rhportst1 & OHCI_RHPORTST_PRSC) != 0) - { - /* Release the RH port from reset */ + if ((rhportst & OHCI_RHPORTST_PRSC) != 0) + { + /* Release the RH port from reset */ - sam_putreg(OHCI_RHPORTST_PRSC, SAM_USBHOST_RHPORTST1); + sam_putreg(OHCI_RHPORTST_PRSC, regaddr); + } } } @@ -1495,9 +1529,8 @@ static int sam_ohci_interrupt(int irq, FAR void *context) { /* The transfer failed for some reason... dump some diagnostic info. */ - ulldbg("ERROR: ED xfrtype:%d TD CTRL:%08x/CC:%d RHPORTST1:%08x\n", - ed->xfrtype, td->hw.ctrl, ed->tdstatus, - sam_getreg(SAM_USBHOST_RHPORTST1)); + ulldbg("ERROR: ED xfrtype: %d TD CTRL: %08x/CC: %d\n", + ed->xfrtype, td->hw.ctrl, ed->tdstatus); } #endif @@ -1519,7 +1552,7 @@ static int sam_ohci_interrupt(int irq, FAR void *context) #ifdef CONFIG_DEBUG_USB if ((pending & SAM_DEBUG_INTS) != 0) { - ulldbg("ERROR: Unhandled interrupts INTST:%08x\n", intst); + ulldbg("ERROR: Unhandled interrupts INTST: %08x\n", intst); } #endif @@ -1539,17 +1572,21 @@ static int sam_ohci_interrupt(int irq, FAR void *context) * Name: sam_wait * * Description: - * Wait for a device to be connected or disconneced. + * Wait for a device to be connected or disconnected to/from a root hub port. * * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call * to the class create() method. - * connected - TRUE: Wait for device to be connected; FALSE: wait for device - * to be disconnected + * connected - A pointer to an array of 3 boolean values corresponding to + * root hubs 1, 2, and 3. For each boolean value: TRUE: Wait for a device + * to be connected on the root hub; FALSE: wait for device to be + * disconnected from the root hub. * * Returned Values: - * Zero (OK) is returned when a device in connected. This function will not - * return until either (1) a device is connected or (2) some failure occurs. + * And index [0, 1, or 2} corresponding to the root hub port number {1, 2, + * or 3} is returned when a device is connected or disconnected. This + * function will not return until either (1) a device is connected or + * disconnected to/from any root hub port or until (2) some failure occurs. * On a failure, a negated errno value is returned indicating the nature of * the failure * @@ -1559,25 +1596,47 @@ static int sam_ohci_interrupt(int irq, FAR void *context) * *******************************************************************************/ -static int sam_wait(FAR struct usbhost_driver_s *drvr, bool connected) +static int sam_wait(FAR struct usbhost_driver_s *drvr, FAR const bool *connected) { struct sam_ohci_s *priv = (struct sam_ohci_s *)drvr; irqstate_t flags; + int rhpndx; - /* Are we already connected? */ + /* Loop until a change in the connection state changes on one of the root hub + * ports or until an error occurs. + */ flags = irqsave(); - while (priv->connected == connected) + for (;;) { - /* No... wait for the connection/disconnection */ + /* Check for a change in the connection state on any root hub port */ + + for (rhpndx = 0; rhpndx < SAM_USBHOST_NRHPORT; rhpndx++) + { + /* Has the connection state changed on the RH port? */ + + while (priv->rhport[rhpndx].connected != connected[rhpndx]) + { + /* Yes.. break out and return the RH port number */ + + break; + } + } + + /* No changes on any port. Wait for a connection/disconnection event + * and check again + */ priv->rhswait = true; sam_takesem(&priv->rhssem); } + irqrestore(flags); - udbg("Connected:%s\n", priv->connected ? "YES" : "NO"); - return OK; + udbg("RHPort%d connected: %s\n", + rhpndx + 1, priv->rhport[rhpndx].connected ? "YES" : "NO"); + + return rhpndx; } /******************************************************************************* @@ -1596,6 +1655,7 @@ static int sam_wait(FAR struct usbhost_driver_s *drvr, bool connected) * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call to * the class create() method. + * rphndx - Root hub port index. 0-(n-1) corresponds to root hub port 1-n. * * Returned Values: * On success, zero (OK) is returned. On a failure, a negated errno value is @@ -1608,15 +1668,16 @@ static int sam_wait(FAR struct usbhost_driver_s *drvr, bool connected) * *******************************************************************************/ -static int sam_enumerate(FAR struct usbhost_driver_s *drvr) +static int sam_enumerate(FAR struct usbhost_driver_s *drvr, int rhpndx) { struct sam_ohci_s *priv = (struct sam_ohci_s *)drvr; + uint32_t regaddr; /* Are we connected to a device? The caller should have called the wait() * method first to be assured that a device is connected. */ - while (!priv->connected) + while (!priv->rhport[rhpndx].connected) { /* No, return an error */ @@ -1628,25 +1689,26 @@ static int sam_enumerate(FAR struct usbhost_driver_s *drvr) up_mdelay(100); - /* Put RH port 1 in reset (the LPC176x supports only a single downstream port) */ + /* Put the root hub port in reset (the SAMA5 supports three downstream ports) */ - sam_putreg(OHCI_RHPORTST_PRS, SAM_USBHOST_RHPORTST1); + regaddr = SAM_USBHOST_RHPORTST(rhpndx+1); + sam_putreg(OHCI_RHPORTST_PRS, regaddr); /* Wait for the port reset to complete */ - while ((sam_getreg(SAM_USBHOST_RHPORTST1) & OHCI_RHPORTST_PRS) != 0); + while ((sam_getreg(regaddr) & OHCI_RHPORTST_PRS) != 0); /* Release RH port 1 from reset and wait a bit */ - sam_putreg(OHCI_RHPORTST_PRSC, SAM_USBHOST_RHPORTST1); + sam_putreg(OHCI_RHPORTST_PRSC, regaddr); up_mdelay(200); /* Let the common usbhost_enumerate do all of the real work. Note that the - * FunctionAddress (USB address) is hardcoded to one. + * FunctionAddress (USB address) is set to the root hub port number for now. */ uvdbg("Enumerate the device\n"); - return usbhost_enumerate(drvr, 1, &priv->class); + return usbhost_enumerate(drvr, rhpndx+1, &priv->class); } /************************************************************************************ @@ -1678,8 +1740,10 @@ static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr, uint16_t maxpacketsize) { struct sam_ohci_s *priv = (struct sam_ohci_s *)drvr; + int rhpndx = (int)funcaddr - 1; - DEBUGASSERT(drvr && funcaddr < 128 && maxpacketsize < 2048); + DEBUGASSERT(drvr && funcaddr > 0 && funcaddr <= SAM_USBHOST_NRHPORT && + maxpacketsize < 2048); /* We must have exclusive access to EP0 and the control list */ @@ -1688,9 +1752,9 @@ static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr, /* Set the EP0 ED control word */ g_edctrl.hw.ctrl = (uint32_t)funcaddr << ED_CONTROL_FA_SHIFT | - (uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT; + (uint32_t)maxpacketsize << ED_CONTROL_MPS_SHIFT; - if (priv->lowspeed) + if (priv->rhport[rhpndx].lowspeed) { g_edctrl.hw.ctrl |= ED_CONTROL_S; } @@ -1700,7 +1764,7 @@ static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr, g_edctrl.xfrtype = USB_EP_ATTR_XFER_CONTROL; sam_givesem(&priv->exclsem); - uvdbg("EP0 CTRL:%08x\n", g_edctrl.hw.ctrl); + uvdbg("EP0 CTRL: %08x\n", g_edctrl.hw.ctrl); return OK; } @@ -1731,13 +1795,16 @@ static int sam_epalloc(FAR struct usbhost_driver_s *drvr, { struct sam_ohci_s *priv = (struct sam_ohci_s *)drvr; struct sam_ed_s *ed; + int rhpndx = (int)epdesc->funcaddr - 1; int ret = -ENOMEM; /* Sanity check. NOTE that this method should only be called if a device is * connected (because we need a valid low speed indication). */ - DEBUGASSERT(priv && epdesc && ep && priv->connected); + DEBUGASSERT(priv && epdesc && ep && + rhpndx >= 0 && rhpndx < SAM_USBHOST_NRHPORT && + priv->rhport[rhpndx].connected); /* We must have exclusive access to the ED pool, the bulk list, the periodic list * and the interrupt table. @@ -1776,7 +1843,7 @@ static int sam_epalloc(FAR struct usbhost_driver_s *drvr, /* Check for a low-speed device */ - if (priv->lowspeed) + if (priv->rhport[rhpndx].lowspeed) { ed->hw.ctrl |= ED_CONTROL_S; } @@ -1793,7 +1860,7 @@ static int sam_epalloc(FAR struct usbhost_driver_s *drvr, ed->hw.ctrl |= ED_CONTROL_F; } #endif - uvdbg("EP%d CTRL:%08x\n", epdesc->addr, ed->hw.ctrl); + uvdbg("EP%d CTRL: %08x\n", epdesc->addr, ed->hw.ctrl); /* Initialize the semaphore that is used to wait for the endpoint * WDH event. @@ -2124,7 +2191,7 @@ static int sam_ctrlin(FAR struct usbhost_driver_s *drvr, int ret; DEBUGASSERT(drvr && req); - uvdbg("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + uvdbg("type: %02x req: %02x value: %02x%02x index: %02x%02x len: %02x%02x\n", req->type, req->req, req->value[1], req->value[0], req->index[1], req->index[0], req->len[1], req->len[0]); @@ -2160,7 +2227,7 @@ static int sam_ctrlout(FAR struct usbhost_driver_s *drvr, int ret; DEBUGASSERT(drvr && req); - uvdbg("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + uvdbg("type: %02x req: %02x value: %02x%02x index: %02x%02x len: %02x%02x\n", req->type, req->req, req->value[1], req->value[0], req->index[1], req->index[0], req->len[1], req->len[0]); @@ -2241,7 +2308,7 @@ static int sam_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, DEBUGASSERT(priv && ed && buffer && buflen > 0); in = (ed->hw.ctrl & ED_CONTROL_D_MASK) == ED_CONTROL_D_IN; - uvdbg("EP%d %s toggle:%d maxpacket:%d buflen:%d\n", + uvdbg("EP%d %s toggle: %d maxpacket: %d buflen: %d\n", (ed->hw.ctrl & ED_CONTROL_EN_MASK) >> ED_CONTROL_EN_SHIFT, in ? "IN" : "OUT", (ed->hw.headp & ED_HEADP_C) != 0 ? 1 : 0, @@ -2583,8 +2650,14 @@ FAR struct usbhost_driver_s *sam_ohci_initialize(int controller) * connected. We need to set the initial connected state accordingly. */ - regval = sam_getreg(SAM_USBHOST_RHPORTST1); - priv->connected = ((regval & OHCI_RHPORTST_CCS) != 0); + for (i = 0; i < SAM_USBHOST_NRHPORT; i++) + { + regval = sam_getreg(SAM_USBHOST_RHPORTST(i)); + priv->rhport[i].connected = ((regval & OHCI_RHPORTST_CCS) != 0); + + uvdbg("RHPort%d Device connected: %s\n", + i+1, priv->rhport[i].connected ? "YES" : "NO"); + } /* Drive Vbus +5V (the smoke test). Should be done elsewhere in OTG * mode. @@ -2595,8 +2668,7 @@ FAR struct usbhost_driver_s *sam_ohci_initialize(int controller) /* Enable interrupts at the interrupt controller */ up_enable_irq(SAM_IRQ_UHPHS); /* enable USB interrupt */ - udbg("USB host Initialized, Device connected:%s\n", - priv->connected ? "YES" : "NO"); + uvdbg("USB OHCI Initialized\n"); return &priv->drvr; } diff --git a/nuttx/arch/arm/src/stm32/stm32_otgfshost.c b/nuttx/arch/arm/src/stm32/stm32_otgfshost.c index 831bde5bc..d1b4f5f54 100644 --- a/nuttx/arch/arm/src/stm32/stm32_otgfshost.c +++ b/nuttx/arch/arm/src/stm32/stm32_otgfshost.c @@ -358,8 +358,8 @@ static void stm32_txfe_enable(FAR struct stm32_usbhost_s *priv, int chidx); /* USB host controller operations **********************************************/ -static int stm32_wait(FAR struct usbhost_driver_s *drvr, bool connected); -static int stm32_enumerate(FAR struct usbhost_driver_s *drvr); +static int stm32_wait(FAR struct usbhost_driver_s *drvr, FAR bool *connected); +static int stm32_enumerate(FAR struct usbhost_driver_s *drvr, int rhpndx); static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr, uint16_t maxpacketsize); static int stm32_epalloc(FAR struct usbhost_driver_s *drvr, @@ -3013,8 +3013,8 @@ static void stm32_txfe_enable(FAR struct stm32_usbhost_s *priv, int chidx) * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call to * the class create() method. - * connected - TRUE: Wait for device to be connected; FALSE: wait for device - * to be disconnected + * connected - A pointer to a boolean value. TRUE: Wait for device to be + * connected; FALSE: wait for device to be disconnected * * Returned Values: * Zero (OK) is returned when a device in connected. This function will not @@ -3028,7 +3028,7 @@ static void stm32_txfe_enable(FAR struct stm32_usbhost_s *priv, int chidx) * *******************************************************************************/ -static int stm32_wait(FAR struct usbhost_driver_s *drvr, bool connected) +static int stm32_wait(FAR struct usbhost_driver_s *drvr, FAR bool *connected) { FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; irqstate_t flags; @@ -3036,7 +3036,7 @@ static int stm32_wait(FAR struct usbhost_driver_s *drvr, bool connected) /* Are we already connected? */ flags = irqsave(); - while (priv->connected == connected) + while (priv->connected == *connected) { /* No... wait for the connection/disconnection */ @@ -3066,6 +3066,7 @@ static int stm32_wait(FAR struct usbhost_driver_s *drvr, bool connected) * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call to * the class create() method. + * rphndx - Root hub port index. 0-(n-1) corresponds to root hub port 1-n. * * Returned Values: * On success, zero (OK) is returned. On a failure, a negated errno value is @@ -3078,13 +3079,15 @@ static int stm32_wait(FAR struct usbhost_driver_s *drvr, bool connected) * *******************************************************************************/ -static int stm32_enumerate(FAR struct usbhost_driver_s *drvr) +static int stm32_enumerate(FAR struct usbhost_driver_s *drvr, int rhpndx) { struct stm32_usbhost_s *priv = (struct stm32_usbhost_s *)drvr; uint32_t regval; int chidx; int ret; + DEBUGASSERT(priv && rhpndx == 0); + /* Are we connected to a device? The caller should have called the wait() * method first to be assured that a device is connected. */ diff --git a/nuttx/configs/cloudctrl/src/up_usb.c b/nuttx/configs/cloudctrl/src/up_usb.c index 98f015dee..2407285c5 100644 --- a/nuttx/configs/cloudctrl/src/up_usb.c +++ b/nuttx/configs/cloudctrl/src/up_usb.c @@ -109,7 +109,7 @@ static int usbhost_waiter(int argc, char *argv[]) { /* Wait for the device to change state */ - ret = DRVR_WAIT(g_drvr, connected); + ret = DRVR_WAIT(g_drvr, &connected); DEBUGASSERT(ret == OK); connected = !connected; @@ -121,7 +121,7 @@ static int usbhost_waiter(int argc, char *argv[]) { /* Yes.. enumerate the newly connected device */ - (void)DRVR_ENUMERATE(g_drvr); + (void)DRVR_ENUMERATE(g_drvr, 0); } } diff --git a/nuttx/configs/mikroe-stm32f4/src/up_usb.c b/nuttx/configs/mikroe-stm32f4/src/up_usb.c index f8debe5ab..cb94e5cbe 100644 --- a/nuttx/configs/mikroe-stm32f4/src/up_usb.c +++ b/nuttx/configs/mikroe-stm32f4/src/up_usb.c @@ -108,7 +108,7 @@ static int usbhost_waiter(int argc, char *argv[]) { /* Wait for the device to change state */ - ret = DRVR_WAIT(g_drvr, connected); + ret = DRVR_WAIT(g_drvr, &connected); DEBUGASSERT(ret == OK); connected = !connected; @@ -120,7 +120,7 @@ static int usbhost_waiter(int argc, char *argv[]) { /* Yes.. enumerate the newly connected device */ - (void)DRVR_ENUMERATE(g_drvr); + (void)DRVR_ENUMERATE(g_drvr, 0); } } diff --git a/nuttx/configs/olimex-lpc1766stk/src/up_nsh.c b/nuttx/configs/olimex-lpc1766stk/src/up_nsh.c index 4ca474c65..e893ba27e 100644 --- a/nuttx/configs/olimex-lpc1766stk/src/up_nsh.c +++ b/nuttx/configs/olimex-lpc1766stk/src/up_nsh.c @@ -169,7 +169,7 @@ static int nsh_waiter(int argc, char *argv[]) { /* Wait for the device to change state */ - ret = DRVR_WAIT(g_drvr, connected); + ret = DRVR_WAIT(g_drvr, &connected); DEBUGASSERT(ret == OK); connected = !connected; @@ -181,7 +181,7 @@ static int nsh_waiter(int argc, char *argv[]) { /* Yes.. enumerate the newly connected device */ - (void)DRVR_ENUMERATE(g_drvr); + (void)DRVR_ENUMERATE(g_drvr, 0); } } diff --git a/nuttx/configs/open1788/src/lpc17_nsh.c b/nuttx/configs/open1788/src/lpc17_nsh.c index 3dca28b2f..fa6e086ed 100644 --- a/nuttx/configs/open1788/src/lpc17_nsh.c +++ b/nuttx/configs/open1788/src/lpc17_nsh.c @@ -193,7 +193,7 @@ static int nsh_waiter(int argc, char *argv[]) { /* Wait for the device to change state */ - ret = DRVR_WAIT(g_drvr, connected); + ret = DRVR_WAIT(g_drvr, &connected); DEBUGASSERT(ret == OK); connected = !connected; @@ -205,7 +205,7 @@ static int nsh_waiter(int argc, char *argv[]) { /* Yes.. enumerate the newly connected device */ - (void)DRVR_ENUMERATE(g_drvr); + (void)DRVR_ENUMERATE(g_drvr, 0); } } diff --git a/nuttx/configs/pic32-starterkit/src/up_nsh.c b/nuttx/configs/pic32-starterkit/src/up_nsh.c index 71909f92e..7c8e21412 100644 --- a/nuttx/configs/pic32-starterkit/src/up_nsh.c +++ b/nuttx/configs/pic32-starterkit/src/up_nsh.c @@ -197,7 +197,7 @@ static int nsh_waiter(int argc, char *argv[]) { /* Wait for the device to change state */ - ret = DRVR_WAIT(g_drvr, connected); + ret = DRVR_WAIT(g_drvr, &connected); DEBUGASSERT(ret == OK); connected = !connected; @@ -209,7 +209,7 @@ static int nsh_waiter(int argc, char *argv[]) { /* Yes.. enumerate the newly connected device */ - (void)DRVR_ENUMERATE(g_drvr); + (void)DRVR_ENUMERATE(g_drvr, 0); } } diff --git a/nuttx/configs/pic32mx7mmb/src/up_nsh.c b/nuttx/configs/pic32mx7mmb/src/up_nsh.c index 37ecc3095..5e59af564 100644 --- a/nuttx/configs/pic32mx7mmb/src/up_nsh.c +++ b/nuttx/configs/pic32mx7mmb/src/up_nsh.c @@ -196,7 +196,7 @@ static int nsh_waiter(int argc, char *argv[]) { /* Wait for the device to change state */ - ret = DRVR_WAIT(g_drvr, connected); + ret = DRVR_WAIT(g_drvr, &connected); DEBUGASSERT(ret == OK); connected = !connected; @@ -208,7 +208,7 @@ static int nsh_waiter(int argc, char *argv[]) { /* Yes.. enumerate the newly connected device */ - (void)DRVR_ENUMERATE(g_drvr); + (void)DRVR_ENUMERATE(g_drvr, 0); } } diff --git a/nuttx/configs/sama5d3x-ek/src/sam_usb.c b/nuttx/configs/sama5d3x-ek/src/sam_usb.c index 3b009bb41..3ab5d3c39 100644 --- a/nuttx/configs/sama5d3x-ek/src/sam_usb.c +++ b/nuttx/configs/sama5d3x-ek/src/sam_usb.c @@ -54,6 +54,7 @@ #include "up_arch.h" #include "sam_pio.h" #include "sam_usbhost.h" +#include "chip/sam_ohci.h" #include "sama5d3x-ek.h" #if defined(CONFIG_SAMA5_UHPHS) || defined(CONFIG_SAMA5_UDPHS) @@ -97,25 +98,29 @@ static struct usbhost_driver_s *g_ehci; #if HAVE_USBHOST static int usbhost_waiter(struct usbhost_driver_s *dev) { - bool connected = false; + bool connected[SAM_USBHOST_NRHPORT] = {false, false, false}; + int rhpndx; uvdbg("Running\n"); for (;;) { /* Wait for the device to change state */ - DEBUGVERIFY(DRVR_WAIT(dev, connected) == OK); + rhpndx = DRVR_WAIT(dev, connected); + DEBUGASSERT(rhpndx >= 0 && rhpndx < SAM_USBHOST_NRHPORT); - connected = !connected; - uvdbg("%s\n", connected ? "connected" : "disconnected"); + connected[rhpndx] = !connected[rhpndx]; + + uvdbg("RHport%d %s\n", + rhpndx + 1, connected[rhpndx] ? "connected" : "disconnected"); /* Did we just become connected? */ - if (connected) + if (connected[rhpndx]) { /* Yes.. enumerate the newly connected device */ - (void)DRVR_ENUMERATE(dev); + (void)DRVR_ENUMERATE(dev, rhpndx); } } diff --git a/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h b/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h index 0cf87b2e4..9f91aee92 100644 --- a/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h +++ b/nuttx/configs/sama5d3x-ek/src/sama5d3x-ek.h @@ -293,7 +293,7 @@ PIO_PORT_PIOD | PIO_PIN27) /* Both Ports B and C - * + * * PIO Signal Name Function * ---- ----------- ------------------------------------------------------- * PD28 OVCUR_USB Combined overrcurrent indication from port A and B diff --git a/nuttx/configs/shenzhou/src/up_usb.c b/nuttx/configs/shenzhou/src/up_usb.c index 0ae1d8c52..88f6d96ba 100644 --- a/nuttx/configs/shenzhou/src/up_usb.c +++ b/nuttx/configs/shenzhou/src/up_usb.c @@ -108,7 +108,7 @@ static int usbhost_waiter(int argc, char *argv[]) { /* Wait for the device to change state */ - ret = DRVR_WAIT(g_drvr, connected); + ret = DRVR_WAIT(g_drvr, &connected); DEBUGASSERT(ret == OK); connected = !connected; @@ -120,7 +120,7 @@ static int usbhost_waiter(int argc, char *argv[]) { /* Yes.. enumerate the newly connected device */ - (void)DRVR_ENUMERATE(g_drvr); + (void)DRVR_ENUMERATE(g_drvr, 0); } } diff --git a/nuttx/configs/stm3220g-eval/src/up_usb.c b/nuttx/configs/stm3220g-eval/src/up_usb.c index b16bdb6aa..4de02df96 100644 --- a/nuttx/configs/stm3220g-eval/src/up_usb.c +++ b/nuttx/configs/stm3220g-eval/src/up_usb.c @@ -108,7 +108,7 @@ static int usbhost_waiter(int argc, char *argv[]) { /* Wait for the device to change state */ - ret = DRVR_WAIT(g_drvr, connected); + ret = DRVR_WAIT(g_drvr, &connected); DEBUGASSERT(ret == OK); connected = !connected; @@ -120,7 +120,7 @@ static int usbhost_waiter(int argc, char *argv[]) { /* Yes.. enumerate the newly connected device */ - (void)DRVR_ENUMERATE(g_drvr); + (void)DRVR_ENUMERATE(g_drvr, 0); } } diff --git a/nuttx/configs/stm3240g-eval/src/up_usb.c b/nuttx/configs/stm3240g-eval/src/up_usb.c index b9082cbe7..c69a017bb 100644 --- a/nuttx/configs/stm3240g-eval/src/up_usb.c +++ b/nuttx/configs/stm3240g-eval/src/up_usb.c @@ -108,7 +108,7 @@ static int usbhost_waiter(int argc, char *argv[]) { /* Wait for the device to change state */ - ret = DRVR_WAIT(g_drvr, connected); + ret = DRVR_WAIT(g_drvr, &connected); DEBUGASSERT(ret == OK); connected = !connected; @@ -120,7 +120,7 @@ static int usbhost_waiter(int argc, char *argv[]) { /* Yes.. enumerate the newly connected device */ - (void)DRVR_ENUMERATE(g_drvr); + (void)DRVR_ENUMERATE(g_drvr, 0); } } diff --git a/nuttx/configs/stm32f4discovery/src/up_usb.c b/nuttx/configs/stm32f4discovery/src/up_usb.c index 4a5268155..166f4e7a9 100644 --- a/nuttx/configs/stm32f4discovery/src/up_usb.c +++ b/nuttx/configs/stm32f4discovery/src/up_usb.c @@ -108,7 +108,7 @@ static int usbhost_waiter(int argc, char *argv[]) { /* Wait for the device to change state */ - ret = DRVR_WAIT(g_drvr, connected); + ret = DRVR_WAIT(g_drvr, &connected); DEBUGASSERT(ret == OK); connected = !connected; @@ -120,7 +120,7 @@ static int usbhost_waiter(int argc, char *argv[]) { /* Yes.. enumerate the newly connected device */ - (void)DRVR_ENUMERATE(g_drvr); + (void)DRVR_ENUMERATE(g_drvr, 0); } } diff --git a/nuttx/configs/sure-pic32mx/src/pic32mx_nsh.c b/nuttx/configs/sure-pic32mx/src/pic32mx_nsh.c index 294afcb79..b9ea90dba 100644 --- a/nuttx/configs/sure-pic32mx/src/pic32mx_nsh.c +++ b/nuttx/configs/sure-pic32mx/src/pic32mx_nsh.c @@ -1,7 +1,7 @@ /**************************************************************************** * config/sure-pic32mx/src/pic32mx_nsh.c * - * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -188,7 +188,7 @@ static int nsh_waiter(int argc, char *argv[]) { /* Wait for the device to change state */ - ret = DRVR_WAIT(g_drvr, connected); + ret = DRVR_WAIT(g_drvr, &connected); DEBUGASSERT(ret == OK); connected = !connected; @@ -200,7 +200,7 @@ static int nsh_waiter(int argc, char *argv[]) { /* Yes.. enumerate the newly connected device */ - (void)DRVR_ENUMERATE(g_drvr); + (void)DRVR_ENUMERATE(g_drvr, 0); } } diff --git a/nuttx/include/nuttx/usb/usbhost.h b/nuttx/include/nuttx/usb/usbhost.h index e8a5a9636..d357e0b9b 100644 --- a/nuttx/include/nuttx/usb/usbhost.h +++ b/nuttx/include/nuttx/usb/usbhost.h @@ -1,7 +1,7 @@ /************************************************************************************ * include/nuttx/usb/usbhost.h * - * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2010-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * References: @@ -155,22 +155,26 @@ * Name: DRVR_WAIT * * Description: - * Wait for a device to be connected or disconneced. + * Wait for a device to be connected or disconnected to/from a root hub port. * * Input Parameters: - * drvr - The USB host driver instance obtained as a parameter from the call to - * the class create() method. - * connected - TRUE: Wait for device to be connected; FALSE: wait for device to - * be disconnected + * drvr - The USB host driver instance obtained as a parameter from the call + * to the class create() method. + * connected - A pointer to an array of n boolean values corresponding to + * root hubs 1 through n. For each boolean value: TRUE: Wait for a device + * to be connected on the root hub; FALSE: wait for device to be + * disconnected from the root hub. * * Returned Values: - * Zero (OK) is returned when a device in connected. This function will not - * return until either (1) a device is connected or (2) some failure occurs. - * On a failure, a negated errno value is returned indicating the nature of - * the failure + * And index [0..(n-1)} corresponding to the root hub port number {1..n} is + * returned when a device in connected or disconnectd. This function will not + * return until either (1) a device is connected or disconntect to/from any + * root hub port or until (2) some failure occurs. On a failure, a negated + * errno value is returned indicating the nature of the failure * * Assumptions: - * This function will *not* be called from an interrupt handler. + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. * *******************************************************************************/ @@ -192,6 +196,7 @@ * Input Parameters: * drvr - The USB host driver instance obtained as a parameter from the call to * the class create() method. + * rphndx - Root hub port index. 0-(n-1) corresponds to root hub port 1-n. * * Returned Values: * On success, zero (OK) is returned. On a failure, a negated errno value is @@ -202,7 +207,7 @@ * ************************************************************************************/ -#define DRVR_ENUMERATE(drvr) ((drvr)->enumerate(drvr)) +#define DRVR_ENUMERATE(drvr,rhpndx) ((drvr)->enumerate(drvr,rhpndx)) /************************************************************************************ * Name: DRVR_EP0CONFIGURE @@ -589,19 +594,19 @@ struct usbhost_driver_s { /* Wait for a device to connect or disconnect. */ - int (*wait)(FAR struct usbhost_driver_s *drvr, bool connected); + int (*wait)(FAR struct usbhost_driver_s *drvr, FAR const bool *connected); - /* Enumerate the connected device. As part of this enumeration process, - * the driver will (1) get the device's configuration descriptor, (2) - * extract the class ID info from the configuration descriptor, (3) call - * usbhost_findclass() to find the class that supports this device, (4) - * call the create() method on the struct usbhost_registry_s interface - * to get a class instance, and finally (5) call the connect() method - * of the struct usbhost_class_s interface. After that, the class is in - * charge of the sequence of operations. + /* Enumerate the device connected on a root hub port. As part of this + * enumeration process, the driver will (1) get the device's configuration + * descriptor, (2) extract the class ID info from the configuration + * descriptor, (3) call usbhost_findclass() to find the class that supports + * this device, (4) call the create() method on the struct usbhost_registry_s + * interface to get a class instance, and finally (5) call the connect() + * method of the struct usbhost_class_s interface. After that, the class is + * in charge of the sequence of operations. */ - int (*enumerate)(FAR struct usbhost_driver_s *drvr); + int (*enumerate)(FAR struct usbhost_driver_s *drvr, int rhpndx); /* Configure endpoint 0. This method is normally used internally by the * enumerate() method but is made available at the interface to support @@ -689,7 +694,8 @@ struct usbhost_driver_s #undef EXTERN #if defined(__cplusplus) #define EXTERN extern "C" -extern "C" { +extern "C" +{ #else #define EXTERN extern #endif @@ -718,7 +724,7 @@ extern "C" { * ************************************************************************************/ -EXTERN int usbhost_registerclass(struct usbhost_registry_s *class); +int usbhost_registerclass(struct usbhost_registry_s *class); /************************************************************************************ * Name: usbhost_findclass @@ -740,7 +746,7 @@ EXTERN int usbhost_registerclass(struct usbhost_registry_s *class); * ************************************************************************************/ -EXTERN const struct usbhost_registry_s *usbhost_findclass(const struct usbhost_id_s *id); +const struct usbhost_registry_s *usbhost_findclass(const struct usbhost_id_s *id); /**************************************************************************** * Name: usbhost_storageinit @@ -759,7 +765,7 @@ EXTERN const struct usbhost_registry_s *usbhost_findclass(const struct usbhost_i * ****************************************************************************/ -EXTERN int usbhost_storageinit(void); +int usbhost_storageinit(void); /**************************************************************************** * Name: usbhost_kbdinit @@ -778,7 +784,7 @@ EXTERN int usbhost_storageinit(void); * ****************************************************************************/ -EXTERN int usbhost_kbdinit(void); +int usbhost_kbdinit(void); /**************************************************************************** * Name: usbhost_wlaninit @@ -797,7 +803,7 @@ EXTERN int usbhost_kbdinit(void); * ****************************************************************************/ -EXTERN int usbhost_wlaninit(void); +int usbhost_wlaninit(void); /******************************************************************************* * Name: usbhost_enumerate @@ -836,9 +842,8 @@ EXTERN int usbhost_wlaninit(void); * *******************************************************************************/ -EXTERN int usbhost_enumerate(FAR struct usbhost_driver_s *drvr, - uint8_t funcaddr, - FAR struct usbhost_class_s **class); +int usbhost_enumerate(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr, + FAR struct usbhost_class_s **class); #undef EXTERN #if defined(__cplusplus) |