[haiku-commits] r36234 - haiku/trunk/src/add-ons/kernel/bus_managers/usb

Author: mmlr
Date: 2010-04-13 20:26:26 +0200 (Tue, 13 Apr 2010)
New Revision: 36234
Changeset: http://dev.haiku-os.org/changeset/36234/haiku

Modified:
   haiku/trunk/src/add-ons/kernel/bus_managers/usb/Hub.cpp
Log:
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.


Modified: haiku/trunk/src/add-ons/kernel/bus_managers/usb/Hub.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/bus_managers/usb/Hub.cpp     2010-04-13 
18:25:56 UTC (rev 36233)
+++ haiku/trunk/src/add-ons/kernel/bus_managers/usb/Hub.cpp     2010-04-13 
18:26:26 UTC (rev 36234)
@@ -218,60 +218,65 @@
                                // new device attached!
                                TRACE_ALWAYS("port %ld: new device 
connected\n", i);
 
-                               // wait some time for the device to power up
-                               snooze(USB_DELAY_DEVICE_POWER_UP);
+                               int32 retry = 2;
+                               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
-                               result = ResetPort(i);
-                               if (result < B_OK) {
-                                       TRACE_ERROR("resetting port %ld 
failed\n", i);
-                                       continue;
-                               }
+                                       // reset the port, this will also 
enable it
+                                       result = ResetPort(i);
+                                       if (result < B_OK) {
+                                               TRACE_ERROR("resetting port %ld 
failed\n", i);
+                                               break;
+                                       }
 
-                               result = UpdatePortStatus(i);
-                               if (result < B_OK)
-                                       continue;
+                                       result = UpdatePortStatus(i);
+                                       if (result < B_OK)
+                                               break;
 
-                               if ((fPortStatus[i].status & 
PORT_STATUS_CONNECTION) == 0) {
-                                       // device has vanished after reset, 
ignore
-                                       TRACE("device disappeared on reset\n");
-                                       continue;
-                               }
+                                       if ((fPortStatus[i].status & 
PORT_STATUS_CONNECTION) == 0) {
+                                               // device has vanished after 
reset, ignore
+                                               TRACE("device disappeared on 
reset\n");
+                                               break;
+                                       }
 
-                               if (fChildren[i] != NULL) {
-                                       TRACE_ERROR("new device on a port that 
is already in use\n");
-                                       fChildren[i]->Changed(changeList, 
false);
-                                       fChildren[i] = NULL;
-                               }
+                                       if (fChildren[i] != NULL) {
+                                               TRACE_ERROR("new device on a 
port that is already in "
+                                                       "use\n");
+                                               
fChildren[i]->Changed(changeList, false);
+                                               fChildren[i] = NULL;
+                                       }
 
-                               usb_speed speed = USB_SPEED_FULLSPEED;
-                               if (fPortStatus[i].status & 
PORT_STATUS_LOW_SPEED)
-                                       speed = USB_SPEED_LOWSPEED;
-                               if (fPortStatus[i].status & 
PORT_STATUS_HIGH_SPEED)
-                                       speed = USB_SPEED_HIGHSPEED;
+                                       usb_speed speed = USB_SPEED_FULLSPEED;
+                                       if (fPortStatus[i].status & 
PORT_STATUS_LOW_SPEED)
+                                               speed = USB_SPEED_LOWSPEED;
+                                       if (fPortStatus[i].status & 
PORT_STATUS_HIGH_SPEED)
+                                               speed = USB_SPEED_HIGHSPEED;
 
-                               // either let the device inherit our addresses 
(if we are
-                               // already potentially using a transaction 
translator) or set
-                               // ourselfs as the hub when we might become the 
transaction
-                               // translator for the device.
-                               int8 hubAddress = HubAddress();
-                               uint8 hubPort = HubPort();
-                               if (Speed() == USB_SPEED_HIGHSPEED) {
-                                       hubAddress = DeviceAddress();
-                                       hubPort = i + 1;
-                               }
+                                       // either let the device inherit our 
addresses (if we are
+                                       // already potentially using a 
transaction translator) or
+                                       // set ourselfs as the hub when we 
might become the
+                                       // transaction translator for the 
device.
+                                       int8 hubAddress = HubAddress();
+                                       uint8 hubPort = HubPort();
+                                       if (Speed() == USB_SPEED_HIGHSPEED) {
+                                               hubAddress = DeviceAddress();
+                                               hubPort = i + 1;
+                                       }
 
-                               Device *newDevice = 
GetBusManager()->AllocateDevice(this,
-                                       hubAddress, hubPort, speed);
+                                       Device *newDevice = 
GetBusManager()->AllocateDevice(this,
+                                               hubAddress, hubPort, speed);
 
-                               if (newDevice) {
-                                       newDevice->Changed(changeList, true);
-                                       fChildren[i] = newDevice;
-                               } else {
-                                       // the device failed to setup 
correctly, disable the port
-                                       // so that the device doesn't get in 
the way of future
-                                       // addressing.
-                                       DisablePort(i);
+                                       if (newDevice) {
+                                               newDevice->Changed(changeList, 
true);
+                                               fChildren[i] = newDevice;
+                                               break;
+                                       } else {
+                                               // the device failed to setup 
correctly, disable the
+                                               // port so that the device 
doesn't get in the way of
+                                               // future addressing.
+                                               DisablePort(i);
+                                       }
                                }
                        } else {
                                // Device removed...


Other related posts:

  • » [haiku-commits] r36234 - haiku/trunk/src/add-ons/kernel/bus_managers/usb - mmlr