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