Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Linux Kernel Patch v2.1, patch-2.1.44 (00/47)

2 views
Skip to first unread message

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part00

lines added deleted
linux/CREDITS : 10 2 1
linux/Documentation/Configure.help : 79 40 5
linux/Documentation/binfmt_misc.txt : 45 10 8
linux/Documentation/ioctl-number.txt : 7 1 0
linux/Documentation/m68k/amiboot.txt : 20 3 3
linux/Documentation/networking/README.cops : 39 39 0
linux/Documentation/networking/ax25.txt : 13 2 2
linux/Documentation/networking/net-modules.txt : 13 7 0
linux/Documentation/networking/x25.txt : 5 0 1
linux/MAINTAINERS : 13 7 0
linux/Makefile : 7 1 1
linux/arch/alpha/defconfig : 42 11 7
linux/arch/alpha/kernel/osf_sys.c : 27 5 2
linux/arch/i386/boot/compressed/Makefile : 8 1 1
linux/arch/i386/defconfig : 32 6 5
linux/arch/i386/kernel/entry.S : 9 3 1
linux/arch/i386/kernel/irq.c : 23 3 2
linux/arch/i386/kernel/setup.c : 8 1 1
linux/arch/m68k/amiga/amifb.c : 19 0 6
linux/arch/m68k/amiga/config.c : 34 13 8
linux/arch/m68k/amiga/cyberfb.c : 8 1 1
linux/arch/m68k/atari/atakeyb.c : 8 1 1
linux/arch/m68k/boot/amiga/bootstrap.c : 13 3 1
linux/arch/m68k/boot/amiga/linuxboot.c : 140 28 25
linux/arch/m68k/config.in : 25 6 0
linux/arch/m68k/console/fbcon.c : 59 13 11
linux/arch/m68k/defconfig : 9 3 0
linux/arch/m68k/ifpsp060/iskeleton.S : 37 3 21
linux/arch/m68k/kernel/console.c : 20 4 0
linux/arch/m68k/mm/memory.c : 49 19 3
linux/arch/mips/Makefile : 207 117 39
linux/arch/mips/boot/Makefile : 61 14 29
linux/arch/mips/boot/mkboot.c : 659 659 0
linux/arch/mips/config.in : 255 146 48
linux/arch/mips/dec/Makefile : 24 24 0
linux/arch/mips/dec/boot.S : 92 92 0
linux/arch/mips/dec/decstation.S : 369 369 0
linux/arch/mips/dec/decstation.c : 200 200 0
linux/arch/mips/dec/hw-access.c : 26 26 0
linux/arch/mips/dec/int-handler.S : 260 260 0
linux/arch/mips/dec/ld.script : 47 47 0
linux/arch/mips/dec/reset.c : 28 28 0
linux/arch/mips/dec/setup.c : 50 50 0
linux/arch/mips/defconfig : 228 143 26
linux/arch/mips/deskstation/Makefile : 22 22 0
linux/arch/mips/deskstation/hw-access.c : 196 196 0
linux/arch/mips/deskstation/int-handler.S : 111 111 0
linux/arch/mips/deskstation/io.c : 68 68 0
linux/arch/mips/deskstation/reset.c : 29 29 0
linux/arch/mips/deskstation/setup.c : 110 110 0
linux/arch/mips/jazz/Makefile : 26 26 0
linux/arch/mips/jazz/g364.c : 418 418 0
linux/arch/mips/jazz/g364.fnt : 4097 4097 0
linux/arch/mips/jazz/hw-access.c : 148 148 0
linux/arch/mips/jazz/int-handler.S : 356 356 0
linux/arch/mips/jazz/io.c : 136 136 0
linux/arch/mips/jazz/jazzdma.c : 515 515 0
linux/arch/mips/jazz/reset.c : 24 24 0
linux/arch/mips/jazz/setup.c : 73 73 0
linux/arch/mips/kernel/Makefile : 123 37 55
linux/arch/mips/kernel/bios32.c : 7 0 7
linux/arch/mips/kernel/branch.c : 196 196 0
linux/arch/mips/kernel/entry.S : 414 129 158
linux/arch/mips/kernel/gdb-low.S : 82 14 8
linux/arch/mips/kernel/gdb-stub.c : 52 12 3
linux/arch/mips/kernel/head.S : 970 633 262
linux/arch/mips/kernel/init_task.c : 22 22 0
linux/arch/mips/kernel/ioport.c : 8 0 2
linux/arch/mips/kernel/ipc.c : 90 14 22
linux/arch/mips/kernel/irix5sys.h : 1024 1024 0
linux/arch/mips/kernel/irixelf.c : 1366 1366 0
linux/arch/mips/kernel/irixioctl.c : 257 257 0
linux/arch/mips/kernel/irixsig.c : 902 902 0
linux/arch/mips/kernel/irq.c : 532 164 217
linux/arch/mips/kernel/jazz-c.c : 99 0 99
linux/arch/mips/kernel/jazzdma.c : 513 0 513
linux/arch/mips/kernel/magnum4000.S : 275 0 275
linux/arch/mips/kernel/mips_ksyms.c : 44 44 0
linux/arch/mips/kernel/pci.c : 180 180 0
linux/arch/mips/kernel/pica.S : 268 0 268
linux/arch/mips/kernel/proc.c : 62 62 0
linux/arch/mips/kernel/process.c : 253 66 119
linux/arch/mips/kernel/ptrace.c : 661 225 238
linux/arch/mips/kernel/r2300_fpu.S : 140 140 0
linux/arch/mips/kernel/r2300_misc.S : 397 397 0
linux/arch/mips/kernel/r2300_scall.S : 84 84 0
linux/arch/mips/kernel/r2300_switch.S : 100 100 0
linux/arch/mips/kernel/r4k_fpu.S : 150 150 0
linux/arch/mips/kernel/r4k_misc.S : 189 189 0
linux/arch/mips/kernel/r4k_scall.S : 72 72 0
linux/arch/mips/kernel/r4k_switch.S : 68 68 0
linux/arch/mips/kernel/r4xx0.S : 829 0 829
linux/arch/mips/kernel/r6000_fpu.S : 102 102 0
linux/arch/mips/kernel/reset.c : 30 30 0
linux/arch/mips/kernel/setup.c : 491 143 247
linux/arch/mips/kernel/signal.c : 531 196 180
linux/arch/mips/kernel/syscall.c : 455 207 78
linux/arch/mips/kernel/syscalls.h : 75 39 6
linux/arch/mips/kernel/sysirix.c : 2307 2307 0
linux/arch/mips/kernel/sysmips.c : 116 34 26
linux/arch/mips/kernel/time.c : 208 90 26
linux/arch/mips/kernel/traps.c : 730 354 162
linux/arch/mips/kernel/tyne-c.c : 122 0 122
linux/arch/mips/kernel/tyne.S : 128 0 128
linux/arch/mips/kernel/unaligned.c : 467 467 0
linux/arch/mips/kernel/vm86.c : 10 1 2
linux/arch/mips/ld.script : 106 0 106
linux/arch/mips/ld.script.big : 106 106 0
linux/arch/mips/ld.script.little : 106 106 0
linux/arch/mips/lib/Makefile : 24 8 4
linux/arch/mips/lib/checksum.c : 225 91 108
linux/arch/mips/lib/copy_user.S : 207 207 0
linux/arch/mips/lib/csum.S : 25 25 0
linux/arch/mips/lib/dump_tlb.c : 148 148 0
linux/arch/mips/lib/io.c : 24 24 0
linux/arch/mips/lib/memcpy.S : 221 221 0
linux/arch/mips/lib/memset.c : 71 71 0
linux/arch/mips/lib/pmaxcon.c : 150 150 0
linux/arch/mips/lib/pmaxio.S : 40 40 0
linux/arch/mips/lib/strlen_user.S : 33 33 0
linux/arch/mips/lib/strncpy_user.S : 48 48 0
linux/arch/mips/lib/tags.c : 75 75 0
linux/arch/mips/lib/tinycon.c : 133 133 0
linux/arch/mips/lib/watch.S : 125 125 0
linux/arch/mips/mm/Makefile : 8 2 1
linux/arch/mips/mm/andes.c : 101 101 0
linux/arch/mips/mm/extable.c : 54 54 0
linux/arch/mips/mm/fault.c : 123 56 16
linux/arch/mips/mm/init.c : 298 90 86
linux/arch/mips/mm/loadmmu.c : 104 104 0
linux/arch/mips/mm/r2300.c : 272 272 0
linux/arch/mips/mm/r4xx0.c : 2583 2583 0
linux/arch/mips/mm/r6000.c : 181 181 0
linux/arch/mips/mm/tfp.c : 102 102 0
linux/arch/mips/sgi/kernel/Makefile : 30 30 0
linux/arch/mips/sgi/kernel/indyIRQ.S : 129 129 0
linux/arch/mips/sgi/kernel/indy_hpc.c : 114 114 0
linux/arch/mips/sgi/kernel/indy_int.c : 599 599 0
linux/arch/mips/sgi/kernel/indy_mc.c : 153 153 0
linux/arch/mips/sgi/kernel/indy_timer.c : 299 299 0
linux/arch/mips/sgi/kernel/reset.c : 25 25 0
linux/arch/mips/sgi/kernel/setup.c : 89 89 0
linux/arch/mips/sgi/kernel/system.c : 174 174 0
linux/arch/mips/sgi/kernel/time.c : 14 14 0
linux/arch/mips/sgi/prom/Makefile : 23 23 0
linux/arch/mips/sgi/prom/cmdline.c : 60 60 0
linux/arch/mips/sgi/prom/console.c : 24 24 0
linux/arch/mips/sgi/prom/env.c : 20 20 0
linux/arch/mips/sgi/prom/file.c : 58 58 0
linux/arch/mips/sgi/prom/init.c : 59 59 0
linux/arch/mips/sgi/prom/memory.c : 129 129 0
linux/arch/mips/sgi/prom/misc.c : 119 119 0
linux/arch/mips/sgi/prom/printf.c : 34 34 0
linux/arch/mips/sgi/prom/salone.c : 24 24 0
linux/arch/mips/sgi/prom/tags.c : 67 67 0
linux/arch/mips/sgi/prom/time.c : 17 17 0
linux/arch/mips/sgi/prom/tree.c : 107 107 0
linux/arch/mips/sni/Makefile : 22 22 0
linux/arch/mips/sni/hw-access.c : 159 159 0
linux/arch/mips/sni/int-handler.S : 174 174 0
linux/arch/mips/sni/io.c : 172 172 0
linux/arch/mips/sni/pci.c : 135 135 0
linux/arch/mips/sni/reset.c : 51 51 0
linux/arch/mips/sni/setup.c : 158 158 0
linux/arch/mips/tools/Makefile : 26 26 0
linux/arch/mips/tools/offset.c : 147 147 0
linux/arch/sparc/config.in : 5 1 1
linux/arch/sparc/defconfig : 15 2 0
linux/arch/sparc/kernel/cpu.c : 7 1 0
linux/arch/sparc/kernel/sparc_ksyms.c : 22 3 2
linux/arch/sparc/mm/Makefile : 35 9 2
linux/arch/sparc/mm/srmmu.c : 132 99 1
linux/arch/sparc/mm/turbosparc.S : 46 46 0
linux/arch/sparc/prom/bootstr.c : 24 6 5
linux/arch/sparc/prom/tree.c : 32 4 4
linux/arch/sparc64/Makefile : 16 3 3
linux/arch/sparc64/config.in : 23 3 2
linux/arch/sparc64/defconfig : 151 41 17
linux/arch/sparc64/kernel/Makefile : 37 12 6
linux/arch/sparc64/kernel/binfmt_aout32.c : 477 477 0
linux/arch/sparc64/kernel/binfmt_elf32.c : 8 2 0
linux/arch/sparc64/kernel/cpu.c : 33 14 3
linux/arch/sparc64/kernel/devices.c : 25 2 3
linux/arch/sparc64/kernel/dtlb_miss.S : 64 18 15
linux/arch/sparc64/kernel/entry.S : 705 341 209
linux/arch/sparc64/kernel/etrap.S : 212 119 86
linux/arch/sparc64/kernel/hack.S : 170 0 170
linux/arch/sparc64/kernel/head.S : 422 130 125
linux/arch/sparc64/kernel/ioctl32.c : 236 187 1
linux/arch/sparc64/kernel/ioport.c : 30 5 8
linux/arch/sparc64/kernel/irq.c : 59 23 6
linux/arch/sparc64/kernel/process.c : 429 95 175
linux/arch/sparc64/kernel/ptrace.c : 436 210 162
linux/arch/sparc64/kernel/rtrap.S : 246 120 117
linux/arch/sparc64/kernel/setup.c : 84 8 29
linux/arch/sparc64/kernel/signal.c : 349 171 66
linux/arch/sparc64/kernel/signal32.c : 290 67 69
linux/arch/sparc64/kernel/sparc64_ksyms.c : 68 8 11
linux/arch/sparc64/kernel/sunos_ioctl32.c : 276 276 0
linux/arch/sparc64/kernel/sys32.S : 427 427 0
linux/arch/sparc64/kernel/sys_sparc.c : 13 1 2
linux/arch/sparc64/kernel/sys_sparc32.c : 1162 391 563
linux/arch/sparc64/kernel/sys_sunos32.c : 1468 1468 0
linux/arch/sparc64/kernel/systbls.S : 199 60 60
linux/arch/sparc64/kernel/time.c : 26 5 4
linux/arch/sparc64/kernel/traps.c : 526 172 224
linux/arch/sparc64/kernel/ttable.S : 45 12 4
linux/arch/sparc64/kernel/unaligned.c : 517 517 0
linux/arch/sparc64/kernel/winfixup.S : 217 61 58
linux/arch/sparc64/lib/Makefile : 64 9 39
linux/arch/sparc64/lib/VIS.h : 113 113 0
linux/arch/sparc64/lib/VISbzero.S : 246 246 0
linux/arch/sparc64/lib/VIScopy.S : 1052 1052 0
linux/arch/sparc64/lib/VISmemset.S : 228 228 0
linux/arch/sparc64/lib/blockops.S : 198 60 128
linux/arch/sparc64/lib/checksum.S : 1157 606 480
linux/arch/sparc64/lib/copy_from_user.S : 469 0 469
linux/arch/sparc64/lib/copy_to_user.S : 469 0 469
linux/arch/sparc64/lib/memcpy.S : 526 0 526
linux/arch/sparc64/lib/memset.S : 196 0 196
linux/arch/sparc64/mm/Makefile : 20 8 2
linux/arch/sparc64/mm/fault.c : 185 95 66
linux/arch/sparc64/mm/generic.c : 47 29 7
linux/arch/sparc64/mm/init.c : 396 134 101
linux/arch/sparc64/mm/modutil.c : 66 66 0
linux/arch/sparc64/mm/ultra.S : 101 101 0
linux/arch/sparc64/prom/bootstr.c : 34 11 9
linux/arch/sparc64/prom/misc.c : 24 4 3
linux/arch/sparc64/prom/p1275.c : 181 36 48
linux/arch/sparc64/vmlinux.lds : 26 3 9
linux/drivers/block/floppy.c : 8 2 0
linux/drivers/block/ide.c : 7 1 0
linux/drivers/block/ide.h : 8 1 1
linux/drivers/block/triton.c : 180 88 26
linux/drivers/char/ChangeLog : 27 24 0
linux/drivers/char/console.c : 130 31 27
linux/drivers/char/n_tty.c : 111 80 1
linux/drivers/char/psaux.c : 11 4 1
linux/drivers/char/pty.c : 156 56 41
linux/drivers/char/random.c : 221 107 38
linux/drivers/char/rtc.c : 17 2 2
linux/drivers/char/serial.c : 60 40 0
linux/drivers/char/sysrq.c : 16 2 2
linux/drivers/char/tty_io.c : 755 340 230
linux/drivers/char/vc_screen.c : 11 5 0
linux/drivers/isdn/avmb1/capiutil.c : 7 1 0
linux/drivers/isdn/sc/Makefile : 6 1 1
linux/drivers/net/Config.in : 23 9 1
linux/drivers/net/Makefile : 40 20 0
linux/drivers/net/Space.c : 55 20 1
linux/drivers/net/cops.c : 1017 1017 0
linux/drivers/net/cops.h : 60 60 0
linux/drivers/net/cops_ffdrv.h : 533 533 0
linux/drivers/net/cops_ltdrv.h : 242 242 0
linux/drivers/net/lapbether.c : 8 1 1
linux/drivers/net/sgiseeq.c : 737 737 0
linux/drivers/net/sgiseeq.h : 103 103 0
linux/drivers/net/sonic.c : 890 890 0
linux/drivers/net/sonic.h : 326 326 0
linux/drivers/pci/pci.c : 8 1 1
linux/drivers/pnp/parport_procfs.c : 7 0 1
linux/drivers/sbus/char/bwtwo.c : 15 3 2
linux/drivers/sbus/char/cgfourteen.c : 14 2 2
linux/drivers/sbus/char/cgsix.c : 104 45 9
linux/drivers/sbus/char/cgthree.c : 14 2 2
linux/drivers/sbus/char/fb.h : 14 2 2
linux/drivers/sbus/char/leo.c : 14 2 2
linux/drivers/sbus/char/openprom.c : 44 5 5
linux/drivers/sbus/char/suncons.c : 92 28 24
linux/drivers/sbus/char/sunfb.c : 58 9 8
linux/drivers/sbus/char/sunkbd.c : 69 11 9
linux/drivers/sbus/char/sunmouse.c : 8 1 1
linux/drivers/sbus/char/sunserial.c : 54 8 3
linux/drivers/sbus/char/tcx.c : 15 3 2
linux/drivers/sbus/char/weitek.c : 14 2 2
linux/drivers/scsi/BusLogic.h : 8 2 0
linux/drivers/scsi/amiga7xx.c : 39 6 7
linux/drivers/scsi/ppa.c : 8 2 0
linux/drivers/scsi/sr_ioctl.c : 4 1 0
linux/drivers/sound/dev_table.h : 7 1 0
linux/fs/affs/namei.c : 14 2 2
linux/fs/autofs/autofs_i.h : 40 4 7
linux/fs/autofs/dir.c : 28 4 17
linux/fs/autofs/dirhash.c : 51 8 20
linux/fs/autofs/init.c : 8 1 1
linux/fs/autofs/inode.c : 49 8 7
linux/fs/autofs/root.c : 322 61 98
linux/fs/autofs/symlink.c : 34 9 5
linux/fs/autofs/waitq.c : 41 8 8
linux/fs/binfmt_elf.c : 58 17 20
linux/fs/binfmt_misc.c : 146 15 30
linux/fs/buffer.c : 51 16 13
linux/fs/dcache.c : 1200 192 822
linux/fs/dquot.c : 8 1 1
linux/fs/ext2/balloc.c : 26 1 5
linux/fs/ext2/dir.c : 7 1 0
linux/fs/ext2/file.c : 7 1 0
linux/fs/ext2/namei.c : 647 115 208
linux/fs/ext2/super.c : 9 2 1
linux/fs/ext2/symlink.c : 78 30 5
linux/fs/fat/misc.c : 34 11 10
linux/fs/inode.c : 474 72 152
linux/fs/minix/namei.c : 17 2 2
linux/fs/namei.c : 1773 579 921
linux/fs/ncpfs/inode.c : 8 1 1
linux/fs/nfs/dir.c : 720 155 383
linux/fs/nfs/file.c : 7 1 0
linux/fs/nfs/inode.c : 27 3 4
linux/fs/nfs/symlink.c : 61 35 1
linux/fs/open.c : 204 74 35
linux/fs/proc/arbitrary.c : 6 0 1
linux/fs/proc/array.c : 15 2 0
linux/fs/proc/base.c : 7 1 0
linux/fs/proc/fd.c : 62 9 20
linux/fs/proc/generic.c : 31 11 0
linux/fs/proc/inode.c : 15 3 2
linux/fs/proc/kmsg.c : 7 1 0
linux/fs/proc/link.c : 170 51 63
linux/fs/proc/mem.c : 7 1 0
linux/fs/proc/net.c : 7 1 0
linux/fs/proc/omirr.c : 7 1 0
linux/fs/proc/openpromfs.c : 23 3 0
linux/fs/proc/procfs_syms.c : 8 1 1
linux/fs/proc/root.c : 243 41 83
linux/fs/proc/scsi.c : 7 1 0
linux/fs/readdir.c : 266 20 153
linux/fs/romfs/inode.c : 8 1 1
linux/fs/smbfs/inode.c : 8 1 1
linux/fs/stat.c : 64 10 11
linux/fs/super.c : 281 70 82
linux/include/asm-alpha/ioctls.h : 8 2 0
linux/include/asm-alpha/pgtable.h : 7 3 0
linux/include/asm-i386/ioctls.h : 9 3 0
linux/include/asm-i386/pgtable.h : 7 3 0
linux/include/asm-i386/unistd.h : 8 2 0
linux/include/asm-m68k/hardirq.h : 6 2 0
linux/include/asm-m68k/ioctls.h : 9 3 0
linux/include/asm-m68k/pgtable.h : 51 7 19
linux/include/asm-mips/addrspace.h : 52 52 0
linux/include/asm-mips/asm.h : 489 258 132
linux/include/asm-mips/asmmacro.h : 115 115 0
linux/include/asm-mips/atomic.h : 190 190 0
linux/include/asm-mips/bitops.h : 598 370 75
linux/include/asm-mips/bootinfo.h : 464 232 168
linux/include/asm-mips/branch.h : 26 26 0
linux/include/asm-mips/bugs.h : 17 3 2
linux/include/asm-mips/byteorder.h : 242 151 67
linux/include/asm-mips/cache.h : 15 3 3
linux/include/asm-mips/cachectl.h : 44 7 20
linux/include/asm-mips/cacheops.h : 47 47 0
linux/include/asm-mips/checksum.h : 244 82 90
linux/include/asm-mips/cpu.h : 40 40 0
linux/include/asm-mips/current.h : 57 45 9
linux/include/asm-mips/decstation.h : 254 254 0
linux/include/asm-mips/delay.h : 40 13 7
linux/include/asm-mips/deskstation.h : 15 15 0
linux/include/asm-mips/dma.h : 50 12 12
linux/include/asm-mips/elf.h : 48 18 8
linux/include/asm-mips/errno.h : 22 16 0
linux/include/asm-mips/fcntl.h : 13 3 3
linux/include/asm-mips/floppy.h : 89 28 16
linux/include/asm-mips/hardirq.h : 24 24 0
linux/include/asm-mips/ide.h : 119 119 0
linux/include/asm-mips/init.h : 13 3 3
linux/include/asm-mips/inst.h : 304 304 0
linux/include/asm-mips/io.h : 216 101 25
linux/include/asm-mips/ioctl.h : 12 9 0
linux/include/asm-mips/ioctls.h : 278 29 215
linux/include/asm-mips/ipc.h : 29 29 0
linux/include/asm-mips/irq.h : 13 5 1
linux/include/asm-mips/jazz.h : 133 44 38
linux/include/asm-mips/jazzdma.h : 34 6 7
linux/include/asm-mips/keyboard.h : 240 211 14
linux/include/asm-mips/mc146818rtc.h : 23 3 5
linux/include/asm-mips/mipsconfig.h : 61 9 37
linux/include/asm-mips/mipsprom.h : 74 74 0
linux/include/asm-mips/mipsregs.h : 256 147 44
linux/include/asm-mips/mman.h : 7 1 0
linux/include/asm-mips/mmu_context.h : 65 65 0
linux/include/asm-mips/namei.h : 54 54 0
linux/include/asm-mips/offset.h : 104 104 0
linux/include/asm-mips/page.h : 80 18 36
linux/include/asm-mips/pci.h : 39 39 0
linux/include/asm-mips/pgtable.h : 983 458 257
linux/include/asm-mips/poll.h : 26 26 0
linux/include/asm-mips/posix_types.h : 117 117 0
linux/include/asm-mips/processor.h : 251 72 104
linux/include/asm-mips/ptrace.h : 95 23 35
linux/include/asm-mips/r4kcache.h : 1026 1026 0
linux/include/asm-mips/reboot.h : 17 17 0
linux/include/asm-mips/reg.h : 112 42 52
linux/include/asm-mips/resource.h : 39 12 13
linux/include/asm-mips/scatterlist.h : 13 3 3
linux/include/asm-mips/segment.h : 192 4 186
linux/include/asm-mips/semaphore.h : 84 84 0
linux/include/asm-mips/sgi.h : 42 42 0
linux/include/asm-mips/sgialib.h : 118 118 0
linux/include/asm-mips/sgiarcs.h : 351 351 0
linux/include/asm-mips/sgidefs.h : 100 100 0
linux/include/asm-mips/sgihpc.h : 340 340 0
linux/include/asm-mips/sgimc.h : 223 223 0
linux/include/asm-mips/sgint23.h : 179 179 0
linux/include/asm-mips/shmparam.h : 8 1 1
linux/include/asm-mips/sigcontext.h : 50 29 11
linux/include/asm-mips/signal.h : 153 76 26
linux/include/asm-mips/slots.h : 17 0 17
linux/include/asm-mips/smp.h : 6 6 0
linux/include/asm-mips/smp_lock.h : 26 26 0
linux/include/asm-mips/sni.h : 91 91 0
linux/include/asm-mips/socket.h : 103 42 38
linux/include/asm-mips/sockios.h : 25 25 0
linux/include/asm-mips/softirq.h : 93 93 0
linux/include/asm-mips/spinlock.h : 54 54 0
linux/include/asm-mips/stackframe.h : 308 119 169
linux/include/asm-mips/stat.h : 17 2 2
linux/include/asm-mips/statfs.h : 53 28 13
linux/include/asm-mips/string.h : 246 44 113
linux/include/asm-mips/sysmips.h : 7 1 0
linux/include/asm-mips/system.h : 272 115 71
linux/include/asm-mips/termbits.h : 215 184 13
linux/include/asm-mips/termios.h : 139 90 8
linux/include/asm-mips/types.h : 105 2 87
linux/include/asm-mips/uaccess.h : 386 386 0
linux/include/asm-mips/unaligned.h : 101 101 0
linux/include/asm-mips/unistd.h : 192 116 16
linux/include/asm-mips/user.h : 19 3 3
linux/include/asm-mips/vector.h : 57 12 19
linux/include/asm-mips/watch.h : 38 38 0
linux/include/asm-ppc/ioctls.h : 8 2 0
linux/include/asm-ppc/pgtable.h : 7 3 0
linux/include/asm-sparc/asi.h : 23 3 3
linux/include/asm-sparc/ioctls.h : 10 2 2
linux/include/asm-sparc/mbus.h : 23 4 2
linux/include/asm-sparc/oplib.h : 20 3 3
linux/include/asm-sparc/pgtable.h : 23 5 2
linux/include/asm-sparc/turbosparc.h : 114 114 0
linux/include/asm-sparc64/asm_offsets.h : 116 35 45
linux/include/asm-sparc64/atomic.h : 120 38 48
linux/include/asm-sparc64/bitops.h : 72 9 23
linux/include/asm-sparc64/byteorder.h : 36 10 4
linux/include/asm-sparc64/checksum.h : 61 25 26
linux/include/asm-sparc64/delay.h : 16 4 2
linux/include/asm-sparc64/elf.h : 15 3 1
linux/include/asm-sparc64/fbio.h : 18 0 5
linux/include/asm-sparc64/fpumacro.h : 90 22 46
linux/include/asm-sparc64/fs_mount.h : 44 0 44
linux/include/asm-sparc64/head.h : 111 36 33
linux/include/asm-sparc64/ioctls.h : 35 4 9
linux/include/asm-sparc64/mmu_context.h : 88 22 47
linux/include/asm-sparc64/page.h : 35 12 5
linux/include/asm-sparc64/pgtable.h : 480 78 218
linux/include/asm-sparc64/processor.h : 127 25 45
linux/include/asm-sparc64/psrcompat.h : 45 7 21
linux/include/asm-sparc64/pstate.h : 25 7 1
linux/include/asm-sparc64/ptrace.h : 52 26 2
linux/include/asm-sparc64/reg.h : 40 30 1
linux/include/asm-sparc64/resource.h : 13 1 2
linux/include/asm-sparc64/sigcontext.h : 60 8 23
linux/include/asm-sparc64/string.h : 85 23 20
linux/include/asm-sparc64/system.h : 117 17 46
linux/include/asm-sparc64/uaccess.h : 123 61 32
linux/include/asm-sparc64/uctx.h : 71 71 0
linux/include/asm-sparc64/unistd.h : 97 20 18
linux/include/asm-sparc64/vaddrs.h : 27 10 7
linux/include/linux/binfmts.h : 7 1 0
linux/include/linux/console_struct.h : 27 8 1
linux/include/linux/dalloc.h : 172 84 41
linux/include/linux/ext2_fs.h : 26 9 11
linux/include/linux/fs.h : 232 41 75
linux/include/linux/ghash.h : 218 218 0
linux/include/linux/if_arp.h : 8 2 0
linux/include/linux/net.h : 8 3 0
linux/include/linux/pci.h : 8 1 1
linux/include/linux/proc_fs.h : 37 4 6
linux/include/linux/random.h : 8 2 0
linux/include/linux/rose.h : 45 22 1
linux/include/linux/sched.h : 24 4 6
linux/include/linux/selection.h : 22 4 2
linux/include/linux/simp.h : 39 39 0
linux/include/linux/slab.h : 17 2 2
linux/include/linux/sysctl.h : 7 1 0
linux/include/linux/tty.h : 30 9 3
linux/include/linux/x25.h : 66 10 32
linux/include/net/ax25.h : 130 37 22
linux/include/net/lapb.h : 52 10 10
linux/include/net/netrom.h : 91 30 17
linux/include/net/rose.h : 132 41 24
linux/include/net/tcp.h : 61 15 6
linux/include/net/x25.h : 83 21 14
linux/kernel/exit.c : 10 2 2
linux/kernel/fork.c : 12 2 4
linux/kernel/ksyms.c : 12 3 2
linux/kernel/module.c : 47 8 4
linux/kernel/sys.c : 93 56 16
linux/kernel/sysctl.c : 7 1 0
linux/mm/mmap.c : 8 2 0
linux/mm/slab.c : 185 33 33
linux/mm/swapfile.c : 23 2 5
linux/mm/vmalloc.c : 35 4 4
linux/net/Makefile : 9 0 3
linux/net/README : 24 5 5
linux/net/appletalk/ddp.c : 50 28 2
linux/net/ax25/af_ax25.c : 645 145 163
linux/net/ax25/ax25_addr.c : 93 20 26
linux/net/ax25/ax25_dev.c : 6 1 1
linux/net/ax25/ax25_ds_in.c : 171 18 68
linux/net/ax25/ax25_ds_subr.c : 46 8 6
linux/net/ax25/ax25_ds_timer.c : 247 51 119
linux/net/ax25/ax25_iface.c : 57 6 15
linux/net/ax25/ax25_in.c : 66 7 10
linux/net/ax25/ax25_ip.c : 70 20 11
linux/net/ax25/ax25_out.c : 263 72 80
linux/net/ax25/ax25_route.c : 139 22 58
linux/net/ax25/ax25_std_in.c : 268 32 100
linux/net/ax25/ax25_std_subr.c : 39 9 5
linux/net/ax25/ax25_std_timer.c : 205 49 90
linux/net/ax25/ax25_subr.c : 72 29 5
linux/net/ax25/ax25_timer.c : 241 180 22
linux/net/ax25/ax25_uid.c : 6 1 1
linux/net/ax25/sysctl_net_ax25.c : 19 5 5
linux/net/core/sysctl_net_core.c : 14 4 0
linux/net/ipv4/Config.in : 7 1 0
linux/net/ipv4/Makefile : 11 5 0
linux/net/ipv4/raw.c : 8 1 1
linux/net/ipv4/route.c : 40 5 4
linux/net/ipv4/syncookies.c : 218 218 0
linux/net/ipv4/sysctl_net_ipv4.c : 24 5 3
linux/net/ipv4/tcp_input.c : 141 20 15
linux/net/ipv4/tcp_ipv4.c : 371 131 63
linux/net/ipv4/utils.c : 33 22 1
linux/net/ipv6/icmp.c : 33 18 2
linux/net/ipv6/tcp_ipv6.c : 135 30 24
linux/net/lapb/lapb_iface.c : 145 29 26
linux/net/lapb/lapb_in.c : 274 55 55
linux/net/lapb/lapb_out.c : 66 8 14
linux/net/lapb/lapb_subr.c : 19 1 7
linux/net/lapb/lapb_timer.c : 203 53 68
linux/net/netrom/af_netrom.c : 411 96 88
linux/net/netrom/nr_dev.c : 6 1 1
linux/net/netrom/nr_in.c : 157 16 44
linux/net/netrom/nr_out.c : 183 53 51
linux/net/netrom/nr_route.c : 93 15 12
linux/net/netrom/nr_subr.c : 51 24 2
linux/net/netrom/nr_timer.c : 282 141 67
linux/net/netrom/sysctl_net_netrom.c : 24 8 8
linux/net/rose/af_rose.c : 503 135 89
linux/net/rose/rose_dev.c : 15 2 2
linux/net/rose/rose_in.c : 230 49 46
linux/net/rose/rose_link.c : 198 62 49
linux/net/rose/rose_out.c : 106 33 25
linux/net/rose/rose_route.c : 372 118 44
linux/net/rose/rose_subr.c : 124 35 21
linux/net/rose/rose_timer.c : 233 120 52
linux/net/rose/sysctl_net_rose.c : 19 6 6
linux/net/socket.c : 15 2 0
linux/net/unix/af_unix.c : 8 1 1
linux/net/unix/sysctl_net_unix.c : 14 4 0
linux/net/x25/af_x25.c : 365 84 84
linux/net/x25/sysctl_net_x25.c : 10 2 2
linux/net/x25/x25_dev.c : 15 2 2
linux/net/x25/x25_facilities.c : 6 1 1
linux/net/x25/x25_in.c : 178 18 44
linux/net/x25/x25_link.c : 168 29 50
linux/net/x25/x25_out.c : 95 28 24
linux/net/x25/x25_route.c : 45 7 9
linux/net/x25/x25_subr.c : 42 23 1
linux/net/x25/x25_timer.c : 196 87 47
linux/scripts/ksymoops.cc : 65 29 5
--
Thomas Koenig, Thomas...@ciw.uni-karlsruhe.de, ig...@dkauni2.bitnet.
The joy of engineering is to find a straight line on a double
logarithmic diagram.

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part02

#!/bin/sh
# this is part 02 of a 47 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 02; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&
+ if (ph[i].p_type != PT_LOAD) {
+ continue;
+ }
+ printf(" Offset: %08lx\n", ph[i].p_offset);
+ printf(" file size: %08lx\n", ph[i].p_filesz);
+ printf(" mem size: %08lx\n", ph[i].p_memsz);
+ printf(" Loading: %08lx - %08lx\n",
+ ph[i].p_vaddr, ph[i].p_vaddr + ph[i].p_filesz);
+ printf(" Zero mapping: %08lx - %08lx\n",
+ ph[i].p_vaddr + ph[i].p_filesz,
+ ph[i].p_vaddr + ph[i].p_memsz);
+ }
+#endif
+
+ /*
+ * Time to open the outputfile.
+ */
+ ofd = open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ if (ofd == -1) {
+ perror("Can't open boot image for output.");
+ exit(1);
+ }
+
+ /*
+ * First compute the layout of the file. We need to do this
+ * first because we can't seek back to the beginning due to the
+ * broken Seek() call in the Magnum firmware.
+ */
+ entry = vaddr = 0xffffffff;
+ bss = 0;
+ for(i = 0;i < eh.e_phnum; i++) {
+ if (ph[i].p_type != PT_LOAD)
+ continue;
+ if (vaddr == 0xffffffff)
+ entry = vaddr = ph[i].p_vaddr;
+ vaddr = ph[i].p_vaddr + ph[i].p_filesz;
+ bss = ph[i].p_memsz - ph[i].p_filesz;
+ }
+
+ /*
+ * In the next step we construct the boot image. The boot file
+ * looks essentially like a dump of the loaded kernel with a
+ * minimal header. Because Milo supports already a.out image
+ * we simply dump the image in an a.out image ... First let's
+ * write the header.
+ */
+
+ /*
+ * Create and write the a.out header.
+ */
+ put_word(ahdr, AOUT_INFO(OMAGIC, M_MIPS1, 0));
+ put_word(ahdr + 4, vaddr - entry); /* text size */
+ put_word(ahdr + 8, 0); /* data size */
+ put_word(ahdr + 12, bss); /* bss size */
+ put_word(ahdr + 16, 2 * 12); /* size of symbol table */
+ put_word(ahdr + 20, entry); /* base address */
+ put_word(ahdr + 24, 0); /* size of text relocations */
+ put_word(ahdr + 28, 0); /* size of data relocations */
+ do_write(ofd, ahdr, 32);
+
+ /*
+ * Write text and data segment combined into the a.out text segment
+ * and a zero length data segment into the file.
+ */
+ vaddr = 0xffffffff;
+ bss = 0;
+ for(i = 0;i < eh.e_phnum; i++) {
+ if (ph[i].p_type != PT_LOAD)
+ continue;
+ if (vaddr == 0xffffffff)
+ vaddr = ph[i].p_vaddr;
+ writepad(ofd, ph[i].p_vaddr - vaddr); /* Write zero pad */
+ do_write(ofd, image + ph[i].p_offset, ph[i].p_filesz);
+ vaddr = ph[i].p_vaddr + ph[i].p_filesz;
+ bss = ph[i].p_memsz - ph[i].p_filesz;
+ }
+
+ /*
+ * Now write the symbol table. It has only two symbols,
+ * kernel_entry and _end which we need for booting.
+ */
+ put_word(ahdr , 4); /* n_un.n_strx */
+ put_byte(ahdr + 4, N_TEXT | N_EXT); /* n_type */
+ put_byte(ahdr + 5, 0); /* n_other */
+ put_half(ahdr + 6, 0); /* n_desc */
+ put_word(ahdr + 8, kernel_entry); /* n_value */
+ do_write(ofd, ahdr, 12);
+
+ put_word(ahdr , 4 + 13); /* n_un.n_strx */
+ put_byte(ahdr + 4, N_ABS | N_EXT); /* n_type */
+ put_byte(ahdr + 5, 0); /* n_other */
+ put_half(ahdr + 6, 0); /* n_desc */
+ put_word(ahdr + 8, kernel_end); /* n_value */
+ do_write(ofd, ahdr, 12);
+
+ /*
+ * Now write stringtable size and the strings.
+ */
+ put_word(ahdr, 4 + 20);
+ do_write(ofd, ahdr, 4);
+ do_write(ofd, "kernel_entry\0_end\0\0", 20);
+
+ /*
+ * That's is all ...
+ */
+ close(ofd);
+
+#ifdef VERBOSE
+ printf("Entry: %08lx\n", entry);
+ printf("Dumped image %08lx - %08lx\n", 0x80000000, vaddr);
+ printf("Extra bss at end: %08lx\n", bss);
+#endif
+
+ return 0;
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/config.in linux/arch/mips/config.in
--- v2.1.43/linux/arch/mips/config.in Mon Apr 7 11:35:29 1997
+++ linux/arch/mips/config.in Thu Jun 26 12:33:36 1997
@@ -3,62 +3,102 @@
X # see the Configure script.
X #
X mainmenu_name "Linux Kernel Configuration"
-
+
X mainmenu_option next_comment
-comment 'Machine setup'
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
X
+mainmenu_option next_comment
+comment 'Machine selection'
X bool 'Support for Acer PICA 1 chipset' CONFIG_ACER_PICA_61
-bool 'Support for DECstation' CONFIG_DECSTATION
-bool 'Support for Deskstation RPC44' CONFIG_DESKSTATION_RPC44
-bool 'Support for Deskstation Tyne' CONFIG_DESKSTATION_TYNE
-bool 'Support for Mips Magnum 3000' CONFIG_MIPS_MAGNUM_3000
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ bool 'Support for Algorithmics P4032' CONFIG_ALGOR_P4032
+ bool 'Support for DECstation' CONFIG_DECSTATION
+ bool 'Support for Deskstation RPC44' CONFIG_DESKSTATION_RPC44
+ bool 'Support for Deskstation Tyne' CONFIG_DESKSTATION_TYNE
+ bool 'Support for Mips Magnum 3000' CONFIG_MIPS_MAGNUM_3000
+fi
X bool 'Support for Mips Magnum 4000' CONFIG_MIPS_MAGNUM_4000
-bool 'Support for Olivetti M700' CONFIG_OLIVETTI_M700
-if [ "$CONFIG_ACER_PICA_61" = "y" -o \
- "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
+bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700
+if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
X "$CONFIG_OLIVETTI_M700" = "y" ]; then
+ define_bool CONFIG_VIDEO_G364 y
+fi
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ bool 'Support for SGI workstations' CONFIG_SGI
+fi
+bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
+if [ "$CONFIG_DESKSTATION_RPC44" = "y" -o \
+ "$CONFIG_DESKSTATION_TYNE" = "y" ]; then
+ define_bool CONFIG_MIPS_ARC y
+fi
+if [ "$CONFIG_ACER_PICA_61" = "y" -o \
+ "$CONFIG_OLIVETTI_M700" = "y" -o \
+ "$CONFIG_MIPS_MAGNUM_4000" = "y" ]; then
X define_bool CONFIG_MIPS_JAZZ y
X fi
+unset CONFIG_PCI
+if [ "$CONFIG_SNI_RM200_PCI" = "y" -o \
+ "$CONFIG_ALGOR_P4032" = "y" ]; then
+ define_bool CONFIG_PCI y
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'CPU selection'
X
X choice 'CPU type' \
X "R3000 CONFIG_CPU_R3000 \
X R6000 CONFIG_CPU_R6000 \
+ R4300 CONFIG_CPU_R4300 \
X R4x00 CONFIG_CPU_R4X00 \
- R4600 CONFIG_CPU_R4600 \
+ R5000 CONFIG_CPU_R5000 \
X R8000 CONFIG_CPU_R8000 \
X R10000 CONFIG_CPU_R10000" R4x00
-if [ "$CONFIG_CPU_R3000" = "y" -o \
- "$CONFIG_CPU_R6000" = "y" -o \
- "$CONFIG_CPU_R4X00" = "y" -o \
- "$CONFIG_CPU_R4600" = "y" -o \
- "$CONFIG_CPU_R8000" = "y" ]; then
- define_bool CONFIG_TLB_SHUTDOWN y
-fi
+endmenu
X
+mainmenu_option next_comment
+comment 'General setup'
+if [ "$CONFIG_DECSTATION" = "y" ]; then
+ bool 'Compile the kernel into the ECOFF object format' CONFIG_ECOFF_KERNEL
+ define_bool CONFIG_CPU_LITTLE_ENDIAN y
+else
+ define_bool CONFIG_ELF_KERNEL y
+ bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
+fi
+if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
+ define_bool CONFIG_BINFMT_IRIX y
+fi
X define_bool CONFIG_BINFMT_ELF y
-define_bool CONFIG_BINFMT_AOUT y
-bool 'Compile the kernel into the ELF object format' CONFIG_ELF_KERNEL
-if [ "$CONFIG_ELF_KERNEL" = "y" ]; then
- bool 'Is your ELF compiler an extra compiler' CONFIG_EXTRA_ELF_COMPILER
+define_bool CONFIG_BINFMT_AOUT n
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
X fi
-bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
X bool 'Networking support' CONFIG_NET
-#bool 'PCI bios support' CONFIG_PCI
-#if [ "$CONFIG_PCI" = "y" ]; then
-# if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-# bool ' PCI bridge optimization (experimental)' CONFIG_PCI_OPTIMIZE
-# fi
-#fi
X bool 'System V IPC' CONFIG_SYSVIPC
X bool 'Sysctl support' CONFIG_SYSCTL
+
+if [ "$CONFIG_SGI" != "y" ]; then
+ tristate 'Parallel port support' CONFIG_PNP_PARPORT
+fi
+
X endmenu
X
X mainmenu_option next_comment
X comment 'Loadable module support'
-bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
-endmenu
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
+ bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
+fi
X
-source drivers/block/Config.in
+#
+# All SGI block devices are SCSI based AFAIK. -davem
+#
+if [ "$CONFIG_SGI" != "y" ]; then
+ source drivers/block/Config.in
+fi
X
X if [ "$CONFIG_NET" = "y" ]; then
X source net/Config.in
@@ -70,7 +110,27 @@
X tristate 'SCSI support' CONFIG_SCSI
X
X if [ "$CONFIG_SCSI" != "n" ]; then
- source drivers/scsi/Config.in
+ if [ "$CONFIG_SGI" = "y" ]; then
+ comment 'SCSI support type (disk, tape, CDrom)'
+
+ dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
+ dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
+ dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
+ dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
+
+ comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
+
+ bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
+
+ bool 'Verbose SCSI error reporting' CONFIG_SCSI_CONSTANTS
+
+ #mainmenu_option next_comment
+ comment 'SCSI low-level drivers'
+
+ dep_tristate 'SGI wd93 Scsi Driver' CONFIG_SCSI_SGIWD93 $CONFIG_SCSI
+ else
+ source drivers/scsi/Config.in
+ fi
X fi
X endmenu
X
@@ -80,38 +140,76 @@
X
X bool 'Network device support' CONFIG_NETDEVICES
X if [ "$CONFIG_NETDEVICES" = "y" ]; then
- source drivers/net/Config.in
+ if [ "$CONFIG_SGI" != "y" ]; then
+ source drivers/net/Config.in
+ else
+ tristate 'Dummy net driver support' CONFIG_DUMMY
+ tristate 'SLIP (serial line) support' CONFIG_SLIP
+ if [ "$CONFIG_SLIP" != "n" ]; then
+ bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
+ bool ' Keepalive and linefill' CONFIG_SLIP_SMART
+ fi
+ tristate 'PPP (point-to-point) support' CONFIG_PPP
+ if [ ! "$CONFIG_PPP" = "n" ]; then
+ comment 'CCP compressors for PPP are only built as modules.'
+ fi
+ bool 'SGI Seeq ethernet controller support' CONFIG_SGISEEQ
+ fi
X fi
X endmenu
X fi
X
-mainmenu_option next_comment
-comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
-
-bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
-if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
- source drivers/cdrom/Config.in
+if [ "$CONFIG_SGI" != "y" ]; then
+ mainmenu_option next_comment
+ comment 'ISDN subsystem'
+
+ tristate 'ISDN support' CONFIG_ISDN
+ if [ "$CONFIG_ISDN" != "n" ]; then
+ source drivers/isdn/Config.in
+ fi
+ endmenu
+
+ mainmenu_option next_comment
+ comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
+
+ bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI
+ if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
+ source drivers/cdrom/Config.in
+ fi
+ endmenu
X fi
-endmenu
X
X source fs/Config.in
X
-source drivers/char/Config.in
-bool 'Standard serial device support' CONFIG_SERIAL n
+if [ "$CONFIG_SGI" != "y" ]; then
+ source drivers/char/Config.in
X
-mainmenu_option next_comment
-comment 'Sound'
+ mainmenu_option next_comment
+ comment 'Sound'
X
-tristate 'Sound card support' CONFIG_SOUND
-if [ "$CONFIG_SOUND" != "n" ]; then
- source drivers/sound/Config.in
+ tristate 'Sound card support' CONFIG_SOUND
+ if [ "$CONFIG_SOUND" != "n" ]; then
+ source drivers/sound/Config.in
+ fi
+ endmenu
+else
+ comment 'SGI Character Devices'
+ bool 'Virtual terminal' CONFIG_VT
+ if [ "$CONFIG_VT" = "y" ]; then
+ bool 'Console on virtual terminal' CONFIG_VT_CONSOLE
+ fi
+ tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
+ bool 'SGI Zilog85C30 serial support' CONFIG_SGI_SERIAL
+ if [ "$CONFIG_SGI_SERIAL" != "n" ]; then
+ define_bool CONFIG_SERIAL y
+ fi
X fi
-endmenu
X
X mainmenu_option next_comment
X comment 'Kernel hacking'
X
X #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
X bool 'Kernel profiling support' CONFIG_PROFILE
X if [ "$CONFIG_PROFILE" = "y" ]; then
X int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
diff -u --recursive --new-file v2.1.43/linux/arch/mips/dec/Makefile linux/arch/mips/dec/Makefile
--- v2.1.43/linux/arch/mips/dec/Makefile Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/dec/Makefile Thu Jun 26 12:33:36 1997
@@ -0,0 +1,24 @@
+#
+# Makefile for the DECstation family specific parts of the kernel
+#
+# 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).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: dec.o
+O_TARGET := dec.o
+O_OBJS := boot.o int-handler.o decstation.o hw-access.o reset.o setup.o
+
+boot.o: boot.S
+
+int-handler.o: int-handler.S
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.43/linux/arch/mips/dec/boot.S linux/arch/mips/dec/boot.S
--- v2.1.43/linux/arch/mips/dec/boot.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/dec/boot.S Thu Jun 26 12:33:36 1997
@@ -0,0 +1,92 @@
+/*
+ * arch/mips/dec/boot.S
+ *
+ * Copyright (C) 1995, 1996 Paul M. Antoine
+ *
+ * Written by Ralf Baechle and Andreas Busse, modified for DECStation
+ * support by Paul Antoine.
+ *
+ * NOTE: There are references to R4X00 code in here, because there is an
+ * upgrade module for Personal DECStations with such a CPU!
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/bootinfo.h>
+
+/*
+ * dec_entry: Called by the boot PROM loader to do DECStation setup, prior
+ * to calling dec_setup() to fill in the boot_info structure.
+ *
+ * This code should also go in the boot loader for loading off
+ * floppy and HD... in addition to the tags code in dec_setup().
+ *
+ * FIXME: arrange for this code only to be linked in when building a
+ * kernel image to be booted via tftp from the boot prom??
+ */
+ .text
+ .globl dec_entry
+dec_entry:
+ /* Save the address of the REX call vector for later
+ * use in printing debug messages.
+ */
+ sw a3,pmax_rex_base
+ sw a2,rex_prom_magic
+ la a0,dec_signon
+ jal pmax_printf
+ nop
+
+ /* Now set up the bootinfo with things that
+ * should be loaded by the boot loader, except that
+ * for the moment we're booting using tftp.
+ */
+ jal dec_setup
+ nop
+/*
+ * Now we need to move exception vector handler routines that appear
+ * in head.S down to the right addresses, 'cos the DECStation loads
+ * kernels at 0x80030000... <sigh>
+ */
+
+/*
+ * First move the TLB refill code down to offset 0x000, at addr 0x80000000
+ */
+ la t0,except_vec0 # begining of exception code
+ la t1,except_vec1 # end of exception code
+ la t2,0x80000000 # where the code should live
+ lw t3,(t0) # get first word
+1: sw t3,(t2) # put it where it should go
+ addiu t0,4 # increment both pointers
+ addiu t2,4
+ lw t3,(t0) # will be in the delay slot
+ bne t0,t1,1b
+/*
+ * Now move the General Exception code down to offset 0x080 at 0x80000000
+ */
+ la t0,except_vec3 # begining of general exception code
+ la t1,end_except # end of general exception code
+ la t2,0x80000080 # where the code should live
+ lw t3,(t0) # get first word
+1: sw t3,(t2)
+ addiu t0,4
+ addiu t2,4
+ lw t3,(t0)
+ bne t0,t1,1b
+
+ la a0,dec_launch # say where we are going
+ jal pmax_printf
+ nop
+
+ la t0,mach_mem_upper # get upper memory bound
+ lw a0,(t0)
+ j kernel_entry
+ nop
+
+ .data
+ .align 2
+dec_signon: .ascii "\n\nLinux/MIPS DECStation Boot\n";
+ .asciiz "Copyright (C) Paul M. Antoine 1995, 1996 and others, 1994, 1995, 1996\n\n";
+dec_launch: .asciiz "Setup complete, launching kernel...\n";
diff -u --recursive --new-file v2.1.43/linux/arch/mips/dec/decstation.S linux/arch/mips/dec/decstation.S
--- v2.1.43/linux/arch/mips/dec/decstation.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/dec/decstation.S Thu Jun 26 12:33:36 1997
@@ -0,0 +1,369 @@
+/*
+ * arch/mips/kernel/decstation.S
+ *
+ * Copyright (C) 1995, 1996 Paul M. Antoine
+ *
+ * Written by Ralf Baechle and Andreas Busse, modified for DECStation
+ * support by Paul Antoine.
+ *
+ * NOTE: There are references to R4X00 code in here, because I believe
+ * that there is an upgrade module for Personal DECStations with
+ * such CPU's!
+ *
+ * FIXME: still plenty to do in this file, as much of the code towards
+ * the end hasn't been modified to suit the DECStation's interrupts.
+ * (Paul, you need to fix this file to comply with NAPS. Won't be
+ * too hard - Ralf)
+ */
+#include <asm/asm.h>
+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/decstation.h>
+#include <asm/stackframe.h>
+#include <asm/bootinfo.h>
+
+/*
+ * dec_entry: Called at boot in head.S to do DECStation setup, and to
+ * fill in the boot_info structure.
+ */
+ .text
+ .globl dec_entry
+dec_entry:
+ /* Save the address of the REX call vector for later
+ * use in printing debug messages.
+ */
+ sw a3,pmax_rex_base
+ la a0,dec_signon
+ jal pmax_printf
+ nop
+ /* Now set up the bootinfo structure with things that
+ * should be loaded by the boot loader, except that
+ * for the moment we're booting using tftp.
+ */
+ la t0,boot_info
+ li t1,0x40 # 64 TLB entries
+/*
+ * FIXME: Ideally, all DEC workstations should be supported, so here we
+ * should put some clevernesses to determine machine type and CPU
+ * type. Needs a hierarchy of DEC machine types. Perhaps Machine
+ * AND Model fields in bootinfo structure?
+ */
+ sw t1,OFFSET_BOOTINFO_TLB_ENTRIES(t0)
+ li t1,MACH_DECSTATION # Machine type
+ sw t1,(t0)
+ li t1,CPU_R3000A # CPU type
+ sw t1,OFFSET_BOOTINFO_CPUTYPE(t0)
+/*
+ * FIXME: the following should find the memory size from the boot PROM
+ */
+ li t1,0x80000000 # Lower memory bound
+ sw t1,OFFSET_BOOTINFO_MEMLOWER(t0)
+ li t1,0x88000000 # Upper memory bound (8MB)
+ sw t1,OFFSET_BOOTINFO_MEMUPPER(t0)
+/*
+ * FIXME: the following should determine the cache size a la the method
+ * used in MACH. For now we just guess - PMA.
+ */
+ li t1,0x100000 # 64K icache
+ sw t1,OFFSET_BOOTINFO_ICACHE_SIZE(t0)
+ li t1,0x100000 # 64K dcache
+ sw t1,OFFSET_BOOTINFO_DCACHE_SIZE(t0)
+
+/*
+ * FIXME: template for other bootinfo fields that probably need filling in...
+ *
+ li t1,0x80000000
+ sw t1,OFFSET_BOOTINFO_(t0)
+*/
+
+/*
+ * Now we need to move exception vector handler routines that appear
+ * in head.S down to the right addresses, 'cos the DECStation loads
+ * kernels at 0x80030000... <sigh>
+ */
+
+/*
+ * First move the TLB refill code down to offset 0x000, at addr 0x80000000
+ */
+ la t0,except_vec0 # begining of TLB exception code
+ la t1,except_vec1 # end of TLB exception code
+ la t2,0x80000000 # where the code should live
+ lw t3,(t0) # get first word
+1: sw t3,(t2) # put it where it should go
+ addiu t0,4 # increment both pointers
+ addiu t2,4
+ lw t3,(t0) # will be in the delay slot
+ bne t0,t1,1b
+
+/*
+ * Now move the General Exception code down to offset 0x080 at 0x80000000
+ */
+ la t0,except_vec3 # begining of general exception code
+ la t1,kernel_entry # end of general exception code
+ la t2,0x80000080 # where the code should live
+ lw t3,(t0) # get first word
+1: sw t3,(t2)
+ addiu t0,4
+ addiu t2,4
+ lw t3,(t0)
+ bne t0,t1,1b
+
+/*
+ * FIXME: Don't forget to set the gp regster... why do I need this?
+ */
+ la gp,_gp
+ la a0,dec_launch # say where we are going
+ jal pmax_printf
+ nop
+ j kernel_entry
+ nop
+
+ .data
+ .align 2
+dec_signon: .ascii "\n\nLinux/MIPS DECStation Boot\n";
+ .asciiz "Copyright (C) Paul M. Antoine 1995, 1996 and others, 1994, 1995, 1996\n\n";
+dec_launch: .asciiz "Launching kernel...\n";
+ .text
+ .set noreorder
+/*
+ * decstation_handle_int: Interrupt handler for Personal DECStation 5000/2x
+ *
+ * FIXME: this is *extremely* experimental, though it is probably o.k. for
+ * most DECStation models.
+ */
+ NESTED(decstation_handle_int, FR_SIZE, ra)
+ .set noat
+ SAVE_ALL
+ REG_S sp,FR_ORIG_REG2(sp)
+ CLI
+ .set at
+
+ /*
+ * Get pending interrupts
+ */
+ mfc0 t0,CP0_CAUSE # get pending interrupts
+ mfc0 t1,CP0_STATUS # get enabled interrupts
+ and t0,t1 # isolate allowed ones
+ andi t0,0xff00 # isolate pending bits
+/*
+ * FIXME: The following branch was:
+ * beqz t0,spurious_interrupt
+ *
+ * ...but the wonders of ecoff cause the gas assembler (ver 2.5.1 )
+ * to complain:
+ *
+ * "Can not represent relocation in this object file format"...
+ *
+ * hence this hack to branch foward a bit, and then jump <sigh>
+ * Perhaps a later version of gas will cope? - Paul
+ * (No, this is impossible in COFF as well as in ELF. - Ralf)
+ */
+ beqz t0,3f;
+ sll t0,16 # delay slot
+
+ /*
+ * Find irq with highest priority
+ * FIXME: This is slow
+ */
+ la t1,ll_vectors
+1: bltz t0,2f # found pending irq
+ sll t0,1
+ b 1b
+ subu t1,PTRSIZE # delay slot
+
+ /*
+ * Do the low-level stuff
+ */
+ .set reorder
+2: LOAD_L t0,(t1)
+ jr t0
+ .set noreorder
+ END(decstation_handle_int)
+
+/*
+ * FIXME: The hack mentioned above.
+ */
+3: j spurious_interrupt
+ nop
+
+/*
+ * FIXME: the rest of this is pretty suspect, as it's straight from
+ * jazz.S... and I really haven't altered it at all - Paul
+ */
+
+/*
+ * Used for keyboard driver's fake_keyboard_interrupt()
+ * (Paul, even for i386 this is no longer being used -- Ralf)
+ */
+ll_sw0: li s1,~IE_SW0
+ mfc0 t0,CP0_CAUSE
+ and t0,s1
+ mtc0 t0,CP0_CAUSE
+ PRINT("sw0 received...\n")
+ li t1,1
+ b call_real
+ li t3,PTRSIZE # delay slot, re-map to irq level 1
+
+ll_sw1: li s1,~IE_SW1
+ PANIC("Unimplemented sw1 handler")
+
+loc_no_irq: PANIC("Unimplemented loc_no_irq handler")
+loc_sound: PANIC("Unimplemented loc_sound handler")
+loc_video: PANIC("Unimplemented loc_video handler")
+loc_scsi: PANIC("Unimplemented loc_scsi handler")
+
+/*
+ * Ethernet interrupt, remapped to level 15
+ * NOTE: Due to a bug somewhere in the kernel I was not able
+ * to figure out, the PRINT() is necessary. Without this,
+ * I get a "gfp called nonatomically from interrupt 00000000".
+ * Only god knows why... Tell me if you find the reason!
+ * (You were fouled by the caches and this is the wrong file for this
+ * comment - Ralf)
+ * Andy, 6/16/95
+ */
+loc_ethernet: PANIC("Unimplemented loc_ethernet\n")
+
+/*
+ * Keyboard interrupt, remapped to level 1
+ */
+loc_keyboard: PANIC("Unimplemented loc_keyboard\n")
+
+loc_mouse: PANIC("Unimplemented loc_mouse handler")
+
+/*
+ * Serial port 1 IRQ, remapped to level 3
+ */
+loc_serial1: PANIC("Unimplemented loc_serial handler")
+
+/*
+ * Serial port 2 IRQ, remapped to level 4
+ */
+loc_serial2: PANIC("Unimplemented loc_serial handler")
+
+/*
+ * Parallel port IRQ, remapped to level 5
+ */
+loc_parallel: PANIC("Unimplemented loc_parallel handler")
+
+/*
+ * Floppy IRQ, remapped to level 6
+ */
+loc_floppy: PANIC("Unimplemented loc_floppy handler")
+
+/*
+ * Now call the real handler
+ */
+loc_call: la t0,IRQ_vectors # delay slot
+
+ /*
+ * Temporarily disable interrupt source
+ */
+/* lhu t2,JAZZ_IO_IRQ_ENABLE
+*/
+ addu t0,t3 # make ptr to IRQ handler
+ LOAD_L t0,(t0)
+ and t2,s1 # delay slot
+/* sh t2,JAZZ_IO_IRQ_ENABLE */
+ jalr t0 # call IRQ handler
+ nor s1,zero,s1 # delay slot
+
+ /*
+ * Reenable interrupt
+ */
+/* lhu t2,JAZZ_IO_IRQ_ENABLE */
+ or t2,s1
+/* sh t2,JAZZ_IO_IRQ_ENABLE */
+
+ jr v0
+ nop # delay slot
+
+ll_tc3: PANIC("Unimplemented tc3 interrupt handler")
+
+ll_fpu: PANIC("Unimplemented fpu interrupt handler")
+
+ll_io_error: PANIC("Unimplemented I/O write timeout interrupt handler")
+
+ll_rtc: PANIC("Unimplemented RTC interrupt handler")
+
+/*
+ * Timer IRQ
+ * We remap the timer irq to be more similar to a IBM compatible
+ */
+ll_timer: PANIC("Timer interrupt!\n");
+/*
+ * CPU count/compare IRQ (unused)
+ */
+ll_reset: li a0,0
+ jal pmax_halt
+ li a1,0 # delay slot
+
+/*
+ * Now call the real handler
+ */
+call_real: la t0,IRQ_vectors # delay slot
+
+ /*
+ * temporarily disable interrupt
+ */
+ mfc0 t2,CP0_STATUS
+ and t2,s1
+
+ addu t0,t3
+ LOAD_L t0,(t0)
+ mtc0 t2,CP0_STATUS # delay slot
+ jalr t0
+ nor s1,zero,s1 # delay slot
+
+ /*
+ * reenable interrupt
+ */
+ mfc0 t2,CP0_STATUS
+ or t2,s1
+ mtc0 t2,CP0_STATUS
+
+ jr v0
+ nop # delay slot
+
+/*
+ * Just for debugging... load a0 with address of the point inside the
+ * framebuffer at which you want to draw a line of 16x32 pixels.
+ * Maxine's framebuffer starts at 0xaa000000.
+ */
+ .set reorder
+ LEAF(drawline)
+ li t1,0xffffffff # set all pixels on
+ li t2,0x10 # we will write 16 words
+1: sw t1,(a0) # write the first word
+ addiu a0,a0,4 # move our framebuffer pointer
+ addiu t2,t2,-1 # one less to do
+ bnez t2,1b # finished?
+ jr ra
+ END(drawline)
+
+/*
+ * FIXME: I have begun to alter this table to reflect Personal DECStation
+ * (i.e. Maxine) interrupts... Paul.
+ */
+ .data
+ PTR ll_sw0 # SW0
+ PTR ll_sw1 # SW1
+ PTR ll_timer # Periodic interrupt
+ PTR ll_rtc # RTC periodic interrupt
+ PTR ll_io_error # Timeout on I/O writes
+ PTR ll_tc3 # TC slot 3, motherboard
+ PTR ll_reset # Halt keycode (CTRL+ALT+ENTER)
+ll_vectors: PTR ll_fpu # FPU
+
+local_vector: PTR loc_no_irq
+ PTR loc_parallel
+ PTR loc_floppy
+ PTR loc_sound
+ PTR loc_video
+ PTR loc_ethernet
+ PTR loc_scsi
+ PTR loc_keyboard
+ PTR loc_mouse
+ PTR loc_serial1
+ PTR loc_serial2
diff -u --recursive --new-file v2.1.43/linux/arch/mips/dec/decstation.c linux/arch/mips/dec/decstation.c
--- v2.1.43/linux/arch/mips/dec/decstation.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/dec/decstation.c Thu Jun 26 12:33:36 1997
@@ -0,0 +1,200 @@
+/*
+ * arch/mips/dec/decstation.c
+ *
+ * Copyright (C) 1996 Paul M. Antoine
+ *
+ * Written by Paul Antoine.
+ *
+ * FIXME: still plenty to do in this file, as we don't yet fully fill
+ * the boot info structure with DEC-specific tags. Also still
+ * too specific to the Person Decstattion 5000/2x!!
+ */
+
+#include <asm/dec/decstation.h>
+#include <asm/dec/maxine.h> /* FIXME: what about other decstations? */
+#include <asm/bootinfo.h>
+
+/*
+ * dec_setup: Called at boot from dec_entry() in boot.S to do
+ * DECStation-specific setup, and to fill in the kernel argument
+ * tags.
+ *
+ * FIXME: I'm not sure all DEC workstations are correctly supported. This
+ * code may not need to be here when booting off floppy or HD??
+ */
+
+unsigned long mach_mem_upper = 0;
+unsigned long mach_mem_lower = 0;
+unsigned long mips_dcache_size = 0;
+unsigned long mips_icache_size = 0;
+unsigned long rex_prom_magic; /* from boot.S */
+unsigned long dec_get_memory_size(void);
+
+void dec_setup(void)
+{
+ unsigned long int mem_mask = 0;
+ unsigned long tag_data_dummy, dec_sysid;
+ unsigned char dec_cpunum, dec_systype, dec_firmrev, dec_etc;
+ extern const char *linux_banner;
+
+ pmax_printf("%s\n", linux_banner);
+ /* First we need the memory upper bound before we can add tag entries... */
+ mach_mem_lower = 0x80000000L;
+ mach_mem_upper = mach_mem_lower + dec_get_memory_size();
+
+ /* First tag is always memory upper limit, right Stoned?? */
+ (void)bi_TagAdd(tag_memupper, ULONGSIZE, &mach_mem_upper);
+
+ /* We're obviously one of the DEC machines */
+ tag_data_dummy = MACH_GROUP_DEC;
+ (void)bi_TagAdd(tag_machgroup, ULONGSIZE, &tag_data_dummy);
+
+ /* Now let's try to figure out what type of DECStation we are */
+ pmax_printf("System id is: ");
+ if ((dec_sysid = pmax_getsysid()) != 0)
+ pmax_printf("%x\n", dec_sysid);
+ else
+ pmax_printf("unknown\n");
+
+ dec_cpunum = (dec_sysid & 0xff000000) >> 24;
+ dec_systype = (dec_sysid & 0xff0000) >> 16;
+ dec_firmrev = (dec_sysid & 0xff00) >> 8;
+ dec_etc = dec_sysid & 0xff;
+
+ /*
+ * FIXME: for now use the PROM to determine the CPU type - should
+ * probably just get the CPU to tell us.
+ */
+ pmax_printf("System has an ");
+ switch(dec_cpunum)
+ {
+ case 0x82:
+ {
+ pmax_printf("R3000 CPU\n");
+ tag_data_dummy = CPU_R3000A;
+ break;
+ }
+ case 0x84:
+ {
+ pmax_printf("R4000 CPU\n");
+ /* FIXME: assume a plain R4000PC for now */
+ tag_data_dummy = CPU_R4000PC;
+ break;
+ }
+ default:
+ {
+ pmax_printf("unknown CPU, code is %x\n", dec_cpunum);
+ /* FIXME: assume an R2000 for now */
+ tag_data_dummy = CPU_R2000;
+ break;
+ }
+ }
+ /* Add the CPU type */
+ (void)bi_TagAdd(tag_cputype, ULONGSIZE, &tag_data_dummy);
+
+ pmax_printf("System has firmware type: ");
+ if (dec_firmrev == 2)
+ pmax_printf("TCF0\n");
+ else
+ pmax_printf("TCF1\n");
+
+ pmax_printf("This DECStation is a: ");
+ switch(dec_systype) {
+ case 1: /* DS2100/3100 Pmax */
+ pmax_printf("DS2100/3100\n");
+ tag_data_dummy = MACH_DECSTATION;
+ break;
+ case 2: /* DS5000 3max */
+ pmax_printf("DS5000\n");
+ tag_data_dummy = MACH_DECSTATION;
+ break;
+ case 3: /* DS5000/100 3min */
+ pmax_printf("DS5000/1x0\n");
+ tag_data_dummy = MACH_DECSTATION;
+ break;
+ case 7: /* Personal DS5000/2x */
+ pmax_printf("Personal DS5000/2x\n");
+ tag_data_dummy = MACH_DECSTATION;
+ break;
+ default:
+ pmax_printf("unknown, id is: %x\n", dec_systype);
+ tag_data_dummy = MACH_UNKNOWN;
+ break;
+ }
+
+ /* Add the machine type */
+ (void)bi_TagAdd(tag_machtype, ULONGSIZE, &tag_data_dummy);
+
+ /* Add the number of tlb entries */
+ tag_data_dummy = 64;
+ (void)bi_TagAdd(tag_tlb_entries, ULONGSIZE, &tag_data_dummy);
+
+ /*
+ * Add the instruction cache size
+ * FIXME: should determine this somehow
+ */
+ tag_data_dummy = 0x100000; /* set it to 64K for now */
+ (void)bi_TagAdd(tag_icache_size, ULONGSIZE, &tag_data_dummy);
+ mips_icache_size = tag_data_dummy;
+
+ /*
+ * Add the data cache size
+ * FIXME: should determine this somehow
+ */
+ tag_data_dummy = 0x100000; /* set it to 64K for now */
+ (void)bi_TagAdd(tag_dcache_size, ULONGSIZE, &tag_data_dummy);
+ mips_dcache_size = tag_data_dummy;
+
+ /* FIXME: should determine vram_base properly */
+ tag_data_dummy = 0xa8000000;
+ (void)bi_TagAdd(tag_vram_base, ULONGSIZE, &tag_data_dummy);
+
+ /* FIXME: dummy drive info tag */
+ tag_data_dummy = 0;
+ (void)bi_TagAdd(tag_drive_info, ULONGSIZE, &tag_data_dummy);
+
+ /* FIXME: do we need a dummy tag at the end? */
+ tag_data_dummy = 0;
+ (void)bi_TagAdd(tag_dummy, 0, &tag_data_dummy);
+
+ pmax_printf("Added tags\n");
+} /* dec_setup */
+
+unsigned long dec_get_memory_size()
+{
+ int i, bitmap_size;
+ unsigned long mem_size = 0;
+ struct pmax_bitmap {
+ int pagesize;
+ unsigned char bitmap[64*1024*1024 - 4];
+ } *bm;
+
+ /* some free 64k */
+ bm = (struct pmax_bitmap *)0x8002f000;
+ bitmap_size = pmax_getbitmap(bm);
+
+ pmax_printf("Page size is: %x\n", bm->pagesize);
+ pmax_printf("Bitmap size is: %d bytes\n", bitmap_size);
+
+ for (i = 0; i < bitmap_size; i++)
+ {
+ /* FIXME: very simplistically only add full sets of pages */
+ if (bm->bitmap[i] == 0xff)
+ mem_size += (8 * bm->pagesize);
+ }
+ pmax_printf("Main memory size is: %d KB\n", (mem_size / 1024));
+ return(mem_size);
+} /* dec_get_memory_size */
+
+unsigned char maxine_rtc_read_data(unsigned long addr)
+{
+ char *rtc = (char *)(PMAX_RTC_BASE);
+ return(rtc[addr * 4]);
+} /* maxine_rtc_read_data */
+
+void maxine_rtc_write_data(unsigned char data, unsigned long addr)
+{
+ char *rtc = (char *)(PMAX_RTC_BASE);
+ rtc[addr * 4] = data;
+} /* maxine_rtc_read_data */
+
diff -u --recursive --new-file v2.1.43/linux/arch/mips/dec/hw-access.c linux/arch/mips/dec/hw-access.c
--- v2.1.43/linux/arch/mips/dec/hw-access.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/dec/hw-access.c Thu Jun 26 12:33:36 1997
@@ -0,0 +1,26 @@
+/*
+ * DECstation specific hardware access code.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 by Paul Antoine
+ */
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/mc146818rtc.h>
+#include <asm/vector.h>
+
+asmlinkage void decstation_handle_int(void);
+extern unsigned char maxine_rtc_read_data(unsigned long);
+extern void maxine_rtc_write_data(unsigned char, unsigned long);
+
+/*
+ * FIXME: Don't have any of the goo required to access fd etc.
+ */
+struct feature decstation_feature = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,
+ maxine_rtc_read_data,
+ maxine_rtc_write_data
+};
diff -u --recursive --new-file v2.1.43/linux/arch/mips/dec/int-handler.S linux/arch/mips/dec/int-handler.S
--- v2.1.43/linux/arch/mips/dec/int-handler.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/dec/int-handler.S Thu Jun 26 12:33:36 1997
@@ -0,0 +1,260 @@
+/*
+ * arch/mips/dec/int-handler.S
+ *
+ * Copyright (C) 1995, 1996 Paul M. Antoine
+ *
+ * Written by Ralf Baechle and Andreas Busse, modified for DECStation
+ * support by Paul Antoine.
+ *
+ * NOTE: There are references to R4X00 code in here, because there is an
+ * upgrade module for Personal DECStations with such a CPU!
+ *
+ * FIXME: still plenty to do in this file, as much of the code hasn't been
+ * modified to suit the DECStation's interrupts.
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/bootinfo.h>
+
+ .text
+ .set noreorder
+/*
+ * decstation_handle_int: Interrupt handler for Personal DECStation 5000/2x
+ *
+ * FIXME: this is *extremely* experimental, though it is probably o.k. for
+ * most DECStation models.
+ */
+ NESTED(decstation_handle_int, FR_SIZE, ra)
+ .set noat
+ SAVE_ALL
+ CLI
+ .set at
+
+ /*
+ * Get pending interrupts
+ */
+ mfc0 t0,CP0_CAUSE # get pending interrupts
+ mfc0 t1,CP0_STATUS # get enabled interrupts
+ and t0,t1 # isolate allowed ones
+ andi t0,0xff00 # isolate pending bits
+/*
+ * FIXME: The following branch was:
+ * beqz t0,spurious_interrupt
+ *
+ * ...but the wonders of ecoff cause the gas assembler (ver 2.5.1 )
+ * to complain:
+ *
+ * "Can not represent relocation in this object file format"...
+ *
+ * hence this hack to branch foward a bit, and then jump <sigh>
+ * Perhaps a later version of gas will cope? - Paul
+ */
+ beqz t0,3f;
+ sll t0,16 # delay slot
+
+ /*
+ * Find irq with highest priority
+ * FIXME: This is slow
+ */
+ la t1,ll_vectors
+1: bltz t0,2f # found pending irq
+ sll t0,1
+ b 1b
+ subu t1,PTRSIZE # delay slot
+
+ /*
+ * Do the low-level stuff
+ */
+2: lw t0,(t1)
+ jr t0
+ nop # delay slot
+ END(decstation_handle_int)
+
+/*
+ * FIXME: The hack mentioned above.
+ */
+3: j spurious_interrupt
+ nop
+
+/*
+ * FIXME: the rest of this is pretty suspect, as it's straight from
+ * jazz.S... and I really haven't altered it at all - Paul
+ */
+
+/*
+ * Used for keyboard driver's fake_keyboard_interrupt()
+ * (Paul, even for i386 this is no longer being used -- Ralf)
+ */
+ll_sw0: li s1,~IE_SW0
+ mfc0 t0,CP0_CAUSE
+ and t0,s1
+ mtc0 t0,CP0_CAUSE
+ PRINT("sw0 received...\n")
+ li t1,1
+ b call_real
+ li t3,PTRSIZE # delay slot, re-map to irq level 1
+
+ll_sw1: li s1,~IE_SW1
+ PANIC("Unimplemented sw1 handler")
+
+loc_no_irq: PANIC("Unimplemented loc_no_irq handler")
+loc_sound: PANIC("Unimplemented loc_sound handler")
+loc_video: PANIC("Unimplemented loc_video handler")
+loc_scsi: PANIC("Unimplemented loc_scsi handler")
+
+/*
+ * Ethernet interrupt, remapped to level 15
+ * NOTE: Due to a bug somewhere in the kernel I was not able
+ * to figure out, the PRINT() is necessary. Without this,
+ * I get a "gfp called nonatomically from interrupt 00000000".
+ * Only god knows why... Tell me if you find the reason!
+ * Andy, 6/16/95
+ */
+loc_ethernet: PANIC("Unimplemented loc_ethernet\n")
+
+/*
+ * Keyboard interrupt, remapped to level 1
+ */
+loc_keyboard: PANIC("Unimplemented loc_keyboard\n")
+
+loc_mouse: PANIC("Unimplemented loc_mouse handler")
+
+/*
+ * Serial port 1 IRQ, remapped to level 3
+ */
+loc_serial1: PANIC("Unimplemented loc_serial handler")
+
+/*
+ * Serial port 2 IRQ, remapped to level 4
+ */
+loc_serial2: PANIC("Unimplemented loc_serial handler")
+
+/*
+ * Parallel port IRQ, remapped to level 5
+ */
+loc_parallel: PANIC("Unimplemented loc_parallel handler")
+
+/*
+ * Floppy IRQ, remapped to level 6
+ */
+loc_floppy: PANIC("Unimplemented loc_floppy handler")
+
+/*
+ * Now call the real handler
+ */
+loc_call: la t0,IRQ_vectors # delay slot
+
+ /*
+ * Temporarily disable interrupt source
+ */
+/* lhu t2,JAZZ_IO_IRQ_ENABLE
+*/
+ addu t0,t3 # make ptr to IRQ handler
+ lw t0,(t0)
+ and t2,s1 # delay slot
+/* sh t2,JAZZ_IO_IRQ_ENABLE */
+ jalr t0 # call IRQ handler
+ nor s1,zero,s1 # delay slot
+
+ /*
+ * Reenable interrupt
+ */
+/* lhu t2,JAZZ_IO_IRQ_ENABLE */
+ or t2,s1
+/* sh t2,JAZZ_IO_IRQ_ENABLE */
+
+ jr v0
+ nop # delay slot
+
+ll_tc3: PANIC("Unimplemented tc3 interrupt handler")
+
+ll_fpu: PANIC("Unimplemented fpu interrupt handler")
+
+ll_io_error: PANIC("Unimplemented I/O write timeout interrupt handler")
+
+ll_rtc: PANIC("Unimplemented RTC interrupt handler")
+
+/*
+ * Timer IRQ
+ * We remap the timer irq to be more similar to a IBM compatible
+ */
+ll_timer: PANIC("Timer interrupt!\n");
+/*
+ * CPU count/compare IRQ (unused)
+ */
+ll_reset: li a0,0
+ jal pmax_halt
+ li a1,0 # delay slot
+
+/*
+ * Now call the real handler
+ */
+call_real: la t0,IRQ_vectors # delay slot
+
+ /*
+ * temporarily disable interrupt
+ */
+ mfc0 t2,CP0_STATUS
+ and t2,s1
+
+ addu t0,t3
+ lw t0,(t0)
+ mtc0 t2,CP0_STATUS # delay slot
+ jalr t0
+ nor s1,zero,s1 # delay slot
+
+ /*
+ * reenable interrupt
+ */
+ mfc0 t2,CP0_STATUS
+ or t2,s1
+ mtc0 t2,CP0_STATUS
+
+ jr v0
+ nop # delay slot
+
+/*
+ * Just for debugging... load a0 with address of the point inside the
+ * framebuffer at which you want to draw a line of 16x32 pixels.
+ * Maxine's framebuffer starts at 0xaa000000.
+ */
+ .set reorder
+ LEAF(drawline)
+ li t1,0xffffffff # set all pixels on
+ li t2,0x10 # we will write 16 words
+1: sw t1,(a0) # write the first word
+ addiu a0,a0,4 # move our framebuffer pointer
+ addiu t2,t2,-1 # one less to do
+ bnez t2,1b # finished?
+ jr ra
+ END(drawline)
+
+/*
+ * FIXME: I have begun to alter this table to reflect Personal DECStation
+ * (i.e. Maxine) interrupts... Paul.
+ */
+ .data
+ PTR ll_sw0 # SW0
+ PTR ll_sw1 # SW1
+ PTR ll_timer # Periodic interrupt
+ PTR ll_rtc # RTC periodic interrupt
+ PTR ll_io_error # Timeout on I/O writes
+ PTR ll_tc3 # TC slot 3, motherboard
+ PTR ll_reset # Halt keycode (CTRL+ALT+ENTER)
+ll_vectors: PTR ll_fpu # FPU
+
+local_vector: PTR loc_no_irq
+ PTR loc_parallel
+ PTR loc_floppy
+ PTR loc_sound
+ PTR loc_video
+ PTR loc_ethernet
+ PTR loc_scsi
+ PTR loc_keyboard
+ PTR loc_mouse
+ PTR loc_serial1
+ PTR loc_serial2
diff -u --recursive --new-file v2.1.43/linux/arch/mips/dec/ld.script linux/arch/mips/dec/ld.script
--- v2.1.43/linux/arch/mips/dec/ld.script Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/dec/ld.script Thu Jun 26 12:33:37 1997
@@ -0,0 +1,47 @@
+OUTPUT_FORMAT("ecoff-littlemips")
+OUTPUT_ARCH(mips)
+ENTRY(dec_entry)
+SECTIONS
+{
+ /* This is probably a little simplistic, and is based on work by
+ * Chris Fraser of Softway Pty Ltd as used in his port of Vsta to
+ * the DECStation - Paul M. Antoine 21/1/96.
+ */
+ . = 0x80030000;
+ .text :
+ {
+ *(.text)
+ . = ALIGN(0x10);
+ _etext = .;
+ __etext = .;
+ }
+ .lit8 : {
+ *(.lit8)
+ }
+ .lit4 : {
+ *(.lit4)
+ }
+ . = ALIGN(0x1000);
+ .data :
+ {
+ *(.data .rdata .rodata)
+ _edata = .;
+ __edata = .;
+ }
+ __bss_start = ALIGN(16) + 0x8000;
+ .sbss :
+ {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss :
+ {
+ *(.bss)
+ *(COMMON)
+ _end = ALIGN(4) ;
+ __end = ALIGN(4) ;
+ }
+ .reginfo : {
+ *(.reginfo)
+ }
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/dec/reset.c linux/arch/mips/dec/reset.c
--- v2.1.43/linux/arch/mips/dec/reset.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/dec/reset.c Thu Jun 26 12:33:37 1997
@@ -0,0 +1,28 @@
+/*
+ * linux/arch/mips/dec/process.c
+ *
+ * Reset a DECstation.
+ */
+#include <linux/kernel.h>
+#include <asm/reboot.h>
+
+void dec_machine_restart(char *command)
+{
+ printk("Implement dec_machine_restart().\n");
+ printk("Press reset to continue.\n");
+ while(1);
+}
+
+void dec_machine_halt(void)
+{
+ printk("Implement dec_machine_halt().\n");
+ printk("Press reset to continue.\n");
+ while(1);
+}
+
+void dec_machine_power_off(void)
+{
+ printk("Implement dec_machine_power_off().\n");
+ printk("Press reset to continue.\n");
+ while(1);
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/dec/setup.c linux/arch/mips/dec/setup.c
--- v2.1.43/linux/arch/mips/dec/setup.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/dec/setup.c Thu Jun 26 12:33:37 1997
@@ -0,0 +1,50 @@
+/*
+ * Setup pointers to hardware dependand routines.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <asm/ptrace.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/vector.h>
+
+extern struct feature decstation_feature;
+
+static void
+dec_irq_setup(void)
+{
+ /* FIXME: should set up the clock as per above? */
+ pmax_printf("Please write the IRQ setup code for the DECStation!\n");
+}
+
+void (*board_time_init)(struct irqaction *irq);
+
+static void dec_time_init(struct irqaction *irq)
+{
+ pmax_printf("Please write the time init code for the DECStation!\n");
+}
+
+extern void dec_machine_restart(char *command);
+extern void dec_machine_halt(void);
+extern void dec_machine_power_off(void).
+
+void
+decstation_setup(void)
+{
+ irq_setup = dec_irq_setup;
+ board_time_init = dec_time_init;
+ /* FIXME: Setup fd_cacheflush */
+ feature = &decstation_feature; /* FIXME: Will go away */
+
+ _machine_restart = dec_machine_restart;
+ _machine_halt = dec_machine_halt;
+ _machine_power_off = dec_machine_power_off;
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/defconfig linux/arch/mips/defconfig
--- v2.1.43/linux/arch/mips/defconfig Mon Apr 7 11:35:29 1997
+++ linux/arch/mips/defconfig Mon Jul 7 08:18:53 1997
@@ -3,42 +3,105 @@
X #
X
X #
-# Machine setup
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Machine selection
X #
X CONFIG_ACER_PICA_61=y
-# CONFIG_DECSTATION is not set
-# CONFIG_DESKSTATION_RPC44 is not set
-# CONFIG_DESKSTATION_TYNE is not set
-# CONFIG_MIPS_MAGNUM_3000 is not set
X # CONFIG_MIPS_MAGNUM_4000 is not set
X # CONFIG_OLIVETTI_M700 is not set
+CONFIG_SNI_RM200_PCI=y
X CONFIG_MIPS_JAZZ=y
+CONFIG_PCI=y
+
+#
+# CPU selection
+#
X # CONFIG_CPU_R3000 is not set
X # CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_R4300 is not set
X CONFIG_CPU_R4X00=y
-# CONFIG_CPU_R4600 is not set
+# CONFIG_CPU_R5000 is not set
X # CONFIG_CPU_R8000 is not set
X # CONFIG_CPU_R10000 is not set
-CONFIG_TLB_SHUTDOWN=y
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-# CONFIG_ELF_KERNEL is not set
+
+#
+# General setup
+#
+CONFIG_ELF_KERNEL=y
X CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_NET is not set
-# CONFIG_SYSVIPC is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
X CONFIG_SYSCTL=y
+# CONFIG_PNP_PARPORT is not set
X
X #
X # Loadable module support
X #
-# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULES is not set
X
X #
-# block devices
+# Floppy, IDE, and other block devices
X #
X CONFIG_BLK_DEV_FD=y
-# CONFIG_ST506 is not set
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_TRITON is not set
+# CONFIG_IDE_CHIPSETS is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
X # CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_EZ is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_NETLINK is not set
+# CONFIG_FIREWALL is not set
+# CONFIG_NET_ALIAS is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ACCT is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+
+#
+# (it is safe to leave these untouched)
+#
+# CONFIG_INET_PCTCP is not set
+# CONFIG_INET_RARP is not set
+CONFIG_PATH_MTU_DISCOVERY=y
+CONFIG_IP_NOSR=y
+# CONFIG_SKB_LARGE is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_AX25 is not set
X
X #
X # SCSI support
@@ -46,6 +109,42 @@
X # CONFIG_SCSI is not set
X
X #
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MIPS_JAZZ_SONIC=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_EISA=y
+CONFIG_PCNET32=y
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DEC_ELCP is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEXPRESS_PRO100 is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI is not set
+# CONFIG_DLCI is not set
+# CONFIG_PPP is not set
+# CONFIG_NET_RADIO is not set
+# CONFIG_SLIP is not set
+# CONFIG_TR is not set
+# CONFIG_LAPBETHER is not set
+# CONFIG_X25_ASY is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
X # CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
X #
X # CONFIG_CD_NO_IDESCSI is not set
@@ -53,30 +152,47 @@
X #
X # Filesystems
X #
+# CONFIG_QUOTA is not set
+# CONFIG_DCACHE_PRELOAD is not set
+# CONFIG_OMIRR is not set
+# CONFIG_TRANS_NAMES is not set
X # CONFIG_MINIX_FS is not set
X CONFIG_EXT2_FS=y
+# CONFIG_FAT_FS is not set
X # CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_UMSDOS_FS is not set
X CONFIG_PROC_FS=y
-# CONFIG_ISO9660_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_RNFS_BOOTP=y
+# CONFIG_RNFS_RARP is not set
+CONFIG_NFSD=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+CONFIG_ISO9660_FS=y
X # CONFIG_HPFS_FS is not set
X # CONFIG_SYSV_FS is not set
-# CONFIG_SMB_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_UFS_FS is not set
X
X #
-# character devices
+# Character devices
X #
X CONFIG_VT=y
X CONFIG_VT_CONSOLE=y
-# CONFIG_CYCLADES is not set
-# CONFIG_STALDRV is not set
-# CONFIG_PRINTER is not set
-# CONFIG_BUSMOUSE is not set
-# CONFIG_PSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
-# CONFIG_ATIXL_BUSMOUSE is not set
+CONFIG_SERIAL=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MOUSE is not set
X # CONFIG_QIC02_TAPE is not set
+# CONFIG_FTAPE is not set
X # CONFIG_APM is not set
-# CONFIG_SERIAL is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
X
X #
X # Sound
@@ -86,4 +202,5 @@
X #
X # Kernel hacking
X #
+# CONFIG_REMOTE_DEBUG is not set
X # CONFIG_PROFILE is not set
diff -u --recursive --new-file v2.1.43/linux/arch/mips/deskstation/Makefile linux/arch/mips/deskstation/Makefile
--- v2.1.43/linux/arch/mips/deskstation/Makefile Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/deskstation/Makefile Thu Jun 26 12:33:37 1997
@@ -0,0 +1,22 @@
+#
+# Makefile for the Deskstation family specific parts of the kernel
+#
+# 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).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: deskstation.o
+O_TARGET := deskstation.o
+O_OBJS := hw-access.o int-handler.o reset.o setup.o
+
+int-handler.o: int-handler.S
+
+clean:
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.43/linux/arch/mips/deskstation/hw-access.c linux/arch/mips/deskstation/hw-access.c
--- v2.1.43/linux/arch/mips/deskstation/hw-access.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/deskstation/hw-access.c Thu Jun 26 12:33:37 1997
@@ -0,0 +1,196 @@
+/*
+ * Low-level hardware access stuff for Deskstation rPC44/Tyne
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/vector.h>
+
+extern int FLOPPY_IRQ;
+extern int FLOPPY_DMA;
+
+asmlinkage extern void deskstation_handle_int(void);
+
+/*
+ * How to access the FDC's registers.
+ */
+static unsigned char
+fd_inb(unsigned int port)
+{
+ return inb_p(port);
+}
+
+static void
+fd_outb(unsigned char value, unsigned int port)
+{
+ outb_p(value, port);
+}
+
+/*
+ * How to access the floppy DMA functions.
+ */
+static void
+fd_enable_dma(void)
+{
+ enable_dma(FLOPPY_DMA);
+}
+
+static void
+fd_disable_dma(void)
+{
+ disable_dma(FLOPPY_DMA);
+}
+
+static int
+fd_request_dma(void)
+{
+ return request_dma(FLOPPY_DMA, "floppy");
+}
+
+static void
+fd_free_dma(void)
+{
+ free_dma(FLOPPY_DMA);
+}
+
+static void
+fd_clear_dma_ff(void)
+{
+ clear_dma_ff(FLOPPY_DMA);
+}
+
+static void
+fd_set_dma_mode(char mode)
+{
+ set_dma_mode(FLOPPY_DMA, mode);
+}
+
+static void
+fd_set_dma_addr(unsigned int addr)
+{
+ set_dma_addr(FLOPPY_DMA, addr);
+}
+
+static void
+fd_set_dma_count(unsigned int count)
+{
+ set_dma_count(FLOPPY_DMA, count);
+}
+
+static int
+fd_get_dma_residue(void)
+{
+ return get_dma_residue(FLOPPY_DMA);
+}
+
+static void
+fd_enable_irq(void)
+{
+ enable_irq(FLOPPY_IRQ);
+}
+
+static void
+fd_disable_irq(void)
+{
+ disable_irq(FLOPPY_IRQ);
+}
+
+void
+deskstation_fd_cacheflush(const void *addr, size_t size)
+{
+ flush_cache_all();
+}
+
+/*
+ * RTC stuff
+ */
+static unsigned char *
+rtc_read_data()
+{
+ return 0;
+}
+
+static void
+rtc_write_data(unsigned char data)
+{
+}
+
+/*
+ * KLUDGE
+ */
+static unsigned long
+vdma_alloc(unsigned long paddr, unsigned long size)
+{
+ return 0;
+}
+
+#ifdef CONFIG_DESKSTATION_TYNE
+struct feature deskstation_tyne_feature = {
+ /*
+ * How to access the floppy controller's ports
+ */
+ fd_inb,
+ fd_outb,
+ /*
+ * How to access the floppy DMA functions.
+ */
+ fd_enable_dma,
+ fd_disable_dma,
+ fd_request_dma,
+ fd_free_dma,
+ fd_clear_dma_ff,
+ fd_set_dma_mode,
+ fd_set_dma_addr,
+ fd_set_dma_count,
+ fd_get_dma_residue,
+ fd_enable_irq,
+ fd_disable_irq,
+ /*
+ * How to access the RTC functions.
+ */
+ rtc_read_data,
+ rtc_write_data
+};
+#endif
+
+#ifdef CONFIG_DESKSTATION_RPC44
+struct feature deskstation_rpc44_feature = {
+ /*
+ * How to access the floppy controller's ports
+ */
+ fd_inb,
+ fd_outb,
+ /*
+ * How to access the floppy DMA functions.
+ */
+ fd_enable_dma,
+ fd_disable_dma,
+ fd_request_dma,
+ fd_free_dma,
+ fd_clear_dma_ff,
+ fd_set_dma_mode,
+ fd_set_dma_addr,
+ fd_set_dma_count,
+ fd_get_dma_residue,
+ fd_enable_irq,
+ fd_disable_irq,
+ /*
+ * How to access the RTC functions.
+ */
+ rtc_read_data,
+ rtc_write_data
+};
+#endif
diff -u --recursive --new-file v2.1.43/linux/arch/mips/deskstation/int-handler.S linux/arch/mips/deskstation/int-handler.S
--- v2.1.43/linux/arch/mips/deskstation/int-handler.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/deskstation/int-handler.S Thu Jun 26 12:33:37 1997
@@ -0,0 +1,111 @@
+/*
+ * Deskstation rPC44/Tyne specific interrupt handler code
+ *
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle
+ */
+#include <asm/asm.h>
+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#error "FIXME - PORT_BASE is defined to port_base which breaks this file"
+
+ .text
+ .set noreorder
+ .set noat
+ .align 5
+ NESTED(deskstation_handle_int, PT_SIZE, sp)
+ SAVE_ALL
+ REG_S sp,PT_OR2(sp)
+ CLI
+ .set at
+ lui s0,%hi(PORT_BASE)
+ li a0,0x0f
+ sb a0,%lo(PORT_BASE+0x20)(s0) # poll command
+ lb a0,%lo(PORT_BASE+0x20)(s0) # read result
+ bgtz a0,poll_second
+ andi a0,7
+ beq a0,2,poll_second # cascade?
+ li s1,1 # delay slot
+ /*
+ * Acknowledge first pic
+ */
+ lb t2,%lo(PORT_BASE+0x21)(s0)
+ lui s4,%hi(cache_21)
+ lb t0,%lo(cache_21)(s4)
+ sllv s1,s1,a0
+ or t0,s1
+ sb t0,%lo(cache_21)(s4)
+ sb t0,%lo(PORT_BASE+0x21)(s0)
+ li t2,0x20
+ sb t2,%lo(PORT_BASE+0x20)(s0)
+ /*
+ * Now call the real handler
+ */
+ la t3,IRQ_vectors
+ sll t2,a0,PTRLOG
+ addu t3,t2
+ LONG_L t3,(t3)
+ jalr t3
+ nop # delay slot
+ /*
+ * Unblock first pic
+ */
+ lbu t1,%lo(PORT_BASE+0x21)(s0)
+ lb t1,%lo(cache_21)(s4)
+ nor s1,zero,s1
+ and t1,s1
+ sb t1,%lo(cache_21)(s4)
+ jr v0
+ sb t1,%lo(PORT_BASE+0x21)(s0) # delay slot
+
+ /*
+ * Cascade interrupt from second PIC
+ */
+ .align 5
+poll_second: li a0,0x0f
+ sb a0,%lo(PORT_BASE+0xa0)(s0) # poll command
+ lb a0,%lo(PORT_BASE+0xa0)(s0) # read result
+ bgtz a0,3f
+ andi a0,7
+ /*
+ * Acknowledge second pic
+ */
+ lbu t2,%lo(PORT_BASE+0xa1)(s0)
+ lui s4,%hi(cache_A1)
+ lb t3,%lo(cache_A1)(s4)
+ sllv s1,s1,a0
+ or t3,s1
+ sb t3,%lo(cache_A1)(s4)
+ sb t3,%lo(PORT_BASE+0xa1)(s0)
+ li t3,0x20
+ sb t3,%lo(PORT_BASE+0xa0)(s0)
+ sb t3,%lo(PORT_BASE+0x20)(s0)
+ /*
+ * Now call the real handler
+ */
+ la t3,IRQ_vectors
+ addiu a0,8
+ sll t2,a0,PTRLOG
+ addu t3,t2
+ LONG_L t3,(t3)
+ jalr t3
+ nop # delay slot
+ /*
+ * Unblock second pic
+ */
+ lb t1,%lo(PORT_BASE+0xa1)(s0)
+ lb t1,%lo(cache_A1)(s4)
+ nor s1,zero,s1
+ and t1,t1,s1
+ sb t1,%lo(cache_A1)(s4)
+ jr v0
+ sb t1,%lo(PORT_BASE+0xa1)(s0) # delay slot
+
+/*
+ * "Jump extender" to reach spurious_interrupt
+ */
+3: j spurious_interrupt
+ nop # delay slot
+ END(deskstation_handle_int)
diff -u --recursive --new-file v2.1.43/linux/arch/mips/deskstation/io.c linux/arch/mips/deskstation/io.c
--- v2.1.43/linux/arch/mips/deskstation/io.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/deskstation/io.c Thu Jun 26 12:33:37 1997
@@ -0,0 +1,68 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Low level I/O functions for Jazz family machine.
+ *
+ * FIXME: This implementation fits the Tyne. How does the EISA rPC44 handle
+ * the eight high address bits?
+ */
+#include <linux/string.h>
+#include <asm/mipsconfig.h>
+#include <asm/addrspace.h>
+#include <asm/sni.h>
+
+/*
+ * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped
+ * for the processor.
+ */
+extern unsigned long isa_slot_offset;
+
+static unsigned char deskstation_readb(unsigned long addr)
+{
+ return *(volatile unsigned char *) (isa_slot_offset + addr);
+}
+
+static unsigned short deskstation_readw(unsigned long addr)
+{
+ return *(volatile unsigned short *) (isa_slot_offset + addr);
+}
+
+static unsigned int deskstation_readl(unsigned long addr)
+{
+ return *(volatile unsigned int *) (isa_slot_offset + addr);
+}
+
+static void deskstation_writeb(unsigned char val, unsigned long addr)
+{
+ *(volatile unsigned char *) (isa_slot_offset + addr) = val;
+}
+
+static void deskstation_writew(unsigned short val, unsigned long addr)
+{
+ *(volatile unsigned char *) (isa_slot_offset + addr) = val;
+}
+
+static void deskstation_writel(unsigned int val, unsigned long addr)
+{
+ *(volatile unsigned char *) (isa_slot_offset + addr) = val;
+}
+
+static void deskstation_memset_io(unsigned long addr, int val, unsigned long len)
+{
+ addr += isa_slot_offset;
+ memset((void *)addr, val, len);
+}
+
+static void deskstation_memcpy_fromio(unsigned long to, unsigned long from, unsigned long len)
+{
+ from += isa_slot_offset;
+ memcpy((void *)to, (void *)from, len);
+}
+
+static void deskstation_memcpy_toio(unsigned long to, unsigned long from, unsigned long len)
+{
+ to += isa_slot_offset;
+ memcpy((void *)to, (void *)from, len);
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/deskstation/reset.c linux/arch/mips/deskstation/reset.c
--- v2.1.43/linux/arch/mips/deskstation/reset.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/deskstation/reset.c Thu Jun 26 12:33:37 1997
@@ -0,0 +1,29 @@
+/*
+ * linux/arch/mips/deskstation/process.c
+ *
+ * Reset a Deskstation.
+ */
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+void deskstation_machine_restart(void)
+{
+ printk("Implement deskstation_machine_restart().\n");
+ printk("Press reset to continue.\n");
+ while(1);
+}
+
+void deskstation_machine_halt(void)
+{
+ printk("Implement deskstation_machine_halt().\n");
+ printk("Press reset to continue.\n");
+ while(1);
+}
+
+void deskstation_machine_power_off(void)
+{
+ printk("Implement dec_machine_power_off().\n");
+ printk("Press reset to continue.\n");
+ while(1);
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/deskstation/setup.c linux/arch/mips/deskstation/setup.c
--- v2.1.43/linux/arch/mips/deskstation/setup.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/deskstation/setup.c Thu Jun 26 12:33:37 1997
SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi
echo 'End of part 02'
echo 'File patch-2.1.44 is continued in part 03'
echo 03 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part01

#!/bin/sh
# This is a shell archive
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
# existing files will NOT be overwritten unless -c is specified
#
# This is part 01 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
#

if test -r _shar_seq_.tmp; then
echo 'Must unpack archives in sequence!'
echo Please unpack part `cat _shar_seq_.tmp` next
exit 1
fi
# ============= patch-2.1.44 ==============
if test -f 'patch-2.1.44' -a X"$1" != X"-c"; then
echo 'x - skipping patch-2.1.44 (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting patch-2.1.44 (Text)'


sed 's/^X//' << 'SHAR_EOF' > 'patch-2.1.44' &&

diff -u --recursive --new-file v2.1.43/linux/CREDITS linux/CREDITS
--- v2.1.43/linux/CREDITS Mon Jun 16 16:35:52 1997
+++ linux/CREDITS Mon Jul 7 08:19:59 1997
@@ -1055,8 +1055,9 @@
X S: Finland
X
X N: Jonathan Naylor
-E: j...@cs.nott.ac.uk
+E: g4...@g4klx.demon.co.uk
X E: g4...@amsat.org
+W: http://zone.pspt.fi/~jsn/
X D: AX.25, NET/ROM and ROSE amateur radio protocol suites
X D: CCITT X.25 PLP and LAPB.
X S: 24 Castle View Drive
diff -u --recursive --new-file v2.1.43/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.1.43/linux/Documentation/Configure.help Mon Jun 16 16:35:53 1997
+++ linux/Documentation/Configure.help Thu Jun 26 12:33:36 1997
@@ -287,17 +287,19 @@
X Linux. This may slow disk throughput by a few percent, but at least
X things will operate 100% reliably. If unsure, say Y.
X
-Intel 82371 PIIX (Triton I/II) DMA support
+Intel 82371 PIIX (Triton I/II), VIA VP-1 DMA support
X CONFIG_BLK_DEV_TRITON
X If your PCI system uses an IDE harddrive (as opposed to SCSI, say)
X and includes the Intel Triton I/II IDE interface chipset (i82371FB,
- i82371SB or i82371AB), you will want to enable this option to allow
- use of bus-mastering DMA data transfers. Read the comments at the
+ i82371SB or i82371AB), or the VIA VP-1 IDE interface chipset
+ (VT82C586), you will want to enable this option to allow use of
+ bus-mastering DMA data transfers. Read the comments at the
X beginning of drivers/block/triton.c and Documentation/ide.txt.
X You can get the latest version of the hdparm utility via
X ftp (user: anonymous) from
X sunsite.unc.edu/pub/Linux/kernel/patches/diskdrives/; it is
- used to tune your harddisk. It is safe to say Y to this question.
+ used to tune your harddisk.
+ It is safe to say Y to this question.
X
X Other IDE chipset support
X CONFIG_IDE_CHIPSETS
@@ -534,6 +536,19 @@
X proxy server). Chances are that you should use this on every machine
X being run as a router and not on any regular host. If unsure, say N.
X
+SYN flood protection
+CONFIG_SYN_COOKIES
+ Normal TCP/IP networking is open to an attack known as SYN flooding.
+ This attack prevents legitimate users from being able to connect to
+ your computer and requires very little work for the attacker.
+ SYN cookies provide protection against this type of attack. With
+ this option turned on the TCP/IP stack will use a cryptographic
+ challenge protocol known as SYN cookies to enable legitimate users
+ to continue to connect, even when your machine is under attack.
+ Note that SYN cookies aren't enabled per default, you need to add
+ echo 1 >/proc/sys/net/ipv4/tcp_syncookies to one of your startup scripts
+ (e.g. /etc/rc.local or /etc/rc.d/rc.local).
+
X Socket Security API Support (EXPERIMENTAL)
X CONFIG_NET_SECURITY
X Enable use of the socket security API. Note that Linux does not include
@@ -1324,7 +1339,7 @@
X networking available. This feature is experimental. Please see
X http://www.maths.unm.edu/~bradford/ltpc.html for support software.
X
-LocalTalk PC card support
+Apple/Farallon LocalTalk PC card support
X CONFIG_LTPC
X This allows you to use the AppleTalk PC card to connect to LocalTalk
X networks. The card is also known as the Farallon PhoneNet PC card.
@@ -1335,6 +1350,26 @@
X kernels, so choose Y or N, but not M for now.
X See README.ltpc in the drivers/net directory, and the web site
X http://www.math.unm.edu/~bradford/ltpc.html
+
+COPS LocalTalk PC card support
+CONFIG_COPS
+ This allows you to use the COPS AppleTalk card to connect to LocalTalk
+ networks. You also need version 1.3.3 or later of the netatalk package.
+ This driver is experimental, which means that it may not work.
+ In particular the module support is not yet working for the 2.1.xx
+ kernels, so choose Y or N, but not M for now.
+ See the web site http://www.math.unm.edu/~bradford/ltpc.html for localtalk
+ IP tools.
+
+Dayna firmware support
+CONFIG_COPS_DAYNA
+ Support COPS compatible cards with Dayna style firmware (Dayna DL2000/
+ Daynatalk/PC (half length), COPS LT-95, Farallon PhoneNET PC III)
+
+Tangent firmware support
+CONFIG_COPS_TANGENT
+ Support COPS compatible cards with Tangent style firmware (Tangent ATB_II,
+ Novell NL-1000, Daystar Digital LT-200
X
X Amateur Radio AX.25 Level 2
X CONFIG_AX25
diff -u --recursive --new-file v2.1.43/linux/Documentation/binfmt_misc.txt linux/Documentation/binfmt_misc.txt
--- v2.1.43/linux/Documentation/binfmt_misc.txt Mon Jun 16 16:35:53 1997
+++ linux/Documentation/binfmt_misc.txt Tue Jul 1 08:55:56 1997
@@ -1,5 +1,5 @@
X Kernel Support for miscellaneous (your favourite) Binary Formats v1.1
- ====================================================================
+ =====================================================================
X
X This Kernel feature allows to invoke almost (for restrictions see below) every
X program by simply typing it's name in the shell.
@@ -47,15 +47,18 @@
X - enable Java(TM)-support (like binfmt_java):
X echo ":Java:M::\xca\xfe\xba\xbe::/usr/local/bin/java:" > register
X echo :Applet:M::\<\!--applet::/usr/local/bin/appletviewer: > register
+
X - enable support for em86 (like binfmt_em86, for Alpha AXP only):
X echo ":i386:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:" > register
X echo ":i486:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:" > register
+
X - enable support for packed DOS applications (pre-configured dosemu hdimages):
X echo ":DEXE:M::\x0eDEX::/usr/bin/dosexec:" > register
+
X - enable support for DOS/Windows executables (using mzloader and dosemu/wine):
X echo ":DOSWin:M::MZ::/usr/sbin/mzloader:" > register
X echo ":DOS:E::com::/usr/sbin/mzloader:" > register
-
+ echo ":DOS2:E::exe::/usr/sbin/mzloader:" > register
X
X You can enable/disable binfmt_misc or one binary type by echoing 0 (to disable)
X or 1 (to enable) to /proc/sys/fs/binfmt_misc/status or /proc/.../the_name.
@@ -68,13 +71,12 @@
X HINTS:
X ======
X
-If your interpreter does not look at the PATH to determine the full name of the
-program, you need to invoke a wrapper-script (like the following for java) first:
+If you want to pass special arguments to your interpreter, you can
+write a wrapper script for it.
X
-#!/bin/sh
-FOO=`which $1` || exit 1
-shift
-/usr/local/bin/java $FOO ${1+$@}
+Your interpreter should NOT look in the PATH for the filename; the
+kernel passes it the full filename to use. Using the PATH can cause
+unexpected behaviour and be a security hazard.
X
X
X There is a web page about binfmt_misc at
diff -u --recursive --new-file v2.1.43/linux/Documentation/ioctl-number.txt linux/Documentation/ioctl-number.txt
--- v2.1.43/linux/Documentation/ioctl-number.txt Thu May 15 16:48:01 1997
+++ linux/Documentation/ioctl-number.txt Thu Jun 26 12:33:36 1997
@@ -91,6 +91,7 @@
X <mailto:nat...@nikhefk.nikhef.nl>
X 'c' all linux/comstats.h
X 'f' all linux/ext2_fs.h
+'k' all asm-sparc/kbio.h, asm-sparc64/kbio.h
X 'l' 00-3F linux/tcfs_fs.h in development:
X <http://mikonos.dia.unisa.it/tcfs>
X 'm' all linux/mtio.h conflict!
diff -u --recursive --new-file v2.1.43/linux/Documentation/m68k/amiboot.txt linux/Documentation/m68k/amiboot.txt
--- v2.1.43/linux/Documentation/m68k/amiboot.txt Tue May 13 22:41:00 1997
+++ linux/Documentation/m68k/amiboot.txt Mon Jul 7 08:18:53 1997
@@ -1,9 +1,9 @@
X
- Linux/m68k Amiga Bootstrap version 5.5
+ Linux/m68k Amiga Bootstrap version 5.6
X --------------------------------------
X
X Maintained by Geert Uytterhoeven (Geert.Uyt...@cs.kuleuven.ac.be)
-Last revised: March 27, 1997
+Last revised: June 12, 1997
X
X
X 0. Introduction
@@ -22,7 +22,7 @@
X first. Although the Installation Guide is getting a bit outdated, it's still a
X good starting point.
X
-Amiboot 5.5 is meant for Linux/m68k 2.0.x, 2.1.x or higher (kernel bootinfo
+Amiboot 5.6 is meant for Linux/m68k 2.0.x, 2.1.x or higher (kernel bootinfo
X interface versions 1.x and 2.x). Please use an older version for older kernels.
X
X
diff -u --recursive --new-file v2.1.43/linux/Documentation/networking/README.cops linux/Documentation/networking/README.cops
--- v2.1.43/linux/Documentation/networking/README.cops Wed Dec 31 16:00:00 1969
+++ linux/Documentation/networking/README.cops Thu Jun 26 12:33:36 1997
@@ -0,0 +1,39 @@
+README for the COPS LocalTalk Linux driver (cops.c).
+ By Jay Schulist <Jay.Sc...@spacs.k12.wi.us>
+
+This driver compiles well against 2.1.29 - 2.1.41.
+
+Building the driver from the cops-0.0*.tar.gz file.
+1. Untar the cops-0.0*.tar.gz it will make a directory called cops.
+2. Copy the cops-kernel.diff to /usr/src/ and then type patch -p0 < cops-kernel.diff
+3. In the cops driver directory type make install. It will copy the driver to
+ the linux/drivers/net directory.
+4. When you configure your kernel select Y or M for COPS LocalTalk PC support.
+ Also make sure you have choosen Appletalk support.
+5. Compile like usual and you should bet set.
+
+This driver has 2 modes and they are: Dayna mode and Tangent mode.
+Each mode corresponds with the type of card. It has been found
+that there are 2 main types of cards and all other cards are
+the same and just have different names or only have minor differences
+such as more IO ports. As this driver is tested it will
+become more clear on exactly what cards are supported. The driver
+defaults to using Dayna mode. To change the drivers mode if you build
+a driver with dual support use board_type=1 or board_type=2 for
+dayna and tangent in the insmod.
+
+Operation/loading of the driver.
+Use modprobe like this: /sbin/modprobe cops.o (IO #) (IRQ #)
+If you do not specify any options the driver will try and use the IO = 0x240,
+IRQ = 5. As of right now I would only use IRQ 5 for the card, if autoprobing.
+
+Use ifconfig like this: /sbin/ifconfig lt0 127.0.0.34 up
+
+You will need to configure atalkd with something like the following to make
+it work with the cops.c driver.
+
+dummy -seed -phase 2 -net 2000 -addr 2000.10 -zone "1033"
+lt0 -seed -phase 1 -net 1000 -addr 1000.50 -zone "1033"
+- Or -
+eth0 -seed -phase 2 -net 3000 -addr 3000.20 -zone "1033"
+lt0 -seed -phase 1 -net 1000 -addr 1000.50 -zone "1033"
diff -u --recursive --new-file v2.1.43/linux/Documentation/networking/ax25.txt linux/Documentation/networking/ax25.txt
--- v2.1.43/linux/Documentation/networking/ax25.txt Thu Feb 27 10:57:29 1997
+++ linux/Documentation/networking/ax25.txt Mon Jul 7 08:19:59 1997
@@ -1,6 +1,6 @@
X To use the amateur radio protocols within Linux you will need to get a
X suitable copy of the AX.25 Utilities. More detailed information about these
-and associated programs can be found on http://www.cs.nott.ac.uk/~jsn/.
+and associated programs can be found on http://zone.pspt.fi/~jsn/.
X
X For more information about the AX.25, NET/ROM and ROSE protocol stacks, see
X the AX25-HOWTO written by Terry Dawson <te...@perf.no.itg.telstra.com.au>
@@ -13,4 +13,4 @@
X
X Jonathan G4KLX
X
-j...@cs.nott.ac.uk
+g4...@g4klx.demon.co.uk
diff -u --recursive --new-file v2.1.43/linux/Documentation/networking/net-modules.txt linux/Documentation/networking/net-modules.txt
--- v2.1.43/linux/Documentation/networking/net-modules.txt Tue May 13 22:41:00 1997
+++ linux/Documentation/networking/net-modules.txt Thu Jun 26 12:33:36 1997
@@ -159,6 +159,13 @@
X (Probes ports: 0x378, 0x278, 0x3BC;
X fixed IRQs: 5 and 7 )
X
+cops.c:
+ io = 0x240
+ irq = 5
+ nodeid = 0 (AutoSelect = 0, NodeID 1-254 is hand selected.)
+ (Probes ports: 0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260,
+ 0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360)
+
X de4x5.c:
X io = 0x000b
X irq = 10
diff -u --recursive --new-file v2.1.43/linux/Documentation/networking/x25.txt linux/Documentation/networking/x25.txt
--- v2.1.43/linux/Documentation/networking/x25.txt Thu Jan 2 05:13:24 1997
+++ linux/Documentation/networking/x25.txt Mon Jul 7 08:19:59 1997
@@ -41,5 +41,4 @@
X
X Jonathan
X
-j...@cs.nott.ac.uk
X g4...@g4klx.demon.co.uk
diff -u --recursive --new-file v2.1.43/linux/MAINTAINERS linux/MAINTAINERS
--- v2.1.43/linux/MAINTAINERS Mon Jun 16 16:35:53 1997
+++ linux/MAINTAINERS Thu Jun 26 12:33:36 1997
@@ -260,6 +260,13 @@
X L: linu...@vger.rutgers.edu
X S: Maintained
X
+MIPS:
+P: Ralf Baechle
+M: ra...@gnu.ai.mit.edu
+W: http://lena.fnet.fr/
+L: linux...@fnet.fr
+S: Maintained
+
X NCP FILESYSTEM:
X P: Volker Lendecke
X M: lend...@Math.Uni-Goettingen.de
diff -u --recursive --new-file v2.1.43/linux/Makefile linux/Makefile
--- v2.1.43/linux/Makefile Mon Jun 16 16:35:53 1997
+++ linux/Makefile Thu Jun 26 12:33:36 1997
@@ -1,6 +1,6 @@
X VERSION = 2
X PATCHLEVEL = 1
-SUBLEVEL = 43
+SUBLEVEL = 44
X
X ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
X
diff -u --recursive --new-file v2.1.43/linux/arch/alpha/defconfig linux/arch/alpha/defconfig
--- v2.1.43/linux/arch/alpha/defconfig Tue May 13 22:41:00 1997
+++ linux/arch/alpha/defconfig Tue Jul 1 23:23:47 1997
@@ -83,6 +83,7 @@
X # CONFIG_IP_ACCT is not set
X # CONFIG_IP_ROUTER is not set
X # CONFIG_NET_IPIP is not set
+# CONFIG_SYN_COOKIES is not set
X
X #
X # (it is safe to leave these untouched)
@@ -194,20 +195,22 @@


X # Filesystems
X #

X # CONFIG_QUOTA is not set


+# CONFIG_DCACHE_PRELOAD is not set
+# CONFIG_OMIRR is not set
+# CONFIG_TRANS_NAMES is not set
X # CONFIG_MINIX_FS is not set
X CONFIG_EXT2_FS=y

-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y


+# CONFIG_FAT_FS is not set

+# CONFIG_MSDOS_FS is not set
X # CONFIG_VFAT_FS is not set
X # CONFIG_UMSDOS_FS is not set
X CONFIG_PROC_FS=y
-CONFIG_NFS_FS=y
-# CONFIG_ROOT_NFS is not set
+# CONFIG_NFS_FS is not set
X # CONFIG_NFSD is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
X # CONFIG_SMB_FS is not set
-CONFIG_ISO9660_FS=y
+# CONFIG_ISO9660_FS is not set


X # CONFIG_HPFS_FS is not set
X # CONFIG_SYSV_FS is not set

X # CONFIG_AFFS_FS is not set
@@ -245,3 +248,4 @@


X # Kernel hacking
X #

X # CONFIG_PROFILE is not set

+# CONFIG_MAGIC_SYSRQ is not set
diff -u --recursive --new-file v2.1.43/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c
--- v2.1.43/linux/arch/alpha/kernel/osf_sys.c Mon Jun 16 16:35:53 1997
+++ linux/arch/alpha/kernel/osf_sys.c Tue Jul 1 23:23:47 1997
@@ -295,7 +295,7 @@
X retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
X if (retval)
X goto out;
- retval = namei(NAM_FOLLOW_LINK, path, &inode);
+ retval = namei(path, &inode);
X if (retval)
X goto out;
X retval = -ENOSYS;
@@ -376,7 +376,7 @@
X struct file_operations *fops;
X int retval;
X
- retval = namei(NAM_FOLLOW_LINK, name, &inode);
+ retval = namei(name, &inode);
X if (retval)
X return retval;
X if (!S_ISBLK(inode->i_mode)) {
@@ -876,6 +876,9 @@
X return -EOPNOTSUPP;
X }
X
+/* Dummy functions for now */
+#define wrfpcr(x) do { } while (0)
+#define rdfpcr() 0
X
X asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer,
X unsigned long nbytes,
diff -u --recursive --new-file v2.1.43/linux/arch/i386/boot/compressed/Makefile linux/arch/i386/boot/compressed/Makefile
--- v2.1.43/linux/arch/i386/boot/compressed/Makefile Wed Apr 16 14:14:59 1997
+++ linux/arch/i386/boot/compressed/Makefile Thu Jun 26 12:33:36 1997
@@ -48,7 +48,7 @@
X
X
X piggy.o: $(SYSTEM)
- tmppiggy=/tmp/$$$$piggy; \
+ tmppiggy=_tmp_$$$$piggy; \
X rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
X $(OBJCOPY) $(SYSTEM) $$tmppiggy; \
X gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
diff -u --recursive --new-file v2.1.43/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.1.43/linux/arch/i386/defconfig Mon Jun 16 16:35:53 1997
+++ linux/arch/i386/defconfig Mon Jul 7 10:50:01 1997
@@ -80,6 +80,7 @@
X # CONFIG_IP_ACCT is not set
X # CONFIG_IP_ROUTER is not set
X # CONFIG_NET_IPIP is not set
+# CONFIG_SYN_COOKIES is not set
X
X #
X # (it is safe to leave these untouched)
@@ -194,11 +195,11 @@
X # CONFIG_DCACHE_PRELOAD is not set
X # CONFIG_OMIRR is not set
X # CONFIG_TRANS_NAMES is not set
-CONFIG_MINIX_FS=y
+# CONFIG_MINIX_FS is not set
X CONFIG_EXT2_FS=y
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y


+# CONFIG_FAT_FS is not set

+# CONFIG_MSDOS_FS is not set


+# CONFIG_VFAT_FS is not set

X # CONFIG_UMSDOS_FS is not set
X CONFIG_PROC_FS=y
X CONFIG_NFS_FS=y
@@ -207,7 +208,7 @@
X CONFIG_SUNRPC=y
X CONFIG_LOCKD=y
X # CONFIG_SMB_FS is not set
-CONFIG_ISO9660_FS=y
+# CONFIG_ISO9660_FS is not set


X # CONFIG_HPFS_FS is not set
X # CONFIG_SYSV_FS is not set

X # CONFIG_AFFS_FS is not set
diff -u --recursive --new-file v2.1.43/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v2.1.43/linux/arch/i386/kernel/entry.S Tue May 13 22:41:00 1997
+++ linux/arch/i386/kernel/entry.S Thu Jun 26 12:33:36 1997
@@ -526,6 +526,8 @@
X .long SYMBOL_NAME(sys_query_module)
X .long SYMBOL_NAME(sys_poll)
X .long SYMBOL_NAME(sys_nfsservctl)
- .rept NR_syscalls-169
+ .long SYMBOL_NAME(sys_setresgid) /* 170 */
+ .long SYMBOL_NAME(sys_getresgid)
+ .rept NR_syscalls-171
X .long SYMBOL_NAME(sys_ni_syscall)
X .endr
diff -u --recursive --new-file v2.1.43/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.1.43/linux/arch/i386/kernel/irq.c Mon Jun 16 16:35:53 1997
+++ linux/arch/i386/kernel/irq.c Mon Jun 30 15:57:04 1997
@@ -82,12 +82,13 @@
X if (irq_nr & 8) {
X inb(0xA1); /* DUMMY */
X outb(cached_A1,0xA1);
+ outb(0x62,0x20); /* Specific EOI to cascade */
X outb(0x20,0xA0);
X } else {
X inb(0x21); /* DUMMY */
X outb(cached_21,0x21);
+ outb(0x20,0x20);
X }
- outb(0x20,0x20);
X spin_unlock(&irq_controller_lock);
X }
X
@@ -207,7 +208,7 @@
X math_error();
X }
X
-static struct irqaction irq13 = { math_error_irq, 0, 0, "math error", NULL, NULL };
+static struct irqaction irq13 = { math_error_irq, 0, 0, "fpu", NULL, NULL };
X
X /*
X * IRQ2 is cascade interrupt to second interrupt controller
diff -u --recursive --new-file v2.1.43/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.1.43/linux/arch/i386/kernel/setup.c Thu May 15 16:48:01 1997
+++ linux/arch/i386/kernel/setup.c Mon Jun 30 15:57:14 1997
@@ -219,7 +219,7 @@
X request_region(0x40,0x20,"timer");
X request_region(0x80,0x10,"dma page reg");
X request_region(0xc0,0x20,"dma2");
- request_region(0xf0,0x10,"npu");
+ request_region(0xf0,0x10,"fpu");
X }
X
X static const char * i486model(unsigned int nr)
diff -u --recursive --new-file v2.1.43/linux/arch/m68k/amiga/amifb.c linux/arch/m68k/amiga/amifb.c
--- v2.1.43/linux/arch/m68k/amiga/amifb.c Mon Jun 16 16:35:53 1997
+++ linux/arch/m68k/amiga/amifb.c Mon Jul 7 08:18:53 1997
@@ -1307,7 +1307,6 @@
X */
X
X extern unsigned short ami_intena_vals[];
-extern void amiga_init_sound(void);
X
X /*
X * Support for Graphics Boards
@@ -1809,11 +1808,6 @@
X {
X int err, tag, i;
X u_long chipptr;
-
- /*
- * Our beloved beeper
- */
- amiga_init_sound();
X
X /*
X * Check for a Graphics Board
diff -u --recursive --new-file v2.1.43/linux/arch/m68k/amiga/config.c linux/arch/m68k/amiga/config.c
--- v2.1.43/linux/arch/m68k/amiga/config.c Mon Jun 16 16:35:53 1997
+++ linux/arch/m68k/amiga/config.c Mon Jul 7 08:18:53 1997
@@ -85,6 +85,7 @@
X static void amiga_debug_init(void);
X
X extern void amiga_video_setup(char *, int *);
+extern void amiga_init_sound(void);
X
X static struct console amiga_console_driver = {
X NULL, NULL, amiga_wait_key
@@ -799,14 +800,18 @@
X
X __initfunc(static void amiga_debug_init(void))
X {
- if (!strcmp( m68k_debug_device, "ser" )) {
- /* no initialization required (?) */
- amiga_console_driver.write = amiga_serial_console_write;
- } else if (!strcmp( m68k_debug_device, "mem" )) {
- amiga_savekmsg_init();
- amiga_console_driver.write = amiga_mem_console_write;
- }
- register_console(&amiga_console_driver);
+ if (!strcmp( m68k_debug_device, "ser" )) {
+ /* no initialization required (?) */
+ amiga_console_driver.write = amiga_serial_console_write;
+ } else if (!strcmp( m68k_debug_device, "mem" )) {
+ amiga_savekmsg_init();
+ amiga_console_driver.write = amiga_mem_console_write;
+ }
+ register_console(&amiga_console_driver);
+
+ /* our beloved beeper */
+ if (AMIGAHW_PRESENT(AMI_AUDIO))
+ amiga_init_sound();
X }
X
X
diff -u --recursive --new-file v2.1.43/linux/arch/m68k/amiga/cyberfb.c linux/arch/m68k/amiga/cyberfb.c
--- v2.1.43/linux/arch/m68k/amiga/cyberfb.c Tue May 13 22:41:02 1997
+++ linux/arch/m68k/amiga/cyberfb.c Mon Jul 7 08:18:53 1997
@@ -671,7 +671,7 @@
X * Rectangle Fill Solid
X */
X void Cyber_RectFill (u_short x, u_short y, u_short width, u_short height,
- u_short mode, u_short color)
+ u_short mode, u_short fcolor)
X {
X u_short blitcmd = S3_FILLEDRECT;
X
diff -u --recursive --new-file v2.1.43/linux/arch/m68k/atari/atakeyb.c linux/arch/m68k/atari/atakeyb.c
--- v2.1.43/linux/arch/m68k/atari/atakeyb.c Mon Jun 16 16:35:53 1997
+++ linux/arch/m68k/atari/atakeyb.c Mon Jul 7 08:18:53 1997
@@ -419,7 +419,7 @@
X * break_flag...
X * */
X int keyval = plain_map[scancode], keytyp;
-
+
X set_bit( scancode, broken_keys );
X self_test_last_rcv = jiffies;
X keyval = plain_map[scancode];
diff -u --recursive --new-file v2.1.43/linux/arch/m68k/boot/amiga/bootstrap.c linux/arch/m68k/boot/amiga/bootstrap.c
--- v2.1.43/linux/arch/m68k/boot/amiga/bootstrap.c Wed Apr 23 19:01:15 1997
+++ linux/arch/m68k/boot/amiga/bootstrap.c Mon Jul 7 08:18:53 1997
@@ -36,10 +36,12 @@
X #include <stdarg.h>
X #include <string.h>
X #include <sys/file.h>
-#include <sys/types.h>
X #include <unistd.h>
X
X /* required Linux/m68k include files */
+#define __KERNEL_STRICT_NAMES /* This is ugly, I know */
+#define _LINUX_POSIX_TYPES_H
+#include <asm/posix_types.h>
X #include <linux/a.out.h>
X #include <linux/elf.h>
X #include <asm/amigahw.h>
diff -u --recursive --new-file v2.1.43/linux/arch/m68k/boot/amiga/linuxboot.c linux/arch/m68k/boot/amiga/linuxboot.c
--- v2.1.43/linux/arch/m68k/boot/amiga/linuxboot.c Tue May 13 22:41:02 1997
+++ linux/arch/m68k/boot/amiga/linuxboot.c Mon Jul 7 08:18:53 1997
@@ -22,9 +22,11 @@
X * for more details.
X *
X * History:
+ * 11 Jun 1997 Fix for unpadded gzipped ramdisks with bootinfo interface
+ * version 1.0
X * 27 Mar 1997 FPU-less machines couldn't boot kernels that use bootinfo
X * interface version 1.0 (Geert)
- * 03 Feb 1997 Implemented kernel decompression (Geert, based on Roman's
+ * 3 Feb 1997 Implemented kernel decompression (Geert, based on Roman's
X * code for ataboot)
X * 30 Dec 1996 Reverted the CPU detection to the old scheme
X * New boot parameter override scheme (Geert)
@@ -55,7 +57,6 @@
X #include <stddef.h>
X #include <string.h>
X #include <errno.h>
-#include <sys/types.h>
X
X #include <linux/a.out.h>
X #include <linux/elf.h>
@@ -70,6 +71,10 @@
X #undef custom
X #define custom ((*(volatile struct CUSTOM *)(CUSTOM_PHYSADDR)))
X
+/* a.out linkage conventions */
+#undef SYMBOL_NAME_STR
+#define SYMBOL_NAME_STR(X) "_"#X
+
X /* temporary stack size */
X #define TEMP_STACKSIZE (256)
X
@@ -130,10 +135,9 @@
X static int add_bi_string(u_short tag, const u_char *s);
X static int check_bootinfo_version(const char *memptr);
X static void start_kernel(void (*startfunc)(), char *stackp, char *memptr,
- u_long start_mem, u_long mem_size, u_long rd_size,
- u_long kernel_size) __attribute__ ((noreturn));
+ u_long start_mem, u_long kernel_size, u_long rd_dest,
+ u_long rd_size) __attribute__ ((noreturn));
X asmlinkage u_long maprommed(void);
-asmlinkage u_long check346(void);
X #ifdef ZKERNEL
X static int load_zkernel(int fd);
X static int KRead(int fd, void *buf, int cnt);
@@ -682,7 +686,7 @@
X if (debugflag) {
X if (bi.ramdisk.size)
X Printf("RAM disk at 0x%08lx, size is %ldK\n",
- (u_long)memptr+kernel_size, bi.ramdisk.size>>10);
+ (u_long)memptr+kernel_size+bi_size, bi.ramdisk.size>>10);
X
X if (elf_kernel) {
X PutChar('\n');
@@ -703,11 +707,11 @@
X Printf("\nKernel entry is 0x%08lx\n", elf_kernel ? kexec_elf.e_entry :
X kexec.a_entry);
X
- Printf("ramdisk dest top is 0x%08lx\n", start_mem+mem_size);
+ Printf("ramdisk dest is 0x%08lx\n", bi.ramdisk.addr);
X Printf("ramdisk lower limit is 0x%08lx\n",
- (u_long)(memptr+kernel_size));
+ (u_long)memptr+kernel_size+bi_size);
X Printf("ramdisk src top is 0x%08lx\n",
- (u_long)(memptr+kernel_size)+rd_size);
+ (u_long)memptr+kernel_size+bi_size+rd_size);
X
X Puts("\nType a key to continue the Linux/m68k boot...");
X GetChar();
@@ -743,7 +747,7 @@
X
X /* execute the copy-and-go code (from CHIP RAM) */
X start_kernel(startfunc, (char *)stack+TEMP_STACKSIZE, memptr, start_mem,
- mem_size, rd_size, kernel_size);
+ kernel_size, bi.ramdisk.addr, rd_size);
X
X /* Clean up and exit in case of a failure */
X Fail:
@@ -1065,6 +1069,7 @@
X compat_bootinfo.memory[i].size = bi.memory[i].size;
X }
X if (bi.ramdisk.size) {
+ bi.ramdisk.addr &= 0xfffffc00;
X compat_bootinfo.ramdisk_size = (bi.ramdisk.size+1023)/1024;
X compat_bootinfo.ramdisk_addr = bi.ramdisk.addr;
X } else {
@@ -1151,14 +1156,14 @@
X */
X
X static void start_kernel(void (*startfunc)(), char *stackp, char *memptr,
- u_long start_mem, u_long mem_size, u_long rd_size,
- u_long kernel_size)
+ u_long start_mem, u_long kernel_size, u_long rd_dest,
+ u_long rd_size)
X {
X register void (*a0)() __asm("a0") = startfunc;
X register char *a2 __asm("a2") = stackp;
X register char *a3 __asm("a3") = memptr;
X register u_long a4 __asm("a4") = start_mem;
- register u_long d0 __asm("d0") = mem_size;
+ register u_long d0 __asm("d0") = rd_dest;
X register u_long d1 __asm("d1") = rd_size;
X register u_long d2 __asm("d2") = kernel_size;
X register u_long d3 __asm("d3") = bi_size;
@@ -1182,7 +1187,7 @@
X *
X * a3 = memptr
X * a4 = start_mem
- * d0 = mem_size
+ * d0 = rd_dest
X * d1 = rd_size
X * d2 = kernel_size
X * d3 = bi_size
@@ -1210,18 +1215,16 @@
X dbra d7,1b | *dest++ = *src++
X
X | /* copy the ramdisk to the top of memory */
- | /* (from back to front) */
- movel a4,a1 | dest = (u_long *)(start_mem+mem_size);
- addl d0,a1
- movel a3,a2 | limit = (u_long *)(memptr+kernel_size +
- addl d2,a2 | bi_size);
- addl d3,a2
- movel a2,a0 | src = (u_long *)((u_long)limit+rd_size);
- addl d1,a0
+ movel a3,a0 | src = (u_long *)(memptr+kernel_size+bi_size);
+ addl d2,a0
+ addl d3,a0
+ movel d0,a1 | dest = (u_long *)rd_dest;
+ movel a0,a2 | limit = (u_long *)(memptr+kernel_size+
+ addl d1,a2 | bi_size+rd_size);
X 1: cmpl a0,a2
- beqs 2f | while (src > limit)
- moveb a0@-,a1@- | *--dest = *--src;
- bras 1b
+ jeq 2f | while (src > limit)
+ moveb a0@+,a1@+ | *dest++ = *src++;
+ jra 1b
X 2:
X | /* jump to start of kernel */
X movel a4,a0 | jump_to (start_mem);
diff -u --recursive --new-file v2.1.43/linux/arch/m68k/config.in linux/arch/m68k/config.in
--- v2.1.43/linux/arch/m68k/config.in Wed Apr 23 19:01:15 1997
+++ linux/arch/m68k/config.in Mon Jul 7 08:18:53 1997
@@ -52,6 +52,10 @@


X bool 'Sysctl support' CONFIG_SYSCTL

X tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
X tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF


+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then

+ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+fi
+
X if [ "$CONFIG_AMIGA" = "y" ]; then
X bool 'Amiga AutoConfig Identification' CONFIG_ZORRO
X bool 'Amiga OCS chipset support' CONFIG_AMIFB_OCS
@@ -153,6 +157,7 @@
X bool 'A4000T SCSI support' CONFIG_A4000T_SCSI
X bool 'A4091 SCSI support' CONFIG_A4091_SCSI
X bool 'WarpEngine SCSI support' CONFIG_WARPENGINE_SCSI
+ bool 'GVP Turbo 040/060 SCSI support' CONFIG_GVP_TURBO_SCSI
X fi
X fi
X if [ "$CONFIG_ATARI" = "y" ]; then
@@ -273,5 +278,6 @@


X if [ "$CONFIG_PROFILE" = "y" ]; then
X int ' Profile shift count' CONFIG_PROFILE_SHIFT 2

X fi
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
X bool 'Remote debugging support' CONFIG_KGDB
X endmenu
diff -u --recursive --new-file v2.1.43/linux/arch/m68k/console/fbcon.c linux/arch/m68k/console/fbcon.c
--- v2.1.43/linux/arch/m68k/console/fbcon.c Mon Jun 16 16:35:53 1997
+++ linux/arch/m68k/console/fbcon.c Mon Jul 7 08:18:53 1997
@@ -97,7 +97,6 @@
X #undef CONFIG_FBCON_CYBER
X #undef CONFIG_FBCON_RETINAZ3
X
-
X /* Monochrome is default */
X
X #define CONFIG_FBCON_MONO
@@ -450,14 +449,17 @@
X int count, int yy, int xx);
X static void rev_char_cyber(struct display *p, int xx, int yy);
X
-extern void Cyber_WaitQueue(u_short fifo);
+extern void Cyber_WaitQueue(unsigned short fifo);
X extern void Cyber_WaitBlit(void);
-extern void Cyber_BitBLT(u_short curx, u_short cury, u_short destx,
- u_short desty, u_short width, u_short height,
- u_short mode);
-extern void Cyber_RectFill(u_short xx, u_short yy, u_short width, u_short height,
- u_short mode, u_short color);
-extern void Cyber_MoveCursor(u_short xx, u_short yy);
+extern void Cyber_BitBLT(unsigned short curx, unsigned short cury,
+ unsigned short destx, unsigned short desty,
+ unsigned short width, unsigned short height,
+ unsigned short mode);
+extern void Cyber_RectFill(unsigned short xx, unsigned short yy,
+ unsigned short width, unsigned short
+ height, unsigned short mode,
+ unsigned short fcolor);
+extern void Cyber_MoveCursor(unsigned short xx, unsigned short yy);
X #endif /* CONFIG_FBCON_CYBER */
X
X #ifdef CONFIG_FBCON_RETINAZ3
@@ -3835,7 +3837,7 @@
X
X c &= 0xff;
X
- dest = p->screen_base+y*p->fontheight*p->next_line+8*x;
+ dest = p->screen_base + yy * p->fontheight * p->next_line + 8 * xx;
X cdat = p->fontdata+(c*p->fontheight);
X fg = disp->fgcol;
X bg = disp->bgcol;
@@ -3874,7 +3876,7 @@
X u_char c, d;
X u_char fg, bg;
X
- dest0 = p->screen_base+y*p->fontheight*p->next_line+8*x;
+ dest0 = p->screen_base + yy * p->fontheight * p->next_line + 8 * xx;
X fg = disp->fgcol;
X bg = disp->bgcol;
X revs = conp->vc_reverse;
@@ -3918,7 +3920,7 @@
X fg = disp->fgcol;
X bg = disp->bgcol;
X
- dest = p->screen_base+y*p->fontheight*p->next_line+8*x;
+ dest = p->screen_base + yy * p->fontheight * p->next_line + 8 * xx;
X Cyber_WaitBlit();
X for (rows = p->fontheight; rows--; dest += p->next_line) {
X *dest = (*dest == fg) ? bg : fg;
diff -u --recursive --new-file v2.1.43/linux/arch/m68k/defconfig linux/arch/m68k/defconfig
--- v2.1.43/linux/arch/m68k/defconfig Wed Apr 23 19:01:15 1997
+++ linux/arch/m68k/defconfig Mon Jul 7 08:18:53 1997
@@ -152,6 +152,9 @@


X # Filesystems
X #

X # CONFIG_QUOTA is not set


+# CONFIG_DCACHE_PRELOAD is not set
+# CONFIG_OMIRR is not set
+# CONFIG_TRANS_NAMES is not set

X CONFIG_MINIX_FS=y
X CONFIG_EXT2_FS=y
X CONFIG_FAT_FS=y
diff -u --recursive --new-file v2.1.43/linux/arch/m68k/ifpsp060/iskeleton.S linux/arch/m68k/ifpsp060/iskeleton.S
--- v2.1.43/linux/arch/m68k/ifpsp060/iskeleton.S Sat May 24 09:10:22 1997
+++ linux/arch/m68k/ifpsp060/iskeleton.S Thu Jun 26 12:33:36 1997
@@ -35,24 +35,7 @@
X |
X
X #include <linux/linkage.h>
-
-/*
- * This has to match entry.S
- */
-LOFF_ORIG_D0 = 0x24
-
-#define curptr a2
-
-#define SAVE_ALL \
- clrl %sp@-; /* stk_adj */ \
- movel %d0,%sp@-; /* orig d0 */ \
- movel %d0,%sp@-; /* d0 */ \
- moveml %d1-%d5/%a0-%a1/%curptr,%sp@-;
-
-#define GET_CURRENT(tmp) \
- movel %sp,tmp; \
- andw &-8192,tmp; \
- movel tmp,%curptr;
+#include <asm/entry.h>
X
X |################################
X | (1) EXAMPLE CALL-OUTS #
@@ -92,9 +75,8 @@
X bne Lmustsched
X rte
X Lmustsched:
- SAVE_ALL
- moveq #-1,%d0
- movel %d0,%sp@(LOFF_ORIG_D0) | indicate stack frame not for syscall
+ SAVE_ALL_INT
+
X GET_CURRENT(%d0)
X bral SYMBOL_NAME(ret_from_exception) | deliver signals, reschedule etc..
X
diff -u --recursive --new-file v2.1.43/linux/arch/m68k/kernel/console.c linux/arch/m68k/kernel/console.c
--- v2.1.43/linux/arch/m68k/kernel/console.c Mon Jun 16 16:35:53 1997
+++ linux/arch/m68k/kernel/console.c Mon Jul 7 08:18:53 1997
@@ -109,6 +109,7 @@
X #include <linux/interrupt.h>
X #include <linux/tty.h>
X #include <linux/tty_flip.h>
+#include <linux/console.h>
X #include <linux/kernel.h>
X #include <linux/string.h>
X #include <linux/errno.h>
@@ -164,9 +165,12 @@
X void poke_blanked_console(void);
X void do_blank_screen(int);
X
+#if 0
+/* Make sure there are no references left to this variables. */
X unsigned long video_num_lines;
X unsigned long video_num_columns;
X unsigned long video_size_row;
+#endif
X
X static int printable = 0; /* Is console ready for printing? */
X unsigned long video_font_height; /* Height of current screen font */
diff -u --recursive --new-file v2.1.43/linux/arch/m68k/mm/memory.c linux/arch/m68k/mm/memory.c
--- v2.1.43/linux/arch/m68k/mm/memory.c Mon Jun 16 16:35:54 1997
+++ linux/arch/m68k/mm/memory.c Mon Jul 7 08:18:53 1997
@@ -555,16 +555,18 @@
X int tmp;
X
X /*
- * cwe need special treatment for the first page, in case it
- * is not page-aligned.
+ * We need special treatment for the first page, in case it
+ * is not page-aligned. Page align the addresses to work
+ * around bug I17 in the 68060.
X */
X if ((tmp = -paddr & (PAGE_SIZE - 1))) {
- pushcl040(paddr);
+ pushcl040(paddr & PAGE_MASK);
X if ((len -= tmp) <= 0)
X return;
X paddr += tmp;
X }
X tmp = PAGE_SIZE;
+ paddr &= PAGE_MASK;
X while ((len -= tmp) >= 0) {
X clear040(paddr);
X paddr += tmp;
@@ -600,6 +602,13 @@
X * the '060!
X */
X len += paddr & (PAGE_SIZE - 1);
+
+ /*
+ * Work around bug I17 in the 68060 affecting some instruction
+ * lines not being invalidated properly.
+ */
+ paddr &= PAGE_MASK;
+
X do {
X pushcli040(paddr);
X paddr += tmp;
@@ -638,6 +647,13 @@
X
X /* on 68040, push cache lines for pages in the range */
X len += vaddr & (PAGE_SIZE - 1);
+
+ /*
+ * Work around bug I17 in the 68060 affecting some instruction
+ * lines not being invalidated properly.
+ */
+ vaddr &= PAGE_MASK;
+
X do {
X pushv040(vaddr);
X vaddr += tmp;
diff -u --recursive --new-file v2.1.43/linux/arch/mips/Makefile linux/arch/mips/Makefile
--- v2.1.43/linux/arch/mips/Makefile Wed Dec 13 02:39:42 1995
+++ linux/arch/mips/Makefile Mon Jul 7 08:18:53 1997
@@ -10,36 +10,32 @@
X # License. See the file "COPYING" in the main directory of this archive
X # for more details.
X #
-# Copyright (C) 1994, 1995 by Ralf Baechle
+# Copyright (C) 1994, 1995, 1996 by Ralf Baechle
+# DECStation modifications by Paul M. Antoine, 1996
+#
+# $Id: Makefile,v 1.7 1997/06/30 15:52:03 ralf Exp $
X #
X
+#
+# Select the object file format to substitute into the linker script.
+#
X ifdef CONFIG_CPU_LITTLE_ENDIAN
-prefix = mipsel-
-oformat = a.out-mips-little-linux
+CROSS_COMPILE = mipsel-linux-
+ifdef CONFIG_MIPS_ECOFF
+oformat = ecoff-littlemips
X else
-prefix = mips-
-oformat = a.out-mips-big-linux
+oformat = elf32-littlemips
X endif
-
-ifdef CONFIG_EXTRA_ELF_COMPILER
-prefix := $(prefix)linuxelf-
X else
-prefix := $(prefix)linux-
+CROSS_COMPILE = mips-linux-
+ifdef CONFIG_MIPS_ECOFF
+oformat = ecoff-bigmips
+else
+oformat = elf32-bigmips
+endif
X endif
X
-AS = $(prefix)as
-LD = $(prefix)ld
-LINKFLAGS = -N -Ttext 0x80000000
-#LINKFLAGS = -oformat=$(oformat) -N -Ttext 0x80000000
-#HOSTCC = gcc
-CC = $(prefix)gcc -D__KERNEL__ -I$(TOPDIR)/include
-CPP = $(CC) -E $(CFLAGS)
-AR = $(prefix)ar
-RANLIB = $(prefix)ranlib
-OBJCOPY = $(prefix)objcopy
-OBJDUMP = $(prefix)objdump
-STRIP = $(prefix)strip
-NM = $(prefix)nm
+LINKFLAGS = -static -N
X
X #
X # The new ELF GCC uses -G0 -mabicalls -fpic as default. We don't need PIC
@@ -47,46 +43,127 @@
X # old GCC these options are just the defaults. At some point we might
X # make use of global pointer optimizations.
X #
+# The DECStation requires an ECOFF kernel for remote booting, other MIPS
+# machines may also.
+#
X ifdef CONFIG_ELF_KERNEL
-CFLAGS := $(CFLAGS) -G0 -mno-abicalls -fno-pic
-LINKFLAGS += -T arch/mips/ld.script
+CFLAGS += -G 0 -mno-abicalls -fno-pic
+LINKFLAGS += -G 0
+endif
+ifdef CONFIG_ECOFF_KERNEL
+CFLAGS += -G 0 -mno-abicalls -fno-pic
+LINKFLAGS += -G 0 -oformat ecoff-littlemips
X endif
X
X ifdef CONFIG_REMOTE_DEBUG
X CFLAGS := $(CFLAGS) -g
X endif
X
+#
+# CPU dependand compiler/assembler options for optimization.
+#
X ifdef CONFIG_CPU_R3000
X CFLAGS := $(CFLAGS) -mcpu=r3000 -mips1
-#ASFLAGS := $(ASFLAGS) -mcpu=r3000 -mips1
X endif
X ifdef CONFIG_CPU_R6000
X CFLAGS := $(CFLAGS) -mcpu=r6000 -mips2
-#ASFLAGS := $(ASFLAGS) -mcpu=r6000 -mips2
+endif
+ifdef CONFIG_CPU_R4300
+CFLAGS := $(CFLAGS) -mcpu=r4600 -Wa,-mcpu=vr4300 -mips2
X endif
X ifdef CONFIG_CPU_R4X00
-CFLAGS := $(CFLAGS) -D__R4000__ -mcpu=r4400 -mips2
-#ASFLAGS := $(ASFLAGS) -mcpu=r4400 -mips2
+CFLAGS := $(CFLAGS) -mcpu=r4600 -mips2
X endif
-ifdef CONFIG_CPU_R4600
-CFLAGS := $(CFLAGS) -D__R4000__ -mcpu=r4600 -mips2
-#ASFLAGS := $(ASFLAGS) -mcpu=r4600 -mips2
+ifdef CONFIG_CPU_R5000
+CFLAGS := $(CFLAGS) -mcpu=r8000 -mips2
X endif
X ifdef CONFIG_CPU_R8000
-CFLAGS := $(CFLAGS) -D__R4000__ -mcpu=r8000 -mips2
-#ASFLAGS := $(ASFLAGS) -mcpu=r8000 -mips2
+CFLAGS := $(CFLAGS) -mcpu=r8000 -mips2
X endif
X ifdef CONFIG_CPU_R10000
-CFLAGS := $(CFLAGS) -D__R4000__ -mcpu=r8000 -mips2
-#ASFLAGS := $(ASFLAGS) -mcpu=r8000 -mips2
+CFLAGS := $(CFLAGS) -mcpu=r8000 -mips2
+endif
+
+#
+# Board dependand options and extra files
+#
+ifdef CONFIG_ALGOR_P4032
+CORE_FILES += arch/mips/algor/algor.o
+SUBDIRS += arch/mips/algor
+#LOADADDR += 0x80000000
+endif
+ifdef CONFIG_DECSTATION
+CORE_FILES += arch/mips/dec/dec.o
+SUBDIRS += arch/mips/dec
+LINKSCRIPT += arch/mips/dec/ld.script
+LOADADDR += 0x80000000
+endif
+ifdef CONFIG_DESKSTATION_RPC44
+CORE_FILES += arch/mips/deskstation/deskstation.o
+SUBDIRS += arch/mips/deskstation
+LOADADDR += 0x80100000
+endif
+ifdef CONFIG_DESKSTATION_TYNE
+CORE_FILES += arch/mips/deskstation/deskstation.o
+SUBDIRS += arch/mips/deskstation
+LOADADDR += 0x80000000
+endif
+#
+# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
+#
+ifdef CONFIG_MIPS_JAZZ
+CORE_FILES += arch/mips/jazz/jazz.o
+SUBDIRS += arch/mips/jazz
+LOADADDR += 0x80000000
+endif
+ifdef CONFIG_MIPS_MAGNUM_3000
+LOADADDR += 0x80000000
+endif
+ifdef CONFIG_SNI_RM200_PCI
+CORE_FILES += arch/mips/sni/sni.o
+SUBDIRS += arch/mips/sni
+LOADADDR += 0x80000000
+endif
+ifdef CONFIG_SGI
+LIBS += arch/mips/sgi/kernel/sgikern.a arch/mips/sgi/prom/promlib.a
+SUBDIRS += arch/mips/sgi/kernel arch/mips/sgi/prom
+#
+# Set LOADADDR to >= 0x88069000 if you want to leave space for symmon,
+# 0x88002000 for production kernels. Note that the value must be
+# 8kb aligned or the handling of the current variable will break.
+#
+LOADADDR += 0x88002000
+HOSTCC = cc
X endif
X
-CFLAGS := $(CFLAGS) -pipe
+#
+# Choosing incompatible machines durings configuration will result in
+# error messages during linking. Select a default linkscript if
+# none has been choosen above.
+#
+ifndef LINKSCRIPT
+ifndef CONFIG_CPU_LITTLE_ENDIAN
+LINKSCRIPT = arch/mips/ld.script.big
+else
+LINKSCRIPT = arch/mips/ld.script.little
+endif
+endif
+LINKFLAGS += -T $(word 1,$(LINKSCRIPT))
+
+ifdef LOADADDR
+LINKFLAGS += -Ttext $(word 1,$(LOADADDR))
+endif
+
+#
+# The pipe options is bad for my low-mem machine
+# Uncomment this if you want this.
+#
+CFLAGS += -pipe
X
-HEAD := arch/mips/kernel/head.o
+HEAD := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
X
-SUBDIRS := $(SUBDIRS) arch/mips/kernel arch/mips/mm arch/mips/lib
-ARCHIVES := arch/mips/kernel/kernel.o arch/mips/mm/mm.o $(ARCHIVES)
+SUBDIRS := $(SUBDIRS) $(addprefix arch/mips/, kernel mm lib tools)
+CORE_FILES := arch/mips/kernel/kernel.o arch/mips/mm/mm.o $(CORE_FILES)
X LIBS := arch/mips/lib/lib.a $(LIBS) arch/mips/lib/lib.a
X
X MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
@@ -102,6 +179,7 @@
X archclean:
X @$(MAKEBOOT) clean
X $(MAKE) -C arch/$(ARCH)/kernel clean
+ $(MAKE) -C arch/$(ARCH)/tools clean
X
X archdep:
X @$(MAKEBOOT) dep
diff -u --recursive --new-file v2.1.43/linux/arch/mips/boot/Makefile linux/arch/mips/boot/Makefile
--- v2.1.43/linux/arch/mips/boot/Makefile Thu Apr 11 23:49:30 1996
+++ linux/arch/mips/boot/Makefile Thu Jun 26 12:33:36 1997
@@ -19,47 +19,32 @@
X # Drop some uninteresting sections in the kernel.
X # This is only relevant for ELF kernels but doesn't hurt a.out
X #
-DROP_SECTIONS = .reginfo .mdebug
-
-#
-# The new options of binutils 2.6 help to shrink object files a lot.
-# This is especially useful for booting from floppy. Though we
-# don't yet require everyone to have binutils 2.6 installed.
-#
-OBJDUMP_VERSION = $(word 4,$(shell $(OBJDUMP) --version))
-ifneq ($(OBJDUMP_VERSION),2.5.2)
-KEEP = kernel_entry boot_info screen_info _end
-STRIP_FLAGS = $(addprefix --keep-symbol=,$(KEEP))
-else
-STRIP_FLAGS = --discard-all
-endif
+drop-sections = .reginfo .mdebug
+strip-flags = $(addprefix --remove-section=,$(drop-sections))
X
X #
X # Fake compressed boot
X #
-ifdef CONFIG_ELF_KERNEL
-zImage: $(CONFIGURE) $(TOPDIR)/vmlinux
- cp $(TOPDIR)/vmlinux zImage.tmp
- $(STRIP) $(addprefix --remove-section=,$(DROP_SECTIONS)) \
- --strip-symbol=blurb zImage.tmp
- $(LD) -oformat=$(oformat) -N -e except_vec0 -Ttext=0x80000000 \
- -o zImage zImage.tmp
+zImage: $(CONFIGURE) mkboot $(TOPDIR)/vmlinux
+ $(OBJCOPY) $(strip-flags) $(TOPDIR)/vmlinux zImage.tmp
+ ./mkboot zImage.tmp zImage
X rm -f zImage.tmp
- $(STRIP) $(STRIP_FLAGS) zImage
-else
-zImage: $(CONFIGURE) $(TOPDIR)/vmlinux
- cp $(TOPDIR)/vmlinux $@
- $(STRIP) $(STRIP_FLAGS) $@
-endif
+
+mkboot: mkboot.c
+ $(HOSTCC) -o $@ $^
X
X zdisk: zImage
- mcopy -n zImage a:vmlinux
+ if [ -f /etc/remote-mcopy ]; then \
+ ssh rio mcopy -o - a:vmlinux <zImage; \
+ else \
+ mcopy -o zImage a:vmlinux; \
+ fi
X
X dep:
X $(CPP) -M *.[cS] > .depend
X
X clean:
- rm -f zImage zImage.tmp
+ rm -f zImage zImage.tmp mkboot
X
X dummy:
X
diff -u --recursive --new-file v2.1.43/linux/arch/mips/boot/mkboot.c linux/arch/mips/boot/mkboot.c
--- v2.1.43/linux/arch/mips/boot/mkboot.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/boot/mkboot.c Thu Jun 26 12:33:36 1997
@@ -0,0 +1,659 @@
+/*
+ * Make a bootable image from a Linux/MIPS kernel.


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 by Ralf Baechle

+ *
+ * This file is written in plain Kernighan & Ritchie C as it has to run
+ * on all crosscompile hosts no matter how braindead. This code might
+ * also become part of Milo. It's therefore important that we don't use
+ * seek because the Seek() call of the Magnum 4000 ARC BIOS is broken.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/*
+ * Define this for verbose debugging output.
+ */
+#undef VERBOSE
+
+/*
+ * Don't use the host's elf.h - it might be using incompatible defines
+ */
+
+#define EI_NIDENT 16
+
+/*
+ * Basic ELF types.
+ */
+typedef unsigned short Elf32_Half;
+typedef unsigned short Elf32_Section;
+typedef unsigned int Elf32_Word;
+typedef unsigned int Elf32_Addr;
+typedef unsigned int Elf32_Off;
+
+typedef struct
+{
+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
+ Elf32_Half e_type; /* Object file type */
+ Elf32_Half e_machine; /* Architecture */
+ Elf32_Word e_version; /* Object file version */
+ Elf32_Addr e_entry; /* Entry point virtual address */
+ Elf32_Off e_phoff; /* Program header table file offset */
+ Elf32_Off e_shoff; /* Section header table file offset */
+ Elf32_Word e_flags; /* Processor-specific flags */
+ Elf32_Half e_ehsize; /* ELF header size in bytes */
+ Elf32_Half e_phentsize; /* Program header table entry size */
+ Elf32_Half e_phnum; /* Program header table entry count */
+ Elf32_Half e_shentsize; /* Section header table entry size */
+ Elf32_Half e_shnum; /* Section header table entry count */
+ Elf32_Half e_shstrndx; /* Section header string table index */
+} Elf32_Ehdr;
+
+/*
+ * ELF magic number
+ */
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define EI_CLASS 4 /* File class byte index */
+#define ELFCLASSNONE 0 /* Invalid class */
+#define ELFCLASS32 1 /* 32-bit objects */
+#define ELFCLASS64 2 /* 64-bit objects */
+
+#define EI_DATA 5 /* Data encoding byte index */
+#define ELFDATA2LSB 1 /* 2's complement, little endian */
+#define ELFDATA2MSB 2 /* 2's complement, big endian */
+
+#define EI_VERSION 6 /* File version byte index */
+#define EV_CURRENT 1 /* Current version */
+
+/*
+ * Acceptable machine type in e_machine.
+ */
+#define EM_MIPS 8 /* MIPS R3000 big-endian */
+#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
+
+/*
+ * The type of ELF file we accept.
+ */
+#define ET_EXEC 2 /* Executable file */
+
+/*
+ * Definition of a single program header structure
+ */
+typedef struct
+{
+ Elf32_Word p_type; /* Segment type */
+ Elf32_Off p_offset; /* Segment file offset */
+ Elf32_Addr p_vaddr; /* Segment virtual address */
+ Elf32_Addr p_paddr; /* Segment physical address */
+ Elf32_Word p_filesz; /* Segment size in file */
+ Elf32_Word p_memsz; /* Segment size in memory */
+ Elf32_Word p_flags; /* Segment flags */
+ Elf32_Word p_align; /* Segment alignment */
+} Elf32_Phdr;
+
+/*
+ * Legal values for p_type
+ */
+#define PT_NULL 0 /* Program header table entry unused */
+#define PT_LOAD 1 /* Loadable program segment */
+#define PT_DYNAMIC 2 /* Dynamic linking information */
+#define PT_INTERP 3 /* Program interpreter */
+#define PT_NOTE 4 /* Auxiliary information */
+#define PT_SHLIB 5 /* Reserved */
+#define PT_PHDR 6 /* Entry for header table itself */
+#define PT_NUM 7 /* Number of defined types. */
+#define PT_LOPROC 0x70000000 /* Start of processor-specific */
+#define PT_HIPROC 0x7fffffff /* End of processor-specific */
+
+typedef struct
+{
+ Elf32_Word sh_name; /* Section name (string tbl index) */
+ Elf32_Word sh_type; /* Section type */
+ Elf32_Word sh_flags; /* Section flags */
+ Elf32_Addr sh_addr; /* Section virtual addr at execution */
+ Elf32_Off sh_offset; /* Section file offset */
+ Elf32_Word sh_size; /* Section size in bytes */
+ Elf32_Word sh_link; /* Link to another section */
+ Elf32_Word sh_info; /* Additional section information */
+ Elf32_Word sh_addralign; /* Section alignment */
+ Elf32_Word sh_entsize; /* Entry size if section holds table */
+} Elf32_Shdr;
+
+typedef struct
+{
+ Elf32_Word st_name; /* Symbol name (string tbl index) */
+ Elf32_Addr st_value; /* Symbol value */
+ Elf32_Word st_size; /* Symbol size */
+ unsigned char st_info; /* Symbol type and binding */
+ unsigned char st_other; /* No defined meaning, 0 */
+ Elf32_Section st_shndx; /* Section index */
+} Elf32_Sym;
+
+/* How to extract and insert information held in the st_info field. */
+#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val) ((val) & 0xf)
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding). */
+#define STB_GLOBAL 1 /* Global symbol */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
+#define STT_NOTYPE 0 /* Symbol type is unspecified */
+#define STT_OBJECT 1 /* Symbol is a data object */
+#define STT_FUNC 2 /* Symbol is a code object */
+
+static unsigned int
+get_Elf32_Half(unsigned char *p)
+{
+ return p[0] | (p[1] << 8);
+}
+#define get_Elf32_Section(p) get_Elf32_Half(p)
+
+static unsigned int
+get_Elf32_Word(unsigned char *p)
+{
+ return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+#define get_Elf32_Addr(p) get_Elf32_Word(p)
+#define get_Elf32_Off(p) get_Elf32_Word(p)
+
+static void
+put_byte(p, x)
+ unsigned char *p;
+ unsigned char x;
+{
+ p[0] = x;
+}
+
+static void
+put_half(p, x)
+ unsigned char *p;
+ unsigned short x;
+{
+ p[0] = x & 0xff;
+ p[1] = (x >> 8) & 0xff;
+}
+
+static void
+put_word(p, x)
+ unsigned char *p;
+ unsigned long x;
+{
+ p[0] = x & 0xff;
+ p[1] = (x >> 8) & 0xff;
+ p[2] = (x >> 16) & 0xff;
+ p[3] = (x >> 24) & 0xff;
+}
+
+/*
+ * Swap a program header in.
+ */
+static void
+get_elfph(p, ph)
+ unsigned char *p;
+ Elf32_Phdr *ph;
+{
+ ph->p_type = get_Elf32_Word(p);
+ ph->p_offset = get_Elf32_Off(p + 4);
+ ph->p_vaddr = get_Elf32_Addr(p + 8);
+ ph->p_paddr = get_Elf32_Addr(p + 12);
+ ph->p_filesz = get_Elf32_Word(p + 16);
+ ph->p_memsz = get_Elf32_Word(p + 20);
+ ph->p_flags = get_Elf32_Word(p + 24);
+ ph->p_align = get_Elf32_Word(p + 28);
+}
+
+/*
+ * Swap a section header in.
+ */
+static void
+get_elfsh(p, sh)
+ unsigned char *p;
+ Elf32_Shdr *sh;
+{
+ sh->sh_name = get_Elf32_Word(p);
+ sh->sh_type = get_Elf32_Word(p + 4);
+ sh->sh_flags = get_Elf32_Word(p + 8);
+ sh->sh_addr = get_Elf32_Addr(p + 12);
+ sh->sh_offset = get_Elf32_Off(p + 16);
+ sh->sh_size = get_Elf32_Word(p + 20);
+ sh->sh_link = get_Elf32_Word(p + 24);
+ sh->sh_info = get_Elf32_Word(p + 28);
+ sh->sh_addralign = get_Elf32_Word(p + 32);
+ sh->sh_entsize = get_Elf32_Word(p + 36);
+}
+
+/*
+ * Swap a section header in.
+ */
+static void
+get_elfsym(p, sym)
+ unsigned char *p;
+ Elf32_Sym *sym;
+{
+ sym->st_name = get_Elf32_Word(p);
+ sym->st_value = get_Elf32_Addr(p + 4);
+ sym->st_size = get_Elf32_Word(p + 8);
+ sym->st_info = *(p + 12);
+ sym->st_other = *(p + 13);
+ sym->st_shndx = get_Elf32_Section(p + 14);
+}
+
+/*
+ * The a.out magic number
+ */
+#define OMAGIC 0407 /* Code indicating object file or impure executable. */
+#define M_MIPS1 151 /* MIPS R3000/R3000 binary */
+#define M_MIPS2 152 /* MIPS R6000/R4000 binary */
+
+/*
+ * Compute and return an a.out magic number.
+ */
+#define AOUT_INFO(magic, type, flags) \
+ (((magic) & 0xffff) | \
+ (((int)(type) & 0xff) << 16) | \
+ (((flags) & 0xff) << 24))
+
+/*
+ * a.out symbols
+ */
+#define N_UNDF 0
+#define N_ABS 2
+#define N_TEXT 4
+#define N_DATA 6
+#define N_BSS 8
+#define N_FN 15
+#define N_EXT 1
+
+#define min(x,y) (((x)<(y))?(x):(y))
+
+static void
+do_read(fd, buf, size)
+ int fd;
+ char *buf;
+ ssize_t size;
+{
+ ssize_t rd;
+
+ while(size != 0) {
+ rd = read(fd, buf, size);
+ if (rd == -1) {
+ perror("Can't read from file.");
+ exit(1);
+ }
+ size -= rd;
+ }
+}
+
+static void
+writepad(fd, size)
+ int fd;
+ size_t size;
+{
+ static void *zeropage = NULL;
+ ssize_t written;
+
+ if (zeropage == NULL) {
+ zeropage = malloc(4096);
+ if (zeropage == NULL) {
+ fprintf(stderr, "Couldn't allocate zero buffer.\n");
+ exit(1);
+ }
+ memset(zeropage, '\0', 4096);
+ }
+ while(size != 0) {
+ written = write(fd, zeropage, min(4096, size));
+ if (written == -1) {
+ perror("Can't write to boot image");
+ exit(1);
+ }
+ size -= written;
+ }
+}
+
+static void
+do_write(fd, buf, size)
+ int fd;
+ char *buf;
+ ssize_t size;
+{
+ ssize_t written;
+
+ while(size != 0) {
+ written = write(fd, buf, size);
+ if (written == -1) {
+ perror("Can't write to boot image");
+ exit(1);
+ }
+ size -= written;
+ }
+}
+
+static int
+usage(program_name)
+ char *program_name;
+{
+ fprintf(stderr, "Usage: %s infile outfile\n", program_name);
+ exit(0);
+}
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char *infile, *outfile;
+ struct stat ifstat;
+ off_t ifsize;
+ char *image;
+ int ifd, ofd, i, symtabix, strtabix;
+ Elf32_Ehdr eh;
+ Elf32_Phdr *ph;
+ Elf32_Shdr *sh;
+ unsigned long vaddr, entry, bss, kernel_entry, kernel_end;
+ unsigned char ahdr[32];
+ Elf32_Sym sym;
+ int symnum;
+ char *symname;
+
+ /*
+ * Verify some basic assuptions about type sizes made in this code
+ */
+ if (sizeof(Elf32_Half) != 2) {
+ fprintf(stderr, "Fix mkboot: sizeof(Elf32_Half) != 2\n");
+ exit(1);
+ }
+ if (sizeof(Elf32_Word) != 4) {
+ fprintf(stderr, "Fix mkboot: sizeof(Elf32_Word) != 4\n");
+ exit(1);
+ }
+ if (sizeof(Elf32_Addr) != 4) {
+ fprintf(stderr, "Fix mkboot: sizeof(Elf32_Addr) != 4\n");
+ exit(1);
+ }
+
+ if (argc != 3)
+ usage(argv[0]);
+
+ infile = argv[1];
+ outfile = argv[2];
+
+ if (stat(infile, &ifstat) < 0) {
+ perror("Can't stat kernel image.");
+ exit(1);
+ }
+
+ if (!S_ISREG(ifstat.st_mode)) {
+ fprintf(stderr, "Input file isn't a regular file.\n");
+ exit(1);
+ }
+ ifsize = ifstat.st_size;
+
+ image = malloc((size_t)ifsize);
+ if (image == NULL) {
+ fprintf(stderr, "Can't allocate memory to read file\n");


+ exit(1);
+ }
+
+ /*

+ * Read the entire input file in.
+ */
+ ifd = open(infile, O_RDONLY);
+ if(ifd == 0) {
+ fprintf(stderr, "Can't open input file\n");
+ exit(1);
+ }
+ do_read(ifd, image, ifsize);
+ close(ifd);
+
+ /*
+ * Now swap the ELF header in. This is ugly but we the file
+ * we're reading might have different type sizes, byteorder
+ * or alignment than the host.
+ */
+ memcpy(eh.e_ident, (void *)image, sizeof(eh.e_ident));
+ if(memcmp(eh.e_ident, ELFMAG, SELFMAG)) {
+ fprintf(stderr, "Input file isn't a ELF file\n");
+ exit(1);
+ }
+ if(eh.e_ident[EI_CLASS] != ELFCLASS32) {
+ fprintf(stderr, "Input file isn't a 32 bit ELF file\n");
+ exit(1);
+ }
+ if(eh.e_ident[EI_DATA] != ELFDATA2LSB) {
+ fprintf(stderr, "Input file isn't a little endian ELF file\n");
+ exit(1);
+ }
+ if(eh.e_ident[EI_VERSION] != EV_CURRENT) {
+ fprintf(stderr, "Input file isn't a version %d ELF file\n",
+ EV_CURRENT);


+ exit(1);
+ }
+
+ /*

+ * Ok, so far the file looks ok. Now swap the rest of the header in
+ * and do some more paranoia checks.
+ */
+ eh.e_type = get_Elf32_Half(image + 16);
+ eh.e_machine = get_Elf32_Half(image + 18);
+ eh.e_version = get_Elf32_Word(image + 20);
+ eh.e_entry = get_Elf32_Addr(image + 24);
+ eh.e_phoff = get_Elf32_Off(image + 28);
+ eh.e_shoff = get_Elf32_Off(image + 32);
+ eh.e_flags = get_Elf32_Word(image + 36);
+ eh.e_ehsize = get_Elf32_Half(image + 40);
+ eh.e_phentsize = get_Elf32_Half(image + 42);
+ eh.e_phnum = get_Elf32_Half(image + 44);
+ eh.e_shentsize = get_Elf32_Half(image + 46);
+ eh.e_shnum = get_Elf32_Half(image + 48);
+ eh.e_shstrndx = get_Elf32_Half(image + 50);
+
+ if(eh.e_type != ET_EXEC) {
+ fprintf(stderr, "Input file isn't a executable.\n");
+ exit(1);
+ }
+ if(eh.e_machine != EM_MIPS && eh.e_machine != EM_MIPS_RS4_BE) {
+ fprintf(stderr, "Input file isn't a MIPS executable.\n");


+ exit(1);
+ }
+
+ /*

+ * Now read the program headers ...
+ */
+ ph = malloc(sizeof(Elf32_Phdr) * eh.e_phnum);
+ if (ph == NULL) {
+ fprintf(stderr, "No memory for program header table.\n");
+ exit(1);
+ }


+ for(i = 0;i < eh.e_phnum; i++)

+ get_elfph((void *)(image + eh.e_phoff + i * 32), ph + i);
+
+ /*
+ * ... and then the section headers.
+ */
+ sh = malloc(sizeof(Elf32_Shdr) * eh.e_shnum);
+ if (sh == NULL) {
+ fprintf(stderr, "No memory for section header table.\n");
+ exit(1);
+ }
+ for(i = 0;i < eh.e_shnum; i++)
+ get_elfsh((void *)(image + eh.e_shoff + (i * 40)), sh + i);
+
+ /*
+ * Find the symboltable and the stringtable in the file.
+ */
+ for(i = 0;i < eh.e_shnum; i++) {
+ if (!strcmp (image + sh [eh.e_shstrndx].sh_offset + sh[i].sh_name,
+ ".symtab")) {
+ symtabix = i;
+ continue;
+ }
+ if (!strcmp (image + sh [eh.e_shstrndx].sh_offset + sh[i].sh_name,
+ ".strtab")) {
+ strtabix = i;
+ continue;
+ }
+ }
+
+ if (symtabix == -1) {
+ fprintf(stderr, "The executable doesn't have a symbol table\n");
+ exit(1);
+ }
+ if (strtabix == -1) {
+ fprintf(stderr, "The executable doesn't have a string table\n");


+ exit(1);
+ }
+
+ /*

+ * Dig for the two required symbols in the symbol table.
+ */
+ symnum = sh[symtabix].sh_size / 16;
+ for(i = 0;i < symnum;i++) {
+ get_elfsym(image + sh[symtabix].sh_offset + (i * 16), &sym);
+ symname = image + sh[strtabix].sh_offset + sym.st_name;
+ if (ELF32_ST_BIND(sym.st_info) != STB_GLOBAL)
+ continue;
+ if (ELF32_ST_TYPE(sym.st_info) != STT_NOTYPE &&
+ ELF32_ST_TYPE(sym.st_info) != STT_OBJECT &&
+ ELF32_ST_TYPE(sym.st_info) != STT_FUNC)
+ continue;
+ if (strcmp("kernel_entry", symname) == 0) {
+ kernel_entry = sym.st_value;
+ continue;
+ }
+ if (strcmp("_end", symname) == 0) {
+ kernel_end = sym.st_value;
+ continue;
+ }
+ }
+
+#ifdef VERBOSE
+ /*
+ * And print what we will be loaded into memory.
+ */


+ for(i = 0;i < eh.e_phnum; i++) {

SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 01'
echo 'File patch-2.1.44 is continued in part 02'
echo 02 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part03

#!/bin/sh
# this is part 03 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 03; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

@@ -0,0 +1,110 @@


+/*
+ * Setup pointers to hardware dependand routines.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * Copyright (C) 1996, 1997 by Ralf Baechle
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/ioport.h>


+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>

+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/ptrace.h>
+#include <asm/mipsregs.h>


+#include <asm/reboot.h>
+#include <asm/vector.h>
+

+/*
+ * Initial irq handlers.
+ */
+static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+/*
+ * IRQ2 is cascade interrupt to second interrupt controller
+ */
+static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL};
+
+extern asmlinkage void deskstation_handle_int(void);
+extern asmlinkage void deskstation_fd_cacheflush(const void *addr, size_t size);
+extern struct feature deskstation_tyne_feature;
+extern struct feature deskstation_rpc44_feature;
+
+extern void deskstation_machine_reboot(void);
+extern void deskstation_machine_halt(void);
+extern void deskstation_machine_power_off(void);
+
+#ifdef CONFIG_DESKSTATION_TYNE
+unsigned long mips_dma_cache_size = 0;
+unsigned long mips_dma_cache_base = KSEG0;
+
+__initfunc(static void tyne_irq_setup(void))
+{
+ set_except_vector(0, deskstation_handle_int);
+ /* set the clock to 100 Hz */
+ outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
+ outb_p(LATCH & 0xff , 0x40); /* LSB */
+ outb(LATCH >> 8 , 0x40); /* MSB */
+ request_region(0x20,0x20, "pic1");
+ request_region(0xa0,0x20, "pic2");
+ setup_x86_irq(2, &irq2);


+}
+#endif
+
+#ifdef CONFIG_DESKSTATION_RPC44

+__initfunc(static void rpc44_irq_setup(void))
+{
+ /*
+ * For the moment just steal the TYNE support. In the
+ * future, we need to consider merging the two -- imp
+ */
+ set_except_vector(0, deskstation_handle_int);
+ /* set the clock to 100 Hz */
+ outb_p(0x34, 0x43); /* binary, mode 2, LSB/MSB, ch 0 */
+ outb_p(LATCH & 0xff , 0x40); /* LSB */
+ outb(LATCH >> 8 , 0x40); /* MSB */
+ request_region(0x20,0x20, "pic1");
+ request_region(0xa0,0x20, "pic2");
+ setup_x86_irq(2, &irq2);
+ set_cp0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1);
+}
+#endif
+
+__initfunc(void deskstation_setup(void))
+{
+ switch(mips_machtype) {
+#ifdef CONFIG_DESKSTATION_TYNE
+ case MACH_DESKSTATION_TYNE:
+ atag = bi_TagFind(tag_dma_cache_size);
+ memcpy(&mips_dma_cache_size, TAGVALPTR(atag), atag->size);
+
+ atag = bi_TagFind(tag_dma_cache_base);
+ memcpy(&mips_dma_cache_base, TAGVALPTR(atag), atag->size);
+
+ irq_setup = tyne_irq_setup;
+ feature = &deskstation_tyne_feature;
+ isa_slot_offset = 0xe3000000; // Will go away
+ break;
+#endif
+#ifdef CONFIG_DESKSTATION_RPC44
+ case MACH_DESKSTATION_RPC44:
+ irq_setup = rpc44_irq_setup;
+ mips_memory_upper = KSEG0 + (32 << 20); /* xxx fixme imp */
+ feature = &deskstation_rpc44_feature; // Will go away
+ isa_slot_offset = 0xa0000000;
+ break;
+#endif
+ }
+ fd_cacheflush = deskstation_fd_cacheflush;
+ request_region(0x00,0x20,"dma1");
+ request_region(0x40,0x20,"timer");
+ request_region(0x70,0x10,"rtc");
+ request_region(0x80,0x10,"dma page reg");
+ request_region(0xc0,0x20,"dma2");
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/jazz/Makefile linux/arch/mips/jazz/Makefile
--- v2.1.43/linux/arch/mips/jazz/Makefile Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/jazz/Makefile Thu Jun 26 12:33:37 1997
@@ -0,0 +1,26 @@
+#
+# Makefile for the Jazz family specific parts of the kernel


+#
+# 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).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+

+all: jazz.o
+O_TARGET := jazz.o
+O_OBJS := hw-access.o int-handler.o jazzdma.o reset.o setup.o
+
+ifdef CONFIG_VIDEO_G364
+O_OBJS += g364.o
+endif


+
+int-handler.o: int-handler.S
+
+clean:
+
+include $(TOPDIR)/Rules.make

diff -u --recursive --new-file v2.1.43/linux/arch/mips/jazz/g364.c linux/arch/mips/jazz/g364.c
--- v2.1.43/linux/arch/mips/jazz/g364.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/jazz/g364.c Mon Jul 7 08:18:53 1997
@@ -0,0 +1,418 @@
+/*
+ * linux/drivers/char/g364.c
+ *
+ * Copyright (C) 1996 Wayne Hodgen
+ *
+ * Based on and using chunks of Jay Estabrooks tga.c
+ *
+ * This module exports the console io support for Inmos's G364 controller
+ * used in Mips Magnums and clones. Based on the hardware desc for the
+ * Olivetti M700-10 ie. an Inmos G364 based card in a dedicated video slot,
+ * 2MB dual ported VRAM with a 64 bit data path, 256 color lookup table,
+ * palette of 16.7M and a user definable 64x64 hardware cursor.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/kd.h>
+#include <linux/malloc.h>
+#include <linux/major.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/consolemap.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/types.h>
+
+extern void register_console(void (*proc)(const char *));
+extern void console_print(const char *);
+unsigned video_res_x;
+
+/*
+ * Various defines for the G364
+ */
+#define G364_MEM_BASE 0xe0800000
+#define G364_PORT_BASE 0xe0200000
+#define ID_REG 0xe0200000 /* Read only */
+#define BOOT_REG 0xe0280000
+#define TIMING_REG 0xe0280108 /* to 0x080170 - DON'T TOUCH! */
+#define MASK_REG 0xe0280200
+#define CTLA_REG 0xe0280300
+#define CURS_TOGGLE 0x800000
+#define BIT_PER_PIX 0x700000 /* bits 22 to 20 of Control A */
+#define DELAY_SAMPLE 0x080000
+#define PORT_INTER 0x040000
+#define PIX_PIPE_DEL 0x030000 /* bits 17 and 16 of Control A */
+#define PIX_PIPE_DEL2 0x008000 /* same as above - don't ask me why */
+#define TR_CYCLE_TOG 0x004000
+#define VRAM_ADR_INC 0x003000 /* bits 13 and 12 of Control A */
+#define BLANK_OFF 0x000800
+#define FORCE_BLANK 0x000400
+#define BLK_FUN_SWTCH 0x000200
+#define BLANK_IO 0x000100
+#define BLANK_LEVEL 0x000080
+#define A_VID_FORM 0x000040
+#define D_SYNC_FORM 0x000020
+#define FRAME_FLY_PAT 0x000010
+#define OP_MODE 0x000008
+#define INTL_STAND 0x000004
+#define SCRN_FORM 0x000002
+#define ENABLE_VTG 0x000001
+#define TOP_REG 0xe0280400
+#define CURS_PAL_REG 0xe0280508 /* to 0x080518 */
+#define CHKSUM_REG 0xe0280600 /* to 0x080610 - unused */
+#define CURS_POS_REG 0xe0280638
+#define CLR_PAL_REG 0xe0280800 /* to 0x080ff8 */
+#define CURS_PAT_REG 0xe0281000 /* to 0x081ff8 */
+#define MON_ID_REG 0xe0300000 /* unused */
+#define RESET_REG 0xe0380000 /* Write only */
+
+/*
+ * built-in font management constants
+ *
+ * NOTE: the built-in font is 8x16, and the video resolution
+ * is either 1280x1024 @ 60Hz or 1024x768 @ 60 or 78Hz.
+ */
+#define FONTSIZE_X 8 /* 8 pixels wide */
+#define FONTSIZE_Y 16 /* 16 pixels high */
+
+unsigned char g364_font[] = {
+#include "g364.fnt"
+};
+
+u32 g364_cursor[256] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0xffff0000,0,0,0,0xffff0000,0,0,0,0xffff0000,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
+#ifdef CONFIG_REMOTE_DEBUG
+/* #define DEBUG_G364 */
+
+extern int putDebugChar(char c);
+
+void
+putDebugString(char *d_str)
+{
+ while (*d_str != '\0') {
+ putDebugChar(*d_str);
+ d_str++;
+ }
+ if (*--d_str != '\n')
+ putDebugChar('\n');
+}
+#endif
+
+void g364_clear_screen(void);
+
+int cursor_initialised=0;
+
+unsigned long
+con_type_init(unsigned long kmem_start, const char **display_desc)
+{
+ can_do_color = 1;
+
+ /*
+ * fake the screen memory with some CPU memory
+ */
+ video_mem_base = kmem_start;
+ kmem_start += video_screen_size;
+ video_mem_term = kmem_start;
+ video_type = VIDEO_TYPE_MIPS_G364;
+ video_res_x = video_num_columns * FONTSIZE_X;
+
+ *display_desc = "G364";
+
+ return kmem_start;
+}
+
+con_type_init_finish(void)
+{
+}
+
+void
+__set_origin(unsigned short offset)
+{
+ /*
+ * should not be called, but if so, do nothing...
+ */
+}
+
+/*
+ * Hide the cursor from view, during blanking, usually...
+ */
+void
+hide_cursor(void)
+{
+/* *(unsigned int *) CTLA_REG &= ~CURS_TOGGLE; */
+}
+
+void
+init_g364_cursor(void)
+{
+ volatile unsigned int *ptr = (unsigned int *) CURS_PAL_REG;
+
+ *ptr |= 0x00ffffff;
+ ptr[2] |= 0x00ffffff;
+ ptr[4] |= 0x00ffffff;
+
+ memcpy((unsigned int *)CURS_PAT_REG, &g364_cursor, 1024);
+ cursor_initialised = 1;
+}
+
+/*
+ * Set the cursor on.
+ */
+void
+set_cursor(int currcons)
+{
+/*
+ if (!cursor_initialised)
+ init_g364_cursor();
+
+ if (console_blanked)
+ return;
+
+ *(unsigned int *) CTLA_REG |= CURS_TOGGLE;
+*/
+}
+
+/*
+ * NOTE: get_scrmem() and set_scrmem() are here only because
+ * the VGA version of set_scrmem() has some direct VGA references.
+ */
+void
+get_scrmem(int currcons)
+{
+ memcpyw((unsigned short *)vc_scrbuf[currcons],
+ (unsigned short *)origin, video_screen_size);
+ origin = video_mem_start = (unsigned long)vc_scrbuf[currcons];
+ scr_end = video_mem_end = video_mem_start + video_screen_size;
+ pos = origin + y*video_size_row + (x<<1);
+}
+
+void
+set_scrmem(int currcons, long offset)
+{
+ if (video_mem_term - video_mem_base < offset + video_screen_size)
+ offset = 0; /* strange ... */
+ memcpyw((unsigned short *)(video_mem_base + offset),
+ (unsigned short *) origin, video_screen_size);
+ video_mem_start = video_mem_base;
+ video_mem_end = video_mem_term;
+ origin = video_mem_base + offset;
+ scr_end = origin + video_screen_size;
+ pos = origin + y*video_size_row + (x<<1);
+}
+
+/*
+ * Fill out later
+ */
+void
+set_palette(void)
+{
+ int i, j;
+ volatile unsigned int *ptr = (volatile unsigned int *) CLR_PAL_REG;
+
+ for (i = 0; i < 16; i++,ptr+=2) {
+ j = color_table[i];
+ *ptr = ((default_red[j] << 16) |
+ (default_grn[j] << 8) |
+ (default_blu[j]));
+ }
+}
+
+/*
+ * NOTE:
+ * this is here, and not in console.c, because the VGA version
+ * tests the controller type to see if color can be done. We *KNOW*
+ * that we can do color on the G364.
+ *
+ */
+
+int
+set_get_cmap(unsigned char * arg, int set)
+{
+ int i;
+
+ for (i=0; i<16; i++) {
+ if (set) {
+ if (!access_ok(VERIFY_READ, (void *)arg, 16*3)) goto fault;
+ if (__get_user(default_red[i], arg++)) goto fault;
+ if (__get_user(default_grn[i], arg++)) goto fault;
+ if (__get_user(default_blu[i], arg++)) goto fault;
+ } else {
+ if (!access_ok(VERIFY_WRITE, (void *)arg, 16*3)) goto fault;
+ if (__put_user(default_red[i], arg++)) goto fault;
+ if (__put_user(default_grn[i], arg++)) goto fault;
+ if (__put_user(default_blu[i], arg++)) goto fault;
+ }
+ }
+ if (set) {
+ for (i=0; i<MAX_NR_CONSOLES; i++)
+ if (vc_cons_allocated(i)) {
+ int j, k ;
+ for (j=k=0; j<16; j++) {
+ vc_cons[i].d->vc_palette[k++] = default_red[j];
+ vc_cons[i].d->vc_palette[k++] = default_grn[j];
+ vc_cons[i].d->vc_palette[k++] = default_blu[j];
+ }
+ }
+ set_palette() ;
+ }


+
+ return 0;
+

+fault:
+ return -EFAULT;
+}
+
+/*
+ * Adjust the screen to fit a font of a certain height
+ *
+ * Returns < 0 for error, 0 if nothing changed, and the number
+ * of lines on the adjusted console if changed.
+ *
+ * for now, we only support the built-in font...
+ */
+int
+con_adjust_height(unsigned long fontheight)
+{
+ return -EINVAL;
+}
+
+/*
+ * PIO_FONT support.
+ *
+ * for now, we will use/allow *only* our built-in font...
+ */
+int
+set_get_font(char * arg, int set, int ch512)
+{
+ return -EINVAL;
+}
+
+/*
+ * print a character to a graphics console.
+ */
+void
+g364_blitc(unsigned short charattr, unsigned long addr)
+{
+ int row, col, temp;
+ register unsigned long long *dst, *font_row;
+ register int i;
+ char c;
+
+ /*
+ * calculate (row,col) from addr and video_mem_base
+ */
+ temp = (addr - video_mem_base) >> 1;
+ col = temp % 128;
+ row = (temp - col) / 128;
+
+ /*
+ * calculate destination address
+ */
+ dst = (unsigned long long *) ( G364_MEM_BASE
+ + ( row * video_res_x * FONTSIZE_Y )
+ + ( col * FONTSIZE_X ) );
+
+ c = charattr & 0x00ff;
+ if (c == 0x20) {
+ for (i=0; i < FONTSIZE_Y; i++, dst += video_num_columns)
+ *dst = 0x00000000;
+ } else {
+ font_row = (unsigned long long *) &g364_font[(c << 7)];
+ for (i=0; i < FONTSIZE_Y; i++, font_row++, dst += video_num_columns)
+ *dst = *font_row;
+ }
+}
+
+/*
+ * print a character to a graphics console. Colour version, slower!
+ */
+void
+g364_blitc_colour(unsigned short charattr, unsigned long addr)
+{
+ int row, col, temp, c, attrib;
+ register unsigned int fgmask, bgmask;
+ register unsigned long long *dst, *font_row;
+ register int i, stride;
+
+ c = charattr & 0x00ff;
+ attrib = (charattr >> 8) & 0x00ff;
+
+ /*
+ * extract foreground and background indices
+ * NOTE: we always treat blink/underline bits as color for now...
+ */
+ fgmask = attrib & 0x0f;
+ bgmask = (attrib >> 4) & 0x0f;
+
+ /* i = (c & 0xff) << 7; NOTE: assumption of 128 bytes per character bitmap */
+
+ /*
+ * calculate (row,col) from addr and video_mem_base
+ */
+ temp = (addr - video_mem_base) >> 1;
+ col = temp % 128;
+ row = (temp - col) / 128;
+ stride = video_res_x / 8;
+
+ /*
+ * calculate destination address
+ */
+ dst = (unsigned long long *) ( G364_MEM_BASE
+ + ( row * video_res_x * FONTSIZE_Y )
+ + ( col * FONTSIZE_X ) );
+
+ font_row = (unsigned long long *) &g364_font[((c & 0xff) << 7)];
+
+ for (i=0; i < FONTSIZE_Y; i++, font_row++, dst += stride) {
+ *dst = *font_row;
+ }
+}
+
+/*
+ * dummy routines for the VESA blanking code, which is VGA only,
+ * so we don't have to carry that stuff around for the G364...
+ */
+void
+vesa_powerdown(void)
+{
+}
+
+void
+vesa_blank(void)
+{
+}
+
+void
+vesa_unblank(void)
+{
+}
+
+void
+set_vesa_blanking(const unsigned long arg)
+{
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/jazz/g364.fnt linux/arch/mips/jazz/g364.fnt
--- v2.1.43/linux/arch/mips/jazz/g364.fnt Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/jazz/g364.fnt Thu Jun 26 12:33:37 1997
@@ -0,0 +1,4097 @@
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x00,0x07,0x07,0x07,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x00,0x07,0x07,0x07,0x00,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x00,0x07,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x07,0x00,
+0x07,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x07,0x00,
+0x07,0x07,0x00,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x07,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x07,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x07,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x07,
+0x07,0x00,0x00,0x07,0x00,0x00,0x00,0x07,
+0x07,0x00,0x00,0x07,0x07,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x07,0x00,0x00,0x07,0x00,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x07,
+0x07,0x00,0x00,0x07,0x07,0x00,0x07,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x07,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x07,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x07,
+0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x07,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x07,0x00,0x00,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x07,0x07,0x07,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,
+0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,
+0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x07,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x07,
+0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,
+0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x07,
+0x07,0x07,0x07,0x07,0x00,0x07,0x00,0x07,
+0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x07,
+0x07,0x07,0x07,0x07,0x00,0x07,0x00,0x07,
+0x07,0x07,0x07,0x00,0x07,0x00,0x07,0x07,
+0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,
+0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
+0x07,0x07,0x00,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x07,0x00,0x00,0x07,0x00,0x07,0x00,0x00,
+0x07,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x07,0x00,0x00,0x07,0x00,
+0x00,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x07,
+0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x07,0x07,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x00,0x00,0x00,
+0x00,0x07,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x07,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x07,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,
+0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,
+0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x00,
+0x00,0x00,0x07,0x07,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 03'
echo 'File patch-2.1.44 is continued in part 04'
echo 04 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part12

#!/bin/sh
# this is part 12 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 12; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

+ current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE;
+ spin_unlock_irq(&current->sigmask_lock);
+ }
+}
X
- regs->reg4 = signr; /* argument for handler */
+static inline void syscall_restart(unsigned long r0, unsigned long or2,
+ unsigned long or7, struct pt_regs *regs,
+ struct sigaction *sa)
+{
+ switch(r0) {
+ case ERESTARTNOHAND:
+ no_system_call_restart:
+ regs->regs[0] = regs->regs[2] = EINTR;
+ break;
+ case ERESTARTSYS:
+ if(!(sa->sa_flags & SA_RESTART))
+ goto no_system_call_restart;
+ /* fallthrough */
+ case ERESTARTNOINTR:
+ regs->regs[0] = regs->regs[2] = or2;
+ regs->regs[7] = or7;
+ regs->cp0_epc -= 8;
+ }
X }
X
+extern int do_irix_signal(unsigned long oldmask, struct pt_regs *regs);
+
X /*
X * Note that 'init' is a special process: it doesn't get signals it doesn't
X * want to handle. Thus you cannot kill init even with a SIGKILL even by
@@ -253,16 +275,15 @@
X */
X asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
X {
- unsigned long mask;
- unsigned long handler_signal = 0;
- struct sc *frame = NULL;
- unsigned long pc = 0;
- unsigned long signr;
+ unsigned long mask = ~current->blocked;
+ unsigned long signr, r0 = regs->regs[0];
+ unsigned long r7 = regs->orig_reg7;
X struct sigaction * sa;
- int ret;
X
- lock_kernel();
- mask = ~current->blocked;
+#ifdef CONFIG_BINFMT_IRIX
+ if(current->personality != PER_LINUX)
+ return do_irix_signal(oldmask, regs);
+#endif
X while ((signr = current->signal & mask)) {
X signr = ffz(~signr);
X clear_bit(signr, &current->signal);
@@ -279,7 +300,9 @@
X if (signr == SIGSTOP)
X continue;
X if (_S(signr) & current->blocked) {
+ spin_lock_irq(&current->sigmask_lock);
X current->signal |= _S(signr);
+ spin_unlock_irq(&current->sigmask_lock);
X continue;
X }
X sa = current->sig->action + signr - 1;
@@ -288,7 +311,7 @@
X if (signr != SIGCHLD)
X continue;
X /* check for SIGCHLD: it's special */
- while (sys_waitpid(-1,NULL,WNOHANG) > 0)
+ while (sys_wait4(-1,NULL,WNOHANG, NULL) > 0)
X /* nothing */;
X continue;
X }
@@ -299,7 +322,10 @@
X case SIGCONT: case SIGCHLD: case SIGWINCH:
X continue;
X
- case SIGSTOP: case SIGTSTP: case SIGTTIN: case SIGTTOU:
+ case SIGTSTP: case SIGTTIN: case SIGTTOU:
+ if (is_orphaned_pgrp(current->pgrp))
+ continue;
+ case SIGSTOP:
X if (current->flags & PF_PTRACED)
X continue;
X current->state = TASK_STOPPED;
@@ -311,68 +337,58 @@
X continue;
X
X case SIGQUIT: case SIGILL: case SIGTRAP:
- case SIGIOT: case SIGFPE: case SIGSEGV: case SIGBUS:
+ case SIGABRT: case SIGFPE: case SIGSEGV:
+ case SIGBUS:
+ lock_kernel();
X if (current->binfmt && current->binfmt->core_dump) {
X if (current->binfmt->core_dump(signr, regs))
X signr |= 0x80;
X }
+ unlock_kernel();
X /* fall through */
X default:
+ spin_lock_irq(&current->sigmask_lock);
X current->signal |= _S(signr & 0x7f);
+ spin_unlock_irq(&current->sigmask_lock);
+
X current->flags |= PF_SIGNALED;
+
+ lock_kernel(); /* 8-( */
X do_exit(signr);
+ unlock_kernel();
X }
X }
X /*
X * OK, we're invoking a handler
X */
- if (regs->orig_reg2 >= 0) {
- if (regs->reg2 == -ERESTARTNOHAND ||
- (regs->reg2 == -ERESTARTSYS &&
- !(sa->sa_flags & SA_RESTART)))
- regs->reg2 = -EINTR;
- }
- handler_signal |= 1 << (signr-1);
- mask &= ~sa->sa_mask;
+ if(r0)
+ syscall_restart(r0, regs->orig_reg2,
+ r7, regs, sa);
+ handle_signal(signr, sa, oldmask, regs);
+ return 1;
X }
X /*
X * Who's code doesn't conform to the restartable syscall convention
X * dies here!!! The li instruction, a single machine instruction,
X * must directly be followed by the syscall instruction.
X */
- if (regs->orig_reg2 >= 0 &&
- (regs->reg2 == -ERESTARTNOHAND ||
- regs->reg2 == -ERESTARTSYS ||
- regs->reg2 == -ERESTARTNOINTR))
- {
- regs->reg2 = regs->orig_reg2;
+ if (r0 &&
+ (regs->regs[2] == ERESTARTNOHAND ||
+ regs->regs[2] == ERESTARTSYS ||
+ regs->regs[2] == ERESTARTNOINTR)) {
+ regs->regs[0] = regs->regs[2] = regs->orig_reg2;
+ regs->regs[7] = r7;
X regs->cp0_epc -= 8;
X }
- ret = 0;
- if (!handler_signal) /* no handler will be called - return 0 */
- goto out;
- pc = regs->cp0_epc;
- frame = (struct sc *) regs->reg29;
- signr = 1;
- sa = current->sig->action;
- for (mask = 1 ; mask ; sa++,signr++,mask += mask) {
- if (mask > handler_signal)
- break;
- if (!(mask & handler_signal))
- continue;
- setup_frame(sa, &frame, pc, regs, signr, oldmask);
- pc = (unsigned long) sa->sa_handler;
- if (sa->sa_flags & SA_ONESHOT)
- sa->sa_handler = NULL;
- current->blocked |= sa->sa_mask;
- oldmask |= sa->sa_mask;
- }
- regs->reg29 = (unsigned long) frame; /* Stack pointer */
- regs->reg31 = (unsigned long) frame->code; /* Return address */
- regs->cp0_epc = pc; /* "return" to the first handler */
+ return 0;
+}
X
- ret = 1;
-out:
- unlock_kernel();
- return ret;
+/*
+ * The signal(2) syscall is no longer available in the kernel
+ * because GNU libc doesn't use it. Maybe I'll add it back to the
+ * kernel for the binary compatibility stuff.
+ */
+asmlinkage unsigned long sys_signal(int signum, __sighandler_t handler)
+{
+ return -ENOSYS;
X }
diff -u --recursive --new-file v2.1.43/linux/arch/mips/kernel/syscall.c linux/arch/mips/kernel/syscall.c
--- v2.1.43/linux/arch/mips/kernel/syscall.c Sun Jan 26 02:07:05 1997
+++ linux/arch/mips/kernel/syscall.c Thu Jun 26 12:33:37 1997
@@ -5,8 +5,16 @@
X * License. See the file "COPYING" in the main directory of this archive


X * for more details.
X *

- * Copyright (C) 1995 by Ralf Baechle
+ * Copyright (C) 1995, 1996 by Ralf Baechle
+ *
+ * TODO: Implement the compatibility syscalls.
+ * Don't waste that much memory for empty entries in the syscall
+ * table.
X */
+#undef CONF_PRINT_SYSCALLS
+#undef CONF_DEBUG_IRIX
+
+#include <linux/config.h>
X #include <linux/linkage.h>
X #include <linux/mm.h>
X #include <linux/smp.h>
@@ -14,73 +22,79 @@
X #include <linux/mman.h>
X #include <linux/sched.h>
X #include <linux/unistd.h>
+#include <asm/branch.h>
X #include <asm/ptrace.h>
-#include <asm/segment.h>
X #include <asm/signal.h>
+#include <asm/uaccess.h>
X
X extern asmlinkage void syscall_trace(void);
X typedef asmlinkage int (*syscall_t)(void *a0,...);
-extern asmlinkage int do_syscalls(struct pt_regs *regs, syscall_t fun,
- int narg);
+extern asmlinkage int (*do_syscalls)(struct pt_regs *regs, syscall_t fun,
+ int narg);
X extern syscall_t sys_call_table[];
X extern unsigned char sys_narg_table[];
X
X asmlinkage int sys_pipe(struct pt_regs *regs)
X {
X int fd[2];
- int error;
+ int error, res;
X
X lock_kernel();
X error = do_pipe(fd);
- if (error)
+ if (error) {
+ res = error;
X goto out;
- regs->reg2 = fd[0];
- regs->reg3 = fd[1];
+ }
+ regs->regs[3] = fd[1];
+ res = fd[0];
X out:
X unlock_kernel();
- return error;
+ return res;
X }
X
X asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, int prot,
X int flags, int fd, off_t offset)
X {
X struct file * file = NULL;
- int ret = -EBADF;
+ unsigned long res;
X
X lock_kernel();
- if (flags & MAP_RENAME) {
+ if (!(flags & MAP_ANONYMOUS)) {
X if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
- goto out;
+ return -EBADF;
X }
X flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
X
- ret = do_mmap(file, addr, len, prot, flags, offset);
-out:
+ res = do_mmap(file, addr, len, prot, flags, offset);
+
X unlock_kernel();
- return ret;
+ return res;
X }
X
X asmlinkage int sys_idle(void)
X {
- int ret = -EPERM;
+ int ret = -EPERM;
X
X lock_kernel();
X if (current->pid != 0)
X goto out;
-
X /* endless idle loop with no priority at all */
+ current->priority = -100;
X current->counter = -100;
X for (;;) {
X /*
- * R4[26]00 have wait, R4[04]00 don't.
+ * R4[236]00 have wait, R4[04]00 don't.
+ * FIXME: We should save power by reducing the clock where
+ * possible. Should help alot for battery powered
+ * R4200/4300i systems.
X */
X if (wait_available && !need_resched)
X __asm__(".set\tmips3\n\t"
X "wait\n\t"
X ".set\tmips0\n\t");
+ run_task_queue(&tq_scheduler);
X schedule();
X }
- ret = 0;
X out:
X unlock_kernel();
X return ret;
@@ -88,28 +102,28 @@
X
X asmlinkage int sys_fork(struct pt_regs *regs)
X {
- int ret;
+ int res;
X
X lock_kernel();
- ret = do_fork(SIGCHLD, regs->reg29, regs);
+ res = do_fork(SIGCHLD, regs->regs[29], regs);
X unlock_kernel();
- return ret;
+ return res;
X }
X
X asmlinkage int sys_clone(struct pt_regs *regs)
X {
X unsigned long clone_flags;
X unsigned long newsp;
- int ret;
+ int res;
X
X lock_kernel();
- clone_flags = regs->reg4;
- newsp = regs->reg5;
+ clone_flags = regs->regs[4];
+ newsp = regs->regs[5];
X if (!newsp)
- newsp = regs->reg29;
- ret = do_fork(clone_flags, newsp, regs);
+ newsp = regs->regs[29];
+ res = do_fork(clone_flags, newsp, regs);
X unlock_kernel();
- return ret;
+ return res;
X }
X
X /*
@@ -117,72 +131,136 @@
X */
X asmlinkage int sys_execve(struct pt_regs *regs)
X {
- int error;
+ int res;
X char * filename;
X
X lock_kernel();
- error = getname((char *) regs->reg4, &filename);
- if (error)
+ res = getname((char *) (long)regs->regs[4], &filename);
+ if (res)
X goto out;
- error = do_execve(filename, (char **) regs->reg5,
- (char **) regs->reg6, regs);
+ res = do_execve(filename, (char **) (long)regs->regs[5],
+ (char **) (long)regs->regs[6], regs);
X putname(filename);
+
X out:
X unlock_kernel();
- return error;
+ return res;
X }
X
X /*
X * Do the indirect syscall syscall.
+ * Don't care about kernel locking; the actual syscall will do it.
X */
-asmlinkage int sys_syscall(unsigned long a0, unsigned long a1, unsigned long a2,
- unsigned long a3, unsigned long a4, unsigned long a5,
- unsigned long a6)
+asmlinkage int sys_syscall(struct pt_regs *regs)
X {
X syscall_t syscall;
+ unsigned long syscallnr = regs->regs[4];
+ unsigned long a0, a1, a2, a3, a4, a5, a6;
+ int nargs, errno;
X
- if (a0 > __NR_Linux + __NR_Linux_syscalls)
+ if (syscallnr > __NR_Linux + __NR_Linux_syscalls)
X return -ENOSYS;
X
- syscall = sys_call_table[a0];
+ syscall = sys_call_table[syscallnr];
+ nargs = sys_narg_table[syscallnr];
X /*
X * Prevent stack overflow by recursive
X * syscall(__NR_syscall, __NR_syscall,...);
X */
- if (syscall == (syscall_t) sys_syscall)
+ if (syscall == (syscall_t) sys_syscall) {
X return -EINVAL;
+ }
X
- if (syscall == NULL)
+ if (syscall == NULL) {
X return -ENOSYS;
+ }
X
+ if(nargs > 3) {
+ unsigned long usp = regs->regs[29];
+ unsigned long *sp = (unsigned long *) usp;
+ if(usp & 3) {
+ printk("unaligned usp -EFAULT\n");
+ force_sig(SIGSEGV, current);
+ return -EFAULT;
+ }
+ errno = verify_area(VERIFY_READ, (void *) (usp + 16),
+ (nargs - 3) * sizeof(unsigned long));
+ if(errno) {
+ return -EFAULT;
+ }
+ switch(nargs) {
+ case 7:
+ a3 = sp[4]; a4 = sp[5]; a5 = sp[6]; a6 = sp[7];
+ break;
+ case 6:
+ a3 = sp[4]; a4 = sp[5]; a5 = sp[6]; a6 = 0;
+ break;
+ case 5:
+ a3 = sp[4]; a4 = sp[5]; a5 = a6 = 0;
+ break;
+ case 4:
+ a3 = sp[4]; a4 = a5 = a6 = 0;


+ break;
+
+ default:

+ a3 = a4 = a5 = a6 = 0;
+ break;
+ }
+ } else {
+ a3 = a4 = a5 = a6 = 0;
+ }
+ a0 = regs->regs[5]; a1 = regs->regs[6]; a2 = regs->regs[7];
+ if(nargs == 0)
+ a0 = (unsigned long) regs;
X return syscall((void *)a0, a1, a2, a3, a4, a5, a6);
X }
X
+/*
+ * If we ever come here the user sp is bad. Zap the process right away.
+ * Due to the bad stack signaling wouldn't work.
+ * XXX kernel locking???
+ */
+asmlinkage void bad_stack(void)
+{
+ do_exit(SIGSEGV);
+}
+
+#ifdef CONF_PRINT_SYSCALLS
+#define SYS(fun, narg) #fun,
+static char *sfnames[] = {
+#include "syscalls.h"
+};
+#endif
+
+#if defined(CONFIG_BINFMT_IRIX) && defined(CONF_DEBUG_IRIX)
+#define SYS(fun, narg) #fun,
+static char *irix_sys_names[] = {
+#include "irix5sys.h"
+};
+#endif
+
+/*
+ * This isn't entirely correct with respect to kernel locking ...
+ */
X void do_sys(struct pt_regs *regs)
X {
X unsigned long syscallnr, usp;
X syscall_t syscall;
X int errno, narg;
X
- /*
- * Compute the return address;
- */
- if (regs->cp0_cause & CAUSEF_BD)
- {
+ /* Skip syscall instruction */
+ if (delay_slot(regs)) {
X /*
- * This syscall is in a branch delay slot. Since we don't do
- * branch delay slot handling we would get a process trying
- * to do syscalls ever and ever again. So better zap it.
+ * By convention "li v0,<syscallno>" is always preceeding
+ * the syscall instruction. So if we're in a delay slot
+ * userland is screwed up.
X */
- printk("%s: syscall in branch delay slot.\n", current->comm);
- current->sig->action[SIGILL-1].sa_handler = NULL;
- current->blocked &= ~(1<<(SIGILL-1));
- send_sig(SIGILL, current, 1);
+ force_sig(SIGILL, current);
X return;
X }
X regs->cp0_epc += 4;
X
- syscallnr = regs->reg2;
+ syscallnr = regs->regs[2];
X if (syscallnr > (__NR_Linux + __NR_Linux_syscalls))
X goto illegal_syscall;
X
@@ -191,37 +269,64 @@
X goto illegal_syscall;
X
X narg = sys_narg_table[syscallnr];
- if (narg > 4)
- {
+#ifdef CONF_PRINT_SYSCALLS
+ if(syscallnr >= 4000)
+ printk("do_sys(%s:%d): %s(%08lx,%08lx,%08lx,%08lx)<pc=%08lx>",
+ current->comm, current->pid, sfnames[syscallnr - __NR_Linux],
+ regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7],
+ regs->cp0_epc);
+#endif
+#if defined(CONFIG_BINFMT_IRIX) && defined(CONF_DEBUG_IRIX)
+ if(syscallnr < 2000 && syscallnr >= 1000) {
+ printk("irix_sys(%s:%d): %s(", current->comm,
+ current->pid, irix_sys_names[syscallnr - 1000]);
+ if((narg < 4) && (narg != 0)) {
+ int i = 0;
+
+ while(i < (narg - 1)) {
+ printk("%08lx, ", regs->regs[i + 4]);
+ i++;
+ }
+ printk("%08lx) ", regs->regs[i + 4]);
+ } else if(narg == 0) {
+ printk("%08lx, %08lx, %08lx, %08lx) ",
+ regs->regs[4], regs->regs[5], regs->regs[6],
+ regs->regs[7]);
+ } else
+ printk("narg=%d) ", narg);
+ }
+#endif
+ if (narg > 4) {
X /*
X * Verify that we can safely get the additional parameters
X * from the user stack. Of course I could read the params
X * from unaligned addresses ... Consider this a programming
X * course caliber .45.
X */
- usp = regs->reg29;
- if (usp & 3)
- {
+ usp = regs->regs[29];
+ if (usp & 3) {
X printk("unaligned usp\n");
- send_sig(SIGSEGV, current, 1);
- regs->reg2 = EFAULT;
- regs->reg7 = 1;
+ force_sig(SIGSEGV, current);
+ regs->regs[2] = EFAULT;
+ regs->regs[7] = 1;
+ return;
+ }
+ if (!access_ok(VERIFY_READ, (void *) (usp + 16),
+ (narg - 4) * sizeof(unsigned long))) {
+ regs->regs[2] = EFAULT;
+ regs->regs[7] = 1;
X return;
X }
- errno = verify_area(VERIFY_READ, (void *) (usp + 16),
- (narg - 4) * sizeof(unsigned long));
- if (errno < 0)
- goto bad_syscall;
X }
X
X if ((current->flags & PF_TRACESYS) == 0)
X {
X errno = do_syscalls(regs, syscall, narg);
- if (errno < 0 || current->errno)
+ if ((errno < 0 && errno > (-ENOIOCTLCMD - 1)) || current->errno) {
X goto bad_syscall;
-
- regs->reg2 = errno;
- regs->reg7 = 0;
+ }
+ regs->regs[2] = errno;
+ regs->regs[7] = 0;
X }
X else
X {
@@ -230,25 +335,49 @@
X errno = do_syscalls(regs, syscall, narg);
X if (errno < 0 || current->errno)
X {
- regs->reg2 = -errno;
- regs->reg7 = 1;
+ regs->regs[2] = -errno;
+ regs->regs[7] = 1;
X }
X else
X {
- regs->reg2 = errno;
- regs->reg7 = 0;
+ regs->regs[2] = errno;
+ regs->regs[7] = 0;
X }
X
X syscall_trace();
X }
+#if defined(CONF_PRINT_SYSCALLS) || \
+ (defined(CONFIG_BINFMT_IRIX) && defined(CONF_DEBUG_IRIX))
+#if 0
+ printk(" returning: normal\n");
+#else
+ if(syscallnr >= 4000 && syscallnr < 5000)
+ printk(" returning: %08lx\n", (unsigned long) errno);
+#endif
+#endif
X return;
X
X bad_syscall:
- regs->reg2 = -errno;
- regs->reg7 = 1;
+ regs->regs[0] = regs->regs[2] = -errno;
+ regs->regs[7] = 1;
+#if defined(CONF_PRINT_SYSCALLS) || \
+ (defined(CONFIG_BINFMT_IRIX) && defined(CONF_DEBUG_IRIX))
+#if 0
+ printk(" returning: bad_syscall\n");
+#else
+ if(syscallnr >= 4000 && syscallnr < 5000)
+ printk(" returning error: %d\n", errno);
+#endif
+#endif
X return;
X illegal_syscall:
- regs->reg2 = ENOSYS;
- regs->reg7 = 1;
+
+ regs->regs[2] = ENOSYS;
+ regs->regs[7] = 1;
+#if defined(CONF_PRINT_SYSCALLS) || \
+ (defined(CONFIG_BINFMT_IRIX) && defined(CONF_DEBUG_IRIX))
+ if(syscallnr >= 1000 && syscallnr < 2000)
+ printk(" returning: illegal_syscall\n");
+#endif
X return;
X }
diff -u --recursive --new-file v2.1.43/linux/arch/mips/kernel/syscalls.h linux/arch/mips/kernel/syscalls.h
--- v2.1.43/linux/arch/mips/kernel/syscalls.h Tue May 13 22:41:02 1997
+++ linux/arch/mips/kernel/syscalls.h Mon Jul 7 08:18:53 1997
@@ -5,7 +5,9 @@
X * License. See the file "COPYING" in the main directory of this archive


X * for more details.
X *

- * Copyright (C) 1995 by Ralf Baechle
+ * Copyright (C) 1995, 1996 by Ralf Baechle
+ *
+ * $Id: syscalls.h,v 1.5 1997/06/25 17:08:35 ralf Exp $
X */
X
X /*
@@ -16,7 +18,7 @@
X *
X * The binary compatibility calls are still missing in this list.
X */
-SYS(sys_syscall, 7) /* 4000 */
+SYS(sys_syscall, 0) /* 4000 */
X SYS(sys_exit, 1)
X SYS(sys_fork, 0)
X SYS(sys_read, 3)
@@ -88,7 +90,7 @@
X SYS(sys_ssetmask, 1)
X SYS(sys_setreuid, 2) /* 4070 */
X SYS(sys_setregid, 2)
-SYS(sys_sigsuspend, 3)
+SYS(sys_sigsuspend, 0)
X SYS(sys_sigpending, 1)
X SYS(sys_sethostname, 2)
X SYS(sys_setrlimit, 2) /* 4075 */
@@ -166,12 +168,43 @@
X SYS(sys_cacheflush, 3)
X SYS(sys_cachectl, 3)
X SYS(sys_sysmips, 4)
-SYS(sys_setup, 0) /* 4150 */
+SYS(sys_setup, 1) /* 4150 */
X SYS(sys_getsid, 1)
-SYS(sys_ni_syscall, 0)
-SYS(sys_ni_syscall, 0)
+SYS(sys_fdatasync, 0)
+SYS(sys_sysctl, 1)
X SYS(sys_mlock, 2)
X SYS(sys_munlock, 2) /* 4155 */
X SYS(sys_mlockall, 1)
X SYS(sys_munlockall, 0)
+SYS(sys_sched_setparam,2)
+SYS(sys_sched_getparam,2)
+SYS(sys_sched_setscheduler,3) /* 4160 */
+SYS(sys_sched_getscheduler,1)
+SYS(sys_sched_yield,0)
+SYS(sys_sched_get_priority_max,1)
+SYS(sys_sched_get_priority_min,1)
+SYS(sys_sched_rr_get_interval,2) /* 4165 */
+SYS(sys_nanosleep,2)
+SYS(sys_mremap,4)
+SYS(sys_accept, 3)
+SYS(sys_bind, 3)
+SYS(sys_connect, 3) /* 4170 */
+SYS(sys_getpeername, 3)
+SYS(sys_getsockname, 3)
+SYS(sys_getsockopt, 5)
+SYS(sys_listen, 2)
+SYS(sys_recv, 4) /* 4175 */
+SYS(sys_recvfrom, 6)
+SYS(sys_recvmsg, 3)
+SYS(sys_send, 4)
+SYS(sys_sendmsg, 3)
+SYS(sys_sendto, 6) /* 4180 */
+SYS(sys_setsockopt, 5)
+SYS(sys_shutdown, 2)
+SYS(sys_socket, 3)
+SYS(sys_socketpair, 4)
+SYS(sys_setresuid, 3) /* 4185 */
+SYS(sys_getresuid, 3)
+SYS(sys_query_module, 5)
+SYS(sys_poll, 3)
X SYS(sys_nfsservctl, 3)
diff -u --recursive --new-file v2.1.43/linux/arch/mips/kernel/sysirix.c linux/arch/mips/kernel/sysirix.c
--- v2.1.43/linux/arch/mips/kernel/sysirix.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/kernel/sysirix.c Mon Jul 7 08:18:54 1997
@@ -0,0 +1,2307 @@
+/* $Id: sysirix.c,v 1.2 1997/06/17 15:24:26 ralf Exp $
+ * sysirix.c: IRIX system call emulation.
+ *
+ * Copyright (C) 1996 David S. Miller
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/pagemap.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/malloc.h>
+#include <linux/swap.h>
+#include <linux/errno.h>
+#include <linux/timex.h>
+#include <linux/times.h>
+#include <linux/elf.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/utsname.h>
+
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+
+/* 2,300 lines of complete and utter shit coming up... */
+
+/* The sysmp commands supported thus far. */
+#define MP_PGSIZE 14 /* Return system page size in v1. */
+
+asmlinkage int irix_sysmp(struct pt_regs *regs)
+{
+ unsigned long cmd;
+ int base = 0;
+ int error = 0;
+
+ lock_kernel();
+ if(regs->regs[2] == 1000)
+ base = 1;
+ cmd = regs->regs[base + 4];
+ switch(cmd) {
+ case MP_PGSIZE:
+ error = PAGE_SIZE;


+ break;
+
+ default:

+ printk("SYSMP[%s:%d]: Unsupported opcode %d\n",
+ current->comm, current->pid, (int)cmd);
+ error = -EINVAL;
+ break;
+ }
+
+ unlock_kernel();
+ return error;
+}
+
+/* The prctl commands. */
+#define PR_MAXPROCS 1 /* Tasks/user. */
+#define PR_ISBLOCKED 2 /* If blocked, return 1. */
+#define PR_SETSTACKSIZE 3 /* Set largest task stack size. */
+#define PR_GETSTACKSIZE 4 /* Get largest task stack size. */
+#define PR_MAXPPROCS 5 /* Num parallel tasks. */
+#define PR_UNBLKONEXEC 6 /* When task exec/exit's, unblock. */
+#define PR_SETEXITSIG 8 /* When task exit's, set signal. */
+#define PR_RESIDENT 9 /* Make task unswappable. */
+#define PR_ATTACHADDR 10 /* (Re-)Connect a vma to a task. */
+#define PR_DETACHADDR 11 /* Disconnect a vma from a task. */
+#define PR_TERMCHILD 12 /* When parent sleeps with fishes, kill child. */
+#define PR_GETSHMASK 13 /* Get the sproc() share mask. */
+#define PR_GETNSHARE 14 /* Number of share group members. */
+#define PR_COREPID 15 /* Add task pid to name when it core. */
+#define PR_ATTACHADDRPERM 16 /* (Re-)Connect vma, with specified prot. */
+#define PR_PTHREADEXIT 17 /* Kill a pthread without prejudice. */
+
+asmlinkage int irix_prctl(struct pt_regs *regs)
+{
+ unsigned long cmd;
+ int error = 0, base = 0;
+
+ lock_kernel();
+ if(regs->regs[2] == 1000)
+ base = 1;
+ cmd = regs->regs[base + 4];
+ switch(cmd) {
+ case PR_MAXPROCS:
+ printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
+ current->comm, current->pid);
+ error = NR_TASKS;
+ break;
+
+ case PR_ISBLOCKED: {
+ struct task_struct *task;
+
+ printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n",
+ current->comm, current->pid);
+ task = find_task_by_pid(regs->regs[base + 5]);
+ if(!task) {
+ error = -ESRCH;
+ break;
+ }
+ error = (task->next_run ? 0 : 1);
+ /* Can _your_ OS find this out that fast? */
+ break;
+ }
+
+ case PR_SETSTACKSIZE: {
+ long value = regs->regs[base + 5];
+
+ printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n",
+ current->comm, current->pid, (unsigned long) value);
+ if(value > RLIM_INFINITY)
+ value = RLIM_INFINITY;
+ if(suser()) {
+ current->rlim[RLIMIT_STACK].rlim_max =
+ current->rlim[RLIMIT_STACK].rlim_cur = value;
+ error = value;
+ break;
+ }
+ if(value > current->rlim[RLIMIT_STACK].rlim_max) {
+ error = -EINVAL;
+ break;
+ }
+ current->rlim[RLIMIT_STACK].rlim_cur = value;
+ error = value;
+ break;
+ }
+
+ case PR_GETSTACKSIZE:
+ printk("irix_prctl[%s:%d]: Wants PR_GETSTACKSIZE\n",
+ current->comm, current->pid);
+ error = current->rlim[RLIMIT_STACK].rlim_cur;
+ break;
+
+ case PR_MAXPPROCS:
+ printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
+ current->comm, current->pid);
+ error = 1;
+ break;
+
+ case PR_UNBLKONEXEC:
+ printk("irix_prctl[%s:%d]: Wants PR_UNBLKONEXEC\n",
+ current->comm, current->pid);
+ error = -EINVAL;
+ break;
+
+ case PR_SETEXITSIG:
+ printk("irix_prctl[%s:%d]: Wants PR_SETEXITSIG\n",
+ current->comm, current->pid);
+
+ /* We can probably play some game where we set the task
+ * exit_code to some non-zero value when this is requested,
+ * and check whether exit_code is already set in do_exit().
+ */
+ error = -EINVAL;
+ break;
+
+ case PR_RESIDENT:
+ printk("irix_prctl[%s:%d]: Wants PR_RESIDENT\n",
+ current->comm, current->pid);
+ error = 0; /* Compatability indeed. */
+ break;
+
+ case PR_ATTACHADDR:
+ printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDR\n",
+ current->comm, current->pid);
+ error = -EINVAL;
+ break;
+
+ case PR_DETACHADDR:
+ printk("irix_prctl[%s:%d]: Wants PR_DETACHADDR\n",
+ current->comm, current->pid);
+ error = -EINVAL;
+ break;
+
+ case PR_TERMCHILD:
+ printk("irix_prctl[%s:%d]: Wants PR_TERMCHILD\n",
+ current->comm, current->pid);
+ error = -EINVAL;
+ break;
+
+ case PR_GETSHMASK:
+ printk("irix_prctl[%s:%d]: Wants PR_GETSHMASK\n",
+ current->comm, current->pid);
+ error = -EINVAL; /* Until I have the sproc() stuff in. */
+ break;
+
+ case PR_GETNSHARE:
+ error = 0; /* Until I have the sproc() stuff in. */
+ break;
+
+ case PR_COREPID:
+ printk("irix_prctl[%s:%d]: Wants PR_COREPID\n",
+ current->comm, current->pid);
+ error = -EINVAL;
+ break;
+
+ case PR_ATTACHADDRPERM:
+ printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDRPERM\n",
+ current->comm, current->pid);
+ error = -EINVAL;
+ break;
+
+ case PR_PTHREADEXIT:
+ printk("irix_prctl[%s:%d]: Wants PR_PTHREADEXIT\n",
+ current->comm, current->pid);
+ do_exit(regs->regs[base + 5]);
+
+ default:
+ printk("irix_prctl[%s:%d]: Non-existant opcode %d\n",
+ current->comm, current->pid, (int)cmd);
+ error = -EINVAL;
+ break;
+ }
+
+ unlock_kernel();
+ return error;
+}
+
+#undef DEBUG_PROCGRPS
+
+extern unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt);
+extern asmlinkage int sys_setpgid(pid_t pid, pid_t pgid);
+extern void sys_sync(void);
+extern asmlinkage int sys_getsid(pid_t pid);
+extern asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist);
+extern asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist);
+extern int getrusage(struct task_struct *p, int who, struct rusage *ru);
+
+/* The syssgi commands supported thus far. */
+#define SGI_SYSID 1 /* Return unique per-machine identifier. */
+#define SGI_RDNAME 6 /* Return string name of a process. */
+#define SGI_SETPGID 21 /* Set process group id. */
+#define SGI_SYSCONF 22 /* POSIX sysconf garbage. */
+#define SGI_SETGROUPS 40 /* POSIX sysconf garbage. */
+#define SGI_GETGROUPS 41 /* POSIX sysconf garbage. */
+#define SGI_RUSAGE 56 /* BSD style rusage(). */
+#define SGI_SSYNC 62 /* Synchronous fs sync. */
+#define SGI_GETSID 65 /* SysVr4 get session id. */
+#define SGI_ELFMAP 68 /* Map an elf image. */
+#define SGI_TOSSTSAVE 108 /* Toss saved vma's. */
+#define SGI_FP_BCOPY 129 /* Should FPU bcopy be used on this machine? */
+#define SGI_PHYSP 1011 /* Translate virtual into physical page. */
+
+asmlinkage int irix_syssgi(struct pt_regs *regs)
+{
+ unsigned long cmd;
+ int retval, base = 0;
+
+ lock_kernel();
+ if(regs->regs[2] == 1000)
+ base = 1;
+
+ cmd = regs->regs[base + 4];
+ switch(cmd) {
+ case SGI_SYSID: {
+ char *buf = (char *) regs->regs[base + 5];
+
+ /* XXX Use ethernet addr.... */
+ retval = clear_user(buf, 64);
+ break;
+ }
+
+ case SGI_RDNAME: {
+ int pid = (int) regs->regs[base + 5];
+ char *buf = (char *) regs->regs[base + 6];
+ struct task_struct *p;
+
+ retval = verify_area(VERIFY_WRITE, buf, 16);
+ if(retval)
+ break;
+ for_each_task(p) {
+ if(p->pid == pid)
+ goto found0;
+ }
+ retval = -ESRCH;
+
+ found0:
+ copy_to_user(buf, p->comm, 16);
+ retval = 0;
+ }
+
+ case SGI_SETPGID: {
+#ifdef DEBUG_PROCGRPS
+ printk("[%s:%d] setpgid(%d, %d) ",
+ current->comm, current->pid,
+ (int) regs->regs[base + 5], (int)regs->regs[base + 6]);
+#endif
+ retval = sys_setpgid(regs->regs[base + 5], regs->regs[base + 6]);
+
+#ifdef DEBUG_PROCGRPS
+ printk("retval=%d\n", retval);
+#endif
+ }
+
+ case SGI_SYSCONF: {
+ switch(regs->regs[base + 5]) {
+ case 1:
+ retval = (MAX_ARG_PAGES >> 4); /* XXX estimate... */
+ goto out;
+ case 2:
+ retval = NR_TASKS;
+ goto out;
+ case 3:
+ retval = HZ;
+ goto out;
+ case 4:
+ retval = NGROUPS;
+ goto out;
+ case 5:
+ retval = NR_OPEN;
+ goto out;
+ case 6:
+ retval = 1;
+ goto out;
+ case 7:
+ retval = 1;
+ goto out;
+ case 8:
+ retval = 199009;
+ goto out;
+ case 11:
+ retval = PAGE_SIZE;
+ goto out;
+ case 12:
+ retval = 4;
+ goto out;
+ case 25:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ retval = 0;
+ goto out;
+ case 31:
+ retval = 32;
+ goto out;
+ default:
+ retval = -EINVAL;
+ goto out;
+ };
+ }
+
+ case SGI_SETGROUPS:
+ retval = sys_setgroups((int) regs->regs[base + 5],
+ (gid_t *) regs->regs[base + 6]);
+ break;
+
+ case SGI_GETGROUPS:
+ retval = sys_getgroups((int) regs->regs[base + 5],
+ (gid_t *) regs->regs[base + 6]);
+ break;
+
+ case SGI_RUSAGE: {
+ struct rusage *ru = (struct rusage *) regs->regs[base + 6];
+
+ switch((int) regs->regs[base + 5]) {
+ case 0:
+ /* rusage self */
+ retval = getrusage(current, RUSAGE_SELF, ru);
+ goto out;
+
+ case -1:
+ /* rusage children */
+ retval = getrusage(current, RUSAGE_CHILDREN, ru);
+ goto out;
+
+ default:
+ retval = -EINVAL;
+ goto out;
+ };
+ }
+
+ case SGI_SSYNC:
+ sys_sync();
+ retval = 0;
+ break;
+
+ case SGI_GETSID:
+#ifdef DEBUG_PROCGRPS
+ printk("[%s:%d] getsid(%d) ", current->comm, current->pid,
+ (int) regs->regs[base + 5]);
+#endif
+ retval = sys_getsid(regs->regs[base + 5]);
+#ifdef DEBUG_PROCGRPS
+ printk("retval=%d\n", retval);
+#endif
+ break;
+
+ case SGI_ELFMAP:
+ retval = irix_mapelf((int) regs->regs[base + 5],
+ (struct elf_phdr *) regs->regs[base + 6],
+ (int) regs->regs[base + 7]);
+ break;
+
+ case SGI_TOSSTSAVE:
+ /* XXX We don't need to do anything? */
+ retval = 0;
+ break;
+
+ case SGI_FP_BCOPY:
+ retval = 0;
+ break;
+
+ case SGI_PHYSP: {
+ pgd_t *pgdp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+ unsigned long addr = regs->regs[base + 5];
+ int *pageno = (int *) (regs->regs[base + 6]);
+
+ retval = verify_area(VERIFY_WRITE, pageno, sizeof(int));
+ if(retval)
+ return retval;
+ pgdp = pgd_offset(current->mm, addr);
+ pmdp = pmd_offset(pgdp, addr);
+ ptep = pte_offset(pmdp, addr);
+ if(ptep) {
+ if(pte_val(*ptep) & (_PAGE_VALID | _PAGE_PRESENT)) {
+ return put_user((pte_val(*ptep) & PAGE_MASK)>>PAGE_SHIFT, pageno);


+ return 0;
+ }
+ }

+ retval = -EINVAL;
+ break;
+ }
+
+ default:
+ printk("irix_syssgi: Unsupported command %d\n", (int)cmd);
+ retval = -EINVAL;
+ break;
+ };
+
+out:
+ unlock_kernel();
+ return retval;
+}
+
+asmlinkage int irix_gtime(struct pt_regs *regs)
+{
+ return CURRENT_TIME;
+}
+
+int vm_enough_memory(long pages);
+
+/*
+ * IRIX is completely broken... it returns 0 on success, otherwise
+ * ENOMEM.
+ */
+asmlinkage int irix_brk(unsigned long brk)
+{
+ unsigned long rlim;
+ unsigned long newbrk, oldbrk;
+ struct mm_struct *mm = current->mm;
+ int ret;
+
+ lock_kernel();
+ if (brk < current->mm->end_code) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ newbrk = PAGE_ALIGN(brk);
+ oldbrk = PAGE_ALIGN(mm->brk);
+ if (oldbrk == newbrk) {
+ mm->brk = brk;
+ ret = 0;
+ goto out;
+ }
+
+ /*
+ * Always allow shrinking brk
+ */
+ if (brk <= current->mm->brk) {
+ mm->brk = brk;
+ do_munmap(newbrk, oldbrk-newbrk);
+ ret = 0;
+ goto out;
+ }
+ /*
+ * Check against rlimit and stack..
+ */
+ rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+ if (rlim >= RLIM_INFINITY)
+ rlim = ~0;
+ if (brk - mm->end_code > rlim) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /*
+ * Check against existing mmap mappings.
+ */
+ if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) {
+ return -ENOMEM;
+ goto out;
+ }
+
+ /*
+ * Check if we have enough memory..
+ */
+ if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) {
+ return -ENOMEM;
+ goto out;
+ }
+
+ /*
+ * Ok, looks good - let it rip.
+ */
+ mm->brk = brk;
+ do_mmap(NULL, oldbrk, newbrk-oldbrk,
+ PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_FIXED|MAP_PRIVATE, 0);
+
+ ret = 0;
+
+out:
+ unlock_kernel();
+ return ret;
+}
+
+asmlinkage int irix_getpid(struct pt_regs *regs)
+{
+ regs->regs[3] = current->p_opptr->pid;
+ return current->pid;
+}
+
+asmlinkage int irix_getuid(struct pt_regs *regs)
+{
+ regs->regs[3] = current->euid;
+ return current->uid;
+}
+
+asmlinkage int irix_getgid(struct pt_regs *regs)
+{
+ regs->regs[3] = current->egid;
+ return current->gid;
+}
+
+asmlinkage int irix_stime(int value)
+{
+ int ret;
+
+ lock_kernel();
+ if(!suser()) {
+ ret = -EPERM;
+ goto out;
+ }
+ cli();
+ xtime.tv_sec = value;
+ xtime.tv_usec = 0;
+ time_state = TIME_ERROR;
+ time_maxerror = MAXPHASE;
+ time_esterror = MAXPHASE;
+ sti();
+ ret = 0;
+
+out:
+ unlock_kernel();
+ return ret;
+}
+
+extern int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue);
+
+static inline void jiffiestotv(unsigned long jiffies, struct timeval *value)
+{
+ value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
+ value->tv_sec = jiffies / HZ;
+ return;
+}
+
+static inline void getitimer_real(struct itimerval *value)
+{
+ register unsigned long val, interval;
+
+ interval = current->it_real_incr;
+ val = 0;
+ if (del_timer(&current->real_timer)) {
+ unsigned long now = jiffies;
+ val = current->real_timer.expires;
+ add_timer(&current->real_timer);
+ /* look out for negative/zero itimer.. */
+ if (val <= now)
+ val = now+1;
+ val -= now;
+ }
+ jiffiestotv(val, &value->it_value);
+ jiffiestotv(interval, &value->it_interval);
+}
+
+asmlinkage unsigned int irix_alarm(unsigned int seconds)
+{
+ struct itimerval it_new, it_old;
+ unsigned int oldalarm;
+
+ lock_kernel();
+ if(!seconds) {
+ getitimer_real(&it_old);
+ del_timer(&current->real_timer);
+ } else {
+ it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
+ it_new.it_value.tv_sec = seconds;
+ it_new.it_value.tv_usec = 0;
+ _setitimer(ITIMER_REAL, &it_new, &it_old);
+ }
+ oldalarm = it_old.it_value.tv_sec;
+ /* ehhh.. We can't return 0 if we have an alarm pending.. */
+ /* And we'd better return too much than too little anyway */
+ if (it_old.it_value.tv_usec)
+ oldalarm++;
+ unlock_kernel();
+ return oldalarm;
+}
+
+asmlinkage int irix_pause(void)
+{
+ lock_kernel();
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ unlock_kernel();
+ return -EINTR;
+}
+
+extern asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
+ unsigned long new_flags, void * data);
+
+/* XXX need more than this... */
+asmlinkage int irix_mount(char *dev_name, char *dir_name, unsigned long flags,
+ char *type, void *data, int datalen)
+{
+ int ret;
+
+ lock_kernel();
+ printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n",
+ current->comm, current->pid,
+ dev_name, dir_name, flags, type, data, datalen);
+ ret = sys_mount(dev_name, dir_name, type, flags, data);
+
+ unlock_kernel();
+ return ret;
+}
+
+struct irix_statfs {
+ short f_type;
+ long f_bsize, f_frsize, f_blocks, f_bfree, f_files, f_ffree;
+ char f_fname[6], f_fpack[6];
+};
+
+asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
+ int len, int fs_type)
+{
+ struct inode *inode;
+ struct statfs kbuf;
+ int error, old_fs, i;
+
+ /* We don't support this feature yet. */
+ if(fs_type) {
+ error = -EINVAL;
+ goto out;
+ }
+ error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
+ if (error)
+ goto out;
+ error = namei(NAM_FOLLOW_LINK, path, &inode);
+ if (error)
+ goto out;
+ if (!inode->i_sb->s_op->statfs) {
+ iput(inode);
+ error = -ENOSYS;
+ goto out;
+ }
+
+ old_fs = get_fs(); set_fs(get_ds());
+ inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs));
+ set_fs(old_fs);
+
+ iput(inode);
+ __put_user(kbuf.f_type, &buf->f_type);
+ __put_user(kbuf.f_bsize, &buf->f_bsize);
+ __put_user(kbuf.f_frsize, &buf->f_frsize);
+ __put_user(kbuf.f_blocks, &buf->f_blocks);
+ __put_user(kbuf.f_bfree, &buf->f_bfree);
+ __put_user(kbuf.f_files, &buf->f_files);
+ __put_user(kbuf.f_ffree, &buf->f_ffree);
+ for(i = 0; i < 6; i++) {
+ __put_user(0, &buf->f_fname[i]);
+ __put_user(0, &buf->f_fpack[i]);
+ }
+ error = 0;
+
+out:
+ unlock_kernel();
+ return error;
+}
+
+asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
+{
+ struct inode * inode;
+ struct statfs kbuf;
+ struct file *file;
+ int error, old_fs, i;
+
+ lock_kernel();
+ error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
+ if (error)
+ goto out;
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ error = -EBADF;
+ goto out;
+ }
+ if (!(inode = file->f_inode)) {
+ error = -ENOENT;
+ goto out;
+ }
+ if (!inode->i_sb->s_op->statfs) {
+ error = -ENOSYS;
+ goto out;
+ }
+
+ old_fs = get_fs(); set_fs(get_ds());
+ inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs));
+ set_fs(old_fs);
+
+ __put_user(kbuf.f_type, &buf->f_type);
+ __put_user(kbuf.f_bsize, &buf->f_bsize);
+ __put_user(kbuf.f_frsize, &buf->f_frsize);
+ __put_user(kbuf.f_blocks, &buf->f_blocks);
+ __put_user(kbuf.f_bfree, &buf->f_bfree);
+ __put_user(kbuf.f_files, &buf->f_files);
+ __put_user(kbuf.f_ffree, &buf->f_ffree);
+ for(i = 0; i < 6; i++) {
+ __put_user(0, &buf->f_fname[i]);
+ __put_user(0, &buf->f_fpack[i]);
+ }
+ error = 0;
+
+out:
+ unlock_kernel();
+ return error;
+}
+
+extern asmlinkage int sys_setpgid(pid_t pid, pid_t pgid);
+extern asmlinkage int sys_setsid(void);
+
+asmlinkage int irix_setpgrp(int flags)
+{
+ int error;
+
+ lock_kernel();
+#ifdef DEBUG_PROCGRPS
+ printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
+#endif
+ if(!flags)
+ error = current->pgrp;
+ else
+ error = sys_setsid();
+#ifdef DEBUG_PROCGRPS
+ printk("returning %d\n", current->pgrp);
+#endif
+
+ unlock_kernel();
+ return error;
+}
+
+asmlinkage int irix_times(struct tms * tbuf)
+{
+ int error;
+
+ lock_kernel();
+ if (tbuf) {
+ error = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf);
+ if (error)
+ goto out;
+ __put_user(current->times.tms_utime,&tbuf->tms_utime);
+ __put_user(current->times.tms_stime,&tbuf->tms_stime);
+ __put_user(current->times.tms_cutime,&tbuf->tms_cutime);
+ __put_user(current->times.tms_cstime,&tbuf->tms_cstime);
+ }
+ error = 0;
+
+out:
+ unlock_kernel();
+ return error;
+}
+
+asmlinkage int irix_exec(struct pt_regs *regs)
+{
+ int error, base = 0;
+ char * filename;
+
+ lock_kernel();
+ if(regs->regs[2] == 1000)
+ base = 1;
+ error = getname((char *) (long)regs->regs[base + 4], &filename);
+ if (error)
+ goto out;
+ error = do_execve(filename, (char **) (long)regs->regs[base + 5],
+ (char **) 0, regs);
+ putname(filename);
+
+out:
+ unlock_kernel();
+ return error;
+}
+
+asmlinkage int irix_exece(struct pt_regs *regs)
+{
+ int error, base = 0;
+ char * filename;
+
+ lock_kernel();
+ if(regs->regs[2] == 1000)
+ base = 1;
+ error = getname((char *) (long)regs->regs[base + 4], &filename);
+ if (error)
+ goto out;
+ error = do_execve(filename, (char **) (long)regs->regs[base + 5],
+ (char **) (long)regs->regs[base + 6], regs);
+ putname(filename);
+
+out:
+ unlock_kernel();
+ return error;
+}
+
+asmlinkage unsigned long irix_gethostid(void)
+{
+ lock_kernel();
+ printk("[%s:%d]: irix_gethostid() called...\n",
+ current->comm, current->pid);
+ unlock_kernel();


+ return -EINVAL;
+}
+

+asmlinkage unsigned long irix_sethostid(unsigned long val)
+{
+ lock_kernel();
+ printk("[%s:%d]: irix_sethostid(%08lx) called...\n",
+ current->comm, current->pid, val);
+ unlock_kernel();


+ return -EINVAL;
+}
+

+extern asmlinkage int sys_socket(int family, int type, int protocol);
+
+asmlinkage int irix_socket(int family, int type, int protocol)
+{
+ switch(type) {
+ case 1:
+ type = SOCK_DGRAM;
+ break;
+
+ case 2:
+ type = SOCK_STREAM;
+ break;
+
+ case 3:
+ type = 9; /* Invalid... */
+ break;
+
+ case 4:
+ type = SOCK_RAW;
+ break;
+
+ case 5:
+ type = SOCK_RDM;
+ break;
+
+ case 6:
+ type = SOCK_SEQPACKET;


+ break;
+
+ default:

+ break;
+ }
+
+ return sys_socket(family, type, protocol);
+}
+
+asmlinkage int irix_getdomainname(char *name, int len)
+{
+ int error;
+
+ lock_kernel();
+ if(len > (__NEW_UTS_LEN - 1))
+ len = __NEW_UTS_LEN - 1;
+ error = verify_area(VERIFY_WRITE, name, len);
+ if(error)
+ goto out;
+ if(copy_to_user(name, system_utsname.domainname, len)) {
+ error = -EFAULT;
+ goto out;
+ }
+ error = 0;
+
+out:
+ unlock_kernel();
+ return error;
+}
+
+asmlinkage unsigned long irix_getpagesize(void)
+{
+ return PAGE_SIZE;
+}
+
+asmlinkage int irix_msgsys(int opcode, unsigned long arg0, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3,
+ unsigned long arg4)
+{
+ switch(opcode) {
+ case 0:
+ return sys_msgget((key_t) arg0, (int) arg1);
+ case 1:
+ return sys_msgctl((int) arg0, (int) arg1, (struct msqid_ds *)arg2);
+ case 2:
+ return sys_msgrcv((int) arg0, (struct msgbuf *) arg1,
+ (size_t) arg2, (long) arg3, (int) arg4);
+ case 3:
+ return sys_msgsnd((int) arg0, (struct msgbuf *) arg1,
+ (size_t) arg2, (int) arg3);
+ default:


+ return -EINVAL;
+ }
+}
+

+asmlinkage int irix_shmsys(int opcode, unsigned long arg0, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3)
+{
+ switch(opcode) {
+ case 0:
+ return sys_shmat((int) arg0, (char *)arg1, (int) arg2,
+ (unsigned long *) arg3);
+ case 1:
+ return sys_shmctl((int)arg0, (int)arg1, (struct shmid_ds *)arg2);
+ case 2:
+ return sys_shmdt((char *)arg0);
+ case 3:
+ return sys_shmget((key_t) arg0, (int) arg1, (int) arg2);
+ default:


+ return -EINVAL;
+ }
+}
+

+asmlinkage int irix_semsys(int opcode, unsigned long arg0, unsigned long arg1,
+ unsigned long arg2, int arg3)
+{
+ switch(opcode) {
+ case 0:
+ return sys_semctl((int) arg0, (int) arg1, (int) arg2,
+ (union semun) arg3);
+ case 1:
+ return sys_semget((key_t) arg0, (int) arg1, (int) arg2);
+ case 2:
+ return sys_semop((int) arg0, (struct sembuf *)arg1,
+ (unsigned int) arg2);
+ default:


+ return -EINVAL;
+ }
+}
+

+extern asmlinkage int sys_llseek(unsigned int fd, unsigned long offset_high,
+ unsigned long offset_low, loff_t * result,
+ unsigned int origin);
+
+asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow, int base)
+{
+ loff_t junk;
+ int old_fs, error;
+
+ lock_kernel();
+ old_fs = get_fs(); set_fs(get_ds());
+ error = sys_llseek(fd, offhi, offlow, &junk, base);
+ set_fs(old_fs);
+
+ if(error)
+ goto out;
+ error = (int) junk;
+out:
+ unlock_kernel();
+ return error;
+}
+
+asmlinkage int irix_sginap(int ticks)
+{
+ lock_kernel();
+ if(ticks) {
+ current->timeout = ticks + jiffies;
+ current->state = TASK_INTERRUPTIBLE;
+ }
+ schedule();
+ unlock_kernel();


+ return 0;
+}
+

+asmlinkage int irix_sgikopt(char *istring, char *ostring, int len)


+{
+ return -EINVAL;
+}
+

+asmlinkage int irix_gettimeofday(struct timeval *tv)
+{
+ int retval;
+
+ lock_kernel();
+ retval = copy_to_user(tv, &xtime, sizeof(*tv)) ? -EFAULT : 0;
+ unlock_kernel();
+ return retval;
+}
+
+asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
+ int flags, int fd, off_t offset)
+{
+ struct file *file = NULL;
+ unsigned long retval;
+
+ lock_kernel();
+ if(!(flags & MAP_ANONYMOUS)) {
+ if(fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ retval = -EBADF;
+ goto out;
+ }
+ }
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+ retval = do_mmap(file, addr, len, prot, flags, offset);
+
+out:
+ unlock_kernel();
+ return retval;
+}
+
+asmlinkage int irix_madvise(unsigned long addr, int len, int behavior)
+{
+ lock_kernel();
+ printk("[%s:%d] Wheee.. irix_madvise(%08lx,%d,%d)\n",
+ current->comm, current->pid, addr, len, behavior);
+ unlock_kernel();


+ return -EINVAL;
+}
+

+asmlinkage int irix_pagelock(char *addr, int len, int op)
+{
+ lock_kernel();
+ printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n",
+ current->comm, current->pid, addr, len, op);
+ unlock_kernel();


+ return -EINVAL;
+}
+

+asmlinkage int irix_quotactl(struct pt_regs *regs)
+{
+ lock_kernel();
+ printk("[%s:%d] Wheee.. irix_quotactl()\n",
+ current->comm, current->pid);
+ unlock_kernel();


+ return -EINVAL;
+}
+

+asmlinkage int irix_BSDsetpgrp(int pid, int pgrp)
+{
+ int error;
+
+ lock_kernel();
+#ifdef DEBUG_PROCGRPS
+ printk("[%s:%d] BSDsetpgrp(%d, %d) ", current->comm, current->pid,
+ pid, pgrp);
+#endif
+ if(!pid)
+ pid = current->pid;
+
+ /* Wheee, weird sysv thing... */
+ if((pgrp == 0) && (pid == current->pid))
+ error = sys_setsid();
+ else
+ error = sys_setpgid(pid, pgrp);
+
+#ifdef DEBUG_PROCGRPS
+ printk("error = %d\n", error);
+#endif
+
+ unlock_kernel();
+ return error;
+}
+
+asmlinkage int irix_systeminfo(int cmd, char *buf, int cnt)
+{
+ lock_kernel();
+ printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n",
+ current->comm, current->pid, cmd, buf, cnt);
+ unlock_kernel();


+ return -EINVAL;
+}
+

+struct iuname {
+ char sysname[257], nodename[257], release[257];
+ char version[257], machine[257];
+ char m_type[257], base_rel[257];
+ char _unused0[257], _unused1[257], _unused2[257];
+ char _unused3[257], _unused4[257], _unused5[257];
+};
+
+asmlinkage int irix_uname(struct iuname *buf)
+{
+ int retval;
+
+ lock_kernel();
+ if(copy_to_user(system_utsname.sysname, buf->sysname, 65)
+ || copy_to_user(system_utsname.nodename, buf->nodename, 65)
+ || copy_to_user(system_utsname.release, buf->release, 65)
+ || copy_to_user(system_utsname.version, buf->version, 65)
+ || copy_to_user(system_utsname.machine, buf->machine, 65)) {
+ retval = -EFAULT;
+ goto out;
+ }
+ retval = 1;
+
+out:
+ unlock_kernel();
+ return retval;
+}
+
+#undef DEBUG_XSTAT
+
+static inline int irix_xstat32_xlate(struct stat *kb, struct stat *ubuf)
+{
+ struct xstat32 {
+ u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
+ u32 st_rdev, st_pad2[2], st_size, st_pad3;
+ u32 st_atime0, st_atime1;
+ u32 st_mtime0, st_mtime1;
+ u32 st_ctime0, st_ctime1;
+ u32 st_blksize, st_blocks;
+ char st_fstype[16];
+ u32 st_pad4[8];
+ } *ub = (struct xstat32 *) ubuf;
+
+ return copy_to_user(ub, kb, sizeof(*ub)) ? -EFAULT : 0;
+}
+
+static inline void irix_xstat64_xlate(struct stat *sb)
+{
+ struct xstat64 {
+ u32 st_dev; s32 st_pad1[3];
+ unsigned long long st_ino;
+ u32 st_mode;
+ u32 st_nlink; s32 st_uid; s32 st_gid; u32 st_rdev;
+ s32 st_pad2[2];
+ long long st_size;
+ s32 st_pad3;
+ struct { s32 tv_sec, tv_nsec; } st_atime, st_mtime, st_ctime;
+ s32 st_blksize;
+ long long st_blocks;
+ char st_fstype[16];
+ s32 st_pad4[8];
+ } ks;
+
+ ks.st_dev = (u32) sb->st_dev;
+ ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;
+ ks.st_ino = (unsigned long long) sb->st_ino;
+ ks.st_mode = (u32) sb->st_mode;
+ ks.st_nlink = (u32) sb->st_nlink;
+ ks.st_uid = (s32) sb->st_uid;
+ ks.st_gid = (s32) sb->st_gid;
+ ks.st_rdev = (u32) sb->st_rdev;
+ ks.st_pad2[0] = ks.st_pad2[1] = 0;
+ ks.st_size = (long long) sb->st_size;
+ ks.st_pad3 = 0;
+
+ /* XXX hackety hack... */
+ ks.st_atime.tv_sec = (s32) sb->st_atime; ks.st_atime.tv_nsec = 0;
+ ks.st_mtime.tv_sec = (s32) sb->st_atime; ks.st_mtime.tv_nsec = 0;
+ ks.st_ctime.tv_sec = (s32) sb->st_atime; ks.st_ctime.tv_nsec = 0;
+
+ ks.st_blksize = (s32) sb->st_blksize;
+ ks.st_blocks = (long long) sb->st_blocks;
+ memcpy(&ks.st_fstype[0], &sb->st_fstype[0], 16);
+ ks.st_pad4[0] = ks.st_pad4[1] = ks.st_pad4[2] = ks.st_pad4[3] =
+ ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0;
+
+ /* Now write it all back. */
+ copy_to_user(sb, &ks, sizeof(struct xstat64));
+}
+
+extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf);
+
+asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
+{
+ int retval;
+
+ lock_kernel();
+#ifdef DEBUG_XSTAT
+ printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ",
+ current->comm, current->pid, version, filename, statbuf);
+#endif
+ switch(version) {
+ case 2: {
+ struct stat kb;
+ int old_fs;
+
+ old_fs = get_fs(); set_fs(get_ds());
+ retval = sys_newstat(filename, &kb);
+ set_fs(old_fs);
+#ifdef DEBUG_XSTAT
+ printk("retval[%d]\n", retval);
+#endif
+ if(retval)
+ goto out;
+ retval = irix_xstat32_xlate(&kb, statbuf);
+ goto out;
+ }
+
+ case 3: {
+ retval = sys_newstat(filename, statbuf);
+#ifdef DEBUG_XSTAT
+ printk("retval[%d]\n", retval);
+#endif
+ if(retval)
+ goto out;
+
+ irix_xstat64_xlate(statbuf);
+ retval = 0;
+ break;
+ }
+
+ default:
+ retval = -EINVAL;
+ break;
+ }
+
+out:
+ unlock_kernel();
+ return retval;
+}
+
+extern asmlinkage int sys_newlstat(char * filename, struct stat * statbuf);
+
+asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
+{
+ int error;
+
+ lock_kernel();
+#ifdef DEBUG_XSTAT
+ printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ",
+ current->comm, current->pid, version, filename, statbuf);
+#endif
+ switch(version) {
+ case 2: {
+ struct stat kb;
+ int old_fs;
+
+ old_fs = get_fs(); set_fs(get_ds());
+ error = sys_newlstat(filename, &kb);
+ set_fs(old_fs);
+#ifdef DEBUG_XSTAT
+ printk("error[%d]\n", error);
+#endif
+ if(error)
+ goto out;
+ error = irix_xstat32_xlate(&kb, statbuf);
+ goto out;
+ }
+
+ case 3: {
+ error = sys_newlstat(filename, statbuf);
+#ifdef DEBUG_XSTAT
+ printk("error[%d]\n", error);
+#endif
+ if(error)
+ goto out;
+
+ irix_xstat64_xlate(statbuf);
+ error = 0;
+ goto out;
+ }
+
+ default:
+ error = -EINVAL;
+ goto out;
+ }
+
+out:
+ unlock_kernel();
+ return error;
+}
+
+extern asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf);
+
+asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
+{
+ int error;
+
+ lock_kernel();
+#ifdef DEBUG_XSTAT
+ printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ",
+ current->comm, current->pid, version, fd, statbuf);
+#endif
+ switch(version) {
+ case 2: {
+ struct stat kb;
+ int old_fs;
+
+ old_fs = get_fs(); set_fs(get_ds());
+ error = sys_newfstat(fd, &kb);
+ set_fs(old_fs);
+#ifdef DEBUG_XSTAT
+ printk("error[%d]\n", error);
+#endif
+ if(error)
+ goto out;
+ error = irix_xstat32_xlate(&kb, statbuf);
+ goto out;
+ }
+
+ case 3: {
+ error = sys_newfstat(fd, statbuf);
+#ifdef DEBUG_XSTAT
+ printk("error[%d]\n", error);
+#endif
+ if(error)
+ goto out;
+
+ irix_xstat64_xlate(statbuf);
+ error = 0;
+ goto out;
+ }
+
+ default:
+ error = -EINVAL;
+ goto out;
+ }
+
+out:
+ unlock_kernel();
+ return error;
+}
+
+extern asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev);
+
+asmlinkage int irix_xmknod(int ver, char *filename, int mode, dev_t dev)
+{
+ int retval;
+
+ lock_kernel();
+ printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
+ current->comm, current->pid, ver, filename, mode, (int) dev);
+ switch(ver) {
+ case 2:
+ retval = sys_mknod(filename, mode, dev);
+ goto out;
+
+ default:
+ retval = -EINVAL;
+ goto out;
+ };
+
+out:
+ unlock_kernel();
+ return retval;
+}
+
+asmlinkage int irix_swapctl(int cmd, char *arg)
+{
+ lock_kernel();
+ printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n",
+ current->comm, current->pid, cmd, arg);
+ unlock_kernel();


+ return -EINVAL;
+}
+

+struct irix_statvfs {
+ u32 f_bsize; u32 f_frsize; u32 f_blocks;
+ u32 f_bfree; u32 f_bavail; u32 f_files; u32 f_ffree; u32 f_favail;
+ u32 f_fsid; char f_basetype[16];
+ u32 f_flag; u32 f_namemax;
+ char f_fstr[32]; u32 f_filler[16];
+};
+
+asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
+{
+ struct inode *inode;
+ struct statfs kbuf;
+ int error, old_fs, i;
+
+ lock_kernel();
+ printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
+ current->comm, current->pid, fname, buf);
+ error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
+ if(error)
+ goto out;
+ error = namei(NAM_FOLLOW_LINK, fname, &inode);
+ if(error)
+ goto out;
+ if(!inode->i_sb->s_op->statfs) {
+ iput(inode);
+ error = -ENOSYS;
+ goto out;
+ }
+
+ old_fs = get_fs(); set_fs(get_ds());
+ inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs));
+ set_fs(old_fs);
+
+ iput(inode);
+ __put_user(kbuf.f_bsize, &buf->f_bsize);
+ __put_user(kbuf.f_frsize, &buf->f_frsize);
+ __put_user(kbuf.f_blocks, &buf->f_blocks);
+ __put_user(kbuf.f_bfree, &buf->f_bfree);
+ __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+ __put_user(kbuf.f_files, &buf->f_files);
+ __put_user(kbuf.f_ffree, &buf->f_ffree);
+ __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+#ifdef __MIPSEB__
+ __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+#else
+ __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+#endif
+ for(i = 0; i < 16; i++)
+ __put_user(0, &buf->f_basetype[i]);
+ __put_user(0, &buf->f_flag);
+ __put_user(kbuf.f_namelen, &buf->f_namemax);
+ for(i = 0; i < 32; i++)
+ __put_user(0, &buf->f_fstr[i]);
+
+ error = 0;
+
+out:
+ unlock_kernel();
+ return error;
+}
+
+asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
+{
+ struct inode * inode;
+ struct statfs kbuf;
+ struct file *file;
+ int error, old_fs, i;
+
+ lock_kernel();
+ printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
+ current->comm, current->pid, fd, buf);
+
+ error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
+ if (error)
+ goto out;
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ error = -EBADF;
+ goto out;
+ }
+ if (!(inode = file->f_inode)) {
+ error = -ENOENT;
+ goto out;
+ }
+ if (!inode->i_sb->s_op->statfs) {
+ error = -ENOSYS;
+ goto out;
+ }
+
+ old_fs = get_fs(); set_fs(get_ds());
+ inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs));
+ set_fs(old_fs);
+
+ __put_user(kbuf.f_bsize, &buf->f_bsize);
+ __put_user(kbuf.f_frsize, &buf->f_frsize);
+ __put_user(kbuf.f_blocks, &buf->f_blocks);
+ __put_user(kbuf.f_bfree, &buf->f_bfree);
+ __put_user(kbuf.f_bfree, &buf->f_bavail); /* XXX hackety hack... */
+ __put_user(kbuf.f_files, &buf->f_files);
+ __put_user(kbuf.f_ffree, &buf->f_ffree);
+ __put_user(kbuf.f_ffree, &buf->f_favail); /* XXX hackety hack... */
+#ifdef __MIPSEB__
+ __put_user(kbuf.f_fsid.val[1], &buf->f_fsid);
+#else
+ __put_user(kbuf.f_fsid.val[0], &buf->f_fsid);
+#endif
+ for(i = 0; i < 16; i++)
+ __put_user(0, &buf->f_basetype[i]);
+ __put_user(0, &buf->f_flag);
+ __put_user(kbuf.f_namelen, &buf->f_namemax);
+ for(i = 0; i < 32; i++)
+ __put_user(0, &buf->f_fstr[i]);
+
+ error = 0;
+
+out:
+ unlock_kernel();
+ return error;
+}
+
+#define NOFOLLOW_LINKS NAM_FOLLOW_TRAILSLASH
+#define FOLLOW_LINKS NAM_FOLLOW_LINK
+
+static inline int chown_common(char *filename, uid_t user, gid_t group, int follow)
+{
+ struct inode * inode;
+ int error;
+ struct iattr newattrs;
+
+ error = namei(follow, filename,&inode);
+ if (error)
+ return error;
+ if (IS_RDONLY(inode)) {
+ iput(inode);
+ return -EROFS;
+ }
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) {
+ iput(inode);
+ return -EPERM;
+ }
+ if (user == (uid_t) -1)
+ user = inode->i_uid;
+ if (group == (gid_t) -1)
+ group = inode->i_gid;
+ newattrs.ia_mode = inode->i_mode;
+ newattrs.ia_uid = user;
+ newattrs.ia_gid = group;
+ newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME;
+ /*
+ * If the owner has been changed, remove the setuid bit
+ */
+ if (inode->i_mode & S_ISUID) {
+ newattrs.ia_mode &= ~S_ISUID;
+ newattrs.ia_valid |= ATTR_MODE;
+ }
+ /*
+ * If the group has been changed, remove the setgid bit
+ *
+ * Don't remove the setgid bit if no group execute bit.
+ * This is a file marked for mandatory locking.
+ */
+ if (((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) {
+ newattrs.ia_mode &= ~S_ISGID;
+ newattrs.ia_valid |= ATTR_MODE;
+ }
+ inode->i_dirt = 1;
+ if (inode->i_sb->dq_op) {
+ inode->i_sb->dq_op->initialize(inode, -1);
+ if (inode->i_sb->dq_op->transfer(inode, &newattrs, 0))
+ return -EDQUOT;
+ error = notify_change(inode, &newattrs);
+ if (error)
+ inode->i_sb->dq_op->transfer(inode, &newattrs, 1);
+ } else
+ error = notify_change(inode, &newattrs);
+ iput(inode);
+ return(error);
+}
+
+asmlinkage int irix_chown(char *fname, int uid, int gid)
+{
+ int retval;
+
+ lock_kernel();
+ /* Do follow any and all links... */
+ retval = chown_common(fname, uid, gid, FOLLOW_LINKS);
+ unlock_kernel();
+ return retval;
+}
+
+asmlinkage int irix_lchown(char *fname, int uid, int gid)
+{
+ int retval;
+
+ lock_kernel();
+ /* Do _not_ follow any links... */
+ retval = chown_common(fname, uid, gid, NOFOLLOW_LINKS);
+ unlock_kernel();
+ return retval;
+}
+
+asmlinkage int irix_priocntl(struct pt_regs *regs)
+{
+ lock_kernel();
+ printk("[%s:%d] Wheee.. irix_priocntl()\n",
+ current->comm, current->pid);
+ unlock_kernel();


+ return -EINVAL;
+}
+

+asmlinkage int irix_sigqueue(int pid, int sig, int code, int val)
+{
+ lock_kernel();
+ printk("[%s:%d] Wheee.. irix_sigqueue(%d,%d,%d,%d)\n",
+ current->comm, current->pid, pid, sig, code, val);
+ unlock_kernel();


+ return -EINVAL;
+}
+

+extern asmlinkage int sys_truncate(const char * path, unsigned long length);
+extern asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length);
+
+asmlinkage int irix_truncate64(char *name, int pad, int size1, int size2)
+{
+ int retval;
+
+ lock_kernel();
+ if(size1) {
+ retval = -EINVAL;
+ goto out;
+ }
+ retval = sys_truncate(name, size2);
+
+out:
+ unlock_kernel();
+ return retval;
+}
+
+asmlinkage int irix_ftruncate64(int fd, int pad, int size1, int size2)
+{
+ int retval;
+
+ lock_kernel();
+ if(size1) {
+ retval = -EINVAL;
+ goto out;
+ }
+ retval = sys_ftruncate(fd, size2);
+
+out:
+ unlock_kernel();
+ return retval;
+}
+
+extern asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, int prot,
+ int flags, int fd, off_t offset);
+
+asmlinkage int irix_mmap64(struct pt_regs *regs)
+{
+ unsigned long addr, *sp;
+ int len, prot, flags, fd, off1, off2, base = 0;
+ int error;
+
+ lock_kernel();
+ if(regs->regs[2] == 1000)
+ base = 1;
+ sp = (unsigned long *) (regs->regs[29] + 16);
+ addr = regs->regs[base + 4];
+ len = regs->regs[base + 5];
+ prot = regs->regs[base + 6];


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 12'
echo 'File patch-2.1.44 is continued in part 13'
echo 13 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part21

#!/bin/sh
# this is part 21 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 21; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_brk
+ mov %g1, %o7
+sys32_msync:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ srl %o1, 0, %o1
+ call sys_msync
+ mov %g1, %o7
+sys32_mlock:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ srl %o1, 0, %o1
+ call sys_mlock
+ mov %g1, %o7
+sys32_munlock:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ srl %o1, 0, %o1
+ call sys_munlock
+ mov %g1, %o7
+sys32_mremap:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ srl %o1, 0, %o1
+ srl %o2, 0, %o2
+ srl %o3, 0, %o3
+ call sys_mremap
+ mov %g1, %o7
+
+ .align 32
+ .globl sys32_read, sys32_write, sys32_open, sys32_access
+ .globl sys32_chdir, sys32_lseek, sys32_llseek, sys32_poll
+ .globl sys32_readlink, sys32_unlink, sys32_rmdir, sys32_symlink
+ .globl sys32_link, sys32_rename, sys32_truncate, sys32_ftruncate
+ .globl sys32_chroot, sys32_chmod, sys32_chown, sys32_creat
+ .globl sys32_mkdir, sys32_mknod, sys32_utimes, sys32_ustat
+sys32_read:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ srl %o2, 0, %o2
+ call sys_read
+ mov %g1, %o7
+sys32_write:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ srl %o2, 0, %o2
+ call sys_write
+ mov %g1, %o7
+sys32_open:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_open
+ mov %g1, %o7
+sys32_access:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_access
+ mov %g1, %o7
+sys32_chdir:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_chdir
+ mov %g1, %o7
+sys32_lseek:
+ sra %o1, 0, %o1
+ mov %o7, %g1
+ call sys_lseek
+ mov %g1, %o7
+sys32_llseek:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ srl %o2, 0, %o2
+ srl %o3, 0, %o3
+ call sys_llseek
+ mov %g1, %o7
+sys32_poll:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_poll
+ mov %g1, %o7
+sys32_readlink:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ srl %o1, 0, %o1
+ call sys_readlink
+ mov %g1, %o7
+sys32_unlink:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_unlink
+ mov %g1, %o7
+sys32_rmdir:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_rmdir
+ mov %g1, %o7
+sys32_symlink:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ srl %o1, 0, %o1
+ call sys_symlink
+ mov %g1, %o7
+sys32_link:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ srl %o1, 0, %o1
+ call sys_link
+ mov %g1, %o7
+sys32_rename:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ srl %o1, 0, %o1
+ call sys_rename
+ mov %g1, %o7
+ nop
+sys32_truncate:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ srl %o1, 0, %o1
+ call sys_truncate
+ mov %g1, %o7
+sys32_ftruncate:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ call sys_ftruncate
+ mov %g1, %o7
+sys32_chroot:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_chroot
+ mov %g1, %o7
+sys32_chmod:
+ sll %o1, 16, %o1
+ mov %o7, %g1
+ srl %o0, 0, %o0
+ srl %o1, 16, %o1
+ call sys_chmod
+ mov %g1, %o7
+sys32_chown:
+ sll %o1, 16, %o1
+ mov %o7, %g1
+ sll %o2, 16, %o2
+ srl %o0, 0, %o0
+ srl %o1, 16, %o1
+ srl %o2, 16, %o2
+ call sys_chown
+ mov %g1, %o7
+sys32_creat:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_creat
+ mov %g1, %o7
+sys32_mkdir:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_mkdir
+ mov %g1, %o7
+sys32_mknod:
+ sll %o2, 16, %o2
+ mov %o7, %g1
+ srl %o0, 0, %o0
+ srl %o2, 16, %o2
+ call sys_mknod
+ mov %g1, %o7
+sys32_utimes:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ srl %o1, 0, %o1
+ call sys_utimes
+ mov %g1, %o7
+sys32_ustat:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ call sys_ustat
+ mov %g1, %o7
+
+ .align 32
+ .globl sys32_bind, sys32_accept, sys32_connect, sys32_getsockname
+ .globl sys32_getpeername, sys32_send, sys32_sendto, sys32_recv
+ .globl sys32_recvfrom, sys32_setsockopt, sys32_getsockopt
+sys32_bind:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ call sys_bind
+ mov %g1, %o7
+sys32_accept:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ srl %o2, 0, %o2
+ call sys_accept
+ mov %g1, %o7
+sys32_connect:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ call sys_connect
+ mov %g1, %o7
+sys32_getsockname:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ srl %o2, 0, %o2
+ call sys_getsockname
+ mov %g1, %o7
+sys32_getpeername:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ srl %o2, 0, %o2
+ call sys_getpeername
+ mov %g1, %o7
+sys32_send:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ srl %o2, 0, %o2
+ call sys_send
+ mov %g1, %o7
+sys32_sendto:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ srl %o2, 0, %o2
+ srl %o4, 0, %o4
+ call sys_sendto
+ mov %g1, %o7
+sys32_recv:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ srl %o2, 0, %o2
+ call sys_recv
+ mov %g1, %o7
+sys32_recvfrom:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ srl %o2, 0, %o2
+ srl %o4, 0, %o4
+ srl %o5, 0, %o5
+ call sys_recvfrom
+ mov %g1, %o7
+sys32_setsockopt:
+ srl %o3, 0, %o3
+ mov %o7, %g1
+ call sys_setsockopt
+ mov %g1, %o7
+sys32_getsockopt:
+ srl %o3, 0, %o3
+ mov %o7, %g1
+ srl %o4, 0, %o4
+ call sys_setsockopt
+ mov %g1, %o7
+
+ .align 32
+ .globl sys32_gettimeofday, sys32_settimeofday
+sys32_gettimeofday:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ srl %o1, 0, %o1
+ call sys_gettimeofday
+ mov %g1, %o7
+sys32_settimeofday:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ srl %o1, 0, %o1
+ call sys_settimeofday
+ mov %g1, %o7
+
+ .globl sys32_bdflush, sys32_uselib, sys32_umount, sys32_syslog
+ .globl sys32_personality, sys32_waitpid, sys32_getitimer
+ .globl sys32_setitimer, sys32_sched_setscheduler
+ .globl sys32_sched_setparam, sys32_sched_getparam, sys32_signal
+ .globl sys32_reboot, sys32_acct, sys32_newuname, sys32_olduname
+ .globl sys32_sethostname, sys32_gethostname, sys32_setdomainname
+ .globl sys32_time, sys32_swapoff, sys32_swapon, sys32_nfsservctl
+ .globl sys32_create_module, sys32_init_module, sys32_delete_module
+sys32_bdflush:
+ sra %o1, 0, %o1
+ mov %o7, %g1
+ call sys_bdflush
+ mov %g1, %o7
+sys32_uselib:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_uselib
+ mov %g1, %o7
+sys32_umount:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_umount
+ mov %g1, %o7
+sys32_syslog:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ call sys_syslog
+ mov %g1, %o7
+sys32_personality:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_personality
+ mov %g1, %o7
+sys32_waitpid:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ call sys_waitpid
+ mov %g1, %o7
+sys32_getitimer:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ call sys_getitimer
+ mov %g1, %o7
+sys32_setitimer:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ srl %o2, 0, %o2
+ call sys_setitimer
+ mov %g1, %o7
+sys32_sched_setscheduler:
+ srl %o2, 0, %o2
+ mov %o7, %g1
+ call sys_sched_setscheduler
+ mov %g1, %o7
+sys32_sched_setparam:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ call sys_sched_setparam
+ mov %g1, %o7
+sys32_sched_getparam:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ call sys_sched_getparam
+ mov %g1, %o7
+sys32_signal:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ call sys_signal
+ mov %g1, %o7
+sys32_reboot:
+ srl %o3, 0, %o3
+ mov %o7, %g1
+ call sys_reboot
+ mov %g1, %o7
+sys32_acct:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_acct
+ mov %g1, %o7
+sys32_newuname:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_newuname
+ mov %g1, %o7
+sys32_olduname:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_olduname
+ mov %g1, %o7
+sys32_sethostname:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_sethostname
+ mov %g1, %o7
+sys32_gethostname:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_gethostname
+ mov %g1, %o7
+sys32_setdomainname:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_setdomainname
+ mov %g1, %o7
+sys32_time:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_time
+ mov %g1, %o7
+sys32_swapoff:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_swapoff
+ mov %g1, %o7
+sys32_swapon:
+ srl %o0, 0, %o0
+ mov %o7, %g1
+ call sys_swapon
+ mov %g1, %o7
+sys32_nfsservctl:
+ srl %o1, 0, %o1
+ mov %o7, %g1
+ srl %o2, 0, %o2
+ call sys_nfsservctl
+ mov %g1, %o7
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/sys_sparc.c linux/arch/sparc64/kernel/sys_sparc.c
--- v2.1.43/linux/arch/sparc64/kernel/sys_sparc.c Mon Apr 14 16:28:09 1997
+++ linux/arch/sparc64/kernel/sys_sparc.c Mon Jul 7 08:18:54 1997
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.1 1997/04/09 08:25:18 jj Exp $
+/* $Id: sys_sparc.c,v 1.2 1997/07/05 09:52:34 davem Exp $
X * linux/arch/sparc64/kernel/sys_sparc.c
X *
X * This file contains various random system calls that
@@ -9,7 +9,6 @@
X #include <linux/errno.h>
X #include <linux/types.h>
X #include <linux/sched.h>
-#include <linux/config.h>
X #include <linux/fs.h>
X #include <linux/mm.h>
X #include <linux/sem.h>
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
--- v2.1.43/linux/arch/sparc64/kernel/sys_sparc32.c Mon Jun 16 16:35:54 1997
+++ linux/arch/sparc64/kernel/sys_sparc32.c Mon Jul 7 08:18:54 1997
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.26 1997/06/04 13:05:21 jj Exp $
+/* $Id: sys_sparc32.c,v 1.42 1997/07/05 09:52:36 davem Exp $
X * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
X *
X * Copyright (C) 1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
@@ -8,6 +8,7 @@
X * environment.
X */
X
+#include <linux/config.h>
X #include <linux/kernel.h>
X #include <linux/fs.h>
X #include <linux/signal.h>
@@ -30,11 +31,13 @@
X #include <linux/ncp_fs.h>
X #include <linux/quota.h>
X #include <linux/file.h>
+#include <linux/module.h>
X
X #include <asm/types.h>
X #include <asm/poll.h>
X #include <asm/ipc.h>
X #include <asm/uaccess.h>
+#include <asm/fpumacro.h>
X
X /* As gcc will warn about casting u32 to some ptr, we have to cast it to
X * unsigned long first, and that's what is A() for.
@@ -372,11 +375,12 @@
X switch (version) {
X case 0: default: {
X unsigned long raddr;
+ u32 *uptr = (u32 *) A(((u32)third));
X err = sys_shmat (first, (char *)A(ptr), second, &raddr);
X if (err)
X goto out;
X err = -EFAULT;
- if(put_user (raddr, ((u32 *)A(third))))
+ if(put_user (raddr, uptr))
X goto out;
X err = 0;
X goto out;
@@ -469,32 +473,6 @@
X return err;
X }
X
-extern asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long off);
-
-asmlinkage unsigned long sys32_mmap(u32 addr, u32 len, u32 prot,
- u32 flags, u32 fd, u32 off)
-{
- return sys_mmap((unsigned long)addr, (unsigned long)len,
- (unsigned long)prot, (unsigned long)flags,
- (unsigned long)fd, (unsigned long)off);
-}
-
-extern asmlinkage int sys_bdflush(int func, long data);
-
-asmlinkage int sys32_bdflush(int func, s32 data)
-{
- return sys_bdflush(func, (long)data);
-}
-
-extern asmlinkage int sys_uselib(const char * library);
-
-asmlinkage int sys32_uselib(u32 library)
-{
- return sys_uselib((const char *)A(library));
-}
-
X static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
X {
X if(get_user(kfl->l_type, &ufl->l_type) ||
@@ -544,55 +522,6 @@
X }
X }
X
-extern asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev);
-
-asmlinkage int sys32_mknod(u32 filename, int mode, __kernel_dev_t32 dev)
-{
- return sys_mknod((const char *)A(filename), mode, dev);
-}
-
-extern asmlinkage int sys_mkdir(const char * pathname, int mode);
-
-asmlinkage int sys32_mkdir(u32 pathname, int mode)
-{
- return sys_mkdir((const char *)A(pathname), mode);
-}
-
-extern asmlinkage int sys_rmdir(const char * pathname);
-
-asmlinkage int sys32_rmdir(u32 pathname)
-{
- return sys_rmdir((const char *)A(pathname));
-}
-
-extern asmlinkage int sys_unlink(const char * pathname);
-
-asmlinkage int sys32_unlink(u32 pathname)
-{
- return sys_unlink((const char *)A(pathname));
-}
-
-extern asmlinkage int sys_symlink(const char * oldname, const char * newname);
-
-asmlinkage int sys32_symlink(u32 oldname, u32 newname)
-{
- return sys_symlink((const char *)A(oldname), (const char *)A(newname));
-}
-
-extern asmlinkage int sys_link(const char * oldname, const char * newname);
-
-asmlinkage int sys32_link(u32 oldname, u32 newname)
-{
- return sys_link((const char *)A(oldname), (const char *)A(newname));
-}
-
-extern asmlinkage int sys_rename(const char * oldname, const char * newname);
-
-asmlinkage int sys32_rename(u32 oldname, u32 newname)
-{
- return sys_rename((const char *)A(oldname), (const char *)A(newname));
-}
-
X struct dqblk32 {
X __u32 dqb_bhardlimit;
X __u32 dqb_bsoftlimit;
@@ -701,20 +630,6 @@
X return ret;
X }
X
-extern asmlinkage int sys_truncate(const char * path, unsigned long length);
-
-asmlinkage int sys32_truncate(u32 path, u32 length)
-{
- return sys_truncate((const char *)A(path), (unsigned long)length);
-}
-
-extern asmlinkage int sys_ftruncate(unsigned int fd, unsigned long length);
-
-asmlinkage int sys32_ftruncate(unsigned int fd, u32 length)
-{
- return sys_ftruncate(fd, (unsigned long)length);
-}
-
X extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
X
X asmlinkage int sys32_utime(u32 filename, u32 times)
@@ -741,96 +656,6 @@
X return ret;
X }
X
-extern asmlinkage int sys_utimes(char * filename, struct timeval * utimes);
-
-asmlinkage int sys32_utimes(u32 filename, u32 utimes)
-{
- /* struct timeval is the same :)) */
- return sys_utimes((char *)A(filename), (struct timeval *)A(utimes));
-}
-
-extern asmlinkage int sys_access(const char * filename, int mode);
-
-asmlinkage int sys32_access(u32 filename, int mode)
-{
- return sys_access((const char *)A(filename), mode);
-}
-
-extern asmlinkage int sys_chdir(const char * filename);
-
-asmlinkage int sys32_chdir(u32 filename)
-{
- return sys_chdir((const char *)A(filename));
-}
-
-extern asmlinkage int sys_chroot(const char * filename);
-
-asmlinkage int sys32_chroot(u32 filename)
-{
- return sys_chroot((const char *)A(filename));
-}
-
-extern asmlinkage int sys_chmod(const char * filename, mode_t mode);
-
-asmlinkage int sys32_chmod(u32 filename, __kernel_mode_t32 mode)
-{
- return sys_chmod((const char *)A(filename), mode);
-}
-
-extern asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group);
-
-asmlinkage int sys32_chown(u32 filename, __kernel_uid_t32 user, __kernel_gid_t32 group)
-{
- return sys_chown((const char *)A(filename), user, group);
-}
-
-extern asmlinkage int sys_open(const char * filename,int flags,int mode);
-
-asmlinkage int sys32_open(u32 filename, int flags, int mode)
-{
- return sys_open((const char *)A(filename), flags, mode);
-}
-
-extern asmlinkage int sys_creat(const char * pathname, int mode);
-
-asmlinkage int sys32_creat(u32 pathname, int mode)
-{
- return sys_creat((const char *)A(pathname), mode);
-}
-
-extern asmlinkage long sys_lseek(unsigned int fd, off_t offset, unsigned int origin);
-
-asmlinkage long sys32_lseek(unsigned int fd, s32 offset, unsigned int origin)
-{
- return sys_lseek(fd, (off_t)offset, origin);
-}
-
-extern asmlinkage int sys_llseek(unsigned int fd, unsigned long offset_high,
- unsigned long offset_low,
- loff_t *result, unsigned int origin);
-
-asmlinkage int sys32_llseek(unsigned int fd, u32 offset_high,
- u32 offset_low, u32 result, unsigned int origin)
-{
- /* loff_t is the same :)) */
- return sys_llseek(fd, (unsigned long)offset_high, (unsigned long)offset_low,
- (loff_t *)A(result), origin);
-}
-
-extern asmlinkage long sys_read(unsigned int fd, char * buf, unsigned long count);
-
-asmlinkage long sys32_read(unsigned int fd, u32 buf, u32 count)
-{
- return sys_read(fd, (char *)A(buf), (unsigned long)count);
-}
-
-extern asmlinkage long sys_write(unsigned int fd, const char * buf, unsigned long count);
-
-asmlinkage long sys32_write(unsigned int fd, u32 buf, u32 count)
-{
- return sys_write(fd, (const char *)A(buf), (unsigned long)count);
-}
-
X struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
X
X typedef long (*IO_fn_t)(struct inode *, struct file *, char *, unsigned long);
@@ -1196,13 +1021,6 @@
X return ret;
X }
X
-extern asmlinkage int sys_poll(struct pollfd * ufds, unsigned int nfds, int timeout);
-
-asmlinkage int sys32_poll(u32 ufds, unsigned int nfds, int timeout)
-{
- return sys_poll((struct pollfd *)A(ufds), nfds, timeout);
-}
-
X static inline int putstat(struct stat32 *ubuf, struct stat *kbuf)
X {
X if (put_user (kbuf->st_dev, &ubuf->st_dev) ||
@@ -1280,13 +1098,6 @@
X return ret;
X }
X
-extern asmlinkage int sys_readlink(const char * path, char * buf, int bufsiz);
-
-asmlinkage int sys32_readlink(u32 path, u32 buf, int bufsiz)
-{
- return sys_readlink((const char *)A(path), (char *)A(buf), bufsiz);
-}
-
X extern asmlinkage int sys_sysfs(int option, ...);
X
X asmlinkage int sys32_sysfs(int option, ...)
@@ -1312,42 +1123,162 @@
X return ret;
X }
X
-extern asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf);
+struct ncp_mount_data32 {
+ int version;
+ unsigned int ncp_fd;
+ __kernel_uid_t32 mounted_uid;
+ __kernel_pid_t32 wdog_pid;
+ unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
+ unsigned int time_out;
+ unsigned int retry_count;
+ unsigned int flags;
+ __kernel_uid_t32 uid;
+ __kernel_gid_t32 gid;
+ __kernel_mode_t32 file_mode;
+ __kernel_mode_t32 dir_mode;
+};
X
-asmlinkage int sys32_ustat(dev_t dev, u32 ubuf)
+static void *do_ncp_super_data_conv(void *raw_data)
X {
- /* ustat is the same :)) */
- return sys_ustat(dev, (struct ustat *)A(ubuf));
+ struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
+ struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
+
+ n->dir_mode = n32->dir_mode;
+ n->file_mode = n32->file_mode;
+ n->gid = n32->gid;
+ n->uid = n32->uid;
+ memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
+ n->wdog_pid = n32->wdog_pid;
+ n->mounted_uid = n32->mounted_uid;
+ return raw_data;
X }
X
-extern asmlinkage int sys_umount(char * name);
+struct smb_mount_data32 {
+ int version;
+ unsigned int fd;
+ __kernel_uid_t32 mounted_uid;
+ struct sockaddr_in addr;
+ char server_name[17];
+ char client_name[17];
+ char service[64];
+ char root_path[64];
+ char username[64];
+ char password[64];
+ char domain[64];
+ unsigned short max_xmit;
+ __kernel_uid_t32 uid;
+ __kernel_gid_t32 gid;
+ __kernel_mode_t32 file_mode;
+ __kernel_mode_t32 dir_mode;
+};
X
-asmlinkage int sys32_umount(u32 name)
+static void *do_smb_super_data_conv(void *raw_data)
X {
- return sys_umount((char *)A(name));
-}
+ struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
+ struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
X
-extern asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
- unsigned long new_flags, void *data);
+ s->dir_mode = s32->dir_mode;
+ s->file_mode = s32->file_mode;
+ s->gid = s32->gid;
+ s->uid = s32->uid;
+ memmove (&s->addr, &s32->addr, (((long)&s->uid) - ((long)&s->addr)));
+ s->mounted_uid = s32->mounted_uid;
+ return raw_data;
+}
X
-asmlinkage int sys32_mount(u32 dev_name, u32 dir_name, u32 type, u32 new_flags, u32 data)
+static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
X {
- return sys_mount((char *)A(dev_name), (char *)A(dir_name), (char *)A(type),
- (unsigned long)new_flags, (void *)A(data));
+ int i;
+ unsigned long page;
+ struct vm_area_struct *vma;
+
+ *kernel = 0;
+ if(!user)
+ return 0;
+ vma = find_vma(current->mm, (unsigned long)user);
+ if(!vma || (unsigned long)user < vma->vm_start)
+ return -EFAULT;
+ if(!(vma->vm_flags & VM_READ))
+ return -EFAULT;
+ i = vma->vm_end - (unsigned long) user;
+ if(PAGE_SIZE <= (unsigned long) i)
+ i = PAGE_SIZE - 1;
+ if(!(page = __get_free_page(GFP_KERNEL)))
+ return -ENOMEM;
+ if(copy_from_user((void *) page, user, i)) {
+ free_page(page);
+ return -EFAULT;
+ }
+ *kernel = page;
+ return 0;
X }
X
-extern asmlinkage int sys_syslog(int type, char * bug, int count);


+extern asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
+ unsigned long new_flags, void *data);

X
-asmlinkage int sys32_syslog(int type, u32 bug, int count)
+#define SMBFS_NAME "smbfs"
+#define NCPFS_NAME "ncpfs"
+
+asmlinkage int sys32_mount(u32 dev_name, u32 dir_name, u32 type, u32 new_flags, u32 data)
X {
- return sys_syslog(type, (char *)A(bug), count);
-}
+ unsigned long type_page;
+ int err, is_smb, is_ncp;
X
-extern asmlinkage int sys_personality(unsigned long personality);
+ if(!suser())
+ return -EPERM;
+ is_smb = is_ncp = 0;
+ err = copy_mount_stuff_to_kernel((const void *)A(type), &type_page);
+ if(err)
+ return err;
+ if(type_page) {
+ is_smb = !strcmp((char *)type_page, SMBFS_NAME);
+ is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
+ }
+ if(!is_smb && !is_ncp) {
+ if(type_page)
+ free_page(type_page);
+ return sys_mount((char *)A(dev_name), (char *)A(dir_name),
+ (char *)A(type), (unsigned long)new_flags,
+ (void *)A(data));
+ } else {
+ unsigned long dev_page, dir_page, data_page;
+ int old_fs;
X
-asmlinkage int sys32_personality(u32 personality)
-{
- return sys_personality((unsigned long)personality);
+ err = copy_mount_stuff_to_kernel((const void *)A(dev_name), &dev_page);
+ if(err)
+ goto out;
+ err = copy_mount_stuff_to_kernel((const void *)A(dir_name), &dir_page);
+ if(err)
+ goto dev_out;
+ err = copy_mount_stuff_to_kernel((const void *)A(data), &data_page);
+ if(err)
+ goto dir_out;
+ if(is_ncp)
+ do_ncp_super_data_conv((void *)data_page);
+ else if(is_smb)
+ do_smb_super_data_conv((void *)data_page);
+ else
+ panic("Tell DaveM he fucked up...");
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_mount((char *)dev_page, (char *)dir_page,
+ (char *)type_page, (unsigned long)new_flags,
+ (void *)data_page);
+ set_fs(old_fs);
+
+ if(data_page)
+ free_page(data_page);
+ dir_out:
+ if(dir_page)
+ free_page(dir_page);
+ dev_out:
+ if(dev_page)
+ free_page(dev_page);
+ out:
+ if(type_page)
+ free_page(type_page);
+ return err;
+ }
X }
X
X struct rusage32 {
@@ -1416,13 +1347,6 @@
X }
X }
X
-extern asmlinkage int sys_waitpid(pid_t pid,unsigned int * stat_addr, int options);
-
-asmlinkage int sys32_waitpid(__kernel_pid_t32 pid, u32 stat_addr, int options)
-{
- return sys_waitpid(pid, (unsigned int *)A(stat_addr), options);
-}
-
X struct sysinfo32 {
X s32 uptime;
X u32 loads[3];
@@ -1462,46 +1386,6 @@
X return ret;
X }
X
-extern asmlinkage int sys_getitimer(int which, struct itimerval *value);
-
-asmlinkage int sys32_getitimer(int which, u32 value)
-{
- /* itimerval is the same :)) */
- return sys_getitimer(which, (struct itimerval *)A(value));
-}
-
-extern asmlinkage int sys_setitimer(int which, struct itimerval *value,
- struct itimerval *ovalue);
-
-asmlinkage int sys32_setitimer(int which, u32 value, u32 ovalue)
-{
- return sys_setitimer(which, (struct itimerval *)A(value),
- (struct itimerval *)A(ovalue));
-}
-
-extern asmlinkage int sys_sched_setscheduler(pid_t pid, int policy,
- struct sched_param *param);
-
-asmlinkage int sys32_sched_setscheduler(__kernel_pid_t32 pid, int policy, u32 param)
-{
- /* sched_param is the same :)) */
- return sys_sched_setscheduler(pid, policy, (struct sched_param *)A(param));
-}
-
-extern asmlinkage int sys_sched_setparam(pid_t pid, struct sched_param *param);
-
-asmlinkage int sys32_sched_setparam(__kernel_pid_t32 pid, u32 param)
-{
- return sys_sched_setparam(pid, (struct sched_param *)A(param));
-}
-
-extern asmlinkage int sys_sched_getparam(pid_t pid, struct sched_param *param);
-
-asmlinkage int sys32_sched_getparam(__kernel_pid_t32 pid, u32 param)
-{
- return sys_sched_getparam(pid, (struct sched_param *)A(param));
-}
-
X struct timespec32 {
X s32 tv_sec;
X s32 tv_nsec;
@@ -1577,25 +1461,29 @@
X return ret;
X }
X
-extern asmlinkage unsigned long sys_signal(int signum, __sighandler_t handler);
+extern asmlinkage int sys_setreuid(uid_t ruid, uid_t euid);
X
-asmlinkage unsigned long sys32_signal(int signum, u32 handler)
+asmlinkage int sys32_setreuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid)
X {
- return sys_signal(signum, (__sighandler_t)A(handler));
-}
+ uid_t sruid, seuid;
X
-extern asmlinkage int sys_reboot(int magic1, int magic2, int cmd, void * arg);
-
-asmlinkage int sys32_reboot(int magic1, int magic2, int cmd, u32 arg)
-{
- return sys_reboot(magic1, magic2, cmd, (void *)A(arg));
+ sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
+ seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
+ return sys_setreuid(sruid, seuid);
X }
X
-extern asmlinkage int sys_acct(const char *name);
+extern asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
X
-asmlinkage int sys32_acct(u32 name)
+asmlinkage int sys32_setresuid(__kernel_uid_t32 ruid,
+ __kernel_uid_t32 euid,
+ __kernel_uid_t32 suid)
X {
- return sys_acct((const char *)A(name));
+ uid_t sruid, seuid, ssuid;
+
+ sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
+ seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
+ ssuid = (suid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)suid);
+ return sys_setresuid(sruid, seuid, ssuid);
X }
X
X extern asmlinkage int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
@@ -1654,7 +1542,7 @@
X set_fs (KERNEL_DS);
X ret = sys_getgroups(gidsetsize, gl);
X set_fs (old_fs);
- if (ret > 0 && ret <= NGROUPS)
+ if (gidsetsize && ret > 0 && ret <= NGROUPS)
X for (i = 0; i < ret; i++, grouplist += sizeof(__kernel_gid_t32))
X if (__put_user (gl[i], (__kernel_gid_t32 *)A(grouplist)))
X return -EFAULT;
@@ -1680,41 +1568,8 @@
X return ret;
X }
X
-extern asmlinkage int sys_newuname(struct new_utsname * name);
-
-asmlinkage int sys32_newuname(u32 name)
-{
- /* utsname is the same :)) */
- return sys_newuname((struct new_utsname *)A(name));
-}
-
-extern asmlinkage int sys_olduname(struct oldold_utsname * name);
-
-asmlinkage int sys32_olduname(u32 name)
-{
- return sys_olduname((struct oldold_utsname *)A(name));
-}
-
-extern asmlinkage int sys_sethostname(char *name, int len);
-
-asmlinkage int sys32_sethostname(u32 name, int len)
-{
- return sys_sethostname((char *)A(name), len);
-}
-
-extern asmlinkage int sys_gethostname(char *name, int len);
-
-asmlinkage int sys32_gethostname(u32 name, int len)
-{
- return sys_gethostname((char *)A(name), len);
-}
-
-extern asmlinkage int sys_setdomainname(char *name, int len);
-
-asmlinkage int sys32_setdomainname(u32 name, int len)
-{
- return sys_setdomainname((char *)A(name), len);
-}
+#define RLIM_INFINITY32 0x7fffffff
+#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
X
X struct rlimit32 {
X s32 rlim_cur;
@@ -1733,8 +1588,8 @@
X ret = sys_getrlimit(resource, &r);
X set_fs (old_fs);
X if (!ret && (
- put_user (r.rlim_cur, &(((struct rlimit32 *)A(rlim))->rlim_cur)) ||
- __put_user (r.rlim_max, &(((struct rlimit32 *)A(rlim))->rlim_max))))
+ put_user (RESOURCE32(r.rlim_cur), &(((struct rlimit32 *)A(rlim))->rlim_cur)) ||
+ __put_user (RESOURCE32(r.rlim_max), &(((struct rlimit32 *)A(rlim))->rlim_max))))
X return -EFAULT;
X return ret;
X }
@@ -1751,6 +1606,10 @@
X if (get_user (r.rlim_cur, &(((struct rlimit32 *)A(rlim))->rlim_cur)) ||
X __get_user (r.rlim_max, &(((struct rlimit32 *)A(rlim))->rlim_max)))
X return -EFAULT;
+ if (r.rlim_cur == RLIM_INFINITY32)
+ r.rlim_cur = RLIM_INFINITY;
+ if (r.rlim_max == RLIM_INFINITY32)
+ r.rlim_max = RLIM_INFINITY;
X set_fs (KERNEL_DS);
X ret = sys_setrlimit(resource, &r);
X set_fs (old_fs);
@@ -1772,28 +1631,6 @@
X return ret;
X }
X
-extern asmlinkage int sys_time(int * tloc);
-
-asmlinkage int sys32_time(u32 tloc)
-{
- return sys_time((int *)A(tloc));
-}
-
-extern asmlinkage int sys_gettimeofday(struct timeval *tv, struct timezone *tz);
-
-asmlinkage int sys32_gettimeofday(u32 tv, u32 tz)
-{
- /* both timeval and timezone are ok :)) */
- return sys_gettimeofday((struct timeval *)A(tv), (struct timezone *)A(tz));
-}
-
-extern asmlinkage int sys_settimeofday(struct timeval *tv, struct timezone *tz);
-
-asmlinkage int sys32_settimeofday(u32 tv, u32 tz)
-{
- return sys_settimeofday((struct timeval *)A(tv), (struct timezone *)A(tz));
-}
-
X struct timex32 {
X unsigned int modes;
X s32 offset;
@@ -1865,170 +1702,6 @@
X return ret;
X }
X
-extern asmlinkage int sys_msync(unsigned long start, size_t len, int flags);
-
-asmlinkage int sys32_msync(u32 start, __kernel_size_t32 len, int flags)
-{
- return sys_msync((unsigned long)start, (size_t)len, flags);
-}
-
-extern asmlinkage int sys_mlock(unsigned long start, size_t len);
-
-asmlinkage int sys32_mlock(u32 start, __kernel_size_t32 len)
-{
- return sys_mlock((unsigned long)start, (size_t)len);
-}
-
-extern asmlinkage int sys_munlock(unsigned long start, size_t len);
-
-asmlinkage int sys32_munlock(u32 start, __kernel_size_t32 len)
-{
- return sys_munlock((unsigned long)start, (size_t)len);
-}
-
-extern asmlinkage unsigned long sys_brk(unsigned long brk);
-
-asmlinkage unsigned long sparc32_brk(u32 brk)
-{
- return sys_brk((unsigned long)brk);
-}
-
-extern asmlinkage int sys_munmap(unsigned long addr, size_t len);
-
-asmlinkage int sys32_munmap(u32 addr, __kernel_size_t32 len)
-{
- return sys_munmap((unsigned long)addr, (size_t)len);
-}
-
-extern asmlinkage int sys_mprotect(unsigned long start, size_t len, unsigned long prot);
-
-asmlinkage int sys32_mprotect(u32 start, __kernel_size_t32 len, u32 prot)
-{
- return sys_mprotect((unsigned long)start, (size_t)len, (unsigned long)prot);
-}
-
-extern asmlinkage unsigned long sys_mremap(unsigned long addr, unsigned long old_len,
- unsigned long new_len, unsigned long flags);
-
-asmlinkage unsigned long sys32_mremap(u32 addr, u32 old_len, u32 new_len, u32 flags)
-{
- return sys_mremap((unsigned long)addr, (unsigned long)old_len,
- (unsigned long)new_len, (unsigned long)flags);
-}
-
-extern asmlinkage int sys_swapoff(const char * specialfile);
-
-asmlinkage int sys32_swapoff(u32 specialfile)
-{
- return sys_swapoff((const char *)A(specialfile));
-}
-
-extern asmlinkage int sys_swapon(const char * specialfile, int swap_flags);
-
-asmlinkage int sys32_swapon(u32 specialfile, int swap_flags)
-{
- return sys_swapon((const char *)A(specialfile), swap_flags);
-}
-
-extern asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
-
-asmlinkage inline int sys32_bind(int fd, u32 umyaddr, int addrlen)
-{
- /* sockaddr is the same :)) */
- return sys_bind(fd, (struct sockaddr *)A(umyaddr), addrlen);
-}
-
-extern asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr,
- int *upeer_addrlen);
-
-asmlinkage inline int sys32_accept(int fd, u32 upeer_sockaddr, u32 upeer_addrlen)
-{
- return sys_accept(fd, (struct sockaddr *)A(upeer_sockaddr),
- (int *)A(upeer_addrlen));
-}
-
-extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
-
-asmlinkage inline int sys32_connect(int fd, u32 uservaddr, int addrlen)
-{
- return sys_connect(fd, (struct sockaddr *)A(uservaddr), addrlen);
-}
-
-extern asmlinkage int sys_getsockname(int fd, struct sockaddr *usockaddr,
- int *usockaddr_len);
-
-asmlinkage int sys32_getsockname(int fd, u32 usockaddr, u32 usockaddr_len)
-{
- return sys_getsockname(fd, (struct sockaddr *)A(usockaddr),
- (int *)A(usockaddr_len));
-}
-
-extern asmlinkage int sys_getpeername(int fd, struct sockaddr *usockaddr,
- int *usockaddr_len);
-
-asmlinkage int sys32_getpeername(int fd, u32 usockaddr, u32 usockaddr_len)
-{
- return sys_getpeername(fd, (struct sockaddr *)A(usockaddr),
- (int *)A(usockaddr_len));
-}
-
-extern asmlinkage int sys_send(int fd, void * buff, size_t len, unsigned flags);
-
-asmlinkage inline int sys32_send(int fd, u32 buff,
- __kernel_size_t32 len, unsigned flags)
-{
- return sys_send(fd, (void *)A(buff), (size_t)len, flags);
-}
-
-extern asmlinkage int sys_sendto(int fd, void * buff, size_t len, unsigned flags,
- struct sockaddr *addr, int addr_len);
-
-asmlinkage inline int sys32_sendto(int fd, u32 buff, __kernel_size_t32 len,
- unsigned flags, u32 addr, int addr_len)
-{
- return sys_sendto(fd, (void *)A(buff), (size_t)len, flags,
- (struct sockaddr *)A(addr), addr_len);
-}
-
-extern asmlinkage int sys_recv(int fd, void * ubuf, size_t size, unsigned flags);
-
-asmlinkage inline int sys32_recv(int fd, u32 ubuf,
- __kernel_size_t32 size, unsigned flags)
-{
- return sys_recv(fd, (void *)A(ubuf), (size_t)size, flags);
-}
-
-extern asmlinkage int sys_recvfrom(int fd, void * ubuf, size_t size, unsigned flags,
- struct sockaddr *addr, int *addr_len);
-
-asmlinkage inline int sys32_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
- unsigned flags, u32 addr, u32 addr_len)
-{
- return sys_recvfrom(fd, (void *)A(ubuf), (size_t)size, flags,
- (struct sockaddr *)A(addr), (int *)A(addr_len));
-}
-
-extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
- char *optval, int optlen);
-
-asmlinkage inline int sys32_setsockopt(int fd, int level, int optname,
- u32 optval, int optlen)
-{
- /* XXX handle ip_fw32->ip_fw conversion for IP firewalling and accounting.
- Do it using some macro in ip_sockglue.c
- Other optval arguments are mostly just ints or 32<->64bit transparent */
- return sys_setsockopt(fd, level, optname, (char *)A(optval), optlen);
-}
-
-extern asmlinkage int sys_getsockopt(int fd, int level, int optname,
- char *optval, int *optlen);
-
-asmlinkage inline int sys32_getsockopt(int fd, int level, int optname,
- u32 optval, u32 optlen)
-{
- return sys_getsockopt(fd, level, optname, (char *)A(optval), (int *)A(optlen));
-}
-
X /* XXX This really belongs in some header file... -DaveM */
X #define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
X 16 for IP, 16 for IPX,
@@ -2293,6 +1966,24 @@
X AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
X #undef AL
X
+extern asmlinkage int sys32_bind(int fd, u32 umyaddr, int addrlen);
+extern asmlinkage int sys32_connect(int fd, u32 uservaddr, int addrlen);
+extern asmlinkage int sys32_accept(int fd, u32 upeer_sockaddr, u32 upeer_addrlen);
+extern asmlinkage int sys32_getsockname(int fd, u32 usockaddr, u32 usockaddr_len);
+extern asmlinkage int sys32_getpeername(int fd, u32 usockaddr, u32 usockaddr_len);
+extern asmlinkage int sys32_send(int fd, u32 buff, __kernel_size_t32 len,
+ unsigned flags);
+extern asmlinkage int sys32_sendto(int fd, u32 buff, __kernel_size_t32 len,
+ unsigned flags, u32 addr, int addr_len);
+extern asmlinkage int sys32_recv(int fd, u32 ubuf, __kernel_size_t32 size,
+ unsigned flags);
+extern asmlinkage int sys32_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
+ unsigned flags, u32 addr, u32 addr_len);
+extern asmlinkage int sys32_setsockopt(int fd, int level, int optname,
+ u32 optval, int optlen);
+extern asmlinkage int sys32_getsockopt(int fd, int level, int optname,
+ u32 optval, u32 optlen);
+
X extern asmlinkage int sys_socket(int family, int type, int protocol);
X extern asmlinkage int sys_socketpair(int family, int type, int protocol,
X int usockvec[2]);
@@ -2389,7 +2080,7 @@
X old_sa.sa_mask = (sigset_t32)(p->sa_mask);
X old_sa.sa_flags = (unsigned)(p->sa_flags);
X old_sa.sa_restorer = (unsigned)(u64)(p->sa_restorer);
- if (copy_to_user(A(oldaction), p, sizeof(struct sigaction32)))
+ if (copy_to_user(A(oldaction), &old_sa, sizeof(struct sigaction32)))
X goto out;
X }
X
@@ -2407,14 +2098,6 @@
X return err;
X }
X
-extern asmlinkage int sys_nfsservctl(int cmd, void *argp, void *resp);
-
-asmlinkage int sys32_nfsservctl(int cmd, u32 argp, u32 resp)
-{
- /* XXX handle argp and resp args */
- return sys_nfsservctl(cmd, (void *)A(argp), (void *)A(resp));
-}
-
X /*
X * count32() counts the number of arguments/envelopes
X */
@@ -2550,74 +2233,219 @@
X (u32 *)A((u32)regs->u_regs[base + UREG_I1]),
X (u32 *)A((u32)regs->u_regs[base + UREG_I2]), regs);
X putname(filename);
+ if(!error) {
+ fprs_write(0);
+ regs->fprs = 0;
+ }
X return error;
X }
X
-/* Modules will be supported with 64bit modutils only */
-asmlinkage int sys32_no_modules(void)
+#ifdef CONFIG_MODULES
+
+extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
+
+asmlinkage unsigned long sys32_create_module(u32 name_user, __kernel_size_t32 size)
X {
- return -ENOSYS;
+ return sys_create_module((const char *)A(name_user), (size_t)size);
X }
X
-struct ncp_mount_data32 {
- int version;
- unsigned int ncp_fd;
- __kernel_uid_t32 mounted_uid;
- __kernel_pid_t32 wdog_pid;
- unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
- unsigned int time_out;
- unsigned int retry_count;
- unsigned int flags;
- __kernel_uid_t32 uid;
- __kernel_gid_t32 gid;
- __kernel_mode_t32 file_mode;
- __kernel_mode_t32 dir_mode;
-};
+extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
X
-void *do_ncp_super_data_conv(void *raw_data)
+/* Hey, when you're trying to init module, take time and prepare us a nice 64bit
+ * module structure, even if from 32bit modutils... Why to pollute kernel... :))
+ */
+asmlinkage int sys32_init_module(u32 nameuser, u32 mod_user)
X {
- struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
- struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
+ return sys_init_module((const char *)A(nameuser), (struct module *)A(mod_user));
+}
X
- n->dir_mode = n32->dir_mode;
- n->file_mode = n32->file_mode;
- n->gid = n32->gid;
- n->uid = n32->uid;
- memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
- n->wdog_pid = n32->wdog_pid;
- n->mounted_uid = n32->mounted_uid;
- return raw_data;
+extern asmlinkage int sys_delete_module(const char *name_user);
+
+asmlinkage int sys32_delete_module(u32 name_user)
+{
+ return sys_delete_module((const char *)A(name_user));
X }
X
-struct smb_mount_data32 {
- int version;
- unsigned int fd;
- __kernel_uid_t32 mounted_uid;
- struct sockaddr_in addr;
- char server_name[17];
- char client_name[17];
- char service[64];
- char root_path[64];
- char username[64];
- char password[64];
- char domain[64];
- unsigned short max_xmit;
- __kernel_uid_t32 uid;
- __kernel_gid_t32 gid;
- __kernel_mode_t32 file_mode;
- __kernel_mode_t32 dir_mode;
+struct module_info32 {
+ u32 addr;
+ u32 size;
+ u32 flags;
+ s32 usecount;
X };
X
-void *do_smb_super_data_conv(void *raw_data)
+extern asmlinkage int sys_query_module(const char *name_user, int which, char *buf, size_t bufsize, size_t *ret);
+
+asmlinkage int sys32_query_module(u32 name_user, int which, u32 buf, __kernel_size_t32 bufsize, u32 retv)
X {
- struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
- struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
+ char *buff;
+ unsigned long old_fs = get_fs();
+ size_t val;
+ int ret, i, j;
+ unsigned long *p;
+ char *usernam = NULL;
+ int bufsiz = bufsize;
+ struct module_info mi;
+
+ switch (which) {
+ case 0: return sys_query_module ((const char *)A(name_user), which, (char *)A(buf), (size_t)bufsize, (size_t *)A(retv));
+ case QM_SYMBOLS:
+ bufsiz <<= 1;
+ case QM_MODULES:
+ case QM_REFS:
+ case QM_DEPS:
+ if (name_user && (ret = getname32 (name_user, &usernam)))
+ return ret;
+ buff = kmalloc (bufsiz, GFP_KERNEL);
+ if (!buff) {
+ if (name_user) putname32 (usernam);
+ return -ENOMEM;
+ }
+qmsym_toshort:
+ set_fs (KERNEL_DS);
+ ret = sys_query_module (usernam, which, buff, bufsiz, &val);
+ set_fs (old_fs);
+ if (which != QM_SYMBOLS) {
+ if (ret == -ENOSPC || !ret) {
+ if (put_user (val, (__kernel_size_t32 *)A(retv)))
+ ret = -EFAULT;
+ }
+ if (!ret) {
+ if (copy_to_user ((char *)A(buf), buff, bufsize))
+ ret = -EFAULT;
+ }
+ } else {
+ if (ret == -ENOSPC) {
+ if (put_user (2 * val, (__kernel_size_t32 *)A(retv)))
+ ret = -EFAULT;
+ }
+ p = (unsigned long *)buff;
+ if (!ret) {
+ if (put_user (val, (__kernel_size_t32 *)A(retv)))
+ ret = -EFAULT;
+ }
+ if (!ret) {
+ j = val * 8;
+ for (i = 0; i < val; i++, p += 2) {
+ if (bufsize < (2 * sizeof (u32))) {
+ bufsiz = 0;
+ goto qmsym_toshort;
+ }
+ if (put_user (p[0], (u32 *)A(buf)) ||
+ __put_user (p[1] - j, (((u32 *)A(buf))+1))) {
+ ret = -EFAULT;
+ break;
+ }
+ bufsize -= (2 * sizeof (u32));
+ buf += (2 * sizeof (u32));
+ }
+ }
+ if (!ret && val) {
+ char *strings = buff + ((unsigned long *)buff)[1];
+ j = *(p - 1) - ((unsigned long *)buff)[1];
+ j = j + strlen (buff + j) + 1;
+ if (bufsize < j) {
+ bufsiz = 0;
+ goto qmsym_toshort;
+ }
+ if (copy_to_user ((char *)A(buf), strings, j))
+ ret = -EFAULT;
+ }
+ }
+ kfree (buff);
+ if (name_user) putname32 (usernam);
+ return ret;
+ case QM_INFO:
+ if (name_user && (ret = getname32 (name_user, &usernam)))
+ return ret;
+ set_fs (KERNEL_DS);
+ ret = sys_query_module (usernam, which, (char *)&mi, sizeof (mi), &val);
+ set_fs (old_fs);
+ if (!ret) {
+ if (put_user (sizeof (struct module_info32), (__kernel_size_t32 *)A(retv)))
+ ret = -EFAULT;
+ else if (bufsize < sizeof (struct module_info32))
+ ret = -ENOSPC;
+ }
+ if (!ret) {
+ if (put_user (mi.addr, &(((struct module_info32 *)A(buf))->addr)) ||
+ __put_user (mi.size, &(((struct module_info32 *)A(buf))->size)) ||
+ __put_user (mi.flags, &(((struct module_info32 *)A(buf))->flags)) ||
+ __put_user (mi.usecount, &(((struct module_info32 *)A(buf))->usecount)))
+ ret = -EFAULT;
+ }
+ if (name_user) putname32 (usernam);
+ return ret;


+ default:
+ return -EINVAL;
+ }
+}

X
- s->dir_mode = s32->dir_mode;
- s->file_mode = s32->file_mode;
- s->gid = s32->gid;
- s->uid = s32->uid;
- memmove (&s->addr, &s32->addr, (((long)&s->uid) - ((long)&s->addr)));
- s->mounted_uid = s32->mounted_uid;
- return raw_data;
+struct kernel_sym32 {
+ u32 value;
+ char name[60];
+};
+
+extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
+
+asmlinkage int sys32_get_kernel_syms(u32 table)
+{
+ int len, i;
+ struct kernel_sym *tbl;
+ unsigned long old_fs;
+
+ len = sys_get_kernel_syms(NULL);
+ if (!table) return len;
+ tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
+ if (!tbl) return -ENOMEM;
+ old_fs = get_fs();
+ set_fs (KERNEL_DS);
+ sys_get_kernel_syms(tbl);
+ set_fs (old_fs);
+ for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
+ if (put_user (tbl[i].value, &(((struct kernel_sym32 *)A(table))->value)) ||
+ copy_to_user (((struct kernel_sym32 *)A(table))->name, tbl[i].name, 60))
+ break;
+ }
+ kfree (tbl);
+ return i;
+}
+
+#else /* CONFIG_MODULES */
+
+asmlinkage unsigned long
+sys_create_module(const char *name_user, size_t size)
+{
+ return -ENOSYS;
+}
+
+asmlinkage int
+sys_init_module(const char *name_user, struct module *mod_user)


+{
+ return -ENOSYS;
X }

+
+asmlinkage int
+sys_delete_module(const char *name_user)
+{
+ return -ENOSYS;
+}
+
+asmlinkage int
+sys_query_module(const char *name_user, int which, char *buf, size_t bufsize,
+ size_t *ret)
+{
+ /* Let the program know about the new interface. Not that
+ it'll do them much good. */
+ if (which == 0)
+ return 0;
+
+ return -ENOSYS;
+}
+
+asmlinkage int
+sys_get_kernel_syms(struct kernel_sym *table)
+{
+ return -ENOSYS;
+}
+
+#endif /* CONFIG_MODULES */
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/sys_sunos32.c linux/arch/sparc64/kernel/sys_sunos32.c
--- v2.1.43/linux/arch/sparc64/kernel/sys_sunos32.c Wed Dec 31 16:00:00 1969
+++ linux/arch/sparc64/kernel/sys_sunos32.c Mon Jul 7 08:18:54 1997
@@ -0,0 +1,1468 @@
+/* $Id: sys_sunos32.c,v 1.2 1997/07/05 07:09:16 davem Exp $
+ * sys_sunos32.c: SunOS binary compatability layer on sparc64.
+ *
+ * Copyright (C) 1995, 1996, 1997 David S. Miller (da...@caip.rutgers.edu)
+ * Copyright (C) 1995 Miguel de Icaza (mig...@nuclecu.unam.mx)
+ *
+ * Based upon preliminary work which is:
+ *
+ * Copyright (C) 1995 Adrian M. Rodriguez (adr...@remus.rutgers.edu)


+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>

+#include <linux/types.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/fs.h>
+#include <linux/resource.h>
+#include <linux/ipc.h>
+#include <linux/shm.h>
+#include <linux/msg.h>
+#include <linux/sem.h>
+#include <linux/signal.h>
+#include <linux/uio.h>
+#include <linux/utsname.h>
+#include <linux/fs.h>
+#include <linux/major.h>
+#include <linux/stat.h>
+#include <linux/malloc.h>
+#include <linux/pagemap.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/pconf.h>
+#include <asm/idprom.h> /* for gethostid() */
+#include <asm/unistd.h>
+#include <asm/system.h>
+
+/* For the nfs mount emulation */
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/nfs.h>
+#include <linux/nfs_mount.h>
+
+/* for sunos_select */
+#include <linux/time.h>
+#include <linux/personality.h>
+
+#define A(x) ((unsigned long)x)
+
+#define SUNOS_NR_OPEN 256
+
+extern unsigned long get_unmapped_area(unsigned long addr, unsigned long len);
+
+asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off)


+{
+ struct file *file = NULL;

+ unsigned long retval, ret_type;
+
+ lock_kernel();
+ current->personality |= PER_BSD;
+ if(flags & MAP_NORESERVE) {
+ printk("%s: unimplemented SunOS MAP_NORESERVE mmap() flag\n",
+ current->comm);
+ flags &= ~MAP_NORESERVE;
+ }
+ retval = -EBADF;
+ if(!(flags & MAP_ANONYMOUS))
+ if(fd >= SUNOS_NR_OPEN || !(file = current->files->fd[fd]))
+ goto out;
+ retval = -ENOMEM;
+ if(!(flags & MAP_FIXED) && !addr) {
+ unsigned long attempt = get_unmapped_area(addr, len);
+ if(!attempt || (attempt >= 0xf0000000UL))
+ goto out;
+ addr = (u32) attempt;
+ }
+ if(MAJOR(file->f_inode->i_rdev) == MEM_MAJOR &&
+ MINOR(file->f_inode->i_rdev) == 5) {
+ flags |= MAP_ANONYMOUS;
+ file = 0;
+ }
+ if(!(flags & MAP_FIXED))
+ addr = 0;
+ ret_type = flags & _MAP_NEW;
+ flags &= ~_MAP_NEW;


+
+ retval = do_mmap(file,

+ (unsigned long) addr, (unsigned long) len,
+ (unsigned long) prot, (unsigned long) flags,
+ (unsigned long) off);
+ if(!ret_type)
+ retval = ((retval < 0xf0000000) ? 0 : retval);
+out:
+ unlock_kernel();
+ return (u32) retval;
+}
+
+asmlinkage int sunos_mctl(u32 addr, u32 len, int function, u32 arg)
+{


+ return 0;
+}
+

+asmlinkage int sunos_brk(u32 baddr)
+{
+ int freepages, retval = -ENOMEM;
+ unsigned long rlim;
+ unsigned long newbrk, oldbrk, brk = (unsigned long) baddr;


+
+ lock_kernel();
+ if (brk < current->mm->end_code)

+ goto out;
+ newbrk = PAGE_ALIGN(brk);
+ oldbrk = PAGE_ALIGN(current->mm->brk);
+ retval = 0;


+ if (oldbrk == newbrk) {

+ current->mm->brk = brk;
+ goto out;
+ }
+ /* Always allow shrinking brk. */


+ if (brk <= current->mm->brk) {

+ current->mm->brk = brk;
+ do_munmap(newbrk, oldbrk-newbrk);
+ goto out;
+ }
+ /* Check against rlimit and stack.. */
+ retval = -ENOMEM;


+ rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+ if (rlim >= RLIM_INFINITY)
+ rlim = ~0;

+ if (brk - current->mm->end_code > rlim)
+ goto out;
+ /* Check against existing mmap mappings. */
+ if (find_vma_intersection(current->mm, oldbrk, newbrk+PAGE_SIZE))
+ goto out;
+ /* stupid algorithm to decide if we have enough memory: while
+ * simple, it hopefully works in most obvious cases.. Easy to
+ * fool it, but this should catch most mistakes.
+ */
+ freepages = buffermem >> PAGE_SHIFT;
+ freepages += page_cache_size;
+ freepages >>= 1;
+ freepages += nr_free_pages;
+ freepages += nr_swap_pages;
+ freepages -= num_physpages >> 4;
+ freepages -= (newbrk-oldbrk) >> PAGE_SHIFT;
+ if (freepages < 0)
+ goto out;
+ /* Ok, we have probably got enough memory - let it rip. */
+ current->mm->brk = brk;


+ do_mmap(NULL, oldbrk, newbrk-oldbrk,
+ PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_FIXED|MAP_PRIVATE, 0);

+ retval = 0;


+out:
+ unlock_kernel();
+ return retval;
+}
+

+asmlinkage u32 sunos_sbrk(int increment)
+{
+ int error, oldbrk;
+
+ /* This should do it hopefully... */
+ lock_kernel();
+ oldbrk = (int)current->mm->brk;
+ error = sunos_brk(((int) current->mm->brk) + increment);
+ if(!error)
+ error = oldbrk;


+ unlock_kernel();
+ return error;
+}
+

+asmlinkage u32 sunos_sstk(int increment)
+{
+ lock_kernel();
+ printk("%s: Call to sunos_sstk(increment<%d>) is unsupported\n",
+ current->comm, increment);
+ unlock_kernel();
+ return (u32)-1;
+}
+
+/* Give hints to the kernel as to what paging strategy to use...
+ * Completely bogus, don't remind me.
+ */
+#define VA_NORMAL 0 /* Normal vm usage expected */
+#define VA_ABNORMAL 1 /* Abnormal/random vm usage probable */
+#define VA_SEQUENTIAL 2 /* Accesses will be of a sequential nature */
+#define VA_INVALIDATE 3 /* Page table entries should be flushed ??? */
+static char *vstrings[] = {
+ "VA_NORMAL",
+ "VA_ABNORMAL",
+ "VA_SEQUENTIAL",
+ "VA_INVALIDATE",
+};
+
+asmlinkage void sunos_vadvise(u32 strategy)
+{
+ /* I wanna see who uses this... */
+ lock_kernel();
+ printk("%s: Advises us to use %s paging strategy\n",
+ current->comm,
+ strategy <= 3 ? vstrings[strategy] : "BOGUS");
+ unlock_kernel();
+}
+
+/* Same as vadvise, and just as bogus, but for a range of virtual
+ * process address space.
+ */
+#define MADV_NORMAL 0 /* Nothing special... */
+#define MADV_RANDOM 1 /* I am emacs... */
+#define MADV_SEQUENTIAL 2 /* I am researcher code... */
+#define MADV_WILLNEED 3 /* Pages in this range will be needed */
+#define MADV_DONTNEED 4 /* Pages in this range won't be needed */
+
+static char *mstrings[] = {
+ "MADV_NORMAL",
+ "MADV_RANDOM",
+ "MADV_SEQUENTIAL",
+ "MADV_WILLNEED",
+ "MADV_DONTNEED",
+};
+
+asmlinkage void sunos_madvise(u32 address, u32 len, u32 strategy)
+{
+ /* I wanna see who uses this... */
+ lock_kernel();
+ printk("%s: Advises us to use %s paging strategy for addr<%08x> len<%08x>\n",
+ current->comm, strategy <= 4 ? mstrings[strategy] : "BOGUS",
+ address, len);
+ unlock_kernel();
+}
+
+/* Places into character array, the status of all the pages in the passed
+ * range from 'addr' to 'addr + len'. -1 on failure, 0 on success...
+ * The encoding in each character is:
+ * low-bit is zero == Page is not in physical ram right now
+ * low-bit is one == Page is currently residing in core
+ * All other bits are undefined within the character so there...
+ * Also, if you try to get stats on an area outside of the user vm area
+ * *or* the passed base address is not aligned on a page boundary you
+ * get an error.
+ */
+asmlinkage int sunos_mincore(u32 addr, u32 len, u32 u_array)
+{


+ pgd_t *pgdp;
+ pmd_t *pmdp;
+ pte_t *ptep;

+ unsigned long limit;
+ int num_pages, pnum, retval = -EINVAL;
+ char *array = (char *)A(u_array);
+
+ lock_kernel();
+ if(addr & ~(4096))
+ goto out;
+ num_pages = (len / 4096);
+ retval = -EFAULT;
+ if(verify_area(VERIFY_WRITE, array, num_pages))
+ goto out;
+ retval = -ENOMEM;
+ if((addr >= 0xf0000000) || ((addr + len) > 0xf0000000))
+ goto out; /* I'm sure you're curious about kernel mappings.. */
+ /* Wheee, go through pte's */
+ pnum = 0;
+ for(limit = addr + len; addr < limit; addr += 4096, pnum++) {


+ pgdp = pgd_offset(current->mm, addr);

+ if(pgd_none(*pgdp))
+ goto out; /* As per SunOS manpage */


+ pmdp = pmd_offset(pgdp, addr);

+ if(pmd_none(*pmdp))
+ goto out; /* As per SunOS manpage */


+ ptep = pte_offset(pmdp, addr);

+ if(pte_none(*ptep))
+ goto out; /* As per SunOS manpage */
+ /* Page in core or Swapped page? */
+ __put_user((pte_present(*ptep) ? 1 : 0), &array[pnum]);
+ }
+ retval = 0; /* Success... I think... */


+out:
+ unlock_kernel();
+ return retval;
+}
+

+/* This just wants the soft limit (ie. rlim_cur element) of the RLIMIT_NOFILE
+ * resource limit and is for backwards compatibility with older sunos
+ * revs.
+ */
+asmlinkage int sunos_getdtablesize(void)
+{
+ return SUNOS_NR_OPEN;
+}
+
+#define _S(nr) (1<<((nr)-1))
+
+#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
+
+asmlinkage u32 sunos_sigblock(u32 blk_mask)
+{
+ unsigned long flags;
+ u32 old;
+
+ lock_kernel();
+ save_and_cli(flags);
+ old = (u32) current->blocked;
+ current->blocked |= (blk_mask & _BLOCKABLE);
+ restore_flags(flags);
+ unlock_kernel();
+ return old;
+}
+
+asmlinkage u32 sunos_sigsetmask(u32 newmask)
+{
+ unsigned long flags;
+ u32 retval;
+
+ lock_kernel();
+ save_and_cli(flags);
+ retval = (u32) current->blocked;
+ current->blocked = (newmask & _BLOCKABLE);
+ restore_flags(flags);


+ unlock_kernel();
+ return retval;
+}
+

+/* SunOS getdents is very similar to the newer Linux (iBCS2 compliant) */
+/* getdents system call, the format of the structure just has a different */
+/* layout (d_off+d_ino instead of d_ino+d_off) */
+struct sunos_dirent {
+ s32 d_off;
+ u32 d_ino;
+ u16 d_reclen;
+ u16 d_namlen;
+ char d_name[1];
+};
+
+struct sunos_dirent_callback {
+ struct sunos_dirent *curr;
+ struct sunos_dirent *previous;
+ int count;


+ int error;
+};
+

+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
+#define ROUND_UP(x) (((x)+sizeof(s32)-1) & ~(sizeof(s32)-1))
+
+static int sunos_filldir(void * __buf, const char * name, int namlen,
+ off_t offset, ino_t ino)
+{
+ struct sunos_dirent * dirent;
+ struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
+ int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+
+ buf->error = -EINVAL; /* only used if we fail.. */
+ if (reclen > buf->count)
+ return -EINVAL;
+ dirent = buf->previous;
+ if (dirent)
+ put_user(offset, &dirent->d_off);
+ dirent = buf->curr;
+ buf->previous = dirent;
+ put_user(ino, &dirent->d_ino);
+ put_user(namlen, &dirent->d_namlen);
+ put_user(reclen, &dirent->d_reclen);
+ copy_to_user(dirent->d_name, name, namlen);
+ put_user(0, dirent->d_name + namlen);
+ ((char *) dirent) += reclen;
+ buf->curr = dirent;
+ buf->count -= reclen;


+ return 0;
+}
+

+asmlinkage int sunos_getdents(unsigned int fd, u32 u_dirent, int cnt)
+{
+ struct file * file;
+ struct sunos_dirent * lastdirent;
+ struct sunos_dirent_callback buf;
+ int error = -EBADF;
+ void *dirent = (void *)A(u_dirent);
+
+ lock_kernel();
+ if (fd >= SUNOS_NR_OPEN || !(file = current->files->fd[fd]))
+ goto out;
+ error = -ENOTDIR;
+ if (!file->f_op || !file->f_op->readdir)
+ goto out;
+ error = -EINVAL;
+ if(cnt < (sizeof(struct sunos_dirent) + 255))
+ goto out;
+
+ buf.curr = (struct sunos_dirent *) dirent;
+ buf.previous = NULL;
+ buf.count = cnt;
+ buf.error = 0;
+ error = file->f_op->readdir(file->f_inode, file, &buf, sunos_filldir);
+ if (error < 0)
+ goto out;
+ lastdirent = buf.previous;
+ if (!lastdirent) {
+ error = buf.error;
+ } else {
+ put_user(file->f_pos, &lastdirent->d_off);
+ error = cnt - buf.count;


+ }
+out:
+ unlock_kernel();
+ return error;
+}
+

+/* Old sunos getdirentries, severely broken compatibility stuff here. */
+struct sunos_direntry {
+ u32 d_ino;
+ u16 d_reclen;
+ u16 d_namlen;
+ char d_name[1];
+};
+
+struct sunos_direntry_callback {
+ struct sunos_direntry *curr;
+ struct sunos_direntry *previous;
+ int count;


+ int error;
+};
+

+static int sunos_filldirentry(void * __buf, const char * name, int namlen,
+ off_t offset, ino_t ino)
+{
+ struct sunos_direntry * dirent;
+ struct sunos_direntry_callback * buf = (struct sunos_direntry_callback *) __buf;
+ int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+
+ buf->error = -EINVAL; /* only used if we fail.. */
+ if (reclen > buf->count)
+ return -EINVAL;
+ dirent = buf->previous;
+ dirent = buf->curr;
+ buf->previous = dirent;
+ put_user(ino, &dirent->d_ino);
+ put_user(namlen, &dirent->d_namlen);
+ put_user(reclen, &dirent->d_reclen);
+ copy_to_user(dirent->d_name, name, namlen);
+ put_user(0, dirent->d_name + namlen);
+ ((char *) dirent) += reclen;
+ buf->curr = dirent;
+ buf->count -= reclen;


+ return 0;
+}
+

+asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent,
+ int cnt, u32 u_basep)
+{
+ struct file * file;
+ struct sunos_direntry * lastdirent;
+ struct sunos_direntry_callback buf;
+ int error = -EBADF;
+ void *dirent = (void *) A(u_dirent);
+ unsigned int *basep = (unsigned int *)A(u_basep);
+
+ lock_kernel();
+ if (fd >= SUNOS_NR_OPEN || !(file = current->files->fd[fd]))
+ goto out;
+ error = -ENOTDIR;
+ if (!file->f_op || !file->f_op->readdir)
+ goto out;
+ error = -EINVAL;
+ if(cnt < (sizeof(struct sunos_direntry) + 255))
+ goto out;
+
+ buf.curr = (struct sunos_direntry *) dirent;
+ buf.previous = NULL;
+ buf.count = cnt;
+ buf.error = 0;
+ error = file->f_op->readdir(file->f_inode, file, &buf, sunos_filldirentry);
+ if (error < 0)
+ goto out;
+ lastdirent = buf.previous;
+ if (!lastdirent) {
+ error = buf.error;
+ } else {
+ put_user(file->f_pos, basep);
+ error = cnt - buf.count;


+ }
+out:
+ unlock_kernel();
+ return error;
+}
+

+asmlinkage int sunos_getdomainname(u32 u_name, int len)
+{
+ int nlen = strlen(system_utsname.domainname);
+ int ret = -EFAULT;
+ char *name = (char *)A(u_name);
+
+ lock_kernel();
+ if (nlen < len)
+ len = nlen;
+
+ if(len > __NEW_UTS_LEN)


+ goto out;
+ if(copy_to_user(name, system_utsname.domainname, len))

+ goto out;
+ ret = 0;


+out:
+ unlock_kernel();
+ return ret;
+}
+

+struct sunos_utsname {
+ char sname[9];
+ char nname[9];
+ char nnext[56];
+ char rel[9];
+ char ver[9];
+ char mach[9];
+};
+
+asmlinkage int sunos_uname(u32 u_name)
+{
+ struct sunos_utsname *name = (struct sunos_utsname *)A(u_name);
+ int ret = -EFAULT;
+
+ lock_kernel();
+ if(!name)
+ goto out;
+ if(copy_to_user(&name->sname[0],
+ &system_utsname.sysname[0],
+ sizeof(name->sname) - 1))


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 21'
echo 'File patch-2.1.44 is continued in part 22'
echo 22 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part14

#!/bin/sh
# this is part 14 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 14; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

+ :"=&r" (value)
+ :"r" (addr), "i" (&&fault));
+ value &= 0xffffffff;
+ regs->regs[insn.i_format.rt] = value;
+ return;
+
+ case ld_op:
+ check_axs(pc, addr, 8);
+ __asm__(
+ ".set\tmips3\n"
+#ifdef __BIG_ENDIAN
+ "1:\tldl\t%0,(%1)\n"
+ "2:\tldr\t%0,7(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tldl\t%0,7(%1)\n"
+ "2:\tldr\t%0,(%1)\n\t"
+#endif
+ ".set\tmips0\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%2\n\t"
+ STR(PTR)"\t2b,%2\n\t"
+ ".previous"
+ :"=&r" (value)
+ :"r" (addr), "i" (&&fault));
+ regs->regs[insn.i_format.rt] = value;
+ return;
+
+ case sh_op:
+ check_axs(pc, addr, 2);
+ value = regs->regs[insn.i_format.rt];
+ __asm__(
+#ifdef __BIG_ENDIAN
+ ".set\tnoat\n"
+ "1:\tsb\t%0,1(%1)\n\t"
+ "srl\t$1,%0,0x8\n"
+ "2:\tsb\t$1,0(%1)\n\t"
+ ".set\tat\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ ".set\tnoat\n"
+ "1:\tsb\t%0,0(%1)\n\t"
+ "srl\t$1,%0,0x8\n"
+ "2:\tsb\t$1,1(%1)\n\t"
+ ".set\tat\n\t"
+#endif
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%2\n\t"
+ STR(PTR)"\t2b,%2\n\t"
+ ".previous"
+ : /* no outputs */
+ :"r" (value), "r" (addr), "i" (&&fault)
+ :"$1");
+ return;
+
+ case sw_op:
+ check_axs(pc, addr, 4);
+ value = regs->regs[insn.i_format.rt];
+ __asm__(
+#ifdef __BIG_ENDIAN
+ "1:\tswl\t%0,(%1)\n"
+ "2:\tswr\t%0,3(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tswl\t%0,3(%1)\n"
+ "2:\tswr\t%0,(%1)\n\t"
+#endif
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%2\n\t"
+ STR(PTR)"\t2b,%2\n\t"
+ ".previous"
+ : /* no outputs */
+ :"r" (value), "r" (addr), "i" (&&fault));
+ return;
+
+ case sd_op:
+ check_axs(pc, addr, 8);
+ value = regs->regs[insn.i_format.rt];
+ __asm__(
+ ".set\tmips3\n"
+#ifdef __BIG_ENDIAN
+ "1:\tsdl\t%0,(%1)\n"
+ "2:\tsdr\t%0,7(%1)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tsdl\t%0,7(%1)\n"
+ "2:\tsdr\t%0,(%1)\n\t"
+#endif
+ ".set\tmips0\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b,%2\n\t"
+ STR(PTR)"\t2b,%2\n\t"
+ ".previous"
+ : /* no outputs */
+ :"r" (value), "r" (addr), "i" (&&fault));
+ return;
+
+ case lwc1_op:
+ case ldc1_op:
+ case swc1_op:
+ case sdc1_op:
+ /*
+ * I herewith declare: this does not happen. So send SIGBUS.
+ */
+ goto sigbus;
+
+ case lwc2_op:
+ case ldc2_op:
+ case swc2_op:
+ case sdc2_op:
+ /*
+ * These are the coprozessor 2 load/stores. The current
+ * implementations don't use cp2 and cp2 should always be
+ * disabled in c0_status. So send SIGILL.
+ * (No longer true: The Sony Praystation uses cp2 for
+ * 3D matrix operations. Dunno if that thingy has a MMU ...)
+ */
+ default:
+ /*
+ * Pheeee... We encountered an yet unknown instruction ...
+ */
+ force_sig(SIGILL, current);
+ }
+ return;
+
+fault:
+ send_sig(SIGSEGV, current, 1);
+ return;
+sigbus:
+ send_sig(SIGBUS, current, 1);
+ return;
+}
+
+unsigned long unaligned_instructions;
+
+static inline void
+fix_ade(struct pt_regs *regs, unsigned long pc)
+{
+ /*
+ * Did we catch a fault trying to load an instruction?
+ */
+ if (regs->cp0_badvaddr == pc) {
+ /*
+ * Phee... Either the code is severly messed up or the
+ * process tried to activate some MIPS16 code.
+ */
+ force_sig(SIGBUS, current);
+ }
+
+ /*
+ * Ok, this wasn't a failed instruction load. The CPU was capable of
+ * reading the instruction and faulted after this. So we don't need
+ * to verify_area the address of the instrucion. We still don't
+ * know whether the address used was legal and therefore need to do
+ * verify_area(). The CPU already did the checking for legal
+ * instructions for us, so we don't need to do this.
+ */
+ emulate_load_store_insn(regs, regs->cp0_badvaddr, pc);
+ unaligned_instructions++;
+}
+
+#define kernel_address(x) ((long)(x) < 0)
+
+asmlinkage void
+do_ade(struct pt_regs *regs)
+{
+ register_t pc = regs->cp0_epc;
+ register_t badvaddr __attribute__ ((unused)) = regs->cp0_badvaddr;
+ char *adels;
+
+ lock_kernel();
+ adels = (((regs->cp0_cause & CAUSEF_EXCCODE) >>
+ CAUSEB_EXCCODE) == 4) ? "adel" : "ades";
+
+#ifdef CONF_NO_UNALIGNED_KERNEL_ACCESS
+ /*
+ * In an ideal world there are no unaligned accesses by the kernel.
+ * So be a bit noisy ...
+ */
+ if (kernel_address(badvaddr) && !user_mode(regs)) {
+ show_regs(regs);
+#ifdef __mips64
+ panic("Caught %s exception in kernel mode accessing %016Lx.",
+ adels, badvaddr);
+#else
+ panic("Caught %s exception in kernel mode accessing %08lx.",
+ adels, badvaddr);
+#endif
+ }
+#endif /* CONF_NO_UNALIGNED_KERNEL_ACCESS */
+
+#ifdef CONF_LOG_UNALIGNED_ACCESSES
+ if (current->tss.mflags & MF_LOGADE) {
+ register_t logpc = pc;
+ if (regs->cp0_cause & CAUSEF_BD)
+ logpc += 4;
+#ifdef __mips64
+ printk(KERN_DEBUG
+ "Caught %s in '%s' at 0x%016Lx accessing 0x%016Lx.\n",
+ adels, current->comm, logpc, regs->cp0_badvaddr);
+#else
+ printk(KERN_DEBUG
+ "Caught %s in '%s' at 0x%08lx accessing 0x%08lx.\n",
+ adels, current->comm, logpc, regs->cp0_badvaddr);
+#endif
+ }
+#endif /* CONF_LOG_UNALIGNED_ACCESSES */
+
+ if (compute_return_epc(regs))
+ goto out;
+ if(current->tss.mflags & MF_FIXADE) {
+ pc += ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0);
+ fix_ade(regs, pc);


+ goto out;
+ }
+

+#ifdef CONF_DEBUG_EXCEPTIONS
+ show_regs(regs);
+#endif
+
+ force_sig(SIGBUS, current);
+
+out:
+ unlock_kernel();
+ return;
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/kernel/vm86.c linux/arch/mips/kernel/vm86.c
--- v2.1.43/linux/arch/mips/kernel/vm86.c Fri Jan 13 08:21:20 1995
+++ linux/arch/mips/kernel/vm86.c Thu Jun 26 12:33:37 1997
@@ -6,9 +6,8 @@
X */
X #include <linux/linkage.h>
X #include <linux/errno.h>
-#include <linux/vm86.h>
X
-asmlinkage int sys_vm86(struct vm86_struct * v86)
+asmlinkage int sys_vm86(void *v86)
X {
X return -ENOSYS;
X }
diff -u --recursive --new-file v2.1.43/linux/arch/mips/ld.script linux/arch/mips/ld.script
--- v2.1.43/linux/arch/mips/ld.script Wed Dec 13 02:39:44 1995
+++ linux/arch/mips/ld.script Wed Dec 31 16:00:00 1969
@@ -1,106 +0,0 @@
-OUTPUT_FORMAT("elf32-littlemips")
-OUTPUT_ARCH(mips)
-ENTRY(kernel_entry)
-SECTIONS
-{
- /* Read-only sections, merged into text segment: */
- . = 0x80000000;
- .rel.text : { *(.rel.text) }
- .rela.text : { *(.rela.text) }
- .rel.data : { *(.rel.data) }
- .rela.data : { *(.rela.data) }
- .rel.rodata : { *(.rel.rodata) }
- .rela.rodata : { *(.rela.rodata) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- .init : { *(.init) } =0
- .text :
- {
- _ftext = . ;
- *(.text)
- *(.rodata)
- *(.rodata1)
- /* .gnu.warning sections are handled specially by elf32.em. */
- *(.gnu.warning)
- } =0
- _etext = .;
- PROVIDE (etext = .);
- .fini : { *(.fini) } =0
- .reginfo : { *(.reginfo) }
- /* Adjust the address for the data segment. We want to adjust up to
- the same address within the page on the next page up. It would
- be more correct to do this:
- . = .;
- The current expression does not correctly handle the case of a
- text segment ending precisely at the end of a page; it causes the
- data segment to skip a page. The above expression does not have
- this problem, but it will currently (2/95) cause BFD to allocate
- a single segment, combining both text and data, for this case.
- This will prevent the text segment from being shared among
- multiple executions of the program; I think that is more
- important than losing a page of the virtual address space (note
- that no actual memory is lost; the page which is skipped can not
- be referenced). */
- . = .;
- .data :
- {
- _fdata = . ;
- *(.data)
- CONSTRUCTORS
- }
- .data1 : { *(.data1) }
- _gp = . + 0x8000;
- .lit8 : { *(.lit8) }
- .lit4 : { *(.lit4) }
- .ctors : { *(.ctors) }
- .dtors : { *(.dtors) }
- .got : { *(.got.plt) *(.got) }
- .dynamic : { *(.dynamic) }
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata : { *(.sdata) }
- _edata = .;
- PROVIDE (edata = .);
- __bss_start = .;
- _fbss = .;
- .bss :
- {
- *(.dynbss)
- *(.bss)
- *(COMMON)
- _end = . ;
- PROVIDE (end = .);
- *(.sbss)
- *(.scommon)
- }
- /* These are needed for ELF backends which have not yet been
- converted to the new style linker. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- /* DWARF debug sections.
- Symbols in the .debug DWARF section are relative to the beginning of the
- section so we begin .debug at 0. It's not clear yet what needs to happen
- for the others. */
- .debug 0 : { *(.debug) }
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- .line 0 : { *(.line) }
- /* These must appear regardless of . */
- .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
- .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
-}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/ld.script.big linux/arch/mips/ld.script.big
--- v2.1.43/linux/arch/mips/ld.script.big Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ld.script.big Thu Jun 26 12:33:37 1997
@@ -0,0 +1,106 @@
+OUTPUT_FORMAT("elf32-bigmips")
+OUTPUT_ARCH(mips)
+ENTRY(kernel_entry)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0x80000000;
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) } =0
+ .text :
+ {
+ _ftext = . ;
+ *(.text)
+ *(.rodata)
+ *(.rodata1)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
+ .fini : { *(.fini) } =0
+ .reginfo : { *(.reginfo) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. It would
+ be more correct to do this:
+ . = .;
+ The current expression does not correctly handle the case of a
+ text segment ending precisely at the end of a page; it causes the
+ data segment to skip a page. The above expression does not have
+ this problem, but it will currently (2/95) cause BFD to allocate
+ a single segment, combining both text and data, for this case.
+ This will prevent the text segment from being shared among
+ multiple executions of the program; I think that is more
+ important than losing a page of the virtual address space (note
+ that no actual memory is lost; the page which is skipped can not
+ be referenced). */
+ . = .;
+ .data :
+ {
+ _fdata = . ;
+ *(.data)
+ CONSTRUCTORS
+ }
+ .data1 : { *(.data1) }
+ _gp = . + 0x8000;
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+ .got : { *(.got.plt) *(.got) }
+ .dynamic : { *(.dynamic) }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : { *(.sdata) }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ _fbss = .;
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ _end = . ;
+ PROVIDE (end = .);


+ *(.sbss)
+ *(.scommon)
+ }

+ /* These are needed for ELF backends which have not yet been
+ converted to the new style linker. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ /* DWARF debug sections.
+ Symbols in the .debug DWARF section are relative to the beginning of the
+ section so we begin .debug at 0. It's not clear yet what needs to happen
+ for the others. */
+ .debug 0 : { *(.debug) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .line 0 : { *(.line) }
+ /* These must appear regardless of . */
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/ld.script.little linux/arch/mips/ld.script.little
--- v2.1.43/linux/arch/mips/ld.script.little Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/ld.script.little Thu Jun 26 12:33:37 1997
@@ -0,0 +1,106 @@
+OUTPUT_FORMAT("elf32-littlemips")
+OUTPUT_ARCH(mips)
+ENTRY(kernel_entry)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0x80000000;
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) } =0
+ .text :
+ {
+ _ftext = . ;
+ *(.text)
+ *(.rodata)
+ *(.rodata1)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
+ .fini : { *(.fini) } =0
+ .reginfo : { *(.reginfo) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. It would
+ be more correct to do this:
+ . = .;
+ The current expression does not correctly handle the case of a
+ text segment ending precisely at the end of a page; it causes the
+ data segment to skip a page. The above expression does not have
+ this problem, but it will currently (2/95) cause BFD to allocate
+ a single segment, combining both text and data, for this case.
+ This will prevent the text segment from being shared among
+ multiple executions of the program; I think that is more
+ important than losing a page of the virtual address space (note
+ that no actual memory is lost; the page which is skipped can not
+ be referenced). */
+ . = .;
+ .data :
+ {
+ _fdata = . ;
+ *(.data)
+ CONSTRUCTORS
+ }
+ .data1 : { *(.data1) }
+ _gp = . + 0x8000;
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+ .got : { *(.got.plt) *(.got) }
+ .dynamic : { *(.dynamic) }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : { *(.sdata) }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ _fbss = .;
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ _end = . ;
+ PROVIDE (end = .);


+ *(.sbss)
+ *(.scommon)
+ }

+ /* These are needed for ELF backends which have not yet been
+ converted to the new style linker. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ /* DWARF debug sections.
+ Symbols in the .debug DWARF section are relative to the beginning of the
+ section so we begin .debug at 0. It's not clear yet what needs to happen
+ for the others. */
+ .debug 0 : { *(.debug) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .line 0 : { *(.line) }
+ /* These must appear regardless of . */
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/Makefile linux/arch/mips/lib/Makefile
--- v2.1.43/linux/arch/mips/lib/Makefile Wed Dec 13 02:39:44 1995
+++ linux/arch/mips/lib/Makefile Thu Jun 26 12:33:37 1997
@@ -1,9 +1,6 @@
X #
X # Makefile for MIPS-specific library files..
X #
-# Many of these routines are just left over debugging trash of ancient
-# times when I just make my Tyne beep and so ...
-#
X
X .S.s:
X $(CPP) $(CFLAGS) $< -o $*.s
@@ -11,6 +8,13 @@
X $(CC) $(CFLAGS) -c $< -o $*.o
X
X L_TARGET = lib.a
-L_OBJS = beep.o checksum.o csum.o dump_tlb.o tinycon.o watch.o
+L_OBJS = checksum.o copy_user.o csum.o dump_tlb.o io.o \
+ memset.o memcpy.o strlen_user.o strncpy_user.o tags.o watch.o
+
+ifdef CONFIG_DECSTATION
+L_OBJS += pmaxcon.o pmaxio.o
+else
+L_OBJS += tinycon.o
+endif
X
X include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/checksum.c linux/arch/mips/lib/checksum.c
--- v2.1.43/linux/arch/mips/lib/checksum.c Thu Apr 11 23:49:30 1996
+++ linux/arch/mips/lib/checksum.c Mon Jul 7 08:18:54 1997
@@ -13,129 +13,92 @@
X * modify it under the terms of the GNU General Public License
X * as published by the Free Software Foundation; either version
X * 2 of the License, or (at your option) any later version.
+ *
+ * $Id: checksum.c,v 1.4 1997/07/03 09:43:16 ralf Exp $
X */
X #include <net/checksum.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
X #include <asm/string.h>
+#include <asm/uaccess.h>
+
+static inline unsigned short from32to16(unsigned long x)
+{
+ /* 32 bits --> 16 bits + carry */
+ x = (x & 0xffff) + (x >> 16);
+ /* 16 bits + carry --> 16 bits including carry */
+ x = (x & 0xffff) + (x >> 16);
+ return x;
+}
+
+static inline unsigned long do_csum(const unsigned char * buff, int len)
+{
+ int odd, count;
+ unsigned long result = 0;
+
+ if (len <= 0)
+ goto out;
+ odd = 1 & (unsigned long) buff;
+ if (odd) {
+ result = be16_to_cpu(*buff);
+ len--;
+ buff++;
+ }
+ count = len >> 1; /* nr of 16-bit words.. */
+ if (count) {
+ if (2 & (unsigned long) buff) {
+ result += *(unsigned short *) buff;
+ count--;
+ len -= 2;
+ buff += 2;
+ }
+ count >>= 1; /* nr of 32-bit words.. */
+ if (count) {
+ unsigned long carry = 0;
+ do {
+ unsigned long w = *(unsigned long *) buff;
+ count--;
+ buff += 4;
+ result += carry;
+ result += w;
+ carry = (w > result);
+ } while (count);
+ result += carry;
+ result = (result & 0xffff) + (result >> 16);
+ }
+ if (len & 2) {
+ result += *(unsigned short *) buff;
+ buff += 2;
+ }
+ }
+ if (len & 1)
+ result += le16_to_cpu(*buff);
+ result = from32to16(result);
+ if (odd)
+ result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+out:
+ return result;
+}
X
X /*
X * computes a partial checksum, e.g. for TCP/UDP fragments
X */
-
X unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum)
X {
- unsigned long scratch1;
- unsigned long scratch2;
-
- /*
- * The GCC generated code for handling carry bits makes
- * it strongly desirable to do this in assembler!
- */
- __asm__("
- .set noreorder
- .set noat
- andi $1,%5,2 # Check alignment
- beqz $1,2f # Branch if ok
- subu $1,%4,2 # delay slot, Alignment uses up two bytes
- bgez $1,1f # Jump if we had at least two bytes
- move %4,$1 # delay slot
- j 4f
- addiu %4,2 # delay slot; len was < 2. Deal with it
-
-1: lw %2,(%5)
- addiu %4,2
- addu %0,%2
- sltu $1,%0,%2
- addu %0,$1
-
-2: move %1,%4
- srl %1,%1,5
- beqz %1,2f
- sll %1,%1,5 # delay slot
-
- addu %1,%5
-1: lw %2,0(%5)
- addu %5,32
- addu %0,%2
- sltu $1,%0,%2
-
- lw %2,-28(%5)
- addu %0,$1
- addu %0,%2
- sltu $1,%0,%2
-
- lw %2,-24(%5)
- addu %0,$1
- addu %0,%2
- sltu $1,%0,%2
-
- lw %2,-20(%5)
- addu %0,$1
- addu %0,%2
- sltu $1,%0,%2
-
- lw %2,-16(%5)
- addu %0,$1
- addu %0,%2
- sltu $1,%0,%2
-
- lw %2,-12(%5)
- addu %0,$1
- addu %0,%2
- sltu $1,%0,%2
-
- lw %2,-8(%5)
- addu %0,$1
- addu %0,%2
- sltu $1,%0,%2
-
- lw %2,-4(%5)
- addu %0,$1
- addu %0,%2
- sltu $1,%0,%2
-
- bne %5,%1,1b
- addu %0,$1 # delay slot
-
-2: andi %1,%4,0x1c
- srl %1,%1,2
- beqz %1,4f
- addu %1,%5 # delay slot
-3: lw %2,0(%5)
- addu %5,4
- addu %0,%2
- sltu $1,%0,%2
- bne %5,%1,3b
- addu %0,$1 # delay slot
-
-4: andi $1,%3,2
- beqz $1,5f
- move %2,$0 # delay slot
- lhu %2,(%5)
- addiu %5,2
-
-5: andi $1,%3,1
- beqz $1,6f
- sll %1,16 # delay slot
- lbu %1,(%5)
- nop # NOP ALERT (spit, gasp)
-6: or %2,%1
- addu %0,%2
- sltu $1,%0,%2
- addu %0,$1
-7: .set at
- .set reorder"
- : "=r"(sum), "=r" (scratch1), "=r" (scratch2)
- : "0"(sum), "r"(len), "r"(buff)
- : "$1");
+ unsigned long result = do_csum(buff, len);
X
- return sum;
+ /* add in old sum, and carry.. */
+ result += sum;
+ if(sum > result)
+ result += 1;
+ return result;
X }
X
X /*
- * copy from fs while checksumming, otherwise like csum_partial
+ * copy while checksumming, otherwise like csum_partial
X */
X unsigned int csum_partial_copy(const char *src, char *dst,
- int len, int sum)
+ int len, unsigned int sum)
X {
X /*
X * It's 2:30 am and I don't feel like doing it real ...
@@ -145,4 +108,24 @@
X memcpy(dst, src, len);
X
X return sum;
+}
+
+/*
+ * Copy from userspace and compute checksum. If we catch an exception
+ * then zero the rest of the buffer.
+ */
+unsigned int csum_partial_copy_from_user (const char *src, char *dst,
+ int len, unsigned int sum,
+ int *err_ptr)
+{
+ int *dst_err_ptr=NULL;
+ int missing;
+
+ missing = copy_from_user(dst, src, len);
+ if (missing) {
+ memset(dst + len - missing, 0, missing);
+ *err_ptr = -EFAULT;
+ }
+
+ return csum_partial(dst, len, sum);
X }
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/copy_user.S linux/arch/mips/lib/copy_user.S
--- v2.1.43/linux/arch/mips/lib/copy_user.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/copy_user.S Thu Jun 26 12:33:37 1997
@@ -0,0 +1,207 @@
+/*
+ * arch/mips/mips1/memcpy.S


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.

+ *
+ * Copyright (c) 1996 by Ralf Baechle
+ *
+ * Less stupid memcpy/user_copy implementation for 32 bit MIPS CPUs.


+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>

+#include <asm/mipsregs.h>
+
+#define BLOCK_SIZE 16
+
+#define EX(addr,handler) \
+ .section __ex_table,"a"; \
+ PTR addr, handler; \
+ .previous
+#define UEX(addr,handler) \
+ EX(addr,handler); \
+ EX(addr+4,handler)
+


+ .set noreorder
+ .set noat
+

+/* ---------------------------------------------------------------------- */
+
+/*
+ * Bad. We can't fix the alignment for both address parts.
+ * Align the source address and copy slowly ...
+ */
+not_even_the_same_alignment:
+ LONG_SUBU v1,zero,a1
+ andi v1,a1,3
+ sltu t0,v0,v1
+ MOVN(v1,v0,t0)
+ beqz v1,align4 # -> finished
+ LONG_ADDU v1,a0 # delay slot
+1: lb $1,(a1)
+ EX(1b, fault)
+ LONG_ADDIU a1,1
+2: sb $1,(a0)
+ EX(2b, fault)
+ LONG_ADDIU a0,1
+ bne a0,v1,1b
+ LONG_SUBU v0,1 # delay slot
+
+/*
+ * Ok. We've fixed the alignment of the copy src for this case.
+ * Now let's copy in the usual BLOCK_SIZE byte blocks using unaligned
+ * stores.
+ * XXX Align the destination address. This is better if the __copy_user
+ * encounters an access fault because we never have to deal with an
+ * only partially modified destination word.
+ */
+ ori v1,v0,BLOCK_SIZE-1
+ xori v1,BLOCK_SIZE-1
+ beqz v1,copy_left_over


+ nop # delay slot

+ LONG_SUBU v0,v1
+ LONG_ADDU v1,a0
+
+1: lw t0,(a1) # Can cause tlb fault
+ EX(1b, fault)
+2: lw t1,4(a1) # Can cause tlb fault
+ EX(2b, fault)
+2: lw t2,8(a1) # Can cause tlb fault
+ EX(2b, fault)
+2: lw t3,12(a1) # Can cause tlb fault
+ EX(2b, fault)
+2: usw t0,(a0) # Can cause tlb faults
+ UEX(2b, fault)
+2: usw t1,4(a0) # Can cause tlb faults
+ UEX(2b, fault_plus_4)
+2: usw t2,8(a0) # Can cause tlb faults
+ UEX(2b, fault_plus_8)
+2: usw t3,12(a0) # Can cause tlb faults
+ UEX(2b, fault_plus_12)
+ LONG_ADDIU a0,BLOCK_SIZE
+ bne a0,v1,1b
+ LONG_ADDIU a1,BLOCK_SIZE # delay slot
+9:
+ b copy_left_over # < BLOCK_SIZE bytes left


+ nop # delay slot
+

+/* ---------------------------------------------------------------------- */
+
+not_w_aligned:
+/*
+ * Ok, src or destination are not 8-byte aligned.
+ * Try to fix that. Do at least both addresses have the same alignment?
+ */
+ xor t0,a0,a1
+ andi t0,3
+ bnez t0,not_even_the_same_alignment


+ nop # delay slot
+
+/*

+ * Ok, we can fix the alignment for both operands and go back to the
+ * fast path. We have to copy at least one byte, on average 3 bytes
+ * bytewise.
+ */
+ LONG_SUBU v1,zero,a0
+ andi v1,3
+ sltu t0,v0,v1
+ MOVN(v1,v0,t0)
+ beqz v1,3f # -> finished
+ LONG_ADDU v1,a0 # delay slot
+1: lb $1,(a1)
+ EX(1b, fault)
+ LONG_ADDIU a1,1
+2: sb $1,(a0)
+ EX(2b, fault)
+ LONG_ADDIU a0,1
+ bne a0,v1,1b
+ LONG_SUBU v0,1 # delay slot
+ b align4


+ nop # delay slot

+3:
+
+/* ---------------------------------------------------------------------- */
+
+LEAF(__copy_user)
+ or t1,a0,a1
+ andi t1,3
+ bnez t1,not_w_aligned
+ move v0,a2 # delay slot
+
+align4:
+ ori v1,v0,BLOCK_SIZE-1
+ xori v1,BLOCK_SIZE-1
+ beqz v1,copy_left_over


+ nop # delay slot

+ LONG_SUBU v0,v1
+ LONG_ADDU v1,a0
+
+1: lw t0,(a1) # Can cause tlb fault
+ EX(1b, fault)
+2: lw t1,4(a1) # Can cause tlb fault
+ EX(2b, fault)
+2: lw t2,8(a1) # Can cause tlb fault
+ EX(2b, fault)
+2: lw t3,12(a1) # Can cause tlb fault
+ EX(2b, fault)
+2: sw t0,(a0) # Can cause tlb fault
+ EX(2b, fault)
+2: sw t1,4(a0) # Can cause tlb fault
+ EX(2b, fault_plus_4)
+2: sw t2,8(a0) # Can cause tlb fault
+ EX(2b, fault_plus_8)
+2: sw t3,12(a0) # Can cause tlb fault
+ EX(2b, fault_plus_12)
+ LONG_ADDIU a0,BLOCK_SIZE
+ bne a0,v1,1b
+ LONG_ADDIU a1,BLOCK_SIZE # delay slot
+9:
+
+/*
+ * XXX Tune me ...
+ */
+copy_left_over:
+ beqz v0,3f


+ nop # delay slot

+1: lb $1,(a1)
+ EX(1b, fault)
+ LONG_ADDIU a1,1
+2: sb $1,(a0)
+ EX(2b, fault)
+ LONG_SUBU v0,1
+ bnez v0,1b
+ LONG_ADDIU a0,1
+3: jr ra


+ nop # delay slot
+

+ END(__copy_user)
+ .set at
+ .set reorder
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Access fault. The number of not copied bytes is in v0. We have to
+ * correct the number of the not copied bytes in v0 in case of a access
+ * fault in an unrolled loop, then return.
+ */
+
+fault: jr ra
+fault_plus_4: LONG_ADDIU v0,4
+ jr ra
+fault_plus_8: LONG_ADDIU v0,8
+ jr ra
+fault_plus_12: LONG_ADDIU v0,12
+ jr ra
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * For now we use __copy_user for __memcpy, too. This is effizient (one
+ * instruction penatly) and smaller but adds unwanted error checking we don't
+ * need. This hopefully doesn't cover any bugs. The memcpy() wrapper in
+ * <asm/string.h> takes care of the return value in a way GCC can optimize.
+ */
+ .globl __memcpy
+__memcpy = __copy_user
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/csum.S linux/arch/mips/lib/csum.S
--- v2.1.43/linux/arch/mips/lib/csum.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/csum.S Thu Jun 26 12:33:37 1997
@@ -0,0 +1,25 @@
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+/*
+ * Compute kernel code checksum to check kernel code against corruption
+ * (Ancient debugging trash ...)
+ */
+ LEAF(csum)
+ LONG_L t0,cacheflush
+ move t8,ra
+ jalr t0
+ li t0,KSEG1
+ la t1,final
+ li t2,KSEG1
+ or t0,t2
+ or t1,t2
+ move v0,zero
+1: lw t2,(t0)
+ addiu t0,4
+ bne t0,t1,1b
+ xor v0,t2
+ jr t8
+ nop
+ END(csum)
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/dump_tlb.c linux/arch/mips/lib/dump_tlb.c
--- v2.1.43/linux/arch/mips/lib/dump_tlb.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/dump_tlb.c Thu Jun 26 12:33:37 1997
@@ -0,0 +1,148 @@
+/*
+ * Dump R4x00 TLB for debugging purposes.
+ *
+ * Copyright (C) 1994, 1995 by Waldorf Electronics,
+ * written by Ralf Baechle.
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+void
+dump_tlb(int first, int last)
+{
+ int i;
+ int wired;
+ unsigned int pagemask;
+ unsigned long long entryhi, entrylo0, entrylo1;
+
+ wired = read_32bit_cp0_register(CP0_WIRED);
+ printk("Wired: %d", wired);
+
+ for(i=first;i<last;i++)
+ {
+ write_32bit_cp0_register(CP0_INDEX, i);
+ __asm__ __volatile__(
+ ".set\tmips3\n\t"
+ ".set\tnoreorder\n\t"
+ "nop;nop;nop;nop\n\t"
+ "tlbr\n\t"
+ "nop;nop;nop;nop\n\t"
+ ".set\treorder\n\t"
+ ".set\tmips0\n\t");
+ pagemask = read_32bit_cp0_register(CP0_PAGEMASK);
+ entryhi = read_64bit_cp0_register(CP0_ENTRYHI);
+ entrylo0 = read_64bit_cp0_register(CP0_ENTRYLO0);
+ entrylo1 = read_64bit_cp0_register(CP0_ENTRYLO1);
+
+ if((entrylo0|entrylo1) & 2)
+ {
+ /*
+ * Only print entries in use
+ */
+ printk("\nIndex: %2d %08x", i, pagemask);
+
+ printk(" %08x %08x", (unsigned int)(entryhi >> 32),
+ (unsigned int) entryhi);
+ printk(" %08x %08x", (unsigned int)(entrylo0 >> 32),
+ (unsigned int) entrylo0);
+ printk(" %08x %08x", (unsigned int)(entrylo1 >> 32),
+ (unsigned int) entrylo1);
+ }
+ }
+ printk("\n");
+}
+
+void
+dump_tlb_all(void)
+{
+ dump_tlb(0, mips_tlb_entries - 1);
+}
+
+void
+dump_tlb_wired(void)
+{
+ dump_tlb(0, read_32bit_cp0_register(CP0_WIRED));
+}
+
+void
+dump_tlb_nonwired(void)
+{
+ dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_tlb_entries - 1);
+}
+
+void
+dump_list_process(struct task_struct *t, void *address)
+{
+ pgd_t *page_dir, *pgd;
+ pmd_t *pmd;
+ pte_t *pte, page;
+ unsigned int addr;
+
+ addr = (unsigned int) address;
+
+ printk("Addr == %08x\n", addr);
+ printk("tasks->tss.pg_dir == %08x\n", (unsigned int) t->tss.pg_dir);
+ printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd);
+
+ page_dir = pgd_offset(t->mm, 0);
+ printk("page_dir == %08x\n", (unsigned int) page_dir);
+
+ pgd = pgd_offset(t->mm, addr);
+ printk("pgd == %08x, ", (unsigned int) pgd);
+
+ pmd = pmd_offset(pgd, addr);
+ printk("pmd == %08x, ", (unsigned int) pmd);
+
+ pte = pte_offset(pmd, addr);
+ printk("pte == %08x, ", (unsigned int) pte);
+
+ page = *pte;
+ printk("page == %08x\n", (unsigned int) pte_val(page));
+}
+
+void
+dump_list_current(void *address)
+{
+ dump_list_process(current, address);
+}
+
+unsigned int
+vtop(void *address)
+{
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ unsigned int addr, paddr;
+
+ addr = (unsigned long) address;
+ pgd = pgd_offset(current->mm, addr);
+ pmd = pmd_offset(pgd, addr);
+ pte = pte_offset(pmd, addr);
+ paddr = (KSEG1 | (unsigned int) pte_val(*pte)) & PAGE_MASK;
+ paddr |= (addr & ~PAGE_MASK);
+
+ return paddr;
+}
+
+void
+dump16(unsigned long *p)


+{
+ int i;
+

+ for(i=0;i<8;i++)
+ {
+ printk("*%08lx == %08lx, ",
+ (unsigned long)p, (unsigned long)*p++);
+ printk("*%08lx == %08lx\n",
+ (unsigned long)p, (unsigned long)*p++);
+ }
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/io.c linux/arch/mips/lib/io.c
--- v2.1.43/linux/arch/mips/lib/io.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/io.c Thu Jun 26 12:33:37 1997
@@ -0,0 +1,24 @@
+/*
+ * include/asm-mips/string.h


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.

+ *
+ * Copyright (c) 1994, 1995, 1996 by Ralf Baechle
+ *
+ * For now io.c contains only the definition of isa_slot_offset. The
+ * real io.S doesn't assemble due to a GAS bug.
+ */
+
+/*
+ * port_base is the begin of the address space to which x86 style
+ * I/O ports are mapped.
+ */
+unsigned long port_base;


+
+/*
+ * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped
+ * for the processor.
+ */

+unsigned long isa_slot_offset;
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/memcpy.S linux/arch/mips/lib/memcpy.S
--- v2.1.43/linux/arch/mips/lib/memcpy.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/memcpy.S Thu Jun 26 12:33:37 1997
@@ -0,0 +1,221 @@
+/* memcpy.S: Mips optimized memcpy based upon SparcLinux code.
+ *
+ * Copyright(C) 1995 Linus Torvalds
+ * Copyright(C) 1996 David S. Miller
+ * Copyright(C) 1996 Eddie C. Dost
+ *
+ * derived from:
+ * e-mail between David and Eddie.
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5) \
+ lw t0, (offset + 0x18)(src); \
+ lw t1, (offset + 0x1c)(src); \
+ sw t0, (offset + 0x18)(dst); \
+ lw t2, (offset + 0x10)(src); \
+ sw t1, (offset + 0x1c)(dst); \
+ lw t3, (offset + 0x14)(src); \
+ sw t2, (offset + 0x10)(dst); \
+ lw t4, (offset + 0x08)(src); \
+ sw t3, (offset + 0x14)(dst); \
+ lw t5, (offset + 0x0c)(src); \
+ sw t4, (offset + 0x08)(dst); \
+ lw t0, (offset + 0x00)(src); \
+ sw t5, (offset + 0x0c)(dst); \
+ lw t1, (offset + 0x04)(src); \
+ sw t0, (offset + 0x00)(dst); \
+ sw t1, (offset + 0x04)(dst); \
+
+ /* Alignment cases are:
+ * 1) (src&0x3)=0x0 (dst&0x3)=0x0 can optimize
+ * 2) (src&0x3)=0x1 (dst&0x3)=0x1 can optimize
+ * 3) (src&0x3)=0x2 (dst&0x3)=0x2 can optimize
+ * 4) (src&0x3)=0x3 (dst&0x3)=0x3 can optimize
+ * 5) anything else cannot optimize
+ */
+
+ /* I hate MIPS register names... AIEEE, it's a SPARC! */
+#define o0 a0
+#define o1 a1
+#define o2 a2
+#define o3 a3
+#define o4 t0
+#define o5 t1
+#define o6 sp
+#define o7 ra
+#define g0 zero
+#define g1 t2
+#define g2 t3
+#define g3 t4
+#define g4 t5
+#define g5 t6
+#define g6 t7
+#define g7 t8


+
+ .text
+ .set noreorder
+ .set noat
+

+ .globl bcopy
+ .globl amemmove
+ .globl memmove
+ .globl memcpy
+ .align 2
+bcopy:
+ move o3, o0
+ move o0, o1
+ move o1, o3
+
+amemmove:
+memmove:
+memcpy: /* o0=dst o1=src o2=len */
+ xor o4, o0, o1
+ andi o4, o4, 0x3
+ move g6, o0
+ beq o4, g0, can_align
+ sltiu g7, o2, 0x8
+
+ b cannot_optimize
+ move g1, o2
+
+can_align:
+ bne g7, g0, cannot_optimize
+ move g1, o2
+
+ beq o2, g0, out
+ andi g7, o1, 0x1
+
+hword_align:
+ beq g7, g0, word_align
+ andi g7, o1, 0x2
+
+ lbu o4, 0x00(o1)
+ subu o2, o2, 0x1
+ sb o4, 0x00(o0)
+ addu o1, o1, 0x1
+ addu o0, o0, 0x1
+ andi g7, o1, 0x2
+
+word_align:
+ beq g7, g0, dword_align
+ sltiu g7, o2, 56
+
+ lhu o4, 0x00(o1)
+ subu o2, o2, 0x2
+ sh o4, 0x00(o0)
+ sltiu g7, o2, 56
+ addu o0, o0, 0x2
+ addu o1, o1, 0x2
+
+dword_align:
+ bne g7, g0, do_end_words
+ move g7, o2
+
+ andi g7, o1, 0x4
+ beq g7, zero, qword_align
+ andi g7, o1, 0x8
+
+ lw o4, 0x00(o1)
+ subu o2, o2, 0x4
+ sw o4, 0x00(o0)
+ addu o1, o1, 0x4
+ addu o0, o0, 0x4
+ andi g7, o1, 0x8
+
+qword_align:
+ beq g7, g0, oword_align
+ andi g7, o1, 0x10
+
+ lw o4, 0x00(o1)
+ lw o5, 0x04(o1)
+ subu o2, o2, 0x8
+ sw o4, 0x00(o0)
+ addu o1, o1, 0x8
+ sw o5, 0x04(o0)
+ andi g7, o1, 0x10
+ addu o0, o0, 0x8
+
+oword_align:
+ beq g7, g0, begin_movement
+ srl g7, o2, 0x7
+
+ lw g2, 0x08(o1)
+ lw g3, 0x0c(o1)
+ lw o4, 0x00(o1)
+ lw o5, 0x04(o1)
+ sw g2, 0x08(o0)
+ subu o2, o2, 0x10
+ sw g3, 0x0c(o0)
+ addu o1, o1, 0x10
+ sw o4, 0x00(o0)
+ srl g7, o2, 0x7
+ addu o0, o0, 0x10
+ sw o5, -0x0c(o0)
+
+begin_movement:
+ beq g7, g0, 0f
+ andi g1, o2, 0x40
+
+move_128bytes:
+ MOVE_BIGCHUNK(o1, o0, 0x00, o4, o5, g2, g3, g4, g5)
+ MOVE_BIGCHUNK(o1, o0, 0x20, o4, o5, g2, g3, g4, g5)
+ MOVE_BIGCHUNK(o1, o0, 0x40, o4, o5, g2, g3, g4, g5)
+ MOVE_BIGCHUNK(o1, o0, 0x60, o4, o5, g2, g3, g4, g5)
+ subu g7, g7, 0x01
+ addu o1, o1, 0x80
+ bne g7, g0, move_128bytes
+ addu o0, o0, 0x80
+
+0:
+ beq g1, g0, 1f
+ andi g1, o2, 0x20
+
+move_64bytes:
+ MOVE_BIGCHUNK(o1, o0, 0x00, o4, o5, g2, g3, g4, g5)
+ MOVE_BIGCHUNK(o1, o0, 0x20, o4, o5, g2, g3, g4, g5)
+ addu o1, o1, 0x40
+ addu o0, o0, 0x40
+
+1:
+ beq g1, g0, do_end_words
+ andi g7, o2, 0x1c
+
+move_32bytes:
+ MOVE_BIGCHUNK(o1, o0, 0x00, o4, o5, g2, g3, g4, g5)
+ andi g7, o2, 0x1c
+ addu o1, o1, 0x20
+ addu o0, o0, 0x20
+
+do_end_words:
+ beq g7, g0, maybe_end_cruft
+ srl g7, g7, 0x2
+
+end_words:
+ lw o4, 0x00(o1)
+ subu g7, g7, 0x1
+ sw o4, 0x00(o0)
+ addu o1, o1, 0x4
+ bne g7, g0, end_words
+ addu o0, o0, 0x4
+
+maybe_end_cruft:
+ andi g1, o2, 0x3
+
+cannot_optimize:
+ beq g1, g0, out
+ move o2, g1
+
+end_bytes:
+ lbu o4, 0x00(o1)
+ subu o2, o2, 0x1
+ sb o4, 0x00(o0)
+ addu o1, o1, 0x1
+ bne o2, g0, end_bytes
+ addu o0, o0, 0x1
+
+out:
+ jr o7
+ move v0, g6
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/memset.c linux/arch/mips/lib/memset.c
--- v2.1.43/linux/arch/mips/lib/memset.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/memset.c Thu Jun 26 12:33:37 1997
@@ -0,0 +1,71 @@
+/* linux/arch/mips/lib/memset.c
+ *
+ * This is from GNU libc.
+ */
+
+#include <linux/types.h>
+
+#define op_t unsigned long int
+#define OPSIZ (sizeof(op_t))
+
+typedef unsigned char byte;
+
+void *memset(void *dstpp, char c, size_t len)
+{
+ long int dstp = (long int) dstpp;
+
+ if (len >= 8) {
+ size_t xlen;
+ op_t cccc;
+
+ cccc = (unsigned char) c;
+ cccc |= cccc << 8;
+ cccc |= cccc << 16;
+
+ /* There are at least some bytes to set.
+ No need to test for LEN == 0 in this alignment loop. */
+ while (dstp % OPSIZ != 0) {
+ ((byte *) dstp)[0] = c;
+ dstp += 1;
+ len -= 1;
+ }
+
+ /* Write 8 `op_t' per iteration until less
+ * than 8 `op_t' remain.
+ */
+ xlen = len / (OPSIZ * 8);
+ while (xlen > 0) {
+ ((op_t *) dstp)[0] = cccc;
+ ((op_t *) dstp)[1] = cccc;
+ ((op_t *) dstp)[2] = cccc;
+ ((op_t *) dstp)[3] = cccc;
+ ((op_t *) dstp)[4] = cccc;
+ ((op_t *) dstp)[5] = cccc;
+ ((op_t *) dstp)[6] = cccc;
+ ((op_t *) dstp)[7] = cccc;
+ dstp += 8 * OPSIZ;
+ xlen -= 1;
+ }
+ len %= OPSIZ * 8;
+
+ /* Write 1 `op_t' per iteration until less than
+ * OPSIZ bytes remain.
+ */
+ xlen = len / OPSIZ;
+ while (xlen > 0) {
+ ((op_t *) dstp)[0] = cccc;
+ dstp += OPSIZ;
+ xlen -= 1;
+ }
+ len %= OPSIZ;
+ }
+
+ /* Write the last few bytes. */
+ while (len > 0) {
+ ((byte *) dstp)[0] = c;
+ dstp += 1;
+ len -= 1;
+ }
+
+ return dstpp;
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/pmaxcon.c linux/arch/mips/lib/pmaxcon.c
--- v2.1.43/linux/arch/mips/lib/pmaxcon.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/pmaxcon.c Thu Jun 26 12:33:37 1997
@@ -0,0 +1,150 @@
+/* ----------------------------------------------------------------------
+ * console.c
+ *
+ * Copyright (C) 1994 by Waldorf Electronic,
+ * written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1995 Paul M. Antoine (PMAX)


+ *
+ * This file is subject to the terms and conditions of the GNU General Public

+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ * ---------------------------------------------------------------------- */
+/*
+ * FIXME: This file is hacked to be hardwired for the Personal DECStation
+ * Only thought of as a debugging console output
+ */
+
+#include <linux/tty.h>
+#include <asm/bootinfo.h>
+
+static unsigned int size_x;
+static unsigned int size_y;
+static unsigned short cursor_x;
+static unsigned short cursor_y;
+static volatile unsigned short *vram_addr;
+static int console_needs_init = 1;
+
+extern struct bootinfo boot_info;
+extern struct screen_info screen_info;
+
+/*
+ * Here is the base address of the prom calls
+ */
+unsigned long pmax_rex_base = 0;
+
+/* ----------------------------------------------------------------------
+ * init_console()
+ * ---------------------------------------------------------------------- */
+
+void init_console(void)
+{
+ size_x = 80;
+ size_y = 50;
+ cursor_x = 0;
+ cursor_y = 0;
+
+ vram_addr = (unsigned short *)0xe10b8000;
+
+ console_needs_init = 0;
+}
+
+void
+set_size_x(unsigned int x)
+{
+ size_x = x;
+}
+
+void
+set_size_y(unsigned int y)
+{
+ size_y = y;
+}
+
+void
+set_vram(unsigned short *vram)
+{
+ vram_addr = vram;
+}
+
+/*
+ * FIXME: Temporary hack - changed its name to avoid conflict in
+ * drivers/char/vga.c that shouldn't be there <sigh> PMA
+ */
+void
+set_pmax_cursor(unsigned int x, unsigned int y)
+{
+ cursor_x = x;
+ cursor_y = y;
+}
+
+void
+print_char(unsigned int x, unsigned int y, unsigned char c)
+{
+ volatile unsigned short *caddr;
+
+/* caddr = vram_addr + (y * size_x) + x;
+ *caddr = (*caddr & 0xff00) | 0x0f00 | (unsigned short) c;
+*/
+ pmax_putch(c);
+}
+
+static void
+scroll(void)
+{
+ volatile unsigned short *caddr;
+ register int i;
+/*
+ caddr = vram_addr;
+ for(i=0; i<size_x * (size_y-1); i++)
+ *(caddr++) = *(caddr + size_x);
+
+ blank last line
+
+ caddr = vram_addr + (size_x * (size_y-1));
+ for(i=0; i<size_x; i++)
+ *(caddr++) = (*caddr & 0xff00) | (unsigned short) ' ';
+*/
+ pmax_putch('\n');
+}
+
+void print_string(const unsigned char *str)
+{
+ unsigned char c;
+
+ if (console_needs_init)
+ init_console();
+/*
+ while((c = *str++))
+ switch(c)
+ {
+ case '\n':
+ cursor_x = 0;
+ cursor_y++;
+ if(cursor_y == size_y)
+ {
+ scroll();
+ cursor_y = size_y - 1;
+ }


+ break;
+
+ default:

+ print_char(cursor_x, cursor_y, c);
+ cursor_x++;
+ if(cursor_x == size_x)
+ {
+ cursor_x = 0;
+ cursor_y++;
+ if(cursor_y == size_y)
+ {
+ scroll();
+ cursor_y = size_y - 1;
+ }
+ }
+ break;
+ }
+*/
+ pmax_printf(str);
+
+}
+
+/* end of file */
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/pmaxio.S linux/arch/mips/lib/pmaxio.S
--- v2.1.43/linux/arch/mips/lib/pmaxio.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/pmaxio.S Thu Jun 26 12:33:37 1997
@@ -0,0 +1,40 @@
+#include <asm/regdef.h>
+#include <asm/decstation.h>
+
+ .text
+ .set reorder
+/*
+ * pmax_printf - call the PROM printf() function
+ */
+ .globl pmax_printf
+pmax_printf:
+ lw v0,pmax_rex_base
+ lw v0,REX_PRINTF(v0)
+ j v0
+
+/*
+ * pmax_getchar - call the PROM getchar() function
+ */
+ .globl pmax_getch
+pmax_getch:
+ lw v0,pmax_rex_base
+ lw v0,REX_GETCHAR(v0)
+ j v0
+
+/*
+ * pmax_putchar - call the PROM putchar() function
+ */
+ .globl pmax_putch
+pmax_putch:
+ lw v0,pmax_rex_base
+ lw v0,REX_PUTCHAR(v0)
+ j v0
+
+/*
+ * pmax_halt - call the PROM halt() function
+ */
+ .globl pmax_halt
+pmax_halt:
+ lw v0,pmax_rex_base
+ lw v0,REX_HALT(v0)
+ j v0
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/strlen_user.S linux/arch/mips/lib/strlen_user.S
--- v2.1.43/linux/arch/mips/lib/strlen_user.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/strlen_user.S Thu Jun 26 12:33:37 1997
@@ -0,0 +1,33 @@
+/*
+ * arch/mips/lib/strlen_user.S


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.

+ *
+ * Copyright (c) 1996 by Ralf Baechle


+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>

+#include <asm/sgidefs.h>
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+LEAF(__strlen_user)
+ move v0,zero
+1: lb t0,(a0)
+ LONG_ADDIU v0,1
+ LONG_ADDIU a0,1
+ bnez t0,1b
+ jr ra
+ END(__strlen_user)
+
+ .section __ex_table,"a"
+ PTR 1b,fault
+ .previous
+
+fault: move v0,zero
+ jr ra
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/strncpy_user.S linux/arch/mips/lib/strncpy_user.S
--- v2.1.43/linux/arch/mips/lib/strncpy_user.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/strncpy_user.S Thu Jun 26 12:33:37 1997
@@ -0,0 +1,48 @@
+/*
+ * arch/mips/lib/strncpy_user.S


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.

+ *
+ * Copyright (c) 1996 by Ralf Baechle
+ */
+#include <linux/errno.h>
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+/*
+ * Returns: -EFAULT if exception before terminator, N if the entire
+ * buffer filled, else strlen.
+ */
+
+/*
+ * Ugly special case have to check: we might get passed a user space
+ * pointer which wraps into the kernel space ...
+ */
+
+LEAF(__strncpy_from_user)
+ move v0,zero
+ move v1,a1
+ .set noreorder
+1: lbu t0,(v1)
+ LONG_ADDIU v1,1
+ beqz t0,2f
+ sb t0,(a0) # delay slot
+ LONG_ADDIU v0,1
+ bne v0,a2,1b
+ LONG_ADDIU a0,1 # delay slot
+ .set reorder
+2: LONG_ADDU t0,a1,v0
+ xor t0,a1
+ bltz t0,fault
+ jr ra # return n
+ END(__strncpy_from_user)
+
+fault: li v0,-EFAULT
+ jr ra
+
+ .section __ex_table,"a"
+ PTR 1b,fault
+ .previous
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/tags.c linux/arch/mips/lib/tags.c
--- v2.1.43/linux/arch/mips/lib/tags.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/tags.c Thu Jun 26 12:33:37 1997
@@ -0,0 +1,75 @@
+/*
+ * linux/arch/mips/lib/tags.c
+ *
+ * Copyright (C) 1996 Stoned Elipot
+ */
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+/*
+ * Parse the tags present in upper memory to find out
+ * a pecular one.
+ *
+ * Parameter: type - tag type to find
+ *
+ * returns : NULL - failure
+ * !NULL - pointer on the tag structure found
+ */
+tag *
+bi_TagFind(enum bi_tag type)
+{
+ tag* t = (tag*)(mips_memory_upper - sizeof(tag));
+
+ while((t->tag != tag_dummy) && (t->tag != type))
+ t = (tag*)(NEXTTAGPTR(t));
+
+ if (t->tag == tag_dummy) /* tag not found */
+ return (tag*)NULL;
+
+ return t;
+}
+
+/*
+ * Snarf from the tag list in memory end some tags needed
+ * before the kernel reachs setup_arch()
+ *
+ * add yours here if you want to, but *beware*: the kernel var
+ * that will hold the values you want to snarf have to be
+ * in .data section of the kernel, so initialized in to whatever
+ * value in the kernel's sources.
+ */
+void bi_EarlySnarf(void)
+{
+ tag* atag;
+
+ /* for wire_mappings() */
+ atag = bi_TagFind(tag_machgroup);
+ if (atag)
+ memcpy(&mips_machgroup, TAGVALPTR(atag), atag->size);
+ else {
+ /* useless for boxes without text video mode but....*/
+ panic("machine group not specified by bootloader");
+ }
+
+ atag = bi_TagFind(tag_machtype);
+ if (atag)
+ memcpy(&mips_machtype, TAGVALPTR(atag), atag->size);
+ else {
+ /* useless for boxes without text video mode but....*/
+ panic("machine type not specified by bootloader");
+ }
+
+ /* for tlbflush() */
+ atag = bi_TagFind(tag_tlb_entries);
+ if (atag)
+ memcpy(&mips_tlb_entries, TAGVALPTR(atag), atag->size);
+ else {
+ /* useless for boxes without text video mode but....*/
+ panic("number of TLB entries not specified by bootloader");
+ }
+
+ return;
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/tinycon.c linux/arch/mips/lib/tinycon.c
--- v2.1.43/linux/arch/mips/lib/tinycon.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/tinycon.c Thu Jun 26 12:33:37 1997
@@ -0,0 +1,133 @@
+/*
+ * arch/mips/lib/console.c
+ *
+ * Copyright (C) 1994 by Waldorf Electronic,
+ * written by Ralf Baechle and Andreas Busse


+ *
+ * This file is subject to the terms and conditions of the GNU General Public

+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * FIXME: This file is hacked to be hardwired for the Deskstation
+ * Only thought as a debugging console output. It's as inefficient
+ * as a piece of code can be but probably a good piece of code to
+ * implement a preliminary console for a new target.
+ */
+
+#include <linux/tty.h>
+#include <asm/bootinfo.h>
+
+static unsigned int size_x;
+static unsigned int size_y;
+static unsigned short cursor_x;
+static unsigned short cursor_y;
+static volatile unsigned short *vram_addr;
+static int console_needs_init = 1;
+
+extern struct screen_info screen_info;
+
+/* ----------------------------------------------------------------------
+ * init_console()
+ * ---------------------------------------------------------------------- */
+
+void init_console(void)
+{
+ size_x = 80;
+ size_y = 25;
+ cursor_x = 0;
+ cursor_y = 0;
+
+ vram_addr = (unsigned short *)0xb00b8000;
+
+ console_needs_init = 0;
+}
+
+void
+set_size_x(unsigned int x)
+{
+ size_x = x;
+}
+
+void
+set_size_y(unsigned int y)
+{
+ size_y = y;
+}
+
+void
+set_vram(unsigned short *vram)
+{
+ vram_addr = vram;
+}
+
+void
+set_crsr(unsigned int x, unsigned int y)
+{
+ cursor_x = x;
+ cursor_y = y;
+}
+
+void
+print_char(unsigned int x, unsigned int y, unsigned char c)
+{
+ volatile unsigned short *caddr;
+
+ caddr = vram_addr + (y * size_x) + x;
+ *caddr = (*caddr & 0xff00) | 0x0f00 | (unsigned short) c;
+}
+
+static void
+scroll(void)
+{
+ volatile unsigned short *caddr;


+ register int i;
+

+ caddr = vram_addr;
+ for(i=0; i<size_x * (size_y-1); i++)
+ *(caddr++) = *(caddr + size_x);
+
+ /* blank last line */
+
+ caddr = vram_addr + (size_x * (size_y-1));
+ for(i=0; i<size_x; i++)
+ *(caddr++) = (*caddr & 0xff00) | (unsigned short) ' ';
+}
+
+void print_string(const unsigned char *str)
+{
+ unsigned char c;
+
+ if (console_needs_init)
+ init_console();
+
+ while((c = *str++))
+ switch(c)
+ {
+ case '\n':
+ cursor_x = 0;
+ cursor_y++;
+ if(cursor_y == size_y)
+ {
+ scroll();
+ cursor_y = size_y - 1;
+ }


+ break;
+
+ default:

+ print_char(cursor_x, cursor_y, c);
+ cursor_x++;
+ if(cursor_x == size_x)
+ {
+ cursor_x = 0;
+ cursor_y++;
+ if(cursor_y == size_y)
+ {
+ scroll();
+ cursor_y = size_y - 1;
+ }
+ }
+ break;
+ }
+}
+
+/* end of file */
diff -u --recursive --new-file v2.1.43/linux/arch/mips/lib/watch.S linux/arch/mips/lib/watch.S
--- v2.1.43/linux/arch/mips/lib/watch.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/lib/watch.S Thu Jun 26 12:33:37 1997
@@ -0,0 +1,125 @@
+/*
+ * Kernel debug stuff to use the Watch registers.
+ * Usefull to find stack overflows, dangeling pointers etc.


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.

+ *


+ * Copyright (C) 1995, 1996 by Ralf Baechle

+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+
+ .set noreorder
+/*
+ * Parameter: a0 - logic address to watch
+ * Currently only KSEG0 addresses are allowed!
+ * a1 - set bit #1 to trap on load references
+ * bit #0 to trap on store references
+ * Results : none
+ */
+ LEAF(__watch_set)
+ li t0,0x80000000
+ subu a0,t0
+ ori a0,7
+ xori a0,7
+ or a0,a1
+ mtc0 a0,CP0_WATCHLO
+ sw a0,watch_savelo
+
+ jr ra
+ mtc0 zero,CP0_WATCHHI
+ END(__watch_set)
+
+/*
+ * Parameter: none
+ * Results : none
+ */
+ LEAF(__watch_clear)
+ jr ra
+ mtc0 zero,CP0_WATCHLO
+ END(__watch_clear)
+
+/*
+ * Parameter: none
+ * Results : none
+ */
+ LEAF(__watch_reenable)
+ lw t0,watch_savelo
+
+ jr ra
+ mtc0 t0,CP0_WATCHLO
+ END(__watch_reenable)
+
+/*
+ * Saved value of the c0_watchlo register for watch_reenable()
+ */
+ .data
+watch_savelo: .word 0
+ .text
+
+/*
+ * The stuff below are just some kernel debugging gadgets. It is only here
+ * because it had to be somewhere and will go away.
+ */
+
+/*
+ * Parameter: none
+ * Results : none
+ */
+ LEAF(get_sp)
+ jr ra
+ move v0,sp
+ END(get_sp)
+
+/*
+ * Parameter: none
+ * Results : none
+ */
+ LEAF(get_ra)
+ jr ra
+ move v0,ra
+ END(get_ra)
+
+/*
+ * Parameter: none
+ * Results : none
+ */
+ LEAF(get_status)
+ jr ra
+ mfc0 v0,CP0_STATUS
+ END(get_status)
+
+/*
+ * Parameter: none
+ * Results : none
+ */
+ NESTED(print_sp, ((5*SZREG)+ALSZ)&ALMASK, sp)
+ .mask 0x80000000,4*SZREG
+ PTR_SUBU sp,((5*SZREG)+ALSZ)&ALMASK
+ REG_S ra,4*SZREG(sp)
+ move a1,sp
+ PRINT("$sp == %08lx\n")
+ REG_L ra,4*SZREG(sp)
+
+ jr ra
+ PTR_ADDU sp,((5*SZREG)+ALSZ)&ALMASK
+ END(print_sp)
+
+/*
+ * Parameter: none
+ * Results : none
+ */
+ NESTED(print_st, ((5*SZREG)+ALSZ)&ALMASK, sp)
+ .mask 0x80000000,4*SZREG
+ PTR_SUBU sp,((5*SZREG)+ALSZ)&ALMASK
+ REG_S ra,4*SZREG(sp)
+ mfc0 a1,CP0_STATUS
+ PRINT("cp0_status == %08lx\n")
+ REG_L ra,4*SZREG(sp)
+
+ jr ra
+ PTR_ADDU sp,((5*SZREG)+ALSZ)&ALMASK
+ END(print_st)
diff -u --recursive --new-file v2.1.43/linux/arch/mips/mm/Makefile linux/arch/mips/mm/Makefile
--- v2.1.43/linux/arch/mips/mm/Makefile Wed Dec 13 02:39:44 1995
+++ linux/arch/mips/mm/Makefile Thu Jun 26 12:33:37 1997
@@ -8,6 +8,7 @@
X # Note 2! The CFLAGS definition is now in the main makefile...
X
X O_TARGET := mm.o
-O_OBJS := fault.o init.o
+O_OBJS := extable.o init.o fault.o r4xx0.o r2300.o r6000.o tfp.o \
+ andes.o loadmmu.o
X
X include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.43/linux/arch/mips/mm/andes.c linux/arch/mips/mm/andes.c
--- v2.1.43/linux/arch/mips/mm/andes.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/mm/andes.c Thu Jun 26 12:33:37 1997
@@ -0,0 +1,101 @@
+/* $Id: andes.c,v 1.1 1997/06/06 09:34:31 ralf Exp $
+ * andes.c: MMU and cache operations for the R10000 (ANDES).
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/sgialib.h>
+
+extern unsigned long mips_tlb_entries;
+
+/* Cache operations. XXX Write these dave... */
+static inline void andes_flush_cache_all(void)
+{
+ /* XXX */
+}
+
+static void andes_flush_cache_mm(struct mm_struct *mm)
+{
+ /* XXX */
+}
+
+static void andes_flush_cache_range(struct mm_struct *mm,
+ unsigned long start,
+ unsigned long end)
+{
+ /* XXX */
+}
+
+static void andes_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long page)
+{
+ /* XXX */
+}
+
+static void andes_flush_page_to_ram(unsigned long page)
+{
+ /* XXX */
+}
+
+static void andes_flush_cache_sigtramp(unsigned long page)
+{
+ /* XXX */
+}
+
+/* TLB operations. XXX Write these dave... */
+static inline void andes_flush_tlb_all(void)
+{
+ /* XXX */
+}
+
+static void andes_flush_tlb_mm(struct mm_struct *mm)
+{
+ /* XXX */
+}
+
+static void andes_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end)
+{
+ /* XXX */
+}
+
+static void andes_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+ /* XXX */
+}
+
+static void andes_load_pgd(unsigned long pg_dir)
+{
+}
+
+static void andes_pgd_init(unsigned long page)
+{
+}
+
+void ld_mmu_andes(void)
+{
+ flush_cache_all = andes_flush_cache_all;
+ flush_cache_mm = andes_flush_cache_mm;
+ flush_cache_range = andes_flush_cache_range;
+ flush_cache_page = andes_flush_cache_page;
+ flush_cache_sigtramp = andes_flush_cache_sigtramp;
+ flush_page_to_ram = andes_flush_page_to_ram;
+
+ flush_tlb_all = andes_flush_tlb_all;
+ flush_tlb_mm = andes_flush_tlb_mm;
+ flush_tlb_range = andes_flush_tlb_range;
+ flush_tlb_page = andes_flush_tlb_page;
+
+ load_pgd = andes_load_pgd;
+ pgd_init = andes_pgd_init;
+
+ flush_cache_all();
+ flush_tlb_all();
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/mm/extable.c linux/arch/mips/mm/extable.c
--- v2.1.43/linux/arch/mips/mm/extable.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/mm/extable.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,54 @@
+/*
+ * linux/arch/mips/mm/extable.c
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
+
+static inline unsigned
+search_one_table(const struct exception_table_entry *first,
+ const struct exception_table_entry *last,
+ unsigned long value)
+{
+ while (first <= last) {
+ const struct exception_table_entry *mid;
+ long diff;
+
+ mid = (last - first) / 2 + first;
+ diff = mid->insn - value;
+ if (diff == 0)
+ return mid->nextinsn;
+ else if (diff < 0)


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 14'
echo 'File patch-2.1.44 is continued in part 15'
echo 15 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part23

#!/bin/sh
# this is part 23 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 23; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

+ /* Ho hum, the slightly complicated case. */
+ win = (struct reg_window *) regs->u_regs[UREG_FP];
+ return win->locals[reg - 16]; /* yes, I know what this does... */
+}
+
+static inline unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs)
+{
+ struct reg_window *win;
+
+ if(reg < 16)
+ return &regs->u_regs[reg];
+ win = (struct reg_window *) regs->u_regs[UREG_FP];
+ return &win->locals[reg - 16];
+}
+
+static inline unsigned long compute_effective_address(struct pt_regs *regs,
+ unsigned int insn)
+{
+ unsigned int rs1 = (insn >> 14) & 0x1f;
+ unsigned int rs2 = insn & 0x1f;
+ unsigned int rd = (insn >> 25) & 0x1f;
+
+ if(insn & 0x2000) {
+ maybe_flush_windows(rs1, 0, rd);
+ return (fetch_reg(rs1, regs) + sign_extend_imm13(insn));
+ } else {
+ maybe_flush_windows(rs1, rs2, rd);
+ return (fetch_reg(rs1, regs) + fetch_reg(rs2, regs));
+ }
+}
+
+/* This is just to make gcc think panic does return... */
+static void unaligned_panic(char *str)
+{
+ panic(str);
+}
+
+#define do_integer_load(dest_reg, size, saddr, is_signed, asi, errh) ({ \
+__asm__ __volatile__ ( \
+ "wr %4, 0, %%asi\n\t" \
+ "cmp %1, 8\n\t" \
+ "bge,pn %%icc, 9f\n\t" \
+ " cmp %1, 4\n\t" \
+ "be,pt %%icc, 6f\n" \
+"4:\t" " lduba [%2] %%asi, %%l1\n" \
+"5:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \
+ "sll %%l1, 8, %%l1\n\t" \
+ "brz,pt %3, 3f\n\t" \
+ " add %%l1, %%l2, %%l1\n\t" \
+ "sllx %%l1, 48, %%l1\n\t" \
+ "srax %%l1, 48, %%l1\n" \
+"3:\t" "ba,pt %%xcc, 0f\n\t" \
+ " stx %%l1, [%0]\n" \
+"6:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \
+ "sll %%l1, 24, %%l1\n" \
+"7:\t" "lduba [%2 + 2] %%asi, %%g7\n\t" \
+ "sll %%l2, 16, %%l2\n" \
+"8:\t" "lduba [%2 + 3] %%asi, %%g1\n\t" \
+ "sll %%g7, 8, %%g7\n\t" \
+ "or %%l1, %%l2, %%l1\n\t" \
+ "or %%g7, %%g1, %%g7\n\t" \
+ "or %%l1, %%g7, %%l1\n\t" \
+ "brnz,a,pt %3, 3f\n\t" \
+ " sra %%l1, 0, %%l1\n" \
+"3:\t" "ba,pt %%xcc, 0f\n\t" \
+ " stx %%l1, [%0]\n" \
+"9:\t" "lduba [%2] %%asi, %%l1\n" \
+"10:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \
+ "sllx %%l1, 56, %%l1\n" \
+"11:\t" "lduba [%2 + 2] %%asi, %%g7\n\t" \
+ "sllx %%l2, 48, %%l2\n" \
+"12:\t" "lduba [%2 + 3] %%asi, %%g1\n\t" \
+ "sllx %%g7, 40, %%g7\n\t" \
+ "sllx %%g1, 32, %%g1\n\t" \
+ "or %%l1, %%l2, %%l1\n\t" \
+ "or %%g7, %%g1, %%g7\n" \
+"13:\t" "lduba [%2 + 4] %%asi, %%l2\n\t" \
+ "or %%l1, %%g7, %%g7\n" \
+"14:\t" "lduba [%2 + 5] %%asi, %%g1\n\t" \
+ "sllx %%l2, 24, %%l2\n" \
+"15:\t" "lduba [%2 + 6] %%asi, %%l1\n\t" \
+ "sllx %%g1, 16, %%g1\n\t" \
+ "or %%g7, %%l2, %%g7\n" \
+"16:\t" "lduba [%2 + 7] %%asi, %%l2\n\t" \
+ "sllx %%l1, 8, %%l1\n\t" \
+ "or %%g7, %%g1, %%g7\n\t" \
+ "or %%l1, %%l2, %%l1\n\t" \
+ "or %%g7, %%l1, %%g7\n\t" \
+ "cmp %1, 8\n\t" \
+ "be,a,pt %%icc, 0f\n\t" \
+ " stx %%g7, [%0]\n\t" \
+ "srlx %%g7, 32, %%l1\n\t" \
+ "sra %%g7, 0, %%g7\n\t" \
+ "stx %%l1, [%0]\n\t" \
+ "stx %%g7, [%0 + 8]\n" \
+"0:\n\n\t" \
+ ".section __ex_table\n\t" \
+ ".xword 4b, " #errh "\n\t" \
+ ".xword 5b, " #errh "\n\t" \
+ ".xword 6b, " #errh "\n\t" \
+ ".xword 7b, " #errh "\n\t" \
+ ".xword 8b, " #errh "\n\t" \
+ ".xword 9b, " #errh "\n\t" \
+ ".xword 10b, " #errh "\n\t" \
+ ".xword 11b, " #errh "\n\t" \
+ ".xword 12b, " #errh "\n\t" \
+ ".xword 13b, " #errh "\n\t" \
+ ".xword 14b, " #errh "\n\t" \
+ ".xword 15b, " #errh "\n\t" \
+ ".xword 16b, " #errh "\n\n\t" \
+ ".previous\n\t" \
+ : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed), "r" (asi) \
+ : "l1", "l2", "g7", "g1", "cc"); \
+})
+
+#define store_common(dst_addr, size, src_val, asi, errh) ({ \
+__asm__ __volatile__ ( \
+ "wr %3, 0, %%asi\n\t" \
+ "ldx [%2], %%l1\n" \
+ "cmp %1, 2\n\t" \
+ "be,pn %%icc, 2f\n\t" \
+ " cmp %1, 4\n\t" \
+ "be,pt %%icc, 1f\n\t" \
+ " srlx %%l1, 24, %%l2\n\t" \
+ "srlx %%l1, 56, %%g1\n\t" \
+ "srlx %%l1, 48, %%g7\n" \
+"4:\t" "stba %%g1, [%0] %%asi\n\t" \
+ "srlx %%l1, 40, %%g1\n" \
+"5:\t" "stba %%g7, [%0 + 1] %%asi\n\t" \
+ "srlx %%l1, 32, %%g7\n" \
+"6:\t" "stba %%g1, [%0 + 2] %%asi\n" \
+"7:\t" "stba %%g7, [%0 + 3] %%asi\n\t" \
+ "srlx %%l1, 16, %%g1\n" \
+"8:\t" "stba %%l2, [%0 + 4] %%asi\n\t" \
+ "srlx %%l1, 8, %%g7\n" \
+"9:\t" "stba %%g1, [%0 + 5] %%asi\n" \
+"10:\t" "stba %%g7, [%0 + 6] %%asi\n\t" \
+ "ba,pt %%xcc, 0f\n" \
+"11:\t" " stba %%l1, [%0 + 7] %%asi\n" \
+"1:\t" "srl %%l1, 16, %%g7\n" \
+"12:\t" "stba %%l2, [%0] %%asi\n\t" \
+ "srl %%l1, 8, %%l2\n" \
+"13:\t" "stba %%g7, [%0 + 1] %%asi\n" \
+"14:\t" "stba %%l2, [%0 + 2] %%asi\n\t" \
+ "ba,pt %%xcc, 0f\n" \
+"15:\t" " stba %%l1, [%0 + 3] %%asi\n" \
+"2:\t" "srl %%l1, 8, %%l2\n" \
+"16:\t" "stba %%l2, [%0] %%asi\n" \
+"17:\t" "stba %%l1, [%0 + 1] %%asi\n" \
+"0:\n\n\t" \
+ ".section __ex_table\n\t" \
+ ".xword 4b, " #errh "\n\t" \
+ ".xword 5b, " #errh "\n\t" \
+ ".xword 6b, " #errh "\n\t" \
+ ".xword 7b, " #errh "\n\t" \
+ ".xword 8b, " #errh "\n\t" \
+ ".xword 9b, " #errh "\n\t" \
+ ".xword 10b, " #errh "\n\t" \
+ ".xword 11b, " #errh "\n\t" \
+ ".xword 12b, " #errh "\n\t" \
+ ".xword 13b, " #errh "\n\t" \
+ ".xword 14b, " #errh "\n\t" \
+ ".xword 15b, " #errh "\n\t" \
+ ".xword 16b, " #errh "\n\t" \
+ ".xword 17b, " #errh "\n\n\t" \
+ ".previous\n\t" \
+ : : "r" (dst_addr), "r" (size), "r" (src_val), "r" (asi) \
+ : "l1", "l2", "g7", "g1", "cc"); \
+})
+
+#define do_integer_store(reg_num, size, dst_addr, regs, asi, errh) ({ \
+ unsigned long zero = 0; \
+ unsigned long *src_val = &zero; \
+ \
+ if (size == 16) { \
+ size = 8; \
+ zero = (((long)(reg_num ? \
+ (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) | \
+ (unsigned)fetch_reg(reg_num + 1, regs); \
+ } else if (reg_num) src_val = fetch_reg_addr(reg_num, regs); \
+ store_common(dst_addr, size, src_val, asi, errh); \
+})
+
+/* XXX Need to capture/release other cpu's for SMP around this. */
+#define do_atomic(srcdest_reg, mem, errh) ({ \
+ unsigned long flags, tmp; \
+ \
+ save_and_cli(flags); \
+ tmp = *srcdest_reg; \
+ do_integer_load(srcdest_reg, 4, mem, 0, errh); \
+ store_common(mem, 4, &tmp, errh); \
+ restore_flags(flags); \
+})
+
+static inline void advance(struct pt_regs *regs)
+{
+ regs->tpc = regs->tnpc;
+ regs->tnpc += 4;
+}
+
+static inline int floating_point_load_or_store_p(unsigned int insn)
+{
+ return (insn >> 24) & 1;
+}
+
+static inline int ok_for_kernel(unsigned int insn)
+{
+ return !floating_point_load_or_store_p(insn);
+}
+
+void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault");
+
+void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+{
+ unsigned long g2 = regs->u_regs [UREG_G2];
+ unsigned long fixup = search_exception_table (regs->tpc, &g2);
+
+ if (!fixup) {
+ unsigned long address = compute_effective_address(regs, insn);
+ if(address < PAGE_SIZE) {
+ printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference in mna handler");
+ } else
+ printk(KERN_ALERT "Unable to handle kernel paging request in mna handler");
+ printk(KERN_ALERT " at virtual address %016lx\n",address);
+ printk(KERN_ALERT "current->mm->context = %016lx\n",
+ (unsigned long) current->mm->context);
+ printk(KERN_ALERT "current->mm->pgd = %016lx\n",
+ (unsigned long) current->mm->pgd);
+ die_if_kernel("Oops", regs);
+ /* Not reached */
+ }
+ regs->tpc = fixup;
+ regs->tnpc = regs->tpc + 4;
+ regs->u_regs [UREG_G2] = g2;
+}
+
+asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
+{
+ enum direction dir = decode_direction(insn);
+ int size = decode_access_size(insn);
+
+ lock_kernel();
+ if(!ok_for_kernel(insn) || dir == both) {
+ printk("Unsupported unaligned load/store trap for kernel at <%016lx>.\n",
+ regs->tpc);
+ unaligned_panic("Wheee. Kernel does fpu/atomic unaligned load/store.");
+
+ __asm__ __volatile__ ("\n"
+"kernel_unaligned_trap_fault:\n\t"
+ "mov %0, %%o0\n\t"
+ "call kernel_mna_trap_fault\n\t"
+ " mov %1, %%o1\n\t"
+ :
+ : "r" (regs), "r" (insn)
+ : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
+ "g1", "g2", "g3", "g4", "g5", "g7", "cc");
+ } else {
+ unsigned long addr = compute_effective_address(regs, insn);
+
+#ifdef DEBUG_MNA
+ printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] retpc[%016lx]\n",
+ regs->tpc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]);
+#endif
+ switch(dir) {
+ case load:
+ do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
+ size, (unsigned long *) addr,
+ decode_signedness(insn), decode_asi(insn, regs),
+ kernel_unaligned_trap_fault);
+ break;
+
+ case store:
+ do_integer_store(((insn>>25)&0x1f), size,
+ (unsigned long *) addr, regs,
+ decode_asi(insn, regs),
+ kernel_unaligned_trap_fault);
+ break;
+#if 0 /* unsupported */
+ case both:
+ do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
+ (unsigned long *) addr,
+ kernel_unaligned_trap_fault);
+ break;
+#endif
+ default:
+ panic("Impossible kernel unaligned trap.");
+ /* Not reached... */
+ }
+ advance(regs);
+ }
+ unlock_kernel();
+}
+
+#if 0 /* XXX: Implement user mna some day */
+static inline int ok_for_user(struct pt_regs *regs, unsigned int insn,
+ enum direction dir)
+{
+ unsigned int reg;
+ int retval, check = (dir == load) ? VERIFY_READ : VERIFY_WRITE;
+ int size = ((insn >> 19) & 3) == 3 ? 8 : 4;
+
+ if((regs->pc | regs->npc) & 3)
+ return 0;
+
+ /* Must verify_area() in all the necessary places. */
+#define WINREG_ADDR(regnum) ((void *)(((unsigned long *)regs->u_regs[UREG_FP])+(regnum)))
+ retval = 0;
+ reg = (insn >> 25) & 0x1f;
+ if(reg >= 16) {
+ retval = verify_area(check, WINREG_ADDR(reg - 16), size);
+ if(retval)
+ return retval;
+ }
+ reg = (insn >> 14) & 0x1f;
+ if(reg >= 16) {
+ retval = verify_area(check, WINREG_ADDR(reg - 16), size);
+ if(retval)
+ return retval;
+ }
+ if(!(insn & 0x2000)) {
+ reg = (insn & 0x1f);
+ if(reg >= 16) {
+ retval = verify_area(check, WINREG_ADDR(reg - 16), size);
+ if(retval)


+ return retval;
+ }
+ }

+ return retval;
+#undef WINREG_ADDR
+}
+
+void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("user_mna_trap_fault");
+
+void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+{
+ current->tss.sig_address = regs->pc;
+ current->tss.sig_desc = SUBSIG_PRIVINST;


+ send_sig(SIGBUS, current, 1);
+}

+
+asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
+{
+ enum direction dir;
+
+ lock_kernel();
+ if(!(current->tss.flags & SPARC_FLAG_UNALIGNED) ||
+ (((insn >> 30) & 3) != 3))
+ goto kill_user;
+ dir = decode_direction(insn);
+ if(!ok_for_user(regs, insn, dir)) {
+ goto kill_user;
+ } else {
+ int size = decode_access_size(insn);
+ unsigned long addr;
+
+ if(floating_point_load_or_store_p(insn)) {
+ printk("User FPU load/store unaligned unsupported.\n");
+ goto kill_user;
+ }
+
+ addr = compute_effective_address(regs, insn);
+ switch(dir) {
+ case load:
+ do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
+ size, (unsigned long *) addr,
+ decode_signedness(insn),
+ user_unaligned_trap_fault);
+ break;
+
+ case store:
+ do_integer_store(((insn>>25)&0x1f), size,
+ (unsigned long *) addr, regs,
+ user_unaligned_trap_fault);
+ break;
+
+ case both:
+ do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
+ (unsigned long *) addr,
+ user_unaligned_trap_fault);


+ break;
+
+ default:

+ unaligned_panic("Impossible user unaligned trap.");
+
+ __asm__ __volatile__ ("\n"
+"user_unaligned_trap_fault:\n\t"
+ "mov %0, %%o0\n\t"
+ "call user_mna_trap_fault\n\t"
+ " mov %1, %%o1\n\t"
+ :
+ : "r" (regs), "r" (insn)
+ : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
+ "g1", "g2", "g3", "g4", "g5", "g7", "cc");
+ goto out;
+ }
+ advance(regs);


+ goto out;
+ }
+

+kill_user:
+ current->tss.sig_address = regs->pc;
+ current->tss.sig_desc = SUBSIG_PRIVINST;
+ send_sig(SIGBUS, current, 1);
+out:
+ unlock_kernel();
+}
+#endif
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/winfixup.S linux/arch/sparc64/kernel/winfixup.S
--- v2.1.43/linux/arch/sparc64/kernel/winfixup.S Mon Jun 16 16:35:54 1997
+++ linux/arch/sparc64/kernel/winfixup.S Mon Jul 7 08:18:54 1997
@@ -1,4 +1,4 @@
-/* $Id: winfixup.S,v 1.8 1997/06/02 06:33:35 davem Exp $
+/* $Id: winfixup.S,v 1.15 1997/07/04 01:41:07 davem Exp $
X *
X * winfixup.S: Handle cases where user stack pointer is found to be bogus.
X *
@@ -31,6 +31,7 @@
X fill_fixup:
X rdpr %tstate, %g1
X andcc %g1, TSTATE_PRIV, %g0
+ clr %g4
X be,pt %xcc, window_scheisse_from_user_common
X and %g1, TSTATE_CWP, %g1
X
@@ -53,25 +54,26 @@
X rdpr %wstate, %g2 ! Grab user mode wstate.
X wrpr %g1, %cwp ! Get into the right window.
X sll %g2, 3, %g2 ! NORMAL-->OTHER
- wrpr %g0, 0x0, %canrestore ! Standard etrap stuff.
X
+ wrpr %g0, 0x0, %canrestore ! Standard etrap stuff.
+ wr %g0, 0x0, %fprs ! zap FPU just in case...
X wrpr %g2, 0x0, %wstate ! This must be consistant.
X wrpr %g0, 0x0, %otherwin ! We know this.
- sethi %uhi(KERNBASE), %g2 ! Set this up
- sllx %g2, 32, %g2 ! for the iflush
X mov PRIMARY_CONTEXT, %g1 ! Change contexts...
X stxa %g0, [%g1] ASI_DMMU ! Back into the nucleus.
- flush %g2 ! Flush instruction buffers
+ flush %g6 ! Flush instruction buffers
X rdpr %pstate, %l1 ! Prepare to change globals.
- mov %g4, %o5 ! Setup args for
- mov %g5, %o4 ! final call to do_sparc64_fault.
X
+ mov %g6, %o7 ! Get current.
+ mov %g5, %l5 ! Fault address
+ clr %l4 ! It was a load, not a store
X wrpr %g0, 0x0, %tl ! Out of trap levels.
X wrpr %l1, (PSTATE_IE | PSTATE_AG), %pstate
- sethi %uhi(KERNBASE), %g4 ! Restore med-any global reg.
- rd %pic, %g6 ! Get current as well.
+ sethi %uhi(PAGE_OFFSET), %g4 ! Prepare page_offset global reg
+ mov %o7, %g6
X b,pt %xcc, window_scheisse_merge ! And merge.
- sllx %g4, 32, %g4 ! Finish med-any reg setup.
+
+ sllx %g4, 32, %g4 ! and finish it...
X
X /* Be very careful about usage of the alternate globals here.
X * You cannot touch %g4/%g5 as that has the fault information
@@ -82,17 +84,16 @@
X * do not touch %g7 or %g2 so we handle the two cases fine.
X */
X spill_fixup:
- rd %pic, %g1
- ldx [%g1 + AOFF_task_tss + AOFF_thread_flags], %g6
- andcc %g6, SPARC_FLAG_32BIT, %g0
- ldx [%g1 + AOFF_task_tss + AOFF_thread_w_saved], %g6
- sll %g6, 3, %g3
- add %g1, %g3, %g3
+ ld [%g6 + AOFF_task_tss + AOFF_thread_flags], %g1
+ andcc %g1, SPARC_FLAG_32BIT, %g0
+ ldx [%g6 + AOFF_task_tss + AOFF_thread_w_saved], %g1
+ sll %g1, 3, %g3
+ add %g6, %g3, %g3
X stx %sp, [%g3 + AOFF_task_tss + AOFF_thread_rwbuf_stkptrs]
- sll %g6, 7, %g3
+ sll %g1, 7, %g3
X
X bne,pt %xcc, 1f
- add %g1, %g3, %g3
+ add %g6, %g3, %g3
X stx %l0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x00]
X stx %l1, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x08]
X stx %l2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x10]
@@ -110,43 +111,45 @@
X stx %i5, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x68]
X
X stx %i6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x70]
- stx %i7, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x78]
X b,pt %xcc, 2f
- add %g6, 1, %g6
-1: std %l0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x00]
- std %l2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x08]
- std %l4, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x10]
- std %l6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x18]
-
- std %i0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x20]
- std %i2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x28]
- std %i4, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x30]
- std %i6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x38]
- add %g6, 1, %g6
-2: stx %g6, [%g1 + AOFF_task_tss + AOFF_thread_w_saved]
+ stx %i7, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x78]
+1: stw %l0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x00]
+ stw %l1, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x04]
+ stw %l2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x08]
+ stw %l3, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x0c]
+ stw %l4, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x10]
+
+ stw %l5, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x14]
+ stw %l6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x18]
+ stw %l7, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x1c]
+ stw %i0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x20]
+ stw %i1, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x24]
+ stw %i2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x28]
+ stw %i3, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x2c]
+ stw %i4, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x30]
+
+ stw %i5, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x34]
+ stw %i6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x38]
+ stw %i7, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x3c]
+2: add %g1, 1, %g1
+ stx %g1, [%g6 + AOFF_task_tss + AOFF_thread_w_saved]
X rdpr %tstate, %g1
- nop
-
X andcc %g1, TSTATE_PRIV, %g0
X saved
+
X and %g1, TSTATE_CWP, %g1
X be,a,pn %xcc, window_scheisse_from_user_common
X or %g4, 0x4, %g4 ! we know it was a write
X retry
X window_scheisse_from_user_common:
- nop
X wrpr %g1, %cwp
-
X ba,pt %xcc, etrap
X rd %pc, %g7
- mov %l5, %o4
- mov %l4, %o5
X window_scheisse_merge:
- srlx %o4, PAGE_SHIFT, %o3
- clr %o1
- sllx %o3, PAGE_SHIFT, %o3
- and %o5, 0x4, %o2
+ srlx %l5, PAGE_SHIFT, %o1
X
+ and %l4, 0x4, %o2
+ sllx %o1, PAGE_SHIFT, %o1
X call do_sparc64_fault
X add %sp, STACK_BIAS + REGWIN_SZ, %o0
X ba,pt %xcc, rtrap
@@ -154,6 +157,7 @@
X winfix_trampoline:
X andn %g3, 0x7f, %g3
X add %g3, 0x7c, %g3
+
X wrpr %g3, %tnpc
X done
X
@@ -174,32 +178,31 @@
X wrpr %g0, 0x0, %canrestore ! Standard etrap stuff.
X wrpr %g2, 0x0, %wstate ! This must be consistant.
X wrpr %g0, 0x0, %otherwin ! We know this.
- sethi %uhi(KERNBASE), %g2 ! Set this up
- sllx %g2, 32, %g2 ! for the iflush
X mov PRIMARY_CONTEXT, %g1 ! Change contexts...
X stxa %g0, [%g1] ASI_DMMU ! Back into the nucleus.
- flush %g2 ! Flush instruction buffers
+ flush %g6 ! Flush instruction buffers
X rdpr %pstate, %l1 ! Prepare to change globals.
X mov %g4, %o5 ! Setup args for
X mov %g5, %o4 ! final call to do_sparc64_fault.
+ mov %g6, %o7 ! Stash away current.
X wrpr %g0, 0x0, %tl ! Out of trap levels.
X wrpr %l1, (PSTATE_IE | PSTATE_AG), %pstate
- sethi %uhi(KERNBASE), %g4 ! Restore med-any global reg.
- rd %pic, %g6 ! Get current as well.
+ sethi %uhi(PAGE_OFFSET), %g4 ! Set page_offset global reg.
+ mov %o7, %g6 ! Get current back.
X b,pt %xcc, window_mna_merge ! And merge.
- sllx %g4, 32, %g4 ! Finish med-any reg setup.
+ sllx %g4, 32, %g4 ! Finish it.
+
X spill_fixup_mna:
- rd %pic, %g1
- ldx [%g1 + AOFF_task_tss + AOFF_thread_flags], %g6
- andcc %g6, SPARC_FLAG_32BIT, %g0
- ldx [%g1 + AOFF_task_tss + AOFF_thread_w_saved], %g6
- sll %g6, 3, %g3
- add %g1, %g3, %g3
+ ld [%g6 + AOFF_task_tss + AOFF_thread_flags], %g1
+ andcc %g1, SPARC_FLAG_32BIT, %g0
+ ldx [%g6 + AOFF_task_tss + AOFF_thread_w_saved], %g1
+ sll %g1, 3, %g3
+ add %g6, %g3, %g3
X stx %sp, [%g3 + AOFF_task_tss + AOFF_thread_rwbuf_stkptrs]
- sll %g6, 7, %g3
+ sll %g1, 7, %g3
X
X bne,pt %xcc, 1f
- add %g1, %g3, %g3
+ add %g6, %g3, %g3
X stx %l0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x00]
X stx %l1, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x08]
X stx %l2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x10]
@@ -219,7 +222,7 @@
X stx %i6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x70]
X stx %i7, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x78]
X b,pt %xcc, 2f
- add %g6, 1, %g6
+ add %g1, 1, %g1
X 1: std %l0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x00]
X std %l2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x08]
X std %l4, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x10]
@@ -229,8 +232,8 @@
X std %i2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x28]
X std %i4, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x30]
X std %i6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x38]
- add %g6, 1, %g6
-2: stx %g6, [%g1 + AOFF_task_tss + AOFF_thread_w_saved]
+ add %g1, 1, %g1
+2: stx %g1, [%g6 + AOFF_task_tss + AOFF_thread_w_saved]
X rdpr %tstate, %g1
X nop
X
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/lib/Makefile linux/arch/sparc64/lib/Makefile
--- v2.1.43/linux/arch/sparc64/lib/Makefile Mon Apr 14 16:28:10 1997
+++ linux/arch/sparc64/lib/Makefile Mon Jul 7 08:18:55 1997
@@ -1,55 +1,25 @@
-# $Id: Makefile,v 1.7 1997/04/07 18:57:05 jj Exp $
+# $Id: Makefile,v 1.12 1997/06/25 10:12:18 jj Exp $
X # Makefile for Sparc library files..
X #
X
X CFLAGS := $(CFLAGS) -ansi
X
-OBJS = memset.o blockops.o locks.o memcpy.o strlen.o strncmp.o \
+OBJS = blockops.o locks.o strlen.o strncmp.o \
X memscan.o strncpy_from_user.o strlen_user.o memcmp.o checksum.o \
- copy_to_user.o copy_from_user.o
+ VIScopy.o VISbzero.o VISmemset.o
X
X lib.a: $(OBJS)
X $(AR) rcs lib.a $(OBJS)
X sync
X
-blockops.o: blockops.S
- $(CC) -ansi -c -o blockops.o blockops.S
+VIScopy.o: VIScopy.S VIS.h
+VISbzero.o: VISbzero.S VIS.h
X
-memset.o: memset.S
- $(CC) -D__ASSEMBLY__ -ansi -c -o memset.o memset.S
+.S.s:
+ $(CPP) -D__ASSEMBLY__ -ansi $< -o $*.s
X
-copy_to_user.o: copy_to_user.S
- $(CC) -D__ASSEMBLY__ -ansi -c -o copy_to_user.o copy_to_user.S
-
-copy_from_user.o: copy_from_user.S
- $(CC) -D__ASSEMBLY__ -ansi -c -o copy_from_user.o copy_from_user.S
-
-memcpy.o: memcpy.S
- $(CC) -D__ASSEMBLY__ -ansi -c -o memcpy.o memcpy.S
-
-strlen.o: strlen.S
- $(CC) -D__ASSEMBLY__ -ansi -c -o strlen.o strlen.S
-
-strncmp.o: strncmp.S
- $(CC) -D__ASSEMBLY__ -ansi -c -o strncmp.o strncmp.S
-
-memcmp.o: memcmp.S
- $(CC) -D__ASSEMBLY__ -ansi -c -o memcmp.o memcmp.S
-
-locks.o: locks.S
- $(CC) -D__ASSEMBLY__ -ansi -c -o locks.o locks.S
-
-checksum.o: checksum.S
- $(CC) -D__ASSEMBLY__ -ansi -c -o checksum.o checksum.S
-
-memscan.o: memscan.S
- $(CC) -D__ASSEMBLY__ -ansi -c -o memscan.o memscan.S
-
-strncpy_from_user.o: strncpy_from_user.S
- $(CC) -D__ASSEMBLY__ -ansi -c -o strncpy_from_user.o strncpy_from_user.S
-
-strlen_user.o: strlen_user.S
- $(CC) -D__ASSEMBLY__ -ansi -c -o strlen_user.o strlen_user.S
+.S.o:
+ $(CC) -D__ASSEMBLY__ -ansi -c $< -o $*.o
X
X dep:
X
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/lib/VIS.h linux/arch/sparc64/lib/VIS.h
--- v2.1.43/linux/arch/sparc64/lib/VIS.h Wed Dec 31 16:00:00 1969
+++ linux/arch/sparc64/lib/VIS.h Mon Jul 7 08:18:55 1997
@@ -0,0 +1,113 @@
+/* $Id: VIS.h,v 1.3 1997/06/27 14:53:18 jj Exp $
+ * VIS.h: High speed copy/clear operations utilizing the UltraSparc
+ * Visual Instruction Set.
+ *
+ * Copyright (C) 1997 David S. Miller (da...@caip.rutgers.edu)
+ * Copyright (C) 1996, 1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
+ */
+
+ /* VIS code can be used for numerous copy/set operation variants.
+ * It can be made to work in the kernel, one single instance,
+ * for all of memcpy, copy_to_user, and copy_from_user by setting
+ * the ASI src/dest globals correctly. Furthermore it can
+ * be used for kernel-->kernel page copies as well, a hook label
+ * is put in here just for this purpose.
+ *
+ * For userland, compiling this without __KERNEL__ defined makes
+ * it work just fine as a generic libc bcopy and memcpy.
+ * If for userland it is compiled with a 32bit gcc (but you need
+ * -Wa,-Av9a), the code will just rely on lower 32bits of
+ * IEU registers, if you compile it with 64bit gcc (ie. define
+ * __sparc_v9__), the code will use full 64bit.
+ */
+
+#ifndef __VIS_H
+#define __VIS_H
+
+#ifdef __KERNEL__
+#include <asm/head.h>
+#include <asm/asi.h>
+#else
+#define ASI_P 0x80 /* Primary, implicit */
+#define ASI_S 0x81 /* Secondary, implicit */
+#define ASI_BLK_COMMIT_P 0xe0 /* Primary, blk store commit */
+#define ASI_BLK_COMMIT_S 0xe1 /* Secondary, blk store commit */
+#define ASI_BLK_P 0xf0 /* Primary, blk ld/st */
+#define ASI_BLK_S 0xf1 /* Secondary, blk ld/st */
+#define FPRS_FEF 0x04
+#endif
+
+ /* I'm telling you, they really did this chip right.
+ * Perhaps the SunSoft folks should visit some of the
+ * people in Sun Microelectronics and start some brain
+ * cell exchange program...
+ */
+#define ASI_BLK_XOR (ASI_P ^ ASI_BLK_P)
+
+#define asi_src %o3
+#define asi_dest %o4
+
+#ifdef __KERNEL__
+#define ASI_SETSRC_BLK wr asi_src, 0, %asi;
+#define ASI_SETSRC_NOBLK wr asi_src, ASI_BLK_XOR, %asi;
+#define ASI_SETDST_BLK wr asi_dest, 0, %asi;
+#define ASI_SETDST_NOBLK wr asi_dest, ASI_BLK_XOR, %asi;
+#define ASIBLK %asi
+#define ASINORMAL %asi
+#define LDUB lduba
+#define LDUH lduha
+#define LDUW lduwa
+#define LDX ldxa
+#define LDD ldda
+#define LDDF ldda
+#define LDBLK ldda
+#define STB stba
+#define STH stha
+#define STW stwa
+#define STD stda
+#define STX stxa
+#define STDF stda
+#define STBLK stda
+#else
+#define ASI_SETSRC_BLK
+#define ASI_SETSRC_NOBLK
+#define ASI_SETDST_BLK
+#define ASI_SETDST_NOBLK
+#define ASI_SETDST_SPECIAL
+#define ASIBLK %asi
+#define ASINORMAL
+#define LDUB ldub
+#define LDUH lduh
+#define LDUW lduw
+#define LDD ldd
+#define LDX ldx
+#define LDDF ldd
+#define LDBLK ldda
+#define STB stb
+#define STH sth
+#define STW stw
+#define STD std
+#define STX stx
+#define STDF std
+#define STBLK stda
+#endif
+
+#ifdef __KERNEL__
+
+#define REGS_64BIT
+
+#else
+
+#ifndef REGS_64BIT
+#ifdef __sparc_v9__
+#define REGS_64BIT
+#endif
+#endif
+
+#endif
+
+#ifndef REGS_64BIT
+#define xcc icc
+#endif
+
+#endif
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/lib/VISbzero.S linux/arch/sparc64/lib/VISbzero.S
--- v2.1.43/linux/arch/sparc64/lib/VISbzero.S Wed Dec 31 16:00:00 1969
+++ linux/arch/sparc64/lib/VISbzero.S Mon Jul 7 08:18:55 1997
@@ -0,0 +1,246 @@
+/* $Id: VISbzero.S,v 1.4 1997/06/28 17:21:21 jj Exp $
+ * VISbzero.S: High speed clear operations utilizing the UltraSparc
+ * Visual Instruction Set.
+ *
+ * Copyright (C) 1997 David S. Miller (da...@caip.rutgers.edu)
+ * Copyright (C) 1996, 1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
+ */
+
+#include "VIS.h"
+
+#ifdef __KERNEL__
+#define EXN(x,y,a,b,z) \
+98: x,y; \
+ .section .fixup; \
+ .align 4; \
+99: ba VISbzerofixup_ret##z; \
+ a, b, %o0; \
+ .section __ex_table; \
+ .align 8; \
+ .xword 98b, 99b; \
+ .text; \
+ .align 4;
+#define EXC(x,y,a,b,c...) \
+98: x,y; \
+ .section .fixup; \
+ .align 4; \
+99: c; \
+ ba VISbzerofixup_ret0; \
+ a, b, %o0; \
+ .section __ex_table; \
+ .align 8; \
+ .xword 98b, 99b; \
+ .text; \
+ .align 4;
+#define EXO1(x,y) \
+98: x,y; \
+ .section __ex_table; \
+ .align 8; \
+ .xword 98b, VISbzerofixup_reto1; \
+ .text; \
+ .align 4;
+#define EX(x,y,a,b) EXN(x,y,a,b,0)
+#define EX1(x,y,a,b) EXN(x,y,a,b,1)
+#define EX2(x,y,a,b) EXN(x,y,a,b,2)
+#define EXT(start,end,handler) \
+ .section __ex_table; \
+ .align 8; \
+ .xword start, 0, end, handler; \
+ .text; \
+ .align 4
+#else
+#define EX(x,y,a,b) x,y
+#define EX1(x,y,a,b) x,y
+#define EX2(x,y,a,b) x,y
+#define EXC(x,y,a,b,c...) x,y
+#define EXO1(x,y) x,y
+#define EXT(a,b,c)
+#endif
+
+#define ZERO_BLOCKS(base, offset, source) \
+ STX source, [base - offset - 0x38] ASINORMAL; \
+ STX source, [base - offset - 0x30] ASINORMAL; \
+ STX source, [base - offset - 0x28] ASINORMAL; \
+ STX source, [base - offset - 0x20] ASINORMAL; \
+ STX source, [base - offset - 0x18] ASINORMAL; \
+ STX source, [base - offset - 0x10] ASINORMAL; \
+ STX source, [base - offset - 0x08] ASINORMAL; \
+ STX source, [base - offset - 0x00] ASINORMAL;
+
+#ifdef __KERNEL__
+#define RETL clr %o0
+#else
+#define RETL mov %g3, %o0
+#endif
+
+ /* Well, bzero is a lot easier to get right than bcopy... */
+#ifdef __KERNEL__
+ .section __ex_table,#alloc
+ .section .fixup,#alloc,#execinstr
+#endif
+ .text
+ .align 32
+#ifdef __KERNEL__
+ .globl __bzero, __bzero_noasi
+__bzero:
+ wr %g0, ASI_P, %asi ! LSU Group
+__bzero_noasi:
+#else
+ .globl bzero
+bzero_private:
+bzero:
+#ifndef REGS_64BIT


+ srl %o1, 0, %o1

+#endif
+ mov %o0, %g3
+#endif
+ cmp %o1, 7
+ bleu,pn %xcc, 17f
+ andcc %o0, 3, %o2
+ be,a,pt %xcc, 4f
+ andcc %o0, 4, %g0
+ cmp %o2, 3
+ be,pn %xcc, 2f
+ EXO1(STB %g0, [%o0 + 0x00] ASINORMAL)
+ cmp %o2, 2
+ be,pt %xcc, 2f
+ EX(STB %g0, [%o0 + 0x01] ASINORMAL, sub %o1, 1)
+ EX(STB %g0, [%o0 + 0x02] ASINORMAL, sub %o1, 2)
+2: sub %o2, 4, %o2
+ sub %o0, %o2, %o0
+ add %o1, %o2, %o1
+ andcc %o0, 4, %g0
+4: be,pt %xcc, 2f
+ cmp %o1, 128
+ EXO1(STW %g0, [%o0] ASINORMAL)
+ sub %o1, 4, %o1
+ add %o0, 4, %o0
+2: blu,pn %xcc, 9f
+ andcc %o0, 0x38, %o2
+ be,pn %icc, 6f
+ mov 64, %o5
+ andcc %o0, 8, %g0
+ be,pn %icc, 1f
+ sub %o5, %o2, %o5
+ EX(STX %g0, [%o0] ASINORMAL, sub %o1, 0)
+ add %o0, 8, %o0
+1: andcc %o5, 16, %g0
+ be,pn %icc, 1f
+ sub %o1, %o5, %o1
+ EX1(STX %g0, [%o0] ASINORMAL, add %g0, 0)
+ EX1(STX %g0, [%o0 + 8] ASINORMAL, sub %g0, 8)
+ add %o0, 16, %o0
+1: andcc %o5, 32, %g0
+ be,pn %icc, 7f
+ andncc %o1, 0x3f, %o3
+ EX(STX %g0, [%o0] ASINORMAL, add %o1, 32)
+ EX(STX %g0, [%o0 + 8] ASINORMAL, add %o1, 24)
+ EX(STX %g0, [%o0 + 16] ASINORMAL, add %o1, 16)
+ EX(STX %g0, [%o0 + 24] ASINORMAL, add %o1, 8)
+ add %o0, 32, %o0
+6: andncc %o1, 0x3f, %o3
+7: be,pn %xcc, 9f
+#ifdef __KERNEL__
+ rd %asi, %g7
+ wr %g0, FPRS_FEF, %fprs
+ wr %g7, ASI_BLK_XOR, %asi
+#else
+ wr %g0, ASI_BLK_P, %asi
+#endif
+ membar #StoreStore | #LoadStore
+ fzero %f0
+ andcc %o3, 0xc0, %o2
+ and %o1, 0x3f, %o1
+ fzero %f2
+ andn %o3, 0xff, %o3
+ faddd %f0, %f2, %f4
+ fmuld %f0, %f2, %f6
+ cmp %o2, 64
+ faddd %f0, %f2, %f8
+ fmuld %f0, %f2, %f10
+ faddd %f0, %f2, %f12
+ brz,pn %o2, 10f
+ fmuld %f0, %f2, %f14
+ be,pn %icc, 2f
+ EXC(STBLK %f0, [%o0 + 0x00] ASIBLK, add %o3, %o2, add %o2, %o1, %o2)
+ cmp %o2, 128
+ be,pn %icc, 2f
+ EXC(STBLK %f0, [%o0 + 0x40] ASIBLK, add %o3, %o2, add %o2, %o1, %o2; sub %o2, 64, %o2)
+ EXC(STBLK %f0, [%o0 + 0x80] ASIBLK, add %o3, %o2, add %o2, %o1, %o2; sub %o2, 128, %o2)
+2: brz,pn %o3, 12f
+ add %o0, %o2, %o0
+10: EX(STBLK %f0, [%o0 + 0x00] ASIBLK, add %o3, %o1)
+ EXC(STBLK %f0, [%o0 + 0x40] ASIBLK, add %o3, %o1, sub %o1, 64, %o1)
+ EXC(STBLK %f0, [%o0 + 0x80] ASIBLK, add %o3, %o1, sub %o1, 128, %o1)
+ EXC(STBLK %f0, [%o0 + 0xc0] ASIBLK, add %o3, %o1, sub %o1, 192, %o1)
+11: subcc %o3, 256, %o3
+ bne,pt %xcc, 10b
+ add %o0, 256, %o0
+12:
+#ifdef __KERNEL__
+ wr %g0, 0, %fprs
+ wr %g7, 0x0, %asi
+#endif
+ membar #Sync
+9: andcc %o1, 0xf8, %o2
+ be,pn %xcc, 13f
+ andcc %o1, 7, %o1
+14: rd %pc, %o4
+ srl %o2, 1, %o3
+ sub %o4, %o3, %o4
+ jmpl %o4 + (13f - 14b), %g0
+ add %o0, %o2, %o0
+12: ZERO_BLOCKS(%o0, 0xc8, %g0)
+ ZERO_BLOCKS(%o0, 0x88, %g0)
+ ZERO_BLOCKS(%o0, 0x48, %g0)
+ ZERO_BLOCKS(%o0, 0x08, %g0)
+ EXT(12b,13f,VISbzerofixup_zb)
+13: be,pn %xcc, 8f
+ andcc %o1, 4, %g0
+ be,pn %xcc, 1f
+ andcc %o1, 2, %g0
+ EX(STW %g0, [%o0] ASINORMAL, and %o1, 7)
+ add %o0, 4, %o0
+1: be,pn %xcc, 1f
+ andcc %o1, 1, %g0
+ EX(STH %g0, [%o0] ASINORMAL, and %o1, 3)
+ add %o0, 2, %o0
+1: bne,a,pn %xcc, 8f
+ EX(STB %g0, [%o0] ASINORMAL, add %g0, 1)
+8: retl
+ RETL
+17: be,pn %xcc, 13b
+ orcc %o1, 0, %g0
+ be,pn %xcc, 0f
+8: add %o0, 1, %o0
+ subcc %o1, 1, %o1
+ bne,pt %xcc, 8b
+ EX(STB %g0, [%o0 - 1] ASINORMAL, add %o1, 1)
+0: retl
+ RETL
+
+#ifdef __KERNEL__
+ .section .fixup
+ .align 4
+VISbzerofixup_reto1:
+ mov %o1, %o0
+VISbzerofixup_ret0:
+ retl
+ wr %g0, 0, %fprs
+VISbzerofixup_ret1:
+ and %o5, 0x30, %o5
+ add %o5, %o1, %o5
+ ba,pt %xcc, VISbzerofixup_ret0
+ add %o0, %o5, %o0
+VISbzerofixup_ret2:
+ and %o5, 0x20, %o5
+ add %o5, %o1, %o5
+ ba,pt %xcc, VISbzerofixup_ret0
+ add %o0, %o5, %o0
+VISbzerofixup_zb:
+ andcc %o1, 7, %o1
+ sll %g2, 3, %g2
+ add %o1, 256, %o1
+ ba,pt %xcc, VISbzerofixup_ret0
+ sub %o1, %g2, %o0
+#endif
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/lib/VIScopy.S linux/arch/sparc64/lib/VIScopy.S
--- v2.1.43/linux/arch/sparc64/lib/VIScopy.S Wed Dec 31 16:00:00 1969
+++ linux/arch/sparc64/lib/VIScopy.S Mon Jul 7 08:18:55 1997
@@ -0,0 +1,1052 @@
+/* $Id: VIScopy.S,v 1.8 1997/06/28 17:21:22 jj Exp $
+ * VIScopy.S: High speed copy operations utilizing the UltraSparc
+ * Visual Instruction Set.
+ *
+ * Copyright (C) 1997 David S. Miller (da...@caip.rutgers.edu)
+ * Copyright (C) 1996, 1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
+ */
+
+#include "VIS.h"
+
+ /* VIS code can be used for numerous copy/set operation variants.
+ * It can be made to work in the kernel, one single instance,
+ * for all of memcpy, copy_to_user, and copy_from_user by setting
+ * the ASI src/dest globals correctly. Furthermore it can
+ * be used for kernel-->kernel page copies as well, a hook label
+ * is put in here just for this purpose.
+ *
+ * For userland, compiling this without __KERNEL__ defined makes
+ * it work just fine as a generic libc bcopy and memcpy.
+ * If for userland it is compiled with a 32bit gcc (but you need
+ * -Wa,-Av9a for as), the code will just rely on lower 32bits of
+ * IEU registers, if you compile it with 64bit gcc (ie. define
+ * __sparc_v9__), the code will use full 64bit.
+ */
+
+#ifdef __KERNEL__
+#define FPU_CLEAN_RETL \
+ wr %g0, 0, %fprs; \
+ retl; \
+ clr %o0;
+#define FPU_RETL \
+ wr %g0, 0, %fprs; \
+ retl; \
+ clr %o0;
+#define NORMAL_RETL \
+ retl; \
+ clr %o0;
+#define EX(x,y,a,b) \
+98: x,y; \
+ .section .fixup; \
+ .align 4; \
+99: ba VIScopyfixup_ret; \
+ a, b, %o0; \
+ .section __ex_table; \
+ .align 8; \
+ .xword 98b, 99b; \
+ .text; \
+ .align 4;
+#define EX2(x,y,c,d,e,a,b) \
+98: x,y; \
+ .section .fixup; \
+ .align 4; \
+99: c, d, e; \
+ ba VIScopyfixup_ret; \
+ a, b, %o0; \
+ .section __ex_table; \
+ .align 8; \
+ .xword 98b, 99b; \
+ .text; \
+ .align 4;
+#define EXO2(x,y) \
+98: x,y; \
+ .section __ex_table; \
+ .align 8; \
+ .xword 98b, VIScopyfixup_reto2; \
+ .text; \
+ .align 4;
+#define EXVISN(x,y,n) \
+98: x,y; \
+ .section __ex_table; \
+ .align 8; \
+ .xword 98b, VIScopyfixup_vis##n; \
+ .text; \
+ .align 4;
+#define EXT(start,end,handler) \
+ .section __ex_table; \
+ .align 8; \
+ .xword start, 0, end, handler; \
+ .text; \
+ .align 4;
+#else
+#define FPU_CLEAN_RETL \
+ retl; \
+ mov %g6, %o0;
+#define FPU_RETL \
+ retl; \
+ mov %g6, %o0;
+#define NORMAL_RETL \
+ retl; \
+ mov %g6, %o0;
+#define EX(x,y,a,b) x,y
+#define EX2(x,y,c,d,e,a,b) x,y
+#define EXO2(x,y) x,y
+#define EXVISN(x,y,n) x,y
+#define EXT(a,b,c)
+#endif
+#define EXVIS(x,y) EXVISN(x,y,0)
+#define EXVIS1(x,y) EXVISN(x,y,1)
+#define EXVIS2(x,y) EXVISN(x,y,2)
+#define EXVIS3(x,y) EXVISN(x,y,3)
+#define EXVIS4(x,y) EXVISN(x,y,4)
+#define EXVIS5(x,y) EXVISN(x,y,5)
+
+#define FREG_FROB(f1, f2, f3, f4, f5, f6, f7, f8, f9) \
+ faligndata %f1, %f2, %f48; \
+ faligndata %f2, %f3, %f50; \
+ faligndata %f3, %f4, %f52; \
+ faligndata %f4, %f5, %f54; \
+ faligndata %f5, %f6, %f56; \
+ faligndata %f6, %f7, %f58; \
+ faligndata %f7, %f8, %f60; \
+ faligndata %f8, %f9, %f62;
+
+#define MAIN_LOOP_CHUNK(src, dest, fdest, fsrc, len, jmptgt) \
+ EXVIS(LDBLK [%src] ASIBLK, %fdest); \
+ add %src, 0x40, %src; \
+ ASI_SETDST_BLK \
+ add %dest, 0x40, %dest; \
+ subcc %len, 0x40, %len; \
+ be,pn %xcc, jmptgt; \
+ EXVIS2(STBLK %fsrc, [%dest - 0x40] ASIBLK); \
+ ASI_SETSRC_BLK
+
+#define LOOP_CHUNK1(src, dest, len, branch_dest) \
+ MAIN_LOOP_CHUNK(src, dest, f0, f48, len, branch_dest)
+#define LOOP_CHUNK2(src, dest, len, branch_dest) \
+ MAIN_LOOP_CHUNK(src, dest, f16, f48, len, branch_dest)
+#define LOOP_CHUNK3(src, dest, len, branch_dest) \
+ MAIN_LOOP_CHUNK(src, dest, f32, f48, len, branch_dest)
+
+#define STORE_SYNC(dest, fsrc) \
+ EXVIS(STBLK %fsrc, [%dest] ASIBLK); \
+ add %dest, 0x40, %dest;
+
+#define STORE_JUMP(dest, fsrc, target) \
+ EXVIS3(STBLK %fsrc, [%dest] ASIBLK); \
+ add %dest, 0x40, %dest; \
+ ba,pt %xcc, target;
+
+#ifndef __KERNEL__
+#define VISLOOP_PAD nop; nop; nop; nop; \
+ nop; nop; nop; nop; \
+ nop; nop; nop; nop; \
+ nop; nop; nop;
+#else
+#define VISLOOP_PAD nop; nop; nop; nop; \
+ nop; nop; nop; nop; \
+ nop;
+#endif
+
+#define FINISH_VISCHUNK(dest, f0, f1, left) \
+ ASI_SETDST_NOBLK \
+ subcc %left, 8, %left; \
+ bl,pn %xcc, vis_out; \
+ faligndata %f0, %f1, %f48; \
+ EXVIS4(STDF %f48, [%dest] ASINORMAL); \
+ add %dest, 8, %dest;
+
+#define UNEVEN_VISCHUNK(dest, f0, f1, left) \
+ subcc %left, 8, %left; \
+ bl,pn %xcc, vis_out; \
+ fsrc1 %f0, %f1; \
+ ba,a,pt %xcc, vis_slk;
+
+ /* Macros for non-VIS memcpy code. */
+#ifdef REGS_64BIT
+
+#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ASI_SETSRC_NOBLK \
+ LDX [%src + offset + 0x00] ASINORMAL, %t0; \
+ LDX [%src + offset + 0x08] ASINORMAL, %t1; \
+ LDX [%src + offset + 0x10] ASINORMAL, %t2; \
+ LDX [%src + offset + 0x18] ASINORMAL, %t3; \
+ ASI_SETDST_NOBLK \
+ STW %t0, [%dst + offset + 0x04] ASINORMAL; \
+ srlx %t0, 32, %t0; \
+ STW %t0, [%dst + offset + 0x00] ASINORMAL; \
+ STW %t1, [%dst + offset + 0x0c] ASINORMAL; \
+ srlx %t1, 32, %t1; \
+ STW %t1, [%dst + offset + 0x08] ASINORMAL; \
+ STW %t2, [%dst + offset + 0x14] ASINORMAL; \
+ srlx %t2, 32, %t2; \
+ STW %t2, [%dst + offset + 0x10] ASINORMAL; \
+ STW %t3, [%dst + offset + 0x1c] ASINORMAL; \
+ srlx %t3, 32, %t3; \
+ STW %t3, [%dst + offset + 0x18] ASINORMAL;
+
+#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ASI_SETSRC_NOBLK \
+ LDX [%src + offset + 0x00] ASINORMAL, %t0; \
+ LDX [%src + offset + 0x08] ASINORMAL, %t1; \
+ LDX [%src + offset + 0x10] ASINORMAL, %t2; \
+ LDX [%src + offset + 0x18] ASINORMAL, %t3; \
+ ASI_SETDST_NOBLK \
+ STX %t0, [%dst + offset + 0x00] ASINORMAL; \
+ STX %t1, [%dst + offset + 0x08] ASINORMAL; \
+ STX %t2, [%dst + offset + 0x10] ASINORMAL; \
+ STX %t3, [%dst + offset + 0x18] ASINORMAL; \
+ ASI_SETSRC_NOBLK \
+ LDX [%src + offset + 0x20] ASINORMAL, %t0; \
+ LDX [%src + offset + 0x28] ASINORMAL, %t1; \
+ LDX [%src + offset + 0x30] ASINORMAL, %t2; \
+ LDX [%src + offset + 0x38] ASINORMAL, %t3; \
+ ASI_SETDST_NOBLK \
+ STX %t0, [%dst + offset + 0x20] ASINORMAL; \
+ STX %t1, [%dst + offset + 0x28] ASINORMAL; \
+ STX %t2, [%dst + offset + 0x30] ASINORMAL; \
+ STX %t3, [%dst + offset + 0x38] ASINORMAL;
+
+#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ASI_SETSRC_NOBLK \
+ LDX [%src - offset - 0x10] ASINORMAL, %t0; \
+ LDX [%src - offset - 0x08] ASINORMAL, %t1; \
+ ASI_SETDST_NOBLK \
+ STW %t0, [%dst - offset - 0x0c] ASINORMAL; \
+ srlx %t0, 32, %t2; \
+ STW %t2, [%dst - offset - 0x10] ASINORMAL; \
+ STW %t1, [%dst - offset - 0x04] ASINORMAL; \
+ srlx %t1, 32, %t3; \
+ STW %t3, [%dst - offset - 0x08] ASINORMAL;
+
+#define MOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1) \
+ ASI_SETSRC_NOBLK \
+ LDX [%src - offset - 0x10] ASINORMAL, %t0; \
+ LDX [%src - offset - 0x08] ASINORMAL, %t1; \
+ ASI_SETDST_NOBLK \
+ STX %t0, [%dst - offset - 0x10] ASINORMAL; \
+ STX %t1, [%dst - offset - 0x08] ASINORMAL;
+
+#else /* !REGS_64BIT */
+
+#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ lduw [%src + offset + 0x00], %t0; \
+ lduw [%src + offset + 0x04], %t1; \
+ lduw [%src + offset + 0x08], %t2; \
+ lduw [%src + offset + 0x0c], %t3; \
+ stw %t0, [%dst + offset + 0x00]; \
+ stw %t1, [%dst + offset + 0x04]; \
+ stw %t2, [%dst + offset + 0x08]; \
+ stw %t3, [%dst + offset + 0x0c]; \
+ lduw [%src + offset + 0x10], %t0; \
+ lduw [%src + offset + 0x14], %t1; \
+ lduw [%src + offset + 0x18], %t2; \
+ lduw [%src + offset + 0x1c], %t3; \
+ stw %t0, [%dst + offset + 0x10]; \
+ stw %t1, [%dst + offset + 0x14]; \
+ stw %t2, [%dst + offset + 0x18]; \
+ stw %t3, [%dst + offset + 0x1c];
+
+#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ lduw [%src - offset - 0x10], %t0; \
+ lduw [%src - offset - 0x0c], %t1; \
+ lduw [%src - offset - 0x08], %t2; \
+ lduw [%src - offset - 0x04], %t3; \
+ stw %t0, [%dst - offset - 0x10]; \
+ stw %t1, [%dst - offset - 0x0c]; \
+ stw %t2, [%dst - offset - 0x08]; \
+ stw %t3, [%dst - offset - 0x04];
+
+#endif /* !REGS_64BIT */
+
+#ifdef __KERNEL__
+ .section __ex_table,#alloc
+ .section .fixup,#alloc,#execinstr
+#endif
+
+ .text
+ .align 32
+ .globl memcpy
+ .type memcpy,@function
+
+ .globl bcopy
+ .type bcopy,@function
+
+#ifdef __KERNEL__
+ .globl __memcpy
+ .type __memcpy,@function
+
+ .globl __memcpy_384plus
+ .type __memcpy_384plus,@function
+
+ .globl __memcpy_16plus
+ .type __memcpy_16plus,@function
+
+ .globl __memcpy_short
+ .type __memcpy_short,@function
+
+ .globl __memcpy_entry
+ .type __memcpy_entry,@function
+
+ .globl copy_page
+ .type copy_page,@function
+
+memcpy_private:
+__memcpy:
+memcpy: mov ASI_BLK_P, asi_src ! IEU0 Group
+ brnz,pt %o2, __memcpy_entry ! CTI
+ mov ASI_BLK_P, asi_dest ! IEU1
+ retl
+ clr %o0
+
+copy_page: wr %g0, FPRS_FEF, %fprs ! FPU Group
+ sethi %hi(8192), %o2 ! IEU0 Group
+ mov ASI_BLK_P, asi_src ! IEU1
+ b,pt %xcc, dest_is_64byte_aligned ! CTI
+ mov ASI_BLK_COMMIT_P, asi_dest ! IEU0 Group
+
+ .align 32
+ .globl __copy_from_user
+ .type __copy_from_user,@function
+__copy_from_user:mov ASI_BLK_S, asi_src ! IEU0 Group
+ brnz,pt %o2, __memcpy_entry ! CTI
+ mov ASI_BLK_P, asi_dest ! IEU1
+
+ .globl __copy_to_user
+ .type __copy_to_user,@function
+__copy_to_user: mov ASI_BLK_P, asi_src ! IEU0 Group
+ brnz,pt %o2, __memcpy_entry ! CTI
+ mov ASI_BLK_S, asi_dest ! IEU1
+ retl ! CTI Group
+ clr %o0 ! IEU0 Group
+#endif
+
+bcopy: or %o0, 0, %g3 ! IEU0 Group
+ addcc %o1, 0, %o0 ! IEU1
+ brgez,pt %o2, memcpy_private ! CTI
+ or %g3, 0, %o1 ! IEU0 Group
+ retl ! CTI Group brk forced
+ clr %o0 ! IEU0
+
+
+ .align 32
+#ifdef __KERNEL__
+__memcpy_384plus:
+ andcc %o0, 7, %g2 ! IEU1 Group
+#endif
+VIS_enter:
+ be,pt %xcc, dest_is_8byte_aligned ! CTI
+ andcc %o0, 0x38, %g5 ! IEU1 Group
+do_dest_8byte_align:
+ mov 8, %g1 ! IEU0
+ sub %g1, %g2, %g2 ! IEU0 Group
+ andcc %o0, 1, %g0 ! IEU1
+ be,pt %icc, 2f ! CTI
+ sub %o2, %g2, %o2 ! IEU0 Group
+1: ASI_SETSRC_NOBLK ! LSU Group
+ EX(LDUB [%o1] ASINORMAL, %o5,
+ add %o2, %g2) ! Load Group
+ add %o1, 1, %o1 ! IEU0
+ add %o0, 1, %o0 ! IEU1
+ ASI_SETDST_NOBLK ! LSU Group
+ subcc %g2, 1, %g2 ! IEU1 Group
+ be,pn %xcc, 3f ! CTI
+ EX2(STB %o5, [%o0 - 1] ASINORMAL,
+ add %g2, 1, %g2,
+ add %o2, %g2) ! Store
+2: ASI_SETSRC_NOBLK ! LSU Group
+ EX(LDUB [%o1] ASINORMAL, %o5,
+ add %o2, %g2) ! Load Group
+ add %o0, 2, %o0 ! IEU0
+ EX(LDUB [%o1 + 1] ASINORMAL, %g3,
+ add %o2, %g2) ! Load Group
+ ASI_SETDST_NOBLK ! LSU Group
+ subcc %g2, 2, %g2 ! IEU1 Group
+ EX2(STB %o5, [%o0 - 2] ASINORMAL,
+ add %g2, 2, %g2,
+ add %o2, %g2) ! Store
+ add %o1, 2, %o1 ! IEU0
+ bne,pt %xcc, 2b ! CTI Group
+ EX2(STB %g3, [%o0 - 1] ASINORMAL,
+ add %g2, 1, %g2,
+ add %o2, %g2) ! Store
+3: andcc %o0, 0x38, %g5 ! IEU1 Group
+dest_is_8byte_aligned:
+ be,pt %icc, dest_is_64byte_aligned ! CTI
+#ifdef __KERNEL__
+ wr %g0, FPRS_FEF, %fprs ! FPU Group
+do_dest_64byte_align:
+ mov 64, %g1 ! IEU0 Group
+#else
+ mov 64, %g1 ! IEU0 Group
+do_dest_64byte_align:
+#endif
+ fmovd %f0, %f2 ! FPU
+ sub %g1, %g5, %g5 ! IEU0 Group
+ ASI_SETSRC_NOBLK ! LSU Group
+ alignaddr %o1, %g0, %g1 ! GRU Group
+ EXO2(LDDF [%g1] ASINORMAL, %f4) ! Load Group
+ sub %o2, %g5, %o2 ! IEU0
+1: EX(LDDF [%g1 + 0x8] ASINORMAL, %f6,
+ add %o2, %g5) ! Load Group
+ add %g1, 0x8, %g1 ! IEU0 Group
+ subcc %g5, 8, %g5 ! IEU1
+ ASI_SETDST_NOBLK ! LSU Group
+ faligndata %f4, %f6, %f0 ! GRU Group
+ EX2(STDF %f0, [%o0] ASINORMAL,
+ add %g5, 8, %g5,
+ add %o2, %g5) ! Store
+ add %o1, 8, %o1 ! IEU0 Group
+ be,pn %xcc, dest_is_64byte_aligned ! CTI
+ add %o0, 8, %o0 ! IEU1
+ ASI_SETSRC_NOBLK ! LSU Group
+ EX(LDDF [%g1 + 0x8] ASINORMAL, %f4,
+ add %o2, %g5) ! Load Group
+ add %g1, 8, %g1 ! IEU0
+ subcc %g5, 8, %g5 ! IEU1
+ ASI_SETDST_NOBLK ! LSU Group
+ faligndata %f6, %f4, %f0 ! GRU Group
+ EX2(STDF %f0, [%o0] ASINORMAL,
+ add %g5, 8, %g5,
+ add %o2, %g5) ! Store
+ add %o1, 8, %o1 ! IEU0
+ ASI_SETSRC_NOBLK ! LSU Group
+ bne,pt %xcc, 1b ! CTI Group
+ add %o0, 8, %o0 ! IEU0
+dest_is_64byte_aligned:
+ membar #LoadStore | #StoreStore | #StoreLoad ! LSU Group
+#ifndef __KERNEL__
+ wr %g0, ASI_BLK_P, %asi ! LSU Group
+#endif
+ subcc %o2, 0x40, %g7 ! IEU1 Group
+ mov %o1, %g1 ! IEU0
+ andncc %g7, (0x40 - 1), %g7 ! IEU1 Group
+ srl %g1, 3, %g2 ! IEU0
+ sub %o2, %g7, %g3 ! IEU0 Group
+ andn %o1, (0x40 - 1), %o1 ! IEU1
+ and %g2, 7, %g2 ! IEU0 Group
+ andncc %g3, 0x7, %g3 ! IEU1
+ fmovd %f0, %f2 ! FPU
+ sub %g3, 0x10, %g3 ! IEU0 Group
+ sub %o2, %g7, %o2 ! IEU1
+ alignaddr %g1, %g0, %g0 ! GRU Group
+ add %g1, %g7, %g1 ! IEU0 Group
+ subcc %o2, %g3, %o2 ! IEU1
+ ASI_SETSRC_BLK ! LSU Group
+ EXVIS1(LDBLK [%o1 + 0x00] ASIBLK, %f0) ! LSU Group
+ add %g1, %g3, %g1 ! IEU0
+ EXVIS1(LDBLK [%o1 + 0x40] ASIBLK, %f16) ! LSU Group
+ sub %g7, 0x80, %g7 ! IEU0
+ EXVIS(LDBLK [%o1 + 0x80] ASIBLK, %f32) ! LSU Group
+ ! Clk1 Group 8-(
+ ! Clk2 Group 8-(
+ ! Clk3 Group 8-(
+ ! Clk4 Group 8-(
+vispc: rd %pc, %g5 ! PDU Group 8-(
+ addcc %g5, %lo(vis00 - vispc), %g5 ! IEU1 Group
+ sll %g2, 9, %g2 ! IEU0
+ jmpl %g5 + %g2, %g0 ! CTI Group brk forced
+ addcc %o1, 0xc0, %o1 ! IEU1 Group
+ .align 512 /* OK, here comes the fun part... */
+vis00:FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) LOOP_CHUNK1(o1, o0, g7, vis01)
+ FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) LOOP_CHUNK2(o1, o0, g7, vis02)
+ FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) LOOP_CHUNK3(o1, o0, g7, vis03)
+ b,pt %xcc, vis00+4; faligndata %f0, %f2, %f48
+vis01:FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) STORE_JUMP(o0, f48, finish_f0) membar #Sync
+vis02:FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) STORE_JUMP(o0, f48, check_finish_f16) add %o2, %g3, %g7
+vis03:FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32) STORE_JUMP(o0, f48, finish_f32) membar #Sync
+ VISLOOP_PAD
+vis10:FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) LOOP_CHUNK1(o1, o0, g7, vis11)
+ FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) LOOP_CHUNK2(o1, o0, g7, vis12)
+ FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) LOOP_CHUNK3(o1, o0, g7, vis13)
+ b,pt %xcc, vis10+4; faligndata %f2, %f4, %f48
+vis11:FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) STORE_JUMP(o0, f48, finish_f2) membar #Sync
+vis12:FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) STORE_JUMP(o0, f48, finish_f18) membar #Sync
+vis13:FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34) STORE_JUMP(o0, f48, finish_f34) membar #Sync
+ VISLOOP_PAD
+vis20:FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) LOOP_CHUNK1(o1, o0, g7, vis21)
+ FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) LOOP_CHUNK2(o1, o0, g7, vis22)
+ FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) LOOP_CHUNK3(o1, o0, g7, vis23)
+ b,pt %xcc, vis20+4; faligndata %f4, %f6, %f48
+vis21:FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) STORE_JUMP(o0, f48, finish_f4) membar #Sync
+vis22:FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) STORE_JUMP(o0, f48, finish_f20) membar #Sync
+vis23:FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36) STORE_JUMP(o0, f48, finish_f36) membar #Sync
+ VISLOOP_PAD
+vis30:FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) LOOP_CHUNK1(o1, o0, g7, vis31)
+ FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) LOOP_CHUNK2(o1, o0, g7, vis32)
+ FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) LOOP_CHUNK3(o1, o0, g7, vis33)
+ b,pt %xcc, vis30+4; faligndata %f6, %f8, %f48
+vis31:FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) STORE_JUMP(o0, f48, finish_f6) membar #Sync
+vis32:FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) STORE_JUMP(o0, f48, finish_f22) membar #Sync
+vis33:FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38) STORE_JUMP(o0, f48, finish_f38) membar #Sync
+ VISLOOP_PAD
+vis40:FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) LOOP_CHUNK1(o1, o0, g7, vis41)
+ FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) LOOP_CHUNK2(o1, o0, g7, vis42)
+ FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) LOOP_CHUNK3(o1, o0, g7, vis43)
+ b,pt %xcc, vis40+4; faligndata %f8, %f10, %f48
+vis41:FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) STORE_JUMP(o0, f48, finish_f8) membar #Sync
+vis42:FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) STORE_JUMP(o0, f48, finish_f24) membar #Sync
+vis43:FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40) STORE_JUMP(o0, f48, finish_f40) membar #Sync
+ VISLOOP_PAD
+vis50:FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) LOOP_CHUNK1(o1, o0, g7, vis51)
+ FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) LOOP_CHUNK2(o1, o0, g7, vis52)
+ FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) LOOP_CHUNK3(o1, o0, g7, vis53)
+ b,pt %xcc, vis50+4; faligndata %f10, %f12, %f48
+vis51:FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) STORE_JUMP(o0, f48, finish_f10) membar #Sync
+vis52:FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) STORE_JUMP(o0, f48, finish_f26) membar #Sync
+vis53:FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42) STORE_JUMP(o0, f48, finish_f42) membar #Sync
+ VISLOOP_PAD
+vis60:FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) LOOP_CHUNK1(o1, o0, g7, vis61)
+ FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) LOOP_CHUNK2(o1, o0, g7, vis62)
+ FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) LOOP_CHUNK3(o1, o0, g7, vis63)
+ b,pt %xcc, vis60+4; faligndata %f12, %f14, %f48
+vis61:FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) STORE_JUMP(o0, f48, finish_f12) membar #Sync
+vis62:FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) STORE_JUMP(o0, f48, finish_f28) membar #Sync
+vis63:FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44) STORE_JUMP(o0, f48, finish_f44) membar #Sync
+ VISLOOP_PAD
+vis70:FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) LOOP_CHUNK1(o1, o0, g7, vis71)
+ FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) LOOP_CHUNK2(o1, o0, g7, vis72)
+ FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) LOOP_CHUNK3(o1, o0, g7, vis73)
+ b,pt %xcc, vis70+4; faligndata %f14, %f16, %f48
+vis71:FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) STORE_JUMP(o0, f48, finish_f14) membar #Sync
+vis72:FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) STORE_JUMP(o0, f48, finish_f30) membar #Sync
+vis73:FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30) STORE_SYNC(o0, f48) membar #Sync
+ FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46) STORE_JUMP(o0, f48, finish_f46) membar #Sync
+ VISLOOP_PAD
+finish_f0: FINISH_VISCHUNK(o0, f0, f2, g3)
+finish_f2: FINISH_VISCHUNK(o0, f2, f4, g3)
+finish_f4: FINISH_VISCHUNK(o0, f4, f6, g3)
+finish_f6: FINISH_VISCHUNK(o0, f6, f8, g3)
+finish_f8: FINISH_VISCHUNK(o0, f8, f10, g3)
+finish_f10: FINISH_VISCHUNK(o0, f10, f12, g3)
+finish_f12: FINISH_VISCHUNK(o0, f12, f14, g3)
+finish_f14: UNEVEN_VISCHUNK(o0, f14, f0, g3)
+/* This is a special hack to speed up 8K page copy */
+check_finish_f16:
+ andcc %g1, 7, %g0
+ bne,pn %icc, finish_f16
+ cmp %g7, 0x40
+ bne,pn %icc, finish_f16
+ FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32)
+ membar #Sync
+ EXVIS1(STBLK %f48, [%o0] ASIBLK)
+ b,pt %xcc, vis_ret
+finish_f16: membar #Sync
+ FINISH_VISCHUNK(o0, f16, f18, g3)
+finish_f18: FINISH_VISCHUNK(o0, f18, f20, g3)
+finish_f20: FINISH_VISCHUNK(o0, f20, f22, g3)
+finish_f22: FINISH_VISCHUNK(o0, f22, f24, g3)
+finish_f24: FINISH_VISCHUNK(o0, f24, f26, g3)
+finish_f26: FINISH_VISCHUNK(o0, f26, f28, g3)
+finish_f28: FINISH_VISCHUNK(o0, f28, f30, g3)
+finish_f30: UNEVEN_VISCHUNK(o0, f30, f0, g3)
+finish_f32: FINISH_VISCHUNK(o0, f32, f34, g3)
+finish_f34: FINISH_VISCHUNK(o0, f34, f36, g3)
+finish_f36: FINISH_VISCHUNK(o0, f36, f38, g3)
+finish_f38: FINISH_VISCHUNK(o0, f38, f40, g3)
+finish_f40: FINISH_VISCHUNK(o0, f40, f42, g3)
+finish_f42: FINISH_VISCHUNK(o0, f42, f44, g3)
+finish_f44: FINISH_VISCHUNK(o0, f44, f46, g3)
+finish_f46: UNEVEN_VISCHUNK(o0, f46, f0, g3)
+vis_slk:ASI_SETSRC_NOBLK ! LSU Group
+ EXVIS4(LDDF [%o1] ASINORMAL, %f2) ! Load Group
+ add %o1, 8, %o1 ! IEU0
+ subcc %g3, 8, %g3 ! IEU1
+ ASI_SETDST_NOBLK ! LSU Group
+ faligndata %f0, %f2, %f8 ! GRU Group
+ EXVIS5(STDF %f8, [%o0] ASINORMAL) ! Store
+ bl,pn %xcc, vis_out ! CTI
+ add %o0, 8, %o0 ! IEU0 Group
+ ASI_SETSRC_NOBLK ! LSU Group
+ EXVIS4(LDDF [%o1] ASINORMAL, %f0) ! Load Group
+ add %o1, 8, %o1 ! IEU0
+ subcc %g3, 8, %g3 ! IEU1
+ ASI_SETDST_NOBLK ! LSU Group
+ faligndata %f2, %f0, %f8 ! GRU Group
+ EXVIS5(STDF %f8, [%o0] ASINORMAL) ! Store
+ bge,pt %xcc, vis_slk ! CTI
+ add %o0, 8, %o0 ! IEU0 Group
+vis_out:brz,pt %o2, vis_ret ! CTI Group
+ mov %g1, %o1 ! IEU0
+vis_slp:ASI_SETSRC_NOBLK ! LSU Group
+ EXO2(LDUB [%o1] ASINORMAL, %g5) ! LOAD
+ add %o1, 1, %o1 ! IEU0
+ add %o0, 1, %o0 ! IEU1
+ ASI_SETDST_NOBLK ! LSU Group
+ subcc %o2, 1, %o2 ! IEU1
+ bne,pt %xcc, vis_slp ! CTI
+ EX(STB %g5, [%o0 - 1] ASINORMAL,
+ add %o2, 1) ! Store Group
+vis_ret:membar #StoreLoad | #StoreStore ! LSU Group
+ FPU_CLEAN_RETL
+
+
+__memcpy_short:
+ andcc %o2, 1, %g0 ! IEU1 Group
+ be,pt %icc, 2f ! CTI
+1: ASI_SETSRC_NOBLK ! LSU Group
+ EXO2(LDUB [%o1] ASINORMAL, %g5) ! LOAD Group
+ add %o1, 1, %o1 ! IEU0
+ add %o0, 1, %o0 ! IEU1
+ ASI_SETDST_NOBLK ! LSU Group
+ subcc %o2, 1, %o2 ! IEU1 Group
+ be,pn %xcc, short_ret ! CTI
+ EX(STB %g5, [%o0 - 1] ASINORMAL,
+ add %o2, 1) ! Store
+2: ASI_SETSRC_NOBLK ! LSU Group
+ EXO2(LDUB [%o1] ASINORMAL, %g5) ! LOAD Group
+ add %o0, 2, %o0 ! IEU0
+ EXO2(LDUB [%o1 + 1] ASINORMAL, %o5) ! LOAD Group
+ add %o1, 2, %o1 ! IEU0
+ ASI_SETDST_NOBLK ! LSU Group
+ subcc %o2, 2, %o2 ! IEU1 Group
+ EX(STB %g5, [%o0 - 2] ASINORMAL,
+ add %o2, 2) ! Store
+ bne,pt %xcc, 2b ! CTI
+ EX(STB %o5, [%o0 - 1] ASINORMAL,
+ add %o2, 1) ! Store
+short_ret:
+ NORMAL_RETL
+
+#ifndef __KERNEL__
+memcpy_private:
+memcpy:
+#ifndef REGS_64BIT
+ srl %o2, 0, %o2 ! IEU1 Group
+#endif
+ brz,pn %o2, short_ret ! CTI Group
+ mov %o0, %g6 ! IEU0
+#endif
+__memcpy_entry:
+ cmp %o2, 15 ! IEU1 Group
+ bleu,pn %xcc, __memcpy_short ! CTI
+ cmp %o2, (64 * 6) ! IEU1 Group


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 23'
echo 'File patch-2.1.44 is continued in part 24'
echo 24 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part17

#!/bin/sh
# this is part 17 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 17; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

+ } else if(i & 0x40) {
+ lc0msk_to_irqnr[i] = 6;
+ lc1msk_to_irqnr[i] = 14;
+ lc2msk_to_irqnr[i] = 22;
+ lc3msk_to_irqnr[i] = 30;
+ } else if(i & 0x20) {
+ lc0msk_to_irqnr[i] = 5;
+ lc1msk_to_irqnr[i] = 13;
+ lc2msk_to_irqnr[i] = 21;
+ lc3msk_to_irqnr[i] = 29;
+ } else if(i & 0x10) {
+ lc0msk_to_irqnr[i] = 4;
+ lc1msk_to_irqnr[i] = 12;
+ lc2msk_to_irqnr[i] = 20;
+ lc3msk_to_irqnr[i] = 28;
+ } else if(i & 0x08) {
+ lc0msk_to_irqnr[i] = 3;
+ lc1msk_to_irqnr[i] = 11;
+ lc2msk_to_irqnr[i] = 19;
+ lc3msk_to_irqnr[i] = 27;
+ } else if(i & 0x04) {
+ lc0msk_to_irqnr[i] = 2;
+ lc1msk_to_irqnr[i] = 10;
+ lc2msk_to_irqnr[i] = 18;
+ lc3msk_to_irqnr[i] = 26;
+ } else if(i & 0x02) {
+ lc0msk_to_irqnr[i] = 1;
+ lc1msk_to_irqnr[i] = 9;
+ lc2msk_to_irqnr[i] = 17;
+ lc3msk_to_irqnr[i] = 25;
+ } else if(i & 0x01) {
+ lc0msk_to_irqnr[i] = 0;
+ lc1msk_to_irqnr[i] = 8;
+ lc2msk_to_irqnr[i] = 16;
+ lc3msk_to_irqnr[i] = 24;
+ } else {
+ lc0msk_to_irqnr[i] = 0;
+ lc1msk_to_irqnr[i] = 0;
+ lc2msk_to_irqnr[i] = 0;
+ lc3msk_to_irqnr[i] = 0;
+ }
+ }
+
+ ioc_icontrol = &sgi_i3regs->ints;
+ ioc_timers = &sgi_i3regs->timers;
+ ioc_tclear = &sgi_i3regs->tclear;
+
+ /* Mask out all interrupts. */
+ ioc_icontrol->imask0 = 0;
+ ioc_icontrol->imask1 = 0;
+ ioc_icontrol->cmeimask0 = 0;
+ ioc_icontrol->cmeimask1 = 0;
+
+ /* Now safe to set the exception vector. */
+ set_except_vector(0, indyIRQ);
+
+#ifdef CONFIG_REMOTE_DEBUG
+ ctype = prom_getcmdline();
+ for(i = 0; i < strlen(ctype); i++) {
+ if(ctype[i]=='k' && ctype[i+1]=='g' &&
+ ctype[i+2]=='d' && ctype[i+3]=='b' &&
+ ctype[i+4]=='=' && ctype[i+5]=='t' &&
+ ctype[i+6]=='t' && ctype[i+7]=='y' &&
+ ctype[i+8]=='d' &&
+ (ctype[i+9] == '1' || ctype[i+9] == '2')) {
+ printk("KGDB: Using serial line /dev/ttyd%d for "
+ "session\n", (ctype[i+9] - '0'));
+ if(ctype[i+9]=='1')
+ rs_kgdb_hook(1);
+ else if(ctype[i+9]=='2')
+ rs_kgdb_hook(0);
+ else {
+ printk("KGDB: whoops bogon tty line "
+ "requested, disabling session\n");
+ }
+
+ }
+ }
+#endif
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/kernel/indy_mc.c linux/arch/mips/sgi/kernel/indy_mc.c
--- v2.1.43/linux/arch/mips/sgi/kernel/indy_mc.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/kernel/indy_mc.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,153 @@
+/* $Id: indy_mc.c,v 1.1 1997/06/06 09:36:24 ralf Exp $
+ * indy_mc.c: Routines for manipulating the INDY memory controller.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+
+#include <asm/addrspace.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/sgimc.h>
+#include <asm/sgihpc.h>
+#include <asm/sgialib.h>
+
+/* #define DEBUG_SGIMC */
+
+struct sgimc_misc_ctrl *mcmisc_regs;
+unsigned long *rpsscounter;
+struct sgimc_dma_ctrl *dmactrlregs;
+
+static inline char *mconfig_string(unsigned long val)
+{
+ switch(val & SGIMC_MCONFIG_RMASK) {
+ case SGIMC_MCONFIG_FOURMB:
+ return "4MB";
+
+ case SGIMC_MCONFIG_EIGHTMB:
+ return "8MB";
+
+ case SGIMC_MCONFIG_SXTEENMB:
+ return "16MB";
+
+ case SGIMC_MCONFIG_TTWOMB:
+ return "32MB";
+
+ case SGIMC_MCONFIG_SFOURMB:
+ return "64MB";
+
+ case SGIMC_MCONFIG_OTEIGHTMB:
+ return "128MB";
+
+ default:
+ return "wheee, unknown";
+ };
+}
+
+void sgimc_init(void)
+{
+ unsigned long tmpreg;
+
+ mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000);
+ rpsscounter = (unsigned long *) (KSEG1 + 0x1fa01004);
+ dmactrlregs = (struct sgimc_dma_ctrl *) (KSEG1+0x1fa02000);
+
+ printk("MC: SGI memory controller Revision %d\n",
+ (int) mcmisc_regs->systemid & SGIMC_SYSID_MASKREV);
+
+#if 0 /* XXX Until I figure out what this bit really indicates XXX */
+ /* XXX Is this systemid bit reliable? */
+ if(mcmisc_regs->systemid & SGIMC_SYSID_EPRESENT) {
+ EISA_bus = 1;
+ printk("with EISA\n");
+ } else {
+ EISA_bus = 0;
+ printk("no EISA\n");
+ }
+#endif
+
+#ifdef DEBUG_SGIMC
+ prom_printf("sgimc_init: memconfig0<%s> mconfig1<%s>\n",
+ mconfig_string(mcmisc_regs->mconfig0),
+ mconfig_string(mcmisc_regs->mconfig1));
+
+ prom_printf("mcdump: cpuctrl0<%08lx> cpuctrl1<%08lx>\n",
+ mcmisc_regs->cpuctrl0, mcmisc_regs->cpuctrl1);
+ prom_printf("mcdump: divider<%08lx>, gioparm<%04x>\n",
+ mcmisc_regs->divider, mcmisc_regs->gioparm);
+#endif
+
+ /* Place the MC into a known state. This must be done before
+ * interrupts are first enabled etc.
+ */
+
+ /* Step 1: The CPU/GIO error status registers will not latch
+ * up a new error status until the register has been
+ * cleared by the cpu. These status registers are
+ * cleared by writing any value to them.
+ */
+ mcmisc_regs->cstat = mcmisc_regs->gstat = 0;
+
+ /* Step 2: Enable all parity checking in cpu control register
+ * zero.
+ */
+ tmpreg = mcmisc_regs->cpuctrl0;
+ tmpreg |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
+ SGIMC_CCTRL0_R4KNOCHKPARR);
+ mcmisc_regs->cpuctrl0 = tmpreg;
+
+ /* Step 3: Setup the MC write buffer depth, this is controlled
+ * in cpu control register 1 in the lower 4 bits.
+ */
+ tmpreg = mcmisc_regs->cpuctrl1;
+ tmpreg &= ~0xf;
+ tmpreg |= 0xd;
+ mcmisc_regs->cpuctrl1 = tmpreg;
+
+ /* Step 4: Initialize the RPSS divider register to run as fast
+ * as it can correctly operate. The register is laid
+ * out as follows:
+ *
+ * ----------------------------------------
+ * | RESERVED | INCREMENT | DIVIDER |
+ * ----------------------------------------
+ * 31 16 15 8 7 0
+ *
+ * DIVIDER determines how often a 'tick' happens,
+ * INCREMENT determines by how the RPSS increment
+ * registers value increases at each 'tick'. Thus,
+ * for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101
+ */
+ mcmisc_regs->divider = 0x101;
+
+ /* Step 5: Initialize GIO64 arbitrator configuration register.
+ *
+ * NOTE: If you dork with startup code the HPC init code in
+ * sgihpc_init() must run before us because of how we
+ * need to know Guiness vs. FullHouse and the board
+ * revision on this machine. You have been warned.
+ */
+
+ /* First the basic invariants across all gio64 implementations. */
+ tmpreg = SGIMC_GIOPARM_HPC64; /* All 1st HPC's interface at 64bits. */
+ tmpreg |= SGIMC_GIOPARM_ONEBUS; /* Only one physical GIO bus exists. */
+
+ if(sgi_guiness) {
+ /* Guiness specific settings. */
+ tmpreg |= SGIMC_GIOPARM_EISA64; /* MC talks to EISA at 64bits */
+ tmpreg |= SGIMC_GIOPARM_MASTEREISA; /* EISA bus can act as master */
+ } else {
+ /* Fullhouse specific settings. */
+ if(sgi_boardid < 2) {
+ tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC at 64bits */
+ tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp0 pipelines */
+ tmpreg |= SGIMC_GIOPARM_MASTEREXP1;/* exp1 masters */
+ tmpreg |= SGIMC_GIOPARM_RTIMEEXP0; /* exp0 is realtime */
+ } else {
+ tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC 64bits */
+ tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp[01] pipelined */
+ tmpreg |= SGIMC_GIOPARM_PLINEEXP1;
+ tmpreg |= SGIMC_GIOPARM_MASTEREISA;/* EISA masters */
+ }
+ }
+ mcmisc_regs->gioparm = tmpreg; /* poof */
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/kernel/indy_timer.c linux/arch/mips/sgi/kernel/indy_timer.c
--- v2.1.43/linux/arch/mips/sgi/kernel/indy_timer.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/kernel/indy_timer.c Mon Jul 7 08:18:54 1997
@@ -0,0 +1,299 @@
+/*
+ * indy_timer.c: Setting up the clock on the INDY 8254 controller.
+ *


+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ *

+ * $Id: indy_timer.c,v 1.2 1997/06/30 15:53:04 ralf Exp $
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/kernel_stat.h>
+


+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/ptrace.h>

+#include <asm/system.h>
+#include <asm/sgi.h>
+#include <asm/sgialib.h>
+#include <asm/sgihpc.h>
+#include <asm/sgint23.h>
+
+/* The layout of registers for the INDY Dallas 1286 clock chipset. */
+struct indy_clock {
+ volatile unsigned int hsec;
+ volatile unsigned int sec;
+ volatile unsigned int min;
+ volatile unsigned int malarm;
+ volatile unsigned int hr;
+ volatile unsigned int halarm;
+ volatile unsigned int day;
+ volatile unsigned int dalarm;
+ volatile unsigned int date;
+ volatile unsigned int month;
+ volatile unsigned int year;
+ volatile unsigned int cmd;
+ volatile unsigned int whsec;
+ volatile unsigned int wsec;
+ volatile unsigned int _unused0[50];
+};
+
+#define INDY_CLOCK_REGS ((struct indy_clock *)(KSEG1ADDR(0x1fbe0000)))
+
+/* Because of a bug in the i8254 timer we need to use the onchip r4k
+ * counter as our system wide timer interrupt running at 100HZ.
+ */
+static unsigned long r4k_offset; /* Amount to increment compare reg each time */
+static unsigned long r4k_cur; /* What counter should be at next timer irq */
+
+static inline void ack_r4ktimer(unsigned long newval)
+{
+ write_32bit_cp0_register(CP0_COMPARE, newval);
+}
+
+static int set_rtc_mmss(unsigned long nowtime)
+{
+ struct indy_clock *clock = INDY_CLOCK_REGS;
+ int retval = 0;
+ int real_seconds, real_minutes, clock_minutes;
+
+#define FROB_FROM_CLOCK(x) (((x) & 0xf) | ((((x) & 0xf0) >> 4) * 10));
+#define FROB_TO_CLOCK(x) ((((((x) & 0xff) / 10)<<4) | (((x) & 0xff) % 10)) & 0xff)
+
+ clock->cmd &= ~(0x80);
+ clock_minutes = clock->min;
+ clock->cmd |= (0x80);
+
+ clock_minutes = FROB_FROM_CLOCK(clock_minutes);
+ real_seconds = nowtime % 60;
+ real_minutes = nowtime / 60;
+
+ if(((abs(real_minutes - clock_minutes) + 15)/30) & 1)
+ real_minutes += 30; /* correct for half hour time zone */
+
+ real_minutes %= 60;
+ if(abs(real_minutes - clock_minutes) < 30) {
+ /* Force clock oscillator to be on. */
+ clock->month &= ~(0x80);
+
+ /* Write real_seconds and real_minutes into the Dallas. */
+ clock->cmd &= ~(0x80);
+ clock->sec = real_seconds;
+ clock->min = real_minutes;
+ clock->cmd |= (0x80);
+ } else
+ return -1;
+
+#undef FROB_FROM_CLOCK
+#undef FROB_TO_CLOCK
+


+ return retval;
+}
+

+static long last_rtc_update = 0;
+
+void indy_timer_interrupt(struct pt_regs *regs)
+{
+ /* Ack timer and compute new compare. */
+ r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
+ ack_r4ktimer(r4k_cur);
+ kstat.interrupts[7]++;
+ do_timer(regs);
+
+ /* We update the Dallas time of day approx. every 11 minutes,
+ * because of how the numbers work out we need to make
+ * absolutely sure we do this update within 500ms before the
+ * next second starts, thus the following code.
+ */
+ if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
+ xtime.tv_usec > 500000 - (tick >> 1) &&
+ xtime.tv_usec < 500000 + (tick >> 1))
+ if (set_rtc_mmss(xtime.tv_sec) == 0)
+ last_rtc_update = xtime.tv_sec;
+ else
+ last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+}
+
+static inline unsigned long dosample(volatile unsigned char *tcwp,
+ volatile unsigned char *tc2p)
+{
+ unsigned long ct0, ct1;
+ unsigned char msb, lsb;
+
+ /* Start the counter. */
+ *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MRGEN);
+ *tc2p = (SGINT_TCSAMP_COUNTER & 0xff);
+ *tc2p = (SGINT_TCSAMP_COUNTER >> 8);
+
+ /* Get initial counter invariant */
+ ct0 = read_32bit_cp0_register(CP0_COUNT);
+
+ /* Latch and spin until top byte of counter2 is zero */
+ *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT);
+ ct1 = read_32bit_cp0_register(CP0_COUNT);
+ lsb = *tc2p;
+ msb = *tc2p;
+ while(msb) {
+ *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT);
+ ct1 = read_32bit_cp0_register(CP0_COUNT);
+ lsb = *tc2p;
+ msb = *tc2p;
+ }
+
+ /* Stop the counter. */
+ *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST);
+
+ /* Return the difference, this is how far the r4k counter increments
+ * for every one HZ.
+ */
+ return ct1 - ct0;
+}
+
+/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * WARNING: this function will overflow on 2106-02-07 06:28:16 on
+ * machines were long is 32-bit! (However, as time_t is signed, we
+ * will already get problems at other places on 2038-01-19 03:14:08)
+ */
+static inline unsigned long mktime(unsigned int year, unsigned int mon,
+ unsigned int day, unsigned int hour,
+ unsigned int min, unsigned int sec)
+{
+ if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
+ mon += 12; /* Puts Feb last since it has leap day */
+ year -= 1;
+ }
+ return (((
+ (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
+ year*365 - 719499
+ )*24 + hour /* now have hours */
+ )*60 + min /* now have minutes */
+ )*60 + sec; /* finally seconds */
+}
+
+unsigned long get_indy_time(void)
+{
+ struct indy_clock *clock = INDY_CLOCK_REGS;
+ unsigned int year, mon, day, hour, min, sec;
+
+ /* Freeze it. */
+ clock->cmd &= ~(0x80);
+
+ /* Read regs. */
+ sec = clock->sec;
+ min = clock->min;
+ hour = (clock->hr & 0x3f);
+ day = (clock->date & 0x3f);
+ mon = (clock->month & 0x1f);
+ year = clock->year;
+
+ /* Unfreeze clock. */
+ clock->cmd |= 0x80;
+
+ /* Frob the bits. */
+#define FROB1(x) (((x) & 0xf) + ((((x) & 0xf0) >> 4) * 10));
+#define FROB2(x) (((x) & 0xf) + (((((x) & 0xf0) >> 4) & 0x3) * 10));
+
+ /* XXX Should really check that secs register is the same
+ * XXX as when we first read it and if not go back and
+ * XXX read the regs above again.
+ */
+ sec = FROB1(sec); min = FROB1(min); day = FROB1(day);
+ mon = FROB1(mon); year = FROB1(year);
+ hour = FROB2(hour);
+
+#undef FROB1
+#undef FROB2
+
+ /* Wheee... */
+ if(year < 45)
+ year += 30;
+ if ((year += 1940) < 1970)
+ year += 100;
+
+ return mktime(year, mon, day, hour, min, sec);
+}
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+
+void indy_timer_init(void)
+{
+ struct sgi_ioc_timers *p;
+ volatile unsigned char *tcwp, *tc2p;
+
+ /* Figure out the r4k offset, the algorithm is very simple
+ * and works in _all_ cases as long as the 8254 counter
+ * register itself works ok (as an interrupt driving timer
+ * it does not because of bug, this is why we are using
+ * the onchip r4k counter/compare register to serve this
+ * purpose, but for r4k_offset calculation it will work
+ * ok for us). There are other very complicated ways
+ * of performing this calculation but this one works just
+ * fine so I am not going to futz around. ;-)
+ */
+ p = ioc_timers;
+ tcwp = &p->tcword;
+ tc2p = &p->tcnt2;
+
+ printk("calculating r4koff... ");
+ r4k_offset = dosample(tcwp, tc2p); /* First sample. */
+ dosample(tcwp, tc2p); /* Eat one... */
+ r4k_offset += dosample(tcwp, tc2p); /* Second sample. */
+ r4k_offset = (r4k_offset >> 1); /* Get average. */
+ r4k_offset = HZ * r4k_offset; /* Multiply by HZ */
+
+ printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
+
+ r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
+ write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
+ set_cp0_status(ST0_IM, ALLINTS);
+ sti();
+
+ /* Read time from the dallas chipset. */
+ xtime.tv_sec = get_indy_time();
+ xtime.tv_usec = 0;
+}
+
+void indy_8254timer_irq(void)
+{
+ kstat.interrupts[4]++;
+ printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
+ prom_getchar();
+ prom_imode();
+}
+
+void do_gettimeofday(struct timeval *tv)


+{
+ unsigned long flags;
+

+ save_and_cli(flags);
+ *tv = xtime;
+ restore_flags(flags);
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+ cli();
+ xtime = *tv;
+ time_state = TIME_BAD;


+ time_maxerror = MAXPHASE;
+ time_esterror = MAXPHASE;
+ sti();

+}
+
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/kernel/reset.c linux/arch/mips/sgi/kernel/reset.c
--- v2.1.43/linux/arch/mips/sgi/kernel/reset.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/kernel/reset.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/mips/sgi/kernel/process.c
+ *
+ * Reset a SGI.
+ */
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/reboot.h>
+
+/* XXX How to pass the reboot command to the firmware??? */
+void sgi_machine_restart(char *command)
+{
+ for(;;)
+ prom_imode();
+}
+
+void sgi_machine_halt(void)


+{
+ /* XXX */
+}
+

+void sgi_machine_power_off(void)


+{
+ /* XXX */
+}

diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/kernel/setup.c linux/arch/mips/sgi/kernel/setup.c
--- v2.1.43/linux/arch/mips/sgi/kernel/setup.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/kernel/setup.c Mon Jul 7 08:18:54 1997
@@ -0,0 +1,89 @@
+/* $Id: setup.c,v 1.2 1997/06/30 15:26:24 ralf Exp $
+ * setup.c: SGI specific setup, including init of the feature struct.
+ *


+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */

+#ifndef __GOGOGO__
+#error "... about to fuckup your Indy?"
+#endif
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/reboot.h>
+#include <asm/vector.h>
+#include <asm/sgialib.h>
+#include <asm/sgi.h>
+#include <asm/sgimc.h>
+#include <asm/sgihpc.h>
+#include <asm/sgint23.h>
+
+extern int serial_console; /* in console.c, of course */
+
+extern void sgi_machine_restart(char *command);
+extern void sgi_machine_halt(void);
+extern void sgi_machine_power_off(void);
+
+struct feature sgi_feature = {
+};
+
+static void sgi_irq_setup(void)
+{
+ sgint_init();
+}
+
+#if 0


+extern void register_console(void (*proc)(const char *));
+

+static void sgi_print(const char *p)
+{
+ char c;
+
+ while((c = *p++) != 0) {
+ if(c == '\n')
+ prom_putchar('\r');
+ prom_putchar(c);
+ }
+}
+#endif
+
+void sgi_setup(void)
+{
+ char *ctype;
+
+ irq_setup = sgi_irq_setup;
+ feature = &sgi_feature;
+
+ _machine_restart = sgi_machine_restart;
+ _machine_halt = sgi_machine_halt;
+ _machine_power_off = sgi_machine_power_off;
+
+ /* register_console(sgi_print); */
+
+ /* Init the INDY HPC I/O controller. Need to call this before
+ * fucking with the memory controller because it needs to know the
+ * boardID and whether this is a Guiness or a FullHouse machine.
+ */
+ sgihpc_init();
+
+ /* Init INDY memory controller. */
+ sgimc_init();
+
+ /* ARCS console environment variable is set to "g?" for
+ * graphics console, it is set to "d" for the first serial
+ * line and "d2" for the second serial line.
+ */
+ ctype = prom_getenv("console");
+ serial_console = 0;
+ if(*ctype == 'd') {
+ if(*(ctype+1)=='2')
+ serial_console = 1;
+ else
+ serial_console = 2;
+ if(!serial_console) {
+ prom_printf("Weird console env setting %s\n", ctype);
+ prom_printf("Press a key to reboot.\n");
+ prom_getchar();
+ prom_imode();
+ }
+ }
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/kernel/system.c linux/arch/mips/sgi/kernel/system.c
--- v2.1.43/linux/arch/mips/sgi/kernel/system.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/kernel/system.c Mon Jul 7 08:18:54 1997
@@ -0,0 +1,174 @@
+/*
+ * system.c: Probe the system type using ARCS prom interface library.
+ *


+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ *

+ * $Id: system.c,v 1.2 1997/06/30 15:26:32 ralf Exp $
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/sgi.h>
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+
+#ifndef __GOGOGO__
+#error "... You're fearless, aren't you?"
+#endif
+
+enum sgi_mach sgimach;
+
+struct smatch {
+ char *name;
+ int type;
+};
+
+static struct smatch sgi_mtable[] = {
+ { "SGI-IP4", ip4 },
+ { "SGI-IP5", ip5 },
+ { "SGI-IP6", ip6 },
+ { "SGI-IP7", ip7 },
+ { "SGI-IP9", ip9 },
+ { "SGI-IP12", ip12 },
+ { "SGI-IP15", ip15 },
+ { "SGI-IP17", ip17 },
+ { "SGI-IP19", ip19 },
+ { "SGI-IP20", ip20 },
+ { "SGI-IP21", ip21 },
+ { "SGI-IP22", ip22 },
+ { "SGI-IP25", ip25 },
+ { "SGI-IP26", ip26 },
+ { "SGI-IP28", ip28 },
+ { "SGI-IP30", ip30 },
+ { "SGI-IP32", ip32 }
+};
+
+#define NUM_MACHS 17 /* for now */
+
+static struct smatch sgi_cputable[] = {
+ { "MIPS-R2000", CPU_R2000 },
+ { "MIPS-R3000", CPU_R3000 },
+ { "MIPS-R3000A", CPU_R3000A },
+ { "MIPS-R4000", CPU_R4000SC },
+ { "MIPS-R4400", CPU_R4400SC },
+ { "MIPS-R4600", CPU_R4600 },
+ { "MIPS-R8000", CPU_R8000 },
+ { "MIPS-R5000", CPU_R5000 },
+ { "MIPS-R5000A", CPU_R5000A }
+};
+
+#define NUM_CPUS 9 /* for now */
+
+static enum sgi_mach string_to_mach(char *s)


+{
+ int i;
+

+ for(i = 0; i < NUM_MACHS; i++) {
+ if(!strcmp(s, sgi_mtable[i].name))
+ return (enum sgi_mach) sgi_mtable[i].type;
+ }
+ prom_printf("\nYeee, could not determine SGI architecture type <%s>\n", s);
+ prom_printf("press a key to reboot\n");
+ prom_getchar();
+ romvec->imode();
+ return (enum sgi_mach) 0;
+}
+
+static int string_to_cpu(char *s)


+{
+ int i;
+

+ for(i = 0; i < NUM_CPUS; i++) {
+ if(!strcmp(s, sgi_cputable[i].name))
+ return sgi_mtable[i].type;
+ }
+ prom_printf("\nYeee, could not determine MIPS cpu type <%s>\n", s);
+ prom_printf("press a key to reboot\n");
+ prom_getchar();
+ romvec->imode();


+ return 0;
+}
+

+/*
+ * We' call this early before loadmmu(). If we do the other way around
+ * the firmware will crash and burn.
+ */
+void sgi_sysinit(void)
+{
+ pcomponent *p, *toplev, *cpup = 0;
+ int cputype = -1;
+
+
+ /* The root component tells us what machine architecture we
+ * have here.
+ */
+ p = prom_getchild(PROM_NULL_COMPONENT);
+ printk("ARCH: %s\n", p->iname);
+ sgimach = string_to_mach(p->iname);
+
+ /* Now scan for cpu(s). */
+ toplev = p = prom_getchild(p);
+ while(p) {
+ int ncpus = 0;
+
+ if(p->type == Cpu) {
+ if(++ncpus > 1) {
+ prom_printf("\nYeee, SGI MP not ready yet\n");
+ prom_printf("press a key to reboot\n");
+ prom_getchar();
+ romvec->imode();
+ }
+ printk("CPU: %s ", p->iname);
+ cpup = p;
+ cputype = string_to_cpu(cpup->iname);
+ }
+ p = prom_getsibling(p);
+ }
+ if(cputype == -1) {
+ prom_printf("\nYeee, could not find cpu ARCS component\n");
+ prom_printf("press a key to reboot\n");
+ prom_getchar();
+ romvec->imode();
+ }
+ p = prom_getchild(cpup);
+ while(p) {
+ switch(p->class) {
+ case processor:
+ switch(p->type) {
+ case Fpu:
+ printk("FPU<%s> ", p->iname);


+ break;
+
+ default:

+ break;
+ };
+ break;
+
+ case cache:
+ switch(p->type) {
+ case picache:
+ printk("ICACHE ");
+ break;
+
+ case pdcache:
+ printk("DCACHE ");
+ break;
+
+ case sccache:
+ printk("SCACHE ");


+ break;
+
+ default:

+ break;
+
+ };


+ break;
+
+ default:

+ break;
+ };
+ p = prom_getsibling(p);


+ }
+ printk("\n");
+}

diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/kernel/time.c linux/arch/mips/sgi/kernel/time.c
--- v2.1.43/linux/arch/mips/sgi/kernel/time.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/kernel/time.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,14 @@
+/* $Id: time.c,v 1.1 1997/06/06 09:36:39 ralf Exp $
+ * time.c: Generic SGI time_init() code, this will dispatch to the
+ * appropriate per-architecture time/counter init code.
+ *


+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+

+extern void indy_timer_init(void);
+
+void time_init(void)
+{
+ /* XXX assume INDY for now XXX */
+ indy_timer_init();
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/Makefile linux/arch/mips/sgi/prom/Makefile
--- v2.1.43/linux/arch/mips/sgi/prom/Makefile Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/Makefile Thu Jun 26 12:33:38 1997
@@ -0,0 +1,23 @@
+# $Id: Makefile,v 1.1 1997/06/06 09:36:49 ralf Exp $
+# Makefile for the SGI arcs prom monitor library routines
+# under Linux.


+#
+# 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...
+
+OBJS = console.o init.o printf.o memory.o tree.o tags.o env.o \
+ cmdline.o misc.o time.o file.o
+
+all: promlib.a
+
+promlib.a: $(OBJS)
+ $(AR) rcs promlib.a $(OBJS)
+ sync
+
+dep:
+ $(CPP) -M *.c > .depend
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/cmdline.c linux/arch/mips/sgi/prom/cmdline.c
--- v2.1.43/linux/arch/mips/sgi/prom/cmdline.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/cmdline.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,60 @@
+/* $Id: cmdline.c,v 1.1 1997/06/06 09:36:53 ralf Exp $
+ * cmdline.c: Kernel command line creation using ARCS argc/argv.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+
+/* #define DEBUG_CMDLINE */
+
+extern char arcs_cmdline[CL_SIZE];
+
+char *prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
+
+static char *ignored[] = {
+ "ConsoleIn=",
+ "ConsoleOut=",
+ "SystemPartition=",
+ "OSLoader=",
+ "OSLoadPartition=",
+ "OSLoadFilename="
+};
+#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0])))))
+
+void prom_init_cmdline(void)
+{
+ char *cp;
+ int actr, i;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ cp = &(arcs_cmdline[0]);
+ while(actr < prom_argc) {
+ for(i = 0; i < NENTS(ignored); i++) {
+ int len = strlen(ignored[i]);
+
+ if(!strncmp(prom_argv[actr], ignored[i], len))
+ goto pic_cont;
+ }
+ /* Ok, we want it. */
+ strcpy(cp, prom_argv[actr]);
+ cp += strlen(prom_argv[actr]);
+ *cp++ = ' ';
+
+ pic_cont:
+ actr++;
+ }
+ *cp = '\0';
+
+#ifdef DEBUG_CMDLINE
+ prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0]));
+#endif
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/console.c linux/arch/mips/sgi/prom/console.c
--- v2.1.43/linux/arch/mips/sgi/prom/console.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/console.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,24 @@
+/* $Id: console.c,v 1.1 1997/06/06 09:36:56 ralf Exp $
+ * console.c: SGI arcs console code.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@sgi.com)
+ */
+
+#include <asm/sgialib.h>
+
+void prom_putchar(char c)
+{
+ long cnt;
+ char it = c;
+
+ romvec->write(1, &it, 1, &cnt);
+}
+
+char prom_getchar(void)
+{
+ long cnt;
+ char c;
+
+ romvec->read(0, &c, 1, &cnt);
+ return c;
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/env.c linux/arch/mips/sgi/prom/env.c
--- v2.1.43/linux/arch/mips/sgi/prom/env.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/env.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,20 @@
+/* $Id: env.c,v 1.1 1997/06/06 09:36:59 ralf Exp $
+ * env.c: ARCS environment variable routines.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/sgialib.h>
+
+char *prom_getenv(char *name)
+{
+ return romvec->get_evar(name);
+}
+
+long prom_setenv(char *name, char *value)
+{
+ return romvec->set_evar(name, value);
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/file.c linux/arch/mips/sgi/prom/file.c
--- v2.1.43/linux/arch/mips/sgi/prom/file.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/file.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,58 @@
+/* $Id: file.c,v 1.1 1997/06/06 09:37:03 ralf Exp $
+ * file.c: ARCS firmware interface to files.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+
+#include <asm/sgialib.h>
+
+long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num,
+ unsigned long *cnt)
+{
+ return romvec->get_vdirent(fd, ent, num, cnt);
+}
+
+long prom_open(char *name, enum linux_omode md, unsigned long *fd)
+{
+ return romvec->open(name, md, fd);
+}
+
+long prom_close(unsigned long fd)
+{
+ return romvec->close(fd);
+}
+
+long prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt)
+{
+ return romvec->read(fd, buf, num, cnt);
+}
+
+long prom_getrstatus(unsigned long fd)
+{
+ return romvec->get_rstatus(fd);
+}
+
+long prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt)
+{
+ return romvec->write(fd, buf, num, cnt);
+}
+
+long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm)
+{
+ return romvec->seek(fd, off, sm);
+}
+
+long prom_mount(char *name, enum linux_mountops op)
+{
+ return romvec->mount(name, op);
+}
+
+long prom_getfinfo(unsigned long fd, struct linux_finfo *buf)
+{
+ return romvec->get_finfo(fd, buf);
+}
+
+long prom_setfinfo(unsigned long fd, unsigned long flags, unsigned long msk)
+{
+ return romvec->set_finfo(fd, flags, msk);
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/init.c linux/arch/mips/sgi/prom/init.c
--- v2.1.43/linux/arch/mips/sgi/prom/init.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/init.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,59 @@
+/* $Id: init.c,v 1.1 1997/06/06 09:37:06 ralf Exp $
+ * init.c: PROM library initialisation code.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+
+#include <linux/kernel.h>
+
+#include <asm/sgialib.h>
+
+/* #define DEBUG_PROM_INIT */
+
+/* Master romvec interface. */
+struct linux_romvec *romvec;
+struct linux_promblock *sgi_pblock;
+int prom_argc;
+char **prom_argv, **prom_envp;
+unsigned short prom_vers, prom_rev;
+
+extern void prom_testtree(void);
+
+int prom_init(int argc, char **argv, char **envp)
+{
+ struct linux_promblock *pb;
+
+ romvec = ROMVECTOR;
+ pb = sgi_pblock = PROMBLOCK;
+ prom_argc = argc;
+ prom_argv = argv;
+ prom_envp = envp;
+
+ if(pb->magic != 0x53435241) {
+ prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic);
+ while(1)
+ ;
+ }
+
+ prom_init_cmdline();
+
+ prom_vers = pb->ver;
+ prom_rev = pb->rev;
+ printk("PROMLIB: SGI ARCS firmware Version %d Revision %d\n",
+ prom_vers, prom_rev);
+ prom_meminit();
+ prom_setup_archtags();
+
+#if 0
+ prom_testtree();
+#endif
+
+#ifdef DEBUG_PROM_INIT
+ {
+ prom_printf("Press a key to reboot\n");
+ (void) prom_getchar();
+ romvec->imode();
+ }
+#endif
+ return 0;
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/memory.c linux/arch/mips/sgi/prom/memory.c
--- v2.1.43/linux/arch/mips/sgi/prom/memory.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/memory.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,129 @@
+/* $Id: memory.c,v 1.1 1997/06/06 09:37:10 ralf Exp $
+ * memory.c: PROM library functions for acquiring/using memory descriptors
+ * given to us from the ARCS firmware.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+
+#include <asm/sgialib.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/bootinfo.h>
+
+/* #define DEBUG */
+
+struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr)
+{
+ return romvec->get_mdesc(curr);
+}
+
+#ifdef DEBUG /* convenient for debugging */
+static char *mtypes[8] = {
+ "Exception Block",
+ "ARCS Romvec Page",
+ "Free/Contig RAM",
+ "Generic Free RAM",
+ "Bad Memory",
+ "Standlong Program Pages",
+ "ARCS Temp Storage Area",
+ "ARCS Permanent Storage Area"
+};
+#endif
+
+static struct prom_pmemblock prom_pblocks[PROM_MAX_PMEMBLOCKS];
+
+struct prom_pmemblock *prom_getpblock_array(void)
+{
+ return &prom_pblocks[0];
+}
+
+static void prom_setup_memupper(void)
+{
+ struct prom_pmemblock *p, *highest;
+
+ for(p = prom_getpblock_array(), highest = 0; p->size != 0; p++) {
+ if(p->base == 0xdeadbeef)
+ prom_printf("WHEEE, bogus pmemblock\n");
+ if(!highest || p->base > highest->base)
+ highest = p;
+ }
+ mips_memory_upper = highest->base + highest->size;
+#ifdef DEBUG
+ prom_printf("prom_setup_memupper: mips_memory_upper = %08lx\n",
+ mips_memory_upper);
+#endif
+}
+
+void prom_meminit(void)
+{
+ struct linux_mdesc *p;
+ int totram;


+ int i = 0;
+

+ p = prom_getmdesc(PROM_NULL_MDESC);
+#ifdef DEBUG
+ prom_printf("ARCS MEMORY DESCRIPTOR dump:\n");
+ while(p) {
+ prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
+ i, p, p->base, p->pages, mtypes[p->type]);
+ p = prom_getmdesc(p);
+ i++;
+ }
+#endif
+ p = prom_getmdesc(PROM_NULL_MDESC);
+ totram = 0;
+ i = 0;
+ while(p) {
+ if(p->type == free || p->type == fcontig) {
+ prom_pblocks[i].base =
+ ((p->base<<PAGE_SHIFT) + 0x80000000);
+ prom_pblocks[i].size = p->pages << PAGE_SHIFT;
+ totram += prom_pblocks[i].size;
+#ifdef DEBUG
+ prom_printf("free_chunk[%d]: base=%08lx size=%d\n",
+ i, prom_pblocks[i].base,
+ prom_pblocks[i].size);
+#endif
+ i++;
+ }
+ p = prom_getmdesc(p);
+ }
+ prom_pblocks[i].base = 0xdeadbeef;
+ prom_pblocks[i].size = 0; /* indicates last elem. of array */
+ printk("PROMLIB: Total free ram %d bytes (%dK,%dMB)\n",
+ totram, (totram/1024), (totram/1024/1024));
+
+ /* Setup upper physical memory bound. */
+ prom_setup_memupper();
+}
+
+/* Called from mem_init() to fixup the mem_map page settings. */
+void prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+ struct prom_pmemblock *p;
+ int i, nents;
+
+ /* Determine number of pblockarray entries. */
+ p = prom_getpblock_array();
+ for(i = 0; p[i].size; i++)
+ ;
+ nents = i;
+ while(start < end) {
+ for(i = 0; i < nents; i++) {
+ if((start >= (p[i].base)) &&
+ (start < (p[i].base + p[i].size))) {
+ start = p[i].base + p[i].size;
+ start &= PAGE_MASK;
+ continue;
+ }
+ }
+ set_bit(PG_reserved, &mem_map[MAP_NR(start)].flags);
+ start += PAGE_SIZE;
+ }
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/misc.c linux/arch/mips/sgi/prom/misc.c
--- v2.1.43/linux/arch/mips/sgi/prom/misc.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/misc.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,119 @@
+/*
+ * misc.c: Miscellaneous ARCS PROM routines.
+ *


+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */

+#include <linux/config.h>
+#include <linux/kernel.h>
+
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+#include <asm/system.h>
+
+extern unsigned long mips_cputype;
+extern int initialize_kbd(void);
+extern void *sgiwd93_host;
+extern void reset_wd33c93(void *instance);
+
+static inline void shutoff_r4600_cache(void)
+{
+ unsigned long tmp1, tmp2, tmp3;
+
+ if(mips_cputype != CPU_R4600 &&
+ mips_cputype != CPU_R4640 &&
+ mips_cputype != CPU_R4700)
+ return;
+ printk("Disabling R4600 SCACHE\n");
+ __asm__ __volatile__("
+ .set noreorder
+ .set mips3
+ li %0, 0x1
+ dsll %0, 31
+ lui %1, 0x9000
+ dsll32 %1, 0
+ or %0, %1, %0
+ mfc0 %2, $12


+ nop; nop; nop; nop;

+ li %1, 0x80
+ mtc0 %1, $12


+ nop; nop; nop; nop;

+ sh $0, 0(%0)
+ mtc0 $0, $12


+ nop; nop; nop; nop;

+ mtc0 %2, $12


+ nop; nop; nop; nop;

+ .set mips2
+ .set reorder
+ " : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3));
+}
+
+void prom_halt(void)
+{
+ shutoff_r4600_cache();
+ initialize_kbd();
+#if CONFIG_SCSI_SGIWD93
+ reset_wd33c93(sgiwd93_host);
+#endif
+ cli();
+ romvec->halt();
+}
+
+void prom_powerdown(void)
+{
+ shutoff_r4600_cache();
+ initialize_kbd();
+#if CONFIG_SCSI_SGIWD93
+ reset_wd33c93(sgiwd93_host);
+#endif
+ cli();
+ romvec->pdown();
+}
+
+/* XXX is this a soft reset basically? XXX */
+void prom_restart(void)
+{
+ shutoff_r4600_cache();
+ initialize_kbd();
+#if CONFIG_SCSI_SGIWD93
+ reset_wd33c93(sgiwd93_host);
+#endif
+ cli();
+ romvec->restart();
+}
+
+void prom_reboot(void)
+{
+ shutoff_r4600_cache();
+ initialize_kbd();
+#if CONFIG_SCSI_SGIWD93
+ reset_wd33c93(sgiwd93_host);
+#endif
+ cli();
+ romvec->reboot();
+}
+
+void prom_imode(void)
+{
+ shutoff_r4600_cache();
+ initialize_kbd();
+#if CONFIG_SCSI_SGIWD93
+ reset_wd33c93(sgiwd93_host);
+#endif
+ cli();
+ romvec->imode();
+}
+
+long prom_cfgsave(void)
+{
+ return romvec->cfg_save();
+}
+
+struct linux_sysid *prom_getsysid(void)
+{
+ return romvec->get_sysid();
+}
+
+void prom_cacheflush(void)
+{
+ romvec->cache_flush();
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/printf.c linux/arch/mips/sgi/prom/printf.c
--- v2.1.43/linux/arch/mips/sgi/prom/printf.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/printf.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,34 @@
+/* $Id: printf.c,v 1.1 1997/06/06 09:37:17 ralf Exp $
+ * printf.c: Putting things on the screen using SGI arcs
+ * PROM facilities.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@sgi.com)


+ */
+
+#include <linux/kernel.h>
+

+#include <asm/sgialib.h>
+
+static char ppbuf[1024];
+
+void
+prom_printf(char *fmt, ...)
+{
+ va_list args;
+ char ch, *bptr;
+ int i;
+
+ va_start(args, fmt);
+ i = vsprintf(ppbuf, fmt, args);
+
+ bptr = ppbuf;
+
+ while((ch = *(bptr++)) != 0) {
+ if(ch == '\n')
+ prom_putchar('\r');
+
+ prom_putchar(ch);
+ }
+ va_end(args);
+ return;
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/salone.c linux/arch/mips/sgi/prom/salone.c
--- v2.1.43/linux/arch/mips/sgi/prom/salone.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/salone.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,24 @@
+/* $Id: salone.c,v 1.1 1997/06/06 09:37:20 ralf Exp $
+ * salone.c: Routines to load into memory and execute stand-along
+ * program images using ARCS PROM firmware.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+
+#include <asm/sgialib.h>
+
+long prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr)
+{
+ return romvec->load(name, end, pc, eaddr);
+}
+
+long prom_invoke(unsigned long pc, unsigned long sp, long argc,
+ char **argv, char **envp)
+{
+ return romvec->invoke(pc, sp, argc, argv, envp);
+}
+
+long prom_exec(char *name, long argc, char **argv, char **envp)
+{
+ return romvec->exec(name, argc, argv, envp);
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/tags.c linux/arch/mips/sgi/prom/tags.c
--- v2.1.43/linux/arch/mips/sgi/prom/tags.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/tags.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,67 @@
+/* $Id: tags.c,v 1.1 1997/06/06 09:37:22 ralf Exp $
+ * tags.c: Initialize the arch tags the way the MIPS kernel setup
+ * expects.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/addrspace.h>
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+#include <asm/sgimc.h>
+
+/* XXX This tag thing is a fucking rats nest, I'm very inclined to completely
+ * XXX rework the MIPS people's multi-arch code _NOW_.
+ */
+
+static unsigned long machtype_SGI_INDY = MACH_SGI_INDY;
+static unsigned long machgroup_SGI = MACH_GROUP_SGI;
+static unsigned long memlower_SGI_INDY = (KSEG0 + SGIMC_SEG0_BADDR);
+static unsigned long cputype_SGI_INDY = CPU_R4400SC;
+static unsigned long tlb_entries_SGI_INDY = 48;
+static unsigned long dummy_SGI_INDY = 0;
+static struct drive_info_struct dummy_dinfo_SGI_INDY = { { 0, }, };
+char arcs_cmdline[CL_SIZE];
+
+#define TAG(t,l) {tag_##t,(l)} /* XXX RATS NEST CODE!!! XXX */
+#define TAGVAL(v) (void*)&(v) /* XXX FUCKING LOSING!!! XXX */
+
+tag_def taglist_sgi_indy[] = {
+ {TAG(machtype, ULONGSIZE), TAGVAL(machtype_SGI_INDY)},
+ {TAG(machgroup, ULONGSIZE), TAGVAL(machgroup_SGI)},
+ {TAG(memlower, ULONGSIZE), TAGVAL(memlower_SGI_INDY)},
+ {TAG(cputype, ULONGSIZE), TAGVAL(cputype_SGI_INDY)},
+ {TAG(tlb_entries, ULONGSIZE), TAGVAL(tlb_entries_SGI_INDY)},
+ {TAG(vram_base, ULONGSIZE), TAGVAL(dummy_SGI_INDY)},
+ {TAG(drive_info, DRVINFOSIZE), TAGVAL(dummy_dinfo_SGI_INDY)},
+ {TAG(mount_root_rdonly, ULONGSIZE), TAGVAL(dummy_SGI_INDY)},
+ {TAG(command_line, CL_SIZE), TAGVAL(arcs_cmdline[0])},
+ {TAG(dummy, 0), NULL}
+ /* XXX COLOSTOMY BAG!!!! XXX */
+};
+
+void prom_setup_archtags(void)
+{
+ tag_def *tdp = &taglist_sgi_indy[0];
+ tag *tp;
+
+ tp = (tag *) (mips_memory_upper - sizeof(tag));
+ while(tdp->t.tag != tag_dummy) {
+ unsigned long size;
+ char *d;
+
+ *tp = tdp->t;
+ size = tp->size;
+ d = (char *) tdp->d;
+ tp = (tag *)(((unsigned long)tp) - (tp->size));
+ if(size)
+ memcpy(tp, d, size);
+
+ tp--;
+ tdp++;
+ }
+ *tp = tdp->t; /* copy last dummy element over */
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/time.c linux/arch/mips/sgi/prom/time.c
--- v2.1.43/linux/arch/mips/sgi/prom/time.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/time.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,17 @@
+/* $Id: time.c,v 1.1 1997/06/06 09:37:26 ralf Exp $
+ * time.c: Extracting time information from ARCS prom.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+
+#include <asm/sgialib.h>
+
+struct linux_tinfo *prom_gettinfo(void)
+{
+ return romvec->get_tinfo();
+}
+
+unsigned long prom_getrtime(void)
+{
+ return romvec->get_rtime();
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/prom/tree.c linux/arch/mips/sgi/prom/tree.c
--- v2.1.43/linux/arch/mips/sgi/prom/tree.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/prom/tree.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,107 @@
+/* $Id: tree.c,v 1.1 1997/06/06 09:37:29 ralf Exp $
+ * tree.c: PROM component device tree code.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+
+#include <asm/sgialib.h>
+
+#define DEBUG_PROM_TREE
+
+pcomponent *prom_getsibling(pcomponent *this)
+{
+ if(this == PROM_NULL_COMPONENT)
+ return PROM_NULL_COMPONENT;
+ return romvec->next_component(this);
+}
+
+pcomponent *prom_getchild(pcomponent *this)
+{
+ return romvec->child_component(this);
+}
+
+pcomponent *prom_getparent(pcomponent *child)
+{
+ if(child == PROM_NULL_COMPONENT)
+ return PROM_NULL_COMPONENT;
+ return romvec->parent_component(child);
+}
+
+long prom_getcdata(void *buffer, pcomponent *this)
+{
+ return romvec->component_data(buffer, this);
+}
+
+pcomponent *prom_childadd(pcomponent *this, pcomponent *tmp, void *data)
+{
+ return romvec->child_add(this, tmp, data);
+}
+
+long prom_delcomponent(pcomponent *this)
+{
+ return romvec->comp_del(this);
+}
+
+pcomponent *prom_componentbypath(char *path)
+{
+ return romvec->component_by_path(path);
+}
+
+#ifdef DEBUG_PROM_TREE
+static char *classes[] = {
+ "system", "processor", "cache", "adapter", "controller", "peripheral",
+ "memory"
+};
+
+static char *types[] = {
+ "arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache", "sccache",
+ "memdev", "eisa adapter", "tc adapter", "scsi adapter", "dti adapter",
+ "multi-func adapter", "disk controller", "tp controller",
+ "cdrom controller", "worm controller", "serial controller",
+ "net controller", "display controller", "parallel controller",
+ "pointer controller", "keyboard controller", "audio controller",
+ "misc controller", "disk peripheral", "floppy peripheral",
+ "tp peripheral", "modem peripheral", "monitor peripheral",
+ "printer peripheral", "pointer peripheral", "keyboard peripheral",
+ "terminal peripheral", "line peripheral", "net peripheral",
+ "misc peripheral", "anonymous"
+};
+
+static char *iflags[] = {
+ "bogus", "read only", "removable", "console in", "console out",
+ "input", "output"
+};
+
+static void dump_component(pcomponent *p)
+{
+ prom_printf("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>",
+ p, classes[p->class], types[p->type],
+ iflags[p->iflags], p->vers, p->rev);
+ prom_printf("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n",
+ p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname);
+}
+
+static void traverse(pcomponent *p, int op)
+{
+ dump_component(p);
+ if(prom_getchild(p))
+ traverse(prom_getchild(p), 1);
+ if(prom_getsibling(p) && op)
+ traverse(prom_getsibling(p), 1);
+}
+
+void prom_testtree(void)
+{
+ pcomponent *p;
+
+ p = prom_getchild(PROM_NULL_COMPONENT);
+ dump_component(p);
+ p = prom_getchild(p);
+ while(p) {
+ dump_component(p);
+ p = prom_getsibling(p);
+ }
+ prom_printf("press a key\n");
+ prom_getchar();
+}
+#endif
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sni/Makefile linux/arch/mips/sni/Makefile
--- v2.1.43/linux/arch/mips/sni/Makefile Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sni/Makefile Thu Jun 26 12:33:38 1997
@@ -0,0 +1,22 @@
+#
+# Makefile for the SNI specific part of the kernel


+#
+# 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).
+#
+
+.S.s:

+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: sni.o
+O_TARGET := sni.o
+O_OBJS := hw-access.o int-handler.o io.o pci.o reset.o setup.o


+
+int-handler.o: int-handler.S
+
+clean:
+

+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sni/hw-access.c linux/arch/mips/sni/hw-access.c
--- v2.1.43/linux/arch/mips/sni/hw-access.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sni/hw-access.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,159 @@
+/*
+ * Low-level hardware access stuff for SNI RM200 PCI


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.

+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ */


+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/types.h>

+#include <linux/mm.h>
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mc146818rtc.h>
+#include <asm/pgtable.h>


+#include <asm/vector.h>
+
+extern int FLOPPY_IRQ;
+extern int FLOPPY_DMA;
+

+/*
+ * How to access the FDC's registers.
+ */
+static unsigned char
+fd_inb(unsigned int port)
+{
+ return inb_p(port);
+}
+
+static void
+fd_outb(unsigned char value, unsigned int port)
+{
+ outb_p(value, port);

+}
+
+/*

+sni_fd_cacheflush(const void *addr, size_t size)
+{
+ flush_cache_all();
+}
+
+/*
+ * RTC stuff (This is a guess on how the RM handles this ...)


+ */
+static unsigned char

+rtc_read_data(unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ return inb_p(RTC_PORT(1));
+}
+
+static void
+rtc_write_data(unsigned char data, unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ outb_p(data, RTC_PORT(1));
+}
+
+struct feature sni_rm200_pci_feature = {


+ /*
+ * How to access the floppy controller's ports
+ */
+ fd_inb,

+ fd_outb,
+ /*


+ * How to access the floppy DMA functions.
+ */
+ fd_enable_dma,
+ fd_disable_dma,
+ fd_request_dma,
+ fd_free_dma,
+ fd_clear_dma_ff,
+ fd_set_dma_mode,
+ fd_set_dma_addr,
+ fd_set_dma_count,
+ fd_get_dma_residue,
+ fd_enable_irq,
+ fd_disable_irq,
+ /*
+ * How to access the RTC functions.
+ */
+ rtc_read_data,
+ rtc_write_data

+};
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sni/int-handler.S linux/arch/mips/sni/int-handler.S
--- v2.1.43/linux/arch/mips/sni/int-handler.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sni/int-handler.S Thu Jun 26 12:33:38 1997
@@ -0,0 +1,174 @@
+/*
+ * SNI RM200 PCI specific interrupt handler code.
+ *
+ * Copyright (C) 1994 - 1997 by Ralf Baechle
+ */
+#include <asm/asm.h>
+#include <linux/config.h>
+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/sni.h>
+#include <asm/stackframe.h>


+
+ .set noreorder
+ .set noat

+ .align 5
+ NESTED(sni_rm200_pci_handle_int, PT_SIZE, sp)


+ SAVE_ALL
+ REG_S sp,PT_OR2(sp)
+ CLI

+ /*
+ * Asume we received an interrupt from the PCI ASIC.
+ */
+ .set at
+ lui s0,%hi(SNI_PORT_BASE)
+ li a0,0x0f
+ sb a0,%lo(SNI_PORT_BASE+0x20)(s0) # poll command
+ lb a0,%lo(SNI_PORT_BASE+0x20)(s0) # read result


+ bgtz a0,poll_second
+ andi a0,7
+ beq a0,2,poll_second # cascade?
+ li s1,1 # delay slot
+ /*
+ * Acknowledge first pic
+ */

+ lb t2,%lo(SNI_PORT_BASE+0x21)(s0)


+ lui s4,%hi(cache_21)
+ lb t0,%lo(cache_21)(s4)
+ sllv s1,s1,a0
+ or t0,s1
+ sb t0,%lo(cache_21)(s4)

+ sb t0,%lo(SNI_PORT_BASE+0x21)(s0)
+ li t2,0x20
+ sb t2,%lo(SNI_PORT_BASE+0x20)(s0)
+ /*


+ * Now call the real handler
+ */
+ la t3,IRQ_vectors
+ sll t2,a0,PTRLOG
+ addu t3,t2
+ LONG_L t3,(t3)
+ jalr t3

+ nop # delay slot

+ /*
+ * Unblock first pic
+ */

+ lbu t1,%lo(SNI_PORT_BASE+0x21)(s0)


+ lb t1,%lo(cache_21)(s4)
+ nor s1,zero,s1
+ and t1,s1
+ sb t1,%lo(cache_21)(s4)
+ jr v0

+ sb t1,%lo(SNI_PORT_BASE+0x21)(s0) # delay slot
+


+ /*
+ * Cascade interrupt from second PIC
+ */
+ .align 5
+poll_second: li a0,0x0f

+ sb a0,%lo(SNI_PORT_BASE+0xa0)(s0) # poll command
+ lb a0,%lo(SNI_PORT_BASE+0xa0)(s0) # read result


+ bgtz a0,3f
+ andi a0,7
+ /*
+ * Acknowledge second pic
+ */

+ lbu t2,%lo(SNI_PORT_BASE+0xa1)(s0)


+ lui s4,%hi(cache_A1)
+ lb t3,%lo(cache_A1)(s4)
+ sllv s1,s1,a0
+ or t3,s1
+ sb t3,%lo(cache_A1)(s4)

+ sb t3,%lo(SNI_PORT_BASE+0xa1)(s0)
+ li t3,0x20
+ sb t3,%lo(SNI_PORT_BASE+0xa0)(s0)
+ sb t3,%lo(SNI_PORT_BASE+0x20)(s0)
+ /*


+ * Now call the real handler
+ */
+ la t3,IRQ_vectors
+ addiu a0,8
+ sll t2,a0,PTRLOG
+ addu t3,t2
+ LONG_L t3,(t3)
+ jalr t3

+ nop # delay slot

+ /*
+ * Unblock second pic
+ */

+ lb t1,%lo(SNI_PORT_BASE+0xa1)(s0)
+ lb t1,%lo(cache_A1)(s4)
+ subu t0,1


+ nor s1,zero,s1
+ and t1,t1,s1
+ sb t1,%lo(cache_A1)(s4)
+ jr v0

+ sb t1,%lo(SNI_PORT_BASE+0xa1)(s0) # delay slot
+
+/*
+ * FIXME: This is definatly wrong but I'll have to do it this way
+ * 'till I get more hardware info.
+ * XXX: Apparently the Lance is attached to interrupt #5.
+ */
+#ifdef CONFIG_PCNET32
+
+/*
+ * FIXME: detect this address
+ */
+#define LANCE_BASE 0xbb000100
+
+/* Offsets from base I/O address. */
+#define LANCE_DATA 0x10
+#define LANCE_ADDR 0x12
+#define LANCE_RESET 0x14
+#define LANCE_BUS_IF 0x16
+#define LANCE_TOTAL_SIZE 0x18
+
+/*
+ * ... check if we were interrupted by the Lance ...
+ */
+3: lh s0,LANCE_BASE+LANCE_ADDR
+ sh zero,LANCE_BASE+LANCE_ADDR
+ lh t1,LANCE_BASE+LANCE_DATA
+ andi t2,t1,0x80
+ beqz t1,3f # no Lance interrupt?
+ mfc0 t0,CP0_STATUS # delay slot
+ ori t0,0x041f
+ xori t0,0x041e
+ mtc0 t0,CP0_STATUS
+ li a0,PCIMT_IRQ_ETHERNET
+ jal do_IRQ
+ move a1,sp # delay slot
+ sh s0,LANCE_BASE+LANCE_ADDR
+ mfc0 t0,CP0_STATUS
+ ori t0,0x0401
+ xori t0,0x0001
+ mtc0 t0,CP0_STATUS
+ j ret_from_sys_call


+ nop # delay slot
+

+#endif /* CONFIG_PCNET32 */
+
+#ifdef CONFIG_SCSI_NCR53C8XX
+
+/*
+ * ... check if we were interrupted by the NCR ...
+ */
+3: lb t0,PCIMT_CSITPEND
+ andi t0,0x40
+ bnez t0,3f # bit 6 == 0 -> SCSI IRQ


+ nop # delay slot

+ jal do_fast_IRQ
+ li a0,PCIMT_IRQ_SCSI # delay slot
+ j return


+ nop # delay slot
+

+#endif /* CONFIG_SCSI_NCR53C8XX */
+
+/*


+ * "Jump extender" to reach spurious_interrupt
+ */
+3: j spurious_interrupt

+ nop # delay slot

+ END(sni_rm200_pci_handle_int)
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sni/io.c linux/arch/mips/sni/io.c
--- v2.1.43/linux/arch/mips/sni/io.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sni/io.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,172 @@
+/*


+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * Low level I/O functions for SNI.


+ */
+#include <linux/string.h>
+#include <asm/mipsconfig.h>
+#include <asm/addrspace.h>

+#include <asm/system.h>
+#include <asm/spinlock.h>
+#include <asm/sni.h>
+
+unsigned char sni_map_isa_cache;
+
+#define unused __attribute__((unused))
+
+/*
+ * The PCIMT_CSMAPISA is shared by all processors; we need locking.
+ *
+ * XXX It's legal to use all the I/O memory access functions in interrupt
+ * code, so we need to use the _irq locking stuff which may result in
+ * significant IRQ latencies.
+ */
+static spinlock_t csmapisa_lock unused = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Urgs... We only can see a 16mb window of the 4gb EISA address space
+ * at PCIMT_EISA_BASE. Maladia segmentitis ...
+ *
+ * XXX Check out if accessing PCIMT_CSMAPISA really is slow.
+ * For now assume so.
+ */
+static inline void update_isa_cache(unsigned long address)
+{
+ unsigned char upper;
+
+ upper = address >> 24;
+ if (sni_map_isa_cache != upper) {
+ sni_map_isa_cache = upper;
+ *(volatile unsigned char *)PCIMT_CSMAPISA = ~upper;
+ }
+}
+
+static unsigned char sni_readb(unsigned long addr)
+{
+ unsigned char res;
+
+ spin_lock_irq(&csmapisa_lock);
+ update_isa_cache(addr);
+ addr &= 0xffffff;
+ res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
+ spin_unlock_irq(&csmapisa_lock);
+
+ return res;
+}
+
+static unsigned short sni_readw(unsigned long addr)
+{
+ unsigned short res;
+
+ spin_lock_irq(&csmapisa_lock);
+ update_isa_cache(addr);
+ addr &= 0xffffff;
+ res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
+ spin_unlock_irq(&csmapisa_lock);
+
+ return res;
+}
+
+static unsigned int sni_readl(unsigned long addr)
+{
+ unsigned int res;
+
+ spin_lock_irq(&csmapisa_lock);
+ update_isa_cache(addr);
+ addr &= 0xffffff;
+ res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
+ spin_unlock_irq(&csmapisa_lock);
+
+ return res;
+}
+
+static void sni_writeb(unsigned char val, unsigned long addr)
+{
+ spin_lock_irq(&csmapisa_lock);
+ update_isa_cache(addr);
+ addr &= 0xffffff;
+ *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
+ spin_unlock_irq(&csmapisa_lock);
+}
+
+static void sni_writew(unsigned short val, unsigned long addr)
+{
+ spin_lock_irq(&csmapisa_lock);
+ update_isa_cache(addr);
+ addr &= 0xffffff;
+ *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
+ spin_unlock_irq(&csmapisa_lock);
+}
+
+static void sni_writel(unsigned int val, unsigned long addr)
+{
+ spin_lock_irq(&csmapisa_lock);
+ update_isa_cache(addr);
+ addr &= 0xffffff;
+ *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
+ spin_unlock_irq(&csmapisa_lock);
+}
+
+static void sni_memset_io(unsigned long addr, int val, unsigned long len)
+{
+ unsigned long waddr;
+
+ waddr = PCIMT_EISA_BASE | (addr & 0xffffff);
+ spin_lock_irq(&csmapisa_lock);
+ while(len) {
+ unsigned long fraglen;
+
+ fraglen = (~addr + 1) & 0xffffff;
+ fraglen = (fraglen < len) ? fraglen : len;
+ update_isa_cache(addr);
+ memset((char *)waddr, val, fraglen);
+ addr += fraglen;
+ waddr = waddr + fraglen - 0x1000000;
+ len -= fraglen;
+ }
+ spin_unlock_irq(&csmapisa_lock);
+}
+
+static void sni_memcpy_fromio(unsigned long to, unsigned long from, unsigned long len)
+{
+ unsigned long waddr;
+
+ waddr = PCIMT_EISA_BASE | (from & 0xffffff);
+ spin_lock_irq(&csmapisa_lock);
+ while(len) {
+ unsigned long fraglen;
+
+ fraglen = (~from + 1) & 0xffffff;
+ fraglen = (fraglen < len) ? fraglen : len;
+ update_isa_cache(from);
+ memcpy((void *)to, (void *)waddr, fraglen);
+ to += fraglen;
+ from += fraglen;
+ waddr = waddr + fraglen - 0x1000000;
+ len -= fraglen;
+ }
+ spin_unlock_irq(&csmapisa_lock);
+}
+
+static void sni_memcpy_toio(unsigned long to, unsigned long from, unsigned long len)
+{
+ unsigned long waddr;
+
+ waddr = PCIMT_EISA_BASE | (to & 0xffffff);
+ spin_lock_irq(&csmapisa_lock);
+ while(len) {
+ unsigned long fraglen;
+
+ fraglen = (~to + 1) & 0xffffff;
+ fraglen = (fraglen < len) ? fraglen : len;
+ update_isa_cache(to);
+ memcpy((char *)to + PCIMT_EISA_BASE, (void *)from, fraglen);
+ to += fraglen;
+ from += fraglen;
+ waddr = waddr + fraglen - 0x1000000;
+ len -= fraglen;
+ }
+ spin_unlock_irq(&csmapisa_lock);
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sni/pci.c linux/arch/mips/sni/pci.c
--- v2.1.43/linux/arch/mips/sni/pci.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sni/pci.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,135 @@
+/*


+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * SNI specific PCI support for RM200/RM300.
+ */
+#include <linux/config.h>
+#include <linux/bios32.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/pci.h>
+#include <asm/sni.h>
+
+#ifdef CONFIG_PCI
+
+extern inline u32 mkaddr(unsigned char bus, unsigned char dev_fn,
+ unsigned char where)
+{
+ return ((bus & 0xff) << 0x10) |
+ ((dev_fn & 0xff) << 0x08) |
+ (where & 0xfc);
+}
+
+static unsigned long sni_rm200_pcibios_fixup (unsigned long memory_start,
+ unsigned long memory_end)
+{
+ /*
+ * TODO: Fix PCI_INTERRUPT_LINE register for onboard cards.
+ * Take care of RM300 revision D boards for where the network
+ * slot became an ordinary PCI slot.
+ */
+ return memory_start;
+}
+
+/*
+ * We can't address 8 and 16 bit words directly. Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 17'
echo 'File patch-2.1.44 is continued in part 18'
echo 18 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part18

#!/bin/sh
# this is part 18 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 18; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

+ */
+static int sni_rm200_pcibios_read_config_byte (unsigned char bus,
+ unsigned char dev_fn,
+ unsigned char where,
+ unsigned char *val)
+{
+ u32 res;
+
+ *(volatile u32 *)PCIMT_CONFIG_ADDRESS = mkaddr(bus, dev_fn, where);
+ res = *(volatile u32 *)PCIMT_CONFIG_DATA;
+ res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff;
+ *val = res;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int sni_rm200_pcibios_read_config_word (unsigned char bus,
+ unsigned char dev_fn,
+ unsigned char where,
+ unsigned short *val)
+{
+ u32 res;
+
+ if (where & 1)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ *(volatile u32 *)PCIMT_CONFIG_ADDRESS = mkaddr(bus, dev_fn, where);
+ res = *(volatile u32 *)PCIMT_CONFIG_DATA;
+ res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff;
+ *val = res;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int sni_rm200_pcibios_read_config_dword (unsigned char bus,
+ unsigned char dev_fn,
+ unsigned char where,
+ unsigned int *val)
+{
+ u32 res;
+
+ if (where & 3)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ *(volatile u32 *)PCIMT_CONFIG_ADDRESS = mkaddr(bus, dev_fn, where);
+ res = *(volatile u32 *)PCIMT_CONFIG_DATA;
+ res = le32_to_cpu(res);
+ *val = res;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int sni_rm200_pcibios_write_config_byte (unsigned char bus,
+ unsigned char dev_fn,
+ unsigned char where,
+ unsigned char val)
+{
+ /* To do */
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int sni_rm200_pcibios_write_config_word (unsigned char bus,
+ unsigned char dev_fn,
+ unsigned char where,
+ unsigned short val)
+{
+ /* To do */
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int sni_rm200_pcibios_write_config_dword (unsigned char bus,
+ unsigned char dev_fn,
+ unsigned char where,
+ unsigned int val)
+{
+ if (where & 3)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ *(volatile u32 *)PCIMT_CONFIG_ADDRESS = mkaddr(bus, dev_fn, where);
+ *(volatile u32 *)PCIMT_CONFIG_DATA = le32_to_cpu(val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+__initfunc(unsigned long sni_rm200_pcibios_init(unsigned long memory_start, unsigned long memory_end))
+{
+ _pcibios_fixup = sni_rm200_pcibios_fixup;
+ _pcibios_read_config_byte = sni_rm200_pcibios_read_config_byte;
+ _pcibios_read_config_word = sni_rm200_pcibios_read_config_word;
+ _pcibios_read_config_dword = sni_rm200_pcibios_read_config_dword;
+ _pcibios_write_config_byte = sni_rm200_pcibios_write_config_byte;
+ _pcibios_write_config_word = sni_rm200_pcibios_write_config_word;
+ _pcibios_write_config_dword = sni_rm200_pcibios_write_config_dword;
+


+ return memory_start;
+}
+

+#endif /* CONFIG_PCI */
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sni/reset.c linux/arch/mips/sni/reset.c
--- v2.1.43/linux/arch/mips/sni/reset.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sni/reset.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,51 @@
+/*
+ * linux/arch/mips/sni/process.c
+ *
+ * Reset a SNI machine.
+ */
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/sni.h>
+
+/*
+ * 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.


+ */
+static inline void

+kb_wait(void)


+{
+ int i;
+

+ for (i=0; i<0x10000; i++)
+ if ((inb_p(0x64) & 0x02) == 0)
+ break;
+}
+
+/* XXX This ends up at the ARC firmware prompt ... */
+void sni_machine_restart(char *command)


+{
+ int i, j;
+

+ /* This does a normal via the keyboard controller like a PC.
+ We can do that easier ... */
+ sti();
+ for (;;) {
+ for (i=0; i<100; i++) {
+ kb_wait();
+ for(j = 0; j < 100000 ; j++)
+ /* nothing */;
+ outb_p(0xfe,0x64); /* pulse reset low */
+ }
+ }
+}
+
+void sni_machine_halt(void)
+{
+}
+
+void sni_machine_power_off(void)
+{
+ *(volatile unsigned char *)PCIMT_CSWCSM = 0xfd;
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sni/setup.c linux/arch/mips/sni/setup.c
--- v2.1.43/linux/arch/mips/sni/setup.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sni/setup.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,158 @@
+/*
+ * Setup pointers to hardware dependand routines.
+ *


+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * Copyright (C) 1996, 1997 by Ralf Baechle
+ */
+#include <asm/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/pci.h>


+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>

+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/sni.h>
+#include <asm/vector.h>
+#include <asm/pci.h>


+
+/*
+ * Initial irq handlers.
+ */
+static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+/*
+ * IRQ2 is cascade interrupt to second interrupt controller
+ */
+static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL};
+

+extern asmlinkage void sni_rm200_pci_handle_int(void);
+extern asmlinkage void sni_fd_cacheflush(const void *addr, size_t size);
+extern struct feature sni_rm200_pci_feature;
+
+extern void sni_machine_restart(char *command);
+extern void sni_machine_halt(void);
+extern void sni_machine_power_off(void);
+
+__initfunc(static void sni_irq_setup(void))
+{
+ set_except_vector(0, sni_rm200_pci_handle_int);


+ request_region(0x20,0x20, "pic1");
+ request_region(0xa0,0x20, "pic2");
+ setup_x86_irq(2, &irq2);

+ /*
+ * IRQ0 seems to be the irq for PC style stuff.
+ * I don't know how to handle the debug button interrupt, so
+ * don't use this button yet or bad things happen ...
+ */
+ set_cp0_status(ST0_IM, IE_IRQ0);


+}
+
+void (*board_time_init)(struct irqaction *irq);
+

+__initfunc(static void sni_rm200_pci_time_init(struct irqaction *irq))
+{


+ /* set the clock to 100 Hz */
+ outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
+ outb_p(LATCH & 0xff , 0x40); /* LSB */
+ outb(LATCH >> 8 , 0x40); /* MSB */

+ setup_x86_irq(0, irq);
+}
+
+unsigned char aux_device_present;
+extern unsigned long sni_rm200_pcibios_init (unsigned long memory_start,
+ unsigned long memory_end);
+extern unsigned char sni_map_isa_cache;
+
+/*
+ * A bit more gossip about the iron we're running on ...
+ */
+static inline void sni_pcimt_detect(void)
+{
+ char boardtype[80];
+ unsigned char csmsr;
+ char *p = boardtype;
+ int asic;
+
+ csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
+
+ p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300");
+ if ((csmsr & 0x80) == 0)
+ p += sprintf(p, ", board revision %s",
+ (csmsr & 0x20) ? "D" : "C");
+ asic = csmsr & 0x80;
+ asic = (csmsr & 0x08) ? asic : !asic;
+ p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1");
+ printk("%s.\n", boardtype);
+}
+
+__initfunc(void sni_rm200_pci_setup(void))
+{
+ tag *atag;
+
+ /*
+ * We just check if a tag_screen_info can be gathered
+ * in setup_arch(), if yes we don't proceed futher...
+ */
+ atag = bi_TagFind(tag_screen_info);
+ if (!atag) {
+ /*
+ * If no, we try to find the tag_arc_displayinfo which is
+ * always created by Milo for an ARC box (for now Milo only
+ * works on ARC boxes :) -Stoned.
+ */
+ atag = bi_TagFind(tag_arcdisplayinfo);
+ if (atag) {
+ screen_info.orig_x =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->cursor_x;
+ screen_info.orig_y =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->cursor_y;
+ screen_info.orig_video_cols =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->columns;
+ screen_info.orig_video_lines =
+ ((mips_arc_DisplayInfo*)TAGVALPTR(atag))->lines;
+ }
+ }
+
+ sni_pcimt_detect();
+
+ irq_setup = sni_irq_setup;
+ fd_cacheflush = sni_fd_cacheflush; // Will go away
+ feature = &sni_rm200_pci_feature;
+ port_base = SNI_PORT_BASE;
+
+ /*
+ * Setup (E)ISA I/O memory access stuff
+ */
+ isa_slot_offset = 0xb0000000;
+ // sni_map_isa_cache = 0;


+ EISA_bus = 1;
+

+ request_region(0x00,0x20,"dma1");
+ request_region(0x40,0x20,"timer");

+ /* XXX FIXME: CONFIG_RTC */


+ request_region(0x70,0x10,"rtc");
+ request_region(0x80,0x10,"dma page reg");
+ request_region(0xc0,0x20,"dma2");

+ board_time_init = sni_rm200_pci_time_init;
+
+ _machine_restart = sni_machine_restart;
+ _machine_halt = sni_machine_halt;
+ _machine_power_off = sni_machine_power_off;
+
+ aux_device_present = 0xaa;
+
+ /*
+ * Some cluefull person has placed the PCI config data directly in
+ * the I/O port space ...
+ */
+ request_region(0xcfc,0x04,"PCI config data");
+ _pcibios_init = sni_rm200_pcibios_init;
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/tools/Makefile linux/arch/mips/tools/Makefile
--- v2.1.43/linux/arch/mips/tools/Makefile Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/tools/Makefile Thu Jun 26 12:33:38 1997
@@ -0,0 +1,26 @@
+# Makefile for MIPS kernel build tools.
+#
+# Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+# Copyright (C) 1997 Ralf Baechle (ra...@gnu.ai.mit.edu)
+#
+TARGET := $(TOPDIR)/include/asm-$(ARCH)/offset.h


+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+

+all: $(TARGET)
+
+$(TARGET): offset.h
+ cmp -s $^ $@ || (cp $^ $(TARGET).new && mv $(TARGET).new $(TARGET))
+
+offset.h: offset.s
+ sed -n '/^@@@/s///p' $^ >$@
+
+offset.s: offset.c
+
+clean:
+ rm -f offset.s $(TARGET).new
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.43/linux/arch/mips/tools/offset.c linux/arch/mips/tools/offset.c
--- v2.1.43/linux/arch/mips/tools/offset.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/tools/offset.c Mon Jul 7 08:18:54 1997
@@ -0,0 +1,147 @@
+/*
+ * offset.c: Calculate pt_regs and task_struct offsets.


+ *
+ * Copyright (C) 1996 David S. Miller

+ * Made portable by Ralf Baechle
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+
+#define text(t) __asm__("\n@@@" t)
+#define _offset(type, member) (&(((type *)NULL)->member))
+
+#define offset(string, ptr, member) \
+ __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)))
+#define size(string, size) \
+ __asm__("\n@@@" string "%0" : : "i" (sizeof(size)))
+#define linefeed text("")
+
+text("/* DO NOT TOUCH, AUTOGENERATED BY OFFSET.C */");
+text("");
+text("#ifndef _MIPS_OFFSET_H");
+text("#define _MIPS_OFFSET_H");
+text("");
+
+void output_ptreg_defines(void)
+{
+ text("/* MIPS pt_regs offsets. */");
+ offset("#define PT_R0 ", struct pt_regs, regs[0]);
+ offset("#define PT_R1 ", struct pt_regs, regs[1]);
+ offset("#define PT_R2 ", struct pt_regs, regs[2]);
+ offset("#define PT_R3 ", struct pt_regs, regs[3]);
+ offset("#define PT_R4 ", struct pt_regs, regs[4]);
+ offset("#define PT_R5 ", struct pt_regs, regs[5]);
+ offset("#define PT_R6 ", struct pt_regs, regs[6]);
+ offset("#define PT_R7 ", struct pt_regs, regs[7]);
+ offset("#define PT_R8 ", struct pt_regs, regs[8]);
+ offset("#define PT_R9 ", struct pt_regs, regs[9]);
+ offset("#define PT_R10 ", struct pt_regs, regs[10]);
+ offset("#define PT_R11 ", struct pt_regs, regs[11]);
+ offset("#define PT_R12 ", struct pt_regs, regs[12]);
+ offset("#define PT_R13 ", struct pt_regs, regs[13]);
+ offset("#define PT_R14 ", struct pt_regs, regs[14]);
+ offset("#define PT_R15 ", struct pt_regs, regs[15]);
+ offset("#define PT_R16 ", struct pt_regs, regs[16]);
+ offset("#define PT_R17 ", struct pt_regs, regs[17]);
+ offset("#define PT_R18 ", struct pt_regs, regs[18]);
+ offset("#define PT_R19 ", struct pt_regs, regs[19]);
+ offset("#define PT_R20 ", struct pt_regs, regs[20]);
+ offset("#define PT_R21 ", struct pt_regs, regs[21]);
+ offset("#define PT_R22 ", struct pt_regs, regs[22]);
+ offset("#define PT_R23 ", struct pt_regs, regs[23]);
+ offset("#define PT_R24 ", struct pt_regs, regs[24]);
+ offset("#define PT_R25 ", struct pt_regs, regs[25]);
+ offset("#define PT_R26 ", struct pt_regs, regs[26]);
+ offset("#define PT_R27 ", struct pt_regs, regs[27]);
+ offset("#define PT_R28 ", struct pt_regs, regs[28]);
+ offset("#define PT_R29 ", struct pt_regs, regs[29]);
+ offset("#define PT_R30 ", struct pt_regs, regs[30]);
+ offset("#define PT_R31 ", struct pt_regs, regs[31]);
+ offset("#define PT_LO ", struct pt_regs, lo);
+ offset("#define PT_HI ", struct pt_regs, hi);
+ offset("#define PT_OR2 ", struct pt_regs, orig_reg2);
+ offset("#define PT_OR7 ", struct pt_regs, orig_reg7);
+ offset("#define PT_EPC ", struct pt_regs, cp0_epc);
+ offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr);
+ offset("#define PT_STATUS ", struct pt_regs, cp0_status);
+ offset("#define PT_CAUSE ", struct pt_regs, cp0_cause);
+ size("#define PT_SIZE ", struct pt_regs);
+ linefeed;
+}
+
+void output_task_defines(void)
+{
+ text("/* MIPS task_struct offsets. */");
+ offset("#define TASK_STATE ", struct task_struct, state);
+ offset("#define TASK_COUNTER ", struct task_struct, counter);
+ offset("#define TASK_PRIORITY ", struct task_struct, priority);
+ offset("#define TASK_SIGNAL ", struct task_struct, signal);
+ offset("#define TASK_BLOCKED ", struct task_struct, blocked);
+ offset("#define TASK_FLAGS ", struct task_struct, flags);
+ offset("#define TASK_MM ", struct task_struct, mm);
+ linefeed;
+}
+
+void output_thread_defines(void)
+{
+ text("/* MIPS specific thread_struct offsets. */");
+ offset("#define THREAD_REG16 ", struct task_struct, tss.reg16);
+ offset("#define THREAD_REG17 ", struct task_struct, tss.reg17);
+ offset("#define THREAD_REG18 ", struct task_struct, tss.reg18);
+ offset("#define THREAD_REG19 ", struct task_struct, tss.reg19);
+ offset("#define THREAD_REG20 ", struct task_struct, tss.reg20);
+ offset("#define THREAD_REG21 ", struct task_struct, tss.reg21);
+ offset("#define THREAD_REG22 ", struct task_struct, tss.reg22);
+ offset("#define THREAD_REG23 ", struct task_struct, tss.reg23);
+ offset("#define THREAD_REG28 ", struct task_struct, tss.reg28);
+ offset("#define THREAD_REG29 ", struct task_struct, tss.reg29);
+ offset("#define THREAD_REG30 ", struct task_struct, tss.reg30);
+ offset("#define THREAD_REG31 ", struct task_struct, tss.reg31);
+ offset("#define THREAD_STATUS ", struct task_struct, tss.cp0_status);
+ offset("#define THREAD_FPU ", struct task_struct, tss.fpu);
+ offset("#define THREAD_BVADDR ", struct task_struct, tss.cp0_badvaddr);
+ offset("#define THREAD_ECODE ", struct task_struct, tss.error_code);
+ offset("#define THREAD_TRAPNO ", struct task_struct, tss.trap_no);
+ offset("#define THREAD_KSP ", struct task_struct, tss.ksp);
+ offset("#define THREAD_PGDIR ", struct task_struct, tss.pg_dir);
+ offset("#define THREAD_MFLAGS ", struct task_struct, tss.mflags);
+ offset("#define THREAD_CURDS ", struct task_struct, tss.current_ds);
+ offset("#define THREAD_TRAMP ", struct task_struct, tss.irix_trampoline);
+ offset("#define THREAD_OLDCTX ", struct task_struct, tss.irix_oldctx);
+ linefeed;
+}
+
+void output_mm_defines(void)
+{
+ text("/* Linux mm_struct offsets. */");
+ offset("#define MM_COUNT ", struct mm_struct, count);
+ offset("#define MM_PGD ", struct mm_struct, pgd);
+ offset("#define MM_CONTEXT ", struct mm_struct, context);
+ linefeed;
+}
+
+void output_sc_defines(void)
+{
+ text("/* Linux sigcontext offsets. */");
+ offset("#define SC_REGMASK ", struct sigcontext, sc_regmask);
+ offset("#define SC_STATUS ", struct sigcontext, sc_status);
+ offset("#define SC_PC ", struct sigcontext, sc_pc);
+ offset("#define SC_REGS ", struct sigcontext, sc_regs);
+ offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs);
+ offset("#define SC_OWNEDFP ", struct sigcontext, sc_ownedfp);
+ offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr);
+ offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir);
+ offset("#define SC_SSFLAGS ", struct sigcontext, sc_ssflags);
+ offset("#define SC_MDHI ", struct sigcontext, sc_mdhi);
+ offset("#define SC_MDLO ", struct sigcontext, sc_mdlo);
+ offset("#define SC_CAUSE ", struct sigcontext, sc_cause);
+ offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr);
+ offset("#define SC_SIGSET ", struct sigcontext, sc_sigset);
+ linefeed;
+}
+
+text("#endif /* !(_MIPS_OFFSET_H) */");
diff -u --recursive --new-file v2.1.43/linux/arch/sparc/config.in linux/arch/sparc/config.in
--- v2.1.43/linux/arch/sparc/config.in Mon Jun 16 16:35:54 1997
+++ linux/arch/sparc/config.in Thu Jun 26 12:33:38 1997
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.35 1997/04/07 06:54:09 davem Exp $
+# $Id: config.in,v 1.36 1997/06/17 03:54:47 davem Exp $
X # For a description of the syntax of this configuration file,


X # see the Configure script.
X #

diff -u --recursive --new-file v2.1.43/linux/arch/sparc/defconfig linux/arch/sparc/defconfig
--- v2.1.43/linux/arch/sparc/defconfig Mon Jun 16 16:35:54 1997
+++ linux/arch/sparc/defconfig Thu Jun 26 12:33:38 1997
@@ -64,6 +64,7 @@
X CONFIG_SYSCTL=y
X CONFIG_BINFMT_AOUT=y
X CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
X CONFIG_BINFMT_JAVA=m
X
X #
@@ -103,6 +104,7 @@
X # CONFIG_IP_MROUTE is not set
X CONFIG_IP_ALIAS=m
X # CONFIG_ARPD is not set


+# CONFIG_SYN_COOKIES is not set
X
X #
X # (it is safe to leave these untouched)

diff -u --recursive --new-file v2.1.43/linux/arch/sparc/kernel/cpu.c linux/arch/sparc/kernel/cpu.c
--- v2.1.43/linux/arch/sparc/kernel/cpu.c Fri Dec 13 01:37:30 1996
+++ linux/arch/sparc/kernel/cpu.c Mon Jul 7 08:18:54 1997
@@ -76,6 +76,7 @@
X { 0, 0, "Fujitsu MB86900/1A or LSI L64831 SparcKIT-40"},
X /* borned STP1012PGA */
X { 0, 4, "Fujitsu MB86904"},
+ { 0, 5, "Fujitsu TurboSparc MB86907"},
X /* SparcStation2, SparcServer 490 & 690 */
X { 1, 0, "LSI Logic Corporation - L64811"},
X /* SparcStation2 */
diff -u --recursive --new-file v2.1.43/linux/arch/sparc/kernel/sparc_ksyms.c linux/arch/sparc/kernel/sparc_ksyms.c
--- v2.1.43/linux/arch/sparc/kernel/sparc_ksyms.c Thu May 15 16:48:01 1997
+++ linux/arch/sparc/kernel/sparc_ksyms.c Mon Jul 7 08:18:54 1997
@@ -1,4 +1,4 @@
-/* $Id: sparc_ksyms.c,v 1.59 1997/05/08 17:45:20 davem Exp $
+/* $Id: sparc_ksyms.c,v 1.60 1997/06/17 13:25:13 jj Exp $
X * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
X *
X * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
@@ -59,6 +59,7 @@
X extern void *__memscan_generic(void *, int, size_t);
X extern int __memcmp(const void *, const void *, __kernel_size_t);
X extern int __strncmp(const char *, const char *, __kernel_size_t);
+extern char saved_command_line[];
X
X extern void bcopy (const char *, char *, int);
X extern int __ashrdi3(int, int);
@@ -200,7 +201,7 @@
X EXPORT_SYMBOL(prom_getproperty);
X EXPORT_SYMBOL(prom_node_has_property);
X EXPORT_SYMBOL(prom_setprop);
-EXPORT_SYMBOL(prom_getbootargs);
+EXPORT_SYMBOL(saved_command_line);
X EXPORT_SYMBOL(prom_apply_obio_ranges);
X EXPORT_SYMBOL(prom_getname);
X EXPORT_SYMBOL(prom_feval);
diff -u --recursive --new-file v2.1.43/linux/arch/sparc/mm/Makefile linux/arch/sparc/mm/Makefile
--- v2.1.43/linux/arch/sparc/mm/Makefile Thu May 15 16:48:02 1997
+++ linux/arch/sparc/mm/Makefile Mon Jul 7 08:18:54 1997
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.25 1997/05/03 05:09:11 davem Exp $
+# $Id: Makefile,v 1.26 1997/06/24 15:48:06 jj Exp $
X # Makefile for the linux Sparc-specific parts of the memory manager.
X #
X # Note! Dependencies are done automagically by 'make dep', which also
@@ -9,7 +9,8 @@


X
X O_TARGET := mm.o

X O_OBJS := fault.o init.o sun4c.o srmmu.o hypersparc.o viking.o \
- tsunami.o loadmmu.o generic.o asyncd.o extable.o
+ tsunami.o loadmmu.o generic.o asyncd.o extable.o \
+ turbosparc.o
X
X include $(TOPDIR)/Rules.make
X
@@ -18,6 +19,9 @@
X hypersparc.o: hypersparc.S
X $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o hypersparc.o hypersparc.S
X
+turbosparc.o: turbosparc.S
+ $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o turbosparc.o turbosparc.S
+
X viking.o: viking.S
X $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o viking.o viking.S
X
@@ -28,6 +32,9 @@
X
X hypersparc.o: hypersparc.S
X $(CC) -D__ASSEMBLY__ -ansi -c -o hypersparc.o hypersparc.S
+
+turbosparc.o: turbosparc.S
+ $(CC) -D__ASSEMBLY__ -ansi -c -o turbosparc.o turbosparc.S
X
X viking.o: viking.S
X $(CC) -D__ASSEMBLY__ -ansi -c -o viking.o viking.S
diff -u --recursive --new-file v2.1.43/linux/arch/sparc/mm/srmmu.c linux/arch/sparc/mm/srmmu.c
--- v2.1.43/linux/arch/sparc/mm/srmmu.c Thu May 29 21:53:04 1997
+++ linux/arch/sparc/mm/srmmu.c Mon Jul 7 08:18:54 1997
@@ -1,9 +1,10 @@
-/* $Id: srmmu.c,v 1.147 1997/05/20 07:58:42 jj Exp $
+/* $Id: srmmu.c,v 1.148 1997/06/24 15:48:02 jj Exp $
X * srmmu.c: SRMMU specific routines for memory management.
X *
X * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
X * Copyright (C) 1995 Peter A. Zaitcev (zai...@ithil.mcst.ru)
X * Copyright (C) 1996 Eddie C. Dost (e...@skynet.be)
+ * Copyright (C) 1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
X */
X
X #include <linux/config.h>
@@ -36,6 +37,7 @@
X #include <asm/ross.h>
X #include <asm/tsunami.h>
X #include <asm/swift.h>
+#include <asm/turbosparc.h>
X
X enum mbus_module srmmu_modtype;
X unsigned int hwbug_bitmask;
@@ -2595,6 +2597,78 @@
X poke_srmmu = poke_swift;
X }
X
+/* turbosparc.S */
+extern void turbosparc_flush_cache_all();
+extern void turbosparc_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
+
+static void poke_turbosparc(void)
+{
+ unsigned long mreg = srmmu_get_mmureg();
+ unsigned long ccreg;
+
+ /* Clear any crap from the cache or else... */
+ turbosparc_flush_cache_all();
+ mreg &= ~(TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE); /* Temporarily disable I & D caches */
+ mreg &= ~(TURBOSPARC_PCENABLE); /* Don't check parity */
+ srmmu_set_mmureg(mreg);
+
+ ccreg = turbosparc_get_ccreg();
+
+#ifdef TURBOSPARC_WRITEBACK
+ ccreg |= (TURBOSPARC_SNENABLE); /* Do DVMA snooping in Dcache */
+ ccreg &= ~(TURBOSPARC_uS2 | TURBOSPARC_WTENABLE);
+ /* Write-back D-cache, emulate VLSI
+ * abortion number three, not number one */
+#else
+ /* For now let's play safe, optimize later */
+ ccreg |= (TURBOSPARC_SNENABLE | TURBOSPARC_WTENABLE);
+ /* Do DVMA snooping in Dcache, Write-thru D-cache */
+ ccreg &= ~(TURBOSPARC_uS2);
+ /* Emulate VLSI abortion number three, not number one */
+#endif
+ switch (ccreg & 7) {
+ case 0: /* No SE cache */
+ case 7: /* Test mode */
+ break;
+ default:
+ ccreg |= (TURBOSPARC_SCENABLE);
+ }
+ turbosparc_set_ccreg (ccreg);
+
+ mreg |= (TURBOSPARC_ICENABLE | TURBOSPARC_DCENABLE); /* I & D caches on */
+ mreg |= (TURBOSPARC_ICSNOOP); /* Icache snooping on */
+ srmmu_set_mmureg(mreg);
+}
+
+__initfunc(static void init_turbosparc(void))
+{
+ srmmu_name = "Fujitsu TurboSparc";
+ srmmu_modtype = TurboSparc;
+
+ flush_cache_all = turbosparc_flush_cache_all;
+ flush_cache_mm = hypersparc_flush_cache_mm;
+ flush_cache_page = hypersparc_flush_cache_page;
+ flush_cache_range = hypersparc_flush_cache_range;
+
+ flush_tlb_all = hypersparc_flush_tlb_all;
+ flush_tlb_mm = hypersparc_flush_tlb_mm;
+ flush_tlb_page = hypersparc_flush_tlb_page;
+ flush_tlb_range = hypersparc_flush_tlb_range;
+
+#ifdef TURBOSPARC_WRITEBACK
+ flush_page_to_ram = hypersparc_flush_page_to_ram;
+ flush_chunk = hypersparc_flush_chunk;
+#else
+ flush_page_to_ram = swift_flush_page_to_ram;
+ flush_chunk = swift_flush_chunk;
+#endif
+
+ flush_sig_insns = turbosparc_flush_sig_insns;
+ flush_page_for_dma = hypersparc_flush_page_for_dma;
+
+ poke_srmmu = poke_turbosparc;
+}
+
X static void poke_tsunami(void)
X {
X unsigned long mreg = srmmu_get_mmureg();
@@ -2785,9 +2859,33 @@
X };
X return;
X }
+
+ /* Now Fujitsu TurboSparc. It might happen that it is
+ in Swift emulation mode, so we will check later... */
+ if (psr_typ == 0 && psr_vers == 5) {
+ init_turbosparc();
+ return;
+ }
X
X /* Next check for Fujitsu Swift. */
X if(psr_typ == 0 && psr_vers == 4) {
+ int cpunode;
+ char node_str[128];
+
+ /* Look if it is not a TurboSparc emulating Swift... */
+ cpunode = prom_getchild(prom_root_node);
+ while((cpunode = prom_getsibling(cpunode)) != 0) {
+ prom_getstring(cpunode, "device_type", node_str, sizeof(node_str));
+ if(!strcmp(node_str, "cpu")) {
+ if (!prom_getintdefault(cpunode, "psr-implementation", 1) &&
+ prom_getintdefault(cpunode, "psr-version", 1) == 5) {
+ init_turbosparc();
+ return;


+ }
+ break;
+ }
+ }

+
X init_swift();
X return;
X }
diff -u --recursive --new-file v2.1.43/linux/arch/sparc/mm/turbosparc.S linux/arch/sparc/mm/turbosparc.S
--- v2.1.43/linux/arch/sparc/mm/turbosparc.S Wed Dec 31 16:00:00 1969
+++ linux/arch/sparc/mm/turbosparc.S Mon Jul 7 08:18:54 1997
@@ -0,0 +1,46 @@
+/* $Id: turbosparc.S,v 1.1 1997/06/24 15:48:05 jj Exp $
+ * turbosparc.S: High speed Hypersparc mmu/cache operations.
+ *


+ * Copyright (C) 1997 David S. Miller (da...@caip.rutgers.edu)

+ * Copyright (C) 1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
+ */
+
+#include <asm/ptrace.h>
+#include <asm/psr.h>
+#include <asm/asi.h>
+#include <asm/page.h>
+#include <asm/pgtsrmmu.h>
+
+#define WINDOW_FLUSH(tmp1, tmp2) \
+ mov 0, tmp1; \
+98: ld [%g6 + AOFF_task_tss + AOFF_thread_uwinmask], tmp2; \
+ orcc %g0, tmp2, %g0; \
+ add tmp1, 1, tmp1; \
+ bne 98b; \
+ save %sp, -64, %sp; \
+99: subcc tmp1, 1, tmp1; \
+ bne 99b; \
+ restore %g0, %g0, %g0;
+
+ .text
+ .align 4
+
+ .globl turbosparc_flush_cache_all
+ .globl turbosparc_flush_sig_insns
+
+turbosparc_flush_cache_all:
+ WINDOW_FLUSH(%g4, %g5)
+ sethi %hi(vac_cache_size), %g4
+ ld [%g4 + %lo(vac_cache_size)], %g5
+ sethi %hi(vac_line_size), %g1
+ ld [%g1 + %lo(vac_line_size)], %g2
+1:
+ subcc %g5, %g2, %g5
+ bne 1b
+ sta %g0, [%g5] ASI_M_DATAC_TAG
+ retl
+ sta %g0, [%g0] ASI_M_IC_FLCLEAR
+
+turbosparc_flush_sig_insns:
+ retl
+ nop
diff -u --recursive --new-file v2.1.43/linux/arch/sparc/prom/bootstr.c linux/arch/sparc/prom/bootstr.c
--- v2.1.43/linux/arch/sparc/prom/bootstr.c Thu Dec 19 01:03:33 1996
+++ linux/arch/sparc/prom/bootstr.c Mon Jul 7 08:18:54 1997
@@ -1,4 +1,4 @@
-/* $Id: bootstr.c,v 1.12 1996/12/18 06:46:54 tridge Exp $
+/* $Id: bootstr.c,v 1.14 1997/06/19 16:28:49 jj Exp $
X * bootstr.c: Boot string/argument acquisition from the PROM.
X *
X * Copyright(C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -7,13 +7,14 @@
X #include <linux/config.h>
X #include <linux/string.h>
X #include <asm/oplib.h>
+#include <linux/init.h>
X
X #define BARG_LEN 256
-static char barg_buf[BARG_LEN];
-static char fetched = 0;
+static char barg_buf[BARG_LEN] __initdata = { 0 };
+static char fetched __initdata = 0;
X
-char *
-prom_getbootargs(void)
+__initfunc(char *
+prom_getbootargs(void))
X {
X int iter;
X char *cp, *arg;
diff -u --recursive --new-file v2.1.43/linux/arch/sparc/prom/tree.c linux/arch/sparc/prom/tree.c
--- v2.1.43/linux/arch/sparc/prom/tree.c Thu May 15 16:48:02 1997
+++ linux/arch/sparc/prom/tree.c Mon Jul 7 08:18:54 1997
@@ -1,4 +1,4 @@
-/* $Id: tree.c,v 1.18 1997/05/14 20:45:03 davem Exp $
+/* $Id: tree.c,v 1.19 1997/06/27 14:52:54 jj Exp $
X * tree.c: Basic device tree traversal/scanning for the Linux
X * prom library.
X *
@@ -231,7 +231,7 @@
X
X /* Return the first property type for node 'node'.
X */
-char * prom_firstprop(int node)
+char * prom_firstprop(int node, char *buffer)
X {
X unsigned long flags;
X char *ret;
@@ -248,7 +248,7 @@
X * at node 'node' . Returns NULL string if no more
X * property types for this node.
X */
-char * prom_nextprop(int node, char *oprop)
+char * prom_nextprop(int node, char *oprop, char *buffer)
X {
X char *ret;
X unsigned long flags;
@@ -293,7 +293,7 @@
X char *current_property = "";
X
X do {
- current_property = prom_nextprop(node, current_property);
+ current_property = prom_nextprop(node, current_property, NULL);
X if(!strcmp(current_property, prop))
X return 1;
X } while (*current_property);
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/Makefile linux/arch/sparc64/Makefile
--- v2.1.43/linux/arch/sparc64/Makefile Thu May 15 16:48:02 1997
+++ linux/arch/sparc64/Makefile Mon Jul 7 08:18:54 1997
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.16 1997/05/04 07:21:08 davem Exp $
+# $Id: Makefile,v 1.19 1997/06/26 12:48:45 jj Exp $
X # sparc64/Makefile
X #
X # Makefile for the architecture dependent flags and dependencies on the
@@ -24,8 +24,8 @@
X # debugging of the kernel to get the proper debugging information.
X
X #CFLAGS := $(CFLAGS) -g -pipe -fcall-used-g5 -fcall-used-g7
-CFLAGS := $(CFLAGS) -pipe \
- -fcall-used-g5 -fcall-used-g7 -Wno-sign-compare
+CFLAGS := $(CFLAGS) -pipe -mno-fpu -mtune=ultrasparc -mmedlow \
+ -ffixed-g4 -fcall-used-g5 -fcall-used-g7 -Wno-sign-compare
X
X LINKFLAGS = -T arch/sparc64/vmlinux.lds
X
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/config.in linux/arch/sparc64/config.in
--- v2.1.43/linux/arch/sparc64/config.in Mon Jun 16 16:35:54 1997
+++ linux/arch/sparc64/config.in Mon Jul 7 08:18:54 1997
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.6 1997/04/17 20:35:42 jj Exp $
+# $Id: config.in,v 1.9 1997/07/04 11:33:05 davem Exp $
X # For a description of the syntax of this configuration file,


X # see the Configure script.
X #

@@ -51,10 +51,10 @@


X bool 'System V IPC' CONFIG_SYSVIPC

X bool 'Sysctl support' CONFIG_SYSCTL

X bool 'Kernel support for Linux/Sparc 32bit binary compatibility' CONFIG_SPARC32_COMPAT
-tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
X tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF
X if [ "$CONFIG_SPARC32_COMPAT" != "n" ]; then
X tristate 'Kernel support for 32-bit ELF binaries' CONFIG_BINFMT_ELF32
+ bool 'Kernel support for 32-bit (ie. SunOS) a.out binaries' CONFIG_BINFMT_AOUT32
X fi
X if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
X tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
@@ -157,4 +157,5 @@


X if [ "$CONFIG_PROFILE" = "y" ]; then
X int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
X fi

+bool 'ECache flush trap support at ta 0x72' CONFIG_EC_FLUSH_TRAP
X endmenu
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.1.43/linux/arch/sparc64/defconfig Thu May 15 16:48:02 1997
+++ linux/arch/sparc64/defconfig Mon Jul 7 08:18:54 1997
@@ -5,12 +5,14 @@
X #
X # Code maturity level options
X #
-# CONFIG_EXPERIMENTAL is not set
+CONFIG_EXPERIMENTAL=y
X
X #


X # Loadable module support
X #

-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KERNELD is not set
X
X #
X # General setup
@@ -45,24 +47,31 @@
X #
X # Misc Linux/SPARC drivers
X #
-# CONFIG_SUN_OPENPROMIO is not set
-# CONFIG_SUN_MOSTEK_RTC is not set
-# CONFIG_SUN_OPENPROMFS is not set
+CONFIG_SUN_OPENPROMIO=m
+CONFIG_SUN_MOSTEK_RTC=y
+# CONFIG_SUN_BPP is not set
+# CONFIG_SUN_VIDEOPIX is not set
+CONFIG_SUN_OPENPROMFS=m
X CONFIG_NET=y
X CONFIG_SYSVIPC=y
X CONFIG_SYSCTL=y
X CONFIG_SPARC32_COMPAT=y
-CONFIG_BINFMT_AOUT=y
X CONFIG_BINFMT_ELF=y
X CONFIG_BINFMT_ELF32=y
+CONFIG_BINFMT_AOUT32=y
+CONFIG_BINFMT_JAVA=m
+CONFIG_BINFMT_MISC=m
X
X #
X # Floppy, IDE, and other block devices
X #
X # CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_STRIPED=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_LOOP=m
X
X #
X # Networking options
@@ -75,6 +84,7 @@


X # CONFIG_IP_ACCT is not set
X # CONFIG_IP_ROUTER is not set
X # CONFIG_NET_IPIP is not set
+# CONFIG_SYN_COOKIES is not set
X
X #
X # (it is safe to leave these untouched)

@@ -84,13 +94,22 @@
X CONFIG_PATH_MTU_DISCOVERY=y
X CONFIG_IP_NOSR=y
X CONFIG_SKB_LARGE=y
+# CONFIG_IPV6 is not set


X
X #
X #

X #
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+# CONFIG_IPX_PPROP_ROUTING is not set
+CONFIG_ATALK=m
+# CONFIG_IPDDP is not set
X # CONFIG_AX25 is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_WAN_ROUTER is not set
X
X #
X # SCSI support
@@ -104,7 +123,7 @@
X # CONFIG_CHR_DEV_ST is not set
X CONFIG_BLK_DEV_SR=y
X CONFIG_BLK_DEV_SR_VENDOR=y
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_CHR_DEV_SG=m
X
X #
X # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -116,7 +135,7 @@
X # SCSI low-level drivers
X #
X CONFIG_SCSI_SUNESP=y
-# CONFIG_SCSI_QLOGICPTI is not set
+CONFIG_SCSI_QLOGICPTI=m
X
X #
X # Network device support
@@ -126,14 +145,17 @@
X # CONFIG_PPP is not set
X # CONFIG_SLIP is not set
X CONFIG_SUNLANCE=y
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNQE is not set
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNQE=m
X # CONFIG_MYRI_SBUS is not set
X
X #


X # Filesystems
X #
X # CONFIG_QUOTA is not set
+# CONFIG_DCACHE_PRELOAD is not set
+# CONFIG_OMIRR is not set
+# CONFIG_TRANS_NAMES is not set
X # CONFIG_MINIX_FS is not set
X CONFIG_EXT2_FS=y

X # CONFIG_FAT_FS is not set
@@ -145,16 +167,17 @@
X CONFIG_ROOT_NFS=y
X CONFIG_RNFS_BOOTP=y
X # CONFIG_RNFS_RARP is not set
-# CONFIG_NFSD is not set
+CONFIG_NFSD=m


X CONFIG_SUNRPC=y
X CONFIG_LOCKD=y
X # CONFIG_SMB_FS is not set

+# CONFIG_NCP_FS is not set
X CONFIG_ISO9660_FS=y


X # CONFIG_HPFS_FS is not set
X # CONFIG_SYSV_FS is not set
X # CONFIG_AFFS_FS is not set

X # CONFIG_ROMFS_FS is not set
-# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS_FS=m
X CONFIG_UFS_FS=y
X CONFIG_BSD_DISKLABEL=y
X CONFIG_SMD_DISKLABEL=y
@@ -163,3 +186,4 @@


X # Kernel hacking
X #
X # CONFIG_PROFILE is not set

+# CONFIG_EC_FLUSH_TRAP is not set
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/Makefile linux/arch/sparc64/kernel/Makefile
--- v2.1.43/linux/arch/sparc64/kernel/Makefile Thu May 29 21:53:04 1997
+++ linux/arch/sparc64/kernel/Makefile Mon Jul 7 08:18:54 1997
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.22 1997/05/27 19:30:17 jj Exp $
+# $Id: Makefile,v 1.28 1997/07/05 09:52:20 davem Exp $
X # Makefile for the linux kernel.
X #
X # Note! Dependencies are done automagically by 'make dep', which also
@@ -16,20 +16,26 @@
X all: kernel.o head.o init_task.o
X
X O_TARGET := kernel.o
-O_OBJS := etrap.o rtrap.o hack.o process.o setup.o cpu.o idprom.o \
- systbls.o traps.o entry.o devices.o auxio.o ioport.o \
- irq.o ptrace.o time.o sys_sparc.o signal.o winfixup.o
+O_OBJS := process.o setup.o cpu.o idprom.o \
+ systbls.o traps.o devices.o auxio.o ioport.o \
+ irq.o ptrace.o time.o sys_sparc.o signal.o \
+ unaligned.o sys_sunos32.o sunos_ioctl32.o
X OX_OBJS := sparc64_ksyms.o
X
X ifdef CONFIG_SPARC32_COMPAT
- O_OBJS += sys_sparc32.o signal32.o ioctl32.o
+ O_OBJS += sys32.o sys_sparc32.o signal32.o ioctl32.o
X endif
X
X ifdef CONFIG_BINFMT_ELF32
X O_OBJS += binfmt_elf32.o
X endif
X
-head.o: head.S ttable.S itlb_miss.S dtlb_miss.S dtlb_prot.S
+ifdef CONFIG_BINFMT_AOUT32
+ O_OBJS += binfmt_aout32.o
+endif
+
+head.o: head.S ttable.S itlb_miss.S dtlb_miss.S dtlb_prot.S etrap.S rtrap.S \
+ winfixup.S entry.S
X $(CC) -D__ASSEMBLY__ -ansi -c $*.S -o $*.o
X
X #
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/binfmt_aout32.c linux/arch/sparc64/kernel/binfmt_aout32.c
--- v2.1.43/linux/arch/sparc64/kernel/binfmt_aout32.c Wed Dec 31 16:00:00 1969
+++ linux/arch/sparc64/kernel/binfmt_aout32.c Mon Jul 7 08:18:54 1997
@@ -0,0 +1,477 @@
+/*
+ * linux/fs/binfmt_aout.c
+ *
+ * Copyright (C) 1991, 1992, 1996 Linus Torvalds
+ *
+ * Hacked a bit by DaveM to make it work with 32-bit SunOS
+ * binaries on the sparc64 port.
+ */
+
+#include <linux/module.h>
+
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/a.out.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/malloc.h>
+#include <linux/binfmts.h>
+#include <linux/personality.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs);
+static int load_aout32_library(int fd);
+static int aout32_core_dump(long signr, struct pt_regs * regs);
+
+extern void dump_thread(struct pt_regs *, struct user *);
+
+static struct linux_binfmt aout32_format = {
+ NULL, NULL, load_aout32_binary, load_aout32_library, aout32_core_dump
+};
+
+static void set_brk(unsigned long start, unsigned long end)
+{
+ start = PAGE_ALIGN(start);
+ end = PAGE_ALIGN(end);
+ if (end <= start)
+ return;
+ do_mmap(NULL, start, end - start,


+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_FIXED | MAP_PRIVATE, 0);

+}
+
+/*
+ * 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->llseek) { \
+ if (file.f_op->llseek(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..
+ */
+
+static inline int
+do_aout32_core_dump(long signr, struct pt_regs * regs)
+{
+ struct inode * inode = NULL;
+ struct file file;
+ unsigned short fs;
+ int has_dumped = 0;
+ char corefile[6+sizeof(current->comm)];
+ unsigned long dump_start, dump_size;
+ struct user dump;
+# define START_DATA(u) (u.u_tsize)
+# define START_STACK(u) ((regs->u_regs[UREG_FP]) & ~(PAGE_SIZE - 1))
+
+ if (!current->dumpable || current->mm->count != 1)
+ return 0;
+ current->dumpable = 0;
+
+/* See if we have enough room to write the upage. */
+ if (current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE)
+ return 0;
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ memcpy(corefile,"core.",5);
+#if 0
+ memcpy(corefile+5,current->comm,sizeof(current->comm));
+#else
+ corefile[4] = '\0';
+#endif
+ if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode,NULL)) {
+ inode = NULL;
+ 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;
+ if (get_write_access(inode))
+ 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 done_coredump;
+ if (!file.f_op->write)
+ goto close_coredump;
+ has_dumped = 1;
+ current->flags |= PF_DUMPCORE;
+ strncpy(dump.u_comm, current->comm, sizeof(current->comm));
+ dump.signal = signr;
+ dump_thread(regs, &dump);
+
+/* 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) >
+ 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) >
+ current->rlim[RLIMIT_CORE].rlim_cur)
+ dump.u_ssize = 0;
+
+/* make sure we actually have a data and stack area to dump */
+ set_fs(USER_DS);
+ if (verify_area(VERIFY_READ, (void *) START_DATA(dump), dump.u_dsize))
+ dump.u_dsize = 0;
+ if (verify_area(VERIFY_READ, (void *) START_STACK(dump), dump.u_ssize))
+ dump.u_ssize = 0;
+
+ set_fs(KERNEL_DS);
+/* struct user */
+ DUMP_WRITE(&dump,sizeof(dump));
+/* now we start writing out the user space info */
+ set_fs(USER_DS);
+/* Dump the data area */
+ if (dump.u_dsize != 0) {
+ dump_start = START_DATA(dump);
+ dump_size = dump.u_dsize;
+ DUMP_WRITE(dump_start,dump_size);
+ }
+/* Now prepare to dump the stack area */
+ if (dump.u_ssize != 0) {
+ dump_start = START_STACK(dump);
+ dump_size = dump.u_ssize;
+ DUMP_WRITE(dump_start,dump_size);
+ }
+/* Finally dump the task struct. Not be used by gdb, but could be useful */
+ set_fs(KERNEL_DS);
+ DUMP_WRITE(current,sizeof(*current));
+ inode->i_status |= ST_MODIFIED;
+close_coredump:
+ if (file.f_op->release)
+ file.f_op->release(inode,&file);
+done_coredump:
+ put_write_access(inode);
+end_coredump:
+ set_fs(fs);
+ iput(inode);
+ return has_dumped;
+}
+
+static int
+aout32_core_dump(long signr, struct pt_regs * regs)


+{
+ int retval;
+

+ MOD_INC_USE_COUNT;
+ retval = do_aout32_core_dump(signr, regs);
+ MOD_DEC_USE_COUNT;


+ return retval;
+}
+

+/*
+ * create_aout32_tables() parses the env- and arg-strings in new user
+ * memory and creates the pointer tables from them, and puts their
+ * addresses on the "stack", returning the new stack pointer value.
+ */
+#define A(x) ((unsigned long)x)
+static u32 *create_aout32_tables(char * p, struct linux_binprm * bprm)
+{
+ u32 *argv, *envp;
+ u32 *sp;
+ int argc = bprm->argc;
+ int envc = bprm->envc;
+
+ sp = (u32 *) ((-(unsigned long)sizeof(char *)) & (unsigned long) p);
+
+ /* This imposes the proper stack alignment for a new process. */
+ sp = (u32 *) (((unsigned long) sp) & ~7);
+ if ((envc+argc+3)&1)
+ --sp;
+
+ sp -= envc+1;
+ envp = (u32 *) sp;
+ sp -= argc+1;
+ argv = (u32 *) sp;
+ put_user(argc,--sp);
+ current->mm->arg_start = (unsigned long) p;
+ while (argc-->0) {
+ char c;
+ put_user(((u32)A(p)),argv++);
+ do {
+ get_user(c,p++);
+ } while (c);
+ }
+ put_user(NULL,argv);
+ current->mm->arg_end = current->mm->env_start = (unsigned long) p;
+ while (envc-->0) {
+ char c;
+ put_user(((u32)A(p)),envp++);
+ do {
+ get_user(c,p++);
+ } while (c);
+ }
+ put_user(NULL,envp);
+ current->mm->env_end = (unsigned long) p;
+ return sp;
+}
+
+/*
+ * These are the functions used to load a.out style executables and shared
+ * libraries. There is no binary dependent code anywhere else.
+ */
+
+static inline int do_load_aout32_binary(struct linux_binprm * bprm,
+ struct pt_regs * regs)
+{
+ struct exec ex;


+ struct file * file;

+ int fd;
+ unsigned long error;
+ unsigned long p = bprm->p;
+ unsigned long fd_offset;


+ unsigned long rlim;
+

+ ex = *((struct exec *) bprm->buf); /* exec-header */
+ if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
+ N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) ||
+ N_TRSIZE(ex) || N_DRSIZE(ex) ||
+ bprm->inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
+ return -ENOEXEC;
+ }
+
+ current->personality = PER_LINUX;
+ fd_offset = N_TXTOFF(ex);
+
+ /* Check initial limits. This avoids letting people circumvent
+ * size limits imposed on them by creating programs with large
+ * arrays in the data or bss.
+ */


+ rlim = current->rlim[RLIMIT_DATA].rlim_cur;
+ if (rlim >= RLIM_INFINITY)
+ rlim = ~0;

+ if (ex.a_data + ex.a_bss > rlim)
+ return -ENOMEM;
+
+ /* OK, This is the point of no return */
+ flush_old_exec(bprm);
+ memcpy(&current->tss.core_exec, &ex, sizeof(struct exec));
+
+ current->mm->end_code = ex.a_text +
+ (current->mm->start_code = N_TXTADDR(ex));
+ current->mm->end_data = ex.a_data +
+ (current->mm->start_data = N_DATADDR(ex));
+ current->mm->brk = ex.a_bss +
+ (current->mm->start_brk = N_BSSADDR(ex));
+
+ current->mm->rss = 0;
+ current->mm->mmap = NULL;
+ current->suid = current->euid = current->fsuid = bprm->e_uid;
+ current->sgid = current->egid = current->fsgid = bprm->e_gid;
+ current->flags &= ~PF_FORKNOEXEC;
+ if (N_MAGIC(ex) == NMAGIC) {
+ /* Fuck me plenty... */
+ error = do_mmap(NULL, N_TXTADDR(ex), ex.a_text,


+ PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_FIXED|MAP_PRIVATE, 0);

+ read_exec(bprm->inode, fd_offset, (char *) N_TXTADDR(ex),
+ ex.a_text, 0);
+ error = do_mmap(NULL, N_DATADDR(ex), ex.a_data,


+ PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_FIXED|MAP_PRIVATE, 0);

+ read_exec(bprm->inode, fd_offset + ex.a_text, (char *) N_DATADDR(ex),
+ ex.a_data, 0);
+ goto beyond_if;
+ }
+
+ if (N_MAGIC(ex) == OMAGIC) {
+ do_mmap(NULL, N_TXTADDR(ex) & PAGE_MASK,
+ ex.a_text+ex.a_data + PAGE_SIZE - 1,


+ PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_FIXED|MAP_PRIVATE, 0);

+ read_exec(bprm->inode, fd_offset, (char *) N_TXTADDR(ex),
+ ex.a_text+ex.a_data, 0);
+ } else {
+ if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
+ (N_MAGIC(ex) != NMAGIC))
+ printk(KERN_NOTICE "executable not page aligned\n");
+
+ fd = open_inode(bprm->inode, O_RDONLY);
+
+ if (fd < 0)
+ return fd;
+ file = current->files->fd[fd];
+ if (!file->f_op || !file->f_op->mmap) {
+ sys_close(fd);
+ do_mmap(NULL, 0, ex.a_text+ex.a_data,


+ PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_FIXED|MAP_PRIVATE, 0);

+ read_exec(bprm->inode, fd_offset,
+ (char *) N_TXTADDR(ex), ex.a_text+ex.a_data, 0);
+ goto beyond_if;
+ }
+
+ error = do_mmap(file, N_TXTADDR(ex), ex.a_text,
+ PROT_READ | PROT_EXEC,
+ MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
+ fd_offset);
+
+ if (error != N_TXTADDR(ex)) {
+ sys_close(fd);
+ send_sig(SIGKILL, current, 0);


+ return error;
+ }
+

+ error = do_mmap(file, N_DATADDR(ex), ex.a_data,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
+ fd_offset + ex.a_text);
+ sys_close(fd);
+ if (error != N_DATADDR(ex)) {
+ send_sig(SIGKILL, current, 0);


+ return error;
+ }
+ }

+beyond_if:
+ if (current->exec_domain && current->exec_domain->module)
+ __MOD_DEC_USE_COUNT(current->exec_domain->module);
+ if (current->binfmt && current->binfmt->module)
+ __MOD_DEC_USE_COUNT(current->binfmt->module);
+ current->exec_domain = lookup_exec_domain(current->personality);
+ current->binfmt = &aout32_format;
+ if (current->exec_domain && current->exec_domain->module)
+ __MOD_INC_USE_COUNT(current->exec_domain->module);
+ if (current->binfmt && current->binfmt->module)
+ __MOD_INC_USE_COUNT(current->binfmt->module);
+
+ set_brk(current->mm->start_brk, current->mm->brk);
+
+ p = setup_arg_pages(p, bprm);
+
+ p = (unsigned long) create_aout32_tables((char *)p, bprm);
+ current->mm->start_stack = p;
+ start_thread32(regs, ex.a_entry, p);
+ if (current->flags & PF_PTRACED)
+ send_sig(SIGTRAP, current, 0);


+ return 0;
+}
+
+

+static int
+load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)


+{
+ int retval;
+

+ MOD_INC_USE_COUNT;
+ retval = do_load_aout32_binary(bprm, regs);
+ MOD_DEC_USE_COUNT;


+ return retval;
+}
+

+static inline int
+do_load_aout32_library(int fd)


+{
+ struct file * file;

+ struct exec ex;


+ struct inode * inode;

+ unsigned int len;
+ unsigned int bss;
+ unsigned int start_addr;
+ unsigned long error;
+
+ file = current->files->fd[fd];
+ inode = file->f_inode;
+
+ if (!file || !file->f_op)
+ return -EACCES;
+
+ /* Seek into the file */
+ if (file->f_op->llseek) {
+ if ((error = file->f_op->llseek(inode, file, 0, 0)) != 0)
+ return -ENOEXEC;
+ } else
+ file->f_pos = 0;
+
+ set_fs(KERNEL_DS);
+ error = file->f_op->read(inode, file, (char *) &ex, sizeof(ex));
+ set_fs(USER_DS);
+ if (error != sizeof(ex))
+ return -ENOEXEC;
+
+ /* We come in here for the regular a.out style of shared libraries */
+ if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) ||
+ N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
+ inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
+ return -ENOEXEC;
+ }
+ if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) &&
+ (N_TXTOFF(ex) < inode->i_sb->s_blocksize)) {
+ printk("N_TXTOFF < BLOCK_SIZE. Please convert library\n");
+ return -ENOEXEC;
+ }
+
+ if (N_FLAGS(ex)) return -ENOEXEC;
+
+ /* For QMAGIC, the starting address is 0x20 into the page. We mask
+ this off to get the starting address for the page */
+
+ start_addr = ex.a_entry & 0xfffff000;
+
+ /* Now use mmap to map the library into memory. */
+ error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
+ N_TXTOFF(ex));
+ if (error != start_addr)
+ return error;
+ len = PAGE_ALIGN(ex.a_text + ex.a_data);
+ bss = ex.a_text + ex.a_data + ex.a_bss;
+ if (bss > len) {
+ error = do_mmap(NULL, start_addr + len, bss-len,
+ PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_PRIVATE|MAP_FIXED, 0);
+ if (error != start_addr + len)
+ return error;
+ }


+ return 0;
+}
+

+static int
+load_aout32_library(int fd)


+{
+ int retval;
+

+ MOD_INC_USE_COUNT;
+ retval = do_load_aout32_library(fd);
+ MOD_DEC_USE_COUNT;


+ return retval;
+}
+
+

+__initfunc(int init_aout32_binfmt(void))
+{
+ return register_binfmt(&aout32_format);
+}
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/binfmt_elf32.c linux/arch/sparc64/kernel/binfmt_elf32.c
--- v2.1.43/linux/arch/sparc64/kernel/binfmt_elf32.c Sat May 24 09:10:23 1997
+++ linux/arch/sparc64/kernel/binfmt_elf32.c Thu Jun 26 12:33:38 1997
@@ -6,6 +6,8 @@
X #define ELF_CLASS ELFCLASS32
X #define ELF_DATA ELFDATA2MSB;
X
+#define elf_check_arch(x) (((x) == EM_SPARC) || ((x) == EM_SPARC32PLUS))
+
X #include <asm/processor.h>
X #include <linux/module.h>
X #include <linux/config.h>
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/cpu.c linux/arch/sparc64/kernel/cpu.c
--- v2.1.43/linux/arch/sparc64/kernel/cpu.c Mon Apr 14 16:28:08 1997
+++ linux/arch/sparc64/kernel/cpu.c Mon Jul 7 08:18:54 1997
@@ -6,7 +6,9 @@
X
X #include <linux/kernel.h>
X #include <linux/init.h>
+#include <asm/asi.h>
X #include <asm/system.h>
+#include <asm/fpumacro.h>
X
X struct cpu_iu_info {
X short manuf;
@@ -50,11 +52,20 @@
X int manuf, impl;
X unsigned i, cpuid;
X long ver, fpu_vers;
-
- cpuid = get_cpuid();
+ long fprs;
X
- __asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]" : "=r" (ver) : "r" (&fpu_vers));
+#ifndef __SMP__
+ cpuid = 0;
+#else
+#error SMP not supported on sparc64 yet
+ /* cpuid = get_cpuid(); */
+#endif
X
+ fprs = fprs_read ();
+ fprs_write (FPRS_FEF);
+ __asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]" : "=r" (ver) : "r" (&fpu_vers));
+ fprs_write (fprs);
+
X manuf = ((ver >> 48)&0xffff);
X impl = ((ver >> 32)&0xffff);
X
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/devices.c linux/arch/sparc64/kernel/devices.c
--- v2.1.43/linux/arch/sparc64/kernel/devices.c Mon Apr 14 16:28:08 1997
+++ linux/arch/sparc64/kernel/devices.c Mon Jul 7 08:18:54 1997
@@ -6,7 +6,6 @@
X
X #include <linux/kernel.h>
X #include <linux/tasks.h>
-#include <linux/config.h>
X #include <linux/init.h>
X
X #include <asm/page.h>
@@ -15,7 +14,7 @@
X #include <asm/smp.h>
X
X struct prom_cpuinfo linux_cpus[NCPUS];
-int linux_num_cpus;
+int linux_num_cpus = 0;
X
X extern void cpu_probe(void);
X
@@ -54,7 +53,7 @@
X };
X if(cpu_ctr == 0) {
X printk("No CPU nodes found, cannot continue.\n");
- halt();
+ prom_halt();
X }
X printk("Found %d CPU prom device tree node(s).\n", cpu_ctr);
X };
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/dtlb_miss.S linux/arch/sparc64/kernel/dtlb_miss.S
--- v2.1.43/linux/arch/sparc64/kernel/dtlb_miss.S Mon Apr 14 16:28:08 1997
+++ linux/arch/sparc64/kernel/dtlb_miss.S Mon Jul 7 08:18:54 1997
@@ -1,4 +1,4 @@
-/* $Id: dtlb_miss.S,v 1.11 1997/04/10 01:59:35 davem Exp $
+/* $Id: dtlb_miss.S,v 1.12 1997/06/26 12:47:08 jj Exp $
X * dtlb_miss.S: Data TLB miss code, this is included directly
X * into the trap table.
X *
@@ -19,9 +19,11 @@
X * }
X * goto longer_processing;
X * } else {
- * if(fault_address >= KERNBASE &&
- * fault_address < VMALLOC_START) {
- * tlb_load(__pa(fault_address) | PAGE_KERNEL);
+ * if(fault_address >= PAGE_OFFSET) {
+ * pte_val = PAGE_KERNEL;
+ * if (fault_address & 0x10000000000)
+ * pte_val = PAGE_KERNEL_IO;
+ * tlb_load(__pa(fault_address) | pte_val);
X * return_from_trap();
X * } else {
X * pgd = pgd_offset(swapper_pg_dir, fault_address);
@@ -32,9 +34,9 @@
X * This is optimized for user TLB misses on purpose.
X */
X
-#define KERN_HIGHBITS (_PAGE_VALID | _PAGE_SZ4MB)
+#define KERN_HIGHBITS ((_PAGE_VALID | _PAGE_SZ4MB) ^ 0xfffff80000000000)
X #define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)
-#define KERN_LOWBITS_IO (_PAGE_E | _PAGE_P | _PAGE_W)
+#define KERN_LOWBITS_IO ((_PAGE_E | _PAGE_P | _PAGE_W) ^ KERN_LOWBITS)
X
X /* ICACHE line 1 */
X /*0x00*/ ldxa [%g0] ASI_DMMU, %g1 ! Get TAG_TARGET
@@ -57,17 +59,17 @@
X 1:/*0x3c*/ retry ! Trap return
X
X 3: /* ICACHE line 3 */
- /*0x40*/ sllx %g1, 43, %g5 ! This gets >= VMALLOC_START...
- /*0x44*/ brlz,pn %g5, 4f ! ...if now less than zero.
- /*0x48*/ andncc %g1, 0x3ff, %g0 ! Slick trick...
- /*0x4c*/ be,pn %xcc, 4f ! Yes, it is some PROM mapping
- /*0x50*/ srlx %g5, 21, %g5 ! This is now physical page
- /*0x54*/ sethi %uhi(KERN_HIGHBITS), %g1 ! Construct PTE
- /*0x58*/ sllx %g1, 32, %g1 ! Move priv bits up
- /*0x5c*/ or %g1, %g5, %g1 ! Or in the page
+ /*0x40*/ sllx %g1, 22, %g5 ! This is now physical page + PAGE_OFFSET
+ /*0x44*/ brgez,pn %g5, 4f ! If >= 0, then walk down page tables
+ /*0x48*/ sethi %uhi(KERN_HIGHBITS), %g1 ! Construct PTE ^ PAGE_OFFSET
+ /*0x4c*/ andcc %g3, 0x80, %g0 ! Slick trick...
+ /*0x50*/ sllx %g1, 32, %g1 ! Move high bits up
+ /*0x54*/ or %g1, (KERN_LOWBITS), %g1 ! Assume not IO
+ /*0x58*/ bne,a,pn %icc, 5f ! Is it an IO page?
+ /*0x5c*/ xor %g1, (KERN_LOWBITS_IO), %g1 ! Aha, it is IO...
X
X /* ICACHE line 4 */
- /*0x60*/ or %g1, (KERN_LOWBITS), %g1 ! Set low priv bits
+5:/*0x60*/ xor %g1, %g5, %g1 ! Slick trick II...
X /*0x64*/ stxa %g1, [%g0] ASI_DTLB_DATA_IN ! TLB load
X /*0x68*/ retry ! Trap return
X 4:/*0x6c*/ ldxa [%g0] ASI_DMMU_TSB_8KB_PTR, %g1 ! For PTE offset
@@ -78,3 +80,4 @@
X
X #undef KERN_HIGHBITS
X #undef KERN_LOWBITS
+#undef KERN_LOWBITS_IO
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/kernel/entry.S linux/arch/sparc64/kernel/entry.S
--- v2.1.43/linux/arch/sparc64/kernel/entry.S Mon Jun 16 16:35:54 1997
+++ linux/arch/sparc64/kernel/entry.S Mon Jul 7 08:18:54 1997
@@ -1,13 +1,12 @@
-/* $Id: entry.S,v 1.31 1997/06/02 06:33:25 davem Exp $
+/* $Id: entry.S,v 1.45 1997/07/05 09:52:25 davem Exp $
X * arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points.
X *
- * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
+ * Copyright (C) 1995,1997 David S. Miller (da...@caip.rutgers.edu)
X * Copyright (C) 1996 Eddie C. Dost (e...@skynet.be)
X * Copyright (C) 1996 Miguel de Icaza (mig...@nuclecu.unam.mx)
X * Copyright (C) 1996,1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
X */
X
-#include <linux/config.h>
X #include <linux/errno.h>
X
X #include <asm/head.h>
@@ -25,7 +24,6 @@
X #define NR_SYSCALLS 256 /* Each OS is different... */
X
X .text
- .align 4
X .globl sparc64_dtlb_prot_catch, sparc64_dtlb_refbit_catch
X .globl sparc64_itlb_refbit_catch
X
@@ -38,24 +36,27 @@
X * to update the dirty bit) and since we left crap in the sfsr
X * it will not get updated properly.
X */
+ .align 32
X sparc64_dtlb_prot_catch:
X wr %g0, ASI_DMMU, %asi
X rdpr %pstate, %g1
X wrpr %g1, PSTATE_AG|PSTATE_MG, %pstate
X rdpr %tl, %g3
X ldxa [%g0 + TLB_TAG_ACCESS] %asi, %g5
- ldxa [%g0 + TLB_SFSR] %asi, %g4
- cmp %g3, 1
X stxa %g0, [%g0 + TLB_SFSR] %asi
+ membar #Sync
+ cmp %g3, 1
+
X bgu,a,pn %icc, winfix_trampoline
X rdpr %tpc, %g3


X ba,pt %xcc, etrap
X rd %pc, %g7

- b,a,pt %xcc, 1f
-
+ b,pt %xcc, 1f
+ mov 1, %o2
X sparc64_dtlb_refbit_catch:
X srlx %g5, 9, %g4
X and %g4, ((_PAGE_PRESENT | _PAGE_READ) >> 9), %g4
+
X cmp %g4, ((_PAGE_PRESENT | _PAGE_READ) >> 9)
X be,a,pt %xcc, 2f
X mov 1, %g4
@@ -64,23 +65,24 @@
X wrpr %g1, PSTATE_AG|PSTATE_MG, %pstate
X rdpr %tl, %g3
X ldxa [%g0 + TLB_TAG_ACCESS] %asi, %g5
+
X cmp %g3, 1
- clr %g4 ! sfsr not updated for tlb misses
- bgu,a,pn %icc, winfix_trampoline
+ bgu,pn %icc, winfix_trampoline
X rdpr %tpc, %g3
- ba,pt %xcc, etrap
+ b,pt %xcc, etrap
X rd %pc, %g7
-1:
- mov %l5, %o4 ! raw tag access
- mov %l4, %o5 ! raw sfsr
- srlx %l5, PAGE_SHIFT, %o3
- clr %o1 ! text_fault == 0
- sllx %o3, PAGE_SHIFT, %o3 ! address
- and %l4, 0x4, %o2 ! write == sfsr.W
+ clr %o2
+1: srlx %l5, PAGE_SHIFT, %o1
+ add %sp, STACK_BIAS + REGWIN_SZ, %o0
+
X call do_sparc64_fault
- add %sp, STACK_BIAS + REGWIN_SZ, %o0 ! pt_regs ptr
- ba,pt %xcc, rtrap


+ sllx %o1, PAGE_SHIFT, %o1

+ b,pt %xcc, rtrap
X clr %l6
+ nop
+ nop
+ nop
+ nop
X
X sparc64_itlb_refbit_catch:
X srlx %g5, 9, %g4
@@ -90,35 +92,105 @@
X mov 1, %g4
X rdpr %pstate, %g1
X wrpr %g1, PSTATE_AG|PSTATE_MG, %pstate
- ba,pt %xcc, etrap
- rd %pc, %g7
-
- ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC], %o3
- mov 1, %o1 ! text_fault == 1
- clr %o2 ! write == 0
- clr %o4 ! tag access (N/A)
- clr %o5 ! raw sfsr (N/A)


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 18'
echo 'File patch-2.1.44 is continued in part 19'
echo 19 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part16

#!/bin/sh
# this is part 16 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 16; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

+{
+ struct mm_struct *mm = vma->vm_mm;
+ unsigned long flags;


+ pgd_t *pgdp;
+ pmd_t *pmdp;
+ pte_t *ptep;

+ int text;
+
+ /* If ownes no valid ASID yet, cannot possibly have gotten
+ * this page into the cache.
+ */
+ if(mm->context == 0)
+ return;
+
+#ifdef DEBUG_CACHE
+ printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+ save_and_cli(flags);
+ page &= PAGE_MASK;
+ pgdp = pgd_offset(mm, page);
+ pmdp = pmd_offset(pgdp, page);
+ ptep = pte_offset(pmdp, page);
+
+ /* If the page isn't marked valid, the page cannot possibly be
+ * in the cache.
+ */
+ if(!(pte_val(*ptep) & _PAGE_VALID))
+ goto out;
+
+ text = (vma->vm_flags & VM_EXEC);
+ /*
+ * Doing flushes for another ASID than the current one is
+ * too difficult since stupid R4k caches do a TLB translation
+ * for every cache flush operation. So we do indexed flushes
+ * in that case, which doesn't overly flush the cache too much.
+ */
+ if(mm == current->mm) {
+ blast_dcache16_page(page);
+ if(text)
+ blast_icache16_page(page);
+ } else {
+ /* Do indexed flush, too much work to get the (possible)
+ * tlb refills to work correctly.
+ */
+ page = (KSEG0 + (page & (dcache_size - 1)));
+ blast_dcache16_page_indexed(page);
+ blast_dcache16_page_indexed(page ^ 0x2000);
+ if(text) {
+ blast_icache16_page_indexed(page);
+ blast_icache16_page_indexed(page ^ 0x2000);
+ }
+ }
+out:
+ restore_flags(flags);
+}
+
+static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma,


+ unsigned long page)
+{

+ struct mm_struct *mm = vma->vm_mm;
+ unsigned long flags;


+ pgd_t *pgdp;
+ pmd_t *pmdp;
+ pte_t *ptep;

+ int text;
+
+ /*
+ * If ownes no valid ASID yet, cannot possibly have gotten
+ * this page into the cache.
+ */
+ if(mm->context == 0)
+ return;
+
+#ifdef DEBUG_CACHE
+ printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+ save_and_cli(flags);
+ page &= PAGE_MASK;
+ pgdp = pgd_offset(mm, page);
+ pmdp = pmd_offset(pgdp, page);
+ ptep = pte_offset(pmdp, page);
+
+ /*
+ * If the page isn't marked valid, the page cannot possibly be
+ * in the cache.
+ */
+ if(!(pte_val(*ptep) & _PAGE_PRESENT))
+ goto out;
+
+ text = (vma->vm_flags & VM_EXEC);
+ /*
+ * Doing flushes for another ASID than the current one is
+ * too difficult since stupid R4k caches do a TLB translation
+ * for every cache flush operation. So we do indexed flushes
+ * in that case, which doesn't overly flush the cache too much.
+ */
+ if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+ blast_dcache32_page(page);
+ if(text)
+ blast_icache32_page(page);
+ } else {
+ /*
+ * Do indexed flush, too much work to get the (possible)
+ * tlb refills to work correctly.
+ */
+ page = (KSEG0 + (page & (dcache_size - 1)));
+ blast_dcache32_page_indexed(page);
+ if(text)
+ blast_icache32_page_indexed(page);
+ }
+out:
+ restore_flags(flags);
+}
+
+static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,


+ unsigned long page)
+{

+ struct mm_struct *mm = vma->vm_mm;
+ unsigned long flags;


+ pgd_t *pgdp;
+ pmd_t *pmdp;
+ pte_t *ptep;

+ int text;
+
+ /*
+ * If ownes no valid ASID yet, cannot possibly have gotten
+ * this page into the cache.
+ */
+ if(mm->context == 0)
+ return;
+
+#ifdef DEBUG_CACHE
+ printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+ save_and_cli(flags);
+ page &= PAGE_MASK;
+ pgdp = pgd_offset(mm, page);
+ pmdp = pmd_offset(pgdp, page);
+ ptep = pte_offset(pmdp, page);
+
+ /*
+ * If the page isn't marked valid, the page cannot possibly be
+ * in the cache.
+ */
+ if(!(pte_val(*ptep) & _PAGE_PRESENT))
+ goto out;
+
+ text = (vma->vm_flags & VM_EXEC);
+ /*
+ * Doing flushes for another ASID than the current one is
+ * too difficult since stupid R4k caches do a TLB translation
+ * for every cache flush operation. So we do indexed flushes
+ * in that case, which doesn't overly flush the cache too much.
+ */
+ if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+ blast_dcache32_page(page);
+ if(text)
+ blast_icache32_page(page);
+ } else {
+ /* Do indexed flush, too much work to get the (possible)
+ * tlb refills to work correctly.
+ */
+ page = (KSEG0 + (page & (dcache_size - 1)));
+ blast_dcache32_page_indexed(page);
+ blast_dcache32_page_indexed(page ^ 0x2000);
+ if(text) {
+ blast_icache32_page_indexed(page);
+ blast_icache32_page_indexed(page ^ 0x2000);
+ }
+ }
+out:
+ restore_flags(flags);
+}
+
+/* If the addresses passed to these routines are valid, they are
+ * either:
+ *
+ * 1) In KSEG0, so we can do a direct flush of the page.
+ * 2) In KSEG2, and since every process can translate those
+ * addresses all the time in kernel mode we can do a direct
+ * flush.
+ * 3) In KSEG1, no flush necessary.
+ */
+static void r4k_flush_page_to_ram_s16d16i16(unsigned long page)
+{
+ page &= PAGE_MASK;
+ if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {


+ unsigned long flags;
+

+#ifdef DEBUG_CACHE
+ printk("cram[%08lx]", page);
+#endif
+ save_and_cli(flags);
+ blast_dcache16_page(page);
+ blast_scache16_page(page);
+ restore_flags(flags);
+ }
+}
+
+static void r4k_flush_page_to_ram_s32d16i16(unsigned long page)
+{
+ page &= PAGE_MASK;
+ if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {


+ unsigned long flags;
+

+#ifdef DEBUG_CACHE
+ printk("cram[%08lx]", page);
+#endif
+ save_and_cli(flags);
+ blast_dcache16_page(page);
+ blast_scache32_page(page);
+ restore_flags(flags);
+ }
+}
+
+static void r4k_flush_page_to_ram_s64d16i16(unsigned long page)
+{
+ page &= PAGE_MASK;
+ if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {


+ unsigned long flags;
+

+#ifdef DEBUG_CACHE
+ printk("cram[%08lx]", page);
+#endif
+ save_and_cli(flags);
+ blast_dcache16_page(page);
+ blast_scache64_page(page);
+ restore_flags(flags);
+ }
+}
+
+static void r4k_flush_page_to_ram_s128d16i16(unsigned long page)
+{
+ page &= PAGE_MASK;
+ if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {


+ unsigned long flags;
+

+#ifdef DEBUG_CACHE
+ printk("cram[%08lx]", page);
+#endif
+ save_and_cli(flags);
+ blast_dcache16_page(page);
+ blast_scache128_page(page);
+ restore_flags(flags);
+ }
+}
+
+static void r4k_flush_page_to_ram_s16d32i32(unsigned long page)
+{
+ page &= PAGE_MASK;
+ if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {


+ unsigned long flags;
+

+#ifdef DEBUG_CACHE
+ printk("cram[%08lx]", page);
+#endif
+ save_and_cli(flags);
+ blast_dcache32_page(page);
+ blast_scache16_page(page);
+ restore_flags(flags);
+ }
+}
+
+static void r4k_flush_page_to_ram_s32d32i32(unsigned long page)
+{
+ page &= PAGE_MASK;
+ if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {


+ unsigned long flags;
+

+#ifdef DEBUG_CACHE
+ printk("cram[%08lx]", page);
+#endif
+ save_and_cli(flags);
+ blast_dcache32_page(page);
+ blast_scache32_page(page);
+ restore_flags(flags);
+ }
+}
+
+static void r4k_flush_page_to_ram_s64d32i32(unsigned long page)
+{
+ page &= PAGE_MASK;
+ if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {


+ unsigned long flags;
+

+#ifdef DEBUG_CACHE
+ printk("cram[%08lx]", page);
+#endif
+ save_and_cli(flags);
+ blast_dcache32_page(page);
+ blast_scache64_page(page);
+ restore_flags(flags);
+ }
+}
+
+static void r4k_flush_page_to_ram_s128d32i32(unsigned long page)
+{
+ page &= PAGE_MASK;
+ if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {


+ unsigned long flags;
+

+#ifdef DEBUG_CACHE
+ printk("cram[%08lx]", page);
+#endif
+ save_and_cli(flags);
+ blast_dcache32_page(page);
+ blast_scache128_page(page);
+ restore_flags(flags);
+ }
+}
+
+static void r4k_flush_page_to_ram_d16i16(unsigned long page)
+{
+ page &= PAGE_MASK;
+ if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {


+ unsigned long flags;
+

+#ifdef DEBUG_CACHE
+ printk("cram[%08lx]", page);
+#endif
+ save_and_cli(flags);
+ blast_dcache16_page(page);
+ restore_flags(flags);
+ }
+}
+
+static void r4k_flush_page_to_ram_d32i32(unsigned long page)
+{
+ page &= PAGE_MASK;
+ if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {


+ unsigned long flags;
+

+#ifdef DEBUG_CACHE
+ printk("cram[%08lx]", page);
+#endif
+ save_and_cli(flags);
+ blast_dcache32_page(page);
+ restore_flags(flags);
+ }
+}
+
+/*
+ * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Invalidate_D,
+ * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only
+ * operate correctly if the internal data cache refill buffer is empty. These
+ * CACHE instructions should be separated from any potential data cache miss
+ * by a load instruction to an uncached address to empty the response buffer."
+ * (Revision 2.0 device errata from IDT available on http://www.idt.com/
+ * in .pdf format.)
+ */
+static void r4k_flush_page_to_ram_d32i32_r4600(unsigned long page)
+{
+ page &= PAGE_MASK;
+ if((page >= KSEG0 && page < KSEG1) || (page >= KSEG2)) {


+ unsigned long flags;
+

+#ifdef DEBUG_CACHE
+ /* #if 1 */
+ printk("r4600_cram[%08lx]", page);
+#endif
+ /*
+ * Workaround for R4600 bug. Explanation see above.
+ */
+ *(volatile unsigned long *)KSEG1;
+
+ save_and_cli(flags);
+ blast_dcache32_page(page);
+ blast_dcache32_page(page ^ 0x2000);
+#ifdef CONFIG_SGI
+ {
+ unsigned long tmp1, tmp2;
+ /*
+ * SGI goo. Have to check this closer ...
+ */


+ __asm__ __volatile__("
+ .set noreorder
+ .set mips3
+ li %0, 0x1
+ dsll %0, 31

+ or %0, %0, %2


+ lui %1, 0x9000
+ dsll32 %1, 0

+ or %0, %0, %1
+ daddu %1, %0, 0x0fe0
+ li %2, 0x80


+ mtc0 %2, $12
+ nop; nop; nop; nop;

+1: sw $0, 0(%0)
+ bltu %0, %1, 1b
+ daddu %0, 32


+ mtc0 $0, $12
+ nop; nop; nop; nop;

+ .set mips0
+ .set reorder"
+ : "=&r" (tmp1), "=&r" (tmp2),
+ "=&r" (page)
+ : "2" (page & 0x0007f000));
+ }
+#endif /* CONFIG_SGI */
+ restore_flags(flags);
+ }
+}
+
+static void r4k_flush_cache_sigtramp(unsigned long addr)
+{
+ addr &= ~(dc_lsize - 1);
+ __asm__ __volatile__("nop;nop;nop;nop");
+ flush_dcache_line(addr);
+ flush_dcache_line(addr + dc_lsize);
+ flush_icache_line(addr);
+ flush_icache_line(addr + dc_lsize);
+}
+
+#undef DEBUG_TLB
+#undef DEBUG_TLBUPDATE
+
+#define NTLB_ENTRIES 48 /* Fixed on all R4XX0 variants... */
+#define NTLB_ENTRIES_HALF 24 /* Fixed on all R4XX0 variants... */
+
+static inline void r4k_flush_tlb_all(void)


+{
+ unsigned long flags;

+ unsigned long old_ctx;
+ int entry;
+
+#ifdef DEBUG_TLB
+ printk("[tlball]");
+#endif
+
+ save_and_cli(flags);
+ /* Save old context and create impossible VPN2 value */
+ old_ctx = (get_entryhi() & 0xff);
+ set_entryhi(KSEG0);
+ set_entrylo0(0);
+ set_entrylo1(0);
+ BARRIER;
+
+ entry = 0;
+
+ /* Blast 'em all away. */
+ while(entry < NTLB_ENTRIES) {
+ set_index(entry);
+ BARRIER;
+ tlb_write_indexed();
+ BARRIER;
+ entry++;
+ }
+ BARRIER;
+ set_entryhi(old_ctx);
+ restore_flags(flags);
+}
+
+static void r4k_flush_tlb_mm(struct mm_struct *mm)
+{
+ if(mm->context != 0) {


+ unsigned long flags;
+

+#ifdef DEBUG_TLB
+ printk("[tlbmm<%d>]", mm->context);
+#endif
+ save_and_cli(flags);
+ get_new_mmu_context(mm, asid_cache);
+ if(mm == current->mm)
+ set_entryhi(mm->context & 0xff);
+ restore_flags(flags);
+ }
+}
+
+static void r4k_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end)
+{
+ if(mm->context != 0) {
+ unsigned long flags;
+ int size;
+
+#ifdef DEBUG_TLB
+ printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
+ start, end);
+#endif
+ save_and_cli(flags);
+ size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ size = (size + 1) >> 1;
+ if(size <= NTLB_ENTRIES_HALF) {
+ int oldpid = (get_entryhi() & 0xff);
+ int newpid = (mm->context & 0xff);
+
+ start &= (PAGE_MASK << 1);
+ end += ((PAGE_SIZE << 1) - 1);
+ end &= (PAGE_MASK << 1);
+ while(start < end) {
+ int idx;
+
+ set_entryhi(start | newpid);
+ start += (PAGE_SIZE << 1);
+ BARRIER;
+ tlb_probe();
+ BARRIER;
+ idx = get_index();
+ set_entrylo0(0);
+ set_entrylo1(0);
+ set_entryhi(KSEG0);
+ BARRIER;
+ if(idx < 0)
+ continue;
+ tlb_write_indexed();
+ BARRIER;
+ }
+ set_entryhi(oldpid);
+ } else {
+ get_new_mmu_context(mm, asid_cache);
+ if(mm == current->mm)
+ set_entryhi(mm->context & 0xff);
+ }
+ restore_flags(flags);
+ }
+}
+
+static void r4k_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+ if(vma->vm_mm->context != 0) {
+ unsigned long flags;
+ int oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+ printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
+#endif
+ newpid = (vma->vm_mm->context & 0xff);
+ page &= (PAGE_MASK << 1);
+ save_and_cli(flags);
+ oldpid = (get_entryhi() & 0xff);
+ set_entryhi(page | newpid);
+ BARRIER;
+ tlb_probe();
+ BARRIER;
+ idx = get_index();
+ set_entrylo0(0);
+ set_entrylo1(0);
+ set_entryhi(KSEG0);
+ if(idx < 0)
+ goto finish;
+ BARRIER;
+ tlb_write_indexed();
+
+ finish:
+ BARRIER;
+ set_entryhi(oldpid);
+ restore_flags(flags);
+ }
+}
+
+/* Load a new root pointer into the TLB. */
+static void r4k_load_pgd(unsigned long pg_dir)
+{
+}
+
+static void r4k_pgd_init(unsigned long page)
+{
+ unsigned long *p = (unsigned long *) page;
+ int i;
+
+ for(i = 0; i < 1024; i+=8) {
+ p[i + 0] = (unsigned long) invalid_pte_table;
+ p[i + 1] = (unsigned long) invalid_pte_table;
+ p[i + 2] = (unsigned long) invalid_pte_table;
+ p[i + 3] = (unsigned long) invalid_pte_table;
+ p[i + 4] = (unsigned long) invalid_pte_table;
+ p[i + 5] = (unsigned long) invalid_pte_table;
+ p[i + 6] = (unsigned long) invalid_pte_table;
+ p[i + 7] = (unsigned long) invalid_pte_table;
+ }
+}
+
+#ifdef DEBUG_TLBUPDATE
+static unsigned long ehi_debug[NTLB_ENTRIES];
+static unsigned long el0_debug[NTLB_ENTRIES];
+static unsigned long el1_debug[NTLB_ENTRIES];
+#endif
+
+/* We will need multiple versions of update_mmu_cache(), one that just
+ * updates the TLB with the new pte(s), and another which also checks
+ * for the R4k "end of page" hardware bug and does the needy.
+ */
+static void r4k_update_mmu_cache(struct vm_area_struct * vma,
+ unsigned long address, pte_t pte)


+{
+ unsigned long flags;

+ pgd_t *pgdp;
+ pmd_t *pmdp;
+ pte_t *ptep;

+ int idx, pid;
+
+ pid = (get_entryhi() & 0xff);
+
+#ifdef DEBUG_TLB
+ if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) {
+ printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
+ (int) (vma->vm_mm->context & 0xff), pid);
+ }
+#endif
+
+ save_and_cli(flags);
+ address &= (PAGE_MASK << 1);
+ set_entryhi(address | (pid));
+ pgdp = pgd_offset(vma->vm_mm, address);
+ BARRIER;
+ tlb_probe();
+ BARRIER;
+ pmdp = pmd_offset(pgdp, address);
+ idx = get_index();
+ ptep = pte_offset(pmdp, address);
+ BARRIER;
+ set_entrylo0(pte_val(*ptep++) >> 6);
+ set_entrylo1(pte_val(*ptep) >> 6);
+ set_entryhi(address | (pid));
+ BARRIER;
+ if(idx < 0) {
+ tlb_write_random();
+#if 0
+ BARRIER;
+ printk("[MISS]");
+#endif
+ } else {
+ tlb_write_indexed();
+#if 0
+ BARRIER;
+ printk("[HIT]");
+#endif
+ }
+#if 0
+ if(!strcmp(current->comm, "args")) {
+ printk("<");
+ for(idx = 0; idx < NTLB_ENTRIES; idx++) {
+ BARRIER;
+ set_index(idx); BARRIER;
+ tlb_read(); BARRIER;
+ address = get_entryhi(); BARRIER;
+ if((address & 0xff) != 0)
+ printk("[%08lx]", address);
+ }
+ printk(">");
+ }
+ BARRIER;
+#endif
+ BARRIER;
+ set_entryhi(pid);
+ BARRIER;
+ restore_flags(flags);
+}
+
+#if 0
+static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma,
+ unsigned long address, pte_t pte)


+{
+ unsigned long flags;

+ pgd_t *pgdp;
+ pmd_t *pmdp;
+ pte_t *ptep;

+ int idx;
+
+ save_and_cli(flags);
+ address &= (PAGE_MASK << 1);
+ set_entryhi(address | (get_entryhi() & 0xff));
+ pgdp = pgd_offset(vma->vm_mm, address);
+ tlb_probe();
+ pmdp = pmd_offset(pgdp, address);
+ idx = get_index();
+ ptep = pte_offset(pmdp, address);
+ set_entrylo0(pte_val(*ptep++) >> 6);
+ set_entrylo1(pte_val(*ptep) >> 6);
+ BARRIER;
+ if(idx < 0)
+ tlb_write_random();
+ else
+ tlb_write_indexed();
+ BARRIER;
+ restore_flags(flags);
+}
+#endif
+
+static void r4k_show_regs(struct pt_regs * regs)
+{
+ /* Saved main processor registers. */
+ printk("$0 : %08lx %08lx %08lx %08lx\n",
+ 0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
+ printk("$4 : %08lx %08lx %08lx %08lx\n",
+ regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+ printk("$8 : %08lx %08lx %08lx %08lx\n",
+ regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
+ printk("$12: %08lx %08lx %08lx %08lx\n",
+ regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+ printk("$16: %08lx %08lx %08lx %08lx\n",
+ regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
+ printk("$20: %08lx %08lx %08lx %08lx\n",
+ regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+ printk("$24: %08lx %08lx\n",
+ regs->regs[24], regs->regs[25]);
+ printk("$28: %08lx %08lx %08lx %08lx\n",
+ regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
+
+ /* Saved cp0 registers. */
+ printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n",
+ regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
+}
+
+/* Detect and size the various r4k caches. */
+static void probe_icache(unsigned long config)
+{
+ unsigned long tmp;
+
+ tmp = (config >> 9) & 7;
+ icache_size = (1 << (12 + tmp));
+ if((config >> 5) & 1)
+ ic_lsize = 32;
+ else
+ ic_lsize = 16;
+
+ printk("Primary ICACHE %dK (linesize %d bytes)\n",
+ (int)(icache_size >> 10), (int)ic_lsize);
+}
+
+static void probe_dcache(unsigned long config)
+{
+ unsigned long tmp;
+
+ tmp = (config >> 6) & 7;
+ dcache_size = (1 << (12 + tmp));
+ if((config >> 4) & 1)
+ dc_lsize = 32;
+ else
+ dc_lsize = 16;
+
+ printk("Primary DCACHE %dK (linesize %d bytes)\n",
+ (int)(dcache_size >> 10), (int)dc_lsize);
+}
+
+static int probe_scache_eeprom(unsigned long config)
+{
+#ifdef CONFIG_SGI
+ volatile unsigned int *cpu_control;
+ unsigned short cmd = 0xc220;
+ unsigned long data = 0;
+ int i, n;
+
+#ifdef __MIPSEB__
+ cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00034);
+#else
+ cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00030);
+#endif
+#define DEASSERT(bit) (*(cpu_control) &= (~(bit)))
+#define ASSERT(bit) (*(cpu_control) |= (bit))
+#define DELAY for(n = 0; n < 100000; n++) __asm__ __volatile__("")
+ DEASSERT(SGIMC_EEPROM_PRE);
+ DEASSERT(SGIMC_EEPROM_SDATAO);
+ DEASSERT(SGIMC_EEPROM_SECLOCK);
+ DEASSERT(SGIMC_EEPROM_PRE);
+ DELAY;
+ ASSERT(SGIMC_EEPROM_CSEL); ASSERT(SGIMC_EEPROM_SECLOCK);
+ for(i = 0; i < 11; i++) {
+ if(cmd & (1<<15))
+ ASSERT(SGIMC_EEPROM_SDATAO);
+ else
+ DEASSERT(SGIMC_EEPROM_SDATAO);
+ DEASSERT(SGIMC_EEPROM_SECLOCK);
+ ASSERT(SGIMC_EEPROM_SECLOCK);
+ cmd <<= 1;
+ }
+ DEASSERT(SGIMC_EEPROM_SDATAO);
+ for(i = 0; i < (sizeof(unsigned short) * 8); i++) {
+ unsigned int tmp;
+
+ DEASSERT(SGIMC_EEPROM_SECLOCK);
+ DELAY;
+ ASSERT(SGIMC_EEPROM_SECLOCK);
+ DELAY;
+ data <<= 1;
+ tmp = *cpu_control;
+ if(tmp & SGIMC_EEPROM_SDATAI)
+ data |= 1;
+ }
+ DEASSERT(SGIMC_EEPROM_SECLOCK);
+ DEASSERT(SGIMC_EEPROM_CSEL);
+ ASSERT(SGIMC_EEPROM_PRE);
+ ASSERT(SGIMC_EEPROM_SECLOCK);
+ data <<= PAGE_SHIFT;
+ printk("R4600/R5000 SCACHE size %dK ", (int) (data >> 10));
+ switch(mips_cputype) {
+ case CPU_R4600:
+ case CPU_R4640:
+ sc_lsize = 32;


+ break;
+
+ default:

+ sc_lsize = 128;
+ break;
+ }
+ printk("linesize %d bytes\n", sc_lsize);
+ scache_size = data;
+ if(data) {
+ unsigned long addr, tmp1, tmp2;
+
+ /* Enable r4600/r5000 cache. But flush it first. */
+ for(addr = KSEG0; addr < (KSEG0 + dcache_size);
+ addr += dc_lsize)
+ flush_dcache_line_indexed(addr);
+ for(addr = KSEG0; addr < (KSEG0 + icache_size);
+ addr += ic_lsize)
+ flush_icache_line_indexed(addr);
+ for(addr = KSEG0; addr < (KSEG0 + scache_size);
+ addr += sc_lsize)
+ flush_scache_line_indexed(addr);
+
+ /* R5000 scache enable is in CP0 config, on R4600 variants
+ * the scache is enable by the memory mapped cache controller.
+ */
+ if(mips_cputype == CPU_R5000) {
+ unsigned long config;
+
+ config = read_32bit_cp0_register(CP0_CONFIG);
+ config |= 0x1000;
+ write_32bit_cp0_register(CP0_CONFIG, config);
+ } else {
+ /* This is really cool... */
+ printk("Enabling R4600 SCACHE\n");


+ __asm__ __volatile__("
+ .set noreorder
+ .set mips3

+ mfc0 %2, $12
+ nop; nop; nop; nop;
+ li %1, 0x80
+ mtc0 %1, $12
+ nop; nop; nop; nop;
+ li %0, 0x1
+ dsll %0, 31
+ lui %1, 0x9000
+ dsll32 %1, 0
+ or %0, %1, %0

+ sb $0, 0(%0)


+ mtc0 $0, $12
+ nop; nop; nop; nop;
+ mtc0 %2, $12
+ nop; nop; nop; nop;

+ .set mips0
+ .set reorder
+ " : "=r" (tmp1), "=r" (tmp2), "=r" (addr));
+ }
+
+ return 1;
+ } else {
+ if(mips_cputype == CPU_R5000)
+ return -1;
+ else
+ return 0;
+ }
+#else
+ /*
+ * XXX For now we don't panic and assume that existing chipset
+ * controlled caches are setup correnctly and are completly
+ * transparent. Works fine for those MIPS machines I know.
+ * Morituri the salutant ...
+ */
+ return 0;
+
+ panic("Cannot probe SCACHE on this machine.");
+#endif
+}
+
+/* If you even _breathe_ on this function, look at the gcc output
+ * and make sure it does not pop things on and off the stack for
+ * the cache sizing loop that executes in KSEG1 space or else
+ * you will crash and burn badly. You have been warned.
+ */
+static int probe_scache(unsigned long config)
+{
+ extern unsigned long stext;
+ unsigned long flags, addr, begin, end, pow2;
+ int tmp;
+
+ tmp = ((config >> 17) & 1);
+ if(tmp)
+ return 0;
+ tmp = ((config >> 22) & 3);
+ switch(tmp) {
+ case 0:
+ sc_lsize = 16;
+ break;
+ case 1:
+ sc_lsize = 32;


+ break;
+ case 2:

+ sc_lsize = 64;


+ break;
+ case 3:

+ sc_lsize = 128;
+ break;
+ }
+
+ begin = (unsigned long) &stext;
+ begin &= ~((4 * 1024 * 1024) - 1);
+ end = begin + (4 * 1024 * 1024);
+
+ /* This is such a bitch, you'd think they would make it
+ * easy to do this. Away you daemons of stupidity!
+ */
+ save_and_cli(flags);
+
+ /* Fill each size-multiple cache line with a valid tag. */
+ pow2 = (64 * 1024);
+ for(addr = begin; addr < end; addr = (begin + pow2)) {
+ unsigned long *p = (unsigned long *) addr;
+ __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
+ pow2 <<= 1;
+ }
+
+ /* Load first line with zero (therefore invalid) tag. */
+ set_taglo(0);
+ set_taghi(0);
+ __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+ __asm__ __volatile__("\n\t.set noreorder\n\t"
+ ".set mips3\n\t"
+ "cache 8, (%0)\n\t"
+ ".set mips0\n\t"
+ ".set reorder\n\t" : : "r" (begin));
+ __asm__ __volatile__("\n\t.set noreorder\n\t"
+ ".set mips3\n\t"
+ "cache 9, (%0)\n\t"
+ ".set mips0\n\t"
+ ".set reorder\n\t" : : "r" (begin));
+ __asm__ __volatile__("\n\t.set noreorder\n\t"
+ ".set mips3\n\t"
+ "cache 11, (%0)\n\t"
+ ".set mips0\n\t"
+ ".set reorder\n\t" : : "r" (begin));
+
+ /* Now search for the wrap around point. */
+ pow2 = (128 * 1024);
+ tmp = 0;
+ for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) {
+ __asm__ __volatile__("\n\t.set noreorder\n\t"
+ ".set mips3\n\t"
+ "cache 7, (%0)\n\t"
+ ".set mips0\n\t"
+ ".set reorder\n\t" : : "r" (addr));
+ __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
+ if(!get_taglo())
+ break;
+ pow2 <<= 1;
+ }
+ restore_flags(flags);
+ addr -= begin;
+ printk("Secondary cache sized at %dK linesize %d\n", (int) (addr >> 10),
+ sc_lsize);
+ scache_size = addr;
+ return 1;
+}
+
+static void setup_noscache_funcs(void)
+{
+ switch(dc_lsize) {
+ case 16:
+ clear_page = r4k_clear_page_d16;
+ copy_page = r4k_copy_page_d16;
+ flush_cache_all = r4k_flush_cache_all_d16i16;
+ flush_cache_mm = r4k_flush_cache_mm_d16i16;
+ flush_cache_range = r4k_flush_cache_range_d16i16;
+ flush_cache_page = r4k_flush_cache_page_d16i16;
+ flush_page_to_ram = r4k_flush_page_to_ram_d16i16;
+ break;
+ case 32:
+ if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2010) {
+ clear_page = r4k_clear_page_r4600_v1;
+ copy_page = r4k_copy_page_r4600_v1;
+ } else {
+ clear_page = r4k_clear_page_d32;
+ copy_page = r4k_copy_page_d32;
+ }
+ flush_cache_all = r4k_flush_cache_all_d32i32;
+ flush_cache_mm = r4k_flush_cache_mm_d32i32;
+ flush_cache_range = r4k_flush_cache_range_d32i32;
+ flush_cache_page = r4k_flush_cache_page_d32i32;
+ flush_page_to_ram = r4k_flush_page_to_ram_d32i32;


+ break;
+ }
+}
+

+static void setup_scache_funcs(void)
+{
+ switch(sc_lsize) {
+ case 16:
+ switch(dc_lsize) {
+ case 16:
+ clear_page = r4k_clear_page_d16;
+ copy_page = r4k_copy_page_d16;
+ flush_cache_all = r4k_flush_cache_all_s16d16i16;
+ flush_cache_mm = r4k_flush_cache_mm_s16d16i16;
+ flush_cache_range = r4k_flush_cache_range_s16d16i16;
+ flush_cache_page = r4k_flush_cache_page_s16d16i16;
+ flush_page_to_ram = r4k_flush_page_to_ram_s16d16i16;
+ break;
+ case 32:
+ clear_page = r4k_clear_page_d32;
+ copy_page = r4k_copy_page_d32;
+ flush_cache_all = r4k_flush_cache_all_s16d32i32;
+ flush_cache_mm = r4k_flush_cache_mm_s16d32i32;
+ flush_cache_range = r4k_flush_cache_range_s16d32i32;
+ flush_cache_page = r4k_flush_cache_page_s16d32i32;
+ flush_page_to_ram = r4k_flush_page_to_ram_s16d32i32;


+ break;
+ };
+ break;

+ case 32:
+ switch(dc_lsize) {
+ case 16:
+ clear_page = r4k_clear_page_d16;
+ copy_page = r4k_copy_page_d16;
+ flush_cache_all = r4k_flush_cache_all_s32d16i16;
+ flush_cache_mm = r4k_flush_cache_mm_s32d16i16;
+ flush_cache_range = r4k_flush_cache_range_s32d16i16;
+ flush_cache_page = r4k_flush_cache_page_s32d16i16;
+ flush_page_to_ram = r4k_flush_page_to_ram_s32d16i16;
+ break;
+ case 32:
+ clear_page = r4k_clear_page_d32;
+ copy_page = r4k_copy_page_d32;
+ flush_cache_all = r4k_flush_cache_all_s32d32i32;
+ flush_cache_mm = r4k_flush_cache_mm_s32d32i32;
+ flush_cache_range = r4k_flush_cache_range_s32d32i32;
+ flush_cache_page = r4k_flush_cache_page_s32d32i32;
+ flush_page_to_ram = r4k_flush_page_to_ram_s32d32i32;
+ break;
+ };
+ case 64:
+ switch(dc_lsize) {
+ case 16:
+ clear_page = r4k_clear_page_d16;
+ copy_page = r4k_copy_page_d16;
+ flush_cache_all = r4k_flush_cache_all_s64d16i16;
+ flush_cache_mm = r4k_flush_cache_mm_s64d16i16;
+ flush_cache_range = r4k_flush_cache_range_s64d16i16;
+ flush_cache_page = r4k_flush_cache_page_s64d16i16;
+ flush_page_to_ram = r4k_flush_page_to_ram_s64d16i16;
+ break;
+ case 32:
+ clear_page = r4k_clear_page_d32;
+ copy_page = r4k_copy_page_d32;
+ flush_cache_all = r4k_flush_cache_all_s64d32i32;
+ flush_cache_mm = r4k_flush_cache_mm_s64d32i32;
+ flush_cache_range = r4k_flush_cache_range_s64d32i32;
+ flush_cache_page = r4k_flush_cache_page_s64d32i32;
+ flush_page_to_ram = r4k_flush_page_to_ram_s64d32i32;
+ break;
+ };
+ case 128:
+ switch(dc_lsize) {
+ case 16:
+ clear_page = r4k_clear_page_d16;
+ copy_page = r4k_copy_page_d16;
+ flush_cache_all = r4k_flush_cache_all_s128d16i16;
+ flush_cache_mm = r4k_flush_cache_mm_s128d16i16;
+ flush_cache_range = r4k_flush_cache_range_s128d16i16;
+ flush_cache_page = r4k_flush_cache_page_s128d16i16;
+ flush_page_to_ram = r4k_flush_page_to_ram_s128d16i16;
+ break;
+ case 32:
+ clear_page = r4k_clear_page_d32;
+ copy_page = r4k_copy_page_d32;
+ flush_cache_all = r4k_flush_cache_all_s128d32i32;
+ flush_cache_mm = r4k_flush_cache_mm_s128d32i32;
+ flush_cache_range = r4k_flush_cache_range_s128d32i32;
+ flush_cache_page = r4k_flush_cache_page_s128d32i32;
+ flush_page_to_ram = r4k_flush_page_to_ram_s128d32i32;
+ break;


+ };
+ break;
+ }
+}
+

+typedef int (*probe_func_t)(unsigned long);
+static probe_func_t probe_scache_kseg1;
+
+void ld_mmu_r4xx0(void)
+{
+ unsigned long cfg = read_32bit_cp0_register(CP0_CONFIG);
+ int sc_present = 0;
+
+ printk("CPU REVISION IS: %08x\n", read_32bit_cp0_register(CP0_PRID));
+
+ probe_icache(cfg);
+ probe_dcache(cfg);
+
+ switch(mips_cputype) {
+ case CPU_R4000PC:
+ case CPU_R4000SC:
+ case CPU_R4000MC:
+ case CPU_R4400PC:
+ case CPU_R4400SC:
+ case CPU_R4400MC:
+try_again:
+ probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
+ sc_present = probe_scache_kseg1(cfg);
+ break;
+
+ case CPU_R4600:
+ case CPU_R4640:
+ case CPU_R4700:
+ case CPU_R5000:
+ probe_scache_kseg1 = (probe_func_t)
+ (KSEG1ADDR(&probe_scache_eeprom));
+ sc_present = probe_scache_eeprom(cfg);
+
+ /* Try using tags if eeprom give us bogus data. */
+ if(sc_present == -1)
+ goto try_again;
+ break;
+ };
+
+ if(!sc_present) {
+ /* Lacks secondary cache. */
+ setup_noscache_funcs();
+ } else {
+ /* Has a secondary cache. */


+ if(mips_cputype != CPU_R4600 &&
+ mips_cputype != CPU_R4640 &&

+ mips_cputype != CPU_R4700 &&
+ mips_cputype != CPU_R5000) {
+ setup_scache_funcs();
+ } else {
+ setup_noscache_funcs();
+ if((mips_cputype != CPU_R5000)) {
+ flush_cache_page =
+ r4k_flush_cache_page_d32i32_r4600;
+ flush_page_to_ram =
+ r4k_flush_page_to_ram_d32i32_r4600;
+ }
+ }
+ }
+
+ flush_cache_sigtramp = r4k_flush_cache_sigtramp;
+
+ flush_tlb_all = r4k_flush_tlb_all;
+ flush_tlb_mm = r4k_flush_tlb_mm;
+ flush_tlb_range = r4k_flush_tlb_range;
+ flush_tlb_page = r4k_flush_tlb_page;
+
+ load_pgd = r4k_load_pgd;
+ pgd_init = r4k_pgd_init;
+ update_mmu_cache = r4k_update_mmu_cache;
+
+ show_regs = r4k_show_regs;
+
+ flush_cache_all();
+ write_32bit_cp0_register(CP0_WIRED, 0);
+
+ /*
+ * You should never change this register:
+ * - On R4600 1.7 the tlbp never hits for pages smaller than
+ * the value in the c0_pagemask register.
+ * - The entire mm handling assumes the c0_pagemask register to
+ * be set for 4kb pages.
+ */
+ write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
+ flush_tlb_all();
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/mm/r6000.c linux/arch/mips/mm/r6000.c
--- v2.1.43/linux/arch/mips/mm/r6000.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/mm/r6000.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,181 @@
+/* $Id: r6000.c,v 1.1 1997/06/06 09:35:31 ralf Exp $
+ * r6000.c: MMU and cache routines for the R6000 processors.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+


+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+

+#include <asm/cacheops.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/sgialib.h>
+
+__asm__(".set mips3"); /* because we know... */


+
+/* Cache operations. XXX Write these dave... */

+static inline void r6000_flush_cache_all(void)


+{
+ /* XXX */
+}
+

+static void r6000_flush_cache_mm(struct mm_struct *mm)


+{
+ /* XXX */
+}
+

+static void r6000_flush_cache_range(struct mm_struct *mm,
+ unsigned long start,
+ unsigned long end)
+{


+ /* XXX */
+}
+

+static void r6000_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long page)


+{
+ /* XXX */
+}
+

+static void r6000_flush_page_to_ram(unsigned long page)


+{
+ /* XXX */
+}
+

+static void r6000_flush_cache_sigtramp(unsigned long page)


+{
+ /* XXX */
+}
+

+/* TLB operations. XXX Write these dave... */

+static inline void r6000_flush_tlb_all(void)


+{
+ /* XXX */
+}
+

+static void r6000_flush_tlb_mm(struct mm_struct *mm)


+{
+ /* XXX */
+}
+

+static void r6000_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end)
+{


+ /* XXX */
+}
+

+static void r6000_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)


+{
+ /* XXX */
+}
+

+static void r6000_load_pgd(unsigned long pg_dir)
+{
+}
+
+static void r6000_pgd_init(unsigned long page)
+{
+ unsigned long dummy1, dummy2;
+
+ /*
+ * This version is optimized for the R6000. We generate dirty lines
+ * in the datacache, overwrite these lines with zeros and then flush
+ * the cache. Sounds horribly complicated but is just a trick to
+ * avoid unnecessary loads of from memory and uncached stores which
+ * are very expensive. Not tested yet as the R6000 is a rare CPU only
+ * available in SGI machines and I don't have one.
+ */
+ __asm__ __volatile__(
+ ".set\tnoreorder\n"
+ "1:\t"
+ "cache\t%5,(%0)\n\t"
+ "sw\t%2,(%0)\n\t"
+ "sw\t%2,4(%0)\n\t"
+ "sw\t%2,8(%0)\n\t"
+ "sw\t%2,12(%0)\n\t"
+ "cache\t%5,16(%0)\n\t"
+ "sw\t%2,16(%0)\n\t"
+ "sw\t%2,20(%0)\n\t"
+ "sw\t%2,24(%0)\n\t"
+ "sw\t%2,28(%0)\n\t"
+ "subu\t%1,1\n\t"
+ "bnez\t%1,1b\n\t"
+ "addiu\t%0,32\n\t"
+ ".set\treorder"
+ :"=r" (dummy1),
+ "=r" (dummy2)
+ :"r" ((unsigned long) invalid_pte_table),
+ "0" (page),
+ "1" (PAGE_SIZE/(sizeof(pmd_t)*8)),
+ "i" (Create_Dirty_Excl_D));
+}
+
+static void r6000_update_mmu_cache(struct vm_area_struct * vma,
+ unsigned long address, pte_t pte)
+{
+ r6000_flush_tlb_page(vma, address);
+ /*
+ * FIXME: We should also reload a new entry into the TLB to
+ * avoid unnecessary exceptions.
+ */
+}
+
+static void r6000_show_regs(struct pt_regs * regs)
+{
+ /*
+ * Saved main processor registers
+ */
+ printk("$0 : %08x %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ 0, (unsigned long) regs->regs[1], (unsigned long) regs->regs[2],
+ (unsigned long) regs->regs[3], (unsigned long) regs->regs[4],
+ (unsigned long) regs->regs[5], (unsigned long) regs->regs[6],
+ (unsigned long) regs->regs[7]);
+ printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (unsigned long) regs->regs[8], (unsigned long) regs->regs[9],
+ (unsigned long) regs->regs[10], (unsigned long) regs->regs[11],
+ (unsigned long) regs->regs[12], (unsigned long) regs->regs[13],
+ (unsigned long) regs->regs[14], (unsigned long) regs->regs[15]);
+ printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (unsigned long) regs->regs[16], (unsigned long) regs->regs[17],
+ (unsigned long) regs->regs[18], (unsigned long) regs->regs[19],
+ (unsigned long) regs->regs[20], (unsigned long) regs->regs[21],
+ (unsigned long) regs->regs[22], (unsigned long) regs->regs[23]);
+ printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ (unsigned long) regs->regs[24], (unsigned long) regs->regs[25],
+ (unsigned long) regs->regs[28], (unsigned long) regs->regs[29],
+ (unsigned long) regs->regs[30], (unsigned long) regs->regs[31]);
+
+ /*
+ * Saved cp0 registers
+ */
+ printk("epc : %08lx\nStatus: %08x\nCause : %08x\n",
+ (unsigned long) regs->cp0_epc, (unsigned int) regs->cp0_status,
+ (unsigned int) regs->cp0_cause);
+}
+
+void ld_mmu_r6000(void)
+{
+ flush_cache_all = r6000_flush_cache_all;
+ flush_cache_mm = r6000_flush_cache_mm;
+ flush_cache_range = r6000_flush_cache_range;
+ flush_cache_page = r6000_flush_cache_page;
+ flush_cache_sigtramp = r6000_flush_cache_sigtramp;
+ flush_page_to_ram = r6000_flush_page_to_ram;
+
+ flush_tlb_all = r6000_flush_tlb_all;
+ flush_tlb_mm = r6000_flush_tlb_mm;
+ flush_tlb_range = r6000_flush_tlb_range;
+ flush_tlb_page = r6000_flush_tlb_page;
+
+ load_pgd = r6000_load_pgd;
+ pgd_init = r6000_pgd_init;
+ update_mmu_cache = r6000_update_mmu_cache;
+
+ show_regs = r6000_show_regs;


+
+ flush_cache_all();
+ flush_tlb_all();

+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/mm/tfp.c linux/arch/mips/mm/tfp.c
--- v2.1.43/linux/arch/mips/mm/tfp.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/mm/tfp.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,102 @@
+/* $Id: tfp.c,v 1.1 1997/06/06 09:35:39 ralf Exp $
+ * tfp.c: MMU and cache routines specific to the r8000 (TFP).
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+


+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+

+#include <asm/page.h>
+#include <asm/pgtable.h>


+#include <asm/system.h>
+#include <asm/sgialib.h>
+
+extern unsigned long mips_tlb_entries;
+
+/* Cache operations. XXX Write these dave... */

+static inline void tfp_flush_cache_all(void)


+{
+ /* XXX */
+}
+

+static void tfp_flush_cache_mm(struct mm_struct *mm)


+{
+ /* XXX */
+}
+

+static void tfp_flush_cache_range(struct mm_struct *mm,
+ unsigned long start,
+ unsigned long end)
+{


+ /* XXX */
+}
+

+static void tfp_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long page)


+{
+ /* XXX */
+}
+

+static void tfp_flush_page_to_ram(unsigned long page)


+{
+ /* XXX */
+}
+

+static void tfp_flush_cache_sigtramp(unsigned long page)


+{
+ /* XXX */
+}
+

+/* TLB operations. XXX Write these dave... */

+static inline void tfp_flush_tlb_all(void)


+{
+ /* XXX */
+}
+

+static void tfp_flush_tlb_mm(struct mm_struct *mm)


+{
+ /* XXX */
+}
+

+static void tfp_flush_tlb_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end)
+{


+ /* XXX */
+}
+

+static void tfp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)


+{
+ /* XXX */
+}
+

+static void tfp_load_pgd(unsigned long pg_dir)
+{
+}
+
+static void tfp_pgd_init(unsigned long page)
+{
+}
+
+void ld_mmu_tfp(void)
+{
+ flush_cache_all = tfp_flush_cache_all;
+ flush_cache_mm = tfp_flush_cache_mm;
+ flush_cache_range = tfp_flush_cache_range;
+ flush_cache_page = tfp_flush_cache_page;
+ flush_cache_sigtramp = tfp_flush_cache_sigtramp;
+ flush_page_to_ram = tfp_flush_page_to_ram;
+
+ flush_tlb_all = tfp_flush_tlb_all;
+ flush_tlb_mm = tfp_flush_tlb_mm;
+ flush_tlb_range = tfp_flush_tlb_range;
+ flush_tlb_page = tfp_flush_tlb_page;
+
+ load_pgd = tfp_load_pgd;
+ pgd_init = tfp_pgd_init;


+
+ flush_cache_all();
+ flush_tlb_all();
+}

+
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/kernel/Makefile linux/arch/mips/sgi/kernel/Makefile
--- v2.1.43/linux/arch/mips/sgi/kernel/Makefile Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/kernel/Makefile Thu Jun 26 12:33:38 1997
@@ -0,0 +1,30 @@
+# $Id: Makefile,v 1.1 1997/06/06 09:36:08 ralf Exp $
+# Makefile for the SGI specific kernel interface routines


+# under Linux.
+#
+# 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...

+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+

+OBJS = indy_mc.o indy_hpc.o indy_int.o system.o indy_timer.o indyIRQ.o \
+ reset.o setup.o time.o
+
+all: sgikern.a
+
+sgikern.a: $(OBJS)
+ $(AR) rcs sgikern.a $(OBJS)
+ sync
+
+indyIRQ.o: indyIRQ.S


+
+dep:
+ $(CPP) -M *.c > .depend

+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/kernel/indyIRQ.S linux/arch/mips/sgi/kernel/indyIRQ.S
--- v2.1.43/linux/arch/mips/sgi/kernel/indyIRQ.S Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/kernel/indyIRQ.S Thu Jun 26 12:33:38 1997
@@ -0,0 +1,129 @@
+/* $Id: indyIRQ.S,v 1.1 1997/06/06 09:36:13 ralf Exp $
+ * indyIRQ.S: Interrupt exception dispatch code for FullHouse and
+ * Guiness.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+
+#include <asm/asm.h>


+#include <asm/mipsconfig.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>

+#include <asm/stackframe.h>
+
+ /* A lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop
+ * and moving across all the pending IRQ bits in the cause
+ * register is _NOT_ the answer, the common case is one
+ * pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register
+ * IRQ mask, that would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs
+ * off, nothing in between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the INDY look basically (barring
+ * software IRQs which we don't use at all) like:
+ *
+ * MIPS IRQ Source
+ * -------- ------
+ * 0 Software (ignored)
+ * 1 Software (ignored)
+ * 2 Local IRQ level zero
+ * 3 Local IRQ level one
+ * 4 8254 Timer zero
+ * 5 8254 Timer one
+ * 6 Bus Error
+ * 7 R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ---- R4k Timer
+ * Local IRQ zero
+ * Local IRQ one
+ * Bus Error
+ * 8254 Timer zero
+ * Lowest ---- 8254 Timer one
+ *
+ * then we just return, if multiple IRQs are pending then
+ * we will just take another exception, big deal.
+ */
+
+ .text
+ .set noreorder
+ .set noat
+ .align 5
+ NESTED(indyIRQ, PT_SIZE, sp)
+ SAVE_ALL


+ CLI
+ .set at

+ mfc0 s0, CP0_CAUSE # get irq mask
+
+ /* First we check for r4k counter/timer IRQ. */
+ andi a0, s0, CAUSEF_IP7
+ beq a0, zero, 1f
+ andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero
+
+ /* Wheee, a timer interrupt. */
+ move a0, sp
+ addiu t0, s7, 1
+ jal indy_timer_interrupt


+ nop # delay slot
+

+ j ret_from_sys_call
+ nop # delay slot
+

+1:
+ beq a0, zero, 1f
+ andi a0, s0, CAUSEF_IP3 # delay slot, check local level one
+
+ /* Wheee, local level zero interrupt. */
+ jal indy_local0_irqdispatch
+ move a0, sp # delay slot
+


+ j ret_from_sys_call
+ nop # delay slot
+

+1:
+ beq a0, zero, 1f
+ andi a0, s0, CAUSEF_IP6 # delay slot, check bus error
+
+ /* Wheee, local level one interrupt. */
+ move a0, sp
+ jal indy_local1_irqdispatch
+ nop
+


+ j ret_from_sys_call
+ nop

+
+1:
+ beq a0, zero, 1f
+ nop
+
+ /* Wheee, an asynchronous bus error... */
+ move a0, sp
+ jal indy_buserror_irq
+ nop
+


+ j ret_from_sys_call
+ nop

+
+1:
+ /* Here by mistake? This is possible, what can happen
+ * is that by the time we take the exception the IRQ
+ * pin goes low, so just leave if this is the case.
+ */
+ andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
+ beq a0, zero, 1f
+ addiu t0, s7, 1
+
+ /* Must be one of the 8254 timers... */
+ move a0, sp
+ jal indy_8254timer_irq
+ nop
+1:


+ j ret_from_sys_call
+ nop

+ END(indyIRQ)
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/kernel/indy_hpc.c linux/arch/mips/sgi/kernel/indy_hpc.c
--- v2.1.43/linux/arch/mips/sgi/kernel/indy_hpc.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/kernel/indy_hpc.c Thu Jun 26 12:33:38 1997
@@ -0,0 +1,114 @@
+/* $Id: indy_hpc.c,v 1.1 1997/06/06 09:36:18 ralf Exp $
+ * indy_hpc.c: Routines for generic manipulation of the HPC controllers.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+


+#include <asm/addrspace.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>

+#include <asm/sgihpc.h>
+#include <asm/sgint23.h>
+#include <asm/sgialib.h>
+
+/* #define DEBUG_SGIHPC */
+
+struct hpc3_regs *hpc3c0, *hpc3c1;
+struct hpc3_miscregs *hpc3mregs;
+
+/* We need software copies of these because they are write only. */
+static unsigned long write1, write2;
+
+/* Machine specific identifier knobs. */
+int sgi_has_ioc2 = 0;
+int sgi_guiness = 0;
+int sgi_boardid;
+
+void sgihpc_write1_modify(int set, int clear)
+{
+ write1 |= set;
+ write1 &= ~clear;
+ hpc3mregs->write1 = write1;
+}
+
+void sgihpc_write2_modify(int set, int clear)
+{
+ write2 |= set;
+ write2 &= ~clear;
+ hpc3mregs->write2 = write2;
+}
+
+void sgihpc_init(void)
+{
+ unsigned long sid, crev, brev;
+
+ hpc3c0 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP0_PBASE);
+ hpc3c1 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP1_PBASE);
+ hpc3mregs = (struct hpc3_miscregs *) (KSEG1 + HPC3_MREGS_PBASE);
+ sid = hpc3mregs->sysid;
+
+ sid &= 0xff;
+ crev = (sid & 0xe0) >> 5;
+ brev = (sid & 0x1e) >> 1;
+
+#ifdef DEBUG_SGIHPC
+ prom_printf("sgihpc_init: crev<%2x> brev<%2x>\n", crev, brev);
+ prom_printf("sgihpc_init: ");
+#endif
+
+ if(sid & 1) {
+#ifdef DEBUG_SGIHPC
+ prom_printf("GUINESS ");
+#endif
+ sgi_guiness = 1;
+ } else {
+#ifdef DEBUG_SGIHPC
+ prom_printf("FULLHOUSE ");
+#endif
+ sgi_guiness = 0;
+ }
+ sgi_boardid = brev;
+
+#ifdef DEBUG_SGIHPC
+ prom_printf("sgi_boardid<%d> ", sgi_boardid);
+#endif
+
+ if(crev == 1) {
+ if((sid & 1) || (brev >= 2)) {
+#ifdef DEBUG_SGIHPC
+ prom_printf("IOC2 ");
+#endif
+ sgi_has_ioc2 = 1;
+ } else {
+#ifdef DEBUG_SGIHPC
+ prom_printf("IOC1 revision 1 ");
+#endif
+ }
+ } else {
+#ifdef DEBUG_SGIHPC
+ prom_printf("IOC1 revision 0 ");
+#endif
+ }
+#ifdef DEBUG_SGIHPC
+ prom_printf("\n");
+#endif
+
+ write1 = (HPC3_WRITE1_PRESET |
+ HPC3_WRITE1_KMRESET |
+ HPC3_WRITE1_ERESET |
+ HPC3_WRITE1_LC0OFF);
+
+ write2 = (HPC3_WRITE2_EASEL |
+ HPC3_WRITE2_NTHRESH |
+ HPC3_WRITE2_TPSPEED |
+ HPC3_WRITE2_EPSEL |
+ HPC3_WRITE2_U0AMODE |
+ HPC3_WRITE2_U1AMODE);
+
+ if(!sgi_guiness)
+ write1 |= HPC3_WRITE1_GRESET;
+ hpc3mregs->write1 = write1;
+ hpc3mregs->write2 = write2;
+
+ hpc3c0->pbus_piocfgs[0][6] |= HPC3_PIOPCFG_HW;
+}
diff -u --recursive --new-file v2.1.43/linux/arch/mips/sgi/kernel/indy_int.c linux/arch/mips/sgi/kernel/indy_int.c
--- v2.1.43/linux/arch/mips/sgi/kernel/indy_int.c Wed Dec 31 16:00:00 1969
+++ linux/arch/mips/sgi/kernel/indy_int.c Mon Jul 7 08:18:54 1997
@@ -0,0 +1,599 @@
+/*
+ * indy_int.c: Routines for generic manipulation of the INT[23] ASIC
+ * found on INDY workstations..
+ *


+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ *

+ * $Id: indy_int.c,v 1.2 1997/06/30 15:53:01 ralf Exp $
+ */
+#include <linux/config.h>
+
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/malloc.h>
+#include <linux/random.h>


+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+

+#include <asm/bitops.h>


+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>

+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/vector.h>


+
+#include <asm/ptrace.h>
+#include <asm/processor.h>

+#include <asm/sgi.h>
+#include <asm/sgihpc.h>
+#include <asm/sgint23.h>
+#include <asm/sgialib.h>
+
+/* #define DEBUG_SGINT */
+
+struct sgi_int2_regs *sgi_i2regs;
+struct sgi_int3_regs *sgi_i3regs;
+struct sgi_ioc_ints *ioc_icontrol;
+struct sgi_ioc_timers *ioc_timers;
+volatile unsigned char *ioc_tclear;
+
+static char lc0msk_to_irqnr[256];
+static char lc1msk_to_irqnr[256];
+static char lc2msk_to_irqnr[256];
+static char lc3msk_to_irqnr[256];
+
+extern asmlinkage void indyIRQ(void);
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void rs_kgdb_hook(int);
+#endif
+
+unsigned int local_irq_count[NR_CPUS];
+unsigned long spurious_count = 0;
+
+/* Local IRQ's are layed out logically like this:
+ *
+ * 0 --> 7 == local 0 interrupts
+ * 8 --> 15 == local 1 interrupts
+ * 16 --> 23 == vectored level 2 interrupts
+ * 24 --> 31 == vectored level 3 interrupts (not used)
+ */
+void disable_local_irq(unsigned int irq_nr)


+{
+ unsigned long flags;
+
+ save_and_cli(flags);

+ switch(irq_nr) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+ ioc_icontrol->imask0 &= ~(1 << irq_nr);
+ break;
+
+ case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
+ ioc_icontrol->imask1 &= ~(1 << (irq_nr - 8));
+ break;
+
+ case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
+ ioc_icontrol->cmeimask0 &= ~(1 << (irq_nr - 16));


+ break;
+
+ default:

+ /* This way we'll see if anyone would ever want vectored
+ * level 3 interrupts. Highly unlikely.
+ */
+ printk("Yeeee, got passed irq_nr %d at disable_irq\n", irq_nr);
+ panic("INVALID IRQ level!");
+ };
+ restore_flags(flags);
+}
+
+void enable_local_irq(unsigned int irq_nr)


+{
+ unsigned long flags;

+ save_and_cli(flags);
+ switch(irq_nr) {
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+ ioc_icontrol->imask0 |= (1 << irq_nr);
+ break;
+
+ case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
+ ioc_icontrol->imask1 |= (1 << (irq_nr - 8));
+ break;
+
+ case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
+ enable_local_irq(7);
+ ioc_icontrol->cmeimask0 |= (1 << (irq_nr - 16));


+ break;
+
+ default:

+ printk("Yeeee, got passed irq_nr %d at disable_irq\n", irq_nr);
+ panic("INVALID IRQ level!");
+ };
+ restore_flags(flags);
+}
+
+void disable_gio_irq(unsigned int irq_nr)
+{
+ /* XXX TODO XXX */
+}
+
+void enable_gio_irq(unsigned int irq_nr)
+{
+ /* XXX TODO XXX */
+}
+
+void disable_hpcdma_irq(unsigned int irq_nr)
+{
+ /* XXX TODO XXX */
+}
+
+void enable_hpcdma_irq(unsigned int irq_nr)
+{
+ /* XXX TODO XXX */
+}
+
+void disable_irq(unsigned int irq_nr)
+{
+ unsigned int n = irq_nr;
+ if(n >= SGINT_END) {
+ printk("whee, invalid irq_nr %d\n", irq_nr);
+ panic("IRQ, you lose...");
+ }
+ if(n >= SGINT_LOCAL0 && n < SGINT_GIO) {
+ disable_local_irq(n - SGINT_LOCAL0);
+ } else if(n >= SGINT_GIO && n < SGINT_HPCDMA) {
+ disable_gio_irq(n - SGINT_GIO);
+ } else if(n >= SGINT_HPCDMA && n < SGINT_END) {
+ disable_hpcdma_irq(n - SGINT_HPCDMA);
+ } else {
+ panic("how did I get here?");
+ }
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+ unsigned int n = irq_nr;
+ if(n >= SGINT_END) {
+ printk("whee, invalid irq_nr %d\n", irq_nr);
+ panic("IRQ, you lose...");
+ }
+ if(n >= SGINT_LOCAL0 && n < SGINT_GIO) {
+ enable_local_irq(n - SGINT_LOCAL0);
+ } else if(n >= SGINT_GIO && n < SGINT_HPCDMA) {
+ enable_gio_irq(n - SGINT_GIO);
+ } else if(n >= SGINT_HPCDMA && n < SGINT_END) {
+ enable_hpcdma_irq(n - SGINT_HPCDMA);
+ } else {
+ panic("how did I get here?");
+ }
+}
+
+#if 0
+/*
+ * Currently unused.
+ */
+static void local_unex(int irq, void *data, struct pt_regs *regs)
+{
+ printk("Whee: unexpected local IRQ at %08lx\n",
+ (unsigned long) regs->cp0_epc);
+ printk("DUMP: stat0<%x> stat1<%x> vmeistat<%x>\n",
+ ioc_icontrol->istat0, ioc_icontrol->istat1,
+ ioc_icontrol->vmeistat);
+}
+#endif
+
+static struct irqaction *local_irq_action[24] = {
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL
+};
+
+int setup_indy_irq(int irq, struct irqaction * new)
+{
+ printk("setup_indy_irq: Yeee, don't know how to setup irq<%d> for %s %p\n",
+ irq, new->name, new->handler);


+ return 0;
+}
+

+static struct irqaction r4ktimer_action = {
+ NULL, 0, 0, "R4000 timer/counter", NULL, NULL,
+};
+
+static struct irqaction indy_berr_action = {
+ NULL, 0, 0, "IP22 Bus Error", NULL, NULL,
+};
+
+static struct irqaction *irq_action[16] = {
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, &indy_berr_action, &r4ktimer_action,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL
+};
+
+int get_irq_list(char *buf)
+{
+ int i, len = 0;
+ int num = 0;
+ struct irqaction * action;
+
+ for (i = 0 ; i < 16 ; i++, num++) {
+ action = irq_action[i];
+ if (!action)
+ continue;
+ len += sprintf(buf+len, "%2d: %8d %c %s",
+ num, kstat.interrupts[num],
+ (action->flags & SA_INTERRUPT) ? '+' : ' ',
+ action->name);
+ for (action=action->next; action; action = action->next) {
+ len += sprintf(buf+len, ",%s %s",
+ (action->flags & SA_INTERRUPT) ? " +" : "",
+ action->name);
+ }
+ len += sprintf(buf+len, " [on-chip]\n");
+ }
+ for (i = 0 ; i < 24 ; i++, num++) {
+ action = local_irq_action[i];
+ if (!action)
+ continue;
+ len += sprintf(buf+len, "%2d: %8d %c %s",
+ num, kstat.interrupts[num],
+ (action->flags & SA_INTERRUPT) ? '+' : ' ',
+ action->name);
+ for (action=action->next; action; action = action->next) {
+ len += sprintf(buf+len, ",%s %s",
+ (action->flags & SA_INTERRUPT) ? " +" : "",
+ action->name);
+ }
+ len += sprintf(buf+len, " [local]\n");
+ }
+ return len;
+}
+
+atomic_t __mips_bh_counter;
+
+#ifdef __SMP__
+#error Send superfluous SMP boxes to ra...@uni-koblenz.de
+#else
+#define irq_enter(cpu, irq) (++local_irq_count[cpu])
+#define irq_exit(cpu, irq) (--local_irq_count[cpu])
+#endif
+
+/*
+ * do_IRQ handles IRQ's that have been installed without the
+ * SA_INTERRUPT flag: it uses the full signal-handling return
+ * and runs with other interrupts enabled. All relatively slow
+ * IRQ's should use this format: notably the keyboard/timer
+ * routines.
+ */
+asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
+{
+ struct irqaction * action = *(irq + irq_action);
+
+ lock_kernel();
+ kstat.interrupts[irq]++;
+ printk("Got irq %d, press a key.", irq);


+ prom_getchar();
+ romvec->imode();

+ while (action) {
+ if (action->flags & SA_SAMPLE_RANDOM)
+ add_interrupt_randomness(irq);
+ action->handler(irq, action->dev_id, regs);
+ action = action->next;
+ }
+ unlock_kernel();
+}
+
+/*
+ * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return
+ * stuff - the handler is also running with interrupts disabled unless
+ * it explicitly enables them later.
+ */
+asmlinkage void do_fast_IRQ(int irq)
+{
+ struct irqaction * action = *(irq + irq_action);
+
+ lock_kernel();
+ printk("Got irq %d, press a key.", irq);


+ prom_getchar();
+ romvec->imode();

+ kstat.interrupts[irq]++;
+ while (action) {
+ if (action->flags & SA_SAMPLE_RANDOM)
+ add_interrupt_randomness(irq);
+ action->handler(irq, action->dev_id, NULL);
+ action = action->next;


+ }
+ unlock_kernel();
+}
+

+int request_local_irq(unsigned int lirq, void (*func)(int, void *, struct pt_regs *),
+ unsigned long iflags, const char *dname, void *devid)
+{
+ struct irqaction *action;
+
+ lirq -= SGINT_LOCAL0;
+ if(lirq >= 24 || !func)
+ return -EINVAL;
+
+ action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+ if(!action)
+ return -ENOMEM;
+
+ action->handler = func;
+ action->flags = iflags;
+ action->mask = 0;
+ action->name = dname;
+ action->dev_id = devid;
+ action->next = 0;
+ local_irq_action[lirq] = action;
+ enable_irq(lirq + SGINT_LOCAL0);


+ return 0;
+}
+

+void free_local_irq(unsigned int lirq, void *dev_id)
+{
+ struct irqaction *action;
+
+ lirq -= SGINT_LOCAL0;
+ if(lirq >= 24) {
+ printk("Aieee: trying to free bogus local irq %d\n",
+ lirq + SGINT_LOCAL0);
+ return;
+ }
+ action = local_irq_action[lirq];
+ local_irq_action[lirq] = NULL;
+ disable_irq(lirq + SGINT_LOCAL0);
+ kfree(action);
+}
+
+int request_irq(unsigned int irq,
+ void (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ const char * devname,
+ void *dev_id)
+{
+ int retval;
+ struct irqaction * action;
+
+ if (irq >= SGINT_END)
+ return -EINVAL;
+ if (!handler)
+ return -EINVAL;
+
+ if((irq >= SGINT_LOCAL0) && (irq < SGINT_GIO))
+ return request_local_irq(irq, handler, irqflags, devname, dev_id);
+
+ action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+ if (!action)
+ return -ENOMEM;
+
+ action->handler = handler;
+ action->flags = irqflags;
+ action->mask = 0;
+ action->name = devname;
+ action->next = NULL;
+ action->dev_id = dev_id;
+
+ retval = setup_indy_irq(irq, action);
+
+ if (retval)
+ kfree(action);


+ return retval;
+}
+

+void free_irq(unsigned int irq, void *dev_id)
+{
+ struct irqaction * action, **p;


+ unsigned long flags;
+

+ if (irq >= SGINT_END) {
+ printk("Trying to free IRQ%d\n",irq);
+ return;
+ }
+ if((irq >= SGINT_LOCAL0) && (irq < SGINT_GIO)) {
+ free_local_irq(irq, dev_id);
+ return;
+ }
+ for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
+ if (action->dev_id != dev_id)
+ continue;
+
+ /* Found it - now free it */
+ save_and_cli(flags);
+ *p = action->next;
+ restore_flags(flags);
+ kfree(action);
+ return;
+ }
+ printk("Trying to free free IRQ%d\n",irq);
+}
+
+void init_IRQ(void)


+{
+ int i;
+

+ for (i = 0; i < 16 ; i++)
+ set_int_vector(i, 0);
+ irq_setup();
+}
+
+void indy_local0_irqdispatch(struct pt_regs *regs)
+{
+ struct irqaction *action;
+ unsigned char mask = ioc_icontrol->istat0;
+ unsigned char mask2 = 0;
+ int irq;
+
+ mask &= ioc_icontrol->imask0;
+ if(mask & ISTAT0_LIO2) {
+ mask2 = ioc_icontrol->vmeistat;
+ mask2 &= ioc_icontrol->cmeimask0;
+ irq = lc2msk_to_irqnr[mask2];
+ action = local_irq_action[irq];
+ } else {
+ irq = lc0msk_to_irqnr[mask];
+ action = local_irq_action[irq];
+ }
+#if 0
+ printk("local0_dispatch: got irq %d mask %2x mask2 %2x\n",
+ irq, mask, mask2);
+ prom_getchar();
+#endif
+ kstat.interrupts[irq + 16]++;
+ action->handler(irq, action->dev_id, regs);
+}
+
+void indy_local1_irqdispatch(struct pt_regs *regs)
+{
+ struct irqaction *action;
+ unsigned char mask = ioc_icontrol->istat1;
+ unsigned char mask2 = 0;
+ int irq;
+
+ mask &= ioc_icontrol->imask1;
+ if(mask & ISTAT1_LIO3) {
+ printk("WHee: Got an LIO3 irq, winging it...\n");
+ mask2 = ioc_icontrol->vmeistat;
+ mask2 &= ioc_icontrol->cmeimask1;
+ irq = lc3msk_to_irqnr[ioc_icontrol->vmeistat];
+ action = local_irq_action[irq];
+ } else {
+ irq = lc1msk_to_irqnr[mask];
+ action = local_irq_action[irq];
+ }
+#if 0
+ printk("local1_dispatch: got irq %d mask %2x mask2 %2x\n",
+ irq, mask, mask2);
+ prom_getchar();
+#endif
+ kstat.interrupts[irq + 24]++;
+ action->handler(irq, action->dev_id, regs);
+}
+
+void indy_buserror_irq(struct pt_regs *regs)
+{
+ kstat.interrupts[6]++;
+ printk("Got a bus error IRQ, shouldn't happen yet\n");
+ show_regs(regs);
+ printk("Spinning...\n");


+ while(1)
+ ;
+}
+

+/* Misc. crap just to keep the kernel linking... */
+unsigned long probe_irq_on (void)


+{
+ return 0;
+}
+

+int probe_irq_off (unsigned long irqs)


+{
+ return 0;
+}
+

+void sgint_init(void)
+{
+ int i;
+#ifdef CONFIG_REMOTE_DEBUG
+ char *ctype;
+#endif
+
+ sgi_i2regs = (struct sgi_int2_regs *) (KSEG1 + SGI_INT2_BASE);
+ sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE);
+
+ /* Init local mask --> irq tables. */
+ for(i = 0; i < 256; i++) {
+ if(i & 0x80) {
+ lc0msk_to_irqnr[i] = 7;
+ lc1msk_to_irqnr[i] = 15;
+ lc2msk_to_irqnr[i] = 23;
+ lc3msk_to_irqnr[i] = 31;


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 16'
echo 'File patch-2.1.44 is continued in part 17'
echo 17 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part25

#!/bin/sh
# this is part 25 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 25; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

X
X ccslow: mov 0, %g5
X brlez,pn %g1, 4f
@@ -401,9 +627,9 @@
X be,a,pt %icc, 1f
X srl %g1, 1, %o3
X sub %g1, 1, %g1
- EX(lduba [%o0] %asi, %g5, add %g1, 1,#)
+ lduba [%o0] %asi, %g5
X add %o0, 1, %o0
- EX2(stb %g5, [%o1],#)
+ stb %g5, [%o1]
X srl %g1, 1, %o3
X add %o1, 1, %o1
X 1: brz,a,pn %o3, 3f
@@ -411,33 +637,33 @@
X andcc %o0, 2, %g0
X be,a,pt %icc, 1f
X srl %o3, 1, %o3
- EX(lduha [%o0] %asi, %o4, add %g1, 0,#)
+ lduha [%o0] %asi, %o4
X sub %g1, 2, %g1
X srl %o4, 8, %g2
X sub %o3, 1, %o3
- EX2(stb %g2, [%o1],#)
+ stb %g2, [%o1]
X add %o4, %g5, %g5
- EX2(stb %o4, [%o1 + 1],#)
+ stb %o4, [%o1 + 1]
X add %o0, 2, %o0
X srl %o3, 1, %o3
X add %o1, 2, %o1
X 1: brz,a,pn %o3, 2f
X andcc %g1, 2, %g0
- EX3(lda [%o0] %asi, %o4,#)
+ lda [%o0] %asi, %o4
X 5: srl %o4, 24, %g2
X srl %o4, 16, %g3
- EX2(stb %g2, [%o1],#)
+ stb %g2, [%o1]
X srl %o4, 8, %g2
- EX2(stb %g3, [%o1 + 1],#)
+ stb %g3, [%o1 + 1]
X add %o0, 4, %o0
- EX2(stb %g2, [%o1 + 2],#)
+ stb %g2, [%o1 + 2]
X addcc %o4, %g5, %g5
- EX2(stb %o4, [%o1 + 3],#)
+ stb %o4, [%o1 + 3]
X addc %g5, %g0, %g5 ! I am now to lazy to optimize this (question is if it
X add %o1, 4, %o1 ! is worthy). Maybe some day - with the sll/srl
X subcc %o3, 1, %o3 ! tricks
X bne,a,pt %icc, 5b
- EX3(lda [%o0] %asi, %o4,#)
+ lda [%o0] %asi, %o4
X sll %g5, 16, %g2
X srl %g5, 16, %g5
X srl %g2, 16, %g2
@@ -445,19 +671,19 @@
X add %g2, %g5, %g5
X 2: be,a,pt %icc, 3f
X andcc %g1, 1, %g0
- EX(lduha [%o0] %asi, %o4, and %g1, 3,#)
+ lduha [%o0] %asi, %o4
X andcc %g1, 1, %g0
X srl %o4, 8, %g2
X add %o0, 2, %o0
- EX2(stb %g2, [%o1],#)
+ stb %g2, [%o1]
X add %g5, %o4, %g5
- EX2(stb %o4, [%o1 + 1],#)
+ stb %o4, [%o1 + 1]
X add %o1, 2, %o1
X 3: be,a,pt %icc, 1f
X sll %g5, 16, %o4
- EX(lduba [%o0] %asi, %g2, add %g0, 1,#)
+ lduba [%o0] %asi, %g2
X sll %g2, 8, %o4
- EX2(stb %g2, [%o1],#)
+ stb %g2, [%o1]
X add %g5, %o4, %g5
X sll %g5, 16, %o4
X 1: addcc %o4, %g5, %g5
@@ -474,103 +700,3 @@
X retl
X srl %o0, 0, %o0
X __csum_partial_copy_end:
-
- .section .fixup,#alloc,#execinstr
- .align 4
-/* We do these strange calculations for the csum_*_from_user case only, ie.
- * we only bother with faults on loads... */
-
-/* o2 = ((g2%20)&3)*8
- * o3 = g1 - (g2/20)*32 - o2 */
-20:
- cmp %g2, 20
- blu,a,pn %icc, 1f
- and %g2, 3, %o2
- sub %g1, 32, %g1
- ba,pt %xcc, 20b
- sub %g2, 20, %g2
-1:
- sll %o2, 3, %o2
- ba,pt %xcc, 31f
- sub %g1, %o2, %o3
-
-/* o2 = (!(g2 & 15) ? 0 : (((g2 & 15) + 1) & ~1)*8)
- * o3 = g1 - (g2/16)*32 - o2 */
-21:
- andcc %g2, 15, %o3
- srl %g2, 4, %g2
- be,a,pn %icc, 1f
- clr %o2
- add %o3, 1, %o3
- and %o3, 14, %o3
- sll %o3, 3, %o2
-1:
- sll %g2, 5, %g2
- sub %g1, %g2, %o3
- ba,pt %xcc, 31f
- sub %o3, %o2, %o3
-
-/* o0 += (g2/10)*16 - 0x70
- * 01 += (g2/10)*16 - 0x70
- * o2 = (g2 % 10) ? 8 : 0
- * o3 += 0x70 - (g2/10)*16 - o2 */
-22:
- cmp %g2, 10
- blu,a,pt %xcc, 1f
- sub %o0, 0x70, %o0
- add %o0, 16, %o0
- add %o1, 16, %o1
- sub %o3, 16, %o3
- ba,pt %xcc, 22b
- sub %g2, 10, %g2
-1:
- sub %o1, 0x70, %o1
- add %o3, 0x70, %o3
- clr %o2
- movrnz %g2, 8, %o2
- ba,pt %xcc, 31f
- sub %o3, %o2, %o3
-96:
- and %g1, 3, %g1
- sll %o3, 2, %o3
- add %g1, %o3, %o3
-30:
-/* %o1 is dst
- * %o3 is # bytes to zero out
- * %o4 is faulting address
- * %o5 is %pc where fault occured */
- clr %o2
-31:
-/* %o0 is src
- * %o1 is dst
- * %o2 is # of bytes to copy from src to dst
- * %o3 is # bytes to zero out
- * %o4 is faulting address
- * %o5 is %pc where fault occured */
- save %sp, -136, %sp
- mov %i5, %o0
- mov %i7, %o1
- mov %i4, %o2
- call lookup_fault
- mov %g7, %i4
- cmp %o0, 2
- bne,pn %icc, 1f
- add %g0, -EFAULT, %i5
- brz,pn %i2, 2f
- mov %i0, %o1
- mov %i1, %o0
- call __copy_from_user
- mov %i2, %o2
- brnz,a,pn %o0, 2f
- add %i3, %i2, %i3
- add %i1, %i2, %i1
-2:
- mov %i1, %o0
- wr %g0, ASI_S, %asi
- call __bzero_noasi
- mov %i3, %o1
-1:
- ldx [%sp + STACK_BIAS + 264], %o2 ! struct_ptr of parent
- st %i5, [%o2]
- ret
- restore
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/lib/copy_from_user.S linux/arch/sparc64/lib/copy_from_user.S
--- v2.1.43/linux/arch/sparc64/lib/copy_from_user.S Mon Jun 16 16:35:54 1997
+++ linux/arch/sparc64/lib/copy_from_user.S Wed Dec 31 16:00:00 1969
@@ -1,469 +0,0 @@
-/* copy_user.S: Sparc optimized copy_from_user code.
- *
- * Copyright(C) 1995 Linus Torvalds
- * Copyright(C) 1996 David S. Miller
- * Copyright(C) 1996 Eddie C. Dost
- * Copyright(C) 1996,1997 Jakub Jelinek
- *
- * derived from:
- * e-mail between David and Eddie.
- *
- * Returns 0 if successful, otherwise count of bytes not copied yet
- *
- * FIXME: This code should be optimized for sparc64... -jj
- */
-
-#include <asm/ptrace.h>
-#include <asm/asi.h>
-#include <asm/head.h>
-
-#define PRE_RETL sethi %uhi(KERNBASE), %g4; sllx %g4, 32, %g4;
-
-#define EX(x,y,a,b,z) \
-98: x,y; \
- .section .fixup,z##alloc,z##execinstr; \
- .align 4; \
-99: PRE_RETL \
- retl; \
- a, b, %o0; \
- .section __ex_table,z##alloc; \
- .align 8; \
- .xword 98b, 99b; \
- .text; \
- .align 4
-
-#define EX2(x,y,c,d,e,a,b,z) \
-98: x,y; \
- .section .fixup,z##alloc,z##execinstr; \
- .align 4; \
-99: c, d, e; \
- PRE_RETL \
- retl; \
- a, b, %o0; \
- .section __ex_table,z##alloc; \
- .align 8; \
- .xword 98b, 99b; \
- .text; \
- .align 4
-
-#define EXO2(x,y,z) \
-98: x,##y; \
- .section __ex_table,z##alloc; \
- .align 8; \
- .xword 98b, 97f; \
- .text; \
- .align 4
-
-#define EXT(start,end,handler,z) \
- .section __ex_table,z##alloc; \
- .align 8; \
- .xword start, 0, end, handler; \
- .text; \
- .align 4
-
-/* Please do not change following macros unless you change logic used
- * in .fixup at the end of this file as well
- */
-
-/* Both these macros have to start with exactly the same insn */
-#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
- ldda [%src + offset + 0x00] %asi, %t0; \
- ldda [%src + offset + 0x08] %asi, %t2; \
- ldda [%src + offset + 0x10] %asi, %t4; \
- ldda [%src + offset + 0x18] %asi, %t6; \
- st %t0, [%dst + offset + 0x00]; \
- st %t1, [%dst + offset + 0x04]; \
- st %t2, [%dst + offset + 0x08]; \
- st %t3, [%dst + offset + 0x0c]; \
- st %t4, [%dst + offset + 0x10]; \
- st %t5, [%dst + offset + 0x14]; \
- st %t6, [%dst + offset + 0x18]; \
- st %t7, [%dst + offset + 0x1c];
-
-#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
- ldda [%src + offset + 0x00] %asi, %t0; \
- ldda [%src + offset + 0x08] %asi, %t2; \
- ldda [%src + offset + 0x10] %asi, %t4; \
- ldda [%src + offset + 0x18] %asi, %t6; \
- std %t0, [%dst + offset + 0x00]; \
- std %t2, [%dst + offset + 0x08]; \
- std %t4, [%dst + offset + 0x10]; \
- std %t6, [%dst + offset + 0x18];
-
-#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
- ldda [%src - offset - 0x10] %asi, %t0; \
- ldda [%src - offset - 0x08] %asi, %t2; \
- st %t0, [%dst - offset - 0x10]; \
- st %t1, [%dst - offset - 0x0c]; \
- st %t2, [%dst - offset - 0x08]; \
- st %t3, [%dst - offset - 0x04];
-
-#define MOVE_HALFCHUNK(src, dst, offset, t0, t1, t2, t3) \
- lduha [%src + offset + 0x00] %asi, %t0; \
- lduha [%src + offset + 0x02] %asi, %t1; \
- lduha [%src + offset + 0x04] %asi, %t2; \
- lduha [%src + offset + 0x06] %asi, %t3; \
- sth %t0, [%dst + offset + 0x00]; \
- sth %t1, [%dst + offset + 0x02]; \
- sth %t2, [%dst + offset + 0x04]; \
- sth %t3, [%dst + offset + 0x06];
-
-#define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
- lduba [%src - offset - 0x02] %asi, %t0; \
- lduba [%src - offset - 0x01] %asi, %t1; \
- stb %t0, [%dst - offset - 0x02]; \
- stb %t1, [%dst - offset - 0x01];
-
- .text
- .align 4
-
- .globl __copy_from_user
-dword_align:
- andcc %o1, 1, %g0
- be 4f
- andcc %o1, 2, %g0
-
- EXO2(lduba [%o1] %asi, %g2,#)
- add %o1, 1, %o1
- stb %g2, [%o0]
- sub %o2, 1, %o2
- bne 3f
- add %o0, 1, %o0
-
- EXO2(lduha [%o1] %asi, %g2,#)
- add %o1, 2, %o1
- sth %g2, [%o0]
- sub %o2, 2, %o2
- ba,pt %xcc, 3f
- add %o0, 2, %o0
-4:
- EXO2(lduha [%o1] %asi, %g2,#)
- add %o1, 2, %o1
- sth %g2, [%o0]
- sub %o2, 2, %o2
- ba,pt %xcc, 3f
- add %o0, 2, %o0
-
-__copy_from_user: /* %o0=dst %o1=src %o2=len */
- wr %g0, ASI_S, %asi
- xor %o0, %o1, %o4
-1:
- andcc %o4, 3, %o5
-2:
- bne,pn %icc, cannot_optimize
- cmp %o2, 15
-
- bleu,pn %xcc, short_aligned_end
- andcc %o1, 3, %g0
-
- bne,pn %icc, dword_align
-3:
- andcc %o1, 4, %g0
-
- be,pt %icc, 2f
- mov %o2, %g1
-
- EXO2(lda [%o1] %asi, %o4,#)
- sub %g1, 4, %g1
- st %o4, [%o0]
- add %o1, 4, %o1
- add %o0, 4, %o0
-2:
- andcc %g1, 0xffffffffffffff80, %g7
- be,pn %xcc, 3f
- andcc %o0, 4, %g0
-
- be,pn %icc, ldd_std + 4
-5:
- MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
-80:
- EXT(5b, 80b, 50f,#)
- subcc %g7, 128, %g7
- add %o1, 128, %o1
- bne,pt %xcc, 5b
- add %o0, 128, %o0
-3:
- andcc %g1, 0x70, %g7
- be,pn %icc, copy_user_table_end
- andcc %g1, 8, %g0
-100:
- rd %pc, %o5
- srl %g7, 1, %o4
- add %g7, %o4, %o4
- add %o1, %g7, %o1
- sub %o5, %o4, %o5
- jmpl %o5 + (copy_user_table_end - 100b), %g0
- add %o0, %g7, %o0
-
-copy_user_table:
- MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
-copy_user_table_end:
- EXT(copy_user_table, copy_user_table_end, 51f,#)
- be,pt %icc, copy_user_last7
- andcc %g1, 4, %g0
-
- EX(ldda [%o1] %asi, %g2, and %g1, 0xf,#)
- add %o0, 8, %o0
- add %o1, 8, %o1
- st %g2, [%o0 - 0x08]
- st %g3, [%o0 - 0x04]
-copy_user_last7:
- be,pn %icc, 1f
- andcc %g1, 2, %g0
-
- EX(lda [%o1] %asi, %g2, and %g1, 7,#)
- add %o1, 4, %o1
- st %g2, [%o0]
- add %o0, 4, %o0
-1:
- be,pn %icc, 1f
- andcc %g1, 1, %g0
-
- EX(lduha [%o1] %asi, %g2, and %g1, 3,#)
- add %o1, 2, %o1
- sth %g2, [%o0]
- add %o0, 2, %o0
-1:
- be,pn %icc, 1f
- nop
-
- EX(lduba [%o1] %asi, %g2, add %g0, 1,#)
- stb %g2, [%o0]
-1:
- PRE_RETL
- retl
- clr %o0
-
-ldd_std:
- MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
-81:
- EXT(ldd_std, 81b, 52f,#)
- subcc %g7, 128, %g7
- add %o1, 128, %o1
- bne,pt %xcc, ldd_std
- add %o0, 128, %o0
-
- andcc %g1, 0x70, %g7
- be,pn %icc, copy_user_table_end
- andcc %g1, 8, %g0
-101:
- rd %pc, %o5
- srl %g7, 1, %o4
- add %g7, %o4, %o4
- add %o1, %g7, %o1
- sub %o5, %o4, %o5
- jmpl %o5 + (copy_user_table_end - 101b), %g0
- add %o0, %g7, %o0
-
-cannot_optimize:
- bleu short_end
- cmp %o5, 2
-
- bne byte_chunk
- and %o2, 0xfffffffffffffff0, %o3
-
- andcc %o1, 1, %g0
- be 10f
- nop
-
- EXO2(lduba [%o1] %asi, %g2,#)
- add %o1, 1, %o1
- stb %g2, [%o0]
- sub %o2, 1, %o2
- andcc %o2, 0xfffffffffffffff0, %o3
- be short_end
- add %o0, 1, %o0
-10:
- MOVE_HALFCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
- MOVE_HALFCHUNK(o1, o0, 0x08, g2, g3, g4, g5)
-82:
- EXT(10b, 82b, 53f,#)
- subcc %o3, 0x10, %o3
- add %o1, 0x10, %o1
- bne 10b
- add %o0, 0x10, %o0
- ba,pt %xcc, 2f
- and %o2, 0xe, %o3
-
-byte_chunk:
- MOVE_SHORTCHUNK(o1, o0, -0x02, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x04, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x06, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x08, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x0a, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x0c, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x0e, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x10, g2, g3)
-83:
- EXT(byte_chunk, 83b, 54f,#)
- subcc %o3, 0x10, %o3
- add %o1, 0x10, %o1
- bne,pt %xcc, byte_chunk
- add %o0, 0x10, %o0
-
-short_end:
- and %o2, 0xe, %o3
-2:
- rd %pc, %o5
- sll %o3, 3, %o4
- add %o0, %o3, %o0
- sub %o5, %o4, %o5
- add %o1, %o3, %o1
- jmpl %o5 + (short_table_end - 2b), %g0
- andcc %o2, 1, %g0
-84:
- MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
-short_table_end:
- EXT(84b, short_table_end, 55f,#)
- be 1f
- nop
- EX(lduba [%o1] %asi, %g2, add %g0, 1,#)
- stb %g2, [%o0]
-1:
- PRE_RETL
- retl
- clr %o0
-
-short_aligned_end:
- bne short_end
- andcc %o2, 8, %g0
-
- be 1f
- andcc %o2, 4, %g0
-
- EXO2(lda [%o1 + 0x00] %asi, %g2,#)
- EX(lda [%o1 + 0x04] %asi, %g3, sub %o2, 4,#)
- add %o1, 8, %o1
- st %g2, [%o0 + 0x00]
- st %g3, [%o0 + 0x04]
- add %o0, 8, %o0
-1:
- ba,pt %xcc, copy_user_last7
- mov %o2, %g1
-
- .section .fixup,#alloc,#execinstr
- .align 4
-97:
- PRE_RETL
- retl
- mov %o2, %o0
-/* exception routine sets %g2 to (broken_insn - first_insn)>>2 */
-50:
-/* This magic counts how many bytes are left when crash in MOVE_BIGCHUNK
- * happens. This is derived from the amount ldd reads, st stores, etc.
- * x = g2 % 12;
- * o0 = g1 + g7 - ((g2 / 12) * 32 + (x < 4) ? x * 8 : (x - 4) * 4)
- */
- cmp %g2, 12
- bcs 1f
- cmp %g2, 24
- bcs 2f
- cmp %g2, 36
- bcs 3f
- nop
- sub %g2, 12, %g2
- sub %g7, 32, %g7
-3:
- sub %g2, 12, %g2
- sub %g7, 32, %g7
-2:
- sub %g2, 12, %g2
- sub %g7, 32, %g7
-1:
- cmp %g2, 4
- bcs,a 1f
- sll %g2, 3, %g2
- sub %g2, 4, %g2
- sll %g2, 2, %g2
-1:
- and %g1, 0x7f, %o0
- add %o0, %g7, %o0
- PRE_RETL
- retl
- sub %o0, %g2, %o0
-51:
-/* i = 41 - g2; j = i % 6;
- * o0 = (g1 & 15) + (i / 6) * 16 + (j < 4) ? (j + 1) * 4 : (j - 3) * 8;
- */
- neg %g2
- and %g1, 0xf, %g1
- add %g2, 41, %g2
-1:
- cmp %g2, 6
- bcs,a 2f
- cmp %g2, 4
- add %g1, 16, %g1
- b 1b
- sub %g2, 6, %g2
-2:
- bcs,a 3f
- inc %g2
- sub %g2, 3, %g2
- b 2f
- sll %g2, 3, %g2
-3:
- sll %g2, 2, %g2
-2:
- PRE_RETL
- retl
- add %g1, %g2, %o0
-52:
-/* o0 = g1 + g7 - (g2 / 8) * 32 + (x & 3) * 8 */
- and %g2, 0xfffffffffffffff8, %g4
- and %g2, 3, %g2
- sll %g4, 2, %g4
- sll %g2, 3, %g2
- add %g2, %g4, %g2
- b,a 1b
-53:
-/* o0 = o3 + (o2 & 15) - (g2 & 8) - (g2 & 3) * 2 */
- and %g2, 3, %g4
- and %g2, 0xfffffffffffffff8, %g2
- sll %g4, 1, %g4
- add %g2, %g4, %g2
- and %o2, 0xf, %o0
- add %o0, %o3, %o0
- PRE_RETL
- retl
- sub %o0, %g2, %o0
-54:
-/* o0 = o3 + (o2 & 15) - (g2 / 4) * 2 - (g2 & 1) */
- srl %g2, 2, %o4
- and %g2, 1, %o1
- sll %o4, 1, %o4
- and %o2, 0xf, %o2
- sub %o3, %o1, %o3
- sub %o2, %o4, %o2
- PRE_RETL
- retl
- add %o2, %o3, %o0
-55:
-/* o0 = (o2 & 1) + (27 - g2)/4 * 2 + ((27 - g2) & 1) */
- neg %g2
- and %o2, 1, %o2
- add %g2, 27, %g2
- srl %g2, 2, %o1
- and %g2, 1, %g2
- sll %o1, 1, %o1
- add %o2, %g2, %o0
- PRE_RETL
- retl
- add %o0, %o1, %o0
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/lib/copy_to_user.S linux/arch/sparc64/lib/copy_to_user.S
--- v2.1.43/linux/arch/sparc64/lib/copy_to_user.S Mon Jun 16 16:35:54 1997
+++ linux/arch/sparc64/lib/copy_to_user.S Wed Dec 31 16:00:00 1969
@@ -1,469 +0,0 @@
-/* copy_user.S: Sparc optimized copy_to_user code.
- *
- * Copyright(C) 1995 Linus Torvalds
- * Copyright(C) 1996 David S. Miller
- * Copyright(C) 1996 Eddie C. Dost
- * Copyright(C) 1996,1997 Jakub Jelinek
- *
- * derived from:
- * e-mail between David and Eddie.
- *
- * Returns 0 if successful, otherwise count of bytes not copied yet
- *
- * FIXME: This code should be optimized for sparc64... -jj
- */
-
-#include <asm/ptrace.h>
-#include <asm/head.h>
-#include <asm/asi.h>
-
-#define PRE_RETL sethi %uhi(KERNBASE), %g4; sllx %g4, 32, %g4;
-
-#define EX(x,y,a,b,z) \
-98: x,y; \
- .section .fixup,z##alloc,z##execinstr; \
- .align 4; \
-99: PRE_RETL \
- retl; \
- a, b, %o0; \
- .section __ex_table,z##alloc; \
- .align 8; \
- .xword 98b, 99b; \
- .text; \
- .align 4
-
-#define EX2(x,y,c,d,e,a,b,z) \
-98: x,y; \
- .section .fixup,z##alloc,z##execinstr; \
- .align 4; \
-99: c, d, e; \
- PRE_RETL \
- retl; \
- a, b, %o0; \
- .section __ex_table,z##alloc; \
- .align 8; \
- .xword 98b, 99b; \
- .text; \
- .align 4
-
-#define EXO2(x,y,z) \
-98: x,##y; \
- .section __ex_table,z##alloc; \
- .align 8; \
- .xword 98b, 97f; \
- .text; \
- .align 4
-
-#define EXT(start,end,handler,z) \
- .section __ex_table,z##alloc; \
- .align 8; \
- .xword start, 0, end, handler; \
- .text; \
- .align 4
-
-/* Please do not change following macros unless you change logic used
- * in .fixup at the end of this file as well
- */
-
-/* Both these macros have to start with exactly the same insn */
-#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
- ldd [%src + offset + 0x00], %t0; \
- ldd [%src + offset + 0x08], %t2; \
- ldd [%src + offset + 0x10], %t4; \
- ldd [%src + offset + 0x18], %t6; \
- sta %t0, [%dst + offset + 0x00] %asi; \
- sta %t1, [%dst + offset + 0x04] %asi; \
- sta %t2, [%dst + offset + 0x08] %asi; \
- sta %t3, [%dst + offset + 0x0c] %asi; \
- sta %t4, [%dst + offset + 0x10] %asi; \
- sta %t5, [%dst + offset + 0x14] %asi; \
- sta %t6, [%dst + offset + 0x18] %asi; \
- sta %t7, [%dst + offset + 0x1c] %asi;
-
-#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
- ldd [%src + offset + 0x00], %t0; \
- ldd [%src + offset + 0x08], %t2; \
- ldd [%src + offset + 0x10], %t4; \
- ldd [%src + offset + 0x18], %t6; \
- stda %t0, [%dst + offset + 0x00] %asi; \
- stda %t2, [%dst + offset + 0x08] %asi; \
- stda %t4, [%dst + offset + 0x10] %asi; \
- stda %t6, [%dst + offset + 0x18] %asi;
-
-#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
- ldd [%src - offset - 0x10], %t0; \
- ldd [%src - offset - 0x08], %t2; \
- sta %t0, [%dst - offset - 0x10] %asi; \
- sta %t1, [%dst - offset - 0x0c] %asi; \
- sta %t2, [%dst - offset - 0x08] %asi; \
- sta %t3, [%dst - offset - 0x04] %asi;
-
-#define MOVE_HALFCHUNK(src, dst, offset, t0, t1, t2, t3) \
- lduh [%src + offset + 0x00], %t0; \
- lduh [%src + offset + 0x02], %t1; \
- lduh [%src + offset + 0x04], %t2; \
- lduh [%src + offset + 0x06], %t3; \
- stha %t0, [%dst + offset + 0x00] %asi; \
- stha %t1, [%dst + offset + 0x02] %asi; \
- stha %t2, [%dst + offset + 0x04] %asi; \
- stha %t3, [%dst + offset + 0x06] %asi;
-
-#define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
- ldub [%src - offset - 0x02], %t0; \
- ldub [%src - offset - 0x01], %t1; \
- stba %t0, [%dst - offset - 0x02] %asi; \
- stba %t1, [%dst - offset - 0x01] %asi;
-
- .text
- .align 4
-
- .globl __copy_to_user
-dword_align:
- andcc %o1, 1, %g0
- be 4f
- andcc %o1, 2, %g0
-
- ldub [%o1], %g2
- add %o1, 1, %o1
- EXO2(stba %g2, [%o0] %asi,#)
- sub %o2, 1, %o2
- bne 3f
- add %o0, 1, %o0
-
- lduh [%o1], %g2
- add %o1, 2, %o1
- EXO2(stha %g2, [%o0] %asi,#)
- sub %o2, 2, %o2
- ba,pt %xcc, 3f
- add %o0, 2, %o0
-4:
- lduh [%o1], %g2
- add %o1, 2, %o1
- EXO2(stha %g2, [%o0] %asi,#)
- sub %o2, 2, %o2
- ba,pt %xcc, 3f
- add %o0, 2, %o0
-
-__copy_to_user: /* %o0=dst %o1=src %o2=len */
- wr %g0, ASI_S, %asi
- xor %o0, %o1, %o4
-1:
- andcc %o4, 3, %o5
-2:
- bne,pn %icc, cannot_optimize
- cmp %o2, 15
-
- bleu,pn %xcc, short_aligned_end
- andcc %o1, 3, %g0
-
- bne,pn %icc, dword_align
-3:
- andcc %o1, 4, %g0
-
- be,pt %icc, 2f
- mov %o2, %g1
-
- ld [%o1], %o4
- sub %g1, 4, %g1
- EXO2(sta %o4, [%o0] %asi,#)
- add %o1, 4, %o1
- add %o0, 4, %o0
-2:
- andcc %g1, 0xffffffffffffff80, %g7
- be,pn %xcc, 3f
- andcc %o0, 4, %g0
-
- be,pn %icc, ldd_std + 4
-5:
- MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
-80:
- EXT(5b, 80b, 50f,#)
- subcc %g7, 128, %g7
- add %o1, 128, %o1
- bne,pt %xcc, 5b
- add %o0, 128, %o0
-3:
- andcc %g1, 0x70, %g7
- be,pn %icc, copy_user_table_end
- andcc %g1, 8, %g0
-100:
- rd %pc, %o5
- srl %g7, 1, %o4
- add %g7, %o4, %o4
- add %o1, %g7, %o1
- sub %o5, %o4, %o5
- jmpl %o5 + (copy_user_table_end - 100b), %g0
- add %o0, %g7, %o0
-
-copy_user_table:
- MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
-copy_user_table_end:
- EXT(copy_user_table, copy_user_table_end, 51f,#)
- be,pt %icc, copy_user_last7
- andcc %g1, 4, %g0
-
- ldd [%o1], %g2
- add %o0, 8, %o0
- add %o1, 8, %o1
- EX(sta %g2, [%o0 - 0x08] %asi, and %g1, 0xf,#)
- EX2(sta %g3, [%o0 - 0x04] %asi, and %g1, 0xf, %g1, sub %g1, 4,#)
-copy_user_last7:
- be,pn %icc, 1f
- andcc %g1, 2, %g0
-
- ld [%o1], %g2
- add %o1, 4, %o1
- EX(sta %g2, [%o0] %asi, and %g1, 7,#)
- add %o0, 4, %o0
-1:
- be,pn %icc, 1f
- andcc %g1, 1, %g0
-
- lduh [%o1], %g2
- add %o1, 2, %o1
- EX(stha %g2, [%o0] %asi, and %g1, 3,#)
- add %o0, 2, %o0
-1:
- be,pn %icc, 1f
- nop
-
- ldub [%o1], %g2
- EX(stba %g2, [%o0] %asi, add %g0, 1,#)
-1:
- PRE_RETL
- retl
- clr %o0
-
-ldd_std:
- MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
-81:
- EXT(ldd_std, 81b, 52f,#)
- subcc %g7, 128, %g7
- add %o1, 128, %o1
- bne,pt %xcc, ldd_std
- add %o0, 128, %o0
-
- andcc %g1, 0x70, %g7
- be,pn %icc, copy_user_table_end
- andcc %g1, 8, %g0
-101:
- rd %pc, %o5
- srl %g7, 1, %o4
- add %g7, %o4, %o4
- add %o1, %g7, %o1
- sub %o5, %o4, %o5
- jmpl %o5 + (copy_user_table_end - 101b), %g0
- add %o0, %g7, %o0
-
-cannot_optimize:
- bleu short_end
- cmp %o5, 2
-
- bne byte_chunk
- and %o2, 0xfffffffffffffff0, %o3
-
- andcc %o1, 1, %g0
- be 10f
- nop
-
- ldub [%o1], %g2
- add %o1, 1, %o1
- EXO2(stba %g2, [%o0] %asi,#)
- sub %o2, 1, %o2
- andcc %o2, 0xfffffffffffffff0, %o3
- be short_end
- add %o0, 1, %o0
-10:
- MOVE_HALFCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
- MOVE_HALFCHUNK(o1, o0, 0x08, g2, g3, g4, g5)
-82:
- EXT(10b, 82b, 53f,#)
- subcc %o3, 0x10, %o3
- add %o1, 0x10, %o1
- bne 10b
- add %o0, 0x10, %o0
- ba,pt %xcc, 2f
- and %o2, 0xe, %o3
-
-byte_chunk:
- MOVE_SHORTCHUNK(o1, o0, -0x02, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x04, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x06, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x08, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x0a, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x0c, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x0e, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x10, g2, g3)
-83:
- EXT(byte_chunk, 83b, 54f,#)
- subcc %o3, 0x10, %o3
- add %o1, 0x10, %o1
- bne,pt %xcc, byte_chunk
- add %o0, 0x10, %o0
-
-short_end:
- and %o2, 0xe, %o3
-2:
- rd %pc, %o5
- sll %o3, 3, %o4
- add %o0, %o3, %o0
- sub %o5, %o4, %o5
- add %o1, %o3, %o1
- jmpl %o5 + (short_table_end - 2b), %g0
- andcc %o2, 1, %g0
-84:
- MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
-short_table_end:
- EXT(84b, short_table_end, 55f,#)
- be 1f
- nop
- ldub [%o1], %g2
- EX(stba %g2, [%o0] %asi, add %g0, 1,#)
-1:
- PRE_RETL
- retl
- clr %o0
-
-short_aligned_end:
- bne short_end
- andcc %o2, 8, %g0
-
- be 1f
- andcc %o2, 4, %g0
-
- ld [%o1 + 0x00], %g2
- ld [%o1 + 0x04], %g3
- add %o1, 8, %o1
- EXO2(sta %g2, [%o0 + 0x00] %asi,#)
- EX(sta %g3, [%o0 + 0x04] %asi, sub %o2, 4,#)
- add %o0, 8, %o0
-1:
- ba,pt %xcc, copy_user_last7
- mov %o2, %g1
-
- .section .fixup,#alloc,#execinstr
- .align 4
-97:
- PRE_RETL
- retl
- mov %o2, %o0
-/* exception routine sets %g2 to (broken_insn - first_insn)>>2 */
-50:
-/* This magic counts how many bytes are left when crash in MOVE_BIGCHUNK
- * happens. This is derived from the amount ldd reads, st stores, etc.
- * x = g2 % 12;
- * o0 = g1 + g7 - ((g2 / 12) * 32 + (x < 4) ? x * 8 : (x - 4) * 4)
- */
- cmp %g2, 12
- bcs 1f
- cmp %g2, 24
- bcs 2f
- cmp %g2, 36
- bcs 3f
- nop
- sub %g2, 12, %g2
- sub %g7, 32, %g7
-3:
- sub %g2, 12, %g2
- sub %g7, 32, %g7
-2:
- sub %g2, 12, %g2
- sub %g7, 32, %g7
-1:
- cmp %g2, 4
- bcs,a 1f
- sll %g2, 3, %g2
- sub %g2, 4, %g2
- sll %g2, 2, %g2
-1:
- and %g1, 0x7f, %o0
- add %o0, %g7, %o0
- PRE_RETL
- retl
- sub %o0, %g2, %o0
-51:
-/* i = 41 - g2; j = i % 6;
- * o0 = (g1 & 15) + (i / 6) * 16 + (j < 4) ? (j + 1) * 4 : (j - 3) * 8;
- */
- neg %g2
- and %g1, 0xf, %g1
- add %g2, 41, %g2
-1:
- cmp %g2, 6
- bcs,a 2f
- cmp %g2, 4
- add %g1, 16, %g1
- b 1b
- sub %g2, 6, %g2
-2:
- bcs,a 3f
- inc %g2
- sub %g2, 3, %g2
- b 2f
- sll %g2, 3, %g2
-3:
- sll %g2, 2, %g2
-2:
- PRE_RETL
- retl
- add %g1, %g2, %o0
-52:
-/* o0 = g1 + g7 - (g2 / 8) * 32 + (x & 3) * 8 */
- and %g2, 0xfffffffffffffff8, %g4
- and %g2, 3, %g2
- sll %g4, 2, %g4
- sll %g2, 3, %g2
- add %g2, %g4, %g2
- b,a 1b
-53:
-/* o0 = o3 + (o2 & 15) - (g2 & 8) - (g2 & 3) * 2 */
- and %g2, 3, %g4
- and %g2, 0xfffffffffffffff8, %g2
- sll %g4, 1, %g4
- add %g2, %g4, %g2
- and %o2, 0xf, %o0
- add %o0, %o3, %o0
- PRE_RETL
- retl
- sub %o0, %g2, %o0
-54:
-/* o0 = o3 + (o2 & 15) - (g2 / 4) * 2 - (g2 & 1) */
- srl %g2, 2, %o4
- and %g2, 1, %o1
- sll %o4, 1, %o4
- and %o2, 0xf, %o2
- sub %o3, %o1, %o3
- sub %o2, %o4, %o2
- PRE_RETL
- retl
- add %o2, %o3, %o0
-55:
-/* o0 = (o2 & 1) + (27 - g2)/4 * 2 + ((27 - g2) & 1) */
- neg %g2
- and %o2, 1, %o2
- add %g2, 27, %g2
- srl %g2, 2, %o1
- and %g2, 1, %g2
- sll %o1, 1, %o1
- add %o2, %g2, %o0
- PRE_RETL
- retl
- add %o0, %o1, %o0
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/lib/memcpy.S linux/arch/sparc64/lib/memcpy.S
--- v2.1.43/linux/arch/sparc64/lib/memcpy.S Mon Apr 14 16:28:10 1997
+++ linux/arch/sparc64/lib/memcpy.S Wed Dec 31 16:00:00 1969
@@ -1,526 +0,0 @@
-/* memcpy.S: Sparc optimized memcpy, bcopy and memmove code
- * Hand optimized from GNU libc's memcpy, bcopy and memmove
- * for UltraSparc
- * Copyright (C) 1991,1996 Free Software Foundation
- * Copyright (C) 1995 Linus Torvalds (Linus.T...@helsinki.fi)
- * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
- * Copyright (C) 1996 Eddie C. Dost (e...@skynet.be)
- * Copyright (C) 1996,1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
- */
-
-#include <asm/asi.h>
-#include <asm/head.h>
-
-#ifdef __KERNEL__
-
-#define FUNC(x) \
- .globl x; \
- .type x,@function; \
- .align 4; \
-x:
-
-#define FASTER_ALIGNED
-
-/* In kernel these functions don't return a value.
- * One should use macros in asm/string.h for that purpose.
- * We return 0, so that bugs are more apparent.
- */
-#define SETUP_RETL
-#define PRE_RETL sethi %uhi(KERNBASE), %g4; clr %o0
-#define RETL_INSN sllx %g4, 32, %g4
-
-#else
-
-/* libc */
-
-#define FASTER_ALIGNED
-
-#ifdef DEBUG
-#define FUNC(x) \
- .globl jj##x##1; \
- .type jj##x##1,@function; \
- .align 4; \
-jj##x##1:
-#else
-#include "DEFS.h"
-#endif
-
-#define SETUP_RETL mov %o0, %g6
-#define PRE_RETL
-#define RETL_INSN mov %g6, %o0
-
-#endif
-
-#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
- ldd [%src + offset + 0x00], %t0; \
- ldd [%src + offset + 0x08], %t2; \
- ldd [%src + offset + 0x10], %t4; \
- ldd [%src + offset + 0x18], %t6; \
- stw %t0, [%dst + offset + 0x00]; \
- stw %t1, [%dst + offset + 0x04]; \
- stw %t2, [%dst + offset + 0x08]; \
- stw %t3, [%dst + offset + 0x0c]; \
- stw %t4, [%dst + offset + 0x10]; \
- stw %t5, [%dst + offset + 0x14]; \
- stw %t6, [%dst + offset + 0x18]; \
- stw %t7, [%dst + offset + 0x1c];
-
-#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
- ldx [%src + offset + 0x00], %t0; \
- ldx [%src + offset + 0x08], %t1; \
- ldx [%src + offset + 0x10], %t2; \
- ldx [%src + offset + 0x18], %t3; \
- ldx [%src + offset + 0x20], %t4; \
- ldx [%src + offset + 0x28], %t5; \
- ldx [%src + offset + 0x30], %t6; \
- ldx [%src + offset + 0x38], %t7; \
- stx %t0, [%dst + offset + 0x00]; \
- stx %t1, [%dst + offset + 0x08]; \
- stx %t2, [%dst + offset + 0x10]; \
- stx %t3, [%dst + offset + 0x18]; \
- stx %t4, [%dst + offset + 0x20]; \
- stx %t5, [%dst + offset + 0x28]; \
- stx %t6, [%dst + offset + 0x30]; \
- stx %t7, [%dst + offset + 0x38];
-
-#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
- ldd [%src - offset - 0x10], %t0; \
- ldd [%src - offset - 0x08], %t2; \
- stw %t0, [%dst - offset - 0x10]; \
- stw %t1, [%dst - offset - 0x0c]; \
- stw %t2, [%dst - offset - 0x08]; \
- stw %t3, [%dst - offset - 0x04];
-
-#define MOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1) \
- ldx [%src - offset - 0x10], %t0; \
- ldx [%src - offset - 0x08], %t1; \
- stx %t0, [%dst - offset - 0x10]; \
- stx %t1, [%dst - offset - 0x08];
-
-#define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
- ldub [%src - offset - 0x02], %t0; \
- ldub [%src - offset - 0x01], %t1; \
- stb %t0, [%dst - offset - 0x02]; \
- stb %t1, [%dst - offset - 0x01];
-
- .text
- .align 4
-
-FUNC(bcopy)
-
- mov %o0, %o3
- mov %o1, %o0
- mov %o3, %o1
- brgez,a,pt %o2, 1f
- cmp %o0, %o1
-
- retl
- nop ! Only bcopy returns here and it retuns void...
-
-#ifdef __KERNEL__
-FUNC(amemmove)
-FUNC(__memmove)
-#endif
-FUNC(memmove)
-
- cmp %o0, %o1
-1:
- SETUP_RETL
- bleu,pt %xcc, 9f
- sub %o0, %o1, %o4
-
- add %o1, %o2, %o3
- cmp %o3, %o0
- bleu,pt %xcc, 0f
- andcc %o4, 3, %o5
-
- add %o1, %o2, %o1
- add %o0, %o2, %o0
- sub %o1, 1, %o1
- sub %o0, 1, %o0
-
-1:
- ldub [%o1], %o4
- subcc %o2, 1, %o2
- sub %o1, 1, %o1
- stb %o4, [%o0]
- bne,pt %icc, 1b
- sub %o0, 1, %o0
-
- PRE_RETL
- retl
- RETL_INSN
-
-#ifdef __KERNEL__
-FUNC(__memcpy)
-#endif
-FUNC(memcpy) /* %o0=dst %o1=src %o2=len */
-
- sub %o0, %o1, %o4
- SETUP_RETL
-9:
- andcc %o4, 3, %o5
-0:
- bne,pn %icc, 86f
- cmp %o2, 15
-
- bleu,pn %xcc, 90f
- andcc %o1, 3, %g0
-
- be,a,pt %icc, 3f ! check if we need to align
- andcc %o1, 4, %g0
-
- andcc %o1, 1, %g0
- be,pn %icc, 4f
- andcc %o1, 2, %g0
-
- ldub [%o1], %g2
- add %o1, 1, %o1
- sub %o2, 1, %o2
- stb %g2, [%o0]
- bne,pn %icc, 5f
- add %o0, 1, %o0
-4:
- lduh [%o1], %g2
- add %o1, 2, %o1
- sub %o2, 2, %o2
- sth %g2, [%o0]
- add %o0, 2, %o0
-5:
- andcc %o1, 4, %g0
-3:
- be,pn %icc, 2f
- mov %o2, %g1
-
- lduw [%o1], %o4
- sub %g1, 4, %g1
- stw %o4, [%o0]
- add %o1, 4, %o1
- add %o0, 4, %o0
-2:
- andcc %g1, -128, %g7
- be,pn %xcc, 3f
- andcc %o0, 4, %g0
-
- be,a,pn %icc, 82f + 4
- ldx [%o1], %o2
-5:
- MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
- subcc %g7, 128, %g7
- add %o1, 128, %o1
- bne,pt %xcc, 5b
- add %o0, 128, %o0
-3:
- andcc %g1, 0x70, %g7
- be,pn %icc, 80f
- andcc %g1, 8, %g0
-79:
- rd %pc, %o5
- srl %g7, 1, %o4
- add %g7, %o4, %o4
- add %o1, %g7, %o1
- sub %o5, %o4, %o5
- jmpl %o5 + %lo(80f-79b), %g0
- add %o0, %g7, %o0
-
- MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
- MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
-
-80: /* memcpy_table_end */
- be,pt %icc, 81f
- andcc %g1, 4, %g0
-
- ldd [%o1], %g2
- add %o0, 8, %o0
- stw %g2, [%o0 - 0x08]
- add %o1, 8, %o1
- stw %g3, [%o0 - 0x04]
-
-81: /* memcpy_last7 */
-
- be,pt %icc, 1f
- andcc %g1, 2, %g0
-
- lduw [%o1], %g2
- add %o1, 4, %o1
- stw %g2, [%o0]
- add %o0, 4, %o0
-1:
- be,pt %icc, 1f
- andcc %g1, 1, %g0
-
- lduh [%o1], %g2
- add %o1, 2, %o1
- sth %g2, [%o0]
- add %o0, 2, %o0
-1:
- be,pt %icc, 1f
- nop
-
- ldub [%o1], %g2
- stb %g2, [%o0]
-1:
- PRE_RETL
- retl
- RETL_INSN
-
-82: /* ldx_stx */
- MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
- MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
- subcc %g7, 128, %g7
- add %o1, 128, %o1
- bne,pt %xcc, 82b
- add %o0, 128, %o0
-
-#ifndef FASTER_ALIGNED
-
- andcc %g1, 0x70, %g7
- be,pn %icc, 80b
- andcc %g1, 8, %g0
-83:
- rd %pc, %o5
- srl %g7, 1, %o4
- add %g7, %o4, %o4
- add %o1, %g7, %o1
- sub %o5, %o4, %o5
- jmpl %o5 + %lo(80b - 83b), %g0
- add %o0, %g7, %o0
-
-#else /* FASTER_ALIGNED */
-
- andcc %g1, 0x70, %g7
- be,pn %icc, 84f
- andcc %g1, 8, %g0
-83:
- rd %pc, %o5
- add %o1, %g7, %o1
- sub %o5, %g7, %o5
- jmpl %o5 + %lo(84f - 83b), %g0
- add %o0, %g7, %o0
-
- MOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3)
- MOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3)
- MOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3)
- MOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3)
- MOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3)
- MOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3)
- MOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3)
-
-84: /* amemcpy_table_end */
- be,pt %icc, 85f
- andcc %g1, 4, %g0
-
- ldx [%o1], %g2
- add %o1, 8, %o1
- stx %g2, [%o0]
- add %o0, 8, %o0
-85: /* amemcpy_last7 */
- be,pt %icc, 1f
- andcc %g1, 2, %g0
-
- lduw [%o1], %g2
- add %o1, 4, %o1
- stw %g2, [%o0]
- add %o0, 4, %o0
-1:
- be,pt %icc, 1f
- andcc %g1, 1, %g0
-
- lduh [%o1], %g2
- add %o1, 2, %o1
- sth %g2, [%o0]
- add %o0, 2, %o0
-1:
- be,pt %icc, 1f
- nop
-
- ldub [%o1], %g2
- stb %g2, [%o0]
-1:
- PRE_RETL
- retl
- RETL_INSN
-
-#endif /* FASTER_ALIGNED */
-
-86: /* non_aligned */
- cmp %o2, 15
- bleu,pn %xcc, 88f
-
- andcc %o0, 3, %g0
- be,pn %icc, 61f
- andcc %o0, 1, %g0
- be,pn %icc, 60f
- andcc %o0, 2, %g0
-
- ldub [%o1], %g5
- add %o1, 1, %o1
- stb %g5, [%o0]
- sub %o2, 1, %o2
- bne,pn %icc, 61f
- add %o0, 1, %o0
-60:
- ldub [%o1], %g3
- add %o1, 2, %o1
- stb %g3, [%o0]
- sub %o2, 2, %o2
- ldub [%o1 - 1], %g3
- add %o0, 2, %o0
- stb %g3, [%o0 - 1]
-61:
- and %o1, 3, %g2
- and %o2, 0xc, %g3
- and %o1, -4, %o1
- cmp %g3, 4
- sll %g2, 3, %g4
- mov 32, %g2
- be,pn %icc, 4f
- sub %g2, %g4, %g7
-
- blu,pn %icc, 3f
- cmp %g3, 0x8
-
- be,pn %icc, 2f
- srl %o2, 2, %g3
-
- lduw [%o1], %o3
- add %o0, -8, %o0
- lduw [%o1 + 4], %o4
- ba,pt %xcc, 8f
- add %g3, 1, %g3
-2:
- lduw [%o1], %o4
- add %o0, -12, %o0
- lduw [%o1 + 4], %o5
- add %g3, 2, %g3
- ba,pt %xcc, 9f
- add %o1, -4, %o1
-3:
- lduw [%o1], %g1
- add %o0, -4, %o0
- lduw [%o1 + 4], %o3
- srl %o2, 2, %g3
- ba,pt %xcc, 7f
- add %o1, 4, %o1
-4:
- lduw [%o1], %o5
- cmp %o2, 7
- lduw [%o1 + 4], %g1
- srl %o2, 2, %g3
- bleu,pn %xcc, 10f
- add %o1, 8, %o1
-
- lduw [%o1], %o3
- add %g3, -1, %g3
-5:
- sll %o5, %g4, %g2
- srl %g1, %g7, %g5
- or %g2, %g5, %g2
- stw %g2, [%o0]
-7:
- lduw [%o1 + 4], %o4
- sll %g1, %g4, %g2
- srl %o3, %g7, %g5
- or %g2, %g5, %g2
- stw %g2, [%o0 + 4]
-8:
- lduw [%o1 + 8], %o5
- sll %o3, %g4, %g2
- srl %o4, %g7, %g5
- or %g2, %g5, %g2
- stw %g2, [%o0 + 8]
-9:
- lduw [%o1 + 12], %g1
- sll %o4, %g4, %g2
- srl %o5, %g7, %g5
- addcc %g3, -4, %g3
- or %g2, %g5, %g2
- add %o1, 16, %o1
- stw %g2, [%o0 + 12]
- add %o0, 16, %o0
- bne,a,pt %xcc, 5b
- lduw [%o1], %o3
-10:
- sll %o5, %g4, %g2
- srl %g1, %g7, %g5
- srl %g7, 3, %g3
- or %g2, %g5, %g2
- sub %o1, %g3, %o1
- andcc %o2, 2, %g0
- stw %g2, [%o0]
- be,pt %icc, 1f
- andcc %o2, 1, %g0
-
- ldub [%o1], %g2
- add %o1, 2, %o1
- stb %g2, [%o0 + 4]
- add %o0, 2, %o0
- ldub [%o1 - 1], %g2
- stb %g2, [%o0 + 3]
-1:
- be,pt %icc, 1f
- nop
-
- ldub [%o1], %g2
- stb %g2, [%o0 + 4]
-1:
- PRE_RETL
- retl
- RETL_INSN
-
-88: /* short_end */
-
- and %o2, 0xe, %o3
-20:
- rd %pc, %o5
- sll %o3, 3, %o4
- add %o0, %o3, %o0
- sub %o5, %o4, %o5
- add %o1, %o3, %o1
- jmpl %o5 + %lo(89f - 20b), %g0
- andcc %o2, 1, %g0
-
- MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
-
-89: /* short_table_end */
-
- be,pt %icc, 1f
- nop
-
- ldub [%o1], %g2
- stb %g2, [%o0]
-1:
- PRE_RETL
- retl
- RETL_INSN
-
-90: /* short_aligned_end */
- bne,pn %xcc, 88b
- andcc %o2, 8, %g0
-
- be,pt %icc, 1f
- andcc %o2, 4, %g0
-
- lduw [%o1 + 0x00], %g2
- lduw [%o1 + 0x04], %g3
- add %o1, 8, %o1
- stw %g2, [%o0 + 0x00]
- stw %g3, [%o0 + 0x04]
- add %o0, 8, %o0
-1:
- ba,pt %xcc, 81b
- mov %o2, %g1
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/lib/memset.S linux/arch/sparc64/lib/memset.S
--- v2.1.43/linux/arch/sparc64/lib/memset.S Mon Jun 16 16:35:54 1997
+++ linux/arch/sparc64/lib/memset.S Wed Dec 31 16:00:00 1969
@@ -1,196 +0,0 @@
-/* linux/arch/sparc64/lib/memset.S: Sparc optimized memset, bzero and clear_user code
- * Copyright (C) 1991,1996 Free Software Foundation
- * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
- * Copyright (C) 1996,1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
- *
- * Returns 0, if ok, and number of bytes not yet set if exception
- * occurs and we were called as clear_user.
- */
-
-#include <asm/asi.h>
-#include <asm/ptrace.h>
-
-#define EX(x,y,a,b,z) \
-98: x,y; \
- .section .fixup,z##alloc,z##execinstr; \
- .align 4; \
-99: ba,pt %xcc, 30f; \
- a, b, %o0; \
- .section __ex_table,z##alloc; \
- .align 8; \
- .xword 98b, 99b; \
- .text; \
- .align 4
-
-#define EXT(start,end,handler,z) \
- .section __ex_table,z##alloc; \
- .align 8; \
- .xword start, 0, end, handler; \
- .text; \
- .align 4
-
-/* Please don't change these macros, unless you change the logic
- * in the .fixup section below as well.
- * Store 64 bytes at (BASE + OFFSET) using value SOURCE. */
-#define ZERO_BIG_BLOCK(base, offset, source) \
- stxa source, [base + offset + 0x00] %asi; \
- stxa source, [base + offset + 0x08] %asi; \
- stxa source, [base + offset + 0x10] %asi; \
- stxa source, [base + offset + 0x18] %asi; \
- stxa source, [base + offset + 0x20] %asi; \
- stxa source, [base + offset + 0x28] %asi; \
- stxa source, [base + offset + 0x30] %asi; \
- stxa source, [base + offset + 0x38] %asi;
-
-#define ZERO_LAST_BLOCKS(base, offset, source) \
- stxa source, [base - offset - 0x38] %asi; \
- stxa source, [base - offset - 0x30] %asi; \
- stxa source, [base - offset - 0x28] %asi; \
- stxa source, [base - offset - 0x20] %asi; \
- stxa source, [base - offset - 0x18] %asi; \
- stxa source, [base - offset - 0x10] %asi; \
- stxa source, [base - offset - 0x08] %asi; \
- stxa source, [base - offset - 0x00] %asi;
-
- .text
- .align 4
-
- .globl __bzero, __memset, __bzero_noasi
- .globl memset, __memset_start, __memset_end
-__memset_start:
-__memset:
-memset:
- and %o1, 0xff, %g3
- sll %g3, 8, %g2
- or %g3, %g2, %g3
- sll %g3, 16, %g2
- or %g3, %g2, %g3
- mov %o2, %o1
- wr %g0, ASI_P, %asi
- sllx %g3, 32, %g2
- ba,pt %xcc, 1f
- or %g3, %g2, %g3
-__bzero:
- wr %g0, ASI_P, %asi
-__bzero_noasi:
- mov %g0, %g3
-1:
- cmp %o1, 7
- bleu,pn %xcc, 7f
- andcc %o0, 3, %o2
-
- be,a,pt %icc, 4f
- andcc %o0, 4, %g0
-
- cmp %o2, 3
- be,pn %icc, 2f
- EX(stba %g3, [%o0] %asi, sub %o1, 0,#)
-
- cmp %o2, 2
- be,pt %icc, 2f
- EX(stba %g3, [%o0 + 0x01] %asi, sub %o1, 1,#)
-
- EX(stba %g3, [%o0 + 0x02] %asi, sub %o1, 2,#)
-2:
- sub %o2, 4, %o2
- sub %o0, %o2, %o0
- add %o1, %o2, %o1
- andcc %o0, 4, %g0
-4:
- be,a,pt %icc, 2f
- andncc %o1, 0x7f, %o3
-
- EX(sta %g3, [%o0] %asi, sub %o1, 0,#)
- sub %o1, 4, %o1
- add %o0, 4, %o0
- andncc %o1, 0x7f, %o3 ! Now everything is 8 aligned and o1 is len to run
-2:
- be,pn %xcc, 9f
- andcc %o1, 0x78, %o2
-10:
- ZERO_BIG_BLOCK(%o0, 0x00, %g3)
- subcc %o3, 128, %o3
- ZERO_BIG_BLOCK(%o0, 0x40, %g3)
-11:
- EXT(10b, 11b, 20f,#)
- bne,pt %xcc, 10b
- add %o0, 128, %o0
-
- tst %o2
-9:
- be,pn %xcc, 13f
- andcc %o1, 7, %o1
-14:
- rd %pc, %o4
- srl %o2, 1, %o3
- sub %o4, %o3, %o4
- jmpl %o4 + (13f - 14b), %g0
- add %o0, %o2, %o0
-12:
- ZERO_LAST_BLOCKS(%o0, 0x48, %g3)
- ZERO_LAST_BLOCKS(%o0, 0x08, %g3)
-13:
- be,pn %icc, 8f
- andcc %o1, 4, %g0
-
- be,pn %icc, 1f
- andcc %o1, 2, %g0
-
- EX(sta %g3, [%o0] %asi, and %o1, 7,#)
- add %o0, 4, %o0
-1:
- be,pn %icc, 1f
- andcc %o1, 1, %g0
-
- EX(stha %g3, [%o0] %asi, and %o1, 3,#)
- add %o0, 2, %o0
-1:
- bne,a,pn %icc, 8f
- EX(stba %g3, [%o0] %asi, and %o1, 1,#)
-8:
- retl
- clr %o0
-7:
- be,pn %icc, 13b
- orcc %o1, 0, %g0
-
- be,pn %icc, 0f
-8:
- add %o0, 1, %o0
- subcc %o1, 1, %o1
- bne,a,pt %icc, 8b
- EX(stba %g3, [%o0 - 1] %asi, add %o1, 1,#)
-0:
- retl
- clr %o0
-__memset_end:
-
- .section .fixup,#alloc,#execinstr
- .align 4
-20:
- cmp %g2, 8
- bleu,pn %xcc, 1f
- and %o1, 0x7f, %o1


- sub %g2, 9, %g2

- add %o3, 64, %o3
-1:
- sll %g2, 3, %g2
- add %o3, %o1, %o0
- ba,pt %xcc, 30f
- sub %o0, %g2, %o0
-21:
- mov 8, %o0
- and %o1, 7, %o1
- sub %o0, %g2, %o0
- sll %o0, 3, %o0
- ba,pt %xcc, 30f
- add %o0, %o1, %o0
-30:
-/* %o4 is faulting address, %o5 is %pc where fault occured */
- save %sp, -160, %sp
- mov %i5, %o0
- mov %i7, %o1
- call lookup_fault
- mov %i4, %o2
- ret
- restore
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/mm/Makefile linux/arch/sparc64/mm/Makefile
--- v2.1.43/linux/arch/sparc64/mm/Makefile Mon Dec 30 01:59:59 1996
+++ linux/arch/sparc64/mm/Makefile Mon Jul 7 08:18:55 1997
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.1 1996/12/26 10:24:22 davem Exp $
+# $Id: Makefile,v 1.3 1997/06/27 14:53:38 jj Exp $
X # Makefile for the linux Sparc64-specific parts of the memory manager.
X #
X # Note! Dependencies are done automagically by 'make dep', which also
@@ -7,7 +7,13 @@
X #
X # Note 2! The CFLAGS definition is now in the main makefile...
X

+.S.s:
+ $(CPP) -D__ASSEMBLY__ -ansi $< -o $*.s

+
+.S.o:
+ $(CC) -D__ASSEMBLY__ -ansi -c $< -o $*.o
+
X O_TARGET := mm.o
-O_OBJS := fault.o init.o generic.o asyncd.o extable.o
+O_OBJS := ultra.o fault.o init.o generic.o asyncd.o extable.o modutil.o
X
X include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/mm/fault.c linux/arch/sparc64/mm/fault.c
--- v2.1.43/linux/arch/sparc64/mm/fault.c Mon Jun 16 16:35:54 1997
+++ linux/arch/sparc64/mm/fault.c Mon Jul 7 08:18:55 1997
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.11 1997/06/01 05:46:15 davem Exp $
+/* $Id: fault.c,v 1.17 1997/07/04 01:41:10 davem Exp $
X * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
X *
X * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
@@ -134,44 +134,14 @@
X return 0;
X }
X
-/* #define FAULT_TRACER */
-/* #define FAULT_TRACER_VERBOSE */
+/* #define DEBUG_EXCEPTIONS */
X
-asmlinkage void do_sparc64_fault(struct pt_regs *regs, int text_fault, int write,
- unsigned long address, unsigned long tag,
- unsigned long sfsr)
+asmlinkage void do_sparc64_fault(struct pt_regs *regs, unsigned long address, int write)
X {
+ struct mm_struct *mm = current->mm;
X struct vm_area_struct *vma;
- struct task_struct *tsk = current;
- struct mm_struct *mm = tsk->mm;
- unsigned long fixup;
- unsigned long g2;
- int from_user = !(regs->tstate & TSTATE_PRIV);
-#ifdef FAULT_TRACER
- static unsigned long last_addr = 0;
- static int rcnt = 0;
-
-#ifdef FAULT_TRACER_VERBOSE
- printk("FAULT(PC[%016lx],t[%d],w[%d],addr[%016lx])...",
- regs->tpc, text_fault, write, address);
-#else
- printk("F[%016lx:%016lx:w(%d)", regs->tpc, address, write);
-#endif
- if(address == last_addr) {
- if(rcnt++ > 15) {
- printk("Wheee lotsa bogus faults, something wrong, spinning\n");
- __asm__ __volatile__("flushw");
- printk("o7[%016lx] i7[%016lx]\n",
- regs->u_regs[UREG_I7],
- ((struct reg_window *)(regs->u_regs[UREG_FP]+STACK_BIAS))->ins[7]);
- sti();
- while(1)
- barrier();
- }
- } else rcnt = 0;
- last_addr = address;
-#endif
- lock_kernel ();
+
+ lock_kernel();
X down(&mm->mmap_sem);
X vma = find_vma(mm, address);
X if(!vma)
@@ -204,40 +174,99 @@
X */
X bad_area:
X up(&mm->mmap_sem);
- /* Is this in ex_table? */
+


+ {
+ unsigned long g2 = regs->u_regs[UREG_G2];

+
+ /* Is this in ex_table? */
+ if (regs->tstate & TSTATE_PRIV) {
+ unsigned char asi = ASI_P;
+ unsigned int insn;
+ unsigned long fixup;
+
+ insn = *(unsigned int *)regs->tpc;
+ if ((insn & 0xc0800000) == 0xc0800000) {
+ if (insn & 0x2000)
+ asi = (regs->tstate >> 24);
+ else
+ asi = (insn >> 5);
+ }
X
- g2 = regs->u_regs[UREG_G2];
- if (!from_user && (fixup = search_exception_table (regs->tpc, &g2))) {
- printk("Exception: PC<%016lx> faddr<%016lx>\n", regs->tpc, address);
- printk("EX_TABLE: insn<%016lx> fixup<%016lx> g2<%016lx>\n",
- regs->tpc, fixup, g2);
- regs->tpc = fixup;
- regs->tnpc = regs->tpc + 4;
- regs->u_regs[UREG_G2] = g2;
- goto out;
- }
- if(from_user) {
-#if 1
- unsigned long cpc;
- __asm__ __volatile__("mov %%i7, %0" : "=r" (cpc));
- printk("[%s:%d] SIGSEGV pc[%016lx] addr[%016lx] w[%d] sfsr[%016lx] "
- "caller[%016lx]\n", current->comm, current->pid, regs->tpc,
- address, write, sfsr, cpc);
+ /* Look in asi.h: All _S asis have LS bit set */
+ if ((asi & 0x1) &&
+ (fixup = search_exception_table (regs->tpc, &g2))) {
+#ifdef DEBUG_EXCEPTIONS
+ printk("Exception: PC<%016lx> faddr<%016lx>\n",
+ regs->tpc, address);
+ printk("EX_TABLE: insn<%016lx> fixup<%016lx> "
+ "g2<%016lx>\n", regs->tpc, fixup, g2);
X #endif
- tsk->tss.sig_address = address;
- tsk->tss.sig_desc = SUBSIG_NOMAPPING;
- send_sig(SIGSEGV, tsk, 1);
- goto out;


+ regs->tpc = fixup;
+ regs->tnpc = regs->tpc + 4;
+ regs->u_regs[UREG_G2] = g2;

+ goto out;
+ }
+ } else {
+ current->tss.sig_address = address;
+ current->tss.sig_desc = SUBSIG_NOMAPPING;
+ send_sig(SIGSEGV, current, 1);
+ goto out;
+ }
+ unhandled_fault (address, current, regs);
X }
- unhandled_fault (address, tsk, regs);
X out:
X unlock_kernel();
-#ifdef FAULT_TRACER
-#ifdef FAULT_TRACER_VERBOSE
- printk(" done\n");
-#else
- printk("]");
-#endif
-#endif
X }
X
+void fixup_dcache_alias(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+ struct vm_area_struct *vmaring;
+ struct inode *inode;
+ unsigned long vaddr, offset, start;


+ pgd_t *pgdp;
+ pmd_t *pmdp;
+ pte_t *ptep;

+ int alias_found = 0;
+
+ inode = vma->vm_inode;
+ if(!inode)
+ return;
+
+ offset = (address & PAGE_MASK) - vma->vm_start;
+ vmaring = inode->i_mmap;
+ do {
+ vaddr = vmaring->vm_start + offset;
+
+ /* This conditional is misleading... */
+ if((vaddr ^ address) & PAGE_SIZE) {
+ alias_found++;
+ start = vmaring->vm_start;
+ while(start < vmaring->vm_end) {
+ pgdp = pgd_offset(vmaring->vm_mm, start);
+ if(!pgdp) goto next;
+ pmdp = pmd_offset(pgdp, start);
+ if(!pmdp) goto next;
+ ptep = pte_offset(pmdp, start);
+ if(!ptep) goto next;
+
+ if(pte_val(*ptep) & _PAGE_PRESENT) {
+ flush_cache_page(vmaring, start);
+ *ptep = __pte(pte_val(*ptep) &
+ ~(_PAGE_CV));
+ flush_tlb_page(vmaring, start);
+ }
+ next:


+ start += PAGE_SIZE;
+ }
+ }

+ } while((vmaring = vmaring->vm_next_share) != NULL);
+
+ if(alias_found && (pte_val(pte) & _PAGE_CV)) {


+ pgdp = pgd_offset(vma->vm_mm, address);

+ pmdp = pmd_offset(pgdp, address);

+ ptep = pte_offset(pmdp, address);

+ flush_cache_page(vma, address);
+ *ptep = __pte(pte_val(*ptep) & ~(_PAGE_CV));
+ flush_tlb_page(vma, address);
+ }
+}
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/mm/generic.c linux/arch/sparc64/mm/generic.c
--- v2.1.43/linux/arch/sparc64/mm/generic.c Mon Dec 30 01:59:59 1996
+++ linux/arch/sparc64/mm/generic.c Mon Jul 7 08:18:55 1997
@@ -1,4 +1,4 @@
-/* $Id: generic.c,v 1.1 1996/12/26 10:24:23 davem Exp $
+/* $Id: generic.c,v 1.2 1997/07/01 09:11:42 jj Exp $
X * generic.c: Generic Sparc mm routines that are not dependent upon
X * MMU type but are Sparc specific.
X *
@@ -66,13 +66,35 @@
X if (end > PMD_SIZE)
X end = PMD_SIZE;
X do {
- pte_t oldpage = *pte;
- pte_clear(pte);
- set_pte(pte, mk_pte_io(offset, prot, space));
- forget_pte(oldpage);
- address += PAGE_SIZE;
+ pte_t oldpage;
+ pte_t entry;
+ unsigned long curend = address + PAGE_SIZE;
+
+ entry = mk_pte_io(offset, prot, space);
X offset += PAGE_SIZE;
- pte++;
+ if (!(address & 0xffff)) {
+ if (!(address & 0x3fffff) && !(offset & 0x3fffff) && end >= address + 0x400000) {
+ entry = mk_pte_io(offset, __pgprot(pgprot_val (prot) | _PAGE_SZ4MB), space);
+ curend = address + 0x400000;
+ offset += 0x400000 - PAGE_SIZE;
+ } else if (!(address & 0x7ffff) && !(offset & 0x7ffff) && end >= address + 0x80000) {
+ entry = mk_pte_io(offset, __pgprot(pgprot_val (prot) | _PAGE_SZ512K), space);
+ curend = address + 0x80000;
+ offset += 0x80000 - PAGE_SIZE;
+ } else if (!(offset & 0xffff) && end >= address + 0x10000) {
+ entry = mk_pte_io(offset, __pgprot(pgprot_val (prot) | _PAGE_SZ64K), space);
+ curend = address + 0x10000;
+ offset += 0x10000 - PAGE_SIZE;
+ }
+ }
+ do {
+ oldpage = *pte;
+ pte_clear(pte);
+ set_pte(pte, entry);
+ forget_pte(oldpage);
+ address += PAGE_SIZE;
+ pte++;
+ } while (address < curend);
X } while (address < end);
X }
X
diff -u --recursive --new-file v2.1.43/linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- v2.1.43/linux/arch/sparc64/mm/init.c Thu May 29 21:53:04 1997
+++ linux/arch/sparc64/mm/init.c Mon Jul 7 08:18:55 1997
@@ -1,15 +1,17 @@
-/* $Id: init.c,v 1.29 1997/05/27 06:28:13 davem Exp $
+/* $Id: init.c,v 1.39 1997/07/07 02:50:57 davem Exp $
X * arch/sparc64/mm/init.c
X *
X * Copyright (C) 1996,1997 David S. Miller (da...@caip.rutgers.edu)
X * Copyright (C) 1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
X */
X
+#include <linux/config.h>
X #include <linux/string.h>
X #include <linux/init.h>
X #include <linux/blk.h>
X #include <linux/swap.h>
X
+#include <asm/head.h>
X #include <asm/system.h>
X #include <asm/page.h>
X #include <asm/pgtable.h>
@@ -33,7 +35,7 @@
X unsigned long tlb_context_cache = CTX_FIRST_VERSION;
X
X /* References to section boundaries */
-extern char __init_begin, __init_end, etext, __p1275_loc, __bss_start;
+extern char __init_begin, __init_end, etext, __bss_start;
X
X /*
X * BAD_PAGE is the page that is used for page faults when linux
@@ -59,13 +61,15 @@
X pte_t *__bad_pte(void)
X {
X memset((void *) &empty_bad_pte_table, 0, PAGE_SIZE);
- return (pte_t *) (((unsigned long)&empty_bad_pte_table) + phys_base);
+ return (pte_t *) (((unsigned long)&empty_bad_pte_table)
+ - ((unsigned long)&empty_zero_page) + phys_base + PAGE_OFFSET);
X }
X
X pte_t __bad_page(void)
X {
X memset((void *) &empty_bad_page, 0, PAGE_SIZE);
- return pte_mkdirty(mk_pte((((unsigned long) &empty_bad_page)+phys_base),
+ return pte_mkdirty(mk_pte((((unsigned long) &empty_bad_page)
+ - ((unsigned long)&empty_zero_page) + phys_base + PAGE_OFFSET),
X PAGE_SHARED));
X }
X
@@ -288,7 +292,7 @@
X };
X
X #define MAX_TRANSLATIONS 64
-static void inherit_prom_mappings(void)
+static inline void inherit_prom_mappings(void)
X {
X struct linux_prom_translation transl[MAX_TRANSLATIONS];
X pgd_t *pgdp;
@@ -332,7 +336,11 @@
X }
X }
X
-static void inherit_locked_prom_mappings(void)
+int prom_itlb_ent, prom_dtlb_ent;
+unsigned long prom_itlb_tag, prom_itlb_data;
+unsigned long prom_dtlb_tag, prom_dtlb_data;
+
+static inline void inherit_locked_prom_mappings(void)
X {
X int i;
X int dtlb_seen = 0;
@@ -359,6 +367,9 @@
X data = spitfire_get_dtlb_data(i);
X if(!dtlb_seen && (data & _PAGE_L)) {
X unsigned long tag = spitfire_get_dtlb_tag(i);
+ prom_dtlb_ent = i;
+ prom_dtlb_tag = tag;
+ prom_dtlb_data = data;
X __asm__ __volatile__("stxa %%g0, [%0] %1"
X : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
X membar("#Sync");
@@ -379,6 +390,9 @@
X data = spitfire_get_itlb_data(i);
X if(!itlb_seen && (data & _PAGE_L)) {
X unsigned long tag = spitfire_get_itlb_tag(i);
+ prom_itlb_ent = i;
+ prom_itlb_tag = tag;
+ prom_itlb_data = data;
X __asm__ __volatile__("stxa %%g0, [%0] %1"
X : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));
X membar("#Sync");
@@ -399,6 +413,64 @@
X }
X }
X
+/* Give PROM back his world, done during reboots... */
+void prom_reload_locked(void)
+{
+ __asm__ __volatile__("stxa %0, [%1] %2"
+ : : "r" (prom_dtlb_tag), "r" (TLB_TAG_ACCESS),
+ "i" (ASI_DMMU));
+ membar("#Sync");
+ spitfire_put_dtlb_data(prom_dtlb_ent, prom_dtlb_data);
+ membar("#Sync");
+
+ __asm__ __volatile__("stxa %0, [%1] %2"
+ : : "r" (prom_itlb_tag), "r" (TLB_TAG_ACCESS),
+ "i" (ASI_IMMU));
+ membar("#Sync");
+ spitfire_put_itlb_data(prom_itlb_ent, prom_itlb_data);
+ membar("#Sync");
+}
+
+/* If not locked, zap it. */
+void flush_tlb_all(void)


+{
+ unsigned long flags;

+ int i;
+
+ save_flags(flags); cli();
+ for(i = 0; i < 64; i++) {
+ if(!(spitfire_get_dtlb_data(i) & _PAGE_L)) {
+ __asm__ __volatile__("stxa %%g0, [%0] %1"


+ : /* no outputs */

+ : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
+ membar("#Sync");
+ spitfire_put_dtlb_data(i, 0x0UL);
+ membar("#Sync");
+ }
+ if(!(spitfire_get_itlb_data(i) & _PAGE_L)) {
+ __asm__ __volatile__("stxa %%g0, [%0] %1"


+ : /* no outputs */

+ : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));
+ membar("#Sync");
+ spitfire_put_itlb_data(i, 0x0UL);
+ membar("#Sync");
+ }


+ }
+ restore_flags(flags);
+}
+

+void get_new_mmu_context(struct mm_struct *mm, unsigned long ctx)
+{
+ if((ctx & ~(CTX_VERSION_MASK)) == 0) {
+ flush_tlb_all();
+ ctx = (ctx & CTX_VERSION_MASK) + CTX_FIRST_VERSION;
+ if(ctx == 1)
+ ctx = CTX_FIRST_VERSION;
+ }
+ tlb_context_cache = ctx + 1;
+ mm->context = ctx;
+}
+
X __initfunc(static void
X allocate_ptable_skeleton(unsigned long start, unsigned long end))
X {
@@ -440,9 +512,9 @@
X physaddr &= PAGE_MASK;
X
X if(rdonly)
- pte = mk_pte_phys(physaddr, __pgprot(pg_iobits));
+ pte = mk_pte_phys(physaddr, __pgprot(pg_iobits | __PRIV_BITS));
X else
- pte = mk_pte_phys(physaddr, __pgprot(pg_iobits | __DIRTY_BITS));
+ pte = mk_pte_phys(physaddr, __pgprot(pg_iobits | __DIRTY_BITS | __PRIV_BITS));
X
X set_pte(ptep, pte);
X }
@@ -500,51 +572,42 @@
X {
X extern unsigned long phys_base;
X extern void setup_tba(unsigned long kpgdir);
- extern void __bfill64(void *, unsigned long);
- pgd_t *pgdp;
+ extern void __bfill64(void *, unsigned long *);
X pmd_t *pmdp;
- pte_t *ptep, pte;
X int i;
-
- /* Must create 2nd locked DTLB entry if physical ram starts at
- * 4MB absolute or higher, kernel image has been placed in the
- * right place at PAGE_OFFSET but references to start_mem and pages
- * will be to the perfect alias mapping, so set it up now.
+ unsigned long alias_base = phys_base + PAGE_OFFSET;
+ unsigned long pt;
+ unsigned long flags;
+ unsigned long shift = alias_base - ((unsigned long)&empty_zero_page);
+
+ /* We assume physical memory starts at some 4mb multiple,
+ * if this were not true we wouldn't boot up to this point
+ * anyways.
X */
- if(phys_base >= (4 * 1024 * 1024)) {
- unsigned long alias_base = phys_base + PAGE_OFFSET;
- unsigned long pte;
- unsigned long flags;
-
- /* We assume physical memory starts at some 4mb multiple,
- * if this were not true we wouldn't boot up to this point
- * anyways.
- */
- pte = phys_base | _PAGE_VALID | _PAGE_SZ4MB;
- pte |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W;
- save_flags(flags); cli();
- __asm__ __volatile__("
- stxa %1, [%0] %3
- stxa %2, [%5] %4
- membar #Sync
- flush %%g4
- nop
- nop
- nop"
- : /* No outputs */
- : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pte),
- "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3)
- : "memory");
- restore_flags(flags);
-
- /* Now set kernel pgd to upper alias so physical page computations
- * work.
- */
- init_mm.pgd += (phys_base / (sizeof(pgd_t *)));
- }
+ pt = phys_base | _PAGE_VALID | _PAGE_SZ4MB;
+ pt |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W;
+ save_flags(flags); cli();
+ __asm__ __volatile__("
+ stxa %1, [%0] %3
+ stxa %2, [%5] %4
+ membar #Sync
+ flush %%g6


+ nop
+ nop
+ nop"

+ : /* No outputs */
+ : "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt),
+ "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3)
+ : "memory");
+ restore_flags(flags);
+
+ /* Now set kernel pgd to upper alias so physical page computations
+ * work.
+ */
+ init_mm.pgd += ((shift) / (sizeof(pgd_t *)));
X
- null_pmd_table = __pa(((unsigned long)&empty_null_pmd_table) + phys_base);
- null_pte_table = __pa(((unsigned long)&empty_null_pte_table) + phys_base);
+ null_pmd_table = __pa(((unsigned long)&empty_null_pmd_table) + shift);
+ null_pte_table = __pa(((unsigned long)&empty_null_pte_table) + shift);
X
X pmdp = (pmd_t *) &empty_null_pmd_table;
X for(i = 0; i < 1024; i++)
@@ -553,13 +616,13 @@
X memset((void *) &empty_null_pte_table, 0, PAGE_SIZE);
X
X /* Now can init the kernel/bad page tables. */
- __bfill64((void *)swapper_pg_dir, null_pmd_table);
- __bfill64((void *)&empty_bad_pmd_table, null_pte_table);
+ __bfill64((void *)swapper_pg_dir, &null_pmd_table);
+ __bfill64((void *)&empty_bad_pmd_table, &null_pte_table);
X
X /* We use mempool to create page tables, therefore adjust it up
X * such that __pa() macros etc. work.
X */
- mempool = PAGE_ALIGN(start_mem) + phys_base;


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 25'
echo 'File patch-2.1.44 is continued in part 26'
echo 26 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part27

#!/bin/sh
# this is part 27 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 27; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

X end_init:
- if (tty)
- free_page((unsigned long) tty);
- if (o_tty)
- free_page((unsigned long) o_tty);
- if (tp)
- kfree_s(tp, sizeof(struct termios));
+ up_tty_sem(idx);
+ return retval;
+
+ /* Release locally allocated memory ... nothing placed in slots */
+free_mem_out:
X if (o_tp)
X kfree_s(o_tp, sizeof(struct termios));
+ if (o_tty)
+ free_page((unsigned long) o_tty);
X if (ltp)
X kfree_s(ltp, sizeof(struct termios));
- if (o_ltp)
- kfree_s(o_ltp, sizeof(struct termios));
- return retval;
+ if (tp)
+ kfree_s(tp, sizeof(struct termios));
+ free_page((unsigned long) tty);
+
+fail_no_mem:
+ retval = -ENOMEM;
+ goto end_init;
+
+ /* call the tty release_mem routine to clean out this slot */
+release_mem_out:
+ printk("init_dev: ldisc open failed, clearing slot %d\n", idx);
+ release_mem(tty, idx);
+ goto end_init;
+}
+
+/*
+ * Releases memory associated with a tty structure, and clears out the
+ * driver table slots.
+ */
+static void release_mem(struct tty_struct *tty, int idx)
+{
+ struct tty_struct *o_tty;
+ struct termios *tp;
+
+ if ((o_tty = tty->link) != NULL) {
+ o_tty->driver.table[idx] = NULL;
+ if (o_tty->driver.flags & TTY_DRIVER_RESET_TERMIOS) {
+ tp = o_tty->driver.termios[idx];
+ o_tty->driver.termios[idx] = NULL;
+ kfree_s(tp, sizeof(struct termios));
+ }
+ o_tty->magic = 0;
+ (*o_tty->driver.refcount)--;
+ free_page((unsigned long) o_tty);
+ }
+
+ tty->driver.table[idx] = NULL;
+ if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS) {
+ tp = tty->driver.termios[idx];
+ tty->driver.termios[idx] = NULL;
+ kfree_s(tp, sizeof(struct termios));
+ }
+ tty->magic = 0;
+ (*tty->driver.refcount)--;
+ free_page((unsigned long) tty);
X }
X
X /*
X * Even releasing the tty structures is a tricky business.. We have
X * to be very careful that the structures are all released at the
X * same time, as interrupts might otherwise get the wrong pointers.
+ *
+ * WSH 09/09/97: rewritten to avoid some nasty race conditions that could
+ * lead to double frees or releasing memory still in use.
X */
X static void release_dev(struct file * filp)
X {
X struct tty_struct *tty, *o_tty;
- struct termios *tp, *o_tp, *ltp, *o_ltp;
- struct task_struct *p;
+ int pty_master, tty_closing, o_tty_closing, do_sleep;
X int idx;
X
X tty = (struct tty_struct *)filp->private_data;
@@ -849,10 +926,11 @@
X
X tty_fasync(filp->f_inode, filp, 0);
X
- tp = tty->termios;
- ltp = tty->termios_locked;
-
X idx = MINOR(tty->device) - tty->driver.minor_start;
+ pty_master = (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
+ tty->driver.subtype == PTY_TYPE_MASTER);
+ o_tty = tty->link;
+
X #ifdef TTY_PARANOIA_CHECK
X if (idx < 0 || idx >= tty->driver.num) {
X printk("release_dev: bad idx when trying to free (%s)\n",
@@ -864,15 +942,15 @@
X idx, kdevname(tty->device));
X return;
X }
- if (tp != tty->driver.termios[idx]) {
- printk("release_dev: driver.termios[%d] not termios for ("
- "%s)\n",
+ if (tty->termios != tty->driver.termios[idx]) {
+ printk("release_dev: driver.termios[%d] not termios "
+ "for (%s)\n",
X idx, kdevname(tty->device));
X return;
X }
- if (ltp != tty->driver.termios_locked[idx]) {
- printk("release_dev: driver.termios_locked[%d] not termios_locked for ("
- "%s)\n",
+ if (tty->termios_locked != tty->driver.termios_locked[idx]) {
+ printk("release_dev: driver.termios_locked[%d] not "
+ "termios_locked for (%s)\n",
X idx, kdevname(tty->device));
X return;
X }
@@ -883,10 +961,6 @@
X tty->count);
X #endif
X
- o_tty = tty->link;
- o_tp = (o_tty) ? o_tty->termios : NULL;
- o_ltp = (o_tty) ? o_tty->termios_locked : NULL;
-
X #ifdef TTY_PARANOIA_CHECK
X if (tty->driver.other) {
X if (o_tty != tty->driver.other->table[idx]) {
@@ -895,34 +969,90 @@
X idx, kdevname(tty->device));
X return;
X }
- if (o_tp != tty->driver.other->termios[idx]) {
- printk("release_dev: other->termios[%d] not o_termios for ("
- "%s)\n",
+ if (o_tty->termios != tty->driver.other->termios[idx]) {
+ printk("release_dev: other->termios[%d] not o_termios "
+ "for (%s)\n",
X idx, kdevname(tty->device));
X return;
X }
- if (o_ltp != tty->driver.other->termios_locked[idx]) {
- printk("release_dev: other->termios_locked[%d] not o_termios_locked for ("
- "%s)\n",
+ if (o_tty->termios_locked !=
+ tty->driver.other->termios_locked[idx]) {
+ printk("release_dev: other->termios_locked[%d] not "
+ "o_termios_locked for (%s)\n",
X idx, kdevname(tty->device));
X return;
X }
-
X if (o_tty->link != tty) {
X printk("release_dev: bad pty pointers\n");
X return;
X }
X }
X #endif
-
+ /*
+ * Sanity check: if tty->count is going to zero, there shouldn't be
+ * any waiters on tty->read_wait or tty->write_wait. We test the
+ * wait queues and kick everyone out _before_ actually starting to
+ * close. This ensures that we won't block while releasing the tty
+ * structure.
+ *
+ * The test for the o_tty closing is necessary, since the master and
+ * slave sides may close in any order. If the slave side closes out
+ * first, its count will be one, since the master side holds an open.
+ * Thus this test wouldn't be triggered at the time the slave closes,
+ * so we do it now.
+ *
+ * Note that it's possible for the tty to be opened again while we're
+ * flushing out waiters. By recalculating the closing flags before
+ * each iteration we avoid any problems.
+ */
+ while (1) {
+ tty_closing = tty->count <= 1;
+ o_tty_closing = o_tty &&
+ (o_tty->count <= (pty_master ? 1 : 0));
+ do_sleep = 0;
+
+ if (tty_closing) {
+ if (waitqueue_active(&tty->read_wait)) {
+ wake_up(&tty->read_wait);
+ do_sleep++;
+ }
+ if (waitqueue_active(&tty->write_wait)) {
+ wake_up(&tty->write_wait);
+ do_sleep++;
+ }
+ }
+ if (o_tty_closing) {
+ if (waitqueue_active(&o_tty->read_wait)) {
+ wake_up(&o_tty->read_wait);
+ do_sleep++;
+ }
+ if (waitqueue_active(&o_tty->write_wait)) {
+ wake_up(&o_tty->write_wait);
+ do_sleep++;
+ }
+ }
+ if (!do_sleep)
+ break;
+
+ printk("release_dev: %s: read/write wait queue active!\n",
+ tty_name(tty));
+ schedule();
+ }
+
+ /*
+ * The closing flags are now consistent with the open counts on
+ * both sides, and we've completed the last operation that could
+ * block, so it's safe to proceed with closing.
+ */
+
X if (tty->driver.close)
X tty->driver.close(tty, filp);
- if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
- tty->driver.subtype == PTY_TYPE_MASTER) {
- if (--tty->link->count < 0) {
+
+ if (pty_master) {
+ if (--o_tty->count < 0) {
X printk("release_dev: bad pty slave count (%d) for %s\n",
- tty->count, tty_name(tty));
- tty->link->count = 0;
+ o_tty->count, tty_name(o_tty));
+ o_tty->count = 0;
X }
X }
X if (--tty->count < 0) {
@@ -930,60 +1060,50 @@
X tty->count, tty_name(tty));
X tty->count = 0;
X }
- if (tty->count)
- return;
X
X /*
- * Sanity check --- if tty->count is zero, there shouldn't be
- * any waiters on tty->read_wait or tty->write_wait. But just
- * in case....
+ * Perform some housekeeping before deciding whether to return.
+ *
+ * Set the TTY_CLOSING flag if this was the last open. In the
+ * case of a pty we may have to wait around for the other side
+ * to close, and TTY_CLOSING makes sure we can't be reopened.
X */
- while (1) {
- if (waitqueue_active(&tty->read_wait)) {
- printk("release_dev: %s: read_wait active?!?\n",
- tty_name(tty));
- wake_up(&tty->read_wait);
- } else if (waitqueue_active(&tty->write_wait)) {
- printk("release_dev: %s: write_wait active?!?\n",
- tty_name(tty));
- wake_up(&tty->write_wait);
- } else
- break;
- schedule();
- }
-
+ if(tty_closing)
+ tty->flags |= (1 << TTY_CLOSING);
+ if(o_tty_closing)
+ o_tty->flags |= (1 << TTY_CLOSING);
+
X /*
- * We're committed; at this point, we must not block!
+ * If _either_ side is closing, make sure there aren't any
+ * processes that still think tty or o_tty is their controlling
+ * tty. Also, clear redirect if it points to either tty.
X */
- if (o_tty) {
- if (o_tty->count)
- return;
- tty->driver.other->table[idx] = NULL;
- tty->driver.other->termios[idx] = NULL;
- kfree_s(o_tp, sizeof(struct termios));
+ if (tty_closing || o_tty_closing) {


+ struct task_struct *p;
+

+ read_lock(&tasklist_lock);
+ for_each_task(p) {
+ if (p->tty == tty || (o_tty && p->tty == o_tty))
+ p->tty = NULL;
+ }
+ read_unlock(&tasklist_lock);
+
+ if (redirect == tty || (o_tty && redirect == o_tty))
+ redirect = NULL;
X }
+
+ /* check whether both sides are closing ... */
+ if (!tty_closing || (o_tty && !o_tty_closing))
+ return;
+ filp->private_data = 0;
X
X #ifdef TTY_DEBUG_HANGUP
X printk("freeing tty structure...");
X #endif
- tty->flags |= (1 << TTY_CLOSING);
X
X /*
- * Make sure there aren't any processes that still think this
- * tty is their controlling tty.
- */
- read_lock(&tasklist_lock);
- for_each_task(p) {
- if (p->tty == tty)
- p->tty = NULL;
- if (o_tty && p->tty == o_tty)
- p->tty = NULL;
- }
- read_unlock(&tasklist_lock);
-
- /*
- * Shutdown the current line discipline, and reset it to
- * N_TTY.
+ * Shutdown the current line discipline, and reset it to N_TTY.
+ * N.B. why reset ldisc when we're releasing the memory??
X */
X if (tty->ldisc.close)
X (tty->ldisc.close)(tty);
@@ -995,41 +1115,34 @@
X o_tty->ldisc = ldiscs[N_TTY];
X }
X
- tty->driver.table[idx] = NULL;
- if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS) {
- tty->driver.termios[idx] = NULL;
- kfree_s(tp, sizeof(struct termios));
- }
- if (tty == redirect || o_tty == redirect)
- redirect = NULL;
X /*
X * Make sure that the tty's task queue isn't activated. If it
- * is, take it out of the linked list.
+ * is, take it out of the linked list. The tqueue isn't used by
+ * pty's, so skip the test for them.
X */
- spin_lock_irq(&tqueue_lock);
- if (tty->flip.tqueue.sync) {
- struct tq_struct *tq, *prev;
-
- for (tq=tq_timer, prev=0; tq; prev=tq, tq=tq->next) {
- if (tq == &tty->flip.tqueue) {
- if (prev)
- prev->next = tq->next;
- else
- tq_timer = tq->next;
- break;
+ if (tty->driver.type != TTY_DRIVER_TYPE_PTY) {
+ spin_lock_irq(&tqueue_lock);
+ if (tty->flip.tqueue.sync) {
+ struct tq_struct *tq, *prev;
+
+ for (tq=tq_timer, prev=0; tq; prev=tq, tq=tq->next) {
+ if (tq == &tty->flip.tqueue) {
+ if (prev)
+ prev->next = tq->next;
+ else
+ tq_timer = tq->next;
+ break;
+ }
X }
X }
+ spin_unlock_irq(&tqueue_lock);
X }
- spin_unlock_irq(&tqueue_lock);
- tty->magic = 0;
- (*tty->driver.refcount)--;
- free_page((unsigned long) tty);
- filp->private_data = 0;
- if (o_tty) {
- o_tty->magic = 0;
- (*o_tty->driver.refcount)--;
- free_page((unsigned long) o_tty);
- }
+
+ /*
+ * The release_mem function takes care of the details of clearing
+ * the slots and preserving the termios structure.
+ */
+ release_mem(tty, idx);
X }
X
X /*
@@ -1077,6 +1190,7 @@
X retval = init_dev(device, &tty);


X if (retval)
X return retval;

+ /* N.B. this error exit may leave filp->f_flags with O_NONBLOCK set */
X filp->private_data = tty;
X check_tty_count(tty, "tty_open");
X if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
@@ -1123,11 +1237,6 @@


X return 0;
X }
X
-/*

- * 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.
- */
X static int tty_release(struct inode * inode, struct file * filp)
X {
X release_dev(filp);
@@ -1545,6 +1654,7 @@
X tty->flip.flag_buf_ptr = tty->flip.flag_buf;
X tty->flip.tqueue.routine = flush_to_ldisc;
X tty->flip.tqueue.data = tty;
+ tty->flip.pty_sem = MUTEX;
X }
X
X /*
diff -u --recursive --new-file v2.1.43/linux/drivers/char/vc_screen.c linux/drivers/char/vc_screen.c
--- v2.1.43/linux/drivers/char/vc_screen.c Mon Jun 16 16:35:55 1997
+++ linux/drivers/char/vc_screen.c Mon Jul 7 08:24:28 1997
@@ -237,6 +237,11 @@
X func_scr_writew((func_scr_readw(org) & 0xff00) | c, org);
X }
X }
+#ifdef CONFIG_FB_CONSOLE
+ if (currcons == fg_console)
+ /* Horribly inefficient if count < screen size. */
+ update_screen(currcons);
+#endif
X written = buf - buf0;
X file->f_pos += written;
X RETURN( written );
diff -u --recursive --new-file v2.1.43/linux/drivers/isdn/avmb1/capiutil.c linux/drivers/isdn/avmb1/capiutil.c
--- v2.1.43/linux/drivers/isdn/avmb1/capiutil.c Thu May 29 21:53:05 1997
+++ linux/drivers/isdn/avmb1/capiutil.c Mon Jul 7 08:19:59 1997
@@ -26,6 +26,7 @@
X *
X */
X #include <linux/module.h>


+#include <linux/config.h>
X #include <linux/string.h>

X #include <linux/ctype.h>
X #include <linux/stddef.h>
diff -u --recursive --new-file v2.1.43/linux/drivers/isdn/sc/Makefile linux/drivers/isdn/sc/Makefile
--- v2.1.43/linux/drivers/isdn/sc/Makefile Thu May 29 21:53:06 1997
+++ linux/drivers/isdn/sc/Makefile Thu Jun 26 12:33:39 1997
@@ -1,5 +1,5 @@
X #
-# $Id: Makefile,v 1.3 1997/05/27 23:25:01 fritz Exp $
+# $Id: Makefile,v 1.1 1997/03/22 02:01:22 fritz Exp $
X # Copyright (C) 1996 SpellCaster Telecommunications Inc.
X #
X # This program is free software; you can redistribute it and/or modify
diff -u --recursive --new-file v2.1.43/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v2.1.43/linux/drivers/net/Config.in Mon Jun 16 16:35:55 1997
+++ linux/drivers/net/Config.in Mon Jul 7 08:19:59 1997
@@ -15,6 +15,9 @@
X #
X bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET
X if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
+ if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then
+ bool 'MIPS JAZZ onboard SONIC ethernet support' CONFIG_MIPS_JAZZ_SONIC
+ fi
X bool '3COM cards' CONFIG_NET_VENDOR_3COM
X if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
X tristate '3c501 support' CONFIG_EL1
@@ -110,7 +113,12 @@
X #


X if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then

X if [ "$CONFIG_ATALK" != "n" ]; then
- tristate 'LocalTalk PC support' CONFIG_LTPC
+ tristate 'Apple/Farallon LocalTalk PC support' CONFIG_LTPC
+ tristate 'COPS LocalTalk PC support' CONFIG_COPS
+ if [ "$CONFIG_COPS" != "n" ]; then
+ bool 'Dayna firmware support' CONFIG_COPS_DAYNA
+ bool 'Tangent firmware support' CONFIG_COPS_TANGENT
+ fi
X fi
X fi
X
diff -u --recursive --new-file v2.1.43/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v2.1.43/linux/drivers/net/Makefile Sun Apr 13 10:18:21 1997
+++ linux/drivers/net/Makefile Thu Jun 26 12:33:39 1997
@@ -275,6 +275,10 @@
X endif
X endif
X
+ifeq ($(CONFIG_SGISEEQ), y)
+L_OBJS += sgiseeq.o
+endif
+
X ifeq ($(CONFIG_HAPPYMEAL),y)
X L_OBJS += sunhme.o
X else
@@ -563,6 +567,14 @@
X endif
X endif
X
+ifeq ($(CONFIG_MIPS_JAZZ_SONIC),y)
+L_OBJS += sonic.o
+else
+ ifeq ($(CONFIG_MIPS_JAZZ_SONIC),m)
+ M_OBJS += sonic.o
+ endif
+endif
+
X ifeq ($(CONFIG_ATARILANCE),y)
X L_OBJS += atarilance.o
X else
@@ -648,6 +660,14 @@
X else
X ifeq ($(CONFIG_LTPC),m)
X M_OBJS += ltpc.o
+ endif
+endif
+
+ifeq ($(CONFIG_COPS),y)
+L_OBJS += cops.o
+else
+ ifeq ($(CONFIG_COPS),m)
+ M_OBJS += cops.o
X endif
X endif
X
diff -u --recursive --new-file v2.1.43/linux/drivers/net/Space.c linux/drivers/net/Space.c
--- v2.1.43/linux/drivers/net/Space.c Wed Apr 23 19:01:18 1997
+++ linux/drivers/net/Space.c Thu Jun 26 12:33:39 1997
@@ -74,6 +74,7 @@
X extern int e2100_probe(struct device *);
X extern int ni52_probe(struct device *);
X extern int ni65_probe(struct device *);
+extern int sonic_probe(struct device *);
X extern int SK_init(struct device *);
X extern int seeq8005_probe(struct device *);
X extern int tc59x_probe(struct device *);
@@ -83,6 +84,7 @@
X extern int happy_meal_probe(struct device *);
X extern int qec_probe(struct device *);
X extern int myri_sbus_probe(struct device *);
+extern int sgiseeq_probe(struct device *);
X extern int atarilance_probe(struct device *);
X extern int a2065_probe(struct device *);
X extern int ariadne_probe(struct device *);
@@ -241,7 +243,7 @@
X && sparc_lance_probe(dev)
X #endif
X #ifdef CONFIG_HAPPYMEAL
- && happy_meal_probe(dev)
+ && happy_meal_probe(dev)
X #endif
X #ifdef CONFIG_SUNQE
X && qec_probe(dev)
@@ -249,6 +251,12 @@
X #ifdef CONFIG_MYRI_SBUS
X && myri_sbus_probe(dev)
X #endif
+#ifdef CONFIG_SGISEEQ
+ && sgiseeq_probe(dev)
+#endif
+#ifdef CONFIG_MIPS_JAZZ_SONIC
+ && sonic_probe(dev)
+#endif
X && 1 ) {
X return 1; /* -ENODEV or -EAGAIN would be more accurate. */
X }
@@ -292,6 +300,17 @@
X # undef NEXT_DEV
X # define NEXT_DEV (&dev_ltpc)
X #endif /* LTPC */
+
+#if defined(CONFIG_COPS)
+ extern int cops_probe(struct device *);
+ static struct device dev_cops = {
+ "lt0",
+ 0, 0, 0, 0,
+ 0x0, 0,
+ 0, 0, 0, NEXT_DEV, cops_probe };
+# undef NEXT_DEV
+# define NEXT_DEV (&dev_cops)
+#endif /* COPS */
X
X /* The first device defaults to I/O base '0', which means autoprobe. */
X #ifndef ETH0_ADDR
diff -u --recursive --new-file v2.1.43/linux/drivers/net/cops.c linux/drivers/net/cops.c
--- v2.1.43/linux/drivers/net/cops.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/cops.c Mon Jul 7 08:19:59 1997
@@ -0,0 +1,1017 @@
+/* cops.c: LocalTalk driver for Linux.
+ *
+ * Authors:
+ * - Jay Schulist <Jay.Sc...@spacs.k12.wi.us>
+ *
+ * With more than a little help from;
+ * - Alan Cox <Alan...@linux.org>
+ *
+ * Derived from:
+ * - skeleton.c: A network driver outline for linux.
+ * Written 1993-94 by Donald Becker.
+ * - ltpc.c: A driver for the LocalTalk PC card.
+ * Written by Bradford W. Johnson.
+ *
+ * Copyright 1993 United States Government as represented by the
+ * Director, National Security Agency.
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License, incorporated herein by reference.
+ *
+ * Changes:
+ * 19970608 Alan Cox Allowed dual card type support
+ * Can set board type in insmod
+ * Hooks for cops_setup routine
+ * (not yet implemented).
+ */
+
+static const char *version =
+ "cops.c:v0.01 3/17/97 Jay Schulist <Jay.Sc...@spacs.k12.wi.us>\n";
+/*
+ * Sources:
+ * COPS Localtalk SDK. This provides almost all of the information
+ * needed.
+ */
+
+/*
+ * insmod/modprobe configurable stuff.
+ * - IO Port, choose one your card supports or 0 if you dare.
+ * - IRQ, also choose one your card supports or nothing and let
+ * the driver figure it out.
+ */
+
+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+#endif
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/errno.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <linux/if_arp.h>
+#include <linux/if_ltalk.h> /* For ltalk_setup() */
+#include <linux/delay.h> /* For udelay() */
+#include <linux/atalk.h>
+
+#include "cops.h" /* Our Stuff */
+#include "cops_ltdrv.h" /* Firmware code for Tangent type cards. */
+#include "cops_ffdrv.h" /* Firmware code for Dayna type cards. */
+
+/*
+ * The name of the card. Is used for messages and in the requests for
+ * io regions, irqs and dma channels
+ */
+
+static const char *cardname = "cops";
+
+#ifdef CONFIG_COPS_DAYNA
+static int board_type = DAYNA; /* Module exported */
+#else
+static int board_type = TANGENT;
+#endif
+
+#ifdef MODULE
+static int io = 0x240; /* Default IO for Dayna */
+static int irq = 5; /* Default IRQ */
+#else
+static int io = 0; /* Default IO for Dayna */
+static int irq = 0; /* Default IRQ */
+#endif
+
+/*
+ * COPS Autoprobe information.
+ * Right now if port address is right but IRQ is not 5 this will
+ * return a 5 no matter what since we will still get a status response.
+ * Need one more additional check to narrow down after we have gotten
+ * the ioaddr. But since only other possible IRQs is 3 and 4 so no real
+ * hurry on this. I *STRONGLY* recommend using IRQ 5 for your card with
+ * this driver.
+ *
+ * This driver has 2 modes and they are: Dayna mode and Tangent mode.
+ * Each mode corresponds with the type of card. It has been found
+ * that there are 2 main types of cards and all other cards are
+ * the same and just have different names or only have minor differences
+ * such as more IO ports. As this driver is tested it will
+ * become more clear on exactly what cards are supported. The driver
+ * defaults to using Dayna mode. To change the drivers mode adjust
+ * drivers/net/CONFIG, and the line COPS_OPTS = -DDAYNA to -DTANGENT.
+ *
+ * This driver should support:
+ * TANGENT driver mode:
+ * Tangent ATB-II, Novell NL-1000, Daystar Digital LT-200
+ * DAYNA driver mode:
+ * Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95, Farallon PhoneNET PC III
+ * Other cards possibly supported mode unkown though:
+ * Farallon PhoneNET PC II
+ * Dayna DL2000 (Full length)
+ *
+ * Cards NOT supported by this driver but supported by the ltpc.c
+ * driver written by Bradford W. Johnson <john...@maroon.tc.umn.edu>
+ * Farallon PhoneNET PC
+ * Original Apple LocalTalk PC card
+ */
+
+/*
+ * Zero terminated list of IO ports to probe.
+ */
+
+static unsigned int cops_portlist[] = {
+ 0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260,
+ 0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360,
+ 0
+};
+
+/*
+ * Zero terminated list of IRQ ports to probe.
+ */
+
+static int cops_irqlist[] = {
+ 5, 4, 3, 0
+};
+
+/* use 0 for production, 1 for verification, 2 for debug, 3 for very verbose debug */
+#ifndef COPS_DEBUG
+#define COPS_DEBUG 1
+#endif
+static unsigned int cops_debug = COPS_DEBUG;
+
+/* The number of low I/O ports used by the card. */
+#define COPS_IO_EXTENT 8
+
+/* Information that needs to be kept for each board. */
+
+struct cops_local
+{
+ struct enet_statistics stats;
+ int board; /* Holds what board type is. */
+ int nodeid; /* Set to 1 once have nodeid. */
+ unsigned char node_acquire; /* Node ID when acquired. */
+};
+
+/* Allocate a new device with the form of lt0, lt1, lt2, etc. */
+struct device *cops_dev_alloc(char *name)
+{
+ int i=0;
+ struct device *d=kmalloc(sizeof(struct device)+8, GFP_KERNEL);
+
+ memset(d,0,sizeof(*d)); /* Clear the structure */
+ if(d==NULL)
+ return NULL;
+ d->name=(char *)(d+1); /* Name string space */
+
+ /* Get next free device name */
+ for(i=0;i<100;i++)
+ {
+ sprintf(d->name,name,i);
+ if(dev_get(d->name)==NULL)
+ return d;
+ }
+ return NULL; /* Over 100 of the things .. bail out! */
+}
+
+/* Index to functions, as function prototypes. */
+extern int cops_probe (struct device *dev);
+static int cops_probe1 (struct device *dev, int ioaddr);
+static int cops_irq (int ioaddr, int board);
+
+static int cops_open (struct device *dev);
+static int cops_jumpstart (struct device *dev);
+static void cops_reset (struct device *dev, int sleep);
+static void cops_load (struct device *dev);
+static int cops_nodeid (struct device *dev, int nodeid);
+
+static void cops_interrupt (int irq, void *dev_id, struct pt_regs *regs);
+static void cops_rx (struct device *dev);
+static int cops_send_packet (struct sk_buff *skb, struct device *dev);
+static void set_multicast_list (struct device *dev);
+static int cops_hard_header (struct sk_buff *skb, struct device *dev,
+ unsigned short type, void *daddr, void *saddr, unsigned len);
+
+static int cops_ioctl (struct device *dev, struct ifreq *rq, int cmd);
+static int cops_close (struct device *dev);
+static struct enet_statistics *cops_get_stats (struct device *dev);
+
+
+/*
+ * Check for a network adaptor of this type, and return '0' iff one exists.
+ * If dev->base_addr == 0, probe all likely locations.
+ * If dev->base_addr == 1, always return failure.
+ * If dev->base_addr == 2, allocate space for the device and return success
+ * (detachable devices only).
+ */
+int cops_probe(struct device *dev)
+{
+ int i;
+ int base_addr = dev ? dev->base_addr : 0;
+
+ if (base_addr == 0 && io)
+ base_addr=io;
+
+ if (base_addr > 0x1ff) /* Check a single specified location. */
+ return cops_probe1(dev, base_addr);
+ else if (base_addr != 0) /* Don't probe at all. */
+ return -ENXIO;
+
+ for (i=0; cops_portlist[i]; i++) {
+ int ioaddr = cops_portlist[i];
+ if (check_region(ioaddr, COPS_IO_EXTENT))
+ continue;
+ if (cops_probe1(dev, ioaddr) == 0)


+ return 0;
+ }
+

+ /* No "lt" devices found. */
+ printk(KERN_WARNING "%s: No COPS localtalk devices found!\n", dev->name);
+ return -ENODEV;
+}
+
+/*
+ * This is the real probe routine. Linux has a history of friendly device
+ * probes on the ISA bus. A good device probes avoids doing writes, and
+ * verifies that the correct device exists and functions.
+ */
+static int cops_probe1(struct device *dev, int ioaddr)
+{
+ struct cops_local *lp;
+ static unsigned version_printed = 0;
+ int irqaddr = 0;
+ int irqval;
+
+ int board = board_type;
+
+/* Defined here to save some trouble */
+
+ /* Allocate a new 'dev' if needed. */
+ if (dev == NULL)
+ {
+ dev=cops_dev_alloc(dev->name); /* New "lt" device; beyond lt0. */
+ if(dev==NULL)


+ return -ENOMEM;
+ }
+

+ if (cops_debug && version_printed++ == 0)
+ printk("%s", version);
+
+ /* Fill in the 'dev' fields. */
+ dev->base_addr = ioaddr;
+
+ /*
+ * Since this board has jumpered interrupts, allocate the interrupt
+ * vector now. There is no point in waiting since no other device
+ * can use the interrupt, and this marks the irq as busy. Jumpered
+ * interrupts are typically not reported by the boards, and we must
+ * used AutoIRQ to find them.
+ *
+ */
+
+ if (dev->irq < 2 && irq)
+ dev->irq = irq;
+
+ if (dev->irq < 2)
+ {
+ irqaddr = cops_irq(ioaddr, board); /* COPS AutoIRQ routine */
+ if (irqaddr == 0)
+ return -EAGAIN; /* No IRQ found on this port */
+ else
+ dev->irq = irqaddr;
+ }
+ else if (dev->irq == 2)
+ /*
+ * Fixup for users that don't know that IRQ 2 is really
+ * IRQ 9, or don't know which one to set.
+ */
+ dev->irq = 9;
+
+ /* Snarf the interrupt now. */
+ irqval = request_irq(dev->irq, &cops_interrupt, 0, cardname, NULL);
+ if (irqval)
+ {
+ printk(KERN_WARNING "%s: Unable to get IRQ %d (irqval=%d).\n", dev->name, dev->irq, irqval);
+ return -EAGAIN;
+ }
+
+ dev->hard_start_xmit = &cops_send_packet;
+
+ /* Initialize the device structure. */
+ dev->priv = kmalloc(sizeof(struct cops_local), GFP_KERNEL);
+ if (dev->priv == NULL)
+ return -ENOMEM;
+
+ lp = (struct cops_local *)dev->priv;
+ memset(lp, 0, sizeof(struct cops_local));
+
+ /* Copy local board variable to lp struct. */
+ lp->board = board;
+
+ /* Tell the user where the card is and what mode were in. */
+ if(board==DAYNA)
+ printk("%s: %s found at %#3x, using IRQ %d, in Dayna mode.\n",
+ dev->name, cardname, ioaddr, dev->irq);
+ if(board==TANGENT)
+ printk("%s: %s found at %#3x, using IRQ %d, in Tangent mode.\n",
+ dev->name, cardname, ioaddr, dev->irq);
+
+ /* Grab the region so no one else tries to probe our ioports. */
+ request_region(ioaddr, COPS_IO_EXTENT, cardname);
+
+ /* Fill in the fields of the device structure with LocalTalk values. */
+ ltalk_setup(dev);
+
+ dev->hard_header = cops_hard_header;
+ dev->get_stats = cops_get_stats;
+ dev->open = cops_open;
+ dev->stop = cops_close;
+ dev->do_ioctl = &cops_ioctl;
+ dev->set_multicast_list = &set_multicast_list;
+ dev->mc_list = NULL;


+
+ return 0;
+}
+

+static int cops_irq (int ioaddr, int board)
+{ /*
+ * This does not use the IRQ to determine where the IRQ is. We just
+ * assume that when we get a correct status response that is the IRQ then.
+ * This really just verifies the IO port but since we only have access
+ * to such a small number of IRQs (5, 4, 3) this is not bad.
+ * This will probably not work for more than one card.
+ */
+ int irqaddr=0;
+ int i, x, status;
+
+ if(board==DAYNA)
+ {
+ outb(0, ioaddr+DAYNA_RESET);
+ inb(ioaddr+DAYNA_RESET);
+ udelay(333333);
+ }
+ if(board==TANGENT)
+ {
+ inb(ioaddr);
+ outb(0, ioaddr);
+ outb(0, ioaddr+TANG_RESET);
+ }
+
+ for(i=0; cops_irqlist[i] !=0; i++)
+ {
+ irqaddr = cops_irqlist[i];
+ for(x = 0xFFFF; x>0; x --) /* wait for response */
+ {
+ if(board==DAYNA)
+ {
+ status = (inb(ioaddr+DAYNA_CARD_STATUS)&3);
+ if (status == 1)
+ return irqaddr;
+ }
+ if(board==TANGENT)
+ {
+ if((inb(ioaddr+TANG_CARD_STATUS)& TANG_TX_READY) !=0)
+ return irqaddr;
+ }
+ }
+ }
+ return 0; /* no IRQ found */
+}
+
+/*
+ * Open/initialize the board. This is called (in the current kernel)
+ * sometime after booting when the 'ifconfig' program is run.
+ */
+static int cops_open(struct device *dev)
+{
+ irq2dev_map[dev->irq] = dev;
+
+ cops_jumpstart(dev); /* Start the card up. */
+
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 1;
+
+#ifdef MODULE
+ MOD_INC_USE_COUNT;
+#endif


+
+ return 0;
+}
+

+/*
+ * This allows for a dynamic start/restart of the entire card.
+ */
+static int cops_jumpstart(struct device *dev)
+{
+ struct cops_local *lp = (struct cops_local *)dev->priv;
+
+ /*
+ * Once the card has the firmware loaded and has acquired
+ * the nodeid, if it is reset it will lose it all.
+ */
+ cops_reset(dev,1); /* Need to reset card before load firmware. */
+ cops_load(dev); /* Load the firmware. */
+
+ /*
+ * If atalkd already gave us a nodeid we will use that
+ * one again, else we wait for atalkd to give us a nodeid
+ * in cops_ioctl. This may cause a problem if someone steals
+ * our nodeid while we are resetting.
+ */
+ if(lp->nodeid == 1)
+ cops_nodeid(dev,lp->node_acquire);


+
+ return 0;
+}
+

+static int tangent_wait_reset(int ioaddr)
+{
+ int timeout=0;
+
+ while(timeout < 5000 && (inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
+ udelay(1000); /* Wait 1000 useconds */


+
+ return 0;
+}
+

+/*
+ * Reset the LocalTalk board.
+ */
+static void cops_reset(struct device *dev, int sleep)
+{
+ struct cops_local *lp = (struct cops_local *)dev->priv;
+ int ioaddr=dev->base_addr;
+
+ if(lp->board==TANGENT)
+ {
+ inb(ioaddr); /* Clear request latch. */
+ outb(0,ioaddr); /* Clear the TANG_TX_READY flop. */
+ outb(0, ioaddr+TANG_RESET); /* Reset the adapter. */
+
+ /* Can take 5 seconds max - youch! */
+ if(sleep)
+ {
+ long snapt=jiffies;
+ while(jiffies-snapt<5*HZ)
+ {
+ if(inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)
+ break;
+ schedule();
+ }
+ }
+ else
+ tangent_wait_reset(ioaddr);
+ outb(0, ioaddr+TANG_CLEAR_INT);
+ }
+ if(lp->board==DAYNA)
+ {
+ outb(0, ioaddr+DAYNA_RESET); /* Assert the reset port */
+ inb(ioaddr+DAYNA_RESET); /* Clear the reset */
+ if(sleep)
+ {
+ long snap=jiffies;
+
+ /* Let card finish initializing, about 1/3 second */
+ while(jiffies-snap<HZ/3)
+ schedule();
+ }
+ else
+ udelay(333333);
+ }
+ dev->tbusy=0;
+
+ return;
+}
+
+static void cops_load (struct device *dev)
+{
+ struct ifreq ifr;
+ struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_data;
+ struct cops_local *lp=(struct cops_local *)dev->priv;
+ int ioaddr=dev->base_addr;
+ int length, i = 0;
+
+ strcpy(ifr.ifr_name,"lt0");
+
+ /* Get card's firmware code and do some checks on it. */
+#ifdef CONFIG_COPS_DAYNA
+ if (lp->board==DAYNA)
+ {
+ ltf->length=sizeof(ffdrv_code);
+ ltf->data=ffdrv_code;
+ }
+ else
+#endif
+#ifdef CONFIG_COPS_TANGENT
+ if (lp->board==TANGENT)
+ {
+ ltf->length=sizeof(ltdrv_code);
+ ltf->data=ltdrv_code;
+ }
+ else
+#endif
+ {
+ printk(KERN_INFO "%s; unsupported board type.\n", dev->name);
+ return;
+ }
+
+ /* Check to make sure firmware is correct length. */
+ if(lp->board==DAYNA && ltf->length!=5983)
+ {
+ printk(KERN_WARNING "%s: Firmware is not length of FFDRV.BIN.\n", dev->name);
+ return;
+ }
+ if(lp->board==TANGENT && ltf->length!=2501)
+ {
+ printk(KERN_WARNING "%s: Firmware is not length of DRVCODE.BIN.\n", dev->name);
+ return;
+ }
+
+ if(lp->board==DAYNA)
+ {
+ /*
+ * We must wait for a status response
+ * with the DAYNA board.
+ */
+ while(++i<65536)
+ {
+ if((inb(ioaddr+DAYNA_CARD_STATUS)&3)==1)
+ break;
+ }
+
+ if(i==65536)
+ return;
+ }
+
+ /*
+ * Upload the firmware and kick. Byte-by-byte works nicely here.
+ */
+ i=0;
+ length = ltf->length;
+ while(length--)
+ {
+ outb(ltf->data[i], ioaddr);
+ i++;
+ }
+
+ if(cops_debug > 1)
+ printk(KERN_DEBUG "%s: Uploaded firmware - %d bytes of %d bytes.\n", dev->name, i, ltf->length);
+
+ if(lp->board==DAYNA)
+ outb(1, ioaddr+DAYNA_INT_CARD); /* Tell Dayna to run the firmware code. */
+ else
+ inb(ioaddr); /* Tell Tang to run the firmware code. */
+
+ if(lp->board==TANGENT)
+ {
+ tangent_wait_reset(ioaddr);
+ inb(ioaddr); /* Clear initial ready signal. */
+ }
+
+ return;
+}
+
+/*
+ * Get the LocalTalk Nodeid from the card. We can suggest
+ * any nodeid 1-254. The card will try and get that exact
+ * address else we can specify 0 as the nodeid and the card
+ * will autoprobe for a nodeid.
+ */
+static int cops_nodeid (struct device *dev, int nodeid)
+{
+ struct cops_local *lp = (struct cops_local *) dev->priv;
+ int ioaddr = dev->base_addr;
+
+ if (lp->board == DAYNA)
+ {
+ /* Empty any pending adapter responses. */
+ while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0)
+ {
+ outb(0, ioaddr+COPS_CLEAR_INT); /* Clear any interrupt. */
+ if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST)
+ cops_rx(dev); /* Kick out any packet waiting. */
+ schedule();
+ }
+
+ outb(2, ioaddr); /* Output command packet length as 2. */
+ outb(0, ioaddr);
+ outb(LAP_INIT, ioaddr); /* Send LAP_INIT command byte. */
+ outb(nodeid, ioaddr); /* Suggest node address. */
+ }
+
+ if (lp->board == TANGENT)
+ {
+ /* Empty any pending adapter responses. */
+ while(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY)
+ {
+ outb(0, ioaddr+COPS_CLEAR_INT); /* Clear any interrupt. */
+ cops_rx(dev); /* Kick out any packet waiting. */
+ schedule();
+ }
+
+ /* Not sure what Tangent does if random nodeid we picked is already used. */
+ if(nodeid == 0) /* Seed. */
+ nodeid = jiffies&0xFF; /* Get a random try .*/
+ outb(2, ioaddr); /* Command length LSB. */
+ outb(0, ioaddr); /* Command length MSB. */
+ outb(LAP_INIT, ioaddr); /* Send LAP_INIT command byte. */
+ outb(nodeid, ioaddr); /* LAP address hint. */
+ outb(0xFF, ioaddr); /* Interrupt level to use (NONE). */
+ }
+
+ lp->node_acquire=0; /* Set nodeid holder to 0. */
+ while(lp->node_acquire==0) /* Get *True* nodeid finally. */
+ {
+ outb(0, ioaddr+COPS_CLEAR_INT); /* Clear any interrupt. */
+
+ if(lp->board == DAYNA)
+ {
+ if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST)
+ cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */
+ }
+ if(lp->board == TANGENT)
+ {
+ if(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY)
+ cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */
+ }
+ schedule();
+ }
+
+ if(cops_debug > 1)
+ printk(KERN_DEBUG "%s: Node ID %d has been acquired.\n", dev->name, lp->node_acquire);
+
+ lp->nodeid=1; /* Set got nodeid to 1. */


+
+ return 0;
+}
+

+/*
+ * The typical workload of the driver:
+ * Handle the network interface interrupts.
+ */
+static void cops_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+ struct device *dev = (struct device *) irq2dev_map[irq];
+ struct cops_local *lp;
+ int ioaddr, status;
+ int boguscount = 0;
+
+ if (dev == NULL)
+ {
+ printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq);
+ return;
+ }
+ dev->interrupt = 1;
+
+ ioaddr = dev->base_addr;
+ lp = (struct cops_local *)dev->priv;
+
+ do
+ {
+ /* Clear any interrupt. */
+ outb(0, ioaddr + COPS_CLEAR_INT);
+
+ if(lp->board==DAYNA)
+ {
+ status=inb(ioaddr+DAYNA_CARD_STATUS);
+ if((status&0x03)==DAYNA_RX_REQUEST)
+ cops_rx(dev);
+ }
+ else
+ {
+ status=inb(ioaddr+TANG_CARD_STATUS);
+ if (status&TANG_RX_READY)
+ cops_rx(dev);
+ }
+
+ dev->tbusy = 0;
+ mark_bh(NET_BH);
+ } while (++boguscount < 20 );
+ dev->interrupt = 0;
+
+ return;
+}
+
+/*
+ * We have a good packet(s), get it/them out of the buffers.
+ */
+static void cops_rx(struct device *dev)
+{
+ int pkt_len = 0;
+ int rsp_type = 0;
+ struct sk_buff *skb;
+ struct cops_local *lp = (struct cops_local *)dev->priv;
+ int ioaddr = dev->base_addr;
+ int boguscount = 0;
+
+ cli(); /* Disable interrupts. */
+
+ if(lp->board==DAYNA)
+ {
+ outb(0, ioaddr); /* Send out Zero length. */
+ outb(0, ioaddr);
+ outb(DATA_READ, ioaddr); /* Send read command out. */
+
+ /* Wait for DMA to turn around. */
+ while(++boguscount<1000000)
+ {
+ if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_READY)
+ break;
+ }
+
+ if(boguscount==1000000)
+ {
+ printk(KERN_WARNING "%s: DMA timed out.\n",dev->name);
+ return;
+ }
+ }
+
+ /* Get response length. */
+ pkt_len = inb(ioaddr) & 0xFF;
+ pkt_len |= (inb(ioaddr) << 8);
+ /* Input IO code. */
+ rsp_type=inb(ioaddr);
+
+ /* Malloc up new buffer. */
+ skb = dev_alloc_skb(pkt_len);
+ if (skb == NULL)
+ {
+ printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
+ lp->stats.rx_dropped++;
+ while(pkt_len--) /* Discard packet */
+ inb(ioaddr);
+ return;
+ }
+ skb->dev = dev;
+ skb_put(skb, pkt_len);
+ skb->protocol = htons(ETH_P_LOCALTALK);
+
+ insb(ioaddr, skb->data, pkt_len); /* Eat the Data */
+
+ if(lp->board==DAYNA)
+ outb(1, ioaddr+DAYNA_INT_CARD); /* Interrupt the card. */
+
+ sti(); /* Restore interrupts. */
+
+ /* Check for bad response length */
+ if (pkt_len < 0 || pkt_len > MAX_LLAP_SIZE)
+ {
+ printk(KERN_NOTICE "%s: Bad packet length of %d bytes.\n", dev->name, pkt_len);
+ lp->stats.tx_errors++;
+ kfree_skb(skb, FREE_READ);
+ return;
+ }
+
+ /* Set nodeid and then get out. */
+ if(rsp_type == LAP_INIT_RSP)
+ {
+ lp->node_acquire = skb->data[0]; /* Nodeid taken from received packet. */
+ kfree_skb(skb, FREE_READ);
+ return;
+ }
+
+ /* One last check to make sure we have a good packet. */
+ if(rsp_type != LAP_RESPONSE)
+ {
+ printk("%s: Bad packet type %d.\n", dev->name, rsp_type);
+ lp->stats.tx_errors++;
+ kfree_skb(skb, FREE_READ);
+ return;
+ }
+
+ skb->mac.raw = skb->data; /* Point to entire packet. */
+ skb_pull(skb,3);
+ skb->h.raw = skb->data; /* Point to just the data (Skip header). */
+
+ /* Update the counters. */
+ lp->stats.rx_packets++;
+ lp->stats.rx_bytes += skb->len;
+
+ /* Send packet to a higher place. */
+ netif_rx(skb);
+
+ return;
+}
+
+/*
+ * Make the card transmit a LocalTalk packet.
+ */
+static int cops_send_packet(struct sk_buff *skb, struct device *dev)
+{
+ struct cops_local *lp = (struct cops_local *)dev->priv;
+ int ioaddr = dev->base_addr;
+
+ if (dev->tbusy)
+ {
+ /*
+ * If we get here, some higher level has decided we are broken.
+ * There should really be a "kick me" function call instead.
+ */
+ int tickssofar = jiffies - dev->trans_start;
+ if (tickssofar < 5)
+ return 1;
+ lp->stats.tx_errors++;
+ if(lp->board==TANGENT)
+ {
+ if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
+ printk(KERN_WARNING "%s: No TX complete interrupt.\n", dev->name);
+ }
+ printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name);
+ cops_jumpstart(dev); /* Restart the card. */
+ dev->tbusy=0;
+ dev->trans_start = jiffies;
+ }
+
+ /*
+ * Block a timer-based transmit from overlapping. This could better be
+ * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
+ */
+ if (test_and_set_bit(0, (void*) &dev->tbusy) != 0)
+ printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
+ else
+ {
+ cli(); /* Disable interrupts. */
+ if(lp->board == DAYNA) /* Wait for adapter transmit buffer. */
+ while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0);
+ if(lp->board == TANGENT) /* Wait for adapter transmit buffer. */
+ while((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0);
+
+ /* Output IO length. */
+ if(lp->board == DAYNA)
+ {
+ outb(skb->len, ioaddr);
+ outb(skb->len >> 8, ioaddr);
+ }
+ else
+ {
+ outb(skb->len&0x0FF, ioaddr);
+ outb((skb->len >> 8)&0x0FF, ioaddr);
+ }
+
+ /* Output IO code. */
+ outb(LAP_WRITE, ioaddr);
+
+ if(lp->board == DAYNA) /* Check the transmit buffer again. */
+ while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0);
+
+ outsb(ioaddr, skb->data, skb->len); /* Send out the data. */
+
+ if(lp->board==DAYNA) /* The Dayna requires you kick the card. */
+ outb(1, ioaddr+DAYNA_INT_CARD);
+
+ sti(); /* Restore interrupts. */
+
+ /* Done sending packet, update counters and cleanup. */
+ lp->stats.tx_packets++;
+ lp->stats.tx_bytes += skb->len;
+ dev->trans_start = jiffies;
+ }
+
+ dev_kfree_skb (skb, FREE_WRITE);
+ dev->tbusy = 0;


+
+ return 0;
+}
+

+/*
+ * Dummy function to keep the Appletalk layer happy.
+ */
+
+static void set_multicast_list(struct device *dev)
+{
+ if(cops_debug >= 3)
+ printk("%s: set_mulicast_list executed. NeatO.\n", dev->name);
+}
+
+/*
+ * Another Dummy function to keep the Appletalk layer happy.
+ */
+
+static int cops_hard_header(struct sk_buff *skb, struct device *dev,
+ unsigned short type, void *daddr, void *saddr, unsigned len)
+{
+ if(cops_debug >= 3)
+ printk("%s: cops_hard_header executed. Wow!\n", dev->name);


+ return 0;
+}
+

+/*
+ * System ioctls for the COPS LocalTalk card.
+ */
+
+static int cops_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
+{
+ struct cops_local *lp = (struct cops_local *)dev->priv;
+ struct sockaddr_at *sa=(struct sockaddr_at *)&ifr->ifr_addr;
+ struct at_addr *aa=(struct at_addr *)&dev->pa_addr;
+
+ switch(cmd)
+ {
+ case SIOCSIFADDR:
+ /* Get and set the nodeid and network # atalkd wants. */
+ cops_nodeid(dev, sa->sat_addr.s_node);
+ aa->s_net = sa->sat_addr.s_net;
+ aa->s_node = lp->node_acquire;
+
+ /* Set broardcast address. */
+ dev->broadcast[0] = 0xFF;
+
+ /* Set hardware address. */
+ dev->dev_addr[0] = aa->s_node;
+ dev->addr_len = 1;
+ return 0;
+
+ case SIOCGIFADDR:
+ sa->sat_addr.s_net = aa->s_net;
+ sa->sat_addr.s_node = aa->s_node;
+ return 0;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+/*
+ * The inverse routine to cops_open().
+ */
+
+static int cops_close(struct device *dev)
+{
+ dev->tbusy = 1;
+ dev->start = 0;
+ irq2dev_map[dev->irq] = 0;
+
+#ifdef MODULE
+ MOD_DEC_USE_COUNT;
+#endif


+
+ return 0;
+}
+

+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct enet_statistics *cops_get_stats(struct device *dev)
+{
+ struct cops_local *lp = (struct cops_local *)dev->priv;
+ return &lp->stats;
+}
+
+#ifdef MODULE
+static struct device dev_cops =
+{
+ "lt0", /* device name */
+ 0, 0, 0, 0,
+ 0x0, 0, /* I/O address, IRQ */
+ 0, 0, 0, NULL, cops_probe
+};
+
+
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(board_type, "i");
+
+int init_module(void)
+{
+ int result;
+
+ if (io == 0)
+ printk(KERN_WARNING "%s: You shouldn't use auto-probing with insmod!\n", cardname);
+
+ /* Copy the parameters from insmod into the device structure. */
+ dev_cops.base_addr = io;
+ dev_cops.irq = irq;
+
+ if ((result = register_netdev(&dev_cops)) != 0)
+ return result;


+
+ return 0;
+}
+

+void cleanup_module(void)
+{
+ /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+
+ free_irq(dev_cops.irq, NULL);
+ release_region(dev_cops.base_addr, COPS_IO_EXTENT);
+ unregister_netdev(&dev_cops);
+
+ if (dev_cops.priv)
+ kfree_s(dev_cops.priv, sizeof(struct cops_local));
+}
+#endif /* MODULE */
diff -u --recursive --new-file v2.1.43/linux/drivers/net/cops.h linux/drivers/net/cops.h
--- v2.1.43/linux/drivers/net/cops.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/cops.h Thu Jun 26 12:33:39 1997
@@ -0,0 +1,60 @@
+/* cops.h: LocalTalk driver for Linux.
+ *
+ * Authors:
+ * - Jay Schulist <Jay.Sc...@spacs.k12.wi.us>
+ */
+
+#ifndef __LINUX_COPSLTALK_H
+#define __LINUX_COPSLTALK_H
+
+#ifdef __KERNEL__
+
+/* Max LLAP size we will accept. */
+#define MAX_LLAP_SIZE 603
+
+/* Tangent */
+#define TANG_CARD_STATUS 1
+#define TANG_CLEAR_INT 1
+#define TANG_RESET 3
+
+#define TANG_TX_READY 1
+#define TANG_RX_READY 2
+
+/* Dayna */
+#define DAYNA_CMD_DATA 0
+#define DAYNA_CLEAR_INT 1
+#define DAYNA_CARD_STATUS 2
+#define DAYNA_INT_CARD 3
+#define DAYNA_RESET 4
+
+#define DAYNA_RX_READY 0
+#define DAYNA_TX_READY 1
+#define DAYNA_RX_REQUEST 3
+
+/* Same on both card types */
+#define COPS_CLEAR_INT 1
+
+/* LAP response codes recieved from the cards. */
+#define LAP_INIT 1 /* Init cmd */
+#define LAP_INIT_RSP 2 /* Init response */
+#define LAP_WRITE 3 /* Write cmd */
+#define DATA_READ 4 /* Data read */
+#define LAP_RESPONSE 4 /* Received ALAP frame response */
+#define LAP_GETSTAT 5 /* Get LAP and HW status */
+#define LAP_RSPSTAT 6 /* Status response */
+
+#endif
+
+/*
+ * Structure to hold the firmware information.
+ */
+struct ltfirmware
+{
+ unsigned int length;
+ unsigned char * data;
+};
+
+#define DAYNA 1
+#define TANGENT 2
+
+#endif
diff -u --recursive --new-file v2.1.43/linux/drivers/net/cops_ffdrv.h linux/drivers/net/cops_ffdrv.h
--- v2.1.43/linux/drivers/net/cops_ffdrv.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/cops_ffdrv.h Mon Jul 7 08:19:59 1997
@@ -0,0 +1,533 @@
+
+/*
+ * The firmware this driver downloads into the Localtalk card is a
+ * seperate program and is not GPL'd source code, even though the Linux
+ * side driver and the routine that loads this data into the card are.
+ *
+ * It is taken from the COPS SDK and is under the following license
+ *
+ * This material is licensed to you strictly for use in conjunction with
+ * the use of COPS LocalTalk adapters.
+ * There is no charge for this SDK. And no waranty express or implied
+ * about its fitness for any purpose. However, we will cheerefully
+ * refund every penny you paid for this SDK...
+ * Regards,
+ *
+ * Thomas F. Divine
+ * Chief Scientist
+ */
+
+
+/* cops_ffdrv.h: LocalTalk driver firmware dump for Linux.
+ *
+ * Authors:
+ * - Jay Schulist <Jay.Sc...@spacs.k12.wi.us>
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_COPS_DAYNA
+
+unsigned char ffdrv_code[] = {
+ 58,3,0,50,228,149,33,255,255,34,226,149,
+ 249,17,40,152,33,202,154,183,237,82,77,68,
+ 11,107,98,19,54,0,237,176,175,50,80,0,
+ 62,128,237,71,62,32,237,57,51,62,12,237,
+ 57,50,237,57,54,62,6,237,57,52,62,12,
+ 237,57,49,33,107,137,34,32,128,33,83,130,
+ 34,40,128,33,86,130,34,42,128,33,112,130,
+ 34,36,128,33,211,130,34,38,128,62,0,237,
+ 57,16,33,63,148,34,34,128,237,94,205,15,
+ 130,251,205,168,145,24,141,67,111,112,121,114,
+ 105,103,104,116,32,40,67,41,32,49,57,56,
+ 56,32,45,32,68,97,121,110,97,32,67,111,
+ 109,109,117,110,105,99,97,116,105,111,110,115,
+ 32,32,32,65,108,108,32,114,105,103,104,116,
+ 115,32,114,101,115,101,114,118,101,100,46,32,
+ 32,40,68,40,68,7,16,8,34,7,22,6,
+ 16,5,12,4,8,3,6,140,0,16,39,128,
+ 0,4,96,10,224,6,0,7,126,2,64,11,
+ 118,12,6,13,0,14,193,15,0,5,96,3,
+ 192,1,64,9,8,62,9,211,66,62,192,211,
+ 66,62,100,61,32,253,6,28,33,205,129,14,
+ 66,237,163,194,253,129,6,28,33,205,129,14,
+ 64,237,163,194,9,130,201,62,47,50,71,152,
+ 62,47,211,68,58,203,129,237,57,20,58,204,
+ 129,237,57,21,33,77,152,54,132,205,233,129,
+ 58,228,149,254,209,40,6,56,4,62,0,24,
+ 2,219,96,33,233,149,119,230,62,33,232,149,
+ 119,213,33,8,152,17,7,0,25,119,19,25,
+ 119,209,201,251,237,77,245,197,213,229,221,229,
+ 205,233,129,62,1,50,106,137,205,158,139,221,
+ 225,225,209,193,241,251,237,77,245,197,213,219,
+ 72,237,56,16,230,46,237,57,16,237,56,12,
+ 58,72,152,183,32,26,6,20,17,128,2,237,
+ 56,46,187,32,35,237,56,47,186,32,29,219,
+ 72,230,1,32,3,5,32,232,175,50,72,152,
+ 229,221,229,62,1,50,106,137,205,158,139,221,
+ 225,225,24,25,62,1,50,72,152,58,201,129,
+ 237,57,12,58,202,129,237,57,13,237,56,16,
+ 246,17,237,57,16,209,193,241,251,237,77,245,
+ 197,229,213,221,229,237,56,16,230,17,237,57,
+ 16,237,56,20,58,34,152,246,16,246,8,211,
+ 68,62,6,61,32,253,58,34,152,246,8,211,
+ 68,58,203,129,237,57,20,58,204,129,237,57,
+ 21,237,56,16,246,34,237,57,16,221,225,209,
+ 225,193,241,251,237,77,33,2,0,57,126,230,
+ 3,237,100,1,40,2,246,128,230,130,245,62,
+ 5,211,64,241,211,64,201,229,213,243,237,56,
+ 16,230,46,237,57,16,237,56,12,251,70,35,
+ 35,126,254,175,202,77,133,254,129,202,15,133,
+ 230,128,194,191,132,43,58,44,152,119,33,76,
+ 152,119,35,62,132,119,120,254,255,40,4,58,
+ 49,152,119,219,72,43,43,112,17,3,0,237,
+ 56,52,230,248,237,57,52,219,72,230,1,194,
+ 141,131,209,225,237,56,52,246,6,237,57,52,
+ 62,1,55,251,201,62,3,211,66,62,192,211,
+ 66,62,48,211,66,0,0,219,66,230,1,40,
+ 4,219,67,24,240,205,203,135,58,75,152,254,
+ 255,202,128,132,58,49,152,254,161,250,207,131,
+ 58,34,152,211,68,62,10,211,66,62,128,211,
+ 66,62,11,211,66,62,6,211,66,24,0,62,
+ 14,211,66,62,33,211,66,62,1,211,66,62,
+ 64,211,66,62,3,211,66,62,209,211,66,62,
+ 100,71,219,66,230,1,32,6,5,32,247,195,
+ 248,132,219,67,71,58,44,152,184,194,248,132,
+ 62,100,71,219,66,230,1,32,6,5,32,247,
+ 195,248,132,219,67,62,100,71,219,66,230,1,
+ 32,6,5,32,247,195,248,132,219,67,254,133,
+ 32,7,62,0,50,74,152,24,17,254,173,32,
+ 7,62,1,50,74,152,24,6,254,141,194,248,
+ 132,71,209,225,58,49,152,254,132,32,10,62,
+ 50,205,2,134,205,144,135,24,27,254,140,32,
+ 15,62,110,205,2,134,62,141,184,32,5,205,
+ 144,135,24,8,62,10,205,2,134,205,8,134,
+ 62,1,50,106,137,205,158,139,237,56,52,246,
+ 6,237,57,52,175,183,251,201,62,20,135,237,
+ 57,20,175,237,57,21,237,56,16,246,2,237,
+ 57,16,237,56,20,95,237,56,21,123,254,10,
+ 48,244,237,56,16,230,17,237,57,16,209,225,
+ 205,144,135,62,1,50,106,137,205,158,139,237,
+ 56,52,246,6,237,57,52,175,183,251,201,209,
+ 225,243,219,72,230,1,40,13,62,10,211,66,
+ 0,0,219,66,230,192,202,226,132,237,56,52,
+ 246,6,237,57,52,62,1,55,251,201,205,203,
+ 135,62,1,50,106,137,205,158,139,237,56,52,
+ 246,6,237,57,52,183,251,201,209,225,62,1,
+ 50,106,137,205,158,139,237,56,52,246,6,237,
+ 57,52,62,2,55,251,201,209,225,243,219,72,
+ 230,1,202,213,132,62,10,211,66,0,0,219,
+ 66,230,192,194,213,132,229,62,1,50,106,137,
+ 42,40,152,205,65,143,225,17,3,0,205,111,
+ 136,62,6,211,66,58,44,152,211,66,237,56,
+ 52,246,6,237,57,52,183,251,201,209,197,237,
+ 56,52,230,248,237,57,52,219,72,230,1,32,
+ 15,193,225,237,56,52,246,6,237,57,52,62,
+ 1,55,251,201,14,23,58,37,152,254,0,40,
+ 14,14,2,254,1,32,5,62,140,119,24,3,
+ 62,132,119,43,43,197,205,203,135,193,62,1,
+ 211,66,62,64,211,66,62,3,211,66,62,193,
+ 211,66,62,100,203,39,71,219,66,230,1,32,
+ 6,5,32,247,195,229,133,33,238,151,219,67,
+ 71,58,44,152,184,194,229,133,119,62,100,71,
+ 219,66,230,1,32,6,5,32,247,195,229,133,
+ 219,67,35,119,13,32,234,193,225,62,1,50,
+ 106,137,205,158,139,237,56,52,246,6,237,57,
+ 52,175,183,251,201,33,234,151,35,35,62,255,
+ 119,193,225,62,1,50,106,137,205,158,139,237,
+ 56,52,246,6,237,57,52,175,251,201,243,61,
+ 32,253,251,201,62,3,211,66,62,192,211,66,
+ 58,49,152,254,140,32,19,197,229,213,17,181,
+ 129,33,185,129,1,2,0,237,176,209,225,193,
+ 24,27,229,213,33,187,129,58,49,152,230,15,
+ 87,30,2,237,92,25,17,181,129,126,18,19,
+ 35,126,18,209,225,58,34,152,246,8,211,68,
+ 58,49,152,254,165,40,14,254,164,40,10,62,
+ 10,211,66,62,224,211,66,24,25,58,74,152,
+ 254,0,40,10,62,10,211,66,62,160,211,66,
+ 24,8,62,10,211,66,62,128,211,66,62,11,
+ 211,66,62,6,211,66,205,147,143,62,5,211,
+ 66,62,224,211,66,62,5,211,66,62,96,211,
+ 66,62,5,61,32,253,62,5,211,66,62,224,
+ 211,66,62,14,61,32,253,62,5,211,66,62,
+ 233,211,66,62,128,211,66,58,181,129,61,32,
+ 253,62,1,211,66,62,192,211,66,1,254,19,
+ 237,56,46,187,32,6,13,32,247,195,226,134,
+ 62,192,211,66,0,0,219,66,203,119,40,250,
+ 219,66,203,87,40,250,243,237,56,16,230,17,
+ 237,57,16,237,56,20,251,62,5,211,66,62,
+ 224,211,66,58,182,129,61,32,253,229,33,181,
+ 129,58,183,129,203,63,119,35,58,184,129,119,
+ 225,62,10,211,66,62,224,211,66,62,11,211,
+ 66,62,118,211,66,62,47,211,68,62,5,211,
+ 66,62,233,211,66,58,181,129,61,32,253,62,
+ 5,211,66,62,224,211,66,58,182,129,61,32,
+ 253,62,5,211,66,62,96,211,66,201,229,213,
+ 58,50,152,230,15,87,30,2,237,92,33,187,
+ 129,25,17,181,129,126,18,35,19,126,18,209,
+ 225,58,71,152,246,8,211,68,58,50,152,254,


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 27'
echo 'File patch-2.1.44 is continued in part 28'
echo 28 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part30

#!/bin/sh
# this is part 30 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 30; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

+++ linux/fs/autofs/inode.c Mon Jul 7 11:10:13 1997
@@ -163,7 +163,8 @@
X s->s_magic = AUTOFS_SUPER_MAGIC;
X s->s_op = &autofs_sops;
X unlock_super(s);
- if (!(s->s_mounted = iget(s, AUTOFS_ROOT_INO))) {
+ s->s_root = d_alloc_root(iget(s, AUTOFS_ROOT_INO), NULL);
+ if (!s->s_root) {
X s->s_dev = 0;
X kfree(sbi);
X printk("autofs: get root inode failed\n");
@@ -171,8 +172,8 @@
X return NULL;
X }
X
- if ( parse_options(data,&pipefd,&s->s_mounted->i_uid,&s->s_mounted->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) {
- iput(s->s_mounted);
+ if ( parse_options(data,&pipefd,&s->s_root->d_inode->i_uid,&s->s_root->d_inode->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) {
+ d_delete(s->s_root);
X s->s_dev = 0;
X kfree(sbi);
X printk("autofs: called with bogus options\n");


@@ -181,7 +182,7 @@
X }

X
X if ( minproto > AUTOFS_PROTO_VERSION || maxproto < AUTOFS_PROTO_VERSION ) {
- iput(s->s_mounted);
+ d_delete(s->s_root);
X s->s_dev = 0;
X kfree(sbi);
X printk("autofs: kernel does not match daemon version\n");
@@ -198,7 +199,7 @@
X } else {
X printk("autofs: could not open pipe file descriptor\n");
X }
- iput(s->s_mounted);
+ d_delete(s->s_root);
X s->s_dev = 0;
X kfree(sbi);
X MOD_DEC_USE_COUNT;
@@ -244,8 +245,8 @@
X return;
X }
X
- inode->i_uid = inode->i_sb->s_mounted->i_uid;
- inode->i_gid = inode->i_sb->s_mounted->i_gid;
+ inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
+ inode->i_gid = inode->i_sb->s_root->d_inode->i_gid;
X
X if ( ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO ) {
X /* Symlink inode - should be in symlink list */
diff -u --recursive --new-file v2.1.43/linux/fs/autofs/root.c linux/fs/autofs/root.c
--- v2.1.43/linux/fs/autofs/root.c Mon Jun 16 16:35:57 1997
+++ linux/fs/autofs/root.c Mon Jul 7 13:55:00 1997
@@ -16,11 +16,11 @@
X #include "autofs_i.h"
X
X static int autofs_root_readdir(struct inode *,struct file *,void *,filldir_t);
-static int autofs_root_lookup(struct inode *,const char *,int,struct inode **);
-static int autofs_root_symlink(struct inode *,const char *,int,const char *);
-static int autofs_root_unlink(struct inode *,const char *,int);
-static int autofs_root_rmdir(struct inode *,const char *,int);
-static int autofs_root_mkdir(struct inode *,const char *,int,int);
+static int autofs_root_lookup(struct inode *,struct qstr *,struct inode **);
+static int autofs_root_symlink(struct inode *,struct dentry *,const char *);
+static int autofs_root_unlink(struct inode *,struct dentry *);
+static int autofs_root_rmdir(struct inode *,struct dentry *);
+static int autofs_root_mkdir(struct inode *,struct dentry *,int);
X static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long);
X
X static struct file_operations autofs_root_operations = {
@@ -48,6 +48,7 @@
X NULL, /* mknod */
X NULL, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */
X NULL, /* bmap */
@@ -92,95 +93,70 @@


X return 0;
X }
X

-static int autofs_root_lookup(struct inode *dir, const char *name, int len,
- struct inode **result)
+static int autofs_root_lookup(struct inode *dir, struct qstr *str, struct inode **result)
X {
X struct autofs_sb_info *sbi;
X struct autofs_dir_ent *ent;
X struct inode *res;
- autofs_hash_t hash;
X int status, oz_mode;
X
X DPRINTK(("autofs_root_lookup: name = "));
- autofs_say(name,len);
+ autofs_say(str->name,str->len);
X
X *result = NULL;
X if (!dir)
X return -ENOENT;
- if (!S_ISDIR(dir->i_mode)) {
- iput(dir);
+ if (!S_ISDIR(dir->i_mode))
X return -ENOTDIR;
- }
-
- /* Handle special cases: . and ..; since this is a root directory,
- they both point to the inode itself */
- *result = dir;
- if (!len)
- return 0;
- if (name[0] == '.') {
- if (len == 1)
- return 0;
- if (name[1] == '.' && len == 2)
- return 0;
- }
X
X *result = res = NULL;
X sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
X
- hash = autofs_hash(name,len);
-
X oz_mode = autofs_oz_mode(sbi);
X DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d\n", current->pid, current->pgrp, sbi->catatonic, oz_mode));
X
X do {
- while ( !(ent = autofs_hash_lookup(&sbi->dirhash,hash,name,len)) ) {
+ while ( !(ent = autofs_hash_lookup(&sbi->dirhash,str)) ) {
X DPRINTK(("lookup failed, pid = %u, pgrp = %u\n", current->pid, current->pgrp));
X
- if ( oz_mode ) {
- iput(dir);
+ if ( oz_mode )
X return -ENOENT;
- } else {
- status = autofs_wait(sbi,hash,name,len);
- DPRINTK(("autofs_wait returned %d\n", status));
- if ( status ) {
- iput(dir);
- return status;
- }
- }
+ up(&dir->i_sem);
+ status = autofs_wait(sbi,str);
+ down(&dir->i_sem);
+ DPRINTK(("autofs_wait returned %d\n", status));
+ if ( status )
+ return status;
X }
X
X DPRINTK(("lookup successful, inode = %08x\n", (unsigned int)ent->ino));
X
X if (!(res = iget(dir->i_sb,ent->ino))) {
X printk("autofs: iget returned null!\n");
- iput(dir);
X return -EACCES;
X }
X
X if ( !oz_mode && S_ISDIR(res->i_mode) && res->i_sb == dir->i_sb ) {
X /* Not a mount point yet, call 1-800-DAEMON */
X DPRINTK(("autofs: waiting on non-mountpoint dir, inode = %lu, pid = %u, pgrp = %u\n", res->i_ino, current->pid, current->pgrp));
- iput(res);
X res = NULL;
- status = autofs_wait(sbi,hash,name,len);
- if ( status ) {
- iput(dir);
+ up(&dir->i_sem);
+ status = autofs_wait(sbi,str);
+ down(&dir->i_sem);
+ if ( status )
X return status;
- }
X }
X } while(!res);
X autofs_update_usage(&sbi->dirhash,ent);
X
X *result = res;
- iput(dir);


X return 0;
X }
X

-static int autofs_root_symlink(struct inode *dir, const char *name, int len, const char *symname)
+static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
X {
X struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
X struct autofs_dirhash *dh = &sbi->dirhash;
- autofs_hash_t hash = autofs_hash(name,len);
X struct autofs_dir_ent *ent;
X unsigned int n;
X int slsize;
@@ -189,70 +165,64 @@
X DPRINTK(("autofs_root_symlink: %s <- ", symname));
X autofs_say(name,len);
X
- if ( !autofs_oz_mode(sbi) ) {
- iput(dir);
+ if ( !autofs_oz_mode(sbi) )
X return -EPERM;
- }
- if ( autofs_hash_lookup(dh,hash,name,len) ) {
- iput(dir);
+
+ if ( autofs_hash_lookup(dh, &dentry->d_name) )
X return -EEXIST;
- }
+
X n = find_first_zero_bit(sbi->symlink_bitmap,AUTOFS_MAX_SYMLINKS);
- if ( n >= AUTOFS_MAX_SYMLINKS ) {
- iput(dir);
+ if ( n >= AUTOFS_MAX_SYMLINKS )
X return -ENOSPC;
- }
+
X set_bit(n,sbi->symlink_bitmap);
X sl = &sbi->symlink[n];
X sl->len = strlen(symname);
X sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL);
X if ( !sl->data ) {
X clear_bit(n,sbi->symlink_bitmap);
- iput(dir);
X return -ENOSPC;
X }
+
X ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
X if ( !ent ) {
X kfree(sl->data);
X clear_bit(n,sbi->symlink_bitmap);
- iput(dir);
X return -ENOSPC;
X }
- ent->name = kmalloc(len, GFP_KERNEL);
+
+ ent->name = kmalloc(dentry->d_name.len, GFP_KERNEL);
X if ( !ent->name ) {
X kfree(sl->data);
X kfree(ent);
X clear_bit(n,sbi->symlink_bitmap);
- iput(dir);
X return -ENOSPC;
X }
+
X memcpy(sl->data,symname,slsize);
X sl->mtime = CURRENT_TIME;
X
X ent->ino = AUTOFS_FIRST_SYMLINK + n;
- ent->hash = hash;
- memcpy(ent->name,name,ent->len = len);
+ ent->hash = dentry->d_name.hash;
+ memcpy(ent->name, dentry->d_name.name,ent->len = dentry->d_name.len);
X
X autofs_hash_insert(dh,ent);
- iput(dir);
+ d_instantiate(dentry, iget(dir->i_sb,ent->ino), 0);
X

X return 0;
X }
X

-static int autofs_root_unlink(struct inode *dir, const char *name, int len)
+static int autofs_root_unlink(struct inode *dir, struct dentry *dentry)
X {
X struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
X struct autofs_dirhash *dh = &sbi->dirhash;
- autofs_hash_t hash = autofs_hash(name,len);
X struct autofs_dir_ent *ent;
X unsigned int n;
X
- iput(dir); /* Nothing below can sleep */
-
X if ( !autofs_oz_mode(sbi) )
X return -EPERM;
X
- ent = autofs_hash_lookup(dh,hash,name,len);
+ ent = autofs_hash_lookup(dh, &dentry->d_name);
X if ( !ent )
X return -ENOENT;
X
@@ -263,75 +233,68 @@
X autofs_hash_delete(ent);
X clear_bit(n,sbi->symlink_bitmap);
X kfree(sbi->symlink[n].data);
+ d_delete(dentry);
X

X return 0;
X }
X

-static int autofs_root_rmdir(struct inode *dir, const char *name, int len)
+static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry)
X {
X struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
X struct autofs_dirhash *dh = &sbi->dirhash;
- autofs_hash_t hash = autofs_hash(name,len);
X struct autofs_dir_ent *ent;
X
- if ( !autofs_oz_mode(sbi) ) {
- iput(dir);
+ if ( !autofs_oz_mode(sbi) )
X return -EPERM;
- }
- ent = autofs_hash_lookup(dh,hash,name,len);
- if ( !ent ) {
- iput(dir);
+
+ ent = autofs_hash_lookup(dh, &dentry->d_name);
+ if ( !ent )
X return -ENOENT;
- }
- if ( (unsigned int)ent->ino < AUTOFS_FIRST_DIR_INO ) {
- iput(dir);
+
+ if ( (unsigned int)ent->ino < AUTOFS_FIRST_DIR_INO )
X return -ENOTDIR; /* Not a directory */
- }
+
X autofs_hash_delete(ent);
X dir->i_nlink--;
- iput(dir);
+ d_delete(dentry);
X

X return 0;
X }
X

-static int autofs_root_mkdir(struct inode *dir, const char *name, int len, int mode)
+static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
X {
X struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
X struct autofs_dirhash *dh = &sbi->dirhash;
- autofs_hash_t hash = autofs_hash(name,len);
X struct autofs_dir_ent *ent;
X
- if ( !autofs_oz_mode(sbi) ) {
- iput(dir);
+ if ( !autofs_oz_mode(sbi) )
X return -EPERM;
- }
- ent = autofs_hash_lookup(dh,hash,name,len);
- if ( ent ) {
- iput(dir);
+
+ ent = autofs_hash_lookup(dh, &dentry->d_name);
+ if ( ent )
X return -EEXIST;
- }
+
X if ( sbi->next_dir_ino < AUTOFS_FIRST_DIR_INO ) {
X printk("autofs: Out of inode numbers -- what the heck did you do??\n");
- iput(dir);
X return -ENOSPC;
X }
+
X ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
- if ( !ent ) {
- iput(dir);
+ if ( !ent )
X return -ENOSPC;
- }
- ent->name = kmalloc(len, GFP_KERNEL);
+
+ ent->name = kmalloc(dentry->d_name.len, GFP_KERNEL);
X if ( !ent->name ) {
X kfree(ent);
- iput(dir);
X return -ENOSPC;
X }
- ent->hash = hash;
- memcpy(ent->name, name, ent->len = len);
+
+ ent->hash = dentry->d_name.hash;
+ memcpy(ent->name, dentry->d_name.name, ent->len = dentry->d_name.len);
X ent->ino = sbi->next_dir_ino++;
X autofs_hash_insert(dh,ent);
X dir->i_nlink++;
- iput(dir);
+ d_instantiate(dentry, iget(dir->i_sb,ent->ino), D_DIR);
X
X return 0;
X }
diff -u --recursive --new-file v2.1.43/linux/fs/autofs/symlink.c linux/fs/autofs/symlink.c
--- v2.1.43/linux/fs/autofs/symlink.c Mon Jun 16 16:35:57 1997
+++ linux/fs/autofs/symlink.c Mon Jul 7 12:58:01 1997
@@ -19,18 +19,21 @@
X struct autofs_symlink *sl;
X int len;
X
- if (!S_ISLNK(inode->i_mode)) {
- iput(inode);
- return -EINVAL;
- }
X sl = (struct autofs_symlink *)inode->u.generic_ip;
X len = sl->len;
X if (len > buflen) len = buflen;
X copy_to_user(buffer,sl->data,len);
- iput(inode);
X return len;
X }
X
+static struct dentry * autofs_follow_link(struct inode *inode, struct dentry *base)
+{
+ struct autofs_symlink *sl;
+
+ sl = (struct autofs_symlink *)inode->u.generic_ip;
+ return lookup_dentry(sl->data, base, 1);
+}
+
X struct inode_operations autofs_symlink_inode_operations = {
X NULL, /* file operations */
X NULL, /* create */
@@ -43,6 +46,7 @@
X NULL, /* mknod */
X NULL, /* rename */
X autofs_readlink, /* readlink */
+ autofs_follow_link, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */
X NULL, /* bmap */
diff -u --recursive --new-file v2.1.43/linux/fs/autofs/waitq.c linux/fs/autofs/waitq.c
--- v2.1.43/linux/fs/autofs/waitq.c Thu May 29 21:53:08 1997
+++ linux/fs/autofs/waitq.c Mon Jul 7 12:57:29 1997
@@ -90,15 +90,15 @@
X autofs_catatonic_mode(sbi);
X }
X
-int autofs_wait(struct autofs_sb_info *sbi, autofs_hash_t hash, const char *name, int len)
+int autofs_wait(struct autofs_sb_info *sbi, struct qstr * name)
X {
X struct autofs_wait_queue *wq;
X int status;
X
X for ( wq = sbi->queues ; wq ; wq = wq->next ) {
- if ( wq->hash == hash &&
- wq->len == len &&
- wq->name && !memcmp(wq->name,name,len) )
+ if ( wq->hash == name->hash &&
+ wq->len == name->len &&
+ wq->name && !memcmp(wq->name,name->name,name->len) )
X break;
X }
X
@@ -108,17 +108,17 @@
X if ( !wq )
X return -ENOMEM;
X
- wq->name = kmalloc(len,GFP_KERNEL);
+ wq->name = kmalloc(name->len,GFP_KERNEL);
X if ( !wq->name ) {
X kfree(wq);
X return -ENOMEM;
X }
X wq->wait_queue_token = autofs_next_wait_queue++;
X init_waitqueue(&wq->queue);
- wq->hash = hash;
- wq->len = len;
+ wq->hash = name->hash;
+ wq->len = name->len;
X wq->status = -EINTR; /* Status return if interrupted */
- memcpy(wq->name, name, len);
+ memcpy(wq->name, name->name, name->len);
X wq->next = sbi->queues;
X sbi->queues = wq;
X
diff -u --recursive --new-file v2.1.43/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- v2.1.43/linux/fs/binfmt_elf.c Mon Jun 16 16:35:57 1997
+++ linux/fs/binfmt_elf.c Mon Jul 7 08:18:55 1997
@@ -111,23 +111,20 @@
X {
X elf_caddr_t *argv;
X elf_caddr_t *envp;
- elf_addr_t *sp;
+ elf_addr_t *sp, *csp;
X
X /*
- * Force 16 byte alignment here for generality.
+ * Force 16 byte _final_ alignment here for generality.
X */
X sp = (elf_addr_t *) (~15UL & (unsigned long) p);
-#ifdef __sparc__
-{
- elf_addr_t *csp;
X csp = sp;
X csp -= exec ? DLINFO_ITEMS*2 : 2;
X csp -= envc+1;
X csp -= argc+1;
- if (!(((unsigned long) csp) & 4))
- sp--;
-}
-#endif
+ csp -= (!ibcs ? 3 : 1); /* argc itself */
+ if ((unsigned long)csp & 15UL) {
+ sp -= (16UL - ((unsigned long)csp & 15UL)) / sizeof(*sp);
+ }
X
X /*
X * Put the ELF interpreter info on the stack
@@ -142,17 +139,17 @@
X if (exec) {
X sp -= 11*2;
X
- NEW_AUX_ENT (0, AT_PHDR, load_addr + exec->e_phoff);
- NEW_AUX_ENT (1, AT_PHENT, sizeof (struct elf_phdr));
- NEW_AUX_ENT (2, AT_PHNUM, exec->e_phnum);
- NEW_AUX_ENT (3, AT_PAGESZ, ELF_EXEC_PAGESIZE);
- NEW_AUX_ENT (4, AT_BASE, interp_load_addr);
- NEW_AUX_ENT (5, AT_FLAGS, 0);
- NEW_AUX_ENT (6, AT_ENTRY, (elf_addr_t) exec->e_entry);
- NEW_AUX_ENT (7, AT_UID, (elf_addr_t) current->uid);
- NEW_AUX_ENT (8, AT_EUID, (elf_addr_t) current->euid);
- NEW_AUX_ENT (9, AT_GID, (elf_addr_t) current->gid);
- NEW_AUX_ENT (10, AT_EGID, (elf_addr_t) current->egid);
+ NEW_AUX_ENT (0, AT_PHDR, load_addr + exec->e_phoff);
+ NEW_AUX_ENT (1, AT_PHENT, sizeof (struct elf_phdr));
+ NEW_AUX_ENT (2, AT_PHNUM, exec->e_phnum);
+ NEW_AUX_ENT (3, AT_PAGESZ, ELF_EXEC_PAGESIZE);
+ NEW_AUX_ENT (4, AT_BASE, interp_load_addr);
+ NEW_AUX_ENT (5, AT_FLAGS, 0);
+ NEW_AUX_ENT (6, AT_ENTRY, (elf_addr_t) exec->e_entry);
+ NEW_AUX_ENT (7, AT_UID, (elf_addr_t) current->uid);
+ NEW_AUX_ENT (8, AT_EUID, (elf_addr_t) current->euid);
+ NEW_AUX_ENT (9, AT_GID, (elf_addr_t) current->gid);
+ NEW_AUX_ENT (10, AT_EGID, (elf_addr_t) current->egid);
X }
X #undef NEW_AUX_ENT
X
diff -u --recursive --new-file v2.1.43/linux/fs/binfmt_misc.c linux/fs/binfmt_misc.c
--- v2.1.43/linux/fs/binfmt_misc.c Mon Jun 16 16:35:57 1997
+++ linux/fs/binfmt_misc.c Tue Jul 1 08:55:56 1997
@@ -7,9 +7,11 @@
X * a specified wrapper. This should obsolete binfmt_java, binfmt_em86 and
X * binfmt_mz.
X *
- * 25.4.97 first version
- * [...]
- * 19.5.97 cleanup
+ * 1997-04-25 first version
+ * [...]
+ * 1997-05-19 cleanup
+ * 1997-06-26 hpa: pass the real filename rather than argv[0]
+ * 1997-06-30 minor cleanup
X */
X
X #include <linux/module.h>
@@ -85,7 +87,6 @@
X *ep = e->next;
X entry_proc_cleanup(e);
X kfree(e);
- MOD_DEC_USE_COUNT;
X }
X write_unlock(&entries_lock);
X }
@@ -102,7 +103,6 @@
X entries = entries->next;
X entry_proc_cleanup(e);
X kfree(e);
- MOD_DEC_USE_COUNT;
X }
X write_unlock(&entries_lock);
X }
@@ -161,7 +161,6 @@
X char *iname_addr = iname, *p;
X int retval, fmt_flags = 0;
X
- MOD_INC_USE_COUNT;
X if (!enabled) {
X retval = -ENOEXEC;
X goto _ret;
@@ -185,12 +184,11 @@
X
X /* Build args for interpreter */
X if ((fmt_flags & ENTRY_STRIP_EXT) &&
- (p = strrchr(bprm->filename, '.'))) {
+ (p = strrchr(bprm->filename, '.')))
X *p = '\0';
- remove_arg_zero(bprm);
- bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2);
- bprm->argc++;
- }
+ remove_arg_zero(bprm);
+ bprm->p = copy_strings(1, &bprm->filename, bprm->page, bprm->p, 2);
+ bprm->argc++;
X bprm->p = copy_strings(1, &iname_addr, bprm->page, bprm->p, 2);
X bprm->argc++;
X if (!bprm->p) {
@@ -206,7 +204,6 @@
X if ((retval = prepare_binprm(bprm)) >= 0)
X retval = search_binary_handler(bprm, regs);
X _ret:
- MOD_DEC_USE_COUNT;
X return retval;
X }
X
@@ -265,18 +262,13 @@
X struct binfmt_entry *e;
X int memsize, cnt = count - 1, err = 0;
X
- MOD_INC_USE_COUNT;
X /* some sanity checks */
- if ((count < 11) || (count > 256)) {
- err = -EINVAL;
- goto _err;
- }
+ if ((count < 11) || (count > 256))
+ return -EINVAL;
X
X memsize = sizeof(struct binfmt_entry) + count;
- if (!(e = (struct binfmt_entry *) kmalloc(memsize, GFP_USER))) {
- err = -ENOMEM;
- goto _err;
- }
+ if (!(e = (struct binfmt_entry *) kmalloc(memsize, GFP_USER)))
+ return -ENOMEM;
X
X sp = buffer + 1;
X del = buffer[0];
@@ -313,8 +305,7 @@
X !(e->proc_name) || !(e->interpreter) ||
X entry_proc_setup(e)) {
X kfree(e);
- err = -EINVAL;
- goto _err;
+ return -EINVAL;
X }
X
X write_lock(&entries_lock);
@@ -323,9 +314,6 @@
X write_unlock(&entries_lock);
X
X return count;
-_err:
- MOD_DEC_USE_COUNT;
- return err;
X }
X
X /*
@@ -340,7 +328,6 @@
X char *dp;
X int elen, i;
X
- MOD_INC_USE_COUNT;
X #ifndef VERBOSE_STATUS
X if (data) {
X read_lock(&entries_lock);
@@ -400,7 +387,6 @@
X *eof = (elen <= count) ? 1 : 0;
X *start = page + off;
X
- MOD_DEC_USE_COUNT;
X return elen;
X }
X
@@ -414,7 +400,6 @@
X struct binfmt_entry *e;
X int res = count;
X
- MOD_INC_USE_COUNT;
X if (((buffer[0] == '1') || (buffer[0] == '0')) &&
X ((count == 1) || ((count == 2) && (buffer[1] == '\n')))) {
X if (data) {
@@ -434,7 +419,6 @@
X } else {
X res = -EINVAL;
X }
- MOD_DEC_USE_COUNT;
X return res;
X }
X
@@ -499,6 +483,7 @@
X unregister_binfmt(&misc_format);
X remove_proc_entry("register", bm_dir);
X remove_proc_entry("status", bm_dir);
+ clear_entries();
X remove_proc_entry("sys/fs/binfmt_misc", NULL);
X }
X #endif
diff -u --recursive --new-file v2.1.43/linux/fs/buffer.c linux/fs/buffer.c
--- v2.1.43/linux/fs/buffer.c Mon Jun 16 16:35:57 1997
+++ linux/fs/buffer.c Tue Jul 1 20:21:42 1997
@@ -495,17 +495,18 @@
X
X static inline struct buffer_head * find_buffer(kdev_t dev, int block, int size)
X {
- struct buffer_head * tmp;
-
- for (tmp = hash(dev,block) ; tmp != NULL ; tmp = tmp->b_next)
- if (tmp->b_blocknr == block && tmp->b_dev == dev) {
- if (tmp->b_size == size)
- return tmp;
+ struct buffer_head * next;
X
- printk("VFS: Wrong blocksize on device %s\n",
- kdevname(dev));
- return NULL;
- }
+ next = hash(dev,block);
+ for (;;) {
+ struct buffer_head *tmp = next;
+ if (!next)
+ break;
+ next = tmp->b_next;
+ if (tmp->b_blocknr != block || tmp->b_size != size || tmp->b_dev != dev)
+ continue;
+ return tmp;
+ }
X return NULL;
X }
X
@@ -518,10 +519,11 @@
X */
X struct buffer_head * get_hash_table(kdev_t dev, int block, int size)
X {
- struct buffer_head * bh;
-
X for (;;) {
- if (!(bh=find_buffer(dev,block,size)))
+ struct buffer_head * bh;
+
+ bh=find_buffer(dev,block,size);
+ if (!bh)
X return NULL;
X bh->b_count++;
X wait_on_buffer(bh);
@@ -1610,6 +1612,7 @@
X next->b_count--;
X }
X }
+ run_task_queue(&tq_disk);
X #ifdef DEBUG
X if (ncount) printk("sync_old_buffers: %d dirty buffers not on dirty list\n", ncount);
X printk("Wrote %d/%d buffers\n", nwritten, ndirty);
diff -u --recursive --new-file v2.1.43/linux/fs/dcache.c linux/fs/dcache.c
--- v2.1.43/linux/fs/dcache.c Mon Jun 16 16:35:57 1997
+++ linux/fs/dcache.c Mon Jul 7 14:50:18 1997
@@ -5,136 +5,27 @@
X * (C) 1997 Thomas Schoebel-Theuer
X */
X
-/* The new dcache is exclusively called from the VFS, not from
- * the specific fs'es any more. Despite having the same name as in the
- * old code, it has less to do with it.
- *
- * It serves many purposes:
- *
- * 1) Any inode that has been retrieved with lookup() and is in use
- * (i_count>0), has access to its full absolute path name, by going
- * to inode->i_dentry and then recursively following the entry->d_parent
- * chain. Use d_path() as predefined method for that.
- * You may find out the corresponding inode belonging to
- * a dentry by calling d_inode(). This can be used as an easy way for
- * determining .. and its absolute pathname, an old UNIX problem that
- * deserved a solution for a long time.
- * Note that hardlinked inodes may have multiple dentries assigned to
- * (via the d_next chain), reflecting multiple alias pathnames.
- *
- * 2) If not disabled by filesystem types specifying FS_NO_DCACHE,
- * the dentries of unused (aged) inodes are retained for speeding up
- * lookup()s, by allowing hashed inquiry starting from the dentry of
- * the parent directory.
- *
- * 3) It can remeber so-called "negative entries", that is dentries for
- * pathnames that are known to *not* exist, so unneccessary repeated
- * lookup()s for non-existant names can be saved.
- *
- * 4) It provides a means for keeping deleted files (inode->i_nlink==0)
- * accessible in the so-called *basket*. Inodes in the basket have been
- * removed with unlink() while being in use (i_count>0), so they would
- * normally use up space on the disk and be accessile through their
- * filedescriptor, but would not be accessible for lookup() any more.
- * The basket simply keeps such files in the dcache (for potential
- * dcache lookup) until they are either eventually removed completely,
- * or transferred to the second-level basket, the so-called *ibasket*.
- * The ibasket is implemented in the new inode code, on request of
- * filesystem types that have the flag FS_IBASKET set, and proliferates
- * the unlinked files when i_count has gone to zero, at least as long
- * as there is space on the disk and enough inodes remain available
- * and no umount() has started.
- *
- * 5) Preliminary dentries can be added by readdir(). While normal dentries
- * directly point to the inode via u.d_inode only the inode number is
- * known from readdir(), but not more. They can be converted to
- * normal dentries by using d_inode().
- */
-
X /*
X * Notes on the allocation strategy:
X *
- * The dcache is a full slave cache of the inodes. Whenever an inode
- * is cleared, all the dentries associated with it will recursively
- * disappear. dentries have no own reference counting; this has to
- * be obeyed for SMP.
- * If directories could go out of inode cache while
- * successors are alive, this would interrupt the d_parent chain of
- * the live successors. To prevent this without using zombies, all
- * directories are thus prevented from __iput() as long as successors
- * are alive.
+ * The dcache is a master of the icache - whenever a dcache entry
+ * exists, the inode will always exist. "iput()" is done either when
+ * the dcache entry is deleted or garbage collected.
X */
X
-#include <linux/config.h>
X #include <linux/string.h>
X #include <linux/mm.h>
X #include <linux/fs.h>
X #include <linux/dalloc.h>
X #include <linux/dlists.h>
+#include <linux/malloc.h>
X
X /* this should be removed after the beta phase */
-/* #define DEBUG */
+/*#define DEBUG*/
X /*#undef DEBUG*/
-/* #define DEBUG_DDIR_COUNT */
-
-#define D_HASHSIZE 64
+/*#define DEBUG_DDIR_COUNT*/
X
-/* local flags for d_flag */
-#define D_DIR 32
-#define D_HASHED 64
-#define D_ZOMBIE 128
-#define D_PRELIMINARY 256
-#define D_INC_DDIR 512
-
-/* local flags for d_del() */
-#define D_RECURSIVE 4
-#define D_NO_FREE 8
-
-/* adjust these constants if you know a probability distribution ... */
-#define D_SMALL 16
-#define D_MEDIUM 64
-#define D_LARGE 256
-#define D_HUGE D_MAXLEN
-
-#define BASE_DHEADER(x) (struct dheader*)((unsigned long)(x) & ~(PAGE_SIZE-1))
-#define BYTE_ADD(x,n) (void*)((char*)(x) + (n))
-#define BYTE_SUB(x,n) (void*)((char*)(x) - (n))
-
-/* This is for global allocation of dentries. Remove this when
- * converting to SLAB.
- */
-struct dheader {
- struct dentry * emptylist;
- short free, maxfree;
- struct dheader * next;
- struct dheader * prev;
-};
-
-struct anchors {
- struct dheader * free; /* each contains at least 1 empty dentry */
- struct dheader * full; /* all the used up ones */
- struct dheader * dir_free;
- struct dheader * dir_full;
-};
-
-/* This is only used for directory dentries. Think of it as an extension
- * of the dentry.
- * It is defined as separate struct, so it uses up space only
- * where necessary.
- */
-struct ddir {
- struct dentry * dd_hashtable[D_HASHSIZE];
- struct dentry * dd_neglist;
- struct dentry * dd_basketlist;
- struct dentry * dd_zombielist;
- unsigned short dd_alloced; /* # d_alloc()ed, but not yet d_add()ed */
- unsigned short dd_hashed; /* # of entries in hashtable */
- unsigned short dd_true_hashed; /* # non-preliminaries in hashtable */
- unsigned short dd_negs; /* # of negative entries */
-};
-
-DEF_INSERT(header,struct dheader,next,prev)
-DEF_REMOVE(header,struct dheader,next,prev)
+void printpath(struct dentry * entry);
X
X DEF_INSERT(alias,struct dentry,d_next,d_prev)
X DEF_REMOVE(alias,struct dentry,d_next,d_prev)
@@ -142,16 +33,30 @@
X DEF_INSERT(hash,struct dentry,d_hash_next,d_hash_prev)
X DEF_REMOVE(hash,struct dentry,d_hash_next,d_hash_prev)
X
-DEF_INSERT(basket,struct dentry,d_basket_next,d_basket_prev)
-DEF_REMOVE(basket,struct dentry,d_basket_next,d_basket_prev)
-
-static struct anchors anchors[4];
-
X struct dentry * the_root = NULL;
X
+/*
+ * This is the single most critical data structure when it comes
+ * to the dcache: the hashtable for lookups. Somebody should try
+ * to make this good - I've just made it work.
+ *
+ * This hash-function tries to avoid losing too many bits of hash
+ * information, yet avoid using a prime hash-size or similar.
+ */
+#define D_HASHBITS 10
+#define D_HASHSIZE (1UL << D_HASHBITS)
+#define D_HASHMASK (D_HASHSIZE-1)
+struct dentry * dentry_hashtable[D_HASHSIZE];
+
+static inline unsigned long dentry_hash(struct dentry *dir, int name_hash)
+{
+ unsigned long hash = name_hash + (unsigned long) dir;
+ hash = hash ^ (hash >> D_HASHBITS) ^ (hash >> D_HASHBITS*2);
+ return hash & D_HASHMASK;
+}
+
X unsigned long name_cache_init(unsigned long mem_start, unsigned long mem_end)
X {
- memset(anchors, 0, sizeof(anchors));
X return mem_start;
X }
X
@@ -174,7 +79,7 @@
X if(cnt % 1000 == 0)
X printk("------%d allocated: %d: %d %d %d\n", inodes_stat, cnt,
X x_alloc, x_freed, x_free);
- if(cnt>=20000) panic("stop");
+ if (cnt>=20000) panic("stop");
X }
X
X #if 0
@@ -182,7 +87,7 @@
X {
X int i;
X for(i = cnt-1; i>=0; i--)
- if(tst[i] == ptr)
+ if (tst[i] == ptr)
X return i;
X return -1;
X }
@@ -195,55 +100,18 @@
X void LOG(char * txt, struct dentry * entry)
X {
X static int count = 0;
- if(entry) {
+ if (entry) {
X TST(txt,entry);
X }
- if(count) {
+ if (count) {
X count--;
X printk("%s: entry=%p\n", txt, entry);
X }
X }
X
X #ifdef DEBUG_DDIR_COUNT
-static struct ddir * d_dir(struct dentry * entry);
X void recursive_test(struct dentry * entry)
X {
- int i;
- struct ddir * ddir = d_dir(entry);
- int sons = 0;
-
- if(ddir->dd_zombielist)
- sons++;
- for(i=0; i < D_HASHSIZE; i++) {
- struct dentry ** base = &ddir->dd_hashtable[i];
- struct dentry * tmp = *base;
- if(tmp) do {
- TST("__clear",tmp);
- if(!(tmp->d_flag & D_HASHED)) {
- printk("VFS: dcache entry not hashed!\n");
- printpath(*base); printk("\n");
- printpath(tmp);
- }
- if(!(tmp->d_flag & D_PRELIMINARY))
- sons++;
- if(tmp->d_flag & D_DIR)
- recursive_test(tmp);
- tmp = tmp->d_hash_next;
- } while(tmp && tmp != *base);
- }
- if(!sons && !(entry->d_flag & D_PRELIMINARY) && entry->u.d_inode) {
- struct inode * inode = entry->u.d_inode;
- if(!atomic_read(&inode->i_count)) {
- if(!(inode->i_status & 1/*ST_AGED*/)) {
- printpath(entry);
- printk(" is not aged!\n");
- }
- if(inode->i_ddir_count) {
- printpath(entry);
- printk(" has ddir_count blockage!\n");
- }
- }
- }
X }
X #else
X #define recursive_test(e) /*nothing*/
@@ -258,782 +126,284 @@
X
X void printpath(struct dentry * entry)
X {
- if(!IS_ROOT(entry))
+ if (!IS_ROOT(entry))
X printpath(entry->d_parent);
- printk("/%s", entry->d_name);
-}
-
-static inline long has_sons(struct ddir * ddir)
-{
- return ((ddir->dd_alloced | ddir->dd_hashed) ||
- ddir->dd_neglist ||
- ddir->dd_basketlist ||
- ddir->dd_zombielist);
-}
-
-static inline int has_true_sons(struct ddir * ddir)
-{
- return (ddir->dd_alloced | ddir->dd_true_hashed);
-}
-
-/* Only hold the i_ddir_count pseudo refcount when neccessary (i.e. when
- * they have true_sons), to prevent keeping too much dir inodes in use.
- */
-static inline void inc_ddir(struct dentry * entry, struct inode * inode)
-{
- if(!(entry->d_flag & D_INC_DDIR)) {
- entry->d_flag |= D_INC_DDIR;
-#ifdef DEBUG
- if(inode->i_ddir_count) {
- printpath(entry);
- printk(" ddir_count=%d\n", inode->i_ddir_count);
- }
-#endif
- inode->i_ddir_count++;
- _get_inode(inode);
- }
+ printk("/%s", entry->d_name.name);
X }
X
-static inline blocking void dec_ddir(struct dentry * entry, struct inode * inode)
+void d_free(struct dentry *dentry)
X {
- if(entry->d_flag & D_INC_DDIR) {
- entry->d_flag &= ~D_INC_DDIR;
- inode->i_ddir_count--;
- if(!inode->i_ddir_count)
- __iput(inode);
+ if (dentry) {
+ kfree(dentry->d_name.name);
+ kfree(dentry);
X }
X }
X
-/* Do not inline this many times. */
-static void d_panic(void)
-{
- panic("VFS: dcache directory corruption");
-}
+#define NAME_ALLOC_LEN(len) ((len+16) & ~15)
X
-static inline struct ddir * d_dir(struct dentry * entry)
+struct dentry * d_alloc(struct dentry * parent, struct qstr *name, int isdir)
X {
- struct ddir * res = BYTE_SUB(entry, sizeof(struct ddir));
+ char *str;
+ struct dentry *res;
X
- if(!(entry->d_flag & D_DIR))
- d_panic();
-#ifdef DEBUG
- if(!entry)
- panic("entry NULL!");
- if(BASE_DHEADER(res) != BASE_DHEADER(entry))
- printk("Scheisse!!!\n");
-#endif
- return res;
-}
-
-static /*inline*/ struct dheader * dinit(int isdir, int size)
-{
- struct dheader * res = (struct dheader*)__get_free_page(GFP_KERNEL);
- int restlen = PAGE_SIZE - sizeof(struct dheader);
- struct dentry * ptr = BYTE_ADD(res, sizeof(struct dheader));
+ res = kmalloc(sizeof(struct dentry), GFP_KERNEL);
+ if (!res)
+ return NULL;
X
- if(!res)
+ str = kmalloc(NAME_ALLOC_LEN(name->len), GFP_KERNEL);
+ if (!str) {
+ kfree(res);
X return NULL;
- memset(res, 0, sizeof(struct dheader));
- if(isdir) {
- ptr = BYTE_ADD(ptr, sizeof(struct ddir));
- size += sizeof(struct ddir);
- }
- if(BASE_DHEADER(ptr) != res)
- panic("Bad kernel page alignment");
- size += sizeof(struct dentry) - D_MAXLEN;
- res->emptylist = NULL;
- res->free = 0;
- while(restlen >= size) {
-#ifdef DEBUG
- ins(ptr);
- if(BASE_DHEADER(ptr) != res)
- panic("Wrong dinit!");
-#endif
- ptr->d_next = res->emptylist;
- res->emptylist = ptr;
- ptr = BYTE_ADD(ptr, size);
- res->free++;
- restlen -= size;
X }
- res->maxfree = res->free;
- return res;
-}
+
+ memcpy(str, name->name, name->len);
+ str[name->len] = 0;
+
+ memset(res, 0, sizeof(struct dentry));
X
-static /*inline*/ struct dentry * __dalloc(struct anchors * anchor,
- struct dentry * parent, int isdir,
- int len, int size)
-{
- struct dheader ** free = isdir ? &anchor->dir_free : &anchor->free;
- struct dheader ** full = isdir ? &anchor->dir_full : &anchor->full;
- struct dheader * base = *free;
- struct dentry * res;
-
- if(!base) {
- base = dinit(isdir, size);
- if(!base)
- return NULL;
- insert_header(free, base);
- }
- base->free--;
- res = base->emptylist;
- if(!(base->emptylist = res->d_next)) {
- remove_header(free, base);
- insert_header(full, base);
- }
- memset(res, 0, sizeof(struct dentry) - D_MAXLEN);
- if(isdir) {
- res->d_flag = D_DIR;
- memset(d_dir(res), 0, sizeof(struct ddir));
- }
- res->d_len = len;
X res->d_parent = parent;
- if(parent) {
- struct ddir * pdir = d_dir(parent);
-#ifdef DEBUG
- if(pdir->dd_alloced > 1 && !IS_ROOT(parent)) {
- printpath(parent);
- printk(" dd_alloced=%d\n", pdir->dd_alloced);
- }
-#endif
- pdir->dd_alloced++;
- }
+ res->d_mounts = res;
+ res->d_covers = res;
+ res->d_flag = isdir ? D_DIR : 0;
+
+ res->d_name.name = str;
+ res->d_name.len = name->len;
+ res->d_name.hash = name->hash;
+
X #ifdef DEBUG
X x_alloc++;
X #endif
X return res;
X }
X
-struct dentry * d_alloc(struct dentry * parent, int len, int isdir)
+extern blocking struct dentry * d_alloc_root(struct inode * root_inode, struct dentry *old_root)
X {
- int i, size;
+ struct dentry *res;
+ struct qstr name = { "/", 1, 0 }; /* dummy qstr */
X
-#ifdef DEBUG
- if(the_root)
- recursive_test(the_root);
- LOG("d_alloc", parent);
-#endif
- if(len >= D_MEDIUM) {
- if(len >= D_LARGE) {
- i = 3;
- size = D_HUGE;
- } else {
- i = 2;
- size = D_LARGE;
- }
- } else if(len >= D_SMALL) {
- i = 1;
- size = D_MEDIUM;
- } else {
- i = 0;
- size = D_SMALL;
- }
- return __dalloc(&anchors[i], parent, isdir, len, size);
-}
-
-extern blocking struct dentry * d_alloc_root(struct inode * root_inode)
-{
- struct dentry * res = the_root;
-
- if(res) {
- d_del(res, D_NO_CLEAR_INODE); /* invalidate everything beyond */
- } else {
- struct ddir * ddir;
-
- the_root = res = d_alloc(NULL, 0, 1);
- LOG("d_alloc_root", res);
- res->d_parent = res;
- res->d_name[0]='\0';
- ddir = d_dir(res);
- ddir->dd_alloced = 999; /* protect from deletion */
- }
- insert_alias(&root_inode->i_dentry, res);
- root_inode->i_dent_count++;
- root_inode->i_ddir_count++;
- res->u.d_inode = root_inode;
+ if (!root_inode)
+ return NULL;
+ res = d_alloc(NULL, &name, 1);
+ LOG("d_alloc_root", res);
+ res->d_parent = res;
+ d_instantiate(res, root_inode, D_DIR);
X return res;
X }
X
-static inline unsigned long d_hash(char first, char last)
+static inline struct dentry ** d_base_qstr(struct dentry * parent, struct qstr * s)
X {
- return ((unsigned long)first ^ ((unsigned long)last << 4)) & (D_HASHSIZE-1);
+ return dentry_hashtable + dentry_hash(parent, s->hash);
X }
X
-static inline struct dentry ** d_base_entry(struct ddir * pdir, struct dentry * entry)
+static inline struct dentry ** d_base_entry(struct dentry * pdir, struct dentry * entry)
X {
- return &pdir->dd_hashtable[d_hash(entry->d_name[0],
- entry->d_name[entry->d_len-1])];
-}
-
-static inline struct dentry ** d_base_qstr(struct ddir * pdir,
- struct qstr * s1,
- struct qstr * s2)
-{
- unsigned long hash;
-
- if(s2 && s2->len) {
- hash = d_hash(s1->name[0], s2->name[s2->len-1]);
- } else {
- hash = d_hash(s1->name[0], s1->name[s1->len-1]);
- }
- return &pdir->dd_hashtable[hash];
+ return d_base_qstr(pdir, &entry->d_name);
X }
X
X
X static /*inline*/ blocking void _d_remove_from_parent(struct dentry * entry,
- struct ddir * pdir,
- struct inode * inode,
- int flags)
+ struct dentry * parent)
X {
- if(entry->d_flag & D_HASHED) {
- struct dentry ** base = d_base_entry(pdir, entry);
+ if (entry->d_flag & D_HASHED) {
+ struct dentry ** base = d_base_entry(parent, entry);
X
X remove_hash(base, entry);
X entry->d_flag &= ~D_HASHED;
- pdir->dd_hashed--;
- if(!(entry->d_flag & D_PRELIMINARY)) {
- pdir->dd_true_hashed--;
- if(!inode) {
-#ifdef DEBUG
- if(!entry->d_next || !entry->d_prev) {
- printpath(entry);
- printk(" flags=%x d_flag=%x negs=%d "
- "hashed=%d\n", flags, entry->d_flag,
- pdir->dd_negs, pdir->dd_hashed);
- }
-#endif
- remove_alias(&pdir->dd_neglist, entry);
- pdir->dd_negs--;
- }
- }
- } else if(!(entry->d_flag & D_ZOMBIE)) {
-#ifdef DEBUG
- if(!pdir->dd_alloced) printk("dd_alloced is 0!\n");
-#endif
- pdir->dd_alloced--;
- }
- if(entry->d_flag & D_BASKET) {
- remove_basket(&pdir->dd_basketlist, entry);
- entry->d_flag &= ~D_BASKET;
- }
-}
-
-/* Theoretically, zombies should never or extremely seldom appear,
- * so this code is nearly superfluous.
- * A way to get zombies is while using inodes (i_count>0), unlink()
- * them as well as rmdir() the parent dir => the parent dir becomes a zombie.
- * Zombies are *not* in the hashtable, because somebody could re-creat()
- * that filename in it's parent dir again.
- * Besides coding errors during beta phase, when forcing an umount()
- * (e.g. at shutdown time), inodes could be in use such that the parent
- * dir is cleared, resulting also in zombies.
- */
-static /*inline*/ void _d_handle_zombie(struct dentry * entry,
- struct ddir * ddir,
- struct ddir * pdir)
-{
- if(entry->d_flag & D_DIR) {
- if(entry->d_flag & D_ZOMBIE) {
- if(!has_sons(ddir)) {
- entry->d_flag &= ~D_ZOMBIE;
- remove_hash(&pdir->dd_zombielist, entry);
- if(!pdir->dd_zombielist &&
- (entry->d_parent->d_flag & D_ZOMBIE)) {
- d_del(entry->d_parent, D_NORMAL);
- }
- }
- } else if(has_sons(ddir)) {
- entry->d_flag |= D_ZOMBIE;
- insert_hash(&pdir->dd_zombielist, entry);
-
- /* This condition is no longer a bug, with the removal
- * of recursive_clear() this happens naturally during
- * an unmount attempt of a filesystem which is busy.
- */
-#if 0
- /* Not sure when this message should show up... */
- if(!IS_ROOT(entry)) {
- printk("VFS: clearing dcache directory "
- "with successors\n");
-#ifdef DEBUG
- printpath(entry);
- printk(" d_flag=%x alloced=%d negs=%d hashed=%d "
- "basket=%p zombies=%p\n",
- entry->d_flag, ddir->dd_alloced,
- ddir->dd_negs, ddir->dd_hashed,
- ddir->dd_basketlist, ddir->dd_zombielist);
-#endif
- }
-#endif
- }
- }
-}
-
-static /*inline*/ blocking void _d_del(struct dentry * entry,
- struct anchors * anchor,
- int flags)
-{
- struct dheader ** free;
- struct dheader ** full;
- struct dheader * base = BASE_DHEADER(entry);
- struct ddir * ddir = NULL;
- struct ddir * pdir;
- struct inode * inode = entry->d_flag & D_PRELIMINARY ? NULL : entry->u.d_inode;
-
-#ifdef DEBUG
- if(inode)
- xcheck("_d_del", inode);
-#endif
- if(!entry->d_parent) {
- printk("VFS: dcache parent is NULL\n");
- return;
- }
- if(entry->d_flag & D_DIR) {
- free = &anchor->dir_free;
- full = &anchor->dir_full;
- } else {
- free = &anchor->free;
- full = &anchor->full;
- }
- pdir = d_dir(entry->d_parent);
- if(!IS_ROOT(entry))
- _d_remove_from_parent(entry, pdir, inode, flags);
-
- /* This may block, be careful! _d_remove_from_parent() is
- * thus called before.
- */
- if(entry->d_flag & D_DIR)
- ddir = d_dir(entry);
- if(IS_ROOT(entry))
- return;
-
- if(flags & D_NO_FREE) {
- /* Make it re-d_add()able */
- pdir->dd_alloced++;
- entry->d_flag &= D_DIR;
- } else
- _d_handle_zombie(entry, ddir, pdir);
-
- /* This dec_ddir() must occur after zombie handling. */
- if(!has_true_sons(pdir))
- dec_ddir(entry->d_parent, entry->d_parent->u.d_inode);
-
- entry->u.d_inode = NULL;
- if(inode) {
- remove_alias(&inode->i_dentry, entry);
- inode->i_dent_count--;
- if (entry->d_flag & D_DIR)
- dec_ddir(entry, inode);
-
- if(!(flags & D_NO_CLEAR_INODE) &&
- !(atomic_read(&inode->i_count) +
- inode->i_ddir_count +
- inode->i_dent_count)) {
-#ifdef DEBUG
- printk("#");
-#endif
- /* This may block also. */
- _clear_inode(inode, 0, 0);
- }
- }
- if(!(flags & D_NO_FREE) && !(entry->d_flag & D_ZOMBIE)) {
- base->free++;
- if(base->free == base->maxfree) {
-#ifndef DEBUG
- remove_header(free, base);
- free_page((unsigned long)base);
- goto done;
-#endif
- }
- entry->d_next = base->emptylist;
- base->emptylist = entry;
- if(!entry->d_next) {
- remove_header(full, base);
- insert_header(free, base);
- }
-#ifdef DEBUG
- x_freed++;
-#endif
- }
-#ifndef DEBUG
-done:
-#else
- x_free++;
-#endif
-}
-
-blocking void d_del(struct dentry * entry, int flags)
-{
- int i;
-
- if(!entry)
- return;
- LOG("d_clear", entry);
- if(entry->d_len >= D_MEDIUM) {
- if(entry->d_len >= D_LARGE) {
- i = 3;
- } else {
- i = 2;
- }
- } else if(entry->d_len >= D_SMALL) {
- i = 1;
- } else {
- i = 0;
X }
- _d_del(entry, &anchors[i], flags);
X }
X
-static inline struct dentry * __dlookup(struct dentry ** base,
- struct qstr * name,
- struct qstr * appendix)
+static inline struct dentry * __dlookup(struct dentry * base, struct dentry * parent, struct qstr * name)
X {
- struct dentry * tmp = *base;
+ if (base) {
+ struct dentry * tmp = base;
+ int len = name->len;
+ int hash = name->hash;
+ const unsigned char *str = name->name;
X
- if(tmp && name->len) {
- int totallen = name->len;
-
- if(appendix)
- totallen += appendix->len;
X do {
- if(tmp->d_len == totallen &&
- !(tmp->d_flag & D_DUPLICATE) &&
- !strncmp(tmp->d_name, name->name, name->len) &&
- (!appendix || !strncmp(tmp->d_name+name->len,
- appendix->name, appendix->len)))
+ if (tmp->d_name.hash == hash &&
+ tmp->d_name.len == len &&
+ tmp->d_parent == parent &&
+ !(tmp->d_flag & D_DUPLICATE) &&
+ !memcmp(tmp->d_name.name, str, len))
X return tmp;
X tmp = tmp->d_hash_next;
- } while(tmp != *base);
+ } while(tmp != base);
X }
X return NULL;
X }
X
-struct dentry * d_lookup(struct inode * dir,
- struct qstr * name,
- struct qstr * appendix)
-{
- if(dir->i_dentry) {
- struct ddir * ddir = d_dir(dir->i_dentry);
- struct dentry ** base = d_base_qstr(ddir, name, appendix);
+struct dentry * d_lookup(struct dentry * dir, struct qstr * name)
+{
+ struct dentry ** base = d_base_qstr(dir, name);
X
- return __dlookup(base, name, appendix);
- }
- return NULL;
+ return __dlookup(*base, dir, name);
X }
X
X static /*inline*/ blocking void _d_insert_to_parent(struct dentry * entry,
- struct ddir * pdir,
+ struct dentry * parent,
X struct inode * inode,
- struct qstr * ininame,
X int flags)
X {
X struct dentry ** base;
- struct dentry * parent = entry->d_parent;
X
-#ifdef DEBUG
- if(!pdir->dd_alloced)
- printk("dd_alloced is 0!\n");
-#endif
- base = d_base_qstr(pdir, ininame, NULL);
- if(!(flags & (D_NOCHECKDUP|D_DUPLICATE)) &&
- __dlookup(base, ininame, NULL)) {
- d_del(entry, D_NO_CLEAR_INODE);
- return;
- }
- if(entry->d_flag & D_HASHED) {
+ base = d_base_qstr(parent, &entry->d_name);
+ if (entry->d_flag & D_HASHED) {
X printk("VFS: dcache entry is already hashed\n");
X return;
X }
- if(!(flags & D_PRELIMINARY))
- pdir->dd_true_hashed++;
- pdir->dd_hashed++;
X insert_hash(base, entry);
X entry->d_flag |= D_HASHED;
- pdir->dd_alloced--;
- if(flags & D_BASKET)
- insert_basket(&pdir->dd_basketlist, entry);
+}
X
-#ifdef DEBUG
- if(inode && inode->i_dentry && (entry->d_flag & D_DIR)) {
- struct dentry * tmp = inode->i_dentry;
- printk("Auweia inode=%p entry=%p (%p %p %s)\n",
- inode, entry, parent->u.d_inode, parent, parent->d_name);
- printk("entry path="); printpath(entry); printk("\n");
- do {
- TST("auweia",tmp);
- printk("alias path="); printpath(tmp); printk("\n");
- tmp = tmp->d_next;
- } while(tmp != inode->i_dentry);
- printk("\n");
+/*
+ * Fill in inode information in the entry.
+ *
+ * This turns negative dentries into productive full members
+ * of society.
+ *
+ * NOTE! This assumes that the inode count has been incremented
+ * (or otherwise set) by the caller to indicate that it is now
+ * in use by the dcache..
+ */
+void d_instantiate(struct dentry *entry, struct inode * inode, int flags)
+{
+ entry->d_flag = (entry->d_flag & ~D_NEGATIVE) | flags;
+
+ if (inode && !(flags & D_NEGATIVE)) {
+ if (entry->d_flag & D_DIR) {
+ if (inode->i_dentry) {
+ printk("VFS: creating dcache directory alias\n");
+ return;
+ }
+ }
+ insert_alias(&inode->i_dentry, entry);
X }
-#endif
- if(has_true_sons(pdir))
- inc_ddir(parent, parent->u.d_inode);
- if(!inode && !(flags & D_PRELIMINARY)) {
- insert_alias(&pdir->dd_neglist, entry);
- pdir->dd_negs++;
-
- /* Don't allow the negative list to grow too much ... */
- while(pdir->dd_negs > (pdir->dd_true_hashed >> 1) + 5)
- d_del(pdir->dd_neglist->d_prev, D_REMOVE);
+
+ entry->d_inode = inode;
+}
+
+/*
+ * Remove the inode from the dentry.. This removes
+ * it from the parent hashes but otherwise leaves it
+ * around - it may be a "zombie", part of a path
+ * that is still in use...
+ *
+ * "The Night of the Living Dead IV - the Dentry"
+ */
+void d_delete(struct dentry * dentry)
+{
+ struct inode * inode = dentry->d_inode;
+
+ _d_remove_from_parent(dentry, dentry->d_parent);
+ if (inode) {
+ remove_alias(&inode->i_dentry, dentry);
+ dentry->d_inode = NULL;
+ iput(inode);
X }
X }
X
-blocking void d_add(struct dentry * entry, struct inode * inode,
- struct qstr * ininame, int flags)
+blocking void d_add(struct dentry * entry, struct inode * inode, int flags)
X {
X struct dentry * parent = entry->d_parent;
- struct qstr dummy;
- struct ddir * pdir;
X
X #ifdef DEBUG
- if(inode)
+ if (inode)
X xcheck("d_add", inode);
- if(IS_ROOT(entry)) {
+ if (IS_ROOT(entry)) {
X printk("VFS: d_add for root dentry ");
X printpath(entry);
X printk(" -> ");
- if(ininame)
- printk("%s", ininame->name);
X printk("\n");
X return;
X }
- if(!parent)
+ if (!parent)
X panic("d_add with parent==NULL");
X LOG("d_add", entry);
X #endif
- if(ininame) {
- if(ininame->len != entry->d_len) {
- printk("VFS: d_add with wrong string length");
- entry->d_len = ininame->len; /* kludge */
- }
- memcpy(entry->d_name, ininame->name, ininame->len);
- entry->d_name[ininame->len] = '\0';
- } else {
- dummy.name = entry->d_name;
- dummy.len = entry->d_len;
- ininame = &dummy;
- }
X if(entry->d_flag & D_HASHED)
X printk("VFS: d_add of already added dcache entry\n");
X
- pdir = d_dir(parent);
- _d_insert_to_parent(entry, pdir, inode, ininame, flags);
- entry->d_flag |= flags;
- if(inode && !(flags & D_PRELIMINARY)) {
- if(entry->d_flag & D_DIR) {
- if(inode->i_dentry) {
- printk("VFS: creating dcache directory alias\n");
- return;
- }
- }
- insert_alias(&inode->i_dentry, entry);
- inode->i_dent_count++;
- }
- entry->u.d_inode = inode;
+ _d_insert_to_parent(entry, parent, inode, flags);
+ d_instantiate(entry, inode, flags);
X }
X
-blocking struct dentry * d_entry(struct dentry * parent,
- struct qstr * name,
- struct inode * inode)
-{
- struct ddir * pdir = d_dir(parent);
- struct dentry ** base = d_base_qstr(pdir, name, NULL);
- struct dentry * found = __dlookup(base, name, NULL);
-
- if(!found) {
- int isdir = (inode && S_ISDIR(inode->i_mode));
-
- found = d_alloc(parent, name->len, isdir);
- if(found) {
- d_add(found, inode, name,
- isdir ? (D_DIR|D_NOCHECKDUP) : D_NOCHECKDUP);
- } else
- printk("VFS: problem with d_alloc\n");
+static inline void alloc_new_name(struct dentry * entry, struct qstr *newname)
+{
+ int len = newname->len;
+ int hash = newname->hash;
+ char *name = (char *) entry->d_name.name;
+
+ if (NAME_ALLOC_LEN(len) != NAME_ALLOC_LEN(entry->d_name.len)) {
+ name = kmalloc(NAME_ALLOC_LEN(len), GFP_KERNEL);
+ if (!name)
+ printk("out of memory for dcache\n");
+ kfree(entry->d_name.name);
+ entry->d_name.name = name;
X }
- return found;
+ memcpy(name, newname->name, len);
+ name[len] = 0;
+ entry->d_name.len = len;
+ entry->d_name.hash = hash;
X }
X
-blocking void d_entry_preliminary(struct dentry * parent,
- struct qstr * name,
- unsigned long ino)
+static inline void d_remove_old_parent(struct dentry * entry)
X {
- struct ddir * pdir = d_dir(parent);
- struct dentry ** base = d_base_qstr(pdir, name, NULL);
- struct dentry * found = __dlookup(base, name, NULL);
+ struct dentry * parent;
+ struct inode * inode;
X
- if(!found && ino) {
- struct dentry * new = d_alloc(parent, name->len, 0);
+ parent = entry->d_parent;
+ inode = entry->d_inode;
+ _d_remove_from_parent(entry, parent);
+}
X
- if(new) {
- d_add(new, NULL, name, D_PRELIMINARY|D_NOCHECKDUP);
- new->u.d_ino = ino;
- } else
- printk("VFS: problem with d_alloc\n");
- }
+static inline void d_add_new_parent(struct dentry * entry, struct dentry * parent)
+{
+ struct inode * inode;
+
+ entry->d_parent = parent;
+ inode = entry->d_inode;
+
+ _d_insert_to_parent(entry, parent, inode, entry->d_flag);
X }
X
-blocking void d_move(struct dentry * entry, struct inode * newdir,
- struct qstr * newname, struct qstr * newapp)
+
+blocking void d_move(struct dentry * entry, struct dentry * newdir, struct qstr * newname)
X {
- struct ddir tmp;
- struct dentry * new;
X struct inode * inode;
- int len;
X int flags;
X
- if(!entry)
+ if (!entry)
X return;
- inode = entry->u.d_inode;
+ inode = entry->d_inode;
X flags = entry->d_flag;
- if((flags & D_PRELIMINARY) || !inode) {
- if(!(flags & D_PRELIMINARY))
- printk("VFS: trying to move negative dcache entry\n");
- d_del(entry, D_NO_CLEAR_INODE);
- return;
+ if (!inode) {
+ printk("VFS: moving negative dcache entry\n");
X }
-#if 0
-printk("d_move %p '%s' -> '%s%s' dent_count=%d\n", inode, entry->d_name,
- newname->name, newapp ? newapp->name : "", inode->i_dent_count);
-#endif
- if(flags & D_ZOMBIE) {
- printk("VFS: moving zombie entry\n");
- }
- if(flags & D_DIR) {
- struct ddir * ddir = d_dir(entry);
X
- memcpy(&tmp, ddir, sizeof(struct ddir));
-
- /* Simulate empty dir for d_del(). */
- memset(ddir, 0, sizeof(struct ddir));
+ if (flags & D_ZOMBIE) {
+ printk("VFS: moving zombie entry\n");
X }
- len = newname->len;
- if(newapp) {
- len += newapp->len;
- flags |= D_BASKET;
- } else
- flags &= ~D_BASKET;
- new = d_alloc(newdir->i_dentry, len, flags & D_DIR);
- memcpy(new->d_name, newname->name, newname->len);
- if(newapp)
- memcpy(new->d_name+newname->len, newapp->name, newapp->len);
- new->d_name[len] = '\0';
- d_del(entry, D_NO_CLEAR_INODE);
- d_add(new, inode, NULL, flags & (D_DIR|D_BASKET));
- if(flags & D_DIR) {
- struct ddir * ddir = d_dir(new);
X
- memcpy(ddir, &tmp, sizeof(struct ddir));
- }
+ d_remove_old_parent(entry);
+ alloc_new_name(entry, newname);
+ d_add_new_parent(entry, newdir);
X }
X
-int d_path(struct dentry * entry, struct inode * chroot, char * buf)
+int d_path(struct dentry * entry, struct dentry * chroot, char * buf)
X {
- if(IS_ROOT(entry) || (chroot && entry->u.d_inode == chroot &&
- !(entry->d_flag & D_PRELIMINARY))) {
+ if (IS_ROOT(entry) || (chroot && entry == chroot)) {
X *buf = '/';
X return 1;
X } else {
X int len = d_path(entry->d_parent, chroot, buf);
X
X buf += len;
- if(len > 1) {
+ if (len > 1) {
X *buf++ = '/';
X len++;
X }
- memcpy(buf, entry->d_name, entry->d_len);
- return len + entry->d_len;
- }
-}
-
-struct dentry * d_basket(struct dentry * dir_entry)
-{
- if(dir_entry && (dir_entry->d_flag & D_DIR)) {
- struct ddir * ddir = d_dir(dir_entry);
-
- return ddir->dd_basketlist;
- } else
- return NULL;
-}
-
-int d_isbasket(struct dentry * entry)
-{
- return entry->d_flag & D_BASKET;
-}
-
-blocking struct inode * d_inode(struct dentry ** changing_entry)
-{
- struct dentry * entry = *changing_entry;
- struct inode * inode;
-
-#ifdef CONFIG_DCACHE_PRELOAD
- if(entry->d_flag & D_PRELIMINARY) {
- struct qstr name = { entry->d_name, entry->d_len };
- struct ddir * pdir = d_dir(entry->d_parent);
- struct dentry ** base = d_base_qstr(pdir, &name, NULL);
- struct dentry * found;
- unsigned long ino;
- struct inode * dir = entry->d_parent->u.d_inode;
- TST("d_inode",entry);
- ino = entry->u.d_ino;
- if(!dir)
- d_panic();
-
- /* Prevent concurrent d_lookup()s or d_inode()s before
- * giving up vfs_lock. This just removes from the parent,
- * but does not deallocate it.
- */
-
- /* !!!!!!! Aiee, here is an unresolved race if somebody
- * unlink()s the inode during the iget(). The problem is
- * that we need to synchronize externally. Proposed solution:
- * put a rw_lock (read-mode) on the parent dir for each
- * iget(), lookup() and so on, and a write-mode lock for
- * everything that changes the dir (e.g. unlink()), and do
- * this consistently everywhere in the generic VFS (not in
- * the concrete filesystems). This should kill similar
- * races everywhere, with a single clean concept.
- * Later, the synchronization stuff can be cleaned out
- * of the concrete fs'es.
- */
- d_del(entry, D_NO_CLEAR_INODE|D_NO_FREE);
- vfs_unlock();
-
- /* This circumvents the normal lookup() of pathnames.
- * Therefore, preliminary entries must not be used
- * (see FS_NO_DCACHE and FS_NO_PRELIM) if the fs does not
- * permit fetching *valid* inodes with plain iget().
- */
- inode = __iget(dir->i_sb, ino, 0);
- vfs_lock();
- if(!inode) {
- printk("VFS: preliminary dcache entry was invalid\n");
- *changing_entry = NULL;
- return NULL;
- }
- xcheck("d_inode iget()", inode);
- if((found = __dlookup(base, &name, NULL))) {
- d_del(entry, D_NO_CLEAR_INODE);
- *changing_entry = found;
- } else if(S_ISDIR(inode->i_mode)) {
- struct dentry * new = d_alloc(entry->d_parent, entry->d_len, 1);
- if(new)
- d_add(new, inode, &name, D_DIR);
- *changing_entry = new;
-
- /* Finally deallocate old entry. */
- d_del(entry, D_NO_CLEAR_INODE);
- } else {
- /* Re-insert to the parent, but now as normal dentry. */
- d_add(entry, inode, NULL, 0);
- }
- return inode;
- }
-#endif
- inode = entry->u.d_inode;
- if(inode) {
-#ifdef DEBUG
- xcheck("d_inode", inode);
-#endif
- iinc_zero(inode);
+ memcpy(buf, entry->d_name.name, entry->d_name.len);
+ return len + entry->d_name.len;
X }
- return inode;
X }
diff -u --recursive --new-file v2.1.43/linux/fs/dquot.c linux/fs/dquot.c
--- v2.1.43/linux/fs/dquot.c Mon Jun 16 16:35:57 1997
+++ linux/fs/dquot.c Tue Jul 1 13:47:22 1997
@@ -1038,7 +1038,7 @@
X if (special == (char *)NULL && (cmds == Q_SYNC || cmds == Q_GETSTATS))
X dev = 0;
X else {
- int error = namei(NAM_FOLLOW_LINK, special, &ino);
+ int error = namei(special, &ino);
X if(error)
X goto out;
X dev = ino->i_rdev;
diff -u --recursive --new-file v2.1.43/linux/fs/ext2/balloc.c linux/fs/ext2/balloc.c
--- v2.1.43/linux/fs/ext2/balloc.c Mon Jun 16 16:35:57 1997
+++ linux/fs/ext2/balloc.c Sun Jul 6 20:13:54 1997
@@ -291,7 +291,7 @@
X printk ("ext2_new_block: nonexistent device");
X return 0;
X }
-retry:
+
X lock_super (sb);
X es = sb->u.ext2_sb.s_es;
X if (le32_to_cpu(es->s_free_blocks_count) <= le32_to_cpu(es->s_r_blocks_count) &&
@@ -299,8 +299,6 @@
X (sb->u.ext2_sb.s_resgid == 0 ||
X !in_group_p (sb->u.ext2_sb.s_resgid)))) {
X unlock_super (sb);
- if(sb->s_ibasket && free_ibasket(sb))
- goto retry;


X return 0;
X }
X

@@ -392,8 +390,6 @@
X }
X if (k >= sb->u.ext2_sb.s_groups_count) {
X unlock_super (sb);
- if(sb->s_ibasket && free_ibasket(sb))
- goto retry;
X return 0;
X }
X bitmap_nr = load_block_bitmap (sb, i);
diff -u --recursive --new-file v2.1.43/linux/fs/ext2/dir.c linux/fs/ext2/dir.c
--- v2.1.43/linux/fs/ext2/dir.c Mon Jun 16 16:35:57 1997
+++ linux/fs/ext2/dir.c Sat Jul 5 20:53:22 1997
@@ -65,6 +65,7 @@
X ext2_mknod, /* mknod */
X ext2_rename, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */
X NULL, /* bmap */
diff -u --recursive --new-file v2.1.43/linux/fs/ext2/file.c linux/fs/ext2/file.c
--- v2.1.43/linux/fs/ext2/file.c Mon Jun 16 16:35:57 1997
+++ linux/fs/ext2/file.c Sat Jul 5 20:53:22 1997
@@ -72,6 +72,7 @@
X NULL, /* mknod */
X NULL, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X generic_readpage, /* readpage */
X NULL, /* writepage */
X ext2_bmap, /* bmap */
diff -u --recursive --new-file v2.1.43/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
--- v2.1.43/linux/fs/ext2/namei.c Mon Jun 16 16:35:57 1997
+++ linux/fs/ext2/namei.c Mon Jul 7 11:29:42 1997
@@ -27,6 +27,7 @@
X #include <linux/string.h>
X #include <linux/locks.h>
X
+
X /*
X * define how far ahead to read directories while searching them.
X */
@@ -154,8 +155,7 @@
X return NULL;
X }
X
-int ext2_lookup (struct inode * dir, const char * name, int len,
- struct inode ** result)
+int ext2_lookup(struct inode * dir, struct qstr *name, struct inode ** result)
X {
X unsigned long ino;
X struct ext2_dir_entry * de;
@@ -164,26 +164,22 @@
X *result = NULL;
X if (!dir)
X return -ENOENT;
- if (!S_ISDIR(dir->i_mode)) {
- iput (dir);
+
+ if (!S_ISDIR(dir->i_mode))
X return -ENOTDIR;
- }
- if (len > EXT2_NAME_LEN) {
- iput (dir);
+
+ if (name->len > EXT2_NAME_LEN)
X return -ENAMETOOLONG;
- }
+
X ino = dir->i_version;
- if (!(bh = ext2_find_entry (dir, name, len, &de))) {
- iput (dir);
+ if (!(bh = ext2_find_entry (dir, name->name, name->len, &de)))


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 30'
echo 'File patch-2.1.44 is continued in part 31'
echo 31 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part34

#!/bin/sh
# this is part 34 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 34; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

+ :"Ir" (i),
+ "m" (__atomic_fool_gcc(v)));
+
+ return result;
+}
+#endif
+
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+#define atomic_inc(v) atomic_add(1,(v))
+#define atomic_dec(v) atomic_sub(1,(v))
+#endif /* defined(__KERNEL__) */
+
+#endif /* __ASM_MIPS_ATOMIC_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/bitops.h linux/include/asm-mips/bitops.h
--- v2.1.43/linux/include/asm-mips/bitops.h Wed Dec 13 02:39:45 1995
+++ linux/include/asm-mips/bitops.h Thu Jun 26 12:33:39 1997
@@ -5,15 +5,55 @@


X * License. See the file "COPYING" in the main directory of this archive
X * for more details.

X *
- * Copyright (c) 1994, 1995 Ralf Baechle
+ * Copyright (c) 1994, 1995, 1996 Ralf Baechle
X */
X #ifndef __ASM_MIPS_BITOPS_H
X #define __ASM_MIPS_BITOPS_H
X
-#if __mips > 1
+#ifdef __KERNEL__
+
+#include <asm/sgidefs.h>
+#include <asm/system.h>
+
+/*
+ * Only disable interrupt for kernel mode stuff to keep usermode stuff
+ * that dares to use kernel include files alive.
+ */
+#define __bi_flags unsigned long flags
+#define __bi_cli() __cli()
+#define __bi_save_flags(x) __save_flags(x)
+#define __bi_restore_flags(x) __restore_flags(x)
+#else
+#define __bi_flags
+#define __bi_cli()
+#define __bi_save_flags(x)
+#define __bi_restore_flags(x)
+#endif /* __KERNEL__ */
+
+/*
+ * Note that the bit operations are defined on arrays of 32 bit sized
+ * elements. With respect to a future 64 bit implementation it is
+ * wrong to use long *. Use u32 * or int *.
+ */
+extern __inline__ void set_bit(int nr, void *addr);
+extern __inline__ void clear_bit(int nr, void *addr);
+extern __inline__ void change_bit(int nr, void *addr);
+extern __inline__ int test_and_set_bit(int nr, void *addr);
+extern __inline__ int test_and_clear_bit(int nr, void *addr);
+extern __inline__ int test_and_change_bit(int nr, void *addr);
+
+extern __inline__ int test_bit(int nr, const void *addr);
+#ifndef __MIPSEB__
+extern __inline__ int find_first_zero_bit (void *addr, unsigned size);
+#endif
+extern __inline__ int find_next_zero_bit (void * addr, int size, int offset);
+extern __inline__ unsigned long ffz(unsigned long word);
+
+#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
X
X /*
- * These functions for MIPS ISA >= 2 are interrupt and SMP proof and
+ * These functions for MIPS ISA > 1 are interrupt and SMP proof and
X * interrupt friendly
X */
X #include <asm/mipsregs.h>
@@ -21,7 +61,42 @@
X /*
X * The following functions will only work for the R4000!
X */
-extern __inline__ int set_bit(int nr, void *addr)
+
+extern __inline__ void set_bit(int nr, void *addr)
+{
+ int mask, mw;
+
+ addr += ((nr >> 3) & ~3);
+ mask = 1 << (nr & 0x1f);
+ do {
+ mw = load_linked(addr);
+ } while (!store_conditional(addr, mw|mask));
+}
+
+extern __inline__ void clear_bit(int nr, void *addr)
+{
+ int mask, mw;
+
+ addr += ((nr >> 3) & ~3);
+ mask = 1 << (nr & 0x1f);
+ do {
+ mw = load_linked(addr);
+ }
+ while (!store_conditional(addr, mw & ~mask));
+}
+
+extern __inline__ void change_bit(int nr, void *addr)
+{
+ int mask, mw;
+
+ addr += ((nr >> 3) & ~3);
+ mask = 1 << (nr & 0x1f);
+ do {
+ mw = load_linked(addr);
+ } while (!store_conditional(addr, mw ^ mask));
+}
+
+extern __inline__ int test_and_set_bit(int nr, void *addr)
X {
X int mask, retval, mw;
X
@@ -30,13 +105,12 @@
X do {
X mw = load_linked(addr);
X retval = (mask & mw) != 0;
- }
- while (!store_conditional(addr, mw|mask));
+ } while (!store_conditional(addr, mw|mask));
X

X return retval;
X }
X

-extern __inline__ int clear_bit(int nr, void *addr)
+extern __inline__ int test_and_clear_bit(int nr, void *addr)
X {
X int mask, retval, mw;
X
@@ -51,7 +125,7 @@


X return retval;
X }
X

-extern __inline__ int change_bit(int nr, void *addr)
+extern __inline__ int test_and_change_bit(int nr, void *addr)
X {
X int mask, retval, mw;
X
@@ -60,124 +134,165 @@
X do {
X mw = load_linked(addr);
X retval = (mask & mw) != 0;
- }
- while (!store_conditional(addr, mw ^ mask));
+ } while (!store_conditional(addr, mw ^ mask));
X

X return retval;
X }
X

-#else /* __mips <= 1 */
+#else /* MIPS I */
X
-/*
- * These functions are only used for MIPS ISA 1 CPUs. Since I don't
- * believe that someone ever will run Linux/SMP on such a beast I don't
- * worry about making them SMP proof.
- */
-#include <asm/system.h>
+extern __inline__ void set_bit(int nr, void * addr)
+{
+ int mask;
+ int *a = addr;
+ __bi_flags;
X
-#ifdef __KERNEL__
-/*
- * Only disable interrupt for kernel mode stuff to keep usermode stuff
- * that dares to use kernel include files alive.
- */
-#define __flags unsigned long flags
-#define __cli() cli()
-#define __save_flags(x) save_flags(x)
-#define __restore_flags(x) restore_flags(x)
-#endif /* __KERNEL__ */
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ __bi_save_flags(flags);
+ __bi_cli();
+ *a |= mask;
+ __bi_restore_flags(flags);
+}
X
-extern __inline__ int set_bit(int nr, void * addr)
+extern __inline__ void clear_bit(int nr, void * addr)
+{
+ int mask;
+ int *a = addr;
+ __bi_flags;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ __bi_save_flags(flags);
+ __bi_cli();
+ *a &= ~mask;
+ __bi_restore_flags(flags);
+}
+
+extern __inline__ void change_bit(int nr, void * addr)
+{
+ int mask;
+ int *a = addr;
+ __bi_flags;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ __bi_save_flags(flags);
+ __bi_cli();
+ *a ^= mask;
+ __bi_restore_flags(flags);
+}
+
+extern __inline__ int test_and_set_bit(int nr, void * addr)
X {
X int mask, retval;
X int *a = addr;
- __flags;
+ __bi_flags;
X
X a += nr >> 5;
X mask = 1 << (nr & 0x1f);
- __save_flags(flags);
- __cli();
+ __bi_save_flags(flags);
+ __bi_cli();
X retval = (mask & *a) != 0;
X *a |= mask;
- __restore_flags(flags);
+ __bi_restore_flags(flags);
X

X return retval;
X }
X

-extern __inline__ int clear_bit(int nr, void * addr)
+extern __inline__ int test_and_clear_bit(int nr, void * addr)
X {
X int mask, retval;
X int *a = addr;
- __flags;
+ __bi_flags;
X
X a += nr >> 5;
X mask = 1 << (nr & 0x1f);
- __save_flags(flags);
- __cli();
+ __bi_save_flags(flags);
+ __bi_cli();
X retval = (mask & *a) != 0;
X *a &= ~mask;
- __restore_flags(flags);
+ __bi_restore_flags(flags);
X

X return retval;
X }
X

-extern __inline__ int change_bit(int nr, void * addr)
+extern __inline__ int test_and_change_bit(int nr, void * addr)
X {
X int mask, retval;
X int *a = addr;
- __flags;
+ __bi_flags;
X
X a += nr >> 5;
X mask = 1 << (nr & 0x1f);
- __save_flags(flags);
- __cli();
+ __bi_save_flags(flags);
+ __bi_cli();
X retval = (mask & *a) != 0;
X *a ^= mask;
- __restore_flags(flags);
+ __bi_restore_flags(flags);
X

X return retval;
X }
X

-#undef __flags
-#undef __cli()
-#undef __save_flags(x)
-#undef __restore_flags(x)
+#undef __bi_flags
+#undef __bi_cli()
+#undef __bi_save_flags(x)
+#undef __bi_restore_flags(x)
X
-#endif /* __mips <= 1 */
+#endif /* MIPS I */
X
X extern __inline__ int test_bit(int nr, const void *addr)
X {
- return 1UL & (((const unsigned int *) addr)[nr >> 5] >> (nr & 31));
+ return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0;
X }
X
+#ifndef __MIPSEB__
+
+/* Little endian versions. */
+
X extern __inline__ int find_first_zero_bit (void *addr, unsigned size)
X {
+ unsigned long dummy;
X int res;
X
X if (!size)
X return 0;
X
- __asm__(".set\tnoreorder\n\t"
+ __asm__ (".set\tnoreorder\n\t"
X ".set\tnoat\n"
- "1:\tsubu\t$1,%2,%0\n\t"
+ "1:\tsubu\t$1,%6,%0\n\t"
X "blez\t$1,2f\n\t"
- "lw\t$1,(%4)\n\t"
- "addiu\t%4,%4,4\n\t"
+ "lw\t$1,(%5)\n\t"
+ "addiu\t%5,4\n\t"
+#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
X "beql\t%1,$1,1b\n\t"
- "addiu\t%0,%0,32\n\t"


+ "addiu\t%0,32\n\t"

+#else


+ "addiu\t%0,32\n\t"

+ "beq\t%1,$1,1b\n\t"
+ "nop\n\t"
+ "subu\t%0,32\n\t"
+#endif
+#ifdef __MIPSEB__
+#error "Fix this for big endian"
+#endif /* __MIPSEB__ */
X "li\t%1,1\n"
- "1:\tand\t%4,$1,%1\n\t"
- "beq\t$0,%4,2f\n\t"
+ "1:\tand\t%2,$1,%1\n\t"
+ "beqz\t%2,2f\n\t"
X "sll\t%1,%1,1\n\t"
- "bne\t$0,%1,1b\n\t"


+ "bnez\t%1,1b\n\t"

X "add\t%0,%0,1\n\t"
X ".set\tat\n\t"
X ".set\treorder\n"
X "2:"
- : "=r" (res)
- : "r" ((unsigned int) 0xffffffff),
- "r" (size),
- "0" ((signed int) 0),
- "r" (addr)
+ : "=r" (res),
+ "=r" (dummy),
+ "=r" (addr)
+ : "0" ((signed int) 0),
+ "1" ((unsigned int) 0xffffffff),
+ "2" (addr),
+ "r" (size)
X : "$1");
X
X return res;
@@ -185,26 +300,32 @@
X
X extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
X {
- unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
+ unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
X int set = 0, bit = offset & 31, res;
+ unsigned long dummy;
X
X if (bit) {
X /*
X * Look for zero in first byte
X */
+#ifdef __MIPSEB__
+#error "Fix this for big endian byte order"
+#endif
X __asm__(".set\tnoreorder\n\t"
X ".set\tnoat\n"
- "1:\tand\t$1,%2,%1\n\t"
- "beq\t$0,$1,2f\n\t"
- "sll\t%2,%2,1\n\t"
- "bne\t$0,%2,1b\n\t"
- "addiu\t%0,%0,1\n\t"
+ "1:\tand\t$1,%4,%1\n\t"
+ "beqz\t$1,1f\n\t"
+ "sll\t%1,%1,1\n\t"


+ "bnez\t%1,1b\n\t"

+ "addiu\t%0,1\n\t"
X ".set\tat\n\t"
X ".set\treorder\n"
- : "=r" (set)
- : "r" (*p >> bit),
- "r" (1),
- "0" (0)
+ "1:"
+ : "=r" (set),
+ "=r" (dummy)
+ : "0" (0),
+ "1" (1 << bit),
+ "r" (*p)
X : "$1");
X if (set < (32 - bit))
X return set + offset;
@@ -214,10 +335,12 @@
X /*
X * No zero yet, search remaining full bytes for a zero
X */
- res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
- return (offset + set + res);
+ res = find_first_zero_bit(p, size - 32 * (p - (unsigned int *) addr));
+ return offset + set + res;
X }
X
+#endif /* !(__MIPSEB__) */
+
X /*
X * ffz = Find First Zero in word. Undefined if no zero exists,
X * so code should check against ~0UL first..
@@ -227,7 +350,7 @@
X unsigned int __res;
X unsigned int mask = 1;


X
- __asm__ __volatile__ (

+ __asm__ (
X ".set\tnoreorder\n\t"
X ".set\tnoat\n\t"
X "move\t%0,$0\n"
@@ -239,11 +362,183 @@
X ".set\tat\n\t"
X ".set\treorder\n"
X "2:\n\t"
- : "=r" (__res), "=r" (mask)
+ : "=&r" (__res), "=r" (mask)
X : "r" (word), "1" (mask)
X : "$1");
X
X return __res;
X }
+
+#ifdef __MIPSEB__
+/* For now I steal the Sparc C versions, no need for speed, just need to
+ * get it working.
+ */
+/* find_next_zero_bit() finds the first zero bit in a bit string of length
+ * 'size' bits, starting the search at bit 'offset'. This is largely based
+ * on Linus's ALPHA routines, which are pretty portable BTW.
+ */
+
+extern __inline__ int find_next_zero_bit(void *addr, int size, int offset)
+{
+ unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+ unsigned long result = offset & ~31UL;


+ unsigned long tmp;
+

+ if (offset >= size)
+ return size;
+ size -= result;
+ offset &= 31UL;
+ if (offset) {
+ tmp = *(p++);
+ tmp |= ~0UL >> (32-offset);
+ if (size < 32)
+ goto found_first;
+ if (~tmp)
+ goto found_middle;
+ size -= 32;
+ result += 32;
+ }
+ while (size & ~31UL) {
+ if (~(tmp = *(p++)))
+ goto found_middle;
+ result += 32;
+ size -= 32;
+ }
+ if (!size)
+ return result;
+ tmp = *p;
+
+found_first:
+ tmp |= ~0UL << size;
+found_middle:
+ return result + ffz(tmp);
+}
+
+/* Linus sez that gcc can optimize the following correctly, we'll see if this
+ * holds on the Sparc as it does for the ALPHA.
+ */
+
+#define find_first_zero_bit(addr, size) \
+ find_next_zero_bit((addr), (size), 0)
+
+#endif /* (__MIPSEB__) */
+
+/* Now for the ext2 filesystem bit operations and helper routines. */
+
+#ifdef __MIPSEB__
+extern __inline__ int ext2_set_bit(int nr,void * addr)
+{
+ int mask, retval, flags;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ save_flags(flags); cli();
+ retval = (mask & *ADDR) != 0;
+ *ADDR |= mask;
+ restore_flags(flags);


+ return retval;
+}
+

+extern __inline__ int ext2_clear_bit(int nr, void * addr)
+{
+ int mask, retval, flags;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ save_flags(flags); cli();
+ retval = (mask & *ADDR) != 0;
+ *ADDR &= ~mask;
+ restore_flags(flags);


+ return retval;
+}
+

+extern __inline__ int ext2_test_bit(int nr, const void * addr)
+{
+ int mask;
+ const unsigned char *ADDR = (const unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ return ((mask & *ADDR) != 0);
+}
+
+#define ext2_find_first_zero_bit(addr, size) \
+ ext2_find_next_zero_bit((addr), (size), 0)
+
+static __inline__ unsigned long __swab32(unsigned long val)
+{
+ return ((val>>24)|((val>>8)&0xff00)|((val<<8)&0xff0000)|(val<<24));
+}
+
+extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+ unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+ unsigned long result = offset & ~31UL;


+ unsigned long tmp;
+

+ if (offset >= size)
+ return size;
+ size -= result;
+ offset &= 31UL;
+ if(offset) {
+ /* We hold the little endian value in tmp, but then the
+ * shift is illegal. So we could keep a big endian value
+ * in tmp, like this:
+ *
+ * tmp = __swab32(*(p++));
+ * tmp |= ~0UL >> (32-offset);
+ *
+ * but this would decrease preformance, so we change the
+ * shift:
+ */
+ tmp = *(p++);
+ tmp |= __swab32(~0UL >> (32-offset));
+ if(size < 32)
+ goto found_first;
+ if(~tmp)
+ goto found_middle;
+ size -= 32;
+ result += 32;
+ }
+ while(size & ~31UL) {
+ if(~(tmp = *(p++)))
+ goto found_middle;
+ result += 32;
+ size -= 32;
+ }
+ if(!size)
+ return result;
+ tmp = *p;
+
+found_first:
+ /* tmp is little endian, so we would have to swab the shift,
+ * see above. But then we have to swab tmp below for ffz, so
+ * we might as well do this here.
+ */
+ return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+ return result + ffz(__swab32(tmp));
+}
+#else /* !(__MIPSEB__) */
+
+/* Native ext2 byte ordering, just collapse using defines. */
+#define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr))
+#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr), (addr))
+#define ext2_test_bit(nr, addr) test_bit((nr), (addr))
+#define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size))
+#define ext2_find_next_zero_bit(addr, size, offset) \
+ find_next_zero_bit((addr), (size), (offset))
+
+/*
+ * Bitmap functions for the minix filesystem.
+ * FIXME: These assume that Minix uses the native byte/bitorder.
+ */
+#define minix_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+#endif /* __KERNEL__ */
X
X #endif /* __ASM_MIPS_BITOPS_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/bootinfo.h linux/include/asm-mips/bootinfo.h
--- v2.1.43/linux/include/asm-mips/bootinfo.h Sat May 24 09:10:25 1997
+++ linux/include/asm-mips/bootinfo.h Thu Jun 26 12:33:39 1997
@@ -1,11 +1,8 @@
X /*
X * bootinfo.h -- Definition of the Linux/MIPS boot information structure
X *
- * Copyright (C) 1994 by Waldorf Electronics
- * Written by Ralf Baechle and Andreas Busse
- *
- * Based on Linux/68k linux/include/linux/bootstrap.h
- * Copyright (C) 1992 by Greg Harp
+ * Copyright (C) 1995, 1996 by Ralf Baechle, Andreas Busse,
+ * Stoned Elipot and Paul M. Antoine.
X *
X * This file is subject to the terms and conditions of the GNU General Public
X * License. See the file COPYING in the main directory of this archive
@@ -14,19 +11,95 @@
X #ifndef __ASM_MIPS_BOOTINFO_H
X #define __ASM_MIPS_BOOTINFO_H
X
+/* XXX */
+#include <linux/config.h>
+
+#if 0
X /*
X * Valid machtype values
+ * FIXME: note that we really need a hierarchy for this stuff, as there are
+ * several models of DECStation (for example). PMA
+ */
+#define MACH_UNKNOWN 0 /* whatever... */
+#define MACH_DESKSTATION_RPC44 1 /* Deskstation rPC44 */
+#define MACH_DESKSTATION_TYNE 2 /* Deskstation Tyne */
+#define MACH_ACER_PICA_61 3 /* Acer PICA-61 (PICA1) */
+#define MACH_MIPS_MAGNUM_4000 4 /* Mips Magnum 4000 "RC4030" */
+#define MACH_OLIVETTI_M700 4 /* almost a clone ... */
+#define MACH_DECSTATION 5 /* DECStation 5000/2x for now */
+#define MACH_SNI_RM200_PCI 6 /* RM200/RM300/RM400 PCI series */
+#define MACH_SGI_INDY 7 /* R4?K and R5K Indy workstaions */
+#define MACH_LAST 7
+
+#define MACH_NAMES {"unknown", "Deskstation rPC44", "Deskstation Tyne", \
+ "Acer PICA 61", "Mips Magnum 4000", "DECStation", "RM200 PCI", \
+ "SGI INDY" }
+#endif
+
+/*
+ * Values for machgroup
+ */
+#define MACH_GROUP_UNKNOWN 0 /* whatever... */
+#define MACH_GROUP_JAZZ 1 /* Jazz */
+#define MACH_GROUP_DEC 2 /* Digital Equipment */
+#define MACH_GROUP_ARC 3 /* Wreckstation Tyne, rPC44, possibly other */
+#define MACH_GROUP_SNI_RM 4 /* Siemens Nixdorf RM series */
+#define MACH_GROUP_ACN 5
+#define MACH_GROUP_SGI 6 /* Silicon Graphics workstations and servers */
+
+#define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", "SNI", "ACN" }
+
+/*
+ * Valid machtype values for group unknown (low order halfword of mips_machtype)
+ */
+#define MACH_UNKNOWN 0 /* whatever... */
+
+#define GROUP_UNKNOWN_NAMES { "unknown" }
+
+/*
+ * Valid machtype values for group JAZZ
+ */
+#define MACH_ACER_PICA_61 0 /* Acer PICA-61 (PICA1) */
+#define MACH_MIPS_MAGNUM_4000 1 /* Mips Magnum 4000 "RC4030" */
+#define MACH_OLIVETTI_M700 2 /* Olivetti M700-10 (-15 ??) */
+
+#define GROUP_JAZZ_NAMES { "Acer PICA 61", "Mips Magnum 4000", "Olivetti M700" }
+
+/*
+ * Valid machtype for group DEC
+ */
+/* FIXME: this is a very fuzzy name, and we got a big "name space now" */
+/* So otiginal DEC codes can be used -Stoned */
+#define MACH_DECSTATION 0 /* DECStation 5000/2x for now */
+
+#define GROUP_DEC_NAMES { "3min" }
+
+/*
+ * Valid machtype for group ARC
X */
-#define MACH_UNKNOWN 0 /* whatever... */
-#define MACH_DESKSTATION_RPC44 1 /* Deskstation rPC44 */
-#define MACH_DESKSTATION_TYNE 2 /* Deskstation Tyne */
-#define MACH_ACER_PICA_61 3 /* Acer PICA-61 (PICA1) */
-#define MACH_MIPS_MAGNUM_4000 4 /* Mips Magnum 4000 "RC4030" */
-#define MACH_OLIVETTI_M700 5 /* Olivetti M700 */
-#define MACH_LAST 5
+#define MACH_DESKSTATION_RPC44 0 /* Deskstation rPC44 */
+#define MACH_DESKSTATION_TYNE 1 /* Deskstation Tyne */
X
-#define MACH_NAMES { "unknown", "Deskstation rPC44", "Deskstation Tyne", \
- "Acer PICA 61", "Mips Magnum 4000", "Olivetti M700" }
+#define GROUP_ARC_NAMES { "Deskstation rPC44", "Deskstation Tyne" }
+
+/*
+ * Valid machtype for group SNI_RM
+ */
+#define MACH_SNI_RM200_PCI 0 /* RM200/RM300/RM400 PCI series */
+
+#define GROUP_SNI_RM_NAMES { "RM200 PCI" }
+
+/*
+ * Valid machtype for group ACN
+ */
+#define MACH_ACN_MIPS_BOARD 0 /* ACN MIPS single board */
+
+#define GROUP_ACN_NAMES { "ACN" }
+
+/*
+ * Valid machtype for group SGI
+ */
+#define MACH_SGI_INDY 0 /* R4?K and R5K Indy workstaions */
X
X /*
X * Valid cputype values
@@ -52,200 +125,191 @@
X #define CPU_R6000A 18
X #define CPU_R8000 19
X #define CPU_R10000 20
-#define CPU_LAST 20
+#define CPU_R4300 21
+#define CPU_R4650 22
+#define CPU_R4700 23
+#define CPU_R5000 24
+#define CPU_R5000A 25
+#define CPU_R4640 26
+#define CPU_LAST 27
X
X #define CPU_NAMES { "unknown", "R2000", "R3000", "R3000A", "R3041", "R3051", \
X "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC", \
X "R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000", \
- "R6000A", "R8000", "R10000" }
+ "R6000A", "R8000", "R10000", "R4300", "R4650", "R4700", "R5000", \
+ "R5000A", "R4640" }
X
X #define CL_SIZE (80)
X
X #ifndef __LANGUAGE_ASSEMBLY__
X
X /*
- * Some machine parameters passed by MILO. Note that bootinfo
- * *must* be in the data segment since the kernel clears the
- * bss segment directly after startup.
+ * Some machine parameters passed by the bootloaders.
X */
X
X struct drive_info_struct {
X char dummy[32];
- };
-
-struct bootinfo {
- /*
- * machine type
- */
- unsigned long machtype;
-
- /*
- * system CPU & FPU
- */
- unsigned long cputype;
-
- /*
- * Installed RAM
- */
- unsigned long memlower;
- unsigned long memupper;
-
- /*
- * Cache Sizes (0xffffffff = unknown)
- */
- unsigned long icache_size;
- unsigned long icache_linesize;
- unsigned long dcache_size;
- unsigned long dcache_linesize;
- unsigned long scache_size;
- unsigned long scache_linesize;
-
- /*
- * TLB Info
- */
- unsigned long tlb_entries;
-
- /*
- * DMA buffer size (Deskstation only)
- */
- unsigned long dma_cache_size;
- unsigned long dma_cache_base;
-
- /*
- * Ramdisk Info
- */
- unsigned long ramdisk_flags; /* ramdisk flags */
- unsigned long ramdisk_base; /* address of the ram disk in mem */
-
- /*
- * Boot flags for the kernel
- */
- unsigned long mount_root_rdonly;
- struct drive_info_struct drive_info;
-
- /*
- * Video ram info (not in tty.h)
- */
- unsigned long vram_base; /* video ram base address */
-
- char command_line[CL_SIZE]; /* kernel command line parameters */
-
X };
X
-#if 0
+/* This is the same as in Milo but renamed for the sake of kernel's */
+/* namespace */
+typedef struct mips_arc_DisplayInfo { /* video adapter information */
+ unsigned short cursor_x;
+ unsigned short cursor_y;
+ unsigned short columns;
+ unsigned short lines;
+} mips_arc_DisplayInfo;
+
X /*
X * New style bootinfo
X *
X * Add new tags only at the end of the enum; *never* remove any tags
X * or you'll break compatibility!
X */
-enum bi_tag {
- /*
- * not a real tag
- */
- dummy,
+enum bi_tag {
+ /*
+ * not a real tag
+ */
+ tag_dummy,
+
+ /*
+ * machine type
+ */
+ tag_machtype,
+
+ /*
+ * system CPU & FPU
+ */
+ tag_cputype,
+
+ /*
+ * Installed RAM
+ */
+ tag_memlower,
+ tag_memupper,
+
+ /*
+ * Cache Sizes (0xffffffff = unknown)
+ */
+ tag_icache_size,
+ tag_icache_linesize,
+ tag_dcache_size,
+ tag_dcache_linesize,
+ tag_scache_size,
+ tag_scache_linesize,
+
+ /*
+ * TLB Info
+ */
+ tag_tlb_entries,
+
+ /*
+ * DMA buffer size (Deskstation only)
+ */
+ tag_dma_cache_size,
+ tag_dma_cache_base,
+
+ /*
+ * Ramdisk Info
+ */
+ tag_ramdisk_size, /* ramdisk size in 1024 byte blocks */
+ tag_ramdisk_base, /* address of the ram disk in mem */
+
+ /*
+ * Boot flags for the kernel
+ */
+ tag_mount_root_rdonly,
+ tag_drive_info,
+
+ /*
+ * Video ram info (not in tty.h)
+ */
+ tag_vram_base, /* video ram base address */
+
+ tag_command_line, /* kernel command line parameters */
+
+ /*
+ * machine group
+ */
+ tag_machgroup,
X
X /*
- * machine type
+ * info on the display from the ARC BIOS
X */
- machtype,
+ tag_arcdisplayinfo,
X
X /*
- * system CPU & FPU
+ * tag to pass a complete struct screen_info
X */
- cputype,
+ tag_screen_info
+};
X
- /*
- * Installed RAM
- */
- memlower,
- memupper,
+/* struct defining a tag */
+typedef struct {
+ enum bi_tag tag;
+ unsigned long size;
+} tag;
X
- /*
- * Cache Sizes (0xffffffff = unknown)
- */
- icache_size,
- icache_linesize,
- dcache_size,
- dcache_linesize,
- scache_size,
- scache_linesize,
+/* struct to define a tag and it's data */
+typedef struct {
+ tag t;
+ void* d;
+} tag_def;
+
+/* macros for parsing tag list */
+#define TAGVALPTR(t) ((void*)(((void*)(t)) - ((t)->size)))
+#define NEXTTAGPTR(t) ((void*)(TAGVALPTR(t) - (sizeof(tag))))
+
+/* size macros for tag size field */
+#define UCHARSIZE (sizeof(unsigned char))
+#define ULONGSIZE (sizeof(unsigned long))
+#define UINTSIZE (sizeof(unsigned int))
+#define DRVINFOSIZE (sizeof(struct drive_info_struct))
+#define CMDLINESIZE (sizeof(char[CL_SIZE])
X
- /*
- * TLB Info
- */
- tlb_entries,
+/*
+ * For tag readers aka the kernel
+ */
+tag *bi_TagFind(enum bi_tag type);
+void bi_EarlySnarf(void);
X
- /*
- * DMA buffer size (Deskstation only)
- */
- dma_cache_size,
- dma_cache_base,
+/* For tag creators aka bootloaders */
+/* Now implemented in Milo 0.26 */
+int bi_TagAdd(enum bi_tag type, unsigned long size, void *data);
+int bi_TagAddList(tag_def* taglist);
+void bi_TagWalk(void);
X
- /*
- * Ramdisk Info
- */
- ramdisk_size, /* ramdisk size in 1024 byte blocks */
- ramdisk_base, /* address of the ram disk in mem */
X
- /*
- * Boot flags for the kernel
- */
- mount_root_rdonly,
- drive_info,
+#ifdef CONFIG_SGI
X
- /*
- * Video ram info (not in tty.h)
- */
- vram_base, /* video ram base address */
-
- command_line /* kernel command line parameters */
-
-};
+/* screen info will dissapear... soon */
+#define DEFAULT_SCREEN_INFO {0, 0, {0, 0, }, 0, 0, 158, 0, 0, 0, 62, 0, 16}
+#define DEFAULT_DRIVE_INFO { {0,}}
+
+#else
+
+/* default values for screen_info variable */
+#define DEFAULT_SCREEN_INFO {0, 0, {0, }, 52, 3, 80, 4626, 3, 9, 50}
+/* default values for drive info */
+#define DEFAULT_DRIVE_INFO { {0,}}
X
-typedef struct {
- bi_tag tag;
- unsigned long size;
-} tag;
X #endif
X
-extern struct bootinfo boot_info;
X
X /*
- * Defaults, may be overwritten by milo. We initialize
- * them to make sure that both boot_info and screen_info
- * are in the .data segment since the .bss segment is
- * cleared during startup.
- */
-#define BOOT_INFO { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, {{0,}}, 0, "" }
-#define SCREEN_INFO {0, 0, {0, }, 52, 3, 80, 4626, 3, 9, 50}
-
-#else /* !__LANGUAGE_ASSEMBLY__ */
-
-/*
- * Same structure, but as offsets for usage within assembler source.
- * Don't mess with struct bootinfo without changing offsets too!
- */
-
-#define OFFSET_BOOTINFO_MACHTYPE 0
-#define OFFSET_BOOTINFO_CPUTYPE 4
-#define OFFSET_BOOTINFO_MEMLOWER 8
-#define OFFSET_BOOTINFO_MEMUPPER 12
-#define OFFSET_BOOTINFO_ICACHE_SIZE 16
-#define OFFSET_BOOTINFO_ICACHE_LINESIZE 20
-#define OFFSET_BOOTINFO_DCACHE_SIZE 24
-#define OFFSET_BOOTINFO_DCACHE_LINESIZE 28
-#define OFFSET_BOOTINFO_SCACHE_SIZE 32
-#define OFFSET_BOOTINFO_SCACHE_LINESIZE 36
-#define OFFSET_BOOTINFO_TLB_ENTRIES 40
-#define OFFSET_BOOTINFO_DMA_CACHE_SIZE 44
-#define OFFSET_BOOTINFO_DMA_CACHE_BASE 48
-#define OFFSET_BOOTINFO_RAMDISK_SIZE 52
-#define OFFSET_BOOTINFO_RAMDISK_BASE 56
-#define OFFSET_BOOTINFO_MOUNT_RD_ONLY 60
-#define OFFSET_BOOTINFO_DRIVE_INFO 64
-#define OFFSET_BOOTINFO_VRAM_BASE 96
-#define OFFSET_BOOTINFO_COMMAND_LINE 100
+ * These are the kernel variables initialized from
+ * the tag. And they have to be initialized to dummy/default
+ * values in setup.c (or whereever suitable) so they are in
+ * .data section
+ */
+extern unsigned long mips_memory_upper;
+extern unsigned long mips_cputype;
+extern unsigned long mips_machtype;
+extern unsigned long mips_machgroup;
+extern unsigned long mips_tlb_entries;
+extern unsigned long mips_vram_base;
+extern unsigned long mips_dma_cache_size;
+extern unsigned long mips_dma_cache_base;
X
X #endif /* __LANGUAGE_ASSEMBLY__ */
X
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/branch.h linux/include/asm-mips/branch.h
--- v2.1.43/linux/include/asm-mips/branch.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/branch.h Thu Jun 26 12:33:39 1997


@@ -0,0 +1,26 @@
+/*

+ * Branch and jump emulation.
+ *


+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.

+ *


+ * Copyright (C) 1996, 1997 by Ralf Baechle
+ */
+#include <asm/ptrace.h>
+

+extern inline int delay_slot(struct pt_regs *regs)
+{
+ return regs->cp0_cause & CAUSEF_BD;
+}
+
+extern int __compute_return_epc(struct pt_regs *regs);
+extern inline int compute_return_epc(struct pt_regs *regs)
+{
+ if (delay_slot(regs)) {
+ return __compute_return_epc(regs);
+ }
+
+ regs->cp0_epc += 4;
+ return 0;
+}
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/bugs.h linux/include/asm-mips/bugs.h
--- v2.1.43/linux/include/asm-mips/bugs.h Sun Jan 15 14:54:27 1995
+++ linux/include/asm-mips/bugs.h Thu Jun 26 12:33:39 1997
@@ -13,14 +13,15 @@
X * void check_bugs(void);
X */
X
-extern struct bootinfo boot_info;
X
X static void check_wait(void)
X {
X printk("Checking for 'wait' instruction... ");
- switch(boot_info.cputype) {
+ switch(mips_cputype) {
X case CPU_R4200:
+ case CPU_R4300:
X case CPU_R4600:
+ case CPU_R5000:
X wait_available = 1;
X printk(" available.\n");
X break;
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/byteorder.h linux/include/asm-mips/byteorder.h
--- v2.1.43/linux/include/asm-mips/byteorder.h Wed Dec 13 02:39:45 1995
+++ linux/include/asm-mips/byteorder.h Mon Jul 7 08:18:55 1997
@@ -1,91 +1,175 @@
+/*
+ * Functions depending of the byteorder.
+ *


+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.

+ *
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ *
+ * $Id: byteorder.h,v 1.5 1997/06/25 19:10:18 ralf Exp $
+ */
X #ifndef __ASM_MIPS_BYTEORDER_H
X #define __ASM_MIPS_BYTEORDER_H
X
+#define __swap32(x) \
+ ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
+ (((unsigned long int)(x) & 0x0000ff00U) << 8) | \
+ (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
+ (((unsigned long int)(x) & 0xff000000U) >> 24)))
+#define __swap16(x) \
+ ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
+ (((unsigned short int)(x) & 0xff00) >> 8)))
+
+#if defined (__MIPSEB__)
+
+#ifndef __BIG_ENDIAN
+#define __BIG_ENDIAN
+#endif
+
+#ifndef __BIG_ENDIAN_BITFIELD
+#define __BIG_ENDIAN_BITFIELD
+#endif
+
+#define __constant_ntohl(x) (x)
+#define __constant_ntohs(x) (x)
+#define __constant_htonl(x) (x)
+#define __constant_htons(x) (x)
+
+#ifdef __KERNEL__
+
X /*
- * FIXME: Add big endian support
+ * In-kernel byte order macros to handle stuff like
+ * byte-order-dependent filesystems etc.
X */
-#undef ntohl
-#undef ntohs
-#undef htonl
-#undef htons
+#define cpu_to_le32(x) __swap32((x))
+#define le32_to_cpu(x) __swap32((x))
+#define cpu_to_le16(x) __swap16((x))
+#define le16_to_cpu(x) __swap16((x))
+
+#define cpu_to_be32(x) (x)
+#define be32_to_cpu(x) (x)
+#define cpu_to_be16(x) (x)
+#define be16_to_cpu(x) (x)
X
-#if defined (__MIPSEL__)
+#endif /* __KERNEL__ */
+
+#elif defined (__MIPSEL__)
+
+#ifndef __LITTLE_ENDIAN
X #define __LITTLE_ENDIAN
+#endif
+
+#ifndef __LITTLE_ENDIAN_BITFIELD
X #define __LITTLE_ENDIAN_BITFIELD
-#elif defined (__MIPSEB__)
-#define __BIG_ENDIAN
-#define __BIG_ENDIAN_BITFIELD
-#else
-#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
X #endif
X
-extern unsigned long int ntohl(unsigned long int);
-extern unsigned short int ntohs(unsigned short int);
-extern unsigned long int htonl(unsigned long int);
-extern unsigned short int htons(unsigned short int);
-
-extern __inline__ unsigned long int __ntohl(unsigned long int);
-extern __inline__ unsigned short int __ntohs(unsigned short int);
-extern __inline__ unsigned long int __constant_ntohl(unsigned long int);
-extern __inline__ unsigned short int __constant_ntohs(unsigned short int);
+#define __constant_ntohl(x) __swap32(x)
+#define __constant_ntohs(x) __swap16(x)
+#define __constant_htonl(x) __swap32(x)
+#define __constant_htons(x) __swap16(x)
+
+#ifdef __KERNEL__
X
X /*
- * The constant and non-constant versions here are the same.
- * Maybe I'll come up with an mips-optimized routine for the
- * non-constant ones (the constant ones don't need it: gcc
- * will optimize it to the correct constant). Oh, and the
- * big endian routines that are still missing will be fairly
- * easy to write :-)
+ * In-kernel byte order macros to handle stuff like
+ * byte-order-dependent filesystems etc.
X */
+#define cpu_to_le32(x) (x)
+#define le32_to_cpu(x) (x)
+#define cpu_to_le16(x) (x)
+#define le16_to_cpu(x) (x)
+
+#define cpu_to_be32(x) __swap32((x))
+#define be32_to_cpu(x) __swap32((x))
+#define cpu_to_be16(x) __swap16((x))
+#define be16_to_cpu(x) __swap16((x))
X
-extern __inline__ unsigned long int
-__ntohl(unsigned long int x)
+#endif /* __KERNEL__ */
+
+#else
+#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
+#endif
+
+/* The same, but returns converted value from the location pointer by addr. */
+extern __inline__ __u16 cpu_to_le16p(__u16 *addr)
X {
- return (((x & 0x000000ffU) << 24) |
- ((x & 0x0000ff00U) << 8) |
- ((x & 0x00ff0000U) >> 8) |
- ((x & 0xff000000U) >> 24));
+ return cpu_to_le16(*addr);
X }
X
-#define __constant_ntohl(x) \
- ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
- (((unsigned long int)(x) & 0x0000ff00U) << 8) | \
- (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
- (((unsigned long int)(x) & 0xff000000U) >> 24)))
+extern __inline__ __u32 cpu_to_le32p(__u32 *addr)
+{
+ return cpu_to_le32(*addr);
+}
X
-extern __inline__ unsigned short int
-__ntohs(unsigned short int x)
+extern __inline__ __u16 cpu_to_be16p(__u16 *addr)
X {
- return (((x & 0x00ff) << 8) |
- ((x & 0xff00) >> 8));
+ return cpu_to_be16(*addr);
X }
X
-#define __constant_ntohs(x) \
- ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
- (((unsigned short int)(x) & 0xff00) >> 8))) \
+extern __inline__ __u32 cpu_to_be32p(__u32 *addr)
+{
+ return cpu_to_be32(*addr);
+}
X
-#define __htonl(x) __ntohl(x)
-#define __htons(x) __ntohs(x)
-#define __constant_htonl(x) __constant_ntohl(x)
-#define __constant_htons(x) __constant_ntohs(x)
-
-#ifdef __OPTIMIZE__
-# define ntohl(x) \
-(__builtin_constant_p((long)(x)) ? \
- __constant_ntohl((x)) : \
- __ntohl((x)))
-# define ntohs(x) \
-(__builtin_constant_p((short)(x)) ? \
- __constant_ntohs((x)) : \
- __ntohs((x)))
-# define htonl(x) \
-(__builtin_constant_p((long)(x)) ? \
- __constant_htonl((x)) : \
- __htonl((x)))
-# define htons(x) \
-(__builtin_constant_p((short)(x)) ? \
- __constant_htons((x)) : \
- __htons((x)))
-#endif
+#define le16_to_cpup(x) cpu_to_le16p(x)
+#define le32_to_cpup(x) cpu_to_le32p(x)
+#define be16_to_cpup(x) cpu_to_be16p(x)
+#define be32_to_cpup(x) cpu_to_be32p(x)
+
+
+/* The same, but do the conversion in situ, ie. put the value back to addr. */
+extern __inline__ void cpu_to_le16s(__u16 *addr)
+{
+ *addr = cpu_to_le16(*addr);
+}
+
+extern __inline__ void cpu_to_le32s(__u32 *addr)
+{
+ *addr = cpu_to_le32(*addr);
+}
+
+extern __inline__ void cpu_to_be16s(__u16 *addr)
+{
+ *addr = cpu_to_be16(*addr);
+}
+
+extern __inline__ void cpu_to_be32s(__u32 *addr)
+{
+ *addr = cpu_to_be32(*addr);
+}
+
+#define le16_to_cpus(x) cpu_to_le16s(x)
+#define le32_to_cpus(x) cpu_to_le32s(x)
+#define be16_to_cpus(x) cpu_to_be16s(x)
+#define be32_to_cpus(x) cpu_to_be32s(x)
+
+#ifdef __KERNEL__
+extern unsigned long int ntohl(unsigned long int __x);
+extern unsigned short int ntohs(unsigned short int __x);
+extern unsigned short int htons(unsigned short int __x);
+extern unsigned long int htonl(unsigned long int __x);
+
+
+extern __inline__ unsigned long int ntohl(unsigned long int __x)
+{
+ return __constant_ntohl(__x);
+}
+
+extern __inline__ unsigned short int ntohs(unsigned short int __x)
+{
+ return __constant_ntohs(__x);
+}
+
+extern __inline__ unsigned long int htonl(unsigned long int __x)
+{
+ return __constant_htonl(__x);
+}
+
+extern __inline__ unsigned short int htons(unsigned short int __x)
+{
+ return __constant_htons(__x);
+}
+#endif /* __KERNEL__ */
X
X #endif /* __ASM_MIPS_BYTEORDER_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/cache.h linux/include/asm-mips/cache.h
--- v2.1.43/linux/include/asm-mips/cache.h Sun Jan 26 02:07:46 1997
+++ linux/include/asm-mips/cache.h Thu Jun 26 12:33:39 1997
@@ -1,12 +1,12 @@
X /*
X * include/asm-mips/cache.h
X */
-#ifndef __ARCH_MIPS_CACHE_H
-#define __ARCH_MIPS_CACHE_H
+#ifndef __ASM_MIPS_CACHE_H
+#define __ASM_MIPS_CACHE_H
X
X /* bytes per L1 cache line */
X #define L1_CACHE_BYTES 32 /* a guess */
X
X #define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
X
-#endif
+#endif /* __ASM_MIPS_CACHE_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/cachectl.h linux/include/asm-mips/cachectl.h
--- v2.1.43/linux/include/asm-mips/cachectl.h Wed Dec 13 02:39:45 1995
+++ linux/include/asm-mips/cachectl.h Thu Jun 26 12:33:39 1997
@@ -1,37 +1,24 @@
X /*
- * include/asm-mips/cachectl.h
+ * cachectl.h -- defines for MIPS cache control system calls
X *
- * Written by Ralf Baechle,
- * Copyright (C) 1994 by Waldorf GMBH
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle
X */
X #ifndef __ASM_MIPS_CACHECTL
X #define __ASM_MIPS_CACHECTL
X
X /*
- * cachectl.h -- defines for MIPS cache control system calls
- */
-
-/*
X * Options for cacheflush system call
X */
X #define ICACHE (1<<0) /* flush instruction cache */
X #define DCACHE (1<<1) /* writeback and flush data cache */
X #define BCACHE (ICACHE|DCACHE) /* flush both caches */
X
-#ifdef __KERNEL__
-#define CACHELINES 512 /* number of cachelines (kludgy) */
-
X /*
- * Cache Operations - for use by assembler code
+ * Caching modes for the cachectl(2) call
+ *
+ * cachctl(2) is currently not supported and returns ENOSYS.
X */
-#define Index_Invalidate_I 0x00
-#define Index_Writeback_Inv_D 0x01
-#define Index_Load_Tag_D 0x05
-
-#ifndef __LANGUAGE_ASSEMBLY__
-
-extern int sys_cacheflush(void *addr, int nbytes, int cache);
+#define CACHEABLE 0 /* make pages cacheable */
+#define UNCACHEABLE 1 /* make pages uncacheable */
X
-#endif /* !__LANGUAGE_ASSEMBLY__ */
-#endif /* __KERNEL__ */
X #endif /* __ASM_MIPS_CACHECTL */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/cacheops.h linux/include/asm-mips/cacheops.h
--- v2.1.43/linux/include/asm-mips/cacheops.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/cacheops.h Thu Jun 26 12:33:39 1997
@@ -0,0 +1,47 @@
+/*
+ * Cache operations for the cache instruction.
+ *


+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * (C) Copyright 1996, 1997 by Ralf Baechle
+ */
+#ifndef __ASM_MIPS_CACHEOPS_H
+#define __ASM_MIPS_CACHEOPS_H
+
+/*
+ * Cache Operations
+ */
+#define Index_Invalidate_I 0x00
+#define Index_Writeback_Inv_D 0x01
+#define Index_Invalidate_SI 0x02
+#define Index_Writeback_Inv_SD 0x03
+#define Index_Load_Tag_I 0x04
+#define Index_Load_Tag_D 0x05
+#define Index_Load_Tag_SI 0x06
+#define Index_Load_Tag_SD 0x07
+#define Index_Store_Tag_I 0x08
+#define Index_Store_Tag_D 0x09
+#define Index_Store_Tag_SI 0x0A
+#define Index_Store_Tag_SD 0x0B
+#define Create_Dirty_Excl_D 0x0d
+#define Create_Dirty_Excl_SD 0x0f
+#define Hit_Invalidate_I 0x10
+#define Hit_Invalidate_D 0x11
+#define Hit_Invalidate_SI 0x12
+#define Hit_Invalidate_SD 0x13
+#define Fill 0x14
+#define Hit_Writeback_Inv_D 0x15
+ /* 0x16 is unused */
+#define Hit_Writeback_Inv_SD 0x17
+#define Hit_Writeback_I 0x18
+#define Hit_Writeback_D 0x19
+ /* 0x1a is unused */
+#define Hit_Writeback_SD 0x1b
+ /* 0x1c is unused */
+ /* 0x1e is unused */
+#define Hit_Set_Virtual_SI 0x1e
+#define Hit_Set_Virtual_SD 0x1f
+
+#endif /* __ASM_MIPS_CACHEOPS_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/checksum.h linux/include/asm-mips/checksum.h
--- v2.1.43/linux/include/asm-mips/checksum.h Sun Nov 3 01:04:41 1996
+++ linux/include/asm-mips/checksum.h Mon Jul 7 08:18:55 1997
@@ -31,15 +31,44 @@
X * here even more important to align src and dst on a 32-bit (or even
X * better 64-bit) boundary
X */
-unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
+unsigned int csum_partial_copy(const char *src, char *dst, int len, unsigned int sum);
X
X /*
- * the same as csum_partial, but copies from user space (but on the alpha
+ * the same as csum_partial, but copies from user space (but on MIPS
X * we have just one address space, so this is identical to the above)
+ *
+ * this is obsolete and will go away.
X */
X #define csum_partial_copy_fromuser csum_partial_copy
X
X /*
+ * this is a new version of the above that records errors it finds in *errp,
+ * but continues and zeros the rest of the buffer.
+ */
+unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len, unsigned int sum, int *errp);
+
+/*
+ * Fold a partial checksum without adding pseudo headers
+ */
+static inline unsigned short int csum_fold(unsigned int sum)
+{
+ __asm__("
+ .set noat
+ sll $1,%0,16
+ addu %0,$1
+ sltu $1,%0,$1
+ srl %0,%0,16
+ addu %0,$1
+ xori %0,0xffff
+ .set at"
+ : "=r" (sum)
+ : "0" (sum)
+ : "$1");
+
+ return sum;
+}
+
+/*
X * This is a version of ip_compute_csum() optimized for IP headers,
X * which always checksum on 4 octet boundaries.
X *
@@ -49,54 +78,48 @@
X static inline unsigned short ip_fast_csum(unsigned char * iph,
X unsigned int ihl)
X {
- unsigned short int sum;
- unsigned long dummy1, dummy2;
+ unsigned int sum;
+ unsigned long dummy;
X
X /*
- * This is optimized for 32-bit MIPS processors.
- * I tried it in plain C but the generated code looks to bad to
- * use with old first generation MIPS CPUs.
- * Using 64-bit code could even further improve these routines.
+ * This is for 32-bit MIPS processors.
X */
- __asm__("
+ __asm__ __volatile__("
X .set noreorder
X .set noat
- lw %0,(%3)
- subu %1,4
- blez %1,2f
- sll %1,%4,2 # delay slot
- lw %2,4(%3)
- addu %1,%3 # delay slot


- addu %0,%2
- sltu $1,%0,%2

- lw %2,8(%3)
+ lw %0,(%1)
+ subu %2,4
+ #blez %2,2f
+ sll %2,2 # delay slot
+
+ lw %3,4(%1)
+ addu %2,%1 # delay slot
+ addu %0,%3
+ sltu $1,%0,%3
+ lw %3,8(%1)
X addu %0,$1


- addu %0,%2
- sltu $1,%0,%2

- lw %2,12(%3)
+ addu %0,%3
+ sltu $1,%0,%3
+ lw %3,12(%1)
X addu %0,$1


- addu %0,%2
- sltu $1,%0,%2

+ addu %0,%3
+ sltu $1,%0,%3
X addu %0,$1
-1: lw %2,16(%3)
- addu %1,4


- addu %0,%2
- sltu $1,%0,%2

- bne %1,%3,1b
+
+1: lw %3,16(%1)
+ addiu %1,4
+ addu %0,%3
+ sltu $1,%0,%3
+ bne %2,%1,1b
X addu %0,$1 # delay slot
- srl $1,%0,16
- addu %0,$1
- sltu $1,%0,$1
- addu %0,$1
- nor %0,$0,%0
- andi %0,0xffff
+
X 2: .set at
X .set reorder"
- : "=r" (sum), "=r" (dummy1), "=r" (dummy2)
- : "r" (iph), "r"(ihl)
+ : "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (dummy)
+ : "1" (iph), "2" (ihl)
X : "$1");
X
- return sum;
+ return csum_fold(sum);
X }
X
X /*
@@ -114,66 +137,38 @@
X addu %0,%2
X sltu $1,%0,%2
X addu %0,$1
+
X addu %0,%3
X sltu $1,%0,%3
X addu %0,$1
+
X addu %0,%4
X sltu $1,%0,%4
X addu %0,$1
- srl $1,%0,16
- addu %0,$1
- sltu $1,%0,$1
- addu %0,$1
- nor %0,$0,%0
- andi %0,0xffff
X .set at"
X : "=r" (sum)
- : "0" (daddr), "r"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum)
+ : "0" (daddr), "r"(saddr),
+#ifdef __MIPSEL__
+ "r" ((ntohs(len)<<16)+proto*256),
+#else
+ "r" (((proto)<<16)+len),
+#endif
+ "r"(sum)
X : "$1");
X
- return (unsigned short)sum;
+ return csum_fold(sum);
X }
X
X /*
- * Fold a partial checksum without adding pseudo headers
- */
-static inline unsigned short int csum_fold(unsigned int sum)
-{
- __asm__("
- .set noat
- srl $1,%0,16
- addu %0,$1
- sltu $1,%0,$1
- nor %0,$0,%0
- andi %0,0xffff
- .set at"
- : "=r"(sum)
- : "0" (sum)
- : "$1");
-
- return sum;
-}
-
-/*
X * this routine is used for miscellaneous IP-like checksums, mainly
X * in icmp.c
X */
-static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
- unsigned short int sum;
-
- __asm__("
- .set noat
- srl $1,%0,16
- addu %0,$1
- sltu $1,%0,$1
- nor %0,$0,%0
- andi %0,0xffff
- .set at"
- : "=r"(sum)
- : "r" (csum_partial(buff, len, 0))
- : "$1");
+static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
+{
+ unsigned int sum;
X
- return sum;
+ sum = csum_partial(buff, len, 0);
+ return csum_fold(sum);
X }
X
X #define _HAVE_ARCH_IPV6_CSUM
@@ -183,9 +178,7 @@
X unsigned short proto,
X unsigned int sum)
X {
- unsigned long scratch;
-
- __asm__("
+ __asm__("
X .set noreorder
X .set noat
X addu %0,%5 # proto (long in network byte order)
@@ -234,14 +227,13 @@
X addu %0,%1
X sltu $1,%0,$1
X .set noat
- .set noreorder
- "
- : "=r" (sum),
- "=r" (scratch)
- : "r" (saddr),
+ .set noreorder"
+ : "=r" (sum),
+ "=r" (proto)
+ : "r" (saddr),
X "r" (daddr),
- "0" (htonl((__u32) (len))),
- "r" (htonl(proto)),
+ "0" (htonl((__u32) (len))),
+ "1" (htonl(proto)),
X "r"(sum)
X : "$1");
X
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/cpu.h linux/include/asm-mips/cpu.h
--- v2.1.43/linux/include/asm-mips/cpu.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/cpu.h Thu Jun 26 12:33:39 1997
@@ -0,0 +1,40 @@
+/* $Id: cpu.h,v 1.1 1997/06/06 09:38:41 ralf Exp $
+ * cpu.h: Values of the PRId register used to match up
+ * various MIPS cpu types.
+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+#ifndef _MIPS_CPU_H
+#define _MIPS_CPU_H
+
+/*
+ * Assigned values for the product ID register. In order to detect a
+ * certain CPU type exactly eventually additional registers may need to
+ * be examined.
+ */
+#define PRID_IMP_R2000 0x0100
+#define PRID_IMP_R3000 0x0200
+#define PRID_IMP_R6000 0x0300
+#define PRID_IMP_R4000 0x0400
+#define PRID_IMP_R6000A 0x0600
+#define PRID_IMP_R10000 0x0900
+#define PRID_IMP_R4300 0x0b00
+#define PRID_IMP_R8000 0x1000
+#define PRID_IMP_R4600 0x2000
+#define PRID_IMP_R4700 0x2100
+#define PRID_IMP_R4640 0x2200
+#define PRID_IMP_R4650 0x2200 /* Same as R4640 */
+#define PRID_IMP_R5000 0x2300
+#define PRID_IMP_SONIC 0x2400
+#define PRID_IMP_MAGIC 0x2500
+#define PRID_IMP_RM7000 0x2700
+#define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */
+
+#define PRID_IMP_UNKNOWN 0xff00
+
+#define PRID_REV_R4400 0x0040
+#define PRID_REV_R3000A 0x0030
+#define PRID_REV_R3000 0x0020
+#define PRID_REV_R2000A 0x0010
+
+#endif /* !(_MIPS_CPU_H) */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/current.h linux/include/asm-mips/current.h
--- v2.1.43/linux/include/asm-mips/current.h Mon Dec 30 01:58:35 1996
+++ linux/include/asm-mips/current.h Thu Jun 26 12:33:39 1997
@@ -1,12 +1,48 @@
-#ifndef _MIPS_CURRENT_H
-#define _MIPS_CURRENT_H
+#ifndef __ASM_MIPS_CURRENT_H
+#define __ASM_MIPS_CURRENT_H
X
-/* Some architectures may want to do something "clever" here since
- * this is the most frequently accessed piece of data in the entire
- * kernel. For an example, see the Sparc implementation where an
- * entire register is hard locked to contain the value of current.
+#ifdef __LANGUAGE_C__
+
+static inline struct task_struct *__get_current(void)
+{
+ struct task_struct *__current;
+
+ __asm__("ori\t%0,$29,%1\n\t"
+ "xori\t%0,%1"
+ :"=r" (__current)
+ :"ir" (8191UL));
+
+ return __current;
+}
+
+#define current __get_current()
+
+#endif /* __LANGUAGE_C__ */
+#ifdef __LANGUAGE_ASSEMBLY__
+
+/*
+ * Get current task pointer
+ */
+#define GET_CURRENT(reg) \
+ lui reg, %hi(kernelsp); \
+ lw reg, %lo(kernelsp)(reg); \
+ ori reg, 8191; \
+ xori reg, 8191
+
+/*
+ * Special variant for use by exception handlers when the stack pointer
+ * is not loaded.
X */
-extern struct task_struct *current_set[NR_CPUS];
-#define current (current_set[smp_processor_id()]) /* Current on this processor */
+#define _GET_CURRENT(reg) \
+ lui reg, %hi(kernelsp); \
+ .set push; \
+ .set noreorder; \
+ lw reg, %lo(kernelsp)(reg); \
+ .set pop; \
+ ori reg, 8191; \
+ xori reg, 8191
+
+
+#endif
X
-#endif /* !(_MIPS_CURRENT_H) */
+#endif /* __ASM_MIPS_CURRENT_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/decstation.h linux/include/asm-mips/decstation.h
--- v2.1.43/linux/include/asm-mips/decstation.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/decstation.h Thu Jun 26 12:33:39 1997
@@ -0,0 +1,254 @@
+/*
+ * Hardware info about DEC Personal DECStation systems (otherwise known
+ * as maxine or pmax (internal DEC codenames).
+ *


+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.

+ *
+ * Copyright (C) 1995 by Paul M. Antoine, some code and definitions are
+ * by curteousy of Chris Fraser.
+ *
+ * This file is under construction - you were warned!
+ */
+
+#ifndef __ASM_MIPS_PMAX_H
+#define __ASM_MIPS_PMAX_H
+
+/*
+ * The addresses below are virtual address. The mappings are
+ * created on startup via wired entries in the tlb.
+ */
+
+#define PMAX_LOCAL_IO_SPACE 0xe0000000
+
+/*
+ * Motherboard regs (kseg1 addresses)
+ */
+#define PMAX_SSR_ADDR 0xbc040100 /* system support reg */
+
+/*
+ * SSR defines
+ */
+#define PMAX_SSR_LEDMASK 0x00000001 /* power LED */
+
+/*
+ * REX functions -- these are for the new TURBOchannel style ROMs
+ */
+#define REX_PROM_MAGIC 0x30464354 /* passed in a2 */
+
+#define REX_GETBITMAP 0x84 /* get mem bitmap */
+#define REX_GETCHAR 0x24 /* getch() */
+#define REX_PUTCHAR 0x13 /* putch() */
+#define REX_HALT 0x9c /* halt the system */
+#define REX_PRINTF 0x30 /* printf() */
+#define REX_PUTS 0x2c /* puts() */
+#define REX_SLOTADDR 0x6c /* slotaddr */
+
+#ifndef __LANGUAGE_ASSEMBLY__
+
+extern __inline__ void pmax_set_led(unsigned int bits)
+{
+ volatile unsigned int *led_register = (unsigned int *) PMAX_SSR_ADDR;
+
+ *led_register = bits & PMAX_SSR_LEDMASK;
+}
+
+/*
+ * Glue code to call the PMAX boot proms.
+ */
+extern asmlinkage void pmax_printf(const char *);
+
+#endif
+
+/*
+ * These are just hacked out of the JAZZ ones, no ideas really.
+ */
+#define PMAX_KEYBOARD_ADDRESS 0xe0005000
+#define PMAX_KEYBOARD_DATA 0xe0005000
+#define PMAX_KEYBOARD_COMMAND 0xe0005001
+
+#ifndef __LANGUAGE_ASSEMBLY__
+
+typedef struct {
+ unsigned char data;
+ unsigned char command;
+} pmax_keyboard_hardware;
+
+typedef struct {
+ unsigned char pad0[3];
+ unsigned char data;
+ unsigned char pad1[3];
+ unsigned char command;
+} mips_keyboard_hardware;
+
+/*
+ * For now.
+ */
+#define keyboard_hardware pmax_keyboard_hardware
+
+#endif
+
+/*
+ * Serial ports on DEC - maybe!
+ */
+
+#define PMAX_SERIAL1_BASE (unsigned int)0xe0006000
+#define PMAX_SERIAL2_BASE (unsigned int)0xe0007000
+
+/*
+ * Dummy Device Address. Used in pmaxdma.c
+ */
+
+#define PMAX_DUMMY_DEVICE 0xe000d000
+
+/*
+ * PMAX timer registers and interrupt no.
+ * Note that the hardware timer interrupt is actually on
+ * cpu level 6, but to keep compatibility with PC stuff
+ * it is remapped to vector 0. See arch/mips/kernel/entry.S.
+ */
+#define PMAX_TIMER_INTERVAL 0xe0000228
+#define PMAX_TIMER_REGISTER 0xe0000230
+
+/*
+ * DRAM configuration register
+ */
+#ifndef __LANGUAGE_ASSEMBLY__
+#ifdef __MIPSEL__
+typedef struct {
+ unsigned int bank2 : 3;
+ unsigned int bank1 : 3;
+ unsigned int mem_bus_width : 1;
+ unsigned int reserved2 : 1;
+ unsigned int page_mode : 1;
+ unsigned int reserved1 : 23;
+} dram_configuration;
+#else /* defined (__MIPSEB__) */
+typedef struct {
+ unsigned int reserved1 : 23;
+ unsigned int page_mode : 1;
+ unsigned int reserved2 : 1;
+ unsigned int mem_bus_width : 1;
+ unsigned int bank1 : 3;
+ unsigned int bank2 : 3;
+} dram_configuration;
+#endif
+#endif /* __LANGUAGE_ASSEMBLY__ */
+
+#define PMAX_DRAM_CONFIG 0xe00fffe0
+
+/*
+ * PMAX interrupt control registers
+ */
+#define PMAX_IO_IRQ_SOURCE 0xe0100000
+#define PMAX_IO_IRQ_ENABLE 0xe0100002
+
+/*
+ * PMAX interrupt enable bits
+ */
+#define PMAX_IE_PARALLEL (1 << 0)
+#define PMAX_IE_FLOPPY (1 << 1)
+#define PMAX_IE_SOUND (1 << 2)
+#define PMAX_IE_VIDEO (1 << 3)
+#define PMAX_IE_ETHERNET (1 << 4)
+#define PMAX_IE_SCSI (1 << 5)
+#define PMAX_IE_KEYBOARD (1 << 6)
+#define PMAX_IE_MOUSE (1 << 7)
+#define PMAX_IE_SERIAL1 (1 << 8)
+#define PMAX_IE_SERIAL2 (1 << 9)
+
+/*
+ * PMAX Interrupt Level definitions
+ */
+
+#define PMAX_TIMER_IRQ 0
+#define PMAX_KEYBOARD_IRQ 1
+#define PMAX_ETHERNET_IRQ 2 /* 15 */
+#define PMAX_SERIAL1_IRQ 3
+#define PMAX_SERIAL2_IRQ 4
+#define PMAX_PARALLEL_IRQ 5
+#define PMAX_FLOPPY_IRQ 6 /* needs to be consistent with floppy driver! */
+
+/*
+ * PMAX DMA Channels
+ * Note: Channels 4...7 are not used with respect to the Acer PICA-61
+ * chipset which does not provide these DMA channels.
+ */
+
+#define PMAX_SCSI_DMA 0 /* SCSI */
+#define PMAX_FLOPPY_DMA 1 /* FLOPPY */
+#define PMAX_AUDIOL_DMA 2 /* AUDIO L */
+#define PMAX_AUDIOR_DMA 3 /* AUDIO R */
+
+/*
+ * PMAX R4030 MCT_ADR chip (DMA controller)
+ * Note: Virtual Addresses !
+ */
+
+#define PMAX_R4030_CONFIG 0xE0000000 /* R4030 config register */
+#define PMAX_R4030_REVISION 0xE0000008 /* same as PICA_ASIC_REVISION */
+#define PMAX_R4030_INV_ADDR 0xE0000010 /* Invalid Address register */
+
+#define PMAX_R4030_TRSTBL_BASE 0xE0000018 /* Translation Table Base */
+#define PMAX_R4030_TRSTBL_LIM 0xE0000020 /* Translation Table Limit */
+#define PMAX_R4030_TRSTBL_INV 0xE0000028 /* Translation Table Invalidate */
+
+#define PMAX_R4030_CACHE_MTNC 0xE0000030 /* Cache Maintenance */
+#define PMAX_R4030_R_FAIL_ADDR 0xE0000038 /* Remote Failed Address */
+#define PMAX_R4030_M_FAIL_ADDR 0xE0000040 /* Memory Failed Adresss */
+
+#define PMAX_R4030_CACHE_PTAG 0xE0000048 /* I/O Cache Physical Tag */
+#define PMAX_R4030_CACHE_LTAG 0xE0000050 /* I/O Cache Logical Tag */
+#define PMAX_R4030_CACHE_BMASK 0xE0000058 /* I/O Cache Byte Mask */
+#define PMAX_R4030_CACHE_BWIN 0xE0000060 /* I/O Cache Buffer Window */
+
+/*
+ * Remote Speed Registers.
+ *
+ * 0: free, 1: Ethernet, 2: SCSI, 3: Floppy,
+ * 4: RTC, 5: Kb./Mouse 6: serial 1, 7: serial 2,
+ * 8: parallel, 9: NVRAM, 10: CPU, 11: PROM,
+ * 12: reserved, 13: free, 14: 7seg LED, 15: ???
+ */
+
+#define PMAX_R4030_REM_SPEED 0xE0000070 /* 16 Remote Speed Registers */
+ /* 0xE0000070,78,80... 0xE00000E8 */
+#define PMAX_R4030_IRQ_ENABLE 0xE00000E8 /* Internal Interrupt Enable */
+
+#define PMAX_R4030_IRQ_SOURCE 0xE0000200 /* Interrupt Source Reg */
+#define PMAX_R4030_I386_ERROR 0xE0000208 /* i386/EISA Bus Error */
+
+
+/*
+ * Access the R4030 DMA and I/O Controller
+ */
+
+#ifndef __LANGUAGE_ASSEMBLY__
+
+extern inline unsigned short r4030_read_reg16(unsigned addr) {
+ unsigned short ret = *((volatile unsigned short *)addr);


+ __asm__ __volatile__("nop; nop; nop; nop;");

+ return ret;
+}
+

+extern inline unsigned int r4030_read_reg32(unsigned addr) {
+ unsigned int ret = *((volatile unsigned int *)addr);


+ __asm__ __volatile__("nop; nop; nop; nop;");

+ return ret;
+}
+

+extern inline void r4030_write_reg16(unsigned addr, unsigned val) {
+ *((volatile unsigned short *)addr) = val;


+ __asm__ __volatile__("nop; nop; nop; nop;");
+}

+
+extern inline unsigned int r4030_write_reg32(unsigned addr, unsigned val) {
+ *((volatile unsigned int *)addr) = val;


+ __asm__ __volatile__("nop; nop; nop; nop;");
+}

+
+#endif /* !LANGUAGE_ASSEMBLY__ */
+
+
+#endif /* __ASM_MIPS_PMAX_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/delay.h linux/include/asm-mips/delay.h
--- v2.1.43/linux/include/asm-mips/delay.h Thu Apr 11 23:49:44 1996
+++ linux/include/asm-mips/delay.h Thu Jun 26 12:33:39 1997
@@ -4,11 +4,9 @@
X extern __inline__ void __delay(int loops)
X {
X __asm__ __volatile__ (
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- "1:\tbne\t$0,%0,1b\n\t"
- "subu\t%0,%0,1\n\t"
- ".set\tat\n\t"
+ ".set\tnoreorder\n"
+ "1:\tbnez\t%0,1b\n\t"
+ "subu\t%0,1\n\t"
X ".set\treorder"
X :"=r" (loops)
X :"0" (loops));
@@ -24,15 +22,23 @@
X * first constant multiplications gets optimized away if the delay is
X * a constant)
X */
-extern __inline__ void udelay(unsigned long usecs)
+extern __inline__ void __udelay(unsigned long usecs, unsigned long lps)
X {
X usecs *= 0x000010c6; /* 2**32 / 1000000 */
X __asm__("multu\t%0,%1\n\t"
X "mfhi\t%0"
X :"=r" (usecs)
- :"0" (usecs),"r" (loops_per_sec));
+ :"0" (usecs),"r" (lps));
X __delay(usecs);
X }
+
+#ifdef __SMP__
+#define __udelay_val cpu_data[smp_processor_id()].udelay_val
+#else
+#define __udelay_val loops_per_sec
+#endif
+
+#define udelay(usecs) __udelay((usecs),__udelay_val)
X
X /*
X * The different variants for 32/64 bit are pure paranoia. The typical
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/deskstation.h linux/include/asm-mips/deskstation.h
--- v2.1.43/linux/include/asm-mips/deskstation.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/deskstation.h Thu Jun 26 12:33:39 1997
@@ -0,0 +1,15 @@
+/*
+ * SNI specific definitions
+ *


+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive

SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 34'
echo 'File patch-2.1.44 is continued in part 35'
echo 35 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part35

#!/bin/sh
# this is part 35 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 35; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

+ * for more details.
+ *

+ * Copyright (C) 1997 by Ralf Baechle
+ */
+#ifndef __ASM_MIPS_DESKSTATION_H
+#define __ASM_MIPS_DESKSTATION_H
+
+#define RPC44_PORT_BASE 0xe2000000
+
+#endif /* __ASM_MIPS_DESKSTATION_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/dma.h linux/include/asm-mips/dma.h
--- v2.1.43/linux/include/asm-mips/dma.h Thu Apr 11 23:49:44 1996
+++ linux/include/asm-mips/dma.h Thu Jun 26 12:33:39 1997
@@ -5,14 +5,15 @@
X * and John Boyd, Nov. 1992.
X *
X * NOTE: all this is true *only* for ISA/EISA expansions on Mips boards
- * and can only be used for expansion cards. Onboard DMA controller, such
+ * and can only be used for expansion cards. Onboard DMA controllers, such
X * as the R4030 on Jazz boards behave totally different!
X */
X
X #ifndef __ASM_MIPS_DMA_H
X #define __ASM_MIPS_DMA_H
X
-#include <asm/io.h> /* need byte IO */
+#include <linux/config.h>
+#include <asm/io.h> /* need byte IO */
X
X
X #ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
@@ -74,12 +75,16 @@
X #define MAX_DMA_CHANNELS 8
X
X /*
- * The maximum address that we can perform a DMA transfer to on this platform
- * This describes only the PC style part of the DMA logic like on Deskstations
- * or Acer PICA but not the much more versatile DMA logic used for the
- * local devices on Acer PICA or Magnums.
+ * The maximum address in KSEG0 that we can perform a DMA transfer to on this
+ * platform. This describes only the PC style part of the DMA logic like on
+ * Deskstations or Acer PICA but not the much more versatile DMA logic used
+ * for the local devices on Acer PICA or Magnums.
X */
-#define MAX_DMA_ADDRESS 0x1000000
+#ifndef CONFIG_SGI
+#define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000)
+#else
+#define MAX_DMA_ADDRESS (~0UL)
+#endif
X
X /* 8237 DMA controllers */
X #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
@@ -275,10 +280,5 @@
X /* These are in kernel/dma.c: */
X extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
X extern void free_dma(unsigned int dmanr); /* release it again */
-
-/*
- * DMA memory allocation - formerly in include/linux/mm.h
- */
-#define __get_dma_pages(priority, order) __get_free_pages((priority),(order), 1)
X
X #endif /* __ASM_MIPS_DMA_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/elf.h linux/include/asm-mips/elf.h
--- v2.1.43/linux/include/asm-mips/elf.h Sun Aug 4 04:12:40 1996
+++ linux/include/asm-mips/elf.h Thu Jun 26 12:33:39 1997
@@ -1,12 +1,9 @@
X #ifndef __ASM_MIPS_ELF_H
X #define __ASM_MIPS_ELF_H
X
-/*
- * ELF register definitions
- * This is "make it compile" stuff!
- */
-#define ELF_NGREG 32
-#define ELF_NFPREG 32
+/* ELF register definitions */
+#define ELF_NGREG 45
+#define ELF_NFPREG 33
X
X typedef unsigned long elf_greg_t;
X typedef elf_greg_t elf_gregset_t[ELF_NGREG];
@@ -17,17 +14,30 @@
X /*
X * This is used to ensure we don't load something for the wrong architecture.
X */
-#define elf_check_arch(x) ((x) == EM_MIPS)
+#define elf_check_arch(x) ((x) == EM_MIPS || (x) == EM_MIPS_RS4_BE)
X
X /*
X * These are used to set parameters in the core dumps.
X * FIXME(eric) I don't know what the correct endianness to use is.
X */
X #define ELF_CLASS ELFCLASS32
-#define ELF_DATA ELFDATA2MSB;
+#ifdef __MIPSEB__
+#define ELF_DATA ELFDATA2MSB;
+#elif __MIPSEL__
+#define ELF_DATA ELFDATA2LSB;
+#endif
X #define ELF_ARCH EM_MIPS
X
X #define USE_ELF_CORE_DUMP
X #define ELF_EXEC_PAGESIZE 4096
+
+#define ELF_CORE_COPY_REGS(_dest,_regs) \
+ memcpy((char *) &_dest, (char *) _regs, \
+ sizeof(struct pt_regs));
+
+/* See comments in asm-alpha/elf.h, this is the same thing
+ * on the MIPS.
+ */
+#define ELF_PLAT_INIT(_r) _r->regs[2] = 0;
X
X #endif /* __ASM_MIPS_ELF_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/errno.h linux/include/asm-mips/errno.h
--- v2.1.43/linux/include/asm-mips/errno.h Wed Dec 13 02:39:45 1995
+++ linux/include/asm-mips/errno.h Thu Jun 26 12:33:39 1997
@@ -137,6 +137,22 @@
X #define EINPROGRESS 150 /* Operation now in progress */
X #define ESTALE 151 /* Stale NFS file handle */
X #define ECANCELED 158 /* AIO operation canceled */
+
+/*
+ * These error are Linux extensions.
+ */
+#define ENOMEDIUM 159 /* No medium found */
+#define EMEDIUMTYPE 160 /* Wrong medium type */
+
+/*
+ * IRIX 5 error number start from 1000.
+ * Stupid enough; ECANCELED gets redefined with a different value ...
+#define ECANCELED 1000
+ */
+
+/*
+ * IRIX 4 compatibility error numbers.
+ */
X #define EDQUOT 1133 /* Quota exceeded */
X #define ENFSREMOTE 1134 /* ??? */
X
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/fcntl.h linux/include/asm-mips/fcntl.h
--- v2.1.43/linux/include/asm-mips/fcntl.h Sat Sep 21 23:41:32 1996
+++ linux/include/asm-mips/fcntl.h Thu Jun 26 12:33:39 1997
@@ -52,10 +52,10 @@
X typedef struct flock {
X short l_type;
X short l_whence;
- off_t l_start;
- off_t l_len;
+ __kernel_off_t l_start;
+ __kernel_off_t l_len;
X long l_sysid; /* XXXXXXXXXXXXXXXXXXXXXXXXX */
- pid_t l_pid;
+ __kernel_pid_t l_pid;
X long pad[4]; /* ZZZZZZZZZZZZZZZZZZZZZZZZZZ */
X } flock_t;
X
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/floppy.h linux/include/asm-mips/floppy.h
--- v2.1.43/linux/include/asm-mips/floppy.h Sat Sep 28 12:05:41 1996
+++ linux/include/asm-mips/floppy.h Thu Jun 26 12:33:39 1997
@@ -10,6 +10,7 @@
X #ifndef __ASM_MIPS_FLOPPY_H
X #define __ASM_MIPS_FLOPPY_H
X
+#include <linux/config.h>
X #include <asm/bootinfo.h>
X #include <asm/jazz.h>
X #include <asm/jazzdma.h>
@@ -30,7 +31,6 @@
X #define fd_get_dma_residue() feature->fd_get_dma_residue()
X #define fd_enable_irq() feature->fd_enable_irq()
X #define fd_disable_irq() feature->fd_disable_irq()
-#define fd_cacheflush(addr, size) feature->fd_cacheflush((void *)addr, size)
X #define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt, \
X SA_INTERRUPT|SA_SAMPLE_RANDOM, \
X "floppy", NULL)
@@ -38,7 +38,21 @@
X
X #define MAX_BUFFER_SECTORS 24
X
-static unsigned long mips_dma_mem_alloc(unsigned long size)
+/* Pure 2^n version of get_order */
+extern __inline__ int __get_order(unsigned long size)
+{
+ int order;
+
+ size = (size-1) >> (PAGE_SHIFT-1);
+ order = -1;
+ do {
+ size >>= 1;
+ order++;
+ } while (size);
+ return order;
+}
+
+extern __inline__ unsigned long mips_dma_mem_alloc(unsigned long size)
X {
X int order = __get_order(size);
X unsigned long mem;
@@ -46,38 +60,36 @@
X mem = __get_dma_pages(GFP_KERNEL,order);
X if(!mem)
X return 0;
- if (boot_info.machtype == MACH_ACER_PICA_61 ||
- boot_info.machtype == MACH_MIPS_MAGNUM_4000 ||
- boot_info.machtype == MACH_OLIVETTI_M700)
+#ifdef CONFIG_MIPS_JAZZ
+ if (mips_machgroup == MACH_GROUP_JAZZ)
X vdma_alloc(PHYSADDR(mem), size);
+#endif
X return mem;
X }
X
-static void mips_dma_mem_free(unsigned long addr, unsigned long size)
+extern __inline__ void mips_dma_mem_free(unsigned long addr, unsigned long size)
X {
- if (boot_info.machtype == MACH_ACER_PICA_61 ||
- boot_info.machtype == MACH_MIPS_MAGNUM_4000 ||
- boot_info.machtype == MACH_OLIVETTI_M700)
+#ifdef CONFIG_MIPS_JAZZ
+ if (mips_machgroup == MACH_GROUP_JAZZ)
X vdma_free(PHYSADDR(addr));
+#endif
X free_pages(addr, __get_order(size));
X }
X
-#define fd_dma_mem_alloc(mem,size) mips_dma_mem_alloc(mem,size)
-#define fd_dma_mem_free(mem) mips_dma_mem_free(mem)
+#define fd_dma_mem_alloc(size) mips_dma_mem_alloc(size)
+#define fd_dma_mem_free(mem,size) mips_dma_mem_free(mem,size)
X
X /*
X * And on Mips's the CMOS info fails also ...
X *
X * FIXME: This information should come from the ARC configuration tree
- * or wherever a particular machine has stored this ...
+ * or whereever a particular machine has stored this ...
X */
X #define FLOPPY0_TYPE 4 /* this is wrong for the Olli M700, but who cares... */
X #define FLOPPY1_TYPE 0
X
-#define FDC1 ((boot_info.machtype == MACH_ACER_PICA_61 || \
- boot_info.machtype == MACH_MIPS_MAGNUM_4000 || \
- boot_info.machtype == MACH_OLIVETTI_M700) ? \
- 0xe0003000 : 0x3f0)
+#define FDC1 ((mips_machgroup == MACH_GROUP_JAZZ) ? \
+ JAZZ_FDC_BASE : 0x3f0)
X static int FDC2=-1;
X
X #define N_FDC 1 /* do you *really* want a second controller? */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/hardirq.h linux/include/asm-mips/hardirq.h
--- v2.1.43/linux/include/asm-mips/hardirq.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/hardirq.h Thu Jun 26 12:33:39 1997
@@ -0,0 +1,24 @@
+#ifndef __ASM_MIPS_HARDIRQ_H
+#define __ASM_MIPS_HARDIRQ_H
+
+#include <linux/tasks.h>
+
+extern unsigned int local_irq_count[NR_CPUS];
+#define in_interrupt() (local_irq_count[smp_processor_id()] != 0)
+
+#ifndef __SMP__
+
+#define hardirq_trylock(cpu) (local_irq_count[cpu] == 0)
+#define hardirq_endlock(cpu) do { } while (0)
+
+#define hardirq_enter(cpu) (local_irq_count[cpu]++)
+#define hardirq_exit(cpu) (local_irq_count[cpu]--)
+
+#define synchronize_irq() do { } while (0)
+
+#else
+
+#error No habla MIPS SMP
+
+#endif /* __SMP__ */
+#endif /* __ASM_MIPS_HARDIRQ_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/ide.h linux/include/asm-mips/ide.h
--- v2.1.43/linux/include/asm-mips/ide.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/ide.h Thu Jun 26 12:33:39 1997


@@ -0,0 +1,119 @@
+/*

+ * linux/include/asm-mips/ide.h
+ *
+ * Copyright (C) 1994-1996 Linus Torvalds & authors
+ */
+
+/*
+ * This file contains the MIPS architecture specific IDE code.
+ */
+
+#ifndef __ASM_MIPS_IDE_H
+#define __ASM_MIPS_IDE_H
+
+#ifdef __KERNEL__
+
+typedef unsigned short ide_ioreg_t;
+
+#ifndef MAX_HWIFS
+#define MAX_HWIFS 4
+#endif
+
+#define ide_sti() sti()
+
+static __inline__ int ide_default_irq(ide_ioreg_t base)
+{
+ switch (base) {
+ case 0x1f0: return 14;
+ case 0x170: return 15;
+ case 0x1e8: return 11;
+ case 0x168: return 10;
+ default:


+ return 0;
+ }
+}
+

+static __inline__ ide_ioreg_t ide_default_io_base(int index)
+{
+ switch (index) {
+ case 0: return 0x1f0;
+ case 1: return 0x170;
+ case 2: return 0x1e8;
+ case 3: return 0x168;
+ default:


+ return 0;
+ }
+}
+

+static __inline__ void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq)
+{
+ ide_ioreg_t port = base;
+ int i = 8;
+
+ while (i--)
+ *p++ = port++;
+ *p++ = base + 0x206;
+ if (irq != NULL)
+ *irq = 0;
+}
+
+typedef union {
+ unsigned all : 8; /* all of the bits together */
+ struct {
+ unsigned head : 4; /* always zeros here */
+ unsigned unit : 1; /* drive select number, 0 or 1 */
+ unsigned bit5 : 1; /* always 1 */
+ unsigned lba : 1; /* using LBA instead of CHS */
+ unsigned bit7 : 1; /* always 1 */
+ } b;
+ } select_t;
+
+static __inline__ int ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+ unsigned long flags, const char *device, void *dev_id)
+{
+ return request_irq(irq, handler, flags, device, dev_id);
+}
+
+static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
+{
+ free_irq(irq, dev_id);
+}
+
+static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent)
+{
+ return check_region(from, extent);
+}
+
+static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name)
+{
+ request_region(from, extent, name);
+}
+
+static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent)
+{
+ release_region(from, extent);
+}
+
+/*
+ * The following are not needed for the non-m68k ports
+ */
+static __inline__ int ide_ack_intr (ide_ioreg_t status_port, ide_ioreg_t irq_port)
+{
+ return(1);
+}
+
+static __inline__ void ide_fix_driveid(struct hd_driveid *id)
+{
+}
+
+static __inline__ void ide_release_lock (int *ide_lock)
+{
+}
+
+static __inline__ void ide_get_lock (int *ide_lock, void (*handler)(int, void *, struct pt_regs *), void *data)
+{
+}


+
+#endif /* __KERNEL__ */

+
+#endif /* __ASM_MIPS_IDE_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/init.h linux/include/asm-mips/init.h
--- v2.1.43/linux/include/asm-mips/init.h Wed Apr 16 14:15:00 1997
+++ linux/include/asm-mips/init.h Thu Jun 26 12:33:39 1997
@@ -1,5 +1,5 @@
-#ifndef _MIPS_INIT_H
-#define _MIPS_INIT_H
+#ifndef __ASM_MIPS_INIT_H
+#define __ASM_MIPS_INIT_H
X
X /* Throwing the initialization code and data out is not supported yet... */
X
@@ -11,4 +11,4 @@
X #define __FINIT
X #define __INITDATA
X
-#endif
+#endif /* __ASM_MIPS_INIT_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/inst.h linux/include/asm-mips/inst.h
--- v2.1.43/linux/include/asm-mips/inst.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/inst.h Thu Jun 26 12:33:39 1997
@@ -0,0 +1,304 @@
+/*
+ * Format of an instruction in memory.


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * Copyright (C) 1996 by Ralf Baechle
+ */
+#ifndef __ASM_MIPS_INST_H
+#define __ASM_MIPS_INST_H
+
+/*
+ * Major opcodes; before MIPS IV cop1x was called cop3.
+ */
+enum major_op {
+ spec_op, bcond_op, j_op, jal_op,
+ beq_op, bne_op, blez_op, bgtz_op,
+ addi_op, addiu_op, slti_op, sltiu_op,
+ andi_op, ori_op, xori_op, lui_op,
+ cop0_op, cop1_op, cop2_op, cop1x_op,
+ beql_op, bnel_op, blezl_op, bgtzl_op,
+ daddi_op, daddiu_op, ldl_op, ldr_op,
+ major_1c_op, major_1d_op, major_1e_op, major_1f_op,
+ lb_op, lh_op, lwl_op, lw_op,
+ lbu_op, lhu_op, lwr_op, lwu_op,
+ sb_op, sh_op, swl_op, sw_op,
+ sdl_op, sdr_op, swr_op, cache_op,
+ ll_op, lwc1_op, lwc2_op, pref_op,
+ lld_op, ldc1_op, ldc2_op, ld_op,
+ sc_op, swc1_op, swc2_op, major_3b_op, /* Opcode 0x3b is unused */
+ scd_op, sdc1_op, sdc2_op, sd_op
+};
+
+/*
+ * func field of spec opcode.
+ */
+enum spec_op {
+ sll_op, movc_op, srl_op, sra_op,
+ sllv_op, srlv_op, srav_op, spec1_unused_op, /* Opcode 0x07 is unused */
+ jr_op, jalr_op, movz_op, movn_op,
+ syscall_op, break_op, spim_op, sync_op,
+ mfhi_op, mthi_op, mflo_op, mtlo_op,
+ dsllv_op, spec2_unused_op, dsrlv_op, dsrav_op,
+ mult_op, multu_op, div_op, divu_op,
+ dmult_op, dmultu_op, ddiv_op, ddivu_op,
+ add_op, addu_op, sub_op, subu_op,
+ and_op, or_op, xor_op, nor_op,
+ spec3_unused_op, spec4_unused_op, slt_op, sltu_op,
+ dadd_op, daddu_op, dsub_op, dsubu_op,
+ tge_op, tgeu_op, tlt_op, tltu_op,
+ teq_op, spec5_unused_op, tne_op, spec6_unused_op,
+ dsll_op, spec7_unused_op, dsrl_op, dsra_op,
+ dsll32_op, spec8_unused_op, dsrl32_op, dsra32_op
+};
+
+/*
+ * rt field of bcond opcodes.
+ */
+enum rt_op {
+ bltz_op, bgez_op, bltzl_op, bgezl_op,
+ spimi_op, unused_rt_op_0x05, unused_rt_op_0x06, unused_rt_op_0x07,
+ tgei_op, tgeiu_op, tlti_op, tltiu_op,
+ teqi_op, unused_0x0d_rt_op, tnei_op, unused_0x0f_rt_op,
+ bltzal_op, bgezal_op, bltzall_op, bgezall_op
+ /*
+ * The others (0x14 - 0x1f) are unused.
+ */
+};
+
+/*
+ * rs field of cop opcodes.
+ */
+enum cop_op {
+ mfc_op = 0x00, dmfc_op = 0x01,
+ cfc_op = 0x02, mtc_op = 0x04,
+ dmtc_op = 0x05, ctc_op = 0x06,
+ bc_op = 0x08, cop_op = 0x10,
+ copm_op = 0x18
+};
+
+/*
+ * func field of cop0 coi opcodes.
+ */
+enum cop0_coi_func {
+ tlbr_op = 0x01, tlbwi_op = 0x02,
+ tlbwr_op = 0x06, tlbp_op = 0x08,
+ rfe_op = 0x10, eret_op = 0x18
+};
+
+/*
+ * func field of cop0 com opcodes.
+ */
+enum cop0_com_func {
+ tlbr1_op = 0x01, tlbw_op = 0x02,
+ tlbp1_op = 0x08, dctr_op = 0x09,
+ dctw_op = 0x0a
+};
+
+/*
+ * fmt field of cop1 opcodes.
+ */
+enum cop1_fmt {
+ s_fmt, d_fmt, e_fmt, q_fmt,
+ w_fmt, l_fmt
+};
+
+/*
+ * func field of cop1 instructions using d, s or w format.
+ */
+enum cop1_sdw_func {
+ fadd_op = 0x00, fsub_op = 0x01,
+ fmul_op = 0x02, fdiv_op = 0x03,
+ fsqrt_op = 0x04, fabs_op = 0x05,
+ fmov_op = 0x06, fneg_op = 0x07,
+ froundl_op = 0x08, ftruncl_op = 0x09,
+ fceill_op = 0x0a, ffloorl_op = 0x0b,
+ fround_op = 0x0c, ftrunc_op = 0x0d,
+ fceil_op = 0x0e, ffloor_op = 0x0f,
+ fmovc_op = 0x11, fmovz_op = 0x12,
+ fmovn_op = 0x13, frecip_op = 0x15,
+ frsqrt_op = 0x16, fcvts_op = 0x20,
+ fcvtd_op = 0x21, fcvte_op = 0x22,
+ fcvtw_op = 0x24, fcvtl_op = 0x25,
+ fcmp_op = 0x30
+};
+
+/*
+ * func field of cop1x opcodes (MIPS IV).
+ */
+enum cop1x_func {
+ lwxc1_op = 0x00, ldxc1_op = 0x01,
+ pfetch_op = 0x07, swxc1_op = 0x08,
+ sdxc1_op = 0x09, madd_s_op = 0x20,
+ madd_d_op = 0x21, madd_e_op = 0x22,
+ msub_s_op = 0x28, msub_d_op = 0x29,
+ msub_e_op = 0x2a, nmadd_s_op = 0x30,
+ nmadd_d_op = 0x31, nmadd_e_op = 0x32,
+ nmsub_s_op = 0x38, nmsub_d_op = 0x39,
+ nmsub_e_op = 0x3a
+};
+
+/*
+ * func field for mad opcodes (MIPS IV).
+ */
+enum mad_func {
+ madd_op = 0x08, msub_op = 0x0a,
+ nmadd_op = 0x0c, nmsub_op = 0x0e
+};
+
+/*
+ * Damn ... bitfields depend from byteorder :-(
+ */
+#ifdef __MIPSEB__
+struct j_format { /* Jump format */
+ unsigned int opcode : 6;
+ unsigned int target : 26;
+};
+
+struct i_format { /* Immediate format (addi, lw, ...) */
+ unsigned int opcode : 6;
+ unsigned int rs : 5;
+ unsigned int rt : 5;
+ signed int simmediate : 16;
+};
+
+struct u_format { /* Unsigned immediate format (ori, xori, ...) */
+ unsigned int opcode : 6;
+ unsigned int rs : 5;
+ unsigned int rt : 5;
+ unsigned int uimmediate : 16;
+};
+
+struct c_format { /* Cache (>= R6000) format */
+ unsigned int opcode : 6;
+ unsigned int rs : 5;
+ unsigned int c_op : 3;
+ unsigned int cache : 2;
+ unsigned int simmediate : 16;
+};
+
+struct r_format { /* Register format */
+ unsigned int opcode : 6;
+ unsigned int rs : 5;
+ unsigned int rt : 5;
+ unsigned int rd : 5;
+ unsigned int re : 5;
+ unsigned int func : 6;
+};
+
+struct p_format { /* Performance counter format (R10000) */
+ unsigned int opcode : 6;
+ unsigned int rs : 5;
+ unsigned int rt : 5;
+ unsigned int rd : 5;
+ unsigned int re : 5;
+ unsigned int func : 6;
+};
+
+struct f_format { /* FPU register format */
+ unsigned int opcode : 6;
+ unsigned int : 1;
+ unsigned int fmt : 4;
+ unsigned int rt : 5;
+ unsigned int rd : 5;
+ unsigned int re : 5;
+ unsigned int func : 6;
+};
+
+struct ma_format { /* FPU multipy and add format (MIPS IV) */
+ unsigned int opcode : 6;
+ unsigned int fr : 5;
+ unsigned int ft : 5;
+ unsigned int fs : 5;
+ unsigned int fd : 5;
+ unsigned int func : 4;
+ unsigned int fmt : 2;
+};
+
+#elif defined(__MIPSEL__)
+
+struct j_format { /* Jump format */
+ unsigned int target : 26;
+ unsigned int opcode : 6;
+};
+
+struct i_format { /* Immediate format */
+ signed int simmediate : 16;
+ unsigned int rt : 5;
+ unsigned int rs : 5;
+ unsigned int opcode : 6;
+};
+
+struct u_format { /* Unsigned immediate format */
+ unsigned int uimmediate : 16;
+ unsigned int rt : 5;
+ unsigned int rs : 5;
+ unsigned int opcode : 6;
+};
+
+struct c_format { /* Cache (>= R6000) format */
+ unsigned int simmediate : 16;
+ unsigned int cache : 2;
+ unsigned int c_op : 3;
+ unsigned int rs : 5;
+ unsigned int opcode : 6;
+};
+
+struct r_format { /* Register format */
+ unsigned int func : 6;
+ unsigned int re : 5;
+ unsigned int rd : 5;
+ unsigned int rt : 5;
+ unsigned int rs : 5;
+ unsigned int opcode : 6;
+};
+
+struct p_format { /* Performance counter format (R10000) */
+ unsigned int func : 6;
+ unsigned int re : 5;
+ unsigned int rd : 5;
+ unsigned int rt : 5;
+ unsigned int rs : 5;
+ unsigned int opcode : 6;
+};
+
+struct f_format { /* FPU register format */
+ unsigned int func : 6;
+ unsigned int re : 5;
+ unsigned int rd : 5;
+ unsigned int rt : 5;
+ unsigned int fmt : 4;
+ unsigned int : 1;
+ unsigned int opcode : 6;
+};
+
+struct ma_format { /* FPU multipy and add format (MIPS IV) */
+ unsigned int fmt : 2;
+ unsigned int func : 4;
+ unsigned int fd : 5;
+ unsigned int fs : 5;
+ unsigned int ft : 5;
+ unsigned int fr : 5;
+ unsigned int opcode : 6;
+};
+
+#else /* !defined (__MIPSEB__) && !defined (__MIPSEL__) */


+#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
+#endif
+

+union mips_instruction {
+ unsigned int word;
+ unsigned short halfword[2];
+ unsigned char byte[4];
+ struct j_format j_format;
+ struct i_format i_format;
+ struct u_format u_format;
+ struct c_format c_format;
+ struct r_format r_format;
+ struct f_format f_format;
+ struct ma_format ma_format;
+};
+
+#endif /* __ASM_MIPS_INST_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/io.h linux/include/asm-mips/io.h
--- v2.1.43/linux/include/asm-mips/io.h Sun Oct 6 22:55:48 1996
+++ linux/include/asm-mips/io.h Thu Jun 26 12:33:39 1997
@@ -1,14 +1,21 @@
X #ifndef __ASM_MIPS_IO_H
X #define __ASM_MIPS_IO_H
X
+/*
+ * Slowdown I/O port space accesses for antique hardware.
+ */
+#undef CONF_SLOWDOWN_IO
+
X #include <asm/mipsconfig.h>
-#include <asm/segment.h>
+#include <asm/addrspace.h>
X
X /*
X * This file contains the definitions for the MIPS counterpart of the
X * x86 in/out instructions. This heap of macros and C results in much
- * better code than the approach of doing it in plain C, though that's
- * probably not needed.
+ * better code than the approach of doing it in plain C. The macros
+ * result in code that is to fast for certain hardware. On the other
+ * side the performance of the string functions should be improved for
+ * sake of certain devices like EIDE disks that do highspeed polled I/O.
X *
X * Ralf
X *
@@ -33,6 +40,7 @@
X * I feel a bit unsafe about using 0x80 (should be safe, though)
X *
X * Linus
+ *
X */
X
X #define __SLOW_DOWN_IO \
@@ -40,11 +48,15 @@
X "sb\t$0,0x80(%0)" \
X : : "r" (PORT_BASE));
X
+#ifdef CONF_SLOWDOWN_IO
X #ifdef REALLY_SLOW_IO
X #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
X #else
X #define SLOW_DOWN_IO __SLOW_DOWN_IO
X #endif
+#else
+#define SLOW_DOWN_IO
+#endif
X
X /*
X * Change virtual addresses to physical addresses and vv.
@@ -52,44 +64,106 @@
X */
X extern inline unsigned long virt_to_phys(volatile void * address)
X {
- return (unsigned long) address - KSEG0;
+ return PHYSADDR(address);
X }
X
X extern inline void * phys_to_virt(unsigned long address)
X {
- return (void *) address + KSEG0;
+ return (void *)KSEG0ADDR(address);
X }
X
+extern void * ioremap(unsigned long phys_addr, unsigned long size);
+extern void iounmap(void *addr);
+
X /*
X * IO bus memory addresses are also 1:1 with the physical address
- * FIXME: This assumption is wrong for the Deskstation Tyne
X */
-#define virt_to_bus virt_to_phys
-#define bus_to_virt phys_to_virt
+extern inline unsigned long virt_to_bus(volatile void * address)
+{
+ return PHYSADDR(address);
+}
+
+extern inline void * bus_to_virt(unsigned long address)
+{
+ return (void *)KSEG0ADDR(address);
+}
+
+/*


+ * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped
+ * for the processor.

+ */
+extern unsigned long isa_slot_offset;
X
X /*
X * readX/writeX() are used to access memory mapped devices. On some
X * architectures the memory mapped IO stuff needs to be accessed
X * differently. On the x86 architecture, we just read/write the
X * memory location directly.
+ *
+ * On MIPS, we have the whole physical address space mapped at all
+ * times, so "ioremap()" and "iounmap()" do not need to do anything.
+ * (This isn't true for all machines but we still handle these cases
+ * with wired TLB entries anyway ...)
+ *
+ * We cheat a bit and always return uncachable areas until we've fixed
+ * the drivers to handle caching properly.
+ */
+extern inline void * ioremap(unsigned long offset, unsigned long size)
+{
+ return (void *) KSEG1ADDR(offset);
+}
+
+/*
+ * This one maps high address device memory and turns off caching for that area.
+ * it's useful if some control registers are in such an area and write combining
+ * or read caching is not desirable:
+ */
+extern inline void * ioremap_nocache (unsigned long offset, unsigned long size)
+{
+ return (void *) KSEG1ADDR(offset);
+}
+
+extern inline void iounmap(void *addr)
+{
+}
+
+/*
+ * XXX We need system specific versions of these to handle EISA address bits
+ * 24-31 on SNI.
X */
-#define readb(addr) (*(volatile unsigned char *) (addr))
-#define readw(addr) (*(volatile unsigned short *) (addr))
-#define readl(addr) (*(volatile unsigned int *) (addr))
+#define readb(addr) (*(volatile unsigned char *) (isa_slot_offset + (unsigned long)(addr)))
+#define readw(addr) (*(volatile unsigned short *) (isa_slot_offset + (unsigned long)(addr)))
+#define readl(addr) (*(volatile unsigned int *) (isa_slot_offset + (unsigned long)(addr)))
X
-#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
-#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
-#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+#define writeb(b,addr) (*(volatile unsigned char *) (isa_slot_offset + (unsigned long)(addr)) = (b))
+#define writew(b,addr) (*(volatile unsigned short *) (isa_slot_offset + (unsigned long)(addr)) = (b))
+#define writel(b,addr) (*(volatile unsigned int *) (isa_slot_offset + (unsigned long)(addr)) = (b))
X
-#define memset_io(a,b,c) memset((void *)(a),(b),(c))
-#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
-#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
+#define memset_io(a,b,c) memset((void *)(isa_slot_offset + (unsigned long)a),(b),(c))
+#define memcpy_fromio(a,b,c) memcpy((a),(void *)(isa_slot_offset + (unsigned long)(b)),(c))
+#define memcpy_toio(a,b,c) memcpy((void *)(isa_slot_offset + (unsigned long)(a)),(b),(c))
X
X /*
- * Again, MIPS does not require mem IO specific function.
+ * We don't have csum_partial_copy_fromio() yet, so we cheat here and
+ * just copy it. The net code will then do the checksum later.
X */
+#define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len))
X
-#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void *)(b),(c),(d))
+static inline int check_signature(unsigned long io_addr,
+ const unsigned char *signature, int length)
+{


+ int retval = 0;

+ do {
+ if (readb(io_addr) != *signature)
+ goto out;
+ io_addr++;
+ signature++;
+ length--;
+ } while (length);
+ retval = 1;
+out:
+ return retval;
+}
X
X /*
X * Talk about misusing macros..
@@ -113,10 +187,10 @@
X extern __inline__ t __in##s(unsigned int port) { t _v;
X
X /*
- * Useless nops will be removed by the assembler
+ * Required nops will be inserted by the assembler
X */
X #define __IN2(m) \
-__asm__ __volatile__ ("l" #m "u\t%0,%1(%2)\n\tnop"
+__asm__ __volatile__ ("l" #m "\t%0,%1(%2)"
X
X #define __IN(t,m,s) \
X __IN1(t,s) __IN2(m) : "=r" (_v) : "i" (0), "r" (PORT_BASE+port)); return _v; } \
@@ -128,10 +202,11 @@
X extern inline void __ins##s(unsigned int port, void * addr, unsigned long count) {
X
X #define __INS2(m) \
+if (count) \
X __asm__ __volatile__ ( \


X ".set\tnoreorder\n\t" \
X ".set\tnoat\n" \

- "1:\tl" #m "u\t$1,%4(%5)\n\t" \
+ "1:\tl" #m "\t$1,%4(%5)\n\t" \
X "subu\t%1,1\n\t" \
X "s" #m "\t$1,(%0)\n\t" \
X "bne\t$0,%1,1b\n\t" \
@@ -153,14 +228,15 @@
X extern inline void __outs##s(unsigned int port, const void * addr, unsigned long count) {
X
X #define __OUTS2(m) \
+if (count) \
X __asm__ __volatile__ ( \


X ".set\tnoreorder\n\t" \
X ".set\tnoat\n" \

- "1:\tl" #m "u\t$1,(%0)\n\t" \
- "subu\t%1,%1,1\n\t" \
+ "1:\tl" #m "\t$1,(%0)\n\t" \
+ "subu\t%1,1\n\t" \
X "s" #m "\t$1,%4(%5)\n\t" \
X "bne\t$0,%1,1b\n\t" \
- "addiu\t%0,%0,%6\n\t" \
+ "addiu\t%0,%6\n\t" \


X ".set\tat\n\t" \
X ".set\treorder"

X
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/ioctl.h linux/include/asm-mips/ioctl.h
--- v2.1.43/linux/include/asm-mips/ioctl.h Wed Dec 13 02:39:45 1995
+++ linux/include/asm-mips/ioctl.h Thu Jun 26 12:33:39 1997
@@ -1,3 +1,12 @@
+/*
+ * Linux ioctl() stuff.


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * Copyright (C) 1995, 1996 by Ralf Baechle
+ */
X #ifndef __ASM_MIPS_IOCTL_H
X #define __ASM_MIPS_IOCTL_H
X
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/ioctls.h linux/include/asm-mips/ioctls.h
--- v2.1.43/linux/include/asm-mips/ioctls.h Wed May 8 00:32:41 1996
+++ linux/include/asm-mips/ioctls.h Thu Jun 26 12:33:39 1997
@@ -1,8 +1,21 @@
+/*
+ * ioctls for Linux/MIPS.


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * Copyright (C) 1995, 1996 by Ralf Baechle
+ */
X #ifndef __ASM_MIPS_IOCTLS_H
X #define __ASM_MIPS_IOCTLS_H
X
X #include <asm/ioctl.h>
X
+#if defined(__USE_MISC) || defined (__KERNEL__)
+#define tIOC ('t' << 8)
+#endif
+
X #define TCGETA 0x5401
X #define TCSETA 0x5402
X #define TCSETAW 0x5403
@@ -39,15 +52,18 @@
X #define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */
X #define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */
X #define TIOCNOTTY 0x5471 /* void tty association */
-#define TIOCSETD 0x7401
-#define TIOCGETD 0x7400
+#define TIOCSETD (tIOC | 1)
+#define TIOCGETD (tIOC | 0)
X
X #define FIOCLEX 0x6601
X #define FIONCLEX 0x6602 /* these numbers need to be adjusted. */
X #define FIOASYNC 0x667d
X #define FIONBIO 0x667e
X
- /* 116-117 compat */
+#if defined(__USE_MISC) || defined (__KERNEL__)
+#define TIOCGLTC (tIOC | 116) /* get special local chars */
+#define TIOCSLTC (tIOC | 117) /* set special local chars */
+#endif
X #define TIOCSPGRP _IOW('t', 118, int) /* set pgrp of tty */
X #define TIOCGPGRP _IOR('t', 119, int) /* get pgrp of tty */
X #define TIOCCONS _IOW('t', 120, int) /* become virtual console */
@@ -55,6 +71,12 @@
X #define FIONREAD 0x467f
X #define TIOCINQ FIONREAD
X
+#if defined(__USE_MISC) || defined (__KERNEL__)
+#define TIOCGETP (tIOC | 8)
+#define TIOCSETP (tIOC | 9)
+#define TIOCSETN (tIOC | 10) /* TIOCSETP wo flush */
+#endif
+
X #if 0
X #define TIOCSETA _IOW('t', 20, struct termios) /* set termios struct */
X #define TIOCSETAW _IOW('t', 21, struct termios) /* drain output, set */
@@ -84,217 +106,9 @@
X #define TIOCSERGETLSR 0x548e /* Get line status register */
X #define TIOCSERGETMULTI 0x548f /* Get multiport config */
X #define TIOCSERSETMULTI 0x5490 /* Set multiport config */
-
-/* ----------------------------------------------------------------------- */
-
-/* c_cc characters */
-#define VINTR 0 /* Interrupt character [ISIG]. */
-#define VQUIT 1 /* Quit character [ISIG]. */
-#define VERASE 2 /* Erase character [ICANON]. */
-#define VKILL 3 /* Kill-line character [ICANON]. */
-#define VEOF 4 /* End-of-file character [ICANON]. */
-#define VMIN VEOF /* Minimum number of bytes read at once [!ICANON]. */
-#define VEOL 5 /* End-of-line character [ICANON]. */
-#define VTIME VEOL /* Time-out value (tenths of a second) [!ICANON]. */
-#if defined (__USE_BSD) || defined (__KERNEL__)
-#define VEOL2 6 /* Second EOL character [ICANON]. */
-/* The next two are guesses ... */
-#define VSWTC 7 /* ??? */
-#endif
-#define VSWTCH VSWTC
-#define VSTART 8 /* Start (X-ON) character [IXON, IXOFF]. */
-#define VSTOP 9 /* Stop (X-OFF) character [IXON, IXOFF]. */
-#define VSUSP 10 /* Suspend character [ISIG]. */
-#if 0
-/*
- * VDSUSP is not supported
- */
-#if defined (__USE_BSD) || defined (__KERNEL__)
-#define VDSUSP 11 /* Delayed suspend character [ISIG]. */
-#endif
-#endif
-#if defined (__USE_BSD) || defined (__KERNEL__)
-#define VREPRINT 12 /* Reprint-line character [ICANON]. */
-#endif
-#if defined (__USE_BSD) || defined (__KERNEL__)
-#define VDISCARD 13 /* Discard character [IEXTEN]. */
-#define VWERASE 14 /* Word-erase character [ICANON]. */
-#define VLNEXT 15 /* Literal-next character [IEXTEN]. */
-#endif
-/*
- * 17 - 19 are reserved
- */
-
-#ifdef __KERNEL__
-/*
- * intr=^C quit=^| erase=del kill=^U
- * eof=^D eol=time=\0 eol2=\0 swtc=\0
- * start=^Q stop=^S susp=^Z vdsusp=
- * reprint=^R discard=^U werase=^W lnext=^V
- */
-#define INIT_C_CC "\003\034\177\025\004\0\0\0\021\023\032\0\022\017\027\026"
-#endif
-
-/* c_iflag bits */
-#define IGNBRK 0000001 /* Ignore break condition. */
-#define BRKINT 0000002 /* Signal interrupt on break. */
-#define IGNPAR 0000004 /* Ignore characters with parity errors. */
-#define PARMRK 0000010 /* Mark parity and framing errors. */
-#define INPCK 0000020 /* Enable input parity check. */
-#define ISTRIP 0000040 /* Strip 8th bit off characters. */
-#define INLCR 0000100 /* Map NL to CR on input. */
-#define IGNCR 0000200 /* Ignore CR. */
-#define ICRNL 0000400 /* Map CR to NL on input. */
-#if defined (__USE_BSD) || defined (__KERNEL__)
-#define IUCLC 0001000 /* Map upper case to lower case on input. */
-#endif
-#define IXON 0002000 /* Enable start/stop output control. */
-#if defined (__USE_BSD) || defined (__KERNEL__)
-#define IXANY 0004000 /* Any character will restart after stop. */
-#endif
-#define IXOFF 0010000 /* Enable start/stop input control. */
-#if defined (__USE_BSD) || defined (__KERNEL__)
-#define IMAXBEL 0020000 /* Ring bell when input queue is full. */
-#endif
-
-/* c_oflag bits */
-#define OPOST 0000001 /* Perform output processing. */
-#if defined (__USE_BSD) || defined (__KERNEL__)
-#define OLCUC 0000002 /* Map lower case to upper case on output. */
-#define ONLCR 0000004 /* Map NL to CR-NL on output. */
-#define OCRNL 0000010
-#define ONOCR 0000020
-#define ONLRET 0000040
-#define OFILL 0000100
-#define OFDEL 0000200
-#define NLDLY 0000400
-#define NL0 0000000
-#define NL1 0000400
-#define CRDLY 0003000
-#define CR0 0000000
-#define CR1 0001000
-#define CR2 0002000
-#define CR3 0003000
-#define TABDLY 0014000
-#define TAB0 0000000
-#define TAB1 0004000
-#define TAB2 0010000
-#define TAB3 0014000
-#define XTABS 0014000
-#define BSDLY 0020000
-#define BS0 0000000
-#define BS1 0020000
-#define VTDLY 0040000
-#define VT0 0000000
-#define VT1 0040000
-#define FFDLY 0100000
-#define FF0 0000000
-#define FF1 0100000
-/*
-#define PAGEOUT ???
-#define WRAP ???
- */
-#endif
-
-/* c_cflag bit meaning */
-#define CBAUD 0010017
-#define B0 0000000 /* hang up */
-#define B50 0000001
-#define B75 0000002
-#define B110 0000003
-#define B134 0000004
-#define B150 0000005
-#define B200 0000006
-#define B300 0000007
-#define B600 0000010
-#define B1200 0000011
-#define B1800 0000012
-#define B2400 0000013
-#define B4800 0000014
-#define B9600 0000015
-#define B19200 0000016
-#define B38400 0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE 0000060 /* Number of bits per byte (mask). */
-#define CS5 0000000 /* 5 bits per byte. */
-#define CS6 0000020 /* 6 bits per byte. */
-#define CS7 0000040 /* 7 bits per byte. */
-#define CS8 0000060 /* 8 bits per byte. */
-#define CSTOPB 0000100 /* Two stop bits instead of one. */
-#define CREAD 0000200 /* Enable receiver. */
-#define PARENB 0000400 /* Parity enable. */
-#define PARODD 0001000 /* Odd parity instead of even. */
-#define HUPCL 0002000 /* Hang up on last close. */
-#define CLOCAL 0004000 /* Ignore modem status lines. */
-#if defined (__USE_BSD) || defined (__KERNEL__)
-#define CBAUDEX 0010000
-#define B57600 0010001
-#define B115200 0010002
-#define B230400 0010003
-#define B460800 0010004
-#define CIBAUD 002003600000 /* input baud rate (not used) */
-#define CRTSCTS 020000000000 /* flow control */
-#endif
-
-/* c_lflag bits */
-#define ISIG 0000001 /* Enable signals. */
-#define ICANON 0000002 /* Do erase and kill processing. */
-#define XCASE 0000004
-#define ECHO 0000010 /* Enable echo. */
-#define ECHOE 0000020 /* Visual erase for ERASE. */
-#define ECHOK 0000040 /* Echo NL after KILL. */
-#define ECHONL 0000100 /* Echo NL even if ECHO is off. */
-#define NOFLSH 0000200 /* Disable flush after interrupt. */
-#define IEXTEN 0000400 /* Enable DISCARD and LNEXT. */
-#if defined (__USE_BSD) || defined (__KERNEL__)
-#define ECHOCTL 0001000 /* Echo control characters as ^X. */
-#define ECHOPRT 0002000 /* Hardcopy visual erase. */
-#define ECHOKE 0004000 /* Visual erase for KILL. */
-#endif
-#define FLUSHO 0020000
-#if defined (__USE_BSD) || defined (__KERNEL__)
-#define PENDIN 0040000 /* Retype pending input (state). */
-#endif
-#define TOSTOP 0100000 /* Send SIGTTOU for background output. */
-#define ITOSTOP TOSTOP
-
-/* modem lines */
-#define TIOCM_LE 0x001 /* line enable */
-#define TIOCM_DTR 0x002 /* data terminal ready */
-#define TIOCM_RTS 0x004 /* request to send */
-#define TIOCM_ST 0x010 /* secondary transmit */
-#define TIOCM_SR 0x020 /* secondary receive */
-#define TIOCM_CTS 0x040 /* clear to send */
-#define TIOCM_CAR 0x100 /* carrier detect */
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RNG 0x200 /* ring */
-#define TIOCM_RI TIOCM_RNG
-#define TIOCM_DSR 0x400 /* data set ready */
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
-/* tcflow() and TCXONC use these */
-#define TCOOFF 0 /* Suspend output. */
-#define TCOON 1 /* Restart suspended output. */
-#define TCIOFF 2 /* Send a STOP character. */
-#define TCION 3 /* Send a START character. */
-
-/* tcflush() and TCFLSH use these */
-#define TCIFLUSH 0 /* Discard data received but not yet read. */
-#define TCOFLUSH 1 /* Discard data written but not yet sent. */
-#define TCIOFLUSH 2 /* Discard all pending data. */
-
-/* tcsetattr uses these */
-#define TCSANOW TCSETS /* Change immediately. */
-#define TCSADRAIN TCSETSW /* Change when pending output is written. */
-#define TCSAFLUSH TCSETSF /* Flush pending input before changing. */
-
-/* line disciplines */
-#define N_TTY 0
-#define N_SLIP 1
-#define N_MOUSE 2
-#define N_PPP 3
+#define TIOCMIWAIT 0x5491 /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT 0x5492 /* read serial port inline interrupt counts */
+#define TIOCSBRK 0x5491 /* BSD compatibility */
+#define TIOCCBRK 0x5492 /* BSD compatibility */
X
X #endif /* __ASM_MIPS_IOCTLS_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/ipc.h linux/include/asm-mips/ipc.h
--- v2.1.43/linux/include/asm-mips/ipc.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/ipc.h Thu Jun 26 12:33:39 1997
@@ -0,0 +1,29 @@
+#ifndef __ASM_MIPS_IPC_H
+#define __ASM_MIPS_IPC_H
+
+/*
+ * These are used to wrap system calls on MIPS.
+ *
+ * See arch/mips/kernel/sysmips.c for ugly details..
+ * FIXME: split up into ordinary syscalls ...
+ */
+struct ipc_kludge {
+ struct msgbuf *msgp;
+ long msgtyp;
+};
+
+#define SEMOP 1
+#define SEMGET 2
+#define SEMCTL 3
+#define MSGSND 11
+#define MSGRCV 12
+#define MSGGET 13
+#define MSGCTL 14
+#define SHMAT 21
+#define SHMDT 22
+#define SHMGET 23
+#define SHMCTL 24
+
+#define IPCCALL(version,op) ((version)<<16 | (op))
+
+#endif /* __ASM_MIPS_IPC_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/irq.h linux/include/asm-mips/irq.h
--- v2.1.43/linux/include/asm-mips/irq.h Wed Dec 13 02:39:46 1995
+++ linux/include/asm-mips/irq.h Thu Jun 26 12:33:39 1997
@@ -15,8 +15,12 @@
X /*
X * Actually this is a lie but we hide the local device's interrupts ...
X */
-#define NR_IRQS 16
+#define NR_IRQS 64
X
+#define TIMER_IRQ 0
+
+struct irqaction;
+extern int setup_x86_irq(int irq, struct irqaction * new);
X extern void disable_irq(unsigned int);
X extern void enable_irq(unsigned int);
X
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/jazz.h linux/include/asm-mips/jazz.h
--- v2.1.43/linux/include/asm-mips/jazz.h Thu Apr 11 23:49:44 1996
+++ linux/include/asm-mips/jazz.h Thu Jun 26 12:33:39 1997
@@ -9,7 +9,6 @@
X *
X * This file is a mess. It really needs some reorganisation!
X */
-
X #ifndef __ASM_MIPS_JAZZ_H
X #define __ASM_MIPS_JAZZ_H
X
@@ -87,6 +86,16 @@
X #endif
X
X /*
+ * Base address of the Sonic Ethernet adapter in Jazz machines.
+ */
+#define JAZZ_ETHERNET_BASE 0xe0001000
+
+/*
+ * Base address of the 53C94 SCSI hostadapter in Jazz machines.
+ */
+#define JAZZ_SCSI_BASE 0xe0002000
+
+/*
X * i8042 keyboard controller for JAZZ and PICA chipsets.
X * This address is just a guess and seems to differ from
X * other mips machines such as RC3xxx...
@@ -196,7 +205,7 @@
X */
X #define JAZZ_TIMER_IRQ 0
X #define JAZZ_KEYBOARD_IRQ 1
-#define JAZZ_ETHERNET_IRQ 2 /* 15 */
+#define JAZZ_ETHERNET_IRQ 13
X #define JAZZ_SERIAL1_IRQ 3
X #define JAZZ_SERIAL2_IRQ 4
X #define JAZZ_PARALLEL_IRQ 5
@@ -245,66 +254,63 @@
X #define JAZZ_R4030_REM_SPEED 0xE0000070 /* 16 Remote Speed Registers */
X /* 0xE0000070,78,80... 0xE00000E8 */
X #define JAZZ_R4030_IRQ_ENABLE 0xE00000E8 /* Internal Interrupt Enable */
-
-#define JAZZ_R4030_IRQ_SOURCE 0xE0000200 /* Interrupt Source Reg */
+#define JAZZ_R4030_INVAL_ADDR 0xE0000010 /* Invalid address Register */
+#define JAZZ_R4030_IRQ_SOURCE 0xE0000200 /* Interrupt Source Register */
X #define JAZZ_R4030_I386_ERROR 0xE0000208 /* i386/EISA Bus Error */
X
+/*
+ * Virtual (E)ISA controller address
+ */
+#define JAZZ_EISA_IRQ_ACK 0xE0000238 /* EISA interrupt acknowledge */
X
X /*
X * Access the R4030 DMA and I/O Controller
X */
X #ifndef __LANGUAGE_ASSEMBLY__
X
-extern inline unsigned short r4030_read_reg16(unsigned addr) {
+extern inline void r4030_delay(void)
+{
+__asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ ".set\treorder");
+}
+
+extern inline unsigned short r4030_read_reg16(unsigned addr)
+{
X unsigned short ret = *((volatile unsigned short *)addr);
- __asm__ __volatile__(


- ".set\tnoreorder\n\t"

- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- ".set\treorder");
+ r4030_delay();


X return ret;
X }
X

-extern inline unsigned int r4030_read_reg32(unsigned addr) {


+extern inline unsigned int r4030_read_reg32(unsigned addr)

+{
X unsigned int ret = *((volatile unsigned int *)addr);
- __asm__ __volatile__(


- ".set\tnoreorder\n\t"

- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- ".set\treorder");
+ r4030_delay();


X return ret;
X }
X

-extern inline void r4030_write_reg16(unsigned addr, unsigned val) {


+extern inline void r4030_write_reg16(unsigned addr, unsigned val)

+{
X *((volatile unsigned short *)addr) = val;
- __asm__ __volatile__(


- ".set\tnoreorder\n\t"

- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- ".set\treorder");
+ r4030_delay();
X }
X
-extern inline unsigned int r4030_write_reg32(unsigned addr, unsigned val) {


+extern inline unsigned int r4030_write_reg32(unsigned addr, unsigned val)

+{
X *((volatile unsigned int *)addr) = val;
- __asm__ __volatile__(


- ".set\tnoreorder\n\t"

- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- "nop\n\t"
- ".set\treorder");
+ r4030_delay();
X }
X
X #endif /* !LANGUAGE_ASSEMBLY__ */
X
-#define JAZZ_FDC_BASE 0xe0003000
+#define JAZZ_FDC_BASE 0xe0003000
+#define JAZZ_RTC_BASE 0xe0004000
+#define JAZZ_PORT_BASE 0xe2000000
X
-#define JAZZ_RTC_BASE 0xe0004000
+#define JAZZ_EISA_BASE 0xe3000000
X
X #endif /* __ASM_MIPS_JAZZ_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/jazzdma.h linux/include/asm-mips/jazzdma.h
--- v2.1.43/linux/include/asm-mips/jazzdma.h Wed Dec 13 02:39:46 1995
+++ linux/include/asm-mips/jazzdma.h Thu Jun 26 12:33:39 1997
@@ -1,14 +1,12 @@
X /*
X * Helpfile for jazzdma.c -- Mips Jazz R4030 DMA controller support
X */
-
-#ifndef __ASM_JAZZDMA_H
-#define __ASM_JAZZDMA_H
+#ifndef __ASM_MIPS_JAZZDMA_H
+#define __ASM_MIPS_JAZZDMA_H
X
X /*
X * Prototypes and macros
X */
-
X unsigned long vdma_init(unsigned long memory_start, unsigned long memory_end);
X unsigned long vdma_alloc(unsigned long paddr, unsigned long size);
X int vdma_free(unsigned long laddr);
@@ -76,8 +74,9 @@
X #define R4030_MEM_INTR (1<<9)
X #define R4030_ADDR_INTR (1<<10)
X
-/* channel mode register bits */
-
+/*
+ * Channel mode register bits
+ */
X #define R4030_MODE_ATIME_40 (0) /* device access time on remote bus */
X #define R4030_MODE_ATIME_80 (1)
X #define R4030_MODE_ATIME_120 (2)
@@ -93,4 +92,4 @@
X #define R4030_MODE_BURST (1<<6) /* Rev. 2 only */
X #define R4030_MODE_FAST_ACK (1<<7) /* Rev. 2 only */
X
-#endif /* __ASM_JAZZDMA_H */
+#endif /* __ASM_MIPS_JAZZDMA_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/keyboard.h linux/include/asm-mips/keyboard.h
--- v2.1.43/linux/include/asm-mips/keyboard.h Mon Jun 16 16:36:00 1997
+++ linux/include/asm-mips/keyboard.h Thu Jun 26 12:33:39 1997
@@ -1,20 +1,22 @@
X /*
- * linux/include/asm-mips/keyboard.h
+ * CPU specific parts of the keyboard driver
X *
- * Created 3 Nov 1996 by Geert Uytterhoeven
- */
-
-/*
- * This file contains the mips architecture specific keyboard definitions


+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * This file is a mess. Put on your peril sensitive glasses.
+ *
+ * $Id: keyboard.h,v 1.4 1997/06/16 00:31:46 ralf Exp $
X */
-
-#ifndef __ASMMIPS_KEYBOARD_H
-#define __ASMMIPS_KEYBOARD_H
+#ifndef __ASM_MIPS_KEYBOARD_H
+#define __ASM_MIPS_KEYBOARD_H
X
X #ifdef __KERNEL__
X
-#define KEYBOARD_IRQ 1
-#define DISABLE_KBD_DURING_INTERRUPTS 0
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
X
X extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
X extern int pckbd_getkeycode(unsigned int scancode);
@@ -33,8 +35,203 @@
X #define kbd_leds pckbd_leds
X #define kbd_init_hw pckbd_init_hw
X
-#define INIT_KBD
+/*
+ * The default IO slowdown is doing 'inb()'s from 0x61, which should be
+ * safe. But as that is the keyboard controller chip address, we do our
+ * slowdowns here by doing short jumps: the keyboard controller should
+ * be able to keep up
+ */
+#define REALLY_SLOW_IO
+#define SLOW_IO_BY_JUMPING
+#include <asm/io.h>
+
+/*
+ * keyboard controller registers
+ */
+#define KBD_STATUS_REG (unsigned int) 0x64
+#define KBD_CNTL_REG (unsigned int) 0x64
+#define KBD_DATA_REG (unsigned int) 0x60
+
+#ifdef CONFIG_SGI
+#include <asm/segment.h>
+#include <asm/sgihpc.h>
+#endif
+#include <asm/bootinfo.h>
+#include <asm/jazz.h>
+
+#ifdef CONFIG_SGI
+#define KEYBOARD_IRQ 20
+#else
+/* Not true for Jazz machines, we cheat a bit for 'em. */
+#define KEYBOARD_IRQ 1
+#endif
+
+#ifdef CONFIG_SGI
+#define DISABLE_KBD_DURING_INTERRUPTS 1
+#else
+#define DISABLE_KBD_DURING_INTERRUPTS 0
+#endif
+
+#ifndef CONFIG_SGI
+#define KBD_REPORT_ERR
+#endif
+#define KBD_REPORT_UNKN
+/* #define KBD_IS_FOCUS_9000 */
+
+int (*kbd_inb_p)(unsigned short port);
+int (*kbd_inb)(unsigned short port);
+void (*kbd_outb_p)(unsigned char data, unsigned short port);
+void (*kbd_outb)(unsigned char data, unsigned short port);
+
+#ifdef CONFIG_MIPS_JAZZ
+#define INIT_KBD /* full initialization for the keyboard controller. */
+
+static volatile keyboard_hardware *jazz_kh;
+
+static int
+jazz_kbd_inb_p(unsigned short port)


+{
+ int result;
+

+ if(port == KBD_DATA_REG)
+ result = jazz_kh->data;
+ else /* Must be KBD_STATUS_REG */
+ result = jazz_kh->command;
+ inb(0x80);


+
+ return result;
+}
+

+static int
+jazz_kbd_inb(unsigned short port)


+{
+ int result;
+

+ if(port == KBD_DATA_REG)
+ result = jazz_kh->data;
+ else /* Must be KBD_STATUS_REG */
+ result = jazz_kh->command;


+
+ return result;
+}
+

+static void
+jazz_kbd_outb_p(unsigned char data, unsigned short port)
+{
+ if(port == KBD_DATA_REG)
+ jazz_kh->data = data;
+ else if(port == KBD_CNTL_REG)
+ jazz_kh->command = data;
+ inb(0x80);
+}
+
+static void
+jazz_kbd_outb(unsigned char data, unsigned short port)
+{
+ if(port == KBD_DATA_REG)
+ jazz_kh->data = data;
+ else if(port == KBD_CNTL_REG)
+ jazz_kh->command = data;
+}
+#endif /* CONFIG_MIPS_JAZZ */
+
+#ifdef CONFIG_SGI
+#define INIT_KBD /* full initialization for the keyboard controller. */
+
+static volatile struct hpc_keyb *sgi_kh;
+
+static int
+sgi_kbd_inb(unsigned short port)


+{
+ int result;
+

+ if(port == KBD_DATA_REG)
+ result = sgi_kh->data;
+ else /* Must be KBD_STATUS_REG */
+ result = sgi_kh->command;


+
+ return result;
+}
+

+static void
+sgi_kbd_outb(unsigned char data, unsigned short port)
+{
+ if(port == KBD_DATA_REG)
+ sgi_kh->data = data;
+ else if(port == KBD_CNTL_REG)
+ sgi_kh->command = data;


+}
+#endif /* CONFIG_SGI */

X
-#endif /* __KERNEL__ */
+/*
+ * Most other MIPS machines access the keyboard controller via
+ * ordinary I/O ports.
+ */
+static int
+port_kbd_inb_p(unsigned short port)


+{
+ return inb_p(port);
+}
+

+static int
+port_kbd_inb(unsigned short port)
+{
+ return inb(port);
+}
+
+static void
+port_kbd_outb_p(unsigned char data, unsigned short port)
+{
+ return outb_p(data, port);
+}
+
+static void
+port_kbd_outb(unsigned char data, unsigned short port)
+{
+ return outb(data, port);
+}
+
+extern __inline__ void keyboard_setup(void)
+{
+#ifdef CONFIG_MIPS_JAZZ
+ if (mips_machgroup == MACH_GROUP_JAZZ) {
+ jazz_kh = (void *) JAZZ_KEYBOARD_ADDRESS;
+ kbd_inb_p = jazz_kbd_inb_p;
+ kbd_inb = jazz_kbd_inb;
+ kbd_outb_p = jazz_kbd_outb_p;
+ kbd_outb = jazz_kbd_outb;
+ /*
+ * Enable keyboard interrupts.
+ */
+ *((volatile u16 *)JAZZ_IO_IRQ_ENABLE) |= JAZZ_IE_KEYBOARD;
+ set_cp0_status(IE_IRQ1, IE_IRQ1);
+ } else
+#endif
+ if (mips_machgroup == MACH_GROUP_ARC || /* this is for Deskstation */
+ (mips_machgroup == MACH_GROUP_SNI_RM
+ && mips_machtype == MACH_SNI_RM200_PCI)) {
+ /*
+ * These machines address their keyboard via the normal
+ * port address range.
+ *
+ * Also enable Scan Mode 2.
+ */
+ kbd_inb_p = port_kbd_inb_p;
+ kbd_inb = port_kbd_inb;
+ kbd_outb_p = port_kbd_outb_p;
+ kbd_outb = port_kbd_outb;
+ request_region(0x60,16,"keyboard");
+ }
+#ifdef CONFIG_SGI
+ if (mips_machgroup == MACH_GROUP_SGI) {
+ sgi_kh = (struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64);
+ kbd_inb_p = sgi_kbd_inb;
+ kbd_inb = sgi_kbd_inb;
+ kbd_outb_p = sgi_kbd_outb;
+ kbd_outb = sgi_kbd_outb;
+ }
+#endif
+}
X
-#endif /* __ASMMIPS_KEYBOARD_H */
+#endif /* __KERNEL */
+#endif /* __ASM_MIPS_KEYBOARD_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/mc146818rtc.h linux/include/asm-mips/mc146818rtc.h
--- v2.1.43/linux/include/asm-mips/mc146818rtc.h Thu Apr 11 23:49:44 1996
+++ linux/include/asm-mips/mc146818rtc.h Thu Jun 26 12:33:39 1997
@@ -9,7 +9,7 @@
X
X #ifndef RTC_PORT
X #define RTC_PORT(x) (0x70 + (x))
-#define RTC_ALWAYS_BCD 1
+#define RTC_ALWAYS_BCD 0 /* RTC operates in binary mode */
X #endif
X
X /*
@@ -17,12 +17,10 @@
X * an ISA port access but the way to access the date register differs ...
X */
X #define CMOS_READ(addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-feature->rtc_read_data(); \
+feature->rtc_read_data(addr); \
X })
X #define CMOS_WRITE(val, addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-feature->rtc_write_data(val); \
+feature->rtc_write_data(val, addr); \
X })
X
X #endif /* __ASM_MIPS_MC146818RTC_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/mipsconfig.h linux/include/asm-mips/mipsconfig.h
--- v2.1.43/linux/include/asm-mips/mipsconfig.h Thu Apr 11 23:49:44 1996
+++ linux/include/asm-mips/mipsconfig.h Thu Jun 26 12:33:39 1997
@@ -5,7 +5,7 @@


X * License. See the file "COPYING" in the main directory of this archive
X * for more details.
X *

- * Copyright (C) 1994, 1995 by Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996, 1997 by Ralf Baechle
X */
X #ifndef __ASM_MIPS_MIPSCONFIG_H
X #define __ASM_MIPS_MIPSCONFIG_H
@@ -15,44 +15,16 @@
X * Must be a value that can be load with a lui instruction.
X */
X #ifndef PORT_BASE
-#define PORT_BASE 0xe2000000
+#if !defined (__LANGUAGE_ASSEMBLY__)
+extern unsigned long port_base;
+#endif
+#define PORT_BASE port_base
X #endif
X
-/*
- * Pagetables are 4MB mapped at 0xe4000000
- * Must be a value that can be loaded with a single instruction.
- */
-#define TLBMAP 0xe4000000
-
-/*
- * The virtual address where we'll map the pagetables
- * For a base address of 0xe3000000 this is 0xe338c000
- * For a base address of 0xe4000000 this is 0xe4390000
- * FIXME: Gas computes the following expression with signed
- * shift and therefore false
-#define TLB_ROOT (TLBMAP + (TLBMAP >> (12-2)))
- */
-#define TLB_ROOT 0xe4390000
-
-/*
- * Use this to activate extra TLB error checking
- */
-#define CONF_DEBUG_TLB
-
-/*
- * Use this to activate extra TLB profiling code
- * (currently not implemented)
- */
-#undef CONF_PROFILE_TLB
-
-/*
- * Disable all caching. Useful to find trouble with caches in drivers.
- */
-#undef CONF_DISABLE_KSEG0_CACHING
+/* Pgdir is 1 page mapped at 0xff800000. */
+#define TLBMAP 0xff800000
X
-/*
- * Set this to one to enable additional vdma debug code.
- */
-#define CONF_DEBUG_VDMA 0
+/* The virtual address where we'll map the pgdir. */
+#define TLB_ROOT 0xff000000
X
X #endif /* __ASM_MIPS_MIPSCONFIG_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/mipsprom.h linux/include/asm-mips/mipsprom.h
--- v2.1.43/linux/include/asm-mips/mipsprom.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/mipsprom.h Thu Jun 26 12:33:40 1997
@@ -0,0 +1,74 @@
+#ifndef __ASM_MIPS_PROM_H
+#define __ASM_MIPS_PROM_H
+
+#define PROM_RESET 0
+#define PROM_EXEC 1
+#define PROM_RESTART 2
+#define PROM_REINIT 3
+#define PROM_REBOOT 4
+#define PROM_AUTOBOOT 5
+#define PROM_OPEN 6
+#define PROM_READ 7
+#define PROM_WRITE 8
+#define PROM_IOCTL 9
+#define PROM_CLOSE 10
+#define PROM_GETCHAR 11
+#define PROM_PUTCHAR 12
+#define PROM_SHOWCHAR 13 /* XXX */
+#define PROM_GETS 14 /* XXX */
+#define PROM_PUTS 15 /* XXX */
+#define PROM_PRINTF 16 /* XXX */
+
+/* What are these for? */
+#define PROM_INITPROTO 17 /* XXX */
+#define PROM_PROTOENABLE 18 /* XXX */
+#define PROM_PROTODISABLE 19 /* XXX */
+#define PROM_GETPKT 20 /* XXX */
+#define PROM_PUTPKT 21 /* XXX */
+
+/* More PROM shit. Probably has to do with VME RMW cycles??? */
+#define PROM_ORW_RMW 22 /* XXX */
+#define PROM_ORH_RMW 23 /* XXX */
+#define PROM_ORB_RMW 24 /* XXX */
+#define PROM_ANDW_RMW 25 /* XXX */
+#define PROM_ANDH_RMW 26 /* XXX */
+#define PROM_ANDB_RMW 27 /* XXX */
+
+/* Cache handling stuff */
+#define PROM_FLUSHCACHE 28 /* XXX */
+#define PROM_CLEARCACHE 29 /* XXX */
+
+/* Libc alike stuff */
+#define PROM_SETJMP 30 /* XXX */
+#define PROM_LONGJMP 31 /* XXX */
+#define PROM_BEVUTLB 32 /* XXX */
+#define PROM_GETENV 33 /* XXX */
+#define PROM_SETENV 34 /* XXX */
+#define PROM_ATOB 35 /* XXX */
+#define PROM_STRCMP 36 /* XXX */
+#define PROM_STRLEN 37 /* XXX */
+#define PROM_STRCPY 38 /* XXX */
+#define PROM_STRCAT 39 /* XXX */
+
+/* Misc stuff */
+#define PROM_PARSER 40 /* XXX */
+#define PROM_RANGE 41 /* XXX */
+#define PROM_ARGVIZE 42 /* XXX */
+#define PROM_HELP 43 /* XXX */
+
+/* Entry points for some PROM commands */
+#define PROM_DUMPCMD 44 /* XXX */
+#define PROM_SETENVCMD 45 /* XXX */
+#define PROM_UNSETENVCMD 46 /* XXX */
+#define PROM_PRINTENVCMD 47 /* XXX */
+#define PROM_BEVEXCEPT 48 /* XXX */
+#define PROM_ENABLECMD 49 /* XXX */
+#define PROM_DISABLECMD 50 /* XXX */
+
+#define PROM_CLEARNOFAULT 51 /* XXX */
+#define PROM_NOTIMPLEMENT 52 /* XXX */
+
+#define PROM_NV_GET 53 /* XXX */
+#define PROM_NV_SET 54 /* XXX */
+
+#endif /* __ASM_MIPS_PROM_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/mipsregs.h linux/include/asm-mips/mipsregs.h
--- v2.1.43/linux/include/asm-mips/mipsregs.h Wed Dec 13 02:39:46 1995
+++ linux/include/asm-mips/mipsregs.h Thu Jun 26 12:33:40 1997
@@ -5,17 +5,18 @@


X * License. See the file "COPYING" in the main directory of this archive
X * for more details.
X *

- * Copyright (C) 1994, 1995 by Ralf Baechle


+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle

+ * Modified for further R[236]000 support by Paul M. Antoine, 1996.
X */
-
X #ifndef __ASM_MIPS_MIPSREGS_H
X #define __ASM_MIPS_MIPSREGS_H
X
+#include <linux/linkage.h>
+
X /*
X * The following macros are especially useful for __asm__
X * inline assembler.
X */
-
X #ifndef __STR
X #define __STR(x) #x
X #endif
@@ -24,17 +25,6 @@
X #endif
X
X /*
- * On the R2000/3000 load instructions are not interlocked -
- * we therefore sometimes need to fill load delay slots with a nop
- * which would be useless for ISA >= 2.
- */
-#if !defined (__R4000__)
-#define FILL_LDS nop
-#else
-#define FILL_LDS
-#endif
-
-/*
X * Coprocessor 0 register names
X */
X #define CP0_INDEX $0
@@ -67,6 +57,20 @@
X #define CP0_ERROREPC $30
X
X /*
+ * R4640/R4650 cp0 register names. These registers are listed
+ * here only for completeness; without MMU these CPUs are not useable
+ * by Linux. A future ELKS port might take make Linux run on them
+ * though ...
+ */
+#define CP0_IBASE $0
+#define CP0_IBOUND $1
+#define CP0_DBASE $2
+#define CP0_DBOUND $3
+#define CP0_CALG $17
+#define CP0_IWATCH $18
+#define CP0_DWATCH $19
+
+/*
X * Coprocessor 1 (FPU) register names
X */
X #define CP1_REVISION $0
@@ -104,6 +108,9 @@
X : "=r" (__res)); \
X __res;})
X
+/*
+ * For now use this only with interrupts disabled!
+ */
X #define read_64bit_cp0_register(source) \
X ({ int __res; \
X __asm__ __volatile__( \
@@ -176,9 +183,14 @@
X /*
X * Inline code for use of the ll and sc instructions
X *
- * FIXME: This instruction is only available on MIPS ISA >=3.


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 35'
echo 'File patch-2.1.44 is continued in part 36'
echo 36 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part39

#!/bin/sh
# this is part 39 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 39; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

+#endif /* __ASM_MIPS_SIGNAL_H */
+
+#if !defined (___nsig_defined) && \
+ (defined (__ASM_MIPS_SIGNAL_H) || defined (__need__nsig))
+#define ___nsig_defined
X #define _NSIG 65
+#endif
+#undef __need__nsig
+#ifdef __KERNEL__
X #define NSIG _NSIG
+#endif
X
+#if !defined (__signums_defined) && \
+ (defined (__ASM_MIPS_SIGNAL_H) || defined (__need_signums))
+#define __signums_defined
X /*
X * For 1.3.0 Linux/MIPS changed the signal numbers to be compatible the ABI.
X */
@@ -58,7 +73,10 @@
X #define SIGPROF 29 /* Profiling alarm clock (4.2 BSD). */
X #define SIGXCPU 30 /* CPU limit exceeded (4.2 BSD). */
X #define SIGXFSZ 31 /* File size limit exceeded (4.2 BSD). */
+#endif /* need signums */
+#undef __need_signums
X
+#ifdef __ASM_MIPS_SIGNAL_H
X /*
X * sa_flags values: SA_STACK is not currently supported, but will allow the
X * usage of signal stacks by using the (now obsolete) sa_restorer field in
@@ -87,37 +105,46 @@
X */
X #define SA_PROBE SA_ONESHOT
X #define SA_SAMPLE_RANDOM SA_RESTART
-#endif


+#endif /* __KERNEL__ */
X

-#define SIG_BLOCK 1 /* for blocking signals */
-#define SIG_UNBLOCK 2 /* for unblocking signals */
-#define SIG_SETMASK 3 /* for setting the signal mask */
+#define SIG_BLOCK 1 /* for blocking signals */
+#define SIG_UNBLOCK 2 /* for unblocking signals */
+#define SIG_SETMASK 3 /* for setting the signal mask */
+#define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility:
+ set only the low 32 bit of the sigset. */
X
+#ifndef __sighandler_t_defined
+#define __sighandler_t_defined
X /* Type of a signal handler. */
X typedef void (*__sighandler_t)(int);
+#endif
+#endif
X
+#if !defined (__fake_sigfuns_defined) && \
+ (defined (__ASM_MIPS_SIGNAL_H) || defined (__need_fake_sigfuns))
+#define __fake_sigfuns_defined
X /* Fake signal functions */
X #define SIG_DFL ((__sighandler_t)0) /* default signal handling */
X #define SIG_IGN ((__sighandler_t)1) /* ignore signal */
X #define SIG_ERR ((__sighandler_t)-1) /* error return from signal */
+#endif
+#undef __need_fake_sigfuns
X
+#ifdef __ASM_MIPS_SIGNAL_H
X struct sigaction {
X unsigned int sa_flags;
X __sighandler_t sa_handler;
X sigset_t sa_mask;
- /*
- * To keep the ABI structure size we have to fill a little gap ...
- */
- unsigned int sa_mask_pad[2];
+ unsigned int __pad0[3]; /* reserved, keep size constant */
X
X /* Abi says here follows reserved int[2] */
X void (*sa_restorer)(void);
-#if __mips < 3
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
X /*
X * For 32 bit code we have to pad struct sigaction to get
X * constant size for the ABI
X */
- int pad0[1]; /* reserved */
+ int __pad1[1]; /* reserved */
X #endif
X };
X
@@ -125,4 +152,27 @@
X #include <asm/sigcontext.h>
X #endif
X
-#endif /* __ASM_MIPS_SIGNAL_H */
+#if defined (__KERNEL__) || defined (__USE_MISC)
+/*
+ * The following break codes are or were in use for specific purposes in
+ * other MIPS operating systems. Linux/MIPS doesn't use all of them. The
+ * unused ones are here as placeholders; we might encounter them in
+ * non-Linux/MIPS object files or make use of them in the future.
+ */
+#define BRK_USERBP 0 /* User bp (used by debuggers) */
+#define BRK_KERNELBP 1 /* Break in the kernel */
+#define BRK_ABORT 2 /* Sometimes used by abort(3) to SIGIOT */
+#define BRK_BD_TAKEN 3 /* For bd slot emulation - not implemented */
+#define BRK_BD_NOTTAKEN 4 /* For bd slot emulation - not implemented */
+#define BRK_SSTEPBP 5 /* User bp (used by debuggers) */
+#define BRK_OVERFLOW 6 /* Overflow check */
+#define BRK_DIVZERO 7 /* Divide by zero check */
+#define BRK_RANGE 8 /* Range error check */
+#define BRK_STACKOVERFLOW 9 /* For Ada stackchecking */
+#define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */
+#define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */
+#define BRK_MULOVF 1023 /* Multiply overflow */
+#endif /* defined (__KERNEL__) || defined (__USE_MISC) */
+#endif /* defined (__ASM_MIPS_SIGNAL_H) */
+
+#endif /* !defined (__ASM_MIPS_SIGNAL_H) */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/slots.h linux/include/asm-mips/slots.h
--- v2.1.43/linux/include/asm-mips/slots.h Fri Jan 13 10:37:41 1995
+++ linux/include/asm-mips/slots.h Wed Dec 31 16:00:00 1969
@@ -1,17 +0,0 @@
-/*
- * include/asm-mips/slots.h
- *


- * Copyright (C) 1994 by Waldorf Electronics
- * Written by Ralf Baechle

- */
-#ifndef __ASM_MIPS_SLOTS_H
-#define __ASM_MIPS_SLOTS_H
-
-/*
- * SLOTSPACE is the address to which the physical address 0
- * of the Slotspace is mapped by the chipset in the main CPU's
- * address space.
- */
-#define SLOTSPACE 0xe1000000
-
-#endif /* __ASM_MIPS_SLOTS_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/smp.h linux/include/asm-mips/smp.h
--- v2.1.43/linux/include/asm-mips/smp.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/smp.h Thu Jun 26 12:33:40 1997
@@ -0,0 +1,6 @@
+#ifndef __ASM_MIPS_SMP_H
+#define __ASM_MIPS_SMP_H
+
+/* We'll get here eventually.. */
+
+#endif /* __ASM_MIPS_SMP_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/smp_lock.h linux/include/asm-mips/smp_lock.h
--- v2.1.43/linux/include/asm-mips/smp_lock.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/smp_lock.h Thu Jun 26 12:33:40 1997
@@ -0,0 +1,26 @@
+/*


+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * Copyright (C) 1996 Ralf Baechle
+ *
+ * Linux/MIPS SMP support. Just a dummy to make building possible.
+ */
+#ifndef __ASM_MIPS_SMPLOCK_H
+#define __ASM_MIPS_SMPLOCK_H
+
+#ifndef __SMP__
+
+#define lock_kernel() do { } while(0)
+#define unlock_kernel() do { } while(0)
+#define release_kernel_lock(task, cpu, depth) ((depth) = 1)
+#define reacquire_kernel_lock(task, cpu, depth) do { } while(0)
+
+#else
+
+#error "We do not support SMP on MIPS yet"


+
+#endif /* __SMP__ */
+

+#endif /* __ASM_MIPS_SMPLOCK_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/sni.h linux/include/asm-mips/sni.h
--- v2.1.43/linux/include/asm-mips/sni.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/sni.h Thu Jun 26 12:33:40 1997
@@ -0,0 +1,91 @@


+/*
+ * SNI specific definitions

+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * Copyright (C) 1997 by Ralf Baechle
+ */

+#ifndef __ASM_MIPS_SNI_H
+#define __ASM_MIPS_SNI_H
+
+#define SNI_PORT_BASE 0xb4000000
+
+/*
+ * ASIC PCI registers for little endian configuration.
+ */
+#ifndef __MIPSEL__
+#error "Fix me for big endian"
+#endif
+#define PCIMT_UCONF 0xbfff0000
+#define PCIMT_IOADTIMEOUT2 0xbfff0008
+#define PCIMT_IOMEMCONF 0xbfff0010
+#define PCIMT_IOMMU 0xbfff0018
+#define PCIMT_IOADTIMEOUT1 0xbfff0020
+#define PCIMT_DMAACCESS 0xbfff0028
+#define PCIMT_DMAHIT 0xbfff0030
+#define PCIMT_ERRSTATUS 0xbfff0038
+#define PCIMT_ERRADDR 0xbfff0040
+#define PCIMT_SYNDROME 0xbfff0048
+#define PCIMT_ITPEND 0xbfff0050
+#define PCIMT_IRQSEL 0xbfff0058
+#define PCIMT_TESTMEM 0xbfff0060
+#define PCIMT_ECCREG 0xbfff0068
+#define PCIMT_CONFIG_ADDRESS 0xbfff0070
+#define PCIMT_ASIC_ID 0xbfff0078 /* read */
+#define PCIMT_SOFT_RESET 0xbfff0078 /* write */
+#define PCIMT_PIA_OE 0xbfff0080
+#define PCIMT_PIA_DATAOUT 0xbfff0088
+#define PCIMT_PIA_DATAIN 0xbfff0090
+#define PCIMT_CACHECONF 0xbfff0098
+#define PCIMT_INVSPACE 0xbfff00a0
+#define PCIMT_PCI_CONF 0xbfff0100
+
+/*
+ * Data port for the PCI bus.
+ */
+#define PCIMT_CONFIG_DATA 0xb4000cfc
+
+/*
+ * Board specific registers
+ */
+#define PCIMT_CSMSR 0xbfd00000
+#define PCIMT_CSSWITCH 0xbfd10000
+#define PCIMT_CSITPEND 0xbfd20000
+#define PCIMT_AUTO_PO_EN 0xbfd30000
+#define PCIMT_CLR_TEMP 0xbfd40000
+#define PCIMT_AUTO_PO_DIS 0xbfd50000
+#define PCIMT_EXMSR 0xbfd60000
+#define PCIMT_UNUSED1 0xbfd70000
+#define PCIMT_CSWCSM 0xbfd80000
+#define PCIMT_UNUSED2 0xbfd90000
+#define PCIMT_CSLED 0xbfda0000
+#define PCIMT_CSMAPISA 0xbfdb0000
+#define PCIMT_CSRSTBP 0xbfdc0000
+#define PCIMT_CLRPOFF 0xbfdd0000
+#define PCIMT_CSTIMER 0xbfde0000
+#define PCIMT_PWDN 0xbfdf0000
+
+/*
+ * Interrupt 0-16 are reserved for PCI and EISA interrupts. The
+ * interrupts from 16 are assigned to the other interrupts generated
+ * by the PCI chipset.
+ */
+#define PCIMT_IRQ_ETHERNET 16
+#define PCIMT_IRQ_TEMPERATURE 17
+#define PCIMT_IRQ_EISA_NMI 18
+#define PCIMT_IRQ_POWER_OFF 19
+#define PCIMT_IRQ_BUTTON 20
+#define PCIMT_IRQ_INTA 21
+#define PCIMT_IRQ_INTB 22
+#define PCIMT_IRQ_INTC 23
+#define PCIMT_IRQ_INTD 24
+#define PCIMT_IRQ_SCSI 25
+
+/*
+ * Base address for the mapped 16mb EISA bus segment.
+ */
+#define PCIMT_EISA_BASE 0xb0000000
+
+#endif /* __ASM_MIPS_SNI_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/socket.h linux/include/asm-mips/socket.h
--- v2.1.43/linux/include/asm-mips/socket.h Thu Mar 27 14:40:07 1997
+++ linux/include/asm-mips/socket.h Thu Jun 26 12:33:40 1997
@@ -2,17 +2,7 @@
X #define __ASM_MIPS_SOCKET_H
X
X #include <linux/types.h>
-#include <asm/ioctl.h>
-
-/* Socket-level I/O control calls. */
-#define FIOGETOWN _IOR('f', 123, int)
-#define FIOSETOWN _IOW('f', 124, int)
-
-#define SIOCATMARK _IOR('s', 7, int)
-#define SIOCSPGRP _IOW('s', 8, pid_t)
-#define SIOCGPGRP _IOR('s', 9, pid_t)
-
-#define SIOCGSTAMP 0x8906 /* Get stamp - linux-specific */
+#include <asm/sockios.h>
X
X /*
X * For setsockoptions(2)
@@ -21,43 +11,57 @@
X */
X #define SOL_SOCKET 0xffff
X
-#define SO_DEBUG 0x0001
-#define SO_REUSEADDR 0x0004
-#define SO_KEEPALIVE 0x0008
-#define SO_DONTROUTE 0x0010
-#define SO_BROADCAST 0x0020
-#define SO_LINGER 0x0080
-#define SO_OOBINLINE 0x0100
-/* To add: #define SO_REUSEPORT 0x0200 */
-
-#define SO_TYPE 0x1008
-#define SO_ERROR 0x1007
-#define SO_SNDBUF 0x1001
-#define SO_RCVBUF 0x1002
+#define SO_DEBUG 0x0001 /* Record debugging information. */
+#define SO_REUSEADDR 0x0004 /* Allow reuse of local addresses. */
+#define SO_KEEPALIVE 0x0008 /* Keep connections alive and send
+ SIGPIPE when they die. */
+#define SO_DONTROUTE 0x0010 /* Don't do local routing. */
+#define SO_BROADCAST 0x0020 /* Allow transmission of
+ broadcast messages. */
+#define SO_LINGER 0x0080 /* Block on close of a reliable
+ socket to transmit pending data. */
+#define SO_OOBINLINE 0x0100 /* Receive out-of-band data in-band. */
+#if 0
+To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
+#endif
+
+#define SO_TYPE 0x1008 /* Compatible name for SO_STYLE. */
+#define SO_STYLE SO_TYPE /* Synonym */
+#define SO_ERROR 0x1007 /* get error status and clear */
+#define SO_SNDBUF 0x1001 /* Send buffer size. */
+#define SO_RCVBUF 0x1002 /* Receive buffer. */
+#define SO_SNDLOWAT 0x1003 /* send low-water mark */
+#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
+#define SO_SNDTIMEO 0x1005 /* send timeout */
+#define SO_RCVTIMEO 0x1006 /* receive timeout */
X
X /* linux-specific, might as well be the same as on i386 */
X #define SO_NO_CHECK 11
X #define SO_PRIORITY 12
X #define SO_BSDCOMPAT 14
X
-/*
- * Weird. There are two ABIs; in the old one SOCK_STREAM and SOCK_DGRAM
- * have swapped values. I choose to be compatible with the new one.
- */
-#define SOCK_DGRAM 1 /* datagram (conn.less) socket */
-#define SOCK_STREAM 2 /* stream (connection) socket */
-#define SOCK_RAW 3 /* raw socket */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequential packet socket */
-#define SOCK_PACKET 10 /* linux specific way of */
- /* getting packets at the dev */
- /* level. For writing rarp and */
- /* other similar things on the */
- /* user level. */
+#define SO_PASSCRED 17
+#define SO_PEERCRED 18
X
X /* Security levels - as per NRL IPv6 - don't actually do anything */
X #define SO_SECURITY_AUTHENTICATION 22
X #define SO_SECURITY_ENCRYPTION_TRANSPORT 23
X #define SO_SECURITY_ENCRYPTION_NETWORK 24
+
+/* Types of sockets. */
+enum __socket_type
+{
+ SOCK_DGRAM = 1, /* Connectionless, unreliable datagrams
+ of fixed maximum length. */
+ SOCK_STREAM = 2, /* Sequenced, reliable, connection-based
+ byte streams. */
+ SOCK_RAW = 3, /* Raw protocol interface. */
+ SOCK_RDM = 4, /* Reliably-delivered messages. */
+ SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based,
+ datagrams of fixed maximum length. */
+ SOCK_PACKET = 10, /* linux specific way of getting packets at
+ the dev level. For writing rarp and
+ other similar things on the user level. */
+};
X
X #endif /* __ASM_MIPS_SOCKET_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/sockios.h linux/include/asm-mips/sockios.h
--- v2.1.43/linux/include/asm-mips/sockios.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/sockios.h Thu Jun 26 12:33:40 1997


@@ -0,0 +1,25 @@
+/*

+ * Socket-level I/O control calls.


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * Copyright (C) 1995 by Ralf Baechle
+ */
+#ifndef __ASM_MIPS_SOCKIOS_H
+#define __ASM_MIPS_SOCKIOS_H
+
+#include <asm/ioctl.h>
+
+/* Socket-level I/O control calls. */
+#define FIOGETOWN _IOR('f', 123, int)
+#define FIOSETOWN _IOW('f', 124, int)
+
+#define SIOCATMARK _IOR('s', 7, int)
+#define SIOCSPGRP _IOW('s', 8, pid_t)
+#define SIOCGPGRP _IOR('s', 9, pid_t)
+
+#define SIOCGSTAMP 0x8906 /* Get stamp - linux-specific */
+
+#endif /* __ASM_MIPS_SOCKIOS_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/softirq.h linux/include/asm-mips/softirq.h
--- v2.1.43/linux/include/asm-mips/softirq.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/softirq.h Thu Jun 26 12:33:40 1997
@@ -0,0 +1,93 @@
+#ifndef __ASM_MIPS_SOFTIRQ_H
+#define __ASM_MIPS_SOFTIRQ_H
+
+/* The locking mechanism for base handlers, to prevent re-entrancy,
+ * is entirely private to an implementation, it should not be
+ * referenced at all outside of this file.
+ */
+extern atomic_t __mips_bh_counter;
+
+#define get_active_bhs() (bh_mask & bh_active)
+
+static inline void clear_active_bhs(unsigned long x)
+{
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ "1:\tll\t%0,%1\n\t"
+ "and\t%0,%2\n\t"
+ "sc\t%0,%1\n\t"
+ "beqz\t%0,1b"
+ :"=&r" (temp),
+ "=m" (bh_active)
+ :"Ir" (x),
+ "m" (bh_active));
+}
+
+extern inline void init_bh(int nr, void (*routine)(void))
+{
+ bh_base[nr] = routine;
+ bh_mask_count[nr] = 0;
+ bh_mask |= 1 << nr;
+}
+
+extern inline void remove_bh(int nr)
+{
+ bh_base[nr] = NULL;
+ bh_mask &= ~(1 << nr);
+}
+
+extern inline void mark_bh(int nr)
+{
+ set_bit(nr, &bh_active);
+}
+
+/*
+ * These use a mask count to correctly handle
+ * nested disable/enable calls
+ */
+extern inline void disable_bh(int nr)
+{
+ bh_mask &= ~(1 << nr);
+ bh_mask_count[nr]++;
+}
+
+extern inline void enable_bh(int nr)
+{
+ if (!--bh_mask_count[nr])
+ bh_mask |= 1 << nr;
+}
+
+/*
+ * start_bh_atomic/end_bh_atomic also nest
+ * naturally by using a counter
+ */
+extern inline void start_bh_atomic(void)
+{
+#ifdef __SMP__
+ atomic_inc(&__mips_bh_counter);
+ synchronize_irq();
+#else
+ atomic_inc(&__mips_bh_counter);
+#endif
+}
+
+extern inline void end_bh_atomic(void)
+{
+ atomic_dec(&__mips_bh_counter);
+}
+
+#ifndef __SMP__
+
+/* These are for the irq's testing the lock */
+#define softirq_trylock() (atomic_read(&__mips_bh_counter) ? \
+ 0 : \
+ ((atomic_set(&__mips_bh_counter,1)),1))
+#define softirq_endlock() (atomic_set(&__mips_bh_counter, 0))
+
+#else
+
+#error FIXME


+
+#endif /* __SMP__ */

+#endif /* __ASM_MIPS_SOFTIRQ_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/spinlock.h linux/include/asm-mips/spinlock.h
--- v2.1.43/linux/include/asm-mips/spinlock.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/spinlock.h Thu Jun 26 12:33:40 1997
@@ -0,0 +1,54 @@
+#ifndef __ASM_MIPS_SPINLOCK_H
+#define __ASM_MIPS_SPINLOCK_H
+
+#ifndef __SMP__
+
+/* gcc 2.7.2 can crash initializing an empty structure. For now we
+ try to do though ... */
+typedef struct { } spinlock_t;
+#define SPIN_LOCK_UNLOCKED { }
+
+#define spin_lock_init(lock) do { } while(0)
+#define spin_lock(lock) do { } while(0)
+#define spin_trylock(lock) do { } while(0)
+#define spin_unlock_wait(lock) do { } while(0)
+#define spin_unlock(lock) do { } while(0)
+#define spin_lock_irq(lock) cli()
+#define spin_unlock_irq(lock) sti()
+
+#define spin_lock_irqsave(lock, flags) save_and_cli(flags)
+#define spin_unlock_irqrestore(lock, flags) restore_flags(flags)
+
+/*
+ * Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts
+ * but no interrupt writers. For those circumstances we
+ * can "mix" irq-safe locks - any writer needs to get a
+ * irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ */
+typedef struct { } rwlock_t;
+#define RW_LOCK_UNLOCKED { }
+
+#define read_lock(lock) do { } while(0)
+#define read_unlock(lock) do { } while(0)
+#define write_lock(lock) do { } while(0)
+#define write_unlock(lock) do { } while(0)
+#define read_lock_irq(lock) cli()
+#define read_unlock_irq(lock) sti()
+#define write_lock_irq(lock) cli()
+#define write_unlock_irq(lock) sti()
+
+#define read_lock_irqsave(lock, flags) save_and_cli(flags)
+#define read_unlock_irqrestore(lock, flags) restore_flags(flags)
+#define write_lock_irqsave(lock, flags) save_and_cli(flags)
+#define write_unlock_irqrestore(lock, flags) restore_flags(flags)
+
+#else
+
+#error "Nix SMP on MIPS"
+
+#endif /* SMP */
+#endif /* __ASM_MIPS_SPINLOCK_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/stackframe.h linux/include/asm-mips/stackframe.h
--- v2.1.43/linux/include/asm-mips/stackframe.h Wed Dec 13 02:39:46 1995
+++ linux/include/asm-mips/stackframe.h Thu Jun 26 12:33:40 1997
@@ -1,189 +1,139 @@
X /*
X * include/asm-mips/stackframe.h
X *
- * Copyright (C) 1994, 1995 Waldorf Electronics
- * written by Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Paul M. Antoine.
X */
-
X #ifndef __ASM_MIPS_STACKFRAME_H
X #define __ASM_MIPS_STACKFRAME_H
X
-/*
- * Stack layout for all exceptions:
- *
- * ptrace needs to have all regs on the stack. If the order here is changed,
- * it needs to be updated in include/asm-mips/ptrace.h
- *
- * The first PTRSIZE*5 bytes are argument save space for C subroutines.
- */
-#define FR_REG1 (PTRSIZE*5)
-#define FR_REG2 ((FR_REG1) + 4)
-#define FR_REG3 ((FR_REG2) + 4)
-#define FR_REG4 ((FR_REG3) + 4)
-#define FR_REG5 ((FR_REG4) + 4)
-#define FR_REG6 ((FR_REG5) + 4)
-#define FR_REG7 ((FR_REG6) + 4)
-#define FR_REG8 ((FR_REG7) + 4)
-#define FR_REG9 ((FR_REG8) + 4)
-#define FR_REG10 ((FR_REG9) + 4)
-#define FR_REG11 ((FR_REG10) + 4)
-#define FR_REG12 ((FR_REG11) + 4)
-#define FR_REG13 ((FR_REG12) + 4)
-#define FR_REG14 ((FR_REG13) + 4)
-#define FR_REG15 ((FR_REG14) + 4)
-#define FR_REG16 ((FR_REG15) + 4)
-#define FR_REG17 ((FR_REG16) + 4)
-#define FR_REG18 ((FR_REG17) + 4)
-#define FR_REG19 ((FR_REG18) + 4)
-#define FR_REG20 ((FR_REG19) + 4)
-#define FR_REG21 ((FR_REG20) + 4)
-#define FR_REG22 ((FR_REG21) + 4)
-#define FR_REG23 ((FR_REG22) + 4)
-#define FR_REG24 ((FR_REG23) + 4)
-#define FR_REG25 ((FR_REG24) + 4)
+#include <asm/asm.h>
+#include <asm/offset.h>
X
-/*
- * $26 (k0) and $27 (k1) not saved
- */
-#define FR_REG28 ((FR_REG25) + 4)
-#define FR_REG29 ((FR_REG28) + 4)
-#define FR_REG30 ((FR_REG29) + 4)
-#define FR_REG31 ((FR_REG30) + 4)
-
-/*
- * Saved special registers
- */
-#define FR_LO ((FR_REG31) + 4)
-#define FR_HI ((FR_LO) + 4)
-
-/*
- * Saved cp0 registers follow
- */
-#define FR_STATUS ((FR_HI) + 4)
-#define FR_EPC ((FR_STATUS) + 4)
-#define FR_CAUSE ((FR_EPC) + 4)
+#define SAVE_ALL \
+ mfc0 k0, CP0_STATUS; \
+ sll k0, 3; /* extract cu0 bit */ \
+ bltz k0, 8f; \
+ move k1, sp; \
+ /* Called from user mode, new stack. */ \
+ lui k1, %hi(kernelsp); \
+ lw k1, %lo(kernelsp)(k1); \
+8: \
+ move k0, sp; \
+ subu sp, k1, PT_SIZE; \
+ sw k0, PT_R29(sp); \
+ sw $2, PT_R2(sp); \
+ sw $1, PT_R1(sp); \
+ sw $2, PT_OR2(sp); \
+ sw $0, PT_R0(sp); \
+ mfc0 v0, CP0_STATUS; \
+ sw $3, PT_R3(sp); \
+ sw v0, PT_STATUS(sp); \
+ sw $4, PT_R4(sp); \
+ mfc0 v0, CP0_CAUSE; \
+ sw $5, PT_R5(sp); \
+ sw v0, PT_CAUSE(sp); \
+ sw $6, PT_R6(sp); \
+ mfc0 v0, CP0_EPC; \
+ sw $7, PT_R7(sp); \
+ sw v0, PT_EPC(sp); \
+ sw $7, PT_OR7(sp); \
+ sw $8, PT_R8(sp); \
+ mfhi v0; \
+ sw $9, PT_R9(sp); \
+ sw v0, PT_HI(sp); \
+ sw $10,PT_R10(sp); \
+ mflo v0; \
+ sw $11, PT_R11(sp); \
+ sw v0, PT_LO(sp); \
+ sw $12, PT_R12(sp); \
+ sw $13, PT_R13(sp); \
+ sw $14, PT_R14(sp); \
+ sw $15, PT_R15(sp); \
+ sw $16, PT_R16(sp); \
+ sw $17, PT_R17(sp); \
+ sw $18, PT_R18(sp); \
+ sw $19, PT_R19(sp); \
+ sw $20, PT_R20(sp); \
+ sw $21, PT_R21(sp); \
+ sw $22, PT_R22(sp); \
+ sw $23, PT_R23(sp); \
+ sw $24, PT_R24(sp); \
+ sw $25, PT_R25(sp); \
+ sw $28, PT_R28(sp); \
+ sw $30, PT_R30(sp); \
+ sw $31, PT_R31(sp);
X
X /*
- * Some goodies...
+ * Note that we restore the IE flags from stack. This means
+ * that a modified IE mask will be nullified.
X */
-#define FR_INTERRUPT ((FR_CAUSE) + 4)
-#define FR_ORIG_REG2 ((FR_INTERRUPT) + 4)
-#define FR_PAD1 ((FR_ORIG_REG2) + 4)
+#define RESTORE_ALL \
+ mfc0 t0, CP0_STATUS; \
+ ori t0, 0x1f; \
+ xori t0, 0x1f; \
+ mtc0 t0, CP0_STATUS; \
+ lw v0, PT_STATUS(sp); \
+ lw v1, PT_LO(sp); \
+ mtc0 v0, CP0_STATUS; \
+ mtlo v1; \
+ lw v0, PT_HI(sp); \
+ lw v1, PT_EPC(sp); \
+ mthi v0; \
+ mtc0 v1, CP0_EPC; \
+ lw $31, PT_R31(sp); \
+ lw $30, PT_R30(sp); \
+ lw $28, PT_R28(sp); \
+ lw $25, PT_R25(sp); \
+ lw $24, PT_R24(sp); \
+ lw $23, PT_R23(sp); \
+ lw $22, PT_R22(sp); \
+ lw $21, PT_R21(sp); \
+ lw $20, PT_R20(sp); \
+ lw $19, PT_R19(sp); \
+ lw $18, PT_R18(sp); \
+ lw $17, PT_R17(sp); \
+ lw $16, PT_R16(sp); \
+ lw $15, PT_R15(sp); \
+ lw $14, PT_R14(sp); \
+ lw $13, PT_R13(sp); \
+ lw $12, PT_R12(sp); \
+ lw $11, PT_R11(sp); \
+ lw $10, PT_R10(sp); \
+ lw $9, PT_R9(sp); \
+ lw $8, PT_R8(sp); \
+ lw $7, PT_R7(sp); \
+ lw $6, PT_R6(sp); \
+ lw $5, PT_R5(sp); \
+ lw $4, PT_R4(sp); \
+ lw $3, PT_R3(sp); \
+ lw $2, PT_R2(sp); \
+ lw $1, PT_R1(sp); \
+ lw sp, PT_R29(sp);
X
X /*
- * Size of stack frame, word/double word alignment
+ * Move to kernel mode and disable interrupts.
+ * Set cp0 enable bit as sign that we're running on the kernel stack
X */
-#define FR_SIZE ((((FR_PAD1) + 4) + (PTRSIZE-1)) & ~(PTRSIZE-1))
-
-#ifdef __R4000__
-
-#define SAVE_ALL \
- mfc0 k0,CP0_STATUS; \
- sll k0,3; /* extract cu0 bit */ \
- bltz k0,8f; \
- move k1,sp; \
- /* \
- * Called from user mode, new stack \
- */ \
- lui k1,%hi(kernelsp); \
- lw k1,%lo(kernelsp)(k1); \
-8: move k0,sp; \
- subu sp,k1,FR_SIZE; \
- sw k0,FR_REG29(sp); \
- sw $2,FR_REG2(sp); \
- sw $2,FR_ORIG_REG2(sp); \
- mfc0 v0,CP0_STATUS; \
- sw v0,FR_STATUS(sp); \
- mfc0 v0,CP0_CAUSE; \
- sw v0,FR_CAUSE(sp); \
- mfc0 v0,CP0_EPC; \
- sw v0,FR_EPC(sp); \
- mfhi v0; \
- sw v0,FR_HI(sp); \
- mflo v0; \
- sw v0,FR_LO(sp); \
- sw $1,FR_REG1(sp); \
- sw $3,FR_REG3(sp); \
- sw $4,FR_REG4(sp); \
- sw $5,FR_REG5(sp); \
- sw $6,FR_REG6(sp); \
- sw $7,FR_REG7(sp); \
- sw $8,FR_REG8(sp); \
- sw $9,FR_REG9(sp); \
- sw $10,FR_REG10(sp); \
- sw $11,FR_REG11(sp); \
- sw $12,FR_REG12(sp); \
- sw $13,FR_REG13(sp); \
- sw $14,FR_REG14(sp); \
- sw $15,FR_REG15(sp); \
- sw $16,FR_REG16(sp); \
- sw $17,FR_REG17(sp); \
- sw $18,FR_REG18(sp); \
- sw $19,FR_REG19(sp); \
- sw $20,FR_REG20(sp); \
- sw $21,FR_REG21(sp); \
- sw $22,FR_REG22(sp); \
- sw $23,FR_REG23(sp); \
- sw $24,FR_REG24(sp); \
- sw $25,FR_REG25(sp); \
- sw $28,FR_REG28(sp); \
- sw $30,FR_REG30(sp); \
- sw $31,FR_REG31(sp)
+#define CLI \
+ mfc0 t0,CP0_STATUS; \
+ li t1,ST0_CU0|0x1f; \
+ or t0,t1; \
+ xori t0,0x1f; \
+ mtc0 t0,CP0_STATUS
X
X /*
- * Note that we restore the IE flags from stack. This means
- * that a modified IE mask will be nullified.
+ * Move to kernel mode and enable interrupts.
+ * Set cp0 enable bit as sign that we're running on the kernel stack
+ *
+ * Note that the mtc0 will be effective on R4000 pipeline stage 7. This
+ * means that another three instructions will be executed with interrupts
+ * disabled. Arch/mips/mips3/r4xx0.S makes use of this fact.
X */
-#define RESTORE_ALL \
- .set mips3; \
+#define STI \
X mfc0 t0,CP0_STATUS; \
- ori t0,0x1f; \
- xori t0,0x1f; \
- mtc0 t0,CP0_STATUS; \
- \
- lw v0,FR_STATUS(sp); \
- lw v1,FR_LO(sp); \
- mtc0 v0,CP0_STATUS; \
- mtlo v1; \
- lw v0,FR_HI(sp); \
- lw v1,FR_EPC(sp); \
- mthi v0; \
- mtc0 v1,CP0_EPC; \
- lw $31,FR_REG31(sp); \
- lw $30,FR_REG30(sp); \
- lw $28,FR_REG28(sp); \
- lw $25,FR_REG25(sp); \
- lw $24,FR_REG24(sp); \
- lw $23,FR_REG23(sp); \
- lw $22,FR_REG22(sp); \
- lw $21,FR_REG21(sp); \
- lw $20,FR_REG20(sp); \
- lw $19,FR_REG19(sp); \
- lw $18,FR_REG18(sp); \
- lw $17,FR_REG17(sp); \
- lw $16,FR_REG16(sp); \
- lw $15,FR_REG15(sp); \
- lw $14,FR_REG14(sp); \
- lw $13,FR_REG13(sp); \
- lw $12,FR_REG12(sp); \
- lw $11,FR_REG11(sp); \
- lw $10,FR_REG10(sp); \
- lw $9,FR_REG9(sp); \
- lw $8,FR_REG8(sp); \
- lw $7,FR_REG7(sp); \
- lw $6,FR_REG6(sp); \
- lw $5,FR_REG5(sp); \
- lw $4,FR_REG4(sp); \
- lw $3,FR_REG3(sp); \
- lw $2,FR_REG2(sp); \
- lw $1,FR_REG1(sp); \
- lw sp,FR_REG29(sp); /* Deallocate stack */ \
- .set mips0
-
-#else /* !defined (__R4000__) */
-
-#error "Implement SAVE_ALL and RESTORE_ALL!"
-
-#endif /* !defined (__R4000__) */
+ li t1,ST0_CU0|0x1f; \
+ or t0,t1; \
+ xori t0,0x1e; \
+ mtc0 t0,CP0_STATUS
X
X #endif /* __ASM_MIPS_STACKFRAME_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/stat.h linux/include/asm-mips/stat.h
--- v2.1.43/linux/include/asm-mips/stat.h Thu Apr 11 23:49:44 1996
+++ linux/include/asm-mips/stat.h Thu Jun 26 12:33:40 1997
@@ -3,7 +3,7 @@
X
X #include <linux/types.h>
X
-struct old_stat {
+struct __old_kernel_stat {
X unsigned int st_dev;
X unsigned int st_ino;
X unsigned int st_mode;
@@ -21,7 +21,7 @@
X unsigned int st_gen;
X };
X
-struct new_stat {
+struct stat {
X dev_t st_dev;
X long st_pad1[3]; /* Reserved for network id */
X ino_t st_ino;
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/statfs.h linux/include/asm-mips/statfs.h
--- v2.1.43/linux/include/asm-mips/statfs.h Wed Dec 13 02:39:47 1995
+++ linux/include/asm-mips/statfs.h Thu Jun 26 12:33:40 1997
@@ -1,25 +1,40 @@
+/*
+ * Definitions for the statfs(2) call.


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * Copyright (C) 1995 by Ralf Baechle
+ */
X #ifndef __ASM_MIPS_STATFS_H
X #define __ASM_MIPS_STATFS_H
X
-typedef struct {
- long val[2];
-} fsid_t;
+#include <linux/posix_types.h>
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t fsid_t;
+
+#endif
X
X struct statfs {
- long f_type;
+ long f_type;
X #define f_fstyp f_type
- long f_bsize;
- long f_frsize; /* Fragment size - unsupported */
- long f_blocks;
- long f_bfree;
- long f_files;
- long f_ffree;
+ long f_bsize;
+ long f_frsize; /* Fragment size - unsupported */
+ long f_blocks;
+ long f_bfree;
+ long f_files;
+ long f_ffree;
X
X /* Linux specials */
X long f_bavail;
- fsid_t f_fsid;
- long f_namelen;
- long f_spare[6];
+ __kernel_fsid_t f_fsid;
+ long f_namelen;
+ long f_spare[6];
X };
X
X #endif /* __ASM_MIPS_STATFS_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/string.h linux/include/asm-mips/string.h
--- v2.1.43/linux/include/asm-mips/string.h Wed Dec 13 02:39:47 1995
+++ linux/include/asm-mips/string.h Thu Jun 26 12:33:40 1997
@@ -5,16 +5,15 @@


X * License. See the file "COPYING" in the main directory of this archive
X * for more details.
X *

- * Copyright (c) 1994, 1995 Waldorf Electronics
- * written by Ralf Baechle
+ * Copyright (c) 1994, 1995, 1996 by Ralf Baechle
X */
X #ifndef __ASM_MIPS_STRING_H
X #define __ASM_MIPS_STRING_H
X
X #define __HAVE_ARCH_STRCPY
-extern __inline__ char * strcpy(char * dest, const char *src)
+extern __inline__ char *strcpy(char *__dest, __const__ char *__src)
X {
- char *xdest = dest;
+ char *__xdest = __dest;
X
X __asm__ __volatile__(


X ".set\tnoreorder\n\t"

@@ -26,43 +25,43 @@
X "addiu\t%0,1\n\t"


X ".set\tat\n\t"
X ".set\treorder"

- : "=r" (dest), "=r" (src)
- : "0" (dest), "1" (src)
+ : "=r" (__dest), "=r" (__src)
+ : "0" (__dest), "1" (__src)
X : "$1","memory");
X
- return xdest;
+ return __xdest;
X }
X
X #define __HAVE_ARCH_STRNCPY
-extern __inline__ char * strncpy(char *dest, const char *src, size_t n)
+extern __inline__ char *strncpy(char *__dest, __const__ char *__src, size_t __n)
X {
- char *xdest = dest;
+ char *__xdest = __dest;
X
- if (n == 0)
- return xdest;
+ if (__n == 0)
+ return __xdest;
X
X __asm__ __volatile__(


X ".set\tnoreorder\n\t"
X ".set\tnoat\n"

X "1:\tlbu\t$1,(%1)\n\t"
- "subu\t%2,%2,1\n\t"
+ "subu\t%2,1\n\t"
X "sb\t$1,(%0)\n\t"
X "beqz\t$1,2f\n\t"


- "addiu\t%0,%0,1\n\t"

+ "addiu\t%0,1\n\t"

X "bnez\t%2,1b\n\t"
- "addiu\t%1,%1,1\n"
+ "addiu\t%1,1\n"
X "2:\n\t"


X ".set\tat\n\t"

- ".set\treorder\n\t"
- : "=r" (dest), "=r" (src), "=r" (n)
- : "0" (dest), "1" (src), "2" (n)
+ ".set\treorder"
+ : "=r" (__dest), "=r" (__src), "=r" (__n)
+ : "0" (__dest), "1" (__src), "2" (__n)
X : "$1","memory");
X
- return dest;
+ return __dest;
X }
X
X #define __HAVE_ARCH_STRCMP
-extern __inline__ int strcmp(const char * cs, const char * ct)
+extern __inline__ int strcmp(__const__ char *__cs, __const__ char *__ct)
X {
X int __res;
X
@@ -76,22 +75,22 @@
X "addiu\t%1,1\n\t"
X "bnez\t%2,1b\n\t"
X "lbu\t%2,(%0)\n\t"
-#ifndef __R4000__
+#if _MIPS_ISA == _MIPS_ISA_MIPS1
X "nop\n\t"
X #endif
X "move\t%2,$1\n"
X "2:\tsubu\t%2,$1\n"
X "3:\t.set\tat\n\t"
X ".set\treorder"
- : "=d" (cs), "=d" (ct), "=d" (__res)
- : "0" (cs), "1" (ct)
+ : "=r" (__cs), "=r" (__ct), "=r" (__res)
+ : "0" (__cs), "1" (__ct)


X : "$1");
X
X return __res;
X }

X
X #define __HAVE_ARCH_STRNCMP
-extern __inline__ int strncmp(const char * cs, const char * ct, size_t count)
+extern __inline__ int strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count)
X {
X char __res;
X
@@ -110,118 +109,50 @@
X "3:\tsubu\t%3,$1\n\t"


X ".set\tat\n\t"
X ".set\treorder"

- : "=d" (cs), "=d" (ct), "=d" (count), "=d" (__res)
- : "0" (cs), "1" (ct), "2" (count)
+ : "=r" (__cs), "=r" (__ct), "=r" (__count), "=r" (__res)
+ : "0" (__cs), "1" (__ct), "2" (__count)


X : "$1");
X
X return __res;
X }

X
X #define __HAVE_ARCH_MEMSET
-extern __inline__ void * memset(void * s, int c, size_t count)
-{
- void *xs = s;
-
- if (!count)
- return xs;


- __asm__ __volatile__(
- ".set\tnoreorder\n"

- "1:\tsb\t%3,(%0)\n\t"
- "bne\t%0,%1,1b\n\t"
- "addiu\t%0,%0,1\n\t"
- ".set\treorder"
- : "=r" (s), "=r" (count)
- : "0" (s), "r" (c), "1" (s + count - 1)
- : "memory");
-
- return xs;
-}
+extern void *memset(void *__s, char __c, size_t __count);
X
X #define __HAVE_ARCH_MEMCPY
-extern __inline__ void * memcpy(void * to, const void * from, size_t n)
-{
- void *xto = to;
-
- if (!n)
- return xto;


- __asm__ __volatile__(
- ".set\tnoreorder\n\t"

- ".set\tnoat\n"
- "1:\tlbu\t$1,(%1)\n\t"
- "addiu\t%1,1\n\t"
- "sb\t$1,(%0)\n\t"
- "subu\t%2,1\n\t"
- "bnez\t%2,1b\n\t"
- "addiu\t%0,1\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- : "=r" (to), "=r" (from), "=r" (n)
- : "0" (to), "1" (from), "2" (n)
- : "$1","memory" );
- return xto;
-}
+extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
X
X #define __HAVE_ARCH_MEMMOVE
-extern __inline__ void * memmove(void * dest,const void * src, size_t n)
-{
- void *xdest = dest;
-
- if (!n)
- return xdest;
+extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
X
- if (dest < src)


- __asm__ __volatile__(
- ".set\tnoreorder\n\t"

- ".set\tnoat\n"
- "1:\tlbu\t$1,(%1)\n\t"
- "addiu\t%1,1\n\t"
- "sb\t$1,(%0)\n\t"
- "subu\t%2,1\n\t"
- "bnez\t%2,1b\n\t"
- "addiu\t%0,1\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- : "=r" (dest), "=r" (src), "=r" (n)
- : "0" (dest), "1" (src), "2" (n)
- : "$1","memory" );
- else


- __asm__ __volatile__(
- ".set\tnoreorder\n\t"

- ".set\tnoat\n"
- "1:\tlbu\t$1,-1(%1)\n\t"
- "subu\t%1,1\n\t"
- "sb\t$1,-1(%0)\n\t"
- "subu\t%2,1\n\t"
- "bnez\t%2,1b\n\t"
- "subu\t%0,1\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- : "=r" (dest), "=r" (src), "=r" (n)
- : "0" (dest+n), "1" (src+n), "2" (n)
- : "$1","memory" );
- return xdest;
-}
+#define __HAVE_ARCH_BCOPY
+extern char * bcopy(const char * src, char * dest, int count);
X
X #define __HAVE_ARCH_MEMSCAN
-extern __inline__ void * memscan(void * addr, int c, size_t size)
+extern __inline__ void *memscan(void *__addr, int __c, size_t __size)
X {
- if (!size)
- return addr;
+ char *__end = (char *)__addr + __size;
+
+ if (!__size)
+ return __addr;
X __asm__(".set\tnoreorder\n\t"
X ".set\tnoat\n"
- "1:\tbeqz\t%1,2f\n\t"
- "lbu\t$1,(%0)\n\t"
- "subu\t%1,1\n\t"
- "bnez\t%1,1b\n\t"
+ "1:\tlbu\t$1,(%0)\n\t"
+#if _MIPS_ISA == _MIPS_ISA_MIPS1
+ "nop\n\t"
+#endif
+ "beq\t$1,%3,2f\n\t"
X "addiu\t%0,1\n\t"
+ "bne\t%0,%2,1b\n\t"
+ "nop\n\t"


X ".set\tat\n\t"

X ".set\treorder\n"
X "2:"

- : "=r" (addr), "=r" (size)
- : "0" (addr), "1" (size), "r" (c)
+ : "=r" (__addr)
+ : "0" (__addr), "1" (__end), "r" (__c)
X : "$1");
X
- return addr;
+ return __addr;
X }
X
X #endif /* __ASM_MIPS_STRING_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/sysmips.h linux/include/asm-mips/sysmips.h
--- v2.1.43/linux/include/asm-mips/sysmips.h Thu Apr 11 23:49:44 1996
+++ linux/include/asm-mips/sysmips.h Thu Jun 26 12:33:40 1997
@@ -19,6 +19,7 @@
X #define SETNAME 1 /* set hostname */
X #define FLUSH_CACHE 3 /* writeback and invalidate caches */
X #define MIPS_FIXADE 7 /* control address error fixing */
+#define MIPS_RDNVRAM 10 /* read NVRAM */
X #define MIPS_ATOMIC_SET 2001 /* atomically set variable */
X
X #endif /* __ASM_MIPS_SYSMIPS_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/system.h linux/include/asm-mips/system.h
--- v2.1.43/linux/include/asm-mips/system.h Wed Dec 13 02:39:47 1995
+++ linux/include/asm-mips/system.h Thu Jun 26 12:33:40 1997
@@ -6,33 +6,73 @@


X * for more details.
X *

X * Copyright (C) 1994, 1995 by Ralf Baechle
+ * Modified further for R[236]000 by Paul M. Antoine, 1996
X */
X #ifndef __ASM_MIPS_SYSTEM_H
X #define __ASM_MIPS_SYSTEM_H
X
+#include <asm/sgidefs.h>
X #include <linux/kernel.h>
X
-#if defined (__R4000__)
-#define sti() \
+extern __inline__ void
+__sti(void)
+{
+ __asm__ __volatile__(


+ ".set\tnoreorder\n\t"

+ ".set\tnoat\n\t"
+ "mfc0\t$1,$12\n\t"
+ "ori\t$1,0x1f\n\t"
+ "xori\t$1,0x1e\n\t"
+ "mtc0\t$1,$12\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"


+ : /* no outputs */

+ : /* no inputs */
+ : "$1", "memory");
+}
+
+/*
+ * For cli() we have to insert nops to make shure that the new value
+ * has actually arrived in the status register before the end of this
+ * macro.
+ * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
+ * no nops at all.


+ */
+extern __inline__ void

+__cli(void)
+{
+ __asm__ __volatile__(


+ ".set\tnoreorder\n\t"

+ ".set\tnoat\n\t"
+ "mfc0\t$1,$12\n\t"
+ "ori\t$1,1\n\t"
+ "xori\t$1,1\n\t"
+ "mtc0\t$1,$12\n\t"


+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"

+ ".set\tat\n\t"
+ ".set\treorder"


+ : /* no outputs */

+ : /* no inputs */
+ : "$1", "memory");
+}
+
+#define __save_flags(x) \
X __asm__ __volatile__( \


X ".set\tnoreorder\n\t" \

- ".set\tnoat\n\t" \

- "mfc0\t$1,$12\n\t" \
- "ori\t$1,0x1f\n\t" \
- "xori\t$1,0x1e\n\t" \
- "mtc0\t$1,$12\n\t" \


- ".set\tat\n\t" \

+ "mfc0\t%0,$12\n\t" \
X ".set\treorder" \
- : /* no outputs */ \
+ : "=r" (x) \
X : /* no inputs */ \
- : "$1")
+ : "memory")
X
-#define cli() \
+#define __save_and_cli(x) \
X __asm__ __volatile__( \


X ".set\tnoreorder\n\t" \

X ".set\tnoat\n\t" \
- "mfc0\t$1,$12\n\t" \
- "ori\t$1,1\n\t" \
+ "mfc0\t%0,$12\n\t" \
+ "ori\t$1,%0,1\n\t" \
X "xori\t$1,1\n\t" \
X "mtc0\t$1,$12\n\t" \
X "nop\n\t" \
@@ -40,78 +80,71 @@
X "nop\n\t" \


X ".set\tat\n\t" \

X ".set\treorder" \
- : /* no outputs */ \
+ : "=r" (x) \
X : /* no inputs */ \
- : "$1")
+ : "$1", "memory")
+
+extern void __inline__
+__restore_flags(int flags)
+{
+ __asm__ __volatile__(


+ ".set\tnoreorder\n\t"

+ "mtc0\t%0,$12\n\t"


+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ ".set\treorder"

+ : /* no output */
+ : "r" (flags)
+ : "memory");
+}
X
-#else /* !defined (__R4000__) */
X /*
- * Untested goodies for the R3000 based DECstation et al.
+ * Non-SMP versions ...
X */
-#define sti() \
-__asm__ __volatile__( \


- ".set\tnoreorder\n\t" \

- ".set\tnoat\n\t" \

- "mfc0\t$1,$12\n\t" \
- "ori\t$1,0x01\n\t" \
- "mtc0\t$1,$12\n\t" \
- ".set\tat\n\t" \
- ".set\treorder" \
- : /* no outputs */ \
- : /* no inputs */ \
- : "$1")
-
-#define cli() \
-__asm__ __volatile__( \


- ".set\tnoreorder\n\t" \

- ".set\tnoat\n\t" \

- "mfc0\t$1,$12\n\t" \
- "ori\t$1,1\n\t" \
- "xori\t$1,1\n\t" \
- "mtc0\t$1,$12\n\t" \
- ".set\tat\n\t" \
- ".set\treorder" \
- : /* no outputs */ \
- : /* no inputs */ \
- : "$1")
-#endif /* !defined (__R4000__) */
+#define sti() __sti()
+#define cli() __cli()
+#define save_flags(x) __save_flags(x)
+#define save_and_cli(x) __save_and_cli(x)
+#define restore_flags(x) __restore_flags(x)
X
-#define nop() __asm__ __volatile__ ("nop")
-
-#define save_flags(x) \
+#define sync_mem() \
X __asm__ __volatile__( \


X ".set\tnoreorder\n\t" \

- "mfc0\t%0,$12\n\t" \
+ "sync\n\t" \
X ".set\treorder" \
- : "=r" (x)) \
+ : /* no output */ \
+ : /* no input */ \
+ : "memory")
X
-#define restore_flags(x) \
-__asm__ __volatile__( \


- ".set\tnoreorder\n\t" \

- "mtc0\t%0,$12\n\t" \


- "nop\n\t" \
- "nop\n\t" \
- "nop\n\t" \

- ".set\treorder" \
- : /* no output */ \
- : "r" (x)) \
+#if !defined (__LANGUAGE_ASSEMBLY__)
+/*
+ * switch_to(n) should switch tasks to task nr n, first
+ * checking that n isn't the current task, in which case it does nothing.
+ */
+extern asmlinkage void (*resume)(void *tsk);
+#endif /* !defined (__LANGUAGE_ASSEMBLY__) */
X
-#define sync_mem() \
-__asm__ __volatile__( \


- ".set\tnoreorder\n\t" \

- "sync\n\t" \
- ".set\treorder") \
+/*
+ * FIXME: resume() assumes current == prev
+ */
+#define switch_to(prev,next) \
+do { \
+ prev->tss.current_ds = active_ds; \
+ active_ds = next->tss.current_ds; \
+ resume(next); \
+} while(0)
X
X /*
X * The 8 and 16 bit variants have to disable interrupts temporarily.
X * Both are currently unused.
X */
-extern inline unsigned long xchg_u8(volatile char * m, unsigned long val)
+extern __inline__ unsigned long xchg_u8(volatile char * m, unsigned long val)
X {
X unsigned long flags, retval;
X
X save_flags(flags);
- sti();
+ cli();
X retval = *m;
X *m = val;
X restore_flags(flags);
@@ -119,12 +152,12 @@
X return retval;
X }
X
-extern inline unsigned long xchg_u16(volatile short * m, unsigned long val)
+extern __inline__ unsigned long xchg_u16(volatile short * m, unsigned long val)
X {
X unsigned long flags, retval;
X
X save_flags(flags);
- sti();
+ cli();
X retval = *m;
X *m = val;
X restore_flags(flags);
@@ -136,8 +169,10 @@
X * For 32 and 64 bit operands we can take advantage of ll and sc.
X * FIXME: This doesn't work for R3000 machines.
X */
-extern inline unsigned long xchg_u32(volatile int * m, unsigned long val)
+extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
X {


+#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)

X unsigned long dummy;
X
X __asm__ __volatile__(
@@ -152,14 +187,23 @@
X ".set\treorder"
X : "=r" (val), "=r" (m), "=r" (dummy)
X : "1" (m), "2" (val));
+#else /* FIXME: Brain-dead approach, but then again, I AM hacking - PMA */
+ unsigned long flags, retval;
+
+ save_flags(flags);
+ cli();
+ retval = *m;
+ *m = val;
+ restore_flags(flags);
X
+#endif /* Processor-dependent optimization */
X return val;
X }
X
X /*
X * Only used for 64 bit kernel.
X */
-extern inline unsigned long xchg_u64(volatile long * m, unsigned long val)
+extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val)
X {
X unsigned long dummy;
X
@@ -192,7 +236,7 @@
X */
X extern void __xchg_called_with_bad_pointer(void);
X
-static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
X {
X switch (size) {
X case 1:
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/termbits.h linux/include/asm-mips/termbits.h
--- v2.1.43/linux/include/asm-mips/termbits.h Thu Apr 11 23:49:44 1996
+++ linux/include/asm-mips/termbits.h Thu Jun 26 12:33:40 1997
@@ -1,25 +1,26 @@
+/*
+ * termbits stuff for Linux/MIPS.


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996 by Ralf Baechle
+ */

X #ifndef __ASM_MIPS_TERMBITS_H
X #define __ASM_MIPS_TERMBITS_H
X
-#include <asm/ioctl.h>
-#include <asm/ioctls.h>
+#include <linux/posix_types.h>
+
+typedef unsigned char cc_t;
+typedef unsigned long speed_t;
+typedef unsigned long tcflag_t;
X
X /*
X * The ABI says nothing about NCC but seems to use NCCS as
X * replacement for it in struct termio
X */
-#define NCC 8
X #define NCCS 23
-
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- char c_line; /* line discipline */
- unsigned char c_cc[NCCS]; /* control characters */
-};
-
X struct termios {
X tcflag_t c_iflag; /* input mode flags */
X tcflag_t c_oflag; /* output mode flags */
@@ -31,5 +32,175 @@
X cc_t c_line; /* line discipline */
X cc_t c_cc[NCCS]; /* control characters */
X };
+
+/* c_cc characters */
+#define VINTR 0 /* Interrupt character [ISIG]. */
+#define VQUIT 1 /* Quit character [ISIG]. */
+#define VERASE 2 /* Erase character [ICANON]. */
+#define VKILL 3 /* Kill-line character [ICANON]. */
+#define VMIN 4 /* Minimum number of bytes read at once [!ICANON]. */
+#define VTIME 5 /* Time-out value (tenths of a second) [!ICANON]. */
+#define VEOL2 6 /* Second EOL character [ICANON]. */
+#define VSWTC 7 /* ??? */
+#define VSWTCH VSWTC
+#define VSTART 8 /* Start (X-ON) character [IXON, IXOFF]. */
+#define VSTOP 9 /* Stop (X-OFF) character [IXON, IXOFF]. */
+#define VSUSP 10 /* Suspend character [ISIG]. */
+#if 0
+/*
+ * VDSUSP is not supported
+ */
+#define VDSUSP 11 /* Delayed suspend character [ISIG]. */
+#endif
+#define VREPRINT 12 /* Reprint-line character [ICANON]. */
+#define VDISCARD 13 /* Discard character [IEXTEN]. */
+#define VWERASE 14 /* Word-erase character [ICANON]. */
+#define VLNEXT 15 /* Literal-next character [IEXTEN]. */
+#define VEOF 16 /* End-of-file character [ICANON]. */
+#define VEOL 17 /* End-of-line character [ICANON]. */
+
+/* c_iflag bits */
+#define IGNBRK 0000001 /* Ignore break condition. */
+#define BRKINT 0000002 /* Signal interrupt on break. */
+#define IGNPAR 0000004 /* Ignore characters with parity errors. */
+#define PARMRK 0000010 /* Mark parity and framing errors. */
+#define INPCK 0000020 /* Enable input parity check. */
+#define ISTRIP 0000040 /* Strip 8th bit off characters. */
+#define INLCR 0000100 /* Map NL to CR on input. */
+#define IGNCR 0000200 /* Ignore CR. */
+#define ICRNL 0000400 /* Map CR to NL on input. */
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define IUCLC 0001000 /* Map upper case to lower case on input. */
+#endif
+#define IXON 0002000 /* Enable start/stop output control. */
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define IXANY 0004000 /* Any character will restart after stop. */
+#endif
+#define IXOFF 0010000 /* Enable start/stop input control. */
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define IMAXBEL 0020000 /* Ring bell when input queue is full. */
+#endif
+
+/* c_oflag bits */
+#define OPOST 0000001 /* Perform output processing. */
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define OLCUC 0000002 /* Map lower case to upper case on output. */
+#define ONLCR 0000004 /* Map NL to CR-NL on output. */
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define XTABS 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+/*
+#define PAGEOUT ???
+#define WRAP ???
+ */
+#endif
+
+/* c_cflag bit meaning */
+#define CBAUD 0010017
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0000060 /* Number of bits per byte (mask). */
+#define CS5 0000000 /* 5 bits per byte. */
+#define CS6 0000020 /* 6 bits per byte. */
+#define CS7 0000040 /* 7 bits per byte. */
+#define CS8 0000060 /* 8 bits per byte. */
+#define CSTOPB 0000100 /* Two stop bits instead of one. */
+#define CREAD 0000200 /* Enable receiver. */
+#define PARENB 0000400 /* Parity enable. */
+#define PARODD 0001000 /* Odd parity instead of even. */
+#define HUPCL 0002000 /* Hang up on last close. */
+#define CLOCAL 0004000 /* Ignore modem status lines. */
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define CBAUDEX 0010000
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define CIBAUD 002003600000 /* input baud rate (not used) */
+#define CISPAR 010000000000 /* mark or space (stick) parity */
+#define CRTSCTS 020000000000 /* flow control */
+#endif
+
+/* c_lflag bits */
+#define ISIG 0000001 /* Enable signals. */
+#define ICANON 0000002 /* Do erase and kill processing. */
+#define XCASE 0000004
+#define ECHO 0000010 /* Enable echo. */
+#define ECHOE 0000020 /* Visual erase for ERASE. */
+#define ECHOK 0000040 /* Echo NL after KILL. */
+#define ECHONL 0000100 /* Echo NL even if ECHO is off. */
+#define NOFLSH 0000200 /* Disable flush after interrupt. */
+#define IEXTEN 0000400 /* Enable DISCARD and LNEXT. */
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define ECHOCTL 0001000 /* Echo control characters as ^X. */
+#define ECHOPRT 0002000 /* Hardcopy visual erase. */
+#define ECHOKE 0004000 /* Visual erase for KILL. */
+#endif
+#define FLUSHO 0020000
+#if defined (__USE_BSD) || defined (__KERNEL__)
+#define PENDIN 0040000 /* Retype pending input (state). */
+#endif
+#define TOSTOP 0100000 /* Send SIGTTOU for background output. */
+#define ITOSTOP TOSTOP
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0 /* Suspend output. */
+#define TCOON 1 /* Restart suspended output. */
+#define TCIOFF 2 /* Send a STOP character. */
+#define TCION 3 /* Send a START character. */
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0 /* Discard data received but not yet read. */
+#define TCOFLUSH 1 /* Discard data written but not yet sent. */
+#define TCIOFLUSH 2 /* Discard all pending data. */
+
+/* tcsetattr uses these */
+#define TCSANOW TCSETS /* Change immediately. */
+#define TCSADRAIN TCSETSW /* Change when pending output is written. */
+#define TCSAFLUSH TCSETSF /* Flush pending input before changing. */
X
X #endif /* __ASM_MIPS_TERMBITS_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/termios.h linux/include/asm-mips/termios.h
--- v2.1.43/linux/include/asm-mips/termios.h Mon Dec 30 02:56:38 1996
+++ linux/include/asm-mips/termios.h Thu Jun 26 12:33:40 1997
@@ -1,8 +1,45 @@


+/*
+ * ioctls for Linux/MIPS.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996 by Ralf Baechle
+ */

X #ifndef __ASM_MIPS_TERMIOS_H
-#define __ASM_MIPS_TERMIOS_H
X
-#include <linux/types.h>
X #include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct sgttyb {
+ char sg_ispeed;
+ char sg_ospeed;
+ char sg_erase;
+ char sg_kill;
+ int sg_flags; /* SGI special - int, not short */
+};
+
+struct tchars {
+ char t_intrc;
+ char t_quitc;
+ char t_startc;
+ char t_stopc;
+ char t_eofc;
+ char t_brkc;
+};
+
+struct ltchars {
+ char t_suspc; /* stop process signal */
+ char t_dsuspc; /* delayed stop process signal */
+ char t_rprntc; /* reprint line */
+ char t_flushc; /* flush output (toggles) */
+ char t_werasc; /* word erase */
+ char t_lnextc; /* literal next character */
+};
+
+/* TIOCGSIZE, TIOCSSIZE not defined yet. Only needed for SunOS source
+ compatibility anyway ... */
X
X struct winsize {
X unsigned short ws_row;
@@ -11,15 +48,60 @@
X unsigned short ws_ypixel;
X };
X
-/* ----------------------------------------------------------------------- */
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ char c_line; /* line discipline */
+ unsigned char c_cc[NCCS]; /* control characters */
+};
+
+#ifdef __KERNEL__
+/*
+ * intr=^C quit=^\ erase=del kill=^U
+ * vmin=\1 vtime=\0 eol2=\0 swtc=\0
+ * start=^Q stop=^S susp=^Z vdsusp=
+ * reprint=^R discard=^U werase=^W lnext=^V
+ * eof=^D eol=\0
+ */
+#define INIT_C_CC "\003\034\177\025\1\0\0\0\021\023\032\0\022\017\027\026\004\0"
+#endif
+
+/* modem lines */
+#define TIOCM_LE 0x001 /* line enable */
+#define TIOCM_DTR 0x002 /* data terminal ready */
+#define TIOCM_RTS 0x004 /* request to send */
+#define TIOCM_ST 0x010 /* secondary transmit */
+#define TIOCM_SR 0x020 /* secondary receive */
+#define TIOCM_CTS 0x040 /* clear to send */
+#define TIOCM_CAR 0x100 /* carrier detect */
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RNG 0x200 /* ring */
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_DSR 0x400 /* data set ready */
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+
+/* line disciplines */
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6 /* X.25 async */


X
X #ifdef __KERNEL__
X

+#include <linux/string.h>
+
X /*
X * Translate a "termio" structure into a "termios". Ugh.
X */
X #define user_termio_to_kernel_termios(termios, termio) \
-do { \
+({ \
X unsigned short tmp; \
X get_user(tmp, &(termio)->c_iflag); \
X (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
@@ -31,24 +113,24 @@
X (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
X get_user((termios)->c_line, &(termio)->c_line); \
X copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
-} while(0)
+})
X
X /*
X * Translate a "termios" structure into a "termio". Ugh.
X */
X #define kernel_termios_to_user_termio(termio, termios) \
-do { \
+({ \
X put_user((termios)->c_iflag, &(termio)->c_iflag); \
X put_user((termios)->c_oflag, &(termio)->c_oflag); \
X put_user((termios)->c_cflag, &(termio)->c_cflag); \
X put_user((termios)->c_lflag, &(termio)->c_lflag); \
X put_user((termios)->c_line, &(termio)->c_line); \
X copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 39'
echo 'File patch-2.1.44 is continued in part 40'
echo 40 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part42

#!/bin/sh
# this is part 42 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 42; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

X
X #endif /* !(_SPARC_VADDRS_H) */
X
diff -u --recursive --new-file v2.1.43/linux/include/linux/binfmts.h linux/include/linux/binfmts.h
--- v2.1.43/linux/include/linux/binfmts.h Mon Jun 16 16:36:00 1997
+++ linux/include/linux/binfmts.h Mon Jul 7 08:24:28 1997
@@ -50,6 +50,7 @@
X extern int init_elf_binfmt(void);
X extern int init_elf32_binfmt(void);
X extern int init_aout_binfmt(void);
+extern int init_aout32_binfmt(void);
X extern int init_script_binfmt(void);
X extern int init_java_binfmt(void);
X extern int init_em86_binfmt(void);
diff -u --recursive --new-file v2.1.43/linux/include/linux/console_struct.h linux/include/linux/console_struct.h
--- v2.1.43/linux/include/linux/console_struct.h Mon Jun 16 16:36:00 1997
+++ linux/include/linux/console_struct.h Mon Jul 7 16:02:33 1997
@@ -4,6 +4,8 @@
X * Data structure and defines shared between console.c, vga.c and tga.c


X */
X
+#include <linux/config.h>

+
X #define NPAR 16
X
X struct vc_data {
@@ -17,12 +19,17 @@
X unsigned char vc_halfcolor; /* Colour for half intensity mode */
X unsigned long vc_origin; /* Used for EGA/VGA fast scroll */
X unsigned long vc_scr_end; /* Used for EGA/VGA fast scroll */
- unsigned long vc_pos;
X unsigned long vc_x,vc_y;
X unsigned long vc_top,vc_bottom;
X unsigned long vc_state;
X unsigned long vc_npar,vc_par[NPAR];
+#ifdef CONFIG_FB_CONSOLE
+ unsigned short *vc_video_mem_start; /* Start of video RAM */
+ unsigned short *vc_pos;
+#else
+ unsigned long vc_pos;
X unsigned long vc_video_mem_start; /* Start of video RAM */
+#endif
X unsigned long vc_video_mem_end; /* End of video RAM (sort of) */
X unsigned long vc_saved_x;
X unsigned long vc_saved_y;
diff -u --recursive --new-file v2.1.43/linux/include/linux/dalloc.h linux/include/linux/dalloc.h
--- v2.1.43/linux/include/linux/dalloc.h Mon Jun 16 16:36:00 1997
+++ linux/include/linux/dalloc.h Mon Jul 7 14:57:40 1997
@@ -9,16 +9,19 @@
X * <scho...@informatik.uni-stuttgart.de>.
X */
X
-#define D_MAXLEN 1024
+#define D_MAXLEN 1024
X
X /* public flags for d_add() */
-#define D_NORMAL 0
-#define D_BASKET 1 /* put into basket (deleted/unref'd files) */
-#define D_DUPLICATE 2 /* allow duplicate entries */
-#define D_NOCHECKDUP 4 /* no not check for duplicates */
-
-/* public flags for d_flag */
-#define D_PRELOADED 8
+#define D_NORMAL 0
+#define D_BASKET 1 /* put into basket (deleted/unref'd files) */
+#define D_DUPLICATE 2 /* allow duplicate entries */
+#define D_NOCHECKDUP 4 /* no not check for duplicates */
+#define D_NEGATIVE 8 /* negative entry */
+#define D_PRELOADED 16
+#define D_DIR 32 /* directory entry - look out for allocation issues */
+#define D_HASHED 64
+#define D_ZOMBIE 128
+#define D_INC_DDIR 512
X
X /* public flags for d_del() */
X #define D_REMOVE 0
@@ -26,53 +29,78 @@
X
X #define IS_ROOT(x) ((x) == (x)->d_parent)
X
+/* "quick string" -- I introduced this to shorten the parameter list
+ * of many routines. Think of it as a (str,stlen,hash) pair.
+ * Storing the len instead of doing strlen() very often is performance
+ * critical.
+ */
+struct qstr {
+ const unsigned char * name;
+ int len, hash;
+};
+
+/* Name hashing routines. Initial hash value */
+#define init_name_hash() 0
+
+/* partial hash update function. Assume roughly 4 bits per character */
+static inline unsigned long partial_name_hash(unsigned char c, unsigned long prevhash)
+{
+ prevhash = (prevhash << 4) | (prevhash >> (8*sizeof(unsigned long)-4));
+ return prevhash ^ c;
+}
+
+/* Finally: cut down the number of bits to a int value (and try to avoid losing bits) */
+static inline unsigned long end_name_hash(unsigned long hash)
+{
+ if (sizeof(hash) > sizeof(unsigned int))
+ hash += hash >> 4*sizeof(hash);
+ return (unsigned int) hash;
+}
+
X struct dentry {
- union {
- struct inode * d_inode; /* Where the name belongs to */
- unsigned long d_ino; /* for preliminary entries */
- } u;
- struct dentry * d_parent; /* parent directory */
- struct dentry * d_next; /* hardlink aliasname / empty list */
- struct dentry * d_prev; /* hardlink aliasname */
+ unsigned int d_flag;
+ unsigned int d_count;
+ struct inode * d_inode; /* Where the name belongs to */
+ struct dentry * d_parent; /* parent directory */
+ struct dentry * d_mounts; /* mount information */
+ struct dentry * d_covers;
+ struct dentry * d_next; /* hardlink aliasname / empty list */
+ struct dentry * d_prev; /* hardlink aliasname */
X struct dentry * d_hash_next;
X struct dentry * d_hash_prev;
X struct dentry * d_basket_next;
X struct dentry * d_basket_prev;
- short d_len; /* set by dalloc() */
- short d_flag;
- char d_name[D_MAXLEN];
+ struct qstr d_name;
X };
X
-/* "quick string" -- I introduced this to shorten the parameter list
- * of many routines. Think of it as a (str,stlen) pair.
- * Storing the len instead of doing strlen() very often is performance
- * critical.
+extern struct dentry * the_root;
+
+/*
+ * These are the low-level FS interfaces to the dcache..
X */
-struct qstr {
- const char * name;
- int len;
-};
+extern void d_instantiate(struct dentry *, struct inode *, int);
+extern void d_delete(struct dentry *);
X
-extern struct dentry * the_root;
X
X /* Note that all these routines must be called with vfs_lock() held */
X
X /* get inode, if necessary retrieve it with iget() */
X extern blocking struct inode * d_inode(struct dentry ** changing_entry);
X
-/* allocate proper space for the len */
-extern struct dentry * d_alloc(struct dentry * parent, int len, int isdir);
+/* allocate/de-allocate */
+extern void d_free(struct dentry *);
+extern struct dentry * d_alloc(struct dentry * parent, struct qstr *name, int isdir);
X
-/* only used once at mount_root() */
+/* only used at mount-time */
X extern blocking
-struct dentry * d_alloc_root(struct inode * root_inode);
+struct dentry * d_alloc_root(struct inode * root_inode, struct dentry * old_root);
X
-/* d_inode is connected with inode, and d_name is copied from ininame.
- * either of them may be NULL, but when ininame is NULL, dname must be
- * set by the caller prior to calling this. */
+/*
+ * This adds the entry to the hash queues and initializes "d_inode".
+ * The entry was actually filled in earlier during "d_alloc()"
+ */
X extern blocking
-void d_add(struct dentry * entry, struct inode * inode,
- struct qstr * ininame, int flags);
+void d_add(struct dentry * entry, struct inode * inode, int flags);
X
X /* combination of d_alloc() and d_add(), less lookup overhead */
X extern blocking
@@ -86,17 +114,32 @@
X
X /* used for rename() and baskets */
X extern blocking
-void d_move(struct dentry * entry, struct inode * newdir,
- struct qstr * newname, struct qstr * newapp);
+void d_move(struct dentry * entry, struct dentry * newparent, struct qstr * newname);
X
X /* appendix may either be NULL or be used for transname suffixes */
-extern struct dentry * d_lookup(struct inode * dir, struct qstr * name,
- struct qstr * appendix);
+extern struct dentry * d_lookup(struct dentry * dir, struct qstr * name);
X
X /* write full pathname into buffer and return length */
-extern int d_path(struct dentry * entry, struct inode * chroot, char * buf);
+extern int d_path(struct dentry * entry, struct dentry * chroot, char * buf);
X
X extern struct dentry * d_basket(struct dentry * dir_entry);
X
X extern int d_isbasket(struct dentry * entry);
+
+/*
+ * Whee..
+ */
+static inline void dput(struct dentry *dentry)
+{
+ if (dentry)
+ dentry->d_count--;
+}
+
+static inline struct dentry * dget(struct dentry *dentry)
+{
+ if (dentry)
+ dentry->d_count++;
+ return dentry;
+}
+
X #endif
diff -u --recursive --new-file v2.1.43/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h
--- v2.1.43/linux/include/linux/ext2_fs.h Mon Jun 16 16:36:00 1997
+++ linux/include/linux/ext2_fs.h Mon Jul 7 11:28:47 1997
@@ -492,17 +492,15 @@
X
X /* namei.c */
X extern void ext2_release (struct inode *, struct file *);
-extern int ext2_lookup (struct inode *,const char *, int, struct inode **);
-extern int ext2_create (struct inode *,const char *, int, int,
- struct inode **);
-extern int ext2_mkdir (struct inode *, const char *, int, int);
-extern int ext2_rmdir (struct inode *, const char *, int);
-extern int ext2_unlink (struct inode *, const char *, int);
-extern int ext2_symlink (struct inode *, const char *, int, const char *);
-extern int ext2_link (struct inode *, struct inode *, const char *, int);
-extern int ext2_mknod (struct inode *, const char *, int, int, int);
-extern int ext2_rename (struct inode *, const char *, int,
- struct inode *, const char *, int);
+extern int ext2_lookup (struct inode *,struct qstr *, struct inode **);
+extern int ext2_create (struct inode *,struct dentry *,int);
+extern int ext2_mkdir (struct inode *,struct dentry *,int);
+extern int ext2_rmdir (struct inode *,struct dentry *);
+extern int ext2_unlink (struct inode *,struct dentry *);
+extern int ext2_symlink (struct inode *,struct dentry *,const char *);
+extern int ext2_link (struct inode *, struct inode *, struct dentry *);
+extern int ext2_mknod (struct inode *, struct dentry *, int, int);
+extern int ext2_rename (struct inode *, struct dentry *,struct inode *, struct dentry *);
X
X /* super.c */
X extern void ext2_error (struct super_block *, const char *, const char *, ...)
diff -u --recursive --new-file v2.1.43/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.1.43/linux/include/linux/fs.h Mon Jun 16 16:36:00 1997
+++ linux/include/linux/fs.h Mon Jul 7 16:02:01 1997
@@ -15,13 +15,17 @@
X #include <linux/net.h>
X #include <linux/kdev_t.h>
X #include <linux/ioctl.h>
+
X #include <asm/atomic.h>
+#include <asm/bitops.h>
X
X /* Prefixes for routines (having no effect), but indicate what
X * the routine may do. This can greatly ease reasoning about routines...
X */
X #define blocking /*routine may schedule()*/
X
+#include <linux/dalloc.h>
+
X /*
X * It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix
X * that later. Anyway, now the file code is no longer dependent
@@ -104,13 +108,6 @@
X #define MS_MGC_MSK 0xffff0000 /* magic flag number mask */
X
X /*
- * Public flags for namei()
- */
-#define NAM_PLAIN 0 /* Retrieve last component of pathname as is. */
-#define NAM_FOLLOW_LINK 2 /* If last component of path is a symlink, follow it */
-#define NAM_FOLLOW_TRAILSLASH 4 /* Follow last symlink only if trailed by slash. */
-
-/*
X * Note that read-only etc flags are inode-specific: setting some file-system
X * flags just means all the inodes inherit those flags by default. It might be
X * possible to override it selectively if you really wanted to with some
@@ -183,18 +180,16 @@
X */
X struct buffer_head {
X /* First cache line: */
+ struct buffer_head * b_next; /* Hash queue list */
X unsigned long b_blocknr; /* block number */
+ unsigned long b_size; /* block size */
X kdev_t b_dev; /* device (B_FREE = free) */
X kdev_t b_rdev; /* Real device */
X unsigned long b_rsector; /* Real buffer location on disk */
- struct buffer_head * b_next; /* Hash queue list */
X struct buffer_head * b_this_page; /* circular list of buffers in one page */
-
- /* Second cache line: */
X unsigned long b_state; /* buffer state bitmap (see above) */
X struct buffer_head * b_next_free;
X unsigned int b_count; /* users using this block */
- unsigned long b_size; /* block size */
X
X /* Non-performance-critical data follows. */
X char * b_data; /* pointer to data block (1024 bytes) */
@@ -342,12 +337,9 @@
X struct inode *i_basket_prev;
X struct dentry *i_dentry;
X
- short i_ddir_count;
- short i_dent_count;
X unsigned short i_status;
X unsigned short i_reuse_count;
X
- struct inode *i_mount;
X unsigned int i_flags;
X unsigned char i_lock;
X unsigned char i_dirt;
@@ -503,8 +495,7 @@
X unsigned long s_flags;
X unsigned long s_magic;
X unsigned long s_time;
- struct inode *s_covered;
- struct inode *s_mounted;
+ struct dentry *s_root;
X struct wait_queue *s_wait;
X
X struct inode *s_ibasket;
@@ -553,16 +544,17 @@
X
X struct inode_operations {
X 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);
- int (*unlink) (struct inode *,const char *,int);
- int (*symlink) (struct inode *,const char *,int,const char *);
- int (*mkdir) (struct inode *,const char *,int,int);
- int (*rmdir) (struct inode *,const char *,int);
- int (*mknod) (struct inode *,const char *,int,int,int);
- int (*rename) (struct inode *,const char *,int,struct inode *,const char *,int);
+ int (*create) (struct inode *,struct dentry *,int);
+ int (*lookup) (struct inode *,struct qstr *name,struct inode **);
+ int (*link) (struct inode *,struct inode *,struct dentry *);
+ int (*unlink) (struct inode *,struct dentry *);
+ int (*symlink) (struct inode *,struct dentry *,const char *);
+ int (*mkdir) (struct inode *,struct dentry *,int);
+ int (*rmdir) (struct inode *,struct dentry *);
+ int (*mknod) (struct inode *,struct dentry *,int,int);
+ int (*rename) (struct inode *,struct dentry *,struct inode *,struct dentry *);
X int (*readlink) (struct inode *,char *,int);
+ struct dentry * (*follow_link) (struct inode *, struct dentry *);
X int (*readpage) (struct inode *, struct page *);
X int (*writepage) (struct inode *, struct page *);
X int (*bmap) (struct inode *,int);
@@ -640,7 +632,7 @@
X extern struct file_system_type *get_fs_type(const char *name);
X
X extern int fs_may_mount(kdev_t dev);
-extern int fs_may_umount(kdev_t dev, struct inode * mount_root);
+extern int fs_may_umount(kdev_t dev, struct dentry * root);
X extern int fs_may_remount_ro(kdev_t dev);
X
X extern struct file *inuse_filps;
@@ -689,15 +681,32 @@
X extern void sync_supers(kdev_t dev);
X extern int bmap(struct inode * inode,int block);
X extern int notify_change(struct inode *, struct iattr *);
-extern int namei(int retr_mode, const char *pathname, struct inode **res_inode);
X extern int permission(struct inode * inode,int mask);
X extern int get_write_access(struct inode *inode);
X extern void put_write_access(struct inode *inode);
X extern int open_namei(const char * pathname, int flag, int mode,
- struct inode ** res_inode, struct inode * base);
+ struct inode ** res_inode, struct dentry * base);
X extern int do_mknod(const char * filename, int mode, dev_t dev);
X extern int do_pipe(int *);
X
+/*
+ * Kernel pointers have redundant information, so we can use a
+ * scheme where we can return either an error code or a dentry
+ * pointer with the same return value.
+ *
+ * This should be a per-architecture thing, to allow different
+ * error and pointer decisions.
+ */
+#define ERR_PTR(err) ((void *)((long)(err)))
+#define PTR_ERR(ptr) ((long)(ptr))
+#define IS_ERR(ptr) ((unsigned long)(ptr) > (unsigned long)(-1000))
+
+extern struct dentry * lookup_dentry(const char *, struct dentry *, int);
+extern int __namei(const char *, struct inode **, int);
+
+#define namei(pathname, inode_p) __namei(pathname, inode_p, 1)
+#define lnamei(pathname, inode_p) __namei(pathname, inode_p, 0)
+
X #include <asm/semaphore.h>
X
X /* Intended for short locks of the global data structures in inode.c.
@@ -728,51 +737,24 @@
X extern void _get_inode(struct inode * inode);
X extern blocking void __iput(struct inode * inode);
X
-/* This must not be called if the inode is not in use (i.e. given
- * back with iput(). The atomic inc assumes that the inode is
- * already in use, and just has to be incremented higher.
- * Please do not directly manipulate i_count any more.
- * Use iget, iinc and iput.
- * You may test i_count for zero if you are aware that it
- * might change under you.
- */
-extern inline void iinc(struct inode * inode)
-{
- atomic_inc(&inode->i_count);
-}
-
-/* The same, but the inode may not be in use. This must be called
- * with vfslock() held, and be asure that the inode argument is
- * valid (i.e. not out of cache). So the vfs_lock() must span the
- * retrieval method of the inode.
- */
-extern inline void iinc_zero(struct inode * inode)
-{
- if(!atomic_read(&inode->i_count)) {
- atomic_inc(&inode->i_count);
- _get_inode(inode);
- } else
- atomic_inc(&inode->i_count);
-}
-
X extern blocking void _iput(struct inode * inode);
X extern inline blocking void iput(struct inode * inode)
X {


- if(inode) {
+ if (inode) {

X extern void wake_up_interruptible(struct wait_queue **q);
X
- if(inode->i_pipe)
+ if (inode->i_pipe)
X wake_up_interruptible(&inode->u.pipe_i.wait);
X
X /* It does not matter if somebody re-increments it in between,
X * only the _last_ user needs to call _iput().
X */
- if(atomic_dec_and_test(&inode->i_count) && inode->i_ddir_count <= 0)
+ if (atomic_dec_and_test(&inode->i_count))
X _iput(inode);
X }
X }
X
-extern blocking struct inode * __iget(struct super_block * sb, unsigned long nr, int crsmnt);
+extern blocking struct inode * iget(struct super_block * sb, unsigned long nr);
X extern blocking void _clear_inode(struct inode * inode, int external, int verbose);
X extern blocking inline void clear_inode(struct inode * inode)
X {
@@ -795,16 +777,6 @@
X */
X blocking struct inode * get_empty_inode_hashed(dev_t i_dev, unsigned long i_ino);
X
-extern inline blocking int free_ibasket(struct super_block * sb)
-{
- extern blocking int _free_ibasket(struct super_block * sb);
- int res;
- vfs_lock();
- res = _free_ibasket(sb);
- vfs_unlock();


- return res;
-}
-

X extern void insert_inode_hash(struct inode *);
X extern blocking struct inode * get_pipe_inode(void);
X extern int get_unused_fd(void);


@@ -871,12 +843,6 @@
X

X extern int inode_change_ok(struct inode *, struct iattr *);
X extern void inode_setattr(struct inode *, struct iattr *);
-
-extern inline blocking
-struct inode * iget(struct super_block * sb, unsigned long nr)
-{
- return __iget(sb, nr, 1);
-}
X
X /* kludge to get SCSI modules working */
X #include <linux/minix_fs.h>
diff -u --recursive --new-file v2.1.43/linux/include/linux/ghash.h linux/include/linux/ghash.h
--- v2.1.43/linux/include/linux/ghash.h Wed Dec 31 16:00:00 1969
+++ linux/include/linux/ghash.h Mon Jul 7 08:24:28 1997
@@ -0,0 +1,218 @@
+/*
+ * include/linux/ghash.h -- generic hashing with fuzzy retrieval
+ *
+ * (C) 1997 Thomas Schoebel-Theuer
+ *
+ * The algorithms implemented here seem to be a completely new invention,
+ * and I'll publish the fundamentals in a paper.
+ */
+
+#ifndef _GHASH_H
+#define _GHASH_H
+/* HASHSIZE _must_ be a power of two!!! */
+
+
+#define DEF_HASH_FUZZY_STRUCTS(NAME,HASHSIZE,TYPE) \
+\
+struct NAME##_table {\
+ TYPE * hashtable[HASHSIZE];\
+ TYPE * sorted_list;\
+ int nr_entries;\
+};\
+\
+struct NAME##_ptrs {\
+ TYPE * next_hash;\
+ TYPE * prev_hash;\
+ TYPE * next_sorted;\
+ TYPE * prev_sorted;\
+};
+
+#define DEF_HASH_FUZZY(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
+\
+LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
+{\
+ int ix = HASHFN(elem->KEY);\
+ TYPE ** base = &tbl->hashtable[ix];\
+ TYPE * ptr = *base;\
+ TYPE * prev = NULL;\
+\
+ tbl->nr_entries++;\
+ while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
+ base = &ptr->PTRS.next_hash;\
+ prev = ptr;\
+ ptr = *base;\
+ }\
+ elem->PTRS.next_hash = ptr;\
+ elem->PTRS.prev_hash = prev;\
+ if(ptr) {\
+ ptr->PTRS.prev_hash = elem;\
+ }\
+ *base = elem;\
+\
+ ptr = prev;\
+ if(!ptr) {\
+ ptr = tbl->sorted_list;\
+ prev = NULL;\
+ } else {\
+ prev = ptr->PTRS.prev_sorted;\
+ }\
+ while(ptr) {\
+ TYPE * next = ptr->PTRS.next_hash;\
+ if(next && KEYCMP(next->KEY, elem->KEY)) {\
+ prev = ptr;\
+ ptr = next;\
+ } else if(KEYCMP(ptr->KEY, elem->KEY)) {\
+ prev = ptr;\
+ ptr = ptr->PTRS.next_sorted;\
+ } else\
+ break;\
+ }\
+ elem->PTRS.next_sorted = ptr;\
+ elem->PTRS.prev_sorted = prev;\
+ if(ptr) {\
+ ptr->PTRS.prev_sorted = elem;\
+ }\
+ if(prev) {\
+ prev->PTRS.next_sorted = elem;\
+ } else {\
+ tbl->sorted_list = elem;\
+ }\
+}\
+\
+LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
+{\
+ TYPE * next = elem->PTRS.next_hash;\
+ TYPE * prev = elem->PTRS.prev_hash;\
+\
+ tbl->nr_entries--;\
+ if(next)\
+ next->PTRS.prev_hash = prev;\
+ if(prev)\
+ prev->PTRS.next_hash = next;\
+ else {\
+ int ix = HASHFN(elem->KEY);\
+ tbl->hashtable[ix] = next;\
+ }\
+\
+ next = elem->PTRS.next_sorted;\
+ prev = elem->PTRS.prev_sorted;\
+ if(next)\
+ next->PTRS.prev_sorted = prev;\
+ if(prev)\
+ prev->PTRS.next_sorted = next;\
+ else\
+ tbl->sorted_list = next;\
+}\
+\
+LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
+{\
+ int ix = hashfn(pos);\
+ TYPE * ptr = tbl->hashtable[ix];\
+ while(ptr && KEYCMP(ptr->KEY, pos))\
+ ptr = ptr->PTRS.next_hash;\
+ if(ptr && !KEYEQ(ptr->KEY, pos))\
+ ptr = NULL;\
+ return ptr;\
+}\
+\
+LINKAGE TYPE * find_##NAME##_hash_fuzzy(struct NAME##_table * tbl, KEYTYPE pos)\
+{\
+ int ix;\
+ int offset;\
+ TYPE * ptr;\
+ TYPE * next;\
+\
+ ptr = tbl->sorted_list;\
+ if(!ptr || KEYCMP(pos, ptr->KEY))\
+ return NULL;\
+ ix = HASHFN(pos);\
+ offset = HASHSIZE;\
+ do {\
+ offset >>= 1;\
+ next = tbl->hashtable[(ix+offset) & ((HASHSIZE)-1)];\
+ if(next && (KEYCMP(next->KEY, pos) || KEYEQ(next->KEY, pos))\
+ && KEYCMP(ptr->KEY, next->KEY))\
+ ptr = next;\
+ } while(offset);\
+\
+ for(;;) {\
+ next = ptr->PTRS.next_hash;\
+ if(next) {\
+ if(KEYCMP(next->KEY, pos)) {\
+ ptr = next;\
+ continue;\
+ }\
+ }\
+ next = ptr->PTRS.next_sorted;\
+ if(next && KEYCMP(next->KEY, pos)) {\
+ ptr = next;\
+ continue;\
+ }\
+ return ptr;\
+ }\
+ return NULL;\
+}
+
+#define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
+\
+struct NAME##_table {\
+ TYPE * hashtable[HASHSIZE];\
+ int nr_entries;\
+};\
+\
+struct NAME##_ptrs {\
+ TYPE * next_hash;\
+ TYPE * prev_hash;\
+};
+
+#define DEF_HASH(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
+\
+LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
+{\
+ int ix = HASHFN(elem->KEY);\
+ TYPE ** base = &tbl->hashtable[ix];\
+ TYPE * ptr = *base;\
+ TYPE * prev = NULL;\
+\
+ tbl->nr_entries++;\
+ while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
+ base = &ptr->PTRS.next_hash;\
+ prev = ptr;\
+ ptr = *base;\
+ }\
+ elem->PTRS.next_hash = ptr;\
+ elem->PTRS.prev_hash = prev;\
+ if(ptr) {\
+ ptr->PTRS.prev_hash = elem;\
+ }\
+ *base = elem;\
+}\
+\
+LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
+{\
+ TYPE * next = elem->PTRS.next_hash;\
+ TYPE * prev = elem->PTRS.prev_hash;\
+\
+ tbl->nr_entries--;\
+ if(next)\
+ next->PTRS.prev_hash = prev;\
+ if(prev)\
+ prev->PTRS.next_hash = next;\
+ else {\
+ int ix = HASHFN(elem->KEY);\
+ tbl->hashtable[ix] = next;\
+ }\
+}\
+\
+LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
+{\
+ int ix = hashfn(pos);\
+ TYPE * ptr = tbl->hashtable[ix];\
+ while(ptr && KEYCMP(ptr->KEY, pos))\
+ ptr = ptr->PTRS.next_hash;\
+ if(ptr && !KEYEQ(ptr->KEY, pos))\
+ ptr = NULL;\
+ return ptr;\
+}
+
+#endif
diff -u --recursive --new-file v2.1.43/linux/include/linux/if_arp.h linux/include/linux/if_arp.h
--- v2.1.43/linux/include/linux/if_arp.h Thu Jun 12 15:29:21 1997
+++ linux/include/linux/if_arp.h Mon Jul 7 16:02:46 1997
@@ -47,6 +47,8 @@
X #define ARPHRD_ROSE 270
X #define ARPHRD_X25 271 /* CCITT X.25 */
X #define ARPHRD_PPP 512
+#define ARPHRD_HDLC 513 /* (Cisco) HDLC */
+#define ARPHRD_LAPB 516 /* LAPB */
X
X #define ARPHRD_TUNNEL 768 /* IPIP tunnel */
X #define ARPHRD_TUNNEL6 769 /* IPIP6 tunnel */
diff -u --recursive --new-file v2.1.43/linux/include/linux/net.h linux/include/linux/net.h
--- v2.1.43/linux/include/linux/net.h Thu Jun 12 15:28:32 1997
+++ linux/include/linux/net.h Thu Jun 26 12:33:40 1997
@@ -136,5 +136,8 @@
X extern int sock_recvmsg(struct socket *, struct msghdr *m, int len, int flags);
X extern int sock_readv_writev(int type, struct inode * inode, struct file * file,
X const struct iovec * iov, long count, long size);
+
+int net_ratelimit(void);
+
X #endif /* __KERNEL__ */
X #endif /* _LINUX_NET_H */
diff -u --recursive --new-file v2.1.43/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.1.43/linux/include/linux/pci.h Mon Jun 16 16:36:00 1997
+++ linux/include/linux/pci.h Thu Jun 26 12:33:40 1997
@@ -497,7 +497,7 @@
X #define PCI_DEVICE_ID_VIA_82C586_1 0x0571
X #define PCI_DEVICE_ID_VIA_82C576 0x0576
X #define PCI_DEVICE_ID_VIA_82C585 0x0585
-#define PCI_DEVICE_ID_VIA_82C586_0 0x0586
+#define PCI_DEVICE_ID_VIA_82C586 0x0586
X #define PCI_DEVICE_ID_VIA_82C416 0x1571
X
X #define PCI_VENDOR_ID_VORTEX 0x1119
diff -u --recursive --new-file v2.1.43/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- v2.1.43/linux/include/linux/proc_fs.h Mon Jun 16 16:36:00 1997
+++ linux/include/linux/proc_fs.h Mon Jul 7 16:02:05 1997
@@ -312,7 +312,8 @@
X extern void proc_statfs(struct super_block *, struct statfs *, int);
X extern void proc_read_inode(struct inode *);
X extern void proc_write_inode(struct inode *);
-extern int proc_match(int, const char *, struct proc_dir_entry *);
+
+extern int proc_match(int, const char *,struct proc_dir_entry *);
X
X /*
X * These are generic /proc routines that use the internal
@@ -322,7 +323,7 @@
X * of the /proc/<pid> subdirectories.
X */
X extern int proc_readdir(struct inode *, struct file *, void *, filldir_t);
-extern int proc_lookup(struct inode *, const char *, int, struct inode **);
+extern int proc_lookup(struct inode *, struct qstr *, struct inode **);
X
X struct openpromfs_dev {
X struct openpromfs_dev *next;
@@ -334,7 +335,7 @@
X };
X extern struct inode_operations *
X proc_openprom_register(int (*readdir)(struct inode *, struct file *, void *, filldir_t),
- int (*lookup)(struct inode *, const char *, int, struct inode **),
+ int (*lookup)(struct inode *, struct qstr *, struct inode **),
X void (*use)(struct inode *, int),
X struct openpromfs_dev ***);
X extern void proc_openprom_deregister(void);
@@ -362,9 +363,6 @@
X #endif
X extern struct inode_operations proc_omirr_inode_operations;
X
-/* Not sure whether this belongs here */
-int proc_arbitrary_lookup(struct inode * dir, const char * name,
- int len, struct inode ** result);


X #endif
X
X /*

diff -u --recursive --new-file v2.1.43/linux/include/linux/random.h linux/include/linux/random.h
--- v2.1.43/linux/include/linux/random.h Thu Jun 6 03:42:15 1996
+++ linux/include/linux/random.h Thu Jun 26 12:33:40 1997
@@ -55,6 +55,8 @@
X
X extern __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
X __u16 sport, __u16 dport);
+extern __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr,
+ __u16 sport, __u16 dport, __u32 sseq, __u32 count);
X
X #ifndef MODULE
X extern struct file_operations random_fops, urandom_fops;
diff -u --recursive --new-file v2.1.43/linux/include/linux/rose.h linux/include/linux/rose.h
--- v2.1.43/linux/include/linux/rose.h Thu May 29 21:53:11 1997
+++ linux/include/linux/rose.h Mon Jul 7 08:19:59 1997
@@ -8,8 +8,9 @@
X #define ROSE_KERNEL_H
X
X #define PF_ROSE AF_ROSE
-#define ROSE_MTU 128
+#define ROSE_MTU 251
X
+#define ROSE_DEFER 1
X #define ROSE_T1 2
X #define ROSE_T2 3
X #define ROSE_T3 4
@@ -17,7 +18,22 @@
X #define ROSE_QBITINCL 6
X #define ROSE_HOLDBACK 7
X
+#define SIOCRSGCAUSE (SIOCPROTOPRIVATE+0)
+#define SIOCRSSCAUSE (SIOCPROTOPRIVATE+1)
X #define SIOCRSL2CALL (SIOCPROTOPRIVATE+2)
+#define SIOCRSACCEPT (SIOCPROTOPRIVATE+3)
+#define SIOCRSCLRRT (SIOCPROTOPRIVATE+4)
+
+#define ROSE_DTE_ORIGINATED 0x00
+#define ROSE_NUMBER_BUSY 0x01
+#define ROSE_INVALID_FACILITY 0x03
+#define ROSE_NETWORK_CONGESTION 0x05
+#define ROSE_OUT_OF_ORDER 0x09
+#define ROSE_ACCESS_BARRED 0x0B
+#define ROSE_NOT_OBTAINABLE 0x0D
+#define ROSE_REMOTE_PROCEDURE 0x11
+#define ROSE_LOCAL_PROCEDURE 0x13
+#define ROSE_SHIP_ABSENT 0x39
X
X typedef struct {
X char rose_addr[5];
@@ -38,6 +54,11 @@
X char device[16];
X unsigned char ndigis;
X ax25_address digipeaters[AX25_MAX_DIGIS];
+};
+
+struct rose_cause_struct {
+ unsigned char cause;
+ unsigned char diagnostic;
X };
X
X #endif
diff -u --recursive --new-file v2.1.43/linux/include/linux/sched.h linux/include/linux/sched.h
--- v2.1.43/linux/include/linux/sched.h Mon Jun 16 16:36:00 1997
+++ linux/include/linux/sched.h Mon Jul 7 16:02:03 1997
@@ -130,7 +130,7 @@
X struct fs_struct {
X int count;
X int umask;
- struct inode * root, * pwd;
+ struct dentry * root, * pwd;
X };
X
X #define INIT_FS { \
@@ -519,12 +519,10 @@
X {
X struct wait_queue * next = wait->next;
X struct wait_queue * head = next;
+ struct wait_queue * tmp;
X
- for (;;) {
- struct wait_queue * nextlist = head->next;
- if (nextlist == wait)
- break;
- head = nextlist;
+ while ((tmp = head->next) != wait) {
+ head = tmp;
X }
X head->next = next;
X }
diff -u --recursive --new-file v2.1.43/linux/include/linux/selection.h linux/include/linux/selection.h
--- v2.1.43/linux/include/linux/selection.h Mon Jun 16 16:36:00 1997
+++ linux/include/linux/selection.h Mon Jul 7 16:02:27 1997
@@ -23,11 +23,11 @@
X #define get_video_num_columns(dummy) video_num_columns
X #define get_video_num_lines(dummy) video_num_lines
X #define get_video_size_row(dummy) video_size_row
-#endif
-
X extern unsigned long video_num_columns;
X extern unsigned long video_num_lines;
X extern unsigned long video_size_row;
+#endif
+
X extern unsigned char video_type;
X extern unsigned long video_mem_base;
X extern unsigned long video_mem_term;
@@ -72,6 +72,8 @@
X
X
X /* how to access screen memory */
+
+#include <linux/config.h>
X
X #if defined(CONFIG_TGA_CONSOLE)
X
diff -u --recursive --new-file v2.1.43/linux/include/linux/simp.h linux/include/linux/simp.h
--- v2.1.43/linux/include/linux/simp.h Wed Dec 31 16:00:00 1969
+++ linux/include/linux/simp.h Mon Jul 7 08:26:24 1997
@@ -0,0 +1,39 @@
+/*
+ * include/linux/simp.h -- simple allocator for cached objects
+ *
+ * This is meant as a faster and simpler (not full-featured) replacement
+ * for SLAB, thus the name "simp" :-)
+ *
+ * (C) 1997 Thomas Schoebel-Theuer
+ */
+
+#ifndef SIMP_H
+#define SIMP_H
+
+/* used for constructors / destructors */
+typedef void (*structor)(void *);
+
+/* create an object cache */
+/* positive clearable_offset means the next two pointers at that offset
+ * can be internally used for freelist pointers when the object is
+ * deallocated / not in use;
+ * if there is no space inside the element that can be reused for
+ * this purpose, supply -1. Using positive offsets is essential for
+ * saving space with very small-sized objects.
+ *
+ * Note for big-sized objects in the range of whole pages, use
+ * the fast Linux page allocator instead, directly.
+ */
+extern struct simp * simp_create(char * name, long size, long clearable_offset,
+ structor first_ctor,
+ structor again_ctor,
+ structor dtor);
+
+/* alloc / dealloc routines */
+extern void * simp_alloc(struct simp * simp);
+extern void simp_free(void * objp);
+
+/* garbage collection */
+extern long simp_garbage(void);
+
+#endif
diff -u --recursive --new-file v2.1.43/linux/include/linux/slab.h linux/include/linux/slab.h
--- v2.1.43/linux/include/linux/slab.h Thu Jun 12 15:28:33 1997
+++ linux/include/linux/slab.h Mon Jul 7 16:02:03 1997
@@ -32,7 +32,7 @@
X #define SLAB_DEBUG_FREE 0x00000100UL /* Peform (expensive) checks on free */
X #define SLAB_DEBUG_INITIAL 0x00000200UL /* Call constructor (as verifier) */
X #define SLAB_RED_ZONE 0x00000400UL /* Red zone objs in a cache */
-#define SLAB_POISION 0x00000800UL /* Poision objects */
+#define SLAB_POISON 0x00000800UL /* Poison objects */
X #define SLAB_NO_REAP 0x00001000UL /* never reap from the cache */
X #define SLAB_HWCACHE_ALIGN 0x00002000UL /* align objs on a h/w cache lines */
X #if 0
@@ -56,7 +56,7 @@
X extern void kmem_cache_free(kmem_cache_t *, void *);
X
X extern void *kmalloc(size_t, int);
-extern void kfree(void *);
+extern void kfree(const void *);
X extern void kfree_s(void *, size_t);
X
X extern int kmem_cache_reap(int, int, int);
diff -u --recursive --new-file v2.1.43/linux/include/linux/sysctl.h linux/include/linux/sysctl.h
--- v2.1.43/linux/include/linux/sysctl.h Mon Jun 16 16:36:00 1997
+++ linux/include/linux/sysctl.h Thu Jun 26 12:33:40 1997
@@ -173,6 +173,7 @@
X NET_IPV4_IGMP_AGE_THRESHOLD,
X NET_TCP_SYNCOOKIES,
X NET_TCP_ALWAYS_SYNCOOKIE,
+ NET_TCP_STDURG,
X };
X
X
diff -u --recursive --new-file v2.1.43/linux/include/linux/tty.h linux/include/linux/tty.h
--- v2.1.43/linux/include/linux/tty.h Thu Jun 12 15:28:33 1997
+++ linux/include/linux/tty.h Mon Jul 7 16:02:03 1997
@@ -90,13 +90,19 @@
X
X struct tty_flip_buffer {
X struct tq_struct tqueue;
- unsigned char char_buf[2*TTY_FLIPBUF_SIZE];
- char flag_buf[2*TTY_FLIPBUF_SIZE];
+ struct semaphore pty_sem;
X char *char_buf_ptr;
X unsigned char *flag_buf_ptr;
X int count;
X int buf_num;
+ unsigned char char_buf[2*TTY_FLIPBUF_SIZE];
+ char flag_buf[2*TTY_FLIPBUF_SIZE];
+ unsigned char slop[4]; /* N.B. bug overwrites buffer by 1 */
X };
+/*
+ * The pty uses char_buf and flag_buf as a contiguous buffer
+ */
+#define PTY_BUF_SIZE 4*TTY_FLIPBUF_SIZE
X
X /*
X * When a break, frame error, or parity error happens, these codes are
@@ -198,7 +204,7 @@
X * most often used by a windowing system, which will set the correct
X * size each time the window is created or resized anyway.
X * IMPORTANT: since this structure is dynamically allocated, it must
- * be no larger than 4096 bytes. Changing TTY_BUF_SIZE will change
+ * be no larger than 4096 bytes. Changing TTY_FLIPBUF_SIZE will change
X * the size of this structure, and it needs to be done with care.
X * - TYT, 9/14/92
X */
diff -u --recursive --new-file v2.1.43/linux/include/linux/x25.h linux/include/linux/x25.h
--- v2.1.43/linux/include/linux/x25.h Sun Jan 19 05:47:26 1997
+++ linux/include/linux/x25.h Mon Jul 7 08:19:59 1997
@@ -13,6 +13,7 @@
X #define SIOCX25SFACILITIES (SIOCPROTOPRIVATE + 3)
X #define SIOCX25GCALLUSERDATA (SIOCPROTOPRIVATE + 4)
X #define SIOCX25SCALLUSERDATA (SIOCPROTOPRIVATE + 5)
+#define SIOCX25GCAUSEDIAG (SIOCPROTOPRIVATE + 6)
X
X /*
X * Values for {get,set}sockopt.
@@ -33,42 +34,11 @@
X #define X25_PS4096 12
X
X /*
- * X.25 Reset error and diagnostic codes.
- */
-#define X25_ERR_RESET 100 /* Call Reset */
-#define X25_ERR_ROUT 101 /* Out of Order */
-#define X25_ERR_RRPE 102 /* Remote Procedure Error */
-#define X25_ERR_RLPE 103 /* Local Procedure Error */
-#define X25_ERR_RNCG 104 /* Network Congestion */
-#define X25_ERR_RRDO 105 /* Remote DTE Operational */
-#define X25_ERR_RNOP 106 /* Network Operational */
-#define X25_ERR_RINV 107 /* Invalid Call */
-#define X25_ERR_RNOO 108 /* Network Out of Order */
-
-/*
- * X.25 Clear error and diagnostic codes.
- */
-#define X25_ERR_CLEAR 110 /* Call Cleared */
-#define X25_ERR_CBUSY 111 /* Number Busy */
-#define X25_ERR_COUT 112 /* Out of Order */
-#define X25_ERR_CRPE 113 /* Remote Procedure Error */
-#define X25_ERR_CRRC 114 /* Collect Call Refused */
-#define X25_ERR_CINV 115 /* Invalid Call */
-#define X25_ERR_CNFS 116 /* Invalid Fast Select */
-#define X25_ERR_CSA 117 /* Ship Absent */
-#define X25_ERR_CIFR 118 /* Invalid Facility Request */
-#define X25_ERR_CAB 119 /* Access Barred */
-#define X25_ERR_CLPE 120 /* Local Procedure Error */
-#define X25_ERR_CNCG 121 /* Network Congestion */
-#define X25_ERR_CNOB 122 /* Not Obtainable */
-#define X25_ERR_CROO 123 /* RPOA Out of Order */
-
-/*
X * An X.121 address, it is held as ASCII text, null terminated, up to 15
X * digits and a null terminator.
X */
X typedef struct {
- char x25_addr[16];
+ char x25_addr[16];
X } x25_address;
X
X /*
@@ -112,6 +82,14 @@
X struct x25_calluserdata {
X unsigned int cudlength;
X unsigned char cuddata[128];
+};
+
+/*
+ * Call clearing Cause and Diagnostic structure.
+ */
+struct x25_causediag {
+ unsigned char cause;
+ unsigned char diagnostic;
X };
X
X #endif
diff -u --recursive --new-file v2.1.43/linux/include/net/ax25.h linux/include/net/ax25.h
--- v2.1.43/linux/include/net/ax25.h Thu Jun 12 15:29:21 1997
+++ linux/include/net/ax25.h Mon Jul 7 16:02:45 1997
@@ -9,10 +9,8 @@
X #include <linux/config.h>
X #include <linux/ax25.h>
X
-#define AX25_SLOWHZ 10 /* Run timing at 1/10 second - gives us better resolution for 56kbit links */
-
-#define AX25_T1CLAMPLO (1 * AX25_SLOWHZ) /* If defined, clamp at 1 second **/
-#define AX25_T1CLAMPHI (30 * AX25_SLOWHZ) /* If defined, clamp at 30 seconds **/
+#define AX25_T1CLAMPLO 1
+#define AX25_T1CLAMPHI (30 * HZ)
X
X #define AX25_BPQ_HEADER_LEN 16
X #define AX25_KISS_HEADER_LEN 1
@@ -125,14 +123,14 @@
X #define AX25_DEF_CONMODE 2 /* Connected mode allowed */
X #define AX25_DEF_WINDOW 2 /* Window=2 */
X #define AX25_DEF_EWINDOW 32 /* Module-128 Window=32 */
-#define AX25_DEF_T1 (10 * AX25_SLOWHZ) /* T1=10s */
-#define AX25_DEF_T2 (3 * AX25_SLOWHZ) /* T2=3s */
-#define AX25_DEF_T3 (300 * AX25_SLOWHZ) /* T3=300s */
+#define AX25_DEF_T1 (10 * HZ) /* T1=10s */
+#define AX25_DEF_T2 (3 * HZ) /* T2=3s */
+#define AX25_DEF_T3 (300 * HZ) /* T3=300s */
X #define AX25_DEF_N2 10 /* N2=10 */
-#define AX25_DEF_IDLE (0 * 60 * AX25_SLOWHZ) /* Idle=None */
+#define AX25_DEF_IDLE (0 * 60 * HZ) /* Idle=None */
X #define AX25_DEF_PACLEN 256 /* Paclen=256 */
X #define AX25_DEF_PROTOCOL AX25_PROTO_STD_SIMPLEX /* Standard AX.25 */
-#define AX25_DEF_DS_TIMEOUT (3 * 60 * AX25_SLOWHZ) /* DAMA timeout 3 minutes */
+#define AX25_DEF_DS_TIMEOUT (3 * 60 * HZ) /* DAMA timeout 3 minutes */
X
X typedef struct ax25_uid_assoc {
X struct ax25_uid_assoc *next;
@@ -186,8 +184,8 @@
X unsigned short vs, vr, va;
X unsigned char condition, backoff;
X unsigned char n2, n2count;
- unsigned short t1, t2, t3, idle, rtt;
- unsigned short t1timer, t2timer, t3timer, idletimer;
+ struct timer_list t1timer, t2timer, t3timer, idletimer;
+ unsigned long t1, t2, t3, idle, rtt;
X unsigned short paclen, fragno, fraglen;
X struct sk_buff_head write_queue;
X struct sk_buff_head reseq_queue;
@@ -251,20 +249,22 @@
X extern void ax25_ds_del_timer(ax25_dev *);
X extern void ax25_ds_timer(ax25_cb *);
X extern void ax25_ds_t1_timeout(ax25_cb *);
+extern void ax25_ds_heartbeat_expiry(ax25_cb *);
+extern void ax25_ds_t3timer_expiry(ax25_cb *);
+extern void ax25_ds_idletimer_expiry(ax25_cb *);
X
X #include <net/ax25call.h>
X
X /* ax25_iface.c */
X extern int ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, ax25_cb *));
X extern void ax25_protocol_release(unsigned int);
-extern int ax25_linkfail_register(void (*)(ax25_address *, struct device *));
-extern void ax25_linkfail_release(void (*)(ax25_address *, struct device *));
+extern int ax25_linkfail_register(void (*)(ax25_cb *, int));
+extern void ax25_linkfail_release(void (*)(ax25_cb *, int));
X extern int ax25_listen_register(ax25_address *, struct device *);
X extern void ax25_listen_release(ax25_address *, struct device *);
X extern int (*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *);
X extern int ax25_listen_mine(ax25_address *, struct device *);
-extern void ax25_link_failed(ax25_address *, struct device *);
-extern int ax25_link_up(ax25_address *, ax25_address *, ax25_digi *, struct device *);
+extern void ax25_link_failed(ax25_cb *, int);
X extern int ax25_protocol_is_registered(unsigned int);
X
X /* ax25_in.c */
@@ -276,7 +276,7 @@
X extern int ax25_rebuild_header(struct sk_buff *);
X
X /* ax25_out.c */
-extern int ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, ax25_digi *, struct device *);
+extern ax25_cb *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, ax25_digi *, struct device *);
X extern void ax25_output(ax25_cb *, int, struct sk_buff *);
X extern void ax25_kick(ax25_cb *);
X extern void ax25_transmit_buffer(ax25_cb *, struct sk_buff *, int);
@@ -288,9 +288,8 @@
X extern int ax25_rt_ioctl(unsigned int, void *);
X extern int ax25_rt_get_info(char *, char **, off_t, int, int);
X extern int ax25_rt_autobind(ax25_cb *, ax25_address *);
-extern void ax25_rt_build_path(ax25_cb *, ax25_address *, struct device *);
-extern struct sk_buff *ax25_dg_build_path(struct sk_buff *, ax25_address *, struct device *);
-extern char ax25_ip_mode_get(ax25_address *, struct device *);
+extern ax25_route *ax25_rt_find_route(ax25_address *, struct device *);
+extern struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *, ax25_address *, ax25_digi *);
X extern void ax25_rt_free(void);
X
X /* ax25_std_in.c */
@@ -304,7 +303,11 @@
X extern void ax25_std_timeout_response(ax25_cb *);
X
X /* ax25_std_timer.c */
-extern void ax25_std_timer(ax25_cb *);
+extern void ax25_std_heartbeat_expiry(ax25_cb *);
+extern void ax25_std_t1timer_expiry(ax25_cb *);
+extern void ax25_std_t2timer_expiry(ax25_cb *);
+extern void ax25_std_t3timer_expiry(ax25_cb *);
+extern void ax25_std_idletimer_expiry(ax25_cb *);
X
X /* ax25_subr.c */
X extern void ax25_clear_queues(ax25_cb *);
@@ -314,11 +317,23 @@
X extern int ax25_decode(ax25_cb *, struct sk_buff *, int *, int *, int *);
X extern void ax25_send_control(ax25_cb *, int, int, int);
X extern void ax25_return_dm(struct device *, ax25_address *, ax25_address *, ax25_digi *);
-extern unsigned short ax25_calculate_t1(ax25_cb *);
+extern void ax25_calculate_t1(ax25_cb *);
X extern void ax25_calculate_rtt(ax25_cb *);
+extern void ax25_disconnect(ax25_cb *, int);
X
X /* ax25_timer.c */
-extern void ax25_set_timer(ax25_cb *);
+extern void ax25_start_heartbeat(ax25_cb *);
+extern void ax25_start_t1timer(ax25_cb *);
+extern void ax25_start_t2timer(ax25_cb *);
+extern void ax25_start_t3timer(ax25_cb *);
+extern void ax25_start_idletimer(ax25_cb *);
+extern void ax25_stop_heartbeat(ax25_cb *);
+extern void ax25_stop_t1timer(ax25_cb *);
+extern void ax25_stop_t2timer(ax25_cb *);
+extern void ax25_stop_t3timer(ax25_cb *);
+extern void ax25_stop_idletimer(ax25_cb *);
+extern int ax25_t1timer_running(ax25_cb *);
+extern unsigned long ax25_display_timer(struct timer_list *);
X
X /* ax25_uid.c */
X extern int ax25_uid_policy;
diff -u --recursive --new-file v2.1.43/linux/include/net/lapb.h linux/include/net/lapb.h
--- v2.1.43/linux/include/net/lapb.h Thu Feb 27 10:57:31 1997
+++ linux/include/net/lapb.h Mon Jul 7 08:19:59 1997
@@ -2,8 +2,6 @@
X #define _LAPB_H
X #include <linux/lapb.h>
X
-#define LAPB_SLOWHZ 10 /* Run timing at 1/10 second */
-
X #define LAPB_HEADER_LEN 20 /* LAPB over Ethernet + a bit more */
X
X #define LAPB_ACK_PENDING_CONDITION 0x01
@@ -58,10 +56,10 @@
X };
X
X #define LAPB_DEFAULT_MODE (LAPB_STANDARD | LAPB_SLP | LAPB_DTE)
-#define LAPB_DEFAULT_WINDOW 7 /* Window=7 */
-#define LAPB_DEFAULT_T1 (5 * LAPB_SLOWHZ) /* T1=5s */
-#define LAPB_DEFAULT_T2 (1 * LAPB_SLOWHZ) /* T2=1s */
-#define LAPB_DEFAULT_N2 20 /* N2=20 */
+#define LAPB_DEFAULT_WINDOW 7 /* Window=7 */
+#define LAPB_DEFAULT_T1 (5 * HZ) /* T1=5s */
+#define LAPB_DEFAULT_T2 (1 * HZ) /* T2=1s */
+#define LAPB_DEFAULT_N2 20 /* N2=20 */
X
X #define LAPB_SMODULUS 8
X #define LAPB_EMODULUS 128
@@ -91,14 +89,12 @@
X unsigned char condition;
X unsigned short n2, n2count;
X unsigned short t1, t2;
- unsigned short t1timer, t2timer;
+ struct timer_list t1timer, t2timer;
X
X /* Internal control information */
- struct sk_buff_head input_queue;
X struct sk_buff_head write_queue;
X struct sk_buff_head ack_queue;
X unsigned char window;
- struct timer_list timer;
X struct lapb_register_struct callbacks;
X
X /* FRMR control information */
@@ -136,7 +132,11 @@
X extern void lapb_transmit_frmr(lapb_cb *);
X
X /* lapb_timer.c */
-extern void lapb_set_timer(lapb_cb *);
+extern void lapb_start_t1timer(lapb_cb *);
+extern void lapb_start_t2timer(lapb_cb *);
+extern void lapb_stop_t1timer(lapb_cb *);
+extern void lapb_stop_t2timer(lapb_cb *);
+extern int lapb_t1timer_running(lapb_cb *);
X
X /*
X * Debug levels.
diff -u --recursive --new-file v2.1.43/linux/include/net/netrom.h linux/include/net/netrom.h
--- v2.1.43/linux/include/net/netrom.h Thu May 29 21:53:11 1997
+++ linux/include/net/netrom.h Mon Jul 7 08:19:59 1997
@@ -8,8 +8,6 @@
X #define _NETROM_H
X #include <linux/netrom.h>
X
-#define NR_SLOWHZ 10 /* Run timing at 1/10 second */
-
X #define NR_NETWORK_LEN 15
X #define NR_TRANSPORT_LEN 5
X
@@ -40,17 +38,17 @@
X #define NR_COND_PEER_RX_BUSY 0x04
X #define NR_COND_OWN_RX_BUSY 0x08
X
-#define NR_DEFAULT_T1 (120 * NR_SLOWHZ) /* Outstanding frames - 120 seconds */
-#define NR_DEFAULT_T2 (5 * NR_SLOWHZ) /* Response delay - 5 seconds */
-#define NR_DEFAULT_N2 3 /* Number of Retries - 3 */
-#define NR_DEFAULT_T4 (180 * NR_SLOWHZ) /* Busy Delay - 180 seconds */
-#define NR_DEFAULT_IDLE (20* 60 * NR_SLOWHZ) /* No Activuty Timeout - 900 seconds*/
-#define NR_DEFAULT_WINDOW 4 /* Default Window Size - 4 */
-#define NR_DEFAULT_OBS 6 /* Default Obsolescence Count - 6 */
-#define NR_DEFAULT_QUAL 10 /* Default Neighbour Quality - 10 */
-#define NR_DEFAULT_TTL 16 /* Default Time To Live - 16 */
-#define NR_DEFAULT_ROUTING 1 /* Is routing enabled ? */
-#define NR_DEFAULT_FAILS 2 /* Link fails until route fails */
+#define NR_DEFAULT_T1 (120 * HZ) /* Outstanding frames - 120 seconds */
+#define NR_DEFAULT_T2 (5 * HZ) /* Response delay - 5 seconds */
+#define NR_DEFAULT_N2 3 /* Number of Retries - 3 */
+#define NR_DEFAULT_T4 (180 * HZ) /* Busy Delay - 180 seconds */
+#define NR_DEFAULT_IDLE (0 * 60 * HZ) /* No Activity Timeout - none */
+#define NR_DEFAULT_WINDOW 4 /* Default Window Size - 4 */
+#define NR_DEFAULT_OBS 6 /* Default Obsolescence Count - 6 */
+#define NR_DEFAULT_QUAL 10 /* Default Neighbour Quality - 10 */
+#define NR_DEFAULT_TTL 16 /* Default Time To Live - 16 */
+#define NR_DEFAULT_ROUTING 1 /* Is routing enabled ? */
+#define NR_DEFAULT_FAILS 2 /* Link fails until route fails */
X
X #define NR_MODULUS 256
X #define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable - 127 */
@@ -64,9 +62,12 @@
X unsigned char state, condition, bpqext, window;
X unsigned short vs, vr, va, vl;
X unsigned char n2, n2count;
- unsigned short t1, t2, t4, idle;
- unsigned short t1timer, t2timer, t4timer, idletimer;
+ unsigned long t1, t2, t4, idle;
X unsigned short fraglen;
+ struct timer_list t1timer;
+ struct timer_list t2timer;
+ struct timer_list t4timer;
+ struct timer_list idletimer;
X struct sk_buff_head ack_queue;
X struct sk_buff_head reseq_queue;
X struct sk_buff_head frag_queue;
@@ -77,6 +78,7 @@
X struct nr_neigh *next;
X ax25_address callsign;
X ax25_digi *digipeat;
+ ax25_cb *ax25;
X struct device *dev;
X unsigned char quality;
X unsigned char locked;
@@ -138,7 +140,7 @@
X extern struct device *nr_dev_first(void);
X extern struct device *nr_dev_get(ax25_address *);
X extern int nr_rt_ioctl(unsigned int, void *);
-extern void nr_link_failed(ax25_address *, struct device *);
+extern void nr_link_failed(ax25_cb *, int);
X extern int nr_route_frame(struct sk_buff *, ax25_cb *);
X extern int nr_nodes_get_info(char *, char **, off_t, int, int);
X extern int nr_neigh_get_info(char *, char **, off_t, int, int);
@@ -152,9 +154,20 @@
X extern int nr_in_rx_window(struct sock *, unsigned short);
X extern void nr_write_internal(struct sock *, int);
X extern void nr_transmit_dm(struct sk_buff *);
+extern void nr_disconnect(struct sock *, int);
X
X /* nr_timer.c */
-extern void nr_set_timer(struct sock *);
+extern void nr_start_heartbeat(struct sock *);
+extern void nr_start_t1timer(struct sock *);
+extern void nr_start_t2timer(struct sock *);
+extern void nr_start_t4timer(struct sock *);
+extern void nr_start_idletimer(struct sock *);
+extern void nr_stop_heartbeat(struct sock *);
+extern void nr_stop_t1timer(struct sock *);
+extern void nr_stop_t2timer(struct sock *);
+extern void nr_stop_t4timer(struct sock *);
+extern void nr_stop_idletimer(struct sock *);
+extern int nr_t1timer_running(struct sock *);
X
X /* sysctl_net_netrom.c */
X extern void nr_register_sysctl(void);
diff -u --recursive --new-file v2.1.43/linux/include/net/rose.h linux/include/net/rose.h
--- v2.1.43/linux/include/net/rose.h Thu May 29 21:53:11 1997
+++ linux/include/net/rose.h Mon Jul 7 08:19:59 1997
@@ -8,8 +8,6 @@
X #define _ROSE_H
X #include <linux/rose.h>
X
-#define ROSE_SLOWHZ 10 /* Run timing at 1/10 second */
-
X #define ROSE_ADDR_LEN 5
X
X #define ROSE_MIN_LEN 3
@@ -45,22 +43,23 @@
X ROSE_STATE_1, /* Awaiting Call Accepted */
X ROSE_STATE_2, /* Awaiting Clear Confirmation */
X ROSE_STATE_3, /* Data Transfer */
- ROSE_STATE_4 /* Awaiting Reset Confirmation */
+ ROSE_STATE_4, /* Awaiting Reset Confirmation */
+ ROSE_STATE_5 /* Deferred Call Acceptance */
X };
X
-#define ROSE_DEFAULT_T0 (180 * ROSE_SLOWHZ) /* Default T10 T20 value */
-#define ROSE_DEFAULT_T1 (200 * ROSE_SLOWHZ) /* Default T11 T21 value */
-#define ROSE_DEFAULT_T2 (180 * ROSE_SLOWHZ) /* Default T12 T22 value */
-#define ROSE_DEFAULT_T3 (180 * ROSE_SLOWHZ) /* Default T13 T23 value */
-#define ROSE_DEFAULT_HB (5 * ROSE_SLOWHZ) /* Default Holdback value */
-#define ROSE_DEFAULT_IDLE (20 * 60 * ROSE_SLOWHZ) /* Default No Activity value */
-#define ROSE_DEFAULT_ROUTING 1 /* Default routing flag */
-#define ROSE_DEFAULT_FAIL_TIMEOUT (120 * ROSE_SLOWHZ) /* Time until link considered usable */
-#define ROSE_DEFAULT_MAXVC 50 /* Maximum number of VCs per neighbour */
-#define ROSE_DEFAULT_WINDOW_SIZE 3 /* Default window size */
+#define ROSE_DEFAULT_T0 (180 * HZ) /* Default T10 T20 value */
+#define ROSE_DEFAULT_T1 (200 * HZ) /* Default T11 T21 value */
+#define ROSE_DEFAULT_T2 (180 * HZ) /* Default T12 T22 value */
+#define ROSE_DEFAULT_T3 (180 * HZ) /* Default T13 T23 value */
+#define ROSE_DEFAULT_HB (5 * HZ) /* Default Holdback value */
+#define ROSE_DEFAULT_IDLE (0 * 60 * HZ) /* No Activity Timeout - none */
+#define ROSE_DEFAULT_ROUTING 1 /* Default routing flag */
+#define ROSE_DEFAULT_FAIL_TIMEOUT (120 * HZ) /* Time until link considered usable */
+#define ROSE_DEFAULT_MAXVC 50 /* Maximum number of VCs per neighbour */
+#define ROSE_DEFAULT_WINDOW_SIZE 3 /* Default window size */
X
X #define ROSE_MODULUS 8
-#define ROSE_MAX_PACKET_SIZE 256 /* Maximum packet size */
+#define ROSE_MAX_PACKET_SIZE 251 /* Maximum packet size */
X
X #define ROSE_COND_ACK_PENDING 0x01
X #define ROSE_COND_PEER_RX_BUSY 0x02
@@ -81,14 +80,16 @@
X struct rose_neigh *next;
X ax25_address callsign;
X ax25_digi *digipeat;
+ ax25_cb *ax25;
X struct device *dev;
X unsigned short count;
+ unsigned short use;
X unsigned int number;
X char restarted;
X char dce_mode;
X struct sk_buff_head queue;
- unsigned short t0timer, ftimer;
- struct timer_list timer;
+ struct timer_list t0timer;
+ struct timer_list ftimer;
X };
X
X struct rose_node {
@@ -124,11 +125,13 @@
X struct rose_neigh *neighbour;
X struct device *device;
X unsigned int lci, rand;
- unsigned char state, condition, qbitincl;
+ unsigned char state, condition, qbitincl, defer;
+ unsigned char cause, diagnostic;
X unsigned short vs, vr, va, vl;
- unsigned short timer;
- unsigned short t1, t2, t3, hb, idle;
+ unsigned long t1, t2, t3, hb, idle;
X unsigned short fraglen;
+ struct timer_list timer;
+ struct timer_list idletimer;
X struct sk_buff_head frag_queue;
X struct sock *sk; /* Backlink to socket */
X } rose_cb;
@@ -164,12 +167,17 @@
X extern int rose_process_rx_frame(struct sock *, struct sk_buff *);
X
X /* rose_link.c */
-extern void rose_link_set_timer(struct rose_neigh *);
+extern void rose_start_ftimer(struct rose_neigh *);
+extern void rose_start_t0timer(struct rose_neigh *);
+extern void rose_stop_ftimer(struct rose_neigh *);
+extern void rose_stop_t0timer(struct rose_neigh *);
+extern int rose_ftimer_running(struct rose_neigh *);
+extern int rose_t0timer_running(struct rose_neigh *);
X extern void rose_link_rx_restart(struct sk_buff *, struct rose_neigh *, unsigned short);
X extern void rose_transmit_restart_request(struct rose_neigh *);
X extern void rose_transmit_restart_confirmation(struct rose_neigh *);
X extern void rose_transmit_diagnostic(struct rose_neigh *, unsigned char);
-extern void rose_transmit_clear_request(struct rose_neigh *, unsigned int, unsigned char);
+extern void rose_transmit_clear_request(struct rose_neigh *, unsigned int, unsigned char, unsigned char);
X extern void rose_transmit_link(struct sk_buff *, struct rose_neigh *);
X
X /* rose_out.c */
@@ -185,9 +193,9 @@
X extern struct device *rose_dev_get(rose_address *);
X extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *);
X extern struct device *rose_ax25_dev_get(char *);
-extern struct rose_neigh *rose_get_neigh(rose_address *);
+extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *);
X extern int rose_rt_ioctl(unsigned int, void *);
-extern void rose_link_failed(ax25_address *, struct device *);
+extern void rose_link_failed(ax25_cb *, int);
X extern int rose_route_frame(struct sk_buff *, ax25_cb *);
X extern int rose_nodes_get_info(char *, char **, off_t, int, int);
X extern int rose_neigh_get_info(char *, char **, off_t, int, int);
@@ -201,9 +209,18 @@
X extern int rose_decode(struct sk_buff *, int *, int *, int *, int *, int *);
X extern int rose_parse_facilities(struct sk_buff *, struct rose_facilities *);
X extern int rose_create_facilities(unsigned char *, rose_cb *);
+extern void rose_disconnect(struct sock *, int, int, int);
X
X /* rose_timer.c */
-extern void rose_set_timer(struct sock *);
+extern void rose_start_heartbeat(struct sock *);
+extern void rose_start_t1timer(struct sock *);
+extern void rose_start_t2timer(struct sock *);
+extern void rose_start_t3timer(struct sock *);
+extern void rose_start_hbtimer(struct sock *);
+extern void rose_start_idletimer(struct sock *);
+extern void rose_stop_heartbeat(struct sock *);
+extern void rose_stop_timer(struct sock *);
+extern void rose_stop_idletimer(struct sock *);
X
X /* sysctl_net_rose.c */
X extern void rose_register_sysctl(void);
diff -u --recursive --new-file v2.1.43/linux/include/net/tcp.h linux/include/net/tcp.h
--- v2.1.43/linux/include/net/tcp.h Thu Jun 12 15:31:03 1997
+++ linux/include/net/tcp.h Mon Jul 7 16:04:03 1997
@@ -281,15 +281,17 @@
X
X int (*conn_request) (struct sock *sk,
X struct sk_buff *skb,
- void *opt,
- __u32 isn);
+ void *opt, __u32 isn);
X
X struct sock * (*syn_recv_sock) (struct sock *sk,
X struct sk_buff *skb,
- struct open_request *req);
+ struct open_request *req,
+ struct dst_entry *dst);
X
+#if 0
X __u32 (*init_sequence) (struct sock *sk,
X struct sk_buff *skb);
+#endif
X
X struct sock * (*get_sock) (struct sk_buff *skb,
X struct tcphdr *th);
@@ -385,7 +387,8 @@
X int len, int nonblock,
X int flags, int *addr_len);
X
-extern void tcp_parse_options(struct tcphdr *th, struct tcp_opt *tp);
+extern void tcp_parse_options(struct tcphdr *th, struct tcp_opt *tp,
+ int no_fancy);
X
X /*
X * TCP v4 functions exported for the inet6 API
@@ -407,7 +410,8 @@
X
X extern struct sock * tcp_v4_syn_recv_sock(struct sock *sk,
X struct sk_buff *skb,
- struct open_request *req);
+ struct open_request *req,
+ struct dst_entry *dst);
X
X extern int tcp_v4_do_rcv(struct sock *sk,
X struct sk_buff *skb);
@@ -417,6 +421,12 @@
X int addr_len);
X
X
+/* From syncookies.c */
+extern struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
+ struct ip_options *opt);
+extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb,
+ __u16 *mss);
+
X extern void tcp_read_wakeup(struct sock *);
X extern void tcp_write_xmit(struct sock *);
X extern void tcp_time_wait(struct sock *);
@@ -521,7 +531,6 @@
X {
X return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base);
X }
-
X
X #undef STATE_TRACE
X
diff -u --recursive --new-file v2.1.43/linux/include/net/x25.h linux/include/net/x25.h
--- v2.1.43/linux/include/net/x25.h Thu May 29 21:53:11 1997
+++ linux/include/net/x25.h Mon Jul 7 08:19:59 1997
@@ -8,8 +8,6 @@
X #define _X25_H
X #include <linux/x25.h>
X
-#define X25_SLOWHZ 1 /* Run timing at 1 Hz */
-
X #define X25_ADDR_LEN 16
X
X #define X25_MAX_L2_LEN 18 /* 802.2 LLC */
@@ -67,11 +65,11 @@
X X25_LINK_STATE_3
X };
X
-#define X25_DEFAULT_T20 (180 * X25_SLOWHZ) /* Default T20 value */
-#define X25_DEFAULT_T21 (200 * X25_SLOWHZ) /* Default T21 value */
-#define X25_DEFAULT_T22 (180 * X25_SLOWHZ) /* Default T22 value */
-#define X25_DEFAULT_T23 (180 * X25_SLOWHZ) /* Default T23 value */
-#define X25_DEFAULT_T2 (3 * X25_SLOWHZ) /* Default ack holdback value */
+#define X25_DEFAULT_T20 (180 * HZ) /* Default T20 value */
+#define X25_DEFAULT_T21 (200 * HZ) /* Default T21 value */
+#define X25_DEFAULT_T22 (180 * HZ) /* Default T22 value */
+#define X25_DEFAULT_T23 (180 * HZ) /* Default T23 value */
+#define X25_DEFAULT_T2 (3 * HZ) /* Default ack holdback value */
X
X #define X25_DEFAULT_WINDOW_SIZE 2 /* Default Window Size */
X #define X25_DEFAULT_PACKET_SIZE X25_PS128 /* Default Packet Size */
@@ -113,8 +111,8 @@
X unsigned int state;
X unsigned int extended;
X struct sk_buff_head queue;
- unsigned short t20, t20timer;
- struct timer_list timer;
+ unsigned long t20;
+ struct timer_list t20timer;
X };
X
X typedef struct {
@@ -123,13 +121,14 @@
X unsigned int lci;
X unsigned char state, condition, qbitincl, intflag;
X unsigned short vs, vr, va, vl;
- unsigned short timer;
- unsigned short t2, t21, t22, t23;


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 42'
echo 'File patch-2.1.44 is continued in part 43'
echo 43 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part44

#!/bin/sh
# this is part 44 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 44; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

- * Return the state of an AX.25 link given source, destination, and
- * device.
- */
-int ax25_link_up(ax25_address *src, ax25_address *dest, ax25_digi *digi, struct device *dev)
-{
- return ax25_find_cb(src, dest, digi, dev) != NULL;
+ (linkfail->func)(ax25, reason);
X }
X
X int ax25_protocol_is_registered(unsigned int pid)
diff -u --recursive --new-file v2.1.43/linux/net/ax25/ax25_in.c linux/net/ax25/ax25_in.c
--- v2.1.43/linux/net/ax25/ax25_in.c Thu May 29 21:53:11 1997
+++ linux/net/ax25/ax25_in.c Mon Jul 7 08:19:59 1997
@@ -1,5 +1,5 @@
X /*
- * AX.25 release 036
+ * AX.25 release 037
X *
X * This code REQUIRES 2.1.15 or higher/ NET3.038
X *
@@ -35,6 +35,7 @@
X * AX.25 035 Hans(PE1AYX) Fixed interface to IP layer.
X * AX.25 036 Jonathan(G4KLX) Move DAMA code into own file.
X * Joerg(DL1BKE) Fixed DAMA Slave.
+ * AX.25 037 Jonathan(G4KLX) New timer architecture.
X */
X
X #include <linux/config.h>
@@ -136,7 +137,7 @@
X
X if (skb == NULL) return 0;
X
- ax25->idletimer = ax25->idle;
+ ax25_start_idletimer(ax25);
X
X pid = *skb->data;
X
@@ -193,8 +194,6 @@
X if (ax25->state == AX25_STATE_0)
X return 0;
X
- del_timer(&ax25->timer);
-
X switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
X case AX25_PROTO_STD_SIMPLEX:
X case AX25_PROTO_STD_DUPLEX:
@@ -211,8 +210,6 @@
X #endif
X }
X
- ax25_set_timer(ax25);
-
X return queued;
X }
X
@@ -413,7 +410,6 @@
X }
X
X ax25_fillin_cb(ax25, ax25_dev);
- ax25->idletimer = ax25->idle;
X }
X
X ax25->source_addr = dest;
@@ -453,12 +449,13 @@
X ax25_dama_on(ax25);
X #endif
X
- ax25->t3timer = ax25->t3;
- ax25->state = AX25_STATE_3;
+ ax25->state = AX25_STATE_3;
X
X ax25_insert_socket(ax25);
X
- ax25_set_timer(ax25);
+ ax25_start_heartbeat(ax25);
+ ax25_start_t3timer(ax25);
+ ax25_start_idletimer(ax25);
X
X if (sk != NULL) {
X if (!sk->dead)
diff -u --recursive --new-file v2.1.43/linux/net/ax25/ax25_ip.c linux/net/ax25/ax25_ip.c
--- v2.1.43/linux/net/ax25/ax25_ip.c Thu May 29 21:53:11 1997
+++ linux/net/ax25/ax25_ip.c Mon Jul 7 08:19:59 1997
@@ -1,5 +1,5 @@
X /*
- * AX.25 release 036
+ * AX.25 release 037
X *
X * This code REQUIRES 2.1.15 or higher/ NET3.038
X *
@@ -105,20 +105,25 @@
X int ax25_rebuild_header(struct sk_buff *skb)
X {
X struct sk_buff *ourskb;
- int mode;
X unsigned char *bp = skb->data;
X struct device *dev = skb->dev;
+ ax25_address *src, *dst;
+ ax25_route *route;
X ax25_dev *ax25_dev;
X
+ dst = (ax25_address *)(bp + 1);
+ src = (ax25_address *)(bp + 8);
+
X if (arp_find(bp + 1, skb))
X return 1;
X
X if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
X return 1;
X
+ route = ax25_rt_find_route(dst, dev);
+
X if (bp[16] == AX25_P_IP) {
- mode = ax25_ip_mode_get((ax25_address *)(bp + 1), dev);
- if (mode == 'V' || (mode == ' ' && ax25_dev->values[AX25_VALUES_IPDEFMODE])) {
+ if (route->ip_mode == 'V' || (route->ip_mode == ' ' && ax25_dev->values[AX25_VALUES_IPDEFMODE])) {
X /*
X * We copy the buffer and release the original thereby
X * keeping it straight
@@ -146,7 +151,7 @@
X
X skb_pull(ourskb, AX25_HEADER_LEN - 1); /* Keep PID */
X
- ax25_send_frame(ourskb, ax25_dev->values[AX25_VALUES_PACLEN], (ax25_address *)(bp + 8), (ax25_address *)(bp + 1), NULL, dev);
+ ax25_send_frame(ourskb, ax25_dev->values[AX25_VALUES_PACLEN], src, dst, route->digipeat, dev);
X
X return 1;
X }
@@ -160,15 +165,19 @@
X bp[14] |= AX25_EBIT;
X bp[14] |= AX25_SSSID_SPARE;
X
- if ((ourskb = ax25_dg_build_path(skb, (ax25_address *)(bp + 1), dev)) == NULL) {
- kfree_skb(skb, FREE_WRITE);
- return 1;
+ if (route->digipeat != NULL) {
+ if ((ourskb = ax25_rt_build_path(skb, src, dst, route->digipeat)) == NULL) {
+ kfree_skb(skb, FREE_WRITE);


+ return 1;
+ }
+

+ skb = ourskb;
X }
X
- ourskb->dev = dev;
- ourskb->priority = SOPRI_NORMAL;


+ skb->dev = dev;

+ skb->priority = SOPRI_NORMAL;
X
- ax25_queue_xmit(ourskb);
+ ax25_queue_xmit(skb);
X
X return 1;
X }
diff -u --recursive --new-file v2.1.43/linux/net/ax25/ax25_out.c linux/net/ax25/ax25_out.c
--- v2.1.43/linux/net/ax25/ax25_out.c Thu May 29 21:53:11 1997
+++ linux/net/ax25/ax25_out.c Mon Jul 7 08:19:59 1997
@@ -1,5 +1,5 @@
X /*
- * AX.25 release 036
+ * AX.25 release 037
X *
X * This code REQUIRES 2.1.15 or higher/ NET3.038
X *
@@ -26,6 +26,7 @@
X * AX.25 I-Frames. Added PACLEN parameter.
X * Joerg(DL1BKE) Fixed a problem with buffer allocation
X * for fragments.
+ * AX.25 037 Jonathan(G4KLX) New timer architecture.
X */
X
X #include <linux/config.h>
@@ -52,7 +53,7 @@
X #include <linux/mm.h>
X #include <linux/interrupt.h>
X
-int ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax25_address *dest, ax25_digi *digi, struct device *dev)
+ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax25_address *dest, ax25_digi *digi, struct device *dev)
X {
X ax25_dev *ax25_dev;
X ax25_cb *ax25;
@@ -65,15 +66,14 @@
X */
X if ((ax25 = ax25_find_cb(src, dest, digi, dev)) != NULL) {
X ax25_output(ax25, paclen, skb);
- ax25->idletimer = ax25->idle;
- return 1; /* It already existed */
+ return ax25; /* It already existed */
X }
X
X if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
- return 0;
+ return NULL;
X
X if ((ax25 = ax25_create_cb()) == NULL)
- return 0;
+ return NULL;
X
X ax25_fillin_cb(ax25, ax25_dev);
X
@@ -83,11 +83,9 @@
X if (digi != NULL) {
X if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
X ax25_free_cb(ax25);
- return 0;
+ return NULL;
X }
X *ax25->digipeat = *digi;
- } else {
- ax25_rt_build_path(ax25, dest, dev);
X }
X
X switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
@@ -106,19 +104,15 @@
X #endif
X }
X
- /* idle timeouts only for mode vc connections */
-
- ax25->idletimer = ax25->idle;
-
X ax25_insert_socket(ax25);
X
X ax25->state = AX25_STATE_1;
X
- ax25_set_timer(ax25);
+ ax25_start_heartbeat(ax25);
X
X ax25_output(ax25, paclen, skb);
X
- return 1; /* We had to create it */
+ return ax25; /* We had to create it */
X }
X
X /*
@@ -195,10 +189,8 @@
X }
X
X if (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_STD_SIMPLEX ||
- ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_STD_DUPLEX) {
- if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4)
- ax25_kick(ax25);
- }
+ ax25->ax25_dev->values[AX25_VALUES_PROTOCOL] == AX25_PROTO_STD_DUPLEX)
+ ax25_kick(ax25);
X }
X
X /*
@@ -228,6 +220,8 @@
X frame[1] |= (ax25->vr << 1);
X }
X
+ ax25_start_idletimer(ax25);
+
X ax25_transmit_buffer(ax25, skb, AX25_COMMAND);
X }
X
@@ -237,76 +231,80 @@
X int last = 1;
X unsigned short start, end, next;
X
- del_timer(&ax25->timer);
+ if (ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4)
+ return;
+
+ if (ax25->condition & AX25_COND_PEER_RX_BUSY)
+ return;
+
+ if (skb_peek(&ax25->write_queue) == NULL)
+ return;
X
X start = (skb_peek(&ax25->ack_queue) == NULL) ? ax25->va : ax25->vs;
X end = (ax25->va + ax25->window) % ax25->modulus;
X
- if (!(ax25->condition & AX25_COND_PEER_RX_BUSY) &&
- start != end &&
- skb_peek(&ax25->write_queue) != NULL) {
+ if (start == end)
+ return;
X
- ax25->vs = start;
+ ax25->vs = start;
X
- /*
- * Transmit data until either we're out of data to send or
- * the window is full. Send a poll on the final I frame if
- * the window is filled.
- */
+ /*
+ * Transmit data until either we're out of data to send or
+ * the window is full. Send a poll on the final I frame if
+ * the window is filled.
+ */
X
- /*
- * Dequeue the frame and copy it.
- */
- skb = skb_dequeue(&ax25->write_queue);
+ /*
+ * Dequeue the frame and copy it.
+ */
+ skb = skb_dequeue(&ax25->write_queue);
X
- do {
- if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
- skb_queue_head(&ax25->write_queue, skb);
- break;
- }
+ do {
+ if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
+ skb_queue_head(&ax25->write_queue, skb);
+ break;
+ }
X
- if (skb->sk != NULL)
- skb_set_owner_w(skbn, skb->sk);
+ if (skb->sk != NULL)
+ skb_set_owner_w(skbn, skb->sk);
X
- next = (ax25->vs + 1) % ax25->modulus;
- last = (next == end);
+ next = (ax25->vs + 1) % ax25->modulus;
+ last = (next == end);
X
- /*
- * Transmit the frame copy.
- * bke 960114: do not set the Poll bit on the last frame
- * in DAMA mode.
- */
- switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
- case AX25_PROTO_STD_SIMPLEX:
- case AX25_PROTO_STD_DUPLEX:
- ax25_send_iframe(ax25, skbn, (last) ? AX25_POLLON : AX25_POLLOFF);
- break;
+ /*
+ * Transmit the frame copy.
+ * bke 960114: do not set the Poll bit on the last frame
+ * in DAMA mode.
+ */
+ switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
+ case AX25_PROTO_STD_SIMPLEX:
+ case AX25_PROTO_STD_DUPLEX:
+ ax25_send_iframe(ax25, skbn, (last) ? AX25_POLLON : AX25_POLLOFF);
+ break;
X
X #ifdef CONFIG_AX25_DAMA_SLAVE
- case AX25_PROTO_DAMA_SLAVE:
- ax25_send_iframe(ax25, skbn, AX25_POLLOFF);
- break;
+ case AX25_PROTO_DAMA_SLAVE:
+ ax25_send_iframe(ax25, skbn, AX25_POLLOFF);
+ break;
X #endif
- }
+ }
X
- ax25->vs = next;
+ ax25->vs = next;
X
- /*
- * Requeue the original data frame.
- */
- skb_queue_tail(&ax25->ack_queue, skb);
+ /*
+ * Requeue the original data frame.
+ */
+ skb_queue_tail(&ax25->ack_queue, skb);
X
- } while (!last && (skb = skb_dequeue(&ax25->write_queue)) != NULL);
+ } while (!last && (skb = skb_dequeue(&ax25->write_queue)) != NULL);
X
- ax25->condition &= ~AX25_COND_ACK_PENDING;
+ ax25->condition &= ~AX25_COND_ACK_PENDING;
X
- if (ax25->t1timer == 0) {
- ax25->t3timer = 0;
- ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
- }
+ if (!ax25_t1timer_running(ax25)) {
+ ax25_stop_t3timer(ax25);
+ ax25_calculate_t1(ax25);
+ ax25_start_t1timer(ax25);
X }
-
- ax25_set_timer(ax25);
X }
X
X void ax25_transmit_buffer(ax25_cb *ax25, struct sk_buff *skb, int type)
@@ -316,14 +314,7 @@
X int headroom;
X
X if (ax25->ax25_dev == NULL) {
- if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ENETUNREACH;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- }
+ ax25_disconnect(ax25, ENETUNREACH);
X return;
X }
X
@@ -381,12 +372,13 @@
X if (ax25->vs == nr) {
X ax25_frames_acked(ax25, nr);
X ax25_calculate_rtt(ax25);
- ax25->t1timer = 0;
- ax25->t3timer = ax25->t3;
+ ax25_stop_t1timer(ax25);
+ ax25_start_t3timer(ax25);
X } else {
X if (ax25->va != nr) {
X ax25_frames_acked(ax25, nr);
- ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
+ ax25_calculate_t1(ax25);
+ ax25_start_t1timer(ax25);
X }
X }
X }
diff -u --recursive --new-file v2.1.43/linux/net/ax25/ax25_route.c linux/net/ax25/ax25_route.c
--- v2.1.43/linux/net/ax25/ax25_route.c Thu May 29 21:53:11 1997
+++ linux/net/ax25/ax25_route.c Mon Jul 7 08:19:59 1997
@@ -1,5 +1,5 @@
X /*
- * AX.25 release 036
+ * AX.25 release 037
X *
X * This code REQUIRES 2.1.15 or higher/ NET3.038
X *
@@ -120,13 +120,12 @@
X struct ax25_routes_struct route;
X struct ax25_route_opt_struct rt_option;
X ax25_dev *ax25_dev;
- int i, err;
+ int i;
X
X switch (cmd) {
X case SIOCADDRT:
- if ((err = verify_area(VERIFY_READ, arg, sizeof(route))) != 0)
- return err;
- copy_from_user(&route, arg, sizeof(route));
+ if (copy_from_user(&route, arg, sizeof(route)))
+ return -EFAULT;
X if ((ax25_dev = ax25_addr_ax25dev(&route.port_addr)) == NULL)
X return -EINVAL;
X if (route.digi_count > AX25_MAX_DIGIS)
@@ -175,9 +174,8 @@
X break;
X
X case SIOCDELRT:
- if ((err = verify_area(VERIFY_READ, arg, sizeof(route))) != 0)
- return err;
- copy_from_user(&route, arg, sizeof(route));
+ if (copy_from_user(&route, arg, sizeof(route)))
+ return -EFAULT;
X if ((ax25_dev = ax25_addr_ax25dev(&route.port_addr)) == NULL)
X return -EINVAL;
X ax25_rt = ax25_route_list;
@@ -206,9 +204,8 @@
X break;
X
X case SIOCAX25OPTRT:
- if ((err = verify_area(VERIFY_READ, arg, sizeof(rt_option))) != 0)
- return err;
- copy_from_user(&rt_option, arg, sizeof(rt_option));
+ if (copy_from_user(&rt_option, arg, sizeof(rt_option)))
+ return -EFAULT;
X if ((ax25_dev = ax25_addr_ax25dev(&rt_option.port_addr)) == NULL)
X return -EINVAL;
X for (ax25_rt = ax25_route_list; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
@@ -390,48 +387,32 @@
X * dl1bke 960117: build digipeater path
X * dl1bke 960301: use the default route if it exists
X */
-void ax25_rt_build_path(ax25_cb *ax25, ax25_address *addr, struct device *dev)
+ax25_route *ax25_rt_find_route(ax25_address *addr, struct device *dev)
X {
+ static ax25_route route;
X ax25_route *ax25_rt;
X
- if ((ax25_rt = ax25_find_route(addr, dev)) == NULL)
- return;
-
- if (ax25_rt->digipeat == NULL)
- return;
-
- if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL)
- return;
-
- if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL)
- return;
+ if ((ax25_rt = ax25_find_route(addr, dev)) == NULL) {
+ route.next = NULL;
+ route.callsign = *addr;
+ route.dev = dev;
+ route.digipeat = NULL;
+ route.ip_mode = ' ';
+ return &route;
+ }
X
- *ax25->digipeat = *ax25_rt->digipeat;
- ax25_adjust_path(addr, ax25->digipeat);
+ return ax25_rt;
X }
X
-struct sk_buff *ax25_dg_build_path(struct sk_buff *skb, ax25_address *addr, struct device *dev)
+struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src, ax25_address *dest, ax25_digi *digi)
X {
X struct sk_buff *skbn;
- ax25_route *ax25_rt;
- ax25_digi digipeat;
- ax25_address src, dest;
X unsigned char *bp;
X int len;
X
X skb_pull(skb, 1); /* skip KISS command */
X
- if ((ax25_rt = ax25_find_route(addr, dev)) == NULL)
- return skb;
-
- if (ax25_rt->digipeat == NULL)
- return skb;
-
- digipeat = *ax25_rt->digipeat;
-
- ax25_adjust_path(addr, &digipeat);
-
- len = ax25_rt->digipeat->ndigi * AX25_ADDR_LEN;
+ len = digi->ndigi * AX25_ADDR_LEN;
X
X if (skb_headroom(skb) < len) {
X if ((skbn = skb_realloc_headroom(skb, len)) == NULL) {
@@ -447,28 +428,11 @@
X skb = skbn;
X }
X
- memcpy(&dest, skb->data + 0, AX25_ADDR_LEN);
- memcpy(&src, skb->data + 7, AX25_ADDR_LEN);
-
X bp = skb_push(skb, len);
X
- ax25_addr_build(bp, &src, &dest, ax25_rt->digipeat, AX25_COMMAND, AX25_MODULUS);
+ ax25_addr_build(bp, src, dest, digi, AX25_COMMAND, AX25_MODULUS);
X
X return skb;
-}
-
-/*
- * Return the IP mode of a given callsign/device pair.
- */
-char ax25_ip_mode_get(ax25_address *callsign, struct device *dev)
-{
- ax25_route *ax25_rt;
-
- for (ax25_rt = ax25_route_list; ax25_rt != NULL; ax25_rt = ax25_rt->next)
- if (ax25cmp(&ax25_rt->callsign, callsign) == 0 && ax25_rt->dev == dev)
- return ax25_rt->ip_mode;
-
- return ' ';
X }
X
X #ifdef MODULE
diff -u --recursive --new-file v2.1.43/linux/net/ax25/ax25_std_in.c linux/net/ax25/ax25_std_in.c
--- v2.1.43/linux/net/ax25/ax25_std_in.c Thu May 29 21:53:11 1997
+++ linux/net/ax25/ax25_std_in.c Mon Jul 7 08:19:59 1997
@@ -1,5 +1,5 @@
X /*
- * AX.25 release 036
+ * AX.25 release 037
X *
X * This code REQUIRES 2.1.15 or higher/ NET3.038
X *
@@ -34,6 +34,7 @@
X * Modularisation changes.
X * AX.25 035 Hans(PE1AYX) Fixed interface to IP layer.
X * AX.25 036 Jonathan(G4KLX) Cloned from ax25_in.c.
+ * AX.25 037 Jonathan(G4KLX) New timer architecture.
X */
X
X #include <linux/config.h>
@@ -87,9 +88,9 @@
X case AX25_UA:
X if (pf) {
X ax25_calculate_rtt(ax25);
- ax25->t1timer = 0;
- ax25->t3timer = ax25->t3;
- ax25->idletimer = ax25->idle;
+ ax25_stop_t1timer(ax25);
+ ax25_start_t3timer(ax25);
+ ax25_start_idletimer(ax25);
X ax25->vs = 0;
X ax25->va = 0;
X ax25->vr = 0;
@@ -107,16 +108,7 @@
X case AX25_DM:
X if (pf) {
X if (ax25->modulus == AX25_MODULUS) {
- ax25_clear_queues(ax25);
- ax25->state = AX25_STATE_0;
- if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ECONNREFUSED;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- }
+ ax25_disconnect(ax25, ECONNREFUSED);
X } else {
X ax25->modulus = AX25_MODULUS;
X ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
@@ -146,30 +138,12 @@
X
X case AX25_DISC:
X ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
- ax25->state = AX25_STATE_0;
- if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = 0;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- }
+ ax25_disconnect(ax25, 0);
X break;
X
X case AX25_DM:
X case AX25_UA:
- if (pf) {
- ax25->state = AX25_STATE_0;
- if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = 0;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- }
- }
+ if (pf) ax25_disconnect(ax25, 0);
X break;
X
X case AX25_I:
@@ -206,10 +180,11 @@
X ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
X }
X ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
+ ax25_stop_t1timer(ax25);
+ ax25_stop_t2timer(ax25);
+ ax25_start_t3timer(ax25);
+ ax25_start_idletimer(ax25);
X ax25->condition = 0x00;
- ax25->t1timer = 0;
- ax25->t3timer = ax25->t3;
- ax25->idletimer = ax25->idle;
X ax25->vs = 0;
X ax25->va = 0;
X ax25->vr = 0;
@@ -217,32 +192,12 @@
X break;
X
X case AX25_DISC:
- ax25_clear_queues(ax25);
X ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
- ax25->t3timer = 0;
- ax25->state = AX25_STATE_0;
- if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = 0;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- }
+ ax25_disconnect(ax25, 0);
X break;
X
X case AX25_DM:
- ax25_clear_queues(ax25);
- ax25->t3timer = 0;
- ax25->state = AX25_STATE_0;
- if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ECONNRESET;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- }
+ ax25_disconnect(ax25, ECONNRESET);
X break;
X
X case AX25_RR:
@@ -268,8 +223,8 @@
X if (ax25_validate_nr(ax25, nr)) {
X ax25_frames_acked(ax25, nr);
X ax25_calculate_rtt(ax25);
- ax25->t1timer = 0;
- ax25->t3timer = ax25->t3;
+ ax25_stop_t1timer(ax25);
+ ax25_start_t3timer(ax25);
X ax25_requeue_frames(ax25);
X } else {
X ax25_std_nr_error_recovery(ax25);
@@ -295,18 +250,15 @@
X if (ns == ax25->vr) {
X ax25->vr = (ax25->vr + 1) % ax25->modulus;
X queued = ax25_rx_iframe(ax25, skb);
- if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
+ if (ax25->condition & AX25_COND_OWN_RX_BUSY)
X ax25->vr = ns; /* ax25->vr - 1 */
- if (pf) ax25_std_enquiry_response(ax25);
- break;
- }
X ax25->condition &= ~AX25_COND_REJECT;
X if (pf) {
X ax25_std_enquiry_response(ax25);
X } else {
X if (!(ax25->condition & AX25_COND_ACK_PENDING)) {
- ax25->t2timer = ax25->t2;
X ax25->condition |= AX25_COND_ACK_PENDING;
+ ax25_start_t2timer(ax25);
X }
X }
X } else {
@@ -353,10 +305,11 @@
X ax25->window = ax25->ax25_dev->values[AX25_VALUES_EWINDOW];
X }
X ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
+ ax25_stop_t1timer(ax25);
+ ax25_stop_t2timer(ax25);
+ ax25_start_t3timer(ax25);
+ ax25_start_idletimer(ax25);
X ax25->condition = 0x00;
- ax25->t1timer = 0;
- ax25->t3timer = ax25->t3;
- ax25->idletimer = ax25->idle;
X ax25->vs = 0;
X ax25->va = 0;
X ax25->vr = 0;
@@ -366,32 +319,12 @@
X break;
X
X case AX25_DISC:
- ax25_clear_queues(ax25);
X ax25_send_control(ax25, AX25_UA, pf, AX25_RESPONSE);
- ax25->t3timer = 0;
- ax25->state = AX25_STATE_0;
- if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = 0;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- }
+ ax25_disconnect(ax25, 0);
X break;
X
X case AX25_DM:
- ax25_clear_queues(ax25);
- ax25->t3timer = 0;
- ax25->state = AX25_STATE_0;
- if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ECONNRESET;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- }
+ ax25_disconnect(ax25, ECONNRESET);
X break;
X
X case AX25_RR:
@@ -401,11 +334,11 @@
X else
X ax25->condition |= AX25_COND_PEER_RX_BUSY;
X if (type == AX25_RESPONSE && pf) {
- ax25->t1timer = 0;
+ ax25_stop_t1timer(ax25);
X if (ax25_validate_nr(ax25, nr)) {
X ax25_frames_acked(ax25, nr);
X if (ax25->vs == ax25->va) {
- ax25->t3timer = ax25->t3;
+ ax25_start_t3timer(ax25);
X ax25->n2count = 0;
X ax25->state = AX25_STATE_3;
X } else {
@@ -430,11 +363,11 @@
X case AX25_REJ:
X ax25->condition &= ~AX25_COND_PEER_RX_BUSY;
X if (pf && type == AX25_RESPONSE) {
- ax25->t1timer = 0;
+ ax25_stop_t1timer(ax25);
X if (ax25_validate_nr(ax25, nr)) {
X ax25_frames_acked(ax25, nr);
X if (ax25->vs == ax25->va) {
- ax25->t3timer = ax25->t3;
+ ax25_start_t3timer(ax25);
X ax25->n2count = 0;
X ax25->state = AX25_STATE_3;
X } else {
@@ -471,18 +404,15 @@
X if (ns == ax25->vr) {
X ax25->vr = (ax25->vr + 1) % ax25->modulus;
X queued = ax25_rx_iframe(ax25, skb);
- if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
+ if (ax25->condition & AX25_COND_OWN_RX_BUSY)
X ax25->vr = ns; /* ax25->vr - 1 */
- if (pf) ax25_std_enquiry_response(ax25);
- break;
- }
X ax25->condition &= ~AX25_COND_REJECT;
X if (pf) {
X ax25_std_enquiry_response(ax25);
X } else {
X if (!(ax25->condition & AX25_COND_ACK_PENDING)) {
- ax25->t2timer = ax25->t2;
X ax25->condition |= AX25_COND_ACK_PENDING;
+ ax25_start_t2timer(ax25);
X }
X }
X } else {
@@ -532,6 +462,8 @@
X queued = ax25_std_state4_machine(ax25, skb, frametype, ns, nr, pf, type);
X break;
X }
+
+ ax25_kick(ax25);
X
X return queued;
X }
diff -u --recursive --new-file v2.1.43/linux/net/ax25/ax25_std_subr.c linux/net/ax25/ax25_std_subr.c
--- v2.1.43/linux/net/ax25/ax25_std_subr.c Thu May 29 21:53:11 1997
+++ linux/net/ax25/ax25_std_subr.c Mon Jul 7 08:19:59 1997
@@ -1,5 +1,5 @@
X /*
- * AX.25 release 036
+ * AX.25 release 037
X *
X * This code REQUIRES 2.1.15 or higher/ NET3.038
X *
@@ -17,6 +17,7 @@
X *
X * History
X * AX.25 036 Jonathan(G4KLX) Split from ax25_out.c.
+ * AX.25 037 Jonathan(G4KLX) New timer architecture.
X */
X
X #include <linux/config.h>
@@ -62,9 +63,11 @@
X else
X ax25_send_control(ax25, AX25_SABME, AX25_POLLON, AX25_COMMAND);
X
- ax25->t3timer = 0;
- ax25->t2timer = 0;
- ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
+ ax25_calculate_t1(ax25);
+ ax25_stop_idletimer(ax25);
+ ax25_stop_t3timer(ax25);
+ ax25_stop_t2timer(ax25);
+ ax25_start_t1timer(ax25);
X }
X
X void ax25_std_transmit_enquiry(ax25_cb *ax25)
@@ -76,7 +79,8 @@
X
X ax25->condition &= ~AX25_COND_ACK_PENDING;
X
- ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
+ ax25_calculate_t1(ax25);
+ ax25_start_t1timer(ax25);
X }
X
X void ax25_std_enquiry_response(ax25_cb *ax25)
diff -u --recursive --new-file v2.1.43/linux/net/ax25/ax25_std_timer.c linux/net/ax25/ax25_std_timer.c
--- v2.1.43/linux/net/ax25/ax25_std_timer.c Thu May 29 21:53:11 1997
+++ linux/net/ax25/ax25_std_timer.c Mon Jul 7 08:19:59 1997
@@ -1,5 +1,5 @@
X /*
- * AX.25 release 036
+ * AX.25 release 037
X *
X * This code REQUIRES 2.1.15 or higher/ NET3.038
X *
@@ -19,6 +19,7 @@
X * AX.25 033 Jonathan(G4KLX) Modularisation functions.
X * AX.25 035 Frederic(F1OAT) Support for pseudo-digipeating.
X * AX.25 036 Jonathan(G4KLX) Split from ax25_timer.c.
+ * AX.25 037 Jonathan(G4KLX) New timer architecture.
X */
X
X #include <linux/config.h>
@@ -44,14 +45,14 @@
X #include <linux/mm.h>
X #include <linux/interrupt.h>
X
-void ax25_std_timer(ax25_cb *ax25)
+void ax25_std_heartbeat_expiry(ax25_cb *ax25)
X {
X switch (ax25->state) {
+
X case AX25_STATE_0:
X /* Magic here: If we listen() and a new link dies before it
X is accepted() it isn't 'dead' so doesn't get removed. */
X if (ax25->sk == NULL || ax25->sk->destroy || (ax25->sk->state == TCP_LISTEN && ax25->sk->dead)) {
- del_timer(&ax25->timer);
X ax25_destroy_socket(ax25);
X return;
X }
@@ -71,78 +72,57 @@
X break;
X }
X }
- /*
- * Check for frames to transmit.
- */
- ax25_kick(ax25);
- break;
-
- default:
- break;
X }
X
- if (ax25->t2timer > 0 && --ax25->t2timer == 0) {
- if (ax25->state == AX25_STATE_3 || ax25->state == AX25_STATE_4) {
- if (ax25->condition & AX25_COND_ACK_PENDING) {
- ax25->condition &= ~AX25_COND_ACK_PENDING;
- ax25_std_timeout_response(ax25);
- }
- }
- }
+ ax25_start_heartbeat(ax25);
+}
X
- if (ax25->t3timer > 0 && --ax25->t3timer == 0) {
- if (ax25->state == AX25_STATE_3) {
- ax25->n2count = 0;
- ax25_std_transmit_enquiry(ax25);
- ax25->state = AX25_STATE_4;
- }
- ax25->t3timer = ax25->t3;
+void ax25_std_t2timer_expiry(ax25_cb *ax25)
+{
+ if (ax25->condition & AX25_COND_ACK_PENDING) {
+ ax25->condition &= ~AX25_COND_ACK_PENDING;
+ ax25_std_timeout_response(ax25);
X }
+}
X
- if (ax25->idletimer > 0 && --ax25->idletimer == 0) {
- /* dl1bke 960228: close the connection when IDLE expires */
- /* similar to DAMA T3 timeout but with */
- /* a "clean" disconnect of the connection */
-
- ax25_clear_queues(ax25);
-
- ax25->n2count = 0;
- ax25->t3timer = 0;
- ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
- ax25->state = AX25_STATE_2;
- ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
-
- if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = 0;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- ax25->sk->destroy = 1;
- }
- }
+void ax25_std_t3timer_expiry(ax25_cb *ax25)
+{
+ ax25->n2count = 0;
+ ax25_std_transmit_enquiry(ax25);
+ ax25->state = AX25_STATE_4;
+}
+
+void ax25_std_idletimer_expiry(ax25_cb *ax25)
+{
+ ax25_clear_queues(ax25);
X
- if (ax25->t1timer == 0 || --ax25->t1timer > 0) {
- ax25_set_timer(ax25);
- return;
+ ax25->n2count = 0;
+ ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
+ ax25->state = AX25_STATE_2;
+
+ ax25_calculate_t1(ax25);
+ ax25_start_t1timer(ax25);
+ ax25_stop_t2timer(ax25);
+ ax25_stop_t3timer(ax25);
+
+ if (ax25->sk != NULL) {
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = 0;
+ ax25->sk->shutdown |= SEND_SHUTDOWN;
+ if (!ax25->sk->dead)
+ ax25->sk->state_change(ax25->sk);
+ ax25->sk->dead = 1;
X }
+}
X
+void ax25_std_t1timer_expiry(ax25_cb *ax25)
+{
X switch (ax25->state) {
X case AX25_STATE_1:
X if (ax25->n2count == ax25->n2) {
X if (ax25->modulus == AX25_MODULUS) {
- ax25_link_failed(&ax25->dest_addr, ax25->ax25_dev->dev);
- ax25_clear_queues(ax25);
- ax25->state = AX25_STATE_0;
- if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ETIMEDOUT;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- }
+ ax25_disconnect(ax25, ETIMEDOUT);
+ return;
X } else {
X ax25->modulus = AX25_MODULUS;
X ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
@@ -160,19 +140,9 @@
X
X case AX25_STATE_2:
X if (ax25->n2count == ax25->n2) {
- ax25_link_failed(&ax25->dest_addr, ax25->ax25_dev->dev);
- ax25_clear_queues(ax25);
- ax25->state = AX25_STATE_0;
X ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
-
- if (ax25->sk != NULL) {
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ETIMEDOUT;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- }
+ ax25_disconnect(ax25, ETIMEDOUT);
+ return;
X } else {
X ax25->n2count++;
X ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
@@ -187,19 +157,9 @@
X
X case AX25_STATE_4:
X if (ax25->n2count == ax25->n2) {
- ax25_link_failed(&ax25->dest_addr, ax25->ax25_dev->dev);
- ax25_clear_queues(ax25);
X ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
- ax25->state = AX25_STATE_0;
- if (ax25->sk != NULL) {
- SOCK_DEBUG(ax25->sk, "AX.25 link Failure\n");
- ax25->sk->state = TCP_CLOSE;
- ax25->sk->err = ETIMEDOUT;
- ax25->sk->shutdown |= SEND_SHUTDOWN;
- if (!ax25->sk->dead)
- ax25->sk->state_change(ax25->sk);
- ax25->sk->dead = 1;
- }
+ ax25_disconnect(ax25, ETIMEDOUT);
+ return;
X } else {
X ax25->n2count++;
X ax25_std_transmit_enquiry(ax25);
@@ -207,9 +167,8 @@
X break;
X }
X
- ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
-
- ax25_set_timer(ax25);
+ ax25_calculate_t1(ax25);
+ ax25_start_t1timer(ax25);
X }
X
X #endif
diff -u --recursive --new-file v2.1.43/linux/net/ax25/ax25_subr.c linux/net/ax25/ax25_subr.c
--- v2.1.43/linux/net/ax25/ax25_subr.c Thu May 29 21:53:11 1997
+++ linux/net/ax25/ax25_subr.c Mon Jul 7 08:19:59 1997
@@ -1,5 +1,5 @@
X /*
- * AX.25 release 036
+ * AX.25 release 037
X *
X * This code REQUIRES 2.1.15 or higher/ NET3.038
X *
@@ -30,6 +30,7 @@
X * AX.25 032 Joerg(DL1BKE) Added ax25_queue_length to count the number of
X * enqueued buffers of a socket..
X * AX.25 035 Frederic(F1OAT) Support for pseudo-digipeating.
+ * AX.25 037 Jonathan(G4KLX) New timer architecture.
X */
X
X #include <linux/config.h>
@@ -259,7 +260,7 @@
X /*
X * Exponential backoff for AX.25
X */
-unsigned short ax25_calculate_t1(ax25_cb *ax25)
+void ax25_calculate_t1(ax25_cb *ax25)
X {
X int n, t = 2;
X
@@ -278,7 +279,7 @@
X break;
X }
X
- return t * ax25->rtt;
+ ax25->t1 = t * ax25->rtt;
X }
X
X /*
@@ -289,14 +290,37 @@
X if (ax25->backoff == 0)
X return;
X
- if (ax25->t1timer > 0 && ax25->n2count == 0)
- ax25->rtt = (9 * ax25->rtt + ax25->t1 - ax25->t1timer) / 10;
+ if (ax25_t1timer_running(ax25) && ax25->n2count == 0)
+ ax25->rtt = (9 * ax25->rtt + ax25->t1 - ax25_display_timer(&ax25->t1timer)) / 10;
X
X if (ax25->rtt < AX25_T1CLAMPLO)
X ax25->rtt = AX25_T1CLAMPLO;
X
X if (ax25->rtt > AX25_T1CLAMPHI)
X ax25->rtt = AX25_T1CLAMPHI;
+}
+
+void ax25_disconnect(ax25_cb *ax25, int reason)
+{
+ ax25_clear_queues(ax25);
+
+ ax25_stop_t1timer(ax25);
+ ax25_stop_t2timer(ax25);
+ ax25_stop_t3timer(ax25);
+ ax25_stop_idletimer(ax25);
+
+ ax25->state = AX25_STATE_0;
+
+ ax25_link_failed(ax25, reason);
+
+ if (ax25->sk != NULL) {
+ ax25->sk->state = TCP_CLOSE;
+ ax25->sk->err = reason;
+ ax25->sk->shutdown |= SEND_SHUTDOWN;
+ if (!ax25->sk->dead)
+ ax25->sk->state_change(ax25->sk);
+ ax25->sk->dead = 1;
+ }
X }
X
X #endif
diff -u --recursive --new-file v2.1.43/linux/net/ax25/ax25_timer.c linux/net/ax25/ax25_timer.c
--- v2.1.43/linux/net/ax25/ax25_timer.c Thu May 29 21:53:11 1997
+++ linux/net/ax25/ax25_timer.c Mon Jul 7 08:19:59 1997
@@ -1,5 +1,5 @@
X /*
- * AX.25 release 036
+ * AX.25 release 037
X *
X * This code REQUIRES 2.1.15 or higher/ NET3.038
X *
@@ -21,6 +21,7 @@
X * AX.25 036 Jonathan(G4KLX) Split Standard and DAMA code into seperate files.
X * Joerg(DL1BKE) Fixed DAMA Slave. We are *required* to start with
X * standard AX.25 mode.
+ * AX.25 037 Jonathan(G4KLX) New timer architecture.
X */
X
X #include <linux/config.h>
@@ -46,48 +47,205 @@
X #include <linux/mm.h>
X #include <linux/interrupt.h>
X
-static void ax25_timer(unsigned long);
+static void ax25_heartbeat_expiry(unsigned long);
+static void ax25_t1timer_expiry(unsigned long);
+static void ax25_t2timer_expiry(unsigned long);
+static void ax25_t3timer_expiry(unsigned long);
+static void ax25_idletimer_expiry(unsigned long);
X
-/*
- * Linux set timer
- */
-void ax25_set_timer(ax25_cb *ax25)
+void ax25_start_heartbeat(ax25_cb *ax25)
X {


- unsigned long flags;
-

- save_flags(flags); cli();
X del_timer(&ax25->timer);
- restore_flags(flags);
X
X ax25->timer.data = (unsigned long)ax25;
- ax25->timer.function = &ax25_timer;
- ax25->timer.expires = jiffies + (HZ / 10);
+ ax25->timer.function = &ax25_heartbeat_expiry;
+ ax25->timer.expires = jiffies + 5 * HZ;
X
X add_timer(&ax25->timer);
X }
X
-/*
- * AX.25 TIMER
- *
- * This routine is called every 100ms. Decrement timer by this
- * amount - if expired then process the event.
- */
-static void ax25_timer(unsigned long param)
+void ax25_start_t1timer(ax25_cb *ax25)
+{
+ del_timer(&ax25->t1timer);
+
+ ax25->t1timer.data = (unsigned long)ax25;
+ ax25->t1timer.function = &ax25_t1timer_expiry;
+ ax25->t1timer.expires = jiffies + ax25->t1;
+
+ add_timer(&ax25->t1timer);
+}
+
+void ax25_start_t2timer(ax25_cb *ax25)
+{
+ del_timer(&ax25->t2timer);
+
+ ax25->t2timer.data = (unsigned long)ax25;
+ ax25->t2timer.function = &ax25_t2timer_expiry;
+ ax25->t2timer.expires = jiffies + ax25->t2;
+
+ add_timer(&ax25->t2timer);
+}
+
+void ax25_start_t3timer(ax25_cb *ax25)
+{
+ del_timer(&ax25->t3timer);
+
+ if (ax25->t3 > 0) {
+ ax25->t3timer.data = (unsigned long)ax25;
+ ax25->t3timer.function = &ax25_t3timer_expiry;
+ ax25->t3timer.expires = jiffies + ax25->t3;
+
+ add_timer(&ax25->t3timer);
+ }
+}
+
+void ax25_start_idletimer(ax25_cb *ax25)
+{
+ del_timer(&ax25->idletimer);
+
+ if (ax25->idle > 0) {
+ ax25->idletimer.data = (unsigned long)ax25;
+ ax25->idletimer.function = &ax25_idletimer_expiry;
+ ax25->idletimer.expires = jiffies + ax25->idle;
+
+ add_timer(&ax25->idletimer);
+ }
+}
+
+void ax25_stop_heartbeat(ax25_cb *ax25)
+{
+ del_timer(&ax25->timer);
+}
+
+void ax25_stop_t1timer(ax25_cb *ax25)
+{
+ del_timer(&ax25->t1timer);
+}
+
+void ax25_stop_t2timer(ax25_cb *ax25)
+{
+ del_timer(&ax25->t2timer);
+}
+
+void ax25_stop_t3timer(ax25_cb *ax25)
+{
+ del_timer(&ax25->t3timer);
+}
+
+void ax25_stop_idletimer(ax25_cb *ax25)
+{
+ del_timer(&ax25->idletimer);
+}
+
+int ax25_t1timer_running(ax25_cb *ax25)
+{
+ return (ax25->t1timer.prev != NULL || ax25->t1timer.next != NULL);
+}
+
+unsigned long ax25_display_timer(struct timer_list *timer)
+{
+ if (timer->prev == NULL && timer->next == NULL)
+ return 0;
+
+ return timer->expires - jiffies;
+}
+
+static void ax25_heartbeat_expiry(unsigned long param)
+{
+ ax25_cb *ax25 = (ax25_cb *)param;
+
+ switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
+ case AX25_PROTO_STD_SIMPLEX:
+ case AX25_PROTO_STD_DUPLEX:
+ ax25_std_heartbeat_expiry(ax25);
+ break;
+
+#ifdef CONFIG_AX25_DAMA_SLAVE
+ case AX25_PROTO_DAMA_SLAVE:
+ if (ax25->ax25_dev->dama.slave)
+ ax25_ds_heartbeat_expiry(ax25);
+ else
+ ax25_std_heartbeat_expiry(ax25);
+ break;
+#endif
+ }
+}
+
+static void ax25_t1timer_expiry(unsigned long param)
+{
+ ax25_cb *ax25 = (ax25_cb *)param;
+
+ switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
+ case AX25_PROTO_STD_SIMPLEX:
+ case AX25_PROTO_STD_DUPLEX:
+ ax25_std_t1timer_expiry(ax25);
+ break;
+
+#ifdef CONFIG_AX25_DAMA_SLAVE
+ case AX25_PROTO_DAMA_SLAVE:
+ if (!ax25->ax25_dev->dama.slave)
+ ax25_std_t1timer_expiry(ax25);
+ break;
+#endif
+ }
+}
+
+static void ax25_t2timer_expiry(unsigned long param)
+{
+ ax25_cb *ax25 = (ax25_cb *)param;
+
+ switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
+ case AX25_PROTO_STD_SIMPLEX:
+ case AX25_PROTO_STD_DUPLEX:
+ ax25_std_t2timer_expiry(ax25);
+ break;
+
+#ifdef CONFIG_AX25_DAMA_SLAVE
+ case AX25_PROTO_DAMA_SLAVE:
+ if (!ax25->ax25_dev->dama.slave)
+ ax25_std_t2timer_expiry(ax25);
+ break;
+#endif
+ }
+}
+
+static void ax25_t3timer_expiry(unsigned long param)
+{
+ ax25_cb *ax25 = (ax25_cb *)param;
+
+ switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
+ case AX25_PROTO_STD_SIMPLEX:
+ case AX25_PROTO_STD_DUPLEX:
+ ax25_std_t3timer_expiry(ax25);
+ break;
+
+#ifdef CONFIG_AX25_DAMA_SLAVE
+ case AX25_PROTO_DAMA_SLAVE:
+ if (ax25->ax25_dev->dama.slave)
+ ax25_ds_t3timer_expiry(ax25);
+ else
+ ax25_std_t3timer_expiry(ax25);
+ break;
+#endif
+ }
+}
+
+static void ax25_idletimer_expiry(unsigned long param)
X {
X ax25_cb *ax25 = (ax25_cb *)param;
X
X switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
X case AX25_PROTO_STD_SIMPLEX:
X case AX25_PROTO_STD_DUPLEX:
- ax25_std_timer(ax25);
+ ax25_std_idletimer_expiry(ax25);
X break;
X
X #ifdef CONFIG_AX25_DAMA_SLAVE
X case AX25_PROTO_DAMA_SLAVE:
X if (ax25->ax25_dev->dama.slave)
- ax25_ds_timer(ax25);
+ ax25_ds_idletimer_expiry(ax25);
X else
- ax25_std_timer(ax25);
+ ax25_std_idletimer_expiry(ax25);
X break;
X #endif
X }
diff -u --recursive --new-file v2.1.43/linux/net/ax25/ax25_uid.c linux/net/ax25/ax25_uid.c
--- v2.1.43/linux/net/ax25/ax25_uid.c Thu May 29 21:53:11 1997
+++ linux/net/ax25/ax25_uid.c Mon Jul 7 08:19:59 1997
@@ -1,5 +1,5 @@
X /*
- * AX.25 release 036
+ * AX.25 release 037
X *
X * This code REQUIRES 2.1.15 or higher/ NET3.038
X *
diff -u --recursive --new-file v2.1.43/linux/net/ax25/sysctl_net_ax25.c linux/net/ax25/sysctl_net_ax25.c
--- v2.1.43/linux/net/ax25/sysctl_net_ax25.c Thu May 29 21:53:11 1997
+++ linux/net/ax25/sysctl_net_ax25.c Mon Jul 7 08:19:59 1997
@@ -17,14 +17,14 @@
X static int min_conmode[] = {0}, max_conmode[] = {2};
X static int min_window[] = {1}, max_window[] = {7};
X static int min_ewindow[] = {1}, max_ewindow[] = {63};
-static int min_t1[] = {1}, max_t1[] = {30 * AX25_SLOWHZ};
-static int min_t2[] = {1}, max_t2[] = {20 * AX25_SLOWHZ};
-static int min_t3[] = {0}, max_t3[] = {3600 * AX25_SLOWHZ};
-static int min_idle[] = {0}, max_idle[] = {65535 * AX25_SLOWHZ};
+static int min_t1[] = {1}, max_t1[] = {30 * HZ};
+static int min_t2[] = {1}, max_t2[] = {20 * HZ};
+static int min_t3[] = {0}, max_t3[] = {3600 * HZ};
+static int min_idle[] = {0}, max_idle[] = {65535 * HZ};
X static int min_n2[] = {1}, max_n2[] = {31};
X static int min_paclen[] = {1}, max_paclen[] = {512};
X static int min_proto[] = {0}, max_proto[] = {3};
-static int min_ds_timeout[] = {0}, max_ds_timeout[] = {65535 * AX25_SLOWHZ};
+static int min_ds_timeout[] = {0}, max_ds_timeout[] = {65535 * HZ};
X
X static struct ctl_table_header *ax25_table_header;
X
diff -u --recursive --new-file v2.1.43/linux/net/core/sysctl_net_core.c linux/net/core/sysctl_net_core.c
--- v2.1.43/linux/net/core/sysctl_net_core.c Mon Jun 16 16:36:01 1997
+++ linux/net/core/sysctl_net_core.c Mon Jul 7 08:19:59 1997
@@ -7,6 +7,9 @@
X
X #include <linux/mm.h>
X #include <linux/sysctl.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_SYSCTL
X
X extern __u32 sysctl_wmem_max;
X extern __u32 sysctl_rmem_max;
@@ -33,3 +36,4 @@
X &proc_dointvec_jiffies},
X { 0 }
X };
+#endif
diff -u --recursive --new-file v2.1.43/linux/net/ipv4/Config.in linux/net/ipv4/Config.in
--- v2.1.43/linux/net/ipv4/Config.in Fri Feb 7 05:54:55 1997
+++ linux/net/ipv4/Config.in Thu Jun 26 12:33:41 1997
@@ -31,6 +31,7 @@
X bool 'IP: ARP daemon support (EXPERIMENTAL)' CONFIG_ARPD
X fi
X fi
+bool 'IP: TCP syncookie support (not enabled per default) ' CONFIG_SYN_COOKIES
X comment '(it is safe to leave these untouched)'
X bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP
X tristate 'IP: Reverse ARP' CONFIG_INET_RARP
diff -u --recursive --new-file v2.1.43/linux/net/ipv4/Makefile linux/net/ipv4/Makefile
--- v2.1.43/linux/net/ipv4/Makefile Thu Mar 27 14:40:15 1997
+++ linux/net/ipv4/Makefile Thu Jun 26 12:33:41 1997
@@ -52,6 +52,11 @@


X endif
X endif
X

+ifeq ($(CONFIG_SYN_COOKIES),y)
+IPV4_OBJS += syncookies.o
+# module not supported, because it would be too messy.
+endif
+
X ifdef CONFIG_INET
X O_OBJS := $(IPV4_OBJS)
X OX_OBJS := $(IPV4X_OBJS)
diff -u --recursive --new-file v2.1.43/linux/net/ipv4/raw.c linux/net/ipv4/raw.c
--- v2.1.43/linux/net/ipv4/raw.c Fri Apr 4 08:52:28 1997
+++ linux/net/ipv4/raw.c Thu Jun 26 12:33:41 1997
@@ -388,7 +388,7 @@
X err = memcpy_fromiovec(buf, msg->msg_iov, len);
X if (!err)
X {
- unsigned short fs;
+ unsigned long fs;
X fs=get_fs();
X set_fs(get_ds());
X err=raw_sendto(sk,buf,len, msg);
diff -u --recursive --new-file v2.1.43/linux/net/ipv4/route.c linux/net/ipv4/route.c
--- v2.1.43/linux/net/ipv4/route.c Tue May 13 22:41:23 1997
+++ linux/net/ipv4/route.c Thu Jun 26 12:33:41 1997
@@ -45,6 +45,7 @@
X * Pavel Krauz : Limited broadcast fixed
X * Alexey Kuznetsov : End of old history. Splitted to fib.c and
X * route.c and rewritten from scratch.
+ * Andi Kleen : Load-limit warning messages.
X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License
@@ -568,7 +569,7 @@
X return;
X
X reject_redirect:
- if (ipv4_config.log_martians)
+ if (ipv4_config.log_martians && net_ratelimit())
X printk(KERN_INFO "Redirect from %lX/%s to %lX ignored."
X "Path = %lX -> %lX, tos %02x\n",
X ntohl(old_gw), dev->name, ntohl(new_gw),
@@ -636,7 +637,7 @@
X if (jiffies - rt->last_error > (RT_REDIRECT_LOAD<<rt->errors)) {
X icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
X rt->last_error = jiffies;
- if (ipv4_config.log_martians && ++rt->errors == RT_REDIRECT_NUMBER)
+ if (ipv4_config.log_martians && ++rt->errors == RT_REDIRECT_NUMBER && net_ratelimit())
X printk(KERN_WARNING "host %08x/%s ignores redirects for %08x to %08x.\n",
X rt->rt_src, rt->rt_src_dev->name, rt->rt_dst, rt->rt_gateway);
X }
@@ -1083,12 +1084,12 @@
X * Do not cache martian addresses: they should be logged (RFC1812)
X */
X martian_destination:
- if (ipv4_config.log_martians)
+ if (ipv4_config.log_martians && net_ratelimit())
X printk(KERN_WARNING "martian destination %08x from %08x, dev %s\n", daddr, saddr, dev->name);
X return -EINVAL;
X
X martian_source:
- if (ipv4_config.log_martians) {
+ if (ipv4_config.log_martians && net_ratelimit()) {
X /*
X * RFC1812 recommenadtion, if source is martian,
X * the only hint is MAC header.
diff -u --recursive --new-file v2.1.43/linux/net/ipv4/syncookies.c linux/net/ipv4/syncookies.c
--- v2.1.43/linux/net/ipv4/syncookies.c Wed Dec 31 16:00:00 1969
+++ linux/net/ipv4/syncookies.c Thu Jun 26 12:33:41 1997


@@ -0,0 +1,218 @@
+/*

+ * Syncookies implementation for the Linux kernel
+ *
+ * Copyright (C) 1997 Andi Kleen
+ * Based on ideas by D.J.Bernstein and Eric Schenk.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * $Id: syncookies.c,v 1.1 1997/06/06 20:37:56 freitag Exp $
+ *
+ * Missing: IPv6 support.
+ * Some counter so that the Administrator can see when the machine
+ * is under a syn flood attack.


+ */
+
+#include <linux/config.h>

+#if defined(CONFIG_SYN_COOKIES)
+#include <linux/tcp.h>
+#include <linux/malloc.h>
+#include <linux/random.h>
+#include <net/tcp.h>
+
+extern int sysctl_tcp_syncookies;
+
+static unsigned long tcp_lastsynq_overflow;
+
+/*
+ * This table has to be sorted. Only 8 entries are allowed and the
+ * last entry has to be duplicated.
+ * XXX generate a better table.
+ * Unresolved Issues: HIPPI with a 64k MSS is not well supported.
+ */
+static __u16 const msstab[] = {
+ 64,
+ 256,
+ 512,
+ 536,
+ 1024,
+ 1440,
+ 1460,
+ 4312,
+ 4312
+};
+
+static __u32 make_syncookie(struct sk_buff *skb, __u32 counter, __u32 seq)
+{
+ __u32 z;
+
+ z = secure_tcp_syn_cookie(skb->nh.iph->saddr, skb->nh.iph->daddr,
+ skb->h.th->source, skb->h.th->dest,
+ seq,
+ counter);
+
+#if 0
+ printk(KERN_DEBUG
+ "msc: z=%u,cnt=%u,seq=%u,sadr=%u,dadr=%u,sp=%u,dp=%u\n",
+ z,counter,seq,
+ skb->nh.iph->saddr,skb->nh.iph->daddr,
+ ntohs(skb->h.th->source), ntohs(skb->h.th->dest));
+#endif
+
+ return z;
+}
+
+/*
+ * Generate a syncookie.
+ */
+__u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb,
+ __u16 *mssp)
+{
+ int i;
+ __u32 isn;
+ const __u16 mss = *mssp, *w;
+
+ tcp_lastsynq_overflow = jiffies;
+
+ isn = make_syncookie(skb, (jiffies/HZ) >> 6, ntohl(skb->h.th->seq));
+
+ /* XXX sort msstab[] by probability? */
+ w = msstab;
+ for (i = 0; i < 8; i++)
+ if (mss >= *w && mss < *++w)
+ goto found;
+ i--;
+found:
+ *mssp = w[-1];
+
+ isn |= i;
+ return isn;
+}
+
+/* This value should be dependant on TCP_TIMEOUT_INIT and
+ * sysctl_tcp_retries1. It's a rather complicated formula
+ * (exponential backoff) to compute at runtime so it's currently hardcoded
+ * here.
+ */
+#define COUNTER_TRIES 4
+
+/*
+ * Check if a ack sequence number is a valid syncookie.
+ */
+static inline int cookie_check(struct sk_buff *skb, __u32 cookie)
+{
+ int mssind;
+ int i;
+ __u32 counter;
+ __u32 seq;
+
+ if ((jiffies - tcp_lastsynq_overflow) > TCP_TIMEOUT_INIT
+ && tcp_lastsynq_overflow)
+ return 0;
+
+ mssind = cookie & 7;
+ cookie &= ~7;
+
+ counter = (jiffies/HZ)>>6;
+ seq = ntohl(skb->h.th->seq)-1;
+ for (i = 0; i < COUNTER_TRIES; i++)
+ if (make_syncookie(skb, counter-i, seq) == cookie)
+ return msstab[mssind];
+


+ return 0;
+}
+

+extern struct or_calltable or_ipv4;
+
+static inline struct sock *
+get_cookie_sock(struct sock *sk, struct sk_buff *skb, struct open_request *req,
+ struct dst_entry *dst)
+{
+ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
+
+ sk = tp->af_specific->syn_recv_sock(sk, skb, req, dst);
+ req->sk = sk;
+
+ /* Queue up for accept() */
+ tcp_synq_queue(tp, req);
+
+ return sk;
+}
+
+struct sock *
+cookie_v4_check(struct sock *sk, struct sk_buff *skb, struct ip_options *opt)
+{
+ __u32 cookie = ntohl(skb->h.th->ack_seq)-1;
+ struct open_request *req;
+ int mss;
+ struct rtable *rt;
+
+ if (!sysctl_tcp_syncookies)
+ return sk;
+ if (!skb->h.th->ack)
+ return sk;
+
+ mss = cookie_check(skb, cookie);
+ if (mss == 0)
+ return sk;
+
+ req = tcp_openreq_alloc();
+ if (req == NULL)
+ return NULL;
+
+ req->rcv_isn = htonl(skb->h.th->seq)-1;
+ req->snt_isn = cookie;
+ req->mss = mss;
+ req->rmt_port = skb->h.th->source;
+ req->af.v4_req.loc_addr = skb->nh.iph->daddr;
+ req->af.v4_req.rmt_addr = skb->nh.iph->saddr;
+ req->class = &or_ipv4; /* for savety */
+
+ /* We throwed the options of the initial SYN away, so we hope
+ * the ACK carries the same options again (see RFC1122 4.2.3.8)
+ */
+ if (opt && opt->optlen) {
+ int opt_size = sizeof(struct ip_options) + opt->optlen;
+
+ req->af.v4_req.opt = kmalloc(opt_size, GFP_ATOMIC);
+ if (req->af.v4_req.opt) {
+ if (ip_options_echo(req->af.v4_req.opt, skb)) {
+ kfree_s(req->af.v4_req.opt, opt_size);
+ req->af.v4_req.opt = NULL;
+ }
+ }
+ }
+
+ req->af.v4_req.opt = NULL;
+ req->snd_wscale = req->rcv_wscale = req->tstamp_ok = 0;
+ req->wscale_ok = 0;
+ req->expires = 0UL;
+ req->retrans = 0;
+
+ /*
+ * We need to lookup the route here to get at the correct
+ * window size. We should better make sure that the window size
+ * hasn't changed since we received the original syn, but I see
+ * no easy way to do this.
+ */
+ if (ip_route_output(&rt,
+ opt && opt->srr ? opt->faddr :
+ req->af.v4_req.rmt_addr,req->af.v4_req.loc_addr,
+ sk->ip_tos, NULL)) {
+ tcp_openreq_free(req);


+ return NULL;
+ }
+

+ /* Try to redo what tcp_v4_send_synack did. */
+ req->window_clamp = rt->u.dst.window;
+ tcp_select_initial_window(sock_rspace(sk)/2,req->mss,
+ &req->rcv_wnd, &req->window_clamp,
+ 0, &req->rcv_wscale);
+
+ return get_cookie_sock(sk, skb, req, &rt->u.dst);
+}
+
+#endif
diff -u --recursive --new-file v2.1.43/linux/net/ipv4/sysctl_net_ipv4.c linux/net/ipv4/sysctl_net_ipv4.c
--- v2.1.43/linux/net/ipv4/sysctl_net_ipv4.c Mon Jun 16 16:36:01 1997
+++ linux/net/ipv4/sysctl_net_ipv4.c Thu Jun 26 12:33:41 1997
@@ -60,8 +60,8 @@
X extern int sysctl_tcp_max_delay_acks;
X extern int sysctl_tcp_fin_timeout;
X extern int sysctl_tcp_syncookies;
-extern int sysctl_tcp_always_syncookie;
X extern int sysctl_tcp_syn_retries;
+extern int sysctl_tcp_stdurg;
X
X extern int tcp_sysctl_congavoid(ctl_table *ctl, int write, struct file * filp,
X void *buffer, size_t *lenp);
@@ -203,10 +203,12 @@
X {NET_IPV4_IGMP_AGE_THRESHOLD, "igmp_age_threshold",
X &sysctl_igmp_age_threshold, sizeof(int), 0644, NULL, &proc_dointvec},
X #endif
+#ifdef CONFIG_SYN_COOKIES
X {NET_TCP_SYNCOOKIES, "tcp_syncookies",
X &sysctl_tcp_syncookies, sizeof(int), 0644, NULL, &proc_dointvec},
- {NET_TCP_ALWAYS_SYNCOOKIE, "tcp_always_syncookie",
- &sysctl_tcp_always_syncookie, sizeof(int), 0644, NULL, &proc_dointvec},
+#endif
+ {NET_TCP_STDURG, "tcp_stdurg", &sysctl_tcp_stdurg,
+ sizeof(int), 0644, NULL, &proc_dointvec},
X {0}
X };
X
diff -u --recursive --new-file v2.1.43/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- v2.1.43/linux/net/ipv4/tcp_input.c Mon Jun 16 16:36:02 1997
+++ linux/net/ipv4/tcp_input.c Thu Jun 26 12:33:41 1997


@@ -5,7 +5,7 @@
X *

X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_input.c,v 1.52 1997/05/31 12:36:42 freitag Exp $
+ * Version: $Id: tcp_input.c,v 1.53 1997/06/06 20:38:00 freitag Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -65,6 +65,7 @@
X int sysctl_tcp_syncookies;
X int sysctl_tcp_always_syncookie;
X int sysctl_tcp_max_delay_acks = MAX_DELAY_ACK;
+int sysctl_tcp_stdurg;
X
X static tcp_sys_cong_ctl_t tcp_sys_cong_ctl_f = &tcp_cong_avoid_vanj;
X
@@ -288,7 +289,7 @@
X * FIXME: surely this can be more efficient. -- erics
X */
X
-void tcp_parse_options(struct tcphdr *th, struct tcp_opt *tp)
+void tcp_parse_options(struct tcphdr *th, struct tcp_opt *tp, int no_fancy)
X {
X unsigned char *ptr;
X int length=(th->doff*4)-sizeof(struct tcphdr);
@@ -323,21 +324,21 @@
X break;
X case TCPOPT_WINDOW:
X if(opsize==TCPOLEN_WINDOW && th->syn)
- if (sysctl_tcp_window_scaling) {
+ if (!no_fancy && sysctl_tcp_window_scaling) {
X tp->wscale_ok = 1;
X tp->snd_wscale = *(__u8 *)ptr;
X }
X break;
X case TCPOPT_SACK_PERM:
X if(opsize==TCPOLEN_SACK_PERM && th->syn)
- if (sysctl_tcp_sack)
+ if (sysctl_tcp_sack && !no_fancy)
X tp->sack_ok = 1;
X case TCPOPT_TIMESTAMP:
X if(opsize==TCPOLEN_TIMESTAMP) {
X /* Cheaper to set again then to
X * test syn. Optimize this?
X */
- if (sysctl_tcp_timestamps)
+ if (sysctl_tcp_timestamps && !no_fancy)
X tp->tstamp_ok = 1;
X tp->saw_tstamp = 1;
X tp->rcv_tsval = ntohl(*(__u32 *)ptr);
@@ -345,6 +346,8 @@
X }
X break;
X case TCPOPT_SACK:
+ if (no_fancy)
+ break;
X tp->sacks = (opsize-2)>>3;
X if (tp->sacks<<3 == opsize-2) {
X int i;
@@ -385,7 +388,7 @@
X return 1;
X }
X }
- tcp_parse_options(th,tp);
+ tcp_parse_options(th,tp,0);
X return 1;
X }
X
@@ -1233,7 +1236,7 @@
X * place. We handle URGent data wrong. We have to - as
X * BSD still doesn't use the correction from RFC961.
X * For 1003.1g we should support a new option TCP_STDURG to permit
- * either form.
+ * either form (or just set the sysctl tcp_stdurg).
X */
X
X static void tcp_check_urg(struct sock * sk, struct tcphdr * th)
@@ -1241,7 +1244,7 @@
X struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
X u32 ptr = ntohs(th->urg_ptr);
X
- if (ptr)
+ if (ptr && !sysctl_tcp_stdurg)
X ptr--;
X ptr += ntohl(th->seq);
X
@@ -1459,13 +1462,11 @@
X /* These use the socket TOS..
X * might want to be the received TOS
X */
- if(th->ack)
+ if(th->ack)
X return 1; /* send reset */
X
X if(th->syn) {
- __u32 isn = tp->af_specific->init_sequence(sk, skb);
-
- if(tp->af_specific->conn_request(sk, skb, opt, isn) < 0)
+ if(tp->af_specific->conn_request(sk, skb, opt, 0) < 0)
X return 1;
X
X /* Now we have several options: In theory there is
@@ -1531,7 +1532,7 @@
X tp->fin_seq = skb->seq;
X
X tcp_set_state(sk, TCP_ESTABLISHED);
- tcp_parse_options(th,tp);
+ tcp_parse_options(th,tp,0);
X /* FIXME: need to make room for SACK still */
X if (tp->wscale_ok == 0) {
X tp->snd_wscale = tp->rcv_wscale = 0;
@@ -1574,7 +1575,7 @@
X * tcp_connect.
X */
X tcp_set_state(sk, TCP_SYN_RECV);
- tcp_parse_options(th,tp);
+ tcp_parse_options(th,tp,0);
X if (tp->saw_tstamp) {
X tp->ts_recent = tp->rcv_tsval;
X tp->ts_recent_stamp = jiffies;
@@ -1616,6 +1617,8 @@
X sk->shutdown = SHUTDOWN_MASK;
X
X isn = tp->rcv_nxt + 128000;
+ if (isn == 0)
+ isn++;
X
X sk = tp->af_specific->get_sock(skb, th);
X
@@ -1710,8 +1713,10 @@
X tp->snd_wl1 = skb->seq;
X tp->snd_wl2 = skb->ack_seq;
X
- } else
+ } else {
+ SOCK_DEBUG(sk, "bad ack\n");
X return 1;
+ }
X break;
X
X case TCP_FIN_WAIT1:
diff -u --recursive --new-file v2.1.43/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.1.43/linux/net/ipv4/tcp_ipv4.c Thu May 15 16:48:06 1997
+++ linux/net/ipv4/tcp_ipv4.c Mon Jul 7 08:19:59 1997


@@ -5,7 +5,7 @@
X *

X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_ipv4.c,v 1.43 1997/05/06 09:31:44 davem Exp $
+ * Version: $Id: tcp_ipv4.c,v 1.51 1997/07/04 23:35:02 freitag Exp $
X *
X * IPv4 specific functions
X *
@@ -30,6 +30,9 @@
X * David S. Miller : Change semantics of established hash,
X * half is devoted to TIME_WAIT sockets
X * and the rest go in the other half.
+ * Andi Kleen : Add support for syncookies and fixed
+ * some bugs: ip options weren't passed to
+ * the TCP layer, missed a check for an ACK bit.
X */
X
X #include <linux/config.h>
@@ -48,6 +51,7 @@
X extern int sysctl_tcp_tsack;
X extern int sysctl_tcp_timestamps;
X extern int sysctl_tcp_window_scaling;
+extern int sysctl_tcp_syncookies;
X
X static void tcp_v4_send_reset(struct sk_buff *skb);
X
@@ -403,7 +407,7 @@
X
X #endif
X
-static __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
+static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
X {
X return secure_tcp_sequence_number(sk->saddr, sk->daddr,
X skb->h.th->dest,
@@ -697,6 +701,12 @@
X }
X
X /* FIXME: What about the IP layer options size here? */
+ /* FIXME: add a timeout here, to cope with broken devices that
+ drop all DF=1 packets. Do some more sanity checking
+ here to prevent DOS attacks?
+ This code should kick the tcp_output routine to
+ retransmit a packet immediately because we know that
+ the last packet has been dropped. -AK */
X if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
X if (sk->ip_pmtudisc != IP_PMTUDISC_DONT) {
X int new_mtu = sk->dst_cache->pmtu - sizeof(struct iphdr) - tp->tcp_header_len;
@@ -835,6 +845,8 @@
X
X /* Don't offer more than they did.
X * This way we don't have to memorize who said what.
+ * FIXME: maybe this should be changed for better performance
+ * with syncookies.
X */
X req->mss = min(mss, req->mss);
X
@@ -891,17 +903,13 @@
X sizeof(struct ip_options) + req->af.v4_req.opt->optlen);
X }
X
-static struct or_calltable or_ipv4 = {
+struct or_calltable or_ipv4 = {
X tcp_v4_send_synack,
X tcp_v4_or_free
X };
X
-static int tcp_v4_syn_filter(struct sock *sk, struct sk_buff *skb, __u32 saddr)
-{
- return 0;
-}
-
-int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb, void *ptr, __u32 isn)
+int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb, void *ptr,
+ __u32 isn)
X {
X struct ip_options *opt = (struct ip_options *) ptr;
X struct tcp_opt tp;
@@ -909,23 +917,39 @@
X struct tcphdr *th = skb->h.th;
X __u32 saddr = skb->nh.iph->saddr;
X __u32 daddr = skb->nh.iph->daddr;
+#ifdef CONFIG_SYN_COOKIES
+ int want_cookie = 0;
+#else
+#define want_cookie 0 /* Argh, why doesn't gcc optimize this :( */
+#endif
X
X /* If the socket is dead, don't accept the connection. */
- if (sk->dead) {
- SOCK_DEBUG(sk, "Reset on %p: Connect on dead socket.\n",sk);
- tcp_statistics.TcpAttemptFails++;
- return -ENOTCONN;
- }
+ if (sk->dead)
+ goto dead;
X
- if (sk->ack_backlog >= sk->max_ack_backlog ||
- tcp_v4_syn_filter(sk, skb, saddr)) {
- SOCK_DEBUG(sk, "dropping syn ack:%d max:%d\n", sk->ack_backlog,
- sk->max_ack_backlog);
-#ifdef CONFIG_IP_TCPSF
- tcp_v4_random_drop(sk);
+ if (sk->ack_backlog >= sk->max_ack_backlog) {
+#ifdef CONFIG_SYN_COOKIES
+ if (sysctl_tcp_syncookies) {
+ static unsigned long warntime;
+
+ if (jiffies - warntime > HZ*60) {
+ warntime = jiffies;
+ printk(KERN_INFO
+ "possible SYN flooding on port %d. Sending cookies.\n", ntohs(skb->h.th->dest));
+ }
+ want_cookie = 1;
+ } else
X #endif
- tcp_statistics.TcpAttemptFails++;
- goto exit;
+ {
+ SOCK_DEBUG(sk, "dropping syn ack:%d max:%d\n", sk->ack_backlog,
+ sk->max_ack_backlog);
+ tcp_statistics.TcpAttemptFails++;
+ goto exit;
+ }
+ } else {

SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 44'
echo 'File patch-2.1.44 is continued in part 45'
echo 45 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part38

#!/bin/sh
# this is part 38 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 38; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

+ * at boot time from head.S before start_kernel is invoked.
+ */
+extern int prom_init(int argc, char **argv, char **envp);
+
+/* Simple char-by-char console I/O. */
+extern void prom_putchar(char c);
+extern char prom_getchar(void);
+
+/* Generic printf() using ARCS console I/O. */
+extern void prom_printf(char *fmt, ...);
+
+/* Memory descriptor management. */
+#define PROM_MAX_PMEMBLOCKS 32
+struct prom_pmemblock {
+ unsigned long base; /* Within KSEG0. */
+ unsigned int size; /* In bytes. */
+};
+
+/* Get next memory descriptor after CURR, returns first descriptor
+ * in chain is CURR is NULL.
+ */
+extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr);
+#define PROM_NULL_MDESC ((struct linux_mdesc *) 0)
+
+/* Called by prom_init to setup the physical memory pmemblock
+ * array.
+ */
+extern void prom_meminit(void);
+extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem);
+
+/* Returns pointer to PROM physical memory block array. */
+extern struct prom_pmemblock *prom_getpblock_array(void);
+
+/* PROM device tree library routines. */
+#define PROM_NULL_COMPONENT ((pcomponent *) 0)
+
+/* Get sibling component of THIS. */
+extern pcomponent *prom_getsibling(pcomponent *this);
+
+/* Get child component of THIS. */
+extern pcomponent *prom_getchild(pcomponent *this);
+
+/* Get parent component of CHILD. */
+extern pcomponent *prom_getparent(pcomponent *child);
+
+/* Copy component opaque data of component THIS into BUFFER
+ * if component THIS has opaque data. Returns success or
+ * failure status.
+ */
+extern long prom_getcdata(void *buffer, pcomponent *this);
+
+/* Other misc. component routines. */
+extern pcomponent *prom_childadd(pcomponent *this, pcomponent *tmp, void *data);
+extern long prom_delcomponent(pcomponent *this);
+extern pcomponent *prom_componentbypath(char *path);
+
+/* This is called at prom_init time to setup the tags which the
+ * MIPS kernel setup code wants to diddle with.
+ */
+extern void prom_setup_archtags(void);
+
+/* Environemt variable routines. */
+extern char *prom_getenv(char *name);
+extern long prom_setenv(char *name, char *value);
+
+/* ARCS command line acquisition and parsing. */
+extern char *prom_getcmdline(void);
+extern void prom_init_cmdline(void);
+
+/* Acquiring info about the current time, etc. */
+extern struct linux_tinfo *prom_gettinfo(void);
+extern unsigned long prom_getrtime(void);
+
+/* File operations. */
+extern long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt);
+extern long prom_open(char *name, enum linux_omode md, unsigned long *fd);
+extern long prom_close(unsigned long fd);
+extern long prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt);
+extern long prom_getrstatus(unsigned long fd);
+extern long prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt);
+extern long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm);
+extern long prom_mount(char *name, enum linux_mountops op);
+extern long prom_getfinfo(unsigned long fd, struct linux_finfo *buf);
+extern long prom_setfinfo(unsigned long fd, unsigned long flags, unsigned long msk);
+
+/* Running stand-along programs. */
+extern long prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr);
+extern long prom_invoke(unsigned long pc, unsigned long sp, long argc, char **argv, char **envp);
+extern long prom_exec(char *name, long argc, char **argv, char **envp);
+
+/* Misc. routines. */
+extern void prom_halt(void);
+extern void prom_powerdown(void);
+extern void prom_restart(void);
+extern void prom_reboot(void);
+extern void prom_imode(void);
+extern long prom_cfgsave(void);
+extern struct linux_sysid *prom_getsysid(void);
+extern void prom_cacheflush(void);
+
+#endif /* !(_MIPS_SGIALIB_H) */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/sgiarcs.h linux/include/asm-mips/sgiarcs.h
--- v2.1.43/linux/include/asm-mips/sgiarcs.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/sgiarcs.h Thu Jun 26 12:33:40 1997
@@ -0,0 +1,351 @@
+/* $Id: sgiarcs.h,v 1.1 1997/06/06 09:39:58 ralf Exp $
+ * SGI ARCS firmware interface defines.
+ *


+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+

+#ifndef _MIPS_SGIARCS_H
+#define _MIPS_SGIARCS_H
+
+/* Various ARCS error codes. */
+#define PROM_ESUCCESS 0x00
+#define PROM_E2BIG 0x01
+#define PROM_EACCESS 0x02
+#define PROM_EAGAIN 0x03
+#define PROM_EBADF 0x04
+#define PROM_EBUSY 0x05
+#define PROM_EFAULT 0x06
+#define PROM_EINVAL 0x07
+#define PROM_EIO 0x08
+#define PROM_EISDIR 0x09
+#define PROM_EMFILE 0x0a
+#define PROM_EMLINK 0x0b
+#define PROM_ENAMETOOLONG 0x0c
+#define PROM_ENODEV 0x0d
+#define PROM_ENOENT 0x0e
+#define PROM_ENOEXEC 0x0f
+#define PROM_ENOMEM 0x10
+#define PROM_ENOSPC 0x11
+#define PROM_ENOTDIR 0x12
+#define PROM_ENOTTY 0x13
+#define PROM_ENXIO 0x14
+#define PROM_EROFS 0x15
+/* SGI ARCS specific errno's. */
+#define PROM_EADDRNOTAVAIL 0x1f
+#define PROM_ETIMEDOUT 0x20
+#define PROM_ECONNABORTED 0x21
+#define PROM_ENOCONNECT 0x22
+
+/* Device classes, types, and identifiers for prom
+ * device inventory queries.
+ */
+enum linux_devclass {
+ system, processor, cache, adapter, controller, peripheral, memory
+};
+
+enum linux_devtypes {
+ /* Generic stuff. */
+ Arc, Cpu, Fpu,
+
+ /* Primary insn and data caches. */
+ picache, pdcache,
+
+ /* Secondary insn, data, and combined caches. */
+ sicache, sdcache, sccache,
+
+ memdev, eisa_adapter, tc_adapter, scsi_adapter, dti_adapter,
+ multifunc_adapter, dsk_controller, tp_controller, cdrom_controller,
+ worm_controller, serial_controller, net_controller, disp_controller,
+ parallel_controller, ptr_controller, kbd_controller, audio_controller,
+ misc_controller, disk_peripheral, flpy_peripheral, tp_peripheral,
+ modem_peripheral, monitor_peripheral, printer_peripheral,
+ ptr_peripheral, kbd_peripheral, term_peripheral, line_peripheral,
+ net_peripheral, misc_peripheral, anon
+};
+
+enum linux_identifier {
+ bogus, ronly, removable, consin, consout, input, output
+};
+
+/* A prom device tree component. */
+struct linux_component {
+ enum linux_devclass class; /* node class */
+ enum linux_devtypes type; /* node type */
+ enum linux_identifier iflags; /* node flags */
+ unsigned short vers; /* node version */
+ unsigned short rev; /* node revision */
+ unsigned long key; /* completely magic */
+ unsigned long amask; /* XXX affinity mask??? */
+ unsigned long cdsize; /* size of configuration data */
+ unsigned long ilen; /* length of string identifier */
+ char *iname; /* string identifier */
+};
+typedef struct linux_component pcomponent;
+
+struct linux_sysid {
+ char vend[8], prod[8];
+};
+
+/* ARCS prom memory descriptors. */
+enum linux_memtypes {
+ eblock, /* exception block */
+ rvpage, /* ARCS romvec page */
+ fcontig, /* Contiguous and free */
+ free, /* Generic free memory */
+ bmem, /* Borken memory, don't use */
+ prog, /* A loaded program resides here */
+ atmp, /* ARCS temporary storage area, wish Sparc OpenBoot told this */
+ aperm, /* ARCS permanent storage... */
+};
+
+struct linux_mdesc {
+ enum linux_memtypes type;
+ unsigned long base;
+ unsigned long pages;
+};
+
+/* Time of day descriptor. */
+struct linux_tinfo {
+ unsigned short yr;
+ unsigned short mnth;
+ unsigned short day;
+ unsigned short hr;
+ unsigned short min;
+ unsigned short sec;
+ unsigned short msec;
+};
+
+/* ARCS virtual dirents. */
+struct linux_vdirent {
+ unsigned long namelen;
+ unsigned char attr;
+ char fname[32]; /* XXX imperical, should be a define */
+};
+
+/* Other stuff for files. */
+enum linux_omode {
+ rdonly, wronly, rdwr, wronly_creat, rdwr_creat,
+ wronly_ssede, rdwr_ssede, dirent, dirent_creat
+};
+
+enum linux_seekmode {
+ absolute, relative
+};
+
+enum linux_mountops {
+ media_load, media_unload
+};
+
+/* This prom has a bolixed design. */
+struct linux_bigint {
+#ifdef __MIPSEL__
+ unsigned long lo;
+ long hi;
+#else /* !(__MIPSEL__) */
+ long hi;
+ unsigned long lo;
+#endif
+};
+
+struct linux_finfo {
+ struct linux_bigint begin;
+ struct linux_bigint end;
+ struct linux_bigint cur;
+ enum linux_devtypes dtype;
+ unsigned long namelen;
+ unsigned char attr;
+ char name[32]; /* XXX imperical, should be define */
+};
+
+struct linux_romvec {
+ /* Load an executable image. */
+ long (*load)(char *file, unsigned long end,
+ unsigned long *start_pc,
+ unsigned long *end_addr);
+
+ /* Invoke a standalong image. */
+ long (*invoke)(unsigned long startpc, unsigned long sp,
+ long argc, char **argv, char **envp);
+
+ /* Load and begin execution of a standalong image. */
+ long (*exec)(char *file, long argc, char **argv, char **envp);
+
+ void (*halt)(void); /* Halt the machine. */
+ void (*pdown)(void); /* Power down the machine. */
+ void (*restart)(void); /* XXX soft reset??? */
+ void (*reboot)(void); /* Reboot the machine. */
+ void (*imode)(void); /* Enter PROM interactive mode. */
+ int _unused1; /* padding */
+
+ /* PROM device tree interface. */
+ pcomponent *(*next_component)(pcomponent *this);
+ pcomponent *(*child_component)(pcomponent *this);
+ pcomponent *(*parent_component)(pcomponent *this);
+ long (*component_data)(void *opaque_data, pcomponent *this);
+ pcomponent *(*child_add)(pcomponent *this,
+ pcomponent *tmp,
+ void *opaque_data);
+ long (*comp_del)(pcomponent *this);
+ pcomponent *(*component_by_path)(char *file);
+
+ /* Misc. stuff. */
+ long (*cfg_save)(void);
+ struct linux_sysid *(*get_sysid)(void);
+
+ /* Probing for memory. */
+ struct linux_mdesc *(*get_mdesc)(struct linux_mdesc *curr);
+ long _unused2; /* padding */
+
+ struct linux_tinfo *(*get_tinfo)(void);
+ unsigned long (*get_rtime)(void);
+
+ /* File type operations. */
+ long (*get_vdirent)(unsigned long fd, struct linux_vdirent *entry,
+ unsigned long num, unsigned long *count);
+ long (*open)(char *file, enum linux_omode mode, unsigned long *fd);
+ long (*close)(unsigned long fd);
+ long (*read)(unsigned long fd, void *buffer, unsigned long num,
+ unsigned long *count);
+ long (*get_rstatus)(unsigned long fd);
+ long (*write)(unsigned long fd, void *buffer, unsigned long num,
+ unsigned long *count);
+ long (*seek)(unsigned long fd, struct linux_bigint *offset,
+ enum linux_seekmode smode);
+ long (*mount)(char *file, enum linux_mountops op);
+
+ /* Dealing with firmware environment variables. */
+ char *(*get_evar)(char *name);
+ long (*set_evar)(char *name, char *value);
+
+ long (*get_finfo)(unsigned long fd, struct linux_finfo *buf);
+ long (*set_finfo)(unsigned long fd, unsigned long flags,
+ unsigned long mask);
+
+ /* Miscellaneous. */
+ void (*cache_flush)(void);
+};
+
+/* The SGI ARCS parameter block is in a fixed location for standalone
+ * programs to access PROM facilities easily.
+ */
+struct linux_promblock {
+ long magic; /* magic cookie */
+#define PROMBLOCK_MAGIC 0x53435241
+
+ unsigned long len; /* length of parm block */
+ unsigned short ver; /* ARCS firmware version */
+ unsigned short rev; /* ARCS firmware revision */
+ long *rs_block; /* Restart block. */
+ long *dbg_block; /* Debug block. */
+ long *gevect; /* XXX General vector??? */
+ long *utlbvect; /* XXX UTLB vector??? */
+ unsigned long rveclen; /* Size of romvec struct. */
+ struct linux_romvec *romvec; /* Function interface. */
+ unsigned long pveclen; /* Length of private vector. */
+ long *pvector; /* Private vector. */
+ long adap_cnt; /* Adapter count. */
+ long adap_typ0; /* First adapter type. */
+ long adap_vcnt0; /* Adapter 0 vector count. */
+ long *adap_vector; /* Adapter 0 vector ptr. */
+ long adap_typ1; /* Second adapter type. */
+ long adap_vcnt1; /* Adapter 1 vector count. */
+ long *adap_vector1; /* Adapter 1 vector ptr. */
+ /* More adapter vectors go here... */
+};
+
+#define PROMBLOCK ((struct linux_promblock *)0xA0001000UL)
+#define ROMVECTOR ((PROMBLOCK)->romvec)
+
+/* Cache layout parameter block. */
+union linux_cache_key {
+ struct param {
+#ifdef __MIPSEL__
+ unsigned short size;
+ unsigned char lsize;
+ unsigned char bsize;
+#else /* !(__MIPSEL__) */
+ unsigned char bsize;
+ unsigned char lsize;
+ unsigned short size;
+#endif
+ } info;
+ unsigned long allinfo;
+};
+
+/* Configuration data. */
+struct linux_cdata {
+ char *name;
+ int mlen;
+ enum linux_devtypes type;
+};
+
+/* Common SGI ARCS firmware file descriptors. */
+#define SGIPROM_STDIN 0
+#define SGIPROM_STDOUT 1
+
+/* Common SGI ARCS firmware file types. */
+#define SGIPROM_ROFILE 0x01 /* read-only file */
+#define SGIPROM_HFILE 0x02 /* hidden file */
+#define SGIPROM_SFILE 0x04 /* System file */
+#define SGIPROM_AFILE 0x08 /* Archive file */
+#define SGIPROM_DFILE 0x10 /* Directory file */
+#define SGIPROM_DELFILE 0x20 /* Deleted file */
+
+/* SGI ARCS boot record information. */
+struct sgi_partition {
+ unsigned char flag;
+#define SGIPART_UNUSED 0x00
+#define SGIPART_ACTIVE 0x80
+
+ unsigned char shead, ssect, scyl; /* unused */
+ unsigned char systype; /* OS type, Irix or NT */
+ unsigned char ehead, esect, ecyl; /* unused */
+ unsigned char rsect0, rsect1, rsect2, rsect3;
+ unsigned char tsect0, tsect1, tsect2, tsect3;
+};
+
+#define SGIBBLOCK_MAGIC 0xaa55
+#define SGIBBLOCK_MAXPART 0x0004
+
+struct sgi_bootblock {
+ unsigned char _unused[446];
+ struct sgi_partition partitions[SGIBBLOCK_MAXPART];
+ unsigned short magic;
+};
+
+/* BIOS parameter block. */
+struct sgi_bparm_block {
+ unsigned short bytes_sect; /* bytes per sector */
+ unsigned char sect_clust; /* sectors per cluster */
+ unsigned short sect_resv; /* reserved sectors */
+ unsigned char nfats; /* # of allocation tables */
+ unsigned short nroot_dirents; /* # of root directory entries */
+ unsigned short sect_volume; /* sectors in volume */
+ unsigned char media_type; /* media descriptor */
+ unsigned short sect_fat; /* sectors per allocation table */
+ unsigned short sect_track; /* sectors per track */
+ unsigned short nheads; /* # of heads */
+ unsigned short nhsects; /* # of hidden sectors */
+};
+
+struct sgi_bsector {
+ unsigned char jmpinfo[3];
+ unsigned char manuf_name[8];
+ struct sgi_bparm_block info;
+};
+
+/* Debugging block used with SGI symmon symbolic debugger. */
+#define SMB_DEBUG_MAGIC 0xfeeddead
+struct linux_smonblock {
+ unsigned long magic;
+ void (*handler)(void); /* Breakpoint routine. */
+ unsigned long dtable_base; /* Base addr of dbg table. */
+ int (*printf)(const char *fmt, ...);
+ unsigned long btable_base; /* Breakpoint table. */
+ unsigned long mpflushreqs; /* SMP cache flush request list. */
+ unsigned long ntab; /* Name table. */
+ unsigned long stab; /* Symbol table. */
+ int smax; /* Max # of symbols. */
+};
+
+#endif /* !(_MIPS_SGIARCS_H) */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/sgidefs.h linux/include/asm-mips/sgidefs.h
--- v2.1.43/linux/include/asm-mips/sgidefs.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/sgidefs.h Thu Jun 26 12:33:40 1997
@@ -0,0 +1,100 @@


+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.

+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ *
+ * Definitions commonly used in SGI style code.
+ */
+#ifndef __ASM_SGIDEFS_H
+#define __ASM_SGIDEFS_H
+
+/*
+ * There are compilers out there that don't define _MIPS_ISA, _MIPS_SIM,
+ * _MIPS_SZINT, _MIPS_SZLONG, _MIPS_SZPTR. So we notify the user about this
+ * problem. The kernel sources are aware of this problem, so we don't warn
+ * when compiling the kernel.
+ */
+#if !defined(_MIPS_ISA) && !defined(__KERNEL__)
+#warning "Macro _MIPS_ISA has not been defined by specs file"
+#endif
+
+#if !defined(_MIPS_SIM) && !defined(__KERNEL__)
+#warning "Macro _MIPS_SIM has not been defined by specs file"
+#endif
+
+#if !defined(_MIPS_SZINT) && !defined(__KERNEL__)
+#warning "Macro _MIPS_SZINT has not been defined by specs file"
+#endif
+
+#if !defined(_MIPS_SZLONG) && !defined(__KERNEL__)
+#warning "Macro _MIPS_SZLONG has not been defined by specs file"
+#endif
+
+#if !defined(_MIPS_SZPTR) && !defined(__KERNEL__)
+#warning "Macro _MIPS_SZPTR has not been defined by specs file"
+#endif
+
+#if (!defined(_MIPS_ISA) || \
+ !defined(_MIPS_SIM) || \
+ !defined(_MIPS_SZINT) || \
+ !defined(_MIPS_SZLONG) || \
+ !defined(_MIPS_SZPTR)) && !defined(__KERNEL__)
+#warning "Please update your GCC to GCC 2.7.2-4 or newer"
+#endif
+
+/*
+ * Now lets try our best to supply some reasonable default values for
+ * whatever defines GCC didn't supply. This cannot be done correct for
+ * all possible combinations of options, so be careful with your options
+ * to GCC. Best bet is to keep your fingers off the a.out GCC and use
+ * ELF GCC 2.7.2-3 where possible.
+ */
+#ifndef _MIPS_ISA
+#if __mips == 1
+#define _MIPS_ISA _MIPS_ISA_MIPS1
+/* It is impossible to handle the -mips2 case correct. */
+#elif __mips == 3
+#define _MIPS_ISA _MIPS_ISA_MIPS3
+#elif __mips == 4
+#define _MIPS_ISA _MIPS_ISA_MIPS4
+#else /* __mips must be 5 */
+#define _MIPS_ISA _MIPS_ISA_MIPS5
+#endif
+#endif
+#ifndef _MIPS_SIM
+#define _MIPS_SIM _MIPS_SIM_ABI32
+#endif
+#ifndef _MIPS_SZINT
+#define _MIPS_SZINT 32
+#endif
+#ifndef _MIPS_SZLONG
+#define _MIPS_SZLONG 32
+#endif
+#ifndef _MIPS_SZPTR
+#define _MIPS_SZPTR 32
+#endif
+
+/*
+ * Definitions for the ISA level
+ */
+#define _MIPS_ISA_MIPS1 1
+#define _MIPS_ISA_MIPS2 2
+#define _MIPS_ISA_MIPS3 3
+#define _MIPS_ISA_MIPS4 4
+#define _MIPS_ISA_MIPS5 5
+
+/*
+ * Subprogram calling convention
+ *
+ * At the moment only _MIPS_SIM_ABI32 is in use. This will change rsn.
+ * Until GCC 2.8.0 is released don't rely on this definitions because the
+ * 64bit code is essentially using the 32bit interface model just with
+ * 64bit registers.
+ */
+#define _MIPS_SIM_ABI32 1
+#define _MIPS_SIM_NABI32 2
+#define _MIPS_SIM_ABI64 3
+
+#endif /* __ASM_SGIDEFS_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/sgihpc.h linux/include/asm-mips/sgihpc.h
--- v2.1.43/linux/include/asm-mips/sgihpc.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/sgihpc.h Thu Jun 26 12:33:40 1997
@@ -0,0 +1,340 @@
+/* $Id: sgihpc.h,v 1.1 1997/06/06 09:40:02 ralf Exp $
+ * sgihpc.h: Various HPC I/O controller defines. The HPC is basically
+ * the approximate functional equivalent of the Sun SYSIO
+ * on SGI INDY machines.
+ *


+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */

+#ifndef _MIPS_SGIHPC_H
+#define _MIPS_SGIHPC_H
+
+#include <asm/page.h>
+
+extern int sgi_has_ioc2; /* to know if we have older ioc1 or ioc2. */
+extern int sgi_guiness; /* GUINESS or FULLHOUSE machine. */
+extern int sgi_boardid; /* Board revision. */
+
+/* An HPC dma descriptor. */
+struct hpc_dma_desc {
+ unsigned long pbuf; /* physical address of data buffer */
+ unsigned long cntinfo; /* counter and info bits */
+#define HPCDMA_EOX 0x80000000 /* last desc in chain for tx */
+#define HPCDMA_EOR 0x80000000 /* last desc in chain for rx */
+#define HPCDMA_EOXP 0x40000000 /* end of packet for tx */
+#define HPCDMA_EORP 0x40000000 /* end of packet for rx */
+#define HPCDMA_XIE 0x20000000 /* irq generated when at end of this desc */
+#define HPCDMA_XIU 0x01000000 /* Tx buffer in use by CPU. */
+#define HPCDMA_EIPC 0x00ff0000 /* SEEQ ethernet special xternal bytecount */
+#define HPCDMA_ETXD 0x00008000 /* set to one by HPC when packet tx'd */
+#define HPCDMA_OWN 0x00004000 /* Denotes ring buffer ownership on rx */
+#define HPCDMA_BCNT 0x00003fff /* size in bytes of this dma buffer */
+
+ unsigned long pnext; /* paddr of next hpc_dma_desc if any */
+};
+
+typedef volatile unsigned long hpcreg;
+
+/* HPC1 stuff. */
+
+/* HPC3 stuff. */
+
+/* The set of regs for each HPC3 pbus dma channel. */
+struct hpc3_pbus_dmacregs {
+ hpcreg pbdma_bptr; /* pbus dma channel buffer ptr */
+ hpcreg pbdma_dptr; /* pbus dma channel desc ptr */
+ char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
+ hpcreg pbdma_ctrl; /* pbus dma channel control reg */
+#define HPC3_PDMACTRL_SEL 0x00000002 /* little endian transfer */
+#define HPC3_PDMACTRL_RCV 0x00000004 /* direction is receive */
+#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */
+#define HPC3_PDMACTRL_ACT 0x00000010 /* start dma transfer */
+#define HPC3_PDMACTRL_LD 0x00000020 /* load enable for ACT */
+#define HPC3_PDMACTRL_RT 0x00000040 /* Use realtime GIO bus servicing */
+#define HPC3_PDMACTRL_HW 0x0000ff00 /* DMA High-water mark */
+#define HPC3_PDMACTRL_FB 0x003f0000 /* Ptr to beginning of fifo */
+#define HPC3_PDMACTRL_FE 0x3f000000 /* Ptr to end of fifo */
+
+ char _unused2[PAGE_SIZE - (sizeof(hpcreg))]; /* padding */
+};
+
+/* The HPC3 scsi registers, this does not include external ones. */
+struct hpc3_scsiregs {
+ hpcreg cbptr; /* current dma buffer ptr, diagnostic use only */
+ hpcreg ndptr; /* next dma descriptor ptr */
+ char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
+ hpcreg bcd; /* byte count info */
+#define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */
+#define HPC3_SBCD_XIE 0x00004000 /* Send IRQ when done with cur buf */
+#define HPC3_SBCD_EOX 0x00008000 /* Indicates this is last buf in chain */
+
+ hpcreg ctrl; /* control register */
+#define HPC3_SCTRL_IRQ 0x01 /* IRQ asserted, either dma done or parity */
+#define HPC3_SCTRL_ENDIAN 0x02 /* DMA endian mode, 0=big 1=little */
+#define HPC3_SCTRL_DIR 0x04 /* DMA direction, 1=dev2mem 0=mem2dev */
+#define HPC3_SCTRL_FLUSH 0x08 /* Tells HPC3 to flush scsi fifos */
+#define HPC3_SCTRL_ACTIVE 0x10 /* SCSI DMA channel is active */
+#define HPC3_SCTRL_AMASK 0x20 /* DMA active inhibits PIO */
+#define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */
+#define HPC3_SCTRL_PERR 0x80 /* Bad parity on HPC3 iface to scsi controller */
+
+ hpcreg gfptr; /* current GIO fifo ptr */
+ hpcreg dfptr; /* current device fifo ptr */
+ hpcreg dconfig; /* DMA configuration register */
+#define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */
+#define HPC3_SDCFG_D1 0x00006 /* Cycles to spend in D1 state */
+#define HPC3_SDCFG_D2 0x00038 /* Cycles to spend in D2 state */
+#define HPC3_SDCFG_D3 0x001c0 /* Cycles to spend in D3 state */
+#define HPC3_SDCFG_HWAT 0x00e00 /* DMA high water mark */
+#define HPC3_SDCFG_HW 0x01000 /* Enable 16-bit halfword DMA accesses to scsi */
+#define HPC3_SDCFG_SWAP 0x02000 /* Byte swap all DMA accesses */
+#define HPC3_SDCFG_EPAR 0x04000 /* Enable parity checking for DMA */
+#define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */
+#define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */
+
+ hpcreg pconfig; /* PIO configuration register */
+#define HPC3_SPCFG_P3 0x0003 /* Cycles to spend in P3 state */
+#define HPC3_SPCFG_P2W 0x001c /* Cycles to spend in P2 state for writes */
+#define HPC3_SPCFG_P2R 0x01e0 /* Cycles to spend in P2 state for reads */
+#define HPC3_SPCFG_P1 0x0e00 /* Cycles to spend in P1 state */
+#define HPC3_SPCFG_HW 0x1000 /* Enable 16-bit halfword PIO accesses to scsi */
+#define HPC3_SPCFG_SWAP 0x2000 /* Byte swap all PIO accesses */
+#define HPC3_SPCFG_EPAR 0x4000 /* Enable parity checking for PIO */
+#define HPC3_SPCFG_FUJI 0x8000 /* Fujitsu scsi controller mode for faster dma/pio */
+
+ char _unused2[PAGE_SIZE - (6 * sizeof(hpcreg))]; /* padding */
+};
+
+/* SEEQ ethernet HPC3 registers, only one seeq per HPC3. */
+struct hpc3_ethregs {
+ /* Receiver registers. */
+ hpcreg rx_cbptr; /* current dma buffer ptr, diagnostic use only */
+ hpcreg rx_ndptr; /* next dma descriptor ptr */
+ char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
+ hpcreg rx_bcd; /* byte count info */
+#define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */
+#define HPC3_ERXBCD_XIE 0x20000000 /* HPC3 interrupts cpu at end of this buf */
+#define HPC3_ERXBCD_EOX 0x80000000 /* flags this as end of descriptor chain */
+
+ hpcreg rx_ctrl; /* control register */
+#define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */
+#define HPC3_ERXCTRL_STAT6 0x00000040 /* Rdonly irq status */
+#define HPC3_ERXCTRL_STAT7 0x00000080 /* Rdonlt old/new status bit from Seeq */
+#define HPC3_ERXCTRL_ENDIAN 0x00000100 /* Endian for dma channel, little=1 big=0 */
+#define HPC3_ERXCTRL_ACTIVE 0x00000200 /* Tells if DMA transfer is in progress */
+#define HPC3_ERXCTRL_AMASK 0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */
+#define HPC3_ERXCTRL_RBO 0x00000800 /* Receive buffer overflow if set to 1 */
+
+ hpcreg rx_gfptr; /* current GIO fifo ptr */
+ hpcreg rx_dfptr; /* current device fifo ptr */
+ hpcreg _unused2; /* padding */
+ hpcreg rx_reset; /* reset register */
+#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */
+#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */
+#define HPC3_ERXRST_LBACK 0x4 /* Enable diagnostic loopback mode of Seeq8003 */
+
+ hpcreg rx_dconfig; /* DMA configuration register */
+#define HPC3_ERXDCFG_D1 0x0000f /* Cycles to spend in D1 state for PIO */
+#define HPC3_ERXDCFG_D2 0x000f0 /* Cycles to spend in D2 state for PIO */
+#define HPC3_ERXDCFG_D3 0x00f00 /* Cycles to spend in D3 state for PIO */
+#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
+#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
+#define HPC3_ERXDCFG_FEOP 0x04000 /* Bad packet marker timeout enable */
+#define HPC3_ERXDCFG_FIRQ 0x08000 /* Another bad packet timeout enable */
+#define HPC3_ERXDCFG_PTO 0x30000 /* Programmed timeout value for above two */
+
+ hpcreg rx_pconfig; /* PIO configuration register */
+#define HPC3_ERXPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */
+#define HPC3_ERXPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */
+#define HPC3_ERXPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */
+#define HPC3_ERXPCFG_TST 0x1000 /* Diagnistic ram test feature bit */
+
+ char _unused3[PAGE_SIZE - (8 * sizeof(hpcreg))]; /* padding */
+
+ /* Transmitter registers. */
+ hpcreg tx_cbptr; /* current dma buffer ptr, diagnostic use only */
+ hpcreg tx_ndptr; /* next dma descriptor ptr */
+ char _unused4[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */
+ hpcreg tx_bcd; /* byte count info */
+#define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */
+#define HPC3_ETXBCD_ESAMP 0x10000000 /* if set, too late to add descriptor */
+#define HPC3_ETXBCD_XIE 0x20000000 /* Interrupt cpu at end of cur desc */
+#define HPC3_ETXBCD_EOP 0x40000000 /* Last byte of cur buf is end of packet */
+#define HPC3_ETXBCD_EOX 0x80000000 /* This buf is the end of desc chain */
+
+ hpcreg tx_ctrl; /* control register */
+#define HPC3_ETXCTRL_STAT30 0x0000000f /* Rdonly copy of seeq tx stat reg */
+#define HPC3_ETXCTRL_STAT4 0x00000010 /* Indicate late collision occurred */
+#define HPC3_ETXCTRL_STAT75 0x000000e0 /* Rdonly irq status from seeq */
+#define HPC3_ETXCTRL_ENDIAN 0x00000100 /* Dma channel endian mode, 1=little 0=big */
+#define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */
+#define HPC3_ETXCTRL_AMASK 0x00000400 /* Indicates ACTIVE inhibits PIO's */
+
+ hpcreg tx_gfptr; /* current GIO fifo ptr */
+ hpcreg tx_dfptr; /* current device fifo ptr */
+ char _unused5[PAGE_SIZE - (4 * sizeof(hpcreg))]; /* padding */
+};
+
+struct hpc3_regs {
+ /* First regs for the PBUS 8 dma channels. */
+ struct hpc3_pbus_dmacregs pbdma0, pbdma1, pbdma2, pbdma3;
+ struct hpc3_pbus_dmacregs pbdma4, pbdma5, pbdma6, pbdma7;
+
+ /* Now the HPC scsi registers, we get two scsi reg sets. */
+ struct hpc3_scsiregs scsi_chan0, scsi_chan1;
+
+ /* The SEEQ hpc3 ethernet dma/control registers. */
+ struct hpc3_ethregs ethregs;
+
+ /* Here are where the hpc3 fifo's can be directly accessed
+ * via PIO accesses. Under normal operation we never stick
+ * our grubby paws in here so it's just padding.
+ */
+ char _unused1[PAGE_SIZE * 16];
+
+ /* HPC3 irq status regs. Due to a peculiar bug you need to
+ * look at two different register addresses to get at all of
+ * the status bits. The first reg can only reliably report
+ * bits 4:0 of the status, and the second reg can only
+ * reliably report bits 9:5 of the hpc3 irq status. I told
+ * you it was a peculiar bug. ;-)
+ */
+ hpcreg istat0; /* Irq status, only bits <4:0> reliable. */
+#define HPC3_ISTAT_PBIMASK 0x0ff /* irq bits for pbus devs 0 --> 7 */
+#define HPC3_ISTAT_SC0MASK 0x100 /* irq bit for scsi channel 0 */
+#define HPC3_ISTAT_SC1MASK 0x200 /* irq bit for scsi channel 1 */
+
+ hpcreg gio64_misc; /* GIO64 misc control bits. */
+#define HPC3_GIOMISC_ERTIME 0x1 /* Enable external timer real time. */
+#define HPC3_GIOMISC_DENDIAN 0x2 /* dma descriptor endian, 1=lit 0=big */
+
+ hpcreg eeprom_data; /* EEPROM data reg. */
+#define HPC3_EEPROM_EPROT 0x01 /* Protect register enable */
+#define HPC3_EEPROM_CSEL 0x02 /* Chip select */
+#define HPC3_EEPROM_ECLK 0x04 /* EEPROM clock */
+#define HPC3_EEPROM_DATO 0x08 /* Data out */
+#define HPC3_EEPROM_DATI 0x10 /* Data in */
+
+ hpcreg istat1; /* Irq status, only bits <9:5> reliable. */
+ hpcreg gio64_estat; /* GIO64 error interrupt status reg. */
+#define HPC3_GIOESTAT_BLMASK 0x000ff /* Bus lane where bad parity occurred */
+#define HPC3_GIOESTAT_CTYPE 0x00100 /* Bus cycle type, 0=PIO 1=DMA */
+#define HPC3_GIOESTAT_PIDMSK 0x3f700 /* DMA channel parity identifier */
+
+ /* Now direct PIO per-HPC3 peripheral access to external regs. */
+ char _unused2[0x13ff0]; /* Trust me... */
+ hpcreg scsi0_ext[256]; /* SCSI channel 0 external regs */
+ char _unused3[0x07c00]; /* Trust me... */
+ hpcreg scsi1_ext[256]; /* SCSI channel 1 external regs */
+ char _unused4[0x07c00]; /* It'll only hurt a little... */
+
+ /* Per-peripheral device external registers and dma/pio control. */
+ hpcreg pbus_extregs[256][10]; /* 2nd indice indexes controller */
+ hpcreg pbus_dmacfgs[128][10]; /* 2nd indice indexes controller */
+#define HPC3_PIODCFG_D3R 0x00000001 /* Cycles to spend in D3 for reads */
+#define HPC3_PIODCFG_D4R 0x0000001e /* Cycles to spend in D4 for reads */
+#define HPC3_PIODCFG_D5R 0x000001e0 /* Cycles to spend in D5 for reads */
+#define HPC3_PIODCFG_D3W 0x00000200 /* Cycles to spend in D3 for writes */
+#define HPC3_PIODCFG_D4W 0x00003c00 /* Cycles to spend in D4 for writes */
+#define HPC3_PIODCFG_D5W 0x0003c000 /* Cycles to spend in D5 for writes */
+#define HPC3_PIODCFG_HWORD 0x00040000 /* Enable 16-bit dma access mode */
+#define HPC3_PIODCFG_EHI 0x00080000 /* Places halfwords on high 16 bits of bus */
+#define HPC3_PIODCFG_RTIME 0x00200000 /* Make this device real time on GIO bus */
+#define HPC3_PIODCFG_BURST 0x07c00000 /* 5 bit burst count for DMA device */
+#define HPC3_PIODCFG_DRQLV 0x08000000 /* Use live pbus_dreq unsynchronized signal */
+
+ hpcreg pbus_piocfgs[64][10]; /* 2nd indice indexes controller */
+#define HPC3_PIOPCFG_RP2 0x00001 /* Cycles to spend in P2 state for reads */
+#define HPC3_PIOPCFG_RP3 0x0001e /* Cycles to spend in P3 state for reads */
+#define HPC3_PIOPCFG_RP4 0x001e0 /* Cycles to spend in P4 state for reads */
+#define HPC3_PIOPCFG_WP2 0x00200 /* Cycles to spend in P2 state for writes */
+#define HPC3_PIOPCFG_WP3 0x03c00 /* Cycles to spend in P3 state for writes */
+#define HPC3_PIOPCFG_WP4 0x3c000 /* Cycles to spend in P4 state for writes */
+#define HPC3_PIOPCFG_HW 0x40000 /* Enable 16-bit PIO accesses */
+#define HPC3_PIOPCFG_EHI 0x80000 /* Place even address bits in bits <15:8> */
+
+ /* PBUS PROM control regs. */
+ hpcreg pbus_promwe; /* PROM write enable register */
+#define HPC3_PROM_WENAB 0x1 /* Enable writes to the PROM */
+
+ char _unused5[0x800 - sizeof(hpcreg)];
+ hpcreg pbus_promswap; /* Chip select swap reg */
+#define HPC3_PROM_SWAP 0x1 /* invert GIO addr bit to select prom0 or prom1 */
+
+ char _unused6[0x800 - sizeof(hpcreg)];
+ hpcreg pbus_gout; /* PROM general purpose output reg */
+#define HPC3_PROM_STAT 0x1 /* General purpose status bit in gout */
+
+ char _unused7[0x1000 - sizeof(hpcreg)];
+ hpcreg pbus_promram[16384]; /* 64k of PROM battery backed ram */
+};
+
+/* It is possible to have two HPC3's within the address space on
+ * one machine, though only having one is more likely on an INDY.
+ * Controller 0 lives at physical address 0x1fb80000 and the controller
+ * 1 if present lives at address 0x1fb00000.
+ */
+extern struct hpc3_regs *hpc3c0, *hpc3c1;
+#define HPC3_CHIP0_PBASE 0x1fb80000 /* physical */
+#define HPC3_CHIP1_PBASE 0x1fb00000 /* physical */
+
+/* Control and misc status information, these live in pbus channel 6. */
+struct hpc3_miscregs {
+ hpcreg pdata, pctrl, pstat, pdmactrl, pistat, pimask;
+ hpcreg ptimer1, ptimer2, ptimer3, ptimer4;
+ hpcreg _unused1[2];
+ hpcreg ser1cmd, ser1data;
+ hpcreg ser0cmd, ser0data;
+ hpcreg kbdmouse0, kbdmouse1;
+ hpcreg gcsel, genctrl, panel;
+ hpcreg _unused2;
+ hpcreg sysid;
+ hpcreg _unused3;
+ hpcreg read, _unused4;
+ hpcreg dselect;
+#define HPC3_DSELECT_SCLK10MHZ 0x00 /* use 10MHZ serial clock */
+#define HPC3_DSELECT_ISDNB 0x01 /* enable isdn B */
+#define HPC3_DSELECT_ISDNA 0x02 /* enable isdn A */
+#define HPC3_DSELECT_LPR 0x04 /* use parallel DMA */
+#define HPC3_DSELECT_SCLK667MHZ 0x10 /* use 6.67MHZ serial clock */
+#define HPC3_DSELECT_SCLKEXT 0x20 /* use external serial clock */
+
+ hpcreg _unused5;
+ hpcreg write1;
+#define HPC3_WRITE1_PRESET 0x01 /* 0=LPR_RESET, 1=NORMAL */
+#define HPC3_WRITE1_KMRESET 0x02 /* 0=KBDMOUSE_RESET, 1=NORMAL */
+#define HPC3_WRITE1_ERESET 0x04 /* 0=EISA_RESET, 1=NORMAL */
+#define HPC3_WRITE1_GRESET 0x08 /* 0=MAGIC_GIO_RESET, 1=NORMAL */
+#define HPC3_WRITE1_LC0OFF 0x10 /* turn led off (guiness=red, else green) */
+#define HPC3_WRITE1_LC1OFF 0x20 /* turn led off (guiness=green, else amber) */
+
+ hpcreg _unused6;
+ hpcreg write2;
+#define HPC3_WRITE2_NTHRESH 0x01 /* use 4.5db threshhold */
+#define HPC3_WRITE2_TPSPEED 0x02 /* use 100ohm TP speed */
+#define HPC3_WRITE2_EPSEL 0x04 /* force cable mode: 1=AUI 0=TP */
+#define HPC3_WRITE2_EASEL 0x08 /* 1=autoselect 0=manual cable selection */
+#define HPC3_WRITE2_U1AMODE 0x10 /* 1=PC 0=MAC UART mode */
+#define HPC3_WRITE2_U0AMODE 0x20 /* 1=PC 0=MAC UART mode */
+#define HPC3_WRITE2_MLO 0x40 /* 1=4.75V 0=+5V */
+#define HPC3_WRITE2_MHI 0x80 /* 1=5.25V 0=+5V */
+};
+extern struct hpc3_miscregs *hpc3mregs;
+#define HPC3_MREGS_PBASE 0x1fbd9800 /* physical */
+
+struct hpc_keyb {
+#ifdef __MIPSEB__
+ unsigned char _unused0[3];
+ volatile unsigned char data;
+ unsigned char _unused1[3];
+ volatile unsigned char command;
+#else
+ volatile unsigned char data;
+ unsigned char _unused0[3];
+ volatile unsigned char command;
+ unsigned char _unused1[3];
+#endif
+};
+
+extern void sgihpc_init(void);
+
+#endif /* !(_MIPS_SGIHPC_H) */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/sgimc.h linux/include/asm-mips/sgimc.h
--- v2.1.43/linux/include/asm-mips/sgimc.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/sgimc.h Thu Jun 26 12:33:40 1997
@@ -0,0 +1,223 @@
+/* $Id: sgimc.h,v 1.1 1997/06/06 09:40:04 ralf Exp $
+ * sgimc.h: Definitions for memory controller hardware found on
+ * SGI IP20, IP22, IP26, and IP28 machines.
+ *


+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+

+#ifndef _MIPS_SGIMC_H
+#define _MIPS_SGIMC_H
+
+struct sgimc_misc_ctrl {
+ unsigned long _unused1;
+ volatile unsigned long cpuctrl0; /* CPU control register 0, readwrite */
+#define SGIMC_CCTRL0_REFS 0x0000000f /* REFS mask */
+#define SGIMC_CCTRL0_EREFRESH 0x00000010 /* Memory refresh enable */
+#define SGIMC_CCTRL0_EPERRGIO 0x00000020 /* GIO parity error enable */
+#define SGIMC_CCTRL0_EPERRMEM 0x00000040 /* Main mem parity error enable */
+#define SGIMC_CCTRL0_EPERRCPU 0x00000080 /* CPU bus parity error enable */
+#define SGIMC_CCTRL0_WDOG 0x00000100 /* Watchdog timer enable */
+#define SGIMC_CCTRL0_SYSINIT 0x00000200 /* System init bit */
+#define SGIMC_CCTRL0_GFXRESET 0x00000400 /* Graphics interface reset */
+#define SGIMC_CCTRL0_EISALOCK 0x00000800 /* Lock CPU from memory for EISA */
+#define SGIMC_CCTRL0_EPERRSCMD 0x00001000 /* SysCMD bus parity error enable */
+#define SGIMC_CCTRL0_IENAB 0x00002000 /* Allow interrupts from MC */
+#define SGIMC_CCTRL0_ESNOOP 0x00004000 /* Snooping I/O enable */
+#define SGIMC_CCTRL0_EPROMWR 0x00008000 /* Prom writes from cpu enable */
+#define SGIMC_CCTRL0_WRESETPMEM 0x00010000 /* Perform warm reset, preserves mem */
+#define SGIMC_CCTRL0_LENDIAN 0x00020000 /* Put MC in little-endian mode */
+#define SGIMC_CCTRL0_WRESETDMEM 0x00040000 /* Warm reset, destroys mem contents */
+#define SGIMC_CCTRL0_CMEMBADPAR 0x02000000 /* Generate bad perr from cpu to mem */
+#define SGIMC_CCTRL0_R4KNOCHKPARR 0x04000000 /* Don't chk parity on mem data reads */
+#define SGIMC_CCTRL0_GIOBTOB 0x08000000 /* Allow GIO back to back writes */
+
+ unsigned long _unused2;
+ volatile unsigned long cpuctrl1; /* CPU control register 1, readwrite */
+#define SGIMC_CCTRL1_EGIOTIMEO 0x00000010 /* GIO bus timeout enable */
+#define SGIMC_CCTRL1_FIXEDEHPC 0x00001000 /* Fixed HPC endianness */
+#define SGIMC_CCTRL1_LITTLEHPC 0x00002000 /* Little endian HPC */
+#define SGIMC_CCTRL1_FIXEDEEXP0 0x00004000 /* Fixed EXP0 endianness */
+#define SGIMC_CCTRL1_LITTLEEXP0 0x00008000 /* Little endian EXP0 */
+#define SGIMC_CCTRL1_FIXEDEEXP1 0x00010000 /* Fixed EXP1 endianness */
+#define SGIMC_CCTRL1_LITTLEEXP1 0x00020000 /* Little endian EXP1 */
+
+ unsigned long _unused3;
+ volatile unsigned long watchdogt; /* Watchdog reg rdonly, write clears */
+
+ unsigned long _unused4;
+ volatile unsigned long systemid; /* MC system ID register, readonly */
+#define SGIMC_SYSID_MASKREV 0x0000000f /* Revision of MC controller */
+#define SGIMC_SYSID_EPRESENT 0x00000010 /* Indicates presence of EISA bus */
+
+ unsigned long _unused5[3];
+ volatile unsigned long divider; /* Divider reg for RPSS */
+
+ unsigned long _unused6;
+ volatile unsigned char eeprom; /* EEPROM byte reg for r4k */
+#define SGIMC_EEPROM_PRE 0x00000001 /* eeprom chip PRE pin assertion */
+#define SGIMC_EEPROM_CSEL 0x00000002 /* Active high, eeprom chip select */
+#define SGIMC_EEPROM_SECLOCK 0x00000004 /* EEPROM serial clock */
+#define SGIMC_EEPROM_SDATAO 0x00000008 /* Serial EEPROM data-out */
+#define SGIMC_EEPROM_SDATAI 0x00000010 /* Serial EEPROM data-in */
+
+ unsigned char _unused7[3];
+ unsigned long _unused8[3];
+ volatile unsigned short rcntpre; /* Preload refresh counter */
+
+ unsigned short _unused9;
+ unsigned long _unused9a;
+ volatile unsigned short rcounter; /* Readonly refresh counter */
+
+ unsigned short _unused10;
+ unsigned long _unused11[13];
+ volatile unsigned long gioparm; /* Parameter word for GIO64 */
+#define SGIMC_GIOPARM_HPC64 0x00000001 /* HPC talks to GIO using 64-bits */
+#define SGIMC_GIOPARM_GFX64 0x00000002 /* GFX talks to GIO using 64-bits */
+#define SGIMC_GIOPARM_EXP064 0x00000004 /* EXP(slot0) talks using 64-bits */
+#define SGIMC_GIOPARM_EXP164 0x00000008 /* EXP(slot1) talks using 64-bits */
+#define SGIMC_GIOPARM_EISA64 0x00000010 /* EISA bus talks 64-bits to GIO */
+#define SGIMC_GIOPARM_HPC264 0x00000020 /* 2nd HPX talks 64-bits to GIO */
+#define SGIMC_GIOPARM_RTIMEGFX 0x00000040 /* GFX device has realtime attr */
+#define SGIMC_GIOPARM_RTIMEEXP0 0x00000080 /* EXP(slot0) has realtime attr */
+#define SGIMC_GIOPARM_RTIMEEXP1 0x00000100 /* EXP(slot1) has realtime attr */
+#define SGIMC_GIOPARM_MASTEREISA 0x00000200 /* EISA bus can act as bus master */
+#define SGIMC_GIOPARM_ONEBUS 0x00000400 /* Exists one GIO64 pipelined bus */
+#define SGIMC_GIOPARM_MASTERGFX 0x00000800 /* GFX can act as a bus master */
+#define SGIMC_GIOPARM_MASTEREXP0 0x00001000 /* EXP(slot0) can bus master */
+#define SGIMC_GIOPARM_MASTEREXP1 0x00002000 /* EXP(slot1) can bus master */
+#define SGIMC_GIOPARM_PLINEEXP0 0x00004000 /* EXP(slot0) has pipeline attr */
+#define SGIMC_GIOPARM_PLINEEXP1 0x00008000 /* EXP(slot1) has pipeline attr */
+
+ unsigned long _unused13;
+ volatile unsigned short cputp; /* CPU bus arb time period */
+
+ unsigned short _unused14;
+ unsigned long _unused15[3];
+ volatile unsigned short lbursttp; /* Time period for long bursts */
+
+ unsigned short _unused16;
+ unsigned long _unused17[9];
+ volatile unsigned long mconfig0; /* Memory config register zero */
+ unsigned long _unused18;
+ volatile unsigned long mconfig1; /* Memory config register one */
+
+ /* These defines apply to both mconfig registers above. */
+#define SGIMC_MCONFIG_FOURMB 0x00000000 /* Physical ram = 4megs */
+#define SGIMC_MCONFIG_EIGHTMB 0x00000100 /* Physical ram = 8megs */
+#define SGIMC_MCONFIG_SXTEENMB 0x00000300 /* Physical ram = 16megs */
+#define SGIMC_MCONFIG_TTWOMB 0x00000700 /* Physical ram = 32megs */
+#define SGIMC_MCONFIG_SFOURMB 0x00000f00 /* Physical ram = 64megs */
+#define SGIMC_MCONFIG_OTEIGHTMB 0x00001f00 /* Physical ram = 128megs */
+#define SGIMC_MCONFIG_RMASK 0x00001f00 /* Ram config bitmask */
+
+ unsigned long _unused19;
+ volatile unsigned long cmacc; /* Mem access config for CPU */
+ unsigned long _unused20;
+ volatile unsigned long gmacc; /* Mem access config for GIO */
+
+ /* This define applies to both cmacc and gmacc registers above. */
+#define SGIMC_MACC_ALIASBIG 0x20000000 /* 512MB home for alias */
+
+ /* Error address/status regs from GIO and CPU perspectives. */
+ unsigned long _unused21;
+ volatile unsigned long cerr; /* Error address reg for CPU */
+ unsigned long _unused22;
+ volatile unsigned long cstat; /* Status reg for CPU */
+ unsigned long _unused23;
+ volatile unsigned long gerr; /* Error address reg for GIO */
+ unsigned long _unused24;
+ volatile unsigned long gstat; /* Status reg for GIO */
+
+ /* Special hard bus locking registers. */
+ unsigned long _unused25;
+ volatile unsigned char syssembit; /* Uni-bit system semaphore */
+ unsigned char _unused26[3];
+ unsigned long _unused27;
+ volatile unsigned char mlock; /* Global GIO memory access lock */
+ unsigned char _unused28[3];
+ unsigned long _unused29;
+ volatile unsigned char elock; /* Locks EISA from GIO accesses */
+
+ /* GIO dma control registers. */
+ unsigned char _unused30[3];
+ unsigned long _unused31[14];
+ volatile unsigned long gio_dma_trans;/* DMA mask to translation GIO addrs */
+ unsigned long _unused32;
+ volatile unsigned long gio_dma_sbits;/* DMA GIO addr substitution bits */
+ unsigned long _unused33;
+ volatile unsigned long dma_intr_cause; /* DMA IRQ cause indicator bits */
+ unsigned long _unused34;
+ volatile unsigned long dma_ctrl; /* Main DMA control reg */
+
+ /* DMA TLB entry 0 */
+ unsigned long _unused35;
+ volatile unsigned long dtlb_hi0;
+ unsigned long _unused36;
+ volatile unsigned long dtlb_lo0;
+
+ /* DMA TLB entry 1 */
+ unsigned long _unused37;
+ volatile unsigned long dtlb_hi1;
+ unsigned long _unused38;
+ volatile unsigned long dtlb_lo1;
+
+ /* DMA TLB entry 2 */
+ unsigned long _unused39;
+ volatile unsigned long dtlb_hi2;
+ unsigned long _unused40;
+ volatile unsigned long dtlb_lo2;
+
+ /* DMA TLB entry 3 */
+ unsigned long _unused41;
+ volatile unsigned long dtlb_hi3;
+ unsigned long _unused42;
+ volatile unsigned long dtlb_lo3;
+};
+
+/* MC misc control registers live at physical 0x1fa00000. */
+extern struct sgimc_misc_ctrl *mcmisc_regs;
+extern unsigned long *rpsscounter; /* Chirps at 100ns */
+
+struct sgimc_dma_ctrl {
+ unsigned long _unused1;
+ volatile unsigned long maddronly; /* Address DMA goes at */
+ unsigned long _unused2;
+ volatile unsigned long maddrpdeflts; /* Same as above, plus set defaults */
+ unsigned long _unused3;
+ volatile unsigned long dmasz; /* DMA count */
+ unsigned long _unused4;
+ volatile unsigned long ssize; /* DMA stride size */
+ unsigned long _unused5;
+ volatile unsigned long gmaddronly; /* Set GIO DMA but do not start trans */
+ unsigned long _unused6;
+ volatile unsigned long dmaddnpgo; /* Set GIO DMA addr + start transfer */
+ unsigned long _unused7;
+ volatile unsigned long dmamode; /* DMA mode config bit settings */
+ unsigned long _unused8;
+ volatile unsigned long dmacount; /* Zoom and byte count for DMA */
+ unsigned long _unused9;
+ volatile unsigned long dmastart; /* Pedal to the metal. */
+ unsigned long _unused10;
+ volatile unsigned long dmarunning; /* DMA op is in progress */
+ unsigned long _unused11;
+
+ /* Set dma addr, defaults, and kick it */
+ volatile unsigned long maddr_defl_go; /* go go go! -lm */
+};
+
+/* MC controller dma regs live at physical 0x1fa02000. */
+extern struct sgimc_dma_ctrl *dmactrlregs;
+
+/* Base location of the two ram banks found in IP2[0268] machines. */
+#define SGIMC_SEG0_BADDR 0x08000000
+#define SGIMC_SEG1_BADDR 0x20000000
+
+/* Maximum size of the above banks are per machine. */
+extern unsigned long sgimc_seg0_size, sgimc_seg1_size;
+#define SGIMC_SEG0_SIZE_ALL 0x10000000 /* 256MB */
+#define SGIMC_SEG1_SIZE_IP20_IP22 0x08000000 /* 128MB */
+#define SGIMC_SEG1_SIZE_IP26_IP28 0x20000000 /* 512MB */
+
+extern void sgimc_init(void);
+
+#endif /* !(_MIPS_SGIMC_H) */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/sgint23.h linux/include/asm-mips/sgint23.h
--- v2.1.43/linux/include/asm-mips/sgint23.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/sgint23.h Thu Jun 26 12:33:40 1997
@@ -0,0 +1,179 @@
+/* $Id: sgint23.h,v 1.1 1997/06/06 09:40:06 ralf Exp $
+ * sgint23.h: Defines for the SGI INT2 and INT3 chipsets.
+ *


+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */

+#ifndef _MIPS_SGINT23_H
+#define _MIPS_SGINT23_H
+
+/* These are the virtual IRQ numbers, we divide all IRQ's into
+ * 'spaces', the 'space' determines where and how to enable/disable
+ * that particular IRQ on an SGI machine. Add new 'spaces' as new
+ * IRQ hardware is supported.
+ */
+#define SGINT_LOCAL0 0 /* INDY has 8 local0 irq levels */
+#define SGINT_LOCAL1 8 /* INDY has 8 local1 irq levels */
+#define SGINT_LOCAL2 16 /* INDY has 8 local2 vectored irq levels */
+#define SGINT_LOCAL3 24 /* INDY has 8 local3 vectored irq levels */
+#define SGINT_GIO 32 /* INDY has 9 GIO irq levels */
+#define SGINT_HPCDMA 41 /* INDY has 11 HPCDMA irq _sources_ */
+#define SGINT_END 52 /* End of 'spaces' */
+
+/* INT2 occupies HPC PBUS slot 4, INT3 uses slot 6. */
+#define SGI_INT2_BASE 0x1fb80100 /* physical */
+#define SGI_INT3_BASE 0x1fbd9880 /* physical */
+
+struct sgi_ioc_ints {
+#ifdef __MIPSEB__
+ unsigned char _unused0[3];
+ volatile unsigned char istat0; /* Interrupt status zero */
+#else
+ volatile unsigned char istat0; /* Interrupt status zero */
+ unsigned char _unused0[3];
+#endif
+#define ISTAT0_FFULL 0x01
+#define ISTAT0_SCSI0 0x02
+#define ISTAT0_SCSI1 0x04
+#define ISTAT0_ENET 0x08
+#define ISTAT0_GFXDMA 0x10
+#define ISTAT0_LPR 0x20
+#define ISTAT0_HPC2 0x40
+#define ISTAT0_LIO2 0x80
+
+#ifdef __MIPSEB__
+ unsigned char _unused1[3];
+ volatile unsigned char imask0; /* Interrupt mask zero */
+ unsigned char _unused2[3];
+ volatile unsigned char istat1; /* Interrupt status one */
+#else
+ volatile unsigned char imask0; /* Interrupt mask zero */
+ unsigned char _unused1[3];
+ volatile unsigned char istat1; /* Interrupt status one */
+ unsigned char _unused2[3];
+#endif
+#define ISTAT1_ISDNI 0x01
+#define ISTAT1_PWR 0x02
+#define ISTAT1_ISDNH 0x04
+#define ISTAT1_LIO3 0x08
+#define ISTAT1_HPC3 0x10
+#define ISTAT1_AFAIL 0x20
+#define ISTAT1_VIDEO 0x40
+#define ISTAT1_GIO2 0x80
+
+#ifdef __MIPSEB__
+ unsigned char _unused3[3];
+ volatile unsigned char imask1; /* Interrupt mask one */
+ unsigned char _unused4[3];
+ volatile unsigned char vmeistat; /* VME interrupt status */
+ unsigned char _unused5[3];
+ volatile unsigned char cmeimask0; /* VME interrupt mask zero */
+ unsigned char _unused6[3];
+ volatile unsigned char cmeimask1; /* VME interrupt mask one */
+ unsigned char _unused7[3];
+ volatile unsigned char cmepol; /* VME polarity */
+#else
+ volatile unsigned char imask1; /* Interrupt mask one */
+ unsigned char _unused3[3];
+ volatile unsigned char vmeistat; /* VME interrupt status */
+ unsigned char _unused4[3];
+ volatile unsigned char cmeimask0; /* VME interrupt mask zero */
+ unsigned char _unused5[3];
+ volatile unsigned char cmeimask1; /* VME interrupt mask one */
+ unsigned char _unused6[3];
+ volatile unsigned char cmepol; /* VME polarity */
+ unsigned char _unused7[3];
+#endif
+};
+
+struct sgi_ioc_timers {
+#ifdef __MIPSEB__
+ unsigned char _unused0[3];
+ volatile unsigned char tcnt0; /* counter 0 */
+ unsigned char _unused1[3];
+ volatile unsigned char tcnt1; /* counter 1 */
+ unsigned char _unused2[3];
+ volatile unsigned char tcnt2; /* counter 2 */
+ unsigned char _unused3[3];
+ volatile unsigned char tcword; /* control word */
+#else
+ volatile unsigned char tcnt0; /* counter 0 */
+ unsigned char _unused0[3];
+ volatile unsigned char tcnt1; /* counter 1 */
+ unsigned char _unused1[3];
+ volatile unsigned char tcnt2; /* counter 2 */
+ unsigned char _unused2[3];
+ volatile unsigned char tcword; /* control word */
+ unsigned char _unused3[3];
+#endif
+};
+
+/* Timer control word bits. */
+#define SGINT_TCWORD_BCD 0x01 /* Use BCD mode for counters */
+#define SGINT_TCWORD_MMASK 0x0e /* Mode bitmask. */
+#define SGINT_TCWORD_MITC 0x00 /* IRQ on terminal count (doesn't work) */
+#define SGINT_TCWORD_MOS 0x02 /* One-shot IRQ mode. */
+#define SGINT_TCWORD_MRGEN 0x04 /* Normal rate generation */
+#define SGINT_TCWORD_MSWGEN 0x06 /* Square wave generator mode */
+#define SGINT_TCWORD_MSWST 0x08 /* Software strobe */
+#define SGINT_TCWORD_MHWST 0x0a /* Hardware strobe */
+#define SGINT_TCWORD_CMASK 0x30 /* Command mask */
+#define SGINT_TCWORD_CLAT 0x00 /* Latch command */
+#define SGINT_TCWORD_CLSB 0x10 /* LSB read/write */
+#define SGINT_TCWORD_CMSB 0x20 /* MSB read/write */
+#define SGINT_TCWORD_CALL 0x30 /* Full counter read/write */
+#define SGINT_TCWORD_CNT0 0x00 /* Select counter zero */
+#define SGINT_TCWORD_CNT1 0x40 /* Select counter one */
+#define SGINT_TCWORD_CNT2 0x80 /* Select counter two */
+#define SGINT_TCWORD_CRBCK 0xc0 /* Readback command */
+
+#define SGINT_TCSAMP_COUNTER 0x164
+
+struct sgi_int2_regs {
+ struct sgi_ioc_ints ints;
+
+ volatile unsigned long ledbits; /* LED control bits */
+#define INT2_LED_TXCLK 0x01 /* GPI to TXCLK enable */
+#define INT2_LED_SERSLCT0 0x02 /* serial port0: 0=apple 1=pc */
+#define INT2_LED_SERSLCT1 0x04 /* serial port1: 0=apple 1=pc */
+#define INT2_LED_CHEAPER 0x08 /* 0=cheapernet 1=ethernet */
+#define INT2_LED_POWEROFF 0x10 /* Power-off request, active high */
+
+#ifdef __MIPSEB__
+ unsigned char _unused0[3];
+ volatile unsigned char tclear; /* Timer clear strobe address */
+#else
+ volatile unsigned char tclear; /* Timer clear strobe address */
+ unsigned char _unused0[3];
+#endif
+#define INT2_TCLEAR_T0CLR 0x1 /* Clear timer0 IRQ */
+#define INT2_TCLEAR_T1CLR 0x2 /* Clear timer1 IRQ */
+
+ unsigned long _unused[3];
+ struct sgi_ioc_timers timers;
+};
+
+struct sgi_int3_regs {
+ struct sgi_ioc_ints ints;
+
+#ifdef __MIPSEB__
+ unsigned char _unused0[3];
+ volatile unsigned char tclear; /* Timer clear strobe address */
+#else
+ volatile unsigned char tclear; /* Timer clear strobe address */
+ unsigned char _unused0[3];
+#endif
+ volatile unsigned long estatus; /* Error status reg */
+ unsigned long _unused1[2];
+ struct sgi_ioc_timers timers;
+};
+
+extern struct sgi_int2_regs *sgi_i2regs;
+extern struct sgi_int3_regs *sgi_i3regs;
+extern struct sgi_ioc_ints *ioc_icontrol;
+extern struct sgi_ioc_timers *ioc_timers;
+extern volatile unsigned char *ioc_tclear;
+
+extern void sgint_init(void);
+extern void indy_timer_init(void);
+
+#endif /* !(_MIPS_SGINT23_H) */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/shmparam.h linux/include/asm-mips/shmparam.h
--- v2.1.43/linux/include/asm-mips/shmparam.h Mon May 6 02:26:15 1996
+++ linux/include/asm-mips/shmparam.h Thu Jun 26 12:33:40 1997
@@ -39,7 +39,7 @@
X #define SHMALL /* max shm system wide (pages) */ \
X (1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
X /*
- * This constant is very large but the ABI in its wisdom says ...
+ * This constant is very large but the ABI in it's wisdom says ...
X */
X #define SHMLBA 0x40000 /* attach addr a multiple of this */
X #define SHMSEG SHMMNI /* max shared segs per process */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/sigcontext.h linux/include/asm-mips/sigcontext.h
--- v2.1.43/linux/include/asm-mips/sigcontext.h Wed Dec 13 02:39:46 1995
+++ linux/include/asm-mips/sigcontext.h Mon Jul 7 08:18:55 1997
@@ -1,21 +1,39 @@
+/*
+ * include/asm-mips/uaccess.h
+ *


+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.

+ *
+ * Copyright (C) 1996, 1997 by Ralf Baechle
+ *
+ * $Id: sigcontext.h,v 1.3 1997/06/25 16:57:31 ralf Exp $
+ */
X #ifndef __ASM_MIPS_SIGCONTEXT_H
X #define __ASM_MIPS_SIGCONTEXT_H
X
X /*
- * This struct isn't in the ABI, so we continue to use the old
- * pre 1.3 definition. Needs to be changed for 64 bit kernels,
- * but it's 4am ...
+ * Keep this struct definition in sync with the sigcontext fragment
+ * in arch/mips/tools/offset.c
X */
-struct sigcontext_struct {
- unsigned long sc_at, sc_v0, sc_v1, sc_a0, sc_a1, sc_a2, sc_a3;
- unsigned long sc_t0, sc_t1, sc_t2, sc_t3, sc_t4, sc_t5, sc_t6, sc_t7;
- unsigned long sc_s0, sc_s1, sc_s2, sc_s3, sc_s4, sc_s5, sc_s6, sc_s7;
- unsigned long sc_t8, sc_t9, sc_gp, sc_sp, sc_fp, sc_ra;
+struct sigcontext {
+ unsigned int sc_regmask; /* Unused */
+ unsigned int sc_status;
+ unsigned long long sc_pc;
+ unsigned long long sc_regs[32];
+ unsigned long long sc_fpregs[32]; /* Unused */
+ unsigned int sc_ownedfp;
+ unsigned int sc_fpc_csr; /* Unused */
+ unsigned int sc_fpc_eir; /* Unused */
+ unsigned int sc_ssflags; /* Unused */
+ unsigned long long sc_mdhi;
+ unsigned long long sc_mdlo;
X
- unsigned long sc_epc;
- unsigned long sc_cause;
+ unsigned int sc_cause; /* Unused */
+ unsigned int sc_badvaddr; /* Unused */
X
- unsigned long sc_oldmask;
+ sigset_t sc_sigset;
+ unsigned long __pad0[3]; /* pad for constant size */
X };
X
X #endif /* __ASM_MIPS_SIGCONTEXT_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/signal.h linux/include/asm-mips/signal.h
--- v2.1.43/linux/include/asm-mips/signal.h Thu Apr 11 23:49:44 1996
+++ linux/include/asm-mips/signal.h Thu Jun 26 12:33:40 1997
@@ -1,26 +1,41 @@
-#ifndef __ASM_MIPS_SIGNAL_H
-#define __ASM_MIPS_SIGNAL_H
-
X /*
- * For now ...
+ * Linux/MIPS specific definitions for signals.
+ *


+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.

+ *
+ * Copyright (C) 1995, 1996 by Ralf Baechle
X */
-#include <linux/types.h>
-typedef __u64 sigset_t;
+#ifndef __ASM_MIPS_SIGNAL_H
X
-#if 0
-/*
- * This is what we should really use but the kernel can't handle
- * a non-scalar type yet. Since we use 64 signals only anyway we
- * just use __u64 and pad another 64 bits in the kernel for now ...
- */
-typedef struct {
- unsigned int sigbits[4];
-} sigset_t;
+#include <asm/sgidefs.h>
+
+/* Any one of these symbols __need_* means that GNU libc
+ wants us just to define one data type. So don't define
+ the symbols that indicate this file's entire job has been done. */
+#if !defined(__need_signums) && !defined(__need_fake_sigfuns) && \
+ !defined(__need__nsig)
+#define __ASM_MIPS_SIGNAL_H
X #endif
X
+#ifdef __ASM_MIPS_SIGNAL_H
+typedef unsigned long sigset_t;


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 38'
echo 'File patch-2.1.44 is continued in part 39'
echo 39 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part47

#!/bin/sh
# this is part 47 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 47; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

- case ROSE_STATE_3: /* HB */
- if (sk->protinfo.rose->condition & ROSE_COND_ACK_PENDING) {
- sk->protinfo.rose->condition &= ~ROSE_COND_ACK_PENDING;
- rose_enquiry_response(sk);
- }
- break;
X
X case ROSE_STATE_1: /* T1 */
X case ROSE_STATE_4: /* T2 */
X rose_write_internal(sk, ROSE_CLEAR_REQUEST);
X sk->protinfo.rose->state = ROSE_STATE_2;
- sk->protinfo.rose->timer = sk->protinfo.rose->t3;
+ rose_start_t3timer(sk);
X break;
X
X case ROSE_STATE_2: /* T3 */
- rose_clear_queues(sk);
- sk->protinfo.rose->state = ROSE_STATE_0;
- sk->state = TCP_CLOSE;
- sk->err = ETIMEDOUT;
- sk->shutdown |= SEND_SHUTDOWN;
- if (!sk->dead)
- sk->state_change(sk);
- sk->dead = 1;
+ sk->protinfo.rose->neighbour->use--;
+ rose_disconnect(sk, ETIMEDOUT, -1, -1);
+ break;
+
+ case ROSE_STATE_3: /* HB */
+ if (sk->protinfo.rose->condition & ROSE_COND_ACK_PENDING) {
+ sk->protinfo.rose->condition &= ~ROSE_COND_ACK_PENDING;
+ rose_enquiry_response(sk);
+ }


X break;
X }
+}
+

+static void rose_idletimer_expiry(unsigned long param)
+{
+ struct sock *sk = (struct sock *)param;
+
+ rose_clear_queues(sk);
+
+ rose_write_internal(sk, ROSE_CLEAR_REQUEST);
+ sk->protinfo.rose->state = ROSE_STATE_2;
+
+ rose_start_t3timer(sk);
+
+ sk->state = TCP_CLOSE;
+ sk->err = 0;
+ sk->shutdown |= SEND_SHUTDOWN;
+
+ if (!sk->dead)
+ sk->state_change(sk);
X
- rose_set_timer(sk);
+ sk->dead = 1;
X }
X
X #endif
diff -u --recursive --new-file v2.1.43/linux/net/rose/sysctl_net_rose.c linux/net/rose/sysctl_net_rose.c
--- v2.1.43/linux/net/rose/sysctl_net_rose.c Thu May 29 21:53:12 1997
+++ linux/net/rose/sysctl_net_rose.c Mon Jul 7 08:20:00 1997
@@ -11,13 +11,13 @@
X #include <net/ax25.h>
X #include <net/rose.h>
X
-static int min_timer[] = {1 * ROSE_SLOWHZ};
-static int max_timer[] = {300 * ROSE_SLOWHZ};
-static int min_idle[] = {0 * ROSE_SLOWHZ};
-static int max_idle[] = {65535 * ROSE_SLOWHZ};
+static int min_timer[] = {1 * HZ};
+static int max_timer[] = {300 * HZ};
+static int min_idle[] = {0 * HZ};
+static int max_idle[] = {65535 * HZ};
X static int min_route[] = {0}, max_route[] = {1};
-static int min_ftimer[] = {60 * ROSE_SLOWHZ};
-static int max_ftimer[] = {600 * ROSE_SLOWHZ};
+static int min_ftimer[] = {60 * HZ};
+static int max_ftimer[] = {600 * HZ};
X static int min_maxvcs[] = {1}, max_maxvcs[] = {254};


X static int min_window[] = {1}, max_window[] = {7};
X

diff -u --recursive --new-file v2.1.43/linux/net/socket.c linux/net/socket.c
--- v2.1.43/linux/net/socket.c Mon Jun 16 16:36:02 1997
+++ linux/net/socket.c Mon Jul 7 10:11:49 1997
@@ -67,6 +67,7 @@
X #include <linux/socket.h>
X #include <linux/fcntl.h>
X #include <linux/file.h>
+#include <linux/dalloc.h>
X #include <linux/net.h>
X #include <linux/interrupt.h>
X #include <linux/netdevice.h>
@@ -266,6 +267,7 @@
X inode = get_empty_inode();
X if (!inode)
X return NULL;
+
X sock = socki_lookup(inode);
X
X inode->i_mode = S_IFSOCK;
diff -u --recursive --new-file v2.1.43/linux/net/unix/af_unix.c linux/net/unix/af_unix.c
--- v2.1.43/linux/net/unix/af_unix.c Mon Jun 16 16:36:02 1997
+++ linux/net/unix/af_unix.c Mon Jul 7 08:20:00 1997
@@ -450,7 +450,7 @@
X static unix_socket *unix_find_other(struct sockaddr_un *sunname, int len,
X int type, unsigned hash, int *error)
X {
- int old_fs;
+ unsigned long old_fs;
X int err;
X struct inode *inode;
X unix_socket *u;
diff -u --recursive --new-file v2.1.43/linux/net/unix/sysctl_net_unix.c linux/net/unix/sysctl_net_unix.c
--- v2.1.43/linux/net/unix/sysctl_net_unix.c Mon Jun 16 16:36:02 1997
+++ linux/net/unix/sysctl_net_unix.c Mon Jul 7 08:20:00 1997
@@ -13,6 +13,9 @@


X
X #include <linux/mm.h>
X #include <linux/sysctl.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_SYSCTL
X

X extern int sysctl_unix_destroy_delay;
X extern int sysctl_unix_delete_delay;
@@ -26,3 +29,4 @@


X &proc_dointvec_jiffies},
X {0}
X };
+#endif

diff -u --recursive --new-file v2.1.43/linux/net/x25/af_x25.c linux/net/x25/af_x25.c
--- v2.1.43/linux/net/x25/af_x25.c Mon Jun 16 16:36:02 1997
+++ linux/net/x25/af_x25.c Mon Jul 7 08:20:00 1997


@@ -1,5 +1,5 @@
X /*

- * X.25 Packet Layer release 001
+ * X.25 Packet Layer release 002
X *
X * This is ALPHA test software. This code may break your machine, randomly fail to work with new
X * releases, misbehave and/or generally screw up. It might even work.
@@ -14,6 +14,8 @@


X *
X * History

X * X.25 001 Jonathan Naylor Started coding.
+ * X.25 002 Jonathan Naylor Centralised disconnect handling.
+ * New timer architecture.


X */
X
X #include <linux/config.h>

@@ -54,8 +56,6 @@
X int sysctl_x25_clear_request_timeout = X25_DEFAULT_T23;
X int sysctl_x25_ack_holdback_timeout = X25_DEFAULT_T2;
X
-static unsigned int lci = 1;
-
X static struct sock *volatile x25_list = NULL;
X
X static struct proto_ops x25_proto_ops;
@@ -173,16 +173,9 @@
X {
X struct sock *s;
X
- for (s = x25_list; s != NULL; s = s->next) {
- if (s->protinfo.x25->neighbour->dev == dev) {
- s->protinfo.x25->state = X25_STATE_0;
- s->state = TCP_CLOSE;
- s->err = ENETUNREACH;
- s->shutdown |= SEND_SHUTDOWN;
- s->state_change(s);
- s->dead = 1;
- }
- }
+ for (s = x25_list; s != NULL; s = s->next)
+ if (s->protinfo.x25->neighbour->dev == dev)
+ x25_disconnect(s, ENETUNREACH, 0, 0);
X }
X
X /*
@@ -254,9 +247,9 @@
X }
X
X /*
- * Find a connected X.25 socket given my LCI.
+ * Find a connected X.25 socket given my LCI and neighbour.
X */
-struct sock *x25_find_socket(unsigned int lci)
+struct sock *x25_find_socket(unsigned int lci, struct x25_neigh *neigh)
X {
X struct sock *s;
X unsigned long flags;
@@ -265,7 +258,7 @@
X cli();
X
X for (s = x25_list; s != NULL; s = s->next) {
- if (s->protinfo.x25->lci == lci) {
+ if (s->protinfo.x25->lci == lci && s->protinfo.x25->neighbour == neigh) {
X restore_flags(flags);
X return s;
X }
@@ -278,14 +271,13 @@
X /*
X * Find a unique LCI for a given device.
X */
-unsigned int x25_new_lci(void)
+unsigned int x25_new_lci(struct x25_neigh *neigh)
X {
- lci++;
- if (lci > 4095) lci = 1;
+ unsigned int lci = 1;
X
- while (x25_find_socket(lci) != NULL) {
+ while (x25_find_socket(lci, neigh) != NULL) {
X lci++;
- if (lci > 4095) lci = 1;
+ if (lci == 4096) return 0;
X }
X
X return lci;
@@ -318,7 +310,8 @@
X save_flags(flags);
X cli();
X
- del_timer(&sk->timer);
+ x25_stop_heartbeat(sk);
+ x25_stop_timer(sk);
X
X x25_remove_socket(sk);
X x25_clear_queues(sk); /* Flush the queues */
@@ -326,7 +319,7 @@
X while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) {
X if (skb->sk != sk) { /* A pending connection */
X skb->sk->dead = 1; /* Queue the unaccepted socket for death */
- x25_set_timer(skb->sk);
+ x25_start_heartbeat(skb->sk);
X skb->sk->protinfo.x25->state = X25_STATE_0;
X }
X
@@ -469,6 +462,8 @@
X
X sock_init_data(sock, sk);
X
+ init_timer(&x25->timer);
+
X sock->ops = &x25_proto_ops;
X sk->protocol = protocol;
X sk->mtu = X25_DEFAULT_PACKET_SIZE; /* X25_PS128 */
@@ -523,6 +518,8 @@
X
X x25->qbitincl = osk->protinfo.x25->qbitincl;
X
+ init_timer(&x25->timer);
+
X return sk;
X }
X
@@ -545,28 +542,17 @@
X switch (sk->protinfo.x25->state) {
X
X case X25_STATE_0:
- sk->state = TCP_CLOSE;
- sk->shutdown |= SEND_SHUTDOWN;
- sk->state_change(sk);
- sk->dead = 1;
- x25_destroy_socket(sk);
- break;
-
X case X25_STATE_2:
- sk->protinfo.x25->state = X25_STATE_0;
- sk->state = TCP_CLOSE;
- sk->shutdown |= SEND_SHUTDOWN;
- sk->state_change(sk);
- sk->dead = 1;
+ x25_disconnect(sk, 0, 0, 0);
X x25_destroy_socket(sk);
- break;
+ break;
X
X case X25_STATE_1:
X case X25_STATE_3:
X case X25_STATE_4:
X x25_clear_queues(sk);
X x25_write_internal(sk, X25_CLEAR_REQUEST);
- sk->protinfo.x25->timer = sk->protinfo.x25->t23;
+ x25_start_t23timer(sk);
X sk->protinfo.x25->state = X25_STATE_2;
X sk->state = TCP_CLOSE;
X sk->shutdown |= SEND_SHUTDOWN;
@@ -644,6 +630,9 @@
X if ((sk->protinfo.x25->neighbour = x25_get_neigh(dev)) == NULL)
X return -ENETUNREACH;
X
+ if ((sk->protinfo.x25->lci = x25_new_lci(sk->protinfo.x25->neighbour)) == 0)
+ return -ENETUNREACH;
+
X if (sk->zapped) /* Must bind first - autobinding does not work */
X return -EINVAL;
X
@@ -651,17 +640,17 @@
X memset(&sk->protinfo.x25->source_addr, '\0', X25_ADDR_LEN);
X
X sk->protinfo.x25->dest_addr = addr->sx25_addr;
- sk->protinfo.x25->lci = x25_new_lci();
X
X /* Move to connecting socket, start sending Connect Requests */
X sock->state = SS_CONNECTING;
X sk->state = TCP_SYN_SENT;
X
X sk->protinfo.x25->state = X25_STATE_1;
- sk->protinfo.x25->timer = sk->protinfo.x25->t21;
+
X x25_write_internal(sk, X25_CALL_REQUEST);
X
- x25_set_timer(sk);
+ x25_start_heartbeat(sk);
+ x25_start_t21timer(sk);
X
X /* Now the loop */
X if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
@@ -850,7 +839,7 @@
X
X skb_queue_head(&sk->receive_queue, skb);
X
- x25_set_timer(make);
+ x25_start_heartbeat(make);
X
X if (!sk->dead)
X sk->data_ready(sk, skb->len);
@@ -987,8 +976,7 @@
X x25_output(sk, skb);
X }
X
- if (sk->protinfo.x25->state == X25_STATE_3)
- x25_kick(sk);
+ x25_kick(sk);
X
X return len;
X }
@@ -1072,30 +1060,27 @@
X
X static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
X {
- struct x25_facilities facilities;
- struct x25_calluserdata calluserdata;
X struct sock *sk = sock->sk;
- int err;
- long amount = 0;
X
X switch (cmd) {
- case TIOCOUTQ:
- if ((err = verify_area(VERIFY_WRITE, (void *)arg, sizeof(unsigned long))) != 0)
- return err;
+ case TIOCOUTQ: {
+ long amount;
X amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
X if (amount < 0)
X amount = 0;
- put_user(amount, (unsigned long *)arg);
+ if (put_user(amount, (unsigned long *)arg))
+ return -EFAULT;
X return 0;
+ }
X
X case TIOCINQ: {
X struct sk_buff *skb;
+ long amount = 0L;
X /* These two are safe on a single CPU system as only user tasks fiddle here */
X if ((skb = skb_peek(&sk->receive_queue)) != NULL)
- amount = skb->len - 20;
- if ((err = verify_area(VERIFY_WRITE, (void *)arg, sizeof(unsigned long))) != 0)
- return err;
- put_user(amount, (unsigned long *)arg);
+ amount = skb->len;
+ if (put_user(amount, (unsigned long *)arg))
+ return -EFAULT;


X return 0;
X }
X

@@ -1103,9 +1088,8 @@


X if (sk != NULL) {

X if (sk->stamp.tv_sec == 0)
X return -ENOENT;
- if ((err = verify_area(VERIFY_WRITE,(void *)arg,sizeof(struct timeval))) != 0)
- return err;
- copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval));
+ if (copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)))
+ return -EFAULT;
X return 0;
X }
X return -EINVAL;
@@ -1134,17 +1118,18 @@
X if (!suser()) return -EPERM;
X return x25_subscr_ioctl(cmd, (void *)arg);
X
- case SIOCX25GFACILITIES:
- if ((err = verify_area(VERIFY_WRITE, (void *)arg, sizeof(facilities))) != 0)
- return err;
+ case SIOCX25GFACILITIES: {
+ struct x25_facilities facilities;
X facilities = sk->protinfo.x25->facilities;
- copy_to_user((void *)arg, &facilities, sizeof(facilities));
+ if (copy_to_user((void *)arg, &facilities, sizeof(facilities)))
+ return -EFAULT;
X return 0;
+ }
X
- case SIOCX25SFACILITIES:
- if ((err = verify_area(VERIFY_READ, (void *)arg, sizeof(facilities))) != 0)
- return err;
- copy_from_user(&facilities, (void *)arg, sizeof(facilities));
+ case SIOCX25SFACILITIES: {
+ struct x25_facilities facilities;
+ if (copy_from_user(&facilities, (void *)arg, sizeof(facilities)))
+ return -EFAULT;
X if (sk->state != TCP_LISTEN)
X return -EINVAL;
X if (facilities.pacsize_in < X25_PS16 || facilities.pacsize_in > X25_PS4096)
@@ -1168,22 +1153,33 @@
X return -EINVAL;
X sk->protinfo.x25->facilities = facilities;
X return 0;
+ }
X
- case SIOCX25GCALLUSERDATA:
- if ((err = verify_area(VERIFY_WRITE, (void *)arg, sizeof(calluserdata))) != 0)
- return err;
+ case SIOCX25GCALLUSERDATA: {
+ struct x25_calluserdata calluserdata;
X calluserdata = sk->protinfo.x25->calluserdata;
- copy_to_user((void *)arg, &calluserdata, sizeof(calluserdata));
+ if (copy_to_user((void *)arg, &calluserdata, sizeof(calluserdata)))
+ return -EFAULT;
X return 0;
+ }
X
- case SIOCX25SCALLUSERDATA:
- if ((err = verify_area(VERIFY_READ, (void *)arg, sizeof(calluserdata))) != 0)
- return err;
- copy_from_user(&calluserdata, (void *)arg, sizeof(calluserdata));
+ case SIOCX25SCALLUSERDATA: {
+ struct x25_calluserdata calluserdata;
+ if (copy_from_user(&calluserdata, (void *)arg, sizeof(calluserdata)))
+ return -EFAULT;
X if (calluserdata.cudlength > X25_MAX_CUD_LEN)
X return -EINVAL;
X sk->protinfo.x25->calluserdata = calluserdata;
X return 0;
+ }
+
+ case SIOCX25GCAUSEDIAG: {
+ struct x25_causediag causediag;
+ causediag = sk->protinfo.x25->causediag;
+ if (copy_to_user((void *)arg, &causediag, sizeof(causediag)))
+ return -EFAULT;


+ return 0;
+ }
X

X default:
X return dev_ioctl(cmd, (void *)arg);
@@ -1212,18 +1208,22 @@
X else
X devname = s->protinfo.x25->neighbour->dev->name;
X
- len += sprintf(buffer + len, "%-10s %-10s %-5s %3.3X %d %d %d %d %3d %3d %3d %3d %3d %5d %5d\n",
+ len += sprintf(buffer + len, "%-10s %-10s %-5s %3.3X %d %d %d %d %3lu %3lu %3lu %3lu %3lu %5d %5d\n",
X (s->protinfo.x25->dest_addr.x25_addr[0] == '\0') ? "*" : s->protinfo.x25->dest_addr.x25_addr,
X (s->protinfo.x25->source_addr.x25_addr[0] == '\0') ? "*" : s->protinfo.x25->source_addr.x25_addr,
- devname, s->protinfo.x25->lci & 0x0FFF,
+ devname,
+ s->protinfo.x25->lci & 0x0FFF,
X s->protinfo.x25->state,
- s->protinfo.x25->vs, s->protinfo.x25->vr, s->protinfo.x25->va,
- s->protinfo.x25->timer / X25_SLOWHZ,
- s->protinfo.x25->t2 / X25_SLOWHZ,
- s->protinfo.x25->t21 / X25_SLOWHZ,
- s->protinfo.x25->t22 / X25_SLOWHZ,
- s->protinfo.x25->t23 / X25_SLOWHZ,
- atomic_read(&s->wmem_alloc), atomic_read(&s->rmem_alloc));
+ s->protinfo.x25->vs,
+ s->protinfo.x25->vr,
+ s->protinfo.x25->va,
+ x25_display_timer(s) / HZ,
+ s->protinfo.x25->t2 / HZ,
+ s->protinfo.x25->t21 / HZ,
+ s->protinfo.x25->t22 / HZ,
+ s->protinfo.x25->t23 / HZ,
+ atomic_read(&s->wmem_alloc),
+ atomic_read(&s->rmem_alloc));
X
X pos = begin + len;
X
@@ -1310,7 +1310,7 @@
X
X register_netdevice_notifier(&x25_dev_notifier);
X
- printk(KERN_INFO "X.25 for Linux. Version 0.1 for Linux 2.1.15\n");
+ printk(KERN_INFO "X.25 for Linux. Version 0.2 for Linux 2.1.15\n");
X
X #ifdef CONFIG_SYSCTL
X x25_register_sysctl();
diff -u --recursive --new-file v2.1.43/linux/net/x25/sysctl_net_x25.c linux/net/x25/sysctl_net_x25.c
--- v2.1.43/linux/net/x25/sysctl_net_x25.c Tue May 13 22:41:25 1997
+++ linux/net/x25/sysctl_net_x25.c Mon Jul 7 08:20:00 1997
@@ -13,8 +13,8 @@
X #include <linux/init.h>
X #include <net/x25.h>
X
-static int min_timer[] = {1 * X25_SLOWHZ};
-static int max_timer[] = {300 * X25_SLOWHZ};
+static int min_timer[] = {1 * HZ};
+static int max_timer[] = {300 * HZ};
X
X static struct ctl_table_header *x25_table_header;
X
diff -u --recursive --new-file v2.1.43/linux/net/x25/x25_dev.c linux/net/x25/x25_dev.c
--- v2.1.43/linux/net/x25/x25_dev.c Thu Mar 27 14:40:18 1997
+++ linux/net/x25/x25_dev.c Mon Jul 7 08:20:00 1997


@@ -1,5 +1,5 @@
X /*

- * X.25 Packet Layer release 001
+ * X.25 Packet Layer release 002
X *
X * This is ALPHA test software. This code may break your machine, randomly fail to work with new
X * releases, misbehave and/or generally screw up. It might even work.
@@ -73,7 +73,7 @@
X /*
X * Find an existing socket.
X */
- if ((sk = x25_find_socket(lci)) != NULL) {
+ if ((sk = x25_find_socket(lci, neigh)) != NULL) {
X skb->h.raw = skb->data;
X return x25_process_rx_frame(sk, skb);
X }
diff -u --recursive --new-file v2.1.43/linux/net/x25/x25_facilities.c linux/net/x25/x25_facilities.c
--- v2.1.43/linux/net/x25/x25_facilities.c Thu May 29 21:53:12 1997
+++ linux/net/x25/x25_facilities.c Mon Jul 7 08:20:00 1997


@@ -1,5 +1,5 @@
X /*

- * X.25 Packet Layer release 001
+ * X.25 Packet Layer release 002
X *
X * This is ALPHA test software. This code may break your machine, randomly fail to work with new
X * releases, misbehave and/or generally screw up. It might even work.
diff -u --recursive --new-file v2.1.43/linux/net/x25/x25_in.c linux/net/x25/x25_in.c
--- v2.1.43/linux/net/x25/x25_in.c Thu May 29 21:53:12 1997
+++ linux/net/x25/x25_in.c Mon Jul 7 08:20:00 1997


@@ -1,5 +1,5 @@
X /*

- * X.25 Packet Layer release 001
+ * X.25 Packet Layer release 002
X *
X * This is ALPHA test software. This code may break your machine, randomly fail to work with new
X * releases, misbehave and/or generally screw up. It might even work.
@@ -14,6 +14,8 @@


X *
X * History

X * X.25 001 Jonathan Naylor Started coding.
+ * X.25 002 Jonathan Naylor Centralised disconnection code.
+ * New timer architecture.


X */
X
X #include <linux/config.h>

@@ -88,8 +90,8 @@
X switch (frametype) {
X
X case X25_CALL_ACCEPTED:
+ x25_stop_timer(sk);
X sk->protinfo.x25->condition = 0x00;
- sk->protinfo.x25->timer = 0;
X sk->protinfo.x25->vs = 0;
X sk->protinfo.x25->va = 0;
X sk->protinfo.x25->vr = 0;
@@ -114,15 +116,8 @@
X break;
X
X case X25_CLEAR_REQUEST:
- x25_clear_queues(sk);
X x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
- sk->protinfo.x25->state = X25_STATE_0;
- sk->state = TCP_CLOSE;
- sk->err = ECONNREFUSED;
- sk->shutdown |= SEND_SHUTDOWN;
- if (!sk->dead)
- sk->state_change(sk);
- sk->dead = 1;
+ x25_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
X break;
X
X default:
@@ -143,15 +138,11 @@
X
X case X25_CLEAR_REQUEST:
X x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
+ x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
+ break;
+
X case X25_CLEAR_CONFIRMATION:
- x25_clear_queues(sk);
- sk->protinfo.x25->state = X25_STATE_0;
- sk->state = TCP_CLOSE;
- sk->err = 0;
- sk->shutdown |= SEND_SHUTDOWN;
- if (!sk->dead)
- sk->state_change(sk);
- sk->dead = 1;
+ x25_disconnect(sk, 0, 0, 0);
X break;
X
X default:
@@ -177,8 +168,8 @@
X
X case X25_RESET_REQUEST:
X x25_write_internal(sk, X25_RESET_CONFIRMATION);
+ x25_stop_timer(sk);
X sk->protinfo.x25->condition = 0x00;
- sk->protinfo.x25->timer = 0;
X sk->protinfo.x25->vs = 0;
X sk->protinfo.x25->vr = 0;
X sk->protinfo.x25->va = 0;
@@ -186,15 +177,8 @@
X break;
X
X case X25_CLEAR_REQUEST:
- x25_clear_queues(sk);
X x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
- sk->protinfo.x25->state = X25_STATE_0;
- sk->state = TCP_CLOSE;
- sk->err = 0;
- sk->shutdown |= SEND_SHUTDOWN;
- if (!sk->dead)
- sk->state_change(sk);
- sk->dead = 1;
+ x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
X break;
X
X case X25_RR:
@@ -207,13 +191,13 @@
X if (!x25_validate_nr(sk, nr)) {
X x25_clear_queues(sk);
X x25_write_internal(sk, X25_RESET_REQUEST);
+ x25_start_t22timer(sk);
X sk->protinfo.x25->condition = 0x00;
X sk->protinfo.x25->vs = 0;
X sk->protinfo.x25->vr = 0;
X sk->protinfo.x25->va = 0;
X sk->protinfo.x25->vl = 0;
X sk->protinfo.x25->state = X25_STATE_4;
- sk->protinfo.x25->timer = sk->protinfo.x25->t22;
X } else {
X if (sk->protinfo.x25->condition & X25_COND_PEER_RX_BUSY) {
X sk->protinfo.x25->va = nr;
@@ -228,13 +212,13 @@
X if (!x25_validate_nr(sk, nr)) {
X x25_clear_queues(sk);
X x25_write_internal(sk, X25_RESET_REQUEST);
+ x25_start_t22timer(sk);
X sk->protinfo.x25->condition = 0x00;
X sk->protinfo.x25->vs = 0;
X sk->protinfo.x25->vr = 0;
X sk->protinfo.x25->va = 0;
X sk->protinfo.x25->vl = 0;
X sk->protinfo.x25->state = X25_STATE_4;
- sk->protinfo.x25->timer = sk->protinfo.x25->t22;
X break;
X }
X if (sk->protinfo.x25->condition & X25_COND_PEER_RX_BUSY) {
@@ -258,11 +242,11 @@
X */
X if (((sk->protinfo.x25->vl + sk->protinfo.x25->facilities.winsize_in) % modulus) == sk->protinfo.x25->vr) {
X sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
- sk->protinfo.x25->timer = 0;
+ x25_stop_timer(sk);
X x25_enquiry_response(sk);
X } else {
X sk->protinfo.x25->condition |= X25_COND_ACK_PENDING;
- sk->protinfo.x25->timer = sk->protinfo.x25->t2;
+ x25_start_t2timer(sk);
X }
X break;
X
@@ -307,7 +291,7 @@
X case X25_RESET_REQUEST:
X x25_write_internal(sk, X25_RESET_CONFIRMATION);
X case X25_RESET_CONFIRMATION:
- sk->protinfo.x25->timer = 0;
+ x25_stop_timer(sk);
X sk->protinfo.x25->condition = 0x00;
X sk->protinfo.x25->va = 0;
X sk->protinfo.x25->vr = 0;
@@ -317,16 +301,8 @@
X break;
X
X case X25_CLEAR_REQUEST:
- x25_clear_queues(sk);
X x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
- sk->protinfo.x25->timer = 0;
- sk->protinfo.x25->state = X25_STATE_0;
- sk->state = TCP_CLOSE;
- sk->err = 0;
- sk->shutdown |= SEND_SHUTDOWN;
- if (!sk->dead)
- sk->state_change(sk);
- sk->dead = 1;
+ x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
X break;
X
X default:
@@ -344,8 +320,6 @@
X if (sk->protinfo.x25->state == X25_STATE_0)
X return 0;
X
- del_timer(&sk->timer);
-
X frametype = x25_decode(sk, skb, &ns, &nr, &q, &d, &m);
X
X switch (sk->protinfo.x25->state) {
@@ -363,7 +337,7 @@
X break;
X }
X
- x25_set_timer(sk);
+ x25_kick(sk);


X
X return queued;
X }

diff -u --recursive --new-file v2.1.43/linux/net/x25/x25_link.c linux/net/x25/x25_link.c
--- v2.1.43/linux/net/x25/x25_link.c Thu May 29 21:53:12 1997
+++ linux/net/x25/x25_link.c Mon Jul 7 08:20:00 1997


@@ -1,5 +1,5 @@
X /*

- * X.25 Packet Layer release 001
+ * X.25 Packet Layer release 002
X *
X * This is ALPHA test software. This code may break your machine, randomly fail to work with new
X * releases, misbehave and/or generally screw up. It might even work.
@@ -14,6 +14,7 @@


X *
X * History

X * X.25 001 Jonathan Naylor Started coding.
+ * X.25 002 Jonathan Naylor New timer architecture.


X */
X
X #include <linux/config.h>

@@ -43,49 +44,34 @@
X
X static struct x25_neigh *x25_neigh_list = NULL;
X
-static void x25_link_timer(unsigned long);
+static void x25_t20timer_expiry(unsigned long);
X
X /*
X * Linux set/reset timer routines
X */
-static void x25_link_set_timer(struct x25_neigh *neigh)
+static void x25_start_t20timer(struct x25_neigh *neigh)


X {
- unsigned long flags;
-
- save_flags(flags); cli();

- del_timer(&neigh->timer);
- restore_flags(flags);
+ del_timer(&neigh->t20timer);
X
- neigh->timer.data = (unsigned long)neigh;
- neigh->timer.function = &x25_link_timer;
- neigh->timer.expires = jiffies + (HZ / 1);
+ neigh->t20timer.data = (unsigned long)neigh;
+ neigh->t20timer.function = &x25_t20timer_expiry;
+ neigh->t20timer.expires = jiffies + neigh->t20;
X
- add_timer(&neigh->timer);
+ add_timer(&neigh->t20timer);
X }
X
-/*
- * X.25 Link TIMER
- *
- * This routine is called every second. Decrement timer by this


- * amount - if expired then process the event.
- */

-static void x25_link_timer(unsigned long param)
+static void x25_t20timer_expiry(unsigned long param)
X {
X struct x25_neigh *neigh = (struct x25_neigh *)param;
X
- if (neigh->t20timer == 0 || --neigh->t20timer > 0) {
- x25_link_set_timer(neigh);
- return;
- }
-
- /*
- * T20 for a link has expired.
- */
X x25_transmit_restart_request(neigh);
X
- neigh->t20timer = neigh->t20;
+ x25_start_t20timer(neigh);
+}
X
- x25_link_set_timer(neigh);
+static void x25_stop_t20timer(struct x25_neigh *neigh)
+{
+ del_timer(&neigh->t20timer);
X }
X
X /*
@@ -97,16 +83,14 @@
X
X switch (frametype) {
X case X25_RESTART_REQUEST:
- neigh->t20timer = 0;
- neigh->state = X25_LINK_STATE_3;
- del_timer(&neigh->timer);
+ x25_stop_t20timer(neigh);
+ neigh->state = X25_LINK_STATE_3;
X x25_transmit_restart_confirmation(neigh);
X break;
X
X case X25_RESTART_CONFIRMATION:
- neigh->t20timer = 0;
- neigh->state = X25_LINK_STATE_3;
- del_timer(&neigh->timer);
+ x25_stop_t20timer(neigh);
+ neigh->state = X25_LINK_STATE_3;
X break;
X
X case X25_DIAGNOSTIC:
@@ -272,9 +256,8 @@
X break;
X case X25_LINK_STATE_1:
X x25_transmit_restart_request(neigh);
- neigh->state = X25_LINK_STATE_2;
- neigh->t20timer = neigh->t20;
- x25_link_set_timer(neigh);
+ neigh->state = X25_LINK_STATE_2;
+ x25_start_t20timer(neigh);
X break;
X }
X }
@@ -300,12 +283,12 @@
X return;
X
X skb_queue_head_init(&x25_neigh->queue);
- init_timer(&x25_neigh->timer);
+
+ init_timer(&x25_neigh->t20timer);
X
X x25_neigh->dev = dev;
X x25_neigh->state = X25_LINK_STATE_0;
X x25_neigh->extended = 0;
- x25_neigh->t20timer = 0;
X x25_neigh->t20 = sysctl_x25_restart_request_timeout;
X
X save_flags(flags); cli();
@@ -323,10 +306,9 @@
X while ((skb = skb_dequeue(&x25_neigh->queue)) != NULL)
X kfree_skb(skb, FREE_WRITE);
X
- del_timer(&x25_neigh->timer);
+ x25_stop_t20timer(x25_neigh);
X
- save_flags(flags);
- cli();
+ save_flags(flags); cli();
X
X if ((s = x25_neigh_list) == x25_neigh) {
X x25_neigh_list = x25_neigh->next;
@@ -387,25 +369,22 @@
X struct x25_subscrip_struct x25_subscr;
X struct x25_neigh *x25_neigh;
X struct device *dev;
- int err;


X
X switch (cmd) {
X

X case SIOCX25GSUBSCRIP:
- if ((err = verify_area(VERIFY_WRITE, arg, sizeof(struct x25_subscrip_struct))) != 0)
- return err;
X if ((dev = x25_dev_get(x25_subscr.device)) == NULL)
X return -EINVAL;
X if ((x25_neigh = x25_get_neigh(dev)) == NULL)
X return -EINVAL;
X x25_subscr.extended = x25_neigh->extended;
- copy_to_user(arg, &x25_subscr, sizeof(struct x25_subscrip_struct));
+ if (copy_to_user(arg, &x25_subscr, sizeof(struct x25_subscrip_struct)))
+ return -EFAULT;
X break;
X
X case SIOCX25SSUBSCRIP:
- if ((err = verify_area(VERIFY_READ, arg, sizeof(struct x25_subscrip_struct))) != 0)
- return err;
- copy_from_user(&x25_subscr, arg, sizeof(struct x25_subscrip_struct));
+ if (copy_from_user(&x25_subscr, arg, sizeof(struct x25_subscrip_struct)))
+ return -EFAULT;
X if ((dev = x25_dev_get(x25_subscr.device)) == NULL)
X return -EINVAL;
X if ((x25_neigh = x25_get_neigh(dev)) == NULL)
diff -u --recursive --new-file v2.1.43/linux/net/x25/x25_out.c linux/net/x25/x25_out.c
--- v2.1.43/linux/net/x25/x25_out.c Sun Jan 19 05:47:30 1997
+++ linux/net/x25/x25_out.c Mon Jul 7 08:20:00 1997


@@ -1,5 +1,5 @@
X /*

- * X.25 Packet Layer release 001
+ * X.25 Packet Layer release 002
X *
X * This is ALPHA test software. This code may break your machine, randomly fail to work with new
X * releases, misbehave and/or generally screw up. It might even work.
@@ -14,6 +14,7 @@


X *
X * History

X * X.25 001 Jonathan Naylor Started coding.
+ * X.25 002 Jonathan Naylor New timer architecture.


X */
X
X #include <linux/config.h>

@@ -129,7 +130,8 @@
X unsigned short end;
X int modulus;
X
- del_timer(&sk->timer);
+ if (sk->protinfo.x25->state != X25_STATE_3)
+ return;
X
X /*
X * Transmit interrupt data.
@@ -140,38 +142,39 @@
X x25_transmit_link(skb, sk->protinfo.x25->neighbour);
X }
X
+ if (sk->protinfo.x25->condition & X25_COND_PEER_RX_BUSY)
+ return;
+
+ if (skb_peek(&sk->write_queue) == NULL)
+ return;
+
X modulus = (sk->protinfo.x25->neighbour->extended) ? X25_EMODULUS : X25_SMODULUS;
X end = (sk->protinfo.x25->va + sk->protinfo.x25->facilities.winsize_out) % modulus;
X
+ if (sk->protinfo.x25->vs == end)
+ return;
+
X /*
- * Transmit normal stream data.


+ * Transmit data until either we're out of data to send or
+ * the window is full.

X */
- if (!(sk->protinfo.x25->condition & X25_COND_PEER_RX_BUSY) &&
- sk->protinfo.x25->vs != end &&
- skb_peek(&sk->write_queue) != NULL) {


- /*
- * Transmit data until either we're out of data to send or
- * the window is full.

- */
X
- skb = skb_dequeue(&sk->write_queue);
+ skb = skb_dequeue(&sk->write_queue);
X
- do {
- /*
- * Transmit the frame.
- */
- x25_send_iframe(sk, skb);
+ do {
+ /*
+ * Transmit the frame.
+ */
+ x25_send_iframe(sk, skb);
X
- sk->protinfo.x25->vs = (sk->protinfo.x25->vs + 1) % modulus;
+ sk->protinfo.x25->vs = (sk->protinfo.x25->vs + 1) % modulus;
X
- } while (sk->protinfo.x25->vs != end && (skb = skb_dequeue(&sk->write_queue)) != NULL);
+ } while (sk->protinfo.x25->vs != end && (skb = skb_dequeue(&sk->write_queue)) != NULL);
X
- sk->protinfo.x25->vl = sk->protinfo.x25->vr;
- sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
- sk->protinfo.x25->timer = 0;
- }
+ sk->protinfo.x25->vl = sk->protinfo.x25->vr;
+ sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
X
- x25_set_timer(sk);
+ x25_stop_timer(sk);
X }
X
X /*
@@ -188,7 +191,8 @@
X
X sk->protinfo.x25->vl = sk->protinfo.x25->vr;
X sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
- sk->protinfo.x25->timer = 0;
+
+ x25_stop_timer(sk);
X }
X
X void x25_check_iframes_acked(struct sock *sk, unsigned short nr)
diff -u --recursive --new-file v2.1.43/linux/net/x25/x25_route.c linux/net/x25/x25_route.c
--- v2.1.43/linux/net/x25/x25_route.c Thu May 29 21:53:12 1997
+++ linux/net/x25/x25_route.c Mon Jul 7 08:20:00 1997


@@ -1,5 +1,5 @@
X /*

- * X.25 Packet Layer release 001
+ * X.25 Packet Layer release 002
X *
X * This is ALPHA test software. This code may break your machine, randomly fail to work with new
X * releases, misbehave and/or generally screw up. It might even work.
@@ -183,14 +183,12 @@
X {
X struct x25_route_struct x25_route;
X struct device *dev;
- int err;


X
X switch (cmd) {
X
X case SIOCADDRT:

- if ((err = verify_area(VERIFY_READ, arg, sizeof(struct x25_route_struct))) != 0)
- return err;
- copy_from_user(&x25_route, arg, sizeof(struct x25_route_struct));
+ if (copy_from_user(&x25_route, arg, sizeof(struct x25_route_struct)))
+ return -EFAULT;
X if (x25_route.sigdigits < 0 || x25_route.sigdigits > 15)
X return -EINVAL;
X if ((dev = x25_dev_get(x25_route.device)) == NULL)
@@ -198,9 +196,8 @@
X return x25_add_route(&x25_route.address, x25_route.sigdigits, dev);
X
X case SIOCDELRT:
- if ((err = verify_area(VERIFY_READ, arg, sizeof(struct x25_route_struct))) != 0)
- return err;
- copy_from_user(&x25_route, arg, sizeof(struct x25_route_struct));
+ if (copy_from_user(&x25_route, arg, sizeof(struct x25_route_struct)))
+ return -EFAULT;
X if (x25_route.sigdigits < 0 || x25_route.sigdigits > 15)
X return -EINVAL;
X if ((dev = x25_dev_get(x25_route.device)) == NULL)
@@ -227,7 +224,8 @@
X
X for (x25_route = x25_route_list; x25_route != NULL; x25_route = x25_route->next) {
X len += sprintf(buffer + len, "%-15s %-6d %-5s\n",
- x25_route->address.x25_addr, x25_route->sigdigits,
+ x25_route->address.x25_addr,
+ x25_route->sigdigits,
X (x25_route->dev != NULL) ? x25_route->dev->name : "???");
X
X pos = begin + len;
diff -u --recursive --new-file v2.1.43/linux/net/x25/x25_subr.c linux/net/x25/x25_subr.c
--- v2.1.43/linux/net/x25/x25_subr.c Thu May 29 21:53:12 1997
+++ linux/net/x25/x25_subr.c Mon Jul 7 08:20:00 1997


@@ -1,5 +1,5 @@
X /*

- * X.25 Packet Layer release 001
+ * X.25 Packet Layer release 002
X *
X * This is ALPHA test software. This code may break your machine, randomly fail to work with new
X * releases, misbehave and/or generally screw up. It might even work.
@@ -14,6 +14,7 @@


X *
X * History

X * X.25 001 Jonathan Naylor Started coding.
+ * X.25 002 Jonathan Naylor Centralised disconnection processing.


X */
X
X #include <linux/config.h>

@@ -279,6 +280,27 @@
X printk(KERN_DEBUG "X.25: invalid PLP frame %02X %02X %02X\n", frame[0], frame[1], frame[2]);
X
X return X25_ILLEGAL;
+}
+
+void x25_disconnect(struct sock *sk, int reason, unsigned char cause, unsigned char diagnostic)
+{
+ x25_clear_queues(sk);
+ x25_stop_timer(sk);
+
+ sk->protinfo.x25->lci = 0;
+ sk->protinfo.x25->state = X25_STATE_0;
+
+ sk->protinfo.x25->causediag.cause = cause;
+ sk->protinfo.x25->causediag.diagnostic = diagnostic;
+
+ sk->state = TCP_CLOSE;
+ sk->err = reason;
+ sk->shutdown |= SEND_SHUTDOWN;
+
+ if (!sk->dead)
+ sk->state_change(sk);
+
+ sk->dead = 1;
X }
X
X #endif
diff -u --recursive --new-file v2.1.43/linux/net/x25/x25_timer.c linux/net/x25/x25_timer.c
--- v2.1.43/linux/net/x25/x25_timer.c Mon Apr 14 16:28:29 1997
+++ linux/net/x25/x25_timer.c Mon Jul 7 08:20:00 1997


@@ -1,5 +1,5 @@
X /*

- * X.25 Packet Layer release 001
+ * X.25 Packet Layer release 002
X *
X * This is ALPHA test software. This code may break your machine, randomly fail to work with new
X * releases, misbehave and/or generally screw up. It might even work.
@@ -14,6 +14,8 @@


X *
X * History

X * X.25 001 Jonathan Naylor Started coding.
+ * X.25 002 Jonathan Naylor New timer architecture.
+ * Centralised disconnection processing.


X */
X
X #include <linux/config.h>

@@ -39,42 +41,93 @@
X #include <linux/interrupt.h>
X #include <net/x25.h>
X
-static void x25_timer(unsigned long);
+static void x25_heartbeat_expiry(unsigned long);
+static void x25_timer_expiry(unsigned long);


X
-/*
- * Linux set timer
- */

-void x25_set_timer(struct sock *sk)
+void x25_start_heartbeat(struct sock *sk)


X {
- unsigned long flags;
-
- save_flags(flags); cli();

X del_timer(&sk->timer);
- restore_flags(flags);
X
X sk->timer.data = (unsigned long)sk;
- sk->timer.function = &x25_timer;
- sk->timer.expires = jiffies + (HZ / 1);
+ sk->timer.function = &x25_heartbeat_expiry;
+ sk->timer.expires = jiffies + 5 * HZ;
X
X add_timer(&sk->timer);
X }
X
-/*
- * X.25 TIMER
- *
- * This routine is called every second. Decrement timer by this


- * amount - if expired then process the event.
- */

-static void x25_timer(unsigned long param)
+void x25_stop_heartbeat(struct sock *sk)
+{
+ del_timer(&sk->timer);
+}
+
+void x25_start_t2timer(struct sock *sk)
+{
+ del_timer(&sk->protinfo.x25->timer);
+
+ sk->protinfo.x25->timer.data = (unsigned long)sk;
+ sk->protinfo.x25->timer.function = &x25_timer_expiry;
+ sk->protinfo.x25->timer.expires = jiffies + sk->protinfo.x25->t2;
+
+ add_timer(&sk->protinfo.x25->timer);
+}
+
+void x25_start_t21timer(struct sock *sk)
+{
+ del_timer(&sk->protinfo.x25->timer);
+
+ sk->protinfo.x25->timer.data = (unsigned long)sk;
+ sk->protinfo.x25->timer.function = &x25_timer_expiry;
+ sk->protinfo.x25->timer.expires = jiffies + sk->protinfo.x25->t21;
+
+ add_timer(&sk->protinfo.x25->timer);
+}
+
+void x25_start_t22timer(struct sock *sk)
+{
+ del_timer(&sk->protinfo.x25->timer);
+
+ sk->protinfo.x25->timer.data = (unsigned long)sk;
+ sk->protinfo.x25->timer.function = &x25_timer_expiry;
+ sk->protinfo.x25->timer.expires = jiffies + sk->protinfo.x25->t22;
+
+ add_timer(&sk->protinfo.x25->timer);
+}
+
+void x25_start_t23timer(struct sock *sk)
+{
+ del_timer(&sk->protinfo.x25->timer);
+
+ sk->protinfo.x25->timer.data = (unsigned long)sk;
+ sk->protinfo.x25->timer.function = &x25_timer_expiry;
+ sk->protinfo.x25->timer.expires = jiffies + sk->protinfo.x25->t23;
+
+ add_timer(&sk->protinfo.x25->timer);
+}
+
+void x25_stop_timer(struct sock *sk)
+{
+ del_timer(&sk->protinfo.x25->timer);
+}
+
+unsigned long x25_display_timer(struct sock *sk)
+{
+ if (sk->protinfo.x25->timer.prev == NULL &&
+ sk->protinfo.x25->timer.next == NULL)
+ return 0;
+
+ return sk->protinfo.x25->timer.expires - jiffies;
+}
+
+static void x25_heartbeat_expiry(unsigned long param)
X {
X struct sock *sk = (struct sock *)param;
X
X switch (sk->protinfo.x25->state) {
+
X case X25_STATE_0:


X /* Magic here: If we listen() and a new link dies before it
X is accepted() it isn't 'dead' so doesn't get removed. */

X if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) {
- del_timer(&sk->timer);
X x25_destroy_socket(sk);
X return;
X }
@@ -89,30 +142,26 @@
X sk->protinfo.x25->condition &= ~X25_COND_OWN_RX_BUSY;
X sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
X sk->protinfo.x25->vl = sk->protinfo.x25->vr;
- sk->protinfo.x25->timer = 0;
X x25_write_internal(sk, X25_RR);
+ x25_stop_timer(sk);
X break;


X }
- /*
- * Check for frames to transmit.
- */

- x25_kick(sk);


- break;
-
- default:

X break;
X }
X
- if (sk->protinfo.x25->timer == 0 || --sk->protinfo.x25->timer > 0) {
- x25_set_timer(sk);
- return;
- }
+ x25_start_heartbeat(sk);
+}
+
+/*
+ * Timer has expired, it may have been T2, T21, T22, or T23. We can tell
+ * by the state machine state.
+ */
+static void x25_timer_expiry(unsigned long param)
+{
+ struct sock *sk = (struct sock *)param;
X
- /*
- * Timer has expired, it may have been T2, T21, T22, or T23. We can tell
- * by the state machine state.
- */
X switch (sk->protinfo.x25->state) {
+
X case X25_STATE_3: /* T2 */
X if (sk->protinfo.x25->condition & X25_COND_ACK_PENDING) {
X sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
@@ -124,22 +173,13 @@
X case X25_STATE_4: /* T22 */
X x25_write_internal(sk, X25_CLEAR_REQUEST);
X sk->protinfo.x25->state = X25_STATE_2;
- sk->protinfo.x25->timer = sk->protinfo.x25->t23;
+ x25_start_t23timer(sk);
X break;
X
X case X25_STATE_2: /* T23 */
- x25_clear_queues(sk);
- sk->protinfo.x25->state = X25_STATE_0;
- sk->state = TCP_CLOSE;
- sk->err = ETIMEDOUT;
- sk->shutdown |= SEND_SHUTDOWN;
- if (!sk->dead)
- sk->state_change(sk);
- sk->dead = 1;
+ x25_disconnect(sk, ETIMEDOUT, 0, 0);
X break;
X }
-
- x25_set_timer(sk);
X }
X
X #endif
diff -u --recursive --new-file v2.1.43/linux/scripts/ksymoops.cc linux/scripts/ksymoops.cc
--- v2.1.43/linux/scripts/ksymoops.cc Sun Nov 10 04:04:07 1996
+++ linux/scripts/ksymoops.cc Thu Jun 26 12:33:41 1997
@@ -31,6 +31,7 @@
X // * Only resolves operands of jump and call instructions.
X
X #include <fstream.h>
+#include <strstream.h>
X #include <iomanip.h>
X #include <stdio.h>
X #include <string.h>
@@ -184,9 +185,23 @@
X
X char buf[1024];
X int lines = 0;
+ int eip_seen = 0;
+ long offset;
X while (fgets(buf, sizeof(buf), objdump_FILE)) {
+ if (eip_seen && buf[4] == ':') {
+ // assume objdump from binutils 2.8..., reformat to old style
+ offset = strtol(buf, 0, 16);
+ char newbuf[sizeof(buf)];
+ memset(newbuf, '\0', sizeof(newbuf));
+ ostrstream ost(newbuf, sizeof(newbuf));
+ ost.width(8);
+ ost << offset;
+ ost << " <_EIP+" << offset << ">: " << &buf[6] << ends;
+ strcpy(buf, newbuf);
+ }
X if (!strnequ(&buf[9], "<_EIP", 5))
X continue;
+ eip_seen = 1;
X if (strstr(buf, " is out of bounds"))
X break;
X lines++;
@@ -195,19 +210,28 @@
X cout << buf;
X continue;
X }
- long offset = strtol(buf, 0, 16);
- char* bp_0 = strchr(buf, '>') + 2;
+ offset = strtol(buf, 0, 16);
+ char* bp_0 = strchr(buf, '>');
X KSym* ksym = find(eip_addr + offset);
+ if (bp_0)
+ bp_0 += 2;
+ else
+ bp_0 = strchr(buf, ':');
X if (ksym)
X cout << *ksym << ' ';
- char* bp = bp_0;
+ char *bp_1 = strstr(bp_0, "\t"); // objdump from binutils 2.8...
+ if (bp_1)
+ ++bp_1;
+ else
+ bp_1 = bp_0;
+ char *bp = bp_1;
X while (!isspace(*bp))
X bp++;
X while (isspace(*bp))
X bp++;
- if (*bp != '0') {
+ if (!isxdigit(*bp)) {
X cout << bp_0;
- } else if (*bp_0 == 'j' || strnequ(bp_0, "call", 4)) { // a jump or call insn
+ } else if (*bp_1 == 'j' || strnequ(bp_1, "call", 4)) { // a jump or call insn
X long rel_addr = strtol(bp, 0, 16);
X ksym = find(eip_addr + rel_addr);
X if (ksym) {


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'

echo 'File patch-2.1.44 is complete' &&
chmod 644 patch-2.1.44 ||


echo 'restore of patch-2.1.44 failed'

Cksum="`cksum < 'patch-2.1.44'`"
if ! test "1980919457 2694247" = "$Cksum"
then
echo 'patch-2.1.44: original Checksum 1980919457 2694247, current one' "$Cksum"
rm -f _shar_wnt_.tmp
rm -f _shar_seq_.tmp
exit 1
fi
rm -f _shar_wnt_.tmp
fi
rm -f _shar_seq_.tmp
echo 'You have unpacked the last part.'
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part33

#!/bin/sh
# this is part 33 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 33; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

- if (!p->fs)
+ if (!p->fs || !p->fs->root)
X break;
- new_inode = p->fs->root;
+ result = dget(p->fs->root);
X break;
+
X case PROC_PID_EXE: {
X struct vm_area_struct * vma;
X if (!p->mm)
X break;
X vma = p->mm->mmap;
X while (vma) {
- if (vma->vm_flags & VM_EXECUTABLE) {
- new_inode = vma->vm_inode;
- break;
- }
+ if (vma->vm_flags & VM_EXECUTABLE)
+ return dget(vma->vm_inode->i_dentry);
+
X vma = vma->vm_next;
X }
X break;
@@ -122,45 +117,38 @@
X if (!p->files)
X break;
X ino &= 0xff;
- if (ino < NR_OPEN && p->files->fd[ino]) {
- new_inode = p->files->fd[ino]->f_inode;
- }
+ if (ino >= NR_OPEN)
+ break;
+ if (!p->files->fd[ino])
+ break;
+ if (!p->files->fd[ino]->f_inode)
+ break;
+ result = dget(p->files->fd[ino]->f_inode->i_dentry);
X break;
X }
X }
- iput(inode);
- if (!new_inode)
- return -ENOENT;
- *res_inode = new_inode;
- atomic_inc(&new_inode->i_count);
- return 0;
+ return result;
X }
X
X static int proc_readlink(struct inode * inode, char * buffer, int buflen)
X {
- int error = proc_follow_link(NULL, inode, 0, 0, &inode);
+ int error;
+ struct dentry * dentry = proc_follow_link(inode, NULL);
X
- if (error)
- return error;
- if (!inode)
- return -EIO;
-
- /* This will return *one* of the alias names (which is not quite
- * correct). I have to rethink the problem, so this is only a
- * quick hack...
- */
- if(inode->i_dentry) {
- char * tmp = (char*)__get_free_page(GFP_KERNEL);
- int len = d_path(inode->i_dentry, current->fs->root, tmp);
- int min = buflen<PAGE_SIZE ? buflen : PAGE_SIZE;
- if(len <= min)
- min = len+1;
- copy_to_user(buffer, tmp, min);
- free_page((unsigned long)tmp);
- error = len;
- } else {
- error= -ENOENT;
+ error = PTR_ERR(dentry);
+ if (!IS_ERR(dentry)) {
+ error = -ENOENT;
+ if (dentry) {
+ char * tmp = (char*)__get_free_page(GFP_KERNEL);
+ int len = d_path(dentry, current->fs->root, tmp);
+ int min = buflen<PAGE_SIZE ? buflen : PAGE_SIZE;
+ if(len <= min)
+ min = len+1;
+ dput(dentry);
+ copy_to_user(buffer, tmp, min);
+ free_page((unsigned long)tmp);
+ error = len;
+ }
X }
- iput(inode);
X return error;
X }
diff -u --recursive --new-file v2.1.43/linux/fs/proc/mem.c linux/fs/proc/mem.c
--- v2.1.43/linux/fs/proc/mem.c Mon Jun 16 16:35:59 1997
+++ linux/fs/proc/mem.c Sat Jul 5 20:53:22 1997
@@ -328,6 +328,7 @@


X NULL, /* mknod */
X NULL, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */

X NULL, /* bmap */
diff -u --recursive --new-file v2.1.43/linux/fs/proc/net.c linux/fs/proc/net.c
--- v2.1.43/linux/fs/proc/net.c Mon Jun 16 16:35:59 1997
+++ linux/fs/proc/net.c Sat Jul 5 20:53:22 1997
@@ -111,6 +111,7 @@


X NULL, /* mknod */
X NULL, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */

X NULL, /* bmap */
diff -u --recursive --new-file v2.1.43/linux/fs/proc/omirr.c linux/fs/proc/omirr.c
--- v2.1.43/linux/fs/proc/omirr.c Mon Jun 16 16:35:59 1997
+++ linux/fs/proc/omirr.c Sat Jul 5 20:53:22 1997
@@ -288,6 +288,7 @@


X NULL, /* mknod */
X NULL, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */

X NULL, /* bmap */
diff -u --recursive --new-file v2.1.43/linux/fs/proc/openpromfs.c linux/fs/proc/openpromfs.c
--- v2.1.43/linux/fs/proc/openpromfs.c Mon Jun 16 16:35:59 1997
+++ linux/fs/proc/openpromfs.c Sat Jul 5 20:53:22 1997
@@ -484,6 +484,7 @@


X NULL, /* mknod */
X NULL, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */
X NULL, /* bmap */

@@ -516,6 +517,7 @@


X NULL, /* mknod */
X NULL, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */
X NULL, /* bmap */

@@ -548,6 +550,7 @@


X NULL, /* mknod */
X NULL, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */

X NULL, /* bmap */
diff -u --recursive --new-file v2.1.43/linux/fs/proc/procfs_syms.c linux/fs/proc/procfs_syms.c
--- v2.1.43/linux/fs/proc/procfs_syms.c Mon Jun 16 16:35:59 1997
+++ linux/fs/proc/procfs_syms.c Thu Jun 26 12:33:39 1997
@@ -38,7 +38,7 @@
X
X static struct file_system_type proc_fs_type = {
X "proc",
- FS_NO_DCACHE,
+ 0 /* FS_NO_DCACHE doesn't work correctly */,
X proc_read_super,
X NULL
X };
diff -u --recursive --new-file v2.1.43/linux/fs/proc/root.c linux/fs/proc/root.c
--- v2.1.43/linux/fs/proc/root.c Mon Jun 16 16:35:59 1997
+++ linux/fs/proc/root.c Mon Jul 7 13:11:02 1997
@@ -24,7 +24,7 @@
X #define FIRST_PROCESS_ENTRY 256
X
X static int proc_root_readdir(struct inode *, struct file *, void *, filldir_t);
-static int proc_root_lookup(struct inode *,const char *,int,struct inode **);
+static int proc_root_lookup(struct inode *,struct qstr *,struct inode **);
X
X static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8] = {0};
X
@@ -64,6 +64,7 @@


X NULL, /* mknod */
X NULL, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */
X NULL, /* bmap */

@@ -104,6 +105,7 @@


X NULL, /* mknod */
X NULL, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */
X NULL, /* bmap */

@@ -149,14 +151,14 @@
X #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
X
X static int (*proc_openprom_defreaddir_ptr)(struct inode *, struct file *, void *, filldir_t);
-static int (*proc_openprom_deflookup_ptr)(struct inode *, const char *, int, struct inode **);
+static int (*proc_openprom_deflookup_ptr)(struct inode *, struct qstr *, struct inode **);
X void (*proc_openprom_use)(struct inode *, int) = 0;
X static struct openpromfs_dev *proc_openprom_devices = NULL;
X static ino_t proc_openpromdev_ino = PROC_OPENPROMD_FIRST;
X
X struct inode_operations *


X proc_openprom_register(int (*readdir)(struct inode *, struct file *, void *, filldir_t),
- int (*lookup)(struct inode *, const char *, int, struct inode **),
+ int (*lookup)(struct inode *, struct qstr *, struct inode **),
X void (*use)(struct inode *, int),

X struct openpromfs_dev ***devices)
X {
@@ -218,14 +220,13 @@
X }
X
X static int
-proc_openprom_deflookup(struct inode * dir,const char * name, int len,


- struct inode ** result)

+proc_openprom_deflookup(struct inode * dir, struct qstr *str, struct inode ** result)
X {
X request_module("openpromfs");
X if (proc_openprom_inode_operations.lookup !=
X proc_openprom_deflookup)
X return proc_openprom_inode_operations.lookup
- (dir, name, len, result);
+ (dir, str, result);
X iput(dir);
X return -ENOENT;
X }
@@ -264,6 +265,7 @@


X NULL, /* mknod */
X NULL, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */
X NULL, /* bmap */

@@ -350,7 +352,6 @@
X int len;
X char tmp[30];
X
- iput(inode);
X len = sprintf(tmp, "%d", current->pid);
X if (buflen < len)
X len = buflen;
@@ -358,6 +359,15 @@


X return len;
X }
X

+static struct dentry * proc_self_follow_link(struct inode *inode, struct dentry *base)
+{
+ int len;
+ char tmp[30];
+
+ len = sprintf(tmp, "%d", current->pid);
+ return lookup_dentry(tmp, base, 1);
+}
+
X static struct inode_operations proc_self_inode_operations = {
X NULL, /* no file-ops */


X NULL, /* create */

@@ -370,6 +380,7 @@


X NULL, /* mknod */
X NULL, /* rename */

X proc_self_readlink, /* readlink */
+ proc_self_follow_link, /* follow_link */


X NULL, /* readpage */
X NULL, /* writepage */
X NULL, /* bmap */

@@ -612,90 +623,41 @@
X }
X
X
-int proc_match(int len,const char * name,struct proc_dir_entry * de)
-{
- if (!de || !de->low_ino)
- return 0;
- /* "" means "." ---> so paths like "/usr/lib//libc.a" work */
- if (!len && (de->name[0]=='.') && (de->name[1]=='\0'))
- return 1;
- if (de->namelen != len)
- return 0;
- return !memcmp(name, de->name, len);
-}
-
-int proc_lookup(struct inode * dir,const char * name, int len,


- struct inode ** result)

+int proc_lookup(struct inode * dir, struct qstr * str, struct inode ** result)
X {
X struct proc_dir_entry * de;
- int ino;


X
X *result = NULL;

- if (!dir || !S_ISDIR(dir->i_mode)) {
- iput(dir);
+ if (!dir || !S_ISDIR(dir->i_mode))
X return -ENOTDIR;
- }
X
X de = (struct proc_dir_entry *) dir->u.generic_ip;
- if (!de) {
- iput(dir);
+ if (!de)
X return -EINVAL;
- }
-
- /* Either remove this as soon as possible due to security problems,
- * or uncomment the root-only usage.
- */
-
- /* Allow generic inode lookups everywhere.
- * No other name in /proc must begin with a '['.
- */
- if(/*!current->uid &&*/ name[0] == '[')
- return proc_arbitrary_lookup(dir,name,len,result);
X
- /* Special case "." and "..": they aren't on the directory list */


- *result = dir;
- if (!len)
- return 0;
- if (name[0] == '.') {
- if (len == 1)
- return 0;
- if (name[1] == '.' && len == 2) {

- struct inode * inode;
- inode = proc_get_inode(dir->i_sb, de->parent->low_ino, de->parent);
- iput(dir);
- if (!inode)
+ *result = NULL;
+ for (de = de->subdir; de ; de = de->next) {
+ if (!de || !de->low_ino)
+ continue;
+ if (de->namelen != str->len)
+ continue;
+ if (!memcmp(str->name, de->name, str->len)) {
+ int ino = de->low_ino | (dir->i_ino & ~(0xffff));
+ if (!(*result = proc_get_inode(dir->i_sb, ino, de)))
X return -EINVAL;
- *result = inode;


X return 0;
X }
X }

-
- *result = NULL;
- for (de = de->subdir; de ; de = de->next) {
- if (proc_match(len, name, de))
- break;
- }
- if (!de) {
- iput(dir);
- return -ENOENT;
- }
-
- ino = de->low_ino | (dir->i_ino & ~(0xffff));
-
- if (!(*result = proc_get_inode(dir->i_sb, ino, de))) {
- iput(dir);
- return -EINVAL;
- }
- iput(dir);
- return 0;
+ return -ENOENT;
X }
X
-static int proc_root_lookup(struct inode * dir,const char * name, int len,


- struct inode ** result)

+static int proc_root_lookup(struct inode * dir,struct qstr *str, struct inode ** result)
X {
X unsigned int pid, c;
X int ino, retval;
X struct task_struct *p;
+ const char *name;
+ int len;
X
X atomic_inc(&dir->i_count);
X
@@ -710,13 +672,13 @@
X read_unlock(&tasklist_lock);
X }
X
- retval = proc_lookup(dir, name, len, result);
- if (retval != -ENOENT) {
- iput(dir);
+ retval = proc_lookup(dir, str, result);
+ if (retval != -ENOENT)
X return retval;
- }
X
X pid = 0;
+ name = str->name;
+ len = str->len;
X while (len-- > 0) {
X c = *name - '0';
X name++;
@@ -732,16 +694,12 @@
X }
X }
X p = find_task_by_pid(pid);
- if (!pid || !p) {
- iput(dir);
+ if (!pid || !p)
X return -ENOENT;
- }
+
X ino = (pid << 16) + PROC_PID_INO;
- if (!(*result = proc_get_inode(dir->i_sb, ino, &proc_pid))) {
- iput(dir);
+ if (!(*result = proc_get_inode(dir->i_sb, ino, &proc_pid)))
X return -EINVAL;
- }
- iput(dir);


X return 0;
X }
X

diff -u --recursive --new-file v2.1.43/linux/fs/proc/scsi.c linux/fs/proc/scsi.c
--- v2.1.43/linux/fs/proc/scsi.c Mon Jun 16 16:35:59 1997
+++ linux/fs/proc/scsi.c Sat Jul 5 20:53:22 1997
@@ -69,6 +69,7 @@


X NULL, /* mknod */
X NULL, /* rename */
X NULL, /* readlink */
+ NULL, /* follow_link */
X NULL, /* readpage */
X NULL, /* writepage */

X NULL, /* bmap */
diff -u --recursive --new-file v2.1.43/linux/fs/readdir.c linux/fs/readdir.c
--- v2.1.43/linux/fs/readdir.c Mon Jun 16 16:35:59 1997
+++ linux/fs/readdir.c Sun Jul 6 20:13:54 1997
@@ -1,35 +1,20 @@
X /*
- * fs/readdir.c
+ * linux/fs/readdir.c
X *
X * Copyright (C) 1995 Linus Torvalds


X */
X
-#include <linux/config.h>

X #include <linux/types.h>
X #include <linux/errno.h>
X #include <linux/stat.h>
X #include <linux/kernel.h>
X #include <linux/sched.h>
X #include <linux/mm.h>
-#ifdef CONFIG_TRANS_NAMES
-#include <linux/nametrans.h>
-#endif
-#include <linux/dalloc.h>
X #include <linux/smp.h>
X #include <linux/smp_lock.h>
X
X #include <asm/uaccess.h>
X
-/* [T.Schoebel-Theuer] I am assuming that directories never get too large.
- * The problem is that getdents() delivers d_offset's that can be used
- * for lseek() by the user, so I must encode the status information for
- * name translation and dcache baskets in the offset.
- * Note that the linux man page getdents(2) does not mention that
- * the d_offset is fs-specific and can be used for lseek().
- */
-#define BASKET_BIT (1<<30) /* 31 is already used by affs */
-#define TRANS_BIT (1<<29)
-
X /*
X * Traditional linux readdir() handling..
X *
@@ -50,9 +35,6 @@
X
X struct readdir_callback {
X struct old_linux_dirent * dirent;
- struct file * file;
- int translate;
- off_t oldoffset;
X int count;
X };
X
@@ -65,26 +47,11 @@
X return -EINVAL;
X buf->count++;
X dirent = buf->dirent;
- copy_to_user(dirent->d_name, name, namlen);
- put_user(0, dirent->d_name + namlen);
-#ifdef CONFIG_TRANS_NAMES
- if(!buf->translate) {
- char * cut;
-#ifdef CONFIG_TRANS_RESTRICT
- struct inode * inode = buf->file->f_inode;
- cut = testname(inode && inode->i_gid != CONFIG_TRANS_GID, dirent->d_name);
-#else
- cut = testname(1, dirent->d_name);
-#endif
- if(cut) {
- put_user(0, cut);
- buf->translate = 1;
- }
- }
-#endif
X put_user(ino, &dirent->d_ino);
X put_user(offset, &dirent->d_offset);
X put_user(namlen, &dirent->d_namlen);


+ copy_to_user(dirent->d_name, name, namlen);
+ put_user(0, dirent->d_name + namlen);

X return 0;
X }
X

@@ -93,7 +60,6 @@
X int error = -EBADF;
X struct file * file;
X struct readdir_callback buf;
- off_t oldpos;
X
X lock_kernel();
X if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
@@ -104,21 +70,11 @@
X error = verify_area(VERIFY_WRITE, dirent, sizeof(struct old_linux_dirent));
X if (error)
X goto out;
- oldpos = file->f_pos;
- buf.file = file;
- buf.dirent = dirent;
X buf.count = 0;
- buf.translate = 0;
- if(file->f_pos & TRANS_BIT) {
- file->f_pos &= ~TRANS_BIT;
- buf.translate = 1;
- }
+ buf.dirent = dirent;
X error = file->f_op->readdir(file->f_inode, file, &buf, fillonedir);
X if (error < 0)
X goto out;
- if(buf.translate) {
- file->f_pos = oldpos | TRANS_BIT;
- }
X error = buf.count;
X out:
X unlock_kernel();
@@ -139,11 +95,8 @@
X struct getdents_callback {
X struct linux_dirent * current_dir;
X struct linux_dirent * previous;
- struct file * file;
X int count;
- int error;
- int restricted;
- int do_preload;
+ int error;
X };
X
X static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
@@ -152,51 +105,18 @@
X struct getdents_callback * buf = (struct getdents_callback *) __buf;
X int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
X
- /* Do not touch buf->error any more if everything is ok! */


+ buf->error = -EINVAL; /* only used if we fail.. */

X if (reclen > buf->count)
- return (buf->error = -EINVAL);
-#ifdef CONFIG_DCACHE_PRELOAD
- if(buf->do_preload && (name[0] != '.' || namlen > 2)) {
- struct qstr qname = { name, namlen };
- struct inode * dir = buf->file->f_inode;
- d_entry_preliminary(dir->i_dentry, &qname, ino);
- }
-#endif


+ return -EINVAL;
+ dirent = buf->previous;
+ if (dirent)
+ put_user(offset, &dirent->d_off);

X dirent = buf->current_dir;
- copy_to_user(dirent->d_name, name, namlen);
- put_user(0, dirent->d_name + namlen);
-#ifdef CONFIG_TRANS_NAMES
- {
- char * cut;
-#ifdef CONFIG_TRANS_RESTRICT
- cut = testname(buf->restricted, dirent->d_name);
-#else
- cut = testname(1, dirent->d_name);
-#endif
- if(cut) {
- int newlen = (int)cut - (int)dirent->d_name;
- int newreclen = ROUND_UP(NAME_OFFSET(dirent) + newlen + 1);
- /* Either both must fit or none. This way we need
- * no status information in f_pos */
- if (reclen+newlen > buf->count)
- return -EINVAL;
- put_user(0, cut);
- put_user(ino, &dirent->d_ino);
- put_user(newreclen, &dirent->d_reclen);
- put_user(offset, &dirent->d_off);
- ((char *) dirent) += newreclen;
- buf->count -= newreclen;
- put_user(offset, &dirent->d_off);
- copy_to_user(dirent->d_name, name, namlen);
- put_user(0, dirent->d_name + namlen);
- }
- }
-#endif


+ buf->previous = dirent;

X put_user(ino, &dirent->d_ino);
X put_user(reclen, &dirent->d_reclen);
- if (buf->previous)
- put_user(buf->file->f_pos, &buf->previous->d_off);
- buf->previous = dirent;


+ copy_to_user(dirent->d_name, name, namlen);
+ put_user(0, dirent->d_name + namlen);

X ((char *) dirent) += reclen;
X buf->current_dir = dirent;
X buf->count -= reclen;
@@ -206,6 +126,7 @@
X asmlinkage int sys_getdents(unsigned int fd, void * dirent, unsigned int count)
X {
X struct file * file;
+ struct linux_dirent * lastdirent;
X struct getdents_callback buf;
X int error = -EBADF;
X
@@ -218,72 +139,18 @@
X error = verify_area(VERIFY_WRITE, dirent, count);
X if (error)
X goto out;
- buf.file = file;
X buf.current_dir = (struct linux_dirent *) dirent;
X buf.previous = NULL;
X buf.count = count;
X buf.error = 0;
- buf.restricted = 0;
-#ifdef CONFIG_TRANS_RESTRICT
- buf.restricted = file->f_inode && file->f_inode->i_gid != CONFIG_TRANS_GID;
-#endif
- buf.do_preload = 0;
-#ifdef CONFIG_DCACHE_PRELOAD
- if(file->f_inode && file->f_inode->i_dentry &&
- !(file->f_inode->i_sb->s_type->fs_flags & (FS_NO_DCACHE|FS_NO_PRELIM)) &&
- !(file->f_inode->i_dentry->d_flag & D_PRELOADED))
- buf.do_preload = 1;
-#endif
-
- if(!(file->f_pos & BASKET_BIT)) {
- int oldcount;
- do {
- oldcount = buf.count;
- error = file->f_op->readdir(file->f_inode, file, &buf, filldir);
- if (error < 0)
- goto out;
- } while(!buf.error && buf.count != oldcount);
- }
- if(!buf.error) {
- int nr = 0;
- struct dentry * list = file->f_inode ?
- d_basket(file->f_inode->i_dentry) : NULL;
- struct dentry * ptr = list;
-#ifdef CONFIG_DCACHE_PRELOAD
- if(buf.do_preload) {
- buf.do_preload = 0;
- file->f_inode->i_dentry->d_flag |= D_PRELOADED;
- }
-#endif
- if(ptr) {
- if(!(file->f_pos & BASKET_BIT))
- file->f_pos = BASKET_BIT;
- do {
- struct dentry * next = ptr->d_basket_next;


- struct inode * inode;

- /* vfs_locks() are missing here */
- inode = d_inode(&ptr);
- if(inode) {
- nr++;
- if(nr > (file->f_pos & ~BASKET_BIT)) {
- int err = filldir(&buf, ptr->d_name,
- ptr->d_len,
- file->f_pos,
- inode->i_ino);
- if(err)
- break;
- file->f_pos++;
- }
- iput(inode);
- }
- ptr = next;
- } while(ptr != list);
- }
- }
- if (!buf.previous) {
+ error = file->f_op->readdir(file->f_inode, file, &buf, filldir);
+ if (error < 0)
+ goto out;


+ lastdirent = buf.previous;
+ if (!lastdirent) {

X error = buf.error;
X } else {
- put_user(file->f_pos, &buf.previous->d_off);


+ put_user(file->f_pos, &lastdirent->d_off);

X error = count - buf.count;
X }
X out:
diff -u --recursive --new-file v2.1.43/linux/fs/romfs/inode.c linux/fs/romfs/inode.c
--- v2.1.43/linux/fs/romfs/inode.c Mon Jun 16 16:35:59 1997
+++ linux/fs/romfs/inode.c Thu Jun 26 12:33:39 1997
@@ -584,7 +584,7 @@
X
X static struct file_system_type romfs_fs_type = {
X "romfs",
- (FS_REQUIRES_DEV | FS_NO_DCACHE), /* Can dcache be used? */
+ FS_REQUIRES_DEV,
X romfs_read_super,
X NULL
X };
diff -u --recursive --new-file v2.1.43/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c
--- v2.1.43/linux/fs/smbfs/inode.c Mon Jun 16 16:35:59 1997
+++ linux/fs/smbfs/inode.c Thu Jun 26 12:33:39 1997
@@ -431,7 +431,7 @@
X
X static struct file_system_type smb_fs_type = {
X "smbfs",
- FS_NO_DCACHE,
+ 0 /* FS_NO_DCACHE doesn't work correctly */,
X smb_read_super,
X NULL
X };
diff -u --recursive --new-file v2.1.43/linux/fs/stat.c linux/fs/stat.c
--- v2.1.43/linux/fs/stat.c Mon Jun 16 16:35:59 1997
+++ linux/fs/stat.c Sun Jul 6 21:31:52 1997
@@ -127,7 +127,7 @@
X int error;
X
X lock_kernel();
- error = namei(NAM_FOLLOW_LINK, filename, &inode);
+ error = namei(filename, &inode);
X if (error)
X goto out;
X if ((error = do_revalidate(inode)) == 0)
@@ -145,7 +145,7 @@
X int error;
X
X lock_kernel();
- error = namei(NAM_FOLLOW_LINK, filename, &inode);
+ error = namei(filename, &inode);
X if (error)
X goto out;
X if ((error = do_revalidate(inode)) == 0)
@@ -168,7 +168,7 @@
X int error;
X
X lock_kernel();
- error = namei(NAM_FOLLOW_TRAILSLASH, filename, &inode);
+ error = lnamei(filename, &inode);
X if (error)
X goto out;
X if ((error = do_revalidate(inode)) == 0)
@@ -187,7 +187,7 @@
X int error;
X
X lock_kernel();
- error = namei(NAM_FOLLOW_TRAILSLASH, filename, &inode);
+ error = lnamei(filename, &inode);
X if (error)
X goto out;
X if ((error = do_revalidate(inode)) == 0)
@@ -241,15 +241,13 @@
X asmlinkage int sys_readlink(const char * path, char * buf, int bufsiz)
X {
X struct inode * inode;
- int error = -EINVAL;
+ int error;
X
- lock_kernel();
X if (bufsiz <= 0)
- goto out;
- error = verify_area(VERIFY_WRITE,buf,bufsiz);
- if (error)
- goto out;
- error = namei(NAM_FOLLOW_TRAILSLASH, path, &inode);
+ return -EINVAL;
+
+ lock_kernel();
+ error = lnamei(path, &inode);
X if (error)
X goto out;
X error = -EINVAL;
@@ -263,6 +261,7 @@
X inode->i_dirt = 1;
X }
X error = inode->i_op->readlink(inode,buf,bufsiz);
+ iput(inode);
X out:
X unlock_kernel();
X return error;
diff -u --recursive --new-file v2.1.43/linux/fs/super.c linux/fs/super.c
--- v2.1.43/linux/fs/super.c Mon Jun 16 16:35:59 1997
+++ linux/fs/super.c Sun Jul 6 20:13:54 1997
@@ -465,7 +465,7 @@
X }
X if (!(sb = get_super(dev)))
X return;
- if (sb->s_covered) {
+ if (sb->s_root != sb->s_root->d_mounts) {
X printk("VFS: Mounted device %s - tssk, tssk\n",
X kdevname(dev));
X return;
@@ -535,7 +535,6 @@
X return NULL;
X }
X s->s_dev = dev;
- s->s_covered = NULL;
X s->s_rd_only = 0;
X s->s_dirt = 0;
X s->s_type = type;
@@ -570,6 +569,30 @@
X kdevname(dev));
X }
X
+static void d_umount(struct dentry *dentry)
+{
+ struct dentry * covers = dentry->d_covers;
+
+ if (covers == dentry) {
+ printk("VFS: unmount - covers == dentry?\n");
+ return;
+ }
+ covers->d_mounts = covers;
+ dentry->d_covers = dentry;
+ dput(covers);
+ dput(dentry);
+}
+
+static void d_mount(struct dentry *covers, struct dentry *dentry)
+{
+ if (covers->d_mounts != covers) {
+ printk("VFS: mount - already mounted\n");
+ return;
+ }
+ covers->d_mounts = dentry;
+ dentry->d_covers = covers;
+}
+
X static int do_umount(kdev_t dev,int unmount_root)
X {
X struct super_block * sb;
@@ -597,28 +620,26 @@
X }
X return 0;
X }
- if (!(sb=get_super(dev)) || !(sb->s_covered))
+ sb=get_super(dev);
+ if (!sb)
X return -ENOENT;
- if (!sb->s_covered->i_mount)
- printk("VFS: umount(%s): mounted inode has i_mount=NULL\n",
- kdevname(dev));
- while(sb->s_ibasket)
- free_ibasket(sb);
- if(sb->s_mounted->i_dentry)
- d_del(sb->s_mounted->i_dentry, D_NO_CLEAR_INODE);
+
X /*
X * Before checking if the filesystem is still busy make sure the kernel
X * doesn't hold any quotafiles open on that device. If the umount fails
X * too bad there are no quotas running anymore. Turn them on again by hand.
X */
X quota_off(dev, -1);
- if (!fs_may_umount(dev, sb->s_mounted))
+ if (!fs_may_umount(dev, sb->s_root))
X return -EBUSY;
- sb->s_covered->i_mount = NULL;
- iput(sb->s_covered);
- sb->s_covered = NULL;
- iput(sb->s_mounted);
- sb->s_mounted = NULL;
+
+ /* Clear up the dcache tree. This should be cleaner.. */
+ if (sb->s_root) {
+ d_umount(sb->s_root);
+ d_delete(sb->s_root);
+ }
+
+ sb->s_root = NULL;
X if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
X sb->s_op->write_super(sb);
X put_super(dev);
@@ -647,12 +668,7 @@
X lock_kernel();
X if (!suser())
X goto out;
- retval = namei(NAM_FOLLOW_LINK, name, &inode);
- if (retval) {
- retval = namei(NAM_FOLLOW_TRAILSLASH, name, &inode);
- if (retval)
- goto out;
- }


+ retval = namei(name, &inode);

X if (S_ISBLK(inode->i_mode)) {
X dev = inode->i_rdev;
X retval = -EACCES;
@@ -662,7 +678,7 @@
X }
X } else {
X retval = -EINVAL;
- if (!inode->i_sb || inode != inode->i_sb->s_mounted) {
+ if (!inode->i_sb || inode != inode->i_sb->s_root->d_inode) {
X iput(inode);
X goto out;
X }
@@ -715,45 +731,44 @@
X
X int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
X {
- struct inode * dir_i = NULL;
+ struct dentry * dir_d = NULL;
X struct super_block * sb;
X struct vfsmount *vfsmnt;
X int error;
- int override = 0;
-
- if(dir_name) {
- char c;
X
- get_user(c, dir_name);
- override = (c == '!');
- }
X if (!(flags & MS_RDONLY) && dev && is_read_only(dev))
X return -EACCES;
X /*flags |= MS_RDONLY;*/
- if(override)
- dir_name++;
- error = namei(NAM_FOLLOW_LINK, dir_name, &dir_i);
- if (error)
+
+ dir_d = lookup_dentry(dir_name, NULL, 1);
+ error = PTR_ERR(dir_d);
+ if (IS_ERR(dir_d))
X return error;
- if (!override && (atomic_read(&dir_i->i_count) != 1 || dir_i->i_mount)) {
- iput(dir_i);
+
+ if (dir_d->d_flag & D_NEGATIVE) {
+ dput(dir_d);
+ return -ENOENT;
+ }
+
+ if (dir_d->d_covers != dir_d) {
+ dput(dir_d);
X return -EBUSY;
X }
- if (!S_ISDIR(dir_i->i_mode)) {
- iput(dir_i);
+ if (!S_ISDIR(dir_d->d_inode->i_mode)) {
+ dput(dir_d);
X return -ENOTDIR;
X }
- if (!fs_may_mount(dev) && !override) {
- iput(dir_i);
+ if (!fs_may_mount(dev)) {
+ dput(dir_d);
X return -EBUSY;
X }
X sb = read_super(dev,type,flags,data,0);
X if (!sb) {
- iput(dir_i);
+ dput(dir_d);
X return -EINVAL;
X }
- if (sb->s_covered) {
- iput(dir_i);
+ if (sb->s_root->d_covers != sb->s_root) {
+ dput(dir_d);
X return -EBUSY;
X }
X vfsmnt = add_vfsmnt(dev, dev_name, dir_name);
@@ -761,25 +776,8 @@
X vfsmnt->mnt_sb = sb;
X vfsmnt->mnt_flags = flags;
X }
- {
- struct dentry * old = dir_i->i_dentry;
- struct dentry * new;
- vfs_lock();
- new = d_alloc(old->d_parent, old->d_len, 1);
- if(new) {
- struct qstr copy = { old->d_name, old->d_len };
- d_add(new, sb->s_mounted, &copy, D_DUPLICATE);
- vfs_unlock();
- } else {
- printk("VFS: cannot setup dentry for mount\n");
- iput(dir_i);
- return -ENOMEM;
- }
- vfs_unlock();
- }
- sb->s_covered = dir_i;
- dir_i->i_mount = sb->s_mounted;
- return 0; /* we don't iput(dir_i) - see umount */
+ d_mount(dir_d, sb->s_root);
+ return 0; /* we don't dput(dir) - see umount */
X }
X
X
@@ -820,10 +818,10 @@
X struct inode *dir_i;
X int retval;
X
- retval = namei(NAM_FOLLOW_LINK, dir, &dir_i);
+ retval = namei(dir, &dir_i);


X if (retval)
X return retval;

- if (dir_i != dir_i->i_sb->s_mounted) {
+ if (dir_i != dir_i->i_sb->s_root->d_inode) {
X iput(dir_i);
X return -EINVAL;
X }
@@ -912,7 +910,7 @@
X t = fstype->name;
X fops = NULL;
X if ((fstype->fs_flags & FS_REQUIRES_DEV)) {
- retval = namei(NAM_FOLLOW_LINK, dev_name, &inode);
+ retval = namei(dev_name, &inode);


X if (retval)
X goto out;

X retval = -ENOTBLK;
@@ -982,7 +980,7 @@
X struct file_system_type * fs_type;
X struct super_block * sb;
X struct vfsmount *vfsmnt;
- struct inode * inode, * d_inode = NULL;
+ struct inode * d_inode = NULL;
X struct file filp;
X int retval;
X
@@ -1001,15 +999,11 @@
X sb->s_dev = get_unnamed_dev();
X sb->s_flags = root_mountflags & ~MS_RDONLY;
X if (nfs_root_mount(sb) >= 0) {
- inode = sb->s_mounted;
- atomic_add(3, &inode->i_count);
- sb->s_covered = inode;
X sb->s_rd_only = 0;
X sb->s_dirt = 0;
X sb->s_type = fs_type;
- current->fs->pwd = inode;
- current->fs->root = inode;
- (void)d_alloc_root(inode);
+ current->fs->root = dget(sb->s_root);
+ current->fs->pwd = dget(sb->s_root);
X ROOT_DEV = sb->s_dev;
X printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
X vfsmnt = add_vfsmnt(ROOT_DEV, "/dev/root", "/");
@@ -1066,15 +1060,9 @@
X continue;
X sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
X if (sb) {
- inode = sb->s_mounted;
-
- /* NOTE! it is logically used 4 times, not 1 */
- atomic_add(3, &inode->i_count);
- sb->s_covered = inode;
X sb->s_flags = root_mountflags;
- current->fs->pwd = inode;
- current->fs->root = inode;
- (void)d_alloc_root(inode);
+ current->fs->root = dget(sb->s_root);
+ current->fs->pwd = dget(sb->s_root);
X printk ("VFS: Mounted root (%s filesystem)%s.\n",
X fs_type->name,
X (sb->s_flags & MS_RDONLY) ? " readonly" : "");
@@ -1121,7 +1109,7 @@
X do_mount_root();
X old_fs = get_fs();
X set_fs(get_ds());
- error = namei(NAM_FOLLOW_LINK, put_old, &inode);
+ error = namei(put_old, &inode);
X if (error) inode = NULL;
X set_fs(old_fs);
X if (!error && (atomic_read(&inode->i_count) != 1 || inode->i_mount))
diff -u --recursive --new-file v2.1.43/linux/include/asm-alpha/ioctls.h linux/include/asm-alpha/ioctls.h
--- v2.1.43/linux/include/asm-alpha/ioctls.h Sun Mar 24 02:09:36 1996
+++ linux/include/asm-alpha/ioctls.h Thu Jun 26 12:33:39 1997
@@ -83,6 +83,8 @@
X #define TIOCGETD 0x5424
X #define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
X #define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
+#define TIOCSBRK 0x5427 /* BSD compatibility */
+#define TIOCCBRK 0x5428 /* BSD compatibility */
X
X #define TIOCSERCONFIG 0x5453
X #define TIOCSERGWILD 0x5454
diff -u --recursive --new-file v2.1.43/linux/include/asm-alpha/pgtable.h linux/include/asm-alpha/pgtable.h
--- v2.1.43/linux/include/asm-alpha/pgtable.h Sat Dec 21 04:24:02 1996
+++ linux/include/asm-alpha/pgtable.h Mon Jul 7 08:18:55 1997
@@ -517,4 +517,7 @@
X #define SWP_OFFSET(entry) ((entry) >> 40)
X #define SWP_ENTRY(type,offset) pte_val(mk_swap_pte((type),(offset)))
X
+#define module_map vmalloc
+#define module_unmap vfree
+
X #endif /* _ALPHA_PGTABLE_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-i386/ioctls.h linux/include/asm-i386/ioctls.h
--- v2.1.43/linux/include/asm-i386/ioctls.h Wed Jul 17 05:10:03 1996
+++ linux/include/asm-i386/ioctls.h Thu Jun 26 12:33:39 1997
@@ -44,6 +44,9 @@
X #define TIOCGETD 0x5424
X #define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
X #define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
+#define TIOCSBRK 0x5427 /* BSD compatibility */
+#define TIOCCBRK 0x5428 /* BSD compatibility */
+
X #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
X #define FIOCLEX 0x5451
X #define FIOASYNC 0x5452
diff -u --recursive --new-file v2.1.43/linux/include/asm-i386/pgtable.h linux/include/asm-i386/pgtable.h
--- v2.1.43/linux/include/asm-i386/pgtable.h Thu Jun 12 15:28:33 1997
+++ linux/include/asm-i386/pgtable.h Mon Jul 7 16:02:01 1997
@@ -491,4 +491,7 @@
X #define SWP_OFFSET(entry) ((entry) >> 8)
X #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
X
+#define module_map vmalloc
+#define module_unmap vfree
+
X #endif /* _I386_PAGE_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- v2.1.43/linux/include/asm-i386/unistd.h Thu May 29 21:53:08 1997
+++ linux/include/asm-i386/unistd.h Thu Jun 26 12:33:39 1997
@@ -175,6 +175,8 @@
X #define __NR_query_module 167
X #define __NR_poll 168
X #define __NR_nfsservctl 169
+#define __NR_setresgid 170
+#define __NR_getresgid 171
X
X /* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
X
diff -u --recursive --new-file v2.1.43/linux/include/asm-m68k/hardirq.h linux/include/asm-m68k/hardirq.h
--- v2.1.43/linux/include/asm-m68k/hardirq.h Sat May 24 09:10:24 1997
+++ linux/include/asm-m68k/hardirq.h Mon Jul 7 08:18:55 1997
@@ -12,4 +12,6 @@
X #define hardirq_enter(cpu) (local_irq_count[cpu]++)
X #define hardirq_exit(cpu) (local_irq_count[cpu]--)
X

+#define synchronize_irq() do { } while (0)
+

X #endif
diff -u --recursive --new-file v2.1.43/linux/include/asm-m68k/ioctls.h linux/include/asm-m68k/ioctls.h
--- v2.1.43/linux/include/asm-m68k/ioctls.h Fri Apr 5 03:08:13 1996
+++ linux/include/asm-m68k/ioctls.h Thu Jun 26 12:33:39 1997
@@ -44,6 +44,9 @@
X #define TIOCGETD 0x5424
X #define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
X #define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
+#define TIOCSBRK 0x5427 /* BSD compatibility */
+#define TIOCCBRK 0x5428 /* BSD compatibility */
+
X #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
X #define FIOCLEX 0x5451
X #define FIOASYNC 0x5452
diff -u --recursive --new-file v2.1.43/linux/include/asm-m68k/pgtable.h linux/include/asm-m68k/pgtable.h
--- v2.1.43/linux/include/asm-m68k/pgtable.h Sat May 24 09:10:24 1997
+++ linux/include/asm-m68k/pgtable.h Mon Jul 7 08:18:55 1997
@@ -95,38 +95,23 @@
X
X extern inline void flush_cache_mm(struct mm_struct *mm)
X {
-#if FLUSH_VIRTUAL_CACHE_040
- if (mm == current->mm) __flush_cache_all();
-#else
- if (mm == current->mm) __flush_cache_030();
-#endif
+ if (mm == current->mm)
+ __flush_cache_030();
X }
X
X extern inline void flush_cache_range(struct mm_struct *mm,
X unsigned long start,
X unsigned long end)
X {
- if (mm == current->mm){
-#if FLUSH_VIRTUAL_CACHE_040
- if (CPU_IS_040_OR_060)
- cache_push_v(start, end-start);
- else
-#endif
+ if (mm == current->mm)
X __flush_cache_030();
- }
X }
X
X extern inline void flush_cache_page(struct vm_area_struct *vma,
X unsigned long vmaddr)
X {
- if (vma->vm_mm == current->mm){
-#if FLUSH_VIRTUAL_CACHE_040
- if (CPU_IS_040_OR_060)
- cache_push_v(vmaddr, PAGE_SIZE);
- else
-#endif
+ if (vma->vm_mm == current->mm)
X __flush_cache_030();
- }
X }
X
X /* Push the page at kernel virtual address and clear the icache */
@@ -782,5 +767,8 @@
X #endif
X
X #endif /* __ASSEMBLY__ */
+
+#define module_map vmalloc
+#define module_unmap vfree
X
X #endif /* _M68K_PGTABLE_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/addrspace.h linux/include/asm-mips/addrspace.h
--- v2.1.43/linux/include/asm-mips/addrspace.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/addrspace.h Thu Jun 26 12:33:39 1997
@@ -0,0 +1,52 @@


+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ *

+ * Defitions for the address spaces of the MIPS CPUs.
+ */
+#ifndef __ASM_MIPS_ADDRSPACE_H
+#define __ASM_MIPS_ADDRSPACE_H
+
+/*
+ * Memory segments (32bit kernel mode addresses)
+ */
+#define KUSEG 0x00000000
+#define KSEG0 0x80000000
+#define KSEG1 0xa0000000
+#define KSEG2 0xc0000000
+#define KSEG3 0xe0000000
+
+/*
+ * Returns the kernel segment base of a given address
+ */
+#define KSEGX(a) (((unsigned long)(a)) & 0xe0000000)
+
+/*
+ * Returns the physical address of a KSEG0/KSEG1 address
+ */
+#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff)
+
+/*
+ * Map an address to a certain kernel segment
+ */
+#define KSEG0ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG0))
+#define KSEG1ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG1))
+#define KSEG2ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG2))
+#define KSEG3ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG3))
+
+/*
+ * Memory segments (64bit kernel mode addresses)
+ */
+#define XKUSEG 0x0000000000000000
+#define XKSSEG 0x4000000000000000
+#define XKPHYS 0x8000000000000000
+#define XKSEG 0xc000000000000000
+#define CKSEG0 0xffffffff80000000
+#define CKSEG1 0xffffffffa0000000
+#define CKSSEG 0xffffffffc0000000
+#define CKSEG3 0xffffffffe0000000
+
+#endif /* __ASM_MIPS_ADDRSPACE_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/asm.h linux/include/asm-mips/asm.h
--- v2.1.43/linux/include/asm-mips/asm.h Mon Dec 25 20:03:01 1995
+++ linux/include/asm-mips/asm.h Thu Jun 26 12:33:39 1997
@@ -5,7 +5,7 @@


X * License. See the file "COPYING" in the main directory of this archive
X * for more details.
X *

- * Copyright (C) 1995 by Ralf Baechle
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
X *
X * Some useful macros for MIPS assembler code
X *
@@ -16,9 +16,7 @@
X #ifndef __ASM_ASM_H
X #define __ASM_ASM_H
X
-#include <linux/config.h>
-#include <asm/regdef.h>
-#include <asm/fpregdef.h>
+#include <asm/sgidefs.h>
X
X #ifndef CAT
X #ifdef __STDC__
@@ -30,32 +28,14 @@
X #endif
X
X /*
- * Macros to handle different pointer sizes for 32/64-bit code
+ * Macros to handle different pointer/register sizes for 32/64-bit code
+ *
+ * 64 bit address space isn't used yet, so we may use the R3000 32 bit
+ * defines for now.
X */
-#if __mips == 3
-#define PTR .quad
-#define PTRSIZE 8
-#define PTRLOG 3
-#define lp ld
-#else
X #define PTR .word
X #define PTRSIZE 4
X #define PTRLOG 2
-#define lp lw
-#endif
-
-/*
- * ELF specific declarations
- */
-#ifdef __ELF__
-#define TYPE(symbol,_type) \
- .type symbol,@_type
-#define SIZE(symbol,_size) \
- .size symbol,_size
-#else
-#define TYPE(symbol,type)
-#define SIZE(symbol,size)
-#endif
X
X /*
X * PIC specific declarations
@@ -63,11 +43,11 @@
X */
X #ifdef __PIC__
X #define CPRESTORE(register) \
- .cprestore register
+ .cprestore register
X #define CPADD(register) \
- .cpadd register
+ .cpadd register
X #define CPLOAD(register) \
- .cpload register
+ .cpload register
X #else
X #define CPRESTORE(register)
X #define CPADD(register)
@@ -78,64 +58,67 @@
X * LEAF - declare leaf routine
X */
X #define LEAF(symbol) \
- .globl symbol; \
- .align 2; \
- TYPE(symbol,function); \
- .ent symbol,0; \
-symbol: .frame sp,0,ra
+ .globl symbol; \
+ .align 2; \
+ .type symbol,@function; \
+ .ent symbol,0; \
+symbol: .frame sp,0,ra
X
X /*
X * NESTED - declare nested routine entry point
X */
X #define NESTED(symbol, framesize, rpc) \
- .globl symbol; \
- .align 2; \
- TYPE(symbol,function); \
- .ent symbol,0; \
-symbol: .frame sp, framesize, rpc
+ .globl symbol; \
+ .align 2; \
+ .type symbol,@function; \
+ .ent symbol,0; \
+symbol: .frame sp, framesize, rpc
X
X /*
X * END - mark end of function
X */
X #define END(function) \
- .end function; \
- SIZE(function,.-function)
+ .end function; \
+ .size function,.-function
X
X /*
X * EXPORT - export definition of symbol
X */
X #define EXPORT(symbol) \
- .globl symbol; \
+ .globl symbol; \
X symbol:
X
X /*
X * ABS - export absolute symbol
X */
X #define ABS(symbol,value) \
- .globl symbol; \
-symbol = value
+ .globl symbol; \
+symbol = value
X
X #define PANIC(msg) \
- la a0,8f; \
- jal panic; \
- nop; \
-9: b 9b; \
- nop; \
- TEXT(msg)
+ .set push; \
+ .set reorder; \
+ la a0,8f; \
+ jal panic; \
+9: b 9b; \
+ .set pop; \
+ TEXT(msg)
X
X /*
X * Print formated string
X */
X #define PRINT(string) \
- la a0,8f; \
- jal printk; \
- nop; \
- TEXT(string)
+ .set push; \
+ .set reorder; \
+ la a0,8f; \
+ jal printk; \
+ .set pop; \
+ TEXT(string)
X
X #define TEXT(msg) \
- .data; \
-8: .asciiz msg; \
- .text
+ .data; \
+8: .asciiz msg; \
+ .previous;
X
X /*
X * Build text tables
@@ -143,68 +126,19 @@
X #define TTABLE(string) \
X .text; \
X .word 1f; \
+ .previous; \
X .data; \
X 1: .asciz string; \
- .text;
+ .previous
X
X /*
- * Move to kernel mode and disable interrupts
- * Set cp0 enable bit as sign that we're running on the kernel stack
- * Use with .set noat!
- * Note that the mtc0 will be effective on R4000 pipeline stage 7. This
- * means that another three instructions will be executed with interrupts
- * disabled.
- */
-#define CLI \
- mfc0 AT,CP0_STATUS; \
- li t0,ST0_CU0|0x1f; \
- or AT,t0; \
- xori AT,0x1f; \
- mtc0 AT,CP0_STATUS; \
-
-/*
- * Move to kernel mode and enable interrupts
- * Set cp0 enable bit as sign that we're running on the kernel stack
- * Use with .set noat!
- * Note that the mtc0 will be effective on R4000 pipeline stage 7. This
- * means that another three instructions will be executed with interrupts
- * disabled. Arch/mips/kernel/r4xx0.S makes use of this fact.
- */
-#define STI \
- mfc0 AT,CP0_STATUS; \
- li t0,ST0_CU0|0x1f; \
- or AT,t0; \
- xori AT,0x1e; \
- mtc0 AT,CP0_STATUS; \
-
-/*
- * Special nop to fill load delay slots
- */
-#ifndef __R4000__
-#define NOP nop
-#else
-#define NOP
-#endif
-
-/*
- * Return from exception
- */
-#if defined (CONFIG_CPU_R3000)
-#define ERET rfe
-#elif defined (CONFIG_CPU_R4X00) || defined (CONFIG_CPU_R4600)
-#define ERET \
- .set mips3; \
- eret; \
- .set mips0
-#else
-#error "Implement ERET macro!"
-#endif
-
-/*
- * R8000/R10000 (MIPS ISA IV) pref instruction.
+ * MIPS IV pref instruction.
X * Use with .set noreorder only!
+ *
+ * MIPS IV implementations are free to treat this as a nop. The R5000
+ * is one of them. So we should have an option not to use this instruction.
X */
-#if defined (CONFIG_CPU_R8000) || defined(CONFIG_CPU_R10000)
+#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
X #define PREF(hint,addr) \
X pref hint,addr
X #define PREFX(hint,addr) \
@@ -215,34 +149,226 @@
X #endif
X
X /*
- * R8000/R10000 (MIPS ISA IV) movn/movz instructions and
- * equivalents for old CPUs. Use with .set noreorder only!
+ * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
X */
-#if defined (CONFIG_CPU_R8000) || defined (CONFIG_CPU_R10000)
+#if _MIPS_ISA == _MIPS_ISA_MIPS1
X #define MOVN(rd,rs,rt) \
- movn rd,rs,rt
-#define MOVZ(rd,rs,rt) \
- movz rd,rs,rt
-#elif defined (CONFIG_CPU_R4000) || defined (CONFIG_CPU_R6000)
-#define MOVN(rd,rs,rt) \
- bnezl rt,9f \
- move rd,rs \
+ .set push; \
+ .set reorder; \
+ beqz rt,9f; \
+ move rd,rs; \
+ .set pop; \
X 9:
X #define MOVZ(rd,rs,rt) \
- beqzl rt,9f \
- movz rd,rt \
+ .set push; \
+ .set reorder; \
+ bnez rt,9f; \
+ move rd,rt; \
+ .set pop; \
X 9:
-#else /* R2000, R3000 */
+#endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */


+#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)

X #define MOVN(rd,rs,rt) \
- beqz rt,9f \
- nop \
- move rd,rs \


+ .set push; \
+ .set noreorder; \

+ bnezl rt,9f; \
+ move rd,rs; \
+ .set pop; \
X 9:
X #define MOVZ(rd,rs,rt) \
- bneqz rt,9f \
- nop \
- movz rd,rt \


+ .set push; \
+ .set noreorder; \

+ beqzl rt,9f; \
+ movz rd,rs; \
+ .set pop; \
X 9:
+#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)
+#define MOVN(rd,rs,rt) \
+ movn rd,rs,rt
+#define MOVZ(rd,rs,rt) \
+ movz rd,rs,rt
+#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5) */
+
+/*
+ * Stack alignment
+ */


+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)

+#define ALSZ 7
+#define ALMASK ~7
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS5)
+#define ALSZ 15
+#define ALMASK ~15
+#endif
+
+/*
+ * Size of a register
+ */
+#ifdef __mips64
+#define SZREG 8
+#else
+#define SZREG 4
+#endif
+
+/*
+ * Use the following macros in assemblercode to load/store registers,
+ * pointers etc.
+ */


+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)

+#define REG_S sw
+#define REG_L lw
+#define PTR_SUBU subu
+#define PTR_ADDU addu
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS5)
+#define REG_S sd
+#define REG_L ld
+/* We still live in a 32 bit address space ... */
+#define PTR_SUBU subu
+#define PTR_ADDU addu
+#endif
+
+/*
+ * How to add/sub/load/store/shift C int variables.
+ */
+#if (_MIPS_SZINT == 32)
+#define INT_ADD add
+#define INT_ADDI addi
+#define INT_ADDU addu
+#define INT_ADDIU addiu
+#define INT_SUB add
+#define INT_SUBI subi
+#define INT_SUBU subu
+#define INT_SUBIU subu
+#define INT_L lw
+#define INT_S sw
+#define LONG_SLL sll
+#define LONG_SLLV sllv
+#define LONG_SRL srl
+#define LONG_SRLV srlv
+#define LONG_SRA sra
+#define LONG_SRAV srav
+#endif
+
+#if (_MIPS_SZINT == 64)
+#define INT_ADD dadd
+#define INT_ADDI daddi
+#define INT_ADDU daddu
+#define INT_ADDIU daddiu
+#define INT_SUB dadd
+#define INT_SUBI dsubi
+#define INT_SUBU dsubu
+#define INT_SUBIU dsubu
+#define INT_L ld
+#define INT_S sd
+#define LONG_SLL dsll
+#define LONG_SLLV dsllv
+#define LONG_SRL dsrl
+#define LONG_SRLV dsrlv
+#define LONG_SRA dsra
+#define LONG_SRAV dsrav
+#endif
+
+/*
+ * How to add/sub/load/store/shift C long variables.
+ */
+#if (_MIPS_SZLONG == 32)
+#define LONG_ADD add
+#define LONG_ADDI addi
+#define LONG_ADDU addu
+#define LONG_ADDIU addiu
+#define LONG_SUB add
+#define LONG_SUBI subi
+#define LONG_SUBU subu
+#define LONG_SUBIU subu
+#define LONG_L lw
+#define LONG_S sw
+#define LONG_SLL sll
+#define LONG_SLLV sllv
+#define LONG_SRL srl
+#define LONG_SRLV srlv
+#define LONG_SRA sra
+#define LONG_SRAV srav
+#endif
+
+#if (_MIPS_SZLONG == 64)
+#define LONG_ADD dadd
+#define LONG_ADDI daddi
+#define LONG_ADDU daddu
+#define LONG_ADDIU daddiu
+#define LONG_SUB dadd
+#define LONG_SUBI dsubi
+#define LONG_SUBU dsubu
+#define LONG_SUBIU dsubu
+#define LONG_L ld
+#define LONG_S sd
+#define LONG_SLL dsll
+#define LONG_SLLV dsllv
+#define LONG_SRL dsrl
+#define LONG_SRLV dsrlv
+#define LONG_SRA dsra
+#define LONG_SRAV dsrav
+#endif
+
+/*
+ * How to add/sub/load/store/shift pointers.
+ */
+#if (_MIPS_SZLONG == 32)
+#define PTR_ADD add
+#define PTR_ADDI addi
+#define PTR_ADDU addu
+#define PTR_ADDIU addiu
+#define PTR_SUB add
+#define PTR_SUBI subi
+#define PTR_SUBU subu
+#define PTR_SUBIU subu
+#define PTR_L lw
+#define PTR_S sw
+#define PTR_SLL sll
+#define PTR_SLLV sllv
+#define PTR_SRL srl
+#define PTR_SRLV srlv
+#define PTR_SRA sra
+#define PTR_SRAV srav
+
+#define PTR_SCALESHIFT 2
+#endif
+
+#if (_MIPS_SZLONG == 64)
+#define PTR_ADD dadd
+#define PTR_ADDI daddi
+#define PTR_ADDU daddu
+#define PTR_ADDIU daddiu
+#define PTR_SUB dadd
+#define PTR_SUBI dsubi
+#define PTR_SUBU dsubu
+#define PTR_SUBIU dsubu
+#define PTR_L ld
+#define PTR_S sd
+#define PTR_SLL dsll
+#define PTR_SLLV dsllv
+#define PTR_SRL dsrl
+#define PTR_SRLV dsrlv
+#define PTR_SRA dsra
+#define PTR_SRAV dsrav
+
+#define PTR_SCALESHIFT 3
+#endif
+
+/*
+ * Some cp0 registers were extended to 64bit for MIPS III.
+ */


+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)

+#define MFC0 mfc0
+#define MTC0 mtc0
+#endif
+#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS5)
+#define MFC0 dmfc0
+#define MTC0 dmtc0
X #endif
X
X #endif /* __ASM_ASM_H */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/asmmacro.h linux/include/asm-mips/asmmacro.h
--- v2.1.43/linux/include/asm-mips/asmmacro.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/asmmacro.h Thu Jun 26 12:33:39 1997
@@ -0,0 +1,115 @@
+/* $Id: asmmacro.h,v 1.1 1997/06/06 09:38:18 ralf Exp $
+ * asmmacro.h: Assembler macros to make things easier to read.


+ *
+ * Copyright (C) 1996 David S. Miller (d...@engr.sgi.com)
+ */
+

+#ifndef __MIPS_ASMMACRO_H
+#define __MIPS_ASMMACRO_H
+
+#include <asm/offset.h>
+
+#define FPU_SAVE_16ODD(thread) \
+ swc1 $f1, (THREAD_FPU + 0x08)(thread); \
+ swc1 $f3, (THREAD_FPU + 0x18)(thread); \
+ swc1 $f5, (THREAD_FPU + 0x28)(thread); \
+ swc1 $f7, (THREAD_FPU + 0x38)(thread); \
+ swc1 $f9, (THREAD_FPU + 0x48)(thread); \
+ swc1 $f11, (THREAD_FPU + 0x58)(thread); \
+ swc1 $f13, (THREAD_FPU + 0x68)(thread); \
+ swc1 $f15, (THREAD_FPU + 0x78)(thread); \
+ swc1 $f17, (THREAD_FPU + 0x88)(thread); \
+ swc1 $f19, (THREAD_FPU + 0x98)(thread); \
+ swc1 $f21, (THREAD_FPU + 0xa8)(thread); \
+ swc1 $f23, (THREAD_FPU + 0xb8)(thread); \
+ swc1 $f25, (THREAD_FPU + 0xc8)(thread); \
+ swc1 $f27, (THREAD_FPU + 0xd8)(thread); \
+ swc1 $f29, (THREAD_FPU + 0xe8)(thread); \
+ swc1 $f31, (THREAD_FPU + 0xf8)(thread);
+
+
+#define FPU_RESTORE_16ODD(thread) \
+ lwc1 $f1, (THREAD_FPU + 0x08)(thread); \
+ lwc1 $f3, (THREAD_FPU + 0x18)(thread); \
+ lwc1 $f5, (THREAD_FPU + 0x28)(thread); \
+ lwc1 $f7, (THREAD_FPU + 0x38)(thread); \
+ lwc1 $f9, (THREAD_FPU + 0x48)(thread); \
+ lwc1 $f11, (THREAD_FPU + 0x58)(thread); \
+ lwc1 $f13, (THREAD_FPU + 0x68)(thread); \
+ lwc1 $f15, (THREAD_FPU + 0x78)(thread); \
+ lwc1 $f17, (THREAD_FPU + 0x88)(thread); \
+ lwc1 $f19, (THREAD_FPU + 0x98)(thread); \
+ lwc1 $f21, (THREAD_FPU + 0xa8)(thread); \
+ lwc1 $f23, (THREAD_FPU + 0xb8)(thread); \
+ lwc1 $f25, (THREAD_FPU + 0xc8)(thread); \
+ lwc1 $f27, (THREAD_FPU + 0xd8)(thread); \
+ lwc1 $f29, (THREAD_FPU + 0xe8)(thread); \
+ lwc1 $f31, (THREAD_FPU + 0xf8)(thread);
+
+#define FPU_SAVE_16EVEN(thread, tmp) \
+ cfc1 tmp, fcr31; \
+ swc1 $f2, (THREAD_FPU + 0x010)(thread); \
+ swc1 $f4, (THREAD_FPU + 0x020)(thread); \
+ swc1 $f6, (THREAD_FPU + 0x030)(thread); \
+ swc1 $f8, (THREAD_FPU + 0x040)(thread); \
+ swc1 $f10, (THREAD_FPU + 0x050)(thread); \
+ swc1 $f12, (THREAD_FPU + 0x060)(thread); \
+ swc1 $f14, (THREAD_FPU + 0x070)(thread); \
+ swc1 $f16, (THREAD_FPU + 0x080)(thread); \
+ swc1 $f18, (THREAD_FPU + 0x090)(thread); \
+ swc1 $f20, (THREAD_FPU + 0x0a0)(thread); \
+ swc1 $f22, (THREAD_FPU + 0x0b0)(thread); \
+ swc1 $f24, (THREAD_FPU + 0x0c0)(thread); \
+ swc1 $f26, (THREAD_FPU + 0x0d0)(thread); \
+ swc1 $f28, (THREAD_FPU + 0x0e0)(thread); \
+ swc1 $f30, (THREAD_FPU + 0x0f0)(thread); \
+ sw tmp, (THREAD_FPU + 0x100)(thread);
+
+
+#define FPU_RESTORE_16EVEN(thread, tmp) \
+ lw tmp, (THREAD_FPU + 0x100)(thread); \
+ lwc1 $f2, (THREAD_FPU + 0x010)(thread); \
+ lwc1 $f4, (THREAD_FPU + 0x020)(thread); \
+ lwc1 $f6, (THREAD_FPU + 0x030)(thread); \
+ lwc1 $f8, (THREAD_FPU + 0x040)(thread); \
+ lwc1 $f10, (THREAD_FPU + 0x050)(thread); \
+ lwc1 $f12, (THREAD_FPU + 0x060)(thread); \
+ lwc1 $f14, (THREAD_FPU + 0x070)(thread); \
+ lwc1 $f16, (THREAD_FPU + 0x080)(thread); \
+ lwc1 $f18, (THREAD_FPU + 0x090)(thread); \
+ lwc1 $f20, (THREAD_FPU + 0x0a0)(thread); \
+ lwc1 $f22, (THREAD_FPU + 0x0b0)(thread); \
+ lwc1 $f24, (THREAD_FPU + 0x0c0)(thread); \
+ lwc1 $f26, (THREAD_FPU + 0x0d0)(thread); \
+ lwc1 $f28, (THREAD_FPU + 0x0e0)(thread); \
+ lwc1 $f30, (THREAD_FPU + 0x0f0)(thread); \
+ ctc1 tmp, fcr31;
+
+#define CPU_SAVE_NONSCRATCH(thread) \
+ sw s0, THREAD_REG16(thread); \
+ sw s1, THREAD_REG17(thread); \
+ sw s2, THREAD_REG18(thread); \
+ sw s3, THREAD_REG19(thread); \
+ sw s4, THREAD_REG20(thread); \
+ sw s5, THREAD_REG21(thread); \
+ sw s6, THREAD_REG22(thread); \
+ sw s7, THREAD_REG23(thread); \
+ sw gp, THREAD_REG28(thread); \
+ sw sp, THREAD_REG29(thread); \
+ sw fp, THREAD_REG30(thread);
+
+#define CPU_RESTORE_NONSCRATCH(thread) \
+ lw s0, THREAD_REG16(thread); \
+ lw s1, THREAD_REG17(thread); \
+ lw s2, THREAD_REG18(thread); \
+ lw s3, THREAD_REG19(thread); \
+ lw s4, THREAD_REG20(thread); \
+ lw s5, THREAD_REG21(thread); \
+ lw s6, THREAD_REG22(thread); \
+ lw s7, THREAD_REG23(thread); \
+ lw gp, THREAD_REG28(thread); \
+ lw sp, THREAD_REG29(thread); \
+ lw fp, THREAD_REG30(thread); \
+ lw ra, THREAD_REG31(thread);
+
+#endif /* !(__MIPS_ASMMACRO_H) */
diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/atomic.h linux/include/asm-mips/atomic.h
--- v2.1.43/linux/include/asm-mips/atomic.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-mips/atomic.h Mon Jul 7 08:18:55 1997
@@ -0,0 +1,190 @@
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ *
+ * But use these as seldom as possible since they are much more slower
+ * than regular operations.


+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *

+ * Copyright (C) 1996 by Ralf Baechle
+ *

+ * $Id: atomic.h,v 1.2 1997/06/25 19:10:33 ralf Exp $
+ */
+#ifndef __ASM_MIPS_ATOMIC_H
+#define __ASM_MIPS_ATOMIC_H
+
+#include <asm/sgidefs.h>
+
+#ifdef __SMP__
+typedef struct { volatile int counter; } atomic_t;
+#else
+typedef struct { int counter; } atomic_t;
+#endif
+
+#ifdef __KERNEL__
+#define ATOMIC_INIT(i) { (i) }
+
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v,i) ((v)->counter = (i))
+
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1)
+
+#include <asm/system.h>
+
+/*
+ * The MIPS I implementation is only atomic with respect to
+ * interrupts. R3000 based multiprocessor machines are rare anyway ...
+ */
+extern __inline__ void atomic_add(int i, volatile atomic_t * v)
+{
+ int flags;
+
+ save_flags(flags);
+ cli();
+ *v += i;
+ restore_flags(flags);
+}
+
+extern __inline__ void atomic_sub(int i, volatile atomic_t * v)
+{
+ int flags;
+
+ save_flags(flags);
+ cli();
+ *v -= i;
+ restore_flags(flags);
+}
+
+extern __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+ int temp, flags;


+
+ save_flags(flags);
+ cli();

+ temp = *v;
+ temp += i;
+ *v = temp;
+ restore_flags(flags);
+
+ return temp;
+}
+
+extern __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+ int temp, flags;


+
+ save_flags(flags);
+ cli();

+ temp = *v;
+ temp -= i;
+ *v = temp;
+ restore_flags(flags);
+
+ return temp;
+}
+#endif
+


+#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS4) || (_MIPS_ISA == _MIPS_ISA_MIPS5)

+/*
+ * ... while for MIPS II and better we can use ll/sc instruction. This
+ * implementation is SMP safe ...
+ */
+
+/*
+ * Make sure gcc doesn't try to be clever and move things around
+ * on us. We need to use _exactly_ the address the user gave us,
+ * not some alias that contains the same information.
+ */
+#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x)
+
+extern __inline__ void atomic_add(int i, volatile atomic_t * v)


+{
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ "1:\tll\t%0,%1\n\t"

+ "addu\t%0,%2\n\t"


+ "sc\t%0,%1\n\t"
+ "beqz\t%0,1b"
+ :"=&r" (temp),

+ "=m" (__atomic_fool_gcc(v))


+ :"Ir" (i),
+ "m" (__atomic_fool_gcc(v)));

+}
+
+extern __inline__ void atomic_sub(int i, volatile atomic_t * v)


+{
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ "1:\tll\t%0,%1\n\t"

+ "subu\t%0,%2\n\t"


+ "sc\t%0,%1\n\t"
+ "beqz\t%0,1b"
+ :"=&r" (temp),

+ "=m" (__atomic_fool_gcc(v))


+ :"Ir" (i),
+ "m" (__atomic_fool_gcc(v)));

+}
+
+/*
+ * Same as above, but return the result value
+ */
+extern __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+ unsigned long temp, result;


+
+ __asm__ __volatile__(
+ ".set\tnoreorder\n"

+ "1:\tll\t%1,%2\n\t"
+ "addu\t%0,%1,%3\n\t"
+ "sc\t%0,%2\n\t"
+ "beqz\t%0,1b\n\t"
+ "addu\t%0,%1,%3\n\t"
+ ".set\treorder"
+ :"=&r" (result),
+ "=&r" (temp),
+ "=m" (__atomic_fool_gcc(v))


+ :"Ir" (i),
+ "m" (__atomic_fool_gcc(v)));

+
+ return result;
+}
+

+extern __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+ unsigned long temp, result;


+
+ __asm__ __volatile__(
+ ".set\tnoreorder\n"

+ "1:\tll\t%1,%2\n\t"
+ "subu\t%0,%1,%3\n\t"
+ "sc\t%0,%2\n\t"
+ "beqz\t%0,1b\n\t"
+ "subu\t%0,%1,%3\n\t"
+ ".set\treorder"
+ :"=&r" (result),
+ "=&r" (temp),
+ "=m" (__atomic_fool_gcc(v))


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'

fi
echo 'End of part 33'
echo 'File patch-2.1.44 is continued in part 34'
echo 34 > _shar_seq_.tmp
exit 0

Thomas...@ciw.uni-karlsruhe.de

unread,
Jul 8, 1997, 3:00:00 AM7/8/97
to

Archive-name: v2.1/patch-2.1.44/part31

#!/bin/sh
# this is part 31 of a 47 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.1.44 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 31; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.1.44'
else
echo 'x - continuing with patch-2.1.44'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.1.44' &&

X return -ENOENT;
- }
+
X ino = le32_to_cpu(de->inode);
X brelse (bh);
- if (!(*result = iget (dir->i_sb, ino))) {
- iput (dir);
+ if (!(*result = iget (dir->i_sb, ino)))
X return -EACCES;
- }
- iput (dir);
+


X return 0;
X }
X

@@ -347,31 +343,35 @@
X return -ENOENT;
X }
X
-int ext2_create (struct inode * dir,const char * name, int len, int mode,


- struct inode ** result)

+/*
+ * By the time this is called, we already have created
+ * the directory cache entry for the new file, but it
+ * is so far marked "D_NEGATIVE".
+ *
+ * If the create succeeds, remove the D_NEGATIVE flag,
+ * and fill in the inode information with d_instantiate().
+ */
+int ext2_create (struct inode * dir, struct dentry * dentry, int mode)
X {
X struct inode * inode;
X struct buffer_head * bh;


X struct ext2_dir_entry * de;

X int err;
X
- *result = NULL;


X if (!dir)
X return -ENOENT;

X inode = ext2_new_inode (dir, mode, &err);
- if (!inode) {
- iput (dir);
+ if (!inode)
X return err;
- }
+
X inode->i_op = &ext2_file_inode_operations;
X inode->i_mode = mode;


X inode->i_dirt = 1;

- bh = ext2_add_entry (dir, name, len, &de, &err);
+ bh = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
X if (!bh) {
X inode->i_nlink--;


X inode->i_dirt = 1;

X iput (inode);
- iput (dir);
X return err;
X }
X de->inode = cpu_to_le32(inode->i_ino);
@@ -382,13 +382,11 @@
X wait_on_buffer (bh);
X }
X brelse (bh);
- iput (dir);
- *result = inode;
+ d_instantiate(dentry, inode, 0);


X return 0;
X }
X

-int ext2_mknod (struct inode * dir, const char * name, int len, int mode,
- int rdev)
+int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
X {


X struct inode * inode;

X struct buffer_head * bh;
@@ -398,21 +396,13 @@


X if (!dir)
X return -ENOENT;

X

- if (len > EXT2_NAME_LEN) {
- iput (dir);

+ if (dentry->d_name.len > EXT2_NAME_LEN)
X return -ENAMETOOLONG;
- }
- bh = ext2_find_entry (dir, name, len, &de);
- if (bh) {
- brelse (bh);
- iput (dir);
- return -EEXIST;
- }
+
X inode = ext2_new_inode (dir, mode, &err);
- if (!inode) {
- iput (dir);
+ if (!inode)
X return err;
- }
+
X inode->i_uid = current->fsuid;
X inode->i_mode = mode;
X inode->i_op = NULL;
@@ -434,12 +424,11 @@
X if (S_ISBLK(mode) || S_ISCHR(mode))
X inode->i_rdev = to_kdev_t(rdev);


X inode->i_dirt = 1;

- bh = ext2_add_entry (dir, name, len, &de, &err);
+ bh = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
X if (!bh) {
X inode->i_nlink--;


X inode->i_dirt = 1;

- iput (inode);
- iput (dir);
+ iput(inode);
X return err;
X }
X de->inode = cpu_to_le32(inode->i_ino);
@@ -449,45 +438,32 @@
X ll_rw_block (WRITE, 1, &bh);
X wait_on_buffer (bh);
X }
- brelse (bh);
- iput (dir);
- iput (inode);
+ brelse(bh);
+ d_instantiate(dentry, inode, 0);


X return 0;
X }
X

-int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
+int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
X {
X struct inode * inode;
X struct buffer_head * bh, * dir_block;


X struct ext2_dir_entry * de;

X int err;
X
- if (!dir)
- return -ENOENT;


- if (len > EXT2_NAME_LEN) {
- iput (dir);

+ if (dentry->d_name.len > EXT2_NAME_LEN)
X return -ENAMETOOLONG;
- }
- bh = ext2_find_entry (dir, name, len, &de);
- if (bh) {
- brelse (bh);
- iput (dir);
- return -EEXIST;
- }
- if (dir->i_nlink >= EXT2_LINK_MAX) {
- iput (dir);
+
+ if (dir->i_nlink >= EXT2_LINK_MAX)
X return -EMLINK;
- }
+
X inode = ext2_new_inode (dir, S_IFDIR, &err);
- if (!inode) {
- iput (dir);
+ if (!inode)
X return err;
- }
+
X inode->i_op = &ext2_dir_inode_operations;
X inode->i_size = inode->i_sb->s_blocksize;
X dir_block = ext2_bread (inode, 0, 1, &err);
X if (!dir_block) {
- iput (dir);
X inode->i_nlink--;


X inode->i_dirt = 1;

X iput (inode);
@@ -511,9 +487,8 @@
X if (dir->i_mode & S_ISGID)
X inode->i_mode |= S_ISGID;


X inode->i_dirt = 1;

- bh = ext2_add_entry (dir, name, len, &de, &err);
+ bh = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
X if (!bh) {
- iput (dir);
X inode->i_nlink = 0;


X inode->i_dirt = 1;

X iput (inode);
@@ -528,8 +503,7 @@
X }
X dir->i_nlink++;
X dir->i_dirt = 1;
- iput (dir);
- iput (inode);
+ d_instantiate(dentry, inode, D_DIR);
X brelse (bh);
X return 0;
X }
@@ -593,51 +567,46 @@


X return 1;
X }
X

-int ext2_rmdir (struct inode * dir, const char * name, int len)
+int ext2_rmdir (struct inode * dir, struct dentry *dentry)
X {
X int retval;


X struct inode * inode;

X struct buffer_head * bh;


X struct ext2_dir_entry * de;

X
-repeat:


X if (!dir)
X return -ENOENT;

X inode = NULL;


- if (len > EXT2_NAME_LEN) {
- iput (dir);

+ if (dentry->d_name.len > EXT2_NAME_LEN)
X return -ENAMETOOLONG;
- }
- bh = ext2_find_entry (dir, name, len, &de);
+
+ bh = ext2_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
X retval = -ENOENT;
X if (!bh)
X goto end_rmdir;
X retval = -EPERM;
- if (!(inode = iget (dir->i_sb, le32_to_cpu(de->inode))))
- goto end_rmdir;
+ inode = dentry->d_inode;
+
X if (inode->i_sb->dq_op)
X inode->i_sb->dq_op->initialize (inode, -1);
- if (inode->i_dev != dir->i_dev) {
- retval = -EBUSY;
- goto end_rmdir;
- }
- if (le32_to_cpu(de->inode) != inode->i_ino) {
- iput(inode);
- brelse(bh);
- current->counter = 0;
- schedule();
- goto repeat;
- }
+
X if ((dir->i_mode & S_ISVTX) && !fsuser() &&
X current->fsuid != inode->i_uid &&
X current->fsuid != dir->i_uid)
X goto end_rmdir;
X if (inode == dir) /* we may not delete ".", but "../dir" is ok */
X goto end_rmdir;
- if (!S_ISDIR(inode->i_mode)) {
- retval = -ENOTDIR;
+
+ retval = -ENOTDIR;
+ if (!S_ISDIR(inode->i_mode))
X goto end_rmdir;
- }
+
+ retval = -EIO;
+ if (inode->i_dev != dir->i_dev)
+ goto end_rmdir;
+ if (le32_to_cpu(de->inode) != inode->i_ino)
+ goto end_rmdir;
+
X down(&inode->i_sem);
X if (!empty_dir (inode))
X retval = -ENOTEMPTY;
@@ -675,52 +644,47 @@
X dir->i_nlink--;
X inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
X dir->i_dirt = 1;
+ d_delete(dentry);
+
X end_rmdir:
- iput (dir);
- iput (inode);
X brelse (bh);


X return retval;
X }
X

-int ext2_unlink (struct inode * dir, const char * name, int len)
+int ext2_unlink(struct inode * dir, struct dentry *dentry)
X {
X int retval;


X struct inode * inode;

X struct buffer_head * bh;


X struct ext2_dir_entry * de;

X
-repeat:
- if (!dir)
- return -ENOENT;
X retval = -ENOENT;
X inode = NULL;


- if (len > EXT2_NAME_LEN) {
- iput (dir);

+ if (dentry->d_name.len > EXT2_NAME_LEN)
X return -ENAMETOOLONG;
- }
- bh = ext2_find_entry (dir, name, len, &de);
+
+ bh = ext2_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
X if (!bh)
X goto end_unlink;
- if (!(inode = iget (dir->i_sb, le32_to_cpu(de->inode))))
- goto end_unlink;
+
+ inode = dentry->d_inode;
X if (inode->i_sb->dq_op)
X inode->i_sb->dq_op->initialize (inode, -1);
+
X retval = -EPERM;
X if (S_ISDIR(inode->i_mode))
X goto end_unlink;
X if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
X goto end_unlink;
- if (le32_to_cpu(de->inode) != inode->i_ino) {
- iput(inode);
- brelse(bh);
- current->counter = 0;
- schedule();
- goto repeat;
- }
X if ((dir->i_mode & S_ISVTX) && !fsuser() &&
X current->fsuid != inode->i_uid &&
X current->fsuid != dir->i_uid)
X goto end_unlink;
+
+ retval = -EIO;
+ if (le32_to_cpu(de->inode) != inode->i_ino)
+ goto end_unlink;
+
X if (!inode->i_nlink) {
X ext2_warning (inode->i_sb, "ext2_unlink",
X "Deleting nonexistent file (%lu), %d",
@@ -742,15 +706,14 @@


X inode->i_dirt = 1;

X inode->i_ctime = dir->i_ctime;
X retval = 0;
+ d_delete(dentry); /* This also frees the inode */
+
X end_unlink:
X brelse (bh);
- iput (inode);
- iput (dir);


X return retval;
X }
X

-int ext2_symlink (struct inode * dir, const char * name, int len,
- const char * symname)
+int ext2_symlink (struct inode * dir, struct dentry *dentry, const char * symname)
X {


X struct ext2_dir_entry * de;

X struct inode * inode = NULL;
@@ -761,7 +724,6 @@
X char c;
X
X if (!(inode = ext2_new_inode (dir, S_IFLNK, &err))) {
- iput (dir);
X return err;
X }
X inode->i_mode = S_IFLNK | S_IRWXUGO;
@@ -775,7 +737,6 @@
X
X name_block = ext2_bread (inode, 0, 1, &err);
X if (!name_block) {
- iput (dir);
X inode->i_nlink--;


X inode->i_dirt = 1;

X iput (inode);
@@ -799,21 +760,11 @@
X inode->i_size = i;


X inode->i_dirt = 1;
X

- bh = ext2_find_entry (dir, name, len, &de);
- if (bh) {
- inode->i_nlink--;
- inode->i_dirt = 1;
- iput (inode);
- brelse (bh);
- iput (dir);
- return -EEXIST;
- }
- bh = ext2_add_entry (dir, name, len, &de, &err);
+ bh = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
X if (!bh) {
X inode->i_nlink--;


X inode->i_dirt = 1;

X iput (inode);
- iput (dir);
X return err;
X }
X de->inode = cpu_to_le32(inode->i_ino);
@@ -824,47 +775,30 @@
X wait_on_buffer (bh);
X }
X brelse (bh);
- iput (dir);
- iput (inode);
+ d_instantiate(dentry, inode, 0);


X return 0;
X }
X

-int ext2_link (struct inode * oldinode, struct inode * dir,
- const char * name, int len)
+int ext2_link (struct inode * inode, struct inode * dir, struct dentry *dentry)
X {
X struct ext2_dir_entry * de;
X struct buffer_head * bh;
X int err;
X
- if (S_ISDIR(oldinode->i_mode)) {
- iput (oldinode);
- iput (dir);
+ if (S_ISDIR(inode->i_mode))
X return -EPERM;
- }
- if (IS_APPEND(oldinode) || IS_IMMUTABLE(oldinode)) {
- iput (oldinode);
- iput (dir);
+
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
X return -EPERM;
- }
- if (oldinode->i_nlink >= EXT2_LINK_MAX) {
- iput (oldinode);
- iput (dir);
+
+ if (inode->i_nlink >= EXT2_LINK_MAX)
X return -EMLINK;
- }
- bh = ext2_find_entry (dir, name, len, &de);
- if (bh) {
- brelse (bh);
- iput (dir);
- iput (oldinode);
- return -EEXIST;
- }
- bh = ext2_add_entry (dir, name, len, &de, &err);
- if (!bh) {
- iput (dir);
- iput (oldinode);
+
+ bh = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
+ if (!bh)
X return err;
- }
- de->inode = cpu_to_le32(oldinode->i_ino);
+
+ de->inode = cpu_to_le32(inode->i_ino);
X dir->i_version = ++event;
X mark_buffer_dirty(bh, 1);
X if (IS_SYNC(dir)) {
@@ -872,11 +806,11 @@
X wait_on_buffer (bh);
X }
X brelse (bh);
- iput (dir);
- oldinode->i_nlink++;
- oldinode->i_ctime = CURRENT_TIME;
- oldinode->i_dirt = 1;
- iput (oldinode);
+ inode->i_nlink++;
+ inode->i_ctime = CURRENT_TIME;


+ inode->i_dirt = 1;

+ atomic_inc(&inode->i_count);
+ d_instantiate(dentry, inode, 0);


X return 0;
X }
X

@@ -895,7 +829,7 @@
X if (new_inode->i_dev != old_inode->i_dev)
X break;
X ino = new_inode->i_ino;
- if (ext2_lookup (new_inode, "..", 2, &new_inode))
+ if (ext2_lookup (new_inode, &(struct qstr) { "..", 2, 0 }, &new_inode))
X break;
X if (new_inode->i_ino == ino)
X break;
@@ -923,43 +857,27 @@
X * Anybody can rename anything with this: the permission checks are left to the
X * higher-level routines.
X */
-static int do_ext2_rename (struct inode * old_dir, const char * old_name,
- int old_len, struct inode * new_dir,
- const char * new_name, int new_len)
+static int do_ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
+ struct inode * new_dir,struct dentry *new_dentry)
X {
X struct inode * old_inode, * new_inode;
X struct buffer_head * old_bh, * new_bh, * dir_bh;
X struct ext2_dir_entry * old_de, * new_de;
X int retval;
X
- goto start_up;
-try_again:
- if (new_bh && new_de) {
- ext2_delete_entry(new_de, new_bh);
- new_dir->i_version = ++event;
- }
- brelse (old_bh);
- brelse (new_bh);
- brelse (dir_bh);
- iput (old_inode);
- iput (new_inode);
- current->counter = 0;
- schedule ();
-start_up:
X old_inode = new_inode = NULL;
X old_bh = new_bh = dir_bh = NULL;
X new_de = NULL;
X retval = -ENAMETOOLONG;
- if (old_len > EXT2_NAME_LEN)
+ if (old_dentry->d_name.len > EXT2_NAME_LEN)
X goto end_rename;
X
- old_bh = ext2_find_entry (old_dir, old_name, old_len, &old_de);
+ old_bh = ext2_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len, &old_de);
X retval = -ENOENT;
X if (!old_bh)
X goto end_rename;
- old_inode = __iget (old_dir->i_sb, le32_to_cpu(old_de->inode), 0); /* don't cross mnt-points */
- if (!old_inode)
- goto end_rename;
+ old_inode = old_dentry->d_inode;
+
X retval = -EPERM;
X if ((old_dir->i_mode & S_ISVTX) &&
X current->fsuid != old_inode->i_uid &&
@@ -967,9 +885,10 @@
X goto end_rename;
X if (IS_APPEND(old_inode) || IS_IMMUTABLE(old_inode))
X goto end_rename;
- new_bh = ext2_find_entry (new_dir, new_name, new_len, &new_de);
+
+ new_inode = new_dentry->d_inode;
+ new_bh = ext2_find_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len, &new_de);
X if (new_bh) {
- new_inode = __iget (new_dir->i_sb, le32_to_cpu(new_de->inode), 0); /* no mntp cross */
X if (!new_inode) {
X brelse (new_bh);
X new_bh = NULL;
@@ -1018,29 +937,18 @@
X goto end_rename;
X }
X if (!new_bh)
- new_bh = ext2_add_entry (new_dir, new_name, new_len, &new_de,
+ new_bh = ext2_add_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len, &new_de,
X &retval);
X if (!new_bh)
X goto end_rename;
X new_dir->i_version = ++event;
- /*
- * sanity checking before doing the rename - avoid races
- */
- if (new_inode && (le32_to_cpu(new_de->inode) != new_inode->i_ino))
- goto try_again;
- if (le32_to_cpu(new_de->inode) && !new_inode)
- goto try_again;
- if (le32_to_cpu(old_de->inode) != old_inode->i_ino)
- goto try_again;
+
X /*
X * ok, that's it
X */
X new_de->inode = le32_to_cpu(old_inode->i_ino);
- retval = ext2_delete_entry (old_de, old_bh);
- if (retval == -ENOENT)
- goto try_again;
- if (retval)
- goto end_rename;
+ ext2_delete_entry (old_de, old_bh);
+
X old_dir->i_version = ++event;
X if (new_inode) {
X new_inode->i_nlink--;
@@ -1072,15 +980,15 @@
X ll_rw_block (WRITE, 1, &new_bh);
X wait_on_buffer (new_bh);
X }
+
+ /* Update the dcache */
+ d_move(old_dentry, new_dentry->d_parent, &new_dentry->d_name);
+ d_delete(new_dentry);
X retval = 0;
X end_rename:
X brelse (dir_bh);
X brelse (old_bh);
X brelse (new_bh);
- iput (old_inode);
- iput (new_inode);
- iput (old_dir);
- iput (new_dir);


X return retval;
X }
X

@@ -1097,16 +1005,15 @@
X * super-block. This way, we really lock other renames only if they occur
X * on the same file system
X */
-int ext2_rename (struct inode * old_dir, const char * old_name, int old_len,
- struct inode * new_dir, const char * new_name, int new_len)
+int ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
+ struct inode * new_dir, struct dentry *new_dentry)
X {
X int result;
X
X while (old_dir->i_sb->u.ext2_sb.s_rename_lock)
X sleep_on (&old_dir->i_sb->u.ext2_sb.s_rename_wait);
X old_dir->i_sb->u.ext2_sb.s_rename_lock = 1;
- result = do_ext2_rename (old_dir, old_name, old_len, new_dir,
- new_name, new_len);
+ result = do_ext2_rename (old_dir, old_dentry, new_dir, new_dentry);
X old_dir->i_sb->u.ext2_sb.s_rename_lock = 0;
X wake_up (&old_dir->i_sb->u.ext2_sb.s_rename_wait);
X return result;
diff -u --recursive --new-file v2.1.43/linux/fs/ext2/super.c linux/fs/ext2/super.c
--- v2.1.43/linux/fs/ext2/super.c Mon Jun 16 16:35:57 1997
+++ linux/fs/ext2/super.c Tue Jul 1 16:42:12 1997
@@ -632,7 +632,8 @@
X */
X sb->s_dev = dev;
X sb->s_op = &ext2_sops;
- if (!(sb->s_mounted = iget (sb, EXT2_ROOT_INO))) {
+ sb->s_root = d_alloc_root(iget(sb, EXT2_ROOT_INO), NULL);
+ if (!sb->s_root) {
X sb->s_dev = 0;
X for (i = 0; i < db_count; i++)
X if (sb->u.ext2_sb.s_group_desc[i])
diff -u --recursive --new-file v2.1.43/linux/fs/ext2/symlink.c linux/fs/ext2/symlink.c
--- v2.1.43/linux/fs/ext2/symlink.c Mon Jun 16 16:35:57 1997
+++ linux/fs/ext2/symlink.c Sun Jul 6 21:31:52 1997
@@ -25,6 +25,7 @@
X #include <linux/stat.h>
X
X static int ext2_readlink (struct inode *, char *, int);
+static struct dentry *ext2_follow_link(struct inode *, struct dentry *);
X
X /*
X * symlinks can't do much...
@@ -41,6 +42,7 @@


X NULL, /* mknod */
X NULL, /* rename */

X ext2_readlink, /* readlink */
+ ext2_follow_link, /* follow_link */


X NULL, /* readpage */
X NULL, /* writepage */
X NULL, /* bmap */

@@ -49,26 +51,50 @@
X NULL /* smap */
X };
X
+static struct dentry * ext2_follow_link(struct inode * inode, struct dentry *base)
+{
+ int error;
+ struct buffer_head * bh = NULL;
+ char * link;
+
+ link = (char *) inode->u.ext2_i.i_data;
+ if (inode->i_blocks) {
+ if (!(bh = ext2_bread (inode, 0, 0, &error))) {
+ dput(base);
+ return ERR_PTR(-EIO);
+ }
+ link = bh->b_data;
+ }
+ if (!IS_RDONLY(inode)) {
+ inode->i_atime = CURRENT_TIME;


+ inode->i_dirt = 1;
+ }

+ base = lookup_dentry(link, base, 1);
+ if (bh)
+ brelse(bh);
+ return base;
+}
+
X static int ext2_readlink (struct inode * inode, char * buffer, int buflen)
X {
X struct buffer_head * bh = NULL;
X char * link;


- int i, err;
+ int i;
X

X if (buflen > inode->i_sb->s_blocksize - 1)
X buflen = inode->i_sb->s_blocksize - 1;
+
+ link = (char *) inode->u.ext2_i.i_data;
X if (inode->i_blocks) {
+ int err;
X bh = ext2_bread (inode, 0, 0, &err);
X if (!bh) {
- iput (inode);
X if(err < 0) /* indicate type of error */
X return err;
X return 0;
X }
X link = bh->b_data;
X }
- else
- link = (char *) inode->u.ext2_i.i_data;
X
X i = 0;
X while (i < buflen && link[i])
@@ -79,7 +105,6 @@
X inode->i_atime = CURRENT_TIME;


X inode->i_dirt = 1;
X }

- iput (inode);
X if (bh)
X brelse (bh);
X return i;
diff -u --recursive --new-file v2.1.43/linux/fs/fat/misc.c linux/fs/fat/misc.c
--- v2.1.43/linux/fs/fat/misc.c Mon Apr 14 16:28:17 1997
+++ linux/fs/fat/misc.c Thu Jul 3 13:18:33 1997
@@ -19,13 +19,14 @@
X
X /* Well-known binary file extensions - of course there are many more */
X
-static char bin_extensions[] =
- "EXE" "COM" "BIN" "APP" "SYS" "DRV" "OVL" "OVR" "OBJ" "LIB" "DLL" "PIF" /* program code */
- "ARC" "ZIP" "LHA" "LZH" "ZOO" "TAR" "Z " "ARJ" /* common archivers */
- "TZ " "TAZ" "TZP" "TPZ" /* abbreviations of tar.Z and tar.zip */
- "GZ " "TGZ" "DEB" /* .gz, .tar.gz and Debian packages */
- "GIF" "BMP" "TIF" "GL " "JPG" "PCX" /* graphics */
- "TFM" "VF " "GF " "PK " "PXL" "DVI"; /* TeX */
+static char ascii_extensions[] =
+ "TXT" "ME " "HTM" "1ST" "LOG" " " /* text files */
+ "C " "H " "CPP" "LIS" "PAS" "FOR" /* programming languages */
+ "F " "MAK" "INC" "BAS" /* programming languages */
+ "BAT" "SH " /* program code :) */
+ "INI" /* config files */
+ "PBM" "PGM" "DXF" /* graphics */
+ "TEX"; /* TeX */
X
X
X /*
@@ -62,9 +63,9 @@
X case 't':
X return 0;
X case 'a':
- for (walk = bin_extensions; *walk; walk += 3)
- if (!strncmp(extension,walk,3)) return 1;
- return 0;
+ for (walk = ascii_extensions; *walk; walk += 3)
+ if (!strncmp(extension,walk,3)) return 0;
+ return 1; /* default binary conversion */
X default:
X printk("Invalid conversion mode - defaulting to "
X "binary.\n");
diff -u --recursive --new-file v2.1.43/linux/fs/inode.c linux/fs/inode.c
--- v2.1.43/linux/fs/inode.c Mon Jun 16 16:35:57 1997
+++ linux/fs/inode.c Mon Jul 7 16:28:05 1997
@@ -110,7 +110,7 @@
X {
X int i;
X for(i=xcnt-1; i>=0; i--)
- if(xtst[i] == p)
+ if (xtst[i] == p)
X return;
X printk("Bogus inode %p in %s\n", p, txt);
X }
@@ -123,7 +123,7 @@
X struct inode * res;
X struct inode * inode = res = (struct inode*)__get_free_page(GFP_KERNEL);
X int size = PAGE_SIZE;
- if(!inode)
+ if (!inode)
X return NULL;
X
X size -= sizeof(struct inode);
@@ -178,7 +178,7 @@
X int res = 0;
X vfs_lock();
X inode->i_status &= ~flags;
- if(inode->i_status & ST_WAITING) {
+ if (inode->i_status & ST_WAITING) {
X inode->i_status &= ~ST_WAITING;
X vfs_unlock();
X wake_up(&inode->i_wait);
@@ -191,10 +191,10 @@
X unsigned short waitflags, unsigned short setflags)
X {
X /* Do nothing if the same op is already in progress. */
- if(op && !(inode->i_status & setflags)) {
+ if (op && !(inode->i_status & setflags)) {
X set_io(inode, waitflags, setflags);
X op(inode);
- if(release_io(inode, setflags)) {
+ if (release_io(inode, setflags)) {
X /* Somebody grabbed my inode from under me. */
X #ifdef DEBUG
X printk("_io grab!\n");
@@ -204,36 +204,10 @@
X }
X }
X
-blocking int _free_ibasket(struct super_block * sb)
-{
- if(sb->s_ibasket) {
- struct inode * delinquish = sb->s_ibasket->i_basket_prev;
-#if 0
-printpath(delinquish->i_dentry);
-printk(" delinquish\n");
-#endif
- _clear_inode(delinquish, 0, 1);
- return 1;


- }
- return 0;
-}
-

-static /*inline*/ void _put_ibasket(struct inode * inode)
-{
- struct super_block * sb = inode->i_sb;
- if(!(inode->i_status & ST_IBASKET)) {
- inode->i_status |= ST_IBASKET;
- insert_ibasket(&sb->s_ibasket, inode);
- sb->s_ibasket_count++;
- if(sb->s_ibasket_count > sb->s_ibasket_max)
- (void)_free_ibasket(sb);
- }
-}
-
X blocking void _clear_inode(struct inode * inode, int external, int verbose)
X {
X xcheck("_clear_inode",inode);
- if(inode->i_status & ST_IBASKET) {
+ if (inode->i_status & ST_IBASKET) {
X struct super_block * sb = inode->i_sb;
X remove_ibasket(&sb->s_ibasket, inode);
X sb->s_ibasket_count--;
@@ -243,32 +217,29 @@
X printk(" put_inode\n");
X #endif
X _io(sb->s_op->put_inode, inode, ST_TO_PUT|ST_TO_WRITE, ST_TO_PUT);
- if(inode->i_status & ST_EMPTY)
+ if (inode->i_status & ST_EMPTY)
X return;
X }
- if(inode->i_status & ST_HASHED)
+ if (inode->i_status & ST_HASHED)
X remove_hash(&hashtable[hash(inode->i_dev, inode->i_ino)], inode);
- if(inode->i_status & ST_AGED) {
+ if (inode->i_status & ST_AGED) {
X /* "cannot happen" when called from an fs because at least
X * the caller must use it. Can happen when called from
X * invalidate_inodes(). */
- if(verbose)
+ if (verbose)
X printk("VFS: clearing aged inode\n");
- if(atomic_read(&inode->i_count))
+ if (atomic_read(&inode->i_count))
X printk("VFS: aged inode is in use\n");
X remove_lru(&aged_i[inode->i_level], inode);
X inodes_stat.aged_count[inode->i_level]--;
X }
- if(!external && inode->i_status & ST_IO) {
+ if (!external && inode->i_status & ST_IO) {
X printk("VFS: clearing inode during IO operation\n");
X }
- if(!(inode->i_status & ST_EMPTY)) {
+ if (!(inode->i_status & ST_EMPTY)) {
X remove_all(&all_i, inode);
X inode->i_status = ST_EMPTY;
- while(inode->i_dentry) {
- d_del(inode->i_dentry, D_NO_CLEAR_INODE);
- }
- if(inode->i_pages) {
+ if (inode->i_pages) {
X vfs_unlock(); /* may block, can that be revised? */
X truncate_inode_pages(inode, 0);
X vfs_lock();
@@ -291,7 +262,7 @@
X {
X xcheck("insert_inode_hash",inode);
X vfs_lock();
- if(!(inode->i_status & ST_HASHED)) {
+ if (!(inode->i_status & ST_HASHED)) {
X insert_hash(&hashtable[hash(inode->i_dev, inode->i_ino)], inode);
X inode->i_status |= ST_HASHED;
X } else
@@ -306,42 +277,42 @@
X
X retry:
X inode = empty_i;


- if(inode) {
+ if (inode) {

X remove_all(&empty_i, inode);
X inodes_stat.nr_free_inodes--;
X } else if(inodes_stat.nr_inodes < max_inodes || retry > 2) {
X inode = grow_inodes();
X }
- if(!inode) {
+ if (!inode) {
X int level;
X int usable = 0;
X for(level = 0; level <= NR_LEVELS; level++)
- if(aged_i[level]) {
+ if (aged_i[level]) {
X inode = aged_i[level]->i_lru_prev;
X /* Here is the picking strategy, tune this */
- if(aged_reused[level] < (usable++ ?
+ if (aged_reused[level] < (usable++ ?
X inodes_stat.aged_count[level] :
X 2))
X break;
X aged_reused[level] = 0;
X }
- if(inode) {
- if(!(inode->i_status & ST_AGED))
+ if (inode) {
+ if (!(inode->i_status & ST_AGED))
X printk("VFS: inode aging inconsistency\n");
- if(atomic_read(&inode->i_count) + inode->i_ddir_count)
+ if (atomic_read(&inode->i_count))
X printk("VFS: i_count of aged inode is not zero\n");
- if(inode->i_dirt)
+ if (inode->i_dirt)
X printk("VFS: Hey, somebody made my aged inode dirty\n");
X _clear_inode(inode, 0, 0);
X goto retry;
X }
X }
- if(!inode) {
+ if (!inode) {
X vfs_unlock();
X schedule();
- if(retry > 10)
+ if (retry > 10)
X panic("VFS: cannot repair inode shortage");
- if(retry > 2)
+ if (retry > 2)
X printk("VFS: no free inodes\n");
X retry++;
X vfs_lock();
@@ -363,8 +334,8 @@
X {
X struct inode ** base = &hashtable[hash(i_dev, i_ino)];
X struct inode * inode = *base;
- if(inode) do {
- if(inode->i_ino == i_ino && inode->i_dev == i_dev) {
+ if (inode) do {
+ if (inode->i_ino == i_ino && inode->i_dev == i_dev) {
X atomic_inc(&inode->i_count);
X printk("VFS: inode %lx is already in use\n", i_ino);
X return inode;
@@ -391,17 +362,17 @@
X
X void _get_inode(struct inode * inode)
X {
- if(inode->i_status & ST_IBASKET) {
+ if (inode->i_status & ST_IBASKET) {
X inode->i_status &= ~ST_IBASKET;
X remove_ibasket(&inode->i_sb->s_ibasket, inode);
X inode->i_sb->s_ibasket_count--;
X }
- if(inode->i_status & ST_AGED) {
+ if (inode->i_status & ST_AGED) {
X inode->i_status &= ~ST_AGED;
X remove_lru(&aged_i[inode->i_level], inode);
X inodes_stat.aged_count[inode->i_level]--;
X aged_reused[inode->i_level]++;
- if(S_ISDIR(inode->i_mode))
+ if (S_ISDIR(inode->i_mode))
X /* make dirs less thrashable */
X inode->i_level = NR_LEVELS-1;
X else if(inode->i_nlink > 1)
@@ -410,30 +381,28 @@
X else if(++inode->i_reuse_count >= age_table[inode->i_level]
X && inode->i_level < NR_LEVELS-1)
X inode->i_level++;
- if(atomic_read(&inode->i_count) != 1)
- printk("VFS: inode count was not zero\n");
+ if (atomic_read(&inode->i_count) != 1)
+ printk("VFS: inode count was not zero (%d after ++)\n", atomic_read(&inode->i_count));
X } else if(inode->i_status & ST_EMPTY)
X printk("VFS: invalid reuse of empty inode\n");
X }
X
-blocking struct inode * __iget(struct super_block * sb,
- unsigned long i_ino,
- int crossmntp)
+blocking struct inode * iget(struct super_block * sb, unsigned long i_ino)
X {
X struct inode ** base;


X struct inode * inode;

X dev_t i_dev;
X
- if(!sb)
+ if (!sb)
X panic("VFS: iget with sb == NULL");
X i_dev = sb->s_dev;
- if(!i_dev)
+ if (!i_dev)
X panic("VFS: sb->s_dev is NULL\n");
X base = &hashtable[hash(i_dev, i_ino)];
X vfs_lock();
X inode = *base;
- if(inode) do {
- if(inode->i_ino == i_ino && inode->i_dev == i_dev) {
+ if (inode) do {
+ if (inode->i_ino == i_ino && inode->i_dev == i_dev) {
X atomic_inc(&inode->i_count);
X _get_inode(inode);
X
@@ -455,21 +424,14 @@
X inode = _get_empty_inode_hashed(i_dev, i_ino);
X inode->i_sb = sb;
X inode->i_flags = sb->s_flags;
- if(sb->s_op && sb->s_op->read_inode) {
+ if (sb->s_op && sb->s_op->read_inode) {
X set_io(inode, 0, ST_TO_READ); /* do not wait at all */
X sb->s_op->read_inode(inode);
- if(release_io(inode, ST_TO_READ))
+ if (release_io(inode, ST_TO_READ))
X goto done;
X }
X vfs_unlock();
X done:
- while(crossmntp && inode->i_mount) {
- struct inode * tmp = inode->i_mount;
- iinc(tmp);
- iput(inode);
- inode = tmp;
- }
-xcheck("_iget",inode);
X return inode;
X }
X
@@ -477,68 +439,43 @@


X {
X struct super_block * sb;

X xcheck("_iput",inode);
- if(atomic_read(&inode->i_count) + inode->i_ddir_count < 0)
+
+ if (atomic_read(&inode->i_count) < 0)
X printk("VFS: i_count is negative\n");
- if((atomic_read(&inode->i_count) + inode->i_ddir_count) ||
- (inode->i_status & ST_FREEING)) {
+
+ if (atomic_read(&inode->i_count) || (inode->i_status & ST_FREEING))
X return;
- }
+
X inode->i_status |= ST_FREEING;
-#ifdef CONFIG_OMIRR
- if(inode->i_status & ST_MODIFIED) {
- inode->i_status &= ~ST_MODIFIED;
- omirr_printall(inode, " W %ld ", CURRENT_TIME);
- }
-#endif


- if(inode->i_pipe) {
+ if (inode->i_pipe) {

X free_page((unsigned long)PIPE_BASE(*inode));
X PIPE_BASE(*inode)= NULL;
X }
- if((sb = inode->i_sb)) {
- if(sb->s_type && (sb->s_type->fs_flags & FS_NO_DCACHE)) {
- while(inode->i_dentry)
- d_del(inode->i_dentry, D_NO_CLEAR_INODE);
- if(atomic_read(&inode->i_count) + inode->i_ddir_count)
- goto done;
- }
- if(sb->s_op) {
- if(inode->i_nlink <= 0 && inode->i_dent_count &&
- !(inode->i_status & (ST_EMPTY|ST_IBASKET)) &&
- (sb->s_type->fs_flags & FS_IBASKET)) {
- _put_ibasket(inode);
+ if ((sb = inode->i_sb)) {
+ if (sb->s_op) {
+ if (inode->i_nlink <= 0 &&
+ !(inode->i_status & (ST_EMPTY|ST_IBASKET))) {
+ _clear_inode(inode, 0, 1);
X goto done;
X }
- if(!inode->i_dent_count ||
- (sb->s_type->fs_flags & FS_NO_DCACHE)) {
- _io(sb->s_op->put_inode, inode,
- ST_TO_PUT|ST_TO_WRITE, ST_TO_PUT);
- if(atomic_read(&inode->i_count) + inode->i_ddir_count)
- goto done;
- if(inode->i_nlink <= 0) {
- if(!(inode->i_status & ST_EMPTY)) {
- _clear_inode(inode, 0, 1);
- }
- goto done;
- }
- }
- if(inode->i_dirt) {
+ if (inode->i_dirt) {
X inode->i_dirt = 0;
X _io(sb->s_op->write_inode, inode,
X ST_TO_PUT|ST_TO_WRITE, ST_TO_WRITE);
- if(atomic_read(&inode->i_count) + inode->i_ddir_count)
+ if (atomic_read(&inode->i_count))
X goto done;
X }
X }
- if(IS_WRITABLE(inode) && sb->dq_op) {
+ if (IS_WRITABLE(inode) && sb->dq_op) {
X /* can operate in parallel to other ops ? */
X _io(sb->dq_op->drop, inode, 0, ST_TO_DROP);
- if(atomic_read(&inode->i_count) + inode->i_ddir_count)
+ if (atomic_read(&inode->i_count))
X goto done;
X }
X }
- if(inode->i_mmap)
+ if (inode->i_mmap)
X printk("VFS: inode has mappings\n");
- if(inode->i_status & ST_AGED) {
+ if (inode->i_status & ST_AGED) {
X printk("VFS: reaging inode\n");
X #if defined(DEBUG)
X printpath(inode->i_dentry);
@@ -546,11 +483,11 @@
X #endif
X goto done;
X }
- if(!(inode->i_status & (ST_HASHED|ST_EMPTY))) {
+ if (!(inode->i_status & (ST_HASHED|ST_EMPTY))) {
X _clear_inode(inode, 0, 1);
X goto done;
X }
- if(inode->i_status & ST_EMPTY) {
+ if (inode->i_status & ST_EMPTY) {
X printk("VFS: aging an empty inode\n");
X goto done;
X }
@@ -573,10 +510,10 @@


X struct inode * inode;

X vfs_lock();
X inode = all_i;
- if(inode) do {
+ if (inode) do {
X xcheck("sync_inodes",inode);
- if(inode->i_dirt && (inode->i_dev == dev || !dev)) {
- if(inode->i_sb && inode->i_sb->s_op &&
+ if (inode->i_dirt && (inode->i_dev == dev || !dev)) {
+ if (inode->i_sb && inode->i_sb->s_op &&
X !(inode->i_status & ST_FREEING)) {
X inode->i_dirt = 0;
X _io(inode->i_sb->s_op->write_inode, inode,
@@ -596,12 +533,12 @@
X vfs_lock();
X startover:
X inode = all_i;
- if(inode) do {
+ if (inode) do {
X struct inode * next;
X xcheck("_check_inodes",inode);
X next = inode->i_next;
- if(inode->i_dev == dev) {
- if(inode->i_dirt || atomic_read(&inode->i_count)) {
+ if (inode->i_dev == dev) {
+ if (inode->i_dirt || atomic_read(&inode->i_count)) {
X bad++;
X } else {
X _clear_inode(inode, 0, 0);
@@ -609,14 +546,14 @@
X /* _clear_inode() may recursively clear other
X * inodes, probably also the next one.
X */
- if(next->i_status & ST_EMPTY)
+ if (next->i_status & ST_EMPTY)
X goto startover;
X }
X }
X inode = next;
X } while(inode != all_i);
X vfs_unlock();
- if(complain && bad)
+ if (complain && bad)
X printk("VFS: %d inode(s) busy on removed device `%s'\n",
X bad, kdevname(dev));
X return (bad == 0);
@@ -642,16 +579,14 @@
X return 1; /* not checked any more */
X }
X
-int fs_may_umount(kdev_t dev, struct inode * mount_root)
+int fs_may_umount(kdev_t dev, struct dentry * root)
X {


X struct inode * inode;

X vfs_lock();
X inode = all_i;
- if(inode) do {
-xcheck("fs_may_umount",inode);
- if(inode->i_dev == dev && atomic_read(&inode->i_count))
- if(inode != mount_root || atomic_read(&inode->i_count) >
- (inode->i_mount == inode ? 2 : 1)) {
+ if (inode) do {
+ if (inode->i_dev == dev && atomic_read(&inode->i_count))
+ if (inode != root->d_inode) {
X vfs_unlock();
X return 0;
X }
@@ -668,7 +603,7 @@
X struct inode * inode = get_empty_inode();
X
X PIPE_BASE(*inode) = (char*)__get_free_page(GFP_USER);
- if(!(PIPE_BASE(*inode))) {
+ if (!(PIPE_BASE(*inode))) {
X iput(inode);
X return NULL;
X }
@@ -682,21 +617,6 @@
X inode->i_op = &pipe_inode_operations;
X PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
X
- /* I hope this does not introduce security problems.
- * Please check and give me response.
- */
- {
- char dummyname[32];
- struct qstr dummy = { dummyname, 0 };
- struct dentry * new;
- sprintf(dummyname, ".anonymous-pipe-%06lud", inode->i_ino);
- dummy.len = strlen(dummyname);
- vfs_lock();
- new = d_alloc(the_root, dummy.len, 0);
- if(new)
- d_add(new, inode, &dummy, D_BASKET);
- vfs_unlock();
- }
X return inode;
X }
X
diff -u --recursive --new-file v2.1.43/linux/fs/minix/namei.c linux/fs/minix/namei.c
--- v2.1.43/linux/fs/minix/namei.c Mon Jun 16 16:35:57 1997
+++ linux/fs/minix/namei.c Thu Jul 3 17:30:52 1997
@@ -697,7 +697,7 @@
X retval = -ENOENT;
X if (!old_bh)
X goto end_rename;
- old_inode = __iget(old_dir->i_sb, old_de->inode,0); /* don't cross mnt-points */
+ old_inode = __iget(old_dir->i_sb, old_de->inode);
X if (!old_inode)
X goto end_rename;
X retval = -EPERM;
@@ -707,7 +707,7 @@
X goto end_rename;
X new_bh = minix_find_entry(new_dir,new_name,new_len,&new_de);
X if (new_bh) {
- new_inode = __iget(new_dir->i_sb, new_de->inode, 0);
+ new_inode = __iget(new_dir->i_sb, new_de->inode);
X if (!new_inode) {
X brelse(new_bh);
X new_bh = NULL;
diff -u --recursive --new-file v2.1.43/linux/fs/namei.c linux/fs/namei.c
--- v2.1.43/linux/fs/namei.c Mon Jun 16 16:35:58 1997
+++ linux/fs/namei.c Mon Jul 7 14:48:23 1997
@@ -12,7 +12,6 @@
X * lookup logic.


X */
X
-#include <linux/config.h>

X #include <linux/errno.h>
X #include <linux/sched.h>
X #include <linux/kernel.h>
@@ -37,10 +36,6 @@
X #undef DEBUG /* some other debugging */
X
X
-/* local flags for __namei() */
-#define NAM_SEMLOCK 8 /* set a semlock on the last dir */
-#define NAM_TRANSCREATE 16 /* last component may be created, try "=CREATE#" suffix*/
-#define NAM_NO_TRAILSLASH 32 /* disallow trailing slashes by returning EISDIR */
X #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
X
X /* [Feb-1997 T. Schoebel-Theuer]
@@ -56,7 +51,7 @@
X * is done solely in the VFS level, such that <fs>_follow_link() is not
X * used any more and could be removed in future. As a side effect,
X * dir_namei(), _namei() and follow_link() are now replaced with a single
- * function __namei() that can handle all the special cases of the former
+ * function lookup_dentry() that can handle all the special cases of the former
X * code.
X *
X * With the new dcache, the pathname is stored at each inode, at least as
@@ -95,13 +90,13 @@
X char * res;
X down(&quicklock);
X res = quicklist;
- if(res) {
+ if (res) {
X #ifdef DEBUG
X char * tmp = res;
X int i;
X for(i=0; i<quickcount; i++)
X tmp = *(char**)tmp;
- if(tmp)
+ if (tmp)
X printk("bad quicklist %x\n", (int)tmp);
X #endif
X quicklist = *(char**)res;
@@ -113,9 +108,21 @@


X return res;
X }
X

+/*
+ * Kernel pointers have redundant information, so we can use a
+ * scheme where we can return either an error code or a dentry
+ * pointer with the same return value.

+ *


+ * This should be a per-architecture thing, to allow different
+ * error and pointer decisions.
+ */
+#define ERR_PTR(err) ((void *)((long)(err)))
+#define PTR_ERR(ptr) ((long)(ptr))
+#define IS_ERR(ptr) ((unsigned long)(ptr) > (unsigned long)(-1000))
+

X inline void putname(char * name)
X {
- if(name) {
+ if (name) {
X down(&quicklock);
X *(char**)name = quicklist;
X quicklist = name;
@@ -160,7 +167,7 @@
X int retval;
X
X tmp = get_page();
- if(!tmp)
+ if (!tmp)
X return -ENOMEM;
X retval = do_getname(filename, tmp);
X if (retval < 0)
@@ -222,417 +229,216 @@
X inode->i_writecount--;
X }
X
-static /*inline */ int concat(struct qstr * name, struct qstr * appendix, char * buf)
-{


- int totallen = name->len;

- if(name->len > MAX_TRANS_FILELEN ||
- appendix->len > MAX_TRANS_SUFFIX) {
- return -ENAMETOOLONG;
- }
- memcpy(buf, name->name, name->len);
- memcpy(buf + name->len, appendix->name, appendix->len);


- totallen += appendix->len;

- buf[totallen] = '\0';
- return totallen;
-}
-
-/* Internal lookup() using the new generic dcache.
- * buf must only be supplied if appendix!=NULL.
+/*
+ * This is called when everything else fails, and we actually have
+ * to go to the low-level filesystem to find out what we should do..
+ *
+ * We get the directory semaphore, and after getting that we also
+ * make sure that nobody added the entry to the dcache in the meantime..
X */
-static int cached_lookup(struct inode * dir, struct qstr * name,
- struct qstr * appendix, char * buf,
- struct qstr * res_name, struct dentry ** res_entry,


- struct inode ** result)

+static struct dentry * real_lookup(struct dentry * dentry, struct qstr * name)
X {
- struct qstr tmp = { name->name, name->len };
- int error;
- struct dentry * cached;
+ struct inode *dir = dentry->d_inode;
+ struct dentry *result;
+ struct inode *inode;
+ int error = -ENOTDIR;
X
- *result = NULL;
- if(name->len >= D_MAXLEN)
- return -ENAMETOOLONG;
- vfs_lock();
- cached = d_lookup(dir, name, appendix);
- if(cached) {
- struct inode *inode = NULL;
+ down(&dir->i_sem);
X
- if(cached->u.d_inode && (inode = d_inode(&cached))) {
- error = 0;
- if(appendix && res_name) {
- tmp.len = error = concat(name, appendix, buf);
- tmp.name = buf;
- if(error > 0)
- error = 0;
- }
- } else {
- error = -ENOENT;
+ error = -ENOTDIR;
+ if (dir->i_op && dir->i_op->lookup)
+ error = dir->i_op->lookup(dir, name, &inode);
+ result = ERR_PTR(error);
+
+ if (!error || error == -ENOENT) {
+ struct dentry *new;
+ int isdir = 0, flags = D_NOCHECKDUP;
+
+ if (error) {
+ flags = D_NEGATIVE;
+ inode = NULL;
+ } else if (S_ISDIR(inode->i_mode)) {
+ isdir = 1;
+ flags = D_DIR|D_NOCHECKDUP;
X }
- vfs_unlock();
- if(res_entry)
- *res_entry = cached;
+ new = d_alloc(dentry, name, isdir);
X
- /* Since we are bypassing the iget() mechanism, we have to
- * fabricate the act of crossing any mount points.
+ /*
+ * Ok, now we can't sleep any more. Double-check that
+ * nobody else added this in the meantime..
X */
- if(!error && inode && inode->i_mount) {
- do {
- struct inode *mnti = inode->i_mount;
- iinc(mnti);
- iput(inode);
- inode = mnti;
- } while(inode->i_mount);
+ result = d_lookup(dentry, name);
+ if (result) {
+ d_free(new);
+ } else {
+ d_add(new, inode, flags);
+ result = new;
X }
- *result = inode;
- goto done;
- } else
- vfs_unlock();
-
- if(appendix) {
- tmp.len = error = concat(name, appendix, buf);
- tmp.name = buf;
- if(error < 0)
- goto done;
- }
- atomic_inc(&dir->i_count);
- error = dir->i_op->lookup(dir, tmp.name, tmp.len, result);
- if(dir->i_dentry && tmp.len &&
- (!error || (error == -ENOENT && (!dir->i_sb || !dir->i_sb->s_type ||
- !(dir->i_sb->s_type->fs_flags & FS_NO_DCACHE))))) {


- struct dentry * res;

- vfs_lock();
- res = d_entry(dir->i_dentry, &tmp, error ? NULL : *result);
- vfs_unlock();
- if(res_entry)
- *res_entry = res;
X }
-done:
- if(res_name) {
- if(error) {
- res_name->name = name->name;
- res_name->len = name->len;
- } else {
- res_name->name = tmp.name;
- res_name->len = tmp.len;
- }
- }
- return error;
+ up(&dir->i_sem);


+ return result;
+}
+

+/* Internal lookup() using the new generic dcache. */
+static inline struct dentry * cached_lookup(struct dentry * dentry, struct qstr * name)
+{
+ return d_lookup(dentry, name);
X }
X
-#ifdef CONFIG_TRANS_NAMES
-/* If a normal filename is seen, try to determine whether a
- * "#keyword=context#" file exists and return the new filename.
- * If the name is to be created (create_mode), check whether a
- * "#keyword=CREATE" name exists and optionally return the corresponding
- * context name even if it didn't exist before.
+/*
+ * "." and ".." are special - ".." especially so because it has to be able
+ * to know about the current root directory and parent relationships
X */
-static int check_suffixes(struct inode * dir, struct qstr * name,
- int create_mode, char * buf,
- struct qstr * res_name, struct dentry ** res_entry,


- struct inode ** result)

-{
- struct translations * trans;
- char * env;
- struct qstr * suffixes;
- int i;
- int error = -ENOENT;
-
- if(!buf)
- panic("buf==NULL");
- env = env_transl();
-#ifdef CONFIG_TRANS_RESTRICT
- if(!env && dir->i_gid != CONFIG_TRANS_GID) {
- return error;
- }
-#endif
- trans = get_translations(env);
- suffixes = create_mode ? trans->c_name : trans->name;
- for(i = 0; i < trans->count; i++) {
- error = cached_lookup(dir, name, &suffixes[i],
- buf, res_name, res_entry, result);
- if(!error) {
- if(res_name && create_mode) {
- /* buf == res_name->name, but is writable */
- memcpy(buf + name->len,
- trans->name[i].name,
- trans->name[i].len);
- res_name->len = name->len + trans->name[i].len;
- buf[res_name->len] = '\0';
+static struct dentry * reserved_lookup(struct dentry * dir, struct qstr * name)
+{
+ struct dentry *result = NULL;
+ if (name->name[0] == '.') {
+ switch (name->len) {
+ default:


+ break;
+ case 2:

+ if (name->name[1] != '.')
+ break;
+
+ if (dir != current->fs->root) {
+ dir = dir->d_covers->d_parent;
X }
+ /* fallthrough */
+ case 1:
+ result = dget(dir);
X break;
X }
X }
- if(env)
- free_page((unsigned long)trans);
- return error;


+ return result;
X }
X

-#endif
-
-/* Any operations involving reserved names at the VFS level should go here. */
-static /*inline*/ int reserved_lookup(struct inode * dir, struct qstr * name,
- int create_mode, char * buf,


- struct inode ** result)

-{
- int error = -ENOENT;
- if(name->name[0] == '.') {
- if(name->len == 1) {
- *result = dir;
- error = 0;
- } else if (name->len==2 && name->name[1] == '.') {
- if (dir == current->fs->root) {
- *result = dir;
- error = 0;
- }
- else if(dir->i_dentry) {
- error = 0;
- *result = dir->i_dentry->d_parent->u.d_inode;
- if(!*result) {
- printk("dcache parent directory is lost");
- error = -ESTALE; /* random error */
- }
- }
+static inline int is_reserved(struct dentry *dentry)
+{
+ if (dentry->d_name.name[0] == '.') {
+ switch (dentry->d_name.len) {
+ case 2:
+ if (dentry->d_name.name[1] != '.')
+ break;
+ /* fallthrough */
+ case 1:
+ return 1;
X }
- if(!error)
- atomic_inc(&(*result)->i_count);
X }
- return error;
+ return 0;
X }
X
X /* In difference to the former version, lookup() no longer eats the dir. */
-static /*inline*/ int lookup(struct inode * dir, struct qstr * name, int create_mode,
- char * buf, struct qstr * res_name,
- struct dentry ** res_entry, struct inode ** result)
-{
- int perm;


-
- *result = NULL;

- perm = -ENOENT;
- if (!dir)
- goto done;
+static struct dentry * lookup(struct dentry * dir, struct qstr * name)
+{
+ int err;
+ struct dentry * result;
X
X /* Check permissions before traversing mount-points. */
- perm = permission(dir,MAY_EXEC);
- if (perm)
+ err = permission(dir->d_inode, MAY_EXEC);
+ result = ERR_PTR(err);
+ if (err)
X goto done;
- perm = reserved_lookup(dir, name, create_mode, buf, result);
- if(!perm) {
- if(res_name) {
- res_name->name = name->name;
- res_name->len = name->len;
- }
+
+ result = reserved_lookup(dir, name);
+ if (result)
X goto done;
- }
- perm = -ENOTDIR;
- if (!dir->i_op || !dir->i_op->lookup)
+
+ result = cached_lookup(dir, name);
+ if (result)
X goto done;
-#ifdef CONFIG_TRANS_NAMES /* try suffixes */
- perm = check_suffixes(dir, name, 0, buf, res_name, res_entry, result);
- if(perm) /* try original name */
-#endif
- perm = cached_lookup(dir, name, NULL, buf, res_name, res_entry, result);
-#ifdef CONFIG_TRANS_NAMES
- if(perm == -ENOENT && create_mode) { /* try the =CREATE# suffix */
- struct inode * dummy;
- if(!check_suffixes(dir, name, 1, buf, res_name, NULL, &dummy)) {
- iput(dummy);
- }
- }
-#endif
+
+ result = real_lookup(dir, name);
+ if (!result)
+ result = ERR_PTR(-ENOTDIR);
X done:
- return perm;
+ if (!IS_ERR(result))
+ result = dget(result->d_mounts);
+


+ return result;
X }
X

-/* [8-Feb-97 T. Schoebel-Theuer] follow_link() modified for generic operation
- * on the VFS layer: first call <fs>_readlink() and then open_namei().
- * All <fs>_follow_link() are not used any more and may be eliminated
- * (by Linus; I refrained in order to not break other patches).
- * Single exeption is procfs, where proc_follow_link() is used
- * internally (and perhaps should be rewritten).
- * Note: [partly obsolete] I removed parameters flag and mode, since now
- * __namei() is called instead of open_namei(). In the old semantics,
- * the _last_ instance of open_namei() did the real create() if O_CREAT was
- * set and the name existed already in form of a symlink. This has been
- * simplified now, and also the semantics when combined with O_EXCL has changed.
- ****************************************************************************
- * [13-Feb-97] Complete rewrite -> functionality of reading symlinks factored
- * out into _read_link(). The above notes remain valid in principle.
+/*
+ * This should check "link_count", but doesn't do that yet..
X */
-static /*inline*/ int _read_link(struct inode * inode, char ** linkname, int loopcount)
+static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry)
X {
- unsigned long old_fs;
- int error;


+ struct inode * inode = dentry->d_inode;

X
- error = -ENOSYS;
- if (!inode->i_op || !inode->i_op->readlink)
- goto done;
- error = -ELOOP;
- if (current->link_count + loopcount > 10)
- goto done;
- error = -ENOMEM;
- if(!*linkname && !(*linkname = get_page()))
- goto done;
- if (DO_UPDATE_ATIME(inode)) {
- inode->i_atime = CURRENT_TIME;
- inode->i_dirt = 1;
- }
- atomic_inc(&inode->i_count);
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- error = inode->i_op->readlink(inode, *linkname, PAGE_SIZE);
- set_fs(old_fs);
- if(!error) {
- error = -ENOENT; /* ? or other error code ? */
- } else if(error > 0) {
- (*linkname)[error] = '\0';
- error = 0;
+ if (inode->i_op && inode->i_op->follow_link) {
+ struct dentry *result;
+
+ /* This eats the base */
+ result = inode->i_op->follow_link(inode, base);
+ base = dentry;
+ dentry = result;
X }
-done:
- iput(inode);
- return error;
+ dput(base);
+ return dentry;
X }
X
-/* [13-Feb-97 T. Schoebel-Theuer] complete rewrite:
- * merged dir_name(), _namei() and follow_link() into one new routine
- * that obeys all the special cases hidden in the old routines in a
- * (hopefully) systematic way:
- * parameter retrieve_mode is bitwise or'ed of the ST_* flags.
- * if res_inode is a NULL pointer, dont try to retrieve the last component
- * at all. Parameters with prefix last_ are used only if res_inode is
- * non-NULL and refer to the last component of the path only.
+/*
+ * Name resolution.
+ *
+ * This is the basic name resolution function, turning a pathname
+ * into the final dentry.
X */
-int __namei(int retrieve_mode, const char * name, struct inode * base,
- char * buf, struct inode ** res_dir, struct inode ** res_inode,
- struct qstr * last_name, struct dentry ** last_entry,
- int * last_error)
-{
- char c;
- struct qstr this;
- char * linkname = NULL;
- char * oldlinkname = NULL;
- int trail_flag = 0;
- int loopcount = 0;
- int error;
-#ifdef DEBUG
- if(last_name) {
- last_name->name = "(Uninitialized)";
- last_name->len = 15;
- }
-#endif
-again:
- error = -ENOENT;
- this.name = name;
- if (this.name[0] == '/') {
- if(base)
- iput(base);
- if (__prefix_namei(retrieve_mode, this.name, base, buf,
- res_dir, res_inode,
- last_name, last_entry, last_error) == 0)
- return 0;
- base = current->fs->root;
- atomic_inc(&base->i_count);
- this.name++;
+struct dentry * lookup_dentry(const char * name, struct dentry * base, int follow_link)
+{
+ struct dentry * dentry;
+
+ if (*name == '/') {
+ if (base)
+ dput(base);
+ base = dget(current->fs->root);
+ do {
+ name++;
+ } while (*name == '/');
X } else if (!base) {
- base = current->fs->pwd;
- atomic_inc(&base->i_count);
+ base = dget(current->fs->pwd);
X }
+
+ if (*name == '\0')
+ return base;
+
+ /* At this point we know we have a real path component. */
X for(;;) {


- struct inode * inode;

- const char * tmp = this.name;
X int len;
+ unsigned long hash;
+ struct qstr this;
+ char c, trailing;
+
+ this.name = name;
+ hash = init_name_hash();
+ for (len = 0; (c = *name++) && (c != '/') ; len++)
+ hash = partial_name_hash(c, hash);
X
- for(len = 0; (c = *tmp++) && (c != '/'); len++) ;
X this.len = len;
- if(!c)
- break;
- while((c = *tmp) == '/') /* remove embedded/trailing slashes */
- tmp++;
- if(!c) {
- trail_flag = 1;
- if(retrieve_mode & NAM_NO_TRAILSLASH) {
- error = -EISDIR;
- goto alldone;
- }
- break;
- }
-#if 0
- if(atomic_read(&base->i_count) == 0)
- printk("vor lookup this=%s tmp=%s\n", this.name, tmp);
-#endif
- error = lookup(base, &this, 0, buf, NULL, NULL, &inode);
-#if 0
- if(atomic_read(&base->i_count) == 0)
- printk("nach lookup this=%s tmp=%s\n", this.name, tmp);
-#endif
- if (error)
- goto alldone;
- if(S_ISLNK(inode->i_mode)) {
- error = _read_link(inode, &linkname, loopcount);
- if(error)
- goto alldone;
- current->link_count++;
- error = __namei((retrieve_mode &
- ~(NAM_SEMLOCK|NAM_TRANSCREATE|NAM_NO_TRAILSLASH))
- | NAM_FOLLOW_LINK,
- linkname, base, buf,
- &base, &inode, NULL, NULL, NULL);
- current->link_count--;
- if(error)
- goto alldone;
- }
-#if 0
- if(atomic_read(&base->i_count) == 0)
- printk("this=%s tmp=%s\n", this.name, tmp);
-#endif
- this.name = tmp;
- iput(base);
- base = inode;
- }
- if(res_inode) {
- if(retrieve_mode & NAM_SEMLOCK)
- down(&base->i_sem);
- error = lookup(base, &this, retrieve_mode & NAM_TRANSCREATE,
- buf, last_name, last_entry, res_inode);
- if(!error && S_ISLNK((*res_inode)->i_mode) &&
- ((retrieve_mode & NAM_FOLLOW_LINK) ||
- (trail_flag && (retrieve_mode & NAM_FOLLOW_TRAILSLASH)))) {
- char * tmp;
-
- error = _read_link(*res_inode, &linkname, loopcount);
- if(error)
- goto lastdone;
- if(retrieve_mode & NAM_SEMLOCK)
- up(&base->i_sem);
- /* exchange pages */
- name = tmp = linkname;
- linkname = oldlinkname; oldlinkname = tmp;
- loopcount++;
- goto again; /* Tail recursion elimination "by hand",
- * uses less dynamic memory.
- */
-
- /* Note that trail_flag is not reset, so it
- * does not matter in a symlink chain where a
- * trailing slash indicates a directory endpoint.
- */
- }
- if(!error && trail_flag && !S_ISDIR((*res_inode)->i_mode)) {
- iput(*res_inode);
- error = -ENOTDIR;
+ this.hash = end_name_hash(hash);
+
+ /* remove trailing slashes? */
+ trailing = c;
+ if (c) {
+ while ((c = *name) == '/')
+ name++;
X }
- lastdone:
- if(last_error) {
- *last_error = error;
- error = 0;
+
+ dentry = lookup(base, &this);
+ if (IS_ERR(dentry))
+ break;
+ if (dentry->d_flag & D_NEGATIVE)
+ break;
+
+ /* Last component? */
+ if (!c) {
+ if (!trailing && !follow_link)
+ break;
+ return do_follow_link(base, dentry);
X }
+
+ base = do_follow_link(base, dentry);
X }
-alldone:
- if(!error && res_dir)
- *res_dir = base;
- else
- iput(base);
- putname(linkname);
- putname(oldlinkname);
- return error;
+ dput(base);
+ return dentry;
X }
X
X /*
@@ -641,26 +447,55 @@
X * is used by most simple commands to get the inode of a specified name.
X * Open, link etc use their own routines, but this is enough for things
X * like 'chmod' etc.
+ *
+ * namei exists in two versions: namei/lnamei. The only difference is
+ * that namei follows links, while lnamei does not.
X */
-
-/* [Feb 1997 T.Schoebel-Theuer] lnamei() completely removed; can be
- * simulated when calling with retrieve_mode==NAM_FOLLOW_TRAILSLASH.
- */
-int namei(int retrieve_mode, const char *pathname, struct inode **res_inode)
+int __namei(const char *pathname, struct inode **res_inode, int follow_link)
X {
X int error;
- char * tmp;
+ char * name;
X
- error = getname(pathname, &tmp);
+ error = getname(pathname, &name);
X if (!error) {
- char buf[MAX_TRANS_FILELEN+MAX_TRANS_SUFFIX+2];
- error = __namei(retrieve_mode, tmp, NULL,
- buf, NULL, res_inode, NULL, NULL, NULL);
- putname(tmp);
+ struct dentry * dentry;
+
+ dentry = lookup_dentry(name, NULL, follow_link);
+ putname(name);


+ error = PTR_ERR(dentry);
+ if (!IS_ERR(dentry)) {
+ error = -ENOENT;
+ if (dentry) {

+ if (!(dentry->d_flag & D_NEGATIVE)) {
+ struct inode *inode = dentry->d_inode;
+ atomic_inc(&inode->i_count);
+ *res_inode = inode;


+ error = 0;
+ }

+ dput(dentry);
+ }
+ }
X }


X return error;
X }
X

+static inline struct inode *get_parent(struct dentry *dentry)
+{
+ struct inode *dir = dentry->d_parent->d_inode;
+
+ atomic_inc(&dir->i_count);
+ return dir;
+}
+
+static inline struct inode *lock_parent(struct dentry *dentry)
+{
+ struct inode *dir = dentry->d_parent->d_inode;
+
+ atomic_inc(&dir->i_count);
+ down(&dir->i_sem);
+ return dir;
+}
+
X /*
X * open_namei()
X *
@@ -675,172 +510,155 @@
X * for symlinks (where the permissions are checked later).
X */
X int open_namei(const char * pathname, int flag, int mode,


- struct inode ** res_inode, struct inode * base)
+ struct inode ** res_inode, struct dentry * base)

X {
- char buf[MAX_TRANS_FILELEN+MAX_TRANS_SUFFIX+2];
- struct qstr last;
X int error;
- int lasterror;
- struct inode * dir, * inode;
- int namei_mode;
+ struct inode *inode;
+ struct dentry *dentry;
X
X mode &= S_IALLUGO & ~current->fs->umask;
X mode |= S_IFREG;
X
- namei_mode = NAM_FOLLOW_LINK;
- if(flag & O_CREAT)
- namei_mode |= NAM_SEMLOCK|NAM_TRANSCREATE|NAM_NO_TRAILSLASH;
- error = __namei(namei_mode, pathname, base, buf,
- &dir, &inode, &last, NULL, &lasterror);
- if (error)
- goto exit;
- error = lasterror;
+ dentry = lookup_dentry(pathname, base, 1);
+ if (IS_ERR(dentry))
+ return PTR_ERR(dentry);
+
X if (flag & O_CREAT) {
- if (!error) {
- if (flag & O_EXCL) {
+ struct inode *dir;
+
+ dir = lock_parent(dentry);
+ /*
+ * The existence test must be done _after_ getting the directory
+ * semaphore - the dentry might otherwise change.
+ */
+ if (!(dentry->d_flag & D_NEGATIVE)) {
+ error = 0;
+ if (flag & O_EXCL)
X error = -EEXIST;
- }
X } else if (IS_RDONLY(dir))
X error = -EROFS;
X else if (!dir->i_op || !dir->i_op->create)
X error = -EACCES;
- else if ((error = permission(dir,MAY_WRITE | MAY_EXEC)) != 0)
- ; /* error is already set! */
- else {
- d_del(d_lookup(dir, &last, NULL), D_REMOVE);
- atomic_inc(&dir->i_count); /* create eats the dir */
+ else if ((error = permission(dir,MAY_WRITE | MAY_EXEC)) == 0) {
X if (dir->i_sb && dir->i_sb->dq_op)
X dir->i_sb->dq_op->initialize(dir, -1);
- error = dir->i_op->create(dir, last.name, last.len,
- mode, res_inode);
-#ifdef CONFIG_OMIRR
- if(!error)
- omirr_print(dir->i_dentry, NULL, &last,
- " c %ld %d ", CURRENT_TIME, mode);
-#endif
- up(&dir->i_sem);
- goto exit_dir;
+ error = dir->i_op->create(dir, dentry, mode);
X }
X up(&dir->i_sem);
+ iput(dir);
+ if (error)
+ goto exit;
X }
+
+ error = -ENOENT;
+ if (dentry->d_flag & D_NEGATIVE)
+ goto exit;
+
+ inode = dentry->d_inode;
+ error = -EISDIR;
+ if (S_ISDIR(inode->i_mode) && (flag & 2))
+ goto exit;
+
+ error = permission(inode,ACC_MODE(flag));
X if (error)
- goto exit_inode;
+ goto exit;
X
- if (S_ISDIR(inode->i_mode) && (flag & 2)) {
- error = -EISDIR;
- goto exit_inode;
- }
- if ((error = permission(inode,ACC_MODE(flag))) != 0) {
- goto exit_inode;
- }
+ /*
+ * FIFO's, sockets and device files are special: they don't
+ * actually live on the filesystem itself, and as such you
+ * can write to them even if the filesystem is read-only.
+ */
X if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
- /*
- * 2-Feb-1995 Bruce Perens <Br...@Pixar.com>
- * Allow opens of Unix domain sockets and FIFOs for write on
- * read-only filesystems. Their data does not live on the disk.
- *
- * If there was something like IS_NODEV(inode) for
- * pipes and/or sockets I'd check it here.
- */
X flag &= ~O_TRUNC;
- }
- else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
- if (IS_NODEV(inode)) {
- error = -EACCES;
- goto exit_inode;
- }
+ } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
+ error = -EACCES;
+ if (IS_NODEV(inode))
+ goto exit;
+
X flag &= ~O_TRUNC;
X } else {
- if (IS_RDONLY(inode) && (flag & 2)) {
- error = -EROFS;
- goto exit_inode;
- }
+ error = -EROFS;
+ if (IS_RDONLY(inode) && (flag & 2))
+ goto exit;
X }
X /*
X * An append-only file must be opened in append mode for writing.
X */
- if (IS_APPEND(inode) && ((flag & FMODE_WRITE) && !(flag & O_APPEND))) {
- error = -EPERM;
- goto exit_inode;
- }
+ error = -EPERM;
+ if (IS_APPEND(inode) && ((flag & FMODE_WRITE) && !(flag & O_APPEND)))
+ goto exit;
+
X if (flag & O_TRUNC) {
- if ((error = get_write_access(inode)))
- goto exit_inode;
+ error = get_write_access(inode);
+ if (error)
+ goto exit;
+
X /*
X * Refuse to truncate files with mandatory locks held on them.
X */
X error = locks_verify_locked(inode);
- if (error)
- goto exit_inode;
- if (inode->i_sb && inode->i_sb->dq_op)


SHAR_EOF
true || echo 'restore of patch-2.1.44 failed'
fi

echo 'End of part 31'
echo 'File patch-2.1.44 is continued in part 32'
echo 32 > _shar_seq_.tmp

0 new messages