diff --git a/arch/arm/src/lpc17xx/lpc17_usbhost.c b/arch/arm/src/lpc17xx/lpc17_usbhost.c
index c65415ca118b0385f79bd0443627ee2ef4cf2770..026db28152dafdfadc01bf3989f1faf83bbb447c 100755
--- a/arch/arm/src/lpc17xx/lpc17_usbhost.c
+++ b/arch/arm/src/lpc17xx/lpc17_usbhost.c
@@ -188,21 +188,45 @@ static int lpc17_usbinterrupt(int irq, FAR void *context);
 
 /* USB host controller operations **********************************************/
 
+static int usbhost_enumerate(FAR struct usbhost_driver_s *drvr);
+static int usbhost_alloc(FAR struct usbhost_driver_s *drvr,
+                         FAR uint8_t **buffer, FAR size_t *maxlen);
+static int usbhost_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer);
+static int usbhost_control(FAR struct usbhost_driver_s *drvr,
+                           const struct usb_ctrlreq_s *req, FAR uint8_t *buffer);
+static int usbhost_transfer(FAR struct usbhost_driver_s *drvr,
+                            FAR struct usbhost_epdesc_s *ed,
+                            FAR uint8_t *buffer, size_t buflen);
+static void usbhost_disconnect(FAR struct usbhost_driver_s *drvr);
+  
 /* Initializaion ***************************************************************/
 
 static void usbhost_tdinit(volatile struct usbhost_hctd_s *td);
-static void usbhost_edinit(volatile struct usbhost_hced_s *);
+static void usbhost_edinit(volatile struct usbhost_hced_s *ed);
 static void usbhost_hccainit(volatile struct usbhost_hcca_s *hcca);
 
 /*******************************************************************************
  * Private Data
  *******************************************************************************/
 
-/* Since there is only a single USB interface, all status information can be
- * be simply retained in a single global instance.
+/* In this driver implementation, support is provided for only a single a single
+ * USB device.  All status information can be simply retained in a single global
+ * instance.
  */
 
-static struct lpc17_usbhost_s g_usbhost;
+static struct lpc17_usbhost_s g_usbhost =
+{
+  .usbhost        =
+    {
+      .enumerate  = usbhost_enumerate,
+      .alloc      = usbhost_alloc,
+      .free       = usbhost_free,
+      .control    = usbhost_control,
+      .transfer   = usbhost_transfer,
+      .disconnect = usbhost_disconnect,
+    },
+  .class          = NULL,
+};
 
 /*******************************************************************************
  * Public Data
@@ -355,9 +379,225 @@ static int lpc17_usbinterrupt(int irq, FAR void *context)
 }
 
 /*******************************************************************************
- * USB Host Device Operations
+ * USB Host Controller Operations
+ *******************************************************************************/
+
+/************************************************************************************
+ * Name: usbhost_enumerate
+ *
+ * Description:
+ *   Enumerate the connected device.  This function will enqueue the
+ *   enumeration process.  As part of this enumeration process, the driver
+ *   will (1) get the device's configuration descriptor, (2) extract the class
+ *   ID info from the configuration descriptor, (3) call usbhost_findclass()
+ *   to find the class that supports this device, (4) call the create()
+ *   method on the struct usbhost_registry_s interface to get a class
+ *   instance, and finally (5) call the configdesc() method of the struct
+ *   usbhost_class_s interface.  After that, the class is in charge of the
+ *   sequence of operations.
+ *
+ * Input Parameters:
+ *   drvr - The USB host driver instance obtained as a parameter from the call to
+ *      the class create() method.
+ *
+ * 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 usbhost_enumerate(FAR struct usbhost_driver_s *drvr)
+{
+# warning "Not Implemented"
+  return -ENOSYS;
+}
+
+/************************************************************************************
+ * Name: usbhost_alloc
+ *
+ * Description:
+ *   Some hardware supports special memory in which transfer descriptors can
+ *   be accessed more efficiently.  This method provides a mechanism to allocate
+ *   the transfer descriptor memory.  If the underlying hardware does not support
+ *   such "special" memory, this functions may simply map to malloc.
+ *
+ * Input Parameters:
+ *   drvr - The USB host driver instance obtained as a parameter from the call to
+ *      the class create() method.
+ *   buffer - The address of a memory location provided by the caller in which to
+ *     return the allocated buffer memory address.
+ *   maxlen - The address of a memory location provided by the caller in which to
+ *     return the maximum size of the allocated buffer memory.
+ *
+ * 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 usbhost_alloc(FAR struct usbhost_driver_s *drvr,
+                         FAR uint8_t **buffer, FAR size_t *maxlen)
+{
+# warning "Not Implemented"
+  return -ENOSYS;
+}
+
+/************************************************************************************
+ * Name: usbhost_free
+ *
+ * Description:
+ *   Some hardware supports special memory in which transfer descriptors can
+ *   be accessed more efficiently.  This method provides a mechanism to free that
+ *   transfer descriptor memory.  If the underlying hardware does not support
+ *   such "special" memory, this functions may simply map to free().
+ *
+ * Input Parameters:
+ *   drvr - The USB host driver instance obtained as a parameter from the call to
+ *      the class create() method.
+ *   buffer - The address of the allocated buffer memory to be freed.
+ *
+ * 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 usbhost_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer)
+{
+# warning "Not Implemented"
+  return -ENOSYS;
+}
+
+/************************************************************************************
+ * Name: usbhost_control
+ *
+ * Description:
+ *   Enqueue a request on the control endpoint.  This method will enqueue
+ *   the request and return immediately.  The transfer will be performed
+ *   asynchronously.  When the transfer completes, the USB host driver will
+ *   call the complete() method of the struct usbhost_class_s interface.
+ *   Only one transfer may be queued; Neither this method nor the transfer()
+ *   method can be called again until the class complete() method has been called.
+ *
+ * Input Parameters:
+ *   drvr - The USB host driver instance obtained as a parameter from the call to
+ *      the class create() method.
+ *   req - Describes the request to be sent.  This data will be copied from the
+ *      user provided memory.  Therefore, the req buffer may be declared on the
+ *      stack.
+ *   buffer - A buffer used for sending the request and for returning any
+ *     responses.  This buffer must be large enough to hold the length value
+ *     in the request description. buffer must have been allocated using DRVR_ALLOC
+ *
+ * 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 usbhost_control(FAR struct usbhost_driver_s *drvr,
+                           const struct usb_ctrlreq_s *req, FAR uint8_t *buffer)
+{
+# warning "Not Implemented"
+  return -ENOSYS;
+}
+
+/************************************************************************************
+ * Name: usbhost_transfer
+ *
+ * Description:
+ *   Enqueue a request to handle a transfer descriptor.  This method will
+ *   enqueue the transfer request and return immediately.  The transfer will
+ *   be performed asynchronously.  When the transfer completes, the USB host
+ *   driver will call the complete() method of the struct usbhost_class_s
+ *   interface.  Only one transfer may be queued; Neither this method nor the
+ *   control method can be called again until the class complete() method has
+ *   been called.
+ *
+ * Input Parameters:
+ *   drvr - The USB host driver instance obtained as a parameter from the call to
+ *      the class create() method.
+ *   ed - The IN or OUT endpoint descriptor for the device endpoint on which to
+ *      perform the transfer.
+ *   buffer - A buffer containing the data to be sent (OUT endpoint) or received
+ *     (IN endpoint).  buffer must have been allocated using DRVR_ALLOC
+ *   buflen - The length of the data to be sent or received.
+ *
+ * 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 usbhost_transfer(FAR struct usbhost_driver_s *drvr,
+                            FAR struct usbhost_epdesc_s *ed,
+                            FAR uint8_t *buffer, size_t buflen)
+{
+# warning "Not Implemented"
+  return -ENOSYS;
+}
+
+/************************************************************************************
+ * Name: usbhost_disconnect
+ *
+ * Description:
+ *   Called by the class when an error occurs and driver has been disconnected.
+ *   The USB host driver should discard the handle to the class instance (it is
+ *   stale) and not attempt any further interaction with the class driver instance
+ *   (until a new instance is received from the create() method).  The driver
+ *   should not called the class' disconnected() method.
+ *
+ * Input Parameters:
+ *   drvr - The USB host driver instance obtained as a parameter from the call to
+ *      the class create() method.
+ *
+ * Returned Values:
+ *   None
+ *
+ * Assumptions:
+ *   This function will *not* be called from an interrupt handler.
+ *
+ ************************************************************************************/
+
+static void usbhost_disconnect(FAR struct usbhost_driver_s *drvr)
+{
+# warning "Not Implemented"
+}
+  
+/*******************************************************************************
+ * Initialization
  *******************************************************************************/
 
+static void usbhost_tdinit(volatile struct usbhost_hctd_s *td)
+{
+# warning "Not Implemented"
+}
+
+static void usbhost_edinit(volatile struct usbhost_hced_s *ed)
+{
+# warning "Not Implemented"
+}
+
+static void usbhost_hccainit(volatile struct usbhost_hcca_s *hcca)
+{
+# warning "Not Implemented"
+}
+
 /*******************************************************************************
  * Public Functions
  *******************************************************************************/
diff --git a/drivers/usbhost/usbhost_storage.c b/drivers/usbhost/usbhost_storage.c
index 5df0f9c7a1b3b61ec1a8bfe96b8d546d1b6bf1b2..e161b24c8c02b3c6a0df9c31c851987e82a07e48 100644
--- a/drivers/usbhost/usbhost_storage.c
+++ b/drivers/usbhost/usbhost_storage.c
@@ -103,21 +103,6 @@
  * Private Types
  ****************************************************************************/
 
-/* This enumeration provides the state of the storage class */
-
-enum USBSTRG_STATE_e
-{
-  USBSTRG_STATE_CREATED = 0,    /* State has been created, waiting for config descriptor */
-  USBSTRG_STATE_CONFIGURED,     /* Received config descriptor */
-  USBSTRG_STATE_MAXLUN,         /* Requested maximum logical unit number */
-  USBSTRG_STATE_TESTUNITREADY,  /* Waiting for test unit ready to complete */
-  USBSTRG_STATE_SENSE,          /* Get sense information */
-  USBSTRG_STATE_CAPACITY,       /* Read the capacity of the volume */
-  USBSTRG_STATE_READY,          /* Registered the block driver, idle, waiting for operation */
-  USBSTRG_STATE_BUSY,           /* Transfer in progress */
-  USBSTRG_STATE_FAIL            /* A fatal error occurred */
-};
-
 /* This structure contains the internal, private state of the USB host mass
  * storage class.
  */
@@ -134,8 +119,6 @@ struct usbhost_state_s
 
   /* The remainder of the fields are provide o the mass storage class */
   
-  uint8_t                 state;      /* See enum USBSTRG_STATE_e */
-  uint8_t                 retries;    /* Retry counter */
   char                    sdchar;     /* Character identifying the /dev/sd[n] device */
   int16_t                 crefs;      /* Reference count on the driver instance */
   uint16_t                blocksize;  /* Block size of USB mass storage device */
@@ -155,7 +138,7 @@ struct usbhost_state_s
 
 /* Semaphores */
 
-static void    usbhost_takesem(sem_t *sem);
+static void usbhost_takesem(sem_t *sem);
 #define usbhost_givesem(s) sem_post(s);
 
 /* Memory allocation services */
@@ -171,7 +154,7 @@ static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *dev
 
 /* CBW helpers */
 
-static inline void usbhost_modesensecbw(FAR struct usbstrg_cbw_s *cbw);
+static inline void usbhost_requestsensecbw(FAR struct usbstrg_cbw_s *cbw);
 static inline void usbhost_testunitreadycbw(FAR struct usbstrg_cbw_s *cbw);
 static inline void usbhost_readcapacitycbw(FAR struct usbstrg_cbw_s *cbw);
 static inline void usbhost_inquirycbw (FAR struct usbstrg_cbw_s *cbw);
@@ -183,7 +166,11 @@ static inline void usbhost_writecbw(size_t startsector, uint16_t blocksize,
                                     FAR struct usbstrg_cbw_s *cbw);
 /* Command helpers */
 
-static int usbhost_testunitready(FAR struct usbhost_state_s *priv);
+static inline int usbhost_maxlunreq(FAR struct usbhost_state_s *priv);
+static inline int usbhost_testunitready(FAR struct usbhost_state_s *priv);
+static inline int usbhost_requestsense(FAR struct usbhost_state_s *priv);
+static inline int usbhost_readcapacity(FAR struct usbhost_state_s *priv);
+static inline int usbhost_inquiry(FAR struct usbhost_state_s *priv);
 
 /* Worker thread actions */
 
@@ -194,8 +181,10 @@ static void usbhost_work(FAR struct usbhost_state_s *priv, worker_t worker);
 /* (Little Endian) Data helpers */
 
 static inline uint16_t usbhost_getle16(const uint8_t *val);
+static inline uint16_t usbhost_getbe16(const uint8_t *val);
 static inline void usbhost_putle16(uint8_t *dest, uint16_t val);
 static inline void usbhost_putbe16(uint8_t *dest, uint16_t val);
+static inline uint32_t usbhost_getbe32(const uint8_t *val);
 static void usbhost_putle32(uint8_t *dest, uint32_t val);
 static void usbhost_putbe32(uint8_t *dest, uint32_t val);
 
@@ -214,10 +203,8 @@ static struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *drvr,
 
 static int usbhost_configdesc(FAR struct usbhost_class_s *class,
                               FAR const uint8_t *configdesc, int desclen);
-static int usbhost_complete1(FAR struct usbhost_class_s *class,
-                             FAR const uint8_t *response, int resplen);
-static int usbhost_complete2(FAR struct usbhost_class_s *class,
-                             FAR const uint8_t *response, int resplen);
+static int usbhost_complete(FAR struct usbhost_class_s *class,
+                            FAR const uint8_t *response, int resplen);
 static int usbhost_disconnected(FAR struct usbhost_class_s *class);
 
 /* struct block_operations methods */
@@ -477,7 +464,7 @@ static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *dev
  *
  ****************************************************************************/
 
-static inline void usbhost_modesensecbw(FAR struct usbstrg_cbw_s *cbw)
+static inline void usbhost_requestsensecbw(FAR struct usbstrg_cbw_s *cbw)
 {
   FAR struct scsicmd_requestsense_s *reqsense;
 
@@ -591,7 +578,36 @@ usbhost_writecbw(size_t startsector, uint16_t blocksize,
  *
  ****************************************************************************/
 
-static int usbhost_testunitready(FAR struct usbhost_state_s *priv)
+static inline int usbhost_maxlunreq(FAR struct usbhost_state_s *priv)
+{
+  struct usb_ctrlreq_s req;
+  int result;
+ 
+  /* Make sure that we have a buffer allocated */
+
+  result = usbhost_tdalloc(priv);
+  if (result == OK)
+    {
+      /* Request maximum logical unit number */
+
+      uvdbg("Request maximum logical unit number\n");
+      memset(&req, 0, sizeof(struct usb_ctrlreq_s));
+      req.type    = USB_DIR_IN|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE;
+      req.req     = USBSTRG_REQ_GETMAXLUN;
+      usbhost_putle16(req.len, 1);
+
+      result      = DRVR_CONTROL(priv->drvr, &req, priv->tdbuffer);
+      if (result == OK)
+        {
+          /* Wait for the control operation to complete */
+
+          usbhost_takesem(&priv->waitsem);
+        }
+    }
+  return result;
+}
+
+static inline int usbhost_testunitready(FAR struct usbhost_state_s *priv)
 {
   FAR struct usbstrg_cbw_s *cbw;
   int result = -ENOMEM;
@@ -601,17 +617,176 @@ static int usbhost_testunitready(FAR struct usbhost_state_s *priv)
   cbw = usbhost_cbwalloc(priv);
   if (cbw)
     {
-      /* Construc and send the CBW */
+      /* Construct and send the CBW */
  
       usbhost_testunitreadycbw(cbw);
       result = DRVR_TRANSFER(priv->drvr, &priv->bulkout,
                             (uint8_t*)cbw, USBSTRG_CBW_SIZEOF);
       if (result == OK)
         {
+          /* Wait for the CBW OUT operation to complete */
+
+          usbhost_takesem(&priv->waitsem);
+
           /* Receive the CSW */
 
           result = DRVR_TRANSFER(priv->drvr, &priv->bulkin,
                                  priv->tdbuffer, USBSTRG_CSW_SIZEOF);
+
+          /* Wait for the CSW IN operation to complete */
+
+          usbhost_takesem(&priv->waitsem); 
+        }
+    }
+  return result;
+}
+
+static inline int usbhost_requestsense(FAR struct usbhost_state_s *priv)
+{
+  FAR struct usbstrg_cbw_s *cbw;
+  int result = -ENOMEM;
+
+  /* Initialize a CBW (allocating it if necessary) */
+ 
+  cbw = usbhost_cbwalloc(priv);
+  if (cbw)
+    {
+      /* Construct and send the CBW */
+ 
+      usbhost_requestsensecbw(cbw);
+      result = DRVR_TRANSFER(priv->drvr, &priv->bulkout,
+                            (uint8_t*)cbw, USBSTRG_CBW_SIZEOF);
+      if (result == OK)
+        {
+          /* Wait for the CBW OUT operation to complete */
+
+          usbhost_takesem(&priv->waitsem);
+
+          /* Receive the sense data response */
+
+          result = DRVR_TRANSFER(priv->drvr, &priv->bulkin,
+                                 priv->tdbuffer, SCSIRESP_FIXEDSENSEDATA_SIZEOF);
+          if (result == OK)
+            {
+              /* Wait for the CBW IN response operation to complete */
+
+              usbhost_takesem(&priv->waitsem);
+
+              /* Receive the CSW */
+
+              result = DRVR_TRANSFER(priv->drvr, &priv->bulkin,
+                                     priv->tdbuffer, USBSTRG_CSW_SIZEOF);
+              if (result == OK)
+                {
+                  /* Wait for the CSW IN operation to complete */
+
+                  usbhost_takesem(&priv->waitsem); 
+                }
+            }
+        }
+    }
+  return result;
+}
+
+static inline int usbhost_readcapacity(FAR struct usbhost_state_s *priv)
+{
+  FAR struct usbstrg_cbw_s *cbw;
+  FAR struct scsiresp_readcapacity10_s *resp;
+  int result = -ENOMEM;
+
+  /* Initialize a CBW (allocating it if necessary) */
+ 
+  cbw = usbhost_cbwalloc(priv);
+  if (cbw)
+    {
+      /* Construct and send the CBW */
+ 
+      usbhost_readcapacitycbw(cbw);
+      result = DRVR_TRANSFER(priv->drvr, &priv->bulkout,
+                             (uint8_t*)cbw, USBSTRG_CBW_SIZEOF);
+      if (result == OK)
+        {
+          /* Wait for the CBW OUT operation to complete */
+
+          usbhost_takesem(&priv->waitsem);
+
+          /* Receive the read capacity CBW IN response */
+
+          result = DRVR_TRANSFER(priv->drvr, &priv->bulkin,
+                                 priv->tdbuffer, SCSIRESP_READCAPACITY10_SIZEOF);
+          if (result == OK)
+            {
+              /* Wait for the CBW IN response operation to complete */
+
+              usbhost_takesem(&priv->waitsem);
+
+              /* Save the capacity information */
+
+              resp = (FAR struct scsiresp_readcapacity10_s *)priv->tdbuffer;
+              priv->nblocks = usbhost_getbe32(resp->lba);
+              priv->blocksize = usbhost_getbe32(resp->blklen);
+
+              /* Receive the CSW */
+
+              result = DRVR_TRANSFER(priv->drvr, &priv->bulkin,
+                                     priv->tdbuffer, USBSTRG_CSW_SIZEOF);
+              if (result == OK)
+                {
+                  /* Wait for the CSW IN operation to complete */
+
+                  usbhost_takesem(&priv->waitsem); 
+                }
+            }
+        }
+    }
+  return result;
+}
+
+static inline int usbhost_inquiry(FAR struct usbhost_state_s *priv)
+{
+  FAR struct usbstrg_cbw_s *cbw;
+  FAR struct scsiresp_inquiry_s *resp;
+  int result = -ENOMEM;
+
+  /* Initialize a CBW (allocating it if necessary) */
+ 
+  cbw = usbhost_cbwalloc(priv);
+  if (cbw)
+    {
+      /* Construct and send the CBW */
+ 
+      usbhost_inquirycbw(cbw);
+      result = DRVR_TRANSFER(priv->drvr, &priv->bulkout,
+                             (uint8_t*)cbw, USBSTRG_CBW_SIZEOF);
+      if (result == OK)
+        {
+          /* Wait for the CBW OUT operation to complete */
+
+          usbhost_takesem(&priv->waitsem);
+
+          /* Receive the CBW IN response */
+
+          result = DRVR_TRANSFER(priv->drvr, &priv->bulkin,
+                                 priv->tdbuffer, SCSIRESP_INQUIRY_SIZEOF);
+          if (result == OK)
+            {
+              /* Wait for the CBW IN response operation to complete */
+
+              usbhost_takesem(&priv->waitsem);
+
+              /* TODO: If USB debug is enabled, dump the response data here */
+
+              resp = (FAR struct scsiresp_inquiry_s *)priv->tdbuffer;
+
+              /* Receive the CSW */
+
+              result = DRVR_TRANSFER(priv->drvr, &priv->bulkin,
+                                     priv->tdbuffer, USBSTRG_CSW_SIZEOF);
+
+              /* Wait for the CSW IN operation to complete */
+
+              usbhost_takesem(&priv->waitsem); 
+            }
         }
     }
   return result;
@@ -689,141 +864,116 @@ static void usbhost_destroy(FAR void *arg)
 static void usbhost_statemachine(FAR void *arg)
 {
   FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)arg;
+  FAR struct usbstrg_csw_s *csw;
+  unsigned int retries;
   int result = OK;
 
   DEBUGASSERT(priv != NULL);
 
-  usbhost_takesem(&priv->exclsem);
-  switch (priv->state)
-    {
-    case USBSTRG_STATE_CONFIGURED:  /* Received config descriptor */
-      {
-        struct usb_ctrlreq_s req;
-        uvdbg("USBSTRG_STATE_CONFIGURED\n");
+  /* Request the maximum logical unit number */
 
-        /* Make sure that we have a buffer allocated */
+  uvdbg("Get max LUN\n");
+  result = usbhost_maxlunreq(priv);
 
-        result = usbhost_tdalloc(priv);
-        if (result == OK)
-          {
-            /* Request maximum logical unit number */
+  /* Wait for the unit to be ready */
 
-            memset(&req, 0, sizeof(struct usb_ctrlreq_s));
-            req.type    = USB_DIR_IN|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE;
-            req.req     = USBSTRG_REQ_GETMAXLUN;
-            usbhost_putle16(req.len, 1);
+  for (retries = 0; retries < USBHOST_MAX_RETRIES && result == OK; retries++)
+    {
+      uvdbg("Test unit ready, retries=%d\n", retries);
 
-            result      = DRVR_CONTROL(priv->drvr, &req, priv->tdbuffer);
-            priv->state = USBSTRG_STATE_MAXLUN;
-          }
-      }
-      break;
+      /* Send TESTUNITREADY to see the unit is ready */
+      
+      result = usbhost_testunitready(priv);
+      if (result == OK)
+        {
+          /* Is the unit is ready */
 
-    case USBSTRG_STATE_MAXLUN:      /* Requested maximum logical unit number */
-      {
-        uvdbg("USBSTRG_STATE_MAXLUN\n");
+          csw = (FAR struct usbstrg_csw_s *)priv->tdbuffer;
+          if (csw->status == 0)
+            {
+              /* Yes... break out of the loop */
 
-        /* Check if the unit is ready */
+              break;
+            }
 
-        result = usbhost_testunitready(priv);
-        priv->retries = 0;
-#warning "Missing Logic"
-        priv->state = USBSTRG_STATE_MAXLUN;
-      }
-      break;
+          /* No.. Request mode sense information (ignoring return status) */
 
-    case USBSTRG_STATE_SENSE: /* MODESENSE compleed */
-      {
-        uvdbg("USBSTRG_STATE_SENSE\n");
+          uvdbg("Request sense\n");
+          result = usbhost_requestsense(priv);
+        }
+    }
 
-        /* Check if the unit is ready again */
+  /* Did the unit become ready?  Did an error occur? Or did we time out? */
 
-        result = usbhost_testunitready(priv);
-        priv->state = USBSTRG_STATE_TESTUNITREADY;
-        priv->retries++;
-      }
-      break;
+  if (retries >= USBHOST_MAX_RETRIES)
+    {
+      udbg("ERROR: Timeout!\n");
+      result = -ETIMEDOUT;
+    }
 
-    case USBSTRG_STATE_TESTUNITREADY: /* TESTUNITREADY completed */
-      {
-        uvdbg("USBSTRG_STATE_TESTUNITREADY\n");
+  if (result == OK)
+    {
+      /* Get the capacity of the volume */
 
-        /* Check the result */
+      uvdbg("Read capacity\n");
+      result = usbhost_readcapacity(priv);
+      if (result == OK)
+        {
+          /* Check the CSW for errors */
+
+          csw = (FAR struct usbstrg_csw_s *)priv->tdbuffer;
+          if (csw->status != 0)
+            {
+              udbg("CSW status error: %d\n", csw->status);
+              result = -ENODEV;
+            }
+        }
+    }
 
-        if (priv->tdbuffer[12] != 0)
-          {
-            /* Not ready... retry? */
+  /* Get information about the volume */
 
-            if (priv->retries < USBHOST_MAX_RETRIES)
-              {
-                /* Request mode sense information */
-#warning "Missing Logic"
-                priv->state = USBSTRG_STATE_SENSE;
+  if (result == OK)
+    {
+      /* Inquiry */
 
-              }
-            else
-              {
-                result = -ETIMEDOUT;
-              }
-          }
-        else
-          {
-            /* Request the capaciy of the volume */
+      uvdbg("Inquiry\n");
+      result = usbhost_inquiry(priv);
+      if (result == OK)
+        {
+          /* Check the CSW for errors */
+
+          csw = (FAR struct usbstrg_csw_s *)priv->tdbuffer;
+          if (csw->status != 0)
+            {
+              udbg("CSW status error: %d\n", csw->status);
+              result = -ENODEV;
+            }
+        }
+    }
 
-#warning "Missing Logic"
-            priv->state = USBSTRG_STATE_CAPACITY;
-          }
-      }
-      break;
+  /* Register the block driver */
 
-    case USBSTRG_STATE_CAPACITY:    /* Read the capacity of the volume */
-      {
-        char devname[DEV_NAMELEN];
-        uvdbg("USBSTRG_STATE_CAPACITY\n");
+  if (result == OK)
+    {
+      char devname[DEV_NAMELEN];
 
-        /* Process capacity information */
-#warning "Missing Logic"
+      uvdbg("Register block driver\n");
+      usbhost_mkdevname(priv, devname);
+      result = register_blockdriver(devname, &g_bops, 0, priv);
+    }
 
-        /* Register the block driver */
+  /* Check if we successfully initialized */
 
-        usbhost_mkdevname(priv, devname);
-        result = register_blockdriver(devname, &g_bops, 0, priv);
-        if (result != OK)
-          {
-            udbg("ERROR! Failed to register block driver: %d\n", result);
-            priv->state          = USBSTRG_STATE_FAIL;
-          }
-        else
-          {
-            /* Set up for normal operation as a block device driver */
+  if (result == OK)
+    {
+      /* Set up for normal operation as a block device driver */
 
-            uvdbg("Successfully initialized\n");
-            priv->class.complete = usbhost_complete2;
-            priv->state          = USBSTRG_STATE_READY;
-          }
-      }
-      break;
-
-    /* This function should not be executed in the following states */
-
-    case USBSTRG_STATE_READY:       /* Registered the block driver, idle, waiting for operation */
-    case USBSTRG_STATE_BUSY:        /* Block driver I/O transfer in progress */
-    case USBSTRG_STATE_CREATED:     /* State has been created, waiting for config descriptor */
-    case USBSTRG_STATE_FAIL:        /* A fatal error occurred */
-    default:
-      {
-        udbg("ERROR! Completion in unexpected stated: %d\n", priv->state);
-        result = -EINVAL;
-      }
-      break;
+      uvdbg("Successfully initialized\n");
     }
-  usbhost_givesem(&priv->exclsem);
-
-  /* Abort everything on an error */
-
-  if (result != OK)
+  else
     {
       udbg("ERROR! Aborting: %d\n", result);
+      DRVR_DISCONNECT(priv->drvr);
       usbhost_destroy(priv);
     }
 }
@@ -884,6 +1034,25 @@ static inline uint16_t usbhost_getle16(const uint8_t *val)
   return (uint16_t)val[1] << 8 | (uint16_t)val[0];
 }
 
+/****************************************************************************
+ * Name: usbhost_getbe16
+ *
+ * Description:
+ *   Get a (possibly unaligned) 16-bit big endian value.
+ *
+ * Input Parameters:
+ *   val - A pointer to the first byte of the big endian value.
+ *
+ * Returned Values:
+ *   A uin16_t representing the whole 16-bit integer value
+ *
+ ****************************************************************************/
+
+static inline uint16_t usbhost_getbe16(const uint8_t *val)
+{
+  return (uint16_t)val[0] << 8 | (uint16_t)val[1];
+}
+
 /****************************************************************************
  * Name: usbhost_putle16
  *
@@ -926,6 +1095,29 @@ static void usbhost_putbe16(uint8_t *dest, uint16_t val)
   dest[1] = val & 0xff;
 }
 
+/****************************************************************************
+ * Name: usbhost_getbe32
+ *
+ * Description:
+ *   Put a (possibly unaligned) 32-bit big endian value.
+ *
+ * Input Parameters:
+ *   dest - A pointer to the first byte to save the big endian value.
+ *   val - The 32-bit value to be saved.
+ *
+ * Returned Values:
+ *   None
+ *
+ ****************************************************************************/
+
+static inline uint32_t usbhost_getbe32(const uint8_t *val)
+{
+  /* Big endian means MS halfword first in byte stream */
+
+  return (uint32_t)usbhost_getbe16(val) << 16 | (uint32_t)usbhost_getbe16(&val[2]);
+}
+
+
 /****************************************************************************
  * Name: usbhost_putle32
  *
@@ -943,7 +1135,7 @@ static void usbhost_putbe16(uint8_t *dest, uint16_t val)
 
 static void usbhost_putle32(uint8_t *dest, uint32_t val)
 {
-  /* Little endian means LS halfwrd first in byte stream */
+  /* Little endian means LS halfword first in byte stream */
 
   usbhost_putle16(dest, (uint16_t)(val & 0xffff));
   usbhost_putle16(dest+2, (uint16_t)(val >> 16));
@@ -966,7 +1158,7 @@ static void usbhost_putle32(uint8_t *dest, uint32_t val)
 
 static void usbhost_putbe32(uint8_t *dest, uint32_t val)
 {
-  /* Big endian means MS halfwrd first in byte stream */
+  /* Big endian means MS halfword first in byte stream */
 
   usbhost_putbe16(dest, (uint16_t)(val >> 16));
   usbhost_putbe16(dest+2, (uint16_t)(val & 0xffff));
@@ -1116,7 +1308,7 @@ static FAR struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *d
          /* Initialize class method function pointers */
 
           priv->class.configdesc   = usbhost_configdesc;
-          priv->class.complete     = usbhost_complete1;
+          priv->class.complete     = usbhost_complete;
           priv->class.disconnected = usbhost_disconnected;
 
           /* The initial reference count is 1... One reference is held by the driver */
@@ -1183,8 +1375,7 @@ static int usbhost_configdesc(FAR struct usbhost_class_s *class,
 
   DEBUGASSERT(priv != NULL && 
               configdesc != NULL &&
-              desclen >= sizeof(struct usb_cfgdesc_s) &&
-              priv->state == USBSTRG_STATE_CREATED);
+              desclen >= sizeof(struct usb_cfgdesc_s));
   
   /* Verify that we were passed a configuration descriptor */
 
@@ -1314,16 +1505,15 @@ static int usbhost_configdesc(FAR struct usbhost_class_s *class,
 
   /* Now configure the LUNs and register the block driver(s) */
 
-  priv->state = USBSTRG_STATE_CONFIGURED;
   usbhost_work(priv, usbhost_statemachine);
   return OK;
 }
 
 /****************************************************************************
- * Name: usbhost_complete1 & 2
+ * Name: usbhost_complete
  *
  * Description:
- *   These functions implement the complete() method of struct
+ *   This function implements the complete() method of struct
  *   usbhost_class_s.  In the interface with the USB host drivers, the class
  *   will queue USB IN/OUT transactions.  The enqueuing function will return
  *   and the transactions will be performed asynchrounously.  When the
@@ -1331,14 +1521,6 @@ static int usbhost_configdesc(FAR struct usbhost_class_s *class,
  *   order to inform the class that the transaction has completed and to
  *   provide any response data.
  *
- *   There are two implementations:  usbhost_complete1() is used during
- *   initialization to sequence through a pre-determined set of queuries
- *   to configure for the connected USB mass storage device.
- *
- *   usbhost_complete2() is used after the completion of the initialization
- *   sequence.  After initialization, the only interactions with the mass
- *   storage device will be through block driver operations.
- *
  * Input Parameters:
  *   class - The USB host class entry previously obtained from a call to
  *     create().
@@ -1354,23 +1536,11 @@ static int usbhost_configdesc(FAR struct usbhost_class_s *class,
  *
  ****************************************************************************/
 
-static int usbhost_complete1(FAR struct usbhost_class_s *class,
+static int usbhost_complete(FAR struct usbhost_class_s *class,
                             FAR const uint8_t *response, int resplen)
 {
   FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)class;
-  DEBUGASSERT(priv != NULL && priv->state == USBSTRG_STATE_BUSY);
-
-  /* Invoke the initialization state machine on each transfer completion event */
-
-  usbhost_work(priv, usbhost_statemachine);
-  return OK;
-}
-
-static int usbhost_complete2(FAR struct usbhost_class_s *class,
-                             FAR const uint8_t *response, int resplen)
-{
-  FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)class;
-  DEBUGASSERT(priv != NULL && priv->state == USBSTRG_STATE_BUSY);
+  DEBUGASSERT(priv != NULL && priv->waitsem.semcount <= 0);
 
   /* Wake up the application thread waiting for the transfer completion event */
 
@@ -1463,7 +1633,6 @@ static int usbhost_open(FAR struct inode *inode)
 
       DEBUGASSERT(priv->crefs < MAX_CREFS);
       usbhost_takesem(&priv->exclsem);
-      DEBUGASSERT(priv->state == USBSTRG_STATE_READY);
       priv->crefs++;
       usbhost_givesem(&priv->exclsem);
       ret = OK;
@@ -1491,7 +1660,6 @@ static int usbhost_close(FAR struct inode *inode)
 
   DEBUGASSERT(priv->crefs > 0);
   usbhost_takesem(&priv->exclsem);
-  DEBUGASSERT(priv->state == USBSTRG_STATE_READY);
   priv->crefs--;
 
   /* Release the semaphore.  The following operations when crefs == 1 are
@@ -1511,6 +1679,7 @@ static int usbhost_close(FAR struct inode *inode)
     {
       /* Destroy the class instance */
 
+      DEBUGASSERT(priv->crefs == 1);
       usbhost_destroy(priv);
     }
   return OK;
@@ -1530,6 +1699,7 @@ static ssize_t usbhost_read(FAR struct inode *inode, unsigned char *buffer,
 {
   FAR struct usbhost_state_s *priv;
   ssize_t ret = 0;
+  int result;
 
   DEBUGASSERT(inode && inode->i_private);
   priv = (FAR struct usbhost_state_s *)inode->i_private;
@@ -1549,9 +1719,64 @@ static ssize_t usbhost_read(FAR struct inode *inode, unsigned char *buffer,
     }
   else if (nsectors > 0)
     {
+      FAR struct usbstrg_cbw_s *cbw;
+
       usbhost_takesem(&priv->exclsem);
-      DEBUGASSERT(priv->state == USBSTRG_STATE_READY);
-#warning "Missing logic"
+
+      /* Assume allocation failure */
+
+      ret = -ENOMEM;
+
+      /* Initialize a CBW (allocating it if necessary) */
+ 
+      cbw = usbhost_cbwalloc(priv);
+      if (cbw)
+        {
+          /* Assume some device failure */
+
+          ret = -ENODEV;
+
+          /* Construct and send the CBW */
+ 
+          usbhost_readcbw(startsector, priv->blocksize, nsectors, cbw);
+          result = DRVR_TRANSFER(priv->drvr, &priv->bulkout,
+                                 (uint8_t*)cbw, USBSTRG_CBW_SIZEOF);
+          if (result == OK)
+            {
+              /* Wait for the CBW OUT operation to complete */
+
+              usbhost_takesem(&priv->waitsem);
+
+              /* Receive the user data */
+#warning "For lpc17xx, I think this buffer needs to lie in BANK1"
+              result = DRVR_TRANSFER(priv->drvr, &priv->bulkin,
+                                     buffer, priv->blocksize * nsectors);
+              if (result == OK)
+                {
+                  /* Wait for the data in operation to complete */
+
+                  usbhost_takesem(&priv->waitsem);
+
+                  /* Receive the CSW */
+
+                  result = DRVR_TRANSFER(priv->drvr, &priv->bulkin,
+                                         priv->tdbuffer, USBSTRG_CSW_SIZEOF);
+                  if (result == OK)
+                    {
+                      FAR struct usbstrg_csw_s *csw;
+
+                      /* Check the CSW status */
+
+                      csw = (FAR struct usbstrg_csw_s *)priv->tdbuffer;
+                      if (csw->status == 0)
+                        {
+                          ret = nsectors;
+                        }
+                    }
+                }
+            }
+        }
+
       usbhost_givesem(&priv->exclsem);
     }
 
@@ -1574,7 +1799,8 @@ static ssize_t usbhost_write(FAR struct inode *inode, const unsigned char *buffe
                            size_t startsector, unsigned int nsectors)
 {
   FAR struct usbhost_state_s *priv;
-  int ret;
+  ssize_t ret;
+  int result;
 
   uvdbg("sector: %d nsectors: %d sectorsize: %d\n");
   DEBUGASSERT(inode && inode->i_private);
@@ -1593,9 +1819,64 @@ static ssize_t usbhost_write(FAR struct inode *inode, const unsigned char *buffe
     }
   else
     {
+      FAR struct usbstrg_cbw_s *cbw;
+
       usbhost_takesem(&priv->exclsem);
-      DEBUGASSERT(priv->state == USBSTRG_STATE_READY);
-#warning "Missing logic"
+
+     /* Assume allocation failure */
+
+      ret = -ENOMEM;
+
+      /* Initialize a CBW (allocating it if necessary) */
+ 
+      cbw = usbhost_cbwalloc(priv);
+      if (cbw)
+        {
+          /* Assume some device failure */
+
+          ret = -ENODEV;
+
+          /* Construct and send the CBW */
+ 
+          usbhost_writecbw(startsector, priv->blocksize, nsectors, cbw);
+          result = DRVR_TRANSFER(priv->drvr, &priv->bulkout,
+                                 (uint8_t*)cbw, USBSTRG_CBW_SIZEOF);
+          if (result == OK)
+            {
+              /* Wait for the CBW OUT operation to complete */
+
+              usbhost_takesem(&priv->waitsem);
+
+              /* Send the user data */
+#warning "For lpc17xx, I think this buffer needs to lie in BANK1"
+              result = DRVR_TRANSFER(priv->drvr, &priv->bulkout,
+                                     buffer, priv->blocksize * nsectors);
+              if (result == OK)
+                {
+                  /* Wait for the data in operation to complete */
+
+                  usbhost_takesem(&priv->waitsem);
+
+                  /* Receive the CSW */
+
+                  result = DRVR_TRANSFER(priv->drvr, &priv->bulkin,
+                                         priv->tdbuffer, USBSTRG_CSW_SIZEOF);
+                  if (result == OK)
+                    {
+                      FAR struct usbstrg_csw_s *csw;
+
+                      /* Check the CSW status */
+
+                      csw = (FAR struct usbstrg_csw_s *)priv->tdbuffer;
+                      if (csw->status == 0)
+                        {
+                          ret = nsectors;
+                        }
+                    }
+                }
+            }
+        }
+
       usbhost_givesem(&priv->exclsem);
     }
 
@@ -1637,7 +1918,6 @@ static int usbhost_geometry(FAR struct inode *inode, struct geometry *geometry)
       /* Return the geometry of the USB mass storage device */
 
       usbhost_takesem(&priv->exclsem);
-      DEBUGASSERT(priv->state == USBSTRG_STATE_READY);
 
       geometry->geo_available     = true;
       geometry->geo_mediachanged  = false;
@@ -1691,8 +1971,6 @@ static int usbhost_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
       /* Process the IOCTL by command */
 
       usbhost_takesem(&priv->exclsem);
-      DEBUGASSERT(priv->state == USBSTRG_STATE_READY);
-
       switch (cmd)
         {
         /* Add support for ioctl commands here */
@@ -1701,7 +1979,6 @@ static int usbhost_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
           ret = -ENOTTY;
           break;
         }
-
       usbhost_givesem(&priv->exclsem);
     }
   return ret;
diff --git a/include/nuttx/usb/usbhost.h b/include/nuttx/usb/usbhost.h
index f49db871eee184f99379c0b4258fe5ba74e0e754..821d127d213fc51225c03e9cdcab09c38503c561 100644
--- a/include/nuttx/usb/usbhost.h
+++ b/include/nuttx/usb/usbhost.h
@@ -313,6 +313,30 @@
 
 #define DRVR_TRANSFER(drvr,ed,buffer,buflen) ((drvr)->transfer(drvr,ed,buffer,buflen))
 
+/************************************************************************************
+ * Name: DRVR_DISCONNECT
+ *
+ * Description:
+ *   Called by the class when an error occurs and driver has been disconnected.
+ *   The USB host driver should discard the handle to the class instance (it is
+ *   stale) and not attempt any further interaction with the class driver instance
+ *   (until a new instance is received from the create() method).  The driver
+ *   should not called the class' disconnected() method.
+ *
+ * Input Parameters:
+ *   drvr - The USB host driver instance obtained as a parameter from the call to
+ *      the class create() method.
+ *
+ * Returned Values:
+ *   None
+ *
+ * Assumptions:
+ *   This function will *not* be called from an interrupt handler.
+ *
+ ************************************************************************************/
+
+#define DRVR_DISCONNECT(drvr) ((drvr)->disconnect(drvr))
+
 /************************************************************************************
  * Public Types
  ************************************************************************************/
@@ -444,6 +468,14 @@ struct usbhost_driver_s
   int (*transfer)(FAR struct usbhost_driver_s *drvr,
                   FAR struct usbhost_epdesc_s *ed,
                   FAR uint8_t *buffer, size_t buflen);
+
+  /* Called by the class when an error occurs and driver has been disconnected.
+   * The USB host driver should discard the handle to the class instance (it is
+   * stale) and not attempt any further interaction with the class driver instance
+   * (until a new instance is received from the create() method).
+   */
+
+  void (*disconnect)(FAR struct usbhost_driver_s *drvr);
 };
 
 /* This structure describes one endpoint */