lor*_*zli 7 c linux kernel linux-device-driver linux-kernel
我写了一个简单的char驱动程序,现在想要使用类在udev中自动注册它.我的代码由以下部分组成init,当驱动程序被加载并调用函数probe时加载驱动程序的设备(当然,他们的反等价调用的函数exit和remove).问题:添加新设备后,我的probe功能在执行device_create命令时失败.现在我想知道为什么:
我怎样才能获得有关此命令失败原因的更多信息(除此之外失败)?任何缺失的参数(比如我的全局声明是否存在问题,我fooClass应该将它移动到probe函数中,这在我眼中并没有显示出来,但是在很多例子中都有显示)?或任何其他监督错误?
根据我的代码,我删除了大多数返回验证(如IS_ERR())和清理函数以便于阅读.这两个变量是全局定义的:
static int foo_majNbr;
static struct class *fooClass;
Run Code Online (Sandbox Code Playgroud)
init 功能:
static int __init foo_init(void)
{
int rv;
dev_t devNbr;
/* Registering driver */
rv = pci_register_driver(&foo_driver);
/* ----> see answer below for correct order <---- */
/* Create device class */
fooClass = class_create(THIS_MODULE, CLASS_NAME);
/* Allocate device number, just one device for the moment */
rv = alloc_chrdev_region(&devNbr, 0, 1, DEVICE_NAME);
foo_majNbr = MAJOR(devNbr);
...
}
Run Code Online (Sandbox Code Playgroud)
和probe功能:
static int __devinit foo_probe(struct pci_dev *dev,
const struct pci_device_id *devId)
{
struct foo_dev *foo_dev = 0;
int rv = 0;
/* Allocate memory in Kernel (for parameters) */
foo_dev = kzalloc(sizeof(*foo_dev), GFP_KERNEL);
foo_dev->pci_dev = dev;
pci_set_drvdata(dev, foo_dev);
foo_dev->devNbr = MKDEV(foo_majNbr, 1);
/* Add class to device */
foo_dev->dev = device_create(fooClass, NULL, foo_dev->devNbr,
foo_dev, DEVICE_NAME);
if (IS_ERR(foo_dev->dev)) {
/* ----> INDICATES FAILURE HERE <---- */
}
/* Add char device */
cdev_init(&foo_dev->cdev, &foo_fops);
rv = cdev_add(&foo_dev->cdev, foo_dev->devNbr, 1);
/* Enabling device */
rv = pci_enable_device(dev);
...
}
Run Code Online (Sandbox Code Playgroud)
您应该至少打印错误号以了解原因.
pr_err("%s:%d error code %d\n", __func__, __LINE__, PTR_ERR(foo_dev->dev));
Run Code Online (Sandbox Code Playgroud)
NULL在文件Linux/include/uapi/asm-generic/errno-base.h中,您可以找到最常见的错误.如果此错误代码对您没有帮助,您可以转到device_create()的源代码,找出生成错误的位置并了解原因.
也许device_create()在打电话之前打印参数.
我知道,这不是那种神奇地解决你问题的答案:)但它是一种继续并找出原因的方法.