xref: /haiku/src/add-ons/kernel/busses/usb/uhci.h (revision b9a5b9a6ee494261f2882bfc0ee9fde92282bef6)
1 /*
2  * Copyright 2004-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  *		Niels S. Reedijk
8  */
9 
10 #ifndef UHCI_H
11 #define UHCI_H
12 
13 #include "usb_p.h"
14 #include "uhci_hardware.h"
15 #include <lock.h>
16 
17 #define UHCI_INTERRUPT_QUEUE				0
18 #define UHCI_LOW_SPEED_CONTROL_QUEUE		1
19 #define UHCI_FULL_SPEED_CONTROL_QUEUE		2
20 #define UHCI_BULK_QUEUE						3
21 #define UHCI_BANDWIDTH_RECLAMATION_QUEUE	4
22 
23 struct pci_info;
24 struct pci_module_info;
25 class UHCIRootHub;
26 
27 
28 class Queue {
29 public:
30 									Queue(Stack *stack);
31 									~Queue();
32 
33 		bool						Lock();
34 		void						Unlock();
35 
36 		status_t					InitCheck();
37 
38 		status_t					LinkTo(Queue *other);
39 		status_t					TerminateByStrayDescriptor();
40 
41 		status_t					AppendTransfer(uhci_qh *transfer);
42 		status_t					RemoveTransfer(uhci_qh *transfer);
43 
44 		addr_t						PhysicalAddress();
45 
46 		void						PrintToStream();
47 
48 private:
49 		status_t					fStatus;
50 		Stack						*fStack;
51 		uhci_qh						*fQueueHead;
52 		uhci_td						*fStrayDescriptor;
53 		uhci_qh						*fQueueTop;
54 		benaphore					fLock;
55 };
56 
57 
58 typedef struct transfer_data_s {
59 	Transfer		*transfer;
60 	Queue			*queue;
61 	uhci_qh			*transfer_queue;
62 	uhci_td			*first_descriptor;
63 	uhci_td			*data_descriptor;
64 	area_id			user_area;
65 	bool			incoming;
66 	transfer_data_s	*link;
67 } transfer_data;
68 
69 
70 class UHCI : public BusManager {
71 public:
72 									UHCI(pci_info *info, Stack *stack);
73 									~UHCI();
74 
75 		status_t					Start();
76 virtual	status_t					SubmitTransfer(Transfer *transfer);
77 virtual status_t					CancelQueuedTransfers(Pipe *pipe);
78 		status_t					SubmitRequest(Transfer *transfer);
79 		status_t					SubmitIsochronous(Transfer *transfer);
80 
81 static	status_t					AddTo(Stack *stack);
82 
83 		// Port operations
84 		status_t					GetPortStatus(uint8 index, usb_port_status *status);
85 		status_t					SetPortFeature(uint8 index, uint16 feature);
86 		status_t					ClearPortFeature(uint8 index, uint16 feature);
87 
88 		status_t					ResetPort(uint8 index);
89 
90 private:
91 		// Controller resets
92 		void						GlobalReset();
93 		status_t					ControllerReset();
94 
95 		// Interrupt functions
96 static	int32						InterruptHandler(void *data);
97 		int32						Interrupt();
98 
99 		// Transfer functions
100 		status_t					AddPendingTransfer(Transfer *transfer,
101 										Queue *queue,
102 										uhci_qh *transferQueue,
103 										uhci_td *firstDescriptor,
104 										uhci_td *dataDescriptor,
105 										bool directionIn);
106 static	int32						FinishThread(void *data);
107 		void						FinishTransfers();
108 
109 		status_t					CreateFilledTransfer(Transfer *transfer,
110 										uhci_td **_firstDescriptor,
111 										uhci_qh **_transferQueue);
112 
113 		// Transfer queue functions
114 		uhci_qh						*CreateTransferQueue(uhci_td *descriptor);
115 		void						FreeTransferQueue(uhci_qh *queueHead);
116 
117 		// Descriptor functions
118 		uhci_td						*CreateDescriptor(Pipe *pipe,
119 										uint8 direction,
120 										size_t bufferSizeToAllocate);
121 		status_t					CreateDescriptorChain(Pipe *pipe,
122 										uhci_td **firstDescriptor,
123 										uhci_td **lastDescriptor,
124 										uint8 direction,
125 										size_t bufferSizeToAllocate);
126 
127 		void						FreeDescriptor(uhci_td *descriptor);
128 		void						FreeDescriptorChain(uhci_td *topDescriptor);
129 
130 		void						LinkDescriptors(uhci_td *first,
131 										uhci_td *second);
132 
133 		size_t						WriteDescriptorChain(uhci_td *topDescriptor,
134 										iovec *vector, size_t vectorCount);
135 		size_t						ReadDescriptorChain(uhci_td *topDescriptor,
136 										iovec *vector, size_t vectorCount,
137 										uint8 *lastDataToggle);
138 		size_t						ReadActualLength(uhci_td *topDescriptor,
139 										uint8 *lastDataToggle);
140 
141 		// Register functions
142 inline	void						WriteReg8(uint32 reg, uint8 value);
143 inline	void						WriteReg16(uint32 reg, uint16 value);
144 inline	void						WriteReg32(uint32 reg, uint32 value);
145 inline	uint8						ReadReg8(uint32 reg);
146 inline	uint16						ReadReg16(uint32 reg);
147 inline	uint32						ReadReg32(uint32 reg);
148 
149 static	pci_module_info				*sPCIModule;
150 
151 		uint32						fRegisterBase;
152 		pci_info					*fPCIInfo;
153 		Stack						*fStack;
154 
155 		// Frame list memory
156 		area_id						fFrameArea;
157 		addr_t						*fFrameList;
158 
159 		// fFrameBandwidth[n] holds the available bandwidth
160 		// of the nth frame in microseconds
161 		int32						*fFrameBandwidth;
162 
163 		// Queues
164 		int32						fQueueCount;
165 		Queue						**fQueues;
166 
167 		// Maintain a linked list of transfers
168 		transfer_data				*fFirstTransfer;
169 		transfer_data				*fLastTransfer;
170 		sem_id						fFinishTransfersSem;
171 		thread_id					fFinishThread;
172 		bool						fStopFinishThread;
173 
174 		// Root hub
175 		UHCIRootHub					*fRootHub;
176 		uint8						fRootHubAddress;
177 		uint8						fPortResetChange;
178 };
179 
180 
181 class UHCIRootHub : public Hub {
182 public:
183 									UHCIRootHub(Object *rootObject,
184 										int8 deviceAddress);
185 
186 static	status_t					ProcessTransfer(UHCI *uhci,
187 										Transfer *transfer);
188 };
189 
190 
191 #endif
192