xref: /haiku/src/add-ons/kernel/bus_managers/usb/usb.cpp (revision b8c6a85136cd56e8cf3282ca69b0d2d2832a3eee)
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:
696da8285SMichael Lotz  *		Niels S. Reedijk
796da8285SMichael Lotz  */
81501c2bfSNiels Sascha Reedijk 
91501c2bfSNiels Sascha Reedijk #include <USB.h>
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 
22*b8c6a851SMichael Lotz Stack *gUSBStack = NULL;
23*b8c6a851SMichael Lotz 
24*b8c6a851SMichael 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: {
3096da8285SMichael Lotz #ifdef TRACE_USB
311a2e81b5SNiels Sascha Reedijk 			set_dprintf_enabled(true);
321a2e81b5SNiels Sascha Reedijk 			load_driver_symbols("usb");
331a2e81b5SNiels Sascha Reedijk #endif
34*b8c6a851SMichael Lotz 			TRACE(("usb_module: init\n"));
3596da8285SMichael Lotz 
36*b8c6a851SMichael Lotz 			Stack *stack = new(std::nothrow) Stack();
37*b8c6a851SMichael Lotz 			if (!stack)
38*b8c6a851SMichael Lotz 				return B_NO_MEMORY;
39*b8c6a851SMichael Lotz 
4096da8285SMichael Lotz 			if (stack->InitCheck() != B_OK) {
411a2e81b5SNiels Sascha Reedijk 				delete stack;
421501c2bfSNiels Sascha Reedijk 				return ENODEV;
431501c2bfSNiels Sascha Reedijk 			}
4496da8285SMichael Lotz 
45*b8c6a851SMichael Lotz 			gUSBStack = stack;
461501c2bfSNiels Sascha Reedijk 			break;
4796da8285SMichael Lotz 		}
4896da8285SMichael Lotz 
491501c2bfSNiels Sascha Reedijk 		case B_MODULE_UNINIT:
50*b8c6a851SMichael Lotz 			TRACE(("usb_module: bus module: uninit\n"));
51*b8c6a851SMichael Lotz 			delete gUSBStack;
52*b8c6a851SMichael Lotz 			gUSBStack = NULL;
531501c2bfSNiels Sascha Reedijk 			break;
5496da8285SMichael Lotz 
551501c2bfSNiels Sascha Reedijk 		default:
561501c2bfSNiels Sascha Reedijk 			return EINVAL;
571501c2bfSNiels Sascha Reedijk 	}
5896da8285SMichael Lotz 
591501c2bfSNiels Sascha Reedijk 	return B_OK;
601501c2bfSNiels Sascha Reedijk }
611501c2bfSNiels Sascha Reedijk 
621501c2bfSNiels Sascha Reedijk 
63*b8c6a851SMichael Lotz status_t
64*b8c6a851SMichael Lotz register_driver(const char *driverName,
65*b8c6a851SMichael Lotz 	const usb_support_descriptor *descriptors,
66*b8c6a851SMichael Lotz 	size_t count, const char *optionalRepublishDriverName)
67*b8c6a851SMichael Lotz {
68*b8c6a851SMichael Lotz 	return gUSBStack->RegisterDriver(driverName, descriptors, count,
69*b8c6a851SMichael Lotz 		optionalRepublishDriverName);
70*b8c6a851SMichael Lotz }
71*b8c6a851SMichael Lotz 
72*b8c6a851SMichael Lotz 
73*b8c6a851SMichael Lotz status_t
74*b8c6a851SMichael Lotz install_notify(const char *driverName, const usb_notify_hooks *hooks)
75*b8c6a851SMichael Lotz {
76*b8c6a851SMichael Lotz 	return gUSBStack->InstallNotify(driverName, hooks);
77*b8c6a851SMichael Lotz }
78*b8c6a851SMichael Lotz 
79*b8c6a851SMichael Lotz 
80*b8c6a851SMichael Lotz status_t
81*b8c6a851SMichael Lotz uninstall_notify(const char *driverName)
82*b8c6a851SMichael Lotz {
83*b8c6a851SMichael Lotz 	return gUSBStack->UninstallNotify(driverName);
84*b8c6a851SMichael Lotz }
85*b8c6a851SMichael Lotz 
86*b8c6a851SMichael Lotz 
87*b8c6a851SMichael Lotz const usb_device_descriptor *
88*b8c6a851SMichael Lotz get_device_descriptor(const usb_device *device)
89*b8c6a851SMichael Lotz {
90*b8c6a851SMichael Lotz 	if (!device)
91*b8c6a851SMichael Lotz 		return NULL;
92*b8c6a851SMichael Lotz 
93*b8c6a851SMichael Lotz 	return ((const Device *)device)->DeviceDescriptor();
94*b8c6a851SMichael Lotz }
95*b8c6a851SMichael Lotz 
96*b8c6a851SMichael Lotz 
97*b8c6a851SMichael Lotz const usb_configuration_info *
98*b8c6a851SMichael Lotz get_nth_configuration(const usb_device *device, uint index)
99*b8c6a851SMichael Lotz {
100*b8c6a851SMichael Lotz 	if (!device)
101*b8c6a851SMichael Lotz 		return NULL;
102*b8c6a851SMichael Lotz 
103*b8c6a851SMichael Lotz 	return ((const Device *)device)->ConfigurationAt((int32)index);
104*b8c6a851SMichael Lotz }
105*b8c6a851SMichael Lotz 
106*b8c6a851SMichael Lotz 
107*b8c6a851SMichael Lotz 
108*b8c6a851SMichael Lotz const usb_configuration_info *
109*b8c6a851SMichael Lotz get_configuration(const usb_device *device)
110*b8c6a851SMichael Lotz {
111*b8c6a851SMichael Lotz 	if (!device)
112*b8c6a851SMichael Lotz 		return NULL;
113*b8c6a851SMichael Lotz 
114*b8c6a851SMichael Lotz 	return ((const Device *)device)->Configuration();
115*b8c6a851SMichael Lotz }
116*b8c6a851SMichael Lotz 
117*b8c6a851SMichael Lotz 
118*b8c6a851SMichael Lotz status_t
119*b8c6a851SMichael Lotz set_configuration(const usb_device *device,
120*b8c6a851SMichael Lotz 	const usb_configuration_info *configuration)
121*b8c6a851SMichael Lotz {
122*b8c6a851SMichael Lotz 	if (!device)
123*b8c6a851SMichael Lotz 		return B_BAD_VALUE;
124*b8c6a851SMichael Lotz 
125*b8c6a851SMichael Lotz 	return ((Device *)device)->SetConfiguration(configuration);
126*b8c6a851SMichael Lotz }
127*b8c6a851SMichael Lotz 
128*b8c6a851SMichael Lotz 
129*b8c6a851SMichael Lotz status_t
130*b8c6a851SMichael Lotz set_alt_interface(const usb_device *device,
131*b8c6a851SMichael Lotz 	const usb_interface_info *interface)
132*b8c6a851SMichael Lotz {
133*b8c6a851SMichael Lotz 	return B_ERROR;
134*b8c6a851SMichael Lotz }
135*b8c6a851SMichael Lotz 
136*b8c6a851SMichael Lotz 
137*b8c6a851SMichael Lotz status_t
138*b8c6a851SMichael Lotz set_feature(const void *object, uint16 selector)
139*b8c6a851SMichael Lotz {
140*b8c6a851SMichael Lotz 	if (!object)
141*b8c6a851SMichael Lotz 		return B_BAD_VALUE;
142*b8c6a851SMichael Lotz 
143*b8c6a851SMichael Lotz 	return ((ControlPipe *)object)->SetFeature(selector);
144*b8c6a851SMichael Lotz }
145*b8c6a851SMichael Lotz 
146*b8c6a851SMichael Lotz 
147*b8c6a851SMichael Lotz status_t
148*b8c6a851SMichael Lotz clear_feature(const void *object, uint16 selector)
149*b8c6a851SMichael Lotz {
150*b8c6a851SMichael Lotz 	if (!object)
151*b8c6a851SMichael Lotz 		return B_BAD_VALUE;
152*b8c6a851SMichael Lotz 
153*b8c6a851SMichael Lotz 	return ((ControlPipe *)object)->ClearFeature(selector);
154*b8c6a851SMichael Lotz }
155*b8c6a851SMichael Lotz 
156*b8c6a851SMichael Lotz 
157*b8c6a851SMichael Lotz status_t
158*b8c6a851SMichael Lotz get_status(const void *object, uint16 *status)
159*b8c6a851SMichael Lotz {
160*b8c6a851SMichael Lotz 	if (!object || !status)
161*b8c6a851SMichael Lotz 		return B_BAD_VALUE;
162*b8c6a851SMichael Lotz 
163*b8c6a851SMichael Lotz 	return ((ControlPipe *)object)->GetStatus(status);
164*b8c6a851SMichael Lotz }
165*b8c6a851SMichael Lotz 
166*b8c6a851SMichael Lotz 
167*b8c6a851SMichael Lotz status_t
168*b8c6a851SMichael Lotz get_descriptor(const usb_device *device, uint8 type, uint8 index,
169*b8c6a851SMichael Lotz 	uint16 languageID, void *data, size_t dataLength, size_t *actualLength)
170*b8c6a851SMichael Lotz {
171*b8c6a851SMichael Lotz 	if (!device || !data)
172*b8c6a851SMichael Lotz 		return B_BAD_VALUE;
173*b8c6a851SMichael Lotz 
174*b8c6a851SMichael Lotz 	return ((Device *)device)->GetDescriptor(type, index, languageID,
175*b8c6a851SMichael Lotz 		data, dataLength, actualLength);
176*b8c6a851SMichael Lotz }
177*b8c6a851SMichael Lotz 
178*b8c6a851SMichael Lotz 
179*b8c6a851SMichael Lotz status_t
180*b8c6a851SMichael Lotz send_request(const usb_device *device, uint8 requestType, uint8 request,
181*b8c6a851SMichael Lotz 	uint16 value, uint16 index, uint16 length, void *data, size_t dataLength,
182*b8c6a851SMichael Lotz 	size_t *actualLength)
183*b8c6a851SMichael Lotz {
184*b8c6a851SMichael Lotz 	if (!device)
185*b8c6a851SMichael Lotz 		return B_BAD_VALUE;
186*b8c6a851SMichael Lotz 
187*b8c6a851SMichael Lotz 	return ((Device *)device)->SendRequest(requestType, request, value, index,
188*b8c6a851SMichael Lotz 		length, data, dataLength, actualLength);
189*b8c6a851SMichael Lotz }
190*b8c6a851SMichael Lotz 
191*b8c6a851SMichael Lotz 
192*b8c6a851SMichael Lotz status_t
193*b8c6a851SMichael Lotz queue_request(const usb_device *device, uint8 requestType, uint8 request,
194*b8c6a851SMichael Lotz 	uint16 value, uint16 index, uint16 length, void *data, size_t dataLength,
195*b8c6a851SMichael Lotz 	usb_callback_func callback, void *callbackCookie)
196*b8c6a851SMichael Lotz {
197*b8c6a851SMichael Lotz 	if (!device)
198*b8c6a851SMichael Lotz 		return B_BAD_VALUE;
199*b8c6a851SMichael Lotz 
200*b8c6a851SMichael Lotz 	return ((Device *)device)->QueueRequest(requestType, request, value, index,
201*b8c6a851SMichael Lotz 		length, data, dataLength, callback, callbackCookie);
202*b8c6a851SMichael Lotz }
203*b8c6a851SMichael Lotz 
204*b8c6a851SMichael Lotz 
205*b8c6a851SMichael Lotz status_t
206*b8c6a851SMichael Lotz queue_interrupt(const usb_pipe *pipe, void *data, size_t dataLength,
207*b8c6a851SMichael Lotz 	usb_callback_func callback, void *callbackCookie)
208*b8c6a851SMichael Lotz {
209*b8c6a851SMichael Lotz 	if (((Pipe *)pipe)->Type() != Pipe::Interrupt)
210*b8c6a851SMichael Lotz 		return B_BAD_VALUE;
211*b8c6a851SMichael Lotz 
212*b8c6a851SMichael Lotz 	return ((InterruptPipe *)pipe)->QueueInterrupt(data, dataLength, callback,
213*b8c6a851SMichael Lotz 		callbackCookie);
214*b8c6a851SMichael Lotz }
215*b8c6a851SMichael Lotz 
216*b8c6a851SMichael Lotz 
217*b8c6a851SMichael Lotz status_t
218*b8c6a851SMichael Lotz queue_bulk(const usb_pipe *pipe, void *data, size_t dataLength,
219*b8c6a851SMichael Lotz 	usb_callback_func callback, void *callbackCookie)
220*b8c6a851SMichael Lotz {
221*b8c6a851SMichael Lotz 	if (((Pipe *)pipe)->Type() != Pipe::Bulk)
222*b8c6a851SMichael Lotz 		return B_BAD_VALUE;
223*b8c6a851SMichael Lotz 
224*b8c6a851SMichael Lotz 	return ((BulkPipe *)pipe)->QueueBulk(data, dataLength, callback,
225*b8c6a851SMichael Lotz 		callbackCookie);
226*b8c6a851SMichael Lotz }
227*b8c6a851SMichael Lotz 
228*b8c6a851SMichael Lotz 
229*b8c6a851SMichael Lotz status_t
230*b8c6a851SMichael Lotz queue_isochronous(const usb_pipe *pipe, void *data, size_t dataLength,
231*b8c6a851SMichael Lotz 	rlea *rleArray, uint16 bufferDurationMS, usb_callback_func callback,
232*b8c6a851SMichael Lotz 	void *callbackCookie)
233*b8c6a851SMichael Lotz {
234*b8c6a851SMichael Lotz 	if (((Pipe *)pipe)->Type() != Pipe::Isochronous)
235*b8c6a851SMichael Lotz 		return B_BAD_VALUE;
236*b8c6a851SMichael Lotz 
237*b8c6a851SMichael Lotz 	return ((IsochronousPipe *)pipe)->QueueIsochronous(data, dataLength,
238*b8c6a851SMichael Lotz 		rleArray, bufferDurationMS, callback, callbackCookie);
239*b8c6a851SMichael Lotz }
240*b8c6a851SMichael Lotz 
241*b8c6a851SMichael Lotz 
242*b8c6a851SMichael Lotz status_t
243*b8c6a851SMichael Lotz set_pipe_policy(const usb_pipe *pipe, uint8 maxQueuedPackets,
244*b8c6a851SMichael Lotz 	uint16 maxBufferDurationMS, uint16 sampleSize)
245*b8c6a851SMichael Lotz {
246*b8c6a851SMichael Lotz 	return B_ERROR;
247*b8c6a851SMichael Lotz }
248*b8c6a851SMichael Lotz 
249*b8c6a851SMichael Lotz 
250*b8c6a851SMichael Lotz status_t
251*b8c6a851SMichael Lotz cancel_queued_transfers(const usb_pipe *pipe)
252*b8c6a851SMichael Lotz {
253*b8c6a851SMichael Lotz 	return ((Pipe *)pipe)->CancelQueuedTransfers();
254*b8c6a851SMichael Lotz }
255*b8c6a851SMichael Lotz 
256*b8c6a851SMichael Lotz 
257*b8c6a851SMichael Lotz status_t
258*b8c6a851SMichael Lotz usb_ioctl(uint32 opcode, void *buffer, size_t bufferSize)
259*b8c6a851SMichael Lotz {
260*b8c6a851SMichael Lotz 	return B_ERROR;
261*b8c6a851SMichael Lotz }
262*b8c6a851SMichael Lotz 
263*b8c6a851SMichael Lotz 
26496da8285SMichael Lotz /*
2651501c2bfSNiels Sascha Reedijk 	This module exports the USB API
26696da8285SMichael Lotz */
26796da8285SMichael Lotz struct usb_module_info gModuleInfo = {
2681501c2bfSNiels Sascha Reedijk 	// First the bus_manager_info:
2691501c2bfSNiels Sascha Reedijk 	{
2701501c2bfSNiels Sascha Reedijk 		{
271*b8c6a851SMichael Lotz 			B_USB_MODULE_NAME,
2721501c2bfSNiels Sascha Reedijk 			B_KEEP_LOADED,				// Keep loaded, even if no driver requires it
2731501c2bfSNiels Sascha Reedijk 			bus_std_ops
2741501c2bfSNiels Sascha Reedijk 		},
2751501c2bfSNiels Sascha Reedijk 		NULL							// the rescan function
2761501c2bfSNiels Sascha Reedijk 	},
27796da8285SMichael Lotz 
278*b8c6a851SMichael Lotz 	register_driver,					// register_driver
279*b8c6a851SMichael Lotz 	install_notify,						// install_notify
280*b8c6a851SMichael Lotz 	uninstall_notify,					// uninstall_notify
281*b8c6a851SMichael Lotz 	get_device_descriptor,				// get_device_descriptor
282*b8c6a851SMichael Lotz 	get_nth_configuration,				// get_nth_configuration
283*b8c6a851SMichael Lotz 	get_configuration,					// get_configuration
284*b8c6a851SMichael Lotz 	set_configuration,					// set_configuration
285*b8c6a851SMichael Lotz 	set_alt_interface,					// set_alt_interface
286*b8c6a851SMichael Lotz 	set_feature,						// set_feature
287*b8c6a851SMichael Lotz 	clear_feature, 						// clear_feature
288*b8c6a851SMichael Lotz 	get_status, 						// get_status
289*b8c6a851SMichael Lotz 	get_descriptor,						// get_descriptor
290*b8c6a851SMichael Lotz 	send_request,						// send_request
291*b8c6a851SMichael Lotz 	queue_interrupt,					// queue_interrupt
292*b8c6a851SMichael Lotz 	queue_bulk,							// queue_bulk
293*b8c6a851SMichael Lotz 	queue_isochronous,					// queue_isochronous
294*b8c6a851SMichael Lotz 	queue_request,						// queue_request
295*b8c6a851SMichael Lotz 	set_pipe_policy,					// set_pipe_policy
296*b8c6a851SMichael Lotz 	cancel_queued_transfers,			// cancel_queued_transfers
297*b8c6a851SMichael Lotz 	usb_ioctl							// usb_ioctl
2981501c2bfSNiels Sascha Reedijk };
2991501c2bfSNiels Sascha Reedijk 
30096da8285SMichael Lotz 
3011501c2bfSNiels Sascha Reedijk module_info *modules[] = {
30296da8285SMichael Lotz 	(module_info *)&gModuleInfo,
3031501c2bfSNiels Sascha Reedijk 	NULL
3041501c2bfSNiels Sascha Reedijk };
305