ohcd.c
资源名称:SMDK2440.rar [点击查看]
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:14k
源码类别:
Windows CE
开发平台:
Windows_Unix
- /*++
- 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.
- Copyright (c) 2001. Samsung Electronics, co. ltd All rights reserved.
- Module Name:
- ohcd.c
- Abstract:
- Platform dependant part of the USB Open Host Controller Driver (OHCD).
- rev:
- 2001.12.26 : OHC base pointer is changed(with VirtaulAlloc&VirtualCopy) (kwangyoon LEE, kwangyoon@samsung.com)
- Because Windows CE may not run in Full-Kernel thread mode (when ROMFLAGS bit 1 is cleared)
- CHECK IMGNOTALLKMODE environment variable!!!
- 2001.12.26 : code clean-up (kwangyoon LEE, kwangyoon@samsung.com)
- Notes:
- --*/
- #include <windows.h>
- #include <nkintr.h>
- #include <oalintr.h>
- #include <ceddk.h>
- #include <ohcdddsi.h>
- // Registry key and value names
- #define OHCI_DRIVER_KEY TEXT("Drivers\BuiltIn\OHCI")
- #define USE_EXISTING_VALUE_NAME TEXT("UseExistingSettings")
- #define IRQ_VALUE_NAME TEXT("Irq")
- #define IOBASE_VALUE_NAME TEXT("MemBase")
- // Amount of memory to use for HCD buffer
- static const DWORD gcTotalAvailablePhysicalMemory = 65536; // 64K
- static const DWORD gcHighPriorityPhysicalMemory = 0x4000; // 16K
- typedef struct _SOhcdPdd
- {
- LPVOID lpvMemoryObject;
- LPVOID lpvOhcdMddObject;
- } SOhcdPdd;
- #define UnusedParameter(x) x = x
- #define USB_INTR 11
- #define USB_BASE 0xB0900000
- #define USB_PHYSICAL_BASE 0x49000000
- #define USB_OPERATIONAL_REGISTER_SIZE 0x4096
- #define ZONE_ERROR 1
- volatile ULONG *v_USBreg;
- /* OhcdPdd_DllMain
- *
- * DLL Entry point.
- *
- * Return Value:
- */
- extern BOOL HcdPdd_DllMain(HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
- {
- UnusedParameter(hinstDLL);
- UnusedParameter(dwReason);
- UnusedParameter(lpvReserved);
- return TRUE;
- }
- /* GetRegistryConfig
- *
- * Function to get the IRQ and I/O port range from the registry.
- * Note: Will need to be changed to support multiple instances.
- *
- * Return Value:
- * TRUE for success, FALSE for error
- */
- static BOOL
- GetRegistryConfig( DWORD * lpdwUseExistingSettings, // OUT- Receives value that indicates whether to
- // just use the resources assigned by the BIOS.
- DWORD * lpdwIrq, // OUT- Receives IRQ value
- DWORD * lpdwIoBase ) // OUT- Receives I/O base
- {
- HKEY hKey;
- DWORD dwData;
- DWORD dwSize;
- DWORD dwType;
- BOOL fRet=FALSE;
- DWORD dwRet;
- dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,OHCI_DRIVER_KEY,0,0,&hKey);
- if (dwRet != ERROR_SUCCESS)
- {
- RETAILMSG(ZONE_ERROR,(TEXT("!OHCD:GetRegistryConfig RegOpenKeyEx(%s) failed %drn"),
- OHCI_DRIVER_KEY, dwRet));
- return FALSE;
- }
- dwSize = sizeof(dwData);
- dwRet = RegQueryValueEx(hKey,USE_EXISTING_VALUE_NAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
- if (dwRet != ERROR_SUCCESS)
- {
- RETAILMSG(ZONE_ERROR, (TEXT("!OHCD:GetRegistryConfig RegQueryValueEx(%s) failed %drn"),
- USE_EXISTING_VALUE_NAME, dwRet));
- goto GetRegistryConfig_exit;
- }
- *lpdwUseExistingSettings = dwData;
- dwSize = sizeof(dwData);
- dwRet = RegQueryValueEx(hKey,IRQ_VALUE_NAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
- if (dwRet != ERROR_SUCCESS)
- {
- RETAILMSG(ZONE_ERROR, (TEXT("!OHCD:GetRegistryConfig RegQueryValueEx(%s) failed %drn"),
- IRQ_VALUE_NAME, dwRet));
- goto GetRegistryConfig_exit;
- }
- *lpdwIrq = dwData;
- dwSize = sizeof(dwData);
- dwRet = RegQueryValueEx(hKey,IOBASE_VALUE_NAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
- if (dwRet != ERROR_SUCCESS)
- {
- RETAILMSG(ZONE_ERROR,(TEXT("!OHCD:GetRegistryConfig RegQueryValueEx(%s) failed %drn"),
- IOBASE_VALUE_NAME, dwRet));
- goto GetRegistryConfig_exit;
- }
- *lpdwIoBase = dwData;
- fRet = TRUE;
- GetRegistryConfig_exit:
- RegCloseKey(hKey);
- return fRet;
- } // GetRegistryConfig
- /* SetRegistryConfig
- *
- * Function to set the IRQ and I/O port range in the registry.
- * Note: Will need to be changed to support multiple instances.
- *
- * Return Value:
- * TRUE for success, FALSE for error
- */
- static BOOL
- SetRegistryConfig( DWORD dwIrq, // IN - IRQ value
- DWORD dwIoBase ) // IN - I/O base
- {
- HKEY hKey;
- BOOL fRet=FALSE;
- DWORD dwRet;
- dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,OHCI_DRIVER_KEY,0,0,&hKey);
- if (dwRet != ERROR_SUCCESS)
- {
- RETAILMSG(ZONE_ERROR,(TEXT("!OHCD:SetRegistryConfig RegOpenKeyEx(%s) failed %drn"),
- OHCI_DRIVER_KEY, dwRet));
- return FALSE;
- }
- dwRet = RegSetValueEx(hKey,IRQ_VALUE_NAME,0,REG_DWORD,(PUCHAR)&dwIrq,sizeof(DWORD));
- if (dwRet != ERROR_SUCCESS)
- {
- RETAILMSG(ZONE_ERROR, (TEXT("!OHCD:SetRegistryConfig RegQueryValueEx(%s) failed %drn"),
- IRQ_VALUE_NAME, dwRet));
- goto SetRegistryConfig_exit;
- }
- dwRet = RegSetValueEx(hKey,IOBASE_VALUE_NAME,0,REG_DWORD,(PUCHAR)&dwIoBase,sizeof(DWORD));
- if (dwRet != ERROR_SUCCESS)
- {
- RETAILMSG(ZONE_ERROR,(TEXT("!OHCD:SetRegistryConfig RegQueryValueEx(%s) failed %drn"),
- IOBASE_VALUE_NAME, dwRet));
- goto SetRegistryConfig_exit;
- }
- fRet = TRUE;
- SetRegistryConfig_exit:
- RegCloseKey(hKey);
- return fRet;
- } // SetRegistryConfig
- /* ConfigureOHCICard
- *
- * Configure OHCI controller I/O base and IRQ based on settings read from registry.
- * This should really call routines which access the IRQ routing and memory base through
- * the PCI BIOS and reconfigure the card. Since we currently don't have the routines
- * to do this, use the following algorithm:
- * -- If fUseExisting flag is set, read the values from the PCI config registers on the
- * card, and update pioPortBase and pIrq.
- * -- If fUseExisting is not set, verify that the passed in values of pioPortBase and
- * pIrq match, and return FALSE if they do not. (change - don't fail if mem base
- * doesn't match, since this is determined by the PCI config mechanism, it will not
- * conflict with other cards.)
- *
- * Return Value
- * Return TRUE if successful, FALSE if card could not be detected, or if configuration
- * does not match what was specified in the registry, and fUseExistingSettings is not set.
- */
- BOOL
- ConfigureOHCICard( BOOL fUseExistingSettings,
- PUCHAR *pioPortBase, // IN - contains physical address of register base
- // OUT- contains virtual address of register base
- ULONG *pIrq ) // IN - contains IRQ value
- // OUT- (if fUseExistingSettings) contains actual IRQ value
- {
- const USHORT cDefaultOhcdPortRange = 0x70;
- const ULONG cHTBAMemorySpace = 0;
- const ULONG cHTBAIOSpace = 1;
- ULONG portRange = cDefaultOhcdPortRange;
- ULONG inIoSpace = cHTBAMemorySpace;
- *pIrq = USB_INTR;
- (DWORD)*pioPortBase = USB_BASE; // This address must be changed to the virtual address.
- // In this time, I don't konw the virtual address map.
- // The physical IO address on the 2400 board.
- // This value must be defined in the config.bib.
- // by hjcho 04/16
- // Virtual address allocation.
- // In the MDD, the USB operational registers are accessed.
- v_USBreg = (ULONG*)VirtualAlloc(0, USB_OPERATIONAL_REGISTER_SIZE, MEM_RESERVE, PAGE_NOACCESS);
- if (v_USBreg == NULL)
- {
- ERRORMSG(1, (TEXT("USB Operational Register Addresses: VirtualAlloc failed!rn")));
- goto error_return;
- }
- if (!VirtualCopy((PVOID)v_USBreg,
- (PVOID)USB_BASE,
- USB_OPERATIONAL_REGISTER_SIZE,
- PAGE_READWRITE|PAGE_NOCACHE) )
- {
- ERRORMSG(1, (TEXT("USB Operational Register Addresses: VirtualCopy failed!rn")));
- goto error_return;
- }
- SetRegistryConfig(*pIrq, (DWORD)*pioPortBase);
- *pioPortBase = v_USBreg;
- RETAILMSG(1,(TEXT("USB:*pIrq=%d, *pioPortBase=0x%Xrn"),*pIrq, *pioPortBase));
- return TRUE;
- error_return:
- if (v_USBreg)
- VirtualFree((PVOID)v_USBreg, 0, MEM_RELEASE);
- v_USBreg = 0;
- return FALSE;
- }
- /* InitializeOHCI
- *
- * Configure and initialize OHCI card
- *
- * Return Value:
- * Return TRUE if card could be located and configured, otherwise FALSE
- */
- static BOOL
- InitializeOHCI( SOhcdPdd * pPddObject, // IN - Pointer to PDD structure
- LPCWSTR szDriverRegKey ) // IN - Pointer to active registry key string
- {
- DWORD dwUseExistingSettings;
- PUCHAR ioPortBase = NULL;
- DWORD dwSysIntr, dwIRQ;
- BOOL fResult = FALSE;
- LPVOID pobMem = NULL;
- LPVOID pobOhcd = NULL;
- RETAILMSG(1, (TEXT("++InitializeOHCIrn")));
- #if 0 // LKY 2001.12, currently We don't use registry!
- if (!GetRegistryConfig(&dwUseExistingSettings, &dwIRQ, (DWORD *)&ioPortBase))
- {
- RETAILMSG(1,(TEXT("!OHCD: Error reading registry settingsrn")));
- return FALSE;
- }
- RETAILMSG(1, (TEXT("OHCD: Read config from registry: Use existing: %u, IRQ: %u, I/O base: %Xrn"),
- dwUseExistingSettings,dwIRQ,ioPortBase));
- #endif
- fResult = ConfigureOHCICard(!!dwUseExistingSettings, &ioPortBase, &dwIRQ);
- if (fResult)
- {
- // The "MapIrq2SysIntr()" makes the system IRQ value be mapped to the physical interrupt.
- // This function is defined in the 'oalintr.h' in the directory 'INC'.
- // The dwIRQ may be used a higher value than 10. The value 0 to 10 is alreay used.
- // by hjcho. 04/16
- // dwSysIntr = SYSINTR_USB = SYSINTR_FIRMWARE + dwIRQ
- // dwIRQ = 11. I decided its value temporary.
- // by hjcho 04/17
- dwSysIntr = MapIrq2SysIntr(dwIRQ);
- RETAILMSG(1,(TEXT("OHCD: MapIrq2SysIntr(%u): %urn"),dwIRQ,dwSysIntr));
- // The PDD can supply a buffer of contiguous physical memory here, or can let the
- // MDD try to allocate the memory from system RAM. In our case, let the MDD do it.
- pobMem = HcdMdd_CreateMemoryObject(gcTotalAvailablePhysicalMemory, gcHighPriorityPhysicalMemory, NULL,NULL);
- if(pobMem)
- {
- RETAILMSG(1,(TEXT("OHCD: Memory Objectrn")));
- pobOhcd = HcdMdd_CreateHcdObject(pPddObject, pobMem, szDriverRegKey, ioPortBase, dwSysIntr);
- fResult = pobOhcd ? TRUE : FALSE;
- }
- else
- fResult = FALSE;
- if (!fResult)
- {
- if (pobOhcd)
- HcdMdd_DestroyHcdObject(pobOhcd);
- if (pobMem)
- HcdMdd_DestroyMemoryObject(pobMem);
- pobOhcd = NULL;
- pobMem = NULL;
- RETAILMSG(1, (TEXT("--InitializeOHCI FAILED!!!rn")));
- return fResult;
- }
- }
- else
- {
- RETAILMSG(1, (TEXT("ConfigureOHCICard() FAILED!!!rn")));
- return fResult;
- }
- pPddObject->lpvMemoryObject = pobMem;
- pPddObject->lpvOhcdMddObject = pobOhcd;
- RETAILMSG(1, (TEXT("--InitializeOHCIrn")));
- return fResult;
- }
- /* OhcdPdd_Init
- *
- * PDD Entry point - called at system init to detect and configure OHCI card.
- *
- * Return Value:
- * Return pointer to PDD specific data structure, or NULL if error.
- */
- extern DWORD
- HcdPdd_Init(DWORD dwContext) // IN - Pointer to context value. For device.exe, this is a string
- // indicating our active registry key.
- {
- SOhcdPdd * pPddObject = malloc(sizeof(SOhcdPdd));
- BOOL fRet = FALSE;
- RETAILMSG(1, (TEXT("USB:OhcdPdd_Initrn")));
- fRet = InitializeOHCI(pPddObject, (LPCWSTR)dwContext);
- if(!fRet)
- {
- free(pPddObject);
- pPddObject = NULL;
- }
- return (DWORD)pPddObject;
- }
- /* OhcdPdd_CheckConfigPower
- *
- * Check power required by specific device configuration and return whether it
- * can be supported on this platform. For CEPC, this is trivial, just limit to
- * the 500mA requirement of USB. For battery powered devices, this could be
- * more sophisticated, taking into account current battery status or other info.
- *
- * Return Value:
- * Return TRUE if configuration can be supported, FALSE if not.
- */
- extern BOOL HcdPdd_CheckConfigPower(UCHAR bPort, // IN - Port number
- DWORD dwCfgPower, // IN - Power required by configuration
- DWORD dwTotalPower) // IN - Total power currently in use on port
- {
- return ((dwCfgPower + dwTotalPower) > 500) ? FALSE : TRUE;
- }
- extern void HcdPdd_PowerUp(DWORD hDeviceContext)
- {
- SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
- HcdMdd_PowerUp(pPddObject->lpvOhcdMddObject);
- return;
- }
- extern void HcdPdd_PowerDown(DWORD hDeviceContext)
- {
- SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
- HcdMdd_PowerDown(pPddObject->lpvOhcdMddObject);
- return;
- }
- extern BOOL HcdPdd_Deinit(DWORD hDeviceContext)
- {
- SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
- if(pPddObject->lpvOhcdMddObject)
- HcdMdd_DestroyHcdObject(pPddObject->lpvOhcdMddObject);
- if(pPddObject->lpvMemoryObject)
- HcdMdd_DestroyMemoryObject(pPddObject->lpvMemoryObject);
- return TRUE;
- }
- extern DWORD HcdPdd_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)
- {
- UnusedParameter(hDeviceContext);
- UnusedParameter(AccessCode);
- UnusedParameter(ShareMode);
- return 1; // we can be opened, but only once!
- }
- extern BOOL HcdPdd_Close(DWORD hOpenContext)
- {
- UnusedParameter(hOpenContext);
- return TRUE;
- }
- extern DWORD HcdPdd_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
- {
- UnusedParameter(hOpenContext);
- UnusedParameter(pBuffer);
- UnusedParameter(Count);
- return (DWORD)-1; // an error occured
- }
- extern DWORD HcdPdd_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes)
- {
- UnusedParameter(hOpenContext);
- UnusedParameter(pSourceBytes);
- UnusedParameter(NumberOfBytes);
- return (DWORD)-1;
- }
- extern DWORD HcdPdd_Seek(DWORD hOpenContext, LONG Amount, DWORD Type)
- {
- UnusedParameter(hOpenContext);
- UnusedParameter(Amount);
- UnusedParameter(Type);
- return (DWORD)-1;
- }
- extern BOOL HcdPdd_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn,
- DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)
- {
- UnusedParameter(hOpenContext);
- UnusedParameter(dwCode);
- UnusedParameter(pBufIn);
- UnusedParameter(dwLenIn);
- UnusedParameter(pBufOut);
- UnusedParameter(dwLenOut);
- UnusedParameter(pdwActualOut);
- return FALSE;
- }
- extern void HcdPdd_InitiatePowerUp(void)
- {
- return;
- }