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 return status; 736 737 command.control.status = device->status; 738 command.control.length = device->actual_length; 739 deviceLocker.Unlock(); 740 741 status = B_OK; 742 if (inTransfer && user_memcpy(command.control.data, controlData, 743 command.control.length) != B_OK) { 744 status = B_BAD_ADDRESS; 745 } 746 break; 747 } 748 749 case B_USB_RAW_COMMAND_INTERRUPT_TRANSFER: 750 case B_USB_RAW_COMMAND_BULK_TRANSFER: 751 case B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER: 752 { 753 if (length < sizeof(command.transfer)) 754 return B_BUFFER_OVERFLOW; 755 756 status = B_OK; 757 const usb_configuration_info *configurationInfo = 758 gUSBModule->get_configuration(device->device); 759 if (configurationInfo == NULL) { 760 command.transfer.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION; 761 break; 762 } 763 764 if (command.transfer.interface >= configurationInfo->interface_count) { 765 command.transfer.status = B_USB_RAW_STATUS_INVALID_INTERFACE; 766 break; 767 } 768 769 const usb_interface_info *interfaceInfo = 770 configurationInfo->interface[command.transfer.interface].active; 771 if (interfaceInfo == NULL) { 772 command.transfer.status = B_USB_RAW_STATUS_ABORTED; 773 break; 774 } 775 776 if (command.transfer.endpoint >= interfaceInfo->endpoint_count) { 777 command.transfer.status = B_USB_RAW_STATUS_INVALID_ENDPOINT; 778 break; 779 } 780 781 const usb_endpoint_info *endpointInfo = 782 &interfaceInfo->endpoint[command.transfer.endpoint]; 783 if (!endpointInfo->handle) { 784 command.transfer.status = B_USB_RAW_STATUS_INVALID_ENDPOINT; 785 break; 786 } 787 788 size_t descriptorsSize = 0; 789 usb_iso_packet_descriptor *packetDescriptors = NULL; 790 void *transferData = NULL; 791 MemoryDeleter descriptorsDeleter, dataDeleter; 792 793 bool inTransfer = (endpointInfo->descr->endpoint_address 794 & USB_ENDPOINT_ADDR_DIR_IN) != 0; 795 if (op == B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER) { 796 if (length < sizeof(command.isochronous)) 797 return B_BUFFER_OVERFLOW; 798 799 descriptorsSize = sizeof(usb_iso_packet_descriptor) 800 * command.isochronous.packet_count; 801 packetDescriptors 802 = (usb_iso_packet_descriptor *)malloc(descriptorsSize); 803 if (packetDescriptors == NULL) { 804 command.transfer.status = B_USB_RAW_STATUS_NO_MEMORY; 805 command.transfer.length = 0; 806 break; 807 } 808 descriptorsDeleter.SetTo(packetDescriptors); 809 810 if (!IS_USER_ADDRESS(command.isochronous.data) 811 || !IS_USER_ADDRESS(command.isochronous.packet_descriptors) 812 || user_memcpy(packetDescriptors, 813 command.isochronous.packet_descriptors, 814 descriptorsSize) != B_OK) { 815 return B_BAD_ADDRESS; 816 } 817 } else { 818 transferData = malloc(command.transfer.length); 819 if (transferData == NULL) { 820 command.transfer.status = B_USB_RAW_STATUS_NO_MEMORY; 821 command.transfer.length = 0; 822 break; 823 } 824 dataDeleter.SetTo(transferData); 825 826 if (!IS_USER_ADDRESS(command.transfer.data) || (!inTransfer 827 && user_memcpy(transferData, command.transfer.data, 828 command.transfer.length) != B_OK)) { 829 return B_BAD_ADDRESS; 830 } 831 } 832 833 status_t status; 834 MutexLocker deviceLocker(device->lock); 835 if (op == B_USB_RAW_COMMAND_INTERRUPT_TRANSFER) { 836 status = gUSBModule->queue_interrupt(endpointInfo->handle, 837 transferData, command.transfer.length, 838 usb_raw_callback, device); 839 } else if (op == B_USB_RAW_COMMAND_BULK_TRANSFER) { 840 status = gUSBModule->queue_bulk(endpointInfo->handle, 841 transferData, command.transfer.length, 842 usb_raw_callback, device); 843 } else { 844 status = gUSBModule->queue_isochronous(endpointInfo->handle, 845 command.isochronous.data, command.isochronous.length, 846 packetDescriptors, command.isochronous.packet_count, NULL, 847 0, usb_raw_callback, device); 848 } 849 850 if (status < B_OK) { 851 command.transfer.status = B_USB_RAW_STATUS_FAILED; 852 command.transfer.length = 0; 853 status = B_OK; 854 break; 855 } 856 857 status = acquire_sem_etc(device->notify, 1, B_KILL_CAN_INTERRUPT, 0); 858 if (status != B_OK) 859 return status; 860 861 command.transfer.status = device->status; 862 command.transfer.length = device->actual_length; 863 deviceLocker.Unlock(); 864 865 status = B_OK; 866 if (op == B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER) { 867 if (user_memcpy(command.isochronous.packet_descriptors, 868 packetDescriptors, descriptorsSize) != B_OK) { 869 status = B_BAD_ADDRESS; 870 } 871 } else { 872 if (inTransfer && user_memcpy(command.transfer.data, 873 transferData, command.transfer.length) != B_OK) { 874 status = B_BAD_ADDRESS; 875 } 876 } 877 878 break; 879 } 880 } 881 882 if (user_memcpy(buffer, &command, min_c(length, sizeof(command))) != B_OK) 883 return B_BAD_ADDRESS; 884 885 return status; 886 } 887 888 889 static status_t 890 usb_raw_read(void *cookie, off_t position, void *buffer, size_t *length) 891 { 892 TRACE((DRIVER_NAME": read()\n")); 893 *length = 0; 894 return B_OK; 895 } 896 897 898 static status_t 899 usb_raw_write(void *cookie, off_t position, const void *buffer, size_t *length) 900 { 901 TRACE((DRIVER_NAME": write()\n")); 902 *length = 0; 903 return B_OK; 904 } 905 906 907 // 908 //#pragma mark - 909 // 910 911 912 status_t 913 init_hardware() 914 { 915 TRACE((DRIVER_NAME": init_hardware()\n")); 916 return B_OK; 917 } 918 919 920 status_t 921 init_driver() 922 { 923 TRACE((DRIVER_NAME": init_driver()\n")); 924 static usb_notify_hooks notifyHooks = { 925 &usb_raw_device_added, 926 &usb_raw_device_removed 927 }; 928 929 gDeviceList = NULL; 930 gDeviceCount = 0; 931 mutex_init(&gDeviceListLock, "usb_raw device list lock"); 932 933 TRACE((DRIVER_NAME": trying module %s\n", B_USB_MODULE_NAME)); 934 status_t result = get_module(B_USB_MODULE_NAME, 935 (module_info **)&gUSBModule); 936 if (result < B_OK) { 937 TRACE((DRIVER_NAME": getting module failed 0x%08" B_PRIx32 "\n", 938 result)); 939 mutex_destroy(&gDeviceListLock); 940 return result; 941 } 942 943 gUSBModule->register_driver(DRIVER_NAME, NULL, 0, NULL); 944 gUSBModule->install_notify(DRIVER_NAME, ¬ifyHooks); 945 return B_OK; 946 } 947 948 949 void 950 uninit_driver() 951 { 952 TRACE((DRIVER_NAME": uninit_driver()\n")); 953 gUSBModule->uninstall_notify(DRIVER_NAME); 954 mutex_lock(&gDeviceListLock); 955 956 if (gDeviceNames) { 957 for (int32 i = 1; gDeviceNames[i]; i++) 958 free(gDeviceNames[i]); 959 free(gDeviceNames); 960 gDeviceNames = NULL; 961 } 962 963 mutex_destroy(&gDeviceListLock); 964 put_module(B_USB_MODULE_NAME); 965 } 966 967 968 const char ** 969 publish_devices() 970 { 971 TRACE((DRIVER_NAME": publish_devices()\n")); 972 if (gDeviceNames) { 973 for (int32 i = 0; gDeviceNames[i]; i++) 974 free(gDeviceNames[i]); 975 free(gDeviceNames); 976 gDeviceNames = NULL; 977 } 978 979 int32 index = 0; 980 gDeviceNames = (char **)malloc(sizeof(char *) * (gDeviceCount + 2)); 981 if (gDeviceNames == NULL) 982 return NULL; 983 984 gDeviceNames[index++] = strdup(DEVICE_NAME); 985 986 mutex_lock(&gDeviceListLock); 987 raw_device *element = gDeviceList; 988 while (element) { 989 gDeviceNames[index++] = strdup(element->name); 990 element = (raw_device *)element->link; 991 } 992 993 gDeviceNames[index++] = NULL; 994 mutex_unlock(&gDeviceListLock); 995 return (const char **)gDeviceNames; 996 } 997 998 999 device_hooks * 1000 find_device(const char *name) 1001 { 1002 TRACE((DRIVER_NAME": find_device()\n")); 1003 static device_hooks hooks = { 1004 &usb_raw_open, 1005 &usb_raw_close, 1006 &usb_raw_free, 1007 &usb_raw_ioctl, 1008 &usb_raw_read, 1009 &usb_raw_write, 1010 NULL, 1011 NULL, 1012 NULL, 1013 NULL 1014 }; 1015 1016 return &hooks; 1017 } 1018