2 * Copyright 2005-2013, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
7 * Salvatore Benedetto <salvatore.benedetto@gmail.com>
8 * Michael Lotz <mmlr@mlotz.ch>
9 * Siarzhuk Zharski <imker@gmx.li>
14 #include "usb_private.h"
15 #include "ohci_hardware.h"
19 struct pci_module_info
;
20 struct pci_x86_module_info
;
23 typedef struct transfer_data
{
25 ohci_endpoint_descriptor
* endpoint
;
26 ohci_general_td
* first_descriptor
;
27 ohci_general_td
* data_descriptor
;
28 ohci_general_td
* last_descriptor
;
35 class OHCI
: public BusManager
{
37 OHCI(pci_info
*info
, Stack
*stack
);
41 virtual status_t
SubmitTransfer(Transfer
*transfer
);
42 virtual status_t
CancelQueuedTransfers(Pipe
*pipe
,
45 virtual status_t
NotifyPipeChange(Pipe
*pipe
,
48 static status_t
AddTo(Stack
*stack
);
51 uint8
PortCount() { return fPortCount
; };
52 status_t
GetPortStatus(uint8 index
,
53 usb_port_status
*status
);
54 status_t
SetPortFeature(uint8 index
, uint16 feature
);
55 status_t
ClearPortFeature(uint8 index
, uint16 feature
);
57 status_t
ResetPort(uint8 index
);
59 virtual const char * TypeName() const { return "ohci"; };
62 // Interrupt functions
63 static int32
_InterruptHandler(void *data
);
67 status_t
_AddPendingTransfer(Transfer
*transfer
,
68 ohci_endpoint_descriptor
*endpoint
,
69 ohci_general_td
*firstDescriptor
,
70 ohci_general_td
*dataDescriptor
,
71 ohci_general_td
*lastDescriptor
,
73 status_t
_AddPendingIsochronousTransfer(
75 ohci_endpoint_descriptor
*endpoint
,
76 ohci_isochronous_td
*firstDescriptor
,
77 ohci_isochronous_td
*lastDescriptor
,
80 status_t
_UnlinkTransfer(transfer_data
*transfer
);
82 static int32
_FinishThread(void *data
);
83 void _FinishTransfers();
84 bool _FinishIsochronousTransfer(
85 transfer_data
*transfer
,
86 transfer_data
**_lastTransfer
);
88 status_t
_SubmitRequest(Transfer
*transfer
);
89 status_t
_SubmitTransfer(Transfer
*transfer
);
90 status_t
_SubmitIsochronousTransfer(
93 void _SwitchEndpointTail(
94 ohci_endpoint_descriptor
*endpoint
,
95 ohci_general_td
*first
,
96 ohci_general_td
*last
);
97 void _SwitchIsochronousEndpointTail(
98 ohci_endpoint_descriptor
*endpoint
,
99 ohci_isochronous_td
*first
,
100 ohci_isochronous_td
*last
);
102 void _RemoveTransferFromEndpoint(
103 transfer_data
*transfer
);
105 // Endpoint related methods
106 ohci_endpoint_descriptor
* _AllocateEndpoint();
108 ohci_endpoint_descriptor
*endpoint
);
109 status_t
_InsertEndpointForPipe(Pipe
*pipe
);
110 status_t
_RemoveEndpointForPipe(Pipe
*pipe
);
111 ohci_endpoint_descriptor
* _FindInterruptEndpoint(uint8 interval
);
113 // Transfer descriptor related methods
114 ohci_general_td
* _CreateGeneralDescriptor(
116 void _FreeGeneralDescriptor(
117 ohci_general_td
*descriptor
);
118 status_t
_CreateDescriptorChain(
119 ohci_general_td
**firstDescriptor
,
120 ohci_general_td
**lastDescriptor
,
123 void _FreeDescriptorChain(
124 ohci_general_td
*topDescriptor
);
126 ohci_isochronous_td
* _CreateIsochronousDescriptor(
128 void _FreeIsochronousDescriptor(
129 ohci_isochronous_td
*descriptor
);
130 status_t
_CreateIsochronousDescriptorChain(
131 ohci_isochronous_td
**firstDescriptor
,
132 ohci_isochronous_td
**lastDescriptor
,
134 void _FreeIsochronousDescriptorChain(
135 ohci_isochronous_td
*topDescriptor
);
137 size_t _WriteDescriptorChain(
138 ohci_general_td
*topDescriptor
,
139 iovec
*vector
, size_t vectorCount
);
140 size_t _ReadDescriptorChain(
141 ohci_general_td
*topDescriptor
,
142 iovec
*vector
, size_t vectorCount
);
144 size_t _WriteIsochronousDescriptorChain(
145 ohci_isochronous_td
*topDescriptor
,
146 iovec
*vector
, size_t vectorCount
);
147 void _ReadIsochronousDescriptorChain(
148 ohci_isochronous_td
*topDescriptor
,
149 iovec
*vector
, size_t vectorCount
);
151 size_t _ReadActualLength(
152 ohci_general_td
*topDescriptor
);
154 void _LinkDescriptors(ohci_general_td
*first
,
155 ohci_general_td
*second
);
156 void _LinkIsochronousDescriptors(
157 ohci_isochronous_td
*first
,
158 ohci_isochronous_td
*second
,
159 ohci_isochronous_td
*nextDone
);
161 bool _AllocateIsochronousBandwidth(uint16 frame
,
163 void _ReleaseIsochronousBandwidth(
164 uint16 startFrame
, uint16 count
);
166 status_t
_GetStatusOfConditionCode(
167 uint8 conditionCode
);
169 bool _LockEndpoints();
170 void _UnlockEndpoints();
172 // Register functions
173 inline void _WriteReg(uint32 reg
, uint32 value
);
174 inline uint32
_ReadReg(uint32 reg
);
178 ohci_endpoint_descriptor
*endpoint
);
179 void _PrintDescriptorChain(
180 ohci_general_td
*topDescriptor
);
181 void _PrintDescriptorChain(
182 ohci_isochronous_td
*topDescriptor
);
184 static pci_module_info
* sPCIModule
;
185 static pci_x86_module_info
* sPCIx86Module
;
190 uint8
* fOperationalRegisters
;
191 area_id fRegisterArea
;
193 // Host Controller Communication Area related stuff
196 ohci_endpoint_descriptor
** fInterruptEndpoints
;
198 // Endpoint management
200 ohci_endpoint_descriptor
* fDummyControl
;
201 ohci_endpoint_descriptor
* fDummyBulk
;
202 ohci_endpoint_descriptor
* fDummyIsochronous
;
204 // Maintain a linked list of transfer
205 transfer_data
* fFirstTransfer
;
206 transfer_data
* fLastTransfer
;
207 sem_id fFinishTransfersSem
;
208 thread_id fFinishThread
;
209 bool fStopFinishThread
;
210 Pipe
* fProcessingPipe
;
211 // frame bandwidth watchdogs array
212 uint16
* fFrameBandwidth
;
215 OHCIRootHub
* fRootHub
;
216 uint8 fRootHubAddress
;
226 class OHCIRootHub
: public Hub
{
228 OHCIRootHub(Object
*rootObject
,
231 static status_t
ProcessTransfer(OHCI
*ohci
,