Fix a problem with TX status on resume from stall

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2295 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2009-12-01 21:14:56 +00:00
parent 1e85cbd2b0
commit 00467c9bd0
4 changed files with 46 additions and 24 deletions

View File

@ -976,3 +976,6 @@
examples/usbstorage to configs/mcu123-lpc214x.
* configs/stm321e-eval/up_usbstrg - Add STM32-specific logic for the
examples/usbstorage test.
* arch/arm/src/stm32/stm32_usbdev.c - Fix bugs in STM32 USB device-side
driver: (1) Need to disconnect after reset received, (2) Status setup
to recover from stall on TX endpoint.

View File

@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
<p>Last Updated: November 30, 2009</p>
<p>Last Updated: December 1, 2009</p>
</td>
</tr>
</table>
@ -1624,6 +1624,9 @@ nuttx-4.14 2009-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
examples/usbstorage to configs/mcu123-lpc214x.
* configs/stm321e-eval/up_usbstrg - Add STM32-specific logic for the
examples/usbstorage test.
* arch/arm/src/stm32/stm32_usbdev.c - Fix bugs in STM32 USB device-side
driver: (1) Need to disconnect after reset received, (2) Status setup
to recover from stall on TX endpoint.
pascal-0.1.3 2009-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;

View File

@ -418,7 +418,7 @@ static int stm32_wrrequest(struct stm32_usbdev_s *priv,
struct stm32_ep_s *privep);
static int stm32_rdrequest(struct stm32_usbdev_s *priv,
struct stm32_ep_s *privep);
static void stm32_cancelrequests(struct stm32_ep_s *privep, int status);
static void stm32_cancelrequests(struct stm32_ep_s *privep);
/* Interrupt level processing ***********************************************/
@ -699,7 +699,8 @@ static inline uint16 stm32_geteptxaddr(ubyte epno)
static void stm32_seteprxcount(ubyte epno, uint16 count)
{
volatile uint32 *epaddr = (uint32*)STM32_USB_COUNT_RX(epno);
uint16 nblocks;
uint32 rxcount = 0;
uint16 nblocks;
/* The upper bits of the RX COUNT value contain the size of allocated
* RX buffer. This is based on a block size of 2 or 32:
@ -725,16 +726,17 @@ static void stm32_seteprxcount(ubyte epno, uint16 count)
nblocks = (count >> 5) - 1 ;
DEBUGASSERT(nblocks <= 0x0f);
*epaddr = (uint32)((nblocks << USB_COUNT_RX_NUM_BLOCK_SHIFT) | USB_COUNT_RX_BL_SIZE);
rxcount = (uint32)((nblocks << USB_COUNT_RX_NUM_BLOCK_SHIFT) | USB_COUNT_RX_BL_SIZE);
}
else
else if (count > 0)
{
/* Blocks of 2 (with 1 meaning one block of 2) */
nblocks = (count + 1) >> 1;
DEBUGASSERT(nblocks > 0 && nblocks < 0x1f);
*epaddr = (uint32)(nblocks << USB_COUNT_RX_NUM_BLOCK_SHIFT);
rxcount = (uint32)(nblocks << USB_COUNT_RX_NUM_BLOCK_SHIFT);
}
*epaddr = rxcount;
}
/****************************************************************************
@ -1219,7 +1221,7 @@ static int stm32_wrrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *prive
if (!privreq)
{
/* There is no TX transfer in progress and no new pending TX
* requests to send... STALL the TX status.
* requests to send.
*/
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPINQEMPTY), 0);
@ -1369,13 +1371,13 @@ static int stm32_rdrequest(struct stm32_usbdev_s *priv, struct stm32_ep_s *prive
* Name: stm32_cancelrequests
****************************************************************************/
static void stm32_cancelrequests(struct stm32_ep_s *privep, int status)
static void stm32_cancelrequests(struct stm32_ep_s *privep)
{
while (!stm32_rqempty(privep))
{
usbtrace(TRACE_COMPLETE(USB_EPNO(privep->ep.eplog)),
(stm32_rqpeek(privep))->req.xfrd);
stm32_reqcomplete(privep, status);
stm32_reqcomplete(privep, -ESHUTDOWN);
}
}
@ -2690,7 +2692,7 @@ static int stm32_epdisable(struct usbdev_ep_s *ep)
/* Cancel any ongoing activity */
flags = irqsave();
stm32_cancelrequests(privep, -ESHUTDOWN);
stm32_cancelrequests(privep);
/* Disable TX; disable RX */
@ -2878,7 +2880,7 @@ static int stm32_epcancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
priv = privep->dev;
flags = irqsave();
stm32_cancelrequests(privep, -ESHUTDOWN);
stm32_cancelrequests(privep);
irqrestore(flags);
return OK;
}
@ -2950,11 +2952,12 @@ static int stm32_epstall(struct usbdev_ep_s *ep, boolean resume)
/* Restart any queued write requests */
if (!stm32_rqempty(privep))
{
(void)stm32_wrrequest(priv, privep);
stm32_seteptxstatus(epno, USB_EPR_STATTX_VALID);
}
priv->txstatus = USB_EPR_STATTX_NAK;
(void)stm32_wrrequest(priv, privep);
/* Set the new TX status */
stm32_seteptxstatus(epno, priv->txstatus);
}
}
else
@ -2973,6 +2976,8 @@ static int stm32_epstall(struct usbdev_ep_s *ep, boolean resume)
{
stm32_clrrxdtog(epno);
}
priv->rxstatus = USB_EPR_STATRX_VALID;
stm32_seteprxstatus(epno, USB_EPR_STATRX_VALID);
}
}
@ -2989,12 +2994,14 @@ static int stm32_epstall(struct usbdev_ep_s *ep, boolean resume)
{
/* IN endpoint */
priv->txstatus = USB_EPR_STATTX_STALL;
stm32_seteptxstatus(epno, USB_EPR_STATTX_STALL);
}
else
{
/* OUT endpoint */
priv->rxstatus = USB_EPR_STATRX_STALL;
stm32_seteprxstatus(epno, USB_EPR_STATRX_STALL);
}
}
@ -3215,6 +3222,12 @@ static void stm32_reset(struct stm32_usbdev_s *priv)
stm32_putreg(USB_CNTR_FRES, STM32_USB_CNTR);
/* Tell the class driver that we are disconnected. The class driver
* should then accept any new configurations.
*/
CLASS_DISCONNECT(priv->driver, &priv->usbdev);
/* Reset the device state structure */
priv->devstate = DEVSTATE_IDLE;
@ -3227,12 +3240,15 @@ static void stm32_reset(struct stm32_usbdev_s *priv)
{
struct stm32_ep_s *privep = &priv->eplist[epno];
/* Cancel any queued write requests */
/* Cancel any queued requests. Since they are canceled
* with status -ESHUTDOWN, then will not be requeued
* until the configuration is reset. NOTE: This should
* not be necessary... the CLASS_DISCONNECT above should
* result in the class implementation calling stm32_epdisable
* for each of its configured endpoints.
*/
if (USB_ISEPIN(privep->ep.eplog))
{
stm32_cancelrequests(privep, -EPIPE);
}
stm32_cancelrequests(privep);
/* Reset endpoint status */

View File

@ -816,9 +816,9 @@ CONFIG_EXAMPLES_USBSTRG_NLUNS=1
CONFIG_EXAMPLES_USBSTRG_DEVMINOR1=0
CONFIG_EXAMPLES_USBSTRG_DEVPATH1="/dev/mmcsd0"
CONFIG_EXAMPLES_USBSTRG_TRACEINIT=n
CONFIG_EXAMPLES_USBSTRG_TRACECLASS=y
CONFIG_EXAMPLES_USBSTRG_TRACETRANSFERS=y
CONFIG_EXAMPLES_USBSTRG_TRACECONTROLLER=y
CONFIG_EXAMPLES_USBSTRG_TRACECLASS=n
CONFIG_EXAMPLES_USBSTRG_TRACETRANSFERS=n
CONFIG_EXAMPLES_USBSTRG_TRACECONTROLLER=n
CONFIG_EXAMPLES_USBSTRG_TRACEINTERRUPTS=n
#