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