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