Commit fd46db1c authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.86

parent af90ad9d
...@@ -508,6 +508,13 @@ N: Kai M"akisara ...@@ -508,6 +508,13 @@ N: Kai M"akisara
E: Kai.Makisara@vtt.fi E: Kai.Makisara@vtt.fi
D: SCSI Tape Driver D: SCSI Tape Driver
N: Hamish Macdonald
E: hamish@border.ocunix.on.ca
D: Linux/68k port
S: 102-B Valleystream Drive
S: Nepean, Ontario
S: Canada K2H-9E1
N: Peter MacDonald N: Peter MacDonald
D: SLS distribution D: SLS distribution
D: Initial implementation of VC's, pty's and select() D: Initial implementation of VC's, pty's and select()
...@@ -914,6 +921,7 @@ D: Original kernel README ...@@ -914,6 +921,7 @@ D: Original kernel README
D: Linux News (electronic magazine) D: Linux News (electronic magazine)
D: Meta-FAQ, originator D: Meta-FAQ, originator
D: INFO-SHEET, former maintainer D: INFO-SHEET, former maintainer
D: Author of the longest-living linux bug
S: Ohratie 16 C 198 S: Ohratie 16 C 198
S: sf-01370 Vantaa S: sf-01370 Vantaa
S: Finland S: Finland
......
VERSION = 1 VERSION = 1
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 85 SUBLEVEL = 86
ARCH = i386 ARCH = i386
...@@ -228,10 +228,6 @@ clean: archclean ...@@ -228,10 +228,6 @@ clean: archclean
rm -f vmlinux System.map rm -f vmlinux System.map
rm -f .tmp* drivers/sound/configure rm -f .tmp* drivers/sound/configure
rm -fr modules/* rm -fr modules/*
ifdef CONFIG_MODVERSIONS
rm -f $(TOPDIR)/include/linux/modversions.h
rm -f $(TOPDIR)/include/linux/modules/*
endif
mrproper: clean mrproper: clean
rm -f include/linux/autoconf.h include/linux/version.h rm -f include/linux/autoconf.h include/linux/version.h
...@@ -239,6 +235,10 @@ mrproper: clean ...@@ -239,6 +235,10 @@ mrproper: clean
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`
ifdef CONFIG_MODVERSIONS
rm -f $(TOPDIR)/include/linux/modversions.h
rm -f $(TOPDIR)/include/linux/modules/*
endif
distclean: mrproper distclean: mrproper
......
...@@ -111,11 +111,12 @@ COMPILING the kernel: ...@@ -111,11 +111,12 @@ COMPILING the kernel:
- keep a backup kernel handy in case something goes wrong. - keep a backup kernel handy in case something goes wrong.
- 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/zImage after compilation) to the place image (found in /usr/src/linux/arch/i386/boot/zImage after compilation)
where your regular bootable kernel is found. to the place where your regular bootable kernel is found.
For some, this is on a floppy disk, in which case you can "cp For some, this is on a floppy disk, in which case you can "cp
/usr/src/linux/zImage /dev/fd0" to make a bootable floppy. /usr/src/linux/arch/i386/boot/zImage /dev/fd0" to make a bootable
floppy.
If you boot Linux from the hard drive, chances are you use LILO which If you boot Linux from the hard drive, chances are you use LILO which
uses the kernel image as specified in the file /etc/lilo/config. The uses the kernel image as specified in the file /etc/lilo/config. The
......
...@@ -9,7 +9,7 @@ bool 'Kernel math emulation' CONFIG_MATH_EMULATION n ...@@ -9,7 +9,7 @@ bool 'Kernel math emulation' CONFIG_MATH_EMULATION n
bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD y bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD y
bool 'Normal (MFM/RLL) disk and IDE disk/cdrom support' CONFIG_ST506 y bool 'Normal (MFM/RLL) disk and IDE disk/cdrom support' CONFIG_ST506 y
if [ "$CONFIG_ST506" = "y" ]; then if [ "$CONFIG_ST506" = "y" ]; then
comment 'Please see block/drivers/README.ide for help/info on IDE drives' comment 'Please see drivers/block/README.ide for help/info on IDE drives'
bool ' Use old (reliable) disk-only driver for primary i/f' CONFIG_BLK_DEV_HD y bool ' Use old (reliable) disk-only driver for primary i/f' CONFIG_BLK_DEV_HD y
if [ "$CONFIG_BLK_DEV_HD" = "y" ]; then if [ "$CONFIG_BLK_DEV_HD" = "y" ]; then
bool ' Include new IDE driver for secondary i/f support' CONFIG_BLK_DEV_IDE n bool ' Include new IDE driver for secondary i/f support' CONFIG_BLK_DEV_IDE n
...@@ -53,6 +53,7 @@ bool 'Assume subnets are local' CONFIG_INET_SNARL y ...@@ -53,6 +53,7 @@ bool 'Assume subnets are local' CONFIG_INET_SNARL y
bool 'Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n bool 'Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n
fi fi
bool 'The IPX protocol' CONFIG_IPX n bool 'The IPX protocol' CONFIG_IPX n
#bool 'Appletalk DDP' CONFIG_ATALK n
#bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n #bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n
fi fi
...@@ -109,7 +110,7 @@ if [ "$CONFIG_NETDEVICES" = "n" ]; then ...@@ -109,7 +110,7 @@ if [ "$CONFIG_NETDEVICES" = "n" ]; then
comment 'Skipping network driver configuration options...' comment 'Skipping network driver configuration options...'
else else
bool 'Dummy net driver support' CONFIG_DUMMY n bool 'Dummy net driver support' CONFIG_DUMMY y
bool 'SLIP (serial line) support' CONFIG_SLIP n bool 'SLIP (serial line) support' CONFIG_SLIP n
if [ "$CONFIG_SLIP" = "y" ]; then if [ "$CONFIG_SLIP" = "y" ]; then
bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED y bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED y
...@@ -160,6 +161,7 @@ if [ "$CONFIG_NET_EISA" = "y" ]; then ...@@ -160,6 +161,7 @@ if [ "$CONFIG_NET_EISA" = "y" ]; then
bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n
fi fi
bool 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n bool 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n
bool 'DE425, DE434, DE435 support' CONFIG_DE4x5 n
# bool 'DEC 21040 PCI support' CONFIG_DEC_ELCP n # bool 'DEC 21040 PCI support' CONFIG_DEC_ELCP n
# bool 'LPL T100V 100Mbs support' CONFIG_LPL_T100 n # bool 'LPL T100V 100Mbs support' CONFIG_LPL_T100 n
# bool 'PCnet32 (32 bit VLB and PCI LANCE) support' CONFIG_PCNET32 n # bool 'PCnet32 (32 bit VLB and PCI LANCE) support' CONFIG_PCNET32 n
......
...@@ -54,7 +54,7 @@ struct screen_info screen_info; ...@@ -54,7 +54,7 @@ struct screen_info screen_info;
unsigned char aux_device_present; unsigned char aux_device_present;
extern int ramdisk_size; extern int ramdisk_size;
extern int root_mountflags; extern int root_mountflags;
extern int end; extern int etext, edata, end;
extern char empty_zero_page[PAGE_SIZE]; extern char empty_zero_page[PAGE_SIZE];
...@@ -95,6 +95,10 @@ void setup_arch(char **cmdline_p, ...@@ -95,6 +95,10 @@ void setup_arch(char **cmdline_p,
if (MOUNT_ROOT_RDONLY) if (MOUNT_ROOT_RDONLY)
root_mountflags |= MS_RDONLY; root_mountflags |= MS_RDONLY;
memory_start = (unsigned long) &end; memory_start = (unsigned long) &end;
init_task.mm->start_code = TASK_SIZE;
init_task.mm->end_code = TASK_SIZE + (unsigned long) &etext;
init_task.mm->end_data = TASK_SIZE + (unsigned long) &edata;
init_task.mm->brk = TASK_SIZE + (unsigned long) &end;
for (;;) { for (;;) {
if (c == ' ' && *(unsigned long *)from == *(unsigned long *)"mem=") { if (c == ' ' && *(unsigned long *)from == *(unsigned long *)"mem=") {
......
# #
# mips/Makefile # arch/mips/Makefile
# #
# This file is included by the global makefile so that you can add your own # This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions # architecture-specific flags and dependencies. Remember to do have actions
...@@ -20,18 +20,23 @@ LD = mips-linux-ld ...@@ -20,18 +20,23 @@ LD = mips-linux-ld
LINKFLAGS = -Ttext 0xa0000000 LINKFLAGS = -Ttext 0xa0000000
#HOSTCC = gcc #HOSTCC = gcc
# #
# KERNELBASE isn't quite useless, but I need it to work # KERNELBASE is quite useless, but I need it to work
# around a hardware bug in my Wreckstation board. Other people # around a hardware bug in my Wreckstation board. Other people
# would burn that @#!%# thing... # would burn that @#!%# thing...
# #
CC = mips-linux-gcc -V 2.5.8 -D__KERNEL__ -I$(TOPDIR)/include CC = mips-linux-gcc -V 2.5.8 -D__KERNEL__ -I$(TOPDIR)/include
CPP = $(CC) -E $(CFLAGS)
AR = mips-linux-ar AR = mips-linux-ar
RANLIB = mips-linux-ranlib RANLIB = mips-linux-ranlib
STRIP = mips-linux-strip STRIP = mips-linux-strip
CFLAGS := $(CFLAGS) #-pipe CFLAGS := $(CFLAGS) #-pipe
CFLAGS := $(CFLAGS) -Wa,-mips3 -mcpu=r4000 -D__R4000__ -DKERNELBASE=0xa0000000 CFLAGS := $(CFLAGS) -DKERNELBASE=0xa0000000
ifdef CONFIG_R4X00
CFLAGS := $(CFLAGS) -Wa,-mips3 -mcpu=r4000 -D__R4000__
endif
HEAD := arch/mips/kernel/head.o HEAD := arch/mips/kernel/head.o
......
...@@ -3,12 +3,20 @@ ...@@ -3,12 +3,20 @@
# see the Configure script. # see the Configure script.
# #
comment 'Machine setup'
bool 'Support for Deskstation Tyne' CONFIG_DESKSTATION_TYNE y
bool 'Support for Acer PICA 1 chipset' CONFIG_ACER_PICA_61 y
bool 'Support for DECstation' CONFIG_DECSTATION n
bool 'Generate code for R4x00' CONFIG_R4X00 y
comment 'General setup' comment 'General setup'
bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD n bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD y
bool 'Normal harddisk support' CONFIG_BLK_DEV_HD n
bool 'Normal (MFM/RLL) disk and IDE disk/cdrom support' CONFIG_ST506 y bool 'Normal (MFM/RLL) disk and IDE disk/cdrom support' CONFIG_ST506 y
if [ "$CONFIG_ST506" = "y" ]; then if [ "$CONFIG_ST506" = "y" ]; then
comment 'Please see block/drivers/README.ide for help/info on IDE drives'
bool ' Use old (reliable) disk-only driver for primary i/f' CONFIG_BLK_DEV_HD y bool ' Use old (reliable) disk-only driver for primary i/f' CONFIG_BLK_DEV_HD y
if [ "$CONFIG_BLK_DEV_HD" = "y" ]; then if [ "$CONFIG_BLK_DEV_HD" = "y" ]; then
bool ' Include new IDE driver for secondary i/f support' CONFIG_BLK_DEV_IDE n bool ' Include new IDE driver for secondary i/f support' CONFIG_BLK_DEV_IDE n
...@@ -27,7 +35,7 @@ bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF n ...@@ -27,7 +35,7 @@ bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF n
if [ "$CONFIG_NET" = "y" ]; then if [ "$CONFIG_NET" = "y" ]; then
comment 'Networking options' comment 'Networking options'
bool 'TCP/IP networking' CONFIG_INET n bool 'TCP/IP networking' CONFIG_INET y
if [ "$CONFIG_INET" "=" "y" ]; then if [ "$CONFIG_INET" "=" "y" ]; then
bool 'IP forwarding/gatewaying' CONFIG_IP_FORWARD y bool 'IP forwarding/gatewaying' CONFIG_IP_FORWARD y
bool 'IP multicasting (ALPHA)' CONFIG_IP_MULTICAST n bool 'IP multicasting (ALPHA)' CONFIG_IP_MULTICAST n
...@@ -89,7 +97,7 @@ if [ "$CONFIG_NET" = "y" ]; then ...@@ -89,7 +97,7 @@ if [ "$CONFIG_NET" = "y" ]; then
comment 'Network device support' comment 'Network device support'
bool 'Network device support?' CONFIG_NETDEVICES y bool 'Network device support?' CONFIG_NETDEVICES n
if [ "$CONFIG_NETDEVICES" = "n" ]; then if [ "$CONFIG_NETDEVICES" = "n" ]; then
comment 'Skipping network driver configuration options...' comment 'Skipping network driver configuration options...'
......
...@@ -19,19 +19,27 @@ ...@@ -19,19 +19,27 @@
$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
OBJS = process.o signal.o entry.o traps.o irq.o ptrace.o cache.o resume.o \ OBJS = process.o signal.o entry.o traps.o irq.o ptrace.o cache.o resume.o \
ioport.o setup.o bios32.o ioport.o setup.o bios32.o tynedma.o
all: kernel.o head.o all: kernel.o head.o
head.o: head.s
head.s: head.S $(TOPDIR)/include/linux/tasks.h
cache.o: cache.s cache.o: cache.s
cache.s: cache.S $(TOPDIR)/include/asm/mipsconfig.h \ cache.s: cache.S $(TOPDIR)/include/asm/mipsconfig.h \
$(TOPDIR)/include/asm/regdef.h $(TOPDIR)/include/asm/segment.h $(TOPDIR)/include/asm/regdef.h $(TOPDIR)/include/asm/segment.h
entry.o: entry.s
entry.s: entry.S $(TOPDIR)/include/linux/sys.h \
$(TOPDIR)/include/linux/autoconf.h $(TOPDIR)/include/asm/segment.h \
$(TOPDIR)/include/asm/mipsregs.h $(TOPDIR)/include/asm/mipsconfig.h \
$(TOPDIR)/include/asm/page.h $(TOPDIR)/include/asm/stackframe.h \
$(TOPDIR)/include/asm/regdef.h $(TOPDIR)/include/asm/processor.h
head.o: head.s
head.s: head.S $(TOPDIR)/include/linux/tasks.h
resume.o: resume.s resume.o: resume.s
resume.s: resume.S $(TOPDIR)/include/asm/regdef.h \ resume.s: resume.S $(TOPDIR)/include/asm/regdef.h \
...@@ -48,7 +56,7 @@ kernel.o: $(OBJS) ...@@ -48,7 +56,7 @@ kernel.o: $(OBJS)
sync sync
dep: dep:
$(CPP) $(CFLAGS) -M *.c > .depend $(CPP) -M *.c > .depend
modules: modules:
......
...@@ -12,10 +12,11 @@ ...@@ -12,10 +12,11 @@
*/ */
#include <linux/sys.h> #include <linux/sys.h>
#include <linux/autoconf.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
#include <asm/mipsconfig.h> #include <asm/mipsconfig.h>
#include <asm/mm.h> #include <asm/page.h>
#include <asm/stackframe.h> #include <asm/stackframe.h>
#include <asm/regdef.h> #include <asm/regdef.h>
#include <asm/processor.h> #include <asm/processor.h>
...@@ -185,16 +186,17 @@ skip_signal_return: ...@@ -185,16 +186,17 @@ skip_signal_return:
return: RESTORE_ALL return: RESTORE_ALL
.set at .set at
#ifdef CONFIG_DESKSTATION_TYNE
/* /*
* Assumptions for _handle_int: * Deskstation Tyne interrupt handler
* - only bank a or b are possible interrupt sources
*/ */
.text .text
.set noreorder .set noreorder
.set noat .set noat
.globl _handle_int .globl _deskstation_tyne_handle_int
.align 5 .align 5
_handle_int: SAVE_ALL _deskstation_tyne_handle_int:
SAVE_ALL
.set at .set at
CLI CLI
lui s0,%hi(PORT_BASE) lui s0,%hi(PORT_BASE)
...@@ -202,7 +204,7 @@ _handle_int: SAVE_ALL ...@@ -202,7 +204,7 @@ _handle_int: SAVE_ALL
sb t1,%lo(PORT_BASE+0x20)(s0) # poll command sb t1,%lo(PORT_BASE+0x20)(s0) # poll command
lb t1,%lo(PORT_BASE+0x20)(s0) # read result lb t1,%lo(PORT_BASE+0x20)(s0) # read result
li s1,1 li s1,1
bgtz t1,poll_second bgtz t1,Lpoll_second
andi t1,t1,7 andi t1,t1,7
/* /*
* Acknowledge first pic * Acknowledge first pic
...@@ -243,11 +245,11 @@ _handle_int: SAVE_ALL ...@@ -243,11 +245,11 @@ _handle_int: SAVE_ALL
sb t1,%lo(PORT_BASE+0x21)(s0) # delay slot sb t1,%lo(PORT_BASE+0x21)(s0) # delay slot
.align 5 .align 5
poll_second: li t1,0x0f Lpoll_second: li t1,0x0f
sb t1,%lo(PORT_BASE+0xa0)(s0) # poll command sb t1,%lo(PORT_BASE+0xa0)(s0) # poll command
lb t1,%lo(PORT_BASE+0xa0)(s0) # read result lb t1,%lo(PORT_BASE+0xa0)(s0) # read result
lui s4,%hi(_cache_A1) lui s4,%hi(_cache_A1)
bgtz t1,spurious_interrupt bgtz t1,Lspurious_interrupt
andi t1,t1,7 andi t1,t1,7
/* /*
* Acknowledge second pic * Acknowledge second pic
...@@ -288,7 +290,7 @@ poll_second: li t1,0x0f ...@@ -288,7 +290,7 @@ poll_second: li t1,0x0f
sb t1,%lo(PORT_BASE+0xa1)(s0) # delay slot sb t1,%lo(PORT_BASE+0xa1)(s0) # delay slot
.align 5 .align 5
spurious_interrupt: Lspurious_interrupt:
/* /*
* Nothing happened... (whistle) * Nothing happened... (whistle)
*/ */
...@@ -298,7 +300,29 @@ spurious_interrupt: ...@@ -298,7 +300,29 @@ spurious_interrupt:
addiu t0,t0,1 addiu t0,t0,1
jr ra jr ra
sw t0,%lo(_spurious_count)(t1) sw t0,%lo(_spurious_count)(t1)
#endif /* CONFIG_DESKSTATION_TYNE */
#ifdef CONFIG_ACER_PICA_61
/*
* Acer PICA interrupt handler dummy
*/
.set noreorder
.set noat
.globl _acer_pica_61_handle_int
.align 5
_acer_pica_61_handle_int:
la a0,acer_text
jal _panic
nop
1: b 1b
nop
acer_text: .asciz "Interrupt handler for Acer PICA not written yet"
.align 2
#endif /* CONFIG_ACER_PICA_61 */
.text
.set noreorder
.set at
.globl _interrupt .globl _interrupt
.align 5 .align 5
_interrupt: move s2,ra _interrupt: move s2,ra
...@@ -418,13 +442,13 @@ invalid_tlbl: ...@@ -418,13 +442,13 @@ invalid_tlbl:
ori k0,k0,3 ori k0,k0,3
xori k0,k0,3 xori k0,k0,3
lw k1,(k0) lw k1,(k0)
andi k1,k1,PAGE_PRESENT andi k1,k1,_PAGE_PRESENT
beqz k1,nopage_tlbl beqz k1,nopage_tlbl
/* /*
* Present bit is set -> set valid and accessed bits * Present bit is set -> set valid and accessed bits
*/ */
lw k1,(k0) # delay slot lw k1,(k0) # delay slot
ori k1,k1,PAGE_ACCESSED ori k1,k1,_PAGE_ACCESSED
sw k1,(k0) sw k1,(k0)
eret eret
...@@ -483,13 +507,13 @@ _handle_tlbs: ...@@ -483,13 +507,13 @@ _handle_tlbs:
ori k0,k0,3 ori k0,k0,3
xori k0,k0,3 xori k0,k0,3
lw k1,(k0) lw k1,(k0)
andi k1,k1,(PAGE_PRESENT|PAGE_RW) andi k1,k1,(_PAGE_PRESENT|_PAGE_RW)
beqz k1,nopage_tlbs beqz k1,nopage_tlbs
/* /*
* Present and writable bits set -> set accessed and dirty bits. * Present and writable bits set -> set accessed and dirty bits.
*/ */
lw k1,(k0) # delay slot lw k1,(k0) # delay slot
ori k1,k1,PAGE_ACCESSED|PAGE_DIRTY ori k1,k1,(_PAGE_ACCESSED|_PAGE_DIRTY)
sw k1,(k0) sw k1,(k0)
/* /*
* Now reload the entry into the tlb * Now reload the entry into the tlb
...@@ -567,13 +591,13 @@ _handle_mod: ...@@ -567,13 +591,13 @@ _handle_mod:
ori k0,k0,3 ori k0,k0,3
xori k0,k0,3 xori k0,k0,3
lw k1,(k0) lw k1,(k0)
andi k1,k1,PAGE_RW andi k1,k1,_PAGE_RW
beqz k1,nopage_tlbs beqz k1,nopage_tlbs
/* /*
* Present and writable bits set -> set accessed and dirty bits. * Present and writable bits set -> set accessed and dirty bits.
*/ */
lw k1,(k0) # delay slot lw k1,(k0) # delay slot
ori k1,k1,(PAGE_ACCESSED|PAGE_DIRTY) ori k1,k1,(_PAGE_ACCESSED|_PAGE_DIRTY)
sw k1,(k0) sw k1,(k0)
/* /*
* Now reload the entry into the tlb * Now reload the entry into the tlb
......
...@@ -36,8 +36,6 @@ ...@@ -36,8 +36,6 @@
.globl _empty_bad_page_table .globl _empty_bad_page_table
.globl _pg0 .globl _pg0
.globl _empty_zero_page .globl _empty_zero_page
.globl _tmp_floppy_area
.globl _floppy_track_buffer
.globl _swapper_pg_dir .globl _swapper_pg_dir
.text .text
...@@ -438,16 +436,7 @@ final: ...@@ -438,16 +436,7 @@ final:
.data .data
/* /*
* Instead of Intel's strange and unportable segment descriptor magic * Inital mapping tables for supported Mips boards.
* we difference user and kernel space by their address.
* Kernel space (== physical memory) is mapped at KSEG[01],
* User space is mapped at 0x0.
*/
.globl _segment_fs
_segment_fs: .word KERNEL_DS
/*
* Initial mapping tables for supported Mips boards.
* First item is always the number of wired TLB entries, * First item is always the number of wired TLB entries,
* following by EntryHi/EntryLo pairs and page mask. * following by EntryHi/EntryLo pairs and page mask.
* Since everything must be quad-aligned (8) we insert * Since everything must be quad-aligned (8) we insert
...@@ -723,19 +712,25 @@ _empty_zero_page = 0x5000 ...@@ -723,19 +712,25 @@ _empty_zero_page = 0x5000
.org 0x6000 .org 0x6000
#if defined (CONFIG_DESKSTATION_TYNE) && !defined (CONFIG_ACER_PICA_61)
#if 0
/* /*
* tmp_floppy_area is used by the floppy-driver when DMA cannot * tmp_floppy_area is used by the floppy-driver when DMA cannot
* reach to a buffer-block. It needs to be aligned, so that it isn't * reach to a buffer-block. It needs to be aligned, so that it isn't
* on a 64kB border. * on a 64kB border.
*/ */
.globl _tmp_floppy_area
_tmp_floppy_area: .fill 1024,1,0 _tmp_floppy_area: .fill 1024,1,0
#endif
/* /*
* floppy_track_buffer is used to buffer one track of floppy data: it * floppy_track_buffer is used to buffer one track of floppy data: it
* has to be separate from the tmp_floppy area, as otherwise a single- * has to be separate from the tmp_floppy area, as otherwise a single-
* sector read/write can mess it up. It can contain one full cylinder (sic) of * sector read/write can mess it up. It can contain one full cylinder (sic) of
* data (36*2*512 bytes). * data (36*2*512 bytes).
*/ */
.globl _floppy_track_buffer
_floppy_track_buffer: .fill 512*2*36,1,0 _floppy_track_buffer: .fill 512*2*36,1,0
#endif /* defined (CONFIG_DESKSTATION_TYNE) && !defined (CONFIG_ACER_PICA_61) */
.globl _kernelsp .globl _kernelsp
_kernelsp: .word 0 _kernelsp: .word 0
beepflag: .word 0 beepflag: .word 0
...@@ -15,6 +15,13 @@ ...@@ -15,6 +15,13 @@
* Naturally it's not a 1:1 relation, but there are similarities. * Naturally it's not a 1:1 relation, but there are similarities.
*/ */
/*
* The Deskstation Tyne is almost completly like an IBM compatible PC with
* another type of microprocessor. Therefore this code is almost completly
* the same. More work needs to be done to support Acer PICA and other
* machines.
*/
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
......
...@@ -44,7 +44,7 @@ asmlinkage int sys_idle(void) ...@@ -44,7 +44,7 @@ asmlinkage int sys_idle(void)
#if 0 #if 0
/* Map out the low memory: it's no longer needed */ /* Map out the low memory: it's no longer needed */
for (i = 0 ; i < 512 ; i++) for (i = 0 ; i < 512 ; i++)
swapper_pg_dir[i] = 0; pgd_clear(swapper_pg_dir + i);
#endif #endif
/* endless idle loop with no priority at all */ /* endless idle loop with no priority at all */
......
...@@ -84,23 +84,30 @@ static inline int put_stack_long(struct task_struct *task, int offset, ...@@ -84,23 +84,30 @@ static inline int put_stack_long(struct task_struct *task, int offset,
*/ */
static unsigned long get_long(struct vm_area_struct * vma, unsigned long addr) static unsigned long get_long(struct vm_area_struct * vma, unsigned long addr)
{ {
pgd_t * pgdir;
pte_t * pgtable;
unsigned long page; unsigned long page;
repeat: repeat:
page = *PAGE_DIR_OFFSET(vma->vm_task, addr); pgdir = PAGE_DIR_OFFSET(vma->vm_task, addr);
if (page & PAGE_PRESENT) { if (pgd_none(*pgdir)) {
page &= PAGE_MASK; do_no_page(vma, addr, 0);
page += PAGE_PTR(addr); goto repeat;
page = *((unsigned long *) page); }
if (pgd_bad(*pgdir)) {
printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
pgd_clear(pgdir);
return 0;
} }
if (!(page & PAGE_PRESENT)) { pgtable = (pte_t *) (PAGE_PTR(addr) + pgd_page(*pgdir));
if (!pte_present(*pgtable)) {
do_no_page(vma, addr, 0); do_no_page(vma, addr, 0);
goto repeat; goto repeat;
} }
page = pte_page(*pgtable);
/* this is a hack for non-kernel-mapped video buffers and similar */ /* this is a hack for non-kernel-mapped video buffers and similar */
if (page >= high_memory) if (page >= high_memory)
return 0; return 0;
page &= PAGE_MASK;
page += addr & ~PAGE_MASK; page += addr & ~PAGE_MASK;
return *(unsigned long *) page; return *(unsigned long *) page;
} }
...@@ -117,39 +124,40 @@ static unsigned long get_long(struct vm_area_struct * vma, unsigned long addr) ...@@ -117,39 +124,40 @@ static unsigned long get_long(struct vm_area_struct * vma, unsigned long addr)
static void put_long(struct vm_area_struct * vma, unsigned long addr, static void put_long(struct vm_area_struct * vma, unsigned long addr,
unsigned long data) unsigned long data)
{ {
unsigned long page, pte = 0; pgd_t *pgdir;
int readonly = 0; pte_t *pgtable;
unsigned long page;
repeat: repeat:
page = *PAGE_DIR_OFFSET(vma->vm_task, addr); pgdir = PAGE_DIR_OFFSET(vma->vm_task, addr);
if (page & PAGE_PRESENT) { if (!pgd_present(*pgdir)) {
page &= PAGE_MASK; do_no_page(vma, addr, 1);
page += PAGE_PTR(addr); goto repeat;
pte = page; }
page = *((unsigned long *) page); if (pgd_bad(*pgdir)) {
printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
pgd_clear(pgdir);
return;
} }
if (!(page & PAGE_PRESENT)) { pgtable = (pte_t *) (PAGE_PTR(addr) + pgd_page(*pgdir));
do_no_page(vma, addr, 0 /* PAGE_RW */); if (!pte_present(*pgtable)) {
do_no_page(vma, addr, 1);
goto repeat; goto repeat;
} }
if (!(page & PAGE_RW)) { page = pte_page(*pgtable);
if (!(page & PAGE_COW)) if (!pte_write(*pgtable)) {
readonly = 1; do_wp_page(vma, addr, 1);
do_wp_page(vma, addr, PAGE_RW | PAGE_PRESENT);
goto repeat; goto repeat;
} }
/* this is a hack for non-kernel-mapped video buffers and similar */ /* this is a hack for non-kernel-mapped video buffers and similar */
if (page >= high_memory) if (page < high_memory) {
return;
/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
*(unsigned long *) pte |= (PAGE_DIRTY|PAGE_COW);
page &= PAGE_MASK;
page += addr & ~PAGE_MASK; page += addr & ~PAGE_MASK;
*(unsigned long *) page = data; *(unsigned long *) page = data;
if (readonly) {
*(unsigned long *) pte &=~ (PAGE_RW|PAGE_COW);
invalidate();
} }
/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
/* this should also re-instate whatever read-only mode there was before */
*pgtable = pte_mkdirty(mk_pte(page, vma->vm_page_prot));
invalidate();
} }
static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigned long addr) static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigned long addr)
......
...@@ -59,14 +59,7 @@ _resume: ...@@ -59,14 +59,7 @@ _resume:
*/ */
ori t2,t1,0x1f ori t2,t1,0x1f
xori t2,0x1e xori t2,0x1e
/*
* Save fs (may be pointing to kernel memory)
*/
lui t4,%hi(_segment_fs)
lw t3,%lo(_segment_fs)(t4)
mtc0 t2,CP0_STATUS mtc0 t2,CP0_STATUS
sw t3,TOFF_FS(t0)
/* /*
* Save non-scratch registers * Save non-scratch registers
...@@ -248,14 +241,10 @@ _resume: ...@@ -248,14 +241,10 @@ _resume:
lw ra,TOFF_REG31(a0) lw ra,TOFF_REG31(a0)
/* /*
* Restore fs segment pointer
* Restore status register * Restore status register
*/ */
lw t0,TOFF_FS(a0) lw t0,TOFF_KSP(a0)
lw t1,TOFF_KSP(a0) sw t0,_kernelsp
sw t0,%lo(_segment_fs)(t4)
sw t1,_kernelsp
jr ra jr ra
mtc0 a2,CP0_STATUS # delay slot mtc0 a2,CP0_STATUS # delay slot
...@@ -34,21 +34,16 @@ static inline void console_verbose(void) ...@@ -34,21 +34,16 @@ static inline void console_verbose(void)
#define get_seg_byte(seg,addr) ({ \ #define get_seg_byte(seg,addr) ({ \
register unsigned char __res; \ register unsigned char __res; \
int unsigned long save; \
save = segment_fs; \
__res = get_user_byte(addr); \ __res = get_user_byte(addr); \
segment_fs = save; \
__res;}) __res;})
#define get_seg_long(seg,addr) ({ \ #define get_seg_long(seg,addr) ({ \
register unsigned long __res; \ register unsigned long __res; \
int unsigned long save; \
save = segment_fs; \
__res = get_user_word(addr); \ __res = get_user_word(addr); \
segment_fs = save; \
__res;}) __res;})
extern asmlinkage void handle_int(void); extern asmlinkage void deskstation_tyne_handle_int(void);
extern asmlinkage void acer_pica_61_handle_int(void);
extern asmlinkage void handle_mod(void); extern asmlinkage void handle_mod(void);
extern asmlinkage void handle_tlbl(void); extern asmlinkage void handle_tlbl(void);
extern asmlinkage void handle_tlbs(void); extern asmlinkage void handle_tlbs(void);
...@@ -373,6 +368,12 @@ void trap_init(void) ...@@ -373,6 +368,12 @@ void trap_init(void)
*/ */
switch(boot_info.machtype) { switch(boot_info.machtype) {
case MACH_DESKSTATION_TYNE: case MACH_DESKSTATION_TYNE:
set_except_vector(0, handle_int); set_except_vector(0, deskstation_tyne_handle_int);
break;
case MACH_ACER_PICA_61:
set_except_vector(0, acer_pica_61_handle_int);
break;
default:
panic("Unknown machine type");
} }
} }
/*
* Tiny Tyne DMA buffer allocator
*
* Copyright (C) 1995 Ralf Baechle
*/
#include <linux/autoconf.h>
#include <linux/types.h>
#include <asm/bootinfo.h>
#ifdef CONFIG_DESKSTATION_TYNE
static unsigned long allocated;
/*
* Not very sophisticated, but should suffice for now...
*/
unsigned long deskstation_tyne_dma_alloc(size_t size)
{
unsigned long ret = allocated;
allocated += size;
if (allocated > boot_info.dma_cache_size)
ret = -1;
return ret;
}
void deskstation_tyne_dma_init(void)
{
if (boot_info.machtype != MACH_DESKSTATION_TYNE)
return;
allocated = 0;
printk ("Deskstation Tyne DMA (%luk) buffer initialized.\n",
boot_info.dma_cache_size >> 10);
}
#endif /* CONFIG_DESKSTATION_TYNE */
# #
# Makefile for the linux i386-specific parts of the memory manager. # Makefile for the linux mips-specific parts of the memory manager.
# #
# Note! Dependencies are done automagically by 'make dep', which also # Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here # removes any old dependencies. DON'T put your own dependencies here
...@@ -22,7 +22,7 @@ mm.o: $(OBJS) ...@@ -22,7 +22,7 @@ mm.o: $(OBJS)
modules: modules:
dep: dep:
$(CPP) $(CFLAGS) -M *.c > .depend $(CPP) -M *.c > .depend
# #
# include a dependency file if one exists # include a dependency file if one exists
......
...@@ -27,6 +27,12 @@ extern void die_if_kernel(char *, struct pt_regs *, long); ...@@ -27,6 +27,12 @@ extern void die_if_kernel(char *, struct pt_regs *, long);
* This routine handles page faults. It determines the address, * This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate * and the problem, and then passes it off to one of the appropriate
* routines. * routines.
*
* The error_code parameter just the same as in the i386 version:
*
* bit 0 == 0 means no page found, 1 means protection fault
* bit 1 == 0 means read, 1 means write
* bit 2 == 0 means kernel, 1 means user-mode
*/ */
asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
{ {
...@@ -38,9 +44,12 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -38,9 +44,12 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
__asm__("dmfc0\t%0,$8" __asm__("dmfc0\t%0,$8"
: "=r" (address)); : "=r" (address));
vma = find_vma(current, address); for (vma = current->mm->mmap ; ; vma = vma->vm_next) {
if (!vma) if (!vma)
goto bad_area; goto bad_area;
if (vma->vm_end > address)
break;
}
if (vma->vm_start <= address) if (vma->vm_start <= address)
goto good_area; goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN)) if (!(vma->vm_flags & VM_GROWSDOWN))
...@@ -54,23 +63,24 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -54,23 +63,24 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
* we can handle it.. * we can handle it..
*/ */
good_area: good_area:
#if 0 /*
if (regs->eflags & VM_MASK) { * was it a write?
unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT; */
if (bit < 32) if (error_code & 2) {
current->tss.screen_bitmap |= 1 << bit; if (!(vma->vm_flags & VM_WRITE))
} goto bad_area;
#endif } else {
if (!(vma->vm_page_prot & PAGE_USER)) /* read with protection fault? */
if (error_code & 1)
goto bad_area; goto bad_area;
if (error_code & PAGE_PRESENT) { if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
if (!(vma->vm_page_prot & (PAGE_RW | PAGE_COW)))
goto bad_area; goto bad_area;
do_wp_page(vma, address, error_code); }
if (error_code & 1) {
do_wp_page(vma, address, error_code & 2);
return; return;
} }
printk("do_page_fault: do_no_page(%x, %x, %d)", vma, address, error_code); do_no_page(vma, address, error_code & 2);
do_no_page(vma, address, error_code);
return; return;
/* /*
...@@ -78,30 +88,30 @@ printk("do_page_fault: do_no_page(%x, %x, %d)", vma, address, error_code); ...@@ -78,30 +88,30 @@ printk("do_page_fault: do_no_page(%x, %x, %d)", vma, address, error_code);
* Fix it, but check if it's kernel or user first.. * Fix it, but check if it's kernel or user first..
*/ */
bad_area: bad_area:
printk("Bad Area...\n"); if (user_mode(regs)) {
if (error_code & PAGE_USER) {
current->tss.cp0_badvaddr = address; current->tss.cp0_badvaddr = address;
current->tss.error_code = error_code; current->tss.error_code = error_code;
#if 0
current->tss.trap_no = 14; current->tss.trap_no = 14;
#endif
send_sig(SIGSEGV, current, 1); send_sig(SIGSEGV, current, 1);
return; return;
} }
/* /*
* Oops. The kernel tried to access some bad page. We'll have to * Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice. * terminate things with extreme prejudice.
*/ */
printk("This processor honours the WP bit even when in supervisor mode. Good.\n");
if ((unsigned long) (address-TASK_SIZE) < PAGE_SIZE) { if ((unsigned long) (address-TASK_SIZE) < PAGE_SIZE) {
printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
pg0[0] = PAGE_SHARED; pg0[0] = pte_val(mk_pte(0, PAGE_SHARED));
} else } else
printk(KERN_ALERT "Unable to handle kernel paging request"); printk(KERN_ALERT "Unable to handle kernel paging request");
printk(" at virtual address %08lx\n",address); printk(" at virtual address %08lx\n",address);
page = current->tss.pg_dir; page = current->tss.pg_dir;
printk(KERN_ALERT "current->tss.pg_dir = %08lx\n", page); printk(KERN_ALERT "current->tss.pg_dir = %08lx\n", page);
page = ((unsigned long *) page)[address >> 22]; page = ((unsigned long *) page)[address >> PGDIR_SHIFT];
printk(KERN_ALERT "*pde = %08lx\n", page); printk(KERN_ALERT "*pde = %08lx\n", page);
if (page & PAGE_PRESENT) { if (page & 1) {
page &= PAGE_MASK; page &= PAGE_MASK;
address &= 0x003ff000; address &= 0x003ff000;
page = ((unsigned long *) page)[address >> PAGE_SHIFT]; page = ((unsigned long *) page)[address >> PAGE_SHIFT];
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
extern unsigned long pg0[1024]; /* page table for 0-4MB for everybody */ extern unsigned long pg0[1024]; /* page table for 0-4MB for everybody */
extern void deskstation_tyne_dma_init(void);
extern void scsi_mem_init(unsigned long); extern void scsi_mem_init(unsigned long);
extern void sound_mem_init(void); extern void sound_mem_init(void);
extern void die_if_kernel(char *,struct pt_regs *,long); extern void die_if_kernel(char *,struct pt_regs *,long);
...@@ -41,7 +42,7 @@ extern void show_net_buffers(void); ...@@ -41,7 +42,7 @@ extern void show_net_buffers(void);
* ZERO_PAGE is a special page that is used for zero-initialized * ZERO_PAGE is a special page that is used for zero-initialized
* data and COW. * data and COW.
*/ */
unsigned long __bad_pagetable(void) pte_t * __bad_pagetable(void)
{ {
extern char empty_bad_page_table[PAGE_SIZE]; extern char empty_bad_page_table[PAGE_SIZE];
unsigned long dummy; unsigned long dummy;
...@@ -55,14 +56,14 @@ unsigned long __bad_pagetable(void) ...@@ -55,14 +56,14 @@ unsigned long __bad_pagetable(void)
".set\treorder" ".set\treorder"
:"=r" (dummy), :"=r" (dummy),
"=r" (dummy) "=r" (dummy)
:"r" (BAD_PAGE + PAGE_TABLE), :"r" (pte_val(BAD_PAGE)),
"0" ((long) empty_bad_page_table), "0" ((long) empty_bad_page_table),
"1" (PTRS_PER_PAGE)); "1" (PTRS_PER_PAGE));
return (unsigned long) empty_bad_page_table; return (pte_t *) empty_bad_page_table;
} }
unsigned long __bad_page(void) pte_t __bad_page(void)
{ {
extern char empty_bad_page[PAGE_SIZE]; extern char empty_bad_page[PAGE_SIZE];
unsigned long dummy; unsigned long dummy;
...@@ -79,7 +80,7 @@ unsigned long __bad_page(void) ...@@ -79,7 +80,7 @@ unsigned long __bad_page(void)
:"0" ((long) empty_bad_page), :"0" ((long) empty_bad_page),
"1" (PTRS_PER_PAGE)); "1" (PTRS_PER_PAGE));
return (unsigned long) empty_bad_page; return pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED));
} }
unsigned long __zero_page(void) unsigned long __zero_page(void)
...@@ -141,8 +142,8 @@ extern unsigned long free_area_init(unsigned long, unsigned long); ...@@ -141,8 +142,8 @@ extern unsigned long free_area_init(unsigned long, unsigned long);
*/ */
unsigned long paging_init(unsigned long start_mem, unsigned long end_mem) unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
{ {
unsigned long * pg_dir; pgd_t * pg_dir;
unsigned long * pg_table; pte_t * pg_table;
unsigned long tmp; unsigned long tmp;
unsigned long address; unsigned long address;
...@@ -150,23 +151,21 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem) ...@@ -150,23 +151,21 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
address = 0; address = 0;
pg_dir = swapper_pg_dir; pg_dir = swapper_pg_dir;
while (address < end_mem) { while (address < end_mem) {
tmp = *pg_dir; if (pgd_none(pg_dir[0])) {
tmp &= PAGE_MASK; pgd_set(pg_dir, (pte_t *) start_mem);
if (!tmp) {
tmp = start_mem;
start_mem += PAGE_SIZE; start_mem += PAGE_SIZE;
} }
/* /*
* also map it in at 0x00000000 for init * also map it in at 0x00000000 for init
*/ */
*pg_dir = tmp | PAGE_TABLE; pg_table = (pte_t *) pgd_page(pg_dir[0]);
pgd_set(pg_dir, pg_table);
pg_dir++; pg_dir++;
pg_table = (unsigned long *) (tmp & PAGE_MASK);
for (tmp = 0 ; tmp < PTRS_PER_PAGE ; tmp++,pg_table++) { for (tmp = 0 ; tmp < PTRS_PER_PAGE ; tmp++,pg_table++) {
if (address < end_mem) if (address < end_mem)
*pg_table = address | PAGE_SHARED; *pg_table = mk_pte(address, PAGE_SHARED);
else else
*pg_table = 0; pte_clear(pg_table);
address += PAGE_SIZE; address += PAGE_SIZE;
} }
} }
...@@ -195,6 +194,9 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) ...@@ -195,6 +194,9 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
mem_map[MAP_NR(start_mem)] = 0; mem_map[MAP_NR(start_mem)] = 0;
start_mem += PAGE_SIZE; start_mem += PAGE_SIZE;
} }
#ifdef CONFIG_DESKSTATION_TYNE
deskstation_tyne_dma_init();
#endif
#ifdef CONFIG_SCSI #ifdef CONFIG_SCSI
scsi_mem_init(high_memory); scsi_mem_init(high_memory);
#endif #endif
...@@ -225,6 +227,7 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) ...@@ -225,6 +227,7 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
codepages << (PAGE_SHIFT-10), codepages << (PAGE_SHIFT-10),
reservedpages << (PAGE_SHIFT-10), reservedpages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10)); datapages << (PAGE_SHIFT-10));
pg0[0] = pte_val(mk_pte(0, PAGE_READONLY));
invalidate(); invalidate();
return; return;
......
...@@ -128,7 +128,8 @@ The ATA Interface spec for IDE disk drives allows a total of 28 bits ...@@ -128,7 +128,8 @@ The ATA Interface spec for IDE disk drives allows a total of 28 bits
(8 bits for sector, 16 bits for cylinder, and 4 bits for head) for addressing (8 bits for sector, 16 bits for cylinder, and 4 bits for head) for addressing
individual disk sectors of 512 bytes each (in "Linear Block Address" (LBA) individual disk sectors of 512 bytes each (in "Linear Block Address" (LBA)
mode, there is still only a total of 28 bits available in the hardware). mode, there is still only a total of 28 bits available in the hardware).
This "limits" the capacity of an IDE drive to no more than 128GB (Giga-bytes). All current day IDE drives are somewhat smaller than this upper limit, and This "limits" the capacity of an IDE drive to no more than 128GB (Giga-bytes).
All current day IDE drives are somewhat smaller than this upper limit, and
within a few years, ATAPI disk drives will raise the limit considerably. within a few years, ATAPI disk drives will raise the limit considerably.
All IDE disk drives "suffer" from a "16-heads" limitation: the hardware has All IDE disk drives "suffer" from a "16-heads" limitation: the hardware has
...@@ -229,7 +230,7 @@ by doing the following after installing slackware (or whatever): ...@@ -229,7 +230,7 @@ by doing the following after installing slackware (or whatever):
A danger with this approach is that whenever an MS-DOS "defragmentation" A danger with this approach is that whenever an MS-DOS "defragmentation"
program is run (like Norton "speeddisk"), it may move the Linux boot program is run (like Norton "speeddisk"), it may move the Linux boot
files around, confusing LILO and making the (Linux) system unbootable. files around, confusing LILO and making the (Linux) system unbootable.
Be sure to keep a "boot floppy" kernel at hand for such circumstances. Be sure to keep a kernel "boot floppy" at hand for such circumstances.
If you "don't do DOS", then partition as you please, but remember to create If you "don't do DOS", then partition as you please, but remember to create
a small partition to hold the /boot directory (and vmlinuz) as described above a small partition to hold the /boot directory (and vmlinuz) as described above
......
/* /*
* linux/drivers/block/ide.c Version 3.10 January 21, 1995 * linux/drivers/block/ide.c Version 3.11 January 25, 1995
* *
* Copyright (C) 1994, 1995 Linus Torvalds & authors (see below) * Copyright (C) 1994, 1995 Linus Torvalds & authors (see below)
*/ */
...@@ -100,6 +100,7 @@ ...@@ -100,6 +100,7 @@
* fix probing for old Seagates without HD_ALTSTATUS * fix probing for old Seagates without HD_ALTSTATUS
* fix byte-ordering for some NEC cdrom drives * fix byte-ordering for some NEC cdrom drives
* Version 3.10 disable multiple mode by default; was causing trouble * Version 3.10 disable multiple mode by default; was causing trouble
* Version 3.11 fix mis-identification of old WD disks as cdroms
* *
* To do: * To do:
* - special 32-bit controller-type detection & support * - special 32-bit controller-type detection & support
...@@ -1597,10 +1598,9 @@ static int lba_capacity_is_ok (struct hd_driveid *id) ...@@ -1597,10 +1598,9 @@ static int lba_capacity_is_ok (struct hd_driveid *id)
static unsigned long probe_mem_start; /* used by drive/irq probing routines */ static unsigned long probe_mem_start; /* used by drive/irq probing routines */
static void do_identify (ide_dev_t *dev) static void do_identify (ide_dev_t *dev, byte cmd)
{ {
int bswap; int bswap;
unsigned short model01;
struct hd_driveid *id; struct hd_driveid *id;
unsigned long capacity, check; unsigned long capacity, check;
...@@ -1610,24 +1610,10 @@ static void do_identify (ide_dev_t *dev) ...@@ -1610,24 +1610,10 @@ static void do_identify (ide_dev_t *dev)
sti(); sti();
/* /*
* Non-ATAPI drives seem to always use big-endian string ordering. * WIN_IDENTIFY returns little-endian info,
* Most ATAPI cdrom drives, such as the Vertos, and some NEC and Mitsumi * WIN_PIDENTIFY return big-endian info.
* models, use little-endian. But some NEC/Mitsumi revisions appear to
* use big-endian, confusing the issue. We try to take all of this
* into consideration, "knowing" that Mitsumi drive model names begin
* with "FX" and NEC drive model names begin with "NE".
*/ */
#define PAIR(hi,lo) ((unsigned short)((hi<<8)|(lo&0xff))) bswap = (cmd == WIN_IDENTIFY);
model01 = PAIR(id->model[0],id->model[1]);
if (model01 == PAIR('N','E') || model01 == PAIR('F','X'))
bswap = 0; /* little endian NEC or Mitsumi */
else if (model01 == PAIR('E','N') || model01 == PAIR('X','F'))
bswap = 1; /* big endian NEC or Mitsumi */
else if ((id->config & 0x8000) || dev->type == cdrom)
bswap = 0; /* all other ATAPI drives */
else
bswap = 1; /* all other non-ATAPI drives */
#undef PAIR
fixstring (id->model, sizeof(id->model), bswap); fixstring (id->model, sizeof(id->model), bswap);
fixstring (id->fw_rev, sizeof(id->fw_rev), bswap); fixstring (id->fw_rev, sizeof(id->fw_rev), bswap);
fixstring (id->serial_no, sizeof(id->serial_no), bswap); fixstring (id->serial_no, sizeof(id->serial_no), bswap);
...@@ -1635,7 +1621,7 @@ static void do_identify (ide_dev_t *dev) ...@@ -1635,7 +1621,7 @@ static void do_identify (ide_dev_t *dev)
/* /*
* Check for an ATAPI device * Check for an ATAPI device
*/ */
if (id->config & 0x8000) { if (cmd == WIN_PIDENTIFY) {
#ifdef CONFIG_BLK_DEV_IDECD #ifdef CONFIG_BLK_DEV_IDECD
byte type = (id->config >> 8) & 0x0f; byte type = (id->config >> 8) & 0x0f;
#endif /* CONFIG_BLK_DEV_IDECD */ #endif /* CONFIG_BLK_DEV_IDECD */
...@@ -1781,7 +1767,7 @@ static int try_to_identify (ide_dev_t *dev, byte cmd) ...@@ -1781,7 +1767,7 @@ static int try_to_identify (ide_dev_t *dev, byte cmd)
delay_10ms(); /* wait for IRQ and DRQ_STAT */ delay_10ms(); /* wait for IRQ and DRQ_STAT */
if (OK_STAT(GET_STAT(DEV_HWIF),DRQ_STAT,BAD_RW_STAT)) { if (OK_STAT(GET_STAT(DEV_HWIF),DRQ_STAT,BAD_RW_STAT)) {
cli(); /* some systems need this */ cli(); /* some systems need this */
do_identify(dev); /* drive returned ID */ do_identify(dev, cmd); /* drive returned ID */
rc = 0; /* success */ rc = 0; /* success */
} else } else
rc = 2; /* drive refused ID */ rc = 2; /* drive refused ID */
......
...@@ -94,7 +94,9 @@ endif ...@@ -94,7 +94,9 @@ endif
dep: dep:
$(CPP) -M $(SRCS) > .depend $(CPP) -M $(SRCS) > .depend
#ifdef MODULES
$(CPP) -M -DMODULE $(MODULES:.o=.c) >> .depend $(CPP) -M -DMODULE $(MODULES:.o=.c) >> .depend
#endif
dummy: dummy:
......
...@@ -69,6 +69,13 @@ ...@@ -69,6 +69,13 @@
#define BLANK 0x0020 #define BLANK 0x0020
#define CAN_LOAD_EGA_FONTS /* undefine if the user must not do this */ #define CAN_LOAD_EGA_FONTS /* undefine if the user must not do this */
/* A bitmap for codes <32. A bit of 1 indicates that the code
* corresponding to that bit number invokes some special action
* (such as cursor movement) and should not be displayed as a
* glyph unless the disp_ctrl mode is explicitly enabled.
*/
#define CTRL_ACTION 0xd00ff80
/* /*
* NOTE!!! We sometimes disable and enable interrupts for a short while * NOTE!!! We sometimes disable and enable interrupts for a short while
* (to put a word in video IO), but this will work even for keyboard * (to put a word in video IO), but this will work even for keyboard
...@@ -1143,6 +1150,9 @@ static void set_mode(int currcons, int on_off) ...@@ -1143,6 +1150,9 @@ static void set_mode(int currcons, int on_off)
report_mouse = on_off ? 2 : 0; report_mouse = on_off ? 2 : 0;
break; break;
} else switch(par[i]) { /* ANSI modes set/reset */ } else switch(par[i]) { /* ANSI modes set/reset */
case 3: /* Monitor (display ctrls) */
disp_ctrl = on_off;
break;
case 4: /* Insert Mode on/off */ case 4: /* Insert Mode on/off */
decim = on_off; decim = on_off;
break; break;
...@@ -1312,7 +1322,7 @@ static void reset_terminal(int currcons, int do_clear) ...@@ -1312,7 +1322,7 @@ static void reset_terminal(int currcons, int do_clear)
utf = 0; utf = 0;
utf_count = 0; utf_count = 0;
disp_ctrl = 1; disp_ctrl = 0;
toggle_meta = 0; toggle_meta = 0;
decscnm = 0; decscnm = 0;
...@@ -1445,9 +1455,15 @@ static int con_write(struct tty_struct * tty, int from_user, ...@@ -1445,9 +1455,15 @@ static int con_write(struct tty_struct * tty, int from_user,
ok = 0; ok = 0;
} }
/* Can print ibm (even if 0), and latin1 provided /* If the original code was < 32 we only allow a
it is a printing char or control chars are printed ^@ */ * glyph to be displayed if the code is not normally
if (!ok && tc && (c >= 32 || (disp_ctrl && (c&0x7f) != 27))) * used (such as for cursor movement) or if the
* disp_ctrl mode has been explicitly enabled.
* Note: ESC is *never* allowed to be displayed as
* that would disable all escape sequences!
*/
if (!ok && tc && (c >= 32 || (disp_ctrl && c != 0x1b)
|| !((CTRL_ACTION >> c) & 1)))
ok = 1; ok = 1;
if (vc_state == ESnormal && ok) { if (vc_state == ESnormal && ok) {
...@@ -1497,10 +1513,12 @@ static int con_write(struct tty_struct * tty, int from_user, ...@@ -1497,10 +1513,12 @@ static int con_write(struct tty_struct * tty, int from_user,
case 14: case 14:
charset = 1; charset = 1;
translate = G1_charset; translate = G1_charset;
disp_ctrl = 1;
continue; continue;
case 15: case 15:
charset = 0; charset = 0;
translate = G0_charset; translate = G0_charset;
disp_ctrl = 0;
continue; continue;
case 24: case 26: case 24: case 26:
vc_state = ESnormal; vc_state = ESnormal;
......
...@@ -39,6 +39,10 @@ ...@@ -39,6 +39,10 @@
# EWRK3 The DIGITAL series of AT Ethernet Cards (DE203/4/5) # EWRK3 The DIGITAL series of AT Ethernet Cards (DE203/4/5)
# EWRK3_DEBUG Set the desired debug level # EWRK3_DEBUG Set the desired debug level
# #
# DE4x5 The DIGITAL series of PCI/EISA Ethernet Cards,
# DE425, DE434 and DE435
# DE4x5_DEBUG Set the desired debug level
#
# The following options exist, but cannot be set in this file. # The following options exist, but cannot be set in this file.
# lance.c # lance.c
...@@ -60,3 +64,4 @@ HP_OPTS = ...@@ -60,3 +64,4 @@ HP_OPTS =
PLIP_OPTS = PLIP_OPTS =
DEPCA_OPTS = -DDEPCA_DEBUG=1 DEPCA_OPTS = -DDEPCA_DEBUG=1
EWRK3_OPTS = -DEWRK3_DEBUG=1 EWRK3_OPTS = -DEWRK3_DEBUG=1
DE4x5_OPTS = -DDE4x5_DEBUG=1
...@@ -188,6 +188,12 @@ ifdef CONFIG_ATP ...@@ -188,6 +188,12 @@ ifdef CONFIG_ATP
NETDRV_OBJS := $(NETDRV_OBJS) atp.o NETDRV_OBJS := $(NETDRV_OBJS) atp.o
endif endif
ifdef CONFIG_DE4x5
NETDRV_OBJS := $(NETDRV_OBJS) de4x5.o
de4x5.o: de4x5.c CONFIG
$(CC) $(CPPFLAGS) $(CFLAGS) $(DE4x5_OPTS) -c $<
endif
ifdef CONFIG_NI52 ifdef CONFIG_NI52
NETDRV_OBJS := $(NETDRV_OBJS) ni52.o NETDRV_OBJS := $(NETDRV_OBJS) ni52.o
endif endif
......
The de425/de434/de435 driver in this distribution is designed to work with
the Digital Equipment Corporation series of PCI/EISA ethernet cards (DE425,
DE434, DE435) and with all kernels that support PCI.
Auto media detection is provided so that the media choice isn't compiled in
and is flexible enough to be able to reconfigure on-the-fly.
The ability to load this driver as a loadable module has been included,
although I don't recommend its use with PCI, since PCI dynamically allocates
where the card will go at boot time.
The performance we've achieved so far has been measured through the 'ttcp'
tool at 1.08MB/s. This measures the total tcp stack performance which
includes the card, so don't expect to get much nearer the 1.25MB/s
theoretical ethernet rate.
************************************************************************
However there is still a known bug which causes ttcp to hang on transmit
(receive is OK), although the adapter/driver continues to function
normally for other applications e.g. nfs mounting disks, pinging etc.
The cause is under investigation.
************************************************************************
Enjoy!
Dave
...@@ -49,6 +49,7 @@ extern int at1700_probe(struct device *); ...@@ -49,6 +49,7 @@ extern int at1700_probe(struct device *);
extern int depca_probe(struct device *); extern int depca_probe(struct device *);
extern int apricot_probe(struct device *); extern int apricot_probe(struct device *);
extern int ewrk3_probe(struct device *); extern int ewrk3_probe(struct device *);
extern int de4x5_probe(struct device *);
extern int el1_probe(struct device *); extern int el1_probe(struct device *);
extern int el16_probe(struct device *); extern int el16_probe(struct device *);
extern int elplus_probe(struct device *); extern int elplus_probe(struct device *);
...@@ -111,6 +112,9 @@ ethif_probe(struct device *dev) ...@@ -111,6 +112,9 @@ ethif_probe(struct device *dev)
#ifdef CONFIG_EWRK3 /* DEC EtherWORKS 3 */ #ifdef CONFIG_EWRK3 /* DEC EtherWORKS 3 */
&& ewrk3_probe(dev) && ewrk3_probe(dev)
#endif #endif
#ifdef CONFIG_DE4X5 /* DEC DE425, DE434, DE435 adapters */
&& de4x5_probe(dev)
#endif
#ifdef CONFIG_APRICOT /* Apricot I82596 */ #ifdef CONFIG_APRICOT /* Apricot I82596 */
&& apricot_probe(dev) && apricot_probe(dev)
#endif #endif
......
This diff is collapsed.
This diff is collapsed.
...@@ -374,7 +374,7 @@ ppp_changedmtu (struct ppp *ppp, int new_mtu, int new_mru) ...@@ -374,7 +374,7 @@ ppp_changedmtu (struct ppp *ppp, int new_mtu, int new_mru)
/* RFC 1331, section 7.2 says the minimum value is 1500 bytes */ /* RFC 1331, section 7.2 says the minimum value is 1500 bytes */
if (mru < PPP_MRU) if (mru < PPP_MRU)
mru = PPP_MRU; mru = new_mru = PPP_MRU;
mtu = (mtu * 2) + 20; mtu = (mtu * 2) + 20;
mru = (mru * 2) + 20; mru = (mru * 2) + 20;
......
...@@ -577,7 +577,7 @@ static void znet_rx(struct device *dev) ...@@ -577,7 +577,7 @@ static void znet_rx(struct device *dev)
#else #else
skb->lock = 0; skb->lock = 0;
if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) { if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) {
kfree_s(skb, sksize); kfree(skb);
lp->stats.rx_dropped++; lp->stats.rx_dropped++;
break; break;
} }
......
...@@ -57,7 +57,7 @@ extern int NCR53c7xx_reset(Scsi_Cmnd *); ...@@ -57,7 +57,7 @@ extern int NCR53c7xx_reset(Scsi_Cmnd *);
NULL, NULL, \ NULL, NULL, \
NULL, NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset,\ NULL, NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset,\
NULL, scsicam_bios_param, \ NULL, scsicam_bios_param, \
/* can queue */ 1, /* id */ 7, 255 /* old SG_ALL */, \ /* can queue */ 1, /* id */ 7, 127 /* old SG_ALL */, \
/* cmd per lun */ 1 , 0, 0, DISABLE_CLUSTERING} /* cmd per lun */ 1 , 0, 0, DISABLE_CLUSTERING}
#else #else
/* Register addresses, ordered numerically */ /* Register addresses, ordered numerically */
......
This diff is collapsed.
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define VER_MAJOR 2 #define VER_MAJOR 2
#define VER_MINOR 1 #define VER_MINOR 1
#define VER_SUB "0h" #define VER_SUB "0i"
/************************************************************************ /************************************************************************
* Here you can configure your drives that are using a non-standard * * Here you can configure your drives that are using a non-standard *
......
...@@ -410,10 +410,19 @@ void scan_scsis (struct Scsi_Host * shpnt) ...@@ -410,10 +410,19 @@ void scan_scsis (struct Scsi_Host * shpnt)
scsi_result[1] |= 0x80; /* removable */ scsi_result[1] |= 0x80; /* removable */
} }
/*
* Unfortunately the Toshiba CD-ROM XM-3401TA doesn't
* understand the vendor specific mode select/sense
* commands which are used by the photo cd routines in
* sr.c.
*/
SDpnt->manufacturer = SCSI_MAN_UNKNOWN; SDpnt->manufacturer = SCSI_MAN_UNKNOWN;
if (!strncmp(scsi_result+8,"NEC",3)) if (!strncmp(scsi_result+8,"NEC",3))
SDpnt->manufacturer = SCSI_MAN_NEC; SDpnt->manufacturer = SCSI_MAN_NEC;
if (!strncmp(scsi_result+8,"TOSHIBA",7)) if (!strncmp(scsi_result+8,"TOSHIBA",7) &&
strncmp(scsi_result+16,"CD-ROM XM-3401TA",16) &&
strncmp(scsi_result+32,"3593",4))
SDpnt->manufacturer = SCSI_MAN_TOSHIBA; SDpnt->manufacturer = SCSI_MAN_TOSHIBA;
SDpnt->removable = (0x80 & SDpnt->removable = (0x80 &
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/mm.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/cdrom.h> #include <linux/cdrom.h>
...@@ -406,6 +407,8 @@ static void sr_photocd(struct inode *inode) ...@@ -406,6 +407,8 @@ static void sr_photocd(struct inode *inode)
break; } break; }
scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector; scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector;
/* The code above may have changed the sector size or capacity. */
scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size = 1;
return; return;
} }
...@@ -424,6 +427,10 @@ static int sr_open(struct inode * inode, struct file * filp) ...@@ -424,6 +427,10 @@ static int sr_open(struct inode * inode, struct file * filp)
if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count) if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
(*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)++; (*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)++;
#if 1 /* don't use for now - it doesn't seem to work for everybody */
sr_photocd(inode);
#endif
/* If this device did not have media in the drive at boot time, then /* If this device did not have media in the drive at boot time, then
we would have been unable to get the sector size. Check to see if we would have been unable to get the sector size. Check to see if
this is the case, and try again. this is the case, and try again.
...@@ -432,10 +439,6 @@ static int sr_open(struct inode * inode, struct file * filp) ...@@ -432,10 +439,6 @@ static int sr_open(struct inode * inode, struct file * filp)
if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size) if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
get_sectorsize(MINOR(inode->i_rdev)); get_sectorsize(MINOR(inode->i_rdev));
#if 1 /* don't use for now - it doesn't seem to work for everybody */
sr_photocd(inode);
#endif
return 0; return 0;
} }
...@@ -691,7 +694,7 @@ are any multiple of 512 bytes long. */ ...@@ -691,7 +694,7 @@ are any multiple of 512 bytes long. */
}; /* if need DMA fixup */ }; /* if need DMA fixup */
}; /* for loop to fill list */ }; /* for loop to fill list */
#ifdef DEBUG #ifdef DEBUG
printk("SG: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector, printk("SR: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
this_count, this_count,
SCpnt->request.current_nr_sectors, SCpnt->request.current_nr_sectors,
SCpnt->request.nr_sectors); SCpnt->request.nr_sectors);
...@@ -916,6 +919,7 @@ static void get_sectorsize(int i){ ...@@ -916,6 +919,7 @@ static void get_sectorsize(int i){
if(scsi_CDs[i].sector_size == 2048) if(scsi_CDs[i].sector_size == 2048)
scsi_CDs[i].capacity *= 4; scsi_CDs[i].capacity *= 4;
scsi_CDs[i].needs_sector_size = 0; scsi_CDs[i].needs_sector_size = 0;
sr_sizes[i] = scsi_CDs[i].capacity;
}; };
scsi_free(buffer, 512); scsi_free(buffer, 512);
} }
......
...@@ -8,6 +8,15 @@ ...@@ -8,6 +8,15 @@
* *
* Copyright 1993, 1994: Eric Youngdale (ericy@cais.com). * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
*/ */
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#else
#define MOD_INC_USE_COUNT
#define MOD_DEC_USE_COUNT
#endif
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/mm.h> #include <linux/mm.h>
...@@ -27,11 +36,6 @@ ...@@ -27,11 +36,6 @@
#include <linux/config.h> #include <linux/config.h>
#ifndef CONFIG_BINFMT_ELF
#include <linux/module.h>
#include <linux/version.h>
#endif
#include <linux/unistd.h> #include <linux/unistd.h>
typedef int (*sysfun_p)(); typedef int (*sysfun_p)();
extern sysfun_p sys_call_table[]; extern sysfun_p sys_call_table[];
...@@ -45,7 +49,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs); ...@@ -45,7 +49,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
static int load_elf_library(int fd); static int load_elf_library(int fd);
struct linux_binfmt elf_format = { struct linux_binfmt elf_format = {
#ifdef CONFIG_BINFMT_ELF #ifndef MODULE
NULL, NULL, load_elf_binary, load_elf_library, NULL NULL, NULL, load_elf_binary, load_elf_library, NULL
#else #else
NULL, &mod_use_count_, load_elf_binary, load_elf_library, NULL NULL, &mod_use_count_, load_elf_binary, load_elf_library, NULL
...@@ -314,9 +318,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -314,9 +318,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
unsigned int elf_stack; unsigned int elf_stack;
char passed_fileno[6]; char passed_fileno[6];
#ifndef CONFIG_BINFMT_ELF
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
#endif
ibcs2_interpreter = 0; ibcs2_interpreter = 0;
status = 0; status = 0;
...@@ -325,9 +327,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -325,9 +327,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if (elf_ex.e_ident[0] != 0x7f || if (elf_ex.e_ident[0] != 0x7f ||
strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) { strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return -ENOEXEC; return -ENOEXEC;
} }
...@@ -337,9 +337,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -337,9 +337,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
(elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) || (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
(!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops || (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops ||
!bprm->inode->i_op->default_file_ops->mmap)){ !bprm->inode->i_op->default_file_ops->mmap)){
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return -ENOEXEC; return -ENOEXEC;
}; };
...@@ -355,9 +353,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -355,9 +353,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
set_fs(old_fs); set_fs(old_fs);
if (retval < 0) { if (retval < 0) {
kfree (elf_phdata); kfree (elf_phdata);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return retval; return retval;
} }
...@@ -370,9 +366,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -370,9 +366,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if (elf_exec_fileno < 0) { if (elf_exec_fileno < 0) {
kfree (elf_phdata); kfree (elf_phdata);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return elf_exec_fileno; return elf_exec_fileno;
} }
...@@ -419,9 +413,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -419,9 +413,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if(retval < 0) { if(retval < 0) {
kfree (elf_phdata); kfree (elf_phdata);
kfree(elf_interpreter); kfree(elf_interpreter);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return retval; return retval;
}; };
}; };
...@@ -436,9 +428,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -436,9 +428,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if(retval < 0) { if(retval < 0) {
kfree(elf_interpreter); kfree(elf_interpreter);
kfree(elf_phdata); kfree(elf_phdata);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return -ELIBACC; return -ELIBACC;
}; };
/* Now figure out which format our binary is */ /* Now figure out which format our binary is */
...@@ -455,9 +445,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -455,9 +445,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{ {
kfree(elf_interpreter); kfree(elf_interpreter);
kfree(elf_phdata); kfree(elf_phdata);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return -ELIBBAD; return -ELIBBAD;
}; };
} }
...@@ -482,9 +470,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -482,9 +470,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
kfree(elf_interpreter); kfree(elf_interpreter);
} }
kfree (elf_phdata); kfree (elf_phdata);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return -E2BIG; return -E2BIG;
} }
} }
...@@ -536,9 +522,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -536,9 +522,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
printk("Unable to load interpreter\n"); printk("Unable to load interpreter\n");
kfree(elf_phdata); kfree(elf_phdata);
send_sig(SIGSEGV, current, 0); send_sig(SIGSEGV, current, 0);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return 0; return 0;
}; };
}; };
...@@ -640,9 +624,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -640,9 +624,7 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
start_thread(regs, elf_entry, bprm->p); start_thread(regs, elf_entry, bprm->p);
if (current->flags & PF_PTRACED) if (current->flags & PF_PTRACED)
send_sig(SIGTRAP, current, 0); send_sig(SIGTRAP, current, 0);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return 0; return 0;
} }
...@@ -662,10 +644,7 @@ load_elf_library(int fd){ ...@@ -662,10 +644,7 @@ load_elf_library(int fd){
int error; int error;
int i,j, k; int i,j, k;
#ifndef CONFIG_BINFMT_ELF
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
#endif
len = 0; len = 0;
file = current->files->fd[fd]; file = current->files->fd[fd];
inode = file->f_inode; inode = file->f_inode;
...@@ -674,18 +653,14 @@ load_elf_library(int fd){ ...@@ -674,18 +653,14 @@ load_elf_library(int fd){
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
if (file->f_op->read(inode, file, (char *) &elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) { if (file->f_op->read(inode, file, (char *) &elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) {
SYS(close)(fd); SYS(close)(fd);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return -EACCES; return -EACCES;
} }
set_fs(USER_DS); set_fs(USER_DS);
if (elf_ex.e_ident[0] != 0x7f || if (elf_ex.e_ident[0] != 0x7f ||
strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) { strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return -ENOEXEC; return -ENOEXEC;
} }
...@@ -693,18 +668,14 @@ load_elf_library(int fd){ ...@@ -693,18 +668,14 @@ load_elf_library(int fd){
if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
(elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) || (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
(!inode->i_op || !inode->i_op->default_file_ops->mmap)){ (!inode->i_op || !inode->i_op->default_file_ops->mmap)){
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return -ENOEXEC; return -ENOEXEC;
}; };
/* Now read in all of the header information */ /* Now read in all of the header information */
if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE) { if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE) {
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return -ENOEXEC; return -ENOEXEC;
} }
...@@ -723,9 +694,7 @@ load_elf_library(int fd){ ...@@ -723,9 +694,7 @@ load_elf_library(int fd){
if(j != 1) { if(j != 1) {
kfree(elf_phdata); kfree(elf_phdata);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return -ENOEXEC; return -ENOEXEC;
}; };
...@@ -745,9 +714,7 @@ load_elf_library(int fd){ ...@@ -745,9 +714,7 @@ load_elf_library(int fd){
SYS(close)(fd); SYS(close)(fd);
if (error != elf_phdata->p_vaddr & 0xfffff000) { if (error != elf_phdata->p_vaddr & 0xfffff000) {
kfree(elf_phdata); kfree(elf_phdata);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return error; return error;
} }
...@@ -760,13 +727,11 @@ load_elf_library(int fd){ ...@@ -760,13 +727,11 @@ load_elf_library(int fd){
PROT_READ|PROT_WRITE|PROT_EXEC, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE, 0); MAP_FIXED|MAP_PRIVATE, 0);
kfree(elf_phdata); kfree(elf_phdata);
#ifndef CONFIG_BINFMT_ELF
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
#endif
return 0; return 0;
} }
#ifndef CONFIG_BINFMT_ELF #ifdef MODULE
char kernel_version[] = UTS_RELEASE; char kernel_version[] = UTS_RELEASE;
int init_module(void) { int init_module(void) {
......
...@@ -110,14 +110,16 @@ int open_inode(struct inode * inode, int mode) ...@@ -110,14 +110,16 @@ int open_inode(struct inode * inode, int mode)
return -EINVAL; return -EINVAL;
f = get_empty_filp(); f = get_empty_filp();
if (!f) if (!f)
return -EMFILE; return -ENFILE;
fd = 0; fd = 0;
fpp = current->files->fd; fpp = current->files->fd;
for (;;) { for (;;) {
if (!*fpp) if (!*fpp)
break; break;
if (++fd > NR_OPEN) if (++fd >= NR_OPEN) {
return -ENFILE; f->f_count--;
return -EMFILE;
}
fpp++; fpp++;
} }
*fpp = f; *fpp = f;
......
...@@ -15,6 +15,18 @@ void msdos_ll_rw_block (struct super_block *sb, int opr, ...@@ -15,6 +15,18 @@ void msdos_ll_rw_block (struct super_block *sb, int opr,
/* These macros exist to avoid modifying all the code */ /* These macros exist to avoid modifying all the code */
/* They should be removed one day I guess */ /* They should be removed one day I guess */
/* The versionning mecanism of the modules system define those macros */
/* This remove some warnings */
#ifdef brelse
#undef brelse
#endif
#ifdef bread
#undef bread
#endif
#ifdef getblk
#undef getblk
#endif
#define brelse(b) msdos_brelse(sb,b) #define brelse(b) msdos_brelse(sb,b)
#define bread(d,b,s) msdos_bread(sb,b) #define bread(d,b,s) msdos_bread(sb,b)
#define getblk(d,b,s) msdos_getblk(sb,b) #define getblk(d,b,s) msdos_getblk(sb,b)
......
...@@ -411,10 +411,10 @@ int do_open(const char * filename,int flags,int mode) ...@@ -411,10 +411,10 @@ int do_open(const char * filename,int flags,int mode)
struct file * f; struct file * f;
int flag,error,fd; int flag,error,fd;
for(fd=0 ; fd<NR_OPEN ; fd++) for(fd=0; fd<NR_OPEN && fd<current->rlim[RLIMIT_NOFILE].rlim_cur; fd++)
if (!current->files->fd[fd]) if (!current->files->fd[fd])
break; break;
if (fd>=NR_OPEN) if (fd>=NR_OPEN || fd>=current->rlim[RLIMIT_NOFILE].rlim_cur)
return -EMFILE; return -EMFILE;
FD_CLR(fd,&current->files->close_on_exec); FD_CLR(fd,&current->files->close_on_exec);
f = get_empty_filp(); f = get_empty_filp();
......
...@@ -394,7 +394,7 @@ asmlinkage int sys_pipe(unsigned long * fildes) ...@@ -394,7 +394,7 @@ asmlinkage int sys_pipe(unsigned long * fildes)
if (j<2) if (j<2)
return -ENFILE; return -ENFILE;
j=0; j=0;
for(i=0;j<2 && i<NR_OPEN;i++) for(i=0;j<2 && i<NR_OPEN && i<current->rlim[RLIMIT_NOFILE].rlim_cur;i++)
if (!current->files->fd[i]) { if (!current->files->fd[i]) {
current->files->fd[ fd[j]=i ] = f[j]; current->files->fd[ fd[j]=i ] = f[j];
j++; j++;
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
* Dusted off the code and added IPX. Fixed the 4K limit. * Dusted off the code and added IPX. Fixed the 4K limit.
* Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de) * Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de)
* /proc/net/snmp. * /proc/net/snmp.
* Alan Cox (gw4pts@gw4pts.ampr.org) 1/95
* Added Appletalk slots
* *
* proc net directory handling functions * proc net directory handling functions
*/ */
...@@ -56,11 +58,13 @@ extern int afinet_get_info(char *, char **, off_t, int); ...@@ -56,11 +58,13 @@ extern int afinet_get_info(char *, char **, off_t, int);
extern int ip_acct_procinfo(char *, char **, off_t, int); extern int ip_acct_procinfo(char *, char **, off_t, int);
extern int ip_fw_blk_procinfo(char *, char **, off_t, int); extern int ip_fw_blk_procinfo(char *, char **, off_t, int);
extern int ip_fw_fwd_procinfo(char *, char **, off_t, int); extern int ip_fw_fwd_procinfo(char *, char **, off_t, int);
extern int ip_msqhst_procinfo(char *, char **, off_t, int);
extern int ip_mc_procinfo(char *, char **, off_t, int); extern int ip_mc_procinfo(char *, char **, off_t, int);
#endif /* CONFIG_INET */ #endif /* CONFIG_INET */
#ifdef CONFIG_IPX #ifdef CONFIG_IPX
extern int ipx_get_info(char *, char **, off_t, int); extern int ipx_get_info(char *, char **, off_t, int);
extern int ipx_rt_get_info(char *, char **, off_t, int); extern int ipx_rt_get_info(char *, char **, off_t, int);
extern int ipx_get_interface_info(char *, char **, off_t , int);
#endif /* CONFIG_IPX */ #endif /* CONFIG_IPX */
#ifdef CONFIG_AX25 #ifdef CONFIG_AX25
extern int ax25_get_info(char *, char **, off_t, int); extern int ax25_get_info(char *, char **, off_t, int);
...@@ -71,6 +75,11 @@ extern int nr_nodes_get_info(char *, char **, off_t, int); ...@@ -71,6 +75,11 @@ extern int nr_nodes_get_info(char *, char **, off_t, int);
extern int nr_neigh_get_info(char *, char **, off_t, int); extern int nr_neigh_get_info(char *, char **, off_t, int);
#endif /* CONFIG_NETROM */ #endif /* CONFIG_NETROM */
#endif /* CONFIG_AX25 */ #endif /* CONFIG_AX25 */
#ifdef CONFIG_ATALK
extern int atalk_get_info(char *, char **, off_t, int);
extern int atalk_rt_get_info(char *, char **, off_t, int);
extern int atalk_if_get_info(char *, char **, off_t, int);
#endif
static struct file_operations proc_net_operations = { static struct file_operations proc_net_operations = {
...@@ -130,6 +139,9 @@ static struct proc_dir_entry net_dir[] = { ...@@ -130,6 +139,9 @@ static struct proc_dir_entry net_dir[] = {
{ PROC_NET_IPFWFWD, 10, "ip_forward"}, { PROC_NET_IPFWFWD, 10, "ip_forward"},
{ PROC_NET_IPBLFWD, 8, "ip_block"}, { PROC_NET_IPBLFWD, 8, "ip_block"},
#endif #endif
#ifdef CONFIG_IP_MASQUERADE
{ PROC_NET_IPMSQHST, 13, "ip_masquerade"},
#endif
#ifdef CONFIG_IP_ACCT #ifdef CONFIG_IP_ACCT
{ PROC_NET_IPACCT, 7, "ip_acct"}, { PROC_NET_IPACCT, 7, "ip_acct"},
#endif #endif
...@@ -137,6 +149,7 @@ static struct proc_dir_entry net_dir[] = { ...@@ -137,6 +149,7 @@ static struct proc_dir_entry net_dir[] = {
#ifdef CONFIG_IPX #ifdef CONFIG_IPX
{ PROC_NET_IPX_ROUTE, 9, "ipx_route" }, { PROC_NET_IPX_ROUTE, 9, "ipx_route" },
{ PROC_NET_IPX, 3, "ipx" }, { PROC_NET_IPX, 3, "ipx" },
{ PROC_NET_IPX_INTERFACE, 13, "ipx_interface" },
#endif /* CONFIG_IPX */ #endif /* CONFIG_IPX */
#ifdef CONFIG_AX25 #ifdef CONFIG_AX25
{ PROC_NET_AX25_ROUTE, 10, "ax25_route" }, { PROC_NET_AX25_ROUTE, 10, "ax25_route" },
...@@ -147,6 +160,11 @@ static struct proc_dir_entry net_dir[] = { ...@@ -147,6 +160,11 @@ static struct proc_dir_entry net_dir[] = {
{ PROC_NET_NR, 2, "nr" }, { PROC_NET_NR, 2, "nr" },
#endif /* CONFIG_NETROM */ #endif /* CONFIG_NETROM */
#endif /* CONFIG_AX25 */ #endif /* CONFIG_AX25 */
#ifdef CONFIG_ATALK
{ PROC_NET_ATALK, 9, "appletalk" },
{ PROC_NET_AT_ROUTE, 11,"atalk_route" },
{ PROC_NET_ATIF, 11,"atalk_iface" },
#endif /* CONFIG_ATALK */
{ 0, 0, NULL } { 0, 0, NULL }
}; };
...@@ -277,6 +295,11 @@ static int proc_readnet(struct inode * inode, struct file * file, ...@@ -277,6 +295,11 @@ static int proc_readnet(struct inode * inode, struct file * file,
length = ip_acct_procinfo(page, &start, file->f_pos,thistime); length = ip_acct_procinfo(page, &start, file->f_pos,thistime);
break; break;
#endif #endif
#ifdef CONFIG_IP_MASQUERADE
case PROC_NET_IPMSQHST:
length = ip_msqhst_procinfo(page, &start, file->f_pos,thistime);
break;
#endif
#ifdef CONFIG_INET_RARP #ifdef CONFIG_INET_RARP
case PROC_NET_RARP: case PROC_NET_RARP:
length = rarp_get_info(page,&start,file->f_pos,thistime); length = rarp_get_info(page,&start,file->f_pos,thistime);
...@@ -284,6 +307,9 @@ static int proc_readnet(struct inode * inode, struct file * file, ...@@ -284,6 +307,9 @@ static int proc_readnet(struct inode * inode, struct file * file,
#endif /* CONFIG_INET_RARP */ #endif /* CONFIG_INET_RARP */
#endif /* CONFIG_INET */ #endif /* CONFIG_INET */
#ifdef CONFIG_IPX #ifdef CONFIG_IPX
case PROC_NET_IPX_INTERFACE:
length = ipx_get_interface_info(page, &start, file->f_pos, thistime);
break;
case PROC_NET_IPX_ROUTE: case PROC_NET_IPX_ROUTE:
length = ipx_rt_get_info(page,&start,file->f_pos,thistime); length = ipx_rt_get_info(page,&start,file->f_pos,thistime);
break; break;
...@@ -291,6 +317,17 @@ static int proc_readnet(struct inode * inode, struct file * file, ...@@ -291,6 +317,17 @@ static int proc_readnet(struct inode * inode, struct file * file,
length = ipx_get_info(page,&start,file->f_pos,thistime); length = ipx_get_info(page,&start,file->f_pos,thistime);
break; break;
#endif /* CONFIG_IPX */ #endif /* CONFIG_IPX */
#ifdef CONFIG_ATALK
case PROC_NET_ATALK:
length = atalk_get_info(page, &start, file->f_pos, thistime);
break;
case PROC_NET_AT_ROUTE:
length = atalk_rt_get_info(page, &start, file->f_pos, thistime);
break;
case PROC_NET_ATIF:
length = atalk_if_get_info(page, &start, file->f_pos, thistime);
break;
#endif /* CONFIG_ATALK */
#ifdef CONFIG_AX25 #ifdef CONFIG_AX25
case PROC_NET_AX25_ROUTE: case PROC_NET_AX25_ROUTE:
length = ax25_rt_get_info(page,&start,file->f_pos,thistime); length = ax25_rt_get_info(page,&start,file->f_pos,thistime);
......
...@@ -37,8 +37,10 @@ static int UMSDOS_file_read( ...@@ -37,8 +37,10 @@ static int UMSDOS_file_read(
{ {
/* We have to set the access time because msdos don't care */ /* We have to set the access time because msdos don't care */
int ret = msdos_file_read(inode,filp,buf,count); int ret = msdos_file_read(inode,filp,buf,count);
if (!IS_RDONLY(inode)){
inode->i_atime = CURRENT_TIME; inode->i_atime = CURRENT_TIME;
inode->i_dirt = 1; inode->i_dirt = 1;
}
return ret; return ret;
} }
/* /*
......
...@@ -164,6 +164,21 @@ int UMSDOS_ioctl_dir ( ...@@ -164,6 +164,21 @@ int UMSDOS_ioctl_dir (
umsdos_parse (data.umsdos_dirent.name umsdos_parse (data.umsdos_dirent.name
,data.umsdos_dirent.name_len,&info); ,data.umsdos_dirent.name_len,&info);
ret = umsdos_newentry (dir,&info); ret = umsdos_newentry (dir,&info);
}else if (cmd == UMSDOS_RENAME_DOS){
/* #Specification: ioctl / UMSDOS_RENAME_DOS
A file or directory is rename in a DOS directory
(not moved accross directory). The source name
is in the dos_dirent.name field and the destination
is in umsdos_dirent.name field.
This ioctl allows umssync to rename a mangle file
name before syncing it back in the EMD.
*/
dir->i_count += 2;
ret = msdos_rename (dir
,data.dos_dirent.d_name,data.dos_dirent.d_reclen
,dir
,data.umsdos_dirent.name,data.umsdos_dirent.name_len);
}else if (cmd == UMSDOS_UNLINK_EMD){ }else if (cmd == UMSDOS_UNLINK_EMD){
/* #Specification: ioctl / UMSDOS_UNLINK_EMD /* #Specification: ioctl / UMSDOS_UNLINK_EMD
The umsdos_dirent field of the struct umsdos_ioctl is used The umsdos_dirent field of the struct umsdos_ioctl is used
......
...@@ -302,7 +302,7 @@ int umsdos_parse ( ...@@ -302,7 +302,7 @@ int umsdos_parse (
*/ */
}else{ }else{
/* Conforming MSDOS file name */ /* Conforming MSDOS file name */
strcpy (info->fake.fname,fname); /* GLU C'est sur on a un 0 a la fin */ strncpy (info->fake.fname,fname,len);
info->msdos_reject = 0; info->msdos_reject = 0;
base_len = firstpt != NULL ? (int)(firstpt - fname) : len; base_len = firstpt != NULL ? (int)(firstpt - fname) : len;
} }
......
...@@ -319,7 +319,7 @@ static int umsdos_rename_f( ...@@ -319,7 +319,7 @@ static int umsdos_rename_f(
int flags) /* 0 == copy flags from old_name */ int flags) /* 0 == copy flags from old_name */
/* != 0, this is the value of flags */ /* != 0, this is the value of flags */
{ {
int ret = EPERM; int ret = -EPERM;
struct umsdos_info old_info; struct umsdos_info old_info;
int old_ret = umsdos_parse (old_name,old_len,&old_info); int old_ret = umsdos_parse (old_name,old_len,&old_info);
struct umsdos_info new_info; struct umsdos_info new_info;
...@@ -334,6 +334,17 @@ chkstk(); ...@@ -334,6 +334,17 @@ chkstk();
chkstk(); chkstk();
PRINTK (("ret %d ",ret)); PRINTK (("ret %d ",ret));
if (ret == 0){ if (ret == 0){
/* check sticky bit on old_dir */
if ( !(old_dir->i_mode & S_ISVTX) || fsuser() ||
current->fsuid == old_info.entry.uid ||
current->fsuid == old_dir->i_uid ) {
/* Does new_name already exist? */
PRINTK(("new findentry "));
ret = umsdos_findentry(new_dir,&new_info,0);
if (ret != 0 || /* if destination file exists, are we allowed to replace it ? */
!(new_dir->i_mode & S_ISVTX) || fsuser() ||
current->fsuid == new_info.entry.uid ||
current->fsuid == new_dir->i_uid ) {
PRINTK (("new newentry ")); PRINTK (("new newentry "));
umsdos_ren_init(&new_info,&old_info,flags); umsdos_ren_init(&new_info,&old_info,flags);
ret = umsdos_newentry (new_dir,&new_info); ret = umsdos_newentry (new_dir,&new_info);
...@@ -387,6 +398,16 @@ chkstk(); ...@@ -387,6 +398,16 @@ chkstk();
} }
} }
} }
}else{
/* sticky bit set on new_dir */
PRINTK(("sticky set on new "));
ret = -EPERM;
}
}else{
/* sticky bit set on old_dir */
PRINTK(("sticky set on old "));
ret = -EPERM;
}
} }
umsdos_unlockcreate(old_dir); umsdos_unlockcreate(old_dir);
umsdos_unlockcreate(new_dir); umsdos_unlockcreate(new_dir);
...@@ -858,6 +879,10 @@ int UMSDOS_rmdir( ...@@ -858,6 +879,10 @@ int UMSDOS_rmdir(
ret = -EBUSY; ret = -EBUSY;
}else if ((empty = umsdos_isempty (sdir)) != 0){ }else if ((empty = umsdos_isempty (sdir)) != 0){
PRINTK (("isempty %d i_count %d ",empty,sdir->i_count)); PRINTK (("isempty %d i_count %d ",empty,sdir->i_count));
/* check sticky bit */
if ( !(dir->i_mode & S_ISVTX) || fsuser() ||
current->fsuid == sdir->i_uid ||
current->fsuid == dir->i_uid ) {
if (empty == 1){ if (empty == 1){
/* We have to removed the EMD file */ /* We have to removed the EMD file */
ret = msdos_unlink(sdir,UMSDOS_EMD_FILE ret = msdos_unlink(sdir,UMSDOS_EMD_FILE
...@@ -881,6 +906,11 @@ int UMSDOS_rmdir( ...@@ -881,6 +906,11 @@ int UMSDOS_rmdir(
ret = umsdos_delentry (dir,&info,1); ret = umsdos_delentry (dir,&info,1);
} }
} }
}else{
/* sticky bit set and we don't have permission */
PRINTK(("sticky set "));
ret = -EPERM;
}
}else{ }else{
/* /*
The subdirectory is not empty, so leave it there The subdirectory is not empty, so leave it there
...@@ -903,15 +933,19 @@ int UMSDOS_unlink ( ...@@ -903,15 +933,19 @@ int UMSDOS_unlink (
const char * name, const char * name,
int len) int len)
{ {
struct umsdos_info info;
int ret = umsdos_nevercreat(dir,name,len,-EPERM); int ret = umsdos_nevercreat(dir,name,len,-EPERM);
if (ret == 0){ if (ret == 0){
struct umsdos_info info;
ret = umsdos_parse (name,len,&info); ret = umsdos_parse (name,len,&info);
if (ret == 0){ if (ret == 0){
umsdos_lockcreate(dir); umsdos_lockcreate(dir);
ret = umsdos_findentry(dir,&info,1); ret = umsdos_findentry(dir,&info,1);
if (ret == 0){ if (ret == 0){
PRINTK (("UMSDOS_unlink %s ",info.fake.fname)); PRINTK (("UMSDOS_unlink %s ",info.fake.fname));
/* check sticky bit */
if ( !(dir->i_mode & S_ISVTX) || fsuser() ||
current->fsuid == info.entry.uid ||
current->fsuid == dir->i_uid ) {
if (info.entry.flags & UMSDOS_HLINK){ if (info.entry.flags & UMSDOS_HLINK){
/* #Specification: hard link / deleting a link /* #Specification: hard link / deleting a link
When we deletes a file, and this file is a link When we deletes a file, and this file is a link
...@@ -961,6 +995,11 @@ int UMSDOS_unlink ( ...@@ -961,6 +995,11 @@ int UMSDOS_unlink (
,info.entry.mode,ret)); ,info.entry.mode,ret));
} }
} }
}else{
/* sticky bit set and we've not got permission */
PRINTK(("sticky set "));
ret = -EPERM;
}
} }
umsdos_unlockcreate(dir); umsdos_unlockcreate(dir);
} }
......
#ifndef __ASM_MIPS_HEAD_H
#define __ASM_MIPS_HEAD_H
#include <linux/types.h>
extern unsigned long swapper_pg_dir[1024];
extern ulong IRQ_vectors[];
#endif /* __ASM_MIPS_HEAD_H */
#ifndef __ASM_MIPS_MM_H
#define __ASM_MIPS_MM_H
#if defined (__KERNEL__)
/*
* Note that we shift the lower 32bits of each EntryLo[01] entry
* 6 bits to the left. That way we can convert the PFN into the
* physical address by a single 'and' operation and gain 6 additional
* bits for storing information which isn't present in a normal
* MIPS page table.
* I've also changed the naming of some bits so that they conform
* the i386 naming as much as possible.
* PAGE_USER isn't implemented in software yet.
*/
#define PAGE_PRESENT (1<<0) /* implemented in software */
#define PAGE_COW (1<<1) /* implemented in software */
#define PAGE_DIRTY (1<<2) /* implemented in software */
#define PAGE_USER (1<<3) /* implemented in software */
#define PAGE_UNUSED1 (1<<4) /* implemented in software */
#define PAGE_UNUSED2 (1<<5) /* implemented in software */
#define PAGE_GLOBAL (1<<6)
#define PAGE_ACCESSED (1<<7) /* The Mips valid bit */
#define PAGE_RW (1<<8) /* The Mips dirty bit */
#define CACHE_CACHABLE_NO_WA (0<<9)
#define CACHE_CACHABLE_WA (1<<9)
#define CACHE_UNCACHED (2<<9)
#define CACHE_CACHABLE_NONCOHERENT (3<<9)
#define CACHE_CACHABLE_CE (4<<9)
#define CACHE_CACHABLE_COW (5<<9)
#define CACHE_CACHABLE_CUW (6<<9)
#define CACHE_MASK (7<<9)
#define PAGE_PRIVATE (PAGE_PRESENT | PAGE_ACCESSED | PAGE_DIRTY | PAGE_RW | \
PAGE_COW | CACHE_CACHABLE_NO_WA)
#define PAGE_SHARED (PAGE_PRESENT | PAGE_ACCESSED | PAGE_DIRTY | PAGE_RW | \
CACHE_CACHABLE_NO_WA)
#define PAGE_COPY (PAGE_PRESENT | PAGE_ACCESSED | PAGE_COW | \
CACHE_CACHABLE_NO_WA)
#define PAGE_READONLY (PAGE_PRESENT | PAGE_ACCESSED | CACHE_CACHABLE_NO_WA)
#define PAGE_TABLE (PAGE_PRESENT | PAGE_ACCESSED | PAGE_DIRTY | PAGE_RW | \
CACHE_CACHABLE_NO_WA)
#ifndef __ASSEMBLY__
#include <asm/system.h>
extern unsigned long invalid_pg_table[1024];
/*
* memory.c & swap.c
*/
extern void mem_init(unsigned long start_mem, unsigned long end_mem);
#endif /* !defined (__ASSEMBLY__) */
#endif /* defined (__KERNEL__) */
#endif /* __ASM_MIPS_MM_H */
This diff is collapsed.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 1994 by Ralf Baechle * Copyright (C) 1994, 1995 by Ralf Baechle
* *
*/ */
#ifndef __ASM_MIPS_SEGMENT_H #ifndef __ASM_MIPS_SEGMENT_H
...@@ -22,199 +22,90 @@ ...@@ -22,199 +22,90 @@
/* /*
* returns the kernel segment base of a given address * returns the kernel segment base of a given address
* Address space is a scarce resource on a R3000, so
* emulate the Intel segment braindamage...
*/ */
#define KSEGX(a) (a & 0xe0000000) #define KSEGX(a) (a & 0xe0000000)
#define KERNEL_CS KERNELBASE
#define KERNEL_DS KERNEL_CS
#define USER_CS 0x00000000
#define USER_DS USER_CS
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
/* /*
* This variable is defined in arch/mips/kernel/head.S. * Beware: the xxx_fs_word functions work on 16bit words!
*/ */
extern unsigned long segment_fs;
#define get_fs_byte(addr) get_user_byte((char *)(addr)) #define get_fs_byte(addr) get_user_byte((char *)(addr))
static inline unsigned char get_user_byte(const char *addr) static inline unsigned char get_user_byte(const char *addr)
{ {
return *(const char *)(((unsigned long)addr)+segment_fs); return *addr;
} }
#define get_fs_word(addr) get_user_word((short *)(addr)) #define get_fs_word(addr) get_user_word((short *)(addr))
static inline unsigned short get_user_word(const short *addr) static inline unsigned short get_user_word(const short *addr)
{ {
return *(const short *)(((unsigned long)addr)+segment_fs); return *addr;
} }
#define get_fs_long(addr) get_user_long((int *)(addr)) #define get_fs_long(addr) get_user_long((int *)(addr))
static inline unsigned long get_user_long(const int *addr) static inline unsigned long get_user_long(const int *addr)
{ {
return *(const int *)(((unsigned long)addr)+segment_fs); return *addr;
} }
#define get_fs_dlong(addr) get_user_dlong((long long *)(addr)) #define get_fs_dlong(addr) get_user_dlong((long long *)(addr))
static inline unsigned long get_user_dlong(const long long *addr) static inline unsigned long get_user_dlong(const long long *addr)
{ {
return *(const long long *)(((unsigned long)addr)+segment_fs); return *addr;
} }
#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr)) #define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))
static inline void put_user_byte(char val,char *addr) static inline void put_user_byte(char val,char *addr)
{ {
*(char *)(((unsigned long)addr)+segment_fs) = val; *addr = val;
} }
#define put_fs_word(x,addr) put_user_word((x),(short *)(addr)) #define put_fs_word(x,addr) put_user_word((x),(short *)(addr))
static inline void put_user_word(short val,short * addr) static inline void put_user_word(short val,short * addr)
{ {
*(short *)(((unsigned long)addr)+segment_fs) = val; *addr = val;
} }
#define put_fs_long(x,addr) put_user_long((x),(int *)(addr)) #define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
static inline void put_user_long(unsigned long val,int * addr) static inline void put_user_long(unsigned long val,int * addr)
{ {
*(int *)(((unsigned long)addr)+segment_fs) = val; *addr = val;
} }
#define put_fs_dlong(x,addr) put_user_dlong((x),(int *)(addr)) #define put_fs_dlong(x,addr) put_user_dlong((x),(int *)(addr))
static inline void put_user_dlong(unsigned long val,long long * addr) static inline void put_user_dlong(unsigned long val,long long * addr)
{ {
*(long long *)(((unsigned long)addr)+segment_fs) = val; *addr = val;
}
static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
{
__asm__(
".set\tnoreorder\n\t"
".set\tnoat\n"
"1:\tlbu\t$1,(%2)\n\t"
"addiu\t%2,%2,1\n\t"
"sb\t$1,(%1)\n\t"
"addiu\t%0,%0,-1\n\t"
"bne\t$0,%0,1b\n\t"
"addiu\t%1,%1,1\n\t"
".set\tat\n\t"
".set\treorder"
: /* no outputs */
:"r" (n),"r" (((long) to)| segment_fs),"r" ((long) from)
:"$1");
} }
static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n) #define memcpy_fromfs(to, from, n) memcpy((to),(from),(n))
{
/*
* Use put_user_byte to avoid trouble with alignment.
*/
switch (n) {
case 0:
return;
case 1:
put_user_byte(*(const char *) from, (char *) to);
return;
case 2:
put_user_byte(*(const char *) from, (char *) to);
put_user_byte(*(1+(const char *) from), 1+(char *) to);
return;
case 3:
put_user_byte(*((const char *) from), (char *) to);
put_user_byte(*(1+(const char *) from), 1+(char *) to);
put_user_byte(*(2+(const char *) from), 2+(char *) to);
return;
case 4:
put_user_byte(*((const char *) from), (char *) to);
put_user_byte(*(1+(const char *) from), 1+(char *) to);
put_user_byte(*(2+(const char *) from), 2+(char *) to);
put_user_byte(*(3+(const char *) from), 3+(char *) to);
return;
}
__generic_memcpy_tofs(to, from, n);
return;
}
static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n) #define memcpy_tofs(to, from, n) memcpy((to),(from),(n))
{
__asm__(
".set\tnoreorder\n\t"
".set\tnoat\n"
"1:\tlbu\t$1,(%2)\n\t"
"addiu\t%2,%2,1\n\t"
"sb\t$1,(%1)\n\t"
"addiu\t%0,%0,-1\n\t"
"bne\t$0,%0,1b\n\t"
"addiu\t%1,%1,1\n\t"
".set\tat\n\t"
".set\treorder"
: /* no outputs */
:"r" (n),"r" ((long) to),"r" (((long) from | segment_fs))
:"$1","memory");
}
static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n) /*
{ * For segmented architectures, these are used to specify which segment
/* * to use for the above functions.
* Use put_user_byte to avoid trouble with alignment. *
* MIPS is not segmented, so these are just dummies.
*/ */
switch (n) {
case 0:
return;
case 1:
*(char *)to = get_user_byte((const char *) from);
return;
case 2:
*(char *) to = get_user_byte((const char *) from);
*(char *) to = get_user_byte(1+(const char *) from);
return;
case 3:
*(char *) to = get_user_byte((const char *) from);
*(char *) to = get_user_byte(1+(const char *) from);
*(char *) to = get_user_byte(2+(const char *) from);
return;
case 4:
*(char *) to = get_user_byte((const char *) from);
*(char *) to = get_user_byte(1+(const char *) from);
*(char *) to = get_user_byte(2+(const char *) from);
*(char *) to = get_user_byte(3+(const char *) from);
return;
}
__generic_memcpy_fromfs(to, from, n);
return;
}
#define memcpy_fromfs(to, from, n) \
(__builtin_constant_p(n) ? \
__constant_memcpy_fromfs((to),(from),(n)) : \
__generic_memcpy_fromfs((to),(from),(n)))
#define memcpy_tofs(to, from, n) \ #define KERNEL_DS 0
(__builtin_constant_p(n) ? \ #define USER_DS 1
__constant_memcpy_tofs((to),(from),(n)) : \
__generic_memcpy_tofs((to),(from),(n)))
static inline unsigned long get_fs(void) static inline unsigned long get_fs(void)
{ {
return segment_fs; return 0;
} }
static inline unsigned long get_ds(void) static inline unsigned long get_ds(void)
{ {
return KERNEL_DS; return 0;
} }
static inline void set_fs(unsigned long val) static inline void set_fs(unsigned long val)
{ {
segment_fs = val;
} }
#endif #endif /* !__ASSEMBLY__ */
#endif /* __ASM_MIPS_SEGMENT_H */ #endif /* __ASM_MIPS_SEGMENT_H */
...@@ -41,8 +41,7 @@ ...@@ -41,8 +41,7 @@
#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */ #define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ #define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
#define ETH_P_802_2 0x0004 /* 802.2 frames */ #define ETH_P_802_2 0x0004 /* 802.2 frames */
#define ETH_P_SNAP 0x0005 /* 802.2 SNAP frames */ #define ETH_P_SNAP 0x0005 /* Internal only */
/* This is an Ethernet frame header. */ /* This is an Ethernet frame header. */
struct ethhdr { struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
......
...@@ -4,9 +4,6 @@ ...@@ -4,9 +4,6 @@
* Authors: * Authors:
* Alan Cox <Alan.Cox@linux.org> * Alan Cox <Alan.Cox@linux.org>
* *
* WARNING:
* This is a 'preliminary' implementation... on your own head
* be it.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -14,8 +11,8 @@ ...@@ -14,8 +11,8 @@
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#ifndef _IGMP_H #ifndef _LINUX_IGMP_H
#define _IGMP_H #define _LINUX_IGMP_H
/* /*
* IGMP protocol structures * IGMP protocol structures
...@@ -40,6 +37,7 @@ struct igmphdr ...@@ -40,6 +37,7 @@ struct igmphdr
* struct for keeping the multicast list in * struct for keeping the multicast list in
*/ */
#ifdef __KERNEL__
struct ip_mc_socklist struct ip_mc_socklist
{ {
unsigned long multiaddr[IP_MAX_MEMBERSHIPS]; /* This is a speed trade off */ unsigned long multiaddr[IP_MAX_MEMBERSHIPS]; /* This is a speed trade off */
...@@ -59,7 +57,6 @@ struct ip_mc_list ...@@ -59,7 +57,6 @@ struct ip_mc_list
extern struct ip_mc_list *ip_mc_head; extern struct ip_mc_list *ip_mc_head;
#ifdef __KERNEL__
extern int igmp_rcv(struct sk_buff *, struct device *, struct options *, unsigned long, unsigned short, extern int igmp_rcv(struct sk_buff *, struct device *, struct options *, unsigned long, unsigned short,
unsigned long, int , struct inet_protocol *); unsigned long, int , struct inet_protocol *);
extern void ip_mc_drop_device(struct device *dev); extern void ip_mc_drop_device(struct device *dev);
......
...@@ -42,19 +42,8 @@ ...@@ -42,19 +42,8 @@
#ifndef _LINUX_INET_H #ifndef _LINUX_INET_H
#define _LINUX_INET_H #define _LINUX_INET_H
#if defined(__i386__)
#define NET16(x) ((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00))
#elif defined(__mc68000__)
#define NET16(x) (x)
#elif defined(__alpha__)
#define NET16(x) ((((x) >> 8) & 0x00FF) | (((x) << 8) & 0xFF00))
#else
#error change this to match your machine
#endif
#ifdef __KERNEL__ #ifdef __KERNEL__
extern void inet_proto_init(struct net_proto *pro); extern void inet_proto_init(struct net_proto *pro);
extern char *in_ntoa(unsigned long in); extern char *in_ntoa(unsigned long in);
extern unsigned long in_aton(char *str); extern unsigned long in_aton(char *str);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#ifndef _LINUX_INTERRUPT_H #ifndef _LINUX_INTERRUPT_H
#define _LINUX_INTERRUPT_H #define _LINUX_INTERRUPT_H
#include <linux/linkage.h>
#include <asm/bitops.h> #include <asm/bitops.h>
struct bh_struct { struct bh_struct {
......
...@@ -40,6 +40,12 @@ struct timestamp { ...@@ -40,6 +40,12 @@ struct timestamp {
#elif defined(__mc68000__) #elif defined(__mc68000__)
__u8 overflow:4, __u8 overflow:4,
flags:4; flags:4;
#elif defined(__MIPSEL__)
__u8 flags:4,
overflow:4;
#elif defined(__MIPSEB__)
__u8 overflow:4,
flags:4;
#elif defined(__alpha__) #elif defined(__alpha__)
__u8 flags:4, __u8 flags:4,
overflow:4; overflow:4;
...@@ -81,7 +87,13 @@ struct iphdr { ...@@ -81,7 +87,13 @@ struct iphdr {
#elif defined (__mc68000__) #elif defined (__mc68000__)
__u8 version:4, __u8 version:4,
ihl:4; ihl:4;
#elif defined (__alpha__) #elif defined(__MIPSEL__)
__u8 ihl:4,
version:4;
#elif defined(__MIPSEB__)
__u8 version:4,
ihl:4;
#elif defined(__alpha__)
__u8 ihl:4, __u8 ihl:4,
version:4; version:4;
#else #else
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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