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