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