xref: /haiku/src/add-ons/kernel/bus_managers/usb/usb_private.h (revision 7ee53ed3bd2222305c93a4959f8c587c373ed97c)
1 /*
2  * Copyright 2003-2006, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Michael Lotz <mmlr@mlotz.ch>
7  *		Niels S. Reedijk
8  */
9 #ifndef _USB_PRIVATE_H
10 #define _USB_PRIVATE_H
11 
12 #include "BeOSCompatibility.h"
13 #include "usbspec_private.h"
14 #include <lock.h>
15 #include <util/Vector.h>
16 
17 
18 #define TRACE_OUTPUT(x, y, z...) \
19 	{ \
20 		dprintf("usb %s%s %ld: ", y, (x)->TypeName(), (x)->USBID()); \
21 		dprintf(z); \
22 	}
23 
24 //#define TRACE_USB
25 #ifdef TRACE_USB
26 #define TRACE(x...)					TRACE_OUTPUT(this, "", x)
27 #define TRACE_STATIC(x, y...)		TRACE_OUTPUT(x, "", y)
28 #define TRACE_MODULE(x...)			dprintf("usb "USB_MODULE_NAME": "x)
29 #else
30 #define TRACE(x...)					/* nothing */
31 #define TRACE_STATIC(x, y...)		/* nothing */
32 #define TRACE_MODULE(x...)			/* nothing */
33 #endif
34 
35 #define TRACE_ALWAYS(x...)			TRACE_OUTPUT(this, "", x)
36 #define TRACE_ERROR(x...)			TRACE_OUTPUT(this, "error ", x)
37 #define TRACE_MODULE_ALWAYS(x...)	dprintf("usb "USB_MODULE_NAME": "x)
38 #define TRACE_MODULE_ERROR(x...)	dprintf("usb "USB_MODULE_NAME": "x)
39 
40 class Hub;
41 class Stack;
42 class Device;
43 class Transfer;
44 class BusManager;
45 class Pipe;
46 class ControlPipe;
47 class Object;
48 class PhysicalMemoryAllocator;
49 
50 
51 struct usb_host_controller_info {
52 	module_info info;
53 	status_t (*control)(uint32 op, void *data, size_t length);
54 	status_t (*add_to)(Stack *stack);
55 };
56 
57 
58 struct usb_driver_cookie {
59 	usb_id device;
60 	void *cookie;
61 	usb_driver_cookie *link;
62 };
63 
64 
65 struct usb_driver_info {
66 	const char *driver_name;
67 	usb_support_descriptor *support_descriptors;
68 	uint32 support_descriptor_count;
69 	const char *republish_driver_name;
70 	usb_notify_hooks notify_hooks;
71 	usb_driver_cookie *cookies;
72 	usb_driver_info *link;
73 };
74 
75 
76 struct change_item {
77 	bool added;
78 	Device *device;
79 	change_item *link;
80 };
81 
82 
83 struct rescan_item {
84 	const char *name;
85 	rescan_item *link;
86 };
87 
88 
89 typedef enum {
90 	USB_SPEED_LOWSPEED = 0,
91 	USB_SPEED_FULLSPEED,
92 	USB_SPEED_HIGHSPEED,
93 	USB_SPEED_SUPER,
94 	USB_SPEED_WIRELESS,
95 	USB_SPEED_MAX = USB_SPEED_WIRELESS
96 } usb_speed;
97 
98 
99 typedef enum {
100 	USB_CHANGE_CREATED = 0,
101 	USB_CHANGE_DESTROYED,
102 	USB_CHANGE_PIPE_POLICY_CHANGED
103 } usb_change;
104 
105 
106 #define USB_OBJECT_NONE					0x00000000
107 #define USB_OBJECT_PIPE					0x00000001
108 #define USB_OBJECT_CONTROL_PIPE			0x00000002
109 #define USB_OBJECT_INTERRUPT_PIPE		0x00000004
110 #define USB_OBJECT_BULK_PIPE			0x00000008
111 #define USB_OBJECT_ISO_PIPE				0x00000010
112 #define USB_OBJECT_INTERFACE			0x00000020
113 #define USB_OBJECT_DEVICE				0x00000040
114 #define USB_OBJECT_HUB					0x00000080
115 
116 
117 class Stack {
118 public:
119 										Stack();
120 										~Stack();
121 
122 		status_t						InitCheck();
123 
124 		bool							Lock();
125 		void							Unlock();
126 
127 		usb_id							GetUSBID(Object *object);
128 		void							PutUSBID(usb_id id);
129 		Object *						GetObject(usb_id id);
130 
131 		// only for the kernel debugger
132 		Object *						GetObjectNoLock(usb_id id) const;
133 
134 		void							AddBusManager(BusManager *bus);
135 		int32							IndexOfBusManager(BusManager *bus);
136 		BusManager *					BusManagerAt(int32 index) const;
137 
138 		status_t						AllocateChunk(void **logicalAddress,
139 											void **physicalAddress,
140 											size_t size);
141 		status_t						FreeChunk(void *logicalAddress,
142 											void *physicalAddress, size_t size);
143 
144 		area_id							AllocateArea(void **logicalAddress,
145 											void **physicalAddress,
146 											size_t size, const char *name);
147 
148 		void							NotifyDeviceChange(Device *device,
149 											rescan_item **rescanList,
150 											bool added);
151 		void							RescanDrivers(rescan_item *rescanItem);
152 
153 		// USB API
154 		status_t						RegisterDriver(const char *driverName,
155 											const usb_support_descriptor *
156 												descriptors,
157 											size_t descriptorCount,
158 											const char *republishDriverName);
159 
160 		status_t						InstallNotify(const char *driverName,
161 											const usb_notify_hooks *hooks);
162 		status_t						UninstallNotify(const char *driverName);
163 
164 		usb_id							USBID() const { return 0; }
165 		const char *					TypeName() const { return "stack"; }
166 
167 private:
168 static	int32							ExploreThread(void *data);
169 
170 		Vector<BusManager *>			fBusManagers;
171 		thread_id						fExploreThread;
172 		bool							fFirstExploreDone;
173 		bool							fStopThreads;
174 
175 		mutex							fStackLock;
176 		mutex							fExploreLock;
177 		PhysicalMemoryAllocator *		fAllocator;
178 
179 		uint32							fObjectIndex;
180 		uint32							fObjectMaxCount;
181 		Object **						fObjectArray;
182 
183 		usb_driver_info *				fDriverList;
184 };
185 
186 
187 /*
188  * This class manages a bus. It is created by the Stack object
189  * after a host controller gives positive feedback on whether the hardware
190  * is found.
191  */
192 class BusManager {
193 public:
194 										BusManager(Stack *stack);
195 virtual									~BusManager();
196 
197 virtual	status_t						InitCheck();
198 
199 		bool							Lock();
200 		void							Unlock();
201 
202 		int8							AllocateAddress();
203 		void							FreeAddress(int8 address);
204 
205 virtual	Device *						AllocateDevice(Hub *parent,
206 											int8 hubAddress, uint8 hubPort,
207 											usb_speed speed);
208 virtual void							FreeDevice(Device *device);
209 
210 virtual	status_t						Start();
211 virtual	status_t						Stop();
212 
213 virtual	status_t						SubmitTransfer(Transfer *transfer);
214 virtual	status_t						CancelQueuedTransfers(Pipe *pipe,
215 											bool force);
216 
217 virtual	status_t						NotifyPipeChange(Pipe *pipe,
218 											usb_change change);
219 
220 		Object *						RootObject() const
221 											{ return fRootObject; }
222 
223 		Hub *							GetRootHub() const { return fRootHub; }
224 		void							SetRootHub(Hub *hub) { fRootHub = hub; }
225 
226 		usb_id							USBID() const { return fUSBID; }
227 virtual	const char *					TypeName() const = 0;
228 
229 protected:
230 		bool							fInitOK;
231 
232 private:
233 		ControlPipe *					_GetDefaultPipe(usb_speed);
234 
235 		mutex							fLock;
236 
237 		bool							fDeviceMap[128];
238 		int8							fDeviceIndex;
239 
240 		Stack *							fStack;
241 		ControlPipe *					fDefaultPipes[USB_SPEED_MAX + 1];
242 		Hub *							fRootHub;
243 		Object *						fRootObject;
244 
245 		usb_id							fUSBID;
246 };
247 
248 
249 class Object {
250 public:
251 										Object(Stack *stack, BusManager *bus);
252 										Object(Object *parent);
253 virtual									~Object();
254 
255 		Object *						Parent() const { return fParent; }
256 
257 		BusManager *					GetBusManager() const
258 											{ return fBusManager; }
259 		Stack *							GetStack() const { return fStack; }
260 
261 		usb_id							USBID() const { return fUSBID; }
262 virtual	uint32							Type() const { return USB_OBJECT_NONE; }
263 virtual	const char *					TypeName() const { return "object"; }
264 
265 		// Convenience functions for standard requests
266 virtual	status_t						SetFeature(uint16 selector);
267 virtual	status_t						ClearFeature(uint16 selector);
268 virtual	status_t						GetStatus(uint16 *status);
269 
270 private:
271 		Object *						fParent;
272 		BusManager *					fBusManager;
273 		Stack *							fStack;
274 		usb_id							fUSBID;
275 };
276 
277 
278 /*
279  * The Pipe class is the communication management between the hardware and
280  * the stack. It creates packets, manages these and performs callbacks.
281  */
282 class Pipe : public Object {
283 public:
284 		enum pipeDirection { In, Out, Default };
285 
286 										Pipe(Object *parent);
287 virtual									~Pipe();
288 
289 		void							InitCommon(int8 deviceAddress,
290 											uint8 endpointAddress,
291 											usb_speed speed,
292 											pipeDirection direction,
293 											size_t maxPacketSize,
294 											uint8 interval,
295 											int8 hubAddress, uint8 hubPort);
296 
297 virtual	uint32							Type() const { return USB_OBJECT_PIPE; }
298 virtual	const char *					TypeName() const { return "pipe"; }
299 
300 		int8							DeviceAddress() const
301 											{ return fDeviceAddress; }
302 		usb_speed						Speed() const { return fSpeed; }
303 		pipeDirection					Direction() const { return fDirection; }
304 		uint8							EndpointAddress() const
305 											{ return fEndpointAddress; }
306 		size_t							MaxPacketSize() const
307 											{ return fMaxPacketSize; }
308 		uint8							Interval() const { return fInterval; }
309 
310 		// Hub port being the one-based logical port number on the hub
311 		void							SetHubInfo(int8 address, uint8 port);
312 		int8							HubAddress() const
313 											{ return fHubAddress; }
314 		uint8							HubPort() const { return fHubPort; }
315 
316 virtual	bool							DataToggle() const
317 											{ return fDataToggle; }
318 virtual	void							SetDataToggle(bool toggle)
319 											{ fDataToggle = toggle; }
320 
321 		status_t						SubmitTransfer(Transfer *transfer);
322 		status_t						CancelQueuedTransfers(bool force);
323 
324 		void							SetControllerCookie(void *cookie)
325 											{ fControllerCookie = cookie; }
326 		void *							ControllerCookie() const
327 											{ return fControllerCookie; }
328 
329 		// Convenience functions for standard requests
330 virtual	status_t						SetFeature(uint16 selector);
331 virtual	status_t						ClearFeature(uint16 selector);
332 virtual	status_t						GetStatus(uint16 *status);
333 
334 private:
335 		int8							fDeviceAddress;
336 		uint8							fEndpointAddress;
337 		pipeDirection					fDirection;
338 		usb_speed						fSpeed;
339 		size_t							fMaxPacketSize;
340 		uint8							fInterval;
341 		int8							fHubAddress;
342 		uint8							fHubPort;
343 		bool							fDataToggle;
344 		void *							fControllerCookie;
345 };
346 
347 
348 class ControlPipe : public Pipe {
349 public:
350 										ControlPipe(Object *parent);
351 virtual									~ControlPipe();
352 
353 virtual	uint32							Type() const { return USB_OBJECT_PIPE
354 											| USB_OBJECT_CONTROL_PIPE; }
355 virtual	const char *					TypeName() const
356 											{ return "control pipe"; }
357 
358 										// The data toggle is not relevant
359 										// for control transfers, as they are
360 										// always enclosed by a setup and
361 										// status packet. The toggle always
362 										// starts at 1.
363 virtual	bool							DataToggle() const { return true; }
364 virtual	void							SetDataToggle(bool toggle) {}
365 
366 		status_t						SendRequest(uint8 requestType,
367 											uint8 request, uint16 value,
368 											uint16 index, uint16 length,
369 											void *data, size_t dataLength,
370 											size_t *actualLength);
371 static	void							SendRequestCallback(void *cookie,
372 											status_t status, void *data,
373 											size_t actualLength);
374 
375 		status_t						QueueRequest(uint8 requestType,
376 											uint8 request, uint16 value,
377 											uint16 index, uint16 length,
378 											void *data, size_t dataLength,
379 											usb_callback_func callback,
380 											void *callbackCookie);
381 
382 private:
383 		mutex							fSendRequestLock;
384 		sem_id							fNotifySem;
385 		status_t						fTransferStatus;
386 		size_t							fActualLength;
387 };
388 
389 
390 class InterruptPipe : public Pipe {
391 public:
392 										InterruptPipe(Object *parent);
393 
394 virtual	uint32							Type() const { return USB_OBJECT_PIPE
395 											| USB_OBJECT_INTERRUPT_PIPE; }
396 virtual	const char *					TypeName() const
397 											{ return "interrupt pipe"; }
398 
399 		status_t						QueueInterrupt(void *data,
400 											size_t dataLength,
401 											usb_callback_func callback,
402 											void *callbackCookie);
403 };
404 
405 
406 class BulkPipe : public Pipe {
407 public:
408 										BulkPipe(Object *parent);
409 
410 virtual	uint32							Type() const { return USB_OBJECT_PIPE
411 											| USB_OBJECT_BULK_PIPE; }
412 virtual	const char *					TypeName() const { return "bulk pipe"; }
413 
414 		status_t						QueueBulk(void *data,
415 											size_t dataLength,
416 											usb_callback_func callback,
417 											void *callbackCookie);
418 		status_t						QueueBulkV(iovec *vector,
419 											size_t vectorCount,
420 											usb_callback_func callback,
421 											void *callbackCookie,
422 											bool physical);
423 };
424 
425 
426 class IsochronousPipe : public Pipe {
427 public:
428 										IsochronousPipe(Object *parent);
429 
430 virtual	uint32							Type() const { return USB_OBJECT_PIPE
431 											| USB_OBJECT_ISO_PIPE; }
432 virtual	const char *					TypeName() const { return "iso pipe"; }
433 
434 		status_t						QueueIsochronous(void *data,
435 											size_t dataLength,
436 											usb_iso_packet_descriptor *
437 												packetDescriptor,
438 											uint32 packetCount,
439 											uint32 *startingFrameNumber,
440 											uint32 flags,
441 											usb_callback_func callback,
442 											void *callbackCookie);
443 
444 		status_t						SetPipePolicy(uint8 maxQueuedPackets,
445 											uint16 maxBufferDurationMS,
446 											uint16 sampleSize);
447 		status_t						GetPipePolicy(uint8 *maxQueuedPackets,
448 											uint16 *maxBufferDurationMS,
449 											uint16 *sampleSize);
450 
451 private:
452 		uint8							fMaxQueuedPackets;
453 		uint16							fMaxBufferDuration;
454 		uint16							fSampleSize;
455 };
456 
457 
458 class Interface : public Object {
459 public:
460 										Interface(Object *parent,
461 											uint8 interfaceIndex);
462 
463 virtual	uint32							Type() const
464 											{ return USB_OBJECT_INTERFACE; }
465 virtual	const char *					TypeName() const { return "interface"; }
466 
467 		// Convenience functions for standard requests
468 virtual	status_t						SetFeature(uint16 selector);
469 virtual	status_t						ClearFeature(uint16 selector);
470 virtual	status_t						GetStatus(uint16 *status);
471 
472 private:
473 		uint8							fInterfaceIndex;
474 };
475 
476 
477 class Device : public Object {
478 public:
479 										Device(Object *parent, int8 hubAddress,
480 											uint8 hubPort,
481 											usb_device_descriptor &desc,
482 											int8 deviceAddress,
483 											usb_speed speed, bool isRootHub,
484 											void *controllerCookie = NULL);
485 virtual									~Device();
486 
487 		status_t						InitCheck();
488 
489 virtual	status_t						Changed(change_item **changeList,
490 											bool added);
491 
492 virtual	uint32							Type() const
493 											{ return USB_OBJECT_DEVICE; }
494 virtual	const char *					TypeName() const { return "device"; }
495 
496 		ControlPipe *					DefaultPipe() const
497 											{ return fDefaultPipe; }
498 
499 virtual	status_t						GetDescriptor(uint8 descriptorType,
500 											uint8 index, uint16 languageID,
501 											void *data, size_t dataLength,
502 											size_t *actualLength);
503 
504 		int8							DeviceAddress() const
505 											{ return fDeviceAddress; }
506 		const usb_device_descriptor *	DeviceDescriptor() const;
507 		usb_speed						Speed() const { return fSpeed; }
508 
509 		const usb_configuration_info *	Configuration() const;
510 		const usb_configuration_info *	ConfigurationAt(uint8 index) const;
511 		status_t						SetConfiguration(
512 											const usb_configuration_info *
513 												configuration);
514 		status_t						SetConfigurationAt(uint8 index);
515 		status_t						Unconfigure(bool atDeviceLevel);
516 
517 		status_t						SetAltInterface(
518 											const usb_interface_info *
519 												interface);
520 
521 		void							InitEndpoints(int32 interfaceIndex);
522 		void							ClearEndpoints(int32 interfaceIndex);
523 
524 virtual	status_t						ReportDevice(
525 											usb_support_descriptor *
526 												supportDescriptors,
527 											uint32 supportDescriptorCount,
528 											const usb_notify_hooks *hooks,
529 											usb_driver_cookie **cookies,
530 											bool added, bool recursive);
531 virtual	status_t						BuildDeviceName(char *string,
532 											uint32 *index, size_t bufferSize,
533 											Device *device);
534 
535 		int8							HubAddress() const
536 											{ return fHubAddress; }
537 		uint8							HubPort() const { return fHubPort; }
538 
539 		void							SetControllerCookie(void *cookie)
540 											{ fControllerCookie = cookie; }
541 		void *							ControllerCookie() const
542 											{ return fControllerCookie; }
543 
544 		// Convenience functions for standard requests
545 virtual	status_t						SetFeature(uint16 selector);
546 virtual	status_t						ClearFeature(uint16 selector);
547 virtual	status_t						GetStatus(uint16 *status);
548 
549 protected:
550 		usb_device_descriptor			fDeviceDescriptor;
551 		bool							fInitOK;
552 
553 private:
554 		bool							fAvailable;
555 		bool							fIsRootHub;
556 		usb_configuration_info *		fConfigurations;
557 		usb_configuration_info *		fCurrentConfiguration;
558 		usb_speed						fSpeed;
559 		int8							fDeviceAddress;
560 		int8							fHubAddress;
561 		uint8							fHubPort;
562 		ControlPipe *					fDefaultPipe;
563 		void *							fControllerCookie;
564 };
565 
566 
567 class Hub : public Device {
568 public:
569 										Hub(Object *parent, int8 hubAddress,
570 											uint8 hubPort,
571 											usb_device_descriptor &desc,
572 											int8 deviceAddress,
573 											usb_speed speed, bool isRootHub);
574 virtual									~Hub();
575 
576 virtual	status_t						Changed(change_item **changeList,
577 											bool added);
578 
579 virtual	uint32							Type() const { return USB_OBJECT_DEVICE
580 											| USB_OBJECT_HUB; }
581 virtual	const char *					TypeName() const { return "hub"; }
582 
583 virtual	status_t						GetDescriptor(uint8 descriptorType,
584 											uint8 index, uint16 languageID,
585 											void *data, size_t dataLength,
586 											size_t *actualLength);
587 
588 		Device *						ChildAt(uint8 index) const
589 											{ return fChildren[index]; }
590 
591 		status_t						UpdatePortStatus(uint8 index);
592 		status_t						ResetPort(uint8 index);
593 		status_t						DisablePort(uint8 index);
594 
595 		void							Explore(change_item **changeList);
596 static	void							InterruptCallback(void *cookie,
597 											status_t status, void *data,
598 											size_t actualLength);
599 
600 virtual	status_t						ReportDevice(
601 											usb_support_descriptor *
602 												supportDescriptors,
603 											uint32 supportDescriptorCount,
604 											const usb_notify_hooks *hooks,
605 											usb_driver_cookie **cookies,
606 											bool added, bool recursive);
607 virtual	status_t						BuildDeviceName(char *string,
608 											uint32 *index, size_t bufferSize,
609 											Device *device);
610 
611 private:
612 		InterruptPipe *					fInterruptPipe;
613 		usb_hub_descriptor				fHubDescriptor;
614 
615 		usb_port_status					fInterruptStatus[USB_MAX_PORT_COUNT];
616 		usb_port_status					fPortStatus[USB_MAX_PORT_COUNT];
617 		Device *						fChildren[USB_MAX_PORT_COUNT];
618 };
619 
620 
621 /*
622  * A Transfer is allocated on the heap and passed to the Host Controller in
623  * SubmitTransfer(). It is generated for all queued transfers. If queuing
624  * succeds (SubmitTransfer() returns with >= B_OK) the Host Controller takes
625  * ownership of the Transfer and will delete it as soon as it has called the
626  * set callback function. If SubmitTransfer() failes, the calling function is
627  * responsible for deleting the Transfer.
628  * Also, the transfer takes ownership of the usb_request_data passed to it in
629  * SetRequestData(), but does not take ownership of the data buffer set by
630  * SetData().
631  */
632 class Transfer {
633 public:
634 									Transfer(Pipe *pipe);
635 									~Transfer();
636 
637 		Pipe *						TransferPipe() const { return fPipe; }
638 
639 		void						SetRequestData(usb_request_data *data);
640 		usb_request_data *			RequestData() const { return fRequestData; }
641 
642 		void						SetIsochronousData(
643 										usb_isochronous_data *data);
644 		usb_isochronous_data *		IsochronousData() const
645 										{ return fIsochronousData; }
646 
647 		void						SetData(uint8 *buffer, size_t length);
648 		uint8 *						Data() const
649 										{ return (uint8 *)fData.iov_base; }
650 		size_t						DataLength() const { return fData.iov_len; }
651 
652 		void						SetPhysical(bool physical);
653 		bool						IsPhysical() const { return fPhysical; }
654 
655 		void						SetVector(iovec *vector,
656 										size_t vectorCount);
657 		iovec *						Vector() { return fVector; }
658 		size_t						VectorCount() const { return fVectorCount; }
659 		size_t						VectorLength();
660 
661 		uint16						Bandwidth() const { return fBandwidth; }
662 
663 		bool						IsFragmented() const { return fFragmented; }
664 		void						AdvanceByFragment(size_t actualLength);
665 
666 		status_t					InitKernelAccess();
667 		status_t					PrepareKernelAccess();
668 
669 		void						SetCallback(usb_callback_func callback,
670 										void *cookie);
671 
672 		void						Finished(uint32 status,
673 										size_t actualLength);
674 
675 		usb_id						USBID() const { return 0; }
676 		const char *				TypeName() const { return "transfer"; }
677 
678 private:
679 		status_t					_CalculateBandwidth();
680 
681 		// Data that is related to the transfer
682 		Pipe *						fPipe;
683 		iovec						fData;
684 		iovec *						fVector;
685 		size_t						fVectorCount;
686 		void *						fBaseAddress;
687 		bool						fPhysical;
688 		bool						fFragmented;
689 		size_t						fActualLength;
690 		area_id						fUserArea;
691 		area_id						fClonedArea;
692 
693 		usb_callback_func			fCallback;
694 		void *						fCallbackCookie;
695 
696 		// For control transfers
697 		usb_request_data *			fRequestData;
698 
699 		// For isochronous transfers
700 		usb_isochronous_data *		fIsochronousData;
701 
702 		// For bandwidth management.
703 		// It contains the bandwidth necessary in microseconds
704 		// for either isochronous, interrupt or control transfers.
705 		// Not used for bulk transactions.
706 		uint16						fBandwidth;
707 };
708 
709 #endif // _USB_PRIVATE_H
710