diff --git a/src/add-ons/kernel/bus_managers/usb/BeOSCompatibility.h b/src/add-ons/kernel/bus_managers/usb/BeOSCompatibility.h index 03f52a2692..26247bf427 100644 --- a/src/add-ons/kernel/bus_managers/usb/BeOSCompatibility.h +++ b/src/add-ons/kernel/bus_managers/usb/BeOSCompatibility.h @@ -55,7 +55,7 @@ mutex_init(mutex *ben, const char *name) inline status_t mutex_init_etc(mutex *ben, const char *name, int32 flags) { - mutex_init(ben, name); + return mutex_init(ben, name); } diff --git a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp index b8c6762867..4b40d5e2a1 100644 --- a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp @@ -293,6 +293,7 @@ ControlPipe::ControlPipe(Object *parent) : Pipe(parent), fNotifySem(-1) { + mutex_init(&fSendRequestLock, "control pipe send request"); } @@ -300,6 +301,7 @@ ControlPipe::~ControlPipe() { if (fNotifySem >= 0) delete_sem(fNotifySem); + mutex_destroy(&fSendRequestLock); } @@ -308,16 +310,24 @@ ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, size_t dataLength, size_t *actualLength) { + status_t result = mutex_lock(&fSendRequestLock); + if (result != B_OK) + return result; + if (fNotifySem < 0) { fNotifySem = create_sem(0, "usb send request notify"); - if (fNotifySem < 0) + if (fNotifySem < 0) { + mutex_unlock(&fSendRequestLock); return B_NO_MORE_SEMS; + } } - status_t result = QueueRequest(requestType, request, value, index, length, - data, dataLength, SendRequestCallback, this); - if (result < B_OK) + result = QueueRequest(requestType, request, value, index, length, data, + dataLength, SendRequestCallback, this); + if (result < B_OK) { + mutex_unlock(&fSendRequestLock); return result; + } // The sem will be released unconditionally in the callback after the // result data was filled in. Use a 1 second timeout for control transfers. @@ -334,12 +344,14 @@ ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value, if (actualLength) *actualLength = 0; + mutex_unlock(&fSendRequestLock); return B_TIMED_OUT; } if (actualLength) *actualLength = fActualLength; + mutex_unlock(&fSendRequestLock); return fTransferStatus; } diff --git a/src/add-ons/kernel/bus_managers/usb/usb_p.h b/src/add-ons/kernel/bus_managers/usb/usb_p.h index d6b808c3f3..67f7dc1443 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_p.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_p.h @@ -334,6 +334,7 @@ static void SendRequestCallback(void *cookie, void *callbackCookie); private: + mutex fSendRequestLock; sem_id fNotifySem; status_t fTransferStatus; size_t fActualLength;