USB: Split WaitForUnbusy from Object::PutUSBID.
In a few instances, we need to not wait for objects to become unbusy
during ID puts because we expect they still will be, e.g. in the case
of Control pipes with submitted transfers that are still running. There,
we need to put the ID, cancel transfers, and only then wait for the
object to become unbusy.
Technically, this is a functional change, but at least in practice
it will have little real-world effect, for two reasons:
1. The DefaultPipe's Busy flag is basically never updated (the Device's
busy flag is generally used instead), so it will virtually never be
"busy".
2. Most devices have no Control endpoints besides that default one.
Change-Id: I32ff4094effeac9ec74546c9643ea2025418e1c1
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4491
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
faae5dd726
commit
8d046e2689
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user