1 /* 2 * Copyright 2006-2018, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 * Adrien Destugues <pulkomandy@pulkomandy.tk> 8 */ 9 10 #include "usb_raw.h" 11 12 #include <KernelExport.h> 13 #include <Drivers.h> 14 #include <algorithm> 15 #include <lock.h> 16 #include <malloc.h> 17 #include <stdio.h> 18 #include <string.h> 19 20 #include <kernel.h> 21 22 23 //#define TRACE_USB_RAW 24 #ifdef TRACE_USB_RAW 25 #define TRACE(x) dprintf x 26 #else 27 #define TRACE(x) /* nothing */ 28 #endif 29 30 #define DRIVER_NAME "usb_raw" 31 #define DEVICE_NAME "bus/usb/raw" 32 33 typedef struct { 34 usb_device device; 35 mutex lock; 36 uint32 reference_count; 37 38 char name[64]; 39 void *link; 40 41 sem_id notify; 42 status_t status; 43 size_t actual_length; 44 } raw_device; 45 46 int32 api_version = B_CUR_DRIVER_API_VERSION; 47 static usb_module_info *gUSBModule = NULL; 48 static raw_device *gDeviceList = NULL; 49 static uint32 gDeviceCount = 0; 50 static mutex gDeviceListLock; 51 static char **gDeviceNames = NULL; 52 53 static status_t 54 usb_raw_device_added(usb_device newDevice, void **cookie) 55 { 56 TRACE((DRIVER_NAME": device_added(0x%08" B_PRIx32 ")\n", newDevice)); 57 raw_device *device = (raw_device *)malloc(sizeof(raw_device)); 58 59 mutex_init(&device->lock, "usb_raw device lock"); 60 61 device->notify = create_sem(0, "usb_raw callback notify"); 62 if (device->notify < B_OK) { 63 mutex_destroy(&device->lock); 64 free(device); 65 return B_NO_MORE_SEMS; 66 } 67 68 char deviceName[64]; 69 memcpy(deviceName, &newDevice, sizeof(usb_device)); 70 if (gUSBModule->usb_ioctl('DNAM', deviceName, sizeof(deviceName)) >= B_OK) { 71 snprintf(device->name, sizeof(device->name), "bus/usb/%s", deviceName); 72 } else { 73 snprintf(device->name, sizeof(device->name), "bus/usb/%08" B_PRIx32, 74 newDevice); 75 } 76 77 device->device = newDevice; 78 device->reference_count = 0; 79 80 mutex_lock(&gDeviceListLock); 81 device->link = (void *)gDeviceList; 82 gDeviceList = device; 83 gDeviceCount++; 84 mutex_unlock(&gDeviceListLock); 85 86 TRACE((DRIVER_NAME": new device: 0x%p\n", device)); 87 *cookie = (void *)device; 88 return B_OK; 89 } 90 91 92 static status_t 93 usb_raw_device_removed(void *cookie) 94 { 95 TRACE((DRIVER_NAME": device_removed(0x%p)\n", cookie)); 96 raw_device *device = (raw_device *)cookie; 97 98 // cancel all pending transfers to make sure no one keeps waiting forever 99 // in syscalls. 100 const usb_configuration_info *configurationInfo = 101 gUSBModule->get_configuration(device->device); 102 if (configurationInfo != NULL) { 103 struct usb_interface_info* interface 104 = configurationInfo->interface->active; 105 for (unsigned int i = 0; i < interface->endpoint_count; i++) 106 gUSBModule->cancel_queued_transfers(interface->endpoint[i].handle); 107 } 108 109 mutex_lock(&gDeviceListLock); 110 if (gDeviceList == device) { 111 gDeviceList = (raw_device *)device->link; 112 } else { 113 raw_device *element = gDeviceList; 114 while (element) { 115 if (element->link == device) { 116 element->link = device->link; 117 break; 118 } 119 120 element = (raw_device *)element->link; 121 } 122 } 123 gDeviceCount--; 124 mutex_unlock(&gDeviceListLock); 125 126 device->device = 0; 127 if (device->reference_count == 0) { 128 mutex_lock(&device->lock); 129 mutex_destroy(&device->lock); 130 delete_sem(device->notify); 131 free(device); 132 } 133 134 return B_OK; 135 } 136 137 138 // 139 //#pragma mark - 140 // 141 142 143 static const usb_configuration_info * 144 usb_raw_get_configuration(raw_device *device, uint32 configIndex, 145 status_t *status) 146 { 147 const usb_configuration_info *result = gUSBModule->get_nth_configuration( 148 device->device, configIndex); 149 if (result == NULL) { 150 *status = B_USB_RAW_STATUS_INVALID_CONFIGURATION; 151 return NULL; 152 } 153 154 return result; 155 } 156 157 158 static const usb_interface_info * 159 usb_raw_get_interface(raw_device *device, uint32 configIndex, 160 uint32 interfaceIndex, uint32 alternateIndex, status_t *status) 161 { 162 const usb_configuration_info *configurationInfo 163 = usb_raw_get_configuration(device, configIndex, status); 164 if (configurationInfo == NULL) 165 return NULL; 166 167 if (interfaceIndex >= configurationInfo->interface_count) { 168 *status = B_USB_RAW_STATUS_INVALID_INTERFACE; 169 return NULL; 170 } 171 172 const usb_interface_info *result = NULL; 173 if (alternateIndex == B_USB_RAW_ACTIVE_ALTERNATE) 174 result = configurationInfo->interface[interfaceIndex].active; 175 else { 176 const usb_interface_list *interfaceList = 177 &configurationInfo->interface[interfaceIndex]; 178 if (alternateIndex >= interfaceList->alt_count) { 179 *status = B_USB_RAW_STATUS_INVALID_INTERFACE; 180 return NULL; 181 } 182 183 result = &interfaceList->alt[alternateIndex]; 184 } 185 186 return result; 187 } 188 189 190 // 191 //#pragma mark - 192 // 193 194 195 static status_t 196 usb_raw_open(const char *name, uint32 flags, void **cookie) 197 { 198 TRACE((DRIVER_NAME": open()\n")); 199 mutex_lock(&gDeviceListLock); 200 raw_device *element = gDeviceList; 201 while (element) { 202 if (strcmp(name, element->name) == 0) { 203 element->reference_count++; 204 *cookie = element; 205 mutex_unlock(&gDeviceListLock); 206 return B_OK; 207 } 208 209 element = (raw_device *)element->link; 210 } 211 212 mutex_unlock(&gDeviceListLock); 213 return B_NAME_NOT_FOUND; 214 } 215 216 217 static status_t 218 usb_raw_close(void *cookie) 219 { 220 TRACE((DRIVER_NAME": close()\n")); 221 return B_OK; 222 } 223 224 225 static status_t 226 usb_raw_free(void *cookie) 227 { 228 TRACE((DRIVER_NAME": free()\n")); 229 mutex_lock(&gDeviceListLock); 230 231 raw_device *device = (raw_device *)cookie; 232 device->reference_count--; 233 if (device->device == 0) { 234 mutex_lock(&device->lock); 235 mutex_destroy(&device->lock); 236 delete_sem(device->notify); 237 free(device); 238 } 239 240 mutex_unlock(&gDeviceListLock); 241 return B_OK; 242 } 243 244 245 static void 246 usb_raw_callback(void *cookie, status_t status, void *data, size_t actualLength) 247 { 248 TRACE((DRIVER_NAME": callback()\n")); 249 raw_device *device = (raw_device *)cookie; 250 251 switch (status) { 252 case B_OK: 253 device->status = B_USB_RAW_STATUS_SUCCESS; 254 break; 255 case B_TIMED_OUT: 256 device->status = B_USB_RAW_STATUS_TIMEOUT; 257 break; 258 case B_CANCELED: 259 device->status = B_USB_RAW_STATUS_ABORTED; 260 break; 261 case B_DEV_CRC_ERROR: 262 device->status = B_USB_RAW_STATUS_CRC_ERROR; 263 break; 264 case B_DEV_STALLED: 265 device->status = B_USB_RAW_STATUS_STALLED; 266 break; 267 default: 268 device->status = B_USB_RAW_STATUS_FAILED; 269 break; 270 } 271 272 device->actual_length = actualLength; 273 release_sem(device->notify); 274 } 275 276 277 static status_t 278 usb_raw_ioctl(void *cookie, uint32 op, void *buffer, size_t length) 279 { 280 TRACE((DRIVER_NAME": ioctl\n")); 281 raw_device *device = (raw_device *)cookie; 282 if (device->device == 0) 283 return B_DEV_NOT_READY; 284 285 usb_raw_command command; 286 if (length < sizeof(command.version.status)) 287 return B_BUFFER_OVERFLOW; 288 if (!IS_USER_ADDRESS(buffer) 289 || user_memcpy(&command, buffer, min_c(length, sizeof(command))) 290 != B_OK) { 291 return B_BAD_ADDRESS; 292 } 293 294 command.version.status = B_USB_RAW_STATUS_ABORTED; 295 status_t status = B_DEV_INVALID_IOCTL; 296 297 switch (op) { 298 case B_USB_RAW_COMMAND_GET_VERSION: 299 { 300 command.version.status = B_USB_RAW_PROTOCOL_VERSION; 301 status = B_OK; 302 break; 303 } 304 305 case B_USB_RAW_COMMAND_GET_DEVICE_DESCRIPTOR: 306 { 307 if (length < sizeof(command.device)) 308 return B_BUFFER_OVERFLOW; 309 310 status = B_OK; 311 const usb_device_descriptor *deviceDescriptor = 312 gUSBModule->get_device_descriptor(device->device); 313 if (deviceDescriptor == NULL) 314 return B_OK; 315 316 if (!IS_USER_ADDRESS(command.device.descriptor) 317 || user_memcpy(command.device.descriptor, deviceDescriptor, 318 sizeof(usb_device_descriptor)) != B_OK) { 319 return B_BAD_ADDRESS; 320 } 321 322 command.device.status = B_USB_RAW_STATUS_SUCCESS; 323 break; 324 } 325 326 case B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR: 327 case B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR_ETC: 328 { 329 if (op == B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR_ETC 330 && length < sizeof(command.config_etc)) 331 return B_BUFFER_OVERFLOW; 332 333 if (length < sizeof(command.config)) 334 return B_BUFFER_OVERFLOW; 335 336 status = B_OK; 337 const usb_configuration_info *configurationInfo = 338 usb_raw_get_configuration(device, command.config.config_index, 339 &command.config.status); 340 if (configurationInfo == NULL) 341 break; 342 343 size_t sizeToCopy = sizeof(usb_configuration_descriptor); 344 if (op == B_USB_RAW_COMMAND_GET_CONFIGURATION_DESCRIPTOR_ETC) { 345 sizeToCopy = std::min(command.config_etc.length, 346 (size_t)configurationInfo->descr->total_length); 347 } 348 349 if (!IS_USER_ADDRESS(command.config.descriptor) 350 || user_memcpy(command.config.descriptor, 351 configurationInfo->descr, sizeToCopy) != B_OK) { 352 return B_BAD_ADDRESS; 353 } 354 355 command.config.status = B_USB_RAW_STATUS_SUCCESS; 356 break; 357 } 358 359 case B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT: 360 case B_USB_RAW_COMMAND_GET_ACTIVE_ALT_INTERFACE_INDEX: 361 { 362 if (length < sizeof(command.alternate)) 363 return B_BUFFER_OVERFLOW; 364 365 status = B_OK; 366 const usb_configuration_info *configurationInfo = 367 usb_raw_get_configuration(device, 368 command.alternate.config_index, 369 &command.alternate.status); 370 if (configurationInfo == NULL) 371 break; 372 373 if (command.alternate.interface_index 374 >= configurationInfo->interface_count) { 375 command.alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE; 376 break; 377 } 378 379 const usb_interface_list *interfaceList 380 = &configurationInfo->interface[ 381 command.alternate.interface_index]; 382 if (op == B_USB_RAW_COMMAND_GET_ALT_INTERFACE_COUNT) { 383 command.alternate.alternate_info = interfaceList->alt_count; 384 } else { 385 for (size_t i = 0; i < interfaceList->alt_count; i++) { 386 if (&interfaceList->alt[i] == interfaceList->active) { 387 command.alternate.alternate_info = i; 388 break; 389 } 390 } 391 } 392 393 command.alternate.status = B_USB_RAW_STATUS_SUCCESS; 394 break; 395 } 396 397 case B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR: 398 case B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR_ETC: 399 { 400 const usb_interface_info *interfaceInfo = NULL; 401 status = B_OK; 402 if (op == B_USB_RAW_COMMAND_GET_INTERFACE_DESCRIPTOR) { 403 if (length < sizeof(command.interface)) 404 return B_BUFFER_OVERFLOW; 405 406 interfaceInfo = usb_raw_get_interface(device, 407 command.interface.config_index, 408 command.interface.interface_index, 409 B_USB_RAW_ACTIVE_ALTERNATE, 410 &command.interface.status); 411 } else { 412 if (length < sizeof(command.interface_etc)) 413 return B_BUFFER_OVERFLOW; 414 415 interfaceInfo = usb_raw_get_interface(device, 416 command.interface_etc.config_index, 417 command.interface_etc.interface_index, 418 command.interface_etc.alternate_index, 419 &command.interface_etc.status); 420 } 421 422 if (interfaceInfo == NULL) 423 break; 424 425 if (!IS_USER_ADDRESS(command.interface.descriptor) 426 || user_memcpy(command.interface.descriptor, interfaceInfo->descr, 427 sizeof(usb_interface_descriptor)) != B_OK) { 428 return B_BAD_ADDRESS; 429 } 430 431 command.interface.status = B_USB_RAW_STATUS_SUCCESS; 432 break; 433 } 434 435 case B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR: 436 case B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR_ETC: 437 { 438 uint32 endpointIndex = 0; 439 const usb_interface_info *interfaceInfo = NULL; 440 status = B_OK; 441 if (op == B_USB_RAW_COMMAND_GET_ENDPOINT_DESCRIPTOR) { 442 if (length < sizeof(command.endpoint)) 443 return B_BUFFER_OVERFLOW; 444 445 interfaceInfo = usb_raw_get_interface(device, 446 command.endpoint.config_index, 447 command.endpoint.interface_index, 448 B_USB_RAW_ACTIVE_ALTERNATE, 449 &command.endpoint.status); 450 endpointIndex = command.endpoint.endpoint_index; 451 } else { 452 if (length < sizeof(command.endpoint_etc)) 453 return B_BUFFER_OVERFLOW; 454 455 interfaceInfo = usb_raw_get_interface(device, 456 command.endpoint_etc.config_index, 457 command.endpoint_etc.interface_index, 458 command.endpoint_etc.alternate_index, 459 &command.endpoint_etc.status); 460 endpointIndex = command.endpoint_etc.endpoint_index; 461 } 462 463 if (interfaceInfo == NULL) 464 break; 465 466 if (endpointIndex >= interfaceInfo->endpoint_count) { 467 command.endpoint.status = B_USB_RAW_STATUS_INVALID_ENDPOINT; 468 break; 469 } 470 471 if (!IS_USER_ADDRESS(command.endpoint.descriptor) 472 || user_memcpy(command.endpoint.descriptor, 473 interfaceInfo->endpoint[endpointIndex].descr, 474 sizeof(usb_endpoint_descriptor)) != B_OK) { 475 return B_BAD_ADDRESS; 476 } 477 478 command.endpoint.status = B_USB_RAW_STATUS_SUCCESS; 479 break; 480 } 481 482 case B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR: 483 case B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR_ETC: 484 { 485 uint32 genericIndex = 0; 486 size_t genericLength = 0; 487 const usb_interface_info *interfaceInfo = NULL; 488 status = B_OK; 489 if (op == B_USB_RAW_COMMAND_GET_GENERIC_DESCRIPTOR) { 490 if (length < sizeof(command.generic)) 491 return B_BUFFER_OVERFLOW; 492 493 interfaceInfo = usb_raw_get_interface(device, 494 command.generic.config_index, 495 command.generic.interface_index, 496 B_USB_RAW_ACTIVE_ALTERNATE, 497 &command.generic.status); 498 genericIndex = command.generic.generic_index; 499 genericLength = command.generic.length; 500 } else { 501 if (length < sizeof(command.generic_etc)) 502 return B_BUFFER_OVERFLOW; 503 504 interfaceInfo = usb_raw_get_interface(device, 505 command.generic_etc.config_index, 506 command.generic_etc.interface_index, 507 command.generic_etc.alternate_index, 508 &command.generic_etc.status); 509 genericIndex = command.generic_etc.generic_index; 510 genericLength = command.generic_etc.length; 511 } 512 513 if (interfaceInfo == NULL) 514 break; 515 516 if (genericIndex >= interfaceInfo->generic_count) { 517 command.endpoint.status = B_USB_RAW_STATUS_INVALID_ENDPOINT; 518 break; 519 } 520 521 usb_descriptor *descriptor = interfaceInfo->generic[genericIndex]; 522 if (descriptor == NULL) 523 break; 524 525 if (!IS_USER_ADDRESS(command.generic.descriptor) 526 || user_memcpy(command.generic.descriptor, descriptor, 527 min_c(genericLength, descriptor->generic.length)) != B_OK) { 528 return B_BAD_ADDRESS; 529 } 530 531 if (descriptor->generic.length > genericLength) 532 command.generic.status = B_USB_RAW_STATUS_NO_MEMORY; 533 else 534 command.generic.status = B_USB_RAW_STATUS_SUCCESS; 535 break; 536 } 537 538 case B_USB_RAW_COMMAND_GET_STRING_DESCRIPTOR: 539 { 540 if (length < sizeof(command.string)) 541 return B_BUFFER_OVERFLOW; 542 543 size_t actualLength = 0; 544 uint8 firstTwoBytes[2]; 545 status = B_OK; 546 547 if (gUSBModule->get_descriptor(device->device, 548 USB_DESCRIPTOR_STRING, command.string.string_index, 0, 549 firstTwoBytes, 2, &actualLength) < B_OK 550 || actualLength != 2 551 || firstTwoBytes[1] != USB_DESCRIPTOR_STRING) { 552 command.string.status = B_USB_RAW_STATUS_ABORTED; 553 command.string.length = 0; 554 break; 555 } 556 557 uint8 stringLength = MIN(firstTwoBytes[0], command.string.length); 558 char *string = (char *)malloc(stringLength); 559 if (string == NULL) { 560 command.string.status = B_USB_RAW_STATUS_ABORTED; 561 command.string.length = 0; 562 status = B_NO_MEMORY; 563 break; 564 } 565 566 if (gUSBModule->get_descriptor(device->device, 567 USB_DESCRIPTOR_STRING, command.string.string_index, 0, 568 string, stringLength, &actualLength) < B_OK 569 || actualLength != stringLength) { 570 command.string.status = B_USB_RAW_STATUS_ABORTED; 571 command.string.length = 0; 572 free(string); 573 break; 574 } 575 576 if (!IS_USER_ADDRESS(command.string.descriptor) 577 || user_memcpy(command.string.descriptor, string, 578 stringLength) != B_OK) { 579 free(string); 580 return B_BAD_ADDRESS; 581 } 582 583 command.string.status = B_USB_RAW_STATUS_SUCCESS; 584 command.string.length = stringLength; 585 free(string); 586 break; 587 } 588 589 case B_USB_RAW_COMMAND_GET_DESCRIPTOR: 590 { 591 if (length < sizeof(command.descriptor)) 592 return B_BUFFER_OVERFLOW; 593 594 size_t actualLength = 0; 595 uint8 firstTwoBytes[2]; 596 status = B_OK; 597 598 if (gUSBModule->get_descriptor(device->device, 599 command.descriptor.type, command.descriptor.index, 600 command.descriptor.language_id, firstTwoBytes, 2, 601 &actualLength) < B_OK 602 || actualLength != 2 603 || firstTwoBytes[1] != command.descriptor.type) { 604 command.descriptor.status = B_USB_RAW_STATUS_ABORTED; 605 command.descriptor.length = 0; 606 break; 607 } 608 609 uint8 descriptorLength = MIN(firstTwoBytes[0], 610 command.descriptor.length); 611 uint8 *descriptorBuffer = (uint8 *)malloc(descriptorLength); 612 if (descriptorBuffer == NULL) { 613 command.descriptor.status = B_USB_RAW_STATUS_ABORTED; 614 command.descriptor.length = 0; 615 status = B_NO_MEMORY; 616 break; 617 } 618 619 if (gUSBModule->get_descriptor(device->device, 620 command.descriptor.type, command.descriptor.index, 621 command.descriptor.language_id, descriptorBuffer, 622 descriptorLength, &actualLength) < B_OK 623 || actualLength != descriptorLength) { 624 command.descriptor.status = B_USB_RAW_STATUS_ABORTED; 625 command.descriptor.length = 0; 626 free(descriptorBuffer); 627 break; 628 } 629 630 if (!IS_USER_ADDRESS(command.descriptor.data) 631 || user_memcpy(command.descriptor.data, descriptorBuffer, 632 descriptorLength) != B_OK) { 633 free(descriptorBuffer); 634 return B_BAD_ADDRESS; 635 } 636 637 command.descriptor.status = B_USB_RAW_STATUS_SUCCESS; 638 command.descriptor.length = descriptorLength; 639 free(descriptorBuffer); 640 break; 641 } 642 643 case B_USB_RAW_COMMAND_SET_CONFIGURATION: 644 { 645 if (length < sizeof(command.config)) 646 return B_BUFFER_OVERFLOW; 647 648 status = B_OK; 649 const usb_configuration_info *configurationInfo = 650 usb_raw_get_configuration(device, command.config.config_index, 651 &command.config.status); 652 if (configurationInfo == NULL) 653 break; 654 655 if (gUSBModule->set_configuration(device->device, 656 configurationInfo) < B_OK) { 657 command.config.status = B_USB_RAW_STATUS_FAILED; 658 break; 659 } 660 661 command.config.status = B_USB_RAW_STATUS_SUCCESS; 662 break; 663 } 664 665 case B_USB_RAW_COMMAND_SET_ALT_INTERFACE: 666 { 667 if (length < sizeof(command.alternate)) 668 return B_BUFFER_OVERFLOW; 669 670 status = B_OK; 671 const usb_configuration_info *configurationInfo = 672 usb_raw_get_configuration(device, 673 command.alternate.config_index, 674 &command.alternate.status); 675 if (configurationInfo == NULL) 676 break; 677 678 if (command.alternate.interface_index 679 >= configurationInfo->interface_count) { 680 command.alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE; 681 break; 682 } 683 684 const usb_interface_list *interfaceList = 685 &configurationInfo->interface[command.alternate.interface_index]; 686 if (command.alternate.alternate_info >= interfaceList->alt_count) { 687 command.alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE; 688 break; 689 } 690 691 if (gUSBModule->set_alt_interface(device->device, 692 &interfaceList->alt[command.alternate.alternate_info]) < B_OK) { 693 command.alternate.status = B_USB_RAW_STATUS_FAILED; 694 break; 695 } 696 697 command.alternate.status = B_USB_RAW_STATUS_SUCCESS; 698 break; 699 } 700 701 case B_USB_RAW_COMMAND_CONTROL_TRANSFER: 702 { 703 if (length < sizeof(command.control)) 704 return B_BUFFER_OVERFLOW; 705 706 void *controlData = malloc(command.control.length); 707 if (controlData == NULL) 708 return B_NO_MEMORY; 709 bool inTransfer = (command.control.request_type 710 & USB_ENDPOINT_ADDR_DIR_IN) != 0; 711 if (!IS_USER_ADDRESS(command.control.data) 712 || (!inTransfer && user_memcpy(controlData, 713 command.control.data, command.control.length) != B_OK)) { 714 free(controlData); 715 return B_BAD_ADDRESS; 716 } 717 718 mutex_lock(&device->lock); 719 if (gUSBModule->queue_request(device->device, 720 command.control.request_type, command.control.request, 721 command.control.value, command.control.index, 722 command.control.length, controlData, 723 usb_raw_callback, device) < B_OK) { 724 command.control.status = B_USB_RAW_STATUS_FAILED; 725 command.control.length = 0; 726 mutex_unlock(&device->lock); 727 free(controlData); 728 status = B_OK; 729 break; 730 } 731 732 acquire_sem(device->notify); 733 command.control.status = device->status; 734 command.control.length = device->actual_length; 735 mutex_unlock(&device->lock); 736 737 status = B_OK; 738 if (inTransfer && user_memcpy(command.control.data, controlData, 739 command.control.length) != B_OK) { 740 status = B_BAD_ADDRESS; 741 } 742 743 free(controlData); 744 break; 745 } 746 747 case B_USB_RAW_COMMAND_INTERRUPT_TRANSFER: 748 case B_USB_RAW_COMMAND_BULK_TRANSFER: 749 case B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER: 750 { 751 if (length < sizeof(command.transfer)) 752 return B_BUFFER_OVERFLOW; 753 754 status = B_OK; 755 const usb_configuration_info *configurationInfo = 756 gUSBModule->get_configuration(device->device); 757 if (configurationInfo == NULL) { 758 command.transfer.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION; 759 break; 760 } 761 762 if (command.transfer.interface >= configurationInfo->interface_count) { 763 command.transfer.status = B_USB_RAW_STATUS_INVALID_INTERFACE; 764 break; 765 } 766 767 const usb_interface_info *interfaceInfo = 768 configurationInfo->interface[command.transfer.interface].active; 769 if (interfaceInfo == NULL) { 770 command.transfer.status = B_USB_RAW_STATUS_ABORTED; 771 break; 772 } 773 774 if (command.transfer.endpoint >= interfaceInfo->endpoint_count) { 775 command.transfer.status = B_USB_RAW_STATUS_INVALID_ENDPOINT; 776 break; 777 } 778 779 const usb_endpoint_info *endpointInfo = 780 &interfaceInfo->endpoint[command.transfer.endpoint]; 781 if (!endpointInfo->handle) { 782 command.transfer.status = B_USB_RAW_STATUS_INVALID_ENDPOINT; 783 break; 784 } 785 786 size_t descriptorsSize = 0; 787 usb_iso_packet_descriptor *packetDescriptors = NULL; 788 void *transferData = NULL; 789 bool inTransfer = (endpointInfo->descr->endpoint_address 790 & USB_ENDPOINT_ADDR_DIR_IN) != 0; 791 if (op == B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER) { 792 if (length < sizeof(command.isochronous)) 793 return B_BUFFER_OVERFLOW; 794 795 descriptorsSize = sizeof(usb_iso_packet_descriptor) 796 * command.isochronous.packet_count; 797 packetDescriptors 798 = (usb_iso_packet_descriptor *)malloc(descriptorsSize); 799 if (packetDescriptors == NULL) { 800 command.transfer.status = B_USB_RAW_STATUS_NO_MEMORY; 801 command.transfer.length = 0; 802 break; 803 } 804 805 if (!IS_USER_ADDRESS(command.isochronous.data) 806 || !IS_USER_ADDRESS(command.isochronous.packet_descriptors) 807 || user_memcpy(packetDescriptors, 808 command.isochronous.packet_descriptors, 809 descriptorsSize) != B_OK) { 810 free(packetDescriptors); 811 return B_BAD_ADDRESS; 812 } 813 } else { 814 transferData = malloc(command.transfer.length); 815 if (transferData == NULL) { 816 command.transfer.status = B_USB_RAW_STATUS_NO_MEMORY; 817 command.transfer.length = 0; 818 break; 819 } 820 821 if (!IS_USER_ADDRESS(command.transfer.data) || (!inTransfer 822 && user_memcpy(transferData, command.transfer.data, 823 command.transfer.length) != B_OK)) { 824 free(transferData); 825 return B_BAD_ADDRESS; 826 } 827 } 828 829 status_t status; 830 mutex_lock(&device->lock); 831 if (op == B_USB_RAW_COMMAND_INTERRUPT_TRANSFER) { 832 status = gUSBModule->queue_interrupt(endpointInfo->handle, 833 transferData, command.transfer.length, 834 usb_raw_callback, device); 835 } else if (op == B_USB_RAW_COMMAND_BULK_TRANSFER) { 836 status = gUSBModule->queue_bulk(endpointInfo->handle, 837 transferData, command.transfer.length, 838 usb_raw_callback, device); 839 } else { 840 status = gUSBModule->queue_isochronous(endpointInfo->handle, 841 command.isochronous.data, command.isochronous.length, 842 packetDescriptors, command.isochronous.packet_count, NULL, 843 0, usb_raw_callback, device); 844 } 845 846 if (status < B_OK) { 847 command.transfer.status = B_USB_RAW_STATUS_FAILED; 848 command.transfer.length = 0; 849 free(packetDescriptors); 850 free(transferData); 851 mutex_unlock(&device->lock); 852 status = B_OK; 853 break; 854 } 855 856 acquire_sem(device->notify); 857 command.transfer.status = device->status; 858 command.transfer.length = device->actual_length; 859 mutex_unlock(&device->lock); 860 861 status = B_OK; 862 if (op == B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER) { 863 if (user_memcpy(command.isochronous.packet_descriptors, 864 packetDescriptors, descriptorsSize) != B_OK) { 865 status = B_BAD_ADDRESS; 866 } 867 868 free(packetDescriptors); 869 } else { 870 if (inTransfer && user_memcpy(command.transfer.data, 871 transferData, command.transfer.length) != B_OK) { 872 status = B_BAD_ADDRESS; 873 } 874 free(transferData); 875 } 876 877 break; 878 } 879 } 880 881 if (user_memcpy(buffer, &command, min_c(length, sizeof(command))) != B_OK) 882 return B_BAD_ADDRESS; 883 884 return status; 885 } 886 887 888 static status_t 889 usb_raw_read(void *cookie, off_t position, void *buffer, size_t *length) 890 { 891 TRACE((DRIVER_NAME": read()\n")); 892 *length = 0; 893 return B_OK; 894 } 895 896 897 static status_t 898 usb_raw_write(void *cookie, off_t position, const void *buffer, size_t *length) 899 { 900 TRACE((DRIVER_NAME": write()\n")); 901 *length = 0; 902 return B_OK; 903 } 904 905 906 // 907 //#pragma mark - 908 // 909 910 911 status_t 912 init_hardware() 913 { 914 TRACE((DRIVER_NAME": init_hardware()\n")); 915 return B_OK; 916 } 917 918 919 status_t 920 init_driver() 921 { 922 TRACE((DRIVER_NAME": init_driver()\n")); 923 static usb_notify_hooks notifyHooks = { 924 &usb_raw_device_added, 925 &usb_raw_device_removed 926 }; 927 928 gDeviceList = NULL; 929 gDeviceCount = 0; 930 mutex_init(&gDeviceListLock, "usb_raw device list lock"); 931 932 TRACE((DRIVER_NAME": trying module %s\n", B_USB_MODULE_NAME)); 933 status_t result = get_module(B_USB_MODULE_NAME, 934 (module_info **)&gUSBModule); 935 if (result < B_OK) { 936 TRACE((DRIVER_NAME": getting module failed 0x%08" B_PRIx32 "\n", 937 result)); 938 mutex_destroy(&gDeviceListLock); 939 return result; 940 } 941 942 gUSBModule->register_driver(DRIVER_NAME, NULL, 0, NULL); 943 gUSBModule->install_notify(DRIVER_NAME, ¬ifyHooks); 944 return B_OK; 945 } 946 947 948 void 949 uninit_driver() 950 { 951 TRACE((DRIVER_NAME": uninit_driver()\n")); 952 gUSBModule->uninstall_notify(DRIVER_NAME); 953 mutex_lock(&gDeviceListLock); 954 955 if (gDeviceNames) { 956 for (int32 i = 1; gDeviceNames[i]; i++) 957 free(gDeviceNames[i]); 958 free(gDeviceNames); 959 gDeviceNames = NULL; 960 } 961 962 mutex_destroy(&gDeviceListLock); 963 put_module(B_USB_MODULE_NAME); 964 } 965 966 967 const char ** 968 publish_devices() 969 { 970 TRACE((DRIVER_NAME": publish_devices()\n")); 971 if (gDeviceNames) { 972 for (int32 i = 0; gDeviceNames[i]; i++) 973 free(gDeviceNames[i]); 974 free(gDeviceNames); 975 gDeviceNames = NULL; 976 } 977 978 int32 index = 0; 979 gDeviceNames = (char **)malloc(sizeof(char *) * (gDeviceCount + 2)); 980 if (gDeviceNames == NULL) 981 return NULL; 982 983 gDeviceNames[index++] = strdup(DEVICE_NAME); 984 985 mutex_lock(&gDeviceListLock); 986 raw_device *element = gDeviceList; 987 while (element) { 988 gDeviceNames[index++] = strdup(element->name); 989 element = (raw_device *)element->link; 990 } 991 992 gDeviceNames[index++] = NULL; 993 mutex_unlock(&gDeviceListLock); 994 return (const char **)gDeviceNames; 995 } 996 997 998 device_hooks * 999 find_device(const char *name) 1000 { 1001 TRACE((DRIVER_NAME": find_device()\n")); 1002 static device_hooks hooks = { 1003 &usb_raw_open, 1004 &usb_raw_close, 1005 &usb_raw_free, 1006 &usb_raw_ioctl, 1007 &usb_raw_read, 1008 &usb_raw_write, 1009 NULL, 1010 NULL, 1011 NULL, 1012 NULL 1013 }; 1014 1015 return &hooks; 1016 } 1017