xref: /haiku/src/add-ons/kernel/bus_managers/usb/usb.cpp (revision 00f6fab9315c42c68c336f31f6061ba6faa17c27)
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