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(%" B_PRId32 ")\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(%" B_PRId32 ", %" B_PRIu32 ")\n", 161 device, index); 162 Object *object = gUSBStack->GetObject(device); 163 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 164 return NULL; 165 166 return ((Device *)object)->ConfigurationAt((int32)index); 167 } 168 169 170 const usb_configuration_info * 171 get_configuration(usb_device device) 172 { 173 TRACE_MODULE("get_configuration(%" B_PRId32 ")\n", device); 174 Object *object = gUSBStack->GetObject(device); 175 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 176 return NULL; 177 178 return ((Device *)object)->Configuration(); 179 } 180 181 182 status_t 183 set_configuration(usb_device device, 184 const usb_configuration_info *configuration) 185 { 186 TRACE_MODULE("set_configuration(%" B_PRId32 ", %p)\n", device, 187 configuration); 188 Object *object = gUSBStack->GetObject(device); 189 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 190 return B_DEV_INVALID_PIPE; 191 192 return ((Device *)object)->SetConfiguration(configuration); 193 } 194 195 196 status_t 197 set_alt_interface(usb_device device, const usb_interface_info *interface) 198 { 199 TRACE_MODULE("set_alt_interface(%" B_PRId32 ", %p)\n", device, interface); 200 Object *object = gUSBStack->GetObject(device); 201 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 202 return B_DEV_INVALID_PIPE; 203 204 return ((Device *)object)->SetAltInterface(interface); 205 } 206 207 208 status_t 209 set_feature(usb_id handle, uint16 selector) 210 { 211 TRACE_MODULE("set_feature(%" B_PRId32 ", %d)\n", handle, selector); 212 Object *object = gUSBStack->GetObject(handle); 213 if (!object) 214 return B_DEV_INVALID_PIPE; 215 216 return object->SetFeature(selector); 217 } 218 219 220 status_t 221 clear_feature(usb_id handle, uint16 selector) 222 { 223 TRACE_MODULE("clear_feature(%" B_PRId32 ", %d)\n", handle, selector); 224 Object *object = gUSBStack->GetObject(handle); 225 if (!object) 226 return B_DEV_INVALID_PIPE; 227 228 return object->ClearFeature(selector); 229 } 230 231 232 status_t 233 get_status(usb_id handle, uint16 *status) 234 { 235 TRACE_MODULE("get_status(%" B_PRId32 ", %p)\n", handle, status); 236 if (!status) 237 return B_BAD_VALUE; 238 239 Object *object = gUSBStack->GetObject(handle); 240 if (!object) 241 return B_DEV_INVALID_PIPE; 242 243 return object->GetStatus(status); 244 } 245 246 247 status_t 248 get_descriptor(usb_device device, uint8 type, uint8 index, uint16 languageID, 249 void *data, size_t dataLength, size_t *actualLength) 250 { 251 TRACE_MODULE("get_descriptor(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, %p, " 252 "%" B_PRIuSIZE ", %p)\n", 253 device, type, index, languageID, data, dataLength, actualLength); 254 Object *object = gUSBStack->GetObject(device); 255 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 256 return B_DEV_INVALID_PIPE; 257 258 return ((Device *)object)->GetDescriptor(type, index, languageID, 259 data, dataLength, actualLength); 260 } 261 262 263 status_t 264 send_request(usb_device device, uint8 requestType, uint8 request, 265 uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength) 266 { 267 TRACE_MODULE("send_request(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, 0x%04x, " 268 "%d, %p, %p)\n", device, requestType, request, value, index, length, 269 data, actualLength); 270 Object *object = gUSBStack->GetObject(device); 271 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 272 return B_DEV_INVALID_PIPE; 273 274 return ((Device *)object)->DefaultPipe()->SendRequest(requestType, request, 275 value, index, length, data, length, actualLength); 276 } 277 278 279 status_t 280 queue_request(usb_device device, uint8 requestType, uint8 request, 281 uint16 value, uint16 index, uint16 length, void *data, 282 usb_callback_func callback, void *callbackCookie) 283 { 284 TRACE_MODULE("queue_request(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, 0x%04x," 285 " %u, %p, %p, %p)\n", device, requestType, request, value, index, 286 length, data, callback, callbackCookie); 287 Object *object = gUSBStack->GetObject(device); 288 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 289 return B_DEV_INVALID_PIPE; 290 291 return ((Device *)object)->DefaultPipe()->QueueRequest(requestType, 292 request, value, index, length, data, length, callback, callbackCookie); 293 } 294 295 296 status_t 297 queue_interrupt(usb_pipe pipe, void *data, size_t dataLength, 298 usb_callback_func callback, void *callbackCookie) 299 { 300 TRACE_MODULE("queue_interrupt(%" B_PRId32 ", %p, %ld, %p, %p)\n", 301 pipe, data, dataLength, callback, callbackCookie); 302 Object *object = gUSBStack->GetObject(pipe); 303 if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) 304 return B_DEV_INVALID_PIPE; 305 306 return ((InterruptPipe *)object)->QueueInterrupt(data, dataLength, callback, 307 callbackCookie); 308 } 309 310 311 status_t 312 queue_bulk(usb_pipe pipe, void *data, size_t dataLength, 313 usb_callback_func callback, void *callbackCookie) 314 { 315 TRACE_MODULE("queue_bulk(%" B_PRId32 ", %p, %" B_PRIuSIZE ", %p, %p)\n", 316 pipe, data, dataLength, callback, callbackCookie); 317 Object *object = gUSBStack->GetObject(pipe); 318 if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 319 return B_DEV_INVALID_PIPE; 320 321 return ((BulkPipe *)object)->QueueBulk(data, dataLength, callback, 322 callbackCookie); 323 } 324 325 326 status_t 327 queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount, 328 usb_callback_func callback, void *callbackCookie) 329 { 330 TRACE_MODULE("queue_bulk_v(%" B_PRId32 ", %p, %" B_PRIuSIZE " %p, %p)\n", 331 pipe, vector, vectorCount, callback, callbackCookie); 332 Object *object = gUSBStack->GetObject(pipe); 333 if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 334 return B_DEV_INVALID_PIPE; 335 336 return ((BulkPipe *)object)->QueueBulkV(vector, vectorCount, callback, 337 callbackCookie, false); 338 } 339 340 341 status_t 342 queue_bulk_v_physical(usb_pipe pipe, iovec *vector, size_t vectorCount, 343 usb_callback_func callback, void *callbackCookie) 344 { 345 TRACE_MODULE("queue_bulk_v_physical(%" B_PRId32 ", %p, %" B_PRIuSIZE 346 ", %p, %p)\n", pipe, vector, vectorCount, callback, callbackCookie); 347 Object *object = gUSBStack->GetObject(pipe); 348 if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 349 return B_DEV_INVALID_PIPE; 350 351 return ((BulkPipe *)object)->QueueBulkV(vector, vectorCount, callback, 352 callbackCookie, true); 353 } 354 355 356 status_t 357 queue_isochronous(usb_pipe pipe, void *data, size_t dataLength, 358 usb_iso_packet_descriptor *packetDesc, uint32 packetCount, 359 uint32 *startingFrameNumber, uint32 flags, usb_callback_func callback, 360 void *callbackCookie) 361 { 362 TRACE_MODULE("queue_isochronous(%" B_PRId32 ", %p, %" B_PRIuSIZE ", %p, " 363 "%" B_PRId32 ", %p, 0x%08" B_PRIx32 ", %p, %p)\n", 364 pipe, data, dataLength, packetDesc, packetCount, startingFrameNumber, 365 flags, callback, callbackCookie); 366 Object *object = gUSBStack->GetObject(pipe); 367 if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) 368 return B_DEV_INVALID_PIPE; 369 370 return ((IsochronousPipe *)object)->QueueIsochronous(data, dataLength, 371 packetDesc, packetCount, startingFrameNumber, flags, callback, 372 callbackCookie); 373 } 374 375 376 status_t 377 set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets, 378 uint16 maxBufferDurationMS, uint16 sampleSize) 379 { 380 TRACE_MODULE("set_pipe_policy(%" B_PRId32 ", %d, %d, %d)\n", pipe, 381 maxQueuedPackets, maxBufferDurationMS, sampleSize); 382 Object *object = gUSBStack->GetObject(pipe); 383 if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) 384 return B_DEV_INVALID_PIPE; 385 386 return ((IsochronousPipe *)object)->SetPipePolicy(maxQueuedPackets, 387 maxBufferDurationMS, sampleSize); 388 } 389 390 391 status_t 392 cancel_queued_transfers(usb_pipe pipe) 393 { 394 TRACE_MODULE("cancel_queued_transfers(%" B_PRId32 ")\n", pipe); 395 Object *object = gUSBStack->GetObject(pipe); 396 if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) 397 return B_DEV_INVALID_PIPE; 398 399 return ((Pipe *)object)->CancelQueuedTransfers(false); 400 } 401 402 403 status_t 404 usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize) 405 { 406 TRACE_MODULE("usb_ioctl(%" B_PRIu32 ", %p, %" B_PRIuSIZE ")\n", opcode, 407 buffer, bufferSize); 408 409 switch (opcode) { 410 case 'DNAM': { 411 Object *object = gUSBStack->GetObject(*(usb_id *)buffer); 412 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 413 return B_BAD_VALUE; 414 415 uint32 index = 0; 416 return ((Device *)object)->BuildDeviceName((char *)buffer, &index, 417 bufferSize, NULL); 418 } 419 } 420 421 return B_DEV_INVALID_IOCTL; 422 } 423 424 425 status_t 426 get_nth_roothub(uint32 index, usb_device *rootHub) 427 { 428 if (!rootHub) 429 return B_BAD_VALUE; 430 431 BusManager *busManager = gUSBStack->BusManagerAt(index); 432 if (!busManager) 433 return B_ENTRY_NOT_FOUND; 434 435 Hub *hub = busManager->GetRootHub(); 436 if (!hub) 437 return B_NO_INIT; 438 439 *rootHub = hub->USBID(); 440 return B_OK; 441 } 442 443 444 status_t 445 get_nth_child(usb_device _hub, uint8 index, usb_device *childDevice) 446 { 447 if (!childDevice) 448 return B_BAD_VALUE; 449 450 Object *object = gUSBStack->GetObject(_hub); 451 if (!object || (object->Type() & USB_OBJECT_HUB) == 0) 452 return B_DEV_INVALID_PIPE; 453 454 Hub *hub = (Hub *)object; 455 for (uint8 i = 0; i < 8; i++) { 456 if (hub->ChildAt(i) == NULL) 457 continue; 458 459 if (index-- > 0) 460 continue; 461 462 *childDevice = hub->ChildAt(i)->USBID(); 463 return B_OK; 464 } 465 466 return B_ENTRY_NOT_FOUND; 467 } 468 469 470 status_t 471 get_device_parent(usb_device _device, usb_device *parentHub, uint8 *portIndex) 472 { 473 if (!parentHub || !portIndex) 474 return B_BAD_VALUE; 475 476 Object *object = gUSBStack->GetObject(_device); 477 if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 478 return B_DEV_INVALID_PIPE; 479 480 Object *parent = object->Parent(); 481 if (!parent || (parent->Type() & USB_OBJECT_HUB) == 0) 482 return B_ENTRY_NOT_FOUND; 483 484 Hub *hub = (Hub *)parent; 485 for (uint8 i = 0; i < 8; i++) { 486 if (hub->ChildAt(i) == object) { 487 *portIndex = i; 488 *parentHub = hub->USBID(); 489 return B_OK; 490 } 491 } 492 493 return B_ERROR; 494 } 495 496 497 status_t 498 reset_port(usb_device _hub, uint8 portIndex) 499 { 500 Object *object = gUSBStack->GetObject(_hub); 501 if (!object || (object->Type() & USB_OBJECT_HUB) == 0) 502 return B_DEV_INVALID_PIPE; 503 504 Hub *hub = (Hub *)object; 505 return hub->ResetPort(portIndex); 506 } 507 508 509 status_t 510 disable_port(usb_device _hub, uint8 portIndex) 511 { 512 Object *object = gUSBStack->GetObject(_hub); 513 if (!object || (object->Type() & USB_OBJECT_HUB) == 0) 514 return B_DEV_INVALID_PIPE; 515 516 Hub *hub = (Hub *)object; 517 return hub->DisablePort(portIndex); 518 } 519 520 521 /* 522 This module exports the USB API v3 523 */ 524 struct usb_module_info gModuleInfoV3 = { 525 // First the bus_manager_info: 526 { 527 { 528 "bus_managers/usb/v3", 529 B_KEEP_LOADED, // Keep loaded, even if no driver requires it 530 bus_std_ops 531 }, 532 NULL // the rescan function 533 }, 534 535 register_driver, // register_driver 536 install_notify, // install_notify 537 uninstall_notify, // uninstall_notify 538 get_device_descriptor, // get_device_descriptor 539 get_nth_configuration, // get_nth_configuration 540 get_configuration, // get_configuration 541 set_configuration, // set_configuration 542 set_alt_interface, // set_alt_interface 543 set_feature, // set_feature 544 clear_feature, // clear_feature 545 get_status, // get_status 546 get_descriptor, // get_descriptor 547 send_request, // send_request 548 queue_interrupt, // queue_interrupt 549 queue_bulk, // queue_bulk 550 queue_bulk_v, // queue_bulk_v 551 queue_isochronous, // queue_isochronous 552 queue_request, // queue_request 553 set_pipe_policy, // set_pipe_policy 554 cancel_queued_transfers, // cancel_queued_transfers 555 usb_ioctl, // usb_ioctl 556 get_nth_roothub, // get_nth_roothub 557 get_nth_child, // get_nth_child 558 get_device_parent, // get_device_parent 559 reset_port, // reset_port 560 disable_port // disable_port 561 //queue_bulk_v_physical // queue_bulk_v_physical 562 }; 563 564 565 // 566 // #pragma mark - 567 // 568 569 570 const usb_device_descriptor * 571 get_device_descriptor_v2(const void *device) 572 { 573 return get_device_descriptor((usb_id)(ssize_t)device); 574 } 575 576 577 const usb_configuration_info * 578 get_nth_configuration_v2(const void *device, uint index) 579 { 580 return get_nth_configuration((usb_id)(ssize_t)device, index); 581 } 582 583 584 const usb_configuration_info * 585 get_configuration_v2(const void *device) 586 { 587 return get_configuration((usb_id)(ssize_t)device); 588 } 589 590 591 status_t 592 set_configuration_v2(const void *device, 593 const usb_configuration_info *configuration) 594 { 595 return set_configuration((usb_id)(ssize_t)device, configuration); 596 } 597 598 599 status_t 600 set_alt_interface_v2(const void *device, const usb_interface_info *interface) 601 { 602 return set_alt_interface((usb_id)(ssize_t)device, interface); 603 } 604 605 606 status_t 607 set_feature_v2(const void *object, uint16 selector) 608 { 609 return set_feature((usb_id)(ssize_t)object, selector); 610 } 611 612 613 status_t 614 clear_feature_v2(const void *object, uint16 selector) 615 { 616 return clear_feature((usb_id)(ssize_t)object, selector); 617 } 618 619 620 status_t 621 get_status_v2(const void *object, uint16 *status) 622 { 623 return get_status((usb_id)(ssize_t)object, status); 624 } 625 626 627 status_t 628 get_descriptor_v2(const void *device, uint8 type, uint8 index, 629 uint16 languageID, void *data, size_t dataLength, size_t *actualLength) 630 { 631 return get_descriptor((usb_id)(ssize_t)device, type, index, languageID, data, 632 dataLength, actualLength); 633 } 634 635 636 status_t 637 send_request_v2(const void *device, uint8 requestType, uint8 request, 638 uint16 value, uint16 index, uint16 length, void *data, 639 size_t /*dataLength*/, size_t *actualLength) 640 { 641 return send_request((usb_id)(ssize_t)device, requestType, request, value, index, 642 length, data, actualLength); 643 } 644 645 646 status_t 647 queue_request_v2(const void *device, uint8 requestType, uint8 request, 648 uint16 value, uint16 index, uint16 length, void *data, 649 size_t /*dataLength*/, usb_callback_func callback, void *callbackCookie) 650 { 651 return queue_request((usb_id)(ssize_t)device, requestType, request, value, index, 652 length, data, callback, callbackCookie); 653 } 654 655 656 status_t 657 queue_interrupt_v2(const void *pipe, void *data, size_t dataLength, 658 usb_callback_func callback, void *callbackCookie) 659 { 660 return queue_interrupt((usb_id)(ssize_t)pipe, data, dataLength, callback, 661 callbackCookie); 662 } 663 664 665 status_t 666 queue_bulk_v2(const void *pipe, void *data, size_t dataLength, 667 usb_callback_func callback, void *callbackCookie) 668 { 669 return queue_bulk((usb_id)(ssize_t)pipe, data, dataLength, callback, 670 callbackCookie); 671 } 672 673 674 status_t 675 queue_isochronous_v2(const void *pipe, void *data, size_t dataLength, 676 rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback, 677 void *callbackCookie) 678 { 679 // ToDo: convert rlea to usb_iso_packet_descriptor 680 // ToDo: use a flag to indicate that the callback shall produce a rlea 681 usb_iso_packet_descriptor *packetDesc = NULL; 682 return queue_isochronous((usb_id)(ssize_t)pipe, data, dataLength, packetDesc, 0, 683 NULL, 0, callback, callbackCookie); 684 } 685 686 687 status_t 688 set_pipe_policy_v2(const void *pipe, uint8 maxQueuedPackets, 689 uint16 maxBufferDurationMS, uint16 sampleSize) 690 { 691 return set_pipe_policy((usb_id)(ssize_t)pipe, maxQueuedPackets, maxBufferDurationMS, 692 sampleSize); 693 } 694 695 696 status_t 697 cancel_queued_transfers_v2(const void *pipe) 698 { 699 return cancel_queued_transfers((usb_id)(ssize_t)pipe); 700 } 701 702 703 struct usb_module_info_v2 { 704 bus_manager_info binfo; 705 status_t (*register_driver)(const char *, const usb_support_descriptor *, size_t, const char *); 706 status_t (*install_notify)(const char *, const usb_notify_hooks *); 707 status_t (*uninstall_notify)(const char *); 708 const usb_device_descriptor *(*get_device_descriptor)(const void *); 709 const usb_configuration_info *(*get_nth_configuration)(const void *, uint); 710 const usb_configuration_info *(*get_configuration)(const void *); 711 status_t (*set_configuration)(const void *, const usb_configuration_info *); 712 status_t (*set_alt_interface)(const void *, const usb_interface_info *); 713 status_t (*set_feature)(const void *, uint16); 714 status_t (*clear_feature)(const void *, uint16); 715 status_t (*get_status)(const void *, uint16 *); 716 status_t (*get_descriptor)(const void *, uint8, uint8, uint16, void *, size_t, size_t *); 717 status_t (*send_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, size_t *); 718 status_t (*queue_interrupt)(const void *, void *, size_t, usb_callback_func, void *); 719 status_t (*queue_bulk)(const void *, void *, size_t, usb_callback_func, void *); 720 status_t (*queue_isochronous)(const void *, void *, size_t, rlea *, uint16, usb_callback_func, void *); 721 status_t (*queue_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, usb_callback_func, void *); 722 status_t (*set_pipe_policy)(const void *, uint8, uint16, uint16); 723 status_t (*cancel_queued_transfers)(const void *); 724 status_t (*usb_ioctl)(uint32 opcode, void *,size_t); 725 }; 726 727 728 /* 729 This module exports the USB API v2 730 */ 731 struct usb_module_info_v2 gModuleInfoV2 = { 732 // First the bus_manager_info: 733 { 734 { 735 "bus_managers/usb/v2", 736 B_KEEP_LOADED, // Keep loaded, even if no driver requires it 737 bus_std_ops 738 }, 739 NULL // the rescan function 740 }, 741 742 register_driver, // register_driver 743 install_notify, // install_notify 744 uninstall_notify, // uninstall_notify 745 get_device_descriptor_v2, // get_device_descriptor 746 get_nth_configuration_v2, // get_nth_configuration 747 get_configuration_v2, // get_configuration 748 set_configuration_v2, // set_configuration 749 set_alt_interface_v2, // set_alt_interface 750 set_feature_v2, // set_feature 751 clear_feature_v2, // clear_feature 752 get_status_v2, // get_status 753 get_descriptor_v2, // get_descriptor 754 send_request_v2, // send_request 755 queue_interrupt_v2, // queue_interrupt 756 queue_bulk_v2, // queue_bulk 757 queue_isochronous_v2, // queue_isochronous 758 queue_request_v2, // queue_request 759 set_pipe_policy_v2, // set_pipe_policy 760 cancel_queued_transfers_v2, // cancel_queued_transfers 761 usb_ioctl // usb_ioctl 762 }; 763 764 765 // 766 // #pragma mark - 767 // 768 769 770 module_info *modules[] = { 771 (module_info *)&gModuleInfoV2, 772 (module_info *)&gModuleInfoV3, 773 NULL 774 }; 775