emailoftest
驱动牛犊
驱动牛犊
  • 注册日期2002-03-18
  • 最后登录2002-06-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2315回复:3

读写PCI配置寄存器问题

楼主#
更多 发布于:2002-04-24 10:32
请问,如何在DriverStudio开发的pci驱动中读写PCI配置寄存器

最新喜欢:

crashedcarcrashe...
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-04-24 10:44
读写寄存器不就是读写io端口吗,给个基址和偏移地址就可以了
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
OS_Dev
驱动中牛
驱动中牛
  • 注册日期2002-01-09
  • 最后登录2004-03-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-04-24 12:35
nt 下可以使用 HalSetBusData HalGetBusData

2k xp据说需要和内核同步,才能读写,但是都不推荐使用这两个函数,你可以看看linux代码,其中这样的函数
I know nothing!
vcmfc
驱动中牛
驱动中牛
  • 注册日期2001-03-23
  • 最后登录2008-01-28
  • 粉丝0
  • 关注0
  • 积分528分
  • 威望53点
  • 贡献值0点
  • 好评度52点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-04-25 18:14
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;
}
Because you can only send the PnP I/O Request Packets (IRPs) at PASSIVE_LEVEL,
you cannot use the above function to get the configuration information at
DISPATCH_LEVEL.
You can perform the following steps to access the configuration space at
DISPATCH_LEVEL:
Send an IRP_MN_QUERY_INTERFACE at PASSIVE_LEVEL to get the direct-call
interface structure (BUS_INTERFACE_STANDARD) from the PCI bus driver. Store
this in a nonpaged pool memory (typically in DevcieExtension).
Call the SetBusData and GetBusData to access the configuration space at
DISPATCH_LEVEL.
The PCI bus driver takes a reference count on the interface before it returns,
so you must dereference the interface when it is no longer needed.
Use the following function to get the BUS_INTERFACE_STANDARD at PASSIVE_LEVEL:
NTSTATUS
GetPCIBusInterfaceStandard(
IN PDEVICE_OBJECT DeviceObject,
OUT PBUS_INTERFACE_STANDARD BusInterfaceStandard
)
/*++
Routine Description:
This routine gets the bus interface standard information from the PDO.
Arguments:
DeviceObject - Device object to query for this information.
BusInterface - Supplies a pointer to the retrieved information.
Return Value:
NT status.
--*/
{
KEVENT event;
NTSTATUS status;
PIRP irp;
IO_STATUS_BLOCK ioStatusBlock;
PIO_STACK_LOCATION irpStack;
PDEVICE_OBJECT targetObject;
Bus_KdPrint((\"GetPciBusInterfaceStandard entered.\\n\"));
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 );
irpStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
irpStack->Parameters.QueryInterface.InterfaceType =
(LPGUID) &GUID_BUS_INTERFACE_STANDARD ;
irpStack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
irpStack->Parameters.QueryInterface.Version = 1;
irpStack->Parameters.QueryInterface.Interface = (PINTERFACE)
BusInterfaceStandard;
irpStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
//
// 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;
}
The following code shows how you can use the interface direct-call function to
get the bus data.
bytes = busInterfaceStandard.GetBusData(<BR/>
busInterfaceStandard.Context,
PCI_WHICHSPACE_CONFIG,
Buffer
Offset,
Length);
When you no longer need the interface, use the following code to dereference
the interface with the code to follow. Do not call any interface routines
after you dereference the interface.
(busInterfaceStandard.InterfaceDereference)(
(PVOID)busInterfaceStandard.Context);
Use the IoGetDeviceProperty function on the PDO of the target device to get
the Bus, Function, and Device numbers as follows:
ULONG propertyAddress, length;
USHORT FunctionNumber; DeviceNumber;
//
// Get the BusNumber. Please read the warning to follow.
//
IoGetDeviceProperty(PhysicalDeviceObject,
DevicePropertyBusNumber,
sizeof(ULONG),
(PVOID)&BusNumber,
&length);
//
// Get the DevicePropertyAddress
//
IoGetDeviceProperty(PhysicalDeviceObject,
DevicePropertyAddress,
sizeof(ULONG),
(PVOID)&propertyAddress,
&length);
//
// For PCI, the DevicePropertyAddress has device number
// in the high word and the function number in the low word.
//
FunctionNumber = (USHORT)((propertyAddress) & 0x0000FFFF);
DeviceNumber = (USHORT)(((propertyAddress) >> 16) & 0x0000FFFF);
Important: PCI Bus numbers may be dynamic and can change at any moment.
Therefore, it is not good to depend on the bus number or use that information
to access the PCI ports directly. This may lead to system failure.
游客

返回顶部