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, 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 130 if (!defaultPipe) { 131 TRACE_ERROR(("USB BusManager: error getting the default pipe for speed %d\n", (int)speed)); 132 FreeAddress(deviceAddress); 133 return NULL; 134 } 135 136 status_t result = B_ERROR; 137 for (int32 i = 0; i < 15; i++) { 138 // Set the address of the device USB 1.1 spec p202 139 result = defaultPipe->SendRequest( 140 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, // type 141 USB_REQUEST_SET_ADDRESS, // request 142 deviceAddress, // value 143 0, // index 144 0, // length 145 NULL, // buffer 146 0, // buffer length 147 NULL); // actual length 148 149 if (result >= B_OK) 150 break; 151 152 snooze(USB_DELAY_SET_ADDRESS_RETRY); 153 } 154 155 if (result < B_OK) { 156 TRACE_ERROR(("USB BusManager: error while setting device address\n")); 157 FreeAddress(deviceAddress); 158 return NULL; 159 } 160 161 // Wait a bit for the device to complete addressing 162 snooze(USB_DELAY_SET_ADDRESS); 163 164 // Create a temporary pipe with the new address 165 ControlPipe pipe(parent, deviceAddress, 0, speed, 8); 166 167 // Get the device descriptor 168 // Just retrieve the first 8 bytes of the descriptor -> minimum supported 169 // size of any device. It is enough because it includes the device type. 170 171 size_t actualLength = 0; 172 usb_device_descriptor deviceDescriptor; 173 174 TRACE(("USB BusManager: getting the device descriptor\n")); 175 pipe.SendRequest( 176 USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type 177 USB_REQUEST_GET_DESCRIPTOR, // request 178 USB_DESCRIPTOR_DEVICE << 8, // value 179 0, // index 180 8, // length 181 (void *)&deviceDescriptor, // buffer 182 8, // buffer length 183 &actualLength); // actual length 184 185 if (actualLength != 8) { 186 TRACE_ERROR(("USB BusManager: error while getting the device descriptor\n")); 187 FreeAddress(deviceAddress); 188 return NULL; 189 } 190 191 TRACE(("short device descriptor for device %d:\n", deviceAddress)); 192 TRACE(("\tlength:..............%d\n", deviceDescriptor.length)); 193 TRACE(("\tdescriptor_type:.....0x%04x\n", deviceDescriptor.descriptor_type)); 194 TRACE(("\tusb_version:.........0x%04x\n", deviceDescriptor.usb_version)); 195 TRACE(("\tdevice_class:........0x%02x\n", deviceDescriptor.device_class)); 196 TRACE(("\tdevice_subclass:.....0x%02x\n", deviceDescriptor.device_subclass)); 197 TRACE(("\tdevice_protocol:.....0x%02x\n", deviceDescriptor.device_protocol)); 198 TRACE(("\tmax_packet_size_0:...%d\n", deviceDescriptor.max_packet_size_0)); 199 200 // Create a new instance based on the type (Hub or Device) 201 if (deviceDescriptor.device_class == 0x09) { 202 TRACE(("USB BusManager: creating new hub\n")); 203 Hub *hub = new(std::nothrow) Hub(parent, deviceDescriptor, 204 deviceAddress, speed); 205 if (!hub) { 206 TRACE_ERROR(("USB BusManager: no memory to allocate hub\n")); 207 FreeAddress(deviceAddress); 208 return NULL; 209 } 210 211 if (hub->InitCheck() < B_OK) { 212 TRACE_ERROR(("USB BusManager: hub failed init check\n")); 213 FreeAddress(deviceAddress); 214 delete hub; 215 return NULL; 216 } 217 218 return (Device *)hub; 219 } 220 221 TRACE(("USB BusManager: creating new device\n")); 222 Device *device = new(std::nothrow) Device(parent, deviceDescriptor, 223 deviceAddress, speed); 224 if (!device) { 225 TRACE_ERROR(("USB BusManager: no memory to allocate device\n")); 226 FreeAddress(deviceAddress); 227 return NULL; 228 } 229 230 if (device->InitCheck() < B_OK) { 231 TRACE_ERROR(("USB BusManager: device failed init check\n")); 232 FreeAddress(deviceAddress); 233 delete device; 234 return NULL; 235 } 236 237 return device; 238 } 239 240 241 void 242 BusManager::FreeDevice(Device *device) 243 { 244 FreeAddress(device->DeviceAddress()); 245 delete device; 246 } 247 248 249 status_t 250 BusManager::Start() 251 { 252 return B_OK; 253 } 254 255 256 status_t 257 BusManager::Stop() 258 { 259 return B_OK; 260 } 261 262 263 status_t 264 BusManager::SubmitTransfer(Transfer *transfer) 265 { 266 // virtual function to be overridden 267 return B_ERROR; 268 } 269 270 271 status_t 272 BusManager::CancelQueuedTransfers(Pipe *pipe) 273 { 274 // virtual function to be overridden 275 return B_ERROR; 276 } 277 278 279 status_t 280 BusManager::NotifyPipeChange(Pipe *pipe, usb_change change) 281 { 282 // virtual function to be overridden 283 return B_ERROR; 284 } 285 286 287 ControlPipe * 288 BusManager::_GetDefaultPipe(usb_speed speed) 289 { 290 if (!Lock()) 291 return NULL; 292 293 if (fDefaultPipes[speed] == NULL) { 294 fDefaultPipes[speed] = new(std::nothrow) ControlPipe(fRootObject, 295 0, 0, speed, 8); 296 } 297 298 if (!fDefaultPipes[speed]) { 299 TRACE_ERROR(("USB BusManager: failed to allocate default pipe for speed %d\n", speed)); 300 } 301 302 Unlock(); 303 return fDefaultPipes[speed]; 304 } 305