* 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:
@@ -13,10 +13,15 @@
|
|||||||
|
|
||||||
Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
|
Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
|
||||||
usb_speed speed)
|
usb_speed speed)
|
||||||
: Device(parent, desc, deviceAddress, speed)
|
: Device(parent, desc, deviceAddress, speed),
|
||||||
|
fInterruptPipe(NULL)
|
||||||
{
|
{
|
||||||
TRACE(("USB Hub %d: creating hub\n", DeviceAddress()));
|
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) {
|
if (!fInitOK) {
|
||||||
TRACE_ERROR(("USB Hub %d: device failed to initialize\n", DeviceAddress()));
|
TRACE_ERROR(("USB Hub %d: device failed to initialize\n", DeviceAddress()));
|
||||||
return;
|
return;
|
||||||
@@ -30,9 +35,6 @@ Hub::Hub(Object *parent, usb_device_descriptor &desc, int8 deviceAddress,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32 i = 0; i < 8; i++)
|
|
||||||
fChildren[i] = NULL;
|
|
||||||
|
|
||||||
if (fDeviceDescriptor.device_class != 9) {
|
if (fDeviceDescriptor.device_class != 9) {
|
||||||
TRACE_ERROR(("USB Hub %d: wrong class! bailing out\n", DeviceAddress()));
|
TRACE_ERROR(("USB Hub %d: wrong class! bailing out\n", DeviceAddress()));
|
||||||
return;
|
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(("\tdevice_removeable:...0x%02x\n", fHubDescriptor.device_removeable));
|
||||||
TRACE(("\tpower_control_mask:..0x%02x\n", fHubDescriptor.power_control_mask));
|
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);
|
Object *object = GetStack()->GetObject(Configuration()->interface->active->endpoint[0].handle);
|
||||||
if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) {
|
if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) {
|
||||||
TRACE_ERROR(("USB Hub %d: no interrupt pipe found\n", DeviceAddress()));
|
TRACE_ERROR(("USB Hub %d: no interrupt pipe found\n", DeviceAddress()));
|
||||||
@@ -183,12 +190,6 @@ void
|
|||||||
Hub::Explore()
|
Hub::Explore()
|
||||||
{
|
{
|
||||||
for (int32 i = 0; i < fHubDescriptor.num_ports; i++) {
|
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);
|
status_t result = UpdatePortStatus(i);
|
||||||
if (result < B_OK)
|
if (result < B_OK)
|
||||||
continue;
|
continue;
|
||||||
@@ -228,6 +229,20 @@ Hub::Explore()
|
|||||||
continue;
|
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;
|
usb_speed speed = USB_SPEED_FULLSPEED;
|
||||||
if (fPortStatus[i].status & PORT_STATUS_LOW_SPEED)
|
if (fPortStatus[i].status & PORT_STATUS_LOW_SPEED)
|
||||||
speed = USB_SPEED_LOWSPEED;
|
speed = USB_SPEED_LOWSPEED;
|
||||||
|
|||||||
@@ -75,11 +75,6 @@ Stack::Stack()
|
|||||||
fExploreThread = spawn_kernel_thread(ExploreThread, "usb explore",
|
fExploreThread = spawn_kernel_thread(ExploreThread, "usb explore",
|
||||||
B_LOW_PRIORITY, this);
|
B_LOW_PRIORITY, this);
|
||||||
resume_thread(fExploreThread);
|
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));
|
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;
|
usb_driver_info *element = fDriverList;
|
||||||
while (element) {
|
while (element) {
|
||||||
if (strcmp(element->driver_name, driverName) == 0) {
|
if (strcmp(element->driver_name, driverName) == 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user