xref: /haiku/src/add-ons/kernel/bus_managers/usb/usb.cpp (revision 6eba063647cc4ff5aa863e1b5dc5093c22a3acb0)
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 
14f14fe767SMichael Lotz #define USB_MODULE_NAME "module"
1596da8285SMichael Lotz 
16b8c6a851SMichael Lotz Stack *gUSBStack = NULL;
17b8c6a851SMichael Lotz 
18b8c6a851SMichael Lotz 
19*6eba0636SMichael Lotz static int
20*6eba0636SMichael Lotz debug_get_pipe_for_id(int argc, char **argv)
21*6eba0636SMichael Lotz {
22*6eba0636SMichael Lotz 	if (gUSBStack == NULL)
23*6eba0636SMichael Lotz 		return 1;
24*6eba0636SMichael Lotz 
25*6eba0636SMichael Lotz 	if (!is_debug_variable_defined("_usbPipeID"))
26*6eba0636SMichael Lotz 		return 2;
27*6eba0636SMichael Lotz 
28*6eba0636SMichael Lotz 	uint64 id = get_debug_variable("_usbPipeID", 0);
29*6eba0636SMichael Lotz 	Object *object = gUSBStack->GetObjectNoLock((usb_id)id);
30*6eba0636SMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_PIPE) == 0)
31*6eba0636SMichael Lotz 		return 3;
32*6eba0636SMichael Lotz 
33*6eba0636SMichael Lotz 	set_debug_variable("_usbPipe", (uint64)object);
34*6eba0636SMichael Lotz 	return 0;
35*6eba0636SMichael Lotz }
36*6eba0636SMichael Lotz 
37*6eba0636SMichael Lotz 
381501c2bfSNiels Sascha Reedijk static int32
391501c2bfSNiels Sascha Reedijk bus_std_ops(int32 op, ...)
401501c2bfSNiels Sascha Reedijk {
411501c2bfSNiels Sascha Reedijk 	switch (op) {
4296da8285SMichael Lotz 		case B_MODULE_INIT: {
43f14fe767SMichael Lotz 			TRACE_MODULE("init\n");
445b0ec61fSMichael Lotz 			if (gUSBStack)
455b0ec61fSMichael Lotz 				return B_OK;
465b0ec61fSMichael Lotz 
4748ab20faSMichael Lotz #ifndef __HAIKU__
4848ab20faSMichael Lotz 			// This code is to handle plain R5 (non-BONE) where the same module
4948ab20faSMichael Lotz 			// gets loaded multiple times (once for each exported module
5048ab20faSMichael Lotz 			// interface, the USB v2 and v3 API in our case). We don't want to
5148ab20faSMichael Lotz 			// ever create multiple stacks however, so we "share" the same stack
5248ab20faSMichael Lotz 			// for both modules by storing it's address in a shared area.
53a94a8358SMichael Lotz 			void *address = NULL;
54a94a8358SMichael Lotz 			area_id shared = find_area("shared usb stack");
55a94a8358SMichael Lotz 			if (shared >= B_OK && clone_area("usb stack clone", &address,
56a94a8358SMichael Lotz 				B_ANY_KERNEL_ADDRESS, B_KERNEL_READ_AREA, shared) >= B_OK) {
57a94a8358SMichael Lotz 				gUSBStack = *((Stack **)address);
58f14fe767SMichael Lotz 				TRACE_MODULE("found shared stack at %p\n", gUSBStack);
59a94a8358SMichael Lotz 				return B_OK;
60a94a8358SMichael Lotz 			}
6148ab20faSMichael Lotz #endif
62a94a8358SMichael Lotz 
6396da8285SMichael Lotz #ifdef TRACE_USB
641a2e81b5SNiels Sascha Reedijk 			set_dprintf_enabled(true);
65facc0035SFrançois Revol #ifndef __HAIKU__
661a2e81b5SNiels Sascha Reedijk 			load_driver_symbols("usb");
67facc0035SFrançois Revol #endif
6802ce23a1SMichael Lotz #endif
69b8c6a851SMichael Lotz 			Stack *stack = new(std::nothrow) Stack();
70f14fe767SMichael Lotz 			TRACE_MODULE("usb_module: stack created %p\n", stack);
71b8c6a851SMichael Lotz 			if (!stack)
72b8c6a851SMichael Lotz 				return B_NO_MEMORY;
73b8c6a851SMichael Lotz 
7496da8285SMichael Lotz 			if (stack->InitCheck() != B_OK) {
751a2e81b5SNiels Sascha Reedijk 				delete stack;
761501c2bfSNiels Sascha Reedijk 				return ENODEV;
771501c2bfSNiels Sascha Reedijk 			}
7896da8285SMichael Lotz 
79eb6a1cbcSMichael Lotz 			gUSBStack = stack;
80*6eba0636SMichael Lotz 			add_debugger_command("get_usb_pipe_for_id",
81*6eba0636SMichael Lotz 				&debug_get_pipe_for_id,
82*6eba0636SMichael Lotz 				"Gets the config for a USB pipe");
8348ab20faSMichael Lotz #ifndef __HAIKU__
8448ab20faSMichael Lotz 			// Plain R5 workaround, see comment above.
85a94a8358SMichael Lotz 			shared = create_area("shared usb stack", &address,
86a94a8358SMichael Lotz 				B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_NO_LOCK,
87a94a8358SMichael Lotz 				B_KERNEL_WRITE_AREA);
8848ab20faSMichael Lotz 			if (shared >= B_OK)
89a94a8358SMichael Lotz 				*((Stack **)address) = gUSBStack;
9048ab20faSMichael Lotz #endif
911501c2bfSNiels Sascha Reedijk 			break;
9296da8285SMichael Lotz 		}
9396da8285SMichael Lotz 
941501c2bfSNiels Sascha Reedijk 		case B_MODULE_UNINIT:
95f14fe767SMichael Lotz 			TRACE_MODULE("uninit\n");
96b8c6a851SMichael Lotz 			delete gUSBStack;
97b8c6a851SMichael Lotz 			gUSBStack = NULL;
98*6eba0636SMichael Lotz 			remove_debugger_command("get_usb_pipe_for_id",
99*6eba0636SMichael Lotz 				&debug_get_pipe_for_id);
1001501c2bfSNiels Sascha Reedijk 			break;
10196da8285SMichael Lotz 
1021501c2bfSNiels Sascha Reedijk 		default:
1031501c2bfSNiels Sascha Reedijk 			return EINVAL;
1041501c2bfSNiels Sascha Reedijk 	}
10596da8285SMichael Lotz 
1061501c2bfSNiels Sascha Reedijk 	return B_OK;
1071501c2bfSNiels Sascha Reedijk }
1081501c2bfSNiels Sascha Reedijk 
1091501c2bfSNiels Sascha Reedijk 
110b8c6a851SMichael Lotz status_t
111b8c6a851SMichael Lotz register_driver(const char *driverName,
112b8c6a851SMichael Lotz 	const usb_support_descriptor *descriptors,
113b8c6a851SMichael Lotz 	size_t count, const char *optionalRepublishDriverName)
114b8c6a851SMichael Lotz {
115b8c6a851SMichael Lotz 	return gUSBStack->RegisterDriver(driverName, descriptors, count,
116b8c6a851SMichael Lotz 		optionalRepublishDriverName);
117b8c6a851SMichael Lotz }
118b8c6a851SMichael Lotz 
119b8c6a851SMichael Lotz 
120b8c6a851SMichael Lotz status_t
121b8c6a851SMichael Lotz install_notify(const char *driverName, const usb_notify_hooks *hooks)
122b8c6a851SMichael Lotz {
123b8c6a851SMichael Lotz 	return gUSBStack->InstallNotify(driverName, hooks);
124b8c6a851SMichael Lotz }
125b8c6a851SMichael Lotz 
126b8c6a851SMichael Lotz 
127b8c6a851SMichael Lotz status_t
128b8c6a851SMichael Lotz uninstall_notify(const char *driverName)
129b8c6a851SMichael Lotz {
130b8c6a851SMichael Lotz 	return gUSBStack->UninstallNotify(driverName);
131b8c6a851SMichael Lotz }
132b8c6a851SMichael Lotz 
133b8c6a851SMichael Lotz 
134b8c6a851SMichael Lotz const usb_device_descriptor *
1355b0ec61fSMichael Lotz get_device_descriptor(usb_device device)
136b8c6a851SMichael Lotz {
137f14fe767SMichael Lotz 	TRACE_MODULE("get_device_descriptor(%ld)\n", device);
1385b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
1395b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
140b8c6a851SMichael Lotz 		return NULL;
141b8c6a851SMichael Lotz 
1425b0ec61fSMichael Lotz 	return ((Device *)object)->DeviceDescriptor();
143b8c6a851SMichael Lotz }
144b8c6a851SMichael Lotz 
145b8c6a851SMichael Lotz 
146b8c6a851SMichael Lotz const usb_configuration_info *
1477e1490e0SMichael Lotz get_nth_configuration(usb_device device, uint32 index)
148b8c6a851SMichael Lotz {
149f14fe767SMichael Lotz 	TRACE_MODULE("get_nth_configuration(%ld, %lu)\n", device, index);
1505b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
1515b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
152b8c6a851SMichael Lotz 		return NULL;
153b8c6a851SMichael Lotz 
1545b0ec61fSMichael Lotz 	return ((Device *)object)->ConfigurationAt((int32)index);
155b8c6a851SMichael Lotz }
156b8c6a851SMichael Lotz 
157b8c6a851SMichael Lotz 
158b8c6a851SMichael Lotz const usb_configuration_info *
1595b0ec61fSMichael Lotz get_configuration(usb_device device)
160b8c6a851SMichael Lotz {
161f14fe767SMichael Lotz 	TRACE_MODULE("get_configuration(%ld)\n", device);
1625b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
1635b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
164b8c6a851SMichael Lotz 		return NULL;
165b8c6a851SMichael Lotz 
1665b0ec61fSMichael Lotz 	return ((Device *)object)->Configuration();
167b8c6a851SMichael Lotz }
168b8c6a851SMichael Lotz 
169b8c6a851SMichael Lotz 
170b8c6a851SMichael Lotz status_t
1715b0ec61fSMichael Lotz set_configuration(usb_device device,
172b8c6a851SMichael Lotz 	const usb_configuration_info *configuration)
173b8c6a851SMichael Lotz {
174f14fe767SMichael Lotz 	TRACE_MODULE("set_configuration(%ld, %p)\n", device, configuration);
1755b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
1765b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
17717f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
178b8c6a851SMichael Lotz 
1795b0ec61fSMichael Lotz 	return ((Device *)object)->SetConfiguration(configuration);
180b8c6a851SMichael Lotz }
181b8c6a851SMichael Lotz 
182b8c6a851SMichael Lotz 
183b8c6a851SMichael Lotz status_t
1845b0ec61fSMichael Lotz set_alt_interface(usb_device device, const usb_interface_info *interface)
185b8c6a851SMichael Lotz {
186f14fe767SMichael Lotz 	TRACE_MODULE("set_alt_interface(%ld, %p)\n", device, interface);
1875b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
1885b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
18917f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
1905b0ec61fSMichael Lotz 
19130cb1cfbSSalvatore Benedetto 	return ((Device *)object)->SetAltInterface(interface);
192b8c6a851SMichael Lotz }
193b8c6a851SMichael Lotz 
194b8c6a851SMichael Lotz 
195b8c6a851SMichael Lotz status_t
1965b0ec61fSMichael Lotz set_feature(usb_id handle, uint16 selector)
197b8c6a851SMichael Lotz {
198f14fe767SMichael Lotz 	TRACE_MODULE("set_feature(%ld, %d)\n", handle, selector);
1995b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(handle);
2008fedfdfcSMichael Lotz 	if (!object)
20117f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
202b8c6a851SMichael Lotz 
2038fedfdfcSMichael Lotz 	return object->SetFeature(selector);
204b8c6a851SMichael Lotz }
205b8c6a851SMichael Lotz 
206b8c6a851SMichael Lotz 
207b8c6a851SMichael Lotz status_t
2085b0ec61fSMichael Lotz clear_feature(usb_id handle, uint16 selector)
209b8c6a851SMichael Lotz {
210f14fe767SMichael Lotz 	TRACE_MODULE("clear_feature(%ld, %d)\n", handle, selector);
2115b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(handle);
2128fedfdfcSMichael Lotz 	if (!object)
21317f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
214b8c6a851SMichael Lotz 
2158fedfdfcSMichael Lotz 	return object->ClearFeature(selector);
216b8c6a851SMichael Lotz }
217b8c6a851SMichael Lotz 
218b8c6a851SMichael Lotz 
219b8c6a851SMichael Lotz status_t
2205b0ec61fSMichael Lotz get_status(usb_id handle, uint16 *status)
221b8c6a851SMichael Lotz {
222f14fe767SMichael Lotz 	TRACE_MODULE("get_status(%ld, %p)\n", handle, status);
2235b0ec61fSMichael Lotz 	if (!status)
2245b0ec61fSMichael Lotz 		return B_BAD_VALUE;
2255b0ec61fSMichael Lotz 
2265b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(handle);
2278fedfdfcSMichael Lotz 	if (!object)
22817f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
229b8c6a851SMichael Lotz 
2308fedfdfcSMichael Lotz 	return object->GetStatus(status);
231b8c6a851SMichael Lotz }
232b8c6a851SMichael Lotz 
233b8c6a851SMichael Lotz 
234b8c6a851SMichael Lotz status_t
2355b0ec61fSMichael Lotz get_descriptor(usb_device device, uint8 type, uint8 index, uint16 languageID,
2365b0ec61fSMichael Lotz 	void *data, size_t dataLength, size_t *actualLength)
237b8c6a851SMichael Lotz {
238f14fe767SMichael Lotz 	TRACE_MODULE("get_descriptor(%ld, 0x%02x, 0x%02x, 0x%04x, %p, %ld, %p)\n",
239f14fe767SMichael Lotz 		device, type, index, languageID, data, dataLength, actualLength);
2405b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
2415b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
24217f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
243b8c6a851SMichael Lotz 
2445b0ec61fSMichael Lotz 	return ((Device *)object)->GetDescriptor(type, index, languageID,
245b8c6a851SMichael Lotz 		data, dataLength, actualLength);
246b8c6a851SMichael Lotz }
247b8c6a851SMichael Lotz 
248b8c6a851SMichael Lotz 
249b8c6a851SMichael Lotz status_t
2505b0ec61fSMichael Lotz send_request(usb_device device, uint8 requestType, uint8 request,
2515b0ec61fSMichael Lotz 	uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength)
252b8c6a851SMichael Lotz {
253f14fe767SMichael Lotz 	TRACE_MODULE("send_request(%ld, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %d, %p, %p)\n",
254f14fe767SMichael Lotz 		device, requestType, request, value, index, length, data, actualLength);
2555b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
2565b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
25717f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
258b8c6a851SMichael Lotz 
2598fedfdfcSMichael Lotz 	return ((Device *)object)->DefaultPipe()->SendRequest(requestType, request,
2608fedfdfcSMichael Lotz 		value, index, length, data, length, actualLength);
261b8c6a851SMichael Lotz }
262b8c6a851SMichael Lotz 
263b8c6a851SMichael Lotz 
264b8c6a851SMichael Lotz status_t
2655b0ec61fSMichael Lotz queue_request(usb_device device, uint8 requestType, uint8 request,
2665b0ec61fSMichael Lotz 	uint16 value, uint16 index, uint16 length, void *data,
267b8c6a851SMichael Lotz 	usb_callback_func callback, void *callbackCookie)
268b8c6a851SMichael Lotz {
269f14fe767SMichael Lotz 	TRACE_MODULE("queue_request(%ld, 0x%02x, 0x%02x, 0x%04x, 0x%04x, %u, %p, %p, %p)\n",
270f14fe767SMichael Lotz 		device, requestType, request, value, index, length, data, callback,
271f14fe767SMichael Lotz 		callbackCookie);
2725b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
2735b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
27417f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
275b8c6a851SMichael Lotz 
2768fedfdfcSMichael Lotz 	return ((Device *)object)->DefaultPipe()->QueueRequest(requestType,
2778fedfdfcSMichael Lotz 		request, value, index, length, data, length, callback, callbackCookie);
278b8c6a851SMichael Lotz }
279b8c6a851SMichael Lotz 
280b8c6a851SMichael Lotz 
281b8c6a851SMichael Lotz status_t
2825b0ec61fSMichael Lotz queue_interrupt(usb_pipe pipe, void *data, size_t dataLength,
283b8c6a851SMichael Lotz 	usb_callback_func callback, void *callbackCookie)
284b8c6a851SMichael Lotz {
285f14fe767SMichael Lotz 	TRACE_MODULE("queue_interrupt(%ld, %p, %ld, %p, %p)\n",
286f14fe767SMichael Lotz 		pipe, data, dataLength, callback, callbackCookie);
2875b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(pipe);
2885b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0)
28917f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
290b8c6a851SMichael Lotz 
2915b0ec61fSMichael Lotz 	return ((InterruptPipe *)object)->QueueInterrupt(data, dataLength, callback,
292b8c6a851SMichael Lotz 		callbackCookie);
293b8c6a851SMichael Lotz }
294b8c6a851SMichael Lotz 
295b8c6a851SMichael Lotz 
296b8c6a851SMichael Lotz status_t
2975b0ec61fSMichael Lotz queue_bulk(usb_pipe pipe, void *data, size_t dataLength,
298b8c6a851SMichael Lotz 	usb_callback_func callback, void *callbackCookie)
299b8c6a851SMichael Lotz {
300f14fe767SMichael Lotz 	TRACE_MODULE("queue_bulk(%ld, %p, %ld, %p, %p)\n",
301f14fe767SMichael Lotz 		pipe, data, dataLength, callback, callbackCookie);
3025b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(pipe);
3035b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0)
30417f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
305b8c6a851SMichael Lotz 
3065b0ec61fSMichael Lotz 	return ((BulkPipe *)object)->QueueBulk(data, dataLength, callback,
307b8c6a851SMichael Lotz 		callbackCookie);
308b8c6a851SMichael Lotz }
309b8c6a851SMichael Lotz 
310b8c6a851SMichael Lotz 
311b8c6a851SMichael Lotz status_t
3125b0ec61fSMichael Lotz queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount,
3135b0ec61fSMichael Lotz 	usb_callback_func callback, void *callbackCookie)
314b8c6a851SMichael Lotz {
315f14fe767SMichael Lotz 	TRACE_MODULE("queue_bulk(%ld, %p, %ld, %p, %p)\n",
316f14fe767SMichael Lotz 		pipe, vector, vectorCount, callback, callbackCookie);
3175b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(pipe);
3185b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0)
31917f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
320b8c6a851SMichael Lotz 
3211e8c0b36SMichael Lotz 	return ((BulkPipe *)object)->QueueBulkV(vector, vectorCount, callback,
3221e8c0b36SMichael Lotz 		callbackCookie);
323b8c6a851SMichael Lotz }
324b8c6a851SMichael Lotz 
325b8c6a851SMichael Lotz 
326b8c6a851SMichael Lotz status_t
3275b0ec61fSMichael Lotz queue_isochronous(usb_pipe pipe, void *data, size_t dataLength,
3281bad4a4eSMichael Lotz 	usb_iso_packet_descriptor *packetDesc, uint32 packetCount,
3291bad4a4eSMichael Lotz 	uint32 *startingFrameNumber, uint32 flags, usb_callback_func callback,
3305b0ec61fSMichael Lotz 	void *callbackCookie)
3315b0ec61fSMichael Lotz {
332f14fe767SMichael Lotz 	TRACE_MODULE("queue_isochronous(%ld, %p, %ld, %p, %ld, %p, 0x%08lx, %p, %p)\n",
333f14fe767SMichael Lotz 		pipe, data, dataLength, packetDesc, packetCount, startingFrameNumber,
334f14fe767SMichael Lotz 		flags, callback, callbackCookie);
3355b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(pipe);
3365b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0)
33717f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
3385b0ec61fSMichael Lotz 
3395b0ec61fSMichael Lotz 	return ((IsochronousPipe *)object)->QueueIsochronous(data, dataLength,
3401bad4a4eSMichael Lotz 		packetDesc, packetCount, startingFrameNumber, flags, callback,
3411bad4a4eSMichael Lotz 		callbackCookie);
3425b0ec61fSMichael Lotz }
3435b0ec61fSMichael Lotz 
3445b0ec61fSMichael Lotz 
3455b0ec61fSMichael Lotz status_t
3465b0ec61fSMichael Lotz set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets,
3475b0ec61fSMichael Lotz 	uint16 maxBufferDurationMS, uint16 sampleSize)
3485b0ec61fSMichael Lotz {
349f14fe767SMichael Lotz 	TRACE_MODULE("set_pipe_policy(%ld, %d, %d, %d)\n", pipe, maxQueuedPackets,
350f14fe767SMichael Lotz 		maxBufferDurationMS, sampleSize);
3515b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(pipe);
3525b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0)
35317f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
3545b0ec61fSMichael Lotz 
35500f6fab9SMichael Lotz 	return ((IsochronousPipe *)object)->SetPipePolicy(maxQueuedPackets,
35600f6fab9SMichael Lotz 		maxBufferDurationMS, sampleSize);
3575b0ec61fSMichael Lotz }
3585b0ec61fSMichael Lotz 
3595b0ec61fSMichael Lotz 
3605b0ec61fSMichael Lotz status_t
3615b0ec61fSMichael Lotz cancel_queued_transfers(usb_pipe pipe)
362b8c6a851SMichael Lotz {
363f14fe767SMichael Lotz 	TRACE_MODULE("cancel_queued_transfers(%ld)\n", pipe);
3645b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(pipe);
3655b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_PIPE) == 0)
36617f83b21SMichael Lotz 		return B_DEV_INVALID_PIPE;
3675b0ec61fSMichael Lotz 
36813508e8bSMichael Lotz 	return ((Pipe *)object)->CancelQueuedTransfers(false);
369b8c6a851SMichael Lotz }
370b8c6a851SMichael Lotz 
371b8c6a851SMichael Lotz 
372b8c6a851SMichael Lotz status_t
373b8c6a851SMichael Lotz usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize)
374b8c6a851SMichael Lotz {
375f14fe767SMichael Lotz 	TRACE_MODULE("usb_ioctl(%lu, %p, %ld)\n", opcode, buffer, bufferSize);
37664f3c065SMichael Lotz 
37764f3c065SMichael Lotz 	switch (opcode) {
37864f3c065SMichael Lotz 		case 'DNAM': {
3795b0ec61fSMichael Lotz 			Object *object = gUSBStack->GetObject(*(usb_id *)buffer);
3805b0ec61fSMichael Lotz 			if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
3815b0ec61fSMichael Lotz 				return B_BAD_VALUE;
3825b0ec61fSMichael Lotz 
38364f3c065SMichael Lotz 			uint32 index = 0;
3845b0ec61fSMichael Lotz 			return ((Device *)object)->BuildDeviceName((char *)buffer, &index,
3855b0ec61fSMichael Lotz 				bufferSize, NULL);
38664f3c065SMichael Lotz 		}
38764f3c065SMichael Lotz 	}
38864f3c065SMichael Lotz 
38964f3c065SMichael Lotz 	return B_DEV_INVALID_IOCTL;
390b8c6a851SMichael Lotz }
391b8c6a851SMichael Lotz 
392b8c6a851SMichael Lotz 
3937e1490e0SMichael Lotz status_t
3947e1490e0SMichael Lotz get_nth_roothub(uint32 index, usb_device *rootHub)
3957e1490e0SMichael Lotz {
3967e1490e0SMichael Lotz 	if (!rootHub)
3977e1490e0SMichael Lotz 		return B_BAD_VALUE;
3987e1490e0SMichael Lotz 
3997e1490e0SMichael Lotz 	BusManager *busManager = gUSBStack->BusManagerAt(index);
4007e1490e0SMichael Lotz 	if (!busManager)
4017e1490e0SMichael Lotz 		return B_ENTRY_NOT_FOUND;
4027e1490e0SMichael Lotz 
4037e1490e0SMichael Lotz 	Hub *hub = busManager->GetRootHub();
4047e1490e0SMichael Lotz 	if (!hub)
4057e1490e0SMichael Lotz 		return B_NO_INIT;
4067e1490e0SMichael Lotz 
4077e1490e0SMichael Lotz 	*rootHub = hub->USBID();
4087e1490e0SMichael Lotz 	return B_OK;
4097e1490e0SMichael Lotz }
4107e1490e0SMichael Lotz 
4117e1490e0SMichael Lotz 
4127e1490e0SMichael Lotz status_t
4137e1490e0SMichael Lotz get_nth_child(usb_device _hub, uint8 index, usb_device *childDevice)
4147e1490e0SMichael Lotz {
4157e1490e0SMichael Lotz 	if (!childDevice)
4167e1490e0SMichael Lotz 		return B_BAD_VALUE;
4177e1490e0SMichael Lotz 
4187e1490e0SMichael Lotz 	Object *object = gUSBStack->GetObject(_hub);
4197e1490e0SMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_HUB) == 0)
4207e1490e0SMichael Lotz 		return B_DEV_INVALID_PIPE;
4217e1490e0SMichael Lotz 
4227e1490e0SMichael Lotz 	Hub *hub = (Hub *)object;
4237e1490e0SMichael Lotz 	for (uint8 i = 0; i < 8; i++) {
4247e1490e0SMichael Lotz 		if (hub->ChildAt(i) == NULL)
4257e1490e0SMichael Lotz 			continue;
4267e1490e0SMichael Lotz 
4277e1490e0SMichael Lotz 		if (index-- > 0)
4287e1490e0SMichael Lotz 			continue;
4297e1490e0SMichael Lotz 
4307e1490e0SMichael Lotz 		*childDevice = hub->ChildAt(i)->USBID();
4317e1490e0SMichael Lotz 		return B_OK;
4327e1490e0SMichael Lotz 	}
4337e1490e0SMichael Lotz 
4347e1490e0SMichael Lotz 	return B_ENTRY_NOT_FOUND;
4357e1490e0SMichael Lotz }
4367e1490e0SMichael Lotz 
4377e1490e0SMichael Lotz 
4387e1490e0SMichael Lotz status_t
4397e1490e0SMichael Lotz get_device_parent(usb_device _device, usb_device *parentHub, uint8 *portIndex)
4407e1490e0SMichael Lotz {
4417e1490e0SMichael Lotz 	if (!parentHub || !portIndex)
4427e1490e0SMichael Lotz 		return B_BAD_VALUE;
4437e1490e0SMichael Lotz 
4447e1490e0SMichael Lotz 	Object *object = gUSBStack->GetObject(_device);
4457e1490e0SMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
4467e1490e0SMichael Lotz 		return B_DEV_INVALID_PIPE;
4477e1490e0SMichael Lotz 
4487e1490e0SMichael Lotz 	Object *parent = object->Parent();
4497e1490e0SMichael Lotz 	if (!parent || (parent->Type() & USB_OBJECT_HUB) == 0)
4507e1490e0SMichael Lotz 		return B_ENTRY_NOT_FOUND;
4517e1490e0SMichael Lotz 
4527e1490e0SMichael Lotz 	Hub *hub = (Hub *)parent;
4537e1490e0SMichael Lotz 	for (uint8 i = 0; i < 8; i++) {
4547e1490e0SMichael Lotz 		if (hub->ChildAt(i) == object) {
4557e1490e0SMichael Lotz 			*portIndex = i;
4567e1490e0SMichael Lotz 			*parentHub = hub->USBID();
4577e1490e0SMichael Lotz 			return B_OK;
4587e1490e0SMichael Lotz 		}
4597e1490e0SMichael Lotz 	}
4607e1490e0SMichael Lotz 
4617e1490e0SMichael Lotz 	return B_ERROR;
4627e1490e0SMichael Lotz }
4637e1490e0SMichael Lotz 
4647e1490e0SMichael Lotz 
4657e1490e0SMichael Lotz status_t
4667e1490e0SMichael Lotz reset_port(usb_device _hub, uint8 portIndex)
4677e1490e0SMichael Lotz {
4687e1490e0SMichael Lotz 	Object *object = gUSBStack->GetObject(_hub);
4697e1490e0SMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_HUB) == 0)
4707e1490e0SMichael Lotz 		return B_DEV_INVALID_PIPE;
4717e1490e0SMichael Lotz 
4727e1490e0SMichael Lotz 	Hub *hub = (Hub *)object;
4737e1490e0SMichael Lotz 	return hub->ResetPort(portIndex);
4747e1490e0SMichael Lotz }
4757e1490e0SMichael Lotz 
4767e1490e0SMichael Lotz 
4777e1490e0SMichael Lotz status_t
4787e1490e0SMichael Lotz disable_port(usb_device _hub, uint8 portIndex)
4797e1490e0SMichael Lotz {
4807e1490e0SMichael Lotz 	Object *object = gUSBStack->GetObject(_hub);
4817e1490e0SMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_HUB) == 0)
4827e1490e0SMichael Lotz 		return B_DEV_INVALID_PIPE;
4837e1490e0SMichael Lotz 
4847e1490e0SMichael Lotz 	Hub *hub = (Hub *)object;
4857e1490e0SMichael Lotz 	return hub->DisablePort(portIndex);
4867e1490e0SMichael Lotz }
4877e1490e0SMichael Lotz 
4887e1490e0SMichael Lotz 
48996da8285SMichael Lotz /*
4905b0ec61fSMichael Lotz 	This module exports the USB API v3
49196da8285SMichael Lotz */
4925b0ec61fSMichael Lotz struct usb_module_info gModuleInfoV3 = {
4931501c2bfSNiels Sascha Reedijk 	// First the bus_manager_info:
4941501c2bfSNiels Sascha Reedijk 	{
4951501c2bfSNiels Sascha Reedijk 		{
4965b0ec61fSMichael Lotz 			"bus_managers/usb/v3",
4971501c2bfSNiels Sascha Reedijk 			B_KEEP_LOADED,				// Keep loaded, even if no driver requires it
4981501c2bfSNiels Sascha Reedijk 			bus_std_ops
4991501c2bfSNiels Sascha Reedijk 		},
5001501c2bfSNiels Sascha Reedijk 		NULL							// the rescan function
5011501c2bfSNiels Sascha Reedijk 	},
50296da8285SMichael Lotz 
503b8c6a851SMichael Lotz 	register_driver,					// register_driver
504b8c6a851SMichael Lotz 	install_notify,						// install_notify
505b8c6a851SMichael Lotz 	uninstall_notify,					// uninstall_notify
506b8c6a851SMichael Lotz 	get_device_descriptor,				// get_device_descriptor
507b8c6a851SMichael Lotz 	get_nth_configuration,				// get_nth_configuration
508b8c6a851SMichael Lotz 	get_configuration,					// get_configuration
509b8c6a851SMichael Lotz 	set_configuration,					// set_configuration
510b8c6a851SMichael Lotz 	set_alt_interface,					// set_alt_interface
511b8c6a851SMichael Lotz 	set_feature,						// set_feature
512b8c6a851SMichael Lotz 	clear_feature, 						// clear_feature
513b8c6a851SMichael Lotz 	get_status, 						// get_status
514b8c6a851SMichael Lotz 	get_descriptor,						// get_descriptor
515b8c6a851SMichael Lotz 	send_request,						// send_request
516b8c6a851SMichael Lotz 	queue_interrupt,					// queue_interrupt
517b8c6a851SMichael Lotz 	queue_bulk,							// queue_bulk
5185b0ec61fSMichael Lotz 	queue_bulk_v,						// queue_bulk_v
519b8c6a851SMichael Lotz 	queue_isochronous,					// queue_isochronous
520b8c6a851SMichael Lotz 	queue_request,						// queue_request
521b8c6a851SMichael Lotz 	set_pipe_policy,					// set_pipe_policy
522b8c6a851SMichael Lotz 	cancel_queued_transfers,			// cancel_queued_transfers
5237e1490e0SMichael Lotz 	usb_ioctl,							// usb_ioctl
5247e1490e0SMichael Lotz 	get_nth_roothub,					// get_nth_roothub
5257e1490e0SMichael Lotz 	get_nth_child,						// get_nth_child
5267e1490e0SMichael Lotz 	get_device_parent,					// get_device_parent
5277e1490e0SMichael Lotz 	reset_port,							// reset_port
5287e1490e0SMichael Lotz 	disable_port						// disable_port
5291501c2bfSNiels Sascha Reedijk };
5301501c2bfSNiels Sascha Reedijk 
53196da8285SMichael Lotz 
5325b0ec61fSMichael Lotz //
5335b0ec61fSMichael Lotz // #pragma mark -
5345b0ec61fSMichael Lotz //
5355b0ec61fSMichael Lotz 
5365b0ec61fSMichael Lotz 
5375b0ec61fSMichael Lotz const usb_device_descriptor *
5385b0ec61fSMichael Lotz get_device_descriptor_v2(const void *device)
5395b0ec61fSMichael Lotz {
5405b0ec61fSMichael Lotz 	return get_device_descriptor((usb_id)device);
5415b0ec61fSMichael Lotz }
5425b0ec61fSMichael Lotz 
5435b0ec61fSMichael Lotz 
5445b0ec61fSMichael Lotz const usb_configuration_info *
5455b0ec61fSMichael Lotz get_nth_configuration_v2(const void *device, uint index)
5465b0ec61fSMichael Lotz {
5475b0ec61fSMichael Lotz 	return get_nth_configuration((usb_id)device, index);
5485b0ec61fSMichael Lotz }
5495b0ec61fSMichael Lotz 
5505b0ec61fSMichael Lotz 
5515b0ec61fSMichael Lotz const usb_configuration_info *
5525b0ec61fSMichael Lotz get_configuration_v2(const void *device)
5535b0ec61fSMichael Lotz {
5545b0ec61fSMichael Lotz 	return get_configuration((usb_id)device);
5555b0ec61fSMichael Lotz }
5565b0ec61fSMichael Lotz 
5575b0ec61fSMichael Lotz 
5585b0ec61fSMichael Lotz status_t
5595b0ec61fSMichael Lotz set_configuration_v2(const void *device,
5605b0ec61fSMichael Lotz 	const usb_configuration_info *configuration)
5615b0ec61fSMichael Lotz {
5625b0ec61fSMichael Lotz 	return set_configuration((usb_id)device, configuration);
5635b0ec61fSMichael Lotz }
5645b0ec61fSMichael Lotz 
5655b0ec61fSMichael Lotz 
5665b0ec61fSMichael Lotz status_t
5675b0ec61fSMichael Lotz set_alt_interface_v2(const void *device, const usb_interface_info *interface)
5685b0ec61fSMichael Lotz {
5695b0ec61fSMichael Lotz 	return set_alt_interface((usb_id)device, interface);
5705b0ec61fSMichael Lotz }
5715b0ec61fSMichael Lotz 
5725b0ec61fSMichael Lotz 
5735b0ec61fSMichael Lotz status_t
5745b0ec61fSMichael Lotz set_feature_v2(const void *object, uint16 selector)
5755b0ec61fSMichael Lotz {
5765b0ec61fSMichael Lotz 	return set_feature((usb_id)object, selector);
5775b0ec61fSMichael Lotz }
5785b0ec61fSMichael Lotz 
5795b0ec61fSMichael Lotz 
5805b0ec61fSMichael Lotz status_t
5815b0ec61fSMichael Lotz clear_feature_v2(const void *object, uint16 selector)
5825b0ec61fSMichael Lotz {
5835b0ec61fSMichael Lotz 	return clear_feature((usb_id)object, selector);
5845b0ec61fSMichael Lotz }
5855b0ec61fSMichael Lotz 
5865b0ec61fSMichael Lotz 
5875b0ec61fSMichael Lotz status_t
5885b0ec61fSMichael Lotz get_status_v2(const void *object, uint16 *status)
5895b0ec61fSMichael Lotz {
5905b0ec61fSMichael Lotz 	return get_status((usb_id)object, status);
5915b0ec61fSMichael Lotz }
5925b0ec61fSMichael Lotz 
5935b0ec61fSMichael Lotz 
5945b0ec61fSMichael Lotz status_t
5955b0ec61fSMichael Lotz get_descriptor_v2(const void *device, uint8 type, uint8 index,
5965b0ec61fSMichael Lotz 	uint16 languageID, void *data, size_t dataLength, size_t *actualLength)
5975b0ec61fSMichael Lotz {
5985b0ec61fSMichael Lotz 	return get_descriptor((usb_id)device, type, index, languageID, data,
5995b0ec61fSMichael Lotz 		dataLength, actualLength);
6005b0ec61fSMichael Lotz }
6015b0ec61fSMichael Lotz 
6025b0ec61fSMichael Lotz 
6035b0ec61fSMichael Lotz status_t
6045b0ec61fSMichael Lotz send_request_v2(const void *device, uint8 requestType, uint8 request,
6055b0ec61fSMichael Lotz 	uint16 value, uint16 index, uint16 length, void *data,
6065b0ec61fSMichael Lotz 	size_t /*dataLength*/, size_t *actualLength)
6075b0ec61fSMichael Lotz {
6085b0ec61fSMichael Lotz 	return send_request((usb_id)device, requestType, request, value, index,
6095b0ec61fSMichael Lotz 		length, data, actualLength);
6105b0ec61fSMichael Lotz }
6115b0ec61fSMichael Lotz 
6125b0ec61fSMichael Lotz 
6135b0ec61fSMichael Lotz status_t
6145b0ec61fSMichael Lotz queue_request_v2(const void *device, uint8 requestType, uint8 request,
6155b0ec61fSMichael Lotz 	uint16 value, uint16 index, uint16 length, void *data,
6165b0ec61fSMichael Lotz 	size_t /*dataLength*/, usb_callback_func callback, void *callbackCookie)
6175b0ec61fSMichael Lotz {
6185b0ec61fSMichael Lotz 	return queue_request((usb_id)device, requestType, request, value, index,
6195b0ec61fSMichael Lotz 		length, data, callback, callbackCookie);
6205b0ec61fSMichael Lotz }
6215b0ec61fSMichael Lotz 
6225b0ec61fSMichael Lotz 
6235b0ec61fSMichael Lotz status_t
6245b0ec61fSMichael Lotz queue_interrupt_v2(const void *pipe, void *data, size_t dataLength,
6255b0ec61fSMichael Lotz 	usb_callback_func callback, void *callbackCookie)
6265b0ec61fSMichael Lotz {
6275b0ec61fSMichael Lotz 	return queue_interrupt((usb_id)pipe, data, dataLength, callback,
6285b0ec61fSMichael Lotz 		callbackCookie);
6295b0ec61fSMichael Lotz }
6305b0ec61fSMichael Lotz 
6315b0ec61fSMichael Lotz 
6325b0ec61fSMichael Lotz status_t
6335b0ec61fSMichael Lotz queue_bulk_v2(const void *pipe, void *data, size_t dataLength,
6345b0ec61fSMichael Lotz 	usb_callback_func callback, void *callbackCookie)
6355b0ec61fSMichael Lotz {
6365b0ec61fSMichael Lotz 	return queue_bulk((usb_id)pipe, data, dataLength, callback,
6375b0ec61fSMichael Lotz 		callbackCookie);
6385b0ec61fSMichael Lotz }
6395b0ec61fSMichael Lotz 
6405b0ec61fSMichael Lotz 
6415b0ec61fSMichael Lotz status_t
6425b0ec61fSMichael Lotz queue_isochronous_v2(const void *pipe, void *data, size_t dataLength,
6435b0ec61fSMichael Lotz 	rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback,
6445b0ec61fSMichael Lotz 	void *callbackCookie)
6455b0ec61fSMichael Lotz {
6461bad4a4eSMichael Lotz 	// ToDo: convert rlea to usb_iso_packet_descriptor
6471bad4a4eSMichael Lotz 	// ToDo: use a flag to indicate that the callback shall produce a rlea
6481bad4a4eSMichael Lotz 	usb_iso_packet_descriptor *packetDesc = NULL;
6491bad4a4eSMichael Lotz 	return queue_isochronous((usb_id)pipe, data, dataLength, packetDesc, 0,
6501bad4a4eSMichael Lotz 		NULL, 0, callback, callbackCookie);
6515b0ec61fSMichael Lotz }
6525b0ec61fSMichael Lotz 
6535b0ec61fSMichael Lotz 
6545b0ec61fSMichael Lotz status_t
6555b0ec61fSMichael Lotz set_pipe_policy_v2(const void *pipe, uint8 maxQueuedPackets,
6565b0ec61fSMichael Lotz 	uint16 maxBufferDurationMS, uint16 sampleSize)
6575b0ec61fSMichael Lotz {
6585b0ec61fSMichael Lotz 	return set_pipe_policy((usb_id)pipe, maxQueuedPackets, maxBufferDurationMS,
6595b0ec61fSMichael Lotz 		sampleSize);
6605b0ec61fSMichael Lotz }
6615b0ec61fSMichael Lotz 
6625b0ec61fSMichael Lotz 
6635b0ec61fSMichael Lotz status_t
6645b0ec61fSMichael Lotz cancel_queued_transfers_v2(const void *pipe)
6655b0ec61fSMichael Lotz {
6665b0ec61fSMichael Lotz 	return cancel_queued_transfers((usb_id)pipe);
6675b0ec61fSMichael Lotz }
6685b0ec61fSMichael Lotz 
6695b0ec61fSMichael Lotz 
6705b0ec61fSMichael Lotz struct usb_module_info_v2 {
6715b0ec61fSMichael Lotz 	bus_manager_info				binfo;
6725b0ec61fSMichael Lotz 	status_t						(*register_driver)(const char *, const usb_support_descriptor *, size_t, const char *);
6735b0ec61fSMichael Lotz 	status_t						(*install_notify)(const char *, const usb_notify_hooks *);
6745b0ec61fSMichael Lotz 	status_t						(*uninstall_notify)(const char *);
6755b0ec61fSMichael Lotz 	const usb_device_descriptor		*(*get_device_descriptor)(const void *);
6765b0ec61fSMichael Lotz 	const usb_configuration_info	*(*get_nth_configuration)(const void *, uint);
6775b0ec61fSMichael Lotz 	const usb_configuration_info	*(*get_configuration)(const void *);
6785b0ec61fSMichael Lotz 	status_t						(*set_configuration)(const void *, const usb_configuration_info *);
6795b0ec61fSMichael Lotz 	status_t						(*set_alt_interface)(const void *, const usb_interface_info *);
6805b0ec61fSMichael Lotz 	status_t						(*set_feature)(const void *, uint16);
6815b0ec61fSMichael Lotz 	status_t						(*clear_feature)(const void *, uint16);
6825b0ec61fSMichael Lotz 	status_t						(*get_status)(const void *, uint16 *);
6835b0ec61fSMichael Lotz 	status_t						(*get_descriptor)(const void *, uint8, uint8, uint16, void *, size_t, size_t *);
6845b0ec61fSMichael Lotz 	status_t						(*send_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, size_t *);
6855b0ec61fSMichael Lotz 	status_t						(*queue_interrupt)(const void *, void *, size_t, usb_callback_func, void *);
6865b0ec61fSMichael Lotz 	status_t						(*queue_bulk)(const void *, void *, size_t, usb_callback_func, void *);
6875b0ec61fSMichael Lotz 	status_t						(*queue_isochronous)(const void *, void *, size_t, rlea *, uint16, usb_callback_func, void *);
6885b0ec61fSMichael Lotz 	status_t						(*queue_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, usb_callback_func, void *);
6895b0ec61fSMichael Lotz 	status_t						(*set_pipe_policy)(const void *, uint8, uint16, uint16);
6905b0ec61fSMichael Lotz 	status_t						(*cancel_queued_transfers)(const void *);
6915b0ec61fSMichael Lotz 	status_t						(*usb_ioctl)(uint32 opcode, void *,size_t);
6925b0ec61fSMichael Lotz };
6935b0ec61fSMichael Lotz 
6945b0ec61fSMichael Lotz 
6955b0ec61fSMichael Lotz /*
6965b0ec61fSMichael Lotz 	This module exports the USB API v2
6975b0ec61fSMichael Lotz */
6985b0ec61fSMichael Lotz struct usb_module_info_v2 gModuleInfoV2 = {
6995b0ec61fSMichael Lotz 	// First the bus_manager_info:
7005b0ec61fSMichael Lotz 	{
7015b0ec61fSMichael Lotz 		{
7025b0ec61fSMichael Lotz 			"bus_managers/usb/v2",
7035b0ec61fSMichael Lotz 			B_KEEP_LOADED,				// Keep loaded, even if no driver requires it
7045b0ec61fSMichael Lotz 			bus_std_ops
7055b0ec61fSMichael Lotz 		},
7065b0ec61fSMichael Lotz 		NULL							// the rescan function
7075b0ec61fSMichael Lotz 	},
7085b0ec61fSMichael Lotz 
7095b0ec61fSMichael Lotz 	register_driver,					// register_driver
7105b0ec61fSMichael Lotz 	install_notify,						// install_notify
7115b0ec61fSMichael Lotz 	uninstall_notify,					// uninstall_notify
7125b0ec61fSMichael Lotz 	get_device_descriptor_v2,			// get_device_descriptor
7135b0ec61fSMichael Lotz 	get_nth_configuration_v2,			// get_nth_configuration
7145b0ec61fSMichael Lotz 	get_configuration_v2,				// get_configuration
7155b0ec61fSMichael Lotz 	set_configuration_v2,				// set_configuration
7165b0ec61fSMichael Lotz 	set_alt_interface_v2,				// set_alt_interface
7175b0ec61fSMichael Lotz 	set_feature_v2,						// set_feature
7185b0ec61fSMichael Lotz 	clear_feature_v2,					// clear_feature
7195b0ec61fSMichael Lotz 	get_status_v2, 						// get_status
7205b0ec61fSMichael Lotz 	get_descriptor_v2,					// get_descriptor
7215b0ec61fSMichael Lotz 	send_request_v2,					// send_request
7225b0ec61fSMichael Lotz 	queue_interrupt_v2,					// queue_interrupt
7235b0ec61fSMichael Lotz 	queue_bulk_v2,						// queue_bulk
7245b0ec61fSMichael Lotz 	queue_isochronous_v2,				// queue_isochronous
7255b0ec61fSMichael Lotz 	queue_request_v2,					// queue_request
7265b0ec61fSMichael Lotz 	set_pipe_policy_v2,					// set_pipe_policy
7275b0ec61fSMichael Lotz 	cancel_queued_transfers_v2,			// cancel_queued_transfers
7285b0ec61fSMichael Lotz 	usb_ioctl							// usb_ioctl
7295b0ec61fSMichael Lotz };
7305b0ec61fSMichael Lotz 
7315b0ec61fSMichael Lotz 
7325b0ec61fSMichael Lotz //
7335b0ec61fSMichael Lotz // #pragma mark -
7345b0ec61fSMichael Lotz //
7355b0ec61fSMichael Lotz 
7365b0ec61fSMichael Lotz 
7371501c2bfSNiels Sascha Reedijk module_info *modules[] = {
7385b0ec61fSMichael Lotz 	(module_info *)&gModuleInfoV2,
7395b0ec61fSMichael Lotz 	(module_info *)&gModuleInfoV3,
7401501c2bfSNiels Sascha Reedijk 	NULL
7411501c2bfSNiels Sascha Reedijk };
742