Commit b960c886 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.1

parent 61fbe25f
VERSION = 1 VERSION = 1
PATCHLEVEL = 3 PATCHLEVEL = 3
SUBLEVEL = 0 SUBLEVEL = 1
ARCH = i386 ARCH = i386
...@@ -236,6 +236,7 @@ clean: archclean ...@@ -236,6 +236,7 @@ clean: archclean
mrproper: clean mrproper: clean
rm -f include/linux/autoconf.h include/linux/version.h rm -f include/linux/autoconf.h include/linux/version.h
rm -f drivers/sound/local.h rm -f drivers/sound/local.h
rm -f drivers/char/uni_hash_tbl.h drivers/char/conmakehash
rm -f .version .config* config.in config.old rm -f .version .config* config.in config.old
rm -f include/asm rm -f include/asm
rm -f .depend `find . -name .depend -print` rm -f .depend `find . -name .depend -print`
......
Linux kernel release 1.2.xx Linux kernel release 1.3.xx
These are the release notes for linux version 1.2. Read them carefully, These are the release notes for linux version 1.3. Read them carefully,
as they tell you what this is all about, explain how to install the as they tell you what this is all about, explain how to install the
kernel, and what to do if something goes wrong. kernel, and what to do if something goes wrong.
Linux version 1.3 is a DEVELOPMENT kernel, and not intended for general
public use. Different releases may have various and sometimes severe
bugs. It is *strongly* recommended that you back up the previous kernel
before installing any new 1.3.xx release.
If you need to use a proven and stable Linux kernel, please use either
1.0.9 or 1.2.xx. All features which will be in the 1.3.xx releases will
be contained in 1.4.xx when the code base has stabilized again.
If you decide to use 1.3, it is recommended that you join the kernel mailing
list. To do this, e-mail majordomo@vger.rutgers.edu, and put in the body
of the message "subscribe linux-kernel" or "subscribe linux-kernel-digest"
for a daily digest of the mailing list (it is a high-traffic list.)
WHAT IS LINUX? WHAT IS LINUX?
Linux is a Unix clone for 386/486-based PCs written from scratch by Linux is a Unix clone for 386/486-based PCs written from scratch by
...@@ -33,12 +47,13 @@ INSTALLING the kernel: ...@@ -33,12 +47,13 @@ INSTALLING the kernel:
- If you install the full sources, do a - If you install the full sources, do a
cd /usr/src cd /usr/src
gzip -cd linux-1.2.XX.tar.gz | tar xfv - gzip -cd linux-1.3.XX.tar.gz | tar xfv -
to get it all put in place. Replace "XX" with the version number of the to get it all put in place. Replace "XX" with the version number of the
latest kernel. latest kernel.
- Installing by patching is not worth the effort because the full set of - You can also upgrade between 1.3.xx releases by patching. For a large
set of revisions, it is not worth the effort since the full set of
patches is bigger than a new kernel distribution. Instead, get the patches is bigger than a new kernel distribution. Instead, get the
latest full source archive and install as above. Then, get all newer latest full source archive and install as above. Then, get all newer
patch files, and do patch files, and do
...@@ -105,7 +120,8 @@ COMPILING the kernel: ...@@ -105,7 +120,8 @@ COMPILING the kernel:
versions can have problems compiling newer versions of linux. If you versions can have problems compiling newer versions of linux. If you
upgrade your compiler, remember to get the new binutils package too upgrade your compiler, remember to get the new binutils package too
(for as/ld/nm and company). Do not use gcc-2.6.0; it has a few serious (for as/ld/nm and company). Do not use gcc-2.6.0; it has a few serious
bugs. bugs. Some problems have been reported occasionally with 2.6.3 as well,
so use that version at your own risk.
- do a "make zImage" to create a compressed kernel image. If you want - do a "make zImage" to create a compressed kernel image. If you want
to make a bootdisk (without root filesystem or lilo), insert a floppy to make a bootdisk (without root filesystem or lilo), insert a floppy
...@@ -113,7 +129,9 @@ COMPILING the kernel: ...@@ -113,7 +129,9 @@ COMPILING the kernel:
"make zlilo" if you have lilo installed to suit the kernel makefiles, "make zlilo" if you have lilo installed to suit the kernel makefiles,
but you may want to check your particular lilo setup first. but you may want to check your particular lilo setup first.
- keep a backup kernel handy in case something goes wrong. - keep a backup kernel handy in case something goes wrong. This is
especially true for the development releases, since each new release
contains new code which has not been debugged.
- In order to boot your new kernel, you'll need to copy the kernel - In order to boot your new kernel, you'll need to copy the kernel
image (found in /usr/src/linux/arch/i386/boot/zImage after compilation) image (found in /usr/src/linux/arch/i386/boot/zImage after compilation)
......
...@@ -175,6 +175,11 @@ novga: mov [14],ax ...@@ -175,6 +175,11 @@ novga: mov [14],ax
int 0x10 int 0x10
mov [4],bx ! bh = display page mov [4],bx ! bh = display page
mov [6],ax ! al = video mode, ah = window width mov [6],ax ! al = video mode, ah = window width
xor ax,ax
mov es,ax ! Access low memory
seg es
mov ax,[0x485] ! POINTS - Height of character matrix
mov [16],ax
! Get hd0 data ! Get hd0 data
......
...@@ -16,6 +16,11 @@ ...@@ -16,6 +16,11 @@
.c.o: .c.o:
$(CC) $(CFLAGS) -c $< $(CC) $(CFLAGS) -c $<
#
# This file contains the font map for the default (hardware) font
#
FONTMAPFILE = cp437.uni
OBJS = tty_io.o n_tty.o console.o keyboard.o serial.o \ OBJS = tty_io.o n_tty.o console.o keyboard.o serial.o \
tty_ioctl.o pty.o vt.o mem.o vc_screen.o \ tty_ioctl.o pty.o vt.o mem.o vc_screen.o \
defkeymap.o consolemap.o vesa_blank.o selection.o defkeymap.o consolemap.o vesa_blank.o selection.o
...@@ -24,7 +29,6 @@ SRCS = tty_io.c n_tty.c console.c keyboard.c serial.c \ ...@@ -24,7 +29,6 @@ SRCS = tty_io.c n_tty.c console.c keyboard.c serial.c \
tty_ioctl.c pty.c vt.c mem.c vc_screen.c \ tty_ioctl.c pty.c vt.c mem.c vc_screen.c \
defkeymap.c consolemap.c vesa_blank.c selection.c defkeymap.c consolemap.c vesa_blank.c selection.c
ifdef CONFIG_CYCLADES ifdef CONFIG_CYCLADES
OBJS := $(OBJS) cyclades.o OBJS := $(OBJS) cyclades.o
SRCS := $(SRCS) cyclades.c SRCS := $(SRCS) cyclades.c
...@@ -98,7 +102,7 @@ modules: ...@@ -98,7 +102,7 @@ modules:
endif endif
dep: dep: uni_hash_tbl.h
$(CPP) -M $(SRCS) > .depend $(CPP) -M $(SRCS) > .depend
ifdef MODULES ifdef MODULES
$(CPP) -M -DMODULE $(MODULES:.o=.c) >> .depend $(CPP) -M -DMODULE $(MODULES:.o=.c) >> .depend
...@@ -106,6 +110,12 @@ endif ...@@ -106,6 +110,12 @@ endif
dummy: dummy:
conhakehash: conmakehash.c
$(HOSTCC) -o conmakehash conmakehash.c
uni_hash_tbl.h: $(FONTMAPFILE) conmakehash
./conmakehash $(FONTMAPFILE) 641 283 6 > uni_hash_tbl.h
# #
# include a dependency file if one exists # include a dependency file if one exists
# #
......
The Linux kernel code has been rewritten to use Unicode to map
characters to fonts. By downloading a single Unicode-to-font table,
both the eight-bit character sets and UTF-8 mode are changed to use
the font as indicated.
This changes the semantics of the eight-bit character tables subtly.
The four character tables are now:
Map symbol Map name Escape code (G0)
LAT1_MAP Latin-1 (ISO 8859-1) ESC ( B
GRAF_MAP DEC VT100 pseudographics ESC ( 0
IBMPC_MAP IBM code page 437 ESC ( U
USER_MAP User defined ESC ( K
In particular, ESC ( U is no longer "straight to font", since the font
might be completely different than the IBM character set. This
permits for example the use of block graphics even with a Latin-1 font
loaded.
In accordance with the Unicode standard/ISO 10646 the range U+F000 to
U+F8FF has been reserved for OS-wide allocation (the Unicode Standard
refers to this as a "Corporate Zone"). U+F000 was picked as the
starting point since it lets the direct-mapping area start on a large
power of two (in case 1024- or 2048-character fonts ever become
necessary). This leaves U+E000 to U+EFFF as End User Zone.
The Unicodes in the range U+F000 to U+F1FF have been hard-coded to map
directly to the loaded font, bypassing the translation table. The
user-defined map now defaults to U+F000 to U+F1FF, emulating the
previous behaviour.
In addition, the following characters not present in Unicode 1.1.4 (at
least, I have not found them!) have been defined; these are used by
the DEC VT graphics map:
U+F800 DEC VT GRAPHICS HORIZONTAL LINE SCAN 1
U+F801 DEC VT GRAPHICS HORIZONTAL LINE SCAN 3
U+F803 DEC VT GRAPHICS HORIZONTAL LINE SCAN 7
U+F804 DEC VT GRAPHICS HORIZONTAL LINE SCAN 9
The DEC VT220 uses a 6x10 character matrix, and these characters form
a smooth progression in the DEC VT graphics character set. I have
omitted the scan 5 line, since it is also used as a block-graphics
character, and hence has been coded as U+2500 FORMS LIGHT HORIZONTAL.
However, I left U+F802 blank should the need arise.
H. Peter Anvin <Peter.Anvin@linux.org>
Yggdrasil Computing, Inc.
/*
* conmakehash.c
*
* Create a pre-initialized kernel Unicode hash table
*
* Copyright (C) 1995 H. Peter Anvin
*
* This program may be freely copied under the terms of the GNU
* General Public License (GPL), version 2, or at your option
* any later version.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <string.h>
#include <ctype.h>
typedef unsigned short unicode;
struct unipair
{
unsigned short glyph; /* Glyph code */
unicode uc; /* Unicode listed */
};
void usage(char *argv0)
{
fprintf(stderr, "Usage: \n"
" %s chartable [hashsize] [hashstep] [maxhashlevel]\n", argv0);
exit(EX_USAGE);
}
int getunicode(char **p0)
{
char *p = *p0;
while (*p == ' ' || *p == '\t')
p++;
if (*p != 'U' || p[1] != '+' ||
!isxdigit(p[2]) || !isxdigit(p[3]) || !isxdigit(p[4]) ||
!isxdigit(p[5]) || isxdigit(p[6]))
return -1;
*p0 = p+6;
return strtol(p+2,0,16);
}
struct unipair *hashtable;
int hashsize = 641; /* Size of hash table */
int hashstep = 189; /* Hash stepping */
int maxhashlevel = 6; /* Maximum hash depth */
int hashlevel = 0; /* Actual hash depth */
void addpair(int fp, int un)
{
int i, lct;
unicode hu;
if ( un <= 0xFFFE )
{
/* Add to hash table */
i = un % hashsize;
lct = 1;
while ( (hu = hashtable[i].uc) != 0xffff && hu != un )
{
if (lct++ >= maxhashlevel)
{
fprintf(stderr, "ERROR: Hash table overflow\n");
exit(EX_DATAERR);
}
i += hashstep;
if ( i >= hashsize )
i -= hashsize;
}
if ( lct > hashlevel )
hashlevel = lct;
hashtable[i].uc = un;
hashtable[i].glyph = fp;
}
/* otherwise: ignore */
}
int main(int argc, char *argv[])
{
FILE *ctbl;
char *tblname;
char buffer[65536];
int fontlen;
int i;
int fp0, fp1, un0, un1;
char *p, *p1;
if ( argc < 2 || argc > 5 )
usage(argv[0]);
if ( !strcmp(argv[1],"-") )
{
ctbl = stdin;
tblname = "stdin";
}
else
{
ctbl = fopen(tblname = argv[1], "r");
if ( !ctbl )
{
perror(tblname);
exit(EX_NOINPUT);
}
}
if ( argc > 2 )
{
hashsize = atoi(argv[2]);
if ( hashsize < 256 || hashsize > 2048 )
{
fprintf(stderr, "Illegal hash size\n");
exit(EX_USAGE);
}
}
if ( argc > 3 )
{
hashstep = atoi(argv[3]) % hashsize;
if ( hashstep < 0 ) hashstep += hashsize;
if ( hashstep < 16 || hashstep >= hashsize-16 )
{
fprintf(stderr, "Bad hash step\n");
exit(EX_USAGE);
}
}
/* Warn the user in case the hashstep and hashsize are not relatively
prime -- this algorithm could be massively improved */
for ( i = hashstep ; i > 1 ; i-- )
{
if ( hashstep % i == 0 && hashsize % i == 0 )
break; /* Found GCD */
}
if ( i > 1 )
{
fprintf(stderr,
"WARNING: hashsize and hashstep have common factors (gcd = %d)\n", i);
}
if ( argc > 4 )
{
maxhashlevel = atoi(argv[4]);
if ( maxhashlevel < 1 || maxhashlevel > hashsize )
{
fprintf(stderr, "Illegal max hash level\n");
exit(EX_USAGE);
}
}
/* For now we assume the default font is always 256 characters */
fontlen = 256;
/* Initialize hash table */
hashtable = malloc(hashsize * sizeof(struct unipair));
if ( !hashtable )
{
fprintf(stderr, "Could not allocate memory for hash table\n");
exit(EX_OSERR);
}
for ( i = 0 ; i < hashsize ; i++ )
{
hashtable[i].uc = 0xffff;
hashtable[i].glyph = 0;
}
/* Now we come to the tricky part. Parse the input table. */
while ( fgets(buffer, sizeof(buffer), ctbl) != NULL )
{
if ( (p = strchr(buffer, '\n')) != NULL )
*p = '\0';
else
fprintf(stderr, "%s: Warning: line too long\n", tblname);
p = buffer;
/*
* Syntax accepted:
* <fontpos> <unicode> <unicode> ...
* <range> idem
* <range> <unicode range>
*
* where <range> ::= <fontpos>-<fontpos>
* and <unicode> ::= U+<h><h><h><h>
* and <h> ::= <hexadecimal digit>
*/
while (*p == ' ' || *p == '\t')
p++;
if (!*p || *p == '#')
continue; /* skip comment or blank line */
fp0 = strtol(p, &p1, 0);
if (p1 == p)
{
fprintf(stderr, "Bad input line: %s\n", buffer);
exit(EX_DATAERR);
}
p = p1;
while (*p == ' ' || *p == '\t')
p++;
if (*p == '-')
{
p++;
fp1 = strtol(p, &p1, 0);
if (p1 == p)
{
fprintf(stderr, "Bad input line: %s\n", buffer);
exit(EX_DATAERR);
}
p = p1;
}
else
fp1 = 0;
if ( fp0 < 0 || fp0 >= fontlen )
{
fprintf(stderr,
"%s: Glyph number (0x%x) larger than font length\n",
tblname, fp0);
exit(EX_DATAERR);
}
if ( fp1 && (fp1 < fp0 || fp1 >= fontlen) )
{
fprintf(stderr,
"%s: Bad end of range (0x%x)\n",
tblname, fp1);
exit(EX_DATAERR);
}
if (fp1)
{
/* we have a range; expect the word "idem" or a Unicode range of the
same length */
while (*p == ' ' || *p == '\t')
p++;
if (!strncmp(p, "idem", 4))
{
for (i=fp0; i<=fp1; i++)
addpair(i,i);
p += 4;
}
else
{
un0 = getunicode(&p);
while (*p == ' ' || *p == '\t')
p++;
if (*p != '-')
{
fprintf(stderr,
"%s: Corresponding to a range of font positions, there should be a Unicode range\n",
tblname);
exit(EX_DATAERR);
}
p++;
un1 = getunicode(&p);
if (un0 < 0 || un1 < 0)
{
fprintf(stderr,
"%s: Bad Unicode range corresponding to font position range 0x%x-0x%x\n",
tblname, fp0, fp1);
exit(EX_DATAERR);
}
if (un1 - un0 != fp1 - fp0)
{
fprintf(stderr,
"%s: Unicode range U+%x-U+%x not of the same length as font position range 0x%x-0x%x\n",
tblname, un0, un1, fp0, fp1);
exit(EX_DATAERR);
}
for(i=fp0; i<=fp1; i++)
addpair(i,un0-fp0+i);
}
}
else
{
/* no range; expect a list of unicode values for a single font position */
while ( (un0 = getunicode(&p)) >= 0 )
addpair(fp0, un0);
}
while (*p == ' ' || *p == '\t')
p++;
if (*p && *p != '#')
fprintf(stderr, "%s: trailing junk (%s) ignored\n", tblname, p);
}
/* Okay, we hit EOF, now output hash table */
fclose(ctbl);
printf("\
/*\n\
* uni_hash_tbl.h\n\
*\n\
* Do not edit this file; it was automatically generated by\n\
*\n\
* conmakehash %s %d %d %d > uni_hash_tbl.h\n\
*\n\
*/\n\
\n\
#include <linux/kd.h>\n\
\n\
#define HASHSIZE %d\n\
#define HASHSTEP %d\n\
#define MAXHASHLEVEL %d\n\
#define DEF_HASHLEVEL %d\n\
\n\
static unsigned int hashsize = HASHSIZE;\n\
static unsigned int hashstep = HASHSTEP;\n\
static unsigned int maxhashlevel = MAXHASHLEVEL;\n\
static unsigned int hashlevel = DEF_HASHLEVEL;\n\
\n\
static struct unipair hashtable[HASHSIZE] =\n\
{\n\t", argv[1], hashsize, hashstep, maxhashlevel,
hashsize, hashstep, maxhashlevel, hashlevel);
for ( i = 0 ; i < hashsize ; i++ )
{
printf("{0x%04x,0x%02x}", hashtable[i].uc, hashtable[i].glyph);
if ( i == hashsize-1 )
printf("\n};\n");
else if ( i % 4 == 3 )
printf(",\n\t");
else
printf(", ");
}
printf("\n\
#ifdef NEED_BACKUP_HASHTABLE\n\
\n\
static const struct unipair backup_hashtable[HASHSIZE] = \n{\n\t");
for ( i = 0 ; i < hashsize ; i++ )
{
printf("{0x%04x,0x%02x}", hashtable[i].uc, hashtable[i].glyph);
if ( i == hashsize-1 )
printf("\n};\n#endif\n");
else if ( i % 4 == 3 )
printf(",\n\t");
else
printf(", ");
}
exit(EX_OK);
}
This diff is collapsed.
This diff is collapsed.
...@@ -3,11 +3,12 @@ ...@@ -3,11 +3,12 @@
* *
* Interface between console.c, selection.c and consolemap.c * Interface between console.c, selection.c and consolemap.c
*/ */
#define NORM_MAP 0 #define LAT1_MAP 0
#define GRAF_MAP 1 #define GRAF_MAP 1
#define NULL_MAP 2 #define IBMPC_MAP 2
#define USER_MAP 3 #define USER_MAP 3
extern int hashtable_contents_valid; extern int hashtable_contents_valid;
extern unsigned char inverse_translate(unsigned char c); extern unsigned char inverse_translate(unsigned char c);
extern unsigned char *set_translate(int m); extern unsigned short *set_translate(int m);
extern int conv_uni_to_pc(long ucs);
#
# Unicode table for IBM Codepage 437. Note that there are many more
# substitutions that could be conceived (for example, thick-line
# graphs probably should be replaced with double-line ones, accented
# Latin characters should replaced with their nonaccented versions,
# and some upper case Greek characters could be replaced by Latin), however,
# I have limited myself to the Unicodes used by the kernel ISO 8859-1,
# DEC VT, and IBM CP 437 tables.
#
# --------------------------------
#
# Basic IBM dingbats, some of which will never have a purpose clear
# to mankind
#
0x00 U+0000
0x01 U+263a
0x02 U+263b
0x03 U+2665
0x04 U+2666 U+25c6
0x05 U+2663
0x06 U+2660
0x07 U+2022
0x08 U+25d8
0x09 U+25cb
0x0a U+25d9
0x0b U+2642
0x0c U+2640
0x0d U+266a
0x0e U+266b
0x0f U+263c
0x10 U+25ba
0x11 U+25c4
0x12 U+2195
0x13 U+203c
0x14 U+00b6
0x15 U+00a7
0x16 U+25ac
0x17 U+21a8
0x18 U+2191
0x19 U+2193
0x1a U+2192
0x1b U+2190
0x1c U+221f
0x1d U+2194
0x1e U+25b2
0x1f U+25bc
#
# The ASCII range is identity-mapped, but some of the characters also
# have to act as substitutes, especially the upper-case characters.
#
0x20 U+0020
0x21 U+0021
0x22 U+0022 U+00a8
0x23 U+0023
0x24 U+0024
0x25 U+0025
0x26 U+0026
0x27 U+0027
0x28 U+0028
0x29 U+0029
0x2a U+002a
0x2b U+002b
0x2c U+002c U+00b8
0x2d U+002d U+00ad
0x2e U+002e
0x2f U+002f
0x30 U+0030
0x31 U+0031
0x32 U+0032
0x33 U+0033
0x34 U+0034
0x35 U+0035
0x36 U+0036
0x37 U+0037
0x38 U+0038
0x39 U+0039
0x3a U+003a
0x3b U+003b
0x3c U+003c
0x3d U+003d
0x3e U+003e
0x3f U+003f
0x40 U+0040
0x41 U+0041 U+00c0 U+00c1 U+00c2 U+00c3
0x42 U+0042
0x43 U+0043 U+00a9
0x44 U+0044
0x45 U+0045 U+00c8 U+00ca U+00cb
0x46 U+0046
0x47 U+0047
0x48 U+0048
0x49 U+0049 U+00cc U+00cd U+00ce U+00cf
0x4a U+004a
0x4b U+004b U+212a
0x4c U+004c
0x4d U+004d
0x4e U+004e
0x4f U+004f U+00d2 U+00d3 U+00d4 U+00d5
0x50 U+0050
0x51 U+0051
0x52 U+0052 U+00ae
0x53 U+0053
0x54 U+0054
0x55 U+0055 U+00d9 U+00da U+00db
0x56 U+0056
0x57 U+0057
0x58 U+0058
0x59 U+0059 U+00dd
0x5a U+005a
0x5b U+005b
0x5c U+005c
0x5d U+005d
0x5e U+005e
0x5f U+005f U+f804
0x60 U+0060
0x61 U+0061 U+00e3
0x62 U+0062
0x63 U+0063
0x64 U+0064
0x65 U+0065
0x66 U+0066
0x67 U+0067
0x68 U+0068
0x69 U+0069
0x6a U+006a
0x6b U+006b
0x6c U+006c
0x6d U+006d
0x6e U+006e
0x6f U+006f U+00f5
0x70 U+0070
0x71 U+0071
0x72 U+0072
0x73 U+0073
0x74 U+0074
0x75 U+0075
0x76 U+0076
0x77 U+0077
0x78 U+0078 U+00d7
0x79 U+0079 U+00fd
0x7a U+007a
0x7b U+007b
0x7c U+007c U+00a5
0x7d U+007d
0x7e U+007e
#
# Okay, what on Earth is this one supposed to be used for?
#
0x7f U+2302
#
# Non-English characters, mostly lower case letters...
#
0x80 U+00c7
0x81 U+00fc
0x82 U+00e9
0x83 U+00e2
0x84 U+00e4
0x85 U+00e0
0x86 U+00e5
0x87 U+00e7
0x88 U+00ea
0x89 U+00eb
0x8a U+00e8
0x8b U+00ef
0x8c U+00ee
0x8d U+00ec
0x8e U+00c4
0x8f U+00c5 U+212b
0x90 U+00c9
0x91 U+00e6
0x92 U+00c6
0x93 U+00f4
0x94 U+00f6
0x95 U+00f2
0x96 U+00fb
0x97 U+00f9
0x98 U+00ff
0x99 U+00d6
0x9a U+00dc
0x9b U+00a2
0x9c U+00a3
0x9d U+00a5
0x9e U+20a7
0x9f U+0192
0xa0 U+00e1
0xa1 U+00ed
0xa2 U+00f3
0xa3 U+00fa
0xa4 U+00f1
0xa5 U+00d1
0xa6 U+00aa
0xa7 U+00ba
0xa8 U+00bf
0xa9 U+2310
0xaa U+00ac
0xab U+00bd
0xac U+00bc
0xad U+00a1
0xae U+00ab
0xaf U+00bb
#
# Block graphics
#
0xb0 U+2591
0xb1 U+2592
0xb2 U+2593
0xb3 U+2502
0xb4 U+2524
0xb5 U+2561
0xb6 U+2562
0xb7 U+2556
0xb8 U+2555
0xb9 U+2563
0xba U+2551
0xbb U+2557
0xbc U+255d
0xbd U+255c
0xbe U+255b
0xbf U+2510
0xc0 U+2514
0xc1 U+2534
0xc2 U+252c
0xc3 U+251c
0xc4 U+2500
0xc5 U+253c
0xc6 U+255e
0xc7 U+255f
0xc8 U+255a
0xc9 U+2554
0xca U+2569
0xcb U+2566
0xcc U+2560
0xcd U+2550
0xce U+256c
0xcf U+2567
0xd0 U+2568
0xd1 U+2564
0xd2 U+2565
0xd3 U+2559
0xd4 U+2558
0xd5 U+2552
0xd6 U+2553
0xd7 U+256b
0xd8 U+256a
0xd9 U+2518
0xda U+250c
0xdb U+2588
0xdc U+2584
0xdd U+258c
0xde U+2590
0xdf U+2580
#
# Greek letters and mathematical symbols
#
0xe0 U+03b1
0xe1 U+03b2 U+00df
0xe2 U+0393
0xe3 U+03c0
0xe4 U+03a3
0xe5 U+03c3
0xe6 U+00b5 U+03bc
0xe7 U+03c4
0xe8 U+03a6 U+00d8
0xe9 U+0398
0xea U+03a9 U+2126
0xeb U+03b4
0xec U+221e
0xed U+03c6 U+00f8
0xee U+03b5
0xef U+2229
0xf0 U+2261
0xf1 U+00b1
0xf2 U+2265
0xf3 U+2264
0xf4 U+2320
0xf5 U+2321
0xf6 U+00f7
0xf7 U+2248
0xf8 U+00b0
0xf9 U+2219
0xfa U+00b7
0xfb U+221a
0xfc U+207f
0xfd U+00b2
#
# Square bullet, non-spacing blank
# Mapping U+fffd to the square bullet means it is the substitution
# character
#
0xfe U+25a0 U+fffd
0xff U+00a0
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include <linux/vt.h> #include <linux/vt.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/malloc.h> #include <linux/malloc.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/segment.h> #include <asm/segment.h>
...@@ -63,13 +65,19 @@ extern unsigned int keymap_count; ...@@ -63,13 +65,19 @@ extern unsigned int keymap_count;
/* /*
* routines to load custom translation table and EGA/VGA font from console.c * routines to load custom translation table and EGA/VGA font from console.c
*/ */
extern int con_set_trans(char * table); extern int con_set_trans_old(char * table);
extern int con_get_trans(char * table); extern int con_get_trans_old(char * table);
extern int con_set_trans_new(unsigned short * table);
extern int con_get_trans_new(unsigned short * table);
extern void con_clear_unimap(struct unimapinit *ui); extern void con_clear_unimap(struct unimapinit *ui);
extern int con_set_unimap(ushort ct, struct unipair *list); extern int con_set_unimap(ushort ct, struct unipair *list);
extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list); extern int con_get_unimap(ushort ct, ushort *uct, struct unipair *list);
extern int con_set_font(char * fontmap); extern int con_set_font(char * fontmap, int ch512);
extern int con_get_font(char * fontmap); extern int con_get_font(char * fontmap);
extern int con_adjust_height(unsigned long fontheight);
extern int video_mode_512ch;
extern unsigned long video_font_height;
/* /*
* these are the valid i/o ports we're allowed to change. they map all the * these are the valid i/o ports we're allowed to change. they map all the
...@@ -79,6 +87,41 @@ extern int con_get_font(char * fontmap); ...@@ -79,6 +87,41 @@ extern int con_get_font(char * fontmap);
#define GPLAST 0x3df #define GPLAST 0x3df
#define GPNUM (GPLAST - GPFIRST + 1) #define GPNUM (GPLAST - GPFIRST + 1)
/*
* This function is called when the size of the physical screen has been
* changed. If either the row or col argument is nonzero, set the appropriate
* entry in each winsize structure for all the virtual consoles, then
* send SIGWINCH to all processes with a virtual console as controlling
* tty.
*/
static void
kd_size_changed(int row, int col)
{
struct task_struct *p;
int i;
if ( !row && !col ) return;
for ( i = 0 ; i < MAX_NR_CONSOLES ; i++ )
{
if ( console_driver.table[i] )
{
if ( row ) console_driver.table[i]->winsize.ws_row = row;
if ( col ) console_driver.table[i]->winsize.ws_col = col;
}
}
for_each_task(p)
{
if ( p->tty && MAJOR(p->tty->device) == TTY_MAJOR &&
MINOR(p->tty->device) <= MAX_NR_CONSOLES && MINOR(p->tty->device) )
{
send_sig(SIGWINCH, p, 1);
}
}
}
/* /*
* Generates sound of some count for some number of clock ticks * Generates sound of some count for some number of clock ticks
* [count = 1193180 / frequency] * [count = 1193180 / frequency]
...@@ -829,22 +872,85 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ...@@ -829,22 +872,85 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return -EPERM; return -EPERM;
if (vt_cons[fg_console]->vc_mode != KD_TEXT) if (vt_cons[fg_console]->vc_mode != KD_TEXT)
return -EINVAL; return -EINVAL;
return con_set_font((char *)arg); return con_set_font((char *)arg, 0);
/* con_set_font() defined in console.c */ /* con_set_font() defined in console.c */
case GIO_FONT: case GIO_FONT:
if (vt_cons[fg_console]->vc_mode != KD_TEXT) if (vt_cons[fg_console]->vc_mode != KD_TEXT ||
video_mode_512ch)
return -EINVAL; return -EINVAL;
return con_get_font((char *)arg); return con_get_font((char *)arg);
/* con_get_font() defined in console.c */ /* con_get_font() defined in console.c */
case PIO_FONTX:
{
struct consolefontdesc cfdarg;
if (!perm)
return -EPERM;
if (vt_cons[fg_console]->vc_mode != KD_TEXT)
return -EINVAL;
i = verify_area(VERIFY_READ, (void *)arg,
sizeof(struct consolefontdesc));
if (i) return i;
memcpy_fromfs(&cfdarg, (void *)arg,
sizeof(struct consolefontdesc));
if ( cfdarg.charcount == 256 ||
cfdarg.charcount == 512 ) {
i = con_set_font(cfdarg.chardata,
cfdarg.charcount == 512);
if (i)
return i;
i = con_adjust_height(cfdarg.charheight);
if (i <= 0) return i;
kd_size_changed(i, 0);
return 0;
} else
return -EINVAL;
}
case GIO_FONTX:
{
struct consolefontdesc cfdarg;
int nchar;
if (vt_cons[fg_console]->vc_mode != KD_TEXT)
return -EINVAL;
i = verify_area(VERIFY_WRITE, (void *)arg,
sizeof(struct consolefontdesc));
if (i) return i;
memcpy_fromfs(&cfdarg, (void *) arg,
sizeof(struct consolefontdesc));
i = cfdarg.charcount;
cfdarg.charcount = nchar = video_mode_512ch ? 512 : 256;
cfdarg.charheight = video_font_height;
memcpy_tofs((void *) arg, &cfdarg,
sizeof(struct consolefontdesc));
if ( cfdarg.chardata )
{
if ( i < nchar )
return -ENOMEM;
return con_get_font(cfdarg.chardata);
} else
return 0;
}
case PIO_SCRNMAP: case PIO_SCRNMAP:
if (!perm) if (!perm)
return -EPERM; return -EPERM;
return con_set_trans((char *)arg); return con_set_trans_old((char *)arg);
case GIO_SCRNMAP: case GIO_SCRNMAP:
return con_get_trans((char *)arg); return con_get_trans_old((char *)arg);
case PIO_UNISCRNMAP:
if (!perm)
return -EPERM;
return con_set_trans_new((unsigned short *)arg);
case GIO_UNISCRNMAP:
return con_get_trans_new((unsigned short *)arg);
case PIO_UNIMAPCLR: case PIO_UNIMAPCLR:
{ struct unimapinit ui; { struct unimapinit ui;
......
/* /*
* u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters. * u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
* *
* 13 Jun 1995 rev. 2.01 for linux 1.2.10
* HAVE_OLD_UX4F_FIRMWARE should be defined for U34F boards when
* the firmware prom is not the lastest one (28008-006).
*
* 11 Mar 1995 rev. 2.00 for linux 1.2.0 * 11 Mar 1995 rev. 2.00 for linux 1.2.0
* Fixed a bug which prevented media change detection for removable * Fixed a bug which prevented media change detection for removable
* disk drives. * disk drives.
...@@ -53,11 +57,11 @@ ...@@ -53,11 +57,11 @@
* *
* Copyright (C) 1994, 1995 Dario Ballabio (dario@milano.europe.dg.com) * Copyright (C) 1994, 1995 Dario Ballabio (dario@milano.europe.dg.com)
* *
* WARNING: if your 14F board has an old firmware revision (see below) * WARNING: if your 14/34F board has an old firmware revision (see below)
* you must change "#undef" into "#define" in the following * you must change "#undef" into "#define" in the following
* statement. * statement.
*/ */
#undef HAVE_OLD_U14F_FIRMWARE #undef HAVE_OLD_UX4F_FIRMWARE
/* /*
* The UltraStor 14F, 24F, and 34F are a family of intelligent, high * The UltraStor 14F, 24F, and 34F are a family of intelligent, high
* performance SCSI-2 host adapters. * performance SCSI-2 host adapters.
...@@ -124,6 +128,10 @@ ...@@ -124,6 +128,10 @@
* *
* The new firmware has fixed all the above problems. * The new firmware has fixed all the above problems.
* *
* For U34F boards the latest bios prom is 38008-002 (BIOS rev. 2.01),
* the latest firmware prom is 28008-006. Older firmware 28008-005 has
* problems when using more then 16 scatter/gather lists.
*
* In order to support multiple ISA boards in a reliable way, * In order to support multiple ISA boards in a reliable way,
* the driver sets host->wish_block = TRUE for all ISA boards. * the driver sets host->wish_block = TRUE for all ISA boards.
*/ */
...@@ -449,6 +457,11 @@ static inline int port_detect(ushort *port_base, unsigned int j, ...@@ -449,6 +457,11 @@ static inline int port_detect(ushort *port_base, unsigned int j,
irqlist[irq] = j; irqlist[irq] = j;
if (HD(j)->subversion == ESA) { if (HD(j)->subversion == ESA) {
#if defined (HAVE_OLD_UX4F_FIRMWARE)
sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
#endif
sh[j]->dma_channel = NO_DMA; sh[j]->dma_channel = NO_DMA;
sh[j]->unchecked_isa_dma = FALSE; sh[j]->unchecked_isa_dma = FALSE;
sprintf(BN(j), "U34F%d", j); sprintf(BN(j), "U34F%d", j);
...@@ -456,7 +469,7 @@ static inline int port_detect(ushort *port_base, unsigned int j, ...@@ -456,7 +469,7 @@ static inline int port_detect(ushort *port_base, unsigned int j,
else { else {
sh[j]->wish_block = TRUE; sh[j]->wish_block = TRUE;
#if defined (HAVE_OLD_U14F_FIRMWARE) #if defined (HAVE_OLD_UX4F_FIRMWARE)
sh[j]->hostt->use_clustering = DISABLE_CLUSTERING; sh[j]->hostt->use_clustering = DISABLE_CLUSTERING;
sh[j]->sg_tablesize = MAX_SAFE_SGLIST; sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
#endif #endif
...@@ -475,7 +488,7 @@ static inline int port_detect(ushort *port_base, unsigned int j, ...@@ -475,7 +488,7 @@ static inline int port_detect(ushort *port_base, unsigned int j,
if (strcmp(&HD(j)->board_id[32], "06000600")) { if (strcmp(&HD(j)->board_id[32], "06000600")) {
printk("%s: %s.\n", BN(j), &HD(j)->board_id[8]); printk("%s: %s.\n", BN(j), &HD(j)->board_id[8]);
printk("%s: firmware %s is outdated, BIOS rev. should be 2.01.\n", printk("%s: firmware %s is outdated, FW PROM should be 28004-006.\n",
BN(j), &HD(j)->board_id[32]); BN(j), &HD(j)->board_id[32]);
sh[j]->hostt->use_clustering = DISABLE_CLUSTERING; sh[j]->hostt->use_clustering = DISABLE_CLUSTERING;
sh[j]->sg_tablesize = MAX_SAFE_SGLIST; sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
......
...@@ -10,7 +10,7 @@ int u14_34f_abort(Scsi_Cmnd *); ...@@ -10,7 +10,7 @@ int u14_34f_abort(Scsi_Cmnd *);
int u14_34f_reset(Scsi_Cmnd *); int u14_34f_reset(Scsi_Cmnd *);
int u14_34f_biosparam(Disk *, int, int *); int u14_34f_biosparam(Disk *, int, int *);
#define U14_34F_VERSION "2.00.00" #define U14_34F_VERSION "2.01.00"
#define ULTRASTOR_14_34F { \ #define ULTRASTOR_14_34F { \
NULL, /* Ptr for modules */ \ NULL, /* Ptr for modules */ \
......
...@@ -1159,6 +1159,31 @@ unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, in ...@@ -1159,6 +1159,31 @@ unsigned long bread_page(unsigned long address, dev_t dev, int b[], int size, in
return address; return address;
} }
/*
* bwrite_page writes a page out to the buffer cache and/or the physical device.
* It's used for mmap writes (the same way bread_page() is used for mmap reads).
*/
void bwrite_page(unsigned long address, dev_t dev, int b[], int size)
{
struct buffer_head * bh[MAX_BUF_PER_PAGE];
int i, j;
for (i=0, j=0; j<PAGE_SIZE ; i++, j+= size) {
bh[i] = NULL;
if (b[i])
bh[i] = getblk(dev, b[i], size);
}
for (i=0, j=0; j<PAGE_SIZE ; i++, j += size, address += size) {
if (bh[i]) {
memcpy(bh[i]->b_data, (void *) address, size);
bh[i]->b_uptodate = 1;
mark_buffer_dirty(bh[i], 0);
brelse(bh[i]);
} else
memset((void *) address, 0, size);
}
}
/* /*
* Try to increase the number of buffers available: the size argument * Try to increase the number of buffers available: the size argument
* is used to determine what kind of buffers we want. * is used to determine what kind of buffers we want.
......
...@@ -232,7 +232,7 @@ void minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz) ...@@ -232,7 +232,7 @@ void minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
tmp.f_bsize = 1024; tmp.f_bsize = 1024;
tmp.f_blocks = (sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone) << sb->u.minix_sb.s_log_zone_size; tmp.f_blocks = (sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone) << sb->u.minix_sb.s_log_zone_size;
tmp.f_bfree = minix_count_free_blocks(sb); tmp.f_bfree = minix_count_free_blocks(sb);
tmp.f_bavail = tmp.f_bavail; tmp.f_bavail = tmp.f_bfree;
tmp.f_files = sb->u.minix_sb.s_ninodes; tmp.f_files = sb->u.minix_sb.s_ninodes;
tmp.f_ffree = minix_count_free_inodes(sb); tmp.f_ffree = minix_count_free_inodes(sb);
tmp.f_namelen = sb->u.minix_sb.s_namelen; tmp.f_namelen = sb->u.minix_sb.s_namelen;
......
...@@ -151,17 +151,32 @@ static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned ...@@ -151,17 +151,32 @@ static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned
case 0: case 0:
return; return;
case 1: case 1:
put_user_byte(*(const char *) from, (char *) to); __put_user(*(const char *) from, (char *) to, 1);
return; return;
case 2: case 2:
put_user_word(*(const short *) from, (short *) to); __put_user(*(const short *) from, (short *) to, 2);
return; return;
case 3: case 3:
put_user_word(*(const short *) from, (short *) to); __put_user(*(const short *) from, (short *) to, 2);
put_user_byte(*(2+(const char *) from), 2+(char *) to); __put_user(*(2+(const char *) from), 2+(char *) to, 1);
return; return;
case 4: case 4:
put_user_long(*(const int *) from, (int *) to); __put_user(*(const int *) from, (int *) to, 4);
return;
case 8:
__put_user(*(const int *) from, (int *) to, 4);
__put_user(*(1+(const int *) from), 1+(int *) to, 4);
return;
case 12:
__put_user(*(const int *) from, (int *) to, 4);
__put_user(*(1+(const int *) from), 1+(int *) to, 4);
__put_user(*(2+(const int *) from), 2+(int *) to, 4);
return;
case 16:
__put_user(*(const int *) from, (int *) to, 4);
__put_user(*(1+(const int *) from), 1+(int *) to, 4);
__put_user(*(2+(const int *) from), 2+(int *) to, 4);
__put_user(*(3+(const int *) from), 3+(int *) to, 4);
return; return;
} }
#define COMMON(x) \ #define COMMON(x) \
...@@ -215,17 +230,32 @@ static inline void __constant_memcpy_fromfs(void * to, const void * from, unsign ...@@ -215,17 +230,32 @@ static inline void __constant_memcpy_fromfs(void * to, const void * from, unsign
case 0: case 0:
return; return;
case 1: case 1:
*(char *)to = get_user_byte((const char *) from); *(char *)to = __get_user((const char *) from, 1);
return; return;
case 2: case 2:
*(short *)to = get_user_word((const short *) from); *(short *)to = __get_user((const short *) from, 2);
return; return;
case 3: case 3:
*(short *) to = get_user_word((const short *) from); *(short *) to = __get_user((const short *) from, 2);
*((char *) to + 2) = get_user_byte(2+(const char *) from); *((char *) to + 2) = __get_user(2+(const char *) from, 1);
return; return;
case 4: case 4:
*(int *) to = get_user_long((const int *) from); *(int *) to = __get_user((const int *) from, 4);
return;
case 8:
*(int *) to = __get_user((const int *) from, 4);
*(1+(int *) to) = __get_user(1+(const int *) from, 4);
return;
case 12:
*(int *) to = __get_user((const int *) from, 4);
*(1+(int *) to) = __get_user(1+(const int *) from, 4);
*(1+(int *) to) = __get_user(2+(const int *) from, 4);
return;
case 16:
*(int *) to = __get_user((const int *) from, 4);
*(1+(int *) to) = __get_user(1+(const int *) from, 4);
*(2+(int *) to) = __get_user(2+(const int *) from, 4);
*(3+(int *) to) = __get_user(3+(const int *) from, 4);
return; return;
} }
#define COMMON(x) \ #define COMMON(x) \
......
...@@ -501,6 +501,7 @@ extern void brelse(struct buffer_head * buf); ...@@ -501,6 +501,7 @@ extern void brelse(struct buffer_head * buf);
extern void set_blocksize(dev_t dev, int size); extern void set_blocksize(dev_t dev, int size);
extern struct buffer_head * bread(dev_t dev, int block, int size); extern struct buffer_head * bread(dev_t dev, int block, int size);
extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int no_share); extern unsigned long bread_page(unsigned long addr,dev_t dev,int b[],int size,int no_share);
extern void bwrite_page(unsigned long addr,dev_t dev,int b[],int size);
extern struct buffer_head * breada(dev_t dev,int block, int size, extern struct buffer_head * breada(dev_t dev,int block, int size,
unsigned int pos, unsigned int filesize); unsigned int pos, unsigned int filesize);
extern void put_super(dev_t dev); extern void put_super(dev_t dev);
......
...@@ -7,6 +7,14 @@ ...@@ -7,6 +7,14 @@
#define GIO_FONT 0x4B60 /* gets font in expanded form */ #define GIO_FONT 0x4B60 /* gets font in expanded form */
#define PIO_FONT 0x4B61 /* use font in expanded form */ #define PIO_FONT 0x4B61 /* use font in expanded form */
#define GIO_FONTX 0x4B6B /* get font using struct consolefontdesc */
#define PIO_FONTX 0x4B6C /* set font using struct consolefontdesc */
struct consolefontdesc {
u_short charcount; /* characters in font (256 or 512) */
u_short charheight; /* scan lines per character (1-32) */
char *chardata; /* font data in expanded form */
};
#define KIOCSOUND 0x4B2F /* start sound generation (0 for off) */ #define KIOCSOUND 0x4B2F /* start sound generation (0 for off) */
#define KDMKTONE 0x4B30 /* generate tone */ #define KDMKTONE 0x4B30 /* generate tone */
...@@ -40,6 +48,8 @@ typedef char scrnmap_t; ...@@ -40,6 +48,8 @@ typedef char scrnmap_t;
#define E_TABSZ 256 #define E_TABSZ 256
#define GIO_SCRNMAP 0x4B40 /* get screen mapping from kernel */ #define GIO_SCRNMAP 0x4B40 /* get screen mapping from kernel */
#define PIO_SCRNMAP 0x4B41 /* put screen mapping table in kernel */ #define PIO_SCRNMAP 0x4B41 /* put screen mapping table in kernel */
#define GIO_UNISCRNMAP 0x4B69 /* get full Unicode screen mapping */
#define PIO_UNISCRNMAP 0x4B6A /* set full Unicode screen mapping */
#define GIO_UNIMAP 0x4B66 /* get unicode-to-font mapping from kernel */ #define GIO_UNIMAP 0x4B66 /* get unicode-to-font mapping from kernel */
struct unipair { struct unipair {
...@@ -58,6 +68,9 @@ struct unimapinit { ...@@ -58,6 +68,9 @@ struct unimapinit {
u_short advised_hashlevel; /* 0 if no opinion */ u_short advised_hashlevel; /* 0 if no opinion */
}; };
#define UNI_DIRECT_BASE 0xF000 /* start of Direct Font Region */
#define UNI_DIRECT_MASK 0x01FF /* Direct Font Region bitmask */
#define K_RAW 0x00 #define K_RAW 0x00
#define K_XLATE 0x01 #define K_XLATE 0x01
#define K_MEDIUMRAW 0x02 #define K_MEDIUMRAW 0x02
...@@ -116,6 +129,6 @@ struct kbkeycode { ...@@ -116,6 +129,6 @@ struct kbkeycode {
/* note: 0x4B00-0x4B4E all have had a value at some time; /* note: 0x4B00-0x4B4E all have had a value at some time;
don't reuse for the time being */ don't reuse for the time being */
/* note: 0x4B60-0x4B68 used above */ /* note: 0x4B60-0x4B6C used above */
#endif /* _LINUX_KD_H */ #endif /* _LINUX_KD_H */
...@@ -239,7 +239,8 @@ extern unsigned long get_unmapped_area(unsigned long, unsigned long); ...@@ -239,7 +239,8 @@ extern unsigned long get_unmapped_area(unsigned long, unsigned long);
* *
* Will go away eventually.. * Will go away eventually..
*/ */
#define SHM_SWP_TYPE 0x41 #define SHM_SWP_TYPE 0x40
extern void shm_no_page (ulong *); extern void shm_no_page (ulong *);
/* /*
......
...@@ -44,6 +44,7 @@ struct screen_info { ...@@ -44,6 +44,7 @@ struct screen_info {
unsigned short orig_video_ega_bx; unsigned short orig_video_ega_bx;
unsigned short orig_video_ega_cx; unsigned short orig_video_ega_cx;
unsigned char orig_video_lines; unsigned char orig_video_lines;
unsigned short orig_video_points;
}; };
extern struct screen_info screen_info; extern struct screen_info screen_info;
...@@ -57,6 +58,7 @@ extern struct screen_info screen_info; ...@@ -57,6 +58,7 @@ extern struct screen_info screen_info;
#define ORIG_VIDEO_EGA_BX (screen_info.orig_video_ega_bx) #define ORIG_VIDEO_EGA_BX (screen_info.orig_video_ega_bx)
#define ORIG_VIDEO_EGA_CX (screen_info.orig_video_ega_cx) #define ORIG_VIDEO_EGA_CX (screen_info.orig_video_ega_cx)
#define ORIG_VIDEO_LINES (screen_info.orig_video_lines) #define ORIG_VIDEO_LINES (screen_info.orig_video_lines)
#define ORIG_VIDEO_POINTS (screen_info.orig_video_points)
#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */ #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
#define VIDEO_TYPE_CGA 0x11 /* CGA Display */ #define VIDEO_TYPE_CGA 0x11 /* CGA Display */
......
...@@ -502,7 +502,7 @@ int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr) ...@@ -502,7 +502,7 @@ int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
return -EIDRM; return -EIDRM;
} }
shmd->vm_pte = (SHM_SWP_TYPE << 1) | (id << SHM_ID_SHIFT); shmd->vm_pte = SWP_ENTRY(SHM_SWP_TYPE, id);
shmd->vm_start = addr; shmd->vm_start = addr;
shmd->vm_end = addr + shp->shm_npages * PAGE_SIZE; shmd->vm_end = addr + shp->shm_npages * PAGE_SIZE;
shmd->vm_task = current; shmd->vm_task = current;
......
...@@ -28,25 +28,26 @@ ...@@ -28,25 +28,26 @@
* though. * though.
*/ */
static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, static inline void multi_bmap(struct inode * inode, unsigned int block, unsigned int * nr, int shift)
unsigned long page, int no_share)
{ {
struct inode * inode = area->vm_inode; int i = PAGE_SIZE >> shift;
unsigned int block; block >>= shift;
int nr[8];
int i, *p;
address &= PAGE_MASK;
block = address - area->vm_start + area->vm_offset;
block >>= inode->i_sb->s_blocksize_bits;
i = PAGE_SIZE >> inode->i_sb->s_blocksize_bits;
p = nr;
do { do {
*p = bmap(inode,block); *nr = bmap(inode, block);
i--; i--;
block++; block++;
p++; nr++;
} while (i > 0); } while (i > 0);
}
static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address,
unsigned long page, int no_share)
{
struct inode * inode = area->vm_inode;
int nr[PAGE_SIZE/512];
multi_bmap(inode, (address & PAGE_MASK) - area->vm_start + area->vm_offset, nr,
inode->i_sb->s_blocksize_bits);
return bread_page(page, inode->i_dev, nr, inode->i_sb->s_blocksize, no_share); return bread_page(page, inode->i_dev, nr, inode->i_sb->s_blocksize, no_share);
} }
...@@ -65,9 +66,10 @@ static void filemap_sync_page(struct vm_area_struct * vma, ...@@ -65,9 +66,10 @@ static void filemap_sync_page(struct vm_area_struct * vma,
unsigned long offset, unsigned long offset,
unsigned long page) unsigned long page)
{ {
struct inode * inode;
int nr[PAGE_SIZE/512];
struct buffer_head * bh; struct buffer_head * bh;
printk("msync: %ld: [%08lx]\n", offset, page);
bh = buffer_pages[MAP_NR(page)]; bh = buffer_pages[MAP_NR(page)];
if (bh) { if (bh) {
/* whee.. just mark the buffer heads dirty */ /* whee.. just mark the buffer heads dirty */
...@@ -78,9 +80,49 @@ static void filemap_sync_page(struct vm_area_struct * vma, ...@@ -78,9 +80,49 @@ static void filemap_sync_page(struct vm_area_struct * vma,
} while (tmp != bh); } while (tmp != bh);
return; return;
} }
/* we'll need to go fetch the buffer heads etc.. RSN */ inode = vma->vm_inode;
printk("Can't handle non-shared page yet\n"); multi_bmap(inode, offset, nr, inode->i_sb->s_blocksize_bits);
return; bwrite_page(page, inode->i_dev, nr, inode->i_sb->s_blocksize);
}
/*
* Swapping to a shared file: while we're busy writing out the page
* (and the page still exists in memory), we save the page information
* in the page table, so that "filemap_swapin()" can re-use the page
* immediately if it is called while we're busy swapping it out..
*
* Once we've written it all out, we mark the page entry "empty", which
* will result in a normal page-in (instead of a swap-in) from the now
* up-to-date shared file mapping.
*/
void filemap_swapout(struct vm_area_struct * vma,
unsigned long offset,
pte_t *page_table)
{
unsigned long page = pte_page(*page_table);
unsigned long entry = SWP_ENTRY(SHM_SWP_TYPE, MAP_NR(page));
pte_val(*page_table) = entry;
filemap_sync_page(vma, offset, page);
if (pte_val(*page_table) == entry)
pte_clear(page_table);
}
/*
* filemap_swapin() is called only if we have something in the page
* tables that is non-zero (but not present), which we know to be the
* page index of a page that is busy being swapped out (see above).
* So we just use it directly..
*/
static pte_t filemap_swapin(struct vm_area_struct * vma,
unsigned long offset,
unsigned long entry)
{
unsigned long page = SWP_OFFSET(entry);
mem_map[page]++;
page = (page << PAGE_SHIFT) + PAGE_OFFSET;
return pte_mkdirty(mk_pte(page,vma->vm_page_prot));
} }
static inline void filemap_sync_pte(pte_t * pte, struct vm_area_struct *vma, static inline void filemap_sync_pte(pte_t * pte, struct vm_area_struct *vma,
...@@ -188,21 +230,6 @@ static void filemap_close(struct vm_area_struct * vma) ...@@ -188,21 +230,6 @@ static void filemap_close(struct vm_area_struct * vma)
filemap_sync(vma, vma->vm_start, vma->vm_end - vma->vm_start, MS_ASYNC); filemap_sync(vma, vma->vm_start, vma->vm_end - vma->vm_start, MS_ASYNC);
} }
/*
* This isn't implemented yet: you'll get a warning and incorrect behaviour.
*
* Note that the page is free'd by the higher-level after return,
* so we have to either write it out or just forget it. We currently
* forget it..
*/
void filemap_swapout(struct vm_area_struct * vma,
unsigned long offset,
pte_t *page_table)
{
printk("swapout not implemented on shared files..\n");
pte_clear(page_table);
}
/* /*
* Shared mappings need to be able to do the right thing at * Shared mappings need to be able to do the right thing at
* close/unmap/sync. They will also use the private file as * close/unmap/sync. They will also use the private file as
...@@ -218,7 +245,7 @@ static struct vm_operations_struct file_shared_mmap = { ...@@ -218,7 +245,7 @@ static struct vm_operations_struct file_shared_mmap = {
filemap_nopage, /* nopage */ filemap_nopage, /* nopage */
NULL, /* wppage */ NULL, /* wppage */
filemap_swapout, /* swapout */ filemap_swapout, /* swapout */
NULL, /* swapin */ filemap_swapin, /* swapin */
}; };
/* /*
...@@ -253,15 +280,8 @@ int generic_mmap(struct inode * inode, struct file * file, struct vm_area_struct ...@@ -253,15 +280,8 @@ int generic_mmap(struct inode * inode, struct file * file, struct vm_area_struct
return -ENOEXEC; return -ENOEXEC;
ops = &file_private_mmap; ops = &file_private_mmap;
if (vma->vm_flags & VM_SHARED) { if (vma->vm_flags & VM_SHARED) {
if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) { if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
static int nr = 0;
ops = &file_shared_mmap; ops = &file_shared_mmap;
#ifndef SHARED_MMAP_REALLY_WORKS /* it doesn't, yet */
if (nr++ < 5)
printk("%s tried to do a shared writeable mapping\n", current->comm);
return -EINVAL;
#endif
}
} }
if (!IS_RDONLY(inode)) { if (!IS_RDONLY(inode)) {
inode->i_atime = CURRENT_TIME; inode->i_atime = CURRENT_TIME;
......
...@@ -211,7 +211,7 @@ void swap_duplicate(unsigned long entry) ...@@ -211,7 +211,7 @@ void swap_duplicate(unsigned long entry)
return; return;
offset = SWP_OFFSET(entry); offset = SWP_OFFSET(entry);
type = SWP_TYPE(entry); type = SWP_TYPE(entry);
if (type == SHM_SWP_TYPE) if (type & SHM_SWP_TYPE)
return; return;
if (type >= nr_swapfiles) { if (type >= nr_swapfiles) {
printk("Trying to duplicate nonexistent swap-page\n"); printk("Trying to duplicate nonexistent swap-page\n");
...@@ -238,7 +238,7 @@ void swap_free(unsigned long entry) ...@@ -238,7 +238,7 @@ void swap_free(unsigned long entry)
if (!entry) if (!entry)
return; return;
type = SWP_TYPE(entry); type = SWP_TYPE(entry);
if (type == SHM_SWP_TYPE) if (type & SHM_SWP_TYPE)
return; return;
if (type >= nr_swapfiles) { if (type >= nr_swapfiles) {
printk("Trying to free nonexistent swap-page\n"); printk("Trying to free nonexistent swap-page\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment