IOReturn AppleUSBUHCI::ClearRootHubPortFeature(UInt16 wValue, UInt16 port) { UInt16 value; USBLog(5, "AppleUSBUHCI[%p]::ClearRootHubPortFeature %d %d", this, wValue, port); switch(wValue) { case kUSBHubPortEnableFeature : USBLog(5, "AppleUSBUHCI[%p]: Clear port enable", this); RHEnablePort(port, false); break; case kUSBHubPortConnectionChangeFeature : USBLog(5, "AppleUSBUHCI[%p]: Clear connection change", this); value = ReadPortStatus(port-1) & kUHCI_PORTSC_MASK; WritePortStatus(port-1, value | kUHCI_PORTSC_CSC); break; case kUSBHubPortEnableChangeFeature : USBLog(5, "AppleUSBUHCI[%p]: Clear port enable change", this); value = ReadPortStatus(port-1) & kUHCI_PORTSC_MASK; WritePortStatus(port-1, value | kUHCI_PORTSC_PEDC); break; case kUSBHubPortResetChangeFeature : USBLog(5, "AppleUSBUHCI[%p]: Clear port reset change", this); _portWasReset[port-1] = false; break; case kUSBHubPortSuspendFeature : RHSuspendPort(port, false); break; case kUSBHubPortSuspendChangeFeature : USBLog(5, "AppleUSBUHCI[%p]: Clear port suspend change", this); _portSuspendChange[port-1] = false; break; #if 0 // These will all fall through to return unsupported. case kUSBHubPortOverCurrentChangeFeature : RHResetOverCurrentChange(port); break; case kUSBHubPortPowerFeature : //status = RHPortPort(port, false); break; #endif default: USBLog(5,"AppleUSBUHCI[%p]: clear unknown feature %d", this, wValue); break; } return kIOReturnSuccess; }
void AppleUSBUHCI::RHCheckStatus() { int i; UInt16 status; /* Read port status registers. * Check for resumed ports. * If the status changed on either, call the * port status changed method. */ for (i=0; i<kUHCI_NUM_PORTS; i++) { if (!_rhPortBeingResumed[i]) // only check ports which are not being resumed { status = ReadPortStatus(i); if (status & kUHCI_PORTSC_RD) { if (_myPowerState >= kUSBPowerStateLowPower) { if (_myPowerState == kUSBPowerStateLowPower) EnsureUsability(); USBLog(3, "AppleUSBUHCI[%p]::RHCheckStatus - resume detected on port %d, spawning thread to resume", this, i+1); _rhPortBeingResumed[i] = true; thread_call_enter1(_rhResumePortTimerThread[i], (void*)(i+1)); } else { USBLog(3, "AppleUSBUHCI[%p]::RHCheckStatus - resume detected while not below low power state, not changing bits until we are back on", this); } } } } }
bool AppleUSBUHCI::RHAreAllPortsDisconnectedOrSuspended( void ) { int i; UInt16 status; bool result = true; for (i=0; i<kUHCI_NUM_PORTS; i++) { status = ReadPortStatus(i); if ((status & kUHCI_PORTSC_CCS) && !(status & kUHCI_PORTSC_SUSPEND)) { result = false; break; } } // If we have pending bulk or control transactions, then force the result to false if ( result ) { if ( _controlBulkTransactionsOut != 0 ) { USBLog(2, "AppleUSBUHCI[%p]::RHAreAllPortsDisconnectedOrSuspended everything disconnected, but %d control/bulk transactions are pending. ", this, (uint32_t)_controlBulkTransactionsOut); result = false; } } USBLog(result ? 2 : 6, "AppleUSBUHCI[%p]::RHAreAllPortsDisconnectedOrSuspended returns %d", this, result); return result; }
IOReturn AppleUSBUHCI::RHResumePortCompletion(UInt32 port) { UInt16 value; USBLog(5, "AppleUSBUHCI[%p]::RHResumePortCompletion - finishing resume on port %d", this, (int)port); if (!_rhPortBeingResumed[port-1]) { USBLog(1, "AppleUSBUHCI[%p]::RHResumePortCompletion - port %d does not appear to be resuming!", this, (int)port); USBTrace( kUSBTUHCI, kTPUHCIRHResumePortCompletion, (uintptr_t)this, (int)port, 0, kIOReturnInternalError ); return kIOReturnInternalError; } if (!_controllerAvailable) { USBLog(5, "AppleUSBEHCI[%p]::RHResumePortCompletion - cannot finish resume on port %d because the controller is unavailable", this, (int)port); _rhPortBeingResumed[port-1] = false; return kIOReturnInternalError; } value = ReadPortStatus(port-1) & kUHCI_PORTSC_MASK; value &= ~(kUHCI_PORTSC_RD | kUHCI_PORTSC_SUSPEND); USBLog(5, "AppleUSBUHCI[%p]: de-asserting resume signal by writing (%p)", this, (void*)value); WritePortStatus(port-1, value); IOSync(); IOSleep(2); // allow it to kick in _rhPortBeingResumed[port-1] = false; _portSuspendChange[port-1] = true; EnsureUsability(); return kIOReturnSuccess; }
/* ==== debugging ==== */ void AppleUSBUHCI::RHDumpPortStatus(int port) { UInt16 value; char buf[64]; static struct { UInt16 mask; const char *string; } strings[] = { {kUHCI_PORTSC_SUSPEND, "SUSPEND "}, {kUHCI_PORTSC_RESET, "RESET "}, {kUHCI_PORTSC_LS, "LS "}, {kUHCI_PORTSC_RD, "RD "}, {kUHCI_PORTSC_LINE0, "LINE0 "}, {kUHCI_PORTSC_LINE1, "LINE1 "}, {kUHCI_PORTSC_PEDC, "PEDC "}, {kUHCI_PORTSC_PED, "PED "}, {kUHCI_PORTSC_CSC, "CSC "}, {kUHCI_PORTSC_CCS, "CCS"}, {0,0} }; int i; port--; // convert 1-based to 0-based. buf[0] = '\0'; value = ReadPortStatus(port); for (i=0; strings[i].string != 0; i++) { if ((value & strings[i].mask) != 0) { strlcat(buf, strings[i].string, sizeof(buf)); } } USBLog(7, "AppleUSBUHCI[%p]: Port %d: status %x %s", this, port+1, value, buf); }
// Print Port Status: // bit 0-1 => port 0, bit 2-3 => port 1, bit 4-5 => port 2 // 0: wait for job, 1: paper out, 2:off line, 3:busy (is printing) // BYTE ReadPrintStatus( void ) { BYTE i, rc = 0; for( i = 0 ; i < NUM_OF_PRN_PORT; i++ ) { rc |= ( ReadPortStatus(i) << ( 2 * i ) ); } return rc; }
//================================================================================================ // // SuspendController // //================================================================================================ // void AppleUSBUHCI::SuspendController(void) { UInt16 cmd, value; int i; USBTrace( kUSBTUHCI, kTPUHCISuspendController, (uintptr_t)this, 0, 0, 1 ); USBLog(5, "AppleUSBUHCI[%p]::SuspendController", this); USBLog(5, "AppleUSBUHCI[%p]: cmd state %x, status %x", this, ioRead16(kUHCI_CMD), ioRead16(kUHCI_STS)); // Stop the controller Run(false); for (i=0; i< 2; i++) { value = ReadPortStatus(i) & kUHCI_PORTSC_MASK; if (value & kUHCI_PORTSC_PED) { if (value & kUHCI_PORTSC_SUSPEND) { USBLog(5, "AppleUSBUHCI[%p]::SuspendController - port[%d] is suspended [%p]", this, i, (void*)value); } else { USBLog(5, "AppleUSBUHCI[%p]::SuspendController - port[%d] is enabled but not suspended [%p]", this, i, (void*)value); } } else { USBLog(5, "AppleUSBUHCI[%p]::SuspendController - port[%d] is not enabled [%p]", this, i, (void*)value); } // only do this for controllers with overcurrent additions. if ((_ERRATA64BITS & kErrataUHCISupportsOvercurrent) && (value & kUHCI_PORTSC_OCI)) // Is the latched Overcurrent set? { // if so, clear it or we won't suspend. USBLog(1, "AppleUSBUHCI[%p]::SuspendController - port[%d] had the overcurrent bit set. Clearing it", this, i); USBTrace( kUSBTUHCI, kTPUHCISuspendController, (uintptr_t)this, i, 0, 2 ); WritePortStatus(i, kUHCI_PORTSC_OCI); // clear overcurrent indicator } } // Put the controller in Global Suspend cmd = ioRead16(kUHCI_CMD) & ~kUHCI_CMD_FGR; cmd |= kUHCI_CMD_EGSM; ioWrite16(kUHCI_CMD, cmd); _myBusState = kUSBBusStateSuspended; IOSleep(3); USBLog(5, "AppleUSBUHCI[%p]: suspend done, cmd %x, status %x", this, ioRead16(kUHCI_CMD), ioRead16(kUHCI_STS)); }
// Reset and enable the port IOReturn AppleUSBUHCI::RHHoldPortReset(int port) { UInt16 value; int i; USBLog(1, "AppleUSBUHCI[%p]::RHHoldPortReset %d", this, port); USBTrace( kUSBTUHCI, kTPUHCIRHHoldPortReset, (uintptr_t)this, (int)port, 0, 0); port--; // convert 1-based to 0-based. value = ReadPortStatus(port) & kUHCI_PORTSC_MASK; WritePortStatus(port, value | kUHCI_PORTSC_RESET); return kIOReturnSuccess; }
void AppleUSBUHCI::RHEnablePort(int port, bool enable) { UInt16 value; // USBLog(5, "AppleUSBUHCI[%p]::RHEnablePort %d %d", this, port, enable); port--; // convert 1-based to 0-based. value = ReadPortStatus(port) & kUHCI_PORTSC_MASK; USBLog(3, "AppleUSBUHCI[%p]::RHEnablePort port: %d enable: %d PortSC: 0x%x", this, port+1, enable, value); USBLog(2, "AppleUSBUHCI[%p]::RHEnablePort (CMD:%p STS:%p INTR:%p PORTSC1:%p PORTSC2:%p FRBASEADDR:%p FRNUM:%p, SOFMOD:%p, ConfigCMD:%p)", this, (void*)ioRead16(kUHCI_CMD), (void*)ioRead16(kUHCI_STS), (void*)ioRead16(kUHCI_INTR), (void*)ioRead16(kUHCI_PORTSC1), (void*)ioRead16(kUHCI_PORTSC2), (void*)ioRead32(kUHCI_FRBASEADDR), (void*)ioRead32(kUHCI_FRNUM), (void*)ioRead32(kUHCI_SOFMOD), (void*)_device->configRead16(kIOPCIConfigCommand)); if (enable) { value |= kUHCI_PORTSC_PED; } else { value &= ~kUHCI_PORTSC_PED; } WritePortStatus(port, value); }
//================================================================================================ // // RestoreControllerStateFromSleep // //================================================================================================ // IOReturn AppleUSBUHCI::RestoreControllerStateFromSleep(void) { int i; UInt16 value; bool wakeMsg = false; USBLog(5, "AppleUSBUHCI[%p]::RestoreControllerStateFromSleep RUN - resuming controller", this); for (i=0; i< 2; i++) { value = ReadPortStatus(i); if (value & kUHCI_PORTSC_CSC) { USBLog(5, "AppleUSBUHCI[%p]::RestoreControllerStateFromSleep Port %d on bus 0x%x connected or disconnected", this, (int)i+1, (uint32_t)_busNumber); // IOLog("USB (UHCI):Port %d on bus 0x%x connected or disconnected\n", (int)i+1, (uint32_t)_busNumber); } else if (value & kUHCI_PORTSC_RD) { USBLog(5, "AppleUSBUHCI[%p]::RestoreControllerStateFromSleep Port %d on bus 0x%x has remote wakeup from some device", this, (int)i+1, (uint32_t)_busNumber); // because of how UHCI works, the root hub driver might not be able to detect that there was a remote wakeup // on a port if the upper level driver issues a Resume before the root hub interrupt timer runs // Let the hub driver know that from here to make sure we get the log if (_rootHubDevice && _rootHubDevice->GetPolicyMaker()) { _rootHubDevice->GetPolicyMaker()->message(kIOUSBMessageRootHubWakeEvent, this, (void *)(uintptr_t) i); } else { IOLog("USB (UHCI):Port %d on bus 0x%x has remote wakeup from some device\n", (int)i+1, (uint32_t)_busNumber); } } } ResumeController(); return kIOReturnSuccess; }
//================================================================================================ // // WakeControllerFromDoze // //================================================================================================ // IOReturn AppleUSBUHCI::WakeControllerFromDoze(void) { UInt16 cmd; int i; bool portHasRD[kUHCI_NUM_PORTS]; UInt16 status; USBTrace( kUSBTUHCI, KTPUHCIWakeFromDoze, (uintptr_t)this, 0, 0, 0); // First, see if we have any ports that have the RD bit set. If they do, then we can go ahead and clear it after we waited the 20ms for the // Global resume for (i=0; i<kUHCI_NUM_PORTS; i++) { status = ReadPortStatus(i); if (status & kUHCI_PORTSC_RD) { USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze controller port %d has kUHCI_PORTSC_RD set", this, i+1); portHasRD[i] = true; } else { portHasRD[i] = false; } } // If we are in Global Suspend mode, we need to resume the controller. We will wait 20ms with the gate held. However, since we only // get into this mode if all devices are suspended, then delaying while holding the wl will not prevent any completions from happening, since // there aren't any. cmd = ioRead16(kUHCI_CMD); if (cmd & kUHCI_CMD_EGSM) { USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze controller is globally suspended - forcing resume", this); cmd |= kUHCI_CMD_FGR; ioWrite16(kUHCI_CMD, cmd); cmd = ioRead16(kUHCI_CMD); USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze after EGSM->FGR, cmd is[%p], sleeping 20ms", this, (void*)cmd); IOSleep(20); cmd &= ~kUHCI_CMD_FGR; cmd &= ~kUHCI_CMD_EGSM; ioWrite16(kUHCI_CMD, cmd); // Clear any RD bits in the port if they were set, now that we have waited 20ms for (i=0; i<kUHCI_NUM_PORTS; i++) { if (portHasRD[i] ) { status = ReadPortStatus(i) & kUHCI_PORTSC_MASK; status &= ~(kUHCI_PORTSC_RD | kUHCI_PORTSC_SUSPEND); USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze de-asserting resume signal for port %d by writing (%p)", this, i+1, (void*)status); WritePortStatus(i, status); IOSync(); IOSleep(2); // allow it to kick in } } } USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze calling Run(true)", this); Run(true); _myBusState = kUSBBusStateRunning; showRegisters(7, "-WakeControllerFromDoze"); return kIOReturnSuccess; }
//================================================================================================ // // ResumeController // //================================================================================================ // void AppleUSBUHCI::ResumeController(void) { UInt16 cmd; int i; USBTrace( kUSBTUHCI, KTPUHCIResumeController , (uintptr_t)this, 0, 0, 0); showRegisters(7, "+ResumeController"); cmd = ioRead16(kUHCI_CMD); if (cmd & kUHCI_CMD_RS) { USBLog(3, "AppleUSBUHCI[%p]::ResumeController - already running - returning", this); return; } // I need to save the existing frame list before I turn on processing so I can send SOF only for 10ms after we turn the controller on for (i=0;i < kUHCI_NVFRAMES; i++) { _frameList[i] |= HostToUSBLong(kUHCI_FRAME_T); } if (cmd & kUHCI_CMD_EGSM) { USBLog(5, "AppleUSBUHCI[%p]::ResumeController controller is globally suspended - forcing resume", this); cmd |= kUHCI_CMD_FGR; ioWrite16(kUHCI_CMD, cmd); cmd = ioRead16(kUHCI_CMD); USBLog(5, "AppleUSBUHCI[%p]::ResumeController after EGSM->FGR, cmd is[%p]", this, (void*)cmd); } if (cmd & kUHCI_CMD_FGR) { // this could either be because the remote wwakeup caused this state or because we did above // need to wait 20ms IOSleep(20); cmd &= ~kUHCI_CMD_FGR; cmd &= ~kUHCI_CMD_EGSM; ioWrite16(kUHCI_CMD, cmd); } if ((cmd & (kUHCI_CMD_MAXP | kUHCI_CMD_CF)) != (kUHCI_CMD_MAXP | kUHCI_CMD_CF)) { USBLog(5, "AppleUSBUHCI[%p]::ResumeController marking MAXP and CF", this); cmd |= (kUHCI_CMD_MAXP | kUHCI_CMD_CF); ioWrite16(kUHCI_CMD, cmd); } // restore the frame list register if (_framesPaddr != NULL) { USBLog(5, "AppleUSBUHCI[%p]::ResumeController setting FRBASEADDR[%p]", this, (void*)_framesPaddr); ioWrite32(kUHCI_FRBASEADDR, _framesPaddr); } USBLog(5, "AppleUSBUHCI[%p]::ResumeController starting controller", this); Run(true); // wait 10 ms for the device to recover IOSleep(10); // restore the list for (i=0;i < kUHCI_NVFRAMES; i++) { _frameList[i] &= ~HostToUSBLong(kUHCI_FRAME_T); } USBLog(7, "AppleUSBUHCI[%p]::ResumeController resume done, cmd %x, status %x ports[%p, %p]", this, ioRead16(kUHCI_CMD), ioRead16(kUHCI_STS),(void*)ReadPortStatus(0), (void*)ReadPortStatus(1)); showRegisters(7, "-ResumeController"); }
// Reset and enable the port IOReturn AppleUSBUHCI::RHResetPort(int port) { UInt16 value; int i; USBLog(3, "AppleUSBUHCI[%p]::RHResetPort %d", this, port); port--; // convert 1-based to 0-based. value = ReadPortStatus(port) & kUHCI_PORTSC_MASK; WritePortStatus(port, value | kUHCI_PORTSC_RESET); /* Assert RESET for 50ms */ IOSleep(50); value = ReadPortStatus(port) & kUHCI_PORTSC_MASK; WritePortStatus(port, value & ~kUHCI_PORTSC_RESET); IODelay(10); value = ReadPortStatus(port) & kUHCI_PORTSC_MASK; WritePortStatus(port, value | kUHCI_PORTSC_PED); for (i=10; i>0; i--) { IOSleep(10); value = ReadPortStatus(port); if ((value & kUHCI_PORTSC_CCS) == 0) { /* No device connected; don't enter reset state. */ //USBLog(5, "%s[%p]: no device connected, not entering reset state"); return kIOReturnNotResponding; break; } if (value & (kUHCI_PORTSC_PEDC | kUHCI_PORTSC_CSC)) { /* Change bits detected. Clear them and continue waiting. */ WritePortStatus(port, (value & kUHCI_PORTSC_MASK) | (kUHCI_PORTSC_PEDC | kUHCI_PORTSC_CSC)); continue; } if (value & kUHCI_PORTSC_PED) { /* Port successfully enabled. */ break; } } if (i == 0) { USBLog(5, "AppleUSBUHCI[%p]: reset port FAILED", this); return kIOReturnNotResponding; } // Remember that we were reset _portWasReset[port] = true; USBLog(5, "AppleUSBUHCI[%p]: reset port succeeded", this); return kIOReturnSuccess; }
IOReturn AppleUSBUHCI::RHSuspendPort(int port, bool suspended) { UInt16 cmd, value; USBLog(3, "AppleUSBUHCI[%p]::RHSuspendPort %d (%s) _rhPortBeingResumed[%d](%s)", this, port, suspended ? "SUSPEND" : "RESUME", (int)port-1, _rhPortBeingResumed[port-1] ? "true" : "false"); showRegisters(7, "RHSuspendPort"); port--; // convert 1-based to 0-based. if (_rhPortBeingResumed[port]) { if (!suspended) { USBLog(3, "AppleUSBUHCI[%p]::RHSuspendPort - resume on port (%d) already being resumed - gracefully ignoring", this, (int)port+1); return kIOReturnSuccess; } USBLog(1, "AppleUSBUHCI[%p]::RHSuspendPort - trying to suspend port (%d) which is being resumed - UNEXPECTED", this, (int)port+1); USBTrace( kUSBTUHCI, kTPUHCIRHSuspendPort, (uintptr_t)this, (int)port+1, 0, 0); } cmd = ioRead16(kUHCI_CMD); value = ReadPortStatus(port) & kUHCI_PORTSC_MASK; if (suspended) { value |= kUHCI_PORTSC_SUSPEND; value &= ~kUHCI_PORTSC_RD; } else { if (cmd & kUHCI_CMD_EGSM) { /* Can't un-suspend a port during global suspend. */ USBError(1, "AppleUSBUHCI[%p]: attempt to resume during global suspend", this); return kIOReturnError; } value |= (kUHCI_PORTSC_SUSPEND | kUHCI_PORTSC_RD); } // Always enable the port also. value |= kUHCI_PORTSC_PED; USBLog(5, "AppleUSBUHCI[%p]: writing (%p) to port control", this, (void*)value); WritePortStatus(port, value); if (suspended) { /* Suspending. * Sleep for 3ms to ensure nothing goes out on the bus * until devices are suspended. */ IOSleep(3); } else { // Resuming USBLog(5,"AppleUSBUHCI[%p]::RHSuspendPort - resuming port %d, calling out to timer", this, (int)port+1); _rhPortBeingResumed[port] = true; thread_call_enter1(_rhResumePortTimerThread[port], (void*)(port+1)); } USBLog(5, "AppleUSBUHCI[%p]::RHSuspendPort %d (%s) calling UIMRootHubStatusChange", this, port+1, suspended ? "SUSPEND" : "RESUME"); UIMRootHubStatusChange(); USBLog(5, "AppleUSBUHCI[%p]::RHSuspendPort %d (%s) DONE", this, port+1, suspended ? "SUSPEND" : "RESUME"); return kIOReturnSuccess; }
IOReturn AppleUSBUHCI::GetRootHubPortStatus(IOUSBHubPortStatus *status, UInt16 port) { UInt16 p_status; UInt16 r_status, r_change; USBLog(7, "AppleUSBUHCI[%p]::GetRootHubPortStatus on port %d", this, port+1); RHDumpPortStatus(port); // no longer do this, as the root hub can be queried even when we are suspended //if (_myBusState == kUSBBusStateSuspended) //{ // return kIOReturnNotResponding; //} port--; // convert to 0-based if (port >= kUHCI_NUM_PORTS) { return kIOReturnBadArgument; } p_status = ReadPortStatus(port); // check to see if suspend is on and connect is off - if so, clear the suspend if ((p_status & kUHCI_PORTSC_SUSPEND) && !(p_status & kUHCI_PORTSC_CCS)) { USBLog(7, "AppleUSBUHCI[%p]::GetRootHubPortStatus - clearing suspend on disconnected port status[%p]", this, (void*)p_status); p_status &= kUHCI_PORTSC_MASK; // make sure not to clear the change bits p_status &= ~kUHCI_PORTSC_SUSPEND; // clear suspend WritePortStatus(port, p_status); // this does a sync and a delay p_status = ReadPortStatus(port); // reload USBLog(7, "AppleUSBUHCI[%p]::GetRootHubPortStatus - new port status[%p]", this, (void*)p_status); } /* Power is always turned on. */ r_status = kHubPortPower; if (p_status & kUHCI_PORTSC_SUSPEND) r_status |= kHubPortSuspend; if (p_status & kUHCI_PORTSC_RESET) r_status |= kHubPortBeingReset; if (p_status & kUHCI_PORTSC_LS) r_status |= kHubPortLowSpeed; if (p_status & kUHCI_PORTSC_PED) r_status |= kHubPortEnabled; if (p_status & kUHCI_PORTSC_CCS) r_status |= kHubPortConnection; status->statusFlags = HostToUSBWord(r_status); /* Synthesize the change bits that are not * in the hardware. */ r_change = r_status ^ _lastPortStatus[port]; if (p_status & kUHCI_PORTSC_PEDC) { r_change |= kHubPortEnabled; } else { r_change &= ~kHubPortEnabled; } if (p_status & kUHCI_PORTSC_CSC) { r_change |= kHubPortConnection; } else { r_change &= ~kHubPortConnection; } /* Suspend change is only when suspend changes * from true to false. It persists until * reset. */ if ((_lastPortStatus[port] & kHubPortSuspend) && !(r_status & kHubPortSuspend)) { USBLog(5, "AppleUSBUHCI[%p]::GetRootHubPortStatus - Turning on suspend change bit", this); _portSuspendChange[port] = true; } if (_portSuspendChange[port]) { r_change |= kHubPortSuspend; } else { r_change &= ~kHubPortSuspend; } /* Synthetic reset bit. */ if (_portWasReset[port]) { r_change |= kHubPortBeingReset; } status->changeFlags = HostToUSBWord(r_change); if (status->changeFlags) { USBLog(5, "AppleUSBUHCI[%p]::GetRootHubPortStatus for port(%d) returned status is (%x,%x)", this, (int)port+1, r_status, r_change); RHDumpHubPortStatus(status); } _lastPortStatus[port] = r_status; return kIOReturnSuccess; }