Basic PCI Express Read And Write

Hi

Can somebody point me to some sample to implement basic Read and write to a PCI express Device.

Some Link will b preferred. I saw someone saying in the list about “OSR PCI KMDF” driver
can someone send me the link for it

Hi.

Here is the discussion I’ve started some time ago about this.
Hope this can help.

http://social.msdn.microsoft.com/Forums/en-US/wdk/thread/d6ab9888-d874-4fae-8b3f-60ffb9da351b/

Thanks ad Regards
Rafael R. Machado

2012/6/13

> Hi
>
> Can somebody point me to some sample to implement basic Read and write to
> a PCI express Device.
>
> Some Link will b preferred. I saw someone saying in the list about “OSR
> PCI KMDF” driver
> can someone send me the link for it
>
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Thanks rafael but i am not looking for code to read the configuration space i want to send and receive data from the Device basically from the memory specified by the BAR addresses

On 14-Jun-2012 10:59, xxxxx@gmail.com wrote:

Thanks rafael but i am not looking for code to read the configuration space i want to send and receive data from the Device basically from the memory specified by the BAR addresses

Haven’t stumbled upon these WDK functions yet?
READ_REGISTER_xxx
WRITE_REGISTER_xxx

  • pa

xxxxx@gmail.com wrote:

Thanks rafael but i am not looking for code to read the configuration space i want to send and receive data from the Device basically from the memory specified by the BAR addresses

There’s not much to that. There are several samples that show how you
get the resources in your EvtPrepareHardware callback, and how to call
MmMapIoSpace to map the BARs to a kernel virtual address.

Once you do that, your BAR is just a chunk of memory. You can use
READ_REGISTER_ULONG and WRITE_REGISTER_ULONG to transfer data.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks to all I am using READ_REGISTER_BUFFER_UCHAR and WRITE_REGISTER_BUFFER_UCHAR for doing the transfer in my DeviceIocontrol callback function.

But i would like someones help to telll me whether i need allocate some memory within my driver i mean do i hav to map memory space to pass the data to the user application or passing the received pointers is enough

wrote in message news:xxxxx@ntdev…
> Thanks to all I am using READ_REGISTER_BUFFER_UCHAR and
> WRITE_REGISTER_BUFFER_UCHAR for doing the transfer in my DeviceIocontrol
> callback function.
>
> But i would like someones help to telll me whether i need allocate some
> memory within my driver i mean do i hav to map memory space to pass the
> data to the user application or passing the received pointers is enough
>

Sure, if you need to store some data you need to alocate some memory.
– pa

xxxxx@gmail.com wrote:

Thanks to all I am using READ_REGISTER_BUFFER_UCHAR and WRITE_REGISTER_BUFFER_UCHAR for doing the transfer in my DeviceIocontrol callback function.

If you are copying a big chunk of data, you will get better performance
with READ_REGISTER_BUFFER_ULONG. That does 4 bytes per cycle, as
opposed to 1 byte.

But i would like someones help to telll me whether i need allocate some memory within my driver i mean do i hav to map memory space to pass the data to the user application or passing the received pointers is enough

This depends on what you need to accomplish. Philosophically, your
driver is supposed to provide an abstraction of your device, so that
applications do not need to worry about the exact register layouts.
That way, you can change the hardware in the next generations and leave
the applications alone

So, YOU need to decide how applications will use your device. You could
create a set of ioctls that enumerate the list of interesting things
that an application might want to do, then have those ioctl handlers
access the appropriate registers. Or, you could have ioctls that do
“transfer block to device” and “transfer block from device”, where the
ioctl handlers basically do WRITE_REGISTER_BUFFER_ULONG and
READ_REGISTER_BUFFER_ULONG. That lets the driver do some validation of
the parameters first, making sure that the addresses are in the BAR
range and that the buffer size is reasonable.

It certainly possible for you to map the BAR region into user-mode
virtual space, and have an ioctl that returns a pointer to the
application, so it can do reads and writes as it wishes. That’s not
recommended, because there are several problems with that approach. (1)
User mode is not secure. It’s easy for an application to gain access to
another application’s address space. If a BAR is mapped, it’s just
normal memory, so another application could write random stuff to your
hardware. If that could cause damage, then you don’t want that. (2)
There is no synchronization. You can’t prevent multiple applications
from accessing the BAR at the same time. With a driver, everything
funnels through you – you can serialize things. (3) There are no
memory barriers. User-mode apps cannot call the READ_REGISTER /
WRITE_REGISTER routines – they will just use the BAR like memory. In
most systems, that’s OK, but there are architectures where an extra step
needs to be taken when you access device memory. The READ/WRITE
routines do that.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.