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