From d1e6fdb230ed063aad217775231eae225149a43a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:09:03 -0500 Subject: [PATCH] [PATCH] Linux-0.96-pre (April 21, 1992) More VFS layer work: remove more special cases, and take advantage of the virtual VFS functions (close and select). Add fchown/fchgrp and [f]truncate. Orest Zborowski shows up, and works on porting X11 to X. This needs a lot of infrastructure support: ioperm() for user-mode IO port access, and SVR style virtual terminal ioctl's to make porting easier. Perhaps more importantly, the mmap() system call shows up, even if it right now is limited only to a direct /dev/mem remapping. [Original changelog below] - truncate/ftruncate/fchmod/fchown system calls note that there aren't any library functions for these, so they aren't very useful yet... [f]truncate needed a change in the logic of the internal truncate VFS call - anybody that has any nonstandard filesystem probably needs to look it up. - io-bitmap syscalls giving root-processes access to selected io ports from user space. There is a "ioperm()" system call that lets the process select which ports it wants to enable/disable (all ports disabled as default) as well as a (standard sysv?) ioctl interface that X uses. again, no library stubs, but it allows things like reading and setting the cmos clock without using /dev/port, as well as control over the VGA registers... - mmap for /dev/mem more things needed for X... - the signal-handling fixes needed for gdb These aren't yet complete: serial lines still send signals under interrupts that can result in problems (ie ptrace doesn't correctly get them), but that's pretty unlikely (and will be fixed in the final 0.96). Breakpoints should work etc.. - multiple shared libraries Up to 6 simultaneous shared libraries/process: the patches were originally by pmacdona, but they were heavily changed by me, and I think they work in a more natural manner now. One user-level change is that the libraries are now checked for read and execute permissions for safety-reasons. - cleaned up special files. read/write/ioctl no longer has special-case code: it is all handled with tables to functions. This will mean that the SCSI patches won't patch in quite cleanly into 0.96: you'll need to add the code that sets up the functions. Again: device drivers and vfs-filesystem hackers need to look into the changes, although they are pretty logical (earlier versions just didn't implement all the vfs-routines) Note that the vfs-code for select is still not used: select is hardcoded for the devices it supports right now. - ptrace() has a new interface as gdb for versions < 0.95c don't work on the new version, and gdb won't work very well at all on 0.95c[+], there was no reason not to break ptrace. Thus 0.96 has a new calling convention for ptrace, and the old ptrace library function no longer works. I'm including the new ptrace library function at the end of this post. - mount() takes 4 arguments, and checks that only the super-user can mount/umount things. Happily this shouldn't break any old binaries. - some general cleanups --- .version | 2 +- Makefile | 164 ++-- boot/bootsect.S | 3 +- boot/setup.S | 273 +------ fs/Makefile | 212 +++-- fs/buffer.c | 48 +- fs/exec.c | 200 +---- fs/ext/Makefile | 108 --- fs/ext/bitmap.c | 242 ------ fs/ext/blkdev.c | 68 -- fs/ext/chrdev.c | 69 -- fs/ext/dir.c | 99 --- fs/ext/fifo.c | 27 - fs/ext/file.c | 223 ------ fs/ext/freelists.c | 345 --------- fs/ext/inode.c | 374 --------- fs/ext/namei.c | 900 ---------------------- fs/ext/symlink.c | 107 --- fs/ext/truncate.c | 157 ---- fs/fcntl.c | 13 +- fs/fifo.c | 115 --- fs/inode.c | 56 +- fs/ioctl.c | 13 +- fs/minix/Makefile | 118 +-- fs/minix/bitmap.c | 47 +- fs/minix/blkdev.c | 62 -- fs/minix/chrdev.c | 63 -- fs/minix/dir.c | 92 --- fs/minix/fifo.c | 27 - fs/minix/file.c | 223 ------ fs/minix/file_dev.c | 169 ++++ fs/minix/inode.c | 63 +- fs/minix/minix_op.c | 62 ++ fs/minix/namei.c | 113 +-- fs/minix/symlink.c | 101 --- fs/minix/truncate.c | 55 +- fs/msdos/Makefile | 77 -- fs/msdos/dir.c | 128 ---- fs/msdos/fat.c | 277 ------- fs/msdos/file.c | 210 ----- fs/msdos/inode.c | 275 ------- fs/msdos/misc.c | 365 --------- fs/msdos/namei.c | 512 ------------- fs/namei.c | 97 +-- fs/open.c | 166 ++-- fs/pipe.c | 145 +--- fs/read_write.c | 7 +- fs/select.c | 152 +++- fs/stat.c | 108 +-- fs/super.c | 132 +--- include/a.out.h | 2 - include/asm/io.h | 38 +- include/asm/irq.h | 94 --- include/asm/memory.h | 2 +- include/asm/segment.h | 2 +- include/asm/system.h | 14 +- include/{linux => }/fcntl.h | 27 +- include/linux/config.dist.h | 27 - include/linux/config.h | 52 +- include/linux/config.site.h | 9 - include/linux/config_rel.h | 2 +- include/linux/config_ver.h | 2 +- include/linux/ext_fs.h | 130 ---- include/linux/fd.h | 32 - include/linux/fdreg.h | 1 - include/linux/fs.h | 126 ++- include/linux/hdreg.h | 1 - include/linux/kernel.h | 2 + include/linux/limits.h | 16 - include/linux/lp.h | 8 +- include/linux/math_emu.h | 4 - include/linux/minix_fs.h | 15 +- include/linux/mm.h | 22 +- include/linux/mouse.h | 61 -- include/linux/msdos_fs.h | 190 ----- include/linux/sched.h | 100 +-- include/linux/string.h | 16 +- include/linux/sys.h | 13 +- include/linux/timer.h | 3 - include/linux/tty.h | 176 ++--- include/linux/unistd.h | 209 ----- include/linux/utsname.h | 24 - include/linux/wait.h | 19 - include/signal.h | 11 +- include/stddef.h | 2 +- include/sys/dirent.h | 1 - include/sys/ptrace.h | 15 - include/sys/resource.h | 7 - include/sys/socket.h | 39 - include/{linux => sys}/stat.h | 62 +- include/sys/time.h | 3 - include/sys/types.h | 25 - include/sys/un.h | 9 - include/sys/user.h | 70 -- include/sys/utsname.h | 17 + include/termios.h | 11 - include/time.h | 11 - include/unistd.h | 204 ++++- include/utime.h | 8 - init/main.c | 82 +- kernel/Makefile | 177 ++--- kernel/asm.s | 35 +- kernel/blk_drv/Makefile | 88 +-- kernel/blk_drv/blk.h | 73 +- kernel/blk_drv/floppy.c | 624 +++------------ kernel/blk_drv/hd.c | 167 +--- kernel/blk_drv/ll_rw_blk.c | 88 +-- kernel/blk_drv/ramdisk.c | 15 +- kernel/blk_drv/scsi/Makefile | 138 ---- kernel/blk_drv/scsi/aha1542.c | 457 ----------- kernel/blk_drv/scsi/aha1542.h | 122 --- kernel/blk_drv/scsi/config.in | 29 - kernel/blk_drv/scsi/hosts.c | 143 ---- kernel/blk_drv/scsi/hosts.h | 179 ----- kernel/blk_drv/scsi/scsi.c | 1016 ------------------------ kernel/blk_drv/scsi/scsi.h | 257 ------- kernel/blk_drv/scsi/scsi_ioctl.c | 153 ---- kernel/blk_drv/scsi/scsi_ioctl.h | 21 - kernel/blk_drv/scsi/sd.c | 380 --------- kernel/blk_drv/scsi/sd.h | 57 -- kernel/blk_drv/scsi/sd_ioctl.c | 24 - kernel/blk_drv/scsi/seagate.c | 607 --------------- kernel/blk_drv/scsi/seagate.h | 123 --- kernel/blk_drv/scsi/st.c | 36 - kernel/blk_drv/scsi/st.h | 26 - kernel/blk_drv/scsi/st_ioctl.c | 19 - kernel/blk_drv/scsi/ultrastor.c | 445 ----------- kernel/blk_drv/scsi/ultrastor.h | 90 --- kernel/chr_drv/Makefile | 150 ++-- kernel/chr_drv/console.c | 1010 ++++++++---------------- kernel/chr_drv/keyboard.S | 805 +++++++++++++++++++ kernel/chr_drv/keyboard.c | 1230 ------------------------------ kernel/chr_drv/lp.c | 37 +- kernel/chr_drv/mem.c | 35 +- kernel/chr_drv/mouse.c | 177 ----- kernel/chr_drv/pty.c | 55 +- kernel/chr_drv/rs_io.s | 164 ++++ kernel/chr_drv/serial.c | 460 ++--------- kernel/chr_drv/tty_io.c | 582 +++++--------- kernel/chr_drv/tty_ioctl.c | 187 ++--- kernel/chr_drv/vt.c | 80 +- kernel/chr_drv/vt_kern.h | 13 +- kernel/exit.c | 109 +-- kernel/fork.c | 39 +- kernel/ioport.c | 27 - kernel/irq.c | 190 ----- kernel/itimer.c | 114 --- kernel/math/Makefile | 121 ++- kernel/math/ea.c | 4 +- kernel/math/emulate.c | 30 +- kernel/math/error.c | 2 +- kernel/math/sqrt.c | 95 --- kernel/printk.c | 85 +-- kernel/ptrace.c | 109 +-- kernel/sched.c | 188 ++--- kernel/signal.c | 70 +- kernel/sys.c | 116 +-- kernel/sys_call.S | 104 ++- kernel/traps.c | 18 +- lib/Makefile | 65 +- lib/_exit.c | 4 +- lib/close.c | 3 +- lib/dup.c | 3 +- lib/execve.c | 3 +- lib/itimer.c | 12 - lib/open.c | 2 +- lib/setsid.c | 4 +- lib/wait.c | 3 +- lib/write.c | 4 +- mm/Makefile | 48 +- mm/memory.c | 126 ++- mm/mmap.c | 8 +- mm/swap.c | 21 +- net/Makefile | 49 -- net/kern_sock.h | 67 -- net/socket.c | 764 ------------------- net/socketcall.h | 13 - net/unix.c | 598 --------------- tools/build.c | 4 +- 179 files changed, 4007 insertions(+), 19469 deletions(-) delete mode 100644 fs/ext/Makefile delete mode 100644 fs/ext/bitmap.c delete mode 100644 fs/ext/blkdev.c delete mode 100644 fs/ext/chrdev.c delete mode 100644 fs/ext/dir.c delete mode 100644 fs/ext/fifo.c delete mode 100644 fs/ext/file.c delete mode 100644 fs/ext/freelists.c delete mode 100644 fs/ext/inode.c delete mode 100644 fs/ext/namei.c delete mode 100644 fs/ext/symlink.c delete mode 100644 fs/ext/truncate.c delete mode 100644 fs/fifo.c delete mode 100644 fs/minix/blkdev.c delete mode 100644 fs/minix/chrdev.c delete mode 100644 fs/minix/dir.c delete mode 100644 fs/minix/fifo.c delete mode 100644 fs/minix/file.c create mode 100644 fs/minix/file_dev.c create mode 100644 fs/minix/minix_op.c delete mode 100644 fs/minix/symlink.c delete mode 100644 fs/msdos/Makefile delete mode 100644 fs/msdos/dir.c delete mode 100644 fs/msdos/fat.c delete mode 100644 fs/msdos/file.c delete mode 100644 fs/msdos/inode.c delete mode 100644 fs/msdos/misc.c delete mode 100644 fs/msdos/namei.c delete mode 100644 include/asm/irq.h rename include/{linux => }/fcntl.h (62%) delete mode 100644 include/linux/config.dist.h delete mode 100644 include/linux/config.site.h delete mode 100644 include/linux/ext_fs.h delete mode 100644 include/linux/fd.h delete mode 100644 include/linux/limits.h delete mode 100644 include/linux/mouse.h delete mode 100644 include/linux/msdos_fs.h delete mode 100644 include/linux/unistd.h delete mode 100644 include/linux/utsname.h delete mode 100644 include/linux/wait.h delete mode 100644 include/sys/socket.h rename include/{linux => sys}/stat.h (50%) delete mode 100644 include/sys/un.h delete mode 100644 include/sys/user.h create mode 100644 include/sys/utsname.h delete mode 100644 kernel/blk_drv/scsi/Makefile delete mode 100644 kernel/blk_drv/scsi/aha1542.c delete mode 100644 kernel/blk_drv/scsi/aha1542.h delete mode 100644 kernel/blk_drv/scsi/config.in delete mode 100644 kernel/blk_drv/scsi/hosts.c delete mode 100644 kernel/blk_drv/scsi/hosts.h delete mode 100644 kernel/blk_drv/scsi/scsi.c delete mode 100644 kernel/blk_drv/scsi/scsi.h delete mode 100644 kernel/blk_drv/scsi/scsi_ioctl.c delete mode 100644 kernel/blk_drv/scsi/scsi_ioctl.h delete mode 100644 kernel/blk_drv/scsi/sd.c delete mode 100644 kernel/blk_drv/scsi/sd.h delete mode 100644 kernel/blk_drv/scsi/sd_ioctl.c delete mode 100644 kernel/blk_drv/scsi/seagate.c delete mode 100644 kernel/blk_drv/scsi/seagate.h delete mode 100644 kernel/blk_drv/scsi/st.c delete mode 100644 kernel/blk_drv/scsi/st.h delete mode 100644 kernel/blk_drv/scsi/st_ioctl.c delete mode 100644 kernel/blk_drv/scsi/ultrastor.c delete mode 100644 kernel/blk_drv/scsi/ultrastor.h create mode 100644 kernel/chr_drv/keyboard.S delete mode 100644 kernel/chr_drv/keyboard.c delete mode 100644 kernel/chr_drv/mouse.c create mode 100644 kernel/chr_drv/rs_io.s delete mode 100644 kernel/irq.c delete mode 100644 kernel/itimer.c delete mode 100644 kernel/math/sqrt.c delete mode 100644 lib/itimer.c delete mode 100644 net/Makefile delete mode 100644 net/kern_sock.h delete mode 100644 net/socket.c delete mode 100644 net/socketcall.h delete mode 100644 net/unix.c diff --git a/.version b/.version index 573541ac9702..fb1e7bc86996 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0 +54 diff --git a/Makefile b/Makefile index ec7057422cdb..dc83ace062bf 100644 --- a/Makefile +++ b/Makefile @@ -1,53 +1,38 @@ # -# ROOT_DEV specifies the default root-device when making the image. -# This can be either FLOPPY, /dev/xxxx or empty, in which case the -# default of FLOPPY is used by 'build'. +# comment this line if you don't want the emulation-code # -ROOT_DEV = /dev/hdb1 +MATH_EMULATION = -DKERNEL_MATH_EMULATION # # uncomment the correct keyboard: # -# The value of KBDFLAGS should be or'ed together from the following -# bits, depending on which features you want enabled. -# 0x80 - Off: the Alt key will set bit 7 if pressed together with -# another key. -# On: the Alt key will NOT set the high bit; an escape -# character is prepended instead. -# The least significant bits control if the following keys are "dead". -# The key is dead by default if the bit is on. -# 0x01 - backquote (`) -# 0x02 - accent acute -# 0x04 - circumflex (^) -# 0x08 - tilde (~) -# 0x10 - dieresis (umlaut) - -KEYBOARD = -DKBD_FINNISH -DKBDFLAGS=0 -# KEYBOARD = -DKBD_FINNISH_LATIN1 -DKBDFLAGS=0x9F -# KEYBOARD = -DKBD_US -DKBDFLAGS=0 -# KEYBOARD = -DKBD_GR -DKBDFLAGS=0 -# KEYBOARD = -DKBD_GR_LATIN1 -DKBDFLAGS=0x9F -# KEYBOARD = -DKBD_FR -DKBDFLAGS=0 -# KEYBOARD = -DKBD_FR_LATIN1 -DKBDFLAGS=0x9F -# KEYBOARD = -DKBD_UK -DKBDFLAGS=0 -# KEYBOARD = -DKBD_DK -DKBDFLAGS=0 -# KEYBOARD = -DKBD_DK_LATIN1 -DKBDFLAGS=0x9F -# KEYBOARD = -DKBD_DVORAK -DKBDFLAGS=0 -# KEYBOARD = -DKBD_SG -DKBDFLAGS=0 -# KEYBOARD = -DKBD_SG_LATIN1 -DKBDFLAGS=0x9F + +KEYBOARD = -DKBD_FINNISH +# KEYBOARD = -DKBD_US +# KEYBOARD = -DKBD_GR +# KEYBOARD = -DKBD_FR +# KEYBOARD = -DKBD_UK +# KEYBOARD = -DKBD_DK + +# +# uncomment this line if you are using gcc-1.40 +# +#GCC_OPT = -fcombine-regs -fstrength-reduce # -# comment this line if you don't want the emulation-code +# standard CFLAGS # -MATH_EMULATION = -DKERNEL_MATH_EMULATION +CFLAGS =-Wall -O6 -fomit-frame-pointer $(GCC_OPT) # -# standard CFLAGS +# ROOT_DEV specifies the default root-device when making the image. +# This can be either FLOPPY, /dev/xxxx or empty, in which case the +# default of FLOPPY is used by 'build'. # -CFLAGS =-Wall -O6 -fomit-frame-pointer +ROOT_DEV = /dev/hdb1 # # if you want the ram-disk device, define this to be the @@ -61,37 +46,32 @@ LD86 =ld86 -0 AS =as LD =ld -HOSTCC =gcc -static -CC =gcc -nostdinc -I$(KERNELHDRS) -MAKE =make -CPP =$(CC) -E -AR =ar - -ARCHIVES =kernel/kernel.o mm/mm.o fs/fs.o net/net.o -FILESYSTEMS =fs/minix/minix.o fs/ext/ext.o fs/msdos/msdos.o -DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a \ - kernel/blk_drv/scsi/scsi.a +#LDFLAGS =-s -x -M +LDFLAGS = -M +CC =gcc $(RAMDISK) +MAKE =make CFLAGS="$(CFLAGS)" +CPP =cpp -nostdinc -Iinclude + +ARCHIVES =kernel/kernel.o mm/mm.o fs/fs.o +FILESYSTEMS =fs/minix/minix.o +DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a MATH =kernel/math/math.a LIBS =lib/lib.a -SUBDIRS =kernel mm fs net lib - -KERNELHDRS =/usr/src/linux/include .c.s: - $(CC) $(CFLAGS) -S $< + $(CC) $(CFLAGS) \ + -nostdinc -Iinclude -S -o $*.s $< .s.o: $(AS) -c -o $*.o $< .c.o: - $(CC) $(CFLAGS) -c -o $*.o $< + $(CC) $(CFLAGS) \ + -nostdinc -Iinclude -c -o $*.o $< all: Version Image -subdirs: dummy - for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done - Version: @./makever.sh - @echo \#define UTS_RELEASE \"0.96c.pl2-`cat .version`\" > include/linux/config_rel.h + @echo \#define UTS_RELEASE \"0.95c-`cat .version`\" > include/linux/config_rel.h @echo \#define UTS_VERSION \"`date +%D`\" > include/linux/config_ver.h touch include/linux/config.h @@ -106,19 +86,44 @@ disk: Image dd bs=8192 if=Image of=/dev/PS0 tools/build: tools/build.c - $(HOSTCC) $(CFLAGS) \ + $(CC) -static $(CFLAGS) \ -o tools/build tools/build.c boot/head.o: boot/head.s -tools/system: boot/head.o init/main.o subdirs - $(LD) $(LDFLAGS) -M boot/head.o init/main.o \ - $(ARCHIVES) \ - $(FILESYSTEMS) \ - $(DRIVERS) \ - $(MATH) \ - $(LIBS) \ - -o tools/system > System.map +tools/system: boot/head.o init/main.o \ + $(ARCHIVES) $(FILESYSTEMS) $(DRIVERS) $(MATH) $(LIBS) + $(LD) $(LDFLAGS) boot/head.o init/main.o \ + $(ARCHIVES) \ + $(FILESYSTEMS) \ + $(DRIVERS) \ + $(MATH) \ + $(LIBS) \ + -o tools/system > System.map + +kernel/math/math.a: dummy + (cd kernel/math; $(MAKE) MATH_EMULATION="$(MATH_EMULATION)") + +kernel/blk_drv/blk_drv.a: dummy + (cd kernel/blk_drv; $(MAKE)) + +kernel/chr_drv/chr_drv.a: dummy + (cd kernel/chr_drv; $(MAKE) KEYBOARD="$(KEYBOARD)") + +kernel/kernel.o: dummy + (cd kernel; $(MAKE)) + +mm/mm.o: dummy + (cd mm; $(MAKE)) + +fs/fs.o: dummy + (cd fs; $(MAKE)) + +fs/minix/minix.o: dummy + (cd fs/minix; $(MAKE)) + +lib/lib.a: dummy + (cd lib; $(MAKE)) boot/setup: boot/setup.s $(AS86) -o boot/setup.o boot/setup.s @@ -138,28 +143,31 @@ clean: rm -f Image System.map tmp_make core boot/bootsect boot/setup \ boot/bootsect.s boot/setup.s init/main.s rm -f init/*.o tools/system tools/build boot/*.o - for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean); done + (cd mm;make clean) + (cd fs;make clean) + (cd kernel;make clean) + (cd lib;make clean) backup: clean - cd .. ; tar cf - linux | compress - > backup.Z + (cd .. ; tar cf - linux | compress - > backup.Z) sync -depend dep: +dep: sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done >> tmp_make + (for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done) >> tmp_make cp tmp_make Makefile - for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep); done + (cd fs; make dep) + (cd kernel; make dep) + (cd mm; make dep) + (cd lib; make dep) dummy: ### Dependencies: -init/main.o : init/main.c /usr/src/linux/include/stddef.h /usr/src/linux/include/stdarg.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/asm/system.h \ - /usr/src/linux/include/asm/io.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/config.h \ - /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \ - /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \ - /usr/src/linux/include/termios.h /usr/src/linux/include/linux/unistd.h +init/main.o : init/main.c include/unistd.h include/sys/stat.h include/sys/types.h \ + include/sys/time.h include/time.h include/sys/times.h include/sys/utsname.h \ + include/sys/param.h include/sys/resource.h include/utime.h include/linux/sched.h \ + include/linux/head.h include/linux/fs.h include/sys/dirent.h include/limits.h \ + include/linux/mm.h include/linux/kernel.h include/signal.h include/linux/tty.h \ + include/termios.h include/linux/string.h include/asm/system.h include/asm/io.h \ + include/stddef.h include/stdarg.h include/fcntl.h diff --git a/boot/bootsect.S b/boot/bootsect.S index 22ebdea74a8e..837be3219e07 100644 --- a/boot/bootsect.S +++ b/boot/bootsect.S @@ -224,7 +224,8 @@ got_sectors: mov ax,#0x021c ! /dev/PS0 - 1.44Mb cmp bx,#18 je root_defined - mov ax,#0x0200 ! /dev/fd0 - autodetect +undef_root: + jmp undef_root root_defined: seg cs mov root_dev,ax diff --git a/boot/setup.S b/boot/setup.S index 88c23cd10ca4..bd23161825c2 100644 --- a/boot/setup.S +++ b/boot/setup.S @@ -189,10 +189,9 @@ end_move: out #0xA1,al .word 0x00eb,0x00eb mov al,#0xFF ! mask off all interrupts for now - out #0xA1,al + out #0x21,al .word 0x00eb,0x00eb - mov al,#0xFB ! mask all irq's but irq2 which - out #0x21,al ! is cascaded + out #0xA1,al ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't ! need no steenking BIOS anyway (except for the initial loading :-). @@ -242,75 +241,10 @@ chsvga: cld push ds push cs pop ds - -! First try and execute a VESA BIOS call - - mov ax,#0x4f00 ! AX = VESA BIOS func RETURN SVGA Info - push cs - pop es - lea di,vib ! ES:[DI] -> VESA Information Block Ptr - int 0x10 - - cmp ax,#0x004f ! Check result status - jne novesa ! VESA BIOS not supported or failed - -! OK! We got a VESA BIOS, let's figure out what we can do! - -! Print out the VESA information from the VIB - - lea si,vib ! This should print out VESA - lodsb - call prnt1 - lodsb - call prnt1 - lodsb - call prnt1 - lodsb - call prnt1 - call space - - mov al,vib+5 ! This is the version of VESA supported - call dprnt - mov al,#0x2e - call prnt1 - mov al,vib+4 - call dprnt - call space - - push ds - lds si,vib+6 ! This prints out the OEM string - call prtstr - call space - pop ds - - mov al,vib+10 ! This prints out the Vesa Capabilities - call dprnt - mov al,vib+11 - call dprnt - mov al,vib+12 - call dprnt - mov al,vib+13 - call dprnt - - push ds ! Finally, go through the list of modes - lds si,vib+14 -model: lodsw ! Get mode number - cmp ax,#0xFFFF - je isvesa - call addmod ! Check to see if this is a TEXT mode - jmp model - -isvesa: call docr - pop ds - lea si,dscvesa - lea di,movesa - lea cx,selmod - jmp cx - -novesa: mov ax,#0xc000 + mov ax,#0xc000 mov es,ax lea si,msg1 - call prtstr ! Press to see SVGA-modes ... + call prtstr flush: in al,#0x60 ! Flush the keyboard buffer cmp al,#0x82 jb nokey @@ -529,38 +463,23 @@ even7: mov al,#0x0c mov al,#0x55 xor al,#0xea cmp al,bh - je isvideo7 - lea cx,set8x8 - jmp cx -isvideo7: + jne novid7 lea si,dscvideo7 lea di,movideo7 - -! Upon Entry to SELMOD, SI -> list of Modes, DI -> List of Mode Numbers - selmod: push si - lea si,msg2 ! Numb: Mode: COLSxROWS + lea si,msg2 call prtstr - mov cx,(di) ! This gets Number of Modes in list + xor cx,cx + mov cl,(di) pop si push si push cx tbl: pop bx push bx - mov ax,bx - sub ax,cx - call hprntl ! Print out selection number - push ax - call spcing - pop ax - push di - add ax,ax - add ax,#2 - add di,ax - mov ax,(di) - call hprntl ! Print out MODE number + mov al,bl + sub al,cl + call dprnt call spcing - pop di lodsw xchg al,ah call dprnt @@ -574,7 +493,7 @@ tbl: pop bx loop tbl pop cx call docr - lea si,msg3 ! Choose Mode Number + lea si,msg3 call prtstr pop si add cl,#0x80 @@ -590,38 +509,18 @@ zero: sub al,#0x0a nozero: sub al,#0x80 dec al xor ah,ah - shl ax,#1 - push ax add di,ax inc di - inc di - mov ax,(di) ! AX = Mode - cmp ah,#0 - jne setvesa - int 0x10 ! Set OLD style mode - -retmode: + push ax + mov al,(di) + int 0x10 pop ax + shl ax,#1 add si,ax - lodsw ! Get COLSxROWS + lodsw pop ds ret - -setvesa: - pop bx - cmp ah,#0xFF ! Special, mode FF, set 8x8 font - je set8x8 - - push bx - mov bx,ax ! Mode to set - mov ax,#0x4f02 ! Set VESA mode - int 0x10 - - jmp retmode - -! If we can't find the adapter in the table, at least set 80x50 - -set8x8: +novid7: mov ax,#0x1112 mov bl,#0 int 0x10 ! use 8x8 font set (50 lines on VGA) @@ -642,83 +541,17 @@ set8x8: mov ax,#0x5032 ! return 80x50 ret -! Routine to add mode in ax to VESA selection table - -addmod: push cx - push ds - push es - push di - push bx - push dx - push ax - - mov cx,ax ! CX = VESA mode number - push cs - pop es - lea di,mib ! ES:[DI] -> Mode Information Block - mov ax,#0x4f01 ! AX = Get VESA Mode Info - int 0x10 - - cmp ax,#0x004f ! If fails, assume it's not a TEXT mode - jne adfail - - push cs - pop ds ! Make DS contain something reasonable - - mov ax,mib ! Get Mode Attributes field - and al,#0x12 ! Mask Text and Extended bits - cmp al,#0x02 ! Text and Extended info available? - jne adfail - - call space - - mov ax,mib+18 ! Horizontal Resolution - mov bl,mib+22 ! X Char Size - div bl -! HACK: For some reason, my Diamond Stealth card returns 160 cols for its -! 132 coloumn modes, so don't return any sizes > 132? - sub al,#132 - jbe orgcol - sub al,al -orgcol: add al,#132 ! MIN(cols, 132) - mov dh,al ! Put num cols in DH - mov ax,mib+20 ! Vertical Resolution - mov bl,mib+23 ! Y Char Size - div bl - mov dl,al ! Put num rows in DL - - mov bx,movesa ! Get current number of video modes - lea di,movesa - inc (di) ! This is a NEW mode - add bx,bx - add di,bx - add di,#2 - pop ax ! Get Mode number back - push ax - mov (di),ax ! Mode number - lea di,dscvesa - add di,bx - mov (di),dx ! Screen resolution - -adfail: pop ax - pop dx - pop bx - pop di - pop es - pop ds - pop cx - - ret - ! Routine that 'tabs' to next col. spcing: mov al,#0x2e + call prnt1 + mov al,#0x20 call prnt1 -space3: mov al,#0x20 + mov al,#0x20 call prnt1 -space2: mov al,#0x20 + mov al,#0x20 call prnt1 -space: mov al,#0x20 + mov al,#0x20 call prnt1 ret @@ -731,39 +564,6 @@ prtstr: lodsb jmp prtstr fin: ret -! Routine to print out HEX values on screen. -! The value to be printed is in the AX register. - -hprntl: xchg ah,al - call hprnt - xchg ah,al - call hprnt - ret - -! Routine to print out HEX values on the screen -! The valueto be printed is in the AL register. AH is preserved. - -hprnt: push ax - shr al,4 - and al,#0xf - call hprnt1 - pop ax - push ax - and al,#0xf - call hprnt1 - pop ax - ret - -! Routine to print out one HEX digit on the screen. -! The value to be printed is in al (0-F) - -hprnt1: cmp al,#10 - jl hdec - add al,#7 ! Convert 10-15 to A-F -hdec: add al,#0x30 ! Convert to ASCII - call prnt1 ! print it - ret - ! Routine to print a decimal value on screen, the value to be ! printed is put in al (i.e 0-255). @@ -835,7 +635,7 @@ gdt_48: msg1: .ascii "Press to see SVGA-modes available or any other key to continue." db 0x0d, 0x0a, 0x0a, 0x00 -msg2: .ascii "Numb: Mode: COLSxROWS:" +msg2: .ascii "Mode: COLSxROWS:" db 0x0d, 0x0a, 0x0a, 0x00 msg3: .ascii "Choose mode by pressing the corresponding number." db 0x0d, 0x0a, 0x00 @@ -847,17 +647,16 @@ idparadise: .ascii "VGA=" ! Manufacturer: Numofmodes: Mode: -moati: .word 0x02, 0x23, 0x33 -moahead: .word 0x05, 0x22, 0x23, 0x24, 0x2f, 0x34 -mocandt: .word 0x02, 0x60, 0x61 -mocirrus: .word 0x04, 0x1f, 0x20, 0x22, 0x31 -moeverex: .word 0x0a, 0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40 -mogenoa: .word 0x0a, 0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78 -moparadise: .word 0x02, 0x55, 0x54 -motrident: .word 0x07, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a -motseng: .word 0x05, 0x26, 0x2a, 0x23, 0x24, 0x22 -movideo7: .word 0x06, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45 -movesa: .word 0x02, 0x03, 0xFFFF, 254*0 +moati: .byte 0x02, 0x23, 0x33 +moahead: .byte 0x05, 0x22, 0x23, 0x24, 0x2f, 0x34 +mocandt: .byte 0x02, 0x60, 0x61 +mocirrus: .byte 0x04, 0x1f, 0x20, 0x22, 0x31 +moeverex: .byte 0x0a, 0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40 +mogenoa: .byte 0x0a, 0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78 +moparadise: .byte 0x02, 0x55, 0x54 +motrident: .byte 0x07, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a +motseng: .byte 0x05, 0x26, 0x2a, 0x23, 0x24, 0x22 +movideo7: .byte 0x06, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45 ! msb = Cols lsb = Rows: @@ -871,11 +670,7 @@ dscparadise: .word 0x8419, 0x842b dsctrident: .word 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843c dsctseng: .word 0x503c, 0x6428, 0x8419, 0x841c, 0x842c dscvideo7: .word 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c -dscvesa: .word 0x5019, 0x5032, 254*0 -vib: .word 256*0 -mib: .word 256*0 - .text endtext: .data diff --git a/fs/Makefile b/fs/Makefile index 6a8403dc7d1b..602e09f33472 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -7,148 +7,108 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -SUBDIRS =minix ext msdos +AR =ar +AS =as +LD =ld +CC =gcc -nostdinc -I../include +CPP =cpp -nostdinc -I../include .c.s: - $(CC) $(CFLAGS) -S $< + $(CC) $(CFLAGS) \ + -S -o $*.s $< .c.o: - $(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) \ + -c -o $*.o $< .s.o: $(AS) -o $*.o $< OBJS= open.o read_write.o inode.o file_table.o buffer.o super.o \ block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \ - select.o fifo.o - -all: fs.o subdirs + select.o fs.o: $(OBJS) $(LD) -r -o fs.o $(OBJS) -subdirs: dummy - for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done - clean: rm -f core *.o *.a tmp_make - for i in *.c; do rm -f `basename $$i .c`.s;done - for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean); done + for i in *.c;do rm -f `basename $$i .c`.s;done + cd minix; make clean -depend dep: +dep: sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - for i in *.c;do $(CPP) -M $$i;done >> tmp_make + (for i in *.c;do $(CPP) -M $$i;done) >> tmp_make cp tmp_make Makefile - for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep); done - -dummy: + cd minix; make dep ### Dependencies: -block_dev.o : block_dev.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/asm/system.h -buffer.o : buffer.c /usr/src/linux/include/stdarg.h /usr/src/linux/include/linux/config.h \ - /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \ - /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/system.h \ - /usr/src/linux/include/asm/io.h -exec.o : exec.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/sys/ptrace.h \ - /usr/src/linux/include/a.out.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h \ - /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/sys/user.h -fcntl.o : fcntl.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h -fifo.o : fifo.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/fcntl.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h -file_table.o : file_table.c /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h -inode.o : inode.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/asm/system.h -ioctl.o : ioctl.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/string.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h -namei.o : namei.c /usr/src/linux/include/errno.h /usr/src/linux/include/const.h \ - /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/string.h \ - /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/stat.h -open.o : open.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/utime.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/string.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/asm/segment.h -pipe.o : pipe.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/termios.h \ - /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h -read_write.o : read_write.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/asm/segment.h -select.o : select.c /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/tty.h \ - /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/string.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/const.h \ - /usr/src/linux/include/errno.h -stat.o : stat.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/stat.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/asm/segment.h -super.o : super.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \ - /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/ext_fs.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/errno.h +block_dev.o : block_dev.c ../include/errno.h ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \ + ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \ + ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/asm/segment.h \ + ../include/asm/system.h +buffer.o : buffer.c ../include/stdarg.h ../include/linux/config.h ../include/linux/config_rel.h \ + ../include/linux/config_ver.h ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \ + ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \ + ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/asm/system.h \ + ../include/asm/io.h +exec.o : exec.c ../include/signal.h ../include/sys/types.h ../include/errno.h \ + ../include/linux/string.h ../include/sys/stat.h ../include/a.out.h ../include/linux/fs.h \ + ../include/sys/dirent.h ../include/limits.h ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/mm.h ../include/linux/kernel.h ../include/sys/param.h ../include/sys/time.h \ + ../include/time.h ../include/sys/resource.h ../include/asm/segment.h +fcntl.o : fcntl.c ../include/linux/string.h ../include/errno.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \ + ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \ + ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \ + ../include/asm/segment.h ../include/fcntl.h ../include/sys/stat.h +file_table.o : file_table.c ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \ + ../include/limits.h +inode.o : inode.c ../include/linux/string.h ../include/sys/stat.h ../include/sys/types.h \ + ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h \ + ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \ + ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \ + ../include/asm/system.h +ioctl.o : ioctl.c ../include/linux/string.h ../include/errno.h ../include/sys/stat.h \ + ../include/sys/types.h ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \ + ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h \ + ../include/signal.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \ + ../include/sys/resource.h +namei.o : namei.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \ + ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \ + ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \ + ../include/time.h ../include/sys/resource.h ../include/asm/segment.h ../include/linux/string.h \ + ../include/fcntl.h ../include/errno.h ../include/const.h ../include/sys/stat.h +open.o : open.c ../include/errno.h ../include/fcntl.h ../include/sys/types.h \ + ../include/utime.h ../include/sys/stat.h ../include/sys/vfs.h ../include/linux/string.h \ + ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h \ + ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \ + ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \ + ../include/asm/segment.h +pipe.o : pipe.c ../include/signal.h ../include/sys/types.h ../include/errno.h \ + ../include/termios.h ../include/fcntl.h ../include/asm/segment.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h \ + ../include/linux/mm.h ../include/linux/kernel.h ../include/sys/param.h ../include/sys/time.h \ + ../include/time.h ../include/sys/resource.h +read_write.o : read_write.c ../include/errno.h ../include/sys/types.h ../include/sys/stat.h \ + ../include/sys/dirent.h ../include/limits.h ../include/linux/kernel.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/linux/mm.h ../include/signal.h \ + ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \ + ../include/linux/minix_fs.h ../include/asm/segment.h +select.o : select.c ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \ + ../include/limits.h ../include/linux/kernel.h ../include/linux/tty.h ../include/termios.h \ + ../include/linux/sched.h ../include/linux/head.h ../include/linux/mm.h ../include/signal.h \ + ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \ + ../include/linux/string.h ../include/asm/segment.h ../include/asm/system.h ../include/sys/stat.h \ + ../include/const.h ../include/errno.h +stat.o : stat.c ../include/errno.h ../include/sys/stat.h ../include/sys/types.h \ + ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \ + ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \ + ../include/asm/segment.h +super.o : super.c ../include/linux/config.h ../include/linux/config_rel.h ../include/linux/config_ver.h \ + ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h \ + ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h \ + ../include/signal.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \ + ../include/sys/resource.h ../include/linux/minix_fs.h ../include/asm/system.h \ + ../include/asm/segment.h ../include/errno.h ../include/sys/stat.h diff --git a/fs/buffer.c b/fs/buffer.c index 571c3b5afeff..4b80848ede48 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -30,7 +30,7 @@ extern int end; static struct buffer_head * start_buffer = (struct buffer_head *) &end; static struct buffer_head * hash_table[NR_HASH]; static struct buffer_head * free_list; -static struct wait_queue * buffer_wait = NULL; +static struct task_struct * buffer_wait = NULL; int NR_BUFFERS = 0; static inline void wait_on_buffer(struct buffer_head * bh) @@ -47,25 +47,23 @@ static void sync_buffers(int dev) struct buffer_head * bh; bh = free_list; - for (i = NR_BUFFERS*2 ; i-- > 0 ; bh = bh->b_next_free) { - if (bh->b_lock) + for (i=0 ; ib_next_free) { +#if 0 + if (dev && (bh->b_dev != dev)) continue; - if (!bh->b_dirt) +#endif + wait_on_buffer(bh); +#if 0 + if (dev && (bh->b_dev != dev)) continue; - ll_rw_block(WRITE,bh); +#endif + if (bh->b_dirt) + ll_rw_block(WRITE,bh); } } int sys_sync(void) { - int i; - - for (i=0 ; iwrite_super - && super_block[i].s_dirt) - super_block[i].s_op->write_super(&super_block[i]); sync_inodes(); /* write out inodes into buffers */ sync_buffers(0); return 0; @@ -73,11 +71,6 @@ int sys_sync(void) int sync_dev(int dev) { - struct super_block * sb; - - if (sb = get_super (dev)) - if (sb->s_op && sb->s_op->write_super && sb->s_dirt) - sb->s_op->write_super (sb); sync_buffers(dev); sync_inodes(); sync_buffers(dev); @@ -265,7 +258,9 @@ repeat: if (bh = get_hash_table(dev,block)) return bh; buffers = NR_BUFFERS; - for (tmp = free_list ; buffers-- > 0 ; tmp = tmp->b_next_free) { + tmp = free_list; + do { + tmp = tmp->b_next_free; if (tmp->b_count) continue; if (!bh || BADNESS(tmp)b_dirt) ll_rw_block(WRITEA,tmp); -#endif - } /* and repeat until we find something good */ + } while (buffers--); if (!bh) { sleep_on(&buffer_wait); goto repeat; @@ -286,9 +279,11 @@ repeat: wait_on_buffer(bh); if (bh->b_count) goto repeat; - if (bh->b_dirt) { - sync_buffers(bh->b_dev); - goto repeat; + while (bh->b_dirt) { + sync_dev(bh->b_dev); + wait_on_buffer(bh); + if (bh->b_count) + goto repeat; } /* NOTE!! While we slept waiting for this block, somebody else might */ /* already have added "this" block to the cache. check it */ @@ -389,7 +384,7 @@ struct buffer_head * breada(int dev,int first, ...) tmp=getblk(dev,first); if (tmp) { if (!tmp->b_uptodate) - ll_rw_block(READA,tmp); + ll_rw_block(READA,bh); tmp->b_count--; } } @@ -425,7 +420,6 @@ void buffer_init(long buffer_end) h->b_next = NULL; h->b_prev = NULL; h->b_data = (char *) b; - h->b_reqnext = NULL; h->b_prev_free = h-1; h->b_next_free = h+1; h++; diff --git a/fs/exec.c b/fs/exec.c index 8a5b0afa71ba..cb7b2ba0ab8e 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -19,18 +19,15 @@ #include #include -#include +#include +#include #include -#include -#include -#include #include #include #include #include #include -#include extern int sys_exit(int exit_code); extern int sys_close(int fd); @@ -42,121 +39,6 @@ extern int sys_close(int fd); */ #define MAX_ARG_PAGES 32 -/* - * These are the only things you should do on a core-file: use only these - * macros to write out all the necessary info. - */ -#define DUMP_WRITE(addr,nr) \ -while (file.f_op->write(inode,&file,(char *)(addr),(nr)) != (nr)) goto close_coredump - -#define DUMP_SEEK(offset) \ -if (file.f_op->lseek) { \ - if (file.f_op->lseek(inode,&file,(offset),0) != (offset)) \ - goto close_coredump; \ -} else file.f_pos = (offset) - -/* - * Routine writes a core dump image in the current directory. - * Currently only a stub-function. - * - * Note that setuid/setgid files won't make a core-dump if the uid/gid - * changed due to the set[u|g]id. It's enforced by the "current->dumpable" - * field, which also makes sure the core-dumps won't be recursive if the - * dumping of the process results in another error.. - */ -int core_dump(long signr, struct pt_regs * regs) -{ - struct inode * inode = NULL; - struct file file; - unsigned short fs; - int has_dumped = 0; - register int dump_start, dump_size; - struct user dump; - - if (!current->dumpable) - return 0; - current->dumpable = 0; -/* See if we have enough room to write the upage. */ - if(current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE/1024) return 0; - __asm__("mov %%fs,%0":"=r" (fs)); - __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10)); - if (open_namei("core",O_CREAT | O_WRONLY | O_TRUNC,0600,&inode)) - goto end_coredump; - if (!S_ISREG(inode->i_mode)) - goto end_coredump; - if (!inode->i_op || !inode->i_op->default_file_ops) - goto end_coredump; - file.f_mode = 3; - file.f_flags = 0; - file.f_count = 1; - file.f_inode = inode; - file.f_pos = 0; - file.f_reada = 0; - file.f_op = inode->i_op->default_file_ops; - if (file.f_op->open) - if (file.f_op->open(inode,&file)) - goto end_coredump; - if (!file.f_op->write) - goto close_coredump; - has_dumped = 1; -/* write and seek example: from kernel space */ - __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10)); - dump.magic = CMAGIC; - dump.u_tsize = current->end_code / PAGE_SIZE; - dump.u_dsize = (current->brk - current->end_code) / PAGE_SIZE; - dump.u_ssize =((current->start_stack +(PAGE_SIZE-1)) / PAGE_SIZE) - - (regs->esp/ PAGE_SIZE); -/* If the size of the dump file exceeds the rlimit, then see what would happen - if we wrote the stack, but not the data area. */ - if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE/1024 > - current->rlim[RLIMIT_CORE].rlim_cur) - dump.u_dsize = 0; -/* Make sure we have enough room to write the stack and data areas. */ - if ((dump.u_ssize+1) * PAGE_SIZE / 1024 > - current->rlim[RLIMIT_CORE].rlim_cur) - dump.u_ssize = 0; - dump.u_comm = 0; - dump.u_ar0 = (struct pt_regs *)(((int)(&dump.regs)) -((int)(&dump))); - dump.signal = signr; - dump.regs = *regs; - dump.start_code = 0; - dump.start_stack = regs->esp & ~(PAGE_SIZE - 1); -/* Flag indicating the math stuff is valid. */ - if (dump.u_fpvalid = current->used_math) { - if (last_task_used_math == current) - __asm__("clts ; fnsave %0"::"m" (dump.i387)); - else - memcpy(&dump.i387,¤t->tss.i387,sizeof(dump.i387)); - }; - DUMP_WRITE(&dump,sizeof(dump)); - DUMP_SEEK(sizeof(dump)); - /* Dump the task struct. Not be used by gdb, but could be useful */ - DUMP_WRITE(current,sizeof(*current)); -/* Now dump all of the user data. Include malloced stuff as well */ - DUMP_SEEK(PAGE_SIZE); -/* now we start writing out the user space info */ - __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x17)); -/* Dump the data area */ - if (dump.u_dsize != 0) { - dump_start = current->end_code; - dump_size = current->brk - current->end_code; - DUMP_WRITE(dump_start,dump_size); - }; -/* Now prepare to dump the stack area */ - if (dump.u_ssize != 0) { - dump_start = regs->esp & ~(PAGE_SIZE - 1); - dump_size = dump.u_ssize * PAGE_SIZE; - DUMP_WRITE(dump_start,dump_size); - }; -close_coredump: - if (file.f_op->release) - file.f_op->release(inode,&file); -end_coredump: - __asm__("mov %0,%%fs"::"r" (fs)); - iput(inode); - return has_dumped; -} - /* * Note that a shared library must be both readable and executable due to * security reasons. @@ -169,8 +51,6 @@ int sys_uselib(const char * library) struct inode * inode; struct buffer_head * bh; struct exec ex; - int i; - struct file * f; if (get_limit(0x17) != TASK_SIZE) return -EINVAL; @@ -182,20 +62,11 @@ int sys_uselib(const char * library) inode = NULL; if (!inode) return -ENOENT; - if (!S_ISREG(inode->i_mode) || !permission(inode,MAY_READ)) { + if (!S_ISREG(inode->i_mode) || !permission(inode,MAY_READ|MAY_EXEC)) { iput(inode); return -EACCES; } - if (inode->i_count > 1) { /* check for writers */ - f=0+file_table; - for (i=0 ; if_count && (f->f_mode & 2)) - if (inode == f->f_inode) { - iput(inode); - return -ETXTBSY; - } - } - if (!(bh = bread(inode->i_dev,bmap(inode,0)))) { + if (!(bh = bread(inode->i_dev,inode->i_data[0]))) { iput(inode); return -EACCES; } @@ -287,7 +158,7 @@ static int count(char ** argv) static unsigned long copy_strings(int argc,char ** argv,unsigned long *page, unsigned long p, int from_kmem) { - char *tmp, *pag = NULL; + char *tmp, *pag; int len, offset = 0; unsigned long old_fs, new_fs; @@ -358,32 +229,6 @@ static unsigned long change_ldt(unsigned long text_size,unsigned long * page) return data_limit; } -static void read_omagic(struct inode *inode, int bytes) -{ - struct buffer_head *bh; - int n, blkno, blk = 0; - char *dest = (char *) 0; - - while (bytes > 0) { - if (!(blkno = bmap(inode, blk))) - sys_exit(-1); - if (!(bh = bread(inode->i_dev, blkno))) - sys_exit(-1); - n = (blk ? BLOCK_SIZE : BLOCK_SIZE - sizeof(struct exec)); - if (bytes < n) - n = bytes; - - memcpy_tofs(dest, (blk ? bh->b_data : - bh->b_data + sizeof(struct exec)), n); - brelse(bh); - ++blk; - dest += n; - bytes -= n; - } - iput(inode); - current->executable = NULL; -} - /* * 'do_execve()' executes a new program. * @@ -403,7 +248,6 @@ int do_execve(unsigned long * eip,long tmp,char * filename, int sh_bang = 0; unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4; int ch; - struct file * f; if ((0xffff & eip[1]) != 0x000f) panic("execve called from supervisor mode"); @@ -411,15 +255,6 @@ int do_execve(unsigned long * eip,long tmp,char * filename, page[i]=0; if (!(inode=namei(filename))) /* get executables inode */ return -ENOENT; - if (inode->i_count > 1) { /* check for writers */ - f=0+file_table; - for (i=0 ; if_count && (f->f_mode & 2)) - if (inode == f->f_inode) { - retval = -ETXTBSY; - goto exec_error2; - } - } argc = count(argv); envc = count(envp); @@ -428,17 +263,7 @@ restart_interp: retval = -EACCES; goto exec_error2; } - if (IS_NOEXEC(inode)) { /* FS mustn't be mounted noexec */ - retval = -EPERM; - goto exec_error2; - } i = inode->i_mode; - if (IS_NOSUID(inode) && (((i & S_ISUID) && inode->i_uid != current-> - euid) || ((i & S_ISGID) && inode->i_gid != current->egid)) && - !suser()) { - retval = -EPERM; - goto exec_error2; - } /* make sure we don't let suid, sgid files be ptraced. */ if (current->flags & PF_PTRACED) { e_uid = current->euid; @@ -456,7 +281,7 @@ restart_interp: retval = -EACCES; goto exec_error2; } - if (!(bh = bread(inode->i_dev,bmap(inode,0)))) { + if (!(bh = bread(inode->i_dev,inode->i_data[0]))) { retval = -EACCES; goto exec_error2; } @@ -534,14 +359,13 @@ restart_interp: goto restart_interp; } brelse(bh); - if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC) || - ex.a_trsize || ex.a_drsize || + if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize || ex.a_drsize || ex.a_text+ex.a_data+ex.a_bss>0x3000000 || inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) { retval = -ENOEXEC; goto exec_error2; } - if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) != OMAGIC) { + if (N_TXTOFF(ex) != BLOCK_SIZE) { printk("%s: N_TXTOFF != BLOCK_SIZE. See a.out.h.", filename); retval = -ENOEXEC; goto exec_error2; @@ -555,7 +379,6 @@ restart_interp: } } /* OK, This is the point of no return */ - current->dumpable = 1; for (i=0; (ch = get_fs_byte(filename++)) != '\0';) if (ch == '/') i = 0; @@ -571,9 +394,6 @@ restart_interp: iput(current->libraries[i].library); current->libraries[i].library = NULL; } - if (e_uid != current->euid || e_gid != current->egid || - !permission(inode,MAY_READ)) - current->dumpable = 0; current->numlibraries = 0; current->executable = inode; current->signal = 0; @@ -602,12 +422,10 @@ restart_interp: current->rss = (LIBRARY_OFFSET - p + PAGE_SIZE-1) / PAGE_SIZE; current->suid = current->euid = e_uid; current->sgid = current->egid = e_gid; - if (N_MAGIC(ex) == OMAGIC) - read_omagic(inode, ex.a_text+ex.a_data); eip[0] = ex.a_entry; /* eip, magic happens :-) */ eip[3] = p; /* stack pointer */ if (current->flags & PF_PTRACED) - send_sig(SIGTRAP, current, 0); + send_sig(SIGTRAP, current, 0); return 0; exec_error2: iput(inode); diff --git a/fs/ext/Makefile b/fs/ext/Makefile deleted file mode 100644 index d498dda20504..000000000000 --- a/fs/ext/Makefile +++ /dev/null @@ -1,108 +0,0 @@ -# -# Makefile for the linux ext-filesystem routines. -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... - -.c.s: - $(CC) $(CFLAGS) -S $< -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< - -OBJS= bitmap.o freelists.o truncate.o namei.o inode.o \ - file.o dir.o symlink.o blkdev.o chrdev.o fifo.o - -ext.o: $(OBJS) - $(LD) -r -o ext.o $(OBJS) - -clean: - rm -f core *.o *.a tmp_make - for i in *.c;do rm -f `basename $$i .c`.s;done - -dep: - sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - for i in *.c;do $(CPP) -M $$i;done >> tmp_make - cp tmp_make Makefile - -### Dependencies: -bitmap.o : bitmap.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h -blkdev.o : blkdev.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \ - /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/errno.h -chrdev.o : chrdev.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \ - /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/errno.h -dir.o : dir.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/stat.h -fifo.o : fifo.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h -file.o : file.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/fcntl.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \ - /usr/src/linux/include/linux/stat.h -freelists.o : freelists.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h -inode.o : inode.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h -namei.o : namei.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \ - /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h \ - /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h /usr/src/linux/include/const.h -symlink.o : symlink.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/stat.h -truncate.o : truncate.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \ - /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/errno.h diff --git a/fs/ext/bitmap.c b/fs/ext/bitmap.c deleted file mode 100644 index f5bad9fbd268..000000000000 --- a/fs/ext/bitmap.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * linux/fs/ext/bitmap.c - * - * (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/bitmap.c - * - * (C) 1991 Linus Torvalds - */ - -/* bitmap.c contains the code that handles the inode and block bitmaps */ - - -#include -#include -#include -#include - -#ifdef EXTFS_BITMAP - -#define clear_block(addr) \ -__asm__("cld\n\t" \ - "rep\n\t" \ - "stosl" \ - ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di") - -#define set_bit(nr,addr) ({\ -char res; \ -__asm__ __volatile__("btsl %1,%2\n\tsetb %0": \ -"=q" (res):"r" (nr),"m" (*(addr))); \ -res;}) - -#define clear_bit(nr,addr) ({\ -char res; \ -__asm__ __volatile__("btrl %1,%2\n\tsetnb %0": \ -"=q" (res):"r" (nr),"m" (*(addr))); \ -res;}) - -#define find_first_zero(addr) ({ \ -int __res; \ -__asm__("cld\n" \ - "1:\tlodsl\n\t" \ - "notl %%eax\n\t" \ - "bsfl %%eax,%%edx\n\t" \ - "jne 2f\n\t" \ - "addl $32,%%ecx\n\t" \ - "cmpl $8192,%%ecx\n\t" \ - "jl 1b\n\t" \ - "xorl %%edx,%%edx\n" \ - "2:\taddl %%edx,%%ecx" \ - :"=c" (__res):"0" (0),"S" (addr):"ax","dx","si"); \ -__res;}) - -static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 }; - -static unsigned long count_used(struct buffer_head *map[], unsigned numblocks, - unsigned numbits) -{ - unsigned i, j, end, sum = 0; - struct buffer_head *bh; - - for (i=0; (i= (8*BLOCK_SIZE)) { - end = BLOCK_SIZE; - numbits -= 8*BLOCK_SIZE; - } else { - int tmp; - end = numbits >> 3; - numbits &= 0x7; - tmp = bh->b_data[end] & ((1<>4)&0xf]; - numbits = 0; - } - for (j=0; jb_data[j] & 0xf] - + nibblemap[(bh->b_data[j]>>4)&0xf]; - } - return(sum); -} - -int ext_free_block(int dev, int block) -{ - struct super_block * sb; - struct buffer_head * bh; - unsigned int bit,zone; - - if (!(sb = get_super(dev))) - panic("trying to free block on nonexistent device"); - if (block < sb->s_firstdatazone || block >= sb->s_nzones) - panic("trying to free block not in datazone"); - bh = get_hash_table(dev,block); - if (bh) { - if (bh->b_count > 1) { - brelse(bh); - return 0; - } - bh->b_dirt=0; - bh->b_uptodate=0; - if (bh->b_count) - brelse(bh); - } - zone = block - sb->s_firstdatazone + 1; - bit = zone & 8191; - zone >>= 13; - bh = sb->s_zmap[zone]; - if (clear_bit(bit,bh->b_data)) - printk("free_block (%04x:%d): bit already cleared\n",dev,block); - bh->b_dirt = 1; - return 1; -} - -int ext_new_block(int dev) -{ - struct buffer_head * bh; - struct super_block * sb; - int i,j; - - if (!(sb = get_super(dev))) - panic("trying to get new block from nonexistant device"); - j = 8192; - for (i=0 ; i<8 ; i++) - if (bh=sb->s_zmap[i]) - if ((j=find_first_zero(bh->b_data))<8192) - break; - if (i>=8 || !bh || j>=8192) - return 0; - if (set_bit(j,bh->b_data)) - panic("new_block: bit already set"); - bh->b_dirt = 1; - j += i*8192 + sb->s_firstdatazone-1; - if (j >= sb->s_nzones) - return 0; - if (!(bh=getblk(dev,j))) - panic("new_block: cannot get block"); - if (bh->b_count != 1) - panic("new block: count is != 1"); - clear_block(bh->b_data); - bh->b_uptodate = 1; - bh->b_dirt = 1; - brelse(bh); -#ifdef EXTFS_DEBUG -printk("ext_new_block: allocating block %d\n", j); -#endif - return j; -} - -unsigned long ext_count_free_blocks(struct super_block *sb) -{ - return (sb->s_nzones - count_used(sb->s_zmap,sb->s_zmap_blocks,sb->s_nzones)) - << sb->s_log_zone_size; -} - -void ext_free_inode(struct inode * inode) -{ - struct buffer_head * bh; - - if (!inode) - return; - if (!inode->i_dev) { - memset(inode,0,sizeof(*inode)); - return; - } - if (inode->i_count>1) { - printk("free_inode: inode has count=%d\n",inode->i_count); - return; - } - if (inode->i_nlink) { - printk("free_inode: inode has nlink=%d\n",inode->i_nlink); - return; - } - if (!inode->i_sb) { - printk("free_inode: inode on nonexistent device\n"); - return; - } - if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) { - printk("free_inode: inode 0 or nonexistent inode\n"); - return; - } - if (!(bh=inode->i_sb->s_imap[inode->i_ino>>13])) { - printk("free_inode: nonexistent imap in superblock\n"); - return; - } - if (clear_bit(inode->i_ino&8191,bh->b_data)) - printk("free_inode: bit already cleared.\n\r"); - bh->b_dirt = 1; - memset(inode,0,sizeof(*inode)); -} - -struct inode * ext_new_inode(int dev) -{ - struct inode * inode; - struct buffer_head * bh; - int i,j; - - if (!(inode=get_empty_inode())) - return NULL; - if (!(inode->i_sb = get_super(dev))) { - printk("new_inode: unknown device\n"); - iput(inode); - return NULL; - } - inode->i_flags = inode->i_sb->s_flags; - j = 8192; - for (i=0 ; i<8 ; i++) - if (bh=inode->i_sb->s_imap[i]) - if ((j=find_first_zero(bh->b_data))<8192) - break; - if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->s_ninodes) { - iput(inode); - return NULL; - } - if (set_bit(j,bh->b_data)) { /* shouldn't happen */ - printk("new_inode: bit already set"); - iput(inode); - return NULL; - } - bh->b_dirt = 1; - inode->i_count = 1; - inode->i_nlink = 1; - inode->i_dev = dev; - inode->i_uid = current->euid; - inode->i_gid = current->egid; - inode->i_dirt = 1; - inode->i_ino = j + i*8192; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - inode->i_op = NULL; -#ifdef EXTFS_DEBUG - printk("ext_new_inode : allocating inode %d\n", inode->i_ino); -#endif - return inode; -} - -unsigned long ext_count_free_inodes(struct super_block *sb) -{ - return sb->s_ninodes - count_used(sb->s_imap,sb->s_imap_blocks,sb->s_ninodes); -} - -#endif diff --git a/fs/ext/blkdev.c b/fs/ext/blkdev.c deleted file mode 100644 index 99312762cef9..000000000000 --- a/fs/ext/blkdev.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * linux/fs/ext/blkdev.c - * - * (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/blkdev.c - * - * (C) 1991 Linus Torvalds - */ - -#include -#include -#include -#include -#include - -#include - -/* - * Called every time an ext block special file is opened - */ -static int blkdev_open(struct inode * inode, struct file * filp) -{ - int i; - - i = MAJOR(inode->i_rdev); - if (i < MAX_BLKDEV) { - filp->f_op = blkdev_fops[i]; - if (filp->f_op && filp->f_op->open) - return filp->f_op->open(inode,filp); - } - return 0; -} - -/* - * Dummy default file-operations: the only thing this does - * is contain the open that then fills in the correct operations - * depending on the special file... - */ -static struct file_operations def_blk_fops = { - NULL, /* lseek */ - NULL, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - blkdev_open, /* open */ - NULL, /* release */ -}; - -struct inode_operations ext_blkdev_inode_operations = { - &def_blk_fops, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - ext_bmap, /* bmap */ - ext_truncate /* truncate */ -}; diff --git a/fs/ext/chrdev.c b/fs/ext/chrdev.c deleted file mode 100644 index 537972ed4490..000000000000 --- a/fs/ext/chrdev.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * linux/fs/ext/chrdev.c - * - * (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/chrdev.c - * - * (C) 1991 Linus Torvalds - */ - -#include -#include -#include -#include -#include - -#include - -/* - * Called every time an ext character special file is opened - */ -static int chrdev_open(struct inode * inode, struct file * filp) -{ - int i; - - i = MAJOR(inode->i_rdev); - if (i < MAX_CHRDEV) { - filp->f_op = chrdev_fops[i]; - if (filp->f_op && filp->f_op->open) - return filp->f_op->open(inode,filp); - } - return 0; -} - -/* - * Dummy default file-operations: the only thing this does - * is contain the open that then fills in the correct operations - * depending on the special file... - */ -static struct file_operations def_chr_fops = { - NULL, /* lseek */ - NULL, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - chrdev_open, /* open */ - NULL, /* release */ -}; - -struct inode_operations ext_chrdev_inode_operations = { - &def_chr_fops, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - ext_bmap, /* bmap */ - ext_truncate /* truncate */ -}; - diff --git a/fs/ext/dir.c b/fs/ext/dir.c deleted file mode 100644 index 730d5a1a6672..000000000000 --- a/fs/ext/dir.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * linux/fs/ext/dir.c - * - * (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/dir.c - * - * (C) 1991 Linus Torvalds - * - * ext directory handling functions - */ - -#include - -#include - -#include -#include -#include - -static int ext_readdir(struct inode *, struct file *, struct dirent *, int); - -static struct file_operations ext_dir_operations = { - NULL, /* lseek - default */ - NULL, /* read */ - NULL, /* write - bad */ - ext_readdir, /* readdir */ - NULL, /* select - default */ - NULL, /* ioctl - default */ - NULL, /* no special open code */ - NULL /* no special release code */ -}; - -/* - * directories can handle most operations... - */ -struct inode_operations ext_dir_inode_operations = { - &ext_dir_operations, /* default directory file-ops */ - ext_create, /* create */ - ext_lookup, /* lookup */ - ext_link, /* link */ - ext_unlink, /* unlink */ - ext_symlink, /* symlink */ - ext_mkdir, /* mkdir */ - ext_rmdir, /* rmdir */ - ext_mknod, /* mknod */ - ext_rename, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - ext_bmap, /* bmap */ - ext_truncate /* truncate */ -}; - -static int ext_readdir(struct inode * inode, struct file * filp, - struct dirent * dirent, int count) -{ - unsigned int block,offset,i; - char c; - struct buffer_head * bh; - struct ext_dir_entry * de; - - if (!inode || !S_ISDIR(inode->i_mode)) - return -EBADF; -/* if (filp->f_pos & (sizeof (struct ext_dir_entry) - 1)) - return -EBADF; */ - while (filp->f_pos < inode->i_size) { - offset = filp->f_pos & 1023; - block = ext_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS); - if (!block || !(bh = bread(inode->i_dev,block))) { - filp->f_pos += 1024-offset; - continue; - } - de = (struct ext_dir_entry *) (offset + bh->b_data); - while (offset < 1024 && filp->f_pos < inode->i_size) { - offset += de->rec_len; - filp->f_pos += de->rec_len; - if (de->inode) { - for (i = 0; i < de->name_len; i++) - if (c = de->name[i]) - put_fs_byte(c,i+dirent->d_name); - else - break; - if (i) { - put_fs_long(de->inode,&dirent->d_ino); - put_fs_byte(0,i+dirent->d_name); - put_fs_word(i,&dirent->d_reclen); - brelse(bh); - return i; - } - } -/* de++; */ - de = (struct ext_dir_entry *) ((char *) de + de->rec_len); - } - brelse(bh); - } - return 0; -} diff --git a/fs/ext/fifo.c b/fs/ext/fifo.c deleted file mode 100644 index c094393b453e..000000000000 --- a/fs/ext/fifo.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * linux/fs/fifo.c - * - * written by Paul H. Hargrove. - */ - -#include -#include - -extern struct file_operations def_fifo_fops; - -struct inode_operations ext_fifo_inode_operations = { - &def_fifo_fops, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* bmap */ - NULL /* truncate */ -}; diff --git a/fs/ext/file.c b/fs/ext/file.c deleted file mode 100644 index 3fe77d3fd106..000000000000 --- a/fs/ext/file.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * linux/fs/ext/file.c - * - * (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/file.c - * - * (C) 1991 Linus Torvalds - * - * ext regular file handling primitives - */ - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#define NBUF 16 - -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - -#include -#include - -static int ext_file_read(struct inode *, struct file *, char *, int); -static int ext_file_write(struct inode *, struct file *, char *, int); - -/* - * We have mostly NULL's here: the current defaults are ok for - * the ext filesystem. - */ -static struct file_operations ext_file_operations = { - NULL, /* lseek - default */ - ext_file_read, /* read */ - ext_file_write, /* write */ - NULL, /* readdir - bad */ - NULL, /* select - default */ - NULL, /* ioctl - default */ - NULL, /* no special open is needed */ - NULL /* release */ -}; - -struct inode_operations ext_file_inode_operations = { - &ext_file_operations, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - ext_bmap, /* bmap */ - ext_truncate /* truncate */ -}; - -static inline void wait_on_buffer(struct buffer_head * bh) -{ - cli(); - while (bh->b_lock) - sleep_on(&bh->b_wait); - sti(); -} - -static int ext_file_read(struct inode * inode, struct file * filp, char * buf, int count) -{ - int read,left,chars,nr; - int block, blocks, offset; - struct buffer_head ** bhb, ** bhe; - struct buffer_head * buflist[NBUF]; - - if (!inode) { - printk("ext_file_read: inode = NULL\n"); - return -EINVAL; - } - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) { - printk("ext_file_read: mode = %07o\n",inode->i_mode); - return -EINVAL; - } - if (filp->f_pos > inode->i_size) - left = 0; - else - left = inode->i_size - filp->f_pos; - if (left > count) - left = count; - if (left <= 0) - return 0; - read = 0; - block = filp->f_pos >> BLOCK_SIZE_BITS; - offset = filp->f_pos & (BLOCK_SIZE-1); - blocks = (left + offset + BLOCK_SIZE - 1) / BLOCK_SIZE; - bhb = bhe = buflist; - do { - if (blocks) { - --blocks; - if (nr = ext_bmap(inode,block++)) { - *bhb = getblk(inode->i_dev,nr); - if (!(*bhb)->b_uptodate) - ll_rw_block(READ,*bhb); - } else - *bhb = NULL; - - if (++bhb == &buflist[NBUF]) - bhb = buflist; - - if (bhb != bhe) - continue; - } - if (*bhe) { - wait_on_buffer(*bhe); - if (!(*bhe)->b_uptodate) { - do { - brelse(*bhe); - if (++bhe == &buflist[NBUF]) - bhe = buflist; - } while (bhe != bhb); - break; - } - } - - if (left < BLOCK_SIZE - offset) - chars = left; - else - chars = BLOCK_SIZE - offset; - filp->f_pos += chars; - left -= chars; - read += chars; - if (*bhe) { - memcpy_tofs(buf,offset+(*bhe)->b_data,chars); - brelse(*bhe); - buf += chars; - } else { - while (chars-->0) - put_fs_byte(0,buf++); - } - offset = 0; - if (++bhe == &buflist[NBUF]) - bhe = buflist; - } while (left > 0); - if (!read) - return -EIO; - if (!IS_RDONLY(inode)) { - inode->i_atime = CURRENT_TIME; - inode->i_dirt = 1; - } - return read; -} - -static int ext_file_write(struct inode * inode, struct file * filp, char * buf, int count) -{ - off_t pos; - int written,block,c; - struct buffer_head * bh; - char * p; - - if (!inode) { - printk("ext_file_write: inode = NULL\n"); - return -EINVAL; - } - if (!S_ISREG(inode->i_mode)) { - printk("ext_file_write: mode = %07o\n",inode->i_mode); - return -EINVAL; - } -/* - * ok, append may not work when many processes are writing at the same time - * but so what. That way leads to madness anyway. - */ - if (filp->f_flags & O_APPEND) - pos = inode->i_size; - else - pos = filp->f_pos; - written = 0; - while (written count-written) - c = count-written; - if (c == BLOCK_SIZE) - bh = getblk(inode->i_dev, block); - else - bh = bread(inode->i_dev,block); - if (!bh) { - if (!written) - written = -EIO; - break; - } - p = (pos % BLOCK_SIZE) + bh->b_data; - pos += c; - if (pos > inode->i_size) { - inode->i_size = pos; - inode->i_dirt = 1; - } - written += c; - memcpy_fromfs(p,buf,c); - buf += c; - bh->b_uptodate = 1; - bh->b_dirt = 1; - brelse(bh); - } - inode->i_mtime = CURRENT_TIME; - inode->i_ctime = CURRENT_TIME; - filp->f_pos = pos; - inode->i_dirt = 1; - return written; -} diff --git a/fs/ext/freelists.c b/fs/ext/freelists.c deleted file mode 100644 index 118fe098a400..000000000000 --- a/fs/ext/freelists.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * linux/fs/ext/freelists.c - * - * (C) 1992 Remy Card (card@masi.ibp.fr) - * - */ - -/* freelists.c contains the code that handles the inode and block free lists */ - - -/* - - The free blocks are managed by a linked list. The super block contains the - number of the first free block. This block contains 254 numbers of other - free blocks and the number of the next block in the list. - - When an ext fs is mounted, the number of the first free block is stored - in s->s_zmap[0] and the block header is stored in s->s_zmap[1]. s_zmap[2] - contains the count of free blocks. - - Currently, it is a hack to allow this kind of management with the super_block - structure. - Perhaps, in the future, we may have to change the super_block structure to - include dedicated fields. - - The free inodes are also managed by a linked list in a similar way. The - super block contains the number of the first free inode. This inode contains - 14 numbers of other free inodes and the number of the next inode in the list. - - The number of the first free inode is stored in s->s_imap[0] and the header - of the block containing the inode is stored in s->s_imap[1]. s_imap[2] contains - the count of free inodes. - -*/ - -#include - -#include -#include -#include - -#ifdef EXTFS_FREELIST - -#define clear_block(addr) \ -__asm__("cld\n\t" \ - "rep\n\t" \ - "stosl" \ - ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di") - -int ext_free_block(int dev, int block) -{ - struct super_block * sb; - struct buffer_head * bh; - struct ext_free_block * efb; - - if (!(sb = get_super(dev))) - panic("trying to free block on nonexistent device"); - lock_super (sb); - if (block < sb->s_firstdatazone || block >= sb->s_nzones) - panic("trying to free block not in datazone"); - bh = get_hash_table(dev,block); - if (bh) { - if (bh->b_count > 1) { - brelse(bh); - free_super (sb); - return 0; - } - bh->b_dirt=0; - bh->b_uptodate=0; - if (bh->b_count) - brelse(bh); - } - if (sb->s_zmap[1]) - efb = (struct ext_free_block *) sb->s_zmap[1]->b_data; - if (!sb->s_zmap[1] || efb->count == 254) { -#ifdef EXTFS_DEBUG -printk("ext_free_block: block full, skipping to %d\n", block); -#endif - if (sb->s_zmap[1]) - brelse (sb->s_zmap[1]); - if (!(sb->s_zmap[1] = bread (dev, block))) - panic ("ext_free_block: unable to read block to free\n"); - efb = (struct ext_free_block *) sb->s_zmap[1]->b_data; - efb->next = (unsigned long) sb->s_zmap[0]; - efb->count = 0; - sb->s_zmap[0] = (struct buffer_head *) block; - } else { - efb->free[efb->count++] = block; - } - sb->s_zmap[2] = (struct buffer_head *) (((unsigned long) sb->s_zmap[2]) + 1); - sb->s_dirt = 1; - sb->s_zmap[1]->b_dirt = 1; - free_super (sb); - return 1; -} - -int ext_new_block(int dev) -{ - struct buffer_head * bh; - struct super_block * sb; - struct ext_free_block * efb; - int /* i, */ j; - - if (!(sb = get_super(dev))) - panic("trying to get new block from nonexistant device"); - if (!sb->s_zmap[1]) - return 0; - lock_super (sb); - efb = (struct ext_free_block *) sb->s_zmap[1]->b_data; - if (efb->count) { - j = efb->free[--efb->count]; - sb->s_zmap[1]->b_dirt = 1; - } else { -#ifdef EXTFS_DEBUG -printk("ext_new_block: block empty, skipping to %d\n", efb->next); -#endif - j = (unsigned long) sb->s_zmap[0]; - sb->s_zmap[0] = (struct buffer_head *) efb->next; - brelse (sb->s_zmap[1]); - if (!sb->s_zmap[0]) { - sb->s_zmap[1] = NULL; - } else { - if (!(sb->s_zmap[1] = bread (dev, (unsigned long) sb->s_zmap[0]))) - panic ("ext_new_block: unable to read next free block\n"); - } - } - if (j < sb->s_firstdatazone || j > sb->s_nzones) { - printk ("ext_new_block: blk = %d\n", j); - panic ("allocating block not in data zone\n"); - } - sb->s_zmap[2] = (struct buffer_head *) (((unsigned long) sb->s_zmap[2]) - 1); - sb->s_dirt = 1; - - if (!(bh=getblk(dev,j))) - panic("new_block: cannot get block"); - if (bh->b_count != 1) - panic("new block: count is != 1"); - clear_block(bh->b_data); - bh->b_uptodate = 1; - bh->b_dirt = 1; - brelse(bh); -#ifdef EXTFS_DEBUG -printk("ext_new_block: allocating block %d\n", j); -#endif - free_super (sb); - return j; -} - -unsigned long ext_count_free_blocks(struct super_block *sb) -{ -#ifdef EXTFS_DEBUG - struct buffer_head * bh; - struct ext_free_block * efb; - unsigned long count, block; - - lock_super (sb); - if (!sb->s_zmap[1]) - count = 0; - else { - efb = (struct ext_free_block *) sb->s_zmap[1]->b_data; - count = efb->count + 1; - block = efb->next; - while (block) { - if (!(bh = bread (sb->s_dev, block))) { - printk ("ext_count_free: error while reading free blocks list\n"); - block = 0; - } else { - efb = (struct ext_free_block *) bh->b_data; - count += efb->count + 1; - block = efb->next; - brelse (bh); - } - } - } -printk("ext_count_free_blocks: stored = %d, computed = %d\n", - (unsigned long) sb->s_zmap[2], count); - free_super (sb); - return count; -#else - return (unsigned long) sb->s_zmap[2]; -#endif -} - -void ext_free_inode(struct inode * inode) -{ - struct buffer_head * bh; - struct ext_free_inode * efi; - unsigned long block; - - if (!inode) - return; - if (!inode->i_dev) { - memset(inode,0,sizeof(*inode)); - return; - } - if (inode->i_count>1) { - printk("free_inode: inode has count=%d\n",inode->i_count); - return; - } - if (inode->i_nlink) { - printk("free_inode: inode has nlink=%d\n",inode->i_nlink); - return; - } - if (!inode->i_sb) { - printk("free_inode: inode on nonexistent device\n"); - return; - } - lock_super (inode->i_sb); - if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) { - printk("free_inode: inode 0 or nonexistent inode\n"); - free_super (inode->i_sb); - return; - } - if (inode->i_sb->s_imap[1]) - efi = ((struct ext_free_inode *) inode->i_sb->s_imap[1]->b_data) + - (((unsigned long) inode->i_sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK; - if (!inode->i_sb->s_imap[1] || efi->count == 14) { -#ifdef EXTFS_DEBUG -printk("ext_free_inode: inode full, skipping to %d\n", inode->i_ino); -#endif - if (inode->i_sb->s_imap[1]) - brelse (inode->i_sb->s_imap[1]); - block = 2 + (inode->i_ino - 1) / EXT_INODES_PER_BLOCK; - if (!(bh = bread(inode->i_dev, block))) - panic("ext_free_inode: unable to read inode block\n"); - efi = ((struct ext_free_inode *) bh->b_data) + - (inode->i_ino - 1) % EXT_INODES_PER_BLOCK; - efi->next = (unsigned long) inode->i_sb->s_imap[0]; - efi->count = 0; - inode->i_sb->s_imap[0] = (struct buffer_head *) inode->i_ino; - inode->i_sb->s_imap[1] = bh; - } else { - efi->free[efi->count++] = inode->i_ino; - } - inode->i_sb->s_imap[2] = (struct buffer_head *) (((unsigned long) inode->i_sb->s_imap[2]) + 1); - inode->i_sb->s_dirt = 1; - inode->i_sb->s_imap[1]->b_dirt = 1; - free_super (inode->i_sb); - memset(inode,0,sizeof(*inode)); -} - -struct inode * ext_new_inode(int dev) -{ - struct inode * inode; - struct ext_free_inode * efi; - unsigned long block; - int /* i, */ j; - - if (!(inode=get_empty_inode())) - return NULL; - if (!(inode->i_sb = get_super(dev))) { - printk("new_inode: unknown device\n"); - iput(inode); - return NULL; - } - inode->i_flags = inode->i_sb->s_flags; - if (!inode->i_sb->s_imap[1]) - return 0; - lock_super (inode->i_sb); - efi = ((struct ext_free_inode *) inode->i_sb->s_imap[1]->b_data) + - (((unsigned long) inode->i_sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK; - if (efi->count) { - j = efi->free[--efi->count]; - inode->i_sb->s_imap[1]->b_dirt = 1; - } else { -#ifdef EXTFS_DEBUG -printk("ext_free_inode: inode empty, skipping to %d\n", efi->next); -#endif - j = (unsigned long) inode->i_sb->s_imap[0]; - if (efi->next < 1 || efi->next > inode->i_sb->s_ninodes) { - printk ("efi->next = %d\n", efi->next); - panic ("ext_new_inode: bad inode number in free list\n"); - } - inode->i_sb->s_imap[0] = (struct buffer_head *) efi->next; - block = 2 + (((unsigned long) efi->next) - 1) / EXT_INODES_PER_BLOCK; - brelse (inode->i_sb->s_imap[1]); - if (!inode->i_sb->s_imap[0]) { - inode->i_sb->s_imap[1] = NULL; - } else { - if (!(inode->i_sb->s_imap[1] = bread (dev, block))) - panic ("ext_new_inode: unable to read next free inode block\n"); - } - } - inode->i_sb->s_imap[2] = (struct buffer_head *) (((unsigned long) inode->i_sb->s_imap[2]) - 1); - inode->i_sb->s_dirt = 1; - inode->i_count = 1; - inode->i_nlink = 1; - inode->i_dev = dev; - inode->i_uid = current->euid; - inode->i_gid = current->egid; - inode->i_dirt = 1; - inode->i_ino = j; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - inode->i_op = NULL; -#ifdef EXTFS_DEBUG -printk("ext_new_inode : allocating inode %d\n", inode->i_ino); -#endif - free_super (inode->i_sb); - return inode; -} - -unsigned long ext_count_free_inodes(struct super_block *sb) -{ -#ifdef EXTFS_DEBUG - struct buffer_head * bh; - struct ext_free_inode * efi; - unsigned long count, block, ino; - - lock_super (sb); - if (!sb->s_imap[1]) - count = 0; - else { - efi = ((struct ext_free_inode *) sb->s_imap[1]->b_data) + - ((((unsigned long) sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK); - count = efi->count + 1; - ino = efi->next; - while (ino) { - if (ino < 1 || ino > sb->s_ninodes) { - printk ("s_imap[0] = %d, ino = %d\n", - (int) sb->s_imap[0],ino); - panic ("ext_count_fre_inodes: bad inode number in free list\n"); - } - block = 2 + ((ino - 1) / EXT_INODES_PER_BLOCK); - if (!(bh = bread (sb->s_dev, block))) { - printk ("ext_count_free_inodes: error while reading free inodes list\n"); - block = 0; - } else { - efi = ((struct ext_free_inode *) bh->b_data) + - ((ino - 1) % EXT_INODES_PER_BLOCK); - count += efi->count + 1; - ino = efi->next; - brelse (bh); - } - } - } -printk("ext_count_free_inodes: stored = %d, computed = %d\n", - (unsigned long) sb->s_imap[2], count); - free_super (sb); - return count; -#else - return (unsigned long) sb->s_imap[2]; -#endif -} - -#endif diff --git a/fs/ext/inode.c b/fs/ext/inode.c deleted file mode 100644 index 807f883e535b..000000000000 --- a/fs/ext/inode.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * linux/fs/ext/inode.c - * - * (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/inode.c - * - * (C) 1991 Linus Torvalds - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -int sync_dev(int dev); - -void ext_put_inode(struct inode *inode) -{ - inode->i_size = 0; - ext_truncate(inode); - ext_free_inode(inode); -} - -void ext_put_super(struct super_block *sb) -{ -#ifdef EXTFS_BITMAP - int i; -#endif - - lock_super(sb); - sb->s_dev = 0; -#ifdef EXTFS_BITMAP - for(i = 0 ; i < EXT_I_MAP_SLOTS ; i++) - brelse(sb->s_imap[i]); - for(i = 0 ; i < EXT_Z_MAP_SLOTS ; i++) - brelse(sb->s_zmap[i]); -#endif -#ifdef EXTFS_FREELIST - if (sb->s_imap[1]) - brelse (sb->s_imap[1]); - if (sb->s_zmap[1]) - brelse (sb->s_zmap[1]); -#endif - free_super(sb); - return; -} - -static struct super_operations ext_sops = { - ext_read_inode, - ext_write_inode, - ext_put_inode, - ext_put_super, - ext_write_super, - ext_statfs -}; - -struct super_block *ext_read_super(struct super_block *s,void *data) -{ - struct buffer_head *bh; - struct ext_super_block *es; - int dev=s->s_dev,block; -#ifdef EXTFS_BITMAP - int i; -#endif - - lock_super(s); - if (!(bh = bread(dev,1))) { - s->s_dev=0; - free_super(s); - printk("bread failed\n"); - return NULL; - } -/* *((struct ext_super_block *) s) = - *((struct ext_super_block *) bh->b_data); */ - es = (struct ext_super_block *) bh->b_data; - s->s_ninodes = es->s_ninodes; - s->s_nzones = es->s_nzones; -#ifdef EXTFS_BITMAP - s->s_imap_blocks = es->s_imap_blocks; - s->s_zmap_blocks = es->s_zmap_blocks; -#endif - s->s_firstdatazone = es->s_firstdatazone; - s->s_log_zone_size = es->s_log_zone_size; - s->s_max_size = es->s_max_size; - s->s_magic = es->s_magic; -#ifdef EXTFS_FREELIST - s->s_zmap[0] = (struct buffer_head *) es->s_firstfreeblock; - s->s_zmap[2] = (struct buffer_head *) es->s_freeblockscount; - s->s_imap[0] = (struct buffer_head *) es->s_firstfreeinode; - s->s_imap[2] = (struct buffer_head *) es->s_freeinodescount; -#endif - brelse(bh); - if (s->s_magic != EXT_SUPER_MAGIC) { - s->s_dev = 0; - free_super(s); - printk("magic match failed\n"); - return NULL; - } -#ifdef EXTFS_BITMAP - for (i=0;i < EXT_I_MAP_SLOTS;i++) - s->s_imap[i] = NULL; - for (i=0;i < EXT_Z_MAP_SLOTS;i++) - s->s_zmap[i] = NULL; - block=2; - for (i=0 ; i < s->s_imap_blocks ; i++) - if (s->s_imap[i]=bread(dev,block)) - block++; - else - break; - for (i=0 ; i < s->s_zmap_blocks ; i++) - if (s->s_zmap[i]=bread(dev,block)) - block++; - else - break; - if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) { - for(i=0;is_imap[i]); - for(i=0;is_zmap[i]); - s->s_dev=0; - free_super(s); - printk("block failed\n"); - return NULL; - } - s->s_imap[0]->b_data[0] |= 1; - s->s_zmap[0]->b_data[0] |= 1; -#endif -#ifdef EXTFS_FREELIST - if (!s->s_zmap[0]) - s->s_zmap[1] = NULL; - else - if (!(s->s_zmap[1] = bread (dev, (unsigned long) s->s_zmap[0]))) { - printk ("ext_read_super: unable to read first free block\n"); - s->s_dev = 0; - free_super(s); - return NULL; - } - if (!s->s_imap[0]) - s->s_imap[1] = NULL; - else { - block = 2 + (((unsigned long) s->s_imap[0]) - 1) / EXT_INODES_PER_BLOCK; - if (!(s->s_imap[1] = bread (dev, block))) { - printk ("ext_read_super: unable to read first free inode block\n"); - brelse(s->s_zmap[1]); - s->s_dev = 0; - free_super (s); - return NULL; - } - } -#endif - - free_super(s); - /* set up enough so that it can read an inode */ - s->s_dev = dev; - s->s_op = &ext_sops; - if (!(s->s_mounted = iget(dev,EXT_ROOT_INO))) { - s->s_dev=0; - printk("get root inode failed\n"); - return NULL; - } - return s; -} - -void ext_write_super (struct super_block *sb) -{ -#ifdef EXTFS_FREELIST - struct buffer_head * bh; - struct ext_super_block * es; - -#ifdef EXTFS_DEBUG - printk ("ext_write_super called\n"); -#endif - if (!(bh = bread (sb->s_dev, 1))) { - printk ("ext_write_super: bread failed\n"); - return; - } - es = (struct ext_super_block *) bh->b_data; - es->s_firstfreeblock = (unsigned long) sb->s_zmap[0]; - es->s_freeblockscount = (unsigned long) sb->s_zmap[2]; - es->s_firstfreeinode = (unsigned long) sb->s_imap[0]; - es->s_freeinodescount = (unsigned long) sb->s_imap[2]; - bh->b_dirt = 1; - brelse (bh); - sb->s_dirt = 0; -#endif -} - -void ext_statfs (struct super_block *sb, struct statfs *buf) -{ - long tmp; - - put_fs_long(EXT_SUPER_MAGIC, &buf->f_type); - put_fs_long(1024, &buf->f_bsize); - put_fs_long(sb->s_nzones << sb->s_log_zone_size, &buf->f_blocks); - tmp = ext_count_free_blocks(sb); - put_fs_long(tmp, &buf->f_bfree); - put_fs_long(tmp, &buf->f_bavail); - put_fs_long(sb->s_ninodes, &buf->f_files); - put_fs_long(ext_count_free_inodes(sb), &buf->f_ffree); - /* Don't know what value to put in buf->f_fsid */ -} - -static int _ext_bmap(struct inode * inode,int block,int create) -{ - struct buffer_head * bh; - int i; - - if (block<0) { - printk("_ext_bmap: block<0"); - return 0; - } - if (block >= 9+256+256*256+256*256*256) { - printk("_ext_bmap: block>big"); - return 0; - } - if (block<9) { - if (create && !inode->i_data[block]) - if (inode->i_data[block]=ext_new_block(inode->i_dev)) { - inode->i_ctime=CURRENT_TIME; - inode->i_dirt=1; - } - return inode->i_data[block]; - } - block -= 9; - if (block<256) { - if (create && !inode->i_data[9]) - if (inode->i_data[9]=ext_new_block(inode->i_dev)) { - inode->i_dirt=1; - inode->i_ctime=CURRENT_TIME; - } - if (!inode->i_data[9]) - return 0; - if (!(bh = bread(inode->i_dev,inode->i_data[9]))) - return 0; - i = ((unsigned long *) (bh->b_data))[block]; - if (create && !i) - if (i=ext_new_block(inode->i_dev)) { - ((unsigned long *) (bh->b_data))[block]=i; - bh->b_dirt=1; - } - brelse(bh); - return i; - } - block -= 256; - if (block<256*256) { - if (create && !inode->i_data[10]) - if (inode->i_data[10]=ext_new_block(inode->i_dev)) { - inode->i_dirt=1; - inode->i_ctime=CURRENT_TIME; - } - if (!inode->i_data[10]) - return 0; - if (!(bh=bread(inode->i_dev,inode->i_data[10]))) - return 0; - i = ((unsigned long *)bh->b_data)[block>>8]; - if (create && !i) - if (i=ext_new_block(inode->i_dev)) { - ((unsigned long *) (bh->b_data))[block>>8]=i; - bh->b_dirt=1; - } - brelse(bh); - if (!i) - return 0; - if (!(bh=bread(inode->i_dev,i))) - return 0; - i = ((unsigned long *)bh->b_data)[block&255]; - if (create && !i) - if (i=ext_new_block(inode->i_dev)) { - ((unsigned long *) (bh->b_data))[block&255]=i; - bh->b_dirt=1; - } - brelse(bh); - return i; - } - printk("ext_bmap: triple indirection not yet implemented\n"); - return 0; -} - -int ext_bmap(struct inode * inode,int block) -{ - return _ext_bmap(inode,block,0); -} - -int ext_create_block(struct inode * inode, int block) -{ - return _ext_bmap(inode,block,1); -} - -void ext_read_inode(struct inode * inode) -{ - struct buffer_head * bh; - struct ext_inode * raw_inode; - int block; - -#ifdef EXTFS_BITMAP - block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks + - (inode->i_ino-1)/EXT_INODES_PER_BLOCK; -#endif -#ifdef EXTFS_FREELIST - block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK; -#endif - if (!(bh=bread(inode->i_dev,block))) - panic("unable to read i-node block"); - raw_inode = ((struct ext_inode *) bh->b_data) + - (inode->i_ino-1)%EXT_INODES_PER_BLOCK; - inode->i_mode = raw_inode->i_mode; - inode->i_uid = raw_inode->i_uid; - inode->i_gid = raw_inode->i_gid; - inode->i_nlink = raw_inode->i_nlinks; - inode->i_size = raw_inode->i_size; - inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time; - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - inode->i_rdev = raw_inode->i_zone[0]; - else for (block = 0; block < 12; block++) - inode->i_data[block] = raw_inode->i_zone[block]; - brelse(bh); - inode->i_op = NULL; - if (S_ISREG(inode->i_mode)) - inode->i_op = &ext_file_inode_operations; - else if (S_ISDIR(inode->i_mode)) - inode->i_op = &ext_dir_inode_operations; - else if (S_ISLNK(inode->i_mode)) - inode->i_op = &ext_symlink_inode_operations; - else if (S_ISCHR(inode->i_mode)) - inode->i_op = &ext_chrdev_inode_operations; - else if (S_ISBLK(inode->i_mode)) - inode->i_op = &ext_blkdev_inode_operations; - else if (S_ISFIFO(inode->i_mode)) { - inode->i_op = &ext_fifo_inode_operations; - inode->i_size = 0; - inode->i_pipe = 1; - PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; - PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; - } -} - -void ext_write_inode(struct inode * inode) -{ - struct buffer_head * bh; - struct ext_inode * raw_inode; - int block; - -#ifdef EXTFS_BITMAP - block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks + - (inode->i_ino-1)/EXT_INODES_PER_BLOCK; -#endif -#ifdef EXTFS_FREELIST - block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK; -#endif - if (!(bh=bread(inode->i_dev,block))) - panic("unable to read i-node block"); - raw_inode = ((struct ext_inode *)bh->b_data) + - (inode->i_ino-1)%EXT_INODES_PER_BLOCK; - raw_inode->i_mode = inode->i_mode; - raw_inode->i_uid = inode->i_uid; - raw_inode->i_gid = inode->i_gid; - raw_inode->i_nlinks = inode->i_nlink; - raw_inode->i_size = inode->i_size; - raw_inode->i_time = inode->i_mtime; - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - raw_inode->i_zone[0] = inode->i_rdev; - else for (block = 0; block < 12; block++) - raw_inode->i_zone[block] = inode->i_data[block]; - bh->b_dirt=1; - inode->i_dirt=0; - brelse(bh); -} diff --git a/fs/ext/namei.c b/fs/ext/namei.c deleted file mode 100644 index d4d44c44a03f..000000000000 --- a/fs/ext/namei.c +++ /dev/null @@ -1,900 +0,0 @@ -/* - * linux/fs/ext/namei.c - * - * (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/namei.c - * - * (C) 1991 Linus Torvalds - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* - * comment out this line if you want names > EXT_NAME_LEN chars to be - * truncated. Else they will be disallowed. - */ -/* #define NO_TRUNCATE */ - -/* - * EXT_DIR_PAD defines the directory entries boundaries - * - * NOTE: It must be a power of 2 and must be greater or equal than 8 - * because a directory entry needs 8 bytes for its fixed part - * (4 bytes for the inode, 2 bytes for the entry length and 2 bytes - * for the name length) - */ -#define EXT_DIR_PAD 8 - -/* - * - * EXT_DIR_MIN_SIZE is the minimal size of a directory entry - * - * During allocations, a directory entry is split into 2 ones - * *ONLY* if the size of the unused part is greater than or - * equal to EXT_DIR_MIN_SIZE - */ -#define EXT_DIR_MIN_SIZE 12 - -/* - * ok, we cannot use strncmp, as the name is not in our data space. - * Thus we'll have to use ext_match. No big problem. Match also makes - * some sanity tests. - * - * NOTE! unlike strncmp, ext_match returns 1 for success, 0 for failure. - */ -static int ext_match(int len,const char * name,struct ext_dir_entry * de) -{ - register int same __asm__("ax"); - - if (!de || !de->inode || len > EXT_NAME_LEN) - return 0; - /* "" means "." ---> so paths like "/usr/lib//libc.a" work */ - if (!len && (de->name[0]=='.') && (de->name[1]=='\0')) - return 1; -/* if (len < EXT_NAME_LEN && de->name[len]) - return 0; */ - if (len < EXT_NAME_LEN && len != de->name_len) - return 0; - __asm__("cld\n\t" - "fs ; repe ; cmpsb\n\t" - "setz %%al" - :"=a" (same) - :"0" (0),"S" ((long) name),"D" ((long) de->name),"c" (len) - :"cx","di","si"); - return same; -} - -/* - * ext_find_entry() - * - * finds an entry in the specified directory with the wanted name. It - * returns the cache buffer in which the entry was found, and the entry - * itself (as a parameter - res_dir). It does NOT read the inode of the - * entry - you'll have to do that yourself if you want to. - * - * addition for the ext file system : this function returns the previous - * and next directory entries in the parameters prev_dir and next_dir - */ -static struct buffer_head * ext_find_entry(struct inode * dir, - const char * name, int namelen, struct ext_dir_entry ** res_dir, - struct ext_dir_entry ** prev_dir, struct ext_dir_entry ** next_dir) -{ -/* int entries; */ - int block /* ,i */; - long offset; - struct buffer_head * bh; - struct ext_dir_entry * de; - - *res_dir = NULL; - if (!dir) - return NULL; -#ifdef NO_TRUNCATE - if (namelen > EXT_NAME_LEN) - return NULL; -#else - if (namelen > EXT_NAME_LEN) - namelen = EXT_NAME_LEN; -#endif -/* entries = dir->i_size / (sizeof (struct ext_dir_entry)); */ - if (!(block = dir->i_data[0])) - return NULL; - if (!(bh = bread(dir->i_dev,block))) - return NULL; - if (prev_dir) - *prev_dir = NULL; - if (next_dir) - *next_dir = NULL; -/* i = 0; */ - offset = 0; - de = (struct ext_dir_entry *) bh->b_data; - while (offset < dir->i_size) { - if ((char *)de >= BLOCK_SIZE+bh->b_data) { - brelse(bh); - bh = NULL; - if (!(block = ext_bmap(dir,offset>>BLOCK_SIZE_BITS)) || - !(bh = bread(dir->i_dev,block))) { -/* i += EXT_DIR_ENTRIES_PER_BLOCK; */ -/* offset += BLOCK_SIZE; */ - continue; - } - de = (struct ext_dir_entry *) bh->b_data; - if (prev_dir) - *prev_dir = NULL; - } - if (ext_match(namelen,name,de)) { - *res_dir = de; - if (next_dir) - if (offset + de->rec_len < dir->i_size) - *next_dir = (struct ext_dir_entry *) - ((char *) de + de->rec_len); - else - *next_dir = NULL; - return bh; - } - offset += de->rec_len; - if (prev_dir) - *prev_dir = de; - de = (struct ext_dir_entry *) ((char *) de + de->rec_len); -/* i++; */ - } - brelse(bh); - return NULL; -} - -int ext_lookup(struct inode * dir,const char * name, int len, - struct inode ** result) -{ - int ino; - struct ext_dir_entry * de; - struct buffer_head * bh; - - *result = NULL; - if (!dir) - return -ENOENT; - if (!S_ISDIR(dir->i_mode)) { - iput(dir); - return -ENOENT; - } - if (!(bh = ext_find_entry(dir,name,len,&de,NULL,NULL))) { - iput(dir); - return -ENOENT; - } - ino = de->inode; - brelse(bh); - if (!(*result = iget(dir->i_dev,ino))) { - iput(dir); - return -EACCES; - } - iput(dir); - return 0; -} - -/* - * ext_add_entry() - * - * adds a file entry to the specified directory, using the same - * semantics as ext_find_entry(). It returns NULL if it failed. - * - * NOTE!! The inode part of 'de' is left at 0 - which means you - * may not sleep between calling this and putting something into - * the entry, as someone else might have used it while you slept. - */ -static struct buffer_head * ext_add_entry(struct inode * dir, - const char * name, int namelen, struct ext_dir_entry ** res_dir) -{ - int block,i; - long offset; - unsigned short rec_len; - struct buffer_head * bh; - struct ext_dir_entry * de, * de1; - - *res_dir = NULL; - if (!dir) - return NULL; -#ifdef NO_TRUNCATE - if (namelen > EXT_NAME_LEN) - return NULL; -#else - if (namelen > EXT_NAME_LEN) - namelen = EXT_NAME_LEN; -#endif - if (!namelen) - return NULL; - if (!(block = dir->i_data[0])) - return NULL; - if (!(bh = bread(dir->i_dev,block))) - return NULL; - rec_len = ((8 + namelen + EXT_DIR_PAD - 1) / EXT_DIR_PAD) * EXT_DIR_PAD; -/* i = 0; */ - offset = 0; - de = (struct ext_dir_entry *) bh->b_data; - while (1) { - if ((char *)de >= BLOCK_SIZE+bh->b_data && offset < dir->i_size) { -#ifdef EXTFS_DEBUG -printk ("ext_add_entry: skipping to next block\n"); -#endif - brelse(bh); - bh = NULL; - block = ext_create_block(dir,offset>>BLOCK_SIZE_BITS); - if (!block) - return NULL; - if (!(bh = bread(dir->i_dev,block))) { -/* i += EXT_DIR_ENTRIES_PER_BLOCK; */ - offset += BLOCK_SIZE; - continue; - } - de = (struct ext_dir_entry *) bh->b_data; - } - if (offset >= dir->i_size) { - /* Check that the directory entry fits in the block */ - if (offset % BLOCK_SIZE == 0 - || (BLOCK_SIZE - (offset % BLOCK_SIZE)) < rec_len) { - if ((offset % BLOCK_SIZE) != 0) { - /* If the entry does not fit in the - block, the remainder of the block - becomes an unused entry */ - de->inode = 0; - de->rec_len = BLOCK_SIZE - - (offset & (BLOCK_SIZE - 1)); - de->name_len = 0; - offset += de->rec_len; - dir->i_size += de->rec_len; - dir->i_dirt = 1; - dir->i_ctime = CURRENT_TIME; - bh->b_dirt = 1; - } - brelse (bh); - bh = NULL; - block = ext_create_block (dir,offset>>BLOCK_SIZE_BITS); -#ifdef EXTFS_DEBUG -printk ("ext_add_entry : creating next block\n"); -#endif - if (!block) - return NULL; - if (!(bh = bread(dir->i_dev,block))) - return NULL; /* Other thing to do ??? */ - de = (struct ext_dir_entry *) bh->b_data; - } - /* Allocate the entry */ - de->inode=0; - de->rec_len = rec_len; -/* dir->i_size = (i+1)*sizeof(struct ext_dir_entry); */ - dir->i_size += de->rec_len; - dir->i_dirt = 1; - dir->i_ctime = CURRENT_TIME; - } - if (!de->inode && de->rec_len >= rec_len) { - if (de->rec_len > rec_len - && de->rec_len - rec_len >= EXT_DIR_MIN_SIZE) { - /* The found entry is too big : it is split - into 2 ones : - - the 1st one will be used to hold the name, - - the 2nd one is unused */ - de1 = (struct ext_dir_entry *) ((char *) de + rec_len); - de1->inode = 0; - de1->rec_len = de->rec_len - rec_len; - de1->name_len = 0; - de->rec_len = rec_len; - } - dir->i_mtime = CURRENT_TIME; - de->name_len = namelen; - for (i=0; i < namelen ; i++) - de->name[i]=/*(ib_dirt = 1; - *res_dir = de; - return bh; - } - offset += de->rec_len; - de = (struct ext_dir_entry *) ((char *) de + de->rec_len); - } - brelse(bh); - return NULL; -} - -int ext_create(struct inode * dir,const char * name, int len, int mode, - struct inode ** result) -{ - struct inode * inode; - struct buffer_head * bh; - struct ext_dir_entry * de; - - *result = NULL; - if (!dir) - return -ENOENT; - inode = ext_new_inode(dir->i_dev); - if (!inode) { - iput(dir); - return -ENOSPC; - } - inode->i_op = &ext_file_inode_operations; - inode->i_mode = mode; - inode->i_dirt = 1; - bh = ext_add_entry(dir,name,len,&de); - if (!bh) { - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - iput(dir); - return -ENOSPC; - } - de->inode = inode->i_ino; - bh->b_dirt = 1; - brelse(bh); - iput(dir); - *result = inode; - return 0; -} - -int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev) -{ - struct inode * inode; - struct buffer_head * bh; - struct ext_dir_entry * de; - - if (!dir) - return -ENOENT; - bh = ext_find_entry(dir,name,len,&de,NULL,NULL); - if (bh) { - brelse(bh); - iput(dir); - return -EEXIST; - } - inode = ext_new_inode(dir->i_dev); - if (!inode) { - iput(dir); - return -ENOSPC; - } - inode->i_uid = current->euid; - inode->i_mode = mode; - inode->i_op = NULL; - if (S_ISREG(inode->i_mode)) - inode->i_op = &ext_file_inode_operations; - else if (S_ISDIR(inode->i_mode)) - inode->i_op = &ext_dir_inode_operations; - else if (S_ISLNK(inode->i_mode)) - inode->i_op = &ext_symlink_inode_operations; - else if (S_ISCHR(inode->i_mode)) - inode->i_op = &ext_chrdev_inode_operations; - else if (S_ISBLK(inode->i_mode)) - inode->i_op = &ext_blkdev_inode_operations; - else if (S_ISFIFO(inode->i_mode)) { - inode->i_op = &ext_fifo_inode_operations; - inode->i_size = 0; - inode->i_pipe = 1; - PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; - PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; - } - if (S_ISBLK(mode) || S_ISCHR(mode)) - inode->i_rdev = rdev; - inode->i_mtime = inode->i_atime = CURRENT_TIME; - inode->i_dirt = 1; - bh = ext_add_entry(dir,name,len,&de); - if (!bh) { - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - iput(dir); - return -ENOSPC; - } - de->inode = inode->i_ino; - bh->b_dirt = 1; - brelse(bh); - iput(dir); - iput(inode); - return 0; -} - -int ext_mkdir(struct inode * dir, const char * name, int len, int mode) -{ - struct inode * inode; - struct buffer_head * bh, *dir_block; - struct ext_dir_entry * de; - - bh = ext_find_entry(dir,name,len,&de,NULL,NULL); - if (bh) { - brelse(bh); - iput(dir); - return -EEXIST; - } - inode = ext_new_inode(dir->i_dev); - if (!inode) { - iput(dir); - return -ENOSPC; - } - inode->i_op = &ext_dir_inode_operations; - inode->i_size = 2 * 16; /* Each entry is coded on 16 bytes for "." and ".." - - 4 bytes for the inode number, - - 2 bytes for the record length - - 2 bytes for the name length - - 8 bytes for the name */ - inode->i_mtime = inode->i_atime = CURRENT_TIME; - if (!(inode->i_data[0] = ext_new_block(inode->i_dev))) { - iput(dir); - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - return -ENOSPC; - } - inode->i_dirt = 1; - if (!(dir_block = bread(inode->i_dev,inode->i_data[0]))) { - iput(dir); - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - return -EIO; - } - de = (struct ext_dir_entry *) dir_block->b_data; - de->inode=inode->i_ino; - de->rec_len=16; - de->name_len=1; - strcpy(de->name,"."); -/* de++; */ - de = (struct ext_dir_entry *) ((char *) de + de->rec_len); - de->inode = dir->i_ino; - de->rec_len=16; - de->name_len=2; - strcpy(de->name,".."); - inode->i_nlink = 2; - dir_block->b_dirt = 1; - brelse(dir_block); - inode->i_mode = I_DIRECTORY | (mode & 0777 & ~current->umask); - inode->i_dirt = 1; - bh = ext_add_entry(dir,name,len,&de); - if (!bh) { - iput(dir); - inode->i_nlink=0; - iput(inode); - return -ENOSPC; - } - de->inode = inode->i_ino; - bh->b_dirt = 1; - dir->i_nlink++; - dir->i_dirt = 1; - iput(dir); - iput(inode); - brelse(bh); - return 0; -} - -/* - * routine to check that the specified directory is empty (for rmdir) - */ -static int empty_dir(struct inode * inode) -{ - int /* nr, */ block; -/* int len; */ - unsigned long offset; - struct buffer_head * bh; - struct ext_dir_entry * de, * de1; - -/* len = inode->i_size / sizeof (struct ext_dir_entry); */ - if (inode->i_size < 2 * 12 || !inode->i_data[0] || - !(bh=bread(inode->i_dev,inode->i_data[0]))) { - printk("warning - bad directory on dev %04x\n",inode->i_dev); - return 0; - } - de = (struct ext_dir_entry *) bh->b_data; - de1 = (struct ext_dir_entry *) ((char *) de + de->rec_len); - if (de->inode != inode->i_ino || !de1->inode || - strcmp(".",de->name) || strcmp("..",de1->name)) { - printk("warning - bad directory on dev %04x\n",inode->i_dev); - return 0; - } -/* nr = 2; */ - offset = de->rec_len + de1->rec_len; - de = (struct ext_dir_entry *) ((char *) de1 + de1->rec_len); - while (offset < inode->i_size ) { - if ((void *) de >= (void *) (bh->b_data+BLOCK_SIZE)) { - brelse(bh); - block = ext_bmap(inode, offset >> BLOCK_SIZE_BITS); - if (!block) { - offset += BLOCK_SIZE; - continue; - } - if (!(bh=bread(inode->i_dev,block))) - return 0; - de = (struct ext_dir_entry *) bh->b_data; - } - if (de->inode) { - brelse(bh); - return 0; - } - offset += de->rec_len; - de = (struct ext_dir_entry *) ((char *) de + de->rec_len); - } - brelse(bh); - return 1; -} - -static inline void ext_merge_entries (struct ext_dir_entry * de, - struct ext_dir_entry * pde, struct ext_dir_entry * nde) -{ - if (! nde->inode) - de->rec_len += nde->rec_len; - if (! pde->inode) - pde->rec_len += de->rec_len; -} - -int ext_rmdir(struct inode * dir, const char * name, int len) -{ - int retval; - struct inode * inode; - struct buffer_head * bh; - struct ext_dir_entry * de, * pde, * nde; - - inode = NULL; - bh = ext_find_entry(dir,name,len,&de,&pde,&nde); - retval = -ENOENT; - if (!bh) - goto end_rmdir; - retval = -EPERM; - if (!(inode = iget(dir->i_dev, de->inode))) - goto end_rmdir; - if ((dir->i_mode & S_ISVTX) && current->euid && - inode->i_uid != current->euid) - goto end_rmdir; - if (inode->i_dev != dir->i_dev) - goto end_rmdir; - if (inode == dir) /* we may not delete ".", but "../dir" is ok */ - goto end_rmdir; - if (!S_ISDIR(inode->i_mode)) { - retval = -ENOTDIR; - goto end_rmdir; - } - if (!empty_dir(inode)) { - retval = -ENOTEMPTY; - goto end_rmdir; - } - if (inode->i_count > 1) { - retval = -EBUSY; - goto end_rmdir; - } - if (inode->i_nlink != 2) - printk("empty directory has nlink!=2 (%d)\n",inode->i_nlink); - de->inode = 0; - de->name_len = 0; - ext_merge_entries (de, pde, nde); - bh->b_dirt = 1; - inode->i_nlink=0; - inode->i_dirt=1; - dir->i_nlink--; - dir->i_ctime = dir->i_mtime = CURRENT_TIME; - dir->i_dirt=1; - retval = 0; -end_rmdir: - iput(dir); - iput(inode); - brelse(bh); - return retval; -} - -int ext_unlink(struct inode * dir, const char * name, int len) -{ - int retval; - struct inode * inode; - struct buffer_head * bh; - struct ext_dir_entry * de, * pde, * nde; - - retval = -ENOENT; - inode = NULL; - bh = ext_find_entry(dir,name,len,&de,&pde,&nde); - if (!bh) - goto end_unlink; - if (!(inode = iget(dir->i_dev, de->inode))) - goto end_unlink; - retval = -EPERM; - if ((dir->i_mode & S_ISVTX) && !suser() && - current->euid != inode->i_uid && - current->euid != dir->i_uid) - goto end_unlink; - if (S_ISDIR(inode->i_mode)) - goto end_unlink; - if (!inode->i_nlink) { - printk("Deleting nonexistent file (%04x:%d), %d\n", - inode->i_dev,inode->i_ino,inode->i_nlink); - inode->i_nlink=1; - } - de->inode = 0; - de->name_len = 0; - ext_merge_entries (de, pde, nde); - bh->b_dirt = 1; - inode->i_nlink--; - inode->i_dirt = 1; - inode->i_ctime = CURRENT_TIME; - retval = 0; -end_unlink: - brelse(bh); - iput(inode); - iput(dir); - return retval; -} - -int ext_symlink(struct inode * dir, const char * name, int len, const char * symname) -{ - struct ext_dir_entry * de; - struct inode * inode = NULL; - struct buffer_head * bh = NULL, * name_block = NULL; - int i; - char c; - - if (!(inode = ext_new_inode(dir->i_dev))) { - iput(dir); - return -ENOSPC; - } - inode->i_mode = S_IFLNK | 0777; - inode->i_op = &ext_symlink_inode_operations; - if (!(inode->i_data[0] = ext_new_block(inode->i_dev))) { - iput(dir); - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - return -ENOSPC; - } - inode->i_dirt = 1; - if (!(name_block = bread(inode->i_dev,inode->i_data[0]))) { - iput(dir); - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - return -EIO; - } - i = 0; - while (i < 1023 && (c=get_fs_byte(symname++))) - name_block->b_data[i++] = c; - name_block->b_data[i] = 0; - name_block->b_dirt = 1; - brelse(name_block); - inode->i_size = i; - inode->i_dirt = 1; - bh = ext_find_entry(dir,name,len,&de,NULL,NULL); - if (bh) { - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - brelse(bh); - iput(dir); - return -EEXIST; - } - bh = ext_add_entry(dir,name,len,&de); - if (!bh) { - inode->i_nlink--; - inode->i_dirt = 1; - iput(inode); - iput(dir); - return -ENOSPC; - } - de->inode = inode->i_ino; - bh->b_dirt = 1; - brelse(bh); - iput(dir); - iput(inode); - return 0; -} - -int ext_link(struct inode * oldinode, struct inode * dir, const char * name, int len) -{ - struct ext_dir_entry * de; - struct buffer_head * bh; - - if (S_ISDIR(oldinode->i_mode)) { - iput(oldinode); - iput(dir); - return -EPERM; - } - bh = ext_find_entry(dir,name,len,&de,NULL,NULL); - if (bh) { - brelse(bh); - iput(dir); - iput(oldinode); - return -EEXIST; - } - bh = ext_add_entry(dir,name,len,&de); - if (!bh) { - iput(dir); - iput(oldinode); - return -ENOSPC; - } - de->inode = oldinode->i_ino; - bh->b_dirt = 1; - brelse(bh); - iput(dir); - oldinode->i_nlink++; - oldinode->i_ctime = CURRENT_TIME; - oldinode->i_dirt = 1; - iput(oldinode); - return 0; -} - -static int subdir(struct inode * new, struct inode * old) -{ - unsigned short fs; - int ino; - int result; - - __asm__("mov %%fs,%0":"=r" (fs)); - __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10)); - new->i_count++; - result = 0; - for (;;) { - if (new == old) { - result = 1; - break; - } - if (new->i_dev != old->i_dev) - break; - ino = new->i_ino; - if (ext_lookup(new,"..",2,&new)) - break; - if (new->i_ino == ino) - break; - } - iput(new); - __asm__("mov %0,%%fs"::"r" (fs)); - return result; -} - -#define PARENT_INO(buffer) \ -((struct ext_dir_entry *) ((char *) buffer + \ -((struct ext_dir_entry *) buffer)->rec_len))->inode -/* (((struct ext_dir_entry *) (buffer))[1].inode) */ - -#define PARENT_NAME(buffer) \ -((struct ext_dir_entry *) ((char *) buffer + \ -((struct ext_dir_entry *) buffer)->rec_len))->name -/* (((struct ext_dir_entry *) (buffer))[1].name) */ - -/* - * rename uses retrying to avoid race-conditions: at least they should be minimal. - * it tries to allocate all the blocks, then sanity-checks, and if the sanity- - * checks fail, it tries to restart itself again. Very practical - no changes - * are done until we know everything works ok.. and then all the changes can be - * done in one fell swoop when we have claimed all the buffers needed. - * - * Anybody can rename anything with this: the permission checks are left to the - * higher-level routines. - */ -static int do_ext_rename(struct inode * old_dir, const char * old_name, int old_len, - struct inode * new_dir, const char * new_name, int new_len) -{ - struct inode * old_inode, * new_inode; - struct buffer_head * old_bh, * new_bh, * dir_bh; - struct ext_dir_entry * old_de, * new_de, * pde, * nde; - int retval; - - goto start_up; -try_again: - brelse(old_bh); - brelse(new_bh); - brelse(dir_bh); - iput(old_inode); - iput(new_inode); - current->counter = 0; - schedule(); -start_up: - old_inode = new_inode = NULL; - old_bh = new_bh = dir_bh = NULL; - old_bh = ext_find_entry(old_dir,old_name,old_len,&old_de,&pde,&nde); - retval = -ENOENT; - if (!old_bh) - goto end_rename; - old_inode = iget(old_dir->i_dev, old_de->inode); - if (!old_inode) - goto end_rename; - if ((old_dir->i_mode & S_ISVTX) && - current->euid != old_inode->i_uid && - current->euid != old_dir->i_uid && !suser()) - goto end_rename; - new_bh = ext_find_entry(new_dir,new_name,new_len,&new_de,NULL,NULL); - if (new_bh) { - new_inode = iget(new_dir->i_dev, new_de->inode); - if (!new_inode) { - brelse(new_bh); - new_bh = NULL; - } - } - if (new_inode == old_inode) { - retval = 0; - goto end_rename; - } - if (S_ISDIR(new_inode->i_mode)) { - retval = -EEXIST; - goto end_rename; - } - if (S_ISDIR(old_inode->i_mode)) { - retval = -EEXIST; - if (new_bh) - goto end_rename; - retval = -EACCES; - if (!permission(old_inode, MAY_WRITE)) - goto end_rename; - retval = -EINVAL; - if (subdir(new_dir, old_inode)) - goto end_rename; - retval = -EIO; - if (!old_inode->i_data[0]) - goto end_rename; - if (!(dir_bh = bread(old_inode->i_dev, old_inode->i_data[0]))) - goto end_rename; - if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino) - goto end_rename; - } - if (!new_bh) - new_bh = ext_add_entry(new_dir,new_name,new_len,&new_de); - retval = -ENOSPC; - if (!new_bh) - goto end_rename; -/* sanity checking before doing the rename - avoid races */ - if (new_inode && (new_de->inode != new_inode->i_ino)) - goto try_again; - if (new_de->inode && !new_inode) - goto try_again; - if (old_de->inode != old_inode->i_ino) - goto try_again; -/* ok, that's it */ - old_de->inode = 0; - old_de->name_len = 0; - ext_merge_entries (old_de, pde, nde); - new_de->inode = old_inode->i_ino; - if (new_inode) { - new_inode->i_nlink--; - new_inode->i_dirt = 1; - } - old_bh->b_dirt = 1; - new_bh->b_dirt = 1; - if (dir_bh) { - PARENT_INO(dir_bh->b_data) = new_dir->i_ino; - dir_bh->b_dirt = 1; - old_dir->i_nlink--; - new_dir->i_nlink++; - old_dir->i_dirt = 1; - new_dir->i_dirt = 1; - } - retval = 0; -end_rename: - brelse(dir_bh); - brelse(old_bh); - brelse(new_bh); - iput(old_inode); - iput(new_inode); - iput(old_dir); - iput(new_dir); - return retval; -} - -/* - * Ok, rename also locks out other renames, as they can change the parent of - * a directory, and we don't want any races. Other races are checked for by - * "do_rename()", which restarts if there are inconsistencies. - * - * Note that there is no race between different filesystems: it's only within - * the same device that races occur: many renames can happen at once, as long - * as they are on different partitions. - */ -int ext_rename(struct inode * old_dir, const char * old_name, int old_len, - struct inode * new_dir, const char * new_name, int new_len) -{ - static struct wait_queue * wait = NULL; - static int lock = 0; - int result; - - while (lock) - sleep_on(&wait); - lock = 1; - result = do_ext_rename(old_dir, old_name, old_len, - new_dir, new_name, new_len); - lock = 0; - wake_up(&wait); - return result; -} diff --git a/fs/ext/symlink.c b/fs/ext/symlink.c deleted file mode 100644 index eeef2b4c1d13..000000000000 --- a/fs/ext/symlink.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * linux/fs/ext/symlink.c - * - * (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/symlink.c - * - * (C) 1991 Linus Torvalds - * - * ext symlink handling code - */ - -#include - -#include - -#include -#include -#include -#include - -static int ext_readlink(struct inode *, char *, int); -static struct inode * ext_follow_link(struct inode *, struct inode *); - -/* - * symlinks can't do much... - */ -struct inode_operations ext_symlink_inode_operations = { - NULL, /* no file-operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - ext_readlink, /* readlink */ - ext_follow_link, /* follow_link */ - NULL, /* bmap */ - NULL /* truncate */ -}; - -static struct inode * ext_follow_link(struct inode * dir, struct inode * inode) -{ - unsigned short fs; - struct buffer_head * bh; - - if (!dir) { - dir = current->root; - dir->i_count++; - } - if (!inode) { - iput(dir); - return NULL; - } - if (!S_ISLNK(inode->i_mode)) { - iput(dir); - return inode; - } - __asm__("mov %%fs,%0":"=r" (fs)); - if ((current->link_count > 5) || !inode->i_data[0] || - !(bh = bread(inode->i_dev, inode->i_data[0]))) { - iput(dir); - iput(inode); - return NULL; - } - iput(inode); - __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10)); - current->link_count++; - inode = _namei(bh->b_data,dir,1); - current->link_count--; - __asm__("mov %0,%%fs"::"r" (fs)); - brelse(bh); - return inode; -} - -static int ext_readlink(struct inode * inode, char * buffer, int buflen) -{ - struct buffer_head * bh; - int i; - char c; - - if (!S_ISLNK(inode->i_mode)) { - iput(inode); - return -EINVAL; - } - if (buflen > 1023) - buflen = 1023; - if (inode->i_data[0]) - bh = bread(inode->i_dev, inode->i_data[0]); - else - bh = NULL; - iput(inode); - if (!bh) - return 0; - i = 0; - while (ib_data[i])) { - i++; - put_fs_byte(c,buffer++); - } - brelse(bh); - return i; -} diff --git a/fs/ext/truncate.c b/fs/ext/truncate.c deleted file mode 100644 index 04c0b2eae3c9..000000000000 --- a/fs/ext/truncate.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * linux/fs/ext/truncate.c - * - * (C) 1992 Remy Card (card@masi.ibp.fr) - * - * from - * - * linux/fs/minix/truncate.c - * - * (C) 1991 Linus Torvalds - */ - -#include -#include -#include -#include -#include - -#include - -/* - * Truncate has the most races in the whole filesystem: coding it is - * a pain in the a**. Especially as I don't do any locking... - * - * The code may look a bit weird, but that's just because I've tried to - * handle things like file-size changes in a somewhat graceful manner. - * Anyway, truncating a file at the same time somebody else writes to it - * is likely to result in pretty weird behaviour... - * - * The new code handles normal truncates (size = 0) as well as the more - * general case (size = XXX). I hope. - */ - -static int trunc_direct(struct inode * inode) -{ - int i; - int result = 0; -#define DIRECT_BLOCK ((inode->i_size + 1023) >> 10) - -repeat: - for (i = DIRECT_BLOCK ; i < 9 ; i++) { - if (i < DIRECT_BLOCK) - goto repeat; - if (!inode->i_data[i]) - continue; - result = 1; - if (ext_free_block(inode->i_dev,inode->i_data[i])) - inode->i_data[i] = 0; - } - return result; -} - -static int trunc_indirect(struct inode * inode, int offset, unsigned long * p) -{ - int i; - struct buffer_head * bh = NULL; - unsigned long * ind; - int result = 0; -#define INDIRECT_BLOCK (DIRECT_BLOCK-offset) - - if (*p) - bh = bread(inode->i_dev,*p); - if (!bh) - return 0; -repeat: - for (i = INDIRECT_BLOCK ; i < 256 ; i++) { - if (i < 0) - i = 0; - if (i < INDIRECT_BLOCK) - goto repeat; - ind = i+(unsigned long *) bh->b_data; - if (!*ind) - continue; - result = 1; - if (ext_free_block(inode->i_dev,*ind)) - *ind = 0; - } - ind = (unsigned long *) bh->b_data; - for (i = 0; i < 256; i++) - if (*(ind++)) - break; - brelse(bh); - if (i >= 256) { - result = 1; - if (ext_free_block(inode->i_dev,*p)) - *p = 0; - } - return result; -} - -static int trunc_dindirect(struct inode * inode) -{ - int i; - struct buffer_head * bh = NULL; - unsigned long * dind; - int result = 0; -#define DINDIRECT_BLOCK ((DIRECT_BLOCK-(256+9))>>8) - - if (inode->i_data[10]) - bh = bread(inode->i_dev,inode->i_data[10]); - if (!bh) - return 0; -repeat: - for (i = DINDIRECT_BLOCK ; i < 256 ; i ++) { - if (i < 0) - i = 0; - if (i < DINDIRECT_BLOCK) - goto repeat; - dind = i+(unsigned long *) bh->b_data; - if (!*dind) - continue; - result |= trunc_indirect(inode,9+256+(i<<8),dind); - } - dind = (unsigned long *) bh->b_data; - for (i = 0; i < 256; i++) - if (*(dind++)) - break; - brelse(bh); - if (i >= 256) { - result = 1; - if (ext_free_block(inode->i_dev,inode->i_data[10])) - inode->i_data[10] = 0; - } - return result; -} - -void ext_truncate(struct inode * inode) -{ - int flag; - - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return; -/* if (inode->i_data[7] & 0xffff0000) - printk("BAD! ext inode has 16 high bits set\n"); */ - while (1) { - flag = trunc_direct(inode); - flag |= trunc_indirect(inode,9,(unsigned long *)&inode->i_data[9]); - flag |= trunc_dindirect(inode); - if (!flag) - break; - current->counter = 0; - schedule(); - } - inode->i_mtime = inode->i_ctime = CURRENT_TIME; - inode->i_dirt = 1; -} - -/* - * Called when a inode is released. Note that this is different - * from ext_open: open gets called at every open, but release - * gets called only when /all/ the files are closed. - */ -void ext_release(struct inode * inode, struct file * filp) -{ - printk("ext_release not implemented\n"); -} diff --git a/fs/fcntl.c b/fs/fcntl.c index 02b5af100ef9..96584831501d 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -4,15 +4,14 @@ * (C) 1991 Linus Torvalds */ -#include - -#include - -#include -#include #include +#include #include #include +#include + +#include +#include extern int sys_close(int fd); @@ -36,8 +35,6 @@ static int dupfd(unsigned int fd, unsigned int arg) int sys_dup2(unsigned int oldfd, unsigned int newfd) { - if (oldfd >= NR_OPEN || !current->filp[oldfd]) - return -EBADF; if (newfd == oldfd) return newfd; sys_close(newfd); diff --git a/fs/fifo.c b/fs/fifo.c deleted file mode 100644 index 8e1a7d2f66ce..000000000000 --- a/fs/fifo.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * linux/fs/fifo.c - * - * written by Paul H. Hargrove - */ - -#include - -#include -#include -#include - -extern struct file_operations read_pipe_fops; -extern struct file_operations write_pipe_fops; -extern struct file_operations rdwr_pipe_fops; - -static int fifo_open(struct inode * inode,struct file * filp) -{ - int retval = 0; - unsigned long page; - - switch( filp->f_mode ) { - - case 1: - /* - * O_RDONLY - * POSIX.1 says that O_NONBLOCK means return with the FIFO - * opened, even when there is no process writing the FIFO. - */ - filp->f_op = &read_pipe_fops; - PIPE_READERS(*inode)++; - if (!(filp->f_flags & O_NONBLOCK)) - while (!PIPE_WRITERS(*inode)) { - if (PIPE_HEAD(*inode) != PIPE_TAIL(*inode)) - break; - if (current->signal & ~current->blocked) { - retval = -ERESTARTSYS; - break; - } - interruptible_sleep_on(&PIPE_READ_WAIT(*inode)); - } - if (retval) - PIPE_READERS(*inode)--; - break; - - case 2: - /* - * O_WRONLY - * POSIX.1 says that O_NONBLOCK means return -1 with - * errno=ENXIO when there is no process reading the FIFO. - */ - if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) { - retval = -ENXIO; - break; - } - filp->f_op = &write_pipe_fops; - PIPE_WRITERS(*inode)++; - while (!PIPE_READERS(*inode)) { - if (current->signal & ~current->blocked) { - retval = -ERESTARTSYS; - break; - } - interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode)); - } - if (retval) - PIPE_WRITERS(*inode)--; - break; - - case 3: - /* - * O_RDWR - * POSIX.1 leaves this case "undefined" when O_NONBLOCK is set. - * This implementation will NEVER block on a O_RDWR open, since - * the process can at least talk to itself. - */ - filp->f_op = &rdwr_pipe_fops; - PIPE_WRITERS(*inode) += 1; - PIPE_READERS(*inode) += 1; - break; - - default: - retval = -EINVAL; - } - if (PIPE_WRITERS(*inode)) - wake_up(&PIPE_READ_WAIT(*inode)); - if (PIPE_READERS(*inode)) - wake_up(&PIPE_WRITE_WAIT(*inode)); - if (retval || inode->i_size) - return retval; - page = get_free_page(); - if (inode->i_size) { - free_page(page); - return 0; - } - if (!page) - return -ENOMEM; - inode->i_size = page; - return 0; -} - -/* - * Dummy default file-operations: the only thing this does - * is contain the open that then fills in the correct operations - * depending on the access mode of the file... - */ -struct file_operations def_fifo_fops = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - fifo_open, /* will set read or write pipe_fops */ - NULL -}; diff --git a/fs/inode.c b/fs/inode.c index 65637dff9ccd..385f2f991121 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -5,11 +5,11 @@ */ #include -#include +#include + #include #include #include - #include struct inode inode_table[NR_INODE]={{0,},}; @@ -39,13 +39,13 @@ static inline void unlock_inode(struct inode * inode) static void write_inode(struct inode * inode) { - if (!inode->i_dirt) - return; - inode->i_dirt = 0; lock_inode(inode); - if (inode->i_dev && inode->i_sb && - inode->i_sb->s_op && inode->i_sb->s_op->write_inode) - inode->i_sb->s_op->write_inode(inode); + if (!inode->i_dirt || !inode->i_dev) { + unlock_inode(inode); + return; + } + if (inode->i_op && inode->i_op->write_inode) + inode->i_op->write_inode(inode); unlock_inode(inode); } @@ -100,7 +100,7 @@ void sync_inodes(void) inode = 0+inode_table; for(i=0 ; ii_dirt) + if (inode->i_dirt && !inode->i_pipe) write_inode(inode); } } @@ -110,34 +110,36 @@ void iput(struct inode * inode) if (!inode) return; wait_on_inode(inode); - if (!inode->i_count) { - printk("iput: trying to free free inode\n"); - printk("device %04x, inode %d, mode=%07o\n",inode->i_rdev, - inode->i_ino,inode->i_mode); - return; - } + if (!inode->i_count) + panic("iput: trying to free free inode"); if (inode->i_pipe) { wake_up(&inode->i_wait); wake_up(&inode->i_wait2); + if (--inode->i_count) + return; + free_page(inode->i_size); + inode->i_count=0; + inode->i_dirt=0; + inode->i_pipe=0; + return; } -repeat: - if (inode->i_count>1) { + if (!inode->i_dev) { inode->i_count--; return; } - if (inode->i_pipe) { - free_page(inode->i_size); - inode->i_size = 0; + if (S_ISBLK(inode->i_mode)) { + sync_dev(inode->i_rdev); + wait_on_inode(inode); } - if (!inode->i_dev) { +repeat: + if (inode->i_count>1) { inode->i_count--; return; } if (!inode->i_nlink) { - if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) { - inode->i_sb->s_op->put_inode(inode); - return; - } + if (inode->i_op && inode->i_op->put_inode) + inode->i_op->put_inode(inode); + return; } if (inode->i_dirt) { write_inode(inode); /* we can sleep - so do again */ @@ -188,13 +190,12 @@ struct inode * get_pipe_inode(void) if (!(inode = get_empty_inode())) return NULL; - if (!(inode->i_size = get_free_page())) { + if (!(inode->i_size=get_free_page())) { inode->i_count = 0; return NULL; } inode->i_count = 2; /* sum of readers/writers */ PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; - PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; inode->i_pipe = 1; return inode; } @@ -252,7 +253,6 @@ struct inode * iget(int dev,int nr) } inode->i_dev = dev; inode->i_ino = nr; - inode->i_flags = inode->i_sb->s_flags; read_inode(inode); return inode; } diff --git a/fs/ioctl.c b/fs/ioctl.c index 6c9ef40532e7..7b2811674620 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -4,27 +4,18 @@ * (C) 1991 Linus Torvalds */ +#include #include +#include -#include -#include -#include #include int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { struct file * filp; - int block; if (fd >= NR_OPEN || !(filp = current->filp[fd])) return -EBADF; - if (S_ISREG(filp->f_inode->i_mode) && cmd == BMAP_IOCTL && - filp->f_inode->i_op->bmap) { - block = get_fs_long((long *) arg); - block = filp->f_inode->i_op->bmap(filp->f_inode,block); - put_fs_long(block,(long *) arg); - return 0; - } if (filp->f_op && filp->f_op->ioctl) return filp->f_op->ioctl(filp->f_inode, filp, cmd,arg); return -EINVAL; diff --git a/fs/minix/Makefile b/fs/minix/Makefile index 0fdd1881513e..81aebc7af46b 100644 --- a/fs/minix/Makefile +++ b/fs/minix/Makefile @@ -7,15 +7,22 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... +AR =ar +AS =as +LD =ld +CC =gcc -nostdinc -I../../include +CPP =cpp -nostdinc -I../../include + .c.s: - $(CC) $(CFLAGS) -S $< + $(CC) $(CFLAGS) \ + -S -o $*.s $< .c.o: - $(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) \ + -c -o $*.o $< .s.o: $(AS) -o $*.o $< -OBJS= bitmap.o truncate.o namei.o inode.o \ - file.o dir.o symlink.o blkdev.o chrdev.o fifo.o +OBJS= minix_op.o bitmap.o truncate.o namei.o inode.o file_dev.o minix.o: $(OBJS) $(LD) -r -o minix.o $(OBJS) @@ -26,78 +33,37 @@ clean: dep: sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - for i in *.c;do $(CPP) -M $$i;done >> tmp_make + (for i in *.c;do $(CPP) -M $$i;done) >> tmp_make cp tmp_make Makefile ### Dependencies: -bitmap.o : bitmap.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h -blkdev.o : blkdev.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \ - /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h -chrdev.o : chrdev.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \ - /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h -dir.o : dir.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/stat.h -fifo.o : fifo.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h -file.o : file.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/fcntl.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \ - /usr/src/linux/include/linux/stat.h -inode.o : inode.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/asm/system.h \ - /usr/src/linux/include/asm/segment.h -namei.o : namei.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \ - /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h \ - /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h /usr/src/linux/include/const.h -symlink.o : symlink.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/stat.h -truncate.o : truncate.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \ - /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h +bitmap.o : bitmap.c ../../include/linux/string.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \ + ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h ../../include/linux/minix_fs.h +file_dev.o : file_dev.c ../../include/errno.h ../../include/fcntl.h ../../include/sys/types.h \ + ../../include/sys/dirent.h ../../include/limits.h ../../include/sys/stat.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h ../../include/linux/mm.h \ + ../../include/linux/kernel.h ../../include/signal.h ../../include/sys/param.h \ + ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h ../../include/linux/minix_fs.h \ + ../../include/asm/segment.h +inode.o : inode.c ../../include/linux/string.h ../../include/sys/stat.h ../../include/sys/types.h \ + ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \ + ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/asm/system.h +minix_op.o : minix_op.c ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \ + ../../include/limits.h ../../include/linux/minix_fs.h +namei.o : namei.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \ + ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \ + ../../include/linux/mm.h ../../include/linux/kernel.h ../../include/signal.h \ + ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \ + ../../include/linux/minix_fs.h ../../include/asm/segment.h ../../include/linux/string.h \ + ../../include/fcntl.h ../../include/errno.h ../../include/const.h ../../include/sys/stat.h +truncate.o : truncate.c ../../include/linux/sched.h ../../include/linux/head.h \ + ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \ + ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/linux/tty.h \ + ../../include/termios.h ../../include/errno.h ../../include/fcntl.h ../../include/sys/stat.h diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 4d560d454ca9..6a3ead378f17 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -1,12 +1,12 @@ /* - * linux/fs/minix/bitmap.c + * linux/fs/bitmap.c * * (C) 1991 Linus Torvalds */ /* bitmap.c contains the code that handles the inode and block bitmaps */ - #include + #include #include #include @@ -44,35 +44,6 @@ __asm__("cld\n" \ :"=c" (__res):"0" (0),"S" (addr):"ax","dx","si"); \ __res;}) -static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 }; - -static unsigned long count_used(struct buffer_head *map[], unsigned numblocks, - unsigned numbits) -{ - unsigned i, j, end, sum = 0; - struct buffer_head *bh; - - for (i=0; (i= (8*BLOCK_SIZE)) { - end = BLOCK_SIZE; - numbits -= 8*BLOCK_SIZE; - } else { - int tmp; - end = numbits >> 3; - numbits &= 0x7; - tmp = bh->b_data[end] & ((1<>4)&0xf]; - numbits = 0; - } - for (j=0; jb_data[j] & 0xf] - + nibblemap[(bh->b_data[j]>>4)&0xf]; - } - return(sum); -} - int minix_free_block(int dev, int block) { struct super_block * sb; @@ -136,12 +107,6 @@ int minix_new_block(int dev) return j; } -unsigned long minix_count_free_blocks(struct super_block *sb) -{ - return (sb->s_nzones - count_used(sb->s_zmap,sb->s_zmap_blocks,sb->s_nzones)) - << sb->s_log_zone_size; -} - void minix_free_inode(struct inode * inode) { struct buffer_head * bh; @@ -191,7 +156,6 @@ struct inode * minix_new_inode(int dev) iput(inode); return NULL; } - inode->i_flags = inode->i_sb->s_flags; j = 8192; for (i=0 ; i<8 ; i++) if (bh=inode->i_sb->s_imap[i]) @@ -215,11 +179,6 @@ struct inode * minix_new_inode(int dev) inode->i_dirt = 1; inode->i_ino = j + i*8192; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - inode->i_op = NULL; + inode->i_op = &minix_inode_operations; return inode; } - -unsigned long minix_count_free_inodes(struct super_block *sb) -{ - return sb->s_ninodes - count_used(sb->s_imap,sb->s_imap_blocks,sb->s_ninodes); -} diff --git a/fs/minix/blkdev.c b/fs/minix/blkdev.c deleted file mode 100644 index 144d19f228ff..000000000000 --- a/fs/minix/blkdev.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * linux/fs/minix/blkdev.c - * - * (C) 1991 Linus Torvalds - */ - -#include - -#include -#include -#include -#include -#include - -/* - * Called every time a minix block special file is opened - */ -static int blkdev_open(struct inode * inode, struct file * filp) -{ - int i; - - i = MAJOR(inode->i_rdev); - if (i < MAX_BLKDEV) { - filp->f_op = blkdev_fops[i]; - if (filp->f_op && filp->f_op->open) - return filp->f_op->open(inode,filp); - } - return 0; -} - -/* - * Dummy default file-operations: the only thing this does - * is contain the open that then fills in the correct operations - * depending on the special file... - */ -static struct file_operations def_blk_fops = { - NULL, /* lseek */ - NULL, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - blkdev_open, /* open */ - NULL, /* release */ -}; - -struct inode_operations minix_blkdev_inode_operations = { - &def_blk_fops, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - minix_bmap, /* bmap */ - minix_truncate /* truncate */ -}; diff --git a/fs/minix/chrdev.c b/fs/minix/chrdev.c deleted file mode 100644 index c9e61d3f9495..000000000000 --- a/fs/minix/chrdev.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * linux/fs/minix/chrdev.c - * - * (C) 1991 Linus Torvalds - */ - -#include - -#include -#include -#include -#include -#include - -/* - * Called every time a minix character special file is opened - */ -static int chrdev_open(struct inode * inode, struct file * filp) -{ - int i; - - i = MAJOR(inode->i_rdev); - if (i < MAX_CHRDEV) { - filp->f_op = chrdev_fops[i]; - if (filp->f_op && filp->f_op->open) - return filp->f_op->open(inode,filp); - } - return 0; -} - -/* - * Dummy default file-operations: the only thing this does - * is contain the open that then fills in the correct operations - * depending on the special file... - */ -static struct file_operations def_chr_fops = { - NULL, /* lseek */ - NULL, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - chrdev_open, /* open */ - NULL, /* release */ -}; - -struct inode_operations minix_chrdev_inode_operations = { - &def_chr_fops, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - minix_bmap, /* bmap */ - minix_truncate /* truncate */ -}; - diff --git a/fs/minix/dir.c b/fs/minix/dir.c deleted file mode 100644 index bfa355123628..000000000000 --- a/fs/minix/dir.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * linux/fs/minix/dir.c - * - * (C) 1991 Linus Torvalds - * - * minix directory handling functions - */ - -#include - -#include - -#include -#include -#include - -static int minix_readdir(struct inode *, struct file *, struct dirent *, int); - -static struct file_operations minix_dir_operations = { - NULL, /* lseek - default */ - minix_file_read, /* read */ - NULL, /* write - bad */ - minix_readdir, /* readdir */ - NULL, /* select - default */ - NULL, /* ioctl - default */ - NULL, /* no special open code */ - NULL /* no special release code */ -}; - -/* - * directories can handle most operations... - */ -struct inode_operations minix_dir_inode_operations = { - &minix_dir_operations, /* default directory file-ops */ - minix_create, /* create */ - minix_lookup, /* lookup */ - minix_link, /* link */ - minix_unlink, /* unlink */ - minix_symlink, /* symlink */ - minix_mkdir, /* mkdir */ - minix_rmdir, /* rmdir */ - minix_mknod, /* mknod */ - minix_rename, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - minix_bmap, /* bmap */ - minix_truncate /* truncate */ -}; - -static int minix_readdir(struct inode * inode, struct file * filp, - struct dirent * dirent, int count) -{ - unsigned int block,offset,i; - char c; - struct buffer_head * bh; - struct minix_dir_entry * de; - - if (!inode || !S_ISDIR(inode->i_mode)) - return -EBADF; - if (filp->f_pos & (sizeof (struct minix_dir_entry) - 1)) - return -EBADF; - while (filp->f_pos < inode->i_size) { - offset = filp->f_pos & 1023; - block = minix_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS); - if (!block || !(bh = bread(inode->i_dev,block))) { - filp->f_pos += 1024-offset; - continue; - } - de = (struct minix_dir_entry *) (offset + bh->b_data); - while (offset < 1024 && filp->f_pos < inode->i_size) { - offset += sizeof (struct minix_dir_entry); - filp->f_pos += sizeof (struct minix_dir_entry); - if (de->inode) { - for (i = 0; i < MINIX_NAME_LEN; i++) - if (c = de->name[i]) - put_fs_byte(c,i+dirent->d_name); - else - break; - if (i) { - put_fs_long(de->inode,&dirent->d_ino); - put_fs_byte(0,i+dirent->d_name); - put_fs_word(i,&dirent->d_reclen); - brelse(bh); - return i; - } - } - de++; - } - brelse(bh); - } - return 0; -} diff --git a/fs/minix/fifo.c b/fs/minix/fifo.c deleted file mode 100644 index 671604bad5b6..000000000000 --- a/fs/minix/fifo.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * linux/fs/fifo.c - * - * written by Paul H. Hargrove - */ - -#include -#include - -extern struct file_operations def_fifo_fops; - -struct inode_operations minix_fifo_inode_operations = { - &def_fifo_fops, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* bmap */ - NULL /* truncate */ -}; diff --git a/fs/minix/file.c b/fs/minix/file.c deleted file mode 100644 index cc7e33a95a0c..000000000000 --- a/fs/minix/file.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * linux/fs/minix/file.c - * - * (C) 1991 Linus Torvalds - * - * minix regular file handling primitives - */ - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#define NBUF 16 - -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - -#include -#include - -int minix_file_read(struct inode *, struct file *, char *, int); -static int minix_file_write(struct inode *, struct file *, char *, int); - -/* - * We have mostly NULL's here: the current defaults are ok for - * the minix filesystem. - */ -static struct file_operations minix_file_operations = { - NULL, /* lseek - default */ - minix_file_read, /* read */ - minix_file_write, /* write */ - NULL, /* readdir - bad */ - NULL, /* select - default */ - NULL, /* ioctl - default */ - NULL, /* no special open is needed */ - NULL /* release */ -}; - -struct inode_operations minix_file_inode_operations = { - &minix_file_operations, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - minix_bmap, /* bmap */ - minix_truncate /* truncate */ -}; - -static inline void wait_on_buffer(struct buffer_head * bh) -{ - cli(); - while (bh->b_lock) - sleep_on(&bh->b_wait); - sti(); -} - -/* - * minix_file_read() is also needed by the directory read-routine, - * so it's not static. NOTE! reading directories directly is a bad idea, - * but has to be supported for now for compatability reasons with older - * versions. - */ -int minix_file_read(struct inode * inode, struct file * filp, char * buf, int count) -{ - int read,left,chars,nr; - int block, blocks, offset; - struct buffer_head ** bhb, ** bhe; - struct buffer_head * buflist[NBUF]; - - if (!inode) { - printk("minix_file_read: inode = NULL\n"); - return -EINVAL; - } - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) { - printk("minix_file_read: mode = %07o\n",inode->i_mode); - return -EINVAL; - } - if (filp->f_pos > inode->i_size) - left = 0; - else - left = inode->i_size - filp->f_pos; - if (left > count) - left = count; - if (left <= 0) - return 0; - read = 0; - block = filp->f_pos >> BLOCK_SIZE_BITS; - offset = filp->f_pos & (BLOCK_SIZE-1); - blocks = (left + offset + BLOCK_SIZE - 1) / BLOCK_SIZE; - bhb = bhe = buflist; - do { - if (blocks) { - --blocks; - if (nr = minix_bmap(inode,block++)) { - *bhb = getblk(inode->i_dev,nr); - if (!(*bhb)->b_uptodate) - ll_rw_block(READ,*bhb); - } else - *bhb = NULL; - - if (++bhb == &buflist[NBUF]) - bhb = buflist; - - if (bhb != bhe) - continue; - } - if (*bhe) { - wait_on_buffer(*bhe); - if (!(*bhe)->b_uptodate) { - do { - brelse(*bhe); - if (++bhe == &buflist[NBUF]) - bhe = buflist; - } while (bhe != bhb); - break; - } - } - - if (left < BLOCK_SIZE - offset) - chars = left; - else - chars = BLOCK_SIZE - offset; - filp->f_pos += chars; - left -= chars; - read += chars; - if (*bhe) { - memcpy_tofs(buf,offset+(*bhe)->b_data,chars); - brelse(*bhe); - buf += chars; - } else { - while (chars-->0) - put_fs_byte(0,buf++); - } - offset = 0; - if (++bhe == &buflist[NBUF]) - bhe = buflist; - } while (left > 0); - if (!read) - return -EIO; - if (!IS_RDONLY(inode)) { - inode->i_atime = CURRENT_TIME; - inode->i_dirt = 1; - } - return read; -} - -static int minix_file_write(struct inode * inode, struct file * filp, char * buf, int count) -{ - off_t pos; - int written,block,c; - struct buffer_head * bh; - char * p; - - if (!inode) { - printk("minix_file_write: inode = NULL\n"); - return -EINVAL; - } - if (!S_ISREG(inode->i_mode)) { - printk("minix_file_write: mode = %07o\n",inode->i_mode); - return -EINVAL; - } -/* - * ok, append may not work when many processes are writing at the same time - * but so what. That way leads to madness anyway. - */ - if (filp->f_flags & O_APPEND) - pos = inode->i_size; - else - pos = filp->f_pos; - written = 0; - while (written count-written) - c = count-written; - if (c == BLOCK_SIZE) - bh = getblk(inode->i_dev, block); - else - bh = bread(inode->i_dev,block); - if (!bh) { - if (!written) - written = -EIO; - break; - } - p = (pos % BLOCK_SIZE) + bh->b_data; - pos += c; - if (pos > inode->i_size) { - inode->i_size = pos; - inode->i_dirt = 1; - } - written += c; - memcpy_fromfs(p,buf,c); - buf += c; - bh->b_uptodate = 1; - bh->b_dirt = 1; - brelse(bh); - } - inode->i_mtime = CURRENT_TIME; - inode->i_ctime = CURRENT_TIME; - filp->f_pos = pos; - inode->i_dirt = 1; - return written; -} diff --git a/fs/minix/file_dev.c b/fs/minix/file_dev.c new file mode 100644 index 000000000000..2ae070554ac8 --- /dev/null +++ b/fs/minix/file_dev.c @@ -0,0 +1,169 @@ +/* + * linux/fs/file_dev.c + * + * (C) 1991 Linus Torvalds + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + +int minix_readdir(struct inode * inode, struct file * filp, struct dirent * dirent, int count) +{ + unsigned int block,offset,i; + char c; + struct buffer_head * bh; + struct minix_dir_entry * de; + + if (!inode || !S_ISDIR(inode->i_mode)) + return -EBADF; + if (filp->f_pos & (sizeof (struct minix_dir_entry) - 1)) + return -EBADF; + while (filp->f_pos < inode->i_size) { + offset = filp->f_pos & 1023; + block = minix_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS); + if (!block || !(bh = bread(inode->i_dev,block))) { + filp->f_pos += 1024-offset; + continue; + } + de = (struct minix_dir_entry *) (offset + bh->b_data); + while (offset < 1024 && filp->f_pos < inode->i_size) { + offset += sizeof (struct minix_dir_entry); + filp->f_pos += sizeof (struct minix_dir_entry); + if (de->inode) { + for (i = 0; i < MINIX_NAME_LEN; i++) + if (c = de->name[i]) + put_fs_byte(c,i+dirent->d_name); + else + break; + if (i) { + put_fs_long(de->inode,&dirent->d_ino); + put_fs_byte(0,i+dirent->d_name); + put_fs_word(i,&dirent->d_reclen); + brelse(bh); + return i; + } + } + de++; + } + brelse(bh); + } + return 0; +} + +int minix_file_read(struct inode * inode, struct file * filp, char * buf, int count) +{ + int read,left,chars,nr; + struct buffer_head * bh; + + if (!inode) { + printk("minix_file_read: inode = NULL\n"); + return -EINVAL; + } + if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) { + printk("minix_file_read: mode = %07o\n",inode->i_mode); + return -EINVAL; + } + if (filp->f_pos > inode->i_size) + left = 0; + else + left = inode->i_size - filp->f_pos; + if (left > count) + left = count; + read = 0; + while (left > 0) { + if (nr = minix_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS)) { + if (!(bh=bread(inode->i_dev,nr))) + return read?read:-EIO; + } else + bh = NULL; + nr = filp->f_pos & (BLOCK_SIZE-1); + chars = MIN( BLOCK_SIZE-nr , left ); + filp->f_pos += chars; + left -= chars; + read += chars; + if (bh) { + memcpy_tofs(buf,nr+bh->b_data,chars); + buf += chars; + brelse(bh); + } else { + while (chars-->0) + put_fs_byte(0,buf++); + } + } + inode->i_atime = CURRENT_TIME; + return read; +} + +int minix_file_write(struct inode * inode, struct file * filp, char * buf, int count) +{ + off_t pos; + int written,block,c; + struct buffer_head * bh; + char * p; + + if (!inode) { + printk("minix_file_write: inode = NULL\n"); + return -EINVAL; + } + if (!S_ISREG(inode->i_mode)) { + printk("minix_file_write: mode = %07o\n",inode->i_mode); + return -EINVAL; + } +/* + * ok, append may not work when many processes are writing at the same time + * but so what. That way leads to madness anyway. + */ + if (filp->f_flags & O_APPEND) + pos = inode->i_size; + else + pos = filp->f_pos; + written = 0; + while (written count-written) + c = count-written; + if (c == BLOCK_SIZE) + bh = getblk(inode->i_dev, block); + else + bh = bread(inode->i_dev,block); + if (!bh) { + if (!written) + written = -EIO; + break; + } + p = (pos % BLOCK_SIZE) + bh->b_data; + pos += c; + if (pos > inode->i_size) { + inode->i_size = pos; + inode->i_dirt = 1; + } + written += c; + memcpy_fromfs(p,buf,c); + buf += c; + bh->b_uptodate = 1; + bh->b_dirt = 1; + brelse(bh); + } + inode->i_mtime = CURRENT_TIME; + if (!(filp->f_flags & O_APPEND)) { + filp->f_pos = pos; + inode->i_ctime = CURRENT_TIME; + } + inode->i_dirt = 1; + return written; +} diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 71b45bc12a16..c635e6e85b97 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -5,23 +5,16 @@ */ #include -#include +#include + #include #include #include #include #include -#include int sync_dev(int dev); -void minix_put_inode(struct inode *inode) -{ - inode->i_size = 0; - minix_truncate(inode); - minix_free_inode(inode); -} - void minix_put_super(struct super_block *sb) { int i; @@ -38,17 +31,12 @@ void minix_put_super(struct super_block *sb) static struct super_operations minix_sops = { minix_read_inode, - minix_write_inode, - minix_put_inode, - minix_put_super, - NULL, - minix_statfs + minix_put_super }; struct super_block *minix_read_super(struct super_block *s,void *data) { struct buffer_head *bh; - struct minix_super_block *ms; int i,dev=s->s_dev,block; lock_super(s); @@ -58,15 +46,8 @@ struct super_block *minix_read_super(struct super_block *s,void *data) printk("bread failed\n"); return NULL; } - ms = (struct minix_super_block *) bh->b_data; - s->s_ninodes = ms->s_ninodes; - s->s_nzones = ms->s_nzones; - s->s_imap_blocks = ms->s_imap_blocks; - s->s_zmap_blocks = ms->s_zmap_blocks; - s->s_firstdatazone = ms->s_firstdatazone; - s->s_log_zone_size = ms->s_log_zone_size; - s->s_max_size = ms->s_max_size; - s->s_magic = ms->s_magic; + *((struct minix_super_block *) s) = + *((struct minix_super_block *) bh->b_data); brelse(bh); if (s->s_magic != MINIX_SUPER_MAGIC) { s->s_dev = 0; @@ -113,21 +94,6 @@ struct super_block *minix_read_super(struct super_block *s,void *data) return s; } -void minix_statfs (struct super_block *sb, struct statfs *buf) -{ - long tmp; - - put_fs_long(MINIX_SUPER_MAGIC, &buf->f_type); - put_fs_long(1024, &buf->f_bsize); - put_fs_long(sb->s_nzones << sb->s_log_zone_size, &buf->f_blocks); - tmp = minix_count_free_blocks(sb); - put_fs_long(tmp, &buf->f_bfree); - put_fs_long(tmp, &buf->f_bavail); - put_fs_long(sb->s_ninodes, &buf->f_files); - put_fs_long(minix_count_free_inodes(sb), &buf->f_ffree); - /* Don't know what value to put in buf->f_fsid */ -} - static int _minix_bmap(struct inode * inode,int block,int create) { struct buffer_head * bh; @@ -233,24 +199,7 @@ void minix_read_inode(struct inode * inode) else for (block = 0; block < 9; block++) inode->i_data[block] = raw_inode->i_zone[block]; brelse(bh); - inode->i_op = NULL; - if (S_ISREG(inode->i_mode)) - inode->i_op = &minix_file_inode_operations; - else if (S_ISDIR(inode->i_mode)) - inode->i_op = &minix_dir_inode_operations; - else if (S_ISLNK(inode->i_mode)) - inode->i_op = &minix_symlink_inode_operations; - else if (S_ISCHR(inode->i_mode)) - inode->i_op = &minix_chrdev_inode_operations; - else if (S_ISBLK(inode->i_mode)) - inode->i_op = &minix_blkdev_inode_operations; - else if (S_ISFIFO(inode->i_mode)) { - inode->i_op = &minix_fifo_inode_operations; - inode->i_size = 0; - inode->i_pipe = 1; - PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; - PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; - } + inode->i_op = &minix_inode_operations; } void minix_write_inode(struct inode * inode) diff --git a/fs/minix/minix_op.c b/fs/minix/minix_op.c new file mode 100644 index 000000000000..a588f095ba8f --- /dev/null +++ b/fs/minix/minix_op.c @@ -0,0 +1,62 @@ +/* + * linux/fs/minix/minix_op.c + * + * structures for the minix super_block/inode/file-operations + */ + +#include +#include + +void minix_put_inode(struct inode *inode) +{ + inode->i_size = 0; + minix_truncate(inode); + minix_free_inode(inode); +} + +/* + * These are the low-level inode operations for minix filesystem inodes. + */ +struct inode_operations minix_inode_operations = { + minix_create, + minix_lookup, + minix_link, + minix_unlink, + minix_symlink, + minix_mkdir, + minix_rmdir, + minix_mknod, + minix_rename, + minix_readlink, + minix_open, + minix_release, + minix_follow_link, + minix_bmap, + minix_truncate, + minix_write_inode, + minix_put_inode +}; + +/* + * We have mostly NULL's here: the current defaults are ok for + * the minix filesystem. + */ +struct file_operations minix_file_operations = { + NULL, /* lseek - default */ + minix_file_read, /* read */ + minix_file_write, /* write */ + NULL, /* readdir - bad */ + NULL, /* close - default */ + NULL, /* select - default */ + NULL /* ioctl - default */ +}; + +struct file_operations minix_dir_operations = { + NULL, /* lseek - default */ + minix_file_read, /* read */ + NULL, /* write - bad */ + minix_readdir, /* readdir */ + NULL, /* close - default */ + NULL, /* select - default */ + NULL /* ioctl - default */ +}; diff --git a/fs/minix/namei.c b/fs/minix/namei.c index a00c8cd54568..912b88319497 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -7,13 +7,13 @@ #include #include #include -#include -#include -#include #include +#include +#include #include #include +#include /* * comment out this line if you want names > MINIX_NAME_LEN chars to be @@ -103,6 +103,40 @@ static struct buffer_head * minix_find_entry(struct inode * dir, return NULL; } +struct inode * minix_follow_link(struct inode * dir, struct inode * inode) +{ + unsigned short fs; + struct buffer_head * bh; + + if (!dir) { + dir = current->root; + dir->i_count++; + } + if (!inode) { + iput(dir); + return NULL; + } + if (!S_ISLNK(inode->i_mode)) { + iput(dir); + return inode; + } + __asm__("mov %%fs,%0":"=r" (fs)); + if ((current->link_count > 5) || !inode->i_data[0] || + !(bh = bread(inode->i_dev, inode->i_data[0]))) { + iput(dir); + iput(inode); + return NULL; + } + iput(inode); + __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10)); + current->link_count++; + inode = _namei(bh->b_data,dir,1); + current->link_count--; + __asm__("mov %0,%%fs"::"r" (fs)); + brelse(bh); + return inode; +} + int minix_lookup(struct inode * dir,const char * name, int len, struct inode ** result) { @@ -215,13 +249,11 @@ int minix_create(struct inode * dir,const char * name, int len, int mode, iput(dir); return -ENOSPC; } - inode->i_op = &minix_file_inode_operations; inode->i_mode = mode; inode->i_dirt = 1; bh = minix_add_entry(dir,name,len,&de); if (!bh) { inode->i_nlink--; - inode->i_dirt = 1; iput(inode); iput(dir); return -ENOSPC; @@ -255,24 +287,6 @@ int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rd } inode->i_uid = current->euid; inode->i_mode = mode; - inode->i_op = NULL; - if (S_ISREG(inode->i_mode)) - inode->i_op = &minix_file_inode_operations; - else if (S_ISDIR(inode->i_mode)) - inode->i_op = &minix_dir_inode_operations; - else if (S_ISLNK(inode->i_mode)) - inode->i_op = &minix_symlink_inode_operations; - else if (S_ISCHR(inode->i_mode)) - inode->i_op = &minix_chrdev_inode_operations; - else if (S_ISBLK(inode->i_mode)) - inode->i_op = &minix_blkdev_inode_operations; - else if (S_ISFIFO(inode->i_mode)) { - inode->i_op = &minix_fifo_inode_operations; - inode->i_size = 0; - inode->i_pipe = 1; - PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; - PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; - } if (S_ISBLK(mode) || S_ISCHR(mode)) inode->i_rdev = rdev; inode->i_mtime = inode->i_atime = CURRENT_TIME; @@ -280,7 +294,6 @@ int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rd bh = minix_add_entry(dir,name,len,&de); if (!bh) { inode->i_nlink--; - inode->i_dirt = 1; iput(inode); iput(dir); return -ENOSPC; @@ -310,13 +323,12 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode) iput(dir); return -ENOSPC; } - inode->i_op = &minix_dir_inode_operations; inode->i_size = 2 * sizeof (struct minix_dir_entry); + inode->i_dirt = 1; inode->i_mtime = inode->i_atime = CURRENT_TIME; if (!(inode->i_data[0] = minix_new_block(inode->i_dev))) { iput(dir); inode->i_nlink--; - inode->i_dirt = 1; iput(inode); return -ENOSPC; } @@ -324,7 +336,6 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode) if (!(dir_block = bread(inode->i_dev,inode->i_data[0]))) { iput(dir); inode->i_nlink--; - inode->i_dirt = 1; iput(inode); return -EIO; } @@ -506,11 +517,10 @@ int minix_symlink(struct inode * dir, const char * name, int len, const char * s return -ENOSPC; } inode->i_mode = S_IFLNK | 0777; - inode->i_op = &minix_symlink_inode_operations; + inode->i_dirt = 1; if (!(inode->i_data[0] = minix_new_block(inode->i_dev))) { iput(dir); inode->i_nlink--; - inode->i_dirt = 1; iput(inode); return -ENOSPC; } @@ -518,7 +528,6 @@ int minix_symlink(struct inode * dir, const char * name, int len, const char * s if (!(name_block = bread(inode->i_dev,inode->i_data[0]))) { iput(dir); inode->i_nlink--; - inode->i_dirt = 1; iput(inode); return -EIO; } @@ -533,7 +542,6 @@ int minix_symlink(struct inode * dir, const char * name, int len, const char * s bh = minix_find_entry(dir,name,len,&de); if (bh) { inode->i_nlink--; - inode->i_dirt = 1; iput(inode); brelse(bh); iput(dir); @@ -542,7 +550,6 @@ int minix_symlink(struct inode * dir, const char * name, int len, const char * s bh = minix_add_entry(dir,name,len,&de); if (!bh) { inode->i_nlink--; - inode->i_dirt = 1; iput(inode); iput(dir); return -ENOSPC; @@ -660,10 +667,6 @@ start_up: old_inode = iget(old_dir->i_dev, old_de->inode); if (!old_inode) goto end_rename; - if ((old_dir->i_mode & S_ISVTX) && - current->euid != old_inode->i_uid && - current->euid != old_dir->i_uid && !suser()) - goto end_rename; new_bh = minix_find_entry(new_dir,new_name,new_len,&new_de); if (new_bh) { new_inode = iget(new_dir->i_dev, new_de->inode); @@ -676,10 +679,6 @@ start_up: retval = 0; goto end_rename; } - if (S_ISDIR(new_inode->i_mode)) { - retval = -EEXIST; - goto end_rename; - } if (S_ISDIR(old_inode->i_mode)) { retval = -EEXIST; if (new_bh) @@ -713,10 +712,8 @@ start_up: /* ok, that's it */ old_de->inode = 0; new_de->inode = old_inode->i_ino; - if (new_inode) { + if (new_inode) new_inode->i_nlink--; - new_inode->i_dirt = 1; - } old_bh->b_dirt = 1; new_bh->b_dirt = 1; if (dir_bh) { @@ -751,7 +748,7 @@ end_rename: int minix_rename(struct inode * old_dir, const char * old_name, int old_len, struct inode * new_dir, const char * new_name, int new_len) { - static struct wait_queue * wait = NULL; + static struct task_struct * wait = NULL; static int lock = 0; int result; @@ -764,3 +761,31 @@ int minix_rename(struct inode * old_dir, const char * old_name, int old_len, wake_up(&wait); return result; } + +int minix_readlink(struct inode * inode, char * buffer, int buflen) +{ + struct buffer_head * bh; + int i; + char c; + + if (!S_ISLNK(inode->i_mode)) { + iput(inode); + return -EINVAL; + } + if (buflen > 1023) + buflen = 1023; + if (inode->i_data[0]) + bh = bread(inode->i_dev, inode->i_data[0]); + else + bh = NULL; + iput(inode); + if (!bh) + return 0; + i = 0; + while (ib_data[i])) { + i++; + put_fs_byte(c,buffer++); + } + brelse(bh); + return i; +} diff --git a/fs/minix/symlink.c b/fs/minix/symlink.c deleted file mode 100644 index 1f99b07f33f7..000000000000 --- a/fs/minix/symlink.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * linux/fs/minix/symlink.c - * - * (C) 1991 Linus Torvalds - * - * minix symlink handling code - */ - -#include - -#include - -#include -#include -#include -#include - -static int minix_readlink(struct inode *, char *, int); -static struct inode * minix_follow_link(struct inode *, struct inode *); - -/* - * symlinks can't do much... - */ -struct inode_operations minix_symlink_inode_operations = { - NULL, /* no file-operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - minix_readlink, /* readlink */ - minix_follow_link, /* follow_link */ - NULL, /* bmap */ - NULL /* truncate */ -}; - -static struct inode * minix_follow_link(struct inode * dir, struct inode * inode) -{ - unsigned short fs; - struct buffer_head * bh; - - if (!dir) { - dir = current->root; - dir->i_count++; - } - if (!inode) { - iput(dir); - return NULL; - } - if (!S_ISLNK(inode->i_mode)) { - iput(dir); - return inode; - } - __asm__("mov %%fs,%0":"=r" (fs)); - if ((current->link_count > 5) || !inode->i_data[0] || - !(bh = bread(inode->i_dev, inode->i_data[0]))) { - iput(dir); - iput(inode); - return NULL; - } - iput(inode); - __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10)); - current->link_count++; - inode = _namei(bh->b_data,dir,1); - current->link_count--; - __asm__("mov %0,%%fs"::"r" (fs)); - brelse(bh); - return inode; -} - -static int minix_readlink(struct inode * inode, char * buffer, int buflen) -{ - struct buffer_head * bh; - int i; - char c; - - if (!S_ISLNK(inode->i_mode)) { - iput(inode); - return -EINVAL; - } - if (buflen > 1023) - buflen = 1023; - if (inode->i_data[0]) - bh = bread(inode->i_dev, inode->i_data[0]); - else - bh = NULL; - iput(inode); - if (!bh) - return 0; - i = 0; - while (ib_data[i])) { - i++; - put_fs_byte(c,buffer++); - } - brelse(bh); - return i; -} diff --git a/fs/minix/truncate.c b/fs/minix/truncate.c index e9c7a82dbf88..7df5268aa824 100644 --- a/fs/minix/truncate.c +++ b/fs/minix/truncate.c @@ -4,13 +4,13 @@ * (C) 1991 Linus Torvalds */ -#include - #include #include #include -#include -#include + +#include +#include +#include /* * Truncate has the most races in the whole filesystem: coding it is @@ -149,3 +149,50 @@ void minix_release(struct inode * inode, struct file * filp) { printk("minix_release not implemented\n"); } + +static int check_char_dev(struct inode * inode, struct file * filp) +{ + struct tty_struct *tty; + int min, dev; + + dev = inode->i_rdev; + if (MAJOR(dev) == 4 || MAJOR(dev) == 5) { + if (MAJOR(dev) == 5) + min = current->tty; + else + min = MINOR(dev); + if (min < 0) + return -1; + if ((IS_A_PTY_MASTER(min)) && (inode->i_count>1)) + return -1; + tty = TTY_TABLE(min); + if (!(filp->f_flags & O_NOCTTY) && + current->leader && + current->tty<0 && + tty->session==0) { + current->tty = min; + tty->session= current->session; + tty->pgrp = current->pgrp; + } + if (IS_A_SERIAL(min)) + serial_open(min-64); + } + return 0; +} + +/* + * Called every time a minix-file is opened + */ +int minix_open(struct inode * inode, struct file * filp) +{ + if (S_ISCHR(inode->i_mode)) { + if (check_char_dev(inode,filp)) + return -EAGAIN; + } else if (S_ISBLK(inode->i_mode)) + check_disk_change(inode->i_rdev); + else if (S_ISREG(inode->i_mode)) + filp->f_op = &minix_file_operations; + else if (S_ISDIR(inode->i_mode)) + filp->f_op = &minix_dir_operations; + return 0; +} diff --git a/fs/msdos/Makefile b/fs/msdos/Makefile deleted file mode 100644 index 204791e8aa9c..000000000000 --- a/fs/msdos/Makefile +++ /dev/null @@ -1,77 +0,0 @@ -# -# Makefile for the linux MS-DOS-filesystem routines. -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are now in the main makefile... - -.c.s: - $(CC) $(CFLAGS) \ - -S -o $*.s $< -.c.o: - $(CC) $(CFLAGS) -c -o $*.o $< -.s.o: - $(AS) -o $*.o $< - -OBJS= namei.o inode.o file.o dir.o misc.o fat.o - -msdos.o: $(OBJS) - $(LD) -r -o msdos.o $(OBJS) - -clean: - rm -f core *.o *.a tmp_make - for i in *.c;do rm -f `basename $$i .c`.s;done - -dep: - sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - (for i in *.c;do $(CPP) -M $$i;done) >> tmp_make - cp tmp_make Makefile - -### Dependencies: -dir.o : dir.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \ - /usr/src/linux/include/linux/wait.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h -fat.o : fat.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/stat.h \ - /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/kernel.h -file.o : file.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \ - /usr/src/linux/include/linux/wait.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/msdos_fs.h -inode.o : inode.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/string.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h \ - /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \ - /usr/src/linux/include/linux/wait.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h -misc.o : misc.c /usr/src/linux/include/errno.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/msdos_fs.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h -namei.o : namei.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/msdos_fs.h diff --git a/fs/msdos/dir.c b/fs/msdos/dir.c deleted file mode 100644 index 999610dab8b0..000000000000 --- a/fs/msdos/dir.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * linux/fs/msdos/dir.c - * - * Written 1992 by Werner Almesberger - * - * MS-DOS directory handling functions - */ - -#include -#include -#include -#include -#include - -/* for compatibility warnings */ -#include - -static int msdos_dummy_read(struct inode *inode,struct file *filp,char *buf, - int count); -static int msdos_readdir(struct inode *inode,struct file *filp, - struct dirent *dirent,int count); - - -static struct file_operations msdos_dir_operations = { - NULL, /* lseek - default */ - msdos_dummy_read, /* read */ - NULL, /* write - bad */ - msdos_readdir, /* readdir */ - NULL, /* select - default */ - NULL, /* ioctl - default */ - NULL, /* no special open code */ - NULL /* no special release code */ -}; - -struct inode_operations msdos_dir_inode_operations = { - &msdos_dir_operations, /* default directory file-ops */ - msdos_create, /* create */ - msdos_lookup, /* lookup */ - NULL, /* link */ - msdos_unlink, /* unlink */ - NULL, /* symlink */ - msdos_mkdir, /* mkdir */ - msdos_rmdir, /* rmdir */ - NULL, /* mknod */ - msdos_rename, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - msdos_bmap, /* bmap */ - NULL /* truncate */ -}; - - -/* So grep * doesn't complain in the presence of directories. */ - -static int msdos_dummy_read(struct inode *inode,struct file *filp,char *buf, - int count) -{ - static long last_warning = 0; - - if (CURRENT_TIME-last_warning >= 10) { - printk("COMPATIBILITY WARNING: reading a directory\r\n"); - last_warning = CURRENT_TIME; - } - return 0; -} - - -static int msdos_readdir(struct inode *inode,struct file *filp, - struct dirent *dirent,int count) -{ - int ino,i,i2,last; - char c,*walk; - struct buffer_head *bh; - struct msdos_dir_entry *de; - - if (!inode || !S_ISDIR(inode->i_mode)) return -EBADF; - if (inode->i_ino == MSDOS_ROOT_INO) { -/* Fake . and .. for the root directory. */ - if (filp->f_pos == 2) filp->f_pos = 0; - else if (filp->f_pos < 2) { - walk = filp->f_pos++ ? ".." : "."; - for (i = 0; *walk; walk++) - put_fs_byte(*walk,dirent->d_name+i++); - put_fs_long(MSDOS_ROOT_INO,&dirent->d_ino); - put_fs_byte(0,dirent->d_name+i); - put_fs_word(i,&dirent->d_reclen); - return i; - } - } - if (filp->f_pos & (sizeof(struct msdos_dir_entry)-1)) return -ENOENT; - bh = NULL; - while ((ino = msdos_get_entry(inode,&filp->f_pos,&bh,&de)) > -1) { - if (de->name[0] && ((unsigned char *) (de->name))[0] != - DELETED_FLAG && !(de->attr & ATTR_VOLUME)) { - for (i = last = 0; i < 8; i++) { - if (!(c = de->name[i])) break; - if (c >= 'A' && c <= 'Z') c += 32; - if (c != ' ') last = i+1; - put_fs_byte(c,i+dirent->d_name); - } - i = last; - if (de->ext[0] && de->ext[0] != ' ') { - put_fs_byte('.',i+dirent->d_name); - i++; - for (i2 = 0; i2 < 3; i2++) { - if (!(c = de->ext[i2])) break; - if (c >= 'A' && c <= 'Z') c += 32; - put_fs_byte(c,i+dirent->d_name); - i++; - if (c != ' ') last = i; - } - } - if (i = last) { - if (!strcmp(de->name,MSDOS_DOT)) - ino = inode->i_ino; - else if (!strcmp(de->name,MSDOS_DOTDOT)) - ino = msdos_parent_ino(inode,0); - put_fs_long(ino,&dirent->d_ino); - put_fs_byte(0,i+dirent->d_name); - put_fs_word(i,&dirent->d_reclen); - brelse(bh); - return i; - } - } - } - if (bh) brelse(bh); - return 0; -} diff --git a/fs/msdos/fat.c b/fs/msdos/fat.c deleted file mode 100644 index 7336ca636714..000000000000 --- a/fs/msdos/fat.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * linux/fs/msdos/fat.c - * - * Written 1992 by Werner Almesberger - */ - -#include -#include -#include -#include - - -static struct fat_cache *fat_cache,cache[FAT_CACHE]; - - -/* Returns the this'th FAT entry, -1 if it is an end-of-file entry. If - new_value is != -1, that FAT entry is replaced by it. */ - -int fat_access(struct super_block *sb,int this,int new_value) -{ - struct buffer_head *bh,*bh2,*c_bh,*c_bh2; - unsigned char *p_first,*p_last; - void *data,*data2,*c_data,*c_data2; - int first,last,next,copy; - - if (MSDOS_SB(sb)->fat_bits == 16) first = last = this*2; - else { - first = this*3/2; - last = first+1; - } - if (!(bh = msdos_sread(sb->s_dev,MSDOS_SB(sb)->fat_start+(first >> - SECTOR_BITS),&data))) { - printk("bread in fat_access failed\r\n"); - return 0; - } - if ((first >> SECTOR_BITS) == (last >> SECTOR_BITS)) { - bh2 = bh; - data2 = data; - } - else { - if (!(bh2 = msdos_sread(sb->s_dev,MSDOS_SB(sb)->fat_start+(last - >> SECTOR_BITS),&data2))) { - brelse(bh); - printk("bread in fat_access failed\r\n"); - return 0; - } - } - if (MSDOS_SB(sb)->fat_bits == 16) { - next = ((unsigned short *) data)[(first & (SECTOR_SIZE-1)) - >> 1]; - if (next >= 0xfff8) next = -1; - } - else { - p_first = &((unsigned char *) data)[first & (SECTOR_SIZE-1)]; - p_last = &((unsigned char *) data2)[(first+1) & - (SECTOR_SIZE-1)]; - if (this & 1) next = ((*p_first >> 4) | (*p_last << 4)) & 0xfff; - else next = (*p_first+(*p_last << 8)) & 0xfff; - if (next >= 0xff8) next = -1; - } - if (new_value != -1) { - if (MSDOS_SB(sb)->fat_bits == 16) - ((unsigned short *) data)[(first & (SECTOR_SIZE-1)) >> - 1] = new_value; - else { - if (this & 1) { - *p_first = (*p_first & 0xf) | (new_value << 4); - *p_last = new_value >> 4; - } - else { - *p_first = new_value & 0xff; - *p_last = (*p_last & 0xf0) | (new_value >> 8); - } - bh2->b_dirt = 1; - } - bh->b_dirt = 1; - for (copy = 1; copy < MSDOS_SB(sb)->fats; copy++) { - if (!(c_bh = msdos_sread(sb->s_dev,MSDOS_SB(sb)-> - fat_start+(first >> SECTOR_BITS)+MSDOS_SB(sb)-> - fat_length*copy,&c_data))) break; - memcpy(c_data,data,SECTOR_SIZE); - c_bh->b_dirt = 1; - if (data != data2 || bh != bh2) { - if (!(c_bh2 = msdos_sread(sb->s_dev, - MSDOS_SB(sb)->fat_start+(first >> - SECTOR_BITS)+MSDOS_SB(sb)->fat_length*copy - +1,&c_data2))) { - brelse(c_bh); - break; - } - memcpy(c_data2,data2,SECTOR_SIZE); - brelse(c_bh2); - } - brelse(c_bh); - } - } - brelse(bh); - if (data != data2) brelse(bh2); - return next; -} - - -void cache_init(void) -{ - static int initialized = 0; - int count; - - if (initialized) return; - fat_cache = &cache[0]; - for (count = 0; count < FAT_CACHE; count++) { - cache[count].device = 0; - cache[count].next = count == FAT_CACHE-1 ? NULL : - &cache[count+1]; - } - initialized = 1; -} - - -void cache_lookup(struct inode *inode,int cluster,int *f_clu,int *d_clu) -{ - struct fat_cache *walk; - -#ifdef DEBUG -printk("cache lookup: %d\r\n",*f_clu); -#endif - for (walk = fat_cache; walk; walk = walk->next) - if (inode->i_dev == walk->device && walk->ino == inode->i_ino && - walk->file_cluster <= cluster && walk->file_cluster > - *f_clu) { - *d_clu = walk->disk_cluster; -#ifdef DEBUG -printk("cache hit: %d (%d)\r\n",walk->file_cluster,*d_clu); -#endif - if ((*f_clu = walk->file_cluster) == cluster) return; - } -} - - -#ifdef DEBUG -static void list_cache(void) -{ - struct fat_cache *walk; - - for (walk = fat_cache; walk; walk = walk->next) { - if (walk->device) printk("(%d,%d) ",walk->file_cluster, - walk->disk_cluster); - else printk("-- "); - } - printk("\r\n"); -} -#endif - - -void cache_add(struct inode *inode,int f_clu,int d_clu) -{ - struct fat_cache *walk,*last; - -#ifdef DEBUG -printk("cache add: %d (%d)\r\n",f_clu,d_clu); -#endif - last = NULL; - for (walk = fat_cache; walk->next; walk = (last = walk)->next) - if (inode->i_dev == walk->device && walk->ino == inode->i_ino && - walk->file_cluster == f_clu) { - if (walk->disk_cluster != d_clu) - panic("FAT cache corruption"); - /* update LRU */ - if (last == NULL) return; - last->next = walk->next; - walk->next = fat_cache; - fat_cache = walk; -#ifdef DEBUG -list_cache(); -#endif - return; - } - walk->device = inode->i_dev; - walk->ino = inode->i_ino; - walk->file_cluster = f_clu; - walk->disk_cluster = d_clu; - last->next = NULL; - walk->next = fat_cache; - fat_cache = walk; -#ifdef DEBUG -list_cache(); -#endif -} - - -/* Cache invalidation occurs rarely, thus the LRU chain is not updated. It - fixes itself after a while. */ - -void cache_inval_inode(struct inode *inode) -{ - struct fat_cache *walk; - - for (walk = fat_cache; walk; walk = walk->next) - if (walk->device == inode->i_dev && walk->ino == inode->i_ino) - walk->device = 0; -} - - -void cache_inval_dev(int device) -{ - struct fat_cache *walk; - - for (walk = fat_cache; walk; walk = walk->next) - if (walk->device == device) walk->device = 0; -} - - -int get_cluster(struct inode *inode,int cluster) -{ - int this,count; - - if (!(this = inode->i_data[D_START])) return 0; - if (!cluster) return this; - count = 0; - for (cache_lookup(inode,cluster,&count,&this); count < cluster; - count++) { - if ((this = fat_access(inode->i_sb,this,-1)) == -1) return 0; - if (!this) return 0; - } - cache_add(inode,cluster,this); - return this; -} - - -int msdos_smap(struct inode *inode,int sector) -{ - struct msdos_sb_info *sb; - int cluster,offset; - - sb = MSDOS_SB(inode->i_sb); - if (inode->i_ino == MSDOS_ROOT_INO || (S_ISDIR(inode->i_mode) && - !inode->i_data[D_START])) { - if (sector >= sb->dir_entries >> MSDOS_DPS_BITS) return 0; - return sector+sb->dir_start; - } - cluster = sector/sb->cluster_size; - offset = sector % sb->cluster_size; - if (!(cluster = get_cluster(inode,cluster))) return 0; - return (cluster-2)*sb->cluster_size+sb->data_start+offset; -} - - -/* Free all clusters after the skip'th cluster. Doesn't use the cache, - because this way we get an additional sanity check. */ - -int fat_free(struct inode *inode,int skip) -{ - int this,last; - - if (!(this = inode->i_data[D_START])) return 0; - last = 0; - while (skip--) { - last = this; - if ((this = fat_access(inode->i_sb,this,-1)) == -1) - return 0; - if (!this) { - printk("fat_free: skipped EOF\r\n"); - return -EIO; - } - } - if (last) - fat_access(inode->i_sb,last,MSDOS_SB(inode->i_sb)->fat_bits == - 12 ? 0xff8 : 0xfff8); - else { - inode->i_data[D_START] = 0; - inode->i_dirt = 1; - } - while (this != -1) - if (!(this = fat_access(inode->i_sb,this,0))) - panic("fat_free: deleting beyond EOF"); - cache_inval_inode(inode); - return 0; -} diff --git a/fs/msdos/file.c b/fs/msdos/file.c deleted file mode 100644 index 449b40d05617..000000000000 --- a/fs/msdos/file.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * linux/fs/msdos/file.c - * - * Written 1992 by Werner Almesberger - * - * MS-DOS regular file handling primitives - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) - - -static int msdos_file_read(struct inode *inode,struct file *filp,char *buf, - int count); -static int msdos_file_write(struct inode *inode,struct file *filp,char *buf, - int count); - - -static struct file_operations msdos_file_operations = { - NULL, /* lseek - default */ - msdos_file_read, /* read */ - msdos_file_write, /* write */ - NULL, /* readdir - bad */ - NULL, /* select - default */ - NULL, /* ioctl - default */ - NULL, /* no special open is needed */ - NULL /* release */ -}; - -struct inode_operations msdos_file_inode_operations = { - &msdos_file_operations, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - msdos_bmap, /* bmap */ - msdos_truncate /* truncate */ -}; - -/* No bmap for MS-DOS FS' that don't align data at kByte boundaries. */ - -struct inode_operations msdos_file_inode_operations_no_bmap = { - &msdos_file_operations, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* bmap */ - msdos_truncate /* truncate */ -}; - - -static int msdos_file_read(struct inode *inode,struct file *filp,char *buf, - int count) -{ - char *start; - int left,offset,size,sector,cnt; - char ch; - struct buffer_head *bh; - void *data; - -/* printk("msdos_file_read\r\n"); */ - if (!inode) { - printk("msdos_file_read: inode = NULL\r\n"); - return -EINVAL; - } - if (!S_ISREG(inode->i_mode)) { - printk("msdos_file_read: mode = %07o\n",inode->i_mode); - return -EINVAL; - } - if (filp->f_pos >= inode->i_size || count <= 0) return 0; - start = buf; - while (left = MIN(inode->i_size-filp->f_pos,count-(buf-start))) { - if (!(sector = msdos_smap(inode,filp->f_pos >> SECTOR_BITS))) - break; - offset = filp->f_pos & (SECTOR_SIZE-1); - if (!(bh = msdos_sread(inode->i_dev,sector,&data))) break; - filp->f_pos += (size = MIN(SECTOR_SIZE-offset,left)); - if (inode->i_data[D_BINARY]) { - memcpy_tofs(buf,data+offset,size); - buf += size; - } - else for (cnt = size; cnt; cnt--) { - if ((ch = *((char *) data+offset++)) == '\r') - size--; - else { - if (ch != 26) put_fs_byte(ch,buf++); - else { - filp->f_pos = inode->i_size; - brelse(bh); - return buf-start; - } - } - } - brelse(bh); - } - if (start == buf) return -EIO; - return buf-start; -} - - -static int msdos_file_write(struct inode *inode,struct file *filp,char *buf, - int count) -{ - int sector,offset,size,left,written; - int error,carry; - char *start,*to,ch; - struct buffer_head *bh; - void *data; - - if (!inode) { - printk("msdos_file_write: inode = NULL\n"); - return -EINVAL; - } - if (!S_ISREG(inode->i_mode)) { - printk("msdos_file_write: mode = %07o\n",inode->i_mode); - return -EINVAL; - } -/* - * ok, append may not work when many processes are writing at the same time - * but so what. That way leads to madness anyway. - */ - if (filp->f_flags & O_APPEND) filp->f_pos = inode->i_size; - if (count <= 0) return 0; - error = carry = 0; - for (start = buf; count || carry; count -= size) { - while (!(sector = msdos_smap(inode,filp->f_pos >> SECTOR_BITS))) - if ((error = msdos_add_cluster(inode)) < 0) break; - if (error) break; - offset = filp->f_pos & (SECTOR_SIZE-1); - size = MIN(SECTOR_SIZE-offset,MAX(carry,count)); - if (!(bh = msdos_sread(inode->i_dev,sector,&data))) { - error = -EIO; - break; - } - if (inode->i_data[D_BINARY]) { - memcpy_fromfs(data+(filp->f_pos & (SECTOR_SIZE-1)), - buf,written = size); - buf += size; - } - else { - written = left = SECTOR_SIZE-offset; - to = data+(filp->f_pos & (SECTOR_SIZE-1)); - if (carry) { - *to++ = '\n'; - left--; - carry = 0; - } - for (size = 0; size < count && left; size++) { - if ((ch = get_fs_byte(buf++)) == '\n') { - *to++ = '\r'; - left--; - } - if (!left) carry = 1; - else { - *to++ = ch; - left--; - } - } - written -= left; - } - filp->f_pos += written; - if (filp->f_pos > inode->i_size) { - inode->i_size = filp->f_pos; - inode->i_dirt = 1; - } - bh->b_dirt = 1; - brelse(bh); - } - inode->i_mtime = inode->i_ctime = CURRENT_TIME; - inode->i_data[D_ATTRS] |= ATTR_ARCH; - inode->i_dirt = 1; - return start == buf ? error : buf-start; -} - - -void msdos_truncate(struct inode *inode) -{ - int cluster; - - if (!S_ISREG(inode->i_mode)) return; - cluster = SECTOR_SIZE*MSDOS_SB(inode->i_sb)->cluster_size; - (void) fat_free(inode,(inode->i_size+(cluster-1))/cluster); - inode->i_data[D_ATTRS] |= ATTR_ARCH; - inode->i_dirt = 1; -} diff --git a/fs/msdos/inode.c b/fs/msdos/inode.c deleted file mode 100644 index 0b43c7284156..000000000000 --- a/fs/msdos/inode.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * linux/fs/msdos/inode.c - * - * Written 1992 by Werner Almesberger - */ - -#include -#include -#include -#include -#include -#include -#include - - -void msdos_put_inode(struct inode *inode) -{ - struct inode *depend; - - inode->i_size = 0; - msdos_truncate(inode); - depend = (struct inode *) inode->i_data[D_DEPEND]; - memset(inode,0,sizeof(struct inode)); - if (depend) { - if ((struct inode *) depend->i_data[D_OLD] != inode) { - printk("Invalid link (0x%X): expected 0x%X, got " - "0x%X\r\n",(int) depend,(int) inode, - depend->i_data[D_OLD]); - panic("That's fatal"); - } - depend->i_data[D_OLD] = 0; - iput(depend); - } -} - - -void msdos_put_super(struct super_block *sb) -{ - cache_inval_dev(sb->s_dev); - lock_super(sb); - sb->s_dev = 0; - free_super(sb); - return; -} - - -static struct super_operations msdos_sops = { - msdos_read_inode, - msdos_write_inode, - msdos_put_inode, - msdos_put_super, - NULL, /* added in 0.96c */ - msdos_statfs -}; - - -static int parse_options(char *options,char *check,char *conversion) -{ - char *this,*value; - - *check = 'n'; - *conversion = 'b'; - if (!options) return 1; - for (this = strtok(options,","); this; this = strtok(NULL,",")) { - if (value = strchr(this,'=')) *value++ = 0; - if (!strcmp(this,"check") && value) { - if (value[0] && !value[1] && strchr("rns",*value)) - *check = *value; - else if (!strcmp(value,"releaxed")) *check = 'r'; - else if (!strcmp(value,"normal")) *check = 'n'; - else if (!strcmp(value,"strict")) *check = 's'; - else return 0; - } - else if (!strcmp(this,"conv") && value) { - if (value[0] && !value[1] && strchr("bta",*value)) - *conversion = *value; - else if (!strcmp(value,"binary")) *conversion = 'b'; - else if (!strcmp(value,"text")) *conversion = 't'; - else if (!strcmp(value,"auto")) *conversion = 'a'; - else return 0; - } - else return 0; - } - return 1; -} - - -/* Read the super block of an MS-DOS FS. */ - -struct super_block *msdos_read_super(struct super_block *s,void *data) -{ - struct buffer_head *bh; - struct msdos_boot_sector *b; - int data_sectors; - char check,conversion; - - if (!parse_options((char *) data,&check,&conversion)) { - s->s_dev = 0; - return NULL; - } - cache_init(); - lock_super(s); - bh = bread(s->s_dev,0); - free_super(s); - if (bh == NULL) { - s->s_dev = 0; - printk("MSDOS bread failed\r\n"); - return NULL; - } - b = (struct msdos_boot_sector *) bh->b_data; - MSDOS_SB(s)->cluster_size = b->cluster_size; - MSDOS_SB(s)->fats = b->fats; - MSDOS_SB(s)->fat_start = b->reserved; - MSDOS_SB(s)->fat_length = b->fat_length; - MSDOS_SB(s)->dir_start = b->reserved+b->fats*b->fat_length; - MSDOS_SB(s)->dir_entries = *((unsigned short *) &b->dir_entries); - MSDOS_SB(s)->data_start = MSDOS_SB(s)->dir_start+((MSDOS_SB(s)-> - dir_entries << 5) >> 9); - data_sectors = (*((unsigned short *) &b->sectors) ? *((unsigned short *) - &b->sectors) : b->total_sect)-MSDOS_SB(s)->data_start; - MSDOS_SB(s)->clusters = b->cluster_size ? data_sectors/b->cluster_size : - 0; - MSDOS_SB(s)->fat_bits = MSDOS_SB(s)->clusters > MSDOS_FAT12 ? 16 : 12; - brelse(bh); -printk("[MS-DOS FS Rel. alpha.5, FAT %d, check=%c, conv=%c]\r\n", - MSDOS_SB(s)->fat_bits,check,conversion); -printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,se=%d,ts=%d]\r\n", - b->media,MSDOS_SB(s)->cluster_size,MSDOS_SB(s)->fats,MSDOS_SB(s)->fat_start, - MSDOS_SB(s)->fat_length,MSDOS_SB(s)->dir_start,MSDOS_SB(s)->dir_entries, - MSDOS_SB(s)->data_start,*(unsigned short *) &b->sectors,b->total_sect); - if (!MSDOS_SB(s)->fats || (MSDOS_SB(s)->dir_entries & (MSDOS_DPS-1)) - || !b->cluster_size || MSDOS_SB(s)->clusters+2 > MSDOS_SB(s)-> - fat_length*SECTOR_SIZE*8/MSDOS_SB(s)->fat_bits) { - s->s_dev = 0; - printk("Unsupported FS parameters\r\n"); - return NULL; - } - if (!MSDOS_CAN_BMAP(MSDOS_SB(s))) printk("No bmap support\r\n"); - s->s_magic = MSDOS_SUPER_MAGIC; - MSDOS_SB(s)->name_check = check; - MSDOS_SB(s)->conversion = conversion; - /* set up enough so that it can read an inode */ - s->s_op = &msdos_sops; - MSDOS_SB(s)->fs_uid = current->uid; - MSDOS_SB(s)->fs_gid = current->gid; - MSDOS_SB(s)->fs_umask = current->umask; - if (!(s->s_mounted = iget(s->s_dev,MSDOS_ROOT_INO))) { - s->s_dev = 0; - printk("get root inode failed\n"); - return NULL; - } - return s; -} - - -void msdos_statfs(struct super_block *sb,struct statfs *buf) -{ - int cluster_size,free,this; - - cluster_size = MSDOS_SB(sb)->cluster_size; - put_fs_long(sb->s_magic,&buf->f_type); - put_fs_long(SECTOR_SIZE,&buf->f_bsize); - put_fs_long(MSDOS_SB(sb)->clusters*cluster_size,&buf->f_blocks); - free = 0; - for (this = 2; this < MSDOS_SB(sb)->clusters+2; this++) - if (!fat_access(sb,this,-1)) free++; - free *= cluster_size; - put_fs_long(free,&buf->f_bfree); - put_fs_long(free,&buf->f_bavail); - put_fs_long(0,&buf->f_files); - put_fs_long(0,&buf->f_ffree); -} - - -int msdos_bmap(struct inode *inode,int block) -{ - struct msdos_sb_info *sb; - int cluster,offset; - - sb = MSDOS_SB(inode->i_sb); - if ((sb->cluster_size & 1) || (sb->data_start & 1)) return 0; - if (inode->i_ino == MSDOS_ROOT_INO) { - if (sb->dir_start & 1) return 0; - return (sb->dir_start >> 1)+block; - } - cluster = (block*2)/sb->cluster_size; - offset = (block*2) % sb->cluster_size; - if (!(cluster = get_cluster(inode,cluster))) return 0; - return ((cluster-2)*sb->cluster_size+sb->data_start+offset) >> 1; -} - - -void msdos_read_inode(struct inode *inode) -{ - struct buffer_head *bh; - struct msdos_dir_entry *raw_entry; - int this; - -/* printk("read inode %d\r\n",inode->i_ino); */ - inode->i_data[D_BUSY] = inode->i_data[D_DEPEND] = - inode->i_data[D_OLD] = 0; - inode->i_data[D_BINARY] = 1; - inode->i_uid = MSDOS_SB(inode->i_sb)->fs_uid; - inode->i_gid = MSDOS_SB(inode->i_sb)->fs_gid; - if (inode->i_ino == MSDOS_ROOT_INO) { - inode->i_mode = (0777 & ~MSDOS_SB(inode->i_sb)->fs_umask) | - S_IFDIR; - inode->i_op = &msdos_dir_inode_operations; - inode->i_nlink = 1; - inode->i_size = MSDOS_SB(inode->i_sb)->dir_entries* - sizeof(struct msdos_dir_entry); - inode->i_data[D_START] = 0; - inode->i_data[D_ATTRS] = 0; - inode->i_mtime = inode->i_atime = inode->i_ctime = 0; - return; - } - if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS))) - panic("unable to read i-node block"); - raw_entry = &((struct msdos_dir_entry *) (bh->b_data)) - [inode->i_ino & (MSDOS_DPB-1)]; - if (raw_entry->attr & ATTR_DIR) { - inode->i_mode = MSDOS_MKMODE(raw_entry->attr,0777 & - ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IFDIR; - inode->i_op = &msdos_dir_inode_operations; - inode->i_nlink = 3; - inode->i_size = 0; - for (this = raw_entry->start; this && this != -1; this = - fat_access(inode->i_sb,this,-1)) - inode->i_size += SECTOR_SIZE*MSDOS_SB(inode->i_sb)-> - cluster_size; - } - else { - inode->i_mode = MSDOS_MKMODE(raw_entry->attr,0666 & - ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IFREG; - inode->i_op = MSDOS_CAN_BMAP(MSDOS_SB(inode->i_sb)) ? - &msdos_file_inode_operations : - &msdos_file_inode_operations_no_bmap; - inode->i_nlink = 1; - inode->i_size = raw_entry->size; - } - inode->i_data[D_BINARY] = is_binary(MSDOS_SB(inode->i_sb)->conversion, - raw_entry->ext); - inode->i_data[D_START] = raw_entry->start; - inode->i_data[D_ATTRS] = raw_entry->attr & ATTR_UNUSED; - inode->i_mtime = inode->i_atime = inode->i_ctime = - date_dos2unix(raw_entry->time,raw_entry->date); - brelse(bh); -} - - -void msdos_write_inode(struct inode *inode) -{ - struct buffer_head *bh; - struct msdos_dir_entry *raw_entry; - - inode->i_dirt = 0; - if (inode->i_ino == MSDOS_ROOT_INO || !inode->i_nlink) return; - if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS))) - panic("unable to read i-node block"); - raw_entry = &((struct msdos_dir_entry *) (bh->b_data)) - [inode->i_ino & (MSDOS_DPB-1)]; - if (S_ISDIR(inode->i_mode)) { - raw_entry->attr = ATTR_DIR; - raw_entry->size = 0; - } - else { - raw_entry->attr = ATTR_NONE; - raw_entry->size = inode->i_size; - } - raw_entry->attr |= MSDOS_MKATTR(inode->i_mode) | inode->i_data[D_ATTRS]; - raw_entry->start = inode->i_data[D_START]; - date_unix2dos(inode->i_mtime,&raw_entry->time,&raw_entry->date); - bh->b_dirt = 1; - brelse(bh); -} diff --git a/fs/msdos/misc.c b/fs/msdos/misc.c deleted file mode 100644 index 563be034cce3..000000000000 --- a/fs/msdos/misc.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * linux/fs/msdos/misc.c - * - * Written 1992 by Werner Almesberger - */ - -#include -#include -#include -#include -#include -#include -#include - - -static char bin_extensions[] = - "EXECOMAPPSYSOVLOBJLIB" /* program code */ - "ARCZIPLHALZHZOOTARZ ARJ" /* common archivers */ - "GIFBMPTIFGL JPG" /* graphics */ - "TFMVF GF PK PXLDVI"; /* TeX */ - - -/* Select binary/text conversion */ - -int is_binary(char conversion,char *extension) -{ - char *walk; - - switch (conversion) { - case 'b': - return 1; - case 't': - return 0; - case 'a': - for (walk = bin_extensions; *walk; walk += 3) - if (!strncmp(extension,walk,3)) return 1; - return 0; - default: - panic("Invalid conversion mode"); - } -} - - -static struct wait_queue *creation_wait = NULL; -static creation_lock = 0; - - -void lock_creation(void) -{ - while (creation_lock) sleep_on(&creation_wait); - creation_lock = 1; -} - - -void unlock_creation(void) -{ - creation_lock = 0; - wake_up(&creation_wait); -} - - -int msdos_add_cluster(struct inode *inode) -{ - static struct wait_queue *wait = NULL; - static int lock = 0; - static int previous = 0; /* works best if one FS is being used */ - int count,this,limit,last,current,sector; - void *data; - struct buffer_head *bh; - - if (inode->i_ino == MSDOS_ROOT_INO) return -ENOSPC; - while (lock) sleep_on(&wait); - lock = 1; - limit = MSDOS_SB(inode->i_sb)->clusters; - this = limit; /* to keep GCC happy */ - for (count = 0; count < limit; count++) { - this = ((count+previous) % limit)+2; - if (fat_access(inode->i_sb,this,-1) == 0) break; - } -#ifdef DEBUG -printk("free cluster: %d\r\n",this); -#endif - previous = (count+previous+1) % limit; - if (count >= limit) { - lock = 0; - wake_up(&wait); - return -ENOSPC; - } - fat_access(inode->i_sb,this,MSDOS_SB(inode->i_sb)->fat_bits == 12 ? - 0xff8 : 0xfff8); - lock = 0; - wake_up(&wait); -#ifdef DEBUG -printk("set to %x\r\n",fat_access(inode->i_sb,this,-1)); -#endif - if (!S_ISDIR(inode->i_mode)) { - last = inode->i_size ? get_cluster(inode,(inode->i_size-1)/ - SECTOR_SIZE/MSDOS_SB(inode->i_sb)->cluster_size) : 0; - } - else { - last = 0; - if (current = inode->i_data[D_START]) { - cache_lookup(inode,INT_MAX,&last,¤t); - while (current && current != -1) - if (!(current = fat_access(inode->i_sb, - last = current,-1))) - panic("File without EOF"); - } - } -#ifdef DEBUG -printk("last = %d\r\n",last); -#endif - if (last) fat_access(inode->i_sb,last,this); - else { - inode->i_data[D_START] = this; - inode->i_dirt = 1; - } -#ifdef DEBUG -if (last) printk("next set to %d\r\n",fat_access(inode->i_sb,last,-1)); -#endif - for (current = 0; current < MSDOS_SB(inode->i_sb)->cluster_size; - current++) { - sector = MSDOS_SB(inode->i_sb)->data_start+(this-2)* - MSDOS_SB(inode->i_sb)->cluster_size+current; -#ifdef DEBUG -printk("zeroing sector %d\r\n",sector); -#endif - if (current < MSDOS_SB(inode->i_sb)->cluster_size-1 && - !(sector & 1)) { - if (!(bh = getblk(inode->i_dev,sector >> 1))) - printk("getblk failed\r\n"); - else { - memset(bh->b_data,0,BLOCK_SIZE); - bh->b_uptodate = 1; - } - current++; - } - else { - if (!(bh = msdos_sread(inode->i_dev,sector,&data))) - printk("msdos_sread failed\r\n"); - else memset(data,0,SECTOR_SIZE); - } - if (bh) { - bh->b_dirt = 1; - brelse(bh); - } - } - if (S_ISDIR(inode->i_mode)) { - if (inode->i_size & (SECTOR_SIZE-1)) - panic("Odd directory size"); - inode->i_size += SECTOR_SIZE*MSDOS_SB(inode->i_sb)-> - cluster_size; -#ifdef DEBUG -printk("size is %d now (%x)\r\n",inode->i_size,inode); -#endif - inode->i_dirt = 1; - } - return 0; -} - - -/* Linear day numbers of the respective 1sts in non-leap years. */ - -static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 }; - /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */ - - -/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */ - -int date_dos2unix(unsigned short time,unsigned short date) -{ - int month,year; - - month = ((date >> 5) & 4)-1; - year = date >> 9; - return (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400* - ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 && - month < 2 ? 1 : 0)+3653); - /* days since 1.1.70 plus 80's leap day */ -} - - -/* Convert linear UNIX date to a MS-DOS time/date pair. */ - -void date_unix2dos(int unix_date,unsigned short *time, - unsigned short *date) -{ - int day,year,nl_day,month; - - *time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+ - (((unix_date/3600) % 24) << 11); - day = unix_date/86400-3652; - year = day/365; - if ((year+3)/4+365*year > day) year--; - day -= (year+3)/4+365*year; - if (day == 59 && !(year & 3)) { - nl_day = day; - month = 2; - } - else { - nl_day = (year & 3) || day <= 59 ? day : day-1; - for (month = 0; month < 12; month++) - if (day_n[month] > nl_day) break; - } - *date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9); -} - - -/* Returns the inode number of the directory entry at offset pos. If bh is - non-NULL, it is brelse'd before. Pos is incremented. The buffer header is - returned in bh. */ - -int msdos_get_entry(struct inode *dir,int *pos,struct buffer_head **bh, - struct msdos_dir_entry **de) -{ - int sector,offset; - void *data; - - while (1) { - offset = *pos; - if ((sector = msdos_smap(dir,*pos >> SECTOR_BITS)) == -1) - return -1; - if (!sector) return -1; /* FAT error ... */ - *pos += sizeof(struct msdos_dir_entry); - if (*bh) brelse(*bh); - if (!(*bh = msdos_sread(dir->i_dev,sector,&data))) continue; - *de = (struct msdos_dir_entry *) (data+(offset & - (SECTOR_SIZE-1))); - return (sector << MSDOS_DPS_BITS)+((offset & (SECTOR_SIZE-1)) >> - MSDOS_DIR_BITS); - } -} - - -/* Scans a directory for a given file (name points to its formatted name) or - for an empty directory slot (name is NULL). Returns the inode number. */ - -int msdos_scan(struct inode *dir,char *name,struct buffer_head **res_bh, - struct msdos_dir_entry **res_de,int *ino) -{ - int pos; - struct msdos_dir_entry *de; - struct inode *inode; - - pos = 0; - *res_bh = NULL; - while ((*ino = msdos_get_entry(dir,&pos,res_bh,&de)) > -1) { - if (name) { - if (de->name[0] && ((unsigned char *) (de->name))[0] - != DELETED_FLAG && !(de->attr & ATTR_VOLUME) && - !strncmp(de->name,name,MSDOS_NAME)) break; - } - else if (!de->name[0] || ((unsigned char *) (de->name))[0] == - DELETED_FLAG) { - if (!(inode = iget(dir->i_dev,*ino))) break; - if (!inode->i_data[D_BUSY]) { - iput(inode); - break; - } - /* skip deleted files that haven't been closed yet */ - iput(inode); - } - } - if (*ino == -1) { - if (*res_bh) brelse(*res_bh); - *res_bh = NULL; - return name ? -ENOENT : -ENOSPC; - } - *res_de = de; - return 0; -} - - -/* Now an ugly part: this set of directory scan routines works on clusters - rather than on inodes and sectors. They are necessary to locate the '..' - directory "inode". */ - - -static int raw_found(struct super_block *sb,int sector,char *name,int number, - int *ino) -{ - struct buffer_head *bh; - struct msdos_dir_entry *data; - int entry,start; - - if (!(bh = msdos_sread(sb->s_dev,sector,(void **) &data))) return -EIO; - for (entry = 0; entry < MSDOS_DPS; entry++) - if (name ? !strncmp(data[entry].name,name,MSDOS_NAME) : - *(unsigned char *) data[entry].name != DELETED_FLAG && - data[entry].start == number) { - if (ino) *ino = sector*MSDOS_DPS+entry; - start = data[entry].start; - brelse(bh); - return start; - } - brelse(bh); - return -1; -} - - -static int raw_scan_root(struct super_block *sb,char *name,int number,int *ino) -{ - int count,cluster; - - for (count = 0; count < MSDOS_SB(sb)->dir_entries/MSDOS_DPS; count++) { - if ((cluster = raw_found(sb,MSDOS_SB(sb)->dir_start+count,name, - number,ino)) >= 0) return cluster; - } - return -ENOENT; -} - - -static int raw_scan_nonroot(struct super_block *sb,int start,char *name, - int number,int *ino) -{ - int count,cluster; - - do { - for (count = 0; count < MSDOS_SB(sb)->cluster_size; count++) { - if ((cluster = raw_found(sb,(start-2)*MSDOS_SB(sb)-> - cluster_size+MSDOS_SB(sb)->data_start+count,name, - number,ino)) >= 0) return cluster; - } - if (!(start = fat_access(sb,start,-1))) panic("FAT error"); - } - while (start != -1); - return -ENOENT; -} - - -static int raw_scan(struct super_block *sb,int start,char *name,int number, - int *ino) -{ - if (start) return raw_scan_nonroot(sb,start,name,number,ino); - else return raw_scan_root(sb,name,number,ino); -} - - -int msdos_parent_ino(struct inode *dir,int locked) -{ - int error,current,prev,this; - - if (!S_ISDIR(dir->i_mode)) panic("Non-directory fed to m_p_i"); - if (dir->i_ino == MSDOS_ROOT_INO) return dir->i_ino; - if (!locked) lock_creation(); /* prevent renames */ - if ((current = raw_scan(dir->i_sb,dir->i_data[D_START],MSDOS_DOTDOT,0, - NULL)) < 0) { - if (!locked) unlock_creation(); - return current; - } - if (!current) this = MSDOS_ROOT_INO; - else { - if ((prev = raw_scan(dir->i_sb,current,MSDOS_DOTDOT,0,NULL)) < - 0) { - if (!locked) unlock_creation(); - return prev; - } - if ((error = raw_scan(dir->i_sb,prev,NULL,current,&this)) < 0) { - if (!locked) unlock_creation(); - return error; - } - } - if (!locked) unlock_creation(); - return this; -} diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c deleted file mode 100644 index ebe9bf3532b4..000000000000 --- a/fs/msdos/namei.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * linux/fs/msdos/namei.c - * - * Written 1992 by Werner Almesberger - */ - -#include -#include -#include -#include -#include -#include -#include - - -/* MS-DOS "device special files" */ - -static char *reserved_names[] = { - "CON ","PRN ","NUL ","AUX ", - "LPT1 ","LPT2 ","LPT3 ","LPT4 ", - "COM1 ","COM2 ","COM3 ","COM4 ", - NULL }; - - -/* Formats an MS-DOS file name. Rejects invalid names. */ - -static int msdos_format_name(char conv,const char *name,int len,char *res) -{ - char *walk,**reserved; - char c; - int space; - - if (get_fs_byte(name) == DELETED_FLAG) return -EINVAL; - if (get_fs_byte(name) == '.' && (len == 1 || (len == 2 && - get_fs_byte(name+1) == '.'))) { - memset(res+1,' ',10); - while (len--) *res++ = '.'; - return 0; - } - space = 0; /* to make GCC happy */ - c = 0; - for (walk = res; len && walk-res < 8; walk++) { - c = get_fs_byte(name++); - len--; - if (c == ' ' && conv != 'r') return -EINVAL; - if (c >= 'A' && c <= 'Z') { - if (conv != 'r') return -EINVAL; - c += 32; - } - if (c < ' ' || c == ':' || c == '\\') return -EINVAL; - if (c == '.') break; - space = c == ' '; - *walk = c >= 'a' && c <= 'z' ? c-32 : c; - } - if (space) return -EINVAL; - if (conv == 's' && len && c != '.') { - c = get_fs_byte(name++); - len--; - if (c != '.') return -EINVAL; - } - while (c != '.' && len--) c = get_fs_byte(name++); - if (walk == res) return -EINVAL; - if (c == '.') { - while (walk-res < 8) *walk++ = ' '; - while (len > 0 && walk-res < MSDOS_NAME) { - c = get_fs_byte(name++); - len--; - if (c == ' ' && conv != 'r') return -EINVAL; - if (c < ' ' || c == ':' || c == '\\' || c == '.') - return -EINVAL; - if (c >= 'A' && c <= 'Z') { - if (conv != 'r') return -EINVAL; - c += 32; - } - space = c == ' '; - *walk++ = c >= 'a' && c <= 'z' ? c-32 : c; - } - if (space) return -EINVAL; - if (conv == 's' && len) return -EINVAL; - } - while (walk-res < MSDOS_NAME) *walk++ = ' '; - for (reserved = reserved_names; *reserved; reserved++) - if (!strncmp(res,*reserved,8)) return -EINVAL; - return 0; -} - - -/* Locates a directory entry. */ - -static int msdos_find(struct inode *dir,const char *name,int len, - struct buffer_head **bh,struct msdos_dir_entry **de,int *ino) -{ - char msdos_name[MSDOS_NAME]; - int res; - - if ((res = msdos_format_name(MSDOS_SB(dir->i_sb)->name_check,name,len, - msdos_name)) < 0) return res; - return msdos_scan(dir,msdos_name,bh,de,ino); -} - - -int msdos_lookup(struct inode *dir,const char *name,int len, - struct inode **result) -{ - int ino,res; - struct msdos_dir_entry *de; - struct buffer_head *bh; - struct inode *next; - - *result = NULL; - if (!dir) return -ENOENT; - if (!S_ISDIR(dir->i_mode)) { - iput(dir); - return -ENOENT; - } - if (len == 1 && get_fs_byte(name) == '.') { - *result = dir; - return 0; - } - if (len == 2 && get_fs_byte(name) == '.' && get_fs_byte(name+1) == '.') - { - ino = msdos_parent_ino(dir,0); - iput(dir); - if (ino < 0) return ino; - if (!(*result = iget(dir->i_dev,ino))) return -EACCES; - return 0; - } - if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) { - iput(dir); - return res; - } - if (bh) brelse(bh); -/* printk("lookup: ino=%d\r\n",ino); */ - if (!(*result = iget(dir->i_dev,ino))) { - iput(dir); - return -EACCES; - } - if ((*result)->i_data[D_BUSY]) { /* mkdir in progress */ - iput(*result); - iput(dir); - return -ENOENT; - } - while ((*result)->i_data[D_OLD]) { - next = (struct inode *) ((*result)->i_data[D_OLD]); - iput(*result); - if (!(*result = iget(next->i_dev,next->i_ino))) - panic("msdos_lookup: Can't happen"); - } - iput(dir); - return 0; -} - - -/* Creates a directory entry (name is already formatted). */ - -static int msdos_create_entry(struct inode *dir,char *name,int is_dir, - struct inode **result) -{ - struct buffer_head *bh; - struct msdos_dir_entry *de; - int res,ino; - - if ((res = msdos_scan(dir,NULL,&bh,&de,&ino)) < 0) { - if (dir->i_ino == MSDOS_ROOT_INO) return -ENOSPC; - if ((res = msdos_add_cluster(dir)) < 0) return res; - if ((res = msdos_scan(dir,NULL,&bh,&de,&ino)) < 0) return res; - } - memcpy(de->name,name,MSDOS_NAME); - de->attr = is_dir ? ATTR_DIR : ATTR_ARCH; - de->start = 0; - date_unix2dos(CURRENT_TIME,&de->time,&de->date); - de->size = 0; - bh->b_dirt = 1; - if (*result = iget(dir->i_dev,ino)) msdos_read_inode(*result); - brelse(bh); - if (!*result) return -EIO; - (*result)->i_mtime = (*result)->i_atime = (*result)->i_ctime = - CURRENT_TIME; - (*result)->i_dirt = 1; - return 0; -} - - -int msdos_create(struct inode *dir,const char *name,int len,int mode, - struct inode **result) -{ - struct buffer_head *bh; - struct msdos_dir_entry *de; - char msdos_name[MSDOS_NAME]; - int ino,res; - - if (!dir) return -ENOENT; - if ((res = msdos_format_name(MSDOS_SB(dir->i_sb)->name_check,name,len, - msdos_name)) < 0) { - iput(dir); - return res; - } - lock_creation(); - if (msdos_scan(dir,msdos_name,&bh,&de,&ino) >= 0) { - unlock_creation(); - brelse(bh); - iput(dir); - return -EEXIST; - } - res = msdos_create_entry(dir,msdos_name,S_ISDIR(mode),result); - unlock_creation(); - iput(dir); - return res; -} - - -int msdos_mkdir(struct inode *dir,const char *name,int len,int mode) -{ - struct buffer_head *bh; - struct msdos_dir_entry *de; - struct inode *inode,*dot; - char msdos_name[MSDOS_NAME]; - int ino,res; - - if ((res = msdos_format_name(MSDOS_SB(dir->i_sb)->name_check,name,len, - msdos_name)) < 0) { - iput(dir); - return res; - } - lock_creation(); - if (msdos_scan(dir,msdos_name,&bh,&de,&ino) >= 0) { - unlock_creation(); - brelse(bh); - iput(dir); - return -EEXIST; - } - if ((res = msdos_create_entry(dir,msdos_name,1,&inode)) < 0) { - unlock_creation(); - iput(dir); - return res; - } - inode->i_data[D_BUSY] = 1; /* prevent lookups */ - if ((res = msdos_add_cluster(inode)) < 0) goto mkdir_error; - if ((res = msdos_create_entry(inode,MSDOS_DOT,1,&dot)) < 0) - goto mkdir_error; - dot->i_size = inode->i_size; - dot->i_data[D_START] = inode->i_data[D_START]; - dot->i_dirt = 1; - iput(dot); - if ((res = msdos_create_entry(inode,MSDOS_DOTDOT,1,&dot)) < 0) - goto mkdir_error; - unlock_creation(); - dot->i_size = dir->i_size; - dot->i_data[D_START] = dir->i_data[D_START]; - dot->i_dirt = 1; - inode->i_data[D_BUSY] = 0; - iput(dot); - iput(inode); - iput(dir); - return 0; -mkdir_error: - iput(inode); - if (msdos_rmdir(dir,name,len) < 0) panic("rmdir in mkdir failed"); - unlock_creation(); - return res; -} - - -int msdos_rmdir(struct inode *dir,const char *name,int len) -{ - int res,ino,pos; - struct buffer_head *bh,*dbh; - struct msdos_dir_entry *de,*dde; - struct inode *inode; - - bh = NULL; - inode = NULL; - res = -EINVAL; - if (len == 1 && get_fs_byte(name) == '.') goto rmdir_done; - if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) goto rmdir_done; - res = -ENOENT; - if (!(inode = iget(dir->i_dev,ino))) goto rmdir_done; - res = -ENOTDIR; - if (!S_ISDIR(inode->i_mode)) goto rmdir_done; - res = -EBUSY; - if (dir->i_dev != inode->i_dev || dir == inode) goto rmdir_done; - if (inode->i_count > 1) goto rmdir_done; - res = -ENOTEMPTY; - pos = 0; - dbh = NULL; - while (msdos_get_entry(inode,&pos,&dbh,&dde) > -1) - if (dde->name[0] && ((unsigned char *) dde->name)[0] != - DELETED_FLAG && strncmp(dde->name,MSDOS_DOT,MSDOS_NAME) && - strncmp(dde->name,MSDOS_DOTDOT,MSDOS_NAME)) goto rmdir_done; - if (dbh) brelse(dbh); - inode->i_nlink = 0; - dir->i_mtime = CURRENT_TIME; - inode->i_dirt = dir->i_dirt = 1; - de->name[0] = DELETED_FLAG; - bh->b_dirt = 1; - res = 0; -rmdir_done: - brelse(bh); - iput(dir); - iput(inode); - return res; -} - - -int msdos_unlink(struct inode *dir,const char *name,int len) -{ - int res,ino; - struct buffer_head *bh; - struct msdos_dir_entry *de; - struct inode *inode; - - bh = NULL; - inode = NULL; - if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) - goto unlink_done; - if (!(inode = iget(dir->i_dev,ino))) { - res = -ENOENT; - goto unlink_done; - } - if (!S_ISREG(inode->i_mode)) { - res = -EPERM; - goto unlink_done; - } - inode->i_nlink = 0; - inode->i_data[D_BUSY] = 1; - inode->i_dirt = 1; - de->name[0] = DELETED_FLAG; - bh->b_dirt = 1; -unlink_done: - brelse(bh); - iput(inode); - iput(dir); - return res; -} - - -static int rename_same_dir(struct inode *old_dir,char *old_name, - struct inode *new_dir,char *new_name,struct buffer_head *old_bh, - struct msdos_dir_entry *old_de,int old_ino) -{ - struct buffer_head *new_bh; - struct msdos_dir_entry *new_de; - struct inode *new_inode,*old_inode; - int new_ino; - int exists; - - if (!strncmp(old_name,new_name,MSDOS_NAME)) return 0; - exists = msdos_scan(new_dir,new_name,&new_bh,&new_de,&new_ino) >= 0; - if (*(unsigned char *) old_de->name == DELETED_FLAG) { - if (exists) brelse(new_bh); - return -ENOENT; - } - if (exists) { - if (!(new_inode = iget(new_dir->i_dev,new_ino))) { - brelse(new_bh); - return -EIO; - } - if (S_ISDIR(new_inode->i_mode)) { - iput(new_inode); - brelse(new_bh); - return -EPERM; - } - new_inode->i_nlink = 0; - new_inode->i_data[D_BUSY] = 1; - new_inode->i_dirt = 1; - new_de->name[0] = DELETED_FLAG; - new_bh->b_dirt = 1; - iput(new_inode); - brelse(new_bh); - } - memcpy(old_de->name,new_name,MSDOS_NAME); - old_bh->b_dirt = 1; - if (MSDOS_SB(old_dir->i_sb)->conversion == 'a') /* update binary info */ - if (old_inode = iget(old_dir->i_dev,old_ino)) { - msdos_read_inode(old_inode); - iput(old_inode); - } - return 0; -} - - -static int rename_diff_dir(struct inode *old_dir,char *old_name, - struct inode *new_dir,char *new_name,struct buffer_head *old_bh, - struct msdos_dir_entry *old_de,int old_ino) -{ - struct buffer_head *new_bh,*free_bh,*dotdot_bh; - struct msdos_dir_entry *new_de,*free_de,*dotdot_de; - struct inode *old_inode,*new_inode,*free_inode,*dotdot_inode,*walk; - int new_ino,free_ino,dotdot_ino; - int error,exists,ino; - - if (old_dir->i_dev != new_dir->i_dev) return -EINVAL; - if (old_ino == new_dir->i_ino) return -EINVAL; - if (!(walk = iget(new_dir->i_dev,new_dir->i_ino))) return -EIO; - while (walk->i_ino != MSDOS_ROOT_INO) { - ino = msdos_parent_ino(walk,1); - iput(walk); - if (ino < 0) return ino; - if (ino == old_ino) return -EINVAL; - if (!(walk = iget(new_dir->i_dev,ino))) return -EIO; - } - iput(walk); - if ((error = msdos_scan(new_dir,NULL,&free_bh,&free_de,&free_ino)) < 0) - return error; - exists = msdos_scan(new_dir,new_name,&new_bh,&new_de,&new_ino) - >= 0; - if (!(old_inode = iget(old_dir->i_dev,old_ino))) { - brelse(free_bh); - if (exists) brelse(new_bh); - return -EIO; - } - if (*(unsigned char *) old_de->name == DELETED_FLAG) { - iput(old_inode); - brelse(free_bh); - if (exists) brelse(new_bh); - return -ENOENT; - } - new_inode = NULL; /* to make GCC happy */ - if (exists) { - if (!(new_inode = iget(new_dir->i_dev,new_ino))) { - iput(old_inode); - brelse(new_bh); - return -EIO; - } - if (S_ISDIR(new_inode->i_mode)) { - iput(new_inode); - iput(old_inode); - brelse(new_bh); - return -EPERM; - } - new_inode->i_nlink = 0; - new_inode->i_data[D_BUSY] = 1; - new_inode->i_dirt = 1; - new_de->name[0] = DELETED_FLAG; - new_bh->b_dirt = 1; - } - memcpy(free_de,old_de,sizeof(struct msdos_dir_entry)); - memcpy(free_de->name,new_name,MSDOS_NAME); - if (!(free_inode = iget(new_dir->i_dev,free_ino))) { - free_de->name[0] = DELETED_FLAG; -/* Don't mark free_bh as dirty. Both states are supposed to be equivalent. */ - brelse(free_bh); - if (exists) { - iput(new_inode); - brelse(new_bh); - } - return -EIO; - } - msdos_read_inode(free_inode); - old_inode->i_data[D_BUSY] = 1; - old_inode->i_dirt = 1; - old_de->name[0] = DELETED_FLAG; - old_bh->b_dirt = 1; - free_bh->b_dirt = 1; - if (!exists) iput(free_inode); - else { - new_inode->i_data[D_DEPEND] = (int) free_inode; - free_inode->i_data[D_OLD] = (int) new_inode; - /* free_inode is put when putting new_inode */ - iput(new_inode); - brelse(new_bh); - } - if (S_ISDIR(old_inode->i_mode)) { - if ((error = msdos_scan(old_inode,MSDOS_DOTDOT,&dotdot_bh, - &dotdot_de,&dotdot_ino)) < 0) goto rename_done; - if (!(dotdot_inode = iget(old_inode->i_dev,dotdot_ino))) { - brelse(dotdot_bh); - error = -EIO; - goto rename_done; - } - dotdot_de->start = dotdot_inode->i_data[D_START] = - new_dir->i_data[D_START]; - dotdot_inode->i_dirt = 1; - dotdot_bh->b_dirt = 1; - iput(dotdot_inode); - brelse(dotdot_bh); - } - error = 0; -rename_done: - brelse(free_bh); - iput(old_inode); - return error; -} - - -int msdos_rename(struct inode *old_dir,const char *old_name,int old_len, - struct inode *new_dir,const char *new_name,int new_len) -{ - char old_msdos_name[MSDOS_NAME],new_msdos_name[MSDOS_NAME]; - struct buffer_head *old_bh; - struct msdos_dir_entry *old_de; - int old_ino,error; - - if ((error = msdos_format_name(MSDOS_SB(old_dir->i_sb)->name_check, - old_name,old_len,old_msdos_name)) < 0) goto rename_done; - if ((error = msdos_format_name(MSDOS_SB(new_dir->i_sb)->name_check, - new_name,new_len,new_msdos_name)) < 0) goto rename_done; - if ((error = msdos_scan(old_dir,old_msdos_name,&old_bh,&old_de, - &old_ino)) < 0) goto rename_done; - lock_creation(); - if (old_dir == new_dir) - error = rename_same_dir(old_dir,old_msdos_name,new_dir, - new_msdos_name,old_bh,old_de,old_ino); - else error = rename_diff_dir(old_dir,old_msdos_name,new_dir, - new_msdos_name,old_bh,old_de,old_ino); - unlock_creation(); - brelse(old_bh); -rename_done: - iput(old_dir); - iput(new_dir); - return error; -} diff --git a/fs/namei.c b/fs/namei.c index 17bdd29f37b5..73c16216246c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -8,16 +8,15 @@ * Some corrections by tytso. */ -#include -#include - -#include - #include #include +#include + #include -#include -#include +#include +#include +#include +#include struct inode * _namei(const char * filename, struct inode * base, int follow_links); @@ -168,6 +167,10 @@ struct inode * _namei(const char * pathname, struct inode * base, inode = follow_link(base,inode); else iput(base); + if (inode) { + inode->i_atime=CURRENT_TIME; + inode->i_dirt=1; + } return inode; } @@ -197,13 +200,12 @@ int open_namei(const char * pathname, int flag, int mode, struct inode ** res_inode) { const char * basename; - int namelen,error,i; + int namelen,error; struct inode * dir, *inode; - struct task_struct ** p; if ((flag & O_TRUNC) && !(flag & O_ACCMODE)) flag |= O_WRONLY; - mode &= 07777 & ~current->umask; + mode &= 0777 & ~current->umask; mode |= I_REGULAR; if (!(dir = dir_namei(pathname,&namelen,&basename,NULL))) return -ENOENT; @@ -230,10 +232,6 @@ int open_namei(const char * pathname, int flag, int mode, iput(dir); return -EACCES; } - if (IS_RDONLY(dir)) { - iput(dir); - return -EROFS; - } return dir->i_op->create(dir,basename,namelen,mode,res_inode); } if (flag & O_EXCL) { @@ -243,65 +241,35 @@ int open_namei(const char * pathname, int flag, int mode, } if (!(inode = follow_link(dir,inode))) return -ELOOP; - if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { - if (IS_NODEV(inode)) { - iput(inode); - return -EACCES; - } - } else { - if (IS_RDONLY(inode) && (flag & (O_TRUNC | O_ACCMODE))) { - iput(inode); - return -EROFS; - } - } if ((S_ISDIR(inode->i_mode) && (flag & O_ACCMODE)) || !permission(inode,ACC_MODE(flag))) { iput(inode); return -EPERM; } - if ((inode->i_count > 1) && (flag & O_ACCMODE)) - for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { - if (!*p) - continue; - if (inode == (*p)->executable) { - iput(inode); - return -ETXTBSY; - } - for (i=0; i < (*p)->numlibraries; i++) - if (inode == (*p)->libraries[i].library) { - iput(inode); - return -ETXTBSY; - } - } + inode->i_atime = CURRENT_TIME; if (flag & O_TRUNC) if (inode->i_op && inode->i_op->truncate) { inode->i_size = 0; inode->i_op->truncate(inode); } - if (!IS_RDONLY(inode)) { - inode->i_atime = CURRENT_TIME; - inode->i_dirt = 1; - } *res_inode = inode; return 0; } -int do_mknod(const char * filename, int mode, int dev) +int sys_mknod(const char * filename, int mode, int dev) { const char * basename; int namelen; struct inode * dir; + if (!suser()) + return -EPERM; if (!(dir = dir_namei(filename,&namelen,&basename, NULL))) return -ENOENT; if (!namelen) { iput(dir); return -ENOENT; } - if (IS_RDONLY(dir)) { - iput(dir); - return -EROFS; - } if (!permission(dir,MAY_WRITE)) { iput(dir); return -EACCES; @@ -313,13 +281,6 @@ int do_mknod(const char * filename, int mode, int dev) return dir->i_op->mknod(dir,basename,namelen,mode,dev); } -int sys_mknod(const char * filename, int mode, int dev) -{ - if (S_ISFIFO(mode) || suser()) - return do_mknod(filename,mode,dev); - return -EPERM; -} - int sys_mkdir(const char * pathname, int mode) { const char * basename; @@ -332,10 +293,6 @@ int sys_mkdir(const char * pathname, int mode) iput(dir); return -ENOENT; } - if (IS_RDONLY(dir)) { - iput(dir); - return -EROFS; - } if (!permission(dir,MAY_WRITE)) { iput(dir); return -EACCES; @@ -359,10 +316,6 @@ int sys_rmdir(const char * name) iput(dir); return -ENOENT; } - if (IS_RDONLY(dir)) { - iput(dir); - return -EROFS; - } if (!permission(dir,MAY_WRITE)) { iput(dir); return -EACCES; @@ -386,10 +339,6 @@ int sys_unlink(const char * name) iput(dir); return -EPERM; } - if (IS_RDONLY(dir)) { - iput(dir); - return -EROFS; - } if (!permission(dir,MAY_WRITE)) { iput(dir); return -EACCES; @@ -414,10 +363,6 @@ int sys_symlink(const char * oldname, const char * newname) iput(dir); return -ENOENT; } - if (IS_RDONLY(dir)) { - iput(dir); - return -EROFS; - } if (!permission(dir,MAY_WRITE)) { iput(dir); return -EACCES; @@ -448,11 +393,6 @@ int sys_link(const char * oldname, const char * newname) iput(dir); return -EPERM; } - if (IS_RDONLY(dir)) { - iput(oldinode); - iput(dir); - return -EROFS; - } if (dir->i_dev != oldinode->i_dev) { iput(dir); iput(oldinode); @@ -512,11 +452,6 @@ int sys_rename(const char * oldname, const char * newname) iput(new_dir); return -EXDEV; } - if (IS_RDONLY(new_dir) || IS_RDONLY(old_dir)) { - iput(old_dir); - iput(new_dir); - return -EROFS; - } if (!old_dir->i_op || !old_dir->i_op->rename) { iput(old_dir); iput(new_dir); diff --git a/fs/open.c b/fs/open.c index 275e42924e23..e2cdce7ebd00 100644 --- a/fs/open.c +++ b/fs/open.c @@ -5,13 +5,13 @@ */ #include +#include #include #include +#include #include -#include -#include #include #include #include @@ -33,34 +33,14 @@ int sys_ustat(int dev, struct ustat * ubuf) int sys_statfs(const char * path, struct statfs * buf) { - struct inode * inode; - - verify_area(buf, sizeof(struct statfs)); - if (!(inode = namei(path))) - return -ENOENT; - if (!inode->i_sb->s_op->statfs) { - iput(inode); - return -ENOSYS; - } - inode->i_sb->s_op->statfs(inode->i_sb, buf); - iput(inode); - return 0; + printk("statfs not implemented\n"); + return -ENOSYS; } int sys_fstatfs(unsigned int fd, struct statfs * buf) { - struct inode * inode; - struct file * file; - - verify_area(buf, sizeof(struct statfs)); - if (fd >= NR_OPEN || !(file = current->filp[fd])) - return -EBADF; - if (!(inode = file->f_inode)) - return -ENOENT; - if (!inode->i_sb->s_op->statfs) - return -ENOSYS; - inode->i_sb->s_op->statfs(inode->i_sb, buf); - return 0; + printk("fstatfs not implemented\n"); + return -ENOSYS; } int sys_truncate(const char * path, unsigned int length) @@ -69,13 +49,9 @@ int sys_truncate(const char * path, unsigned int length) if (!(inode = namei(path))) return -ENOENT; - if (S_ISDIR(inode->i_mode) || !permission(inode,MAY_WRITE)) { + if (!permission(inode,MAY_WRITE)) { iput(inode); - return -EACCES; - } - if (IS_RDONLY(inode)) { - iput(inode); - return -EROFS; + return -EPERM; } inode->i_size = length; if (inode->i_op && inode->i_op->truncate) @@ -95,8 +71,8 @@ int sys_ftruncate(unsigned int fd, unsigned int length) return -EBADF; if (!(inode = file->f_inode)) return -ENOENT; - if (S_ISDIR(inode->i_mode) || !(file->f_mode & 2)) - return -EACCES; + if (!(file->f_flags & 2)) + return -EPERM; inode->i_size = length; if (inode->i_op && inode->i_op->truncate) inode->i_op->truncate(inode); @@ -105,10 +81,6 @@ int sys_ftruncate(unsigned int fd, unsigned int length) return 0; } -/* If times==NULL, set access and modification to current time, - * must be owner or have write permission. - * Else, update from *times, must be owner or super user. - */ int sys_utime(char * filename, struct utimbuf * times) { struct inode * inode; @@ -116,25 +88,16 @@ int sys_utime(char * filename, struct utimbuf * times) if (!(inode=namei(filename))) return -ENOENT; - if (IS_RDONLY(inode)) { - iput(inode); - return -EROFS; - } if (times) { - if ((current->euid != inode->i_uid) && !suser()) { + if (current->euid != inode->i_uid && + !permission(inode,MAY_WRITE)) { iput(inode); return -EPERM; } actime = get_fs_long((unsigned long *) ×->actime); modtime = get_fs_long((unsigned long *) ×->modtime); - } else { - if ((current->euid != inode->i_uid) && - !permission(inode,MAY_WRITE)) { - iput(inode); - return -EACCES; - } + } else actime = modtime = CURRENT_TIME; - } inode->i_atime = actime; inode->i_mtime = modtime; inode->i_dirt = 1; @@ -158,8 +121,8 @@ int sys_access(const char * filename,int mode) iput(inode); if (current->uid == inode->i_uid) res >>= 6; - else if (in_group_p(inode->i_gid)) - res >>= 3; + else if (current->gid == inode->i_gid) + res >>= 6; if ((res & 0007 & mode) == mode) return 0; /* @@ -184,10 +147,6 @@ int sys_chdir(const char * filename) iput(inode); return -ENOTDIR; } - if (!permission(inode,MAY_EXEC)) { - iput(inode); - return -EACCES; - } iput(current->pwd); current->pwd = inode; return (0); @@ -203,10 +162,6 @@ int sys_chroot(const char * filename) iput(inode); return -ENOTDIR; } - if (!suser()) { - iput(inode); - return -EPERM; - } iput(current->root); current->root = inode; return (0); @@ -222,9 +177,7 @@ int sys_fchmod(unsigned int fd, mode_t mode) if (!(inode = file->f_inode)) return -ENOENT; if ((current->euid != inode->i_uid) && !suser()) - return -EPERM; - if (IS_RDONLY(inode)) - return -EROFS; + return -EACCES; inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777); inode->i_dirt = 1; return 0; @@ -238,11 +191,7 @@ int sys_chmod(const char * filename, mode_t mode) return -ENOENT; if ((current->euid != inode->i_uid) && !suser()) { iput(inode); - return -EPERM; - } - if (IS_RDONLY(inode)) { - iput(inode); - return -EROFS; + return -EACCES; } inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777); inode->i_dirt = 1; @@ -259,40 +208,29 @@ int sys_fchown(unsigned int fd, uid_t user, gid_t group) return -EBADF; if (!(inode = file->f_inode)) return -ENOENT; - if (IS_RDONLY(inode)) - return -EROFS; - if ((current->euid == inode->i_uid && user == inode->i_uid && - (in_group_p(group) || group == inode->i_gid)) || - suser()) { - inode->i_uid = user; - inode->i_gid = group; - inode->i_dirt=1; - return 0; - } - return -EPERM; + if (!suser()) + return -EACCES; + inode->i_uid = user; + inode->i_gid = group; + inode->i_dirt=1; + return 0; } int sys_chown(const char * filename, uid_t user, gid_t group) { struct inode * inode; - if (!(inode = lnamei(filename))) + if (!(inode = namei(filename))) return -ENOENT; - if (IS_RDONLY(inode)) { - iput(inode); - return -EROFS; - } - if ((current->euid == inode->i_uid && user == inode->i_uid && - (in_group_p(group) || group == inode->i_gid)) || - suser()) { - inode->i_uid = user; - inode->i_gid = group; - inode->i_dirt=1; + if (!suser()) { iput(inode); - return 0; + return -EACCES; } + inode->i_uid = user; + inode->i_gid = group; + inode->i_dirt = 1; iput(inode); - return -EPERM; + return 0; } int sys_open(const char * filename,int flag,int mode) @@ -305,30 +243,37 @@ int sys_open(const char * filename,int flag,int mode) if (!current->filp[fd]) break; if (fd>=NR_OPEN) - return -EMFILE; + return -EINVAL; current->close_on_exec &= ~(1<f_count) break; if (i>=NR_FILE) - return -ENFILE; + return -EINVAL; (current->filp[fd] = f)->f_count++; if ((i = open_namei(filename,flag,mode,&inode))<0) { current->filp[fd]=NULL; f->f_count=0; return i; } + f->f_op = NULL; + if (inode) + if (S_ISCHR(inode->i_mode)) { + i = MAJOR(inode->i_rdev); + if (i < MAX_CHRDEV) + f->f_op = chrdev_fops[i]; + } else if (S_ISBLK(inode->i_mode)) { + i = MAJOR(inode->i_rdev); + if (i < MAX_CHRDEV) + f->f_op = blkdev_fops[i]; + } f->f_mode = "\001\002\003\000"[flag & O_ACCMODE]; f->f_flags = flag; f->f_count = 1; f->f_inode = inode; f->f_pos = 0; - f->f_reada = 0; - f->f_op = NULL; - if (inode->i_op) - f->f_op = inode->i_op->default_file_ops; - if (f->f_op && f->f_op->open) - if (i = f->f_op->open(inode,f)) { + if (inode->i_op && inode->i_op->open) + if (i = inode->i_op->open(inode,f)) { iput(inode); f->f_count=0; current->filp[fd]=NULL; @@ -345,7 +290,6 @@ int sys_creat(const char * pathname, int mode) int sys_close(unsigned int fd) { struct file * filp; - struct inode * inode; if (fd >= NR_OPEN) return -EINVAL; @@ -353,18 +297,12 @@ int sys_close(unsigned int fd) if (!(filp = current->filp[fd])) return -EINVAL; current->filp[fd] = NULL; - if (filp->f_count == 0) { - printk("Close: file count is 0\n"); - return 0; - } - if (filp->f_count > 1) { - filp->f_count--; - return 0; - } - inode = filp->f_inode; - if (filp->f_op && filp->f_op->release) - filp->f_op->release(inode,filp); - filp->f_count--; - iput(inode); + if (filp->f_count == 0) + panic("Close: file count is 0"); + if (--filp->f_count) + return (0); + if (filp->f_op && filp->f_op->close) + return filp->f_op->close(filp->f_inode,filp); + iput(filp->f_inode); return 0; } diff --git a/fs/pipe.c b/fs/pipe.c index 29f43bf7b70b..0aef899e08e8 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -7,10 +7,10 @@ #include #include #include +#include #include -#include #include #include @@ -21,7 +21,7 @@ static int pipe_read(struct inode * inode, struct file * filp, char * buf, int c if (!(filp->f_flags & O_NONBLOCK)) while (!PIPE_SIZE(*inode)) { wake_up(& PIPE_WRITE_WAIT(*inode)); - if (!PIPE_WRITERS(*inode)) /* are there any writers? */ + if (inode->i_count != 2) /* are there any writers? */ return 0; if (current->signal & ~current->blocked) return -ERESTARTSYS; @@ -33,12 +33,13 @@ static int pipe_read(struct inode * inode, struct file * filp, char * buf, int c chars = count; if (chars > size) chars = size; - memcpy_tofs(buf, (char *)inode->i_size+PIPE_TAIL(*inode), chars ); + count -= chars; read += chars; + size = PIPE_TAIL(*inode); PIPE_TAIL(*inode) += chars; PIPE_TAIL(*inode) &= (PAGE_SIZE-1); - count -= chars; - buf += chars; + while (chars-->0) + put_fs_byte(((char *)inode->i_size)[size++],buf++); } wake_up(& PIPE_WRITE_WAIT(*inode)); return read?read:-EAGAIN; @@ -48,44 +49,31 @@ static int pipe_write(struct inode * inode, struct file * filp, char * buf, int { int chars, size, written = 0; - if (!PIPE_READERS(*inode)) { /* no readers */ - send_sig(SIGPIPE,current,0); - return -EPIPE; - } -/* if count < PAGE_SIZE, we have to make it atomic */ - if (count < PAGE_SIZE) - size = PAGE_SIZE-count; - else - size = PAGE_SIZE-1; while (count>0) { - while (PIPE_SIZE(*inode) >= size) { - if (!PIPE_READERS(*inode)) { /* no readers */ - send_sig(SIGPIPE,current,0); - return written?written:-EPIPE; + while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) { + wake_up(& PIPE_READ_WAIT(*inode)); + if (inode->i_count != 2) { /* no readers */ + current->signal |= (1<<(SIGPIPE-1)); + return written?written:-EINTR; } if (current->signal & ~current->blocked) - return written?written:-ERESTARTSYS; - if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - else - interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode)); + return written?written:-EINTR; + interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode)); } - while (count>0 && (size = (PAGE_SIZE-1)-PIPE_SIZE(*inode))) { - chars = PAGE_SIZE-PIPE_HEAD(*inode); - if (chars > count) - chars = count; - if (chars > size) - chars = size; - memcpy_fromfs((char *)inode->i_size+PIPE_HEAD(*inode), buf, chars ); - written += chars; - PIPE_HEAD(*inode) += chars; - PIPE_HEAD(*inode) &= (PAGE_SIZE-1); - count -= chars; - buf += chars; - } - wake_up(& PIPE_READ_WAIT(*inode)); - size = PAGE_SIZE-1; + chars = PAGE_SIZE-PIPE_HEAD(*inode); + if (chars > count) + chars = count; + if (chars > size) + chars = size; + count -= chars; + written += chars; + size = PIPE_HEAD(*inode); + PIPE_HEAD(*inode) += chars; + PIPE_HEAD(*inode) &= (PAGE_SIZE-1); + while (chars-->0) + ((char *)inode->i_size)[size++]=get_fs_byte(buf++); } + wake_up(& PIPE_READ_WAIT(*inode)); return written; } @@ -117,87 +105,24 @@ static int pipe_ioctl(struct inode *pino, struct file * filp, } } -static int pipe_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait) -{ - switch (sel_type) { - case SEL_IN: - if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode)) - return 1; - select_wait(&PIPE_READ_WAIT(*inode), wait); - return 0; - case SEL_OUT: - if (!PIPE_FULL(*inode) || !PIPE_WRITERS(*inode)) - return 1; - select_wait(&PIPE_WRITE_WAIT(*inode), wait); - return 0; - case SEL_EX: - if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode)) - return 1; - select_wait(&inode->i_wait,wait); - return 0; - } - return 0; -} - -/* - * Ok, these three routines NOW keep track of readers/writers, - * Linus previously did it with inode->i_count checking. - */ -static void pipe_read_release(struct inode * inode, struct file * filp) -{ - PIPE_READERS(*inode)--; - wake_up(&PIPE_WRITE_WAIT(*inode)); -} - -static void pipe_write_release(struct inode * inode, struct file * filp) -{ - PIPE_WRITERS(*inode)--; - wake_up(&PIPE_READ_WAIT(*inode)); -} - -static void pipe_rdwr_release(struct inode * inode, struct file * filp) -{ - PIPE_READERS(*inode)--; - PIPE_WRITERS(*inode)--; - wake_up(&PIPE_READ_WAIT(*inode)); - wake_up(&PIPE_WRITE_WAIT(*inode)); -} - -/* - * The three file_operations structs are not static because they - * are also used in linux/fs/fifo.c to do operations on fifo's. - */ -struct file_operations read_pipe_fops = { +static struct file_operations read_pipe_fops = { pipe_lseek, pipe_read, bad_pipe_rw, pipe_readdir, - pipe_select, - pipe_ioctl, - NULL, /* no special open code */ - pipe_read_release + NULL, /* pipe_close */ + NULL, /* pipe_select */ + pipe_ioctl }; -struct file_operations write_pipe_fops = { +static struct file_operations write_pipe_fops = { pipe_lseek, bad_pipe_rw, pipe_write, pipe_readdir, - pipe_select, - pipe_ioctl, - NULL, /* no special open code */ - pipe_write_release -}; - -struct file_operations rdwr_pipe_fops = { - pipe_lseek, - pipe_read, - pipe_write, - pipe_readdir, - pipe_select, - pipe_ioctl, - NULL, /* no special open code */ - pipe_rdwr_release + NULL, /* pipe_close */ + NULL, /* pipe_select */ + pipe_ioctl }; int sys_pipe(unsigned long * fildes) @@ -207,7 +132,6 @@ int sys_pipe(unsigned long * fildes) int fd[2]; int i,j; - verify_area(fildes,8); j=0; for(i=0;j<2 && if_inode = f[1]->f_inode = inode; f[0]->f_pos = f[1]->f_pos = 0; - f[0]->f_flags = f[1]->f_flags = 0; f[0]->f_op = &read_pipe_fops; f[0]->f_mode = 1; /* read */ f[1]->f_op = &write_pipe_fops; diff --git a/fs/read_write.c b/fs/read_write.c index f7919fd66238..19cbcdaad961 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -6,9 +6,9 @@ #include #include +#include #include -#include #include #include #include @@ -36,7 +36,7 @@ int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count) int sys_lseek(unsigned int fd, off_t offset, unsigned int origin) { struct file * file; - int tmp = -1; + int tmp; if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode)) return -EBADF; @@ -62,7 +62,6 @@ int sys_lseek(unsigned int fd, off_t offset, unsigned int origin) if (tmp < 0) return -EINVAL; file->f_pos = tmp; - file->f_reada = 0; return file->f_pos; } @@ -80,6 +79,7 @@ int sys_read(unsigned int fd,char * buf,unsigned int count) verify_area(buf,count); if (file->f_op && file->f_op->read) return file->f_op->read(inode,file,buf,count); + printk("(Read)inode->i_mode=%06o\n\r",inode->i_mode); return -EINVAL; } @@ -96,5 +96,6 @@ int sys_write(unsigned int fd,char * buf,unsigned int count) return 0; if (file->f_op && file->f_op->write) return file->f_op->write(inode,file,buf,count); + printk("(Write)inode->i_mode=%06o\n\r",inode->i_mode); return -EINVAL; } diff --git a/fs/select.c b/fs/select.c index d5fa7e872d8c..98e74c476af1 100644 --- a/fs/select.c +++ b/fs/select.c @@ -7,13 +7,14 @@ #include #include +#include #include #include -#include #include #include +#include #include #include @@ -28,46 +29,138 @@ * understand what I'm doing here, then you understand how the linux sleep/wakeup * mechanism works. * - * Two very simple procedures, select_wait() and free_wait() make all the work. - * select_wait() is a inline-function defined in , as all select - * functions have to call it to add an entry to the select table. + * Two very simple procedures, add_wait() and free_wait() make all the work. We + * have to have interrupts disabled throughout the select, but that's not really + * such a loss: sleeping automatically frees interrupts when we aren't in this + * task. */ static select_table * sel_tables = NULL; +static void add_wait(struct task_struct ** wait_address, select_table * p) +{ + int i; + + if (!wait_address) + return; + for (i = 0 ; i < p->nr ; i++) + if (p->entry[i].wait_address == wait_address) + return; + current->next_wait = NULL; + p->entry[p->nr].wait_address = wait_address; + p->entry[p->nr].old_task = *wait_address; + *wait_address = current; + p->nr++; +} + +/* + * free_wait removes the current task from any wait-queues and then + * wakes up the queues. + */ +static void free_one_table(select_table * p) +{ + int i; + struct task_struct ** tpp; + + for(tpp = &LAST_TASK ; tpp > &FIRST_TASK ; --tpp) + if (*tpp && ((*tpp)->next_wait == p->current)) + (*tpp)->next_wait = NULL; + if (!p->nr) + return; + for (i = 0; i < p->nr ; i++) { + wake_up(p->entry[i].wait_address); + wake_up(&p->entry[i].old_task); + } + p->nr = 0; +} + static void free_wait(select_table * p) { - struct select_table_entry * entry = p->entry + p->nr; + select_table * tmp; - while (p->nr > 0) { - p->nr--; - entry--; - remove_wait_queue(entry->wait_address,&entry->wait); + if (p->woken) + return; + p = sel_tables; + sel_tables = NULL; + while (p) { + wake_up(&p->current); + p->woken = 1; + tmp = p->next_table; + p->next_table = NULL; + free_one_table(p); + p = tmp; } } +static struct tty_struct * get_tty(struct inode * inode) +{ + int major, minor; + + if (!S_ISCHR(inode->i_mode)) + return NULL; + if ((major = MAJOR(inode->i_rdev)) != 5 && major != 4) + return NULL; + if (major == 5) + minor = current->tty; + else + minor = MINOR(inode->i_rdev); + if (minor < 0) + return NULL; + return TTY_TABLE(minor); +} + /* * The check_XX functions check out a file. We know it's either - * a pipe, a character device or a fifo + * a pipe, a character device or a fifo (fifo's not implemented) */ -static int check_in(select_table * wait, struct inode * inode, struct file * file) +static int check_in(select_table * wait, struct inode * inode) { - if (file->f_op && file->f_op->select) - return file->f_op->select(inode,file,SEL_IN,wait); + struct tty_struct * tty; + + if (tty = get_tty(inode)) + if (!EMPTY(tty->secondary)) + return 1; + else + add_wait(&tty->secondary->proc_list, wait); + else if (inode->i_pipe) + if (!PIPE_EMPTY(*inode) || inode->i_count < 2) + return 1; + else + add_wait(&inode->i_wait, wait); return 0; } -static int check_out(select_table * wait, struct inode * inode, struct file * file) +static int check_out(select_table * wait, struct inode * inode) { - if (file->f_op && file->f_op->select) - return file->f_op->select(inode,file,SEL_OUT,wait); + struct tty_struct * tty; + + if (tty = get_tty(inode)) + if (!FULL(tty->write_q)) + return 1; + else + add_wait(&tty->write_q->proc_list, wait); + else if (inode->i_pipe) + if (!PIPE_FULL(*inode)) + return 1; + else + add_wait(&inode->i_wait, wait); return 0; } -static int check_ex(select_table * wait, struct inode * inode, struct file * file) +static int check_ex(select_table * wait, struct inode * inode) { - if (file->f_op && file->f_op->select) - return file->f_op->select(inode,file,SEL_EX,wait); + struct tty_struct * tty; + + if (tty = get_tty(inode)) + if (!FULL(tty->write_q)) + return 0; + else + return 0; + else if (inode->i_pipe) + if (inode->i_count < 2) + return 1; + else + add_wait(&inode->i_wait,wait); return 0; } @@ -76,7 +169,6 @@ int do_select(fd_set in, fd_set out, fd_set ex, { int count; select_table wait_table; - struct file * file; int i; fd_set mask; @@ -94,42 +186,44 @@ int do_select(fd_set in, fd_set out, fd_set ex, continue; if (S_ISFIFO(current->filp[i]->f_inode->i_mode)) continue; - if (S_ISSOCK(current->filp[i]->f_inode->i_mode)) - continue; return -EBADF; } repeat: wait_table.nr = 0; + wait_table.woken = 0; + wait_table.current = current; + wait_table.next_table = sel_tables; + sel_tables = &wait_table; *inp = *outp = *exp = 0; count = 0; - current->state = TASK_INTERRUPTIBLE; mask = 1; for (i = 0 ; i < NR_OPEN ; i++, mask += mask) { - file = current->filp[i]; if (mask & in) - if (check_in(&wait_table,file->f_inode,file)) { + if (check_in(&wait_table,current->filp[i]->f_inode)) { *inp |= mask; count++; } if (mask & out) - if (check_out(&wait_table,file->f_inode,file)) { + if (check_out(&wait_table,current->filp[i]->f_inode)) { *outp |= mask; count++; } if (mask & ex) - if (check_ex(&wait_table,file->f_inode,file)) { + if (check_ex(&wait_table,current->filp[i]->f_inode)) { *exp |= mask; count++; } } if (!(current->signal & ~current->blocked) && current->timeout && !count) { + current->state = TASK_INTERRUPTIBLE; + sti(); schedule(); + cli(); free_wait(&wait_table); goto repeat; } free_wait(&wait_table); - current->state = TASK_RUNNING; return count; } @@ -172,11 +266,13 @@ int sys_select( unsigned long *buffer ) timeout += jiffies; } current->timeout = timeout; + cli(); i = do_select(in, out, ex, &res_in, &res_out, &res_ex); if (current->timeout > jiffies) timeout = current->timeout - jiffies; else timeout = 0; + sti(); current->timeout = 0; if (i < 0) return i; diff --git a/fs/stat.c b/fs/stat.c index 3f1dbf6f1ab6..029ec2ff7bf9 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -5,20 +5,19 @@ */ #include +#include -#include #include #include #include #include -static void cp_old_stat(struct inode * inode, struct old_stat * statbuf) +static void cp_stat(struct inode * inode, struct stat * statbuf) { - struct old_stat tmp; + struct stat tmp; + int i; - if (inode->i_ino & 0xffff0000) - printk("Warning: using old stat() call on bigfs\n"); - verify_area(statbuf,sizeof (*statbuf)); + verify_area(statbuf,sizeof (struct stat)); tmp.st_dev = inode->i_dev; tmp.st_ino = inode->i_ino; tmp.st_mode = inode->i_mode; @@ -26,123 +25,44 @@ static void cp_old_stat(struct inode * inode, struct old_stat * statbuf) tmp.st_uid = inode->i_uid; tmp.st_gid = inode->i_gid; tmp.st_rdev = inode->i_rdev; - if( S_ISFIFO(inode->i_mode) ) - tmp.st_size = 0; - else - tmp.st_size = inode->i_size; + tmp.st_size = inode->i_size; tmp.st_atime = inode->i_atime; tmp.st_mtime = inode->i_mtime; tmp.st_ctime = inode->i_ctime; - memcpy_tofs(statbuf,&tmp,sizeof(tmp)); + for (i=0 ; ii_dev; - tmp.st_ino = inode->i_ino; - tmp.st_mode = inode->i_mode; - tmp.st_nlink = inode->i_nlink; - tmp.st_uid = inode->i_uid; - tmp.st_gid = inode->i_gid; - tmp.st_rdev = inode->i_rdev; - if( S_ISFIFO(inode->i_mode) ) - tmp.st_size = 0; - else - tmp.st_size = inode->i_size; - tmp.st_atime = inode->i_atime; - tmp.st_mtime = inode->i_mtime; - tmp.st_ctime = inode->i_ctime; -/* - * Right now we fake the st_blocks numbers: we'll eventually have to - * add st_blocks to the inode, and let the vfs routines keep track of - * it all. This algorithm doesn't guarantee correct block numbers, but - * at least it tries to come up with a plausible answer... - * - * In fact, the minix fs doesn't use these numbers (it uses 7 and 512 - * instead of 10 and 256), but who cares... It's not that exact anyway. - */ - blocks = (tmp.st_size + 1023) / 1024; - if (blocks > 10) { - indirect = (blocks - 11)/256+1; - if (blocks > 10+256) { - indirect += (blocks - 267)/(256*256)+1; - if (blocks > 10+256+256*256) - indirect++; - } - blocks += indirect; - } - tmp.st_blksize = 1024; - tmp.st_blocks = blocks; - memcpy_tofs(statbuf,&tmp,sizeof(tmp)); -} - -int sys_stat(char * filename, struct old_stat * statbuf) +int sys_stat(char * filename, struct stat * statbuf) { struct inode * inode; if (!(inode=namei(filename))) return -ENOENT; - cp_old_stat(inode,statbuf); + cp_stat(inode,statbuf); iput(inode); return 0; } -int sys_newstat(char * filename, struct new_stat * statbuf) -{ - struct inode * inode; - - if (!(inode=namei(filename))) - return -ENOENT; - cp_new_stat(inode,statbuf); - iput(inode); - return 0; -} - -int sys_lstat(char * filename, struct old_stat * statbuf) -{ - struct inode * inode; - - if (!(inode = lnamei(filename))) - return -ENOENT; - cp_old_stat(inode,statbuf); - iput(inode); - return 0; -} - -int sys_newlstat(char * filename, struct new_stat * statbuf) +int sys_lstat(char * filename, struct stat * statbuf) { struct inode * inode; if (!(inode = lnamei(filename))) return -ENOENT; - cp_new_stat(inode,statbuf); + cp_stat(inode,statbuf); iput(inode); return 0; } -int sys_fstat(unsigned int fd, struct old_stat * statbuf) -{ - struct file * f; - struct inode * inode; - - if (fd >= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode)) - return -EBADF; - cp_old_stat(inode,statbuf); - return 0; -} - -int sys_newfstat(unsigned int fd, struct new_stat * statbuf) +int sys_fstat(unsigned int fd, struct stat * statbuf) { struct file * f; struct inode * inode; if (fd >= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode)) return -EBADF; - cp_new_stat(inode,statbuf); + cp_stat(inode,statbuf); return 0; } diff --git a/fs/super.c b/fs/super.c index 970ce2e7a506..78f8b6c0a4ce 100644 --- a/fs/super.c +++ b/fs/super.c @@ -10,15 +10,12 @@ #include #include #include -#include -#include #include -#include #include #include #include - +#include int sync_dev(int dev); void wait_for_keypress(void); @@ -37,8 +34,6 @@ int ROOT_DEV = 0; static struct file_system_type file_systems[] = { {minix_read_super,"minix"}, - {ext_read_super,"ext"}, - {msdos_read_super,"msdos"}, {NULL,NULL} }; @@ -65,8 +60,10 @@ void lock_super(struct super_block * sb) void free_super(struct super_block * sb) { + cli(); sb->s_lock = 0; wake_up(&(sb->s_wait)); + sti(); } void wait_on_super(struct super_block * sb) @@ -113,7 +110,7 @@ void put_super(int dev) sb->s_op->put_super(sb); } -static struct super_block * read_super(int dev,char *name,int flags,void *data) +static struct super_block * read_super(int dev,char *name,void *data) { struct super_block * s; struct file_system_type *type; @@ -134,7 +131,6 @@ static struct super_block * read_super(int dev,char *name,int flags,void *data) break; } s->s_dev = dev; - s->s_flags = flags; if (!type->read_super(s,data)) return(NULL); s->s_dev = dev; @@ -178,30 +174,32 @@ int sys_umount(char * dev_name) sb->s_covered = NULL; iput(sb->s_mounted); sb->s_mounted = NULL; - if (sb->s_op && sb->s_op->write_super && sb->s_dirt) - sb->s_op->write_super (sb); put_super(dev); sync_dev(dev); return 0; } -/* - * do_mount() does the actual mounting after sys_mount has done the ugly - * parameter parsing. When enough time has gone by, and everything uses the - * new mount() parameters, sys_mount() can then be cleaned up. - * - * We cannot mount a filesystem if it has active, used, or dirty inodes. - * We also have to flush all inode-data for this device, as the new mount - * might need new info. - */ -static int do_mount(int dev, const char * dir, char * type, int flags, void * data) +int sys_mount(char * dev_name, char * dir_name, char * type, int rw_flag) { - struct inode * inode, * dir_i; + struct inode * dev_i, * dir_i; struct super_block * sb; + int dev; + char tmp[100],*t; + int i; - if (!(dir_i = namei(dir))) + if (!suser()) + return -EPERM; + if (!(dev_i = namei(dev_name))) return -ENOENT; - if (dir_i->i_count != 1 || dir_i->i_mount) { + dev = dev_i->i_rdev; + if (!S_ISBLK(dev_i->i_mode)) { + iput(dev_i); + return -EPERM; + } + iput(dev_i); + if (!(dir_i=namei(dir_name))) + return -ENOENT; + if (dir_i->i_count != 1 || dir_i->i_ino == MINIX_ROOT_INO) { iput(dir_i); return -EBUSY; } @@ -209,82 +207,29 @@ static int do_mount(int dev, const char * dir, char * type, int flags, void * da iput(dir_i); return -EPERM; } - for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++) { - if (inode->i_dev != dev) - continue; - if (inode->i_count || inode->i_dirt || inode->i_lock) { - iput(dir_i); - return -EBUSY; - } - inode->i_dev = 0; - } - sb = read_super(dev,type,flags,data); - if (!sb || sb->s_covered) { + if (dir_i->i_mount) { iput(dir_i); - return -EBUSY; - } - sb->s_flags = flags; - sb->s_covered = dir_i; - dir_i->i_mount = 1; - return 0; /* we don't iput(dir_i) - see umount */ -} - -/* - * Flags is a 16-bit value that allows up to 16 non-fs dependent flags to - * be given to the mount() call (ie: read-only, no-dev, no-suid etc). - * - * data is a (void *) that can point to any structure up to 4095 bytes, which - * can contain arbitrary fs-dependent information (or be NULL). - * - * NOTE! As old versions of mount() didn't use this setup, the flags has to have - * a special 16-bit magic number in the hight word: 0xC0ED. If this magic word - * isn't present, the flags and data info isn't used, as the syscall assumes we - * are talking to an older version that didn't understand them. - */ -int sys_mount(char * dev_name, char * dir_name, char * type, - unsigned long new_flags, void *data) -{ - struct inode * inode; - int dev; - int retval = 0; - char tmp[100],*t; - int i; - unsigned long flags = 0; - unsigned long page = 0; - - if (!suser()) return -EPERM; - if (!(inode = namei(dev_name))) - return -ENOENT; - dev = inode->i_rdev; - if (!S_ISBLK(inode->i_mode)) - retval = -EPERM; - else if (IS_NODEV(inode)) - retval = -EACCES; - iput(inode); - if (retval) - return retval; - if ((new_flags & 0xffff0000) == 0xC0ED0000) { - flags = new_flags & 0xffff; - if (data && (unsigned long) data < TASK_SIZE) - page = get_free_page(); - } - if (page) { - i = TASK_SIZE - (unsigned long) data; - if (i < 0 || i > 4095) - i = 4095; - memcpy_fromfs((void *) page,data,i); } if (type) { - for (i = 0 ; i < 100 ; i++) - if (!(tmp[i] = get_fs_byte(type++))) - break; + i = 0; + while (i < 100 && (tmp[i] = get_fs_byte(type++))) + i++; t = tmp; } else t = "minix"; - retval = do_mount(dev,dir_name,t,flags,(void *) page); - free_page(page); - return retval; + if (!(sb = read_super(dev,t,NULL))) { + iput(dir_i); + return -EBUSY; + } + if (sb->s_covered) { + iput(dir_i); + return -EBUSY; + } + sb->s_covered = dir_i; + dir_i->i_mount = 1; + dir_i->i_dirt = 1; /* NOTE! we don't iput(dir_i) */ + return 0; /* we do that in umount */ } void mount_root(void) @@ -306,7 +251,7 @@ void mount_root(void) p->s_lock = 0; p->s_wait = NULL; } - if (!(p=read_super(ROOT_DEV,"minix",0,NULL))) + if (!(p=read_super(ROOT_DEV,"minix",NULL))) panic("Unable to mount root"); /*wait_for_keypress(); if (!(mi=iget(ROOT_DEV,MINIX_ROOT_INO))) @@ -315,7 +260,6 @@ void mount_root(void) mi=p->s_mounted; mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */ p->s_mounted = p->s_covered = mi; - p->s_flags = 0; current->pwd = mi; current->root = mi; free=0; diff --git a/include/a.out.h b/include/a.out.h index 69bf01f3749e..5468aa41ec3e 100644 --- a/include/a.out.h +++ b/include/a.out.h @@ -72,8 +72,6 @@ enum machine_type { /* Code indicating demand-paged executable. */ #define ZMAGIC 0413 -/* Code indicating core file. */ -#define CMAGIC 0421 #if !defined (N_BADMAG) #define N_BADMAG(x) \ (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \ diff --git a/include/asm/io.h b/include/asm/io.h index 7c54b0f5d4da..226f3439bf60 100644 --- a/include/asm/io.h +++ b/include/asm/io.h @@ -1,36 +1,27 @@ #ifndef _ASM_IO_H #define _ASM_IO_H -/* - * Thanks to James van Artsdalen for a better timing-fix than - * the two short jumps: using outb's to a nonexistent port seems - * to guarantee better timings even on fast machines. - * - * Linus - */ - extern void inline outb(char value, unsigned short port) { -__asm__ __volatile__ ("outb %0,%1" +__asm__ volatile ("outb %0,%1" ::"a" ((char) value),"d" ((unsigned short) port)); } extern void inline outb_p(char value, unsigned short port) { -__asm__ __volatile__ ("outb %0,%1\n\t" -#ifdef REALLY_SLOW_IO - "outb %0,$0x80\n\t" - "outb %0,$0x80\n\t" - "outb %0,$0x80\n\t" -#endif - "outb %0,$0x80" +__asm__ volatile ("outb %0,%1\n" + "\tjmp 1f\n" + "1:\tjmp 1f\n" + "1:\tjmp 1f\n" + "1:\tjmp 1f\n" + "1:" ::"a" ((char) value),"d" ((unsigned short) port)); } extern unsigned char inline inb(unsigned short port) { unsigned char _v; -__asm__ __volatile__ ("inb %1,%0" +__asm__ volatile ("inb %1,%0" :"=a" (_v):"d" ((unsigned short) port)); return _v; } @@ -38,13 +29,12 @@ __asm__ __volatile__ ("inb %1,%0" extern unsigned char inline inb_p(unsigned short port) { unsigned char _v; -__asm__ __volatile__ ("inb %1,%0\n\t" -#ifdef REALLY_SLOW_IO - "outb %0,$0x80\n\t" - "outb %0,$0x80\n\t" - "outb %0,$0x80\n\t" -#endif - "outb %0,$0x80" +__asm__ volatile ("inb %1,%0\n" + "\tjmp 1f\n" + "1:\tjmp 1f\n" + "1:\tjmp 1f\n" + "1:\tjmp 1f\n" + "1:" :"=a" (_v):"d" ((unsigned short) port)); return _v; } diff --git a/include/asm/irq.h b/include/asm/irq.h deleted file mode 100644 index f9fbe02585b8..000000000000 --- a/include/asm/irq.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef _ASM_IRQ_H -#define _ASM_IRQ_H - -/* - * linux/include/asm/irq.h - * - * (C) 1992 Linus Torvalds - */ - -#define SAVE_ALL \ - "cld\n\t" \ - "push %gs\n\t" \ - "push %fs\n\t" \ - "push %es\n\t" \ - "push %ds\n\t" \ - "pushl %eax\n\t" \ - "pushl %ebp\n\t" \ - "pushl %edi\n\t" \ - "pushl %esi\n\t" \ - "pushl %edx\n\t" \ - "pushl %ecx\n\t" \ - "pushl %ebx\n\t" \ - "movl $0x10,%edx\n\t" \ - "mov %dx,%ds\n\t" \ - "mov %dx,%es\n\t" \ - "movl $0x17,%edx\n\t" \ - "mov %dx,%fs\n\t" - -#define ACK_FIRST(mask) \ - "inb $0x21,%al\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\torb $" #mask ",%al\n\t" \ - "outb %al,$0x21\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\tmovb $0x20,%al\n\t" \ - "outb %al,$0x20\n\t" - -#define ACK_SECOND(mask) \ - "inb $0xA1,%al\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\torb $" #mask ",%al\n\t" \ - "outb %al,$0xA1\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\tmovb $0x20,%al\n\t" \ - "outb %al,$0xA0\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\toutb %al,$0x20\n\t" - -#define UNBLK_FIRST(mask) \ - "inb $0x21,%al\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\tandb $~(" #mask "),%al\n\t" \ - "outb %al,$0x21\n\t" - -#define UNBLK_SECOND(mask) \ - "inb $0xA1,%al\n\t" \ - "jmp 1f\n" \ - "1:\tjmp 1f\n" \ - "1:\tandb $~(" #mask "),%al\n\t" \ - "outb %al,$0xA1\n\t" - -#define IRQ_NAME2(nr) nr##_interrupt() -#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) - -#define BUILD_IRQ(chip,nr,mask) \ -extern void IRQ_NAME(nr); \ -__asm__( \ -"\n.align 2\n" \ -".globl _IRQ" #nr "_interrupt\n" \ -"_IRQ" #nr "_interrupt:\n\t" \ - "pushl $-1\n\t" \ - SAVE_ALL \ - "cli\n\t" \ - ACK_##chip(mask) \ - "sti\n\t" \ - "movl %esp,%ebx\n\t" \ - "pushl %ebx\n\t" \ - "pushl $" #nr "\n\t" \ - "call _do_IRQ\n\t" \ - "addl $8,%esp\n\t" \ - "testl %eax,%eax\n\t" \ - "jne ret_from_sys_call\n\t" \ - "cli\n\t" \ - UNBLK_##chip(mask) \ - "sti\n\t" \ - "jmp ret_from_sys_call"); - -#endif diff --git a/include/asm/memory.h b/include/asm/memory.h index 0d2b7a29fd2e..4b0a98e7be4c 100644 --- a/include/asm/memory.h +++ b/include/asm/memory.h @@ -7,7 +7,7 @@ */ #define memcpy(dest,src,n) ({ \ void * _res = dest; \ -__asm__ __volatile__ ("cld;rep;movsb" \ +__asm__ ("cld;rep;movsb" \ ::"D" ((long)(_res)),"S" ((long)(src)),"c" ((long) (n)) \ :"di","si","cx"); \ _res; \ diff --git a/include/asm/segment.h b/include/asm/segment.h index b354a8a5fc6b..cf2890c27e04 100644 --- a/include/asm/segment.h +++ b/include/asm/segment.h @@ -94,6 +94,6 @@ extern inline unsigned long get_ds() extern inline void set_fs(unsigned long val) { - __asm__ __volatile__("mov %0,%%fs"::"r" ((unsigned short) val)); + __asm__("mov %0,%%fs"::"r" ((unsigned short) val)); } diff --git a/include/asm/system.h b/include/asm/system.h index 877ae34777e1..6fbcf1bba082 100644 --- a/include/asm/system.h +++ b/include/asm/system.h @@ -1,5 +1,5 @@ #define move_to_user_mode() \ -__asm__ __volatile__ ("movl %%esp,%%eax\n\t" \ +__asm__ ("movl %%esp,%%eax\n\t" \ "pushl $0x17\n\t" \ "pushl %%eax\n\t" \ "pushfl\n\t" \ @@ -13,14 +13,14 @@ __asm__ __volatile__ ("movl %%esp,%%eax\n\t" \ "mov %%ax,%%gs" \ :::"ax") -#define sti() __asm__ __volatile__ ("sti"::) -#define cli() __asm__ __volatile__ ("cli"::) -#define nop() __asm__ __volatile__ ("nop"::) +#define sti() __asm__ ("sti"::) +#define cli() __asm__ ("cli"::) +#define nop() __asm__ ("nop"::) -#define iret() __asm__ __volatile__ ("iret"::) +#define iret() __asm__ ("iret"::) #define _set_gate(gate_addr,type,dpl,addr) \ -__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ +__asm__ ("movw %%dx,%%ax\n\t" \ "movw %0,%%dx\n\t" \ "movl %%eax,%1\n\t" \ "movl %%edx,%2" \ @@ -50,7 +50,7 @@ __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ ((limit) & 0x0ffff); } #define _set_tssldt_desc(n,addr,type) \ -__asm__ __volatile__ ("movw $232,%1\n\t" \ +__asm__ ("movw $232,%1\n\t" \ "movw %%ax,%2\n\t" \ "rorl $16,%%eax\n\t" \ "movb %%al,%3\n\t" \ diff --git a/include/linux/fcntl.h b/include/fcntl.h similarity index 62% rename from include/linux/fcntl.h rename to include/fcntl.h index dcf49e3c5125..4bc0c10cf2b0 100644 --- a/include/linux/fcntl.h +++ b/include/fcntl.h @@ -3,19 +3,18 @@ #include -/* open/fcntl - O_SYNC isn't implemented yet */ -#define O_ACCMODE 0003 -#define O_RDONLY 00 -#define O_WRONLY 01 -#define O_RDWR 02 -#define O_CREAT 0100 /* not fcntl */ -#define O_EXCL 0200 /* not fcntl */ -#define O_NOCTTY 0400 /* not fcntl */ -#define O_TRUNC 01000 /* not fcntl */ -#define O_APPEND 02000 -#define O_NONBLOCK 04000 +/* open/fcntl - NOCTTY, NDELAY isn't implemented yet */ +#define O_ACCMODE 00003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 00100 /* not fcntl */ +#define O_EXCL 00200 /* not fcntl */ +#define O_NOCTTY 00400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 #define O_NDELAY O_NONBLOCK -#define O_SYNC 010000 /* Defines for fcntl-commands. Note that currently * locking isn't supported, and other things aren't really @@ -49,4 +48,8 @@ struct flock { pid_t l_pid; }; +extern int creat(const char * filename,mode_t mode); +extern int fcntl(int fildes,int cmd, ...); +extern int open(const char * filename, int flags, ...); + #endif diff --git a/include/linux/config.dist.h b/include/linux/config.dist.h deleted file mode 100644 index 4a84fbf3a3c4..000000000000 --- a/include/linux/config.dist.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _CONFIG_DIST_H -#define _CONFIG_DIST_H -#ifdef CONFIG_DISTRIBUTION - -#undef CONFG_SCSI -#define CONFIG_SCSI - -#undef CONFIG_SCSI_AHA1542 -#define CONFIG_SCSI_AHA1542 -#undef CONFIG_SCSI_CSC -#define CONFIG_SCSI_CSC -#undef CONFIG_SCSI_DTC -#define CONFIG_SCSI_DTC -#undef CONFIG_SCSI_FUTURE_DOMAIN -#define CONFIG_SCSI_FUTURE_DOMAIN -#undef CONFIG_SCSI_SEAGATE -#define CONFIG_SCSI_SEAGATE -#undef CONFIG_SCSI_ULTRASTOR -#define CONFIG_SCSI_ULTRASTOR - -#undef CONFIG_BLK_DEV_SD -#define CONFIG_BLK_DEV_SD -#undef CONFIG_BLK_DEV_ST -#define CONFIG_BLK_DEV_ST - -#endif -#endif diff --git a/include/linux/config.h b/include/linux/config.h index 0e5f4cd8ff56..8c79f935c375 100644 --- a/include/linux/config.h +++ b/include/linux/config.h @@ -1,8 +1,6 @@ #ifndef _CONFIG_H #define _CONFIG_H -#define CONFIG_DISTRIBUTION - /* * Defines for what uname() should return */ @@ -26,7 +24,7 @@ #define DEF_INITSEG 0x9000 #define DEF_SYSSEG 0x1000 #define DEF_SETUPSEG 0x9020 -#define DEF_SYSSIZE 0x5000 +#define DEF_SYSSIZE 0x4000 /* * The root-device is no longer hard-coded. You can change the default @@ -64,52 +62,4 @@ leave HD_TYPE undefined. This is the normal thing to do. */ -#undef HD_TYPE - -#undef CONFIG_BLK_DEV_SD -#undef CONFIG_BLK_DEV_ST - -/* - Choose supported SCSI adapters here. -*/ - -#undef CONFIG_SCSI_AHA1542 -#undef CONFIG_SCSI_ALWAYS -#undef CONFIG_SCSI_CSC -#undef CONFIG_SCSI_DTC -#undef CONFIG_SCSI_FUTURE_DOMAIN -#undef CONFIG_SCSI_SEAGATE -#undef CONFIG_SCSI_ULTRASTOR - -#if defined(CONFIG_BLK_DEV_SD) || defined(CONFIG_BLK_DEV_ST) - #ifndef CONFIG_SCSI - #define CONFIG_SCSI - #endif - - #if !defined(CONFIG_SCSI_AHA1542) && !defined(CONFIG_SCSI_CSC) && !defined(CONFIG_SCSI_DTC) && \ - !defined(CONFIG_SCSI_FUTURE_DOMAIN) && !defined(CONFIG_SCSI_SEAGATE) && !defined(CONFIG_SCSI_ULTRASTOR) - - #error Error : SCSI devices enabled, but no low level drivers have been enabled. - #endif -#endif - -#ifdef CONFIG_DISTRIBUTION - #include -#else - #include -#endif - -/* - File type specific stuff goes into this. -*/ - -#ifdef ASM_SRC -#endif - -#ifdef C_SRC -#endif - -#ifdef MAKE -#endif - #endif diff --git a/include/linux/config.site.h b/include/linux/config.site.h deleted file mode 100644 index 49b731bb0499..000000000000 --- a/include/linux/config.site.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _CONFIG_SITE_H -#define _CONFIG_SITE_H - -/* - This configuration file contains site specific things, things - that you have added and config.dist will not know about. -*/ - -#endif diff --git a/include/linux/config_rel.h b/include/linux/config_rel.h index c286ac2ffa5e..a602c1f56132 100644 --- a/include/linux/config_rel.h +++ b/include/linux/config_rel.h @@ -1 +1 @@ -#define UTS_RELEASE "0.96b-63" +#define UTS_RELEASE "0.95c-54" diff --git a/include/linux/config_ver.h b/include/linux/config_ver.h index d32d8b268bf7..34e98a9644b4 100644 --- a/include/linux/config_ver.h +++ b/include/linux/config_ver.h @@ -1 +1 @@ -#define UTS_VERSION "07/04/92" +#define UTS_VERSION "04/22/92" diff --git a/include/linux/ext_fs.h b/include/linux/ext_fs.h deleted file mode 100644 index 0877bdb61600..000000000000 --- a/include/linux/ext_fs.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * The ext filesystem constants/structures - */ - -#ifndef _EXT_FS_H -#define _EXT_FS_H - -#include - -/* - * Free blocks/inodes management style - * - * One of these two constants must be defined - * - */ -/* #define EXTFS_BITMAP */ /* use a bitmap */ -#define EXTFS_FREELIST /* use a linked list */ - -#define EXT_NAME_LEN 255 -#define EXT_ROOT_INO 1 - -#define EXT_I_MAP_SLOTS 8 -#define EXT_Z_MAP_SLOTS 8 -#define EXT_SUPER_MAGIC 0x137D - -#define EXT_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct ext_inode))) -/* #define EXT_DIR_ENTRIES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct ext_dir_entry))) */ - -struct ext_inode { - unsigned short i_mode; - unsigned short i_uid; - unsigned long i_size; - unsigned long i_time; - unsigned short i_gid; - unsigned short i_nlinks; - unsigned long i_zone[12]; -}; - -struct ext_free_inode { - unsigned long count; - unsigned long free[14]; - unsigned long next; -}; - -struct ext_free_block { - unsigned long count; - unsigned long free[254]; - unsigned long next; -}; - -struct ext_super_block { - unsigned long s_ninodes; - unsigned long s_nzones; -#ifdef EXTFS_BITMAP - unsigned long s_imap_blocks; - unsigned long s_zmap_blocks; -#endif -#ifdef EXTFS_FREELIST - unsigned long s_firstfreeblock; - unsigned long s_freeblockscount; - unsigned long s_firstfreeinode; - unsigned long s_freeinodescount; -#endif - unsigned long s_firstdatazone; - unsigned long s_log_zone_size; - unsigned long s_max_size; - unsigned long s_reserved1; - unsigned long s_reserved2; - unsigned long s_reserved3; - unsigned long s_reserved4; - unsigned long s_reserved5; - unsigned short s_magic; -}; - -struct ext_dir_entry { - unsigned long inode; - unsigned short rec_len; - unsigned short name_len; - char name[EXT_NAME_LEN]; -}; - -extern int ext_open(struct inode * inode, struct file * filp); -extern void ext_release(struct inode * inode, struct file * filp); -extern int ext_lookup(struct inode * dir,const char * name, int len, - struct inode ** result); -extern int ext_create(struct inode * dir,const char * name, int len, int mode, - struct inode ** result); -extern int ext_mkdir(struct inode * dir, const char * name, int len, int mode); -extern int ext_rmdir(struct inode * dir, const char * name, int len); -extern int ext_unlink(struct inode * dir, const char * name, int len); -extern int ext_symlink(struct inode * inode, const char * name, int len, - const char * symname); -extern int ext_link(struct inode * oldinode, struct inode * dir, const char * name, int len); -extern int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev); -extern int ext_rename(struct inode * old_dir, const char * old_name, int old_len, - struct inode * new_dir, const char * new_name, int new_len); -extern struct inode * ext_new_inode(int dev); -extern void ext_free_inode(struct inode * inode); -extern unsigned long ext_count_free_inodes(struct super_block *sb); -extern int ext_new_block(int dev); -extern int ext_free_block(int dev, int block); -extern unsigned long ext_count_free_blocks(struct super_block *sb); - -extern int ext_create_block(struct inode *, int); -extern int ext_bmap(struct inode *,int); - -extern void ext_truncate(struct inode *); -extern void ext_put_super(struct super_block *); -extern void ext_write_super(struct super_block *); -extern struct super_block *ext_read_super(struct super_block *,void *); -extern void ext_read_inode(struct inode *); -extern void ext_write_inode(struct inode *); -extern void ext_put_inode(struct inode *); -extern void ext_statfs(struct super_block *, struct statfs *); - -extern int ext_lseek(struct inode *, struct file *, off_t, int); -extern int ext_read(struct inode *, struct file *, char *, int); -extern int ext_write(struct inode *, struct file *, char *, int); - -extern struct inode_operations ext_file_inode_operations; -extern struct inode_operations ext_dir_inode_operations; -extern struct inode_operations ext_symlink_inode_operations; -extern struct inode_operations ext_chrdev_inode_operations; -extern struct inode_operations ext_blkdev_inode_operations; -extern struct inode_operations ext_fifo_inode_operations; - -extern struct file_operations ext_file_operations; -extern struct file_operations ext_dir_operations; - -#endif diff --git a/include/linux/fd.h b/include/linux/fd.h deleted file mode 100644 index d490194a64ba..000000000000 --- a/include/linux/fd.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _FD_H -#define _FD_H - -#define FDCLRPRM 0 /* clear user-defined parameters */ -#define FDSETPRM 1 /* set user-defined parameters for current media */ -#define FDDEFPRM 2 /* set user-defined parameters until explicitly cleared */ -#define FDGETPRM 3 /* get disk parameters */ -#define FDMSGON 4 /* issue kernel messages on media type change */ -#define FDMSGOFF 5 /* don't issue kernel messages on media type change */ -#define FDFMTBEG 6 /* begin formatting a disk */ -#define FDFMTTRK 7 /* format the specified track */ -#define FDFMTEND 8 /* end formatting a disk */ - -#define FD_FILL_BYTE 0xF6 /* format fill byte */ - -#define FORMAT_NONE 0 /* no format request */ -#define FORMAT_WAIT 1 /* format request is waiting */ -#define FORMAT_BUSY 2 /* formatting in progress */ -#define FORMAT_OKAY 3 /* successful completion */ -#define FORMAT_ERROR 4 /* formatting error */ - -struct floppy_struct { - unsigned int size, sect, head, track, stretch; - unsigned char gap,rate,spec1,fmt_gap; - char *name; /* used only for predefined formats */ -}; - -struct format_descr { - unsigned int device,head,track; -}; - -#endif diff --git a/include/linux/fdreg.h b/include/linux/fdreg.h index 77a270eb398c..01355af4a7ed 100644 --- a/include/linux/fdreg.h +++ b/include/linux/fdreg.h @@ -63,7 +63,6 @@ extern void floppy_deselect(unsigned int nr); #define FD_WRITE 0xC5 /* write with MT, MFM */ #define FD_SENSEI 0x08 /* Sense Interrupt Status */ #define FD_SPECIFY 0x03 /* specify HUT etc */ -#define FD_FORMAT 0x4D /* format one track */ /* DMA commands */ #define DMA_READ 0x46 diff --git a/include/linux/fs.h b/include/linux/fs.h index 925f64a1b063..7e067bde4f94 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -6,12 +6,8 @@ #ifndef _FS_H #define _FS_H -#include -#include - #include #include -#include /* devices are as follows: (same as minix, so we can use the minix * file system. These are major numbers.) @@ -24,11 +20,9 @@ * 5 - /dev/tty * 6 - /dev/lp * 7 - unnamed pipes - * 8 - /dev/sd - * 9 - /dev/st */ -#define IS_SEEKABLE(x) ((x)>=1 && (x)<=3 || (x)==8) +#define IS_SEEKABLE(x) ((x)>=1 && (x)<=3) #define MAY_EXEC 1 #define MAY_WRITE 2 @@ -44,6 +38,17 @@ void buffer_init(long buffer_end); #define MAJOR(a) (((unsigned)(a))>>8) #define MINOR(a) ((a)&0xff) +#define NR_OPEN 20 +#define NR_INODE 128 +#define NR_FILE 64 +#define NR_SUPER 8 +#define NR_HASH 307 +#define NR_BUFFERS nr_buffers +#define BLOCK_SIZE 1024 +#define BLOCK_SIZE_BITS 10 +#define MAX_CHRDEV 16 +#define MAX_BLKDEV 16 + #ifndef NULL #define NULL ((void *) 0) #endif @@ -52,8 +57,6 @@ void buffer_init(long buffer_end); #define PIPE_WRITE_WAIT(inode) ((inode).i_wait2) #define PIPE_HEAD(inode) ((inode).i_data[0]) #define PIPE_TAIL(inode) ((inode).i_data[1]) -#define PIPE_READERS(inode) ((inode).i_data[2]) -#define PIPE_WRITERS(inode) ((inode).i_data[3]) #define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1)) #define PIPE_EMPTY(inode) (PIPE_HEAD(inode)==PIPE_TAIL(inode)) #define PIPE_FULL(inode) (PIPE_SIZE(inode)==(PAGE_SIZE-1)) @@ -63,35 +66,6 @@ void buffer_init(long buffer_end); #define SEL_OUT 2 #define SEL_EX 4 -/* - * These are the fs-independent mount-flags: up to 16 flags are supported - */ -#define MS_RDONLY 1 /* mount read-only */ -#define MS_NOSUID 2 /* ignore suid and sgid bits */ -#define MS_NODEV 4 /* disallow access to device special files */ -#define MS_NOEXEC 8 /* disallow program execution */ -#define MS_SYNC 16 /* writes are synced at once */ - -/* - * Note that read-only etc flags are inode-specific: setting some file-system - * flags just means all the inodes inherit those flags by default. It might be - * possible to overrride it sevelctively if you really wanted to with some - * ioctl() that is not currently implemented. - */ -#define IS_RDONLY(inode) ((inode)->i_flags & MS_RDONLY) -#define IS_NOSUID(inode) ((inode)->i_flags & MS_NOSUID) -#define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV) -#define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC) -#define IS_SYNC(inode) ((inode)->i_flags & MS_SYNC) - -/* the read-only stuff doesn't really belong here, but any other place is - probably as bad and I don't want to create yet another include file. */ - -#define BLKROSET 4701 /* set device read-only (0 = read-write) */ -#define BLKROGET 4702 /* get read-only status (0 = read_write) */ - -#define BMAP_IOCTL 1 - typedef char buffer_block[BLOCK_SIZE]; struct buffer_head { @@ -102,33 +76,31 @@ struct buffer_head { unsigned char b_dirt; /* 0-clean,1-dirty */ unsigned char b_count; /* users using this block */ unsigned char b_lock; /* 0 - ok, 1 -locked */ - struct wait_queue * b_wait; + struct task_struct * b_wait; struct buffer_head * b_prev; struct buffer_head * b_next; struct buffer_head * b_prev_free; struct buffer_head * b_next_free; - struct buffer_head * b_reqnext; }; struct inode { - dev_t i_dev; - unsigned long i_ino; - umode_t i_mode; - nlink_t i_nlink; - uid_t i_uid; - gid_t i_gid; - dev_t i_rdev; - off_t i_size; - time_t i_atime; - time_t i_mtime; - time_t i_ctime; + dev_t i_dev; + ino_t i_ino; + umode_t i_mode; + nlink_t i_nlink; + uid_t i_uid; + gid_t i_gid; + dev_t i_rdev; + off_t i_size; + time_t i_atime; + time_t i_mtime; + time_t i_ctime; unsigned long i_data[16]; struct inode_operations * i_op; struct super_block * i_sb; - struct wait_queue * i_wait; - struct wait_queue * i_wait2; /* for pipes */ + struct task_struct * i_wait; + struct task_struct * i_wait2; /* for pipes */ unsigned short i_count; - unsigned short i_flags; unsigned char i_lock; unsigned char i_dirt; unsigned char i_pipe; @@ -141,20 +113,30 @@ struct file { unsigned short f_mode; unsigned short f_flags; unsigned short f_count; - unsigned short f_reada; - unsigned short f_rdev; /* needed for /dev/tty */ struct inode * f_inode; struct file_operations * f_op; off_t f_pos; }; +typedef struct { + struct task_struct * old_task; + struct task_struct ** wait_address; +} wait_entry; + +typedef struct select_table_struct { + int nr, woken; + struct task_struct * current; + struct select_table_struct * next_table; + wait_entry entry[NR_OPEN*3]; +} select_table; + struct super_block { - unsigned long s_ninodes; - unsigned long s_nzones; - unsigned long s_imap_blocks; - unsigned long s_zmap_blocks; - unsigned long s_firstdatazone; - unsigned long s_log_zone_size; + unsigned short s_ninodes; + unsigned short s_nzones; + unsigned short s_imap_blocks; + unsigned short s_zmap_blocks; + unsigned short s_firstdatazone; + unsigned short s_log_zone_size; unsigned long s_max_size; unsigned short s_magic; /* These are only in memory */ @@ -164,13 +146,12 @@ struct super_block { struct inode * s_covered; struct inode * s_mounted; unsigned long s_time; - struct wait_queue * s_wait; + struct task_struct * s_wait; unsigned char s_lock; unsigned char s_rd_only; unsigned char s_dirt; /* TUBE */ struct super_operations *s_op; - int s_flags; }; struct file_operations { @@ -178,14 +159,12 @@ struct file_operations { int (*read) (struct inode *, struct file *, char *, int); int (*write) (struct inode *, struct file *, char *, int); int (*readdir) (struct inode *, struct file *, struct dirent *, int count); + int (*close) (struct inode *, struct file *); int (*select) (struct inode *, struct file *, int, select_table *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned int); - int (*open) (struct inode *, struct file *); - void (*release) (struct inode *, struct file *); }; struct inode_operations { - struct file_operations * default_file_ops; int (*create) (struct inode *,const char *,int,int,struct inode **); int (*lookup) (struct inode *,const char *,int,struct inode **); int (*link) (struct inode *,struct inode *,const char *,int); @@ -196,18 +175,19 @@ struct inode_operations { int (*mknod) (struct inode *,const char *,int,int,int); int (*rename) (struct inode *,const char *,int,struct inode *,const char *,int); int (*readlink) (struct inode *,char *,int); + int (*open) (struct inode *, struct file *); + void (*release) (struct inode *, struct file *); struct inode * (*follow_link) (struct inode *, struct inode *); int (*bmap) (struct inode *,int); void (*truncate) (struct inode *); + /* added by entropy */ + void (*write_inode)(struct inode *inode); + void (*put_inode)(struct inode *inode); }; struct super_operations { void (*read_inode)(struct inode *inode); - void (*write_inode) (struct inode *inode); - void (*put_inode) (struct inode *inode); void (*put_super)(struct super_block *sb); - void (*write_super) (struct super_block *sb); - void (*statfs) (struct super_block *sb, struct statfs *buf); }; struct file_system_type { @@ -227,11 +207,11 @@ extern struct buffer_head * start_buffer; extern int nr_buffers; extern void check_disk_change(int dev); -extern void invalidate_inodes(int dev); extern int floppy_change(struct buffer_head * first_block); extern int ticks_to_floppy_on(unsigned int dev); extern void floppy_on(unsigned int dev); extern void floppy_off(unsigned int dev); +extern void truncate(struct inode * inode); extern void sync_inodes(void); extern void wait_on(struct inode * inode); extern int bmap(struct inode * inode,int block); @@ -242,7 +222,6 @@ extern struct inode * _namei(const char * filename, struct inode * base, int follow_links); extern int open_namei(const char * pathname, int flag, int mode, struct inode ** res_inode); -extern int do_mknod(const char * filename, int mode, int dev); extern void iput(struct inode * inode); extern struct inode * iget(int dev,int nr); extern struct inode * get_empty_inode(void); @@ -258,7 +237,6 @@ extern void bread_page(unsigned long addr,int dev,int b[4]); extern struct buffer_head * breada(int dev,int block,...); extern int sync_dev(int dev); extern struct super_block * get_super(int dev); -extern void put_super(int dev); extern int ROOT_DEV; extern void mount_root(void); diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h index 67e538683b30..e7e134762d4a 100644 --- a/include/linux/hdreg.h +++ b/include/linux/hdreg.h @@ -69,6 +69,5 @@ struct hd_geometry { unsigned char heads; unsigned char sectors; unsigned short cylinders; - unsigned long start; }; #endif diff --git a/include/linux/kernel.h b/include/linux/kernel.h index ef27d832fa17..2451af9c86bb 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -4,7 +4,9 @@ void verify_area(void * addr,int count); volatile void panic(const char * str); volatile void do_exit(long error_code); +int printf(const char * fmt, ...); int printk(const char * fmt, ...); +void console_print(const char * str); void * malloc(unsigned int size); void free_s(void * obj, int size); diff --git a/include/linux/limits.h b/include/linux/limits.h deleted file mode 100644 index 97450b7ab7fa..000000000000 --- a/include/linux/limits.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _LINUX_LIMITS_H -#define _LINUX_LIMITS_H - -#define NR_OPEN 32 -#define NR_INODE 128 -#define NR_FILE 128 -#define NR_SUPER 8 -#define NR_HASH 307 -#define NR_BUFFERS nr_buffers -#define BLOCK_SIZE 1024 -#define BLOCK_SIZE_BITS 10 -#define MAX_CHRDEV 16 -#define MAX_BLKDEV 16 - - -#endif diff --git a/include/linux/lp.h b/include/linux/lp.h index 785b17d178a8..6e565dad6f6a 100644 --- a/include/linux/lp.h +++ b/include/linux/lp.h @@ -31,7 +31,9 @@ $Header: /usr/src/linux/include/linux/lp.h,v 1.2 1992/01/21 23:59:24 james_r_wie #define LP_B(minor) lp_table[(minor)].base #define LP_F(minor) lp_table[(minor)].flags +#define LP_T(minor) lp_table[(minor)].lp_task #define LP_S(minor) inb(LP_B((minor)) + 1) +#define LP_R(minor) lp_table[(minor)].remainder /* since we are dealing with a horribly slow device @@ -43,6 +45,10 @@ I don't see the need for a queue struct lp_struct { int base; int flags; + /* number of characters yet to be printed in current block */ + int remainder; + /* needed for busy determination */ + int lp_task; }; /* @@ -100,4 +106,4 @@ struct lp_struct lp_table[] = { * function prototypes */ -extern long lp_init(long); +extern void lp_init(void); diff --git a/include/linux/math_emu.h b/include/linux/math_emu.h index 64e734c3fee5..c5501b6eae0d 100644 --- a/include/linux/math_emu.h +++ b/include/linux/math_emu.h @@ -177,10 +177,6 @@ void fmul(const temp_real *, const temp_real *, temp_real *); void fdiv(const temp_real *, const temp_real *, temp_real *); -/* sqrt.c */ - -void fsqrt(const temp_real *, temp_real *); - /* compare.c */ void fcom(const temp_real *, const temp_real *); diff --git a/include/linux/minix_fs.h b/include/linux/minix_fs.h index 99b9f45fc7da..c427cb131b0e 100644 --- a/include/linux/minix_fs.h +++ b/include/linux/minix_fs.h @@ -45,6 +45,7 @@ struct minix_dir_entry { extern int minix_open(struct inode * inode, struct file * filp); extern void minix_release(struct inode * inode, struct file * filp); +extern struct inode * minix_follow_link(struct inode * dir, struct inode * inode); extern int minix_lookup(struct inode * dir,const char * name, int len, struct inode ** result); extern int minix_create(struct inode * dir,const char * name, int len, int mode, @@ -58,12 +59,11 @@ extern int minix_link(struct inode * oldinode, struct inode * dir, const char * extern int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rdev); extern int minix_rename(struct inode * old_dir, const char * old_name, int old_len, struct inode * new_dir, const char * new_name, int new_len); +extern int minix_readlink(struct inode * inode, char * buffer, int buflen); extern struct inode * minix_new_inode(int dev); extern void minix_free_inode(struct inode * inode); -extern unsigned long minix_count_free_inodes(struct super_block *sb); extern int minix_new_block(int dev); extern int minix_free_block(int dev, int block); -extern unsigned long minix_count_free_blocks(struct super_block *sb); extern int minix_create_block(struct inode *, int); extern int minix_bmap(struct inode *,int); @@ -73,20 +73,15 @@ extern void minix_put_super(struct super_block *); extern struct super_block *minix_read_super(struct super_block *,void *); extern void minix_read_inode(struct inode *); extern void minix_write_inode(struct inode *); -extern void minix_put_inode(struct inode *); -extern void minix_statfs(struct super_block *, struct statfs *); extern int minix_lseek(struct inode *, struct file *, off_t, int); extern int minix_read(struct inode *, struct file *, char *, int); extern int minix_write(struct inode *, struct file *, char *, int); +extern int minix_readdir(struct inode *, struct file *, struct dirent *, int); extern int minix_file_read(struct inode *, struct file *, char *, int); +extern int minix_file_write(struct inode *, struct file *, char *, int); -extern struct inode_operations minix_file_inode_operations; -extern struct inode_operations minix_dir_inode_operations; -extern struct inode_operations minix_symlink_inode_operations; -extern struct inode_operations minix_chrdev_inode_operations; -extern struct inode_operations minix_blkdev_inode_operations; -extern struct inode_operations minix_fifo_inode_operations; +extern struct inode_operations minix_inode_operations; extern struct file_operations minix_file_operations; extern struct file_operations minix_dir_operations; diff --git a/include/linux/mm.h b/include/linux/mm.h index 4b3b61b42bd0..e1eacea98b03 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -17,29 +17,11 @@ extern void rw_swap_page(int rw, unsigned int nr, char * buf); #define write_swap_page(nr,buf) \ rw_swap_page(WRITE,(nr),(buf)) -/* memory.c */ - extern unsigned long get_free_page(void); extern unsigned long put_dirty_page(unsigned long page,unsigned long address); extern void free_page(unsigned long addr); -extern int free_page_tables(unsigned long from,unsigned long size); -extern int copy_page_tables(unsigned long from,unsigned long to,long size); -extern int unmap_page_range(unsigned long from, unsigned long size); -extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size, - int permiss); -extern void un_wp_page(unsigned long * table_entry); -extern void do_wp_page(unsigned long error_code,unsigned long address); -extern void write_verify(unsigned long address); -extern void do_no_page(unsigned long error_code, unsigned long address, - struct task_struct *tsk, unsigned long user_esp); -extern void mem_init(long start_mem, long end_mem); -extern void show_mem(void); -extern void do_page_fault(unsigned long *esp, unsigned long error_code); - -/* swap.c */ - -extern void swap_free(int page_nr); -extern void swap_in(unsigned long *table_ptr); +void swap_free(int page_nr); +void swap_in(unsigned long *table_ptr); extern inline volatile void oom(void) { diff --git a/include/linux/mouse.h b/include/linux/mouse.h deleted file mode 100644 index 913123c2464f..000000000000 --- a/include/linux/mouse.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * linux/include/linux/mouse.h: header file for Logitech Bus Mouse driver - * by James Banks - * - * based on information gleamed from various mouse drivers on the net - * - * Heavily modified by David giller (rafetmad@oxy.edu) - * - * Minor modifications for Linux 0.96c-pl1 by Nathan Laredo - * gt7080a@prism.gatech.edu (13JUL92) - * - */ - -#ifndef _MOUSE_H -#define _MOUSE_H - -#define MOUSE_IRQ 5 - -#define MSE_DATA_PORT 0x23c -#define MSE_SIGNATURE_PORT 0x23d -#define MSE_CONTROL_PORT 0x23e -#define MSE_INTERRUPT_PORT 0x23e -#define MSE_CONFIG_PORT 0x23f - -#define MSE_ENABLE_INTERRUPTS 0x00 -#define MSE_DISABLE_INTERRUPTS 0x10 - -#define MSE_READ_X_LOW 0x80 -#define MSE_READ_X_HIGH 0xa0 -#define MSE_READ_Y_LOW 0xc0 -#define MSE_READ_Y_HIGH 0xe0 - -/* Magic number used to check if the mouse exists */ -#define MSE_CONFIG_BYTE 0x91 -#define MSE_DEFAULT_MODE 0x90 -#define MSE_SIGNATURE_BYTE 0xa5 - -/* useful macros */ - -#define MSE_INT_OFF() outb(MSE_DISABLE_INTERRUPTS, MSE_CONTROL_PORT) -#define MSE_INT_ON() outb(MSE_ENABLE_INTERRUPTS, MSE_CONTROL_PORT) - -struct mouse_status - { - char buttons; - char latch_buttons; - int dx; - int dy; - - int present; - int ready; - int active; - - struct inode *inode; - }; - -/* Function Prototypes */ -extern long mouse_init(long); - -#endif - diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h deleted file mode 100644 index 719dcc30aeb0..000000000000 --- a/include/linux/msdos_fs.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * The MS-DOS filesystem constants/structures - */ - -#ifndef _MSDOS_FS_H -#define _MSDOS_FS_H - -#include -#include - -#define MSDOS_ROOT_INO 1 -#define SECTOR_SIZE 512 /* sector size (bytes) */ -#define SECTOR_BITS 9 /* log2(SECTOR_SIZE) */ -#define MSDOS_DPB (MSDOS_DPS*2) /* dir entries per block */ -#define MSDOS_DPB_BITS 5 /* log2(MSDOS_DPB) */ -#define MSDOS_DPS (SECTOR_SIZE/sizeof(struct msdos_dir_entry)) -#define MSDOS_DPS_BITS 4 /* log2(MSDOS_DPS) */ -#define MSDOS_DIR_BITS 5 /* log2(sizeof(struct msdos_dir_entry)) */ - -#define MSDOS_SUPER_MAGIC 0x4d44 /* MD */ - -#define FAT_CACHE 8 /* FAT cache size */ - -#define ATTR_RO 1 /* read-only */ -#define ATTR_HIDDEN 2 /* hidden */ -#define ATTR_SYS 4 /* system */ -#define ATTR_VOLUME 8 /* volume label */ -#define ATTR_DIR 16 /* directory */ -#define ATTR_ARCH 32 /* archived */ - -#define ATTR_NONE 0 /* no attribute bits */ -#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS) - /* attribute bits that are copied "as is" */ - -#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */ - -#define D_START 0 /* i_data[0]: first cluster or 0 */ -#define D_ATTRS 1 /* i_data[1]: unused attribute bits */ -#define D_BUSY 2 /* i_data[2]: file is either deleted but still open, or - inconsistent (mkdir) */ -#define D_DEPEND 3 /* i_data[3]: pointer to inode that depends on the current - inode */ -#define D_OLD 4 /* i_data[4]: pointer to the old inode this inode depends - on */ -#define D_BINARY 5 /* i_data[5]: file contains non-text data */ - -#define SET_DIRTY(i) (i)->i_dirt = (i)->i_data[D_DIRT] = 1 - -#define MSDOS_SB(s) ((struct msdos_sb_info *) s) - -#define MSDOS_NAME 11 /* maximum name length */ -#define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */ -#define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */ - -#define MSDOS_FAT12 4086 /* maximum number of clusters in a 12 bit FAT */ - -struct msdos_boot_sector { - char ignored[13]; - unsigned char cluster_size; /* sectors/cluster */ - unsigned short reserved; /* reserved sectors */ - unsigned char fats; /* number of FATs */ - unsigned char dir_entries[2];/* root directory entries */ - unsigned char sectors[2]; /* number of sectors */ - unsigned char media; /* media code (unused) */ - unsigned short fat_length; /* sectors/FAT */ - unsigned short secs_track; /* sectors per track (unused) */ - unsigned short heads; /* number of heads (unused) */ - unsigned long hidden; /* hidden sectors (unused) */ - unsigned long total_sect; /* number of sectors (if sectors == 0) */ -}; - -struct msdos_sb_info { /* space in struct super_block is 28 bytes */ - unsigned short cluster_size; /* sectors/cluster */ - unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */ - unsigned short fat_start,fat_length; /* FAT start & length (sec.) */ - unsigned short dir_start,dir_entries; /* root dir start & entries */ - unsigned short data_start; /* first data sector */ - unsigned long clusters; /* number of clusters */ - uid_t fs_uid; - gid_t fs_gid; - unsigned short fs_umask; - unsigned char name_check; /* r = releaxed, n = normal, s = strict */ - unsigned char conversion; /* b = binary, t = text, a = auto */ -}; /* 28 bytes */ - -struct msdos_dir_entry { - char name[8],ext[3]; /* name and extension */ - unsigned char attr; /* attribute bits */ - char unused[10]; - unsigned short time,date,start; /* time, date and first cluster */ - unsigned long size; /* file size (in bytes) */ -}; - -struct fat_cache { - int device; /* device number. 0 means unused. */ - int ino; /* inode number. */ - int file_cluster; /* cluster number in the file. */ - int disk_cluster; /* cluster number on disk. */ - struct fat_cache *next; /* next cache entry */ -}; - -/* Determine whether this FS has kB-aligned data. */ - -#define MSDOS_CAN_BMAP(mib) (!(((mib)->cluster_size & 1) || \ - ((mib)->data_start & 1))) - -/* Convert attribute bits and a mask to the UNIX mode. */ - -#define MSDOS_MKMODE(a,m) (m & (a & ATTR_RO ? 0444 : (a & ATTR_HIDDEN ? 0 : \ - 0777))) - -/* Convert the UNIX mode to MS-DOS attribute bits. */ - -#define MSDOS_MKATTR(m) (!(m & 0600) ? ATTR_HIDDEN : ((m & 0600) == 0400 ? \ - ATTR_RO : ATTR_NONE)) - - -static inline struct buffer_head *msdos_sread(int dev,int sector,void **start) -{ - struct buffer_head *bh; - - if (!(bh = bread(dev,sector >> 1))) return NULL; - *start = bh->b_data+((sector & 1) << SECTOR_BITS); - return bh; -} - - -/* misc.c */ - -extern int is_binary(char conversion,char *extension); -extern void lock_creation(void); -extern void unlock_creation(void); -extern int msdos_add_cluster(struct inode *inode); -extern int date_dos2unix(unsigned short time,unsigned short date); -extern void date_unix2dos(int unix_date,unsigned short *time, - unsigned short *date); -extern int msdos_get_entry(struct inode *dir,int *pos,struct buffer_head **bh, - struct msdos_dir_entry **de); -extern int msdos_scan(struct inode *dir,char *name,struct buffer_head **res_bh, - struct msdos_dir_entry **res_de,int *ino); -extern int msdos_parent_ino(struct inode *dir,int locked); - -/* fat.c */ - -extern int fat_access(struct super_block *sb,int this,int new_value); -extern int msdos_smap(struct inode *inode,int sector); -extern int fat_free(struct inode *inode,int skip); -extern void cache_init(void); -void cache_lookup(struct inode *inode,int cluster,int *f_clu,int *d_clu); -void cache_add(struct inode *inode,int f_clu,int d_clu); -void cache_inval_inode(struct inode *inode); -void cache_inval_dev(int device); -int get_cluster(struct inode *inode,int cluster); - -/* namei.c */ - -extern int msdos_lookup(struct inode *dir,const char *name,int len, - struct inode **result); -extern int msdos_create(struct inode *dir,const char *name,int len,int mode, - struct inode **result); -extern int msdos_mkdir(struct inode *dir,const char *name,int len,int mode); -extern int msdos_rmdir(struct inode *dir,const char *name,int len); -extern int msdos_unlink(struct inode *dir,const char *name,int len); -extern int msdos_rename(struct inode *old_dir,const char *old_name,int old_len, - struct inode *new_dir,const char *new_name,int new_len); - -/* inode.c */ - -extern void msdos_put_inode(struct inode *inode); -extern void msdos_put_super(struct super_block *sb); -extern struct super_block *msdos_read_super(struct super_block *s,void *data); -extern void msdos_statfs(struct super_block *sb,struct statfs *buf); -extern int msdos_bmap(struct inode *inode,int block); -extern void msdos_read_inode(struct inode *inode); -extern void msdos_write_inode(struct inode *inode); - -/* dir.c */ - -extern struct file_operations msdos_dir_operations; -extern struct inode_operations msdos_dir_inode_operations; - -/* file.c */ - -extern struct file_operations msdos_file_operations; -extern struct inode_operations msdos_file_inode_operations; -extern struct inode_operations msdos_file_inode_operations_no_bmap; - -extern void msdos_truncate(struct inode *inode); - -#endif diff --git a/include/linux/sched.h b/include/linux/sched.h index 8065edd57efe..9d744cbba3f1 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -60,8 +60,10 @@ #define MAX_SHARED_LIBS 6 +extern int copy_page_tables(unsigned long from, unsigned long to, long size); +extern int free_page_tables(unsigned long from, unsigned long size); + extern void sched_init(void); -extern void show_state(void); extern void schedule(void); extern void trap_init(void); extern void panic(const char * str); @@ -117,26 +119,22 @@ struct task_struct { long blocked; /* bitmap of masked signals */ /* various fields */ int exit_code; - int dumpable; unsigned long start_code,end_code,end_data,brk,start_stack; long pid,pgrp,session,leader; int groups[NGROUPS]; /* - * pointers to (original) parent process, youngest child, younger sibling, + * pointers to parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with * p->p_pptr->pid) */ - struct task_struct *p_opptr,*p_pptr, *p_cptr, *p_ysptr, *p_osptr; + struct task_struct *p_pptr, *p_cptr, *p_ysptr, *p_osptr; /* - * For ease of programming... Normal sleeps don't need to - * keep track of a wait-queue: every task has an entry of it's own + * sleep makes a singly linked list with this. */ - struct wait_queue wait; + struct task_struct *next_wait; unsigned short uid,euid,suid; unsigned short gid,egid,sgid; - unsigned long timeout; - unsigned long it_real_value, it_prof_value, it_virt_value; - unsigned long it_real_incr, it_prof_incr, it_virt_incr; + unsigned long timeout,alarm; long utime,stime,cutime,cstime,start_time; unsigned long min_flt, maj_flt; unsigned long cmin_flt, cmaj_flt; @@ -183,13 +181,12 @@ struct task_struct { #define INIT_TASK \ /* state etc */ { 0,15,15, \ /* signals */ 0,{{},},0, \ -/* ec,brk... */ 0,0,0,0,0,0,0, \ +/* ec,brk... */ 0,0,0,0,0,0, \ /* pid etc.. */ 0,0,0,0, \ /* suppl grps*/ {NOGROUP,}, \ -/* proc links*/ &init_task.task,&init_task.task,NULL,NULL,NULL, \ -/* wait queue*/ {&init_task.task,NULL}, \ +/* proc links*/ &init_task.task,NULL,NULL,NULL,NULL, \ /* uid etc */ 0,0,0,0,0,0, \ -/* timeout */ 0,0,0,0,0,0,0,0,0,0,0,0, \ +/* timeout */ 0,0,0,0,0,0,0, \ /* min_flt */ 0,0,0,0, \ /* rlimits */ { {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}, \ {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}, \ @@ -224,19 +221,11 @@ extern int jiffies_offset; #define CURRENT_TIME (startup_time+(jiffies+jiffies_offset)/HZ) extern void add_timer(long jiffies, void (*fn)(void)); - -extern void sleep_on(struct wait_queue ** p); -extern void interruptible_sleep_on(struct wait_queue ** p); -extern void wake_up(struct wait_queue ** p); -extern void wake_one_task(struct task_struct * p); - -extern int send_sig(long sig,struct task_struct * p,int priv); +extern void sleep_on(struct task_struct ** p); +extern void interruptible_sleep_on(struct task_struct ** p); +extern void wake_up(struct task_struct ** p); extern int in_group_p(gid_t grp); -extern int request_irq(unsigned int irq,void (*handler)(int)); -extern void free_irq(unsigned int irq); -extern int irqaction(unsigned int irq,struct sigaction * new); - /* * Entry into gdt where to find first TSS. 0-nul, 1-cs, 2-ds, 3-syscall * 4-TSS0, 5-LDT0, 6-TSS1 etc ... @@ -264,10 +253,8 @@ struct {long a,b;} __tmp; \ __asm__("cmpl %%ecx,_current\n\t" \ "je 1f\n\t" \ "movw %%dx,%1\n\t" \ - "cli\n\t" \ "xchgl %%ecx,_current\n\t" \ "ljmp %0\n\t" \ - "sti\n\t" \ "cmpl %%ecx,_last_task_used_math\n\t" \ "jne 1f\n\t" \ "clts\n" \ @@ -305,51 +292,6 @@ __asm__("movw %%dx,%0\n\t" \ #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base ) #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 ) -extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wait) -{ - unsigned long flags; - struct wait_queue * tmp; - - __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); - wait->next = *p; - tmp = wait; - while (tmp->next) - if ((tmp = tmp->next)->next == *p) - break; - *p = tmp->next = wait; - __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); -} - -extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait) -{ - unsigned long flags; - struct wait_queue * tmp; - - __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); - if (*p == wait) - if ((*p = wait->next) == wait) - *p = NULL; - tmp = wait; - while (tmp && tmp->next != wait) - tmp = tmp->next; - if (tmp) - tmp->next = wait->next; - wait->next = NULL; - __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); -} - -extern inline void select_wait(struct wait_queue ** wait_address, select_table * p) -{ - struct select_table_entry * entry = p->entry + p->nr; - - if (!wait_address) - return; - entry->wait_address = wait_address; - entry->wait.task = current; - add_wait_queue(wait_address,&entry->wait); - p->nr++; -} - static unsigned long inline _get_base(char * addr) { unsigned long __base; @@ -374,18 +316,4 @@ static unsigned long inline get_limit(unsigned long segment) return __limit+1; } -#define REMOVE_LINKS(p) \ - if ((p)->p_osptr) \ - (p)->p_osptr->p_ysptr = (p)->p_ysptr; \ - if ((p)->p_ysptr) \ - (p)->p_ysptr->p_osptr = (p)->p_osptr; \ - else \ - (p)->p_pptr->p_cptr = (p)->p_osptr - -#define SET_LINKS(p) \ - (p)->p_ysptr = NULL; \ - if ((p)->p_osptr = (p)->p_pptr->p_cptr) \ - (p)->p_osptr->p_ysptr = p; \ - (p)->p_pptr->p_cptr = p - #endif diff --git a/include/linux/string.h b/include/linux/string.h index 73c4ee2ec28c..7da1793d138e 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -1,12 +1,15 @@ #ifndef _STRING_H_ #define _STRING_H_ -#include - #ifndef NULL #define NULL ((void *) 0) #endif +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned int size_t; +#endif + extern char * strerror(int errno); /* @@ -273,7 +276,7 @@ extern char * ___strtok; extern inline char * strtok(char * s,const char * ct) { -register char * __res; +register char * __res __asm__("si"); __asm__("testl %1,%1\n\t" "jne 1f\n\t" "testl %0,%0\n\t" @@ -324,7 +327,12 @@ __asm__("testl %1,%1\n\t" "jne 8f\n\t" "movl %0,%1\n" "8:" - :"=b" (__res),"=S" (___strtok) +#if __GNUC__ == 2 + :"=r" (__res) +#else + :"=b" (__res) +#endif + ,"=S" (___strtok) :"0" (___strtok),"1" (s),"g" (ct) :"ax","cx","dx","di"); return __res; diff --git a/include/linux/sys.h b/include/linux/sys.h index 736ad01bc9d9..df8264c3806c 100644 --- a/include/linux/sys.h +++ b/include/linux/sys.h @@ -104,15 +104,6 @@ extern int sys_profil(); extern int sys_statfs(); extern int sys_fstatfs(); extern int sys_ioperm(); -extern int sys_socketcall(); -extern int sys_syslog(); -extern int sys_getitimer(); -extern int sys_setitimer(); -extern int sys_newstat(); -extern int sys_newlstat(); -extern int sys_newfstat(); -extern int sys_newuname(); -extern int sys_iopl(); fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read, sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link, @@ -132,9 +123,7 @@ sys_gettimeofday, sys_settimeofday, sys_getgroups, sys_setgroups, sys_select, sys_symlink, sys_lstat, sys_readlink, sys_uselib, sys_swapon, sys_reboot, sys_readdir, sys_mmap, sys_munmap, sys_truncate, sys_ftruncate, sys_fchmod, sys_fchown, sys_getpriority, -sys_setpriority, sys_profil, sys_statfs, sys_fstatfs, sys_ioperm, -sys_socketcall, sys_syslog, sys_setitimer, sys_getitimer, sys_newstat, -sys_newlstat, sys_newfstat, sys_newuname, sys_iopl }; +sys_setpriority, sys_profil, sys_statfs, sys_fstatfs, sys_ioperm }; /* So we don't have to do any more manual updating.... */ int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr); diff --git a/include/linux/timer.h b/include/linux/timer.h index aa92aa300a5b..ab3c74ed3be1 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -20,8 +20,6 @@ * HD_TIMER harddisk timer * * FLOPPY_TIMER floppy disk timer (not used right now) - * - * SCSI_TIMER scsi.c timeout timer */ #define BLANK_TIMER 0 @@ -39,7 +37,6 @@ #define HD_TIMER 16 #define FLOPPY_TIMER 17 -#define SCSI_TIMER 18 struct timer_struct { unsigned long expires; diff --git a/include/linux/tty.h b/include/linux/tty.h index 329165ed65f9..22f0f0e98836 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -9,18 +9,11 @@ #ifndef _TTY_H #define _TTY_H -#include - -#define NR_CONSOLES 8 +#define MAX_CONSOLES 8 #define NR_SERIALS 4 #define NR_PTYS 4 -/* - * This character is the same as _POSIX_VDISABLE: it cannot be used as - * a c_cc[] character, but indicates that a particular special character - * isn't in use (eg VINTR ahs no character etc) - */ -#define __DISABLED_CHAR '\0' +extern int NR_CONSOLES; #include @@ -30,27 +23,10 @@ struct tty_queue { unsigned long data; unsigned long head; unsigned long tail; - struct wait_queue * proc_list; - unsigned char buf[TTY_BUF_SIZE]; + struct task_struct * proc_list; + char buf[TTY_BUF_SIZE]; }; -struct serial_struct { - unsigned short type; - unsigned short line; - unsigned short port; - unsigned short irq; - struct tty_struct * tty; -}; - -/* - * These are the supported serial types. - */ -#define PORT_UNKNOWN 0 -#define PORT_8250 1 -#define PORT_16450 2 -#define PORT_16550 3 -#define PORT_16550A 4 - #define IS_A_CONSOLE(min) (((min) & 0xC0) == 0x00) #define IS_A_SERIAL(min) (((min) & 0xC0) == 0x40) #define IS_A_PTY(min) ((min) & 0x80) @@ -65,9 +41,10 @@ struct serial_struct { #define LAST(a) ((a)->buf[(TTY_BUF_SIZE-1)&((a)->head-1)]) #define FULL(a) (!LEFT(a)) #define CHARS(a) (((a)->head-(a)->tail)&(TTY_BUF_SIZE-1)) - -extern void put_tty_queue(char c, struct tty_queue * queue); -extern int get_tty_queue(struct tty_queue * queue); +#define GETCH(queue,c) \ +(void)({c=(queue)->buf[(queue)->tail];INC((queue)->tail);}) +#define PUTCH(c,queue) \ +(void)({(queue)->buf[(queue)->head]=(c);INC((queue)->head);}) #define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR]) #define QUIT_CHAR(tty) ((tty)->termios.c_cc[VQUIT]) @@ -78,46 +55,14 @@ extern int get_tty_queue(struct tty_queue * queue); #define STOP_CHAR(tty) ((tty)->termios.c_cc[VSTOP]) #define SUSPEND_CHAR(tty) ((tty)->termios.c_cc[VSUSP]) -#define _L_FLAG(tty,f) ((tty)->termios.c_lflag & f) -#define _I_FLAG(tty,f) ((tty)->termios.c_iflag & f) -#define _O_FLAG(tty,f) ((tty)->termios.c_oflag & f) - -#define L_CANON(tty) _L_FLAG((tty),ICANON) -#define L_ISIG(tty) _L_FLAG((tty),ISIG) -#define L_ECHO(tty) _L_FLAG((tty),ECHO) -#define L_ECHOE(tty) _L_FLAG((tty),ECHOE) -#define L_ECHOK(tty) _L_FLAG((tty),ECHOK) -#define L_ECHONL(tty) _L_FLAG((tty),ECHONL) -#define L_ECHOCTL(tty) _L_FLAG((tty),ECHOCTL) -#define L_ECHOKE(tty) _L_FLAG((tty),ECHOKE) -#define L_TOSTOP(tty) _L_FLAG((tty),TOSTOP) - -#define I_UCLC(tty) _I_FLAG((tty),IUCLC) -#define I_NLCR(tty) _I_FLAG((tty),INLCR) -#define I_CRNL(tty) _I_FLAG((tty),ICRNL) -#define I_NOCR(tty) _I_FLAG((tty),IGNCR) -#define I_IXON(tty) _I_FLAG((tty),IXON) -#define I_STRP(tty) _I_FLAG((tty),ISTRIP) - -#define O_POST(tty) _O_FLAG((tty),OPOST) -#define O_NLCR(tty) _O_FLAG((tty),ONLCR) -#define O_CRNL(tty) _O_FLAG((tty),OCRNL) -#define O_NLRET(tty) _O_FLAG((tty),ONLRET) -#define O_LCUC(tty) _O_FLAG((tty),OLCUC) - -#define C_SPEED(tty) ((tty)->termios.c_cflag & CBAUD) -#define C_HUP(tty) (C_SPEED((tty)) == B0) - struct tty_struct { struct termios termios; int pgrp; int session; int stopped; - int flags; - int count; + int busy; struct winsize winsize; void (*write)(struct tty_struct * tty); - struct tty_struct *link; struct tty_queue *read_q; struct tty_queue *write_q; struct tty_queue *secondary; @@ -126,46 +71,38 @@ struct tty_struct { /* * so that interrupts won't be able to mess up the * queues, copy_to_cooked must be atomic with repect - * to itself, as must tty->write. These are the flag - * bit-numbers. Use the set_bit() and clear_bit() - * macros to make it all atomic. + * to itself, as must tty->write. */ -#define TTY_WRITE_BUSY 0 -#define TTY_READ_BUSY 1 -#define TTY_CR_PENDING 2 - -/* - * These have to be done with inline assembly: that way the bit-setting - * is guaranteed to be atomic. Both set_bit and clear_bit return 0 - * if the bit-setting went ok, != 0 if the bit already was set/cleared. - */ -extern inline int set_bit(int nr,int * addr) -{ - char ok; - - __asm__ __volatile__("btsl %1,%2\n\tsetb %0": - "=q" (ok):"r" (nr),"m" (*(addr))); - return ok; -} - -extern inline int clear_bit(int nr, int * addr) -{ - char ok; - - __asm__ __volatile__("btrl %1,%2\n\tsetnb %0": - "=q" (ok):"r" (nr),"m" (*(addr))); - return ok; -} - -#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) -#define TTY_READ_FLUSH(tty) tty_read_flush((tty)) - -extern void tty_write_flush(struct tty_struct *); -extern void tty_read_flush(struct tty_struct *); +#define TTY_WRITE_BUSY 1 +#define TTY_READ_BUSY 2 + +#define TTY_WRITE_FLUSH(tty) \ +do { \ + cli(); \ + if (!EMPTY((tty)->write_q) && !(TTY_WRITE_BUSY & (tty)->busy)) { \ + (tty)->busy |= TTY_WRITE_BUSY; \ + sti(); \ + (tty)->write((tty)); \ + cli(); \ + (tty)->busy &= ~TTY_WRITE_BUSY; \ + } \ + sti(); \ +} while (0) + +#define TTY_READ_FLUSH(tty) \ +do { \ + cli(); \ + if (!EMPTY((tty)->read_q) && !(TTY_READ_BUSY & (tty)->busy)) { \ + (tty)->busy |= TTY_READ_BUSY; \ + sti(); \ + copy_to_cooked((tty)); \ + cli(); \ + (tty)->busy &= ~TTY_READ_BUSY; \ + } \ + sti(); \ +} while (0) extern struct tty_struct tty_table[]; -extern struct serial_struct serial_table[]; -extern struct tty_struct * redirect; extern int fg_console; extern unsigned long video_num_columns; extern unsigned long video_num_lines; @@ -182,47 +119,22 @@ extern unsigned long video_num_lines; */ #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" -extern long rs_init(long); -extern long lp_init(long); -extern long con_init(long); -extern long tty_init(long); - -extern void flush_input(struct tty_struct * tty); -extern void flush_output(struct tty_struct * tty); -extern void wait_until_sent(struct tty_struct * tty); -extern void copy_to_cooked(struct tty_struct * tty); +extern void rs_init(void); +extern void lp_init(void); +extern void con_init(void); +extern void tty_init(void); extern int tty_ioctl(struct inode *, struct file *, unsigned int, unsigned int); -extern int is_orphaned_pgrp(int pgrp); -extern int is_ignored(int sig); -extern int tty_signal(int sig, struct tty_struct *tty); -extern int kill_pg(int pgrp, int sig, int priv); - -/* tty write functions */ extern void rs_write(struct tty_struct * tty); extern void con_write(struct tty_struct * tty); extern void mpty_write(struct tty_struct * tty); extern void spty_write(struct tty_struct * tty); -/* serial.c */ - -extern int serial_open(unsigned int line, struct file * filp); -extern void serial_close(unsigned int line, struct file * filp); -extern void change_speed(unsigned int line); -extern void send_break(unsigned int line); -extern int get_serial_info(unsigned int, struct serial_struct *); -extern int set_serial_info(unsigned int, struct serial_struct *); - -/* pty.c */ - -extern int pty_open(unsigned int dev, struct file * filp); -extern void pty_close(unsigned int dev, struct file * filp); +extern void serial_open(unsigned int line); -/* console.c */ +void copy_to_cooked(struct tty_struct * tty); void update_screen(int new_console); -void blank_screen(void); -void unblank_screen(void); #endif diff --git a/include/linux/unistd.h b/include/linux/unistd.h deleted file mode 100644 index 4675fbce0cff..000000000000 --- a/include/linux/unistd.h +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef _LINUX_UNISTD_H -#define _LINUX_UNISTD_H - -/* - * This file contains the system call numbers and the syscallX - * macros - */ - -#define __NR_setup 0 /* used only by init, to get system going */ -#define __NR_exit 1 -#define __NR_fork 2 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_waitpid 7 -#define __NR_creat 8 -#define __NR_link 9 -#define __NR_unlink 10 -#define __NR_execve 11 -#define __NR_chdir 12 -#define __NR_time 13 -#define __NR_mknod 14 -#define __NR_chmod 15 -#define __NR_chown 16 -#define __NR_break 17 -#define __NR_oldstat 18 -#define __NR_lseek 19 -#define __NR_getpid 20 -#define __NR_mount 21 -#define __NR_umount 22 -#define __NR_setuid 23 -#define __NR_getuid 24 -#define __NR_stime 25 -#define __NR_ptrace 26 -#define __NR_alarm 27 -#define __NR_oldfstat 28 -#define __NR_pause 29 -#define __NR_utime 30 -#define __NR_stty 31 -#define __NR_gtty 32 -#define __NR_access 33 -#define __NR_nice 34 -#define __NR_ftime 35 -#define __NR_sync 36 -#define __NR_kill 37 -#define __NR_rename 38 -#define __NR_mkdir 39 -#define __NR_rmdir 40 -#define __NR_dup 41 -#define __NR_pipe 42 -#define __NR_times 43 -#define __NR_prof 44 -#define __NR_brk 45 -#define __NR_setgid 46 -#define __NR_getgid 47 -#define __NR_signal 48 -#define __NR_geteuid 49 -#define __NR_getegid 50 -#define __NR_acct 51 -#define __NR_phys 52 -#define __NR_lock 53 -#define __NR_ioctl 54 -#define __NR_fcntl 55 -#define __NR_mpx 56 -#define __NR_setpgid 57 -#define __NR_ulimit 58 -#define __NR_olduname 59 -#define __NR_umask 60 -#define __NR_chroot 61 -#define __NR_ustat 62 -#define __NR_dup2 63 -#define __NR_getppid 64 -#define __NR_getpgrp 65 -#define __NR_setsid 66 -#define __NR_sigaction 67 -#define __NR_sgetmask 68 -#define __NR_ssetmask 69 -#define __NR_setreuid 70 -#define __NR_setregid 71 -#define __NR_sigsuspend 72 -#define __NR_sigpending 73 -#define __NR_sethostname 74 -#define __NR_setrlimit 75 -#define __NR_getrlimit 76 -#define __NR_getrusage 77 -#define __NR_gettimeofday 78 -#define __NR_settimeofday 79 -#define __NR_getgroups 80 -#define __NR_setgroups 81 -#define __NR_select 82 -#define __NR_symlink 83 -#define __NR_oldlstat 84 -#define __NR_readlink 85 -#define __NR_uselib 86 -#define __NR_swapon 87 -#define __NR_reboot 88 -#define __NR_readdir 89 -#define __NR_mmap 90 -#define __NR_munmap 91 -#define __NR_truncate 92 -#define __NR_ftruncate 93 -#define __NR_fchmod 94 -#define __NR_fchown 95 -#define __NR_getpriority 96 -#define __NR_setpriority 97 -#define __NR_profil 98 -#define __NR_statfs 99 -#define __NR_fstatfs 100 -#define __NR_ioperm 101 -#define __NR_socketcall 102 -#define __NR_syslog 103 -#define __NR_setitimer 104 -#define __NR_getitimer 105 -#define __NR_stat 106 -#define __NR_lstat 107 -#define __NR_fstat 108 -#define __NR_uname 109 -#define __NR_iopl 110 - -extern int errno; - -/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ -#define _syscall0(type,name) \ -type name(void) \ -{ \ -long __res; \ -__asm__ volatile ("int $0x80" \ - : "=a" (__res) \ - : "0" (__NR_##name)); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall1(type,name,atype,a) \ -type name(atype a) \ -{ \ -long __res; \ -__asm__ volatile ("movl %2,%%ebx\n\t" \ - "int $0x80" \ - : "=a" (__res) \ - : "0" (__NR_##name),"g" ((long)(a)):"bx"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall2(type,name,atype,a,btype,b) \ -type name(atype a,btype b) \ -{ \ -long __res; \ -__asm__ volatile ("movl %2,%%ebx\n\t" \ - "int $0x80" \ - : "=a" (__res) \ - : "0" (__NR_##name),"g" ((long)(a)),"c" ((long)(b)):"bx"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall3(type,name,atype,a,btype,b,ctype,c) \ -type name(atype a,btype b,ctype c) \ -{ \ -long __res; \ -__asm__ volatile ("movl %2,%%ebx\n\t" \ - "int $0x80" \ - : "=a" (__res) \ - : "0" (__NR_##name),"g" ((long)(a)),"c" ((long)(b)),"d" ((long)(c)):"bx"); \ -if (__res>=0) \ - return (type) __res; \ -errno=-__res; \ -return -1; \ -} - -#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ -type name (atype a, btype b, ctype c, dtype d) \ -{ \ -long __res; \ -__asm__ volatile ("movl %2,%%ebx\n\t" \ - "int $0x80" \ - : "=a" (__res) \ - : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)), \ - "d" ((long)(c)),"S" ((long)(d))); \ -if (__res>=0) \ - return (type) __res; \ -errno=-__res; \ -return -1; \ -} - -#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ -type name (atype a,btype b,ctype c,dtype d,etype e) \ -{ \ -long __res; \ -__asm__ volatile ("movl %2,%%ebx\n\t" \ - "int $0x80" \ - : "=a" (__res) \ - : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)), \ - "d" ((long)(c)),"S" ((long)(d)),"D" ((long)(e))); \ -if (__res>=0) \ - return (type) __res; \ -errno=-__res; \ -return -1; \ -} - -#endif /* _LINUX_UNISTD_H */ diff --git a/include/linux/utsname.h b/include/linux/utsname.h deleted file mode 100644 index 4efd512949bc..000000000000 --- a/include/linux/utsname.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _LINUX_UTSNAME_H -#define _LINUX_UTSNAME_H - -#define __OLD_UTS_LEN 8 - -struct old_utsname { - char sysname[9]; - char nodename[9]; - char release[9]; - char version[9]; - char machine[9]; -}; - -#define __NEW_UTS_LEN 64 - -struct new_utsname { - char sysname[65]; - char nodename[65]; - char release[65]; - char version[65]; - char machine[65]; -}; - -#endif diff --git a/include/linux/wait.h b/include/linux/wait.h deleted file mode 100644 index 77ad9a314268..000000000000 --- a/include/linux/wait.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _LINUX_WAIT_H -#define _LINUX_WAIT_H - -#include - -struct wait_queue { - struct task_struct * task; - struct wait_queue * next; -}; - -typedef struct select_table_struct { - int nr; - struct select_table_entry { - struct wait_queue wait; - struct wait_queue ** wait_address; - } entry[NR_OPEN*3]; -} select_table; - -#endif diff --git a/include/signal.h b/include/signal.h index 00ef5683f353..e4126d339125 100644 --- a/include/signal.h +++ b/include/signal.h @@ -43,10 +43,9 @@ typedef unsigned int sigset_t; /* 32 bits */ #define SIGPOLL SIGIO #define SIGXCPU 24 #define SIGXFSZ 25 -*/ - #define SIGVTALRM 26 #define SIGPROF 27 +*/ #define SIGWINCH 28 @@ -80,10 +79,6 @@ struct sigaction { void (*sa_restorer)(void); }; -#ifdef __cplusplus -extern "C" { -#endif - void (*signal(int _sig, void (*_func)(int)))(int); int raise(int sig); int kill(pid_t pid, int sig); @@ -97,8 +92,4 @@ int sigprocmask(int how, sigset_t *set, sigset_t *oldset); int sigsuspend(sigset_t *sigmask); int sigaction(int sig, struct sigaction *act, struct sigaction *oldact); -#ifdef __cplusplus -} -#endif - #endif /* _SIGNAL_H */ diff --git a/include/stddef.h b/include/stddef.h index 2828f8ec19fb..697c4f4ad684 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -8,7 +8,7 @@ typedef long ptrdiff_t; #ifndef _SIZE_T #define _SIZE_T -typedef unsigned int size_t; +typedef unsigned long size_t; #endif #undef NULL diff --git a/include/sys/dirent.h b/include/sys/dirent.h index 2df2c83423f4..d0873a9ba823 100644 --- a/include/sys/dirent.h +++ b/include/sys/dirent.h @@ -2,7 +2,6 @@ #define _SYS_DIRENT_H #include -#include struct dirent { long d_ino; diff --git a/include/sys/ptrace.h b/include/sys/ptrace.h index 9d9defb67df4..14bf3c737a90 100644 --- a/include/sys/ptrace.h +++ b/include/sys/ptrace.h @@ -4,21 +4,6 @@ #ifndef _SYS_PTRACE_H #define _SYS_PTRACE_H /* has the defines to get at the registers. */ - -#define PTRACE_TRACEME 0 -#define PTRACE_PEEKTEXT 1 -#define PTRACE_PEEKDATA 2 -#define PTRACE_PEEKUSR 3 -#define PTRACE_POKETEXT 4 -#define PTRACE_POKEDATA 5 -#define PTRACE_POKEUSR 6 -#define PTRACE_CONT 7 -#define PTRACE_KILL 8 -#define PTRACE_SINGLESTEP 9 - -#define PTRACE_ATTACH 0x10 -#define PTRACE_DETACH 0x11 - /* use ptrace (3 or 6, pid, PT_EXCL, data); to read or write the processes registers. */ diff --git a/include/sys/resource.h b/include/sys/resource.h index 3f34379682a6..e23ec63987a6 100644 --- a/include/sys/resource.h +++ b/include/sys/resource.h @@ -60,11 +60,4 @@ struct rlimit { int rlim_max; }; -#define PRIO_MIN -99 -#define PRIO_MAX 14 - -#define PRIO_PROCESS 0 -#define PRIO_PGRP 1 -#define PRIO_USER 2 - #endif /* _SYS_RESOURCE_H */ diff --git a/include/sys/socket.h b/include/sys/socket.h deleted file mode 100644 index 7d840a6cd749..000000000000 --- a/include/sys/socket.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _SOCKET_H -#define _SOCKET_H - -struct sockaddr { - u_short sa_family; /* address family, AF_xxx */ - char sa_data[14]; /* 14 bytes of protocol address */ -}; - -/* - * socket types - */ -#define SOCK_STREAM 1 /* stream (connection) socket */ -#define SOCK_DGRAM 2 /* datagram (connectionless) socket */ -#define SOCK_SEQPACKET 3 /* sequential packet socket */ -#define SOCK_RAW 4 /* raw socket */ - -/* - * supported address families - */ -#define AF_UNSPEC 0 -#define AF_UNIX 1 -#define AF_INET 2 - -/* - * protocol families, same as address families - */ -#define PF_UNIX AF_UNIX -#define PF_INET AF_INET - -int socket(int family, int type, int protocol); -int socketpair(int family, int type, int protocol, int sockvec[2]); -int bind(int sockfd, struct sockaddr *my_addr, int addrlen); -int connect(int sockfd, struct sockaddr *serv_addr, int addrlen); -int listen(int sockfd, int backlog); -int accept(int sockfd, struct sockaddr *peer, int *paddrlen); -int getsockname(int sockfd, struct sockaddr *addr, int *paddrlen); -int getpeername(int sockfd, struct sockaddr *peer, int *paddrlen); - -#endif /* _SOCKET_H */ diff --git a/include/linux/stat.h b/include/sys/stat.h similarity index 50% rename from include/linux/stat.h rename to include/sys/stat.h index 2e11b1ce8494..b709165c4517 100644 --- a/include/linux/stat.h +++ b/include/sys/stat.h @@ -1,41 +1,20 @@ -#ifndef _LINUX_STAT_H -#define _LINUX_STAT_H - -struct old_stat { - unsigned short st_dev; - unsigned short st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned long st_size; - unsigned long st_atime; - unsigned long st_mtime; - unsigned long st_ctime; -}; - -struct new_stat { - unsigned short st_dev; - unsigned short __pad1; - unsigned long st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned short __pad2; - unsigned long st_size; - unsigned long st_blksize; - unsigned long st_blocks; - unsigned long st_atime; - unsigned long __unused1; - unsigned long st_mtime; - unsigned long __unused2; - unsigned long st_ctime; - unsigned long __unused3; - unsigned long __unused4; - unsigned long __unused5; +#ifndef _SYS_STAT_H +#define _SYS_STAT_H + +#include + +struct stat { + dev_t st_dev; + ino_t st_ino; + umode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + off_t st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; }; #define S_IFMT 00170000 @@ -73,4 +52,11 @@ struct new_stat { #define S_IWOTH 00002 #define S_IXOTH 00001 +extern int chmod(const char *_path, mode_t mode); +extern int fstat(int fildes, struct stat *stat_buf); +extern int mkdir(const char *_path, mode_t mode); +extern int mkfifo(const char *_path, mode_t mode); +extern int stat(const char *filename, struct stat *stat_buf); +extern mode_t umask(mode_t mask); + #endif diff --git a/include/sys/time.h b/include/sys/time.h index 1ef722b77135..1165c2632cc7 100644 --- a/include/sys/time.h +++ b/include/sys/time.h @@ -54,9 +54,6 @@ struct itimerval { struct timeval it_value; /* current value */ }; -int getitimer(int which, struct itimerval *value); -int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); - #include #include diff --git a/include/sys/types.h b/include/sys/types.h index 46b57b520884..8529532ad4c0 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -1,28 +1,16 @@ #ifndef _SYS_TYPES_H #define _SYS_TYPES_H -#include - #ifndef _SIZE_T #define _SIZE_T typedef unsigned int size_t; #endif -#ifndef _SSIZE_T -#define _SSIZE_T -typedef int ssize_t; -#endif - #ifndef _TIME_T #define _TIME_T typedef long time_t; #endif -#ifndef _CLOCK_T -#define _CLOCK_T -typedef long clock_t; -#endif - #ifndef _PTRDIFF_T #define _PTRDIFF_T typedef long ptrdiff_t; @@ -36,29 +24,16 @@ typedef int pid_t; typedef unsigned short uid_t; typedef unsigned short gid_t; typedef unsigned short dev_t; -#ifdef OLD_LINUX typedef unsigned short ino_t; -#else -typedef unsigned long ino_t; -#endif typedef unsigned short mode_t; typedef unsigned short umode_t; typedef unsigned short nlink_t; typedef int daddr_t; typedef long off_t; - -/* bsd */ typedef unsigned char u_char; typedef unsigned short u_short; -typedef unsigned int u_int; typedef unsigned long u_long; - -/* sysv */ -typedef unsigned char unchar; typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; - typedef char *caddr_t; typedef unsigned char cc_t; diff --git a/include/sys/un.h b/include/sys/un.h deleted file mode 100644 index 26a51f457bc9..000000000000 --- a/include/sys/un.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _UN_H -#define _UN_H - -struct sockaddr_un { - u_short sun_family; /* AF_UNIX */ - char sun_path[108]; /* pathname */ -}; - -#endif /* _UN_H */ diff --git a/include/sys/user.h b/include/sys/user.h deleted file mode 100644 index 1a3c292f1e77..000000000000 --- a/include/sys/user.h +++ /dev/null @@ -1,70 +0,0 @@ -#include -/* Core file format: The core file is written in such a way that gdb - can understand it and provide useful information to the user (under - linux we use the 'trad-core' bfd). There are quite a number of - obstacles to being able to view the contents of the floating point - registers, and until these are solved you will not be able to view the - contents of them. Actually, you can read in the core file and look at - the contents of the user struct to find out what the floating point - registers contain. - The actual file contents are as follows: - UPAGE: 1 page consisting of a user struct that tells gdb what is present - in the file. Directly after this is a copy of the task_struct, which - is currently not used by gdb, but it may come in useful at some point. - All of the registers are stored as part of the upage. The upage should - always be only one page. - DATA: The data area is stored. We use current->end_text to - current->brk to pick up all of the user variables, plus any memory - that may have been malloced. No attempt is made to determine if a page - is demand-zero or if a page is totally unused, we just cover the entire - range. All of the addresses are rounded in such a way that an integral - number of pages is written. - STACK: We need the stack information in order to get a meaningful - backtrace. We need to write the data from (esp) to - current->start_stack, so we round each of these off in order to be able - to write an integer number of pages. - The minimum core file size is 3 pages, or 12288 bytes. -*/ - -struct user_i387_struct { - long cwd; - long swd; - long twd; - long fip; - long fcs; - long foo; - long fos; - long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */ -}; - -/* When the kernel dumps core, it starts by dumping the user struct - - this will be used by gdb to figure out where the data and stack segments - are within the file, and what virtual addresses to use. */ -struct user{ -/* We start with the registers, to mimic the way that "memory" is returned - from the ptrace(3,...) function. */ - struct pt_regs regs; /* Where the registers are actually stored */ -/* ptrace does not yet supply these. Someday.... */ - int u_fpvalid; /* True if math co-processor being used. */ - /* for this mess. Not yet used. */ - struct user_i387_struct i387; /* Math Co-processor registers. */ -/* The rest of this junk is to help gdb figure out what goes where */ - unsigned long int u_tsize; /* Text segment size (pages). */ - unsigned long int u_dsize; /* Data segment size (pages). */ - unsigned long int u_ssize; /* Stack segment size (pages). */ - unsigned long start_code; /* Starting virtual address of text. */ - unsigned long start_stack; /* Starting virtual address of stack area. - This is actually the bottom of the stack, - the top of the stack is always found in the - esp register. */ - long int signal; /* Signal that caused the core dump. */ - char * u_comm; /* User command that was responsible */ - struct pt_regs * u_ar0; /* Used by gdb to help find the values for */ - /* the registers. */ - struct user_i387_struct* u_fpstate; /* Math Co-processor pointer. */ - unsigned long magic; /* To uniquely identify a core file */ -}; -#define NBPG 4096 -#define UPAGES 1 -#define HOST_TEXT_START_ADDR (u.start_code) -#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) diff --git a/include/sys/utsname.h b/include/sys/utsname.h new file mode 100644 index 000000000000..0e6aef8b4d52 --- /dev/null +++ b/include/sys/utsname.h @@ -0,0 +1,17 @@ +#ifndef _SYS_UTSNAME_H +#define _SYS_UTSNAME_H + +#include +#include + +struct utsname { + char sysname[9]; + char nodename[MAXHOSTNAMELEN+1]; + char release[9]; + char version[9]; + char machine[9]; +}; + +extern int uname(struct utsname * utsbuf); + +#endif diff --git a/include/termios.h b/include/termios.h index da7b09a4d917..b04a0e9928ec 100644 --- a/include/termios.h +++ b/include/termios.h @@ -34,9 +34,6 @@ #define FIONREAD 0x541B #define TIOCINQ FIONREAD #define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F struct winsize { unsigned short ws_row; @@ -213,10 +210,6 @@ struct termios { #define TCSADRAIN 1 #define TCSAFLUSH 2 -#ifdef __cplusplus -extern "C" { -#endif - extern speed_t cfgetispeed(struct termios *termios_p); extern speed_t cfgetospeed(struct termios *termios_p); extern int cfsetispeed(struct termios *termios_p, speed_t speed); @@ -229,8 +222,4 @@ extern int tcsendbreak(int fildes, int duration); extern int tcsetattr(int fildes, int optional_actions, struct termios *termios_p); -#ifdef __cplusplus -} -#endif - #endif diff --git a/include/time.h b/include/time.h index 66aa63489eac..f7e7ba1982ee 100644 --- a/include/time.h +++ b/include/time.h @@ -17,10 +17,7 @@ typedef unsigned int size_t; #define CLOCKS_PER_SEC 100 -#ifndef _CLOCK_T -#define _CLOCK_T typedef long clock_t; -#endif struct tm { int tm_sec; @@ -37,10 +34,6 @@ struct tm { #define __isleap(year) \ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) -#ifdef __cplusplus -extern "C" { -#endif - clock_t clock(void); time_t time(time_t * tp); double difftime(time_t time2, time_t time1); @@ -53,8 +46,4 @@ struct tm *localtime(const time_t * tp); size_t strftime(char * s, size_t smax, const char * fmt, const struct tm * tp); void tzset(void); -#ifdef __cplusplus -} -#endif - #endif diff --git a/include/unistd.h b/include/unistd.h index 041977bba3a7..6631444ad58b 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -64,16 +64,205 @@ #include #ifdef __LIBRARY__ -#include + +#define __NR_setup 0 /* used only by init, to get system going */ +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_stat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_fstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_phys 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_uname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_lstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +/* + * Not all of these are implemented yet, but these are the + * numbers they will use. + */ +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 + +/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ +#define _syscall0(type,name) \ +type name(void) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name)); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall1(type,name,atype,a) \ +type name(atype a) \ +{ \ +long __res; \ +__asm__ volatile ("movl %2,%%ebx\n\t" \ + "int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"g" ((long)(a)):"bx"); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall2(type,name,atype,a,btype,b) \ +type name(atype a,btype b) \ +{ \ +long __res; \ +__asm__ volatile ("movl %2,%%ebx\n\t" \ + "int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"g" ((long)(a)),"c" ((long)(b)):"bx"); \ +if (__res >= 0) \ + return (type) __res; \ +errno = -__res; \ +return -1; \ +} + +#define _syscall3(type,name,atype,a,btype,b,ctype,c) \ +type name(atype a,btype b,ctype c) \ +{ \ +long __res; \ +__asm__ volatile ("movl %2,%%ebx\n\t" \ + "int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"g" ((long)(a)),"c" ((long)(b)),"d" ((long)(c)):"bx"); \ +if (__res>=0) \ + return (type) __res; \ +errno=-__res; \ +return -1; \ +} + +#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ +type name (atype a, btype b, ctype c, dtype d) \ +{ \ +long __res; \ +__asm__ volatile ("movl %2,%%ebx\n\t" \ + "int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)), \ + "d" ((long)(c)),"S" ((long)(d))); \ +if (__res>=0) \ + return (type) __res; \ +errno=-__res; \ +return -1; \ +} + +#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ +type name (atype a,btype b,ctype c,dtype d,etype e) \ +{ \ +long __res; \ +__asm__ volatile ("movl %2,%%ebx\n\t" \ + "int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)), \ + "d" ((long)(c)),"S" ((long)(d)),"D" ((long)(e))); \ +if (__res>=0) \ + return (type) __res; \ +errno=-__res; \ +return -1; \ +} + #endif /* __LIBRARY__ */ /* XXX - illegal. */ extern int errno; -#ifdef __cplusplus -extern "C" { -#endif - /* XXX - several non-POSIX functions here, and POSIX functions that are * supposed to be declared elsewhere. Non-promotion of short types in * prototypes may cause trouble. Arg names should be prefixed by @@ -156,9 +345,4 @@ int setgroups(int gidsetlen, gid_t *gidset); int select(int width, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval * timeout); int swapon(const char * specialfile); - -#ifdef __cplusplus -} -#endif - #endif diff --git a/include/utime.h b/include/utime.h index a7b79b3300e1..83f07c7bbfe7 100644 --- a/include/utime.h +++ b/include/utime.h @@ -8,14 +8,6 @@ struct utimbuf { time_t modtime; }; -#ifdef __cplusplus -extern "C" { -#endif - extern int utime(const char *filename, struct utimbuf *times); -#ifdef __cplusplus -} -#endif - #endif diff --git a/init/main.c b/init/main.c index 1f6174d4f29b..378ca99adb28 100644 --- a/init/main.c +++ b/init/main.c @@ -4,22 +4,10 @@ * (C) 1991 Linus Torvalds */ -#include -#include +#define __LIBRARY__ +#include #include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - /* * we need this inline - forking from kernel space will result * in NO COPY ON WRITE (!!!), until an execve is executed. This @@ -36,37 +24,34 @@ static inline _syscall0(int,fork) static inline _syscall0(int,pause) static inline _syscall1(int,setup,void *,BIOS) static inline _syscall0(int,sync) -static inline _syscall0(pid_t,setsid) -static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) -static inline _syscall1(int,dup,int,fd) -static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) -static inline _syscall3(int,open,const char *,file,int,flag,int,mode) -static inline _syscall1(int,close,int,fd) -static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) -static inline pid_t wait(int * wait_stat) -{ - return waitpid(-1,wait_stat,0); -} +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include static char printbuf[1024]; +extern char *strcpy(); extern int vsprintf(); extern void init(void); -extern void init_IRQ(void); -extern long blk_dev_init(long,long); -extern long chr_dev_init(long,long); +extern void blk_dev_init(void); +extern void chr_dev_init(void); extern void hd_init(void); extern void floppy_init(void); -extern void sock_init(void); extern void mem_init(long start, long end); extern long rd_init(long mem_start, int length); extern long kernel_mktime(struct tm * tm); -#ifdef CONFIG_SCSI -extern void scsi_dev_init(void); -#endif - static int sprintf(char * str, const char *fmt, ...) { va_list args; @@ -164,37 +149,32 @@ void start_kernel(void) else buffer_memory_end = 1*1024*1024; main_memory_start = buffer_memory_end; - trap_init(); - init_IRQ(); - sched_init(); - main_memory_start = chr_dev_init(main_memory_start,memory_end); - main_memory_start = blk_dev_init(main_memory_start,memory_end); +#ifdef RAMDISK + main_memory_start += rd_init(main_memory_start, RAMDISK*1024); +#endif mem_init(main_memory_start,memory_end); + trap_init(); + chr_dev_init(); + blk_dev_init(); time_init(); - printk("Linux version " UTS_RELEASE " " __DATE__ " " __TIME__ "\n"); + sched_init(); buffer_init(buffer_memory_end); hd_init(); floppy_init(); - sock_init(); sti(); -#ifdef CONFIG_SCSI - scsi_dev_init(); -#endif move_to_user_mode(); if (!fork()) { /* we count on this going ok */ init(); } /* - * task[0] is meant to be used as an "idle" task: it may not sleep, but - * it might do some general things like count free pages or it could be - * used to implement a reasonable LRU algorithm for the paging routines: - * anything that can be useful, but shouldn't take time from the real - * processes. - * - * Right now task[0] just does a infinite loop in user mode. + * NOTE!! For any other task 'pause()' would mean we have to get a + * signal to awaken, but task0 is the sole exception (see 'schedule()') + * as task 0 gets activated at every idle moment (when no other tasks + * can run). For task0 'pause()' just means we go check if some other + * task can run, and if not we return here. */ for(;;) - /* nothing */ ; + __asm__("int $0x80"::"a" (__NR_pause):"ax"); } static int printf(const char *fmt, ...) diff --git a/kernel/Makefile b/kernel/Makefile index 3b1c608e9d04..0ebd895d7ea2 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -7,30 +7,33 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... +AR =ar +AS =as +LD =ld +LDFLAGS =-s -x +CC =gcc -nostdinc -I../include +CPP =cpp -nostdinc -I../include + + .S.s: $(CPP) -traditional $< -o $*.s .c.s: - $(CC) $(CFLAGS) -S $< + $(CC) $(CFLAGS) \ + -S -o $*.s $< .s.o: $(AS) -c -o $*.o $< .c.o: - $(CC) $(CFLAGS) -c $< - -SUBDIRS = chr_drv blk_drv math + $(CC) $(CFLAGS) \ + -c -o $*.o $< -OBJS = sched.o sys_call.o traps.o irq.o fork.o \ +OBJS = sched.o sys_call.o traps.o asm.o fork.o \ panic.o printk.o vsprintf.o sys.o exit.o \ - signal.o mktime.o ptrace.o ioport.o itimer.o - -all: kernel.o subdirs + signal.o mktime.o ptrace.o ioport.o kernel.o: $(OBJS) $(LD) -r -o kernel.o $(OBJS) sync -subdirs: dummy - for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done - sys_call.s: sys_call.S sys_call.o: sys_call.s @@ -41,104 +44,66 @@ sched.o: sched.c clean: rm -f core *.o *.a tmp_make sys_call.s for i in *.c;do rm -f `basename $$i .c`.s;done - for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean); done + (cd chr_drv; make clean) + (cd blk_drv; make clean) + (cd math; make clean) dep: sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - for i in *.c;do $(CPP) -M $$i;done >> tmp_make + (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ + $(CPP) -M $$i;done) >> tmp_make cp tmp_make Makefile - for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep); done - -dummy: + (cd chr_drv; make dep) + (cd blk_drv; make dep) + (cd math; make dep) ### Dependencies: -exit.o : exit.c /usr/src/linux/include/errno.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/wait.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \ - /usr/src/linux/include/asm/segment.h -fork.o : fork.c /usr/src/linux/include/errno.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/asm/system.h -ioport.o : ioport.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/errno.h -irq.o : irq.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/sys/ptrace.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/irq.h -itimer.o : itimer.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/string.h \ - /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h -mktime.o : mktime.c /usr/src/linux/include/time.h -panic.o : panic.c /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h -printk.o : printk.c /usr/src/linux/include/stdarg.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h -ptrace.o : ptrace.c /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h \ - /usr/src/linux/include/errno.h /usr/src/linux/include/sys/ptrace.h -sched.o : sched.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/sys.h \ - /usr/src/linux/include/linux/fdreg.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \ - /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h -signal.o : signal.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/sys/wait.h \ - /usr/src/linux/include/sys/ptrace.h /usr/src/linux/include/errno.h -sys.o : sys.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \ - /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/linux/config.h \ - /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \ - /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/sys/times.h /usr/src/linux/include/linux/utsname.h /usr/src/linux/include/linux/string.h -traps.o : traps.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/system.h \ - /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/errno.h -vsprintf.o : vsprintf.c /usr/src/linux/include/stdarg.h /usr/src/linux/include/linux/string.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h +exit.s exit.o : exit.c ../include/errno.h ../include/signal.h ../include/sys/types.h \ + ../include/sys/wait.h ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \ + ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h \ + ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \ + ../include/linux/tty.h ../include/termios.h ../include/asm/segment.h +fork.s fork.o : fork.c ../include/errno.h ../include/stddef.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h \ + ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h \ + ../include/sys/param.h ../include/sys/time.h ../include/time.h ../include/sys/resource.h \ + ../include/asm/segment.h ../include/asm/system.h +ioport.s ioport.o : ioport.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \ + ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \ + ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \ + ../include/time.h ../include/sys/resource.h ../include/errno.h +mktime.s mktime.o : mktime.c ../include/time.h +panic.s panic.o : panic.c ../include/linux/kernel.h ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \ + ../include/linux/mm.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \ + ../include/time.h ../include/sys/resource.h +printk.s printk.o : printk.c ../include/stdarg.h ../include/stddef.h ../include/linux/kernel.h +ptrace.s ptrace.o : ptrace.c ../include/linux/head.h ../include/linux/kernel.h ../include/linux/sched.h \ + ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \ + ../include/linux/mm.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \ + ../include/time.h ../include/sys/resource.h ../include/errno.h ../include/asm/segment.h \ + ../include/asm/system.h ../include/sys/ptrace.h +sched.s sched.o : sched.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \ + ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \ + ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \ + ../include/time.h ../include/sys/resource.h ../include/linux/timer.h ../include/linux/sys.h \ + ../include/linux/fdreg.h ../include/asm/system.h ../include/asm/io.h ../include/asm/segment.h \ + ../include/errno.h +signal.s signal.o : signal.c ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h \ + ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/linux/mm.h \ + ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h ../include/sys/time.h \ + ../include/time.h ../include/sys/resource.h ../include/asm/segment.h ../include/sys/wait.h \ + ../include/errno.h +sys.s sys.o : sys.c ../include/errno.h ../include/linux/sched.h ../include/linux/head.h \ + ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \ + ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \ + ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/linux/tty.h \ + ../include/termios.h ../include/linux/config.h ../include/linux/config_rel.h \ + ../include/linux/config_ver.h ../include/asm/segment.h ../include/sys/times.h \ + ../include/sys/utsname.h ../include/linux/string.h +traps.s traps.o : traps.c ../include/linux/string.h ../include/linux/head.h ../include/linux/sched.h \ + ../include/linux/fs.h ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h \ + ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \ + ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/asm/system.h \ + ../include/asm/segment.h ../include/asm/io.h ../include/errno.h +vsprintf.s vsprintf.o : vsprintf.c ../include/stdarg.h ../include/linux/string.h diff --git a/kernel/asm.s b/kernel/asm.s index f62751ca6ac8..f565060bbe63 100644 --- a/kernel/asm.s +++ b/kernel/asm.s @@ -11,7 +11,40 @@ * care about the stack layout etc. */ -.globl _floppy_interrupt,_parallel_interrupt +.globl _hd_interrupt,_floppy_interrupt,_parallel_interrupt + +_hd_interrupt: + cld + pushl %eax + pushl %ecx + pushl %edx + push %ds + push %es + push %fs + movl $0x10,%eax + mov %ax,%ds + mov %ax,%es + movl $0x17,%eax + mov %ax,%fs + movb $0x20,%al + outb %al,$0xA0 # EOI to interrupt controller #1 + jmp 1f # give port chance to breathe +1: jmp 1f +1: outb %al,$0x20 + andl $0xfffeffff,_timer_active + xorl %edx,%edx + xchgl _do_hd,%edx + testl %edx,%edx + jne 1f + movl $_unexpected_hd_interrupt,%edx +1: call *%edx # "interesting" way of handling intr. + pop %fs + pop %es + pop %ds + popl %edx + popl %ecx + popl %eax + iret _floppy_interrupt: cld diff --git a/kernel/blk_drv/Makefile b/kernel/blk_drv/Makefile index 99d573a9808f..3aaf96197c76 100644 --- a/kernel/blk_drv/Makefile +++ b/kernel/blk_drv/Makefile @@ -9,72 +9,62 @@ # parent makefile. # +AR =ar +AS =as +LD =ld +LDFLAGS =-s -x +CC =gcc -nostdinc -I../../include +CPP =cpp -nostdinc -I../../include + .c.s: - $(CC) $(CFLAGS) $(RAMDISK) -S $< + $(CC) $(CFLAGS) \ + -S -o $*.s $< .s.o: $(AS) -c -o $*.o $< .c.o: - $(CC) $(CFLAGS) $(RAMDISK) -c $< - -SUBDIRS = scsi - -OBJS = hd.o ll_rw_blk.o floppy.o ramdisk.o + $(CC) $(CFLAGS) \ + -c -o $*.o $< -all: blk_drv.a subdirs +OBJS = ll_rw_blk.o floppy.o hd.o ramdisk.o blk_drv.a: $(OBJS) - rm -f blk_drv.a $(AR) rcs blk_drv.a $(OBJS) sync -subdirs: dummy - for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done - clean: rm -f core *.o *.a tmp_make for i in *.c;do rm -f `basename $$i .c`.s;done - cd scsi; $(MAKE) clean dep: sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - for i in *.c;do $(CPP) -M $$i;done >> tmp_make + (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ + $(CPP) -M $$i;done) >> tmp_make cp tmp_make Makefile -dummy: - ### Dependencies: -floppy.o : floppy.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/fdreg.h \ - /usr/src/linux/include/linux/fd.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \ - /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h blk.h -hd.o : hd.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/config.h \ - /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \ - /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h \ - /usr/src/linux/include/linux/hdreg.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \ - /usr/src/linux/include/asm/segment.h blk.h -ll_rw_blk.o : ll_rw_blk.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/system.h \ - blk.h -ramdisk.o : ramdisk.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \ - /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \ - /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/memory.h \ +floppy.s floppy.o : floppy.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \ + ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \ + ../../include/linux/mm.h ../../include/linux/kernel.h ../../include/signal.h \ + ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \ + ../../include/linux/fdreg.h ../../include/asm/system.h ../../include/asm/io.h \ + ../../include/asm/segment.h blk.h +hd.s hd.o : hd.c ../../include/errno.h ../../include/linux/config.h ../../include/linux/config_rel.h \ + ../../include/linux/config_ver.h ../../include/linux/sched.h ../../include/linux/head.h \ + ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \ + ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h ../../include/linux/timer.h ../../include/linux/hdreg.h \ + ../../include/asm/system.h ../../include/asm/io.h ../../include/asm/segment.h \ blk.h +ll_rw_blk.s ll_rw_blk.o : ll_rw_blk.c ../../include/errno.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \ + ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h ../../include/asm/system.h blk.h +ramdisk.s ramdisk.o : ramdisk.c ../../include/linux/string.h ../../include/linux/config.h \ + ../../include/linux/config_rel.h ../../include/linux/config_ver.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \ + ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h ../../include/linux/minix_fs.h ../../include/asm/system.h \ + ../../include/asm/segment.h ../../include/asm/memory.h blk.h diff --git a/kernel/blk_drv/blk.h b/kernel/blk_drv/blk.h index 097c9934fdb9..746f5f024f05 100644 --- a/kernel/blk_drv/blk.h +++ b/kernel/blk_drv/blk.h @@ -1,7 +1,7 @@ #ifndef _BLK_H #define _BLK_H -#define NR_BLK_DEV 10 +#define NR_BLK_DEV 7 /* * NR_REQUEST is the number of entries in the request-queue. * NOTE that writes may use only the low 2/3 of these: reads @@ -27,9 +27,8 @@ struct request { unsigned long sector; unsigned long nr_sectors; char * buffer; - struct wait_queue * waiting; + struct task_struct * waiting; struct buffer_head * bh; - struct buffer_head * bhtail; struct request * next; }; @@ -50,18 +49,10 @@ struct blk_dev_struct { extern struct blk_dev_struct blk_dev[NR_BLK_DEV]; extern struct request request[NR_REQUEST]; -extern struct wait_queue * wait_for_request; +extern struct task_struct * wait_for_request; extern int * blk_size[NR_BLK_DEV]; -extern int is_read_only(int dev); -extern void set_device_ro(int dev,int flag); - -#define RO_IOCTLS(dev,where) \ - case BLKROSET: if (!suser()) return -EPERM; \ - set_device_ro((dev),get_fs_long((long *) (where))); return 0; \ - case BLKROGET: put_fs_long(is_read_only(dev),(long *) (where)); return 0; - #ifdef MAJOR_NR /* @@ -97,24 +88,6 @@ extern void set_device_ro(int dev,int flag); #define DEVICE_ON(device) #define DEVICE_OFF(device) -#elif (MAJOR_NR == 8) -/* scsi disk */ -#define DEVICE_NAME "scsidisk" -#define DEVICE_INTR do_sd -#define DEVICE_REQUEST do_sd_request -#define DEVICE_NR(device) (MINOR(device) >> 4) -#define DEVICE_ON(device) -#define DEVICE_OFF(device) - -#elif (MAJOR_NR == 9) -/* scsi tape */ -#define DEVICE_NAME "scsitape" -#define DEVICE_INTR do_st -#define DEVICE_REQUEST do_st_request -#define DEVICE_NR(device) (MINOR(device)) -#define DEVICE_ON(device) -#define DEVICE_OFF(device) - #elif /* unknown blk device */ #error "unknown blk device" @@ -157,40 +130,22 @@ extern inline void unlock_buffer(struct buffer_head * bh) wake_up(&bh->b_wait); } -static void end_request(int uptodate) +extern inline void end_request(int uptodate) { - struct request * req; - struct buffer_head * bh; - - req = CURRENT; - req->errors = 0; + DEVICE_OFF(CURRENT->dev); + if (CURRENT->bh) { + CURRENT->bh->b_uptodate = uptodate; + unlock_buffer(CURRENT->bh); + } if (!uptodate) { printk(DEVICE_NAME " I/O error\n\r"); - printk("dev %04x, sector %d\n\r",req->dev,req->sector); - req->nr_sectors--; - req->nr_sectors &= ~1; - req->sector += 2; - req->sector &= ~1; - } - if (bh = req->bh) { - req->bh = bh->b_reqnext; - bh->b_reqnext = NULL; - bh->b_uptodate = uptodate; - unlock_buffer(bh); - if (bh = req->bh) { - if (req->nr_sectors < 2) { - req->nr_sectors = 2; - printk("end_request: buffer-list destroyed\n"); - } - req->buffer = bh->b_data; - return; - } + printk("dev %04x, block %d\n\r",CURRENT->dev, + CURRENT->bh->b_blocknr); } - DEVICE_OFF(req->dev); - CURRENT = req->next; - wake_up(&req->waiting); - req->dev = -1; + wake_up(&CURRENT->waiting); wake_up(&wait_for_request); + CURRENT->dev = -1; + CURRENT = CURRENT->next; } #ifdef DEVICE_INTR diff --git a/kernel/blk_drv/floppy.c b/kernel/blk_drv/floppy.c index 7fb9e571add4..acda4c925e12 100644 --- a/kernel/blk_drv/floppy.c +++ b/kernel/blk_drv/floppy.c @@ -32,33 +32,21 @@ * by entropy@wintermute.wpi.edu (Lawrence Foard). Linus. */ -/* - * Automatic floppy-detection and formatting written by Werner Almesberger - * (almesber@nessie.cs.id.ethz.ch), who also corrected some problems with - * the floppy-change signal detection. - */ - -#define FLOPPY_IRQ 6 - #include #include #include -#include #include -#include #include #include #include -#include #define MAJOR_NR 2 #include "blk.h" -static unsigned int changed_floppies = 0, fake_change = 0; +unsigned int changed_floppies = 0; static int recalibrate = 0; static int reset = 0; -static int recover = 0; /* recalibrate immediately after resetting */ static int seek = 0; extern unsigned char current_DOR; @@ -75,20 +63,6 @@ __asm__("outb %0,%1\n\tjmp 1f\n1:\tjmp 1f\n1:"::"a" ((char) (val)),"i" (port)) */ #define MAX_ERRORS 12 -/* - * Maximum disk size (in kilobytes). This default is used whenever the - * current disk size is unknown. - */ - -#define MAX_DISK_SIZE 1440 - -/* - * Maximum number of sectors in a track buffer. Track buffering is disabled - * if tracks are bigger. - */ - -#define MAX_BUFFER_SECTORS 18 - /* * globals used by 'result()' */ @@ -109,95 +83,22 @@ static unsigned char reply_buffer[MAX_REPLIES]; * types (ie 360kB diskette in 1.2MB drive etc). Others should * be self-explanatory. */ - -static struct floppy_struct floppy_type[] = { - { 0, 0,0, 0,0,0x00,0x00,0x00,0x00,NULL }, /* no testing */ - { 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,NULL }, /* 360kB PC diskettes */ - { 2400,15,2,80,0,0x1B,0x00,0xDF,0x54,NULL }, /* 1.2 MB AT-diskettes */ - { 720, 9,2,40,1,0x2A,0x02,0xDF,0x50,NULL }, /* 360kB in 720kB drive */ - { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,NULL }, /* 3.5" 720kB diskette */ - { 720, 9,2,40,1,0x23,0x01,0xDF,0x50,NULL }, /* 360kB in 1.2MB drive */ - { 1440, 9,2,80,0,0x23,0x01,0xDF,0x50,NULL }, /* 720kB in 1.2MB drive */ - { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }, /* 1.44MB diskette */ -}; - -/* For auto-detection. Each drive type has a pair of formats to try. */ - -static struct floppy_struct floppy_types[] = { - { 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"360k/PC" }, /* 360kB PC diskettes */ - { 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"360k/PC" }, /* 360kB PC diskettes */ - { 2400,15,2,80,0,0x1B,0x00,0xDF,0x54,"1.2M" }, /* 1.2 MB AT-diskettes */ - { 720, 9,2,40,1,0x23,0x01,0xDF,0x50,"360k/AT" }, /* 360kB in 1.2MB drive */ - { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"720k" }, /* 3.5" 720kB diskette */ - { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"720k" }, /* 3.5" 720kB diskette */ - { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"1.44M" }, /* 1.44MB diskette */ - { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"720k/AT" }, /* 3.5" 720kB diskette */ +struct floppy_struct { + unsigned int size, sect, head, track, stretch; + unsigned char gap,rate,spec1; }; -/* Auto-detection: Disk type used until the next media change occurs. */ - -struct floppy_struct *current_type[4] = { NULL, NULL, NULL, NULL }; - -/* This type is tried first. */ - -struct floppy_struct *base_type[4]; - -/* User-provided type information. current_type points to the respective entry - of this array. */ - -struct floppy_struct user_params[4]; - -static int floppy_sizes[] ={ - MAX_DISK_SIZE, MAX_DISK_SIZE, MAX_DISK_SIZE, MAX_DISK_SIZE, - 360, 360 ,360, 360, - 1200,1200,1200,1200, - 360, 360, 360, 360, - 720, 720, 720, 720, - 360, 360, 360, 360, - 720, 720, 720, 720, - 1440,1440,1440,1440 +static struct floppy_struct floppy_type[] = { + { 0, 0,0, 0,0,0x00,0x00,0x00 }, /* no testing */ + { 720, 9,2,40,0,0x2A,0x02,0xDF }, /* 360kB PC diskettes */ + { 2400,15,2,80,0,0x1B,0x00,0xDF }, /* 1.2 MB AT-diskettes */ + { 720, 9,2,40,1,0x2A,0x02,0xDF }, /* 360kB in 720kB drive */ + { 1440, 9,2,80,0,0x2A,0x02,0xDF }, /* 3.5" 720kB diskette */ + { 720, 9,2,40,1,0x23,0x01,0xDF }, /* 360kB in 1.2MB drive */ + { 1440, 9,2,80,0,0x23,0x01,0xDF }, /* 720kB in 1.2MB drive */ + { 2880,18,2,80,0,0x1B,0x00,0xCF }, /* 1.44MB diskette */ }; -/* The driver is trying to determine the correct media format while probing - is set. rw_interrupts clears it after a successful access. */ - -static int probing = 0; - -/* (User-provided) media information is _not_ discarded after a media change - if the corresponding keep_data flag is non-zero. Positive values are - decremented after each probe. */ - -static int keep_data[4] = { 0,0,0,0 }; - -/* Announce successful media type detection and media information loss after - disk changes. */ - -static ftd_msg[4] = { 1,1,1,1 }; - -/* Synchronization of FDC access. */ - -static volatile int format_status = FORMAT_NONE, fdc_busy = 0; -static struct wait_queue *fdc_wait = NULL, *format_done = NULL; - -/* Errors during formatting are counted here. */ - -static int format_errors; - -/* Format request descriptor. */ - -static struct format_descr format_req; - -/* Current device number. Taken either from the block header or from the - format request descriptor. */ - -#define CURRENT_DEVICE (format_status == FORMAT_BUSY ? format_req.device : \ - (CURRENT->dev)) - -/* Current error count. */ - -#define CURRENT_ERRORS (format_status == FORMAT_BUSY ? format_errors : \ - (CURRENT->errors)) - /* * Rate is 0 for 500kb/s, 2 for 300kbps, 1 for 250kbps * Spec1 is 0xSH, where S is stepping rate (F=1ms, E=2ms, D=3ms etc), @@ -207,10 +108,9 @@ static struct format_descr format_req; * and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA). */ +extern void floppy_interrupt(void); extern char tmp_floppy_area[1024]; -extern char floppy_track_buffer[512*2*MAX_BUFFER_SECTORS]; - -static void redo_fd_request(void); +extern char floppy_track_buffer[512*2*18]; /* * These are global variables, as that's the easiest way to give @@ -233,7 +133,7 @@ static unsigned char seek_track = 0; static unsigned char current_track = NO_TRACK; static unsigned char command = 0; unsigned char selected = 0; -struct wait_queue * wait_on_floppy_select = NULL; +struct task_struct * wait_on_floppy_select = NULL; void floppy_deselect(unsigned int nr) { @@ -243,16 +143,6 @@ void floppy_deselect(unsigned int nr) wake_up(&wait_on_floppy_select); } -void request_done(int uptodate) -{ - timer_active &= ~(1 << FLOPPY_TIMER); - if (format_status != FORMAT_BUSY) end_request(uptodate); - else { - format_status = uptodate ? FORMAT_OKAY : FORMAT_ERROR; - wake_up(&format_done); - } -} - /* * floppy-change is never called from an interrupt, so we can relax a bit * here, sleep etc. Note that floppy-on tries to set current_DOR to point @@ -264,15 +154,9 @@ int floppy_change(struct buffer_head * bh) unsigned int mask = 1 << (bh->b_dev & 0x03); if (MAJOR(bh->b_dev) != 2) { - printk("floppy_changed: not a floppy\r\n"); + printk("floppy_changed: not a floppy\n"); return 0; } - if (fake_change & mask) { - fake_change &= ~mask; -/* omitting the next line breaks formatting in a horrible way ... */ - changed_floppies &= ~mask; - return 1; - } if (changed_floppies & mask) { changed_floppies &= ~mask; recalibrate = 1; @@ -295,7 +179,7 @@ int floppy_change(struct buffer_head * bh) changed_floppies &= ~mask; recalibrate = 1; return 1; - } + } return 0; } @@ -306,16 +190,10 @@ __asm__("cld ; rep ; movsl" \ static void setup_DMA(void) { - unsigned long addr,count; + unsigned long addr = (long) CURRENT->buffer; + unsigned long count = 1024; - if (command == FD_FORMAT) { - addr = (long) tmp_floppy_area; - count = floppy->sect*4; - } - else { - addr = (long) CURRENT->buffer; - count = 1024; - } + cli(); if (read_track) { /* mark buffer-track bad, in case all this fails.. */ buffer_drive = buffer_track = -1; @@ -327,7 +205,6 @@ static void setup_DMA(void) copy_buffer(CURRENT->buffer,tmp_floppy_area); } /* mask DMA 2 */ - cli(); immoutb_p(4|2,10); /* output command byte. I don't know why, but everyone (minix, */ /* sanches & canton) output this twice, first to 12 then to 11 */ @@ -397,12 +274,12 @@ static int result(void) static void bad_flp_intr(void) { current_track = NO_TRACK; - CURRENT_ERRORS++; - if (CURRENT_ERRORS > MAX_ERRORS) { + CURRENT->errors++; + if (CURRENT->errors > MAX_ERRORS) { floppy_deselect(current_drive); - request_done(0); + end_request(0); } - if (CURRENT_ERRORS > MAX_ERRORS/2) + if (CURRENT->errors > MAX_ERRORS/2) reset = 1; else recalibrate = 1; @@ -420,22 +297,12 @@ static void rw_interrupt(void) if (ST1 & 0x02) { printk("Drive %d is write protected\n\r",current_drive); floppy_deselect(current_drive); - request_done(0); + end_request(0); } else bad_flp_intr(); - redo_fd_request(); + do_fd_request(); return; } - if (probing) { - int drive = MINOR(CURRENT->dev); - - if (ftd_msg[drive]) - printk("Auto-detected floppy type %s in fd%d\r\n", - floppy->name,drive); - current_type[drive] = floppy; - floppy_sizes[drive] = floppy->size >> 1; - probing = 0; - } if (read_track) { buffer_track = seek_track; buffer_drive = current_drive; @@ -446,8 +313,8 @@ static void rw_interrupt(void) (unsigned long)(CURRENT->buffer) >= 0x100000) copy_buffer(tmp_floppy_area,CURRENT->buffer); floppy_deselect(current_drive); - request_done(1); - redo_fd_request(); + end_request(1); + do_fd_request(); } /* @@ -462,31 +329,23 @@ inline void setup_rw_floppy(void) setup_DMA(); do_floppy = rw_interrupt; output_byte(command); - if (command != FD_FORMAT) { - if (read_track) { - output_byte(current_drive); - output_byte(track); - output_byte(0); - output_byte(1); - } else { - output_byte(head<<2 | current_drive); - output_byte(track); - output_byte(head); - output_byte(sector); - } - output_byte(2); /* sector size = 512 */ - output_byte(floppy->sect); - output_byte(floppy->gap); - output_byte(0xFF); /* sector size (0xff when n!=0 ?) */ + if (read_track) { + output_byte(current_drive); + output_byte(track); + output_byte(0); + output_byte(1); } else { output_byte(head<<2 | current_drive); - output_byte(2); - output_byte(floppy->sect); - output_byte(floppy->fmt_gap); - output_byte(FD_FILL_BYTE); - } + output_byte(track); + output_byte(head); + output_byte(sector); + } + output_byte(2); /* sector size = 512 */ + output_byte(floppy->sect); + output_byte(floppy->gap); + output_byte(0xFF); /* sector size (0xff when n!=0 ?) */ if (reset) - redo_fd_request(); + do_fd_request(); } /* @@ -501,7 +360,7 @@ static void seek_interrupt(void) if (result() != 2 || (ST0 & 0xF8) != 0x20 || ST1 != seek_track) { recalibrate = 1; bad_flp_intr(); - redo_fd_request(); + do_fd_request(); return; } current_track = ST1; @@ -515,8 +374,7 @@ static void seek_interrupt(void) */ static void transfer(void) { - read_track = (command == FD_READ) && (CURRENT_ERRORS < 4) && - (floppy->sect <= MAX_BUFFER_SECTORS); + read_track = (command == FD_READ) && (CURRENT->errors < 4); if (cur_spec1 != floppy->spec1) { cur_spec1 = floppy->spec1; output_byte(FD_SPECIFY); @@ -526,7 +384,7 @@ static void transfer(void) if (cur_rate != floppy->rate) outb_p(cur_rate = floppy->rate,FD_DCR); if (reset) { - redo_fd_request(); + do_fd_request(); return; } if (!seek) { @@ -541,27 +399,22 @@ static void transfer(void) output_byte((head<<2) | current_drive); output_byte(seek_track); if (reset) - redo_fd_request(); + do_fd_request(); } /* * Special case - used after a unexpected interrupt (or reset) */ - -static void recalibrate_floppy(); - static void recal_interrupt(void) { output_byte(FD_SENSEI); current_track = NO_TRACK; if (result()!=2 || (ST0 & 0xE0) == 0x60) reset = 1; -/* Recalibrate until track 0 is reached. Might help on some errors. */ - if ((ST0 & 0x10) == 0x10) recalibrate_floppy(); - else redo_fd_request(); + do_fd_request(); } -static void unexpected_floppy_interrupt(void) +void unexpected_floppy_interrupt(void) { current_track = NO_TRACK; output_byte(FD_SENSEI); @@ -579,7 +432,7 @@ static void recalibrate_floppy(void) output_byte(FD_RECALIBRATE); output_byte(head<<2 | current_drive); if (reset) - redo_fd_request(); + do_fd_request(); } static void reset_interrupt(void) @@ -589,11 +442,7 @@ static void reset_interrupt(void) output_byte(FD_SPECIFY); output_byte(cur_spec1); /* hut etc */ output_byte(6); /* Head load time =6ms, DMA */ - if (!recover) redo_fd_request(); - else { - recalibrate_floppy(); - recover = 0; - } + do_fd_request(); } /* @@ -618,72 +467,11 @@ static void reset_floppy(void) sti(); } -static void floppy_shutdown(void) -{ - cli(); - request_done(0); - recover = 1; - reset_floppy(); - sti(); -} - -static void shake_done(void) -{ - current_track = NO_TRACK; - if (inb(FD_DIR) & 0x80) request_done(0); - redo_fd_request(); -} - -static int retry_recal(void (*proc)(void)) -{ - output_byte(FD_SENSEI); - if (result() == 2 && (ST0 & 0x10) != 0x10) return 0; - do_floppy = proc; - output_byte(FD_RECALIBRATE); - output_byte(head<<2 | current_drive); - return 1; -} - -static void shake_zero(void) -{ - if (!retry_recal(shake_zero)) shake_done(); -} - -static void shake_one(void) -{ - if (retry_recal(shake_one)) return; - do_floppy = shake_done; - output_byte(FD_SEEK); - output_byte(head << 2 | current_drive); - output_byte(1); -} - static void floppy_on_interrupt(void) { if (inb(FD_DIR) & 0x80) { changed_floppies |= 1< 0) - keep_data[current_drive]--; - } - else { - if (ftd_msg[current_drive] && current_type[ - current_drive] != NULL) - printk("Disk type is undefined after disk " - "change in fd%d\r\n",current_drive); - current_type[current_drive] = NULL; - floppy_sizes[current_drive] = MAX_DISK_SIZE; - } -/* Forcing the drive to seek makes the "media changed" condition go away. - There should be a cleaner solution for that ... */ - if (!reset && !recalibrate) { - do_floppy = (current_track && current_track != NO_TRACK) - ? shake_zero : shake_one; - output_byte(FD_RECALIBRATE); - output_byte(head<<2 | current_drive); - return; - } } if (reset) { reset_floppy(); @@ -706,109 +494,45 @@ static void floppy_on_interrupt(void) transfer(); } -static void setup_format_params(void) -{ - unsigned char *here = (unsigned char *) tmp_floppy_area; - int count; - - for (count = 1; count <= floppy->sect; count++) { - *here++ = track; - *here++ = head; - *here++ = count; - *here++ = 2; /* 512 bytes */ - } -} - -static void redo_fd_request(void) +void do_fd_request(void) { unsigned int block; char * buffer_area; - int device; - -repeat: - if (format_status == FORMAT_WAIT) format_status = FORMAT_BUSY; - if (format_status != FORMAT_BUSY) { - if (!CURRENT) { - if (!fdc_busy) panic("FDC access conflict"); - fdc_busy = 0; - wake_up(&fdc_wait); - CLEAR_INTR; - return; - } - if (MAJOR(CURRENT->dev) != MAJOR_NR) - panic(DEVICE_NAME ": request list destroyed"); \ - if (CURRENT->bh) { - if (!CURRENT->bh->b_lock) - panic(DEVICE_NAME ": block not locked"); - } - } + + INIT_REQUEST; seek = 0; - probing = 0; - device = MINOR(CURRENT_DEVICE); - if (device > 3) - floppy = (device >> 2) + floppy_type; - else { /* Auto-detection */ - if ((floppy = current_type[device & 3]) == NULL) { - probing = 1; - if ((floppy = base_type[device & 3]) == - NULL) { - request_done(0); - goto repeat; - } - floppy += CURRENT_ERRORS & 1; - } - } - if (format_status != FORMAT_BUSY) { - if (current_drive != CURRENT_DEV) - current_track = NO_TRACK; - current_drive = CURRENT_DEV; - block = CURRENT->sector; - if (block+2 > floppy->size) { - request_done(0); - goto repeat; - } - sector = block % floppy->sect; - block /= floppy->sect; - head = block % floppy->head; - track = block / floppy->head; - seek_track = track << floppy->stretch; - if (CURRENT->cmd == READ) - command = FD_READ; - else if (CURRENT->cmd == WRITE) - command = FD_WRITE; - else { - printk("do_fd_request: unknown command\n"); - request_done(0); - goto repeat; - } - } + floppy = (MINOR(CURRENT->dev)>>2) + floppy_type; + if (current_drive != CURRENT_DEV) + current_track = NO_TRACK; + current_drive = CURRENT_DEV; + block = CURRENT->sector; + if (block+2 > floppy->size) { + end_request(0); + goto repeat; + } + sector = block % floppy->sect; + block /= floppy->sect; + head = block % floppy->head; + track = block / floppy->head; + seek_track = track << floppy->stretch; + if (CURRENT->cmd == READ) + command = FD_READ; + else if (CURRENT->cmd == WRITE) + command = FD_WRITE; else { - if (current_drive != (format_req.device & 3)) - current_track = NO_TRACK; - current_drive = format_req.device & 3; - if (((unsigned) format_req.track) >= floppy->track || - (format_req.head & 0xfffe) || probing) { - request_done(0); - goto repeat; - } - head = format_req.head; - track = format_req.track; - seek_track = track << floppy->stretch; - if (seek_track == buffer_track) buffer_track = -1; - command = FD_FORMAT; - setup_format_params(); + printk("do_fd_request: unknown command\n"); + end_request(0); + goto repeat; } - timer_table[FLOPPY_TIMER].expires = jiffies+10*HZ; - timer_active |= 1 << FLOPPY_TIMER; if ((seek_track == buffer_track) && (current_drive == buffer_drive)) { buffer_area = floppy_track_buffer + ((sector + head*floppy->sect)<<9); if (command == FD_READ) { copy_buffer(buffer_area,CURRENT->buffer); - request_done(1); + end_request(1); goto repeat; - } else if (command == FD_WRITE) + } else copy_buffer(CURRENT->buffer,buffer_area); } if (seek_track != current_track) @@ -817,188 +541,25 @@ repeat: add_timer(ticks_to_floppy_on(current_drive),&floppy_on_interrupt); } -void do_fd_request(void) -{ - cli(); - while (fdc_busy) sleep_on(&fdc_wait); - fdc_busy = 1; - sti(); - redo_fd_request(); -} - -static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned int param) -{ - int drive,cnt,okay; - struct floppy_struct *this; - - switch (cmd) { - RO_IOCTLS(inode->i_rdev,param); - } - if (!suser()) return -EPERM; - drive = MINOR(inode->i_rdev); - switch (cmd) { - case FDFMTBEG: - return 0; - case FDFMTEND: - cli(); - fake_change |= 1 << (drive & 3); - sti(); - drive &= 3; - cmd = FDCLRPRM; - break; - case FDGETPRM: - if (drive > 3) this = &floppy_type[drive >> 2]; - else if ((this = current_type[drive & 3]) == NULL) - return -ENODEV; - verify_area((void *) param,sizeof(struct floppy_struct)); - for (cnt = 0; cnt < sizeof(struct floppy_struct); cnt++) - put_fs_byte(((char *) this)[cnt], - (char *) param+cnt); - return 0; - case FDFMTTRK: - cli(); - while (format_status != FORMAT_NONE) - sleep_on(&format_done); - for (cnt = 0; cnt < sizeof(struct format_descr); cnt++) - ((char *) &format_req)[cnt] = get_fs_byte( - (char *) param+cnt); - format_req.device = drive; - format_status = FORMAT_WAIT; - format_errors = 0; - while (format_status != FORMAT_OKAY && format_status != - FORMAT_ERROR) { - if (fdc_busy) sleep_on(&fdc_wait); - else { - fdc_busy = 1; - redo_fd_request(); - } - } - while (format_status != FORMAT_OKAY && format_status != - FORMAT_ERROR) - sleep_on(&format_done); - sti(); - okay = format_status == FORMAT_OKAY; - format_status = FORMAT_NONE; - wake_up(&format_done); - return okay ? 0 : -EIO; - } - if (drive < 0 || drive > 3) return -EINVAL; - switch (cmd) { - case FDCLRPRM: - current_type[drive] = NULL; - floppy_sizes[drive] = MAX_DISK_SIZE; - keep_data[drive] = 0; - break; - case FDSETPRM: - case FDDEFPRM: - for (cnt = 0; cnt < sizeof(struct floppy_struct); cnt++) - ((char *) &user_params[drive])[cnt] = - get_fs_byte((char *) param+cnt); - current_type[drive] = &user_params[drive]; - floppy_sizes[drive] = user_params[drive].size >> 1; - if (cmd == FDDEFPRM) keep_data[drive] = -1; - else { - cli(); - while (fdc_busy) sleep_on(&fdc_wait); - fdc_busy = 1; - sti(); - outb_p((current_DOR & 0xfc) | drive | - (0x10 << drive),FD_DOR); - for (cnt = 0; cnt < 1000; cnt++) __asm__("nop"); - keep_data[drive] = (inb(FD_DIR) & 0x80) ? 1 : 0; - outb_p(current_DOR,FD_DOR); - fdc_busy = 0; - wake_up(&fdc_wait); - } - break; - case FDMSGON: - ftd_msg[drive] = 1; - break; - case FDMSGOFF: - ftd_msg[drive] = 0; - break; - default: - return -EINVAL; - } - return 0; -} - -#define CMOS_READ(addr) ({ \ -outb_p(0x80|addr,0x70); \ -inb_p(0x71); \ -}) - -static struct floppy_struct *find_base(int drive,int code) -{ - struct floppy_struct *base; - - if (code > 0 && code < 5) { - base = &floppy_types[(code-1)*2]; - printk("fd%d is %s",drive,base->name); - return base; - } - printk("fd%d is unknown type %d",drive,code); - return NULL; -} - -static void config_types(void) -{ - printk("Floppy drive(s): "); - base_type[0] = find_base(0,(CMOS_READ(0x10) >> 4) & 15); - if (((CMOS_READ(0x14) >> 6) & 1) == 0) - base_type[1] = NULL; - else { - printk(", "); - base_type[1] = find_base(1,CMOS_READ(0x10) & 15); - } - base_type[2] = base_type[3] = NULL; - printk("\r\n"); -} - -static int floppy_open(struct inode * inode, struct file * filp) -{ - if (filp->f_mode) - check_disk_change(inode->i_rdev); - return 0; -} - -static void floppy_release(struct inode * inode, struct file * filp) -{ - sync_dev(inode->i_rdev); -} +static int floppy_sizes[] ={ + 0, 0, 0, 0, + 360, 360 ,360, 360, + 1200,1200,1200,1200, + 360, 360, 360, 360, + 720, 720, 720, 720, + 360, 360, 360, 360, + 720, 720, 720, 720, + 1440,1440,1440,1440 +}; static struct file_operations floppy_fops = { NULL, /* lseek - default */ block_read, /* read - general block-dev read */ block_write, /* write - general block-dev write */ NULL, /* readdir - bad */ + NULL, /* close - default */ NULL, /* select */ - fd_ioctl, /* ioctl */ - floppy_open, /* open */ - floppy_release /* release */ -}; - -static void floppy_interrupt(int cpl) -{ - void (*handler)(void) = DEVICE_INTR; - - DEVICE_INTR = NULL; - if (!handler) - handler = unexpected_floppy_interrupt; - handler(); -} - -/* - * This is the harddisk IRQ descruption. The SA_INTERRUPT in sa_flags - * means we run the IRQ-handler with interrupts disabled: this is bad for - * interrupt latency, but may be safer... - */ -static struct sigaction floppy_sigaction = { - floppy_interrupt, - 0, - SA_INTERRUPT, - NULL + NULL /* ioctl */ }; void floppy_init(void) @@ -1007,9 +568,6 @@ void floppy_init(void) blk_size[MAJOR_NR] = floppy_sizes; blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; blkdev_fops[MAJOR_NR] = &floppy_fops; - timer_table[FLOPPY_TIMER].fn = floppy_shutdown; - timer_active &= ~(1 << FLOPPY_TIMER); - config_types(); - if (irqaction(FLOPPY_IRQ,&floppy_sigaction)) - printk("Unable to grab IRQ%d for the floppy driver\n",FLOPPY_IRQ); + set_intr_gate(0x26,&floppy_interrupt); + outb(inb_p(0x21)&~0x40,0x21); } diff --git a/kernel/blk_drv/hd.c b/kernel/blk_drv/hd.c index 8ff900d2542a..756ebde19b48 100644 --- a/kernel/blk_drv/hd.c +++ b/kernel/blk_drv/hd.c @@ -16,10 +16,7 @@ * in the early extended-partition checks and added DM partitions */ -#define HD_IRQ 14 - #include -#include #include #include @@ -27,8 +24,6 @@ #include #include #include - -#define REALLY_SLOW_IO #include #include #include @@ -42,8 +37,6 @@ static inline unsigned char CMOS_READ(unsigned char addr) return inb_p(0x71); } -#define HD_DELAY 0 - /* Max read/write errors/sector */ #define MAX_ERRORS 7 #define MAX_HD 2 @@ -54,10 +47,6 @@ static void bad_rw_intr(void); static int recalibrate = 0; static int reset = 0; -#if (HD_DELAY > 0) -unsigned long last_req, read_timer(); -#endif - /* * This struct defines the HD's and their types. */ @@ -85,6 +74,7 @@ __asm__("cld;rep;insw"::"d" (port),"D" (buf),"c" (nr):"cx","di") #define port_write(port,buf,nr) \ __asm__("cld;rep;outsw"::"d" (port),"S" (buf),"c" (nr):"cx","si") +extern void hd_interrupt(void); extern void rd_load(void); static unsigned int current_minor; @@ -281,29 +271,11 @@ int sys_setup(void * BIOS) blk_size[MAJOR_NR] = hd_sizes; if (NR_HD) printk("Partition table%s ok.\n\r",(NR_HD>1)?"s":""); -#ifdef RAMDISK rd_load(); -#endif mount_root(); return (0); } -#if (HD_DELAY > 0) -unsigned long read_timer(void) -{ - unsigned long t; - int i; - - cli(); - outb_p(0xc2, 0x43); - t = jiffies * 11931 + (inb_p(0x40) & 0x80 ? 5966 : 11932); - i = inb_p(0x40); - i |= inb(0x40) << 8; - sti(); - return(t - i / 2); -} -#endif - static int controller_ready(void) { int retries = 100000; @@ -336,10 +308,6 @@ static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect, if (drive>1 || head>15) panic("Trying to write bad sector"); -#if (HD_DELAY > 0) - while (read_timer() - last_req < HD_DELAY) - /* nothing */; -#endif if (reset || !controller_ready()) { reset = 1; return; @@ -353,7 +321,7 @@ static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect, outb_p(cyl,++port); outb_p(cyl>>8,++port); outb_p(0xA0|(drive<<4)|head,++port); - outb_p(cmd,++port); + outb(cmd,++port); } static int drive_busy(void) @@ -375,7 +343,6 @@ static void reset_controller(void) { int i; - printk("HD-controller reset\r\n"); outb(4,HD_CMD); for(i = 0; i < 1000; i++) nop(); outb(hd_info[0].ctl & 0x0f ,HD_CMD); @@ -430,82 +397,48 @@ static void bad_rw_intr(void) return; if (++CURRENT->errors >= MAX_ERRORS) end_request(0); - else if (CURRENT->errors > MAX_ERRORS/2) + if (CURRENT->errors > MAX_ERRORS/2) reset = 1; else recalibrate = 1; } -#define STAT_MASK (BUSY_STAT | READY_STAT | WRERR_STAT | SEEK_STAT | ERR_STAT) -#define STAT_OK (READY_STAT | SEEK_STAT) - static void read_intr(void) { - int i; - - i = (unsigned) inb_p(HD_STATUS); - if (!(i & DRQ_STAT)) - goto bad_read; - if ((i & STAT_MASK) != STAT_OK) - goto bad_read; + SET_INTR(&read_intr); + if (win_result()) { + SET_INTR(NULL); + bad_rw_intr(); + do_hd_request(); + return; + } port_read(HD_DATA,CURRENT->buffer,256); - i = (unsigned) inb_p(HD_STATUS); - if (!(i & BUSY_STAT)) - if ((i & STAT_MASK) != STAT_OK) - goto bad_read; CURRENT->errors = 0; CURRENT->buffer += 512; CURRENT->sector++; - i = --CURRENT->nr_sectors; - if (!i || (CURRENT->bh && !(i&1))) - end_request(1); - if (i > 0) { - SET_INTR(&read_intr); + if (--CURRENT->nr_sectors) return; - } -#if (HD_DELAY > 0) - last_req = read_timer(); -#endif - do_hd_request(); - return; -bad_read: - if (i & ERR_STAT) - i = (unsigned) inb(HD_ERROR); - bad_rw_intr(); + SET_INTR(NULL); + end_request(1); do_hd_request(); - return; } static void write_intr(void) { - int i; - - i = (unsigned) inb_p(HD_STATUS); - if ((i & STAT_MASK) != STAT_OK) - goto bad_write; - if (CURRENT->nr_sectors > 1 && !(i & DRQ_STAT)) - goto bad_write; - CURRENT->sector++; - i = --CURRENT->nr_sectors; - CURRENT->buffer += 512; - if (!i || (CURRENT->bh && !(i & 1))) - end_request(1); - if (i > 0) { + if (win_result()) { + bad_rw_intr(); + do_hd_request(); + return; + } + if (--CURRENT->nr_sectors) { + CURRENT->sector++; + CURRENT->buffer += 512; SET_INTR(&write_intr); port_write(HD_DATA,CURRENT->buffer,256); - } else { -#if (HD_DELAY > 0) - last_req = read_timer(); -#endif - do_hd_request(); + return; } - return; -bad_write: - if (i & ERR_STAT) - i = (unsigned) inb(HD_ERROR); - bad_rw_intr(); + end_request(1); do_hd_request(); - return; } static void recal_intr(void) @@ -521,7 +454,7 @@ static void recal_intr(void) */ static void hd_times_out(void) { - DEVICE_INTR = NULL; + do_hd = NULL; reset = 1; if (!CURRENT) return; @@ -543,7 +476,7 @@ static void do_hd_request(void) dev = MINOR(CURRENT->dev); block = CURRENT->sector; nsect = CURRENT->nr_sectors; - if (dev >= (NR_HD<<6) || block >= hd[dev].nr_sects) { + if (dev >= (NR_HD<<6) || block+nsect > hd[dev].nr_sects) { end_request(0); goto repeat; } @@ -561,7 +494,8 @@ static void do_hd_request(void) } if (recalibrate) { recalibrate = 0; - hd_out(dev,hd_info[dev].sect,0,0,0,WIN_RESTORE,&recal_intr); + hd_out(dev,hd_info[dev].sect,0,0,0, + WIN_RESTORE,&recal_intr); if (reset) goto repeat; return; @@ -598,71 +532,34 @@ static int hd_ioctl(struct inode * inode, struct file * file, return -EINVAL; switch (cmd) { case HDIO_REQ: - verify_area(loc, sizeof(*loc)); put_fs_byte(hd_info[dev].head, (char *) &loc->heads); put_fs_byte(hd_info[dev].sect, (char *) &loc->sectors); put_fs_word(hd_info[dev].cyl, (short *) &loc->cylinders); - put_fs_long(hd[MINOR(inode->i_rdev)].start_sect, - (long *) &loc->start); return 0; - RO_IOCTLS(inode->i_rdev,arg); default: return -EINVAL; } } -/* - * Releasing a block device means we sync() it, so that it can safely - * be forgotten about... - */ -static void hd_release(struct inode * inode, struct file * file) -{ - sync_dev(inode->i_rdev); -} - static struct file_operations hd_fops = { NULL, /* lseek - default */ block_read, /* read - general block-dev read */ block_write, /* write - general block-dev write */ NULL, /* readdir - bad */ + NULL, /* close - default */ NULL, /* select */ - hd_ioctl, /* ioctl */ - NULL, /* no special open code */ - hd_release /* release */ -}; - -static void hd_interrupt(int cpl) -{ - void (*handler)(void) = DEVICE_INTR; - - DEVICE_INTR = NULL; - timer_active &= ~(1< -#include #include #include #include #include "blk.h" -extern long rd_init(long mem_start, int length); - /* * The request-struct contains all necessary data * to load a nr of sectors into memory @@ -26,7 +23,7 @@ struct request request[NR_REQUEST]; /* * used to wait on when there are no free requests */ -struct wait_queue * wait_for_request = NULL; +struct task_struct * wait_for_request = NULL; /* blk_dev_struct is: * do_request-address @@ -39,10 +36,7 @@ struct blk_dev_struct blk_dev[NR_BLK_DEV] = { { NULL, NULL }, /* dev hd */ { NULL, NULL }, /* dev ttyx */ { NULL, NULL }, /* dev tty */ - { NULL, NULL }, /* dev lp */ - { NULL, NULL }, /* dev pipes */ - { NULL, NULL }, /* dev sd */ - { NULL, NULL } /* dev st */ + { NULL, NULL } /* dev lp */ }; /* @@ -71,31 +65,6 @@ static inline void unlock_buffer(struct buffer_head * bh) wake_up(&bh->b_wait); } -/* RO fail safe mechanism */ - -static long ro_bits[NR_BLK_DEV][8]; - -int is_read_only(int dev) -{ - int minor,major; - - major = MAJOR(dev); - minor = MINOR(dev); - if (major < 0 || major >= NR_BLK_DEV) return 0; - return ro_bits[major][minor >> 5] & (1 << (minor & 31)); -} - -void set_device_ro(int dev,int flag) -{ - int minor,major; - - major = MAJOR(dev); - minor = MINOR(dev); - if (major < 0 || major >= NR_BLK_DEV) return; - if (flag) ro_bits[major][minor >> 5] |= 1 << (minor & 31); - else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31)); -} - /* * add-request adds a request to the linked list. * It disables interrupts so that it can muck with the @@ -153,34 +122,12 @@ static void make_request(int major,int rw, struct buffer_head * bh) printk("Bad block dev command, must be R/W/RA/WA\n"); return; } - if (blk_size[major]) - if (blk_size[major][MINOR(bh->b_dev)] <= bh->b_blocknr) { - bh->b_dirt = bh->b_uptodate = 0; - return; - } lock_buffer(bh); if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) { unlock_buffer(bh); return; } repeat: - cli(); - if (major == 3 && (req = blk_dev[major].current_request)) { - while (req = req->next) { - if (req->dev == bh->b_dev && - !req->waiting && - req->cmd == rw && - req->sector + req->nr_sectors == bh->b_blocknr << 1 && - req->nr_sectors < 254) { - req->bhtail->b_reqnext = bh; - req->bhtail = bh; - req->nr_sectors += 2; - bh->b_dirt = 0; - sti(); - return; - } - } - } /* we don't allow the write-requests to fill up the queue completely: * we want some room for reads: they take precedence. The last third * of the requests are only for reads. @@ -190,6 +137,7 @@ repeat: else req = request+(NR_REQUEST/2); /* find an empty request */ + cli(); while (--req >= request) if (req->dev < 0) goto found; @@ -207,13 +155,12 @@ found: sti(); /* fill up the request-info, and add it to the queue */ req->dev = bh->b_dev; req->cmd = rw; - req->errors = 0; + req->errors=0; req->sector = bh->b_blocknr<<1; req->nr_sectors = 2; req->buffer = bh->b_data; req->waiting = NULL; req->bh = bh; - req->bhtail = bh; req->next = NULL; add_request(major+blk_dev,req); } @@ -229,10 +176,6 @@ void ll_rw_page(int rw, int dev, int page, char * buffer) } if (rw!=READ && rw!=WRITE) panic("Bad block dev command, must be R/W"); - if (rw == WRITE && is_read_only(dev)) { - printk("Can't page to read-only device 0x%X\n\r",dev); - return; - } cli(); repeat: req = request+NR_REQUEST; @@ -251,7 +194,7 @@ repeat: req->sector = page<<3; req->nr_sectors = 8; req->buffer = buffer; - req->waiting = ¤t->wait; + req->waiting = current; req->bh = NULL; req->next = NULL; current->state = TASK_UNINTERRUPTIBLE; @@ -263,23 +206,15 @@ void ll_rw_block(int rw, struct buffer_head * bh) { unsigned int major; - if (!bh) - return; if ((major=MAJOR(bh->b_dev)) >= NR_BLK_DEV || !(blk_dev[major].request_fn)) { printk("ll_rw_block: Trying to read nonexistent block-device\n\r"); - bh->b_dirt = bh->b_uptodate = 0; - return; - } - if ((rw == WRITE || rw == WRITEA) && is_read_only(bh->b_dev)) { - printk("Can't write to read-only device 0x%X\n\r",bh->b_dev); - bh->b_dirt = bh->b_uptodate = 0; return; } make_request(major,rw,bh); } -long blk_dev_init(long mem_start, long mem_end) +void blk_dev_init(void) { int i; @@ -287,11 +222,6 @@ long blk_dev_init(long mem_start, long mem_end) request[i].dev = -1; request[i].next = NULL; } - memset(ro_bits,0,sizeof(ro_bits)); -#ifdef RAMDISK - mem_start += rd_init(mem_start, RAMDISK*1024); -#endif - return mem_start; } void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buf) @@ -309,10 +239,6 @@ void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buf) printk("ll_rw_swap: bad block dev command, must be R/W"); return; } - if (rw == WRITE && is_read_only(dev)) { - printk("Can't swap to read-only device 0x%X\n\r",dev); - return; - } for (i=0; isector = b[i] << 1; req->nr_sectors = 2; req->buffer = buf; - req->waiting = ¤t->wait; + req->waiting = current; req->bh = NULL; req->next = NULL; current->state = TASK_UNINTERRUPTIBLE; diff --git a/kernel/blk_drv/ramdisk.c b/kernel/blk_drv/ramdisk.c index 833322f64ad1..c507631aeb58 100644 --- a/kernel/blk_drv/ramdisk.c +++ b/kernel/blk_drv/ramdisk.c @@ -52,10 +52,9 @@ static struct file_operations rd_fops = { block_read, /* read - general block-dev read */ block_write, /* write - general block-dev write */ NULL, /* readdir - bad */ + NULL, /* close - default */ NULL, /* select */ - NULL, /* ioctl */ - NULL, /* no special open code */ - NULL /* no special release code */ + NULL /* ioctl */ }; /* @@ -84,7 +83,7 @@ long rd_init(long mem_start, int length) void rd_load(void) { struct buffer_head *bh; - struct minix_super_block s; + struct super_block s; int block = 256; /* Start at block 256 */ int i = 1; int nblocks; @@ -112,7 +111,7 @@ void rd_load(void) nblocks, rd_length >> BLOCK_SIZE_BITS); return; } - printk("Loading %d bytes into ram disk\n", + printk("Loading %d bytes into ram disk... 0000k", nblocks << BLOCK_SIZE_BITS); cp = rd_start; while (nblocks) { @@ -127,12 +126,12 @@ void rd_load(void) } (void) memcpy(cp, bh->b_data, BLOCK_SIZE); brelse(bh); - if (!(nblocks-- & 15)) - printk("."); + printk("\010\010\010\010\010%4dk",i); cp += BLOCK_SIZE; block++; + nblocks--; i++; } - printk("\ndone\n"); + printk("\010\010\010\010\010done \n"); ROOT_DEV=0x0101; } diff --git a/kernel/blk_drv/scsi/Makefile b/kernel/blk_drv/scsi/Makefile deleted file mode 100644 index fd978dd1f471..000000000000 --- a/kernel/blk_drv/scsi/Makefile +++ /dev/null @@ -1,138 +0,0 @@ -# -# Makefile for the linux kernel block device drivers. -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# - -#DEBUG = -DDEBUG=0xffffffff -DDEBUG_NO_CMD - -.c.s: - $(CC) $(CFLAGS) $(DEBUG) -S $< -.s.o: - $(AS) -c -o $*.o $< -.c.o: - $(CC) $(CFLAGS) $(DEBUG) -c $< - -LOWLEVELCSRC = aha1542.c seagate.c ultrastor.c -LOWLEVELHSRC = aha1542.c seagate.h ultrastor.h - -CSRC = hosts.c sd.c st.c scsi.c $(LOWLEVELCSRC) -HSRC = hosts.h sd.h st.h scsi.h $(LOWLEVELHSRC) - -OBJS = scsi.o hosts.o scsi_ioctl.o sd.o sd_ioctl.o st.o st_ioctl.o \ - aha1542.o seagate.o ultrastor.o - -all: scsi.a - -config.out : config.in $(KERNELHDRS)/linux/config.h - rm -f foo.c - ln -s config.in foo.c - $(CPP) foo.c | grep '\.o' > config.out - rm foo.c - -figure : hosts.h $(KERNELHDRS)/linux/config.h hosts.c config.out - $(HOSTCC) -I$(KERNELHDRS) -DFIGURE_MAX_SCSI_HOSTS hosts.c -o figure - -max_hosts.h : figure - (echo "#ifndef _MAX_HOSTS_H"; \ - echo "#define _MAX_HOSTS_H"; \ - echo "#define MAX_SCSI_HOSTS `./figure`";\ - echo "#endif") > tmp_max - cp tmp_max max_hosts.h - -scsi.a: $(OBJS) - $(AR) rcs scsi.a $(OBJS) - sync - -scsi.shar: Makefile scsi.doc $(CSRC) $(HSRC) ../ll_rw_blk.c ../blk.h all.diff - (cd ..; shar scsi/scsi.doc scsi/Makefile scsi/*.{c,h} scsi/all.diff blk.h ll_rw_blk.c) > scsi.shar; - -clean: - rm -f core *.o *.a tmp_make tmp_max figure config.out Makefile.tag max_hosts.h - -seagate.s seagate.o : seagate.c ../../../include/linux/config.h \ - ../../../include/linux/config.dist.h ../../../include/linux/sched.h \ - ../../../include/linux/head.h ../../../include/linux/fs.h \ - ../../../include/sys/types.h ../../../include/linux/mm.h \ - ../../../include/linux/kernel.h ../../../include/signal.h \ - ../../../include/sys/param.h ../../../include/sys/time.h \ - ../../../include/time.h ../../../include/sys/resource.h \ - ../../../include/linux/string.h seagate.h scsi.h hosts.h max_hosts.h - $(CC) -Wall -c seagate.c $(DEBUG) - -dep: - sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - for i in *.c ;do $(CPP) -M $$i;done >> tmp_make - cp tmp_make Makefile - -### Dependencies: -aha1542.s aha1542.o : aha1542.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \ - ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/linux/kernel.h \ - ../../../include/linux/head.h ../../../include/linux/string.h ../../../include/asm/system.h \ - ../../../include/asm/io.h scsi.h hosts.h max_hosts.h aha1542.h -hosts.s hosts.o : hosts.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \ - ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/linux/kernel.h \ - scsi.h hosts.h max_hosts.h aha1542.h seagate.h ultrastor.h -scsi.s scsi.o : scsi.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \ - ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/asm/system.h \ - ../../../include/linux/sched.h ../../../include/linux/head.h ../../../include/linux/fs.h \ - ../../../include/sys/types.h ../../../include/sys/dirent.h ../../../include/limits.h \ - ../../../include/linux/mm.h ../../../include/linux/kernel.h ../../../include/signal.h \ - ../../../include/sys/param.h ../../../include/sys/time.h ../../../include/time.h \ - ../../../include/sys/resource.h ../../../include/linux/timer.h ../../../include/linux/string.h \ - scsi.h hosts.h max_hosts.h sd.h st.h -scsi_ioctl.s scsi_ioctl.o : scsi_ioctl.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \ - ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/errno.h \ - ../../../include/asm/io.h ../../../include/asm/segment.h ../../../include/asm/system.h \ - ../../../include/linux/kernel.h ../../../include/linux/sched.h ../../../include/linux/head.h \ - ../../../include/linux/fs.h ../../../include/sys/types.h ../../../include/sys/dirent.h \ - ../../../include/limits.h ../../../include/linux/mm.h ../../../include/signal.h \ - ../../../include/sys/param.h ../../../include/sys/time.h ../../../include/time.h \ - ../../../include/sys/resource.h ../../../include/linux/string.h scsi.h hosts.h \ - max_hosts.h scsi_ioctl.h -sd.s sd.o : sd.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \ - ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/linux/string.h \ - ../../../include/linux/fs.h ../../../include/sys/types.h ../../../include/sys/dirent.h \ - ../../../include/limits.h ../../../include/linux/kernel.h ../../../include/linux/sched.h \ - ../../../include/linux/head.h ../../../include/linux/mm.h ../../../include/signal.h \ - ../../../include/sys/param.h ../../../include/sys/time.h ../../../include/time.h \ - ../../../include/sys/resource.h scsi.h sd.h ../blk.h -sd_ioctl.s sd_ioctl.o : sd_ioctl.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \ - ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/linux/kernel.h \ - ../../../include/linux/sched.h ../../../include/linux/head.h ../../../include/linux/fs.h \ - ../../../include/sys/types.h ../../../include/sys/dirent.h ../../../include/limits.h \ - ../../../include/linux/mm.h ../../../include/signal.h ../../../include/sys/param.h \ - ../../../include/sys/time.h ../../../include/time.h ../../../include/sys/resource.h \ - scsi.h sd.h -seagate.s seagate.o : seagate.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \ - ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/linux/sched.h \ - ../../../include/linux/head.h ../../../include/linux/fs.h ../../../include/sys/types.h \ - ../../../include/sys/dirent.h ../../../include/limits.h ../../../include/linux/mm.h \ - ../../../include/linux/kernel.h ../../../include/signal.h ../../../include/sys/param.h \ - ../../../include/sys/time.h ../../../include/time.h ../../../include/sys/resource.h \ - seagate.h scsi.h hosts.h max_hosts.h -st.s st.o : st.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \ - ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h scsi.h \ - st.h ../../../include/linux/fs.h ../../../include/sys/types.h ../../../include/sys/dirent.h \ - ../../../include/limits.h ../../../include/linux/kernel.h ../../../include/linux/sched.h \ - ../../../include/linux/head.h ../../../include/linux/mm.h ../../../include/signal.h \ - ../../../include/sys/param.h ../../../include/sys/time.h ../../../include/time.h \ - ../../../include/sys/resource.h ../blk.h -st_ioctl.s st_ioctl.o : st_ioctl.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \ - ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/linux/kernel.h \ - ../../../include/linux/sched.h ../../../include/linux/head.h ../../../include/linux/fs.h \ - ../../../include/sys/types.h ../../../include/sys/dirent.h ../../../include/limits.h \ - ../../../include/linux/mm.h ../../../include/signal.h ../../../include/sys/param.h \ - ../../../include/sys/time.h ../../../include/time.h ../../../include/sys/resource.h \ - st.h scsi.h -ultrastor.s ultrastor.o : ultrastor.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \ - ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/stddef.h \ - ../../../include/linux/string.h ../../../include/linux/sched.h ../../../include/linux/head.h \ - ../../../include/linux/fs.h ../../../include/sys/types.h ../../../include/sys/dirent.h \ - ../../../include/limits.h ../../../include/linux/mm.h ../../../include/linux/kernel.h \ - ../../../include/signal.h ../../../include/sys/param.h ../../../include/sys/time.h \ - ../../../include/time.h ../../../include/sys/resource.h ../../../include/linux/hdreg.h \ - ../../../include/asm/system.h ../../../include/asm/io.h ../../../include/asm/segment.h \ - ultrastor.h scsi.h hosts.h max_hosts.h diff --git a/kernel/blk_drv/scsi/aha1542.c b/kernel/blk_drv/scsi/aha1542.c deleted file mode 100644 index f09a2f2e9851..000000000000 --- a/kernel/blk_drv/scsi/aha1542.c +++ /dev/null @@ -1,457 +0,0 @@ -/* $Id: aha1542.c,v 1.1 1992/04/24 18:01:50 root Exp root $ - * linux/kernel/aha1542.c - * - * (C) 1992 Tommy Thorn - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "scsi.h" -#include "hosts.h" - -#include "aha1542.h" -#ifdef DEBUG -#define DEB(x) x -#else -#define DEB(x) -#endif - -/* -static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/aha1542.c,v 1.1 1992/04/24 18:01:50 root Exp root $"; -*/ - -#define base 0x330 -#define intr_chan 11 - -static struct mailbox mb[2]; -static struct ccb ccb; - -long WAITtimeout, WAITnexttimeout = 3000000; - -void (*do_done)() = NULL; - -#define aha1542_intr_reset() outb(IRST, CONTROL) -#define aha1542_enable_intr() outb(inb_p(0xA1) & ~8, 0xA1) -#define aha1542_disable_intr() outb(inb_p(0xA1) | 8, 0xA1) - -#define WAIT(port, mask, allof, noneof) \ - { register WAITbits; \ - register WAITtimeout = WAITnexttimeout; \ - while (1) { \ - WAITbits = inb(port) & (mask); \ - if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \ - break; \ - if (--WAITtimeout == 0) goto fail; \ - } \ - } - -static void aha1542_stat(void) -{ - int s = inb(STATUS), i = inb(INTRFLAGS); -/* printk("status = %x, intrflags = %x served %d last %x timeout %d\n", s, i, intr_flag, intr_last, WAITtimeout); */ - printk("status=%x intrflags=%x\n", s, i, WAITnexttimeout-WAITtimeout); -} - -static int aha1542_out(unchar *cmdp, int len) -{ - while (len--) - { - WAIT(STATUS, CDF, 0, CDF); - outb(*cmdp++, DATA); - } - return 0; - fail: - printk("aha1542_out failed(%d): ", len+1); aha1542_stat(); - return 1; -} - -int makecode(unsigned hosterr, unsigned scsierr) -{ - switch (hosterr) { - case 0x0: - case 0xa: /* Linked command complete without error and linked normally */ - case 0xb: /* Linked command complete without error, interrupt generated */ - hosterr = 0; - break; - - case 0x11: /* Selection time out-The initiator selection or target - reselection was not complete within the SCSI Time out period */ - hosterr = DID_TIME_OUT; - break; - - case 0x12: /* Data overrun/underrun-The target attempted to transfer more data - thean was allocated by the Data Length field or the sum of the - Scatter / Gather Data Length fields. */ - - case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */ - - case 0x15: /* MBO command was not 00, 01 or 02-The first byte of the CB was - invalid. This usually indicates a software failure. */ - - case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid. - This usually indicates a software failure. */ - - case 0x17: /* Linked CCB does not have the same LUN-A subsequent CCB of a set - of linked CCB's does not specify the same logical unit number as - the first. */ - case 0x18: /* Invalid Target Direction received from Host-The direction of a - Target Mode CCB was invalid. */ - - case 0x19: /* Duplicate CCB Received in Target Mode-More than once CCB was - received to service data transfer between the same target LUN - and initiator SCSI ID in the same direction. */ - - case 0x1a: /* Invalid CCB or Segment List Parameter-A segment list with a zero - length segment or invalid segment list boundaries was received. - A CCB parameter was invalid. */ - hosterr = DID_ERROR; /* Couldn't find any better */ - break; - - case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus - phase sequence was requested by the target. The host adapter - will generate a SCSI Reset Condition, notifying the host with - a SCRD interrupt */ - hosterr = DID_RESET; - break; - default: - printk("makecode: unknown hoststatus %x\n", hosterr); - break; - } - return scsierr|(hosterr << 16); -} - -int aha1542_test_port(void) -{ - volatile int debug = 0; - - /* Reset the adapter. I ought to make a hard reset, but it's not really nessesary */ - - /* DEB(printk("aha1542_test_port called \n")); */ - - outb(SRST|IRST/*|SCRST*/, CONTROL); - - debug = 1; - /* Expect INIT and IDLE, any of the others are bad */ - WAIT(STATUS, STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF); - - debug = 2; - /* Shouldn't have generated any interrupts during reset */ - if (inb(INTRFLAGS)&INTRMASK) goto fail; - - debug = 3; - /* Test the basic ECHO command */ - outb(CMD_ECHO, DATA); - - debug = 4; - /* Wait for CDF=0. If any of the others are set, it's bad */ - WAIT(STATUS, STATMASK, 0, STST|DIAGF|INVDCMD|DF|CDF); - - debug = 5; - /* The meaning of life */ - outb(42, DATA); - - debug = 6; - /* Expect only DF, that is, data ready */ - WAIT(STATUS, STATMASK, DF, STST|DIAGF|CDF|INVDCMD); - - debug = 7; - /* Is the answer correct? */ - if (inb(DATA) != 42) goto fail; - - debug = 8; - /* Reading port should reset DF */ - if (inb(STATUS) & DF) goto fail; - - debug = 9; - /* When HACC, command is completed, and we're though testing */ - WAIT(INTRFLAGS, HACC, HACC, 0); - /* now initialize adapter */ - - debug = 10; - /* Clear interrupts */ - outb(IRST, CONTROL); - - debug = 11; - - return debug; /* 1 = ok */ - fail: - return 0; /* 0 = not ok */ -} - -/* What's this little function for? */ -char *aha1542_info(void) -{ - static char buffer[] = "Adaptec 1542"; - return buffer; -} - -/* A "high" level interrupt handler */ -static void aha1542_interrupt(int cpl) -{ - int flag = inb(INTRFLAGS); - void (*my_done)() = do_done; - int errstatus; - - do_done = NULL; -#ifdef DEBUG - printk("aha1542_interrupt: "); - if (!(flag&ANYINTR)) printk("no interrupt?"); - if (flag&MBIF) printk("MBIF "); - if (flag&MBOA) printk("MBOF "); - if (flag&HACC) printk("HACC "); - if (flag&SCRD) printk("SCRD "); - printk("status %02x\n", inb(STATUS)); - if (ccb.tarstat|ccb.hastat) - printk("aha1542_command: returning %x (status %d)\n", ccb.tarstat + ((int) ccb.hastat << 16), mb[1].status); -#endif - aha1542_intr_reset(); - if (!my_done) { - printk("aha1542_interrupt: Unexpected interrupt\n"); - return; - } - - /* is there mail :-) */ - - if (!mb[1].status) { - DEB(printk("aha1542_interrupt: strange: mbif but no mail!\n")); - my_done(DID_TIME_OUT << 16); - return; - } - - /* more error checking left out here */ - if (mb[1].status != 1) - /* This is surely wrong, but I don't know what's right */ - errstatus = makecode(ccb.hastat, ccb.tarstat); - else - errstatus = 0; - - mb[1].status = 0; - - if (ccb.tarstat == 2) { - int i; - DEB(printk("aha1542_interrupt: sense:")); - for (i = 0; i < 12; i++) - printk("%02x ", ccb.cdb[ccb.cdblen+i]); - printk("\n"); -/* - DEB(printk("aha1542_interrupt: buf:")); - for (i = 0; i < bufflen; i++) - printk("%02x ", ((unchar *)buff)[i]); - printk("\n"); -*/ - } - DEB(if (errstatus) printk("aha1542_interrupt: returning %6x\n", errstatus)); - my_done(errstatus); - return; -} - -int aha1542_queuecommand(unchar target, const void *cmnd, void *buff, int bufflen, void (*done)(int)) -{ - unchar ahacmd = CMD_START_SCSI; - int i; - unchar *cmd = (unchar *) cmnd; - - DEB(if (target > 1) {done(DID_TIME_OUT << 16); return 0;}); - -#ifdef DEBUG - if (*cmd == READ_10 || *cmd == WRITE_10) - i = xscsi2int(cmd+2); - else if (*cmd == READ_6 || *cmd == WRITE_6) - i = scsi2int(cmd+2); - else - i = -1; - if (done) - printk("aha1542_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen); - else - printk("aha1542_command: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen); - aha1542_stat(); - printk("aha1542_queuecommand: dumping scsi cmd:"); - for (i = 0; i < (*cmd<=0x1f?6:10); i++) printk("%02x ", cmd[i]); - printk("\n"); - if (*cmd == WRITE_10 || *cmd == WRITE_6) - return 0; /* we are still testing, so *don't* write */ -#endif - memset(&ccb, 0, sizeof ccb); - - ccb.cdblen = (*cmd<=0x1f)?6:10; /* SCSI Command Descriptor Block Length */ - - memcpy(ccb.cdb, cmd, ccb.cdblen); - ccb.op = 0; /* SCSI Initiator Command */ - ccb.idlun = (target&7)<<5; /* SCSI Target Id */ - ccb.rsalen = 12; - any2scsi(ccb.datalen, bufflen); - any2scsi(ccb.dataptr, buff); - ccb.linkptr[0] = ccb.linkptr[1] = ccb.linkptr[2] = 0; - ccb.commlinkid = 0; - - mb[0].status = 1; - mb[1].status = 0; - -#ifdef DEBUGd - printk("aha1542_command: sending.. "); - for (i = 0; i < sizeof(ccb)-10; i++) - printk("%02x ", ((unchar *)&ccb)[i]); -#endif - - if (done) { - DEB(printk("aha1542_queuecommand: now waiting for interrupt "); aha1542_stat()); - if (do_done) - printk("aha1542_queuecommand: Two concurrent queuecommand?\n"); - else - do_done = done; - aha1542_out(&ahacmd, 1); /* start scsi command */ - DEB(aha1542_stat()); - aha1542_enable_intr(); - } - else - printk("aha1542_queuecommand: done can't be NULL\n"); - - return 0; -} - -volatile static int internal_done_flag = 0; -volatile static int internal_done_errcode = 0; -static void internal_done(int errcode) -{ - internal_done_errcode = errcode; - ++internal_done_flag; -} - -int aha1542_command(unchar target, const void *cmnd, void *buff, int bufflen) -{ - DEB(printk("aha1542_command: ..calling aha1542_queuecommand\n")); - aha1542_queuecommand(target, cmnd, buff, bufflen, internal_done); - - while (!internal_done_flag); - internal_done_flag = 0; - return internal_done_errcode; -} - -/* Initialize mailboxes */ -static void setup_mailboxes() -{ - static unchar cmd[5] = {CMD_MBINIT, 1}; - - mb[0].status = mb[1].status = 0; - aha1542_intr_reset(); /* reset interrupts, so they don't block */ - any2scsi((cmd+2), mb); - any2scsi(mb[0].ccbptr, &ccb); - aha1542_out(cmd, 5); - WAIT(INTRFLAGS, INTRMASK, HACC, 0); - while (0) { - fail: - printk("aha1542_detect: failed setting up mailboxes\n"); - } - aha1542_intr_reset(); -} - -/* a hack to avoid a strange compilation error */ - -void call_buh() -{ - struct sigaction sa; - - sa.sa_handler = aha1542_interrupt; - sa.sa_flags = SA_INTERRUPT; - sa.sa_mask = 0; - sa.sa_restorer = NULL; - if (irqaction(intr_chan,&sa)) - printk("Unable to allocate IRQ%d for aha controller\n", intr_chan); -} - -/* return non-zero on detection */ -int aha1542_detect(int hostnum) /* hostnum ignored for now */ -{ - int i; - - DEB(printk("aha1542_detect: \n")); - - if (!(i = aha1542_test_port())) { - return 0; - } - - /* Set the Bus on/off-times as not to ruin floppy performens */ - { - static unchar oncmd[] = {CMD_BUSON_TIME, 5}; - static unchar offcmd[] = {CMD_BUSOFF_TIME, 9}; - - aha1542_intr_reset(); - aha1542_out(oncmd, 2); - WAIT(INTRFLAGS, INTRMASK, HACC, 0); - aha1542_intr_reset(); - aha1542_out(offcmd, 2); - WAIT(INTRFLAGS, INTRMASK, HACC, 0); - while (0) { - fail: - printk("aha1542_detect: setting bus on/off-time failed\n"); - } - aha1542_intr_reset(); - } - - aha1542_stat(); - setup_mailboxes(); - - aha1542_stat(); - - DEB(printk("aha1542_detect: enable interrupt channel %d\n", intr_chan)); - call_buh(); - - if (intr_chan >= 8) - outb(inb_p(0x21)&0xfb,0x21); /* open for slave ?? */ - - DEB(printk("aha1542_detect: enabling interrupts\n")); - aha1542_enable_intr(); - -#ifdef DEBUG - DEB(printk(" *** READ CAPACITY ***\n")); - - { - unchar buf[8]; - static unchar cmd[] = { READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int i; - - for (i = 0; i < sizeof(buf); ++i) buf[i] = 0x87; - for (i = 0; i < 2; ++i) - if (!aha1542_command(i, cmd, buf, sizeof(buf))) { - printk("aha_detect: LU %d sector_size %d device_size %d\n", - i, xscsi2int(buf+4), xscsi2int(buf)); - } - } - - DEB(printk(" *** NOW RUNNING MY OWN TEST *** \n")); - - for (i = 0; i < 4; ++i) - { - unsigned char cmd[10]; - static buffer[512]; - - cmd[0] = READ_10; - cmd[1] = 0; - xany2scsi(cmd+2, i); - cmd[6] = 0; - cmd[7] = 0; - cmd[8] = 1; - cmd[9] = 0; - aha1542_command(0, cmd, buffer, 512); - } -#endif - return 1; -} - -int aha1542_abort(int i) -{ - DEB(printk("aha1542_abort\n")); - return 0; -} - -int aha1542_reset(void) -{ - DEB(printk("aha1542_reset called\n")); - return 0; -} diff --git a/kernel/blk_drv/scsi/aha1542.h b/kernel/blk_drv/scsi/aha1542.h deleted file mode 100644 index 47848d8fe958..000000000000 --- a/kernel/blk_drv/scsi/aha1542.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef _AHA1542_H - -/* $Id: aha1542.h,v 1.1 1992/04/24 18:01:50 root Exp root $ - * - * Header file for the adaptec 1542 driver for Linux - * - * $Log: aha1542.h,v $ - * Revision 1.1 1992/04/24 18:01:50 root - * Initial revision - * - * Revision 1.1 1992/04/02 03:23:13 drew - * Initial revision - * - * Revision 1.3 1992/01/27 14:46:29 tthorn - * *** empty log message *** - * - */ - -/* I/O Port interface 4.2 */ -/* READ */ -#define STATUS base -#define STST 0x80 /* Self Test in Progress */ -#define DIAGF 0x40 /* Internal Diagonostic Failure */ -#define INIT 0x20 /* Mailbox Initialization Required */ -#define IDLE 0x10 /* SCSI Host Adapter Idle */ -#define CDF 0x08 /* Command/Data Out Port Full */ -#define DF 0x04 /* Data In Port Full */ -#define INVDCMD 0x01 /* Invalid H A Command */ -#define STATMASK 0xfd /* 0x02 is reserved */ - -#define INTRFLAGS STATUS+2 -#define ANYINTR 0x80 /* Any Interrupt */ -#define SCRD 0x08 /* SCSI Reset Detected */ -#define HACC 0x04 /* HA Command Complete */ -#define MBOA 0x02 /* MBO Empty */ -#define MBIF 0x01 /* MBI Full */ -#define INTRMASK 0x8f - -/* WRITE */ -#define CONTROL STATUS -#define HRST 0x80 /* Hard Reset */ -#define SRST 0x40 /* Soft Reset */ -#define IRST 0x20 /* Interrupt Reset */ -#define SCRST 0x10 /* SCSI Bus Reset */ - -/* READ/WRITE */ -#define DATA STATUS+1 -#define CMD_NOP 0x00 /* No Operation */ -#define CMD_MBINIT 0x01 /* Mailbox Initialization */ -#define CMD_START_SCSI 0x02 /* Start SCSI Command */ -#define CMD_INQUIRY 0x04 /* Adapter Inquiry */ -#define CMD_EMBOI 0x05 /* Enable MailBox Out Interrupt */ -#define CMD_BUSON_TIME 0x07 /* Set Bus-On Time */ -#define CMD_BUSOFF_TIME 0x08 /* Set Bus-Off Time */ -#define CMD_RETDEVS 0x0a /* Return Installed Devices */ -#define CMD_RETCONF 0x0b /* Return Configuration Data */ -#define CMD_RETSETUP 0x0d /* Return Setup Data */ -#define CMD_ECHO 0x1f /* ECHO Command Data */ - -/* Mailbox Definition 5.2.1 and 5.2.2 */ -struct mailbox { - unchar status; /* Command/Status */ - unchar ccbptr[3]; /* msb, .., lsb */ -}; - -/* These belong in scsi.h also */ -#define any2scsi(up, p) \ -(up)[0] = (((long)(p)) >> 16) & 0xff; \ -(up)[1] = ((long)(p)) >> 8; \ -(up)[2] = ((long)(p)); - -#define scsi2int(up) ( (((long)*(up)) << 16) + (((long)(up)[1]) << 8) + ((long)(up)[2]) ) - -#define xany2scsi(up, p) \ -(up)[0] = ((long)(p)) >> 24; \ -(up)[1] = ((long)(p)) >> 16; \ -(up)[2] = ((long)(p)) >> 8; \ -(up)[3] = ((long)(p)); - -#define xscsi2int(up) ( (((long)(up)[0]) << 24) + (((long)(up)[1]) << 16) \ - + (((long)(up)[2]) << 8) + ((long)(up)[3]) ) - -#define MAX_CDB 12 -#define MAX_SENSE 14 - -struct ccb { /* Command Control Block 5.3 */ - unchar op; /* Command Control Block Operation Code */ - unchar idlun; /* op=0,2:Target Id, op=1:Initiator Id */ - /* Outbound data transfer, length is checked*/ - /* Inbound data transfer, length is checked */ - /* Logical Unit Number */ - unchar cdblen; /* SCSI Command Length */ - unchar rsalen; /* Request Sense Allocation Length/Disable */ - unchar datalen[3]; /* Data Length (msb, .., lsb) */ - unchar dataptr[3]; /* Data Pointer */ - unchar linkptr[3]; /* Link Pointer */ - unchar commlinkid; /* Command Linking Identifier */ - unchar hastat; /* Host Adapter Status (HASTAT) */ - unchar tarstat; /* Target Device Status */ - unchar reserved[2]; - unchar cdb[MAX_CDB+MAX_SENSE];/* SCSI Command Descriptor Block */ - /* REQUEST SENSE */ -}; - -int aha1542_detect(int); -int aha1542_command(unsigned char target, const void *cmnd, void *buff, int bufflen); -/*int aha1542_queuecommand(unchar target, const void *cmnd, void *buff, int bufflen, void (*done)(int));*/ -int aha1542_abort(int); -char *aha1542_info(void); -int aha1542_reset(void); - -#ifndef NULL - #define NULL 0 -#endif - -#define AHA1542 {"Adaptec 1542", aha1542_detect, \ - aha1542_info, aha1542_command, \ - /*aha1542_queuecommand*/ NULL, \ - aha1542_abort, \ - aha1542_reset, \ - 0, 7, 0} -#endif diff --git a/kernel/blk_drv/scsi/config.in b/kernel/blk_drv/scsi/config.in deleted file mode 100644 index 75c1fde7e681..000000000000 --- a/kernel/blk_drv/scsi/config.in +++ /dev/null @@ -1,29 +0,0 @@ -#include - -#ifdef CONFIG_SCSI -scsi.o -hosts.o -scsi_ioctl.o -#endif - -#ifdef CONFIG_BLK_DEV_SD -sd.o -sd_ioctl.o -#endif - -#ifdef CONFIG_BLK_DEV_ST -st.o -st_ioctl.o -#endif - -#ifdef CONFIG_SCSI_AHA1542 -aha1542.o -#endif - -#ifdef CONFIG_SCSI_SEAGATE -seagate.o -#endif - -#ifdef CONFIG_SCSI_ULTRASTOR -ultrastor.o -#endif diff --git a/kernel/blk_drv/scsi/hosts.c b/kernel/blk_drv/scsi/hosts.c deleted file mode 100644 index 268bc71f9c38..000000000000 --- a/kernel/blk_drv/scsi/hosts.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * hosts.c Copyright (C) 1992 Drew Eckhardt - * mid to lowlevel SCSI driver interface by - * Drew Eckhardt - * - * - */ - - -/* - This file contains the medium level SCSI - host interface initialization, as well as the scsi_hosts array of SCSI - hosts currently present in the system. -*/ - -#include - -#ifdef CONFIG_SCSI -#include -#include "scsi.h" - -#ifndef NULL - #define NULL 0L -#endif - -#ifdef FIGURE_MAX_SCSI_HOSTS - #define MAX_SCSI_HOSTS -#endif - -#include "hosts.h" - -#ifdef CONFIG_SCSI_AHA1542 -#include -#include "aha1542.h" -#endif - -#ifdef CONFIG_SCSI_SEAGATE -#include "seagate.h" -#endif - -#ifdef CONFIG_SCSI_ULTRASTOR -#include "ultrastor.h" -#endif - -/* -static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/hosts.c,v 1.1 1992/04/24 18:01:50 root Exp root $"; -*/ - -/* - The scsi host entries should be in the order you wish the - cards to be detected. A driver may appear more than once IFF - it can deal with being detected (and therefore initialized) - with more than one simulatenous host number, can handle being - rentrant, etc. - - They may appear in any order, as each SCSI host is told which host number it is - during detection. -*/ - -/* - When figure is run, we don't want to link to any object code. Since - the macro for each host will contain function pointers, we cannot - use it and instead must use a "blank" that does no such - idiocy. -*/ - -#ifdef FIGURE_MAX_SCSI_HOSTS - #define BLANKIFY(what) BLANK_HOST -#else - #define BLANKIFY(what) what -#endif - -Scsi_Host scsi_hosts[] = - { -#ifdef CONFIG_SCSI_AHA1542 - BLANKIFY(AHA1542), -#endif - -#ifdef CONFIG_SCSI_SEAGATE - BLANKIFY(SEAGATE_ST0X), -#endif -#ifdef CONFIG_SCSI_ULTRASTOR - BLANKIFY(ULTRASTOR_14F), -#endif - }; - -#ifdef FIGURE_MAX_SCSI_HOSTS - #undef MAX_SCSI_HOSTS - #define MAX_SCSI_HOSTS (sizeof(scsi_hosts) / sizeof(Scsi_Host)) -#endif - -#ifdef FIGURE_MAX_SCSI_HOSTS -#include -void main (void) -{ - printf("%d", MAX_SCSI_HOSTS); -} -#else -/* - Our semaphores and timeout counters, where size depends on MAX_SCSI_HOSTS here. -*/ - -volatile unsigned char host_busy[MAX_SCSI_HOSTS]; -volatile int host_timeout[MAX_SCSI_HOSTS]; -volatile Scsi_Cmnd *host_queue[MAX_SCSI_HOSTS]; -/* - scsi_init initializes the scsi hosts. -*/ - -void scsi_init(void) - { - static int called = 0; - int i, count; - if (!called) - { - called = 1; - for (count = i = 0; i < MAX_SCSI_HOSTS; ++i) - { - /* - Initialize our semaphores. -1 is interpreted to mean - "inactive" - where as 0 will indicate a time out condition. - */ - - host_busy[i] = 0; - host_timeout[i] = 0; - host_queue[i] = NULL; - - if ((scsi_hosts[i].detect) && (scsi_hosts[i].present = scsi_hosts[i].detect(i))) - { - printk ("Host %d is detected as a(n) %s.\n\r", - count, scsi_hosts[i].name); - printk ("%s", scsi_hosts[i].info()); - ++count; - } - } - printk ("%d host adapters detected. \n\r", count); - } - - } - -#endif - -#endif diff --git a/kernel/blk_drv/scsi/hosts.h b/kernel/blk_drv/scsi/hosts.h deleted file mode 100644 index 468a044392b9..000000000000 --- a/kernel/blk_drv/scsi/hosts.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * hosts.h Copyright (C) 1992 Drew Eckhardt - * mid to low-level SCSI driver interface header by - * Drew Eckhardt - * - * - */ - -#ifndef _HOSTS_H - #define _HOSTS_H - -#ifndef MAX_SCSI_HOSTS - #include "max_hosts.h" -#endif - -/* - $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/hosts.h,v 1.1 1992/04/24 18:01:50 root Exp root $ -*/ - -/* - The Scsi_Cmnd structure is used by scsi.c internally, and for communication with - low level drivers that support multiple outstanding commands. -*/ - -typedef struct scsi_cmnd { - int host; - unsigned char target, lun; - unsigned char cmnd[10]; - unsigned bufflen; - void *buffer; - - unsigned char sense_cmnd[6]; - unsigned char *sense_buffer; - - unsigned flags; - - int retries; - int allowed; - int timeout_per_command, timeout_total, timeout; - - void (*done)(int,int); - struct scsi_cmnd *next, *prev; - } Scsi_Cmnd; - -/* - The Scsi_Host type has all that is needed to interface with a SCSI - host in a device independant matter. -*/ - -typedef struct - { - /* - The name pointer is a pointer to the name of the SCSI - device detected. - */ - - char *name; - - /* - The detect function shall return non zero on detection, - and initialize all data necessary for this particular - SCSI driver. It is passed the host number, so this host - knows where it is in the hosts array - */ - - int (* detect)(int); - - /* - The info function will return whatever useful - information the developer sees fit. - */ - - char *(* info)(void); - - /* - The command function takes a target, a command (this is a SCSI - command formatted as per the SCSI spec, nothing strange), a - data buffer pointer, and data buffer length pointer. The return - is a status int, bit fielded as follows : - Byte What - 0 SCSI status code - 1 SCSI 1 byte message - 2 host error return. - 3 mid level error return - */ - - int (* command)(unsigned char target, const void *cmnd, - void *buff, int bufflen); - - /* - The QueueCommand function works in a similar manner - to the command function. It takes an additional parameter, - void (* done)(int host, int code) which is passed the host - # and exit result when the command is complete. - Host number is the POSITION IN THE hosts array of THIS - host adapter. - */ - - int (* queuecommand)(unsigned char target, const void *cmnd, - void *buff, int bufflen, void (*done)(int,int)); - - - /* - Since the mid level driver handles time outs, etc, we want to - be able to abort the current command. Abort returns 0 if the - abortion was successful. If non-zero, the code passed to it - will be used as the return code, otherwise - DID_ABORT should be returned. - - Note that the scsi driver should "clean up" after itself, - resetting the bus, etc. if necessary. - */ - - int (* abort)(int); - - /* - The reset function will reset the SCSI bus. Any executing - commands should fail with a DID_RESET in the host byte. - */ - - int (* reset)(void); - - /* - This determines if we will use a non-interrupt driven - or an interrupt driven scheme, It is set to the maximum number - of simulataneous commands a given host adapter will accept. - */ - - int can_queue; - - /* - In many instances, especially where disconnect / reconnect are - supported, our host also has an ID on the SCSI bus. If this is - the case, then it must be reserved. Please set this_id to -1 if your settup is in single initiator mode, and the host lacks an - ID. - */ - - int this_id; - - /* - present contains a flag as to weather we are present - - so we don't have to call detect multiple times. - */ - - unsigned present:1; - } Scsi_Host; - -/* - The scsi_hosts array is the array containing the data for all - possible scsi hosts. -*/ - -extern Scsi_Host scsi_hosts[]; - -/* - This is our semaphore array, used by scsi.c, sd.c, st.c. - Other routines SHOULD NOT mess with it. Your driver should NOT mess with it. - This is used to protect against contention by disk and tape drivers. -*/ - -extern volatile unsigned char host_busy[]; -extern volatile int host_timeout[]; - -/* - This is the queue of currently pending commands for a given - SCSI host. -*/ - -extern volatile Scsi_Cmnd *host_queue[]; - -/* - scsi_init initializes the scsi hosts. -*/ - - -void scsi_init(void); - -#define BLANK_HOST {"", 0, 0, 0, 0, 0, 0, 0, 0, 0} -#endif diff --git a/kernel/blk_drv/scsi/scsi.c b/kernel/blk_drv/scsi/scsi.c deleted file mode 100644 index 22f340232fa0..000000000000 --- a/kernel/blk_drv/scsi/scsi.c +++ /dev/null @@ -1,1016 +0,0 @@ -/* - * scsi.c Copyright (C) 1992 Drew Eckhardt - * generic mid-level SCSI driver by - * Drew Eckhardt - * - * - */ -#include - -#ifdef CONFIG_SCSI -#include -#include -#include -#include - -#include "scsi.h" -#include "hosts.h" - -#ifdef CONFIG_BLK_DEV_SD -#include "sd.h" -#endif - -#ifdef CONFIG_BLK_DEV_ST -#include "st.h" -#endif - -/* -static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.c,v 1.1 1992/04/24 18:01:50 root Exp root $"; -*/ - -#define INTERNAL_ERROR (printk ("Internal error in file %s, line %s.\n", __FILE__, __LINE__), panic("")) - -static void scsi_done (int host, int result); -static void update_timeout (void); - -static int time_start; -static int time_elapsed; - -/* - global variables : - NR_SCSI_DEVICES is the number of SCSI devices we have detected, - scsi_devices an array of these specifing the address for each - (host, id, LUN) -*/ - -int NR_SCSI_DEVICES=0; -Scsi_Device scsi_devices[MAX_SCSI_DEVICE]; - -#define SENSE_LENGTH 255 -/* - As the scsi do command functions are inteligent, and may need to - redo a command, we need to keep track of the last command - executed on each one. -*/ - -#define WAS_RESET 0x01 -#define WAS_TIMEDOUT 0x02 -#define WAS_SENSE 0x04 -#define IS_RESETTING 0x08 - -static Scsi_Cmnd last_cmnd[MAX_SCSI_HOSTS]; -static int last_reset[MAX_SCSI_HOSTS]; - -/* - This is the number of clock ticks we should wait before we time out - and abort the command. This is for where the scsi.c module generates - the command, not where it originates from a higher level, in which - case the timeout is specified there. - - - ABORT_TIMEOUT and RESET_TIMEOUT are the timeouts for RESET and ABORT - respectively. -*/ -#ifdef DEBUG - #define SCSI_TIMEOUT 500 -#else - #define SCSI_TIMEOUT 100 -#endif -#ifdef DEBUG - #define SENSE_TIMEOUT SCSI_TIMEOUT - #define ABORT_TIMEOUT SCSI_TIMEOUT - #define RESET_TIMEOUT SCSI_TIMEOUT -#else - - #define SENSE_TIMEOUT 50 - #define RESET_TIMEOUT 50 - #define ABORT_TIMEOUT 50 - #define MIN_RESET_DELAY 25 - -#endif -/* - As the actual SCSI command runs in the background, we must set up a - flag that tells scan_scsis() when the result it has is valid. - scan_scsis can set the_result to -1, and watch for it to become the - actual return code for that call. the scan_scsis_done function() is - our user specified completion function that is passed on to the - scsi_do_cmd() function. -*/ - -static int the_result; -static unsigned char sense_buffer[SENSE_LENGTH]; -static void scan_scsis_done (int host, int result) - { - -#ifdef DEBUG - printk ("scan_scsis_done(%d, %06x\n\r", host, result); -#endif - the_result = result; - } -/* - Detecting SCSI devices : - We scan all present host adapter's busses, from ID 0 to ID 6. - We use the INQUIRY command, determine device type, and pass the ID / - lun address of all sequential devices to the tape driver, all random - devices to the disk driver. -*/ - -static void scan_scsis (void) - { - int host_nr , dev, lun, type, maxed; - static unsigned char scsi_cmd [12]; - static unsigned char scsi_result [256]; - - for (host_nr = 0; host_nr < MAX_SCSI_HOSTS; ++host_nr) - if (scsi_hosts[host_nr].present) - { - for (dev = 0; dev < 7; ++dev) - if (scsi_hosts[host_nr].this_id != dev) - #ifdef MULTI_LUN - for (lun = 0; lun < 8; ++lun) - { - #else - { - lun = 0; - #endif - /* Build an INQUIRY command block. */ - - scsi_cmd[0] = INQUIRY; - scsi_cmd[1] = (lun << 5) & 0xe0; - scsi_cmd[2] = 0; - scsi_cmd[3] = 0; - scsi_cmd[4] = 255; - scsi_cmd[5] = 0; - the_result = -1; -#ifdef DEBUG - memset ((void *) scsi_result , 0, 255); -#endif - scsi_do_cmd (host_nr, dev, (void *) scsi_cmd, (void *) - scsi_result, 256, scan_scsis_done, - SCSI_TIMEOUT, sense_buffer, 3); - - /* Wait for valid result */ - - while (the_result < 0); - - - if (!the_result) - { - scsi_devices[NR_SCSI_DEVICES]. - host_no = host_nr; - scsi_devices[NR_SCSI_DEVICES]. - id = dev; - scsi_devices[NR_SCSI_DEVICES]. - lun = lun; - scsi_devices[NR_SCSI_DEVICES]. - removable = (0x80 & - scsi_result[1]) >> 7; - - - -/* - Currently, all sequential devices are assumed to be tapes, - all random devices disk, with the appropriate read only - flags set for ROM / WORM treated as RO. -*/ - - switch (type = scsi_result[0]) - { - case TYPE_TAPE: - case TYPE_DISK: - scsi_devices[NR_SCSI_DEVICES].writeable = 1; - break; - case TYPE_WORM: - case TYPE_ROM: - scsi_devices[NR_SCSI_DEVICES].writeable = 0; - break; - default: - type = -1; - } - - scsi_devices[NR_SCSI_DEVICES].random = (type == TYPE_TAPE) ? 0 : 1; - - maxed = 0; - switch (type) - { - case -1: - break; - case TYPE_TAPE: - printk("Detected scsi tape at host %d, ID %d, lun %d \n", host_nr, dev, lun); -#ifdef CONFIG_BLK_DEV_ST - if (!(maxed = (NR_ST == MAX_ST))) - scsi_tapes[NR_ST].device = &scsi_devices[NR_SCSI_DEVICES]; -#endif - default: - printk("Detected scsi disk at host %d, ID %d, lun %d \n", host_nr, dev, lun); -#ifdef CONFIG_BLK_DEV_SD - if (!(maxed = (NR_SD >= MAX_SD))) - rscsi_disks[NR_SD].device = &scsi_devices[NR_SCSI_DEVICES]; -#endif - } - - if (maxed) - { - printk ("Already have detected maximum number of SCSI %ss Unable to \n" - "add drive at SCSI host %s, ID %d, LUN %d\n\r", (type == TYPE_TAPE) ? - "tape" : "disk", scsi_hosts[host_nr].name, - dev, lun); - type = -1; - break; - } - - else if (type != -1) - { - if (type == TYPE_TAPE) -#ifdef CONFIG_BLK_DEV_ST - ++NR_ST; -#else -; -#endif - - else -#ifdef CONFIG_BLK_DEV_SD - ++NR_SD; -#else -; -#endif - } - ++NR_SCSI_DEVICES; - } /* if result == DID_OK ends */ - } /* for lun ends */ - } /* if present */ - - printk("Detected " -#ifdef CONFIG_BLK_DEV_SD -"%d disk%s " -#endif - -#ifdef CONFIG_BLK_DEV_ST -"%d tape%s " -#endif - -"total.\n", - -#ifdef CONFIG_BLK_DEV_SD -NR_SD, (NR_SD != 1) ? "s" : "" -#ifdef CONFIG_BLK_DEV_ST -, -#endif -#endif - -#ifdef CONFIG_BLK_DEV_ST -NR_ST, (NR_ST != 1) ? "s" : "" -#endif -); - } /* scan_scsis ends */ - -/* - We handle the timeout differently if it happens when a reset, - abort, etc are in process. -*/ - -static unsigned char internal_timeout[MAX_SCSI_HOSTS]; - -/* Flag bits for the internal_timeout array */ - -#define NORMAL_TIMEOUT 0 -#define IN_ABORT 1 -#define IN_RESET 2 -/* - This is our time out function, called when the timer expires for a - given host adapter. It will attempt to abort the currently executing - command, that failing perform a kernel panic. -*/ - -static void scsi_times_out (int host) - { - - switch (internal_timeout[host] & (IN_ABORT | IN_RESET)) - { - case NORMAL_TIMEOUT: - printk("SCSI host %d timed out - aborting command \r\n", - host); - - if (!scsi_abort (host, DID_TIME_OUT)) - return; - case IN_ABORT: - printk("SCSI host %d abort() timed out - reseting \r\n", - host); - if (!scsi_reset (host)) - return; - case IN_RESET: - case (IN_ABORT | IN_RESET): - printk("Unable to reset scsi host %d\r\n",host); - panic(""); - default: - INTERNAL_ERROR; - } - - } - -/* - This is inline because we have stack problemes if we recurse to deeply. -*/ - -static void internal_cmnd (int host, unsigned char target, const void *cmnd , - void *buffer, unsigned bufflen, void (*done)(int,int)) - { - int temp; - -#ifdef DEBUG_DELAY - int clock; -#endif - - if ((host < 0) || (host > MAX_SCSI_HOSTS)) - panic ("Host number in internal_cmnd() is out of range.\n"); - - -/* - We will wait MIN_RESET_DELAY clock ticks after the last reset so - we can avoid the drive not being ready. -*/ -temp = last_reset[host]; -while (jiffies < temp); - -host_timeout[host] = last_cmnd[host].timeout_per_command; -update_timeout(); - -/* - We will use a queued command if possible, otherwise we will emulate the - queing and calling of completion function ourselves. -*/ -#ifdef DEBUG - printk("internal_cmnd (host = %d, target = %d, command = %08x, buffer = %08x, \n" - "bufflen = %d, done = %08x)\n", host, target, cmnd, buffer, bufflen, done); -#endif - - - if (scsi_hosts[host].can_queue) - { -#ifdef DEBUG - printk("queuecommand : routine at %08x\n", - scsi_hosts[host].queuecommand); -#endif - scsi_hosts[host].queuecommand (target, cmnd, buffer, bufflen, - done); - } - else - { - -#ifdef DEBUG - printk("command() : routine at %08x\n", scsi_hosts[host].command); -#endif - temp=scsi_hosts[host].command (target, cmnd, buffer, bufflen); - -#ifdef DEBUG_DELAY - clock = jiffies + 400; - while (jiffies < clock); - printk("done(host = %d, result = %04x) : routine at %08x\n", host, temp, done); -#endif - done(host, temp); - } -#ifdef DEBUG - printk("leaving internal_cmnd()\n"); -#endif - } - -static void scsi_request_sense (int host, unsigned char target, - unsigned char lun) - { - cli(); - host_timeout[host] = SENSE_TIMEOUT; - update_timeout(); - last_cmnd[host].flags |= WAS_SENSE; - sti(); - - last_cmnd[host].sense_cmnd[1] = lun << 5; - - internal_cmnd (host, target, (void *) last_cmnd[host].sense_cmnd, - (void *) last_cmnd[host].sense_buffer, SENSE_LENGTH, - scsi_done); - } - - - - - -/* - scsi_do_cmd sends all the commands out to the low-level driver. It - handles the specifics required for each low level driver - ie queued - or non queud. It also prevents conflicts when different high level - drivers go for the same host at the same time. -*/ - -void scsi_do_cmd (int host, unsigned char target, const void *cmnd , - void *buffer, unsigned bufflen, void (*done)(int,int), - int timeout, unsigned char *sense_buffer, int retries - ) - { - int ok = 0; - -#ifdef DEBUG - int i; - printk ("scsi_do_cmd (host = %d, target = %d, buffer =%08x, " - "bufflen = %d, done = %08x, timeout = %d, retries = %d)\n" - "command : " , host, target, buffer, bufflen, done, timeout, retries); - for (i = 0; i < 10; ++i) - printk ("%02x ", ((unsigned char *) cmnd)[i]); - printk("\n"); -#endif - - if ((host >= MAX_SCSI_HOSTS) || !scsi_hosts[host].present) - { - printk ("Invalid or not present host number. %d\n", host); - panic(""); - } - - -/* - We must prevent reentrancy to the lowlevel host driver. This prevents - it - we enter a loop until the host we want to talk to is not busy. - Race conditions are prevented, as interrupts are disabled inbetween the - time we check for the host being not busy, and the time we mark it busy - ourselves. -*/ - - do { - cli(); - if (host_busy[host]) - { - sti(); -#ifdef DEBUG - printk("Host %d is busy.\n" ); -#endif - while (host_busy[host]); -#ifdef DEBUG - printk("Host %d is no longer busy."); -#endif - } - else - { - host_busy[host] = 1; - ok = 1; - sti(); - } - } while (!ok); - - -/* - Our own function scsi_done (which marks the host as not busy, disables - the timeout counter, etc) will be called by us or by the - scsi_hosts[host].queuecommand() function needs to also call - the completion function for the high level driver. - -*/ - - memcpy ((void *) last_cmnd[host].cmnd , (void *) cmnd, 10); - last_cmnd[host].host = host; - last_cmnd[host].target = target; - last_cmnd[host].lun = (last_cmnd[host].cmnd[1] >> 5); - last_cmnd[host].bufflen = bufflen; - last_cmnd[host].buffer = buffer; - last_cmnd[host].sense_buffer = sense_buffer; - last_cmnd[host].flags=0; - last_cmnd[host].retries=0; - last_cmnd[host].allowed=retries; - last_cmnd[host].done = done; - last_cmnd[host].timeout_per_command = timeout; - - /* Start the timer ticking. */ - - internal_timeout[host] = 0; - internal_cmnd (host, target, cmnd , buffer, bufflen, scsi_done); - -#ifdef DEBUG - printk ("Leaving scsi_do_cmd()\n"); -#endif - } - - -/* - The scsi_done() function disables the timeout timer for the scsi host, - marks the host as not busy, and calls the user specified completion - function for that host's current command. -*/ - -static void reset (int host) - { - #ifdef DEBUG - printk("reset(%d)\n", host); - #endif - - last_cmnd[host].flags |= (WAS_RESET | IS_RESETTING); - scsi_reset(host); - - #ifdef DEBUG - printk("performing request sense\n"); - #endif - - scsi_request_sense (host, last_cmnd[host].target, last_cmnd[host].lun); - } - - - -static int check_sense (int host) - { - if (((sense_buffer[0] & 0x70) >> 4) == 7) - switch (sense_buffer[2] & 0xf) - { - case NO_SENSE: - case RECOVERED_ERROR: - return 0; - - case ABORTED_COMMAND: - case NOT_READY: - case UNIT_ATTENTION: - return SUGGEST_RETRY; - - /* these three are not supported */ - case COPY_ABORTED: - case VOLUME_OVERFLOW: - case MISCOMPARE: - - case MEDIUM_ERROR: - return SUGGEST_REMAP; - case BLANK_CHECK: - case DATA_PROTECT: - case HARDWARE_ERROR: - case ILLEGAL_REQUEST: - default: - return SUGGEST_ABORT; - } - else - return SUGGEST_RETRY; - } - -static void scsi_done (int host, int result) - { - int status=0; - int exit=0; - int checked; - int oldto; - oldto = host_timeout[host]; - host_timeout[host] = 0; - update_timeout(); - -#define FINISHED 0 -#define MAYREDO 1 -#define REDO 3 - -#ifdef DEBUG - printk("In scsi_done(host = %d, result = %06x)\n", host, result); -#endif - if (host > MAX_SCSI_HOSTS || host < 0) - { - host_timeout[host] = 0; - update_timeout(); - panic("scsi_done() called with invalid host number.\n"); - } - - switch (host_byte(result)) - { - case DID_OK: - if (last_cmnd[host].flags & IS_RESETTING) - { - last_cmnd[host].flags &= ~IS_RESETTING; - status = REDO; - break; - } - - if (status_byte(result) && (last_cmnd[host].flags & - WAS_SENSE)) - { - last_cmnd[host].flags &= ~WAS_SENSE; - cli(); - internal_timeout[host] &= ~SENSE_TIMEOUT; - sti(); - - if (!(last_cmnd[host].flags & WAS_RESET)) - reset(host); - else - { - exit = (DRIVER_HARD | SUGGEST_ABORT); - status = FINISHED; - } - } - else switch(msg_byte(result)) - { - case COMMAND_COMPLETE: - switch (status_byte(result)) - { - case GOOD: - if (last_cmnd[host].flags & WAS_SENSE) - { -#ifdef DEBUG - printk ("In scsi_done, GOOD status, COMMAND COMPLETE, parsing sense information.\n"); -#endif - - last_cmnd[host].flags &= ~WAS_SENSE; - cli(); - internal_timeout[host] &= ~SENSE_TIMEOUT; - sti(); - - switch (checked = check_sense(host)) - { - case 0: -#ifdef DEBUG - printk("NO SENSE. status = REDO\n"); -#endif - - host_timeout[host] = oldto; - update_timeout(); - status = REDO; - break; - case SUGGEST_REMAP: - case SUGGEST_RETRY: -#ifdef DEBUG - printk("SENSE SUGGEST REMAP or SUGGEST RETRY - status = MAYREDO\n"); -#endif - - status = MAYREDO; - exit = SUGGEST_RETRY; - break; - case SUGGEST_ABORT: -#ifdef DEBUG - printk("SENSE SUGGEST ABORT - status = FINISHED"); -#endif - - status = FINISHED; - exit = DRIVER_SENSE; - break; - default: - printk ("Internal error %s %s \n", __FILE__, - __LINE__); - } - } - else - { -#ifdef DEBUG - printk("COMMAND COMPLETE message returned, status = FINISHED. \n"); -#endif - - exit = DRIVER_OK; - status = FINISHED; - } - break; - - case CHECK_CONDITION: - -#ifdef DEBUG - printk("CHECK CONDITION message returned, performing request sense.\n"); -#endif - - scsi_request_sense (host, last_cmnd[host].target, last_cmnd[host].lun); - break; - - case CONDITION_GOOD: - case INTERMEDIATE_GOOD: - case INTERMEDIATE_C_GOOD: -#ifdef DEBUG - printk("CONDITION GOOD, INTERMEDIATE GOOD, or INTERMEDIATE CONDITION GOOD recieved and ignored. \n"); -#endif - break; - - case BUSY: -#ifdef DEBUG - printk("BUSY message returned, performing REDO"); -#endif - host_timeout[host] = oldto; - update_timeout(); - status = REDO; - break; - - case RESERVATION_CONFLICT: - reset(host); - exit = DRIVER_SOFT | SUGGEST_ABORT; - status = MAYREDO; - break; - default: - printk ("Internal error %s %s \n" - "status byte = %d \n", __FILE__, - __LINE__, status_byte(result)); - - } - break; - default: - panic ("unsupported message byte recieved."); - } - break; - case DID_TIME_OUT: -#ifdef DEBUG - printk("Host returned DID_TIME_OUT - "); -#endif - - if (last_cmnd[host].flags & WAS_TIMEDOUT) - { -#ifdef DEBUG - printk("Aborting\n"); -#endif - exit = (DRIVER_TIMEOUT | SUGGEST_ABORT); - } - else - { -#ifdef DEBUG - printk ("Retrying.\n"); -#endif - last_cmnd[host].flags |= WAS_TIMEDOUT; - status = REDO; - } - break; - case DID_BUS_BUSY: - case DID_PARITY: - status = REDO; - break; - case DID_NO_CONNECT: -#ifdef DEBUG - printk("Couldn't connect.\n"); -#endif - exit = (DRIVER_HARD | SUGGEST_ABORT); - break; - case DID_ERROR: - status = MAYREDO; - exit = (DRIVER_HARD | SUGGEST_ABORT); - break; - case DID_BAD_TARGET: - case DID_ABORT: - exit = (DRIVER_INVALID | SUGGEST_ABORT); - break; - default : - exit = (DRIVER_ERROR | SUGGEST_DIE); - } - - switch (status) - { - case FINISHED: - break; - case MAYREDO: - -#ifdef DEBUG - printk("In MAYREDO, allowing %d retries, have %d\n\r", - last_cmnd[host].allowed, last_cmnd[host].retries); -#endif - - if ((++last_cmnd[host].retries) < last_cmnd[host].allowed) - { - if ((last_cmnd[host].retries >= (last_cmnd[host].allowed >> 1)) - && !(last_cmnd[host].flags & WAS_RESET)) - reset(host); - break; - - } - else - { - status = FINISHED; - break; - } - /* fall through to REDO */ - - case REDO: - if (last_cmnd[host].flags & WAS_SENSE) - scsi_request_sense (host, last_cmnd[host].target, - last_cmnd[host].lun); - else - internal_cmnd (host, last_cmnd[host].target, - last_cmnd[host].cmnd, - last_cmnd[host].buffer, - last_cmnd[host].bufflen, scsi_done); - break; - default: - INTERNAL_ERROR; - } - - if (status == FINISHED) - { - #ifdef DEBUG - printk("Calling done function - at address %08x\n", last_cmnd[host].done); - #endif - last_cmnd[host].done (host, (result | ((exit & 0xff) << 24))); - host_busy[host] = 0; - } - - -#undef FINISHED -#undef REDO -#undef MAYREDO - - } - -/* - The scsi_abort function interfaces with the abort() function of the host - we are aborting, and causes the current command to not complete. The - caller should deal with any error messages or status returned on the - next call. - - This will not be called rentrantly for a given host. -*/ - -/* - Since we're nice guys and specified that abort() and reset() - can be non-reentrant. The internal_timeout flags are used for - this. -*/ - - -int scsi_abort (int host, int why) - { - int temp, oldto; - - while(1) - { - cli(); - if (internal_timeout[host] & IN_ABORT) - { - sti(); - while (internal_timeout[host] & IN_ABORT); - } - else - { - internal_timeout[host] |= IN_ABORT; - host_timeout[host] = ABORT_TIMEOUT; - update_timeout(); - - oldto = host_timeout[host]; - - sti(); - if (!host_busy[host] || !scsi_hosts[host].abort(why)) - temp = 0; - else - temp = 1; - - cli(); - internal_timeout[host] &= ~IN_ABORT; - host_timeout[host]=oldto; - update_timeout(); - sti(); - return temp; - } - } - } - -int scsi_reset (int host) - { - int temp, oldto; - - while (1) { - cli(); - if (internal_timeout[host] & IN_RESET) - { - sti(); - while (internal_timeout[host] & IN_RESET); - } - else - { - oldto = host_timeout[host]; - host_timeout[host] = RESET_TIMEOUT; - update_timeout(); - internal_timeout[host] |= IN_RESET; - - if (host_busy[host]) - { - sti(); - if (!(last_cmnd[host].flags & IS_RESETTING) && !(internal_timeout[host] & IN_ABORT)) - scsi_abort(host, DID_RESET); - - temp = scsi_hosts[host].reset(); - } - else - { - host_busy[host]=1; - - sti(); - temp = scsi_hosts[host].reset(); - last_reset[host] = jiffies; - host_busy[host]=0; - } - - cli(); - host_timeout[host] = oldto; - update_timeout(); - internal_timeout[host] &= ~IN_RESET; - sti(); - return temp; - } - } - } - - -static void scsi_main_timeout(void) - { - /* - We must not enter update_timeout with a timeout condition still pending. - */ - - int i, timed_out; - - do { - cli(); - - /* - Find all timers such that they have 0 or negative (shouldn't happen) - time remaining on them. - */ - - for (i = timed_out = 0; i < MAX_SCSI_HOSTS; ++i) - if (host_timeout[i] != 0 && host_timeout[i] <= time_elapsed) - { - sti(); - host_timeout[i] = 0; - scsi_times_out(i); - ++timed_out; - } - - update_timeout(); - } while (timed_out); - sti(); - } - -/* - These are used to keep track of things. -*/ - -static int time_start, time_elapsed; - -/* - The strategy is to cause the timer code to call scsi_times_out() - when the soonest timeout is pending. -*/ - -static void update_timeout(void) - { - int i, least, used; - - cli(); - -/* - Figure out how much time has passed since the last time the timeouts - were updated -*/ - used = (time_start) ? (jiffies - time_start) : 0; - -/* - Find out what is due to timeout soonest, and adjust all timeouts for - the amount of time that has passed since the last time we called - update_timeout. -*/ - - for (i = 0, least = 0xffffffff; i < MAX_SCSI_HOSTS; ++i) - if (host_timeout[i] > 0 && (host_timeout[i] -= used) < least) - least = host_timeout[i]; - -/* - If something is due to timeout again, then we will set the next timeout - interrupt to occur. Otherwise, timeouts are disabled. -*/ - - if (least != 0xffffffff) - { - time_start = jiffies; - timer_table[SCSI_TIMER].expires = (time_elapsed = least) + jiffies; - timer_active |= 1 << SCSI_TIMER; - } - else - { - timer_table[SCSI_TIMER].expires = time_start = time_elapsed = 0; - timer_active &= ~(1 << SCSI_TIMER); - } - sti(); - } -/* - scsi_dev_init() is our initialization routine, which inturn calls host - initialization, bus scanning, and sd/st initialization routines. It - should be called from main(). -*/ - -static unsigned char generic_sense[6] = {REQUEST_SENSE, 0,0,0, 255, 0}; -void scsi_dev_init (void) - { - int i; -#ifdef FOO_ON_YOU - return; -#endif - timer_table[SCSI_TIMER].fn = scsi_main_timeout; - timer_table[SCSI_TIMER].expires = 0; - - scsi_init(); /* initialize all hosts */ - /* - Set up sense command in each host structure. - */ - - for (i = 0; i < MAX_SCSI_HOSTS; ++i) - { - memcpy ((void *) last_cmnd[i].sense_cmnd, (void *) generic_sense, - 6); - last_reset[i] = 0; - } - - scan_scsis(); /* scan for scsi devices */ - -#ifdef CONFIG_BLK_DEV_SD - sd_init(); /* init scsi disks */ -#endif - -#ifdef CONFIG_BLK_DEV_ST - st_init(); /* init scsi tapes */ -#endif - } -#endif diff --git a/kernel/blk_drv/scsi/scsi.h b/kernel/blk_drv/scsi/scsi.h deleted file mode 100644 index 1a949ab990ff..000000000000 --- a/kernel/blk_drv/scsi/scsi.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * scsi.h Copyright (C) 1992 Drew Eckhardt - * generic SCSI package header file by - * Drew Eckhardt - * - * - */ - -#ifndef _SCSI_H - #define _SCSI_H -/* - $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.h,v 1.1 1992/04/24 18:01:50 root Exp root $ - - For documentation on the OPCODES, MESSAGES, and SENSE values, - please consult the SCSI standard. - -*/ - -/* - SCSI opcodes -*/ - -#define TEST_UNIT_READY 0x00 -#define REZERO_UNIT 0x01 -#define REQUEST_SENSE 0x03 -#define FORMAT_UNIT 0x04 -#define REASSIGN_BLOCKS 0x07 -#define READ_6 0x08 -#define WRITE_6 0x0a -#define SEEK_6 0x0b -#define INQUIRY 0x12 -#define MODE_SELECT 0x15 -#define RESERVE 0x16 -#define RELEASE 0x17 -#define COPY 0x18 -#define MODE_SENSE 0x1a -#define START_STOP 0x1b -#define RECIEVE_DAIGNOSTIC 0x1c -#define SEND_DIAGNOSTIC 0x1d -#define ALLOW_MEDIUM_REMOVAL 0x1e - -#define READ_CAPACITY 0x25 -#define READ_10 0x28 -#define WRITE_10 0x2a -#define SEEK_10 0x2b -#define WRITE_VERIFY 0x2e -#define VERIFY 0x2f -#define SEARCH_HIGH 0x30 -#define SEARCH_EQUAL 0x31 -#define SEARCH_LOW 0x32 -#define SET_LIMITS 0x33 -#define COMPARE 0x39 -#define COPY_VERIFY 0x3a - -#define COMMAND_SIZE(opcode) ((opcode) ? ((opcode) > 0x20 ? 10 : 6) : 0) - -/* - MESSAGE CODES -*/ - -#define COMMAND_COMPLETE 0x00 -#define EXTENDED_MESSAGE 0x01 -#define SAVE_POINTERS 0x02 -#define RESTORE_POINTERS 0x03 -#define DISCONNECT 0x04 -#define INITIATOR_ERROR 0x05 -#define ABORT 0x06 -#define MESSAGE_REJECT 0x07 -#define NOP 0x08 -#define MSG_PARITY_ERROR 0x09 -#define LINKED_CMD_COMPLETE 0x0a -#define LINKED_FLG_CMD_COMPLETE 0x0b -#define BUS_DEVICE_RESET 0x0c -#define IDENTIFY 0x80 -/* - Status codes -*/ - -#define GOOD 0x00 -#define CHECK_CONDITION 0x01 -#define CONDITION_GOOD 0x02 -#define BUSY 0x04 -#define INTERMEDIATE_GOOD 0x08 -#define INTERMEDIATE_C_GOOD 0x0a -#define RESERVATION_CONFLICT 0x0c - -#define STATUS_MASK 0x1e - -/* - the return of the status word will be in the following format : - The low byte is the status returned by the SCSI command, - with vendor specific bits masked. - - The next byte is the message which followed the SCSI status. - This allows a stos to be used, since the Intel is a little - endian machine. - - The final byte is a host return code, which is one of the following. - - IE - lsb msb - status msg host code - - Our errors returned by OUR driver, NOT SCSI message. Orr'd with - SCSI message passed back to driver . -*/ - -/* NO error */ -#define DID_OK 0x00 -/* Couldn't connect before timeout period */ -#define DID_NO_CONNECT 0x01 -/* BUS stayed busy through time out period */ -#define DID_BUS_BUSY 0x02 -/* TIMED OUT for other reason */ -#define DID_TIME_OUT 0x03 -/* BAD target. */ -#define DID_BAD_TARGET 0x04 -/* Told to abort for some other reason */ -#define DID_ABORT 0x05 -/* - Parity error -*/ -#define DID_PARITY 0x06 -/* - Internal error -*/ -#define DID_ERROR 0x07 -/* - Reset by somebody. -*/ -#define DID_RESET 0x08 - -/* - Driver status -*/ -#define DRIVER_OK 0x00 - -/* - These indicate the error that occured, and what is available. -*/ - -#define DRIVER_BUSY 0x01 -#define DRIVER_SOFT 0x02 -#define DRIVER_MEDIA 0x03 -#define DRIVER_ERROR 0x04 - -#define DRIVER_INVALID 0x05 -#define DRIVER_TIMEOUT 0x06 -#define DRIVER_HARD 0x07 - -#define SUGGEST_RETRY 0x08 -#define SUGGEST_ABORT 0x09 -#define SUGGEST_REMAP 0x0a -#define SUGGEST_DIE 0x0b - -#define DRIVER_SENSE 0x10 - -#define DRIVER_MASK 0x0f -#define SUGGEST_MASK 0xf0 - -/* - - SENSE KEYS -*/ - -#define NO_SENSE 0x00 -#define RECOVERED_ERROR 0x01 -#define NOT_READY 0x02 -#define MEDIUM_ERROR 0x03 -#define HARDWARE_ERROR 0x04 -#define ILLEGAL_REQUEST 0x05 -#define UNIT_ATTENTION 0x06 -#define DATA_PROTECT 0x07 -#define BLANK_CHECK 0x08 -#define COPY_ABORTED 0x0a -#define ABORTED_COMMAND 0x0b -#define VOLUME_OVERFLOW 0x0d -#define MISCOMPARE 0x0e - - -/* - DEVICE TYPES - -*/ - -#define TYPE_DISK 0x00 -#define TYPE_TAPE 0x01 -#define TYPE_WORM 0x04 /* Treated as ROM by our system */ -#define TYPE_ROM 0x05 -#define TYPE_NO_LUN 0x7f -/* - Every SCSI command starts with a one byte OP-code. - The next byte's high three bits are the LUN of the - device. Any multi-byte quantities are stored high byte - first, and may have a 5 bit MSB in the same byte - as the LUN. -*/ - - -/* - The scsi_device struct contains what we know about each given scsi - device. -*/ - -typedef struct scsi_device { - unsigned char host_no, id, lun; - unsigned writeable:1; - unsigned removable:1; - unsigned random:1; - } Scsi_Device; -/* - Use these to separate status msg and our bytes -*/ - -#define status_byte(result) (((result) >> 1) & 0xf) -#define msg_byte(result) (((result) >> 8) & 0xff) -#define host_byte(result) (((result) >> 16) & 0xff) -#define driver_byte(result) (((result) >> 24) & 0xff) -#define sugestion(result) (driver_byte(result) & SUGGEST_MASK) - -#define sense_class(sense) (((sense) >> 4) & 0x7) -#define sense_error(sense) ((sense) & 0xf) -#define sense_valid(sense) ((sense) & 0x80); - -/* - These are the SCSI devices available on the system. -*/ - -#define MAX_SCSI_DEVICE 2 -extern int NR_SCSI_DEVICES; -extern Scsi_Device scsi_devices[MAX_SCSI_DEVICE]; -/* - scsi_abort aborts the current command that is executing on host host. - The error code, if non zero is returned in the host byte, otherwise - DID_ABORT is returned in the hostbyte. -*/ - -extern int scsi_abort (int host, int code); - -/* - Initializes all SCSI devices. This scans all scsi busses. -*/ - -extern void scsi_dev_init (void); - -/* - You guesed it. This sends a command to the selected SCSI host -*/ - - - -extern void scsi_do_cmd (int host, unsigned char target, const void *cmnd , - void *buffer, unsigned bufflen, void (*done)(int,int), - int timeout, unsigned char *sense_buffer, int retries); - -int scsi_reset (int host); -#endif diff --git a/kernel/blk_drv/scsi/scsi_ioctl.c b/kernel/blk_drv/scsi/scsi_ioctl.c deleted file mode 100644 index b373c3b306d0..000000000000 --- a/kernel/blk_drv/scsi/scsi_ioctl.c +++ /dev/null @@ -1,153 +0,0 @@ -#include -#ifdef CONFIG_SCSI - -#include -#include -#include -#include - -#include -#include -#include - -#include "scsi.h" -#include "hosts.h" -#include "scsi_ioctl.h" - -#define MAX_RETRIES 5 -#define MAX_TIMEOUT 200 -#define MAX_BUF 1024 - -#define max(a,b) (((a) > (b)) ? (a) : (b)) - -/* - * If we are told to probe a host, we will return 0 if the host is not - * present, 1 if the host is present, and will return an identifying - * string at *arg, if arg is non null, filling to the length stored at - * (int *) arg - */ - -static int ioctl_probe(int dev, void *buffer) -{ - int temp; - int len; - - if ((temp = scsi_hosts[dev].present) && buffer) { - len = get_fs_long ((int *) buffer); - memcpy_tofs (buffer, scsi_hosts[dev].info(), len); - } - return temp; -} - -/* - * - * The SCSI_IOCTL_SEND_COMMAND ioctl sends a command out to the SCSI host. - * The MAX_TIMEOUT and MAX_RETRIES variables are used. - * - * dev is the SCSI device number, *(int *) arg the length of the input - * data, *((int *)arg + 1) the output buffer. - * - * *(char *) ((int *) arg)[1] the actual command. - * - * Note that no more than MAX_BUF bytes will be transfered. Since - * SCSI block device size is 512 bytes, I figured 1K was good. - * - * This size * does * include the initial lengths that were passed. - * - * The SCSI command is read from the memory location immediately after the - * length words, and the out data after the command. The SCSI routines know the - * command size based on the length byte. - * - * The area is then filled in from the byte at offset 0. - */ - -static int the_result[MAX_SCSI_HOSTS]; - -static void scsi_ioctl_done (int host, int result) -{ - the_result[host] = result; -} - -static int ioctl_command(Scsi_Device *dev, void *buffer) -{ - char buf[MAX_BUF]; - char cmd[10]; - char * cmd_in; - unsigned char opcode; - int inlen, outlen, cmdlen, temp, host; - - if (!buffer) - return -EINVAL; - - inlen = get_fs_long((int *) buffer); - outlen = get_fs_long(((int *) buffer) + 1); - - cmd_in = (char *) ( ((int *)buffer) + 2); - opcode = get_fs_byte(cmd_in); - - memcpy_fromfs ((void *) cmd, cmd_in, cmdlen = COMMAND_SIZE (opcode)); - memcpy_fromfs ((void *) buf, (void *) (cmd_in + cmdlen), inlen); - host = dev->host_no; - -#ifndef DEBUG_NO_CMD - do { - cli(); - if (the_result[host]) { - sti(); - while(the_result[host]) - /* nothing */; - } else { - the_result[host]=-1; - sti(); - break; - } - } while (1); - - scsi_do_cmd(host, dev->id, cmd, buf, ((outlen > MAX_BUF) ? - MAX_BUF : outlen), scsi_ioctl_done, MAX_TIMEOUT, - buf, MAX_RETRIES); - - while (the_result[host] == -1) - /* nothing */; - temp = the_result[host]; - the_result[host]=0; - memcpy_tofs (buffer, buf, (outlen > MAX_BUF) ? MAX_BUF : outlen); - return temp; -#else - { - int i; - printk("scsi_ioctl : device %d. command = ", dev); - for (i = 0; i < 10; ++i) - printk("%02x ", cmd[i]); - printk("\r\nbuffer ="); - for (i = 0; i < 20; ++i) - printk("%02x ", buf[i]); - printk("\r\n"); - } - return 0; -#endif -} - - -/* - the scsi_ioctl() function differs from most ioctls in that it does - not take a major/minor number as the dev filed. Rather, it takes - an index in scsi_devices[] -*/ -int scsi_ioctl (int dev, int cmd, void *arg) -{ - if ((cmd != 0 && dev > NR_SCSI_DEVICES) || dev < 0) - return -ENODEV; - if ((cmd == 0 && dev > MAX_SCSI_HOSTS)) - return -ENODEV; - - switch (cmd) { - case SCSI_IOCTL_PROBE_HOST: - return ioctl_probe(dev, arg); - case SCSI_IOCTL_SEND_COMMAND: - return ioctl_command((Scsi_Device *) dev, arg); - default : - return -EINVAL; - } -} -#endif diff --git a/kernel/blk_drv/scsi/scsi_ioctl.h b/kernel/blk_drv/scsi/scsi_ioctl.h deleted file mode 100644 index 2acdb55fe4d7..000000000000 --- a/kernel/blk_drv/scsi/scsi_ioctl.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _SCSI_IOCTL_H -#define _SCSI_IOCTL_H - -#ifndef _CONFIG_H -#include -#endif - -#define SCSI_IOCTL_PROBE_HOST 0 -#define SCSI_IOCTL_SEND_COMMAND 1 - -#ifdef CONFIG_BLK_DEV_SD -/* Should start at 128 */ -#endif - -#ifdef CONFIG_BLK_DEV_SD -/* Should start at 256 */ -#endif - -#endif - - diff --git a/kernel/blk_drv/scsi/sd.c b/kernel/blk_drv/scsi/sd.c deleted file mode 100644 index 0ad47d336857..000000000000 --- a/kernel/blk_drv/scsi/sd.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * sd.c Copyright (C) 1992 Drew Eckhardt - * Linux scsi disk driver by - * Drew Eckhardt - * - * - */ - -#include - -#ifdef CONFIG_BLK_DEV_SD -#include -#include -#include -#include -#include "scsi.h" -#include "sd.h" - -#define MAJOR_NR 8 - -#include "../blk.h" - -/* -static const char RCSid[] = "$Header:"; -*/ - -#define MAX_RETRIES 5 - -/* - * Time out in seconds - */ - -#define SD_TIMEOUT 100 - -Partition scsi_disks[MAX_SD << 4]; -int NR_SD=0; -Scsi_Disk rscsi_disks[MAX_SD]; -static int sd_sizes[MAX_SD << 4]; -static int this_count; -static int the_result; - -extern int sd_ioctl(struct inode *, struct file *, unsigned long, unsigned long); - -static void sd_release(struct inode * inode, struct file * file) -{ - sync_dev(inode->i_rdev); -} - -static struct file_operations sd_fops = { - NULL, /* lseek - default */ - block_read, /* read - general block-dev read */ - block_write, /* write - general block-dev write */ - NULL, /* readdir - bad */ - NULL, /* select */ - sd_ioctl, /* ioctl */ - NULL, /* no special open code */ - sd_release /* release */ -}; - -/* - The sense_buffer is where we put data for all mode sense commands - performed. -*/ - -static unsigned char sense_buffer[255]; - -/* - rw_intr is the interrupt routine for the device driver. It will - be notified on the end of a SCSI read / write, and - will take on of several actions based on success or failure. -*/ - -static void rw_intr (int host, int result) -{ - if (HOST != host) - panic ("sd.o : rw_intr() recieving interrupt for different host."); - -/* - First case : we assume that the command succeeded. One of two things will - happen here. Either we will be finished, or there will be more - sectors that we were unable to read last time. -*/ - - if (!result) - if (!(CURRENT->nr_sectors -= this_count)) { - end_request(1); - do_sd_request(); - } else { - CURRENT->nr_sectors -= this_count; -/* - The CURRENT->nr_sectors field is always done in 512 byte sectors, - even if this really isn't the case. -*/ - - (char *) CURRENT->buffer += this_count << 9; - CURRENT->sector += this_count; - CURRENT->errors = 0; - do_sd_request(); - } - -/* - Now, if we were good little boys and girls, Santa left us a request - sense buffer. We can extract information from this, so we - can choose a block to remap, etc. -*/ - - else if (driver_byte(result) & DRIVER_SENSE) { - if (sugestion(result) == SUGGEST_REMAP) { -#ifdef REMAP -/* - Not yet implemented. A read will fail after being remapped, - a write will call the strategy routine again. -*/ - - if rscsi_disks[DEVICE_NR(CURRENT->dev)].remap - { - result = 0; - } - else - -#endif - } -/* - If we had an ILLEGAL REQUEST returned, then we may have performed - an unsupported command. The only thing this should be would be a ten - byte read where only a six byte read was supportted. Also, on a - system where READ CAPACITY failed, we mave have read past the end of the - disk. -*/ - - else if (sense_buffer[7] == ILLEGAL_REQUEST) { - if (rscsi_disks[DEVICE_NR(CURRENT->dev)].ten) { - rscsi_disks[DEVICE_NR(CURRENT->dev)].ten = 0; - do_sd_request(); - result = 0; - } else { - } - } - } - if (result) { - printk("SCSI disk error : host %d id %d lun %d return code = %03x\n", - rscsi_disks[DEVICE_NR(CURRENT->dev)].device->host_no, - rscsi_disks[DEVICE_NR(CURRENT->dev)].device->id, - rscsi_disks[DEVICE_NR(CURRENT->dev)].device->lun); - - if (driver_byte(result) & DRIVER_SENSE) - printk("\tSense class %x, sense error %x, extended sense %x\n", - sense_class(sense_buffer[0]), - sense_error(sense_buffer[0]), - sense_buffer[2] & 0xf); - - end_request(0); - } -} - -/* - do_sd_request() is the request handler function for the sd driver. - Its function in life is to take block device requests, and translate - them to SCSI commands. -*/ - -void do_sd_request (void) -{ - int dev, block; - unsigned char cmd[10]; - - INIT_REQUEST; - dev = MINOR(CURRENT->dev); - block = CURRENT->sector; - -#ifdef DEBUG - printk("Doing sd request, dev = %d, block = %d\n", dev, block); -#endif - - if (dev >= (NR_SD << 4) || block + 2 > scsi_disks[dev].nr_sects || - (dev % 16) > 5) - { - end_request(0); - goto repeat; - } - - block += scsi_disks[dev].start_sect; - dev = DEVICE_NR(dev); - -#ifdef DEBUG - printk("Real dev = %d, block = %d\n", dev, block); -#endif - - if (!rscsi_disks[dev].use) - { - end_request(0); - goto repeat; - } - - this_count = CURRENT->nr_sectors; - switch (CURRENT->cmd) - { - case WRITE : - if (!rscsi_disks[dev].device->writeable) - { - end_request(0); - goto repeat; - } - cmd[0] = WRITE_6; - break; - case READ : - cmd[0] = READ_6; - break; - default : - printk ("Unknown sd command %d\r\n", CURRENT->cmd); - panic(""); - } - - cmd[1] = (LUN << 5) & 0xe0; - - if (((this_count > 0xff) || (block > 0x1fffff)) && rscsi_disks[dev].ten) - { - if (this_count > 0xffff) - this_count = 0xffff; - - cmd[0] += READ_10 - READ_6 ; - cmd[2] = (unsigned char) (block >> 24) & 0xff; - cmd[3] = (unsigned char) (block >> 16) & 0xff; - cmd[4] = (unsigned char) (block >> 8) & 0xff; - cmd[5] = (unsigned char) block & 0xff; - cmd[6] = cmd[9] = 0; - cmd[7] = (unsigned char) (this_count >> 8) & 0xff; - cmd[8] = (unsigned char) this_count & 0xff; - } - else - { - if (this_count > 0xff) - this_count = 0xff; - - cmd[1] |= (unsigned char) ((block >> 16) & 0x1f); - cmd[2] = (unsigned char) ((block >> 8) & 0xff); - cmd[3] = (unsigned char) block & 0xff; - cmd[4] = (unsigned char) this_count; - cmd[5] = 0; - } - - scsi_do_cmd (HOST, ID, (void *) cmd, CURRENT->buffer, this_count << 9, - rw_intr, SD_TIMEOUT, sense_buffer, MAX_RETRIES); -} - -static void sd_init_done (int host, int result) -{ - the_result = result; -} - -/* - The sd_init() function looks at all SCSI drives present, determines - their size, and reads partition table entries for them. -*/ - -void sd_init(void) -{ - int i,j,k; - unsigned char cmd[10]; - unsigned char buffer[513]; - - Partition *p; - - - for (i = 0; i < NR_SD; ++i) - { - cmd[0] = READ_CAPACITY; - rscsi_disks[i].use = 1; - cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; - memset ((void *) &cmd[2], 0, 8); - the_result = -1; -#ifdef DEBUG - printk("Read capacity, disk %d at host = %d, id = %d\n", i, - rscsi_disks[i].device->host_no, rscsi_disks[i].device->id); -#endif - scsi_do_cmd (rscsi_disks[i].device->host_no , - rscsi_disks[i].device->id, - (void *) cmd, (void *) buffer, - 512, sd_init_done, SD_TIMEOUT, sense_buffer, - MAX_RETRIES); - - while(the_result < 0); -/* - The SCSI standard says "READ CAPACITY is necessary for self confuring software" - While not mandatory, support of READ CAPACITY is strongly encouraged. - - We used to die if we couldn't successfully do a READ CAPACITY. - But, now we go on about our way. The side effects of this are - - 1. We can't know block size with certainty. I have said "512 bytes is it" - as this is most common. - - 2. Recovery from when some one attempts to read past the end of the raw device will - be slower. -*/ - - if (the_result) - { - printk ("Warning : SCSI device at host %d, id %d, lun %d failed READ CAPACITY.\n" - "status = %x, message = %02x, host = %02x, driver = %02x \n", - rscsi_disks[i].device->host_no, rscsi_disks[i].device->id, - rscsi_disks[i].device->lun, - status_byte(the_result), - msg_byte(the_result), - host_byte(the_result), - driver_byte(the_result) - ); - if (driver_byte(the_result) & DRIVER_SENSE) - printk("Extended sense code = %1x \n", sense_buffer[2] & 0xf); - else - printk("Sense not available. \n"); - - printk("Block size assumed to be 512 bytes, disk size 1GB. \n"); - rscsi_disks[i].capacity = 0x1fffff; - rscsi_disks[i].sector_size = 512; - } - else - { - rscsi_disks[i].capacity = (buffer[0] << 24) | - (buffer[1] << 16) | - (buffer[2] << 8) | - buffer[3]; - - if ((rscsi_disks[i].sector_size = (buffer[4] << 24) | - (buffer[5] << 16) | - (buffer[6] << 8) | - buffer[7]) != 512) - { - printk ("Unsupported sector size %d for sd %d", - rscsi_disks[i].sector_size, i); - rscsi_disks[i].use = 0; - } - } - - if (rscsi_disks[i].use) - { - scsi_disks[j = (i << 4)].start_sect = 0; - - sd_sizes[j]=(scsi_disks[j].nr_sects = rscsi_disks[i].capacity)>>1; -#ifdef DEBUG - printk("/dev/sd%1d size = %d\n", j, sd_sizes[j]); -#endif - cmd[0] = READ_6; - cmd[2] = cmd[3] = cmd[5] = 0; - cmd[4] = 1; - the_result = -1; - - scsi_do_cmd (rscsi_disks[i].device->host_no , rscsi_disks[i].device->id, - (void *) cmd, (void *) buffer, 512, sd_init_done, SD_TIMEOUT, - sense_buffer, MAX_RETRIES); - - while (the_result < 0); - - - if (the_result || (0xaa55 != *(unsigned short *)(buffer + 510))) - { - printk ("Cannot read partition table for sd %d" - "\n\r",i); - rscsi_disks[i].use = 0; - } - else - for (++j, k=j+4, p=(Partition *) (buffer + 0x1be); j < k; ++j, ++p) - { - memcpy ((void *) &scsi_disks[j], (void *) p, sizeof(Partition)); - sd_sizes[j]=(scsi_disks[j].nr_sects)>>1; -#ifdef DEBUG - printk("/dev/sd%1d size = %d (%d blocks), offset = %d\n", j, scsi_disks[j].nr_sects, sd_sizes[j], scsi_disks[j].start_sect); -#endif - } - - rscsi_disks[i].ten = 1; - rscsi_disks[i].remap = 1; - } - } - blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; - blk_size[MAJOR_NR] = sd_sizes; - blkdev_fops[MAJOR_NR] = &sd_fops; -} -#endif - diff --git a/kernel/blk_drv/scsi/sd.h b/kernel/blk_drv/scsi/sd.h deleted file mode 100644 index e4c4613bdb27..000000000000 --- a/kernel/blk_drv/scsi/sd.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * sd.h Copyright (C) 1992 Drew Eckhardt - * SCSI disk driver header file by - * Drew Eckhardt - * - * - */ -#ifndef _SD_H - #define _SD_H -/* - $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/sd.h,v 1.1 1992/04/24 18:01:50 root Exp root $ -*/ - -#ifndef _SCSI_H -#include "scsi.h" -#endif - -#define MAX_SD 2 - -typedef struct partition { - unsigned char boot_ind; /* 0x80 - active (unused) */ - unsigned char head; /* ? */ - unsigned char sector; /* ? */ - unsigned char cyl; /* ? */ - unsigned char sys_ind; /* ? */ - unsigned char end_head; /* ? */ - unsigned char end_sector; /* ? */ - unsigned char end_cyl; /* ? */ - unsigned int start_sect; /* starting sector counting from 0 */ - unsigned int nr_sects; /* nr of sectors in partition */ -} Partition; - -extern int NR_SD; - -extern Partition scsi_disks[MAX_SD << 4] ; - - -typedef struct { - unsigned capacity; /* size in blocks */ - unsigned sector_size; /* size in bytes */ - Scsi_Device *device; - unsigned char sector_bit_size; /* sector_size = 2 to the bit size power */ - unsigned char sector_bit_shift; /* power of 2 sectors per FS block */ - unsigned ten:1; /* support ten byte read / write */ - unsigned remap:1; /* support remapping */ - unsigned use:1; /* after the initial inquiry, is - the device still supported ? */ - } Scsi_Disk; - -extern Scsi_Disk rscsi_disks[MAX_SD]; - -void sd_init(void); - -#define HOST (rscsi_disks[DEVICE_NR(CURRENT->dev)].device->host_no) -#define ID (rscsi_disks[DEVICE_NR(CURRENT->dev)].device->id) -#define LUN (rscsi_disks[DEVICE_NR(CURRENT->dev)].device->lun) -#endif diff --git a/kernel/blk_drv/scsi/sd_ioctl.c b/kernel/blk_drv/scsi/sd_ioctl.c deleted file mode 100644 index 5c55e167c8db..000000000000 --- a/kernel/blk_drv/scsi/sd_ioctl.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#ifdef CONFIG_BLK_DEV_SD -#include -#include -#include -#include -#include "../blk.h" -#include -#include "scsi.h" -#include "sd.h" - -extern int scsi_ioctl (int dev, int cmd, void *arg); - -int sd_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsigned long arg) -{ - int dev = inode->i_rdev; - - switch (cmd) { - RO_IOCTLS(dev,arg); - default: - return scsi_ioctl(rscsi_disks[MINOR(dev) >> 4].device,cmd,(void *) arg); - } -} -#endif diff --git a/kernel/blk_drv/scsi/seagate.c b/kernel/blk_drv/scsi/seagate.c deleted file mode 100644 index 28df16202054..000000000000 --- a/kernel/blk_drv/scsi/seagate.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - * seagate.c Copyright (C) 1992 Drew Eckhardt - * low level scsi driver for ST01/ST02 by - * Drew Eckhardt - * - * - */ - -#include - -#ifdef CONFIG_SCSI_SEAGATE -#include - -#include "seagate.h" -#include "scsi.h" -#include "hosts.h" - -static int incommand; /* - set if arbitration has finished and we are - in some command phase. - */ - -static void *base_address = NULL; /* - Where the card ROM starts, - used to calculate memory mapped - register location. - */ -static volatile int abort_confirm = 0; - -volatile void *st0x_cr_sr; /* - control register write, - status register read. - 256 bytes in length. - - Read is status of SCSI BUS, - as per STAT masks. - - */ - - -static volatile void *st0x_dr; /* - data register, read write - 256 bytes in length. - */ - - -static volatile int st0x_aborted=0; /* - set when we are aborted, ie by a time out, etc. - */ - - /* - In theory, we have a nice auto - detect routine - but this - overides it. - */ - - -#define retcode(result) (((result) << 16) | (message << 8) | status) -#define STATUS (*(unsigned char *) st0x_cr_sr) -#define CONTROL STATUS -#define DATA (*(unsigned char *) st0x_dr) - -#ifndef OVERRIDE -static const char * seagate_bases[] = {(char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000, (char *) 0xce000, (char *) 0xce000, - (char *) 0xdc000, (char *) 0xde000}; -typedef struct - { - char *signature ; - unsigned offset; - unsigned length; - } Signature; - -static const Signature signatures[] = { -{"SCSI BIOS 2.00 (C) Copyright 1987 Seagate", 15, 40}, -{"SEAGATE SCSI BIOS ",16, 17}, -{"SEAGATE SCSI BIOS ",17, 17}}; -/* - Note that the last signature handles BIOS revisions 3.0.0 and - 3.2 - the real ID's are - -SEAGATE SCSI BIOS REVISION 3.0.0 -SEAGATE SCSI BIOS REVISION 3.2 - -*/ - -#define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature)) -#endif - -int seagate_st0x_detect (int hostnum) - { - #ifndef OVERRIDE - int i,j; - #endif - - /* - First, we try for the manual override. - */ - #ifdef DEBUG - printk("Autodetecting seagate ST0x\n"); - #endif - - base_address = NULL; - #ifdef OVERRIDE - base_address = (void *) OVERRIDE; - #ifdef DEBUG - printk("Base address overridden to %x\n", base_address); - #endif - #else - /* - To detect this card, we simply look for the SEAGATE SCSI - from the BIOS version notice in all the possible locations - of the ROM's. - */ - - for (i = 0; i < (sizeof (seagate_bases) / sizeof (char * )); ++i) - for (j = 0; !base_address && j < NUM_SIGNATURES; ++j) - if (!memcmp ((void *) (seagate_bases[i] + - signatures[j].offset), (void *) signatures[j].signature, - signatures[j].length)) - base_address = (void *) seagate_bases[i]; - #endif - - if (base_address) - { - st0x_cr_sr =(void *) (((unsigned char *) base_address) + 0x1a00); - st0x_dr = (void *) (((unsigned char *) base_address )+ 0x1c00); - #ifdef DEBUG - printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr); - #endif - return -1; - } - else - { - #ifdef DEBUG - printk("ST0x not detected.\n"); - #endif - return 0; - } - } - - - -char *seagate_st0x_info(void) -{ - static char buffer[] = "Seagate ST-0X SCSI driver by Drew Eckhardt \n" -"$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/seagate.c,v 1.1 1992/04/24 18:01:50 root Exp root $\n"; - return buffer; -} - - - -int seagate_st0x_command(unsigned char target, const void *cmnd, - void *buff, int bufflen) - { - int len; - unsigned char *data; - - int clock; /* - We use clock for timeouts, etc. This replaces the - seagate_st0x_timeout that we had been using. - */ - #if (DEBUG & PHASE_SELECTION) - int temp; - #endif - - #if (DEBUG & PHASE_EXIT) - void *retaddr, *realretaddr; - #endif - - #if ((DEBUG & PHASE_ETC) || (DEBUG & PRINT_COMMAND) || (DEBUG & PHASE_EXIT)) - int i; - #endif - - #if (DEBUG & PHASE_ETC) - int phase=0, newphase; - #endif - - int done = 0; - unsigned char status = 0; - unsigned char message = 0; - register unsigned char status_read; - - #if (DEBUG & PHASE_EXIT) - __asm__(" -movl 4(%%ebp), %%eax -":"=a" (realretaddr):); - printk("return address = %08x\n", realretaddr); - #endif - - - len=bufflen; - data=(unsigned char *) buff; - - incommand = 0; - st0x_aborted = 0; - - #if (DEBUG & PRINT_COMMAND) - printk ("seagate_st0x_command, target = %d, command = ", target); - for (i = 0; i < COMMAND_SIZE(((unsigned char *)cmnd)[0]); ++i) - printk("%02x ", ((unsigned char *) cmnd)[i]); - printk("\n"); - #endif - - if (target > 6) - return DID_BAD_TARGET; - - - #if (DEBUG & PHASE_BUS_FREE) - printk ("SCSI PHASE = BUS FREE \n"); - #endif - - /* - - BUS FREE PHASE - - On entry, we make sure that the BUS is in a BUS FREE - phase, by insuring that both BSY and SEL are low for - at least one bus settle delay. The standard requires a - minimum of 400 ns, which is 16 clock cycles on a - 386-40 . - - This doesn't give us much time - so we'll do two several - reads to be sure be sure. - */ - - clock = jiffies + ST0X_BUS_FREE_DELAY; - - while (((STATUS | STATUS | STATUS) & - (STAT_BSY | STAT_SEL)) && - (!st0x_aborted) && (jiffies < clock)); - - if (jiffies > clock) - return retcode(DID_BUS_BUSY); - else if (st0x_aborted) - return retcode(st0x_aborted); - - /* - Bus free has been detected, within BUS settle. I used to support an arbitration - phase - however, on the seagate, this degraded performance by a factor > 10 - so - it is no more. - */ - - /* - SELECTION PHASE - - Now, we select the disk, giving it the SCSI ID at data - and a command of PARITY if necessary, plus driver enable, - plus raise select signal. - */ - - #if (DEBUG & PHASE_SELECTION) - printk("SCSI PHASE = SELECTION\n"); - #endif - - clock = jiffies + ST0X_SELECTION_DELAY; - DATA = (unsigned char) (1 << target); - - CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL; - - /* - When the SCSI device decides that we're gawking at it, it will respond by asserting BUSY on the bus. - */ - while (!((status_read = STATUS) & STAT_BSY) && (jiffies < clock) && !st0x_aborted) - -#if (DEBUG & PHASE_SELECTION) - { - temp = clock - jiffies; - - if (!(jiffies % 5)) - printk("seagate_st0x_timeout : %d \r",temp); - - } - printk("Done. \n\r"); - printk("Status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n", status_read, temp, - st0x_aborted); -#else - ; -#endif - - - if ((jiffies > clock) || (!st0x_aborted & !(status_read & STAT_BSY))) - { - #if (DEBUG & PHASE_SELECT) - printk ("NO CONNECT with target %d, status = %x \n", target, STATUS); - #endif - return retcode(DID_NO_CONNECT); - } - - /* - If we have been aborted, and we have a command in progress, IE the target still has - BSY asserted, then we will reset the bus, and notify the midlevel driver to - expect sense. - */ - - if (st0x_aborted) - { - CONTROL = BASE_CMD; - if (STATUS & STAT_BSY) - { - seagate_st0x_reset(); - return retcode(DID_RESET); - } - - return retcode(st0x_aborted); - } - - /* - COMMAND PHASE - The device has responded with a BSY, so we may now enter - the information transfer phase, where we will send / recieve - data and command as directed by the target. - - - The nasty looking read / write inline assembler loops we use for - DATAIN and DATAOUT phases are approximately 4-5 times as fast as - the 'C' versions - since we're moving 1024 bytes of data, this - really adds up. - */ - - #if (DEBUG & PHASE_ETC) - printk("PHASE = information transfer\n"); - #endif - - incommand = 1; - - /* - Enable command - */ - - CONTROL = BASE_CMD | CMD_DRVR_ENABLE; - - /* - Now, we poll the device for status information, - and handle any requests it makes. Note that since we are unsure of - how much data will be flowing across the system, etc and cannot - make reasonable timeouts, that we will instead have the midlevel - driver handle any timeouts that occur in this phase. - */ - - while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done) - { - #ifdef PARITY - if (status_read & STAT_PARITY) - { - done = 1; - st0x_aborted = DID_PARITY; - } - #endif - - if (status_read & STAT_REQ) - { - #if (DEBUG & PHASE_ETC) - if ((newphase = (status_read & REQ_MASK)) != phase) - { - phase = newphase; - switch (phase) - { - case REQ_DATAOUT : printk("SCSI PHASE = DATA OUT\n"); break; - case REQ_DATAIN : printk("SCSI PHASE = DATA IN\n"); break; - case REQ_CMDOUT : printk("SCSI PHASE = COMMAND OUT\n"); break; - case REQ_STATIN : printk("SCSI PHASE = STATUS IN\n"); break; - case REQ_MSGOUT : printk("SCSI PHASE = MESSAGE OUT\n"); break; - case REQ_MSGIN : printk("SCSI PHASE = MESSAGE IN\n"); break; - default : printk("UNKNOWN PHASE"); st0x_aborted = 1; done = 1; - } - } - #endif - - switch (status_read & REQ_MASK) - { - case REQ_DATAOUT : - - /* - We loop as long as we are in a data out phase, there is data to send, and BSY is still - active - */ - __asm__ (" - -/* - Local variables : - len = ecx - data = esi - st0x_cr_sr = ebx - st0x_dr = edi - - Test for any data here at all. -*/ - movl %0, %%esi /* local value of data */ - movl %1, %%ecx /* local value of len */ - orl %%ecx, %%ecx - jz 2f - - cld - - movl _st0x_cr_sr, %%ebx - movl _st0x_dr, %%edi - -1: movb (%%ebx), %%al -/* - Test for BSY -*/ - - test $1, %%al - jz 2f - -/* - Test for data out phase - STATUS & REQ_MASK should be REQ_DATAOUT, which is 0. -*/ - test $0xe, %%al - jnz 2f -/* - Test for REQ -*/ - test $0x10, %%al - jz 1b - lodsb - movb %%al, (%%edi) - loop 1b - -2: - movl %%esi, %2 - movl %%ecx, %3 - ": -/* output */ -"=r" (data), "=r" (len) : -/* input */ -"0" (data), "1" (len) : -/* clobbered */ -"ebx", "ecx", "edi", "esi"); - - break; - - case REQ_DATAIN : - /* - We loop as long as we are in a data out phase, there is room to read, and BSY is still - active - */ - - __asm__ (" -/* - Local variables : - ecx = len - edi = data - esi = st0x_cr_sr - ebx = st0x_dr - - Test for room to read -*/ - - movl %0, %%edi /* data */ - movl %1, %%ecx /* len */ - orl %%ecx, %%ecx - jz 2f - - cld - movl _st0x_cr_sr, %%esi - movl _st0x_dr, %%ebx - -1: movb (%%esi), %%al -/* - Test for BSY -*/ - - test $1, %%al - jz 2f - -/* - Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, = STAT_IO, which is 4. -*/ - movb $0xe, %%ah - andb %%al, %%ah - cmpb $0x04, %%ah - jne 2f - -/* - Test for REQ -*/ - test $0x10, %%al - jz 1b - - movb (%%ebx), %%al - stosb - loop 1b - -2: movl %%edi, %2 /* data */ - movl %%ecx, %3 /* len */ - ": -/* output */ -"=r" (data), "=r" (len) : -/* input */ -"0" (data), "1" (len) : -/* clobbered */ -"ebx", "ecx", "edi", "esi"); - break; - - case REQ_CMDOUT : - while (((status_read = STATUS) & STAT_BSY) && ((status_read & REQ_MASK) == - REQ_CMDOUT)) - DATA = *(unsigned char *) cmnd ++; - break; - - case REQ_STATIN : - status = DATA; - break; - - case REQ_MSGOUT : - DATA = MESSAGE_REJECT; - break; - - case REQ_MSGIN : - if ((message = DATA) == COMMAND_COMPLETE) - done=1; - - break; - - default : printk("UNKNOWN PHASE"); st0x_aborted = DID_ERROR; - } - } - - } - -#if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT)) - printk("Transfered %d bytes, allowed %d additional bytes\n", (bufflen - len), len); -#endif - -#if (DEBUG & PHASE_EXIT) - printk("Buffer : \n"); - for (i = 0; i < 20; ++i) - printk ("%02x ", ((unsigned char *) buff)[i]); - printk("\n"); - printk("Status = %02x, message = %02x\n", status, message); -#endif - - - if (st0x_aborted) - { - if (STATUS & STAT_BSY) - { - seagate_st0x_reset(); - st0x_aborted = DID_RESET; - } - abort_confirm = 1; - } - - CONTROL = BASE_CMD; - -#if (DEBUG & PHASE_EXIT) - __asm__(" -mov 4(%%ebp), %%eax -":"=a" (retaddr):); - - printk("Exiting seagate_st0x_command() - return address is %08x \n", retaddr); - if (retaddr != realretaddr) - panic ("Corrupted stack : return address on entry != return address on exit.\n"); - -#endif - - return retcode (st0x_aborted); - } - -int seagate_st0x_abort (int code) - { - if (code) - st0x_aborted = code; - else - st0x_aborted = DID_ABORT; - - return 0; - } - -/* - the seagate_st0x_reset function resets the SCSI bus -*/ - -int seagate_st0x_reset (void) - { - unsigned clock; - /* - No timeouts - this command is going to fail because - it was reset. - */ - -#ifdef DEBUG - printk("In seagate_st0x_reset()\n"); -#endif - - - /* assert RESET signal on SCSI bus. */ - - CONTROL = BASE_CMD | CMD_RST; - clock=jiffies+2; - - - /* Wait. */ - - while (jiffies < clock); - - CONTROL = BASE_CMD; - - st0x_aborted = DID_RESET; - -#ifdef DEBUG - printk("SCSI bus reset.\n"); -#endif - return 0; - } -#endif diff --git a/kernel/blk_drv/scsi/seagate.h b/kernel/blk_drv/scsi/seagate.h deleted file mode 100644 index d625446b4312..000000000000 --- a/kernel/blk_drv/scsi/seagate.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * seagate.h Copyright (C) 1992 Drew Eckhardt - * low level scsi driver header for ST01/ST02 by - * Drew Eckhardt - * - * - */ - -#ifndef _SEAGATE_H - #define SEAGATE_H -/* - $Header -*/ -#ifndef ASM -int seagate_st0x_detect(int); -int seagate_st0x_command(unsigned char target, const void *cmnd, void *buff, int bufflen); -int seagate_st0x_abort(int); -char *seagate_st0x_info(void); -int seagate_st0x_reset(void); - -#ifndef NULL - #define NULL 0 -#endif - -#define SEAGATE_ST0X {"Seagate ST-01/ST-02", seagate_st0x_detect, \ - seagate_st0x_info, seagate_st0x_command, \ - NULL, seagate_st0x_abort, seagate_st0x_reset, \ - 0, 7, 0} -#endif - - -/* - defining PARITY causes parity data to be checked -*/ - -#define PARITY - -/* - defining ARBITRATE causes the arbitration sequence to be used. And speed to drop by a - factor of ten. -*/ - -#undef ARBITRATE - - -/* - Thanks to Brian Antoine for the example code in his Messy-Loss ST-01 - driver, and Mitsugu Suzuki for information on the ST-01 - SCSI host. -*/ - -/* - CONTROL defines -*/ - -#define CMD_RST 0x01 -#define CMD_SEL 0x02 -#define CMD_BSY 0x04 -#define CMD_ATTN 0x08 -#define CMD_START_ARB 0x10 -#define CMD_EN_PARITY 0x20 -#define CMD_INTR 0x40 -#define CMD_DRVR_ENABLE 0x80 - -/* - STATUS -*/ - -#define STAT_BSY 0x01 -#define STAT_MSG 0x02 -#define STAT_IO 0x04 -#define STAT_CD 0x08 -#define STAT_REQ 0x10 -#define STAT_SEL 0x20 -#define STAT_PARITY 0x40 -#define STAT_ARB_CMPL 0x80 - -/* - REQUESTS -*/ - -#define REQ_MASK (STAT_CD | STAT_IO | STAT_MSG) -#define REQ_DATAOUT 0 -#define REQ_DATAIN STAT_IO -#define REQ_CMDOUT STAT_CD -#define REQ_STATIN (STAT_CD | STAT_IO) -#define REQ_MSGOUT (STAT_MSG | STAT_CD) -#define REQ_MSGIN (STAT_MSG | STAT_CD | STAT_IO) - -extern volatile int seagate_st0x_timeout; - -#ifdef PARITY - #define BASE_CMD CMD_EN_PARITY -#else - #define BASE_CMD 0 -#endif - -/* - Debugging code -*/ - -#define PHASE_BUS_FREE 1 -#define PHASE_ARBITRATION 2 -#define PHASE_SELECTION 4 -#define PHASE_DATAIN 8 -#define PHASE_DATAOUT 0x10 -#define PHASE_CMDOUT 0x20 -#define PHASE_MSGIN 0x40 -#define PHASE_MSGOUT 0x80 -#define PHASE_STATUSIN 0x100 -#define PHASE_ETC (PHASE_DATAIN | PHASE_DATA_OUT | PHASE_CMDOUT | PHASE_MSGIN | PHASE_MSGOUT | PHASE_STATUSIN) -#define PRINT_COMMAND 0x200 -#define PHASE_EXIT 0x400 - -/* - Control options - these are timeouts specified in .01 seconds. -*/ - -#define ST0X_BUS_FREE_DELAY 25 -#define ST0X_SELECTION_DELAY 25 - -#endif - diff --git a/kernel/blk_drv/scsi/st.c b/kernel/blk_drv/scsi/st.c deleted file mode 100644 index bef3ae8f4aaf..000000000000 --- a/kernel/blk_drv/scsi/st.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - The st.c file is a sub-stub file. I just wanted to have all the detect code, etc in the - mid level driver present and working. If no one else volunteers for this, I'll - do it - but it's low on my list of priorities. -*/ -#include - -#ifdef CONFIG_BLK_DEV_ST -#include "scsi.h" -#include "st.h" - -#define MAJOR_NR 9 -#include -#include -#include -#include "../blk.h" - -/* -static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/st.c,v 1.1 1992/04/24 18:01:50 root Exp root $"; -*/ - -Scsi_Tape scsi_tapes[MAX_ST]; -static int st_sizes[MAX_ST]; -int NR_ST=0; - -void do_st_request(void) -{ - panic("There is no st driver.\n\r"); -} - -void st_init(void) -{ - blk_dev[MAJOR_NR].request_fn = do_st_request; - blk_size[MAJOR_NR] = st_sizes; -} -#endif diff --git a/kernel/blk_drv/scsi/st.h b/kernel/blk_drv/scsi/st.h deleted file mode 100644 index 1a7c044352ef..000000000000 --- a/kernel/blk_drv/scsi/st.h +++ /dev/null @@ -1,26 +0,0 @@ - -#ifndef _ST_H - #define _ST_H -/* - $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/st.h,v 1.1 1992/04/24 18:01:50 root Exp root $ -*/ - -#ifndef _SCSI_H -#include "scsi.h" -#endif - -#define MAX_ST 1 - -typedef struct - { - /* - Undecided goodies go here!!! - */ - Scsi_Device* device; - } Scsi_Tape; - - -extern int NR_ST; -extern Scsi_Tape scsi_tapes[MAX_ST]; -void st_init(void); -#endif diff --git a/kernel/blk_drv/scsi/st_ioctl.c b/kernel/blk_drv/scsi/st_ioctl.c deleted file mode 100644 index 4bc7a39fe49a..000000000000 --- a/kernel/blk_drv/scsi/st_ioctl.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#ifdef CONFIG_BLK_DEV_ST -#include -#include -#include -#include "st.h" - -extern int scsi_ioctl(int dev, int cmd, void *arg); - -int st_ioctl(struct inode * inode,struct file * file, unsigned long cmd, unsigned long arg) -{ - int dev = inode->i_rdev; - - switch (cmd) { - default: - return scsi_ioctl(scsi_tapes[MINOR(dev)].device,cmd,(void *) arg); - } -} -#endif diff --git a/kernel/blk_drv/scsi/ultrastor.c b/kernel/blk_drv/scsi/ultrastor.c deleted file mode 100644 index ba30f211aee9..000000000000 --- a/kernel/blk_drv/scsi/ultrastor.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * ultrastor.c (C) 1991 David B. Gentzel - * Low-level SCSI driver for UltraStor 14F - * by David B. Gentzel, Whitfield Software Services, Carnegie, PA - * (gentzel@nova.enet.dec.com) - * Thanks to UltraStor for providing the necessary documentation - */ - -/* - * NOTES: - * The UltraStor 14F is an intelligent, high performance ISA SCSI-2 host - * adapter. It is essentially an ISA version of the UltraStor 24F EISA - * adapter. It supports first-party DMA, command queueing, and - * scatter/gather I/O. It can also emulate the standard AT MFM/RLL/IDE - * interface for use with OS's which don't support SCSI. - * - * This driver may also work (with some small changes) with the UltraStor - * 24F. I have no way of confirming this... - * - * Places flagged with a triple question-mark are things which are either - * unfinished, questionable, or wrong. - */ - -/* - * CAVEATS: ??? - * This driver is VERY stupid. It takes no advantage of much of the power - * of the UltraStor controller. We just sit-and-spin while waiting for - * commands to complete. I hope to go back and beat it into shape, but - * PLEASE, anyone else who would like to, please make improvements! - * - * By defining USE_QUEUECOMMAND as TRUE in ultrastor.h, you enable the - * queueing feature of the mid-level SCSI driver. This should improve - * performance somewhat. However, it does not seem to work. I believe - * this is due to a bug in the mid-level driver, but I haven't looked - * too closely. - */ - -#include - -#ifdef CONFIG_SCSI_ULTRASTOR - -#include - -#include -#include -#include -#include -#include - -#define ULTRASTOR_PRIVATE /* Get the private stuff from ultrastor.h */ -#include "ultrastor.h" -#include "scsi.h" -#include "hosts.h" - -#define VERSION "1.0 beta" - -#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr)[0]) -#define BIT(n) (1ul << (n)) -#define BYTE(num, n) ((unsigned char)((unsigned int)(num) >> ((n) * 8))) - -/* Simply using "unsigned long" in these structures won't work as it causes - alignment. Perhaps the "aligned" attribute may be used in GCC 2.0 to get - around this, but for now I use this hack. */ -typedef struct { - unsigned char bytes[4]; -} Longword; - -/* Used to fetch the configuration info from the config i/o registers. We - then store (in a friendlier format) in config. */ -struct config_1 { - unsigned char bios_segment: 3; - unsigned char reserved: 1; - unsigned char interrupt: 2; - unsigned char dma_channel: 2; -}; -struct config_2 { - unsigned char ha_scsi_id: 3; - unsigned char mapping_mode: 2; - unsigned char bios_drive_number: 1; - unsigned char tfr_port: 2; -}; - -/* Used to store configuration info read from config i/o registers. Most of - this is not used yet, but might as well save it. */ -struct config { - unsigned short port_address; - const void *bios_segment; - unsigned char interrupt: 4; - unsigned char dma_channel: 3; - unsigned char ha_scsi_id: 3; - unsigned char heads: 6; - unsigned char sectors: 6; - unsigned char bios_drive_number: 1; -}; - -/* MailBox SCSI Command Packet. Basic command structure for communicating - with controller. */ -struct mscp { - unsigned char opcode: 3; /* type of command */ - unsigned char xdir: 2; /* data transfer direction */ - unsigned char dcn: 1; /* disable disconnect */ - unsigned char ca: 1; /* use cache (if available) */ - unsigned char sg: 1; /* scatter/gather operation */ - unsigned char target_id: 3; /* target SCSI id */ - unsigned char ch_no: 2; /* SCSI channel (always 0 for 14f) */ - unsigned char lun: 3; /* logical unit number */ - Longword transfer_data; /* transfer data pointer */ - Longword transfer_data_length; /* length in bytes */ - Longword command_link; /* for linking command chains */ - unsigned char scsi_command_link_id; /* identifies command in chain */ - unsigned char number_of_sg_list; /* (if sg is set) 8 bytes per list */ - unsigned char length_of_sense_byte; - unsigned char length_of_scsi_cdbs; /* 6, 10, or 12 */ - unsigned char scsi_cdbs[12]; /* SCSI commands */ - unsigned char adapter_status; /* non-zero indicates HA error */ - unsigned char target_status; /* non-zero indicates target error */ - Longword sense_data; -}; - -/* Allowed BIOS base addresses for 14f (NULL indicates reserved) */ -static const void *const bios_segment_table[8] = { - NULL, (void *)0xC4000, (void *)0xC8000, (void *)0xCC000, - (void *)0xD0000, (void *)0xD4000, (void *)0xD8000, (void *)0xDC000, -}; - -/* Allowed IRQs for 14f */ -static const unsigned char interrupt_table[4] = { 15, 14, 11, 10 }; - -/* Allowed DMA channels for 14f (0 indicates reserved) */ -static const unsigned char dma_channel_table[4] = { 5, 6, 7, 0 }; - -/* Head/sector mappings allowed by 14f */ -static const struct { - unsigned char heads; - unsigned char sectors; -} mapping_table[4] = { { 16, 63 }, { 64, 32 }, { 64, 63 }, { 0, 0 } }; - -/* Config info */ -static struct config config; - -/* Our index in the host adapter array maintained by higher-level driver */ -static int host_number; - -/* PORT_ADDRESS is first port address used for i/o of messages. */ -#ifdef PORT_OVERRIDE -# define PORT_ADDRESS PORT_OVERRIDE -#else -# define PORT_ADDRESS (config.port_address) -#endif - -static volatile int aborted = 0; - -#ifndef PORT_OVERRIDE -static const unsigned short ultrastor_ports[] = { - 0x330, 0x340, 0x310, 0x230, 0x240, 0x210, 0x130, 0x140, -}; -#endif - -void ultrastor_interrupt(int cpl); - -static void (*ultrastor_done)(int, int) = 0; - -static const struct { - const char *signature; - size_t offset; - size_t length; -} signatures[] = { - { "SBIOS 1.01 COPYRIGHT (C) UltraStor Corporation,1990-1992.", 0x10, 57 }, -}; - -int ultrastor_14f_detect(int hostnum) -{ - size_t i; - unsigned char in_byte; - struct config_1 config_1; - struct config_2 config_2; - -#if (ULTRASTOR_DEBUG & UD_DETECT) - printk("US14F: detect: called\n"); -#endif - -#ifndef PORT_OVERRIDE - PORT_ADDRESS = 0; - for (i = 0; i < ARRAY_SIZE(ultrastor_ports); i++) { - PORT_ADDRESS = ultrastor_ports[i]; -#endif - -#if (ULTRASTOR_DEBUG & UD_DETECT) - printk("US14F: detect: testing port address %03X\n", PORT_ADDRESS); -#endif - - in_byte = inb(PRODUCT_ID(PORT_ADDRESS + 0)); - if (in_byte != US14F_PRODUCT_ID_0) { -#if (ULTRASTOR_DEBUG & UD_DETECT) -# ifdef PORT_OVERRIDE - printk("US14F: detect: wrong product ID 0 - %02X\n", in_byte); -# else - printk("US14F: detect: no adapter at port %03X", PORT_ADDRESS); -# endif -#endif -#ifdef PORT_OVERRIDE - return FALSE; -#else - continue; -#endif - } - in_byte = inb(PRODUCT_ID(PORT_ADDRESS + 1)); - /* Only upper nibble is defined for Product ID 1 */ - if ((in_byte & 0xF0) != US14F_PRODUCT_ID_1) { -#if (ULTRASTOR_DEBUG & UD_DETECT) -# ifdef PORT_OVERRIDE - printk("US14F: detect: wrong product ID 1 - %02X\n", in_byte); -# else - printk("US14F: detect: no adapter at port %03X", PORT_ADDRESS); -# endif -#endif -#ifdef PORT_OVERRIDE - return FALSE; -#else - continue; -#endif - } -#ifndef PORT_OVERRIDE - break; - } - if (i == ARRAY_SIZE(ultrastor_ports)) { -# if (ULTRASTOR_DEBUG & UD_DETECT) - printk("US14F: detect: no port address found!\n"); -# endif - return FALSE; - } -#endif - -#if (ULTRASTOR_DEBUG & UD_DETECT) - printk("US14F: detect: adapter found at port address %03X\n", - PORT_ADDRESS); -#endif - - /* All above tests passed, must be the right thing. Get some useful - info. */ - *(char *)&config_1 = inb(CONFIG(PORT_ADDRESS + 0)); - *(char *)&config_2 = inb(CONFIG(PORT_ADDRESS + 1)); - config.bios_segment = bios_segment_table[config_1.bios_segment]; - config.interrupt = interrupt_table[config_1.interrupt]; - config.dma_channel = dma_channel_table[config_1.dma_channel]; - config.ha_scsi_id = config_2.ha_scsi_id; - config.heads = mapping_table[config_2.mapping_mode].heads; - config.sectors = mapping_table[config_2.mapping_mode].sectors; - config.bios_drive_number = config_2.bios_drive_number; - - /* To verify this card, we simply look for the UltraStor SCSI from the - BIOS version notice. */ - if (config.bios_segment != NULL) { - int found = 0; - - for (i = 0; !found && i < ARRAY_SIZE(signatures); i++) - if (memcmp((char *)config.bios_segment + signatures[i].offset, - signatures[i].signature, signatures[i].length)) - found = 1; - if (!found) - config.bios_segment = NULL; - } - if (!config.bios_segment) { -#if (ULTRASTOR_DEBUG & UD_DETECT) - printk("US14F: detect: not detected.\n"); -#endif - return FALSE; - } - - /* Final consistancy check, verify previous info. */ - if (!config.dma_channel || !(config_2.tfr_port & 0x2)) { -#if (ULTRASTOR_DEBUG & UD_DETECT) - printk("US14F: detect: consistancy check failed\n"); -#endif - return FALSE; - } - - /* If we were TRULY paranoid, we could issue a host adapter inquiry - command here and verify the data returned. But frankly, I'm - exhausted! */ - - /* Finally! Now I'm satisfied... */ -#if (ULTRASTOR_DEBUG & UD_DETECT) - printk("US14F: detect: detect succeeded\n" - " Port address: %03X\n" - " BIOS segment: %05X\n" - " Interrupt: %u\n" - " DMA channel: %u\n" - " H/A SCSI ID: %u\n", - PORT_ADDRESS, config.bios_segment, config.interrupt, - config.dma_channel, config.ha_scsi_id); -#endif - host_number = hostnum; - scsi_hosts[hostnum].this_id = config.ha_scsi_id; -#if USE_QUEUECOMMAND - { - struct sigaction sa; - sa.sa_handler = ultrastor_interrupt; - sa.sa_flags = SA_INTERRUPT; - sa.sa_mask = 0; - sa.sa_restorer = NULL; - if (irqaction(config.interrupt,&sa)) { - printk("unable to get IRQ%d for ultrastor controller\n",config.interrupt); - return FALSE; - } - } -#endif - return TRUE; -} - -const char *ultrastor_14f_info(void) -{ - return "UltraStor 14F SCSI driver version " - VERSION - " by David B. Gentzel\n"; -} - -static struct mscp mscp = { - OP_SCSI, DTD_SCSI, FALSE, TRUE, FALSE /* This stuff doesn't change */ -}; - -int ultrastor_14f_queuecommand(unsigned char target, const void *cmnd, - void *buff, int bufflen, void (*done)(int, int)) -{ - unsigned char in_byte; - -#if (ULTRASTOR_DEBUG & UD_COMMAND) - printk("US14F: queuecommand: called\n"); -#endif - - /* Skip first (constant) byte */ - memset((char *)&mscp + 1, 0, sizeof (struct mscp) - 1); - mscp.target_id = target; - /* mscp.lun = ???; */ - mscp.transfer_data = *(Longword *)&buff; - mscp.transfer_data_length = *(Longword *)&bufflen, - mscp.length_of_scsi_cdbs = ((*(unsigned char *)cmnd <= 0x1F) ? 6 : 10); - memcpy(mscp.scsi_cdbs, cmnd, mscp.length_of_scsi_cdbs); - - /* Find free OGM slot (OGMINT bit is 0) */ - do - in_byte = inb_p(LCL_DOORBELL_INTR(PORT_ADDRESS)); - while (!aborted && (in_byte & 1)); - if (aborted) - /* ??? is this right? */ - return (aborted << 16); - - /* Store pointer in OGM address bytes */ - outb_p(BYTE(&mscp, 0), OGM_DATA_PTR(PORT_ADDRESS + 0)); - outb_p(BYTE(&mscp, 1), OGM_DATA_PTR(PORT_ADDRESS + 1)); - outb_p(BYTE(&mscp, 2), OGM_DATA_PTR(PORT_ADDRESS + 2)); - outb_p(BYTE(&mscp, 3), OGM_DATA_PTR(PORT_ADDRESS + 3)); - - /* Issue OGM interrupt */ - outb_p(0x1, LCL_DOORBELL_INTR(PORT_ADDRESS)); - - ultrastor_done = done; - -#if (ULTRASTOR_DEBUG & UD_COMMAND) - printk("US14F: queuecommand: returning\n"); -#endif - - return 0; -} - -#if !USE_QUEUECOMMAND -int ultrastor_14f_command(unsigned char target, const void *cmnd, - void *buff, int bufflen) -{ - unsigned char in_byte; - -#if (ULTRASTOR_DEBUG & UD_COMMAND) - printk("US14F: command: called\n"); -#endif - - (void)ultrastor_14f_queuecommand(target, cmnd, buff, bufflen, 0); - - /* Wait for ICM interrupt */ - do - in_byte = inb_p(SYS_DOORBELL_INTR(PORT_ADDRESS)); - while (!aborted && !(in_byte & 1)); - if (aborted) - /* ??? is this right? */ - return (aborted << 16); - - /* Clean ICM slot (set ICMINT bit to 0) */ - outb_p(0x1, SYS_DOORBELL_INTR(PORT_ADDRESS)); - -#if (ULTRASTOR_DEBUG & UD_COMMAND) - printk("US14F: command: returning %08X\n", - (mscp.adapter_status << 16) | mscp.target_status); -#endif - - /* ??? not right, but okay for now? */ - return (mscp.adapter_status << 16) | mscp.target_status; -} -#endif - -int ultrastor_14f_abort(int code) -{ - aborted = (code ? code : DID_ABORT); - return 0; -} - -int ultrastor_14f_reset(void) -{ - unsigned char in_byte; - -#if (ULTRASTOR_DEBUG & UD_RESET) - printk("US14F: reset: called\n"); -#endif - - /* Issue SCSI BUS reset */ - outb_p(0x20, LCL_DOORBELL_INTR(PORT_ADDRESS)); - - /* Wait for completion... */ - do - in_byte = inb_p(LCL_DOORBELL_INTR(PORT_ADDRESS)); - while (in_byte & 0x20); - - aborted = DID_RESET; - -#if (ULTRASTOR_DEBUG & UD_RESET) - printk("US14F: reset: returning\n"); -#endif - return 0; -} - -#if USE_QUEUECOMMAND -void ultrastor_interrupt(int cpl) -{ - if (ultrastor_done == 0) { - printk("US14F: unexpected ultrastor interrupt\n\r"); - /* ??? Anything else we should do here? Reset? */ - return; - } - printk("US14F: got an ultrastor interrupt: %u\n\r", - (mscp.adapter_status << 16) | mscp.target_status); - ultrastor_done(host_number, - (mscp.adapter_status << 16) | mscp.target_status); - ultrastor_done = 0; -} -#endif - -#endif diff --git a/kernel/blk_drv/scsi/ultrastor.h b/kernel/blk_drv/scsi/ultrastor.h deleted file mode 100644 index dfe34ee947b2..000000000000 --- a/kernel/blk_drv/scsi/ultrastor.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * ultrastor.c (C) 1991 David B. Gentzel - * Low-level scsi driver for UltraStor 14F - * by David B. Gentzel, Whitfield Software Services, Carnegie, PA - * (gentzel@nova.enet.dec.com) - * Thanks to UltraStor for providing the necessary documentation - */ - -#ifndef _ULTRASTOR_H -#define _ULTRASTOR_H - -/* ??? These don't really belong here */ -#ifndef TRUE -# define TRUE 1 -#endif -#ifndef FALSE -# define FALSE 0 -#endif - -/* ??? This should go eventually, once the queueing bug is fixed */ -#define USE_QUEUECOMMAND FALSE - -int ultrastor_14f_detect(int); -const char *ultrastor_14f_info(void); -int ultrastor_14f_queuecommand(unsigned char target, const void *cmnd, - void *buff, int bufflen, - void (*done)(int, int)); -#if !USE_QUEUECOMMAND -int ultrastor_14f_command(unsigned char target, const void *cmnd, - void *buff, int bufflen); -#endif -int ultrastor_14f_abort(int); -int ultrastor_14f_reset(void); - -#if !USE_QUEUECOMMAND -#define ULTRASTOR_14F \ - { "UltraStor 14F", ultrastor_14f_detect, ultrastor_14f_info, \ - ultrastor_14f_command, 0, ultrastor_14f_abort, ultrastor_14f_reset, \ - FALSE, 0, 0 } -#else -#define ULTRASTOR_14F \ - { "UltraStor 14F", ultrastor_14f_detect, ultrastor_14f_info, 0, \ - ultrastor_14f_queuecommand, ultrastor_14f_abort, ultrastor_14f_reset, \ - TRUE, 0, 0 } -#endif - -#define UD_DETECT 0x1 -#define UD_COMMAND 0x2 -#define UD_RESET 0x4 - -#ifdef ULTRASTOR_PRIVATE - -/* #define PORT_OVERRIDE 0x330 */ - -/* Port addresses (relative to the base address) */ -#define LCL_DOORBELL_MASK(port) ((port) + 0x0) -#define LCL_DOORBELL_INTR(port) ((port) + 0x1) -#define SYS_DOORBELL_MASK(port) ((port) + 0x2) -#define SYS_DOORBELL_INTR(port) ((port) + 0x3) -#define PRODUCT_ID(port) ((port) + 0x4) -#define CONFIG(port) ((port) + 0x6) -#define OGM_DATA_PTR(port) ((port) + 0x8) -#define ICM_DATA_PTR(port) ((port) + 0xC) - -/* Values for the PRODUCT_ID ports for the 14F */ -#define US14F_PRODUCT_ID_0 0x56 -#define US14F_PRODUCT_ID_1 0x40 /* NOTE: Only upper nibble is used */ - -/* MSCP field values */ - -/* Opcode */ -#define OP_HOST_ADAPTER 0x1 -#define OP_SCSI 0x2 -#define OP_RESET 0x4 - -/* Date Transfer Direction */ -#define DTD_SCSI 0x0 -#define DTD_IN 0x1 -#define DTD_OUT 0x2 -#define DTD_NONE 0x3 - -/* Host Adapter command subcodes */ -#define HA_CMD_INQUIRY 0x1 -#define HA_CMD_SELF_DIAG 0x2 -#define HA_CMD_READ_BUFF 0x3 -#define HA_CMD_WRITE_BUFF 0x4 - -#endif - -#endif diff --git a/kernel/chr_drv/Makefile b/kernel/chr_drv/Makefile index 83fffae88ef1..8049f2fcca96 100644 --- a/kernel/chr_drv/Makefile +++ b/kernel/chr_drv/Makefile @@ -9,22 +9,31 @@ # parent makes.. # +AR =ar +AS =as +LD =ld +LDFLAGS =-s -x +CC =gcc -nostdinc -I../../include +CPP =cpp -nostdinc -I../../include + .c.s: - $(CC) $(CFLAGS) -S $< + $(CC) $(CFLAGS) \ + -S -o $*.s $< .s.o: $(AS) -c -o $*.o $< .c.o: - $(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) \ + -c -o $*.o $< -OBJS = tty_io.o console.o keyboard.o serial.o \ - tty_ioctl.o pty.o lp.o vt.o mem.o mouse.o +OBJS = tty_io.o console.o keyboard.o serial.o rs_io.o \ + tty_ioctl.o pty.o lp.o vt.o mem.o chr_drv.a: $(OBJS) $(AR) rcs chr_drv.a $(OBJS) sync -keyboard.o: keyboard.c - $(CC) $(CFLAGS) $(KEYBOARD) -c -o keyboard.o keyboard.c +keyboard.s: keyboard.S + $(CPP) $(KEYBOARD) -traditional keyboard.S -o keyboard.s clean: rm -f core *.o *.a tmp_make keyboard.s @@ -32,82 +41,61 @@ clean: dep: sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - for i in *.c;do $(CPP) -M -DKBD_FINNISH $$i;done >> tmp_make + (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ + $(CPP) -M $$i;done) >> tmp_make cp tmp_make Makefile ### Dependencies: -console.o : console.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/tty.h \ - /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/linux/config.h \ - /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \ - /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/linux/string.h /usr/src/linux/include/errno.h /usr/src/linux/include/sys/kd.h \ +console.s console.o : console.c ../../include/linux/sched.h ../../include/linux/head.h \ + ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \ + ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h ../../include/linux/timer.h ../../include/linux/tty.h \ + ../../include/termios.h ../../include/linux/config.h ../../include/linux/config_rel.h \ + ../../include/linux/config_ver.h ../../include/asm/io.h ../../include/asm/system.h \ + ../../include/asm/segment.h ../../include/linux/string.h ../../include/errno.h \ + ../../include/sys/kd.h vt_kern.h +lp.s lp.o : lp.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \ + ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \ + ../../include/linux/mm.h ../../include/linux/kernel.h ../../include/signal.h \ + ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \ + ../../include/linux/lp.h ../../include/errno.h ../../include/asm/io.h ../../include/asm/segment.h +mem.s mem.o : mem.c ../../include/errno.h ../../include/sys/types.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \ + ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h ../../include/linux/tty.h ../../include/termios.h \ + ../../include/asm/segment.h ../../include/asm/io.h +pty.s pty.o : pty.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \ + ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \ + ../../include/linux/mm.h ../../include/linux/kernel.h ../../include/signal.h \ + ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \ + ../../include/linux/tty.h ../../include/termios.h ../../include/asm/system.h \ + ../../include/asm/io.h +serial.s serial.o : serial.c ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \ + ../../include/sys/types.h ../../include/sys/dirent.h ../../include/limits.h \ + ../../include/linux/mm.h ../../include/linux/kernel.h ../../include/signal.h \ + ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \ + ../../include/linux/timer.h ../../include/linux/tty.h ../../include/termios.h \ + ../../include/asm/system.h ../../include/asm/io.h +tty_io.s tty_io.o : tty_io.c ../../include/linux/ctype.h ../../include/errno.h ../../include/signal.h \ + ../../include/sys/types.h ../../include/unistd.h ../../include/sys/stat.h ../../include/sys/time.h \ + ../../include/time.h ../../include/sys/times.h ../../include/sys/utsname.h ../../include/sys/param.h \ + ../../include/sys/resource.h ../../include/utime.h ../../include/fcntl.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \ + ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/linux/tty.h ../../include/termios.h ../../include/asm/segment.h \ + ../../include/asm/system.h +tty_ioctl.s tty_ioctl.o : tty_ioctl.c ../../include/errno.h ../../include/termios.h ../../include/sys/types.h \ + ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \ + ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h ../../include/linux/tty.h ../../include/asm/io.h \ + ../../include/asm/segment.h ../../include/asm/system.h +vt.s vt.o : vt.c ../../include/errno.h ../../include/sys/types.h ../../include/sys/kd.h \ + ../../include/sys/vt.h ../../include/asm/io.h ../../include/asm/segment.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \ + ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h ../../include/linux/tty.h ../../include/termios.h \ vt_kern.h -keyboard.o : keyboard.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ctype.h /usr/src/linux/include/linux/tty.h \ - /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/asm/io.h -lp.o : lp.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/lp.h /usr/src/linux/include/errno.h \ - /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h -mem.o : mem.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \ - /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/asm/io.h -pty.o : pty.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \ - /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/linux/fcntl.h \ - /usr/src/linux/include/asm/io.h -serial.o : serial.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h \ - /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \ - /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h -tty_io.o : tty_io.c /usr/src/linux/include/errno.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/fcntl.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \ - /usr/src/linux/include/linux/ctype.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/sys/kd.h vt_kern.h -tty_ioctl.o : tty_ioctl.c /usr/src/linux/include/errno.h /usr/src/linux/include/termios.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \ - /usr/src/linux/include/asm/segment.h -vt.o : vt.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/kd.h /usr/src/linux/include/sys/vt.h \ - /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \ - /usr/src/linux/include/linux/timer.h vt_kern.h diff --git a/kernel/chr_drv/console.c b/kernel/chr_drv/console.c index c440e7aa26fb..01421e5a5769 100644 --- a/kernel/chr_drv/console.c +++ b/kernel/chr_drv/console.c @@ -8,7 +8,7 @@ * console.c * * This module implements the console io functions - * 'long con_init(long)' + * 'void con_init(void)' * 'void con_write(struct tty_queue * queue)' * Hopefully this will be a rather complete VT102 implementation. * @@ -30,8 +30,6 @@ * */ -#define KEYBOARD_IRQ 1 - #include #include #include @@ -48,6 +46,19 @@ #include #include "vt_kern.h" +#define DEF_TERMIOS \ +(struct termios) { \ + ICRNL, \ + OPOST | ONLCR, \ + 0, \ + IXON | ISIG | ICANON | ECHO | ECHOCTL | ECHOKE, \ + 0, \ + INIT_C_CC \ +} + +static void blank_screen(void); +static void unblank_screen(void); + /* * These are set up by the setup-routine at boot-time: */ @@ -69,17 +80,16 @@ #define NPAR 16 +int NR_CONSOLES = 0; + extern void vt_init(void); -extern void keyboard_interrupt(int cpl); +extern void keyboard_interrupt(void); extern void set_leds(void); extern unsigned char kapplic; -extern unsigned char ckmode; -extern unsigned char krepeat; extern unsigned char kleds; extern unsigned char kmode; extern unsigned char kraw; extern unsigned char ke0; -extern unsigned char lfnlmode; unsigned long video_num_columns; /* Number of text columns */ unsigned long video_num_lines; /* Number of test lines */ @@ -91,65 +101,40 @@ static unsigned long video_size_row; /* Bytes per row */ static unsigned char video_page; /* Initial video page */ static unsigned short video_port_reg; /* Video register select port */ static unsigned short video_port_val; /* Video register value port */ -static int can_do_color = 0; +static int can_do_colour = 0; static struct { - unsigned short vc_video_erase_char; /* Background erase character */ - unsigned char vc_attr; /* Current attributes */ - unsigned char vc_def_color; /* Default colors */ - unsigned char vc_color; /* Foreground & background */ - unsigned char vc_s_color; /* Saved foreground & background */ - unsigned char vc_ulcolor; /* Colour for underline mode */ - unsigned char vc_halfcolor; /* Colour for half intensity mode */ + unsigned short vc_video_erase_char; + unsigned char vc_attr; + unsigned char vc_def_attr; + int vc_bold_attr; + unsigned long vc_ques; + unsigned long vc_state; + char * vc_restate; + unsigned long vc_checkin; unsigned long vc_origin; /* Used for EGA/VGA fast scroll */ unsigned long vc_scr_end; /* Used for EGA/VGA fast scroll */ unsigned long vc_pos; unsigned long vc_x,vc_y; unsigned long vc_top,vc_bottom; - unsigned long vc_state; unsigned long vc_npar,vc_par[NPAR]; unsigned long vc_video_mem_start; /* Start of video RAM */ unsigned long vc_video_mem_end; /* End of video RAM (sort of) */ - unsigned long vc_saved_x; - unsigned long vc_saved_y; - /* mode flags */ - unsigned long vc_kbdapplic : 1; /* Application keyboard */ - unsigned long vc_charset : 1; /* Character set G0 / G1 */ - unsigned long vc_s_charset : 1; /* Saved character set */ - unsigned long vc_decckm : 1; /* Cursor Keys Mode */ - unsigned long vc_decscnm : 1; /* Screen Mode */ - unsigned long vc_decom : 1; /* Origin Mode */ - unsigned long vc_decawm : 1; /* Autowrap Mode */ - unsigned long vc_decarm : 1; /* Autorepeat Mode */ - unsigned long vc_deccm : 1; /* Cursor Visible */ - unsigned long vc_decim : 1; /* Insert Mode */ - unsigned long vc_lnm : 1; /* Line feed New line Mode */ - /* attribute flags */ - unsigned long vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */ - unsigned long vc_underline : 1; - unsigned long vc_blink : 1; - unsigned long vc_reverse : 1; - unsigned long vc_s_intensity : 2; /* saved rendition */ - unsigned long vc_s_underline : 1; - unsigned long vc_s_blink : 1; - unsigned long vc_s_reverse : 1; - /* misc */ - unsigned long vc_ques : 1; - unsigned long vc_need_wrap : 1; - unsigned long vc_tab_stop[5]; /* Tab stops. 160 columns. */ + unsigned int vc_saved_x; + unsigned int vc_saved_y; + unsigned int vc_iscolor; + unsigned char vc_kbdapplic; + unsigned char vc_kbdleds; unsigned char vc_kbdmode; + unsigned char vc_kbdraw; + unsigned char vc_kbde0; char * vc_translate; - char * vc_G0_charset; - char * vc_G1_charset; - char * vc_saved_G0; - char * vc_saved_G1; - /* additional information is in vt_kern.h */ -} vc_cons [NR_CONSOLES]; +} vc_cons [MAX_CONSOLES]; #define MEM_BUFFER_SIZE (2*80*50*8) -unsigned short *vc_scrbuf[NR_CONSOLES]; -static unsigned short * vc_scrmembuf; +unsigned short *vc_scrbuf[MAX_CONSOLES]; +unsigned short vc_scrmembuf[MEM_BUFFER_SIZE/2]; static int console_blanked = 0; #define origin (vc_cons[currcons].vc_origin) @@ -160,6 +145,8 @@ static int console_blanked = 0; #define x (vc_cons[currcons].vc_x) #define y (vc_cons[currcons].vc_y) #define state (vc_cons[currcons].vc_state) +#define restate (vc_cons[currcons].vc_restate) +#define checkin (vc_cons[currcons].vc_checkin) #define npar (vc_cons[currcons].vc_npar) #define par (vc_cons[currcons].vc_par) #define ques (vc_cons[currcons].vc_ques) @@ -167,61 +154,27 @@ static int console_blanked = 0; #define saved_x (vc_cons[currcons].vc_saved_x) #define saved_y (vc_cons[currcons].vc_saved_y) #define translate (vc_cons[currcons].vc_translate) -#define G0_charset (vc_cons[currcons].vc_G0_charset) -#define G1_charset (vc_cons[currcons].vc_G1_charset) -#define saved_G0 (vc_cons[currcons].vc_saved_G0) -#define saved_G1 (vc_cons[currcons].vc_saved_G1) #define video_mem_start (vc_cons[currcons].vc_video_mem_start) #define video_mem_end (vc_cons[currcons].vc_video_mem_end) -#define video_erase_char (vc_cons[currcons].vc_video_erase_char) -#define decckm (vc_cons[currcons].vc_decckm) -#define decscnm (vc_cons[currcons].vc_decscnm) -#define decom (vc_cons[currcons].vc_decom) -#define decawm (vc_cons[currcons].vc_decawm) -#define decarm (vc_cons[currcons].vc_decarm) -#define deccm (vc_cons[currcons].vc_deccm) -#define decim (vc_cons[currcons].vc_decim) -#define lnm (vc_cons[currcons].vc_lnm) +#define def_attr (vc_cons[currcons].vc_def_attr) +#define video_erase_char (vc_cons[currcons].vc_video_erase_char) +#define iscolor (vc_cons[currcons].vc_iscolor) #define kbdapplic (vc_cons[currcons].vc_kbdapplic) -#define need_wrap (vc_cons[currcons].vc_need_wrap) -#define color (vc_cons[currcons].vc_color) -#define s_color (vc_cons[currcons].vc_s_color) -#define def_color (vc_cons[currcons].vc_def_color) -#define foreground (color & 0x0f) -#define background (color & 0xf0) -#define charset (vc_cons[currcons].vc_charset) -#define s_charset (vc_cons[currcons].vc_s_charset) -#define intensity (vc_cons[currcons].vc_intensity) -#define underline (vc_cons[currcons].vc_underline) -#define blink (vc_cons[currcons].vc_blink) -#define reverse (vc_cons[currcons].vc_reverse) -#define s_intensity (vc_cons[currcons].vc_s_intensity) -#define s_underline (vc_cons[currcons].vc_s_underline) -#define s_blink (vc_cons[currcons].vc_s_blink) -#define s_reverse (vc_cons[currcons].vc_s_reverse) -#define ulcolor (vc_cons[currcons].vc_ulcolor) -#define halfcolor (vc_cons[currcons].vc_halfcolor) #define kbdmode (vc_cons[currcons].vc_kbdmode) -#define tab_stop (vc_cons[currcons].vc_tab_stop) -#define kbdraw (vt_cons[currcons].vc_kbdraw) -#define kbdleds (vt_cons[currcons].vc_kbdleds) -#define vtmode (vt_cons[currcons].vt_mode) +#define kbdraw (vc_cons[currcons].vc_kbdraw) +#define kbde0 (vc_cons[currcons].vc_kbde0) +#define kbdleds (vc_cons[currcons].vc_kbdleds) -#define SET(mode,fg,v) \ - (mode) = (v); \ - if (currcons == fg_console) \ - (fg) = (v) - -int blankinterval = 10*60*HZ; +int blankinterval = 5*60*HZ; static int screen_size = 0; static void sysbeep(void); /* - * this is what the terminal answers to a ESC-Z or csi0c query. + * this is what the terminal answers to a ESC-Z or csi0c + * query (= vt100 response). */ -#define VT100ID "\033[?1;2c" -#define VT102ID "\033[?6c" +#define RESPONSE "\033[?1;2c" static char * translations[] = { /* 8-bit Latin-1 mapped to the PC charater set: '\0' means non-printable */ @@ -243,8 +196,8 @@ static char * translations[] = { "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" " !\"#$%&'()*+,-./0123456789:;<=>?" "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ " - "\004\261\007\007\007\007\370\361\040\007\331\277\332\300\305\007" - "\007\304\007\007\303\264\301\302\263\007\007\007\007\007\234\0" + "\004\261\007\007\007\007\370\361\007\007\275\267\326\323\327\304" + "\304\304\304\304\307\266\320\322\272\363\362\343\007\234\007\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\040\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376" @@ -252,70 +205,27 @@ static char * translations[] = { "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376" "\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341" "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213" - "\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230", -/* IBM grapgics: minimal translations (CR, LF, LL and ESC) */ - "\000\001\002\003\004\005\006\007\010\011\000\013\000\000\016\017" - "\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037" - "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057" - "\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077" - "\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117" - "\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137" - "\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157" - "\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177" - "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217" - "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237" - "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257" - "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277" - "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317" - "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337" - "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357" - "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377" + "\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230" }; #define NORM_TRANS (translations[0]) #define GRAF_TRANS (translations[1]) -#define NULL_TRANS (translations[2]) - -static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, - 8,12,10,14, 9,13,11,15 }; -/* - * gotoxy() must verify all boundaries, because the arguments - * might also be negative. If the given position is out of - * bounds, the cursor is placed at the nearest margin. - */ -static void gotoxy(int currcons, int new_x, int new_y) +/* NOTE! gotoxy thinks x==video_num_columns is ok */ +static inline void gotoxy(int currcons, unsigned int new_x,unsigned int new_y) { - int max_y; - - if (new_x < 0) - x = 0; - else - if (new_x >= video_num_columns) - x = video_num_columns - 1; - else - x = new_x; - if (decom) { - new_y += top; - max_y = bottom; - } else - max_y = video_num_lines; - if (new_y < 0) - y = 0; - else - if (new_y >= max_y) - y = max_y - 1; - else - y = new_y; + if (new_x > video_num_columns || new_y >= video_num_lines) + return; + x = new_x; + y = new_y; pos = origin + y*video_size_row + (x<<1); - need_wrap = 0; } -static void set_origin(int currcons) +static inline void set_origin(int currcons) { if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM) return; - if (currcons != fg_console || console_blanked || vtmode == KD_GRAPHICS) + if (currcons != fg_console) return; cli(); outb_p(12, video_port_reg); @@ -406,7 +316,6 @@ static void lf(int currcons) return; } else scrup(currcons,top,bottom); - need_wrap = 0; } static void ri(int currcons) @@ -417,31 +326,20 @@ static void ri(int currcons) return; } else scrdown(currcons,top,bottom); - need_wrap = 0; } -static inline void cr(int currcons) +static void cr(int currcons) { pos -= x<<1; - need_wrap = x = 0; + x=0; } -static inline void bs(int currcons) -{ - if (x) { - pos -= 2; - x--; - need_wrap = 0; - } -} - -static inline void del(int currcons) +static void del(int currcons) { if (x) { pos -= 2; x--; *(unsigned short *)pos = video_erase_char; - need_wrap = 0; } } @@ -456,7 +354,7 @@ static void csi_J(int currcons, int vpar) start = pos; break; case 1: /* erase from start to cursor */ - count = ((pos-origin)>>1)+1; + count = (pos-origin)>>1; start = origin; break; case 2: /* erase whole display */ @@ -472,7 +370,6 @@ static void csi_J(int currcons, int vpar) ::"c" (count), "D" (start),"a" (video_erase_char) :"cx","di"); - need_wrap = 0; } static void csi_K(int currcons, int vpar) @@ -482,12 +379,14 @@ static void csi_K(int currcons, int vpar) switch (vpar) { case 0: /* erase from cursor to end of line */ + if (x>=video_num_columns) + return; count = video_num_columns-x; start = pos; break; case 1: /* erase from start of line to cursor */ start = pos - (x<<1); - count = x+1; + count = (x> 4) | (attr << 4)) & 0x77); - if (blink) - attr ^= 0x80; - if (intensity == 2) - attr ^= 0x08; - if (!can_do_color) { - if (underline) - attr = (attr & 0xf8) | 0x01; - else if (intensity == 0) - attr = (attr & 0xf0) | 0x08; - } - if (decscnm) - video_erase_char = ((color & 0x88) | (((color >> 4) | - (color << 4)) & 0x77) << 8) | ' '; - else - video_erase_char = (color << 8) | ' '; -} - -static void default_attr(int currcons) { - intensity = 1; - underline = 0; - reverse = 0; - blink = 0; - color = def_color; -} - -static void csi_m(int currcons) +static void csi_m(int currcons ) { int i; + static int conv_table[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; for (i=0;i<=npar;i++) switch (par[i]) { - case 0: /* all attributes off */ - default_attr(currcons); - break; - case 1: - intensity = 2; - break; - case 2: - intensity = 0; - break; - case 4: - underline = 1; - break; - case 5: - blink = 1; - break; - case 7: - reverse = 1; - break; - case 21: - case 22: - intensity = 1; - break; - case 24: - underline = 0; - break; - case 25: - blink = 0; - break; - case 27: - reverse = 0; - break; - case 39: - color = (def_color & 0x0f) | background; - break; - case 49: - color = (def_color & 0xf0) | foreground; - break; + case 0: attr=def_attr;break; /* default */ + case 1: attr=(iscolor?attr|0x08:attr|0x0f);break; /* bold */ + /*case 4: attr=attr|0x01;break;*/ /* underline */ + case 4: /* bold */ + if (!iscolor) + attr |= 0x01; + else + { /* check if forground == background */ + if (vc_cons[currcons].vc_bold_attr != -1) + attr = (vc_cons[currcons].vc_bold_attr&0x0f)|(0xf0&(attr)); + else + { short newattr = (attr&0xf0)|(0xf&(~attr)); + attr = ((newattr&0xf)==((attr>>4)&0xf)? + (attr&0xf0)|(((attr&0xf)+1)%0xf): + newattr); + } + } + break; + case 5: attr=attr|0x80;break; /* blinking */ + case 7: attr=(attr&0x88)|((attr<<4)&0x70)| + ((attr>>4)&0x07);break; /* negative */ + case 22: attr=attr&0xf7;break; /* not bold */ + case 24: attr=attr&0xfe;break; /* not underline */ + case 25: attr=attr&0x7f;break; /* not blinking */ + case 27: attr=def_attr;break; /* positive image */ + case 39: attr=(attr & 0xf8)|(def_attr & 0x07); break; + case 49: attr=(attr & 0x8f)|(def_attr & 0x70); break; default: - if (par[i] >= 30 && par[i] <= 37) - color = color_table[par[i]-30] - | background; - else if (par[i] >= 40 && par[i] <= 47) - color = (color_table[par[i]-40]<<4) - | foreground; + if (!can_do_colour) + break; + iscolor = 1; + if ((par[i]>=30) && (par[i]<=37)) + attr = (attr & 0xf8) | conv_table[par[i]-30]; + else /* Background color */ + if ((par[i]>=40) && (par[i]<=47)) + attr = (attr & 0x8f) | (conv_table[par[i]-40]<<4); + else break; } - update_attr(currcons); +} + +static inline void set_cursor(int currcons) +{ + if (currcons != fg_console) + return; + cli(); + outb_p(14, video_port_reg); + outb_p(0xff&((pos-video_mem_base)>>9), video_port_val); + outb_p(15, video_port_reg); + outb_p(0xff&((pos-video_mem_base)>>1), video_port_val); + sti(); } static inline void hide_cursor(int currcons) @@ -607,149 +471,19 @@ static inline void hide_cursor(int currcons) outb_p(0xff&((scr_end-video_mem_base)>>1), video_port_val); } -static inline void set_cursor(int currcons) +static void respond(int currcons, struct tty_struct * tty) { - if (currcons != fg_console || console_blanked) - return; - cli(); - if (deccm) { - outb_p(14, video_port_reg); - outb_p(0xff&((pos-video_mem_base)>>9), video_port_val); - outb_p(15, video_port_reg); - outb_p(0xff&((pos-video_mem_base)>>1), video_port_val); - } else - hide_cursor(currcons); - sti(); -} + char * p = RESPONSE; -static void respond_string(char * p, int currcons, struct tty_struct * tty) -{ + cli(); while (*p) { - put_tty_queue(*p,tty->read_q); + PUTCH(*p,tty->read_q); p++; } + sti(); TTY_READ_FLUSH(tty); } -static void respond_num(unsigned int n, int currcons, struct tty_struct * tty) -{ - char buff[3]; - int i = 0; - - do { - buff[i++] = (n%10)+'0'; - n /= 10; - } while(n && i < 3); /* We'll take no chances */ - while (i--) { - put_tty_queue(buff[i],tty->read_q); - } - /* caller must flush */ -} - -static void cursor_report(int currcons, struct tty_struct * tty) -{ - put_tty_queue('\033', tty->read_q); - put_tty_queue('[', tty->read_q); - respond_num(y + (decom ? top+1 : 1), currcons, tty); - put_tty_queue(';', tty->read_q); - respond_num(x+1, currcons, tty); - put_tty_queue('R', tty->read_q); - TTY_READ_FLUSH(tty); -} - -static inline void status_report(int currcons, struct tty_struct * tty) -{ - respond_string("\033[0n", currcons, tty); /* Terminal ok */ -} - -static inline void respond_ID(int currcons, struct tty_struct * tty) -{ - respond_string(VT102ID, currcons, tty); -} - -static void invert_screen(int currcons) { - unsigned char *p; - - if (can_do_color) - for (p = (unsigned char *)origin+1; p < (unsigned char *)scr_end; p+=2) - *p = (*p & 0x88) | (((*p >> 4) | (*p << 4)) & 0x77); - else - for (p = (unsigned char *)origin+1; p < (unsigned char *)scr_end; p+=2) - *p ^= *p & 0x07 == 1 ? 0x70 : 0x77; -} - -static void set_mode(int currcons, int on_off) -{ - int i; - - for (i=0; i<=npar; i++) - if (ques) switch(par[i]) { /* DEC private modes set/reset */ - case 1: /* Cursor keys send ^[Ox/^[[x */ - SET(decckm,ckmode,on_off); - break; - case 3: /* 80/132 mode switch unimplemented */ - csi_J(currcons,2); - gotoxy(currcons,0,0); - break; - case 5: /* Inverted screen on/off */ - if (decscnm != on_off) { - decscnm = on_off; - invert_screen(currcons); - update_attr(currcons); - } - break; - case 6: /* Origin relative/absolute */ - decom = on_off; - gotoxy(currcons,0,0); - break; - case 7: /* Autowrap on/off */ - decawm = on_off; - break; - case 8: /* Autorepeat on/off */ - SET(decarm,krepeat,on_off); - break; - case 25: /* Cursor on/off */ - deccm = on_off; - set_cursor(currcons); - break; - } else switch(par[i]) { /* ANSI modes set/reset */ - case 4: /* Insert Mode on/off */ - decim = on_off; - break; - case 20: /* Lf, Enter == CrLf/Lf */ - SET(lnm,lfnlmode,on_off); - break; - } -} - -static void setterm_command(int currcons) -{ - switch(par[0]) { - case 1: /* set color for underline mode */ - if (can_do_color && par[1] < 16) { - ulcolor = color_table[par[1]]; - if (underline) - update_attr(currcons); - } - break; - case 2: /* set color for half intensity mode */ - if (can_do_color && par[1] < 16) { - halfcolor = color_table[par[1]]; - if (intensity == 0) - update_attr(currcons); - } - break; - case 8: /* store colors as defaults */ - def_color = attr; - default_attr(currcons); - update_attr(currcons); - break; - case 9: /* set blanking interval */ - blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ; - break; - } -} - static void insert_char(int currcons) { unsigned int i = x; @@ -762,13 +496,11 @@ static void insert_char(int currcons) old = tmp; p++; } - need_wrap = 0; } static void insert_line(int currcons) { scrdown(currcons,y,bottom); - need_wrap = 0; } static void delete_char(int currcons) @@ -776,18 +508,18 @@ static void delete_char(int currcons) unsigned int i = x; unsigned short * p = (unsigned short *) pos; + if (x >= video_num_columns) + return; while (++i < video_num_columns) { *p = *(p+1); p++; } *p = video_erase_char; - need_wrap = 0; } static void delete_line(int currcons) { scrup(currcons,y,bottom); - need_wrap = 0; } static void csi_at(int currcons, unsigned int nr) @@ -832,164 +564,82 @@ static void csi_M(int currcons, unsigned int nr) static void save_cur(int currcons) { - saved_x = x; - saved_y = y; - s_intensity = intensity; - s_underline = underline; - s_blink = blink; - s_reverse = reverse; - s_charset = charset; - s_color = color; - saved_G0 = G0_charset; - saved_G1 = G1_charset; + saved_x = x; + saved_y = y; } static void restore_cur(int currcons) { - gotoxy(currcons,saved_x,saved_y); - intensity = s_intensity; - underline = s_underline; - blink = s_blink; - reverse = s_reverse; - charset = s_charset; - color = s_color; - G0_charset = saved_G0; - G1_charset = saved_G1; - translate = charset ? G1_charset : G0_charset; - update_attr(currcons); - need_wrap = 0; + gotoxy(currcons, saved_x, saved_y); } -enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey, - EShash, ESsetG0, ESsetG1, ESignore }; -static void reset_terminal(int currcons, int do_clear) -{ - top = 0; - bottom = video_num_lines; - state = ESnormal; - ques = 0; - translate = NORM_TRANS; - G0_charset = NORM_TRANS; - G1_charset = GRAF_TRANS; - charset = 0; - need_wrap = 0; - - decscnm = 0; - decom = 0; - decawm = 1; - deccm = 1; - decim = 0; - - if (currcons == fg_console) { - krepeat = 1; - ckmode = 0; - kapplic = 0; - lfnlmode = 0; - kleds = 2; - kmode = 0; - set_leds(); - } else { - decarm = 1; - decckm = 0; - kbdapplic = 0; - lnm = 0; - kbdleds = 2; - kbdmode = 0; - } - - default_attr(currcons); - update_attr(currcons); - - tab_stop[0] = 0x01010100; - tab_stop[1] = - tab_stop[2] = - tab_stop[3] = - tab_stop[4] = 0x01010101; - - if (do_clear) { - gotoxy(currcons,0,0); - csi_J(currcons,2); - save_cur(currcons); - } -} +enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey, + ESsetterm, ESsetgraph, ESgraph, ESgresc, ESignore }; void con_write(struct tty_struct * tty) { - int c; + unsigned char c; unsigned int currcons; wake_up(&tty->write_q->proc_list); currcons = tty - tty_table; - if (currcons >= NR_CONSOLES) { + if (currcons >= MAX_CONSOLES) { printk("con_write: illegal tty\n\r"); return; } - while (!tty->stopped && (c = get_tty_queue(tty->write_q)) >= 0) { - if (state == ESnormal && translate[c]) { - if (need_wrap) { - cr(currcons); - lf(currcons); - } - if (decim) - insert_char(currcons); - c = translate[c]; - *(char *) pos = c; - *(char *) (pos+1) = attr; - if (x == video_num_columns - 1) - need_wrap = decawm; - else { - x++; - pos+=2; - } - continue; - } - - /* - * Control characters can be used in the _middle_ - * of an escape sequence. - */ - if (c < 32 || c == 127) switch(c) { - case 7: - sysbeep(); - break; - case 8: - bs(currcons); - break; - case 9: - pos -= (x << 1); - while (x < video_num_columns - 1) { + while (!EMPTY(tty->write_q)) { + if (tty->stopped) + break; + GETCH(tty->write_q,c); + if (c == 24 || c == 26) + state = ESnormal; + switch(state) { + case ESnormal: + if (translate[c]) { + c = translate[c]; + while (x >= video_num_columns) { + x -= video_num_columns; + pos -= video_size_row; + lf(currcons); + } + *(char *) pos = c; + *(char *) (pos+1) = attr; + pos += 2; x++; - if (tab_stop[x >> 5] & (1 << (x & 31))) - break; - } - pos += (x << 1); - break; - case 10: case 11: case 12: - lf(currcons); - if (!lfnlmode) - break; - case 13: - cr(currcons); - break; - case 14: - charset = 1; - translate = G1_charset; - break; - case 15: - charset = 0; - translate = G0_charset; - break; - case 24: case 26: - state = ESnormal; - break; - case 27: - state = ESesc; - break; - case 127: - del(currcons); + } else if (c == 27) + state = ESesc; + else if (c == 10 || c == 11 || c == 12) + lf(currcons); + else if (c == 13) + cr(currcons); + else if (c == 127) + del(currcons); + else if (c == 8) { + if (x) { + x--; + pos -= 2; + } + } else if (c == 9) { + c = 8-(x&7); + x += c; + pos += c<<1; + if (x > video_num_columns) { + x -= video_num_columns; + pos -= video_size_row; + lf(currcons); + } + c = 9; + } else if (c == 7) + sysbeep(); + else if (c == 14) { + checkin = 1; + translate = restate; + } else if (c == 15) { + translate = NORM_TRANS; + checkin = 0; + } break; - } else switch(state) { case ESesc: state = ESnormal; switch (c) { @@ -997,8 +647,7 @@ void con_write(struct tty_struct * tty) state = ESsquare; break; case 'E': - cr(currcons); - lf(currcons); + gotoxy(currcons,0,y+1); break; case 'M': ri(currcons); @@ -1006,11 +655,8 @@ void con_write(struct tty_struct * tty) case 'D': lf(currcons); break; - case 'H': - tab_stop[x >> 5] |= (1 << (x & 31)); - break; case 'Z': - respond_ID(currcons,tty); + respond(currcons,tty); break; case '7': save_cur(currcons); @@ -1019,22 +665,32 @@ void con_write(struct tty_struct * tty) restore_cur(currcons); break; case '(': - state = ESsetG0; - break; case ')': - state = ESsetG1; + state = ESsetgraph; break; + case 'P': + state = ESsetterm; + break; case '#': - state = EShash; - break; + state = -1; + break; case 'c': - reset_terminal(currcons,1); - break; + tty->termios = DEF_TERMIOS; + state = ESnormal; + restate = NORM_TRANS; + checkin = 0; + top = 0; + bottom = video_num_lines; + translate = NORM_TRANS; case '>': /* Numeric keypad */ - SET(kbdapplic,kapplic,0); - break; + kbdapplic = 0; + if (currcons == fg_console) + kapplic = 0; + break; case '=': /* Appl. keypad */ - SET(kbdapplic,kapplic,1); + kbdapplic = 1; + if (currcons == fg_console) + kapplic = 1; break; } break; @@ -1046,7 +702,7 @@ void con_write(struct tty_struct * tty) if (c == '[') { /* Function key */ state=ESfunckey; break; - } + } if (ques=(c=='?')) break; case ESgetpars: @@ -1060,25 +716,10 @@ void con_write(struct tty_struct * tty) } else state=ESgotpars; case ESgotpars: state = ESnormal; - switch(c) { - case 'h': - set_mode(currcons,1); - break; - case 'l': - set_mode(currcons,0); - break; - case 'n': - if (!ques) - if (par[0] == 5) - status_report(currcons,tty); - else if (par[0] == 6) - cursor_report(currcons,tty); - break; - } if (ques) { ques = 0; break; - } + } switch(c) { case 'G': case '`': if (par[0]) par[0]--; @@ -1132,35 +773,21 @@ void con_write(struct tty_struct * tty) case 'P': csi_P(currcons,par[0]); break; - case 'c': - if (!par[0]) - respond_ID(currcons,tty); - break; - case 'g': - if (!par[0]) - tab_stop[x >> 5] &= ~(1 << (x & 31)); - else if (par[0] == 3) { - tab_stop[0] = - tab_stop[1] = - tab_stop[2] = - tab_stop[3] = - tab_stop[4] = 0; - } + case '@': + csi_at(currcons,par[0]); break; case 'm': csi_m(currcons); break; case 'r': - if (!par[0]) - par[0]++; + if (par[0]) + par[0]--; if (!par[1]) par[1] = video_num_lines; - /* Minimum allowed region is 2 lines */ if (par[0] < par[1] && par[1] <= video_num_lines) { - top=par[0]-1; + top=par[0]; bottom=par[1]; - gotoxy(currcons,0,0); } break; case 's': @@ -1169,65 +796,61 @@ void con_write(struct tty_struct * tty) case 'u': restore_cur(currcons); break; - case '@': - csi_at(currcons,par[0]); - break; - case ']': /* setterm functions */ - setterm_command(currcons); - break; + case 'l': /* blank interval */ + case 'b': /* bold attribute */ + if (!((npar >= 2) && + ((par[1]-13) == par[0]) && + ((par[2]-17) == par[0]))) + break; + if ((c=='l') && (par[0]<=60)) { + blankinterval = HZ*60*par[0]; + } + if (c=='b') + vc_cons[currcons].vc_bold_attr + = par[0]; } break; case ESfunckey: state = ESnormal; break; - case EShash: - state = ESnormal; - if (c == '8') { - /* DEC screen alignment test. kludge :-) */ - video_erase_char = - (video_erase_char & 0xff00) | 'E'; - csi_J(currcons, 2); - video_erase_char = - (video_erase_char & 0xff00) | ' '; - } - break; - case ESsetG0: - if (c == '0') - G0_charset = GRAF_TRANS; - else if (c == 'B') - G0_charset = NORM_TRANS; - else if (c == 'U') - G0_charset = NULL_TRANS; - if (charset == 0) - translate = G0_charset; + case ESsetterm: /* Setterm functions. */ state = ESnormal; + if (c == 'S') { + def_attr = attr; + video_erase_char = (video_erase_char&0x0ff) | (def_attr<<8); + } else if (c == 'L') + /*linewrap on*/; + else if (c == 'l') + /*linewrap off*/; break; - case ESsetG1: - if (c == '0') - G1_charset = GRAF_TRANS; - else if (c == 'B') - G1_charset = NORM_TRANS; - else if (c == 'U') - G1_charset = NULL_TRANS; - if (charset == 1) - translate = G1_charset; + case ESsetgraph: + if (c == '0') { + if (checkin) + translate = GRAF_TRANS; + restate = GRAF_TRANS; + } else if (c == 'B') + translate = restate = NORM_TRANS; state = ESnormal; break; default: state = ESnormal; } } - if (vtmode == KD_GRAPHICS) - return; set_cursor(currcons); + timer_active &= ~(1< MAX_CONSOLES) + NR_CONSOLES = MAX_CONSOLES; + if (!NR_CONSOLES) + NR_CONSOLES = 1; + video_memory = screen_size; + /* Initialize the variables used for scrolling (mostly EGA/VGA) */ - - base = (long)vc_scrmembuf; - for (currcons = 0; currcons=NR_CONSOLES)) + if ((currcons<0) || (currcons>NR_CONSOLES)) return -EIO; put_fs_byte((char)(video_num_lines),buf++); put_fs_byte((char)(video_num_columns),buf++); @@ -1487,32 +1138,27 @@ void console_print(const char * b) if (currcons<0 || currcons>=NR_CONSOLES) currcons = 0; + if (vt_info[currcons].mode == KD_GRAPHICS) + return; /* no output in graphics mode */ while (c = *(b++)) { - if (c == 10 || c == 13 || need_wrap) { + if (c == 10) { cr(currcons); - if (c == 10 || need_wrap) - lf(currcons); - need_wrap = 0; + lf(currcons); continue; } - *(char *) pos = c; - *(char *) (pos+1) = attr; - if (x == video_num_columns - 1) { - need_wrap = 1; + if (c == 13) { + cr(currcons); continue; } + while (x >= video_num_columns) { + x -= video_num_columns; + pos -= video_size_row; + lf(currcons); + } + *(char *) pos = c; + *(char *) (pos+1) = attr; + pos += 2; x++; - pos+=2; } set_cursor(currcons); - if (vt_cons[fg_console].vt_mode == KD_GRAPHICS) - return; - timer_active &= ~(1< + .fill 10,1,0 + +alt_map: + .byte 0,0 + .ascii "\0@\243$\0\0{[]}\\\0" + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte '~,13,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0,0,0 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte 0,0,0,0,0 /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '| + .fill 10,1,0 + +#elif defined(KBD_US) + +key_map: + .byte 0,27 + .ascii "1234567890-=" + .byte 127,9 + .ascii "qwertyuiop[]" + .byte 13,0 + .ascii "asdfghjkl;'" + .byte '`,0 + .ascii "\\zxcvbnm,./" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '< + .fill 10,1,0 + +shift_map: + .byte 0,27 + .ascii "!@#$%^&*()_+" + .byte 127,9 + .ascii "QWERTYUIOP{}" + .byte 13,0 + .ascii "ASDFGHJKL:\"" + .byte '~,0 + .ascii "|ZXCVBNM<>?" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '> + .fill 10,1,0 + +alt_map: + .byte 0,0 + .ascii "\0@\0$\0\0{[]}\\\0" + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte '~,13,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0,0,0 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte 0,0,0,0,0 /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '| + .fill 10,1,0 + +#elif defined(KBD_UK) + +key_map: + .byte 0,27 + .ascii "1234567890-=" + .byte 127,9 + .ascii "qwertyuiop[]" + .byte 13,0 + .ascii "asdfghjkl;'" + .byte '`,0 + .ascii "#zxcvbnm,./" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .ascii "\\" + .fill 10,1,0 + +shift_map: + .byte 0,27 + .ascii "!\"\243$%^&*()_+" + .byte 127,9 + .ascii "QWERTYUIOP{}" + .byte 13,0 + .ascii "ASDFGHJKL:@" + .byte '~,0 + .ascii "~ZXCVBNM<>?" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '| + .fill 10,1,0 + +alt_map: + .byte 0,0 + .ascii "\0@\0$\0\0{[]}\\\0" + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte '~,13,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0,0,0 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte 0,0,0,0,0 /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '| + .fill 10,1,0 + +#elif defined(KBD_GR) + +key_map: + .byte 0,27 + .ascii "1234567890\\'" + .byte 127,9 + .ascii "qwertzuiop@+" + .byte 13,0 + .ascii "asdfghjkl[]^" + .byte 0,'# + .ascii "yxcvbnm,.-" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '< + .fill 10,1,0 + +shift_map: + .byte 0,27 + .ascii "!\"#$%&/()=?`" + .byte 127,9 + .ascii "QWERTZUIOP\\*" + .byte 13,0 + .ascii "ASDFGHJKL{}~" + .byte 0,'' + .ascii "YXCVBNM;:_" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '> + .fill 10,1,0 + +alt_map: + .byte 0,0 + .ascii "\0@\0$\0\0{[]}\\\0" + .byte 0,0 + .byte '@,0,0,0,0,0,0,0,0,0,0 + .byte '~,13,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0,0,0 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte 0,0,0,0,0 /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '| + .fill 10,1,0 + +#elif defined(KBD_FR) + +key_map: + .byte 0,27 + .ascii "&{\"'(-}_/@)=" + .byte 127,9 + .ascii "azertyuiop^$" + .byte 13,0 + .ascii "qsdfghjklm|" + .byte '`,0,42 /* coin sup gauche, don't know, [*|mu] */ + .ascii "wxcvbn,;:!" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '< + .fill 10,1,0 + +shift_map: + .byte 0,27 + .ascii "1234567890]+" + .byte 127,9 + .ascii "AZERTYUIOP<>" + .byte 13,0 + .ascii "QSDFGHJKLM%" + .byte '~,0,'# + .ascii "WXCVBN?./\\" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '> + .fill 10,1,0 + +alt_map: + .byte 0,0 + .ascii "\0~#{[|`\\^@]}" + .byte 0,0 + .byte '@,0,0,0,0,0,0,0,0,0,0 + .byte '~,13,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0,0,0 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte 0,0,0,0,0 /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '| + .fill 10,1,0 + +#elif defined(KBD_DK) + +key_map: + .byte 0,27 + .ascii "1234567890+'" + .byte 127,9 + .ascii "qwertyuiop" + .byte 134,0,13,0 /* This is IBM-PC, change it to latin-1 */ + .ascii "asdfghjkl" + .byte 145,155,0,0 + .ascii "'zxcvbnm,.-" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '< + .fill 10,1,0 + +shift_map: + .byte 0,27 + .ascii "!\"#$%&/()=?`" + .byte 127,9 + .ascii "QWERTYUIOP" + .byte 143,94,13,0 + .ascii "ASDFGHJKL" + .byte 146,157,0,0 + .ascii "*ZXCVBNM;:_" + .byte 0,'*,0,32 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte '-,0,0,0,'+ /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .byte '> + .fill 10,1,0 + +alt_map: + .byte 0,0 + .ascii "\0@\0$\0\0{[]}\0" + .byte '|,0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte '~,13,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0 + .byte 0,0,0,0,0,0,0,0,0,0,0 + .byte 0,0,0,0 /* 36-39 */ + .fill 16,1,0 /* 3A-49 */ + .byte 0,0,0,0,0 /* 4A-4E */ + .byte 0,0,0,0,0,0,0 /* 4F-55 */ + .ascii "\\" + .fill 10,1,0 + +#else +#error "KBD-type not defined" +#endif +/* + * do_self handles "normal" keys, ie keys that don't change meaning + * and which have just one character returns. + */ +do_self: + lea alt_map,%ebx + testb $0x20,_kmode /* alt-gr */ + jne 1f + lea shift_map,%ebx + testb $0x0f,_kmode + jne 1f + lea key_map,%ebx +1: movb (%ebx,%eax),%al + orb %al,%al + je none + testb $0x4c,_kmode /* ctrl or caps */ + je 2f + cmpb $'a,%al + jb 2f + cmpb $'},%al + ja 2f + subb $32,%al +2: testb $0x0c,_kmode /* ctrl */ + je 3f + andb $0x1f,%al +3: testb $0x10,_kmode /* left alt */ + je 4f + orb $0x80,%al +4: andl $0xff,%eax + xorl %ebx,%ebx + call put_queue +none: ret + +/* + * slash and star have routines of their own, as a 'E0h' before + * the scan code for slash means that the numeric keypad + * slash was pushed. + */ +slash: cmpb $1,_ke0 + jne do_self + cmpb $1,_kapplic + jne notmapplic + movw $'Q,%ax + jmp applkey + +notmapplic: + movl $'/,%eax + xorl %ebx,%ebx + jmp put_queue + +star: cmpb $1,_kapplic + jne do_self + movw $'R,%ax + jmp applkey + +notsapplic: + movl $'*,%eax + xorl %ebx,%ebx + jmp put_queue + +enter: cmpb $1,_ke0 + jne do_self + cmpb $1,_kapplic + jne do_self + movw $'M,%ax + jmp applkey + +minus: cmpb $1,_kapplic + jne do_self + movw $'S,%ax + jmp applkey + +plus: cmpb $1,_kapplic + jne do_self + movw $'l,%ax + jmp applkey + +/* + * This table decides which routine to call when a scan-code has been + * gotten. Most routines just call do_self, or none, depending if + * they are make or break. + */ +key_table: + .long none,do_self,do_self,do_self /* 00-03 s0 esc 1 2 */ + .long do_self,do_self,do_self,do_self /* 04-07 3 4 5 6 */ + .long do_self,do_self,do_self,do_self /* 08-0B 7 8 9 0 */ + .long do_self,do_self,do_self,do_self /* 0C-0F + ' bs tab */ + .long do_self,do_self,do_self,do_self /* 10-13 q w e r */ + .long do_self,do_self,do_self,do_self /* 14-17 t y u i */ + .long do_self,do_self,do_self,do_self /* 18-1B o p } ^ */ + .long enter,ctrl,do_self,do_self /* 1C-1F enter ctrl a s */ + .long do_self,do_self,do_self,do_self /* 20-23 d f g h */ + .long do_self,do_self,do_self,do_self /* 24-27 j k l | */ + .long do_self,do_self,lshift,do_self /* 28-2B { para lshift , */ + .long do_self,do_self,do_self,do_self /* 2C-2F z x c v */ + .long do_self,do_self,do_self,do_self /* 30-33 b n m , */ + .long do_self,slash,rshift,star /* 34-37 . - rshift * */ + .long alt,do_self,caps,func /* 38-3B alt sp caps f1 */ + .long func,func,func,func /* 3C-3F f2 f3 f4 f5 */ + .long func,func,func,func /* 40-43 f6 f7 f8 f9 */ + .long func,num,scroll,cursor /* 44-47 f10 num scr home */ + .long cursor,cursor,minus,cursor /* 48-4B up pgup - left */ + .long cursor,cursor,plus,cursor /* 4C-4F n5 right + end */ + .long cursor,cursor,cursor,cursor /* 50-53 dn pgdn ins del */ + .long none,none,do_self,func /* 54-57 sysreq ? < f11 */ + .long func,none,none,none /* 58-5B f12 ? ? ? */ + .long none,none,none,none /* 5C-5F ? ? ? ? */ + .long none,none,none,none /* 60-63 ? ? ? ? */ + .long none,none,none,none /* 64-67 ? ? ? ? */ + .long none,none,none,none /* 68-6B ? ? ? ? */ + .long none,none,none,none /* 6C-6F ? ? ? ? */ + .long none,none,none,none /* 70-73 ? ? ? ? */ + .long none,none,none,none /* 74-77 ? ? ? ? */ + .long none,none,none,none /* 78-7B ? ? ? ? */ + .long none,none,none,none /* 7C-7F ? ? ? ? */ + .long none,none,none,none /* 80-83 ? br br br */ + .long none,none,none,none /* 84-87 br br br br */ + .long none,none,none,none /* 88-8B br br br br */ + .long none,none,none,none /* 8C-8F br br br br */ + .long none,none,none,none /* 90-93 br br br br */ + .long none,none,none,none /* 94-97 br br br br */ + .long none,none,none,none /* 98-9B br br br br */ + .long none,unctrl,none,none /* 9C-9F br unctrl br br */ + .long none,none,none,none /* A0-A3 br br br br */ + .long none,none,none,none /* A4-A7 br br br br */ + .long none,none,unlshift,none /* A8-AB br br unlshift br */ + .long none,none,none,none /* AC-AF br br br br */ + .long none,none,none,none /* B0-B3 br br br br */ + .long none,none,unrshift,none /* B4-B7 br br unrshift br */ + .long unalt,none,uncaps,none /* B8-BB unalt br uncaps br */ + .long none,none,none,none /* BC-BF br br br br */ + .long none,none,none,none /* C0-C3 br br br br */ + .long none,none,none,none /* C4-C7 br br br br */ + .long none,none,none,none /* C8-CB br br br br */ + .long none,none,none,none /* CC-CF br br br br */ + .long none,none,none,none /* D0-D3 br br br br */ + .long none,none,none,none /* D4-D7 br br br br */ + .long none,none,none,none /* D8-DB br ? ? ? */ + .long none,none,none,none /* DC-DF ? ? ? ? */ + .long none,none,none,none /* E0-E3 e0 e1 ? ? */ + .long none,none,none,none /* E4-E7 ? ? ? ? */ + .long none,none,none,none /* E8-EB ? ? ? ? */ + .long none,none,none,none /* EC-EF ? ? ? ? */ + .long none,none,none,none /* F0-F3 ? ? ? ? */ + .long none,none,none,none /* F4-F7 ? ? ? ? */ + .long none,none,none,none /* F8-FB ? ? ? ? */ + .long none,none,none,none /* FC-FF ? ? ? ? */ + +/* + * kb_wait waits for the keyboard controller buffer to empty. + */ +kb_wait: + pushl %eax + pushl %ebx + movl $10000,%ebx +1: inb $0x64,%al + testb $0x02,%al + je 2f + decl %ebx + jne 1b +2: popl %ebx + popl %eax + ret + +no_idt: + .long 0,0 +/* + * This routine reboots the machine by asking the keyboard + * controller to pulse the reset-line low. We try that for a while, + * and if it doesn't work, we do some other stupid things. + */ +_hard_reset_now: + sti + movl $100,%ebx +1: call kb_wait + movw $0x1234,0x472 /* don't do memory check */ + movb $0xfe,%al /* pulse reset low */ + outb %al,$0x64 + decl %ebx + jne 1b + lidt no_idt /* zero-length idt: should triple-fault */ + jmp _hard_reset_now diff --git a/kernel/chr_drv/keyboard.c b/kernel/chr_drv/keyboard.c deleted file mode 100644 index bd437f14a9c4..000000000000 --- a/kernel/chr_drv/keyboard.c +++ /dev/null @@ -1,1230 +0,0 @@ -/* - * linux/kernel/chr_drv/keyboard.c - * - * Keyboard driver for Linux v0.96 using Latin-1. - * - * Written for linux by Johan Myreen as a translation from - * the assembly version by Linus (with diacriticals added) - */ - -#include -#include -#include -#include -#include -#include - -#define LSHIFT 0x01 -#define RSHIFT 0x02 -#define LCTRL 0x04 -#define RCTRL 0x08 -#define ALT 0x10 -#define ALTGR 0x20 -#define CAPS 0x40 -#define CAPSDOWN 0x80 - -#define SCRLED 0x01 -#define NUMLED 0x02 -#define CAPSLED 0x04 - -#define NO_META_BIT 0x80 - -unsigned char kapplic = 0; -unsigned char ckmode = 0; -unsigned char krepeat = 1; -unsigned char kmode = 0; -unsigned char kleds = NUMLED; -unsigned char ke0 = 0; -unsigned char kraw = 0; -unsigned char kbd_flags = KBDFLAGS; -unsigned char lfnlmode = 0; - -extern void do_keyboard_interrupt(void); -extern void ctrl_alt_del(void); -extern void change_console(unsigned int new_console); -extern struct tty_queue *table_list[]; - -typedef void (*fptr)(int); - -static unsigned char old_leds = 2; -static int diacr = -1; -static int npadch = 0; -fptr key_table[]; - -static void put_queue(int); -void set_leds(void); -static void applkey(int); -static void cur(int); -static void kb_wait(void), kb_ack(void); -static unsigned int handle_diacr(unsigned int); - -void keyboard_interrupt(int cpl) -{ - static unsigned char rep = 0xff, repke0 = 0; - unsigned char scancode, x; - struct tty_struct * tty = TTY_TABLE(0); - - scancode=inb_p(0x60); - x=inb_p(0x61); - outb_p(x|0x80, 0x61); - outb_p(x&0x7f, 0x61); - outb(0x20, 0x20); - sti(); - - if (kraw) { - put_queue(scancode); - do_keyboard_interrupt(); - return; - } - if (scancode == 0xe0) { - ke0 = 1; - return; - } - if (scancode == 0xe1) { - ke0 = 2; - return; - } - /* - * The keyboard maintains its own internal caps lock and num lock - * statuses. In caps lock mode E0 AA precedes make code and E0 2A - * follows break code. In num lock mode, E0 2A precedes make - * code and E0 AA follows break code. We do our own book-keeping, - * so we will just ignore these. - */ - if (ke0 == 1 && (scancode == 0x2a || scancode == 0xaa)) { - ke0 = 0; - return; - } - /* - * Repeat a key only if the input buffers are empty or the - * characters get echoed locally. This makes key repeat usable - * with slow applications and unders heavy loads. - */ - if (rep == 0xff) { - if (scancode < 0x80) { - rep = scancode; - repke0 = ke0; - } - } else if (ke0 == repke0 && (scancode & 0x7f) == rep) - if (scancode & 0x80) - rep = 0xff; - else if (!(krepeat && (L_ECHO(tty) || (EMPTY(tty->secondary) && - EMPTY(tty->read_q))))) { - ke0 = 0; - return; - } - key_table[scancode](scancode); - do_keyboard_interrupt(); - ke0 = 0; -} - -static void put_queue(int ch) -{ - register struct tty_queue *qp = table_list[0]; - unsigned long new_head; - - qp->buf[qp->head]=ch; - if ((new_head=(qp->head+1)&(TTY_BUF_SIZE-1)) != qp->tail) - qp->head=new_head; - wake_up(&qp->proc_list); -} - -static void puts_queue(char *cp) -{ - register struct tty_queue *qp = table_list[0]; - unsigned long new_head; - char ch; - - while (ch=*cp++) { - qp->buf[qp->head]=ch; - if ((new_head=(qp->head+1)&(TTY_BUF_SIZE-1)) - != qp->tail) - qp->head=new_head; - } - wake_up(&qp->proc_list); -} - -static void ctrl(int sc) -{ - if (ke0) - kmode|=RCTRL; - else - kmode|=LCTRL; -} - -static void alt(int sc) -{ - if (ke0) - kmode|=ALTGR; - else - kmode|=ALT; -} - -static void unctrl(int sc) -{ - if (ke0) - kmode&=(~RCTRL); - else - kmode&=(~LCTRL); -} - -static void unalt(int sc) -{ - if (ke0) - kmode&=(~ALTGR); - else { - kmode&=(~ALT); - if (npadch != 0) { - put_queue(npadch); - npadch=0; - } - } -} - -static void lshift(int sc) -{ - kmode|=LSHIFT; -} - -static void unlshift(int sc) -{ - kmode&=(~LSHIFT); -} - -static void rshift(int sc) -{ - kmode|=RSHIFT; -} - -static void unrshift(int sc) -{ - kmode&=(~RSHIFT); -} - -static void caps(int sc) -{ - if (!(kmode & CAPSDOWN)) { - kleds ^= CAPSLED; - kmode ^= CAPS; - kmode |= CAPSDOWN; - set_leds(); - } -} - -void set_leds(void) -{ - if (kleds != old_leds) { - old_leds = kleds; - kb_wait(); - outb(0xed, 0x60); /* set leds command */ - kb_ack(); - kb_wait(); - outb(kleds, 0x60); - kb_ack(); - } -} - -static void uncaps(int sc) -{ - kmode &= ~CAPSDOWN; -} - -static void scroll(int sc) -{ - if (kmode & (LSHIFT | RSHIFT)) - show_mem(); - else - show_state(); - kleds ^= SCRLED; - set_leds(); -} - -static void num(int sc) -{ - if (kapplic) - applkey(0x50); - else { - kleds ^= NUMLED; - set_leds(); - } -} - -static void applkey(int key) -{ - char buf[] = { 0x1b, 0x4f, 0x00, 0x00 }; - - buf[2] = key; - puts_queue(buf); -} - - -#if defined KBD_FINNISH - -static unsigned char key_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '+', '\'', 127, 9, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '}', 0, 13, 0, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', '|', - '{', 0, 0, '\'', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '-', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char shift_map[] = { - 0, 27, '!', '\"', '#', '$', '%', '&', - '/', '(', ')', '=', '?', '`', 127, 9, - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', ']', '^', 13, 0, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', '\\', - '[', 0, 0, '*', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', ';', ':', '_', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '>', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char alt_map[] = { - 0, 0, 0, '@', 163, '$', 0, 0, - '{', '[', ']', '}', '\\', 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, '~', 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '|', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -#elif defined KBD_FINNISH_LATIN1 - -static unsigned char key_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '+', 180, 127, 9, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', 229, 168, 13, 0, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', 246, - 228, 167, 0, '\'', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '-', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char shift_map[] = { - 0, 27, '!', '"', '#', '$', '%', '&', - '/', '(', ')', '=', '?', '`', 127, 9, - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', 197, '^', 13, 0, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', 214, - 196, 189, 0, '*', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', ';', ':', '_', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '>', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char alt_map[] = { - 0, 0, 0, '@', 163, '$', 0, 0, - '{', '[', ']', '}', '\\', 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, '~', 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '|', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -#elif defined KBD_US - -static unsigned char key_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', 127, 9, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', 13, 0, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '/', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char shift_map[] = { - 0, 27, '!', '@', '#', '$', '%', '^', - '&', '*', '(', ')', '_', '+', 127, 9, - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '{', '}', 13, 0, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', - '"', '~', '0', '|', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '>', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char alt_map[] = { - 0, 0, 0, '@', 0, '$', 0, 0, - '{', '[', ']', '}', '\\', 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, '~', 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '|', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -#elif defined KBD_UK - -static unsigned char key_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', 127, 9, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', 13, 0, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - '\'', '`', 0, '#', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '/', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '\\', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char shift_map[] = { - 0, 27, '!', '"', 163, '$', '%', '^', - '&', '*', '(', ')', '_', '+', 127, 9, - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '{', '}', 13, 0, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', - '@', '~', '0', '~', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '|', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char alt_map[] = { - 0, 0, 0, '@', 0, '$', 0, 0, - '{', '[', ']', '}', '\\', 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, '~', 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '|', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -#elif defined KBD_GR - -static unsigned char key_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '\\', '\'', 127, 9, - 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', - 'o', 'p', '@', '+', 13, 0, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', '[', - ']', '^', 0, '#', 'y', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '-', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char shift_map[] = { - 0, 27, '!', '"', '#', '$', '%', '&', - '/', '(', ')', '=', '?', '`', 127, 9, - 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', - 'O', 'P', '\\', '*', 13, 0, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', '{', - '}', '~', 0, '\'', 'Y', 'X', 'C', 'V', - 'B', 'N', 'M', ';', ':', '_', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '>', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char alt_map[] = { - 0, 0, 0, '@', 0, '$', 0, 0, - '{', '[', ']', '}', '\\', 0, 0, 0, - '@', 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, '~', 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '|', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -#elif defined KBD_GR_LATIN1 - -static unsigned char key_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', 223, 180, 127, 9, - 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', - 'o', 'p', 252, '+', 13, 0, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', 246, - 228, 94, 0, '#', 'y', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '-', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char shift_map[] = { - 0, 27, '!', '"', 167, '$', '%', '&', - '/', '(', ')', '=', '?', '`', 127, 9, - 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', - 'O', 'P', 220, '*', 13, 0, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', 214, - 196, 176, 0, '\'', 'Y', 'X', 'C', 'V', - 'B', 'N', 'M', ';', ':', '_', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '>', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char alt_map[] = { - 0, 0, 0, 178, 179, '$', 0, 0, - '{', '[', ']', '}', '\\', 0, 0, 0, - '@', 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, '~', 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 181, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '|', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -#elif defined KBD_FR - -static unsigned char key_map[] = { - 0, 27, '&', '{', '"', '\'', '(', '-', - '}', '_', '/', '@', ')', '=', 127, 9, - 'a', 'z', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '^', '$', 13, 0, 'q', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', - '|', '`', 0, 42, 'w', 'x', 'c', 'v', - 'b', 'n', ',', ';', ':', '!', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char shift_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', ']', '+', 127, 9, - 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '<', '>', 13, 0, 'Q', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', - '%', '~', 0, '#', 'W', 'X', 'C', 'V', - 'B', 'N', '?', '.', '/', '\\', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '>', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char alt_map[] = { - 0, 0, 0, '~', '#', '{', '[', '|', - '`', '\\', '^', '@', ']', '}', 0, 0, - '@', 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, '~', 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '|', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -#elif defined KBD_FR_LATIN1 - -static unsigned char key_map[] = { - 0, 27, '&', 233, '"', '\'', '(', '-', - 232, '_', 231, 224, ')', '=', 127, 9, - 'a', 'z', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '^', '$', 13, 0, 'q', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', - 249, 178, 0, 42, 'w', 'x', 'c', 'v', - 'b', 'n', ',', ';', ':', '!', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char shift_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', 176, '+', 127, 9, - 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', 168, 163, 13, 0, 'Q', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', - '%', 0, 0, 181, 'W', 'X', 'C', 'V', - 'B', 'N', '?', '.', '/', 167, 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '>', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char alt_map[] = { - 0, 0, 0, '~', '#', '{', '[', '|', - '`', '\\', '^', '@', ']', '}', 0, 0, - '@', 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 164, 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '|', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -#elif defined KBD_DK - -static unsigned char key_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '+', '\'', 127, 9, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', 229, 0, 13, 0, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', 230, - 162, 0, 0, '\'', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '-', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char shift_map[] = { - 0, 27, '!', '\"', '#', '$', '%', '&', - '/', '(', ')', '=', '?', '`', 127, 9, - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', 197, '^', 13, 0, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', 198, - 165, 0, 0, '*', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', ';', ':', '_', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '>', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char alt_map[] = { - 0, 0, 0, '@', 163, '$', 0, 0, - '{', '[', ']', '}', 0, '|', 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, '~', 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '\\', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -#elif defined KBD_DK_LATIN1 - -static unsigned char key_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '+', 180, 127, 9, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', 229, 168, 13, 0, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', 230, - 162, 189, 0, '\'', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '-', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char shift_map[] = { - 0, 27, '!', '\"', '#', '$', '%', '&', - '/', '(', ')', '=', '?', '`', 127, 9, - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', 197, '^', 13, 0, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', 198, - 165, 167, 0, '*', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', ';', ':', '_', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '>', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char alt_map[] = { - 0, 0, 0, '@', 163, '$', 0, 0, - '{', '[', ']', '}', 0, '|', 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, '~', 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '\\', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -#elif defined KBD_DVORAK - -static unsigned char key_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '\\', '=', 127, 9, - '\'', ',', '.', 'p', 'y', 'f', 'g', 'c', - 'r', 'l', '/', ']', 13, 0, 'a', 'o', - 'e', 'u', 'i', 'd', 'h', 't', 'n', 's', - '-', '`', 0, '[', ';', 'q', 'j', 'k', - 'x', 'b', 'm', 'w', 'v', 'z', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char shift_map[] = { - 0, 27, '!', '@', '#', '$', '%', '^', - '&', '*', '(', ')', '|', '+', 127, 9, - '"', '<', '>', 'P', 'Y', 'F', 'G', 'C', - 'R', 'L', '?', '}', 13, 0, 'A', 'O', - 'E', 'U', 'I', 'D', 'H', 'T', 'N', 'S', - '_', '~', 0, '{', ':', 'Q', 'J', 'K', - 'X', 'B', 'M', 'W', 'V', 'Z', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -static unsigned char alt_map[] = { - 0, 0, 0, '@', 0, '$', 0, 0, - '{', '[', ']', '}', '\\', 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, '~', 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '|', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; - -#elif defined KBD_SG -static unsigned char key_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '\'', '^', 127, 9, - 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', - 'o', 'p', 0, 0, 13, 0, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0, - 0, 0, 0, '$', 'y', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '-', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; -static unsigned char shift_map[] = { - 0, 27, '+', '"', '*', 0, '%', '&', - '/', '(', ')', '=', '?', '`', 127, 9, - 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', - 'O', 'P', 0, '!', 13, 0, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0, - 0, 0, 0, 0, 'Y', 'X', 'C', 'V', - 'B', 'N', 'M', ';', ':', '_', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '>', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; -static unsigned char alt_map[] = { - 0, 0, 0, '@', '#', 0, 0, 0, - '|', 0, 0, 0, '\'', '~', 0, 0, - '@', 0, 0, 0, 0, 0, 0, 0, - 0, 0, '[', ']', 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - '{', 0, 0, '}', 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '\\', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; -#elif defined KBD_SG_LATIN1 -static unsigned char key_map[] = { - 0, 27, '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '\'', '^', 127, 9, - 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', - 'o', 'p', 252, 0, 13, 0, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', 246, - 228, 167, 0, '$', 'y', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '-', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '<', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; -static unsigned char shift_map[] = { - 0, 27, '+', '"', '*', 231, '%', '&', - '/', '(', ')', '=', '?', '`', 127, 9, - 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', - 'O', 'P', 220, '!', 13, 0, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', 214, - 196, 176, 0, 163, 'Y', 'X', 'C', 'V', - 'B', 'N', 'M', ';', ':', '_', 0, '*', - 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, '-', 0, 0, 0, '+', 0, - 0, 0, 0, 0, 0, 0, '>', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; -static unsigned char alt_map[] = { - 0, 0, 0, '@', '#', 0, 0, 172, - '|', 162, 0, 0, '\'', '~', 0, 0, - '@', 0, 0, 0, 0, 0, 0, 0, - 0, 0, '[', ']', 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 233, - '{', 0, 0, '}', 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, '\\', 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0 }; -#else -#error "KBD-type not defined" -#endif - -static void do_self(int sc) -{ - unsigned char ch; - - if (kmode & ALTGR) - ch = alt_map[sc]; - else if (kmode & (LSHIFT | RSHIFT | LCTRL | RCTRL)) - ch = shift_map[sc]; - else - ch = key_map[sc]; - - if (ch == 0) - return; - - if ((ch = handle_diacr(ch)) == 0) - return; - - if (kmode & (LCTRL | RCTRL | CAPS)) /* ctrl or caps */ - if ((ch >= 'a' && ch <= 'z') || (ch >= 224 && ch <= 254)) - ch -= 32; - if (kmode & (LCTRL | RCTRL)) /* ctrl */ - ch &= 0x1f; - - if (kmode & ALT) - if (kbd_flags & NO_META_BIT) { - put_queue('\033'); - put_queue(ch); - } else - put_queue(ch|0x80); - else - put_queue(ch); -} - -unsigned char accent_table[5][64] = { - " \300BCD\310FGH\314JKLMN\322PQRST\331VWXYZ[\\]^_" - "`\340bcd\350fgh\354jklmn\362pqrst\371vwxyz{|}~", /* accent grave */ - - " \301BCD\311FGH\315JKLMN\323PQRST\332VWX\335Z[\\]^_" - "`\341bcd\351fgh\355jklmn\363pqrst\372vwxyz{|}~", /* accent acute */ - - " \302BCD\312FGH\316JKLMN\324PQRST\333VWXYZ[\\]^_" - "`\342bcd\352fgh\356jklmn\364pqrst\373vwxyz{|}~", /* circumflex */ - - " \303BCDEFGHIJKLMN\325PQRSTUVWXYZ[\\]^_" - "`\343bcdefghijklm\361\365pqrstuvwxyz{|}~", /* tilde */ - - " \304BCD\313FGH\316JKLMN\326PQRST\334VWXYZ[\\]^_" - "`\344bcd\353fgh\357jklmn\366pqrst\374vwx\377z{|}~" /* dieresis */ -}; - - -/* - * Check if dead key pressed. If so, check if same key pressed twice; - * in that case return the char, otherwise store char and return 0. - * If dead key not pressed, check if accented character pending. If - * not: return the char, otherwise check if char is a space. If it is - * a space return the diacritical. Else combine char with diacritical - * mark and return. - */ - -unsigned int handle_diacr(unsigned int ch) -{ - static unsigned char diacr_table[] = - {'`', 180, '^', '~', 168, 0}; /* Must end with 0 */ - int i; - - for(i=0; diacr_table[i]; i++) - if (ch==diacr_table[i] && ((1<122) { - diacr=-1; - return ch; - } else { - ch=accent_table[diacr][ch-64]; - diacr=-1; - return ch; - } -} - - -#if defined KBD_FR || defined KBD_US || defined KBD_UK -static unsigned char num_table[] = "789-456+1230."; -#else -static unsigned char num_table[] = "789-456+1230,"; -#endif - -static unsigned char cur_table[] = "HA5-DGC+YB623"; -static unsigned int pad_table[] = { 7,8,9,0,4,5,6,0,1,2,3,0,0 }; - -/* - Keypad / 35 B7 Q - Keypad * (PrtSc) 37 B7 R - Keypad NumLock 45 ?? P - Keypad 7 (Home) 47 C7 w - Keypad 8 (Up arrow) 48 C8 x - Keypad 9 (PgUp) 49 C9 y - Keypad - 4A CA S - Keypad 4 (Left arrow) 4B CB t - Keypad 5 4C CC u - Keypad 6 (Right arrow) 4D CD v - Keypad + 4E CE l - Keypad 1 (End) 4F CF q - Keypad 2 (Down arrow) 50 D0 r - Keypad 3 (PgDn) 51 D1 s - Keypad 0 (Ins) 52 D2 p - Keypad . (Del) 53 D3 n -*/ - -static unsigned char appl_table[] = "wxyStuvlqrspn"; - -static char *func_table[] = { - "\033[[A", "\033[[B", "\033[[C", "\033[[D", - "\033[[E", "\033[[F", "\033[[G", "\033[[H", - "\033[[I", "\033[[J", "\033[[K", "\033[[L" -}; - - -static void cursor(int sc) -{ - if (sc < 0x47 || sc > 0x53) - return; - sc-=0x47; - if (sc == 12 && (kmode&(LCTRL|RCTRL)) && (kmode&(ALT|ALTGR))) { - ctrl_alt_del(); - return; - } - if (ke0 == 1) { - cur(sc); - return; - } - - if ((kmode&ALT) && sc!=12) { /* Alt-numpad */ - npadch=npadch*10+pad_table[sc]; - return; - } - - if (kapplic && !(kmode&(LSHIFT|RSHIFT))) { /* shift forces cursor */ - applkey(appl_table[sc]); - return; - } - - if (kleds&NUMLED) { - put_queue(num_table[sc]); - } else - cur(sc); -} - -static void cur(int sc) -{ - char buf[] = { 0x1b, '[', 0, 0, 0 }; /* must not be static */ - - buf[2]=cur_table[sc]; - if (buf[2] < '9') - buf[3]='~'; - if ((buf[2] >= 'A' && buf[2] <= 'D') ? ckmode : kapplic) - buf[1]='O'; - puts_queue(buf); -} - -static void func(int sc) -{ - if (sc < 0x3b) - return; - sc-=0x3b; - if (sc > 9) { - sc-=18; - if (sc < 10 || sc > 11) - return; - } - if (kmode&ALT) - change_console(sc); - else - puts_queue(func_table[sc]); -} - - -static void slash(int sc) -{ - if (ke0 != 1) - do_self(sc); - else if (kapplic) - applkey('Q'); - else - put_queue('/'); -} - -static void star(int sc) -{ - if (kapplic) - applkey('R'); - else - do_self(sc); -} - -static void enter(int sc) -{ - if (ke0 == 1 && kapplic) - applkey('M'); - else { - put_queue(13); - if (lfnlmode) - put_queue(10); - } -} - -static void minus(int sc) -{ - if (kapplic) - applkey('S'); - else - do_self(sc); -} - -static void plus(int sc) -{ - if (kapplic) - applkey('l'); - else - do_self(sc); -} - - -static void none(int sc) -{ -} - - -/* - * kb_wait waits for the keyboard controller buffer to empty. - */ - -static void kb_wait(void) -{ - int i; - - for (i=0; i<0x10000; i++) - if ((inb(0x64)&0x02) == 0) - break; -} - -/* - * kb_ack waits for 0xfa to appear in port 0x60 - * - * Suggested by Bruce Evans - * Added by Niels Skou Olsen [NSO] - * April 21, 1992 - * - * Heavily inspired by kb_wait :-) - * I don't know how much waiting actually is required, - * but this seems to work - */ - -void kb_ack(void) -{ - int i; - - for(i=0; i<0x10000; i++) - if (inb(0x60) == 0xfa) - break; -} - -long no_idt[2] = {0, 0}; - -/* - * This routine reboots the machine by asking the keyboard - * controller to pulse the reset-line low. We try that for a while, - * and if it doesn't work, we do some other stupid things. - */ -void hard_reset_now(void) -{ - int i; - - sti(); - for (;;) { - for (i=0; i<100; i++) { - kb_wait(); - *((unsigned short *)0x472)=0x1234; - outb(0xfe,0x64); /* pulse reset low */ - } - __asm__("\tlidt _no_idt"::); - } -} - - -static fptr key_table[] = { - none,do_self,do_self,do_self, /* 00-03 s0 esc 1 2 */ - do_self,do_self,do_self,do_self, /* 04-07 3 4 5 6 */ - do_self,do_self,do_self,do_self, /* 08-0B 7 8 9 0 */ - do_self,do_self,do_self,do_self, /* 0C-0F + ' bs tab */ - do_self,do_self,do_self,do_self, /* 10-13 q w e r */ - do_self,do_self,do_self,do_self, /* 14-17 t y u i */ - do_self,do_self,do_self,do_self, /* 18-1B o p } ^ */ - enter,ctrl,do_self,do_self, /* 1C-1F enter ctrl a s */ - do_self,do_self,do_self,do_self, /* 20-23 d f g h */ - do_self,do_self,do_self,do_self, /* 24-27 j k l | */ - do_self,do_self,lshift,do_self, /* 28-2B { para lshift , */ - do_self,do_self,do_self,do_self, /* 2C-2F z x c v */ - do_self,do_self,do_self,do_self, /* 30-33 b n m , */ - do_self,slash,rshift,star, /* 34-37 . - rshift * */ - alt,do_self,caps,func, /* 38-3B alt sp caps f1 */ - func,func,func,func, /* 3C-3F f2 f3 f4 f5 */ - func,func,func,func, /* 40-43 f6 f7 f8 f9 */ - func,num,scroll,cursor, /* 44-47 f10 num scr home */ - cursor,cursor,minus,cursor, /* 48-4B up pgup - left */ - cursor,cursor,plus,cursor, /* 4C-4F n5 right + end */ - cursor,cursor,cursor,cursor, /* 50-53 dn pgdn ins del */ - none,none,do_self,func, /* 54-57 sysreq ? < f11 */ - func,none,none,none, /* 58-5B f12 ? ? ? */ - none,none,none,none, /* 5C-5F ? ? ? ? */ - none,none,none,none, /* 60-63 ? ? ? ? */ - none,none,none,none, /* 64-67 ? ? ? ? */ - none,none,none,none, /* 68-6B ? ? ? ? */ - none,none,none,none, /* 6C-6F ? ? ? ? */ - none,none,none,none, /* 70-73 ? ? ? ? */ - none,none,none,none, /* 74-77 ? ? ? ? */ - none,none,none,none, /* 78-7B ? ? ? ? */ - none,none,none,none, /* 7C-7F ? ? ? ? */ - none,none,none,none, /* 80-83 ? br br br */ - none,none,none,none, /* 84-87 br br br br */ - none,none,none,none, /* 88-8B br br br br */ - none,none,none,none, /* 8C-8F br br br br */ - none,none,none,none, /* 90-93 br br br br */ - none,none,none,none, /* 94-97 br br br br */ - none,none,none,none, /* 98-9B br br br br */ - none,unctrl,none,none, /* 9C-9F br unctrl br br */ - none,none,none,none, /* A0-A3 br br br br */ - none,none,none,none, /* A4-A7 br br br br */ - none,none,unlshift,none, /* A8-AB br br unlshift br */ - none,none,none,none, /* AC-AF br br br br */ - none,none,none,none, /* B0-B3 br br br br */ - none,none,unrshift,none, /* B4-B7 br br unrshift br */ - unalt,none,uncaps,none, /* B8-BB unalt br uncaps br */ - none,none,none,none, /* BC-BF br br br br */ - none,none,none,none, /* C0-C3 br br br br */ - none,none,none,none, /* C4-C7 br br br br */ - none,none,none,none, /* C8-CB br br br br */ - none,none,none,none, /* CC-CF br br br br */ - none,none,none,none, /* D0-D3 br br br br */ - none,none,none,none, /* D4-D7 br br br br */ - none,none,none,none, /* D8-DB br ? ? ? */ - none,none,none,none, /* DC-DF ? ? ? ? */ - none,none,none,none, /* E0-E3 e0 e1 ? ? */ - none,none,none,none, /* E4-E7 ? ? ? ? */ - none,none,none,none, /* E8-EB ? ? ? ? */ - none,none,none,none, /* EC-EF ? ? ? ? */ - none,none,none,none, /* F0-F3 ? ? ? ? */ - none,none,none,none, /* F4-F7 ? ? ? ? */ - none,none,none,none, /* F8-FB ? ? ? ? */ - none,none,none,none /* FC-FF ? ? ? ? */ -}; diff --git a/kernel/chr_drv/lp.c b/kernel/chr_drv/lp.c index 4643c27135e8..53d4c9be564a 100644 --- a/kernel/chr_drv/lp.c +++ b/kernel/chr_drv/lp.c @@ -53,6 +53,13 @@ static int lp_write(struct inode * inode, struct file * file, char * buf, int co unsigned int minor = MINOR(inode->i_rdev); char c, *temp = buf; + if (minor >= LP_NO) + return -ENODEV; + if ((LP_F(minor) & LP_EXIST) == 0) + return -ENODEV; + LP_T(minor) = current->pid; + LP_F(minor) |= LP_BUSY; + LP_R(minor) = count; temp = buf; while (count > 0) { c = get_fs_byte(temp++); @@ -90,39 +97,22 @@ static int lp_lseek(struct inode * inode, struct file * file, off_t offset, int return -EINVAL; } -static int lp_open(struct inode * inode, struct file * file) +static int lp_readdir(struct inode * inode, struct file * file, struct dirent * de, int count) { - unsigned int minor = MINOR(inode->i_rdev); - - if (minor >= LP_NO) - return -ENODEV; - if ((LP_F(minor) & LP_EXIST) == 0) - return -ENODEV; - if (LP_F(minor) & LP_BUSY) - return -EBUSY; - LP_F(minor) |= LP_BUSY; - return 0; -} - -static void lp_release(struct inode * inode, struct file * file) -{ - unsigned int minor = MINOR(inode->i_rdev); - - LP_F(minor) &= ~LP_BUSY; + return -ENOTDIR; } static struct file_operations lp_fops = { lp_lseek, lp_read, lp_write, - NULL, /* lp_readdir */ + lp_readdir, + NULL, /* lp_close */ NULL, /* lp_select */ - NULL, /* lp_ioctl */ - lp_open, - lp_release + NULL /* lp_ioctl */ }; -long lp_init(long kmem_start) +void lp_init(void) { int offset = 0; unsigned int testvalue = 0; @@ -145,5 +135,4 @@ long lp_init(long kmem_start) } if (count == 0) printk("lp_init: no lp devices found\n"); - return kmem_start; } diff --git a/kernel/chr_drv/mem.c b/kernel/chr_drv/mem.c index 64d83655bc1e..db3138f5acb8 100644 --- a/kernel/chr_drv/mem.c +++ b/kernel/chr_drv/mem.c @@ -154,17 +154,6 @@ static int write_port(struct inode * inode,struct file * file,char * buf, int co return tmp-buf; } -static int read_zero(struct inode *node,struct file *file,char *buf,int count) -{ - int left; - - for (left = count; left > 0; left--) { - put_fs_byte(0,buf); - buf++; - } - return count; -} - /* * The memory devices use the full 32 bits of the offset, and so we cannot * check against negative addresses: they are ok. The return value is weird, @@ -203,8 +192,6 @@ static int mem_read(struct inode * inode, struct file * file, char * buf, int co return 0; /* /dev/null */ case 4: return read_port(inode,file,buf,count); - case 5: - return read_zero(inode,file,buf,count); default: return -ENODEV; } @@ -223,29 +210,29 @@ static int mem_write(struct inode * inode, struct file * file, char * buf, int c return count; /* /dev/null */ case 4: return write_port(inode,file,buf,count); - case 5: - return count; /* /dev/zero */ default: return -ENODEV; } } +static int mem_readdir(struct inode * inode, struct file * file, struct dirent * de, int count) +{ + return -ENOTDIR; +} + static struct file_operations mem_fops = { mem_lseek, mem_read, mem_write, - NULL, /* mem_readdir */ + mem_readdir, + NULL, /* mem_close */ NULL, /* mem_select */ - NULL, /* mem_ioctl */ - NULL, /* no special open code */ - NULL /* no special release code */ + NULL /* mem_ioctl */ }; -long chr_dev_init(long mem_start, long mem_end) +void chr_dev_init(void) { chrdev_fops[1] = &mem_fops; - mem_start = tty_init(mem_start); - mem_start = lp_init(mem_start); - mem_start = mouse_init(mem_start); - return mem_start; + tty_init(); + lp_init(); } diff --git a/kernel/chr_drv/mouse.c b/kernel/chr_drv/mouse.c deleted file mode 100644 index 66f0cccd7552..000000000000 --- a/kernel/chr_drv/mouse.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Logitech Bus Mouse Driver for Linux - * by James Banks - * - * Heavily modified by David Giller - * changed from queue- to counter- driven - * hacked out a (probably incorrect) mouse_select - * - * Modified again by Nathan Laredo to interface with - * 0.96c-pl1 IRQ handling changes (13JUL92) - * didn't bother touching select code. - * - * Modified the select() code blindly to conform to the VFS - * requirements. 92.07.14 - Linus. Somebody should test it out. - * - * version 0.1 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct mouse_status mouse; - -static void mouse_interrupt(int cpl) -{ - char dx, dy, buttons; - - MSE_INT_OFF(); - - outb(MSE_READ_X_LOW, MSE_CONTROL_PORT); - dx = (inb(MSE_DATA_PORT) & 0xf); - - outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT); - dx |= (inb(MSE_DATA_PORT) & 0xf) << 4; - - outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT ); - dy = (inb(MSE_DATA_PORT) & 0xf); - - outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT); - buttons = inb(MSE_DATA_PORT); - - dy |= (buttons & 0xf) << 4; - buttons = ((buttons >> 5) & 0x07); - - mouse.buttons = buttons; - mouse.latch_buttons |= buttons; - mouse.dx += dx; - mouse.dy += dy; - mouse.ready = 1; - if (mouse.inode && mouse.inode->i_wait) - wake_up(&mouse.inode->i_wait); - - MSE_INT_ON(); -} - -static void release_mouse(struct inode * inode, struct file * file) -{ - MSE_INT_OFF(); - mouse.active = 0; - mouse.ready = 0; - mouse.inode = NULL; - free_irq(MOUSE_IRQ); -} - -static int open_mouse(struct inode * inode, struct file * file) -{ - if (mouse.active) - return -EBUSY; - if (!mouse.present) - return -EINVAL; - if (request_irq(MOUSE_IRQ, mouse_interrupt)) - return -EBUSY; - mouse.active = 1; - mouse.ready = 0; - mouse.inode = inode; - mouse.dx = 0; - mouse.dy = 0; - mouse.buttons = mouse.latch_buttons = 0x80; - MSE_INT_ON(); - return 0; -} - -static int write_mouse(struct inode * inode, struct file * file, char * buffer, int count) -{ - return -EINVAL; -} - -static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count) -{ - int i; - - if (count < 3) return -EINVAL; - if (!mouse.ready) return -EAGAIN; - - MSE_INT_OFF(); - - put_fs_byte(mouse.latch_buttons | 0x80, buffer); - - if (mouse.dx < -127) mouse.dx = -127; - if (mouse.dx > 127) mouse.dx = 127; - - put_fs_byte((char)mouse.dx, buffer + 1); - - if (mouse.dy < -127) mouse.dy = -127; - if (mouse.dy > 127) mouse.dy = 127; - - put_fs_byte((char) -mouse.dy, buffer + 2); - - for (i = 3; i < count; i++) - put_fs_byte(0x00, buffer + i); - - mouse.dx = 0; - mouse.dy = 0; - mouse.latch_buttons = mouse.buttons; - mouse.ready = 0; - - MSE_INT_ON(); - return i; -} - -static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait) -{ - if (sel_type != SEL_IN) - return 0; - if (mouse.ready) - return 1; - select_wait(&inode->i_wait,wait); - return 0; -} - -static struct file_operations mouse_fops = { - NULL, /* mouse_seek */ - read_mouse, - write_mouse, - NULL, /* mouse_readdir */ - mouse_select, /* mouse_select */ - NULL, /* mouse_ioctl */ - open_mouse, - release_mouse, -}; - -long mouse_init(long kmem_start) -{ - int i; - - outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT); - outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT); - - for (i = 0; i < 100000; i++); /* busy loop */ - if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) { - printk("No bus mouse detected.\n"); - mouse.present = 0; - return kmem_start; - } - chrdev_fops[10] = &mouse_fops; - outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT); - - MSE_INT_OFF(); - - mouse.present = 1; - mouse.active = 0; - mouse.ready = 0; - mouse.buttons = mouse.latch_buttons = 0x80; - mouse.dx = 0; - mouse.dy = 0; - printk("Bus mouse detected and installed.\n"); - return kmem_start; -} diff --git a/kernel/chr_drv/pty.c b/kernel/chr_drv/pty.c index 729be84fbe35..0647ce821457 100644 --- a/kernel/chr_drv/pty.c +++ b/kernel/chr_drv/pty.c @@ -12,48 +12,15 @@ * void spty_write(struct tty_struct * queue); */ -#include - #include #include -#include #include #include -int pty_open(unsigned int dev, struct file * filp) -{ - struct tty_struct * tty; - - tty = tty_table + dev; - if (!tty->link) - return -ENODEV; - wake_up(&tty->read_q->proc_list); - if (filp->f_flags & O_NDELAY) - return 0; - while (!tty->link->count && !(current->signal & ~current->blocked)) - interruptible_sleep_on(&tty->link->read_q->proc_list); - if (!tty->link->count) - return -ERESTARTSYS; - return 0; -} - -void pty_close(unsigned int dev, struct file * filp) -{ - struct tty_struct * tty; - - tty = tty_table + dev; - wake_up(&tty->read_q->proc_list); - wake_up(&tty->link->write_q->proc_list); - if (IS_A_PTY_MASTER(dev)) { - if (tty->link->pgrp > 0) - kill_pg(tty->link->pgrp,SIGHUP,1); - } -} - static inline void pty_copy(struct tty_struct * from, struct tty_struct * to) { - int c; + char c; while (!from->stopped && !EMPTY(from->write_q)) { if (FULL(to->read_q)) { @@ -62,8 +29,8 @@ static inline void pty_copy(struct tty_struct * from, struct tty_struct * to) TTY_READ_FLUSH(to); continue; } - c = get_tty_queue(from->write_q); - put_tty_queue(c,to->read_q); + GETCH(from->write_q,c); + PUTCH(c,to->read_q); if (current->signal & ~current->blocked) break; } @@ -78,12 +45,20 @@ static inline void pty_copy(struct tty_struct * from, struct tty_struct * to) */ void mpty_write(struct tty_struct * tty) { - if (tty->link) - pty_copy(tty,tty->link); + int nr = tty - tty_table; + + if ((nr >> 6) != 2) + printk("bad mpty\n\r"); + else + pty_copy(tty,tty+64); } void spty_write(struct tty_struct * tty) { - if (tty->link) - pty_copy(tty,tty->link); + int nr = tty - tty_table; + + if ((nr >> 6) != 3) + printk("bad spty\n\r"); + else + pty_copy(tty,tty-64); } diff --git a/kernel/chr_drv/rs_io.s b/kernel/chr_drv/rs_io.s new file mode 100644 index 000000000000..e74dcd3f329c --- /dev/null +++ b/kernel/chr_drv/rs_io.s @@ -0,0 +1,164 @@ +/* + * linux/kernel/rs_io.s + * + * (C) 1991 Linus Torvalds + */ + +/* + * rs_io.s + * + * This module implements the rs232 io interrupts. + */ + +.text +.globl _rs1_interrupt,_rs2_interrupt + +size = 2048 /* must be power of two ! + and must match the value + in tty_io.c!!! */ + +/* these are the offsets into the read/write buffer structures */ +rs_addr = 0 +head = 4 +tail = 8 +proc_list = 12 +buf = 16 + +startup = 256 /* chars left in write queue when we restart it */ + +/* + * These are the actual interrupt routines. They look where + * the interrupt is coming from, and take appropriate action. + * + * rs1_interrupt (IRQ 4) takes care of com1 and com3 + * rs2_interrupt (IRQ 3) takes care of com2 and com4 + */ +.align 2 +_rs1_interrupt: + pushl $_table_list+8 + pushl $_table_list+24 + jmp rs_int + +.align 2 +_rs2_interrupt: + pushl $_table_list+16 + pushl $_table_list+32 +rs_int: cld + pushl %edx + pushl %ecx + pushl %ebx + pushl %eax + push %es + push %ds /* as this is an interrupt, we cannot */ + pushl $0x10 /* know that bs is ok. Load it */ + pop %ds + pushl $0x10 + pop %es + movl 24(%esp),%edx + call do_rs_intr + movl 28(%esp),%edx + call do_rs_intr + movb $0x20,%al + outb %al,$0x20 /* EOI */ + pop %ds + pop %es + popl %eax + popl %ebx + popl %ecx + popl %edx + addl $8,%esp # jump over the _table_list entries + iret + +do_rs_intr: + pushl %edx + movl (%edx),%edx + movl rs_addr(%edx),%edx + addl $2,%edx /* interrupt ident. reg */ +1: xorl %eax,%eax + inb %dx,%al + testb $1,%al + jne 2f + cmpb $6,%al /* this shouldn't happen, but ... */ + ja 2f + movl (%esp),%ecx + pushl %edx + subl $2,%edx + call jmp_table(,%eax,2) /* NOTE! not *4, bit0 is 0 already */ + popl %edx + jmp 1b +2: popl %edx + ret + +jmp_table: + .long modem_status,write_char,read_char,line_status + +.align 2 +modem_status: + addl $6,%edx /* clear intr by reading modem status reg */ + inb %dx,%al + ret + +.align 2 +line_status: + addl $5,%edx /* clear intr by reading line status reg. */ + inb %dx,%al + ret + +.align 2 +read_char: + inb %dx,%al + movl %ecx,%edx + subl $_table_list,%edx + shrl $3,%edx + movl (%ecx),%ecx # read-queue + movl head(%ecx),%ebx + movb %al,buf(%ecx,%ebx) + incl %ebx + andl $size-1,%ebx + cmpl tail(%ecx),%ebx + je 1f + movl %ebx,head(%ecx) +1: movl mask_table(,%edx,4),%edx + orl %edx,_timer_active + ret + +.align 2 +mask_table: + .long 0,4,8,16,32 + +.align 2 +write_char: + movl 4(%ecx),%ecx # write-queue + movl head(%ecx),%ebx + subl tail(%ecx),%ebx + andl $size-1,%ebx # nr chars in queue + je write_buffer_empty + cmpl $startup,%ebx + ja 1f + movl proc_list(%ecx),%ebx # wake up sleeping process + testl %ebx,%ebx # is there any? + je 1f + movl $0,(%ebx) +1: movl tail(%ecx),%ebx + movb buf(%ecx,%ebx),%al + outb %al,%dx + incl %ebx + andl $size-1,%ebx + movl %ebx,tail(%ecx) + cmpl head(%ecx),%ebx + je write_buffer_empty + ret + +.align 2 +write_buffer_empty: + movl proc_list(%ecx),%ebx # wake up sleeping process + testl %ebx,%ebx # is there any? + je 1f + movl $0,(%ebx) +1: incl %edx + inb %dx,%al + jmp 1f +1: jmp 1f +1: andb $0xd,%al # disable transmit interrupt + outb %al,%dx + ret diff --git a/kernel/chr_drv/serial.c b/kernel/chr_drv/serial.c index 284f0b62a2ed..f6260714eaf5 100644 --- a/kernel/chr_drv/serial.c +++ b/kernel/chr_drv/serial.c @@ -9,193 +9,22 @@ * * This module implements the rs232 io functions * void rs_write(struct tty_struct * queue); - * long rs_init(long); + * void rs_init(void); * and all interrupts pertaining to serial IO. */ -#include -#include - #include #include #include #include #include -#include - -#define WAKEUP_CHARS (3*TTY_BUF_SIZE/4) - -struct serial_struct serial_table[NR_SERIALS] = { - { PORT_UNKNOWN, 0, 0x3F8, 4, NULL}, - { PORT_UNKNOWN, 1, 0x2F8, 3, NULL}, - { PORT_UNKNOWN, 2, 0x3E8, 4, NULL}, - { PORT_UNKNOWN, 3, 0x2E8, 3, NULL}, -}; - -static void send_intr(struct serial_struct * info); - -static void modem_status_intr(struct serial_struct * info) -{ - unsigned char status = inb(info->port+6); - - if (!(info->tty->termios.c_cflag & CLOCAL)) { - if ((status & 0x88) == 0x08 && info->tty->pgrp > 0) - kill_pg(info->tty->pgrp,SIGHUP,1); - - if (info->tty->termios.c_cflag & CRTSCTS) - info->tty->stopped = !(status & 0x10); - - if (!info->tty->stopped) - send_intr(info); - } -} - -void send_break(unsigned int line) -{ - unsigned short port; - struct serial_struct * info; - - if (line >= NR_SERIALS) - return; - info = serial_table + line; - if (!(port = info->port)) - return; - port += 3; - current->state = TASK_INTERRUPTIBLE; - current->timeout = jiffies + 25; - outb_p(inb_p(port) | 0x40,port); - schedule(); - outb_p(inb_p(port) & 0xbf,port); -} - -/* - * There are several races here: we avoid most of them by disabling timer_active - * for the crucial part of the process.. That's a good idea anyway. - * - * The problem is that we have to output characters /both/ from interrupts - * and from the normal write: the latter to be sure the interrupts start up - * again. With serial lines, the interrupts can happen so often that the - * races actually are noticeable. - */ -static void send_intr(struct serial_struct * info) -{ - unsigned short port = info->port; - unsigned int timer = SER1_TIMEOUT + info->line; - struct tty_queue * queue = info->tty->write_q; - int c, i = 0; - - if (info->tty->stopped) return; - - timer_active &= ~(1 << timer); - while (inb_p(info->port+5) & 0x20) { - if (queue->tail == queue->head) - goto end_send; - c = queue->buf[queue->tail]; - queue->tail++; - queue->tail &= TTY_BUF_SIZE-1; - outb(c,port); - if ((info->type != PORT_16550A) || (++i >= 14) || info->tty->stopped) - break; - } - timer_table[timer].expires = jiffies + 10; - timer_active |= 1 << timer; -end_send: - if (LEFT(queue) > WAKEUP_CHARS) - wake_up(&queue->proc_list); -} - -static void receive_intr(struct serial_struct * info) -{ - unsigned short port = info->port; - struct tty_queue * queue = info->tty->read_q; - int head = queue->head; - int maxhead = (queue->tail-1) & (TTY_BUF_SIZE-1); - - timer_active &= ~((1<line); - do { - queue->buf[head] = inb(port); - if (head != maxhead) { - head++; - head &= TTY_BUF_SIZE-1; - } - } while (inb(port+5) & 1); - queue->head = head; - timer_active |= (1<line; -} - -static void line_status_intr(struct serial_struct * info) -{ - unsigned char status = inb(info->port+5); - -/* printk("line status: %02x\n",status); */ -} - -static void (*jmp_table[4])(struct serial_struct *) = { - modem_status_intr, - send_intr, - receive_intr, - line_status_intr -}; - -static void check_tty(struct serial_struct * info) -{ - unsigned char ident; - - if (!info || !info->tty || !info->port) - return; - while (1) { - ident = inb(info->port+2) & 7; - if (ident & 1) - return; - ident >>= 1; - if (ident > 3) - return; - jmp_table[ident](info); - } -} - -/* - * Again, we disable interrupts to be sure there aren't any races: - * see send_intr for details. - */ -static inline void do_rs_write(struct serial_struct * info) -{ - if (!info->tty || !info->port) - return; - if (!info->tty->write_q || EMPTY(info->tty->write_q)) - return; - cli(); - send_intr(info); - sti(); -} - -/* - * IRQ routines: one per line - */ -static void com1_IRQ(int cpl) -{ - check_tty(serial_table+0); -} - -static void com2_IRQ(int cpl) -{ - check_tty(serial_table+1); -} -static void com3_IRQ(int cpl) -{ - check_tty(serial_table+2); -} +#define WAKEUP_CHARS (TTY_BUF_SIZE/4) -static void com4_IRQ(int cpl) -{ - check_tty(serial_table+3); -} +extern void rs1_interrupt(void); +extern void rs2_interrupt(void); -/* - * Receive timer routines: one per line - */ static void com1_timer(void) { TTY_READ_FLUSH(tty_table+64); @@ -216,234 +45,89 @@ static void com4_timer(void) TTY_READ_FLUSH(tty_table+67); } -/* - * Send timeout routines: one per line - */ +static inline void do_rs_write(unsigned int port) +{ + char c; + +#define TTY (tty_table[64+port].write_q) +#define TIMER (SER1_TIMEOUT+port) + cli(); + if (!EMPTY(TTY)) { + outb_p(inb_p(TTY->data+1)|0x02,TTY->data+1); + if (inb(TTY->data+5) & 0x20) { + GETCH(TTY,c); + outb(c,TTY->data); + } + timer_table[TIMER].expires = jiffies + 50; + timer_active |= 1 << TIMER; + } else + timer_active &= ~(1 << TIMER); + sti(); +#undef TIMER +#undef TTY +} + static void com1_timeout(void) { - do_rs_write(serial_table); + do_rs_write(0); } static void com2_timeout(void) { - do_rs_write(serial_table + 1); + do_rs_write(1); } static void com3_timeout(void) { - do_rs_write(serial_table + 2); + do_rs_write(2); } static void com4_timeout(void) { - do_rs_write(serial_table + 3); + do_rs_write(3); } -static void init(struct serial_struct * info) +static void init(int port) { - unsigned char status1, status2, scratch; - unsigned short port = info->port; - - if (inb(port+5) == 0xff) { - info->type = PORT_UNKNOWN; - return; - } - - scratch = inb(port+7); - outb_p(0xa5, port+7); - status1 = inb(port+7); - outb_p(0x5a, port+7); - status2 = inb(port+7); - if (status1 == 0xa5 && status2 == 0x5a) { - outb_p(scratch, port+7); - outb_p(0x01, port+2); - scratch = inb(port+2) >> 6; - switch (scratch) { - case 0: - info->type = PORT_16450; - break; - case 1: - info->type = PORT_UNKNOWN; - break; - case 2: - info->type = PORT_16550; - outb_p(0x00, port+2); - break; - case 3: - info->type = PORT_16550A; - outb_p(0xc7, port+2); - break; - } - } else - info->type = PORT_8250; outb_p(0x80,port+3); /* set DLAB of line control reg */ - outb_p(0x30,port); /* LS of divisor (48 -> 2400 bps) */ + outb_p(0x30,port); /* LS of divisor (48 -> 2400 bps */ outb_p(0x00,port+1); /* MS of divisor */ outb_p(0x03,port+3); /* reset DLAB */ outb_p(0x00,port+4); /* reset DTR,RTS, OUT_2 */ - outb_p(0x00,port+1); /* disable all intrs */ + outb_p(0x0d,port+1); /* enable all intrs but writes */ (void)inb(port); /* read data port to reset things (?) */ } -void serial_close(unsigned line, struct file * filp) +/* + * this routine enables interrupts on 'line', and disables them on + * 'line ^ 2', as they share the same IRQ. Braindamaged AT hardware. + */ +void serial_open(unsigned int line) { - struct serial_struct * info; - int irq; + unsigned short port; + unsigned short port2; - if (line >= NR_SERIALS) + if (line>3) return; - info = serial_table + line; - if (!info->port) + port = tty_table[64+line].read_q->data; + if (!port) return; - outb(0x00,info->port+4); /* reset DTR, RTS, */ - irq = info->irq; - if (irq == 2) - irq = 9; - free_irq(irq); -} - -static void startup(unsigned short port) -{ + port2 = tty_table[64+(line ^ 2)].read_q->data; + cli(); + if (port2) + outb_p(0x00,port2+4); outb_p(0x03,port+3); /* reset DLAB */ outb_p(0x0f,port+4); /* set DTR,RTS, OUT_2 */ - outb_p(0x0f,port+1); /* enable all intrs */ - inb_p(port+2); - inb_p(port+6); - inb_p(port+2); - inb_p(port+5); - do { /* drain all of the stuck characters out of the port */ - inb_p(port+0); - } while (inb_p(port+5) & 1 == 1); - inb_p(port+2); + outb_p(0x0d,port+1); /* enable all intrs but writes */ inb_p(port+5); -} - -void change_speed(unsigned int line) -{ - struct serial_struct * info; - unsigned short port,quot; - unsigned cflag,cval; - static unsigned short quotient[] = { - 0, 2304, 1536, 1047, 857, - 768, 576, 384, 192, 96, - 64, 48, 24, 12, 6, 3 - }; - - if (line >= NR_SERIALS) - return; - info = serial_table + line; - cflag = info->tty->termios.c_cflag; - if (!(port = info->port)) - return; - quot = quotient[cflag & CBAUD]; - if (!quot) - outb(0x00,port+4); - else if (!inb(port+4)) - startup(port); -/* byte size and parity */ - cval = cflag & (CSIZE | CSTOPB); - cval >>= 4; - if (cflag & PARENB) - cval |= 8; - if (!(cflag & PARODD)) - cval |= 16; - cli(); - outb_p(cval | 0x80,port+3); /* set DLAB */ - outb_p(quot & 0xff,port); /* LS of divisor */ - outb_p(quot >> 8,port+1); /* MS of divisor */ - outb(cval,port+3); /* reset DLAB */ - sti(); -} - -static void (*serial_handler[NR_SERIALS])(int) = { - com1_IRQ,com2_IRQ,com3_IRQ,com4_IRQ -}; - -/* - * this routine enables interrupts on 'line', and disables them for any - * other serial line that shared the same IRQ. Braindamaged AT hardware. - */ -int serial_open(unsigned line, struct file * filp) -{ - struct serial_struct * info; - int irq,retval; - unsigned short port; - void (*handler)(int) = serial_handler[line]; - - if (line >= NR_SERIALS) - return -ENODEV; - info = serial_table + line; - if (!(port = info->port)) - return -ENODEV; - irq = info->irq; - if (irq == 2) - irq = 9; - if (retval = request_irq(irq,handler)) - return retval; - startup(port); - return 0; -} - -int get_serial_info(unsigned int line, struct serial_struct * info) -{ - if (line >= NR_SERIALS) - return -ENODEV; - if (!info) - return -EFAULT; - memcpy_tofs(info,serial_table+line,sizeof(*info)); - return 0; -} - -int set_serial_info(unsigned int line, struct serial_struct * info) -{ - struct serial_struct tmp; - unsigned new_port; - unsigned irq,new_irq; - int retval; - void (*handler)(int) = serial_handler[line]; - - if (!suser()) - return -EPERM; - if (line >= NR_SERIALS) - return -ENODEV; - if (!info) - return -EFAULT; - memcpy_fromfs(&tmp,info,sizeof(tmp)); - info = serial_table + line; - if (!(new_port = tmp.port)) - new_port = info->port; - if (!(new_irq = tmp.irq)) - new_irq = info->irq; - if (new_irq > 15 || new_port > 0xffff) - return -EINVAL; - if (new_irq == 2) - new_irq = 9; - irq = info->irq; - if (irq == 2) - irq = 9; - if (irq != new_irq) { - retval = request_irq(new_irq,handler); - if (retval) - return retval; - info->irq = new_irq; - free_irq(irq); - } - cli(); - if (new_port != info->port) { - outb(0x00,info->port+4); /* reset DTR, RTS, */ - info->port = new_port; - init(info); - startup(new_port); - } + inb_p(port+0); + inb(port+6); + inb(port+2); sti(); - return 0; } -long rs_init(long kmem_start) +void rs_init(void) { - int i; - struct serial_struct * info; - /* SERx_TIMER timers are used for receiving: timeout is always 0 (immediate) */ timer_table[SER1_TIMER].fn = com1_timer; timer_table[SER1_TIMER].expires = 0; @@ -462,31 +146,13 @@ long rs_init(long kmem_start) timer_table[SER3_TIMEOUT].expires = 0; timer_table[SER4_TIMEOUT].fn = com4_timeout; timer_table[SER4_TIMEOUT].expires = 0; - for (i = 0, info = serial_table; i < NR_SERIALS; i++,info++) { - info->tty = (tty_table+64) + i; - init(info); - if (info->type == PORT_UNKNOWN) - continue; - printk("serial port at 0x%04x (irq = %d)",info->port,info->irq); - switch (info->type) { - case PORT_8250: - printk(" is a 8250\n"); - break; - case PORT_16450: - printk(" is a 16450\n"); - break; - case PORT_16550: - printk(" is a 16550\n"); - break; - case PORT_16550A: - printk(" is a 16550A\n"); - break; - default: - printk("\n"); - break; - } - } - return kmem_start; + set_intr_gate(0x24,rs1_interrupt); + set_intr_gate(0x23,rs2_interrupt); + init(tty_table[64].read_q->data); + init(tty_table[65].read_q->data); + init(tty_table[66].read_q->data); + init(tty_table[67].read_q->data); + outb(inb_p(0x21)&0xE7,0x21); } /* @@ -498,7 +164,9 @@ long rs_init(long kmem_start) */ void rs_write(struct tty_struct * tty) { - int line = tty - tty_table - 64; - - do_rs_write(serial_table+line); + cli(); + if (!EMPTY(tty->write_q)) + outb_p(inb_p(tty->write_q->data+1)|0x02,tty->write_q->data+1); + timer_active |= 15 << SER1_TIMEOUT; + sti(); } diff --git a/kernel/chr_drv/tty_io.c b/kernel/chr_drv/tty_io.c index f50227ccbf20..8e376bb82cbf 100644 --- a/kernel/chr_drv/tty_io.c +++ b/kernel/chr_drv/tty_io.c @@ -11,109 +11,88 @@ * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0. */ +#include #include #include - -#include +#include +#include #define ALRMMASK (1<<(SIGALRM-1)) #include #include -#include -#include #include #include -#include -#include "vt_kern.h" +int kill_pg(int pgrp, int sig, int priv); +int is_orphaned_pgrp(int pgrp); + +extern void lp_init(void); + +#define _L_FLAG(tty,f) ((tty)->termios.c_lflag & f) +#define _I_FLAG(tty,f) ((tty)->termios.c_iflag & f) +#define _O_FLAG(tty,f) ((tty)->termios.c_oflag & f) + +#define L_CANON(tty) _L_FLAG((tty),ICANON) +#define L_ISIG(tty) _L_FLAG((tty),ISIG) +#define L_ECHO(tty) _L_FLAG((tty),ECHO) +#define L_ECHOE(tty) _L_FLAG((tty),ECHOE) +#define L_ECHOK(tty) _L_FLAG((tty),ECHOK) +#define L_ECHONL(tty) _L_FLAG((tty),ECHONL) +#define L_ECHOCTL(tty) _L_FLAG((tty),ECHOCTL) +#define L_ECHOKE(tty) _L_FLAG((tty),ECHOKE) +#define L_TOSTOP(tty) _L_FLAG((tty),TOSTOP) + +#define I_UCLC(tty) _I_FLAG((tty),IUCLC) +#define I_NLCR(tty) _I_FLAG((tty),INLCR) +#define I_CRNL(tty) _I_FLAG((tty),ICRNL) +#define I_NOCR(tty) _I_FLAG((tty),IGNCR) +#define I_IXON(tty) _I_FLAG((tty),IXON) +#define I_STRP(tty) _I_FLAG((tty),ISTRIP) + +#define O_POST(tty) _O_FLAG((tty),OPOST) +#define O_NLCR(tty) _O_FLAG((tty),ONLCR) +#define O_CRNL(tty) _O_FLAG((tty),OCRNL) +#define O_NLRET(tty) _O_FLAG((tty),ONLRET) +#define O_LCUC(tty) _O_FLAG((tty),OLCUC) + +#define C_SPEED(tty) ((tty)->termios.c_cflag & CBAUD) +#define C_HUP(tty) (C_SPEED((tty)) == B0) #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif -#define QUEUES (3*(NR_CONSOLES+NR_SERIALS+2*NR_PTYS)) -static struct tty_queue * tty_queues; +#define QUEUES (3*(MAX_CONSOLES+NR_SERIALS+2*NR_PTYS)) +static struct tty_queue tty_queues[QUEUES]; struct tty_struct tty_table[256]; #define con_queues tty_queues -#define rs_queues ((3*NR_CONSOLES) + tty_queues) -#define mpty_queues ((3*(NR_CONSOLES+NR_SERIALS)) + tty_queues) -#define spty_queues ((3*(NR_CONSOLES+NR_SERIALS+NR_PTYS)) + tty_queues) +#define rs_queues ((3*MAX_CONSOLES) + tty_queues) +#define mpty_queues ((3*(MAX_CONSOLES+NR_SERIALS)) + tty_queues) +#define spty_queues ((3*(MAX_CONSOLES+NR_SERIALS+NR_PTYS)) + tty_queues) #define con_table tty_table #define rs_table (64+tty_table) #define mpty_table (128+tty_table) #define spty_table (192+tty_table) -/* - * fg_console is the current virtual console, - * redirect is the pseudo-tty that console output - * is redirected to if asked by TIOCCONS. - */ int fg_console = 0; -struct tty_struct * redirect = NULL; /* * these are the tables used by the machine code handlers. * you can implement virtual consoles. */ -struct tty_queue * table_list[] = { NULL, NULL }; - -void put_tty_queue(char c, struct tty_queue * queue) -{ - int head; - unsigned long flags; - - __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); - head = (queue->head + 1) & (TTY_BUF_SIZE-1); - if (head != queue->tail) { - queue->buf[queue->head] = c; - queue->head = head; - } - __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); -} - -int get_tty_queue(struct tty_queue * queue) -{ - int result = -1; - unsigned long flags; - - __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); - if (queue->tail != queue->head) { - result = 0xff & queue->buf[queue->tail]; - queue->tail = (queue->tail + 1) & (TTY_BUF_SIZE-1); - } - __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); - return result; -} - -void tty_write_flush(struct tty_struct * tty) -{ - if (EMPTY(tty->write_q)) - return; - if (set_bit(TTY_WRITE_BUSY,&tty->flags)) - return; - tty->write(tty); - if (clear_bit(TTY_WRITE_BUSY,&tty->flags)) - printk("tty_write_flush: bit already cleared\n"); -} - -void tty_read_flush(struct tty_struct * tty) -{ - if (EMPTY(tty->read_q)) - return; - if (set_bit(TTY_READ_BUSY, &tty->flags)) - return; - copy_to_cooked(tty); - if (clear_bit(TTY_READ_BUSY, &tty->flags)) - printk("tty_read_flush: bit already cleared\n"); -} +struct tty_queue * table_list[]={ + con_queues + 0, con_queues + 1, + rs_queues + 0, rs_queues + 1, + rs_queues + 3, rs_queues + 4, + rs_queues + 6, rs_queues + 7, + rs_queues + 9, rs_queues + 10 + }; void change_console(unsigned int new_console) { - if (vt_cons[fg_console].vt_mode == KD_GRAPHICS) - return; if (new_console == fg_console || new_console >= NR_CONSOLES) return; table_list[0] = con_queues + 0 + new_console*3; @@ -129,6 +108,16 @@ static void sleep_if_empty(struct tty_queue * queue) sti(); } +static void sleep_if_full(struct tty_queue * queue) +{ + if (!FULL(queue)) + return; + cli(); + while (!(current->signal & ~current->blocked) && LEFT(queue)<128) + interruptible_sleep_on(&queue->proc_list); + sti(); +} + void wait_for_keypress(void) { sleep_if_empty(tty_table[fg_console].secondary); @@ -136,7 +125,7 @@ void wait_for_keypress(void) void copy_to_cooked(struct tty_struct * tty) { - int c; + unsigned char c; if (!(tty && tty->write && tty->read_q && tty->write_q && tty->secondary)) { @@ -144,11 +133,15 @@ void copy_to_cooked(struct tty_struct * tty) return; } while (1) { - if (FULL(tty->secondary)) + if (EMPTY(tty->read_q)) break; - c = get_tty_queue(tty->read_q); - if (c < 0) + if (FULL(tty->secondary)) { + if (tty->secondary->proc_list) + if (tty->secondary->proc_list != current) + current->counter = 0; break; + } + GETCH(tty->read_q,c); if (I_STRP(tty)) c &= 0x7f; if (c==13) { @@ -161,44 +154,34 @@ void copy_to_cooked(struct tty_struct * tty) if (I_UCLC(tty)) c=tolower(c); if (L_CANON(tty)) { - if ((KILL_CHAR(tty) != __DISABLED_CHAR) && + if ((KILL_CHAR(tty) != _POSIX_VDISABLE) && (c==KILL_CHAR(tty))) { /* deal with killing the input line */ while(!(EMPTY(tty->secondary) || (c=LAST(tty->secondary))==10 || - ((EOF_CHAR(tty) != __DISABLED_CHAR) && + ((EOF_CHAR(tty) != _POSIX_VDISABLE) && (c==EOF_CHAR(tty))))) { if (L_ECHO(tty)) { - if (c<32) { - put_tty_queue(8,tty->write_q); - put_tty_queue(' ',tty->write_q); - put_tty_queue(8,tty->write_q); - } - put_tty_queue(8,tty->write_q); - put_tty_queue(' ',tty->write_q); - put_tty_queue(8,tty->write_q); + if (c<32) + PUTCH(127,tty->write_q); + PUTCH(127,tty->write_q); TTY_WRITE_FLUSH(tty); } DEC(tty->secondary->head); } continue; } - if ((ERASE_CHAR(tty) != __DISABLED_CHAR) && + if ((ERASE_CHAR(tty) != _POSIX_VDISABLE) && (c==ERASE_CHAR(tty))) { if (EMPTY(tty->secondary) || (c=LAST(tty->secondary))==10 || - ((EOF_CHAR(tty) != __DISABLED_CHAR) && + ((EOF_CHAR(tty) != _POSIX_VDISABLE) && (c==EOF_CHAR(tty)))) continue; if (L_ECHO(tty)) { - if (c<32) { - put_tty_queue(8,tty->write_q); - put_tty_queue(' ',tty->write_q); - put_tty_queue(8,tty->write_q); - } - put_tty_queue(8,tty->write_q); - put_tty_queue(32,tty->write_q); - put_tty_queue(8,tty->write_q); + if (c<32) + PUTCH(127,tty->write_q); + PUTCH(127,tty->write_q); TTY_WRITE_FLUSH(tty); } DEC(tty->secondary->head); @@ -206,12 +189,12 @@ void copy_to_cooked(struct tty_struct * tty) } } if (I_IXON(tty)) { - if ((STOP_CHAR(tty) != __DISABLED_CHAR) && + if ((STOP_CHAR(tty) != _POSIX_VDISABLE) && (c==STOP_CHAR(tty))) { tty->stopped=1; continue; } - if ((START_CHAR(tty) != __DISABLED_CHAR) && + if ((START_CHAR(tty) != _POSIX_VDISABLE) && (c==START_CHAR(tty))) { tty->stopped=0; TTY_WRITE_FLUSH(tty); @@ -219,39 +202,37 @@ void copy_to_cooked(struct tty_struct * tty) } } if (L_ISIG(tty)) { - if ((INTR_CHAR(tty) != __DISABLED_CHAR) && + if ((INTR_CHAR(tty) != _POSIX_VDISABLE) && (c==INTR_CHAR(tty))) { kill_pg(tty->pgrp, SIGINT, 1); - flush_input(tty); continue; } - if ((QUIT_CHAR(tty) != __DISABLED_CHAR) && + if ((QUIT_CHAR(tty) != _POSIX_VDISABLE) && (c==QUIT_CHAR(tty))) { kill_pg(tty->pgrp, SIGQUIT, 1); - flush_input(tty); continue; } - if ((SUSPEND_CHAR(tty) != __DISABLED_CHAR) && + if ((SUSPEND_CHAR(tty) != _POSIX_VDISABLE) && (c==SUSPEND_CHAR(tty))) { if (!is_orphaned_pgrp(tty->pgrp)) kill_pg(tty->pgrp, SIGTSTP, 1); continue; } } - if (c==10 || (EOF_CHAR(tty) != __DISABLED_CHAR && + if (c==10 || (EOF_CHAR(tty) != _POSIX_VDISABLE && c==EOF_CHAR(tty))) tty->secondary->data++; - if ((L_ECHO(tty) || (L_CANON(tty) && L_ECHONL(tty))) && (c==10)) { - put_tty_queue(10,tty->write_q); - put_tty_queue(13,tty->write_q); + if ((L_ECHO(tty) || L_ECHONL(tty)) && (c==10)) { + PUTCH(10,tty->write_q); + PUTCH(13,tty->write_q); } else if (L_ECHO(tty)) { if (c<32 && L_ECHOCTL(tty)) { - put_tty_queue('^',tty->write_q); - put_tty_queue(c+64,tty->write_q); + PUTCH('^',tty->write_q); + PUTCH(c+64,tty->write_q); } else - put_tty_queue(c,tty->write_q); + PUTCH(c,tty->write_q); } - put_tty_queue(c,tty->secondary); + PUTCH(c,tty->secondary); TTY_WRITE_FLUSH(tty); } TTY_WRITE_FLUSH(tty); @@ -261,12 +242,6 @@ void copy_to_cooked(struct tty_struct * tty) wake_up(&tty->write_q->proc_list); } -int is_ignored(int sig) -{ - return ((current->blocked & (1<<(sig-1))) || - (current->sigaction[sig-1].sa_handler == SIG_IGN)); -} - /* * Called when we need to send a SIGTTIN or SIGTTOU to our process * group @@ -284,36 +259,24 @@ int is_ignored(int sig) */ int tty_signal(int sig, struct tty_struct *tty) { + if (is_orphaned_pgrp(current->pgrp)) + return -EIO; /* don't stop an orphaned pgrp */ (void) kill_pg(current->pgrp,sig,1); - return -ERESTARTSYS; -} - -static void wait_for_canon_input(struct tty_struct * tty) -{ - while (1) { - TTY_READ_FLUSH(tty); - if (tty->link) - if (tty->link->count) - TTY_WRITE_FLUSH(tty->link); - else - return; - if (current->signal & ~current->blocked) - return; - if (FULL(tty->read_q)) - return; - if (tty->secondary->data) - return; - cli(); - if (!tty->secondary->data) - interruptible_sleep_on(&tty->secondary->proc_list); - sti(); - } + if ((current->blocked & (1<<(sig-1))) || + ((int) current->sigaction[sig-1].sa_handler == 1)) + return -EIO; /* Our signal will be ignored */ + else if (current->sigaction[sig-1].sa_handler) + return -EINTR; /* We _will_ be interrupted :-) */ + else + return -ERESTARTSYS; /* We _will_ be interrupted :-) */ + /* (but restart after we continue) */ } static int read_chan(unsigned int channel, struct file * file, char * buf, int nr) { struct tty_struct * tty; - int c; + struct tty_struct * other_tty = NULL; + unsigned char c; char * b=buf; int minimum,time; @@ -322,71 +285,71 @@ static int read_chan(unsigned int channel, struct file * file, char * buf, int n tty = TTY_TABLE(channel); if (!(tty->read_q && tty->secondary)) return -EIO; - if ((tty->pgrp > 0) && - (current->tty == channel) && + if ((tty->pgrp > 0) && (current->tty == channel) && (tty->pgrp != current->pgrp)) - if (is_ignored(SIGTTIN) || is_orphaned_pgrp(current->pgrp)) - return -EIO; - else - return(tty_signal(SIGTTIN, tty)); - if (L_CANON(tty)) - minimum = time = current->timeout = 0; + return(tty_signal(SIGTTIN, tty)); + if (channel & 0x80) + other_tty = tty_table + (channel ^ 0x40); + time = 10L*tty->termios.c_cc[VTIME]; + minimum = tty->termios.c_cc[VMIN]; + if (L_CANON(tty)) { + minimum = nr; + current->timeout = 0xffffffff; + time = 0; + } else if (minimum) + current->timeout = 0xffffffff; else { - time = 10L*tty->termios.c_cc[VTIME]; - minimum = tty->termios.c_cc[VMIN]; - if (minimum) - current->timeout = 0xffffffff; - else { - if (time) - current->timeout = time + jiffies; - else - current->timeout = 0; - time = 0; - minimum = 1; - } + minimum = nr; + if (time) + current->timeout = time + jiffies; + time = 0; } if (file->f_flags & O_NONBLOCK) time = current->timeout = 0; - else if (L_CANON(tty)) - wait_for_canon_input(tty); if (minimum>nr) minimum = nr; + TTY_READ_FLUSH(tty); while (nr>0) { - TTY_READ_FLUSH(tty); - if (tty->link) - TTY_WRITE_FLUSH(tty->link); - while (nr > 0 && ((c = get_tty_queue(tty->secondary)) >= 0)) { - if ((EOF_CHAR(tty) != __DISABLED_CHAR && + if (other_tty && other_tty->write) + TTY_WRITE_FLUSH(other_tty); + cli(); + if (EMPTY(tty->secondary) || (L_CANON(tty) && + !FULL(tty->read_q) && !tty->secondary->data)) { + if (!current->timeout) + break; + if (current->signal & ~current->blocked) + break; + if (IS_A_PTY_SLAVE(channel) && C_HUP(other_tty)) + break; + interruptible_sleep_on(&tty->secondary->proc_list); + sti(); + TTY_READ_FLUSH(tty); + continue; + } + sti(); + do { + GETCH(tty->secondary,c); + if ((EOF_CHAR(tty) != _POSIX_VDISABLE && c==EOF_CHAR(tty)) || c==10) tty->secondary->data--; - if ((EOF_CHAR(tty) != __DISABLED_CHAR && + if ((EOF_CHAR(tty) != _POSIX_VDISABLE && c==EOF_CHAR(tty)) && L_CANON(tty)) break; - put_fs_byte(c,b++); - nr--; - if (time) - current->timeout = time+jiffies; + else { + put_fs_byte(c,b++); + if (!--nr) + break; + } if (c==10 && L_CANON(tty)) break; - }; + } while (nr>0 && !EMPTY(tty->secondary)); wake_up(&tty->read_q->proc_list); - if (b-buf >= minimum || !current->timeout) - break; - if (current->signal & ~current->blocked) + if (L_CANON(tty) || b-buf >= minimum) break; - if (tty->link && !tty->link->count) - break; - TTY_READ_FLUSH(tty); - if (tty->link) - TTY_WRITE_FLUSH(tty->link); - cli(); - if (EMPTY(tty->secondary)) - interruptible_sleep_on(&tty->secondary->proc_list); - sti(); + if (time) + current->timeout = time+jiffies; } - TTY_READ_FLUSH(tty); - if (tty->link && tty->link->write) - TTY_WRITE_FLUSH(tty->link); + sti(); current->timeout = 0; if (b-buf) return b-buf; @@ -399,42 +362,26 @@ static int read_chan(unsigned int channel, struct file * file, char * buf, int n static int write_chan(unsigned int channel, struct file * file, char * buf, int nr) { + static cr_flag=0; struct tty_struct * tty; char c, *b=buf; if (channel > 255) return -EIO; tty = TTY_TABLE(channel); - if (L_TOSTOP(tty) && (tty->pgrp > 0) && - (current->tty == channel) && (tty->pgrp != current->pgrp)) { - if (is_orphaned_pgrp(tty->pgrp)) - return -EIO; - if (!is_ignored(SIGTTOU)) - return tty_signal(SIGTTOU, tty); - } + if (!(tty->write_q && tty->write)) + return -EIO; + if (L_TOSTOP(tty) && (tty->pgrp > 0) && + (current->tty == channel) && (tty->pgrp != current->pgrp)) + return(tty_signal(SIGTTOU, tty)); if (nr < 0) return -EINVAL; if (!nr) return 0; - if (redirect && tty == TTY_TABLE(0)) - tty = redirect; - if (!(tty->write_q && tty->write)) - return -EIO; while (nr>0) { + sleep_if_full(tty->write_q); if (current->signal & ~current->blocked) break; - if (tty->link && !tty->link->count) { - send_sig(SIGPIPE,current,0); - break; - } - if (FULL(tty->write_q)) { - TTY_WRITE_FLUSH(tty); - cli(); - if (FULL(tty->write_q)) - interruptible_sleep_on(&tty->write_q->proc_list); - sti(); - continue; - } while (nr>0 && !FULL(tty->write_q)) { c=get_fs_byte(b); if (O_POST(tty)) { @@ -442,26 +389,24 @@ static int write_chan(unsigned int channel, struct file * file, char * buf, int c='\n'; else if (c=='\n' && O_NLRET(tty)) c='\r'; - if (c=='\n' && O_NLCR(tty) && - !set_bit(TTY_CR_PENDING,&tty->flags)) { - put_tty_queue(13,tty->write_q); + if (c=='\n' && !cr_flag && O_NLCR(tty)) { + cr_flag = 1; + PUTCH(13,tty->write_q); continue; } if (O_LCUC(tty)) c=toupper(c); } b++; nr--; - clear_bit(TTY_CR_PENDING,&tty->flags); - put_tty_queue(c,tty->write_q); + cr_flag = 0; + PUTCH(c,tty->write_q); } + TTY_WRITE_FLUSH(tty); if (nr>0) schedule(); } - TTY_WRITE_FLUSH(tty); if (b-buf) return b-buf; - if (tty->link && !tty->link->count) - return -EPIPE; if (current->signal & ~current->blocked) return -ERESTARTSYS; return 0; @@ -469,190 +414,78 @@ static int write_chan(unsigned int channel, struct file * file, char * buf, int static int tty_read(struct inode * inode, struct file * file, char * buf, int count) { - int i; - - if (MAJOR(file->f_rdev) != 4) { - printk("tty_read: pseudo-major != 4\n"); - return -EINVAL; - } - i = read_chan(MINOR(file->f_rdev),file,buf,count); - if (i > 0) - inode->i_atime = CURRENT_TIME; - return i; + return read_chan(current->tty,file,buf,count); } -static int tty_write(struct inode * inode, struct file * file, char * buf, int count) +static int ttyx_read(struct inode * inode, struct file * file, char * buf, int count) { - int i; - - if (MAJOR(file->f_rdev) != 4) { - printk("tty_write: pseudo-major != 4\n"); - return -EINVAL; - } - i = write_chan(MINOR(file->f_rdev),file,buf,count); - if (i > 0) - inode->i_mtime = CURRENT_TIME; - return i; + return read_chan(MINOR(inode->i_rdev),file,buf,count); } -static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig) +static int tty_write(struct inode * inode, struct file * file, char * buf, int count) { - return -EBADF; + return write_chan(current->tty,file,buf,count); } -/* - * tty_open and tty_release keep up the tty count that contains the - * number of opens done on a tty. We cannot use the inode-count, as - * different inodes might point to the same tty. - * - * Open-counting is needed for pty masters, as well as for keeping - * track of serial lines: DTR is dropped when the last close happens. - */ -static int tty_open(struct inode * inode, struct file * filp) +static int ttyx_write(struct inode * inode, struct file * file, char * buf, int count) { - struct tty_struct *tty; - int dev, retval; - - dev = inode->i_rdev; - if (MAJOR(dev) == 5) - dev = current->tty; - else - dev = MINOR(dev); - if (dev < 0) - return -ENODEV; - filp->f_rdev = 0x0400 | dev; - tty = TTY_TABLE(dev); - if (!tty->count && !(tty->link && tty->link->count)) { - flush_input(tty); - flush_output(tty); - tty->stopped = 0; - } - if (IS_A_PTY_MASTER(dev)) { - if (tty->count) - return -EAGAIN; - if (tty->link) - tty->link->count++; - } - tty->count++; - retval = 0; - if (!(filp->f_flags & O_NOCTTY) && - current->leader && - current->tty<0 && - tty->session==0) { - current->tty = dev; - tty->session = current->session; - tty->pgrp = current->pgrp; - } - if (IS_A_SERIAL(dev) && tty->count < 2) - retval = serial_open(dev-64,filp); - else if (IS_A_PTY(dev)) - retval = pty_open(dev,filp); - if (retval) { - tty->count--; - if (IS_A_PTY_MASTER(dev) && tty->link) - tty->link->count--; - } - return retval; + return write_chan(MINOR(inode->i_rdev),file,buf,count); } -/* - * Note that releasing a pty master also releases the child, so - * we have to make the redirection checks after that and on both - * sides of a pty. - */ -static void tty_release(struct inode * inode, struct file * filp) +static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig) { - int dev; - struct tty_struct * tty; - - dev = filp->f_rdev; - if (MAJOR(dev) != 4) { - printk("tty_close: tty pseudo-major != 4\n"); - return; - } - dev = MINOR(filp->f_rdev); - tty = TTY_TABLE(dev); - if (IS_A_PTY_MASTER(dev) && tty->link) - tty->link->count--; - tty->count--; - if (tty->count) - return; - if (IS_A_SERIAL(dev)) { - wait_until_sent(tty); - serial_close(dev-64,filp); - } else if (IS_A_PTY(dev)) - pty_close(dev,filp); - if (!tty->count && (tty == redirect)) - redirect = NULL; - if (tty = tty->link) - if (!tty->count && (tty == redirect)) - redirect = NULL; + return -EBADF; } -static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait) +static int tty_readdir(struct inode * inode, struct file * file, struct dirent * de, int count) { - int dev; - struct tty_struct * tty; - - dev = filp->f_rdev; - if (MAJOR(dev) != 4) { - printk("tty_select: tty pseudo-major != 4\n"); - return 0; - } - dev = MINOR(filp->f_rdev); - tty = TTY_TABLE(dev); - switch (sel_type) { - case SEL_IN: - if (!EMPTY(tty->secondary)) - return 1; - if (tty->link && !tty->link->count) - return 1; - select_wait(&tty->secondary->proc_list, wait); - return 0; - case SEL_OUT: - if (!FULL(tty->write_q)) - return 1; - select_wait(&tty->write_q->proc_list, wait); - return 0; - case SEL_EX: - if (tty->link && !tty->link->count) - return 1; - return 0; - } - return 0; + return -ENOTDIR; } static struct file_operations tty_fops = { tty_lseek, tty_read, tty_write, - NULL, /* tty_readdir */ - tty_select, - tty_ioctl, - tty_open, - tty_release + tty_readdir, + NULL, /* tty_close */ + NULL, /* tty_select */ + tty_ioctl /* tty_ioctl */ +}; + +static struct file_operations ttyx_fops = { + tty_lseek, + ttyx_read, + ttyx_write, + tty_readdir, + NULL, /* ttyx_close */ + NULL, /* ttyx_select */ + tty_ioctl /* ttyx_ioctl */ }; -long tty_init(long kmem_start) +void tty_init(void) { int i; - tty_queues = (struct tty_queue *) kmem_start; - kmem_start += QUEUES * (sizeof (struct tty_queue)); - table_list[0] = con_queues + 0; - table_list[1] = con_queues + 1; - chrdev_fops[4] = &tty_fops; + chrdev_fops[4] = &ttyx_fops; chrdev_fops[5] = &tty_fops; for (i=0 ; i < QUEUES ; i++) tty_queues[i] = (struct tty_queue) {0,0,0,0,""}; + rs_queues[0] = (struct tty_queue) {0x3f8,0,0,0,""}; + rs_queues[1] = (struct tty_queue) {0x3f8,0,0,0,""}; + rs_queues[3] = (struct tty_queue) {0x2f8,0,0,0,""}; + rs_queues[4] = (struct tty_queue) {0x2f8,0,0,0,""}; + rs_queues[6] = (struct tty_queue) {0x3e8,0,0,0,""}; + rs_queues[7] = (struct tty_queue) {0x3e8,0,0,0,""}; + rs_queues[9] = (struct tty_queue) {0x2e8,0,0,0,""}; + rs_queues[10] = (struct tty_queue) {0x2e8,0,0,0,""}; for (i=0 ; i<256 ; i++) { tty_table[i] = (struct tty_struct) { {0, 0, 0, 0, 0, INIT_C_CC}, - -1, 0, 0, 0, 0, {0,0,0,0}, - NULL, NULL, NULL, NULL, NULL + -1, 0, 0, 0, {0,0,0,0}, + NULL, NULL, NULL, NULL }; } - kmem_start = con_init(kmem_start); + con_init(); for (i = 0 ; iread_q->data)) + return; + quot = quotient[tty->termios.c_cflag & CBAUD]; + cli(); + outb_p(0x80,port+3); /* set DLAB */ + outb_p(quot & 0xff,port); /* LS of divisor */ + outb_p(quot >> 8,port+1); /* MS of divisor */ + outb(0x03,port+3); /* reset DLAB */ + sti(); +} + static void flush(struct tty_queue * queue) { if (queue) { @@ -31,55 +53,21 @@ static void flush(struct tty_queue * queue) } } -void flush_input(struct tty_struct * tty) -{ - if (tty->read_q) { - flush(tty->read_q); - wake_up(&tty->read_q->proc_list); - } - if (tty->secondary) { - flush(tty->secondary); - tty->secondary->data = 0; - } - if ((tty = tty->link) && tty->write_q) { - flush(tty->write_q); - wake_up(&tty->write_q->proc_list); - } -} - -void flush_output(struct tty_struct * tty) -{ - if (tty->write_q) { - flush(tty->write_q); - wake_up(&tty->write_q->proc_list); - } - if (tty = tty->link) { - if (tty->read_q) { - flush(tty->read_q); - wake_up(&tty->read_q->proc_list); - } - if (tty->secondary) { - flush(tty->secondary); - tty->secondary->data = 0; - } - } -} - -void wait_until_sent(struct tty_struct * tty) +static void wait_until_sent(struct tty_struct * tty) { + cli(); while (!(current->signal & ~current->blocked) && !EMPTY(tty->write_q)) { - TTY_WRITE_FLUSH(tty); current->counter = 0; - cli(); - if (EMPTY(tty->write_q)) - break; - else - interruptible_sleep_on(&tty->write_q->proc_list); - sti(); + interruptible_sleep_on(&tty->write_q->proc_list); } sti(); } +static void send_break(struct tty_struct * tty) +{ + /* do nothing - not implemented */ +} + static int do_get_ps_info(int arg) { struct tstruct { @@ -121,23 +109,19 @@ static int get_termios(struct tty_struct * tty, struct termios * termios) static int set_termios(struct tty_struct * tty, struct termios * termios, int channel) { - int i; - unsigned short old_cflag = tty->termios.c_cflag; + int i, retsig; /* If we try to set the state of terminal and we're not in the foreground, send a SIGTTOU. If the signal is blocked or ignored, go ahead and perform the operation. POSIX 7.2) */ - if ((current->tty == channel) && - (tty->pgrp != current->pgrp)) { - if (is_orphaned_pgrp(current->pgrp)) - return -EIO; - if (!is_ignored(SIGTTOU)) - return tty_signal(SIGTTOU, tty); + if ((current->tty == channel) && (tty->pgrp != current->pgrp)) { + retsig = tty_signal(SIGTTOU, tty); + if (retsig == -ERESTARTSYS || retsig == -EINTR) + return retsig; } for (i=0 ; i< (sizeof (*termios)) ; i++) ((char *)&tty->termios)[i]=get_fs_byte(i+(char *)termios); - if (IS_A_SERIAL(channel) && tty->termios.c_cflag != old_cflag) - change_speed(channel-64); + change_speed(tty); return 0; } @@ -165,17 +149,13 @@ static int get_termio(struct tty_struct * tty, struct termio * termio) static int set_termio(struct tty_struct * tty, struct termio * termio, int channel) { - int i; + int i, retsig; struct termio tmp_termio; - unsigned short old_cflag = tty->termios.c_cflag; - if ((current->tty == channel) && - (tty->pgrp > 0) && - (tty->pgrp != current->pgrp)) { - if (is_orphaned_pgrp(current->pgrp)) - return -EIO; - if (!is_ignored(SIGTTOU)) - return tty_signal(SIGTTOU, tty); + if ((current->tty == channel) && (tty->pgrp != current->pgrp)) { + retsig = tty_signal(SIGTTOU, tty); + if (retsig == -ERESTARTSYS || retsig == -EINTR) + return retsig; } for (i=0 ; i< (sizeof (*termio)) ; i++) ((char *)&tmp_termio)[i]=get_fs_byte(i+(char *)termio); @@ -186,8 +166,7 @@ static int set_termio(struct tty_struct * tty, struct termio * termio, tty->termios.c_line = tmp_termio.c_line; for(i=0 ; i < NCC ; i++) tty->termios.c_cc[i] = tmp_termio.c_cc[i]; - if (IS_A_SERIAL(channel) && tty->termios.c_cflag != old_cflag) - change_speed(channel-64); + change_speed(tty); return 0; } @@ -234,11 +213,12 @@ int tty_ioctl(struct inode * inode, struct file * file, int pgrp; int dev; - if (MAJOR(file->f_rdev) != 4) { - printk("tty_ioctl: tty pseudo-major != 4\n"); - return -EINVAL; - } - dev = MINOR(file->f_rdev); + if (MAJOR(inode->i_rdev) == 5) { + dev = current->tty; + if (dev<0) + return -EINVAL; + } else + dev = MINOR(inode->i_rdev); tty = tty_table + (dev ? ((dev < 64)? dev-1:dev) : fg_console); if (IS_A_PTY(dev)) @@ -252,7 +232,10 @@ int tty_ioctl(struct inode * inode, struct file * file, case TCGETS: return get_termios(tty,(struct termios *) arg); case TCSETSF: - flush_input(tty); + flush(tty->read_q); + flush(tty->secondary); + if (other_tty) + flush(other_tty->write_q); /* fallthrough */ case TCSETSW: wait_until_sent(tty); @@ -262,18 +245,20 @@ int tty_ioctl(struct inode * inode, struct file * file, case TCGETA: return get_termio(tty,(struct termio *) arg); case TCSETAF: - flush_input(tty); + flush(tty->read_q); + flush(tty->secondary); + if (other_tty) + flush(other_tty->write_q); /* fallthrough */ case TCSETAW: wait_until_sent(tty); /* fallthrough */ case TCSETA: return set_termio(tty,(struct termio *) arg, dev); case TCSBRK: - if (!IS_A_SERIAL(dev)) - return -EINVAL; - wait_until_sent(tty); - if (!arg) - send_break(dev-64); + if (!arg) { + wait_until_sent(tty); + send_break(tty); + } return 0; case TCXONC: switch (arg) { @@ -287,22 +272,28 @@ int tty_ioctl(struct inode * inode, struct file * file, return 0; case TCIOFF: if (STOP_CHAR(tty)) - put_tty_queue(STOP_CHAR(tty),tty->write_q); + PUTCH(STOP_CHAR(tty),tty->write_q); return 0; case TCION: if (START_CHAR(tty)) - put_tty_queue(START_CHAR(tty),tty->write_q); + PUTCH(START_CHAR(tty),tty->write_q); return 0; } return -EINVAL; /* not implemented */ case TCFLSH: - if (arg==0) - flush_input(tty); - else if (arg==1) - flush_output(tty); + if (arg==0) { + flush(tty->read_q); + flush(tty->secondary); + if (other_tty) + flush(other_tty->write_q); + } else if (arg==1) + flush(tty->write_q); else if (arg==2) { - flush_input(tty); - flush_output(tty); + flush(tty->read_q); + flush(tty->secondary); + flush(tty->write_q); + if (other_tty) + flush(other_tty->write_q); } else return -EINVAL; return 0; @@ -334,18 +325,15 @@ int tty_ioctl(struct inode * inode, struct file * file, return 0; case TIOCINQ: verify_area((void *) arg,4); - if (L_CANON(tty) && !tty->secondary->data) - put_fs_long(0, (unsigned long *) arg); - else - put_fs_long(CHARS(tty->secondary), - (unsigned long *) arg); + put_fs_long(CHARS(tty->secondary), + (unsigned long *) arg); return 0; case TIOCSTI: return -EINVAL; /* not implemented */ case TIOCGWINSZ: return get_window_size(tty,(struct winsize *) arg); case TIOCSWINSZ: - if (IS_A_PTY_MASTER(dev)) + if (other_tty) set_window_size(other_tty,(struct winsize *) arg); return set_window_size(tty,(struct winsize *) arg); case TIOCMGET: @@ -370,27 +358,6 @@ int tty_ioctl(struct inode * inode, struct file * file, default: return -EINVAL; } - case TIOCCONS: - if (!IS_A_PTY(dev)) - return -EINVAL; - if (redirect) - return -EBUSY; - if (!suser()) - return -EPERM; - if (IS_A_PTY_MASTER(dev)) - redirect = other_tty; - else - redirect = tty; - return 0; - case TIOCGSERIAL: - if (!IS_A_SERIAL(dev)) - return -EINVAL; - verify_area((void *) arg,sizeof(struct serial_struct)); - return get_serial_info(dev-64,(struct serial_struct *) arg); - case TIOCSSERIAL: - if (!IS_A_SERIAL(dev)) - return -EINVAL; - return set_serial_info(dev-64,(struct serial_struct *) arg); default: return vt_ioctl(tty, dev, cmd, arg); } diff --git a/kernel/chr_drv/vt.c b/kernel/chr_drv/vt.c index 407f09bebfc0..549cb93fa731 100644 --- a/kernel/chr_drv/vt.c +++ b/kernel/chr_drv/vt.c @@ -15,7 +15,6 @@ #include #include -#include #include #include "vt_kern.h" @@ -24,8 +23,9 @@ * console (vt and kd) routines, as defined by usl svr4 manual */ -struct vt_cons vt_cons[NR_CONSOLES]; +struct vt_info vt_info[MAX_CONSOLES]; +extern int NR_CONSOLES; extern unsigned char kleds; extern unsigned char kraw; extern unsigned char ke0; @@ -64,27 +64,14 @@ kiocsound(unsigned int freq) return 0; } -/* - * all the vt ioctls affect only consoles, so we reject all other ttys. - * we also have the capability to modify any console, not just the fg_console. - */ int vt_ioctl(struct tty_struct *tty, int dev, int cmd, int arg) { - int console = dev ? dev - 1 : fg_console; - unsigned char ucval; - - if (!IS_A_CONSOLE(dev) || console < 0 || console >= NR_CONSOLES) - return -EINVAL; - switch (cmd) { case KIOCSOUND: return kiocsound((unsigned int)arg); case KDGKBTYPE: - /* - * this is naive. - */ verify_area((void *) arg, sizeof(unsigned char)); put_fs_byte(KB_101, (unsigned char *) arg); return 0; @@ -101,8 +88,7 @@ vt_ioctl(struct tty_struct *tty, int dev, int cmd, int arg) case KDENABIO: case KDDISABIO: - return sys_ioperm(GPFIRST, GPNUM, - (cmd == KDENABIO)) ? -ENXIO : 0; + return sys_ioperm(GPFIRST, GPNUM, (cmd == KDENABIO)) ? -ENXIO : 0; case KDSETMODE: /* @@ -121,21 +107,11 @@ vt_ioctl(struct tty_struct *tty, int dev, int cmd, int arg) default: return -EINVAL; } - if (vt_cons[console].vt_mode == (unsigned char) arg) - return 0; - vt_cons[console].vt_mode = (unsigned char) arg; - if (console != fg_console) - return 0; - if (arg == KD_TEXT) - unblank_screen(); - else { - timer_active &= 1< #include -#include #include #include int sys_close(int fd); -int send_sig(long sig,struct task_struct * p,int priv) +inline int send_sig(long sig,struct task_struct * p,int priv) { if (!p || (sig < 0) || (sig > 32)) return -EINVAL; - if (!priv && ((sig != SIGCONT) || (current->session != p->session)) && - (current->euid != p->euid) && (current->uid != p->uid) && !suser()) + if (!priv && (current->euid!=p->euid) && !suser()) return -EPERM; if (!sig) return 0; @@ -43,7 +41,7 @@ int send_sig(long sig,struct task_struct * p,int priv) /* save the signal number for wait. */ p->exit_code = sig; - /* we have to make sure the parent process is awake. */ + /* we have to make sure the parent is awake. */ if (p->p_pptr != NULL && p->p_pptr->state == TASK_INTERRUPTIBLE) p->p_pptr->state = TASK_RUNNING; @@ -67,7 +65,13 @@ void release(struct task_struct * p) for (i=1 ; ip_osptr) + p->p_osptr->p_ysptr = p->p_ysptr; + if (p->p_ysptr) + p->p_ysptr->p_osptr = p->p_osptr; + else + p->p_pptr->p_cptr = p->p_osptr; free_page((long) p); return; } @@ -163,26 +167,14 @@ void audit_ptree() } #endif /* DEBUG_PROC_TREE */ -/* - * This checks not only the pgrp, but falls back on the pid if no - * satisfactory prgp is found. I dunno - gdb doesn't work correctly - * without this... - */ int session_of_pgrp(int pgrp) { struct task_struct **p; - int fallback; - fallback = -1; - for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { - if (!*p || (*p)->session <= 0) - continue; + for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) if ((*p)->pgrp == pgrp) - return (*p)->session; - if ((*p)->pid == pgrp) - fallback = (*p)->session; - } - return fallback; + return((*p)->session); + return -1; } int kill_pg(int pgrp, int sig, int priv) @@ -194,7 +186,7 @@ int kill_pg(int pgrp, int sig, int priv) if (sig<0 || sig>32 || pgrp<=0) return -EINVAL; for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) - if (*p && (*p)->pgrp == pgrp) { + if ((*p)->pgrp == pgrp) { if (sig && (err = send_sig(sig,*p,priv))) retval = err; else @@ -210,7 +202,7 @@ int kill_proc(int pid, int sig, int priv) if (sig<0 || sig>32) return -EINVAL; for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) - if (*p && (*p)->pid == pid) + if ((*p)->pid == pid) return(sig ? send_sig(sig,*p,priv) : 0); return(-ESRCH); } @@ -228,7 +220,7 @@ int sys_kill(int pid,int sig) return(kill_pg(current->pgrp,sig,0)); if (pid == -1) { while (--p > &FIRST_TASK) - if (*p && (*p)->pid > 1 && *p != current) { + if ((*p)->pid > 1 && *p != current) { ++count; if ((err = send_sig(sig,*p,0)) != -EPERM) retval = err; @@ -271,7 +263,7 @@ static int has_stopped_jobs(int pgrp) struct task_struct ** p; for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { - if (!*p || (*p)->pgrp != pgrp) + if ((*p)->pgrp != pgrp) continue; if ((*p)->state == TASK_STOPPED) return(1); @@ -279,37 +271,23 @@ static int has_stopped_jobs(int pgrp) return(0); } -static void forget_original_parent(struct task_struct * father) -{ - struct task_struct ** p; - - for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) - if (*p && (*p)->p_opptr == father) - if (task[1]) - (*p)->p_opptr = task[1]; - else - (*p)->p_opptr = task[0]; -} - volatile void do_exit(long code) { struct task_struct *p; int i; -fake_volatile: free_page_tables(get_base(current->ldt[1]),get_limit(0x0f)); free_page_tables(get_base(current->ldt[2]),get_limit(0x17)); for (i=0 ; ifilp[i]) sys_close(i); - forget_original_parent(current); iput(current->pwd); current->pwd = NULL; iput(current->root); current->root = NULL; iput(current->executable); current->executable = NULL; - for (i=0; i < current->numlibraries; i++) { + for (i=0; inumlibraries; i++) { iput(current->libraries[i].library); current->libraries[i].library = NULL; } @@ -341,21 +319,18 @@ fake_volatile: * A. Make init inherit all the child processes * B. Check to see if any process groups have become orphaned * as a result of our exiting, and if they have any stopped - * jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2) + * jons, send them a SIGUP and then a SIGCONT. (POSIX 3.2.2.2) */ while (p = current->p_cptr) { current->p_cptr = p->p_osptr; p->p_ysptr = NULL; - p->flags &= ~PF_PTRACED; - if (task[1]) - p->p_pptr = task[1]; - else - p->p_pptr = task[0]; - p->p_osptr = p->p_pptr->p_cptr; - p->p_osptr->p_ysptr = p; - p->p_pptr->p_cptr = p; + p->flags &= ~PF_PTRACED; + p->p_pptr = task[1]; + p->p_osptr = task[1]->p_cptr; + task[1]->p_cptr->p_ysptr = p; + task[1]->p_cptr = p; if (p->state == TASK_ZOMBIE) - send_sig(SIGCHLD,p->p_pptr,1); + task[1]->signal |= (1<<(SIGCHLD-1)); /* * process group orphan check * Case ii: Our child is in a different pgrp @@ -382,7 +357,7 @@ fake_volatile: tty->session = 0; } for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) - if (*p && (*p)->session == current->session) + if ((*p)->session == current->session) (*p)->tty = -1; } if (last_task_used_math == current) @@ -391,20 +366,6 @@ fake_volatile: audit_ptree(); #endif schedule(); -/* - * In order to get rid of the "volatile function does return" message - * I did this little loop that confuses gcc to think do_exit really - * is volatile. In fact it's schedule() that is volatile in some - * circumstances: when current->state = ZOMBIE, schedule() never - * returns. - * - * In fact the natural way to do all this is to have the label and the - * goto right after each other, but I put the fake_volatile label at - * the start of the function just in case something /really/ bad - * happens, and the schedule returns. This way we can try again. I'm - * not paranoid: it's just that everybody is out to get me. - */ - goto fake_volatile; } int sys_exit(int error_code) @@ -421,9 +382,8 @@ int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options) if (stat_addr) verify_area(stat_addr,4); repeat: - current->signal &= ~(1<<(SIGCHLD-1)); flag=0; - for (p = current->p_cptr ; p ; p = p->p_osptr) { + for (p = current->p_cptr ; p ; p = p->p_osptr) { if (pid>0) { if (p->pid != pid) continue; @@ -436,9 +396,8 @@ repeat: } switch (p->state) { case TASK_STOPPED: - if (!p->exit_code) - continue; - if (!(options & WUNTRACED) && !(p->flags & PF_PTRACED)) + if (!(options & WUNTRACED) || + !p->exit_code) continue; if (stat_addr) put_fs_long((p->exit_code << 8) | 0x7f, @@ -453,13 +412,7 @@ repeat: flag = p->pid; if (stat_addr) put_fs_long(p->exit_code, stat_addr); - if (p->p_opptr != p->p_pptr) { - REMOVE_LINKS(p); - p->p_pptr = p->p_opptr; - SET_LINKS(p); - send_sig(SIGCHLD,p->p_pptr,1); - } else - release(p); + release(p); #ifdef DEBUG_PROC_TREE audit_ptree(); #endif @@ -484,3 +437,5 @@ repeat: } return -ECHILD; } + + diff --git a/kernel/fork.c b/kernel/fork.c index ca15238015ce..89277ab86bc3 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -15,10 +15,11 @@ #include #include -#include #include #include +extern void write_verify(unsigned long address); + long last_pid=0; void verify_area(void * addr,int size) @@ -66,25 +67,17 @@ int copy_mem(int nr,struct task_struct * p) static int find_empty_process(void) { - int i, task_nr; + int i; repeat: - if ((++last_pid) & 0xffff0000) - last_pid=1; + if ((++last_pid)<0) last_pid=1; for(i=0 ; ipid == last_pid) || (task[i]->pgrp == last_pid))) goto repeat; -/* Only the super-user can fill the last available slot */ - task_nr = 0; for(i=1 ; iwait.task = p; - p->wait.next = NULL; p->state = TASK_UNINTERRUPTIBLE; - p->flags &= ~PF_PTRACED; p->pid = last_pid; - p->p_pptr = p->p_opptr = current; + p->p_pptr = current; p->p_cptr = NULL; - SET_LINKS(p); + p->p_ysptr = NULL; + if (p->p_osptr = current->p_cptr) + p->p_osptr->p_ysptr = p; + current->p_cptr = p; p->counter = p->priority; p->signal = 0; - p->it_real_value = p->it_virt_value = p->it_prof_value = 0; - p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0; + p->alarm = 0; p->leader = 0; /* process leadership doesn't inherit */ p->utime = p->stime = 0; p->cutime = p->cstime = 0; @@ -134,7 +126,7 @@ int sys_fork(long ebx,long ecx,long edx, p->tss.esp0 = PAGE_SIZE + (long) p; p->tss.ss0 = 0x10; p->tss.eip = eip; - p->tss.eflags = eflags & 0xffffcfff; /* iopl is always 0 for a new process */ + p->tss.eflags = eflags; p->tss.eax = 0; p->tss.ecx = ecx; p->tss.edx = edx; @@ -157,7 +149,12 @@ int sys_fork(long ebx,long ecx,long edx, __asm__("clts ; fnsave %0 ; frstor %0"::"m" (p->tss.i387)); if (copy_mem(nr,p)) { task[nr] = NULL; - REMOVE_LINKS(p); + if (p->p_pptr->p_cptr == p) + p->p_pptr->p_cptr = p->p_osptr; + if (p->p_osptr) + p->p_osptr->p_ysptr = p->p_ysptr; + if (p->p_ysptr) + p->p_ysptr->p_osptr = p->p_osptr; free_page((long) p); return -EAGAIN; } diff --git a/kernel/ioport.c b/kernel/ioport.c index 70a77dd66cc2..cdca95af5021 100644 --- a/kernel/ioport.c +++ b/kernel/ioport.c @@ -92,30 +92,3 @@ int sys_ioperm(unsigned long from, unsigned long num, int turn_on) } return 0; } - -unsigned int *stack; - -/* - * sys_iopl has to be used when you want to access the IO ports - * beyond the 0x3ff range: to get the full 65536 ports bitmapped - * you'd need 8kB of bitmaps/process, which is a bit excessive. - * - * Here we just change the eflags value on the stack: we allow - * only the super-user to do it. This depends on the stack-layout - * on system-call entry - see also fork() and the signal handling - * code. - */ -int sys_iopl(long ebx,long ecx,long edx, - long esi, long edi, long ebp, long eax, long ds, - long es, long fs, long gs, long orig_eax, - long eip,long cs,long eflags,long esp,long ss) -{ - unsigned int level = ebx; - - if (level > 3) - return -EINVAL; - if (!suser()) - return -EPERM; - *(&eflags) = (eflags & 0xffffcfff) | (level << 12); - return 0; -} diff --git a/kernel/irq.c b/kernel/irq.c deleted file mode 100644 index 8b6cd6968d8a..000000000000 --- a/kernel/irq.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * linux/kernel/irq.c - * - * (C) 1992 Linus Torvalds - * - * This file contains the code used by various IRQ handling routines: - * asking for different IRQ's should be done through these routines - * instead of just grabbing them. Thus setups with different IRQ numbers - * shouldn't result in any weird surprises, and installing new handlers - * should be easier. - */ - -/* - * IRQ's are in fact implemented a bit like signal handlers for the kernel. - * The same sigaction struct is used, and with similar semantics (ie there - * is a SA_INTERRUPT flag etc). Naturally it's not a 1:1 relation, but there - * are similarities. - * - * sa_handler(int irq_NR) is the default function called. - * sa_mask is 0 if nothing uses this IRQ - * sa_flags contains various info: SA_INTERRUPT etc - * sa_restorer is the unused - */ - -#include -#include - -#include - -#include -#include -#include -#include - -struct sigaction irq_sigaction[16] = { - { NULL, 0, 0, NULL }, -}; - -void irq13(void); - -/* - * This builds up the IRQ handler stubs using some ugly macros in irq.h - * - * These macros create the low-level assembly IRQ routines that do all - * the operations that are needed to keep the AT interrupt-controller - * happy. They are also written to be fast - and to disable interrupts - * as little as humanly possible. - */ -BUILD_IRQ(FIRST,0,0x01) -BUILD_IRQ(FIRST,1,0x02) -BUILD_IRQ(FIRST,2,0x04) -BUILD_IRQ(FIRST,3,0x08) -BUILD_IRQ(FIRST,4,0x10) -BUILD_IRQ(FIRST,5,0x20) -BUILD_IRQ(FIRST,6,0x40) -BUILD_IRQ(FIRST,7,0x80) -BUILD_IRQ(SECOND,8,0x01) -BUILD_IRQ(SECOND,9,0x02) -BUILD_IRQ(SECOND,10,0x04) -BUILD_IRQ(SECOND,11,0x08) -BUILD_IRQ(SECOND,12,0x10) -BUILD_IRQ(SECOND,13,0x20) -BUILD_IRQ(SECOND,14,0x40) -BUILD_IRQ(SECOND,15,0x80) - -/* - * This routine gets called at every IRQ request. Interrupts - * are enabled, the interrupt has been accnowledged and this - * particular interrupt is disabled when this is called. - * - * The routine has to call the appropriate handler (disabling - * interrupts if needed first). If no handler exists, we return - * an error value, telling the low-level IRQ routines not to - * re-enable this IRQ line. - * - * Note similarities on a very low level between this and the - * do_signal() function. Naturally this is simplified, but they - * get similar arguments, use them similarly etc... Note that - * unlike the signal-handlers, the IRQ-handlers don't get the IRQ - * (signal) number as argument, but the cpl value at the time of - * the interrupt. - */ -int do_IRQ(int irq, struct pt_regs * regs) -{ - struct sigaction * sa = irq + irq_sigaction; - void (*handler)(int); - unsigned int esp; - - if (!(handler = sa->sa_handler)) - return -1; /* the irq isn't re-enabled */ - __asm__ __volatile__("movl %%esp,%0":"=r" (esp)); - if (esp < 200+(unsigned long)(current+1)) { - printk("Stack overflow on IRQ%d: shutting down\n",irq); - return -1; - } - if (sa->sa_flags & SA_INTERRUPT) - cli(); - handler(regs->cs & 3); - sti(); - return 0; /* re-enable the irq when returning */ -} - -int irqaction(unsigned int irq, struct sigaction * new) -{ - struct sigaction * sa; - unsigned long flags; - - if (irq > 15) - return -EINVAL; - if (irq == 2) - irq = 9; - sa = irq + irq_sigaction; - if (sa->sa_mask) - return -EBUSY; - __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); - *sa = *new; - sa->sa_mask = 1; - if (irq < 8) - outb(inb_p(0x21) & ~(1< 15) { - printk("Trying to free IRQ%d\n",irq); - return; - } - if (!sa->sa_mask) { - printk("Trying to free free IRQ%d\n",irq); - return; - } - __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); - if (irq < 8) - outb(inb_p(0x21) | (1<sa_handler = NULL; - sa->sa_flags = 0; - sa->sa_mask = 0; - sa->sa_restorer = NULL; - __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); -} - -extern void math_error(void); - -static void math_error_irq(int cpl) -{ - outb(0,0xF0); - math_error(); -} - -void init_IRQ(void) -{ - set_trap_gate(0x20,IRQ0_interrupt); - set_trap_gate(0x21,IRQ1_interrupt); - set_trap_gate(0x22,IRQ2_interrupt); - set_trap_gate(0x23,IRQ3_interrupt); - set_trap_gate(0x24,IRQ4_interrupt); - set_trap_gate(0x25,IRQ5_interrupt); - set_trap_gate(0x26,IRQ6_interrupt); - set_trap_gate(0x27,IRQ7_interrupt); - set_trap_gate(0x28,IRQ8_interrupt); - set_trap_gate(0x29,IRQ9_interrupt); - set_trap_gate(0x2a,IRQ10_interrupt); - set_trap_gate(0x2b,IRQ11_interrupt); - set_trap_gate(0x2c,IRQ12_interrupt); - set_trap_gate(0x2d,IRQ13_interrupt); - set_trap_gate(0x2e,IRQ14_interrupt); - set_trap_gate(0x2f,IRQ15_interrupt); - if (request_irq(13,math_error_irq)) - printk("Unable to get IRQ13 for math-error handler\n"); -} diff --git a/kernel/itimer.c b/kernel/itimer.c deleted file mode 100644 index d04e2e79e298..000000000000 --- a/kernel/itimer.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * linux/kernel/itimer.c - * - * (C) 1992 Darren Senn - */ - -/* These are all the functions necessary to implement itimers */ - -#include -#include -#include - -#include -#include -#include - -static unsigned long tvtojiffies(struct timeval *value) -{ - return((unsigned long )value->tv_sec * HZ + - (unsigned long )(value->tv_usec + (1000000 / HZ - 1)) / - (1000000 / HZ)); -} - -static void jiffiestotv(unsigned long jiffies, struct timeval *value) -{ - value->tv_usec = (jiffies % HZ) * (1000000 / HZ); - value->tv_sec = jiffies / HZ; - return; -} - -int _getitimer(int which, struct itimerval *value) -{ - register unsigned long val, interval; - - switch (which) { - case ITIMER_REAL: - val = current->it_real_value; - interval = current->it_real_incr; - break; - case ITIMER_VIRTUAL: - val = current->it_virt_value; - interval = current->it_virt_incr; - break; - case ITIMER_PROF: - val = current->it_prof_value; - interval = current->it_prof_incr; - break; - default: - return(-EINVAL); - } - jiffiestotv(val, &value->it_value); - jiffiestotv(interval, &value->it_interval); - return(0); -} - -int sys_getitimer(int which, struct itimerval *value) -{ - struct itimerval get_buffer; - int k; - - if (!value) - return -EFAULT; - k = _getitimer(which, &get_buffer); - if (k < 0) - return k; - verify_area(value, sizeof(struct itimerval)); - memcpy_tofs(value, &get_buffer, sizeof(get_buffer)); - return 0; -} - -int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue) -{ - register unsigned long i, j; - int k; - - i = tvtojiffies(&value->it_interval); - j = tvtojiffies(&value->it_value); - if (ovalue && (k = _getitimer(which, ovalue)) < 0) - return k; - switch (which) { - case ITIMER_REAL: - current->it_real_value = j; - current->it_real_incr = i; - break; - case ITIMER_VIRTUAL: - current->it_virt_value = j; - current->it_virt_incr = i; - break; - case ITIMER_PROF: - current->it_prof_value = j; - current->it_prof_incr = i; - break; - default: - return -EINVAL; - } - return 0; -} - -int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) -{ - struct itimerval set_buffer, get_buffer; - int k; - - if (!value) - memset((char *) &set_buffer, 0, sizeof(set_buffer)); - else - memcpy_fromfs(&set_buffer, value, sizeof(set_buffer)); - k = _setitimer(which, &set_buffer, ovalue ? &get_buffer : 0); - if (k < 0 || !ovalue) - return k; - verify_area(ovalue, sizeof(struct itimerval)); - memcpy_tofs(ovalue, &get_buffer, sizeof(get_buffer)); - return 0; -} diff --git a/kernel/math/Makefile b/kernel/math/Makefile index 67828ab91116..79e3276a063b 100644 --- a/kernel/math/Makefile +++ b/kernel/math/Makefile @@ -6,15 +6,24 @@ # unless it's something special (ie not a .c file). # +AR =ar +AS =as +LD =ld +LDFLAGS =-s -x +CC =gcc -nostdinc -I../../include +CPP =cpp -nostdinc -I../../include + .c.s: - $(CC) $(CFLAGS) $(MATH_EMULATION) -S $< + $(CC) $(CFLAGS) $(MATH_EMULATION) \ + -S -o $*.s $< .s.o: $(AS) -c -o $*.o $< .c.o: - $(CC) $(CFLAGS) $(MATH_EMULATION) -c $< + $(CC) $(CFLAGS) $(MATH_EMULATION) \ + -c -o $*.o $< OBJS = emulate.o error.o convert.o ea.o get_put.o \ - add.o mul.o div.o compare.o sqrt.o + add.o mul.o div.o compare.o math.a: $(OBJS) $(AR) rcs math.a $(OBJS) @@ -26,67 +35,51 @@ clean: dep: sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - for i in *.c;do $(CPP) -M $$i;done >> tmp_make + (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ + $(CPP) -M $$i;done) >> tmp_make cp tmp_make Makefile ### Dependencies: -add.o : add.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h -compare.o : compare.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h -convert.o : convert.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h -div.o : div.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h -ea.o : ea.c /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/math_emu.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h -emulate.o : emulate.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h -error.o : error.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h -get_put.o : get_put.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h -mul.o : mul.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h -sqrt.o : sqrt.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h +add.s add.o : add.c ../../include/linux/math_emu.h ../../include/linux/sched.h ../../include/linux/head.h \ + ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \ + ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h +compare.s compare.o : compare.c ../../include/linux/math_emu.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \ + ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h +convert.s convert.o : convert.c ../../include/linux/math_emu.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \ + ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h +div.s div.o : div.c ../../include/linux/math_emu.h ../../include/linux/sched.h ../../include/linux/head.h \ + ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \ + ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h +ea.s ea.o : ea.c ../../include/stddef.h ../../include/linux/math_emu.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/types.h \ + ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h ../../include/asm/segment.h +emulate.s emulate.o : emulate.c ../../include/signal.h ../../include/sys/types.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \ + ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h +error.s error.o : error.c ../../include/signal.h ../../include/sys/types.h ../../include/linux/sched.h \ + ../../include/linux/head.h ../../include/linux/fs.h ../../include/sys/dirent.h \ + ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h +get_put.s get_put.o : get_put.c ../../include/signal.h ../../include/sys/types.h ../../include/linux/math_emu.h \ + ../../include/linux/sched.h ../../include/linux/head.h ../../include/linux/fs.h \ + ../../include/sys/dirent.h ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h ../../include/sys/resource.h \ + ../../include/asm/segment.h +mul.s mul.o : mul.c ../../include/linux/math_emu.h ../../include/linux/sched.h ../../include/linux/head.h \ + ../../include/linux/fs.h ../../include/sys/types.h ../../include/sys/dirent.h \ + ../../include/limits.h ../../include/linux/mm.h ../../include/linux/kernel.h \ + ../../include/signal.h ../../include/sys/param.h ../../include/sys/time.h ../../include/time.h \ + ../../include/sys/resource.h diff --git a/kernel/math/ea.c b/kernel/math/ea.c index 571dc1eaf403..85a1131c9ded 100644 --- a/kernel/math/ea.c +++ b/kernel/math/ea.c @@ -58,7 +58,7 @@ static char * sib(struct info * info, int mod) char * ea(struct info * info, unsigned short code) { unsigned char mod,rm; - long * tmp; + long * tmp = &EAX; int offset = 0; mod = (code >> 6) & 3; @@ -84,7 +84,7 @@ char * ea(struct info * info, unsigned short code) EIP += 4; break; case 3: - math_abort(info,SIGILL); + math_abort(info,1<<(SIGILL-1)); } I387.foo = offset; I387.fos = 0x17; diff --git a/kernel/math/emulate.c b/kernel/math/emulate.c index f3a682981114..b8e3ac2089ef 100644 --- a/kernel/math/emulate.c +++ b/kernel/math/emulate.c @@ -79,7 +79,7 @@ static void do_emu(struct info * info) return; case 0x1d1: case 0x1d2: case 0x1d3: case 0x1d4: case 0x1d5: case 0x1d6: case 0x1d7: - math_abort(info,SIGILL); + math_abort(info,1<<(SIGILL-1)); case 0x1e0: ST(0).exponent ^= 0x8000; return; @@ -87,15 +87,15 @@ static void do_emu(struct info * info) ST(0).exponent &= 0x7fff; return; case 0x1e2: case 0x1e3: - math_abort(info,SIGILL); + math_abort(info,1<<(SIGILL-1)); case 0x1e4: ftst(PST(0)); return; case 0x1e5: printk("fxam not implemented\n\r"); - math_abort(info,SIGILL); + math_abort(info,1<<(SIGILL-1)); case 0x1e6: case 0x1e7: - math_abort(info,SIGILL); + math_abort(info,1<<(SIGILL-1)); case 0x1e8: fpush(); ST(0) = CONST1; @@ -125,17 +125,13 @@ static void do_emu(struct info * info) ST(0) = CONSTZ; return; case 0x1ef: - math_abort(info,SIGILL); - case 0x1fa: - fsqrt(PST(0),&tmp); - real_to_real(&tmp,&ST(0)); - return; + math_abort(info,1<<(SIGILL-1)); case 0x1f0: case 0x1f1: case 0x1f2: case 0x1f3: case 0x1f4: case 0x1f5: case 0x1f6: case 0x1f7: - case 0x1f8: case 0x1f9: case 0x1fb: case 0x1fd: - case 0x1fe: case 0x1ff: + case 0x1f8: case 0x1f9: case 0x1fa: case 0x1fb: + case 0x1fd: case 0x1fe: case 0x1ff: printk("%04x fxxx not implemented\n\r",code + 0xd800); - math_abort(info,SIGILL); + math_abort(info,1<<(SIGILL-1)); case 0x1fc: frndint(PST(0),&tmp); real_to_real(&tmp,&ST(0)); @@ -246,7 +242,7 @@ static void do_emu(struct info * info) return; case 0xb8: printk("ffree not implemented\n\r"); - math_abort(info,SIGILL); + math_abort(info,1<<(SIGILL-1)); case 0xb9: fxchg(&ST(0),&ST(code & 7)); return; @@ -303,7 +299,7 @@ static void do_emu(struct info * info) return; case 0xf8: printk("ffree not implemented\n\r"); - math_abort(info,SIGILL); + math_abort(info,1<<(SIGILL-1)); fpop(); return; case 0xf9: @@ -478,7 +474,7 @@ static void do_emu(struct info * info) return; } printk("Unknown math-insns: %04x:%08x %04x\n\r",CS,EIP,code); - math_abort(info,SIGFPE); + math_abort(info,1<<(SIGFPE-1)); } void math_emulate(long ___false) @@ -495,7 +491,7 @@ void math_emulate(long ___false) void __math_abort(struct info * info, unsigned int signal) { EIP = ORIG_EIP; - send_sig(signal,current,1); + current->signal |= signal; __asm__("movl %0,%%esp ; ret"::"g" (((long) info)-4)); } @@ -542,7 +538,7 @@ static temp_real_unaligned * __st(int i) void math_emulate(long ___false) { - send_sig(SIGFPE,current,1); + current->signal |= 1<<(SIGFPE-1); schedule(); } diff --git a/kernel/math/error.c b/kernel/math/error.c index a4218a21a12e..5f1c1c2ca4c2 100644 --- a/kernel/math/error.c +++ b/kernel/math/error.c @@ -11,6 +11,6 @@ void math_error(void) { if (last_task_used_math) - send_sig(SIGFPE,last_task_used_math,1); + last_task_used_math->signal |= 1<<(SIGFPE-1); __asm__("fnclex"); } diff --git a/kernel/math/sqrt.c b/kernel/math/sqrt.c deleted file mode 100644 index 8982d75f406d..000000000000 --- a/kernel/math/sqrt.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * linux/kernel/math/sqrt.c - * - * (C) 1991 Linus Torvalds - */ - -/* - * simple and stupid temporary real fsqrt() routine - * - * There are probably better ways to do this, but this should work ok. - */ - -#include -#include - -static void shift_right(int * c) -{ - __asm__("shrl $1,12(%0) ; rcrl $1,8(%0) ; rcrl $1,4(%0) ; rcrl $1,(%0)" - ::"r" ((long) c)); -} - -static int sqr64(unsigned long * a, unsigned long * b) -{ - unsigned long tmp[4]; - - __asm__("movl (%0),%%eax ; mull %%eax\n\t" - "movl %%eax,(%1) ; movl %%edx,4(%1)\n\t" - "movl 4(%0),%%eax ; mull %%eax\n\t" - "movl %%eax,8(%1) ; movl %%edx,12(%1)\n\t" - "movl (%0),%%eax ; mull 4(%0)\n\t" - "addl %%eax,%%eax ; adcl %%edx,%%edx\n\t" - "adcl $0,12(%1) ; addl %%eax,4(%1)\n\t" - "adcl %%edx,8(%1) ; adcl $0,12(%1)" - ::"b" ((long) a),"c" ((long) tmp) - :"ax","bx","cx","dx"); - if (tmp[3] > b[3] || - (tmp[3] == b[3] && (tmp[2] > b[2] || - (tmp[2] == b[2] && (tmp[1] > b[1] || - (tmp[1] == b[1] && tmp[0] > b[0])))))) - return 0; - return 1; -} - -void fsqrt(const temp_real * s, temp_real * d) -{ - unsigned long src[4]; - unsigned long res[2]; - int exponent; - unsigned long mask, *c; - int i; - - exponent = s->exponent; - src[0] = src[1] = 0; - src[2] = s->a; - src[3] = s->b; - d->exponent = 0; - d->a = d->b = 0; - if (!exponent) /* fsqrt(0.0) = 0.0 */ - return; - if (!src[2] && !src[3]) - return; - if (exponent & 0x8000) { - send_sig(SIGFPE,current,0); - return; - } - if (exponent & 1) { - shift_right(src); - exponent++; - } - exponent >>= 1; - exponent += 0x1fff; - c = res + 2; - mask = 0; - for (i = 64 ; i > 0 ; i--) { - if (!(mask >>= 1)) { - c--; - mask = 0x80000000; - } - res[0] = d->a; res[1] = d->b; - *c |= mask; - if (sqr64(res,src)) { - d->a = res[0]; - d->b = res[1]; - } - } - if (!d->a && !d->b) - return; - while (!(d->b & 0x80000000)) { - __asm__("addl %%eax,%%eax ; adcl %%edx,%%edx" - :"=a" (d->a),"=d" (d->b) - :"0" (d->a),"1" (d->b)); - exponent--; - } - d->exponent = exponent; -} diff --git a/kernel/printk.c b/kernel/printk.c index 1d5ef8dd3112..ebce88c6d6d2 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -4,101 +4,28 @@ * (C) 1991 Linus Torvalds */ +/* + * When in kernel-mode, we cannot use printf, as fs is liable to + * point to 'interesting' things. Make a printf with fs-saving, and + * all is well. + */ #include #include -#include -#include -#include - -#include #include static char buf[1024]; extern int vsprintf(char * buf, const char * fmt, va_list args); -extern void console_print(const char *); - -static unsigned long log_page = 0; -static unsigned long log_start = 0; -static unsigned long log_size = 0; -static struct wait_queue * log_wait = NULL; - -int sys_syslog(int type, char * buf, int len) -{ - unsigned long i; - char c; - - if (!suser()) - return -EPERM; - switch (type) { - case 0: - i = log_page; - log_page = 0; - free_page(i); - wake_up(&log_wait); - return 0; - case 1: - i = get_free_page(); - if (log_page) { - free_page(i); - return 0; - } else if (log_page = i) { - log_start = log_size = 0; - return 0; - } - return -ENOMEM; - case 2: - if (!buf || len < 0) - return -EINVAL; - if (!len) - return 0; - verify_area(buf,len); - while (!log_size) { - if (!log_page) - return -EIO; - if (current->signal & ~current->blocked) - return -ERESTARTSYS; - cli(); - if (!log_size) - interruptible_sleep_on(&log_wait); - sti(); - } - i = 0; - while (log_size && len) { - c = *((char *) log_page+log_start); - log_start++; - log_size--; - log_start &= 4095; - put_fs_byte(c,buf); - buf++; - i++; - } - return i; - } - return -EINVAL; -} - int printk(const char *fmt, ...) { va_list args; - int i,j; - char * p; + int i; va_start(args, fmt); i=vsprintf(buf,fmt,args); va_end(args); - for (j = 0; j < i && log_page ; j++) { - p = (char *) log_page + (4095 & (log_start+log_size)); - *p = buf[j]; - if (log_size < 4096) - log_size++; - else - log_start++; - } - if (log_page) - wake_up(&log_wait); console_print(buf); return i; } diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 4cfc7c8d13af..4602fc2ab966 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -6,11 +6,9 @@ #include #include #include - +#include #include #include - -#include #include /* @@ -31,19 +29,19 @@ */ #define MAGICNUMBER 68 -void do_no_page(unsigned long, unsigned long, struct task_struct *, unsigned long); +void do_no_page(unsigned long, unsigned long, struct task_struct *); void write_verify(unsigned long); /* change a pid into a task struct. */ -static inline struct task_struct * get_task(int pid) +static inline int get_task(int pid) { int i; - for (i = 1; i < NR_TASKS; i++) { + for (i = 0; i < NR_TASKS; i++) { if (task[i] != NULL && (task[i]->pid == pid)) - return task[i]; + return i; } - return NULL; + return -1; } /* @@ -102,7 +100,7 @@ repeat: page = *((unsigned long *) page); } if (!(page & PAGE_PRESENT)) { - do_no_page(0,addr,tsk,0); + do_no_page(0,addr,tsk); goto repeat; } page &= 0xfffff000; @@ -131,7 +129,7 @@ repeat: page = *((unsigned long *) page); } if (!(page & PAGE_PRESENT)) { - do_no_page(0,addr,tsk,0); + do_no_page(0,addr,tsk); goto repeat; } if (!(page & PAGE_RW)) { @@ -224,54 +222,32 @@ static int write_long(struct task_struct * tsk, unsigned long addr, int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; + int childno; - if (request == PTRACE_TRACEME) { - /* are we already being traced? */ - if (current->flags & PF_PTRACED) - return -EPERM; + if (request == 0) { /* set the ptrace bit in the proccess flags. */ current->flags |= PF_PTRACED; return 0; } - if (!(child = get_task(pid))) - return -ESRCH; - if (request == PTRACE_ATTACH) { - long tmp; - - if (child == current) - return -EPERM; - if ((!child->dumpable || (current->uid != child->euid) || - (current->gid != child->egid)) && !suser()) - return -EPERM; - /* the same process cannot be attached many times */ - if (child->flags & PF_PTRACED) - return -EPERM; - child->flags |= PF_PTRACED; - if (child->p_pptr != current) { - REMOVE_LINKS(child); - child->p_pptr = current; - SET_LINKS(child); - } - tmp = get_stack_long(child, 4*EFL-MAGICNUMBER) | TRAP_FLAG; - put_stack_long(child, 4*EFL-MAGICNUMBER,tmp); - if (child->state == TASK_INTERRUPTIBLE || - child->state == TASK_STOPPED) - child->state = TASK_RUNNING; - child->signal = 0; - return 0; - } - if (!(child->flags & PF_PTRACED) || child->state != TASK_STOPPED) + + childno = get_task(pid); + + if (childno < 0) return -ESRCH; - if (child->p_pptr != current) + else + child = task[childno]; + + if (child->p_pptr != current || !(child->flags & PF_PTRACED) || + child->state != TASK_STOPPED) return -ESRCH; switch (request) { /* when I and D space are seperate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ - case PTRACE_PEEKDATA: { + case 1: /* read word at location addr. */ + case 2: { int tmp,res; - res = read_long(child, addr, &tmp); + res = read_long(task[childno], addr, &tmp); if (res < 0) return res; verify_area((void *) data, 4); @@ -280,7 +256,7 @@ int sys_ptrace(long request, long pid, long addr, long data) } /* read the word at location addr in the USER area. */ - case PTRACE_PEEKUSR: { + case 3: { int tmp; addr = addr >> 2; /* temporary hack. */ if (addr < 0 || addr >= 17) @@ -292,11 +268,11 @@ int sys_ptrace(long request, long pid, long addr, long data) } /* when I and D space are seperate, this will have to be fixed. */ - case PTRACE_POKETEXT: /* write the word at location addr. */ - case PTRACE_POKEDATA: - return write_long(child,addr,data); + case 4: /* write the word at location addr. */ + case 5: + return write_long(task[childno],addr,data); - case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ + case 6: /* write the word at location addr in the USER area */ addr = addr >> 2; /* temproary hack. */ if (addr < 0 || addr >= 17) return -EIO; @@ -310,13 +286,13 @@ int sys_ptrace(long request, long pid, long addr, long data) return -EIO; return 0; - case PTRACE_CONT: { /* restart after signal. */ + case 7: { /* restart after signal. */ long tmp; - child->signal = 0; + child->signal=0; if (data > 0 && data <= NSIG) child->signal = 1<<(data-1); - child->state = TASK_RUNNING; + child->state = 0; /* make sure the single step bit is not set. */ tmp = get_stack_long(child, 4*EFL-MAGICNUMBER) & ~TRAP_FLAG; put_stack_long(child, 4*EFL-MAGICNUMBER,tmp); @@ -328,10 +304,10 @@ int sys_ptrace(long request, long pid, long addr, long data) * perhaps it should be put in the status that it want's to * exit. */ - case PTRACE_KILL: { + case 8: { long tmp; - child->state = TASK_RUNNING; + child->state = 0; child->signal = 1 << (SIGKILL-1); /* make sure the single step bit is not set. */ tmp = get_stack_long(child, 4*EFL-MAGICNUMBER) & ~TRAP_FLAG; @@ -339,34 +315,19 @@ int sys_ptrace(long request, long pid, long addr, long data) return 0; } - case PTRACE_SINGLESTEP: { /* set the trap flag. */ + case 9: { /* set the trap flag. */ long tmp; tmp = get_stack_long(child, 4*EFL-MAGICNUMBER) | TRAP_FLAG; put_stack_long(child, 4*EFL-MAGICNUMBER,tmp); - child->state = TASK_RUNNING; + child->state = 0; child->signal = 0; - if (data > 0 && data <= NSIG) + if (data > 0 && data signal= 1<<(data-1); /* give it a chance to run. */ return 0; } - case PTRACE_DETACH: { /* detach a process that was attached. */ - long tmp; - - child->flags &= ~PF_PTRACED; - child->signal=0; - child->state = 0; - REMOVE_LINKS(child); - child->p_pptr = child->p_opptr; - SET_LINKS(child); - /* make sure the single step bit is not set. */ - tmp = get_stack_long(child, 4*EFL-MAGICNUMBER) & ~TRAP_FLAG; - put_stack_long(child, 4*EFL-MAGICNUMBER,tmp); - return 0; - } - default: return -EIO; } diff --git a/kernel/sched.c b/kernel/sched.c index f8ad4ad264a0..098d096154ea 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -10,9 +10,6 @@ * call functions (type getpid(), which just extracts a field from * current-task */ - -#define TIMER_IRQ 0 - #include #include #include @@ -21,21 +18,18 @@ #include #include #include -#include #include #include -int need_resched = 0; - #define _S(nr) (1<<((nr)-1)) #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) -static void show_task(int nr,struct task_struct * p) +void show_task(int nr,struct task_struct * p) { int i,j = 4096-sizeof(struct task_struct); - printk("%d: pid=%d, state=%d, father=%d, child=%d, ",(p == current)?-nr:nr,p->pid, + printk("%d: pid=%d, state=%d, father=%d, child=%d, ",nr,p->pid, p->state, p->p_pptr->pid, p->p_cptr ? p->p_cptr->pid : -1); i=0; while (i &FIRST_TASK ; --p) if (*p) { if ((*p)->timeout && (*p)->timeout < jiffies) if ((*p)->state == TASK_INTERRUPTIBLE) { (*p)->timeout = 0; - wake_one_task(*p); + (*p)->state = TASK_RUNNING; } + if ((*p)->alarm && (*p)->alarm < jiffies) { + (*p)->signal |= (1<<(SIGALRM-1)); + (*p)->alarm = 0; + } if (((*p)->signal & ~(*p)->blocked) && - (*p)->state==TASK_INTERRUPTIBLE) - wake_one_task(*p); + (*p)->state==TASK_INTERRUPTIBLE) + (*p)->state=TASK_RUNNING; } /* this is the scheduler proper: */ @@ -181,68 +178,54 @@ int sys_pause(void) return -EINTR; } -void wake_one_task(struct task_struct * p) -{ - p->state = TASK_RUNNING; - if (p->counter > current->counter) - need_resched = 1; -} - -/* - * wake_up doesn't wake up stopped processes - they have to be awakened - * with signals or similar. - */ -void wake_up(struct wait_queue **q) +void wake_up(struct task_struct **p) { - struct wait_queue *tmp, *next; - struct task_struct * p; - unsigned long flags; - - if (!q || !(next = *q)) - return; - __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); - do { - tmp = next; - next = tmp->next; - if (p = tmp->task) { - if (p->state == TASK_ZOMBIE) + struct task_struct * wakeup_ptr, * tmp; + + if (p && *p) { + wakeup_ptr = *p; + *p = NULL; + while (wakeup_ptr && wakeup_ptr != task[0]) { + if (wakeup_ptr->state == TASK_STOPPED) + printk("wake_up: TASK_STOPPED\n"); + else if (wakeup_ptr->state == TASK_ZOMBIE) printk("wake_up: TASK_ZOMBIE\n"); - else if (p->state != TASK_STOPPED) { - p->state = TASK_RUNNING; - if (p->counter > current->counter) - need_resched = 1; - } + else + wakeup_ptr->state = TASK_RUNNING; + tmp = wakeup_ptr->next_wait; + wakeup_ptr->next_wait = task[0]; + wakeup_ptr = tmp; } - tmp->next = NULL; - } while (next && next != *q); - __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); + } } -static inline void __sleep_on(struct wait_queue **p, int state) +static inline void __sleep_on(struct task_struct **p, int state) { - unsigned long flags; + unsigned int flags; if (!p) return; if (current == task[0]) panic("task[0] trying to sleep"); - if (current->wait.next) - printk("__sleep_on: wait->next exists\n"); - __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); + __asm__("pushfl ; popl %0":"=r" (flags)); + current->next_wait = *p; + task[0]->next_wait = NULL; + *p = current; current->state = state; - add_wait_queue(p,¤t->wait); sti(); schedule(); - remove_wait_queue(p,¤t->wait); + if (current->next_wait != task[0]) + wake_up(p); + current->next_wait = NULL; __asm__("pushl %0 ; popfl"::"r" (flags)); } -void interruptible_sleep_on(struct wait_queue **p) +void interruptible_sleep_on(struct task_struct **p) { __sleep_on(p,TASK_INTERRUPTIBLE); } -void sleep_on(struct wait_queue **p) +void sleep_on(struct task_struct **p) { __sleep_on(p,TASK_UNINTERRUPTIBLE); } @@ -252,7 +235,7 @@ void sleep_on(struct wait_queue **p) * proper. They are here because the floppy needs a timer, and this * was the easiest way of doing it. */ -static struct wait_queue * wait_motor[4] = {NULL,NULL,NULL,NULL}; +static struct task_struct * wait_motor[4] = {NULL,NULL,NULL,NULL}; static int mon_timer[4]={0,0,0,0}; static int moff_timer[4]={0,0,0,0}; unsigned char current_DOR = 0x0C; @@ -350,75 +333,14 @@ void add_timer(long jiffies, void (*fn)(void)) sti(); } -#define FSHIFT 11 -#define FSCALE (1< &FIRST_TASK; --p) - if (*p && ((*p)->state == TASK_RUNNING || - (*p)->state == TASK_UNINTERRUPTIBLE)) - ++n; - - for (i = 0; i < 3; ++i) - averunnable[i] = (cexp[i] * averunnable[i] + - n * FSCALE * (FSCALE - cexp[i])) >> FSHIFT; -} - unsigned long timer_active = 0; struct timer_struct timer_table[32]; -static void do_timer(int cpl) +void do_timer(long cpl) { unsigned long mask; struct timer_struct *tp = timer_table+0; - struct task_struct ** task_p; - static int avg_cnt = 0; - jiffies++; - if (!cpl) - current->stime++; - else - current->utime++; - if (--avg_cnt < 0) { - avg_cnt = 500; - update_avg(); - } - if ((--current->counter)<=0) { - current->counter=0; - need_resched = 1; - } - /* Update ITIMER_REAL for every task */ - for (task_p = &LAST_TASK; task_p >= &FIRST_TASK; task_p--) - if (*task_p && (*task_p)->it_real_value - && !(--(*task_p)->it_real_value)) { - send_sig(SIGALRM,*task_p,1); - (*task_p)->it_real_value = (*task_p)->it_real_incr; - need_resched = 1; - } - /* Update ITIMER_PROF for the current task */ - if (current->it_prof_value && !(--current->it_prof_value)) { - current->it_prof_value = current->it_prof_incr; - send_sig(SIGPROF,current,1); - } - /* Update ITIMER_VIRT for current task if not in a system call */ - if (current->it_virt_value && !(--current->it_virt_value)) { - current->it_virt_value = current->it_virt_incr; - send_sig(SIGVTALRM,current,1); - } for (mask = 1 ; mask ; tp++,mask += mask) { if (mask > timer_active) break; @@ -428,8 +350,13 @@ static void do_timer(int cpl) continue; timer_active &= ~mask; tp->fn(); - sti(); } + + if (cpl) + current->utime++; + else + current->stime++; + if (next_timer) { next_timer->jiffies--; while (next_timer && next_timer->jiffies <= 0) { @@ -443,18 +370,20 @@ static void do_timer(int cpl) } if (current_DOR & 0xf0) do_floppy_timer(); + if ((--current->counter)>0) return; + current->counter=0; + if (!cpl) return; + schedule(); } int sys_alarm(long seconds) { - extern int _setitimer(int, struct itimerval *, struct itimerval *); - struct itimerval new, old; - - new.it_interval.tv_sec = new.it_interval.tv_usec = 0; - new.it_value.tv_sec = seconds; - new.it_value.tv_usec = 0; - _setitimer(ITIMER_REAL, &new, &old); - return(old.it_value.tv_sec + (old.it_value.tv_usec / 1000000)); + int old = current->alarm; + + if (old) + old = (old - jiffies) / HZ; + current->alarm = (seconds>0)?(jiffies+HZ*seconds):0; + return (old); } int sys_getpid(void) @@ -491,7 +420,7 @@ int sys_nice(long increment) { if (increment < 0 && !suser()) return -EPERM; - if (increment >= current->priority) + if (increment > current->priority) increment = current->priority-1; current->priority -= increment; return 0; @@ -506,7 +435,6 @@ void sched_init(void) panic("Struct sigaction MUST be 16 bytes"); set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss)); set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt)); - set_system_gate(0x80,&system_call); p = gdt+2+FIRST_TSS_ENTRY; for(i=1 ; i> 8 , 0x40); /* MSB */ - request_irq(TIMER_IRQ,do_timer); + set_intr_gate(0x20,&timer_interrupt); + outb(inb_p(0x21)&~0x01,0x21); + set_system_gate(0x80,&system_call); } diff --git a/kernel/signal.c b/kernel/signal.c index ea33ca18f21a..cf0aa01baa96 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -10,11 +10,10 @@ #include #include -#include #include - -extern int core_dump(long signr,struct pt_regs * regs); - + +int send_sig (int, struct task_struct *, int); + int sys_sgetmask() { return current->blocked; @@ -94,7 +93,7 @@ int sys_signal(int signum, long handler, long restorer) return -EINVAL; tmp.sa_handler = (void (*)(int)) handler; tmp.sa_mask = 0; - tmp.sa_flags = SA_ONESHOT | SA_NOMASK | SA_INTERRUPT; + tmp.sa_flags = SA_ONESHOT | SA_NOMASK; tmp.sa_restorer = (void (*)(void)) restorer; handler = (long) current->sigaction[signum-1].sa_handler; current->sigaction[signum-1] = tmp; @@ -120,32 +119,47 @@ int sys_sigaction(int signum, const struct sigaction * action, return 0; } +/* + * Routine writes a core dump image in the current directory. + * Currently not implemented. + */ +int core_dump(long signr) +{ + return(0); /* We didn't do a dump */ +} + extern int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options); -int do_signal(long signr,struct pt_regs * regs) +int do_signal(long signr,long ebx, long ecx, long edx, + long esi, long edi, long ebp, long eax, + long ds, long es, long fs, long gs, + long orig_eax, + long eip, long cs, long eflags, + unsigned long * esp, long ss) { unsigned long sa_handler; - long old_eip = regs->eip; + long old_eip=eip; struct sigaction * sa = current->sigaction + signr - 1; int longs; + unsigned long * tmp_esp; #ifdef notdef printk("pid: %d, signr: %x, eax=%d, oeax = %d, int=%d\n", - current->pid, signr, regs->eax, regs->orig_eax, + current->pid, signr, eax, orig_eax, sa->sa_flags & SA_INTERRUPT); #endif - sa_handler = (unsigned long) sa->sa_handler; - if ((regs->orig_eax != -1) && - ((regs->eax == -ERESTARTSYS) || (regs->eax == -ERESTARTNOINTR))) { - if ((sa_handler > 1) && (regs->eax == -ERESTARTSYS) && - (sa->sa_flags & SA_INTERRUPT)) - regs->eax = -EINTR; + if ((orig_eax != -1) && + ((eax == -ERESTARTSYS) || (eax == -ERESTARTNOINTR))) { + if ((eax == -ERESTARTSYS) && ((sa->sa_flags & SA_INTERRUPT) || + signr < SIGCONT || signr > SIGTTOU)) + *(&eax) = -EINTR; else { - regs->eax = regs->orig_eax; - regs->eip = old_eip -= 2; + *(&eax) = orig_eax; + *(&eip) = old_eip -= 2; } } + sa_handler = (unsigned long) sa->sa_handler; if (sa_handler==1) { /* check for SIGCHLD: it's special */ if (signr == SIGCHLD) @@ -168,7 +182,9 @@ int do_signal(long signr,struct pt_regs * regs) current->exit_code = signr; if (!(current->p_pptr->sigaction[SIGCHLD-1].sa_flags & SA_NOCLDSTOP)) - send_sig(SIGCHLD, current->p_pptr, 1); + send_sig(SIGCHLD, current->p_pptr, 1); +/* current->p_pptr->signal |= (1<<(SIGCHLD-1));*/ + return(1); /* Reschedule another event */ case SIGQUIT: @@ -177,7 +193,7 @@ int do_signal(long signr,struct pt_regs * regs) case SIGIOT: case SIGFPE: case SIGSEGV: - if (core_dump(signr,regs)) + if (core_dump(signr)) do_exit(signr|0x80); /* fall through */ default: @@ -189,19 +205,19 @@ int do_signal(long signr,struct pt_regs * regs) */ if (sa->sa_flags & SA_ONESHOT) sa->sa_handler = NULL; - regs->eip = sa_handler; - longs = (sa->sa_flags & SA_NOMASK)?(7*4):(8*4); - regs->esp -= longs; - tmp_esp = (unsigned long *) regs->esp; - verify_area(tmp_esp,longs); + *(&eip) = sa_handler; + longs = (sa->sa_flags & SA_NOMASK)?7:8; + *(&esp) -= longs; + verify_area(esp,longs*4); + tmp_esp=esp; put_fs_long((long) sa->sa_restorer,tmp_esp++); put_fs_long(signr,tmp_esp++); if (!(sa->sa_flags & SA_NOMASK)) put_fs_long(current->blocked,tmp_esp++); - put_fs_long(regs->eax,tmp_esp++); - put_fs_long(regs->ecx,tmp_esp++); - put_fs_long(regs->edx,tmp_esp++); - put_fs_long(regs->eflags,tmp_esp++); + put_fs_long(eax,tmp_esp++); + put_fs_long(ecx,tmp_esp++); + put_fs_long(edx,tmp_esp++); + put_fs_long(eflags,tmp_esp++); put_fs_long(old_eip,tmp_esp++); current->blocked |= sa->sa_mask; /* force a supervisor-mode page-in of the signal handler to reduce races */ diff --git a/kernel/sys.c b/kernel/sys.c index 013b6d487fef..a9190287803d 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -30,72 +30,14 @@ struct timezone sys_tz = { 0, 0}; extern int session_of_pgrp(int pgrp); -#define PZERO 15 - -static int proc_sel(struct task_struct *p, int which, int who) -{ - switch (which) { - case PRIO_PROCESS: - if (!who && p == current) - return 1; - return(p->pid == who); - case PRIO_PGRP: - if (!who) - who = current->pgrp; - return(p->pgrp == who); - case PRIO_USER: - if (!who) - who = current->uid; - return(p->uid == who); - } - return 0; -} - -int sys_setpriority(int which, int who, int niceval) +int sys_getpriority() { - struct task_struct **p; - int error = ESRCH; - int priority; - - if (which > 2 || which < 0) - return -EINVAL; - - if ((priority = PZERO - niceval) <= 0) - priority = 1; - - for(p = &LAST_TASK; p > &FIRST_TASK; --p) { - if (!*p || !proc_sel(*p, which, who)) - continue; - if ((*p)->uid != current->euid && - (*p)->uid != current->uid && !suser()) { - error = EPERM; - continue; - } - if (error == ESRCH) - error = 0; - if (priority > (*p)->priority && !suser()) - error = EACCES; - else - (*p)->priority = priority; - } - return -error; + return -ENOSYS; } -int sys_getpriority(int which, int who) +int sys_setpriority() { - struct task_struct **p; - int max_prio = 0; - - if (which > 2 || which < 0) - return -EINVAL; - - for(p = &LAST_TASK; p > &FIRST_TASK; --p) { - if (!*p || !proc_sel(*p, which, who)) - continue; - if ((*p)->priority > max_prio) - max_prio = (*p)->priority; - } - return(max_prio ? max_prio : -ESRCH); + return -ENOSYS; } int sys_profil() @@ -164,9 +106,6 @@ void ctrl_alt_del(void) { if (C_A_D) hard_reset_now(); - else - if (task[1]) - send_sig(SIGINT,task[1],1); } @@ -183,14 +122,14 @@ void ctrl_alt_del(void) */ int sys_setregid(int rgid, int egid) { - if (rgid >= 0) { + if (rgid>0) { if ((current->gid == rgid) || suser()) current->gid = rgid; else return(-EPERM); } - if (egid >= 0) { + if (egid>0) { if ((current->gid == egid) || (current->egid == egid) || suser()) { @@ -270,17 +209,17 @@ int sys_setreuid(int ruid, int euid) { int old_ruid = current->uid; - if (ruid >= 0) { + if (ruid>0) { if ((current->euid==ruid) || - (old_ruid == ruid) || + (old_ruid == ruid) || suser()) current->uid = ruid; else return(-EPERM); } - if (euid >= 0) { + if (euid>0) { if ((old_ruid == euid) || - (current->euid == euid) || + (current->euid == euid) || suser()) { current->euid = euid; current->suid = euid; @@ -446,34 +385,19 @@ int in_group_p(gid_t grp) return 0; } -static struct new_utsname thisname = { +static struct utsname thisname = { UTS_SYSNAME, UTS_NODENAME, UTS_RELEASE, UTS_VERSION, UTS_MACHINE }; -int sys_newuname(struct new_utsname * name) +int sys_uname(struct utsname * name) { - if (!name) - return -EFAULT; - verify_area(name, sizeof *name); - memcpy_tofs(name,&thisname,sizeof *name); - return 0; -} + int i; -int sys_uname(struct old_utsname * name) -{ if (!name) return -EINVAL; verify_area(name,sizeof *name); - memcpy_tofs(&name->sysname,&thisname.sysname,__OLD_UTS_LEN); - put_fs_byte(0,name->sysname+__OLD_UTS_LEN); - memcpy_tofs(&name->nodename,&thisname.nodename,__OLD_UTS_LEN); - put_fs_byte(0,name->nodename+__OLD_UTS_LEN); - memcpy_tofs(&name->release,&thisname.release,__OLD_UTS_LEN); - put_fs_byte(0,name->release+__OLD_UTS_LEN); - memcpy_tofs(&name->version,&thisname.version,__OLD_UTS_LEN); - put_fs_byte(0,name->version+__OLD_UTS_LEN); - memcpy_tofs(&name->machine,&thisname.machine,__OLD_UTS_LEN); - put_fs_byte(0,name->machine+__OLD_UTS_LEN); + for(i=0;i __NEW_UTS_LEN) + if (len > MAXHOSTNAMELEN) return -EINVAL; for (i=0; i < len; i++) { if ((thisname.nodename[i] = get_fs_byte(name+i)) == 0) - return 0; + break; + } + if (thisname.nodename[i]) { + thisname.nodename[i>MAXHOSTNAMELEN ? MAXHOSTNAMELEN : i] = 0; } - thisname.nodename[i] = 0; return 0; } diff --git a/kernel/sys_call.S b/kernel/sys_call.S index 410f3fef54f7..e6f77667483c 100644 --- a/kernel/sys_call.S +++ b/kernel/sys_call.S @@ -37,6 +37,8 @@ * 40(%esp) - %oldss */ +SIG_CHLD = 17 + EBX = 0x00 ECX = 0x04 EDX = 0x08 @@ -79,14 +81,14 @@ ENOSYS = 38 * Ok, I get parallel printer interrupts while using the floppy for some * strange reason. Urgel. Now I just ignore them. */ -.globl _system_call,_sys_execve +.globl _system_call,_timer_interrupt,_sys_execve .globl _device_not_available, _coprocessor_error .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op .globl _double_fault,_coprocessor_segment_overrun .globl _invalid_TSS,_segment_not_present,_stack_segment -.globl _general_protection,_reserved +.globl _general_protection,_irq13,_reserved .globl _alignment_check,_page_fault -.globl ret_from_sys_call +.globl _keyboard_interrupt #define SAVE_ALL \ cld; \ @@ -107,17 +109,59 @@ ENOSYS = 38 movl $0x17,%edx; \ mov %dx,%fs +#define ACK_FIRST(mask) \ + inb $0x21,%al; \ + jmp 1f; \ +1: jmp 1f; \ +1: orb $(mask),%al; \ + outb %al,$0x21; \ + jmp 1f; \ +1: jmp 1f; \ +1: movb $0x20,%al; \ + outb %al,$0x20 + +#define ACK_SECOND(mask) \ + inb $0xA1,%al; \ + jmp 1f; \ +1: jmp 1f; \ +1: orb $mask,%al; \ + outb %al,$0xA1; \ + jmp 1f; \ +1: jmp 1f; \ +1: movb $0x20,%al; \ + outb %al,$0x20 + jmp 1f; \ +1: jmp 1f; \ +1: outb %al,$0xA0 + +#define UNBLK_FIRST(mask) \ + inb $0x21,%al; \ + jmp 1f; \ +1: jmp 1f; \ +1: andb $~(mask),%al; \ + outb %al,$0x21 + +#define UNBLK_SECOND(mask) \ + inb $0xA1,%al; \ + jmp 1f; \ +1: jmp 1f; \ +1: andb $~(mask),%al; \ + outb %al,$0xA1 + +.align 2 +bad_sys_call: + movl $-ENOSYS,EAX(%esp) + jmp ret_from_sys_call .align 2 reschedule: pushl $ret_from_sys_call jmp _schedule .align 2 _system_call: - pushl %eax # save orig_eax + pushl %eax # save orig_eax SAVE_ALL - movl $-ENOSYS,EAX(%esp) cmpl _NR_syscalls,%eax - jae ret_from_sys_call + jae bad_sys_call call _sys_call_table(,%eax,4) movl %eax,EAX(%esp) # save the return value ret_from_sys_call: @@ -125,17 +169,13 @@ ret_from_sys_call: jne 2f cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ? jne 2f -1: cmpl $0,_need_resched - jne reschedule - movl _current,%eax +1: movl _current,%eax + cmpl _task,%eax # task[0] cannot have signals + je 2f cmpl $0,state(%eax) # state jne reschedule cmpl $0,counter(%eax) # counter je reschedule - movl $1,_need_resched - cmpl _task,%eax # task[0] cannot have signals - je 2f - movl $0,_need_resched movl signal(%eax),%ebx movl blocked(%eax),%ecx notl %ecx @@ -144,13 +184,10 @@ ret_from_sys_call: je 2f btrl %ecx,%ebx movl %ebx,signal(%eax) - movl %esp,%ebx - pushl %ebx incl %ecx pushl %ecx call _do_signal popl %ecx - popl %ebx testl %eax, %eax jne 1b # see if we need to switch tasks, or do more signals 2: popl %ebx @@ -168,6 +205,16 @@ ret_from_sys_call: iret .align 2 +_irq13: + pushl %eax + xorb %al,%al + outb %al,$0xF0 + movb $0x20,%al + outb %al,$0x20 + jmp 1f +1: jmp 1f +1: outb %al,$0xA0 + popl %eax _coprocessor_error: pushl $-1 # mark this as an int. SAVE_ALL @@ -188,6 +235,31 @@ _device_not_available: addl $4,%esp ret +.align 2 +_keyboard_interrupt: + pushl $-1 + SAVE_ALL + ACK_FIRST(2) + sti + call _do_keyboard + cli + UNBLK_FIRST(2) + jmp ret_from_sys_call + +.align 2 +_timer_interrupt: + pushl $-1 # mark this as an int + SAVE_ALL + incl _jiffies + movb $0x20,%al # EOI to interrupt controller #1 + outb %al,$0x20 + movl CS(%esp),%eax + andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor) + pushl %eax + call _do_timer # 'do_timer(long CPL)' does everything from + addl $4,%esp # task switching to accounting ... + jmp ret_from_sys_call + .align 2 _sys_execve: lea (EIP+4)(%esp),%eax # don't forget about the return address. diff --git a/kernel/traps.c b/kernel/traps.c index 99310156357d..89b65f3b0bca 100644 --- a/kernel/traps.c +++ b/kernel/traps.c @@ -57,7 +57,10 @@ void general_protection(void); void page_fault(void); void coprocessor_error(void); void reserved(void); +void parallel_interrupt(void); +void irq13(void); void alignment_check(void); +int send_sig(long, struct task_struct *, int); static void die(char * str,long esp_ptr,long nr) { @@ -81,10 +84,7 @@ static void die(char * str,long esp_ptr,long nr) for(i=0;i<10;i++) printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0]))); printk("\n\r"); - if ((0xffff & esp[1]) == 0xf) - send_sig(SIGSEGV, current, 0); - else - do_exit(SIGSEGV); + do_exit(11); /* play segment exception */ } void do_double_fault(long esp, long error_code) @@ -99,7 +99,7 @@ void do_general_protection(long esp, long error_code) void do_alignment_check(long esp, long error_code) { - die("alignment check",esp,error_code); + die("alignment check",esp,error_code); } void do_divide_error(long esp, long error_code) @@ -114,12 +114,12 @@ void do_int3(long esp, long error_code) void do_nmi(long esp, long error_code) { - printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n"); + die("nmi",esp,error_code); } void do_debug(long esp, long error_code) { - send_sig(SIGTRAP, current, 0); + send_sig(SIGTRAP, current, 0); } void do_overflow(long esp, long error_code) @@ -198,4 +198,8 @@ void trap_init(void) set_trap_gate(17,&alignment_check); for (i=18;i<48;i++) set_trap_gate(i,&reserved); + set_trap_gate(45,&irq13); + outb_p(inb_p(0x21)&0xfb,0x21); + outb(inb_p(0xA1)&0xdf,0xA1); + set_trap_gate(39,¶llel_interrupt); } diff --git a/lib/Makefile b/lib/Makefile index 698c50d34028..78afc1ea569f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -6,12 +6,21 @@ # unless it's something special (ie not a .c file). # +AR =ar +AS =as +LD =ld +LDFLAGS =-s -x +CC =gcc -nostdinc -I../include +CPP =gcc -E -nostdinc -I../include + .c.s: - $(CC) $(CFLAGS) -S $< + $(CC) $(CFLAGS) \ + -S -o $*.s $< .s.o: $(AS) -c -o $*.o $< .c.o: - $(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) \ + -c -o $*.o $< OBJS = ctype.o _exit.o open.o close.o errno.o write.o dup.o setsid.o \ execve.o wait.o string.o malloc.o @@ -26,26 +35,38 @@ clean: dep: sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - for i in *.c;do $(CPP) -M $$i;done >> tmp_make + (for i in *.c;do echo -n `echo $$i | sed 's,\.c,\.s,'`" "; \ + $(CPP) -M $$i;done) >> tmp_make cp tmp_make Makefile ### Dependencies: -_exit.o : _exit.c /usr/src/linux/include/linux/unistd.h -close.o : close.c /usr/src/linux/include/linux/unistd.h -ctype.o : ctype.c /usr/src/linux/include/linux/ctype.h -dup.o : dup.c /usr/src/linux/include/linux/unistd.h -errno.o : errno.c -execve.o : execve.c /usr/src/linux/include/linux/unistd.h -malloc.o : malloc.c /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/asm/system.h -open.o : open.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/stdarg.h -setsid.o : setsid.c /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ - /usr/src/linux/include/linux/unistd.h -string.o : string.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h -wait.o : wait.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/sys/wait.h \ - /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h -write.o : write.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h +_exit.s _exit.o : _exit.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \ + ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/sys/param.h ../include/sys/resource.h ../include/utime.h +close.s close.o : close.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \ + ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/sys/param.h ../include/sys/resource.h ../include/utime.h +ctype.s ctype.o : ctype.c ../include/linux/ctype.h +dup.s dup.o : dup.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \ + ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/sys/param.h ../include/sys/resource.h ../include/utime.h +errno.s errno.o : errno.c +execve.s execve.o : execve.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \ + ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/sys/param.h ../include/sys/resource.h ../include/utime.h +malloc.s malloc.o : malloc.c ../include/linux/kernel.h ../include/linux/mm.h ../include/linux/fs.h \ + ../include/sys/types.h ../include/sys/dirent.h ../include/limits.h ../include/signal.h \ + ../include/asm/system.h +open.s open.o : open.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \ + ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/sys/param.h ../include/sys/resource.h ../include/utime.h ../include/stdarg.h +setsid.s setsid.o : setsid.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \ + ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/sys/param.h ../include/sys/resource.h ../include/utime.h +string.s string.o : string.c ../include/linux/string.h +wait.s wait.o : wait.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \ + ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/sys/param.h ../include/sys/resource.h ../include/utime.h ../include/sys/wait.h +write.s write.o : write.c ../include/unistd.h ../include/sys/stat.h ../include/sys/types.h \ + ../include/sys/time.h ../include/time.h ../include/sys/times.h ../include/sys/utsname.h \ + ../include/sys/param.h ../include/sys/resource.h ../include/utime.h diff --git a/lib/_exit.c b/lib/_exit.c index a1630f42ef30..ac48d1aaf7b9 100644 --- a/lib/_exit.c +++ b/lib/_exit.c @@ -5,12 +5,10 @@ */ #define __LIBRARY__ -#include +#include volatile void _exit(int exit_code) { -fake_volatile: __asm__("movl %1,%%ebx\n\t" "int $0x80"::"a" (__NR_exit),"g" (exit_code)); - goto fake_volatile; } diff --git a/lib/close.c b/lib/close.c index 31bb780f6d0d..afd8364f6bec 100644 --- a/lib/close.c +++ b/lib/close.c @@ -5,7 +5,6 @@ */ #define __LIBRARY__ -#include +#include _syscall1(int,close,int,fd) - diff --git a/lib/dup.c b/lib/dup.c index fddb3c3911c0..dd13414adf60 100644 --- a/lib/dup.c +++ b/lib/dup.c @@ -5,7 +5,6 @@ */ #define __LIBRARY__ -#include +#include _syscall1(int,dup,int,fd) - diff --git a/lib/execve.c b/lib/execve.c index 996b0eae81eb..a89726dec770 100644 --- a/lib/execve.c +++ b/lib/execve.c @@ -5,7 +5,6 @@ */ #define __LIBRARY__ -#include +#include _syscall3(int,execve,const char *,file,char **,argv,char **,envp) - diff --git a/lib/itimer.c b/lib/itimer.c deleted file mode 100644 index 69cf1eb2c1b4..000000000000 --- a/lib/itimer.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - * linux/lib/itimer.c - * - * (C) 1992 Darren Senn - */ - -#define __LIBRARY__ -#include -#include - -_syscall2(int,getitimer,int,which,struct itimerval *,value) -_syscall3(int,setitimer,int,which,struct itimerval *,value,struct itimerval *,ovalue) diff --git a/lib/open.c b/lib/open.c index 55c82ece60c8..59728071612b 100644 --- a/lib/open.c +++ b/lib/open.c @@ -5,7 +5,7 @@ */ #define __LIBRARY__ -#include +#include #include int open(const char * filename, int flag, ...) diff --git a/lib/setsid.c b/lib/setsid.c index f9f056f15b1f..68516c7e579d 100644 --- a/lib/setsid.c +++ b/lib/setsid.c @@ -5,8 +5,6 @@ */ #define __LIBRARY__ -#include -#include +#include _syscall0(pid_t,setsid) - diff --git a/lib/wait.c b/lib/wait.c index 114ef331a763..2815c16aeeb5 100644 --- a/lib/wait.c +++ b/lib/wait.c @@ -5,7 +5,7 @@ */ #define __LIBRARY__ -#include +#include #include _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) @@ -14,4 +14,3 @@ pid_t wait(int * wait_stat) { return waitpid(-1,wait_stat,0); } - diff --git a/lib/write.c b/lib/write.c index 5269cc686073..df52e74d6ede 100644 --- a/lib/write.c +++ b/lib/write.c @@ -5,8 +5,6 @@ */ #define __LIBRARY__ -#include -#include +#include _syscall3(int,write,int,fd,const char *,buf,off_t,count) - diff --git a/mm/Makefile b/mm/Makefile index c5ad9d3da0c5..c60e25bc8284 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -7,12 +7,20 @@ # # Note 2! The CFLAGS definition is now in the main makefile... +AS =as +AR =ar +LD =ld +CC =gcc -nostdinc -I../include +CPP =cpp -nostdinc -I../include + .c.o: - $(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) \ + -c -o $*.o $< .s.o: $(AS) -o $*.o $< .c.s: - $(CC) $(CFLAGS) -S $< + $(CC) $(CFLAGS) \ + -S -o $*.s $< OBJS = memory.o swap.o mmap.o @@ -25,27 +33,21 @@ clean: dep: sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - for i in *.c;do $(CPP) -M $$i;done >> tmp_make + (for i in *.c;do $(CPP) -M $$i;done) >> tmp_make cp tmp_make Makefile ### Dependencies: -memory.o : memory.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h -mmap.o : mmap.c /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ - /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/asm/system.h /usr/src/linux/include/errno.h /usr/src/linux/include/sys/mman.h -swap.o : swap.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/stat.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ - /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ - /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ - /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ - /usr/src/linux/include/sys/resource.h +memory.o : memory.c ../include/signal.h ../include/sys/types.h ../include/asm/system.h \ + ../include/linux/sched.h ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h \ + ../include/limits.h ../include/linux/mm.h ../include/linux/kernel.h ../include/sys/param.h \ + ../include/sys/time.h ../include/time.h ../include/sys/resource.h +mmap.o : mmap.c ../include/sys/stat.h ../include/sys/types.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h \ + ../include/linux/mm.h ../include/linux/kernel.h ../include/signal.h ../include/sys/param.h \ + ../include/sys/time.h ../include/time.h ../include/sys/resource.h ../include/asm/segment.h \ + ../include/asm/system.h ../include/errno.h ../include/sys/mman.h +swap.o : swap.c ../include/errno.h ../include/sys/stat.h ../include/sys/types.h \ + ../include/linux/mm.h ../include/linux/fs.h ../include/sys/dirent.h ../include/limits.h \ + ../include/linux/kernel.h ../include/signal.h ../include/linux/string.h ../include/linux/sched.h \ + ../include/linux/head.h ../include/sys/param.h ../include/sys/time.h ../include/time.h \ + ../include/sys/resource.h diff --git a/mm/memory.c b/mm/memory.c index 6fea34625b4f..866a5cb64ce5 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -189,7 +189,8 @@ int copy_page_tables(unsigned long from,unsigned long to,long size) * a more complete version of free_page_tables which performs with page * granularity. */ -int unmap_page_range(unsigned long from, unsigned long size) +int +unmap_page_range(unsigned long from, unsigned long size) { unsigned long page, page_dir; unsigned long *page_table, *dir; @@ -255,7 +256,8 @@ int unmap_page_range(unsigned long from, unsigned long size) * write/copy: yes/copy copy/copy * exec: yes yes */ -int remap_page_range(unsigned long from, unsigned long to, unsigned long size, +int +remap_page_range(unsigned long from, unsigned long to, unsigned long size, int permiss) { unsigned long *page_table, *dir; @@ -353,7 +355,7 @@ static unsigned long put_page(unsigned long page,unsigned long address) return 0; } if (mem_map[(page-LOW_MEM)>>12] != 1) { - printk("put_page: mem_map disagrees with %p at %p\n",page,address); + printk("mem_map disagrees with %p at %p\n",page,address); return 0; } page_table = (unsigned long *) ((address>>20) & 0xffc); @@ -487,7 +489,7 @@ void write_verify(unsigned long address) return; } -static void get_empty_page(unsigned long address) +void get_empty_page(unsigned long address) { unsigned long tmp; @@ -563,7 +565,7 @@ static int share_page(struct inode * inode, unsigned long address) struct task_struct ** p; int i; - if (!inode || inode->i_count < 2) + if (inode->i_count < 2 || !inode) return 0; for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { if (!*p) @@ -586,39 +588,14 @@ static int share_page(struct inode * inode, unsigned long address) return 0; } -/* - * fill in an empty page or directory if none exists - */ -static unsigned long get_empty(unsigned long * p) -{ - unsigned long page = 0; - -repeat: - if (1 & *p) { - free_page(page); - return *p; - } - if (*p) { - printk("get_empty: bad page entry \n"); - *p = 0; - } - if (page) { - *p = page | 7; - return *p; - } - if (!(page = get_free_page())) - oom(); - goto repeat; -} - void do_no_page(unsigned long error_code, unsigned long address, - struct task_struct *tsk, unsigned long user_esp) + struct task_struct *tsk) { static unsigned int last_checked = 0; int nr[4]; unsigned long tmp; unsigned long page; - unsigned int block,i; + int block,i; struct inode * inode; /* Thrashing ? Make it interruptible, but don't penalize otherwise */ @@ -639,50 +616,54 @@ void do_no_page(unsigned long error_code, unsigned long address, printk("Bad things happen: nonexistent page error in do_no_page\n\r"); do_exit(SIGSEGV); } - page = get_empty((unsigned long *) ((address >> 20) & 0xffc)); - page &= 0xfffff000; - page += (address >> 10) & 0xffc; - tmp = *(unsigned long *) page; - if (tmp & 1) { - printk("bogus do_no_page\n"); - return; - } ++tsk->rss; - if (tmp) { - ++tsk->maj_flt; - swap_in((unsigned long *) page); - return; + page = *(unsigned long *) ((address >> 20) & 0xffc); +/* check the page directory: make a page dir entry if no such exists */ + if (page & 1) { + page &= 0xfffff000; + page += (address >> 10) & 0xffc; + tmp = *(unsigned long *) page; + if (tmp && !(1 & tmp)) { + ++tsk->maj_flt; + swap_in((unsigned long *) page); + return; + } + } else { + if (page) + printk("do_no_page: bad page directory\n"); + if (!(page = get_free_page())) + oom(); + page |= 7; + *(unsigned long *) ((address >> 20) & 0xffc) = page; } address &= 0xfffff000; tmp = address - tsk->start_code; - inode = NULL; - block = 0; - if (tmp < tsk->end_data) { - inode = tsk->executable; - block = 1 + tmp / BLOCK_SIZE; - } else { + if (tmp >= LIBRARY_OFFSET ) { + inode = NULL; + block = 1; i = tsk->numlibraries; while (i-- > 0) { - if (tmp < tsk->libraries[i].start) - continue; - block = tmp - tsk->libraries[i].start; - if (block >= tsk->libraries[i].length) - continue; - inode = tsk->libraries[i].library; - block = 1 + block / BLOCK_SIZE; - break; + if (tmp < (tsk->libraries[i].start + + tsk->libraries[i].length)) { + inode = tsk->libraries[i].library; + block = 1 + (tmp - tsk->libraries[i].start) / + BLOCK_SIZE; + break; + } } + } else if (tmp < tsk->end_data) { + inode = tsk->executable; + block = 1 + tmp / BLOCK_SIZE; + } else { + inode = NULL; + block = 0; } if (!inode) { ++tsk->min_flt; + if (tmp < LIBRARY_OFFSET && tmp > tsk->brk && tsk == current && + LIBRARY_OFFSET - tmp > tsk->rlim[RLIMIT_STACK].rlim_max) + do_exit(SIGSEGV); get_empty_page(address); - if (tsk != current) - return; - if (tmp >= LIBRARY_OFFSET || tmp < tsk->brk) - return; - if (tmp+8192 >= (user_esp & 0xfffff000)) - return; - send_sig(SIGSEGV,tsk,1); return; } if (tsk == current) @@ -693,6 +674,7 @@ void do_no_page(unsigned long error_code, unsigned long address, ++tsk->maj_flt; if (!(page = get_free_page())) oom(); +/* remember that 1 block is used for header */ for (i=0 ; i<4 ; block++,i++) nr[i] = bmap(inode,block); bread_page(page,inode->i_dev,nr); @@ -700,7 +682,7 @@ void do_no_page(unsigned long error_code, unsigned long address, if (i>4095) i = 0; tmp = page + 4096; - while (i--) { + while (i-- > 0) { tmp--; *(char *)tmp = 0; } @@ -714,9 +696,6 @@ void mem_init(long start_mem, long end_mem) { int i; - end_mem &= 0xfffff000; - start_mem += 0xfff; - start_mem &= 0xfffff000; swap_device = 0; swap_file = NULL; HIGH_MEMORY = end_mem; @@ -784,16 +763,11 @@ void show_mem(void) void do_page_fault(unsigned long *esp, unsigned long error_code) { unsigned long address; - unsigned long user_esp; - - if ((0xffff & esp[1]) == 0xf) - user_esp = esp[3]; - else - user_esp = 0; /* get the address */ + __asm__("movl %%cr2,%0":"=r" (address)); if (!(error_code & 1)) { - do_no_page(error_code, address, current, user_esp); + do_no_page(error_code, address, current); return; } else { do_wp_page(error_code, address); diff --git a/mm/mmap.c b/mm/mmap.c index 281da970ef15..a8ea62805d3a 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -3,10 +3,9 @@ * * Written by obz. */ -#include +#include #include #include -#include #include #include #include @@ -38,11 +37,16 @@ #define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \ current->start_code + current->end_code) +extern int remap_page_range(unsigned long from, unsigned long to, + unsigned long size, int permiss); +extern int unmap_page_range(unsigned long from, unsigned long size); + static caddr_t mmap_chr(unsigned long addr, size_t len, int prot, int flags, struct inode *inode, unsigned long off) { int major, minor; + extern unsigned long HIGH_MEMORY; major = MAJOR(inode->i_rdev); minor = MINOR(inode->i_rdev); diff --git a/mm/swap.c b/mm/swap.c index f968e0518b53..ba4139946030 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -10,8 +10,8 @@ */ #include +#include -#include #include #include #include @@ -245,10 +245,10 @@ repeat: * * The swapon system call */ + int sys_swapon(const char * specialfile) { struct inode * swap_inode; - char * tmp; int i,j; if (!suser()) @@ -268,39 +268,38 @@ int sys_swapon(const char * specialfile) iput(swap_inode); return -EINVAL; } - tmp = (char *) get_free_page(); - if (!tmp) { + swap_bitmap = (char *) get_free_page(); + if (!swap_bitmap) { iput(swap_file); swap_device = 0; swap_file = NULL; printk("Unable to start swapping: out of memory :-)\n"); return -ENOMEM; } - read_swap_page(0,tmp); - if (strncmp("SWAP-SPACE",tmp+4086,10)) { + read_swap_page(0,swap_bitmap); + if (strncmp("SWAP-SPACE",swap_bitmap+4086,10)) { printk("Unable to find swap-space signature\n\r"); - free_page((long) tmp); + free_page((long) swap_bitmap); iput(swap_file); swap_device = 0; swap_file = NULL; swap_bitmap = NULL; return -EINVAL; } - memset(tmp+4086,0,10); + memset(swap_bitmap+4086,0,10); j = 0; for (i = 1 ; i < SWAP_BITS ; i++) - if (bit(tmp,i)) + if (bit(swap_bitmap,i)) j++; if (!j) { printk("Empty swap-file\n"); - free_page((long) tmp); + free_page((long) swap_bitmap); iput(swap_file); swap_device = 0; swap_file = NULL; swap_bitmap = NULL; return -EINVAL; } - swap_bitmap = tmp; printk("Adding Swap: %d pages (%d bytes) swap-space\n\r",j,j*4096); return 0; } diff --git a/net/Makefile b/net/Makefile deleted file mode 100644 index 1292340ace9d..000000000000 --- a/net/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -# -# Makefile for the linux networking. -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definition is now in the main makefile... - -.c.o: - $(CC) $(CFLAGS) -c $< -.s.o: - $(AS) -o $*.o $< -.c.s: - $(CC) $(CFLAGS) -S $< - -OBJS = socket.o unix.o - -net.o: $(OBJS) - $(LD) -r -o net.o $(OBJS) - -clean: - rm -f core *.o *.a tmp_make - for i in *.c;do rm -f `basename $$i .c`.s;done - -dep: - sed '/\#\#\# Dependencies/q' < Makefile > tmp_make - for i in *.c;do $(CPP) -M $$i;done >> tmp_make - cp tmp_make Makefile - -### Dependencies: -socket.o : socket.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \ - /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \ - /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \ - /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ - /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/stat.h \ - /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/sys/socket.h \ - /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/termios.h kern_sock.h \ - socketcall.h -unix.o : unix.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \ - /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/linux/string.h \ - /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ - /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ - /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h \ - /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ - /usr/src/linux/include/linux/stat.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h \ - /usr/src/linux/include/sys/socket.h /usr/src/linux/include/sys/un.h /usr/src/linux/include/linux/fcntl.h \ - /usr/src/linux/include/termios.h kern_sock.h diff --git a/net/kern_sock.h b/net/kern_sock.h deleted file mode 100644 index ccbd5e49f87b..000000000000 --- a/net/kern_sock.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _KERN_SOCK_H -#define _KERN_SOCK_H - -#define NSOCKETS 128 /* should be dynamic, later... */ - -typedef enum { - SS_FREE = 0, /* not allocated */ - SS_UNCONNECTED, /* unconnected to any socket */ - SS_CONNECTING, /* in process of connecting */ - SS_CONNECTED, /* connected to socket */ - SS_DISCONNECTING, /* in process of disconnecting */ -} socket_state; - -#define SO_ACCEPTCON (1<<16) /* performed a listen */ - -/* - * internel representation of a socket. not all the fields are used by - * all configurations: - * - * server client - * conn client connected to server connected to - * iconn list of clients -unused- - * awaiting connections - * wait sleep for clients, sleep for connection, - * sleep for i/o sleep for i/o - */ -struct socket { - short type; /* SOCK_STREAM, ... */ - socket_state state; - long flags; - struct proto_ops *ops; /* protocols do most everything */ - char *data; /* protocol data */ - struct socket *conn; /* server socket connected to */ - struct socket *iconn; /* incomplete client connections */ - struct socket *next; - struct wait_queue **wait; /* ptr to place to wait on */ - void *dummy; -}; - -struct proto_ops { - int (*init)(void); - int (*create)(struct socket *sock, int protocol); - int (*dup)(struct socket *newsock, struct socket *oldsock); - int (*release)(struct socket *sock, struct socket *peer); - int (*bind)(struct socket *sock, struct sockaddr *umyaddr, - int sockaddr_len); - int (*connect)(struct socket *sock, struct sockaddr *uservaddr, - int sockaddr_len); - int (*socketpair)(struct socket *sock1, struct socket *sock2); - int (*accept)(struct socket *sock, struct socket *newsock); - int (*getname)(struct socket *sock, struct sockaddr *uaddr, - int *usockaddr_len, int peer); - int (*read)(struct socket *sock, char *ubuf, int size, int nonblock); - int (*write)(struct socket *sock, char *ubuf, int size, int nonblock); - int (*select)(struct socket *sock, int sel_type, select_table * wait); - int (*ioctl)(struct socket *sock, unsigned int cmd, unsigned long arg); -}; - -extern int sock_awaitconn(struct socket *mysock, struct socket *servsock); - -#ifdef SOCK_DEBUG -#define PRINTK printk -#else -#define PRINTK (void) -#endif - -#endif /* _KERN_SOCK_H */ diff --git a/net/socket.c b/net/socket.c deleted file mode 100644 index ec3cd3509e15..000000000000 --- a/net/socket.c +++ /dev/null @@ -1,764 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kern_sock.h" -#include "socketcall.h" - -extern int sys_close(int fd); - -extern struct proto_ops unix_proto_ops; - -static struct { - short family; - char *name; - struct proto_ops *ops; -} proto_table[] = { - AF_UNIX, "AF_UNIX", &unix_proto_ops -}; -#define NPROTO (sizeof(proto_table) / sizeof(proto_table[0])) - -static char * -family_name(int family) -{ - int i; - - for (i = 0; i < NPROTO; ++i) - if (proto_table[i].family == family) - return proto_table[i].name; - return "UNKNOWN"; -} - -static int sock_lseek(struct inode *inode, struct file *file, off_t offset, - int whence); -static int sock_read(struct inode *inode, struct file *file, char *buf, - int size); -static int sock_write(struct inode *inode, struct file *file, char *buf, - int size); -static int sock_readdir(struct inode *inode, struct file *file, - struct dirent *dirent, int count); -static void sock_close(struct inode *inode, struct file *file); -static int sock_select(struct inode *inode, struct file *file, int which, select_table *seltable); -static int sock_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned int arg); - -static struct file_operations socket_file_ops = { - sock_lseek, - sock_read, - sock_write, - sock_readdir, - sock_select, /* not in vfs yet */ - sock_ioctl, - NULL, /* no special open code... */ - sock_close -}; - -#define SOCK_INODE(S) ((struct inode *)(S)->dummy) - -static struct socket sockets[NSOCKETS]; -#define last_socket (sockets + NSOCKETS - 1) -static struct wait_queue *socket_wait_free = NULL; - -/* - * obtains the first available file descriptor and sets it up for use - */ -static int -get_fd(struct inode *inode) -{ - int fd, i; - struct file *file; - - /* - * find a file descriptor suitable for return to the user. - */ - for (fd = 0; fd < NR_OPEN; ++fd) - if (!current->filp[fd]) - break; - if (fd == NR_OPEN) - return -1; - current->close_on_exec &= ~(1 << fd); - for (file = file_table, i = 0; i < NR_FILE; ++i, ++file) - if (!file->f_count) - break; - if (i == NR_FILE) - return -1; - current->filp[fd] = file; - file->f_op = &socket_file_ops; - file->f_mode = 3; - file->f_flags = 0; - file->f_count = 1; - file->f_inode = inode; - file->f_pos = 0; - return fd; -} - -/* - * reverses the action of get_fd() by releasing the file. it closes the - * descriptor, but makes sure it does nothing more. called when an incomplete - * socket must be closed, along with sock_release(). - */ -static inline void -toss_fd(int fd) -{ - current->filp[fd]->f_inode = NULL; /* safe from iput */ - sys_close(fd); -} - -static inline struct socket * -socki_lookup(struct inode *inode) -{ - struct socket *sock; - - for (sock = sockets; sock <= last_socket; ++sock) - if (sock->state != SS_FREE && SOCK_INODE(sock) == inode) - return sock; - return NULL; -} - -static inline struct socket * -sockfd_lookup(int fd, struct file **pfile) -{ - struct file *file; - - if (fd < 0 || fd >= NR_OPEN || !(file = current->filp[fd])) - return NULL; - if (pfile) - *pfile = file; - return socki_lookup(file->f_inode); -} - -static struct socket * -sock_alloc(int wait) -{ - struct socket *sock; - - while (1) { - cli(); - for (sock = sockets; sock <= last_socket; ++sock) - if (sock->state == SS_FREE) { - sock->state = SS_UNCONNECTED; - sti(); - sock->flags = 0; - sock->ops = NULL; - sock->data = NULL; - sock->conn = NULL; - sock->iconn = NULL; - /* - * this really shouldn't be necessary, but - * everything else depends on inodes, so we - * grab it. - * sleeps are also done on the i_wait member - * of this inode. - * the close system call will iput this inode - * for us. - */ - if (!(SOCK_INODE(sock) = get_empty_inode())) { - printk("sock_alloc: no more inodes\n"); - sock->state = SS_FREE; - return NULL; - } - SOCK_INODE(sock)->i_mode = S_IFSOCK; - sock->wait = &SOCK_INODE(sock)->i_wait; - PRINTK("sock_alloc: socket 0x%x, inode 0x%x\n", - sock, SOCK_INODE(sock)); - return sock; - } - sti(); - if (!wait) - return NULL; - PRINTK("sock_alloc: no free sockets, sleeping...\n"); - interruptible_sleep_on(&socket_wait_free); - if (current->signal & ~current->blocked) { - PRINTK("sock_alloc: sleep was interrupted\n"); - return NULL; - } - PRINTK("sock_alloc: wakeup... trying again...\n"); - } -} - -static inline void -sock_release_peer(struct socket *peer) -{ - peer->state = SS_DISCONNECTING; - wake_up(peer->wait); -} - -static void -sock_release(struct socket *sock) -{ - int oldstate; - struct socket *peersock, *nextsock; - - PRINTK("sock_release: socket 0x%x, inode 0x%x\n", sock, - SOCK_INODE(sock)); - if ((oldstate = sock->state) != SS_UNCONNECTED) - sock->state = SS_DISCONNECTING; - /* - * wake up anyone waiting for connections - */ - for (peersock = sock->iconn; peersock; peersock = nextsock) { - nextsock = peersock->next; - sock_release_peer(peersock); - } - /* - * wake up anyone we're connected to. first, we release the - * protocol, to give it a chance to flush data, etc. - */ - peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL; - if (sock->ops) - sock->ops->release(sock, peersock); - if (peersock) - sock_release_peer(peersock); - sock->state = SS_FREE; /* this really releases us */ - wake_up(&socket_wait_free); -} - -static int -sock_lseek(struct inode *inode, struct file *file, off_t offset, int whence) -{ - PRINTK("sock_lseek: huh?\n"); - return -EBADF; -} - -static int -sock_read(struct inode *inode, struct file *file, char *ubuf, int size) -{ - struct socket *sock; - - PRINTK("sock_read: buf=0x%x, size=%d\n", ubuf, size); - if (!(sock = socki_lookup(inode))) { - printk("sock_read: can't find socket for inode!\n"); - return -EBADF; - } - if (sock->flags & SO_ACCEPTCON) - return -EINVAL; - return sock->ops->read(sock, ubuf, size, (file->f_flags & O_NONBLOCK)); -} - -static int -sock_write(struct inode *inode, struct file *file, char *ubuf, int size) -{ - struct socket *sock; - - PRINTK("sock_write: buf=0x%x, size=%d\n", ubuf, size); - if (!(sock = socki_lookup(inode))) { - printk("sock_write: can't find socket for inode!\n"); - return -EBADF; - } - if (sock->flags & SO_ACCEPTCON) - return -EINVAL; - return sock->ops->write(sock, ubuf, size,(file->f_flags & O_NONBLOCK)); -} - -static int -sock_readdir(struct inode *inode, struct file *file, struct dirent *dirent, - int count) -{ - PRINTK("sock_readdir: huh?\n"); - return -EBADF; -} - -int -sock_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned int arg) -{ - struct socket *sock; - - PRINTK("sock_ioctl: inode=0x%x cmd=0x%x arg=%d\n", inode, cmd, arg); - if (!(sock = socki_lookup(inode))) { - printk("sock_ioctl: can't find socket for inode!\n"); - return -EBADF; - } - switch (cmd) { - case TIOCINQ: - case TIOCOUTQ: - if (sock->flags & SO_ACCEPTCON) - return -EINVAL; - break; - - default: - return -EINVAL; - } - return sock->ops->ioctl(sock, cmd, arg); -} - -static int -sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait) -{ - struct socket *sock; - - PRINTK("sock_select: inode = 0x%x, kind = %s\n", inode, - (sel_type == SEL_IN) ? "in" : - (sel_type == SEL_OUT) ? "out" : "ex"); - if (!(sock = socki_lookup(inode))) { - printk("sock_select: can't find socket for inode!\n"); - return 0; - } - - /* - * handle server sockets specially - */ - if (sock->flags & SO_ACCEPTCON) { - if (sel_type == SEL_IN) { - PRINTK("sock_select: %sconnections pending\n", - sock->iconn ? "" : "no "); - if (sock->iconn) - return 1; - select_wait(&inode->i_wait, wait); - return sock->iconn ? 1 : 0; - } - PRINTK("sock_select: nothing else for server socket\n"); - select_wait(&inode->i_wait, wait); - return 0; - } - /* - * we can't return errors to select, so its either yes or no. - */ - if (sock->ops && sock->ops->select) - return sock->ops->select(sock, sel_type, wait); - return 0; -} - -void -sock_close(struct inode *inode, struct file *file) -{ - struct socket *sock; - - PRINTK("sock_close: inode=0x%x (cnt=%d)\n", inode, inode->i_count); - /* - * it's possible the inode is NULL if we're closing an unfinished - * socket. - */ - if (!inode) - return; - if (!(sock = socki_lookup(inode))) { - printk("sock_close: can't find socket for inode!\n"); - return; - } - sock_release(sock); -} - -int -sock_awaitconn(struct socket *mysock, struct socket *servsock) -{ - struct socket *last; - - PRINTK("sock_awaitconn: trying to connect socket 0x%x to 0x%x\n", - mysock, servsock); - if (!(servsock->flags & SO_ACCEPTCON)) { - PRINTK("sock_awaitconn: server not accepting connections\n"); - return -EINVAL; - } - - /* - * put ourselves on the server's incomplete connection queue. - */ - mysock->next = NULL; - cli(); - if (!(last = servsock->iconn)) - servsock->iconn = mysock; - else { - while (last->next) - last = last->next; - last->next = mysock; - } - mysock->state = SS_CONNECTING; - mysock->conn = servsock; - sti(); - - /* - * wake up server, then await connection. server will set state to - * SS_CONNECTED if we're connected. - */ - wake_up(servsock->wait); - if (mysock->state != SS_CONNECTED) { - interruptible_sleep_on(mysock->wait); - if (mysock->state != SS_CONNECTED) { - /* - * if we're not connected we could have been - * 1) interrupted, so we need to remove ourselves - * from the server list - * 2) rejected (mysock->conn == NULL), and have - * already been removed from the list - */ - if (mysock->conn == servsock) { - cli(); - if ((last = servsock->iconn) == mysock) - servsock->iconn = mysock->next; - else { - while (last->next != mysock) - last = last->next; - last->next = mysock->next; - } - sti(); - } - return mysock->conn ? -EINTR : -EACCES; - } - } - return 0; -} - -/* - * perform the socket system call. we locate the appropriate family, then - * create a fresh socket. - */ -static int -sock_socket(int family, int type, int protocol) -{ - int i, fd; - struct socket *sock; - struct proto_ops *ops; - - PRINTK("sys_socket: family = %d (%s), type = %d, protocol = %d\n", - family, family_name(family), type, protocol); - - /* - * locate the correct protocol family - */ - for (i = 0; i < NPROTO; ++i) - if (proto_table[i].family == family) - break; - if (i == NPROTO) { - PRINTK("sys_socket: family not found\n"); - return -EINVAL; - } - ops = proto_table[i].ops; - - /* - * check that this is a type that we know how to manipulate and - * the protocol makes sense here. the family can still reject the - * protocol later. - */ - if ((type != SOCK_STREAM && - type != SOCK_DGRAM && - type != SOCK_SEQPACKET && - type != SOCK_RAW) || - protocol < 0) - return -EINVAL; - - /* - * allocate the socket and allow the family to set things up. if - * the protocol is 0, the family is instructed to select an appropriate - * default. - */ - if (!(sock = sock_alloc(1))) { - printk("sys_socket: no more sockets\n"); - return -EAGAIN; - } - sock->type = type; - sock->ops = ops; - if ((i = sock->ops->create(sock, protocol)) < 0) { - sock_release(sock); - return i; - } - - if ((fd = get_fd(SOCK_INODE(sock))) < 0) { - sock_release(sock); - return -EINVAL; - } - - return fd; -} - -static int -sock_socketpair(int family, int type, int protocol, int usockvec[2]) -{ - int fd1, fd2, i; - struct socket *sock1, *sock2; - - PRINTK("sys_socketpair: family = %d, type = %d, protocol = %d\n", - family, type, protocol); - - /* - * obtain the first socket and check if the underlying protocol - * supports the socketpair call - */ - if ((fd1 = sock_socket(family, type, protocol)) < 0) - return fd1; - sock1 = sockfd_lookup(fd1, NULL); - if (!sock1->ops->socketpair) { - sys_close(fd1); - return -EINVAL; - } - - /* - * now grab another socket and try to connect the two together - */ - if ((fd2 = sock_socket(family, type, protocol)) < 0) { - sys_close(fd1); - return -EINVAL; - } - sock2 = sockfd_lookup(fd2, NULL); - if ((i = sock1->ops->socketpair(sock1, sock2)) < 0) { - sys_close(fd1); - sys_close(fd2); - return i; - } - sock1->conn = sock2; - sock2->conn = sock1; - sock1->state = SS_CONNECTED; - sock2->state = SS_CONNECTED; - - verify_area(usockvec, 2 * sizeof(int)); - put_fs_long(fd1, &usockvec[0]); - put_fs_long(fd2, &usockvec[1]); - - return 0; -} - -/* - * binds a name to a socket. nothing much to do here since its the - * protocol's responsibility to handle the local address - */ -static int -sock_bind(int fd, struct sockaddr *umyaddr, int addrlen) -{ - struct socket *sock; - int i; - - PRINTK("sys_bind: fd = %d\n", fd); - if (!(sock = sockfd_lookup(fd, NULL))) - return -EBADF; - if ((i = sock->ops->bind(sock, umyaddr, addrlen)) < 0) { - PRINTK("sys_bind: bind failed\n"); - return i; - } - return 0; -} - -/* - * perform a listen. basically, we allow the protocol to do anything - * necessary for a listen, and if that works, we mark the socket as - * ready for listening. - */ -static int -sock_listen(int fd, int backlog) -{ - struct socket *sock; - - PRINTK("sys_listen: fd = %d\n", fd); - if (!(sock = sockfd_lookup(fd, NULL))) - return -EBADF; - if (sock->state != SS_UNCONNECTED) { - PRINTK("sys_listen: socket isn't unconnected\n"); - return -EINVAL; - } - if (sock->flags & SO_ACCEPTCON) { - PRINTK("sys_listen: socket already accepting connections!\n"); - return -EINVAL; - } - sock->flags |= SO_ACCEPTCON; - return 0; -} - -/* - * for accept, we attempt to create a new socket, set up the link with the - * client, wake up the client, then return the new connected fd. - */ -static int -sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen) -{ - struct file *file; - struct socket *sock, *clientsock, *newsock; - int i; - - PRINTK("sys_accept: fd = %d\n", fd); - if (!(sock = sockfd_lookup(fd, &file))) - return -EBADF; - if (sock->state != SS_UNCONNECTED) { - PRINTK("sys_accept: socket isn't unconnected\n"); - return -EINVAL; - } - if (!(sock->flags & SO_ACCEPTCON)) { - PRINTK("sys_accept: socket not accepting connections!\n"); - return -EINVAL; - } - - /* - * if there aren't any sockets awaiting connection, then wait for - * one, unless nonblocking - */ - while (!(clientsock = sock->iconn)) { - if (file->f_flags & O_NONBLOCK) - return -EAGAIN; - interruptible_sleep_on(sock->wait); - if (current->signal & ~current->blocked) { - PRINTK("sys_accept: sleep was interrupted\n"); - return -ERESTARTSYS; - } - } - - if (!(newsock = sock_alloc(0))) { - printk("sys_accept: no more sockets\n"); - return -EINVAL; - } - newsock->type = sock->type; - newsock->ops = sock->ops; - if ((i = sock->ops->dup(newsock, sock)) < 0) { - sock_release(newsock); - return i; - } - - if ((fd = get_fd(SOCK_INODE(newsock))) < 0) { - sock_release(newsock); - return -EINVAL; - } - - /* - * great. finish the connection relative to server and client, - * wake up the client and return the new fd to the server - */ - sock->iconn = clientsock->next; - clientsock->next = NULL; - newsock->conn = clientsock; - clientsock->conn = newsock; - clientsock->state = SS_CONNECTED; - newsock->state = SS_CONNECTED; - newsock->ops->accept(sock, newsock); - PRINTK("sys_accept: connected socket 0x%x via 0x%x to 0x%x\n", - sock, newsock, clientsock); - if (upeer_sockaddr) - newsock->ops->getname(newsock, upeer_sockaddr, - upeer_addrlen, 1); - wake_up(clientsock->wait); - - return fd; -} - -/* - * attempt to connect to a socket with the server address. - */ -static int -sock_connect(int fd, struct sockaddr *uservaddr, int addrlen) -{ - struct socket *sock; - int i; - - PRINTK("sys_connect: fd = %d\n", fd); - if (!(sock = sockfd_lookup(fd, NULL))) - return -EBADF; - if (sock->state != SS_UNCONNECTED) { - PRINTK("sys_connect: socket not unconnected\n"); - return -EINVAL; - } - if ((i = sock->ops->connect(sock, uservaddr, addrlen)) < 0) { - PRINTK("sys_connect: connect failed\n"); - return i; - } - return 0; -} - -static int -sock_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len) -{ - struct socket *sock; - - PRINTK("sys_getsockname: fd = %d\n", fd); - if (!(sock = sockfd_lookup(fd, NULL))) - return -EBADF; - return sock->ops->getname(sock, usockaddr, usockaddr_len, 0); -} - -static int -sock_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len) -{ - struct socket *sock; - - PRINTK("sys_getpeername: fd = %d\n", fd); - if (!(sock = sockfd_lookup(fd, NULL))) - return -EBADF; - return sock->ops->getname(sock, usockaddr, usockaddr_len, 1); -} - -/* - * system call vectors. since i want to rewrite sockets as streams, we have - * this level of indirection. not a lot of overhead, since more of the work is - * done via read/write/select directly - */ -int -sys_socketcall(int call, unsigned long *args) -{ - switch (call) { - case SYS_SOCKET: - verify_area(args, 3 * sizeof(long)); - return sock_socket(get_fs_long(args+0), - get_fs_long(args+1), - get_fs_long(args+2)); - - case SYS_BIND: - verify_area(args, 3 * sizeof(long)); - return sock_bind(get_fs_long(args+0), - (struct sockaddr *)get_fs_long(args+1), - get_fs_long(args+2)); - - case SYS_CONNECT: - verify_area(args, 3 * sizeof(long)); - return sock_connect(get_fs_long(args+0), - (struct sockaddr *)get_fs_long(args+1), - get_fs_long(args+2)); - - case SYS_LISTEN: - verify_area(args, 2 * sizeof(long)); - return sock_listen(get_fs_long(args+0), - get_fs_long(args+1)); - - case SYS_ACCEPT: - verify_area(args, 3 * sizeof(long)); - return sock_accept(get_fs_long(args+0), - (struct sockaddr *)get_fs_long(args+1), - (int *)get_fs_long(args+2)); - - case SYS_GETSOCKNAME: - verify_area(args, 3 * sizeof(long)); - return sock_getsockname(get_fs_long(args+0), - (struct sockaddr *)get_fs_long(args+1), - (int *)get_fs_long(args+2)); - - case SYS_GETPEERNAME: - verify_area(args, 3 * sizeof(long)); - return sock_getpeername(get_fs_long(args+0), - (struct sockaddr *)get_fs_long(args+1), - (int *)get_fs_long(args+2)); - - case SYS_SOCKETPAIR: - verify_area(args, 4 * sizeof(long)); - return sock_socketpair(get_fs_long(args+0), - get_fs_long(args+1), - get_fs_long(args+2), - (int *)get_fs_long(args+3)); - - default: - return -EINVAL; - } -} - -void -sock_init(void) -{ - struct socket *sock; - int i, ok; - - for (sock = sockets; sock <= last_socket; ++sock) - sock->state = SS_FREE; - for (i = ok = 0; i < NPROTO; ++i) { - printk("sock_init: initializing family %d (%s)\n", - proto_table[i].family, proto_table[i].name); - if ((*proto_table[i].ops->init)() < 0) { - printk("sock_init: init failed.\n", - proto_table[i].family); - proto_table[i].family = -1; - } - else - ++ok; - } - if (!ok) - printk("sock_init: warning: no protocols initialized\n"); - return; -} - diff --git a/net/socketcall.h b/net/socketcall.h deleted file mode 100644 index 4b48562de73a..000000000000 --- a/net/socketcall.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _SOCKETCALL_ -#define _SOCKETCALL_ - -#define SYS_SOCKET 1 -#define SYS_BIND 2 -#define SYS_CONNECT 3 -#define SYS_LISTEN 4 -#define SYS_ACCEPT 5 -#define SYS_GETSOCKNAME 6 -#define SYS_GETPEERNAME 7 -#define SYS_SOCKETPAIR 8 - -#endif _SOCKETCALL_ diff --git a/net/unix.c b/net/unix.c deleted file mode 100644 index 64a5eb6e7af3..000000000000 --- a/net/unix.c +++ /dev/null @@ -1,598 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kern_sock.h" - -static struct unix_proto_data { - int refcnt; /* cnt of reference 0=free */ - struct socket *socket; /* socket we're bound to */ - int protocol; - struct sockaddr_un sockaddr_un; - short sockaddr_len; /* >0 if name bound */ - char *buf; - int bp_head, bp_tail; - struct inode *inode; - struct unix_proto_data *peerupd; -} unix_datas[NSOCKETS]; -#define last_unix_data (unix_datas + NSOCKETS - 1) - -#define UN_DATA(SOCK) ((struct unix_proto_data *)(SOCK)->data) -#define UN_PATH_OFFSET ((unsigned long)((struct sockaddr_un *)0)->sun_path) - -/* - * buffer size must be power of 2. buffer mgmt inspired by pipe code. - * note that buffer contents can wraparound, and we can write one byte less - * than full size to discern full vs empty. - */ -#define BUF_SIZE PAGE_SIZE -#define UN_BUF_AVAIL(UPD) (((UPD)->bp_head - (UPD)->bp_tail) & (BUF_SIZE-1)) -#define UN_BUF_SPACE(UPD) ((BUF_SIZE-1) - UN_BUF_AVAIL(UPD)) - -static int unix_proto_init(void); -static int unix_proto_create(struct socket *sock, int protocol); -static int unix_proto_dup(struct socket *newsock, struct socket *oldsock); -static int unix_proto_release(struct socket *sock, struct socket *peer); -static int unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr, - int sockaddr_len); -static int unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr, - int sockaddr_len); -static int unix_proto_socketpair(struct socket *sock1, struct socket *sock2); -static int unix_proto_accept(struct socket *sock, struct socket *newsock); -static int unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr, - int *usockaddr_len, int peer); -static int unix_proto_read(struct socket *sock, char *ubuf, int size, - int nonblock); -static int unix_proto_write(struct socket *sock, char *ubuf, int size, - int nonblock); -static int unix_proto_select(struct socket *sock, int sel_type, select_table * wait); -static int unix_proto_ioctl(struct socket *sock, unsigned int cmd, - unsigned long arg); - -struct proto_ops unix_proto_ops = { - unix_proto_init, - unix_proto_create, - unix_proto_dup, - unix_proto_release, - unix_proto_bind, - unix_proto_connect, - unix_proto_socketpair, - unix_proto_accept, - unix_proto_getname, - unix_proto_read, - unix_proto_write, - unix_proto_select, - unix_proto_ioctl -}; - -#ifdef SOCK_DEBUG -void -sockaddr_un_printk(struct sockaddr_un *sockun, int sockaddr_len) -{ - char buf[sizeof(sockun->sun_path) + 1]; - - sockaddr_len -= UN_PATH_OFFSET; - if (sockun->sun_family != AF_UNIX) - printk("sockaddr_un: \n", sockun->sun_family); - else if (sockaddr_len <= 0 || sockaddr_len >= sizeof(buf)-1) - printk("sockaddr_un: \n", sockaddr_len); - else { - memcpy(buf, sockun->sun_path, sockaddr_len); - buf[sockaddr_len] = '\0'; - printk("sockaddr_un: '%s'[%d]\n", buf, - sockaddr_len + UN_PATH_OFFSET); - } -} -#endif - -static struct unix_proto_data * -unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len) -{ - struct unix_proto_data *upd; - - for (upd = unix_datas; upd <= last_unix_data; ++upd) { - if (upd->refcnt && upd->socket && - upd->sockaddr_len == sockaddr_len && - memcmp(&upd->sockaddr_un, sockun, sockaddr_len) == 0) - return upd; - } - return NULL; -} - -static struct unix_proto_data * -unix_data_alloc(void) -{ - struct unix_proto_data *upd; - - cli(); - for (upd = unix_datas; upd <= last_unix_data; ++upd) { - if (!upd->refcnt) { - upd->refcnt = 1; - sti(); - upd->socket = NULL; - upd->sockaddr_len = 0; - upd->buf = NULL; - upd->bp_head = upd->bp_tail = 0; - upd->inode = NULL; - upd->peerupd = NULL; - return upd; - } - } - sti(); - return NULL; -} - -static inline void -unix_data_ref(struct unix_proto_data *upd) -{ - ++upd->refcnt; - PRINTK("unix_data_ref: refing data 0x%x (%d)\n", upd, upd->refcnt); -} - -static void -unix_data_deref(struct unix_proto_data *upd) -{ - if (upd->refcnt == 1) { - PRINTK("unix_data_deref: releasing data 0x%x\n", upd); - if (upd->buf) { - free_page((unsigned long)upd->buf); - upd->buf = NULL; - upd->bp_head = upd->bp_tail = 0; - } - } - --upd->refcnt; -} - -/* - * upon a create, we allocate an empty protocol data, and grab a page to - * buffer writes - */ -static int -unix_proto_create(struct socket *sock, int protocol) -{ - struct unix_proto_data *upd; - - PRINTK("unix_proto_create: socket 0x%x, proto %d\n", sock, protocol); - if (protocol != 0) { - PRINTK("unix_proto_create: protocol != 0\n"); - return -EINVAL; - } - if (!(upd = unix_data_alloc())) { - printk("unix_proto_create: can't allocate buffer\n"); - return -ENOMEM; - } - if (!(upd->buf = (char *)get_free_page())) { - printk("unix_proto_create: can't get page!\n"); - unix_data_deref(upd); - return -ENOMEM; - } - upd->protocol = protocol; - upd->socket = sock; - UN_DATA(sock) = upd; - PRINTK("unix_proto_create: allocated data 0x%x\n", upd); - return 0; -} - -static int -unix_proto_dup(struct socket *newsock, struct socket *oldsock) -{ - struct unix_proto_data *upd = UN_DATA(oldsock); - - return unix_proto_create(newsock, upd->protocol); -} - -static int -unix_proto_release(struct socket *sock, struct socket *peer) -{ - struct unix_proto_data *upd = UN_DATA(sock); - - PRINTK("unix_proto_release: socket 0x%x, unix_data 0x%x\n", - sock, upd); - if (!upd) - return 0; - if (upd->socket != sock) { - printk("unix_proto_release: socket link mismatch!\n"); - return -EINVAL; - } - if (upd->inode) { - PRINTK("unix_proto_release: releasing inode 0x%x\n", - upd->inode); - iput(upd->inode); - upd->inode = NULL; - } - UN_DATA(sock) = NULL; - upd->socket = NULL; - if (upd->peerupd) - unix_data_deref(upd->peerupd); - unix_data_deref(upd); - return 0; -} - -/* - * bind a name to a socket. this is where much of the work is done. we - * allocate a fresh page for the buffer, grab the appropriate inode and - * set things up. - * - * XXX what should we do if an address is already bound? here we return - * EINVAL, but it may be necessary to re-bind. i think thats what bsd does - * in the case of datagram sockets - */ -static int -unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr, - int sockaddr_len) -{ - struct unix_proto_data *upd = UN_DATA(sock); - char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1]; - int i; - unsigned long old_fs; - - PRINTK("unix_proto_bind: socket 0x%x, len=%d\n", sock, - sockaddr_len); - if (sockaddr_len <= UN_PATH_OFFSET || - sockaddr_len >= sizeof(struct sockaddr_un)) { - PRINTK("unix_proto_bind: bad length %d\n", sockaddr_len); - return -EINVAL; - } - if (upd->sockaddr_len || upd->inode) { - printk("unix_proto_bind: already bound!\n"); - return -EINVAL; - } - verify_area(umyaddr, sockaddr_len); - memcpy_fromfs(&upd->sockaddr_un, umyaddr, sockaddr_len); - if (upd->sockaddr_un.sun_family != AF_UNIX) { - PRINTK("unix_proto_bind: family is %d, not AF_UNIX (%d)\n", - upd->sockaddr_un.sun_family, AF_UNIX); - return -EINVAL; - } - - memcpy(fname, upd->sockaddr_un.sun_path, sockaddr_len-UN_PATH_OFFSET); - fname[sockaddr_len-UN_PATH_OFFSET] = '\0'; - old_fs = get_fs(); - set_fs(get_ds()); - i = do_mknod(fname, S_IFSOCK | 0777, 0); - if (i == 0) - i = open_namei(fname, 0, S_IFSOCK, &upd->inode); - set_fs(old_fs); - if (i < 0) { - printk("unix_proto_bind: can't open socket %s\n", fname); - return i; - } - - upd->sockaddr_len = sockaddr_len; /* now its legal */ - PRINTK("unix_proto_bind: bound socket address: "); -#ifdef SOCK_DEBUG - sockaddr_un_printk(&upd->sockaddr_un, upd->sockaddr_len); -#endif - return 0; -} - -/* - * perform a connection. we can only connect to unix sockets (i can't for - * the life of me find an application where that wouldn't be the case!) - */ -static int -unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr, - int sockaddr_len) -{ - int i; - struct unix_proto_data *serv_upd; - struct sockaddr_un sockun; - - PRINTK("unix_proto_connect: socket 0x%x, servlen=%d\n", sock, - sockaddr_len); - if (sockaddr_len <= UN_PATH_OFFSET || - sockaddr_len >= sizeof(struct sockaddr_un)) { - PRINTK("unix_proto_connect: bad length %d\n", sockaddr_len); - return -EINVAL; - } - verify_area(uservaddr, sockaddr_len); - memcpy_fromfs(&sockun, uservaddr, sockaddr_len); - if (sockun.sun_family != AF_UNIX) { - PRINTK("unix_proto_connect: family is %d, not AF_UNIX (%d)\n", - sockun.sun_family, AF_UNIX); - return -EINVAL; - } - if (!(serv_upd = unix_data_lookup(&sockun, sockaddr_len))) { - PRINTK("unix_proto_connect: can't locate peer\n"); - return -EINVAL; - } - if ((i = sock_awaitconn(sock, serv_upd->socket)) < 0) { - PRINTK("unix_proto_connect: can't await connection\n"); - return i; - } - unix_data_ref(UN_DATA(sock->conn)); - UN_DATA(sock)->peerupd = UN_DATA(sock->conn); /* ref server */ - return 0; -} - -/* - * to do a socketpair, we make just connect the two datas, easy! since we - * always wait on the socket inode, they're no contention for a wait area, - * and deadlock prevention in the case of a process writing to itself is, - * ignored, in true unix fashion! - */ -static int -unix_proto_socketpair(struct socket *sock1, struct socket *sock2) -{ - struct unix_proto_data *upd1 = UN_DATA(sock1), *upd2 = UN_DATA(sock2); - - unix_data_ref(upd1); - unix_data_ref(upd2); - upd1->peerupd = upd2; - upd2->peerupd = upd1; - return 0; -} - -/* - * on accept, we ref the peer's data for safe writes - */ -static int -unix_proto_accept(struct socket *sock, struct socket *newsock) -{ - PRINTK("unix_proto_accept: socket 0x%x accepted via socket 0x%x\n", - sock, newsock); - unix_data_ref(UN_DATA(newsock->conn)); - UN_DATA(newsock)->peerupd = UN_DATA(newsock->conn); - return 0; -} - -/* - * gets the current name or the name of the connected socket. - */ -static int -unix_proto_getname(struct socket *sock, struct sockaddr *usockaddr, - int *usockaddr_len, int peer) -{ - struct unix_proto_data *upd; - int len; - - PRINTK("unix_proto_getname: socket 0x%x for %s\n", sock, - peer ? "peer" : "self"); - if (peer) { - if (sock->state != SS_CONNECTED) { - PRINTK("unix_proto_getname: socket not connected\n"); - return -EINVAL; - } - upd = UN_DATA(sock->conn); - } - else - upd = UN_DATA(sock); - verify_area(usockaddr_len, sizeof(*usockaddr_len)); - if ((len = get_fs_long(usockaddr_len)) <= 0) - return -EINVAL; - if (len > upd->sockaddr_len) - len = upd->sockaddr_len; - if (len) { - verify_area(usockaddr, len); - memcpy_tofs(usockaddr, &upd->sockaddr_un, len); - } - put_fs_long(len, usockaddr_len); - return 0; -} - -/* - * we read from our own buf. - */ -static int -unix_proto_read(struct socket *sock, char *ubuf, int size, int nonblock) -{ - struct unix_proto_data *upd; - int todo, avail; - - if ((todo = size) <= 0) - return 0; - upd = UN_DATA(sock); - while (!(avail = UN_BUF_AVAIL(upd))) { - if (sock->state != SS_CONNECTED) { - PRINTK("unix_proto_read: socket not connected\n"); - return (sock->state == SS_DISCONNECTING) ? 0 : -EINVAL; - } - PRINTK("unix_proto_read: no data available...\n"); - if (nonblock) - return -EAGAIN; - interruptible_sleep_on(sock->wait); - if (current->signal & ~current->blocked) { - PRINTK("unix_proto_read: interrupted\n"); - return -ERESTARTSYS; - } - if (sock->state == SS_DISCONNECTING) { - PRINTK("unix_proto_read: disconnected\n"); - return 0; - } - } - - /* - * copy from the read buffer into the user's buffer, watching for - * wraparound. then we wake up the writer - */ - do { - int part, cando; - - if (avail <= 0) { - PRINTK("unix_proto_read: AVAIL IS NEGATIVE!!!\n"); - send_sig(SIGKILL,current,1); - return -EINTR; - } - - if ((cando = todo) > avail) - cando = avail; - if (cando > (part = BUF_SIZE - upd->bp_tail)) - cando = part; - PRINTK("unix_proto_read: avail=%d, todo=%d, cando=%d\n", - avail, todo, cando); - verify_area(ubuf, cando); - memcpy_tofs(ubuf, upd->buf + upd->bp_tail, cando); - upd->bp_tail = (upd->bp_tail + cando) & (BUF_SIZE-1); - ubuf += cando; - todo -= cando; - if (sock->state == SS_CONNECTED) - wake_up(sock->conn->wait); - avail = UN_BUF_AVAIL(upd); - } while (todo && avail); - return size - todo; -} - -/* - * we write to our peer's buf. when we connected we ref'd this peer so we - * are safe that the buffer remains, even after the peer has disconnected, - * which we check other ways. - */ -static int -unix_proto_write(struct socket *sock, char *ubuf, int size, int nonblock) -{ - struct unix_proto_data *pupd; - int todo, space; - - if ((todo = size) <= 0) - return 0; - if (sock->state != SS_CONNECTED) { - PRINTK("unix_proto_write: socket not connected\n"); - if (sock->state == SS_DISCONNECTING) { - send_sig(SIGPIPE,current,1); - return -EINTR; - } - return -EINVAL; - } - pupd = UN_DATA(sock)->peerupd; /* safer than sock->conn */ - - while (!(space = UN_BUF_SPACE(pupd))) { - PRINTK("unix_proto_write: no space left...\n"); - if (nonblock) - return -EAGAIN; - interruptible_sleep_on(sock->wait); - if (current->signal & ~current->blocked) { - PRINTK("unix_proto_write: interrupted\n"); - return -ERESTARTSYS; - } - if (sock->state == SS_DISCONNECTING) { - PRINTK("unix_proto_write: disconnected (SIGPIPE)\n"); - send_sig(SIGPIPE,current,1); - return -EINTR; - } - } - - /* - * copy from the user's buffer to the write buffer, watching for - * wraparound. then we wake up the reader - */ - do { - int part, cando; - - if (space <= 0) { - PRINTK("unix_proto_write: SPACE IS NEGATIVE!!!\n"); - send_sig(SIGKILL,current,1); - return -EINTR; - } - - /* - * we may become disconnected inside this loop, so watch - * for it (peerupd is safe until we close) - */ - if (sock->state == SS_DISCONNECTING) { - send_sig(SIGPIPE,current,1); - return -EINTR; - } - if ((cando = todo) > space) - cando = space; - if (cando > (part = BUF_SIZE - pupd->bp_head)) - cando = part; - PRINTK("unix_proto_write: space=%d, todo=%d, cando=%d\n", - space, todo, cando); - verify_area(ubuf, cando); - memcpy_fromfs(pupd->buf + pupd->bp_head, ubuf, cando); - pupd->bp_head = (pupd->bp_head + cando) & (BUF_SIZE-1); - ubuf += cando; - todo -= cando; - if (sock->state == SS_CONNECTED) - wake_up(sock->conn->wait); - space = UN_BUF_SPACE(pupd); - } while (todo && space); - return size - todo; -} - -static int -unix_proto_select(struct socket *sock, int sel_type, select_table * wait) -{ - struct unix_proto_data *upd, *peerupd; - - if (sel_type == SEL_IN) { - upd = UN_DATA(sock); - PRINTK("unix_proto_select: there is%s data available\n", - UN_BUF_AVAIL(upd) ? "" : " no"); - if (UN_BUF_AVAIL(upd)) /* even if disconnected */ - return 1; - else if (sock->state != SS_CONNECTED) { - PRINTK("unix_proto_select: socket not connected (read EOF)\n"); - return 1; - } - select_wait(sock->wait,wait); - return 0; - } - if (sel_type == SEL_OUT) { - if (sock->state != SS_CONNECTED) { - PRINTK("unix_proto_select: socket not connected (write EOF)\n"); - return 1; - } - peerupd = UN_DATA(sock->conn); - PRINTK("unix_proto_select: there is%s space available\n", - UN_BUF_SPACE(peerupd) ? "" : " no"); - if (UN_BUF_SPACE(peerupd) > 0) - return 1; - select_wait(sock->wait,wait); - return 0; - } - /* SEL_EX */ - PRINTK("unix_proto_select: there are no exceptions here?!\n"); - return 0; -} - -static int -unix_proto_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - struct unix_proto_data *upd, *peerupd; - - upd = UN_DATA(sock); - peerupd = (sock->state == SS_CONNECTED) ? UN_DATA(sock->conn) : NULL; - - switch (cmd) { - case TIOCINQ: - verify_area((void *)arg, sizeof(unsigned long)); - if (UN_BUF_AVAIL(upd) || peerupd) - put_fs_long(UN_BUF_AVAIL(upd), (unsigned long *)arg); - else - put_fs_long(1, (unsigned long *)arg); /* read EOF */ - break; - - case TIOCOUTQ: - verify_area((void *)arg, sizeof(unsigned long)); - if (peerupd) - put_fs_long(UN_BUF_SPACE(peerupd), - (unsigned long *)arg); - else - put_fs_long(0, (unsigned long *)arg); - break; - - default: - return -EINVAL; - } - return 0; -} - -static int -unix_proto_init(void) -{ - struct unix_proto_data *upd; - - PRINTK("unix_proto_init: initializing...\n"); - for (upd = unix_datas; upd <= last_unix_data; ++upd) - upd->refcnt = 0; - return 0; -} diff --git a/tools/build.c b/tools/build.c index 24ab2162dfb3..1fa477bad97a 100644 --- a/tools/build.c +++ b/tools/build.c @@ -32,7 +32,7 @@ #define MINIX_HEADER 32 #define GCC_HEADER 1024 -#define SYS_SIZE 0x5000 +#define SYS_SIZE 0x4000 #define DEFAULT_MAJOR_ROOT 0 #define DEFAULT_MINOR_ROOT 0 @@ -81,7 +81,7 @@ int main(int argc, char ** argv) } fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root); if ((major_root != 2) && (major_root != 3) && - (major_root != 8) && (major_root != 0)) { + (major_root != 0)) { fprintf(stderr, "Illegal root device (major = %d)\n", major_root); die("Bad root device --- major #"); -- 2.39.5