Add logic to handle state and BDTs correctly with USB packet is dispatched by the class driver

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4314 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-01-19 21:25:21 +00:00
parent 3a1523d2d9
commit c13af9c70f

View File

@ -1265,10 +1265,6 @@ static void pic32mx_ep0done(struct pic32mx_usbdev_s *priv,
} }
#endif #endif
/* Send the EP0 SETUP response */
pic32mx_epwrite(&priv->eplist[EP0], response, nbytes);
/* Prepare OUT EP to respond to early termination NOTE: If /* Prepare OUT EP to respond to early termination NOTE: If
* something went wrong during the control transfer, the last * something went wrong during the control transfer, the last
* status stage may not be sent by the host. When this happens, * status stage may not be sent by the host. When this happens,
@ -1331,6 +1327,7 @@ static void pic32mx_ep0setup(struct pic32mx_usbdev_s *priv)
union wb_u index; union wb_u index;
union wb_u len; union wb_u len;
union wb_u response; union wb_u response;
uint16_t regval;
bool dispatched = false; bool dispatched = false;
uint8_t epno; uint8_t epno;
int nbytes = 0; /* Assume zero-length packet */ int nbytes = 0; /* Assume zero-length packet */
@ -1394,7 +1391,8 @@ static void pic32mx_ep0setup(struct pic32mx_usbdev_s *priv)
/* Let the class implementation handle all non-standar requests */ /* Let the class implementation handle all non-standar requests */
pic32mx_dispatchrequest(priv); pic32mx_dispatchrequest(priv);
return; dispatched = true;
goto resume_packet_processing; /* Sorry about the goto */
} }
/* Handle standard request. Pick off the things of interest to the /* Handle standard request. Pick off the things of interest to the
@ -1813,6 +1811,15 @@ static void pic32mx_ep0setup(struct pic32mx_usbdev_s *priv)
break; break;
} }
/* PKTDIS bit is set when a Setup Transaction is received. Clear to resume
* packet processing.
*/
resume_packet_processing:
regval = pic32mx_getreg(PIC32MX_USB_CON);
regval &= ~USB_CON_PKTDIS;
pic32mx_putreg(regval, PIC32MX_USB_CON);
/* At this point, the request has been handled and there are three possible /* At this point, the request has been handled and there are three possible
* outcomes: * outcomes:
* *
@ -1830,40 +1837,40 @@ static void pic32mx_ep0setup(struct pic32mx_usbdev_s *priv)
* logic altogether. * logic altogether.
*/ */
if (!dispatched) if (!dispatched && (priv->ctrlstate != CTRLSTATE_STALLED))
{ {
uint16_t regval; /* The SETUP command was not dispatched to the class driver and the SETUP
* command did not cause a stall. We will respond. First, restrict the
/* PKTDIS bit is set when a Setup Transaction is received. Clear to resume * data length to the length requested in the setup packet
* packet processing.
*/ */
regval = pic32mx_getreg(PIC32MX_USB_CON); if (nbytes > len.w)
regval &= ~USB_CON_PKTDIS;
pic32mx_putreg(regval, PIC32MX_USB_CON);
if (priv->ctrlstate != CTRLSTATE_STALLED)
{ {
/* We will respond. First, restrict the data length to the length nbytes = len.w;
* requested in the setup packet
*/
if (nbytes > len.w)
{
nbytes = len.w;
}
/* Send the response (might be a zero-length packet) */
pic32mx_ep0done(priv, response.b, nbytes);
priv->ctrlstate = CTRLSTATE_WAITSETUP;
} }
else
{
/* Stall EP0 */
(void)pic32mx_epstall(&ep0->ep, false); /* Send the EP0 SETUP response (might be a zero-length packet) */
}
pic32mx_epwrite(&priv->eplist[EP0], response.b, nbytes);
priv->ctrlstate = CTRLSTATE_WAITSETUP;
}
/* Did we stall? This might have occurred from the above logic OR the stall
* condition may have been set less obviously in pic32mx_dispatchrequest().
* In either case, we handle the stall condition the same.
*/
if (priv->ctrlstate != CTRLSTATE_STALLED)
{
/* No.. Set up the BDTs to accept the next setup commend. */
pic32mx_ep0done(priv, response.b, nbytes);
}
else
{
/* Stall EP0 */
(void)pic32mx_epstall(&ep0->ep, false);
} }
} }