xref: /haiku/src/add-ons/kernel/busses/usb/ohci.h (revision 7b3e89c0944ae1efa9a8fc66c7303874b7a344b2)
1 /*
2  * Copyright 2005-2013, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Jan-Rixt Van Hoye
7  *		Salvatore Benedetto <salvatore.benedetto@gmail.com>
8  *		Michael Lotz <mmlr@mlotz.ch>
9  *		Siarzhuk Zharski <imker@gmx.li>
10  */
11 #ifndef OHCI_H
12 #define OHCI_H
13 
14 #include "usb_private.h"
15 #include "ohci_hardware.h"
16 #include <lock.h>
17 
18 struct pci_info;
19 struct pci_device_module_info;
20 struct pci_device;
21 class OHCIRootHub;
22 
23 typedef struct transfer_data {
24 	Transfer *					transfer;
25 	ohci_endpoint_descriptor *	endpoint;
26 	ohci_general_td *			first_descriptor;
27 	ohci_general_td *			data_descriptor;
28 	ohci_general_td *			last_descriptor;
29 	bool						incoming;
30 	bool						canceled;
31 	transfer_data *				link;
32 } transfer_data;
33 
34 
35 class OHCI : public BusManager {
36 public:
37 									OHCI(pci_info *info, pci_device_module_info* pci,
38 										pci_device* device, Stack *stack, device_node* node);
39 									~OHCI();
40 
41 		status_t					Start();
42 virtual	status_t					SubmitTransfer(Transfer *transfer);
43 virtual status_t					CancelQueuedTransfers(Pipe *pipe,
44 										bool force);
45 
46 virtual	status_t					NotifyPipeChange(Pipe *pipe,
47 										usb_change change);
48 
49 		// Port operations
50 		uint8						PortCount() { return fPortCount; };
51 		status_t					GetPortStatus(uint8 index,
52 										usb_port_status *status);
53 		status_t					SetPortFeature(uint8 index, uint16 feature);
54 		status_t					ClearPortFeature(uint8 index, uint16 feature);
55 
56 		status_t					ResetPort(uint8 index);
57 
58 virtual	const char *				TypeName() const { return "ohci"; };
59 
60 private:
61 		// Interrupt functions
62 static	int32						_InterruptHandler(void *data);
63 		int32						_Interrupt();
64 
65 		// Transfer functions
66 		status_t					_AddPendingTransfer(Transfer *transfer,
67 										ohci_endpoint_descriptor *endpoint,
68 										ohci_general_td *firstDescriptor,
69 										ohci_general_td *dataDescriptor,
70 										ohci_general_td *lastDescriptor,
71 										bool directionIn);
72 		status_t					_AddPendingIsochronousTransfer(
73 										Transfer *transfer,
74 										ohci_endpoint_descriptor *endpoint,
75 										ohci_isochronous_td *firstDescriptor,
76 										ohci_isochronous_td *lastDescriptor,
77 										bool directionIn);
78 
79 		status_t					_UnlinkTransfer(transfer_data *transfer);
80 
81 static	int32						_FinishThread(void *data);
82 		void						_FinishTransfers();
83 		bool						_FinishIsochronousTransfer(
84 										transfer_data *transfer,
85 										transfer_data **_lastTransfer);
86 
87 		status_t					_SubmitRequest(Transfer *transfer);
88 		status_t					_SubmitTransfer(Transfer *transfer);
89 		status_t					_SubmitIsochronousTransfer(
90 										Transfer *transfer);
91 
92 		void						_SwitchEndpointTail(
93 										ohci_endpoint_descriptor *endpoint,
94 										ohci_general_td *first,
95 										ohci_general_td *last);
96 		void						_SwitchIsochronousEndpointTail(
97 										ohci_endpoint_descriptor *endpoint,
98 										ohci_isochronous_td *first,
99 										ohci_isochronous_td *last);
100 
101 		void						_RemoveTransferFromEndpoint(
102 										transfer_data *transfer);
103 
104 		// Endpoint related methods
105 		ohci_endpoint_descriptor *	_AllocateEndpoint();
106 		void						_FreeEndpoint(
107 										ohci_endpoint_descriptor *endpoint);
108 		status_t					_InsertEndpointForPipe(Pipe *pipe);
109 		status_t					_RemoveEndpointForPipe(Pipe *pipe);
110 		ohci_endpoint_descriptor *	_FindInterruptEndpoint(uint8 interval);
111 
112 		// Transfer descriptor related methods
113 		ohci_general_td *			_CreateGeneralDescriptor(
114 										size_t bufferSize);
115 		void						_FreeGeneralDescriptor(
116 										ohci_general_td *descriptor);
117 		status_t					_CreateDescriptorChain(
118 										ohci_general_td **firstDescriptor,
119 										ohci_general_td **lastDescriptor,
120 										uint32 direction,
121 										size_t bufferSize);
122 		void						_FreeDescriptorChain(
123 										ohci_general_td *topDescriptor);
124 
125 		ohci_isochronous_td *		_CreateIsochronousDescriptor(
126 										size_t bufferSize);
127 		void						_FreeIsochronousDescriptor(
128 										ohci_isochronous_td *descriptor);
129 		status_t					_CreateIsochronousDescriptorChain(
130 										ohci_isochronous_td **firstDescriptor,
131 										ohci_isochronous_td **lastDescriptor,
132 										Transfer *transfer);
133 		void						_FreeIsochronousDescriptorChain(
134 										ohci_isochronous_td *topDescriptor);
135 
136 		size_t						_WriteDescriptorChain(
137 										ohci_general_td *topDescriptor,
138 										iovec *vector, size_t vectorCount);
139 		size_t						_ReadDescriptorChain(
140 										ohci_general_td *topDescriptor,
141 										iovec *vector, size_t vectorCount);
142 
143 		size_t						_WriteIsochronousDescriptorChain(
144 										ohci_isochronous_td *topDescriptor,
145 										iovec *vector, size_t vectorCount);
146 		void						_ReadIsochronousDescriptorChain(
147 										ohci_isochronous_td *topDescriptor,
148 										iovec *vector, size_t vectorCount);
149 
150 		size_t						_ReadActualLength(
151 										ohci_general_td *topDescriptor);
152 
153 		void						_LinkDescriptors(ohci_general_td *first,
154 										ohci_general_td *second);
155 		void						_LinkIsochronousDescriptors(
156 										ohci_isochronous_td *first,
157 										ohci_isochronous_td *second,
158 										ohci_isochronous_td *nextDone);
159 
160 		bool						_AllocateIsochronousBandwidth(uint16 frame,
161 										uint16 size);
162 		void						_ReleaseIsochronousBandwidth(
163 										uint16 startFrame, uint16 count);
164 
165 		status_t					_GetStatusOfConditionCode(
166 										uint8 conditionCode);
167 		// Private locking
168 		bool						_LockEndpoints();
169 		void						_UnlockEndpoints();
170 
171 		// Register functions
172 inline	void						_WriteReg(uint32 reg, uint32 value);
173 inline	uint32						_ReadReg(uint32 reg);
174 
175 		// Debug functions
176 		void						_PrintEndpoint(
177 										ohci_endpoint_descriptor *endpoint);
178 		void						_PrintDescriptorChain(
179 										ohci_general_td *topDescriptor);
180 		void						_PrintDescriptorChain(
181 										ohci_isochronous_td *topDescriptor);
182 
183 		pci_info *					fPCIInfo;
184 		pci_device_module_info*		fPci;
185 		pci_device*					fDevice;
186 		Stack *						fStack;
187 
188 		uint8 *						fOperationalRegisters;
189 		area_id						fRegisterArea;
190 
191 		// Host Controller Communication Area related stuff
192 		area_id						fHccaArea;
193 		ohci_hcca *					fHcca;
194 		ohci_endpoint_descriptor **	fInterruptEndpoints;
195 
196 		// Endpoint management
197 		mutex						fEndpointLock;
198 		ohci_endpoint_descriptor *	fDummyControl;
199 		ohci_endpoint_descriptor *	fDummyBulk;
200 		ohci_endpoint_descriptor *	fDummyIsochronous;
201 
202 		// Maintain a linked list of transfer
203 		transfer_data *				fFirstTransfer;
204 		transfer_data *				fLastTransfer;
205 		sem_id						fFinishTransfersSem;
206 		thread_id					fFinishThread;
207 		bool						fStopFinishThread;
208 		Pipe *						fProcessingPipe;
209 		// frame bandwidth watchdogs array
210 		uint16 *					fFrameBandwidth;
211 
212 		// Root Hub
213 		OHCIRootHub *				fRootHub;
214 		uint8						fRootHubAddress;
215 
216 		// Port management
217 		uint8						fPortCount;
218 
219 		uint8						fIRQ;
220 		bool						fUseMSI;
221 };
222 
223 
224 class OHCIRootHub : public Hub {
225 public:
226 									OHCIRootHub(Object *rootObject,
227 										int8 deviceAddress);
228 
229 static	status_t					ProcessTransfer(OHCI *ohci,
230 										Transfer *transfer);
231 };
232 
233 
234 #endif // OHCI_H
235