#include "ioctl.h"
#include "../dev.h"

// Работа с символьным устройством в старом стиле...
static int hello_open( struct inode *n, struct file *f ) {
   // ... при этом MINOR номер устройства должна обслуживать функция open:
   // unsigned int minor = iminor( n );
   return 0;
}

static int hello_release( struct inode *n, struct file *f ) {
   return 0;
}

static int hello_ioctl( struct inode *n, struct file *f,
                        unsigned int cmd, unsigned long arg ) {
   if( ( _IOC_TYPE( cmd ) != IOC_MAGIC ) ) return -ENOTTY;
   switch( cmd ) {
      case IOCTL_GET_STRING:
         if( copy_to_user( (void*)arg, hello_str, _IOC_SIZE( cmd ) ) ) return -EFAULT;
         break;
      default: 
         return -ENOTTY;
   }
   return 0;
}

static const struct file_operations hello_fops = {
   .owner = THIS_MODULE,
   .open = hello_open,
   .release = hello_release,
   .read  = hello_read,
   .ioctl = hello_ioctl
};

#define HELLO_MAJOR 200
#define HELLO_MODNAME "hello_dev"

static int __init hello_init( void ) {
   int ret = register_chrdev( HELLO_MAJOR, HELLO_MODNAME, &hello_fops );
   if( ret < 0 ) {
      printk( KERN_ERR "Can not register char device\n" );
      goto err;
   }
err:
   return ret;
}

static void __exit hello_exit( void ) {
  unregister_chrdev( HELLO_MAJOR, HELLO_MODNAME );
}
