xref: /haiku/src/add-ons/kernel/busses/usb/ohci.h (revision 445d4fd926c569e7b9ae28017da86280aaecbae2)
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 										generic_io_vec *vector, size_t vectorCount,
139 										bool physical);
140 		size_t						_ReadDescriptorChain(
141 										ohci_general_td *topDescriptor,
142 										generic_io_vec *vector, size_t vectorCount,
143 										bool physical);
144 
145 		size_t						_WriteIsochronousDescriptorChain(
146 										ohci_isochronous_td *topDescriptor,
147 										generic_io_vec *vector, size_t vectorCount,
148 										bool physical);
149 		void						_ReadIsochronousDescriptorChain(
150 										ohci_isochronous_td *topDescriptor,
151 										generic_io_vec *vector, size_t vectorCount,
152 										bool physical);
153 
154 		size_t						_ReadActualLength(
155 										ohci_general_td *topDescriptor);
156 
157 		void						_LinkDescriptors(ohci_general_td *first,
158 										ohci_general_td *second);
159 		void						_LinkIsochronousDescriptors(
160 										ohci_isochronous_td *first,
161 										ohci_isochronous_td *second,
162 										ohci_isochronous_td *nextDone);
163 
164 		bool						_AllocateIsochronousBandwidth(uint16 frame,
165 										uint16 size);
166 		void						_ReleaseIsochronousBandwidth(
167 										uint16 startFrame, uint16 count);
168 
169 		status_t					_GetStatusOfConditionCode(
170 										uint8 conditionCode);
171 		// Private locking
172 		bool						_LockEndpoints();
173 		void						_UnlockEndpoints();
174 
175 		// Register functions
176 inline	void						_WriteReg(uint32 reg, uint32 value);
177 inline	uint32						_ReadReg(uint32 reg);
178 
179 		// Debug functions
180 		void						_PrintEndpoint(
181 										ohci_endpoint_descriptor *endpoint);
182 		void						_PrintDescriptorChain(
183 										ohci_general_td *topDescriptor);
184 		void						_PrintDescriptorChain(
185 										ohci_isochronous_td *topDescriptor);
186 
187 		pci_info *					fPCIInfo;
188 		pci_device_module_info*		fPci;
189 		pci_device*					fDevice;
190 		Stack *						fStack;
191 
192 		uint8 *						fOperationalRegisters;
193 		area_id						fRegisterArea;
194 
195 		// Host Controller Communication Area related stuff
196 		area_id						fHccaArea;
197 		ohci_hcca *					fHcca;
198 		ohci_endpoint_descriptor **	fInterruptEndpoints;
199 
200 		// Endpoint management
201 		mutex						fEndpointLock;
202 		ohci_endpoint_descriptor *	fDummyControl;
203 		ohci_endpoint_descriptor *	fDummyBulk;
204 		ohci_endpoint_descriptor *	fDummyIsochronous;
205 
206 		// Maintain a linked list of transfer
207 		transfer_data *				fFirstTransfer;
208 		transfer_data *				fLastTransfer;
209 		sem_id						fFinishTransfersSem;
210 		thread_id					fFinishThread;
211 		bool						fStopFinishThread;
212 		Pipe *						fProcessingPipe;
213 		// frame bandwidth watchdogs array
214 		uint16 *					fFrameBandwidth;
215 
216 		// Root Hub
217 		OHCIRootHub *				fRootHub;
218 		uint8						fRootHubAddress;
219 
220 		// Port management
221 		uint8						fPortCount;
222 
223 		uint8						fIRQ;
224 		bool						fUseMSI;
225 };
226 
227 
228 class OHCIRootHub : public Hub {
229 public:
230 									OHCIRootHub(Object *rootObject,
231 										int8 deviceAddress);
232 
233 static	status_t					ProcessTransfer(OHCI *ohci,
234 										Transfer *transfer);
235 };
236 
237 
238 #endif // OHCI_H
239