xref: /haiku/src/add-ons/kernel/bus_managers/usb/usb.cpp (revision 5b0ec61f972bca106675a66c37354e38efb8016d)
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:
6*5b0ec61fSMichael 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"
121501c2bfSNiels Sascha Reedijk 
1396da8285SMichael Lotz 
1496da8285SMichael Lotz #define TRACE_USB
1596da8285SMichael Lotz #ifdef TRACE_USB
1696da8285SMichael Lotz #define TRACE(x)	dprintf x
171501c2bfSNiels Sascha Reedijk #else
1896da8285SMichael Lotz #define TRACE(x)	/* nothing */
191501c2bfSNiels Sascha Reedijk #endif
201501c2bfSNiels Sascha Reedijk 
211501c2bfSNiels Sascha Reedijk 
22b8c6a851SMichael Lotz Stack *gUSBStack = NULL;
23b8c6a851SMichael Lotz 
24b8c6a851SMichael Lotz 
251501c2bfSNiels Sascha Reedijk static int32
261501c2bfSNiels Sascha Reedijk bus_std_ops(int32 op, ...)
271501c2bfSNiels Sascha Reedijk {
281501c2bfSNiels Sascha Reedijk 	switch (op) {
2996da8285SMichael Lotz 		case B_MODULE_INIT: {
30*5b0ec61fSMichael Lotz 			if (gUSBStack)
31*5b0ec61fSMichael Lotz 				return B_OK;
32*5b0ec61fSMichael Lotz 
3396da8285SMichael Lotz #ifdef TRACE_USB
341a2e81b5SNiels Sascha Reedijk 			set_dprintf_enabled(true);
351a2e81b5SNiels Sascha Reedijk 			load_driver_symbols("usb");
361a2e81b5SNiels Sascha Reedijk #endif
37b8c6a851SMichael Lotz 			TRACE(("usb_module: init\n"));
3896da8285SMichael Lotz 
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;
491501c2bfSNiels Sascha Reedijk 			break;
5096da8285SMichael Lotz 		}
5196da8285SMichael Lotz 
521501c2bfSNiels Sascha Reedijk 		case B_MODULE_UNINIT:
53b8c6a851SMichael Lotz 			TRACE(("usb_module: bus module: uninit\n"));
54b8c6a851SMichael Lotz 			delete gUSBStack;
55b8c6a851SMichael Lotz 			gUSBStack = NULL;
561501c2bfSNiels Sascha Reedijk 			break;
5796da8285SMichael Lotz 
581501c2bfSNiels Sascha Reedijk 		default:
591501c2bfSNiels Sascha Reedijk 			return EINVAL;
601501c2bfSNiels Sascha Reedijk 	}
6196da8285SMichael Lotz 
621501c2bfSNiels Sascha Reedijk 	return B_OK;
631501c2bfSNiels Sascha Reedijk }
641501c2bfSNiels Sascha Reedijk 
651501c2bfSNiels Sascha Reedijk 
66b8c6a851SMichael Lotz status_t
67b8c6a851SMichael Lotz register_driver(const char *driverName,
68b8c6a851SMichael Lotz 	const usb_support_descriptor *descriptors,
69b8c6a851SMichael Lotz 	size_t count, const char *optionalRepublishDriverName)
70b8c6a851SMichael Lotz {
71b8c6a851SMichael Lotz 	return gUSBStack->RegisterDriver(driverName, descriptors, count,
72b8c6a851SMichael Lotz 		optionalRepublishDriverName);
73b8c6a851SMichael Lotz }
74b8c6a851SMichael Lotz 
75b8c6a851SMichael Lotz 
76b8c6a851SMichael Lotz status_t
77b8c6a851SMichael Lotz install_notify(const char *driverName, const usb_notify_hooks *hooks)
78b8c6a851SMichael Lotz {
79b8c6a851SMichael Lotz 	return gUSBStack->InstallNotify(driverName, hooks);
80b8c6a851SMichael Lotz }
81b8c6a851SMichael Lotz 
82b8c6a851SMichael Lotz 
83b8c6a851SMichael Lotz status_t
84b8c6a851SMichael Lotz uninstall_notify(const char *driverName)
85b8c6a851SMichael Lotz {
86b8c6a851SMichael Lotz 	return gUSBStack->UninstallNotify(driverName);
87b8c6a851SMichael Lotz }
88b8c6a851SMichael Lotz 
89b8c6a851SMichael Lotz 
90b8c6a851SMichael Lotz const usb_device_descriptor *
91*5b0ec61fSMichael Lotz get_device_descriptor(usb_device device)
92b8c6a851SMichael Lotz {
93f1020a6cSMichael Lotz 	TRACE(("usb_module: get_device_descriptor(0x%08x)\n", device));
94*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
95*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
96b8c6a851SMichael Lotz 		return NULL;
97b8c6a851SMichael Lotz 
98*5b0ec61fSMichael Lotz 	return ((Device *)object)->DeviceDescriptor();
99b8c6a851SMichael Lotz }
100b8c6a851SMichael Lotz 
101b8c6a851SMichael Lotz 
102b8c6a851SMichael Lotz const usb_configuration_info *
103*5b0ec61fSMichael Lotz get_nth_configuration(usb_device device, uint index)
104b8c6a851SMichael Lotz {
105f1020a6cSMichael Lotz 	TRACE(("usb_module: get_nth_configuration(0x%08x, %d)\n", device, index));
106*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
107*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
108b8c6a851SMichael Lotz 		return NULL;
109b8c6a851SMichael Lotz 
110*5b0ec61fSMichael Lotz 	return ((Device *)object)->ConfigurationAt((int32)index);
111b8c6a851SMichael Lotz }
112b8c6a851SMichael Lotz 
113b8c6a851SMichael Lotz 
114b8c6a851SMichael Lotz const usb_configuration_info *
115*5b0ec61fSMichael Lotz get_configuration(usb_device device)
116b8c6a851SMichael Lotz {
117f1020a6cSMichael Lotz 	TRACE(("usb_module: get_configuration(0x%08x)\n", device));
118*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
119*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
120b8c6a851SMichael Lotz 		return NULL;
121b8c6a851SMichael Lotz 
122*5b0ec61fSMichael Lotz 	return ((Device *)object)->Configuration();
123b8c6a851SMichael Lotz }
124b8c6a851SMichael Lotz 
125b8c6a851SMichael Lotz 
126b8c6a851SMichael Lotz status_t
127*5b0ec61fSMichael Lotz set_configuration(usb_device device,
128b8c6a851SMichael Lotz 	const usb_configuration_info *configuration)
129b8c6a851SMichael Lotz {
130f1020a6cSMichael Lotz 	TRACE(("usb_module: set_configuration(0x%08x, 0x%08x)\n", device, configuration));
131*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
132*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
133b8c6a851SMichael Lotz 		return B_BAD_VALUE;
134b8c6a851SMichael Lotz 
135*5b0ec61fSMichael Lotz 	return ((Device *)object)->SetConfiguration(configuration);
136b8c6a851SMichael Lotz }
137b8c6a851SMichael Lotz 
138b8c6a851SMichael Lotz 
139b8c6a851SMichael Lotz status_t
140*5b0ec61fSMichael Lotz set_alt_interface(usb_device device, const usb_interface_info *interface)
141b8c6a851SMichael Lotz {
142f1020a6cSMichael Lotz 	TRACE(("usb_module: set_alt_interface(0x%08x, 0x%08x)\n", device, interface));
143*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
144*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
145*5b0ec61fSMichael Lotz 		return B_BAD_VALUE;
146*5b0ec61fSMichael Lotz 
147b8c6a851SMichael Lotz 	return B_ERROR;
148b8c6a851SMichael Lotz }
149b8c6a851SMichael Lotz 
150b8c6a851SMichael Lotz 
151b8c6a851SMichael Lotz status_t
152*5b0ec61fSMichael Lotz set_feature(usb_id handle, uint16 selector)
153b8c6a851SMichael Lotz {
154*5b0ec61fSMichael Lotz 	TRACE(("usb_module: set_feature(0x%08x, %d)\n", handle, selector));
155*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(handle);
156*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_PIPE) == 0)
157b8c6a851SMichael Lotz 		return B_BAD_VALUE;
158b8c6a851SMichael Lotz 
15949617128SMichael Lotz 	return ((Pipe *)object)->SetFeature(selector);
160b8c6a851SMichael Lotz }
161b8c6a851SMichael Lotz 
162b8c6a851SMichael Lotz 
163b8c6a851SMichael Lotz status_t
164*5b0ec61fSMichael Lotz clear_feature(usb_id handle, uint16 selector)
165b8c6a851SMichael Lotz {
166*5b0ec61fSMichael Lotz 	TRACE(("usb_module: clear_feature(0x%08x, %d)\n", handle, selector));
167*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(handle);
168*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_PIPE) == 0)
169b8c6a851SMichael Lotz 		return B_BAD_VALUE;
170b8c6a851SMichael Lotz 
17149617128SMichael Lotz 	return ((Pipe *)object)->ClearFeature(selector);
172b8c6a851SMichael Lotz }
173b8c6a851SMichael Lotz 
174b8c6a851SMichael Lotz 
175b8c6a851SMichael Lotz status_t
176*5b0ec61fSMichael Lotz get_status(usb_id handle, uint16 *status)
177b8c6a851SMichael Lotz {
178*5b0ec61fSMichael Lotz 	TRACE(("usb_module: get_status(0x%08x, 0x%08x)\n", handle, status));
179*5b0ec61fSMichael Lotz 	if (!status)
180*5b0ec61fSMichael Lotz 		return B_BAD_VALUE;
181*5b0ec61fSMichael Lotz 
182*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(handle);
183*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_PIPE) == 0)
184b8c6a851SMichael Lotz 		return B_BAD_VALUE;
185b8c6a851SMichael Lotz 
18649617128SMichael Lotz 	return ((Pipe *)object)->GetStatus(status);
187b8c6a851SMichael Lotz }
188b8c6a851SMichael Lotz 
189b8c6a851SMichael Lotz 
190b8c6a851SMichael Lotz status_t
191*5b0ec61fSMichael Lotz get_descriptor(usb_device device, uint8 type, uint8 index, uint16 languageID,
192*5b0ec61fSMichael Lotz 	void *data, size_t dataLength, size_t *actualLength)
193b8c6a851SMichael Lotz {
194f1020a6cSMichael 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));
195*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
196*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
197b8c6a851SMichael Lotz 		return B_BAD_VALUE;
198b8c6a851SMichael Lotz 
199*5b0ec61fSMichael Lotz 	return ((Device *)object)->GetDescriptor(type, index, languageID,
200b8c6a851SMichael Lotz 		data, dataLength, actualLength);
201b8c6a851SMichael Lotz }
202b8c6a851SMichael Lotz 
203b8c6a851SMichael Lotz 
204b8c6a851SMichael Lotz status_t
205*5b0ec61fSMichael Lotz send_request(usb_device device, uint8 requestType, uint8 request,
206*5b0ec61fSMichael Lotz 	uint16 value, uint16 index, uint16 length, void *data, size_t *actualLength)
207b8c6a851SMichael Lotz {
208*5b0ec61fSMichael 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));
209*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
210*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
211b8c6a851SMichael Lotz 		return B_BAD_VALUE;
212b8c6a851SMichael Lotz 
213*5b0ec61fSMichael Lotz 	return ((Device *)object)->SendRequest(requestType, request, value, index,
214*5b0ec61fSMichael Lotz 		length, data, length, actualLength);
215b8c6a851SMichael Lotz }
216b8c6a851SMichael Lotz 
217b8c6a851SMichael Lotz 
218b8c6a851SMichael Lotz status_t
219*5b0ec61fSMichael Lotz queue_request(usb_device device, uint8 requestType, uint8 request,
220*5b0ec61fSMichael Lotz 	uint16 value, uint16 index, uint16 length, void *data,
221b8c6a851SMichael Lotz 	usb_callback_func callback, void *callbackCookie)
222b8c6a851SMichael Lotz {
223*5b0ec61fSMichael 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));
224*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(device);
225*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
226b8c6a851SMichael Lotz 		return B_BAD_VALUE;
227b8c6a851SMichael Lotz 
228*5b0ec61fSMichael Lotz 	return ((Device *)object)->QueueRequest(requestType, request, value, index,
229*5b0ec61fSMichael Lotz 		length, data, length, callback, callbackCookie);
230b8c6a851SMichael Lotz }
231b8c6a851SMichael Lotz 
232b8c6a851SMichael Lotz 
233b8c6a851SMichael Lotz status_t
234*5b0ec61fSMichael Lotz queue_interrupt(usb_pipe pipe, void *data, size_t dataLength,
235b8c6a851SMichael Lotz 	usb_callback_func callback, void *callbackCookie)
236b8c6a851SMichael Lotz {
237f1020a6cSMichael Lotz 	TRACE(("usb_module: queue_interrupt(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, data, dataLength, callback, callbackCookie));
238*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(pipe);
239*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_INTERRUPT_PIPE) == 0)
240b8c6a851SMichael Lotz 		return B_BAD_VALUE;
241b8c6a851SMichael Lotz 
242*5b0ec61fSMichael Lotz 	return ((InterruptPipe *)object)->QueueInterrupt(data, dataLength, callback,
243b8c6a851SMichael Lotz 		callbackCookie);
244b8c6a851SMichael Lotz }
245b8c6a851SMichael Lotz 
246b8c6a851SMichael Lotz 
247b8c6a851SMichael Lotz status_t
248*5b0ec61fSMichael Lotz queue_bulk(usb_pipe pipe, void *data, size_t dataLength,
249b8c6a851SMichael Lotz 	usb_callback_func callback, void *callbackCookie)
250b8c6a851SMichael Lotz {
251f1020a6cSMichael Lotz 	TRACE(("usb_module: queue_bulk(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, data, dataLength, callback, callbackCookie));
252*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(pipe);
253*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0)
254b8c6a851SMichael Lotz 		return B_BAD_VALUE;
255b8c6a851SMichael Lotz 
256*5b0ec61fSMichael Lotz 	return ((BulkPipe *)object)->QueueBulk(data, dataLength, callback,
257b8c6a851SMichael Lotz 		callbackCookie);
258b8c6a851SMichael Lotz }
259b8c6a851SMichael Lotz 
260b8c6a851SMichael Lotz 
261b8c6a851SMichael Lotz status_t
262*5b0ec61fSMichael Lotz queue_bulk_v(usb_pipe pipe, iovec *vector, size_t vectorCount,
263*5b0ec61fSMichael Lotz 	usb_callback_func callback, void *callbackCookie)
264b8c6a851SMichael Lotz {
265*5b0ec61fSMichael Lotz 	TRACE(("usb_module: queue_bulk(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, vector, vectorCount, callback, callbackCookie));
266*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(pipe);
267*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_BULK_PIPE) == 0)
268b8c6a851SMichael Lotz 		return B_BAD_VALUE;
269b8c6a851SMichael Lotz 
270b8c6a851SMichael Lotz 	return B_ERROR;
271b8c6a851SMichael Lotz }
272b8c6a851SMichael Lotz 
273b8c6a851SMichael Lotz 
274b8c6a851SMichael Lotz status_t
275*5b0ec61fSMichael Lotz queue_isochronous(usb_pipe pipe, void *data, size_t dataLength,
276*5b0ec61fSMichael Lotz 	rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback,
277*5b0ec61fSMichael Lotz 	void *callbackCookie)
278*5b0ec61fSMichael Lotz {
279*5b0ec61fSMichael Lotz 	TRACE(("usb_module: queue_isochronous(0x%08x, 0x%08x, %d, 0x%08x, %d, 0x%08x, 0x%08x)\n", pipe, data, dataLength, rleArray, bufferDurationMS, callback, callbackCookie));
280*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(pipe);
281*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0)
282*5b0ec61fSMichael Lotz 		return B_BAD_VALUE;
283*5b0ec61fSMichael Lotz 
284*5b0ec61fSMichael Lotz 	return ((IsochronousPipe *)object)->QueueIsochronous(data, dataLength,
285*5b0ec61fSMichael Lotz 		rleArray, bufferDurationMS, callback, callbackCookie);
286*5b0ec61fSMichael Lotz }
287*5b0ec61fSMichael Lotz 
288*5b0ec61fSMichael Lotz 
289*5b0ec61fSMichael Lotz status_t
290*5b0ec61fSMichael Lotz set_pipe_policy(usb_pipe pipe, uint8 maxQueuedPackets,
291*5b0ec61fSMichael Lotz 	uint16 maxBufferDurationMS, uint16 sampleSize)
292*5b0ec61fSMichael Lotz {
293*5b0ec61fSMichael Lotz 	TRACE(("usb_module: set_pipe_policy(0x%08x, %d, %d, %d)\n", pipe, maxQueuedPackets, maxBufferDurationMS, sampleSize));
294*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(pipe);
295*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_ISO_PIPE) == 0)
296*5b0ec61fSMichael Lotz 		return B_BAD_VALUE;
297*5b0ec61fSMichael Lotz 
298*5b0ec61fSMichael Lotz 	return B_ERROR;
299*5b0ec61fSMichael Lotz }
300*5b0ec61fSMichael Lotz 
301*5b0ec61fSMichael Lotz 
302*5b0ec61fSMichael Lotz status_t
303*5b0ec61fSMichael Lotz cancel_queued_transfers(usb_pipe pipe)
304b8c6a851SMichael Lotz {
305f1020a6cSMichael Lotz 	TRACE(("usb_module: cancel_queued_transfers(0x%08x)\n", pipe));
306*5b0ec61fSMichael Lotz 	Object *object = gUSBStack->GetObject(pipe);
307*5b0ec61fSMichael Lotz 	if (!object || (object->Type() & USB_OBJECT_PIPE) == 0)
308*5b0ec61fSMichael Lotz 		return B_BAD_VALUE;
309*5b0ec61fSMichael Lotz 
310*5b0ec61fSMichael Lotz 	return ((Pipe *)object)->CancelQueuedTransfers();
311b8c6a851SMichael Lotz }
312b8c6a851SMichael Lotz 
313b8c6a851SMichael Lotz 
314b8c6a851SMichael Lotz status_t
315b8c6a851SMichael Lotz usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize)
316b8c6a851SMichael Lotz {
317f1020a6cSMichael Lotz 	TRACE(("usb_module: usb_ioctl(0x%08x, 0x%08x, %d)\n", opcode, buffer, bufferSize));
31864f3c065SMichael Lotz 
31964f3c065SMichael Lotz 	switch (opcode) {
32064f3c065SMichael Lotz 		case 'DNAM': {
321*5b0ec61fSMichael Lotz 			Object *object = gUSBStack->GetObject(*(usb_id *)buffer);
322*5b0ec61fSMichael Lotz 			if (!object || (object->Type() & USB_OBJECT_DEVICE) == 0)
323*5b0ec61fSMichael Lotz 				return B_BAD_VALUE;
324*5b0ec61fSMichael Lotz 
32564f3c065SMichael Lotz 			uint32 index = 0;
326*5b0ec61fSMichael Lotz 			return ((Device *)object)->BuildDeviceName((char *)buffer, &index,
327*5b0ec61fSMichael Lotz 				bufferSize, NULL);
32864f3c065SMichael Lotz 		}
32964f3c065SMichael Lotz 	}
33064f3c065SMichael Lotz 
33164f3c065SMichael Lotz 	return B_DEV_INVALID_IOCTL;
332b8c6a851SMichael Lotz }
333b8c6a851SMichael Lotz 
334b8c6a851SMichael Lotz 
33596da8285SMichael Lotz /*
336*5b0ec61fSMichael Lotz 	This module exports the USB API v3
33796da8285SMichael Lotz */
338*5b0ec61fSMichael Lotz struct usb_module_info gModuleInfoV3 = {
3391501c2bfSNiels Sascha Reedijk 	// First the bus_manager_info:
3401501c2bfSNiels Sascha Reedijk 	{
3411501c2bfSNiels Sascha Reedijk 		{
342*5b0ec61fSMichael Lotz 			"bus_managers/usb/v3",
3431501c2bfSNiels Sascha Reedijk 			B_KEEP_LOADED,				// Keep loaded, even if no driver requires it
3441501c2bfSNiels Sascha Reedijk 			bus_std_ops
3451501c2bfSNiels Sascha Reedijk 		},
3461501c2bfSNiels Sascha Reedijk 		NULL							// the rescan function
3471501c2bfSNiels Sascha Reedijk 	},
34896da8285SMichael Lotz 
349b8c6a851SMichael Lotz 	register_driver,					// register_driver
350b8c6a851SMichael Lotz 	install_notify,						// install_notify
351b8c6a851SMichael Lotz 	uninstall_notify,					// uninstall_notify
352b8c6a851SMichael Lotz 	get_device_descriptor,				// get_device_descriptor
353b8c6a851SMichael Lotz 	get_nth_configuration,				// get_nth_configuration
354b8c6a851SMichael Lotz 	get_configuration,					// get_configuration
355b8c6a851SMichael Lotz 	set_configuration,					// set_configuration
356b8c6a851SMichael Lotz 	set_alt_interface,					// set_alt_interface
357b8c6a851SMichael Lotz 	set_feature,						// set_feature
358b8c6a851SMichael Lotz 	clear_feature, 						// clear_feature
359b8c6a851SMichael Lotz 	get_status, 						// get_status
360b8c6a851SMichael Lotz 	get_descriptor,						// get_descriptor
361b8c6a851SMichael Lotz 	send_request,						// send_request
362b8c6a851SMichael Lotz 	queue_interrupt,					// queue_interrupt
363b8c6a851SMichael Lotz 	queue_bulk,							// queue_bulk
364*5b0ec61fSMichael Lotz 	queue_bulk_v,						// queue_bulk_v
365b8c6a851SMichael Lotz 	queue_isochronous,					// queue_isochronous
366b8c6a851SMichael Lotz 	queue_request,						// queue_request
367b8c6a851SMichael Lotz 	set_pipe_policy,					// set_pipe_policy
368b8c6a851SMichael Lotz 	cancel_queued_transfers,			// cancel_queued_transfers
369b8c6a851SMichael Lotz 	usb_ioctl							// usb_ioctl
3701501c2bfSNiels Sascha Reedijk };
3711501c2bfSNiels Sascha Reedijk 
37296da8285SMichael Lotz 
373*5b0ec61fSMichael Lotz //
374*5b0ec61fSMichael Lotz // #pragma mark -
375*5b0ec61fSMichael Lotz //
376*5b0ec61fSMichael Lotz 
377*5b0ec61fSMichael Lotz 
378*5b0ec61fSMichael Lotz const usb_device_descriptor *
379*5b0ec61fSMichael Lotz get_device_descriptor_v2(const void *device)
380*5b0ec61fSMichael Lotz {
381*5b0ec61fSMichael Lotz 	return get_device_descriptor((usb_id)device);
382*5b0ec61fSMichael Lotz }
383*5b0ec61fSMichael Lotz 
384*5b0ec61fSMichael Lotz 
385*5b0ec61fSMichael Lotz const usb_configuration_info *
386*5b0ec61fSMichael Lotz get_nth_configuration_v2(const void *device, uint index)
387*5b0ec61fSMichael Lotz {
388*5b0ec61fSMichael Lotz 	return get_nth_configuration((usb_id)device, index);
389*5b0ec61fSMichael Lotz }
390*5b0ec61fSMichael Lotz 
391*5b0ec61fSMichael Lotz 
392*5b0ec61fSMichael Lotz const usb_configuration_info *
393*5b0ec61fSMichael Lotz get_configuration_v2(const void *device)
394*5b0ec61fSMichael Lotz {
395*5b0ec61fSMichael Lotz 	return get_configuration((usb_id)device);
396*5b0ec61fSMichael Lotz }
397*5b0ec61fSMichael Lotz 
398*5b0ec61fSMichael Lotz 
399*5b0ec61fSMichael Lotz status_t
400*5b0ec61fSMichael Lotz set_configuration_v2(const void *device,
401*5b0ec61fSMichael Lotz 	const usb_configuration_info *configuration)
402*5b0ec61fSMichael Lotz {
403*5b0ec61fSMichael Lotz 	return set_configuration((usb_id)device, configuration);
404*5b0ec61fSMichael Lotz }
405*5b0ec61fSMichael Lotz 
406*5b0ec61fSMichael Lotz 
407*5b0ec61fSMichael Lotz status_t
408*5b0ec61fSMichael Lotz set_alt_interface_v2(const void *device, const usb_interface_info *interface)
409*5b0ec61fSMichael Lotz {
410*5b0ec61fSMichael Lotz 	return set_alt_interface((usb_id)device, interface);
411*5b0ec61fSMichael Lotz }
412*5b0ec61fSMichael Lotz 
413*5b0ec61fSMichael Lotz 
414*5b0ec61fSMichael Lotz status_t
415*5b0ec61fSMichael Lotz set_feature_v2(const void *object, uint16 selector)
416*5b0ec61fSMichael Lotz {
417*5b0ec61fSMichael Lotz 	return set_feature((usb_id)object, selector);
418*5b0ec61fSMichael Lotz }
419*5b0ec61fSMichael Lotz 
420*5b0ec61fSMichael Lotz 
421*5b0ec61fSMichael Lotz status_t
422*5b0ec61fSMichael Lotz clear_feature_v2(const void *object, uint16 selector)
423*5b0ec61fSMichael Lotz {
424*5b0ec61fSMichael Lotz 	return clear_feature((usb_id)object, selector);
425*5b0ec61fSMichael Lotz }
426*5b0ec61fSMichael Lotz 
427*5b0ec61fSMichael Lotz 
428*5b0ec61fSMichael Lotz status_t
429*5b0ec61fSMichael Lotz get_status_v2(const void *object, uint16 *status)
430*5b0ec61fSMichael Lotz {
431*5b0ec61fSMichael Lotz 	return get_status((usb_id)object, status);
432*5b0ec61fSMichael Lotz }
433*5b0ec61fSMichael Lotz 
434*5b0ec61fSMichael Lotz 
435*5b0ec61fSMichael Lotz status_t
436*5b0ec61fSMichael Lotz get_descriptor_v2(const void *device, uint8 type, uint8 index,
437*5b0ec61fSMichael Lotz 	uint16 languageID, void *data, size_t dataLength, size_t *actualLength)
438*5b0ec61fSMichael Lotz {
439*5b0ec61fSMichael Lotz 	return get_descriptor((usb_id)device, type, index, languageID, data,
440*5b0ec61fSMichael Lotz 		dataLength, actualLength);
441*5b0ec61fSMichael Lotz }
442*5b0ec61fSMichael Lotz 
443*5b0ec61fSMichael Lotz 
444*5b0ec61fSMichael Lotz status_t
445*5b0ec61fSMichael Lotz send_request_v2(const void *device, uint8 requestType, uint8 request,
446*5b0ec61fSMichael Lotz 	uint16 value, uint16 index, uint16 length, void *data,
447*5b0ec61fSMichael Lotz 	size_t /*dataLength*/, size_t *actualLength)
448*5b0ec61fSMichael Lotz {
449*5b0ec61fSMichael Lotz 	return send_request((usb_id)device, requestType, request, value, index,
450*5b0ec61fSMichael Lotz 		length, data, actualLength);
451*5b0ec61fSMichael Lotz }
452*5b0ec61fSMichael Lotz 
453*5b0ec61fSMichael Lotz 
454*5b0ec61fSMichael Lotz status_t
455*5b0ec61fSMichael Lotz queue_request_v2(const void *device, uint8 requestType, uint8 request,
456*5b0ec61fSMichael Lotz 	uint16 value, uint16 index, uint16 length, void *data,
457*5b0ec61fSMichael Lotz 	size_t /*dataLength*/, usb_callback_func callback, void *callbackCookie)
458*5b0ec61fSMichael Lotz {
459*5b0ec61fSMichael Lotz 	return queue_request((usb_id)device, requestType, request, value, index,
460*5b0ec61fSMichael Lotz 		length, data, callback, callbackCookie);
461*5b0ec61fSMichael Lotz }
462*5b0ec61fSMichael Lotz 
463*5b0ec61fSMichael Lotz 
464*5b0ec61fSMichael Lotz status_t
465*5b0ec61fSMichael Lotz queue_interrupt_v2(const void *pipe, void *data, size_t dataLength,
466*5b0ec61fSMichael Lotz 	usb_callback_func callback, void *callbackCookie)
467*5b0ec61fSMichael Lotz {
468*5b0ec61fSMichael Lotz 	return queue_interrupt((usb_id)pipe, data, dataLength, callback,
469*5b0ec61fSMichael Lotz 		callbackCookie);
470*5b0ec61fSMichael Lotz }
471*5b0ec61fSMichael Lotz 
472*5b0ec61fSMichael Lotz 
473*5b0ec61fSMichael Lotz status_t
474*5b0ec61fSMichael Lotz queue_bulk_v2(const void *pipe, void *data, size_t dataLength,
475*5b0ec61fSMichael Lotz 	usb_callback_func callback, void *callbackCookie)
476*5b0ec61fSMichael Lotz {
477*5b0ec61fSMichael Lotz 	return queue_bulk((usb_id)pipe, data, dataLength, callback,
478*5b0ec61fSMichael Lotz 		callbackCookie);
479*5b0ec61fSMichael Lotz }
480*5b0ec61fSMichael Lotz 
481*5b0ec61fSMichael Lotz 
482*5b0ec61fSMichael Lotz status_t
483*5b0ec61fSMichael Lotz queue_isochronous_v2(const void *pipe, void *data, size_t dataLength,
484*5b0ec61fSMichael Lotz 	rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback,
485*5b0ec61fSMichael Lotz 	void *callbackCookie)
486*5b0ec61fSMichael Lotz {
487*5b0ec61fSMichael Lotz 	return queue_isochronous((usb_id)pipe, data, dataLength, rleArray,
488*5b0ec61fSMichael Lotz 		bufferDurationMS, callback, callbackCookie);
489*5b0ec61fSMichael Lotz }
490*5b0ec61fSMichael Lotz 
491*5b0ec61fSMichael Lotz 
492*5b0ec61fSMichael Lotz status_t
493*5b0ec61fSMichael Lotz set_pipe_policy_v2(const void *pipe, uint8 maxQueuedPackets,
494*5b0ec61fSMichael Lotz 	uint16 maxBufferDurationMS, uint16 sampleSize)
495*5b0ec61fSMichael Lotz {
496*5b0ec61fSMichael Lotz 	return set_pipe_policy((usb_id)pipe, maxQueuedPackets, maxBufferDurationMS,
497*5b0ec61fSMichael Lotz 		sampleSize);
498*5b0ec61fSMichael Lotz }
499*5b0ec61fSMichael Lotz 
500*5b0ec61fSMichael Lotz 
501*5b0ec61fSMichael Lotz status_t
502*5b0ec61fSMichael Lotz cancel_queued_transfers_v2(const void *pipe)
503*5b0ec61fSMichael Lotz {
504*5b0ec61fSMichael Lotz 	return cancel_queued_transfers((usb_id)pipe);
505*5b0ec61fSMichael Lotz }
506*5b0ec61fSMichael Lotz 
507*5b0ec61fSMichael Lotz 
508*5b0ec61fSMichael Lotz struct usb_module_info_v2 {
509*5b0ec61fSMichael Lotz 	bus_manager_info				binfo;
510*5b0ec61fSMichael Lotz 	status_t						(*register_driver)(const char *, const usb_support_descriptor *, size_t, const char *);
511*5b0ec61fSMichael Lotz 	status_t						(*install_notify)(const char *, const usb_notify_hooks *);
512*5b0ec61fSMichael Lotz 	status_t						(*uninstall_notify)(const char *);
513*5b0ec61fSMichael Lotz 	const usb_device_descriptor		*(*get_device_descriptor)(const void *);
514*5b0ec61fSMichael Lotz 	const usb_configuration_info	*(*get_nth_configuration)(const void *, uint);
515*5b0ec61fSMichael Lotz 	const usb_configuration_info	*(*get_configuration)(const void *);
516*5b0ec61fSMichael Lotz 	status_t						(*set_configuration)(const void *, const usb_configuration_info *);
517*5b0ec61fSMichael Lotz 	status_t						(*set_alt_interface)(const void *, const usb_interface_info *);
518*5b0ec61fSMichael Lotz 	status_t						(*set_feature)(const void *, uint16);
519*5b0ec61fSMichael Lotz 	status_t						(*clear_feature)(const void *, uint16);
520*5b0ec61fSMichael Lotz 	status_t						(*get_status)(const void *, uint16 *);
521*5b0ec61fSMichael Lotz 	status_t						(*get_descriptor)(const void *, uint8, uint8, uint16, void *, size_t, size_t *);
522*5b0ec61fSMichael Lotz 	status_t						(*send_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, size_t *);
523*5b0ec61fSMichael Lotz 	status_t						(*queue_interrupt)(const void *, void *, size_t, usb_callback_func, void *);
524*5b0ec61fSMichael Lotz 	status_t						(*queue_bulk)(const void *, void *, size_t, usb_callback_func, void *);
525*5b0ec61fSMichael Lotz 	status_t						(*queue_isochronous)(const void *, void *, size_t, rlea *, uint16, usb_callback_func, void *);
526*5b0ec61fSMichael Lotz 	status_t						(*queue_request)(const void *, uint8, uint8, uint16, uint16, uint16, void *, size_t, usb_callback_func, void *);
527*5b0ec61fSMichael Lotz 	status_t						(*set_pipe_policy)(const void *, uint8, uint16, uint16);
528*5b0ec61fSMichael Lotz 	status_t						(*cancel_queued_transfers)(const void *);
529*5b0ec61fSMichael Lotz 	status_t						(*usb_ioctl)(uint32 opcode, void *,size_t);
530*5b0ec61fSMichael Lotz };
531*5b0ec61fSMichael Lotz 
532*5b0ec61fSMichael Lotz 
533*5b0ec61fSMichael Lotz /*
534*5b0ec61fSMichael Lotz 	This module exports the USB API v2
535*5b0ec61fSMichael Lotz */
536*5b0ec61fSMichael Lotz struct usb_module_info_v2 gModuleInfoV2 = {
537*5b0ec61fSMichael Lotz 	// First the bus_manager_info:
538*5b0ec61fSMichael Lotz 	{
539*5b0ec61fSMichael Lotz 		{
540*5b0ec61fSMichael Lotz 			"bus_managers/usb/v2",
541*5b0ec61fSMichael Lotz 			B_KEEP_LOADED,				// Keep loaded, even if no driver requires it
542*5b0ec61fSMichael Lotz 			bus_std_ops
543*5b0ec61fSMichael Lotz 		},
544*5b0ec61fSMichael Lotz 		NULL							// the rescan function
545*5b0ec61fSMichael Lotz 	},
546*5b0ec61fSMichael Lotz 
547*5b0ec61fSMichael Lotz 	register_driver,					// register_driver
548*5b0ec61fSMichael Lotz 	install_notify,						// install_notify
549*5b0ec61fSMichael Lotz 	uninstall_notify,					// uninstall_notify
550*5b0ec61fSMichael Lotz 	get_device_descriptor_v2,			// get_device_descriptor
551*5b0ec61fSMichael Lotz 	get_nth_configuration_v2,			// get_nth_configuration
552*5b0ec61fSMichael Lotz 	get_configuration_v2,				// get_configuration
553*5b0ec61fSMichael Lotz 	set_configuration_v2,				// set_configuration
554*5b0ec61fSMichael Lotz 	set_alt_interface_v2,				// set_alt_interface
555*5b0ec61fSMichael Lotz 	set_feature_v2,						// set_feature
556*5b0ec61fSMichael Lotz 	clear_feature_v2,					// clear_feature
557*5b0ec61fSMichael Lotz 	get_status_v2, 						// get_status
558*5b0ec61fSMichael Lotz 	get_descriptor_v2,					// get_descriptor
559*5b0ec61fSMichael Lotz 	send_request_v2,					// send_request
560*5b0ec61fSMichael Lotz 	queue_interrupt_v2,					// queue_interrupt
561*5b0ec61fSMichael Lotz 	queue_bulk_v2,						// queue_bulk
562*5b0ec61fSMichael Lotz 	queue_isochronous_v2,				// queue_isochronous
563*5b0ec61fSMichael Lotz 	queue_request_v2,					// queue_request
564*5b0ec61fSMichael Lotz 	set_pipe_policy_v2,					// set_pipe_policy
565*5b0ec61fSMichael Lotz 	cancel_queued_transfers_v2,			// cancel_queued_transfers
566*5b0ec61fSMichael Lotz 	usb_ioctl							// usb_ioctl
567*5b0ec61fSMichael Lotz };
568*5b0ec61fSMichael Lotz 
569*5b0ec61fSMichael Lotz 
570*5b0ec61fSMichael Lotz //
571*5b0ec61fSMichael Lotz // #pragma mark -
572*5b0ec61fSMichael Lotz //
573*5b0ec61fSMichael Lotz 
574*5b0ec61fSMichael Lotz 
5751501c2bfSNiels Sascha Reedijk module_info *modules[] = {
576*5b0ec61fSMichael Lotz 	(module_info *)&gModuleInfoV2,
577*5b0ec61fSMichael Lotz 	(module_info *)&gModuleInfoV3,
5781501c2bfSNiels Sascha Reedijk 	NULL
5791501c2bfSNiels Sascha Reedijk };
580