xref: /haiku/src/add-ons/kernel/busses/usb/ohci.h (revision 28fa064595b1b5cde9867af1225171c9c90760de)
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 		// Endpoint related methods
115 		ohci_endpoint_descriptor	*_AllocateEndpoint();
116 		void						_FreeEndpoint(
117 										ohci_endpoint_descriptor *endpoint);
118 		status_t					_InsertEndpointForPipe(Pipe *pipe);
119 		status_t					_RemoveEndpointForPipe(Pipe *pipe);
120 		void						_RemoveTransferFromEndpoint(
121 										transfer_data *transfer);
122 		ohci_endpoint_descriptor	*_FindInterruptEndpoint(uint8 interval);
123 
124 		// Transfer descriptor related methods
125 		ohci_general_td				*_CreateGeneralDescriptor(
126 										size_t bufferSize);
127 		status_t					_CreateDescriptorChain(
128 										ohci_general_td **firstDescriptor,
129 										ohci_general_td **lastDescriptor,
130 										uint8 direction,
131 										size_t bufferSize);
132 
133 		void						_FreeGeneralDescriptor(
134 										ohci_general_td *descriptor);
135 		void						_FreeDescriptorChain(
136 										ohci_general_td *topDescriptor);
137 
138 		void						_LinkDescriptors(ohci_general_td *first,
139 										ohci_general_td *second);
140 
141 		ohci_isochronous_td			*_CreateIsochronousDescriptor();
142 		void						_FreeIsochronousDescriptor(
143 										ohci_isochronous_td *descriptor);
144 
145 		size_t						_WriteDescriptorChain(
146 										ohci_general_td *topDescriptor,
147 										iovec *vector,
148 										size_t vectorCount);
149 
150 		// Hash tables related methods
151 		void						_AddDescriptorToHash(
152 										ohci_general_td *descriptor);
153 		void						_RemoveDescriptorFromHash(
154 										ohci_general_td *descriptor);
155 		ohci_general_td				*_FindDescriptorInHash(
156 										uint32 physicalAddress);
157 
158 		void						_AddIsoDescriptorToHash(
159 										ohci_isochronous_td *descriptor);
160 		void						_RemoveIsoDescriptorFromHash(
161 										ohci_isochronous_td *descriptor);
162 		ohci_isochronous_td			*_FindIsoDescriptorInHash(
163 										uint32 physicalAddress);
164 
165 
166 		// Register functions
167 inline	void						_WriteReg(uint32 reg, uint32 value);
168 inline	uint32						_ReadReg(uint32 reg);
169 
170 static	pci_module_info				*sPCIModule;
171 		pci_info 					*fPCIInfo;
172 		Stack						*fStack;
173 
174 		uint32						*fOperationalRegisters;
175 		area_id						fRegisterArea;
176 
177 		// Host Controller Communication Area related stuff
178 		area_id						fHccaArea;
179 		ohci_hcca					*fHcca;
180 		ohci_endpoint_descriptor	**fInterruptEndpoints;
181 
182 		// Dummy endpoints
183 		ohci_endpoint_descriptor	*fDummyControl;
184 		ohci_endpoint_descriptor	*fDummyBulk;
185 		ohci_endpoint_descriptor	*fDummyIsochronous;
186 
187 		// Maintain a linked list of transfer
188 		transfer_data				*fFirstTransfer;
189 		transfer_data				*fLastTransfer;
190 		sem_id						fFinishTransfersSem;
191 		thread_id					fFinishThread;
192 		bool						fStopFinishThread;
193 
194 		// Hash table
195 		ohci_general_td				**fHashGenericTable;
196 		ohci_isochronous_td			**fHashIsochronousTable;
197 
198 		// Root Hub
199 		OHCIRootHub 				*fRootHub;
200 		uint8						fRootHubAddress;
201 
202 		// Port management
203 		uint8						fPortCount;
204 };
205 
206 
207 class OHCIRootHub : public Hub {
208 public:
209 									OHCIRootHub(Object *rootObject,
210 										int8 deviceAddress);
211 
212 static	status_t	 				ProcessTransfer(OHCI *ohci,
213 										Transfer *transfer);
214 };
215 
216 
217 #endif // OHCI_H
218