xref: /haiku/src/add-ons/kernel/busses/usb/ohci.h (revision e688bf23d48bfd1216a0cacbdbda5e35a1bcd779)
1 /*
2  * Copyright 2005-2008, 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  */
10 #ifndef OHCI_H
11 #define OHCI_H
12 
13 #include "usb_private.h"
14 #include "ohci_hardware.h"
15 #include <lock.h>
16 
17 struct pci_info;
18 struct pci_module_info;
19 struct pci_x86_module_info;
20 class OHCIRootHub;
21 
22 typedef struct transfer_data {
23 	Transfer *					transfer;
24 	ohci_endpoint_descriptor *	endpoint;
25 	ohci_general_td *			first_descriptor;
26 	ohci_general_td *			data_descriptor;
27 	ohci_general_td *			last_descriptor;
28 	bool						incoming;
29 	bool						canceled;
30 	transfer_data *				link;
31 } transfer_data;
32 
33 
34 class OHCI : public BusManager {
35 public:
36 									OHCI(pci_info *info, Stack *stack);
37 									~OHCI();
38 
39 		status_t					Start();
40 virtual	status_t					SubmitTransfer(Transfer *transfer);
41 virtual status_t					CancelQueuedTransfers(Pipe *pipe,
42 										bool force);
43 
44 virtual	status_t					NotifyPipeChange(Pipe *pipe,
45 										usb_change change);
46 
47 static	status_t					AddTo(Stack *stack);
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					_CancelQueuedIsochronousTransfers(
73 										Pipe *pipe, bool force);
74 		status_t					_UnlinkTransfer(transfer_data *transfer);
75 
76 static	int32						_FinishThread(void *data);
77 		void						_FinishTransfers();
78 
79 		status_t					_SubmitRequest(Transfer *transfer);
80 		status_t					_SubmitTransfer(Transfer *transfer);
81 		status_t					_SubmitIsochronousTransfer(
82 										Transfer *transfer);
83 
84 		void						_SwitchEndpointTail(
85 										ohci_endpoint_descriptor *endpoint,
86 										ohci_general_td *first,
87 										ohci_general_td *last);
88 		void						_RemoveTransferFromEndpoint(
89 										transfer_data *transfer);
90 
91 		// Endpoint related methods
92 		ohci_endpoint_descriptor *	_AllocateEndpoint();
93 		void						_FreeEndpoint(
94 										ohci_endpoint_descriptor *endpoint);
95 		status_t					_InsertEndpointForPipe(Pipe *pipe);
96 		status_t					_RemoveEndpointForPipe(Pipe *pipe);
97 		ohci_endpoint_descriptor *	_FindInterruptEndpoint(uint8 interval);
98 
99 		// Transfer descriptor related methods
100 		ohci_general_td *			_CreateGeneralDescriptor(
101 										size_t bufferSize);
102 		void						_FreeGeneralDescriptor(
103 										ohci_general_td *descriptor);
104 
105 		status_t					_CreateDescriptorChain(
106 										ohci_general_td **firstDescriptor,
107 										ohci_general_td **lastDescriptor,
108 										uint32 direction,
109 										size_t bufferSize);
110 		void						_FreeDescriptorChain(
111 										ohci_general_td *topDescriptor);
112 
113 		size_t						_WriteDescriptorChain(
114 										ohci_general_td *topDescriptor,
115 										iovec *vector, size_t vectorCount);
116 		size_t						_ReadDescriptorChain(
117 										ohci_general_td *topDescriptor,
118 										iovec *vector, size_t vectorCount);
119 		size_t						_ReadActualLength(
120 										ohci_general_td *topDescriptor);
121 
122 		void						_LinkDescriptors(ohci_general_td *first,
123 										ohci_general_td *second);
124 
125 		ohci_isochronous_td *		_CreateIsochronousDescriptor();
126 		void						_FreeIsochronousDescriptor(
127 										ohci_isochronous_td *descriptor);
128 
129 		// Private locking
130 		bool						_LockEndpoints();
131 		void						_UnlockEndpoints();
132 
133 		// Register functions
134 inline	void						_WriteReg(uint32 reg, uint32 value);
135 inline	uint32						_ReadReg(uint32 reg);
136 
137 		// Debug functions
138 		void						_PrintEndpoint(
139 										ohci_endpoint_descriptor *endpoint);
140 		void						_PrintDescriptorChain(
141 										ohci_general_td *topDescriptor);
142 
143 static	pci_module_info *			sPCIModule;
144 static	pci_x86_module_info *		sPCIx86Module;
145 
146 		pci_info *					fPCIInfo;
147 		Stack *						fStack;
148 
149 		uint8 *						fOperationalRegisters;
150 		area_id						fRegisterArea;
151 
152 		// Host Controller Communication Area related stuff
153 		area_id						fHccaArea;
154 		ohci_hcca *					fHcca;
155 		ohci_endpoint_descriptor **	fInterruptEndpoints;
156 
157 		// Endpoint management
158 		mutex						fEndpointLock;
159 		ohci_endpoint_descriptor *	fDummyControl;
160 		ohci_endpoint_descriptor *	fDummyBulk;
161 		ohci_endpoint_descriptor *	fDummyIsochronous;
162 
163 		// Maintain a linked list of transfer
164 		transfer_data *				fFirstTransfer;
165 		transfer_data *				fLastTransfer;
166 		sem_id						fFinishTransfersSem;
167 		thread_id					fFinishThread;
168 		bool						fStopFinishThread;
169 		Pipe *						fProcessingPipe;
170 
171 		// Root Hub
172 		OHCIRootHub *				fRootHub;
173 		uint8						fRootHubAddress;
174 
175 		// Port management
176 		uint8						fPortCount;
177 };
178 
179 
180 class OHCIRootHub : public Hub {
181 public:
182 									OHCIRootHub(Object *rootObject,
183 										int8 deviceAddress);
184 
185 static	status_t					ProcessTransfer(OHCI *ohci,
186 										Transfer *transfer);
187 };
188 
189 
190 #endif // OHCI_H
191