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 #include <util/kernel_cpp.h> 11 #include "usb_private.h" 12 #include <USB_rle.h> 13 14 #define USB_MODULE_NAME "module" 15 16 Stack *gUSBStack = NULL; 17 18 19 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 20 static int 21 debug_get_pipe_for_id(int argc, char **argv) 22 { 23 if (gUSBStack == NULL) 24 return 1; 25 26 if (!is_debug_variable_defined("_usbPipeID")) 27 return 2; 28 29 uint64 id = get_debug_variable("_usbPipeID", 0); 30 Object *object = gUSBStack->GetObjectNoLock((usb_id)id); 31 if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) 32 return 3; 33 34 // check if we support debug transfers for this pipe (only on UHCI for now) 35 if (object->GetBusManager()->TypeName()[0] != 'u') 36 return 4; 37 38 set_debug_variable("_usbPipe", (uint64)object); 39 return 0; 40 } 41 #endif 42 43 44 static int32 45 bus_std_ops(int32 op, ...) 46 { 47 switch (op) { 48 case B_MODULE_INIT: { 49 TRACE_MODULE("init\n"); 50 if (gUSBStack) 51 return B_OK; 52 53 #ifdef HAIKU_TARGET_PLATFORM_BEOS 54 // This code is to handle plain R5 (non-BONE) where the same module 55 // gets loaded multiple times (once for each exported module 56 // interface, the USB v2 and v3 API in our case). We don't want to 57 // ever create multiple stacks however, so we "share" the same stack 58 // for both modules by storing it's address in a shared area. 59 void *address = NULL; 60 area_id shared = find_area("shared usb stack"); 61 if (shared >= B_OK && clone_area("usb stack clone", &address, 62 B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA, shared) >= B_OK) { 63 gUSBStack = *((Stack **)address); 64 TRACE_MODULE("found shared stack at %p\n", gUSBStack); 65 return B_OK; 66 } 67 #endif 68 69 #ifdef TRACE_USB 70 set_dprintf_enabled(true); 71 #ifndef HAIKU_TARGET_PLATFORM_HAIKU 72 load_driver_symbols("usb"); 73 #endif 74 #endif 75 Stack *stack = new(std::nothrow) Stack(); 76 TRACE_MODULE("usb_module: stack created %p\n", stack); 77 if (!stack) 78 return B_NO_MEMORY; 79 80 if (stack->InitCheck() != B_OK) { 81 delete stack; 82 return ENODEV; 83 } 84 85 gUSBStack = stack; 86 87 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 88 add_debugger_command("get_usb_pipe_for_id", 89 &debug_get_pipe_for_id, 90 "Gets the config for a USB pipe"); 91 #elif HAIKU_TARGET_PLATFORM_BEOS 92 // Plain R5 workaround, see comment above. 93 shared = create_area("shared usb stack", &address, 94 B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, 95 B_KERNEL_WRITE_AREA); 96 if (shared >= B_OK) 97 *((Stack **)address) = gUSBStack; 98 #endif 99 break; 100 } 101 102 case B_MODULE_UNINIT: 103 TRACE_MODULE("uninit\n"); 104 delete gUSBStack; 105 gUSBStack = NULL; 106 107 #ifdef HAIKU_TARGET_PLATFORM_HAIKU 108 remove_debugger_command("get_usb_pipe_for_id", 109 &debug_get_pipe_for_id); 110 #endif 111 break; 112 113 default: 114 return EINVAL; 115 } 116 117 return B_OK; 118 } 119 120 121 status_t 122 register_driver(const char *driverName, 123 const usb_support_descriptor *descriptors, 124 size_t count, const char *optionalRepublishDriverName) 125 { 126 return gUSBStack->RegisterDriver(driverName, descriptors, count, 127 optionalRepublishDriverName); 128 } 129 130 131 status_t 132 install_notify(const char *driverName, const usb_notify_hooks *hooks) 133 { 134 return gUSBStack->InstallNotify(driverName, hooks); 135 } 136 137 138 status_t 139 uninstall_notify(const char *driverName) 140 { 141 return gUSBStack->UninstallNotify(driverName); 142 } 143 144 145 const usb_device_descriptor * 146 get_device_descriptor(usb_device device) 147 { 148 TRACE_MODULE("get_device_descriptor(%ld)\n", device); 149 Object *object = gUSBStack->GetObject(device); 150 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 151 return NULL; 152 153 return ((Device *)object)->DeviceDescriptor(); 154 } 155 156 157 const usb_configuration_info * 158 get_nth_configuration(usb_device device, uint32 index) 159 { 160 TRACE_MODULE("get_nth_configuration(%ld, %lu)\n", device, index); 161 Object *object = gUSBStack->GetObject(device); 162 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 163 return NULL; 164 165 return ((Device *)object)->ConfigurationAt((int32)index); 166 } 167 168 169 const usb_configuration_info * 170 get_configuration(usb_device device) 171 { 172 TRACE_MODULE("get_configuration(%ld)\n", device); 173 Object *object = gUSBStack->GetObject(device); 174 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 175 return NULL; 176 177 return ((Device *)object)->Configuration(); 178 } 179 180 181 status_t 182 set_configuration(usb_device device, 183 const usb_configuration_info *configuration) 184 { 185 TRACE_MODULE("set_configuration(%ld, %p)\n", device, configuration); 186 Object *object = gUSBStack->GetObject(device); 187 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 188 return B_DEV_INVALID_PIPE; 189 190 return ((Device *)object)->SetConfiguration(configuration); 191 } 192 193 194 status_t 195 set_alt_interface(usb_device device, const usb_interface_info *interface) 196 { 197 TRACE_MODULE("set_alt_interface(%ld, %p)\n", device, interface); 198 Object *object = gUSBStack->GetObject(device); 199 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 200 return B_DEV_INVALID_PIPE; 201 202 return ((Device *)object)->SetAltInterface(interface); 203 } 204 205 206 status_t 207 set_feature(usb_id handle, uint16 selector) 208 { 209 TRACE_MODULE("set_feature(%ld, %d)\n", handle, selector); 210 Object *object = gUSBStack->GetObject(handle); 211 if (!object) 212 return B_DEV_INVALID_PIPE; 213 214 return object->SetFeature(selector); 215 } 216 217 218 status_t 219 clear_feature(usb_id handle, uint16 selector) 220 { 221 TRACE_MODULE("clear_feature(%ld, %d)\n", handle, selector); 222 Object *object = gUSBStack->GetObject(handle); 223 if (!object) 224 return B_DEV_INVALID_PIPE; 225 226 return object->ClearFeature(selector); 227 } 228 229 230 status_t 231 get_status(usb_id handle, uint16 *status) 232 { 233 TRACE_MODULE("get_status(%ld, %p)\n", handle, status); 234 if (!status) 235 return B_BAD_VALUE; 236 237 Object *object = gUSBStack->GetObject(handle); 238 if (!object) 239 return B_DEV_INVALID_PIPE; 240 241 return object->GetStatus(status); 242 } 243 244 245 status_t 246 get_descriptor(usb_device device, uint8 type, uint8 index, uint16 languageID, 247 void *data, size_t dataLength, size_t *actualLength) 248 { 249 TRACE_MODULE("get_descriptor(%ld, 0x%02x, 0x%02x, 0x%04x, %p, %ld, %p)\n", 250 device, type, index, languageID, data, dataLength, actualLength); 251 Object *object = gUSBStack->GetObject(device); 252 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 253 return B_DEV_INVALID_PIPE; 254 255 return ((Device *)object)->GetDescriptor(type, index, languageID, 256 data, dataLength, actualLength); 257 } 258 259 260 status_t 261 send_request(usb_device device, uint8 requestType, uint8 request, 262 uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength) 263 { 264 TRACE_MODULE("send_request(%ld, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, %p, %p)\n", 265 device, requestType, request, value, index, length, data, actualLength); 266 Object *object = gUSBStack->GetObject(device); 267 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 268 return B_DEV_INVALID_PIPE; 269 270 return ((Device *)object)->DefaultPipe()->SendRequest(requestType, request, 271 value, index, length, data, length, actualLength); 272 } 273 274 275 status_t 276 queue_request(usb_device device, uint8 requestType, uint8 request, 277 uint16 value, uint16 index, uint16 length, void *data, 278 usb_callback_func callback, void *callbackCookie) 279 { 280 TRACE_MODULE("queue_request(%ld, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %u, %p, %p, %p)\n", 281 device, requestType, request, value, index, length, data, callback, 282 callbackCookie); 283 Object *object = gUSBStack->GetObject(device); 284 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 285 return B_DEV_INVALID_PIPE; 286 287 return ((Device *)object)->DefaultPipe()->QueueRequest(requestType, 288 request, value, index, length, data, length, callback, callbackCookie); 289 } 290 291 292 status_t 293 queue_interrupt(usb_pipe pipe, void *data, size_t dataLength, 294 usb_callback_func callback, void *callbackCookie) 295 { 296 TRACE_MODULE("queue_interrupt(%ld, %p, %ld, %p, %p)\n", 297 pipe, data, dataLength, callback, callbackCookie); 298 Object *object = gUSBStack->GetObject(pipe); 299 if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) 300 return B_DEV_INVALID_PIPE; 301 302 return ((InterruptPipe *)object)->QueueInterrupt(data, dataLength, callback, 303 callbackCookie); 304 } 305 306 307 status_t 308 queue_bulk(usb_pipe pipe, void *data, size_t dataLength, 309 usb_callback_func callback, void *callbackCookie) 310 { 311 TRACE_MODULE("queue_bulk(%ld, %p, %ld, %p, %p)\n", 312 pipe, data, dataLength, callback, callbackCookie); 313 Object *object = gUSBStack->GetObject(pipe); 314 if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 315 return B_DEV_INVALID_PIPE; 316 317 return ((BulkPipe *)object)->QueueBulk(data, dataLength, callback, 318 callbackCookie); 319 } 320 321 322 status_t 323 queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount, 324 usb_callback_func callback, void *callbackCookie) 325 { 326 TRACE_MODULE("queue_bulk_v(%ld, %p, %ld, %p, %p)\n", 327 pipe, vector, vectorCount, callback, callbackCookie); 328 Object *object = gUSBStack->GetObject(pipe); 329 if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 330 return B_DEV_INVALID_PIPE; 331 332 return ((BulkPipe *)object)->QueueBulkV(vector, vectorCount, callback, 333 callbackCookie, false); 334 } 335 336 337 status_t 338 queue_bulk_v_physical(usb_pipe pipe, iovec *vector, size_t vectorCount, 339 usb_callback_func callback, void *callbackCookie) 340 { 341 TRACE_MODULE("queue_bulk_v_physical(%ld, %p, %ld, %p, %p)\n", 342 pipe, vector, vectorCount, callback, callbackCookie); 343 Object *object = gUSBStack->GetObject(pipe); 344 if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 345 return B_DEV_INVALID_PIPE; 346 347 return ((BulkPipe *)object)->QueueBulkV(vector, vectorCount, callback, 348 callbackCookie, true); 349 } 350 351 352 status_t 353 queue_isochronous(usb_pipe pipe, void *data, size_t dataLength, 354 usb_iso_packet_descriptor *packetDesc, uint32 packetCount, 355 uint32 *startingFrameNumber, uint32 flags, usb_callback_func callback, 356 void *callbackCookie) 357 { 358 TRACE_MODULE("queue_isochronous(%ld, %p, %ld, %p, %ld, %p, 0x%08lx, %p, %p)\n", 359 pipe, data, dataLength, packetDesc, packetCount, startingFrameNumber, 360 flags, callback, callbackCookie); 361 Object *object = gUSBStack->GetObject(pipe); 362 if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) 363 return B_DEV_INVALID_PIPE; 364 365 return ((IsochronousPipe *)object)->QueueIsochronous(data, dataLength, 366 packetDesc, packetCount, startingFrameNumber, flags, callback, 367 callbackCookie); 368 } 369 370 371 status_t 372 set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets, 373 uint16 maxBufferDurationMS, uint16 sampleSize) 374 { 375 TRACE_MODULE("set_pipe_policy(%ld, %d, %d, %d)\n", pipe, maxQueuedPackets, 376 maxBufferDurationMS, sampleSize); 377 Object *object = gUSBStack->GetObject(pipe); 378 if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) 379 return B_DEV_INVALID_PIPE; 380 381 return ((IsochronousPipe *)object)->SetPipePolicy(maxQueuedPackets, 382 maxBufferDurationMS, sampleSize); 383 } 384 385 386 status_t 387 cancel_queued_transfers(usb_pipe pipe) 388 { 389 TRACE_MODULE("cancel_queued_transfers(%ld)\n", pipe); 390 Object *object = gUSBStack->GetObject(pipe); 391 if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) 392 return B_DEV_INVALID_PIPE; 393 394 return ((Pipe *)object)->CancelQueuedTransfers(false); 395 } 396 397 398 status_t 399 usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize) 400 { 401 TRACE_MODULE("usb_ioctl(%lu, %p, %ld)\n", opcode, buffer, bufferSize); 402 403 switch (opcode) { 404 case 'DNAM': { 405 Object *object = gUSBStack->GetObject(*(usb_id *)buffer); 406 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 407 return B_BAD_VALUE; 408 409 uint32 index = 0; 410 return ((Device *)object)->BuildDeviceName((char *)buffer, &index, 411 bufferSize, NULL); 412 } 413 } 414 415 return B_DEV_INVALID_IOCTL; 416 } 417 418 419 status_t 420 get_nth_roothub(uint32 index, usb_device *rootHub) 421 { 422 if (!rootHub) 423 return B_BAD_VALUE; 424 425 BusManager *busManager = gUSBStack->BusManagerAt(index); 426 if (!busManager) 427 return B_ENTRY_NOT_FOUND; 428 429 Hub *hub = busManager->GetRootHub(); 430 if (!hub) 431 return B_NO_INIT; 432 433 *rootHub = hub->USBID(); 434 return B_OK; 435 } 436 437 438 status_t 439 get_nth_child(usb_device _hub, uint8 index, usb_device *childDevice) 440 { 441 if (!childDevice) 442 return B_BAD_VALUE; 443 444 Object *object = gUSBStack->GetObject(_hub); 445 if (!object || (object->Type() & USB_OBJECT_HUB) == 0) 446 return B_DEV_INVALID_PIPE; 447 448 Hub *hub = (Hub *)object; 449 for (uint8 i = 0; i < 8; i++) { 450 if (hub->ChildAt(i) == NULL) 451 continue; 452 453 if (index-- > 0) 454 continue; 455 456 *childDevice = hub->ChildAt(i)->USBID(); 457 return B_OK; 458 } 459 460 return B_ENTRY_NOT_FOUND; 461 } 462 463 464 status_t 465 get_device_parent(usb_device _device, usb_device *parentHub, uint8 *portIndex) 466 { 467 if (!parentHub || !portIndex) 468 return B_BAD_VALUE; 469 470 Object *object = gUSBStack->GetObject(_device); 471 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 472 return B_DEV_INVALID_PIPE; 473 474 Object *parent = object->Parent(); 475 if (!parent || (parent->Type() & USB_OBJECT_HUB) == 0) 476 return B_ENTRY_NOT_FOUND; 477 478 Hub *hub = (Hub *)parent; 479 for (uint8 i = 0; i < 8; i++) { 480 if (hub->ChildAt(i) == object) { 481 *portIndex = i; 482 *parentHub = hub->USBID(); 483 return B_OK; 484 } 485 } 486 487 return B_ERROR; 488 } 489 490 491 status_t 492 reset_port(usb_device _hub, uint8 portIndex) 493 { 494 Object *object = gUSBStack->GetObject(_hub); 495 if (!object || (object->Type() & USB_OBJECT_HUB) == 0) 496 return B_DEV_INVALID_PIPE; 497 498 Hub *hub = (Hub *)object; 499 return hub->ResetPort(portIndex); 500 } 501 502 503 status_t 504 disable_port(usb_device _hub, uint8 portIndex) 505 { 506 Object *object = gUSBStack->GetObject(_hub); 507 if (!object || (object->Type() & USB_OBJECT_HUB) == 0) 508 return B_DEV_INVALID_PIPE; 509 510 Hub *hub = (Hub *)object; 511 return hub->DisablePort(portIndex); 512 } 513 514 515 /* 516 This module exports the USB API v3 517 */ 518 struct usb_module_info gModuleInfoV3 = { 519 // First the bus_manager_info: 520 { 521 { 522 "bus_managers/usb/v3", 523 B_KEEP_LOADED, // Keep loaded, even if no driver requires it 524 bus_std_ops 525 }, 526 NULL // the rescan function 527 }, 528 529 register_driver, // register_driver 530 install_notify, // install_notify 531 uninstall_notify, // uninstall_notify 532 get_device_descriptor, // get_device_descriptor 533 get_nth_configuration, // get_nth_configuration 534 get_configuration, // get_configuration 535 set_configuration, // set_configuration 536 set_alt_interface, // set_alt_interface 537 set_feature, // set_feature 538 clear_feature, // clear_feature 539 get_status, // get_status 540 get_descriptor, // get_descriptor 541 send_request, // send_request 542 queue_interrupt, // queue_interrupt 543 queue_bulk, // queue_bulk 544 queue_bulk_v, // queue_bulk_v 545 queue_isochronous, // queue_isochronous 546 queue_request, // queue_request 547 set_pipe_policy, // set_pipe_policy 548 cancel_queued_transfers, // cancel_queued_transfers 549 usb_ioctl, // usb_ioctl 550 get_nth_roothub, // get_nth_roothub 551 get_nth_child, // get_nth_child 552 get_device_parent, // get_device_parent 553 reset_port, // reset_port 554 disable_port // disable_port 555 //queue_bulk_v_physical // queue_bulk_v_physical 556 }; 557 558 559 // 560 // #pragma mark - 561 // 562 563 564 const usb_device_descriptor * 565 get_device_descriptor_v2(const void *device) 566 { 567 return get_device_descriptor((usb_id)device); 568 } 569 570 571 const usb_configuration_info * 572 get_nth_configuration_v2(const void *device, uint index) 573 { 574 return get_nth_configuration((usb_id)device, index); 575 } 576 577 578 const usb_configuration_info * 579 get_configuration_v2(const void *device) 580 { 581 return get_configuration((usb_id)device); 582 } 583 584 585 status_t 586 set_configuration_v2(const void *device, 587 const usb_configuration_info *configuration) 588 { 589 return set_configuration((usb_id)device, configuration); 590 } 591 592 593 status_t 594 set_alt_interface_v2(const void *device, const usb_interface_info *interface) 595 { 596 return set_alt_interface((usb_id)device, interface); 597 } 598 599 600 status_t 601 set_feature_v2(const void *object, uint16 selector) 602 { 603 return set_feature((usb_id)object, selector); 604 } 605 606 607 status_t 608 clear_feature_v2(const void *object, uint16 selector) 609 { 610 return clear_feature((usb_id)object, selector); 611 } 612 613 614 status_t 615 get_status_v2(const void *object, uint16 *status) 616 { 617 return get_status((usb_id)object, status); 618 } 619 620 621 status_t 622 get_descriptor_v2(const void *device, uint8 type, uint8 index, 623 uint16 languageID, void *data, size_t dataLength, size_t *actualLength) 624 { 625 return get_descriptor((usb_id)device, type, index, languageID, data, 626 dataLength, actualLength); 627 } 628 629 630 status_t 631 send_request_v2(const void *device, uint8 requestType, uint8 request, 632 uint16 value, uint16 index, uint16 length, void *data, 633 size_t /*dataLength*/, size_t *actualLength) 634 { 635 return send_request((usb_id)device, requestType, request, value, index, 636 length, data, actualLength); 637 } 638 639 640 status_t 641 queue_request_v2(const void *device, uint8 requestType, uint8 request, 642 uint16 value, uint16 index, uint16 length, void *data, 643 size_t /*dataLength*/, usb_callback_func callback, void *callbackCookie) 644 { 645 return queue_request((usb_id)device, requestType, request, value, index, 646 length, data, callback, callbackCookie); 647 } 648 649 650 status_t 651 queue_interrupt_v2(const void *pipe, void *data, size_t dataLength, 652 usb_callback_func callback, void *callbackCookie) 653 { 654 return queue_interrupt((usb_id)pipe, data, dataLength, callback, 655 callbackCookie); 656 } 657 658 659 status_t 660 queue_bulk_v2(const void *pipe, void *data, size_t dataLength, 661 usb_callback_func callback, void *callbackCookie) 662 { 663 return queue_bulk((usb_id)pipe, data, dataLength, callback, 664 callbackCookie); 665 } 666 667 668 status_t 669 queue_isochronous_v2(const void *pipe, void *data, size_t dataLength, 670 rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback, 671 void *callbackCookie) 672 { 673 // ToDo: convert rlea to usb_iso_packet_descriptor 674 // ToDo: use a flag to indicate that the callback shall produce a rlea 675 usb_iso_packet_descriptor *packetDesc = NULL; 676 return queue_isochronous((usb_id)pipe, data, dataLength, packetDesc, 0, 677 NULL, 0, callback, callbackCookie); 678 } 679 680 681 status_t 682 set_pipe_policy_v2(const void *pipe, uint8 maxQueuedPackets, 683 uint16 maxBufferDurationMS, uint16 sampleSize) 684 { 685 return set_pipe_policy((usb_id)pipe, maxQueuedPackets, maxBufferDurationMS, 686 sampleSize); 687 } 688 689 690 status_t 691 cancel_queued_transfers_v2(const void *pipe) 692 { 693 return cancel_queued_transfers((usb_id)pipe); 694 } 695 696 697 struct usb_module_info_v2 { 698 bus_manager_info binfo; 699 status_t (*register_driver)(const char *, const usb_support_descriptor *, size_t, const char *); 700 status_t (*install_notify)(const char *, const usb_notify_hooks *); 701 status_t (*uninstall_notify)(const char *); 702 const usb_device_descriptor *(*get_device_descriptor)(const void *); 703 const usb_configuration_info *(*get_nth_configuration)(const void *, uint); 704 const usb_configuration_info *(*get_configuration)(const void *); 705 status_t (*set_configuration)(const void *, const usb_configuration_info *); 706 status_t (*set_alt_interface)(const void *, const usb_interface_info *); 707 status_t (*set_feature)(const void *, uint16); 708 status_t (*clear_feature)(const void *, uint16); 709 status_t (*get_status)(const void *, uint16 *); 710 status_t (*get_descriptor)(const void *, uint8, uint8, uint16, void *, size_t, size_t *); 711 status_t (*send_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, size_t *); 712 status_t (*queue_interrupt)(const void *, void *, size_t, usb_callback_func, void *); 713 status_t (*queue_bulk)(const void *, void *, size_t, usb_callback_func, void *); 714 status_t (*queue_isochronous)(const void *, void *, size_t, rlea *, uint16, usb_callback_func, void *); 715 status_t (*queue_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, usb_callback_func, void *); 716 status_t (*set_pipe_policy)(const void *, uint8, uint16, uint16); 717 status_t (*cancel_queued_transfers)(const void *); 718 status_t (*usb_ioctl)(uint32 opcode, void *,size_t); 719 }; 720 721 722 /* 723 This module exports the USB API v2 724 */ 725 struct usb_module_info_v2 gModuleInfoV2 = { 726 // First the bus_manager_info: 727 { 728 { 729 "bus_managers/usb/v2", 730 B_KEEP_LOADED, // Keep loaded, even if no driver requires it 731 bus_std_ops 732 }, 733 NULL // the rescan function 734 }, 735 736 register_driver, // register_driver 737 install_notify, // install_notify 738 uninstall_notify, // uninstall_notify 739 get_device_descriptor_v2, // get_device_descriptor 740 get_nth_configuration_v2, // get_nth_configuration 741 get_configuration_v2, // get_configuration 742 set_configuration_v2, // set_configuration 743 set_alt_interface_v2, // set_alt_interface 744 set_feature_v2, // set_feature 745 clear_feature_v2, // clear_feature 746 get_status_v2, // get_status 747 get_descriptor_v2, // get_descriptor 748 send_request_v2, // send_request 749 queue_interrupt_v2, // queue_interrupt 750 queue_bulk_v2, // queue_bulk 751 queue_isochronous_v2, // queue_isochronous 752 queue_request_v2, // queue_request 753 set_pipe_policy_v2, // set_pipe_policy 754 cancel_queued_transfers_v2, // cancel_queued_transfers 755 usb_ioctl // usb_ioctl 756 }; 757 758 759 // 760 // #pragma mark - 761 // 762 763 764 module_info *modules[] = { 765 (module_info *)&gModuleInfoV2, 766 (module_info *)&gModuleInfoV3, 767 NULL 768 }; 769