* Moved around some initialization to avoid problems when deleting incompletely created objects

* Also move waiting for the first explore to run through out of the constructor to reduce delays
* Remove the old device when a new one is connected to the same port - this could happen when you very quickly un- and replug a device

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21042 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2007-05-06 15:17:00 +00:00
parent e1a99f77d4
commit a49633c222
2 changed files with 30 additions and 15 deletions
+25 -10
View File
@@ -13,10 +13,15 @@
Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
usb_speed speed)
: Device(parent, desc, deviceAddress, speed)
: Device(parent, desc, deviceAddress, speed),
fInterruptPipe(NULL)
{
TRACE(("USB Hub %d: creating hub\n", DeviceAddress()));
memset(&fHubDescriptor, 0, sizeof(fHubDescriptor));
for (int32 i = 0; i < 8; i++)
fChildren[i] = NULL;
if (!fInitOK) {
TRACE_ERROR(("USB Hub %d: device failed to initialize\n", DeviceAddress()));
return;
@@ -30,9 +35,6 @@ Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
return;
}
for (int32 i = 0; i < 8; i++)
fChildren[i] = NULL;
if (fDeviceDescriptor.device_class != 9) {
TRACE_ERROR(("USB Hub %d: wrong class! bailing out\n", DeviceAddress()));
return;
@@ -58,6 +60,11 @@ Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
TRACE(("\tdevice_removeable:...0x%02x\n", fHubDescriptor.device_removeable));
TRACE(("\tpower_control_mask:..0x%02x\n", fHubDescriptor.power_control_mask));
if (fHubDescriptor.num_ports > 8) {
TRACE(("USB Hub %d: hub supports more ports than we do (%d vs. 8)\n", DeviceAddress(), fHubDescriptor.num_ports));
fHubDescriptor.num_ports = 8;
}
Object *object = GetStack()->GetObject(Configuration()->interface->active->endpoint[0].handle);
if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) {
TRACE_ERROR(("USB Hub %d: no interrupt pipe found\n", DeviceAddress()));
@@ -183,12 +190,6 @@ void
Hub::Explore()
{
for (int32 i = 0; i < fHubDescriptor.num_ports; i++) {
if (i >= 8) {
TRACE(("USB Hub %d: hub supports more ports than we do (%d)\n", DeviceAddress(), fHubDescriptor.num_ports));
fHubDescriptor.num_ports = 8;
continue;
}
status_t result = UpdatePortStatus(i);
if (result < B_OK)
continue;
@@ -228,6 +229,20 @@ Hub::Explore()
continue;
}
if (fChildren[i]) {
TRACE_ERROR(("USB Hub %d: new device on a port that is already in use\n", DeviceAddress()));
// Remove previous device first
TRACE(("USB Hub %d: removing device 0x%08lx\n", DeviceAddress(), fChildren[i]));
GetStack()->NotifyDeviceChange(fChildren[i], false);
if (Lock()) {
GetBusManager()->FreeDevice(fChildren[i]);
fChildren[i] = NULL;
Unlock();
}
}
usb_speed speed = USB_SPEED_FULLSPEED;
if (fPortStatus[i].status & PORT_STATUS_LOW_SPEED)
speed = USB_SPEED_LOWSPEED;
@@ -75,11 +75,6 @@ Stack::Stack()
fExploreThread = spawn_kernel_thread(ExploreThread, "usb explore",
B_LOW_PRIORITY, this);
resume_thread(fExploreThread);
// wait for the first explore to complete
// this ensures that we get all initial devices under InstallNotify
while (!fFirstExploreDone)
snooze(1000);
}
@@ -380,6 +375,11 @@ Stack::InstallNotify(const char *driverName, const usb_notify_hooks *hooks)
{
TRACE(("USB Stack: installing notify hooks for driver \"%s\"\n", driverName));
// wait for the first explore to complete
// this ensures that we get all initial devices
while (!fFirstExploreDone)
snooze(1000);
usb_driver_info *element = fDriverList;
while (element) {
if (strcmp(element->driver_name, driverName) == 0) {