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