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 26a94a8358SMichael Lotz void *address = NULL; 27a94a8358SMichael Lotz area_id shared = find_area("shared usb stack"); 28a94a8358SMichael Lotz if (shared >= B_OK && clone_area("usb stack clone", &address, 29a94a8358SMichael Lotz B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA, shared) >= B_OK) { 30a94a8358SMichael Lotz gUSBStack = *((Stack **)address); 31a94a8358SMichael Lotz return B_OK; 32a94a8358SMichael Lotz } 33a94a8358SMichael Lotz 3496da8285SMichael Lotz #ifdef TRACE_USB 351a2e81b5SNiels Sascha Reedijk set_dprintf_enabled(true); 361a2e81b5SNiels Sascha Reedijk load_driver_symbols("usb"); 37b8c6a851SMichael Lotz TRACE(("usb_module: init\n")); 3802ce23a1SMichael Lotz #endif 39b8c6a851SMichael Lotz Stack *stack = new(std::nothrow) Stack(); 40b8c6a851SMichael Lotz if (!stack) 41b8c6a851SMichael Lotz return B_NO_MEMORY; 42b8c6a851SMichael Lotz 4396da8285SMichael Lotz if (stack->InitCheck() != B_OK) { 441a2e81b5SNiels Sascha Reedijk delete stack; 451501c2bfSNiels Sascha Reedijk return ENODEV; 461501c2bfSNiels Sascha Reedijk } 4796da8285SMichael Lotz 48b8c6a851SMichael Lotz gUSBStack = stack; 49a94a8358SMichael Lotz shared = create_area("shared usb stack", &address, 50a94a8358SMichael Lotz B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, 51a94a8358SMichael Lotz B_KERNEL_WRITE_AREA); 52a94a8358SMichael Lotz if (shared >= B_OK) { 53a94a8358SMichael Lotz *((Stack **)address) = gUSBStack; 54a94a8358SMichael Lotz return B_OK; 55a94a8358SMichael Lotz } 561501c2bfSNiels Sascha Reedijk break; 5796da8285SMichael Lotz } 5896da8285SMichael Lotz 591501c2bfSNiels Sascha Reedijk case B_MODULE_UNINIT: 60c4cce727SMichael Lotz TRACE(("usb_module: uninit\n")); 61b8c6a851SMichael Lotz delete gUSBStack; 62b8c6a851SMichael Lotz gUSBStack = NULL; 631501c2bfSNiels Sascha Reedijk break; 6496da8285SMichael Lotz 651501c2bfSNiels Sascha Reedijk default: 661501c2bfSNiels Sascha Reedijk return EINVAL; 671501c2bfSNiels Sascha Reedijk } 6896da8285SMichael Lotz 691501c2bfSNiels Sascha Reedijk return B_OK; 701501c2bfSNiels Sascha Reedijk } 711501c2bfSNiels Sascha Reedijk 721501c2bfSNiels Sascha Reedijk 73b8c6a851SMichael Lotz status_t 74b8c6a851SMichael Lotz register_driver(const char *driverName, 75b8c6a851SMichael Lotz const usb_support_descriptor *descriptors, 76b8c6a851SMichael Lotz size_t count, const char *optionalRepublishDriverName) 77b8c6a851SMichael Lotz { 78b8c6a851SMichael Lotz return gUSBStack->RegisterDriver(driverName, descriptors, count, 79b8c6a851SMichael Lotz optionalRepublishDriverName); 80b8c6a851SMichael Lotz } 81b8c6a851SMichael Lotz 82b8c6a851SMichael Lotz 83b8c6a851SMichael Lotz status_t 84b8c6a851SMichael Lotz install_notify(const char *driverName, const usb_notify_hooks *hooks) 85b8c6a851SMichael Lotz { 86b8c6a851SMichael Lotz return gUSBStack->InstallNotify(driverName, hooks); 87b8c6a851SMichael Lotz } 88b8c6a851SMichael Lotz 89b8c6a851SMichael Lotz 90b8c6a851SMichael Lotz status_t 91b8c6a851SMichael Lotz uninstall_notify(const char *driverName) 92b8c6a851SMichael Lotz { 93b8c6a851SMichael Lotz return gUSBStack->UninstallNotify(driverName); 94b8c6a851SMichael Lotz } 95b8c6a851SMichael Lotz 96b8c6a851SMichael Lotz 97b8c6a851SMichael Lotz const usb_device_descriptor * 985b0ec61fSMichael Lotz get_device_descriptor(usb_device device) 99b8c6a851SMichael Lotz { 100c4cce727SMichael Lotz TRACE(("usb_module: get_device_descriptor(%ld)\n", device)); 1015b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 1025b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 103b8c6a851SMichael Lotz return NULL; 104b8c6a851SMichael Lotz 1055b0ec61fSMichael Lotz return ((Device *)object)->DeviceDescriptor(); 106b8c6a851SMichael Lotz } 107b8c6a851SMichael Lotz 108b8c6a851SMichael Lotz 109b8c6a851SMichael Lotz const usb_configuration_info * 1105b0ec61fSMichael Lotz get_nth_configuration(usb_device device, uint index) 111b8c6a851SMichael Lotz { 112c4cce727SMichael Lotz TRACE(("usb_module: get_nth_configuration(%ld, %d)\n", device, index)); 1135b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 1145b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 115b8c6a851SMichael Lotz return NULL; 116b8c6a851SMichael Lotz 1175b0ec61fSMichael Lotz return ((Device *)object)->ConfigurationAt((int32)index); 118b8c6a851SMichael Lotz } 119b8c6a851SMichael Lotz 120b8c6a851SMichael Lotz 121b8c6a851SMichael Lotz const usb_configuration_info * 1225b0ec61fSMichael Lotz get_configuration(usb_device device) 123b8c6a851SMichael Lotz { 124c4cce727SMichael Lotz TRACE(("usb_module: get_configuration(%ld)\n", device)); 1255b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 1265b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 127b8c6a851SMichael Lotz return NULL; 128b8c6a851SMichael Lotz 1295b0ec61fSMichael Lotz return ((Device *)object)->Configuration(); 130b8c6a851SMichael Lotz } 131b8c6a851SMichael Lotz 132b8c6a851SMichael Lotz 133b8c6a851SMichael Lotz status_t 1345b0ec61fSMichael Lotz set_configuration(usb_device device, 135b8c6a851SMichael Lotz const usb_configuration_info *configuration) 136b8c6a851SMichael Lotz { 137c4cce727SMichael Lotz TRACE(("usb_module: set_configuration(%ld, 0x%08lx)\n", device, configuration)); 1385b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 1395b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 14017f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 141b8c6a851SMichael Lotz 1425b0ec61fSMichael Lotz return ((Device *)object)->SetConfiguration(configuration); 143b8c6a851SMichael Lotz } 144b8c6a851SMichael Lotz 145b8c6a851SMichael Lotz 146b8c6a851SMichael Lotz status_t 1475b0ec61fSMichael Lotz set_alt_interface(usb_device device, const usb_interface_info *interface) 148b8c6a851SMichael Lotz { 149c4cce727SMichael Lotz TRACE(("usb_module: set_alt_interface(%ld, 0x%08lx)\n", device, interface)); 1505b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 1515b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 15217f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 1535b0ec61fSMichael Lotz 154b8c6a851SMichael Lotz return B_ERROR; 155b8c6a851SMichael Lotz } 156b8c6a851SMichael Lotz 157b8c6a851SMichael Lotz 158b8c6a851SMichael Lotz status_t 1595b0ec61fSMichael Lotz set_feature(usb_id handle, uint16 selector) 160b8c6a851SMichael Lotz { 161c4cce727SMichael Lotz TRACE(("usb_module: set_feature(%ld, %d)\n", handle, selector)); 1625b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(handle); 1638fedfdfcSMichael Lotz if (!object) 16417f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 165b8c6a851SMichael Lotz 1668fedfdfcSMichael Lotz return object->SetFeature(selector); 167b8c6a851SMichael Lotz } 168b8c6a851SMichael Lotz 169b8c6a851SMichael Lotz 170b8c6a851SMichael Lotz status_t 1715b0ec61fSMichael Lotz clear_feature(usb_id handle, uint16 selector) 172b8c6a851SMichael Lotz { 173c4cce727SMichael Lotz TRACE(("usb_module: clear_feature(%ld, %d)\n", handle, selector)); 1745b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(handle); 1758fedfdfcSMichael Lotz if (!object) 17617f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 177b8c6a851SMichael Lotz 1788fedfdfcSMichael Lotz return object->ClearFeature(selector); 179b8c6a851SMichael Lotz } 180b8c6a851SMichael Lotz 181b8c6a851SMichael Lotz 182b8c6a851SMichael Lotz status_t 1835b0ec61fSMichael Lotz get_status(usb_id handle, uint16 *status) 184b8c6a851SMichael Lotz { 185c4cce727SMichael Lotz TRACE(("usb_module: get_status(%ld, 0x%08lx)\n", handle, status)); 1865b0ec61fSMichael Lotz if (!status) 1875b0ec61fSMichael Lotz return B_BAD_VALUE; 1885b0ec61fSMichael Lotz 1895b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(handle); 1908fedfdfcSMichael Lotz if (!object) 19117f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 192b8c6a851SMichael Lotz 1938fedfdfcSMichael Lotz return object->GetStatus(status); 194b8c6a851SMichael Lotz } 195b8c6a851SMichael Lotz 196b8c6a851SMichael Lotz 197b8c6a851SMichael Lotz status_t 1985b0ec61fSMichael Lotz get_descriptor(usb_device device, uint8 type, uint8 index, uint16 languageID, 1995b0ec61fSMichael Lotz void *data, size_t dataLength, size_t *actualLength) 200b8c6a851SMichael Lotz { 201c4cce727SMichael Lotz TRACE(("usb_module: get_descriptor(%ld, 0x%02x, 0x%02x, 0x%04x, 0x%08lx, %ld, 0x%08lx)\n", device, type, index, languageID, data, dataLength, 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 2065b0ec61fSMichael Lotz return ((Device *)object)->GetDescriptor(type, index, languageID, 207b8c6a851SMichael Lotz data, dataLength, actualLength); 208b8c6a851SMichael Lotz } 209b8c6a851SMichael Lotz 210b8c6a851SMichael Lotz 211b8c6a851SMichael Lotz status_t 2125b0ec61fSMichael Lotz send_request(usb_device device, uint8 requestType, uint8 request, 2135b0ec61fSMichael Lotz uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength) 214b8c6a851SMichael Lotz { 215c4cce727SMichael Lotz TRACE(("usb_module: send_request(%ld, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, 0x%08lx, 0x%08lx)\n", device, requestType, request, value, index, length, data, actualLength)); 2165b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 2175b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 21817f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 219b8c6a851SMichael Lotz 2208fedfdfcSMichael Lotz return ((Device *)object)->DefaultPipe()->SendRequest(requestType, request, 2218fedfdfcSMichael Lotz value, index, length, data, length, actualLength); 222b8c6a851SMichael Lotz } 223b8c6a851SMichael Lotz 224b8c6a851SMichael Lotz 225b8c6a851SMichael Lotz status_t 2265b0ec61fSMichael Lotz queue_request(usb_device device, uint8 requestType, uint8 request, 2275b0ec61fSMichael Lotz uint16 value, uint16 index, uint16 length, void *data, 228b8c6a851SMichael Lotz usb_callback_func callback, void *callbackCookie) 229b8c6a851SMichael Lotz { 230c4cce727SMichael Lotz TRACE(("usb_module: queue_request(%ld, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %ld, 0x%08lx, 0x%08lx, 0x%08lx)\n", device, requestType, request, value, index, length, data, callback, callbackCookie)); 2315b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(device); 2325b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 23317f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 234b8c6a851SMichael Lotz 2358fedfdfcSMichael Lotz return ((Device *)object)->DefaultPipe()->QueueRequest(requestType, 2368fedfdfcSMichael Lotz request, value, index, length, data, length, callback, callbackCookie); 237b8c6a851SMichael Lotz } 238b8c6a851SMichael Lotz 239b8c6a851SMichael Lotz 240b8c6a851SMichael Lotz status_t 2415b0ec61fSMichael Lotz queue_interrupt(usb_pipe pipe, void *data, size_t dataLength, 242b8c6a851SMichael Lotz usb_callback_func callback, void *callbackCookie) 243b8c6a851SMichael Lotz { 244c4cce727SMichael Lotz TRACE(("usb_module: queue_interrupt(%ld, 0x%08lx, %ld, 0x%08lx, 0x%08lx)\n", pipe, data, dataLength, callback, callbackCookie)); 2455b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(pipe); 2465b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0) 24717f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 248b8c6a851SMichael Lotz 2495b0ec61fSMichael Lotz return ((InterruptPipe *)object)->QueueInterrupt(data, dataLength, callback, 250b8c6a851SMichael Lotz callbackCookie); 251b8c6a851SMichael Lotz } 252b8c6a851SMichael Lotz 253b8c6a851SMichael Lotz 254b8c6a851SMichael Lotz status_t 2555b0ec61fSMichael Lotz queue_bulk(usb_pipe pipe, void *data, size_t dataLength, 256b8c6a851SMichael Lotz usb_callback_func callback, void *callbackCookie) 257b8c6a851SMichael Lotz { 258c4cce727SMichael Lotz TRACE(("usb_module: queue_bulk(%ld, 0x%08lx, %ld, 0x%08lx, 0x%08lx)\n", pipe, data, dataLength, 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 2635b0ec61fSMichael Lotz return ((BulkPipe *)object)->QueueBulk(data, dataLength, callback, 264b8c6a851SMichael Lotz callbackCookie); 265b8c6a851SMichael Lotz } 266b8c6a851SMichael Lotz 267b8c6a851SMichael Lotz 268b8c6a851SMichael Lotz status_t 2695b0ec61fSMichael Lotz queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount, 2705b0ec61fSMichael Lotz usb_callback_func callback, void *callbackCookie) 271b8c6a851SMichael Lotz { 272c4cce727SMichael Lotz TRACE(("usb_module: queue_bulk(%ld, 0x%08lx, %ld, 0x%08lx, 0x%08lx)\n", pipe, vector, vectorCount, callback, callbackCookie)); 2735b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(pipe); 2745b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0) 27517f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 276b8c6a851SMichael Lotz 2771e8c0b36SMichael Lotz return ((BulkPipe *)object)->QueueBulkV(vector, vectorCount, callback, 2781e8c0b36SMichael Lotz callbackCookie); 279b8c6a851SMichael Lotz } 280b8c6a851SMichael Lotz 281b8c6a851SMichael Lotz 282b8c6a851SMichael Lotz status_t 2835b0ec61fSMichael Lotz queue_isochronous(usb_pipe pipe, void *data, size_t dataLength, 2841bad4a4eSMichael Lotz usb_iso_packet_descriptor *packetDesc, uint32 packetCount, 2851bad4a4eSMichael Lotz uint32 *startingFrameNumber, uint32 flags, usb_callback_func callback, 2865b0ec61fSMichael Lotz void *callbackCookie) 2875b0ec61fSMichael Lotz { 288c4cce727SMichael Lotz TRACE(("usb_module: queue_isochronous(%ld, 0x%08lx, %ld, 0x%08lx, %ld, 0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n", pipe, data, dataLength, packetDesc, packetCount, startingFrameNumber, flags, callback, callbackCookie)); 2895b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(pipe); 2905b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) 29117f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 2925b0ec61fSMichael Lotz 2935b0ec61fSMichael Lotz return ((IsochronousPipe *)object)->QueueIsochronous(data, dataLength, 2941bad4a4eSMichael Lotz packetDesc, packetCount, startingFrameNumber, flags, callback, 2951bad4a4eSMichael Lotz callbackCookie); 2965b0ec61fSMichael Lotz } 2975b0ec61fSMichael Lotz 2985b0ec61fSMichael Lotz 2995b0ec61fSMichael Lotz status_t 3005b0ec61fSMichael Lotz set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets, 3015b0ec61fSMichael Lotz uint16 maxBufferDurationMS, uint16 sampleSize) 3025b0ec61fSMichael Lotz { 303c4cce727SMichael Lotz TRACE(("usb_module: set_pipe_policy(%ld, %d, %d, %d)\n", pipe, maxQueuedPackets, maxBufferDurationMS, sampleSize)); 3045b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(pipe); 3055b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0) 30617f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 3075b0ec61fSMichael Lotz 30800f6fab9SMichael Lotz return ((IsochronousPipe *)object)->SetPipePolicy(maxQueuedPackets, 30900f6fab9SMichael Lotz maxBufferDurationMS, sampleSize); 3105b0ec61fSMichael Lotz } 3115b0ec61fSMichael Lotz 3125b0ec61fSMichael Lotz 3135b0ec61fSMichael Lotz status_t 3145b0ec61fSMichael Lotz cancel_queued_transfers(usb_pipe pipe) 315b8c6a851SMichael Lotz { 316c4cce727SMichael Lotz TRACE(("usb_module: cancel_queued_transfers(%ld)\n", pipe)); 3175b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(pipe); 3185b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_PIPE) == 0) 31917f83b21SMichael Lotz return B_DEV_INVALID_PIPE; 3205b0ec61fSMichael Lotz 321*13508e8bSMichael Lotz return ((Pipe *)object)->CancelQueuedTransfers(false); 322b8c6a851SMichael Lotz } 323b8c6a851SMichael Lotz 324b8c6a851SMichael Lotz 325b8c6a851SMichael Lotz status_t 326b8c6a851SMichael Lotz usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize) 327b8c6a851SMichael Lotz { 328c4cce727SMichael Lotz TRACE(("usb_module: usb_ioctl(0x%08lx, 0x%08lx, %ld)\n", opcode, buffer, bufferSize)); 32964f3c065SMichael Lotz 33064f3c065SMichael Lotz switch (opcode) { 33164f3c065SMichael Lotz case 'DNAM': { 3325b0ec61fSMichael Lotz Object *object = gUSBStack->GetObject(*(usb_id *)buffer); 3335b0ec61fSMichael Lotz if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0) 3345b0ec61fSMichael Lotz return B_BAD_VALUE; 3355b0ec61fSMichael Lotz 33664f3c065SMichael Lotz uint32 index = 0; 3375b0ec61fSMichael Lotz return ((Device *)object)->BuildDeviceName((char *)buffer, &index, 3385b0ec61fSMichael Lotz bufferSize, NULL); 33964f3c065SMichael Lotz } 34064f3c065SMichael Lotz } 34164f3c065SMichael Lotz 34264f3c065SMichael Lotz return B_DEV_INVALID_IOCTL; 343b8c6a851SMichael Lotz } 344b8c6a851SMichael Lotz 345b8c6a851SMichael Lotz 34696da8285SMichael Lotz /* 3475b0ec61fSMichael Lotz This module exports the USB API v3 34896da8285SMichael Lotz */ 3495b0ec61fSMichael Lotz struct usb_module_info gModuleInfoV3 = { 3501501c2bfSNiels Sascha Reedijk // First the bus_manager_info: 3511501c2bfSNiels Sascha Reedijk { 3521501c2bfSNiels Sascha Reedijk { 3535b0ec61fSMichael Lotz "bus_managers/usb/v3", 3541501c2bfSNiels Sascha Reedijk B_KEEP_LOADED, // Keep loaded, even if no driver requires it 3551501c2bfSNiels Sascha Reedijk bus_std_ops 3561501c2bfSNiels Sascha Reedijk }, 3571501c2bfSNiels Sascha Reedijk NULL // the rescan function 3581501c2bfSNiels Sascha Reedijk }, 35996da8285SMichael Lotz 360b8c6a851SMichael Lotz register_driver, // register_driver 361b8c6a851SMichael Lotz install_notify, // install_notify 362b8c6a851SMichael Lotz uninstall_notify, // uninstall_notify 363b8c6a851SMichael Lotz get_device_descriptor, // get_device_descriptor 364b8c6a851SMichael Lotz get_nth_configuration, // get_nth_configuration 365b8c6a851SMichael Lotz get_configuration, // get_configuration 366b8c6a851SMichael Lotz set_configuration, // set_configuration 367b8c6a851SMichael Lotz set_alt_interface, // set_alt_interface 368b8c6a851SMichael Lotz set_feature, // set_feature 369b8c6a851SMichael Lotz clear_feature, // clear_feature 370b8c6a851SMichael Lotz get_status, // get_status 371b8c6a851SMichael Lotz get_descriptor, // get_descriptor 372b8c6a851SMichael Lotz send_request, // send_request 373b8c6a851SMichael Lotz queue_interrupt, // queue_interrupt 374b8c6a851SMichael Lotz queue_bulk, // queue_bulk 3755b0ec61fSMichael Lotz queue_bulk_v, // queue_bulk_v 376b8c6a851SMichael Lotz queue_isochronous, // queue_isochronous 377b8c6a851SMichael Lotz queue_request, // queue_request 378b8c6a851SMichael Lotz set_pipe_policy, // set_pipe_policy 379b8c6a851SMichael Lotz cancel_queued_transfers, // cancel_queued_transfers 380b8c6a851SMichael Lotz usb_ioctl // usb_ioctl 3811501c2bfSNiels Sascha Reedijk }; 3821501c2bfSNiels Sascha Reedijk 38396da8285SMichael Lotz 3845b0ec61fSMichael Lotz // 3855b0ec61fSMichael Lotz // #pragma mark - 3865b0ec61fSMichael Lotz // 3875b0ec61fSMichael Lotz 3885b0ec61fSMichael Lotz 3895b0ec61fSMichael Lotz const usb_device_descriptor * 3905b0ec61fSMichael Lotz get_device_descriptor_v2(const void *device) 3915b0ec61fSMichael Lotz { 3925b0ec61fSMichael Lotz return get_device_descriptor((usb_id)device); 3935b0ec61fSMichael Lotz } 3945b0ec61fSMichael Lotz 3955b0ec61fSMichael Lotz 3965b0ec61fSMichael Lotz const usb_configuration_info * 3975b0ec61fSMichael Lotz get_nth_configuration_v2(const void *device, uint index) 3985b0ec61fSMichael Lotz { 3995b0ec61fSMichael Lotz return get_nth_configuration((usb_id)device, index); 4005b0ec61fSMichael Lotz } 4015b0ec61fSMichael Lotz 4025b0ec61fSMichael Lotz 4035b0ec61fSMichael Lotz const usb_configuration_info * 4045b0ec61fSMichael Lotz get_configuration_v2(const void *device) 4055b0ec61fSMichael Lotz { 4065b0ec61fSMichael Lotz return get_configuration((usb_id)device); 4075b0ec61fSMichael Lotz } 4085b0ec61fSMichael Lotz 4095b0ec61fSMichael Lotz 4105b0ec61fSMichael Lotz status_t 4115b0ec61fSMichael Lotz set_configuration_v2(const void *device, 4125b0ec61fSMichael Lotz const usb_configuration_info *configuration) 4135b0ec61fSMichael Lotz { 4145b0ec61fSMichael Lotz return set_configuration((usb_id)device, configuration); 4155b0ec61fSMichael Lotz } 4165b0ec61fSMichael Lotz 4175b0ec61fSMichael Lotz 4185b0ec61fSMichael Lotz status_t 4195b0ec61fSMichael Lotz set_alt_interface_v2(const void *device, const usb_interface_info *interface) 4205b0ec61fSMichael Lotz { 4215b0ec61fSMichael Lotz return set_alt_interface((usb_id)device, interface); 4225b0ec61fSMichael Lotz } 4235b0ec61fSMichael Lotz 4245b0ec61fSMichael Lotz 4255b0ec61fSMichael Lotz status_t 4265b0ec61fSMichael Lotz set_feature_v2(const void *object, uint16 selector) 4275b0ec61fSMichael Lotz { 4285b0ec61fSMichael Lotz return set_feature((usb_id)object, selector); 4295b0ec61fSMichael Lotz } 4305b0ec61fSMichael Lotz 4315b0ec61fSMichael Lotz 4325b0ec61fSMichael Lotz status_t 4335b0ec61fSMichael Lotz clear_feature_v2(const void *object, uint16 selector) 4345b0ec61fSMichael Lotz { 4355b0ec61fSMichael Lotz return clear_feature((usb_id)object, selector); 4365b0ec61fSMichael Lotz } 4375b0ec61fSMichael Lotz 4385b0ec61fSMichael Lotz 4395b0ec61fSMichael Lotz status_t 4405b0ec61fSMichael Lotz get_status_v2(const void *object, uint16 *status) 4415b0ec61fSMichael Lotz { 4425b0ec61fSMichael Lotz return get_status((usb_id)object, status); 4435b0ec61fSMichael Lotz } 4445b0ec61fSMichael Lotz 4455b0ec61fSMichael Lotz 4465b0ec61fSMichael Lotz status_t 4475b0ec61fSMichael Lotz get_descriptor_v2(const void *device, uint8 type, uint8 index, 4485b0ec61fSMichael Lotz uint16 languageID, void *data, size_t dataLength, size_t *actualLength) 4495b0ec61fSMichael Lotz { 4505b0ec61fSMichael Lotz return get_descriptor((usb_id)device, type, index, languageID, data, 4515b0ec61fSMichael Lotz dataLength, actualLength); 4525b0ec61fSMichael Lotz } 4535b0ec61fSMichael Lotz 4545b0ec61fSMichael Lotz 4555b0ec61fSMichael Lotz status_t 4565b0ec61fSMichael Lotz send_request_v2(const void *device, uint8 requestType, uint8 request, 4575b0ec61fSMichael Lotz uint16 value, uint16 index, uint16 length, void *data, 4585b0ec61fSMichael Lotz size_t /*dataLength*/, size_t *actualLength) 4595b0ec61fSMichael Lotz { 4605b0ec61fSMichael Lotz return send_request((usb_id)device, requestType, request, value, index, 4615b0ec61fSMichael Lotz length, data, actualLength); 4625b0ec61fSMichael Lotz } 4635b0ec61fSMichael Lotz 4645b0ec61fSMichael Lotz 4655b0ec61fSMichael Lotz status_t 4665b0ec61fSMichael Lotz queue_request_v2(const void *device, uint8 requestType, uint8 request, 4675b0ec61fSMichael Lotz uint16 value, uint16 index, uint16 length, void *data, 4685b0ec61fSMichael Lotz size_t /*dataLength*/, usb_callback_func callback, void *callbackCookie) 4695b0ec61fSMichael Lotz { 4705b0ec61fSMichael Lotz return queue_request((usb_id)device, requestType, request, value, index, 4715b0ec61fSMichael Lotz length, data, callback, callbackCookie); 4725b0ec61fSMichael Lotz } 4735b0ec61fSMichael Lotz 4745b0ec61fSMichael Lotz 4755b0ec61fSMichael Lotz status_t 4765b0ec61fSMichael Lotz queue_interrupt_v2(const void *pipe, void *data, size_t dataLength, 4775b0ec61fSMichael Lotz usb_callback_func callback, void *callbackCookie) 4785b0ec61fSMichael Lotz { 4795b0ec61fSMichael Lotz return queue_interrupt((usb_id)pipe, data, dataLength, callback, 4805b0ec61fSMichael Lotz callbackCookie); 4815b0ec61fSMichael Lotz } 4825b0ec61fSMichael Lotz 4835b0ec61fSMichael Lotz 4845b0ec61fSMichael Lotz status_t 4855b0ec61fSMichael Lotz queue_bulk_v2(const void *pipe, void *data, size_t dataLength, 4865b0ec61fSMichael Lotz usb_callback_func callback, void *callbackCookie) 4875b0ec61fSMichael Lotz { 4885b0ec61fSMichael Lotz return queue_bulk((usb_id)pipe, data, dataLength, callback, 4895b0ec61fSMichael Lotz callbackCookie); 4905b0ec61fSMichael Lotz } 4915b0ec61fSMichael Lotz 4925b0ec61fSMichael Lotz 4935b0ec61fSMichael Lotz status_t 4945b0ec61fSMichael Lotz queue_isochronous_v2(const void *pipe, void *data, size_t dataLength, 4955b0ec61fSMichael Lotz rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback, 4965b0ec61fSMichael Lotz void *callbackCookie) 4975b0ec61fSMichael Lotz { 4981bad4a4eSMichael Lotz // ToDo: convert rlea to usb_iso_packet_descriptor 4991bad4a4eSMichael Lotz // ToDo: use a flag to indicate that the callback shall produce a rlea 5001bad4a4eSMichael Lotz usb_iso_packet_descriptor *packetDesc = NULL; 5011bad4a4eSMichael Lotz return queue_isochronous((usb_id)pipe, data, dataLength, packetDesc, 0, 5021bad4a4eSMichael Lotz NULL, 0, callback, callbackCookie); 5035b0ec61fSMichael Lotz } 5045b0ec61fSMichael Lotz 5055b0ec61fSMichael Lotz 5065b0ec61fSMichael Lotz status_t 5075b0ec61fSMichael Lotz set_pipe_policy_v2(const void *pipe, uint8 maxQueuedPackets, 5085b0ec61fSMichael Lotz uint16 maxBufferDurationMS, uint16 sampleSize) 5095b0ec61fSMichael Lotz { 5105b0ec61fSMichael Lotz return set_pipe_policy((usb_id)pipe, maxQueuedPackets, maxBufferDurationMS, 5115b0ec61fSMichael Lotz sampleSize); 5125b0ec61fSMichael Lotz } 5135b0ec61fSMichael Lotz 5145b0ec61fSMichael Lotz 5155b0ec61fSMichael Lotz status_t 5165b0ec61fSMichael Lotz cancel_queued_transfers_v2(const void *pipe) 5175b0ec61fSMichael Lotz { 5185b0ec61fSMichael Lotz return cancel_queued_transfers((usb_id)pipe); 5195b0ec61fSMichael Lotz } 5205b0ec61fSMichael Lotz 5215b0ec61fSMichael Lotz 5225b0ec61fSMichael Lotz struct usb_module_info_v2 { 5235b0ec61fSMichael Lotz bus_manager_info binfo; 5245b0ec61fSMichael Lotz status_t (*register_driver)(const char *, const usb_support_descriptor *, size_t, const char *); 5255b0ec61fSMichael Lotz status_t (*install_notify)(const char *, const usb_notify_hooks *); 5265b0ec61fSMichael Lotz status_t (*uninstall_notify)(const char *); 5275b0ec61fSMichael Lotz const usb_device_descriptor *(*get_device_descriptor)(const void *); 5285b0ec61fSMichael Lotz const usb_configuration_info *(*get_nth_configuration)(const void *, uint); 5295b0ec61fSMichael Lotz const usb_configuration_info *(*get_configuration)(const void *); 5305b0ec61fSMichael Lotz status_t (*set_configuration)(const void *, const usb_configuration_info *); 5315b0ec61fSMichael Lotz status_t (*set_alt_interface)(const void *, const usb_interface_info *); 5325b0ec61fSMichael Lotz status_t (*set_feature)(const void *, uint16); 5335b0ec61fSMichael Lotz status_t (*clear_feature)(const void *, uint16); 5345b0ec61fSMichael Lotz status_t (*get_status)(const void *, uint16 *); 5355b0ec61fSMichael Lotz status_t (*get_descriptor)(const void *, uint8, uint8, uint16, void *, size_t, size_t *); 5365b0ec61fSMichael Lotz status_t (*send_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, size_t *); 5375b0ec61fSMichael Lotz status_t (*queue_interrupt)(const void *, void *, size_t, usb_callback_func, void *); 5385b0ec61fSMichael Lotz status_t (*queue_bulk)(const void *, void *, size_t, usb_callback_func, void *); 5395b0ec61fSMichael Lotz status_t (*queue_isochronous)(const void *, void *, size_t, rlea *, uint16, usb_callback_func, void *); 5405b0ec61fSMichael Lotz status_t (*queue_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, usb_callback_func, void *); 5415b0ec61fSMichael Lotz status_t (*set_pipe_policy)(const void *, uint8, uint16, uint16); 5425b0ec61fSMichael Lotz status_t (*cancel_queued_transfers)(const void *); 5435b0ec61fSMichael Lotz status_t (*usb_ioctl)(uint32 opcode, void *,size_t); 5445b0ec61fSMichael Lotz }; 5455b0ec61fSMichael Lotz 5465b0ec61fSMichael Lotz 5475b0ec61fSMichael Lotz /* 5485b0ec61fSMichael Lotz This module exports the USB API v2 5495b0ec61fSMichael Lotz */ 5505b0ec61fSMichael Lotz struct usb_module_info_v2 gModuleInfoV2 = { 5515b0ec61fSMichael Lotz // First the bus_manager_info: 5525b0ec61fSMichael Lotz { 5535b0ec61fSMichael Lotz { 5545b0ec61fSMichael Lotz "bus_managers/usb/v2", 5555b0ec61fSMichael Lotz B_KEEP_LOADED, // Keep loaded, even if no driver requires it 5565b0ec61fSMichael Lotz bus_std_ops 5575b0ec61fSMichael Lotz }, 5585b0ec61fSMichael Lotz NULL // the rescan function 5595b0ec61fSMichael Lotz }, 5605b0ec61fSMichael Lotz 5615b0ec61fSMichael Lotz register_driver, // register_driver 5625b0ec61fSMichael Lotz install_notify, // install_notify 5635b0ec61fSMichael Lotz uninstall_notify, // uninstall_notify 5645b0ec61fSMichael Lotz get_device_descriptor_v2, // get_device_descriptor 5655b0ec61fSMichael Lotz get_nth_configuration_v2, // get_nth_configuration 5665b0ec61fSMichael Lotz get_configuration_v2, // get_configuration 5675b0ec61fSMichael Lotz set_configuration_v2, // set_configuration 5685b0ec61fSMichael Lotz set_alt_interface_v2, // set_alt_interface 5695b0ec61fSMichael Lotz set_feature_v2, // set_feature 5705b0ec61fSMichael Lotz clear_feature_v2, // clear_feature 5715b0ec61fSMichael Lotz get_status_v2, // get_status 5725b0ec61fSMichael Lotz get_descriptor_v2, // get_descriptor 5735b0ec61fSMichael Lotz send_request_v2, // send_request 5745b0ec61fSMichael Lotz queue_interrupt_v2, // queue_interrupt 5755b0ec61fSMichael Lotz queue_bulk_v2, // queue_bulk 5765b0ec61fSMichael Lotz queue_isochronous_v2, // queue_isochronous 5775b0ec61fSMichael Lotz queue_request_v2, // queue_request 5785b0ec61fSMichael Lotz set_pipe_policy_v2, // set_pipe_policy 5795b0ec61fSMichael Lotz cancel_queued_transfers_v2, // cancel_queued_transfers 5805b0ec61fSMichael Lotz usb_ioctl // usb_ioctl 5815b0ec61fSMichael Lotz }; 5825b0ec61fSMichael Lotz 5835b0ec61fSMichael Lotz 5845b0ec61fSMichael Lotz // 5855b0ec61fSMichael Lotz // #pragma mark - 5865b0ec61fSMichael Lotz // 5875b0ec61fSMichael Lotz 5885b0ec61fSMichael Lotz 5891501c2bfSNiels Sascha Reedijk module_info *modules[] = { 5905b0ec61fSMichael Lotz (module_info *)&gModuleInfoV2, 5915b0ec61fSMichael Lotz (module_info *)&gModuleInfoV3, 5921501c2bfSNiels Sascha Reedijk NULL 5931501c2bfSNiels Sascha Reedijk }; 594