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

📄 amcc_orig.cpp

📁 The PCI Local bus concept was developed to break the PC data I/O bottleneck and clearly opens the d
💻 CPP
📖 第 1 页 / 共 4 页
字号:
Return Value:

    STATUS_SUCCESS if successful
	NT status code

*/
NTSTATUS SheldonUnMapDirect(PDEVICE_EXTENSION pdx)
{
	NTSTATUS ntStatus = STATUS_SUCCESS;
	int i;

	KdPrint(("SIWDM - Entering SheldonUnMapDirect\n"));

	for(i=0;i<PCI_TYPE0_ADDRESSES;i++)
	{
		if(pdx->Direct_Baddr[i] != NULL)
		{
			__try
			{
				MmUnmapLockedPages((PVOID) pdx->Direct_Baddr[i], pdx->Mdl[i]);
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				ntStatus = GetExceptionCode();
				KdPrint(("SIWDM - SheldonUnMapDirect:  Fail to Unmap Mdl[%x]\n", i));
				KdPrint(("SIWDM - SheldonUnMapDirect:  Error Code %x\n", ntStatus));
			}

			pdx->Direct_Baddr[i] = NULL;
		}

		if(pdx->Mdl[i] != NULL)
		{
			__try
			{
				IoFreeMdl(pdx->Mdl[i]);
			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				ntStatus = GetExceptionCode();
				KdPrint(("SIWDM - SheldonUnMapDirect:  Fail to Free Mdl[%x]\n", i));
				KdPrint(("SIWDM - SheldonUnMapDirect:  Error Code %x\n", ntStatus));
			}

			pdx->Mdl[i] = NULL;
		}
	}

	KdPrint(("SIWDM - Exiting SheldonUnMapDirect\n"));

    return ntStatus;
}

/*

Function Name:

	SheldonConfigRead

Routine Description:

    Enables the user application to read the PCI configuration space for the device.
	This function creates an IRP which is passed down to the PCI bus driver, which handles
	the request.

Arguments:

	fdo - pointer to the function device object

	Irp - I/O request being serviced

	pdx - pointer to the device extension.

Return Value:

    STATUS_SUCCESS if successful
	NT status code

*/
NTSTATUS SheldonConfigRead(IN PDEVICE_OBJECT fdo, PIRP Irp, PDEVICE_EXTENSION pdx)
{
	PULONG params;
	NTSTATUS ntStatus;
	PIO_STACK_LOCATION ConfigIrpStack;
	PIRP ConfigIrp;
	KEVENT ConfigEvent;
	ULONG byteCount;

	// read the configuration space of the device
	params = (PULONG) Irp->AssociatedIrp.SystemBuffer;

	byteCount = params[SI_CONFIG_COUNT_INDEX];

	// write number of bytes coming back, before this param is overwritten
	Irp->IoStatus.Information = byteCount;

	ConfigIrp = IoAllocateIrp(fdo->StackSize, FALSE);
	
	if(ConfigIrp == NULL)
		return STATUS_INSUFFICIENT_RESOURCES;

	KeInitializeEvent(&ConfigEvent, NotificationEvent, FALSE);

	IoSetCompletionRoutine
	(
		ConfigIrp, 
		(PIO_COMPLETION_ROUTINE) OnRequestComplete, 
		&ConfigEvent, 
		TRUE, TRUE, TRUE
	);

	ConfigIrpStack = IoGetNextIrpStackLocation(ConfigIrp);

	if(ConfigIrpStack == NULL)
		return STATUS_INSUFFICIENT_RESOURCES;

	ConfigIrpStack -> MajorFunction = IRP_MJ_PNP;
	ConfigIrpStack -> MinorFunction = IRP_MN_READ_CONFIG;
	ConfigIrpStack -> Parameters.ReadWriteConfig.Buffer = (PVOID) &(params[SI_CONFIG_READ_DATA_INDEX]);
	ConfigIrpStack -> Parameters.ReadWriteConfig.Offset = params[SI_CONFIG_OFFSET_INDEX];
	ConfigIrpStack -> Parameters.ReadWriteConfig.Length = byteCount;

	ntStatus = IoCallDriver(fdo, ConfigIrp);

	if(ntStatus == STATUS_PENDING)
	{
		KeWaitForSingleObject(&ConfigEvent, Executive, KernelMode, FALSE, NULL);
		ntStatus = ConfigIrp->IoStatus.Status;
	}

	IoFreeIrp(ConfigIrp);

	return ntStatus;
}

/*

Function Name:

	SheldonConfigWrite

Routine Description:

    Enables the user application to write the PCI configuration space for the device.
	This function creates an IRP which is passed down to the PCI bus driver, which handles
	the request.  This function has not been tested.

Arguments:

	fdo - pointer to the function device object

	Irp - I/O request being serviced

	pdx - pointer to the device extension.

Return Value:

    STATUS_SUCCESS if successful
	NT status code

*/
#define JUST_TESTING
//#define ORIGINAL_CODE
NTSTATUS SheldonConfigWrite(IN PDEVICE_OBJECT fdo, PIRP Irp, PDEVICE_EXTENSION pdx)
{
#ifdef JUST_TESTING
	PULONG params;
    KEVENT event;
    NTSTATUS status;
    PIRP irp2;
    IO_STATUS_BLOCK ioStatusBlock;
    PIO_STACK_LOCATION irpStack;
    PDEVICE_OBJECT targetObject;

    PAGED_CODE();

	// read the configuration space of the device
	params = (PULONG) Irp->AssociatedIrp.SystemBuffer;

    KeInitializeEvent( &event, NotificationEvent, FALSE );

    targetObject = IoGetAttachedDeviceReference( fdo );

    irp2 = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
                                        targetObject,
                                        NULL,
                                        0,
                                        NULL,
                                        &event,
                                        &ioStatusBlock );

    if (irp2 == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto End;
    }

    irpStack = IoGetNextIrpStackLocation( irp2 );

    irpStack->MinorFunction = IRP_MN_WRITE_CONFIG;

    irpStack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
    irpStack->Parameters.ReadWriteConfig.Buffer = (PVOID) &(params[SI_CONFIG_WRITE_DATA_INDEX]);
    irpStack->Parameters.ReadWriteConfig.Offset = params[SI_CONFIG_OFFSET_INDEX];
    irpStack->Parameters.ReadWriteConfig.Length = params[SI_CONFIG_COUNT_INDEX];

    // 
    // Initialize the status to error in case the bus driver does not 
    // set it correctly.
    // 

    irp2->IoStatus.Status = STATUS_NOT_SUPPORTED ;

    status = IoCallDriver( targetObject, irp2 );

    if (status == STATUS_PENDING) {

        KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
        status = ioStatusBlock.Status;
    }

End:
    // 
    // Done with reference
    // 
    ObDereferenceObject( targetObject );

    return status;
#endif

#ifdef ORIGINAL_CODE
// origonal code
	PULONG params;
	NTSTATUS ntStatus;
	PIO_STACK_LOCATION ConfigIrpStack;
	PIRP ConfigIrp;
	KEVENT ConfigEvent;

	// read the configuration space of the device
	params = (PULONG) Irp->AssociatedIrp.SystemBuffer;

	ConfigIrp = IoAllocateIrp(fdo->StackSize, FALSE);
	
	if(ConfigIrp == NULL)
		return STATUS_INSUFFICIENT_RESOURCES;

	KeInitializeEvent(&ConfigEvent, NotificationEvent, FALSE);
	IoSetCompletionRoutine(ConfigIrp, (PIO_COMPLETION_ROUTINE) OnRequestComplete, &ConfigEvent, TRUE, TRUE, TRUE);
	ConfigIrpStack = IoGetNextIrpStackLocation(ConfigIrp);

	if(ConfigIrpStack == NULL)
		return STATUS_INSUFFICIENT_RESOURCES;

	ConfigIrpStack -> MajorFunction = IRP_MJ_PNP;
	ConfigIrpStack -> MinorFunction = IRP_MN_WRITE_CONFIG;
	ConfigIrpStack -> Parameters.ReadWriteConfig.Buffer = (PVOID) &(params[SI_CONFIG_WRITE_DATA_INDEX]);
	ConfigIrpStack -> Parameters.ReadWriteConfig.Offset = params[SI_CONFIG_OFFSET_INDEX];
	ConfigIrpStack -> Parameters.ReadWriteConfig.Length = params[SI_CONFIG_COUNT_INDEX];

	ntStatus = IoCallDriver(fdo, ConfigIrp);

	if(ntStatus == STATUS_PENDING)
	{
		KeWaitForSingleObject(&ConfigEvent, Executive, KernelMode, FALSE, NULL);
		ntStatus = ConfigIrp->IoStatus.Status;
	}

	IoFreeIrp(ConfigIrp);

	return ntStatus;
#endif


}


#ifdef XXXXXXXX
// From mocrosoft.com
NTSTATUS
ReadWriteConfigSpace(
    IN PDEVICE_OBJECT DeviceObject,
    IN ULONG	      ReadOrWrite, // 0 for read 1 for write
    IN PVOID	      Buffer,
    IN ULONG	      Offset,
    IN ULONG	      Length
    )
{
    KEVENT event;
    NTSTATUS status;
    PIRP irp;
    IO_STATUS_BLOCK ioStatusBlock;
    PIO_STACK_LOCATION irpStack;
    PDEVICE_OBJECT targetObject;

    PAGED_CODE();

    KeInitializeEvent( &event, NotificationEvent, FALSE );

    targetObject = IoGetAttachedDeviceReference( DeviceObject );

    irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
                                        targetObject,
                                        NULL,
                                        0,
                                        NULL,
                                        &event,
                                        &ioStatusBlock );

    if (irp == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto End;
    }

    irpStack = IoGetNextIrpStackLocation( irp );

    if (ReadOrWrite == 0) {
        irpStack->MinorFunction = IRP_MN_READ_CONFIG;
    }else {
        irpStack->MinorFunction = IRP_MN_WRITE_CONFIG;
    }

    irpStack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
    irpStack->Parameters.ReadWriteConfig.Buffer = Buffer;
    irpStack->Parameters.ReadWriteConfig.Offset = Offset;
    irpStack->Parameters.ReadWriteConfig.Length = Length;

    // 
    // Initialize the status to error in case the bus driver does not 
    // set it correctly.
    // 

    irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;

    status = IoCallDriver( targetObject, irp );

    if (status == STATUS_PENDING) {

        KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
        status = ioStatusBlock.Status;
    }

End:
    // 
    // Done with reference
    // 
    ObDereferenceObject( targetObject );

    return status;

}
				
#endif

//=================================================================
//	Following two calls are used by Sheldon Instruments hardware. 
//	They can be safely ignored or removed from the driver if non-SI 
//	hardware is used.
//=================================================================

#define SI_ROBS_REGS						1
#define SI_DUAL_ACCESS_READ_ADDRESS_OFFSET	0
#define SI_DUAL_ACCESS_WRITE_ADDRESS_OFFSET	1
#define SI_DUAL_ACCESS_DATA_OFFSET			2

NTSTATUS
SheldonDualAccessRead(PIRP Irp, PDEVICE_EXTENSION pDeviceExt)
{
	PULONG		Buffer;
	ULONG		dsp_address;
	ULONG		i;
	ULONG		count;

	// get a ULONG pointer to the buffer
	Buffer = (ULONG *)MmGetSystemAddressForMdl(Irp->MdlAddress);
	count= MmGetMdlByteCount(Irp->MdlAddress)/sizeof(ULONG);

	// get the dsp_address	
	dsp_address=*(PULONG)Irp->AssociatedIrp.SystemBuffer;	

	for (i=0;i<count;i++)
	{			
		WRITE_REGISTER_ULONG
		(
			pDeviceExt->base[SI_ROBS_REGS]
				+SI_DUAL_ACCESS_READ_ADDRESS_OFFSET, 
			dsp_address++
		);
		*Buffer++ =
			READ_REGISTER_ULONG
			(
				pDeviceExt->base[SI_ROBS_REGS] 
					+ SI_DUAL_ACCESS_DATA_OFFSET
			);
	}

	Irp->IoStatus.Information=sizeof(ULONG)*count;

	return STATUS_SUCCESS;			
}

//===========================================================

NTSTATUS
SheldonDualAccessWrite(PIRP Irp, PDEVICE_EXTENSION pDeviceExt)
{
	PULONG		Buffer;
	ULONG		dsp_address;
	ULONG		i;
	ULONG		count;

	// get a ULONG pointer to the buffer
	Buffer = (ULONG *)MmGetSystemAddressForMdl(Irp->MdlAddress);
	count= MmGetMdlByteCount(Irp->MdlAddress)/sizeof(ULONG);

	// get the dsp_address	
	dsp_address=*(PULONG)Irp->AssociatedIrp.SystemBuffer;	

	for (i=0;i<count;i++)
	{			
		WRITE_REGISTER_ULONG
		(
			pDeviceExt->base[SI_ROBS_REGS]
				+SI_DUAL_ACCESS_WRITE_ADDRESS_OFFSET, 
			dsp_address++
		);
		WRITE_REGISTER_ULONG
		(
			pDeviceExt->base[SI_ROBS_REGS]
				+SI_DUAL_ACCESS_DATA_OFFSET, 
			*Buffer++
		);
	}

	Irp->IoStatus.Information=0;
	return STATUS_SUCCESS;
}

⌨️ 快捷键说明

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