亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? pci9054device.cpp

?? 《windows驅動開發程序XP》(武安河)的驅動開發書籍源代碼
?? CPP
字號:
// PCI9054Device.cpp
// Implementation of PCI9054Device device class
//
// Generated by DriverWizard version DriverStudio 2.6.0 (Build 336)
// Requires Compuware's DriverWorks classes
//

#pragma warning(disable:4065) // Allow switch statement with no cases
		  
#include <vdw.h>
#include "..\PCI9054Deviceinterface.h"

#include "PCI9054.h"
#include "PCI9054Device.h"

#pragma hdrstop("PCI9054.pch")

#define INTCSR    0x68
#define DMAMODE0  0x80
#define DMAPADR0  0x84
#define DMALADR0  0x88
#define DMASIZ0   0x8C
#define DMADPR0   0x90
#define DMACSR0   0xA8

GUID PCI9054Device_Guid = PCI9054Device_CLASS_GUID;
KTrace t("PCI9054");

PCI9054Device::PCI9054Device(PDEVICE_OBJECT Pdo, ULONG Unit) :
	KPnpDevice(Pdo, &PCI9054Device_Guid)
{

	// Check constructor status
    if ( ! NT_SUCCESS(m_ConstructorStatus) )
	{
	    return;
	}

	// Remember our unit number
	m_Unit = Unit;

	// Initialize the lower device
	m_Lower.Initialize(this, Pdo);

    // Inform the base class of the lower edge device object
	SetLowerDevice(&m_Lower);

	// Initialize the PnP Policy settings to the "standard" policy
	SetPnpPolicy();

}

PCI9054Device::~PCI9054Device()
{
}

NTSTATUS PCI9054Device::DefaultPnp(KIrp I) 
{
	I.ForceReuseOfCurrentStackLocationInCalldown();
	return m_Lower.PnpCall(this, I);
}

NTSTATUS PCI9054Device::DefaultPower(KIrp I) 
{
	I.IndicatePowerIrpProcessed();
	I.CopyParametersDown();
	return m_Lower.PnpPowerCall(this, I);
}

NTSTATUS PCI9054Device::SystemControl(KIrp I) 
{
	I.ForceReuseOfCurrentStackLocationInCalldown();
	return m_Lower.PnpCall(this, I);
}

VOID PCI9054Device::Invalidate()
{
	// It is not necessary to release the system resource for the DMA adapter
	// object, since NT provides no mechanism for this.
	m_Buffer.Invalidate();

	// For each memory mapped region, release the underlying system resoruce.
	m_MemoryRange0.Invalidate();

	// For each I/O port mapped region, release the underlying system resource.
	m_IoPortRange0.Invalidate();
	m_IoPortRange1.Invalidate();

	// For the interrupt, release the underlying system resource.
	m_Irq.Invalidate();
}

NTSTATUS PCI9054Device::OnStartDevice(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	I.Information() = 0;

	// The default Pnp policy has already cleared the IRP with the lower device
	// Initialize the physical device object.

	// Get the list of raw resources from the IRP
	PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources();
	// Get the list of translated resources from the IRP
	PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources();

// TODO:	Check to ensure that the following parameters are correct for your hardware
//
#define MAX_DMA_LENGTH	0x100000	// 0x100000 is 1 MB

	// Initialize the device descriptor for the DMA object using the assigned resource
	DEVICE_DESCRIPTION dd;
	RtlZeroMemory(&dd, sizeof(dd));
	dd.Version = DEVICE_DESCRIPTION_VERSION;
	dd.Master = TRUE;
	dd.ScatterGather = FALSE;
	dd.DemandMode = TRUE;
	dd.AutoInitialize = FALSE;
	dd.Dma32BitAddresses = TRUE;
	dd.IgnoreCount = FALSE;
	dd.DmaChannel = 0;
	dd.InterfaceType = PCIBus;
	dd.DmaWidth = Width32Bits;	// PCI default width
	dd.DmaSpeed = Compatible;
	dd.MaximumLength = MAX_DMA_LENGTH;

	// Initialize the DMA adapter object
	m_Dma.Initialize(&dd, m_Lower.TopOfStack());
	m_Buffer.Initialize(&m_Dma,2048);

	// Create an instance of KPciConfiguration so we can map Base Address
	// Register indicies to ordinals for memory or I/O port ranges.
	KPciConfiguration PciConfig(m_Lower.TopOfStack());

	// For each memory mapped region, initialize the memory mapped range
	// using the resources provided by NT. Once initialized, each memory
	// range's base virtual address in system space can be obtained by calling
	// member Base(). Each memory range's physical address in CPU space can
	// obtained by calling CpuPhysicalAddress(). To access the memory mapped
	// range use member functions such as inb/outb, or the array element operator. 
	status = m_MemoryRange0.Initialize(
		pResListTranslated,
		pResListRaw,
		PciConfig.BaseAddressIndexToOrdinal(0)
		);
	if (!NT_SUCCESS(status))
	{
		Invalidate();
		return status;		
	}

	// For each I/O port mapped region, initialize the I/O port range using
	// the resources provided by NT. Once initialized, use member functions such as
	// inb/outb, or the array element operator to access the ports range.
	status = m_IoPortRange0.Initialize(
		pResListTranslated,
		pResListRaw,
		PciConfig.BaseAddressIndexToOrdinal(1)
		);
	if (!NT_SUCCESS(status))
	{
		Invalidate();
		return status;		
	}

	status = m_IoPortRange1.Initialize(
		pResListTranslated,
		pResListRaw,
		1
		);
	if (!NT_SUCCESS(status))
	{
		Invalidate();
		return status;		
	}

	// Initialize and connect the interrupt
	status = m_Irq.InitializeAndConnect(
		pResListTranslated, 
		LinkTo(Isr_Irq), 
		this
		);
	if (!NT_SUCCESS(status))
	{
		Invalidate();
		return status;		
	}

	// Setup the DPC to be used for interrupt processing
	m_DpcFor_Irq.Setup(LinkTo(DpcFor_Irq), this);
	// TODO:	Add device-specific code to start your device.
	m_IoPortRange0.outd(INTCSR,0x40100);//允許PCI中斷和DMA通道0中斷

	return status;
}

NTSTATUS PCI9054Device::OnStopDevice(KIrp I)
{
	m_IoPortRange0.outd(INTCSR,0);//禁止PCI中斷和DMA通道0中斷
	m_Irq.Disconnect();
	Invalidate();

	return STATUS_SUCCESS;
}

NTSTATUS PCI9054Device::OnRemoveDevice(KIrp I)
{
	m_IoPortRange0.outd(INTCSR,0);
	m_Irq.Disconnect();
	Invalidate();

	return STATUS_SUCCESS;
}

VOID PCI9054Device::CancelQueuedIrp(KIrp I)
{
	KDeviceQueue dq(DeviceQueue());

	// Test if the IRP is the current IRP.
	if ( (PIRP)I == CurrentIrp() )
	{
		CurrentIrp() = NULL;
		CancelSpinLock::Release(I.CancelIrql());
	    I.Information() = 0;
		I.Status() = STATUS_CANCELLED;
		PnpNextIrp(I);
	}
	// See if the IRP can be removed from the device queue.
	else if (dq.RemoveSpecificEntry(I))
	{
		CancelSpinLock::Release(I.CancelIrql());
	    I.Information() = 0;
		I.PnpComplete(this, STATUS_CANCELLED);
	}
	else
	{
		CancelSpinLock::Release(I.CancelIrql());
	}
}

VOID PCI9054Device::StartIo(KIrp I)
{
	if ( !I.TestAndSetCancelRoutine(
		LinkTo(CancelQueuedIrp),
		NULL,
		CurrentIrp()) )
	{
		return;
	}

	switch (I.MajorFunction())
	{
		case IRP_MJ_READ:
			SerialRead(I);
			break;
		case IRP_MJ_WRITE:
			SerialWrite(I);
			break;
		default:
			ASSERT(FALSE);
			PnpNextIrp(I);
			break;
	}
}

NTSTATUS PCI9054Device::Create(KIrp I)
{
	NTSTATUS status;

	status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

	return status;
}

NTSTATUS PCI9054Device::Close(KIrp I)
{
	NTSTATUS status;

	status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

    return status;
}

NTSTATUS PCI9054Device::CleanUp(KIrp I)
{
    KDeviceQueue dq(DeviceQueue());
	dq.PnpCleanUp(this, I.FileObject());
	return I.PnpComplete(this, STATUS_SUCCESS);
}

void PCI9054Device::SerialRead(KIrp I)
{
	NTSTATUS status		= STATUS_SUCCESS;

	t << "Entering SerialRead\n";

	// Create a new DMA transfer object for this IRP
	m_CurrentTransfer = new(NonPagedPool) KDmaTransfer(this, &m_Dma);

	if ( m_CurrentTransfer == NULL )
	{
		status = STATUS_INSUFFICIENT_RESOURCES;
		DbgPrint("unable to allocate transfer object: %x\n", status);

		I.Information() = 0;
		I.Status() = status;
		PnpNextIrp(I);
	}

	//下面采用應用程序的數據緩沖區作為DMA數據區
	status = m_CurrentTransfer->Initiate(
		I.Mdl(),
		(I.MajorFunction() == IRP_MJ_READ) ? FromDeviceToMemory : FromMemoryToDevice,
		LinkTo(OnDmaReady)
		);
/*	下面采用公用緩沖區作為DMA數據區
	status = m_CurrentTransfer->Initiate(
		this,
		&m_Dma,
		I.Mdl(),
		(I.MajorFunction() == IRP_MJ_READ) ? FromDeviceToMemory : FromMemoryToDevice,
		LinkTo(OnDmaReady),
		&m_Buffer
		);
*/
	// If the transfer cannot be initiated, complete it with an error status.
	if ( ! NT_SUCCESS(status) )
	{
		DbgPrint("unable to initiate transfer: %x\n", status);

		delete m_CurrentTransfer;
		m_CurrentTransfer = NULL;

		I.Information() = 0;
		I.Status() = status;
		PnpNextIrp(I);
	}
}

NTSTATUS PCI9054Device::Read(KIrp I) 
{
	if (I.ReadSize() == 0)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_SUCCESS);
	}

	return QueueIrp(I, LinkTo(CancelQueuedIrp));
}

void PCI9054Device::SerialWrite(KIrp I)
{
	NTSTATUS status		= STATUS_SUCCESS;
	ULONG i;

	// Declare a memory object
	KMemory Mem(I.Mdl());
	// Use the memory object to create a pointer to the caller's buffer
	PUCHAR	pBuffer		= (PUCHAR) Mem.MapToSystemSpace();

	ULONG   dwTotalSize = I.WriteSize(CURRENT);
	ULONG   dwBytesSent = 0;
	//清空FIFO
	m_IoPortRange1.outb(0,0);
	//用I/O輸出命令往FIFO寫數據
	for (i=0;i<dwTotalSize;i++) m_IoPortRange1.outb(0x4,*pBuffer++);

	I.Information() = dwBytesSent;
	I.Status() = status;

	PnpNextIrp(I);
}

NTSTATUS PCI9054Device::Write(KIrp I) 
{
	if (I.WriteSize() == 0)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_SUCCESS);
	}

	return QueueIrp(I, LinkTo(CancelQueuedIrp));
}

VOID PCI9054Device::DpcFor_Irq(PVOID Arg1, PVOID Arg2)
{
	m_CurrentTransfer->Continue(UseTransferSize);
}

BOOLEAN PCI9054Device::Isr_Irq(void)
{
	ULONG status;

	status=	m_IoPortRange0.ind(INTCSR);

	if ((status & 0x200000)==0)
	{
		// Return FALSE to indicate that this device did not cause the interrupt.
		return FALSE;
	}
	m_IoPortRange0.outd(DMAMODE0,0x20800);
	m_IoPortRange0.outb(DMACSR0,0x10);//Clear Interrupt

	// Request deferred procedure call
	// The arguments to Request may be any values that you choose
	if (!m_DpcFor_Irq.Request(NULL, NULL))
	{
// TODO:	Request is already in the queue
//			You may want to set flags or perform
//			other actions in this case
	}

	// Return TRUE to indicate that our device caused the interrupt
	return TRUE;
}

VOID PCI9054Device::StartDMA(ULONG PAddress,ULONG NBytes)
{
	//下面幾條語句設置DMA通道0寄存器,啟動塊傳輸方式,從FIFO讀數據
	//Channel0 interrupt to the PCI Bus interrupt,Done Interrupt Enable,FIFO
	m_IoPortRange0.outd(DMAMODE0,0x20C00);
	//DMA Channel0 PCI Address
	m_IoPortRange0.outd(DMAPADR0,PAddress);
	//DMA Channel0 Local Address,自己設計的FIFO地址
	m_IoPortRange0.outd(DMALADR0,0x8);
	//DMA Channel0 Transfer Size(Bytes)
	m_IoPortRange0.outd(DMASIZ0,NBytes);
	//from the Local Bus to the PCI Bus
	m_IoPortRange0.outd(DMADPR0,0x8);
	//Channel0 Enable,Start
	m_IoPortRange0.outb(DMACSR0,0x3);
}

VOID PCI9054Device::OnDmaReady(KDmaTransfer* pXfer, KIrp I)
{
	// All KDmaTransfer callbacks must first check to see if there are any bytes
	// left to transfer.
	if (pXfer->BytesRemaining() == 0)
	{
		// If there are no bytes left to transfer, the callback must call
		// Terminate(). Then it completes the IRP with STATUS_SUCCESS.
		pXfer->Terminate();
	
		I.Information() = I.ReadSize(CURRENT);
		I.Status() = STATUS_SUCCESS;
		PnpNextIrp(I);

		m_CurrentTransfer = NULL;
		delete pXfer;
		return;
	}

	// We must get the descriptor for the physical memory location for
	// the DMA transfer.

	PTRANSFER_DESCRIPTOR ptd;

	while (pXfer->SequenceTransferDescriptors(&ptd)) {
		// program the h/w using  ppTD
		t << " Physical address 0x" << ptd->td_PhysAddr.LowPart << ". Length is 0x"
			<< ptd->td_Length << "." << EOL;
	}

	// If this is the first time through, then start the DMA going.
	// We only want to do this ONCE for a given Read transfer.  That
	// way, our data will be collected smoothly, without interruptions
	// or dropouts.
	if ((ULONG) pXfer->BytesRemaining() == I.ReadSize())
		StartDMA(ptd->td_PhysAddr.LowPart,ptd->td_Length);
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91在线一区二区| 国产麻豆成人传媒免费观看| 中文成人综合网| 久久久久国色av免费看影院| 精品国产乱码久久久久久浪潮| 91成人免费在线| 欧美亚洲综合在线| 欧美色偷偷大香| 日韩欧美电影一二三| 精品福利二区三区| 国产午夜亚洲精品理论片色戒| 国产网红主播福利一区二区| 亚洲国产精品精华液2区45| 中文av一区二区| 夜夜揉揉日日人人青青一国产精品| 亚洲国产欧美在线| 紧缚捆绑精品一区二区| 国产成人在线电影| 色噜噜狠狠色综合中国| 欧美性欧美巨大黑白大战| 91精品久久久久久蜜臀| 亚洲精品一区二区三区香蕉| 欧美国产精品一区二区| 亚洲精品一二三区| 蜜桃传媒麻豆第一区在线观看| 国产露脸91国语对白| 97aⅴ精品视频一二三区| 欧美亚男人的天堂| 久久久久久久性| 亚洲综合久久av| 精品一区二区三区免费毛片爱| 成人免费三级在线| 在线电影院国产精品| 久久婷婷色综合| 一区二区三区四区亚洲| 久久精品免费看| 91激情五月电影| 精品成人一区二区三区四区| 亚洲女人小视频在线观看| 奇米影视在线99精品| 成人动漫中文字幕| 3atv在线一区二区三区| 国产精品传媒入口麻豆| 麻豆一区二区在线| 色先锋资源久久综合| 欧美精品一区二区三区在线| 一卡二卡三卡日韩欧美| 国产露脸91国语对白| 欧美一区二区三区四区久久 | 欧美日韩mp4| 欧美激情一区在线| 日本欧美肥老太交大片| 色婷婷av一区二区三区gif| 精品福利在线导航| 日韩精品一二三| 91麻豆国产福利在线观看| 久久夜色精品一区| 免费成人你懂的| 欧洲精品在线观看| 国产精品国产自产拍高清av王其 | 夜夜嗨av一区二区三区网页 | 日韩精品成人一区二区三区| k8久久久一区二区三区 | 日韩美女视频在线| 香港成人在线视频| 色94色欧美sute亚洲线路二| 国产日韩欧美激情| 国产精品白丝jk白祙喷水网站 | 不卡一区二区三区四区| 26uuu久久综合| 美女在线一区二区| 日韩欧美中文字幕一区| 日韩高清在线观看| 欧美一级艳片视频免费观看| 免费在线欧美视频| 91精品国产综合久久久久久久久久| 亚洲小说春色综合另类电影| 97se狠狠狠综合亚洲狠狠| 中文字幕中文字幕一区| 91丨九色丨尤物| 亚洲美女免费在线| 欧美午夜精品一区二区三区| 亚洲日本乱码在线观看| 一本大道综合伊人精品热热 | 国产99久久精品| 国产女人18水真多18精品一级做| 精品亚洲免费视频| 久久久美女艺术照精彩视频福利播放| 久久精品国产亚洲高清剧情介绍| 欧美一区二区二区| 国产原创一区二区三区| 国产精品久久久久影院亚瑟 | 色综合天天天天做夜夜夜夜做| 亚洲精品国产无天堂网2021| 91国产成人在线| 日日夜夜免费精品| 欧美本精品男人aⅴ天堂| 国产精品18久久久久久久久 | 国产日产欧美一区| 91天堂素人约啪| 日韩av高清在线观看| 精品国产乱子伦一区| 91丨九色porny丨蝌蚪| 日韩电影在线观看一区| 2022国产精品视频| 99久久国产综合精品女不卡| 亚洲成人动漫在线观看| 久久久久久久久久久久电影| 91麻豆蜜桃一区二区三区| 蜜臀av在线播放一区二区三区| 日韩一区二区电影在线| 不卡在线视频中文字幕| 男人操女人的视频在线观看欧美| 久久久久久久久一| 欧美三级在线播放| 激情国产一区二区| 亚洲成人自拍偷拍| 国产精品久久三| 日韩欧美国产三级电影视频| 91啪九色porn原创视频在线观看| 奇米888四色在线精品| 亚洲欧美日韩国产手机在线| 久久青草欧美一区二区三区| 欧美日韩性生活| 99re亚洲国产精品| 国产一区二区三区精品欧美日韩一区二区三区 | 日韩免费在线观看| 色噜噜狠狠成人网p站| 激情小说欧美图片| 亚洲成a人片在线不卡一二三区| 精品国产电影一区二区| 欧美午夜电影一区| 91欧美激情一区二区三区成人| 国产一区视频网站| 日本欧美在线观看| 五月婷婷综合网| 一区二区三区在线观看动漫| 中文成人综合网| 亚洲国产高清在线| 久久久精品影视| 久久综合久久综合九色| 欧美一区二区精品在线| 欧美人伦禁忌dvd放荡欲情| 色综合天天综合色综合av| 成人综合在线观看| 国产91丝袜在线观看| 国产精品一区免费视频| 激情成人综合网| 麻豆91免费观看| 麻豆91精品视频| 久久99国产精品免费| 麻豆传媒一区二区三区| 久久精品久久99精品久久| 免费av网站大全久久| 日韩av不卡一区二区| 免费成人美女在线观看| 精品一区二区在线视频| 国产呦萝稀缺另类资源| 国产资源在线一区| 粉嫩av一区二区三区在线播放| 国产一区999| 成人av在线影院| 99久久免费国产| 欧美视频一区二区三区在线观看 | 99久久伊人久久99| 91同城在线观看| 欧美午夜电影一区| 日韩视频一区二区在线观看| 日韩欧美亚洲国产另类| 久久综合精品国产一区二区三区| 久久蜜臀精品av| 综合久久综合久久| 视频一区在线播放| 美女一区二区三区在线观看| 久久99蜜桃精品| 高清成人在线观看| 在线亚洲高清视频| 欧美一级一级性生活免费录像| 精品国一区二区三区| 中文字幕中文在线不卡住| 亚洲电影一区二区| 国产老肥熟一区二区三区| 成人av免费网站| 欧美一区二区三区免费观看视频| 久久久噜噜噜久噜久久综合| 亚洲免费观看在线视频| 久久精品72免费观看| 99国产精品久| 欧美一区二区三区思思人| 中文字幕永久在线不卡| 三级成人在线视频| 国产精品小仙女| 欧美精选午夜久久久乱码6080| 国产嫩草影院久久久久| 亚洲18影院在线观看| 成人中文字幕电影| 欧美哺乳videos| 亚洲制服丝袜一区| 波多野结衣91| 精品国产一区二区三区不卡|