xref: /haiku/src/add-ons/kernel/busses/usb/ohci.h (revision cfc3fa87da824bdf593eb8b817a83b6376e77935)
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  */
9 
10 #ifndef OHCI_H
11 #define OHCI_H
12 
13 #include "usb_p.h"
14 #include "ohci_hardware.h"
15 #include <lock.h>
16 
17 struct pci_info;
18 struct pci_module_info;
19 class OHCIRootHub;
20 
21 typedef struct transfer_data_s {
22 	Transfer					*transfer;
23 	ohci_endpoint_descriptor	*endpoint;
24 	ohci_general_td				*first_descriptor;
25 	ohci_general_td				*data_descriptor;
26 	bool						incoming;
27 	bool						canceled;
28 	transfer_data_s				*link;
29 } transfer_data;
30 
31 // --------------------------------------
32 //	OHCI:: 	Software isonchronous
33 //			transfer descriptor
34 // --------------------------------------
35 typedef struct hcd_soft_itransfer
36 {
37 	ohci_isochronous_td	itd;
38 	struct hcd_soft_itransfer			*nextitd; 	// mirrors nexttd in ITD
39 	struct hcd_soft_itransfer			*dnext; 	// next in done list
40 	addr_t 								physaddr;	// physical address to the host controller isonchronous transfer
41 	//LIST_ENTRY(hcd_soft_itransfer) 		hnext;
42 	uint16								flags;		// flags
43 #ifdef DIAGNOSTIC
44 	char 								isdone;		// is the transfer done?
45 #endif
46 }hcd_soft_itransfer;
47 
48 #define	OHCI_SITD_SIZE	((sizeof (struct hcd_soft_itransfer) + OHCI_ITD_ALIGN - 1) / OHCI_ITD_ALIGN * OHCI_ITD_ALIGN)
49 #define	OHCI_SITD_CHUNK	64
50 
51 #define	OHCI_NUMBER_OF_ENDPOINTS	(2 * OHCI_NUMBER_OF_INTERRUPTS - 1)
52 
53 // Note: the controller returns only the physical
54 // address of the first processed descriptor of
55 // an heterogeneous list (isochronous + generic). Unfortunately
56 // we don't have a way to know whether the descriptor is
57 // generic or isochronous, either way to translate the address back to
58 // kernel address. The physical address is used as the hash value.
59 // (Kindly borrowed from *BSD)
60 
61 #define OHCI_HASH_SIZE 128
62 #define HASH(x) (((x) >> 4) % OHCI_HASH_SIZE)
63 
64 
65 class OHCI : public BusManager
66 {
67 public:
68 
69 									OHCI(pci_info *info, Stack *stack);
70 									~OHCI();
71 
72 		status_t					Start();
73 virtual	status_t 					SubmitTransfer(Transfer *transfer);
74 virtual status_t					CancelQueuedTransfers(Pipe *pipe,
75 										bool force);
76 
77 virtual	status_t					NotifyPipeChange(Pipe *pipe,
78 										usb_change change);
79 
80 static	status_t					AddTo(Stack *stack);
81 
82 		// Port operations
83 		uint8 						PortCount() { return fPortCount; };
84 		status_t 					GetPortStatus(uint8 index,
85 										usb_port_status *status);
86 		status_t					SetPortFeature(uint8 index, uint16 feature);
87 		status_t					ClearPortFeature(uint8 index, uint16 feature);
88 
89 		status_t					ResetPort(uint8 index);
90 
91 
92 private:
93 		// Interrupt functions
94 static	int32						_InterruptHandler(void *data);
95 		int32						_Interrupt();
96 
97 		// Transfer functions
98 		status_t					_AddPendingTransfer(Transfer *transfer,
99 										ohci_endpoint_descriptor *endpoint,
100 										ohci_general_td *first,
101 										ohci_general_td *data,
102 										bool directionIn);
103 		status_t					_CancelQueuedIsochronousTransfers(
104 										Pipe *pipe, bool force);
105 		status_t					_UnlinkTransfer(transfer_data *transfer);
106 
107 static	int32						_FinishThread(void *data);
108 		void						_FinishTransfer();
109 
110 		status_t					_SubmitControlRequest(Transfer *transfer);
111 		status_t					_SubmitBulkTransfer(Transfer *transfer);
112 		status_t					_SubmitPeriodicTransfer(Transfer *transfer);
113 
114 		status_t					_AppendChainDescriptorsToEndpoint(
115 										ohci_endpoint_descriptor *endpoint,
116 										ohci_general_td *first,
117 										ohci_general_td *last);
118 		void						_RemoveTransferFromEndpoint(
119 										transfer_data *);
120 
121 		// Endpoint related methods
122 		ohci_endpoint_descriptor	*_AllocateEndpoint();
123 		void						_FreeEndpoint(
124 										ohci_endpoint_descriptor *endpoint);
125 		status_t					_InsertEndpointForPipe(Pipe *pipe);
126 		status_t					_RemoveEndpointForPipe(Pipe *pipe);
127 		ohci_endpoint_descriptor	*_FindInterruptEndpoint(uint8 interval);
128 
129 		// Transfer descriptor related methods
130 		ohci_general_td				*_CreateGeneralDescriptor(
131 										size_t bufferSize);
132 		status_t					_CreateDescriptorChain(
133 										ohci_general_td **firstDescriptor,
134 										ohci_general_td **lastDescriptor,
135 										uint8 direction,
136 										size_t bufferSize);
137 
138 		void						_FreeGeneralDescriptor(
139 										ohci_general_td *descriptor);
140 		void						_FreeDescriptorChain(
141 										ohci_general_td *topDescriptor);
142 
143 		void						_LinkDescriptors(ohci_general_td *first,
144 										ohci_general_td *second);
145 
146 		ohci_isochronous_td			*_CreateIsochronousDescriptor();
147 		void						_FreeIsochronousDescriptor(
148 										ohci_isochronous_td *descriptor);
149 
150 		size_t						_WriteDescriptorChain(
151 										ohci_general_td *topDescriptor,
152 										iovec *vector,
153 										size_t vectorCount);
154 
155 		// Hash tables related methods
156 		void						_AddDescriptorToHash(
157 										ohci_general_td *descriptor);
158 		void						_RemoveDescriptorFromHash(
159 										ohci_general_td *descriptor);
160 		ohci_general_td				*_FindDescriptorInHash(
161 										uint32 physicalAddress);
162 
163 		void						_AddIsoDescriptorToHash(
164 										ohci_isochronous_td *descriptor);
165 		void						_RemoveIsoDescriptorFromHash(
166 										ohci_isochronous_td *descriptor);
167 		ohci_isochronous_td			*_FindIsoDescriptorInHash(
168 										uint32 physicalAddress);
169 
170 
171 		// Register functions
172 inline	void						_WriteReg(uint32 reg, uint32 value);
173 inline	uint32						_ReadReg(uint32 reg);
174 
175 static	pci_module_info				*sPCIModule;
176 		pci_info 					*fPCIInfo;
177 		Stack						*fStack;
178 
179 		uint32						*fOperationalRegisters;
180 		area_id						fRegisterArea;
181 
182 		// Host Controller Communication Area related stuff
183 		area_id						fHccaArea;
184 		ohci_hcca					*fHcca;
185 		ohci_endpoint_descriptor	**fInterruptEndpoints;
186 
187 		// Dummy endpoints
188 		ohci_endpoint_descriptor	*fDummyControl;
189 		ohci_endpoint_descriptor	*fDummyBulk;
190 		ohci_endpoint_descriptor	*fDummyIsochronous;
191 
192 		// Maintain a linked list of transfer
193 		transfer_data				*fFirstTransfer;
194 		transfer_data				*fLastTransfer;
195 		sem_id						fFinishTransfersSem;
196 		thread_id					fFinishThread;
197 		bool						fStopFinishThread;
198 
199 		// Hash table
200 		ohci_general_td				**fHashGenericTable;
201 		ohci_isochronous_td			**fHashIsochronousTable;
202 
203 		// Root Hub
204 		OHCIRootHub 				*fRootHub;
205 		uint8						fRootHubAddress;
206 
207 		// Port management
208 		uint8						fPortCount;
209 };
210 
211 
212 class OHCIRootHub : public Hub {
213 public:
214 									OHCIRootHub(Object *rootObject,
215 										int8 deviceAddress);
216 
217 static	status_t	 				ProcessTransfer(OHCI *ohci,
218 										Transfer *transfer);
219 };
220 
221 
222 #endif // OHCI_H
223