xref: /haiku/src/add-ons/kernel/busses/usb/ehci.h (revision 3cb015b1ee509d69c643506e8ff573808c86dcfc)
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 	area_id			user_area;
26 	bool			incoming;
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 		status_t					SubmitPeriodicTransfer(Transfer *transfer);
39 		status_t					SubmitAsyncTransfer(Transfer *transfer);
40 
41 virtual	status_t					NotifyPipeChange(Pipe *pipe,
42 										usb_change change);
43 
44 static	status_t					AddTo(Stack *stack);
45 
46 		// Port operations for root hub
47 		uint8						PortCount() { return fPortCount; };
48 		status_t					GetPortStatus(uint8 index, usb_port_status *status);
49 		status_t					SetPortFeature(uint8 index, uint16 feature);
50 		status_t					ClearPortFeature(uint8 index, uint16 feature);
51 
52 		status_t					ResetPort(uint8 index);
53 		status_t					SuspendPort(uint8 index);
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					CancelPendingTransfer(Transfer *transfer);
70 		status_t					CancelAllPendingTransfers();
71 
72 static	int32						FinishThread(void *data);
73 		void						FinishTransfers();
74 static	int32						CleanupThread(void *data);
75 		void						Cleanup();
76 
77 		// Queue Head functions
78 		ehci_qh						*CreateQueueHead();
79 		void						FreeQueueHead(ehci_qh *queueHead);
80 
81 		status_t					LinkQueueHead(ehci_qh *queueHead);
82 		status_t					UnlinkQueueHead(ehci_qh *queueHead,
83 										ehci_qh **freeList);
84 
85 		// Queue functions
86 		status_t					FillQueueWithRequest(Transfer *transfer,
87 										ehci_qh *queueHead,
88 										ehci_qtd **dataDescriptor,
89 										bool *directionIn);
90 		status_t					FillQueueWithData(Transfer *transfer,
91 										ehci_qh *queueHead,
92 										ehci_qtd **dataDescriptor,
93 										bool *directionIn);
94 
95 		// Descriptor functions
96 		ehci_qtd					*CreateDescriptor(size_t bufferSizeToAllocate,
97 										uint8 pid);
98 		status_t					CreateDescriptorChain(Pipe *pipe,
99 										ehci_qtd **firstDescriptor,
100 										ehci_qtd **lastDescriptor,
101 										ehci_qtd *strayDescriptor,
102 										size_t bufferSizeToAllocate,
103 										uint8 pid);
104 
105 		void						FreeDescriptor(ehci_qtd *descriptor);
106 		void						FreeDescriptorChain(ehci_qtd *topDescriptor);
107 
108 		void						LinkDescriptors(ehci_qtd *first,
109 										ehci_qtd *last, ehci_qtd *alt);
110 
111 		size_t						WriteDescriptorChain(ehci_qtd *topDescriptor,
112 										iovec *vector, size_t vectorCount);
113 		size_t						ReadDescriptorChain(ehci_qtd *topDescriptor,
114 										iovec *vector, size_t vectorCount,
115 										bool *nextDataToggle);
116 		size_t						ReadActualLength(ehci_qtd *topDescriptor,
117 										bool *nextDataToggle);
118 
119 		// Operational register functions
120 inline	void						WriteOpReg(uint32 reg, uint32 value);
121 inline	uint32						ReadOpReg(uint32 reg);
122 
123 		// Capability register functions
124 inline	uint8						ReadCapReg8(uint32 reg);
125 inline	uint16						ReadCapReg16(uint32 reg);
126 inline	uint32						ReadCapReg32(uint32 reg);
127 
128 static	pci_module_info				*sPCIModule;
129 
130 		uint8						*fCapabilityRegisters;
131 		uint8						*fOperationalRegisters;
132 		area_id						fRegisterArea;
133 		pci_info					*fPCIInfo;
134 		Stack						*fStack;
135 
136 		// Framelist memory
137 		area_id						fPeriodicFrameListArea;
138 		addr_t						*fPeriodicFrameList;
139 
140 		// Async frame list management
141 		ehci_qh						*fAsyncQueueHead;
142 		sem_id						fAsyncAdvanceSem;
143 
144 		// Maintain a linked list of transfers
145 		transfer_data				*fFirstTransfer;
146 		transfer_data				*fLastTransfer;
147 		sem_id						fFinishTransfersSem;
148 		thread_id					fFinishThread;
149 		sem_id						fCleanupSem;
150 		thread_id					fCleanupThread;
151 		bool						fStopThreads;
152 		ehci_qh						*fFreeListHead;
153 
154 		// Root Hub
155 		EHCIRootHub					*fRootHub;
156 		uint8						fRootHubAddress;
157 
158 		// Port management
159 		uint8						fPortCount;
160 		uint16						fPortResetChange;
161 		uint16						fPortSuspendChange;
162 };
163 
164 
165 class EHCIRootHub : public Hub {
166 public:
167 									EHCIRootHub(Object *rootObject,
168 										int8 deviceAddress);
169 
170 static	status_t					ProcessTransfer(EHCI *ehci,
171 										Transfer *transfer);
172 };
173 
174 
175 #endif // !EHCI_H
176