Add a new method to the USB host driver interface: getdevinfo. This method will return information about the currently connected device. At present, it only returns the device speed. The speed is needed by the enumeration logic in order to set a credible initial EP0 max packet size
This commit is contained in:
parent
8130f5bd64
commit
12beaf4b1a
@ -5459,4 +5459,10 @@
|
|||||||
by the STM32 SDIO driver. From CCTSAO (2013-6-26)
|
by the STM32 SDIO driver. From CCTSAO (2013-6-26)
|
||||||
* drivers/net/encx24j600.c and .h: Use the ENC's SRAM for multiple TX
|
* drivers/net/encx24j600.c and .h: Use the ENC's SRAM for multiple TX
|
||||||
packets. From Max Holtzberg (2013-6-26).
|
packets. From Max Holtzberg (2013-6-26).
|
||||||
|
* include/nuttx/usb/usbhost.h, drivers/usbhost/usbhost_enumerate.c, and
|
||||||
|
all USB host drivers: Added a new driver method: getdevinfo. This
|
||||||
|
method is intended to get various information about the connected device,
|
||||||
|
but currently returns only the device speed. The device speed is
|
||||||
|
necessary by usbhost_enumerate in order to set a credible initial EP0
|
||||||
|
max packetsize. High speed needs 64 bytes, low speed needs 8 bytes,
|
||||||
|
and full speed can handle almost any size (2013-8-26).
|
||||||
|
@ -3434,9 +3434,10 @@ extern void up_ledoff(int led);
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<b>Examples</b>:
|
<b>Examples</b>:
|
||||||
<code>arch/arm/src/lpc17xx/lpc17_usbhost.c</code>.
|
<code>arch/arm/src/lpc17xx/lpc17_usbhost.c</code>,
|
||||||
<code>arch/arm/src/stm32/stm32_otgfshost.c</code>.
|
<code>arch/arm/src/stm32/stm32_otgfshost.c</code>,
|
||||||
<code>arch/arm/src/sama5/sam_ohci.c</code>.
|
<code>arch/arm/src/sama5/sam_ohci.c</code>, and
|
||||||
|
<code>arch/arm/src/sama5/sam_ehci.c</code>.
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
@ -270,13 +270,13 @@ static void lpc17_setinttab(uint32_t value, unsigned int interval, unsigned int
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline int lpc17_addinted(struct lpc17_usbhost_s *priv,
|
static inline int lpc17_addinted(struct lpc17_usbhost_s *priv,
|
||||||
const FAR struct usbhost_epdesc_s *epdesc,
|
FAR const struct usbhost_epdesc_s *epdesc,
|
||||||
struct lpc17_ed_s *ed);
|
struct lpc17_ed_s *ed);
|
||||||
static inline int lpc17_reminted(struct lpc17_usbhost_s *priv,
|
static inline int lpc17_reminted(struct lpc17_usbhost_s *priv,
|
||||||
struct lpc17_ed_s *ed);
|
struct lpc17_ed_s *ed);
|
||||||
|
|
||||||
static inline int lpc17_addisoced(struct lpc17_usbhost_s *priv,
|
static inline int lpc17_addisoced(struct lpc17_usbhost_s *priv,
|
||||||
const FAR struct usbhost_epdesc_s *epdesc,
|
FAR const struct usbhost_epdesc_s *epdesc,
|
||||||
struct lpc17_ed_s *ed);
|
struct lpc17_ed_s *ed);
|
||||||
static inline int lpc17_remisoced(struct lpc17_usbhost_s *priv,
|
static inline int lpc17_remisoced(struct lpc17_usbhost_s *priv,
|
||||||
struct lpc17_ed_s *ed);
|
struct lpc17_ed_s *ed);
|
||||||
@ -302,8 +302,10 @@ static int lpc17_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx);
|
|||||||
|
|
||||||
static int lpc17_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
static int lpc17_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
||||||
uint16_t maxpacketsize);
|
uint16_t maxpacketsize);
|
||||||
|
static int lpc17_getdevinfo(FAR struct usbhost_driver_s *drvr,
|
||||||
|
FAR struct usbhost_devinfo_s *devinfo);
|
||||||
static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
|
static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
|
||||||
const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep);
|
FAR const struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep);
|
||||||
static int lpc17_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
|
static int lpc17_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
|
||||||
static int lpc17_alloc(FAR struct usbhost_driver_s *drvr,
|
static int lpc17_alloc(FAR struct usbhost_driver_s *drvr,
|
||||||
FAR uint8_t **buffer, FAR size_t *maxlen);
|
FAR uint8_t **buffer, FAR size_t *maxlen);
|
||||||
@ -339,6 +341,7 @@ static struct lpc17_usbhost_s g_usbhost =
|
|||||||
.drvr =
|
.drvr =
|
||||||
{
|
{
|
||||||
.ep0configure = lpc17_ep0configure,
|
.ep0configure = lpc17_ep0configure,
|
||||||
|
.getdevinfo = lpc17_getdevinfo,
|
||||||
.epalloc = lpc17_epalloc,
|
.epalloc = lpc17_epalloc,
|
||||||
.epfree = lpc17_epfree,
|
.epfree = lpc17_epfree,
|
||||||
.alloc = lpc17_alloc,
|
.alloc = lpc17_alloc,
|
||||||
@ -889,7 +892,7 @@ static void lpc17_setinttab(uint32_t value, unsigned int interval, unsigned int
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
static inline int lpc17_addinted(struct lpc17_usbhost_s *priv,
|
static inline int lpc17_addinted(struct lpc17_usbhost_s *priv,
|
||||||
const FAR struct usbhost_epdesc_s *epdesc,
|
FAR const struct usbhost_epdesc_s *epdesc,
|
||||||
struct lpc17_ed_s *ed)
|
struct lpc17_ed_s *ed)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_USBHOST_INT_DISABLE
|
#ifndef CONFIG_USBHOST_INT_DISABLE
|
||||||
@ -1125,7 +1128,7 @@ static inline int lpc17_reminted(struct lpc17_usbhost_s *priv,
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
static inline int lpc17_addisoced(struct lpc17_usbhost_s *priv,
|
static inline int lpc17_addisoced(struct lpc17_usbhost_s *priv,
|
||||||
const FAR struct usbhost_epdesc_s *epdesc,
|
FAR const struct usbhost_epdesc_s *epdesc,
|
||||||
struct lpc17_ed_s *ed)
|
struct lpc17_ed_s *ed)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_USBHOST_ISOC_DISABLE
|
#ifndef CONFIG_USBHOST_ISOC_DISABLE
|
||||||
@ -1694,6 +1697,37 @@ static int lpc17_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcadd
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: lpc17_getdevinfo
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get information about the connected device.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||||
|
* the class create() method.
|
||||||
|
* devinfo - A pointer to memory provided by the caller in which to return the
|
||||||
|
* device information.
|
||||||
|
*
|
||||||
|
* Returned Values:
|
||||||
|
* On success, zero (OK) is returned. On a failure, a negated errno value is
|
||||||
|
* returned indicating the nature of the failure
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* This function will *not* be called from an interrupt handler.
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
static int lpc17_getdevinfo(FAR struct usbhost_driver_s *drvr,
|
||||||
|
FAR struct usbhost_devinfo_s *devinfo)
|
||||||
|
{
|
||||||
|
struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
|
||||||
|
|
||||||
|
DEBUGASSERT(drvr && devinfo);
|
||||||
|
devinfo->speed = priv->lowspeed ? DEVINFO_SPEED_LOW : DEVINFO_SPEED_FULL;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: lpc17_epalloc
|
* Name: lpc17_epalloc
|
||||||
*
|
*
|
||||||
@ -1717,7 +1751,7 @@ static int lpc17_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcadd
|
|||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
|
static int lpc17_epalloc(FAR struct usbhost_driver_s *drvr,
|
||||||
const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep)
|
FAR const struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep)
|
||||||
{
|
{
|
||||||
struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
|
struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr;
|
||||||
struct lpc17_ed_s *ed;
|
struct lpc17_ed_s *ed;
|
||||||
|
@ -364,6 +364,8 @@ static int sam_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx);
|
|||||||
|
|
||||||
static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
||||||
uint16_t maxpacketsize);
|
uint16_t maxpacketsize);
|
||||||
|
static int sam_getdevinfo(FAR struct usbhost_driver_s *drvr,
|
||||||
|
FAR struct usbhost_devinfo_s *devinfo);
|
||||||
static int sam_epalloc(FAR struct usbhost_driver_s *drvr,
|
static int sam_epalloc(FAR struct usbhost_driver_s *drvr,
|
||||||
const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep);
|
const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep);
|
||||||
static int sam_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
|
static int sam_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
|
||||||
@ -2981,6 +2983,64 @@ static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: sam_getdevinfo
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get information about the connected device.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||||
|
* the class create() method.
|
||||||
|
* devinfo - A pointer to memory provided by the caller in which to return the
|
||||||
|
* device information.
|
||||||
|
*
|
||||||
|
* Returned Values:
|
||||||
|
* On success, zero (OK) is returned. On a failure, a negated errno value is
|
||||||
|
* returned indicating the nature of the failure
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* This function will *not* be called from an interrupt handler.
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
static int sam_getdevinfo(FAR struct usbhost_driver_s *drvr,
|
||||||
|
FAR struct usbhost_devinfo_s *devinfo)
|
||||||
|
{
|
||||||
|
struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr;
|
||||||
|
struct sam_epinfo_s *epinfo;
|
||||||
|
|
||||||
|
DEBUGASSERT(drvr && devinfo);
|
||||||
|
epinfo = &rhport->ep0;
|
||||||
|
|
||||||
|
/* As implemented now, this driver supports only HIGH speed. All
|
||||||
|
* low or full speed devices are handed off to the OHCI driver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
switch (epinfo->speed)
|
||||||
|
{
|
||||||
|
case EHCI_LOW_SPEED:
|
||||||
|
devinfo->speed = DEVINFO_SPEED_LOW;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EHCI_FULL_SPEED:
|
||||||
|
devinfo->speed = DEVINFO_SPEED_FULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case EHCI_HIGH_SPEED:
|
||||||
|
devinfo->speed = DEVINFO_SPEED_HIGH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
devinfo->speed = DEVINFO_SPEED_HIGH;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: sam_epalloc
|
* Name: sam_epalloc
|
||||||
*
|
*
|
||||||
@ -3670,6 +3730,7 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller)
|
|||||||
/* Initialize the device operations */
|
/* Initialize the device operations */
|
||||||
|
|
||||||
rhport->drvr.ep0configure = sam_ep0configure;
|
rhport->drvr.ep0configure = sam_ep0configure;
|
||||||
|
rhport->drvr.getdevinfo = sam_getdevinfo;
|
||||||
rhport->drvr.epalloc = sam_epalloc;
|
rhport->drvr.epalloc = sam_epalloc;
|
||||||
rhport->drvr.epfree = sam_epfree;
|
rhport->drvr.epfree = sam_epfree;
|
||||||
rhport->drvr.alloc = sam_alloc;
|
rhport->drvr.alloc = sam_alloc;
|
||||||
|
@ -383,6 +383,8 @@ static int sam_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx);
|
|||||||
|
|
||||||
static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
||||||
uint16_t maxpacketsize);
|
uint16_t maxpacketsize);
|
||||||
|
static int sam_getdevinfo(FAR struct usbhost_driver_s *drvr,
|
||||||
|
FAR struct usbhost_devinfo_s *devinfo);
|
||||||
static int sam_epalloc(FAR struct usbhost_driver_s *drvr,
|
static int sam_epalloc(FAR struct usbhost_driver_s *drvr,
|
||||||
const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep);
|
const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep);
|
||||||
static int sam_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
|
static int sam_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
|
||||||
@ -2261,6 +2263,37 @@ static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: sam_getdevinfo
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get information about the connected device.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||||
|
* the class create() method.
|
||||||
|
* devinfo - A pointer to memory provided by the caller in which to return the
|
||||||
|
* device information.
|
||||||
|
*
|
||||||
|
* Returned Values:
|
||||||
|
* On success, zero (OK) is returned. On a failure, a negated errno value is
|
||||||
|
* returned indicating the nature of the failure
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* This function will *not* be called from an interrupt handler.
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
static int sam_getdevinfo(FAR struct usbhost_driver_s *drvr,
|
||||||
|
FAR struct usbhost_devinfo_s *devinfo)
|
||||||
|
{
|
||||||
|
struct sam_rhport_s *rhport = (struct sam_rhport_s *)drvr;
|
||||||
|
|
||||||
|
DEBUGASSERT(drvr && devinfo);
|
||||||
|
devinfo->speed = rhport->lowspeed ? DEVINFO_SPEED_LOW : DEVINFO_SPEED_FULL;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: sam_epalloc
|
* Name: sam_epalloc
|
||||||
*
|
*
|
||||||
@ -3156,6 +3189,7 @@ FAR struct usbhost_connection_s *sam_ohci_initialize(int controller)
|
|||||||
|
|
||||||
rhport->rhpndx = i;
|
rhport->rhpndx = i;
|
||||||
rhport->drvr.ep0configure = sam_ep0configure;
|
rhport->drvr.ep0configure = sam_ep0configure;
|
||||||
|
rhport->drvr.getdevinfo = sam_getdevinfo;
|
||||||
rhport->drvr.epalloc = sam_epalloc;
|
rhport->drvr.epalloc = sam_epalloc;
|
||||||
rhport->drvr.epfree = sam_epfree;
|
rhport->drvr.epfree = sam_epfree;
|
||||||
rhport->drvr.alloc = sam_alloc;
|
rhport->drvr.alloc = sam_alloc;
|
||||||
|
@ -364,6 +364,8 @@ static int stm32_enumerate(FAR struct usbhost_connection_s *conn, int rhpndx);
|
|||||||
|
|
||||||
static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
||||||
uint16_t maxpacketsize);
|
uint16_t maxpacketsize);
|
||||||
|
static int stm32_getdevinfo(FAR struct usbhost_driver_s *drvr,
|
||||||
|
FAR struct usbhost_devinfo_s *devinfo);
|
||||||
static int stm32_epalloc(FAR struct usbhost_driver_s *drvr,
|
static int stm32_epalloc(FAR struct usbhost_driver_s *drvr,
|
||||||
FAR const FAR struct usbhost_epdesc_s *epdesc,
|
FAR const FAR struct usbhost_epdesc_s *epdesc,
|
||||||
FAR usbhost_ep_t *ep);
|
FAR usbhost_ep_t *ep);
|
||||||
@ -409,6 +411,7 @@ static struct stm32_usbhost_s g_usbhost =
|
|||||||
.drvr =
|
.drvr =
|
||||||
{
|
{
|
||||||
.ep0configure = stm32_ep0configure,
|
.ep0configure = stm32_ep0configure,
|
||||||
|
.getdevinfo = stm32_getdevinfo,
|
||||||
.epalloc = stm32_epalloc,
|
.epalloc = stm32_epalloc,
|
||||||
.epfree = stm32_epfree,
|
.epfree = stm32_epfree,
|
||||||
.alloc = stm32_alloc,
|
.alloc = stm32_alloc,
|
||||||
@ -3234,6 +3237,37 @@ static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcadd
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: stm32_getdevinfo
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get information about the connected device.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||||
|
* the class create() method.
|
||||||
|
* devinfo - A pointer to memory provided by the caller in which to return the
|
||||||
|
* device information.
|
||||||
|
*
|
||||||
|
* Returned Values:
|
||||||
|
* On success, zero (OK) is returned. On a failure, a negated errno value is
|
||||||
|
* returned indicating the nature of the failure
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* This function will *not* be called from an interrupt handler.
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
static int stm32_getdevinfo(FAR struct usbhost_driver_s *drvr,
|
||||||
|
FAR struct usbhost_devinfo_s *devinfo)
|
||||||
|
{
|
||||||
|
FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr;
|
||||||
|
|
||||||
|
DEBUGASSERT(drvr && devinfo);
|
||||||
|
devinfo->speed = priv->lowspeed ? DEVINFO_SPEED_LOW : DEVINFO_SPEED_FULL;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: stm32_epalloc
|
* Name: stm32_epalloc
|
||||||
*
|
*
|
||||||
|
@ -309,6 +309,7 @@ int usbhost_enumerate(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
|||||||
FAR struct usbhost_class_s **class)
|
FAR struct usbhost_class_s **class)
|
||||||
{
|
{
|
||||||
struct usb_ctrlreq_s *ctrlreq;
|
struct usb_ctrlreq_s *ctrlreq;
|
||||||
|
struct usbhost_devinfo_s devinfo;
|
||||||
struct usbhost_id_s id;
|
struct usbhost_id_s id;
|
||||||
size_t maxlen;
|
size_t maxlen;
|
||||||
unsigned int cfglen;
|
unsigned int cfglen;
|
||||||
@ -336,17 +337,52 @@ int usbhost_enumerate(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set max pkt size = 8 */
|
/* Get information about the connected device */
|
||||||
|
|
||||||
DRVR_EP0CONFIGURE(drvr, 0, 8);
|
ret = DRVR_GETDEVINFO(drvr, &devinfo);
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
udbg("DRVR_GETDEVINFO failed: %d\n", ret);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read first 8 bytes of the device descriptor */
|
/* Pick an appropriate packet size for this device
|
||||||
|
*
|
||||||
|
* USB 2.0, Paragraph 5.5.3 "Control Transfer Packet Size Constraints"
|
||||||
|
*
|
||||||
|
* "An endpoint for control transfers specifies the maximum data
|
||||||
|
* payload size that the endpoint can accept from or transmit to
|
||||||
|
* the bus. The allowable maximum control transfer data payload
|
||||||
|
* sizes for full-speed devices is 8, 16, 32, or 64 bytes; for
|
||||||
|
* high-speed devices, it is 64 bytes and for low-speed devices,
|
||||||
|
* it is 8 bytes. This maximum applies to the data payloads of the
|
||||||
|
* Data packets following a Setup..."
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (devinfo.speed == DEVINFO_SPEED_HIGH)
|
||||||
|
{
|
||||||
|
/* For high-speed, we must use 64 bytes */
|
||||||
|
|
||||||
|
maxpacketsize = 64;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Eight will work for both low- and full-speed */
|
||||||
|
|
||||||
|
maxpacketsize = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the initial maximum packet size */
|
||||||
|
|
||||||
|
DRVR_EP0CONFIGURE(drvr, 0, maxpacketsize);
|
||||||
|
|
||||||
|
/* Read first 'maxpacketsize' bytes of the device descriptor */
|
||||||
|
|
||||||
ctrlreq->type = USB_REQ_DIR_IN|USB_REQ_RECIPIENT_DEVICE;
|
ctrlreq->type = USB_REQ_DIR_IN|USB_REQ_RECIPIENT_DEVICE;
|
||||||
ctrlreq->req = USB_REQ_GETDESCRIPTOR;
|
ctrlreq->req = USB_REQ_GETDESCRIPTOR;
|
||||||
usbhost_putle16(ctrlreq->value, (USB_DESC_TYPE_DEVICE << 8));
|
usbhost_putle16(ctrlreq->value, (USB_DESC_TYPE_DEVICE << 8));
|
||||||
usbhost_putle16(ctrlreq->index, 0);
|
usbhost_putle16(ctrlreq->index, 0);
|
||||||
usbhost_putle16(ctrlreq->len, 8);
|
usbhost_putle16(ctrlreq->len, maxpacketsize);
|
||||||
|
|
||||||
ret = DRVR_CTRLIN(drvr, ctrlreq, buffer);
|
ret = DRVR_CTRLIN(drvr, ctrlreq, buffer);
|
||||||
if (ret != OK)
|
if (ret != OK)
|
||||||
|
@ -236,6 +236,35 @@
|
|||||||
|
|
||||||
#define DRVR_EP0CONFIGURE(drvr,funcaddr,mps) ((drvr)->ep0configure(drvr,funcaddr,mps))
|
#define DRVR_EP0CONFIGURE(drvr,funcaddr,mps) ((drvr)->ep0configure(drvr,funcaddr,mps))
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: DRVR_GETDEVINFO
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get information about the connected device.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* drvr - The USB host driver instance obtained as a parameter from the call to
|
||||||
|
* the class create() method.
|
||||||
|
* devinfo - A pointer to memory provided by the caller in which to return the
|
||||||
|
* device information.
|
||||||
|
*
|
||||||
|
* Returned Values:
|
||||||
|
* On success, zero (OK) is returned. On a failure, a negated errno value is
|
||||||
|
* returned indicating the nature of the failure
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* This function will *not* be called from an interrupt handler.
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
#define DRVR_GETDEVINFO(drvr,devinfo) ((drvr)->getdevinfo(drvr,devinfo))
|
||||||
|
|
||||||
|
/* struct usbhost_devinfo_s speed settings */
|
||||||
|
|
||||||
|
#define DEVINFO_SPEED_LOW 0
|
||||||
|
#define DEVINFO_SPEED_FULL 1
|
||||||
|
#define DEVINFO_SPEED_HIGH 2
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: DRVR_EPALLOC
|
* Name: DRVR_EPALLOC
|
||||||
*
|
*
|
||||||
@ -578,6 +607,13 @@ struct usbhost_epdesc_s
|
|||||||
uint16_t mxpacketsize; /* Max packetsize */
|
uint16_t mxpacketsize; /* Max packetsize */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* This structure provides information about the connected device */
|
||||||
|
|
||||||
|
struct usbhost_devinfo_s
|
||||||
|
{
|
||||||
|
uint8_t speed:2; /* Device speed: 0=low, 1=full, 2=high */
|
||||||
|
};
|
||||||
|
|
||||||
/* This type represents one endpoint configured by the epalloc() method.
|
/* This type represents one endpoint configured by the epalloc() method.
|
||||||
* The actual form is know only internally to the USB host controller
|
* The actual form is know only internally to the USB host controller
|
||||||
* (for example, for an OHCI driver, this would probably be a pointer
|
* (for example, for an OHCI driver, this would probably be a pointer
|
||||||
@ -624,11 +660,17 @@ struct usbhost_driver_s
|
|||||||
int (*ep0configure)(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
int (*ep0configure)(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
|
||||||
uint16_t maxpacketsize);
|
uint16_t maxpacketsize);
|
||||||
|
|
||||||
|
/* Get information about the connected device */
|
||||||
|
|
||||||
|
int (*getdevinfo)(FAR struct usbhost_driver_s *drvr,
|
||||||
|
FAR struct usbhost_devinfo_s *devinfo);
|
||||||
|
|
||||||
/* Allocate and configure an endpoint. */
|
/* Allocate and configure an endpoint. */
|
||||||
|
|
||||||
int (*epalloc)(FAR struct usbhost_driver_s *drvr,
|
int (*epalloc)(FAR struct usbhost_driver_s *drvr,
|
||||||
const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep);
|
FAR const struct usbhost_epdesc_s *epdesc,
|
||||||
int (*epfree)(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
|
FAR usbhost_ep_t *ep);
|
||||||
|
int (*epfree)(FAR struct usbhost_driver_s *drvr, FAR usbhost_ep_t ep);
|
||||||
|
|
||||||
/* Some hardware supports special memory in which transfer descriptors can
|
/* Some hardware supports special memory in which transfer descriptors can
|
||||||
* be accessed more efficiently. The following methods provide a mechanism
|
* be accessed more efficiently. The following methods provide a mechanism
|
||||||
|
Loading…
Reference in New Issue
Block a user