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, device_node* node) 14 : fInitOK(false), 15 fStack(stack), 16 fRootHub(NULL), 17 fStackIndex((uint32)-1), 18 fNode(node) 19 { 20 mutex_init(&fLock, "usb busmanager lock"); 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 mutex_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 (mutex_lock(&fLock) == B_OK); 63 } 64 65 66 void 67 BusManager::Unlock() 68 { 69 mutex_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("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("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, int8 hubAddress, uint8 hubPort, 119 usb_speed speed) 120 { 121 // Check if there is a free entry in the device map (for the device number) 122 int8 deviceAddress = AllocateAddress(); 123 if (deviceAddress < 0) { 124 TRACE_ERROR("could not allocate an address\n"); 125 return NULL; 126 } 127 128 TRACE("setting device address to %d\n", deviceAddress); 129 ControlPipe *defaultPipe = _GetDefaultPipe(speed); 130 131 if (!defaultPipe) { 132 TRACE_ERROR("error getting the default pipe for speed %d\n", speed); 133 FreeAddress(deviceAddress); 134 return NULL; 135 } 136 137 defaultPipe->SetHubInfo(hubAddress, hubPort); 138 139 status_t result = B_ERROR; 140 for (int32 i = 0; i < 3; i++) { 141 // Set the address of the device USB 1.1 spec p202 142 result = defaultPipe->SendRequest( 143 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, // type 144 USB_REQUEST_SET_ADDRESS, // request 145 deviceAddress, // value 146 0, // index 147 0, // length 148 NULL, // buffer 149 0, // buffer length 150 NULL); // actual length 151 152 if (result >= B_OK) 153 break; 154 155 snooze(USB_DELAY_SET_ADDRESS_RETRY); 156 } 157 158 if (result < B_OK) { 159 TRACE_ERROR("error while setting device address\n"); 160 FreeAddress(deviceAddress); 161 return NULL; 162 } 163 164 // Wait a bit for the device to complete addressing 165 snooze(USB_DELAY_SET_ADDRESS); 166 167 // Create a temporary pipe with the new address 168 ControlPipe pipe(fRootObject); 169 pipe.InitCommon(deviceAddress, 0, speed, Pipe::Default, 8, 0, hubAddress, 170 hubPort); 171 172 // Get the device descriptor 173 // Just retrieve the first 8 bytes of the descriptor -> minimum supported 174 // size of any device. It is enough because it includes the device type. 175 176 size_t actualLength = 0; 177 usb_device_descriptor deviceDescriptor; 178 179 TRACE("getting the device descriptor\n"); 180 pipe.SendRequest( 181 USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type 182 USB_REQUEST_GET_DESCRIPTOR, // request 183 USB_DESCRIPTOR_DEVICE << 8, // value 184 0, // index 185 8, // length 186 (void *)&deviceDescriptor, // buffer 187 8, // buffer length 188 &actualLength); // actual length 189 190 if (actualLength != 8) { 191 TRACE_ERROR("error while getting the device descriptor\n"); 192 FreeAddress(deviceAddress); 193 return NULL; 194 } 195 196 TRACE("short device descriptor for device %d:\n", deviceAddress); 197 TRACE("\tlength:..............%d\n", deviceDescriptor.length); 198 TRACE("\tdescriptor_type:.....0x%04x\n", deviceDescriptor.descriptor_type); 199 TRACE("\tusb_version:.........0x%04x\n", deviceDescriptor.usb_version); 200 TRACE("\tdevice_class:........0x%02x\n", deviceDescriptor.device_class); 201 TRACE("\tdevice_subclass:.....0x%02x\n", deviceDescriptor.device_subclass); 202 TRACE("\tdevice_protocol:.....0x%02x\n", deviceDescriptor.device_protocol); 203 TRACE("\tmax_packet_size_0:...%d\n", deviceDescriptor.max_packet_size_0); 204 205 // Create a new instance based on the type (Hub or Device) 206 if (deviceDescriptor.device_class == 0x09) { 207 TRACE("creating new hub\n"); 208 Hub *hub = new(std::nothrow) Hub(parent, hubAddress, hubPort, 209 deviceDescriptor, deviceAddress, speed, false); 210 if (!hub) { 211 TRACE_ERROR("no memory to allocate hub\n"); 212 FreeAddress(deviceAddress); 213 return NULL; 214 } 215 216 if (hub->InitCheck() < B_OK) { 217 TRACE_ERROR("hub failed init check\n"); 218 FreeAddress(deviceAddress); 219 delete hub; 220 return NULL; 221 } 222 223 hub->RegisterNode(); 224 225 return (Device *)hub; 226 } 227 228 TRACE("creating new device\n"); 229 Device *device = new(std::nothrow) Device(parent, hubAddress, hubPort, 230 deviceDescriptor, deviceAddress, speed, false); 231 if (!device) { 232 TRACE_ERROR("no memory to allocate device\n"); 233 FreeAddress(deviceAddress); 234 return NULL; 235 } 236 237 if (device->InitCheck() < B_OK) { 238 TRACE_ERROR("device failed init check\n"); 239 FreeAddress(deviceAddress); 240 delete device; 241 return NULL; 242 } 243 244 device->RegisterNode(); 245 246 return device; 247 } 248 249 250 void 251 BusManager::FreeDevice(Device *device) 252 { 253 FreeAddress(device->DeviceAddress()); 254 delete device; 255 } 256 257 258 status_t 259 BusManager::Start() 260 { 261 fStack->AddBusManager(this); 262 fStackIndex = fStack->IndexOfBusManager(this); 263 fStack->Explore(); 264 return B_OK; 265 } 266 267 268 status_t 269 BusManager::Stop() 270 { 271 return B_OK; 272 } 273 274 275 status_t 276 BusManager::StartDebugTransfer(Transfer *transfer) 277 { 278 // virtual function to be overridden 279 return B_UNSUPPORTED; 280 } 281 282 283 status_t 284 BusManager::CheckDebugTransfer(Transfer *transfer) 285 { 286 // virtual function to be overridden 287 return B_UNSUPPORTED; 288 } 289 290 291 void 292 BusManager::CancelDebugTransfer(Transfer *transfer) 293 { 294 // virtual function to be overridden 295 } 296 297 298 status_t 299 BusManager::SubmitTransfer(Transfer *transfer) 300 { 301 // virtual function to be overridden 302 return B_ERROR; 303 } 304 305 306 status_t 307 BusManager::CancelQueuedTransfers(Pipe *pipe, bool force) 308 { 309 // virtual function to be overridden 310 return B_ERROR; 311 } 312 313 314 status_t 315 BusManager::NotifyPipeChange(Pipe *pipe, usb_change change) 316 { 317 // virtual function to be overridden 318 return B_ERROR; 319 } 320 321 322 ControlPipe * 323 BusManager::_GetDefaultPipe(usb_speed speed) 324 { 325 if (!Lock()) 326 return NULL; 327 328 if (fDefaultPipes[speed] == NULL) { 329 fDefaultPipes[speed] = new(std::nothrow) ControlPipe(fRootObject); 330 fDefaultPipes[speed]->InitCommon(0, 0, speed, Pipe::Default, 8, 0, 0, 0); 331 } 332 333 if (!fDefaultPipes[speed]) { 334 TRACE_ERROR("failed to allocate default pipe for speed %d\n", speed); 335 } 336 337 Unlock(); 338 return fDefaultPipes[speed]; 339 } 340 341