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:
parent
3a1523d2d9
commit
c13af9c70f
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user