forked from RehabMan/OS-X-Generic-USB3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
V2Overrides.cpp
147 lines (134 loc) · 3.85 KB
/
V2Overrides.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//
// V2Overrides.cpp
// GenericUSBXHCI
//
// Created by Zenith432 on December 26th, 2012.
// Copyright (c) 2012-2013 Zenith432. All rights reserved.
//
#include "GenericUSBXHCI.h"
#include "Isoch.h"
#define CLASS GenericUSBXHCI
#define super IOUSBControllerV3
#pragma mark -
#pragma mark IOUSBControllerV2 Overrides
#pragma mark -
IOReturn CLASS::ConfigureDeviceZero(UInt8 maxPacketSize, UInt8 speed, USBDeviceAddress hub, int port)
{
uint16_t _port = static_cast<uint16_t>(port);
if (hub == _hub2Address || hub == _hub3Address) {
_port = PortNumberProtocolToCanonical(_port, (hub == _hub3Address ? kUSBDeviceSpeedSuper : kUSBDeviceSpeedHigh));
if (_port >= _rootHubNumPorts)
return kIOReturnNoDevice;
++_port;
}
_deviceZero.PortOnHub = _port;
_deviceZero.HubAddress = hub;
return super::ConfigureDeviceZero(maxPacketSize, speed, hub, _port);
}
IOReturn CLASS::UIMHubMaintenance(USBDeviceAddress highSpeedHub, UInt32 highSpeedPort, UInt32 command, UInt32 flags)
{
if (command == kUSBHSHubCommandRemoveHub)
return kIOReturnSuccess;
if (command != kUSBHSHubCommandAddHub)
return kIOReturnBadArgument;
return configureHub(highSpeedHub, flags);
}
IOReturn CLASS::UIMSetTestMode(UInt32 mode, UInt32 port)
{
switch (mode) {
case 0U:
case 1U:
case 2U:
case 3U:
case 4U:
case 5U:
if (!_inTestMode)
break;
return PlacePortInMode(port, mode);
case 10U:
return EnterTestMode();
case 11U:
return LeaveTestMode();
}
return kIOReturnInternalError;
}
UInt64 CLASS::GetMicroFrameNumber(void)
{
uint64_t counter1, counter2;
uint32_t sts, mfIndex, count;
sts = Read32Reg(&_pXHCIOperationalRegisters->USBSts);
if (m_invalid_regspace || (sts & XHCI_STS_HCH))
return 0ULL;
/*
* TBD: For 32-bit compile, access to _millsecondCounter
* is non-atomic, here vs FilterEventRing.
*/
for (count = 0U; count < 2U; ++count) {
if (count)
IODelay(126U);
counter1 = _millsecondCounter;
mfIndex = Read32Reg(&_pXHCIRuntimeRegisters->MFIndex);
counter2 = _millsecondCounter;
if (m_invalid_regspace)
return 0ULL;
if (counter1 != counter2) {
/*
* Note: This can only happen if a primary
* interrupt takes place between readings,
* so use the 2nd reading and assume
* MFIndex 0.
*/
return counter2 << 3;
}
mfIndex &= XHCI_MFINDEX_MASK;
if (mfIndex)
break;
/*
* Note: XHCI allows controllers to halt the
* clock if no device is connected. Some,
* such as the Renesas uPD720200a don't
* generate timer interrupts when no device
* is connected initially. No need to delay.
*/
if (!counter1)
break;
}
return (counter1 << 3) + mfIndex;
}
IOReturn CLASS::UIMCreateIsochEndpoint(short functionAddress, short endpointNumber, UInt32 maxPacketSize, UInt8 direction,
USBDeviceAddress highSpeedHub, int highSpeedPort, UInt8 interval)
{
uint32_t maxBurst = 0U;
/*
* Preprocessing code added OS 10.8.3
*/
if (maxPacketSize > kUSB_EPDesc_MaxMPS) {
maxBurst = ((maxPacketSize + kUSB_EPDesc_MaxMPS - 1U) / kUSB_EPDesc_MaxMPS);
maxPacketSize = (maxPacketSize + maxBurst - 1U) / maxBurst;
--maxBurst;
}
return CreateIsochEndpoint(functionAddress, endpointNumber, maxPacketSize, direction, interval, maxBurst, 0U);
}
IOUSBControllerIsochEndpoint* CLASS::AllocateIsochEP(void)
{
GenericUSBXHCIIsochEP* obj = OSTypeAlloc(GenericUSBXHCIIsochEP);
if (obj && !obj->init()) {
obj->release();
obj = 0;
}
return obj;
}
IODMACommand* CLASS::GetNewDMACommand(void)
{
return IODMACommand::withSpecification(IODMACommand::OutputHost64,
XHCI_HCC_AC64(_HCCLow) ? 64U : 32U,
0U);
}
IOReturn CLASS::GetFrameNumberWithTime(UInt64* frameNumber, AbsoluteTime* theTime)
{
if (!frameNumber || !theTime)
return kIOReturnBadArgument;
if (!_commandGate)
return kIOReturnUnsupported;
return _commandGate->runAction(GatedGetFrameNumberWithTime, frameNumber, theTime);
}