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(BusManager *bus, Device *parent, usb_device_descriptor &desc, 14 int8 deviceAddress, bool lowSpeed) 15 : ControlPipe(bus, deviceAddress, 16 lowSpeed ? Pipe::LowSpeed : Pipe::NormalSpeed, 17 desc.max_packet_size_0), 18 fDeviceDescriptor(desc), 19 fConfigurations(NULL), 20 fCurrentConfiguration(NULL), 21 fInitOK(false), 22 fLowSpeed(lowSpeed), 23 fBus(bus), 24 fParent(parent), 25 fDeviceAddress(deviceAddress), 26 fLock(-1), 27 fNotifyCookie(NULL) 28 { 29 TRACE(("USB Device: new device\n")); 30 31 fLock = create_sem(1, "USB Device Lock"); 32 if (fLock < B_OK) { 33 TRACE_ERROR(("USB Device: could not create locking semaphore\n")); 34 return; 35 } 36 37 set_sem_owner(fLock, B_SYSTEM_TEAM); 38 39 fMaxPacketIn[0] = fMaxPacketOut[0] = fDeviceDescriptor.max_packet_size_0; 40 41 // Get the device descriptor 42 // We already have a part of it, but we want it all 43 size_t actualLength; 44 status_t status = GetDescriptor(USB_DESCRIPTOR_DEVICE, 0, 0, 45 (void *)&fDeviceDescriptor, sizeof(fDeviceDescriptor), &actualLength); 46 47 if (status < B_OK || actualLength != sizeof(fDeviceDescriptor)) { 48 TRACE_ERROR(("USB Device: error while getting the device descriptor\n")); 49 return; 50 } 51 52 TRACE(("full device descriptor for device %d:\n", fDeviceAddress)); 53 TRACE(("\tlength:..............%d\n", fDeviceDescriptor.length)); 54 TRACE(("\tdescriptor_type:.....0x%04x\n", fDeviceDescriptor.descriptor_type)); 55 TRACE(("\tusb_version:.........0x%04x\n", fDeviceDescriptor.usb_version)); 56 TRACE(("\tdevice_class:........0x%02x\n", fDeviceDescriptor.device_class)); 57 TRACE(("\tdevice_subclass:.....0x%02x\n", fDeviceDescriptor.device_subclass)); 58 TRACE(("\tdevice_protocol:.....0x%02x\n", fDeviceDescriptor.device_protocol)); 59 TRACE(("\tmax_packet_size_0:...%d\n", fDeviceDescriptor.max_packet_size_0)); 60 TRACE(("\tvendor_id:...........0x%04x\n", fDeviceDescriptor.vendor_id)); 61 TRACE(("\tproduct_id:..........0x%04x\n", fDeviceDescriptor.product_id)); 62 TRACE(("\tdevice_version:......0x%04x\n", fDeviceDescriptor.device_version)); 63 TRACE(("\tmanufacturer:........0x%04x\n", fDeviceDescriptor.manufacturer)); 64 TRACE(("\tproduct:.............0x%02x\n", fDeviceDescriptor.product)); 65 TRACE(("\tserial_number:.......0x%02x\n", fDeviceDescriptor.serial_number)); 66 TRACE(("\tnum_configurations:..%d\n", fDeviceDescriptor.num_configurations)); 67 68 // Get the configurations 69 fConfigurations = (usb_configuration_info *)malloc( 70 fDeviceDescriptor.num_configurations * sizeof(usb_configuration_info)); 71 if (fConfigurations == NULL) { 72 TRACE_ERROR(("USB Device: out of memory during config creations!\n")); 73 return; 74 } 75 76 for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) { 77 usb_configuration_descriptor configDescriptor; 78 status = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i, 0, 79 (void *)&configDescriptor, sizeof(usb_configuration_descriptor), 80 &actualLength); 81 82 if (status < B_OK || actualLength != sizeof(usb_configuration_descriptor)) { 83 TRACE_ERROR(("USB Device %d: error fetching configuration %ld\n", fDeviceAddress, i)); 84 return; 85 } 86 87 TRACE(("USB Device %d: configuration %d\n", fDeviceAddress, i)); 88 TRACE(("\tlength:..............%d\n", configDescriptor.length)); 89 TRACE(("\tdescriptor_type:.....0x%02x\n", configDescriptor.descriptor_type)); 90 TRACE(("\ttotal_length:........%d\n", configDescriptor.total_length)); 91 TRACE(("\tnumber_interfaces:...%d\n", configDescriptor.number_interfaces)); 92 TRACE(("\tconfiguration_value:.0x%02x\n", configDescriptor.configuration_value)); 93 TRACE(("\tconfiguration:.......0x%02x\n", configDescriptor.configuration)); 94 TRACE(("\tattributes:..........0x%02x\n", configDescriptor.attributes)); 95 TRACE(("\tmax_power:...........%d\n", configDescriptor.max_power)); 96 97 uint8 *configData = (uint8 *)malloc(configDescriptor.total_length); 98 status = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i, 0, 99 (void *)configData, configDescriptor.total_length, &actualLength); 100 101 if (status < B_OK || actualLength != configDescriptor.total_length) { 102 TRACE_ERROR(("USB Device %d: error fetching full configuration descriptor %ld\n", fDeviceAddress, i)); 103 return; 104 } 105 106 usb_configuration_descriptor *configuration = (usb_configuration_descriptor *)configData; 107 fConfigurations[i].descr = configuration; 108 fConfigurations[i].interface_count = configuration->number_interfaces; 109 fConfigurations[i].interface = (usb_interface_list *)malloc( 110 configuration->number_interfaces * sizeof(usb_interface_list)); 111 memset(fConfigurations[i].interface, 0, 112 configuration->number_interfaces * sizeof(usb_interface_list)); 113 114 usb_interface_info *currentInterface = NULL; 115 uint32 descriptorStart = sizeof(usb_configuration_descriptor); 116 while (descriptorStart < actualLength) { 117 switch (configData[descriptorStart + 1]) { 118 case USB_DESCRIPTOR_INTERFACE: { 119 TRACE(("USB Device %d: got interface descriptor\n", fDeviceAddress)); 120 usb_interface_descriptor *interfaceDescriptor = (usb_interface_descriptor *)&configData[descriptorStart]; 121 TRACE(("\tlength:.............%d\n", interfaceDescriptor->length)); 122 TRACE(("\tdescriptor_type:....0x%02x\n", interfaceDescriptor->descriptor_type)); 123 TRACE(("\tinterface_number:...%d\n", interfaceDescriptor->interface_number)); 124 TRACE(("\talternate_setting:..%d\n", interfaceDescriptor->alternate_setting)); 125 TRACE(("\tnum_endpoints:......%d\n", interfaceDescriptor->num_endpoints)); 126 TRACE(("\tinterface_class:....0x%02x\n", interfaceDescriptor->interface_class)); 127 TRACE(("\tinterface_subclass:.0x%02x\n", interfaceDescriptor->interface_subclass)); 128 TRACE(("\tinterface_protocol:.0x%02x\n", interfaceDescriptor->interface_protocol)); 129 TRACE(("\tinterface:..........%d\n", interfaceDescriptor->interface)); 130 131 usb_interface_list *interfaceList = 132 &fConfigurations[i].interface[interfaceDescriptor->interface_number]; 133 134 /* allocate this alternate */ 135 interfaceList->alt_count++; 136 interfaceList->alt = (usb_interface_info *)realloc( 137 interfaceList->alt, interfaceList->alt_count 138 * sizeof(usb_interface_info)); 139 interfaceList->active = interfaceList->alt; 140 141 /* setup this alternate */ 142 usb_interface_info *interfaceInfo = 143 &interfaceList->alt[interfaceList->alt_count - 1]; 144 interfaceInfo->descr = interfaceDescriptor; 145 interfaceInfo->endpoint_count = 0; 146 interfaceInfo->endpoint = NULL; 147 interfaceInfo->generic_count = 0; 148 interfaceInfo->generic = NULL; 149 150 Interface *interface = new(std::nothrow) Interface(this); 151 interfaceInfo->handle = interface->USBID(); 152 153 currentInterface = interfaceInfo; 154 break; 155 } 156 157 case USB_DESCRIPTOR_ENDPOINT: { 158 TRACE(("USB Device %d: got endpoint descriptor\n", fDeviceAddress)); 159 usb_endpoint_descriptor *endpointDescriptor = (usb_endpoint_descriptor *)&configData[descriptorStart]; 160 TRACE(("\tlength:.............%d\n", endpointDescriptor->length)); 161 TRACE(("\tdescriptor_type:....0x%02x\n", endpointDescriptor->descriptor_type)); 162 TRACE(("\tendpoint_address:...0x%02x\n", endpointDescriptor->endpoint_address)); 163 TRACE(("\tattributes:.........0x%02x\n", endpointDescriptor->attributes)); 164 TRACE(("\tmax_packet_size:....%d\n", endpointDescriptor->max_packet_size)); 165 TRACE(("\tinterval:...........%d\n", endpointDescriptor->interval)); 166 167 if (!currentInterface) 168 break; 169 170 /* allocate this endpoint */ 171 currentInterface->endpoint_count++; 172 currentInterface->endpoint = (usb_endpoint_info *)realloc( 173 currentInterface->endpoint, 174 currentInterface->endpoint_count 175 * sizeof(usb_endpoint_info)); 176 177 /* setup this endpoint */ 178 usb_endpoint_info *endpointInfo = 179 ¤tInterface->endpoint[currentInterface->endpoint_count - 1]; 180 endpointInfo->descr = endpointDescriptor; 181 182 Pipe *endpoint = NULL; 183 switch (endpointDescriptor->attributes & 0x03) { 184 case 0x00: /* Control Endpoint */ 185 endpoint = new(std::nothrow) ControlPipe(this, 186 Speed(), 187 endpointDescriptor->endpoint_address & 0x0f, 188 endpointDescriptor->max_packet_size); 189 break; 190 191 case 0x01: /* Isochronous Endpoint */ 192 endpoint = new(std::nothrow) IsochronousPipe(this, 193 endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out, 194 Speed(), 195 endpointDescriptor->endpoint_address & 0x0f, 196 endpointDescriptor->max_packet_size); 197 break; 198 199 case 0x02: /* Bulk Endpoint */ 200 endpoint = new(std::nothrow) BulkPipe(this, 201 endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out, 202 Speed(), 203 endpointDescriptor->endpoint_address & 0x0f, 204 endpointDescriptor->max_packet_size); 205 break; 206 207 case 0x03: /* Interrupt Endpoint */ 208 endpoint = new(std::nothrow) InterruptPipe(this, 209 endpointDescriptor->endpoint_address & 0x80 > 0 ? Pipe::In : Pipe::Out, 210 Speed(), 211 endpointDescriptor->endpoint_address & 0x0f, 212 endpointDescriptor->max_packet_size); 213 break; 214 } 215 216 endpointInfo->handle = endpoint->USBID(); 217 break; 218 } 219 220 default: 221 TRACE(("USB Device %d: got generic descriptor\n", fDeviceAddress)); 222 usb_generic_descriptor *genericDescriptor = (usb_generic_descriptor *)&configData[descriptorStart]; 223 TRACE(("\tlength:.............%d\n", genericDescriptor->length)); 224 TRACE(("\tdescriptor_type:....0x%02x\n", genericDescriptor->descriptor_type)); 225 226 if (!currentInterface) 227 break; 228 229 /* allocate this descriptor */ 230 currentInterface->generic_count++; 231 currentInterface->generic = (usb_descriptor **)realloc( 232 currentInterface->generic, 233 currentInterface->generic_count 234 * sizeof(usb_descriptor *)); 235 236 /* add this descriptor */ 237 currentInterface->generic[currentInterface->generic_count] = 238 (usb_descriptor *)genericDescriptor; 239 break; 240 } 241 242 descriptorStart += configData[descriptorStart]; 243 } 244 } 245 246 // Set default configuration 247 TRACE(("USB Device %d: setting default configuration\n", fDeviceAddress)); 248 if (SetConfigurationAt(0) < B_OK) { 249 TRACE_ERROR(("USB Device %d: failed to set default configuration\n", fDeviceAddress)); 250 return; 251 } 252 253 fInitOK = true; 254 } 255 256 257 status_t 258 Device::InitCheck() 259 { 260 if (fInitOK) 261 return B_OK; 262 263 return B_ERROR; 264 } 265 266 267 status_t 268 Device::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID, 269 void *data, size_t dataLength, size_t *actualLength) 270 { 271 return SendRequest( 272 USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, // type 273 USB_REQUEST_GET_DESCRIPTOR, // request 274 (descriptorType << 8) | index, // value 275 languageID, // index 276 dataLength, // length 277 data, // buffer 278 dataLength, // buffer length 279 actualLength); // actual length 280 } 281 282 283 const usb_configuration_info * 284 Device::Configuration() const 285 { 286 return fCurrentConfiguration; 287 } 288 289 290 const usb_configuration_info * 291 Device::ConfigurationAt(uint8 index) const 292 { 293 if (index >= fDeviceDescriptor.num_configurations) 294 return NULL; 295 296 return &fConfigurations[index]; 297 } 298 299 300 status_t 301 Device::SetConfiguration(const usb_configuration_info *configuration) 302 { 303 for (uint8 i = 0; i < fDeviceDescriptor.num_configurations; i++) { 304 if (configuration == &fConfigurations[i]) 305 return SetConfigurationAt(i); 306 } 307 308 return B_BAD_VALUE; 309 } 310 311 312 status_t 313 Device::SetConfigurationAt(uint8 index) 314 { 315 if (index >= fDeviceDescriptor.num_configurations) 316 return B_BAD_VALUE; 317 318 status_t result = 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 // Wait some for the configuration being finished 335 snooze(USB_DELAY_SET_CONFIGURATION); 336 return B_OK; 337 } 338 339 340 const usb_device_descriptor * 341 Device::DeviceDescriptor() const 342 { 343 return &fDeviceDescriptor; 344 } 345 346 347 void 348 Device::ReportDevice(usb_support_descriptor *supportDescriptors, 349 uint32 supportDescriptorCount, const usb_notify_hooks *hooks, bool added) 350 { 351 TRACE(("USB Device ReportDevice\n")); 352 if (supportDescriptorCount == 0 || supportDescriptors == NULL) { 353 if (added && hooks->device_added != NULL) 354 hooks->device_added(USBID(), &fNotifyCookie); 355 else if (!added && hooks->device_removed != NULL) 356 hooks->device_removed(fNotifyCookie); 357 return; 358 } 359 360 for (uint32 i = 0; i < supportDescriptorCount; i++) { 361 if ((supportDescriptors[i].vendor != 0 362 && fDeviceDescriptor.vendor_id != supportDescriptors[i].vendor) 363 || (supportDescriptors[i].product != 0 364 && fDeviceDescriptor.product_id != supportDescriptors[i].product)) 365 continue; 366 367 if ((supportDescriptors[i].dev_class == 0 368 || fDeviceDescriptor.device_class == supportDescriptors[i].dev_class) 369 && (supportDescriptors[i].dev_subclass == 0 370 || fDeviceDescriptor.device_subclass == supportDescriptors[i].dev_subclass) 371 && (supportDescriptors[i].dev_protocol == 0 372 || fDeviceDescriptor.device_protocol == supportDescriptors[i].dev_protocol)) { 373 374 if (added && hooks->device_added != NULL) 375 hooks->device_added(USBID(), &fNotifyCookie); 376 else if (!added && hooks->device_removed != NULL) 377 hooks->device_removed(fNotifyCookie); 378 return; 379 } 380 381 // we have to check all interfaces for matching class/subclass/protocol 382 for (uint32 j = 0; j < fDeviceDescriptor.num_configurations; j++) { 383 for (uint32 k = 0; k < fConfigurations[j].interface_count; k++) { 384 for (uint32 l = 0; l < fConfigurations[j].interface[k].alt_count; l++) { 385 usb_interface_descriptor *descriptor = fConfigurations[j].interface[k].alt[l].descr; 386 if ((supportDescriptors[i].dev_class == 0 387 || descriptor->interface_class == supportDescriptors[i].dev_class) 388 && (supportDescriptors[i].dev_subclass == 0 389 || descriptor->interface_subclass == supportDescriptors[i].dev_subclass) 390 && (supportDescriptors[i].dev_protocol == 0 391 || descriptor->interface_protocol == supportDescriptors[i].dev_protocol)) { 392 393 if (added && hooks->device_added != NULL) 394 hooks->device_added(USBID(), &fNotifyCookie); 395 else if (!added && hooks->device_removed != NULL) 396 hooks->device_removed(fNotifyCookie); 397 return; 398 } 399 } 400 } 401 } 402 } 403 } 404 405 406 status_t 407 Device::BuildDeviceName(char *string, uint32 *index, size_t bufferSize, 408 Device *device) 409 { 410 if (!fParent) 411 return B_ERROR; 412 413 fParent->BuildDeviceName(string, index, bufferSize, this); 414 return B_OK; 415 } 416 417 418 status_t 419 Device::SetFeature(uint16 selector) 420 { 421 return SendRequest( 422 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, 423 USB_REQUEST_SET_FEATURE, 424 selector, 425 0, 426 0, 427 NULL, 428 0, 429 NULL); 430 } 431 432 433 status_t 434 Device::ClearFeature(uint16 selector) 435 { 436 return SendRequest( 437 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, 438 USB_REQUEST_CLEAR_FEATURE, 439 selector, 440 0, 441 0, 442 NULL, 443 0, 444 NULL); 445 } 446 447 448 status_t 449 Device::GetStatus(uint16 *status) 450 { 451 return SendRequest( 452 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_IN, 453 USB_REQUEST_GET_STATUS, 454 0, 455 0, 456 2, 457 (void *)status, 458 2, 459 NULL); 460 } 461