Полный драйвер “parlelport”

Предыдущая  Содержание  Следующая V*D*V

Я продолжу, глядя на весь код модуля parlelport. Вы должны заменить слово memory словом parlelport во всём коде модуля memory. Окончательный результат приведён ниже:

 

<parlelport.c> =

 

<parlelport initial>

<parlelport init module>

<parlelport exit module>

<parlelport open>

<parlelport release>

<parlelport read>

<parlelport write>

Секция инициализации

В секции инициализации драйвера используется другой старший номер (61). Кроме того, глобальная переменная переменная memory_buffer изменена на port и добавлены ещё две строчки с #include: ioport.h и io.h.

 

<parlelport initial> =

 

/* Необходимые подключения для драйверов */

#include <linux/init.h>

#include <linux/config.h>

#include <linux/module.h>

#include <linux/kernel.h> /* printk() */

#include <linux/slab.h> /* kmalloc() */

#include <linux/fs.h> /* всё самое важное... */

#include <linux/errno.h> /* коды ошибок */

#include <linux/types.h> /* size_t */

#include <linux/proc_fs.h>

#include <linux/fcntl.h> /* O_ACCMODE */

#include <linux/ioport.h>

#include <asm/system.h> /* cli(), *_flags */

#include <asm/uaccess.h> /* copy_from/to_user */

#include <asm/io.h> /* inb, outb */

 

MODULE_LICENSE("Dual BSD/GPL");

 

/* Декларация функций parlelport.c */

int parlelport_open(struct inode *inode, struct file *filp);

int parlelport_release(struct inode *inode, struct file *filp);

ssize_t parlelport_read(struct file *filp, char *buf,

size_t count, loff_t *f_pos);

ssize_t parlelport_write(struct file *filp, char *buf,

size_t count, loff_t *f_pos);

void parlelport_exit(void);

int parlelport_init(void);

 

/* Структура, которая декларирует основные операции */

/* функции доступа к файлу */

struct file_operations parlelport_fops = {

    read: parlelport_read,

    write: parlelport_write,

    open: parlelport_open,

    release: parlelport_release

};

 

/* Глобальные переменные драйвера */

/* Старший номер */

int parlelport_major = 61;

 

/* Управляющие переменные для памяти */

/* резервирование параллельного порта */

int port;

 

module_init(parlelport_init);

module_exit(parlelport_exit);

Инициализация модуля

В этой процедуре инициализации модуля я познакомлю вас с резервированием памяти параллельного порта, как это было описано ранее.

 

<parlelport init module> =

 

int parlelport_init(void) {

    int result;

 

    /* Регистрируем устройство */

    result = register_chrdev(parlelport_major, "parlelport",

                &parlelport_fops);

    if (result < 0) {

        printk(

            "<1>parlelport: cannot obtain major number %d\n",

        parlelport_major);

        return result;

    }

 

    <parlelport modified init module>

 

    printk("<1>Inserting parlelport module\n");

    return 0;

 

fail:

    parlelport_exit();

    return result;

}

Удаление модуля

Эта процедура включает изменения, о которых говорилось ранее.

 

<parlelport exit module> =

 

void parlelport_exit(void) {

 

    /* Делаем старший номер свободным! */

    unregister_chrdev(parlelport_major, "parlelport");

 

    <parlelport modified exit module>

 

    printk("<1>Removing parlelport module\n");

}

 

Открытие устройства как файл

Эта процедура идентична такой же в драйвере memory.

 

<parlelport open> =

 

int parlelport_open(struct inode *inode, struct file *filp) {

 

    /* Успешно */

    return 0;

}

 

Закрытие устройства как файл

И снова, прекрасное соответствие.

 

<parlelport release> =

 

int parlelport_release(struct inode *inode, struct file *filp) {

 

    /* Success */

    return 0;

}

Чтение устройства

Функция чтения похожа на функцию в memory с соответствующими изменениями на чтение из порта устройства.

 

<parlelport read> =

 

ssize_t parlelport_read(struct file *filp, char *buf,

                        size_t count, loff_t *f_pos) {

 

    /* Буфер для чтения устройства */

    char parlelport_buffer;

 

    <parlelport inport>

 

    /* Передаём данные в пользовательское пространство */

    copy_to_user(buf,&parlelport_buffer,1);

 

    /* Изменяем позицию чтения, как это необходимо */

    if (*f_pos == 0) {

        *f_pos+=1;

        return 1;

    } else {

        return 0;

    }

}

Запись в устройство

Она аналогична такой же в memory, исключая запись в устройство.

 

<parlelport write> =

 

ssize_t parlelport_write( struct file *filp, char *buf,

                          size_t count, loff_t *f_pos) {

    char *tmp;

 

    /* Buffer writing to the device */

    char parlelport_buffer;

    tmp=buf+count-1;

    copy_from_user(&parlelport_buffer,tmp,1);

 

    <parlelport outport>

 

    return 1;

}

 

Предыдущая  Содержание  Следующая