Ich schrieb einen einfachen Char-Treiber und möchte es jetzt automatisch in udev mit Klassen registrieren. Mein Code besteht aus der init
-Funktion, die aufgerufen wird, wenn der Treiber geladen wird, und der probe
-Funktion, die aufgerufen wird, wenn der Treiber seine Geräte lädt (und natürlich ihre Gegenäquivalente und remove
). Das Problem: Sobald ein neues Gerät hinzugefügt wird, schlägt die probe
-Funktion beim Ausführen des Befehls device_create
fehl. Jetzt frage ich mich warum:Debugging eines einfachen Char-Treibers in Linux fehlgeschlagen auf device_create()
Wie kann ich möglicherweise mehr Informationen darüber erhalten, warum dieser Befehl fehlschlägt (abgesehen davon, dass es fehlschlägt)? Irgendein Argument fehlt (wie gibt es ein Problem mit meiner globalen Deklaration fooClass
, sollte ich es stattdessen zu der probe
Funktion verschieben, die in meinen Augen nicht Sinn macht, aber in vielen Beispielen gezeigt wird)? Oder irgendein anderer übersehener Fehler?
Nach meinem Code, von dem ich die meisten Rückverifizierung entfernt (wie IS_ERR()
) und bereinigen Funktionen für die Lesbarkeit. Diese beiden Variablen sind global definiert:
static int foo_majNbr;
static struct class *fooClass;
init
Funktion:
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);
...
}
und die probe
Funktion:
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);
...
}
Vielen Dank, genau, was ich suchte und es half das Problem zu finden :) - Ich habe die Lösung in einer getrennten Antwort unten veröffentlicht. – lorenzli