If device allocation fails, retry the attach process, i.e. reset and initialize
the device again. Makes Axel's USB stick work and might also help with other (broken) devices. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36234 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
a1b2e9e959
commit
696914f907
@ -218,60 +218,65 @@ Hub::Explore(change_item **changeList)
|
|||||||
// new device attached!
|
// new device attached!
|
||||||
TRACE_ALWAYS("port %ld: new device connected\n", i);
|
TRACE_ALWAYS("port %ld: new device connected\n", i);
|
||||||
|
|
||||||
// wait some time for the device to power up
|
int32 retry = 2;
|
||||||
snooze(USB_DELAY_DEVICE_POWER_UP);
|
while (retry--) {
|
||||||
|
// wait some time for the device to power up
|
||||||
|
snooze(USB_DELAY_DEVICE_POWER_UP);
|
||||||
|
|
||||||
// reset the port, this will also enable it
|
// reset the port, this will also enable it
|
||||||
result = ResetPort(i);
|
result = ResetPort(i);
|
||||||
if (result < B_OK) {
|
if (result < B_OK) {
|
||||||
TRACE_ERROR("resetting port %ld failed\n", i);
|
TRACE_ERROR("resetting port %ld failed\n", i);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = UpdatePortStatus(i);
|
result = UpdatePortStatus(i);
|
||||||
if (result < B_OK)
|
if (result < B_OK)
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
if ((fPortStatus[i].status & PORT_STATUS_CONNECTION) == 0) {
|
if ((fPortStatus[i].status & PORT_STATUS_CONNECTION) == 0) {
|
||||||
// device has vanished after reset, ignore
|
// device has vanished after reset, ignore
|
||||||
TRACE("device disappeared on reset\n");
|
TRACE("device disappeared on reset\n");
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fChildren[i] != NULL) {
|
if (fChildren[i] != NULL) {
|
||||||
TRACE_ERROR("new device on a port that is already in use\n");
|
TRACE_ERROR("new device on a port that is already in "
|
||||||
fChildren[i]->Changed(changeList, false);
|
"use\n");
|
||||||
fChildren[i] = NULL;
|
fChildren[i]->Changed(changeList, false);
|
||||||
}
|
fChildren[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
if (fPortStatus[i].status & PORT_STATUS_HIGH_SPEED)
|
if (fPortStatus[i].status & PORT_STATUS_HIGH_SPEED)
|
||||||
speed = USB_SPEED_HIGHSPEED;
|
speed = USB_SPEED_HIGHSPEED;
|
||||||
|
|
||||||
// either let the device inherit our addresses (if we are
|
// either let the device inherit our addresses (if we are
|
||||||
// already potentially using a transaction translator) or set
|
// already potentially using a transaction translator) or
|
||||||
// ourselfs as the hub when we might become the transaction
|
// set ourselfs as the hub when we might become the
|
||||||
// translator for the device.
|
// transaction translator for the device.
|
||||||
int8 hubAddress = HubAddress();
|
int8 hubAddress = HubAddress();
|
||||||
uint8 hubPort = HubPort();
|
uint8 hubPort = HubPort();
|
||||||
if (Speed() == USB_SPEED_HIGHSPEED) {
|
if (Speed() == USB_SPEED_HIGHSPEED) {
|
||||||
hubAddress = DeviceAddress();
|
hubAddress = DeviceAddress();
|
||||||
hubPort = i + 1;
|
hubPort = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Device *newDevice = GetBusManager()->AllocateDevice(this,
|
Device *newDevice = GetBusManager()->AllocateDevice(this,
|
||||||
hubAddress, hubPort, speed);
|
hubAddress, hubPort, speed);
|
||||||
|
|
||||||
if (newDevice) {
|
if (newDevice) {
|
||||||
newDevice->Changed(changeList, true);
|
newDevice->Changed(changeList, true);
|
||||||
fChildren[i] = newDevice;
|
fChildren[i] = newDevice;
|
||||||
} else {
|
break;
|
||||||
// the device failed to setup correctly, disable the port
|
} else {
|
||||||
// so that the device doesn't get in the way of future
|
// the device failed to setup correctly, disable the
|
||||||
// addressing.
|
// port so that the device doesn't get in the way of
|
||||||
DisablePort(i);
|
// future addressing.
|
||||||
|
DisablePort(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Device removed...
|
// Device removed...
|
||||||
|
Loading…
Reference in New Issue
Block a user