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