简体   繁体   中英

how to get pci_dev from file object in a driver's ioctl()?

I'm working on a linux driver for a PCIE hardware. The kernel is v4.13 . For each device object, there is a bunch of data stored with pci_set_drvdata(struct pci_dev *pdev, void *data) .

In IOCtl() service routine, how can I get the data back using struct file * pFile ?

long IOCtlService(struct file * pFile, unsigned int cmd, unsigned long arg)

thanks

Using ioctl() driver will take command & work on those commands as

 ioctl(fd, cmd , INPARAM or OUTPARAM);

how can I get the data back using struct file * pFile ? what operation you want to perform ? you can use commands which are available in ioctl.h for this. for eg IOR (If the command needs to read some thing from the kernel space)

If you have more then one device you are likely using an IDR to allocate and track minor dev node IDs. The call to idr_alloc accepts a pointer to store with the ID for future use.

In your ioctl handler you can then lookup the pointer from the idr using idr_find . For example:

Allocate an IDR and store info with it

Global defines

DEFINE_MUTEX(minor_lock);
DEFINE_IDR(mydev_idr);

In your PCI probe handler

struct my_dev * info;

info = kzalloc(sizeof(struct mydev_info), GFP_KERNEL);
if (!info)
  return -ENOMEM;

mutex_lock(&minor_lock);
info->minor = idr_alloc(&mydev_idr, info, 0, MYDEV_MAX_DEVICES, GFP_KERNEL);
if (info->minor < 0)
{
  mutex_unlock(&minor_lock);
  goto out_unreg;
}
mutex_unlock(&minor_lock);

pci_set_drvdata(dev, info);

Lookup the stored pointer from the IDR

unsigned minor = iminor(flip->f_inode);
struct my_dev * dev = (struct my_dev *)idr_find(&my_idr, minor);
if (!dev)
  return -EINVAL;

Make sure to free your IDRs on device removal

mutex_lock(&minor_lock);
idr_remove(&mydev_idr, info->minor);
mutex_unlock(&minor_lock);

struct file also have private_data , so you can store pci_dev there, just like what struct miscdev does:

static int misc_open(struct inode *inode, struct file *file)
{
    ......
    struct miscdevice *c;

    ......

    /*
     * Place the miscdevice in the file's
     * private_data so it can be used by the
     * file operations, including f_op->open below
     */
    file->private_data = c;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM