简体   繁体   English

如何从驱动程序的 ioctl() 中的文件 object 获取 pci_dev?

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

I'm working on a linux driver for a PCIE hardware.我正在为PCIE硬件开发 linux 驱动程序。 The kernel is v4.13 . kernel 是v4.13 For each device object, there is a bunch of data stored with pci_set_drvdata(struct pci_dev *pdev, void *data) .对于每个设备 object,有一堆数据存储在pci_set_drvdata(struct pci_dev *pdev, void *data)中。

In IOCtl() service routine, how can I get the data back using struct file * pFile ?IOCtl()服务例程中,如何使用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()驱动程序将获取命令并处理这些命令

 ioctl(fd, cmd , INPARAM or OUTPARAM);

how can I get the data back using struct file * pFile ?如何使用 struct file * pFile 取回数据? what operation you want to perform ?你想执行什么操作? you can use commands which are available in ioctl.h for this. ioctl.h ,您可以使用ioctl.h中提供的命令。 for eg IOR (If the command needs to read some thing from the kernel space)例如IOR (如果命令需要从内核空间读取一些东西)

If you have more then one device you are likely using an IDR to allocate and track minor dev node IDs.如果您有不止一个设备,您可能会使用 IDR 来分配和跟踪次要开发节点 ID。 The call to idr_alloc accepts a pointer to store with the ID for future use.idr_alloc的调用接受一个与 ID 一起存储以备将来使用的指针。

In your ioctl handler you can then lookup the pointer from the idr using idr_find .在您的 ioctl 处理程序中,您可以使用idr_find从 idr 中查找指针。 For example:例如:

Allocate an IDR and store info with it分配一个 IDR 并用它存储info

Global defines全局定义

DEFINE_MUTEX(minor_lock);
DEFINE_IDR(mydev_idr);

In your PCI probe handler在您的 PCI 探针处理程序中

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从 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确保在移除设备时释放您的 IDR

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: struct file也有private_data ,所以你可以在那里存储pci_dev ,就像struct miscdev所做的那样:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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