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 temp[4]; 547 status = B_OK; 548 549 // We need to fetch the default language code, first. 550 if (gUSBModule->get_descriptor(device->device, 551 USB_DESCRIPTOR_STRING, 0, 0, 552 temp, 4, &actualLength) < B_OK 553 || actualLength != 4 554 || temp[1] != USB_DESCRIPTOR_STRING) { 555 command.string.status = B_USB_RAW_STATUS_ABORTED; 556 command.string.length = 0; 557 break; 558 } 559 const uint16 langid = (temp[2] | (temp[3] << 8)); 560 561 // Now fetch the string length. 562 if (gUSBModule->get_descriptor(device->device, 563 USB_DESCRIPTOR_STRING, command.string.string_index, langid, 564 temp, 2, &actualLength) < B_OK 565 || actualLength != 2 566 || temp[1] != USB_DESCRIPTOR_STRING) { 567 command.string.status = B_USB_RAW_STATUS_ABORTED; 568 command.string.length = 0; 569 break; 570 } 571 572 uint8 stringLength = MIN(temp[0], command.string.length); 573 char *string = (char *)malloc(stringLength); 574 if (string == NULL) { 575 command.string.status = B_USB_RAW_STATUS_ABORTED; 576 command.string.length = 0; 577 status = B_NO_MEMORY; 578 break; 579 } 580 581 if (gUSBModule->get_descriptor(device->device, 582 USB_DESCRIPTOR_STRING, command.string.string_index, langid, 583 string, stringLength, &actualLength) < B_OK 584 || actualLength != stringLength) { 585 command.string.status = B_USB_RAW_STATUS_ABORTED; 586 command.string.length = 0; 587 free(string); 588 break; 589 } 590 591 if (!IS_USER_ADDRESS(command.string.descriptor) 592 || user_memcpy(command.string.descriptor, string, 593 stringLength) != B_OK) { 594 free(string); 595 return B_BAD_ADDRESS; 596 } 597 598 command.string.status = B_USB_RAW_STATUS_SUCCESS; 599 command.string.length = stringLength; 600 free(string); 601 break; 602 } 603 604 case B_USB_RAW_COMMAND_GET_DESCRIPTOR: 605 { 606 if (length < sizeof(command.descriptor)) 607 return B_BUFFER_OVERFLOW; 608 609 size_t actualLength = 0; 610 uint8 firstTwoBytes[2]; 611 status = B_OK; 612 613 if (gUSBModule->get_descriptor(device->device, 614 command.descriptor.type, command.descriptor.index, 615 command.descriptor.language_id, firstTwoBytes, 2, 616 &actualLength) < B_OK 617 || actualLength != 2 618 || firstTwoBytes[1] != command.descriptor.type) { 619 command.descriptor.status = B_USB_RAW_STATUS_ABORTED; 620 command.descriptor.length = 0; 621 break; 622 } 623 624 uint8 descriptorLength = MIN(firstTwoBytes[0], 625 command.descriptor.length); 626 uint8 *descriptorBuffer = (uint8 *)malloc(descriptorLength); 627 if (descriptorBuffer == NULL) { 628 command.descriptor.status = B_USB_RAW_STATUS_ABORTED; 629 command.descriptor.length = 0; 630 status = B_NO_MEMORY; 631 break; 632 } 633 634 if (gUSBModule->get_descriptor(device->device, 635 command.descriptor.type, command.descriptor.index, 636 command.descriptor.language_id, descriptorBuffer, 637 descriptorLength, &actualLength) < B_OK 638 || actualLength != descriptorLength) { 639 command.descriptor.status = B_USB_RAW_STATUS_ABORTED; 640 command.descriptor.length = 0; 641 free(descriptorBuffer); 642 break; 643 } 644 645 if (!IS_USER_ADDRESS(command.descriptor.data) 646 || user_memcpy(command.descriptor.data, descriptorBuffer, 647 descriptorLength) != B_OK) { 648 free(descriptorBuffer); 649 return B_BAD_ADDRESS; 650 } 651 652 command.descriptor.status = B_USB_RAW_STATUS_SUCCESS; 653 command.descriptor.length = descriptorLength; 654 free(descriptorBuffer); 655 break; 656 } 657 658 case B_USB_RAW_COMMAND_SET_CONFIGURATION: 659 { 660 if (length < sizeof(command.config)) 661 return B_BUFFER_OVERFLOW; 662 663 status = B_OK; 664 const usb_configuration_info *configurationInfo = 665 usb_raw_get_configuration(device, command.config.config_index, 666 &command.config.status); 667 if (configurationInfo == NULL) 668 break; 669 670 if (gUSBModule->set_configuration(device->device, 671 configurationInfo) < B_OK) { 672 command.config.status = B_USB_RAW_STATUS_FAILED; 673 break; 674 } 675 676 command.config.status = B_USB_RAW_STATUS_SUCCESS; 677 break; 678 } 679 680 case B_USB_RAW_COMMAND_SET_ALT_INTERFACE: 681 { 682 if (length < sizeof(command.alternate)) 683 return B_BUFFER_OVERFLOW; 684 685 status = B_OK; 686 const usb_configuration_info *configurationInfo = 687 usb_raw_get_configuration(device, 688 command.alternate.config_index, 689 &command.alternate.status); 690 if (configurationInfo == NULL) 691 break; 692 693 if (command.alternate.interface_index 694 >= configurationInfo->interface_count) { 695 command.alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE; 696 break; 697 } 698 699 const usb_interface_list *interfaceList = 700 &configurationInfo->interface[command.alternate.interface_index]; 701 if (command.alternate.alternate_info >= interfaceList->alt_count) { 702 command.alternate.status = B_USB_RAW_STATUS_INVALID_INTERFACE; 703 break; 704 } 705 706 if (gUSBModule->set_alt_interface(device->device, 707 &interfaceList->alt[command.alternate.alternate_info]) < B_OK) { 708 command.alternate.status = B_USB_RAW_STATUS_FAILED; 709 break; 710 } 711 712 command.alternate.status = B_USB_RAW_STATUS_SUCCESS; 713 break; 714 } 715 716 case B_USB_RAW_COMMAND_CONTROL_TRANSFER: 717 { 718 if (length < sizeof(command.control)) 719 return B_BUFFER_OVERFLOW; 720 721 void *controlData = malloc(command.control.length); 722 if (controlData == NULL) 723 return B_NO_MEMORY; 724 MemoryDeleter dataDeleter(controlData); 725 726 bool inTransfer = (command.control.request_type 727 & USB_ENDPOINT_ADDR_DIR_IN) != 0; 728 if (!IS_USER_ADDRESS(command.control.data) 729 || (!inTransfer && user_memcpy(controlData, 730 command.control.data, command.control.length) != B_OK)) { 731 return B_BAD_ADDRESS; 732 } 733 734 MutexLocker deviceLocker(device->lock); 735 if (gUSBModule->queue_request(device->device, 736 command.control.request_type, command.control.request, 737 command.control.value, command.control.index, 738 command.control.length, controlData, 739 usb_raw_callback, device) < B_OK) { 740 command.control.status = B_USB_RAW_STATUS_FAILED; 741 command.control.length = 0; 742 status = B_OK; 743 break; 744 } 745 746 status = acquire_sem_etc(device->notify, 1, B_KILL_CAN_INTERRUPT, 0); 747 if (status != B_OK) { 748 gUSBModule->cancel_queued_requests(device->device); 749 acquire_sem(device->notify); 750 } 751 752 command.control.status = device->status; 753 command.control.length = device->actual_length; 754 deviceLocker.Unlock(); 755 756 if (command.control.status == B_OK) 757 status = B_OK; 758 if (inTransfer && user_memcpy(command.control.data, controlData, 759 command.control.length) != B_OK) { 760 status = B_BAD_ADDRESS; 761 } 762 break; 763 } 764 765 case B_USB_RAW_COMMAND_INTERRUPT_TRANSFER: 766 case B_USB_RAW_COMMAND_BULK_TRANSFER: 767 case B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER: 768 { 769 if (length < sizeof(command.transfer)) 770 return B_BUFFER_OVERFLOW; 771 772 status = B_OK; 773 const usb_configuration_info *configurationInfo = 774 gUSBModule->get_configuration(device->device); 775 if (configurationInfo == NULL) { 776 command.transfer.status = B_USB_RAW_STATUS_INVALID_CONFIGURATION; 777 break; 778 } 779 780 if (command.transfer.interface >= configurationInfo->interface_count) { 781 command.transfer.status = B_USB_RAW_STATUS_INVALID_INTERFACE; 782 break; 783 } 784 785 const usb_interface_info *interfaceInfo = 786 configurationInfo->interface[command.transfer.interface].active; 787 if (interfaceInfo == NULL) { 788 command.transfer.status = B_USB_RAW_STATUS_ABORTED; 789 break; 790 } 791 792 if (command.transfer.endpoint >= interfaceInfo->endpoint_count) { 793 command.transfer.status = B_USB_RAW_STATUS_INVALID_ENDPOINT; 794 break; 795 } 796 797 const usb_endpoint_info *endpointInfo = 798 &interfaceInfo->endpoint[command.transfer.endpoint]; 799 if (!endpointInfo->handle) { 800 command.transfer.status = B_USB_RAW_STATUS_INVALID_ENDPOINT; 801 break; 802 } 803 804 size_t descriptorsSize = 0; 805 usb_iso_packet_descriptor *packetDescriptors = NULL; 806 void *transferData = NULL; 807 MemoryDeleter descriptorsDeleter, dataDeleter; 808 809 bool inTransfer = (endpointInfo->descr->endpoint_address 810 & USB_ENDPOINT_ADDR_DIR_IN) != 0; 811 if (op == B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER) { 812 if (length < sizeof(command.isochronous)) 813 return B_BUFFER_OVERFLOW; 814 815 descriptorsSize = sizeof(usb_iso_packet_descriptor) 816 * command.isochronous.packet_count; 817 packetDescriptors 818 = (usb_iso_packet_descriptor *)malloc(descriptorsSize); 819 if (packetDescriptors == NULL) { 820 command.transfer.status = B_USB_RAW_STATUS_NO_MEMORY; 821 command.transfer.length = 0; 822 break; 823 } 824 descriptorsDeleter.SetTo(packetDescriptors); 825 826 if (!IS_USER_ADDRESS(command.isochronous.data) 827 || !IS_USER_ADDRESS(command.isochronous.packet_descriptors) 828 || user_memcpy(packetDescriptors, 829 command.isochronous.packet_descriptors, 830 descriptorsSize) != B_OK) { 831 return B_BAD_ADDRESS; 832 } 833 } else { 834 transferData = malloc(command.transfer.length); 835 if (transferData == NULL) { 836 command.transfer.status = B_USB_RAW_STATUS_NO_MEMORY; 837 command.transfer.length = 0; 838 break; 839 } 840 dataDeleter.SetTo(transferData); 841 842 if (!IS_USER_ADDRESS(command.transfer.data) || (!inTransfer 843 && user_memcpy(transferData, command.transfer.data, 844 command.transfer.length) != B_OK)) { 845 return B_BAD_ADDRESS; 846 } 847 } 848 849 status_t status; 850 MutexLocker deviceLocker(device->lock); 851 if (op == B_USB_RAW_COMMAND_INTERRUPT_TRANSFER) { 852 status = gUSBModule->queue_interrupt(endpointInfo->handle, 853 transferData, command.transfer.length, 854 usb_raw_callback, device); 855 } else if (op == B_USB_RAW_COMMAND_BULK_TRANSFER) { 856 status = gUSBModule->queue_bulk(endpointInfo->handle, 857 transferData, command.transfer.length, 858 usb_raw_callback, device); 859 } else { 860 status = gUSBModule->queue_isochronous(endpointInfo->handle, 861 command.isochronous.data, command.isochronous.length, 862 packetDescriptors, command.isochronous.packet_count, NULL, 863 0, usb_raw_callback, device); 864 } 865 866 if (status < B_OK) { 867 command.transfer.status = B_USB_RAW_STATUS_FAILED; 868 command.transfer.length = 0; 869 status = B_OK; 870 break; 871 } 872 873 status = acquire_sem_etc(device->notify, 1, B_KILL_CAN_INTERRUPT, 0); 874 if (status != B_OK) { 875 gUSBModule->cancel_queued_transfers(endpointInfo->handle); 876 acquire_sem(device->notify); 877 } 878 879 command.transfer.status = device->status; 880 command.transfer.length = device->actual_length; 881 deviceLocker.Unlock(); 882 883 if (command.transfer.status == B_OK) 884 status = B_OK; 885 if (op == B_USB_RAW_COMMAND_ISOCHRONOUS_TRANSFER) { 886 if (user_memcpy(command.isochronous.packet_descriptors, 887 packetDescriptors, descriptorsSize) != B_OK) { 888 status = B_BAD_ADDRESS; 889 } 890 } else { 891 if (inTransfer && user_memcpy(command.transfer.data, 892 transferData, command.transfer.length) != B_OK) { 893 status = B_BAD_ADDRESS; 894 } 895 } 896 897 break; 898 } 899 } 900 901 if (user_memcpy(buffer, &command, min_c(length, sizeof(command))) != B_OK) 902 return B_BAD_ADDRESS; 903 904 return status; 905 } 906 907 908 static status_t 909 usb_raw_read(void *cookie, off_t position, void *buffer, size_t *length) 910 { 911 TRACE((DRIVER_NAME": read()\n")); 912 *length = 0; 913 return B_OK; 914 } 915 916 917 static status_t 918 usb_raw_write(void *cookie, off_t position, const void *buffer, size_t *length) 919 { 920 TRACE((DRIVER_NAME": write()\n")); 921 *length = 0; 922 return B_OK; 923 } 924 925 926 // 927 //#pragma mark - 928 // 929 930 931 status_t 932 init_hardware() 933 { 934 TRACE((DRIVER_NAME": init_hardware()\n")); 935 return B_OK; 936 } 937 938 939 status_t 940 init_driver() 941 { 942 TRACE((DRIVER_NAME": init_driver()\n")); 943 static usb_notify_hooks notifyHooks = { 944 &usb_raw_device_added, 945 &usb_raw_device_removed 946 }; 947 948 gDeviceList = NULL; 949 gDeviceCount = 0; 950 mutex_init(&gDeviceListLock, "usb_raw device list lock"); 951 952 TRACE((DRIVER_NAME": trying module %s\n", B_USB_MODULE_NAME)); 953 status_t result = get_module(B_USB_MODULE_NAME, 954 (module_info **)&gUSBModule); 955 if (result < B_OK) { 956 TRACE((DRIVER_NAME": getting module failed 0x%08" B_PRIx32 "\n", 957 result)); 958 mutex_destroy(&gDeviceListLock); 959 return result; 960 } 961 962 gUSBModule->register_driver(DRIVER_NAME, NULL, 0, NULL); 963 gUSBModule->install_notify(DRIVER_NAME, ¬ifyHooks); 964 return B_OK; 965 } 966 967 968 void 969 uninit_driver() 970 { 971 TRACE((DRIVER_NAME": uninit_driver()\n")); 972 gUSBModule->uninstall_notify(DRIVER_NAME); 973 mutex_lock(&gDeviceListLock); 974 975 if (gDeviceNames) { 976 for (int32 i = 1; gDeviceNames[i]; i++) 977 free(gDeviceNames[i]); 978 free(gDeviceNames); 979 gDeviceNames = NULL; 980 } 981 982 mutex_destroy(&gDeviceListLock); 983 put_module(B_USB_MODULE_NAME); 984 } 985 986 987 const char ** 988 publish_devices() 989 { 990 TRACE((DRIVER_NAME": publish_devices()\n")); 991 if (gDeviceNames) { 992 for (int32 i = 0; gDeviceNames[i]; i++) 993 free(gDeviceNames[i]); 994 free(gDeviceNames); 995 gDeviceNames = NULL; 996 } 997 998 int32 index = 0; 999 gDeviceNames = (char **)malloc(sizeof(char *) * (gDeviceCount + 2)); 1000 if (gDeviceNames == NULL) 1001 return NULL; 1002 1003 gDeviceNames[index++] = strdup(DEVICE_NAME); 1004 1005 mutex_lock(&gDeviceListLock); 1006 raw_device *element = gDeviceList; 1007 while (element) { 1008 gDeviceNames[index++] = strdup(element->name); 1009 element = (raw_device *)element->link; 1010 } 1011 1012 gDeviceNames[index++] = NULL; 1013 mutex_unlock(&gDeviceListLock); 1014 return (const char **)gDeviceNames; 1015 } 1016 1017 1018 device_hooks * 1019 find_device(const char *name) 1020 { 1021 TRACE((DRIVER_NAME": find_device()\n")); 1022 static device_hooks hooks = { 1023 &usb_raw_open, 1024 &usb_raw_close, 1025 &usb_raw_free, 1026 &usb_raw_ioctl, 1027 &usb_raw_read, 1028 &usb_raw_write, 1029 NULL, 1030 NULL, 1031 NULL, 1032 NULL 1033 }; 1034 1035 return &hooks; 1036 } 1037