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 Device::Device(Object *parent, usb_device_descriptor &desc, int8 deviceAddress, 14 usb_speed speed) 15 : Object(parent), 16 fDeviceDescriptor(desc), 17 fInitOK(false), 18 fConfigurations(NULL), 19 fCurrentConfiguration(NULL), 20 fSpeed(speed), 21 fDeviceAddress(deviceAddress) 22 { 23 TRACE(("USB Device %d: creating device\n", fDeviceAddress)); 24 25 fDefaultPipe = new(std::nothrow) ControlPipe(this, deviceAddress, 0, 26 fSpeed, fDeviceDescriptor.max_packet_size_0); 27 if (!fDefaultPipe) { 28 TRACE_ERROR(("USB Device %d: could not allocate default pipe\n", fDeviceAddress)); 29 return; 30 } 31 32 // Get the device descriptor 33 // We already have a part of it, but we want it all 34 size_t actualLength; 35 status_t status = GetDescriptor(USB_DESCRIPTOR_DEVICE, 0, 0, 36 (void *)&fDeviceDescriptor, sizeof(fDeviceDescriptor), &actualLength); 37 38 if (status < B_OK || actualLength != sizeof(fDeviceDescriptor)) { 39 TRACE_ERROR(("USB Device %d: error while getting the device descriptor\n", fDeviceAddress)); 40 return; 41 } 42 43 TRACE(("full device descriptor for device %d:\n", fDeviceAddress)); 44 TRACE(("\tlength:..............%d\n", fDeviceDescriptor.length)); 45 TRACE(("\tdescriptor_type:.....0x%04x\n", fDeviceDescriptor.descriptor_type)); 46 TRACE(("\tusb_version:.........0x%04x\n", fDeviceDescriptor.usb_version)); 47 TRACE(("\tdevice_class:........0x%02x\n", fDeviceDescriptor.device_class)); 48 TRACE(("\tdevice_subclass:.....0x%02x\n", fDeviceDescriptor.device_subclass)); 49 TRACE(("\tdevice_protocol:.....0x%02x\n", fDeviceDescriptor.device_protocol)); 50 TRACE(("\tmax_packet_size_0:...%d\n", fDeviceDescriptor.max_packet_size_0)); 51 TRACE(("\tvendor_id:...........0x%04x\n", fDeviceDescriptor.vendor_id)); 52 TRACE(("\tproduct_id:..........0x%04x\n", fDeviceDescriptor.product_id)); 53 TRACE(("\tdevice_version:......0x%04x\n", fDeviceDescriptor.device_version)); 54 TRACE(("\tmanufacturer:........0x%02x\n", fDeviceDescriptor.manufacturer)); 55 TRACE(("\tproduct:.............0x%02x\n", fDeviceDescriptor.product)); 56 TRACE(("\tserial_number:.......0x%02x\n", fDeviceDescriptor.serial_number)); 57 TRACE(("\tnum_configurations:..%d\n", fDeviceDescriptor.num_configurations)); 58 59 // Get the configurations 60 fConfigurations = (usb_configuration_info *)malloc( 61 fDeviceDescriptor.num_configurations * sizeof(usb_configuration_info)); 62 if (fConfigurations == NULL) { 63 TRACE_ERROR(("USB Device %d: out of memory during config creations!\n", fDeviceAddress)); 64 return; 65 } 66 67 for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) { 68 usb_configuration_descriptor configDescriptor; 69 status = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i, 0, 70 (void *)&configDescriptor, sizeof(usb_configuration_descriptor), 71 &actualLength); 72 73 if (status < B_OK || actualLength != sizeof(usb_configuration_descriptor)) { 74 TRACE_ERROR(("USB Device %d: error fetching configuration %ld\n", fDeviceAddress, i)); 75 return; 76 } 77 78 TRACE(("USB Device %d: configuration %ld\n", fDeviceAddress, i)); 79 TRACE(("\tlength:..............%d\n", configDescriptor.length)); 80 TRACE(("\tdescriptor_type:.....0x%02x\n", configDescriptor.descriptor_type)); 81 TRACE(("\ttotal_length:........%d\n", configDescriptor.total_length)); 82 TRACE(("\tnumber_interfaces:...%d\n", configDescriptor.number_interfaces)); 83 TRACE(("\tconfiguration_value:.0x%02x\n", configDescriptor.configuration_value)); 84 TRACE(("\tconfiguration:.......0x%02x\n", configDescriptor.configuration)); 85 TRACE(("\tattributes:..........0x%02x\n", configDescriptor.attributes)); 86 TRACE(("\tmax_power:...........%d\n", configDescriptor.max_power)); 87 88 uint8 *configData = (uint8 *)malloc(configDescriptor.total_length); 89 status = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i, 0, 90 (void *)configData, configDescriptor.total_length, &actualLength); 91 92 if (status < B_OK || actualLength != configDescriptor.total_length) { 93 TRACE_ERROR(("USB Device %d: error fetching full configuration descriptor %ld\n", fDeviceAddress, i)); 94 return; 95 } 96 97 usb_configuration_descriptor *configuration = (usb_configuration_descriptor *)configData; 98 fConfigurations[i].descr = configuration; 99 fConfigurations[i].interface_count = configuration->number_interfaces; 100 fConfigurations[i].interface = (usb_interface_list *)malloc( 101 configuration->number_interfaces * sizeof(usb_interface_list)); 102 memset(fConfigurations[i].interface, 0, 103 configuration->number_interfaces * sizeof(usb_interface_list)); 104 105 usb_interface_info *currentInterface = NULL; 106 uint32 descriptorStart = sizeof(usb_configuration_descriptor); 107 while (descriptorStart < actualLength) { 108 switch (configData[descriptorStart + 1]) { 109 case USB_DESCRIPTOR_INTERFACE: { 110 TRACE(("USB Device %d: got interface descriptor\n", fDeviceAddress)); 111 usb_interface_descriptor *interfaceDescriptor = (usb_interface_descriptor *)&configData[descriptorStart]; 112 TRACE(("\tlength:.............%d\n", interfaceDescriptor->length)); 113 TRACE(("\tdescriptor_type:....0x%02x\n", interfaceDescriptor->descriptor_type)); 114 TRACE(("\tinterface_number:...%d\n", interfaceDescriptor->interface_number)); 115 TRACE(("\talternate_setting:..%d\n", interfaceDescriptor->alternate_setting)); 116 TRACE(("\tnum_endpoints:......%d\n", interfaceDescriptor->num_endpoints)); 117 TRACE(("\tinterface_class:....0x%02x\n", interfaceDescriptor->interface_class)); 118 TRACE(("\tinterface_subclass:.0x%02x\n", interfaceDescriptor->interface_subclass)); 119 TRACE(("\tinterface_protocol:.0x%02x\n", interfaceDescriptor->interface_protocol)); 120 TRACE(("\tinterface:..........%d\n", interfaceDescriptor->interface)); 121 122 usb_interface_list *interfaceList = 123 &fConfigurations[i].interface[interfaceDescriptor->interface_number]; 124 125 /* allocate this alternate */ 126 interfaceList->alt_count++; 127 interfaceList->alt = (usb_interface_info *)realloc( 128 interfaceList->alt, interfaceList->alt_count 129 * sizeof(usb_interface_info)); 130 interfaceList->active = interfaceList->alt; 131 132 /* setup this alternate */ 133 usb_interface_info *interfaceInfo = 134 &interfaceList->alt[interfaceList->alt_count - 1]; 135 interfaceInfo->descr = interfaceDescriptor; 136 interfaceInfo->endpoint_count = 0; 137 interfaceInfo->endpoint = NULL; 138 interfaceInfo->generic_count = 0; 139 interfaceInfo->generic = NULL; 140 141 Interface *interface = new(std::nothrow) Interface(this, 142 interfaceDescriptor->interface_number); 143 interfaceInfo->handle = interface->USBID(); 144 145 currentInterface = interfaceInfo; 146 break; 147 } 148 149 case USB_DESCRIPTOR_ENDPOINT: { 150 TRACE(("USB Device %d: got endpoint descriptor\n", fDeviceAddress)); 151 usb_endpoint_descriptor *endpointDescriptor = (usb_endpoint_descriptor *)&configData[descriptorStart]; 152 TRACE(("\tlength:.............%d\n", endpointDescriptor->length)); 153 TRACE(("\tdescriptor_type:....0x%02x\n", endpointDescriptor->descriptor_type)); 154 TRACE(("\tendpoint_address:...0x%02x\n", endpointDescriptor->endpoint_address)); 155 TRACE(("\tattributes:.........0x%02x\n", endpointDescriptor->attributes)); 156 TRACE(("\tmax_packet_size:....%d\n", endpointDescriptor->max_packet_size)); 157 TRACE(("\tinterval:...........%d\n", endpointDescriptor->interval)); 158 159 if (!currentInterface) 160 break; 161 162 /* allocate this endpoint */ 163 currentInterface->endpoint_count++; 164 currentInterface->endpoint = (usb_endpoint_info *)realloc( 165 currentInterface->endpoint, 166 currentInterface->endpoint_count 167 * sizeof(usb_endpoint_info)); 168 169 /* setup this endpoint */ 170 usb_endpoint_info *endpointInfo = 171 ¤tInterface->endpoint[currentInterface->endpoint_count - 1]; 172 endpointInfo->descr = endpointDescriptor; 173 endpointInfo->handle = 0; 174 break; 175 } 176 177 default: 178 TRACE(("USB Device %d: got generic descriptor\n", fDeviceAddress)); 179 usb_generic_descriptor *genericDescriptor = (usb_generic_descriptor *)&configData[descriptorStart]; 180 TRACE(("\tlength:.............%d\n", genericDescriptor->length)); 181 TRACE(("\tdescriptor_type:....0x%02x\n", genericDescriptor->descriptor_type)); 182 183 if (!currentInterface) 184 break; 185 186 /* allocate this descriptor */ 187 currentInterface->generic_count++; 188 currentInterface->generic = (usb_descriptor **)realloc( 189 currentInterface->generic, 190 currentInterface->generic_count 191 * sizeof(usb_descriptor *)); 192 193 /* add this descriptor */ 194 currentInterface->generic[currentInterface->generic_count - 1] = 195 (usb_descriptor *)genericDescriptor; 196 break; 197 } 198 199 descriptorStart += configData[descriptorStart]; 200 } 201 } 202 203 // Set default configuration 204 TRACE(("USB Device %d: setting default configuration\n", fDeviceAddress)); 205 if (SetConfigurationAt(0) < B_OK) { 206 TRACE_ERROR(("USB Device %d: failed to set default configuration\n", fDeviceAddress)); 207 return; 208 } 209 210 fInitOK = true; 211 } 212 213 214 Device::~Device() 215 { 216 // Destroy open endpoints. Do not send a device request to unconfigure 217 // though, since we may be deleted because the device was unplugged 218 // already. 219 Unconfigure(false); 220 221 // Free all allocated resources 222 for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) { 223 usb_configuration_info *configuration = &fConfigurations[i]; 224 for (size_t j = 0; j < configuration->interface_count; j++) { 225 usb_interface_list *interfaceList = configuration->interface; 226 for (size_t k = 0; k < interfaceList->alt_count; k++) { 227 usb_interface_info *interface = &interfaceList->alt[k]; 228 delete (Interface *)GetStack()->GetObject(interface->handle); 229 free(interface->endpoint); 230 free(interface->generic); 231 } 232 233 free(interfaceList->alt); 234 } 235 236 free(configuration->interface); 237 free(configuration->descr); 238 } 239 240 free(fConfigurations); 241 delete fDefaultPipe; 242 } 243 244 245 status_t 246 Device::InitCheck() 247 { 248 if (fInitOK) 249 return B_OK; 250 251 return B_ERROR; 252 } 253 254 255 status_t 256 Device::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID, 257 void *data, size_t dataLength, size_t *actualLength) 258 { 259 return fDefaultPipe->SendRequest( 260 USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type 261 USB_REQUEST_GET_DESCRIPTOR, // request 262 (descriptorType << 8) | index, // value 263 languageID, // index 264 dataLength, // length 265 data, // buffer 266 dataLength, // buffer length 267 actualLength); // actual length 268 } 269 270 271 const usb_configuration_info * 272 Device::Configuration() const 273 { 274 return fCurrentConfiguration; 275 } 276 277 278 const usb_configuration_info * 279 Device::ConfigurationAt(uint8 index) const 280 { 281 if (index >= fDeviceDescriptor.num_configurations) 282 return NULL; 283 284 return &fConfigurations[index]; 285 } 286 287 288 status_t 289 Device::SetConfiguration(const usb_configuration_info *configuration) 290 { 291 if (!configuration) 292 return Unconfigure(true); 293 294 for (uint8 i = 0; i < fDeviceDescriptor.num_configurations; i++) { 295 if (configuration->descr->configuration_value 296 == fConfigurations[i].descr->configuration_value) 297 return SetConfigurationAt(i); 298 } 299 300 return B_BAD_VALUE; 301 } 302 303 304 status_t 305 Device::SetConfigurationAt(uint8 index) 306 { 307 if (index >= fDeviceDescriptor.num_configurations) 308 return B_BAD_VALUE; 309 if (&fConfigurations[index] == fCurrentConfiguration) 310 return B_OK; 311 312 // Destroy our open endpoints 313 Unconfigure(false); 314 315 // Tell the device to set the configuration 316 status_t result = fDefaultPipe->SendRequest( 317 USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD, // type 318 USB_REQUEST_SET_CONFIGURATION, // request 319 fConfigurations[index].descr->configuration_value, // value 320 0, // index 321 0, // length 322 NULL, // buffer 323 0, // buffer length 324 NULL); // actual length 325 326 if (result < B_OK) 327 return result; 328 329 // Set current configuration 330 fCurrentConfiguration = &fConfigurations[index]; 331 332 // Initialize all the endpoints that are now active 333 usb_interface_info *interfaceInfo = fCurrentConfiguration->interface[0].active; 334 for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) { 335 usb_endpoint_info *endpoint = &interfaceInfo->endpoint[i]; 336 Pipe *pipe = NULL; 337 338 switch (endpoint->descr->attributes & 0x03) { 339 case 0x00: /* Control Endpoint */ 340 pipe = new(std::nothrow) ControlPipe(this, fDeviceAddress, 341 endpoint->descr->endpoint_address & 0x0f, fSpeed, 342 endpoint->descr->max_packet_size); 343 break; 344 345 case 0x01: /* Isochronous Endpoint */ 346 pipe = new(std::nothrow) IsochronousPipe(this, fDeviceAddress, 347 endpoint->descr->endpoint_address & 0x0f, 348 (endpoint->descr->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out, 349 fSpeed, endpoint->descr->max_packet_size); 350 break; 351 352 case 0x02: /* Bulk Endpoint */ 353 pipe = new(std::nothrow) BulkPipe(this, fDeviceAddress, 354 endpoint->descr->endpoint_address & 0x0f, 355 (endpoint->descr->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out, 356 fSpeed, endpoint->descr->max_packet_size); 357 break; 358 359 case 0x03: /* Interrupt Endpoint */ 360 pipe = new(std::nothrow) InterruptPipe(this, fDeviceAddress, 361 endpoint->descr->endpoint_address & 0x0f, 362 (endpoint->descr->endpoint_address & 0x80) > 0 ? Pipe::In : Pipe::Out, 363 fSpeed, endpoint->descr->max_packet_size); 364 break; 365 } 366 367 endpoint->handle = pipe->USBID(); 368 } 369 370 // Wait some for the configuration being finished 371 snooze(USB_DELAY_SET_CONFIGURATION); 372 return B_OK; 373 } 374 375 376 status_t 377 Device::Unconfigure(bool atDeviceLevel) 378 { 379 // if we only want to destroy our open pipes before setting 380 // another configuration unconfigure will be called with 381 // atDevice = false. otherwise we explicitly want to unconfigure 382 // the device and have to send it the corresponding request. 383 if (atDeviceLevel) { 384 status_t result = fDefaultPipe->SendRequest( 385 USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD, // type 386 USB_REQUEST_SET_CONFIGURATION, // request 387 0, // value 388 0, // index 389 0, // length 390 NULL, // buffer 391 0, // buffer length 392 NULL); // actual length 393 394 if (result < B_OK) 395 return result; 396 397 snooze(USB_DELAY_SET_CONFIGURATION); 398 } 399 400 if (!fCurrentConfiguration) 401 return B_OK; 402 403 usb_interface_info *interfaceInfo = fCurrentConfiguration->interface[0].active; 404 for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) { 405 usb_endpoint_info *endpoint = &interfaceInfo->endpoint[i]; 406 delete (Pipe *)GetStack()->GetObject(endpoint->handle); 407 endpoint->handle = 0; 408 } 409 410 fCurrentConfiguration = NULL; 411 return B_OK; 412 } 413 414 415 const usb_device_descriptor * 416 Device::DeviceDescriptor() const 417 { 418 return &fDeviceDescriptor; 419 } 420 421 422 status_t 423 Device::ReportDevice(usb_support_descriptor *supportDescriptors, 424 uint32 supportDescriptorCount, const usb_notify_hooks *hooks, 425 usb_driver_cookie **cookies, bool added) 426 { 427 TRACE(("USB Device %d: reporting device\n", fDeviceAddress)); 428 bool supported = false; 429 if (supportDescriptorCount == 0 || supportDescriptors == NULL) 430 supported = true; 431 432 for (uint32 i = 0; !supported && i < supportDescriptorCount; i++) { 433 if ((supportDescriptors[i].vendor != 0 434 && fDeviceDescriptor.vendor_id != supportDescriptors[i].vendor) 435 || (supportDescriptors[i].product != 0 436 && fDeviceDescriptor.product_id != supportDescriptors[i].product)) 437 continue; 438 439 if ((supportDescriptors[i].dev_class == 0 440 || fDeviceDescriptor.device_class == supportDescriptors[i].dev_class) 441 && (supportDescriptors[i].dev_subclass == 0 442 || fDeviceDescriptor.device_subclass == supportDescriptors[i].dev_subclass) 443 && (supportDescriptors[i].dev_protocol == 0 444 || fDeviceDescriptor.device_protocol == supportDescriptors[i].dev_protocol)) { 445 supported = true; 446 } 447 448 // we have to check all interfaces for matching class/subclass/protocol 449 for (uint32 j = 0; !supported && j < fDeviceDescriptor.num_configurations; j++) { 450 for (uint32 k = 0; !supported && k < fConfigurations[j].interface_count; k++) { 451 for (uint32 l = 0; !supported && l < fConfigurations[j].interface[k].alt_count; l++) { 452 usb_interface_descriptor *descriptor = fConfigurations[j].interface[k].alt[l].descr; 453 if ((supportDescriptors[i].dev_class == 0 454 || descriptor->interface_class == supportDescriptors[i].dev_class) 455 && (supportDescriptors[i].dev_subclass == 0 456 || descriptor->interface_subclass == supportDescriptors[i].dev_subclass) 457 && (supportDescriptors[i].dev_protocol == 0 458 || descriptor->interface_protocol == supportDescriptors[i].dev_protocol)) { 459 supported = true; 460 } 461 } 462 } 463 } 464 } 465 466 if (!supported) 467 return B_UNSUPPORTED; 468 469 if ((added && hooks->device_added == NULL) 470 || (!added && hooks->device_removed == NULL)) { 471 // hooks are not installed, but report success to indicate that 472 // the driver supports the device 473 return B_OK; 474 } 475 476 usb_id id = USBID(); 477 if (added) { 478 usb_driver_cookie *cookie = new(std::nothrow) usb_driver_cookie; 479 if (hooks->device_added(id, &cookie->cookie) >= B_OK) { 480 cookie->device = id; 481 cookie->link = *cookies; 482 *cookies = cookie; 483 } else 484 delete cookie; 485 } else { 486 usb_driver_cookie **pointer = cookies; 487 usb_driver_cookie *cookie = *cookies; 488 while (cookie) { 489 if (cookie->device == id) 490 break; 491 pointer = &cookie->link; 492 cookie = cookie->link; 493 } 494 495 if (!cookie) { 496 // the device is supported, but there is no cookie. this most 497 // probably means that the device_added hook above failed. 498 return B_OK; 499 } 500 501 hooks->device_removed(cookie->cookie); 502 *pointer = cookie->link; 503 delete cookie; 504 } 505 506 return B_OK; 507 } 508 509 510 status_t 511 Device::BuildDeviceName(char *string, uint32 *index, size_t bufferSize, 512 Device *device) 513 { 514 if (!Parent() || (Parent()->Type() & USB_OBJECT_HUB) == 0) 515 return B_ERROR; 516 517 ((Hub *)Parent())->BuildDeviceName(string, index, bufferSize, this); 518 return B_OK; 519 } 520 521 522 status_t 523 Device::SetFeature(uint16 selector) 524 { 525 return fDefaultPipe->SendRequest( 526 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, 527 USB_REQUEST_SET_FEATURE, 528 selector, 529 0, 530 0, 531 NULL, 532 0, 533 NULL); 534 } 535 536 537 status_t 538 Device::ClearFeature(uint16 selector) 539 { 540 return fDefaultPipe->SendRequest( 541 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, 542 USB_REQUEST_CLEAR_FEATURE, 543 selector, 544 0, 545 0, 546 NULL, 547 0, 548 NULL); 549 } 550 551 552 status_t 553 Device::GetStatus(uint16 *status) 554 { 555 return fDefaultPipe->SendRequest( 556 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_IN, 557 USB_REQUEST_GET_STATUS, 558 0, 559 0, 560 2, 561 (void *)status, 562 2, 563 NULL); 564 } 565