patch-2.3.47 linux/drivers/char/vc_screen.c
Next file: linux/drivers/char/vt.c
Previous file: linux/drivers/char/sysrq.c
Back to the patch index
Back to the overall index
- Lines: 130
- Date:
Sun Feb 20 20:19:12 2000
- Orig file:
v2.3.46/linux/drivers/char/vc_screen.c
- Orig date:
Wed Feb 16 17:03:52 2000
diff -u --recursive --new-file v2.3.46/linux/drivers/char/vc_screen.c linux/drivers/char/vc_screen.c
@@ -21,6 +21,7 @@
* - making it shorter - scr_readw are macros which expand in PRETTY long code
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/errno.h>
@@ -37,6 +38,7 @@
#include <linux/console.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#undef attr
#undef org
@@ -175,71 +177,58 @@
con_buf0[1] = (char) video_num_columns;
getconsxy(currcons, con_buf0 + 2);
- tmp_count = HEADER_SIZE - p;
+ con_buf_start += p;
+ this_round += p;
+ if (this_round > CON_BUF_SIZE) {
+ this_round = CON_BUF_SIZE;
+ orig_count = this_round - p;
+ }
+
+ tmp_count = HEADER_SIZE;
if (tmp_count > this_round)
tmp_count = this_round;
/* Advance state pointers and move on. */
this_round -= tmp_count;
- con_buf_start += p;
- orig_count -= p;
- p += tmp_count;
- con_buf0 = con_buf + p;
+ p = HEADER_SIZE;
+ con_buf0 = con_buf + HEADER_SIZE;
+ /* If this_round >= 0, then p is even... */
+ } else if (p & 1) {
+ /* Skip first byte for output if start address is odd
+ * Update region sizes up/down depending on free
+ * space in buffer.
+ */
+ con_buf_start++;
+ if (this_round < CON_BUF_SIZE)
+ this_round++;
+ else
+ orig_count--;
}
- p -= HEADER_SIZE;
- col = (p/2) % maxcol;
if (this_round > 0) {
- char tmp_byte;
-
- org = screen_pos(currcons, p/2, viewed);
- if ((p & 1) && this_round > 0) {
-#ifdef __BIG_ENDIAN
- tmp_byte = vcs_scr_readw(currcons, org++) & 0xff;
-#else
- tmp_byte = vcs_scr_readw(currcons, org++) >> 8;
-#endif
-
- *con_buf0++ = tmp_byte;
+ unsigned short *tmp_buf = (unsigned short *)con_buf0;
- this_round--;
- p++;
- if (++col == maxcol) {
- org = screen_pos(currcons, p/2, viewed);
- col = 0;
- }
- }
+ p -= HEADER_SIZE;
p /= 2;
+ col = p % maxcol;
+
+ org = screen_pos(currcons, p, viewed);
p += maxcol - col;
- }
- if (this_round > 1) {
- size_t tmp_count = this_round;
- unsigned short *tmp_buf = (unsigned short *)con_buf0;
+ /* Buffer has even length, so we can always copy
+ * character + attribute. We do not copy last byte
+ * to userspace if this_round is odd.
+ */
+ this_round = (this_round + 1) >> 1;
- while (tmp_count > 1) {
+ while (this_round) {
*tmp_buf++ = vcs_scr_readw(currcons, org++);
- tmp_count -= 2;
+ this_round --;
if (++col == maxcol) {
org = screen_pos(currcons, p, viewed);
col = 0;
p += maxcol;
}
}
-
- /* Advance pointers, and move on. */
- this_round = tmp_count;
- con_buf0 = (char*)tmp_buf;
- }
- if (this_round > 0) {
- char tmp_byte;
-
-#ifdef __BIG_ENDIAN
- tmp_byte = vcs_scr_readw(currcons, org) >> 8;
-#else
- tmp_byte = vcs_scr_readw(currcons, org) & 0xff;
-#endif
-
- *con_buf0++ = tmp_byte;
}
}
@@ -415,7 +404,7 @@
while (this_round > 1) {
unsigned short w;
- w = *((const unsigned short *)con_buf0);
+ w = get_unaligned(((const unsigned short *)con_buf0));
vcs_scr_writew(currcons, w, org++);
con_buf0 += 2;
this_round -= 2;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)