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 device_manager_info *gDeviceManager; 19 20 21 /*! The function is an evil hack to allow <tt> <kdebug>usb_keyboard </tt> to 22 execute transfers. 23 When invoked the first time, a new transfer is started, each time the 24 function is called afterwards, it is checked whether the transfer is already 25 completed. If called with argv[1] == "cancel" the function cancels a 26 possibly pending transfer. 27 */ 28 static status_t 29 debug_run_transfer(Pipe *pipe, uint8 *data, size_t dataLength, 30 usb_request_data *requestData, bool cancel) 31 { 32 static uint8 transferBuffer[sizeof(Transfer)] 33 __attribute__((aligned(16))); 34 static Transfer *transfer = NULL; 35 36 BusManager *bus = pipe->GetBusManager(); 37 38 if (cancel) { 39 if (transfer != NULL) { 40 bus->CancelDebugTransfer(transfer); 41 transfer = NULL; 42 } 43 44 return B_OK; 45 } 46 47 if (transfer != NULL) { 48 status_t error = bus->CheckDebugTransfer(transfer); 49 if (error != B_DEV_PENDING) 50 transfer = NULL; 51 52 return error; 53 } 54 55 transfer = new(transferBuffer) Transfer(pipe); 56 transfer->SetData(data, dataLength); 57 transfer->SetRequestData(requestData); 58 59 status_t error = bus->StartDebugTransfer(transfer); 60 if (error != B_OK) { 61 transfer = NULL; 62 return error; 63 } 64 65 return B_DEV_PENDING; 66 } 67 68 69 static int 70 debug_get_pipe_for_id(int argc, char **argv) 71 { 72 if (gUSBStack == NULL) 73 return 1; 74 75 if (!is_debug_variable_defined("_usbPipeID")) 76 return 2; 77 78 uint64 id = get_debug_variable("_usbPipeID", 0); 79 Object *object = gUSBStack->GetObjectNoLock((usb_id)id); 80 if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) 81 return 3; 82 83 set_debug_variable("_usbPipe", (uint64)object); 84 return 0; 85 } 86 87 88 static int 89 debug_process_transfer(int argc, char **argv) 90 { 91 Pipe *pipe = (Pipe *)get_debug_variable("_usbPipe", 0); 92 if (pipe == NULL) 93 return B_BAD_VALUE; 94 95 uint8 *data = (uint8 *)get_debug_variable("_usbTransferData", 0); 96 size_t length = (size_t)get_debug_variable("_usbTransferLength", 0); 97 usb_request_data *requestData 98 = (usb_request_data *)get_debug_variable("_usbRequestData", 0); 99 100 return debug_run_transfer(pipe, data, length, requestData, 101 argc > 1 && strcmp(argv[1], "cancel") == 0); 102 } 103 104 105 static int 106 debug_clear_stall(int argc, char *argv[]) 107 { 108 Pipe *pipe = (Pipe *)get_debug_variable("_usbPipe", 0); 109 if (pipe == NULL) 110 return B_BAD_VALUE; 111 112 static usb_request_data requestData; 113 114 requestData.RequestType = USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_OUT; 115 requestData.Request = USB_REQUEST_CLEAR_FEATURE; 116 requestData.Value = USB_FEATURE_ENDPOINT_HALT; 117 requestData.Index = pipe->EndpointAddress() 118 | (pipe->Direction() == Pipe::In ? USB_ENDPOINT_ADDR_DIR_IN 119 : USB_ENDPOINT_ADDR_DIR_OUT); 120 requestData.Length = 0; 121 122 Pipe *parentPipe = ((Device *)pipe->Parent())->DefaultPipe(); 123 for (int tries = 0; tries < 100; tries++) { 124 status_t result 125 = debug_run_transfer(parentPipe, NULL, 0, &requestData, false); 126 127 if (result == B_DEV_PENDING) 128 continue; 129 130 if (result == B_OK) { 131 // clearing a stalled condition resets the data toggle 132 pipe->SetDataToggle(false); 133 return B_OK; 134 } 135 136 return result; 137 } 138 139 return B_TIMED_OUT; 140 } 141 142 143 static int32 144 bus_std_ops(int32 op, ...) 145 { 146 switch (op) { 147 case B_MODULE_INIT: { 148 TRACE_MODULE("init\n"); 149 if (gUSBStack) 150 return B_OK; 151 152 #ifdef TRACE_USB 153 set_dprintf_enabled(true); 154 #endif 155 Stack *stack = new(std::nothrow) Stack(); 156 TRACE_MODULE("usb_module: stack created %p\n", stack); 157 if (!stack) 158 return B_NO_MEMORY; 159 160 if (stack->InitCheck() != B_OK) { 161 delete stack; 162 return ENODEV; 163 } 164 165 gUSBStack = stack; 166 167 add_debugger_command("get_usb_pipe_for_id", 168 &debug_get_pipe_for_id, 169 "Sets _usbPipe by resolving _usbPipeID"); 170 add_debugger_command("usb_process_transfer", 171 &debug_process_transfer, 172 "Transfers _usbTransferData with _usbTransferLength" 173 " (and/or _usbRequestData) to pipe _usbPipe"); 174 add_debugger_command("usb_clear_stall", 175 &debug_clear_stall, 176 "Tries to issue a clear feature request for the endpoint halt" 177 " feature on pipe _usbPipe"); 178 break; 179 } 180 181 case B_MODULE_UNINIT: 182 TRACE_MODULE("uninit\n"); 183 delete gUSBStack; 184 gUSBStack = NULL; 185 186 remove_debugger_command("get_usb_pipe_for_id", 187 &debug_get_pipe_for_id); 188 break; 189 190 default: 191 return EINVAL; 192 } 193 194 return B_OK; 195 } 196 197 198 // #pragma mark - public methods 199 200 201 status_t 202 register_driver(const char *driverName, 203 const usb_support_descriptor *descriptors, 204 size_t count, const char *optionalRepublishDriverName) 205 { 206 return gUSBStack->RegisterDriver(driverName, descriptors, count, 207 optionalRepublishDriverName); 208 } 209 210 211 status_t 212 install_notify(const char *driverName, const usb_notify_hooks *hooks) 213 { 214 return gUSBStack->InstallNotify(driverName, hooks); 215 } 216 217 218 status_t 219 uninstall_notify(const char *driverName) 220 { 221 return gUSBStack->UninstallNotify(driverName); 222 } 223 224 225 const usb_device_descriptor * 226 get_device_descriptor(usb_device dev) 227 { 228 TRACE_MODULE("get_device_descriptor(%" B_PRId32 ")\n", dev); 229 BReference<Object> object(gUSBStack->GetObject(dev), true); 230 if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0) 231 return NULL; 232 Device *device = (Device *)object.Get(); 233 234 return device->DeviceDescriptor(); 235 } 236 237 238 const usb_configuration_info * 239 get_nth_configuration(usb_device dev, uint32 index) 240 { 241 TRACE_MODULE("get_nth_configuration(%" B_PRId32 ", %" B_PRIu32 ")\n", 242 dev, index); 243 BReference<Object> object(gUSBStack->GetObject(dev), true); 244 if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0) 245 return NULL; 246 Device *device = (Device *)object.Get(); 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 BReference<Object> object(gUSBStack->GetObject(dev), true); 257 if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0) 258 return NULL; 259 Device *device = (Device *)object.Get(); 260 261 return device->Configuration(); 262 } 263 264 265 status_t 266 set_configuration(usb_device dev, 267 const usb_configuration_info *configuration) 268 { 269 TRACE_MODULE("set_configuration(%" B_PRId32 ", %p)\n", dev, 270 configuration); 271 BReference<Object> object(gUSBStack->GetObject(dev), true); 272 if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0) 273 return B_DEV_INVALID_PIPE; 274 Device *device = (Device *)object.Get(); 275 276 return device->SetConfiguration(configuration); 277 } 278 279 280 status_t 281 set_alt_interface(usb_device dev, const usb_interface_info *interface) 282 { 283 TRACE_MODULE("set_alt_interface(%" B_PRId32 ", %p)\n", dev, interface); 284 BReference<Object> object(gUSBStack->GetObject(dev), true); 285 if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0) 286 return B_DEV_INVALID_PIPE; 287 Device *device = (Device *)object.Get(); 288 289 return device->SetAltInterface(interface); 290 } 291 292 293 status_t 294 set_feature(usb_id handle, uint16 selector) 295 { 296 TRACE_MODULE("set_feature(%" B_PRId32 ", %d)\n", handle, selector); 297 BReference<Object> object(gUSBStack->GetObject(handle), true); 298 if (!object.IsSet()) 299 return B_DEV_INVALID_PIPE; 300 301 return object->SetFeature(selector); 302 } 303 304 305 status_t 306 clear_feature(usb_id handle, uint16 selector) 307 { 308 TRACE_MODULE("clear_feature(%" B_PRId32 ", %d)\n", handle, selector); 309 BReference<Object> object(gUSBStack->GetObject(handle), true); 310 if (!object.IsSet()) 311 return B_DEV_INVALID_PIPE; 312 313 return object->ClearFeature(selector); 314 } 315 316 317 status_t 318 get_status(usb_id handle, uint16 *status) 319 { 320 TRACE_MODULE("get_status(%" B_PRId32 ", %p)\n", handle, status); 321 if (!status) 322 return B_BAD_VALUE; 323 324 BReference<Object> object(gUSBStack->GetObject(handle), true); 325 if (!object.IsSet()) 326 return B_DEV_INVALID_PIPE; 327 328 return object->GetStatus(status); 329 } 330 331 332 status_t 333 get_descriptor(usb_device dev, uint8 type, uint8 index, uint16 languageID, 334 void *data, size_t dataLength, size_t *actualLength) 335 { 336 TRACE_MODULE("get_descriptor(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, %p, " 337 "%" B_PRIuSIZE ", %p)\n", 338 dev, type, index, languageID, data, dataLength, actualLength); 339 BReference<Object> object(gUSBStack->GetObject(dev), true); 340 if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0) 341 return B_DEV_INVALID_PIPE; 342 Device *device = (Device *)object.Get(); 343 344 return device->GetDescriptor(type, index, languageID, 345 data, dataLength, actualLength); 346 } 347 348 349 status_t 350 send_request(usb_device dev, uint8 requestType, uint8 request, 351 uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength) 352 { 353 TRACE_MODULE("send_request(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, 0x%04x, " 354 "%d, %p, %p)\n", dev, requestType, request, value, index, length, 355 data, actualLength); 356 BReference<Object> object(gUSBStack->GetObject(dev), true); 357 if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0) 358 return B_DEV_INVALID_PIPE; 359 Device *device = (Device *)object.Get(); 360 361 return device->DefaultPipe()->SendRequest(requestType, request, 362 value, index, length, data, length, actualLength); 363 } 364 365 366 status_t 367 queue_request(usb_device dev, uint8 requestType, uint8 request, 368 uint16 value, uint16 index, uint16 length, void *data, 369 usb_callback_func callback, void *callbackCookie) 370 { 371 TRACE_MODULE("queue_request(%" B_PRId32 ", 0x%02x, 0x%02x, 0x%04x, 0x%04x," 372 " %u, %p, %p, %p)\n", dev, requestType, request, value, index, 373 length, data, callback, callbackCookie); 374 BReference<Object> object(gUSBStack->GetObject(dev), true); 375 if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0) 376 return B_DEV_INVALID_PIPE; 377 Device *device = (Device *)object.Get(); 378 379 return device->DefaultPipe()->QueueRequest(requestType, 380 request, value, index, length, data, length, callback, callbackCookie); 381 } 382 383 384 status_t 385 queue_interrupt(usb_pipe pipe, void *data, size_t dataLength, 386 usb_callback_func callback, void *callbackCookie) 387 { 388 TRACE_MODULE("queue_interrupt(%" B_PRId32 ", %p, %ld, %p, %p)\n", 389 pipe, data, dataLength, callback, callbackCookie); 390 BReference<Object> object(gUSBStack->GetObject(pipe), true); 391 if (!object.IsSet() || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) 392 return B_DEV_INVALID_PIPE; 393 394 return ((InterruptPipe *)object.Get())->QueueInterrupt(data, dataLength, 395 callback, callbackCookie); 396 } 397 398 399 status_t 400 queue_bulk(usb_pipe pipe, void *data, size_t dataLength, 401 usb_callback_func callback, void *callbackCookie) 402 { 403 TRACE_MODULE("queue_bulk(%" B_PRId32 ", %p, %" B_PRIuSIZE ", %p, %p)\n", 404 pipe, data, dataLength, callback, callbackCookie); 405 BReference<Object> object(gUSBStack->GetObject(pipe), true); 406 if (!object.IsSet() || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 407 return B_DEV_INVALID_PIPE; 408 409 return ((BulkPipe *)object.Get())->QueueBulk(data, dataLength, callback, 410 callbackCookie); 411 } 412 413 414 status_t 415 queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount, 416 usb_callback_func callback, void *callbackCookie) 417 { 418 TRACE_MODULE("queue_bulk_v(%" B_PRId32 ", %p, %" B_PRIuSIZE " %p, %p)\n", 419 pipe, vector, vectorCount, callback, callbackCookie); 420 BReference<Object> object(gUSBStack->GetObject(pipe), true); 421 if (!object.IsSet() || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 422 return B_DEV_INVALID_PIPE; 423 424 return ((BulkPipe *)object.Get())->QueueBulkV(vector, vectorCount, 425 callback, callbackCookie); 426 } 427 428 429 status_t 430 queue_bulk_v_physical(usb_pipe pipe, physical_entry *vector, size_t vectorCount, 431 usb_callback_func callback, void *callbackCookie) 432 { 433 TRACE_MODULE("queue_bulk_v_physical(%" B_PRId32 ", %p, %" B_PRIuSIZE 434 ", %p, %p)\n", pipe, vector, vectorCount, callback, callbackCookie); 435 BReference<Object> object(gUSBStack->GetObject(pipe), true); 436 if (!object.IsSet() || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 437 return B_DEV_INVALID_PIPE; 438 439 return ((BulkPipe *)object.Get())->QueueBulkV(vector, vectorCount, 440 callback, callbackCookie); 441 } 442 443 444 status_t 445 queue_isochronous(usb_pipe pipe, void *data, size_t dataLength, 446 usb_iso_packet_descriptor *packetDesc, uint32 packetCount, 447 uint32 *startingFrameNumber, uint32 flags, usb_callback_func callback, 448 void *callbackCookie) 449 { 450 TRACE_MODULE("queue_isochronous(%" B_PRId32 ", %p, %" B_PRIuSIZE ", %p, " 451 "%" B_PRId32 ", %p, 0x%08" B_PRIx32 ", %p, %p)\n", 452 pipe, data, dataLength, packetDesc, packetCount, startingFrameNumber, 453 flags, callback, callbackCookie); 454 BReference<Object> object(gUSBStack->GetObject(pipe), true); 455 if (!object.IsSet() || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) 456 return B_DEV_INVALID_PIPE; 457 458 return ((IsochronousPipe *)object.Get())->QueueIsochronous(data, dataLength, 459 packetDesc, packetCount, startingFrameNumber, flags, callback, 460 callbackCookie); 461 } 462 463 464 status_t 465 set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets, 466 uint16 maxBufferDurationMS, uint16 sampleSize) 467 { 468 TRACE_MODULE("set_pipe_policy(%" B_PRId32 ", %d, %d, %d)\n", pipe, 469 maxQueuedPackets, maxBufferDurationMS, sampleSize); 470 BReference<Object> object(gUSBStack->GetObject(pipe), true); 471 if (!object.IsSet() || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) 472 return B_DEV_INVALID_PIPE; 473 474 return ((IsochronousPipe *)object.IsSet())->SetPipePolicy(maxQueuedPackets, 475 maxBufferDurationMS, sampleSize); 476 } 477 478 479 status_t 480 cancel_queued_transfers(usb_pipe pipe) 481 { 482 TRACE_MODULE("cancel_queued_transfers(%" B_PRId32 ")\n", pipe); 483 BReference<Object> object(gUSBStack->GetObject(pipe), true); 484 if (!object.IsSet() || (object->Type() & USB_OBJECT_PIPE) == 0) 485 return B_DEV_INVALID_PIPE; 486 487 return ((Pipe *)object.Get())->CancelQueuedTransfers(false); 488 } 489 490 491 status_t 492 cancel_queued_requests(usb_device dev) 493 { 494 TRACE_MODULE("cancel_queued_requests(%" B_PRId32 ")\n", dev); 495 BReference<Object> object(gUSBStack->GetObject(dev), true); 496 if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0) 497 return B_DEV_INVALID_PIPE; 498 Device *device = (Device *)object.Get(); 499 500 return device->DefaultPipe()->CancelQueuedTransfers(false); 501 } 502 503 504 status_t 505 usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize) 506 { 507 TRACE_MODULE("usb_ioctl(%" B_PRIu32 ", %p, %" B_PRIuSIZE ")\n", opcode, 508 buffer, bufferSize); 509 510 switch (opcode) { 511 case 'DNAM': { 512 BReference<Object> object(gUSBStack->GetObject(*(usb_id *)buffer), true); 513 if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0) 514 return B_BAD_VALUE; 515 Device *device = (Device *)object.Get(); 516 517 uint32 index = 0; 518 return device->BuildDeviceName((char *)buffer, &index, 519 bufferSize, NULL); 520 } 521 } 522 523 return B_DEV_INVALID_IOCTL; 524 } 525 526 527 status_t 528 get_nth_roothub(uint32 index, usb_device *rootHub) 529 { 530 if (!rootHub) 531 return B_BAD_VALUE; 532 533 BusManager *busManager = gUSBStack->BusManagerAt(index); 534 if (!busManager) 535 return B_ENTRY_NOT_FOUND; 536 537 Hub *hub = busManager->GetRootHub(); 538 if (!hub) 539 return B_NO_INIT; 540 541 *rootHub = hub->USBID(); 542 return B_OK; 543 } 544 545 546 status_t 547 get_nth_child(usb_device _hub, uint8 index, usb_device *childDevice) 548 { 549 if (!childDevice) 550 return B_BAD_VALUE; 551 552 BReference<Object> object(gUSBStack->GetObject(_hub), true); 553 if (!object.IsSet() || (object->Type() & USB_OBJECT_HUB) == 0) 554 return B_DEV_INVALID_PIPE; 555 556 Hub *hub = (Hub *)object.Get(); 557 for (uint8 i = 0; i < 8; i++) { 558 if (hub->ChildAt(i) == NULL) 559 continue; 560 561 if (index-- > 0) 562 continue; 563 564 *childDevice = hub->ChildAt(i)->USBID(); 565 return B_OK; 566 } 567 568 return B_ENTRY_NOT_FOUND; 569 } 570 571 572 status_t 573 get_device_parent(usb_device _device, usb_device *parentHub, uint8 *portIndex) 574 { 575 if (!parentHub || !portIndex) 576 return B_BAD_VALUE; 577 578 BReference<Object> object(gUSBStack->GetObject(_device), true); 579 if (!object.IsSet() || (object->Type() & USB_OBJECT_DEVICE) == 0) 580 return B_DEV_INVALID_PIPE; 581 582 Object *parent = object->Parent(); 583 if (!parent || (parent->Type() & USB_OBJECT_HUB) == 0) 584 return B_ENTRY_NOT_FOUND; 585 586 Hub *hub = (Hub *)parent; 587 for (uint8 i = 0; i < 8; i++) { 588 if (hub->ChildAt(i) == object.Get()) { 589 *portIndex = i; 590 *parentHub = hub->USBID(); 591 return B_OK; 592 } 593 } 594 595 return B_ERROR; 596 } 597 598 599 status_t 600 reset_port(usb_device _hub, uint8 portIndex) 601 { 602 BReference<Object> object(gUSBStack->GetObject(_hub), true); 603 if (!object.IsSet() || (object->Type() & USB_OBJECT_HUB) == 0) 604 return B_DEV_INVALID_PIPE; 605 606 Hub *hub = (Hub *)object.Get(); 607 return hub->ResetPort(portIndex); 608 } 609 610 611 status_t 612 disable_port(usb_device _hub, uint8 portIndex) 613 { 614 BReference<Object> object(gUSBStack->GetObject(_hub), true); 615 if (!object.IsSet() || (object->Type() & USB_OBJECT_HUB) == 0) 616 return B_DEV_INVALID_PIPE; 617 618 Hub *hub = (Hub *)object.Get(); 619 return hub->DisablePort(portIndex); 620 } 621 622 623 /* 624 This module exports the USB API v3 625 */ 626 struct usb_module_info gModuleInfoV3 = { 627 // First the bus_manager_info: 628 { 629 { 630 "bus_managers/usb/v3.1", 631 B_KEEP_LOADED, // Keep loaded, even if no driver requires it 632 bus_std_ops 633 }, 634 NULL // the rescan function 635 }, 636 637 register_driver, // register_driver 638 install_notify, // install_notify 639 uninstall_notify, // uninstall_notify 640 get_device_descriptor, // get_device_descriptor 641 get_nth_configuration, // get_nth_configuration 642 get_configuration, // get_configuration 643 set_configuration, // set_configuration 644 set_alt_interface, // set_alt_interface 645 set_feature, // set_feature 646 clear_feature, // clear_feature 647 get_status, // get_status 648 get_descriptor, // get_descriptor 649 send_request, // send_request 650 queue_interrupt, // queue_interrupt 651 queue_bulk, // queue_bulk 652 queue_bulk_v, // queue_bulk_v 653 queue_bulk_v_physical, // queue_bulk_v_physical 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 cancel_queued_requests, // cancel_queued_requests 659 usb_ioctl, // usb_ioctl 660 get_nth_roothub, // get_nth_roothub 661 get_nth_child, // get_nth_child 662 get_device_parent, // get_device_parent 663 reset_port, // reset_port 664 disable_port, // disable_port 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 status_t 874 usb_added_device(device_node *parent) 875 { 876 return B_OK; 877 } 878 879 880 status_t 881 usb_get_stack(void** stack) 882 { 883 *stack = gUSBStack; 884 return B_OK; 885 } 886 887 888 usb_for_controller_interface gForControllerModule = { 889 { 890 { 891 USB_FOR_CONTROLLER_MODULE_NAME, 892 B_KEEP_LOADED, 893 &bus_std_ops 894 }, 895 896 NULL, // supported devices 897 usb_added_device, 898 NULL, 899 NULL, 900 NULL 901 }, 902 903 usb_get_stack, 904 }; 905 906 907 static status_t 908 device_std_ops(int32 op, ...) 909 { 910 switch (op) { 911 case B_MODULE_INIT: 912 { 913 // Link to USB bus. 914 // USB device driver must have USB bus loaded, but it calls its 915 // functions directly instead via official interface, so this 916 // pointer is never read. 917 module_info *dummy; 918 return get_module(B_USB_MODULE_NAME, &dummy); 919 } 920 case B_MODULE_UNINIT: 921 return put_module(B_USB_MODULE_NAME); 922 923 default: 924 return B_ERROR; 925 } 926 } 927 928 929 usb_device_interface gUSBDeviceModule = { 930 { 931 { 932 USB_DEVICE_MODULE_NAME, 933 0, 934 device_std_ops 935 }, 936 937 NULL, // supported devices 938 NULL, // register node 939 NULL, //usb_init_device, 940 NULL, // (void (*)(void *)) usb_uninit_device, 941 NULL, // register child devices 942 NULL, // rescan 943 NULL// (void (*)(void *)) usb_device_removed 944 }, 945 }; 946 947 948 module_dependency module_dependencies[] = { 949 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager }, 950 {} 951 }; 952 953 954 module_info *modules[] = { 955 (module_info *)&gModuleInfoV2, 956 (module_info *)&gModuleInfoV3, 957 (module_info *)&gForControllerModule, 958 (module_info *)&gUSBDeviceModule, 959 NULL 960 }; 961