mirror of https://github.com/ARMmbed/mbed-os.git
Protection against concurrent access to USBHost
Fixed regression: Protection against concurrent access to USBHost using locking class Use Lock class within USBHostpull/202/head
parent
8c6ca15be8
commit
876134ec22
|
@ -79,7 +79,9 @@ void USBHost::usb_process() {
|
||||||
too_many_hub = false;
|
too_many_hub = false;
|
||||||
buf[4] = 0;
|
buf[4] = 0;
|
||||||
|
|
||||||
usb_mutex.lock();
|
do
|
||||||
|
{
|
||||||
|
Lock lock(this);
|
||||||
|
|
||||||
for (i = 0; i < MAX_DEVICE_CONNECTED; i++) {
|
for (i = 0; i < MAX_DEVICE_CONNECTED; i++) {
|
||||||
if (!deviceInUse[i]) {
|
if (!deviceInUse[i]) {
|
||||||
|
@ -93,7 +95,6 @@ void USBHost::usb_process() {
|
||||||
|
|
||||||
if (i == MAX_DEVICE_CONNECTED) {
|
if (i == MAX_DEVICE_CONNECTED) {
|
||||||
USB_ERR("Too many device connected!!\r\n");
|
USB_ERR("Too many device connected!!\r\n");
|
||||||
usb_mutex.unlock();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,14 +184,16 @@ void USBHost::usb_process() {
|
||||||
deviceInUse[i] = true;
|
deviceInUse[i] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_mutex.unlock();
|
} while(0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// a device has been disconnected
|
// a device has been disconnected
|
||||||
case DEVICE_DISCONNECTED_EVENT:
|
case DEVICE_DISCONNECTED_EVENT:
|
||||||
|
|
||||||
usb_mutex.lock();
|
do
|
||||||
|
{
|
||||||
|
Lock lock(this);
|
||||||
|
|
||||||
controlListState = disableList(CONTROL_ENDPOINT);
|
controlListState = disableList(CONTROL_ENDPOINT);
|
||||||
bulkListState = disableList(BULK_ENDPOINT);
|
bulkListState = disableList(BULK_ENDPOINT);
|
||||||
|
@ -205,7 +208,7 @@ void USBHost::usb_process() {
|
||||||
if (bulkListState) enableList(BULK_ENDPOINT);
|
if (bulkListState) enableList(BULK_ENDPOINT);
|
||||||
if (interruptListState) enableList(INTERRUPT_ENDPOINT);
|
if (interruptListState) enableList(INTERRUPT_ENDPOINT);
|
||||||
|
|
||||||
usb_mutex.unlock();
|
} while(0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -278,6 +281,15 @@ USBHost::USBHost() : usbThread(USBHost::usb_process_static, (void *)this, osPrio
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
USBHost::Lock::Lock(USBHost* pHost) : m_pHost(pHost)
|
||||||
|
{
|
||||||
|
m_pHost->usb_mutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
USBHost::Lock::~Lock()
|
||||||
|
{
|
||||||
|
m_pHost->usb_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
void USBHost::transferCompleted(volatile uint32_t addr)
|
void USBHost::transferCompleted(volatile uint32_t addr)
|
||||||
{
|
{
|
||||||
|
@ -810,13 +822,14 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
|
||||||
uint16_t total_conf_descr_length = 0;
|
uint16_t total_conf_descr_length = 0;
|
||||||
USB_TYPE res;
|
USB_TYPE res;
|
||||||
|
|
||||||
usb_mutex.lock();
|
do
|
||||||
|
{
|
||||||
|
Lock lock(this);
|
||||||
|
|
||||||
// don't enumerate a device which all interfaces are registered to a specific driver
|
// don't enumerate a device which all interfaces are registered to a specific driver
|
||||||
int index = findDevice(dev);
|
int index = findDevice(dev);
|
||||||
|
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
usb_mutex.unlock();
|
|
||||||
return USB_TYPE_ERROR;
|
return USB_TYPE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,7 +838,6 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
|
||||||
USB_DBG("dev: %p nb_intf_attached: %d", dev, nb_intf_attached);
|
USB_DBG("dev: %p nb_intf_attached: %d", dev, nb_intf_attached);
|
||||||
if ((nb_intf_attached != 0) && (dev->getNbIntf() == 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);
|
USB_DBG("Don't enumerate dev: %p because all intf are registered with a driver", dev);
|
||||||
usb_mutex.unlock();
|
|
||||||
return USB_TYPE_OK;
|
return USB_TYPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,7 +848,6 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
|
||||||
|
|
||||||
if (res != USB_TYPE_OK) {
|
if (res != USB_TYPE_OK) {
|
||||||
USB_DBG("GET DEV DESCR FAILED");
|
USB_DBG("GET DEV DESCR FAILED");
|
||||||
usb_mutex.unlock();
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,7 +862,6 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
|
||||||
|
|
||||||
res = getConfigurationDescriptor(dev, data, sizeof(data), &total_conf_descr_length);
|
res = getConfigurationDescriptor(dev, data, sizeof(data), &total_conf_descr_length);
|
||||||
if (res != USB_TYPE_OK) {
|
if (res != USB_TYPE_OK) {
|
||||||
usb_mutex.unlock();
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -874,7 +884,6 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
|
||||||
|
|
||||||
if (res != USB_TYPE_OK) {
|
if (res != USB_TYPE_OK) {
|
||||||
USB_DBG("SET CONF FAILED");
|
USB_DBG("SET CONF FAILED");
|
||||||
usb_mutex.unlock();
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -883,10 +892,11 @@ USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerato
|
||||||
|
|
||||||
// Now the device is enumerated!
|
// Now the device is enumerated!
|
||||||
USB_DBG("dev %p is enumerated\r\n", dev);
|
USB_DBG("dev %p is enumerated\r\n", dev);
|
||||||
usb_mutex.unlock();
|
|
||||||
|
} while(0);
|
||||||
|
|
||||||
// Some devices may require this delay
|
// Some devices may require this delay
|
||||||
wait_ms(100);
|
Thread::wait(100);
|
||||||
|
|
||||||
return USB_TYPE_OK;
|
return USB_TYPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -987,38 +997,33 @@ USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, ui
|
||||||
USB_DBG_TRANSFER("----- %s %s [dev: %p - %s - hub: %d - port: %d - addr: %d - ep: %02X]------", type_str, (write) ? "WRITE" : "READ", dev, dev->getName(ep->getIntfNb()), dev->getHub(), dev->getPort(), dev->getAddress(), ep->getAddress());
|
USB_DBG_TRANSFER("----- %s %s [dev: %p - %s - hub: %d - port: %d - addr: %d - ep: %02X]------", type_str, (write) ? "WRITE" : "READ", dev, dev->getName(ep->getIntfNb()), dev->getHub(), dev->getPort(), dev->getAddress(), ep->getAddress());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
usb_mutex.lock();
|
Lock lock(this);
|
||||||
|
|
||||||
USB_TYPE res;
|
USB_TYPE res;
|
||||||
ENDPOINT_DIRECTION dir = (write) ? OUT : IN;
|
ENDPOINT_DIRECTION dir = (write) ? OUT : IN;
|
||||||
|
|
||||||
if (dev == NULL) {
|
if (dev == NULL) {
|
||||||
USB_ERR("dev NULL");
|
USB_ERR("dev NULL");
|
||||||
usb_mutex.unlock();
|
|
||||||
return USB_TYPE_ERROR;
|
return USB_TYPE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep == NULL) {
|
if (ep == NULL) {
|
||||||
USB_ERR("ep NULL");
|
USB_ERR("ep NULL");
|
||||||
usb_mutex.unlock();
|
|
||||||
return USB_TYPE_ERROR;
|
return USB_TYPE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep->getState() != USB_TYPE_IDLE) {
|
if (ep->getState() != USB_TYPE_IDLE) {
|
||||||
USB_WARN("[ep: %p - dev: %p - %s] NOT IDLE: %s", ep, ep->dev, ep->dev->getName(ep->getIntfNb()), ep->getStateString());
|
USB_WARN("[ep: %p - dev: %p - %s] NOT IDLE: %s", ep, ep->dev, ep->dev->getName(ep->getIntfNb()), ep->getStateString());
|
||||||
usb_mutex.unlock();
|
|
||||||
return ep->getState();
|
return ep->getState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ep->getDir() != dir) || (ep->getType() != type)) {
|
if ((ep->getDir() != dir) || (ep->getType() != type)) {
|
||||||
USB_ERR("[ep: %p - dev: %p] wrong dir or bad USBEndpoint type", ep, ep->dev);
|
USB_ERR("[ep: %p - dev: %p] wrong dir or bad USBEndpoint type", ep, ep->dev);
|
||||||
usb_mutex.unlock();
|
|
||||||
return USB_TYPE_ERROR;
|
return USB_TYPE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->getAddress() != ep->getDeviceAddress()) {
|
if (dev->getAddress() != ep->getDeviceAddress()) {
|
||||||
USB_ERR("[ep: %p - dev: %p] USBEndpoint addr and device addr don't match", ep, ep->dev);
|
USB_ERR("[ep: %p - dev: %p] USBEndpoint addr and device addr don't match", ep, ep->dev);
|
||||||
usb_mutex.unlock();
|
|
||||||
return USB_TYPE_ERROR;
|
return USB_TYPE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1040,15 +1045,12 @@ USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, ui
|
||||||
USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep);
|
USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep);
|
||||||
|
|
||||||
if (res != USB_TYPE_IDLE) {
|
if (res != USB_TYPE_IDLE) {
|
||||||
usb_mutex.unlock();
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_mutex.unlock();
|
|
||||||
return USB_TYPE_OK;
|
return USB_TYPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_mutex.unlock();
|
|
||||||
return USB_TYPE_PROCESSING;
|
return USB_TYPE_PROCESSING;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1064,7 +1066,7 @@ USB_TYPE USBHost::controlWrite(USBDeviceConnected * dev, uint8_t requestType, ui
|
||||||
|
|
||||||
USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len, bool write)
|
USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len, bool write)
|
||||||
{
|
{
|
||||||
usb_mutex.lock();
|
Lock lock(this);
|
||||||
USB_DBG_TRANSFER("----- CONTROL %s [dev: %p - hub: %d - port: %d] ------", (write) ? "WRITE" : "READ", dev, dev->getHub(), dev->getPort());
|
USB_DBG_TRANSFER("----- CONTROL %s [dev: %p - hub: %d - port: %d] ------", (write) ? "WRITE" : "READ", dev, dev->getHub(), dev->getPort());
|
||||||
|
|
||||||
int length_transfer = len;
|
int length_transfer = len;
|
||||||
|
@ -1098,7 +1100,6 @@ USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType,
|
||||||
USB_DBG_TRANSFER("CONTROL setup stage %s", control->getStateString());
|
USB_DBG_TRANSFER("CONTROL setup stage %s", control->getStateString());
|
||||||
|
|
||||||
if (res != USB_TYPE_IDLE) {
|
if (res != USB_TYPE_IDLE) {
|
||||||
usb_mutex.unlock();
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1126,7 +1127,6 @@ USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (res != USB_TYPE_IDLE) {
|
if (res != USB_TYPE_IDLE) {
|
||||||
usb_mutex.unlock();
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1139,7 +1139,6 @@ USB_TYPE USBHost::controlTransfer(USBDeviceConnected * dev, uint8_t requestType,
|
||||||
res = control->getState();
|
res = control->getState();
|
||||||
|
|
||||||
USB_DBG_TRANSFER("CONTROL ack stage %s", control->getStateString());
|
USB_DBG_TRANSFER("CONTROL ack stage %s", control->getStateString());
|
||||||
usb_mutex.unlock();
|
|
||||||
|
|
||||||
if (res != USB_TYPE_IDLE)
|
if (res != USB_TYPE_IDLE)
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -187,6 +187,18 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate to protect USB thread from accessing shared objects (USBConnectedDevices and Interfaces)
|
||||||
|
*/
|
||||||
|
class Lock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Lock(USBHost* pHost);
|
||||||
|
~Lock();
|
||||||
|
private:
|
||||||
|
USBHost* m_pHost;
|
||||||
|
};
|
||||||
|
|
||||||
friend class USBHostHub;
|
friend class USBHostHub;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -20,11 +20,6 @@
|
||||||
|
|
||||||
#ifdef USBHOST_3GMODULE
|
#ifdef USBHOST_3GMODULE
|
||||||
|
|
||||||
#define __DEBUG__ 0
|
|
||||||
#ifndef __MODULE__
|
|
||||||
#define __MODULE__ "WANDongle.cpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "dbg.h"
|
#include "dbg.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "rtos.h"
|
#include "rtos.h"
|
||||||
|
@ -50,11 +45,15 @@ bool WANDongle::tryConnect()
|
||||||
USB_DBG("Trying to connect device");
|
USB_DBG("Trying to connect device");
|
||||||
|
|
||||||
if (dev_connected) {
|
if (dev_connected) {
|
||||||
|
USB_DBG("Device is already connected!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pInitializer = NULL;
|
m_pInitializer = NULL;
|
||||||
|
|
||||||
|
//Protect from concurrent access from USB thread
|
||||||
|
USBHost::Lock lock(host);
|
||||||
|
|
||||||
for (int i = 0; i < MAX_DEVICE_CONNECTED; i++)
|
for (int i = 0; i < MAX_DEVICE_CONNECTED; i++)
|
||||||
{
|
{
|
||||||
if ((dev = host->getDevice(i)) != NULL)
|
if ((dev = host->getDevice(i)) != NULL)
|
||||||
|
|
Loading…
Reference in New Issue