aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt/vt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/vt/vt.c')
-rw-r--r--drivers/tty/vt/vt.c141
1 files changed, 54 insertions, 87 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 84cbf298c094..999ca63afdef 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -537,45 +537,27 @@ void complement_pos(struct vc_data *vc, int offset)
537 537
538static void insert_char(struct vc_data *vc, unsigned int nr) 538static void insert_char(struct vc_data *vc, unsigned int nr)
539{ 539{
540 unsigned short *p, *q = (unsigned short *)vc->vc_pos; 540 unsigned short *p = (unsigned short *) vc->vc_pos;
541 541
542 p = q + vc->vc_cols - nr - vc->vc_x; 542 scr_memmovew(p + nr, p, vc->vc_cols - vc->vc_x);
543 while (--p >= q) 543 scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
544 scr_writew(scr_readw(p), p + nr);
545 scr_memsetw(q, vc->vc_video_erase_char, nr * 2);
546 vc->vc_need_wrap = 0; 544 vc->vc_need_wrap = 0;
547 if (DO_UPDATE(vc)) { 545 if (DO_UPDATE(vc))
548 unsigned short oldattr = vc->vc_attr; 546 do_update_region(vc, (unsigned long) p,
549 vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x, vc->vc_y, vc->vc_x + nr, 1, 547 (vc->vc_cols - vc->vc_x) / 2 + 1);
550 vc->vc_cols - vc->vc_x - nr);
551 vc->vc_attr = vc->vc_video_erase_char >> 8;
552 while (nr--)
553 vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, vc->vc_x + nr);
554 vc->vc_attr = oldattr;
555 }
556} 548}
557 549
558static void delete_char(struct vc_data *vc, unsigned int nr) 550static void delete_char(struct vc_data *vc, unsigned int nr)
559{ 551{
560 unsigned int i = vc->vc_x; 552 unsigned short *p = (unsigned short *) vc->vc_pos;
561 unsigned short *p = (unsigned short *)vc->vc_pos;
562 553
563 while (++i <= vc->vc_cols - nr) { 554 scr_memcpyw(p, p + nr, vc->vc_cols - vc->vc_x - nr);
564 scr_writew(scr_readw(p+nr), p); 555 scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char,
565 p++; 556 nr * 2);
566 }
567 scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
568 vc->vc_need_wrap = 0; 557 vc->vc_need_wrap = 0;
569 if (DO_UPDATE(vc)) { 558 if (DO_UPDATE(vc))
570 unsigned short oldattr = vc->vc_attr; 559 do_update_region(vc, (unsigned long) p,
571 vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x + nr, vc->vc_y, vc->vc_x, 1, 560 (vc->vc_cols - vc->vc_x) / 2);
572 vc->vc_cols - vc->vc_x - nr);
573 vc->vc_attr = vc->vc_video_erase_char >> 8;
574 while (nr--)
575 vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y,
576 vc->vc_cols - 1 - nr);
577 vc->vc_attr = oldattr;
578 }
579} 561}
580 562
581static int softcursor_original; 563static int softcursor_original;
@@ -1172,45 +1154,26 @@ static void csi_J(struct vc_data *vc, int vpar)
1172 case 0: /* erase from cursor to end of display */ 1154 case 0: /* erase from cursor to end of display */
1173 count = (vc->vc_scr_end - vc->vc_pos) >> 1; 1155 count = (vc->vc_scr_end - vc->vc_pos) >> 1;
1174 start = (unsigned short *)vc->vc_pos; 1156 start = (unsigned short *)vc->vc_pos;
1175 if (DO_UPDATE(vc)) {
1176 /* do in two stages */
1177 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
1178 vc->vc_cols - vc->vc_x);
1179 vc->vc_sw->con_clear(vc, vc->vc_y + 1, 0,
1180 vc->vc_rows - vc->vc_y - 1,
1181 vc->vc_cols);
1182 }
1183 break; 1157 break;
1184 case 1: /* erase from start to cursor */ 1158 case 1: /* erase from start to cursor */
1185 count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1; 1159 count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
1186 start = (unsigned short *)vc->vc_origin; 1160 start = (unsigned short *)vc->vc_origin;
1187 if (DO_UPDATE(vc)) {
1188 /* do in two stages */
1189 vc->vc_sw->con_clear(vc, 0, 0, vc->vc_y,
1190 vc->vc_cols);
1191 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1192 vc->vc_x + 1);
1193 }
1194 break; 1161 break;
1195 case 3: /* erase scroll-back buffer (and whole display) */ 1162 case 3: /* erase scroll-back buffer (and whole display) */
1196 scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, 1163 scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
1197 vc->vc_screenbuf_size >> 1); 1164 vc->vc_screenbuf_size >> 1);
1198 set_origin(vc); 1165 set_origin(vc);
1199 if (CON_IS_VISIBLE(vc))
1200 update_screen(vc);
1201 /* fall through */ 1166 /* fall through */
1202 case 2: /* erase whole display */ 1167 case 2: /* erase whole display */
1203 count = vc->vc_cols * vc->vc_rows; 1168 count = vc->vc_cols * vc->vc_rows;
1204 start = (unsigned short *)vc->vc_origin; 1169 start = (unsigned short *)vc->vc_origin;
1205 if (DO_UPDATE(vc))
1206 vc->vc_sw->con_clear(vc, 0, 0,
1207 vc->vc_rows,
1208 vc->vc_cols);
1209 break; 1170 break;
1210 default: 1171 default:
1211 return; 1172 return;
1212 } 1173 }
1213 scr_memsetw(start, vc->vc_video_erase_char, 2 * count); 1174 scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
1175 if (DO_UPDATE(vc))
1176 do_update_region(vc, (unsigned long) start, count);
1214 vc->vc_need_wrap = 0; 1177 vc->vc_need_wrap = 0;
1215} 1178}
1216 1179
@@ -1223,29 +1186,22 @@ static void csi_K(struct vc_data *vc, int vpar)
1223 case 0: /* erase from cursor to end of line */ 1186 case 0: /* erase from cursor to end of line */
1224 count = vc->vc_cols - vc->vc_x; 1187 count = vc->vc_cols - vc->vc_x;
1225 start = (unsigned short *)vc->vc_pos; 1188 start = (unsigned short *)vc->vc_pos;
1226 if (DO_UPDATE(vc))
1227 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
1228 vc->vc_cols - vc->vc_x);
1229 break; 1189 break;
1230 case 1: /* erase from start of line to cursor */ 1190 case 1: /* erase from start of line to cursor */
1231 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); 1191 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
1232 count = vc->vc_x + 1; 1192 count = vc->vc_x + 1;
1233 if (DO_UPDATE(vc))
1234 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1235 vc->vc_x + 1);
1236 break; 1193 break;
1237 case 2: /* erase whole line */ 1194 case 2: /* erase whole line */
1238 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); 1195 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
1239 count = vc->vc_cols; 1196 count = vc->vc_cols;
1240 if (DO_UPDATE(vc))
1241 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1242 vc->vc_cols);
1243 break; 1197 break;
1244 default: 1198 default:
1245 return; 1199 return;
1246 } 1200 }
1247 scr_memsetw(start, vc->vc_video_erase_char, 2 * count); 1201 scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
1248 vc->vc_need_wrap = 0; 1202 vc->vc_need_wrap = 0;
1203 if (DO_UPDATE(vc))
1204 do_update_region(vc, (unsigned long) start, count);
1249} 1205}
1250 1206
1251static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */ 1207static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */
@@ -1380,7 +1336,7 @@ static void respond_string(const char *p, struct tty_struct *tty)
1380 tty_insert_flip_char(tty, *p, 0); 1336 tty_insert_flip_char(tty, *p, 0);
1381 p++; 1337 p++;
1382 } 1338 }
1383 con_schedule_flip(tty); 1339 tty_schedule_flip(tty);
1384} 1340}
1385 1341
1386static void cursor_report(struct vc_data *vc, struct tty_struct *tty) 1342static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
@@ -2792,41 +2748,52 @@ static void con_flush_chars(struct tty_struct *tty)
2792/* 2748/*
2793 * Allocate the console screen memory. 2749 * Allocate the console screen memory.
2794 */ 2750 */
2795static int con_open(struct tty_struct *tty, struct file *filp) 2751static int con_install(struct tty_driver *driver, struct tty_struct *tty)
2796{ 2752{
2797 unsigned int currcons = tty->index; 2753 unsigned int currcons = tty->index;
2798 int ret = 0; 2754 struct vc_data *vc;
2755 int ret;
2799 2756
2800 console_lock(); 2757 console_lock();
2801 if (tty->driver_data == NULL) { 2758 ret = vc_allocate(currcons);
2802 ret = vc_allocate(currcons); 2759 if (ret)
2803 if (ret == 0) { 2760 goto unlock;
2804 struct vc_data *vc = vc_cons[currcons].d;
2805 2761
2806 /* Still being freed */ 2762 vc = vc_cons[currcons].d;
2807 if (vc->port.tty) {
2808 console_unlock();
2809 return -ERESTARTSYS;
2810 }
2811 tty->driver_data = vc;
2812 vc->port.tty = tty;
2813 2763
2814 if (!tty->winsize.ws_row && !tty->winsize.ws_col) { 2764 /* Still being freed */
2815 tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; 2765 if (vc->port.tty) {
2816 tty->winsize.ws_col = vc_cons[currcons].d->vc_cols; 2766 ret = -ERESTARTSYS;
2817 } 2767 goto unlock;
2818 if (vc->vc_utf)
2819 tty->termios->c_iflag |= IUTF8;
2820 else
2821 tty->termios->c_iflag &= ~IUTF8;
2822 console_unlock();
2823 return ret;
2824 }
2825 } 2768 }
2769
2770 ret = tty_port_install(&vc->port, driver, tty);
2771 if (ret)
2772 goto unlock;
2773
2774 tty->driver_data = vc;
2775 vc->port.tty = tty;
2776
2777 if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
2778 tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
2779 tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
2780 }
2781 if (vc->vc_utf)
2782 tty->termios.c_iflag |= IUTF8;
2783 else
2784 tty->termios.c_iflag &= ~IUTF8;
2785unlock:
2826 console_unlock(); 2786 console_unlock();
2827 return ret; 2787 return ret;
2828} 2788}
2829 2789
2790static int con_open(struct tty_struct *tty, struct file *filp)
2791{
2792 /* everything done in install */
2793 return 0;
2794}
2795
2796
2830static void con_close(struct tty_struct *tty, struct file *filp) 2797static void con_close(struct tty_struct *tty, struct file *filp)
2831{ 2798{
2832 /* Nothing to do - we defer to shutdown */ 2799 /* Nothing to do - we defer to shutdown */
@@ -2839,7 +2806,6 @@ static void con_shutdown(struct tty_struct *tty)
2839 console_lock(); 2806 console_lock();
2840 vc->port.tty = NULL; 2807 vc->port.tty = NULL;
2841 console_unlock(); 2808 console_unlock();
2842 tty_shutdown(tty);
2843} 2809}
2844 2810
2845static int default_italic_color = 2; // green (ASCII) 2811static int default_italic_color = 2; // green (ASCII)
@@ -2947,6 +2913,7 @@ static int __init con_init(void)
2947console_initcall(con_init); 2913console_initcall(con_init);
2948 2914
2949static const struct tty_operations con_ops = { 2915static const struct tty_operations con_ops = {
2916 .install = con_install,
2950 .open = con_open, 2917 .open = con_open,
2951 .close = con_close, 2918 .close = con_close,
2952 .write = con_write, 2919 .write = con_write,