2017-02-14 2 views
0

J'ai le chardev suivant défini:Mise ENOTTY sur ioctl pour un module du noyau Linux

.h

#define MAJOR_NUM 245 
#define MINOR_NUM 0 
#define IOCTL_MY_DEV1 _IOW(MAJOR_NUM, 0, unsigned long) 
#define IOCTL_MY_DEV2 _IOW(MAJOR_NUM, 1, unsigned long) 
#define IOCTL_MY_DEV3 _IOW(MAJOR_NUM, 2, unsigned long) 
Module

.c

static long device_ioctl(
        struct file* file, 
        unsigned int ioctl_num, 
        unsigned long ioctl_param) 
{ 
    ... 
} 

static int device_open(struct inode* inode, struct file* file) 
{ 
    ... 
} 

static int device_release(struct inode* inode, struct file* file) 
{ 
    ... 
} 

struct file_operations Fops = { 
    .open=device_open, 
    .unlocked_ioctl= device_ioctl, 
    .release=device_release 
}; 

static int __init my_dev_init(void) 
{ 
    register_chrdev(MAJOR_NUM, "MY_DEV", &Fops); 
    ... 
} 
module_init(my_dev_init); 

Mon code utilisateur

ioctl(fd, IOCTL_MY_DEV1, 1); 

Échoue toujours avec la même erreur: ENOTTY

Inappropriate ioctl for device

J'ai vu des questions similaires: -à-dire

Linux kernel module - IOCTL usage returns ENOTTY

Linux Kernel Module/IOCTL: inappropriate ioctl for device

Mais leurs solutions ne fonctionnent pas pour moi

+0

Avez-vous vérifié si votre 'device_ioctl()' est appelé? (mettre un appel printk dedans) – nos

+0

@nos mon 'device_ioctl()' n'est pas appelé, mettre un corps vide avec seulement 'printk' – Mugen

+0

Vous n'avez pas bien enregistré la version de votre appel ioctl ... essayez le verrouillé. –

Répondre

1

ENOTTY est émis par le noyau lorsque votre pilote de périphérique n'a pas enregistré une fonction ioctl à appeler . Je crains que votre fonction ne soit pas bien enregistrée, probablement parce que vous l'avez enregistrée dans le champ .unlocked_ioctl de la structure struct file_operations.

Vous obtiendrez probablement un résultat différent si vous l'enregistrez dans la version verrouillée de la fonction. La cause la plus probable est que le inode est verrouillé pour l'appel ioctl (comme il devrait être, d'éviter les conditions de course avec des opérations simultanées read ou write au même dispositif)

Désolé, je n'ai pas accès à l'arbre source linux pour le nom propre du champ à utiliser, mais pour sûr, vous serez en mesure de le trouver vous-même.