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