dStatus q117AllocateBuffers ( PQ117_CONTEXT Context ) { ULONG i; ULONG totalBuffs; // // Allocate DMA buffers in physically contiguous memory. // NOTE: HalAllocateCommonBuffer is really for BUS MASTERS ONLY // but this is the only way we can guarantee that IoMapTransfer // doesn't copy our buffer somewhere else. This would stop the // tape from streaming. // totalBuffs = 0; for (i = 0; i < UNIX_MAXBFS; i++) { if ((Context->SegmentBuffer[i].logical = HalAllocateCommonBuffer(Context->AdapterInfo->AdapterObject, BLOCKS_PER_SEGMENT * BYTES_PER_SECTOR, &Context->SegmentBuffer[i].physical, FALSE)) == NULL) { break; } ++totalBuffs; CheckedDump(QIC117INFO,("q117: buffer %x ",i,Context->SegmentBuffer[i].logical)); CheckedDump(QIC117INFO,("Logical: %x%08x Virtual: %x\n", Context->SegmentBuffer[i].physical, Context->SegmentBuffer[i].logical)); } Context->SegmentBuffersAvailable = totalBuffs; // // We need at least two buffers to stream // if (totalBuffs < 2) { CheckedDump(QIC117DBGP,("Fatal error - Insufficient buffers available from HalAllocateCommonBuffer()\n")); q117FreeTemporaryMemory(Context); return ERROR_ENCODE(ERR_NO_MEMORY, FCT_ID, 2); } return ERR_NO_ERR; }
SHAREMEM *AllocateShareMem(DWORD dwSize,DWORD *pdwPhyAddr) { DMA_ADAPTER_OBJECT dmaobj; PVOID pMemAddr; // Virtual address of transfer buffer PHYSICAL_ADDRESS PhyAddr; dmaobj.ObjectSize = sizeof(DMA_ADAPTER_OBJECT); dmaobj.InterfaceType = Internal; dmaobj.BusNumber = 1; pMemAddr = HalAllocateCommonBuffer(&dmaobj, dwSize, &PhyAddr , FALSE); *pdwPhyAddr = PhyAddr.LowPart; return (SHAREMEM *)pMemAddr; }
PVOID VideoPortGetCommonBuffer( IN PVOID HwDeviceExtension, IN PVIDEO_REQUEST_PACKET pVrp, IN ULONG Length, OUT PPHYSICAL_ADDRESS pLogicalAddress, IN BOOLEAN CacheEnabled ) /*++ Routine Description: Provides physical address visible to both device and system. Memory seen as coniguous by device. Arguments: HwDeviceExtension - device extension available to miniport. pVrp - PVIDEO_REQUEST_PACKET available to miniport. Length - size of desired memory (should be minimal). pLogicalAddress - [out] parameter which will hold PHYSICAL_ADDRESS upon function return. CacheEnabled - Specifies whether the allocated memory can be cached. Return Value: --*/ { PDEVICE_EXTENSION deviceExtension = ((PDEVICE_EXTENSION) HwDeviceExtension) - 1; PPUBLIC_VIDEO_REQUEST_BLOCK pPVRB; GET_PVRB_FROM_PVRP(pPVRB, pVrp); return (HalAllocateCommonBuffer(deviceExtension->DmaAdapterObject, Length, pLogicalAddress, CacheEnabled )); }
BOOL CST202T_SATA::ConfigPort( ) { BOOL bRet = FALSE; DMA_ADAPTER_OBJECT Adapter; Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT); Adapter.InterfaceType = (INTERFACE_TYPE)m_pPort->m_pController->m_dwi.dwInterfaceType; Adapter.BusNumber = m_pPort->m_pController->m_dwi.dwBusNumber; if (!m_LLITable) { m_LLITable = (pSATA_DMA_LLI)HalAllocateCommonBuffer(&Adapter, UserKInfo[KINX_PAGESIZE], &m_LLITablePhys, FALSE); } // Setup the interrupt here and create the controller's IST. if (m_LLITable && CPCIDisk::ConfigPort()) { HANDLE hThread; // Create IST hThread = ::CreateThread(NULL, 0, InterruptThreadStub, this, 0, NULL); // Set IST thread priority if it is specified in registry DWORD dwThreadPri; if (AtaGetRegistryValue (m_hDevKey, L"IstPriority256", &dwThreadPri)) { ::CeSetThreadPriority (hThread, dwThreadPri); } CloseHandle(hThread); bRet = TRUE; } return bRet; }
BOOL OMAP2420DMAContext::HWMapDMAMemory(DWORD dwSize) { PBYTE pbDMATemp; PHYSICAL_ADDRESS pa; /* find the system dma controller */ uint bytesToAlloc = 0; uint err = DMA_ControllerEnum(NULL,&bytesToAlloc); if (err!=DMAERR_NOTENOUGHSPACE) { DEBUGMSG(ZONE_ERROR, (L"OMAP2420DMAContext::HWMapDMAMemory: " L"Could not get size of enumeration of platform dma controllers.\r\n" )); return FALSE; } DMACONTROLLER *pContList = (DMACONTROLLER *)malloc(bytesToAlloc); if (pContList == NULL) { DEBUGMSG(ZONE_ERROR, (L"OMAP2420DMAContext::HWMapDMAMemory: " L"Could not malloc dma controllers.\r\n" )); return FALSE; } err = DMA_ControllerEnum(pContList,&bytesToAlloc); if (err) { DEBUGMSG(ZONE_ERROR, (L"OMAP2420DMAContext::HWMapDMAMemory: " L"Could not enumerate platform dma controllers.\r\n" )); free(pContList); return FALSE; } /* find the system dma controller */ uint numEntries = bytesToAlloc/sizeof(DMACONTROLLER); uint i; for(i=0;i<numEntries;i++) { if (!_stricmp(pContList[i].mName,"System")) break; } if (i==numEntries) { DEBUGMSG(ZONE_ERROR, (L"OMAP2420DMAContext::HWMapDMAMemory: " L"Could not find \"System\" dma controller.\r\n" )); free(pContList); return FALSE; } uint controllerId = pContList[i].mSysId; free(pContList); /* open the controller now */ err = DMA_ControllerOpen(controllerId, &m_hCont); if (err) { DEBUGMSG(ZONE_ERROR, (L"OMAP2420DMAContext::HWMapDMAMemory: " L"Could not open \"System\" dma controller.\r\n" )); return FALSE; } /* we need to allocate our input and output channels */ uint chanIO = (1<<AUDIO_INPUT_DMA_CHANNEL) | (1<<AUDIO_OUTPUT_DMA_CHANNEL); err = DMA_ControllerAcquireChannels(m_hCont, 2, &chanIO); if (err) { DEBUGMSG(ZONE_ERROR, (L"OMAP2420DMAContext::HWMapDMAMemory: " L"Could not acquire audio i/o channels\r\n" )); DMA_ControllerClose(m_hCont); m_hCont = NULL; return FALSE; } /* if we get here, then we have ownership of the two dma channels we need */ // map DMA registers into driver address space pa.HighPart= 0; pa.LowPart = OMAP2420_SDMA_REGS_PA; volatile OMAP2420_SDMA_REGS *pDMA_Regs = (OMAP2420_SDMA_REGS *)MmMapIoSpace(pa, sizeof(OMAP2420_SDMA_REGS), FALSE); if (!pDMA_Regs) { DEBUGMSG(ZONE_ERROR, (L"OMAP2420DMAContext::HWMapDMAMemory: " L"ERROR mapping DMA registers.\n" )); goto ErrExit; } // enable input DMA IRQ err = DMA_ControllerSet(m_hCont, DMACP_L3IntEnb, 1<< AUDIO_INPUT_DMA_CHANNEL); if (err) { DEBUGMSG(ZONE_ERROR, (L"OMAP2420DMAContext::HWMapDMAMemory: " L"ERROR setting IRQ for L3 input dma channel.\r\n" )); goto ErrExit; } // enable output DMA IRQ err = DMA_ControllerSet(m_hCont, DMACP_L2IntEnb, 1<< AUDIO_OUTPUT_DMA_CHANNEL); if (err) { DEBUGMSG(ZONE_ERROR, (L"OMAP2420DMAContext::HWMapDMAMemory: " L"ERROR setting IRQ for L2 output dma channel.\r\n" )); goto ErrExit; } // get the channel register pointers m_pInDMAReg = &pDMA_Regs->CHNL_CTRL[AUDIO_INPUT_DMA_CHANNEL]; m_pOutDMAReg = &pDMA_Regs->CHNL_CTRL[AUDIO_OUTPUT_DMA_CHANNEL]; // allocate the DMA pages DMA_ADAPTER_OBJECT AdapterObject; AdapterObject.ObjectSize = sizeof(AdapterObject); AdapterObject.InterfaceType = Internal; AdapterObject.BusNumber = 0; m_pbDMABufOut = NULL; pbDMATemp = (PBYTE)HalAllocateCommonBuffer(&AdapterObject, dwSize, &m_paAudioDMA, FALSE); if (!pbDMATemp) { DEBUGMSG(ZONE_ERROR, (L"OMAP2420DMAContext::HWMapDMAMemory: " L"ERROR mapping DMA memory.\n" )); goto ErrExit; } m_pbDMABufOut = m_pbDMABufIn = pbDMATemp; #ifdef MIXER_CACHEDMEM // Map DMA buffer also to cached memory for DMA out // Mixer will call cache flush after block is completed m_pbDMABufOut = (PBYTE)MmMapIoSpace(m_paAudioDMA, dwSize, TRUE); if (!m_pbDMABufOut) { DEBUGMSG(ZONE_ERROR, (L"OMAP2420DMAContext::HWMapDMAMemory: " L"ERROR mapping DMA buffer to cached memory, using uncached.\n" )); m_pbDMABufOut = pbDMATemp; } #endif return TRUE; ErrExit: m_pInDMAReg =NULL; m_pOutDMAReg =NULL; m_pbDMABufOut=NULL; m_pbDMABufIn =NULL; if (m_hCont) { DMA_ControllerClose(m_hCont); m_hCont = NULL; } return FALSE; }
BOOL CPCIDisk::SetupDMA( PSG_BUF pSgBuf, DWORD dwSgCount, BOOL fRead ) { DWORD dwAlignMask = m_dwDMAAlign - 1; DWORD dwPageMask = UserKInfo[KINX_PAGESIZE] - 1; DWORD iPage = 0, iPFN, iBuffer; BOOL fUnalign = FALSE; DMA_ADAPTER_OBJECT Adapter; Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT); Adapter.InterfaceType = (INTERFACE_TYPE)m_pPort->m_pController->m_dwi.dwInterfaceType; Adapter.BusNumber = m_pPort->m_pController->m_dwi.dwBusNumber; DEBUGMSG(ZONE_DMA, (_T( "Atapi!CPCIDisk::SetupDMA> Request(%s), SgCount(%d)\r\n" ), fRead ? (_T("Read")) : (_T("Write")), dwSgCount)); #ifndef ST202T_SATA // disable bus master WriteBMCommand(0); #endif if (!m_pPRD) { m_pPRD = (PDMATable)HalAllocateCommonBuffer(&Adapter, UserKInfo[KINX_PAGESIZE], &m_pPRDPhys, FALSE); if (!m_pPRD) { goto ExitFailure; } } // m_pPhysList tracks pages used for DMA buffers when the scatter/gather // buffer is unaligned if (!m_pPhysList) { m_pPhysList = (PPhysTable)VirtualAlloc(m_pStartMemory, UserKInfo[KINX_PAGESIZE], MEM_COMMIT, PAGE_READWRITE); if (!m_pPhysList) { goto ExitFailure; } // allocate the minimum number of fixed pages for (DWORD i = 0; i < MIN_PHYS_PAGES; i++) { PHYSICAL_ADDRESS PhysicalAddress = {0}; m_pPhysList[i].pVirtualAddress = (LPBYTE)HalAllocateCommonBuffer(&Adapter, UserKInfo[KINX_PAGESIZE], &PhysicalAddress, FALSE); m_pPhysList[i].pPhysicalAddress = (LPBYTE)PhysicalAddress.QuadPart; if (!m_pPhysList[i].pVirtualAddress) { goto ExitFailure; } } } m_dwPhysCount = 0; // m_pSGCopy tracks the mapping between scatter/gather buffers and DMA // buffers when the scatter/gather buffer is unaligned and we are reading, // so we can copy the read data back to the scatter/gather buffer; when the // scatter/gather buffer is aligned, m_pSGCopy tracks the scatter/gather // buffers of a particular DMA transfer, so we can unlock the buffers at // completion if (!m_pSGCopy) { m_pSGCopy = (PSGCopyTable)VirtualAlloc( m_pStartMemory + UserKInfo[KINX_PAGESIZE], UserKInfo[KINX_PAGESIZE], MEM_COMMIT, PAGE_READWRITE); if (!m_pSGCopy) { goto ExitFailure; } } m_dwSGCount = 0; if (!m_pPFNs) { m_pPFNs = (PDWORD)VirtualAlloc( m_pStartMemory + 2*UserKInfo[KINX_PAGESIZE], UserKInfo[KINX_PAGESIZE], MEM_COMMIT, PAGE_READWRITE); if (!m_pPFNs) { goto ExitFailure; } } // determine whether the a buffer or the buffer length is unaligned for (iBuffer = 0; iBuffer < dwSgCount; iBuffer++) { if ( ((DWORD)pSgBuf[iBuffer].sb_buf & dwAlignMask) || ((DWORD)pSgBuf[iBuffer].sb_len & dwAlignMask) ) { fUnalign = TRUE; break; } } if (fUnalign) { DWORD dwCurPageOffset = 0; for (iBuffer = 0; iBuffer < dwSgCount; iBuffer++) { LPBYTE pBuffer = (LPBYTE)pSgBuf[iBuffer].sb_buf; DWORD dwBufferLeft = pSgBuf[iBuffer].sb_len; while (dwBufferLeft) { DWORD dwBytesInCurPage = UserKInfo[KINX_PAGESIZE] - dwCurPageOffset; DWORD dwBytesToTransfer = (dwBufferLeft > dwBytesInCurPage) ? dwBytesInCurPage : dwBufferLeft; // allocate a new page, if necessary if ((dwCurPageOffset == 0) && (m_dwPhysCount >= MIN_PHYS_PAGES)) { PHYSICAL_ADDRESS PhysicalAddress = {0}; m_pPhysList[m_dwPhysCount].pVirtualAddress = (LPBYTE)HalAllocateCommonBuffer( &Adapter, UserKInfo[KINX_PAGESIZE], &PhysicalAddress, FALSE); m_pPhysList[m_dwPhysCount].pPhysicalAddress = (LPBYTE)PhysicalAddress.QuadPart; if (!m_pPhysList[m_dwPhysCount].pVirtualAddress) { goto ExitFailure; } } if (fRead) { // prepare a scatter/gather copy entry on read, so we can // copy data from the DMA buffer to the scatter/gather // buffer after this DMA transfer is complete m_pSGCopy[m_dwSGCount].pSrcAddress = m_pPhysList[m_dwPhysCount].pVirtualAddress + dwCurPageOffset; m_pSGCopy[m_dwSGCount].pDstAddress = pBuffer; m_pSGCopy[m_dwSGCount].dwSize = dwBytesToTransfer; m_dwSGCount++; } else { memcpy(m_pPhysList[m_dwPhysCount].pVirtualAddress + dwCurPageOffset, pBuffer, dwBytesToTransfer); } // if this buffer is larger than the space remaining on the page, // then finish processing this page by setting @dwCurPageOffset<-0 if (dwBufferLeft >= dwBytesInCurPage) { dwCurPageOffset = 0; } else { dwCurPageOffset += dwBytesToTransfer; } // have we finished a page? (i.e., offset was reset or this is the last buffer) if ((dwCurPageOffset == 0) || (iBuffer == (dwSgCount - 1))) { // add this to the PRD table m_pPRD[m_dwPhysCount].physAddr = (DWORD)m_pPhysList[m_dwPhysCount].pPhysicalAddress; m_pPRD[m_dwPhysCount].size = dwCurPageOffset ? (USHORT)dwCurPageOffset : (USHORT)UserKInfo[KINX_PAGESIZE]; m_pPRD[m_dwPhysCount].EOTpad = 0; m_dwPhysCount++; } // update transfer dwBufferLeft -= dwBytesToTransfer; pBuffer += dwBytesToTransfer; } } m_pPRD[m_dwPhysCount - 1].EOTpad = 0x8000; } else { DWORD dwTotalBytes = 0; for (iBuffer = 0; iBuffer < dwSgCount; iBuffer++) { LPBYTE pBuffer = (LPBYTE)pSgBuf[iBuffer].sb_buf; // determine the number of bytes remaining to be placed in PRD dwTotalBytes = pSgBuf[iBuffer].sb_len; if (!LockPages ( pBuffer, dwTotalBytes, m_pPFNs, fRead ? LOCKFLAG_WRITE : LOCKFLAG_READ) ) { goto ExitFailure; } // add a scatter/gather copy entry for the area we lock, so that // we can unlock it when we are finished m_pSGCopy[m_dwSGCount].pSrcAddress = pBuffer; m_pSGCopy[m_dwSGCount].pDstAddress = 0; m_pSGCopy[m_dwSGCount].dwSize = dwTotalBytes; m_dwSGCount++; iPFN = 0; while (dwTotalBytes) { DWORD dwBytesToTransfer = UserKInfo[KINX_PAGESIZE]; if ((DWORD)pBuffer & dwPageMask) { // the buffer is not page aligned; use up the next page // boundary dwBytesToTransfer = UserKInfo[KINX_PAGESIZE] - ((DWORD)pBuffer & dwPageMask); } if (dwTotalBytes < dwBytesToTransfer) { // use what remains dwBytesToTransfer = dwTotalBytes; } m_pPRD[iPage].physAddr = (m_pPFNs[iPFN] << UserKInfo[KINX_PFN_SHIFT]) + ((DWORD)pBuffer & dwPageMask); if (!TranslateAddress(&m_pPRD[iPage].physAddr)) { goto ExitFailure; } m_pPRD[iPage].size = (USHORT)dwBytesToTransfer; m_pPRD[iPage].EOTpad = 0; iPage++; iPFN++; // update transfer pBuffer += dwBytesToTransfer; dwTotalBytes -= dwBytesToTransfer; } } m_dwPhysCount = 0; m_pPRD[iPage-1].EOTpad = 0x8000; } return TRUE; ExitFailure: DEBUGCHK(0); // clean up // FreeDMABuffers(); 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 { PUCHAR ioPortBase = NULL; DWORD dwAddrLen; DWORD dwIOSpace; BOOL InstallIsr = FALSE; BOOL fResult = FALSE; LPVOID pobMem = NULL; LPVOID pobOhcd = NULL; DWORD PhysAddr; DWORD dwHPPhysicalMemSize; HKEY hKey=NULL; DDKWINDOWINFO dwi; DDKISRINFO dii; USBH_MSG((_T("[USBH] ++InitializeOHCI()\n\r"))); g_pSysConReg = (S3C6410_SYSCON_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_SYSCON, sizeof(S3C6410_SYSCON_REG), FALSE); if (g_pSysConReg == NULL) { USBH_ERR((_T("[USBH:ERR] InitializeOHCI() : DrvLib_MapIoSpace() Failed\n"))); return FALSE; } #ifdef USE_SRCCLK_EPLL //----------------------- // Initialize Clock // ClkSrc = MOUT_EPLL (96MHz) // Divide by 2 (96/2=48MHz) // HCLK, SCLK gate pass //----------------------- g_pSysConReg->CLK_SRC = (g_pSysConReg->CLK_SRC & ~(0x3<<5)) | (0x1<<5); // UHOST_SEL : MoutEPLL g_pSysConReg->CLK_DIV1 = (g_pSysConReg->CLK_DIV1 & ~(0xf<<20)) | (0x1<<20); // UHOST_RATIO : 96 MHz / (1+1) = 48 MHz #else //----------------------- // Initialize Clock // ClkSrc = USB_PHY(48MHz) // Divide by 1 (48/1=48MHz) // HCLK, SCLK gate pass //----------------------- g_pSysConReg->OTHERS |= (1<<16); // Set SUB Signal Mask g_pSysConReg->CLK_SRC &= ~(0x3<<5); // UHOST_SEL : 48MHz g_pSysConReg->CLK_DIV1 &= ~(0xf<<20); // UHOST_RATIO : 48 MHz / (0+1) = 48 MHz #endif g_pSysConReg->HCLK_GATE |= (0x1<<29); // HCLK_UHOST Pass (EVT1) g_pSysConReg->SCLK_GATE |= (0x1<<30); // SCLK_UHOST Pass if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,szDriverRegKey,0,0,&hKey)!= ERROR_SUCCESS) { DEBUGMSG(ZONE_ERROR,(TEXT("InitializeOHCI:GetRegistryConfig RegOpenKeyEx(%s) failed\r\n"), szDriverRegKey)); return FALSE; } dwi.cbSize=sizeof(dwi); dii.cbSize=sizeof(dii); if ( (DDKReg_GetWindowInfo(hKey, &dwi ) != ERROR_SUCCESS) || (DDKReg_GetIsrInfo (hKey, &dii ) != ERROR_SUCCESS)) { DEBUGMSG(ZONE_ERROR,(TEXT("InitializeOHCI:DDKReg_GetWindowInfo or DDKReg_GetWindowInfo failed\r\n"))); goto InitializeOHCI_Error; } if (dwi.dwNumMemWindows!=0) { PhysAddr = dwi.memWindows[0].dwBase; dwAddrLen= dwi.memWindows[0].dwLen; dwIOSpace = 0; } else if (dwi.dwNumIoWindows!=0) { PhysAddr= dwi.ioWindows[0].dwBase; dwAddrLen = dwi.ioWindows[0].dwLen; dwIOSpace = 1; } else { goto InitializeOHCI_Error; } DEBUGMSG(ZONE_INIT,(TEXT("OHCD: 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", dii.dwSysintr, dwi.dwInterfaceType, dwi.dwBusNumber)); ioPortBase = (PBYTE) PhysAddr; if (!(fResult = ConfigureOHCICard(pPddObject, &ioPortBase, dwAddrLen, dwIOSpace,(INTERFACE_TYPE)dwi.dwInterfaceType, dwi.dwBusNumber))) { goto InitializeOHCI_Error; } if (dii.szIsrDll[0] != 0 && dii.szIsrHandler[0]!=0 && dii.dwIrq<0xff && dii.dwIrq>0 ) { // Install ISR handler pPddObject->IsrHandle = LoadIntChainHandler(dii.szIsrDll, dii.szIsrHandler, (BYTE)dii.dwIrq); if (!pPddObject->IsrHandle) { DEBUGMSG(ZONE_ERROR, (L"OHCD: Couldn't install ISR handler\r\n")); } else { GIISR_INFO Info; PHYSICAL_ADDRESS PortAddress = {PhysAddr, 0}; DEBUGMSG(ZONE_INIT, (L"OHCD: Installed ISR handler, Dll = '%s', Handler = '%s', Irq = %d\r\n", dii.szIsrDll, dii.szIsrHandler, dii.dwIrq)); if (!BusTransBusAddrToStatic(pPddObject->hParentBusHandle,(INTERFACE_TYPE)dwi.dwInterfaceType, dwi.dwBusNumber, PortAddress, dwAddrLen, &dwIOSpace, (PPVOID)&PhysAddr)) { DEBUGMSG(ZONE_ERROR, (L"OHCD: Failed TransBusAddrToStatic\r\n")); goto InitializeOHCI_Error; } // Set up ISR handler Info.SysIntr = dii.dwSysintr; Info.CheckPort = TRUE; Info.PortIsIO = (dwIOSpace) ? TRUE : FALSE; Info.UseMaskReg = TRUE; Info.PortAddr = PhysAddr + 0x0C; Info.PortSize = sizeof(DWORD); Info.MaskAddr = PhysAddr + 0x10; if (!KernelLibIoControl(pPddObject->IsrHandle, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL)) { DEBUGMSG(ZONE_ERROR, (L"OHCD: KernelLibIoControl call failed.\r\n")); } } } // The PDD can supply a buffer of contiguous physical memory here, or can let the // MDD try to allocate the memory from system RAM. We will use the HalAllocateCommonBuffer() // API to allocate the memory and bus controller physical addresses and pass this information // into the MDD. if (GetRegistryPhysicalMemSize(szDriverRegKey,&pPddObject->dwPhysicalMemSize)) { // A quarter for High priority Memory. dwHPPhysicalMemSize = pPddObject->dwPhysicalMemSize/4; // Align with page size. pPddObject->dwPhysicalMemSize = (pPddObject->dwPhysicalMemSize + PAGE_SIZE -1) & ~(PAGE_SIZE -1); dwHPPhysicalMemSize = ((dwHPPhysicalMemSize + PAGE_SIZE -1) & ~(PAGE_SIZE -1)); } else { pPddObject->dwPhysicalMemSize=0; dwHPPhysicalMemSize = 0 ; } if (pPddObject->dwPhysicalMemSize<gcTotalAvailablePhysicalMemory) { // Setup Minimun requirement. pPddObject->dwPhysicalMemSize = gcTotalAvailablePhysicalMemory; dwHPPhysicalMemSize = gcHighPriorityPhysicalMemory; } pPddObject->AdapterObject.ObjectSize = sizeof(DMA_ADAPTER_OBJECT); pPddObject->AdapterObject.InterfaceType = dwi.dwInterfaceType; pPddObject->AdapterObject.BusNumber = dwi.dwBusNumber; if ((pPddObject->pvVirtualAddress = HalAllocateCommonBuffer(&pPddObject->AdapterObject, pPddObject->dwPhysicalMemSize, &pPddObject->LogicalAddress, FALSE)) == NULL) { goto InitializeOHCI_Error; } if (!(pobMem = HcdMdd_CreateMemoryObject(pPddObject->dwPhysicalMemSize, dwHPPhysicalMemSize, (PUCHAR) pPddObject->pvVirtualAddress, (PUCHAR) pPddObject->LogicalAddress.LowPart))) { goto InitializeOHCI_Error; } if (!(pobOhcd = HcdMdd_CreateHcdObject(pPddObject, pobMem, szDriverRegKey, ioPortBase, dii.dwSysintr))) { goto InitializeOHCI_Error; } pPddObject->lpvMemoryObject = pobMem; pPddObject->lpvOhcdMddObject = pobOhcd; _tcsncpy(pPddObject->szDriverRegKey, szDriverRegKey, MAX_PATH); pPddObject->ioPortBase = ioPortBase; pPddObject->dwSysIntr = dii.dwSysintr; // PCI OHCI support suspend and resume if ( hKey!=NULL) { DWORD dwCapability; DWORD dwType; DWORD dwLength = sizeof(DWORD); if (RegQueryValueEx(hKey, HCD_CAPABILITY_VALNAME, 0, &dwType, (PUCHAR)&dwCapability, &dwLength) == ERROR_SUCCESS) { HcdMdd_SetCapability(pobOhcd, dwCapability); USBH_INF((_T("[USBH:INF] InitializeOHCI() : USB Host Cap : 0x%08x\n"), dwCapability)); } RegCloseKey(hKey); } USBH_MSG((_T("[USBH] --InitializeOHCI() : Success\n\r"))); return TRUE; InitializeOHCI_Error: if (g_pSysConReg != NULL) { DrvLib_UnmapIoSpace((PVOID)g_pSysConReg); g_pSysConReg = NULL; } if (pPddObject->IsrHandle) { FreeIntChainHandler(pPddObject->IsrHandle); pPddObject->IsrHandle = NULL; } if (pobOhcd) { HcdMdd_DestroyHcdObject(pobOhcd); } if (pobMem) { HcdMdd_DestroyMemoryObject(pobMem); } if(pPddObject->pvVirtualAddress) { HalFreeCommonBuffer(&pPddObject->AdapterObject, pPddObject->dwPhysicalMemSize, pPddObject->LogicalAddress, pPddObject->pvVirtualAddress, FALSE); } pPddObject->lpvMemoryObject = NULL; pPddObject->lpvOhcdMddObject = NULL; pPddObject->pvVirtualAddress = NULL; if ( hKey!=NULL) { RegCloseKey(hKey); } USBH_ERR((_T("[USBH:ERR] --InitializeOHCI() : Error\n\r"))); return FALSE; }
BOOL CRomiDisk::Init( HKEY hActiveKey ) { BOOL bRet = FALSE; m_f16Bit = TRUE; // PCI is 16-bit // configure port if (!InitializePort()) { DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T( "Atapi!CRomiDisk::Init> Failed to configure port; device(%u)\r\n" ), m_dwDeviceId)); goto exit; } // assign the appropriate folder name m_szDiskName = (IsCDRomDevice() ? g_szPCICDRomDisk : g_szPCIHardDisk); // reserve memory for DMA buffers m_pStartMemory = (LPBYTE)VirtualAlloc(NULL, 0x10000, MEM_RESERVE, PAGE_READWRITE); if (!m_pStartMemory) { bRet = FALSE; } WriteReg(ATA_CONTROL, ReadReg(ATA_CONTROL) | 0x1); // finish intialization; i.e., initialize device bRet = CDisk::Init(hActiveKey); if ((m_pPort->m_pDskReg[m_dwDeviceId]->dwEnablePDMA || m_pPort->m_pDskReg[m_dwDeviceId]->dwEnableUDMA) && m_pDMAVirtualAddress == NULL) { DMA_ADAPTER_OBJECT dmaAdapter; dmaAdapter.ObjectSize = sizeof(dmaAdapter); dmaAdapter.InterfaceType = Internal; dmaAdapter.BusNumber = 0; m_pDMAVirtualAddress= (PBYTE)HalAllocateCommonBuffer( &dmaAdapter, m_pPort->m_pDskReg[m_dwDeviceId]->dwDoubleBufferSize, &m_DMAPhyaddress, FALSE ); } if (m_pPort->m_pDskReg[m_dwDeviceId]->dwEnableUDMA && ( m_Id.UltraDMASupport & 0x3f)) { for(int i=5;i>=0;i--) { if(m_Id.UltraDMASupport & (0x01<<i)) { m_dwCurrentUDMAMode = (i > 4) ? 4 : i; break; } } SetPioMode(PIO0); SetUdmaMode(); DEBUGMSG(ZONE_INIT, (_T("### ATA-Disk supports UDMA to 0x%x 0x%x\r\n"), m_Id.UltraDMASupport,m_dwCurrentUDMAMode)); m_pPort->m_pDskReg[m_dwDeviceId]->dwEnablePDMA = FALSE; } else if (m_pPort->m_pDskReg[m_dwDeviceId]->dwEnablePDMA) { SetPioMode(m_Id.AdvancedPIOxferreserved); m_pPort->m_pDskReg[m_dwDeviceId]->dwEnableUDMA = FALSE;; DEBUGMSG(ZONE_INIT, (_T("### ATA-Disk dose not support UDMA. It is running on PDMA\r\n"))); } else { SetPioMode(m_Id.AdvancedPIOxferreserved); m_pPort->m_pDskReg[m_dwDeviceId]->dwEnableUDMA = FALSE;; m_pPort->m_pDskReg[m_dwDeviceId]->dwEnablePDMA = FALSE;; DEBUGMSG(ZONE_INIT, (_T("### ATA-Disk is running on PIO MODE\r\n"))); DEBUGMSG(ZONE_INIT, (_T("Atapi!CDisk::Init> Disabled DMA\r\n"))); } // associate interrupt event with IRQ if (!InterruptInitialize( m_pPort->m_dwSysIntr, m_pPort->m_hIRQEvent, NULL, 0) ) { DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T( "Atapi!CRomiDisk::ConfigPort> Failed to initialize interrupt(SysIntr(%d)) for device(%d)\r\n" ), m_pPort->m_dwSysIntr, m_dwDeviceId)); bRet = FALSE; } if (!bRet) { goto exit; } exit:; return bRet; }
BOOLEAN CreateDMA(PDEVICE_OBJECT DeviceObject) { DEVICE_DESCRIPTION Desc; ULONG MappedRegs = 0; PDEVICE_EXTENSION Device = DeviceObject->DeviceExtension; KEVENT DMAEvent; KIRQL OldIrql; // Buffersize should already be set but it isn't yet ! Device->BufferSize = SB_BUFSIZE; DPRINT("Bufsize == %u\n", Device->BufferSize); RtlZeroMemory(&Desc, sizeof(DEVICE_DESCRIPTION)); // Init memory! Desc.Version = DEVICE_DESCRIPTION_VERSION; Desc.Master = FALSE; // Slave Desc.ScatterGather = FALSE; // Don't think so anyway Desc.DemandMode = FALSE; // == !SingleModeDMA Desc.AutoInitialize = TRUE; // ? Desc.Dma32BitAddresses = FALSE; // I don't think we can Desc.IgnoreCount = FALSE; // Should be OK Desc.Reserved1 = 0; // Desc.Reserved2 = 0; Desc.BusNumber = 0; Desc.DmaChannel = Device->DMA; // Our channel :) Desc.InterfaceType = Isa; // (BusType == MicroChannel) ? MicroChannel : Isa; Desc.DmaWidth = 0; // hmm... 8 bits? Desc.DmaSpeed = 0; // double hmm (Compatible it should be) Desc.MaximumLength = Device->BufferSize; // Desc.MinimumLength = 0; Desc.DmaPort = 0; DPRINT("Calling HalGetAdapter(), asking for %d mapped regs\n", MappedRegs); Device->Adapter = HalGetAdapter(&Desc, &MappedRegs); DPRINT("Called\n"); if (! Device->Adapter) { DPRINT("HalGetAdapter() FAILED\n"); return FALSE; } DPRINT("Bufsize == %u\n", Device->BufferSize); if (MappedRegs < BYTES_TO_PAGES(Device->BufferSize)) { DPRINT("Could only allocate %u mapping registers\n", MappedRegs); if (MappedRegs == 0) return FALSE; Device->BufferSize = MappedRegs * PAGE_SIZE; DPRINT("Bufsize == %u\n", Device->BufferSize); } DPRINT("Allocated %u mapping registers\n", MappedRegs); // Check if we already have memory here... // Check to make sure we're >= minimum DPRINT("Allocating buffer\n"); DPRINT("Bufsize == %u\n", Device->BufferSize); Device->VirtualBuffer = HalAllocateCommonBuffer(Device->Adapter, Device->BufferSize, &Device->Buffer, FALSE); // For some reason BufferSize == 0 here?! // DPRINT("Buffer == 0x%x Bufsize == %u\n", Device->Buffer, Device->BufferSize); DPRINT("Bufsize == %u,", Device->BufferSize); DPRINT("Buffer == 0x%x\n", Device->Buffer); if (! Device->VirtualBuffer) { DPRINT("Could not allocate buffer :(\n"); // should try again with smaller buffer... return FALSE; } // DPRINT("Buffer == 0x%x Bufsize == %u\n", Device->Buffer, Device->BufferSize); DPRINT("Bufsize == %u,", Device->BufferSize); DPRINT("Buffer == 0x%x\n", Device->Buffer); DPRINT("Calling IoAllocateMdl()\n"); Device->Mdl = IoAllocateMdl(Device->VirtualBuffer, Device->BufferSize, FALSE, FALSE, NULL); DPRINT("Bufsize == %u\n", Device->BufferSize); // IS THIS RIGHT: if (! Device->Mdl) { DPRINT("IoAllocateMdl() FAILED\n"); // Free the HAL buffer return FALSE; } DPRINT("VBuffer == 0x%x Mdl == %u Bufsize == %u\n", Device->VirtualBuffer, Device->Mdl, Device->BufferSize); DPRINT("Calling MmBuildMdlForNonPagedPool\n"); MmBuildMdlForNonPagedPool(Device->Mdl); DPRINT("Bufsize == %u\n", Device->BufferSize); // part II: KeInitializeEvent(&DMAEvent, SynchronizationEvent, FALSE); // Raise IRQL KeRaiseIrql(DISPATCH_LEVEL,&OldIrql); IoAllocateAdapterChannel(Device->Adapter, DeviceObject, BYTES_TO_PAGES(Device->BufferSize), SoundProgramDMA, &DMAEvent); // Lower IRQL KeLowerIrql(OldIrql); DPRINT("VBuffer == 0x%x Bufsize == %u\n", Device->VirtualBuffer, Device->BufferSize); KeWaitForSingleObject(&DMAEvent, Executive, KernelMode, FALSE, NULL); // if (MappedRegs == 0) // MappedRegs = 2; // else // MappedRegs ++; // Status = IoAllocateAdapterChannel( // Adapter, // DeviceObject, // MappedRegs, // CALLBACK, // DeviceObject); // Context return TRUE; }
NTSTATUS SpWmiPassToMiniPort( IN PDEVICE_OBJECT DeviceObject, IN UCHAR WmiMinorCode, IN OUT PWMI_PARAMETERS WmiParameters ) /*++ Routine Description: This function pass a WMI request to the miniport driver for processing. It creates an SRB which is processed normally by the port driver. This call is synchronous. Callers of SpWmiPassToMiniPort must be running at IRQL PASSIVE_LEVEL. Arguments: DeviceObject - Pointer to the functional or physical device object. WmiMinorCode - WMI action to perform. WmiParameters - WMI parameters. Return Value: An NTSTATUS code describing the result of handling the WMI request. Complete the IRP with this status. Notes: If this WMI request is completed with STATUS_SUCCESS, the WmiParameters BufferSize field will reflect the actual size of the WMI return buffer. --*/ { PCOMMON_EXTENSION commonExtension = DeviceObject->DeviceExtension; PADAPTER_EXTENSION fdoExtension; SCSI_WMI_REQUEST_BLOCK srb; LARGE_INTEGER startingOffset; PLOGICAL_UNIT_EXTENSION logicalUnit; ULONG commonBufferSize; PUCHAR commonBuffer; PHYSICAL_ADDRESS physicalAddress; PVOID removeTag = (PVOID)((ULONG_PTR)WmiParameters+3); PWNODE_HEADER wnode; NTSTATUS status; PAGED_CODE(); startingOffset.QuadPart = (LONGLONG) 1; // // Zero out the SRB. // RtlZeroMemory(&srb, sizeof(SCSI_WMI_REQUEST_BLOCK)); // // Initialize the SRB for a WMI request. // if (commonExtension->IsPdo) { // [PDO] // // Set the logical unit addressing from this PDO's device extension. // logicalUnit = DeviceObject->DeviceExtension; SpAcquireRemoveLock(DeviceObject, removeTag); srb.PathId = logicalUnit->PathId; srb.TargetId = logicalUnit->TargetId; srb.Lun = logicalUnit->Lun; fdoExtension = logicalUnit->AdapterExtension; } else { // [FDO] // // Set the logical unit addressing to the first logical unit. This is // merely used for addressing purposes for adapter requests only. // NOTE: SpFindSafeLogicalUnit will acquire the remove lock // logicalUnit = SpFindSafeLogicalUnit(DeviceObject, 0xff, removeTag); if (logicalUnit == NULL) { return(STATUS_DEVICE_DOES_NOT_EXIST); } fdoExtension = DeviceObject->DeviceExtension; srb.WMIFlags = SRB_WMI_FLAGS_ADAPTER_REQUEST; srb.PathId = logicalUnit->PathId; srb.TargetId = logicalUnit->TargetId; srb.Lun = logicalUnit->Lun; } // // HACK - allocate a chunk of common buffer for the actual request to // get processed in. We need to determine the size of buffer to allocate // this is the larger of the input or output buffers // if (WmiMinorCode == IRP_MN_EXECUTE_METHOD) { wnode = (PWNODE_HEADER)WmiParameters->Buffer; commonBufferSize = (WmiParameters->BufferSize > wnode->BufferSize) ? WmiParameters->BufferSize : wnode->BufferSize; } else { commonBufferSize = WmiParameters->BufferSize; } commonBuffer = HalAllocateCommonBuffer(fdoExtension->DmaAdapterObject, commonBufferSize, &physicalAddress, FALSE); if(commonBuffer == NULL) { DebugPrint((1, "SpWmiPassToMiniPort: Unable to allocate %#x bytes of " "common buffer\n", commonBufferSize)); SpReleaseRemoveLock(logicalUnit->DeviceObject, removeTag); return STATUS_INSUFFICIENT_RESOURCES; } try { KEVENT event; PIRP irp; PMDL mdl; PIO_STACK_LOCATION irpStack; RtlCopyMemory(commonBuffer, WmiParameters->Buffer, commonBufferSize); srb.DataBuffer = commonBuffer; // [already non-paged] srb.DataTransferLength = WmiParameters->BufferSize; srb.Function = SRB_FUNCTION_WMI; srb.Length = sizeof(SCSI_REQUEST_BLOCK); srb.WMISubFunction = WmiMinorCode; srb.DataPath = WmiParameters->DataPath; srb.SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_NO_QUEUE_FREEZE; srb.TimeOutValue = 10; // [ten seconds] // // Note that the value in DataBuffer may be used regardless of the value // of the MapBuffers field. // // // Initialize the notification event. // KeInitializeEvent(&event, NotificationEvent, FALSE); // // Build IRP for this request. // Note we do this synchronously for two reasons. If it was done // asynchonously then the completion code would have to make a special // check to deallocate the buffer. Second if a completion routine were // used then an additional IRP stack location would be needed. // irp = IoAllocateIrp(logicalUnit->DeviceObject->StackSize, FALSE); if(irp == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; leave; } mdl = IoAllocateMdl(commonBuffer, WmiParameters->BufferSize, FALSE, FALSE, irp); if(mdl == NULL) { IoFreeIrp(irp); status = STATUS_INSUFFICIENT_RESOURCES; leave; } MmBuildMdlForNonPagedPool(mdl); srb.OriginalRequest = irp; irpStack = IoGetNextIrpStackLocation(irp); // // Set major code. // irpStack->MajorFunction = IRP_MJ_SCSI; // // Set SRB pointer. // irpStack->Parameters.Scsi.Srb = (PSCSI_REQUEST_BLOCK)&srb; // // Setup a completion routine so we know when the request has completed. // IoSetCompletionRoutine(irp, SpSignalCompletion, &event, TRUE, TRUE, TRUE); // // Flush the data buffer for output. This will insure that the data is // written back to memory. Since the data-in flag is the the port driver // will flush the data again for input which will ensure the data is not // in the cache. // KeFlushIoBuffers(irp->MdlAddress, FALSE, TRUE); // // Call port driver to handle this request. // IoCallDriver(logicalUnit->CommonExtension.DeviceObject, irp); // // Wait for request to complete. // KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = irp->IoStatus.Status; // // Relay the return buffer's size to the caller on success. // if (NT_SUCCESS(status)) { WmiParameters->BufferSize = srb.DataTransferLength; } // // Copy back the correct number of bytes into the caller provided buffer. // RtlCopyMemory(WmiParameters->Buffer, commonBuffer, WmiParameters->BufferSize); // // Free the irp and MDL. // IoFreeMdl(mdl); IoFreeIrp(irp); } finally { HalFreeCommonBuffer(fdoExtension->DmaAdapterObject, commonBufferSize, physicalAddress, commonBuffer, FALSE); SpReleaseRemoveLock(logicalUnit->CommonExtension.DeviceObject, removeTag); } // // Return the IRP's status. // return status; }