⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ohcdpdd.c

📁 Intel PXA270 Wince5.0 BSP
💻 C
📖 第 1 页 / 共 4 页
字号:
   WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,pwrCtrlPolLow,1);  // Need to invert the signal from the SA-1111 for the USB power controller
   WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,pwrSensePolLow,1);  

   WRITE_BITFIELD(struct  skpcrBITS,&v_pDCPLLReg->skpcr,DCLKEn,1);  //Enable DMA Clocks 
#endif

#ifndef PLAT_LUBBOCK
   RETAILMSG(1,(TEXT("OHCI_Reset: Resetting Bulverde OHCI.\r\n")));

   // Do the reset for the Bulverde part.
   // Two levels of reset need to be initiated:
   //	The OHCI core needs to be reset via the FHR bit,
   //	then the OHCI system bus interface needs to be reset via the FSBIR bit.

	// reset the OHC core and all OHC blocks driven by the 12 MHz clock, eg. write fifo, etc.
	v_pDCUSBOHCIReg->uhchr |=  XLLP_USBOHCI_UHCHR_FHR;
	usWait( 10 );		// ten micro second wait called for by spec.
	v_pDCUSBOHCIReg->uhchr &= ~XLLP_USBOHCI_UHCHR_FHR;

	// reset the OHC system bus interface, eg. SBI, DMA blocks, fifos, etc.
	v_pDCUSBOHCIReg->uhchr |=  XLLP_USBOHCI_UHCHR_FSBIR;
	while( v_pDCUSBOHCIReg->uhchr & XLLP_USBOHCI_UHCHR_FSBIR );	// auto clears in 3 system bus clocks

	// now set the polarity fields so the OHCI knows to:
	//		assert or deassert the power control signals to power or shutdown a port, and
	//		detect overcurrent indication from assertion or de-assertion of the power sense signals.

	// note: the correcting settings for these values are determined by the board layout and the
	// external voltage regulators in use. In the case of the Mainstone, the external voltage
	// regulator is a MAX1693EUB USB Power Switch, which uses negative polarity for power enable
	// and for fault notification.
	v_pDCUSBOHCIReg->uhchr |=  XLLP_USBOHCI_UHCHR_PCPL;			// bit = 1 means power control polarity is active low
	v_pDCUSBOHCIReg->uhchr |=  XLLP_USBOHCI_UHCHR_PSPL;			// bit = 1 means power (ie. over-current) sense polarity is active low

//	v_pDCUSBOHCIReg->uhchr |=  XLLP_USBOHCI_UHCHR_SSEP1;		// keep port 1 in sleep/standby (eg. disable port 1)
	v_pDCUSBOHCIReg->uhchr &= ~XLLP_USBOHCI_UHCHR_SSEP1;		// for port 1, enable power to the single ended receivers and the port (DevMan says to do this)
	v_pDCUSBOHCIReg->uhchr &= ~XLLP_USBOHCI_UHCHR_SSEP0;		// for port 0, enable power to the single ended receivers and the port
	v_pDCUSBOHCIReg->uhchr &= ~XLLP_USBOHCI_UHCHR_SSE;			// allow the values of SSEP1 and SSPE0 to control the power.

#endif

   RETAILMSG(1,(TEXT("OHCI_Reset: done.\r\n")));
}

// a thread for debugging....
INT WINAPI OHCIPDDDebugThread(LPVOID lpvParam)
{
	// this thread will enable and disable the 
	// usb ohci port every fifteen seconds to
	// do an automated plug / unplug stress test.
	while(1)
	{
		// disable the usb ohci port
		RETAILMSG(1,(TEXT("OHCIPDDDebugThread: disabling USB OHCI port 0.\r\n")));
		v_pDCUSBOHCIReg->uhchr |= XLLP_USBOHCI_UHCHR_SSEP0;		// port 0 standby: enabled
		Sleep( 15 * 1000 );										// fifteen second delay
		
		// enable the usb ohci port
		RETAILMSG(1,(TEXT("OHCIPDDDebugThread: enabling USB OHCI port 0.\r\n")));
		v_pDCUSBOHCIReg->uhchr &= ~XLLP_USBOHCI_UHCHR_SSEP0;	// port 0 standby: disabled.
		Sleep( 15 * 1000 );
	}
}

// handle PDD interrupts
INT WINAPI OHCIPDDIntrThread(LPVOID lpvParam)
{
    BOOL fKnownInterrupt;
    UnusedParameter(lpvParam);

	RETAILMSG(1,(TEXT("OHCIPDD INTR Thread: Started.\r\n")));

    while (1) {
        WaitForSingleObject(gOHCIPDDIntrEvent, INFINITE);

#ifdef PLAT_LUBBOCK        
        //See which SA-1111 non-OHCI Controller interrupt we got
        RETAILMSG(1, (TEXT("OHCIPDD INTR Thread Interrupt Event\r\n")));
        fKnownInterrupt = FALSE;
        if (v_pDCUSBReg->ussr[0].irqHciRmtWkp)  {
            RETAILMSG(1, (TEXT("OHCIPdd Int Thread Remote Wakeup Event\r\n")));
            fKnownInterrupt = TRUE;
        }	
        if (v_pDCUSBReg->ussr[0].irqHciBuffAcc)  {
            RETAILMSG(1, (TEXT("OHCIPdd Int Thread Buffer Active Event\r\n")));
            fKnownInterrupt = TRUE;
        }	
        if (v_pDCUSBReg->ussr[0].nIrqHciM)  {
            RETAILMSG(1, (TEXT("OHCIPdd Int Thread Normal HC Interrupt Event\r\n")));
            fKnownInterrupt = TRUE;
        }	
        if (v_pDCUSBReg->ussr[0].nHciMFCir)  {
            RETAILMSG(1, (TEXT("OHCIPdd Int Thread Clear Signals Event\r\n")));
            fKnownInterrupt = TRUE;
        }
        if (v_pDCUSBReg->ussr[0].usbPwrSense)  {
            RETAILMSG(1, (TEXT("OHCIPdd Int Thread Power Sense Event\r\n")));
            fKnownInterrupt = TRUE;
        }
#endif

#ifndef PLAT_LUBBOCK
		if( v_pDCUSBOHCIReg->uhcstat )
		{
			RETAILMSG(1,(TEXT("OHCIPdd Int Thread uhcstat: %08x.\r\n"), v_pDCUSBOHCIReg->uhcstat ));

			// clear the interrupt:
			v_pDCUSBOHCIReg->uhcstat = v_pDCUSBOHCIReg->uhcstat;

			RETAILMSG(1,(TEXT("OHCIPdd Int Thread new uhcstat: %08x.\r\n"), v_pDCUSBOHCIReg->uhcstat ));

			fKnownInterrupt = TRUE;
		}

#endif

        if(!fKnownInterrupt) {
            RETAILMSG(1, (TEXT("OHCIPdd Int Thread No known Event\r\n")));
        }

#if 0   // allow HcdPdd_ResumeThread() to handle resume notifications 
        //if the USB clock is on go through reset sequence to start up the USB
        // otherwise let normal HC int process
        //Right now only Port Resume interrupts are enabled
        if (!v_pDCPLLReg->skpcrBits[0].UCLKEn)	{ 
            RETAILMSG(1, (TEXT("OHCIPdd Int Port Resume, reseting Sense Event\r\n")));
            OHCI_Reset();
        }
#endif  // boolean

        //DEBUGMSG(ZONE_INIT, (TEXT("OHCI PDD INTR Thread called P\r\n")));
        InterruptDone(dwSysIntrOhciPdd/*SYSINTR_OHCI_PDD*/);
    }

	RETAILMSG(1,(TEXT("OHCIPDD INTR Thread: Ended.\r\n")));
}


// This PDD will set up two interrupt service threads, 
// first we create a thread to service the SA-1111 non-OHCI host controller interrupts
// Then in InitializeOHCI we hook the SA-1111 OHCI host controller interrupt in to the MDD
BOOL InitPddInterrupts(void)
{
    

    gOHCIPDDIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    
    if (!(InterruptInitialize(dwSysIntrOhciPdd/*SYSINTR_OHCI_PDD*/, gOHCIPDDIntrEvent, NULL, 0))) {
        DEBUGMSG(ZONE_INIT, (TEXT("OHCI PDD INTR INIT Failed\r\n")));
        DEBUGMSG(ZONE_INIT, (TEXT("OHCI PDD INTR INIT ERR: 0x%x\r\r"), GetLastError()));
        //return NULL;		
        return FALSE;		
    }
    
 //   gOHCIPDDIntrThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) OHCIPDDIntrThread, NULL, 0, NULL);
 //   if ( gOHCIPDDIntrThread == NULL ) {
 //       ERRORMSG(1, (TEXT("Fatal Error!  Failed to create OHCIPDD interrupt thread.\r\n")));
 //       //return (NULL);
 //       return (FALSE);
 //   } else {
 //       DEBUGMSG(ZONE_INIT, (TEXT("-OHCIPDD  Init\r\n")));
 //       //return TRUE;
 //   }
    
    RETAILMSG(1, (TEXT("InitPddInterrupts RhPortStatus: 0x%x.\r\n"), v_pDCUSBReg->RhPortStatus[0]));
    return TRUE;
}


/* HcdPdd_DllMain
 * 
 *  DLL Entry point.
 *
 * Return Value:
 */
extern BOOL HcdPdd_DllMain(HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
    UnusedParameter(hinstDLL);
    UnusedParameter(dwReason);
    UnusedParameter(lpvReserved);
    RETAILMSG(1, (TEXT("Modified File: ohcd.c.\r\n")));

    return TRUE;
}


/* GetRegistryConfig
 *  
 *   Note: Will need to be changed to support multiple instances.
 *
 * Return Value:
 *   TRUE for success, FALSE for error
 */
static BOOL
GetRegistryConfig(
    LPCWSTR RegKeyPath,         // IN - driver registry key path
    DWORD * lpdwBaseAddr,       // OUT - base address
    DWORD * lpdwAddrLen,        // OUT - address range
    DWORD * lpdwIOSpace,        // OUT - 1 if base address describes I/O port, 0 otherwise
    DWORD * lpdwSysIntr,        // OUT - system interrupt number
    PINTERFACE_TYPE lpIfcType,  // OUT - interface type (PCIbus, ISAbus, etc)
    DWORD * lpdwBusNumber,      // OUT - bus number, depends on interface type
    BOOL * bInstallIsr,         // OUT - TRUE if ISR Handler found in registry
    LPWSTR IsrDll,              // OUT - Name of ISR Handler dll
    LPWSTR IsrHandler,          // OUT - Name of ISR Handler routine
    DWORD * Irq                 // OUT - IRQ number, used to hook ISR handler
    )
{
    HKEY hKey = NULL;
    BOOL  fRet=FALSE;
    DWORD dwRet;

    // initialize with default values
    *lpdwBaseAddr = (DWORD) v_pDCUSBReg->Revision;
    *lpdwAddrLen = SK_USB_HCI_SPACE;
    *lpdwIOSpace = 0;
    *lpdwSysIntr = dwSysIntrOhciMdd;
    *lpIfcType = Isa;
    *bInstallIsr = FALSE;
    *lpdwBusNumber = 0;
    IsrDll[0] = 0;
    IsrHandler[0] = 0;
    *Irq = 0;

    // Open key
    dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,RegKeyPath,0,0,&hKey);
    if (dwRet != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ERROR,(TEXT("!UHCD:GetRegistryConfig RegOpenKeyEx(%s) failed %d\r\n"),
                             RegKeyPath, dwRet));
    } else {
        DWORD dwData;
        DWORD dwSize;
        DWORD dwType;
        
        // read registry data
        dwSize = sizeof(dwData);
        dwRet = RegQueryValueEx(hKey,IRQ_VALUE_NAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
        if (dwRet == ERROR_SUCCESS) {
            *lpdwSysIntr = dwData;
        }

        dwSize = sizeof(dwData);
        dwRet = RegQueryValueEx(hKey,IOBASE_VALUE_NAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
        if (dwRet == ERROR_SUCCESS) {
            *lpdwBaseAddr = dwData;
        }
    }
        
    fRet = TRUE;

    if(hKey != NULL) RegCloseKey(hKey);

    return fRet;
}   // GetRegistryConfig


/* ConfigureUHCICard
 * 
 */
BOOL
ConfigureUHCICard(
    PUCHAR *pioPortBase,   // IN - contains physical address of register base
                           // OUT- contains virtual address of register base
    DWORD dwAddrLen,
    DWORD dwIOSpace,
    INTERFACE_TYPE IfcType,
    DWORD dwBusNumber
    )
{
#ifdef TRANSLATE_ADDRESSES
    ULONG               inIoSpace = dwIOSpace;
    ULONG               portBase;
    PHYSICAL_ADDRESS    ioPhysicalBase = {0, 0};
    
    portBase = (ULONG)*pioPortBase;
    ioPhysicalBase.LowPart = portBase;

    if (!TransBusAddrToVirtual(IfcType, dwBusNumber, ioPhysicalBase, dwAddrLen, &inIoSpace, (PPVOID)pioPortBase)) {
        DEBUGMSG(ZONE_ERROR, (L"UHCD: Failed TransBusAddrToVirtual\r\n"));
        return FALSE;
    }

    DEBUGMSG(ZONE_INIT, 
             (TEXT("UHCD: ioPhysicalBase 0x%X, IoSpace 0x%X\r\n"),
              ioPhysicalBase.LowPart, inIoSpace));
    DEBUGMSG(ZONE_INIT, 
             (TEXT("UHCD: ioPortBase 0x%X, portBase 0x%X\r\n"),
              *pioPortBase, portBase));
#else
    UnusedParameter(pioPortBase);
    UnusedParameter(dwAddrLen);
    UnusedParameter(dwIOSpace);
    UnusedParameter(IfcType);
    UnusedParameter(dwBusNumber);
#endif

    return TRUE;
}


/* InitializeUHCI
 *
 *  Configure and initialize UHCI card
 *
 * Return Value:
 *  Return TRUE if card could be located and configured, otherwise FALSE
 */
static BOOL 
InitializeUHCI(
    SUhcdPdd * pPddObject,    // IN - Pointer to PDD structure
    LPCWSTR szDriverRegKey)   // IN - Pointer to active registry key string
{
    PUCHAR ioPortBase = NULL;
    DWORD dwAddrLen;
    DWORD dwIOSpace;
    DWORD dwSysIntr;
    INTERFACE_TYPE IfcType;
    DWORD dwBusNumber;
    BOOL InstallIsr = FALSE;
    WCHAR IsrDll[DEVDLL_LEN];
    WCHAR IsrHandler[DEVENTRY_LEN];
    DWORD Irq = -1;
    BOOL fResult = FALSE;
    LPVOID pobMem = NULL;
    LPVOID pobUhcd = NULL;
    DWORD PhysAddr;

    // reset the host controller and enable its clocks

    OHCI_Reset();
    
    if (!GetRegistryConfig(szDriverRegKey, &PhysAddr, &dwAddrLen, &dwIOSpace, &dwSysIntr, &IfcType, &dwBusNumber, &InstallIsr, IsrDll, IsrHandler, &Irq)) {
        RETAILMSG(1,(TEXT("!UHCD: Error reading registry settings\r\n")));
        return FALSE;
    }
    
    DEBUGMSG(ZONE_INIT,(TEXT("InitializeUHCI: Read config from registry: Base Address: 0x%X, Length: 0x%X, I/O Port: %s, SysIntr: 0x%X, Interface Type: %u, Bus Number: %u\r\n"),
                        PhysAddr, dwAddrLen, dwIOSpace ? L"YES" : L"NO", dwSysIntr, IfcType, dwBusNumber));

    ioPortBase = (PUCHAR)PhysAddr;
                        
    if (!(fResult = ConfigureUHCICard(&ioPortBase, dwAddrLen, dwIOSpace, IfcType, dwBusNumber))) {
        goto InitializeUHCI_Error;
    }
    
#ifndef OSV_LOCAL_MERLIN
	// The following is only supported in Jameson, but this
	// code is for a Merlin build
    if (InstallIsr) {
        // Install ISR handler
        g_IsrHandle = LoadIntChainHandler(IsrDll, IsrHandler, (BYTE)Irq);

        if (!g_IsrHandle) {
            DEBUGMSG(ZONE_ERROR, (L"UHCD: Couldn't install ISR handler\r\n"));
        } else {
            GIISR_INFO Info;
            PHYSICAL_ADDRESS PortAddress = {PhysAddr, 0};
            
            DEBUGMSG(ZONE_INIT, (L"UHCD: Installed ISR handler, Dll = '%s', Handler = '%s', Irq = %d\r\n",
                IsrDll, IsrHandler, Irq));
            
            if (!TransBusAddrToStatic(IfcType, dwBusNumber, PortAddress, dwAddrLen, &dwIOSpace, &(PVOID)PhysAddr)) {
                DEBUGMSG(ZONE_ERROR, (L"UHCD: Failed TransBusAddrToStatic\r\n"));
                return FALSE;
            }
        
            // Set up ISR handler
            Info.SysIntr = dwSysIntr;
            Info.CheckPort = TRUE;
            Info.PortIsIO = (dwIOSpace) ? TRUE : FALSE;
            Info.UseMaskReg = TRUE;
            Info.PortAddr = PhysAddr + 0x0C;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -