* Revised locking of the USB stack classes

* Implemented the Hub destructor to properly free all of its child devices
* Added FreeDevice() and FreeAddress() to the BusManager class
* Added timeout to ControlPipe::SendRequest()
* Changed how the recursive device reporting works so that it respects the support descriptors of a driver
* Enabled driver rescanning for drivers that are not currently loaded but still registered (R5 only as the devfs function is yet missing from Haiku)
* Changed the way usb_ids are handed out so that free ones are reused instead of just running out of ids
* Fixed driver registration so that each driver is only added once (and devices are reported once per driver)
* Unified debug output and fixed some warnings with debug output turned on
* Fixed some style issues and removed stray whitespaces

Overall the USB stack should now be much more reliable. It should not crash on disconnects anymore and repluging of a device should be noticed by all drivers.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19860 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2007-01-18 22:25:02 +00:00
parent dff0f5c833
commit c4cce7277c
8 changed files with 337 additions and 203 deletions
@@ -15,7 +15,7 @@ BusManager::BusManager(Stack *stack)
fRootHub(NULL)
{
if (benaphore_init(&fLock, "usb busmanager lock") < B_OK) {
TRACE_ERROR(("usb BusManager: failed to create busmanager lock\n"));
TRACE_ERROR(("USB BusManager: failed to create busmanager lock\n"));
return;
}
@@ -26,6 +26,7 @@ BusManager::BusManager(Stack *stack)
// Clear the device map
for (int32 i = 0; i < 128; i++)
fDeviceMap[i] = false;
fDeviceIndex = 0;
// Set the default pipes to NULL (these will be created when needed)
for (int32 i = 0; i <= USB_SPEED_MAX; i++)
@@ -41,6 +42,7 @@ BusManager::~BusManager()
benaphore_destroy(&fLock);
for (int32 i = 0; i <= USB_SPEED_MAX; i++)
delete fDefaultPipes[i];
delete fRootObject;
}
@@ -74,35 +76,60 @@ BusManager::AllocateAddress()
if (!Lock())
return -1;
int8 deviceAddress = -1;
for (int32 i = 1; i < 128; i++) {
if (fDeviceMap[i] == false) {
deviceAddress = i;
fDeviceMap[i] = true;
break;
int8 tries = 127;
int8 address = fDeviceIndex;
while (tries-- > 0) {
if (fDeviceMap[address] == false) {
fDeviceIndex = (address + 1) % 127;
fDeviceMap[address] = true;
Unlock();
return address + 1;
}
address = (address + 1) % 127;
}
TRACE_ERROR(("USB BusManager: the busmanager has run out of device addresses\n"));
Unlock();
return -1;
}
void
BusManager::FreeAddress(int8 address)
{
address--;
if (address < 0)
return;
if (!Lock())
return;
if (!fDeviceMap[address]) {
TRACE_ERROR(("USB BusManager: freeing address %d which was not allocated\n", address));
}
fDeviceMap[address] = false;
Unlock();
return deviceAddress;
}
Device *
BusManager::AllocateNewDevice(Hub *parent, usb_speed speed)
BusManager::AllocateDevice(Hub *parent, usb_speed speed)
{
// Check if there is a free entry in the device map (for the device number)
int8 deviceAddress = AllocateAddress();
if (deviceAddress < 0) {
TRACE_ERROR(("usb BusManager::AllocateNewDevice(): could not get a new address\n"));
TRACE_ERROR(("USB BusManager: could not allocate an address\n"));
return NULL;
}
TRACE(("usb BusManager::AllocateNewDevice(): setting device address to %d\n", deviceAddress));
TRACE(("USB BusManager: setting device address to %d\n", deviceAddress));
ControlPipe *defaultPipe = _GetDefaultPipe(speed);
if (!defaultPipe) {
TRACE(("usb BusManager::AllocateNewDevice(): Error getting the default pipe for speed %d\n", (int)speed));
TRACE(("USB BusManager: error getting the default pipe for speed %d\n", (int)speed));
FreeAddress(deviceAddress);
return NULL;
}
@@ -126,7 +153,8 @@ BusManager::AllocateNewDevice(Hub *parent, usb_speed speed)
}
if (result < B_OK) {
TRACE_ERROR(("usb BusManager::AllocateNewDevice(): error while setting device address\n"));
TRACE_ERROR(("USB BusManager: error while setting device address\n"));
FreeAddress(deviceAddress);
return NULL;
}
@@ -143,19 +171,20 @@ BusManager::AllocateNewDevice(Hub *parent, usb_speed speed)
size_t actualLength = 0;
usb_device_descriptor deviceDescriptor;
TRACE(("usb BusManager::AllocateNewDevice(): getting the device descriptor\n"));
TRACE(("USB BusManager: getting the device descriptor\n"));
pipe.SendRequest(
USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type
USB_REQUEST_GET_DESCRIPTOR, // request
USB_DESCRIPTOR_DEVICE << 8, // value
0, // index
8, // length
8, // length
(void *)&deviceDescriptor, // buffer
8, // buffer length
&actualLength); // actual length
if (actualLength != 8) {
TRACE_ERROR(("usb BusManager::AllocateNewDevice(): error while getting the device descriptor\n"));
TRACE_ERROR(("USB BusManager: error while getting the device descriptor\n"));
FreeAddress(deviceAddress);
return NULL;
}
@@ -170,16 +199,18 @@ BusManager::AllocateNewDevice(Hub *parent, usb_speed speed)
// Create a new instance based on the type (Hub or Device)
if (deviceDescriptor.device_class == 0x09) {
TRACE(("usb BusManager::AllocateNewDevice(): creating new hub\n"));
TRACE(("USB BusManager: creating new hub\n"));
Hub *hub = new(std::nothrow) Hub(parent, deviceDescriptor,
deviceAddress, speed);
if (!hub) {
TRACE_ERROR(("usb BusManager::AllocateNewDevice(): no memory to allocate hub\n"));
TRACE_ERROR(("USB BusManager: no memory to allocate hub\n"));
FreeAddress(deviceAddress);
return NULL;
}
if (hub->InitCheck() < B_OK) {
TRACE_ERROR(("usb BusManager::AllocateNewDevice(): hub failed init check\n"));
TRACE_ERROR(("USB BusManager: hub failed init check\n"));
FreeAddress(deviceAddress);
delete hub;
return NULL;
}
@@ -187,16 +218,18 @@ BusManager::AllocateNewDevice(Hub *parent, usb_speed speed)
return (Device *)hub;
}
TRACE(("usb BusManager::AllocateNewDevice(): creating new device\n"));
TRACE(("USB BusManager: creating new device\n"));
Device *device = new(std::nothrow) Device(parent, deviceDescriptor,
deviceAddress, speed);
if (!device) {
TRACE_ERROR(("usb BusManager::AllocateNewDevice(): no memory to allocate device\n"));
TRACE_ERROR(("USB BusManager: no memory to allocate device\n"));
FreeAddress(deviceAddress);
return NULL;
}
if (device->InitCheck() < B_OK) {
TRACE_ERROR(("usb BusManager::AllocateNewDevice(): device failed init check\n"));
TRACE_ERROR(("USB BusManager: device failed init check\n"));
FreeAddress(deviceAddress);
delete device;
return NULL;
}
@@ -205,6 +238,14 @@ BusManager::AllocateNewDevice(Hub *parent, usb_speed speed)
}
void
BusManager::FreeDevice(Device *device)
{
FreeAddress(device->DeviceAddress());
delete device;
}
status_t
BusManager::Start()
{
@@ -234,24 +275,22 @@ BusManager::NotifyPipeChange(Pipe *pipe, usb_change change)
return B_ERROR;
}
ControlPipe *
BusManager::_GetDefaultPipe(usb_speed speed)
{
if (!Lock())
return NULL;
if (fDefaultPipes[speed] == NULL) {
fDefaultPipes[speed] = new(std::nothrow) ControlPipe(fRootObject,
0, 0, speed, 8);
if (!fDefaultPipes[speed]) {
TRACE_ERROR(("usb BusManager: failed to allocate default pipe\n"));
Unlock();
return NULL;
}
0, 0, speed, 8);
}
if (!fDefaultPipes[speed]) {
TRACE_ERROR(("USB BusManager: failed to allocate default pipe for speed %d\n", speed));
}
Unlock();
return fDefaultPipes[speed];
}
+37 -31
View File
@@ -20,17 +20,15 @@ Device::Device(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
fSpeed(speed),
fDeviceAddress(deviceAddress)
{
TRACE(("USB Device: new device\n"));
TRACE(("USB Device %d: creating device\n", fDeviceAddress));
fDefaultPipe = new(std::nothrow) ControlPipe(this, deviceAddress, 0,
fSpeed, fDeviceDescriptor.max_packet_size_0);
if (!fDefaultPipe) {
TRACE_ERROR(("USB Device: could not allocate default pipe\n"));
TRACE_ERROR(("USB Device %d: could not allocate default pipe\n", fDeviceAddress));
return;
}
fMaxPacketIn[0] = fMaxPacketOut[0] = fDeviceDescriptor.max_packet_size_0;
// Get the device descriptor
// We already have a part of it, but we want it all
size_t actualLength;
@@ -38,7 +36,7 @@ Device::Device(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
(void *)&fDeviceDescriptor, sizeof(fDeviceDescriptor), &actualLength);
if (status < B_OK || actualLength != sizeof(fDeviceDescriptor)) {
TRACE_ERROR(("USB Device: error while getting the device descriptor\n"));
TRACE_ERROR(("USB Device %d: error while getting the device descriptor\n", fDeviceAddress));
return;
}
@@ -62,7 +60,7 @@ Device::Device(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
fConfigurations = (usb_configuration_info *)malloc(
fDeviceDescriptor.num_configurations * sizeof(usb_configuration_info));
if (fConfigurations == NULL) {
TRACE_ERROR(("USB Device: out of memory during config creations!\n"));
TRACE_ERROR(("USB Device %d: out of memory during config creations!\n", fDeviceAddress));
return;
}
@@ -77,7 +75,7 @@ Device::Device(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
return;
}
TRACE(("USB Device %d: configuration %d\n", fDeviceAddress, i));
TRACE(("USB Device %d: configuration %ld\n", fDeviceAddress, i));
TRACE(("\tlength:..............%d\n", configDescriptor.length));
TRACE(("\tdescriptor_type:.....0x%02x\n", configDescriptor.descriptor_type));
TRACE(("\ttotal_length:........%d\n", configDescriptor.total_length));
@@ -263,11 +261,11 @@ Device::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID,
USB_REQUEST_GET_DESCRIPTOR, // request
(descriptorType << 8) | index, // value
languageID, // index
dataLength, // length
dataLength, // length
data, // buffer
dataLength, // buffer length
actualLength); // actual length
}
}
const usb_configuration_info *
@@ -320,7 +318,7 @@ Device::SetConfigurationAt(uint8 index)
USB_REQUEST_SET_CONFIGURATION, // request
fConfigurations[index].descr->configuration_value, // value
0, // index
0, // length
0, // length
NULL, // buffer
0, // buffer length
NULL); // actual length
@@ -388,7 +386,7 @@ Device::Unconfigure(bool atDeviceLevel)
USB_REQUEST_SET_CONFIGURATION, // request
0, // value
0, // index
0, // length
0, // length
NULL, // buffer
0, // buffer length
NULL); // actual length
@@ -404,7 +402,7 @@ Device::Unconfigure(bool atDeviceLevel)
usb_interface_info *interfaceInfo = fCurrentConfiguration->interface[0].active;
for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) {
usb_endpoint_info *endpoint = &interfaceInfo->endpoint[i];
usb_endpoint_info *endpoint = &interfaceInfo->endpoint[i];
delete (Pipe *)GetStack()->GetObject(endpoint->handle);
endpoint->handle = 0;
}
@@ -426,11 +424,7 @@ Device::ReportDevice(usb_support_descriptor *supportDescriptors,
uint32 supportDescriptorCount, const usb_notify_hooks *hooks,
usb_driver_cookie **cookies, bool added)
{
TRACE(("USB Device ReportDevice\n"));
if ((added && hooks->device_added == NULL)
|| (!added && hooks->device_removed == NULL))
return B_BAD_VALUE;
TRACE(("USB Device %d: reporting device\n", fDeviceAddress));
bool supported = false;
if (supportDescriptorCount == 0 || supportDescriptors == NULL)
supported = true;
@@ -441,7 +435,7 @@ Device::ReportDevice(usb_support_descriptor *supportDescriptors,
|| (supportDescriptors[i].product != 0
&& fDeviceDescriptor.product_id != supportDescriptors[i].product))
continue;
if ((supportDescriptors[i].dev_class == 0
|| fDeviceDescriptor.device_class == supportDescriptors[i].dev_class)
&& (supportDescriptors[i].dev_subclass == 0
@@ -469,17 +463,26 @@ Device::ReportDevice(usb_support_descriptor *supportDescriptors,
}
}
if (supported) {
usb_id id = USBID();
if (added) {
usb_driver_cookie *cookie = new(std::nothrow) usb_driver_cookie;
status_t result = hooks->device_added(id, &cookie->cookie);
if (!supported)
return B_UNSUPPORTED;
if ((added && hooks->device_added == NULL)
|| (!added && hooks->device_removed == NULL)) {
// hooks are not installed, but report success to indicate that
// the driver supports the device
return B_OK;
}
usb_id id = USBID();
if (added) {
usb_driver_cookie *cookie = new(std::nothrow) usb_driver_cookie;
if (hooks->device_added(id, &cookie->cookie) >= B_OK) {
cookie->device = id;
cookie->link = *cookies;
*cookies = cookie;
return result;
}
} else
delete cookie;
} else {
usb_driver_cookie **pointer = cookies;
usb_driver_cookie *cookie = *cookies;
while (cookie) {
@@ -489,15 +492,18 @@ Device::ReportDevice(usb_support_descriptor *supportDescriptors,
cookie = cookie->link;
}
if (cookie) {
hooks->device_removed(cookie->cookie);
*pointer = cookie->link;
delete cookie;
if (!cookie) {
// the device is supported, but there is no cookie. this most
// probably means that the device_added hook above failed.
return B_OK;
}
hooks->device_removed(cookie->cookie);
*pointer = cookie->link;
delete cookie;
}
return B_UNSUPPORTED;
return B_OK;
}
+81 -32
View File
@@ -15,36 +15,41 @@ Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
usb_speed speed)
: Device(parent, desc, deviceAddress, speed)
{
TRACE(("USB Hub is being initialised\n"));
TRACE(("USB Hub %d: creating hub\n", DeviceAddress()));
if (!fInitOK) {
TRACE_ERROR(("USB Hub: Device failed to initialize\n"));
TRACE_ERROR(("USB Hub %d: device failed to initialize\n", DeviceAddress()));
return;
}
// Set to false again for the hub init.
fInitOK = false;
if (benaphore_init(&fLock, "usb hub lock") < B_OK) {
TRACE_ERROR(("USB Hub %d: failed to create hub lock\n", DeviceAddress()));
return;
}
for (int32 i = 0; i < 8; i++)
fChildren[i] = NULL;
if (fDeviceDescriptor.device_class != 9) {
TRACE_ERROR(("USB Hub: wrong class! Bailing out\n"));
TRACE_ERROR(("USB Hub %d: wrong class! bailing out\n", DeviceAddress()));
return;
}
TRACE(("USB Hub: Getting hub descriptor...\n"));
TRACE(("USB Hub %d: Getting hub descriptor...\n", DeviceAddress()));
size_t actualLength;
status_t status = GetDescriptor(USB_DESCRIPTOR_HUB, 0, 0,
(void *)&fHubDescriptor, sizeof(usb_hub_descriptor), &actualLength);
// we need at least 8 bytes
if (status < B_OK || actualLength < 8) {
TRACE_ERROR(("USB Hub: Error getting hub descriptor\n"));
TRACE_ERROR(("USB Hub %d: Error getting hub descriptor\n", DeviceAddress()));
return;
}
TRACE(("USB Hub: Hub descriptor (%d bytes):\n", actualLength));
TRACE(("USB Hub %d: hub descriptor (%ld bytes):\n", DeviceAddress(), actualLength));
TRACE(("\tlength:..............%d\n", fHubDescriptor.length));
TRACE(("\tdescriptor_type:.....0x%02x\n", fHubDescriptor.descriptor_type));
TRACE(("\tnum_ports:...........%d\n", fHubDescriptor.num_ports));
@@ -55,7 +60,7 @@ Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
Object *object = GetStack()->GetObject(Configuration()->interface->active->endpoint[0].handle);
if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) {
TRACE_ERROR(("USB Hub: no interrupt pipe found\n"));
TRACE_ERROR(("USB Hub %d: no interrupt pipe found\n", DeviceAddress()));
return;
}
@@ -72,14 +77,47 @@ Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
USB_REQUEST_SET_FEATURE, PORT_POWER, i + 1, 0, NULL, 0, NULL);
if (status < B_OK)
TRACE_ERROR(("USB Hub: power up failed on port %ld\n", i));
TRACE_ERROR(("USB Hub %d: power up failed on port %ld\n", DeviceAddress(), i));
}
// Wait for power to stabilize
snooze(fHubDescriptor.power_on_to_power_good * 2000);
fInitOK = true;
TRACE(("USB Hub: initialised ok\n"));
TRACE(("USB Hub %d: initialised ok\n", DeviceAddress()));
}
Hub::~Hub()
{
Lock();
benaphore_destroy(&fLock);
// Remove all child devices
for (int32 i = 0; i < fHubDescriptor.num_ports; i++) {
if (!fChildren[i])
continue;
TRACE(("USB Hub %d: removing device 0x%08lx\n", DeviceAddress(), fChildren[i]));
GetStack()->NotifyDeviceChange(fChildren[i], false);
GetBusManager()->FreeDevice(fChildren[i]);
}
delete fInterruptPipe;
}
bool
Hub::Lock()
{
return (benaphore_lock(&fLock) == B_OK);
}
void
Hub::Unlock()
{
benaphore_unlock(&fLock);
}
@@ -93,7 +131,7 @@ Hub::UpdatePortStatus(uint8 index)
4, &actualLength);
if (result < B_OK || actualLength < 4) {
TRACE_ERROR(("USB Hub: error updating port status\n"));
TRACE_ERROR(("USB Hub %d: error updating port status\n", DeviceAddress()));
return B_ERROR;
}
@@ -124,7 +162,7 @@ Hub::ResetPort(uint8 index)
}
if ((fPortStatus[index].change & C_PORT_RESET) == 0) {
TRACE_ERROR(("USB Hub: port %d won't reset\n", index));
TRACE_ERROR(("USB Hub %d: port %d won't reset\n", DeviceAddress(), index));
return B_ERROR;
}
@@ -136,7 +174,7 @@ Hub::ResetPort(uint8 index)
// wait for reset recovery
snooze(USB_DELAY_PORT_RESET_RECOVERY);
TRACE(("USB Hub: port %d was reset successfully\n", index));
TRACE(("USB Hub %d: port %d was reset successfully\n", DeviceAddress(), index));
return B_OK;
}
@@ -146,7 +184,7 @@ Hub::Explore()
{
for (int32 i = 0; i < fHubDescriptor.num_ports; i++) {
if (i >= 8) {
TRACE(("USB Hub: hub supports more ports than we do (%d)\n", fHubDescriptor.num_ports));
TRACE(("USB Hub %d: hub supports more ports than we do (%d)\n", DeviceAddress(), fHubDescriptor.num_ports));
fHubDescriptor.num_ports = 8;
continue;
}
@@ -157,8 +195,8 @@ Hub::Explore()
#ifdef TRACE_USB
if (fPortStatus[i].change) {
TRACE(("USB Hub: port %d: status: 0x%04x; change: 0x%04x\n", i, fPortStatus[i].status, fPortStatus[i].change));
TRACE(("USB Hub: device at port %d: 0x%08x\n", i, fChildren[i]));
TRACE(("USB Hub %d: port %ld: status: 0x%04x; change: 0x%04x\n", DeviceAddress(), i, fPortStatus[i].status, fPortStatus[i].change));
TRACE(("USB Hub %d: device at port %ld: 0x%08lx\n", DeviceAddress(), i, fChildren[i]));
}
#endif
@@ -170,7 +208,7 @@ Hub::Explore()
if (fPortStatus[i].status & PORT_STATUS_CONNECTION) {
// new device attached!
TRACE(("USB Hub: Explore(): New device connected\n"));
TRACE(("USB Hub %d: new device connected\n", DeviceAddress()));
// wait some time for the device to power up
snooze(USB_DELAY_DEVICE_POWER_UP);
@@ -186,7 +224,7 @@ Hub::Explore()
if ((fPortStatus[i].status & PORT_STATUS_CONNECTION) == 0) {
// device has vanished after reset, ignore
TRACE(("USB Hub: device disappeared on reset\n"));
TRACE(("USB Hub %d: device disappeared on reset\n", DeviceAddress()));
continue;
}
@@ -196,13 +234,16 @@ Hub::Explore()
if (fPortStatus[i].status & PORT_STATUS_HIGH_SPEED)
speed = USB_SPEED_HIGHSPEED;
Device *newDevice = GetBusManager()->AllocateNewDevice(this,
speed);
Device *newDevice = GetBusManager()->AllocateDevice(this, speed);
if (newDevice) {
if (newDevice && Lock()) {
fChildren[i] = newDevice;
Unlock();
GetStack()->NotifyDeviceChange(fChildren[i], true);
} else {
if (newDevice)
GetBusManager()->FreeDevice(newDevice);
// the device failed to setup correctly, disable the port
// so that the device doesn't get in the way of future
// addressing.
@@ -212,40 +253,44 @@ Hub::Explore()
}
} else {
// Device removed...
TRACE(("USB Hub Explore(): Device removed\n"));
TRACE(("USB Hub %d: device removed\n", DeviceAddress()));
if (fChildren[i]) {
TRACE(("USB Hub: removing device 0x%08x\n", fChildren[i]));
TRACE(("USB Hub %d: removing device 0x%08lx\n", DeviceAddress(), fChildren[i]));
GetStack()->NotifyDeviceChange(fChildren[i], false);
delete fChildren[i];
fChildren[i] = NULL;
if (Lock()) {
GetBusManager()->FreeDevice(fChildren[i]);
fChildren[i] = NULL;
Unlock();
}
}
}
}
// other port changes we do not really handle, report and clear them
if (fPortStatus[i].change & PORT_STATUS_ENABLE) {
TRACE_ERROR(("USB Hub Explore(): port %ld %sabled\n", i, (fPortStatus[i].status & PORT_STATUS_ENABLE) ? "en" : "dis"));
TRACE_ERROR(("USB Hub %d: port %ld %sabled\n", DeviceAddress(), i, (fPortStatus[i].status & PORT_STATUS_ENABLE) ? "en" : "dis"));
DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_CLEAR_FEATURE, C_PORT_ENABLE, i + 1,
0, NULL, 0, NULL);
}
if (fPortStatus[i].change & PORT_STATUS_SUSPEND) {
TRACE_ERROR(("USB Hub Explore(): port %ld is %ssuspended\n", i, (fPortStatus[i].status & PORT_STATUS_SUSPEND) ? "" : "not "));
TRACE_ERROR(("USB Hub %d: port %ld is %ssuspended\n", DeviceAddress(), i, (fPortStatus[i].status & PORT_STATUS_SUSPEND) ? "" : "not "));
DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_CLEAR_FEATURE, C_PORT_SUSPEND, i + 1,
0, NULL, 0, NULL);
}
if (fPortStatus[i].change & PORT_STATUS_OVER_CURRENT) {
TRACE_ERROR(("USB Hub Explore(): port %ld is %sin an over current state\n", i, (fPortStatus[i].status & PORT_STATUS_OVER_CURRENT) ? "" : "not "));
TRACE_ERROR(("USB Hub %d: port %ld is %sin an over current state\n", DeviceAddress(), i, (fPortStatus[i].status & PORT_STATUS_OVER_CURRENT) ? "" : "not "));
DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_CLEAR_FEATURE, C_PORT_OVER_CURRENT, i + 1,
0, NULL, 0, NULL);
}
if (fPortStatus[i].change & PORT_RESET) {
TRACE_ERROR(("USB Hub Explore(): port %ld was reset\n", i));
TRACE_ERROR(("USB Hub %d: port %ld was reset\n", DeviceAddress(), i));
DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT,
USB_REQUEST_CLEAR_FEATURE, C_PORT_RESET, i + 1,
0, NULL, 0, NULL);
@@ -266,7 +311,7 @@ void
Hub::InterruptCallback(void *cookie, status_t status, void *data,
size_t actualLength)
{
TRACE(("USB Hub: interrupt callback!\n"));
TRACE(("USB Hub %d: interrupt callback!\n", ((Hub *)data)->DeviceAddress()));
}
@@ -279,11 +324,11 @@ Hub::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID,
USB_REQUEST_GET_DESCRIPTOR, // request
(descriptorType << 8) | index, // value
languageID, // index
dataLength, // length
dataLength, // length
data, // buffer
dataLength, // buffer length
actualLength); // actual length
}
}
status_t
@@ -291,13 +336,16 @@ Hub::ReportDevice(usb_support_descriptor *supportDescriptors,
uint32 supportDescriptorCount, const usb_notify_hooks *hooks,
usb_driver_cookie **cookies, bool added)
{
TRACE(("USB Hub ReportDevice\n"));
TRACE(("USB Hub %d: reporting hub\n", DeviceAddress()));
// Report ourselfs first
status_t result = Device::ReportDevice(supportDescriptors,
supportDescriptorCount, hooks, cookies, added);
// Then report all of our children
if (!Lock())
return B_ERROR;
for (int32 i = 0; i < fHubDescriptor.num_ports; i++) {
if (!fChildren[i])
continue;
@@ -307,6 +355,7 @@ Hub::ReportDevice(usb_support_descriptor *supportDescriptors,
result = B_OK;
}
Unlock();
return result;
}
+20 -10
View File
@@ -41,7 +41,7 @@ Pipe::SubmitTransfer(Transfer *transfer)
status_t
Pipe::CancelQueuedTransfers()
{
TRACE_ERROR(("Pipe: cancelling transfers is not implemented!\n"));
TRACE_ERROR(("USB Pipe: cancelling transfers is not implemented!\n"));
return B_ERROR;
}
@@ -120,7 +120,7 @@ InterruptPipe::QueueInterrupt(void *data, size_t dataLength,
transfer->SetData((uint8 *)data, dataLength);
transfer->SetCallback(callback, callbackCookie);
status_t result = SubmitTransfer(transfer);
status_t result = GetBusManager()->SubmitTransfer(transfer);
if (result < B_OK)
delete transfer;
return result;
@@ -151,7 +151,7 @@ BulkPipe::QueueBulk(void *data, size_t dataLength, usb_callback_func callback,
transfer->SetData((uint8 *)data, dataLength);
transfer->SetCallback(callback, callbackCookie);
status_t result = SubmitTransfer(transfer);
status_t result = GetBusManager()->SubmitTransfer(transfer);
if (result < B_OK)
delete transfer;
return result;
@@ -169,7 +169,7 @@ BulkPipe::QueueBulkV(iovec *vector, size_t vectorCount,
transfer->SetVector(vector, vectorCount);
transfer->SetCallback(callback, callbackCookie);
status_t result = SubmitTransfer(transfer);
status_t result = GetBusManager()->SubmitTransfer(transfer);
if (result < B_OK)
delete transfer;
return result;
@@ -261,7 +261,7 @@ ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value,
size_t *actualLength)
{
transfer_result_data transferResult;
transferResult.notify_sem = create_sem(0, "Send Request Notify Sem");
transferResult.notify_sem = create_sem(0, "usb send request notify");
if (transferResult.notify_sem < B_OK)
return B_NO_MORE_SEMS;
@@ -272,11 +272,21 @@ ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value,
return result;
}
// the sem will be released in the callback after
// the result data was filled into the provided struct
acquire_sem(transferResult.notify_sem);
delete_sem(transferResult.notify_sem);
// the sem will be released in the callback after the result data was
// filled into the provided struct. use a 5 seconds timeout to avoid
// hanging applications.
if (acquire_sem_etc(transferResult.notify_sem, 1, B_RELATIVE_TIMEOUT, 5000000) < B_OK) {
TRACE_ERROR(("USB ControlPipe: timeout waiting for queued request to complete\n"));
delete_sem(transferResult.notify_sem);
if (actualLength)
*actualLength = 0;
// ToDo: cancel the transfer at the bus manager
return B_TIMED_OUT;
}
delete_sem(transferResult.notify_sem);
if (actualLength)
*actualLength = transferResult.actual_length;
@@ -320,7 +330,7 @@ ControlPipe::QueueRequest(uint8 requestType, uint8 request, uint16 value,
transfer->SetData((uint8 *)data, dataLength);
transfer->SetCallback(callback, callbackCookie);
status_t result = SubmitTransfer(transfer);
status_t result = GetBusManager()->SubmitTransfer(transfer);
if (result < B_OK)
delete transfer;
return result;
+89 -68
View File
@@ -13,6 +13,9 @@
#include "usb_p.h"
#include "PhysicalMemoryAllocator.h"
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
#include <fs/devfs.h>
#endif
Stack::Stack()
: fExploreThread(-1),
@@ -23,10 +26,10 @@ Stack::Stack()
fObjectArray(NULL),
fDriverList(NULL)
{
TRACE(("usb stack: stack init\n"));
TRACE(("USB Stack: stack init\n"));
if (benaphore_init(&fLock, "USB Stack Master Lock") < B_OK) {
TRACE_ERROR(("usb stack: failed to create benaphore lock\n"));
if (benaphore_init(&fLock, "usb stack lock") < B_OK) {
TRACE_ERROR(("USB Stack: failed to create benaphore lock\n"));
return;
}
@@ -37,7 +40,7 @@ Stack::Stack()
fAllocator = new(std::nothrow) PhysicalMemoryAllocator("USB Stack Allocator",
8, B_PAGE_SIZE * 4, 64);
if (!fAllocator || fAllocator->InitCheck() < B_OK) {
TRACE_ERROR(("usb stack: failed to allocate the allocator\n"));
TRACE_ERROR(("USB Stack: failed to allocate the allocator\n"));
delete fAllocator;
return;
}
@@ -47,10 +50,10 @@ Stack::Stack()
char moduleName[B_PATH_NAME_LENGTH];
size_t bufferSize = sizeof(moduleName);
TRACE(("usb stack: Looking for host controller modules\n"));
TRACE(("USB Stack: looking for host controller modules\n"));
while(read_next_module_name(moduleList, moduleName, &bufferSize) == B_OK) {
bufferSize = sizeof(moduleName);
TRACE(("usb stack: Found module %s\n", moduleName));
TRACE(("USB Stack: found module %s\n", moduleName));
host_controller_info *module = NULL;
if (get_module(moduleName, (module_info **)&module) != B_OK)
@@ -59,16 +62,11 @@ Stack::Stack()
if (module->add_to(this) < B_OK)
continue;
TRACE(("usb stack: module %s successfully loaded\n", moduleName));
TRACE(("USB Stack: module %s successfully loaded\n", moduleName));
}
if (fBusManagers.Count() == 0) {
TRACE_ERROR(("usb stack: no bus managers available\n"));
return;
}
if (benaphore_init(&fExploreLock, "usb explore lock") < B_OK) {
TRACE_ERROR(("usb stack: failed to create benaphore explore lock\n"));
TRACE_ERROR(("USB Stack: no bus managers available\n"));
return;
}
@@ -99,7 +97,7 @@ Stack::~Stack()
}
delete fAllocator;
}
}
status_t
@@ -132,16 +130,22 @@ Stack::GetUSBID(Object *object)
if (!Lock())
return 0;
if (fObjectIndex >= fObjectMaxCount) {
Unlock();
return 0;
uint32 id = fObjectIndex;
uint32 tries = fObjectMaxCount;
while (tries-- > 0) {
if (fObjectArray[id] == NULL) {
fObjectIndex = (id + 1) % fObjectMaxCount;
fObjectArray[id] = object;
Unlock();
return (usb_id)id;
}
id = (id + 1) % fObjectMaxCount;
}
uint32 id = fObjectIndex++;
fObjectArray[id] = object;
TRACE_ERROR(("USB Stack: the stack did run out of usb_ids\n"));
Unlock();
return (usb_id)id;
return 0;
}
@@ -152,7 +156,7 @@ Stack::PutUSBID(usb_id id)
return;
if (id >= fObjectMaxCount) {
TRACE_ERROR(("usb stack: tried to put invalid usb_id!\n"));
TRACE_ERROR(("USB Stack: tried to put an invalid usb_id\n"));
Unlock();
return;
}
@@ -169,14 +173,14 @@ Stack::GetObject(usb_id id)
return NULL;
if (id >= fObjectMaxCount) {
TRACE_ERROR(("usb stack: tried to get object with invalid id\n"));
TRACE_ERROR(("USB Stack: tried to get object with invalid usb_id\n"));
Unlock();
return NULL;
}
Object *result = fObjectArray[id];
Unlock();
Unlock();
return result;
}
@@ -187,9 +191,6 @@ Stack::ExploreThread(void *data)
Stack *stack = (Stack *)data;
while (!stack->fStopThreads) {
if (benaphore_lock(&stack->fExploreLock) != B_OK)
continue;
for (int32 i = 0; i < stack->fBusManagers.Count(); i++) {
Hub *rootHub = stack->fBusManagers.ElementAt(i)->GetRootHub();
if (rootHub)
@@ -197,7 +198,6 @@ Stack::ExploreThread(void *data)
}
stack->fFirstExploreDone = true;
benaphore_unlock(&stack->fExploreLock);
snooze(USB_DELAY_HUB_EXPLORE);
}
@@ -228,7 +228,7 @@ Stack::AllocateChunk(void **logicalAddress, void **physicalAddress, size_t size)
status_t
Stack::FreeChunk(void *logicalAddress, void *physicalAddress, size_t size)
{
{
return fAllocator->Deallocate(size, logicalAddress, physicalAddress);
}
@@ -237,7 +237,7 @@ area_id
Stack::AllocateArea(void **logicalAddress, void **physicalAddress, size_t size,
const char *name)
{
TRACE(("usb stack: allocating %ld bytes for %s\n", size, name));
TRACE(("USB Stack: allocating %ld bytes for %s\n", size, name));
void *logAddress;
size = (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
@@ -245,7 +245,7 @@ Stack::AllocateArea(void **logicalAddress, void **physicalAddress, size_t size,
B_FULL_LOCK | B_CONTIGUOUS, 0);
if (area < B_OK) {
TRACE_ERROR(("usb stack: couldn't allocate area %s\n", name));
TRACE_ERROR(("USB Stack: couldn't allocate area %s\n", name));
return B_ERROR;
}
@@ -253,7 +253,7 @@ Stack::AllocateArea(void **logicalAddress, void **physicalAddress, size_t size,
status_t result = get_memory_map(logAddress, size, &physicalEntry, 1);
if (result < B_OK) {
delete_area(area);
TRACE_ERROR(("usb stack: couldn't map area %s\n", name));
TRACE_ERROR(("USB Stack: couldn't map area %s\n", name));
return B_ERROR;
}
@@ -264,7 +264,7 @@ Stack::AllocateArea(void **logicalAddress, void **physicalAddress, size_t size,
if (physicalAddress)
*physicalAddress = physicalEntry.address;
TRACE(("usb stack: area = 0x%08x, size = %ld, log = 0x%08x, phy = 0x%08x\n",
TRACE(("USB Stack: area = 0x%08lx, size = %ld, log = 0x%08lx, phy = 0x%08lx\n",
area, size, logAddress, physicalEntry.address));
return area;
}
@@ -273,24 +273,33 @@ Stack::AllocateArea(void **logicalAddress, void **physicalAddress, size_t size,
void
Stack::NotifyDeviceChange(Device *device, bool added)
{
TRACE(("usb stack: device %s\n", added ? "added" : "removed"));
TRACE(("USB Stack: device %s\n", added ? "added" : "removed"));
usb_driver_info *element = fDriverList;
while (element) {
if ((added && element->notify_hooks.device_added != NULL)
|| (!added && element->notify_hooks.device_removed != NULL)) {
status_t result = device->ReportDevice(element->support_descriptors,
element->support_descriptor_count,
&element->notify_hooks, &element->cookies, added);
status_t result = device->ReportDevice(element->support_descriptors,
element->support_descriptor_count, &element->notify_hooks,
&element->cookies, added);
if (result == B_OK) {
const char *name = element->driver_name;
if (element->republish_driver_name)
name = element->republish_driver_name;
int devFS = open("/dev", O_WRONLY);
write(devFS, name, strlen(name));
close(devFS);
}
if (result >= B_OK) {
// the device is supported by this driver. it either got notified
// already by the hooks or it is not loaded at this time. in any
// case we will rescan the driver so it either is loaded and can
// scan for supported devices or its publish_devices hook will be
// called to expose new devices.
const char *name = element->driver_name;
if (element->republish_driver_name)
name = element->republish_driver_name;
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
// the R5 way to republish a device in devfs
int devFS = open("/dev", O_WRONLY);
write(devFS, name, strlen(name));
close(devFS);
#else
// use the private devfs API under Haiku
//devfs_rescan_driver(name);
#endif
}
element = element->link;
@@ -303,10 +312,39 @@ Stack::RegisterDriver(const char *driverName,
const usb_support_descriptor *descriptors,
size_t descriptorCount, const char *republishDriverName)
{
TRACE(("usb stack: register driver \"%s\"\n", driverName));
TRACE(("USB Stack: register driver \"%s\"\n", driverName));
if (!driverName)
return B_BAD_VALUE;
if (!Lock())
return B_ERROR;
usb_driver_info *element = fDriverList;
while (element) {
if (strcmp(element->driver_name, driverName) == 0) {
// we already have an entry for this driver, just update it
free((char *)element->republish_driver_name);
element->republish_driver_name = strdup(republishDriverName);
free(element->support_descriptors);
size_t descriptorsSize = descriptorCount * sizeof(usb_support_descriptor);
element->support_descriptors = (usb_support_descriptor *)malloc(descriptorsSize);
memcpy(element->support_descriptors, descriptors, descriptorsSize);
element->support_descriptor_count = descriptorCount;
Unlock();
return B_OK;
}
element = element->link;
}
// this is a new driver, add it to the driver list
usb_driver_info *info = new(std::nothrow) usb_driver_info;
if (!info)
if (!info) {
Unlock();
return B_NO_MEMORY;
}
info->driver_name = strdup(driverName);
info->republish_driver_name = strdup(republishDriverName);
@@ -321,11 +359,6 @@ Stack::RegisterDriver(const char *driverName,
info->cookies = NULL;
info->link = NULL;
if (!Lock()) {
delete info;
return B_ERROR;
}
if (fDriverList) {
usb_driver_info *element = fDriverList;
while (element->link)
@@ -343,16 +376,11 @@ Stack::RegisterDriver(const char *driverName,
status_t
Stack::InstallNotify(const char *driverName, const usb_notify_hooks *hooks)
{
TRACE(("usb stack: installing notify hooks for driver \"%s\"\n", driverName));
TRACE(("USB Stack: installing notify hooks for driver \"%s\"\n", driverName));
usb_driver_info *element = fDriverList;
while (element) {
if (strcmp(element->driver_name, driverName) == 0) {
// ensure that no devices are added/removed while we are
// reporting devices
if (benaphore_lock(&fExploreLock) != B_OK)
return B_ERROR;
// inform driver about any already present devices
for (int32 i = 0; i < fBusManagers.Count(); i++) {
Hub *rootHub = fBusManagers.ElementAt(i)->GetRootHub();
@@ -366,7 +394,6 @@ Stack::InstallNotify(const char *driverName, const usb_notify_hooks *hooks)
element->notify_hooks.device_added = hooks->device_added;
element->notify_hooks.device_removed = hooks->device_removed;
benaphore_unlock(&fExploreLock);
return B_OK;
}
@@ -380,16 +407,11 @@ Stack::InstallNotify(const char *driverName, const usb_notify_hooks *hooks)
status_t
Stack::UninstallNotify(const char *driverName)
{
TRACE(("usb stack: uninstalling notify hooks for driver \"%s\"\n", driverName));
TRACE(("USB Stack: uninstalling notify hooks for driver \"%s\"\n", driverName));
usb_driver_info *element = fDriverList;
while (element) {
if (strcmp(element->driver_name, driverName) == 0) {
// ensure that no devices are added/removed while we are
// reporting devices
if (benaphore_lock(&fExploreLock) != B_OK)
return B_ERROR;
// trigger the device removed hook
for (int32 i = 0; i < fBusManagers.Count(); i++) {
Hub *rootHub = fBusManagers.ElementAt(i)->GetRootHub();
@@ -401,7 +423,6 @@ Stack::UninstallNotify(const char *driverName)
element->notify_hooks.device_added = NULL;
element->notify_hooks.device_removed = NULL;
benaphore_unlock(&fExploreLock);
return B_OK;
}
+19 -19
View File
@@ -43,7 +43,7 @@ bus_std_ops(int32 op, ...)
}
case B_MODULE_UNINIT:
TRACE(("usb_module: bus module: uninit\n"));
TRACE(("usb_module: uninit\n"));
delete gUSBStack;
gUSBStack = NULL;
break;
@@ -83,7 +83,7 @@ uninstall_notify(const char *driverName)
const usb_device_descriptor *
get_device_descriptor(usb_device device)
{
TRACE(("usb_module: get_device_descriptor(0x%08x)\n", device));
TRACE(("usb_module: get_device_descriptor(%ld)\n", device));
Object *object = gUSBStack->GetObject(device);
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return NULL;
@@ -95,7 +95,7 @@ get_device_descriptor(usb_device device)
const usb_configuration_info *
get_nth_configuration(usb_device device, uint index)
{
TRACE(("usb_module: get_nth_configuration(0x%08x, %d)\n", device, index));
TRACE(("usb_module: get_nth_configuration(%ld, %d)\n", device, index));
Object *object = gUSBStack->GetObject(device);
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return NULL;
@@ -107,7 +107,7 @@ get_nth_configuration(usb_device device, uint index)
const usb_configuration_info *
get_configuration(usb_device device)
{
TRACE(("usb_module: get_configuration(0x%08x)\n", device));
TRACE(("usb_module: get_configuration(%ld)\n", device));
Object *object = gUSBStack->GetObject(device);
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return NULL;
@@ -120,7 +120,7 @@ status_t
set_configuration(usb_device device,
const usb_configuration_info *configuration)
{
TRACE(("usb_module: set_configuration(0x%08x, 0x%08x)\n", device, configuration));
TRACE(("usb_module: set_configuration(%ld, 0x%08lx)\n", device, configuration));
Object *object = gUSBStack->GetObject(device);
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return B_DEV_INVALID_PIPE;
@@ -132,7 +132,7 @@ set_configuration(usb_device device,
status_t
set_alt_interface(usb_device device, const usb_interface_info *interface)
{
TRACE(("usb_module: set_alt_interface(0x%08x, 0x%08x)\n", device, interface));
TRACE(("usb_module: set_alt_interface(%ld, 0x%08lx)\n", device, interface));
Object *object = gUSBStack->GetObject(device);
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return B_DEV_INVALID_PIPE;
@@ -144,7 +144,7 @@ set_alt_interface(usb_device device, const usb_interface_info *interface)
status_t
set_feature(usb_id handle, uint16 selector)
{
TRACE(("usb_module: set_feature(0x%08x, %d)\n", handle, selector));
TRACE(("usb_module: set_feature(%ld, %d)\n", handle, selector));
Object *object = gUSBStack->GetObject(handle);
if (!object)
return B_DEV_INVALID_PIPE;
@@ -156,7 +156,7 @@ set_feature(usb_id handle, uint16 selector)
status_t
clear_feature(usb_id handle, uint16 selector)
{
TRACE(("usb_module: clear_feature(0x%08x, %d)\n", handle, selector));
TRACE(("usb_module: clear_feature(%ld, %d)\n", handle, selector));
Object *object = gUSBStack->GetObject(handle);
if (!object)
return B_DEV_INVALID_PIPE;
@@ -168,7 +168,7 @@ clear_feature(usb_id handle, uint16 selector)
status_t
get_status(usb_id handle, uint16 *status)
{
TRACE(("usb_module: get_status(0x%08x, 0x%08x)\n", handle, status));
TRACE(("usb_module: get_status(%ld, 0x%08lx)\n", handle, status));
if (!status)
return B_BAD_VALUE;
@@ -184,7 +184,7 @@ status_t
get_descriptor(usb_device device, uint8 type, uint8 index, uint16 languageID,
void *data, size_t dataLength, size_t *actualLength)
{
TRACE(("usb_module: get_descriptor(0x%08x, 0x%02x, 0x%02x, 0x%04x, 0x%08x, %d, 0x%08x)\n", device, type, index, languageID, data, dataLength, actualLength));
TRACE(("usb_module: get_descriptor(%ld, 0x%02x, 0x%02x, 0x%04x, 0x%08lx, %ld, 0x%08lx)\n", device, type, index, languageID, data, dataLength, actualLength));
Object *object = gUSBStack->GetObject(device);
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return B_DEV_INVALID_PIPE;
@@ -198,7 +198,7 @@ status_t
send_request(usb_device device, uint8 requestType, uint8 request,
uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength)
{
TRACE(("usb_module: send_request(0x%08x, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, 0x%08x, 0x%08x)\n", device, requestType, request, value, index, length, data, actualLength));
TRACE(("usb_module: send_request(%ld, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, 0x%08lx, 0x%08lx)\n", device, requestType, request, value, index, length, data, actualLength));
Object *object = gUSBStack->GetObject(device);
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return B_DEV_INVALID_PIPE;
@@ -213,7 +213,7 @@ queue_request(usb_device device, uint8 requestType, uint8 request,
uint16 value, uint16 index, uint16 length, void *data,
usb_callback_func callback, void *callbackCookie)
{
TRACE(("usb_module: queue_request(0x%08x, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, 0x%08x, 0x%08x, 0x%08x)\n", device, requestType, request, value, index, length, data, callback, callbackCookie));
TRACE(("usb_module: queue_request(%ld, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %ld, 0x%08lx, 0x%08lx, 0x%08lx)\n", device, requestType, request, value, index, length, data, callback, callbackCookie));
Object *object = gUSBStack->GetObject(device);
if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
return B_DEV_INVALID_PIPE;
@@ -227,7 +227,7 @@ status_t
queue_interrupt(usb_pipe pipe, void *data, size_t dataLength,
usb_callback_func callback, void *callbackCookie)
{
TRACE(("usb_module: queue_interrupt(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, data, dataLength, callback, callbackCookie));
TRACE(("usb_module: queue_interrupt(%ld, 0x%08lx, %ld, 0x%08lx, 0x%08lx)\n", pipe, data, dataLength, callback, callbackCookie));
Object *object = gUSBStack->GetObject(pipe);
if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0)
return B_DEV_INVALID_PIPE;
@@ -241,7 +241,7 @@ status_t
queue_bulk(usb_pipe pipe, void *data, size_t dataLength,
usb_callback_func callback, void *callbackCookie)
{
TRACE(("usb_module: queue_bulk(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, data, dataLength, callback, callbackCookie));
TRACE(("usb_module: queue_bulk(%ld, 0x%08lx, %ld, 0x%08lx, 0x%08lx)\n", pipe, data, dataLength, callback, callbackCookie));
Object *object = gUSBStack->GetObject(pipe);
if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0)
return B_DEV_INVALID_PIPE;
@@ -255,7 +255,7 @@ status_t
queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount,
usb_callback_func callback, void *callbackCookie)
{
TRACE(("usb_module: queue_bulk(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, vector, vectorCount, callback, callbackCookie));
TRACE(("usb_module: queue_bulk(%ld, 0x%08lx, %ld, 0x%08lx, 0x%08lx)\n", pipe, vector, vectorCount, callback, callbackCookie));
Object *object = gUSBStack->GetObject(pipe);
if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0)
return B_DEV_INVALID_PIPE;
@@ -271,7 +271,7 @@ queue_isochronous(usb_pipe pipe, void *data, size_t dataLength,
uint32 *startingFrameNumber, uint32 flags, usb_callback_func callback,
void *callbackCookie)
{
TRACE(("usb_module: queue_isochronous(0x%08x, 0x%08x, %d, 0x%08x, %d, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", pipe, data, dataLength, packetDesc, packetCount, startingFrameNumber, flags, callback, callbackCookie));
TRACE(("usb_module: queue_isochronous(%ld, 0x%08lx, %ld, 0x%08lx, %ld, 0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n", pipe, data, dataLength, packetDesc, packetCount, startingFrameNumber, flags, callback, callbackCookie));
Object *object = gUSBStack->GetObject(pipe);
if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0)
return B_DEV_INVALID_PIPE;
@@ -286,7 +286,7 @@ status_t
set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets,
uint16 maxBufferDurationMS, uint16 sampleSize)
{
TRACE(("usb_module: set_pipe_policy(0x%08x, %d, %d, %d)\n", pipe, maxQueuedPackets, maxBufferDurationMS, sampleSize));
TRACE(("usb_module: set_pipe_policy(%ld, %d, %d, %d)\n", pipe, maxQueuedPackets, maxBufferDurationMS, sampleSize));
Object *object = gUSBStack->GetObject(pipe);
if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0)
return B_DEV_INVALID_PIPE;
@@ -299,7 +299,7 @@ set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets,
status_t
cancel_queued_transfers(usb_pipe pipe)
{
TRACE(("usb_module: cancel_queued_transfers(0x%08x)\n", pipe));
TRACE(("usb_module: cancel_queued_transfers(%ld)\n", pipe));
Object *object = gUSBStack->GetObject(pipe);
if (!object || (object->Type() & USB_OBJECT_PIPE) == 0)
return B_DEV_INVALID_PIPE;
@@ -311,7 +311,7 @@ cancel_queued_transfers(usb_pipe pipe)
status_t
usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize)
{
TRACE(("usb_module: usb_ioctl(0x%08x, 0x%08x, %d)\n", opcode, buffer, bufferSize));
TRACE(("usb_module: usb_ioctl(0x%08lx, 0x%08lx, %ld)\n", opcode, buffer, bufferSize));
switch (opcode) {
case 'DNAM': {
+15 -6
View File
@@ -15,7 +15,6 @@
#include "BeOSCompatibility.h"
//#define TRACE_USB
#ifdef TRACE_USB
#define TRACE(x) dprintf x
#define TRACE_ERROR(x) dprintf x
@@ -135,7 +134,6 @@ static int32 ExploreThread(void *data);
bool fStopThreads;
benaphore fLock;
benaphore fExploreLock;
PhysicalMemoryAllocator *fAllocator;
uint32 fObjectIndex;
@@ -149,7 +147,7 @@ static int32 ExploreThread(void *data);
/*
* This class manages a bus. It is created by the Stack object
* after a host controller gives positive feedback on whether the hardware
* is found.
* is found.
*/
class BusManager {
public:
@@ -162,8 +160,11 @@ virtual status_t InitCheck();
void Unlock();
int8 AllocateAddress();
Device *AllocateNewDevice(Hub *parent,
void FreeAddress(int8 address);
Device *AllocateDevice(Hub *parent,
usb_speed speed);
void FreeDevice(Device *device);
virtual status_t Start();
virtual status_t Stop();
@@ -185,7 +186,10 @@ private:
ControlPipe *_GetDefaultPipe(usb_speed);
benaphore fLock;
bool fDeviceMap[128];
int8 fDeviceIndex;
ControlPipe *fDefaultPipes[USB_SPEED_MAX + 1];
Hub *fRootHub;
Object *fRootObject;
@@ -410,6 +414,7 @@ virtual status_t GetDescriptor(uint8 descriptorType,
void *data, size_t dataLength,
size_t *actualLength);
int8 DeviceAddress() const { return fDeviceAddress; };
const usb_device_descriptor *DeviceDescriptor() const;
const usb_configuration_info *Configuration() const;
@@ -442,8 +447,6 @@ private:
usb_configuration_info *fCurrentConfiguration;
usb_speed fSpeed;
int8 fDeviceAddress;
size_t fMaxPacketIn[16];
size_t fMaxPacketOut[16];
ControlPipe *fDefaultPipe;
};
@@ -454,6 +457,10 @@ public:
usb_device_descriptor &desc,
int8 deviceAddress,
usb_speed speed);
virtual ~Hub();
bool Lock();
void Unlock();
virtual uint32 Type() { return USB_OBJECT_DEVICE | USB_OBJECT_HUB; };
@@ -480,6 +487,8 @@ virtual status_t BuildDeviceName(char *string,
Device *device);
private:
benaphore fLock;
InterruptPipe *fInterruptPipe;
usb_hub_descriptor fHubDescriptor;
@@ -41,11 +41,11 @@ struct memory_chunk
struct usb_request_data
{
uint8 RequestType;
uint8 Request;
uint16 Value;
uint16 Index;
uint16 Length;
uint8 RequestType;
uint8 Request;
uint16 Value;
uint16 Index;
uint16 Length;
};