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*,

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

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

Отметить Добавить цитату