tty/module.c
changeset 1787 439f186185be
parent 1786 7198caede741
child 1789 058248c47ba0
equal deleted inserted replaced
1786:7198caede741 1787:439f186185be
   108     unsigned int rx_write_idx;
   108     unsigned int rx_write_idx;
   109 
   109 
   110     struct timer_list timer;
   110     struct timer_list timer;
   111     struct tty_struct *tty;
   111     struct tty_struct *tty;
   112 
   112 
   113     int (*cflag_cb)(void *, tcflag_t);
   113     ec_tty_operations_t ops;
   114     void *cb_data;
   114     void *cb_data;
   115 };
   115 };
   116 
   116 
   117 static const struct tty_operations ec_tty_ops; // see below
   117 static const struct tty_operations ec_tty_ops; // see below
   118 
   118 
   182 /******************************************************************************
   182 /******************************************************************************
   183  * ec_tty_t methods.
   183  * ec_tty_t methods.
   184  *****************************************************************************/
   184  *****************************************************************************/
   185 
   185 
   186 int ec_tty_init(ec_tty_t *tty, int minor,
   186 int ec_tty_init(ec_tty_t *tty, int minor,
   187         int (*cflag_cb)(void *, tcflag_t), void *cb_data)
   187         const ec_tty_operations_t *ops, void *cb_data)
   188 {
   188 {
   189     tty->minor = minor;
   189     tty->minor = minor;
   190     tty->tx_read_idx = 0;
   190     tty->tx_read_idx = 0;
   191     tty->tx_write_idx = 0;
   191     tty->tx_write_idx = 0;
   192     tty->wakeup = 0;
   192     tty->wakeup = 0;
   193     tty->rx_read_idx = 0;
   193     tty->rx_read_idx = 0;
   194     tty->rx_write_idx = 0;
   194     tty->rx_write_idx = 0;
   195     init_timer(&tty->timer);
   195     init_timer(&tty->timer);
   196     tty->tty = NULL;
   196     tty->tty = NULL;
   197     tty->cflag_cb = cflag_cb;
   197     tty->ops = *ops;
   198     tty->cb_data = cb_data;
   198     tty->cb_data = cb_data;
   199 
   199 
   200     tty->dev = tty_register_device(tty_driver, tty->minor, NULL);
   200     tty->dev = tty_register_device(tty_driver, tty->minor, NULL);
   201     if (IS_ERR(tty->dev)) {
   201     if (IS_ERR(tty->dev)) {
   202         printk(KERN_ERR PFX "Failed to register tty device.\n");
   202         printk(KERN_ERR PFX "Failed to register tty device.\n");
   341  *****************************************************************************/
   341  *****************************************************************************/
   342 
   342 
   343 static int ec_tty_open(struct tty_struct *tty, struct file *file)
   343 static int ec_tty_open(struct tty_struct *tty, struct file *file)
   344 {
   344 {
   345     ec_tty_t *t;
   345     ec_tty_t *t;
   346     int line = tty->index, ret;
   346     int line = tty->index;
   347 
   347 
   348 #if EC_TTY_DEBUG >= 1
   348 #if EC_TTY_DEBUG >= 1
   349     printk(KERN_INFO PFX "Opening line %i.\n", line);
   349     printk(KERN_INFO PFX "Opening line %i.\n", line);
   350 #endif
   350 #endif
   351 
   351 
   362         return -EBUSY;
   362         return -EBUSY;
   363     }
   363     }
   364 
   364 
   365     t->tty = tty;
   365     t->tty = tty;
   366     tty->driver_data = t;
   366     tty->driver_data = t;
   367 
       
   368     // request initial settings
       
   369     ret = t->cflag_cb(t->cb_data, t->tty->termios->c_cflag);
       
   370     if (ret) {
       
   371         printk(KERN_ERR PFX "Error: Device does not accept"
       
   372                 " initial configuration!\n");
       
   373         return ret;
       
   374     }
       
   375 
       
   376     return 0;
   367     return 0;
   377 }
   368 }
   378 
   369 
   379 /*****************************************************************************/
   370 /*****************************************************************************/
   380 
   371 
   550 #if EC_TTY_DEBUG >= 2
   541 #if EC_TTY_DEBUG >= 2
   551     printk(KERN_INFO "cflag changed from %x to %x.\n",
   542     printk(KERN_INFO "cflag changed from %x to %x.\n",
   552             old_termios->c_cflag, tty->termios->c_cflag);
   543             old_termios->c_cflag, tty->termios->c_cflag);
   553 #endif
   544 #endif
   554 
   545 
   555     ret = t->cflag_cb(t->cb_data, tty->termios->c_cflag);
   546     ret = t->ops.cflag_changed(t->cb_data, tty->termios->c_cflag);
   556     if (ret) {
   547     if (ret) {
   557         printk(KERN_ERR PFX "ERROR: cflag 0x%x not accepted.\n",
   548         printk(KERN_ERR PFX "ERROR: cflag 0x%x not accepted.\n",
   558                 tty->termios->c_cflag);
   549                 tty->termios->c_cflag);
   559         tty->termios->c_cflag = old_termios->c_cflag;
   550         tty->termios->c_cflag = old_termios->c_cflag;
   560     }
   551     }
   644 
   635 
   645 /******************************************************************************
   636 /******************************************************************************
   646  * Public functions and methods
   637  * Public functions and methods
   647  *****************************************************************************/
   638  *****************************************************************************/
   648 
   639 
   649 ec_tty_t *ectty_create(int (*cflag_cb)(void *, tcflag_t), void *cb_data)
   640 ec_tty_t *ectty_create(const ec_tty_operations_t *ops, void *cb_data)
   650 {
   641 {
   651     ec_tty_t *tty;
   642     ec_tty_t *tty;
   652     int minor, ret;
   643     int minor, ret;
   653 
   644 
   654     if (down_interruptible(&tty_sem)) {
   645     if (down_interruptible(&tty_sem)) {
   664                 up(&tty_sem);
   655                 up(&tty_sem);
   665                 printk(KERN_ERR PFX "Failed to allocate memory.\n");
   656                 printk(KERN_ERR PFX "Failed to allocate memory.\n");
   666                 return ERR_PTR(-ENOMEM);
   657                 return ERR_PTR(-ENOMEM);
   667             }
   658             }
   668 
   659 
   669             ret = ec_tty_init(tty, minor, cflag_cb, cb_data);
   660             ret = ec_tty_init(tty, minor, ops, cb_data);
   670             if (ret) {
   661             if (ret) {
   671                 up(&tty_sem);
   662                 up(&tty_sem);
   672                 kfree(tty);
   663                 kfree(tty);
   673                 return ERR_PTR(ret);
   664                 return ERR_PTR(ret);
   674             }
   665             }