Аллен Питер В.
Шрифт:
dev_state->dev_open=0;
MOD_DEC_USE_COUNT;
return 0;
}
Теперь нам нужно указать ядру, какие функции нужно использовать для открытия и закрытия устройства:
struct file_operations FO = {
open: device_open,
release: device_close
};
Полный код модуля устройства device вместе с функциями открытия и закрытия устройства, а также структурой file_operations приведен в следующем листинге:
Листинг 28.9. Модуль устройства device (module.с)
#define MODULE
#define __KERNEL__
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h> // регистрация устройств
#include <linux/ioport.h> // работа с портами ввода/вывода
#include <linux/sched.h> // резервирование прерывания
// Имя нашего устройства
#define DEV_NAME "device"
// Порты ввода-вывода нашего устройства
#define PORT_START 0x2000
#define PORT_QTY 10
// Память нашего устройства
#define MEM_START 0x20000000
#define MEM_QTY 0x20
// Номер прерывания для нашего устройства
#define IRQ_NUM 9
MODULE_AUTHOR("Denis Kolisnichenko dhsilabs@mail.ru");
MODULE_DESCRIPTION("Linux kernel module");
// Старший номер файла устройства
static int Major;
// Структура file_operations - пока пустая,
// но вскоре мы ее напишем
struct file_operations FO {
open: device_open,
release: device_close
};
// Структура для хранения состояния устройства
struct device_state {
int dev_open; // 1 - устройство открыто, 0 — закрыто
ssize_t byte_read; // Количество прочитанных байтов
// из устройства
ssize_t byte_write; // Количество записанных байтов
};
// Массив для хранения информации о состоянии устройств
static struct device_state state[2];
// Обработчик прерывания
void irq_handler(int irq, void *dev_id, struct pt_regs
*regs) {
return;
}
int init_module {
// Регистрируем устройство
printk("My module: starting...\n") ;
Major = register_chrdev(0, DEV_NAME, &F0);
if (Major < 0) {
// Устройство не зарегистрировано
printk("My module: registration failed\n");
return Major;
}
printk("My module: device registered, major number = %d\n",
Major);
// Резервирование портов ввода-вывода
printk("My module: allocating io ports\n");
if (check_region(PORT_START, PORT_QTY)) {
printk("My module: allocation io ports failed\n");
return -EBUSY;
}
request_region(PORT_START, PORT_QTY, DEV_NAME);
printk("My module: io ports allocated\n");
// Резервирование памяти
if (check_mem_region(MEM_START, MEM_QTY)) {
printk(My module: memory allocation failed\n");
release_region(PORT_START, PQRT_QTY);
return -EBUSY;
}
request_mem_region(MEM_START, MEM_QTY, DEV_NAME);