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