?? chw.hpp
字號:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Module Name:
// CHW.hpp
//
// Abstract: Provides interface to UHCI host controller
//
// Notes:
//
#ifndef __CHW_HPP__
#define __CHW_HPP__
#include <globals.hpp>
#include <hcd.hpp>
class CUhcd;
class CHW;
typedef const DWORD C_DWORD;
struct HcRegisters {
struct {
DWORD REV:8; // OHCI revision. Must be 0x10.
DWORD :24;
} const HcRevision;
struct HcControl { // All fields default to zero at reset.
DWORD CBSR:2; // Control/Bulk Service Ratio (CBSR+1):1
DWORD PLE:1; // Periodic List Enable
DWORD IE:1; // Isochronous Enable
DWORD CLE:1; // Control List Enable
DWORD BLE:1; // Bulk List Enable
DWORD HCFS:2; // Host Controller Functional State
enum { HCFS_RESET=0, HCFS_RESUME=1, HCFS_OPERATIONAL=2, HCFS_SUSPEND=3 };
DWORD IR:1; // Interrupt Routing (unused)
DWORD RWC:1; // Remote Wakeup Connected (unusable - see spec)
DWORD RWE:1; // Remote Wakeup Enable (unused)
DWORD :21;
} HcControl;
struct { // All fields default to zero at reset.
DWORD HCR:1; // Host Controller Reset (auto-clear)
DWORD CLF:1; // Control List Filled
DWORD BLF:1; // Bulk List Filled
DWORD OCR:1; // Ownership Change Request (unused)
DWORD :12;
DWORD SOC:2; // Scheduling Overrun Count
DWORD :14;
} HcCommandStatus;
union HcInterruptStatus {
struct { // Write 1 to clear each condition bit.
DWORD SO:1; // Scheduling Overrun
DWORD WDH:1; // Writeback DoneHead
DWORD SF:1; // Start of Frame
DWORD RD:1; // Resume Detected
DWORD UE:1; // Unrecoverable Error
DWORD FNO:1; // Frame Number Overflow
DWORD RHSC:1; // Root Hub Status Change
DWORD :23;
DWORD OC:1; // Ownership Change (unused)
DWORD :1;
};
DWORD reg; // the entire register at once
} HcInterruptStatus;
struct OHCI_Ints { // Write 1 to enable each interrupt.
DWORD SO:1; // Scheduling Overrun
DWORD WDH:1; // Writeback DoneHead
DWORD SF:1; // Start of Frame
DWORD RD:1; // Resume Detected
DWORD UE:1; // Unrecoverable Error
DWORD FNO:1; // Frame Number Overflow
DWORD RHSC:1; // Root Hub Status Change
DWORD :23;
DWORD OC:1; // Ownership Change (unused)
DWORD MIE:1; // Master Interrupt Enable
} HcInterruptEnable;
struct OHCI_Ints // Write 1 to diable each interrupt
HcInterruptDisable;
DWORD HcHCCA; // PAddr of the HCCA. Must be 256-byte aligned.
DWORD HcPeriodCurrentED; // PAddr of current Isoch or Intr ED. 16-byte aligned.
DWORD HcControlHeadED; // PAddr of first Control ED. 16-byte aligned.
DWORD HcControlCurrentED; // PAddr of current Control ED. 16-byte aligned.
DWORD HcBulkHeadED; // Like Control but for Bulk.
DWORD HcBulkCurrentED; // Like Control but for Bulk.
C_DWORD HcDoneHead; // PAddr of last completed TD.
struct HcFmInterval {
DWORD FI:14; // Frame Interval (nominally 11999 or 0x2EDF)
DWORD :2;
DWORD FSMPS:15; // FS Largest Data Packet (see OHCI section 5.4)
DWORD FIT:1; // Frame Interval Toggle
} HcFmInterval;
C_DWORD HcFmRemaining; // (unused)
struct {
C_DWORD FN:16; // Frame Number (LSW)
C_DWORD :16;
} HcFmNumber;
struct {
DWORD PS:14; // Periodic Start
DWORD :18;
} HcPeriodicStart;
struct {
C_DWORD LST:11; // Low Speed Threshold (nominally 0x628)
C_DWORD :21;
} HcLSThreshold;
struct {
DWORD NDP:8; // Number of Downstream Ports
DWORD PSM:1; // Power Switching Mode
DWORD NPS:1; // No Power Switching
DWORD DT:1; // Device Type (must be zero)
DWORD OCPM:1; // Over-Current Protection Mode
DWORD NOCP:1; // No Over-Current Protection
DWORD :11;
DWORD POTPGT:8; // Power-On to Power-Good Time (2ms units)
} HcRhDescriptorA;
struct {
DWORD DR:16; // Device Removable (bitmask, b0 reserved)
DWORD PPCM:16; // Port Power Control Mask (ditto)
} HcRhDescriptorB;
union HcRhStatus { // We can not use bit field structure it is write to set or clear
enum { LPS=0x1,OCI=0x2,DRWE=0x8000,LPSC=0x10000,OCIC=0x20000,CRWE=0x80000000};
DWORD reg;
} HcRhStatus;
union HcRhPortStatus {
// for writing, we generally set only one bit at a time.
enum { CPE=0x00000001, SPE=0x00000002, SPS=0x00000004, CPS=0x00000008,
SPR=0x00000010,
SPP=0x00000100, CPP=0x00000200,
CCSC=0x00010000, CPESC=0x00020000, CPSSC=0x00040000, COCIC=0x00080000,
CPRSC=0x00100000
};
struct {
DWORD CCS:1; // Current Connect Status / Clear Port Enable
DWORD PES:1; // Port Enable Status / Set Port Enable
DWORD PSS:1; // Port Suspend Status / Set Port Suspend
DWORD POCI:1; // Port Over-Current Indicator / Clear Port Suspend
DWORD PRS:1; // Port Reset Status / Set Port Reset
DWORD :3;
DWORD PPS:1; // Port Power Status / Set Port Power
DWORD LSDA:1; // Low Speed Device Attached / Clear Port Power
DWORD :6;
DWORD CSC:1; // Connect Status Change / clear CSC
DWORD PESC:1; // Port Enable Status Change / clear PESC
DWORD PSSC:1; // Port Suspend Status Change / clear PSSC
DWORD OCIC:1; // Over-Current Indicator Change / clear OCIC
DWORD PRSC:1; // Port Reset Status Change / clear PRSC
DWORD :11;
};
DWORD reg;
} HcRhPortStatus[15];
};
struct HCCA {
DWORD HccaInterruptTable[32];
WORD HccaFrameNumber;
WORD HccaPad1; // unused
DWORD HccaDoneHead; // PAddr of first TD in Done Queue. 16-byte aligned. LSb special.
// remainder is reserved so we can ignore it.
};
// this class is an encapsulation of UHCI hardware registers.
class CHW : public CHcd
{
public:
// ****************************************************
// public Functions
// ****************************************************
//
// Hardware Init/Deinit routines
//
CHW(IN const REGISTER portBase,
IN const DWORD dwSysIntr,
IN CPhysMem * const pCPhysMem,
IN LPVOID pvUhcdPddObject );
~CHW();
virtual BOOL Initialize(void);
virtual void DeInitialize( void );
virtual void SignalCheckForDoneTransfers ( DWORD ) { ASSERT(FALSE); };
void EnterOperationalState(void);
void StopHostController(void);
enum { LIST_CONTROL=1, LIST_BULK=2, LIST_INTERRUPT=4, LIST_ISOCH=8, LIST_ALL=15 };
void ListControl( IN const DWORD bfList,
IN const BOOL bEnable,
IN const BOOL bFill );
//
// Functions to Query frame values
//
BOOL GetFrameNumber( OUT LPDWORD lpdwFrameNumber );
BOOL GetFrameLength( OUT LPUSHORT lpuFrameLength );
BOOL SetFrameLength( IN HANDLE hEvent,
IN USHORT uFrameLength );
BOOL StopAdjustingFrame( void );
BOOL WaitOneFrame( void );
//
// Root Hub Queries
//
BOOL DidPortStatusChange( IN const UCHAR port );
BOOL GetPortStatus( IN const UCHAR port,
OUT USB_HUB_AND_PORT_STATUS& rStatus );
void GetRootHubDescriptor( OUT USB_HUB_DESCRIPTOR& descriptor );
BOOL RootHubFeature( IN const UCHAR port,
IN const UCHAR setOrClearFeature,
IN const USHORT feature );
BOOL ResetAndEnablePort( IN const UCHAR port );
void DisablePort( IN const UCHAR port );
// ****************************************************
// public Variables
// ****************************************************
PDWORD m_pControlHead;
PDWORD m_pBulkHead;
PDWORD m_pInterruptTable;
private:
// ****************************************************
// private Functions
// ****************************************************
static DWORD CALLBACK CeResumeThreadStub( IN PVOID context );
DWORD CeResumeThread( );
static DWORD CALLBACK UsbInterruptThreadStub( IN PVOID context );
DWORD UsbInterruptThread();
static DWORD CALLBACK UsbAdjustFrameLengthThreadStub( IN PVOID context );
DWORD CALLBACK UsbAdjustFrameLengthThread();
void UpdateFrameCounter( void );
VOID SuspendHostController();
VOID ResumeHostController();
#ifdef DEBUG
// Query Host Controller for registers, and prints contents
DWORD dwTickCountLastTime;
static void DumpAllRegisters(void);
#endif
WORD lastFn;
// ****************************************************
// Private Variables
// ****************************************************
volatile HcRegisters *m_portBase;
volatile HCCA *m_pHCCA;
// internal frame counter variables
CRITICAL_SECTION m_csFrameCounter;
WORD m_wFrameHigh;
// interrupt thread variables
DWORD m_dwSysIntr;
HANDLE m_hUsbInterruptEvent;
HANDLE m_hUsbInterruptThread;
BOOL m_fUsbInterruptThreadClosing;
// frame length adjustment variables
// note - use LONG because we need to use InterlockedTestExchange
LONG m_fFrameLengthIsBeingAdjusted;
LONG m_fStopAdjustingFrameLength;
HANDLE m_hAdjustDoneCallbackEvent;
USHORT m_uNewFrameLength;
// initialization parameters for the IST to support CE resume
// (resume from fully unpowered controller).
CPhysMem *m_pMem;
LPVOID m_pPddContext;
DWORD m_dwCapability;
BOOL m_bDoResume;
public:
DWORD SetCapability(DWORD dwCap);
DWORD GetCapability() { return m_dwCapability; };
private:
BOOL g_fPowerUpFlag;
BOOL g_fPowerResuming;
public:
VOID PowerMgmtCallback( IN BOOL fOff );
BOOL GetPowerUpFlag() { return g_fPowerUpFlag; };
BOOL SetPowerUpFlag(BOOL bFlag) { return (g_fPowerUpFlag=bFlag); };
BOOL GetPowerResumingFlag() { return g_fPowerResuming ; };
BOOL SetPowerResumingFlag(BOOL bFlag) { return (g_fPowerResuming=bFlag) ; };
};
#endif // __CHW_HPP__
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -