196da8285SMichael Lotz /* 296da8285SMichael Lotz * Copyright 2003-2006, Haiku Inc. All rights reserved. 396da8285SMichael Lotz * Distributed under the terms of the MIT License. 496da8285SMichael Lotz * 596da8285SMichael Lotz * Authors: 65b0ec61fSMichael Lotz * Michael Lotz <mmlr@mlotz.ch> 796da8285SMichael Lotz * Niels S. Reedijk 896da8285SMichael Lotz */ 91501c2bfSNiels Sascha Reedijk 101501c2bfSNiels Sascha Reedijk #include <util/kernel_cpp.h> 111501c2bfSNiels Sascha Reedijk #include "usb_p.h" 121bad4a4eSMichael Lotz #include <USB_rle.h> 131501c2bfSNiels Sascha Reedijk 1496da8285SMichael Lotz 15b8c6a851SMichael Lotz Stack *gUSBStack = NULL; 16b8c6a851SMichael Lotz 17b8c6a851SMichael Lotz 181501c2bfSNiels Sascha Reedijk static int32 191501c2bfSNiels Sascha Reedijk bus_std_ops(int32 op, ...) 201501c2bfSNiels Sascha Reedijk { 211501c2bfSNiels Sascha Reedijk switch (op) { 2296da8285SMichael Lotz case B_MODULE_INIT: { 235b0ec61fSMichael Lotz if (gUSBStack) 245b0ec61fSMichael Lotz return B_OK; 255b0ec61fSMichael Lotz 2696da8285SMichael Lotz #ifdef TRACE_USB 271a2e81b5SNiels Sascha Reedijk set_dprintf_enabled(true); 281a2e81b5SNiels Sascha Reedijk load_driver_symbols("usb"); 29b8c6a851SMichael Lotz TRACE(("usb_module: init\n")); 3002ce23a1SMichael Lotz #endif 3196da8285SMichael Lotz 32b8c6a851SMichael Lotz Stack *stack = new(std::nothrow) Stack(); 33b8c6a851SMichael Lotz if (!stack) 34b8c6a851SMichael Lotz return B_NO_MEMORY; 35b8c6a851SMichael Lotz 3696da8285SMichael Lotz if (stack->InitCheck() != B_OK) { 371a2e81b5SNiels Sascha Reedijk delete stack; 381501c2bfSNiels Sascha Reedijk return ENODEV; 391501c2bfSNiels Sascha Reedijk } 4096da8285SMichael Lotz 41b8c6a851SMichael Lotz gUSBStack = stack; 421501c2bfSNiels Sascha Reedijk break; 4396da8285SMichael Lotz } 4496da8285SMichael Lotz 451501c2bfSNiels Sascha Reedijk case B_MODULE_UNINIT: 46b8c6a851SMichael Lotz TRACE(("usb_module: bus module: uninit\n")); 47b8c6a851SMichael Lotz delete gUSBStack; 48b8c6a851SMichael Lotz gUSBStack = NULL; 491501c2bfSNiels Sascha Reedijk break; 5096da8285SMichael Lotz 511501c2bfSNiels Sascha Reedijk default: 521501c2bfSNiels Sascha Reedijk return EINVAL; 531501c2bfSNiels Sascha Reedijk } 5496da8285SMichael Lotz 551501c2bfSNiels Sascha Reedijk return B_OK; 561501c2bfSNiels Sascha Reedijk } 571501c2bfSNiels Sascha Reedijk 581501c2bfSNiels Sascha Reedijk 59b8c6a851SMichael Lotz status_t 60b8c6a851SMichael Lotz register_driver(const char *driverName, 61b8c6a851SMichael Lotz const usb_support_descriptor *descriptors, 62b8c6a851SMichael Lotz size_t count, const char *optionalRepublishDriverName) 63b8c6a851SMichael Lotz { 64b8c6a851SMichael Lotz return gUSBStack->RegisterDriver(driverName, descriptors, count, 65b8c6a851SMichael Lotz optionalRepublishDriverName); 66b8c6a851SMichael Lotz } 67b8c6a851SMichael Lotz 68b8c6a851SMichael Lotz 69b8c6a851SMichael Lotz status_t 70b8c6a851SMichael Lotz install_notify(const char *driverName, const usb_notify_hooks *hooks) 71b8c6a851SMichael Lotz { 72b8c6a851SMichael Lotz return gUSBStack->InstallNotify(driverName, hooks); 73b8c6a851SMichael Lotz } 74b8c6a851SMichael Lotz 75b8c6a851SMichael Lotz 76b8c6a851SMichael Lotz status_t 77b8c6a851SMichael Lotz uninstall_notify(const char *driverName) 78b8c6a851SMichael Lotz { 79b8c6a851SMichael Lotz return gUSBStack->UninstallNotify(driverName); 80b8c6a851SMichael Lotz } 81b8c6a851SMichael Lotz 82b8c6a851SMichael Lotz 83b8c6a851SMichael Lotz const usb_device_descriptor * 845b0ec61fSMichael Lotz get_device_descriptor(usb_device device) 85b8c6a851SMichael Lotz { 86f1020a6cSMichael Lotz TRACE(("usb_module: get_device_descriptor(0x%08x)\n", device)); 875b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 885b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 89b8c6a851SMichael Lotz return NULL; 90b8c6a851SMichael Lotz 915b0ec61fSMichael Lotz return ((Device *)object)->DeviceDescriptor(); 92b8c6a851SMichael Lotz } 93b8c6a851SMichael Lotz 94b8c6a851SMichael Lotz 95b8c6a851SMichael Lotz const usb_configuration_info * 965b0ec61fSMichael Lotz get_nth_configuration(usb_device device, uint index) 97b8c6a851SMichael Lotz { 98f1020a6cSMichael Lotz TRACE(("usb_module: get_nth_configuration(0x%08x, %d)\n", device, index)); 995b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 1005b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 101b8c6a851SMichael Lotz return NULL; 102b8c6a851SMichael Lotz 1035b0ec61fSMichael Lotz return ((Device *)object)->ConfigurationAt((int32)index); 104b8c6a851SMichael Lotz } 105b8c6a851SMichael Lotz 106b8c6a851SMichael Lotz 107b8c6a851SMichael Lotz const usb_configuration_info * 1085b0ec61fSMichael Lotz get_configuration(usb_device device) 109b8c6a851SMichael Lotz { 110f1020a6cSMichael Lotz TRACE(("usb_module: get_configuration(0x%08x)\n", device)); 1115b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 1125b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 113b8c6a851SMichael Lotz return NULL; 114b8c6a851SMichael Lotz 1155b0ec61fSMichael Lotz return ((Device *)object)->Configuration(); 116b8c6a851SMichael Lotz } 117b8c6a851SMichael Lotz 118b8c6a851SMichael Lotz 119b8c6a851SMichael Lotz status_t 1205b0ec61fSMichael Lotz set_configuration(usb_device device, 121b8c6a851SMichael Lotz const usb_configuration_info *configuration) 122b8c6a851SMichael Lotz { 123f1020a6cSMichael Lotz TRACE(("usb_module: set_configuration(0x%08x, 0x%08x)\n", device, configuration)); 1245b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 1255b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 12617f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 127b8c6a851SMichael Lotz 1285b0ec61fSMichael Lotz return ((Device *)object)->SetConfiguration(configuration); 129b8c6a851SMichael Lotz } 130b8c6a851SMichael Lotz 131b8c6a851SMichael Lotz 132b8c6a851SMichael Lotz status_t 1335b0ec61fSMichael Lotz set_alt_interface(usb_device device, const usb_interface_info *interface) 134b8c6a851SMichael Lotz { 135f1020a6cSMichael Lotz TRACE(("usb_module: set_alt_interface(0x%08x, 0x%08x)\n", device, interface)); 1365b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 1375b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 13817f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 1395b0ec61fSMichael Lotz 140b8c6a851SMichael Lotz return B_ERROR; 141b8c6a851SMichael Lotz } 142b8c6a851SMichael Lotz 143b8c6a851SMichael Lotz 144b8c6a851SMichael Lotz status_t 1455b0ec61fSMichael Lotz set_feature(usb_id handle, uint16 selector) 146b8c6a851SMichael Lotz { 1475b0ec61fSMichael Lotz TRACE(("usb_module: set_feature(0x%08x, %d)\n", handle, selector)); 1485b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(handle); 1498fedfdfcSMichael Lotz if (!object) 15017f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 151b8c6a851SMichael Lotz 1528fedfdfcSMichael Lotz return object->SetFeature(selector); 153b8c6a851SMichael Lotz } 154b8c6a851SMichael Lotz 155b8c6a851SMichael Lotz 156b8c6a851SMichael Lotz status_t 1575b0ec61fSMichael Lotz clear_feature(usb_id handle, uint16 selector) 158b8c6a851SMichael Lotz { 1595b0ec61fSMichael Lotz TRACE(("usb_module: clear_feature(0x%08x, %d)\n", handle, selector)); 1605b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(handle); 1618fedfdfcSMichael Lotz if (!object) 16217f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 163b8c6a851SMichael Lotz 1648fedfdfcSMichael Lotz return object->ClearFeature(selector); 165b8c6a851SMichael Lotz } 166b8c6a851SMichael Lotz 167b8c6a851SMichael Lotz 168b8c6a851SMichael Lotz status_t 1695b0ec61fSMichael Lotz get_status(usb_id handle, uint16 *status) 170b8c6a851SMichael Lotz { 1715b0ec61fSMichael Lotz TRACE(("usb_module: get_status(0x%08x, 0x%08x)\n", handle, status)); 1725b0ec61fSMichael Lotz if (!status) 1735b0ec61fSMichael Lotz return B_BAD_VALUE; 1745b0ec61fSMichael Lotz 1755b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(handle); 1768fedfdfcSMichael Lotz if (!object) 17717f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 178b8c6a851SMichael Lotz 1798fedfdfcSMichael Lotz return object->GetStatus(status); 180b8c6a851SMichael Lotz } 181b8c6a851SMichael Lotz 182b8c6a851SMichael Lotz 183b8c6a851SMichael Lotz status_t 1845b0ec61fSMichael Lotz get_descriptor(usb_device device, uint8 type, uint8 index, uint16 languageID, 1855b0ec61fSMichael Lotz void *data, size_t dataLength, size_t *actualLength) 186b8c6a851SMichael Lotz { 187f1020a6cSMichael Lotz TRACE(("usb_module: get_descriptor(0x%08x, 0x%02x, 0x%02x, 0x%04x, 0x%08x, %d, 0x%08x)\n", device, type, index, languageID, data, dataLength, actualLength)); 1885b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 1895b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 19017f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 191b8c6a851SMichael Lotz 1925b0ec61fSMichael Lotz return ((Device *)object)->GetDescriptor(type, index, languageID, 193b8c6a851SMichael Lotz data, dataLength, actualLength); 194b8c6a851SMichael Lotz } 195b8c6a851SMichael Lotz 196b8c6a851SMichael Lotz 197b8c6a851SMichael Lotz status_t 1985b0ec61fSMichael Lotz send_request(usb_device device, uint8 requestType, uint8 request, 1995b0ec61fSMichael Lotz uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength) 200b8c6a851SMichael Lotz { 2015b0ec61fSMichael Lotz TRACE(("usb_module: send_request(0x%08x, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, 0x%08x, 0x%08x)\n", device, requestType, request, value, index, length, data, actualLength)); 2025b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 2035b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 20417f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 205b8c6a851SMichael Lotz 2068fedfdfcSMichael Lotz return ((Device *)object)->DefaultPipe()->SendRequest(requestType, request, 2078fedfdfcSMichael Lotz value, index, length, data, length, actualLength); 208b8c6a851SMichael Lotz } 209b8c6a851SMichael Lotz 210b8c6a851SMichael Lotz 211b8c6a851SMichael Lotz status_t 2125b0ec61fSMichael Lotz queue_request(usb_device device, uint8 requestType, uint8 request, 2135b0ec61fSMichael Lotz uint16 value, uint16 index, uint16 length, void *data, 214b8c6a851SMichael Lotz usb_callback_func callback, void *callbackCookie) 215b8c6a851SMichael Lotz { 2165b0ec61fSMichael Lotz TRACE(("usb_module: queue_request(0x%08x, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, 0x%08x, 0x%08x, 0x%08x)\n", device, requestType, request, value, index, length, data, callback, callbackCookie)); 2175b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 2185b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 21917f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 220b8c6a851SMichael Lotz 2218fedfdfcSMichael Lotz return ((Device *)object)->DefaultPipe()->QueueRequest(requestType, 2228fedfdfcSMichael Lotz request, value, index, length, data, length, callback, callbackCookie); 223b8c6a851SMichael Lotz } 224b8c6a851SMichael Lotz 225b8c6a851SMichael Lotz 226b8c6a851SMichael Lotz status_t 2275b0ec61fSMichael Lotz queue_interrupt(usb_pipe pipe, void *data, size_t dataLength, 228b8c6a851SMichael Lotz usb_callback_func callback, void *callbackCookie) 229b8c6a851SMichael Lotz { 230f1020a6cSMichael Lotz TRACE(("usb_module: queue_interrupt(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, data, dataLength, callback, callbackCookie)); 2315b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(pipe); 2325b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) 23317f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 234b8c6a851SMichael Lotz 2355b0ec61fSMichael Lotz return ((InterruptPipe *)object)->QueueInterrupt(data, dataLength, callback, 236b8c6a851SMichael Lotz callbackCookie); 237b8c6a851SMichael Lotz } 238b8c6a851SMichael Lotz 239b8c6a851SMichael Lotz 240b8c6a851SMichael Lotz status_t 2415b0ec61fSMichael Lotz queue_bulk(usb_pipe pipe, void *data, size_t dataLength, 242b8c6a851SMichael Lotz usb_callback_func callback, void *callbackCookie) 243b8c6a851SMichael Lotz { 244f1020a6cSMichael Lotz TRACE(("usb_module: queue_bulk(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, data, dataLength, callback, callbackCookie)); 2455b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(pipe); 2465b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 24717f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 248b8c6a851SMichael Lotz 2495b0ec61fSMichael Lotz return ((BulkPipe *)object)->QueueBulk(data, dataLength, callback, 250b8c6a851SMichael Lotz callbackCookie); 251b8c6a851SMichael Lotz } 252b8c6a851SMichael Lotz 253b8c6a851SMichael Lotz 254b8c6a851SMichael Lotz status_t 2555b0ec61fSMichael Lotz queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount, 2565b0ec61fSMichael Lotz usb_callback_func callback, void *callbackCookie) 257b8c6a851SMichael Lotz { 2585b0ec61fSMichael Lotz TRACE(("usb_module: queue_bulk(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, vector, vectorCount, callback, callbackCookie)); 2595b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(pipe); 2605b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 26117f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 262b8c6a851SMichael Lotz 2631e8c0b36SMichael Lotz return ((BulkPipe *)object)->QueueBulkV(vector, vectorCount, callback, 2641e8c0b36SMichael Lotz callbackCookie); 265b8c6a851SMichael Lotz } 266b8c6a851SMichael Lotz 267b8c6a851SMichael Lotz 268b8c6a851SMichael Lotz status_t 2695b0ec61fSMichael Lotz queue_isochronous(usb_pipe pipe, void *data, size_t dataLength, 2701bad4a4eSMichael Lotz usb_iso_packet_descriptor *packetDesc, uint32 packetCount, 2711bad4a4eSMichael Lotz uint32 *startingFrameNumber, uint32 flags, usb_callback_func callback, 2725b0ec61fSMichael Lotz void *callbackCookie) 2735b0ec61fSMichael Lotz { 2741bad4a4eSMichael Lotz TRACE(("usb_module: queue_isochronous(0x%08x, 0x%08x, %d, 0x%08x, %d, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", pipe, data, dataLength, packetDesc, packetCount, startingFrameNumber, flags, callback, callbackCookie)); 2755b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(pipe); 2765b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) 27717f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 2785b0ec61fSMichael Lotz 2795b0ec61fSMichael Lotz return ((IsochronousPipe *)object)->QueueIsochronous(data, dataLength, 2801bad4a4eSMichael Lotz packetDesc, packetCount, startingFrameNumber, flags, callback, 2811bad4a4eSMichael Lotz callbackCookie); 2825b0ec61fSMichael Lotz } 2835b0ec61fSMichael Lotz 2845b0ec61fSMichael Lotz 2855b0ec61fSMichael Lotz status_t 2865b0ec61fSMichael Lotz set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets, 2875b0ec61fSMichael Lotz uint16 maxBufferDurationMS, uint16 sampleSize) 2885b0ec61fSMichael Lotz { 2895b0ec61fSMichael Lotz TRACE(("usb_module: set_pipe_policy(0x%08x, %d, %d, %d)\n", pipe, maxQueuedPackets, maxBufferDurationMS, sampleSize)); 2905b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(pipe); 2915b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) 29217f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 2935b0ec61fSMichael Lotz 294*00f6fab9SMichael Lotz return ((IsochronousPipe *)object)->SetPipePolicy(maxQueuedPackets, 295*00f6fab9SMichael Lotz maxBufferDurationMS, sampleSize); 2965b0ec61fSMichael Lotz } 2975b0ec61fSMichael Lotz 2985b0ec61fSMichael Lotz 2995b0ec61fSMichael Lotz status_t 3005b0ec61fSMichael Lotz cancel_queued_transfers(usb_pipe pipe) 301b8c6a851SMichael Lotz { 302f1020a6cSMichael Lotz TRACE(("usb_module: cancel_queued_transfers(0x%08x)\n", pipe)); 3035b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(pipe); 3045b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) 30517f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 3065b0ec61fSMichael Lotz 3075b0ec61fSMichael Lotz return ((Pipe *)object)->CancelQueuedTransfers(); 308b8c6a851SMichael Lotz } 309b8c6a851SMichael Lotz 310b8c6a851SMichael Lotz 311b8c6a851SMichael Lotz status_t 312b8c6a851SMichael Lotz usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize) 313b8c6a851SMichael Lotz { 314f1020a6cSMichael Lotz TRACE(("usb_module: usb_ioctl(0x%08x, 0x%08x, %d)\n", opcode, buffer, bufferSize)); 31564f3c065SMichael Lotz 31664f3c065SMichael Lotz switch (opcode) { 31764f3c065SMichael Lotz case 'DNAM': { 3185b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(*(usb_id *)buffer); 3195b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 3205b0ec61fSMichael Lotz return B_BAD_VALUE; 3215b0ec61fSMichael Lotz 32264f3c065SMichael Lotz uint32 index = 0; 3235b0ec61fSMichael Lotz return ((Device *)object)->BuildDeviceName((char *)buffer, &index, 3245b0ec61fSMichael Lotz bufferSize, NULL); 32564f3c065SMichael Lotz } 32664f3c065SMichael Lotz } 32764f3c065SMichael Lotz 32864f3c065SMichael Lotz return B_DEV_INVALID_IOCTL; 329b8c6a851SMichael Lotz } 330b8c6a851SMichael Lotz 331b8c6a851SMichael Lotz 33296da8285SMichael Lotz /* 3335b0ec61fSMichael Lotz This module exports the USB API v3 33496da8285SMichael Lotz */ 3355b0ec61fSMichael Lotz struct usb_module_info gModuleInfoV3 = { 3361501c2bfSNiels Sascha Reedijk // First the bus_manager_info: 3371501c2bfSNiels Sascha Reedijk { 3381501c2bfSNiels Sascha Reedijk { 3395b0ec61fSMichael Lotz "bus_managers/usb/v3", 3401501c2bfSNiels Sascha Reedijk B_KEEP_LOADED, // Keep loaded, even if no driver requires it 3411501c2bfSNiels Sascha Reedijk bus_std_ops 3421501c2bfSNiels Sascha Reedijk }, 3431501c2bfSNiels Sascha Reedijk NULL // the rescan function 3441501c2bfSNiels Sascha Reedijk }, 34596da8285SMichael Lotz 346b8c6a851SMichael Lotz register_driver, // register_driver 347b8c6a851SMichael Lotz install_notify, // install_notify 348b8c6a851SMichael Lotz uninstall_notify, // uninstall_notify 349b8c6a851SMichael Lotz get_device_descriptor, // get_device_descriptor 350b8c6a851SMichael Lotz get_nth_configuration, // get_nth_configuration 351b8c6a851SMichael Lotz get_configuration, // get_configuration 352b8c6a851SMichael Lotz set_configuration, // set_configuration 353b8c6a851SMichael Lotz set_alt_interface, // set_alt_interface 354b8c6a851SMichael Lotz set_feature, // set_feature 355b8c6a851SMichael Lotz clear_feature, // clear_feature 356b8c6a851SMichael Lotz get_status, // get_status 357b8c6a851SMichael Lotz get_descriptor, // get_descriptor 358b8c6a851SMichael Lotz send_request, // send_request 359b8c6a851SMichael Lotz queue_interrupt, // queue_interrupt 360b8c6a851SMichael Lotz queue_bulk, // queue_bulk 3615b0ec61fSMichael Lotz queue_bulk_v, // queue_bulk_v 362b8c6a851SMichael Lotz queue_isochronous, // queue_isochronous 363b8c6a851SMichael Lotz queue_request, // queue_request 364b8c6a851SMichael Lotz set_pipe_policy, // set_pipe_policy 365b8c6a851SMichael Lotz cancel_queued_transfers, // cancel_queued_transfers 366b8c6a851SMichael Lotz usb_ioctl // usb_ioctl 3671501c2bfSNiels Sascha Reedijk }; 3681501c2bfSNiels Sascha Reedijk 36996da8285SMichael Lotz 3705b0ec61fSMichael Lotz // 3715b0ec61fSMichael Lotz // #pragma mark - 3725b0ec61fSMichael Lotz // 3735b0ec61fSMichael Lotz 3745b0ec61fSMichael Lotz 3755b0ec61fSMichael Lotz const usb_device_descriptor * 3765b0ec61fSMichael Lotz get_device_descriptor_v2(const void *device) 3775b0ec61fSMichael Lotz { 3785b0ec61fSMichael Lotz return get_device_descriptor((usb_id)device); 3795b0ec61fSMichael Lotz } 3805b0ec61fSMichael Lotz 3815b0ec61fSMichael Lotz 3825b0ec61fSMichael Lotz const usb_configuration_info * 3835b0ec61fSMichael Lotz get_nth_configuration_v2(const void *device, uint index) 3845b0ec61fSMichael Lotz { 3855b0ec61fSMichael Lotz return get_nth_configuration((usb_id)device, index); 3865b0ec61fSMichael Lotz } 3875b0ec61fSMichael Lotz 3885b0ec61fSMichael Lotz 3895b0ec61fSMichael Lotz const usb_configuration_info * 3905b0ec61fSMichael Lotz get_configuration_v2(const void *device) 3915b0ec61fSMichael Lotz { 3925b0ec61fSMichael Lotz return get_configuration((usb_id)device); 3935b0ec61fSMichael Lotz } 3945b0ec61fSMichael Lotz 3955b0ec61fSMichael Lotz 3965b0ec61fSMichael Lotz status_t 3975b0ec61fSMichael Lotz set_configuration_v2(const void *device, 3985b0ec61fSMichael Lotz const usb_configuration_info *configuration) 3995b0ec61fSMichael Lotz { 4005b0ec61fSMichael Lotz return set_configuration((usb_id)device, configuration); 4015b0ec61fSMichael Lotz } 4025b0ec61fSMichael Lotz 4035b0ec61fSMichael Lotz 4045b0ec61fSMichael Lotz status_t 4055b0ec61fSMichael Lotz set_alt_interface_v2(const void *device, const usb_interface_info *interface) 4065b0ec61fSMichael Lotz { 4075b0ec61fSMichael Lotz return set_alt_interface((usb_id)device, interface); 4085b0ec61fSMichael Lotz } 4095b0ec61fSMichael Lotz 4105b0ec61fSMichael Lotz 4115b0ec61fSMichael Lotz status_t 4125b0ec61fSMichael Lotz set_feature_v2(const void *object, uint16 selector) 4135b0ec61fSMichael Lotz { 4145b0ec61fSMichael Lotz return set_feature((usb_id)object, selector); 4155b0ec61fSMichael Lotz } 4165b0ec61fSMichael Lotz 4175b0ec61fSMichael Lotz 4185b0ec61fSMichael Lotz status_t 4195b0ec61fSMichael Lotz clear_feature_v2(const void *object, uint16 selector) 4205b0ec61fSMichael Lotz { 4215b0ec61fSMichael Lotz return clear_feature((usb_id)object, selector); 4225b0ec61fSMichael Lotz } 4235b0ec61fSMichael Lotz 4245b0ec61fSMichael Lotz 4255b0ec61fSMichael Lotz status_t 4265b0ec61fSMichael Lotz get_status_v2(const void *object, uint16 *status) 4275b0ec61fSMichael Lotz { 4285b0ec61fSMichael Lotz return get_status((usb_id)object, status); 4295b0ec61fSMichael Lotz } 4305b0ec61fSMichael Lotz 4315b0ec61fSMichael Lotz 4325b0ec61fSMichael Lotz status_t 4335b0ec61fSMichael Lotz get_descriptor_v2(const void *device, uint8 type, uint8 index, 4345b0ec61fSMichael Lotz uint16 languageID, void *data, size_t dataLength, size_t *actualLength) 4355b0ec61fSMichael Lotz { 4365b0ec61fSMichael Lotz return get_descriptor((usb_id)device, type, index, languageID, data, 4375b0ec61fSMichael Lotz dataLength, actualLength); 4385b0ec61fSMichael Lotz } 4395b0ec61fSMichael Lotz 4405b0ec61fSMichael Lotz 4415b0ec61fSMichael Lotz status_t 4425b0ec61fSMichael Lotz send_request_v2(const void *device, uint8 requestType, uint8 request, 4435b0ec61fSMichael Lotz uint16 value, uint16 index, uint16 length, void *data, 4445b0ec61fSMichael Lotz size_t /*dataLength*/, size_t *actualLength) 4455b0ec61fSMichael Lotz { 4465b0ec61fSMichael Lotz return send_request((usb_id)device, requestType, request, value, index, 4475b0ec61fSMichael Lotz length, data, actualLength); 4485b0ec61fSMichael Lotz } 4495b0ec61fSMichael Lotz 4505b0ec61fSMichael Lotz 4515b0ec61fSMichael Lotz status_t 4525b0ec61fSMichael Lotz queue_request_v2(const void *device, uint8 requestType, uint8 request, 4535b0ec61fSMichael Lotz uint16 value, uint16 index, uint16 length, void *data, 4545b0ec61fSMichael Lotz size_t /*dataLength*/, usb_callback_func callback, void *callbackCookie) 4555b0ec61fSMichael Lotz { 4565b0ec61fSMichael Lotz return queue_request((usb_id)device, requestType, request, value, index, 4575b0ec61fSMichael Lotz length, data, callback, callbackCookie); 4585b0ec61fSMichael Lotz } 4595b0ec61fSMichael Lotz 4605b0ec61fSMichael Lotz 4615b0ec61fSMichael Lotz status_t 4625b0ec61fSMichael Lotz queue_interrupt_v2(const void *pipe, void *data, size_t dataLength, 4635b0ec61fSMichael Lotz usb_callback_func callback, void *callbackCookie) 4645b0ec61fSMichael Lotz { 4655b0ec61fSMichael Lotz return queue_interrupt((usb_id)pipe, data, dataLength, callback, 4665b0ec61fSMichael Lotz callbackCookie); 4675b0ec61fSMichael Lotz } 4685b0ec61fSMichael Lotz 4695b0ec61fSMichael Lotz 4705b0ec61fSMichael Lotz status_t 4715b0ec61fSMichael Lotz queue_bulk_v2(const void *pipe, void *data, size_t dataLength, 4725b0ec61fSMichael Lotz usb_callback_func callback, void *callbackCookie) 4735b0ec61fSMichael Lotz { 4745b0ec61fSMichael Lotz return queue_bulk((usb_id)pipe, data, dataLength, callback, 4755b0ec61fSMichael Lotz callbackCookie); 4765b0ec61fSMichael Lotz } 4775b0ec61fSMichael Lotz 4785b0ec61fSMichael Lotz 4795b0ec61fSMichael Lotz status_t 4805b0ec61fSMichael Lotz queue_isochronous_v2(const void *pipe, void *data, size_t dataLength, 4815b0ec61fSMichael Lotz rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback, 4825b0ec61fSMichael Lotz void *callbackCookie) 4835b0ec61fSMichael Lotz { 4841bad4a4eSMichael Lotz // ToDo: convert rlea to usb_iso_packet_descriptor 4851bad4a4eSMichael Lotz // ToDo: use a flag to indicate that the callback shall produce a rlea 4861bad4a4eSMichael Lotz usb_iso_packet_descriptor *packetDesc = NULL; 4871bad4a4eSMichael Lotz return queue_isochronous((usb_id)pipe, data, dataLength, packetDesc, 0, 4881bad4a4eSMichael Lotz NULL, 0, callback, callbackCookie); 4895b0ec61fSMichael Lotz } 4905b0ec61fSMichael Lotz 4915b0ec61fSMichael Lotz 4925b0ec61fSMichael Lotz status_t 4935b0ec61fSMichael Lotz set_pipe_policy_v2(const void *pipe, uint8 maxQueuedPackets, 4945b0ec61fSMichael Lotz uint16 maxBufferDurationMS, uint16 sampleSize) 4955b0ec61fSMichael Lotz { 4965b0ec61fSMichael Lotz return set_pipe_policy((usb_id)pipe, maxQueuedPackets, maxBufferDurationMS, 4975b0ec61fSMichael Lotz sampleSize); 4985b0ec61fSMichael Lotz } 4995b0ec61fSMichael Lotz 5005b0ec61fSMichael Lotz 5015b0ec61fSMichael Lotz status_t 5025b0ec61fSMichael Lotz cancel_queued_transfers_v2(const void *pipe) 5035b0ec61fSMichael Lotz { 5045b0ec61fSMichael Lotz return cancel_queued_transfers((usb_id)pipe); 5055b0ec61fSMichael Lotz } 5065b0ec61fSMichael Lotz 5075b0ec61fSMichael Lotz 5085b0ec61fSMichael Lotz struct usb_module_info_v2 { 5095b0ec61fSMichael Lotz bus_manager_info binfo; 5105b0ec61fSMichael Lotz status_t (*register_driver)(const char *, const usb_support_descriptor *, size_t, const char *); 5115b0ec61fSMichael Lotz status_t (*install_notify)(const char *, const usb_notify_hooks *); 5125b0ec61fSMichael Lotz status_t (*uninstall_notify)(const char *); 5135b0ec61fSMichael Lotz const usb_device_descriptor *(*get_device_descriptor)(const void *); 5145b0ec61fSMichael Lotz const usb_configuration_info *(*get_nth_configuration)(const void *, uint); 5155b0ec61fSMichael Lotz const usb_configuration_info *(*get_configuration)(const void *); 5165b0ec61fSMichael Lotz status_t (*set_configuration)(const void *, const usb_configuration_info *); 5175b0ec61fSMichael Lotz status_t (*set_alt_interface)(const void *, const usb_interface_info *); 5185b0ec61fSMichael Lotz status_t (*set_feature)(const void *, uint16); 5195b0ec61fSMichael Lotz status_t (*clear_feature)(const void *, uint16); 5205b0ec61fSMichael Lotz status_t (*get_status)(const void *, uint16 *); 5215b0ec61fSMichael Lotz status_t (*get_descriptor)(const void *, uint8, uint8, uint16, void *, size_t, size_t *); 5225b0ec61fSMichael Lotz status_t (*send_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, size_t *); 5235b0ec61fSMichael Lotz status_t (*queue_interrupt)(const void *, void *, size_t, usb_callback_func, void *); 5245b0ec61fSMichael Lotz status_t (*queue_bulk)(const void *, void *, size_t, usb_callback_func, void *); 5255b0ec61fSMichael Lotz status_t (*queue_isochronous)(const void *, void *, size_t, rlea *, uint16, usb_callback_func, void *); 5265b0ec61fSMichael Lotz status_t (*queue_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, usb_callback_func, void *); 5275b0ec61fSMichael Lotz status_t (*set_pipe_policy)(const void *, uint8, uint16, uint16); 5285b0ec61fSMichael Lotz status_t (*cancel_queued_transfers)(const void *); 5295b0ec61fSMichael Lotz status_t (*usb_ioctl)(uint32 opcode, void *,size_t); 5305b0ec61fSMichael Lotz }; 5315b0ec61fSMichael Lotz 5325b0ec61fSMichael Lotz 5335b0ec61fSMichael Lotz /* 5345b0ec61fSMichael Lotz This module exports the USB API v2 5355b0ec61fSMichael Lotz */ 5365b0ec61fSMichael Lotz struct usb_module_info_v2 gModuleInfoV2 = { 5375b0ec61fSMichael Lotz // First the bus_manager_info: 5385b0ec61fSMichael Lotz { 5395b0ec61fSMichael Lotz { 5405b0ec61fSMichael Lotz "bus_managers/usb/v2", 5415b0ec61fSMichael Lotz B_KEEP_LOADED, // Keep loaded, even if no driver requires it 5425b0ec61fSMichael Lotz bus_std_ops 5435b0ec61fSMichael Lotz }, 5445b0ec61fSMichael Lotz NULL // the rescan function 5455b0ec61fSMichael Lotz }, 5465b0ec61fSMichael Lotz 5475b0ec61fSMichael Lotz register_driver, // register_driver 5485b0ec61fSMichael Lotz install_notify, // install_notify 5495b0ec61fSMichael Lotz uninstall_notify, // uninstall_notify 5505b0ec61fSMichael Lotz get_device_descriptor_v2, // get_device_descriptor 5515b0ec61fSMichael Lotz get_nth_configuration_v2, // get_nth_configuration 5525b0ec61fSMichael Lotz get_configuration_v2, // get_configuration 5535b0ec61fSMichael Lotz set_configuration_v2, // set_configuration 5545b0ec61fSMichael Lotz set_alt_interface_v2, // set_alt_interface 5555b0ec61fSMichael Lotz set_feature_v2, // set_feature 5565b0ec61fSMichael Lotz clear_feature_v2, // clear_feature 5575b0ec61fSMichael Lotz get_status_v2, // get_status 5585b0ec61fSMichael Lotz get_descriptor_v2, // get_descriptor 5595b0ec61fSMichael Lotz send_request_v2, // send_request 5605b0ec61fSMichael Lotz queue_interrupt_v2, // queue_interrupt 5615b0ec61fSMichael Lotz queue_bulk_v2, // queue_bulk 5625b0ec61fSMichael Lotz queue_isochronous_v2, // queue_isochronous 5635b0ec61fSMichael Lotz queue_request_v2, // queue_request 5645b0ec61fSMichael Lotz set_pipe_policy_v2, // set_pipe_policy 5655b0ec61fSMichael Lotz cancel_queued_transfers_v2, // cancel_queued_transfers 5665b0ec61fSMichael Lotz usb_ioctl // usb_ioctl 5675b0ec61fSMichael Lotz }; 5685b0ec61fSMichael Lotz 5695b0ec61fSMichael Lotz 5705b0ec61fSMichael Lotz // 5715b0ec61fSMichael Lotz // #pragma mark - 5725b0ec61fSMichael Lotz // 5735b0ec61fSMichael Lotz 5745b0ec61fSMichael Lotz 5751501c2bfSNiels Sascha Reedijk module_info *modules[] = { 5765b0ec61fSMichael Lotz (module_info *)&gModuleInfoV2, 5775b0ec61fSMichael Lotz (module_info *)&gModuleInfoV3, 5781501c2bfSNiels Sascha Reedijk NULL 5791501c2bfSNiels Sascha Reedijk }; 580