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