I wrote a simple char driver and would now like to register it automatically in udev using classes. My code consists of the init
function called when the driver is loaded and probe
function called when the driver is loading its devices (and of course their counter-equivalent exit
and remove
). The problem: Once a new device is added my probe
function fails when executing the device_create
command.
Now I am wondering why:
How can I possibly get more information about why this command fails (besides that it fails)? Any argument missing (like is there a problem with my global declaration of fooClass
, should I move it to the probe
function instead, which does not make sens in my eyes but is shown in many examples)? Or any other overseen error?
Following my code of which I stripped most return verification (like IS_ERR()
) and clean up functions for readability. This two variables are defined globally:
static int foo_majNbr;
static struct class *fooClass;
init
function:
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);
...
}
and the probe
function:
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);
...
}
You should print the error number at least to know the reason.
pr_err("%s:%d error code %d\n", __func__, __LINE__, PTR_ERR(foo_dev->dev));
NULL
in the file Linux/include/uapi/asm-generic/errno-base.h you can find the most common errors. If this error code doesn't help you, you can go to the source code of device_create() an find out where your kind of error is generated and understand why.
Maybe print also the arguments of device_create()
before call it.
I know, this is not the kind of answer that magically solve you problem :) but it is a way to proceed and find out the reason.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With