1 /* 2 * Copyright 2003-2006, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 * Niels S. Reedijk 8 */ 9 10 #include "usb_p.h" 11 12 13 BusManager::BusManager(Stack *stack) 14 : fInitOK(false), 15 fRootHub(NULL) 16 { 17 if (benaphore_init(&fLock, "usb busmanager lock") < B_OK) { 18 TRACE_ERROR(("USB BusManager: failed to create busmanager lock\n")); 19 return; 20 } 21 22 fRootObject = new(std::nothrow) Object(stack, this); 23 if (!fRootObject) 24 return; 25 26 // Clear the device map 27 for (int32 i = 0; i < 128; i++) 28 fDeviceMap[i] = false; 29 fDeviceIndex = 0; 30 31 // Set the default pipes to NULL (these will be created when needed) 32 for (int32 i = 0; i <= USB_SPEED_MAX; i++) 33 fDefaultPipes[i] = NULL; 34 35 fInitOK = true; 36 } 37 38 39 BusManager::~BusManager() 40 { 41 Lock(); 42 benaphore_destroy(&fLock); 43 for (int32 i = 0; i <= USB_SPEED_MAX; i++) 44 delete fDefaultPipes[i]; 45 delete fRootObject; 46 } 47 48 49 status_t 50 BusManager::InitCheck() 51 { 52 if (fInitOK) 53 return B_OK; 54 55 return B_ERROR; 56 } 57 58 59 bool 60 BusManager::Lock() 61 { 62 return (benaphore_lock(&fLock) == B_OK); 63 } 64 65 66 void 67 BusManager::Unlock() 68 { 69 benaphore_unlock(&fLock); 70 } 71 72 73 int8 74 BusManager::AllocateAddress() 75 { 76 if (!Lock()) 77 return -1; 78 79 int8 tries = 127; 80 int8 address = fDeviceIndex; 81 while (tries-- > 0) { 82 if (fDeviceMap[address] == false) { 83 fDeviceIndex = (address + 1) % 127; 84 fDeviceMap[address] = true; 85 Unlock(); 86 return address + 1; 87 } 88 89 address = (address + 1) % 127; 90 } 91 92 TRACE_ERROR(("USB BusManager: the busmanager has run out of device addresses\n")); 93 Unlock(); 94 return -1; 95 } 96 97 98 void 99 BusManager::FreeAddress(int8 address) 100 { 101 address--; 102 if (address < 0) 103 return; 104 105 if (!Lock()) 106 return; 107 108 if (!fDeviceMap[address]) { 109 TRACE_ERROR(("USB BusManager: freeing address %d which was not allocated\n", address)); 110 } 111 112 fDeviceMap[address] = false; 113 Unlock(); 114 } 115 116 117 Device * 118 BusManager::AllocateDevice(Hub *parent, uint8 port, usb_speed speed) 119 { 120 // Check if there is a free entry in the device map (for the device number) 121 int8 deviceAddress = AllocateAddress(); 122 if (deviceAddress < 0) { 123 TRACE_ERROR(("USB BusManager: could not allocate an address\n")); 124 return NULL; 125 } 126 127 TRACE(("USB BusManager: setting device address to %d\n", deviceAddress)); 128 ControlPipe *defaultPipe = _GetDefaultPipe(speed); 129 defaultPipe->SetHubInfo(parent->DeviceAddress(), port); 130 131 if (!defaultPipe) { 132 TRACE_ERROR(("USB BusManager: error getting the default pipe for speed %d\n", (int)speed)); 133 FreeAddress(deviceAddress); 134 return NULL; 135 } 136 137 status_t result = B_ERROR; 138 for (int32 i = 0; i < 3; i++) { 139 // Set the address of the device USB 1.1 spec p202 140 result = defaultPipe->SendRequest( 141 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, // type 142 USB_REQUEST_SET_ADDRESS, // request 143 deviceAddress, // value 144 0, // index 145 0, // length 146 NULL, // buffer 147 0, // buffer length 148 NULL); // actual length 149 150 if (result >= B_OK) 151 break; 152 153 snooze(USB_DELAY_SET_ADDRESS_RETRY); 154 } 155 156 if (result < B_OK) { 157 TRACE_ERROR(("USB BusManager: error while setting device address\n")); 158 FreeAddress(deviceAddress); 159 return NULL; 160 } 161 162 // Wait a bit for the device to complete addressing 163 snooze(USB_DELAY_SET_ADDRESS); 164 165 // Create a temporary pipe with the new address 166 ControlPipe pipe(fRootObject); 167 pipe.InitCommon(deviceAddress, 0, speed, Pipe::Default, 8, 0, 168 parent->DeviceAddress(), port); 169 170 // Get the device descriptor 171 // Just retrieve the first 8 bytes of the descriptor -> minimum supported 172 // size of any device. It is enough because it includes the device type. 173 174 size_t actualLength = 0; 175 usb_device_descriptor deviceDescriptor; 176 177 TRACE(("USB BusManager: getting the device descriptor\n")); 178 pipe.SendRequest( 179 USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type 180 USB_REQUEST_GET_DESCRIPTOR, // request 181 USB_DESCRIPTOR_DEVICE << 8, // value 182 0, // index 183 8, // length 184 (void *)&deviceDescriptor, // buffer 185 8, // buffer length 186 &actualLength); // actual length 187 188 if (actualLength != 8) { 189 TRACE_ERROR(("USB BusManager: error while getting the device descriptor\n")); 190 FreeAddress(deviceAddress); 191 return NULL; 192 } 193 194 TRACE(("short device descriptor for device %d:\n", deviceAddress)); 195 TRACE(("\tlength:..............%d\n", deviceDescriptor.length)); 196 TRACE(("\tdescriptor_type:.....0x%04x\n", deviceDescriptor.descriptor_type)); 197 TRACE(("\tusb_version:.........0x%04x\n", deviceDescriptor.usb_version)); 198 TRACE(("\tdevice_class:........0x%02x\n", deviceDescriptor.device_class)); 199 TRACE(("\tdevice_subclass:.....0x%02x\n", deviceDescriptor.device_subclass)); 200 TRACE(("\tdevice_protocol:.....0x%02x\n", deviceDescriptor.device_protocol)); 201 TRACE(("\tmax_packet_size_0:...%d\n", deviceDescriptor.max_packet_size_0)); 202 203 // Create a new instance based on the type (Hub or Device) 204 if (deviceDescriptor.device_class == 0x09) { 205 TRACE(("USB BusManager: creating new hub\n")); 206 Hub *hub = new(std::nothrow) Hub(parent, port, deviceDescriptor, 207 deviceAddress, speed, false); 208 if (!hub) { 209 TRACE_ERROR(("USB BusManager: no memory to allocate hub\n")); 210 FreeAddress(deviceAddress); 211 return NULL; 212 } 213 214 if (hub->InitCheck() < B_OK) { 215 TRACE_ERROR(("USB BusManager: hub failed init check\n")); 216 FreeAddress(deviceAddress); 217 delete hub; 218 return NULL; 219 } 220 221 return (Device *)hub; 222 } 223 224 TRACE(("USB BusManager: creating new device\n")); 225 Device *device = new(std::nothrow) Device(parent, port, deviceDescriptor, 226 deviceAddress, speed, false); 227 if (!device) { 228 TRACE_ERROR(("USB BusManager: no memory to allocate device\n")); 229 FreeAddress(deviceAddress); 230 return NULL; 231 } 232 233 if (device->InitCheck() < B_OK) { 234 TRACE_ERROR(("USB BusManager: device failed init check\n")); 235 FreeAddress(deviceAddress); 236 delete device; 237 return NULL; 238 } 239 240 return device; 241 } 242 243 244 void 245 BusManager::FreeDevice(Device *device) 246 { 247 FreeAddress(device->DeviceAddress()); 248 delete device; 249 } 250 251 252 status_t 253 BusManager::Start() 254 { 255 return B_OK; 256 } 257 258 259 status_t 260 BusManager::Stop() 261 { 262 return B_OK; 263 } 264 265 266 status_t 267 BusManager::SubmitTransfer(Transfer *transfer) 268 { 269 // virtual function to be overridden 270 return B_ERROR; 271 } 272 273 274 status_t 275 BusManager::CancelQueuedTransfers(Pipe *pipe, bool force) 276 { 277 // virtual function to be overridden 278 return B_ERROR; 279 } 280 281 282 status_t 283 BusManager::NotifyPipeChange(Pipe *pipe, usb_change change) 284 { 285 // virtual function to be overridden 286 return B_ERROR; 287 } 288 289 290 ControlPipe * 291 BusManager::_GetDefaultPipe(usb_speed speed) 292 { 293 if (!Lock()) 294 return NULL; 295 296 if (fDefaultPipes[speed] == NULL) { 297 fDefaultPipes[speed] = new(std::nothrow) ControlPipe(fRootObject); 298 fDefaultPipes[speed]->InitCommon(0, 0, speed, Pipe::Default, 8, 0, 0, 0); 299 } 300 301 if (!fDefaultPipes[speed]) { 302 TRACE_ERROR(("USB BusManager: failed to allocate default pipe for speed %d\n", speed)); 303 } 304 305 Unlock(); 306 return fDefaultPipes[speed]; 307 } 308