xref: /haiku/src/add-ons/kernel/bus_managers/usb/usb_private.h (revision 9d9aa08a75fd804f5a03c0e617c98179a7ba4297)
1853e6be8SMichael Lotz /*
2853e6be8SMichael Lotz  * Copyright 2003-2006, Haiku Inc. All rights reserved.
3853e6be8SMichael Lotz  * Distributed under the terms of the MIT License.
4853e6be8SMichael Lotz  *
5853e6be8SMichael Lotz  * Authors:
6853e6be8SMichael Lotz  *		Michael Lotz <mmlr@mlotz.ch>
7853e6be8SMichael Lotz  *		Niels S. Reedijk
8853e6be8SMichael Lotz  */
9cc9f959dSMichael Lotz #ifndef _USB_PRIVATE_H
10cc9f959dSMichael Lotz #define _USB_PRIVATE_H
11853e6be8SMichael Lotz 
12e6ce95c5SJérôme Duval 
13e6ce95c5SJérôme Duval #include <device_manager.h>
142c08dd5bSJérôme Duval #include <bus/USB.h>
15e6ce95c5SJérôme Duval 
16cc9f959dSMichael Lotz #include "usbspec_private.h"
17853e6be8SMichael Lotz #include <lock.h>
18*9d9aa08aSAugustin Cavalier #include <Referenceable.h>
190e76cf0bSJérôme Duval #include <util/Vector.h>
2055a46882SAugustin Cavalier 
2155a46882SAugustin Cavalier // include vm.h before iovec_support.h for generic_memcpy, which is used by the bus drivers.
2255a46882SAugustin Cavalier #include <vm/vm.h>
2399626c29SAugustin Cavalier #include <util/iovec_support.h>
24853e6be8SMichael Lotz 
25853e6be8SMichael Lotz 
26853e6be8SMichael Lotz #define TRACE_OUTPUT(x, y, z...) \
27853e6be8SMichael Lotz 	{ \
28d8b4cfc9SRene Gollent 		dprintf("usb %s%s %" B_PRId32 ": ", y, (x)->TypeName(), (x)->USBID()); \
29853e6be8SMichael Lotz 		dprintf(z); \
30853e6be8SMichael Lotz 	}
31853e6be8SMichael Lotz 
32853e6be8SMichael Lotz //#define TRACE_USB
33853e6be8SMichael Lotz #ifdef TRACE_USB
34853e6be8SMichael Lotz #define TRACE(x...)					TRACE_OUTPUT(this, "", x)
35853e6be8SMichael Lotz #define TRACE_STATIC(x, y...)		TRACE_OUTPUT(x, "", y)
36853e6be8SMichael Lotz #define TRACE_MODULE(x...)			dprintf("usb " USB_MODULE_NAME ": " x)
37853e6be8SMichael Lotz #else
38853e6be8SMichael Lotz #define TRACE(x...)					/* nothing */
39853e6be8SMichael Lotz #define TRACE_STATIC(x, y...)		/* nothing */
40853e6be8SMichael Lotz #define TRACE_MODULE(x...)			/* nothing */
41853e6be8SMichael Lotz #endif
42853e6be8SMichael Lotz 
43853e6be8SMichael Lotz #define TRACE_ALWAYS(x...)			TRACE_OUTPUT(this, "", x)
44853e6be8SMichael Lotz #define TRACE_ERROR(x...)			TRACE_OUTPUT(this, "error ", x)
45853e6be8SMichael Lotz #define TRACE_MODULE_ALWAYS(x...)	dprintf("usb " USB_MODULE_NAME ": " x)
46853e6be8SMichael Lotz #define TRACE_MODULE_ERROR(x...)	dprintf("usb " USB_MODULE_NAME ": " x)
47853e6be8SMichael Lotz 
48e6ce95c5SJérôme Duval extern device_manager_info *gDeviceManager;
49e6ce95c5SJérôme Duval 
50e6ce95c5SJérôme Duval 
51853e6be8SMichael Lotz class Hub;
52853e6be8SMichael Lotz class Stack;
53853e6be8SMichael Lotz class Device;
54853e6be8SMichael Lotz class Transfer;
55853e6be8SMichael Lotz class BusManager;
56853e6be8SMichael Lotz class Pipe;
57853e6be8SMichael Lotz class ControlPipe;
58853e6be8SMichael Lotz class Object;
59853e6be8SMichael Lotz class PhysicalMemoryAllocator;
60853e6be8SMichael Lotz 
61853e6be8SMichael Lotz 
62853e6be8SMichael Lotz struct usb_host_controller_info {
63853e6be8SMichael Lotz 	module_info info;
64853e6be8SMichael Lotz 	status_t (*control)(uint32 op, void *data, size_t length);
65853e6be8SMichael Lotz 	status_t (*add_to)(Stack *stack);
66853e6be8SMichael Lotz };
67853e6be8SMichael Lotz 
68853e6be8SMichael Lotz 
69853e6be8SMichael Lotz struct usb_driver_cookie {
70853e6be8SMichael Lotz 	usb_id device;
71853e6be8SMichael Lotz 	void *cookie;
72853e6be8SMichael Lotz 	usb_driver_cookie *link;
73853e6be8SMichael Lotz };
74853e6be8SMichael Lotz 
75853e6be8SMichael Lotz 
76853e6be8SMichael Lotz struct usb_driver_info {
77853e6be8SMichael Lotz 	const char *driver_name;
78853e6be8SMichael Lotz 	usb_support_descriptor *support_descriptors;
79853e6be8SMichael Lotz 	uint32 support_descriptor_count;
80853e6be8SMichael Lotz 	const char *republish_driver_name;
81853e6be8SMichael Lotz 	usb_notify_hooks notify_hooks;
82853e6be8SMichael Lotz 	usb_driver_cookie *cookies;
83853e6be8SMichael Lotz 	usb_driver_info *link;
84853e6be8SMichael Lotz };
85853e6be8SMichael Lotz 
86853e6be8SMichael Lotz 
87853e6be8SMichael Lotz struct change_item {
88853e6be8SMichael Lotz 	bool added;
89853e6be8SMichael Lotz 	Device *device;
90853e6be8SMichael Lotz 	change_item *link;
91853e6be8SMichael Lotz };
92853e6be8SMichael Lotz 
93853e6be8SMichael Lotz 
94853e6be8SMichael Lotz struct rescan_item {
95853e6be8SMichael Lotz 	const char *name;
96853e6be8SMichael Lotz 	rescan_item *link;
97853e6be8SMichael Lotz };
98853e6be8SMichael Lotz 
99853e6be8SMichael Lotz 
100853e6be8SMichael Lotz typedef enum {
101853e6be8SMichael Lotz 	USB_SPEED_LOWSPEED = 0,
102853e6be8SMichael Lotz 	USB_SPEED_FULLSPEED,
103853e6be8SMichael Lotz 	USB_SPEED_HIGHSPEED,
1046e2bbbb1SAugustin Cavalier 	USB_SPEED_SUPERSPEED,
1056aab5c47SJérôme Duval 	USB_SPEED_SUPERSPEEDPLUS,
1066aab5c47SJérôme Duval 	USB_SPEED_MAX = USB_SPEED_SUPERSPEEDPLUS
107853e6be8SMichael Lotz } usb_speed;
108853e6be8SMichael Lotz 
109853e6be8SMichael Lotz 
110853e6be8SMichael Lotz typedef enum {
111853e6be8SMichael Lotz 	USB_CHANGE_CREATED = 0,
112853e6be8SMichael Lotz 	USB_CHANGE_DESTROYED,
113853e6be8SMichael Lotz 	USB_CHANGE_PIPE_POLICY_CHANGED
114853e6be8SMichael Lotz } usb_change;
115853e6be8SMichael Lotz 
116853e6be8SMichael Lotz 
117853e6be8SMichael Lotz #define USB_OBJECT_NONE					0x00000000
118853e6be8SMichael Lotz #define USB_OBJECT_PIPE					0x00000001
119853e6be8SMichael Lotz #define USB_OBJECT_CONTROL_PIPE			0x00000002
120853e6be8SMichael Lotz #define USB_OBJECT_INTERRUPT_PIPE		0x00000004
121853e6be8SMichael Lotz #define USB_OBJECT_BULK_PIPE			0x00000008
122853e6be8SMichael Lotz #define USB_OBJECT_ISO_PIPE				0x00000010
123853e6be8SMichael Lotz #define USB_OBJECT_INTERFACE			0x00000020
124853e6be8SMichael Lotz #define USB_OBJECT_DEVICE				0x00000040
125853e6be8SMichael Lotz #define USB_OBJECT_HUB					0x00000080
126853e6be8SMichael Lotz 
127853e6be8SMichael Lotz 
128853e6be8SMichael Lotz class Stack {
129853e6be8SMichael Lotz public:
130853e6be8SMichael Lotz 										Stack();
131853e6be8SMichael Lotz 										~Stack();
132853e6be8SMichael Lotz 
133853e6be8SMichael Lotz 		status_t						InitCheck();
134853e6be8SMichael Lotz 
135853e6be8SMichael Lotz 		bool							Lock();
136853e6be8SMichael Lotz 		void							Unlock();
137853e6be8SMichael Lotz 
138853e6be8SMichael Lotz 		usb_id							GetUSBID(Object *object);
1391e02632bSAugustin Cavalier 		void							PutUSBID(Object *object);
1405ee91867SAugustin Cavalier 
141f7325a93SAugustin Cavalier 		// Acquires a reference to the object.
142853e6be8SMichael Lotz 		Object *						GetObject(usb_id id);
143853e6be8SMichael Lotz 
144f7325a93SAugustin Cavalier 		// only for the kernel debugger (and doesn't acquire a reference)
14538fc536eSMichael Lotz 		Object *						GetObjectNoLock(usb_id id) const;
146853e6be8SMichael Lotz 
147853e6be8SMichael Lotz 		void							AddBusManager(BusManager *bus);
148c0035251SAugustin Cavalier 		int32							IndexOfBusManager(BusManager *bus) const;
14938fc536eSMichael Lotz 		BusManager *					BusManagerAt(int32 index) const;
150853e6be8SMichael Lotz 
151853e6be8SMichael Lotz 		status_t						AllocateChunk(void **logicalAddress,
152d8b4cfc9SRene Gollent 											phys_addr_t *physicalAddress,
15319b8f8a0SMichael Lotz 											size_t size);
154853e6be8SMichael Lotz 		status_t						FreeChunk(void *logicalAddress,
155d8b4cfc9SRene Gollent 											phys_addr_t physicalAddress,
156d8b4cfc9SRene Gollent 											size_t size);
157853e6be8SMichael Lotz 
158853e6be8SMichael Lotz 		area_id							AllocateArea(void **logicalAddress,
159d8b4cfc9SRene Gollent 											phys_addr_t *physicalAddress,
160853e6be8SMichael Lotz 											size_t size, const char *name);
161853e6be8SMichael Lotz 
162853e6be8SMichael Lotz 		void							NotifyDeviceChange(Device *device,
163853e6be8SMichael Lotz 											rescan_item **rescanList,
164853e6be8SMichael Lotz 											bool added);
165853e6be8SMichael Lotz 		void							RescanDrivers(rescan_item *rescanItem);
166853e6be8SMichael Lotz 
167853e6be8SMichael Lotz 		// USB API
168853e6be8SMichael Lotz 		status_t						RegisterDriver(const char *driverName,
16919b8f8a0SMichael Lotz 											const usb_support_descriptor *
17019b8f8a0SMichael Lotz 												descriptors,
171853e6be8SMichael Lotz 											size_t descriptorCount,
172853e6be8SMichael Lotz 											const char *republishDriverName);
173853e6be8SMichael Lotz 
174853e6be8SMichael Lotz 		status_t						InstallNotify(const char *driverName,
175853e6be8SMichael Lotz 											const usb_notify_hooks *hooks);
176853e6be8SMichael Lotz 		status_t						UninstallNotify(const char *driverName);
177853e6be8SMichael Lotz 
USBID()17819b8f8a0SMichael Lotz 		usb_id							USBID() const { return 0; }
TypeName()17919b8f8a0SMichael Lotz 		const char *					TypeName() const { return "stack"; }
180853e6be8SMichael Lotz 
1817c18d58fSJérôme Duval 		void							Explore();
1823f7abfc9SJérôme Duval 
183853e6be8SMichael Lotz private:
184853e6be8SMichael Lotz static	int32							ExploreThread(void *data);
185853e6be8SMichael Lotz 
186853e6be8SMichael Lotz 		Vector<BusManager *>			fBusManagers;
187853e6be8SMichael Lotz 		thread_id						fExploreThread;
1883f7abfc9SJérôme Duval 		sem_id							fExploreSem;
189853e6be8SMichael Lotz 
190853e6be8SMichael Lotz 		mutex							fStackLock;
191853e6be8SMichael Lotz 		mutex							fExploreLock;
192853e6be8SMichael Lotz 		PhysicalMemoryAllocator *		fAllocator;
193853e6be8SMichael Lotz 
194853e6be8SMichael Lotz 		uint32							fObjectIndex;
195853e6be8SMichael Lotz 		uint32							fObjectMaxCount;
196853e6be8SMichael Lotz 		Object **						fObjectArray;
197853e6be8SMichael Lotz 
198853e6be8SMichael Lotz 		usb_driver_info *				fDriverList;
199853e6be8SMichael Lotz };
200853e6be8SMichael Lotz 
201853e6be8SMichael Lotz 
202853e6be8SMichael Lotz /*
203853e6be8SMichael Lotz  * This class manages a bus. It is created by the Stack object
204853e6be8SMichael Lotz  * after a host controller gives positive feedback on whether the hardware
205853e6be8SMichael Lotz  * is found.
206853e6be8SMichael Lotz  */
207853e6be8SMichael Lotz class BusManager {
208853e6be8SMichael Lotz public:
209e6ce95c5SJérôme Duval 										BusManager(Stack *stack, device_node* node);
210853e6be8SMichael Lotz virtual									~BusManager();
211853e6be8SMichael Lotz 
212853e6be8SMichael Lotz virtual	status_t						InitCheck();
213853e6be8SMichael Lotz 
214853e6be8SMichael Lotz 		bool							Lock();
215853e6be8SMichael Lotz 		void							Unlock();
216853e6be8SMichael Lotz 
217853e6be8SMichael Lotz 		int8							AllocateAddress();
218853e6be8SMichael Lotz 		void							FreeAddress(int8 address);
219853e6be8SMichael Lotz 
220319a3798SJérôme Duval virtual	Device *						AllocateDevice(Hub *parent,
221853e6be8SMichael Lotz 											int8 hubAddress, uint8 hubPort,
222853e6be8SMichael Lotz 											usb_speed speed);
223319a3798SJérôme Duval virtual void							FreeDevice(Device *device);
224853e6be8SMichael Lotz 
225853e6be8SMichael Lotz virtual	status_t						Start();
226853e6be8SMichael Lotz virtual	status_t						Stop();
227853e6be8SMichael Lotz 
228159aa93bSMichael Lotz virtual	status_t						StartDebugTransfer(Transfer *transfer);
229159aa93bSMichael Lotz virtual	status_t						CheckDebugTransfer(Transfer *transfer);
230159aa93bSMichael Lotz virtual	void							CancelDebugTransfer(Transfer *transfer);
231159aa93bSMichael Lotz 
232853e6be8SMichael Lotz virtual	status_t						SubmitTransfer(Transfer *transfer);
233853e6be8SMichael Lotz virtual	status_t						CancelQueuedTransfers(Pipe *pipe,
234853e6be8SMichael Lotz 											bool force);
235853e6be8SMichael Lotz 
236853e6be8SMichael Lotz virtual	status_t						NotifyPipeChange(Pipe *pipe,
237853e6be8SMichael Lotz 											usb_change change);
238853e6be8SMichael Lotz 
RootObject()23919b8f8a0SMichael Lotz 		Object *						RootObject() const
24019b8f8a0SMichael Lotz 											{ return fRootObject; }
241853e6be8SMichael Lotz 
GetRootHub()24219b8f8a0SMichael Lotz 		Hub *							GetRootHub() const { return fRootHub; }
SetRootHub(Hub * hub)24319b8f8a0SMichael Lotz 		void							SetRootHub(Hub *hub) { fRootHub = hub; }
244853e6be8SMichael Lotz 
24538fc536eSMichael Lotz virtual	const char *					TypeName() const = 0;
246853e6be8SMichael Lotz 
Node()247e6ce95c5SJérôme Duval 		device_node *					Node() const
248e6ce95c5SJérôme Duval 											{ return fNode; }
249853e6be8SMichael Lotz protected:
USBID()250decd5b8fSAugustin Cavalier 		usb_id							USBID() const { return fStackIndex; }
251decd5b8fSAugustin Cavalier 
252decd5b8fSAugustin Cavalier protected:
253853e6be8SMichael Lotz 		bool							fInitOK;
254853e6be8SMichael Lotz 
255853e6be8SMichael Lotz private:
256853e6be8SMichael Lotz 		ControlPipe *					_GetDefaultPipe(usb_speed);
257853e6be8SMichael Lotz 
258853e6be8SMichael Lotz 		mutex							fLock;
259853e6be8SMichael Lotz 
260853e6be8SMichael Lotz 		bool							fDeviceMap[128];
261853e6be8SMichael Lotz 		int8							fDeviceIndex;
262853e6be8SMichael Lotz 
263853e6be8SMichael Lotz 		Stack *							fStack;
264853e6be8SMichael Lotz 		ControlPipe *					fDefaultPipes[USB_SPEED_MAX + 1];
265853e6be8SMichael Lotz 		Hub *							fRootHub;
266853e6be8SMichael Lotz 		Object *						fRootObject;
26719b8f8a0SMichael Lotz 
268decd5b8fSAugustin Cavalier 		usb_id							fStackIndex;
269e6ce95c5SJérôme Duval 
270e6ce95c5SJérôme Duval 		device_node*					fNode;
271853e6be8SMichael Lotz };
272853e6be8SMichael Lotz 
273853e6be8SMichael Lotz 
274f7325a93SAugustin Cavalier class Object : public BReferenceable {
275853e6be8SMichael Lotz public:
276853e6be8SMichael Lotz 										Object(Stack *stack, BusManager *bus);
277853e6be8SMichael Lotz 										Object(Object *parent);
278853e6be8SMichael Lotz virtual									~Object();
279853e6be8SMichael Lotz 
Parent()28019b8f8a0SMichael Lotz 		Object *						Parent() const { return fParent; }
281853e6be8SMichael Lotz 
GetBusManager()28219b8f8a0SMichael Lotz 		BusManager *					GetBusManager() const
28319b8f8a0SMichael Lotz 											{ return fBusManager; }
GetStack()28419b8f8a0SMichael Lotz 		Stack *							GetStack() const { return fStack; }
285853e6be8SMichael Lotz 
USBID()28619b8f8a0SMichael Lotz 		usb_id							USBID() const { return fUSBID; }
2875ee91867SAugustin Cavalier 
Type()28819b8f8a0SMichael Lotz virtual	uint32							Type() const { return USB_OBJECT_NONE; }
TypeName()28919b8f8a0SMichael Lotz virtual	const char *					TypeName() const { return "object"; }
290853e6be8SMichael Lotz 
291853e6be8SMichael Lotz 		// Convenience functions for standard requests
292853e6be8SMichael Lotz virtual	status_t						SetFeature(uint16 selector);
293853e6be8SMichael Lotz virtual	status_t						ClearFeature(uint16 selector);
294853e6be8SMichael Lotz virtual	status_t						GetStatus(uint16 *status);
295853e6be8SMichael Lotz 
2961e02632bSAugustin Cavalier protected:
297f7325a93SAugustin Cavalier 		void							PutUSBID(bool waitForIdle = true);
298f7325a93SAugustin Cavalier 		void							WaitForIdle();
2991e02632bSAugustin Cavalier 
300853e6be8SMichael Lotz private:
301853e6be8SMichael Lotz 		Object *						fParent;
302853e6be8SMichael Lotz 		BusManager *					fBusManager;
303853e6be8SMichael Lotz 		Stack *							fStack;
304853e6be8SMichael Lotz 		usb_id							fUSBID;
305853e6be8SMichael Lotz };
306853e6be8SMichael Lotz 
307853e6be8SMichael Lotz 
308853e6be8SMichael Lotz /*
309853e6be8SMichael Lotz  * The Pipe class is the communication management between the hardware and
310853e6be8SMichael Lotz  * the stack. It creates packets, manages these and performs callbacks.
311853e6be8SMichael Lotz  */
312853e6be8SMichael Lotz class Pipe : public Object {
313853e6be8SMichael Lotz public:
314853e6be8SMichael Lotz 		enum pipeDirection { In, Out, Default };
315853e6be8SMichael Lotz 
316853e6be8SMichael Lotz 										Pipe(Object *parent);
317853e6be8SMichael Lotz virtual									~Pipe();
318853e6be8SMichael Lotz 
319334c06aeSJérôme Duval virtual	void							InitCommon(int8 deviceAddress,
320853e6be8SMichael Lotz 											uint8 endpointAddress,
321853e6be8SMichael Lotz 											usb_speed speed,
322853e6be8SMichael Lotz 											pipeDirection direction,
323853e6be8SMichael Lotz 											size_t maxPacketSize,
324853e6be8SMichael Lotz 											uint8 interval,
325853e6be8SMichael Lotz 											int8 hubAddress, uint8 hubPort);
326086528f6SAugustin Cavalier virtual void							InitSuperSpeed(uint8 maxBurst,
327086528f6SAugustin Cavalier 											uint16 bytesPerInterval);
328853e6be8SMichael Lotz 
Type()32919b8f8a0SMichael Lotz virtual	uint32							Type() const { return USB_OBJECT_PIPE; }
TypeName()33019b8f8a0SMichael Lotz virtual	const char *					TypeName() const { return "pipe"; }
331853e6be8SMichael Lotz 
DeviceAddress()33219b8f8a0SMichael Lotz 		int8							DeviceAddress() const
33319b8f8a0SMichael Lotz 											{ return fDeviceAddress; }
Speed()33419b8f8a0SMichael Lotz 		usb_speed						Speed() const { return fSpeed; }
Direction()33519b8f8a0SMichael Lotz 		pipeDirection					Direction() const { return fDirection; }
EndpointAddress()33619b8f8a0SMichael Lotz 		uint8							EndpointAddress() const
33719b8f8a0SMichael Lotz 											{ return fEndpointAddress; }
MaxPacketSize()33819b8f8a0SMichael Lotz 		size_t							MaxPacketSize() const
33919b8f8a0SMichael Lotz 											{ return fMaxPacketSize; }
Interval()34019b8f8a0SMichael Lotz 		uint8							Interval() const { return fInterval; }
341853e6be8SMichael Lotz 
342086528f6SAugustin Cavalier 		// SuperSpeed-only parameters
MaxBurst()343086528f6SAugustin Cavalier 		uint8							MaxBurst() const
344086528f6SAugustin Cavalier 											{ return fMaxBurst; }
BytesPerInterval()345086528f6SAugustin Cavalier 		uint16							BytesPerInterval() const
346086528f6SAugustin Cavalier 											{ return fBytesPerInterval; }
347086528f6SAugustin Cavalier 
348853e6be8SMichael Lotz 		// Hub port being the one-based logical port number on the hub
349853e6be8SMichael Lotz 		void							SetHubInfo(int8 address, uint8 port);
HubAddress()35019b8f8a0SMichael Lotz 		int8							HubAddress() const
35119b8f8a0SMichael Lotz 											{ return fHubAddress; }
HubPort()35219b8f8a0SMichael Lotz 		uint8							HubPort() const { return fHubPort; }
353853e6be8SMichael Lotz 
DataToggle()35419b8f8a0SMichael Lotz virtual	bool							DataToggle() const
35519b8f8a0SMichael Lotz 											{ return fDataToggle; }
SetDataToggle(bool toggle)35619b8f8a0SMichael Lotz virtual	void							SetDataToggle(bool toggle)
35719b8f8a0SMichael Lotz 											{ fDataToggle = toggle; }
358853e6be8SMichael Lotz 
359853e6be8SMichael Lotz 		status_t						SubmitTransfer(Transfer *transfer);
3602f496b30SAugustin Cavalier virtual	status_t						CancelQueuedTransfers(bool force);
361853e6be8SMichael Lotz 
SetControllerCookie(void * cookie)36219b8f8a0SMichael Lotz 		void							SetControllerCookie(void *cookie)
36319b8f8a0SMichael Lotz 											{ fControllerCookie = cookie; }
ControllerCookie()36419b8f8a0SMichael Lotz 		void *							ControllerCookie() const
36519b8f8a0SMichael Lotz 											{ return fControllerCookie; }
366853e6be8SMichael Lotz 
367853e6be8SMichael Lotz 		// Convenience functions for standard requests
368853e6be8SMichael Lotz virtual	status_t						SetFeature(uint16 selector);
369853e6be8SMichael Lotz virtual	status_t						ClearFeature(uint16 selector);
370853e6be8SMichael Lotz virtual	status_t						GetStatus(uint16 *status);
371853e6be8SMichael Lotz 
37283825112SAugustin Cavalier protected:
37383825112SAugustin Cavalier 		friend class					Device;
37483825112SAugustin Cavalier 
375853e6be8SMichael Lotz private:
376853e6be8SMichael Lotz 		int8							fDeviceAddress;
377853e6be8SMichael Lotz 		uint8							fEndpointAddress;
378853e6be8SMichael Lotz 		pipeDirection					fDirection;
379853e6be8SMichael Lotz 		usb_speed						fSpeed;
380853e6be8SMichael Lotz 		size_t							fMaxPacketSize;
381853e6be8SMichael Lotz 		uint8							fInterval;
382086528f6SAugustin Cavalier 		uint8							fMaxBurst;
383086528f6SAugustin Cavalier 		uint16							fBytesPerInterval;
384853e6be8SMichael Lotz 		int8							fHubAddress;
385853e6be8SMichael Lotz 		uint8							fHubPort;
386853e6be8SMichael Lotz 		bool							fDataToggle;
387853e6be8SMichael Lotz 		void *							fControllerCookie;
388853e6be8SMichael Lotz };
389853e6be8SMichael Lotz 
390853e6be8SMichael Lotz 
391853e6be8SMichael Lotz class ControlPipe : public Pipe {
392853e6be8SMichael Lotz public:
393853e6be8SMichael Lotz 										ControlPipe(Object *parent);
394853e6be8SMichael Lotz virtual									~ControlPipe();
395853e6be8SMichael Lotz 
396b62bb24fSMichael Lotz virtual	void							InitCommon(int8 deviceAddress,
397b62bb24fSMichael Lotz 											uint8 endpointAddress,
398b62bb24fSMichael Lotz 											usb_speed speed,
399b62bb24fSMichael Lotz 											pipeDirection direction,
400b62bb24fSMichael Lotz 											size_t maxPacketSize,
401b62bb24fSMichael Lotz 											uint8 interval,
402b62bb24fSMichael Lotz 											int8 hubAddress, uint8 hubPort);
403b62bb24fSMichael Lotz 
Type()40419b8f8a0SMichael Lotz virtual	uint32							Type() const { return USB_OBJECT_PIPE
40519b8f8a0SMichael Lotz 											| USB_OBJECT_CONTROL_PIPE; }
TypeName()40619b8f8a0SMichael Lotz virtual	const char *					TypeName() const
40719b8f8a0SMichael Lotz 											{ return "control pipe"; }
408853e6be8SMichael Lotz 
409853e6be8SMichael Lotz 										// The data toggle is not relevant
410853e6be8SMichael Lotz 										// for control transfers, as they are
411853e6be8SMichael Lotz 										// always enclosed by a setup and
412853e6be8SMichael Lotz 										// status packet. The toggle always
413853e6be8SMichael Lotz 										// starts at 1.
DataToggle()41419b8f8a0SMichael Lotz virtual	bool							DataToggle() const { return true; }
SetDataToggle(bool toggle)41538fc536eSMichael Lotz virtual	void							SetDataToggle(bool toggle) {}
416853e6be8SMichael Lotz 
417853e6be8SMichael Lotz 		status_t						SendRequest(uint8 requestType,
418853e6be8SMichael Lotz 											uint8 request, uint16 value,
419853e6be8SMichael Lotz 											uint16 index, uint16 length,
420853e6be8SMichael Lotz 											void *data, size_t dataLength,
421853e6be8SMichael Lotz 											size_t *actualLength);
422853e6be8SMichael Lotz static	void							SendRequestCallback(void *cookie,
423853e6be8SMichael Lotz 											status_t status, void *data,
424853e6be8SMichael Lotz 											size_t actualLength);
425853e6be8SMichael Lotz 
426853e6be8SMichael Lotz 		status_t						QueueRequest(uint8 requestType,
427853e6be8SMichael Lotz 											uint8 request, uint16 value,
428853e6be8SMichael Lotz 											uint16 index, uint16 length,
429853e6be8SMichael Lotz 											void *data, size_t dataLength,
430853e6be8SMichael Lotz 											usb_callback_func callback,
431853e6be8SMichael Lotz 											void *callbackCookie);
432853e6be8SMichael Lotz 
4332f496b30SAugustin Cavalier virtual	status_t						CancelQueuedTransfers(bool force);
4342f496b30SAugustin Cavalier 
435853e6be8SMichael Lotz private:
436853e6be8SMichael Lotz 		mutex							fSendRequestLock;
437853e6be8SMichael Lotz 		sem_id							fNotifySem;
438853e6be8SMichael Lotz 		status_t						fTransferStatus;
439853e6be8SMichael Lotz 		size_t							fActualLength;
440853e6be8SMichael Lotz };
441853e6be8SMichael Lotz 
442853e6be8SMichael Lotz 
443853e6be8SMichael Lotz class InterruptPipe : public Pipe {
444853e6be8SMichael Lotz public:
445853e6be8SMichael Lotz 										InterruptPipe(Object *parent);
446853e6be8SMichael Lotz 
Type()44719b8f8a0SMichael Lotz virtual	uint32							Type() const { return USB_OBJECT_PIPE
44819b8f8a0SMichael Lotz 											| USB_OBJECT_INTERRUPT_PIPE; }
TypeName()44919b8f8a0SMichael Lotz virtual	const char *					TypeName() const
45019b8f8a0SMichael Lotz 											{ return "interrupt pipe"; }
451853e6be8SMichael Lotz 
452853e6be8SMichael Lotz 		status_t						QueueInterrupt(void *data,
453853e6be8SMichael Lotz 											size_t dataLength,
454853e6be8SMichael Lotz 											usb_callback_func callback,
455853e6be8SMichael Lotz 											void *callbackCookie);
456853e6be8SMichael Lotz };
457853e6be8SMichael Lotz 
458853e6be8SMichael Lotz 
459853e6be8SMichael Lotz class BulkPipe : public Pipe {
460853e6be8SMichael Lotz public:
461853e6be8SMichael Lotz 										BulkPipe(Object *parent);
462853e6be8SMichael Lotz 
463334c06aeSJérôme Duval virtual	void							InitCommon(int8 deviceAddress,
464334c06aeSJérôme Duval 											uint8 endpointAddress,
465334c06aeSJérôme Duval 											usb_speed speed,
466334c06aeSJérôme Duval 											pipeDirection direction,
467334c06aeSJérôme Duval 											size_t maxPacketSize,
468334c06aeSJérôme Duval 											uint8 interval,
469334c06aeSJérôme Duval 											int8 hubAddress, uint8 hubPort);
470334c06aeSJérôme Duval 
Type()47119b8f8a0SMichael Lotz virtual	uint32							Type() const { return USB_OBJECT_PIPE
47219b8f8a0SMichael Lotz 											| USB_OBJECT_BULK_PIPE; }
TypeName()47319b8f8a0SMichael Lotz virtual	const char *					TypeName() const { return "bulk pipe"; }
474853e6be8SMichael Lotz 
475853e6be8SMichael Lotz 		status_t						QueueBulk(void *data,
476853e6be8SMichael Lotz 											size_t dataLength,
477853e6be8SMichael Lotz 											usb_callback_func callback,
478853e6be8SMichael Lotz 											void *callbackCookie);
47955a46882SAugustin Cavalier 		status_t						QueueBulkV(iovec *vector, size_t vectorCount,
48055a46882SAugustin Cavalier 											usb_callback_func callback, void *callbackCookie);
48155a46882SAugustin Cavalier 		status_t						QueueBulkV(physical_entry *vector, size_t vectorCount,
48255a46882SAugustin Cavalier 											usb_callback_func callback, void *callbackCookie);};
483853e6be8SMichael Lotz 
484853e6be8SMichael Lotz 
485853e6be8SMichael Lotz class IsochronousPipe : public Pipe {
486853e6be8SMichael Lotz public:
487853e6be8SMichael Lotz 										IsochronousPipe(Object *parent);
488853e6be8SMichael Lotz 
Type()48919b8f8a0SMichael Lotz virtual	uint32							Type() const { return USB_OBJECT_PIPE
49019b8f8a0SMichael Lotz 											| USB_OBJECT_ISO_PIPE; }
TypeName()49119b8f8a0SMichael Lotz virtual	const char *					TypeName() const { return "iso pipe"; }
492853e6be8SMichael Lotz 
493853e6be8SMichael Lotz 		status_t						QueueIsochronous(void *data,
494853e6be8SMichael Lotz 											size_t dataLength,
49519b8f8a0SMichael Lotz 											usb_iso_packet_descriptor *
49619b8f8a0SMichael Lotz 												packetDescriptor,
497853e6be8SMichael Lotz 											uint32 packetCount,
498853e6be8SMichael Lotz 											uint32 *startingFrameNumber,
499853e6be8SMichael Lotz 											uint32 flags,
500853e6be8SMichael Lotz 											usb_callback_func callback,
501853e6be8SMichael Lotz 											void *callbackCookie);
502853e6be8SMichael Lotz 
503853e6be8SMichael Lotz 		status_t						SetPipePolicy(uint8 maxQueuedPackets,
504853e6be8SMichael Lotz 											uint16 maxBufferDurationMS,
505853e6be8SMichael Lotz 											uint16 sampleSize);
506853e6be8SMichael Lotz 		status_t						GetPipePolicy(uint8 *maxQueuedPackets,
507853e6be8SMichael Lotz 											uint16 *maxBufferDurationMS,
508853e6be8SMichael Lotz 											uint16 *sampleSize);
509853e6be8SMichael Lotz 
510853e6be8SMichael Lotz private:
511853e6be8SMichael Lotz 		uint8							fMaxQueuedPackets;
512853e6be8SMichael Lotz 		uint16							fMaxBufferDuration;
513853e6be8SMichael Lotz 		uint16							fSampleSize;
514853e6be8SMichael Lotz };
515853e6be8SMichael Lotz 
516853e6be8SMichael Lotz 
517853e6be8SMichael Lotz class Interface : public Object {
518853e6be8SMichael Lotz public:
519853e6be8SMichael Lotz 										Interface(Object *parent,
520853e6be8SMichael Lotz 											uint8 interfaceIndex);
521853e6be8SMichael Lotz 
Type()52219b8f8a0SMichael Lotz virtual	uint32							Type() const
52319b8f8a0SMichael Lotz 											{ return USB_OBJECT_INTERFACE; }
TypeName()52419b8f8a0SMichael Lotz virtual	const char *					TypeName() const { return "interface"; }
525853e6be8SMichael Lotz 
526853e6be8SMichael Lotz 		// Convenience functions for standard requests
527853e6be8SMichael Lotz virtual	status_t						SetFeature(uint16 selector);
528853e6be8SMichael Lotz virtual	status_t						ClearFeature(uint16 selector);
529853e6be8SMichael Lotz virtual	status_t						GetStatus(uint16 *status);
530853e6be8SMichael Lotz 
531853e6be8SMichael Lotz private:
532853e6be8SMichael Lotz 		uint8							fInterfaceIndex;
533853e6be8SMichael Lotz };
534853e6be8SMichael Lotz 
535853e6be8SMichael Lotz 
536853e6be8SMichael Lotz class Device : public Object {
537853e6be8SMichael Lotz public:
538853e6be8SMichael Lotz 										Device(Object *parent, int8 hubAddress,
539853e6be8SMichael Lotz 											uint8 hubPort,
540853e6be8SMichael Lotz 											usb_device_descriptor &desc,
541853e6be8SMichael Lotz 											int8 deviceAddress,
5422b31b4a8SJérôme Duval 											usb_speed speed, bool isRootHub,
5432b31b4a8SJérôme Duval 											void *controllerCookie = NULL);
544853e6be8SMichael Lotz virtual									~Device();
545853e6be8SMichael Lotz 
546853e6be8SMichael Lotz 		status_t						InitCheck();
547853e6be8SMichael Lotz 
548853e6be8SMichael Lotz virtual	status_t						Changed(change_item **changeList,
549853e6be8SMichael Lotz 											bool added);
550853e6be8SMichael Lotz 
Type()55119b8f8a0SMichael Lotz virtual	uint32							Type() const
55219b8f8a0SMichael Lotz 											{ return USB_OBJECT_DEVICE; }
TypeName()55319b8f8a0SMichael Lotz virtual	const char *					TypeName() const { return "device"; }
554853e6be8SMichael Lotz 
DefaultPipe()55519b8f8a0SMichael Lotz 		ControlPipe *					DefaultPipe() const
55619b8f8a0SMichael Lotz 											{ return fDefaultPipe; }
557853e6be8SMichael Lotz 
558853e6be8SMichael Lotz virtual	status_t						GetDescriptor(uint8 descriptorType,
559853e6be8SMichael Lotz 											uint8 index, uint16 languageID,
560853e6be8SMichael Lotz 											void *data, size_t dataLength,
561853e6be8SMichael Lotz 											size_t *actualLength);
562853e6be8SMichael Lotz 
DeviceAddress()56319b8f8a0SMichael Lotz 		int8							DeviceAddress() const
56419b8f8a0SMichael Lotz 											{ return fDeviceAddress; }
565853e6be8SMichael Lotz 		const usb_device_descriptor *	DeviceDescriptor() const;
Speed()56619b8f8a0SMichael Lotz 		usb_speed						Speed() const { return fSpeed; }
567853e6be8SMichael Lotz 
568853e6be8SMichael Lotz 		const usb_configuration_info *	Configuration() const;
569853e6be8SMichael Lotz 		const usb_configuration_info *	ConfigurationAt(uint8 index) const;
57019b8f8a0SMichael Lotz 		status_t						SetConfiguration(
57119b8f8a0SMichael Lotz 											const usb_configuration_info *
57219b8f8a0SMichael Lotz 												configuration);
573853e6be8SMichael Lotz 		status_t						SetConfigurationAt(uint8 index);
574853e6be8SMichael Lotz 		status_t						Unconfigure(bool atDeviceLevel);
575853e6be8SMichael Lotz 
57619b8f8a0SMichael Lotz 		status_t						SetAltInterface(
57719b8f8a0SMichael Lotz 											const usb_interface_info *
57819b8f8a0SMichael Lotz 												interface);
579853e6be8SMichael Lotz 
580853e6be8SMichael Lotz 		void							InitEndpoints(int32 interfaceIndex);
581853e6be8SMichael Lotz 		void							ClearEndpoints(int32 interfaceIndex);
582853e6be8SMichael Lotz 
583853e6be8SMichael Lotz virtual	status_t						ReportDevice(
58419b8f8a0SMichael Lotz 											usb_support_descriptor *
58519b8f8a0SMichael Lotz 												supportDescriptors,
586853e6be8SMichael Lotz 											uint32 supportDescriptorCount,
587853e6be8SMichael Lotz 											const usb_notify_hooks *hooks,
588853e6be8SMichael Lotz 											usb_driver_cookie **cookies,
589853e6be8SMichael Lotz 											bool added, bool recursive);
590853e6be8SMichael Lotz virtual	status_t						BuildDeviceName(char *string,
591853e6be8SMichael Lotz 											uint32 *index, size_t bufferSize,
592853e6be8SMichael Lotz 											Device *device);
593853e6be8SMichael Lotz 
594e6ce95c5SJérôme Duval 		device_node *					RegisterNode(device_node* parent = NULL);
595e6ce95c5SJérôme Duval 
HubAddress()59619b8f8a0SMichael Lotz 		int8							HubAddress() const
59719b8f8a0SMichael Lotz 											{ return fHubAddress; }
HubPort()59819b8f8a0SMichael Lotz 		uint8							HubPort() const { return fHubPort; }
599853e6be8SMichael Lotz 
SetControllerCookie(void * cookie)6002b31b4a8SJérôme Duval 		void							SetControllerCookie(void *cookie)
6012b31b4a8SJérôme Duval 											{ fControllerCookie = cookie; }
ControllerCookie()6022b31b4a8SJérôme Duval 		void *							ControllerCookie() const
6032b31b4a8SJérôme Duval 											{ return fControllerCookie; }
Node()604e6ce95c5SJérôme Duval 		device_node *					Node() const
605e6ce95c5SJérôme Duval 											{ return fNode; }
SetNode(device_node * node)606e6ce95c5SJérôme Duval 		void							SetNode(device_node* node) { fNode = node; }
6072b31b4a8SJérôme Duval 
608853e6be8SMichael Lotz 		// Convenience functions for standard requests
609853e6be8SMichael Lotz virtual	status_t						SetFeature(uint16 selector);
610853e6be8SMichael Lotz virtual	status_t						ClearFeature(uint16 selector);
611853e6be8SMichael Lotz virtual	status_t						GetStatus(uint16 *status);
612853e6be8SMichael Lotz 
613853e6be8SMichael Lotz protected:
614853e6be8SMichael Lotz 		usb_device_descriptor			fDeviceDescriptor;
615853e6be8SMichael Lotz 		bool							fInitOK;
616853e6be8SMichael Lotz 
617853e6be8SMichael Lotz private:
618853e6be8SMichael Lotz 		bool							fAvailable;
619853e6be8SMichael Lotz 		bool							fIsRootHub;
620853e6be8SMichael Lotz 		usb_configuration_info *		fConfigurations;
621853e6be8SMichael Lotz 		usb_configuration_info *		fCurrentConfiguration;
622853e6be8SMichael Lotz 		usb_speed						fSpeed;
623853e6be8SMichael Lotz 		int8							fDeviceAddress;
624853e6be8SMichael Lotz 		int8							fHubAddress;
625853e6be8SMichael Lotz 		uint8							fHubPort;
626853e6be8SMichael Lotz 		ControlPipe *					fDefaultPipe;
6272b31b4a8SJérôme Duval 		void *							fControllerCookie;
628e6ce95c5SJérôme Duval 		device_node*					fNode;
629853e6be8SMichael Lotz };
630853e6be8SMichael Lotz 
631853e6be8SMichael Lotz 
632853e6be8SMichael Lotz class Hub : public Device {
633853e6be8SMichael Lotz public:
634853e6be8SMichael Lotz 										Hub(Object *parent, int8 hubAddress,
635853e6be8SMichael Lotz 											uint8 hubPort,
636853e6be8SMichael Lotz 											usb_device_descriptor &desc,
637853e6be8SMichael Lotz 											int8 deviceAddress,
63817aa359bSAkshay Jaggi 											usb_speed speed, bool isRootHub,
63917aa359bSAkshay Jaggi 											void *controllerCookie = NULL);
640853e6be8SMichael Lotz virtual									~Hub();
641853e6be8SMichael Lotz 
642853e6be8SMichael Lotz virtual	status_t						Changed(change_item **changeList,
643853e6be8SMichael Lotz 											bool added);
644853e6be8SMichael Lotz 
Type()64519b8f8a0SMichael Lotz virtual	uint32							Type() const { return USB_OBJECT_DEVICE
64619b8f8a0SMichael Lotz 											| USB_OBJECT_HUB; }
TypeName()64719b8f8a0SMichael Lotz virtual	const char *					TypeName() const { return "hub"; }
648853e6be8SMichael Lotz 
649853e6be8SMichael Lotz virtual	status_t						GetDescriptor(uint8 descriptorType,
650853e6be8SMichael Lotz 											uint8 index, uint16 languageID,
651853e6be8SMichael Lotz 											void *data, size_t dataLength,
652853e6be8SMichael Lotz 											size_t *actualLength);
653853e6be8SMichael Lotz 
ChildAt(uint8 index)65419b8f8a0SMichael Lotz 		Device *						ChildAt(uint8 index) const
65519b8f8a0SMichael Lotz 											{ return fChildren[index]; }
656853e6be8SMichael Lotz 
657853e6be8SMichael Lotz 		status_t						UpdatePortStatus(uint8 index);
658853e6be8SMichael Lotz 		status_t						ResetPort(uint8 index);
659853e6be8SMichael Lotz 		status_t						DisablePort(uint8 index);
660853e6be8SMichael Lotz 
661853e6be8SMichael Lotz 		void							Explore(change_item **changeList);
662853e6be8SMichael Lotz static	void							InterruptCallback(void *cookie,
663853e6be8SMichael Lotz 											status_t status, void *data,
664853e6be8SMichael Lotz 											size_t actualLength);
665853e6be8SMichael Lotz 
666853e6be8SMichael Lotz virtual	status_t						ReportDevice(
66719b8f8a0SMichael Lotz 											usb_support_descriptor *
66819b8f8a0SMichael Lotz 												supportDescriptors,
669853e6be8SMichael Lotz 											uint32 supportDescriptorCount,
670853e6be8SMichael Lotz 											const usb_notify_hooks *hooks,
671853e6be8SMichael Lotz 											usb_driver_cookie **cookies,
672853e6be8SMichael Lotz 											bool added, bool recursive);
673853e6be8SMichael Lotz virtual	status_t						BuildDeviceName(char *string,
674853e6be8SMichael Lotz 											uint32 *index, size_t bufferSize,
675853e6be8SMichael Lotz 											Device *device);
676853e6be8SMichael Lotz 
677853e6be8SMichael Lotz private:
678827c7224SMichael Lotz 		status_t						_DebouncePort(uint8 index);
679827c7224SMichael Lotz 
680853e6be8SMichael Lotz 		InterruptPipe *					fInterruptPipe;
681853e6be8SMichael Lotz 		usb_hub_descriptor				fHubDescriptor;
682853e6be8SMichael Lotz 
683853e6be8SMichael Lotz 		usb_port_status					fInterruptStatus[USB_MAX_PORT_COUNT];
684853e6be8SMichael Lotz 		usb_port_status					fPortStatus[USB_MAX_PORT_COUNT];
685853e6be8SMichael Lotz 		Device *						fChildren[USB_MAX_PORT_COUNT];
686853e6be8SMichael Lotz };
687853e6be8SMichael Lotz 
688853e6be8SMichael Lotz 
689853e6be8SMichael Lotz /*
690853e6be8SMichael Lotz  * A Transfer is allocated on the heap and passed to the Host Controller in
691853e6be8SMichael Lotz  * SubmitTransfer(). It is generated for all queued transfers. If queuing
692853e6be8SMichael Lotz  * succeds (SubmitTransfer() returns with >= B_OK) the Host Controller takes
693853e6be8SMichael Lotz  * ownership of the Transfer and will delete it as soon as it has called the
694853e6be8SMichael Lotz  * set callback function. If SubmitTransfer() failes, the calling function is
695853e6be8SMichael Lotz  * responsible for deleting the Transfer.
696853e6be8SMichael Lotz  * Also, the transfer takes ownership of the usb_request_data passed to it in
697853e6be8SMichael Lotz  * SetRequestData(), but does not take ownership of the data buffer set by
698853e6be8SMichael Lotz  * SetData().
699853e6be8SMichael Lotz  */
700853e6be8SMichael Lotz class Transfer {
701853e6be8SMichael Lotz public:
702853e6be8SMichael Lotz 									Transfer(Pipe *pipe);
703853e6be8SMichael Lotz 									~Transfer();
704853e6be8SMichael Lotz 
TransferPipe()70519b8f8a0SMichael Lotz 		Pipe *						TransferPipe() const { return fPipe; }
706853e6be8SMichael Lotz 
707853e6be8SMichael Lotz 		void						SetRequestData(usb_request_data *data);
RequestData()70819b8f8a0SMichael Lotz 		usb_request_data *			RequestData() const { return fRequestData; }
709853e6be8SMichael Lotz 
71019b8f8a0SMichael Lotz 		void						SetIsochronousData(
71119b8f8a0SMichael Lotz 										usb_isochronous_data *data);
IsochronousData()71219b8f8a0SMichael Lotz 		usb_isochronous_data *		IsochronousData() const
71319b8f8a0SMichael Lotz 										{ return fIsochronousData; }
714853e6be8SMichael Lotz 
715853e6be8SMichael Lotz 		void						SetData(uint8 *buffer, size_t length);
Data()71619b8f8a0SMichael Lotz 		uint8 *						Data() const
71799626c29SAugustin Cavalier 										{ return fPhysical ? NULL : (uint8 *)fData.base; }
DataLength()71899626c29SAugustin Cavalier 		size_t						DataLength() const { return fData.length; }
719853e6be8SMichael Lotz 
IsPhysical()72019b8f8a0SMichael Lotz 		bool						IsPhysical() const { return fPhysical; }
721853e6be8SMichael Lotz 
72299626c29SAugustin Cavalier 		void						SetVector(iovec *vector, size_t vectorCount);
72355a46882SAugustin Cavalier 		void						SetVector(physical_entry *vector, size_t vectorCount);
Vector()72499626c29SAugustin Cavalier 		generic_io_vec *			Vector() { return fVector; }
VectorCount()72519b8f8a0SMichael Lotz 		size_t						VectorCount() const { return fVectorCount; }
726853e6be8SMichael Lotz 
Bandwidth()72719b8f8a0SMichael Lotz 		uint16						Bandwidth() const { return fBandwidth; }
728853e6be8SMichael Lotz 
IsFragmented()72919b8f8a0SMichael Lotz 		bool						IsFragmented() const { return fFragmented; }
730853e6be8SMichael Lotz 		void						AdvanceByFragment(size_t actualLength);
731bc7fd433SAugustin Cavalier 		size_t						FragmentLength() const;
732853e6be8SMichael Lotz 
733853e6be8SMichael Lotz 		status_t					InitKernelAccess();
734853e6be8SMichael Lotz 		status_t					PrepareKernelAccess();
735853e6be8SMichael Lotz 
736853e6be8SMichael Lotz 		void						SetCallback(usb_callback_func callback,
737853e6be8SMichael Lotz 										void *cookie);
Callback()738159aa93bSMichael Lotz 		usb_callback_func			Callback() const
739159aa93bSMichael Lotz 										{ return fCallback; }
CallbackCookie()740159aa93bSMichael Lotz 		void *						CallbackCookie() const
741159aa93bSMichael Lotz 										{ return fCallbackCookie; }
742853e6be8SMichael Lotz 
74319b8f8a0SMichael Lotz 		void						Finished(uint32 status,
74419b8f8a0SMichael Lotz 										size_t actualLength);
745853e6be8SMichael Lotz 
USBID()74619b8f8a0SMichael Lotz 		usb_id						USBID() const { return 0; }
TypeName()74719b8f8a0SMichael Lotz 		const char *				TypeName() const { return "transfer"; }
748853e6be8SMichael Lotz 
749853e6be8SMichael Lotz private:
75055a46882SAugustin Cavalier 		void						_CheckFragmented();
751853e6be8SMichael Lotz 		status_t					_CalculateBandwidth();
752853e6be8SMichael Lotz 
753853e6be8SMichael Lotz 		// Data that is related to the transfer
754b6ea04cfSAugustin Cavalier 		BReference<Pipe>			fPipe;
75599626c29SAugustin Cavalier 		generic_io_vec				fData;
75699626c29SAugustin Cavalier 		generic_io_vec *			fVector;
757853e6be8SMichael Lotz 		size_t						fVectorCount;
758853e6be8SMichael Lotz 		void *						fBaseAddress;
759853e6be8SMichael Lotz 		bool						fPhysical;
760853e6be8SMichael Lotz 		bool						fFragmented;
761853e6be8SMichael Lotz 		size_t						fActualLength;
762853e6be8SMichael Lotz 		area_id						fUserArea;
763853e6be8SMichael Lotz 		area_id						fClonedArea;
764853e6be8SMichael Lotz 
765853e6be8SMichael Lotz 		usb_callback_func			fCallback;
766853e6be8SMichael Lotz 		void *						fCallbackCookie;
767853e6be8SMichael Lotz 
768853e6be8SMichael Lotz 		// For control transfers
769853e6be8SMichael Lotz 		usb_request_data *			fRequestData;
770853e6be8SMichael Lotz 
771853e6be8SMichael Lotz 		// For isochronous transfers
772853e6be8SMichael Lotz 		usb_isochronous_data *		fIsochronousData;
773853e6be8SMichael Lotz 
774853e6be8SMichael Lotz 		// For bandwidth management.
775853e6be8SMichael Lotz 		// It contains the bandwidth necessary in microseconds
776853e6be8SMichael Lotz 		// for either isochronous, interrupt or control transfers.
777853e6be8SMichael Lotz 		// Not used for bulk transactions.
778853e6be8SMichael Lotz 		uint16						fBandwidth;
779853e6be8SMichael Lotz };
780853e6be8SMichael Lotz 
7811eebcfa0SJérôme Duval 
7821eebcfa0SJérôme Duval // Interface between usb_bus and underlying implementation (xhci_pci)
7831eebcfa0SJérôme Duval typedef struct usb_bus_interface {
7841eebcfa0SJérôme Duval 	driver_module_info info;
7851eebcfa0SJérôme Duval } usb_bus_interface;
7861eebcfa0SJérôme Duval 
7871eebcfa0SJérôme Duval 
7881eebcfa0SJérôme Duval typedef struct {
7891eebcfa0SJérôme Duval 	driver_module_info info;
7901eebcfa0SJérôme Duval 	status_t           (*get_stack)(void** stack);
7911eebcfa0SJérôme Duval } usb_for_controller_interface;
7921eebcfa0SJérôme Duval 
7931eebcfa0SJérôme Duval #define USB_FOR_CONTROLLER_MODULE_NAME "bus_managers/usb/controller/driver_v1"
7941eebcfa0SJérôme Duval 
795e6ce95c5SJérôme Duval // bus manager device interface for peripheral driver
796e6ce95c5SJérôme Duval typedef struct {
797e6ce95c5SJérôme Duval 	driver_module_info info;
798e6ce95c5SJérôme Duval 
799e6ce95c5SJérôme Duval } usb_device_interface;
800e6ce95c5SJérôme Duval 
801e6ce95c5SJérôme Duval 
802e6ce95c5SJérôme Duval #define USB_DEVICE_MODULE_NAME "bus_managers/usb/device/driver_v1"
8031eebcfa0SJérôme Duval 
804cc9f959dSMichael Lotz #endif // _USB_PRIVATE_H
805