1 /* 2 * Copyright 2003-2006, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 * Niels S. Reedijk 8 */ 9 10 11 #include <util/kernel_cpp.h> 12 #include "usb_private.h" 13 #include <USB_rle.h> 14 15 #define USB_MODULE_NAME "module" 16 17 Stack *gUSBStack = NULL; 18 19 20 /*! The function is an evil hack to allow <tt> <kdebug>usb_keyboard </tt> to 21 execute transfers. 22 When invoked the first time, a new transfer is started, each time the 23 function is called afterwards, it is checked whether the transfer is already 24 completed. If called with argv[1] == "cancel" the function cancels a 25 possibly pending transfer. 26 */ 27 static status_t 28 debug_run_transfer(Pipe *pipe, uint8 *data, size_t dataLength, 29 usb_request_data *requestData, bool cancel) 30 { 31 static uint8 transferBuffer[sizeof(Transfer)] 32 __attribute__((aligned(16))); 33 static Transfer *transfer = NULL; 34 35 BusManager *bus = pipe->GetBusManager(); 36 37 if (cancel) { 38 if (transfer != NULL) { 39 bus->CancelDebugTransfer(transfer); 40 transfer = NULL; 41 } 42 43 return B_OK; 44 } 45 46 if (transfer != NULL) { 47 status_t error = bus->CheckDebugTransfer(transfer); 48 if (error != B_DEV_PENDING) 49 transfer = NULL; 50 51 return error; 52 } 53 54 transfer = new(transferBuffer) Transfer(pipe); 55 transfer->SetData(data, dataLength); 56 transfer->SetRequestData(requestData); 57 58 status_t error = bus->StartDebugTransfer(transfer); 59 if (error != B_OK) { 60 transfer = NULL; 61 return error; 62 } 63 64 return B_DEV_PENDING; 65 } 66 67 68 static int 69 debug_get_pipe_for_id(int argc, char **argv) 70 { 71 if (gUSBStack == NULL) 72 return 1; 73 74 if (!is_debug_variable_defined("_usbPipeID")) 75 return 2; 76 77 uint64 id = get_debug_variable("_usbPipeID", 0); 78 Object *object = gUSBStack->GetObjectNoLock((usb_id)id); 79 if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) 80 return 3; 81 82 set_debug_variable("_usbPipe", (uint64)object); 83 return 0; 84 } 85 86 87 static int 88 debug_process_transfer(int argc, char **argv) 89 { 90 Pipe *pipe = (Pipe *)get_debug_variable("_usbPipe", 0); 91 if (pipe == NULL) 92 return B_BAD_VALUE; 93 94 uint8 *data = (uint8 *)get_debug_variable("_usbTransferData", 0); 95 size_t length = (size_t)get_debug_variable("_usbTransferLength", 0); 96 usb_request_data *requestData 97 = (usb_request_data *)get_debug_variable("_usbRequestData", 0); 98 99 return debug_run_transfer(pipe, data, length, requestData, 100 argc > 1 && strcmp(argv[1], "cancel") == 0); 101 } 102 103 104 static int 105 debug_clear_stall(int argc, char *argv[]) 106 { 107 Pipe *pipe = (Pipe *)get_debug_variable("_usbPipe", 0); 108 if (pipe == NULL) 109 return B_BAD_VALUE; 110 111 static usb_request_data requestData; 112 113 requestData.RequestType = USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_OUT; 114 requestData.Request = USB_REQUEST_CLEAR_FEATURE; 115 requestData.Value = USB_FEATURE_ENDPOINT_HALT; 116 requestData.Index = pipe->EndpointAddress() 117 | (pipe->Direction() == Pipe::In ? USB_ENDPOINT_ADDR_DIR_IN 118 : USB_ENDPOINT_ADDR_DIR_OUT); 119 requestData.Length = 0; 120 121 Pipe *parentPipe = ((Device *)pipe->Parent())->DefaultPipe(); 122 for (int tries = 0; tries < 100; tries++) { 123 status_t result 124 = debug_run_transfer(parentPipe, NULL, 0, &requestData, false); 125 126 if (result == B_DEV_PENDING) 127 continue; 128 129 if (result == B_OK) { 130 // clearing a stalled condition resets the data toggle 131 pipe->SetDataToggle(false); 132 return B_OK; 133 } 134 135 return result; 136 } 137 138 return B_TIMED_OUT; 139 } 140 141 142 static int32 143 bus_std_ops(int32 op, ...) 144 { 145 switch (op) { 146 case B_MODULE_INIT: { 147 TRACE_MODULE("init\n"); 148 if (gUSBStack) 149 return B_OK; 150 151 #ifdef TRACE_USB 152 set_dprintf_enabled(true); 153 #endif 154 Stack *stack = new(std::nothrow) Stack(); 155 TRACE_MODULE("usb_module: stack created %p\n", stack); 156 if (!stack) 157 return B_NO_MEMORY; 158 159 if (stack->InitCheck() != B_OK) { 160 delete stack; 161 return ENODEV; 162 } 163 164 gUSBStack = stack; 165 166 add_debugger_command("get_usb_pipe_for_id", 167 &debug_get_pipe_for_id, 168 "Sets _usbPipe by resolving _usbPipeID"); 169 add_debugger_command("usb_process_transfer", 170 &debug_process_transfer, 171 "Transfers _usbTransferData with _usbTransferLength" 172 " (and/or _usbRequestData) to pipe _usbPipe"); 173 add_debugger_command("usb_clear_stall", 174 &debug_clear_stall, 175 "Tries to issue a clear feature request for the endpoint halt" 176 " feature on pipe _usbPipe"); 177 break; 178 } 179 180 case B_MODULE_UNINIT: 181 TRACE_MODULE("uninit\n"); 182 delete gUSBStack; 183 gUSBStack = NULL; 184 185 remove_debugger_command("get_usb_pipe_for_id", 186 &debug_get_pipe_for_id); 187 break; 188 189 default: 190 return EINVAL; 191 } 192 193 return B_OK; 194 } 195 196 197 status_t 198 register_driver(const char *driverName, 199 const usb_support_descriptor *descriptors, 200 size_t count, const char *optionalRepublishDriverName) 201 { 202 return gUSBStack->RegisterDriver(driverName, descriptors, count, 203 optionalRepublishDriverName); 204 } 205 206 207 status_t 208 install_notify(const char *driverName, const usb_notify_hooks *hooks) 209 { 210 return gUSBStack->InstallNotify(driverName, hooks); 211 } 212 213 214 status_t 215 uninstall_notify(const char *driverName) 216 { 217 return gUSBStack->UninstallNotify(driverName); 218 } 219 220 221 const usb_device_descriptor * 222 get_device_descriptor(usb_device dev) 223 { 224 TRACE_MODULE("get_device_descriptor(%" B_PRId32 ")\n", dev); 225 Object *object = gUSBStack->GetObject(dev); 226 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 227 return NULL; 228 Device *device = (Device *)object; 229 if (device->InitCheck() != B_OK) 230 return NULL; 231 232 return device->DeviceDescriptor(); 233 } 234 235 236 const usb_configuration_info * 237 get_nth_configuration(usb_device dev, uint32 index) 238 { 239 TRACE_MODULE("get_nth_configuration(%" B_PRId32 ", %" B_PRIu32 ")\n", 240 dev, index); 241 Object *object = gUSBStack->GetObject(dev); 242 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 243 return NULL; 244 Device *device = (Device *)object; 245 if (device->InitCheck() != B_OK) 246 return NULL; 247 248 return device->ConfigurationAt((int32)index); 249 } 250 251 252 const usb_configuration_info * 253 get_configuration(usb_device dev) 254 { 255 TRACE_MODULE("get_configuration(%" B_PRId32 ")\n", dev); 256 Object *object = gUSBStack->GetObject(dev); 257 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 258 return NULL; 259 Device *device = (Device *)object; 260 if (device->InitCheck() != B_OK) 261 return NULL; 262 263 return device->Configuration(); 264 } 265 266 267 status_t 268 set_configuration(usb_device dev, 269 const usb_configuration_info *configuration) 270 { 271 TRACE_MODULE("set_configuration(%" B_PRId32 ", %p)\n", dev, 272 configuration); 273 Object *object = gUSBStack->GetObject(dev); 274 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 275 return B_DEV_INVALID_PIPE; 276 Device *device = (Device *)object; 277 if (device->InitCheck() != B_OK) 278 return B_NO_INIT; 279 280 return device->SetConfiguration(configuration); 281 } 282 283 284 status_t 285 set_alt_interface(usb_device dev, const usb_interface_info *interface) 286 { 287 TRACE_MODULE("set_alt_interface(%" B_PRId32 ", %p)\n", dev, interface); 288 Object *object = gUSBStack->GetObject(dev); 289 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 290 return B_DEV_INVALID_PIPE; 291 Device *device = (Device *)object; 292 if (device->InitCheck() != B_OK) 293 return B_NO_INIT; 294 295 return device->SetAltInterface(interface); 296 } 297 298 299 status_t 300 set_feature(usb_id handle, uint16 selector) 301 { 302 TRACE_MODULE("set_feature(%" B_PRId32 ", %d)\n", handle, selector); 303 Object *object = gUSBStack->GetObject(handle); 304 if (!object) 305 return B_DEV_INVALID_PIPE; 306 307 return object->SetFeature(selector); 308 } 309 310 311 status_t 312 clear_feature(usb_id handle, uint16 selector) 313 { 314 TRACE_MODULE("clear_feature(%" B_PRId32 ", %d)\n", handle, selector); 315 Object *object = gUSBStack->GetObject(handle); 316 if (!object) 317 return B_DEV_INVALID_PIPE; 318 319 return object->ClearFeature(selector); 320 } 321 322 323 status_t 324 get_status(usb_id handle, uint16 *status) 325 { 326 TRACE_MODULE("get_status(%" B_PRId32 ", %p)\n", handle, status); 327 if (!status) 328 return B_BAD_VALUE; 329 330 Object *object = gUSBStack->GetObject(handle); 331 if (!object) 332 return B_DEV_INVALID_PIPE; 333 334 return object->GetStatus(status); 335 } 336 337 338 status_t 339 get_descriptor(usb_device dev, uint8 type, uint8 index, uint16 languageID, 340 void *data, size_t dataLength, size_t *actualLength) 341 { 342 TRACE_MODULE("get_descriptor(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, %p, " 343 "%" B_PRIuSIZE ", %p)\n", 344 dev, type, index, languageID, data, dataLength, actualLength); 345 Object *object = gUSBStack->GetObject(dev); 346 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 347 return B_DEV_INVALID_PIPE; 348 Device *device = (Device *)object; 349 if (device->InitCheck() != B_OK) 350 return B_NO_INIT; 351 352 return device->GetDescriptor(type, index, languageID, 353 data, dataLength, actualLength); 354 } 355 356 357 status_t 358 send_request(usb_device dev, uint8 requestType, uint8 request, 359 uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength) 360 { 361 TRACE_MODULE("send_request(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, 0x%04x, " 362 "%d, %p, %p)\n", dev, requestType, request, value, index, length, 363 data, actualLength); 364 Object *object = gUSBStack->GetObject(dev); 365 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 366 return B_DEV_INVALID_PIPE; 367 Device *device = (Device *)object; 368 if (device->InitCheck() != B_OK) 369 return B_NO_INIT; 370 371 return device->DefaultPipe()->SendRequest(requestType, request, 372 value, index, length, data, length, actualLength); 373 } 374 375 376 status_t 377 queue_request(usb_device dev, uint8 requestType, uint8 request, 378 uint16 value, uint16 index, uint16 length, void *data, 379 usb_callback_func callback, void *callbackCookie) 380 { 381 TRACE_MODULE("queue_request(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, 0x%04x," 382 " %u, %p, %p, %p)\n", dev, requestType, request, value, index, 383 length, data, callback, callbackCookie); 384 Object *object = gUSBStack->GetObject(dev); 385 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 386 return B_DEV_INVALID_PIPE; 387 Device *device = (Device *)object; 388 if (device->InitCheck() != B_OK) 389 return B_NO_INIT; 390 391 return device->DefaultPipe()->QueueRequest(requestType, 392 request, value, index, length, data, length, callback, callbackCookie); 393 } 394 395 396 status_t 397 queue_interrupt(usb_pipe pipe, void *data, size_t dataLength, 398 usb_callback_func callback, void *callbackCookie) 399 { 400 TRACE_MODULE("queue_interrupt(%" B_PRId32 ", %p, %ld, %p, %p)\n", 401 pipe, data, dataLength, callback, callbackCookie); 402 Object *object = gUSBStack->GetObject(pipe); 403 if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) 404 return B_DEV_INVALID_PIPE; 405 406 return ((InterruptPipe *)object)->QueueInterrupt(data, dataLength, callback, 407 callbackCookie); 408 } 409 410 411 status_t 412 queue_bulk(usb_pipe pipe, void *data, size_t dataLength, 413 usb_callback_func callback, void *callbackCookie) 414 { 415 TRACE_MODULE("queue_bulk(%" B_PRId32 ", %p, %" B_PRIuSIZE ", %p, %p)\n", 416 pipe, data, dataLength, callback, callbackCookie); 417 Object *object = gUSBStack->GetObject(pipe); 418 if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 419 return B_DEV_INVALID_PIPE; 420 421 return ((BulkPipe *)object)->QueueBulk(data, dataLength, callback, 422 callbackCookie); 423 } 424 425 426 status_t 427 queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount, 428 usb_callback_func callback, void *callbackCookie) 429 { 430 TRACE_MODULE("queue_bulk_v(%" B_PRId32 ", %p, %" B_PRIuSIZE " %p, %p)\n", 431 pipe, vector, vectorCount, callback, callbackCookie); 432 Object *object = gUSBStack->GetObject(pipe); 433 if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 434 return B_DEV_INVALID_PIPE; 435 436 return ((BulkPipe *)object)->QueueBulkV(vector, vectorCount, callback, 437 callbackCookie, false); 438 } 439 440 441 status_t 442 queue_bulk_v_physical(usb_pipe pipe, iovec *vector, size_t vectorCount, 443 usb_callback_func callback, void *callbackCookie) 444 { 445 TRACE_MODULE("queue_bulk_v_physical(%" B_PRId32 ", %p, %" B_PRIuSIZE 446 ", %p, %p)\n", pipe, vector, vectorCount, callback, callbackCookie); 447 Object *object = gUSBStack->GetObject(pipe); 448 if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 449 return B_DEV_INVALID_PIPE; 450 451 return ((BulkPipe *)object)->QueueBulkV(vector, vectorCount, callback, 452 callbackCookie, true); 453 } 454 455 456 status_t 457 queue_isochronous(usb_pipe pipe, void *data, size_t dataLength, 458 usb_iso_packet_descriptor *packetDesc, uint32 packetCount, 459 uint32 *startingFrameNumber, uint32 flags, usb_callback_func callback, 460 void *callbackCookie) 461 { 462 TRACE_MODULE("queue_isochronous(%" B_PRId32 ", %p, %" B_PRIuSIZE ", %p, " 463 "%" B_PRId32 ", %p, 0x%08" B_PRIx32 ", %p, %p)\n", 464 pipe, data, dataLength, packetDesc, packetCount, startingFrameNumber, 465 flags, callback, callbackCookie); 466 Object *object = gUSBStack->GetObject(pipe); 467 if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) 468 return B_DEV_INVALID_PIPE; 469 470 return ((IsochronousPipe *)object)->QueueIsochronous(data, dataLength, 471 packetDesc, packetCount, startingFrameNumber, flags, callback, 472 callbackCookie); 473 } 474 475 476 status_t 477 set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets, 478 uint16 maxBufferDurationMS, uint16 sampleSize) 479 { 480 TRACE_MODULE("set_pipe_policy(%" B_PRId32 ", %d, %d, %d)\n", pipe, 481 maxQueuedPackets, maxBufferDurationMS, sampleSize); 482 Object *object = gUSBStack->GetObject(pipe); 483 if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) 484 return B_DEV_INVALID_PIPE; 485 486 return ((IsochronousPipe *)object)->SetPipePolicy(maxQueuedPackets, 487 maxBufferDurationMS, sampleSize); 488 } 489 490 491 status_t 492 cancel_queued_transfers(usb_pipe pipe) 493 { 494 TRACE_MODULE("cancel_queued_transfers(%" B_PRId32 ")\n", pipe); 495 Object *object = gUSBStack->GetObject(pipe); 496 if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) 497 return B_DEV_INVALID_PIPE; 498 499 return ((Pipe *)object)->CancelQueuedTransfers(false); 500 } 501 502 503 status_t 504 usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize) 505 { 506 TRACE_MODULE("usb_ioctl(%" B_PRIu32 ", %p, %" B_PRIuSIZE ")\n", opcode, 507 buffer, bufferSize); 508 509 switch (opcode) { 510 case 'DNAM': { 511 Object *object = gUSBStack->GetObject(*(usb_id *)buffer); 512 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 513 return B_BAD_VALUE; 514 Device *device = (Device *)object; 515 if (device->InitCheck() != B_OK) 516 return B_NO_INIT; 517 518 uint32 index = 0; 519 return device->BuildDeviceName((char *)buffer, &index, 520 bufferSize, NULL); 521 } 522 } 523 524 return B_DEV_INVALID_IOCTL; 525 } 526 527 528 status_t 529 get_nth_roothub(uint32 index, usb_device *rootHub) 530 { 531 if (!rootHub) 532 return B_BAD_VALUE; 533 534 BusManager *busManager = gUSBStack->BusManagerAt(index); 535 if (!busManager) 536 return B_ENTRY_NOT_FOUND; 537 538 Hub *hub = busManager->GetRootHub(); 539 if (!hub) 540 return B_NO_INIT; 541 542 *rootHub = hub->USBID(); 543 return B_OK; 544 } 545 546 547 status_t 548 get_nth_child(usb_device _hub, uint8 index, usb_device *childDevice) 549 { 550 if (!childDevice) 551 return B_BAD_VALUE; 552 553 Object *object = gUSBStack->GetObject(_hub); 554 if (!object || (object->Type() & USB_OBJECT_HUB) == 0) 555 return B_DEV_INVALID_PIPE; 556 557 Hub *hub = (Hub *)object; 558 for (uint8 i = 0; i < 8; i++) { 559 if (hub->ChildAt(i) == NULL) 560 continue; 561 562 if (index-- > 0) 563 continue; 564 565 *childDevice = hub->ChildAt(i)->USBID(); 566 return B_OK; 567 } 568 569 return B_ENTRY_NOT_FOUND; 570 } 571 572 573 status_t 574 get_device_parent(usb_device _device, usb_device *parentHub, uint8 *portIndex) 575 { 576 if (!parentHub || !portIndex) 577 return B_BAD_VALUE; 578 579 Object *object = gUSBStack->GetObject(_device); 580 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 581 return B_DEV_INVALID_PIPE; 582 583 Object *parent = object->Parent(); 584 if (!parent || (parent->Type() & USB_OBJECT_HUB) == 0) 585 return B_ENTRY_NOT_FOUND; 586 587 Hub *hub = (Hub *)parent; 588 for (uint8 i = 0; i < 8; i++) { 589 if (hub->ChildAt(i) == object) { 590 *portIndex = i; 591 *parentHub = hub->USBID(); 592 return B_OK; 593 } 594 } 595 596 return B_ERROR; 597 } 598 599 600 status_t 601 reset_port(usb_device _hub, uint8 portIndex) 602 { 603 Object *object = gUSBStack->GetObject(_hub); 604 if (!object || (object->Type() & USB_OBJECT_HUB) == 0) 605 return B_DEV_INVALID_PIPE; 606 607 Hub *hub = (Hub *)object; 608 return hub->ResetPort(portIndex); 609 } 610 611 612 status_t 613 disable_port(usb_device _hub, uint8 portIndex) 614 { 615 Object *object = gUSBStack->GetObject(_hub); 616 if (!object || (object->Type() & USB_OBJECT_HUB) == 0) 617 return B_DEV_INVALID_PIPE; 618 619 Hub *hub = (Hub *)object; 620 return hub->DisablePort(portIndex); 621 } 622 623 624 /* 625 This module exports the USB API v3 626 */ 627 struct usb_module_info gModuleInfoV3 = { 628 // First the bus_manager_info: 629 { 630 { 631 "bus_managers/usb/v3", 632 B_KEEP_LOADED, // Keep loaded, even if no driver requires it 633 bus_std_ops 634 }, 635 NULL // the rescan function 636 }, 637 638 register_driver, // register_driver 639 install_notify, // install_notify 640 uninstall_notify, // uninstall_notify 641 get_device_descriptor, // get_device_descriptor 642 get_nth_configuration, // get_nth_configuration 643 get_configuration, // get_configuration 644 set_configuration, // set_configuration 645 set_alt_interface, // set_alt_interface 646 set_feature, // set_feature 647 clear_feature, // clear_feature 648 get_status, // get_status 649 get_descriptor, // get_descriptor 650 send_request, // send_request 651 queue_interrupt, // queue_interrupt 652 queue_bulk, // queue_bulk 653 queue_bulk_v, // queue_bulk_v 654 queue_isochronous, // queue_isochronous 655 queue_request, // queue_request 656 set_pipe_policy, // set_pipe_policy 657 cancel_queued_transfers, // cancel_queued_transfers 658 usb_ioctl, // usb_ioctl 659 get_nth_roothub, // get_nth_roothub 660 get_nth_child, // get_nth_child 661 get_device_parent, // get_device_parent 662 reset_port, // reset_port 663 disable_port // disable_port 664 //queue_bulk_v_physical // queue_bulk_v_physical 665 }; 666 667 668 // 669 // #pragma mark - 670 // 671 672 673 const usb_device_descriptor * 674 get_device_descriptor_v2(const void *device) 675 { 676 return get_device_descriptor((usb_id)(ssize_t)device); 677 } 678 679 680 const usb_configuration_info * 681 get_nth_configuration_v2(const void *device, uint index) 682 { 683 return get_nth_configuration((usb_id)(ssize_t)device, index); 684 } 685 686 687 const usb_configuration_info * 688 get_configuration_v2(const void *device) 689 { 690 return get_configuration((usb_id)(ssize_t)device); 691 } 692 693 694 status_t 695 set_configuration_v2(const void *device, 696 const usb_configuration_info *configuration) 697 { 698 return set_configuration((usb_id)(ssize_t)device, configuration); 699 } 700 701 702 status_t 703 set_alt_interface_v2(const void *device, const usb_interface_info *interface) 704 { 705 return set_alt_interface((usb_id)(ssize_t)device, interface); 706 } 707 708 709 status_t 710 set_feature_v2(const void *object, uint16 selector) 711 { 712 return set_feature((usb_id)(ssize_t)object, selector); 713 } 714 715 716 status_t 717 clear_feature_v2(const void *object, uint16 selector) 718 { 719 return clear_feature((usb_id)(ssize_t)object, selector); 720 } 721 722 723 status_t 724 get_status_v2(const void *object, uint16 *status) 725 { 726 return get_status((usb_id)(ssize_t)object, status); 727 } 728 729 730 status_t 731 get_descriptor_v2(const void *device, uint8 type, uint8 index, 732 uint16 languageID, void *data, size_t dataLength, size_t *actualLength) 733 { 734 return get_descriptor((usb_id)(ssize_t)device, type, index, languageID, data, 735 dataLength, actualLength); 736 } 737 738 739 status_t 740 send_request_v2(const void *device, uint8 requestType, uint8 request, 741 uint16 value, uint16 index, uint16 length, void *data, 742 size_t /*dataLength*/, size_t *actualLength) 743 { 744 return send_request((usb_id)(ssize_t)device, requestType, request, value, index, 745 length, data, actualLength); 746 } 747 748 749 status_t 750 queue_request_v2(const void *device, uint8 requestType, uint8 request, 751 uint16 value, uint16 index, uint16 length, void *data, 752 size_t /*dataLength*/, usb_callback_func callback, void *callbackCookie) 753 { 754 return queue_request((usb_id)(ssize_t)device, requestType, request, value, index, 755 length, data, callback, callbackCookie); 756 } 757 758 759 status_t 760 queue_interrupt_v2(const void *pipe, void *data, size_t dataLength, 761 usb_callback_func callback, void *callbackCookie) 762 { 763 return queue_interrupt((usb_id)(ssize_t)pipe, data, dataLength, callback, 764 callbackCookie); 765 } 766 767 768 status_t 769 queue_bulk_v2(const void *pipe, void *data, size_t dataLength, 770 usb_callback_func callback, void *callbackCookie) 771 { 772 return queue_bulk((usb_id)(ssize_t)pipe, data, dataLength, callback, 773 callbackCookie); 774 } 775 776 777 status_t 778 queue_isochronous_v2(const void *pipe, void *data, size_t dataLength, 779 rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback, 780 void *callbackCookie) 781 { 782 // ToDo: convert rlea to usb_iso_packet_descriptor 783 // ToDo: use a flag to indicate that the callback shall produce a rlea 784 usb_iso_packet_descriptor *packetDesc = NULL; 785 return queue_isochronous((usb_id)(ssize_t)pipe, data, dataLength, packetDesc, 0, 786 NULL, 0, callback, callbackCookie); 787 } 788 789 790 status_t 791 set_pipe_policy_v2(const void *pipe, uint8 maxQueuedPackets, 792 uint16 maxBufferDurationMS, uint16 sampleSize) 793 { 794 return set_pipe_policy((usb_id)(ssize_t)pipe, maxQueuedPackets, maxBufferDurationMS, 795 sampleSize); 796 } 797 798 799 status_t 800 cancel_queued_transfers_v2(const void *pipe) 801 { 802 return cancel_queued_transfers((usb_id)(ssize_t)pipe); 803 } 804 805 806 struct usb_module_info_v2 { 807 bus_manager_info binfo; 808 status_t (*register_driver)(const char *, const usb_support_descriptor *, size_t, const char *); 809 status_t (*install_notify)(const char *, const usb_notify_hooks *); 810 status_t (*uninstall_notify)(const char *); 811 const usb_device_descriptor *(*get_device_descriptor)(const void *); 812 const usb_configuration_info *(*get_nth_configuration)(const void *, uint); 813 const usb_configuration_info *(*get_configuration)(const void *); 814 status_t (*set_configuration)(const void *, const usb_configuration_info *); 815 status_t (*set_alt_interface)(const void *, const usb_interface_info *); 816 status_t (*set_feature)(const void *, uint16); 817 status_t (*clear_feature)(const void *, uint16); 818 status_t (*get_status)(const void *, uint16 *); 819 status_t (*get_descriptor)(const void *, uint8, uint8, uint16, void *, size_t, size_t *); 820 status_t (*send_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, size_t *); 821 status_t (*queue_interrupt)(const void *, void *, size_t, usb_callback_func, void *); 822 status_t (*queue_bulk)(const void *, void *, size_t, usb_callback_func, void *); 823 status_t (*queue_isochronous)(const void *, void *, size_t, rlea *, uint16, usb_callback_func, void *); 824 status_t (*queue_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, usb_callback_func, void *); 825 status_t (*set_pipe_policy)(const void *, uint8, uint16, uint16); 826 status_t (*cancel_queued_transfers)(const void *); 827 status_t (*usb_ioctl)(uint32 opcode, void *,size_t); 828 }; 829 830 831 /* 832 This module exports the USB API v2 833 */ 834 struct usb_module_info_v2 gModuleInfoV2 = { 835 // First the bus_manager_info: 836 { 837 { 838 "bus_managers/usb/v2", 839 B_KEEP_LOADED, // Keep loaded, even if no driver requires it 840 bus_std_ops 841 }, 842 NULL // the rescan function 843 }, 844 845 register_driver, // register_driver 846 install_notify, // install_notify 847 uninstall_notify, // uninstall_notify 848 get_device_descriptor_v2, // get_device_descriptor 849 get_nth_configuration_v2, // get_nth_configuration 850 get_configuration_v2, // get_configuration 851 set_configuration_v2, // set_configuration 852 set_alt_interface_v2, // set_alt_interface 853 set_feature_v2, // set_feature 854 clear_feature_v2, // clear_feature 855 get_status_v2, // get_status 856 get_descriptor_v2, // get_descriptor 857 send_request_v2, // send_request 858 queue_interrupt_v2, // queue_interrupt 859 queue_bulk_v2, // queue_bulk 860 queue_isochronous_v2, // queue_isochronous 861 queue_request_v2, // queue_request 862 set_pipe_policy_v2, // set_pipe_policy 863 cancel_queued_transfers_v2, // cancel_queued_transfers 864 usb_ioctl // usb_ioctl 865 }; 866 867 868 // 869 // #pragma mark - 870 // 871 872 873 module_info *modules[] = { 874 (module_info *)&gModuleInfoV2, 875 (module_info *)&gModuleInfoV3, 876 NULL 877 }; 878