USB class drivers need to call DEV_CONNECT

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3159 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2010-12-04 17:35:19 +00:00
parent 1c5ab5f894
commit fbd11d66b3
10 changed files with 81 additions and 41 deletions

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: December 3, 2010</p>
<p>Last Updated: December 4, 2010</p>
</td>
</tr>
</table>
@ -2011,6 +2011,10 @@ nuttx-5.15 2010-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
or data. This is typical, for example, in "9-bit" displays where the 9th bit
is the CMD/DATA bit. The cmddata method provides selection of command or data.
* drivers/lcd/p14201.c -- Now used the cmddata() method of the SPI interface.
* arch/arm/src/lpc17xx/lpc17_usbdev.c -- LPC17xx USB driver is not functional.
* drivers/usbdev/usbserial.c and usbstorage.c -- All USB class drivers need
to call DEV_CONNECT() when they are ready to be enumerated. That is,
(1) initially when bound to the USB driver, and (2) after a USB reset.
pascal-2.1 2010-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;

9
TODO
View File

@ -716,13 +716,8 @@ o ARM/LPC17xx (arch/arm/src/lpc17xx/)
Status: Open
Priority: High
Description: a) USB DMA not fully implemented. Partial logic is in place but it is
fragmentary and bogus. (Leveraged from the lpc214x)
b) Possible errors in USB device driver reported "I suspect there's a few
issues in the lpc214x USB driver -- in particular it doesn't stall both
in/out endpoints for unsupported setup requests and it doesn't call
CLASS_DISCONNCET on a USB reset -- I don't have any access to that hardware
so can't pursue it really."
Description: USB DMA not fully implemented. Partial logic is in place but it is
fragmentary and bogus. (Leveraged from the lpc214x)
Status: Open
Priority: Low

View File

@ -1487,6 +1487,15 @@ static void lpc17_usbreset(struct lpc17_usbdev_s *priv)
lpc17_putreg(USB_SLOW_INT|USB_DEVSTATUS_INT|USB_FAST_INT|USB_FRAME_INT|USB_ERROR_INT,
LPC17_USBDEV_INTEN);
/* Tell the class driver that we are disconnected. The class
* driver should then accept any new configurations.
*/
if (priv->driver)
{
CLASS_DISCONNECT(priv->driver, &priv->usbdev);
}
}
/*******************************************************************************
@ -1895,8 +1904,8 @@ static inline void lpc17_ep0setup(struct lpc17_usbdev_s *priv)
if (priv->stalled)
{
usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_EP0SETUPSTALLED), priv->ep0state);
lpc17_epstall(&ep0->ep, false);
lpc17_epstall(&ep0->ep, false);
lpc17_epstall(&priv->eplist[LPC17_EP0_IN].ep, false);
lpc17_epstall(&priv->eplist[LPC17_EP0_OUT].ep, false);
}
}
@ -1957,9 +1966,8 @@ static inline void lpc17_ep0dataoutinterrupt(struct lpc17_usbdev_s *priv)
if (priv->stalled)
{
usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_EP0OUTSTALLED), priv->ep0state);
ep0 = &priv->eplist[LPC17_EP0_OUT];
lpc17_epstall(&ep0->ep, false);
lpc17_epstall(&ep0->ep, false);
lpc17_epstall(&priv->eplist[LPC17_EP0_IN].ep, false);
lpc17_epstall(&priv->eplist[LPC17_EP0_OUT].ep, false);
}
return;
}
@ -2024,9 +2032,8 @@ static inline void lpc17_ep0dataininterrupt(struct lpc17_usbdev_s *priv)
if (priv->stalled)
{
usbtrace(TRACE_DEVERROR(LPC17_TRACEERR_EP0INSTALLED), priv->ep0state);
ep0 = &priv->eplist[LPC17_EP0_IN];
lpc17_epstall(&ep0->ep, false);
lpc17_epstall(&ep0->ep, false);
lpc17_epstall(&priv->eplist[LPC17_EP0_IN].ep, false);
lpc17_epstall(&priv->eplist[LPC17_EP0_OUT].ep, false);
}
}

View File

@ -2604,7 +2604,11 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
/* FIXME: nothing seems to call DEV_CONNECT(), but we need to set
* the RS bit to enable the controller. It kind of makes sense
* to do this after the class has bound to us... */
* to do this after the class has bound to us...
* GEN: This bug is really in the class driver. It should make the
* soft connect when it is ready to be enumerated. I have added
* that logic to the class drivers but left this logic here.
*/
lpc313x_pullup(&g_usbdev.usbdev, true);
}

View File

@ -853,6 +853,12 @@ CONFIG_EXAMPLES_USBSTRG_TRACETRANSFERS=n
CONFIG_EXAMPLES_USBSTRG_TRACECONTROLLER=n
CONFIG_EXAMPLES_USBSTRG_TRACEINTERRUPTS=n
CONFIG_EXAMPLES_USBSTRG_TRACEINIT=n
CONFIG_EXAMPLES_USBSTRG_TRACECLASS=n
CONFIG_EXAMPLES_USBSTRG_TRACETRANSFERS=n
CONFIG_EXAMPLES_USBSTRG_TRACECONTROLLER=n
CONFIG_EXAMPLES_USBSTRG_TRACEINTERRUPTS=n
#
# Stack and heap information
#

View File

@ -60,6 +60,7 @@
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>

View File

@ -1392,6 +1392,10 @@ static int usbclass_bind(FAR struct usbdev_s *dev, FAR struct usbdevclass_driver
#ifdef CONFIG_USBDEV_SELFPOWERED
DEV_SETSELFPOWERED(dev);
#endif
/* And pull-up the data line for the soft connect function */
DEV_CONNECT(dev);
return OK;
errout:
@ -1830,6 +1834,12 @@ static void usbclass_disconnect(FAR struct usbdev_s *dev)
priv->serdev.xmit.head = 0;
priv->serdev.xmit.tail = 0;
irqrestore(flags);
/* Perform the soft connect function so that we will we can be
* re-enumerated.
*/
DEV_CONNECT(dev);
}
/****************************************************************************

View File

@ -601,6 +601,10 @@ static int usbstrg_bind(FAR struct usbdev_s *dev, FAR struct usbdevclass_driver_
#ifdef CONFIG_USBDEV_SELFPOWERED
DEV_SETSELFPOWERED(dev);
#endif
/* And pull-up the data line for the soft connect function */
DEV_CONNECT(dev);
return OK;
errout:
@ -1045,6 +1049,12 @@ static void usbstrg_disconnect(FAR struct usbdev_s *dev)
priv->theventset |= USBSTRG_EVENT_DISCONNECT;
pthread_cond_signal(&priv->cond);
irqrestore(flags);
/* Perform the soft connect function so that we will we can be
* re-enumerated.
*/
DEV_CONNECT(dev);
}
/****************************************************************************

View File

@ -367,21 +367,21 @@ struct usbstrg_lun_s
struct usbstrg_dev_s
{
FAR struct usbdev_s *usbdev; /* usbdev driver pointer (Non-null if registered) */
FAR struct usbdev_s *usbdev; /* usbdev driver pointer (Non-null if registered) */
/* Worker thread interface */
pthread_t thread; /* The worker thread */
pthread_mutex_t mutex; /* Mutually exclusive access to resources*/
pthread_cond_t cond; /* Used to signal worker thread */
pthread_t thread; /* The worker thread */
pthread_mutex_t mutex; /* Mutually exclusive access to resources*/
pthread_cond_t cond; /* Used to signal worker thread */
volatile uint8_t thstate; /* State of the worker thread */
volatile uint16_t theventset; /* Set of pending events signaled to worker thread */
volatile uint8_t thvalue; /* Value passed with the event (must persist) */
/* Storage class configuration and state */
uint8_t nluns:4; /* Number of LUNs */
uint8_t config; /* Configuration number */
uint8_t nluns:4; /* Number of LUNs */
uint8_t config; /* Configuration number */
/* Endpoints */
@ -394,29 +394,29 @@ struct usbstrg_dev_s
struct usbstrg_lun_s *lun; /* Currently selected LUN */
struct usbstrg_lun_s *luntab; /* Allocated table of all LUNs */
uint8_t cdb[USBSTRG_MAXCDBLEN]; /* Command data (cdb[]) from CBW */
uint8_t phaseerror:1; /* Need to send phase sensing status */
uint8_t shortpacket:1; /* Host transmission stopped unexpectedly */
uint8_t cbwdir:2; /* Direction from CBW. See USBSTRG_FLAGS_DIR* definitions */
uint8_t cdblen; /* Length of cdb[] from CBW */
uint8_t cbwlun; /* LUN from the CBW */
uint16_t nsectbytes; /* Bytes buffered in iobuffer[] */
uint16_t nreqbytes; /* Bytes buffered in head write requests */
uint16_t iosize; /* Size of iobuffer[] */
uint32_t cbwlen; /* Length of data from CBW */
uint32_t cbwtag; /* Tag from the CBW */
uint8_t phaseerror:1; /* Need to send phase sensing status */
uint8_t shortpacket:1; /* Host transmission stopped unexpectedly */
uint8_t cbwdir:2; /* Direction from CBW. See USBSTRG_FLAGS_DIR* definitions */
uint8_t cdblen; /* Length of cdb[] from CBW */
uint8_t cbwlun; /* LUN from the CBW */
uint16_t nsectbytes; /* Bytes buffered in iobuffer[] */
uint16_t nreqbytes; /* Bytes buffered in head write requests */
uint16_t iosize; /* Size of iobuffer[] */
uint32_t cbwlen; /* Length of data from CBW */
uint32_t cbwtag; /* Tag from the CBW */
union
{
uint32_t xfrlen; /* Read/Write: Sectors remaining to be transferred */
uint32_t alloclen; /* Other device-to-host: Host allocation length */
uint32_t xfrlen; /* Read/Write: Sectors remaining to be transferred */
uint32_t alloclen; /* Other device-to-host: Host allocation length */
} u;
uint32_t sector; /* Current sector (relative to lun->startsector) */
uint32_t residue; /* Untransferred amount reported in the CSW */
uint8_t *iobuffer; /* Buffer for data transfers */
uint32_t sector; /* Current sector (relative to lun->startsector) */
uint32_t residue; /* Untransferred amount reported in the CSW */
uint8_t *iobuffer; /* Buffer for data transfers */
/* Write request list */
struct sq_queue_s wrreqlist; /* List of empty write request containers */
struct sq_queue_s rdreqlist; /* List of filled read request containers */
struct sq_queue_s wrreqlist; /* List of empty write request containers */
struct sq_queue_s rdreqlist; /* List of filled read request containers */
/* Pre-allocated write request containers. The write requests will
* be linked in a free list (wrreqlist), and used to send requests to

View File

@ -135,7 +135,10 @@
#define DEV_CLRSELFPOWERED(dev) (dev)->ops->selfpowered(dev, false)
/* Software-controlled connect to USB host */
/* Software-controlled connect to USB host. All USB class drivers need to call
* DEV_CONNECT() when they are ready to be enumerated. That is, (1) initially when
* bound to the USB driver, and (2) after a USB reset.
*/
#define DEV_CONNECT(dev) (dev)->ops->pullup ? (dev)->ops->pullup(dev,true) : -EOPNOTSUPP