2 * IBM/3270 Driver -- Copyright (C) 2000, 2001 UTS Global LLC
4 * tubtty.c -- Linemode tty driver
10 * Author: Richard Hitt
12 #include <linux/config.h>
15 /* Initialization & uninitialization for tubtty */
16 int tty3270_init(void);
17 void tty3270_fini(void);
19 /* Interface routines from the upper tty layer to the tty driver */
20 static int tty3270_open(struct tty_struct *, struct file *);
21 static void tty3270_close(struct tty_struct *, struct file *);
22 static int tty3270_write(struct tty_struct *, int,
23 const unsigned char *, int);
24 static void tty3270_put_char(struct tty_struct *, unsigned char);
25 static void tty3270_flush_chars(struct tty_struct *);
26 static int tty3270_write_room(struct tty_struct *);
27 static int tty3270_chars_in_buffer(struct tty_struct *);
28 static int tty3270_ioctl(struct tty_struct *, struct file *,
29 unsigned int cmd, unsigned long arg);
30 static void tty3270_set_termios(struct tty_struct *, struct termios *);
31 static void tty3270_hangup(struct tty_struct *);
32 static void tty3270_flush_buffer(struct tty_struct *);
33 static int tty3270_read_proc(char *, char **, off_t, int, int *, void *);
34 static int tty3270_write_proc(struct file *, const char *,
35 unsigned long, void *);
37 /* tty3270 utility functions */
38 static void tty3270_bh(void *);
39 void tty3270_sched_bh(tub_t *);
40 static int tty3270_wait(tub_t *, long *);
41 void tty3270_int(tub_t *, devstat_t *);
42 int tty3270_try_logging(tub_t *);
43 static void tty3270_start_input(tub_t *);
44 static void tty3270_do_input(tub_t *);
45 static void tty3270_do_enter(tub_t *, char *, int);
46 static void tty3270_do_showi(tub_t *, char *, int);
47 int tty3270_io(tub_t *);
48 static int tty3270_show_tube(int, char *, int);
50 int tty3270_major = -1;
51 struct tty_driver tty3270_driver;
53 struct tty_struct *tty3270_table[TUBMAXMINS];
54 struct termios *tty3270_termios[TUBMAXMINS];
55 struct termios *tty3270_termios_locked[TUBMAXMINS];
56 #ifdef CONFIG_TN3270_CONSOLE
57 int con3270_major = -1;
58 struct tty_driver con3270_driver;
60 struct tty_struct *con3270_table[1];
61 struct termios *con3270_termios[1];
62 struct termios *con3270_termios_locked[1];
63 #endif /* CONFIG_TN3270_CONSOLE */
65 int tty3270_proc_index;
66 int tty3270_proc_data;
67 int tty3270_proc_misc;
68 enum tubwhat tty3270_proc_what;
71 * tty3270_init() -- Register the tty3270 driver
76 struct tty_driver *td = &tty3270_driver;
79 /* Initialize for tty driver */
80 td->magic = TTY_DRIVER_MAGIC;
81 td->driver_name = "tty3270";
83 td->major = IBM_TTY3270_MAJOR;
86 td->type = TTY_DRIVER_TYPE_SYSTEM;
87 td->subtype = SYSTEM_TYPE_TTY;
88 td->init_termios = tty_std_termios;
89 td->flags = TTY_DRIVER_RESET_TERMIOS;
90 #ifdef CONFIG_DEVFS_FS
91 td->flags |= TTY_DRIVER_NO_DEVFS;
93 td->refcount = &tty3270_refcount;
94 td->table = tty3270_table;
95 td->termios = tty3270_termios;
96 td->termios_locked = tty3270_termios_locked;
98 td->open = tty3270_open;
99 td->close = tty3270_close;
100 td->write = tty3270_write;
101 td->put_char = tty3270_put_char;
102 td->flush_chars = tty3270_flush_chars;
103 td->write_room = tty3270_write_room;
104 td->chars_in_buffer = tty3270_chars_in_buffer;
105 td->ioctl = tty3270_ioctl;
107 td->set_termios = tty3270_set_termios;
109 td->unthrottle = NULL;
112 td->hangup = tty3270_hangup;
113 td->break_ctl = NULL;
114 td->flush_buffer = tty3270_flush_buffer;
115 td->set_ldisc = NULL;
116 td->wait_until_sent = NULL;
117 td->send_xchar = NULL;
118 td->read_proc = tty3270_read_proc;
119 td->write_proc = tty3270_write_proc;
121 rc = tty_register_driver(td);
123 printk(KERN_ERR "tty3270 registration failed with %d\n", rc);
125 tty3270_major = IBM_TTY3270_MAJOR;
126 if (td->proc_entry != NULL)
127 td->proc_entry->mode = S_IRUGO | S_IWUGO;
129 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
130 #ifdef CONFIG_TN3270_CONSOLE
131 if (CONSOLE_IS_3270) {
132 tty3270_con_driver = *td;
133 td = &tty3270_con_driver;
134 td->driver_name = "con3270";
135 td->name = "con3270";
136 td->major = MAJOR(S390_CONSOLE_DEV);
137 td->minor_start = MINOR(S390_CONSOLE_DEV);
139 td->refcount = &con3270_refcount;
140 td->table = con3270_table;
141 td->termios = con3270_termios;
142 td->termios_locked = con3270_termios_locked;
144 rc = tty_register_driver(td);
147 "con3270 registration failed with %d\n", rc);
149 con3270_major = MAJOR(S390_CONSOLE_DEV);
150 if (td->proc_entry != NULL)
151 td->proc_entry->mode = S_IRUGO | S_IWUGO;
154 #endif /* ifdef CONFIG_TN3270_CONSOLE */
155 #endif /* if LINUX_VERSION_CODE */
161 * tty3270_fini() -- Uninitialize linemode tubes
166 if (tty3270_major != -1) {
167 tty_unregister_driver(&tty3270_driver);
170 #ifdef CONFIG_TN3270_CONSOLE
171 if (CONSOLE_IS_3270 && con3270_major != -1) {
172 tty_unregister_driver(&con3270_driver);
179 tty3270_open(struct tty_struct *tty, struct file *filp)
186 if ((tubp = TTY2TUB(tty)) == NULL) {
191 if ((rc = tty3270_wait(tubp, &flags)) != 0)
193 if (tubp->lnopen > 0) {
195 TUBUNLOCK(tubp->irq, flags);
198 if (tubp->flags & TUB_OPEN_STET) {
202 tubp->flags &= ~TUB_SIZED;
204 if ((rc = tty3270_size(tubp, &flags)) != 0)
206 if ((rc = tty3270_rcl_init(tubp)) != 0)
208 if ((rc = tty3270_aid_init(tubp)) != 0)
210 if ((rc = tty3270_scl_init(tubp)) != 0)
213 tubp->intv = tty3270_int;
216 tty->driver_data = tubp;
217 tty->winsize.ws_row = tubp->geom_rows - 2;
218 tty->winsize.ws_col = tubp->geom_cols;
219 if (tubp->tty_input == NULL)
220 tubp->tty_input = kmalloc(GEOM_INPLEN, GFP_KERNEL|GFP_DMA);
221 tubp->tty_inattr = TF_INPUT;
224 TUBUNLOCK(tubp->irq, flags);
228 tty3270_scl_fini(tubp);
229 tty3270_aid_fini(tubp);
230 tty3270_rcl_fini(tubp);
231 TUBUNLOCK(tubp->irq, flags);
237 tty3270_close(struct tty_struct *tty, struct file *filp)
242 if ((tubp = tty->driver_data) == NULL)
245 tty3270_wait(tubp, &flags);
246 if (--tubp->lnopen > 0)
249 tty->driver_data = NULL;
250 tty3270_aid_fini(tubp);
251 tty3270_rcl_fini(tubp);
252 tty3270_scl_fini(tubp);
255 TUBUNLOCK(tubp->irq, flags);
259 tty3270_write(struct tty_struct *tty, int fromuser,
260 const unsigned char *buf, int count)
267 if ((tubp = tty->driver_data) == NULL)
270 #ifdef CONFIG_TN3270_CONSOLE
271 if (CONSOLE_IS_3270 && tub3270_con_tubp == tubp)
272 tub3270_con_copy(tubp);
273 #endif /* CONFIG_TN3270_CONSOLE */
275 obcb.bc_buf = (char *)buf;
276 obcb.bc_len = obcb.bc_cnt = obcb.bc_wr = count;
279 TUBLOCK(tubp->irq, flags);
280 rc = tub3270_movedata(&obcb, &tubp->tty_bcb, fromuser);
281 tty3270_try_logging(tubp);
282 TUBUNLOCK(tubp->irq, flags);
287 tty3270_put_char(struct tty_struct *tty, unsigned char ch)
293 if ((tubp = tty->driver_data) == NULL)
296 TUBLOCK(tubp->irq, flags);
298 if (ob->bc_cnt < ob->bc_len) {
299 ob->bc_buf[ob->bc_wr++] = ch;
300 if (ob->bc_wr == ob->bc_len)
304 tty3270_try_logging(tubp);
305 TUBUNLOCK(tubp->irq, flags);
309 tty3270_flush_chars(struct tty_struct *tty)
314 if ((tubp = tty->driver_data) == NULL)
317 TUBLOCK(tubp->irq, flags);
318 tty3270_try_logging(tubp);
319 TUBUNLOCK(tubp->irq, flags);
323 tty3270_write_room(struct tty_struct *tty)
328 if ((tubp = tty->driver_data) == NULL)
332 return ob->bc_len - ob->bc_cnt;
336 tty3270_chars_in_buffer(struct tty_struct *tty)
341 if ((tubp = tty->driver_data) == NULL)
349 tty3270_ioctl(struct tty_struct *tty, struct file *file,
350 unsigned int cmd, unsigned long arg)
355 struct termios termios;
357 if ((tubp = tty->driver_data) == NULL)
360 TUBLOCK(tubp->irq, flags);
361 if (tty->flags * (1 << TTY_IO_ERROR)) {
369 case TCFLSH: /* arg: 2 or 0 */
373 if (user_termios_to_kernel_termios(&termios,
374 (struct termios *)arg)) {
384 if (user_termio_to_kernel_termios(&termios,
385 (struct termio *)arg)) {
397 TUBUNLOCK(tubp->irq, flags);
402 tty3270_set_termios(struct tty_struct *tty, struct termios *old)
408 if ((tubp = tty->driver_data) == NULL)
411 if (tty3270_wait(tubp, &flags) != 0) {
412 TUBUNLOCK(tubp->irq, flags);
415 new = L_ICANON(tty)? L_ECHO(tty)? TF_INPUT: TF_INPUTN:
417 if (new != tubp->tty_inattr) {
418 tubp->tty_inattr = new;
419 tubp->cmd = TBC_CLRINPUT;
423 TUBUNLOCK(tubp->irq, flags);
427 tty3270_flush_buffer(struct tty_struct *tty)
433 if ((tubp = tty->driver_data) == NULL)
436 if (tubp->mode == TBM_FS && tubp->fs_pid != 0) {
437 kill_proc(tubp->fs_pid, SIGHUP, 1);
440 if ((tubp->flags & TUB_OPEN_STET) == 0) {
442 TUBLOCK(tubp->irq, flags);
446 TUBUNLOCK(tubp->irq, flags);
452 tty3270_read_proc(char *buf, char **start, off_t off, int count,
453 int *eof, void *data)
461 if (tty3270_proc_what == TW_CONFIG) {
463 * Describe the 3270 configuration in ascii lines.
464 * Line 1: 0 <fsmajor> 0
465 * Console line: <devnum> CONSOLE <minor>
466 * Other lines: <devnum> <ttymajor> <minor>
468 len += sprintf(buf + len, "0 %d 0\n", fs3270_major);
469 for (i = 1; i <= tubnummins; i++) {
470 tubp = (*tubminors)[i];
471 #ifdef CONFIG_TN3270_CONSOLE
472 if (CONSOLE_IS_3270 && tubp == tub3270_con_tubp)
473 len += sprintf(buf + len, "%.4x CONSOLE %d\n",
477 len += sprintf(buf + len, "%.4x %d %d\n",
478 tubp->devno, tty3270_major, i);
479 if (begin + len > off + count)
481 if (begin + len < off) {
488 if (off >= begin + len) {
491 *start = buf + off - begin;
492 rc = MIN(count, begin + len - off);
495 tty3270_proc_what = TW_BOGUS;
499 len += sprintf(buf, "There are %d devices. fs major is %d, "
500 "tty major is %d.\n", tubnummins, fs3270_major,
502 len += sprintf(buf+len, " index=%d data=%d misc=%d\n",
508 * Display info for the tube with minor nr in index
510 len += tty3270_show_tube(tty3270_proc_index, buf+len, count-len);
513 if (off >= begin + len)
515 *start = buf + off - begin;
516 return MIN(count, begin + len - off);
520 tty3270_write_proc(struct file *file, const char *buffer,
521 unsigned long count, void *data)
523 char mybuf[GEOM_MAXINPLEN];
526 struct tty_struct *tty;
530 mycount = MIN(count, sizeof mybuf - 1);
531 if (copy_from_user(mybuf, buffer, mycount) != 0)
533 mybuf[mycount] = '\0';
536 * User-mode settings affect only the current tty ---
540 device = tty? tty->device: 0;
542 if (MAJOR(device) == IBM_TTY3270_MAJOR)
543 tubp = (*tubminors)[MINOR(device)];
544 #ifdef CONFIG_TN3270_CONSOLE
545 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
546 if (CONSOLE_IS_3270 && device == S390_CONSOLE_DEV)
547 tubp = tub3270_con_tubp;
548 #endif /* LINUX_VERSION_CODE */
549 #endif /* CONFIG_TN3270_CONSOLE */
552 if ((rc = tty3270_aid_set(tubp, mybuf, mycount + 1)))
553 return rc > 0? count: rc;
554 if ((rc = tty3270_rcl_set(tubp, mybuf, mycount + 1)))
555 return rc > 0? count: rc;
556 if ((rc = tty3270_scl_set(tubp, mybuf, mycount + 1)))
557 return rc > 0? count: rc;
561 * Superuser-mode settings affect the driver overall ---
565 } else if (strncmp(mybuf, "index=", 6) == 0) {
566 tty3270_proc_index = simple_strtoul(mybuf + 6, 0,0);
568 } else if (strncmp(mybuf, "data=", 5) == 0) {
569 tty3270_proc_data = simple_strtoul(mybuf + 5, 0, 0);
571 } else if (strncmp(mybuf, "misc=", 5) == 0) {
572 tty3270_proc_misc = simple_strtoul(mybuf + 5, 0, 0);
574 } else if (strncmp(mybuf, "what=", 5) == 0) {
575 if (strcmp(mybuf+5, "bogus") == 0)
576 tty3270_proc_what = 0;
577 else if (strncmp(mybuf+5, "config", 6) == 0)
578 tty3270_proc_what = TW_CONFIG;
586 tty3270_hangup(struct tty_struct *tty)
589 extern void fs3270_release(tub_t *);
591 if ((tubp = tty->driver_data) == NULL)
593 tty3270_rcl_purge(tubp);
594 tty3270_aid_reinit(tubp);
595 fs3270_release(tubp);
600 * tty3270_bh(tubp) -- Perform back-half processing
603 tty3270_bh(void *data)
608 struct tty_struct *tty;
610 ioinfop = ioinfo[(tubp = data)->irq];
611 while (TUBTRYLOCK(tubp->irq, flags) == 0) {
612 if (ioinfop->ui.flags.unready == 1)
615 if (ioinfop->ui.flags.unready == 1 ||
616 ioinfop->ui.flags.ready == 0)
619 tubp->flags &= ~TUB_BHPENDING;
622 if (tubp->flags & TUB_UNSOL_DE) {
623 tubp->flags &= ~TUB_UNSOL_DE;
626 wake_up_interruptible(&tubp->waitq);
631 if (tubp->flags & TUB_IACTIVE) { /* If read ended, */
632 tty3270_do_input(tubp);
633 tubp->flags &= ~TUB_IACTIVE;
636 if ((tubp->flags & TUB_WORKING) == 0) {
637 if (tubp->flags & TUB_ATTN) {
638 tty3270_start_input(tubp);
639 tubp->flags &= ~TUB_ATTN;
640 } else if (tty3270_try_logging(tubp) == 0) {
641 wake_up_interruptible(&tubp->waitq);
649 TUBUNLOCK(tubp->irq, flags);
653 * tty3270_sched_bh(tubp) -- Schedule the back half
654 * Irq lock must be held on entry and remains held on exit.
657 tty3270_sched_bh(tub_t *tubp)
659 if (tubp->flags & TUB_BHPENDING)
661 tubp->flags |= TUB_BHPENDING;
662 tubp->tqueue.routine = tty3270_bh;
663 tubp->tqueue.data = tubp;
664 queue_task(&tubp->tqueue, &tq_immediate);
665 mark_bh(IMMEDIATE_BH);
669 * tty3270_io() -- Perform line-mode reads and writes here
672 tty3270_io(tub_t *tubp)
677 tubp->flags |= TUB_WORKING;
679 ccwp = &tubp->ttyccw;
681 rc = do_IO(tubp->irq, ccwp, tubp->irq, 0, 0);
686 * tty3270_wait(tubp) -- Wait until TUB_WORKING is off
687 * On entry the lock must not be held; on exit it is held.
690 tty3270_wait(tub_t *tubp, long *flags)
692 DECLARE_WAITQUEUE(wait, current);
694 TUBLOCK(tubp->irq, *flags);
695 add_wait_queue(&tubp->waitq, &wait);
696 while (!signal_pending(current) &&
697 (tubp->flags & TUB_WORKING) != 0) {
698 current->state = TASK_INTERRUPTIBLE;
699 TUBUNLOCK(tubp->irq, *flags);
701 current->state = TASK_RUNNING;
702 TUBLOCK(tubp->irq, *flags);
704 remove_wait_queue(&tubp->waitq, &wait);
705 return signal_pending(current)? -ERESTARTSYS: 0;
709 tty3270_int(tub_t *tubp, devstat_t *dsp)
711 #define DEV_UE_BUSY \
712 (DEV_STAT_CHN_END | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP)
713 #define DEV_NOT_WORKING \
714 (DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_CHECK)
716 tubp->dstat = dsp->dstat;
718 /* Handle CE-DE-UE and subsequent UDE */
719 if (dsp->dstat == DEV_UE_BUSY) {
720 tubp->flags |= TUB_UE_BUSY;
722 } else if (tubp->flags & TUB_UE_BUSY) {
723 tubp->flags &= ~TUB_UE_BUSY;
724 if (dsp->dstat == DEV_STAT_DEV_END &&
725 (tubp->flags & TUB_WORKING) != 0) {
732 if (dsp->dstat & DEV_STAT_ATTENTION)
733 tubp->flags |= TUB_ATTN;
735 if (dsp->dstat & DEV_STAT_CHN_END) {
736 tubp->cswl = dsp->rescnt;
737 if ((dsp->dstat & DEV_STAT_DEV_END) == 0)
738 tubp->flags |= TUB_EXPECT_DE;
740 tubp->flags &= ~TUB_EXPECT_DE;
741 } else if (dsp->dstat & DEV_STAT_DEV_END) {
742 if ((tubp->flags & TUB_EXPECT_DE) == 0)
743 tubp->flags |= TUB_UNSOL_DE;
744 tubp->flags &= ~TUB_EXPECT_DE;
746 if (dsp->dstat & DEV_NOT_WORKING)
747 tubp->flags &= ~TUB_WORKING;
748 if (dsp->dstat & DEV_STAT_UNIT_CHECK)
749 tubp->sense = dsp->ii.sense;
750 if ((tubp->flags & TUB_WORKING) == 0)
751 tty3270_sched_bh(tubp);
755 * tty3270_refresh(), called by fs3270_close() when tubp->fsopen == 0.
756 * On entry, lock is held.
759 tty3270_refresh(tub_t *tubp)
763 tubp->intv = tty3270_int;
764 tty3270_scl_resettimer(tubp);
765 tubp->cmd = TBC_UPDATE;
771 tty3270_try_logging(tub_t *tubp)
773 if (tubp->flags & TUB_WORKING)
775 if (tubp->mode == TBM_FS)
777 if (tubp->stat == TBS_HOLD)
779 if (tubp->stat == TBS_MORE)
781 #ifdef CONFIG_TN3270_CONSOLE
782 if (CONSOLE_IS_3270 && tub3270_con_tubp == tubp)
783 tub3270_con_copy(tubp);
784 #endif /* CONFIG_TN3270_CONSOLE */
785 if (tubp->tty_bcb.bc_cnt == 0)
787 if (tubp->intv != tty3270_int)
789 tubp->cmd = TBC_UPDLOG;
790 return tty3270_build(tubp);
793 /* tty3270 utility functions */
796 tty3270_start_input(tub_t *tubp)
798 if (tubp->tty_input == NULL)
800 tubp->ttyccw.cda = virt_to_phys(tubp->tty_input);
801 tubp->ttyccw.cmd_code = TC_READMOD;
802 tubp->ttyccw.count = GEOM_INPLEN;
803 tubp->ttyccw.flags = CCW_FLAG_SLI;
805 tubp->flags |= TUB_IACTIVE;
809 tty3270_do_input(tub_t *tubp)
816 count = GEOM_INPLEN - tubp->cswl;
817 if ((in = tubp->tty_input) == NULL)
819 tty3270_aid_get(tubp, in[0], &aidflags, &aidstring);
821 if (aidflags & TA_CLEARKEY) {
822 tubp->stat = TBS_RUNNING;
823 tty3270_scl_resettimer(tubp);
824 tubp->cmd = TBC_UPDATE;
825 } else if (aidflags & TA_CLEARLOG) {
826 tubp->stat = TBS_RUNNING;
827 tty3270_scl_resettimer(tubp);
828 tubp->cmd = TBC_CLRUPDLOG;
829 } else if (aidflags & TA_DOENTER) {
833 tubp->stat = TBS_HOLD;
834 tty3270_scl_resettimer(tubp);
837 tubp->stat = TBS_MORE;
838 tty3270_scl_settimer(tubp);
841 tty3270_do_enter(tubp, in + 6, 0);
844 tubp->cmd = TBC_UPDSTAT;
849 TUB_EBCASC(in, count);
850 tubp->cmd = TBC_CLRINPUT;
851 tty3270_do_enter(tubp, in, count);
852 } else if ((aidflags & TA_DOSTRING) != 0 && aidstring != NULL) {
853 tubp->cmd = TBC_KRUPDLOG;
854 tty3270_do_enter(tubp, aidstring, strlen(aidstring));
855 } else if ((aidflags & TA_DOSTRINGD) != 0 && aidstring != NULL) {
856 tty3270_do_showi(tubp, aidstring, strlen(aidstring));
857 tubp->cmd = TBC_UPDINPUT;
860 tubp->flags |= TUB_ALARM;
861 tubp->cmd = TBC_KRUPDLOG;
868 tty3270_do_enter(tub_t *tubp, char *cp, int count)
870 struct tty_struct *tty;
873 if ((tty = tubp->tty) == NULL)
877 if (count == 2 && (cp[0] == '^' || cp[0] == '\252')) {
880 func = INTR_CHAR(tty);
883 func = EOF_CHAR(tty);
886 func = SUSP_CHAR(tty);
889 } else if (count == 2 && cp[0] == 0x1b) { /* if ESC */
891 char buf[GEOM_INPLEN + 1];
904 len = tty3270_rcl_get(tubp, buf, sizeof buf, inc);
906 tubp->flags |= TUB_ALARM;
909 tty3270_do_showi(tubp, buf, len);
910 tubp->cmd = TBC_UPDINPUT;
915 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
916 *tty->flip.char_buf_ptr++ = func;
919 tty3270_rcl_put(tubp, cp, count);
920 memcpy(tty->flip.char_buf_ptr, cp, count);
921 /* Add newline unless line ends with "^n" */
922 if (count < 2 || cp[count - 1] != 'n' ||
923 (cp[count - 2] != '^' && cp[count - 2] != '\252')) {
924 tty->flip.char_buf_ptr[count] = '\n';
927 count -= 2; /* Lop trailing "^n" from text */
929 memset(tty->flip.flag_buf_ptr, TTY_NORMAL, count);
930 tty->flip.char_buf_ptr += count;
931 tty->flip.flag_buf_ptr += count;
932 tty->flip.count += count;
934 tty_flip_buffer_push(tty);
938 tty3270_do_showi(tub_t *tubp, char *cp, int cl)
940 if (cl > GEOM_INPLEN)
942 memset(tubp->tty_input, 0, GEOM_INPLEN);
943 memcpy(tubp->tty_input, cp, cl);
944 TUB_ASCEBC(tubp->tty_input, cl);
949 /* Debugging routine */
951 tty3270_show_tube(int minor, char *buf, int count)
954 struct tty_struct *tty;
958 /*012345678901234567890123456789012345678901234567890123456789 */
959 /*Info for tub_t[dd] at xxxxxxxx: */
960 /* geom: rows=dd cols=dd model=d */
961 /* lnopen=dd fsopen=dd waitq=xxxxxxxx */
962 /* dstat=xx mode=dd stat=dd flags=xxxx */
963 /* oucount=dddd ourd=ddddd ouwr=ddddd nextlogx=ddddd */
965 /* write_wait=xxxxxxxx read_wait=xxxxxxxx */
966 /* iflag=xxxxxxxx oflag=xxxxxxxx cflag=xxxxxxxx lflag=xxxxxxxx */
968 if (minor < 0 || minor > tubnummins ||
969 (tubp = (*tubminors)[minor]) == NULL)
970 return sprintf(buf, "No tube at index=%d\n", minor);
975 len += sprintf(buf+len, "Info for tub_t[%d] at %p:\n", minor, tubp);
977 len += sprintf(buf+len, "inattr is at %p\n", &tubp->tty_inattr);
980 len += sprintf(buf+len, " geom: rows=%.2d cols=%.2d model=%.1d\n",
981 tubp->geom_rows, tubp->geom_cols, tubp->tubiocb.model);
983 len += sprintf(buf+len,
984 " lnopen=%-2d fsopen=%-2d waitq=%p\n",
985 tubp->lnopen, tubp->fsopen, &tubp->waitq);
987 len += sprintf(buf+len, " dstat=%.2x mode=%-2d "
988 "stat=%-2d flags=%-4x\n", tubp->dstat,
989 tubp->mode, tubp->stat, tubp->flags);
992 len += sprintf(buf+len,
993 " oucount=%-4d ourd=%-5d ouwr=%-5d"
994 " nextlogx=%-5d\n", tubp->tty_oucount,
995 tubp->tty_ourd, tubp->tty_ouwr, tubp->tty_nextlogx);
998 len += sprintf(buf+len, " tty=%p\n",tubp->tty);
1001 len += sprintf(buf+len,
1002 " write_wait=%p read_wait=%p\n",
1003 &tty->write_wait, &tty->read_wait);
1005 if (tty && ((mp = tty->termios)))
1006 len += sprintf(buf+len," iflag=%.8x oflag=%.8x "
1007 "cflag=%.8x lflag=%.8x\n", mp->c_iflag,
1008 mp->c_oflag, mp->c_cflag, mp->c_lflag);