| 1052 | } |
| 1053 | |
| 1054 | struct tty * |
| 1055 | tty_alloc_mutex(struct ttydevsw *tsw, void *sc, struct mtx *mutex) |
| 1056 | { |
| 1057 | struct tty *tp; |
| 1058 | |
| 1059 | /* Make sure the driver defines all routines. */ |
| 1060 | #define PATCH_FUNC(x) do { \ |
| 1061 | if (tsw->tsw_ ## x == NULL) \ |
| 1062 | tsw->tsw_ ## x = ttydevsw_def ## x; \ |
| 1063 | } while (0) |
| 1064 | PATCH_FUNC(open); |
| 1065 | PATCH_FUNC(close); |
| 1066 | PATCH_FUNC(outwakeup); |
| 1067 | PATCH_FUNC(inwakeup); |
| 1068 | PATCH_FUNC(ioctl); |
| 1069 | PATCH_FUNC(cioctl); |
| 1070 | PATCH_FUNC(param); |
| 1071 | PATCH_FUNC(modem); |
| 1072 | PATCH_FUNC(mmap); |
| 1073 | PATCH_FUNC(pktnotify); |
| 1074 | PATCH_FUNC(free); |
| 1075 | PATCH_FUNC(busy); |
| 1076 | #undef PATCH_FUNC |
| 1077 | |
| 1078 | tp = malloc(sizeof(struct tty) + TTY_PRBUF_SIZE, M_TTY, |
| 1079 | M_WAITOK | M_ZERO); |
| 1080 | tp->t_prbufsz = TTY_PRBUF_SIZE; |
| 1081 | tp->t_devsw = tsw; |
| 1082 | tp->t_devswsoftc = sc; |
| 1083 | tp->t_flags = tsw->tsw_flags; |
| 1084 | tp->t_drainwait = tty_drainwait; |
| 1085 | |
| 1086 | tty_init_termios(tp); |
| 1087 | |
| 1088 | cv_init(&tp->t_inwait, "ttyin"); |
| 1089 | cv_init(&tp->t_outwait, "ttyout"); |
| 1090 | cv_init(&tp->t_outserwait, "ttyosr"); |
| 1091 | cv_init(&tp->t_bgwait, "ttybg"); |
| 1092 | cv_init(&tp->t_dcdwait, "ttydcd"); |
| 1093 | |
| 1094 | /* Allow drivers to use a custom mutex to lock the TTY. */ |
| 1095 | if (mutex != NULL) { |
| 1096 | tp->t_mtx = mutex; |
| 1097 | } else { |
| 1098 | tp->t_mtx = &tp->t_mtxobj; |
| 1099 | mtx_init(&tp->t_mtxobj, "ttymtx", NULL, MTX_DEF); |
| 1100 | } |
| 1101 | |
| 1102 | knlist_init_mtx(&tp->t_inpoll.si_note, tp->t_mtx); |
| 1103 | knlist_init_mtx(&tp->t_outpoll.si_note, tp->t_mtx); |
| 1104 | |
| 1105 | return (tp); |
| 1106 | } |
| 1107 | |
| 1108 | static void |
| 1109 | tty_dealloc(void *arg) |
no test coverage detected