mirror of https://github.com/ARMmbed/mbed-os.git
USBMSD fixes
Make the following fixes: -deinit in destructor to prevent race conditions -cancel the reset task before calling it since it may be in progress -wait for tasks to complete without mutex held -prevent double connect with _init flagfeature-hal-spec-usb-device
parent
3b7201cc13
commit
af527b490c
|
@ -63,7 +63,7 @@ enum Status {
|
|||
|
||||
USBMSD::USBMSD(BlockDevice *bd, USBPhy *phy, uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
|
||||
: USBDevice(phy, vendor_id, product_id, product_release),
|
||||
_in_task(&_queue), _out_task(&_queue), _reset_task(&_queue), _control_task(&_queue), _configure_task(&_queue)
|
||||
_init(false), _in_task(&_queue), _out_task(&_queue), _reset_task(&_queue), _control_task(&_queue), _configure_task(&_queue)
|
||||
{
|
||||
_bd = bd;
|
||||
_bd->init();
|
||||
|
@ -91,16 +91,26 @@ USBMSD::~USBMSD()
|
|||
{
|
||||
disconnect();
|
||||
_bd->deinit();
|
||||
deinit();
|
||||
}
|
||||
|
||||
bool USBMSD::connect()
|
||||
{
|
||||
_mutex_init.lock();
|
||||
_mutex.lock();
|
||||
|
||||
// already initialized
|
||||
if (_init) {
|
||||
_mutex.unlock();
|
||||
_mutex_init.unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
//disk initialization
|
||||
if (disk_status() & NO_INIT) {
|
||||
if (disk_initialize()) {
|
||||
_mutex.unlock();
|
||||
_mutex_init.unlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -118,25 +128,31 @@ bool USBMSD::connect()
|
|||
_page = (uint8_t *)malloc(_block_size * sizeof(uint8_t));
|
||||
if (_page == NULL) {
|
||||
_mutex.unlock();
|
||||
_mutex_init.unlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_mutex.unlock();
|
||||
_mutex_init.unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
//connect the device
|
||||
USBDevice::connect();
|
||||
_init = true;
|
||||
_mutex.unlock();
|
||||
_mutex_init.unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
void USBMSD::disconnect()
|
||||
{
|
||||
_mutex_init.lock();
|
||||
_mutex.lock();
|
||||
|
||||
USBDevice::disconnect();
|
||||
_init = false;
|
||||
|
||||
_in_task.cancel();
|
||||
_out_task.cancel();
|
||||
|
@ -144,17 +160,23 @@ void USBMSD::disconnect()
|
|||
_control_task.cancel();
|
||||
_configure_task.cancel();
|
||||
|
||||
_mutex.unlock();
|
||||
|
||||
// object mutex must be unlocked for waiting
|
||||
_in_task.wait();
|
||||
_out_task.wait();
|
||||
_reset_task.wait();
|
||||
_control_task.wait();
|
||||
_configure_task.wait();
|
||||
|
||||
_mutex.lock();
|
||||
|
||||
//De-allocate MSD page size:
|
||||
free(_page);
|
||||
_page = NULL;
|
||||
|
||||
_mutex.unlock();
|
||||
_mutex_init.unlock();
|
||||
}
|
||||
|
||||
bool USBMSD::ready()
|
||||
|
@ -231,6 +253,7 @@ void USBMSD::callback_state_change(DeviceState new_state)
|
|||
// called in ISR context
|
||||
|
||||
if (new_state != Configured) {
|
||||
_reset_task.cancel();
|
||||
_reset_task.call();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -189,6 +189,9 @@ private:
|
|||
uint8_t Status;
|
||||
} CSW;
|
||||
|
||||
// If this class has been initialized
|
||||
bool _init;
|
||||
|
||||
//state of the bulk-only state machine
|
||||
Stage _stage;
|
||||
|
||||
|
@ -232,6 +235,7 @@ private:
|
|||
Task<void()> _configure_task;
|
||||
|
||||
BlockDevice *_bd;
|
||||
rtos::Mutex _mutex_init;
|
||||
rtos::Mutex _mutex;
|
||||
|
||||
// space for config descriptor
|
||||
|
|
Loading…
Reference in New Issue