Re: PCI Driver - Read/Write to Base Address



Never mind, I was able to take ownership of the region. I just needed
to add pci_release_regions(dev) in the remove function.

Still awaiting a response to this question:
In addition, I eventually want to take the reading configuration
register, reading PCI memory, and writing PCI memory code out of the
probe function and set each one as a function. After the device driver
is loaded, how do I call those functions from another C program?

elliotng.ee@xxxxxxxxx wrote:
Thanks for your help.

Unfortunately, I get this message in the kernel log:
PCI: Unable to reserve mem region #2:4000@de000000

Is there a way to get around this error? Is it because of the
pci_request_region function?

In addition, I eventually want to take the reading configuration
register, reading PCI memory, and writing PCI memory code out of the
probe function and set each one as a function. After the device driver
is loaded, how do I call those functions from another C program?

gil_hamilton@xxxxxxxxxxx wrote:
elliotng.ee@xxxxxxxxx wrote:
I am trying to read and write to a PCI Base Address. Right now, I have:

static int rpm_probe(struct pci_dev *dev, const struct pci_device_id
*id)
{
pci_enable_device(dev);

u32 BaseAddress0;
pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &BaseAddress0);
printk(KERN_ALERT "PCI_BASE_ADDRESS_0: %x\n", BaseAddress0);
}


To read/write to that particular base address, do we just need to add
the following lines:
u32 BaseAddress0data;
pci_read_config_dword(dev, BaseAddress0, &BaseAddress0data);
pci_write_config_dword(dev, BaseAddress0, 0xFF000000);

or is there another pci function that I should use?

No, that's not correct, if I understand what you're doing.

First, you should get the base address value (for memory-mapped I/O
region 0) with:
int BarNumber = 0;
pci_request_region(dev, BarNumber, "MyDriverName");
BaseAddress0 = pci_resource_start(dev, BarNumber);
BarLen = pci_resource_len(dev, BarNumber);

This marks you as the owner of the region and returns to you its base
(physical) address and length.

Second, when you actually read or write the memory-mapped I/O in your
device, you don't use pci_read_config* / pci_write_config* -- those are
only used when you are reading / writing the device's *configuration
space registers*. Reading the memory-mapped I/O region is done
something like this:

char * Region0 = ioremap_nocache(BaseAddress0, BarLen);
Data = readl(Region0 + offsetToRead);
writel(DataToWrite, Region0 + offsetToRead);

ioremap_nocache creates a virtual-to-physical mapping in kernel address
space that you can use to access the device memory.

readl() and writel() are arch-specific macros that typically boil down
to something like this (however, you should still use them since there
may be slight variations between architectures):
unsigned long readl(void * addr) { return *((volatile unsigned long
*)addr)); }
void writel(unsigned long value, void * addr) { *((volatile unsigned
long *)addr) = value; }

You might want to check out the book "Linux Device Drivers, version 3"
which is available for free online. It has a chapter on PCI Drivers as
well as info on kernel memory management.

Also, check out the skeleton network driver in
/usr/src/linux/drivers/net/pci-skeleton.c for some sample code.

GH

.



Relevant Pages

  • Re: Unknown Process reading application memory
    ... I'm thinking it may be some other device driver on the system as only ... it would have access to the physical memory on the card itself. ... The card itself has been instrumented with logging and I have proven ... that the card is not reading that memory address itself. ...
    (microsoft.public.win32.programmer.kernel)
  • Re: Please help!
    ... This bug check is issued if paged memory is accessed ... installation of a faulty device driver, system service, or BIOS. ...
    (microsoft.public.windowsxp.help_and_support)
  • Re: DosAllocMem and OBJ_ANY
    ... OS/2 moved from 16-bit display driver DLLs to 32-bit display driver DLLs. ... Memory that is allocated in the GDT (and therefore accessible to any process calling into the device driver) will always be in the high memory region by nature. ...
    (comp.os.os2.programmer.misc)
  • Re: DosAllocMem and OBJ_ANY
    ... Memory that is allocated in the GDT (and therefore accessible to any process ... calling into the device driver) will always be in the high memory region by ... example might be that a display driver DLL might use the SCREEN IOCTLs ...
    (comp.os.os2.programmer.misc)
  • Re: Programming in standard c
    ... I consider having the text file size used for reading the file into ... memory to be used insufficiently often to make it worth caching it. ... size may suck significantly more than getting the binary-mode size ... NOT precalculate the size) and reallocing when needed ...
    (comp.lang.c)