General:
I am developing a PCIE(PCI Express) linux device driver with the open()/close()/read()/write()
methods being implemented and the probe()
function for the PCIE
part.
Current situation:
Within the probe()
function I have access to the dev
pointer driver_pcie_probe(struct pci_dev *dev, const struct pci_device_id *id)
and through it I can do stuff like:
int my_pcie_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int err = 0;
int *bar0 = NULL;
int x = 0;
int i = 0;
// Before any device resources can be accessed, the device needs to be enabled.
err = pci_enable_device(dev);
if(err < 0) {
printk(KERN_ALERT "Unable to enable PCIe device!\n");
return err;
}
// Request all BARs to this device.
err = pci_request_regions(dev, MY_DRIVER_NAME);
if(err) {
printk(KERN_ALERT "Unable to request memory regions (BARs) from PCIe device!\n");
return err;
}
// !!! TESTING !!!
bar0 = pci_iomap(dev, 0, 0);
for(i = 0; i < 16; i++) {
x = ioread32(bar0 + i);
printk(KERN_ALERT "cycle: %d bar0: 0x%p, x = 0x%016x\n", i, bar0, x);
}
for(i = 0; i < 16; i++) {
iowrite32(i, bar0 + i);
}
// !!! TESTING !!!
return err;
}
within the probe() function which works perfect.
What I want to do:
...is transfer the iowrite/ioreads
into the character devices read/write
methods.
ssize_t char_device_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
ssize_t ret = 0;
struct my_device *my_dev;
int device_buf[16];
int i = 0;
my_dev = filp->private_data;
if (down_interruptible(&my_dev->sem)) {
return -ERESTARTSYS;
}
for(i = 0; i < 16; i++) {
device_buf[i] = ioread32(my_dev->BAR0 + i);
}
if (copy_to_user(buf, device_buf, count)) {
return -EFAULT;
}
*f_pos += count;
ret = count;
up(&my_dev->sem);
return ret;
}
Problem:
I need access to the pci_dev struct *dev
within the character devices read/write
method in order to do an ioread/iowrite
.
What I know:
There is filp->private_data
within the read/write
methods of the character device, so I thought about having my_own_device_struct
which I set the filp->private_data
to. This way it's available within open/close/read/write
of the character device.
What I thoughts works, but I can't figure out how:
I thought I can set the filp->private_data->
... within the probe()
function of the PCIE driver. This way the *dev
(or at least the a bar0
which is a member of my_own_device_struct
is available for the open/close/read/write
methods of the character device, but unfortunately this doesn't work and dev_set_drvdata()
doesn't seem to do the job either.
Anyone can help me on this?
The only way I found so far is using a struct my_own_device
with a struct pci_dev
as member being initialized during the probe()
function. It's just a static variable within my device driver module accessible from every function.
Since I have only one PCIe device that I am communicating with this might just be sufficient.