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
17struct pci_info;
18struct pci_module_info;
19struct pci_x86_module_info;
20class OHCIRootHub;
21
22typedef 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
34class OHCI : public BusManager {
35public:
36									OHCI(pci_info *info, Stack *stack);
37									~OHCI();
38
39		status_t					Start();
40virtual	status_t					SubmitTransfer(Transfer *transfer);
41virtual status_t					CancelQueuedTransfers(Pipe *pipe,
42										bool force);
43
44virtual	status_t					NotifyPipeChange(Pipe *pipe,
45										usb_change change);
46
47static	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
58virtual	const char *				TypeName() const { return "ohci"; };
59
60private:
61		// Interrupt functions
62static	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
76static	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
134inline	void						_WriteReg(uint32 reg, uint32 value);
135inline	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
143static	pci_module_info *			sPCIModule;
144static	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
180class OHCIRootHub : public Hub {
181public:
182									OHCIRootHub(Object *rootObject,
183										int8 deviceAddress);
184
185static	status_t					ProcessTransfer(OHCI *ohci,
186										Transfer *transfer);
187};
188
189
190#endif // OHCI_H
191