mirror of
https://review.haiku-os.org/haiku
synced 2024-11-23 07:18:40 +01:00
USB: Use BReferenceable for USB objects.
The "busy" counter functionally amounted to a reference count. So just turn it into a real one, instead.
This commit is contained in:
parent
50496cd3da
commit
f7325a93db
@ -334,7 +334,7 @@ Device::~Device()
|
||||
if (fDefaultPipe != NULL) {
|
||||
fDefaultPipe->PutUSBID(false);
|
||||
fDefaultPipe->CancelQueuedTransfers(true);
|
||||
fDefaultPipe->WaitForUnbusy();
|
||||
fDefaultPipe->WaitForIdle();
|
||||
}
|
||||
|
||||
// Destroy open endpoints. Do not send a device request to unconfigure
|
||||
@ -365,7 +365,7 @@ Device::~Device()
|
||||
Interface* interfaceObject =
|
||||
(Interface*)GetStack()->GetObject(interface->handle);
|
||||
if (interfaceObject != NULL)
|
||||
interfaceObject->SetBusy(false);
|
||||
interfaceObject->ReleaseReference();
|
||||
delete interfaceObject;
|
||||
interface->handle = 0;
|
||||
}
|
||||
@ -648,7 +648,7 @@ Device::ClearEndpoints(int32 interfaceIndex)
|
||||
usb_endpoint_info* endpoint = &interfaceInfo->endpoint[i];
|
||||
Pipe* pipe = (Pipe*)GetStack()->GetObject(endpoint->handle);
|
||||
if (pipe != NULL)
|
||||
pipe->SetBusy(false);
|
||||
pipe->ReleaseReference();
|
||||
delete pipe;
|
||||
endpoint->handle = 0;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ Hub::Hub(Object *parent, int8 hubAddress, uint8 hubPort,
|
||||
} else {
|
||||
TRACE_ALWAYS("no interrupt pipe found\n");
|
||||
}
|
||||
object->SetBusy(false);
|
||||
object->ReleaseReference();
|
||||
|
||||
// Wait some time before powering up the ports
|
||||
if (!isRootHub)
|
||||
|
@ -13,8 +13,7 @@ Object::Object(Stack *stack, BusManager *bus)
|
||||
: fParent(NULL),
|
||||
fBusManager(bus),
|
||||
fStack(stack),
|
||||
fUSBID(fStack->GetUSBID(this)),
|
||||
fBusy(0)
|
||||
fUSBID(fStack->GetUSBID(this))
|
||||
{
|
||||
}
|
||||
|
||||
@ -23,8 +22,7 @@ Object::Object(Object *parent)
|
||||
: fParent(parent),
|
||||
fBusManager(parent->GetBusManager()),
|
||||
fStack(parent->GetStack()),
|
||||
fUSBID(fStack->GetUSBID(this)),
|
||||
fBusy(0)
|
||||
fUSBID(fStack->GetUSBID(this))
|
||||
{
|
||||
}
|
||||
|
||||
@ -36,26 +34,26 @@ Object::~Object()
|
||||
|
||||
|
||||
void
|
||||
Object::PutUSBID(bool waitForUnbusy)
|
||||
Object::PutUSBID(bool waitForIdle)
|
||||
{
|
||||
if (fUSBID != UINT32_MAX) {
|
||||
fStack->PutUSBID(this);
|
||||
fUSBID = UINT32_MAX;
|
||||
}
|
||||
|
||||
if (waitForUnbusy)
|
||||
WaitForUnbusy();
|
||||
if (waitForIdle)
|
||||
WaitForIdle();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Object::WaitForUnbusy()
|
||||
Object::WaitForIdle()
|
||||
{
|
||||
int32 retries = 20;
|
||||
while (atomic_get(&fBusy) != 0 && retries--)
|
||||
while (CountReferences() != 1 && retries--)
|
||||
snooze(100);
|
||||
if (retries <= 0)
|
||||
panic("USB object did not become unbusy!");
|
||||
panic("USB object did not become idle!");
|
||||
}
|
||||
|
||||
|
||||
|
@ -375,7 +375,7 @@ ControlPipe::~ControlPipe()
|
||||
// We do this here in case a submitted request is still running.
|
||||
PutUSBID(false);
|
||||
ControlPipe::CancelQueuedTransfers(true);
|
||||
WaitForUnbusy();
|
||||
WaitForIdle();
|
||||
|
||||
if (fNotifySem >= 0)
|
||||
delete_sem(fNotifySem);
|
||||
|
@ -183,7 +183,7 @@ Stack::GetObject(usb_id id)
|
||||
Object *result = fObjectArray[id];
|
||||
|
||||
if (result != NULL)
|
||||
result->SetBusy(true);
|
||||
result->AcquireReference();
|
||||
|
||||
Unlock();
|
||||
return result;
|
||||
|
@ -195,46 +195,6 @@ bus_std_ops(int32 op, ...)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - ObjectBusyReleaser
|
||||
|
||||
|
||||
class ObjectBusyReleaser {
|
||||
public:
|
||||
ObjectBusyReleaser(Object* object) : fObject(object) {}
|
||||
|
||||
~ObjectBusyReleaser()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
void Release()
|
||||
{
|
||||
if (fObject != NULL) {
|
||||
fObject->SetBusy(false);
|
||||
fObject = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool IsSet() const
|
||||
{
|
||||
return fObject != NULL;
|
||||
}
|
||||
|
||||
inline Object *Get() const
|
||||
{
|
||||
return fObject;
|
||||
}
|
||||
|
||||
inline Object *operator->() const
|
||||
{
|
||||
return fObject;
|
||||
}
|
||||
|
||||
private:
|
||||
Object *fObject;
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - public methods
|
||||
|
||||
|
||||
@ -266,7 +226,7 @@ const usb_device_descriptor *
|
||||
get_device_descriptor(usb_device dev)
|
||||
{
|
||||
TRACE_MODULE("get_device_descriptor(%" B_PRId32 ")\n", dev);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(dev));
|
||||
BReference<Object> object(gUSBStack->GetObject(dev), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||
return NULL;
|
||||
Device *device = (Device *)object.Get();
|
||||
@ -280,7 +240,7 @@ get_nth_configuration(usb_device dev, uint32 index)
|
||||
{
|
||||
TRACE_MODULE("get_nth_configuration(%" B_PRId32 ", %" B_PRIu32 ")\n",
|
||||
dev, index);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(dev));
|
||||
BReference<Object> object(gUSBStack->GetObject(dev), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||
return NULL;
|
||||
Device *device = (Device *)object.Get();
|
||||
@ -293,7 +253,7 @@ const usb_configuration_info *
|
||||
get_configuration(usb_device dev)
|
||||
{
|
||||
TRACE_MODULE("get_configuration(%" B_PRId32 ")\n", dev);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(dev));
|
||||
BReference<Object> object(gUSBStack->GetObject(dev), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||
return NULL;
|
||||
Device *device = (Device *)object.Get();
|
||||
@ -308,7 +268,7 @@ set_configuration(usb_device dev,
|
||||
{
|
||||
TRACE_MODULE("set_configuration(%" B_PRId32 ", %p)\n", dev,
|
||||
configuration);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(dev));
|
||||
BReference<Object> object(gUSBStack->GetObject(dev), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
Device *device = (Device *)object.Get();
|
||||
@ -321,7 +281,7 @@ status_t
|
||||
set_alt_interface(usb_device dev, const usb_interface_info *interface)
|
||||
{
|
||||
TRACE_MODULE("set_alt_interface(%" B_PRId32 ", %p)\n", dev, interface);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(dev));
|
||||
BReference<Object> object(gUSBStack->GetObject(dev), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
Device *device = (Device *)object.Get();
|
||||
@ -334,7 +294,7 @@ status_t
|
||||
set_feature(usb_id handle, uint16 selector)
|
||||
{
|
||||
TRACE_MODULE("set_feature(%" B_PRId32 ", %d)\n", handle, selector);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(handle));
|
||||
BReference<Object> object(gUSBStack->GetObject(handle), true);
|
||||
if (!object.IsSet())
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -346,7 +306,7 @@ status_t
|
||||
clear_feature(usb_id handle, uint16 selector)
|
||||
{
|
||||
TRACE_MODULE("clear_feature(%" B_PRId32 ", %d)\n", handle, selector);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(handle));
|
||||
BReference<Object> object(gUSBStack->GetObject(handle), true);
|
||||
if (!object.IsSet())
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -361,7 +321,7 @@ get_status(usb_id handle, uint16 *status)
|
||||
if (!status)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(handle));
|
||||
BReference<Object> object(gUSBStack->GetObject(handle), true);
|
||||
if (!object.IsSet())
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -376,7 +336,7 @@ get_descriptor(usb_device dev, uint8 type, uint8 index, uint16 languageID,
|
||||
TRACE_MODULE("get_descriptor(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, %p, "
|
||||
"%" B_PRIuSIZE ", %p)\n",
|
||||
dev, type, index, languageID, data, dataLength, actualLength);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(dev));
|
||||
BReference<Object> object(gUSBStack->GetObject(dev), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
Device *device = (Device *)object.Get();
|
||||
@ -393,7 +353,7 @@ send_request(usb_device dev, uint8 requestType, uint8 request,
|
||||
TRACE_MODULE("send_request(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, 0x%04x, "
|
||||
"%d, %p, %p)\n", dev, requestType, request, value, index, length,
|
||||
data, actualLength);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(dev));
|
||||
BReference<Object> object(gUSBStack->GetObject(dev), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
Device *device = (Device *)object.Get();
|
||||
@ -411,7 +371,7 @@ queue_request(usb_device dev, uint8 requestType, uint8 request,
|
||||
TRACE_MODULE("queue_request(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, 0x%04x,"
|
||||
" %u, %p, %p, %p)\n", dev, requestType, request, value, index,
|
||||
length, data, callback, callbackCookie);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(dev));
|
||||
BReference<Object> object(gUSBStack->GetObject(dev), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
Device *device = (Device *)object.Get();
|
||||
@ -427,7 +387,7 @@ queue_interrupt(usb_pipe pipe, void *data, size_t dataLength,
|
||||
{
|
||||
TRACE_MODULE("queue_interrupt(%" B_PRId32 ", %p, %ld, %p, %p)\n",
|
||||
pipe, data, dataLength, callback, callbackCookie);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(pipe));
|
||||
BReference<Object> object(gUSBStack->GetObject(pipe), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -442,7 +402,7 @@ queue_bulk(usb_pipe pipe, void *data, size_t dataLength,
|
||||
{
|
||||
TRACE_MODULE("queue_bulk(%" B_PRId32 ", %p, %" B_PRIuSIZE ", %p, %p)\n",
|
||||
pipe, data, dataLength, callback, callbackCookie);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(pipe));
|
||||
BReference<Object> object(gUSBStack->GetObject(pipe), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_BULK_PIPE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -457,7 +417,7 @@ queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount,
|
||||
{
|
||||
TRACE_MODULE("queue_bulk_v(%" B_PRId32 ", %p, %" B_PRIuSIZE " %p, %p)\n",
|
||||
pipe, vector, vectorCount, callback, callbackCookie);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(pipe));
|
||||
BReference<Object> object(gUSBStack->GetObject(pipe), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_BULK_PIPE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -472,7 +432,7 @@ queue_bulk_v_physical(usb_pipe pipe, physical_entry *vector, size_t vectorCount,
|
||||
{
|
||||
TRACE_MODULE("queue_bulk_v_physical(%" B_PRId32 ", %p, %" B_PRIuSIZE
|
||||
", %p, %p)\n", pipe, vector, vectorCount, callback, callbackCookie);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(pipe));
|
||||
BReference<Object> object(gUSBStack->GetObject(pipe), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_BULK_PIPE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -491,7 +451,7 @@ queue_isochronous(usb_pipe pipe, void *data, size_t dataLength,
|
||||
"%" B_PRId32 ", %p, 0x%08" B_PRIx32 ", %p, %p)\n",
|
||||
pipe, data, dataLength, packetDesc, packetCount, startingFrameNumber,
|
||||
flags, callback, callbackCookie);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(pipe));
|
||||
BReference<Object> object(gUSBStack->GetObject(pipe), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_ISO_PIPE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -507,7 +467,7 @@ set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets,
|
||||
{
|
||||
TRACE_MODULE("set_pipe_policy(%" B_PRId32 ", %d, %d, %d)\n", pipe,
|
||||
maxQueuedPackets, maxBufferDurationMS, sampleSize);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(pipe));
|
||||
BReference<Object> object(gUSBStack->GetObject(pipe), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_ISO_PIPE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -520,7 +480,7 @@ status_t
|
||||
cancel_queued_transfers(usb_pipe pipe)
|
||||
{
|
||||
TRACE_MODULE("cancel_queued_transfers(%" B_PRId32 ")\n", pipe);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(pipe));
|
||||
BReference<Object> object(gUSBStack->GetObject(pipe), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_PIPE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -532,7 +492,7 @@ status_t
|
||||
cancel_queued_requests(usb_device dev)
|
||||
{
|
||||
TRACE_MODULE("cancel_queued_requests(%" B_PRId32 ")\n", dev);
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(dev));
|
||||
BReference<Object> object(gUSBStack->GetObject(dev), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
Device *device = (Device *)object.Get();
|
||||
@ -549,7 +509,7 @@ usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize)
|
||||
|
||||
switch (opcode) {
|
||||
case 'DNAM': {
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(*(usb_id *)buffer));
|
||||
BReference<Object> object(gUSBStack->GetObject(*(usb_id *)buffer), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||
return B_BAD_VALUE;
|
||||
Device *device = (Device *)object.Get();
|
||||
@ -589,7 +549,7 @@ get_nth_child(usb_device _hub, uint8 index, usb_device *childDevice)
|
||||
if (!childDevice)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(_hub));
|
||||
BReference<Object> object(gUSBStack->GetObject(_hub), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_HUB) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -615,7 +575,7 @@ get_device_parent(usb_device _device, usb_device *parentHub, uint8 *portIndex)
|
||||
if (!parentHub || !portIndex)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(_device));
|
||||
BReference<Object> object(gUSBStack->GetObject(_device), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -639,7 +599,7 @@ get_device_parent(usb_device _device, usb_device *parentHub, uint8 *portIndex)
|
||||
status_t
|
||||
reset_port(usb_device _hub, uint8 portIndex)
|
||||
{
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(_hub));
|
||||
BReference<Object> object(gUSBStack->GetObject(_hub), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_HUB) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
@ -651,7 +611,7 @@ reset_port(usb_device _hub, uint8 portIndex)
|
||||
status_t
|
||||
disable_port(usb_device _hub, uint8 portIndex)
|
||||
{
|
||||
ObjectBusyReleaser object(gUSBStack->GetObject(_hub));
|
||||
BReference<Object> object(gUSBStack->GetObject(_hub), true);
|
||||
if (!object.IsSet() || (object->Type() & USB_OBJECT_HUB) == 0)
|
||||
return B_DEV_INVALID_PIPE;
|
||||
|
||||
|
@ -137,10 +137,10 @@ public:
|
||||
usb_id GetUSBID(Object *object);
|
||||
void PutUSBID(Object *object);
|
||||
|
||||
// This sets the object as busy; the caller must set it un-busy.
|
||||
// Acquires a reference to the object.
|
||||
Object * GetObject(usb_id id);
|
||||
|
||||
// only for the kernel debugger
|
||||
// only for the kernel debugger (and doesn't acquire a reference)
|
||||
Object * GetObjectNoLock(usb_id id) const;
|
||||
|
||||
void AddBusManager(BusManager *bus);
|
||||
@ -270,7 +270,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class Object {
|
||||
class Object : public BReferenceable {
|
||||
public:
|
||||
Object(Stack *stack, BusManager *bus);
|
||||
Object(Object *parent);
|
||||
@ -283,8 +283,6 @@ virtual ~Object();
|
||||
Stack * GetStack() const { return fStack; }
|
||||
|
||||
usb_id USBID() const { return fUSBID; }
|
||||
void SetBusy(bool busy)
|
||||
{ atomic_add(&fBusy, busy ? 1 : -1); }
|
||||
|
||||
virtual uint32 Type() const { return USB_OBJECT_NONE; }
|
||||
virtual const char * TypeName() const { return "object"; }
|
||||
@ -295,15 +293,14 @@ virtual status_t ClearFeature(uint16 selector);
|
||||
virtual status_t GetStatus(uint16 *status);
|
||||
|
||||
protected:
|
||||
void PutUSBID(bool waitForUnbusy = true);
|
||||
void WaitForUnbusy();
|
||||
void PutUSBID(bool waitForIdle = true);
|
||||
void WaitForIdle();
|
||||
|
||||
private:
|
||||
Object * fParent;
|
||||
BusManager * fBusManager;
|
||||
Stack * fStack;
|
||||
usb_id fUSBID;
|
||||
int32 fBusy;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user