ST/USBHOST forked to add another HID handler for raw keyboard data to get more detail not available with current handlers (all pressed keys, all releases, and periodic updates)

Dependents:   C64-stm429_discovery

Files at this revision

API Documentation at this revision

Comitter:
frq08711@LMECWL0871.LME.ST.COM
Date:
Wed Apr 26 18:11:37 2017 +0200
Parent:
3:1c76b46ad779
Child:
6:d3ac9e1c0035
Commit message:
update for hub support

Changed in this revision

USBHost/TARGET_STM/USBEndpoint_STM.cpp Show annotated file Show diff for this revision Revisions of this file
USBHost/TARGET_STM/USBHALHost_STM.cpp Show annotated file Show diff for this revision Revisions of this file
USBHost/USBEndpoint.h Show annotated file Show diff for this revision Revisions of this file
USBHost/USBHALHost.h Show annotated file Show diff for this revision Revisions of this file
USBHost/USBHost.cpp Show annotated file Show diff for this revision Revisions of this file
USBHost/USBHostConf.h Show annotated file Show diff for this revision Revisions of this file
USBHost/USBHostTypes.h Show annotated file Show diff for this revision Revisions of this file
USBHostHID/USBHostKeyboard.cpp Show annotated file Show diff for this revision Revisions of this file
USBHostHID/USBHostMouse.cpp Show annotated file Show diff for this revision Revisions of this file
USBHostHID/USBHostMouse.h Show annotated file Show diff for this revision Revisions of this file
USBHostHub/USBHostHub.cpp Show annotated file Show diff for this revision Revisions of this file
USBHostMSD/USBHostMSD.cpp Show annotated file Show diff for this revision Revisions of this file
USBHostMSD/USBHostMSD.h Show annotated file Show diff for this revision Revisions of this file
--- a/USBHost/TARGET_STM/USBEndpoint_STM.cpp	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHost/TARGET_STM/USBEndpoint_STM.cpp	Wed Apr 26 18:11:37 2017 +0200
@@ -19,10 +19,17 @@
 #include "USBEndpoint.h"
 extern uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
 extern uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
+extern void HAL_HCD_DisableInt(HCD_HandleTypeDef* hhcd, uint8_t chn_num);
+extern void HAL_HCD_EnableInt(HCD_HandleTypeDef* hhcd, uint8_t chn_num);
+
+
 
 
 void USBEndpoint::init(HCED * hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir_, uint32_t size, uint8_t ep_number, HCTD* td_list_[2])
 {
+    HCD_HandleTypeDef *hhcd;
+    uint32_t *addr;
+
     hced = hced_;
     type = type_;
     dir = dir_;
@@ -46,10 +53,14 @@
 
     td_current = td_list[0];
     td_next = td_list[1];
-
+    /*  remove potential post pending from previous endpoint */
+    ep_queue.get(0);
     intf_nb = 0;
-
+    hhcd = (HCD_HandleTypeDef*)hced->hhcd;
+    addr = &((uint32_t *)hhcd->pData)[hced->ch_num];
+    *addr = 0;
     state = USB_TYPE_IDLE;
+    speed =false;
 }
 void USBEndpoint::setSize(uint32_t size)
 {
@@ -59,8 +70,14 @@
 
 void USBEndpoint::setDeviceAddress(uint8_t addr)
 {
+    HCD_HandleTypeDef *hhcd;
+    uint8_t hcd_speed = HCD_SPEED_FULL;
+    /* fix me : small speed device with hub not supported
+    if (this->speed) hcd_speed = HCD_SPEED_LOW; */
+    if (this->speed) USB_WARN("small speed device on hub not supported");
+    MBED_ASSERT(HAL_HCD_HC_Init((HCD_HandleTypeDef*)hced->hhcd,hced->ch_num, address, addr, hcd_speed,  type, size)!=HAL_BUSY);
     this->device_address = addr;
-    HAL_HCD_HC_Init((HCD_HandleTypeDef*)hced->hhcd,hced->ch_num, address, addr, HCD_SPEED_FULL,  type, size);
+
 }
 
 void USBEndpoint::setSpeed(uint8_t speed)
@@ -70,19 +87,41 @@
 
 
 
-void USBEndpoint::setState(uint8_t st) {
-    if (st > 18)
-        return;
-    if (state == USB_TYPE_FREE) HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
+void USBEndpoint::setState(USB_TYPE st)
+{
+    /*  modify this state is possible only with a plug   */
+    if ((state == USB_TYPE_FREE)) return;
 
-    state = (USB_TYPE)st;
+    state = st;
+    if (st == USB_TYPE_FREE) {
+        HCD_HandleTypeDef *hhcd = (HCD_HandleTypeDef*)hced->hhcd;
+        uint32_t *addr = &((uint32_t *)hhcd->pData)[hced->ch_num];
+        if ((*addr)&& (type!=INTERRUPT_ENDPOINT)) {
+            this->ep_queue.put((uint8_t*)1);
+        }
+        MBED_ASSERT(HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num)!=HAL_BUSY);
+        HAL_HCD_DisableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
+        *addr = 0;
+
+    }
+    if ((st == USB_TYPE_ERROR) ) {
+        MBED_ASSERT(HAL_HCD_HC_Halt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num)!=HAL_BUSY);
+        HAL_HCD_DisableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
+
+    }
+    if ((st == USB_TYPE_ERROR) ) {
+        uint8_t hcd_speed = HCD_SPEED_FULL;
+        /* small speed device with hub not supported
+           if (this->speed) hcd_speed = HCD_SPEED_LOW;*/
+        MBED_ASSERT(HAL_HCD_HC_Init((HCD_HandleTypeDef*)hced->hhcd,hced->ch_num, address, 0, hcd_speed,  type, size)!=HAL_BUSY);
+    }
 }
 
 
 extern uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
 extern uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
 
- 
+
 USB_TYPE USBEndpoint::queueTransfer()
 {
     HCD_HandleTypeDef *hhcd = (HCD_HandleTypeDef*)hced->hhcd;
@@ -90,38 +129,36 @@
     uint32_t type = HAL_HCD_HC_GetType(hhcd, hced->ch_num);
     uint32_t max_size =  HAL_HCD_HC_GetMaxPacket(hhcd, hced->ch_num);
     /*  if a packet is queue on disconnected ; no solution for now */
-    if(*addr == (uint32_t) -1) {
-        /* set td as disconnected  */
-        td_current->state =  USB_TYPE_DISCONNECTED;
-        return USB_TYPE_DISCONNECTED;
+    if ((state == USB_TYPE_FREE) ) {
+        td_current->state =  USB_TYPE_FREE;
+        return USB_TYPE_FREE;
     }
+    ep_queue.get(0);
     MBED_ASSERT(*addr ==0);
-    if ((type == EP_TYPE_BULK) || (type== EP_TYPE_CTRL)) {
-        transfer_len =   td_current->size <= max_size ? td_current->size : max_size;
-        transferred = td_current->size;
-    } else  {
-        transfer_len =   td_current->size;
-        transferred = td_current->size;
-        MBED_ASSERT(transferred <= (int)max_size);
-    }
+    transfer_len =   td_current->size <= max_size ? td_current->size : max_size;
     buf_start = (uint8_t *)td_current->currBufPtr;
 
     //Now add this free TD at this end of the queue
     state = USB_TYPE_PROCESSING;
     /*  one request */
     td_current->nextTD = (hcTd*)0;
+#if defined(MAX_NYET_RETRY)
     td_current->retry = 0;
+#endif
+    td_current->setup = setup;
     *addr = (uint32_t)td_current;
     /*  dir /setup is inverted for ST */
     /* token is useful only ctrl endpoint */
     /*  last parameter is ping ? */
     MBED_ASSERT(HAL_HCD_HC_SubmitRequest((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num, dir-1, type,!setup,(uint8_t*) td_current->currBufPtr, transfer_len, 0)==HAL_OK);
+    HAL_HCD_EnableInt((HCD_HandleTypeDef*)hced->hhcd, hced->ch_num);
+
     return USB_TYPE_PROCESSING;
 }
 
 void USBEndpoint::unqueueTransfer(volatile HCTD * td)
 {
-
+    if (state==USB_TYPE_FREE) return;
     uint32_t *addr = &((uint32_t *)((HCD_HandleTypeDef*)hced->hhcd)->pData)[hced->ch_num];
     td->state=0;
     td->currBufPtr=0;
--- a/USBHost/TARGET_STM/USBHALHost_STM.cpp	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHost/TARGET_STM/USBHALHost_STM.cpp	Wed Apr 26 18:11:37 2017 +0200
@@ -26,52 +26,44 @@
 {
     USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData);
     USBHALHost *obj= priv->inst;
-    int i;
     void (USBHALHost::*func)(int hub, int port, bool lowSpeed, USBHostHub * hub_parent ) = priv->deviceConnected;
-	for (i=0; i<MAX_ENDPOINT; i++)
-		if (priv->addr[i]==(uint32_t)-1)priv->addr[i]=0;
-    (obj->*func)(0,1,1,NULL);
+    (obj->*func)(0,1,0,NULL);
 }
 void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
 {
     USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData);
     USBHALHost *obj= priv->inst;
     void (USBHALHost::*func1)(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr)= priv->deviceDisconnected;
-    void (USBHALHost::*func2)(volatile uint32_t addr)= priv->transferCompleted;
-    int i;
     (obj->*func1)(0,1,(USBHostHub *)NULL,0);
-
-    /* fix me  call with same frame number */
-    /*  all on going transaction must end and any new one must be rejected */
-    for (i=0; i<MAX_ENDPOINT; i++) {
-        uint32_t addr = priv->addr[i];
-        priv->addr[i]=(uint32_t)-1;
-        if ((addr!=(uint32_t)-1)&& (addr!=0)){
-            HCTD *td = (HCTD *)addr;
-            td->currBufPtr +=HAL_HCD_HC_GetXferCount(hhcd, i);
-            td->state =  USB_TYPE_DISCONNECTED;
-            (obj->*func2)(addr);
-        }
-    }
-    for (i=1; i< MAX_ENDPOINT;i++)HAL_HCD_HC_Halt(hhcd,i);
 }
 int HAL_HCD_HC_GetDirection(HCD_HandleTypeDef *hhcd,uint8_t chnum)
 {
-/*  useful for transmission */
- return hhcd->hc[chnum].ep_is_in;
+    /*  useful for transmission */
+    return hhcd->hc[chnum].ep_is_in;
 }
 
 uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd,uint8_t chnum)
 {
-/*  useful for transmission */
- return hhcd->hc[chnum].max_packet;
+    /*  useful for transmission */
+    return hhcd->hc[chnum].max_packet;
+}
+
+void  HAL_HCD_EnableInt(HCD_HandleTypeDef *hhcd,uint8_t chnum)
+{
+    USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
+    USBx_HOST->HAINTMSK |= (1 << chnum);
 }
 
 
+void  HAL_HCD_DisableInt(HCD_HandleTypeDef *hhcd,uint8_t chnum)
+{
+    USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
+    USBx_HOST->HAINTMSK &= ~(1 << chnum);
+}
 uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd,uint8_t chnum)
 {
-/*  useful for transmission */
- return hhcd->hc[chnum].ep_type;
+    /*  useful for transmission */
+    return hhcd->hc[chnum].ep_type;
 }
 
 void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd,uint8_t chnum, HCD_URBStateTypeDef urb_state)
@@ -79,118 +71,152 @@
     USBHALHost_Private_t *priv=(USBHALHost_Private_t *)(hhcd->pData);
     USBHALHost *obj= priv->inst;
     void (USBHALHost::*func)(volatile uint32_t addr)= priv->transferCompleted;
+
     uint32_t addr = priv->addr[chnum];
     uint32_t max_size = HAL_HCD_HC_GetMaxPacket(hhcd, chnum);
     uint32_t type = HAL_HCD_HC_GetType(hhcd, chnum);
     uint32_t dir = HAL_HCD_HC_GetDirection(hhcd,chnum);
     uint32_t length;
-    if ((addr!=(uint32_t)-1) && (addr!=0)) {
+    if ( (addr!=0)) {
         HCTD *td = (HCTD *)addr;
-        /*  put the state */
-        if ((urb_state == URB_IDLE) && (type == EP_TYPE_INTR) ) {
-            length = td->size;
-            MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , 1,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK);
-            return;
-        }
-        td->state = (urb_state == URB_DONE) ?  USB_TYPE_IDLE : USB_TYPE_ERROR;
-		/*  move buffer pointer , for size  */
-        if ((type != EP_TYPE_BULK) && (type != EP_TYPE_CTRL )) {
-            /*  in packet  */
-        } else {
-            if (urb_state == URB_DONE) {
-                /*  reset retry counter */
-                td->retry = 0;
-                if (td->size >  max_size) {
-                    /*  enqueue  another request */
-                    td->currBufPtr += max_size;
-                    td->size -= max_size;
-                    length = td->size <= max_size ? td->size : max_size;
-                    MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , 1,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK);
-                    return;
-                }
-            }else if (urb_state == URB_NOTREADY) {
-                /*  try again  */
-                /*  abritary limit , to avoid dead lock if other error than
-                 *  slow response is  */
-                if (td->retry < 1000) {
-                    /*  increment retry counter */
-                    td->retry++;
-                    length = td->size <= max_size ? td->size : max_size;
-                    MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , 1,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK);
-                    return;
-                }else USB_ERR("urb_state != URB_NOTREADY");
 
-
+        if ((type == EP_TYPE_BULK) || (type == EP_TYPE_CTRL )) {
+            switch (urb_state) {
+                case URB_DONE:
+#if defined(MAX_NYET_RETRY)
+                    td->retry = 0;
+#endif
+                    if (td->size >  max_size) {
+                        /*  enqueue  another request */
+                        td->currBufPtr += max_size;
+                        td->size -= max_size;
+                        length = td->size <= max_size ? td->size : max_size;
+                        MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , !td->setup,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK);
+                        HAL_HCD_EnableInt(hhcd, chnum);
+                        return;
+                    }
+                    break;
+                case  URB_NOTREADY:
+                    /*  try again  */
+                    /*  abritary limit , to avoid dead lock if other error than
+                     *  slow response is  */
+#if defined(MAX_NYET_RETRY)
+                    if (td->retry < MAX_NYET_RETRY) {
+                        /*  increment retry counter */
+                        td->retry++;
+#endif
+                        length = td->size <= max_size ? td->size : max_size;
+                        MBED_ASSERT(HAL_HCD_HC_SubmitRequest(hhcd, chnum, dir ,type , !td->setup,(uint8_t*) td->currBufPtr, length, 0)==HAL_OK);
+                        HAL_HCD_EnableInt(hhcd, chnum);
+                        return;
+#if defined(MAX_NYET_RETRY)
+                    } else USB_ERR("urb_state != URB_NOTREADY");
+#endif
+                    break;
             }
         }
-        td->state = (urb_state == URB_DONE) ?  USB_TYPE_IDLE : USB_TYPE_ERROR;
+        if ((type == EP_TYPE_INTR) ) {
+            /*  reply a packet of length NULL, this will be analyse in call back
+             *  for mouse or hub */
+            td->state =USB_TYPE_IDLE ;
+            HAL_HCD_DisableInt(hhcd, chnum);
+
+        } else {
+            td->state = (urb_state == URB_DONE) ?  USB_TYPE_IDLE : USB_TYPE_ERROR;
+        }
         td->currBufPtr +=HAL_HCD_HC_GetXferCount(hhcd, chnum);
-        priv->addr[chnum]=0;
         (obj->*func)(addr);
-    }
-    else
-    {
-        USB_DBG_EVENT("spurious %d %d",chnum, urb_state);
+    } else {
+        if (urb_state !=0)
+            USB_DBG_EVENT("spurious %d %d",chnum, urb_state);
     }
 }
+
 USBHALHost * USBHALHost::instHost;
 
 
-void USBHALHost::init() {
+void USBHALHost::init()
+{
 
     NVIC_DisableIRQ(USBHAL_IRQn);
     NVIC_SetVector(USBHAL_IRQn, (uint32_t)(_usbisr));
     HAL_HCD_Init((HCD_HandleTypeDef *) usb_hcca);
     NVIC_EnableIRQ(USBHAL_IRQn);
+    control_disable = 0;
     HAL_HCD_Start((HCD_HandleTypeDef *) usb_hcca);
     usb_vbus(1);
 }
 
-uint32_t USBHALHost::controlHeadED() {
+uint32_t USBHALHost::controlHeadED()
+{
+    return 0xffffffff;
+}
+
+uint32_t USBHALHost::bulkHeadED()
+{
     return 0xffffffff;
 }
 
-uint32_t USBHALHost::bulkHeadED() {
-   return 0xffffffff;
+uint32_t USBHALHost::interruptHeadED()
+{
+    return 0xffffffff;
 }
 
-uint32_t USBHALHost::interruptHeadED() {
-   return 0xffffffff;
-}
-
-void USBHALHost::updateBulkHeadED(uint32_t addr) {
+void USBHALHost::updateBulkHeadED(uint32_t addr)
+{
 }
 
 
-void USBHALHost::updateControlHeadED(uint32_t addr) {
+void USBHALHost::updateControlHeadED(uint32_t addr)
+{
 }
 
-void USBHALHost::updateInterruptHeadED(uint32_t addr) {
+void USBHALHost::updateInterruptHeadED(uint32_t addr)
+{
 }
 
 
-void USBHALHost::enableList(ENDPOINT_TYPE type) {
-}
-
-
-bool USBHALHost::disableList(ENDPOINT_TYPE type) {
-       return true;
+void USBHALHost::enableList(ENDPOINT_TYPE type)
+{
+    /*  react when the 3 lists are requested to be disabled */
+    if (type == CONTROL_ENDPOINT) {
+        control_disable--;
+        if (control_disable==0)
+            NVIC_EnableIRQ(USBHAL_IRQn);
+        else printf("reent\n");
+    }
 }
 
 
-void USBHALHost::memInit() {
-	usb_hcca =  (volatile HCD_HandleTypeDef *)usb_buf;
+bool USBHALHost::disableList(ENDPOINT_TYPE type)
+{
+    if (type == CONTROL_ENDPOINT) {
+        NVIC_DisableIRQ(USBHAL_IRQn);
+        control_disable++;
+        if (control_disable>1)
+            printf("disable reentrance !!!\n");
+        return true;
+    }
+    return false;
+}
+
+
+void USBHALHost::memInit()
+{
+    usb_hcca =  (volatile HCD_HandleTypeDef *)usb_buf;
     usb_edBuf = usb_buf + HCCA_SIZE;
     usb_tdBuf = usb_buf + HCCA_SIZE +(MAX_ENDPOINT*ED_SIZE);
-	/*  init channel  */
-	for (int i=0; i < MAX_ENDPOINT; i++) {
-		HCED	*hced = (HCED*)(usb_edBuf + i*ED_SIZE);
-		hced->ch_num = i;
-		hced->hhcd = (HCCA *) usb_hcca;
-	}
+    /*  init channel  */
+    memset((void*)usb_buf,0, TOTAL_SIZE);
+    for (int i=0; i < MAX_ENDPOINT; i++) {
+        HCED	*hced = (HCED*)(usb_edBuf + i*ED_SIZE);
+        hced->ch_num = i;
+        hced->hhcd = (HCCA *) usb_hcca;
+    }
 }
 
-volatile uint8_t * USBHALHost::getED() {
+volatile uint8_t * USBHALHost::getED()
+{
     for (int i = 0; i < MAX_ENDPOINT; i++) {
         if ( !edBufAlloc[i] ) {
             edBufAlloc[i] = true;
@@ -201,7 +227,8 @@
     return NULL; //Could not alloc ED
 }
 
-volatile uint8_t * USBHALHost::getTD() {
+volatile uint8_t * USBHALHost::getTD()
+{
     int i;
     for (i = 0; i < MAX_TD; i++) {
         if ( !tdBufAlloc[i] ) {
@@ -214,33 +241,38 @@
 }
 
 
-void USBHALHost::freeED(volatile uint8_t * ed) {
+void USBHALHost::freeED(volatile uint8_t * ed)
+{
     int i;
     i = (ed - usb_edBuf) / ED_SIZE;
     edBufAlloc[i] = false;
 }
 
-void USBHALHost::freeTD(volatile uint8_t * td) {
+void USBHALHost::freeTD(volatile uint8_t * td)
+{
     int i;
     i = (td - usb_tdBuf) / TD_SIZE;
     tdBufAlloc[i] = false;
 }
 
 
-void USBHALHost::resetRootHub() {
+void USBHALHost::resetRootHub()
+{
     // Initiate port reset
     wait(0.2);
     HAL_HCD_ResetPort((HCD_HandleTypeDef *)usb_hcca);
 }
 
 
-void USBHALHost::_usbisr(void) {
+void USBHALHost::_usbisr(void)
+{
     if (instHost) {
         instHost->UsbIrqhandler();
     }
 }
 
-void USBHALHost::UsbIrqhandler() {
+void USBHALHost::UsbIrqhandler()
+{
     HAL_HCD_IRQHandler((HCD_HandleTypeDef *)usb_hcca);
 }
 #endif
--- a/USBHost/USBEndpoint.h	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHost/USBEndpoint.h	Wed Apr 26 18:11:37 2017 +0200
@@ -33,6 +33,9 @@
     * Constructor
     */
     USBEndpoint() {
+#ifdef USBHOST_OTHER
+        speed = false;
+#endif
         state = USB_TYPE_FREE;
         nextEp = NULL;
     };
@@ -111,7 +114,11 @@
 
 
     // setters
+#ifdef USBHOST_OTHER
+    void setState(USB_TYPE st);
+#else
     inline void setState(USB_TYPE st) { state = st; }
+#endif
     void setState(uint8_t st);
     void setDeviceAddress(uint8_t addr);
     inline void setLengthTransferred(int len) { transferred = len; };
--- a/USBHost/USBHALHost.h	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHost/USBHALHost.h	Wed Apr 26 18:11:37 2017 +0200
@@ -164,6 +164,10 @@
 
     bool volatile  edBufAlloc[MAX_ENDPOINT];
     bool volatile tdBufAlloc[MAX_TD];
+#ifdef USBHOST_OTHER
+    int control_disable;
+#endif
+
 };
 
 #endif
--- a/USBHost/USBHost.cpp	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHost/USBHost.cpp	Wed Apr 26 18:11:37 2017 +0200
@@ -46,7 +46,8 @@
 *       - when the usb_thread receives the event, it:
 *           - call the callback attached to the endpoint where the td is attached
 */
-void USBHost::usb_process() {
+void USBHost::usb_process()
+{
 
     bool controlListState;
     bool bulkListState;
@@ -79,110 +80,123 @@
                     too_many_hub = false;
                     buf[4] = 0;
 
-                    do
-                    {
-                      Lock lock(this);
+                    do {
+                        Lock lock(this);
+                        bool hub_unplugged = true;
 
-                      for (i = 0; i < MAX_DEVICE_CONNECTED; i++) {
-                          if (!deviceInUse[i]) {
-                              USB_DBG_EVENT("new device connected: %p\r\n", &devices[i]);
-                              devices[i].init(usb_msg->hub, usb_msg->port, usb_msg->lowSpeed);
-                              deviceReset[i] = false;
-                              deviceInited[i] = true;
-                              break;
-                          }
-                      }
+                        int idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent));
+                        /*  check that hub is connected to root port  */
+                        if (usb_msg->hub_parent) {
+                            /*  a hub device must be present */
+                            for (k = 0; k < MAX_HUB_NB; k++) {
+                                if ((&hubs[k] == usb_msg->hub_parent) && (hub_in_use[k]))
+                                    hub_unplugged=false;
+                            }
+                        } else hub_unplugged = false;
 
-                      if (i == MAX_DEVICE_CONNECTED) {
-                          USB_ERR("Too many device connected!!\r\n");
-                          continue;
-                      }
+                        if (((idx!=-1) && deviceInUse[idx] ) || ((idx == -1) && hub_unplugged))
+                            break;
 
-                      if (!controlEndpointAllocated) {
-                          control = newEndpoint(CONTROL_ENDPOINT, OUT, 0x08, 0x00);
-                          addEndpoint(NULL, 0, (USBEndpoint*)control);
-                          controlEndpointAllocated = true;
-                      }
+                        for (i =0 ; i < MAX_DEVICE_CONNECTED; i++) {
+                            if (!deviceInUse[i]) {
+                                USB_DBG_EVENT("new device connected: %p\r\n", &devices[i]);
+                                devices[i].init(usb_msg->hub, usb_msg->port, usb_msg->lowSpeed);
+                                deviceReset[i] = false;
+                                deviceInited[i] = true;
+                                break;
+                            }
+                        }
 
-  #if MAX_HUB_NB
-                      if (usb_msg->hub_parent)
-                          devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent));
-  #endif
+                        if (i == MAX_DEVICE_CONNECTED) {
+                            USB_ERR("Too many device connected!!\r\n");
+                            continue;
+                        }
 
-                      for (j = 0; j < timeout_set_addr; j++) {
-
-                          resetDevice(&devices[i]);
-
-                          // set size of control endpoint
-                          devices[i].setSizeControlEndpoint(8);
+                        if (!controlEndpointAllocated) {
+                            control = newEndpoint(CONTROL_ENDPOINT, OUT, 0x08, 0x00);
+                            addEndpoint(NULL, 0, (USBEndpoint*)control);
+                            controlEndpointAllocated = true;
+                        }
 
-                          devices[i].activeAddress(false);
+#if MAX_HUB_NB
+                        if (usb_msg->hub_parent)
+                            devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent));
+#endif
 
-                          // get first 8 bit of device descriptor
-                          // and check if we deal with a hub
-                          USB_DBG("usb_thread read device descriptor on dev: %p\r\n", &devices[i]);
-                          res = getDeviceDescriptor(&devices[i], buf, 8);
+                        for (j = 0; j < timeout_set_addr; j++) {
+
+                            resetDevice(&devices[i]);
 
-                          if (res != USB_TYPE_OK) {
-                              USB_ERR("usb_thread could not read dev descr");
-                              continue;
-                          }
+                            // set size of control endpoint
+                            devices[i].setSizeControlEndpoint(8);
+
+                            devices[i].activeAddress(false);
 
-                          // set size of control endpoint
-                          devices[i].setSizeControlEndpoint(buf[7]);
+                            // get first 8 bit of device descriptor
+                            // and check if we deal with a hub
+                            USB_DBG("usb_thread read device descriptor on dev: %p\r\n", &devices[i]);
+                            res = getDeviceDescriptor(&devices[i], buf, 8);
 
-                          // second step: set an address to the device
-                          res = setAddress(&devices[i], devices[i].getAddress());
+                            if (res != USB_TYPE_OK) {
+                                USB_ERR("usb_thread could not read dev descr");
+                                continue;
+                            }
 
-                          if (res != USB_TYPE_OK) {
-                              USB_ERR("SET ADDR FAILED");
-                              continue;
-                          }
-                          devices[i].activeAddress(true);
-                          USB_DBG("Address of %p: %d", &devices[i], devices[i].getAddress());
+                            // set size of control endpoint
+                            devices[i].setSizeControlEndpoint(buf[7]);
+
+                            // second step: set an address to the device
+                            res = setAddress(&devices[i], devices[i].getAddress());
 
-                          // try to read again the device descriptor to check if the device
-                          // answers to its new address
-                          res = getDeviceDescriptor(&devices[i], buf, 8);
+                            if (res != USB_TYPE_OK) {
+                                USB_ERR("SET ADDR FAILED");
+                                continue;
+                            }
+                            devices[i].activeAddress(true);
+                            USB_DBG("Address of %p: %d", &devices[i], devices[i].getAddress());
 
-                          if (res == USB_TYPE_OK) {
-                              break;
-                          }
+                            // try to read again the device descriptor to check if the device
+                            // answers to its new address
+                            res = getDeviceDescriptor(&devices[i], buf, 8);
 
-                          Thread::wait(100);
-                      }
+                            if (res == USB_TYPE_OK) {
+                                break;
+                            }
 
-                      USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port);
+                            Thread::wait(100);
+                        }
 
-  #if MAX_HUB_NB
-                      if (buf[4] == HUB_CLASS) {
-                          for (k = 0; k < MAX_HUB_NB; k++) {
-                              if (hub_in_use[k] == false) {
-                                  for (uint8_t j = 0; j < MAX_TRY_ENUMERATE_HUB; j++) {
-                                      if (hubs[k].connect(&devices[i])) {
-                                          devices[i].hub = &hubs[k];
-                                          hub_in_use[k] = true;
-                                          break;
-                                      }
-                                  }
-                                  if (hub_in_use[k] == true)
-                                      break;
-                              }
-                          }
+                        USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port);
 
-                          if (k == MAX_HUB_NB) {
-                              USB_ERR("Too many hubs connected!!\r\n");
-                              too_many_hub = true;
-                          }
-                      }
+#if MAX_HUB_NB
+                        if (buf[4] == HUB_CLASS) {
+                            for (k = 0; k < MAX_HUB_NB; k++) {
+                                if (hub_in_use[k] == false) {
+                                    for (uint8_t j = 0; j < MAX_TRY_ENUMERATE_HUB; j++) {
+                                        if (hubs[k].connect(&devices[i])) {
+                                            devices[i].hub = &hubs[k];
+                                            hub_in_use[k] = true;
+                                            break;
+                                        }
+                                    }
+                                    if (hub_in_use[k] == true)
+                                        break;
+                                }
+                            }
 
-                      if (usb_msg->hub_parent)
-                          ((USBHostHub *)(usb_msg->hub_parent))->deviceConnected(&devices[i]);
-  #endif
+                            if (k == MAX_HUB_NB) {
+                                USB_ERR("Too many hubs connected!!\r\n");
+                                too_many_hub = true;
+                            }
+                        }
 
-                      if ((i < MAX_DEVICE_CONNECTED) && !too_many_hub) {
-                          deviceInUse[i] = true;
-                      }
+                        if (usb_msg->hub_parent)
+                            ((USBHostHub *)(usb_msg->hub_parent))->deviceConnected(&devices[i]);
+#endif
+
+                        if ((i < MAX_DEVICE_CONNECTED) && !too_many_hub) {
+                            deviceInUse[i] = true;
+                        }
 
                     } while(0);
 
@@ -191,22 +205,22 @@
                 // a device has been disconnected
                 case DEVICE_DISCONNECTED_EVENT:
 
-                    do
-                    {
-                      Lock lock(this);
+                    do {
+                        Lock lock(this);
 
-                      controlListState = disableList(CONTROL_ENDPOINT);
-                      bulkListState = disableList(BULK_ENDPOINT);
-                      interruptListState = disableList(INTERRUPT_ENDPOINT);
+                        controlListState = disableList(CONTROL_ENDPOINT);
+                        bulkListState = disableList(BULK_ENDPOINT);
+                        interruptListState = disableList(INTERRUPT_ENDPOINT);
 
-                      idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent));
-                      if (idx != -1) {
-                          freeDevice((USBDeviceConnected*)&devices[idx]);
-                      }
+                        idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent));
+                        if (idx != -1) {
+                            freeDevice((USBDeviceConnected*)&devices[idx]);
+                            deviceInited[idx]=false;
+                        }
 
-                      if (controlListState) enableList(CONTROL_ENDPOINT);
-                      if (bulkListState) enableList(BULK_ENDPOINT);
-                      if (interruptListState) enableList(INTERRUPT_ENDPOINT);
+                        if (controlListState) enableList(CONTROL_ENDPOINT);
+                        if (bulkListState) enableList(BULK_ENDPOINT);
+                        if (interruptListState) enableList(INTERRUPT_ENDPOINT);
 
                     } while(0);
 
@@ -236,6 +250,12 @@
                             if (deviceInUse[idx]) {
                                 USB_WARN("td %p processed but not in idle state: %s [ep: %p - dev: %p - %s]", usb_msg->td_addr, ep->getStateString(), ep, ep->dev, ep->dev->getName(ep->getIntfNb()));
                                 ep->setState(USB_TYPE_IDLE);
+                                /* as error, on interrupt endpoint can be
+                                 * reported, call the call back registered ,
+                                 * if  device still in use, this call back
+                                 * shall ask again an interrupt request.
+                                 */
+                                ep->call(); 
                             }
                         }
                     }
@@ -282,12 +302,12 @@
 
 USBHost::Lock::Lock(USBHost* pHost) : m_pHost(pHost)
 {
-  m_pHost->usb_mutex.lock();
+    m_pHost->usb_mutex.lock();
 }
 
 USBHost::Lock::~Lock()
 {
-  m_pHost->usb_mutex.unlock();
+    m_pHost->usb_mutex.unlock();
 }
 
 void USBHost::transferCompleted(volatile uint32_t addr)
@@ -340,7 +360,7 @@
                 usb_msg->td_state = state;
                 mail_usb_event.put(usb_msg);
             }
-            ep->setState(state);
+            ep->setState((USB_TYPE)state);
             ep->ep_queue.put((uint8_t*)1);
         }
     }
@@ -363,12 +383,16 @@
 /* virtual */ void USBHost::deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent)
 {
     // be sure that the new device connected is not already connected...
+    disableList(CONTROL_ENDPOINT);
+
     int idx = findDevice(hub, port, hub_parent);
     if (idx != -1) {
-        if (deviceInited[idx])
+        if (deviceInited[idx]) {
+            enableList(CONTROL_ENDPOINT);
+
             return;
+        }
     }
-
     message_t * usb_msg = mail_usb_event.alloc();
     usb_msg->event_id = DEVICE_CONNECTED_EVENT;
     usb_msg->hub = hub;
@@ -376,6 +400,9 @@
     usb_msg->lowSpeed = lowSpeed;
     usb_msg->hub_parent = hub_parent;
     mail_usb_event.put(usb_msg);
+    enableList(CONTROL_ENDPOINT);
+
+
 }
 
 /*
@@ -385,11 +412,17 @@
 /* virtual */ void USBHost::deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr)
 {
     // be sure that the device disconnected is connected...
+
+    disableList(CONTROL_ENDPOINT);
+
     int idx = findDevice(hub, port, hub_parent);
     if (idx != -1) {
-        if (!deviceInUse[idx])
+        if (!deviceInUse[idx]) {
+            enableList(CONTROL_ENDPOINT);
             return;
+        }
     } else {
+        enableList(CONTROL_ENDPOINT);
         return;
     }
 
@@ -399,6 +432,9 @@
     usb_msg->port = port;
     usb_msg->hub_parent = hub_parent;
     mail_usb_event.put(usb_msg);
+    enableList(CONTROL_ENDPOINT);
+
+
 }
 
 void USBHost::freeDevice(USBDeviceConnected * dev)
@@ -695,14 +731,14 @@
     volatile HCTD * hctd = NULL;
     const char * type_str = (type == BULK_ENDPOINT) ? "BULK" :
                             ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" :
-                            ((type == CONTROL_ENDPOINT) ? "CONTROL" : "ISOCHRONOUS"));
+                             ((type == CONTROL_ENDPOINT) ? "CONTROL" : "ISOCHRONOUS"));
     printf("State of %s:\r\n", type_str);
     while (hced != NULL) {
         uint8_t dir = ((hced->control & (3 << 11)) >> 11);
         printf("hced: %p [ADDR: %d, DIR: %s, EP_NB: 0x%X]\r\n", hced,
-                                                   hced->control & 0x7f,
-                                                   (dir == 1) ? "OUT" : ((dir == 0) ? "FROM_TD":"IN"),
-                                                    (hced->control & (0xf << 7)) >> 7);
+               hced->control & 0x7f,
+               (dir == 1) ? "OUT" : ((dir == 0) ? "FROM_TD":"IN"),
+               (hced->control & (0xf << 7)) >> 7);
         hctd = (HCTD *)((uint32_t)(hced->headTD) & ~(0xf));
         while (hctd != hced->tailTD) {
             printf("\thctd: %p [DIR: %s]\r\n", hctd, ((hctd->control & (3 << 19)) >> 19) == 1 ? "OUT" : "IN");
@@ -720,7 +756,7 @@
 USB_TYPE USBHost::addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len)
 {
     USB_TYPE ret=USB_TYPE_PROCESSING;
-	td_mutex.lock();
+    td_mutex.lock();
 
     // allocate a TD which will be freed in TDcompletion
     volatile HCTD * td = ed->getNextTD();
@@ -728,7 +764,7 @@
         return USB_TYPE_ERROR;
     }
 
-#ifndef USBHOST_OTHER 
+#ifndef USBHOST_OTHER
     uint32_t token = (ed->isSetup() ? TD_SETUP : ( (ed->getDir() == IN) ? TD_IN : TD_OUT ));
 
     uint32_t td_toggle;
@@ -754,10 +790,10 @@
     printList(type);
     enableList(type);
 #else
-	/*  call method specific for endpoint  */
-	td->currBufPtr   = buf;
-	td->size = len;
-	ret = ed->queueTransfer();
+    /*  call method specific for endpoint  */
+    td->currBufPtr   = buf;
+    td->size = len;
+    ret = ed->queueTransfer();
 #endif
 
     td_mutex.unlock();
@@ -770,10 +806,10 @@
 USB_TYPE USBHost::getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_dev_descr)
 {
     USB_TYPE t = controlRead(  dev,
-                         USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE,
-                         GET_DESCRIPTOR,
-                         (DEVICE_DESCRIPTOR << 8) | (0),
-                         0, buf, MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf));
+                               USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE,
+                               GET_DESCRIPTOR,
+                               (DEVICE_DESCRIPTOR << 8) | (0),
+                               0, buf, MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf));
     if (len_dev_descr)
         *len_dev_descr = MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf);
 
@@ -812,7 +848,8 @@
 }
 
 
-USB_TYPE USBHost::setAddress(USBDeviceConnected * dev, uint8_t address) {
+USB_TYPE USBHost::setAddress(USBDeviceConnected * dev, uint8_t address)
+{
     return controlWrite(    dev,
                             USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE,
                             SET_ADDRESS,
@@ -830,7 +867,8 @@
                          0, NULL, 0);
 }
 
-uint8_t USBHost::numberDriverAttached(USBDeviceConnected * dev) {
+uint8_t USBHost::numberDriverAttached(USBDeviceConnected * dev)
+{
     int index = findDevice(dev);
     uint8_t cnt = 0;
     if (index == -1)
@@ -848,76 +886,75 @@
     uint16_t total_conf_descr_length = 0;
     USB_TYPE res;
 
-    do
-    {
-      Lock lock(this);
+    do {
+        Lock lock(this);
 
-      // don't enumerate a device which all interfaces are registered to a specific driver
-      int index = findDevice(dev);
+        // don't enumerate a device which all interfaces are registered to a specific driver
+        int index = findDevice(dev);
 
-      if (index == -1) {
-          return USB_TYPE_ERROR;
-      }
+        if (index == -1) {
+            return USB_TYPE_ERROR;
+        }
 
-      uint8_t nb_intf_attached = numberDriverAttached(dev);
-      USB_DBG("dev: %p nb_intf: %d", dev, dev->getNbIntf());
-      USB_DBG("dev: %p nb_intf_attached: %d", dev, nb_intf_attached);
-      if ((nb_intf_attached != 0) && (dev->getNbIntf() == nb_intf_attached)) {
-          USB_DBG("Don't enumerate dev: %p because all intf are registered with a driver", dev);
-          return USB_TYPE_OK;
-      }
+        uint8_t nb_intf_attached = numberDriverAttached(dev);
+        USB_DBG("dev: %p nb_intf: %d", dev, dev->getNbIntf());
+        USB_DBG("dev: %p nb_intf_attached: %d", dev, nb_intf_attached);
+        if ((nb_intf_attached != 0) && (dev->getNbIntf() == nb_intf_attached)) {
+            USB_DBG("Don't enumerate dev: %p because all intf are registered with a driver", dev);
+            return USB_TYPE_OK;
+        }
+
+        USB_DBG("Enumerate dev: %p", dev);
 
-      USB_DBG("Enumerate dev: %p", dev);
-
-      // third step: get the whole device descriptor to see vid, pid
-      res = getDeviceDescriptor(dev, data, DEVICE_DESCRIPTOR_LENGTH);
+        // third step: get the whole device descriptor to see vid, pid
+        res = getDeviceDescriptor(dev, data, DEVICE_DESCRIPTOR_LENGTH);
 
-      if (res != USB_TYPE_OK) {
-          USB_DBG("GET DEV DESCR FAILED");
-          return res;
-      }
+        if (res != USB_TYPE_OK) {
+            USB_DBG("GET DEV DESCR FAILED");
+            return res;
+        }
+
+        dev->setClass(data[4]);
+        dev->setSubClass(data[5]);
+        dev->setProtocol(data[6]);
+        dev->setVid(data[8] | (data[9] << 8));
+        dev->setPid(data[10] | (data[11] << 8));
+        USB_DBG("CLASS: %02X \t VID: %04X \t PID: %04X", data[4], data[8] | (data[9] << 8), data[10] | (data[11] << 8));
 
-      dev->setClass(data[4]);
-      dev->setSubClass(data[5]);
-      dev->setProtocol(data[6]);
-      dev->setVid(data[8] | (data[9] << 8));
-      dev->setPid(data[10] | (data[11] << 8));
-      USB_DBG("CLASS: %02X \t VID: %04X \t PID: %04X", data[4], data[8] | (data[9] << 8), data[10] | (data[11] << 8));
+        pEnumerator->setVidPid( data[8] | (data[9] << 8), data[10] | (data[11] << 8) );
 
-      pEnumerator->setVidPid( data[8] | (data[9] << 8), data[10] | (data[11] << 8) );
+        res = getConfigurationDescriptor(dev, data, sizeof(data), &total_conf_descr_length);
+        if (res != USB_TYPE_OK) {
+            return res;
+        }
 
-      res = getConfigurationDescriptor(dev, data, sizeof(data), &total_conf_descr_length);
-      if (res != USB_TYPE_OK) {
-          return res;
-      }
+#if (DEBUG > 3)
+        USB_DBG("CONFIGURATION DESCRIPTOR:\r\n");
+        for (int i = 0; i < total_conf_descr_length; i++)
+            printf("%02X ", data[i]);
+        printf("\r\n\r\n");
+#endif
 
-  #if (DEBUG > 3)
-      USB_DBG("CONFIGURATION DESCRIPTOR:\r\n");
-      for (int i = 0; i < total_conf_descr_length; i++)
-          printf("%02X ", data[i]);
-      printf("\r\n\r\n");
-  #endif
+        // Parse the configuration descriptor
+        parseConfDescr(dev, data, total_conf_descr_length, pEnumerator);
 
-      // Parse the configuration descriptor
-      parseConfDescr(dev, data, total_conf_descr_length, pEnumerator);
+        // only set configuration if not enumerated before
+        if (!dev->isEnumerated()) {
 
-      // only set configuration if not enumerated before
-      if (!dev->isEnumerated()) {
-
-          USB_DBG("Set configuration 1 on dev: %p", dev);
-          // sixth step: set configuration (only 1 supported)
-          res = setConfiguration(dev, 1);
+            USB_DBG("Set configuration 1 on dev: %p", dev);
+            // sixth step: set configuration (only 1 supported)
+            res = setConfiguration(dev, 1);
 
-          if (res != USB_TYPE_OK) {
-              USB_DBG("SET CONF FAILED");
-              return res;
-          }
-      }
+            if (res != USB_TYPE_OK) {
+                USB_DBG("SET CONF FAILED");
+                return res;
+            }
+        }
 
-      dev->setEnumerated();
+        dev->setEnumerated();
 
-      // Now the device is enumerated!
-      USB_DBG("dev %p is enumerated\r\n", dev);
+        // Now the device is enumerated!
+        USB_DBG("dev %p is enumerated\r\n", dev);
 
     } while(0);
 
@@ -1016,7 +1053,8 @@
     return generalTransfer(dev, ep, buf, len, blocking, INTERRUPT_ENDPOINT, false);
 }
 
-USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking, ENDPOINT_TYPE type, bool write) {
+USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking, ENDPOINT_TYPE type, bool write)
+{
 
 #if DEBUG_TRANSFER
     const char * type_str = (type == BULK_ENDPOINT) ? "BULK" : ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" : "ISOCHRONOUS");
@@ -1064,8 +1102,20 @@
     res = addTransfer(ep, buf, len);
 
     if ((blocking)&& (res == USB_TYPE_PROCESSING)) {
-
+#ifdef USBHOST_OTHER
+        osEvent  event = ep->ep_queue.get(TD_TIMEOUT);
+        if (event.status == osEventTimeout)
+        {
+            /*  control endpoint is confusing for merge on b */
+            disableList(CONTROL_ENDPOINT);
+            ep->setState(USB_TYPE_ERROR);
+            ep->ep_queue.get(0);
+            ep->unqueueTransfer(ep->getProcessedTD());
+            enableList(CONTROL_ENDPOINT);
+        }
+#else
         ep->ep_queue.get();
+#endif
         res = ep->getState();
 
         USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep);
@@ -1082,11 +1132,13 @@
 }
 
 
-USB_TYPE USBHost::controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) {
+USB_TYPE USBHost::controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len)
+{
     return controlTransfer(dev, requestType, request, value, index, buf, len, false);
 }
 
-USB_TYPE USBHost::controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) {
+USB_TYPE USBHost::controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len)
+{
     return controlTransfer(dev, requestType, request, value, index, buf, len, true);
 }
 
@@ -1120,7 +1172,20 @@
     control->setNextToken(TD_SETUP);
     res = addTransfer(control, (uint8_t*)setupPacket, 8);
 
-    if (res == USB_TYPE_PROCESSING) control->ep_queue.get();
+    if (res == USB_TYPE_PROCESSING)
+#ifdef USBHOST_OTHER
+    {   osEvent  event = control->ep_queue.get(TD_TIMEOUT_CTRL);
+        if (event.status == osEventTimeout) {
+            disableList(CONTROL_ENDPOINT);
+            control->setState(USB_TYPE_ERROR);
+            control->ep_queue.get(0);
+            control->unqueueTransfer(control->getProcessedTD());
+            enableList(CONTROL_ENDPOINT);
+        }
+    }
+#else
+        control->ep_queue.get();
+#endif
     res = control->getState();
 
     USB_DBG_TRANSFER("CONTROL setup stage %s", control->getStateString());
@@ -1134,7 +1199,21 @@
         control->setNextToken(token);
         res = addTransfer(control, (uint8_t *)buf, length_transfer);
 
-        if (res == USB_TYPE_PROCESSING) control->ep_queue.get();
+        if (res == USB_TYPE_PROCESSING)
+#ifdef USBHOST_OTHER
+        {   osEvent  event = control->ep_queue.get(TD_TIMEOUT_CTRL);
+            if (event.status == osEventTimeout)
+            {
+                disableList(CONTROL_ENDPOINT);
+                control->setState(USB_TYPE_ERROR);
+                control->ep_queue.get(0);
+                control->unqueueTransfer(control->getProcessedTD());
+                enableList(CONTROL_ENDPOINT);
+            }
+        }
+#else
+        control->ep_queue.get();
+#endif
         res = control->getState();
 
 #if DEBUG_TRANSFER
@@ -1160,8 +1239,22 @@
     token = (write) ? TD_IN : TD_OUT;
     control->setNextToken(token);
     res = addTransfer(control, NULL, 0);
-
-    if (res == USB_TYPE_PROCESSING) control->ep_queue.get();
+    if (res == USB_TYPE_PROCESSING)
+#ifdef USBHOST_OTHER
+    {
+        osEvent  event = control->ep_queue.get(TD_TIMEOUT_CTRL);
+        if (event.status == osEventTimeout)
+        {
+            disableList(CONTROL_ENDPOINT);
+            control->setState(USB_TYPE_ERROR);
+            control->ep_queue.get(0);
+            control->unqueueTransfer(control->getProcessedTD());
+            enableList(CONTROL_ENDPOINT);
+        }
+    }
+#else
+        control->ep_queue.get();
+#endif
     res = control->getState();
 
     USB_DBG_TRANSFER("CONTROL ack stage %s", control->getStateString());
--- a/USBHost/USBHostConf.h	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHost/USBHostConf.h	Wed Apr 26 18:11:37 2017 +0200
@@ -22,17 +22,17 @@
 * to the usb host
 */
 /*   hub + 2 devices */
-#define MAX_DEVICE_CONNECTED        3
+#define MAX_DEVICE_CONNECTED        5
 
 /*
 * Maximum of Hub connected to the usb host
 */
-#define MAX_HUB_NB                  0
+#define MAX_HUB_NB                  3
 
 /*
 * Maximum number of ports on a USB hub
 */
-#define MAX_HUB_PORT                2
+#define MAX_HUB_PORT                4
 
 /*
 * Enable USBHostMSD
--- a/USBHost/USBHostTypes.h	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHost/USBHostTypes.h	Wed Apr 26 18:11:37 2017 +0200
@@ -18,7 +18,7 @@
 #define USB_INC_H
 
 #include "mbed.h"
-#include "toolchain.h"
+#include "mbed_toolchain.h"
 
 enum USB_TYPE {
     USB_TYPE_OK = 0,
@@ -117,6 +117,8 @@
 
 #else
 
+#define TD_TIMEOUT_CTRL  100
+#define TD_TIMEOUT  2000
 #define  TD_SETUP           (uint32_t)(0)                  // Direction of Setup Packet
 #define  TD_IN              (uint32_t)(0x00100000)         // Direction In
 #define  TD_OUT             (uint32_t)(0x00080000)         // Direction Out
@@ -158,6 +160,7 @@
 	__IO  uint32_t   size;        // size of buffer
 	void * ep;                      // ep address where a td is linked in
 	__IO  uint32_t retry;
+	__IO  uint32_t setup;
 } PACKED HCTD;
 // ----------- HostController EndPoint Descriptor -------------
 typedef struct hcEd {
--- a/USBHostHID/USBHostKeyboard.cpp	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHostHID/USBHostKeyboard.cpp	Wed Apr 26 18:11:37 2017 +0200
@@ -99,7 +99,8 @@
 }
 
 
-bool USBHostKeyboard::connect() {
+bool USBHostKeyboard::connect()
+{
 
     if (dev_connected) {
         return true;
@@ -112,16 +113,23 @@
                 break;
 
             if (keyboard_device_found) {
-                int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN);
+                {
+                    /* As this is done in a specific thread
+                     * this lock is taken to avoid to process the device
+                     * disconnect in usb process during the device registering */
+                    USBHost::Lock  Lock(host);
 
-                if (!int_in)
-                    break;
+                    int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN);
 
-                USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf);
-                dev->setName("Keyboard", keyboard_intf);
-                host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init);
+                    if (!int_in)
+                        break;
 
-                int_in->attach(this, &USBHostKeyboard::rxHandler);
+                    USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf);
+                    dev->setName("Keyboard", keyboard_intf);
+                    host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init);
+
+                    int_in->attach(this, &USBHostKeyboard::rxHandler);
+                }
                 host->interruptRead(dev, int_in, report, int_in->getSize(), false);
 
                 dev_connected = true;
--- a/USBHostHID/USBHostMouse.cpp	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHostHID/USBHostMouse.cpp	Wed Apr 26 18:11:37 2017 +0200
@@ -46,7 +46,8 @@
     return dev_connected;
 }
 
-bool USBHostMouse::connect() {
+bool USBHostMouse::connect()
+{
     int len_listen;
 
     if (dev_connected) {
@@ -58,25 +59,32 @@
 
             if(host->enumerate(dev, this))
                 break;
-
             if (mouse_device_found) {
-
-                int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN);
-                if (!int_in)
-                    break;
+                {
+                    /* As this is done in a specific thread
+                     * this lock is taken to avoid to process the device
+                     * disconnect in usb process during the device registering */
+                    USBHost::Lock  Lock(host);
+                    int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN);
+                    if (!int_in)
+                        break;
 
-                USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, mouse_intf);
-                dev->setName("Mouse", mouse_intf);
-                host->registerDriver(dev, mouse_intf, this, &USBHostMouse::init);
+                    USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, mouse_intf);
+                    dev->setName("Mouse", mouse_intf);
+                    host->registerDriver(dev, mouse_intf, this, &USBHostMouse::init);
 
-                int_in->attach(this, &USBHostMouse::rxHandler);
-                len_listen = int_in->getSize();
-                if (len_listen > sizeof(report)) {
-                    len_listen = sizeof(report);
+                    int_in->attach(this, &USBHostMouse::rxHandler);
+                    len_listen = int_in->getSize();
+                    if (len_listen > sizeof(report)) {
+                        len_listen = sizeof(report);
+                    }
                 }
-                host->interruptRead(dev, int_in, report, len_listen, false);
-
-                dev_connected = true;
+                int ret=host->interruptRead(dev, int_in, report, len_listen, false);
+                MBED_ASSERT((ret==USB_TYPE_OK) || (ret ==USB_TYPE_PROCESSING) || (ret == USB_TYPE_FREE));
+                if ((ret==USB_TYPE_OK) || (ret ==USB_TYPE_PROCESSING))
+                    dev_connected = true;
+                if (ret == USB_TYPE_FREE)
+                    dev_connected = false;
                 return true;
             }
         }
@@ -86,33 +94,37 @@
 }
 
 void USBHostMouse::rxHandler() {
-    int len_listen = int_in->getSize();
+    int len_listen = int_in->getLengthTransferred();
+    if (len_listen !=0) {
 
-    if (onUpdate) {
-        (*onUpdate)(report[0] & 0x07, report[1], report[2], report[3]);
-    }
+        if (onUpdate) {
+            (*onUpdate)(report[0] & 0x07, report[1], report[2], report[3]);
+        }
 
-    if (onButtonUpdate && (buttons != (report[0] & 0x07))) {
-        (*onButtonUpdate)(report[0] & 0x07);
-    }
+        if (onButtonUpdate && (buttons != (report[0] & 0x07))) {
+            (*onButtonUpdate)(report[0] & 0x07);
+        }
 
-    if (onXUpdate && (x != report[1])) {
-        (*onXUpdate)(report[1]);
-    }
+        if (onXUpdate && (x != report[1])) {
+            (*onXUpdate)(report[1]);
+        }
 
-    if (onYUpdate && (y != report[2])) {
-        (*onYUpdate)(report[2]);
-    }
+        if (onYUpdate && (y != report[2])) {
+            (*onYUpdate)(report[2]);
+        }
 
-    if (onZUpdate && (z != report[3])) {
-        (*onZUpdate)(report[3]);
+        if (onZUpdate && (z != report[3])) {
+            (*onZUpdate)(report[3]);
+        }
+
+        // update mouse state
+        buttons = report[0] & 0x07;
+        x = report[1];
+        y = report[2];
+        z = report[3];
     }
-
-    // update mouse state
-    buttons = report[0] & 0x07;
-    x = report[1];
-    y = report[2];
-    z = report[3];
+    /*  set again the maximum value */
+    len_listen = int_in->getSize();
 
     if (len_listen > sizeof(report)) {
         len_listen = sizeof(report);
--- a/USBHostHID/USBHostMouse.h	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHostHID/USBHostMouse.h	Wed Apr 26 18:11:37 2017 +0200
@@ -113,8 +113,7 @@
     USBHost * host;
     USBDeviceConnected * dev;
     USBEndpoint * int_in;
-    uint8_t report[4];
-
+    uint8_t report[64];
     bool dev_connected;
     bool mouse_device_found;
     int mouse_intf;
--- a/USBHostHub/USBHostHub.cpp	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHostHub/USBHostHub.cpp	Wed Apr 26 18:11:37 2017 +0200
@@ -180,7 +180,7 @@
 void USBHostHub::rxHandler() {
     uint32_t status;
     if (int_in) {
-        if (int_in->getState() == USB_TYPE_IDLE) {
+        if ((int_in->getLengthTransferred())&&(int_in->getState() == USB_TYPE_IDLE)) {
             for (int port = 1; port <= nb_port; port++) {
                 status = getPortStatus(port);
                 USB_DBG("[hub handler hub: %d] status port %d [hub: %p]: 0x%X", dev->getHub(), port, dev, status);
@@ -227,6 +227,9 @@
 #endif
     while(1) {
         status = getPortStatus(port);
+        /*  disconnection since reset request */
+        if (!(status & PORT_CONNECTION))
+            break;
         if (status & (PORT_ENABLE | PORT_RESET))
             break;
         if (status & PORT_OVER_CURRENT) {
--- a/USBHostMSD/USBHostMSD.cpp	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHostMSD/USBHostMSD.cpp	Wed Apr 26 18:11:37 2017 +0200
@@ -17,7 +17,6 @@
 #include "USBHostMSD.h"
 
 #if USBHOST_MSD
-
 #include "dbg.h"
 
 #define CBW_SIGNATURE   0x43425355
@@ -29,13 +28,16 @@
 #define GET_MAX_LUN             (0xFE)
 #define BO_MASS_STORAGE_RESET   (0xFF)
 
-USBHostMSD::USBHostMSD(const char * rootdir) : FATFileSystem(rootdir)
+USBHostMSD::USBHostMSD()
 {
     host = USBHost::getHostInst();
-    init();
+    /*  register an object in FAT */
+
+    init_usb();
 }
 
-void USBHostMSD::init() {
+void USBHostMSD::init_usb()
+{
     dev_connected = false;
     dev = NULL;
     bulk_in = NULL;
@@ -72,6 +74,11 @@
                 break;
 
             if (msd_device_found) {
+                /* As this is done in a specific thread
+                 * this lock is taken to avoid to process a disconnection in
+                 * usb process during the device registering */
+                USBHost::Lock  Lock(host);
+
                 bulk_in = dev->getEndpoint(msd_intf, BULK_ENDPOINT, IN);
                 bulk_out = dev->getEndpoint(msd_intf, BULK_ENDPOINT, OUT);
 
@@ -80,14 +87,14 @@
 
                 USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, msd_intf);
                 dev->setName("MSD", msd_intf);
-                host->registerDriver(dev, msd_intf, this, &USBHostMSD::init);
+                host->registerDriver(dev, msd_intf, this, &USBHostMSD::init_usb);
 
                 dev_connected = true;
                 return true;
             }
         } //if()
     } //for()
-    init();
+    init_usb();
     return false;
 }
 
@@ -99,9 +106,9 @@
 /*virtual*/ bool USBHostMSD::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
 {
     if ((msd_intf == -1) &&
-        (intf_class == MSD_CLASS) &&
-        (intf_subclass == 0x06) &&
-        (intf_protocol == 0x50)) {
+            (intf_class == MSD_CLASS) &&
+            (intf_subclass == 0x06) &&
+            (intf_protocol == 0x50)) {
         msd_intf = intf_nb;
         return true;
     }
@@ -122,13 +129,15 @@
 }
 
 
-int USBHostMSD::testUnitReady() {
+int USBHostMSD::testUnitReady()
+{
     USB_DBG("Test unit ready");
     return SCSITransfer(NULL, 6, DEVICE_TO_HOST, 0, 0);
 }
 
 
-int USBHostMSD::readCapacity() {
+int USBHostMSD::readCapacity()
+{
     USB_DBG("Read capacity");
     uint8_t cmd[10] = {0x25,0,0,0,0,0,0,0,0,0};
     uint8_t result[8];
@@ -136,13 +145,14 @@
     if (status == 0) {
         blockCount = (result[0] << 24) | (result[1] << 16) | (result[2] << 8) | result[3];
         blockSize = (result[4] << 24) | (result[5] << 16) | (result[6] << 8) | result[7];
-        USB_INFO("MSD [dev: %p] - blockCount: %lu, blockSize: %d,Capacity: %llu\r\n", dev, blockCount, blockSize,(uint64_t)blockCount*(uint64_t)blockSize);
+        USB_INFO("MSD [dev: %p] - blockCount: %u, blockSize: %d, Capacity: %d\r\n", dev, blockCount, blockSize, blockCount*blockSize);
     }
     return status;
 }
 
 
-int USBHostMSD::SCSIRequestSense() {
+int USBHostMSD::SCSIRequestSense()
+{
     USB_DBG("Request sense");
     uint8_t cmd[6] = {0x03,0,0,0,18,0};
     uint8_t result[18];
@@ -151,7 +161,8 @@
 }
 
 
-int USBHostMSD::inquiry(uint8_t lun, uint8_t page_code) {
+int USBHostMSD::inquiry(uint8_t lun, uint8_t page_code)
+{
     USB_DBG("Inquiry");
     uint8_t evpd = (page_code == 0) ? 0 : 1;
     uint8_t cmd[6] = {0x12, uint8_t((lun << 5) | evpd), page_code, 0, 36, 0};
@@ -174,7 +185,8 @@
     return status;
 }
 
-int USBHostMSD::checkResult(uint8_t res, USBEndpoint * ep) {
+int USBHostMSD::checkResult(uint8_t res, USBEndpoint * ep)
+{
     // if ep stalled: send clear feature
     if (res == USB_TYPE_STALL_ERROR) {
         res = host->controlWrite(   dev,
@@ -183,6 +195,7 @@
                                     0, ep->getAddress(), NULL, 0);
         // set state to IDLE if clear feature successful
         if (res == USB_TYPE_OK) {
+            USBHost::Lock  Lock(host);
             ep->setState(USB_TYPE_IDLE);
         }
     }
@@ -194,7 +207,8 @@
 }
 
 
-int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len) {
+int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len)
+{
 
     int res = 0;
 
@@ -277,7 +291,8 @@
 }
 
 
-int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction) {
+int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction)
+{
     uint8_t cmd[10];
     memset(cmd,0,10);
     cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A;
@@ -293,7 +308,8 @@
     return SCSITransfer(cmd, 10, direction, buf, blockSize*nbBlock);
 }
 
-int USBHostMSD::getMaxLun() {
+int USBHostMSD::getMaxLun()
+{
     uint8_t buf[1], res;
     res = host->controlRead(    dev, USB_RECIPIENT_INTERFACE | USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
                                 0xfe, 0, msd_intf, buf, 1);
@@ -301,12 +317,11 @@
     return res;
 }
 
-int USBHostMSD::disk_initialize() {
+int USBHostMSD::init()
+{
     USB_DBG("FILESYSTEM: init");
-    uint16_t i, timeout = 10;
-
+    uint16_t i, timeout = 10, ret;
     getMaxLun();
-
     for (i = 0; i < timeout; i++) {
         Thread::wait(100);
         if (!testUnitReady())
@@ -323,12 +338,17 @@
     return readCapacity();
 }
 
-int USBHostMSD::disk_write(const uint8_t* buffer, uint32_t block_number, uint32_t count) {
+int USBHostMSD::program(const void *buffer, bd_addr_t addr, bd_size_t size)
+{
+    uint32_t block_number, count;
     if (!disk_init) {
-        disk_initialize();
+        init();
     }
     if (!disk_init)
         return -1;
+    block_number =  addr / blockSize;
+    count = size /blockSize;
+
     for (uint32_t b = block_number; b < block_number + count; b++) {
         if (dataTransfer((uint8_t*)buffer, b, 1, HOST_TO_DEVICE))
             return -1;
@@ -337,13 +357,17 @@
     return 0;
 }
 
-int USBHostMSD::disk_read(uint8_t* buffer, uint32_t block_number, uint32_t count) {
-    USB_DBG("FILESYSTEM: read block: %lld, count: %d", block_number, count);
+int USBHostMSD::read(void *buffer, bd_addr_t addr, bd_size_t size)
+{
+    uint32_t block_number, count;
     if (!disk_init) {
-        disk_initialize();
+        init();
     }
     if (!disk_init)
         return -1;
+    block_number =  addr / blockSize;
+    count = size /blockSize;
+
     for (uint32_t b = block_number; b < block_number + count; b++) {
         if (dataTransfer((uint8_t*)buffer, b, 1, DEVICE_TO_HOST))
             return -1;
@@ -352,14 +376,36 @@
     return 0;
 }
 
-uint32_t USBHostMSD::disk_sectors() {
-    USB_DBG("FILESYSTEM: sectors");
-    if (!disk_init) {
-        disk_initialize();
-    }
+int USBHostMSD::erase(bd_addr_t addr, bd_size_t size)
+{
+    return 0;
+}
+
+bd_size_t USBHostMSD::get_read_size() const
+{
+    if (!disk_init)
+        return -1;
+    return (bd_size_t)blockSize;
+}
+
+bd_size_t USBHostMSD::get_program_size() const
+{
+    if (!disk_init)
+        return -1;
+    return  (bd_size_t)blockSize;
+}
+bd_size_t USBHostMSD::get_erase_size() const
+{
+    if (!disk_init)
+        return -1;
+    return  (bd_size_t)blockSize;
+}
+
+bd_size_t USBHostMSD::size() const
+{
+    USB_DBG("FILESYSTEM: size ");
     if (!disk_init)
         return 0;
-    return blockCount;
+    return (bd_size_t)blockCount*(bd_size_t)blockSize;
 }
-
 #endif
--- a/USBHostMSD/USBHostMSD.h	Fri Feb 17 12:40:57 2017 +0100
+++ b/USBHostMSD/USBHostMSD.h	Wed Apr 26 18:11:37 2017 +0200
@@ -23,24 +23,26 @@
 
 #include "USBHost.h"
 #include "FATFileSystem.h"
+#include "BlockDevice.h"
 
 /**
  * A class to communicate a USB flash disk
  */
-class USBHostMSD : public IUSBEnumerator, public FATFileSystem {
+class USBHostMSD : public IUSBEnumerator, public BlockDevice
+{
 public:
     /**
-    * Constructor
-    *
-    * @param rootdir mount name
-    */
-    USBHostMSD(const char * rootdir);
+     * Constructor
+     *
+     * @param rootdir mount name
+     */
+    USBHostMSD();
 
     /**
-    * Check if a MSD device is connected
-    *
-    * @return true if a MSD device is connected
-    */
+     * Check if a MSD device is connected
+     *
+     * @return true if a MSD device is connected
+     */
     bool connected();
 
     /**
@@ -49,6 +51,20 @@
      * @return true if connection was successful
      */
     bool connect();
+    virtual int init();
+    virtual int deinit()
+    {
+        return BD_ERROR_OK;
+    };
+    virtual int read(void *buffer, bd_addr_t addr, bd_size_t size);
+    virtual int program(const void *buffer, bd_addr_t addr, bd_size_t size);
+    virtual int erase(bd_addr_t addr, bd_size_t size);
+    virtual bd_size_t get_read_size() const;
+    virtual bd_size_t get_program_size() const;
+    virtual bd_size_t get_erase_size() const;
+    virtual bd_size_t size() const;
+
+
 
 protected:
     //From IUSBEnumerator
@@ -56,13 +72,6 @@
     virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
     virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
 
-    // From FATFileSystem
-    virtual int disk_initialize();
-    virtual int disk_status() {return 0;};
-    virtual int disk_read(uint8_t* buffer, uint32_t sector, uint32_t count);
-    virtual int disk_write(const uint8_t* buffer, uint32_t sector, uint32_t count);
-    virtual int disk_sync() {return 0;};
-    virtual uint32_t disk_sectors();
 
 private:
     USBHost * host;
@@ -110,7 +119,7 @@
     bool msd_device_found;
     bool disk_init;
 
-    void init();
+    void init_usb();
 
 };