diff --git a/ChangeLog b/ChangeLog
index 319c377030f629b313c9dc47cf469cbaef6397d6..6c2464db44c4ed8bf51ccc1ec6db2e1822ee3b8a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5459,4 +5459,10 @@
 	  by the STM32 SDIO driver.  From CCTSAO (2013-6-26)
 	* drivers/net/encx24j600.c and .h: Use the ENC's SRAM for multiple TX
 	  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).
diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html
index adfc5d36e9e08018c8afc4a1e30b815adce95b26..444d82659c08c59fd49c9993d1a10b3b0a1f61e0 100644
--- a/Documentation/NuttxPortingGuide.html
+++ b/Documentation/NuttxPortingGuide.html
@@ -3434,9 +3434,10 @@ extern void up_ledoff(int led);
     </p>
     <p>
       <b>Examples</b>:
-      <code>arch/arm/src/lpc17xx/lpc17_usbhost.c</code>.
-      <code>arch/arm/src/stm32/stm32_otgfshost.c</code>.
-      <code>arch/arm/src/sama5/sam_ohci.c</code>.
+      <code>arch/arm/src/lpc17xx/lpc17_usbhost.c</code>,
+      <code>arch/arm/src/stm32/stm32_otgfshost.c</code>,
+      <code>arch/arm/src/sama5/sam_ohci.c</code>, and
+      <code>arch/arm/src/sama5/sam_ehci.c</code>.
     </p>
   </li>
   <li>
diff --git a/arch/arm/src/lpc17xx/lpc17_usbhost.c b/arch/arm/src/lpc17xx/lpc17_usbhost.c
index abda1ddf8f4a6cb7d4ae78436a556fce004ef882..08bc9df8bf7cd8ff54a16848dbdbd0e4e47af3a7 100644
--- a/arch/arm/src/lpc17xx/lpc17_usbhost.c
+++ b/arch/arm/src/lpc17xx/lpc17_usbhost.c
@@ -270,13 +270,13 @@ static void lpc17_setinttab(uint32_t value, unsigned int interval, unsigned int
 #endif
 
 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);
 static inline int lpc17_reminted(struct lpc17_usbhost_s *priv,
                                  struct lpc17_ed_s *ed);
 
 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);
 static inline int lpc17_remisoced(struct lpc17_usbhost_s *priv,
                                   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,
                               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,
-                         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_alloc(FAR struct usbhost_driver_s *drvr,
                        FAR uint8_t **buffer, FAR size_t *maxlen);
@@ -339,6 +341,7 @@ static struct lpc17_usbhost_s g_usbhost =
   .drvr             =
     {
       .ep0configure = lpc17_ep0configure,
+      .getdevinfo   = lpc17_getdevinfo,
       .epalloc      = lpc17_epalloc,
       .epfree       = lpc17_epfree,
       .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,
-                                 const FAR struct usbhost_epdesc_s *epdesc, 
+                                 FAR const struct usbhost_epdesc_s *epdesc, 
                                  struct lpc17_ed_s *ed)
 {
 #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,
-                                  const FAR struct usbhost_epdesc_s *epdesc, 
+                                  FAR const struct usbhost_epdesc_s *epdesc, 
                                   struct lpc17_ed_s *ed)
 {
 #ifndef CONFIG_USBHOST_ISOC_DISABLE
@@ -1694,6 +1697,37 @@ static int lpc17_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcadd
   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
  *
@@ -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,
-                         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_ed_s      *ed;
diff --git a/arch/arm/src/sama5/sam_ehci.c b/arch/arm/src/sama5/sam_ehci.c
index 1889f97838c7ed312e72a40b8d00ad72067d9d34..69c13b4cebc190205105103c2f81f1a5ae094a67 100755
--- a/arch/arm/src/sama5/sam_ehci.c
+++ b/arch/arm/src/sama5/sam_ehci.c
@@ -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,
          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,
          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);
@@ -2981,6 +2983,64 @@ static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
   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
  *
@@ -3670,6 +3730,7 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller)
       /* Initialize the device operations */
 
       rhport->drvr.ep0configure   = sam_ep0configure;
+      rhport->drvr.getdevinfo     = sam_getdevinfo;
       rhport->drvr.epalloc        = sam_epalloc;
       rhport->drvr.epfree         = sam_epfree;
       rhport->drvr.alloc          = sam_alloc;
diff --git a/arch/arm/src/sama5/sam_ohci.c b/arch/arm/src/sama5/sam_ohci.c
index ea6f94ddb6086efa597c517e37559b593326ad4b..c2b6ff26d81268895a3a2e6d26eba5cc93a361ba 100644
--- a/arch/arm/src/sama5/sam_ohci.c
+++ b/arch/arm/src/sama5/sam_ohci.c
@@ -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,
                             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,
                        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);
@@ -2261,6 +2263,37 @@ static int sam_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
   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
  *
@@ -3156,6 +3189,7 @@ FAR struct usbhost_connection_s *sam_ohci_initialize(int controller)
 
       rhport->rhpndx              = i;
       rhport->drvr.ep0configure   = sam_ep0configure;
+      rhport->drvr.getdevinfo     = sam_getdevinfo;
       rhport->drvr.epalloc        = sam_epalloc;
       rhport->drvr.epfree         = sam_epfree;
       rhport->drvr.alloc          = sam_alloc;
diff --git a/arch/arm/src/stm32/stm32_otgfshost.c b/arch/arm/src/stm32/stm32_otgfshost.c
index 315782a7e0ef3bc55eef356ba41daad9e6b54716..84903b3f8dd3e661eac7a01181f0374e9310f7bd 100644
--- a/arch/arm/src/stm32/stm32_otgfshost.c
+++ b/arch/arm/src/stm32/stm32_otgfshost.c
@@ -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,
                               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,
                          FAR const FAR struct usbhost_epdesc_s *epdesc,
                          FAR usbhost_ep_t *ep);
@@ -409,6 +411,7 @@ static struct stm32_usbhost_s g_usbhost =
   .drvr             =
     {
       .ep0configure = stm32_ep0configure,
+      .getdevinfo   = stm32_getdevinfo,
       .epalloc      = stm32_epalloc,
       .epfree       = stm32_epfree,
       .alloc        = stm32_alloc,
@@ -3234,6 +3237,37 @@ static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, uint8_t funcadd
   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
  *
diff --git a/drivers/usbhost/usbhost_enumerate.c b/drivers/usbhost/usbhost_enumerate.c
index 7bcf1840ebad299af9651220984980ffefbeed44..44e1439cde96c7f1bd4989f955fa02c2db179e46 100644
--- a/drivers/usbhost/usbhost_enumerate.c
+++ b/drivers/usbhost/usbhost_enumerate.c
@@ -309,6 +309,7 @@ int usbhost_enumerate(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
                       FAR struct usbhost_class_s **class)
 {
   struct usb_ctrlreq_s *ctrlreq;
+  struct usbhost_devinfo_s devinfo;
   struct usbhost_id_s id;
   size_t maxlen;
   unsigned int cfglen;
@@ -336,17 +337,52 @@ int usbhost_enumerate(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
       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;
+    }
+
+  /* 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 8 bytes of the device descriptor */
+  /* Read first 'maxpacketsize' bytes of the device descriptor */
 
   ctrlreq->type = USB_REQ_DIR_IN|USB_REQ_RECIPIENT_DEVICE;
   ctrlreq->req  = USB_REQ_GETDESCRIPTOR;
   usbhost_putle16(ctrlreq->value, (USB_DESC_TYPE_DEVICE << 8));
   usbhost_putle16(ctrlreq->index, 0);
-  usbhost_putle16(ctrlreq->len, 8);
+  usbhost_putle16(ctrlreq->len, maxpacketsize);
 
   ret = DRVR_CTRLIN(drvr, ctrlreq, buffer);
   if (ret != OK)
diff --git a/include/nuttx/usb/usbhost.h b/include/nuttx/usb/usbhost.h
index 1fe4e3dfe2f7ddae089b1d50b4f94049ef246bb0..3965edef546701e8b63d4dfe4b041f7b00a17fb2 100644
--- a/include/nuttx/usb/usbhost.h
+++ b/include/nuttx/usb/usbhost.h
@@ -236,6 +236,35 @@
 
 #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
  *
@@ -578,6 +607,13 @@ struct usbhost_epdesc_s
   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.
  * The actual form is know only internally to the USB host controller
  * (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,
                       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. */
 
   int (*epalloc)(FAR struct usbhost_driver_s *drvr,
-                const FAR struct usbhost_epdesc_s *epdesc, usbhost_ep_t *ep);
-  int (*epfree)(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep);
+                 FAR const struct usbhost_epdesc_s *epdesc,
+                 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
    * be accessed more efficiently.  The following methods provide a mechanism
@@ -655,7 +697,7 @@ struct usbhost_driver_s
    */
 
   int (*ioalloc)(FAR struct usbhost_driver_s *drvr,
-               FAR uint8_t **buffer, size_t buflen);
+                 FAR uint8_t **buffer, size_t buflen);
   int (*iofree)(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer);
 
   /* Process a IN or OUT request on the control endpoint.  These methods