xref: /haiku/src/add-ons/kernel/busses/usb/ohci.h (revision 02354704729d38c3b078c696adc1bbbd33cbcf72)
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_module_info;
20 struct pci_x86_module_info;
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 static	status_t					AddTo(Stack *stack);
38 
39 									OHCI(pci_info *info, Stack *stack);
40 									~OHCI();
41 
42 		status_t					Start();
43 virtual	status_t					SubmitTransfer(Transfer *transfer);
44 virtual status_t					CancelQueuedTransfers(Pipe *pipe,
45 										bool force);
46 
47 virtual	status_t					NotifyPipeChange(Pipe *pipe,
48 										usb_change change);
49 
50 		// Port operations
51 		uint8						PortCount() { return fPortCount; };
52 		status_t					GetPortStatus(uint8 index,
53 										usb_port_status *status);
54 		status_t					SetPortFeature(uint8 index, uint16 feature);
55 		status_t					ClearPortFeature(uint8 index, uint16 feature);
56 
57 		status_t					ResetPort(uint8 index);
58 
59 virtual	const char *				TypeName() const { return "ohci"; };
60 
61 private:
62 		// Interrupt functions
63 static	int32						_InterruptHandler(void *data);
64 		int32						_Interrupt();
65 
66 		// Transfer functions
67 		status_t					_AddPendingTransfer(Transfer *transfer,
68 										ohci_endpoint_descriptor *endpoint,
69 										ohci_general_td *firstDescriptor,
70 										ohci_general_td *dataDescriptor,
71 										ohci_general_td *lastDescriptor,
72 										bool directionIn);
73 		status_t					_AddPendingIsochronousTransfer(
74 										Transfer *transfer,
75 										ohci_endpoint_descriptor *endpoint,
76 										ohci_isochronous_td *firstDescriptor,
77 										ohci_isochronous_td *lastDescriptor,
78 										bool directionIn);
79 
80 		status_t					_UnlinkTransfer(transfer_data *transfer);
81 
82 static	int32						_FinishThread(void *data);
83 		void						_FinishTransfers();
84 		bool						_FinishIsochronousTransfer(
85 										transfer_data *transfer,
86 										transfer_data **_lastTransfer);
87 
88 		status_t					_SubmitRequest(Transfer *transfer);
89 		status_t					_SubmitTransfer(Transfer *transfer);
90 		status_t					_SubmitIsochronousTransfer(
91 										Transfer *transfer);
92 
93 		void						_SwitchEndpointTail(
94 										ohci_endpoint_descriptor *endpoint,
95 										ohci_general_td *first,
96 										ohci_general_td *last);
97 		void						_SwitchIsochronousEndpointTail(
98 										ohci_endpoint_descriptor *endpoint,
99 										ohci_isochronous_td *first,
100 										ohci_isochronous_td *last);
101 
102 		void						_RemoveTransferFromEndpoint(
103 										transfer_data *transfer);
104 
105 		// Endpoint related methods
106 		ohci_endpoint_descriptor *	_AllocateEndpoint();
107 		void						_FreeEndpoint(
108 										ohci_endpoint_descriptor *endpoint);
109 		status_t					_InsertEndpointForPipe(Pipe *pipe);
110 		status_t					_RemoveEndpointForPipe(Pipe *pipe);
111 		ohci_endpoint_descriptor *	_FindInterruptEndpoint(uint8 interval);
112 
113 		// Transfer descriptor related methods
114 		ohci_general_td *			_CreateGeneralDescriptor(
115 										size_t bufferSize);
116 		void						_FreeGeneralDescriptor(
117 										ohci_general_td *descriptor);
118 		status_t					_CreateDescriptorChain(
119 										ohci_general_td **firstDescriptor,
120 										ohci_general_td **lastDescriptor,
121 										uint32 direction,
122 										size_t bufferSize);
123 		void						_FreeDescriptorChain(
124 										ohci_general_td *topDescriptor);
125 
126 		ohci_isochronous_td *		_CreateIsochronousDescriptor(
127 										size_t bufferSize);
128 		void						_FreeIsochronousDescriptor(
129 										ohci_isochronous_td *descriptor);
130 		status_t					_CreateIsochronousDescriptorChain(
131 										ohci_isochronous_td **firstDescriptor,
132 										ohci_isochronous_td **lastDescriptor,
133 										Transfer *transfer);
134 		void						_FreeIsochronousDescriptorChain(
135 										ohci_isochronous_td *topDescriptor);
136 
137 		size_t						_WriteDescriptorChain(
138 										ohci_general_td *topDescriptor,
139 										iovec *vector, size_t vectorCount);
140 		size_t						_ReadDescriptorChain(
141 										ohci_general_td *topDescriptor,
142 										iovec *vector, size_t vectorCount);
143 
144 		size_t						_WriteIsochronousDescriptorChain(
145 										ohci_isochronous_td *topDescriptor,
146 										iovec *vector, size_t vectorCount);
147 		void						_ReadIsochronousDescriptorChain(
148 										ohci_isochronous_td *topDescriptor,
149 										iovec *vector, size_t vectorCount);
150 
151 		size_t						_ReadActualLength(
152 										ohci_general_td *topDescriptor);
153 
154 		void						_LinkDescriptors(ohci_general_td *first,
155 										ohci_general_td *second);
156 		void						_LinkIsochronousDescriptors(
157 										ohci_isochronous_td *first,
158 										ohci_isochronous_td *second,
159 										ohci_isochronous_td *nextDone);
160 
161 		bool						_AllocateIsochronousBandwidth(uint16 frame,
162 										uint16 size);
163 		void						_ReleaseIsochronousBandwidth(
164 										uint16 startFrame, uint16 count);
165 
166 		status_t					_GetStatusOfConditionCode(
167 										uint8 conditionCode);
168 		// Private locking
169 		bool						_LockEndpoints();
170 		void						_UnlockEndpoints();
171 
172 		// Register functions
173 inline	void						_WriteReg(uint32 reg, uint32 value);
174 inline	uint32						_ReadReg(uint32 reg);
175 
176 		// Debug functions
177 		void						_PrintEndpoint(
178 										ohci_endpoint_descriptor *endpoint);
179 		void						_PrintDescriptorChain(
180 										ohci_general_td *topDescriptor);
181 		void						_PrintDescriptorChain(
182 										ohci_isochronous_td *topDescriptor);
183 
184 static	pci_module_info *			sPCIModule;
185 static	pci_x86_module_info *		sPCIx86Module;
186 
187 		pci_info *					fPCIInfo;
188 		Stack *						fStack;
189 
190 		uint8 *						fOperationalRegisters;
191 		area_id						fRegisterArea;
192 
193 		// Host Controller Communication Area related stuff
194 		area_id						fHccaArea;
195 		ohci_hcca *					fHcca;
196 		ohci_endpoint_descriptor **	fInterruptEndpoints;
197 
198 		// Endpoint management
199 		mutex						fEndpointLock;
200 		ohci_endpoint_descriptor *	fDummyControl;
201 		ohci_endpoint_descriptor *	fDummyBulk;
202 		ohci_endpoint_descriptor *	fDummyIsochronous;
203 
204 		// Maintain a linked list of transfer
205 		transfer_data *				fFirstTransfer;
206 		transfer_data *				fLastTransfer;
207 		sem_id						fFinishTransfersSem;
208 		thread_id					fFinishThread;
209 		bool						fStopFinishThread;
210 		Pipe *						fProcessingPipe;
211 		// frame bandwidth watchdogs array
212 		uint16 *					fFrameBandwidth;
213 
214 		// Root Hub
215 		OHCIRootHub *				fRootHub;
216 		uint8						fRootHubAddress;
217 
218 		// Port management
219 		uint8						fPortCount;
220 
221 		uint8						fIRQ;
222 		bool						fUseMSI;
223 };
224 
225 
226 class OHCIRootHub : public Hub {
227 public:
228 									OHCIRootHub(Object *rootObject,
229 										int8 deviceAddress);
230 
231 static	status_t					ProcessTransfer(OHCI *ohci,
232 										Transfer *transfer);
233 };
234 
235 
236 #endif // OHCI_H
237