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