xref: /haiku/src/add-ons/kernel/busses/usb/ehci.h (revision 50b3e74489a1a46fec88df793e4f6780e4de933c)
1 /*
2  * Copyright 2006, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Michael Lotz <mmlr@mlotz.ch>
7  */
8 #ifndef EHCI_H
9 #define EHCI_H
10 
11 #include "usb_private.h"
12 #include "ehci_hardware.h"
13 
14 
15 struct pci_info;
16 struct pci_module_info;
17 class EHCIRootHub;
18 
19 
20 typedef struct transfer_data {
21 	Transfer *		transfer;
22 	ehci_qh *		queue_head;
23 	ehci_qtd *		data_descriptor;
24 	bool			incoming;
25 	bool			canceled;
26 	transfer_data *	link;
27 } transfer_data;
28 
29 
30 class EHCI : public BusManager {
31 public:
32 									EHCI(pci_info *info, Stack *stack);
33 									~EHCI();
34 
35 		status_t					Start();
36 virtual	status_t					SubmitTransfer(Transfer *transfer);
37 virtual	status_t					CancelQueuedTransfers(Pipe *pipe, bool force);
38 
39 virtual	status_t					NotifyPipeChange(Pipe *pipe,
40 										usb_change change);
41 
42 static	status_t					AddTo(Stack *stack);
43 
44 		// Port operations for root hub
45 		uint8						PortCount() { return fPortCount; };
46 		status_t					GetPortStatus(uint8 index, usb_port_status *status);
47 		status_t					SetPortFeature(uint8 index, uint16 feature);
48 		status_t					ClearPortFeature(uint8 index, uint16 feature);
49 
50 		status_t					ResetPort(uint8 index);
51 		status_t					SuspendPort(uint8 index);
52 
53 virtual	const char *				TypeName() const { return "ehci"; };
54 
55 private:
56 		// Controller resets
57 		status_t					ControllerReset();
58 		status_t					LightReset();
59 
60 		// Interrupt functions
61 static	int32						InterruptHandler(void *data);
62 		int32						Interrupt();
63 
64 		// Transfer management
65 		status_t					AddPendingTransfer(Transfer *transfer,
66 										ehci_qh *queueHead,
67 										ehci_qtd *dataDescriptor,
68 										bool directionIn);
69 		status_t					CancelAllPendingTransfers();
70 
71 static	int32						FinishThread(void *data);
72 		void						FinishTransfers();
73 static	int32						CleanupThread(void *data);
74 		void						Cleanup();
75 
76 		// Queue Head functions
77 		ehci_qh *					CreateQueueHead();
78 		status_t					InitQueueHead(ehci_qh *queueHead,
79 										Pipe *pipe);
80 		void						FreeQueueHead(ehci_qh *queueHead);
81 
82 		status_t					LinkQueueHead(ehci_qh *queueHead);
83 		status_t					LinkInterruptQueueHead(ehci_qh *queueHead,
84 										Pipe *pipe);
85 		status_t					UnlinkQueueHead(ehci_qh *queueHead,
86 										ehci_qh **freeList);
87 
88 		// Queue functions
89 		status_t					FillQueueWithRequest(Transfer *transfer,
90 										ehci_qh *queueHead,
91 										ehci_qtd **dataDescriptor,
92 										bool *directionIn);
93 		status_t					FillQueueWithData(Transfer *transfer,
94 										ehci_qh *queueHead,
95 										ehci_qtd **dataDescriptor,
96 										bool *directionIn);
97 
98 		// Descriptor functions
99 		ehci_qtd *					CreateDescriptor(
100 										size_t bufferSizeToAllocate,
101 										uint8 pid);
102 		status_t					CreateDescriptorChain(Pipe *pipe,
103 										ehci_qtd **firstDescriptor,
104 										ehci_qtd **lastDescriptor,
105 										ehci_qtd *strayDescriptor,
106 										size_t bufferSizeToAllocate,
107 										uint8 pid);
108 
109 		void						FreeDescriptor(ehci_qtd *descriptor);
110 		void						FreeDescriptorChain(ehci_qtd *topDescriptor);
111 
112 		void						LinkDescriptors(ehci_qtd *first,
113 										ehci_qtd *last, ehci_qtd *alt);
114 
115 		size_t						WriteDescriptorChain(
116 										ehci_qtd *topDescriptor,
117 										iovec *vector, size_t vectorCount);
118 		size_t						ReadDescriptorChain(ehci_qtd *topDescriptor,
119 										iovec *vector, size_t vectorCount,
120 										bool *nextDataToggle);
121 		size_t						ReadActualLength(ehci_qtd *topDescriptor,
122 										bool *nextDataToggle);
123 
124 		// Operational register functions
125 inline	void						WriteOpReg(uint32 reg, uint32 value);
126 inline	uint32						ReadOpReg(uint32 reg);
127 
128 		// Capability register functions
129 inline	uint8						ReadCapReg8(uint32 reg);
130 inline	uint16						ReadCapReg16(uint32 reg);
131 inline	uint32						ReadCapReg32(uint32 reg);
132 
133 static	pci_module_info *			sPCIModule;
134 
135 		uint8 *						fCapabilityRegisters;
136 		uint8 *						fOperationalRegisters;
137 		area_id						fRegisterArea;
138 		pci_info *					fPCIInfo;
139 		Stack *						fStack;
140 		uint32						fEnabledInterrupts;
141 
142 		// Periodic transfer framelist and interrupt entries
143 		area_id						fPeriodicFrameListArea;
144 		addr_t *					fPeriodicFrameList;
145 		interrupt_entry *			fInterruptEntries;
146 
147 		// Async transfer queue management
148 		ehci_qh *					fAsyncQueueHead;
149 		sem_id						fAsyncAdvanceSem;
150 
151 		// Maintain a linked list of transfers
152 		transfer_data *				fFirstTransfer;
153 		transfer_data *				fLastTransfer;
154 		sem_id						fFinishTransfersSem;
155 		thread_id					fFinishThread;
156 		sem_id						fCleanupSem;
157 		thread_id					fCleanupThread;
158 		bool						fStopThreads;
159 		ehci_qh *					fFreeListHead;
160 		Pipe *						fProcessingPipe;
161 
162 		// Root Hub
163 		EHCIRootHub *				fRootHub;
164 		uint8						fRootHubAddress;
165 
166 		// Port management
167 		uint8						fPortCount;
168 		uint16						fPortResetChange;
169 		uint16						fPortSuspendChange;
170 };
171 
172 
173 class EHCIRootHub : public Hub {
174 public:
175 									EHCIRootHub(Object *rootObject,
176 										int8 deviceAddress);
177 
178 static	status_t					ProcessTransfer(EHCI *ehci,
179 										Transfer *transfer);
180 };
181 
182 
183 #endif // !EHCI_H
184