USB host: Update skeleton driver file

This commit is contained in:
Gregory Nutt
2015-04-21 09:54:11 -06:00
parent 6b27c48068
commit d6b963a62e
2 changed files with 42 additions and 44 deletions
+39 -42
View File
@@ -96,10 +96,6 @@ struct usbhost_state_s
struct usbhost_class_s usbclass; struct usbhost_class_s usbclass;
/* This is an instance of the USB host driver bound to this class instance */
struct usbhost_driver_s *drvr;
/* The remainder of the fields are provide to the class driver */ /* The remainder of the fields are provide to the class driver */
char devchar; /* Character identifying the /dev/skel[n] device */ char devchar; /* Character identifying the /dev/skel[n] device */
@@ -143,7 +139,7 @@ static void usbhost_destroy(FAR void *arg);
static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv, static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
FAR const uint8_t *configdesc, FAR const uint8_t *configdesc,
int desclen, uint8_t funcaddr); int desclen);
static inline int usbhost_devinit(FAR struct usbhost_state_s *priv); static inline int usbhost_devinit(FAR struct usbhost_state_s *priv);
/* (Little Endian) Data helpers */ /* (Little Endian) Data helpers */
@@ -160,14 +156,13 @@ static inline int usbhost_tfree(FAR struct usbhost_state_s *priv);
/* struct usbhost_registry_s methods */ /* struct usbhost_registry_s methods */
static struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *drvr, static struct usbhost_class_s *usbhost_create(FAR struct usbhost_hubport_s *hport,
FAR const struct usbhost_id_s *id); FAR const struct usbhost_id_s *id);
/* struct usbhost_class_s methods */ /* struct usbhost_class_s methods */
static int usbhost_connect(FAR struct usbhost_class_s *usbclass, static int usbhost_connect(FAR struct usbhost_class_s *usbclass,
FAR const uint8_t *configdesc, int desclen, FAR const uint8_t *configdesc, int desclen);
uint8_t funcaddr);
static int usbhost_disconnected(FAR struct usbhost_class_s *usbclass); static int usbhost_disconnected(FAR struct usbhost_class_s *usbclass);
/* Driver methods -- depend upon the type of NuttX driver interface exported */ /* Driver methods -- depend upon the type of NuttX driver interface exported */
@@ -352,8 +347,11 @@ static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv,
static void usbhost_destroy(FAR void *arg) static void usbhost_destroy(FAR void *arg)
{ {
FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)arg; FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)arg;
FAR struct usbhost_hport_s *hport
DEBUGASSERT(priv != NULL && priv->usbclass.hport != NULL);
hport = priv->usbclass.hport;
DEBUGASSERT(priv != NULL);
uvdbg("crefs: %d\n", priv->crefs); uvdbg("crefs: %d\n", priv->crefs);
/* Unregister the driver */ /* Unregister the driver */
@@ -370,7 +368,7 @@ static void usbhost_destroy(FAR void *arg)
/* Disconnect the USB host device */ /* Disconnect the USB host device */
DRVR_DISCONNECT(priv->drvr); DRVR_DISCONNECT(hport->drvr);
/* And free the class instance. Hmmm.. this may execute on the worker /* And free the class instance. Hmmm.. this may execute on the worker
* thread and the work structure is part of what is getting freed. That * thread and the work structure is part of what is getting freed. That
@@ -395,8 +393,6 @@ static void usbhost_destroy(FAR void *arg)
* configdesc - A pointer to a uint8_t buffer container the configuration * configdesc - A pointer to a uint8_t buffer container the configuration
* descriptor. * descriptor.
* desclen - The length in bytes of the configuration descriptor. * desclen - The length in bytes of the configuration descriptor.
* funcaddr - The USB address of the function containing the endpoint that
* EP0 controls
* *
* Returned Values: * Returned Values:
* On success, zero (OK) is returned. On a failure, a negated errno value is * On success, zero (OK) is returned. On a failure, a negated errno value is
@@ -408,9 +404,9 @@ static void usbhost_destroy(FAR void *arg)
****************************************************************************/ ****************************************************************************/
static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv, static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
FAR const uint8_t *configdesc, int desclen, FAR const uint8_t *configdesc, int desclen)
uint8_t funcaddr)
{ {
FAR struct usbhost_hubport_s *hport;
FAR struct usb_cfgdesc_s *cfgdesc; FAR struct usb_cfgdesc_s *cfgdesc;
FAR struct usb_desc_s *desc; FAR struct usb_desc_s *desc;
FAR struct usbhost_epdesc_s bindesc; FAR struct usbhost_epdesc_s bindesc;
@@ -419,9 +415,9 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
uint8_t found = 0; uint8_t found = 0;
int ret; int ret;
DEBUGASSERT(priv != NULL && DEBUGASSERT(priv != NULL && priv->usbclass.hport &&
configdesc != NULL && configdesc != NULL && desclen >= sizeof(struct usb_cfgdesc_s));
desclen >= sizeof(struct usb_cfgdesc_s)); hport = priv->usbclass.hport;
/* Verify that we were passed a configuration descriptor */ /* Verify that we were passed a configuration descriptor */
@@ -504,9 +500,9 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
/* Save the bulk OUT endpoint information */ /* Save the bulk OUT endpoint information */
boutdesc.hport = hport;
boutdesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK; boutdesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
boutdesc.in = false; boutdesc.in = false;
boutdesc.funcaddr = funcaddr;
boutdesc.xfrtype = USB_EP_ATTR_XFER_BULK; boutdesc.xfrtype = USB_EP_ATTR_XFER_BULK;
boutdesc.interval = epdesc->interval; boutdesc.interval = epdesc->interval;
boutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize); boutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
@@ -527,13 +523,14 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
return -EINVAL; return -EINVAL;
} }
found |= USBHOST_BINFOUND; found |= USBHOST_BINFOUND;
/* Save the bulk IN endpoint information */ /* Save the bulk IN endpoint information */
bindesc.hport = hport;
bindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK; bindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
bindesc.in = 1; bindesc.in = 1;
bindesc.funcaddr = funcaddr;
bindesc.xfrtype = USB_EP_ATTR_XFER_BULK; bindesc.xfrtype = USB_EP_ATTR_XFER_BULK;
bindesc.interval = epdesc->interval; bindesc.interval = epdesc->interval;
bindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize); bindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
@@ -578,18 +575,18 @@ static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
/* We are good... Allocate the endpoints */ /* We are good... Allocate the endpoints */
ret = DRVR_EPALLOC(priv->drvr, &boutdesc, &priv->epout); ret = DRVR_EPALLOC(hport->drvr, &boutdesc, &priv->epout);
if (ret != OK) if (ret != OK)
{ {
udbg("ERROR: Failed to allocate Bulk OUT endpoint\n"); udbg("ERROR: Failed to allocate Bulk OUT endpoint\n");
return ret; return ret;
} }
ret = DRVR_EPALLOC(priv->drvr, &bindesc, &priv->epin); ret = DRVR_EPALLOC(hport->drvr, &bindesc, &priv->epin);
if (ret != OK) if (ret != OK)
{ {
udbg("ERROR: Failed to allocate Bulk IN endpoint\n"); udbg("ERROR: Failed to allocate Bulk IN endpoint\n");
(void)DRVR_EPFREE(priv->drvr, priv->epout); (void)DRVR_EPFREE(hport->drvr, priv->epout);
return ret; return ret;
} }
@@ -781,8 +778,13 @@ static void usbhost_putle32(uint8_t *dest, uint32_t val)
static inline int usbhost_talloc(FAR struct usbhost_state_s *priv) static inline int usbhost_talloc(FAR struct usbhost_state_s *priv)
{ {
DEBUGASSERT(priv && priv->tbuffer == NULL); FAR struct usbhost_hubport_s *hport;
return DRVR_ALLOC(priv->drvr, &priv->tbuffer, &priv->tbuflen);
DEBUGASSERT(priv != NULL && priv->usbclass.hport != NULL &&
priv->tbuffer == NULL);
hport = priv->usbclass.hport;
return DRVR_ALLOC(hport->drvr, &priv->tbuffer, &priv->tbuflen);
} }
/**************************************************************************** /****************************************************************************
@@ -802,16 +804,19 @@ static inline int usbhost_talloc(FAR struct usbhost_state_s *priv)
static inline int usbhost_tfree(FAR struct usbhost_state_s *priv) static inline int usbhost_tfree(FAR struct usbhost_state_s *priv)
{ {
FAR struct usbhost_hubport_s *hport;
int result = OK; int result = OK;
DEBUGASSERT(priv);
DEBUGASSERT(priv != NULL && priv->usbclass.hport != NULL);
if (priv->tbuffer) if (priv->tbuffer)
{ {
DEBUGASSERT(priv->drvr); hport = priv->usbclass.hport;
result = DRVR_FREE(priv->drvr, priv->tbuffer); result = DRVR_FREE(hport->drvr, priv->tbuffer);
priv->tbuffer = NULL; priv->tbuffer = NULL;
priv->tbuflen = 0; priv->tbuflen = 0;
} }
return result; return result;
} }
@@ -831,9 +836,7 @@ static inline int usbhost_tfree(FAR struct usbhost_state_s *priv)
* USB ports and multiple USB devices simultaneously connected. * USB ports and multiple USB devices simultaneously connected.
* *
* Input Parameters: * Input Parameters:
* drvr - An instance of struct usbhost_driver_s that the class * hport - The hub hat manages the new class instance.
* implementation will "bind" to its state structure and will
* subsequently use to communicate with the USB host driver.
* id - In the case where the device supports multiple base classes, * id - In the case where the device supports multiple base classes,
* subclasses, or protocols, this specifies which to configure for. * subclasses, or protocols, this specifies which to configure for.
* *
@@ -841,12 +844,12 @@ static inline int usbhost_tfree(FAR struct usbhost_state_s *priv)
* On success, this function will return a non-NULL instance of struct * On success, this function will return a non-NULL instance of struct
* usbhost_class_s that can be used by the USB host driver to communicate * usbhost_class_s that can be used by the USB host driver to communicate
* with the USB host class. NULL is returned on failure; this function * with the USB host class. NULL is returned on failure; this function
* will fail only if the drvr input parameter is NULL or if there are * will fail only if the hport input parameter is NULL or if there are
* insufficient resources to create another USB host class instance. * insufficient resources to create another USB host class instance.
* *
****************************************************************************/ ****************************************************************************/
static FAR struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *drvr, static FAR struct usbhost_class_s *usbhost_create(FAR struct usbhost_hubport_s *hport,
FAR const struct usbhost_id_s *id) FAR const struct usbhost_id_s *id)
{ {
FAR struct usbhost_state_s *priv; FAR struct usbhost_state_s *priv;
@@ -866,6 +869,7 @@ static FAR struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *d
{ {
/* Initialize class method function pointers */ /* Initialize class method function pointers */
priv->usbclass.hport = hport;
priv->usbclass.connect = usbhost_connect; priv->usbclass.connect = usbhost_connect;
priv->usbclass.disconnected = usbhost_disconnected; priv->usbclass.disconnected = usbhost_disconnected;
@@ -873,14 +877,10 @@ static FAR struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *d
priv->crefs = 1; priv->crefs = 1;
/* Initialize semphores (this works okay in the interrupt context) */ /* Initialize semaphores (this works okay in the interrupt context) */
sem_init(&priv->exclsem, 0, 1); sem_init(&priv->exclsem, 0, 1);
/* Bind the driver to the storage class instance */
priv->drvr = drvr;
/* Return the instance of the USB class driver */ /* Return the instance of the USB class driver */
return &priv->usbclass; return &priv->usbclass;
@@ -914,8 +914,6 @@ static FAR struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *d
* configdesc - A pointer to a uint8_t buffer container the configuration * configdesc - A pointer to a uint8_t buffer container the configuration
* descriptor. * descriptor.
* desclen - The length in bytes of the configuration descriptor. * desclen - The length in bytes of the configuration descriptor.
* funcaddr - The USB address of the function containing the endpoint
* that EP0 controls
* *
* Returned Values: * Returned Values:
* On success, zero (OK) is returned. On a failure, a negated errno value is * On success, zero (OK) is returned. On a failure, a negated errno value is
@@ -933,8 +931,7 @@ static FAR struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *d
****************************************************************************/ ****************************************************************************/
static int usbhost_connect(FAR struct usbhost_class_s *usbclass, static int usbhost_connect(FAR struct usbhost_class_s *usbclass,
FAR const uint8_t *configdesc, int desclen, FAR const uint8_t *configdesc, int desclen)
uint8_t funcaddr)
{ {
FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)usbclass; FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)usbclass;
int ret; int ret;
@@ -945,7 +942,7 @@ static int usbhost_connect(FAR struct usbhost_class_s *usbclass,
/* Parse the configuration descriptor to get the endpoints */ /* Parse the configuration descriptor to get the endpoints */
ret = usbhost_cfgdesc(priv, configdesc, desclen, funcaddr); ret = usbhost_cfgdesc(priv, configdesc, desclen);
if (ret != OK) if (ret != OK)
{ {
udbg("usbhost_cfgdesc() failed: %d\n", ret); udbg("usbhost_cfgdesc() failed: %d\n", ret);
+3 -2
View File
@@ -81,7 +81,7 @@
* Input Parameters: * Input Parameters:
* reg - The USB host class registry entry previously obtained from a call to * reg - The USB host class registry entry previously obtained from a call to
* usbhost_findclass(). * usbhost_findclass().
* hub - The hub that manages the new class instance. * hport - The hub hat manages the new class instance.
* id - In the case where the device supports multiple base classes, subclasses, or * id - In the case where the device supports multiple base classes, subclasses, or
* protocols, this specifies which to configure for. * protocols, this specifies which to configure for.
* *
@@ -99,7 +99,7 @@
* *
************************************************************************************/ ************************************************************************************/
#define CLASS_CREATE(reg,hub,id) ((reg)->create(hub,id)) #define CLASS_CREATE(reg,hport,id) ((reg)->create(hport,id))
/************************************************************************************ /************************************************************************************
* Name: CLASS_CONNECT * Name: CLASS_CONNECT
@@ -1001,3 +1001,4 @@ int usbhost_enumerate(FAR struct usbhost_hubport_s *hub,
#endif #endif
#endif /* __INCLUDE_NUTTX_USB_USBHOST_H */ #endif /* __INCLUDE_NUTTX_USB_USBHOST_H */