Exemplo n.º 1
0
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;

}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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
           ));

}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
/* 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;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
Arquivo: dma.c Projeto: GYGit/reactos
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;
}
Exemplo n.º 10
0
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;
}