39 #include <linux/tty_driver.h> |
39 #include <linux/tty_driver.h> |
40 #include <linux/tty_flip.h> |
40 #include <linux/tty_flip.h> |
41 #include <linux/termios.h> |
41 #include <linux/termios.h> |
42 #include <linux/timer.h> |
42 #include <linux/timer.h> |
43 #include <linux/version.h> |
43 #include <linux/version.h> |
|
44 #include <linux/serial.h> |
|
45 #include <linux/uaccess.h> |
44 |
46 |
45 #include "../master/globals.h" |
47 #include "../master/globals.h" |
46 #include "../include/ectty.h" |
48 #include "../include/ectty.h" |
47 |
49 |
48 /*****************************************************************************/ |
50 /*****************************************************************************/ |
76 module_param_named(debug_level, debug_level, uint, S_IRUGO); |
78 module_param_named(debug_level, debug_level, uint, S_IRUGO); |
77 MODULE_PARM_DESC(debug_level, "Debug level"); |
79 MODULE_PARM_DESC(debug_level, "Debug level"); |
78 |
80 |
79 /** \endcond */ |
81 /** \endcond */ |
80 |
82 |
|
83 /** Standard termios for ec_tty devices. |
|
84 * |
|
85 * Simplest possible configuration, as you would expect. |
|
86 */ |
81 static struct ktermios ec_tty_std_termios = { |
87 static struct ktermios ec_tty_std_termios = { |
82 .c_iflag = ICRNL | IXON, |
88 .c_iflag = 0, |
83 .c_oflag = OPOST, |
89 .c_oflag = 0, |
84 .c_cflag = B38400 | CS8 | CREAD | HUPCL, |
90 .c_cflag = B9600 | CS8 | CREAD, |
85 .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN, |
91 .c_lflag = 0, |
86 .c_cc = INIT_C_CC, |
92 .c_cc = INIT_C_CC, |
87 }; |
93 }; |
88 |
94 |
89 struct ec_tty { |
95 struct ec_tty { |
90 int minor; |
96 int minor; |
137 tty_driver->minor_start = 0; |
143 tty_driver->minor_start = 0; |
138 tty_driver->type = TTY_DRIVER_TYPE_SERIAL; |
144 tty_driver->type = TTY_DRIVER_TYPE_SERIAL; |
139 tty_driver->subtype = SERIAL_TYPE_NORMAL; |
145 tty_driver->subtype = SERIAL_TYPE_NORMAL; |
140 tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
146 tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
141 tty_driver->init_termios = ec_tty_std_termios; |
147 tty_driver->init_termios = ec_tty_std_termios; |
142 tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
|
143 tty_set_operations(tty_driver, &ec_tty_ops); |
148 tty_set_operations(tty_driver, &ec_tty_ops); |
144 |
149 |
145 ret = tty_register_driver(tty_driver); |
150 ret = tty_register_driver(tty_driver); |
146 if (ret) { |
151 if (ret) { |
147 printk(KERN_ERR PFX "Failed to register tty driver.\n"); |
152 printk(KERN_ERR PFX "Failed to register tty driver.\n"); |
299 { |
304 { |
300 del_timer_sync(&tty->timer); |
305 del_timer_sync(&tty->timer); |
301 tty_unregister_device(tty_driver, tty->minor); |
306 tty_unregister_device(tty_driver, tty->minor); |
302 } |
307 } |
303 |
308 |
|
309 /*****************************************************************************/ |
|
310 |
|
311 int ec_tty_get_serial_info(ec_tty_t *tty, struct serial_struct *data) |
|
312 { |
|
313 struct serial_struct tmp; |
|
314 |
|
315 if (!data) |
|
316 return -EFAULT; |
|
317 |
|
318 memset(&tmp, 0, sizeof(tmp)); |
|
319 |
|
320 if (copy_to_user(data, &tmp, sizeof(*data))) { |
|
321 return -EFAULT; |
|
322 } |
|
323 return 0; |
|
324 } |
|
325 |
304 /****************************************************************************** |
326 /****************************************************************************** |
305 * Device callbacks |
327 * Device callbacks |
306 *****************************************************************************/ |
328 *****************************************************************************/ |
307 |
329 |
308 static int ec_tty_open(struct tty_struct *tty, struct file *file) |
330 static int ec_tty_open(struct tty_struct *tty, struct file *file) |
452 /*****************************************************************************/ |
474 /*****************************************************************************/ |
453 |
475 |
454 static int ec_tty_ioctl(struct tty_struct *tty, struct file *file, |
476 static int ec_tty_ioctl(struct tty_struct *tty, struct file *file, |
455 unsigned int cmd, unsigned long arg) |
477 unsigned int cmd, unsigned long arg) |
456 { |
478 { |
457 #if EC_TTY_DEBUG >= 2 |
479 ec_tty_t *t = (ec_tty_t *) tty->driver_data; |
458 printk(KERN_INFO PFX "%s().\n", __func__); |
480 int ret = -ENOTTY; |
459 #endif |
481 |
460 return -ENOTTY; |
482 #if EC_TTY_DEBUG >= 2 |
461 } |
483 printk(KERN_INFO PFX "%s(tty=%p, file=%p, cmd=%08x, arg=%08lx).\n", |
462 |
484 __func__, tty, file, cmd, arg); |
463 /*****************************************************************************/ |
485 printk(KERN_INFO PFX "decoded: type=%02x nr=%u\n", |
464 |
486 _IOC_TYPE(cmd), _IOC_NR(cmd)); |
465 static void ec_tty_throttle(struct tty_struct *tty) |
487 #endif |
466 { |
488 |
467 #if EC_TTY_DEBUG >= 2 |
489 switch (cmd) { |
468 printk(KERN_INFO PFX "%s().\n", __func__); |
490 case TIOCGSERIAL: |
469 #endif |
491 if (access_ok(VERIFY_WRITE, |
470 } |
492 (void *) arg, sizeof(struct serial_struct))) { |
471 |
493 ret = ec_tty_get_serial_info(t, (struct serial_struct *) arg); |
472 /*****************************************************************************/ |
494 } else { |
473 |
495 ret = -EFAULT; |
474 static void ec_tty_unthrottle(struct tty_struct *tty) |
496 } |
475 { |
497 break; |
476 #if EC_TTY_DEBUG >= 2 |
498 |
477 printk(KERN_INFO PFX "%s().\n", __func__); |
499 case TIOCSSERIAL: // TODO |
478 #endif |
500 break; |
|
501 |
|
502 default: |
|
503 #if EC_TTY_DEBUG >= 2 |
|
504 printk(KERN_INFO PFX "no ioctl()!\n"); |
|
505 #endif |
|
506 ret = -ENOIOCTLCMD; |
|
507 break; |
|
508 } |
|
509 |
|
510 return ret; |
479 } |
511 } |
480 |
512 |
481 /*****************************************************************************/ |
513 /*****************************************************************************/ |
482 |
514 |
483 static void ec_tty_set_termios(struct tty_struct *tty, |
515 static void ec_tty_set_termios(struct tty_struct *tty, |
484 struct ktermios *old_termios) |
516 struct ktermios *old_termios) |
485 { |
517 { |
|
518 //ec_tty_t *t = (ec_tty_t *) tty->driver_data; |
|
519 |
486 #if EC_TTY_DEBUG >= 2 |
520 #if EC_TTY_DEBUG >= 2 |
487 printk(KERN_INFO PFX "%s().\n", __func__); |
521 printk(KERN_INFO PFX "%s().\n", __func__); |
|
522 #endif |
|
523 |
|
524 if (tty->termios->c_cflag == old_termios->c_cflag) |
|
525 return; |
|
526 |
|
527 #if EC_TTY_DEBUG >= 2 |
|
528 printk(KERN_INFO "cflag changed from %x to %x.\n", |
|
529 old_termios->c_cflag, tty->termios->c_cflag); |
488 #endif |
530 #endif |
489 } |
531 } |
490 |
532 |
491 /*****************************************************************************/ |
533 /*****************************************************************************/ |
492 |
534 |
546 static void ec_tty_wait_until_sent(struct tty_struct *tty, int timeout) |
588 static void ec_tty_wait_until_sent(struct tty_struct *tty, int timeout) |
547 { |
589 { |
548 #if EC_TTY_DEBUG >= 2 |
590 #if EC_TTY_DEBUG >= 2 |
549 printk(KERN_INFO PFX "%s(timeout=%i).\n", __func__, timeout); |
591 printk(KERN_INFO PFX "%s(timeout=%i).\n", __func__, timeout); |
550 #endif |
592 #endif |
551 } |
|
552 |
|
553 /*****************************************************************************/ |
|
554 |
|
555 static int ec_tty_tiocmget(struct tty_struct *tty, struct file *file) |
|
556 { |
|
557 #if EC_TTY_DEBUG >= 2 |
|
558 printk(KERN_INFO PFX "%s().\n", __func__); |
|
559 #endif |
|
560 return -EBUSY; |
|
561 } |
|
562 |
|
563 /*****************************************************************************/ |
|
564 |
|
565 static int ec_tty_tiocmset(struct tty_struct *tty, struct file *file, |
|
566 unsigned int set, unsigned int clear) |
|
567 { |
|
568 #if EC_TTY_DEBUG >= 2 |
|
569 printk(KERN_INFO PFX "%s(set=%u, clear=%u).\n", __func__, set, clear); |
|
570 #endif |
|
571 return -EBUSY; |
|
572 } |
593 } |
573 |
594 |
574 /*****************************************************************************/ |
595 /*****************************************************************************/ |
575 |
596 |
576 static const struct tty_operations ec_tty_ops = { |
597 static const struct tty_operations ec_tty_ops = { |
580 .put_char = ec_tty_put_char, |
601 .put_char = ec_tty_put_char, |
581 .write_room = ec_tty_write_room, |
602 .write_room = ec_tty_write_room, |
582 .chars_in_buffer = ec_tty_chars_in_buffer, |
603 .chars_in_buffer = ec_tty_chars_in_buffer, |
583 .flush_buffer = ec_tty_flush_buffer, |
604 .flush_buffer = ec_tty_flush_buffer, |
584 .ioctl = ec_tty_ioctl, |
605 .ioctl = ec_tty_ioctl, |
585 .throttle = ec_tty_throttle, |
|
586 .unthrottle = ec_tty_unthrottle, |
|
587 .set_termios = ec_tty_set_termios, |
606 .set_termios = ec_tty_set_termios, |
588 .stop = ec_tty_stop, |
607 .stop = ec_tty_stop, |
589 .start = ec_tty_start, |
608 .start = ec_tty_start, |
590 .hangup = ec_tty_hangup, |
609 .hangup = ec_tty_hangup, |
591 .break_ctl = ec_tty_break, |
610 .break_ctl = ec_tty_break, |
592 .send_xchar = ec_tty_send_xchar, |
611 .send_xchar = ec_tty_send_xchar, |
593 .wait_until_sent = ec_tty_wait_until_sent, |
612 .wait_until_sent = ec_tty_wait_until_sent, |
594 .tiocmget = ec_tty_tiocmget, |
|
595 .tiocmset = ec_tty_tiocmset, |
|
596 }; |
613 }; |
597 |
614 |
598 /****************************************************************************** |
615 /****************************************************************************** |
599 * Public functions and methods |
616 * Public functions and methods |
600 *****************************************************************************/ |
617 *****************************************************************************/ |