printk('My module: allocating io ports
');
if (check_region(PORT_START, PORT_QTY)) {
printk('My module: allocation io ports failed
');
return -EBUSY;
}
request_region(PORT_START, PORT_QTY, DEV_NAME);
printk('My module: io ports allocated
');
// Резервирование памяти
if (check_mem_region(MEM_START, MEM_QTY)) {
printk(My module: memory allocation failed
');
release_region(PORT_START, PQRT_QTY);
return -EBUSY;
}
request_mem_region(MEM_START, MEM_QTY, DEV_NAME);
printk('My module: memory allocated
');
// Резервирование прерывания
if (request_irq(IRQ_NUM, irq_handler, 0, DEV_NAME, NULL)) {
printk('My module: IRQ allocation failed
');
release_mem_region(MEM_START, MEM_QTY);
release_region(PORT_START, PORT_QTY);
return -EBUSY;
}
printk('My module: IRQ allocated
');
return 0;
}
void cleanup_module() {
// Освобождаем порты ввода-вывода
release_region(PORT_START, PORT_QTY);
printk('My module: release io ports
');
// Освобождаем память
release_mem_region(MEM_START, MEM_QTY);
printk('My module: release memory
');
// Освобождаем прерывание
free_irq(IRQ_NUM, NULL);
printk('My module: release irq
');
// Отменяем регистрацию устройства
if (unregister_chrdev(Major, DEV_NAME) < 0) {
printk('My module: cannot to unregister device
');
}
printk('My module: device unregistered
');
return;
}
static int device_open(struct inode *inode,
struct file *fp) {
struct device_state *dev_state;
printk('My module: try to open device with minor number %d
',
MINOR(inode->i_rdev));
dev_state = &state[MINOR(inode->i_rdev)];
if (dev__state->dev_open) {
printk('Devise is busy
');
return -EBUSY;
}
dev_state->dev_open = 1;
dev_state->byte_read = 0;
dev_state->byte_write = 0;
MOD_INC_USE_COUNT;
return 0;
}
static int device_close(struct inode *inode, struct file
*fp) {
struct device_state *dev_state;
printk('My module: try to close device with minor number %d
',
MINOR(inode->i_rdev));
dev_state = &state[MINOR(inode->i_rdev)];
if (!dev_state->dev_open) {
printk('Device is not open
');
return 0;
}
dev_state->dev_open = 0;
MOD_DEC_USE_COUNT;
return 0;
}
Теперь модуль для абстрактного устройства device готов. Вы можете написать небольшую программку, которая пыталась бы выполнить операции с нашим устройством: открыть его и закрыть — других операций мы не определили. Для определения других действий используется та же структура file_operations. Листинг 28.10 показывает, как она объявлена в файле /usr/src/linux- 2.4/include/linux/fs.h
.
Листинг 28.10. Фрагмент файла /usr/src/linux-2.4/include/linux/fs.h
struct file_operations {
struct module *owner;
loff_t (*llseek)(struct file*, loff_t, int);
ssize_t (*read)(struct file*, char*, size_t, loff_t*);
ssize_t (*write)(struct file*, const char*,
size_t, loff_t*);
int (*readdir)(struct file*, void*, filldir_t);
unsigned int (*poll) (struct file*,
struct poll_table_struct*);
int (*ioctl)(struct inode*, struct file*, unsigned int,
unsigned long);
int (*mmap)(struct file*, struct vm_area_struct*);
int (*open)(struct inode*, struct file*);
int (*flush)(struct file*);
int (*release)(struct inode*, struct file*);
int (*fsync)(struct file*, struct dentry*,