From c0a1148d1e58b1b4443134640cc0f2fdabc02609 Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 19 Jan 2012 21:25:21 +0000 Subject: 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 --- nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c | 69 +++++++++++++++------------- 1 file changed, 38 insertions(+), 31 deletions(-) (limited to 'nuttx/arch/mips/src/pic32mx') diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c b/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c index e1c3e7751..30801aa67 100644 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-usbdev.c @@ -1265,10 +1265,6 @@ static void pic32mx_ep0done(struct pic32mx_usbdev_s *priv, } #endif - /* Send the EP0 SETUP response */ - - pic32mx_epwrite(&priv->eplist[EP0], response, nbytes); - /* Prepare OUT EP to respond to early termination NOTE: If * something went wrong during the control transfer, the last * 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 len; union wb_u response; + uint16_t regval; bool dispatched = false; uint8_t epno; 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 */ 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 @@ -1813,6 +1811,15 @@ static void pic32mx_ep0setup(struct pic32mx_usbdev_s *priv) 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 * outcomes: * @@ -1830,40 +1837,40 @@ static void pic32mx_ep0setup(struct pic32mx_usbdev_s *priv) * logic altogether. */ - if (!dispatched) + if (!dispatched && (priv->ctrlstate != CTRLSTATE_STALLED)) { - uint16_t regval; - - /* PKTDIS bit is set when a Setup Transaction is received. Clear to resume - * packet processing. + /* 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 + * data length to the length requested in the setup packet */ - regval = pic32mx_getreg(PIC32MX_USB_CON); - regval &= ~USB_CON_PKTDIS; - pic32mx_putreg(regval, PIC32MX_USB_CON); - - if (priv->ctrlstate != CTRLSTATE_STALLED) + if (nbytes > len.w) { - /* We will respond. First, restrict the data length to the length - * requested in the setup packet - */ + nbytes = len.w; + } - if (nbytes > len.w) - { - nbytes = len.w; - } + /* Send the EP0 SETUP response (might be a zero-length packet) */ - /* Send the response (might be a zero-length packet) */ + pic32mx_epwrite(&priv->eplist[EP0], response.b, nbytes); + priv->ctrlstate = CTRLSTATE_WAITSETUP; + } - pic32mx_ep0done(priv, response.b, nbytes); - priv->ctrlstate = CTRLSTATE_WAITSETUP; - } - else - { - /* Stall EP0 */ + /* 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. + */ - (void)pic32mx_epstall(&ep0->ep, false); - } + 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); } } -- cgit v1.2.3