diff --git a/src/add-ons/kernel/bus_managers/usb/Device.cpp b/src/add-ons/kernel/bus_managers/usb/Device.cpp index e80ecd0e47..5e4bc842b6 100644 --- a/src/add-ons/kernel/bus_managers/usb/Device.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Device.cpp @@ -329,8 +329,9 @@ Device::~Device() // Cancel transfers on the default pipe and put its USBID to prevent // further transfers from being queued. if (fDefaultPipe != NULL) { - fDefaultPipe->PutUSBID(); + fDefaultPipe->PutUSBID(false); fDefaultPipe->CancelQueuedTransfers(true); + fDefaultPipe->WaitForUnbusy(); } // Destroy open endpoints. Do not send a device request to unconfigure diff --git a/src/add-ons/kernel/bus_managers/usb/Object.cpp b/src/add-ons/kernel/bus_managers/usb/Object.cpp index d2a3f5966b..595dbc03de 100644 --- a/src/add-ons/kernel/bus_managers/usb/Object.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Object.cpp @@ -36,20 +36,26 @@ Object::~Object() void -Object::PutUSBID() +Object::PutUSBID(bool waitForUnbusy) { - if (fUSBID == UINT32_MAX) - return; + if (fUSBID != UINT32_MAX) { + fStack->PutUSBID(this); + fUSBID = UINT32_MAX; + } - fStack->PutUSBID(this); + if (waitForUnbusy) + WaitForUnbusy(); +} + +void +Object::WaitForUnbusy() +{ int32 retries = 20; while (atomic_get(&fBusy) != 0 && retries--) snooze(100); if (retries <= 0) panic("USB object did not become unbusy!"); - - fUSBID = UINT32_MAX; } diff --git a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp index 106b8857ec..58249e7a01 100644 --- a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp @@ -338,8 +338,9 @@ ControlPipe::ControlPipe(Object *parent) ControlPipe::~ControlPipe() { // We do this here in case a submitted request is still running. - PutUSBID(); + PutUSBID(false); ControlPipe::CancelQueuedTransfers(true); + WaitForUnbusy(); if (fNotifySem >= 0) delete_sem(fNotifySem); diff --git a/src/add-ons/kernel/bus_managers/usb/usb_private.h b/src/add-ons/kernel/bus_managers/usb/usb_private.h index a5bd1ba43d..a5bcd77fa4 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_private.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_private.h @@ -278,7 +278,8 @@ virtual status_t ClearFeature(uint16 selector); virtual status_t GetStatus(uint16 *status); protected: - void PutUSBID(); + void PutUSBID(bool waitForUnbusy = true); + void WaitForUnbusy(); private: Object * fParent;