From 9527119f73d00229cbe74611f9ebc5c8d8c33f0f Mon Sep 17 00:00:00 2001 From: patacongo Date: Tue, 28 Aug 2012 22:28:49 +0000 Subject: [PATCH] Slightly improved delay logic for the USB host git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@5064 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- nuttx/arch/arm/src/stm32/stm32_otgfshost.c | 48 ++++++++++++++-------- nuttx/drivers/usbhost/usbhost_enumerate.c | 15 +++---- nuttx/drivers/usbhost/usbhost_storage.c | 12 ++++-- 3 files changed, 46 insertions(+), 29 deletions(-) diff --git a/nuttx/arch/arm/src/stm32/stm32_otgfshost.c b/nuttx/arch/arm/src/stm32/stm32_otgfshost.c index d888c52f14..6849049254 100644 --- a/nuttx/arch/arm/src/stm32/stm32_otgfshost.c +++ b/nuttx/arch/arm/src/stm32/stm32_otgfshost.c @@ -1474,7 +1474,7 @@ static int stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx, FAR uint8_t *buffer, size_t buflen) { FAR struct stm32_chan_s *chan; - int ret; + int ret = OK; /* Loop until the transfer completes (i.e., buflen is decremented to zero) * or a fatal error occurs (any error other than a simple NAK) @@ -1484,6 +1484,17 @@ static int stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx, chan->buffer = buffer; chan->buflen = buflen; + /* There is a bug in the code at present. With debug OFF, this driver + * overruns the typical FLASH device and there are many problems with + * NAKS. Sticking a big delay here allows the device (FLASH drive) to + * catch up but sacrifices driver performance. + */ + +#if !defined(CONFIG_DEBUG_VERBOSE) || !defined(CONFIG_DEBUG_USB) +#warning "REVISIT this delay" + usleep(50*1000); +#endif + while (chan->buflen > 0) { /* Set up for the wait BEFORE starting the transfer */ @@ -1537,17 +1548,6 @@ static int stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx, } } - /* There is a bug in the code at present. With debug OFF, this driver - * overruns the typical FLASH device and there are many problems with - * NAKS sticking a big delay here allows the driver to work but with - * very poor performance when debug is off. - */ - -#if !defined(CONFIG_DEBUG_VERBOSE) && !defined(CONFIG_DEBUG_USB) -#warning "REVISIT this delay" - usleep(100*1000); -#endif - /* Start the transfer */ stm32_transfer_start(priv, chidx); @@ -1557,18 +1557,30 @@ static int stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx, ret = stm32_chan_wait(priv, chan); /* EAGAIN indicates that the device NAKed the transfer and we need - * do try again. Anything else (success or other errors) will - * cause use to return + * do try again. NAK retries are not yet supported for OUT transfers + * so any unsuccessful response will cause us to abort the OUT + * transfer. */ if (ret != OK) { udbg("Transfer failed: %d\n", ret); - return ret; + break; } } - return OK; + /* There is a bug in the code at present. With debug OFF, this driver + * overruns the typical FLASH device and there are many problems with + * NAKS. Sticking a big delay here allows the device (FLASH drive) to + * catch up but sacrifices driver performance. + */ + +#if !defined(CONFIG_DEBUG_VERBOSE) || !defined(CONFIG_DEBUG_USB) +#warning "REVISIT this delay" + usleep(50*1000); +#endif + + return ret; } /******************************************************************************* @@ -3086,9 +3098,9 @@ static int stm32_enumerate(FAR struct usbhost_driver_s *drvr) priv->chan[chidx].indata1 = false; priv->chan[chidx].outdata1 = false; - /* USB 2.0 spec says at least 50ms delay before port reset */ + /* USB 2.0 spec says at least 50ms delay before port reset. We wait 100ms. */ - up_mdelay(100); + usleep(100*1000); /* Reset the host port */ diff --git a/nuttx/drivers/usbhost/usbhost_enumerate.c b/nuttx/drivers/usbhost/usbhost_enumerate.c index 36bfa20d19..26b93bf360 100644 --- a/nuttx/drivers/usbhost/usbhost_enumerate.c +++ b/nuttx/drivers/usbhost/usbhost_enumerate.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -317,7 +318,7 @@ int usbhost_enumerate(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr, DEBUGASSERT(drvr && class); - /* Allocate TD buffers for use in this function. We will need two: + /* Allocate descriptor buffers for use in this function. We will need two: * One for the request and one for the data buffer. */ @@ -400,7 +401,7 @@ int usbhost_enumerate(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr, udbg("ERROR: SETADDRESS DRVR_CTRLOUT returned %d\n", ret); goto errout; } - up_mdelay(2); + usleep(2*1000); /* Modify control pipe with the provided USB device address */ @@ -461,9 +462,9 @@ int usbhost_enumerate(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr, goto errout; } - /* Free the TD that we were using for the request buffer. It is not needed - * further here but it may be needed by the class driver during its connection - * operations. + /* Free the descriptor buffer that we were using for the request buffer. + * It is not needed further here but it may be needed by the class driver + * during its connection operations. */ DRVR_FREE(drvr, (uint8_t*)ctrlreq); @@ -488,9 +489,9 @@ int usbhost_enumerate(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr, } } - /* Some devices may require this delay before initialization */ + /* Some devices may require some delay before initialization */ - up_mdelay(100); + usleep(100*1000); /* Parse the configuration descriptor and bind to the class instance for the * device. This needs to be the last thing done because the class driver diff --git a/nuttx/drivers/usbhost/usbhost_storage.c b/nuttx/drivers/usbhost/usbhost_storage.c index 853287371d..2e3136b339 100644 --- a/nuttx/drivers/usbhost/usbhost_storage.c +++ b/nuttx/drivers/usbhost/usbhost_storage.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -724,6 +725,7 @@ static inline int usbhost_testunitready(FAR struct usbhost_state_s *priv) usbhost_dumpcsw((FAR struct usbmsc_csw_s *)priv->tbuffer); } } + return result; } @@ -1195,13 +1197,15 @@ static inline int usbhost_initvolume(FAR struct usbhost_state_s *priv) uvdbg("Get max LUN\n"); ret = usbhost_maxlunreq(priv); - /* Wait for the unit to be ready */ - - for (retries = 0; retries < USBHOST_MAX_RETRIES && ret == OK; retries++) + for (retries = 0; retries < USBHOST_MAX_RETRIES /* && ret == OK */; retries++) { uvdbg("Test unit ready, retries=%d\n", retries); - /* Send TESTUNITREADY to see the unit is ready */ + /* Wait just a bit */ + + usleep(50*1000); + + /* Send TESTUNITREADY to see if the unit is ready */ ret = usbhost_testunitready(priv); if (ret == OK)