Linux Kernel Patch v2.3, patch-2.3.6 (00/27)

22 views
Skip to first unread message

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.3/patch-2.3.6/part00

lines added deleted
linux/CREDITS : 7 -1 -1
linux/Documentation/Configure.help : 54 24 2
linux/Documentation/filesystems/hpfs.txt : 121 62 27
linux/Documentation/mtrr.txt : 14 3 1
linux/MAINTAINERS : 33 18 8
linux/Makefile : 25 12 0
linux/arch/alpha/kernel/ptrace.c : 7 1 1
linux/arch/alpha/lib/memcpy.c : 26 0 20
linux/arch/arm/kernel/ptrace.c : 154 77 11
linux/arch/i386/Makefile : 25 0 19
linux/arch/i386/boot/bootsect.S : 13 7 0
linux/arch/i386/config.in : 14 2 2
linux/arch/i386/defconfig : 19 6 0
linux/arch/i386/kernel/mca.c : 45 18 0
linux/arch/i386/kernel/ptrace.c : 106 29 18
linux/arch/i386/kernel/setup.c : 25 0 19
linux/arch/i386/kernel/signal.c : 43 15 7
linux/arch/i386/mm/init.c : 7 1 0
linux/arch/i386/mm/ioremap.c : 19 4 1
linux/arch/i386/vmlinux.lds : 34 8 9
linux/arch/i386/vmlinux.lds.S : 14 2 2
linux/arch/m68k/kernel/ptrace.c : 69 69 0
linux/arch/mips/kernel/irixelf.c : 25 0 19
linux/arch/mips/kernel/ptrace.c : 42 4 11
linux/arch/mips/kernel/sysirix.c : 25 0 19
linux/arch/ppc/chrpboot/Makefile : 29 3 6
linux/arch/ppc/chrpboot/main.c : 31 5 5
linux/arch/ppc/chrpboot/mknote.c : 72 12 18
linux/arch/ppc/coffboot/zlib.c : 43 43 0
linux/arch/ppc/common_defconfig : 20 6 1
linux/arch/ppc/config.in : 157 62 14
linux/arch/ppc/defconfig : 7 1 0
linux/arch/ppc/kernel/chrp_pci.c : 121 34 13
linux/arch/ppc/kernel/chrp_setup.c : 106 74 5
linux/arch/ppc/kernel/head.S : 145 61 26
linux/arch/ppc/kernel/idle.c : 24 1 3
linux/arch/ppc/kernel/irq.c : 14 2 1
linux/arch/ppc/kernel/misc.S : 14 1 2
linux/arch/ppc/kernel/prom.c : 11 4 0
linux/arch/ppc/kernel/ptrace.c : 94 23 7
linux/arch/ppc/kernel/smp.c : 25 0 19
linux/arch/ppc/kernel/syscalls.c : 19 4 1
linux/arch/ppc/kernel/time.c : 23 5 9
linux/arch/ppc/mm/init.c : 25 6 2
linux/arch/ppc/xmon/xmon.c : 15 2 2
linux/arch/sparc/Makefile : 8 1 1
linux/arch/sparc/kernel/ebus.c : 14 2 2
linux/arch/sparc/kernel/entry.S : 161 75 17
linux/arch/sparc/kernel/head.S : 59 49 1
linux/arch/sparc/kernel/pcic.c : 45 9 3
linux/arch/sparc/kernel/ptrace.c : 581 325 94
linux/arch/sparc/kernel/setup.c : 26 0 20
linux/arch/sparc/kernel/sys_sunos.c : 13 2 1
linux/arch/sparc64/Makefile : 27 2 6
linux/arch/sparc64/defconfig : 14 2 2
linux/arch/sparc64/kernel/binfmt_aout32.c : 8 2 0
linux/arch/sparc64/kernel/ioctl32.c : 82 16 23
linux/arch/sparc64/kernel/ptrace.c : 48 23 1
linux/arch/sparc64/kernel/signal.c : 26 0 20
linux/arch/sparc64/kernel/sys_sparc.c : 110 8 60
linux/arch/sparc64/kernel/sys_sparc32.c : 45 1 34
linux/arch/sparc64/kernel/sys_sunos32.c : 119 42 31
linux/arch/sparc64/kernel/systbls.S : 27 2 6
linux/arch/sparc64/kernel/traps.c : 14 2 2
linux/arch/sparc64/math-emu/sfp-util.h : 25 9 4
linux/drivers/Makefile : 14 2 2
linux/drivers/block/cy82c693.c : 15 9 0
linux/drivers/block/floppy.c : 9 2 1
linux/drivers/block/ide-pmac.c : 17 1 3
linux/drivers/block/ll_rw_blk.c : 43 7 13
linux/drivers/block/ns87415.c : 16 3 0
linux/drivers/block/piix.c : 17 4 2
linux/drivers/block/rd.c : 252 88 52
linux/drivers/char/adbmouse.c : 8 1 1
linux/drivers/char/bttv.c : 8 1 1
linux/drivers/char/bttv.h : 59 25 0
linux/drivers/char/misc.c : 47 19 1
linux/drivers/char/radio-cadet.c : 19 5 1
linux/drivers/char/rtc.c : 35 7 8
linux/drivers/char/tuner.c : 130 53 10
linux/drivers/char/tuner.h : 10 3 1
linux/drivers/i2o/Config.in : 7 1 0
linux/drivers/i2o/Makefile : 12 12 0
linux/drivers/i2o/README : 75 75 0
linux/drivers/i2o/README.ioctl : 78 78 0
linux/drivers/i2o/README.lan : 398 398 0
linux/drivers/i2o/i2o_block.c : 38 38 0
linux/drivers/i2o/i2o_config.c : 1071 1071 0
linux/drivers/i2o/i2o_core.c : 613 613 0
linux/drivers/i2o/i2o_lan.c : 2053 2053 0
linux/drivers/i2o/i2o_lan.h : 853 853 0
linux/drivers/i2o/i2o_pci.c : 112 112 0
linux/drivers/i2o/i2o_proc.c : 243 243 0
linux/drivers/i2o/i2o_proc.h : 2382 2382 0
linux/drivers/i2o/i2o_scsi.c : 141 141 0
linux/drivers/i2o/i2o_scsi.h : 871 871 0
linux/drivers/macintosh/Makefile : 48 48 0
linux/drivers/macintosh/adb.c : 8 2 0
linux/drivers/macintosh/mac_keyb.c : 34 4 3
linux/drivers/macintosh/macserial.c : 7 0 1
linux/drivers/misc/BUGS-parport : 52 8 8
linux/drivers/misc/Makefile : 4 1 0
linux/drivers/misc/TODO-parport : 10 4 0
linux/drivers/misc/parport_amiga.c : 5 2 0
linux/drivers/misc/parport_arc.c : 60 10 20
linux/drivers/misc/parport_atari.c : 81 28 11
linux/drivers/misc/parport_ax.c : 64 11 20
linux/drivers/misc/parport_init.c : 111 26 37
linux/drivers/misc/parport_mfc3.c : 50 12 5
linux/drivers/misc/parport_pc.c : 53 10 16
linux/drivers/misc/parport_procfs.c : 456 225 80
linux/drivers/misc/parport_share.c : 726 321 296
linux/drivers/net/3c515.c : 90 9 40
linux/drivers/net/Config.in : 23 3 0
linux/drivers/net/Makefile : 20 7 0
linux/drivers/net/Space.c : 48 28 0
linux/drivers/net/cosa.c : 17 4 0
linux/drivers/net/cs89x0.c : 35 8 1
linux/drivers/net/cycx_drv.c : 8 1 1
linux/drivers/net/cycx_main.c : 663 663 0
linux/drivers/net/cycx_x25.c : 377 377 0
linux/drivers/net/irda/Config.in : 1538 1538 0
linux/drivers/net/irda/Makefile : 7 1 0
linux/drivers/net/irda/actisys.c : 76 56 0
linux/drivers/net/irda/esi.c : 39 3 8
linux/drivers/net/irda/girbil.c : 37 3 7
linux/drivers/net/irda/irport.c : 75 11 11
linux/drivers/net/irda/litelink.c : 509 168 84
linux/drivers/net/irda/pc87108.c : 110 15 18
linux/drivers/net/irda/smc-ircc.c : 423 107 106
linux/drivers/net/irda/tekram.c : 969 969 0
linux/drivers/net/irda/uircc.c : 91 14 13
linux/drivers/net/irda/w83977af_ir.c : 44 5 5
linux/drivers/net/myri_sbus.c : 26 1 5
linux/drivers/net/ni52.c : 7 1 0
linux/drivers/net/ni52.h : 8 1 1
linux/drivers/net/ni65.c : 8 1 1
linux/drivers/net/ptifddi.c : 36 6 2
linux/drivers/net/sdladrv.c : 5 1 1
linux/drivers/net/sdlamain.c : 33 1 5
linux/drivers/net/sk_mca.c : 24 3 1
linux/drivers/net/sk_mca.h : 1143 1143 0
linux/drivers/pci/oldproc.c : 175 174 0
linux/drivers/sbus/char/Config.in : 81 23 1
linux/drivers/sbus/char/aurora.c : 10 6 0
linux/drivers/sbus/char/bpp.c : 15 1 1
linux/drivers/sbus/char/pcikbd.c : 8 1 1
linux/drivers/sbus/char/rtc.c : 122 28 20
linux/drivers/sbus/char/su.c : 36 10 3
linux/drivers/sbus/char/vfc_dev.c : 611 181 195
linux/drivers/scsi/Config.in : 19 2 3
linux/drivers/scsi/README.aic7xxx : 12 2 4
linux/drivers/scsi/aic7xxx/aic7xxx.reg : 63 17 12
linux/drivers/scsi/aic7xxx/aic7xxx.seq : 145 78 0
linux/drivers/scsi/aic7xxx/scsi_message.h : 509 137 112
linux/drivers/scsi/aic7xxx.c : 13 9 1
linux/drivers/scsi/aic7xxx_proc.c : 3280 1316 669
linux/drivers/scsi/aic7xxx_reg.h : 105 32 23
linux/drivers/scsi/aic7xxx_seq.c : 91 42 0
linux/drivers/scsi/scsi.c : 986 344 315
linux/drivers/scsi/scsi.h : 18 3 2
linux/drivers/scsi/scsi_proc.c : 7 1 0
linux/drivers/scsi/scsi_syms.c : 8 1 1
linux/drivers/scsi/scsicam.c : 22 2 3
linux/drivers/scsi/sd.c : 37 4 5
linux/drivers/scsi/sg.c : 28 4 4
linux/drivers/sound/dmasound.c : 1160 407 270
linux/drivers/sound/sound_core.c : 97 52 0
linux/drivers/usb/CREDITS : 31 17 1
linux/drivers/usb/Config.in : 7 1 0
linux/drivers/usb/Makefile : 12 5 1
linux/drivers/usb/README.ohci : 31 16 0
linux/drivers/usb/acm.c : 9 6 0
linux/drivers/usb/audio.c : 34 6 6
linux/drivers/usb/cpia.c : 17 2 2
linux/drivers/usb/hub.c : 17 2 2
linux/drivers/usb/keyboard.c : 39 6 6
linux/drivers/usb/keymap-mac.c : 33 7 2
linux/drivers/usb/maps/mac.map : 50 50 0
linux/drivers/usb/mkmap.adb : 350 350 0
linux/drivers/usb/mouse.c : 88 88 0
linux/drivers/usb/ohci-debug.c : 17 2 2
linux/drivers/usb/ohci.c : 83 21 17
linux/drivers/usb/ohci.h : 729 230 141
linux/drivers/usb/printer.c : 53 14 12
linux/drivers/usb/stopusb : 35 6 5
linux/drivers/usb/uhci.c : 9 2 2
linux/drivers/usb/uhci.h : 362 150 49
linux/drivers/usb/usb-core.c : 11 2 1
linux/drivers/usb/usb-debug.c : 18 4 1
linux/drivers/usb/usb.c : 22 11 4
linux/drivers/usb/usb.h : 336 136 40
linux/drivers/usb/usb_scsi.c : 151 66 20
linux/drivers/usb/usb_scsi.h : 1098 1098 0
linux/drivers/usb/usb_scsi_debug.c : 145 145 0
linux/drivers/usb/usb_scsi_dt.c : 104 104 0
linux/drivers/video/atyfb.c : 4 4 0
linux/drivers/video/igafb.c : 192 40 21
linux/fs/Config.in : 88 32 12
linux/fs/adfs/super.c : 12 3 3
linux/fs/affs/super.c : 18 2 3
linux/fs/autofs/inode.c : 8 1 1
linux/fs/binfmt_aout.c : 8 1 1
linux/fs/binfmt_elf.c : 69 8 22
linux/fs/buffer.c : 53 6 14
linux/fs/coda/inode.c : 8 1 1
linux/fs/dcache.c : 17 2 2
linux/fs/devpts/inode.c : 8 1 1
linux/fs/efs/super.c : 8 1 1
linux/fs/ext2/super.c : 8 1 1
linux/fs/ext2/symlink.c : 8 1 1
linux/fs/fat/inode.c : 7 0 1
linux/fs/fcntl.c : 8 1 1
linux/fs/hfs/bnode.c : 74 31 22
linux/fs/hfs/btree.c : 8 2 0
linux/fs/hfs/catalog.c : 8 1 1
linux/fs/hfs/mdb.c : 8 2 0
linux/fs/hfs/super.c : 10 3 1
linux/fs/hpfs/alloc.c : 8 1 1
linux/fs/hpfs/hpfs_fn.h : 13 5 2
linux/fs/hpfs/namei.c : 8 1 1
linux/fs/hpfs/super.c : 32 6 11
linux/fs/isofs/inode.c : 8 1 1
linux/fs/minix/bitmap.c : 8 1 1
linux/fs/minix/inode.c : 35 4 4
linux/fs/minix/namei.c : 8 1 1
linux/fs/ncpfs/inode.c : 13 1 6
linux/fs/nfs/dir.c : 8 1 1
linux/fs/nfs/inode.c : 733 335 229
linux/fs/nfs/nfs2xdr.c : 101 22 10
linux/fs/nfs/proc.c : 297 104 98
linux/fs/nfs/read.c : 86 0 73
linux/fs/nfs/symlink.c : 7 1 0
linux/fs/nfs/write.c : 197 121 50
linux/fs/nfsd/export.c : 43 16 3
linux/fs/nfsd/nfsfh.c : 19 2 3
linux/fs/ntfs/fs.c : 26 3 3
linux/fs/pipe.c : 8 1 1
linux/fs/proc/Makefile : 8 1 1
linux/fs/proc/inode.c : 8 1 1
linux/fs/proc/link.c : 8 1 1
linux/fs/proc/root.c : 8 1 1
linux/fs/proc/sysvipc.c : 18 4 1
linux/fs/qnx4/inode.c : 138 138 0
linux/fs/romfs/inode.c : 8 1 1
linux/fs/smbfs/dir.c : 8 1 1
linux/fs/smbfs/inode.c : 8 1 1
linux/fs/super.c : 8 1 1
linux/fs/sysv/inode.c : 33 13 13
linux/fs/ufs/super.c : 8 1 1
linux/fs/umsdos/check.c : 8 1 1
linux/include/asm-alpha/softirq.h : 8 1 1
linux/include/asm-alpha/spinlock.h : 16 10 0
linux/include/asm-alpha/string.h : 100 29 37
linux/include/asm-alpha/system.h : 7 1 0
linux/include/asm-i386/bugs.h : 11 5 0
linux/include/asm-i386/page.h : 21 11 3
linux/include/asm-i386/page_offset.h : 11 4 1
linux/include/asm-mips/namei.h : 8 8 0
linux/include/asm-ppc/system.h : 8 1 1
linux/include/asm-sparc/io.h : 18 5 0
linux/include/asm-sparc/namei.h : 21 10 1
linux/include/asm-sparc/pcic.h : 8 1 1
linux/include/asm-sparc64/namei.h : 52 16 2
linux/include/linux/cyclomx.h : 8 1 1
linux/include/linux/cycx_cfm.h : 91 91 0
linux/include/linux/cycx_drv.h : 81 81 0
linux/include/linux/cycx_x25.h : 66 66 0
linux/include/linux/dcache.h : 103 103 0
linux/include/linux/file.h : 57 7 10
linux/include/linux/fs.h : 19 4 4
linux/include/linux/i2o.h : 277 59 65
linux/include/linux/igmp.h : 588 588 0
linux/include/linux/inet.h : 20 1 13
linux/include/linux/inetdevice.h : 7 1 0
linux/include/linux/mm.h : 8 1 1
linux/include/linux/netdevice.h : 16 3 0
linux/include/linux/nfs.h : 29 9 0
linux/include/linux/nfs_fs.h : 39 8 9
linux/include/linux/nfs_fs_i.h : 37 2 7
linux/include/linux/pagemap.h : 10 4 0
linux/include/linux/parport.h : 7 1 0
linux/include/linux/pci.h : 60 7 10
linux/include/linux/pkt_sched.h : 71 22 1
linux/include/linux/proc_fs.h : 9 3 0
linux/include/linux/rtnetlink.h : 46 11 1
linux/include/linux/sched.h : 152 15 114
linux/include/linux/sysctl.h : 79 21 24
linux/include/linux/wanrouter.h : 43 31 1
linux/include/net/addrconf.h : 49 9 2
linux/include/net/dst.h : 16 2 1
linux/include/net/if_inet6.h : 9 3 0
linux/include/net/ip.h : 15 2 0
linux/include/net/irda/dongle.h : 13 3 3
linux/include/net/irda/ircomm_common.h : 27 4 4
linux/include/net/irda/irda_device.h : 23 5 5
linux/include/net/irda/irlan_common.h : 25 3 3
linux/include/net/irda/irlan_eth.h : 36 7 2
linux/include/net/irda/irport.h : 20 3 2
linux/include/net/irda/irqueue.h : 25 4 3
linux/include/net/irda/irvtd.h : 17 1 3
linux/include/net/irda/smc-ircc.h : 18 4 1
linux/include/net/irda/smc_ircc.h : 160 160 0
linux/include/net/neighbour.h : 123 0 123
linux/include/net/pkt_cls.h : 76 16 23
linux/include/net/pkt_sched.h : 17 3 6
linux/include/net/route.h : 138 88 7
linux/include/net/tcp.h : 21 1 7
linux/include/net/udp.h : 8 1 1
linux/include/scsi/scsicam.h : 15 7 1
linux/include/scsi/sg.h : 6 2 0
linux/ipc/msg.c : 272 87 90
linux/ipc/sem.c : 95 59 1
linux/ipc/shm.c : 90 56 0
linux/kernel/ksyms.c : 96 60 0
linux/kernel/signal.c : 16 2 1
linux/kernel/sys.c : 24 3 1
linux/mm/memory.c : 8 2 0
linux/mm/mmap.c : 120 18 31
linux/mm/mremap.c : 186 110 20
linux/mm/swapfile.c : 30 2 2
linux/net/core/dev.c : 16 2 1
linux/net/core/dev_mcast.c : 497 104 131
linux/net/core/dst.c : 156 34 16
linux/net/core/neighbour.c : 66 38 4
linux/net/core/rtnetlink.c : 886 223 113
linux/net/decnet/dn_neigh.c : 90 9 21
linux/net/ethernet/eth.c : 41 10 4
linux/net/ipv4/af_inet.c : 7 1 0
linux/net/ipv4/arp.c : 17 2 2
linux/net/ipv4/devinet.c : 264 38 46
linux/net/ipv4/fib_frontend.c : 78 10 10
linux/net/ipv4/fib_hash.c : 22 1 3
linux/net/ipv4/fib_rules.c : 207 17 21
linux/net/ipv4/icmp.c : 146 21 19
linux/net/ipv4/igmp.c : 39 6 6
linux/net/ipv4/ip_input.c : 333 81 19
linux/net/ipv4/ip_masq_vdolive.c : 32 3 7
linux/net/ipv4/ip_options.c : 8 1 1
linux/net/ipv4/ipconfig.c : 8 1 1
linux/net/ipv4/ipmr.c : 24 3 3
linux/net/ipv4/route.c : 36 6 3
linux/net/ipv4/tcp_input.c : 28 4 3
linux/net/ipv4/tcp_ipv4.c : 8 1 1
linux/net/ipv4/udp.c : 8 1 1
linux/net/ipv4/utils.c : 114 51 19
linux/net/ipv6/addrconf.c : 20 6 1
linux/net/ipv6/af_inet6.c : 102 13 16
linux/net/ipv6/ip6_fw.c : 17 2 2
linux/net/ipv6/ip6_output.c : 17 2 2
linux/net/ipv6/mcast.c : 31 4 13
linux/net/ipv6/ndisc.c : 378 76 22
linux/net/ipv6/raw.c : 163 29 23
linux/net/ipv6/reassembly.c : 26 1 12
linux/net/ipv6/route.c : 8 1 1
linux/net/ipv6/tcp_ipv6.c : 46 12 3
linux/net/ipv6/udp.c : 8 1 1
linux/net/irda/Config.in : 27 1 13
linux/net/irda/af_irda.c : 54 20 23
linux/net/irda/discovery.c : 72 12 8
linux/net/irda/ircomm/ircomm_common.c : 41 8 6
linux/net/irda/ircomm/irvtd_driver.c : 168 32 27
linux/net/irda/irda_device.c : 374 114 43
linux/net/irda/irlan/irlan_client.c : 207 66 30
linux/net/irda/irlan/irlan_client_event.c : 30 8 2
linux/net/irda/irlan/irlan_common.c : 8 1 1
linux/net/irda/irlan/irlan_eth.c : 293 93 34
linux/net/irda/irlan/irlan_filter.c : 208 50 56
linux/net/irda/irlap.c : 16 2 1
linux/net/irda/irlap_event.c : 1069 273 273
linux/net/irda/irlap_frame.c : 264 31 64
linux/net/irda/irlmp.c : 44 2 15
linux/net/irda/irlmp_frame.c : 45 8 10
linux/net/irda/irmod.c : 31 6 6
linux/net/irda/irttp.c : 17 2 2
linux/net/irda/wrapper.c : 244 37 49
linux/net/netrom/nr_route.c : 52 10 6
linux/net/netsyms.c : 31 4 4
linux/net/packet/af_packet.c : 17 1 3
linux/net/rose/rose_route.c : 85 16 13
linux/net/sched/cls_api.c : 31 4 4
linux/net/sched/cls_fw.c : 118 33 8
linux/net/sched/cls_route.c : 83 14 9
linux/net/sched/cls_rsvp.h : 125 23 16
linux/net/sched/cls_u32.c : 72 12 8
linux/net/sched/estimator.c : 70 12 7
linux/net/sched/police.c : 65 19 7
linux/net/sched/sch_api.c : 96 22 3
linux/net/sched/sch_cbq.c : 234 68 19
linux/net/sched/sch_csz.c : 155 41 15
linux/net/sched/sch_generic.c : 34 4 4
linux/net/sched/sch_prio.c : 450 213 71
linux/net/sched/sch_sfq.c : 44 9 4
linux/net/sched/sch_tbf.c : 17 2 2
linux/net/sched/sch_teql.c : 17 2 2
linux/net/socket.c : 79 27 11
linux/net/sunrpc/xprt.c : 8 1 1
linux/net/wanrouter/wanmain.c : 139 64 13
linux/net/x25/af_x25.c : 56 9 6
--
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,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.3/patch-2.3.6/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 27 - 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.3.6 ==============
if test -f 'patch-2.3.6' -a X"$1" != X"-c"; then
echo 'x - skipping patch-2.3.6 (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting patch-2.3.6 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'patch-2.3.6' &&
diff -u --recursive --new-file v2.3.5/linux/CREDITS linux/CREDITS
--- v2.3.5/linux/CREDITS Mon May 31 22:28:04 1999
+++ linux/CREDITS Tue Jun 8 10:27:18 1999
@@ -16,6 +16,14 @@
X S: (ask for current address)
X S: Finland
X
+N: Dragos Acostachioaie
+E: dra...@iname.com
+W: http://www.arbornet.org/~dragos
+D: /proc/sysvipc
+S: C. Negri 6, bl. D3
+S: Iasi 6600
+S: Romania
+
X N: Dave Airlie
X E: air...@linux.ie
X W: http://www.csn.ul.ie/~airlied
@@ -821,7 +829,7 @@
X S: Germany
X
X N: Michael Hipp
-E: mh...@student.uni-tuebingen.de
+E: hi...@informatik.uni-tuebingen.de
X D: drivers for the racal ni5210 & ni6510 Ethernet-boards
X S: Talstr. 1
X S: D - 72072 Tuebingen
@@ -1349,8 +1357,11 @@
X
X N: Arnaldo Carvalho de Melo
X E: ac...@conectiva.com.br
+W: http://www.conectiva.com.br/~acme
X D: wanrouter hacking
-D: cyclades 2X sync card driver (still in early devel stage)
+D: Cyclom 2X synchronous card driver
+D: i18n for minicom, net-tools, util-linux, fetchmail, etc
+S: Conectiva Informatica LTDA
X S: R. Prof. Rubens Elke Braga, 558 - Parolin
X S: 80220-320 Curitiba - Parana
X S: Brazil
@@ -1929,6 +1940,17 @@
X S: 1050 Woodduck Avenue
X S: Santa Clara, California 95051
X S: USA
+
+N: Marcelo W. Tosatti
+E: mar...@conectiva.com.br
+W: http://lie-br.conectiva.com.br/~marcelo/
+D: Miscellaneous kernel hacker
+D: Cyclom 2X driver hacker
+D: linuxconf apache & proftpd module maintainer
+S: Conectiva Informatica LTDA
+S: R. Prof. Rubens Elke Braga, 558 - Parolin
+S: 80220-320 Curitiba - Parana
+S: Brazil
X
X N: Stefan Traby
X E: ste...@quant-x.com
diff -u --recursive --new-file v2.3.5/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.3.5/linux/Documentation/Configure.help Mon May 31 22:28:04 1999
+++ linux/Documentation/Configure.help Wed Jun 9 16:59:15 1999
@@ -3958,34 +3958,49 @@
X say M here and read Documentation/modules.txt. The module will be
X called aic7xxx.o.
X
-Override driver defaults for commands per LUN
-CONFIG_OVERRIDE_CMDS
- Say Y here if you want to override the default maximum number of
- commands that a single device on the aic7xxx controller is allowed
- to have active at one time. This option only affects tagged queueing
- capable devices. The driver uses a value of 24 by default.
- If you say Y here, you can adjust the number of commands per LUN
- with the following configuration option.
+Enable or Disable Tagged Command Queueing by default
+CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
+ This option causes the aic7xxx driver to attempt to use tagged command
+ queueing on any devices that claim to support it. If this is set to yes,
+ you can still turn off TCQ on troublesome devices with the use of the
+ tag_info boot parameter. See /usr/src/linux/drivers/scsi/README.aic7xxx
+ for more information on that and other aic7xxx setup commands. If this
+ option is turned off, you may still enable TCQ on known good devices by
+ use of the tag_info boot parameter.
X
- If unsure, say N.
-
-Maximum number of commands per LUN
-CONFIG_AIC7XXX_CMDS_PER_LUN
- Specify the maximum number of commands you would like to allocate
- per LUN (a LUN is a Logical Unit Number -- some physical SCSI
- devices, e.g. CD jukeboxes, act logically as several separate units,
- each of which gets its own number).
+ If you are unsure about your devices then it is safest to say N here.
+
+ However, TCQ can increase performance on some hard drives by as much
+ as 50% or more, so I would recommend that if you say N here, that you
+ at least read the README.aic7xxx file so you will know how to enable
+ this option manually should your drives prove to be safe in regards
+ to TCQ.
+
+ Conversely, certain drives are known to lock up or cause bus resets when
+ TCQ is enabled on them. If you have a Western Digital Enterprise SCSI
+ drive for instance, then don't even bother to enable TCQ on it as the
+ drive will become unreliable, and it will actually reduce performance.
+
+Default number of TCQ commands per device
+CONFIG_AIC7XXX_CMDS_PER_DEVICE
+ Specify the number of commands you would like to allocate per SCSI
+ device when Tagged Command Queueing (TCQ) is enabled on that device.
X
- Reasonable figures are in the range of 14 to 32 commands per device,
+ Reasonable figures are in the range of 8 to 24 commands per device,
X but depending on hardware could be increased or decreased from that
X figure. If the number is too high for any particular device, the
X driver will automatically compensate usually after only 10 minutes
- of uptime and will issue a message to alert you to the fact that the
- number of commands for that device has been reduced. It will not
- hinder performance if some of your devices eventually have their
- commands per LUN reduced, but is a waste of memory if all of your
- devices end up reducing this number down to a more reasonable
- figure. Default: 24
+ of uptime. It will not hinder performance if some of your devices
+ eventually have their command depth reduced, but is a waste of memory
+ if all of your devices end up reducing this number down to a more
+ reasonable figure.
+
+ NOTE: Certain very broken drives are known to lock up when given more
+ commands than they like to deal with. Quantum Fireball drives are the
+ most common in this category. For the Quantum Fireball drives I would
+ suggest no more than 8 commands per device.
+
+ Default: 8
X
X Collect statistics to report in /proc
X CONFIG_AIC7XXX_PROC_STATS
@@ -6369,6 +6384,20 @@
X module, say M here and read Documentation/modules.txt as well as
X Documentation/networking/net-modules.txt.
X
+SKnet MCA support
+CONFIG_SKMC
+ This are Micro Channel ethernet adapters. You need to set CONFIG_MCA
+ to use this driver. It's both available as an in-kernel driver and
+ as a module ( = code which can be inserted in and removed from the
+ running kernel whenever you want). If you want to compile it as a module,
+ say M here and read Documentation/modules.txt as well as
+ Documentation/networking/net-modules.txt. If you plan to use more than
+ one network card under linux, read the Multiple-Ethernet-mini-HOWTO,
+ available from sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini. Supported
+ cards are the SKnet Junior MC2 and the SKnet MC2(+). Distinguishing
+ both cards is done automatically. Note that using multiple boards
+ of different type hasn't been tested with this driver.
+
X EISA, VLB, PCI and on board controllers
X CONFIG_NET_EISA
X This is another class of network cards which attach directly to the
@@ -8936,8 +8965,8 @@
X
X Zilog serial support
X CONFIG_SUN_ZS
- This driver does not exist at this point, so you might as well
- say N.
+ If you are asked this question, something is wrong with config scripts.
+ Zilog serial driver is always enabled in sparc architecture.
X
X Double Talk PC internal speech card support
X CONFIG_DTLK
@@ -10338,8 +10367,14 @@
X inserted in and removed from the running kernel whenever you want),
X say M and read Documentation/modules.txt. If unsure, say Y.
X
-#Mostek real time clock support
-#CONFIG_SUN_MOSTEK_RTC
+Mostek real time clock support
+CONFIG_SUN_MOSTEK_RTC
+ The Mostek RTC chip is used on all knows Sun computers except
+ some JavaStation-s. For a JavaStation you need to say Y both here
+ and to CONFIG_RTC.
+
+ Say Y here unless you are building a special purpose kernel.
+
X #
X #Siemens SAB82532 serial support
X #CONFIG_SAB82532
diff -u --recursive --new-file v2.3.5/linux/Documentation/filesystems/hpfs.txt linux/Documentation/filesystems/hpfs.txt
--- v2.3.5/linux/Documentation/filesystems/hpfs.txt Mon May 17 09:55:20 1999
+++ linux/Documentation/filesystems/hpfs.txt Fri Jun 4 01:06:29 1999
@@ -1,4 +1,4 @@
-Read/Write HPFS 1.99b
+Read/Write HPFS 2.00
X 1998-1999, Mikulas Patocka
X
X email: mik...@artax.karlin.mff.cuni.cz
@@ -267,6 +267,8 @@
X file
X Now it tries to truncate the file if there's not enough space when deleting
X Removed a lot of redundat code
+2.00 Fixed a bug in rename (it was there since 1.96)
+ Better anti-fragmentation strategy
X
X
X vim: set textwidth=80:
diff -u --recursive --new-file v2.3.5/linux/Documentation/mtrr.txt linux/Documentation/mtrr.txt
--- v2.3.5/linux/Documentation/mtrr.txt Mon May 17 09:55:20 1999
+++ linux/Documentation/mtrr.txt Thu Jun 3 08:17:28 1999
@@ -1,15 +1,25 @@
X MTRR (Memory Type Range Register) control
-16 May 1999
+3 Jun 1999
X Richard Gooch
X <rgo...@atnf.csiro.au>
X
- On Intel Pentium Pro/Pentium II systems the Memory Type Range
- Registers (MTRRs) may be used to control processor access to memory
- ranges. This is most useful when you have a video (VGA) card on a
- PCI or AGP bus. Enabling write-combining allows bus write transfers
- to be combined into a larger transfer before bursting over the
- PCI/AGP bus. This can increase performance of image write operations
- 2.5 times or more.
+ On Intel P6 family processors (Pentium Pro, Pentium II and later)
+ the Memory Type Range Registers (MTRRs) may be used to control
+ processor access to memory ranges. This is most useful when you have
+ a video (VGA) card on a PCI or AGP bus. Enabling write-combining
+ allows bus write transfers to be combined into a larger transfer
+ before bursting over the PCI/AGP bus. This can increase performance
+ of image write operations 2.5 times or more.
+
+ The Cyrix 6x86, 6x86MX and M II processors have Address Range
+ Registers (ARRs) which provide a similar functionality to MTRRs. For
+ these, the ARRs are used to emulate the MTRRs.
+
+ The AMD K6-2 (stepping 8 and above) and K6-3 processors have two
+ MTRRs. These are supported.
+
+ The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These
+ are supported.
X
X The CONFIG_MTRR option creates a /proc/mtrr file which may be used
X to manipulate your MTRRs. Typically the X server should use
diff -u --recursive --new-file v2.3.5/linux/MAINTAINERS linux/MAINTAINERS
--- v2.3.5/linux/MAINTAINERS Mon May 17 09:55:20 1999
+++ linux/MAINTAINERS Thu Jun 3 08:26:42 1999
@@ -192,6 +192,13 @@
X M: j...@acm.org
X S: Maintained
X
+CYCLADES 2X SYNC CARD DRIVER
+P: Arnaldo Carvalho de Melo
+M: ac...@conectiva.com.br
+W: http://www.conectiva.com.br/~acme
+L: cycsyn...@bazar.conectiva.com.br
+S: Maintained
+
X CYCLADES ASYNC MUX DRIVER
X P: Ivan Passos
X M: Ivan Passos <iv...@cyclades.com>
@@ -390,6 +397,11 @@
X M: Paul.R...@rustcorp.com.au
X W: http://www.rustcorp.com/linux/ipchains
X S: Supported
+
+IP MASQUERADING:
+P: Juanjo Ciarlante
+M: jjci...@raiz.uncu.edu.ar
+S: Maintained
X
X IPX/SPX NETWORK LAYER
X P: Jay Schulist
diff -u --recursive --new-file v2.3.5/linux/Makefile linux/Makefile
--- v2.3.5/linux/Makefile Wed Jun 2 14:44:39 1999
+++ linux/Makefile Wed Jun 2 14:40:19 1999
@@ -1,6 +1,6 @@
X VERSION = 2
X PATCHLEVEL = 3
-SUBLEVEL = 5
+SUBLEVEL = 6
X EXTRAVERSION =
X
X ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
diff -u --recursive --new-file v2.3.5/linux/arch/alpha/kernel/ptrace.c linux/arch/alpha/kernel/ptrace.c
--- v2.3.5/linux/arch/alpha/kernel/ptrace.c Mon May 31 22:28:04 1999
+++ linux/arch/alpha/kernel/ptrace.c Mon Jun 7 11:15:33 1999
@@ -246,26 +246,6 @@
X flush_tlb();
X }
X
-static struct vm_area_struct *
-find_extend_vma(struct task_struct * tsk, unsigned long addr)
-{
- struct vm_area_struct * vma;
-
- addr &= PAGE_MASK;
- vma = find_vma(tsk->mm,addr);
- if (!vma)
- return NULL;
- if (vma->vm_start <= addr)
- return vma;
- if (!(vma->vm_flags & VM_GROWSDOWN))
- return NULL;
- if (vma->vm_end - addr > tsk->rlim[RLIMIT_STACK].rlim_cur)
- return NULL;
- vma->vm_offset -= vma->vm_start - addr;
- vma->vm_start = addr;
- return vma;
-}
-
X /*
X * This routine checks the page boundaries, and that the offset is
X * within the task area. It then calls get_long() to read a long.
diff -u --recursive --new-file v2.3.5/linux/arch/alpha/lib/memcpy.c linux/arch/alpha/lib/memcpy.c
--- v2.3.5/linux/arch/alpha/lib/memcpy.c Tue Apr 7 08:05:05 1998
+++ linux/arch/alpha/lib/memcpy.c Mon Jun 7 11:37:13 1999
@@ -21,30 +21,44 @@
X * This should be done in one go with ldq_u*2/mask/stq_u. Do it
X * with a macro so that we can fix it up later..
X */
-#define ALIGN_DEST_TO8(d,s,n) \
+#define ALIGN_DEST_TO8_UP(d,s,n) \
X while (d & 7) { \
X if (n <= 0) return; \
X n--; \
X *(char *) d = *(char *) s; \
X d++; s++; \
X }
+#define ALIGN_DEST_TO8_DN(d,s,n) \
+ while (d & 7) { \
+ if (n <= 0) return; \
+ n--; \
+ d--; s--; \
+ *(char *) d = *(char *) s; \
+ }
X
X /*
X * This should similarly be done with ldq_u*2/mask/stq. The destination
X * is aligned, but we don't fill in a full quad-word
X */
-#define DO_REST(d,s,n) \
+#define DO_REST_UP(d,s,n) \
X while (n > 0) { \
X n--; \
X *(char *) d = *(char *) s; \
X d++; s++; \
X }
+#define DO_REST_DN(d,s,n) \
+ while (n > 0) { \
+ n--; \
+ d--; s--; \
+ *(char *) d = *(char *) s; \
+ }
X
X /*
X * This should be done with ldq/mask/stq. The source and destination are
X * aligned, but we don't fill in a full quad-word
X */
-#define DO_REST_ALIGNED(d,s,n) DO_REST(d,s,n)
+#define DO_REST_ALIGNED_UP(d,s,n) DO_REST_UP(d,s,n)
+#define DO_REST_ALIGNED_DN(d,s,n) DO_REST_DN(d,s,n)
X
X /*
X * This does unaligned memory copies. We want to avoid storing to
@@ -53,9 +67,10 @@
X *
X * Note the ordering to try to avoid load (and address generation) latencies.
X */
-static inline void __memcpy_unaligned(unsigned long d, unsigned long s, long n)
+static inline void __memcpy_unaligned_up (unsigned long d, unsigned long s,
+ long n)
X {
- ALIGN_DEST_TO8(d,s,n);
+ ALIGN_DEST_TO8_UP(d,s,n);
X n -= 8; /* to avoid compare against 8 in the loop */
X if (n >= 0) {
X unsigned long low_word, high_word;
@@ -77,7 +92,17 @@
X } while (n >= 0);
X }
X n += 8;
- DO_REST(d,s,n);
+ DO_REST_UP(d,s,n);
+}
+
+static inline void __memcpy_unaligned_dn (unsigned long d, unsigned long s,
+ long n)
+{
+ /* I don't understand AXP assembler well enough for this. -Tim */
+ s += n;
+ d += n;
+ while (n--)
+ * (char *) --d = * (char *) --s;
X }
X
X /*
@@ -88,9 +113,10 @@
X *
X * Note the ordering to try to avoid load (and address generation) latencies.
X */
-static inline void __memcpy_aligned(unsigned long d, unsigned long s, long n)
+static inline void __memcpy_aligned_up (unsigned long d, unsigned long s,
+ long n)
X {
- ALIGN_DEST_TO8(d,s,n);
+ ALIGN_DEST_TO8_UP(d,s,n);
X n -= 8;
X while (n >= 0) {
X unsigned long tmp;
@@ -101,18 +127,58 @@
X d += 8;
X }
X n += 8;
- DO_REST_ALIGNED(d,s,n);
+ DO_REST_ALIGNED_UP(d,s,n);
+}
+static inline void __memcpy_aligned_dn (unsigned long d, unsigned long s,
+ long n)
+{
+ s += n;
+ d += n;
+ ALIGN_DEST_TO8_DN(d,s,n);
+ n -= 8;
+ while (n >= 0) {
+ unsigned long tmp;
+ s -= 8;
+ __asm__("ldq %0,%1":"=r" (tmp):"m" (*(unsigned long *) s));
+ n -= 8;
+ d -= 8;
+ *(unsigned long *) d = tmp;
+ }
+ n += 8;
+ DO_REST_ALIGNED_DN(d,s,n);
X }
X
X void * memcpy(void * dest, const void *src, size_t n)
X {
X if (!(((unsigned long) dest ^ (unsigned long) src) & 7)) {
- __memcpy_aligned((unsigned long) dest, (unsigned long) src, n);
+ __memcpy_aligned_up ((unsigned long) dest, (unsigned long) src,
+ n);
X return dest;
X }
- __memcpy_unaligned((unsigned long) dest, (unsigned long) src, n);
+ __memcpy_unaligned_up ((unsigned long) dest, (unsigned long) src, n);
X return dest;
X }
X
X /* For backward modules compatibility, define __memcpy. */
X asm("__memcpy = memcpy; .globl __memcpy");
+
+void *memmove (void *dest, const void *src, size_t n)
+{
+ if (dest <= src) {
+ if (!(((unsigned long) dest ^ (unsigned long) src) & 7))
+ __memcpy_aligned_up ((unsigned long) dest,
+ (unsigned long) src, n);
+ else
+ __memcpy_unaligned_up ((unsigned long) dest,
+ (unsigned long) src, n);
+ }
+ else {
+ if (!(((unsigned long) dest ^ (unsigned long) src) & 7))
+ __memcpy_aligned_dn ((unsigned long) dest,
+ (unsigned long) src, n);
+ else
+ __memcpy_unaligned_dn ((unsigned long) dest,
+ (unsigned long) src, n);
+ }
+ return dest;
+}
diff -u --recursive --new-file v2.3.5/linux/arch/arm/kernel/ptrace.c linux/arch/arm/kernel/ptrace.c
--- v2.3.5/linux/arch/arm/kernel/ptrace.c Mon May 31 22:28:04 1999
+++ linux/arch/arm/kernel/ptrace.c Mon Jun 7 11:15:33 1999
@@ -164,25 +164,6 @@
X flush_tlb();
X }
X
-static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigned long addr)
-{
- struct vm_area_struct * vma;
-
- addr &= PAGE_MASK;
- vma = find_vma(tsk->mm,addr);
- if (!vma)
- return NULL;
- if (vma->vm_start <= addr)
- return vma;
- if (!(vma->vm_flags & VM_GROWSDOWN))
- return NULL;
- if (vma->vm_end - addr > tsk->rlim[RLIMIT_STACK].rlim_cur)
- return NULL;
- vma->vm_offset -= vma->vm_start - addr;
- vma->vm_start = addr;
- return vma;
-}
-
X /*
X * This routine checks the page boundaries, and that the offset is
X * within the task area. It then calls get_long() to read a long.
diff -u --recursive --new-file v2.3.5/linux/arch/i386/Makefile linux/arch/i386/Makefile
--- v2.3.5/linux/arch/i386/Makefile Mon May 17 09:55:20 1999
+++ linux/arch/i386/Makefile Mon Jun 7 17:02:23 1999
@@ -67,6 +67,13 @@
X
X MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
X
+vmlinux: arch/i386/vmlinux.lds
+
+arch/i386/vmlinux.lds: arch/i386/vmlinux.lds.S FORCE
+ gcc -E -C -P -I$(HPATH) -imacros $(HPATH)/asm-i386/page_offset.h -Ui386 arch/i386/vmlinux.lds.S >arch/i386/vmlinux.lds
+
+FORCE: ;
+
X zImage: vmlinux
X @$(MAKEBOOT) zImage
X
diff -u --recursive --new-file v2.3.5/linux/arch/i386/boot/bootsect.S linux/arch/i386/boot/bootsect.S
--- v2.3.5/linux/arch/i386/boot/bootsect.S Wed Jun 24 14:30:08 1998
+++ linux/arch/i386/boot/bootsect.S Tue Jun 8 10:47:57 1999
@@ -58,12 +58,12 @@
X mov ds,ax
X mov ax,#INITSEG
X mov es,ax
- mov cx,#256
+ mov cx,#128
X sub si,si
X sub di,di
X cld
X rep
- movsw
+ movsd
X jmpi go,INITSEG
X
X ! ax and es already contain INITSEG
diff -u --recursive --new-file v2.3.5/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.3.5/linux/arch/i386/config.in Fri May 14 18:55:11 1999
+++ linux/arch/i386/config.in Mon Jun 7 17:02:23 1999
@@ -33,6 +33,10 @@
X define_bool CONFIG_X86_GOOD_APIC y
X fi
X
+choice 'Maximum Physical Memory' \
+ "1GB CONFIG_1GB \
+ 2GB CONFIG_2GB" 1GB
+
X bool 'Math emulation' CONFIG_MATH_EMULATION
X bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
X bool 'Symmetric multi-processing support' CONFIG_SMP
@@ -113,6 +117,8 @@
X fi
X
X endmenu
+
+source drivers/i2o/Config.in
X
X source drivers/pnp/Config.in
X
diff -u --recursive --new-file v2.3.5/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.3.5/linux/arch/i386/defconfig Wed Jun 2 14:44:39 1999
+++ linux/arch/i386/defconfig Mon Jun 7 22:12:01 1999
@@ -21,6 +21,8 @@
X CONFIG_X86_POPAD_OK=y
X CONFIG_X86_TSC=y
X CONFIG_X86_GOOD_APIC=y
+CONFIG_1GB=y
+# CONFIG_2GB is not set
X # CONFIG_MATH_EMULATION is not set
X # CONFIG_MTRR is not set
X CONFIG_SMP=y
@@ -58,6 +60,16 @@
X # CONFIG_APM is not set
X
X #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
X # Plug and Play support
X #
X # CONFIG_PNP is not set
@@ -243,6 +255,11 @@
X # CONFIG_HAMRADIO is not set
X
X #
+# IrDA subsystem support
+#
+# CONFIG_IRDA is not set
+
+#
X # ISDN subsystem
X #
X # CONFIG_ISDN is not set
@@ -308,6 +325,7 @@
X # CONFIG_USB_AUDIO is not set
X # CONFIG_USB_ACM is not set
X # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_SCSI is not set
X
X #
X # Filesystems
diff -u --recursive --new-file v2.3.5/linux/arch/i386/kernel/mca.c linux/arch/i386/kernel/mca.c
--- v2.3.5/linux/arch/i386/kernel/mca.c Mon May 10 13:00:10 1999
+++ linux/arch/i386/kernel/mca.c Mon Jun 7 16:17:59 1999
@@ -112,21 +112,25 @@
X static ssize_t proc_mca_read(struct file*, char*, size_t, loff_t *);
X
X static struct file_operations proc_mca_operations = {
- NULL, /* array_lseek */
- proc_mca_read, /* array_read */
- NULL, /* array_write */
- NULL, /* array_readdir */
- NULL, /* array_poll */
- NULL, /* array_ioctl */
+ NULL, /* llseek */
+ proc_mca_read, /* read */
+ NULL, /* write */
+ NULL, /* readdir */
+ NULL, /* poll */
+ NULL, /* ioctl */
X NULL, /* mmap */
- NULL, /* no special open code */
+ NULL, /* open */
X NULL, /* flush */
- NULL, /* no special release code */
- NULL /* can't fsync */
+ NULL, /* release */
+ NULL, /* fsync */
+ NULL, /* fascync */
+ NULL, /* check_media_change */
+ NULL, /* revalidate */
+ NULL /* lock */
X };
X
X static struct inode_operations proc_mca_inode_operations = {
- &proc_mca_operations, /* default base directory file-ops */
+ &proc_mca_operations, /* default file-ops */
X NULL, /* create */
X NULL, /* lookup */
X NULL, /* link */
@@ -142,7 +146,10 @@
X NULL, /* writepage */
X NULL, /* bmap */
X NULL, /* truncate */
- NULL /* permission */
+ NULL, /* permission */
+ NULL, /* smap */
+ NULL, /* updatepage */
+ NULL /* revalidate */
X };
X #endif
X
@@ -220,18 +227,19 @@
X if(!MCA_bus)
X return;
X printk("Micro Channel bus detected.\n");
- save_flags(flags);
- cli();
X
X /* Allocate MCA_info structure (at address divisible by 8) */
X
- mca_info = kmalloc(sizeof(struct MCA_info), GFP_KERNEL);
+ mca_info = (struct MCA_info *)kmalloc(sizeof(struct MCA_info), GFP_KERNEL);
X
X if(mca_info == NULL) {
X printk("Failed to allocate memory for mca_info!");
- restore_flags(flags);
X return;
X }
+ memset(mca_info, 0, sizeof(struct MCA_info));
+
+ save_flags(flags);
+ cli();
X
X /* Make sure adapter setup is off */
X
@@ -705,12 +713,15 @@
X mca_info->slot[i].dev = 0;
X
X if(!mca_isadapter(i)) continue;
- node = kmalloc(sizeof(struct proc_dir_entry), GFP_KERNEL);
+
+ node = (struct proc_dir_entry *)kmalloc(sizeof(struct proc_dir_entry), GFP_KERNEL);
X
X if(node == NULL) {
X printk("Failed to allocate memory for MCA proc-entries!");
X return;
X }
+ memset(node, 0, sizeof(struct proc_dir_entry));
+
X if(i < MCA_MAX_SLOT_NR) {
X node->low_ino = PROC_MCA_SLOT + i;
X node->namelen = sprintf(mca_info->slot[i].procname,
@@ -854,7 +865,7 @@
X type = inode->i_ino;
X pid = type >> 16;
X type &= 0x0000ffff;
- start = 0;
+ start = NULL;
X dp = (struct proc_dir_entry *) inode->u.generic_ip;
X length = mca_fill((char *) page, pid, type,
X &start, ppos, count);
@@ -862,7 +873,7 @@
X free_page(page);
X return length;
X }
- if(start != 0) {
+ if(start != NULL) {
X /* We have had block-adjusting processing! */
X
X copy_to_user(buf, start, length);
diff -u --recursive --new-file v2.3.5/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c
--- v2.3.5/linux/arch/i386/kernel/ptrace.c Wed Mar 24 13:18:46 1999
+++ linux/arch/i386/kernel/ptrace.c Mon Jun 7 11:15:33 1999
@@ -172,25 +172,6 @@
X flush_tlb();
X }
X
-static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigned long addr)
-{
- struct vm_area_struct * vma;
-
- addr &= PAGE_MASK;
- vma = find_vma(tsk->mm,addr);
- if (!vma)
- return NULL;
- if (vma->vm_start <= addr)
- return vma;
- if (!(vma->vm_flags & VM_GROWSDOWN))
- return NULL;
- if (vma->vm_end - addr > tsk->rlim[RLIMIT_STACK].rlim_cur)
- return NULL;
- vma->vm_offset -= vma->vm_start - addr;
- vma->vm_start = addr;
- return vma;
-}
-
X /*
X * This routine checks the page boundaries, and that the offset is
X * within the task area. It then calls get_long() to read a long.
diff -u --recursive --new-file v2.3.5/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.3.5/linux/arch/i386/kernel/setup.c Sat May 15 23:46:03 1999
+++ linux/arch/i386/kernel/setup.c Tue Jun 8 10:42:46 1999
@@ -12,6 +12,8 @@
X *
X * Force Centaur C6 processors to report MTRR capability.
X * Bart Hartgers <ba...@etpmod.phys.tue.nl>, May 199.
+ *
+ * Intel Mobile Pentium II detection fix. Sean Gilley, June 1999.
X */
X
X /*
@@ -688,7 +690,7 @@
X NULL, NULL, NULL, NULL }},
X { X86_VENDOR_INTEL, 6,
X { "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II (Klamath)",
- NULL, "Pentium II (Deschutes)", "Celeron (Mendocino)", NULL,
+ NULL, "Pentium II (Deschutes)", "Mobile Pentium II", NULL,
X NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }},
X { X86_VENDOR_AMD, 4,
X { NULL, NULL, NULL, "486 DX/2", NULL, NULL, NULL, "486 DX/2-WB",
@@ -794,13 +796,19 @@
X if (c->x86_model <= 16)
X p = cpu_models[i].model_names[c->x86_model];
X
- /* Names for the Pentium II processors */
+ /* Names for the Pentium II Celeron processors
+ detectable only by also checking the cache size */
X if ((cpu_models[i].vendor == X86_VENDOR_INTEL)
- && (cpu_models[i].x86 == 6)
- && (c->x86_model == 5)
- && (c->x86_cache_size == 0)) {
- p = "Celeron (Covington)";
- }
+ && (cpu_models[i].x86 == 6)){
+ if(c->x86_model == 6 && c->x86_cache_size == 128) {
+ p = "Celeron (Mendocino)";
+ }
+ else {
+ if (c->x86_model == 5 && c->x86_cache_size == 0) {
+ p = "Celeron (Covington)";
+ }
+ }
+ }
X }
X
X }
diff -u --recursive --new-file v2.3.5/linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c
--- v2.3.5/linux/arch/i386/kernel/signal.c Tue Dec 1 11:28:24 1998
+++ linux/arch/i386/kernel/signal.c Mon Jun 7 16:14:06 1999
@@ -698,6 +698,7 @@
X default:
X lock_kernel();
X sigaddset(&current->signal, signr);
+ recalc_sigpending(current);
X current->flags |= PF_SIGNALED;
X do_exit(exit_code);
X /* NOTREACHED */
diff -u --recursive --new-file v2.3.5/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c
--- v2.3.5/linux/arch/i386/mm/init.c Thu Jan 21 11:28:40 1999
+++ linux/arch/i386/mm/init.c Tue Jun 8 10:49:48 1999
@@ -390,6 +390,7 @@
X int datapages = 0;
X int initpages = 0;
X unsigned long tmp;
+ unsigned long endbase;
X
X end_mem &= PAGE_MASK;
X high_memory = (void *) end_mem;
@@ -417,8 +418,10 @@
X * IBM messed up *AGAIN* in their thinkpad: 0xA0000 -> 0x9F000.
X * They seem to have done something stupid with the floppy
X * controller as well..
+ * The amount of available base memory is in WORD 40:13.
X */
- while (start_low_mem < 0x9f000+PAGE_OFFSET) {
+ endbase = PAGE_OFFSET + ((*(unsigned short *)__va(0x413) * 1024) & PAGE_MASK);
+ while (start_low_mem < endbase) {
X clear_bit(PG_reserved, &mem_map[MAP_NR(start_low_mem)].flags);
X start_low_mem += PAGE_SIZE;
X }
diff -u --recursive --new-file v2.3.5/linux/arch/i386/mm/ioremap.c linux/arch/i386/mm/ioremap.c
--- v2.3.5/linux/arch/i386/mm/ioremap.c Fri Nov 27 15:03:14 1998
+++ linux/arch/i386/mm/ioremap.c Thu Jun 3 14:17:51 1999
@@ -93,12 +93,17 @@
X {
X void * addr;
X struct vm_struct * area;
- unsigned long offset;
+ unsigned long offset, last_addr;
+
+ /* Don't allow wraparound or zero size */
+ last_addr = phys_addr + size - 1;
+ if (!size || last_addr < phys_addr)
+ return NULL;
X
X /*
X * Don't remap the low PCI/ISA area, it's always mapped..
X */
- if (phys_addr >= 0xA0000 && (phys_addr+size) <= 0x100000)
+ if (phys_addr >= 0xA0000 && last_addr < 0x100000)
X return phys_to_virt(phys_addr);
X
X /*
@@ -112,13 +117,7 @@
X */
X offset = phys_addr & ~PAGE_MASK;
X phys_addr &= PAGE_MASK;
- size = PAGE_ALIGN(size + offset);
-
- /*
- * Don't allow mappings that wrap..
- */
- if (!size || size > phys_addr + size)
- return NULL;
+ size = PAGE_ALIGN(last_addr) - phys_addr;
X
X /*
X * Ok, go for it..
diff -u --recursive --new-file v2.3.5/linux/arch/i386/vmlinux.lds linux/arch/i386/vmlinux.lds
--- v2.3.5/linux/arch/i386/vmlinux.lds Sun Dec 27 22:45:13 1998
+++ linux/arch/i386/vmlinux.lds Tue Jun 8 23:03:37 1999
@@ -1,12 +1,12 @@
X /* ld script to make i386 Linux kernel
- * Written by Martin Mares <m...@atrey.karlin.mff.cuni.cz>
+ * Written by Martin Mares <m...@atrey.karlin.mff.cuni.cz>;
X */
X OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
X OUTPUT_ARCH(i386)
X ENTRY(_start)
X SECTIONS
X {
- . = 0xC0000000 + 0x100000;
+ . = 0xC0000000 + 0x100000;
X _text = .; /* Text and read-only data */
X .text : {
X *(.text)
diff -u --recursive --new-file v2.3.5/linux/arch/i386/vmlinux.lds.S linux/arch/i386/vmlinux.lds.S
--- v2.3.5/linux/arch/i386/vmlinux.lds.S Wed Dec 31 16:00:00 1969
+++ linux/arch/i386/vmlinux.lds.S Mon Jun 7 17:02:23 1999
@@ -0,0 +1,69 @@
+/* ld script to make i386 Linux kernel
+ * Written by Martin Mares <m...@atrey.karlin.mff.cuni.cz>;
+ */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+ . = PAGE_OFFSET_RAW + 0x100000;
+ _text = .; /* Text and read-only data */
+ .text : {
+ *(.text)
+ *(.fixup)
+ *(.gnu.warning)
+ } = 0x9090
+ .text.lock : { *(.text.lock) } /* out-of-line lock text */
+ .rodata : { *(.rodata) }
+ .kstrtab : { *(.kstrtab) }
+
+ . = ALIGN(16); /* Exception table */
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ __start___ksymtab = .; /* Kernel symbol table */
+ __ksymtab : { *(__ksymtab) }
+ __stop___ksymtab = .;
+
+ _etext = .; /* End of text section */
+
+ .data : { /* Data */
+ *(.data)
+ CONSTRUCTORS
+ }
+
+ _edata = .; /* End of data section */
+
+ . = ALIGN(8192); /* init_task */
+ .data.init_task : { *(.data.init_task) }
+
+ . = ALIGN(4096); /* Init code and data */
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(4096);
+ __init_end = .;
+
+ . = ALIGN(32);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+ . = ALIGN(4096);
+ .data.page_aligned : { *(.data.idt) }
+
+
+ __bss_start = .; /* BSS */
+ .bss : {
+ *(.bss)
+ }
+ _end = . ;
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+}
diff -u --recursive --new-file v2.3.5/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c
--- v2.3.5/linux/arch/m68k/kernel/ptrace.c Tue May 11 09:57:14 1999
+++ linux/arch/m68k/kernel/ptrace.c Mon Jun 7 11:15:33 1999
@@ -196,25 +196,6 @@
X flush_tlb_all();
X }
X
-static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigned long addr)
-{
- struct vm_area_struct * vma;
-
- addr &= PAGE_MASK;
- vma = find_vma(tsk->mm, addr);
- if (!vma)
- return NULL;
- if (vma->vm_start <= addr)
- return vma;
- if (!(vma->vm_flags & VM_GROWSDOWN))
- return NULL;
- if (vma->vm_end - addr > tsk->rlim[RLIMIT_STACK].rlim_cur)
- return NULL;
- vma->vm_offset -= vma->vm_start - addr;
- vma->vm_start = addr;
- return vma;
-}
-
X /*
X * This routine checks the page boundaries, and that the offset is
X * within the task area. It then calls get_long() to read a long.
diff -u --recursive --new-file v2.3.5/linux/arch/mips/kernel/irixelf.c linux/arch/mips/kernel/irixelf.c
--- v2.3.5/linux/arch/mips/kernel/irixelf.c Wed Nov 11 11:49:59 1998
+++ linux/arch/mips/kernel/irixelf.c Thu Jun 3 23:15:29 1999
@@ -132,9 +132,7 @@
X end = PAGE_ALIGN(end);
X if (end <= start)
X return;
- do_mmap(NULL, start, end - start,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE, 0);
+ do_brk(start, end - start);
X }
X
X
@@ -394,9 +392,7 @@
X
X /* Map the last of the bss segment */
X if (last_bss > len) {
- do_mmap(NULL, len, (last_bss - len),
- PROT_READ|PROT_WRITE|PROT_EXEC,
- MAP_FIXED|MAP_PRIVATE, 0);
+ do_brk(len, (last_bss - len));
X }
X kfree(elf_phdata);
X
@@ -589,8 +585,7 @@
X unsigned long v;
X struct prda *pp;
X
- v = do_mmap (NULL, PRDA_ADDRESS, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE, 0);
+ v = do_brk (PRDA_ADDRESS, PAGE_SIZE);
X
X if (v < 0)
X return;
@@ -931,9 +926,7 @@
X len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
X bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
X if (bss > len)
- do_mmap(NULL, len, bss-len,
- PROT_READ|PROT_WRITE|PROT_EXEC,
- MAP_FIXED|MAP_PRIVATE, 0);
+ do_brk(len, bss-len);
X kfree(elf_phdata);
X return 0;
X }
diff -u --recursive --new-file v2.3.5/linux/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c
--- v2.3.5/linux/arch/mips/kernel/ptrace.c Mon May 31 22:28:04 1999
+++ linux/arch/mips/kernel/ptrace.c Mon Jun 7 11:15:33 1999
@@ -143,25 +143,6 @@
X flush_tlb_page(vma, addr);
X }
X
-static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigned long addr)
-{
- struct vm_area_struct * vma;
-
- addr &= PAGE_MASK;
- vma = find_vma(tsk->mm, addr);
- if (!vma)
- return NULL;
- if (vma->vm_start <= addr)
- return vma;
- if (!(vma->vm_flags & VM_GROWSDOWN))
- return NULL;
- if (vma->vm_end - addr > tsk->rlim[RLIMIT_STACK].rlim_cur)
- return NULL;
- vma->vm_offset -= vma->vm_start - addr;
- vma->vm_start = addr;
- return vma;
-}
-
X /*
X * This routine checks the page boundaries, and that the offset is
X * within the task area. It then calls get_long() to read a long.
diff -u --recursive --new-file v2.3.5/linux/arch/mips/kernel/sysirix.c linux/arch/mips/kernel/sysirix.c
--- v2.3.5/linux/arch/mips/kernel/sysirix.c Sat May 8 11:14:01 1999
+++ linux/arch/mips/kernel/sysirix.c Thu Jun 3 23:15:29 1999
@@ -571,7 +571,7 @@
X * Check against existing mmap mappings.
X */
X if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) {
- return -ENOMEM;
+ ret = -ENOMEM;
X goto out;
X }
X
@@ -579,7 +579,7 @@
X * Check if we have enough memory..
X */
X if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) {
- return -ENOMEM;
+ ret = -ENOMEM;
X goto out;
X }
X
@@ -587,10 +587,7 @@
X * Ok, looks good - let it rip.
X */
X mm->brk = brk;
- do_mmap(NULL, oldbrk, newbrk-oldbrk,
- PROT_READ|PROT_WRITE|PROT_EXEC,
- MAP_FIXED|MAP_PRIVATE, 0);
-
+ do_brk(oldbrk, newbrk-oldbrk);
X ret = 0;
X
X out:
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/chrpboot/Makefile linux/arch/ppc/chrpboot/Makefile
--- v2.3.5/linux/arch/ppc/chrpboot/Makefile Mon May 31 22:28:04 1999
+++ linux/arch/ppc/chrpboot/Makefile Mon Jun 7 12:11:51 1999
@@ -17,7 +17,7 @@
X $(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $<
X
X CFLAGS = -O -fno-builtin -DSTDC_HEADERS -I$(TOPDIR)/include
-LD_ARGS = -T ../vmlinux.lds -Ttext 0x00800000
+LD_ARGS = -Ttext 0x00400000
X OBJCOPY = $(CROSS_COMPILE)objcopy
X
X OBJS = crt0.o start.o main.o misc.o ../coffboot/string.o ../coffboot/zlib.o image.o # initrd.o
@@ -65,9 +65,10 @@
X initrd.o: ramdisk.image.gz piggyback
X ./piggyback initrd < ramdisk.image.gz | $(AS) -o initrd.o
X
-zImage: $(OBJS) no_initrd.o
+zImage: $(OBJS) no_initrd.o mknote
X $(LD) $(LD_ARGS) -o $@ $(OBJS) no_initrd.o $(LIBS)
- objcopy zImage zImage
+ ./mknote > note
+ $(OBJCOPY) $@ $@ --add-section=.note=note -R .comment
X
X zImage.initrd: $(OBJS) initrd.o
X $(LD) $(LD_ARGS) -o $@ $(OBJS) initrd.o $(LIBS)
@@ -92,8 +93,7 @@
X
X
X clean:
- rm -f piggyback
- rm -f $(OBJS) zImage
+ rm -f piggyback note mknote $(OBJS) zImage
X
X fastdep:
X $(TOPDIR)/scripts/mkdep *.[Sch] > .depend
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/chrpboot/main.c linux/arch/ppc/chrpboot/main.c
--- v2.3.5/linux/arch/ppc/chrpboot/main.c Wed Sep 30 10:14:16 1998
+++ linux/arch/ppc/chrpboot/main.c Mon Jun 7 12:11:51 1999
@@ -17,9 +17,9 @@
X #define get_32be(x) (*(unsigned *)(x))
X
X #define RAM_START 0x00000000
-#define RAM_END 0x00800000 /* only 8M mapped with BATs */
+#define RAM_END (8<<20)
X
-#define RAM_FREE 0x00540000 /* after image of chrpboot */
+#define RAM_FREE (6<<20) /* after image of chrpboot */
X #define PROG_START 0x00010000
X
X char *avail_ram;
@@ -38,16 +38,16 @@
X void *dst;
X unsigned char *im;
X unsigned initrd_start, initrd_size;
+ extern char _start;
X
- printf("chrpboot starting\n\r");
- /* setup_bats(); */
+ printf("chrpboot starting: loaded at 0x%x\n\r", &_start);
X
X if (initrd_len) {
X initrd_size = initrd_len;
X initrd_start = (RAM_END - initrd_size) & ~0xFFF;
X a1 = initrd_start;
X a2 = initrd_size;
- printf("initial ramdisk at %x (%u bytes)\n\r", initrd_start,
+ printf("initial ramdisk at 0x%x (%u bytes)\n\r", initrd_start,
X initrd_size);
X memcpy((char *)initrd_start, initrd_data, initrd_size);
X end_avail = (char *)initrd_start;
@@ -58,25 +58,19 @@
X dst = (void *) PROG_START;
X
X if (im[0] == 0x1f && im[1] == 0x8b) {
- void *cp = (void *) RAM_FREE;
- avail_ram = (void *) (RAM_FREE + ((len + 7) & -8));
- memcpy(cp, im, len);
- printf("gunzipping... ");
- gunzip(dst, 0x400000, cp, &len);
- printf("done\n\r");
-
+ avail_ram = (char *)RAM_FREE;
+ printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+ gunzip(dst, 0x400000, im, &len);
+ printf("done %u bytes\n\r", len);
X } else {
X memmove(dst, im, len);
X }
X
X flush_cache(dst, len);
-
- sa = PROG_START+12;
+
+ sa = *(unsigned long *)PROG_START+PROG_START;
X printf("start address = 0x%x\n\r", sa);
X
-#if 0
- pause();
-#endif
X (*(void (*)())sa)(a1, a2, prom, 0, 0);
X
X printf("returned?\n\r");
@@ -150,7 +144,7 @@
X s.avail_out = dstlen;
X r = inflate(&s, Z_FINISH);
X if (r != Z_OK && r != Z_STREAM_END) {
- printf("inflate returned %d\n\r", r);
+ printf("inflate returned %d msg: %s\n\r", r, s.msg);
X exit();
X }
X *lenp = s.next_out - (unsigned char *) dst;
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/chrpboot/mknote.c linux/arch/ppc/chrpboot/mknote.c
--- v2.3.5/linux/arch/ppc/chrpboot/mknote.c Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/chrpboot/mknote.c Mon Jun 7 12:11:51 1999
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) Cort Dougan 1999.
+ *
+ * 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.
+ *
+ * Generate a note section as per the CHRP specification.
+ *
+ */
+
+#include <stdio.h>
+
+#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
+
+int main(void)
+{
+/* header */
+ /* namesz */
+ PL(strlen("PowerPC")+1);
+ /* descrsz */
+ PL(6*4);
+ /* type */
+ PL(0x1275);
+ /* name */
+ printf("PowerPC"); printf("%c", 0);
+
+/* descriptor */
+ /* real-mode */
+ PL(0xffffffff);
+ /* real-base */
+ PL(0x00c00000);
+ /* real-size */
+ PL(0xffffffff);
+ /* virt-base */
+ PL(0xffffffff);
+ /* virt-size */
+ PL(0xffffffff);
+ /* load-base */
+ PL(0x4000);
+ return 0;
+}
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/coffboot/zlib.c linux/arch/ppc/coffboot/zlib.c
--- v2.3.5/linux/arch/ppc/coffboot/zlib.c Wed Sep 30 10:14:16 1998
+++ linux/arch/ppc/coffboot/zlib.c Mon Jun 7 12:11:51 1999
@@ -11,7 +11,7 @@
X * - added Z_PACKET_FLUSH (see zlib.h for details)
X * - added inflateIncomp
X *
- * $Id: zlib.c,v 1.2 1998/09/03 17:40:53 cort Exp $
+ * $Id: zlib.c,v 1.3 1999/05/27 22:22:54 cort Exp $
X */
X
X /*+++++*/
@@ -649,6 +649,11 @@
X /* load local pointers */
X #define LOAD {LOADIN LOADOUT}
X
+/*
+ * The IBM 150 firmware munges the data right after _etext[]. This
+ * protects it. -- Cort
+ */
+local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0};
X /* And'ing with mask[n] masks the lower n bits */
X local uInt inflate_mask[] = {
X 0x0000,
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/common_defconfig linux/arch/ppc/common_defconfig
--- v2.3.5/linux/arch/ppc/common_defconfig Mon May 31 22:28:04 1999
+++ linux/arch/ppc/common_defconfig Mon Jun 7 12:11:51 1999
@@ -9,14 +9,13 @@
X CONFIG_6xx=y
X # CONFIG_PPC64 is not set
X # CONFIG_8xx is not set
-CONFIG_PMAC=y
+# CONFIG_PMAC is not set
X # CONFIG_PREP is not set
X # CONFIG_CHRP is not set
-# CONFIG_ALL_PPC is not set
+CONFIG_ALL_PPC=y
X # CONFIG_APUS is not set
X # CONFIG_MBX is not set
X # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
X CONFIG_6xx=y
X
X #
@@ -51,6 +50,7 @@
X # CONFIG_TOTALMP is not set
X CONFIG_BOOTX_TEXT=y
X # CONFIG_MOTOROLA_HOTSWAP is not set
+# CONFIG_CMDLINE_BOOL is not set
X
X #
X # Plug and Play support
@@ -60,7 +60,7 @@
X #
X # Block devices
X #
-# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV_FD=y
X CONFIG_BLK_DEV_IDE=y
X
X #
@@ -77,7 +77,7 @@
X # CONFIG_BLK_DEV_CMD640 is not set
X # CONFIG_BLK_DEV_RZ1000 is not set
X # CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_SL82C105=y
X CONFIG_BLK_DEV_IDE_PMAC=y
X CONFIG_BLK_DEV_IDEDMA_PMAC=y
X CONFIG_BLK_DEV_IDEDMA=y
@@ -117,7 +117,7 @@
X # CONFIG_NET_IPGRE is not set
X # CONFIG_IP_MROUTE is not set
X CONFIG_IP_ALIAS=y
-# CONFIG_SYN_COOKIES is not set
+CONFIG_SYN_COOKIES=y
X
X #
X # (it is safe to leave these untouched)
@@ -199,7 +199,14 @@
X # CONFIG_SCSI_SYM53C416 is not set
X # CONFIG_SCSI_NCR53C7xx is not set
X # CONFIG_SCSI_NCR53C8XX is not set
-# CONFIG_SCSI_SYM53C8XX is not set
+CONFIG_SCSI_SYM53C8XX=y
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=20
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
X # CONFIG_SCSI_PAS16 is not set
X # CONFIG_SCSI_PCI2000 is not set
X # CONFIG_SCSI_PCI2220I is not set
@@ -237,7 +244,7 @@
X # CONFIG_ACENIC is not set
X # CONFIG_NET_ISA is not set
X CONFIG_NET_EISA=y
-# CONFIG_PCNET32 is not set
+CONFIG_PCNET32=y
X # CONFIG_AC3200 is not set
X # CONFIG_APRICOT is not set
X # CONFIG_CS89x0 is not set
@@ -297,12 +304,16 @@
X CONFIG_FB_CONTROL=y
X CONFIG_FB_PLATINUM=y
X CONFIG_FB_VALKYRIE=y
-CONFIG_FB_ATY=y
+# CONFIG_FB_ATY is not set
X CONFIG_FB_IMSTT=y
X CONFIG_FB_CT65550=y
X # CONFIG_FB_S3TRIO is not set
-# CONFIG_FB_MATROX is not set
-CONFIG_FB_ATY=y
+CONFIG_FB_MATROX=y
+# CONFIG_FB_MATROX_MILLENIUM is not set
+CONFIG_FB_MATROX_MYSTIQUE=y
+# CONFIG_FB_MATROX_G100 is not set
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+# CONFIG_FB_ATY is not set
X # CONFIG_FB_VIRTUAL is not set
X # CONFIG_FBCON_ADVANCED is not set
X CONFIG_FBCON_CFB8=y
@@ -324,12 +335,22 @@
X #
X CONFIG_VT=y
X CONFIG_VT_CONSOLE=y
-# CONFIG_SERIAL is not set
+CONFIG_SERIAL=m
X # CONFIG_SERIAL_EXTENDED is not set
X # CONFIG_SERIAL_NONSTANDARD is not set
X CONFIG_UNIX98_PTYS=y
X CONFIG_UNIX98_PTY_COUNT=256
-# CONFIG_MOUSE is not set
+CONFIG_MOUSE=y
+
+#
+# Mice
+#
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
X # CONFIG_QIC02_TAPE is not set
X # CONFIG_WATCHDOG is not set
X CONFIG_NVRAM=y
@@ -448,7 +469,34 @@
X # CONFIG_SOUND_SONICVIBES is not set
X # CONFIG_SOUND_MSNDCLAS is not set
X # CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_OSS is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+CONFIG_SOUND_CS4232=m
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_UART6850 is not set
+
+#
+# Additional low level sound drivers
+#
+# CONFIG_LOWLEVEL_SOUND is not set
X
X #
X # Kernel hacking
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v2.3.5/linux/arch/ppc/config.in Mon May 31 22:28:04 1999
+++ linux/arch/ppc/config.in Tue Jun 8 10:52:26 1999
@@ -176,6 +176,7 @@
X endmenu
X
X source drivers/char/Config.in
+source drivers/usb/Config.in
X source fs/Config.in
X
X mainmenu_option next_comment
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/defconfig linux/arch/ppc/defconfig
--- v2.3.5/linux/arch/ppc/defconfig Mon May 31 22:28:04 1999
+++ linux/arch/ppc/defconfig Mon Jun 7 12:11:51 1999
@@ -9,14 +9,13 @@
X CONFIG_6xx=y
X # CONFIG_PPC64 is not set
X # CONFIG_8xx is not set
-CONFIG_PMAC=y
+# CONFIG_PMAC is not set
X # CONFIG_PREP is not set
X # CONFIG_CHRP is not set
-# CONFIG_ALL_PPC is not set
+CONFIG_ALL_PPC=y
X # CONFIG_APUS is not set
X # CONFIG_MBX is not set
X # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
X CONFIG_6xx=y
X
X #
@@ -51,6 +50,7 @@
X # CONFIG_TOTALMP is not set
X CONFIG_BOOTX_TEXT=y
X # CONFIG_MOTOROLA_HOTSWAP is not set
+# CONFIG_CMDLINE_BOOL is not set
X
X #
X # Plug and Play support
@@ -60,7 +60,7 @@
X #
X # Block devices
X #
-# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV_FD=y
X CONFIG_BLK_DEV_IDE=y
X
X #
@@ -77,7 +77,7 @@
X # CONFIG_BLK_DEV_CMD640 is not set
X # CONFIG_BLK_DEV_RZ1000 is not set
X # CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_SL82C105=y
X CONFIG_BLK_DEV_IDE_PMAC=y
X CONFIG_BLK_DEV_IDEDMA_PMAC=y
X CONFIG_BLK_DEV_IDEDMA=y
@@ -117,7 +117,7 @@
X # CONFIG_NET_IPGRE is not set
X # CONFIG_IP_MROUTE is not set
X CONFIG_IP_ALIAS=y
-# CONFIG_SYN_COOKIES is not set
+CONFIG_SYN_COOKIES=y
X
X #
X # (it is safe to leave these untouched)
@@ -199,7 +199,14 @@
X # CONFIG_SCSI_SYM53C416 is not set
X # CONFIG_SCSI_NCR53C7xx is not set
X # CONFIG_SCSI_NCR53C8XX is not set
-# CONFIG_SCSI_SYM53C8XX is not set
+CONFIG_SCSI_SYM53C8XX=y
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=20
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
X # CONFIG_SCSI_PAS16 is not set
X # CONFIG_SCSI_PCI2000 is not set
X # CONFIG_SCSI_PCI2220I is not set
@@ -237,7 +244,7 @@
X # CONFIG_ACENIC is not set
X # CONFIG_NET_ISA is not set
X CONFIG_NET_EISA=y
-# CONFIG_PCNET32 is not set
+CONFIG_PCNET32=y
X # CONFIG_AC3200 is not set
X # CONFIG_APRICOT is not set
X # CONFIG_CS89x0 is not set
@@ -297,12 +304,16 @@
X CONFIG_FB_CONTROL=y
X CONFIG_FB_PLATINUM=y
X CONFIG_FB_VALKYRIE=y
-CONFIG_FB_ATY=y
+# CONFIG_FB_ATY is not set
X CONFIG_FB_IMSTT=y
X CONFIG_FB_CT65550=y
X # CONFIG_FB_S3TRIO is not set
-# CONFIG_FB_MATROX is not set
-CONFIG_FB_ATY=y
+CONFIG_FB_MATROX=y
+# CONFIG_FB_MATROX_MILLENIUM is not set
+CONFIG_FB_MATROX_MYSTIQUE=y
+# CONFIG_FB_MATROX_G100 is not set
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+# CONFIG_FB_ATY is not set
X # CONFIG_FB_VIRTUAL is not set
X # CONFIG_FBCON_ADVANCED is not set
X CONFIG_FBCON_CFB8=y
@@ -324,12 +335,22 @@
X #
X CONFIG_VT=y
X CONFIG_VT_CONSOLE=y
-# CONFIG_SERIAL is not set
+CONFIG_SERIAL=m
X # CONFIG_SERIAL_EXTENDED is not set
X # CONFIG_SERIAL_NONSTANDARD is not set
X CONFIG_UNIX98_PTYS=y
X CONFIG_UNIX98_PTY_COUNT=256
-# CONFIG_MOUSE is not set
+CONFIG_MOUSE=y
+
+#
+# Mice
+#
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
X # CONFIG_QIC02_TAPE is not set
X # CONFIG_WATCHDOG is not set
X CONFIG_NVRAM=y
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/kernel/chrp_pci.c linux/arch/ppc/kernel/chrp_pci.c
--- v2.3.5/linux/arch/ppc/kernel/chrp_pci.c Mon May 31 22:28:04 1999
+++ linux/arch/ppc/kernel/chrp_pci.c Mon Jun 7 12:11:51 1999
@@ -167,6 +167,62 @@
X return PCIBIOS_SUCCESSFUL;
X }
X
+
+int rtas_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned char *val)
+{
+ unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
+ if ( call_rtas( "read-pci-config", 2, 2, (ulong *)&val, addr, 1 ) != 0 )
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int rtas_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned short *val)
+{
+ unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
+ if ( call_rtas( "read-pci-config", 2, 2, (ulong *)&val, addr, 2 ) != 0 )
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+int rtas_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned int *val)
+{
+ unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
+ if ( call_rtas( "read-pci-config", 2, 2, (ulong *)&val, addr, 4 ) != 0 )
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int rtas_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned char val)
+{
+ unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
+ if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 1, (ulong)val ) != 0 )
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int rtas_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned short val)
+{
+ unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
+ if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 2, (ulong)val ) != 0 )
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int rtas_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned int val)
+{
+ unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
+ if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 4, (ulong)val ) != 0 )
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ return PCIBIOS_SUCCESSFUL;
+}
+
X /*
X * Temporary fixes for PCI devices. These should be replaced by OF query
X * code -- Geert
@@ -256,6 +312,7 @@
X
X decl_config_access_method(grackle);
X decl_config_access_method(indirect);
+decl_config_access_method(rtas);
X
X void __init
X chrp_setup_pci_ptrs(void)
@@ -276,7 +333,7 @@
X {
X /* find out how many pythons */
X while ( (py = py->next) ) python_busnr++;
- set_config_access_method(python);
+ set_config_access_method(python);
X /*
X * We base these values on the machine type but should
X * try to read them from the python controller itself.
@@ -297,10 +354,22 @@
X }
X else
X {
- pci_dram_offset = 0;
- isa_mem_base = 0xf7000000;
- isa_io_base = 0xf8000000;
- set_config_access_method(gg2);
+ if ( !strncmp("IBM,7043-150", get_property(find_path_device("/"), "name", NULL),12) )
+ {
+ pci_dram_offset = 0;
+ isa_mem_base = 0x80000000;
+ isa_io_base = 0xfe000000;
+ pci_config_address = (unsigned int *)0xfec00000;
+ pci_config_data = (unsigned char *)0xfee00000;
+ set_config_access_method(indirect);
+ }
+ else
+ {
+ pci_dram_offset = 0;
+ isa_mem_base = 0xf7000000;
+ isa_io_base = 0xf8000000;
+ set_config_access_method(gg2);
+ }
X }
X }
X
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c
--- v2.3.5/linux/arch/ppc/kernel/chrp_setup.c Mon May 31 22:28:04 1999
+++ linux/arch/ppc/kernel/chrp_setup.c Mon Jun 7 12:11:51 1999
@@ -32,6 +32,7 @@
X #include <linux/console.h>
X #include <linux/pci.h>
X #include <linux/openpic.h>
+#include <linux/version.h>
X
X #include <asm/mmu.h>
X #include <asm/processor.h>
@@ -65,6 +66,7 @@
X
X unsigned long chrp_get_rtc_time(void);
X int chrp_set_rtc_time(unsigned long nowtime);
+unsigned long rtas_event_scan_rate = 0, rtas_event_scan_ct = 0;
X void chrp_calibrate_decr(void);
X void chrp_time_init(void);
X
@@ -235,6 +237,7 @@
X chrp_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p))
X {
X extern char cmd_line[];
+ struct device_node *device;
X
X /* init to some ~sane value until calibrate_delay() runs */
X loops_per_sec = 50000000;
@@ -274,57 +277,73 @@
X find_path_device("/"), "platform-open-pic", NULL);
X OpenPIC = ioremap((unsigned long)OpenPIC, sizeof(struct OpenPIC));
X }
-
+
X /*
X * Fix the Super I/O configuration
X */
- sio_init();
+ /*sio_init();*/
X #ifdef CONFIG_DUMMY_CONSOLE
X conswitchp = &dummy_con;
X #endif
- /* my starmax 6000 needs this but the longtrail shouldn't do it -- Cort */
- if ( !strncmp("MOT", get_property(find_path_device("/"),
- "model", NULL),3) )
- *memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p);
+ *memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p);
+
+ /* Get the event scan rate for the rtas so we know how
+ * often it expects a heartbeat. -- Cort
+ */
+ if ( rtas_data )
+ {
+ struct property *p;
+ device = find_devices("rtas");
+ for ( p = device->properties;
+ strncmp(p->name, "rtas-event-scan-rate", 20) && p ;
+ p = p->next )
+ /* nothing */ ;
+ if ( p && *(unsigned long *)p->value )
+ {
+ rtas_event_scan_rate = (HZ/(*(unsigned long *)p->value)*30)-1;
+ rtas_event_scan_ct = 1;
+ printk("RTAS Event Scan Rate: %lu (%lu jiffies)\n",
+ *(unsigned long *)p->value, rtas_event_scan_rate );
+ }
+ }
X }
X
X void
+chrp_event_scan(void)
+{
+ unsigned char log[1024];
+ if ( rtas_event_scan_rate && (rtas_event_scan_ct-- <= 0) )
+ {
+ call_rtas( "event-scan", 4, 1, NULL, 0x0, 1, __pa(log), 1024 );
+ rtas_event_scan_ct = rtas_event_scan_rate;
+ }
+}
+
+void
X chrp_restart(char *cmd)
X {
-#if 0
- extern unsigned int rtas_entry, rtas_data, rtas_size;
X printk("RTAS system-reboot returned %d\n",
X call_rtas("system-reboot", 0, 1, NULL));
- printk("rtas_entry: %08lx rtas_data: %08lx rtas_size: %08lx\n",
- rtas_entry,rtas_data,rtas_size);
X for (;;);
-#else
- printk("System Halted\n");
- while(1);
-#endif
X }
X
X void
X chrp_power_off(void)
X {
- /* RTAS doesn't seem to work on Longtrail.
- For now, do it the same way as the PReP. */
-#if 0
- extern unsigned int rtas_entry, rtas_data, rtas_size;
+ /* allow power on only with power button press */
+#define PWR_FIELD(x) (0x8000000000000000 >> ((x)-96))
X printk("RTAS power-off returned %d\n",
- call_rtas("power-off", 2, 1, NULL, 0, 0));
- printk("rtas_entry: %08lx rtas_data: %08lx rtas_size: %08lx\n",
- rtas_entry,rtas_data,rtas_size);
+ call_rtas("power-off", 2, 1, NULL,
+ ((PWR_FIELD(96)|PWR_FIELD(97))>>32)&0xffffffff,
+ (PWR_FIELD(96)|PWR_FIELD(97))&0xffffffff));
+#undef PWR_FIELD
X for (;;);
-#else
- chrp_restart(NULL);
-#endif
X }
X
X void
X chrp_halt(void)
X {
- chrp_restart(NULL);
+ chrp_power_off();
X }
X
X u_int
@@ -653,5 +672,21 @@
X ppc_ide_md.ide_init_hwif = chrp_ide_init_hwif_ports;
X
X ppc_ide_md.io_base = _IO_BASE;
-#endif
+#endif
+ /*
+ * Print the banner, then scroll down so boot progress
+ * can be printed. -- Cort
+ */
+ chrp_progress("Linux/PPC "UTS_RELEASE"\n");
+}
+
+void chrp_progress(char *s)
+{
+ extern unsigned int rtas_data;
+
+ if ( (_machine != _MACH_chrp) || !rtas_data )
+ return;
+ call_rtas( "display-character", 1, 1, NULL, '\r' );
+ while ( *s )
+ call_rtas( "display-character", 1, 1, NULL, *s++ );
X }
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
--- v2.3.5/linux/arch/ppc/kernel/head.S Mon May 31 22:28:04 1999
+++ linux/arch/ppc/kernel/head.S Mon Jun 7 12:11:51 1999
@@ -1,7 +1,7 @@
X /*
X * arch/ppc/kernel/head.S
X *
- * $Id: head.S,v 1.131 1999/05/14 22:37:21 cort Exp $
+ * $Id: head.S,v 1.133 1999/05/20 05:13:08 cort Exp $
X *
X * PowerPC version
X * Copyright (C) 1995-1996 Gary Thomas (g...@linuxppc.org)
@@ -2615,7 +2615,6 @@
X */
X .globl enter_rtas
X enter_rtas:
- stwu r1,-16(r1)
X mflr r0
X stw r0,20(r1)
X lis r4,rtas_data@ha
@@ -2636,7 +2635,6 @@
X andi. r9,r9,MSR_ME|MSR_RI
X sync /* disable interrupts so SRR0/1 */
X mtmsr r0 /* don't get trashed */
- li r6,0
X mtlr r6
X mtspr SPRG2,r7
X mtspr SRR0,r8
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/kernel/idle.c linux/arch/ppc/kernel/idle.c
--- v2.3.5/linux/arch/ppc/kernel/idle.c Thu Apr 29 12:39:01 1999
+++ linux/arch/ppc/kernel/idle.c Mon Jun 7 12:11:51 1999
@@ -1,5 +1,5 @@
X /*
- * $Id: idle.c,v 1.61 1999/03/18 04:15:45 cort Exp $
+ * $Id: idle.c,v 1.62 1999/05/24 05:43:18 cort Exp $
X *
X * Idle daemon for PowerPC. Idle daemon will handle any action
X * that needs to be taken when the system becomes idle.
@@ -50,6 +50,7 @@
X /* endless loop with no priority at all */
X current->priority = 0;
X current->counter = -100;
+ init_idle();
X for (;;)
X {
X __sti();
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- v2.3.5/linux/arch/ppc/kernel/irq.c Thu Apr 29 12:39:01 1999
+++ linux/arch/ppc/kernel/irq.c Mon Jun 7 12:11:51 1999
@@ -1,5 +1,5 @@
X /*
- * $Id: irq.c,v 1.105 1999/03/25 19:51:51 cort Exp $
+ * $Id: irq.c,v 1.106 1999/05/25 21:16:04 cort Exp $
X *
X * arch/ppc/kernel/irq.c
X *
@@ -65,7 +65,6 @@
X void enable_irq(unsigned int irq_nr);
X void disable_irq(unsigned int irq_nr);
X
-/* Fixme - Need to figure out a way to get rid of this - Corey */
X volatile unsigned char *chrp_int_ack_special;
X
X #ifdef CONFIG_APUS
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
--- v2.3.5/linux/arch/ppc/kernel/misc.S Mon May 31 22:28:04 1999
+++ linux/arch/ppc/kernel/misc.S Mon Jun 7 12:11:51 1999
@@ -866,7 +866,11 @@
X .long sys_getresuid /* 165 */
SHAR_EOF
true || echo 'restore of patch-2.3.6 failed'
fi
echo 'End of part 01'
echo 'File patch-2.3.6 is continued in part 02'
echo 02 > _shar_seq_.tmp
exit 0

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.3/patch-2.3.6/part02

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


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

# file patch-2.3.6 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.3.6'
else
echo 'x - continuing with patch-2.3.6'


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

X .long sys_query_module
X .long sys_poll
+#ifdef CONFIG_NFS
X .long sys_nfsservctl
+#else
+ .long sys_ni_syscall
+#endif
X .long sys_setresgid
X .long sys_getresgid /* 170 */
X .long sys_prctl
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
--- v2.3.5/linux/arch/ppc/kernel/prom.c Tue May 11 08:24:32 1999
+++ linux/arch/ppc/kernel/prom.c Mon Jun 7 12:11:51 1999


@@ -1,5 +1,5 @@
X /*

- * $Id: prom.c,v 1.54 1999/05/10 04:43:46 cort Exp $
+ * $Id: prom.c,v 1.60 1999/05/25 01:42:41 cort Exp $
X *
X * Procedures for interfacing to the Open Firmware PROM on
X * Power Macintosh computers.
@@ -24,6 +24,7 @@
X #include <asm/io.h>
X #include <asm/smp.h>
X #include <asm/bootx.h>
+#include <asm/system.h>
X
X /*
X * Properties whose value is longer than this get excluded from our
@@ -412,6 +413,9 @@
X mem = copy_device_tree(mem, mem + (1<<20));
X prom_print(RELOC("done\n"));
X
+
+ RELOC(klimit) = (char *) (mem - offset);
+
X prom_rtas = call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
X if (prom_rtas != (void *) -1) {
X RELOC(rtas_size) = 0;
@@ -421,9 +425,19 @@
X if (RELOC(rtas_size) == 0) {
X RELOC(rtas_data) = 0;
X } else {
- mem = (mem + 4095) & -4096; /* round to page bdry */
+ /*
+ * We do _not_ want the rtas_data inside the klimit
+ * boundry since it'll be squashed when we do the
+ * relocate of the kernel on chrp right after prom_init()
+ * in head.S. So, we just pick a spot in memory.
+ * -- Cort
+ */
+#if 0
+ mem = (mem + 4095) & -4096;
X RELOC(rtas_data) = mem + KERNELBASE;
X mem += RELOC(rtas_size);
+#endif
+ RELOC(rtas_data) = (6<<20) + KERNELBASE;
X }
X prom_rtas = call_prom(RELOC("open"), 1, 1, RELOC("/rtas"));
X {
@@ -448,7 +462,7 @@
X else
X prom_print(RELOC(" done\n"));
X }
- RELOC(klimit) = (char *) (mem - offset);
+
X #ifdef CONFIG_SMP
X /*
X * With CHRP SMP we need to use the OF to start the other
@@ -1289,7 +1303,7 @@
X unsigned long *outputs, ...)
X {
X va_list list;
- int i;
+ int i, s;
X struct device_node *rtas;
X int *tokp;
X union {
@@ -1305,16 +1319,19 @@
X printk(KERN_ERR "No RTAS service called %s\n", service);
X return -1;
X }
- u.words[0] = __pa(*tokp);
+ u.words[0] = *tokp;
X u.words[1] = nargs;
X u.words[2] = nret;
X va_start(list, outputs);
X for (i = 0; i < nargs; ++i)
X u.words[i+3] = va_arg(list, unsigned long);
X va_end(list);
+
+ s = _disable_interrupts();
X spin_lock(&rtas_lock);
X enter_rtas((void *)__pa(&u));
X spin_unlock(&rtas_lock);
+ _enable_interrupts(s);
X if (nret > 1 && outputs != NULL)
X for (i = 0; i < nret-1; ++i)
X outputs[i] = u.words[i+nargs+4];
@@ -1326,8 +1343,7 @@
X abort()
X {
X #ifdef CONFIG_XMON
- extern void xmon(void *);
- xmon(0);
+ xmon(NULL);
X #endif
X prom_exit();
X }
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/kernel/ptrace.c linux/arch/ppc/kernel/ptrace.c
--- v2.3.5/linux/arch/ppc/kernel/ptrace.c Mon May 31 22:28:04 1999
+++ linux/arch/ppc/kernel/ptrace.c Mon Jun 7 11:15:33 1999
@@ -190,25 +190,6 @@


X flush_tlb_all();
X }
X
-static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigned long addr)
-{
- struct vm_area_struct * vma;
-
- addr &= PAGE_MASK;

- vma = find_vma(tsk->mm,addr);
- if (!vma)
- return NULL;
- if (vma->vm_start <= addr)
- return vma;
- if (!(vma->vm_flags & VM_GROWSDOWN))
- return NULL;
- if (vma->vm_end - addr > tsk->rlim[RLIMIT_STACK].rlim_cur)
- return NULL;
- vma->vm_offset -= vma->vm_start - addr;
- vma->vm_start = addr;
- return vma;
-}
-
X /*
X * This routine checks the page boundaries, and that the offset is
X * within the task area. It then calls get_long() to read a long.

diff -u --recursive --new-file v2.3.5/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
--- v2.3.5/linux/arch/ppc/kernel/smp.c Thu Apr 29 12:39:01 1999
+++ linux/arch/ppc/kernel/smp.c Mon Jun 7 12:11:51 1999


@@ -1,5 +1,5 @@
X /*

- * $Id: smp.c,v 1.49 1999/03/18 04:16:31 cort Exp $
+ * $Id: smp.c,v 1.52 1999/05/23 22:43:51 cort Exp $
X *
X * Smp support for ppc.
X *
@@ -388,9 +388,12 @@
X
X void __init smp_callin(void)
X {
+ int i;
+
X printk("SMP %d: smp_callin()\n",current->processor);
X smp_store_cpu_info(current->processor);
X set_dec(decrementer_count);
+
X #if 0
X current->mm->mmap->vm_page_prot = PAGE_SHARED;
X current->mm->mmap->vm_start = PAGE_OFFSET;
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/kernel/syscalls.c linux/arch/ppc/kernel/syscalls.c
--- v2.3.5/linux/arch/ppc/kernel/syscalls.c Mon May 31 22:28:04 1999
+++ linux/arch/ppc/kernel/syscalls.c Mon Jun 7 12:11:51 1999
@@ -182,18 +182,14 @@
X int fd[2];
X int error;
X
- error = verify_area(VERIFY_WRITE, fildes, 8);
- if (error)
- return error;
X lock_kernel();
X error = do_pipe(fd);
X unlock_kernel();
- if (error)
- return error;
- if (__put_user(fd[0],0+fildes)
- || __put_user(fd[1],1+fildes))
- return -EFAULT; /* should we close the fds? */
- return 0;
+ if (!error) {
+ if (copy_to_user(fildes, fd, 2*sizeof(int)))
+ error = -EFAULT;
+ }
+ return error;
X }
X
X asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c
--- v2.3.5/linux/arch/ppc/kernel/time.c Thu Apr 29 12:39:01 1999
+++ linux/arch/ppc/kernel/time.c Mon Jun 7 12:11:51 1999


@@ -1,5 +1,5 @@
X /*

- * $Id: time.c,v 1.47 1999/03/18 05:11:11 cort Exp $
+ * $Id: time.c,v 1.48 1999/05/22 19:35:57 cort Exp $
X * Common time routines among all ppc machines.
X *
X * Written by Cort Dougan (co...@cs.nmt.edu) to merge
@@ -126,13 +126,17 @@
X smp_local_timer_interrupt(regs);
X #endif
X
- /* Fixme - make this more generic - Corey */
X #ifdef CONFIG_APUS
X {
X extern void apus_heartbeat (void);
X apus_heartbeat ();
X }
X #endif
+#if defined(CONFIG_ALL_PPC) || defined(CONFIG_CHRP)
+ if ( _machine == _MACH_chrp )
+ chrp_event_scan();
+#endif
+
X hardirq_exit(cpu);
X }
X
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v2.3.5/linux/arch/ppc/mm/init.c Mon May 31 22:28:04 1999
+++ linux/arch/ppc/mm/init.c Mon Jun 7 12:11:51 1999


@@ -1,5 +1,5 @@
X /*

- * $Id: init.c,v 1.165 1999/05/14 22:37:29 cort Exp $
+ * $Id: init.c,v 1.166 1999/05/22 18:18:30 cort Exp $


X *
X * PowerPC version
X * Copyright (C) 1995-1996 Gary Thomas (g...@linuxppc.org)

@@ -402,7 +402,7 @@
X for (i = 0; i < size; i += PAGE_SIZE)
X map_page(&init_task, v+i, p+i, flags);
X out:
- return (void *) (v + (p & ~PAGE_MASK));
+ return (void *) (v + (addr & ~PAGE_MASK));
X }
X
X void iounmap(void *addr)
diff -u --recursive --new-file v2.3.5/linux/arch/ppc/xmon/xmon.c linux/arch/ppc/xmon/xmon.c
--- v2.3.5/linux/arch/ppc/xmon/xmon.c Mon May 31 22:28:04 1999
+++ linux/arch/ppc/xmon/xmon.c Mon Jun 7 12:11:51 1999
@@ -999,7 +999,7 @@
X int c;
X
X c = inchar();
- if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
+ if ((isxdigit(c) && (c != 'f') && (c != 'd')) || (c == '\n'))
X termch = c;
X scanhex(&adrs);
X if( termch != '\n')
diff -u --recursive --new-file v2.3.5/linux/arch/sparc/Makefile linux/arch/sparc/Makefile
--- v2.3.5/linux/arch/sparc/Makefile Sun Oct 4 10:22:42 1998
+++ linux/arch/sparc/Makefile Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.39 1998/09/16 12:31:31 jj Exp $
+# $Id: Makefile,v 1.41 1999/06/04 13:29:05 jj Exp $
X # sparc/Makefile
X #
X # Makefile for the architecture dependent flags and dependencies on the
@@ -15,7 +15,7 @@
X # Uncomment the first CFLAGS if you are doing kgdb source level
X # debugging of the kernel to get the proper debugging information.
X
-IS_EGCS := $(shell if $(CC) --version 2>&1 | grep 'egcs' > /dev/null; then echo y; else echo n; fi)
+IS_EGCS := $(shell if $(CC) -c -m32 -o _tmp.o arch/sparc/math-emu/fnegs.c >/dev/null 2>&1; then echo y; else echo n; fi; rm -f _tmp.o)
X NEW_GAS := $(shell if $(LD) --version 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
X
X ifeq ($(NEW_GAS),y)
diff -u --recursive --new-file v2.3.5/linux/arch/sparc/kernel/ebus.c linux/arch/sparc/kernel/ebus.c
--- v2.3.5/linux/arch/sparc/kernel/ebus.c Tue Oct 27 09:52:20 1998
+++ linux/arch/sparc/kernel/ebus.c Wed Jun 9 14:44:25 1999
@@ -1,9 +1,10 @@
-/* $Id: ebus.c,v 1.2 1998/10/07 11:35:16 jj Exp $
+/* $Id: ebus.c,v 1.3 1999/06/03 15:02:09 davem Exp $
X * ebus.c: PCI to EBus bridge device.
X *
X * Copyright (C) 1997 Eddie C. Dost (e...@skynet.be)
X *
X * Adopted for sparc by V. Roganov and G. Raiko.
+ * Fixes for different platforms by Pete Zaitcev.
X */
X
X #include <linux/config.h>
@@ -25,9 +26,9 @@
X #undef DEBUG_FILL_EBUS_DEV
X
X #ifdef PROM_DEBUG
-#define dprintf prom_printf
+#define dprintk prom_printf
X #else
-#define dprintf printk
+#define dprintk printk
X #endif
X
X struct linux_ebus *ebus_chain = 0;
@@ -48,6 +49,9 @@
X extern int envctrl_init(void);
X #endif
X
+/* We are together with pcic.c under CONFIG_PCI. */
+extern unsigned int pcic_pin_to_irq(unsigned int, char *name);
+
X static inline unsigned long ebus_alloc(size_t size)
X {
X return (unsigned long)kmalloc(size, GFP_ATOMIC);
@@ -66,6 +70,7 @@
X strcpy(dev->prom_name, lbuf);
X
X len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
+ if (len == -1) len = 0;
X dev->num_addrs = len / sizeof(regs[0]);
X
X for (i = 0; i < dev->num_addrs; i++) {
@@ -77,22 +82,36 @@
X dev->base_address[i] = dev->parent->base_address[regs[i]];
X }
X
+ /*
+ * Houston, we have a problem...
+ * Sometimes PROM supplies absolutely meaningless properties.
+ * Still, we take what it gives since we have nothing better.
+ * Children of ebus may be wired on any input pin of PCIC.
+ */
X len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
X if ((len == -1) || (len == 0)) {
X dev->num_irqs = 0;
- /*
- * Oh, well, some PROMs don't export interrupts
- * property to children of EBus devices...
- *
- * Be smart about PS/2 keyboard and mouse.
- */
- if (!strcmp(dev->parent->prom_name, "8042")) {
+ dev->irqs[0] = 0;
+ if (dev->parent->num_irqs != 0) {
X dev->num_irqs = 1;
X dev->irqs[0] = dev->parent->irqs[0];
+/* P3 remove */ printk("EBUS: dev %s irq %d from parent\n", dev->prom_name, dev->irqs[0]);
X }
X } else {
X dev->num_irqs = len / sizeof(irqs[0]);
- printk("FIXME: %s irq(%d)\n", dev->prom_name, irqs[0]);
+ if (irqs[0] == 0 || irqs[0] >= 8) {
+ /*
+ * XXX Zero is a valid pin number...
+ * This works as long as Ebus is not wired to INTA#.
+ */
+ printk("EBUS: %s got bad irq %d from PROM\n",
+ dev->prom_name, irqs[0]);
+ dev->num_irqs = 0;
+ dev->irqs[0] = 0;
+ } else {
+ dev->irqs[0] = pcic_pin_to_irq(irqs[0], dev->prom_name);
+/* P3 remove */ printk("EBUS: dev %s irq %d from PROM\n", dev->prom_name, dev->irqs[0]);
+ }
X }
X
X #ifdef DEBUG_FILL_EBUS_DEV
@@ -131,7 +150,30 @@
X dev->num_addrs = len / sizeof(struct linux_prom_registers);
X
X for (i = 0; i < dev->num_addrs; i++) {
- n = (regs[i].which_io - 0x10) >> 2;
+ /*
+ * XXX Collect JE-1 PROM
+ *
+ * Example - JS-E with 3.11:
+ * /ebus
+ * regs
+ * 0x00000000, 0x0, 0x00000000, 0x0, 0x00000000,
+ * 0x82000010, 0x0, 0xf0000000, 0x0, 0x01000000,
+ * 0x82000014, 0x0, 0x38800000, 0x0, 0x00800000,
+ * ranges
+ * 0x00, 0x00000000, 0x02000010, 0x0, 0x0, 0x01000000,
+ * 0x01, 0x01000000, 0x02000014, 0x0, 0x0, 0x00800000,
+ * /ebus/8042
+ * regs
+ * 0x00000001, 0x00300060, 0x00000008,
+ * 0x00000001, 0x00300060, 0x00000008,
+ */
+ n = regs[i].which_io;
+ if (n >= 4) {
+ /* XXX This is copied from old JE-1 by Gleb. */
+ n = (regs[i].which_io - 0x10) >> 2;
+ } else {
+ ;
+ }
X
X dev->base_address[i] = dev->bus->self->base_address[n];
X dev->base_address[i] += regs[i].phys_addr;
@@ -141,8 +183,14 @@
X (unsigned long)sparc_alloc_io (dev->base_address[i], 0,
X regs[i].reg_size,
X dev->prom_name, 0, 0);
+#if 0
+/*
+ * This release_region() screwes those who do sparc_alloc_io().
+ * Change drivers which do check_region(). See drivers/block/floppy.c.
+ */
X /* Some drivers call 'check_region', so we release it */
X release_region(dev->base_address[i] & PAGE_MASK, PAGE_SIZE);
+#endif
X
X if (dev->base_address[i] == 0 ) {
X panic("ebus: unable sparc_alloc_io for dev %s",
@@ -154,12 +202,22 @@
X len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
X if ((len == -1) || (len == 0)) {
X dev->num_irqs = 0;
+ if ((dev->irqs[0] = dev->bus->self->irq) != 0) {
+ dev->num_irqs = 1;
+/* P3 remove */ printk("EBUS: child %s irq %d from parent\n", dev->prom_name, dev->irqs[0]);
+ }
X } else {
- dev->num_irqs = len / sizeof(irqs[0]);
-
-#define IRQ_8042 7
- if (irqs[0] == 4) dev->irqs[0] = IRQ_8042;
- printk("FIXME: %s irq(%d)\n", dev->prom_name, irqs[0]);
+ dev->num_irqs = 1; /* dev->num_irqs = len / sizeof(irqs[0]); */
+ if (irqs[0] == 0 || irqs[0] >= 8) {
+ /* See above for the parent. XXX */
+ printk("EBUS: %s got bad irq %d from PROM\n",
+ dev->prom_name, irqs[0]);
+ dev->num_irqs = 0;
+ dev->irqs[0] = 0;
+ } else {
+ dev->irqs[0] = pcic_pin_to_irq(irqs[0], dev->prom_name);
+/* P3 remove */ printk("EBUS: child %s irq %d from PROM\n", dev->prom_name, dev->irqs[0]);
+ }
X }
X
X #ifdef DEBUG_FILL_EBUS_DEV
diff -u --recursive --new-file v2.3.5/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S
--- v2.3.5/linux/arch/sparc/kernel/entry.S Tue May 11 08:24:31 1999
+++ linux/arch/sparc/kernel/entry.S Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.159 1999/05/08 03:00:03 davem Exp $
+/* $Id: entry.S,v 1.160 1999/06/03 15:02:11 davem Exp $
X * arch/sparc/kernel/entry.S: Sparc trap low-level entry points.
X *
X * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -1888,5 +1888,53 @@
X LOAD_CURRENT(g6, o0)
X retl
X nop
+
+#ifdef CONFIG_PCI
+#include <asm/pcic.h>
+
+ .align 4
+ .globl linux_trap_ipi15_pcic
+linux_trap_ipi15_pcic:
+ rd %wim, %l3
+ SAVE_ALL
+
+ /*
+ * First deactivate NMI
+ * or we cannot drop ET, cannot get window spill traps.
+ * The busy loop is necessary because the PIO error
+ * sometimes does not go away quickly and we trap again.
+ */
+ sethi %hi(C_LABEL(pcic_regs)), %o1
+ ld [%o1 + %lo(C_LABEL(pcic_regs))], %o2
+
+ ! Get pending status for printouts later.
+ ld [%o2 + PCI_SYS_INT_PENDING], %o0
+
+ mov PCI_SYS_INT_PENDING_CLEAR_ALL, %o1
+ stb %o1, [%o2 + PCI_SYS_INT_PENDING_CLEAR]
+1:
+ ld [%o2 + PCI_SYS_INT_PENDING], %o1
+ andcc %o1, ((PCI_SYS_INT_PENDING_PIO|PCI_SYS_INT_PENDING_PCI)>>24), %g0
+ bne 1b
+ nop
+
+ or %l0, PSR_PIL, %l4
+ wr %l4, 0x0, %psr
+ WRITE_PAUSE
+ wr %l4, PSR_ET, %psr
+ WRITE_PAUSE
+
+ call C_LABEL(pcic_nmi)
+ add %sp, REGWIN_SZ, %o1 ! struct pt_regs *regs
+ RESTORE_ALL
+
+ .globl C_LABEL(pcic_nmi_trap_patch)
+C_LABEL(pcic_nmi_trap_patch):
+ sethi %hi(linux_trap_ipi15_pcic), %l3
+ jmpl %l3 + %lo(linux_trap_ipi15_pcic), %g0
+ rd %psr, %l0
+ .word 0
+
+#endif /* CONFIG_PCI */
X
X /* End of entry.S */
diff -u --recursive --new-file v2.3.5/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S
--- v2.3.5/linux/arch/sparc/kernel/head.S Thu Apr 22 19:24:51 1999
+++ linux/arch/sparc/kernel/head.S Wed Jun 9 14:44:25 1999
@@ -1,11 +1,13 @@
-/* $Id: head.S,v 1.95 1999/04/13 07:40:34 anton Exp $
+/* $Id: head.S,v 1.96 1999/06/03 15:02:15 davem Exp $
X * head.S: The initial boot code for the Sparc port of Linux.
X *
X * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
- * Copyright (C) 1995 Peter Zaitcev (Zai...@ipmce.su)
+ * Copyright (C) 1995,1999 Pete Zaitcev (zai...@metabyte.com)
X * Copyright (C) 1996 Miguel de Icaza (mig...@nuclecu.unam.mx)
X * Copyright (C) 1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
X * Copyright (C) 1997 Michael A. Griffith (gr...@acm.org)
+ *
+ * CompactPCI platform by Eric Brower, 1999.
X */
X
X #include <linux/version.h>
@@ -116,10 +118,10 @@
X t_irq12:TRAP_ENTRY_INTERRUPT(12) /* IRQ Zilog serial chip */
X t_irq13:TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */
X t_irq14:TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */
+ .globl t_nmi
X #ifndef __SMP__
X t_nmi: NMI_TRAP /* Level 15 (NMI) */
X #else
- .globl t_nmi
X t_nmi: TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m)
X #endif
X t_racc: TRAP_ENTRY(0x20, do_reg_access) /* General Register Access Error */
@@ -842,6 +844,8 @@
X be 1f
X cmp %l1, 'm'
X be 1f
+ cmp %l1, 's'
+ be 1f
X cmp %l1, 'd'
X be 1f
X cmp %l1, 'e'
@@ -853,6 +857,8 @@
X 1: set C_LABEL(cputypval), %l1
X ldub [%l1 + 0x4], %l1
X cmp %l1, 'm' ! Test for sun4d, sun4e ?
+ be sun4m_init
+ cmp %l1, 's' ! Treat sun4s as sun4m
X be sun4m_init
X cmp %l1, 'd' ! Let us see how the beast will die
X be sun4d_init
diff -u --recursive --new-file v2.3.5/linux/arch/sparc/kernel/pcic.c linux/arch/sparc/kernel/pcic.c
--- v2.3.5/linux/arch/sparc/kernel/pcic.c Tue Mar 16 21:52:05 1999
+++ linux/arch/sparc/kernel/pcic.c Wed Jun 9 14:44:25 1999
@@ -1,10 +1,13 @@
-/* $Id: pcic.c,v 1.5 1999/03/16 00:15:20 davem Exp $
+/* $Id: pcic.c,v 1.6 1999/06/03 15:02:18 davem Exp $
X * pcic.c: Sparc/PCI controller support
X *
X * Copyright (C) 1998 V. Roganov and G. Raiko
X *
X * Code is derived from Ultra/PCI PSYCHO controller support, see that
X * for author info.
+ *
+ * Support for diverse IIep based platforms by Pete Zaitcev.
+ * CP-1200 by Eric Brower.
X */
X
X #include <linux/config.h>
@@ -16,6 +19,7 @@
X
X #include <asm/ebus.h>
X #include <asm/sbus.h> /* for sanity check... */
+#include <asm/swift.h> /* for cache flushing. */
X
X #include <asm/io.h>
X
@@ -69,9 +73,99 @@
X
X #else
X
+unsigned int pcic_pin_to_irq(unsigned int pin, char *name);
+
+/*
+ * I studied different documents and many live PROMs both from 2.30
+ * family and 3.xx versions. I came to the amazing conclusion: there is
+ * absolutely no way to route interrupts in IIep systems relying on
+ * information which PROM presents. We must hardcode interrupt routing
+ * schematics. And this actually sucks. -- zaitcev 1999/05/12
+ *
+ * To find irq for a device we determine which routing map
+ * is in effect or, in other words, on which machine we are running.
+ * We use PROM name for this although other techniques may be used
+ * in special cases (Gleb reports a PROMless IIep based system).
+ * Once we know the map we take device configuration address and
+ * find PCIC pin number where INT line goes. Then we may either program
+ * preferred irq into the PCIC or supply the preexisting irq to the device.
+ *
+ * XXX Entries for JE-1 are completely bogus. Gleb, Vladimir, please fill them.
+ */
+struct pcic_ca2irq {
+ unsigned char busno; /* PCI bus number */
+ unsigned char devfn; /* Configuration address */
+ unsigned char pin; /* PCIC external interrupt pin */
+ unsigned char irq; /* Preferred IRQ (mappable in PCIC) */
+ unsigned int force; /* Enforce preferred IRQ */
+};
+
+struct pcic_sn2list {
+ char *sysname;
+ struct pcic_ca2irq *intmap;
+ int mapdim;
+};
+
+/*
+ * XXX JE-1 is a little known beast.
+ * One rumor has the map this way: pin 0 - parallel, audio;
+ * pin 1 - Ethernet; pin 2 - su; pin 3 - PS/2 kbd and mouse.
+ * All other comparable systems tie serial and keyboard together,
+ * so we do not code this rumor just yet.
+ */
+static struct pcic_ca2irq pcic_i_je1[] = {
+ { 0, 0x01, 1, 6, 1 }, /* Happy Meal */
+};
+
+/* XXX JS-E entry is incomplete - PCI Slot 2 address (pin 7)? */
+static struct pcic_ca2irq pcic_i_jse[] = {
+ { 0, 0x00, 0, 13, 0 }, /* Ebus - serial and keyboard */
+ { 0, 0x01, 1, 6, 0 }, /* hme */
+ { 0, 0x08, 2, 9, 0 }, /* VGA - we hope not used :) */
+ { 0, 0x18, 6, 8, 0 }, /* PCI INTA# in Slot 1 */
+ { 0, 0x38, 4, 9, 0 }, /* All ISA devices. Read 8259. */
+ { 0, 0x80, 5, 11, 0 }, /* EIDE */
+ /* {0,0x88, 0,0,0} - unknown device... PMU? Probably no interrupt. */
+ { 0, 0xA0, 4, 9, 0 }, /* USB */
+ /*
+ * Some pins belong to non-PCI devices, we hardcode them in drivers.
+ * sun4m timers - irq 10, 14
+ * PC style RTC - pin 7, irq 4 ?
+ * Smart card, Parallel - pin 4 shared with USB, ISA
+ * audio - pin 3, irq 5 ?
+ */
+};
+
+/* SPARCengine-6 was the original release name of CP1200.
+ * The documentation differs between the two versions
+ */
+static struct pcic_ca2irq pcic_i_se6[] = {
+ { 0, 0x08, 0, 2, 0 }, /* SCSI */
+ { 0, 0x01, 1, 6, 0 }, /* HME */
+ { 0, 0x00, 3, 13, 0 }, /* EBus */
+};
+
+/*
+ * Several entries in this list may point to the same routing map
+ * as several PROMs may be installed on the same physical board.
+ */
+#define SN2L_INIT(name, map) \
+ { name, map, sizeof(map)/sizeof(struct pcic_ca2irq) }
+
+static struct pcic_sn2list pcic_known_sysnames[] = {
+ SN2L_INIT("JE-1-name", pcic_i_je1), /* XXX Gleb, put name here, pls */
+ SN2L_INIT("SUNW,JS-E", pcic_i_jse), /* PROLL JavaStation-E */
+ SN2L_INIT("SUNW,SPARCengine-6", pcic_i_se6), /* SPARCengine-6/CP-1200 */
+ { NULL, NULL, 0 }
+};
+
X static struct linux_pcic PCIC;
X static struct linux_pcic *pcic = NULL;
X
+unsigned int pcic_regs;
+volatile int pcic_speculative;
+volatile int pcic_trapped;
+
X static void pci_do_gettimeofday(struct timeval *tv);
X static void pci_do_settimeofday(struct timeval *tv);
X
@@ -149,6 +243,37 @@
X pbm->prom_node = node;
X prom_getstring(node, "name", namebuf, sizeof(namebuf));
X strcpy(pbm->prom_name, namebuf);
+
+ {
+ extern volatile int t_nmi[1];
+ extern int pcic_nmi_trap_patch[1];
+
+ t_nmi[0] = pcic_nmi_trap_patch[0];
+ t_nmi[1] = pcic_nmi_trap_patch[1];
+ t_nmi[2] = pcic_nmi_trap_patch[2];
+ t_nmi[3] = pcic_nmi_trap_patch[3];
+ swift_flush_dcache();
+ pcic_regs = pcic->pcic_regs;
+ }
+
+ prom_getstring(prom_root_node, "name", namebuf, sizeof(namebuf));
+ {
+ struct pcic_sn2list *p;
+
+ for (p = pcic_known_sysnames; p->sysname != NULL; p++) {
+ if (strcmp(namebuf, p->sysname) == 0)
+ break;
+ }
+ pcic->pcic_imap = p->intmap;
+ pcic->pcic_imdim = p->mapdim;
+ }
+ if (pcic->pcic_imap == NULL) {
+ /*
+ * We do not panic here for the sake of embedded systems.
+ */
+ printk("PCIC: System %s is unknown, cannot route interrupts\n",
+ namebuf);
+ }
X }
X
X __initfunc(void pcibios_init(void))
@@ -166,20 +291,15 @@
X pcic->pcic_regs, pcic->pcic_io);
X
X /*
- * FIXME:
X * Switch off IOTLB translation.
- * It'll be great to use IOMMU to handle HME's rings
- * but we couldn't. Thus, we have to flush CPU cache
- * in HME.
X */
X writeb(PCI_DVMA_CONTROL_IOTLB_DISABLE,
X pcic->pcic_regs+PCI_DVMA_CONTROL);
X
X /*
- * FIXME:
X * Increase mapped size for PCI memory space (DMA access).
X * Should be done in that order (size first, address second).
- * Why we couldn't set up 4GB and forget about it ?
+ * Why we couldn't set up 4GB and forget about it? XXX
X */
X writel(0xF0000000UL, pcic->pcic_regs+PCI_SIZE_0);
X writel(0+PCI_BASE_ADDRESS_SPACE_MEMORY,
@@ -204,7 +324,7 @@
X if(err != 0 && err != -1) {
X unsigned long devfn = (regs[0].which_io >> 8) & 0xff;
X if(devfn == pdev->devfn)
- return node; /* Match */
+ return node;
X }
X node = prom_getsibling(node);
X }
@@ -216,9 +336,9 @@
X return kmalloc(sizeof(struct pcidev_cookie), GFP_ATOMIC);
X }
X
-
-static void pcic_map_pci_device (struct pci_dev *dev) {
- int node, pcinode;
+static void pcic_map_pci_device (struct pci_dev *dev, int node) {
+ struct linux_prom_pci_assigned_addresses addrs[6];
+ int addrlen;
X int i, j;
X
X /* Is any valid address present ? */
@@ -227,74 +347,132 @@
X if (dev->base_address[j]) i++;
X if (!i) return; /* nothing to do */
X
+ if (node == 0 || node == -1) {
+ printk("PCIC: no prom node for device ID (%x,%x)\n",
+ dev->device, dev->vendor);
+ return;
+ }
+
X /*
X * find related address and get it's window length
X */
- pcinode = prom_getchild(prom_root_node);
- pcinode = prom_searchsiblings(pcinode, "pci");
- if (!pcinode)
- panic("PCIC: failed to locate 'pci' node");
-
-
- for (node = prom_getchild(pcinode); node;
- node = prom_getsibling(node)) {
- struct linux_prom_pci_assigned_addresses addrs[6];
- int addrlen = prom_getproperty(node,"assigned-addresses",
+ addrlen = prom_getproperty(node,"assigned-addresses",
X (char*)addrs, sizeof(addrs));
- if (addrlen == -1)
- continue;
+ if (addrlen == -1) {
+ printk("PCIC: no \"assigned-addresses\" for device (%x,%x)\n",
+ dev->device, dev->vendor);
+ return;
+ }
X
- addrlen /= sizeof(struct linux_prom_pci_assigned_addresses);
- for (i = 0; i < addrlen; i++ )
- for (j = 0; j < 6; j++) {
- if (!dev->base_address[j] || !addrs[i].phys_lo)
- continue;
- if (addrs[i].phys_lo == dev->base_address[j]) {
- unsigned long address = dev->base_address[j];
- int length = addrs[i].size_lo;
- char namebuf[128] = { 0, };
- unsigned long mapaddr, addrflags;
-
- prom_getstring(node, "name",
- namebuf, sizeof(namebuf));
-
- /* FIXME:
- * failure in allocation too large space
- */
- if (length > 0x200000) {
+ addrlen /= sizeof(struct linux_prom_pci_assigned_addresses);
+ for (i = 0; i < addrlen; i++ )
+ for (j = 0; j < 6; j++) {
+ if (!dev->base_address[j] || !addrs[i].phys_lo)
+ continue;
+ if (addrs[i].phys_lo == dev->base_address[j]) {
+ unsigned long address = dev->base_address[j];
+ int length = addrs[i].size_lo;
+ char namebuf[128] = { 0, };
+ unsigned long mapaddr, addrflags;
+
+ prom_getstring(node, "name", namebuf, sizeof(namebuf));
+
+ /*
+ * failure in allocation too large space
+ */
+ if (length > 0x200000) {
X length = 0x200000;
X prom_printf("PCIC: map window for device '%s' "
X "reduced to 2MB !\n", namebuf);
- }
+ }
X
- /*
- * Be careful with MEM/IO address flags
- */
- if ((address & PCI_BASE_ADDRESS_SPACE) ==
+ /*
+ * Be careful with MEM/IO address flags
+ */
+ if ((address & PCI_BASE_ADDRESS_SPACE) ==
X PCI_BASE_ADDRESS_SPACE_IO) {
X mapaddr = address & PCI_BASE_ADDRESS_IO_MASK;
- } else {
+ } else {
X mapaddr = address & PCI_BASE_ADDRESS_MEM_MASK;
- }
- addrflags = address ^ mapaddr;
+ }
+ addrflags = address ^ mapaddr;
X
- dev->base_address[j] =
+ dev->base_address[j] =
X (unsigned long)sparc_alloc_io(address, 0,
X length,
X namebuf, 0, 0);
- if ( dev->base_address[j] == 0 )
+ if ( dev->base_address[j] == 0 )
X panic("PCIC: failed make mapping for "
X "pci device '%s' with address %lx\n",
X namebuf, address);
X
- dev->base_address[j] ^= addrflags;
- return;
- }
+ dev->base_address[j] ^= addrflags;
+ return;
X }
+ }
+
+ printk("PCIC: unable to match addresses for device (%x,%x)\n",
+ dev->device, dev->vendor);
+}
+
+static void pcic_fill_irq(struct pci_dev *dev, int node) {
+ struct pcic_ca2irq *p;
+ int i, ivec;
+ char namebuf[64]; /* P3 remove */
+
+ if (node == -1) {
+ strcpy(namebuf, "???");
+ } else {
+ prom_getstring(node, "name", namebuf, sizeof(namebuf)); /* P3 remove */
X }
X
- panic("PCIC: unable to locate prom node for pci device (%x,%x) \n",
- dev->device, dev->vendor);
+ if ((p = pcic->pcic_imap) == 0) {
+ dev->irq = 0;
+ return;
+ }
+ for (i = 0; i < pcic->pcic_imdim; i++) {
+ if (p->busno == dev->bus->number && p->devfn == dev->devfn)
+ break;
+ p++;
+ }
+ if (i >= pcic->pcic_imdim) {
+ printk("PCIC: device %s devfn %02x:%02x not found in %d\n",
+ namebuf, dev->bus->number, dev->devfn, pcic->pcic_imdim);
+ dev->irq = 0;
+ return;
+ }
+
+ i = p->pin;
+ if (i >= 0 && i < 4) {
+ ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_LO);
+ dev->irq = ivec >> (i << 2) & 0xF;
+ } else if (i >= 4 && i < 8) {
+ ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI);
+ dev->irq = ivec >> ((i-4) << 2) & 0xF;
+ } else { /* Corrupted map */
+ printk("PCIC: BAD PIN %d\n", i); for (;;) {}
+ }
+/* P3 remove later */ printk("PCIC: device %s pin %d ivec 0x%x irq %x\n", namebuf, i, ivec, dev->irq);
+
+ /*
+ * dev->irq=0 means PROM did not bothered to program the upper
+ * half of PCIC. This happens on JS-E with PROM 3.11, for instance.
+ */
+ if (dev->irq == 0 || p->force) {
+ if (p->irq == 0 || p->irq >= 15) { /* Corrupted map */
+ printk("PCIC: BAD IRQ %d\n", p->irq); for (;;) {}
+ }
+ printk("PCIC: setting irq %x for device (%x,%x)\n",
+ p->irq, dev->device, dev->vendor);
+ dev->irq = p->irq;
+
+ ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI);
+ ivec &= ~(0xF << ((p->pin - 4) << 2));
+ ivec |= p->irq << ((p->pin - 4) << 2);
+ writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_HI);
+ }
+
+ return;
X }
X
X /*
@@ -317,9 +495,10 @@
X writeb((pcic->pcic_io_phys>>24) & PCI_SIBAR_ADDRESS_MASK,
X pcic->pcic_regs+PCI_SIBAR);
X writeb(PCI_ISIZE_16M, pcic->pcic_regs+PCI_ISIZE);
+
X }
X if(paddr < pcic->pcic_mapped_io ||
- paddr > pcic->pcic_mapped_io + PCI_SPACE_SIZE)
+ paddr >= pcic->pcic_mapped_io + 0x10000)
X return 0;
X offset = paddr - pcic->pcic_mapped_io;
X *addr = pcic->pcic_io_phys + offset;
@@ -334,6 +513,9 @@
X struct pci_dev *dev;
X int i, has_io, has_mem;
X unsigned short cmd;
+ struct linux_pbm_info* pbm = &pcic->pbm;
+ int node;
+ struct pcidev_cookie *pcp;
X
X if(pcic == NULL) {
X prom_printf("PCI: Error, PCIC not found.\n");
@@ -359,47 +541,61 @@
X }
X pci_read_config_word(dev, PCI_COMMAND, &cmd);
X if (has_io && !(cmd & PCI_COMMAND_IO)) {
- printk("PCI: Enabling I/O for device %02x:%02x\n",
+ printk("PCIC: Enabling I/O for device %02x:%02x\n",
X dev->bus->number, dev->devfn);
X cmd |= PCI_COMMAND_IO;
X pci_write_config_word(dev, PCI_COMMAND, cmd);
X }
X if (has_mem && !(cmd & PCI_COMMAND_MEMORY)) {
- printk("PCI: Enabling memory for device %02x:%02x\n",
+ printk("PCIC: Enabling memory for device %02x:%02x\n",
X dev->bus->number, dev->devfn);
X cmd |= PCI_COMMAND_MEMORY;
X pci_write_config_word(dev, PCI_COMMAND, cmd);
X }
X
+ node = pdev_to_pnode(pbm, dev);
+ if(node == 0)
+ node = -1;
+
X /* cookies */
- {
- struct pcidev_cookie *pcp;
- struct linux_pbm_info* pbm = &pcic->pbm;
- int node = pdev_to_pnode(pbm, dev);
-
- if(node == 0)
- node = -1;
- pcp = pci_devcookie_alloc();
- pcp->pbm = pbm;
- pcp->prom_node = node;
- dev->sysdata = pcp;
- }
+ pcp = pci_devcookie_alloc();
+ pcp->pbm = pbm;
+ pcp->prom_node = node;
+ dev->sysdata = pcp;
X
X /* memory mapping */
- if (!(dev->vendor == PCI_VENDOR_ID_SUN &&
- dev->device == PCI_DEVICE_ID_SUN_EBUS)) {
- pcic_map_pci_device(dev);
- }
+ if ((dev->class>>16) != PCI_BASE_CLASS_BRIDGE)
+ pcic_map_pci_device(dev, node);
X
- /* irq */
-#define SETIRQ(vend,devid,irqn) \
- if (dev->vendor==vend && dev->device==devid) dev->irq = irqn;
-
- SETIRQ(PCI_VENDOR_ID_SUN,PCI_DEVICE_ID_SUN_HAPPYMEAL,3);
+ pcic_fill_irq(dev, node);
X }
+
X ebus_init();
X }
X
+/*
+ * pcic_pin_to_irq() is exported to ebus.c.
+ */
+unsigned int
+pcic_pin_to_irq(unsigned int pin, char *name)
+{
+ unsigned int irq;
+ unsigned int ivec;
+
+ if (pin < 4) {
+ ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_LO);
+ irq = ivec >> (pin << 2) & 0xF;
+ } else if (pin < 8) {
+ ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI);
+ irq = ivec >> ((pin-4) << 2) & 0xF;
+ } else { /* Corrupted map */
+ printk("PCIC: BAD PIN %d FOR %s\n", pin, name);
+ for (;;) {} /* XXX Cannot panic properly in case of PROLL */
+ }
+/* P3 remove later */ printk("PCIC: dev %s pin %d ivec 0x%x irq %x\n", name, pin, ivec, irq);
+ return irq;
+}
+
X /* Makes compiler happy */
X static volatile int pcic_timer_dummy;
X
@@ -539,26 +735,38 @@
X unsigned char where, unsigned int *value)
X {
X unsigned long flags;
- if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;
- if (bus != 0 ||
- (device_fn != 0 && device_fn != 1 && device_fn != 0x80)) {
- *value = 0xffffffff;
- return PCIBIOS_SUCCESSFUL;
- }
X
- /* FIXME: IGA haven't got high config memory addresses !!! */
- if (device_fn == 0x80 && where > PCI_INTERRUPT_LINE) {
- *value = 0xffffffff;
- return PCIBIOS_SUCCESSFUL;
- }
+ if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;
X
X save_and_cli(flags);
+#if 0
+ pcic_speculative = 1;
+ pcic_trapped = 0;
+#endif
X writel(CONFIG_CMD(bus,device_fn,where), pcic->pcic_config_space_addr);
+#if 0
+ nop();
+ if (pcic_trapped) {
+ restore_flags(flags);
+ *value = ~0;
+ return PCIBIOS_SUCCESSFUL;
+ }
+#endif
+ pcic_speculative = 2;
+ pcic_trapped = 0;
X *value = readl(pcic->pcic_config_space_data + (where&4));
+ nop();
+ if (pcic_trapped) {
+ pcic_speculative = 0;
+ restore_flags(flags);
+ *value = ~0;
+ return PCIBIOS_SUCCESSFUL;
+ }
+ pcic_speculative = 0;
X restore_flags(flags);
X return PCIBIOS_SUCCESSFUL;
X }
-
+
X int pcibios_write_config_byte (unsigned char bus, unsigned char devfn,
X unsigned char where, unsigned char value)
X {
@@ -586,8 +794,8 @@
X unsigned char where, unsigned int value)
X {
X unsigned long flags;
- if ((where&3) || bus != 0 || (devfn != 0 && devfn != 1 && devfn != 0x80))
- return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;
X
X save_and_cli(flags);
X writel(CONFIG_CMD(bus,devfn,where),pcic->pcic_config_space_addr);
@@ -599,6 +807,29 @@
X __initfunc(char *pcibios_setup(char *str))
X {
X return str;
+}
+
+/*
+ * NMI
+ */
+void pcic_nmi(unsigned int pend, struct pt_regs *regs)
+{
+
+ pend = flip_dword(pend);
+
+ if (!pcic_speculative || (pend & PCI_SYS_INT_PENDING_PIO) == 0) {
+ /*
+ * XXX On CP-1200 PCI #SERR may happen, we do not know
+ * what to do about it yet.
+ */
+ printk("Aiee, NMI pend 0x%x pc 0x%x spec %d, hanging\n",
+ pend, (int)regs->pc, pcic_speculative);
+ for (;;) { }
+ }
+ pcic_speculative = 0;
+ pcic_trapped = 1;
+ regs->pc = regs->npc;
+ regs->npc += 4;
X }
X
X /*
diff -u --recursive --new-file v2.3.5/linux/arch/sparc/kernel/ptrace.c linux/arch/sparc/kernel/ptrace.c
--- v2.3.5/linux/arch/sparc/kernel/ptrace.c Mon May 31 22:28:04 1999
+++ linux/arch/sparc/kernel/ptrace.c Mon Jun 7 11:15:33 1999
@@ -134,26 +134,6 @@


X flush_tlb_page(vma, addr);
X }
X
-static struct vm_area_struct * find_extend_vma(struct task_struct * tsk,

- unsigned long addr)


-{
- struct vm_area_struct * vma;
-
- addr &= PAGE_MASK;
- vma = find_vma(tsk->mm,addr);
- if (!vma)
- return NULL;
- if (vma->vm_start <= addr)
- return vma;
- if (!(vma->vm_flags & VM_GROWSDOWN))
- return NULL;
- if (vma->vm_end - addr > tsk->rlim[RLIMIT_STACK].rlim_cur)
- return NULL;
- vma->vm_offset -= vma->vm_start - addr;
- vma->vm_start = addr;
- return vma;
-}
-
X /*
X * This routine checks the page boundaries, and that the offset is
X * within the task area. It then calls get_long() to read a long.

diff -u --recursive --new-file v2.3.5/linux/arch/sparc/kernel/setup.c linux/arch/sparc/kernel/setup.c
--- v2.3.5/linux/arch/sparc/kernel/setup.c Mon May 31 22:28:04 1999
+++ linux/arch/sparc/kernel/setup.c Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.106 1999/05/28 16:03:18 anton Exp $
+/* $Id: setup.c,v 1.107 1999/06/03 15:02:20 davem Exp $
X * linux/arch/sparc/kernel/setup.c
X *
X * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -313,6 +313,7 @@
X if(!strcmp(&cputypval,"sun4 ")) { sparc_cpu_model=sun4; }
X if(!strcmp(&cputypval,"sun4c")) { sparc_cpu_model=sun4c; }
X if(!strcmp(&cputypval,"sun4m")) { sparc_cpu_model=sun4m; }
+ if(!strcmp(&cputypval,"sun4s")) { sparc_cpu_model=sun4m; } /* CP-1200 with PROM 2.30 -E */
X if(!strcmp(&cputypval,"sun4d")) { sparc_cpu_model=sun4d; }
X if(!strcmp(&cputypval,"sun4e")) { sparc_cpu_model=sun4e; }
X if(!strcmp(&cputypval,"sun4u")) { sparc_cpu_model=sun4u; }
diff -u --recursive --new-file v2.3.5/linux/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c
--- v2.3.5/linux/arch/sparc/kernel/sys_sunos.c Mon May 31 22:28:04 1999
+++ linux/arch/sparc/kernel/sys_sunos.c Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.97 1999/05/24 19:40:39 davem Exp $
+/* $Id: sys_sunos.c,v 1.98 1999/06/09 08:23:39 davem Exp $
X * sys_sunos.c: SunOS specific syscall compatibility support.
X *
X * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -150,7 +150,6 @@
X unsigned long newbrk, oldbrk;
X
X down(&current->mm->mmap_sem);
- lock_kernel();
X if(ARCH_SUN4C_SUN4) {
X if(brk >= 0x20000000 && brk < 0xe0000000) {
X goto out;
@@ -210,12 +209,9 @@
X * Ok, we have probably got enough memory - let it rip.
X */
X current->mm->brk = brk;


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

+ do_brk(oldbrk, newbrk-oldbrk)
X retval = 0;
X out:
- unlock_kernel();
X up(&current->mm->mmap_sem);
X return retval;
X }
diff -u --recursive --new-file v2.3.5/linux/arch/sparc64/Makefile linux/arch/sparc64/Makefile
--- v2.3.5/linux/arch/sparc64/Makefile Wed Mar 10 16:53:36 1999
+++ linux/arch/sparc64/Makefile Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.35 1999/01/02 16:45:50 davem Exp $
+# $Id: Makefile,v 1.37 1999/06/04 13:29:10 jj Exp $
X # sparc64/Makefile
X #
X # Makefile for the architecture dependent flags and dependencies on the
@@ -15,7 +15,7 @@
X CC := sparc64-linux-gcc -D__KERNEL__ -I$(TOPDIR)/include
X
X CC_HAS_ARGS := $(shell if echo "$(CC)" | grep '\(__KERNEL__\| \)' > /dev/null; then echo y; else echo n; fi)
-IS_EGCS := $(shell if $(CC) --version 2>&1 | grep 'egcs' > /dev/null; then echo y; else echo n; fi)
+IS_EGCS := $(shell if $(CC) -c -m64 -mcmodel=medlow -o _tmp.o arch/sparc64/math-emu/fnegq.c >/dev/null 2>&1; then echo y; else echo n; fi; rm -f _tmp.o)
X NEW_GAS := $(shell if $(LD) --version 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
X
X ifneq ($(CC_HAS_ARGS),y)
diff -u --recursive --new-file v2.3.5/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.3.5/linux/arch/sparc64/defconfig Mon May 31 22:28:04 1999
+++ linux/arch/sparc64/defconfig Wed Jun 9 14:44:25 1999
@@ -69,6 +69,8 @@
X # CONFIG_SUN_BPP is not set
X # CONFIG_SUN_VIDEOPIX is not set
X CONFIG_SUN_AURORA=m
+CONFIG_APM_RTC_IS_GMT=y
+# CONFIG_RTC is not set
X
X #
X # Linux/SPARC audio subsystem (EXPERIMENTAL)
diff -u --recursive --new-file v2.3.5/linux/arch/sparc64/kernel/binfmt_aout32.c linux/arch/sparc64/kernel/binfmt_aout32.c
--- v2.3.5/linux/arch/sparc64/kernel/binfmt_aout32.c Mon Mar 22 10:06:36 1999
+++ linux/arch/sparc64/kernel/binfmt_aout32.c Wed Jun 9 14:44:25 1999
@@ -48,9 +48,7 @@


X end = PAGE_ALIGN(end);
X if (end <= start)
X return;
- do_mmap(NULL, start, end - start,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_FIXED | MAP_PRIVATE, 0);
+ do_brk(start, end - start);
X }
X

X /*
@@ -284,24 +282,18 @@
X current->flags &= ~PF_FORKNOEXEC;
X if (N_MAGIC(ex) == NMAGIC) {
X /* Fuck me plenty... */
- error = do_mmap(NULL, N_TXTADDR(ex), ex.a_text,


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

+ error = do_brk(N_TXTADDR(ex), ex.a_text);
X read_exec(bprm->dentry, fd_offset, (char *) N_TXTADDR(ex),
X 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);

+ error = do_brk(N_DATADDR(ex), ex.a_data);
X read_exec(bprm->dentry, fd_offset + ex.a_text, (char *) N_DATADDR(ex),
X ex.a_data, 0);
X goto beyond_if;
X }
X
X 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);

+ do_brk(N_TXTADDR(ex) & PAGE_MASK,
+ ex.a_text+ex.a_data + PAGE_SIZE - 1);
X read_exec(bprm->dentry, fd_offset, (char *) N_TXTADDR(ex),
X ex.a_text+ex.a_data, 0);
X } else {
@@ -316,9 +308,7 @@
X
X if (!file->f_op || !file->f_op->mmap) {
X sys_close(fd);
- do_mmap(NULL, 0, ex.a_text+ex.a_data,


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

+ do_brk(0, ex.a_text+ex.a_data);
X read_exec(bprm->dentry, fd_offset,
X (char *) N_TXTADDR(ex), ex.a_text+ex.a_data, 0);
X goto beyond_if;
@@ -359,11 +349,16 @@
X
X set_brk(current->mm->start_brk, current->mm->brk);
X
- p = setup_arg_pages(p, bprm);
+ retval = setup_arg_pages(bprm);
+ if (retval < 0) {
+ /* Someone check-me: is this error path enough? */
+ send_sig(SIGKILL, current, 0);
+ return retval;
+ }
X
- p = (unsigned long) create_aout32_tables((char *)p, bprm);
- current->mm->start_stack = p;
- start_thread32(regs, ex.a_entry, p);
+ current->mm->start_stack =
+ (unsigned long) create_aout32_tables((char *)bprm->p, bprm);
+ start_thread32(regs, ex.a_entry, current->mm->start_stack);
X if (current->flags & PF_PTRACED)
X send_sig(SIGTRAP, current, 0);
X return 0;
@@ -442,9 +437,7 @@
X len = PAGE_ALIGN(ex.a_text + ex.a_data);
X bss = ex.a_text + ex.a_data + ex.a_bss;
X if (bss > len) {
- error = do_mmap(NULL, start_addr + len, bss - len,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_FIXED, 0);
+ error = do_brk(start_addr + len, bss - len);
X retval = error;
X if (error != start_addr + len)
X goto out_putf;
diff -u --recursive --new-file v2.3.5/linux/arch/sparc64/kernel/ioctl32.c linux/arch/sparc64/kernel/ioctl32.c
--- v2.3.5/linux/arch/sparc64/kernel/ioctl32.c Tue May 11 08:24:31 1999
+++ linux/arch/sparc64/kernel/ioctl32.c Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.62 1999/05/01 09:17:44 davem Exp $
+/* $Id: ioctl32.c,v 1.63 1999/06/09 04:56:14 davem Exp $
X * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
X *
X * Copyright (C) 1997 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
@@ -37,6 +37,7 @@
X #include <linux/fb.h>
X #include <linux/ext2_fs.h>
X #include <linux/videodev.h>
+#include <linux/netdevice.h>
X
X #include <scsi/scsi.h>
X /* Ugly hack. */
@@ -417,6 +418,23 @@
X __kernel_caddr_t32 ifcbuf;
X };
X
+static int dev_ifname32(unsigned int fd, unsigned long arg)
+{
+ struct device *dev;
+ struct ifreq32 ifr32;
+ int err;
+
+ if (copy_from_user(&ifr32, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+ return -EFAULT;
+
+ dev = dev_get_by_index(ifr32.ifr_ifindex);
+ if (!dev)
+ return -ENODEV;
+
+ err = copy_to_user((struct ifreq32 *)arg, &ifr32, sizeof(struct ifreq32));
+ return (err ? -EFAULT : 0);
+}
+
X static inline int dev_ifconf(unsigned int fd, unsigned long arg)
X {
X struct ifconf32 ifc32;
@@ -1687,6 +1705,10 @@
X goto out;
X }
X switch (cmd) {
+ case SIOCGIFNAME:
+ error = dev_ifname32(fd, arg);
+ goto out;
+
X case SIOCGIFCONF:
X error = dev_ifconf(fd, arg);
X goto out;
diff -u --recursive --new-file v2.3.5/linux/arch/sparc64/kernel/ptrace.c linux/arch/sparc64/kernel/ptrace.c
--- v2.3.5/linux/arch/sparc64/kernel/ptrace.c Mon May 31 22:28:04 1999
+++ linux/arch/sparc64/kernel/ptrace.c Mon Jun 7 11:15:33 1999
@@ -204,26 +204,6 @@


X flush_tlb_page(vma, addr);
X }
X
-static struct vm_area_struct * find_extend_vma(struct task_struct * tsk,

- unsigned long addr)


-{
- struct vm_area_struct * vma;
-
- addr &= PAGE_MASK;
- vma = find_vma(tsk->mm,addr);
- if (!vma)
- return NULL;
- if (vma->vm_start <= addr)
- return vma;
- if (!(vma->vm_flags & VM_GROWSDOWN))
- return NULL;
- if (vma->vm_end - addr > tsk->rlim[RLIMIT_STACK].rlim_cur)
- return NULL;
- vma->vm_offset -= vma->vm_start - addr;
- vma->vm_start = addr;
- return vma;
-}
-
X /*
X * This routine checks the page boundaries, and that the offset is
X * within the task area. It then calls get_long() to read a long.

diff -u --recursive --new-file v2.3.5/linux/arch/sparc64/kernel/signal.c linux/arch/sparc64/kernel/signal.c
--- v2.3.5/linux/arch/sparc64/kernel/signal.c Tue Oct 27 09:52:20 1998
+++ linux/arch/sparc64/kernel/signal.c Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.38 1998/10/16 03:19:04 davem Exp $
+/* $Id: signal.c,v 1.40 1999/06/02 19:19:52 jj Exp $
X * arch/sparc64/kernel/signal.c
X *
X * Copyright (C) 1991, 1992 Linus Torvalds
@@ -491,7 +491,7 @@
X /* Checks if the fp is valid */
X static int invalid_frame_pointer(void *fp, int fplen)
X {
- if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x80000000000ULL - fplen)
+ if (((unsigned long) fp) & 7)
X return 1;
X return 0;
X }
@@ -554,8 +554,10 @@
X goto sigill;
X
X if (current->tss.w_saved != 0) {
+#ifdef DEBUG_SIGNALS
X printk ("%s[%d]: Invalid user stack frame for "
X "signal delivery.\n", current->comm, current->pid);
+#endif
X goto sigill;
X }
X
@@ -590,35 +592,7 @@
X regs->tnpc = (regs->tpc + 4);
X
X /* 4. return to kernel instructions */
- if (ka->ka_restorer)
- regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
- else {
- /* Flush instruction space. */
- unsigned long address = ((unsigned long)&(sf->insns[0]));
- pgd_t *pgdp = pgd_offset(current->mm, address);
- pmd_t *pmdp = pmd_offset(pgdp, address);
- pte_t *ptep = pte_offset(pmdp, address);
-
- regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
-
- /* mov __NR_sigreturn, %g1 */
- err |= __put_user(0x821020d8, &sf->insns[0]);
-
- /* t 0x6d */
- err |= __put_user(0x91d0206d, &sf->insns[1]);
- if (err)
- goto sigsegv;
-
- if(pte_present(*ptep)) {
- unsigned long page = pte_page(*ptep);
-
- __asm__ __volatile__("
- membar #StoreStore
- flush %0 + %1"
- : : "r" (page), "r" (address & (PAGE_SIZE - 1))
- : "memory");
- }
- }
+ regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
X return;
X
X sigill:
@@ -650,8 +624,10 @@
X goto sigill;
X
X if (current->tss.w_saved != 0) {
+#ifdef DEBUG_SIGNALS
X printk ("%s[%d]: Invalid user stack frame for "
X "signal delivery.\n", current->comm, current->pid);
+#endif
X goto sigill;
X }
X
@@ -690,35 +666,7 @@
X regs->tnpc = (regs->tpc + 4);
X
X /* 4. return to kernel instructions */
- if (ka->ka_restorer)
- regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
- else {
- /* Flush instruction space. */
- unsigned long address = ((unsigned long)&(sf->insns[0]));
- pgd_t *pgdp = pgd_offset(current->mm, address);
- pmd_t *pmdp = pmd_offset(pgdp, address);
- pte_t *ptep = pte_offset(pmdp, address);
-
- regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
-
- /* mov __NR_rt_sigreturn, %g1 */
- err |= __put_user(0x82102065, &sf->insns[0]);
-
- /* t 0x6d */
- err |= __put_user(0x91d0206d, &sf->insns[1]);
- if (err)
- goto sigsegv;
-
- if(pte_present(*ptep)) {
- unsigned long page = pte_page(*ptep);
-
- __asm__ __volatile__("
- membar #StoreStore
- flush %0 + %1"
- : : "r" (page), "r" (address & (PAGE_SIZE - 1))
- : "memory");
- }
- }
+ regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
X return;
X
X sigill:
diff -u --recursive --new-file v2.3.5/linux/arch/sparc64/kernel/sys_sparc.c linux/arch/sparc64/kernel/sys_sparc.c
--- v2.3.5/linux/arch/sparc64/kernel/sys_sparc.c Wed Mar 10 16:53:37 1999
+++ linux/arch/sparc64/kernel/sys_sparc.c Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.26 1999/01/07 19:07:01 jj Exp $
+/* $Id: sys_sparc.c,v 1.27 1999/06/02 12:06:34 jj Exp $
X * linux/arch/sparc64/kernel/sys_sparc.c
X *
X * This file contains various random system calls that
@@ -325,39 +325,6 @@
X return -EINVAL;
X regs->tstate = (regs->tstate & ~TSTATE_MM) | (model << 14);
X return 0;
-}
-
-asmlinkage int
-sys_sigaction(int sig, const struct old_sigaction *act,
- struct old_sigaction *oact)
-{
- struct k_sigaction new_ka, old_ka;
- int ret;
-
- if (act) {
- old_sigset_t mask;
- if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
- return -EFAULT;
- __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __get_user(mask, &act->sa_mask);
- siginitset(&new_ka.sa.sa_mask, mask);
- new_ka.ka_restorer = NULL;
- }
-
- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-
- if (!ret && oact) {
- if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
- return -EFAULT;
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
- }
-
- return ret;
X }
X
X asmlinkage int
diff -u --recursive --new-file v2.3.5/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
--- v2.3.5/linux/arch/sparc64/kernel/sys_sparc32.c Mon May 17 09:55:21 1999
+++ linux/arch/sparc64/kernel/sys_sparc32.c Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.108 1999/05/16 10:50:32 davem Exp $
+/* $Id: sys_sparc32.c,v 1.109 1999/06/03 07:11:31 davem Exp $
X * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
X *
X * Copyright (C) 1997,1998 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
@@ -2776,42 +2776,46 @@
X * memory to free pages in kernel mem. These are in a format ready
X * to be put directly into the top of new user memory.
X */
-static unsigned long
-copy_strings32(int argc,u32 * argv,unsigned long *page,
- unsigned long p)
+static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
X {
- u32 str;
-
- if (!p) return 0; /* bullet-proofing */
X while (argc-- > 0) {
+ u32 str;
X int len;
X unsigned long pos;
X
- get_user(str, argv+argc);
- if (!str) panic("VFS: argc is wrong");
- len = strlen_user((char *)A(str)); /* includes the '\0' */
- if (p < len) /* this shouldn't happen - 128kB */
- return 0;
- p -= len; pos = p;
+ if (get_user(str, argv + argc) ||
+ !str ||
+ !(len = strlen_user((char *)A(str))))
+ return -EFAULT;
+ if (bprm->p < len)
+ return -E2BIG;
+
+ bprm->p -= len;
+
+ pos = bprm->p;
X while (len) {
X char *pag;
X int offset, bytes_to_copy;
X
X offset = pos % PAGE_SIZE;
- if (!(pag = (char *) page[pos/PAGE_SIZE]) &&
- !(pag = (char *) page[pos/PAGE_SIZE] =
+ if (!(pag = (char *) bprm->page[pos/PAGE_SIZE]) &&
+ !(pag = (char *) bprm->page[pos/PAGE_SIZE] =
X (unsigned long *) get_free_page(GFP_USER)))
- return 0;
+ return -ENOMEM;
+
X bytes_to_copy = PAGE_SIZE - offset;
X if (bytes_to_copy > len)
X bytes_to_copy = len;
- copy_from_user(pag + offset, (char *)A(str), bytes_to_copy);
+
+ if (copy_from_user(pag + offset, (char *)A(str), bytes_to_copy))
+ return -EFAULT;
+
X pos += bytes_to_copy;
X str += bytes_to_copy;
X len -= bytes_to_copy;
X }
X }
- return p;
+ return 0;
X }
X
X /*
@@ -2850,29 +2854,36 @@
X }
X
X retval = prepare_binprm(&bprm);
+ if (retval < 0)
+ goto out;
X
- if(retval>=0) {
- bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
- bprm.exec = bprm.p;
- bprm.p = copy_strings32(bprm.envc,envp,bprm.page,bprm.p);
- bprm.p = copy_strings32(bprm.argc,argv,bprm.page,bprm.p);
- if (!bprm.p)
- retval = -E2BIG;
- }
+ retval = copy_strings_kernel(1, &bprm.filename, &bprm);
+ if (retval < 0)
+ goto out;
+
+ bprm.exec = bprm.p;
+ retval = copy_strings32(bprm.envc, envp, &bprm);
+ if (retval < 0)
+ goto out;
X
- if(retval>=0)
- retval = search_binary_handler(&bprm,regs);
- if(retval>=0)
+ retval = copy_strings32(bprm.argc, argv, &bprm);
+ if (retval < 0)
+ goto out;
+
+ retval = search_binary_handler(&bprm, regs);
+ if (retval >= 0)
X /* execve success */
X return retval;
X
+out:
X /* Something went wrong, return the inode and free the argument pages*/
- if(bprm.dentry)
+ if (bprm.dentry)
X dput(bprm.dentry);
X
X for (i=0 ; i<MAX_ARG_PAGES ; i++)
X free_page(bprm.page[i]);
- return(retval);
+
+ return retval;
X }
X
X /*
diff -u --recursive --new-file v2.3.5/linux/arch/sparc64/kernel/sys_sunos32.c linux/arch/sparc64/kernel/sys_sunos32.c
--- v2.3.5/linux/arch/sparc64/kernel/sys_sunos32.c Mon May 31 22:28:04 1999
+++ linux/arch/sparc64/kernel/sys_sunos32.c Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos32.c,v 1.25 1999/05/24 19:40:44 davem Exp $
+/* $Id: sys_sunos32.c,v 1.26 1999/06/09 08:23:54 davem Exp $
X * sys_sunos32.c: SunOS binary compatability layer on sparc64.
X *
X * Copyright (C) 1995, 1996, 1997 David S. Miller (da...@caip.rutgers.edu)
@@ -134,7 +134,6 @@
X unsigned long newbrk, oldbrk, brk = (unsigned long) baddr;
X
X down(&current->mm->mmap_sem);
- lock_kernel();
X if (brk < current->mm->end_code)
X goto out;
X newbrk = PAGE_ALIGN(brk);
@@ -175,12 +174,9 @@
X goto out;
X /* Ok, we have probably got enough memory - let it rip. */
X current->mm->brk = brk;


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

+ do_brk(oldbrk, newbrk-oldbrk);
X retval = 0;
X out:
- unlock_kernel();
X up(&current->mm->mmap_sem);
X return retval;
X }
diff -u --recursive --new-file v2.3.5/linux/arch/sparc64/kernel/systbls.S linux/arch/sparc64/kernel/systbls.S
--- v2.3.5/linux/arch/sparc64/kernel/systbls.S Thu Apr 22 19:24:51 1999
+++ linux/arch/sparc64/kernel/systbls.S Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.53 1999/04/07 17:14:11 davem Exp $
+/* $Id: systbls.S,v 1.54 1999/06/02 12:06:31 jj Exp $
X * systbls.S: System call entry point tables for OS compatibility.
X * The native Linux system call table lives here also.
X *
@@ -115,7 +115,7 @@
X /*180*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_sigpending, sys_query_module
X .word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_newuname
X /*190*/ .word sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
- .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_sigaction, sys_sgetmask
+ .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
X /*200*/ .word sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, sys_nis_syscall
X .word sys_nis_syscall, sys_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall
X /*210*/ .word sys_idle, sys_nis_syscall, sys_waitpid, sys_swapoff, sys_sysinfo
diff -u --recursive --new-file v2.3.5/linux/arch/sparc64/kernel/traps.c linux/arch/sparc64/kernel/traps.c
--- v2.3.5/linux/arch/sparc64/kernel/traps.c Mon May 31 22:28:04 1999
+++ linux/arch/sparc64/kernel/traps.c Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.59 1999/05/18 16:57:10 jj Exp $
+/* $Id: traps.c,v 1.60 1999/06/02 19:19:55 jj Exp $
X * arch/sparc64/kernel/traps.c
X *
X * Copyright (C) 1995,1997 David S. Miller (da...@caip.rutgers.edu)
@@ -282,11 +282,16 @@
X unsigned long sfsr, unsigned long sfar)
X {
X lock_kernel();
+ if (regs->tstate & TSTATE_PRIV) {
X #if 1
- printk("instruction_access_exception: Shit SFSR[%016lx] SFAR[%016lx], going.\n",
- sfsr, sfar);
+ printk("instruction_access_exception: Shit SFSR[%016lx] SFAR[%016lx], going.\n",
+ sfsr, sfar);
X #endif
- die_if_kernel("Iax", regs);
+ die_if_kernel("Iax", regs);
+ }
+ current->tss.sig_desc = SUBSIG_ILLINST;
+ current->tss.sig_address = regs->tpc;
+ force_sig(SIGILL, current);
X unlock_kernel();
X }
X
diff -u --recursive --new-file v2.3.5/linux/arch/sparc64/math-emu/sfp-util.h linux/arch/sparc64/math-emu/sfp-util.h
--- v2.3.5/linux/arch/sparc64/math-emu/sfp-util.h Mon May 31 22:28:05 1999
+++ linux/arch/sparc64/math-emu/sfp-util.h Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-/* $Id: sfp-util.h,v 1.1 1999/05/28 13:43:07 jj Exp $
+/* $Id: sfp-util.h,v 1.2 1999/06/07 18:24:15 jj Exp $
X * arch/sparc64/math-emu/sfp-util.h
X *
X * Copyright (C) 1999 Jakub Jelinek (j...@ultra.linux.cz)
@@ -55,7 +55,7 @@
X srlx %7,32,%5
X mulx %3,%5,%3
X mulx %2,%5,%5
- sethi 0x80000000,%2
+ sethi %%hi(0x80000000),%2
X addcc %4,%3,%4
X srlx %4,32,%4
X add %2,%2,%2
diff -u --recursive --new-file v2.3.5/linux/drivers/Makefile linux/drivers/Makefile
--- v2.3.5/linux/drivers/Makefile Mon May 10 10:18:34 1999
+++ linux/drivers/Makefile Wed Jun 2 14:40:22 1999
@@ -53,6 +53,15 @@
X endif
X endif
X
+ifeq ($(CONFIG_I2O),y)
+SUB_DIRS += i2o
+MOD_SUB_DIRS += i2o
+else
+ ifeq ($(CONFIG_I2O),m)
+ MOD_SUB_DIRS += i2o
+ endif
+endif
+
X # If CONFIG_SCSI is set, the core of SCSI support will be added to the kernel,
X # but some of the low-level things may also be modules.
X ifeq ($(CONFIG_SCSI),y)
diff -u --recursive --new-file v2.3.5/linux/drivers/block/cy82c693.c linux/drivers/block/cy82c693.c
--- v2.3.5/linux/drivers/block/cy82c693.c Mon May 31 22:28:05 1999
+++ linux/drivers/block/cy82c693.c Wed Jun 2 22:21:51 1999
@@ -423,7 +423,8 @@
X __initfunc(void ide_init_cy82c693(ide_hwif_t *hwif))
X {
X hwif->chipset = ide_cy82c693;
- hwif->dmaproc = &cy82c693_dmaproc;
+ if (hwif->dma_base)
+ hwif->dmaproc = &cy82c693_dmaproc;
X hwif->tuneproc = &cy82c693_tune_drive;
X
X init_cy82c693_chip(hwif->pci_dev);
diff -u --recursive --new-file v2.3.5/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v2.3.5/linux/drivers/block/floppy.c Mon May 17 09:55:21 1999
+++ linux/drivers/block/floppy.c Wed Jun 9 16:42:58 1999
@@ -1927,8 +1927,6 @@
X
X static void floppy_ready(void)
X {
- unsigned long flags;
-
X CHECK_RESET;
X if (start_motor(floppy_ready)) return;
X if (fdc_dtr()) return;
@@ -1948,7 +1946,7 @@
X if ((raw_cmd->flags & FD_RAW_READ) ||
X (raw_cmd->flags & FD_RAW_WRITE))
X {
- flags=claim_dma_lock();
+ unsigned long flags = claim_dma_lock();
X fd_chose_dma_mode(raw_cmd->kernel_data,
X raw_cmd->length);
X release_dma_lock(flags);
diff -u --recursive --new-file v2.3.5/linux/drivers/block/ide-pmac.c linux/drivers/block/ide-pmac.c
--- v2.3.5/linux/drivers/block/ide-pmac.c Fri May 14 18:55:14 1999


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

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

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.3/patch-2.3.6/part03

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


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.6 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.3.6'
else
echo 'x - continuing with patch-2.3.6'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.6' &&

+++ linux/drivers/block/ide-pmac.c Mon Jun 7 12:12:22 1999
@@ -65,7 +65,6 @@
X ide_ioreg_t ctrl_port,
X int *irq)
X {
- ide_ioreg_t reg = ide_ioreg_t data_port;
X int i, r;
X
X if (data_port == 0)
@@ -76,20 +75,15 @@
X r = check_media_bay_by_base(data_port, MB_CD);
X if (r == -EINVAL)
X return;
-
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hw->io_ports[i] = reg * 0x10;
- reg += 1;
- }
- if (ctrl_port) {
- hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
- } else {
- hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x160;
- }
+
+ for ( i = 0; i < 8 ; ++i )
+ hw->io_ports[i] = data_port + i * 0x10;
+ hw->io_ports[8] = data_port + 0x160;
+
X if (irq != NULL) {
X *irq = 0;
X for (i = 0; i < MAX_HWIFS; ++i) {
- if (base == pmac_ide_regbase[i]) {
+ if (data_port == pmac_ide_regbase[i]) {
X *irq = pmac_ide_irq[i];
X break;
X }
@@ -156,7 +150,7 @@
X np->full_name);
X continue;
X }
-
+
X base = (unsigned long) ioremap(np->addrs[0].address, 0x200);
X
X /* XXX This is bogus. Should be fixed in the registry by checking
diff -u --recursive --new-file v2.3.5/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v2.3.5/linux/drivers/block/ll_rw_blk.c Fri May 14 18:55:14 1999
+++ linux/drivers/block/ll_rw_blk.c Wed Jun 2 22:21:51 1999
@@ -471,6 +471,8 @@
X case IDE3_MAJOR:
X case IDE4_MAJOR:
X case IDE5_MAJOR:
+ case IDE6_MAJOR:
+ case IDE7_MAJOR:
X case ACSI_MAJOR:
X case MFM_ACORN_MAJOR:
X /*
@@ -497,6 +499,7 @@
X case SCSI_DISK6_MAJOR:
X case SCSI_DISK7_MAJOR:
X case SCSI_CDROM_MAJOR:
+ case I2O_MAJOR:
X
X do {
X if (req->sem)
diff -u --recursive --new-file v2.3.5/linux/drivers/block/ns87415.c linux/drivers/block/ns87415.c
--- v2.3.5/linux/drivers/block/ns87415.c Mon May 31 22:28:05 1999
+++ linux/drivers/block/ns87415.c Wed Jun 2 22:21:51 1999
@@ -166,13 +166,15 @@
X #endif
X }
X
- outb(0x60, hwif->dma_base + 2);
+ if (hwif->dma_base)
+ outb(0x60, hwif->dma_base + 2);
X
X if (!using_inta)
X hwif->irq = hwif->channel ? 15 : 14; /* legacy mode */
X else if (!hwif->irq && hwif->mate && hwif->mate->irq)
X hwif->irq = hwif->mate->irq; /* share IRQ with mate */
X
- hwif->dmaproc = &ns87415_dmaproc;
+ if (hwif->dma_base)
+ hwif->dmaproc = &ns87415_dmaproc;
X hwif->selectproc = &ns87415_selectproc;
X }
diff -u --recursive --new-file v2.3.5/linux/drivers/block/piix.c linux/drivers/block/piix.c
--- v2.3.5/linux/drivers/block/piix.c Fri May 14 18:55:14 1999
+++ linux/drivers/block/piix.c Wed Jun 2 22:21:51 1999


@@ -1,5 +1,5 @@
X /*

- * linux/drivers/block/piix.c Version 0.22 March 29, 1999
+ * linux/drivers/block/piix.c Version 0.23 May 29, 1999
X *
X * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
X * Copyright (C) 1998-1999 Andre Hedrick, Author and Maintainer
@@ -13,10 +13,10 @@
X * 41
X * 43
X *
- * | PIO 0 | c0 | 80 | 0 |
- * | PIO 2 | SW2 | d0 | 90 | 4 |
- * | PIO 3 | MW1 | e1 | a1 | 9 |
- * | PIO 4 | MW2 | e3 | a3 | b |
+ * | PIO 0 | c0 | 80 | 0 | piix_tune_drive(drive, 0);
+ * | PIO 2 | SW2 | d0 | 90 | 4 | piix_tune_drive(drive, 2);
+ * | PIO 3 | MW1 | e1 | a1 | 9 | piix_tune_drive(drive, 3);
+ * | PIO 4 | MW2 | e3 | a3 | b | piix_tune_drive(drive, 4);
X *
X * sitre = word40 & 0x4000; primary
X * sitre = word42 & 0x4000; secondary
@@ -58,10 +58,40 @@
X
X #include "ide_modes.h"
X
-#define PIIX_DMA_PROC 0
-#define PIIX_DEBUG_SET_XFER 0
X #define PIIX_DEBUG_DRIVE_INFO 0
X
+extern char *ide_xfer_verbose (byte xfer_rate);
+
+/*
+ *
+ */
+static byte piix_dma_2_pio (byte xfer_rate) {
+ switch(xfer_rate) {
+ case XFER_UDMA_4:
+ case XFER_UDMA_3:
+ case XFER_UDMA_2:
+ case XFER_UDMA_1:
+ case XFER_UDMA_0:
+ case XFER_MW_DMA_2:
+ case XFER_PIO_4:
+ return 4;
+ case XFER_MW_DMA_1:
+ case XFER_PIO_3:
+ return 3;
+ case XFER_SW_DMA_2:
+ case XFER_PIO_2:
+ return 2;
+ case XFER_MW_DMA_0:
+ case XFER_SW_DMA_1:
+ case XFER_SW_DMA_0:
+ case XFER_PIO_1:
+ case XFER_PIO_0:
+ case XFER_PIO_SLOW:
+ default:
+ return 0;
+ }
+}
+
X /*
X * Based on settings done by AMI BIOS
X * (might be usefull if drive is not registered in CMOS for any reason).
@@ -70,19 +100,22 @@


X {
X unsigned long flags;

X u16 master_data;
- byte slave_data, speed;
- int err;
- int is_slave = (&HWIF(drive)->drives[1] == drive);
- int master_port = HWIF(drive)->index ? 0x42 : 0x40;
- int slave_port = 0x44;
- /* ISP RTC */
- byte timings[][2] = { { 0, 0 },
- { 0, 0 },
- { 1, 0 },
- { 2, 1 },
- { 2, 3 }, };
-
+ byte slave_data;
+ int is_slave = (&HWIF(drive)->drives[1] == drive);
+ int master_port = HWIF(drive)->index ? 0x42 : 0x40;
+ int slave_port = 0x44;
+ /* ISP RTC */
+ byte timings[][2] = { { 0, 0 },
+ { 0, 0 },
+ { 1, 0 },
+ { 2, 1 },
+ { 2, 3 }, };
+
+#if 1
+ pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
+#else
X pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+#endif
X pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
X if (is_slave) {
X master_data = master_data | 0x4000;
@@ -107,28 +140,15 @@
X if (is_slave)
X pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data);
X restore_flags(flags);
-
- switch(pio) {
- case 4: speed = XFER_PIO_4;break;
- case 3: speed = XFER_PIO_3;break;
- case 2: speed = XFER_PIO_2;break;
- case 1: speed = XFER_PIO_1;break;
- default:
- speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
- break;
- }
-
- err = ide_wait_cmd(drive, WIN_SETFEATURES, speed, SETFEATURES_XFER, 0, NULL);
X }
X
-extern char *ide_xfer_verbose (byte xfer_rate);
-
X static int piix_config_drive_for_dma(ide_drive_t *drive, int ultra)
X {
X struct hd_driveid *id = drive->id;
X ide_hwif_t *hwif = HWIF(drive);
X struct pci_dev *dev = hwif->pci_dev;
X
+ unsigned long flags;
X int sitre;
X short reg4042, reg44, reg48, reg4a;
X byte speed;
@@ -144,23 +164,22 @@
X pci_read_config_word(dev, 0x48, &reg48);
X pci_read_config_word(dev, 0x4a, &reg4a);
X
-#if PIIX_DEBUG_SET_XFER
- printk("PIIX%s: DMA enable ",
- (dev->device == PCI_DEVICE_ID_INTEL_82371FB_0) ? "a" :
- (dev->device == PCI_DEVICE_ID_INTEL_82371FB_1) ? "b" :
- (dev->device == PCI_DEVICE_ID_INTEL_82371SB_1) ? "3" :
- (dev->device == PCI_DEVICE_ID_INTEL_82371AB) ? "4" : " UNKNOWN" );
-#endif /* PIIX_DEBUG_SET_XFER */


+ save_flags(flags);
+ cli();
X

X if (id->dma_ultra && (ultra)) {
X if (!(reg48 & u_flag)) {
X pci_write_config_word(dev, 0x48, reg48|u_flag);
X }
X } else {
- pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
+ if (reg48 & u_flag) {
+ pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
+ }
X }
X
X if ((id->dma_ultra & 0x0004) && (ultra)) {
+ drive->id->dma_mword &= ~0x0F00;
+ drive->id->dma_1word &= ~0x0F00;
X if (!((id->dma_ultra >> 8) & 4)) {
X drive->id->dma_ultra &= ~0x0F00;
X drive->id->dma_ultra |= 0x0404;
@@ -171,6 +190,8 @@
X }
X speed = XFER_UDMA_2;
X } else if ((id->dma_ultra & 0x0002) && (ultra)) {
+ drive->id->dma_mword &= ~0x0F00;
+ drive->id->dma_1word &= ~0x0F00;
X if (!((id->dma_ultra >> 8) & 2)) {
X drive->id->dma_ultra &= ~0x0F00;
X drive->id->dma_ultra |= 0x0202;
@@ -182,6 +203,8 @@
X }
X speed = XFER_UDMA_1;
X } else if ((id->dma_ultra & 0x0001) && (ultra)) {
+ drive->id->dma_mword &= ~0x0F00;
+ drive->id->dma_1word &= ~0x0F00;
X if (!((id->dma_ultra >> 8) & 1)) {
X drive->id->dma_ultra &= ~0x0F00;
X drive->id->dma_ultra |= 0x0101;
@@ -193,33 +216,46 @@
X }
X speed = XFER_UDMA_0;
X } else if (id->dma_mword & 0x0004) {
- drive->id->dma_ultra &= ~0x0F0F;
- pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
+ if (reg4a & a_speed)
+ pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
+ drive->id->dma_ultra &= ~0x0F00;
+ drive->id->dma_1word &= ~0x0F00;
X if (!((id->dma_mword >> 8) & 4)) {
X drive->id->dma_mword &= ~0x0F00;
X drive->id->dma_mword |= 0x0404;
X }
X speed = XFER_MW_DMA_2;
X } else if (id->dma_mword & 0x0002) {
- drive->id->dma_ultra &= ~0x0F0F;
- pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
+ if (reg4a & a_speed)
+ pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
+ drive->id->dma_ultra &= ~0x0F00;
+ drive->id->dma_1word &= ~0x0F00;
X if (!((id->dma_mword >> 8) & 2)) {
X drive->id->dma_mword &= ~0x0F00;
X drive->id->dma_mword |= 0x0202;
X }
X speed = XFER_MW_DMA_1;
X } else if (id->dma_1word & 0x0004) {
- drive->id->dma_ultra &= ~0x0F0F;
- pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
+ if (reg4a & a_speed)
+ pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
+ drive->id->dma_ultra &= ~0x0F00;
+ drive->id->dma_mword &= ~0x0F00;
X if (!((id->dma_1word >> 8) & 4)) {
X drive->id->dma_1word &= ~0x0F00;
X drive->id->dma_1word |= 0x0404;
X }
X speed = XFER_SW_DMA_2;
X } else {
- return ide_dma_off_quietly;
+#if 0
+ speed = XFER_PIO_0;
+#else
+ speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
+#endif
X }
X
+ restore_flags(flags);
+ piix_tune_drive(drive, piix_dma_2_pio(speed));
+
X (void) ide_wait_cmd(drive, WIN_SETFEATURES, speed, SETFEATURES_XFER, 0, NULL);
X
X #if PIIX_DEBUG_DRIVE_INFO
@@ -241,7 +277,7 @@
X int ultra = (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_INTEL_82371AB) ? 1 : 0;
X switch (func) {
X case ide_dma_check:
- return piix_config_drive_for_dma(drive, ultra);
+ return ide_dmaproc((ide_dma_action_t) piix_config_drive_for_dma(drive, ultra), drive);
X default :
X break;
X }
@@ -252,7 +288,7 @@
X void ide_init_piix (ide_hwif_t *hwif)
X {
X hwif->tuneproc = &piix_tune_drive;
-#if PIIX_DMA_PROC
- hwif->dmaproc = &piix_dmaproc;
-#endif /* PIIX_DMA_PROC */
+ if (hwif->dma_base) {
+ hwif->dmaproc = &piix_dmaproc;
+ }
X }
diff -u --recursive --new-file v2.3.5/linux/drivers/block/rd.c linux/drivers/block/rd.c
--- v2.3.5/linux/drivers/block/rd.c Mon May 17 09:55:21 1999
+++ linux/drivers/block/rd.c Fri Jun 4 01:03:28 1999
@@ -627,7 +627,7 @@
X #ifdef CONFIG_BLK_DEV_INITRD
X __initfunc(void initrd_load(void))
X {
- rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),0,0);
+ rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),rd_image_start,0);
X }
X #endif
X
diff -u --recursive --new-file v2.3.5/linux/drivers/char/adbmouse.c linux/drivers/char/adbmouse.c
--- v2.3.5/linux/drivers/char/adbmouse.c Thu Apr 29 12:53:48 1999
+++ linux/drivers/char/adbmouse.c Mon Jun 7 12:12:22 1999
@@ -248,7 +248,7 @@
X {
X mouse.active = 0;
X mouse.ready = 0;
- mouse.wait = NULL;
+ init_waitqueue_head(&mouse.wait);
X
X #ifdef __powerpc__
X if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
diff -u --recursive --new-file v2.3.5/linux/drivers/char/bttv.c linux/drivers/char/bttv.c
--- v2.3.5/linux/drivers/char/bttv.c Mon May 31 22:28:05 1999
+++ linux/drivers/char/bttv.c Mon Jun 7 16:17:59 1999
@@ -1,3 +1,4 @@
+
X /*
X bttv - Bt848 frame grabber driver
X
@@ -545,6 +546,8 @@
X { 3, 4, 0, 2, 0x01e000, { 2, 0, 1, 1}, {0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 }},
X /* "Leadtek WinView 601", */
X { 3, 1, 0, 2, 0x8300f8, { 2, 3, 1, 1,0}, {0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007}},
+ /* AVEC Intercapture */
+ { 3, 1, 9, 2, 0, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0}},
X };
X #define TVCARDS (sizeof(tvcards)/sizeof(tvcard))
X
@@ -2900,6 +2903,18 @@
X I2CWrite(bus, I2C_TEA6300, TEA6300_SW, 0x01, 1); /* mute off input A */
X }
X
+static void init_tea6320(struct i2c_bus *bus)
+{
+ I2CWrite(bus, I2C_TEA6300, TEA6320_V, 0x28, 1); /* master volume */
+ I2CWrite(bus, I2C_TEA6300, TEA6320_FFL, 0x28, 1); /* volume left 0dB */
+ I2CWrite(bus, I2C_TEA6300, TEA6320_FFR, 0x28, 1); /* volume right 0dB */
+ I2CWrite(bus, I2C_TEA6300, TEA6320_FRL, 0x28, 1); /* volume rear left 0dB */
+ I2CWrite(bus, I2C_TEA6300, TEA6320_FRR, 0x28, 1); /* volume rear right 0dB */
+ I2CWrite(bus, I2C_TEA6300, TEA6320_BA, 0x11, 1); /* bass 0dB */
+ I2CWrite(bus, I2C_TEA6300, TEA6320_TR, 0x11, 1); /* treble 0dB */
+ I2CWrite(bus, I2C_TEA6300, TEA6320_S, TEA6320_S_GMU, 1); /* mute off input A */
+}
+
X static void init_tda8425(struct i2c_bus *bus)
X {
X I2CWrite(bus, I2C_TDA8425, TDA8425_VL, 0xFC, 1); /* volume left 0dB */
@@ -3027,9 +3042,16 @@
X
X if (I2CRead(&(btv->i2c), I2C_TEA6300) >=0)
X {
+ if(btv->type==BTTV_AVEC_INTERCAP)
+ {
+ printk(KERN_INFO "bttv%d: fader chip: TEA6320\n",btv->nr);
+ btv->audio_chip = TEA6320;
+ init_tea6320(&(btv->i2c));
+ } else {
X printk(KERN_INFO "bttv%d: fader chip: TEA6300\n",btv->nr);
X btv->audio_chip = TEA6300;
X init_tea6300(&(btv->i2c));
+ }
X } else
X printk(KERN_INFO "bttv%d: NO fader chip: TEA6300\n",btv->nr);
X
@@ -3073,6 +3095,9 @@
X case BTTV_WINVIEW_601:
X strcpy(btv->video_dev.name,"BT848(Leadtek WinView 601)");
X break;
+ case BTTV_AVEC_INTERCAP:
+ strcpy(btv->video_dev.name,"(AVEC Intercapture)");
+ break;
X }
X printk("%s\n",btv->video_dev.name);
X audio(btv, AUDIO_MUTE);
diff -u --recursive --new-file v2.3.5/linux/drivers/char/bttv.h linux/drivers/char/bttv.h
--- v2.3.5/linux/drivers/char/bttv.h Mon May 31 22:28:05 1999
+++ linux/drivers/char/bttv.h Mon Jun 7 16:17:59 1999
@@ -211,6 +211,7 @@
X #define BTTV_ZOLTRIX 0x0f
X #define BTTV_PIXVIEWPLAYTV 0x10
X #define BTTV_WINVIEW_601 0x11
+#define BTTV_AVEC_INTERCAP 0x12
X
X #define AUDIO_TUNER 0x00
X #define AUDIO_RADIO 0x01
@@ -225,6 +226,7 @@
X #define TDA8425 0x02
X #define TDA9840 0x03
X #define TEA6300 0x04
+#define TEA6320 0x05
X
X #define I2C_TSA5522 0xc2
X #define I2C_TDA9840 0x84
@@ -233,7 +235,7 @@
X #define I2C_HAUPEE 0xa0
X #define I2C_STBEE 0xae
X #define I2C_VHX 0xc0
-#define I2C_TEA6300 0x80
+#define I2C_TEA6300 0x80 /* same as TEA6320 */
X
X #define TDA9840_SW 0x00
X #define TDA9840_LVADJ 0x02
@@ -260,6 +262,22 @@
X #define TEA6300_TR 0x03 /* treble control */
X #define TEA6300_FA 0x04 /* fader control */
X #define TEA6300_SW 0x05 /* mute and source switch */
+
+
+#define TEA6320_V 0x00
+#define TEA6320_FFR 0x01 /* volume front right */
+#define TEA6320_FFL 0x02 /* volume front left */
+#define TEA6320_FRR 0x03 /* volume rear right */
+#define TEA6320_FRL 0x04 /* volume rear left */
+#define TEA6320_BA 0x05 /* bass */
+#define TEA6320_TR 0x06 /* treble */
+#define TEA6320_S 0x07 /* switch register */
+ /* values for those registers: */
+#define TEA6320_S_SA 0x01 /* stereo A input */
+#define TEA6320_S_SB 0x02 /* stereo B */
+#define TEA6320_S_SC 0x04 /* stereo C */
+#define TEA6320_S_GMU 0x80 /* general mute */
+
X
X #define PT2254_L_CHANEL 0x10
X #define PT2254_R_CHANEL 0x08
diff -u --recursive --new-file v2.3.5/linux/drivers/char/misc.c linux/drivers/char/misc.c
--- v2.3.5/linux/drivers/char/misc.c Fri Mar 26 13:57:41 1999
+++ linux/drivers/char/misc.c Wed Jun 9 14:44:25 1999
@@ -76,6 +76,7 @@
X extern void dtlk_init(void);
X extern void pcwatchdog_init(void);
X extern int rtc_init(void);
+extern int rtc_sun_init(void); /* Combines MK48T02 and MK48T08 */
X extern int rtc_DP8570A_init(void);
X extern int rtc_MK48T08_init(void);
X extern int dsp56k_init(void);
@@ -247,7 +248,10 @@
X #ifdef CONFIG_BVME6000
X rtc_DP8570A_init();
X #endif
-#if defined(CONFIG_RTC) || defined(CONFIG_SUN_MOSTEK_RTC)
+#if defined(CONFIG_SUN_MOSTEK_RTC)
+ rtc_sun_init();
+#endif
+#if defined(CONFIG_RTC)
X rtc_init();
X #endif
X #ifdef CONFIG_ATARI_DSP56K
diff -u --recursive --new-file v2.3.5/linux/drivers/char/radio-cadet.c linux/drivers/char/radio-cadet.c
--- v2.3.5/linux/drivers/char/radio-cadet.c Fri May 14 18:55:17 1999
+++ linux/drivers/char/radio-cadet.c Mon Jun 7 16:17:59 1999
@@ -1,7 +1,7 @@
X /* cadet.c - A video4linux driver for the ADS Cadet AM/FM Radio Card
X *
X * by Fred Gleason <fr...@wava.com>
- * Version 0.3.1
+ * Version 0.3.2
X *
X * (Loosely) based on code for the Aztech radio card by
X *
@@ -557,7 +557,7 @@
X return -EINVAL;
X
X request_region(io,2,"cadet");
- printk(KERN_INFO "ADS Cadet Radio Card at %x\n",io);
+ printk(KERN_INFO "ADS Cadet Radio Card at 0x%x\n",io);
X return 0;
X }
X
@@ -570,12 +570,11 @@
X
X for(i=0;i<8;i++) {
X io=iovals[i];
- if(check_region(io,2)) {
- return -1;
- }
- cadet_setfreq(1410);
- if(cadet_getfreq()==1410) {
- return io;
+ if(check_region(io,2)>=0) {
+ cadet_setfreq(1410);
+ if(cadet_getfreq()==1410) {
+ return io;
+ }
X }
X }
X return -1;
diff -u --recursive --new-file v2.3.5/linux/drivers/char/rtc.c linux/drivers/char/rtc.c
--- v2.3.5/linux/drivers/char/rtc.c Fri May 14 18:55:17 1999
+++ linux/drivers/char/rtc.c Wed Jun 9 14:44:25 1999
@@ -32,10 +32,11 @@
X * 1.08 Miquel van Smoorenburg: disallow certain things on the
X * DEC Alpha as the CMOS clock is also used for other things.
X * 1.09 Nikita Schmidt: epoch support and some Alpha cleanup.
+ * 1.09a Pete Zaitcev: Sun SPARC
X *
X */
X
-#define RTC_VERSION "1.09"
+#define RTC_VERSION "1.09a"
X
X #define RTC_IRQ 8 /* Can't see this changing soon. */
X #define RTC_IO_EXTENT 0x10 /* Only really two ports, but... */
@@ -62,6 +63,12 @@
X #include <asm/uaccess.h>
X #include <asm/system.h>
X
+#ifdef __sparc__
+#include <asm/ebus.h>
+
+static unsigned long rtc_port;
+#endif
+
X /*
X * We sponge a minor off of the misc major. No need slurping
X * up another valuable major dev number for this. If you add
@@ -83,12 +90,12 @@
X
X static unsigned int rtc_poll(struct file *file, poll_table *wait);
X
-void get_rtc_time (struct rtc_time *rtc_tm);
-void get_rtc_alm_time (struct rtc_time *alm_tm);
-void rtc_dropped_irq(unsigned long data);
+static void get_rtc_time (struct rtc_time *rtc_tm);
+static void get_rtc_alm_time (struct rtc_time *alm_tm);
+static void rtc_dropped_irq(unsigned long data);
X
-void set_rtc_irq_bit(unsigned char bit);
-void mask_rtc_irq_bit(unsigned char bit);
+static void set_rtc_irq_bit(unsigned char bit);
+static void mask_rtc_irq_bit(unsigned char bit);
X
X static inline unsigned char rtc_is_updating(void);
X
@@ -525,7 +532,42 @@
X unsigned long uip_watchdog;
X char *guess = NULL;
X #endif
+#ifdef __sparc__
+ struct linux_ebus *ebus;
+ struct linux_ebus_device *edev;
+ int rtc_irq;
+#endif
+
X printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION);
+#ifdef __sparc__
+ for_each_ebus(ebus) {
+ for_each_ebusdev(edev, ebus) {
+ if(strcmp(edev->prom_name, "rtc") == 0) {
+ goto found;
+ }
+ }
+ }
+ printk("rtc_init: no PC rtc found\n");
+ return -EIO;
+
+found:
+ rtc_port = edev->base_address[0];
+ rtc_irq = edev->irqs[0];
+ /*
+ * XXX Interrupt pin #7 in Espresso is shared between RTC and
+ * PCI Slot 2 INTA# (and some INTx# in Slot 1). SA_INTERRUPT here
+ * is asking for trouble with add-on boards. Change to SA_SHIRQ.
+ */
+ if(request_irq(rtc_irq, rtc_interrupt, SA_INTERRUPT, "rtc", (void *)&rtc_port)) {
+ /*
+ * Standard way for sparc to print irq's is to use
+ * __irq_itoa(). I think for EBus it's ok to use %d.
+ */
+ printk("rtc: cannot register IRQ %d\n", rtc_irq);
+ return -EIO;
+ }
+ misc_register(&rtc_dev);
+#else
X if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL))
X {
X /* Yeah right, seeing as irq 8 doesn't even hit the bus. */
@@ -535,6 +577,7 @@
X misc_register(&rtc_dev);
X /* Check region? Naaah! Just snarf it up. */
X request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
+#endif /* __sparc__ vs. others */
X #ifdef __alpha__
X rtc_freq = HZ;
X
@@ -588,7 +631,7 @@
X * for something that requires a steady > 1KHz signal anyways.)
X */
X
-void rtc_dropped_irq(unsigned long data)
+static void rtc_dropped_irq(unsigned long data)


X {
X unsigned long flags;

X
@@ -696,7 +739,7 @@
X return uip;
X }
X
-void get_rtc_time(struct rtc_time *rtc_tm)
+static void get_rtc_time(struct rtc_time *rtc_tm)
X {
X
X unsigned long flags, uip_watchdog = jiffies;
@@ -753,7 +796,7 @@
X rtc_tm->tm_mon--;
X }
X
-void get_rtc_alm_time(struct rtc_time *alm_tm)
+static void get_rtc_alm_time(struct rtc_time *alm_tm)


X {
X unsigned long flags;

X unsigned char ctrl;
@@ -803,7 +846,7 @@
X rtc_irq_data = 0;
X }
X
-void set_rtc_irq_bit(unsigned char bit)
+static void set_rtc_irq_bit(unsigned char bit)
X {
X unsigned char val;
X unsigned long flags;
diff -u --recursive --new-file v2.3.5/linux/drivers/char/tuner.c linux/drivers/char/tuner.c
--- v2.3.5/linux/drivers/char/tuner.c Sun Jan 17 18:28:06 1999
+++ linux/drivers/char/tuner.c Mon Jun 7 16:17:59 1999
@@ -84,7 +84,9 @@
X // 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,0xc2,623},
X 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,0xc2,623},
X {"Temic 4036 FY5 NTSC", TEMIC, NTSC,
- 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,0xc2,732},
+ 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,0xc2,732},
+ {"Alps HSBH1", TEMIC, NTSC,
+ 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,0xc2,732},
X };
X
X /* ---------------------------------------------------------------------- */
diff -u --recursive --new-file v2.3.5/linux/drivers/char/tuner.h linux/drivers/char/tuner.h
--- v2.3.5/linux/drivers/char/tuner.h Sun Nov 8 14:36:46 1998
+++ linux/drivers/char/tuner.h Mon Jun 7 16:17:59 1999
@@ -31,6 +31,7 @@
X #define TUNER_TEMIC_NTSC 6
X #define TUNER_TEMIC_PAL_I 7
X #define TUNER_TEMIC_4036FY5_NTSC 8
+#define TUNER_ALPS_TSBH1_NTSC 9
X
X #define NOTUNER 0
X #define PAL 1
diff -u --recursive --new-file v2.3.5/linux/drivers/i2o/Config.in linux/drivers/i2o/Config.in
--- v2.3.5/linux/drivers/i2o/Config.in Wed Dec 31 16:00:00 1969
+++ linux/drivers/i2o/Config.in Wed Jun 2 14:47:42 1999
@@ -0,0 +1,12 @@
+mainmenu_option next_comment
+comment 'I2O device support'
+
+tristate 'I2O support' CONFIG_I2O
+
+dep_tristate 'I2O PCI support' CONFIG_I2O_PCI $CONFIG_I2O
+dep_tristate 'I2O Block OSM' CONFIG_I2O_BLOCK $CONFIG_I2O
+dep_tristate 'I2O LAN OSM' CONFIG_I2O_LAN $CONFIG_I2O
+dep_tristate 'I2O SCSI OSM' CONFIG_I2O_SCSI $CONFIG_I2O
+dep_tristate 'I2O /proc support' CONFIG_I2O_PROC $CONFIG_I2O
+
+endmenu
diff -u --recursive --new-file v2.3.5/linux/drivers/i2o/Makefile linux/drivers/i2o/Makefile
--- v2.3.5/linux/drivers/i2o/Makefile Wed Dec 31 16:00:00 1969
+++ linux/drivers/i2o/Makefile Wed Jun 2 14:40:22 1999
@@ -0,0 +1,75 @@
+#
+# Makefile for the kernel I2O OSM.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now inherited from the
+# parent makefile.
+#
+
+#
+# Note : at this point, these files are compiled on all systems.
+# In the future, some of these should be built conditionally.
+#
+
+SUB_DIRS :=
+MOD_SUB_DIRS := $(SUB_DIRS)
+ALL_SUB_DIRS := $(SUB_DIRS)
+
+
+L_TARGET := i2o.a
+L_OBJS :=
+M_OBJS :=
+
+ifeq ($(CONFIG_I2O_PCI),y)
+L_OBJS += i2o_pci.o
+else
+ ifeq ($(CONFIG_I2O_PCI),m)
+ M_OBJS += i2o_pci.o
+ endif
+endif
+
+ifeq ($(CONFIG_I2O),y)
+LX_OBJS += i2o_core.o i2o_config.o
+else
+ ifeq ($(CONFIG_I2O),m)
+ MX_OBJS += i2o_core.o i2o_config.o
+ endif
+endif
+
+ifeq ($(CONFIG_I2O_BLOCK),y)
+LX_OBJS += i2o_block.o
+else
+ ifeq ($(CONFIG_I2O_BLOCK),m)
+ MX_OBJS += i2o_block.o
+ endif
+endif
+
+ifeq ($(CONFIG_I2O_LAN),y)
+LX_OBJS += i2o_lan.o
+else
+ ifeq ($(CONFIG_I2O_LAN),m)
+ MX_OBJS += i2o_lan.o
+ endif
+endif
+
+ifeq ($(CONFIG_I2O_SCSI),y)
+LX_OBJS += i2o_scsi.o
+else
+ ifeq ($(CONFIG_I2O_SCSI),m)
+ MX_OBJS += i2o_scsi.o
+ endif
+endif
+
+ifeq ($(CONFIG_I2O_PROC),y)
+LX_OBJS += i2o_proc.o
+else
+ ifeq ($(CONFIG_I2O_PROC),m)
+ MX_OBJS += i2o_proc.o
+ endif
+endif
+
+include $(TOPDIR)/Rules.make
+
diff -u --recursive --new-file v2.3.5/linux/drivers/i2o/README linux/drivers/i2o/README
--- v2.3.5/linux/drivers/i2o/README Wed Dec 31 16:00:00 1969
+++ linux/drivers/i2o/README Wed Jun 2 14:40:22 1999
@@ -0,0 +1,78 @@
+
+ Linux I2O Support (c) Copyright 1999 Red Hat Software
+ and others.
+
+ 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.
+
+AUTHORS (so far)
+
+Alan Cox, Building Number Three Ltd.
+ Core code, SCSI and Block OSMs
+
+Steve Ralston, LSI Logic Corp.
+ Debugging SCSI and Block OSM
+
+Deepak Saxena, Intel Corp.
+ /proc interface, bug fixes
+ Ioctl interfaces for control
+
+Philip Rumpf
+ Fixed assorted dumb SMP locking bugs
+
+Juha Sievanen, University Of Helsinki Finland
+ LAN OSM
+ Bug fixes
+ Core code extensions
+
+CREDITS
+
+ This work was made possible by
+
+Red Hat Software
+ Funding for the Building #3 part of the project
+
+Symbios Logic (Now LSI)
+ Host adapters, hints, known to work platforms when I hit
+ compatibility problems
+
+BoxHill Corporation
+ Loan of initial FibreChannel disk array used for development work.
+
+STATUS:
+
+o The core setup works within limits.
+o The scsi layer seems to almost work. I'm still chasing down the hang
+ bug.
+o The block OSM is fairly minimal but does seem to work.
+
+
+TO DO:
+
+General:
+o Support multiple IOP's and tell them about each other
+o Provide hidden address space if asked
+o Long term message flow control
+o PCI IOP's without interrupts are not supported yet
+o Push FAIL handling into the core
+o DDM control interfaces for module load etc
+
+Block:
+o Real error handler
+o Multiple major numbers
+o Read ahead and cache handling stuff. Talk to Ingo and people
+o Power management
+o Finish Media changers
+
+SCSI:
+o Find the right way to associate drives/luns/busses
+
+Net:
+o Port the existing RCPCI work to the frame work or write a new
+ driver. This one is with the Finns
+
+Tape:
+o Anyone seen anything implementing this ?
+
diff -u --recursive --new-file v2.3.5/linux/drivers/i2o/README.ioctl linux/drivers/i2o/README.ioctl
--- v2.3.5/linux/drivers/i2o/README.ioctl Wed Dec 31 16:00:00 1969
+++ linux/drivers/i2o/README.ioctl Wed Jun 2 14:40:22 1999
@@ -0,0 +1,398 @@
+
+Linux I2O User Space Interface
+rev 0.3 - 04/20/99
+
+=============================================================================
+Originally written by Deepak Saxena(deepak...@intel.com)
+Currently maintained by Deepak Saxena(deepak...@intel.com)
+=============================================================================
+
+I. Introduction
+
+The Linux I2O susbsytem provides a set of ioctl() commands than can be
+utilized by user space applications to communicate with IOPs and devices
+on individual IOPs. This document defines the specific ioctl() commands
+that are available to the user and provides examples of their uses.
+
+This document assumes the reader is familiar with or has access to the
+I2O specification as no I2O message parameters are outlined. For information
+on the specification, see http://www.i2osig.org
+
+This document and the I2O user space interface are currently maintained
+by Deepak Saxena. Please send all comments, errata, and bug fixes to
+deepak...@intel.com
+
+II. IOP Access
+
+Access to the I2O subsystem is provided through the device file named
+/dev/i2octl. This file is a character file with major number 10 and minor
+number 166. It can be created through the following command:
+
+ mknod /dev/i2octl c 10 166
+
+III. Determining the IOP Count
+
+ SYNOPSIS
+
+ ioctl(fd, I2OGETIOPS, int *count);
+
+ u8 count[MAX_I2O_CONTROLLERS];
+
+ DESCRIPTION
+
+ This function returns the system's active IOP table. count should
+ point to a buffer containing MAX_I2O_CONTROLLERS entries. Upon
+ returning, each entry will contain a non-zero value if the given
+ IOP unit is active, and NULL if it is inactive or non-existent.
+
+ RETURN VALUE.
+
+ Returns 0 if no errors occur, and -1 otherwise. If an error occurs,
+ errno is set appropriately:
+
+ EIO Unkown error
+
+IV. ExecHrtGet Message
+
+ SYNOPSIS
+
+ ioctl(fd, I2OHRTGET, struct i2o_cmd_hrt *hrt);
+
+ struct i2o_cmd_hrtlct
+ {
+ u32 iop; /* IOP unit number */
+ void *resbuf; /* Buffer for result */
+ u32 *reslen; /* Buffer length in bytes */
+ };
+
+ DESCRIPTION
+
+ This function posts an ExecHrtHet message to the IOP specified by
+ hrt->iop and returns the data in the buffer pointed to by hrt->buf
+ The size of the data written is placed into the memory pointed to
+ by hrt->len.
+
+ RETURNS
+
+ This function returns 0 if no errors occur. If an error occurs, -1
+ is returned and errno is set appropriately:
+
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(hrt->reslen)
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ EIO Unkown error
+
+V. ExecLctNotify Message
+
+ SYNOPSIS
+
+ ioctl(fd, I2OLCTGET, struct i2o_cmd_lct *lct);
+
+ struct i2o_cmd_hrtlct
+ {
+ u32 iop; /* IOP unit number */
+ void *resbuf; /* Buffer for result */
+ u32 *reslen; /* Buffer length in bytes */
+ };
+
+ DESCRIPTION
+
+ This function posts an ExecLctGet message to the IOP specified by
+ lct->iop and returns the data in the buffer pointed to by lct->buf
+ The size of the data written is placed into the memory pointed to
+ by lct->reslen.
+
+ RETURNS
+
+ This function returns 0 if no errors occur. If an error occurs, -1
+ is returned and errno is set appropriately:
+
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(lct->reslen)
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ EIO Unkown error
+
+VI. UtilParamsSet Message
+
+ SYNOPSIS
+
+ ioctl(fd, I2OPARMSET, struct i2o_parm_setget *ops);
+
+ struct i2o_cmd_psetget
+ {
+ u32 iop; /* IOP unit number */
+ u32 tid; /* Target device TID */
+ void *opbuf; /* Operation List buffer */
+ u32 oplen; /* Operation List buffer length in bytes */
+ void *resbuf; /* Result List buffer */
+ u32 *reslen; /* Result List buffer length in bytes */
+ };
+
+ DESCRIPTION
+
+ This function posts a UtilParamsSet message to the device identified
+ by ops->iop and ops->tid. The operation list for the message is
+ sent through the ops->oplen buffer, and the result list is written
+ into the buffer pointed to by ops->oplen. The number of bytes
+ written is placed into *(ops->reslen).
+
+ RETURNS
+
+ The return value is the size in bytes of the data written into
+ ops->resbuf if no errors occur. If an error occurs, -1 is returned
+ and errno is set appropriatly:
+
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(ops->reslen)
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ EIO Unkown error
+
+ A return value of 0 does not mean that the value was actually
+ changed properly on the IOP. The user should check the result
+ list to determine the specific status of the transaction.
+
+VII. UtilParamsGet Message
+
+ SYNOPSIS
+
+ ioctl(fd, I2OPARMGET, struct i2o_parm_setget *ops);
+
+ struct i2o_parm_setget
+ {
+ u32 iop; /* IOP unit number */
+ u32 tid; /* Target device TID */
+ void *opbuf; /* Operation List buffer */
+ u32 oplen; /* Operation List buffer length in bytes */
+ void *resbuf; /* Result List buffer */
+ u32 *reslen; /* Result List buffer length in bytes */
+ };
+
+ DESCRIPTION
+
+ This function posts a UtilParamsGet message to the device identified
+ by ops->iop and ops->tid. The operation list for the message is
+ sent through the ops->oplen buffer, and the result list is written
+ into the buffer pointed to by ops->oplen. The actual size of data
+ written is placed into *(ops->reslen).
+
+ RETURNS
+
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(ops->reslen)
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ EIO Unkown error
+
+ A return value of 0 does not mean that the value was actually
+ properly retreived. The user should check the result list
+ to determine the specific status of the transaction.
+
+VIII. ExecSwDownload Message
+
+ SYNOPSIS
+
+ ioctl(fd, I2OSWDL, struct i2o_sw_xfer *sw);
+
+ struct i2o_sw_xfer
+ {
+ u32 iop; /* IOP unit number */
+ u8 dl_flags; /* DownLoadFlags field */
+ u8 sw_type; /* Software type */
+ u32 sw_id; /* Software ID */
+ void *buf; /* Pointer to software buffer */
+ u32 *swlen; /* Length of software data */
+ u32 *maxfrag; /* Number of fragments */
+ u32 *curfrag; /* Current fragment number */
+ };
+
+ DESCRIPTION
+
+ This function downloads the software pointed to by sw->buf to the
+ iop identified by sw->iop. The DownloadFlags, SwID, and SwType fields
+ of the ExecSwDownload message are filed in with the values of
+ sw->dl_flags, sw->sw_id, and sw->sw_type.
+
+ Once the ioctl() is called and software transfer begins, the
+ user can read the value *(sw->maxfrag) and *(sw->curfrag) to
+ determine the status of the software transfer. As the IOP
+ is very slow when it comes to SW transfers, this can be
+ used by a separate thread to report status to the user. The
+ user _should not_ write to this memory location until the ioctl()
+ has returned.
+
+ RETURNS
+
+ This function returns 0 no errors occur. If an error occurs, -1
+ is returned and errno is set appropriatly:
+
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(ops->reslen)
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ EIO Unkown error
+
+IX. ExecSwUpload Message
+
+ SYNOPSIS
+
+ ioctl(fd, I2OSWUL, struct i2o_sw_xfer *sw);
+
+ struct i2o_sw_xfer
+ {
+ u32 iop; /* IOP unit number */
+ u8 flags; /* Unused */
+ u8 sw_type; /* Software type */
+ u32 sw_id; /* Software ID */
+ void *buf; /* Pointer to software buffer */
+ u32 *swlen; /* Length in bytes of software */
+ u32 *maxfrag; /* Number of fragments */
+ u32 *curfrag; /* Current fragment number */
+ };
+
+ DESCRIPTION
+
+ This function uploads software from the IOP identified by sw->iop
+ and places it in the buffer pointed to by sw->buf. The SwID, SwType
+ and SwSize fields of the ExecSwDownload message are filed in
+ with the values of sw->sw_id, sw->sw_type, sw->swlen, and. The
+ actual size of the module is written into *(sw->buflen).
+
+ Once the ioctl() is called and software transfer begins, the
+ user can read the value *(sw->maxfrag) and *(sw->curfrag) to
+ determine the status of the software transfer. As the IOP
+ is very slow when it comes to SW transfers, this can be
+ used by a separate thread to report status to the user. The
+ user _should not_ write to this memory location until the ioctl()
+ has returned.
+
+ RETURNS
+
+ This function returns 0 if no errors occur. If an error occurs, -1
+ is returned and errno is set appropriatly:
+
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(ops->reslen)
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ EIO Unkown error
+
+X. ExecSwRemove Message
+
+ SYNOPSIS
+
+ ioctl(fd, I2OSWDEL, struct i2o_sw_xfer *sw);
+
+ struct i2o_sw_xfer
+ {
+ u32 iop; /* IOP unit number */
+ u8 flags; /* Unused */
+ u8 sw_type; /* Software type */
+ u32 sw_id; /* Software ID */
+ void *buf; /* Unused */
+ u32 *swlen; /* Length in bytes of software data */
+ u32 *maxfrag; /* Unused */
+ u32 *curfrag; /* Unused */
+ };
+
+ DESCRIPTION
+
+ This function uploads software from the IOP identified by sw->iop
+ and places it in the buffer pointed to by sw->buf. The SwID, SwType
+ and SwSize fields of the ExecSwDownload message are filed in
+ with the values of sw->dl_flags, sw->sw_id, and sw->sw_type. The
+ actual size of the module is written into *(sw->buflen).
+
+ RETURNS
+
+ This function returns 0 if no errors occur. If an error occurs, -1
+ is returned and errno is set appropriatly:
+
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(ops->reslen)
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ EIO Unkown error
+
+X. UtilConfigDialog Message
+
+ SYNOPSIS
+
+ ioctl(fd, I2OHTML, struct i2o_html *htquery);
+
+ struct i2o_html
+ {
+ u32 iop; /* IOP unit number */
+ u32 tid; /* Target device ID */
+ u32 page; /* HTML page */
+ void *resbuf; /* Buffer for reply HTML page */
+ u32 *reslen; /* Length in bytes of reply buffer */
+ void *qbuf; /* Pointer to HTTP query string */
+ u32 qlen; /* Length in bytes of query string buffer */
+ };
+
+ DESCRIPTION
+
+ This function posts an UtilConfigDialog message to the device identified
+ by htquery->iop and htquery->tid. The requested HTML page number is
+ provided by the htquery->page field, and the resultant data is stored
+ in the buffer pointed to by htquery->resbuf. If there is an HTTP query
+ string that is to be sent to the device, it should be sent in the buffer
+ pointed to by htquery->qbuf. If there is no query string, this field
+ should be set to NULL. The actual size of the reply received is written
+ into *(htquery->reslen)
+
+ RETURNS
+
+ This function returns 0 if no error occur. If an error occurs, -1
+ is returned and J errno is set appropriatly:
+
+ ETIMEDOUT Timeout waiting for reply message
+ ENOMEM Kernel memory allocation error
+ ENOBUFS Buffer not large enough. If this occurs, the required
+ buffer length is written into *(ops->reslen)
+ EFAULT Invalid user space pointer was passed
+ ENXIO Invalid IOP number
+ EIO Unkown error
+
+XI. Events
+
+ In the process of determining this. Current idea is to have use
+ the select() interface to allow user apps to periodically poll
+ the /dev/i2octl device for events. When select() notifies the user
+ that an event is available, the user would call read() to retrieve
+ a list of all the events that are pending for the specific device.
+
+=============================================================================
+Revision History
+=============================================================================
+
+Rev 0.1 - 04/01/99
+- Initial revision
+
+Rev 0.2 - 04/06/99
+- Changed return values to match UNIX ioctl() standard. Only return values
+ are 0 and -1. All errors are reported through errno.
+- Added summary of proposed possible event interfaces
+
+Rev 0.3 - 04/20/99
+- Changed all ioctls() to use pointers to user data instead of actual data
+- Updated error values to match the code
+
+
diff -u --recursive --new-file v2.3.5/linux/drivers/i2o/README.lan linux/drivers/i2o/README.lan
--- v2.3.5/linux/drivers/i2o/README.lan Wed Dec 31 16:00:00 1969
+++ linux/drivers/i2o/README.lan Wed Jun 2 14:40:22 1999
@@ -0,0 +1,38 @@
+
+ Linux I2O LAN OSM
+ (c) University of Helsinki, Department of Computer Science
+
+ 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.
+
+AUTHORS
+Auvo Häkkinen, Auvo.H...@cs.Helsinki.FI
+Juha Sievänen, Juha.S...@cs.Helsinki.FI
+
+CREDITS
+
+ This work was made possible by
+
+European Committee
+ Funding for the project
+
+SysKonnect
+ Loaning of FDDI cards
+
+ASUSTeK
+ I2O motherboard
+
+STATUS:
+o The FDDI part of LAN OSM is working to some extent.
+o Only packet per bucket is now supported.
+
+TO DO:
+
+LAN:
+o Add support for bactches
+o Find why big packets flow from I2O box out, but don't want to come in
+o Find the bug in i2o_set_multicast_list(), which kills interrupt
+ handler in i2o_wait_reply()
+o Add support for Ethernet, Token Ring, AnyLAN, Fibre Channel
diff -u --recursive --new-file v2.3.5/linux/drivers/i2o/i2o_block.c linux/drivers/i2o/i2o_block.c
--- v2.3.5/linux/drivers/i2o/i2o_block.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/i2o/i2o_block.c Wed Jun 2 14:40:22 1999
@@ -0,0 +1,1071 @@
+/*
+ * I2O block device driver.
+ *
+ * (C) Copyright 1999 Red Hat Software
+ *
+ * Written by Alan Cox, Building Number Three Ltd


+ *
+ * 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.
+ *

+ * This is an initial test release. Most of the good code was taken
+ * from the nbd driver by Pavel Machek, who in turn took some of it
+ * from loop.c. Isn't free software great for reusability 8)
+ *
+ * Fixes:
+ * Steve Ralston: Multiple device handling error fixes,
+ * Added a queue depth.
+ */
+
+#include <linux/major.h>
+
+#include <linux/module.h>
+
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/file.h>
+#include <linux/ioctl.h>
+#include <linux/i2o.h>
+#include <linux/blkdev.h>
+#include <linux/malloc.h>
+#include <linux/hdreg.h>
+
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+
+#define MAJOR_NR I2O_MAJOR
+
+#include <linux/blk.h>
+
+#define MAX_I2OB 16
+
+#define MAX_I2OB_DEPTH 4
+
+/*
+ * Some of these can be made smaller later
+ */
+
+static int i2ob_blksizes[MAX_I2OB<<4];
+static int i2ob_hardsizes[MAX_I2OB<<4];
+static int i2ob_sizes[MAX_I2OB<<4];
+static int i2ob_media_change_flag[MAX_I2OB];
+static u32 i2ob_max_sectors[MAX_I2OB<<4];
+
+static int i2ob_context;
+
+#ifdef __SMP__
+static spinlock_t i2ob_lock = SPIN_LOCK_UNLOCKED;
+#endif
+
+struct i2ob_device
+{
+ struct i2o_controller *controller;
+ struct i2o_device *i2odev;
+ int tid;
+ int flags;
+ int refcnt;
+ struct request *head, *tail;
+ int done_flag;
+};
+
+/*
+ * Each I2O disk is one of these.
+ */
+
+static struct i2ob_device i2ob_dev[MAX_I2OB<<4];
+static int i2ob_devices = 0;
+static struct hd_struct i2ob[MAX_I2OB<<4];
+static struct gendisk i2ob_gendisk; /* Declared later */
+
+static atomic_t queue_depth; /* For flow control later on */
+
+#define DEBUG( s )
+/* #define DEBUG( s ) printk( s )
+ */
+
+static int i2ob_install_device(struct i2o_controller *, struct i2o_device *, int);
+static void i2ob_end_request(struct request *);
+static void do_i2ob_request(void);
+
+/*
+ * Get a message
+ */
+
+static u32 i2ob_get(struct i2ob_device *dev)
+{
+ struct i2o_controller *c=dev->controller;
+ return I2O_POST_READ32(c);
+}
+
+/*
+ * Turn a Linux block request into an I2O block read/write.
+ */
+
+static int i2ob_send(u32 m, struct i2ob_device *dev, struct request *req, u32 base, int unit)
+{
+ struct i2o_controller *c = dev->controller;
+ int tid = dev->tid;
+ u32 *msg;
+ u32 *mptr;
+ u64 offset;
+ struct buffer_head *bh = req->bh;
+ static int old_qd = 2;
+ int count = req->nr_sectors<<9;
+
+ /*
+ * Build a message
+ */
+
+ msg = bus_to_virt(c->mem_offset + m);
+
+ msg[2] = i2ob_context|(unit<<8);
+ msg[3] = (u32)req; /* 64bit issue again here */
+ msg[5] = req->nr_sectors << 9;
+
+ /* This can be optimised later - just want to be sure its right for
+ starters */
+ offset = ((u64)(req->sector+base)) << 9;
+ msg[6] = offset & 0xFFFFFFFF;
+ msg[7] = (offset>>32);
+ mptr=msg+8;
+
+ if(req->cmd == READ)
+ {
+ msg[1] = I2O_CMD_BLOCK_READ<<24|HOST_TID<<12|tid;
+ /* We don't yet do cache/readahead and other magic */
+ msg[4] = 1<<16;
+ while(bh!=NULL)
+ {
+ *mptr++ = 0x10000000|(bh->b_size);
+ *mptr++ = virt_to_bus(bh->b_data);
+ count -= bh->b_size;
+ bh = bh->b_reqnext;
+ }
+ }
+ else if(req->cmd == WRITE)
+ {
+ msg[1] = I2O_CMD_BLOCK_WRITE<<24|HOST_TID<<12|tid;
+ msg[4] = 1<<16;
+ while(bh!=NULL)
+ {
+ *mptr++ = 0x14000000|(bh->b_size);
+ count -= bh->b_size;
+ *mptr++ = virt_to_bus(bh->b_data);
+ bh = bh->b_reqnext;
+ }
+ }
+ mptr[-2]|= 0xC0000000;
+ msg[0] = I2O_MESSAGE_SIZE(mptr-msg) | SGL_OFFSET_8;
+
+ if(req->current_nr_sectors > 8)
+ printk("Gathered sectors %ld.\n",
+ req->current_nr_sectors);
+
+ if(count != 0)
+ {
+ printk("Request count botched by %d.\n", count);
+ msg[5] -= count;
+ }
+
+// printk("Send for %p\n", req);
+
+ i2o_post_message(c,m);
+ atomic_inc(&queue_depth);
+ if(atomic_read(&queue_depth)>old_qd)
+ {
+ old_qd=atomic_read(&queue_depth);
+ printk("Depth now %d.\n", old_qd);
+ }
+ return 0;
+}
+
+/*
+ * Remove a request from the _locked_ request list. We update both the
+ * list chain and if this is the last item the tail pointer.
+ */
+
+static void i2ob_unhook_request(struct i2ob_device *dev, struct request *req)
+{
+ struct request **p = &dev->head;
+ struct request *nt = NULL;
+ static int crap = 0;
+
+ while(*p!=NULL)
+ {
+ if(*p==req)
+ {
+ if(dev->tail==req)
+ dev->tail = nt;
+ *p=req->next;
+ return;
+ }
+ nt=*p;
+ p=&(nt->next);
+ }
+ if(!crap++)
+ printk("i2o_block: request queue corrupt!\n");
+}
+
+/*
+ * Request completion handler
+ */
+
+static void i2ob_end_request(struct request *req)
+{
+ /*
+ * Loop until all of the buffers that are linked
+ * to this request have been marked updated and
+ * unlocked.
+ */
+ while (end_that_request_first( req, !req->errors, "i2o block" ));
+
+ /*
+ * It is now ok to complete the request.
+ */
+ end_that_request_last( req );
+}
+
+
+/*
+ * OSM reply handler. This gets all the message replies
+ */
+
+static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg)
+{
+ struct request *req;
+ u8 st;
+ u32 *m = (u32 *)msg;
+ u8 unit = (m[2]>>8)&0xF0; /* low 4 bits are partition */
+
+ if(m[0] & (1<<13))
+ {
+ printk("IOP fail.\n");
+ printk("From %d To %d Cmd %d.\n",
+ (m[1]>>12)&0xFFF,
+ m[1]&0xFFF,
+ m[1]>>24);
+ printk("Failure Code %d.\n", m[4]>>24);
+ if(m[4]&(1<<16))
+ printk("Format error.\n");
+ if(m[4]&(1<<17))
+ printk("Path error.\n");
+ if(m[4]&(1<<18))
+ printk("Path State.\n");
+ if(m[4]&(1<<18))
+ printk("Congestion.\n");
+
+ m=(u32 *)bus_to_virt(m[7]);
+ printk("Failing message is %p.\n", m);
+
+ /* We need to up the request failure count here and maybe
+ abort it */
+ req=(struct request *)m[3];
+ /* Now flush the message by making it a NOP */
+ m[0]&=0x00FFFFFF;
+ m[0]|=(I2O_CMD_UTIL_NOP)<<24;
+ i2o_post_message(c,virt_to_bus(m));
+
+ }
+ else
+ {
+ if(m[2]&0x80000000)
+ {
+ int * ptr = (int *)m[3];
+ if(m[4]>>24)
+ *ptr = -1;
+ else
+ *ptr = 1;
+ return;
+ }
+ /*
+ * Lets see what is cooking. We stuffed the
+ * request in the context.
+ */
+
+ req=(struct request *)m[3];
+ st=m[4]>>24;
+
+ if(st!=0)
+ {
+ printk(KERN_ERR "i2ob: error %08X\n", m[4]);
+ /*
+ * Now error out the request block
+ */
+ req->errors++;
+ }
+ }
+ /*
+ * Dequeue the request.
+ */
+
+ spin_lock(&io_request_lock);
+ spin_lock(&i2ob_lock);
+ i2ob_unhook_request(&i2ob_dev[unit], req);
+ i2ob_end_request(req);
+
+ /*
+ * We may be able to do more I/O
+ */
+
+ atomic_dec(&queue_depth);
+ do_i2ob_request();
+ spin_unlock(&i2ob_lock);
+ spin_unlock(&io_request_lock);
+}
+
+static struct i2o_handler i2o_block_handler =
+{
+ i2o_block_reply,
+ "I2O Block OSM",
+ 0
+};
+
+
+/*
+ * Flush all pending requests as errors. Must call with the queue
+ * locked.
+ */
+
+#if 0
+static void i2ob_clear_queue(struct i2ob_device *dev)
+{
+ struct request *req;
+
+ while (1) {
+ req = dev->tail;
+ if (!req)
+ return;
+ req->errors++;
+ i2ob_end_request(req);
+
+ if (dev->tail == dev->head)
+ dev->head = NULL;
+ dev->tail = dev->tail->next;
+ }
+}
+#endif
+
+/*
+ * The I2O block driver is listed as one of those that pulls the
+ * front entry off the queue before processing it. This is important
+ * to remember here. If we drop the io lock then CURRENT will change
+ * on us. We must unlink CURRENT in this routine before we return, if
+ * we use it.
+ */
+
+static void do_i2ob_request(void)
+{
+ struct request *req;
+ int unit;
+ struct i2ob_device *dev;
+ u32 m;
+
+ while (CURRENT) {
+ /*
+ * On an IRQ completion if there is an inactive
+ * request on the queue head it means it isnt yet
+ * ready to dispatch.
+ */
+ if(CURRENT->rq_status == RQ_INACTIVE)
+ return;
+
+ /*
+ * Queue depths probably belong with some kind of
+ * generic IOP commit control. Certainly its not right
+ * its global!
+ */
+ if(atomic_read(&queue_depth)>=MAX_I2OB_DEPTH)
+ break;
+
+ req = CURRENT;
+ unit = MINOR(req->rq_dev);
+ dev = &i2ob_dev[(unit&0xF0)];
+ /* Get a message */
+ m = i2ob_get(dev);
+ /* No messages -> punt
+ FIXME: if we have no messages, and there are no messages
+ we deadlock now. Need a timer/callback ?? */
+ if(m==0xFFFFFFFF)
+ {
+ printk("i2ob: no messages!\n");
+ break;
+ }
+ req->errors = 0;
+ CURRENT = CURRENT->next;
+ req->next = NULL;
+
+ if (dev->head == NULL) {
+ dev->head = req;
+ dev->tail = req;
+ } else {
+ dev->tail->next = req;
+ dev->tail = req;
+ }
+ i2ob_send(m, dev, req, i2ob[unit].start_sect, (unit&0xF0));
+ }
+}
+
+static void i2ob_request(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&i2ob_lock, flags);
+ do_i2ob_request();
+ spin_unlock_irqrestore(&i2ob_lock, flags);
+}
+
+/*
+ * SCSI-CAM for ioctl geometry mapping
+ * Duplicated with SCSI - this should be moved into somewhere common
+ * perhaps genhd ?
+ */
+
+static void i2o_block_biosparam(
+ unsigned long capacity,
+ unsigned short *cyls,
+ unsigned char *hds,
+ unsigned char *secs)
+{
+ unsigned long heads, sectors, cylinders, temp;
+
+ cylinders = 1024L; /* Set number of cylinders to max */
+ sectors = 62L; /* Maximize sectors per track */
+
+ temp = cylinders * sectors; /* Compute divisor for heads */
+ heads = capacity / temp; /* Compute value for number of heads */
+ if (capacity % temp) { /* If no remainder, done! */
+ heads++; /* Else, increment number of heads */
+ temp = cylinders * heads; /* Compute divisor for sectors */
+ sectors = capacity / temp; /* Compute value for sectors per
+ track */
+ if (capacity % temp) { /* If no remainder, done! */
+ sectors++; /* Else, increment number of sectors */
+ temp = heads * sectors; /* Compute divisor for cylinders */
+ cylinders = capacity / temp;/* Compute number of cylinders */
+ }
+ }
+ /* if something went wrong, then apparently we have to return
+ a geometry with more than 1024 cylinders */
+ if (cylinders == 0 || heads > 255 || sectors > 63 || cylinders >1023)
+ {
+ unsigned long temp_cyl;
+
+ heads = 64;
+ sectors = 32;
+ temp_cyl = capacity / (heads * sectors);
+ if (temp_cyl > 1024)
+ {
+ heads = 255;
+ sectors = 63;
+ }
+ cylinders = capacity / (heads * sectors);
+ }
+ *cyls = (unsigned int) cylinders; /* Stuff return values */
+ *secs = (unsigned int) sectors;
+ *hds = (unsigned int) heads;
+}
+
+/*
+ * Rescan the partition tables
+ */
+
+static int do_i2ob_revalidate(kdev_t dev, int maxu)
+{
+ int minor=MINOR(dev);
+ int i;
+
+ minor&=0xF0;
+
+ i2ob_dev[minor].refcnt++;
+ if(i2ob_dev[minor].refcnt>maxu+1)
+ {
+ i2ob_dev[minor].refcnt--;
+ return -EBUSY;
+ }
+
+ for( i = 15; i>=0 ; i--)
+ {
+ int m = minor+i;
+ kdev_t d = MKDEV(MAJOR_NR, m);
+ struct super_block *sb = get_super(d);
+
+ sync_dev(d);
+ if(sb)
+ invalidate_inodes(sb);
+ invalidate_buffers(d);
+ i2ob_gendisk.part[m].start_sect = 0;
+ i2ob_gendisk.part[m].nr_sects = 0;
+ }
+
+ /*
+ * Do a physical check and then reconfigure
+ */
+
+ i2ob_install_device(i2ob_dev[minor].controller, i2ob_dev[minor].i2odev,
+ minor);
+ i2ob_dev[minor].refcnt--;
+ return 0;
+}
+
+/*
+ * Issue device specific ioctl calls.
+ */
+
+static int i2ob_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct i2ob_device *dev;
+ int minor;
+
+ /* Anyone capable of this syscall can do *real bad* things */
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (!inode)
+ return -EINVAL;
+ minor = MINOR(inode->i_rdev);
+ if (minor >= (MAX_I2OB<<4))
+ return -ENODEV;
+
+ dev = &i2ob_dev[minor];
+ switch (cmd) {
+ case BLKRASET:
+ if(!capable(CAP_SYS_ADMIN)) return -EACCES;
+ if(arg > 0xff) return -EINVAL;
+ read_ahead[MAJOR(inode->i_rdev)] = arg;
+ return 0;
+
+ case BLKRAGET:
+ if (!arg) return -EINVAL;
+ return put_user(read_ahead[MAJOR(inode->i_rdev)],
+ (long *) arg);
+ case BLKGETSIZE:
+ return put_user(i2ob[minor].nr_sects, (long *) arg);
+
+ case BLKFLSBUF:
+ if(!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ fsync_dev(inode->i_rdev);
+ invalidate_buffers(inode->i_rdev);
+ return 0;
+
+ case HDIO_GETGEO:
+ {
+ struct hd_geometry g;
+ int u=minor&0xF0;
+ i2o_block_biosparam(i2ob_sizes[u]<<1,
+ &g.cylinders, &g.heads, &g.sectors);
+ g.start = i2ob[minor].start_sect;
+ return copy_to_user((void *)arg,&g, sizeof(g))?-EFAULT:0;
+ }
+
+ case BLKRRPART:
+ if(!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ return do_i2ob_revalidate(inode->i_rdev,1);
+
+ default:
+ return blk_ioctl(inode->i_rdev, cmd, arg);
+ }
+}
+
+/*
+ * Issue UTIL_CLAIM messages
+ */
+
+static int i2ob_claim_device(struct i2ob_device *dev, int onoff)
+{
+ return i2o_issue_claim(dev->controller, dev->tid, i2ob_context, onoff, &dev->done_flag);
+}
+
+/*
+ * Close the block device down
+ */
+
+static int i2ob_release(struct inode *inode, struct file *file)
+{
+ struct i2ob_device *dev;
+ int minor;
+
+ minor = MINOR(inode->i_rdev);
+ if (minor >= (MAX_I2OB<<4))
+ return -ENODEV;
+ sync_dev(inode->i_rdev);
+ dev = &i2ob_dev[(minor&0xF0)];
+ if (dev->refcnt <= 0)
+ printk(KERN_ALERT "i2ob_release: refcount(%d) <= 0\n", dev->refcnt);
+ dev->refcnt--;
+ if(dev->refcnt==0)
+ {
+ /*
+ * Flush the onboard cache on unmount
+ */
+ u32 msg[5];
+ int *query_done = &dev->done_flag;
+ msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|dev->tid;
+ msg[2] = i2ob_context|0x80000000;
+ msg[3] = (u32)query_done;
+ msg[4] = 60<<16;
+ i2o_post_wait(dev->controller, dev->tid, msg, 20, query_done,2);
+ /*
+ * Unlock the media
+ */
+ msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = I2O_CMD_BLOCK_MUNLOCK<<24|HOST_TID<<12|dev->tid;
+ msg[2] = i2ob_context|0x80000000;
+ msg[3] = (u32)query_done;
+ msg[4] = -1;
+ i2o_post_wait(dev->controller, dev->tid, msg, 20, query_done,2);
+
+ /*
+ * Now unclaim the device.
+ */
+ if (i2ob_claim_device(dev, 0)<0)
+ printk(KERN_ERR "i2ob_release: controller rejected unclaim.\n");
+
+ }
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+/*
+ * Open the block device.
+ */
+
+static int i2ob_open(struct inode *inode, struct file *file)
+{
+ int minor;
+ struct i2ob_device *dev;
+
+ if (!inode)
+ return -EINVAL;
+ minor = MINOR(inode->i_rdev);
+ if (minor >= MAX_I2OB<<4)
+ return -ENODEV;
+ dev=&i2ob_dev[(minor&0xF0)];
+
+ if(dev->refcnt++==0)
+ {
+ u32 msg[6];
+ int *query_done;
+
+
+ if(i2ob_claim_device(dev, 1)<0)
+ {
+ dev->refcnt--;
+ return -EBUSY;
+ }
+
+ query_done = &dev->done_flag;
+ /*
+ * Mount the media if needed. Note that we don't use
+ * the lock bit. Since we have to issue a lock if it
+ * refuses a mount (quite possible) then we might as


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

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

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.3/patch-2.3.6/part11

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


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

if test "$Scheck" != 11; 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.3.6'
else
echo 'x - continuing with patch-2.3.6'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.6' &&
+

+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#define _SK_MCA_DRIVER_
+#include "sk_mca.h"
+
+/* ------------------------------------------------------------------------
+ * global static data - not more since we can handle multiple boards and
+ * have to pack all state info into the device struct!
+ * ------------------------------------------------------------------------ */
+
+static char *MediaNames[Media_Count]=
+ {"10Base2", "10BaseT", "10Base5", "Unknown"};
+
+static unsigned char poly[] =
+ {1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0};
+
+/* ------------------------------------------------------------------------
+ * private subfunctions
+ * ------------------------------------------------------------------------ */
+
+/* dump parts of shared memory - only needed during debugging */
+
+#ifdef DEBUG
+static void dumpmem(struct device *dev, u32 start, u32 len)
+{
+ int z;
+
+ for (z = 0; z < len; z++)
+ {
+ if ((z & 15) == 0)
+ printk("%04x:", z);
+ printk(" %02x", readb(dev->mem_start + start + z));
+ if ((z & 15) == 15)
+ printk("\n");
+ }
+}
+
+/* print exact time - ditto */
+
+static void PrTime(void)
+{
+ struct timeval tv;
+
+ do_gettimeofday(&tv);
+ printk("%9d:%06d: ", tv.tv_sec, tv.tv_usec);
+}
+#endif
+
+/* deduce resources out of POS registers */
+
+static void getaddrs(int slot, int junior, int *base, int *irq,
+ skmca_medium *medium)
+{
+ u_char pos0, pos1, pos2;
+
+ if (junior)
+ {
+ pos0 = mca_read_stored_pos(slot, 2);
+ *base = ((pos0 & 0x0e) << 13) + 0xc0000;
+ *irq = ((pos0 & 0x10) >> 4) + 10;
+ *medium = Media_Unknown;
+ }
+ else
+ {
+ /* reset POS 104 Bits 0+1 so the shared memory region goes to the
+ configured area between 640K and 1M. Afterwards, enable the MC2.
+ I really don't know what rode SK to do this... */
+
+ mca_write_pos(slot, 4, mca_read_stored_pos(slot, 4) & 0xfc);
+ mca_write_pos(slot, 2, mca_read_stored_pos(slot, 2) | 0x01);
+
+ pos1 = mca_read_stored_pos(slot, 3);
+ pos2 = mca_read_stored_pos(slot, 4);
+ *base = ((pos1 & 0x07) << 14) + 0xc0000;
+ switch (pos2 & 0x0c)
+ {
+ case 0: *irq = 3; break;
+ case 4: *irq = 5; break;
+ case 8: *irq = 10; break;
+ case 12: *irq = 11; break;
+ }
+ *medium = (pos2 >> 6) & 3;
+ }
+}
+
+/* check for both cards:
+ When the MC2 is turned off, it was configured for more than 15MB RAM,
+ is disabled and won't get detected using the standard probe. We
+ therefore have to scan the slots manually :-( */
+
+static int dofind(int *junior, int firstslot)
+{
+ int slot;
+ unsigned int id;
+
+ for (slot = firstslot; slot < MCA_MAX_SLOT_NR; slot++)
+ {
+ id = mca_read_stored_pos(slot, 0)
+ + (((unsigned int) mca_read_stored_pos(slot, 1)) << 8);
+
+ *junior = 0;
+ if (id == SKNET_MCA_ID)
+ return slot;
+ *junior = 1;
+ if (id == SKNET_JUNIOR_MCA_ID)
+ return slot;
+ }
+ return MCA_NOTFOUND;
+}
+
+/* reset the whole board */
+
+static void ResetBoard(struct device *dev)
+{
+ skmca_priv *priv = (skmca_priv*) dev->priv;
+
+ writeb(CTRL_RESET_ON, priv->ctrladdr);
+ udelay(10);
+ writeb(CTRL_RESET_OFF, priv->ctrladdr);
+}
+
+/* set LANCE register - must be atomic */
+
+static void SetLANCE(struct device *dev, u16 addr, u16 value)
+{
+ skmca_priv *priv = (skmca_priv*) dev->priv;


+ unsigned long flags;
+

+ /* disable interrupts */


+
+ save_flags(flags);
+ cli();

+
+ /* wait until no transfer is pending */
+
+ while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
+
+ /* transfer register address to RAP */
+
+ writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP, priv->ctrladdr);
+ writew(addr, priv->ioregaddr);
+ writeb(IOCMD_GO, priv->cmdaddr);
+ udelay(1);
+ while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
+
+ /* transfer data to register */
+
+ writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_DATA, priv->ctrladdr);
+ writew(value, priv->ioregaddr);
+ writeb(IOCMD_GO, priv->cmdaddr);
+ udelay(1);
+ while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
+
+ /* reenable interrupts */
+
+ restore_flags(flags);
+}
+
+/* get LANCE register */
+
+static u16 GetLANCE(struct device *dev, u16 addr)
+{
+ skmca_priv *priv = (skmca_priv*) dev->priv;
+ unsigned long flags;
+ unsigned int res;
+
+ /* disable interrupts */


+
+ save_flags(flags);
+ cli();

+
+ /* wait until no transfer is pending */
+
+ while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
+
+ /* transfer register address to RAP */
+
+ writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP, priv->ctrladdr);
+ writew(addr, priv->ioregaddr);
+ writeb(IOCMD_GO, priv->cmdaddr);
+ udelay(1);
+ while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
+
+ /* transfer data from register */
+
+ writeb(CTRL_RESET_OFF | CTRL_RW_READ | CTRL_ADR_DATA, priv->ctrladdr);
+ writeb(IOCMD_GO, priv->cmdaddr);
+ udelay(1);
+ while ((readb(priv->ctrladdr) & STAT_IO_BUSY) == STAT_IO_BUSY);
+ res = readw(priv->ioregaddr);
+
+ /* reenable interrupts */
+
+ restore_flags(flags);
+
+ return res;
+}
+
+/* build up descriptors in shared RAM */
+
+static void InitDscrs(struct device *dev)
+{
+ u32 bufaddr;
+
+ /* Set up Tx descriptors. The board has only 16K RAM so bits 16..23
+ are always 0. */
+
+ bufaddr = RAM_DATABASE;
+ {
+ LANCE_TxDescr descr;
+ int z;
+
+ for (z = 0; z < TXCOUNT; z++)
+ {
+ descr.LowAddr = bufaddr;
+ descr.Flags = 0;
+ descr.Len = 0xf000;
+ descr.Status = 0;
+ memcpy_toio(dev->mem_start + RAM_TXBASE + (z * sizeof(LANCE_TxDescr)),
+ &descr, sizeof(LANCE_TxDescr));
+ memset_io(dev->mem_start + bufaddr, 0, RAM_BUFSIZE);
+ bufaddr += RAM_BUFSIZE;
+ }
+ }
+
+ /* do the same for the Rx descriptors */
+
+ {
+ LANCE_RxDescr descr;
+ int z;
+
+ for (z = 0; z < RXCOUNT; z++)
+ {
+ descr.LowAddr = bufaddr;
+ descr.Flags = RXDSCR_FLAGS_OWN;
+ descr.MaxLen = -RAM_BUFSIZE;
+ descr.Len = 0;
+ memcpy_toio(dev->mem_start + RAM_RXBASE + (z * sizeof(LANCE_RxDescr)),
+ &descr, sizeof(LANCE_RxDescr));
+ memset_io(dev->mem_start + bufaddr, 0, RAM_BUFSIZE);
+ bufaddr += RAM_BUFSIZE;
+ }
+ }
+}
+
+/* calculate the hash bit position for a given multicast address
+ taken more or less directly from the AMD datasheet... */
+
+static void UpdateCRC(unsigned char *CRC, int bit)
+{
+ int j;
+
+ /* shift CRC one bit */
+
+ memmove(CRC + 1, CRC, 32 * sizeof(unsigned char));
+ CRC[0] = 0;
+
+ /* if bit XOR controlbit = 1, set CRC = CRC XOR polynomial */
+
+ if (bit ^ CRC[32])
+ for (j = 0; j < 32; j++)
+ CRC[j] ^= poly[j];
+}
+
+static unsigned int GetHash(char *address)
+{
+ unsigned char CRC[33];
+ int i, byte, hashcode;
+
+ /* a multicast address has bit 0 in the first byte set */
+
+ if ((address[0] & 1) == 0)
+ return -1;
+
+ /* initialize CRC */
+
+ memset(CRC, 1, sizeof(CRC));
+
+ /* loop through address bits */
+
+ for (byte = 0; byte < 6; byte++)
+ for (i = 0; i < 8; i++)
+ UpdateCRC(CRC, (address[byte] >> i) & 1);
+
+ /* hashcode is the 6 least significant bits of the CRC */
+
+ hashcode = 0;
+ for (i = 0; i < 6; i++)
+ hashcode = (hashcode << 1) + CRC[i];
+ return hashcode;
+}
+
+/* feed ready-built initialization block into LANCE */
+
+static void InitLANCE(struct device *dev)
+{
+ skmca_priv *priv = (skmca_priv*) dev->priv;
+
+ /* build up descriptors. */
+
+ InitDscrs(dev);
+
+ /* next RX descriptor to be read is the first one. Since the LANCE
+ will start from the beginning after initialization, we have to
+ reset out pointers too. */
+
+ priv->nextrx = 0;
+
+ /* no TX descriptors active */
+
+ priv->nexttxput = priv->nexttxdone = priv->txbusy = 0;
+
+ /* set up the LANCE bus control register - constant for SKnet boards */
+
+ SetLANCE(dev, LANCE_CSR3, CSR3_BSWAP_OFF | CSR3_ALE_LOW | CSR3_BCON_HOLD);
+
+ /* write address of initialization block into LANCE */
+
+ SetLANCE(dev, LANCE_CSR1, RAM_INITBASE & 0xffff);
+ SetLANCE(dev, LANCE_CSR2, (RAM_INITBASE >> 16) & 0xff);
+
+ /* we don't get ready until the LANCE has read the init block */
+
+ dev->tbusy = 1;
+
+ /* let LANCE read the initialization block. LANCE is ready
+ when we receive the corresponding interrupt. */
+
+ SetLANCE(dev, LANCE_CSR0, CSR0_INEA | CSR0_INIT);
+}
+
+/* stop the LANCE so we can reinitialize it */
+
+static void StopLANCE(struct device *dev)
+{
+ /* can't take frames any more */
+
+ dev->tbusy = 1;
+
+ /* disable interrupts, stop it */
+
+ SetLANCE(dev, LANCE_CSR0, CSR0_STOP);
+}
+
+/* initialize card and LANCE for proper operation */
+
+static void InitBoard(struct device *dev)
+{
+ LANCE_InitBlock block;
+
+ /* Lay out the shared RAM - first we create the init block for the LANCE.
+ We do not overwrite it later because we need it again when we switch
+ promiscous mode on/off. */
+
+ block.Mode = 0;
+ if (dev->flags & IFF_PROMISC)
+ block.Mode |= LANCE_INIT_PROM;
+ memcpy(block.PAdr, dev->dev_addr, 6);
+ memset(block.LAdrF, 0, sizeof(block.LAdrF));
+ block.RdrP = (RAM_RXBASE & 0xffffff) | (LRXCOUNT << 29);
+ block.TdrP = (RAM_TXBASE & 0xffffff) | (LTXCOUNT << 29);
+
+ memcpy_toio(dev->mem_start + RAM_INITBASE, &block, sizeof(block));
+
+ /* initialize LANCE. Implicitly sets up other structures in RAM. */
+
+ InitLANCE(dev);
+}
+
+/* deinitialize card and LANCE */
+
+static void DeinitBoard(struct device *dev)
+{
+ /* stop LANCE */
+
+ StopLANCE(dev);
+
+ /* reset board */
+
+ ResetBoard(dev);
+}
+
+/* ------------------------------------------------------------------------
+ * interrupt handler(s)
+ * ------------------------------------------------------------------------ */
+
+/* LANCE has read initializazion block -> start it */
+
+static u16 irqstart_handler(struct device *dev, u16 oldcsr0)
+{
+ /* now we're ready to transmit */
+
+ dev->tbusy = 0;
+
+ /* reset IDON bit, start LANCE */
+
+ SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_IDON | CSR0_STRT);
+ return GetLANCE(dev, LANCE_CSR0);
+}
+
+/* receive interrupt */
+
+static u16 irqrx_handler(struct device *dev, u16 oldcsr0)
+{
+ skmca_priv *priv = (skmca_priv*) dev->priv;
+ LANCE_RxDescr descr;
+ unsigned int descraddr;
+
+ /* did we loose blocks due to a FIFO overrun ? */
+
+ if (oldcsr0 & CSR0_MISS)
+ priv->stat.rx_fifo_errors++;
+
+ /* run through queue until we reach a descriptor we do not own */
+
+ descraddr = RAM_RXBASE + (priv->nextrx * sizeof(LANCE_RxDescr));
+ while (1)
+ {
+ /* read descriptor */
+ memcpy_fromio(&descr, dev->mem_start + descraddr, sizeof(LANCE_RxDescr));
+
+ /* if we reach a descriptor we do not own, we're done */
+ if ((descr.Flags & RXDSCR_FLAGS_OWN) != 0)
+ break;
+
+#ifdef DEBUG
+ PrTime(); printk("Receive packet on descr %d len %d\n", priv->nextrx, descr.Len);
+#endif
+
+ /* erroneous packet ? */
+ if ((descr.Flags & RXDSCR_FLAGS_ERR) != 0)
+ {
+ priv->stat.rx_errors++;
+ if ((descr.Flags & RXDSCR_FLAGS_CRC) != 0)
+ priv->stat.rx_crc_errors++;
+ else if ((descr.Flags & RXDSCR_FLAGS_CRC) != 0)
+ priv->stat.rx_frame_errors++;
+ else if ((descr.Flags & RXDSCR_FLAGS_OFLO) != 0)
+ priv->stat.rx_fifo_errors++;
+ }
+
+ /* good packet ? */
+ else
+ {
+ struct sk_buff *skb;
+
+ skb = dev_alloc_skb(descr.Len + 2);
+ if (skb == NULL)
+ priv->stat.rx_dropped++;
+ else
+ {
+ memcpy_fromio(skb_put(skb, descr.Len),
+ dev->mem_start + descr.LowAddr, descr.Len);
+ skb->dev = dev;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->ip_summed = CHECKSUM_NONE;
+ priv->stat.rx_packets++;
+#if LINUX_VERSION_CODE >= 0x020119 /* byte counters for >= 2.1.25 */
+ priv->stat.rx_bytes += descr.Len;
+#endif
+ netif_rx(skb);
+ }
+ }
+
+ /* give descriptor back to LANCE */
+ descr.Len = 0;
+ descr.Flags |= RXDSCR_FLAGS_OWN;
+
+ /* update descriptor in shared RAM */
+ memcpy_toio(dev->mem_start + descraddr, &descr, sizeof(LANCE_RxDescr));
+
+ /* go to next descriptor */
+ priv->nextrx++; descraddr += sizeof(LANCE_RxDescr);
+ if (priv->nextrx >= RXCOUNT)
+ {
+ priv->nextrx = 0;
+ descraddr = RAM_RXBASE;
+ }
+ }
+
+ /* reset RINT bit */
+
+ SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_RINT);
+ return GetLANCE(dev, LANCE_CSR0);
+}
+
+/* transmit interrupt */
+
+static u16 irqtx_handler(struct device *dev, u16 oldcsr0)
+{
+ skmca_priv *priv = (skmca_priv*) dev->priv;
+ LANCE_TxDescr descr;
+ unsigned int descraddr;
+
+ /* check descriptors at most until no busy one is left */
+
+ descraddr = RAM_TXBASE + (priv->nexttxdone * sizeof(LANCE_TxDescr));
+ while (priv->txbusy > 0)
+ {
+ /* read descriptor */
+ memcpy_fromio(&descr, dev->mem_start + descraddr, sizeof(LANCE_TxDescr));
+
+ /* if the LANCE still owns this one, we've worked out all sent packets */
+ if ((descr.Flags & TXDSCR_FLAGS_OWN) != 0)
+ break;
+
+#ifdef DEBUG
+ PrTime(); printk("Send packet done on descr %d\n", priv->nexttxdone);
+#endif
+
+ /* update statistics */
+ if ((descr.Flags & TXDSCR_FLAGS_ERR) == 0)
+ {
+ priv->stat.tx_packets++;
+#if LINUX_VERSION_CODE >= 0x020119 /* byte counters for >= 2.1.25 */
+ priv->stat.tx_bytes++;
+#endif
+ }
+ else
+ {
+ priv->stat.tx_errors++;
+ if ((descr.Status & TXDSCR_STATUS_UFLO) != 0)
+ {
+ priv->stat.tx_fifo_errors++;
+ InitLANCE(dev);
+ }
+ else if ((descr.Status & TXDSCR_STATUS_LCOL) != 0)
+ priv->stat.tx_window_errors++;
+ else if ((descr.Status & TXDSCR_STATUS_LCAR) != 0)
+ priv->stat.tx_carrier_errors++;
+ else if ((descr.Status & TXDSCR_STATUS_RTRY) != 0)
+ priv->stat.tx_aborted_errors++;
+ }
+
+ /* go to next descriptor */
+ priv->nexttxdone++;
+ descraddr += sizeof(LANCE_TxDescr);
+ if (priv->nexttxdone >= TXCOUNT)
+ {
+ priv->nexttxdone = 0;
+ descraddr = RAM_TXBASE;
+ }
+ priv->txbusy--;
+ }
+
+ /* reset TX interrupt bit */
+
+ SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_TINT);
+ oldcsr0 = GetLANCE(dev, LANCE_CSR0);
+
+ /* at least one descriptor is freed. Therefore we can accept
+ a new one */
+
+ dev->tbusy = 0;
+
+ /* inform upper layers we're in business again */
+
+ mark_bh(NET_BH);
+
+ return oldcsr0;
+}
+
+/* general interrupt entry */
+
+static void irq_handler(int irq, void *device, struct pt_regs *regs)
+{
+ struct device *dev = (struct device*) device;
+ u16 csr0val;
+
+ /* read CSR0 to get interrupt cause */
+
+ csr0val = GetLANCE(dev, LANCE_CSR0);
+
+ /* in case we're not meant... */
+
+ if ((csr0val & CSR0_INTR) == 0)
+ return;
+
+ dev->interrupt = 1;
+
+ /* loop through the interrupt bits until everything is clear */
+
+ do
+ {
+ if ((csr0val & CSR0_IDON) != 0)
+ csr0val = irqstart_handler(dev, csr0val);
+ if ((csr0val & CSR0_RINT) != 0)
+ csr0val = irqrx_handler(dev, csr0val);
+ if ((csr0val & CSR0_TINT) != 0)
+ csr0val = irqtx_handler(dev, csr0val);
+ }
+ while ((csr0val & CSR0_INTR) != 0);
+
+ dev->interrupt = 0;
+}
+
+/* ------------------------------------------------------------------------
+ * driver methods
+ * ------------------------------------------------------------------------ */
+
+/* MCA info */
+
+static int skmca_getinfo(char *buf, int slot, void *d)
+{
+ int len = 0, i;
+ struct device *dev = (struct device*) d;
+ skmca_priv *priv;
+
+ /* can't say anything about an uninitialized device... */
+
+ if (dev == NULL)
+ return len;
+ if (dev->priv == NULL)
+ return len;
+ priv = (skmca_priv*) dev->priv;
+
+ /* print info */
+
+ len += sprintf(buf + len, "IRQ: %d\n", priv->realirq);
+ len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start,
+ dev->mem_end - 1);
+ len += sprintf(buf + len, "Transceiver: %s\n", MediaNames[priv->medium]);
+ len += sprintf(buf + len, "Device: %s\n", dev->name);
+ len += sprintf(buf + len, "MAC address:");
+ for (i = 0; i < 6; i ++ )
+ len += sprintf( buf+len, " %02x", dev->dev_addr[i] );
+ buf[len++] = '\n';
+ buf[len] = 0;
+
+ return len;
+}
+
+/* open driver. Means also initialization and start of LANCE */
+
+static int skmca_open(struct device *dev)
+{
+ int result;
+ skmca_priv *priv = (skmca_priv*) dev->priv;
+
+ /* register resources - only necessary for IRQ */
+ result = request_irq(priv->realirq, irq_handler, SA_SHIRQ | SA_SAMPLE_RANDOM,
+ "sk_mca", dev);
+ if (result != 0)
+ {
+ printk("%s: failed to register irq %d\n", dev->name, dev->irq);
+ return result;
+ }
+ dev->irq = priv->realirq;
+
+ /* set up the card and LANCE */
+ InitBoard(dev);
+
+#ifdef MODULE
+ MOD_INC_USE_COUNT;
+#endif


+
+ return 0;
+}
+

+/* close driver. Shut down board and free allocated resources */
+
+static int skmca_close(struct device *dev)
+{
+ /* turn off board */
+ DeinitBoard(dev);
+
+ /* release resources */
+ if (dev->irq != 0)
+ free_irq(dev->irq, dev);


+ dev->irq = 0;
+

+#ifdef MODULE
+ MOD_DEC_USE_COUNT;
+#endif


+
+ return 0;
+}
+

+/* transmit a block. */
+
+static int skmca_tx(struct sk_buff *skb, struct device *dev)
+{
+ skmca_priv *priv = (skmca_priv*) dev->priv;
+ LANCE_TxDescr descr;
+ unsigned int address;
+ int tmplen, retval = 0;


+ unsigned long flags;
+

+ /* if we get called with a NULL descriptor, the Ethernet layer thinks
+ our card is stuck an we should reset it. We'll do this completely: */
+
+ if (skb == NULL)
+ {
+ DeinitBoard(dev);
+ InitBoard(dev);
+ return 0; /* don't try to free the block here ;-) */
+ }
+
+ /* is there space in the Tx queue ? If no, the upper layer gave us a
+ packet in spite of us not being ready and is really in trouble.
+ We'll do the dropping for him: */
+ if (priv->txbusy >= TXCOUNT)
+ {
+ priv->stat.tx_dropped++;
+ retval = -EIO;
+ goto tx_done;
+ }
+
+ /* get TX descriptor */
+ address = RAM_TXBASE + (priv->nexttxput * sizeof(LANCE_TxDescr));
+ memcpy_fromio(&descr, dev->mem_start + address, sizeof(LANCE_TxDescr));
+
+ /* enter packet length as 2s complement - assure minimum length */
+ tmplen = skb->len;
+ if (tmplen < 60)
+ tmplen = 60;
+ descr.Len = 65536 - tmplen;
+
+ /* copy filler into RAM - in case we're filling up...
+ we're filling a bit more than necessary, but that doesn't harm
+ since the buffer is far larger... */
+ if (tmplen > skb->len)
+ {
+ char *fill = "NetBSD is a nice OS too! ";
+ unsigned int destoffs = 0, l = strlen(fill);
+
+ while (destoffs < tmplen)
+ {
+ memcpy_toio(dev->mem_start + descr.LowAddr + destoffs, fill, l);
+ destoffs += l;
+ }
+ }
+
+ /* do the real data copying */
+ memcpy_toio(dev->mem_start + descr.LowAddr, skb->data, skb->len);
+
+ /* hand descriptor over to LANCE - this is the first and last chunk */
+ descr.Flags = TXDSCR_FLAGS_OWN | TXDSCR_FLAGS_STP | TXDSCR_FLAGS_ENP;
+
+#ifdef DEBUG
+ PrTime(); printk("Send packet on descr %d len %d\n", priv->nexttxput, skb->len);
+#endif
+
+ /* one more descriptor busy */
+ save_flags(flags);
+ cli();
+ priv->nexttxput++;
+ if (priv->nexttxput >= TXCOUNT)
+ priv->nexttxput = 0;
+ priv->txbusy++;
+ dev->tbusy = (priv->txbusy >= TXCOUNT);
+
+ /* write descriptor back to RAM */
+ memcpy_toio(dev->mem_start + address, &descr, sizeof(LANCE_TxDescr));
+
+ /* if no descriptors were active, give the LANCE a hint to read it
+ immediately */
+
+ if (priv->txbusy == 0)
+ SetLANCE(dev, LANCE_CSR0, CSR0_INEA | CSR0_TDMD);
+
+ restore_flags(flags);
+
+tx_done:
+
+ /* When did that change exactly ? */
+
+#if LINUX_VERSION_CODE >= 0x020200
+ dev_kfree_skb(skb);
+#else
+ dev_kfree_skb(skb, FREE_WRITE);
+#endif
+ return retval;
+}
+
+/* return pointer to Ethernet statistics */
+
+static struct enet_statistics *skmca_stats(struct device *dev)
+{
+ skmca_priv *priv = (skmca_priv*) dev->priv;
+
+ return &(priv->stat);
+}
+
+/* we don't support runtime reconfiguration, since am MCA card can
+ be unambigously identified by its POS registers. */
+
+static int skmca_config(struct device *dev, struct ifmap *map)


+{
+ return 0;
+}
+

+/* switch receiver mode. We use the LANCE's multicast filter to prefilter
+ multicast addresses. */
+
+static void skmca_set_multicast_list(struct device *dev)
+{
+ LANCE_InitBlock block;
+
+ /* first stop the LANCE... */
+ StopLANCE(dev);
+
+ /* ...then modify the initialization block... */
+ memcpy_fromio(&block, dev->mem_start + RAM_INITBASE, sizeof(block));
+ if (dev->flags & IFF_PROMISC)
+ block.Mode |= LANCE_INIT_PROM;
+ else
+ block.Mode &= ~LANCE_INIT_PROM;
+
+ if (dev->flags & IFF_ALLMULTI) /* get all multicasts */
+ {
+ memset(block.LAdrF, 8, 0xff);
+ }
+ else /* get selected/no multicasts */
+ {
+ struct dev_mc_list *mptr;
+ int code;
+
+ memset(block.LAdrF, 8, 0x00);
+ for (mptr = dev->mc_list; mptr != NULL; mptr = mptr->next)
+ {
+ code = GetHash(mptr->dmi_addr);
+ block.LAdrF[(code >> 3) & 7] |= 1 << (code & 7);
+ }
+ }
+
+ memcpy_toio(dev->mem_start + RAM_INITBASE, &block, sizeof(block));
+
+ /* ...then reinit LANCE with the correct flags */
+ InitLANCE(dev);
+}
+
+/* ------------------------------------------------------------------------
+ * hardware check
+ * ------------------------------------------------------------------------ */
+
+#ifdef MODULE
+static int startslot; /* counts through slots when probing multiple devices */
+#else
+#define startslot 0 /* otherwise a dummy, since there is only eth0 in-kern*/
+#endif
+
+int skmca_probe(struct device *dev)
+{
+ int force_detect = 0;
+ int junior, slot, i;
+ int base = 0, irq = 0;
+ skmca_priv *priv;
+ skmca_medium medium;
+
+ /* can't work without an MCA bus ;-) */
+
+ if (MCA_bus == 0)
+ return ENODEV;
+
+ /* start address of 1 --> forced detection */
+
+ if (dev->mem_start == 1)
+ force_detect = 1;
+
+ /* search through slots */
+
+ if (dev != NULL)
+ {
+ base = dev->mem_start;
+ irq = dev->irq;
+ }
+ slot = dofind(&junior, startslot);
+
+ while (slot != -1)
+ {
+ /* deduce card addresses */
+
+ getaddrs(slot, junior, &base, &irq, &medium);
+
+#if 0
+ /* this should work, but it doesn't with 2.2.9 :-(
+ somehow 'mca_is_adapter_used()' is missing in kernel syms... */
+#if LINUX_VERSION_CODE >= 0x020200
+ /* slot already in use ? */
+
+ if (mca_is_adapter_used(slot))
+ {
+ slot = dofind(&junior, slot + 1);
+ continue;
+ }
+#endif
+#endif
+
+ /* were we looking for something different ? */
+
+ if ((dev->irq != 0) || (dev->mem_start != 0))
+ {
+ if ((dev->irq != 0) && (dev->irq != irq))
+ {
+ slot = dofind(&junior, slot + 1);
+ continue;
+ }
+ if ((dev->mem_start != 0) && (dev->mem_start != base))
+ {
+ slot = dofind(&junior, slot + 1);
+ continue;
+ }
+ }
+
+ /* found something that matches */
+
+ break;
+ }
+
+ /* nothing found ? */
+
+ if (slot == -1)
+ return ((base != 0) || (irq != 0)) ? ENXIO : ENODEV;
+
+ /* make procfs entries */
+
+ if (junior)
+ mca_set_adapter_name(slot, "SKNET junior MC2 Ethernet Adapter");
+ else
+ mca_set_adapter_name(slot, "SKNET MC2+ Ethernet Adapter");
+ mca_set_adapter_procfn(slot, (MCA_ProcFn) skmca_getinfo, dev);
+
+#if LINUX_VERSION_CODE >= 0x020200
+ mca_mark_as_used(slot);
+#endif
+
+ /* announce success */
+ printk("%s: SKNet %s adapter found in slot %d\n", dev->name,
+ junior ? "Junior MC2" : "MC2+", slot + 1);
+
+ /* allocate structure */
+ priv = dev->priv = (skmca_priv*) kmalloc(sizeof(skmca_priv), GFP_KERNEL);
+ priv->slot = slot;
+ priv->macbase = base + 0x3fc0;
+ priv->ioregaddr = base + 0x3ff0;
+ priv->ctrladdr = base + 0x3ff2;
+ priv->cmdaddr = base + 0x3ff3;
+ priv->realirq = irq;
+ priv->medium = medium;
+ memset(&(priv->stat), 0, sizeof(struct enet_statistics));
+
+ /* set base + irq for this device (irq not allocated so far) */


+ dev->irq = 0;

+ dev->mem_start = base;
+ dev->mem_end = base + 0x4000;
+
+ /* set methods */
+ dev->open = skmca_open;
+ dev->stop = skmca_close;
+ dev->set_config = skmca_config;
+ dev->hard_start_xmit = skmca_tx;
+ dev->do_ioctl = NULL;
+ dev->get_stats = skmca_stats;
+ dev->set_multicast_list = skmca_set_multicast_list;
+ dev->flags |= IFF_MULTICAST;
+
+ /* generic setup */
+ ether_setup(dev);
+ dev->interrupt = 0;
+ dev->tbusy = 0;
+ dev->start = 0;
+
+ /* copy out MAC address */
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = readb(priv->macbase + (i << 1));
+
+ /* print config */
+ printk("%s: IRQ %d, memory %#lx-%#lx, "
+ "MAC address %02x:%02x:%02x:%02x:%02x:%02x.\n",
+ dev->name, priv->realirq, dev->mem_start, dev->mem_end - 1,
+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+ printk("%s: %s medium\n", dev->name, MediaNames[priv->medium]);
+
+ /* reset board */
+
+ ResetBoard(dev);
+
+#ifdef MODULE
+ startslot = slot + 1;
+#endif


+
+ return 0;
+}
+

+/* ------------------------------------------------------------------------
+ * modularization support
+ * ------------------------------------------------------------------------ */
+
+#ifdef MODULE
+
+#define DEVMAX 5
+
+static char NameSpace[8 * DEVMAX];
+static struct device moddevs[DEVMAX] =
+ {{NameSpace + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
+ {NameSpace + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
+ {NameSpace + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
+ {NameSpace + 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe},
+ {NameSpace + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, skmca_probe}};
+
+int irq=0;
+int io=0;
+
+int init_module(void)
+{
+ int z, res;
+
+ startslot = 0;
+ for (z = 0; z < DEVMAX; z++)
+ {
+ strcpy(moddevs[z].name, " ");
+ res = register_netdev(moddevs + z);
+ if (res != 0)
+ return (z > 0) ? 0 : -EIO;
+ }


+
+ return 0;
+}
+

+void cleanup_module(void)


+{
+ struct device *dev;

+ skmca_priv *priv;
+ int z;
+
+ if (MOD_IN_USE)
+ {
+ printk("cannot unload, module in use\n");
+ return;
+ }
+
+ for (z = 0; z < DEVMAX; z++)
+ {
+ dev = moddevs + z;
+ if (dev->priv != NULL)
+ {
+ priv = (skmca_priv*) dev->priv;
+ DeinitBoard(dev);
+ if (dev->irq != 0)
+ free_irq(dev->irq, dev);


+ dev->irq = 0;

+ unregister_netdev(dev);
+#if LINUX_VERSION_CODE >= 0x020200
+ mca_mark_as_unused(priv->slot);
+#endif
+ mca_set_adapter_procfn(priv->slot, NULL, NULL);
+ kfree_s(dev->priv, sizeof(skmca_priv));
+ dev->priv = NULL;
+ }
+ }
+}
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.5/linux/drivers/net/sk_mca.h linux/drivers/net/sk_mca.h
--- v2.3.5/linux/drivers/net/sk_mca.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/sk_mca.h Mon Jun 7 14:34:46 1999
@@ -0,0 +1,174 @@
+#ifndef _SK_MCA_INCLUDE_
+#define _SK_MCA_INCLUDE_
+
+#ifdef _SK_MCA_DRIVER_
+
+/* Adapter ID's */
+#define SKNET_MCA_ID 0x6afd
+#define SKNET_JUNIOR_MCA_ID 0x6be9
+
+/* media enumeration - defined in a way that it fits onto the MC2+'s
+ POS registers... */
+
+typedef enum {Media_10Base2, Media_10BaseT,
+ Media_10Base5, Media_Unknown, Media_Count} skmca_medium;
+
+/* private structure */
+typedef struct
+ {
+ unsigned int slot; /* MCA-Slot-# */
+ unsigned int macbase; /* base address of MAC address PROM */
+ unsigned int ioregaddr; /* address of I/O-register (Lo) */
+ unsigned int ctrladdr; /* address of control/stat register */
+ unsigned int cmdaddr; /* address of I/O-command register */
+ int nextrx; /* index of next RX descriptor to
+ be read */
+ int nexttxput; /* index of next free TX descriptor */
+ int nexttxdone; /* index of next TX descriptor to
+ be finished */
+ int txbusy; /* # of busy TX descriptors */
+ struct enet_statistics stat; /* packet statistics */
+ int realirq; /* memorizes actual IRQ, even when
+ currently not allocated */
+ skmca_medium medium; /* physical cannector */
+ } skmca_priv;
+
+/* card registers: control/status register bits */
+
+#define CTRL_ADR_DATA 0 /* Bit 0 = 0 ->access data register */
+#define CTRL_ADR_RAP 1 /* Bit 0 = 1 ->access RAP register */
+#define CTRL_RW_WRITE 0 /* Bit 1 = 0 ->write register */
+#define CTRL_RW_READ 2 /* Bit 1 = 1 ->read register */
+#define CTRL_RESET_ON 0 /* Bit 3 = 0 ->reset board */
+#define CTRL_RESET_OFF 8 /* Bit 3 = 1 ->no reset of board */
+
+#define STAT_ADR_DATA 0 /* Bit 0 of ctrl register read back */
+#define STAT_ADR_RAP 1
+#define STAT_RW_WRITE 0 /* Bit 1 of ctrl register read back */
+#define STAT_RW_READ 2
+#define STAT_RESET_ON 0 /* Bit 3 of ctrl register read back */
+#define STAT_RESET_OFF 8
+#define STAT_IRQ_ACT 0 /* interrupt pending */
+#define STAT_IRQ_NOACT 16 /* no interrupt pending */
+#define STAT_IO_NOBUSY 0 /* no transfer busy */
+#define STAT_IO_BUSY 32 /* transfer busy */
+
+/* I/O command register bits */
+
+#define IOCMD_GO 128 /* Bit 7 = 1 -> start register xfer */
+
+/* LANCE registers */
+
+#define LANCE_CSR0 0 /* Status/Control */
+
+#define CSR0_ERR 0x8000 /* general error flag */
+#define CSR0_BABL 0x4000 /* transmitter timeout */
+#define CSR0_CERR 0x2000 /* collision error */
+#define CSR0_MISS 0x1000 /* lost Rx block */
+#define CSR0_MERR 0x0800 /* memory access error */
+#define CSR0_RINT 0x0400 /* receiver interrupt */
+#define CSR0_TINT 0x0200 /* transmitter interrupt */
+#define CSR0_IDON 0x0100 /* initialization done */
+#define CSR0_INTR 0x0080 /* general interrupt flag */
+#define CSR0_INEA 0x0040 /* interrupt enable */
+#define CSR0_RXON 0x0020 /* receiver enabled */
+#define CSR0_TXON 0x0010 /* transmitter enabled */
+#define CSR0_TDMD 0x0008 /* force transmission now */
+#define CSR0_STOP 0x0004 /* stop LANCE */
+#define CSR0_STRT 0x0002 /* start LANCE */
+#define CSR0_INIT 0x0001 /* read initialization block */
+
+#define LANCE_CSR1 1 /* addr bit 0..15 of initialization */
+#define LANCE_CSR2 2 /* 16..23 block */
+
+#define LANCE_CSR3 3 /* Bus control */
+#define CSR3_BCON_HOLD 0 /* Bit 0 = 0 -> BM1,BM0,HOLD */
+#define CSR3_BCON_BUSRQ 1 /* Bit 0 = 1 -> BUSAK0,BYTE,BUSRQ */
+#define CSR3_ALE_HIGH 0 /* Bit 1 = 0 -> ALE asserted high */
+#define CSR3_ALE_LOW 2 /* Bit 1 = 1 -> ALE asserted low */
+#define CSR3_BSWAP_OFF 0 /* Bit 2 = 0 -> no byte swap */
+#define CSR3_BSWAP_ON 0 /* Bit 2 = 1 -> byte swap */
+
+/* LANCE structures */
+
+typedef struct /* LANCE initialization block */
+ {
+ u16 Mode; /* mode flags */
+ u8 PAdr[6]; /* MAC address */
+ u8 LAdrF[8]; /* Multicast filter */
+ u32 RdrP; /* Receive descriptor */
+ u32 TdrP; /* Transmit descriptor */
+ } LANCE_InitBlock;
+
+/* Mode flags init block */
+
+#define LANCE_INIT_PROM 0x8000 /* enable promiscous mode */
+#define LANCE_INIT_INTL 0x0040 /* internal loopback */
+#define LANCE_INIT_DRTY 0x0020 /* disable retry */
+#define LANCE_INIT_COLL 0x0010 /* force collision */
+#define LANCE_INIT_DTCR 0x0008 /* disable transmit CRC */
+#define LANCE_INIT_LOOP 0x0004 /* loopback */
+#define LANCE_INIT_DTX 0x0002 /* disable transmitter */
+#define LANCE_INIT_DRX 0x0001 /* disable receiver */
+
+typedef struct /* LANCE Tx descriptor */
+ {
+ u16 LowAddr; /* bit 0..15 of address */
+ u16 Flags; /* bit 16..23 of address + Flags */
+ u16 Len; /* 2s complement of packet length */
+ u16 Status; /* Result of transmission */
+ } LANCE_TxDescr;
+
+#define TXDSCR_FLAGS_OWN 0x8000 /* LANCE owns descriptor */
+#define TXDSCR_FLAGS_ERR 0x4000 /* summary error flag */
+#define TXDSCR_FLAGS_MORE 0x1000 /* more than one retry needed? */
+#define TXDSCR_FLAGS_ONE 0x0800 /* one retry? */
+#define TXDSCR_FLAGS_DEF 0x0400 /* transmission deferred? */
+#define TXDSCR_FLAGS_STP 0x0200 /* first packet in chain? */
+#define TXDSCR_FLAGS_ENP 0x0100 /* last packet in chain? */
+
+#define TXDSCR_STATUS_BUFF 0x8000 /* buffer error? */
+#define TXDSCR_STATUS_UFLO 0x4000 /* silo underflow during transmit? */
+#define TXDSCR_STATUS_LCOL 0x1000 /* late collision? */
+#define TXDSCR_STATUS_LCAR 0x0800 /* loss of carrier? */
+#define TXDSCR_STATUS_RTRY 0x0400 /* retry error? */
+
+typedef struct /* LANCE Rx descriptor */
+ {
+ u16 LowAddr; /* bit 0..15 of address */
+ u16 Flags; /* bit 16..23 of address + Flags */
+ u16 MaxLen; /* 2s complement of buffer length */
+ u16 Len; /* packet length */
+ } LANCE_RxDescr;
+
+#define RXDSCR_FLAGS_OWN 0x8000 /* LANCE owns descriptor */
+#define RXDSCR_FLAGS_ERR 0x4000 /* summary error flag */
+#define RXDSCR_FLAGS_FRAM 0x2000 /* framing error flag */
+#define RXDSCR_FLAGS_OFLO 0x1000 /* FIFO overflow? */
+#define RXDSCR_FLAGS_CRC 0x0800 /* CRC error? */
+#define RXDSCR_FLAGS_BUFF 0x0400 /* buffer error? */
+#define RXDSCR_FLAGS_STP 0x0200 /* first packet in chain? */
+#define RXDCSR_FLAGS_ENP 0x0100 /* last packet in chain? */
+
+/* RAM layout */
+
+#define TXCOUNT 4 /* length of TX descriptor queue */
+#define LTXCOUNT 2 /* log2 of it */
+#define RXCOUNT 4 /* length of RX descriptor queue */
+#define LRXCOUNT 2 /* log2 of it */
+
+#define RAM_INITBASE 0 /* LANCE init block */
+#define RAM_TXBASE 24 /* Start of TX descriptor queue */
+#define RAM_RXBASE \
+(RAM_TXBASE + (TXCOUNT * 8)) /* Start of RX descriptor queue */
+#define RAM_DATABASE \
+(RAM_RXBASE + (RXCOUNT * 8)) /* Start of data area for frames */
+#define RAM_BUFSIZE 1580 /* max. frame size - should never be
+ reached */
+
+#endif /* _SK_MCA_DRIVER_ */
+
+extern int skmca_probe(struct device *);
+
+
+#endif /* _SK_MCA_INCLUDE_ */
\ No newline at end of file
diff -u --recursive --new-file v2.3.5/linux/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c
--- v2.3.5/linux/drivers/pci/oldproc.c Fri May 14 18:55:20 1999
+++ linux/drivers/pci/oldproc.c Wed Jun 9 16:59:15 1999
@@ -102,6 +102,7 @@
X DEVICE( DEC, DEC_21150, "DC21150"),
X DEVICE( DEC, DEC_21152, "DC21152"),
X DEVICE( DEC, DEC_21153, "DC21153"),
+ DEVICE( DEC, DEC_21154, "DC21154"),
X DEVICE( CIRRUS, CIRRUS_7548, "GD 7548"),
X DEVICE( CIRRUS, CIRRUS_5430, "GD 5430"),
X DEVICE( CIRRUS, CIRRUS_5434_4, "GD 5434"),
@@ -202,6 +203,8 @@
X DEVICE( MOTOROLA, MOTOROLA_MPC105,"MPC105 Eagle"),
X DEVICE( MOTOROLA, MOTOROLA_MPC106,"MPC106 Grackle"),
X DEVICE( MOTOROLA, MOTOROLA_RAVEN, "Raven"),
+ DEVICE( MOTOROLA, MOTOROLA_FALCON,"Falcon"),
+ DEVICE( MOTOROLA, MOTOROLA_CPX8216,"CPX8216"),
X DEVICE( PROMISE, PROMISE_20246, "IDE UltraDMA/33"),
X DEVICE( PROMISE, PROMISE_20262, "IDE UltraDMA/66"),
X DEVICE( PROMISE, PROMISE_5300, "DC5030"),
@@ -467,6 +470,7 @@
X DEVICE( PICTUREL, PICTUREL_PCIVST,"PCIVST"),
X DEVICE( NVIDIA_SGS, NVIDIA_SGS_RIVA128, "Riva 128"),
X DEVICE( CBOARDS, CBOARDS_DAS1602_16,"DAS1602/16"),
+ DEVICE( MOTOROLA_OOPS, MOTOROLA_FALCON,"Falcon"),
X DEVICE( SYMPHONY, SYMPHONY_101, "82C101"),
X DEVICE( TEKRAM, TEKRAM_DC290, "DC-290"),
X DEVICE( 3DLABS, 3DLABS_300SX, "GLINT 300SX"),
@@ -536,9 +540,11 @@
X DEVICE( INTEL, INTEL_82450GX, "82450GX Orion P6"),
X DEVICE( KTI, KTI_ET32P2, "ET32P2"),
X DEVICE( ADAPTEC, ADAPTEC_7810, "AIC-7810 RAID"),
+ DEVICE( ADAPTEC, ADAPTEC_7821, "AIC-7860"),
X DEVICE( ADAPTEC, ADAPTEC_7850, "AIC-7850"),
X DEVICE( ADAPTEC, ADAPTEC_7855, "AIC-7855"),
X DEVICE( ADAPTEC, ADAPTEC_5800, "AIC-5800"),
+ DEVICE( ADAPTEC, ADAPTEC_3860, "AIC-7860"),
X DEVICE( ADAPTEC, ADAPTEC_7860, "AIC-7860"),
X DEVICE( ADAPTEC, ADAPTEC_7861, "AIC-7861"),
X DEVICE( ADAPTEC, ADAPTEC_7870, "AIC-7870"),
@@ -552,13 +558,26 @@
X DEVICE( ADAPTEC, ADAPTEC_7882, "AIC-7882U"),
X DEVICE( ADAPTEC, ADAPTEC_7883, "AIC-7883U"),
X DEVICE( ADAPTEC, ADAPTEC_7884, "AIC-7884U"),
+ DEVICE( ADAPTEC, ADAPTEC_7885, "AIC-7885U"),
+ DEVICE( ADAPTEC, ADAPTEC_7886, "AIC-7886U"),
+ DEVICE( ADAPTEC, ADAPTEC_7887, "AIC-7887U"),
+ DEVICE( ADAPTEC, ADAPTEC_7888, "AIC-7888U"),
X DEVICE( ADAPTEC, ADAPTEC_1030, "ABA-1030 DVB receiver"),
X DEVICE( ADAPTEC2, ADAPTEC2_2940U2,"AHA-2940U2"),
- DEVICE( ADAPTEC2, ADAPTEC2_78902, "AIC-7890/1"),
+ DEVICE( ADAPTEC2, ADAPTEC2_2930U2,"AHA-2930U2"),
+ DEVICE( ADAPTEC2, ADAPTEC2_7890B, "AIC-7890/1"),
X DEVICE( ADAPTEC2, ADAPTEC2_7890, "AIC-7890/1"),
X DEVICE( ADAPTEC2, ADAPTEC2_3940U2,"AHA-3940U2"),
X DEVICE( ADAPTEC2, ADAPTEC2_3950U2D,"AHA-3950U2D"),
X DEVICE( ADAPTEC2, ADAPTEC2_7896, "AIC-7896/7"),
+ DEVICE( ADAPTEC2, ADAPTEC2_7892A, "AIC-7892"),
+ DEVICE( ADAPTEC2, ADAPTEC2_7892B, "AIC-7892"),
+ DEVICE( ADAPTEC2, ADAPTEC2_7892D, "AIC-7892"),
+ DEVICE( ADAPTEC2, ADAPTEC2_7892P, "AIC-7892"),
+ DEVICE( ADAPTEC2, ADAPTEC2_7899A, "AIC-7899"),
+ DEVICE( ADAPTEC2, ADAPTEC2_7899B, "AIC-7899"),
+ DEVICE( ADAPTEC2, ADAPTEC2_7899D, "AIC-7899"),
+ DEVICE( ADAPTEC2, ADAPTEC2_7899P, "AIC-7899"),
X DEVICE( ATRONICS, ATRONICS_2015, "IDE-2015PL"),
X DEVICE( TIGERJET, TIGERJET_300, "Tiger300 ISDN"),
X DEVICE( ARK, ARK_STING, "Stingray"),
@@ -676,6 +695,8 @@
X case PCI_CLASS_SERIAL_USB: return "USB Controller";
X case PCI_CLASS_SERIAL_FIBER: return "Fiber Channel";
X
+ case PCI_CLASS_HOT_SWAP_CONTROLLER: return "Hot Swap Controller";
+
X default: return "Unknown class";
X }
X }
@@ -715,6 +736,7 @@
X case PCI_VENDOR_ID_OAK: return "OAK";
X case PCI_VENDOR_ID_WINBOND2: return "Winbond";
X case PCI_VENDOR_ID_MOTOROLA: return "Motorola";
+ case PCI_VENDOR_ID_MOTOROLA_OOPS: return "Motorola";
X case PCI_VENDOR_ID_PROMISE: return "Promise Technology";
X case PCI_VENDOR_ID_N9: return "Number Nine";
X case PCI_VENDOR_ID_UMC: return "UMC";
diff -u --recursive --new-file v2.3.5/linux/drivers/sbus/char/Config.in linux/drivers/sbus/char/Config.in
--- v2.3.5/linux/drivers/sbus/char/Config.in Mon May 31 22:28:06 1999
+++ linux/drivers/sbus/char/Config.in Wed Jun 9 14:44:25 1999
@@ -12,4 +12,10 @@
X tristate 'Bidirectional parallel port support (EXPERIMENTAL)' CONFIG_SUN_BPP
X tristate 'Videopix Frame Grabber (EXPERIMENTAL)' CONFIG_SUN_VIDEOPIX
X tristate 'Aurora Multiboard 1600se (EXPERIMENTAL)' CONFIG_SUN_AURORA
+
+ # XXX Why don't we do "source drivers/char/Config.in" somewhere?
+ if [ "$CONFIG_PCI" = "y" ]; then
+ define_bool CONFIG_APM_RTC_IS_GMT y # no shit
+ bool 'PC-style RTC' CONFIG_RTC
+ fi
X fi
diff -u --recursive --new-file v2.3.5/linux/drivers/sbus/char/aurora.c linux/drivers/sbus/char/aurora.c
--- v2.3.5/linux/drivers/sbus/char/aurora.c Mon May 31 22:28:06 1999
+++ linux/drivers/sbus/char/aurora.c Wed Jun 9 14:44:25 1999
@@ -53,6 +53,7 @@
X #include <linux/kernel.h>
X #include <linux/init.h>
X #include <linux/tqueue.h>
+#include <linux/delay.h>
X
X #include <asm/io.h>
X #include <asm/irq.h>
@@ -60,7 +61,6 @@
X #include <asm/system.h>
X #include <asm/segment.h>
X #include <asm/bitops.h>
-#include <asm/delay.h>
X #include <asm/kdebug.h>
X #include <asm/sbus.h>
X #include <asm/uaccess.h>
diff -u --recursive --new-file v2.3.5/linux/drivers/sbus/char/bpp.c linux/drivers/sbus/char/bpp.c
--- v2.3.5/linux/drivers/sbus/char/bpp.c Fri May 14 18:55:21 1999
+++ linux/drivers/sbus/char/bpp.c Wed Jun 9 14:44:25 1999
@@ -997,7 +997,7 @@
X instances[idx].enhanced = 0;
X instances[idx].direction = 0;
X instances[idx].mode = COMPATIBILITY;
- instances[idx].wait_queue = 0;
+ init_waitqueue_head(&instances[idx].wait_queue);
X instances[idx].run_length = 0;
X instances[idx].run_flag = 0;
X init_timer(&instances[idx].timer_list);
diff -u --recursive --new-file v2.3.5/linux/drivers/sbus/char/pcikbd.c linux/drivers/sbus/char/pcikbd.c
--- v2.3.5/linux/drivers/sbus/char/pcikbd.c Mon May 17 09:55:22 1999
+++ linux/drivers/sbus/char/pcikbd.c Wed Jun 9 14:44:25 1999
@@ -1,8 +1,8 @@
-/* $Id: pcikbd.c,v 1.29 1999/05/16 13:47:53 ecd Exp $
+/* $Id: pcikbd.c,v 1.30 1999/06/03 15:02:36 davem Exp $
X * pcikbd.c: Ultra/AX PC keyboard support.
X *


X * Copyright (C) 1997 Eddie C. Dost (e...@skynet.be)

- * JavaStation(MrCoffee) support by Pete A. Zaitcev.
+ * JavaStation support by Pete A. Zaitcev.
X *
X * This code is mainly put together from various places in
X * drivers/char, please refer to these sources for credits
@@ -30,13 +30,16 @@
X #include <asm/io.h>
X #include <asm/uaccess.h>
X
-#ifdef __sparc_v9__
-#define PCI_KB_NAME "kb_ps2"
-#define PCI_MS_NAME "kdmouse"
-#else
-#define PCI_KB_NAME "keyboard"
-#define PCI_MS_NAME "mouse"
-#endif
+/*
+ * Different platforms provide different permutations of names.
+ * AXi - kb_ps2, kdmouse.
+ * MrCoffee - keyboard, mouse.
+ * Espresso - keyboard, kdmouse.
+ */
+#define PCI_KB_NAME1 "kb_ps2"
+#define PCI_KB_NAME2 "keyboard"
+#define PCI_MS_NAME1 "kdmouse"
+#define PCI_MS_NAME2 "mouse"
X
X #include "pcikbd.h"
X #include "sunserial.h"
@@ -502,7 +505,8 @@
X for_each_ebusdev(edev, ebus) {
X if(!strcmp(edev->prom_name, "8042")) {
X for_each_edevchild(edev, child) {
- if (!strcmp(child->prom_name, PCI_KB_NAME))
+ if (strcmp(child->prom_name, PCI_KB_NAME1) == 0 ||
+ strcmp(child->prom_name, PCI_KB_NAME2) == 0)
X goto found;
X }
X }
@@ -513,12 +517,14 @@
X
X found:
X pcikbd_iobase = child->base_address[0];
+#ifdef __sparc_v9__
X if (check_region(pcikbd_iobase, sizeof(unsigned long))) {
X printk("8042: can't get region %lx, %d\n",
X pcikbd_iobase, (int)sizeof(unsigned long));
X return;
X }
X request_region(pcikbd_iobase, sizeof(unsigned long), "8042 controller");
+#endif
X
X pcikbd_irq = child->irqs[0];
X if (request_irq(pcikbd_irq, &pcikbd_interrupt,
@@ -548,7 +554,7 @@
X * XXX: my 3.1.3 PROM does not give me the beeper node for the audio
X * auxio register, though I know it is there... (ecd)
X *
- * Both JE1 & MrCoffe have no beeper. How about Krups? --zaitcev
+ * JavaStations appear not to have beeper. --zaitcev
X */
X if (!edev)
X pcibeep_iobase = (pcikbd_iobase & ~(0xffffff)) | 0x722000;
@@ -575,7 +581,6 @@
X }
X
X
-
X /*
X * Here begins the Mouse Driver.
X */
@@ -955,7 +960,8 @@
X for_each_ebusdev(edev, ebus) {
X if(!strcmp(edev->prom_name, "8042")) {
X for_each_edevchild(edev, child) {
- if (!strcmp(child->prom_name, PCI_MS_NAME))
+ if (strcmp(child->prom_name, PCI_MS_NAME1) == 0 ||
+ strcmp(child->prom_name, PCI_MS_NAME2) == 0)
X goto found;
X }
X }
@@ -1023,7 +1029,7 @@
X
X __initfunc(int ps2kbd_probe(unsigned long *memory_start))
X {
- int pnode, enode, node, dnode;
+ int pnode, enode, node, dnode, xnode;
X int kbnode = 0, msnode = 0, bnode = 0;
X int devices = 0;
X char prop[128];
@@ -1103,18 +1109,20 @@
X * For each '8042' on this EBus...
X */
X while (node) {
+ dnode = prom_getchild(node);
+
X /*
X * Does it match?
X */
- dnode = prom_getchild(node);
- dnode = prom_searchsiblings(dnode, PCI_KB_NAME);
- if (dnode == kbnode) {
+ if ((xnode = prom_searchsiblings(dnode, PCI_KB_NAME1)) == kbnode) {
+ ++devices;
+ } else if ((xnode = prom_searchsiblings(dnode, PCI_KB_NAME2)) == kbnode) {
X ++devices;
X }
X
- dnode = prom_getchild(node);
- dnode = prom_searchsiblings(dnode, PCI_MS_NAME);
- if (dnode == msnode) {
+ if ((xnode = prom_searchsiblings(dnode, PCI_MS_NAME1)) == msnode) {
+ ++devices;
+ } else if ((xnode = prom_searchsiblings(dnode, PCI_MS_NAME2)) == msnode) {
X ++devices;
X }
X
diff -u --recursive --new-file v2.3.5/linux/drivers/sbus/char/rtc.c linux/drivers/sbus/char/rtc.c
--- v2.3.5/linux/drivers/sbus/char/rtc.c Sun Oct 4 10:22:44 1998
+++ linux/drivers/sbus/char/rtc.c Wed Jun 9 14:44:25 1999
@@ -1,4 +1,4 @@
-/* $Id: rtc.c,v 1.13 1998/08/26 10:29:44 davem Exp $
+/* $Id: rtc.c,v 1.14 1999/06/03 15:02:38 davem Exp $
X *
X * Linux/SPARC Real Time Clock Driver
X * Copyright (C) 1996 Thomas K. Dyas (td...@eden.rutgers.edu)


@@ -107,6 +107,7 @@
X

X static int rtc_open(struct inode *inode, struct file *file)
X {
+
X if (rtc_busy)
X return -EBUSY;
X
@@ -144,14 +145,20 @@
X #ifdef MODULE
X int init_module(void)
X #else
-__initfunc(int rtc_init(void))
+__initfunc(int rtc_sun_init(void))
X #endif
X {
X int error;
X
+ if (mstk48t02_regs == 0) {
+ /* This diagnostic is a debugging aid... But a useful one. */
+ printk(KERN_ERR "rtc: no Mostek in this computer\n");


+ return -ENODEV;
+ }
+

X error = misc_register(&rtc_dev);
X if (error) {
- printk(KERN_ERR "rtc: unable to get misc minor\n");
+ printk(KERN_ERR "rtc: unable to get misc minor for Mostek\n");
X return error;
X }
X
diff -u --recursive --new-file v2.3.5/linux/drivers/sbus/char/su.c linux/drivers/sbus/char/su.c
--- v2.3.5/linux/drivers/sbus/char/su.c Fri May 14 18:55:21 1999
+++ linux/drivers/sbus/char/su.c Wed Jun 9 14:44:25 1999
@@ -1,8 +1,8 @@
-/* $Id: su.c,v 1.19 1999/05/12 11:15:14 davem Exp $
+/* $Id: su.c,v 1.20 1999/06/03 15:02:40 davem Exp $
X * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
X *


X * Copyright (C) 1997 Eddie C. Dost (e...@skynet.be)

- * Coypright (C) 1998 Pete Zaitcev (zai...@metabyte.com)
+ * Copyright (C) 1998-1999 Pete Zaitcev (zai...@metabyte.com)
X *
X * This is mainly a variation of drivers/char/serial.c,
X * credits go to authors mentioned therein.
@@ -92,6 +92,11 @@
X int su_serial_console_init(void);
X #endif
X
+enum su_type { SU_PORT_NONE, SU_PORT_MS, SU_PORT_KBD, SU_PORT_PORT };
+static char *su_typev[] = { "???", "mouse", "kbd", "serial" };
+
+#define SU_PROPSIZE 128
+
X /*
X * serial.c saves memory when it allocates async_info upon first open.
X * We have parts of state structure together because we do call startup
@@ -107,8 +112,7 @@
X int line;
X int cflag;
X
- int kbd_node;
- int ms_node;
+ enum su_type port_type; /* Hookup type: e.g. mouse */
X int port_node;
X
X char name[16];
@@ -145,6 +149,18 @@
X unsigned long last_active; /* For async_struct, to be */
X };
X
+/*
+ * Scan status structure.
+ * "prop" is a local variable but it eats stack to keep it in each
+ * stack frame of a recursive procedure.
+ */
+struct su_probe_scan {
+ int msnode, kbnode; /* PROM nodes for mouse and keyboard */
+ int msx, kbx; /* minors for mouse and keyboard */
+ int devices; /* scan index */
+ char prop[SU_PROPSIZE];
+};
+
X static char *serial_name = "PCIO serial driver";
X static char serial_version[16];
X
@@ -223,8 +239,6 @@


X return 0;
X }
X

-#ifdef __sparc_v9__
-
X static inline
X unsigned int su_inb(struct su_struct *info, unsigned long offset)
X {
@@ -234,20 +248,7 @@
X static inline void
X su_outb(struct su_struct *info, unsigned long offset, int value)
X {
- outb(value, info->port + offset);
-}
-
-#else
-
-static inline
-unsigned int su_inb(struct su_struct *info, unsigned long offset)
-{
- return (unsigned int)(*(volatile unsigned char *)(info->port + offset));
-}
-
-static inline void
-su_outb(struct su_struct *info, unsigned long offset, int value)
-{
+#ifndef __sparc_v9__
X /*
X * MrCoffee has weird schematics: IRQ4 & P10(?) pins of SuperIO are
X * connected with a gate then go to SlavIO. When IRQ4 goes tristated
@@ -257,10 +258,9 @@
X * This problem is similar to what Alpha people suffer, see serial.c.
X */
X if (offset == UART_MCR) value |= UART_MCR_OUT2;
- *(volatile unsigned char *)(info->port + offset) = value;
-}
-
X #endif
+ outb(value, info->port + offset);
+}
X
X #define serial_in(info, off) su_inb(info, off)
X #define serial_inp(info, off) su_inb(info, off)
@@ -348,7 +348,7 @@
X
X do {
X ch = serial_inp(info, UART_RX);
- if (info->kbd_node) {
+ if (info->port_type == SU_PORT_KBD) {
X if(ch == SUNKBD_RESET) {
X l1a_state.kbd_id = 1;
X l1a_state.l1_down = 0;
@@ -529,7 +529,7 @@
X (status & UART_MSR_DCD))
X hardpps();
X #endif
- }
+ }
X if (status & UART_MSR_DCTS)
X icount->cts++;
X wake_up_interruptible(&info->delta_msr_wait);
@@ -775,7 +775,7 @@
X /*
X * Allocate the IRQ if necessary
X */
- if (info->kbd_node || info->ms_node) {
+ if (info->port_type != SU_PORT_PORT) {
X retval = request_irq(info->irq, su_kbd_ms_interrupt,
X SA_SHIRQ, info->name, info);
X } else {
@@ -956,7 +956,7 @@
X int bits;


X unsigned long flags;
X

- if (!info->kbd_node && !info->ms_node) {
+ if (info->port_type == SU_PORT_PORT) {
X if (!info->tty || !info->tty->termios)
X return;
X if (!info->port)
@@ -1133,9 +1133,9 @@
X struct su_struct *info = su_table;
X int lsr;
X
- if (!info->kbd_node)
+ if (!info->port_type != SU_PORT_KBD)
X ++info;
- if (!info)
+ if (!info->port_type != SU_PORT_KBD)
X return;
X
X do {
@@ -1151,9 +1151,9 @@
X {
X struct su_struct *info = su_table;
X
- if (!info->ms_node)
+ if (!info->port_type != SU_PORT_MS)
X ++info;
- if (!info)
+ if (!info->port_type != SU_PORT_MS)
X return;
X
X info->cflag &= ~(CBAUDEX | CBAUD);
@@ -2202,9 +2202,9 @@
X
X /*
X * ---------------------------------------------------------------------
- * su_init() and friends
+ * su_XXX_init() and friends
X *
- * su_init() is called at boot-time to initialize the serial driver.
+ * su_XXX_init() is called at boot-time to initialize the serial driver.
X * ---------------------------------------------------------------------
X */
X
@@ -2215,7 +2215,7 @@
X */
X __initfunc(static __inline__ void show_su_version(void))
X {
- char *revision = "$Revision: 1.19 $";
+ char *revision = "$Revision: 1.20 $";
X char *version, *p;
X
X version = strchr(revision, ' ');
@@ -2226,8 +2226,8 @@
X }
X
X /*
- * This routine is called by su_init() to initialize a specific serial
- * port. It determines what type of UART chip this serial port is
+ * This routine is called by su_{serial|kbd_ms}_init() to initialize a specific
+ * serial port. It determines what type of UART chip this serial port is
X * using: 8250, 16450, 16550, 16550A. The important question is
X * whether or not this UART is a 16550A, since this will determine
X * whether or not we can use its FIFO features.
@@ -2236,38 +2236,42 @@
X autoconfig(struct su_struct *info)
X {
X unsigned char status1, status2, scratch, scratch2;
-#ifdef __sparc_v9__
X struct linux_ebus_device *dev = 0;
X struct linux_ebus *ebus;
-#else
+#ifndef __sparc_v9__
X struct linux_prom_registers reg0;
X #endif


X unsigned long flags;
X

-#ifdef __sparc_v9__
+ if (!info->port_node || !info->port_type)


+ return;
+
+ /*

+ * First we look for Ebus-bases su's
+ */
X for_each_ebus(ebus) {
X for_each_ebusdev(dev, ebus) {
- if (!strncmp(dev->prom_name, "su", 2)) {
- if (dev->prom_node == info->kbd_node)
- goto ebus_done;
- if (dev->prom_node == info->ms_node)
- goto ebus_done;
+ if (dev->prom_node == info->port_node) {
+ info->port = dev->base_address[0];
+#ifdef __sparc_v9__
+ if (check_region(info->port, 8))
+ return;
+#endif
+ info->irq = dev->irqs[0];
+ goto ebus_done;
X }
X }
X }
-ebus_done:
- if (!dev)
- return;
-
- info->port = dev->base_address[0];
- if (check_region(info->port, 8))
- return;
X
- info->irq = dev->irqs[0];
+#ifdef __sparc_v9__
+ /*
+ * Not on Ebus, bailing.
+ */
+ return;
X #else
- if (!info->port_node)
- return;
-
+ /*
+ * Not on Ebus, must be OBIO.
+ */
X if (prom_getproperty(info->port_node, "reg",
X (char *)&reg0, sizeof(reg0)) == -1) {
X prom_printf("su: no \"reg\" property\n");
@@ -2279,21 +2283,24 @@
X prom_printf("su: cannot map\n");
X return;
X }
+
X /*
- * There is no intr property on MrCoffee, so hardwire it. Krups?
+ * There is no intr property on MrCoffee, so hardwire it.
X */
X info->irq = IRQ_4M(13);
X #endif
X
-#ifdef DEBUG_SERIAL_OPEN
- printk("Found 'su' at %016lx IRQ %s\n", dev->base_address[0],
- __irq_itoa(dev->irqs[0]));
+ebus_done:
+
+#ifdef SERIAL_DEBUG_OPEN
+ printk("Found 'su' at %016lx IRQ %s\n", info->port,
+ __irq_itoa(info->irq));
X #endif
X
X info->magic = SERIAL_MAGIC;
X
X save_flags(flags); cli();
-
+
X /*
X * Do a simple existence test first; if we fail this, there's
X * no point trying anything else.
@@ -2312,17 +2319,20 @@
X return; /* We failed; there's nothing here */
X }
X
-#if 0 /* P3: This does not work on MrCoffee. OUT2 is 0x80 - should work... */
X scratch = serial_inp(info, UART_MCR);
X serial_outp(info, UART_MCR, UART_MCR_LOOP | scratch);
X serial_outp(info, UART_MCR, UART_MCR_LOOP | 0x0A);
X status1 = serial_inp(info, UART_MSR) & 0xF0;
X serial_outp(info, UART_MCR, scratch);
X if (status1 != 0x90) {
+ /*
+ * This code fragment used to fail, now it fixed itself.
+ * We keep the printout for a case.
+ */
+ printk("su: loopback returned status 0x%02x\n", status1);
X restore_flags(flags);
X return;
X }
-#endif
X
X scratch2 = serial_in(info, UART_LCR);
X serial_outp(info, UART_LCR, 0xBF); /* set up for StarTech test */
@@ -2389,10 +2399,7 @@
X return;
X }
X
- if (info->kbd_node || info->ms_node)
- sprintf(info->name, "su(%s)", info->ms_node ? "mouse" : "kbd");
- else
- strcpy(info->name, "su(serial)");
+ sprintf(info->name, "su(%s)", su_typev[info->port_type]);
X
X #ifdef __sparc_v9__
X request_region(info->port, 8, info->name);
@@ -2494,13 +2501,16 @@
X info->tqueue.routine = do_softint;
X info->tqueue.data = info;
X info->cflag = serial_driver.init_termios.c_cflag;
+ init_waitqueue_head(&info->open_wait);
+ init_waitqueue_head(&info->close_wait);
+ init_waitqueue_head(&info->delta_msr_wait);
X
X autoconfig(info);
X if (info->type == PORT_UNKNOWN)
X continue;
X
- printk(KERN_INFO "%s at %16lx (irq = %s) is a %s\n",
- info->name, info->port, __irq_itoa(info->irq),
+ printk(KERN_INFO "%s at 0x%lx (tty %d irq %s) is a %s\n",
+ info->name, (long)info->port, i, __irq_itoa(info->irq),
X uart_config[info->type].name);
X }
X
@@ -2519,11 +2529,15 @@
X info->type = PORT_UNKNOWN;
X info->baud_base = BAUD_BASE;
X
- if (info->kbd_node)
+ if (info->port_type == SU_PORT_KBD)
X info->cflag = B1200 | CS8 | CLOCAL | CREAD;
X else
X info->cflag = B4800 | CS8 | CLOCAL | CREAD;
X
+ init_waitqueue_head(&info->open_wait);
+ init_waitqueue_head(&info->close_wait);
+ init_waitqueue_head(&info->delta_msr_wait);
+
X autoconfig(info);
X if (info->type == PORT_UNKNOWN)
X continue;
@@ -2533,7 +2547,7 @@
X uart_config[info->type].name);
X
X startup(info);
- if (info->kbd_node)
+ if (info->port_type == SU_PORT_KBD)
X keyboard_zsinit(su_put_char_kbd);
X else
X sun_mouse_zsinit();
@@ -2541,154 +2555,126 @@


X return 0;
X }
X

-__initfunc(int su_probe (unsigned long *memory_start))
+/*
+ * We got several platforms which present 'su' in different parts
+ * of device tree. 'su' may be found under obio, ebus, isa and pci.
+ * We walk over the tree and find them wherever PROM hides them.
+ */
+__initfunc(void su_probe_any(struct su_probe_scan *t, int sunode))
X {
- struct su_struct *info = su_table;


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

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

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.3/patch-2.3.6/part13

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


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

if test "$Scheck" != 13; 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.3.6'
else
echo 'x - continuing with patch-2.3.6'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.6' &&

X p->needsdtr_copy |= (1<<tindex);
X
- if (p->flags & AHC_SEEPROM_FOUND)
+ p->transinfo[tindex].goal_period = p->transinfo[tindex].user_period;
+ p->transinfo[tindex].goal_options = p->transinfo[tindex].user_options;
+ if (p->transinfo[tindex].user_offset)
X {
- p->transinfo[tindex].goal_period = p->transinfo[tindex].user_period;
- p->transinfo[tindex].goal_offset = p->transinfo[tindex].user_offset;
- }
- else
- {
- if (p->features & AHC_ULTRA2)
- {
- p->transinfo[tindex].goal_period =
- aic7xxx_syncrates[AHC_SYNCRATE_ULTRA2].period;
- }
- else if (p->features & AHC_ULTRA)
- {
- p->transinfo[tindex].goal_period =
- aic7xxx_syncrates[AHC_SYNCRATE_ULTRA].period;
- }
- else
- {
- p->transinfo[tindex].goal_period =
- aic7xxx_syncrates[AHC_SYNCRATE_FAST].period;
- }
X if (p->features & AHC_ULTRA2)
X p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
X else if (p->transinfo[tindex].goal_width == MSG_EXT_WDTR_BUS_16_BIT)
@@ -2952,14 +2931,57 @@
X p->needsdtr_copy &= ~(1<<tindex);
X p->transinfo[tindex].goal_period = 0;
X p->transinfo[tindex].goal_offset = 0;
+ p->transinfo[tindex].goal_options = 0;
+ }
+ if ( (buffer[2] & SCSI_VERSION_BITS) == 3 )
+ {
+ p->dev_flags[tindex] |= DEVICE_SCSI_3;
+ /*
+ * OK, we are a SCSI 3 device and we are in need of negotiation.
+ * Use PPR messages instead of WDTR and SDTR messages.
+ */
+ if ( (p->needsdtr & (1<<tindex)) ||
+ (p->needwdtr & (1<<tindex)) )
+ {
+ p->needppr |= (1<<tindex);
+ p->needppr_copy |= (1<<tindex);
+ }
+ p->needwdtr &= ~(1<<tindex);
+ p->needwdtr_copy &= ~(1<<tindex);
+ p->needsdtr &= ~(1<<tindex);
+ p->needsdtr_copy &= ~(1<<tindex);
+ }
+ /*
+ * Get the INQUIRY checksum. We use this on Ultra 160/m
+ * and older devices both. It allows us to drop speed on any bus type
+ * while at the same time giving us the needed domain validation for
+ * Ultra 160/m
+ *
+ * Note: We only get the checksum and set the SCANNED bit if this is
+ * one of our dtr commands. If we don't do this, then we end up
+ * getting bad checksum results on the mid-level SCSI code's INQUIRY
+ * commands.
+ */
+ if(p->dev_dtr_cmnd[tindex] == cmd) {
+ unsigned int checksum = 0;
+ int *ibuffer;
+ int i=0;
+
+ ibuffer = (int *)buffer;
+ for( i = 0; i < (cmd->request_bufflen >> 2); i++)
+ {
+ checksum += ibuffer[i];
+ }
+ p->dev_checksum[tindex] = checksum;
+ p->dev_flags[tindex] |= DEVICE_SCANNED;
+ p->dev_flags[tindex] |= DEVICE_PRINT_DTR;
X }
- p->dev_flags[tindex] |= DEVICE_SCANNED;
- p->dev_flags[tindex] |= DEVICE_PRINT_WDTR | DEVICE_PRINT_SDTR;
X #undef WIDE_INQUIRY_BITS
X #undef SYNC_INQUIRY_BITS
+#undef SCSI_VERSION_BITS
X }
X }
- else if ((scb->flags & (SCB_MSGOUT_WDTR | SCB_MSGOUT_SDTR)) != 0)
+ else if ((scb->flags & SCB_MSGOUT_BITS) != 0)
X {
X unsigned short mask;
X int message_error = FALSE;
@@ -2979,11 +3001,11 @@
X
X if (scb->flags & SCB_MSGOUT_WDTR)
X {
- p->wdtr_pending &= ~mask;
+ p->dtr_pending &= ~mask;
X if (message_error)
X {
X if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
- (p->dev_flags[tindex] & DEVICE_PRINT_WDTR) )
+ (p->dev_flags[tindex] & DEVICE_PRINT_DTR) )
X {
X printk(INFO_LEAD "Device failed to complete Wide Negotiation "
X "processing and\n", p->host_no, CTL_OF_SCB(scb));
@@ -2991,7 +3013,6 @@
X "disabling future\n", p->host_no, CTL_OF_SCB(scb));
X printk(INFO_LEAD "Wide negotiation to this device.\n", p->host_no,
X CTL_OF_SCB(scb));
- p->dev_flags[tindex] &= ~DEVICE_PRINT_WDTR;
X }
X p->needwdtr &= ~mask;
X p->needwdtr_copy &= ~mask;
@@ -2999,11 +3020,11 @@
X }
X if (scb->flags & SCB_MSGOUT_SDTR)
X {
- p->sdtr_pending &= ~mask;
+ p->dtr_pending &= ~mask;
X if (message_error)
X {
X if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
- (p->dev_flags[tindex] & DEVICE_PRINT_SDTR) )
+ (p->dev_flags[tindex] & DEVICE_PRINT_DTR) )
X {
X printk(INFO_LEAD "Device failed to complete Sync Negotiation "
X "processing and\n", p->host_no, CTL_OF_SCB(scb));
@@ -3011,12 +3032,38 @@
X "disabling future\n", p->host_no, CTL_OF_SCB(scb));
X printk(INFO_LEAD "Sync negotiation to this device.\n", p->host_no,
X CTL_OF_SCB(scb));
- p->dev_flags[tindex] &= ~DEVICE_PRINT_SDTR;
+ p->dev_flags[tindex] &= ~DEVICE_PRINT_DTR;
X }
X p->needsdtr &= ~mask;
X p->needsdtr_copy &= ~mask;
X }
X }
+ if (scb->flags & SCB_MSGOUT_PPR)
+ {
+ p->dtr_pending &= ~mask;
+ if(message_error)
+ {
+ if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
+ (p->dev_flags[tindex] & DEVICE_PRINT_DTR) )
+ {
+ printk(INFO_LEAD "Device failed to complete Parallel Protocol "
+ "Request processing and\n", p->host_no, CTL_OF_SCB(scb));
+ printk(INFO_LEAD "returned a sense error code for invalid message, "
+ "disabling future\n", p->host_no, CTL_OF_SCB(scb));
+ printk(INFO_LEAD "Parallel Protocol Request negotiation to this "
+ "device.\n", p->host_no, CTL_OF_SCB(scb));
+ }
+ /*
+ * Disable PPR negotiation and revert back to WDTR and SDTR setup
+ */
+ p->needppr &= ~mask;
+ p->needppr_copy &= ~mask;
+ p->needsdtr |= mask;
+ p->needsdtr_copy |= mask;
+ p->needwdtr |= mask;
+ p->needwdtr_copy |= mask;
+ }
+ }
X }
X queue_depth = p->dev_temp_queue_depth[tindex];
X if (queue_depth >= p->dev_active_cmds[tindex])
@@ -3058,16 +3105,6 @@
X p->dev_active_cmds[tindex]--;
X p->activescbs--;
X
- /*
- * If this was an untagged I/O, unbusy the target so the sequencer won't
- * mistake things later
- */
- if (aic7xxx_index_busy_target(p, scb->hscb->target_channel_lun, FALSE) ==
- scb->hscb->tag)
- {
- aic7xxx_index_busy_target(p, scb->hscb->target_channel_lun, TRUE);
- }
-
X {
X int actual;
X
@@ -3122,7 +3159,7 @@
X #endif /* AIC7XXX_PROC_STATS */
X }
X #ifdef AIC7XXX_PROC_STATS
- x = -10;
+ x = -11;
X while(actual)
X {
X actual >>= 1;
@@ -3429,11 +3466,10 @@
X if (aic7xxx_verbose & (VERBOSE_ABORT_PROCESS | VERBOSE_RESET_PROCESS))
X printk(INFO_LEAD "Cleaning up status information "
X "and delayed_scbs.\n", p->host_no, channel, i, lun);
- p->dev_flags[i] &= ~BUS_DEVICE_RESET_PENDING;
+ p->dev_flags[i] &= ~(BUS_DEVICE_RESET_PENDING | DEVICE_PARITY_ERROR);
X if ( tag == SCB_LIST_NULL )
X {
- p->dev_flags[i] |= DEVICE_PRINT_WDTR | DEVICE_PRINT_SDTR |
- DEVICE_RESET_DELAY;
+ p->dev_flags[i] |= DEVICE_PRINT_DTR | DEVICE_RESET_DELAY;
X p->dev_expires[i] = jiffies + (4 * HZ);
X p->dev_timer_active |= (0x01 << i);
X p->dev_last_queue_full_count[i] = 0;
@@ -3625,7 +3661,7 @@
X if (aic7xxx_verbose & (VERBOSE_ABORT_PROCESS | VERBOSE_RESET_PROCESS))
X printk(INFO_LEAD "Cleaning disconnected scbs "
X "list.\n", p->host_no, channel, target, lun);
- if (p->features & AHC_PAGESCBS)
+ if (p->flags & AHC_PAGESCBS)
X {
X unsigned char next, prev, scb_index;
X
@@ -3641,14 +3677,14 @@
X printk(WARN_LEAD "Disconnected List inconsistency; SCB index=%d, "
X "numscbs=%d\n", p->host_no, channel, target, lun, scb_index,
X p->scb_data->numscbs);
- next = aic7xxx_rem_scb_from_disc_list(p, next);
+ next = aic7xxx_rem_scb_from_disc_list(p, next, prev);
X }
X else
X {
X scbp = p->scb_data->scb_array[scb_index];
X if (aic7xxx_match_scb(p, scbp, target, channel, lun, tag))
X {
- next = aic7xxx_rem_scb_from_disc_list(p, next);
+ next = aic7xxx_rem_scb_from_disc_list(p, next, prev);
X if (scbp->flags & SCB_WAITINGQ)
X {
X p->dev_active_cmds[TARGET_INDEX(scbp->cmd)]++;
@@ -3677,7 +3713,7 @@
X * Walk the free list making sure no entries on the free list have
X * a valid SCB_TAG value or SCB_CONTROL byte.
X */
- if (p->features & AHC_PAGESCBS)
+ if (p->flags & AHC_PAGESCBS)
X {
X unsigned char next;
X
@@ -3734,7 +3770,6 @@
X {
X aic_outb(p, SCB_LIST_NULL, SCB_TAG);
X aic_outb(p, SCB_LIST_NULL, SCB_NEXT);
- aic_outb(p, SCB_LIST_NULL, SCB_PREV);
X aic_outb(p, 0, SCB_CONTROL);
X aic7xxx_add_curscb_to_free_list(p);
X }
@@ -3863,28 +3898,35 @@
X if (channel == 1)
X {
X p->needsdtr |= (p->needsdtr_copy & 0xFF00);
- p->sdtr_pending &= 0x00FF;
+ p->dtr_pending &= 0x00FF;
X offset_min = 8;
X offset_max = 16;
X }
X else
X {
- if (p->features & AHC_WIDE)
+ if (p->features & AHC_TWIN)
X {
- p->needsdtr = p->needsdtr_copy;
- p->needwdtr = p->needwdtr_copy;
- p->sdtr_pending = 0x0;
- p->wdtr_pending = 0x0;
+ /* Channel A */
+ p->needsdtr |= (p->needsdtr_copy & 0x00FF);
+ p->dtr_pending &= 0xFF00;
X offset_min = 0;
- offset_max = 16;
+ offset_max = 8;
X }
X else
X {
- /* Channel A */
- p->needsdtr |= (p->needsdtr_copy & 0x00FF);
- p->sdtr_pending &= 0xFF00;
+ p->needppr = p->needppr_copy;
+ p->needsdtr = p->needsdtr_copy;
+ p->needwdtr = p->needwdtr_copy;
+ p->dtr_pending = 0x0;
X offset_min = 0;
- offset_max = 8;
+ if (p->features & AHC_WIDE)
+ {
+ offset_max = 16;
+ }
+ else
+ {
+ offset_max = 8;
+ }
X }
X }
X
@@ -4188,6 +4230,30 @@
X
X /*+F*************************************************************************
X * Function:
+ * aic7xxx_construct_ppr
+ *
+ * Description:
+ * Build up a Parallel Protocol Request message for use with SCSI-3
+ * devices.
+ *-F*************************************************************************/
+static void
+aic7xxx_construct_ppr(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
+{
+ int tindex = TARGET_INDEX(scb->cmd);
+
+ p->msg_buf[p->msg_index++] = MSG_EXTENDED;
+ p->msg_buf[p->msg_index++] = MSG_EXT_PPR_LEN;
+ p->msg_buf[p->msg_index++] = MSG_EXT_PPR;
+ p->msg_buf[p->msg_index++] = p->transinfo[tindex].goal_period;
+ p->msg_buf[p->msg_index++] = 0;
+ p->msg_buf[p->msg_index++] = p->transinfo[tindex].goal_offset;
+ p->msg_buf[p->msg_index++] = p->transinfo[tindex].goal_width;
+ p->msg_buf[p->msg_index++] = p->transinfo[tindex].goal_options;
+ p->msg_len += 8;
+}
+
+/*+F*************************************************************************
+ * Function:
X * aic7xxx_construct_sdtr
X *
X * Description:
@@ -4304,10 +4370,10 @@
X /*
X * Go back to async/narrow transfers and renegotiate.
X */
+ p->needppr |= (p->needppr_copy & targ_mask);
X p->needsdtr |= (p->needsdtr_copy & targ_mask);
X p->needwdtr |= (p->needwdtr_copy & targ_mask);
- p->sdtr_pending &= ~targ_mask;
- p->wdtr_pending &= ~targ_mask;
+ p->dtr_pending &= ~targ_mask;
X aic_outb(p, 0, TARG_SCSIRATE + tindex);
X if (p->features & AHC_ULTRA2)
X aic_outb(p, 0, TARG_OFFSET + tindex);
@@ -4315,7 +4381,7 @@
X if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
X printk(INFO_LEAD "Bus Device Reset delivered.\n", p->host_no, channel,
X target, -1);
- aic7xxx_run_done_queue(p, /*complete*/ FALSE);
+ aic7xxx_run_done_queue(p, /*complete*/ TRUE);
X }
X
X /*+F*************************************************************************
@@ -4360,6 +4426,8 @@
X p->host_no, channel, target, lun,
X aic_inb(p, SAVED_TCL), aic_inb(p, ARG_1),
X (aic_inb(p, SEQADDR1) << 8) | aic_inb(p, SEQADDR0));
+ if (aic7xxx_panic_on_abort)
+ aic7xxx_panic_abort(p, NULL);
X }
X break;
X
@@ -4387,7 +4455,7 @@
X lun, aic_inb(p, LASTPHASE), aic_inb(p, SAVED_TCL));
X
X aic7xxx_reset_channel(p, channel, /*initiate reset*/ TRUE);
- aic7xxx_run_done_queue(p, FALSE);
+ aic7xxx_run_done_queue(p, TRUE);
X
X }
X break;
@@ -4517,7 +4585,7 @@
X aic7xxx_reset_device(p, target, channel, lun, i);
X reset++;
X }
- aic7xxx_run_done_queue(p, FALSE);
+ aic7xxx_run_done_queue(p, TRUE);
X }
X }
X aic7xxx_verbose = old_verbose;
@@ -4533,6 +4601,51 @@
X aic_outb(p, aic_inb(p, SCSISIGI) | ATNO, SCSISIGO);
X }
X }
+ else if (scb->flags & SCB_MSGOUT_PPR)
+ {
+ /*
+ * As per the draft specs, any device capable of supporting any of
+ * the option values other than 0 are not allowed to reject the
+ * PPR message. Instead, they must negotiate out what they do
+ * support instead of rejecting our offering.
+ */
+ p->needppr &= ~target_mask;
+ p->needppr_copy &= ~target_mask;
+ aic7xxx_set_width(p, target, channel, lun, MSG_EXT_WDTR_BUS_8_BIT,
+ (AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE));
+ aic7xxx_set_syncrate(p, NULL, target, channel, 0, 0, 0,
+ AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE);
+ p->transinfo[tindex].goal_options = 0;
+ p->dtr_pending &= ~target_mask;
+ scb->flags &= ~SCB_MSGOUT_BITS;
+ if(aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+ {
+ printk(INFO_LEAD "Device is rejecting PPR messages, falling "
+ "back.\n", p->host_no, channel, target, lun);
+ }
+ if ( p->transinfo[tindex].goal_width )
+ {
+ p->needwdtr |= target_mask;
+ p->needwdtr_copy |= target_mask;
+ p->dtr_pending |= target_mask;
+ scb->flags |= SCB_MSGOUT_WDTR;
+ }
+ if ( p->transinfo[tindex].goal_offset )
+ {
+ p->needsdtr |= target_mask;
+ p->needsdtr_copy |= target_mask;
+ if( !(p->dtr_pending & target_mask) )
+ {
+ p->dtr_pending |= target_mask;
+ scb->flags |= SCB_MSGOUT_SDTR;
+ }
+ }
+ if ( p->dtr_pending & target_mask )
+ {
+ aic_outb(p, HOST_MSG, MSG_OUT);
+ aic_outb(p, aic_inb(p, SCSISIGI) | ATNO, SCSISIGO);
+ }
+ }
X else if (scb->flags & SCB_MSGOUT_WDTR)
X {
X /*
@@ -4540,20 +4653,18 @@
X */
X p->needwdtr &= ~target_mask;
X p->needwdtr_copy &= ~target_mask;
- p->wdtr_pending &= ~target_mask;
+ p->dtr_pending &= ~target_mask;
X scb->flags &= ~SCB_MSGOUT_BITS;
X aic7xxx_set_width(p, target, channel, lun, MSG_EXT_WDTR_BUS_8_BIT,
X (AHC_TRANS_ACTIVE|AHC_TRANS_GOAL|AHC_TRANS_CUR));
- aic7xxx_set_syncrate(p, NULL, target, channel, 0, 0,
+ aic7xxx_set_syncrate(p, NULL, target, channel, 0, 0, 0,
X AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE);
- if ( (p->needsdtr_copy & target_mask) &&
- !(p->sdtr_pending & target_mask) )
+ if(aic7xxx_verbose & VERBOSE_NEGOTIATION2)
X {
- p->sdtr_pending |= target_mask;
- scb->flags |= SCB_MSGOUT_SDTR;
- aic_outb(p, HOST_MSG, MSG_OUT);
- aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
+ printk(INFO_LEAD "Device is rejecting WDTR messages, using "
+ "narrow transfers.\n", p->host_no, channel, target, lun);
X }
+ p->needsdtr |= (p->needsdtr_copy & target_mask);
X }
X else if (scb->flags & SCB_MSGOUT_SDTR)
X {
@@ -4562,10 +4673,15 @@
X */
X p->needsdtr &= ~target_mask;
X p->needsdtr_copy &= ~target_mask;
- p->sdtr_pending &= ~target_mask;
+ p->dtr_pending &= ~target_mask;
X scb->flags &= ~SCB_MSGOUT_SDTR;
- aic7xxx_set_syncrate(p, NULL, target, channel, 0, 0,
+ aic7xxx_set_syncrate(p, NULL, target, channel, 0, 0, 0,
X (AHC_TRANS_CUR|AHC_TRANS_ACTIVE|AHC_TRANS_GOAL));
+ if(aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+ {
+ printk(INFO_LEAD "Device is rejecting SDTR messages, using "
+ "async transfers.\n", p->host_no, channel, target, lun);
+ }
X }
X else if (aic7xxx_verbose & VERBOSE_SEQINT)
X {
@@ -4681,41 +4797,24 @@
X * However, if this SCB already was attempting to negotiate,
X * then we assume this isn't the problem and skip this part.
X */
-#ifdef AIC7XXX_FAKE_NEGOTIATION_CMDS
X if ( (scb->cmd->cmnd[0] != TEST_UNIT_READY) &&
X (p->dev_flags[tindex] & DEVICE_SCANNED) &&
- !(p->wdtr_pending & target_mask) &&
- !(p->sdtr_pending & target_mask) )
+ !(p->dtr_pending & target_mask) )
X {
+ p->needppr |= (p->needppr_copy & target_mask);
X p->needwdtr |= (p->needwdtr_copy & target_mask);
X p->needsdtr |= (p->needsdtr_copy & target_mask);
X }
- else if ( (scb->cmd == p->dev_wdtr_cmnd[tindex]) ||
- (scb->cmd == p->dev_sdtr_cmnd[tindex]) )
+ else if ( scb->cmd == p->dev_dtr_cmnd[tindex] )
X {
X /*
X * This is already a negotiation command, so we must have
- * already done either WDTR or SDTR (or maybe both). So
- * we simply check sdtr_pending and needsdtr to see if we
- * should throw out SDTR on this command.
- *
- * Note: Don't check the needsdtr_copy here, instead just
- * check to see if WDTR wiped out our SDTR and set needsdtr.
- * Even if WDTR did wipe out SDTR and set needsdtr, if
- * parse_msg() then turned around and started our SDTR
- * in back to back fasion, then conclusion of that should
- * have negated any needsdtr setting. That's why we only
- * check needsdtr and sdtr_pending.
+ * already done PPR, WDTR or SDTR. Since our negotiation
+ * could have gotten rejected, we don't really know the
+ * full state of things. Don't do anything here, and allow
+ * the negotiation_complete() handler to do the right
+ * thing.
X */
- scb->flags &= ~SCB_MSGOUT_BITS;
- if ( (scb->cmd == p->dev_wdtr_cmnd[tindex]) &&
- !(p->sdtr_pending & target_mask) &&
- (p->needsdtr & target_mask) )
- {
- p->sdtr_pending |= target_mask;
- hscb->control |= MK_MESSAGE;
- scb->flags |= SCB_MSGOUT_SDTR;
- }
X
X /*
X * This is the important part though. We are getting sense
@@ -4736,43 +4835,13 @@
X hscb->data_pointer = scb->sg_list[0].address;
X }
X }
-#else
- if ( (scb->cmd->cmnd[0] != TEST_UNIT_READY) &&
- !(scb->flags & SCB_MSGOUT_BITS) &&
- (scb->cmd->lun == 0) &&
- (p->dev_flags[TARGET_INDEX(scb->cmd)] & DEVICE_SCANNED) )
- {
- if ( (p->needwdtr_copy & target_mask) &&
- !(p->wdtr_pending & target_mask) &&
- !(p->sdtr_pending & target_mask) )
- {
- p->needwdtr |= target_mask;
- p->wdtr_pending |= target_mask;
- hscb->control |= MK_MESSAGE;
- scb->flags |= SCB_MSGOUT_WDTR;
- }
- if ( p->needsdtr_copy & target_mask )
- {
- p->needsdtr |= target_mask;
- if ( !(p->wdtr_pending & target_mask) &&
- !(p->sdtr_pending & target_mask) )
- {
- p->sdtr_pending |= target_mask;
- hscb->control |= MK_MESSAGE;
- scb->flags |= SCB_MSGOUT_SDTR;
- }
- }
- }
- else
- scb->flags &= ~SCB_MSGOUT_BITS;
-#endif /* AIC7XXX_FAKE_NEGOTIATION_CMDS */
X scb->flags |= SCB_SENSE;
X /*
X * Ensure the target is busy since this will be an
X * an untagged request.
X */
X #ifdef AIC7XXX_VERBOSE_DEBUGGING
- if (aic7xxx_verbose > 0xffff)
+ if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
X {
X if (scb->flags & SCB_MSGOUT_BITS)
X printk(INFO_LEAD "Requesting SENSE with %s\n", p->host_no,
@@ -4914,7 +4983,8 @@
X }
X }
X #ifdef AIC7XXX_VERBOSE_DEBUGGING
- if (aic7xxx_verbose & VERBOSE_MINOR_ERROR)
+ if( (aic7xxx_verbose & VERBOSE_MINOR_ERROR) ||
+ (aic7xxx_verbose > 0xffff) )
X {
X if (queue_flag)
X printk(INFO_LEAD "Queue full received; queue depth %d, "
@@ -4928,8 +4998,6 @@
X #endif
X if (queue_flag)
X {
- p->dev_temp_queue_depth[tindex] =
- p->dev_active_cmds[tindex];
X if ( p->dev_last_queue_full[tindex] !=
X p->dev_active_cmds[tindex] )
X {
@@ -4951,10 +5019,28 @@
X p->dev_active_cmds[tindex];
X p->dev_last_queue_full[tindex] = 0;
X p->dev_last_queue_full_count[tindex] = 0;
+ p->dev_temp_queue_depth[tindex] =
+ p->dev_active_cmds[tindex];
+ }
+ else if (p->dev_active_cmds[tindex] == 0)
+ {
+ if (aic7xxx_verbose & VERBOSE_NEGOTIATION)
+ {
+ printk(INFO_LEAD "QUEUE_FULL status received with 0 "
+ "commands active.\n", p->host_no, CTL_OF_SCB(scb));
+ printk(INFO_LEAD "Tagged Command Queueing disabled\n",
+ p->host_no, CTL_OF_SCB(scb));
+ }
+ p->dev_max_queue_depth[tindex] = 1;
+ p->dev_temp_queue_depth[tindex] = 1;
+ scb->tag_action = 0;
+ scb->hscb->control &= ~(MSG_ORDERED_Q_TAG|MSG_SIMPLE_Q_TAG);
X }
X else
X {
X p->dev_flags[tindex] |= DEVICE_WAS_BUSY;
+ p->dev_temp_queue_depth[tindex] =
+ p->dev_active_cmds[tindex];
X }
X }
X break;
@@ -4989,7 +5075,7 @@
X */
X
X if ( !(scb->flags & SCB_DEVICE_RESET) &&
- (aic_inb(p, MSG_OUT) == MSG_IDENTIFYFLAG) &&
+ (msg_out == MSG_IDENTIFYFLAG) &&
X (scb->hscb->control & TAG_ENB) )
X {
X p->msg_buf[p->msg_index++] = scb->tag_action;
@@ -5020,34 +5106,68 @@
X printk(INFO_LEAD "Abort message mailed.\n", p->host_no,
X CTL_OF_SCB(scb));
X }
- else if (scb->flags & SCB_MSGOUT_WDTR)
+ else if (scb->flags & SCB_MSGOUT_PPR)
X {
-#ifdef AIC7XXX_VERBOSE_DEBUGGING
- if (aic7xxx_verbose > 0xffff)
+ unsigned int max_sync, period;
+ unsigned char options = p->transinfo[tindex].goal_options;
+
+ if (p->features & AHC_ULTRA2)
+ {
+ if ( (aic_inb(p, SBLKCTL) & ENAB40) &&
+ !(aic_inb(p, SSTAT2) & EXP_ACTIVE) )
+ {
+ if( (p->features & AHC_ULTRA3) &&
+ (p->dev_flags[tindex] & DEVICE_SCSI_3) &&
+ (p->transinfo[tindex].goal_width ==
+ MSG_EXT_WDTR_BUS_16_BIT) &&
+ (options != 0) )
+ {
+ max_sync = AHC_SYNCRATE_ULTRA3;
+ }
+ else
+ {
+ max_sync = AHC_SYNCRATE_ULTRA2;
+ }
+ }
+ else
+ {
+ max_sync = AHC_SYNCRATE_ULTRA;
+ }
+ }
+ else if (p->features & AHC_ULTRA)
+ {
+ max_sync = AHC_SYNCRATE_ULTRA;
+ }
+ else
+ {
+ max_sync = AHC_SYNCRATE_FAST;
+ }
+ period = p->transinfo[tindex].goal_period;
+ aic7xxx_find_syncrate(p, &period, max_sync, &options);
+ p->transinfo[tindex].goal_period = period;
+ p->transinfo[tindex].goal_options = options;
+ if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+ {
+ printk(INFO_LEAD "Sending PPR (%d/%d/%d/%d) message.\n",
+ p->host_no, CTL_OF_SCB(scb), period,
+ p->transinfo[tindex].goal_offset,
+ p->transinfo[tindex].goal_width, options);
+ }
+ aic7xxx_construct_ppr(p, scb);
+ }
+ else if (scb->flags & SCB_MSGOUT_WDTR)
+ {
+ if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+ {
X printk(INFO_LEAD "Sending WDTR message.\n", p->host_no,
X CTL_OF_SCB(scb));
-#endif
- aic7xxx_construct_wdtr(p,
- p->transinfo[TARGET_INDEX(scb->cmd)].goal_width);
+ }
+ aic7xxx_construct_wdtr(p, p->transinfo[tindex].goal_width);
X }
X else if (scb->flags & SCB_MSGOUT_SDTR)
X {
X unsigned int max_sync, period;
- /*
- * We need to set an accurate goal_offset instead of
- * the ridiculously high one we default to. We should
- * now know if we are wide. Plus, the WDTR code will
- * set our goal_offset for us as well.
- */
- if (p->transinfo[tindex].goal_offset)
- {
- if (p->features & AHC_ULTRA2)
- p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
- else if (p->transinfo[tindex].cur_width == MSG_EXT_WDTR_BUS_16_BIT)
- p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
- else
- p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
- }
+ unsigned char options = 0;
X /*
X * Now that the device is selected, use the bits in SBLKCTL and
X * SSTAT2 to determine the max sync rate for this device.
@@ -5073,14 +5193,14 @@
X max_sync = AHC_SYNCRATE_FAST;
X }
X period = p->transinfo[tindex].goal_period;
- aic7xxx_find_syncrate(p, &period, max_sync);
-#ifdef AIC7XXX_VERBOSE_DEBUGGING
- if (aic7xxx_verbose > 0xffff)
+ aic7xxx_find_syncrate(p, &period, max_sync, &options);
+ if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+ {
X printk(INFO_LEAD "Sending SDTR %d/%d message.\n", p->host_no,
X CTL_OF_SCB(scb),
X p->transinfo[tindex].goal_period,
X p->transinfo[tindex].goal_offset);
-#endif
+ }
X aic7xxx_construct_sdtr(p, period,
X p->transinfo[tindex].goal_offset);
X }
@@ -5154,15 +5274,15 @@
X #if AIC7XXX_NOT_YET
X case TRACEPOINT:
X {
- printk(INFO_LEAD "Tracepoint #1 reached.\n", p->host_no, channel,
- target, lun);
+ printk(INFO_LEAD "Tracepoint #1 reached.\n", p->host_no,
+ channel, target, lun);
X }
X break;
X
X case TRACEPOINT2:
X {
- printk(INFO_LEAD "Tracepoint #2 reached.\n", p->host_no, channel,
- target, lun);
+ printk(INFO_LEAD "Tracepoint #2 reached.\n", p->host_no,
+ channel, target, lun);
X }
X break;
X
@@ -5237,7 +5357,7 @@
X case MSG_EXT_SDTR:
X {
X unsigned int period, offset;
- unsigned char maxsync, saved_offset;
+ unsigned char maxsync, saved_offset, options;
X struct aic7xxx_syncrate *syncrate;
X
X if (p->msg_buf[1] != MSG_EXT_SDTR_LEN)
@@ -5253,7 +5373,13 @@
X
X period = p->msg_buf[3];
X saved_offset = offset = p->msg_buf[4];
+ options = 0;
X
+ /*
+ * Even if we are an Ultra3 card, don't allow Ultra3 sync rates when
+ * using the SDTR messages. We need the PPR messages to enable the
+ * higher speeds that include things like Dual Edge clocking.
+ */
X if (p->features & AHC_ULTRA2)
X {
X if ( (aic_inb(p, SBLKCTL) & ENAB40) &&
@@ -5283,7 +5409,9 @@
X if ( (scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) !=
X (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR) )
X {
- if (!(p->dev_flags[tindex] & DEVICE_SCANNED))
+ if (!(p->dev_flags[tindex] & DEVICE_SCANNED) &&
+ !(p->needsdtr_copy & target_mask) &&
+ (p->transinfo[tindex].user_offset) )
X {
X /*
X * Not only is the device starting this up, but it also hasn't
@@ -5295,38 +5423,49 @@
X */
X p->transinfo[tindex].goal_period =
X p->transinfo[tindex].user_period;
- p->transinfo[tindex].goal_offset =
- p->transinfo[tindex].user_offset;
+ if(p->features & AHC_ULTRA2)
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
+ }
+ else if (p->transinfo[tindex].cur_width)
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
+ }
+ else
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
+ }
X p->needsdtr_copy |= target_mask;
X }
+ if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+ {
+ printk(INFO_LEAD "Received pre-emptive SDTR message from "
+ "target.\n", p->host_no, CTL_OF_SCB(scb));
+ }
X if ( !p->transinfo[tindex].goal_offset )
X period = 255;
X if ( p->transinfo[tindex].goal_period > period )
X period = p->transinfo[tindex].goal_period;
X }
X
- syncrate = aic7xxx_find_syncrate(p, &period, maxsync);
+ syncrate = aic7xxx_find_syncrate(p, &period, maxsync, &options);
X aic7xxx_validate_offset(p, syncrate, &offset,
X target_scsirate & WIDEXFER);
X aic7xxx_set_syncrate(p, syncrate, target, channel, period,
- offset, AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
+ offset, options, AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
X
X /*
- * Did we drop to async? If so, are we sending a reply? If we are,
+ * Did we drop to async? Or are we sending a reply? If we are,
X * then we have to make sure that the reply value reflects the proper
X * settings so we need to set the goal values according to what
X * we need to send.
X */
- if ( (offset == 0) || (offset != saved_offset) ||
+ if ( (offset != saved_offset) ||
X ((scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) !=
X (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR) ) )
X {
- aic7xxx_set_syncrate(p, syncrate, target, channel, period,
- offset, AHC_TRANS_GOAL|AHC_TRANS_QUITE);
- if ( offset == 0 )
- {
- p->needsdtr_copy &= ~target_mask;
- }
+ aic7xxx_set_syncrate(p, syncrate, target, channel, period, offset,
+ options, AHC_TRANS_GOAL|AHC_TRANS_QUITE);
X }
X
X /*
@@ -5334,15 +5473,13 @@
X * go async, then send an SDTR back to the target
X */
X p->needsdtr &= ~target_mask;
- p->sdtr_pending &= ~target_mask;
- if ( ((scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) ==
- (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) &&
- (offset == saved_offset) )
- {
- scb->flags &= ~SCB_MSGOUT_BITS;
- }
- else
+ p->dtr_pending &= ~target_mask;
+ if ( ((scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) !=
+ (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) ||
+ (offset != saved_offset) )
X {
+ reply = TRUE;
+ p->dtr_pending |= target_mask;
X scb->flags &= ~SCB_MSGOUT_BITS;
X scb->flags |= SCB_MSGOUT_SDTR;
X aic_outb(p, HOST_MSG, MSG_OUT);
@@ -5376,12 +5513,11 @@
X {
X reject = TRUE;
X if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
- ((p->dev_flags[tindex] & DEVICE_PRINT_WDTR) ||
+ ((p->dev_flags[tindex] & DEVICE_PRINT_DTR) ||
X (aic7xxx_verbose > 0xffff)) )
X {
X printk(INFO_LEAD "Requesting %d bit transfers, rejecting.\n",
X p->host_no, CTL_OF_SCB(scb), 8 * (0x01 << bus_width));
- p->dev_flags[tindex] &= ~DEVICE_PRINT_WDTR;
X }
X } /* We fall through on purpose */
X case MSG_EXT_WDTR_BUS_8_BIT:
@@ -5395,15 +5531,11 @@
X break;
X }
X }
- scb->flags &= ~SCB_MSGOUT_BITS;
- p->wdtr_pending &= ~target_mask;
+ p->dtr_pending &= ~target_mask;
X p->needwdtr &= ~target_mask;
X }
X else
X {
- scb->flags &= ~SCB_MSGOUT_BITS;
- scb->flags |= SCB_MSGOUT_WDTR;
- reply = TRUE;
X if ( !(p->dev_flags[tindex] & DEVICE_SCANNED) )
X {
X /*
@@ -5413,13 +5545,33 @@
X */
X p->transinfo[tindex].goal_period =
X p->transinfo[tindex].user_period;
- p->transinfo[tindex].goal_offset =
- p->transinfo[tindex].user_offset;
+ if(p->transinfo[tindex].user_offset)
+ {
+ if(p->features & AHC_ULTRA2)
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
+ }
+ else if( p->transinfo[tindex].user_width &&
+ (bus_width == MSG_EXT_WDTR_BUS_16_BIT) &&
+ p->features & AHC_WIDE )
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
+ }
+ else
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
+ }
+ }
X p->transinfo[tindex].goal_width =
X p->transinfo[tindex].user_width;
X p->needwdtr_copy |= target_mask;
X p->needsdtr_copy |= target_mask;
X }
+ if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+ {
+ printk(INFO_LEAD "Received pre-emptive WDTR message from "
+ "target.\n", p->host_no, CTL_OF_SCB(scb));
+ }
X switch(bus_width)
X {
X default:
@@ -5441,8 +5593,11 @@
X break;
X }
X }
+ reply = TRUE;
+ scb->flags &= ~SCB_MSGOUT_BITS;
+ scb->flags |= SCB_MSGOUT_WDTR;
X p->needwdtr &= ~target_mask;
- p->wdtr_pending &= ~target_mask;
+ p->dtr_pending |= target_mask;
X aic_outb(p, HOST_MSG, MSG_OUT);
X aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
X }
@@ -5456,24 +5611,211 @@
X * supports SDTR at all. Therefore, we check needsdtr_copy instead
X * of needstr.
X */
- aic7xxx_set_syncrate(p, NULL, target, channel, 0, 0,
+ aic7xxx_set_syncrate(p, NULL, target, channel, 0, 0, 0,
X AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE);
- if ( (p->needsdtr_copy & target_mask) &&
- !(p->sdtr_pending & target_mask))
+ p->needsdtr |= (p->needsdtr_copy & target_mask);
+ done = TRUE;
+ break;
+ }
+ case MSG_EXT_PPR:
+ {
+ unsigned char bus_width, trans_options, new_trans_options;
+ unsigned int period, offset;
+ unsigned char maxsync, saved_offset;
+ struct aic7xxx_syncrate *syncrate;
+
+ if (p->msg_buf[1] != MSG_EXT_PPR_LEN)
+ {
+ reject = TRUE;


+ break;
+ }
+
+ /*

+ * If we aren't on one of the new Ultra3 cards, then reject any PPR
+ * message since we can't support any option field other than 0
+ */
+ if( !(p->features & AHC_ULTRA3) )
+ {
+ reject = TRUE;
+ break;
+ }
+
+ if (p->msg_len < (MSG_EXT_PPR_LEN + 2))


+ {
+ break;
+ }
+

+ period = p->msg_buf[3];
+ offset = saved_offset = p->msg_buf[5];
+ bus_width = p->msg_buf[6];
+ trans_options = new_trans_options = p->msg_buf[7] & 0xf;
+
+ if(aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+ {
+ printk(INFO_LEAD "Parsing PPR message (%d/%d/%d/%d)\n",
+ p->host_no, CTL_OF_SCB(scb), period, offset, bus_width,
+ trans_options);
+ }
+
+ if ( (aic_inb(p, SBLKCTL) & ENAB40) &&
+ !(aic_inb(p, SSTAT2) & EXP_ACTIVE) )
X {
- p->needsdtr |= target_mask;
- if ( !reject && !reply )
+ if(p->features & AHC_ULTRA3)
+ {
+ maxsync = AHC_SYNCRATE_ULTRA3;
+ }
+ else
X {
- scb->flags &= ~SCB_MSGOUT_WDTR;
- if (p->transinfo[tindex].goal_period)
+ maxsync = AHC_SYNCRATE_ULTRA2;
+ }
+ }
+ else
+ {
+ maxsync = AHC_SYNCRATE_ULTRA;
+ }
+ /*
+ * We might have a device that is starting negotiation with us
+ * before we can start up negotiation with it....be prepared to
+ * have a device ask for a higher speed then we want to give it
+ * in that case
+ */
+ if ( (scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_PPR)) !=
+ (SCB_MSGOUT_SENT|SCB_MSGOUT_PPR) )
+ {
+ reply = TRUE;
+ scb->flags &= ~SCB_MSGOUT_BITS;
+ scb->flags |= SCB_MSGOUT_PPR;
+ if (!(p->dev_flags[tindex] & DEVICE_SCANNED))
+ {
+ /*
+ * Not only is the device starting this up, but it also hasn't
+ * been scanned yet, so this would likely be our TUR or our
+ * INQUIRY command at scan time, so we need to use the
+ * settings from the SEEPROM if they existed. Of course, even
+ * if we didn't find a SEEPROM, we stuffed default values into
+ * the user settings anyway, so use those in all cases.
+ */
+ p->transinfo[tindex].goal_period =
+ p->transinfo[tindex].user_period;
+ if(p->transinfo[tindex].user_offset)
X {
- p->sdtr_pending |= target_mask;
- scb->flags |= SCB_MSGOUT_SDTR;
- aic_outb(p, HOST_MSG, MSG_OUT);
- aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
+ if(p->features & AHC_ULTRA2)
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
+ }
+ else if( p->transinfo[tindex].user_width &&
+ (bus_width == MSG_EXT_WDTR_BUS_16_BIT) &&
+ p->features & AHC_WIDE )
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
+ }
+ else
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
+ }
+ }
+ p->transinfo[tindex].goal_width =
+ p->transinfo[tindex].user_width;
+ p->transinfo[tindex].goal_options =
+ p->transinfo[tindex].user_options;
+ p->needppr_copy |= target_mask;
+ }
+ if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+ {
+ printk(INFO_LEAD "Received pre-emptive PPR message from "
+ "target.\n", p->host_no, CTL_OF_SCB(scb));
+ }
+ if ( !p->transinfo[tindex].goal_offset )
+ period = 255;
+ if ( p->transinfo[tindex].goal_period > period )
+ period = p->transinfo[tindex].goal_period;
+ if ( p->transinfo[tindex].goal_options == 0 )
+ new_trans_options = 0;
+ switch(bus_width)
+ {
+ default:
+ {
+ if ( (p->features & AHC_WIDE) &&
+ (p->transinfo[tindex].goal_width ==
+ MSG_EXT_WDTR_BUS_16_BIT) )
+ {
+ bus_width = MSG_EXT_WDTR_BUS_16_BIT;
+ break;
+ }
+ } /* Fall through if we aren't a wide card */
+ case MSG_EXT_WDTR_BUS_8_BIT:
+ {
+ p->needwdtr_copy &= ~target_mask;
+ bus_width = MSG_EXT_WDTR_BUS_8_BIT;
+ aic7xxx_set_width(p, target, channel, lun, bus_width,
+ AHC_TRANS_GOAL|AHC_TRANS_QUITE);


+ break;
+ }
+ }
+ }

+ else
+ {
+ switch(bus_width)
+ {
+ default:
+ {
+ reply = TRUE;
+ if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
+ ((p->dev_flags[tindex] & DEVICE_PRINT_DTR) ||
+ (aic7xxx_verbose > 0xffff)) )
+ {
+ printk(INFO_LEAD "Requesting %d bit transfers, rejecting.\n",
+ p->host_no, CTL_OF_SCB(scb), 8 * (0x01 << bus_width));
+ }
+ } /* We fall through on purpose */
+ case MSG_EXT_WDTR_BUS_8_BIT:
+ {
+ /*
+ * According to the spec, if we aren't wide, we also can't be
+ * Dual Edge so clear the options byte
+ */
+ new_trans_options = 0;
+ bus_width = MSG_EXT_WDTR_BUS_8_BIT;
+ break;
+ }
+ case MSG_EXT_WDTR_BUS_16_BIT:
+ {
+ break;
X }
X }
X }
+
+ aic7xxx_set_width(p, target, channel, lun, bus_width,
+ AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
+ syncrate = aic7xxx_find_syncrate(p, &period, maxsync,
+ &new_trans_options);
+ aic7xxx_validate_offset(p, syncrate, &offset, bus_width);
+ aic7xxx_set_syncrate(p, syncrate, target, channel, period,
+ offset, new_trans_options,
+ AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
+
+ if( (offset != saved_offset) ||
+ (trans_options != new_trans_options) ||
+ ((scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_PPR)) !=
+ (SCB_MSGOUT_SENT|SCB_MSGOUT_PPR)) )
+ {
+ aic7xxx_set_width(p, target, channel, lun, bus_width,
+ AHC_TRANS_GOAL|AHC_TRANS_QUITE);
+ aic7xxx_set_syncrate(p, syncrate, target, channel, period,
+ offset, new_trans_options,
+ AHC_TRANS_GOAL|AHC_TRANS_QUITE);
+ reply = TRUE;
+ }
+ p->dtr_pending &= ~target_mask;
+ p->needppr &= ~target_mask;
+ if(reply)
+ {
+ p->dtr_pending |= target_mask;
+ scb->flags &= ~SCB_MSGOUT_BITS;
+ scb->flags |= SCB_MSGOUT_PPR;
+ aic_outb(p, HOST_MSG, MSG_OUT);
+ aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
+ }
X done = TRUE;
X break;
X }
@@ -5485,7 +5827,7 @@
X } /* end of switch(p->msg_type) */
X } /* end of if (!reject && (p->msg_len > 2)) */
X
- if (reject)
+ if (!reply && reject)
X {
X aic_outb(p, MSG_MESSAGE_REJECT, MSG_OUT);
X aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
@@ -5657,12 +5999,14 @@
X if (aic7xxx_verbose & VERBOSE_RESET)
X printk(WARN_LEAD "Someone else reset the channel!!\n",
X p->host_no, channel, -1, -1);
+ if (aic7xxx_panic_on_abort)
+ aic7xxx_panic_abort(p, NULL);
X /*
X * Go through and abort all commands for the channel, but do not
X * reset the channel again.
X */
X aic7xxx_reset_channel(p, channel, /* Initiate Reset */ FALSE);
- aic7xxx_run_done_queue(p, FALSE);
+ aic7xxx_run_done_queue(p, TRUE);
X scb = NULL;
X }
X else if ( ((status & BUSFREE) != 0) && ((status & SELTO) == 0) )
@@ -5698,7 +6042,7 @@
X CTL_OF_SCB(scb), scb->hscb->tag);
X aic7xxx_reset_device(p, target, channel, ALL_LUNS,
X (message == MSG_ABORT) ? SCB_LIST_NULL : scb->hscb->tag );
- aic7xxx_run_done_queue(p, FALSE);
+ aic7xxx_run_done_queue(p, TRUE);
X scb = NULL;
X printerror = 0;
X }
@@ -5709,6 +6053,22 @@
X printerror = 0;
X }
X }
+ if ( (scb != NULL) &&
+ (scb->cmd == p->dev_dtr_cmnd[TARGET_INDEX(scb->cmd)]) )
+ {
+ /*
+ * This might be a SCSI-3 device that is dropping the bus due to
+ * errors and signalling that we should reduce the transfer speed.
+ * All we have to do is complete this command (since it's a negotiation
+ * command already) and the checksum routine should flag an error and
+ * reduce the speed setting and renegotiate. We call the reset routing
+ * just to clean out the hardware from this scb.
+ */
+ printerror = 0;
+ aic7xxx_reset_device(p, target, channel, ALL_LUNS, scb->hscb->tag);
+ aic7xxx_run_done_queue(p, TRUE);
+ scb = NULL;
+ }
X if (printerror != 0)
X {
X if (scb != NULL)
@@ -5724,7 +6084,12 @@
X tag = SCB_LIST_NULL;
X }
X aic7xxx_reset_device(p, target, channel, ALL_LUNS, tag);
- aic7xxx_run_done_queue(p, FALSE);
+ aic7xxx_run_done_queue(p, TRUE);
+ }
+ else
+ {
+ aic7xxx_reset_device(p, target, channel, ALL_LUNS, SCB_LIST_NULL);
+ aic7xxx_run_done_queue(p, TRUE);
X }
X printk(INFO_LEAD "Unexpected busfree, LASTPHASE = 0x%x, "
X "SEQADDR = 0x%x\n", p->host_no, channel, target, -1, lastphase,
@@ -5829,12 +6194,26 @@
X cmd->result = 0;
X scb = NULL;
X }
+ if (scb->cmd == p->dev_dtr_cmnd[TARGET_INDEX(scb->cmd)])
+ {
+ /*
+ * Turn off the needsdtr, needwdtr, and needppr bits since this device
+ * doesn't seem to exist.
+ */
+ p->needppr &= ~(0x01 << TARGET_INDEX(scb->cmd));
+ p->needppr_copy &= ~(0x01 << TARGET_INDEX(scb->cmd));
+ p->needsdtr &= ~(0x01 << TARGET_INDEX(scb->cmd));
+ p->needsdtr_copy &= ~(0x01 << TARGET_INDEX(scb->cmd));
+ p->needwdtr &= ~(0x01 << TARGET_INDEX(scb->cmd));
+ p->needwdtr_copy &= ~(0x01 << TARGET_INDEX(scb->cmd));
+ }
X }
X /*
X * Restarting the sequencer will stop the selection and make sure devices
X * are allowed to reselect in.
X */
X aic_outb(p, 0, SCSISEQ);
+ aic_outb(p, CLRSELINGO, CLRSINT0);
X aic_outb(p, aic_inb(p, SIMODE1) & ~(ENREQINIT|ENBUSFREE), SIMODE1);
X p->flags &= ~AHC_HANDLING_REQINITS;
X aic_outb(p, CLRSELTIMEO | CLRBUSFREE, CLRSINT1);
@@ -5868,6 +6247,8 @@
X Scsi_Cmnd *cmd;
X unsigned char mesg_out = MSG_NOOP;
X unsigned char lastphase = aic_inb(p, LASTPHASE);
+ unsigned char sstat2 = aic_inb(p, SSTAT2);
+ unsigned char tindex = TARGET_INDEX(scb->cmd);
X
X cmd = scb->cmd;
X switch (lastphase)
@@ -5898,12 +6279,81 @@
X break;
X }
X
- /*
- * A parity error has occurred during a data
- * transfer phase. Flag it and continue.
- */
- printk(WARN_LEAD "Parity error during %s phase.\n",
- p->host_no, CTL_OF_SCB(scb), phase);
+ /*
+ * A parity error has occurred during a data
+ * transfer phase. Flag it and continue.
+ */
+ if( (aic_inb(p, SCSIRATE) & AHC_SYNCRATE_CRC) && (lastphase == P_DATAIN) )
+ {
+ printk(WARN_LEAD "CRC error during %s phase.\n",
+ p->host_no, CTL_OF_SCB(scb), phase);
+ if(sstat2 & CRCVALERR)
+ {
+ printk(WARN_LEAD " CRC error in intermediate CRC packet.\n",
+ p->host_no, CTL_OF_SCB(scb));
+ }
+ if(sstat2 & CRCENDERR)
+ {
+ printk(WARN_LEAD " CRC error in ending CRC packet.\n",
+ p->host_no, CTL_OF_SCB(scb));
+ }
+ if(sstat2 & CRCREQERR)
+ {
+ printk(WARN_LEAD " Target incorrectly requested a CRC packet.\n",
+ p->host_no, CTL_OF_SCB(scb));
+ }
+ if(sstat2 & DUAL_EDGE_ERROR)
+ {
+ printk(WARN_LEAD " Dual Edge transmission error.\n",
+ p->host_no, CTL_OF_SCB(scb));
+ }
+ }
+ else
+ {
+ printk(WARN_LEAD "Parity error during %s phase.\n",
+ p->host_no, CTL_OF_SCB(scb), phase);
+ }
+
+ if(p->dev_flags[tindex] & DEVICE_PARITY_ERROR)
+ {
+ struct aic7xxx_syncrate *syncrate;
+ unsigned int period = p->transinfo[tindex].cur_period;
+ unsigned char options = p->transinfo[tindex].cur_options;
+ /*
+ * oops, we had a failure, lower the transfer rate and try again. It's
+ * worth noting here that it might be wise to also check for typical
+ * wide setting on narrow cable type problems and try disabling wide
+ * instead of slowing down if those exist. That's hard to do with simple
+ * checksums though.
+ */
+ if((syncrate = aic7xxx_find_syncrate(p, &period, 0, &options)) != NULL)
+ {
+ syncrate++;
+ if( (syncrate->rate[0] != NULL) &&
+ (!(p->features & AHC_ULTRA2) || (syncrate->sxfr_ultra2 == 0)) )
+ {
+ p->transinfo[tindex].goal_period = syncrate->period;
+ if( !(syncrate->sxfr_ultra2 & 0x40) )
+ {
+ p->transinfo[tindex].goal_options = 0;
+ }
+ }
+ else
+ {
+ p->transinfo[tindex].goal_offset = 0;
+ p->transinfo[tindex].goal_period = 0;
+ p->transinfo[tindex].goal_options = 0;
+ }
+ p->needppr |= (p->needppr_copy & (1<<tindex));
+ p->needsdtr |= (p->needsdtr_copy & (1<<tindex));
+ p->needwdtr |= (p->needwdtr_copy & (1<<tindex));
+ }
+ p->dev_flags[tindex] &= ~DEVICE_PARITY_ERROR;
+ }
+ else
+ {
+ p->dev_flags[tindex] |= DEVICE_PARITY_ERROR;
+ }
X
X /*
X * We've set the hardware to assert ATN if we get a parity
@@ -6072,13 +6522,6 @@
X printk("HSCB %d bad, SCB_NEXT points to self.\n", i);
X bogus = TRUE;
X }
- temp = aic_inb(p, SCB_PREV);
- if ((temp != SCB_LIST_NULL) &&
- (temp >= p->scb_data->maxhscbs))
- {
- printk("HSCB %d bad, SCB_PREV invalid(%d).\n", i, temp);
- bogus = TRUE;
- }
X if (scb_status[i] == 0)
X lost++;
X if (lost > 1)
@@ -6163,7 +6606,7 @@
X unsigned char scb_index;
X
X #ifdef AIC7XXX_VERBOSE_DEBUGGING
- if(aic7xxx_verbose > 0xffff)
+ if( (p->isr_count < 16) && (aic7xxx_verbose > 0xffff) )
X printk(INFO_LEAD "Command Complete Int.\n", p->host_no, -1, -1, -1);
X #endif
X
@@ -6368,7 +6811,7 @@
X * Determines the queue depth for a given device. There are two ways
X * a queue depth can be obtained for a tagged queueing device. One
X * way is the default queue depth which is determined by whether
- * AIC7XXX_CMDS_PER_LUN is defined. If it is defined, then it is used
+ * AIC7XXX_CMDS_PER_DEVICE is defined. If it is defined, then it is used
X * as the default queue depth. Otherwise, we use either 4 or 8 as the
X * default queue depth (dependent on the number of hardware SCBs).
X * The other way we determine queue depth is through the use of the
@@ -6396,7 +6839,7 @@
X {
X int tag_enabled = TRUE;
X
- default_depth = AIC7XXX_CMDS_PER_LUN;
+ default_depth = AIC7XXX_CMDS_PER_DEVICE;
X
X if (!(p->discenable & target_mask))
X {
@@ -6958,7 +7401,7 @@
X }
X printk("\n");
X #endif
- if (checksum != scarray[len - 1])
+ if ( (checksum != scarray[len - 1]) || (checksum == 0) )
X {
X return (0);
X }
@@ -7371,7 +7814,6 @@
X aic_outb(p, i, SCBPTR);
X aic_outb(p, 0, SCB_CONTROL); /* Clear the control byte. */
X aic_outb(p, i + 1, SCB_NEXT); /* Set the next pointer. */
- aic_outb(p, i - 1, SCB_PREV); /* Set the prev pointer. */
X aic_outb(p, SCB_LIST_NULL, SCB_TAG); /* Make the tag invalid. */
X aic_outb(p, SCB_LIST_NULL, SCB_BUSYTARGETS); /* no busy untagged */
X aic_outb(p, SCB_LIST_NULL, SCB_BUSYTARGETS+1);/* targets active yet */
@@ -7840,6 +8282,11 @@
X */
X aic7xxx_loadseq(p);
X
+ /*
+ * Make sure the AUTOFLUSHDIS bit is *not* set in the SBLKCTL register
+ */
+ aic_outb(p, aic_inb(p, SBLKCTL) & ~AUTOFLUSHDIS, SBLKCTL);
+
X if ( (p->chip & AHC_CHIPID_MASK) == AHC_AIC7770 )
X {
X aic_outb(p, ENABLE, BCTL); /* Enable the boards BUS drivers. */
@@ -8035,6 +8482,7 @@
X {
X p->transinfo[i].goal_period = 0;
X p->transinfo[i].goal_offset = 0;
+ p->transinfo[i].goal_options = 0;
X p->transinfo[i].goal_width = MSG_EXT_WDTR_BUS_8_BIT;
X }
X DRIVER_LOCK_INIT
@@ -8090,10 +8538,14 @@
X */
X for (i = 0; i < MAX_TARGETS; i++)
X {
- if(p->dev_wdtr_cmnd[i])
- kfree(p->dev_wdtr_cmnd[i]);
- if(p->dev_sdtr_cmnd[i])
- kfree(p->dev_sdtr_cmnd[i]);
+ if(p->dev_dtr_cmnd[i])
+ {
+ if(p->dev_dtr_cmnd[i]->request_buffer)
+ {
+ kfree(p->dev_dtr_cmnd[i]->request_buffer);
+ }
+ kfree(p->dev_dtr_cmnd[i]);
+ }
X }
X
X }
@@ -8184,14 +8636,16 @@
X {
X printk("aic7xxx: Using leftover BIOS values.\n");
X }
- if ( *sxfrctl1 & STPWEN )
+ if ( ((p->chip & ~AHC_CHIPID_MASK) == AHC_PCI) && (*sxfrctl1 & STPWEN) )
X {
X p->flags |= AHC_TERM_ENB_SE_LOW | AHC_TERM_ENB_SE_HIGH;
X sc->adapter_control &= ~CFAUTOTERM;
X sc->adapter_control |= CFSTERM | CFWSTERM | CFLVDSTERM;
X }
X if (aic7xxx_extended)
- p->flags |= AHC_EXTEND_TRANS_A | AHC_EXTEND_TRANS_B;
+ p->flags |= (AHC_EXTEND_TRANS_A | AHC_EXTEND_TRANS_B);
+ else
+ p->flags &= ~(AHC_EXTEND_TRANS_A | AHC_EXTEND_TRANS_B);
X }
X else
X {
@@ -8256,8 +8710,7 @@
X * Limit to 16 targets just in case. The 2842 for one is known to
X * blow the max_targets setting, future cards might also.
X */
- max_targets = MIN(sc->max_targets & CFMAXTARG,
- ((p->features & (AHC_TWIN | AHC_WIDE)) ? 16 : 8));
+ max_targets = ((p->features & (AHC_TWIN | AHC_WIDE)) ? 16 : 8);
X
X if (have_seeprom)
X {
@@ -8279,7 +8732,7 @@
X mask = (0x01 << i);
X if (!have_seeprom)
X {
- if(aic_inb(p, SCSISEQ) != 0)
+ if (aic_inb(p, SCSISEQ) != 0)
X {
X /*
X * OK...the BIOS set things up and left behind the settings we need.
@@ -8323,7 +8776,9 @@
X sc->device_flags[i] = CFDISC;
X if (p->features & AHC_WIDE)
X sc->device_flags[i] |= CFWIDEB;
- if (p->features & AHC_ULTRA2)
+ if (p->features & AHC_ULTRA3)
+ sc->device_flags[i] |= 2;
+ else if (p->features & AHC_ULTRA2)
X sc->device_flags[i] |= 3;
X else if (p->features & AHC_ULTRA)
X sc->device_flags[i] |= CFSYNCHISULTRA;
@@ -8339,20 +8794,30 @@
X }
X if (p->flags & AHC_NEWEEPROM_FMT)
X {
- if (sc->device_flags[i] & CFSYNCHISULTRA)
- {
- p->ultraenb |= mask;
- }
- else if (sc->device_flags[i] & CFNEWULTRAFORMAT)
+ if ( (sc->device_flags[i] & CFNEWULTRAFORMAT) &&
+ !(p->features & AHC_ULTRA2) )
X {
- if ( ((sc->device_flags[i] & (CFSYNCHISULTRA | CFXFER)) == 0x03) &&
- !(p->features & AHC_ULTRA2) )
+ /*
+ * I know of two different Ultra BIOSes that do this differently.
+ * One on the Gigabyte 6BXU mb that wants flags[i] & CFXFER to
+ * be == to 0x03 and SYNCISULTRA to be true to mean 40MByte/s
+ * while on the IBM Netfinity 5000 they want the same thing
+ * to be something else, while flags[i] & CFXFER == 0x03 and
+ * SYNCISULTRA false should be 40MByte/s. So, we set both to
+ * 40MByte/s and the lower speeds be damned. People will have
+ * to select around the conversely mapped lower speeds in order
+ * to select lower speeds on these boards.
+ */
+ if ((sc->device_flags[i] & (CFXFER)) == 0x03)
X {
X sc->device_flags[i] &= ~CFXFER;
X sc->device_flags[i] |= CFSYNCHISULTRA;
- p->ultraenb |= mask;
X }
X }


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

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

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.3/patch-2.3.6/part10

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


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

if test "$Scheck" != 10; 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.3.6'
else
echo 'x - continuing with patch-2.3.6'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.6' &&

+
+ MOD_INC_USE_COUNT;
X
X /* Ready to play! */
X dev->tbusy = 0;
X dev->interrupt = 0;
X dev->start = 1;
X
- MOD_INC_USE_COUNT;
-
- irport_start(iobase);
+ /* Change speed to make sure dongles follow us again */
+ if (idev->change_speed)
+ idev->change_speed(idev, 9600);
X
X return 0;
X }
@@ -558,12 +619,12 @@
X
X iobase = idev->io.iobase2;
X
- irport_stop(iobase);
-
X /* Stop device */
X dev->tbusy = 1;
X dev->start = 0;
X
+ irport_stop(idev, iobase);
+
X free_irq(idev->io.irq2, idev);
X
X MOD_DEC_USE_COUNT;
@@ -571,12 +632,32 @@


X return 0;
X }
X

-static void irport_wait_until_sent(struct irda_device *idev)
+/*
+ * Function irport_wait_until_sent (idev)
+ *
+ * Delay exectution until finished transmitting
+ *
+ */
+void irport_wait_until_sent(struct irda_device *idev)
X {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(60*HZ/1000);
+ int iobase;
+
+ iobase = idev->io.iobase2;
+
+ /* Wait until Tx FIFO is empty */
+ while (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
+ DEBUG(2, __FUNCTION__ "(), waiting!\n");
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(MSECS_TO_JIFFIES(60));
+ }
X }
X
+/*
+ * Function irport_is_receiving (idev)
+ *
+ * Returns true is we are currently receiving data
+ *
+ */
X static int irport_is_receiving(struct irda_device *idev)
X {
X return (idev->rx_buff.state != OUTSIDE_FRAME);


@@ -635,6 +716,9 @@
X

X MODULE_PARM(io, "1-4i");
X MODULE_PARM(irq, "1-4i");
+
+MODULE_AUTHOR("Dag Brattli <da...@cs.uit.no>");
+MODULE_DESCRIPTION("Half duplex serial driver for IrDA SIR mode");
X
X /*
X * Function cleanup_module (void)
diff -u --recursive --new-file v2.3.5/linux/drivers/net/irda/litelink.c linux/drivers/net/irda/litelink.c
--- v2.3.5/linux/drivers/net/irda/litelink.c Mon May 31 22:28:05 1999
+++ linux/drivers/net/irda/litelink.c Mon Jun 7 16:18:58 1999
@@ -6,7 +6,7 @@
X * Status: Stable
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Fri May 7 12:50:33 1999
- * Modified at: Mon May 10 15:12:18 1999
+ * Modified at: Wed May 19 07:25:15 1999
X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
X * Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -33,19 +33,19 @@
X #include <linux/tty.h>
X #include <linux/sched.h>
X #include <linux/init.h>
-#include <asm/ioctls.h>
-#include <asm/uaccess.h>
X
X #include <net/irda/irda.h>
X #include <net/irda/irmod.h>
X #include <net/irda/irda_device.h>
X #include <net/irda/dongle.h>
X
-static void litelink_reset(struct irda_device *dev, int unused);
+#define MIN_DELAY 25 /* 15 us, but wait a little more to be sure */
+#define MAX_DELAY 10000 /* 1 ms */
+
X static void litelink_open(struct irda_device *idev, int type);
X static void litelink_close(struct irda_device *dev);
-static void litelink_change_speed( struct irda_device *dev, int baudrate);
-static void litelink_reset(struct irda_device *dev, int unused);
+static void litelink_change_speed(struct irda_device *dev, int baudrate);
+static void litelink_reset(struct irda_device *dev);
X static void litelink_init_qos(struct irda_device *idev, struct qos_info *qos);
X
X /* These are the baudrates supported */
@@ -105,13 +105,13 @@
X irda_device_set_dtr_rts(idev, TRUE, FALSE);
X
X /* Sleep a minimum of 15 us */
- udelay(15);
+ udelay(MIN_DELAY);
X
X /* Go back to normal mode */
X irda_device_set_dtr_rts(idev, TRUE, TRUE);
X
X /* Sleep a minimum of 15 us */
- udelay(15);
+ udelay(MIN_DELAY);
X
X /* Cycle through avaiable baudrates until we reach the correct one */
X for (i=0; i<5 && baud_rates[i] != baudrate; i++) {
@@ -120,13 +120,13 @@
X irda_device_set_dtr_rts(idev, FALSE, TRUE);
X
X /* Sleep a minimum of 15 us */
- udelay(15);
+ udelay(MIN_DELAY);
X
X /* Set DTR, Set RTS */
X irda_device_set_dtr_rts(idev, TRUE, TRUE);
X
X /* Sleep a minimum of 15 us */
- udelay(15);
+ udelay(MIN_DELAY);
X }
X }
X
@@ -137,11 +137,8 @@
X * called with a process context!
X *
X */
-static void litelink_reset(struct irda_device *idev, int unused)
+static void litelink_reset(struct irda_device *idev)
X {
- struct irtty_cb *self;
- struct tty_struct *tty;
-
X ASSERT(idev != NULL, return;);
X ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
X
@@ -149,19 +146,19 @@
X irda_device_set_dtr_rts(idev, TRUE, TRUE);
X
X /* Sleep a minimum of 15 us */
- udelay(15);
+ udelay(MIN_DELAY);
X
X /* Clear RTS to reset dongle */
X irda_device_set_dtr_rts(idev, TRUE, FALSE);
X
X /* Sleep a minimum of 15 us */
- udelay(15);
+ udelay(MIN_DELAY);
X
X /* Go back to normal mode */
X irda_device_set_dtr_rts(idev, TRUE, TRUE);
X
X /* Sleep a minimum of 15 us */
- udelay(15);
+ udelay(MIN_DELAY);
X
X /* This dongles speed defaults to 115200 bps */
X idev->qos.baud_rate.value = 115200;
@@ -173,7 +170,7 @@
X * Initialize QoS capabilities
X *
X */
-static void litelink_init_qos( struct irda_device *idev, struct qos_info *qos)
+static void litelink_init_qos(struct irda_device *idev, struct qos_info *qos)
X {
X qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
X qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */
diff -u --recursive --new-file v2.3.5/linux/drivers/net/irda/pc87108.c linux/drivers/net/irda/pc87108.c
--- v2.3.5/linux/drivers/net/irda/pc87108.c Mon May 31 22:28:05 1999
+++ linux/drivers/net/irda/pc87108.c Mon Jun 7 16:18:58 1999
@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Sat Nov 7 21:43:15 1998
- * Modified at: Sun May 9 12:57:46 1999
+ * Modified at: Mon May 24 15:19:21 1999
X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
X * Copyright (c) 1998-1999 Dag Brattli <da...@cs.uit.no>
@@ -72,7 +72,7 @@
X #define CHIP_IO_EXTENT 8
X
X static unsigned int io[] = { 0x2f8, ~0, ~0, ~0 };
-static unsigned int io2[] = { 0x150, 0, 0, 0};
+static unsigned int io2[] = { 0x150, 0, 0, 0 };
X static unsigned int irq[] = { 3, 0, 0, 0 };
X static unsigned int dma[] = { 0, 0, 0, 0 };
X
@@ -98,28 +98,28 @@
X };
X
X /* Some prototypes */
-static int pc87108_open( int i, unsigned int iobase, unsigned int board_addr,
- unsigned int irq, unsigned int dma);
+static int pc87108_open(int i, unsigned int iobase, unsigned int board_addr,
+ unsigned int irq, unsigned int dma);
X #ifdef MODULE
-static int pc87108_close( struct irda_device *idev);
+static int pc87108_close(struct irda_device *idev);
X #endif /* MODULE */
-static int pc87108_probe( int iobase, int board_addr, int irq, int dma);
-static void pc87108_pio_receive( struct irda_device *idev);
-static int pc87108_dma_receive( struct irda_device *idev);
+static int pc87108_probe(int iobase, int board_addr, int irq, int dma);
+static void pc87108_pio_receive(struct irda_device *idev);
+static int pc87108_dma_receive(struct irda_device *idev);
X static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase);
-static int pc87108_hard_xmit( struct sk_buff *skb, struct device *dev);
-static int pc87108_pio_write( int iobase, __u8 *buf, int len, int fifo_size);
-static void pc87108_dma_write( struct irda_device *idev, int iobase);
-static void pc87108_change_speed( struct irda_device *idev, int baud);
+static int pc87108_hard_xmit(struct sk_buff *skb, struct device *dev);
+static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size);
+static void pc87108_dma_write(struct irda_device *idev, int iobase);
+static void pc87108_change_speed(struct irda_device *idev, int baud);
X static void pc87108_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void pc87108_wait_until_sent( struct irda_device *idev);
-static int pc87108_is_receiving( struct irda_device *idev);
-static int pc87108_read_dongle_id ( int iobase);
-static void pc87108_init_dongle_interface ( int iobase, int dongle_id);
-
-static int pc87108_net_init( struct device *dev);
-static int pc87108_net_open( struct device *dev);
-static int pc87108_net_close( struct device *dev);
+static void pc87108_wait_until_sent(struct irda_device *idev);
+static int pc87108_is_receiving(struct irda_device *idev);
+static int pc87108_read_dongle_id (int iobase);
+static void pc87108_init_dongle_interface (int iobase, int dongle_id);
+
+static int pc87108_net_init(struct device *dev);
+static int pc87108_net_open(struct device *dev);
+static int pc87108_net_close(struct device *dev);
X
X /*
X * Function pc87108_init ()
@@ -131,11 +131,11 @@
X {
X int i;
X
- for ( i=0; (io[i] < 2000) && (i < 4); i++) {
+ for (i=0; (io[i] < 2000) && (i < 4); i++) {
X int ioaddr = io[i];
X if (check_region(ioaddr, CHIP_IO_EXTENT) < 0)
X continue;
- if (pc87108_open( i, io[i], io2[i], irq[i], dma[i]) == 0)
+ if (pc87108_open(i, io[i], io2[i], irq[i], dma[i]) == 0)
X return 0;
X }
X return -ENODEV;
@@ -167,29 +167,29 @@
X * Open driver instance
X *
X */
-static int pc87108_open( int i, unsigned int iobase, unsigned int board_addr,
- unsigned int irq, unsigned int dma)
+static int pc87108_open(int i, unsigned int iobase, unsigned int board_addr,
+ unsigned int irq, unsigned int dma)
X {
X struct pc87108 *self;
X struct irda_device *idev;
X int ret;
X int dongle_id;
X
- DEBUG( 0, __FUNCTION__ "()\n");
+ DEBUG(0, __FUNCTION__ "()\n");
X
- if (( dongle_id = pc87108_probe( iobase, board_addr, irq, dma)) == -1)
+ if ((dongle_id = pc87108_probe(iobase, board_addr, irq, dma)) == -1)
X return -1;
X
X /*
X * Allocate new instance of the driver
X */
- self = kmalloc( sizeof(struct pc87108), GFP_KERNEL);
- if ( self == NULL) {
- printk( KERN_ERR "IrDA: Can't allocate memory for "
- "IrDA control block!\n");
+ self = kmalloc(sizeof(struct pc87108), GFP_KERNEL);
+ if (self == NULL) {
+ printk(KERN_ERR "IrDA: Can't allocate memory for "
+ "IrDA control block!\n");
X return -ENOMEM;
X }
- memset( self, 0, sizeof(struct pc87108));
+ memset(self, 0, sizeof(struct pc87108));
X
X /* Need to store self somewhere */
X dev_self[i] = self;
@@ -204,24 +204,24 @@
X idev->io.fifo_size = 32;
X
X /* Lock the port that we need */
- ret = check_region( idev->io.iobase, idev->io.io_ext);
- if ( ret < 0) {
- DEBUG( 0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
- idev->io.iobase);
+ ret = check_region(idev->io.iobase, idev->io.io_ext);
+ if (ret < 0) {
+ DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
+ idev->io.iobase);
X /* pc87108_cleanup( self->idev); */
X return -ENODEV;
X }
- request_region( idev->io.iobase, idev->io.io_ext, idev->name);
+ request_region(idev->io.iobase, idev->io.io_ext, idev->name);
X
X /* Initialize QoS for this device */
- irda_init_max_qos_capabilies( &idev->qos);
+ irda_init_max_qos_capabilies(&idev->qos);
X
X /* The only value we must override it the baudrate */
X idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
X IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);
X
X idev->qos.min_turn_time.bits = qos_mtt_bits;
- irda_qos_bits_to_value( &idev->qos);
+ irda_qos_bits_to_value(&idev->qos);
X
X idev->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO|IFF_DONGLE;
X
@@ -245,10 +245,10 @@
X idev->netdev.stop = pc87108_net_close;
X
X idev->io.dongle_id = dongle_id;
- pc87108_init_dongle_interface( iobase, dongle_id);
+ pc87108_init_dongle_interface(iobase, dongle_id);
X
X /* Open the IrDA device */
- irda_device_open( idev, driver_name, self);
+ irda_device_open(idev, driver_name, self);
X
X return 0;
X }
@@ -267,15 +267,14 @@
X
X DEBUG( 4, __FUNCTION__ "()\n");
X
- ASSERT( idev != NULL, return -1;);
- ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+ ASSERT(idev != NULL, return -1;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
X
X iobase = idev->io.iobase;
X self = (struct pc87108 *) idev->priv;
X
X /* Release the PORT that this driver is using */
- DEBUG( 4, __FUNCTION__ "(), Releasing Region %03x\n",
- idev->io.iobase);
+ DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase);
X release_region(idev->io.iobase, idev->io.io_ext);
X
X irda_device_close(idev);
@@ -292,22 +291,22 @@
X * Returns non-negative on success.
X *
X */
-static int pc87108_probe( int iobase, int board_addr, int irq, int dma)
+static int pc87108_probe(int iobase, int board_addr, int irq, int dma)
X {
X int version;
X __u8 temp=0;
X int dongle_id;
X
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
X
X /* Base Address and Interrupt Control Register BAIC */
X outb(0, board_addr);
- switch ( iobase) {
- case 0x3E8: outb( 0x14, board_addr+1); break;
- case 0x2E8: outb( 0x15, board_addr+1); break;
- case 0x3F8: outb( 0x16, board_addr+1); break;
- case 0x2F8: outb( 0x17, board_addr+1); break;
- default: DEBUG(0, __FUNCTION__ "(), invalid base_address");
+ switch (iobase) {
+ case 0x3E8: outb(0x14, board_addr+1); break;
+ case 0x2E8: outb(0x15, board_addr+1); break;
+ case 0x3F8: outb(0x16, board_addr+1); break;
+ case 0x2F8: outb(0x17, board_addr+1); break;
+ default: ERROR(__FUNCTION__ "(), invalid base_address");
X }
X
X /* Control Signal Routing Register CSRT */
@@ -319,74 +318,73 @@
X case 9: temp = 0x05; break;
X case 11: temp = 0x06; break;
X case 15: temp = 0x07; break;
- default: DEBUG( 0, __FUNCTION__ "(), invalid irq");
+ default: ERROR(__FUNCTION__ "(), invalid irq");
X }
- outb( 1, board_addr);
-
+ outb(1, board_addr);
+
X switch (dma) {
- case 0: outb( 0x08+temp, board_addr+1); break;
- case 1: outb( 0x10+temp, board_addr+1); break;
- case 3: outb( 0x18+temp, board_addr+1); break;
+ case 0: outb(0x08+temp, board_addr+1); break;
+ case 1: outb(0x10+temp, board_addr+1); break;
+ case 3: outb(0x18+temp, board_addr+1); break;
X default: DEBUG( 0, __FUNCTION__ "(), invalid dma");
X }
X
X /* Mode Control Register MCTL */
- outb( 2, board_addr);
- outb( 0x03, board_addr+1);
+ outb(2, board_addr);
+ outb(0x03, board_addr+1);
X
X /* read the Module ID */
- switch_bank( iobase, BANK3);
- version = inb( iobase+MID);
+ switch_bank(iobase, BANK3);
+ version = inb(iobase+MID);
X
X /* should be 0x2? */
- if (0x20 != (version & 0xf0))
- {
- DEBUG( 0, __FUNCTION__ "(), Wrong chip version");
+ if (0x20 != (version & 0xf0)) {
+ ERROR(__FUNCTION__ "(), Wrong chip version %02x\n", version);
X return -1;
X }
X
X /* Switch to advanced mode */
X switch_bank( iobase, BANK2);
- outb( ECR1_EXT_SL, iobase+ECR1);
- switch_bank( iobase, BANK0);
+ outb(ECR1_EXT_SL, iobase+ECR1);
+ switch_bank(iobase, BANK0);
X
- dongle_id = pc87108_read_dongle_id( iobase);
- DEBUG( 0, __FUNCTION__ "(), Found dongle: %s\n",
- dongle_types[ dongle_id]);
+ dongle_id = pc87108_read_dongle_id(iobase);
+ DEBUG(0, __FUNCTION__ "(), Found dongle: %s\n",
+ dongle_types[ dongle_id]);
X
X /* Set FIFO threshold to TX17, RX16, reset and enable FIFO's */
- switch_bank( iobase, BANK0);
- outb( FCR_RXTH|FCR_TXTH|FCR_TXSR|FCR_RXSR|FCR_FIFO_EN, iobase+FCR);
+ switch_bank(iobase, BANK0);
+ outb(FCR_RXTH|FCR_TXTH|FCR_TXSR|FCR_RXSR|FCR_FIFO_EN, iobase+FCR);
X
X /* Set FIFO size to 32 */
- switch_bank( iobase, BANK2);
- outb( EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2);
+ switch_bank(iobase, BANK2);
+ outb(EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2);
X
X /* IRCR2: FEND_MD is set */
- switch_bank( iobase, BANK5);
- outb( 0x2a, iobase+4);
+ switch_bank(iobase, BANK5);
+ outb(0x2a, iobase+4);
X
X /* Make sure that some defaults are OK */
- switch_bank( iobase, BANK6);
- outb( 0x20, iobase+0); /* Set 32 bits FIR CRC */
- outb( 0x0a, iobase+1); /* Set MIR pulse width */
- outb( 0x0d, iobase+2); /* Set SIR pulse width */
- outb( 0x2a, iobase+4); /* Set beginning frag, and preamble length */
+ switch_bank(iobase, BANK6);
+ outb(0x20, iobase+0); /* Set 32 bits FIR CRC */
+ outb(0x0a, iobase+1); /* Set MIR pulse width */
+ outb(0x0d, iobase+2); /* Set SIR pulse width */
+ outb(0x2a, iobase+4); /* Set beginning frag, and preamble length */
X
X /* Receiver frame length */
- switch_bank( iobase, BANK4);
- outb( 2048 & 0xff, iobase+6);
- outb(( 2048 >> 8) & 0x1f, iobase+7);
+ switch_bank(iobase, BANK4);
+ outb(2048 & 0xff, iobase+6);
+ outb((2048 >> 8) & 0x1f, iobase+7);
X
X /* Transmitter frame length */
- outb( 2048 & 0xff, iobase+4);
- outb(( 2048 >> 8) & 0x1f, iobase+5);
+ outb(2048 & 0xff, iobase+4);
+ outb((2048 >> 8) & 0x1f, iobase+5);
X
- DEBUG( 0, "PC87108 driver loaded. Version: 0x%02x\n", version);
+ DEBUG(0, "PC87108 driver loaded. Version: 0x%02x\n", version);
X
X /* Enable receive interrupts */
- switch_bank( iobase, BANK0);
- outb( IER_RXHDL_IE, iobase+IER);
+ switch_bank(iobase, BANK0);
+ outb(IER_RXHDL_IE, iobase+IER);
X
X return dongle_id;
X }
@@ -409,10 +407,10 @@
X bank = inb( iobase+BSR);
X
X /* Select Bank 7 */
- switch_bank( iobase, BANK7);
+ switch_bank(iobase, BANK7);
X
X /* IRCFG4: IRSL0_DS and IRSL21_DS are cleared */
- outb( 0x00, iobase+7);
+ outb(0x00, iobase+7);
X
X /* ID0, 1, and 2 are pulled up/down very slowly */
X udelay(50);
@@ -421,16 +419,16 @@
X dongle_id = inb( iobase+4) & 0x0f;
X
X #ifdef BROKEN_DONGLE_ID
- if ( dongle_id == 0x0a)
+ if (dongle_id == 0x0a)
X dongle_id = 0x09;
X #endif
-
+
X /* Go back to bank 0 before returning */
- switch_bank( iobase, BANK0);
+ switch_bank(iobase, BANK0);
X
- DEBUG( 0, __FUNCTION__ "(), Dongle = %#x\n", dongle_id);
+ DEBUG(0, __FUNCTION__ "(), Dongle = %#x\n", dongle_id);
X
- outb( bank, iobase+BSR);
+ outb(bank, iobase+BSR);
X
X return dongle_id;
X }
@@ -443,7 +441,7 @@
X * power-on/reset. It also needs to be used whenever you suspect that
X * the dongle is changed.
X */
-static void pc87108_init_dongle_interface ( int iobase, int dongle_id)
+static void pc87108_init_dongle_interface (int iobase, int dongle_id)
X {
X int bank;
X
@@ -818,11 +816,11 @@
X iobase+ECR1);
X
X /* Enable DMA */
- switch_bank( iobase, BANK0);
- outb( inb( iobase+MCR)|MCR_DMA_EN, iobase+MCR);
+ switch_bank(iobase, BANK0);
+ outb(inb(iobase+MCR)|MCR_DMA_EN, iobase+MCR);
X
X /* Restore bank register */
- outb( bsr, iobase+BSR);
+ outb(bsr, iobase+BSR);
X }
X
X /*
@@ -832,7 +830,7 @@
X * got transfered
X *
X */
-static int pc87108_pio_write( int iobase, __u8 *buf, int len, int fifo_size)
+static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size)
X {
X int actual = 0;
X __u8 bank;
@@ -851,16 +849,16 @@
X }
X
X /* Fill FIFO with current frame */
- while (( fifo_size-- > 0) && (actual < len)) {
+ while ((fifo_size-- > 0) && (actual < len)) {
X /* Transmit next byte */
- outb( buf[actual++], iobase+TXD);
+ outb(buf[actual++], iobase+TXD);
X }
X
- DEBUG( 4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n",
- fifo_size, actual, len);
+ DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n",
+ fifo_size, actual, len);
X
X /* Restore bank */
- outb( bank, iobase+BSR);
+ outb(bank, iobase+BSR);
X
X return actual;
X }
@@ -1466,6 +1464,9 @@
X MODULE_DESCRIPTION("NSC PC87108 IrDA Device Driver");
X
X MODULE_PARM(qos_mtt_bits, "i");
+MODULE_PARM(io, "1-4i");
+MODULE_PARM(io2, "1-4i");
+MODULE_PARM(irq, "1-4i");
X
X /*
X * Function init_module (void)
diff -u --recursive --new-file v2.3.5/linux/drivers/net/irda/smc-ircc.c linux/drivers/net/irda/smc-ircc.c
--- v2.3.5/linux/drivers/net/irda/smc-ircc.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/irda/smc-ircc.c Mon Jun 7 16:18:58 1999
@@ -0,0 +1,969 @@
+/*********************************************************************
+ *
+ * Filename: smc-ircc.c
+ * Version: 0.1
+ * Description: Driver for the SMC Infrared Communications Controller (SMC)
+ * Status: Experimental.
+ * Author: Thomas Davis (tad...@jps.net)
+ * Created at:
+ * Modified at: Wed May 19 15:30:08 1999
+ * Modified by: Dag Brattli <da...@cs.uit.no>
+ *
+ * Copyright (c) 1998-1999 Thomas Davis, All Rights Reserved.


+ *
+ * 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.
+ *
+ * I, Thomas Davis, admit no liability nor provide warranty for any
+ * of this software. This material is provided "AS-IS" and at no charge.
+ *
+ * Applicable Models : Fujitsu Lifebook 635t
+ * Sony PCG-505TX (gets DMA wrong.)
+ *
+ ********************************************************************/
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/byteorder.h>
+
+#include <net/irda/wrapper.h>
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/irlap_frame.h>
+#include <net/irda/irda_device.h>
+
+#include <net/irda/smc-ircc.h>
+#include <net/irda/irport.h>
+
+static char *driver_name = "smc-ircc";
+
+#define CHIP_IO_EXTENT 8
+
+static unsigned int io[] = { 0x2e8, 0x140, ~0, ~0 };
+static unsigned int io2[] = { 0x2f8, 0x3e8, 0, 0};
+
+static struct ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL};
+
+/* Some prototypes */
+static int ircc_open( int i, unsigned int iobase, unsigned int board_addr);
+static int ircc_close( struct irda_device *idev);
+static int ircc_probe( int iobase, int board_addr);
+static int ircc_dma_receive( struct irda_device *idev);
+static int ircc_dma_receive_complete(struct irda_device *idev, int iobase);
+static int ircc_hard_xmit( struct sk_buff *skb, struct device *dev);
+static void ircc_dma_write( struct irda_device *idev, int iobase);
+static void ircc_change_speed( struct irda_device *idev, int baud);
+static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void ircc_wait_until_sent( struct irda_device *idev);
+static int ircc_is_receiving( struct irda_device *idev);
+
+static int ircc_net_init( struct device *dev);
+static int ircc_net_open( struct device *dev);
+static int ircc_net_close( struct device *dev);
+
+static int ircc_debug=3;
+static int ircc_irq=255;
+static int ircc_dma=255;
+
+static inline void register_bank(int port, int bank)
+{
+ outb(((inb(port+UART_MASTER) & 0xF0) | (bank & 0x07)),
+ port+UART_MASTER);
+}
+
+static inline unsigned int serial_in(int port, int offset)
+{
+ return inb(port+offset);
+}
+
+static inline void serial_out(int port, int offset, int value)
+{
+ outb(value, port+offset);
+}
+
+/*
+ * Function ircc_init ()
+ *
+ * Initialize chip. Just try to find out how many chips we are dealing with
+ * and where they are
+ */
+__initfunc(int ircc_init(void))
+{
+ int i;
+
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+ for ( i=0; (io[i] < 2000) && (i < 4); i++) {
+ int ioaddr = io[i];
+ if (check_region(ioaddr, CHIP_IO_EXTENT))
+ continue;
+ if (ircc_open( i, io[i], io2[i]) == 0)
+ return 0;
+ }
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+


+ return -ENODEV;
+}
+

+/*
+ * Function ircc_cleanup ()
+ *
+ * Close all configured chips
+ *
+ */
+#ifdef MODULE
+static void ircc_cleanup(void)
+{
+ int i;
+
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+
+ for ( i=0; i < 4; i++) {
+ if ( dev_self[i])
+ ircc_close( &(dev_self[i]->idev));
+ }
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");


+}
+#endif /* MODULE */

+
+/*
+ * Function ircc_open (iobase, irq)
+ *
+ * Open driver instance
+ *
+ */
+static int ircc_open( int i, unsigned int iobase, unsigned int iobase2)
+{
+ struct ircc_cb *self;
+ struct irda_device *idev;
+ int ret;
+ int config;
+
+ DEBUG( ircc_debug, __FUNCTION__ " -->\n");
+
+ if ((config = ircc_probe( iobase, iobase2)) == -1) {
+ DEBUG(ircc_debug,
+ __FUNCTION__ ": addr 0x%04x - no device found!\n", iobase);
+ return -1;
+ }
+
+ /*
+ * Allocate new instance of the driver
+ */
+ self = kmalloc( sizeof(struct ircc_cb), GFP_KERNEL);
+ if ( self == NULL) {
+ printk( KERN_ERR "IrDA: Can't allocate memory for "
+ "IrDA control block!\n");
+ return -ENOMEM;
+ }
+ memset(self, 0, sizeof(struct ircc_cb));
+
+ /* Need to store self somewhere */
+ dev_self[i] = self;
+
+ idev = &self->idev;
+
+ /* Initialize IO */
+ idev->io.iobase = iobase;
+ idev->io.iobase2 = iobase2; /* Used by irport */
+ idev->io.irq = config >> 4 & 0x0f;
+ if (ircc_irq < 255) {
+ printk(KERN_INFO "smc: Overriding IRQ - chip says %d, using %d\n",
+ idev->io.irq, ircc_irq);
+ idev->io.irq = ircc_irq;
+ }
+ idev->io.io_ext = CHIP_IO_EXTENT;
+ idev->io.io_ext2 = 8; /* Used by irport */
+ idev->io.dma = config & 0x0f;
+ if (ircc_dma < 255) {
+ printk(KERN_INFO "smc: Overriding DMA - chip says %d, using %d\n",
+ idev->io.dma, ircc_dma);
+ idev->io.dma = ircc_dma;
+ }
+ idev->io.fifo_size = 16;
+
+ /* Lock the port that we need */
+ ret = check_region( idev->io.iobase, idev->io.io_ext);
+ if ( ret < 0) {
+ DEBUG( 0, __FUNCTION__ ": can't get iobase of 0x%03x\n",
+ idev->io.iobase);
+ /* ircc_cleanup( self->idev); */
+ return -ENODEV;
+ }
+ ret = check_region( idev->io.iobase2, idev->io.io_ext2);
+ if ( ret < 0) {
+ DEBUG( 0, __FUNCTION__ ": can't get iobase of 0x%03x\n",
+ idev->io.iobase2);
+ /* ircc_cleanup( self->idev); */
+ return -ENODEV;
+ }
+ request_region( idev->io.iobase, idev->io.io_ext, idev->name);
+ request_region( idev->io.iobase2, idev->io.io_ext2, idev->name);
+
+ /* Initialize QoS for this device */
+ irda_init_max_qos_capabilies( &idev->qos);
+
+#if 1
+ /* The only value we must override it the baudrate */
+ idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
+ IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);
+#else
+ /* The only value we must override it the baudrate */
+ idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
+ IR_115200;
+#endif
+
+ idev->qos.min_turn_time.bits = 0x07;
+ irda_qos_bits_to_value( &idev->qos);
+
+ idev->flags = IFF_FIR|IFF_SIR|IFF_DMA|IFF_PIO;
+
+ /* Specify which buffer allocation policy we need */
+ idev->rx_buff.flags = GFP_KERNEL | GFP_DMA;
+ idev->tx_buff.flags = GFP_KERNEL | GFP_DMA;
+
+ /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
+ idev->rx_buff.truesize = 4000;
+ idev->tx_buff.truesize = 4000;
+
+ /* Initialize callbacks */
+ idev->change_speed = ircc_change_speed;
+ idev->wait_until_sent = ircc_wait_until_sent;
+ idev->is_receiving = ircc_is_receiving;
+
+ /* Override the network functions we need to use */
+ idev->netdev.init = ircc_net_init;
+ idev->netdev.hard_start_xmit = ircc_hard_xmit;
+ idev->netdev.open = ircc_net_open;
+ idev->netdev.stop = ircc_net_close;
+
+ irport_start(idev, iobase2);
+
+ /* Open the IrDA device */
+ irda_device_open( idev, driver_name, self);
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");


+ return 0;
+}
+
+/*

+ * Function ircc_close (idev)
+ *
+ * Close driver instance
+ *
+ */
+static int ircc_close( struct irda_device *idev)
+{
+ int iobase;
+
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+
+ ASSERT( idev != NULL, return -1;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+
+ iobase = idev->io.iobase;
+
+ irport_stop(idev, idev->io.iobase2);
+
+ register_bank(iobase, 0);
+ serial_out(iobase, UART_IER, 0);
+ serial_out(iobase, UART_MASTER, UART_MASTER_RESET);
+
+ register_bank(iobase, 1);
+
+ serial_out(iobase, UART_SCE_CFGA,
+ UART_CFGA_IRDA_SIR_A | UART_CFGA_TX_POLARITY);
+ serial_out(iobase, UART_SCE_CFGB, UART_CFGB_IR);
+
+ /* Release the PORT that this driver is using */
+ DEBUG( ircc_debug,
+ __FUNCTION__ ": releasing 0x%03x\n", idev->io.iobase);
+
+ release_region( idev->io.iobase, idev->io.io_ext);
+
+ if ( idev->io.iobase2) {
+ DEBUG( ircc_debug, __FUNCTION__ ": releasing 0x%03x\n",
+ idev->io.iobase2);
+ release_region( idev->io.iobase2, idev->io.io_ext2);
+ }
+
+ irda_device_close( idev);
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");


+ return 0;
+}
+
+/*

+ * Function ircc_probe (iobase, board_addr, irq, dma)
+ *
+ * Returns non-negative on success.
+ *
+ */
+static int ircc_probe( int iobase, int iobase2)
+{
+ int version = 1;
+ int low, high, chip, config, dma, irq;
+
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+
+ register_bank(iobase, 3);
+ high = serial_in(iobase, UART_ID_HIGH);
+ low = serial_in(iobase, UART_ID_LOW);
+ chip = serial_in(iobase, UART_CHIP_ID);
+ version = serial_in(iobase, UART_VERSION);
+ config = serial_in(iobase, UART_INTERFACE);
+ irq = config >> 4 & 0x0f;
+ dma = config & 0x0f;
+
+ if (high == 0x10 && low == 0xb8 && chip == 0xf1) {
+ DEBUG(0, "SMC IrDA Controller found; version = %d, "
+ "port 0x%04x, dma %d, interrupt %d\n",
+ version, iobase, dma, irq);
+ } else {


+ return -1;
+ }
+

+ serial_out(iobase, UART_MASTER, 0);
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+
+ return config;
+}
+
+/*
+ * Function ircc_change_speed (idev, baud)
+ *
+ * Change the speed of the device
+ *
+ */
+static void ircc_change_speed( struct irda_device *idev, int speed)
+{
+ struct ircc_cb *self;
+ int iobase, ir_mode, select, fast;
+
+ DEBUG(ircc_debug+1, __FUNCTION__ " -->\n");
+
+ ASSERT(idev != NULL, return;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+ self = idev->priv;
+ iobase = idev->io.iobase;
+
+ /* Update accounting for new speed */
+ idev->io.baudrate = speed;
+
+ switch ( speed) {
+ case 9600:
+ case 19200:
+ case 37600:
+ case 57600:
+ case 115200:
+ DEBUG(ircc_debug+1,
+ __FUNCTION__ ": using irport to change speed to %d\n",
+ speed);
+ register_bank(iobase, 0);
+ serial_out(iobase, UART_IER, 0);
+ serial_out(iobase, UART_MASTER, UART_MASTER_RESET);
+ serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN);
+ irport_start(idev, idev->io.iobase2);
+ irport_change_speed( idev, speed);
+ return;
+ break;
+
+ case 576000:
+ ir_mode = UART_CFGA_IRDA_HDLC;
+ select = 0;
+ fast = 0;
+ DEBUG( ircc_debug, __FUNCTION__ ": handling baud of 576000\n");
+ break;
+ case 1152000:
+ ir_mode = UART_CFGA_IRDA_HDLC;
+ select = UART_1152;
+ fast = 0;
+ DEBUG(ircc_debug, __FUNCTION__ ": handling baud of 1152000\n");
+ break;
+ case 4000000:
+ ir_mode = UART_CFGA_IRDA_4PPM;
+ select = 0;
+ fast = UART_LCR_A_FAST;
+ DEBUG(ircc_debug, __FUNCTION__ ": handling baud of 4000000\n");
+ break;
+ default:
+ DEBUG( 0, __FUNCTION__ ": unknown baud rate of %d\n", speed);
+ return;
+ }
+
+#if 0
+ serial_out(idev->io.iobase2, 4, 0x08);
+#endif
+
+ serial_out(iobase, UART_MASTER, UART_MASTER_RESET);
+
+ register_bank(iobase, 0);
+ serial_out(iobase, UART_IER, 0);
+
+ irport_stop(idev, idev->io.iobase2);
+
+ idev->netdev.tbusy = 0;
+
+ register_bank(iobase, 1);
+
+ serial_out(iobase, UART_SCE_CFGA,
+ ((serial_in(iobase, UART_SCE_CFGA) & 0x87) | ir_mode));
+
+ serial_out(iobase, UART_SCE_CFGB,
+ ((serial_in(iobase, UART_SCE_CFGB) & 0x3f) | UART_CFGB_IR));
+
+ (void) serial_in(iobase, UART_FIFO_THRESHOLD);
+ serial_out(iobase, UART_FIFO_THRESHOLD, 64);
+
+ register_bank(iobase, 4);
+
+ serial_out(iobase, UART_CONTROL,
+ (serial_in(iobase, UART_CONTROL) & 0x30)
+ | select | UART_CRC );
+
+ register_bank(iobase, 0);
+
+ serial_out(iobase, UART_LCR_A, fast);
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+}
+
+/*
+ * Function ircc_hard_xmit (skb, dev)
+ *
+ * Transmit the frame!
+ *
+ */
+static int ircc_hard_xmit( struct sk_buff *skb, struct device *dev)
+{
+ struct irda_device *idev;
+ int iobase;
+ int mtt;
+
+ DEBUG(ircc_debug+1, __FUNCTION__ " -->\n");
+ idev = (struct irda_device *) dev->priv;
+
+ ASSERT( idev != NULL, return 0;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+
+ iobase = idev->io.iobase;
+
+ DEBUG(ircc_debug+1, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len);
+
+ /* Use irport for SIR speeds */
+ if (idev->io.baudrate <= 115200) {
+ DEBUG(ircc_debug+1, __FUNCTION__ ": calling irport_hard_xmit\n");
+ return irport_hard_xmit(skb, dev);
+ }
+
+ DEBUG(ircc_debug, __FUNCTION__ ": using dma; len=%d\n", skb->len);
+
+ /* Lock transmit buffer */
+ if (irda_lock((void *) &dev->tbusy) == FALSE)
+ return -EBUSY;
+
+ memcpy( idev->tx_buff.head, skb->data, skb->len);
+
+ /* Make sure that the length is a multiple of 16 bits */
+ if ( skb->len & 0x01)
+ skb->len++;
+
+ idev->tx_buff.len = skb->len;
+ idev->tx_buff.data = idev->tx_buff.head;
+#if 0
+ idev->tx_buff.offset = 0;
+#endif
+
+ mtt = irda_get_mtt( skb);
+
+ /* Use udelay for delays less than 50 us. */
+ if (mtt)
+ udelay( mtt);
+
+ ircc_dma_write( idev, iobase);
+
+ dev_kfree_skb( skb);
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");


+ return 0;
+}
+
+/*

+ * Function ircc_dma_xmit (idev, iobase)
+ *
+ * Transmit data using DMA
+ *
+ */
+static void ircc_dma_write( struct irda_device *idev, int iobase)
+{
+ struct ircc_cb *self;
+
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+
+ ASSERT( idev != NULL, return;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+ self = idev->priv;
+ iobase = idev->io.iobase;
+
+ setup_dma( idev->io.dma, idev->tx_buff.data, idev->tx_buff.len,
+ DMA_MODE_WRITE);
+
+ idev->io.direction = IO_XMIT;
+
+ serial_out(idev->io.iobase2, 4, 0x08);
+
+ register_bank(iobase, 4);
+ serial_out(iobase, UART_CONTROL,
+ (serial_in(iobase, UART_CONTROL) & 0xF0));
+
+ serial_out(iobase, UART_BOF_COUNT_LO, 2);
+ serial_out(iobase, UART_BRICKWALL_CNT_LO, 0);
+#if 1
+ serial_out(iobase, UART_BRICKWALL_TX_CNT_HI, idev->tx_buff.len >> 8);
+ serial_out(iobase, UART_TX_SIZE_LO, idev->tx_buff.len & 0xff);
+#else
+ serial_out(iobase, UART_BRICKWALL_TX_CNT_HI, 0);
+ serial_out(iobase, UART_TX_SIZE_LO, 0);
+#endif
+
+ register_bank(iobase, 1);
+ serial_out(iobase, UART_SCE_CFGB,
+ serial_in(iobase, UART_SCE_CFGB) | UART_CFGB_DMA_ENABLE);
+
+ register_bank(iobase, 0);
+
+ serial_out(iobase, UART_IER, UART_IER_ACTIVE_FRAME | UART_IER_EOM);
+ serial_out(iobase, UART_LCR_B,
+ UART_LCR_B_SCE_TRANSMIT|UART_LCR_B_SIP_ENABLE);
+
+ serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN);
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+}
+
+/*
+ * Function ircc_dma_xmit_complete (idev)
+ *
+ * The transfer of a frame in finished. This function will only be called
+ * by the interrupt handler
+ *
+ */
+static void ircc_dma_xmit_complete( struct irda_device *idev, int underrun)
+{
+ struct ircc_cb *self;
+ int iobase, d;
+
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+
+ ASSERT( idev != NULL, return;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+ register_bank(idev->io.iobase, 1);
+
+ serial_out(idev->io.iobase, UART_SCE_CFGB,
+ serial_in(idev->io.iobase, UART_SCE_CFGB) &
+ ~UART_CFGB_DMA_ENABLE);
+
+ d = get_dma_residue(idev->io.dma);
+
+ DEBUG(ircc_debug, __FUNCTION__ ": dma residue = %d, len=%d, sent=%d\n",
+ d, idev->tx_buff.len, idev->tx_buff.len - d);
+
+ self = idev->priv;
+
+ iobase = idev->io.iobase;
+
+ /* Check for underrrun! */
+ if ( underrun) {
+ idev->stats.tx_errors++;
+ idev->stats.tx_fifo_errors++;
+ } else {
+ idev->stats.tx_packets++;
+ idev->stats.tx_bytes += idev->tx_buff.len;
+ }
+
+ /* Unlock tx_buff and request another frame */
+ idev->netdev.tbusy = 0; /* Unlock */
+ idev->media_busy = FALSE;
+
+ /* Tell the network layer, that we can accept more frames */
+ mark_bh( NET_BH);
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+}
+
+/*
+ * Function ircc_dma_receive (idev)
+ *
+ * Get ready for receiving a frame. The device will initiate a DMA
+ * if it starts to receive a frame.
+ *
+ */
+static int ircc_dma_receive( struct irda_device *idev)
+{
+ struct ircc_cb *self;
+ int iobase;
+
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+
+ ASSERT( idev != NULL, return -1;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+
+ self = idev->priv;
+ iobase= idev->io.iobase;
+
+ setup_dma( idev->io.dma, idev->rx_buff.data, idev->rx_buff.truesize,
+ DMA_MODE_READ);
+
+ /* driver->media_busy = FALSE; */
+ idev->io.direction = IO_RECV;
+ idev->rx_buff.data = idev->rx_buff.head;
+#if 0
+ idev->rx_buff.offset = 0;
+#endif
+
+ register_bank(iobase, 4);
+ serial_out(iobase, UART_CONTROL,
+ (serial_in(iobase, UART_CONTROL) &0xF0));
+ serial_out(iobase, UART_BOF_COUNT_LO, 2);
+ serial_out(iobase, UART_BRICKWALL_CNT_LO, 0);
+ serial_out(iobase, UART_BRICKWALL_TX_CNT_HI, 0);
+ serial_out(iobase, UART_TX_SIZE_LO, 0);
+ serial_out(iobase, UART_RX_SIZE_HI, 0);
+ serial_out(iobase, UART_RX_SIZE_LO, 0);
+
+ register_bank(iobase, 0);
+ serial_out(iobase,
+ UART_LCR_B, UART_LCR_B_SCE_RECEIVE | UART_LCR_B_SIP_ENABLE);
+
+ register_bank(iobase, 1);
+ serial_out(iobase, UART_SCE_CFGB,
+ serial_in(iobase, UART_SCE_CFGB) |
+ UART_CFGB_DMA_ENABLE | UART_CFGB_DMA_BURST);
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");


+ return 0;
+}
+
+/*

+ * Function ircc_dma_receive_complete (idev)
+ *
+ * Finished with receiving frames
+ *
+ *
+ */
+static int ircc_dma_receive_complete( struct irda_device *idev, int iobase)


+{
+ struct sk_buff *skb;

+ struct ircc_cb *self;
+ int len, msgcnt;
+
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+
+ self = idev->priv;
+
+ msgcnt = serial_in(idev->io.iobase, UART_LCR_B) & 0x08;
+
+ DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n",
+ get_dma_residue(idev->io.dma));
+
+ len = idev->rx_buff.truesize - get_dma_residue(idev->io.dma) - 4;
+
+ DEBUG(ircc_debug, __FUNCTION__ ": msgcnt = %d, len=%d\n", msgcnt, len);
+
+ skb = dev_alloc_skb( len+1);


+
+ if (skb == NULL) {

+ printk( KERN_INFO __FUNCTION__
+ ": memory squeeze, dropping frame.\n");
+ return FALSE;
+ }
+
+ /* Make sure IP header gets aligned */
+ skb_reserve( skb, 1);
+ skb_put( skb, len);
+
+ memcpy(skb->data, idev->rx_buff.data, len);
+ idev->stats.rx_packets++;
+
+ skb->dev = &idev->netdev;
+ skb->mac.raw = skb->data;
+ skb->protocol = htons(ETH_P_IRDA);
+ netif_rx( skb);
+
+ register_bank(idev->io.iobase, 1);
+ serial_out(idev->io.iobase, UART_SCE_CFGB,
+ serial_in(idev->io.iobase, UART_SCE_CFGB) &
+ ~UART_CFGB_DMA_ENABLE);
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+ return TRUE;
+}
+
+/*
+ * Function ircc_interrupt (irq, dev_id, regs)
+ *
+ * An interrupt from the chip has arrived. Time to do some work
+ *
+ */
+static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ int iobase, iir;
+
+ struct irda_device *idev = (struct irda_device *) dev_id;
+
+ DEBUG(ircc_debug+1, __FUNCTION__ " -->\n");
+
+ if (idev == NULL) {
+ printk( KERN_WARNING "%s: irq %d for unknown device.\n",
+ driver_name, irq);
+ return;
+ }
+
+ if (idev->io.baudrate <= 115200) {
+ DEBUG(ircc_debug+1, __FUNCTION__
+ ": routing interrupt to irport_interrupt\n");
+ return irport_interrupt( irq, dev_id, regs);
+ }
+
+ iobase = idev->io.iobase;
+
+ idev->netdev.interrupt = 1;
+
+ serial_out(iobase, UART_MASTER, 0);
+
+ register_bank(iobase, 0);
+
+ iir = serial_in(iobase, UART_IIR);
+
+ serial_out(iobase, UART_IER, 0);
+
+ DEBUG(ircc_debug, __FUNCTION__ ": iir = 0x%02x\n", iir);
+
+ if (iir & UART_IIR_EOM) {
+ DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_EOM\n");
+ if (idev->io.direction == IO_RECV) {
+ ircc_dma_receive_complete(idev, iobase);
+ } else {
+ ircc_dma_xmit_complete(idev, iobase);
+ }
+ ircc_dma_receive(idev);
+ }
+
+ if (iir & UART_IIR_ACTIVE_FRAME) {
+ DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_ACTIVE_FRAME\n");
+ idev->rx_buff.state = INSIDE_FRAME;
+#if 0
+ ircc_dma_receive(idev);
+#endif
+ }
+
+ if (iir & UART_IIR_RAW_MODE) {
+ DEBUG(ircc_debug, __FUNCTION__ ": IIR RAW mode interrupt.\n");
+ }
+
+ idev->netdev.interrupt = 0;
+
+ register_bank(iobase, 0);
+ serial_out(iobase, UART_IER, UART_IER_ACTIVE_FRAME|UART_IER_EOM);
+ serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN);
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+}
+
+/*
+ * Function ircc_wait_until_sent (idev)
+ *
+ * This function should put the current thread to sleep until all data
+ * have been sent, so it is safe to change the speed.
+ */
+static void ircc_wait_until_sent( struct irda_device *idev)
+{
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+
+ /* Just delay 60 ms */
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(6);
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+}
+
+/*
+ * Function ircc_is_receiving (idev)
+ *
+ * Return TRUE is we are currently receiving a frame
+ *
+ */
+static int ircc_is_receiving( struct irda_device *idev)
+{
+ int status = FALSE;
+ /* int iobase; */
+
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+
+ ASSERT( idev != NULL, return FALSE;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return FALSE;);
+
+ DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n",
+ get_dma_residue(idev->io.dma));
+
+ status = ( idev->rx_buff.state != OUTSIDE_FRAME);
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+
+ return status;
+}
+
+/*
+ * Function ircc_net_init (dev)
+ *
+ * Initialize network device
+ *
+ */
+static int ircc_net_init( struct device *dev)
+{
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+
+ /* Setup to be a normal IrDA network device driver */
+ irda_device_setup( dev);
+
+ /* Insert overrides below this line! */
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");


+ return 0;
+}
+
+

+/*
+ * Function ircc_net_open (dev)
+ *
+ * Start the device
+ *
+ */
+static int ircc_net_open( struct device *dev)
+{
+ struct irda_device *idev;
+ int iobase;
+
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+
+ ASSERT( dev != NULL, return -1;);
+ idev = (struct irda_device *) dev->priv;
+
+ ASSERT( idev != NULL, return 0;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+
+ iobase = idev->io.iobase;
+
+ if (request_irq( idev->io.irq, ircc_interrupt, 0, idev->name,
+ (void *) idev)) {
+ return -EAGAIN;
+ }
+ /*
+ * Always allocate the DMA channel after the IRQ,
+ * and clean up on failure.
+ */
+ if (request_dma(idev->io.dma, idev->name)) {
+ free_irq( idev->io.irq, idev);
+ return -EAGAIN;
+ }
+
+ /* Ready to play! */


+ dev->tbusy = 0;
+ dev->interrupt = 0;

+ dev->start = 1;
+
+ /* turn on interrupts */
+
+ MOD_INC_USE_COUNT;
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");


+ return 0;
+}
+
+/*

+ * Function ircc_net_close (dev)
+ *
+ * Stop the device
+ *
+ */
+static int ircc_net_close(struct device *dev)
+{
+ struct irda_device *idev;
+ int iobase;
+
+ DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+
+ /* Stop device */


+ dev->tbusy = 1;

+ dev->start = 0;
+

+ ASSERT( dev != NULL, return -1;);
+ idev = (struct irda_device *) dev->priv;
+
+ ASSERT( idev != NULL, return 0;);
+ ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+
+ iobase = idev->io.iobase;
+
+ disable_dma( idev->io.dma);
+
+ /* Disable interrupts */
+
+ free_irq( idev->io.irq, idev);
+ free_dma( idev->io.dma);
+
+ MOD_DEC_USE_COUNT;
+
+ DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");


+ return 0;
+}
+

+#ifdef MODULE
+
+MODULE_AUTHOR("Thomas Davis <tad...@jps.net>");
+MODULE_DESCRIPTION("SMC IrCC controller driver");
+MODULE_PARM(ircc_debug,"1i");
+MODULE_PARM(ircc_dma, "1i");
+MODULE_PARM(ircc_irq, "1i");
+
+/*
+ * Function init_module (void)
+ *
+ *
+ *
+ */
+int init_module(void)
+{
+ return ircc_init();
+}
+
+/*
+ * Function cleanup_module (void)
+ *
+ *
+ *
+ */
+void cleanup_module(void)
+{
+ ircc_cleanup();
+}
+
+#endif
diff -u --recursive --new-file v2.3.5/linux/drivers/net/irda/tekram.c linux/drivers/net/irda/tekram.c
--- v2.3.5/linux/drivers/net/irda/tekram.c Mon May 31 22:28:05 1999
+++ linux/drivers/net/irda/tekram.c Mon Jun 7 16:18:58 1999
@@ -1,12 +1,12 @@
X /*********************************************************************
X *
X * Filename: tekram.c
- * Version: 1.1
+ * Version: 1.2
X * Description: Implementation of the Tekram IrMate IR-210B dongle
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Wed Oct 21 20:02:35 1998
- * Modified at: Mon May 10 16:10:17 1999
+ * Modified at: Sun May 16 14:33:42 1999
X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
X * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
@@ -28,16 +28,12 @@
X #include <linux/sched.h>
X #include <linux/init.h>
X
-#include <asm/ioctls.h>
-#include <asm/segment.h>
-#include <asm/uaccess.h>
-
X #include <net/irda/irda.h>
X #include <net/irda/irda_device.h>
X #include <net/irda/irtty.h>
X #include <net/irda/dongle.h>
X
-static void tekram_reset(struct irda_device *dev, int unused);
+static void tekram_reset(struct irda_device *dev);
X static void tekram_open(struct irda_device *dev, int type);
X static void tekram_close(struct irda_device *dev);
X static void tekram_change_speed(struct irda_device *dev, int baud);
@@ -49,7 +45,7 @@
X #define TEKRAM_19200 0x03
X #define TEKRAM_9600 0x04
X
-#define TEKRAM_PW 0x10 /* Pulse select bit */
+#define TEKRAM_PW 0x10 /* Pulse select bit */
X
X static struct dongle dongle = {
X TEKRAM_DONGLE,
@@ -112,7 +108,7 @@
X
X ASSERT(idev != NULL, return;);
X ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
-
+
X switch (baud) {
X default:
X case 9600:
@@ -121,7 +117,7 @@
X case 19200:
X byte = TEKRAM_PW|TEKRAM_19200;
X break;
- case 34800:
+ case 38400:
X byte = TEKRAM_PW|TEKRAM_38400;
X break;
X case 57600:
@@ -132,6 +128,9 @@
X break;
X }
X
+ /* Need to reset the dongle and go to 9600 bps before programming */
+ tekram_reset(idev);
+
X /* Set DTR, Clear RTS */
X irda_device_set_dtr_rts(idev, TRUE, FALSE);
X
@@ -162,7 +161,7 @@
X * 3. clear DTR to SPACE state, wait at least 50 us for further
X * operation
X */
-void tekram_reset(struct irda_device *idev, int unused)
+void tekram_reset(struct irda_device *idev)
X {
X ASSERT(idev != NULL, return;);
X ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
@@ -185,8 +184,10 @@
X irda_device_set_dtr_rts(idev, TRUE, TRUE);
X
X udelay(50);
-
- /* Finished! */
+
+ /* Make sure the IrDA chip also goes to defalt speed */
+ if (idev->change_speed)
+ idev->change_speed(idev, 9600);
X }
X
X /*
diff -u --recursive --new-file v2.3.5/linux/drivers/net/irda/uircc.c linux/drivers/net/irda/uircc.c
--- v2.3.5/linux/drivers/net/irda/uircc.c Mon May 31 22:28:06 1999
+++ linux/drivers/net/irda/uircc.c Mon Jun 7 16:18:58 1999
@@ -7,7 +7,7 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Sat Dec 26 10:59:03 1998
- * Modified at: Mon May 10 22:11:09 1999
+ * Modified at: Wed May 19 15:29:56 1999
X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
X * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
@@ -216,7 +216,7 @@
X idev->netdev.open = uircc_net_open;
X idev->netdev.stop = uircc_net_close;
X
- irport_start(iobase2);
+ irport_start(idev, iobase2);
X
X /* Open the IrDA device */
X irda_device_open(idev, driver_name, self);
@@ -251,7 +251,7 @@
X /* Disable modem */
X outb(0x00, iobase+UIRCC_CR10);
X
- irport_stop(idev->io.iobase2);
+ irport_stop(idev, idev->io.iobase2);
X
X /* Release the PORT that this driver is using */
X DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase);
@@ -350,7 +350,7 @@
X case 37600:
X case 57600:
X case 115200:
- irport_start(idev->io.iobase2);
+ irport_start(idev, idev->io.iobase2);
X irport_change_speed(idev, speed);
X
X /* Some magic to disable FIR and enable SIR */
@@ -367,7 +367,7 @@
X DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n");
X break;
X case 4000000:
- irport_stop(idev->io.iobase2);
+ irport_stop(idev, idev->io.iobase2);
X
X /* Some magic to disable SIR and enable FIR */
X uircc_toshiba_cmd(&status, 0xffff, 0x001b, 0x0001);
diff -u --recursive --new-file v2.3.5/linux/drivers/net/irda/w83977af_ir.c linux/drivers/net/irda/w83977af_ir.c
--- v2.3.5/linux/drivers/net/irda/w83977af_ir.c Mon May 31 22:28:06 1999
+++ linux/drivers/net/irda/w83977af_ir.c Mon Jun 7 16:18:58 1999
@@ -6,7 +6,7 @@
X * Status: Experimental.
X * Author: Paul VanderSpek
X * Created at: Wed Nov 4 11:46:16 1998
- * Modified at: Thu May 13 08:03:27 1999
+ * Modified at: Fri May 21 22:18:19 1999
X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
X * Copyright (c) 1998-1999 Dag Brattli <da...@cs.uit.no>
@@ -80,8 +80,6 @@
X
X static struct w83977af_ir *dev_self[] = { NULL, NULL, NULL, NULL};
X
-static struct st_fifo_entry prev;
-
X /* Some prototypes */
X static int w83977af_open(int i, unsigned int iobase, unsigned int irq,
X unsigned int dma);
@@ -112,8 +110,6 @@
X int i;
X
X DEBUG(0, __FUNCTION__ "()\n");
-
- prev.status = 0;
X
X for (i=0; (io[i] < 2000) && (i < 4); i++) {
X int ioaddr = io[i];
diff -u --recursive --new-file v2.3.5/linux/drivers/net/myri_sbus.c linux/drivers/net/myri_sbus.c
--- v2.3.5/linux/drivers/net/myri_sbus.c Fri Mar 26 13:57:41 1999
+++ linux/drivers/net/myri_sbus.c Wed Jun 9 14:45:36 1999
@@ -756,6 +756,7 @@
X eth->h_proto = type;
X memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
X memcpy(eth->h_dest, neigh->ha, dev->addr_len);
+ hh->hh_len = 16;


X return 0;
X }
X

diff -u --recursive --new-file v2.3.5/linux/drivers/net/ni52.c linux/drivers/net/ni52.c
--- v2.3.5/linux/drivers/net/ni52.c Wed Oct 7 15:51:45 1998
+++ linux/drivers/net/ni52.c Tue Jun 8 10:27:18 1999
@@ -5,7 +5,7 @@
X * same Gnu Public License that covers that work.
X *
X * Alphacode 0.82 (96/09/29) for Linux 2.0.0 (or later)
- * Copyrights (c) 1994,1995,1996 by M.Hipp (Michae...@student.uni-tuebingen.de)
+ * Copyrights (c) 1994,1995,1996 by M.Hipp (hi...@informatik.uni-tuebingen.de)
X * [feel free to mail ....]
X *
X * when using as module: (no autoprobing!)
diff -u --recursive --new-file v2.3.5/linux/drivers/net/ni52.h linux/drivers/net/ni52.h
--- v2.3.5/linux/drivers/net/ni52.h Thu Apr 11 23:49:38 1996
+++ linux/drivers/net/ni52.h Tue Jun 8 10:27:18 1999
@@ -4,7 +4,7 @@
X * This is an extension to the Linux operating system, and is covered by the
X * same Gnu Public License that covers that work.
X *
- * copyrights (c) 1994 by Michael Hipp (mh...@student.uni-tuebingen.de)
+ * copyrights (c) 1994 by Michael Hipp (hi...@informatik.uni-tuebingen.de)
X *
X * I have done a look in the following sources:
X * crynwr-packet-driver by Russ Nelson
diff -u --recursive --new-file v2.3.5/linux/drivers/net/ni65.c linux/drivers/net/ni65.c
--- v2.3.5/linux/drivers/net/ni65.c Fri Oct 9 11:56:59 1998
+++ linux/drivers/net/ni65.c Tue Jun 8 10:27:18 1999
@@ -16,7 +16,7 @@
X *
X * comments/bugs/suggestions can be sent to:
X * Michael Hipp
- * email: Michae...@student.uni-tuebingen.de
+ * email: hi...@informatik.uni-tuebingen.de
X *
X * sources:
X * some things are from the 'ni6510-packet-driver for dos by Russ Nelson'
@@ -45,6 +45,7 @@
X */
X
X /*
+ * 99.Jun.8: added support for /proc/net/dev byte count for xosview (HK)
X * 96.Sept.29: virt_to_bus stuff added for new memory modell
X * 96.April.29: Added Harald Koenig's Patches (MH)
X * 96.April.13: enhanced error handling .. more tests (MH)
@@ -966,8 +967,10 @@
X p->stats.tx_errors++;
X tmdp->status2 = 0;
X }
- else
+ else {
+ p->stats.tx_bytes -= (short)(tmdp->blen);
X p->stats.tx_packets++;
+ }
X
X #ifdef XMT_VIA_SKB
X if(p->tmd_skb[p->tmdlast]) {
@@ -1054,6 +1057,7 @@
X eth_copy_and_sum(skb, (unsigned char *) p->recvbounce[p->rmdnum],len,0);
X #endif
X p->stats.rx_packets++;
+ p->stats.rx_bytes += len;
X skb->protocol=eth_type_trans(skb,dev);
X netif_rx(skb);
X }
diff -u --recursive --new-file v2.3.5/linux/drivers/net/ptifddi.c linux/drivers/net/ptifddi.c
--- v2.3.5/linux/drivers/net/ptifddi.c Wed Jun 2 14:44:39 1999
+++ linux/drivers/net/ptifddi.c Wed Jun 9 14:45:36 1999
@@ -1,4 +1,4 @@
-/* $Id: ptifddi.c,v 1.5 1997/04/16 10:27:27 jj Exp $
+/* $Id: ptifddi.c,v 1.7 1999/06/09 08:19:01 davem Exp $
X * ptifddi.c: Network driver for Performance Technologies single-attach
X * and dual-attach FDDI sbus cards.
X *
diff -u --recursive --new-file v2.3.5/linux/drivers/net/sdladrv.c linux/drivers/net/sdladrv.c
--- v2.3.5/linux/drivers/net/sdladrv.c Thu Jan 7 09:21:53 1999
+++ linux/drivers/net/sdladrv.c Wed Jun 2 14:40:22 1999
@@ -13,6 +13,7 @@
X * as published by the Free Software Foundation; either version
X * 2 of the License, or (at your option) any later version.
X * ============================================================================
+* May 19, 1999 Arnaldo Melo wanpipe_init belongs to sdlamain.c
X * Dec 20, 1996 Gene Kozin Version 3.0.0. Complete overhaul.
X * Jul 12, 1996 Gene Kozin Changes for Linux 2.0 compatibility.
X * Jun 12, 1996 Gene Kozin Added support for S503 card.
@@ -89,7 +90,6 @@
X #include <linux/sched.h> /* for jiffies, HZ, etc. */
X #include <linux/sdladrv.h> /* API definitions */
X #include <linux/sdlasfm.h> /* SDLA firmware module definitions */
-#include <linux/init.h>
X #include <asm/io.h> /* for inb(), outb(), etc. */
X #define _INB(port) (inb(port))
X #define _OUTB(port, byte) (outb((byte),(port)))
@@ -288,9 +288,6 @@
X

X #ifdef MODULE
X int init_module (void)

-#else
-__initfunc(int wanpipe_init(void))
-#endif
X {
X printk(KERN_INFO "%s v%u.%u %s\n",
X fullname, MOD_VERSION, MOD_RELEASE, copyright);
@@ -301,7 +298,6 @@


X return 0;
X }
X

-#ifdef MODULE
X /*============================================================================
X * Module 'remove' entry point.
X * o release all remaining system resources
diff -u --recursive --new-file v2.3.5/linux/drivers/net/sdlamain.c linux/drivers/net/sdlamain.c
--- v2.3.5/linux/drivers/net/sdlamain.c Mon Dec 28 11:05:14 1998
+++ linux/drivers/net/sdlamain.c Wed Jun 2 14:40:22 1999
@@ -11,6 +11,7 @@
X * as published by the Free Software Foundation; either version
X * 2 of the License, or (at your option) any later version.
X * ============================================================================
+* May 19, 1999 Arnaldo Melo __initfunc for wanpipe_init
X * Nov 28, 1997 Jaspreet Singh Changed DRV_RELEASE to 1
X * Nov 10, 1997 Jaspreet Singh Changed sti() to restore_flags();
X * Nov 06, 1997 Jaspreet Singh Changed DRV_VERSION to 4 and DRV_RELEASE to 0
@@ -42,6 +43,7 @@
X #include <linux/wanpipe.h> /* WANPIPE common user API definitions */
X #include <asm/uaccess.h> /* kernel <-> user copy */
X #include <asm/io.h> /* phys_to_virt() */
+#include <linux/init.h> /* __initfunc (when not using as a module) */
X
X
X /****** Defines & Macros ****************************************************/
@@ -122,7 +124,7 @@


X #ifdef MODULE
X int init_module (void)
X #else

-int wanpipe_init(void)
+__initfunc(int wanpipe_init(void))
X #endif
X {
X int cnt, err = 0;
diff -u --recursive --new-file v2.3.5/linux/drivers/net/sk_mca.c linux/drivers/net/sk_mca.c
--- v2.3.5/linux/drivers/net/sk_mca.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/sk_mca.c Mon Jun 7 14:34:46 1999
@@ -0,0 +1,1143 @@
+/*
+net-3-driver for the SKNET MCA-based cards
+
+This is an extension to the Linux operating system, and is covered by the
+same Gnu Public License that covers that work.
+
+Copyright 1999 by Alfred Arnold (alf...@ccac.rwth-aachen.de, aar...@elsa.de)
+
+This driver is based both on the 3C523 driver and the SK_G16 driver.
+
+paper sources:
+ 'PC Hardware: Aufbau, Funktionsweise, Programmierung' by
+ Hans-Peter Messmer for the basic Microchannel stuff
+
+ 'Linux Geraetetreiber' by Allesandro Rubini, Kalle Dalheimer
+ for help on Ethernet driver programming
+
+ 'Ethernet/IEEE 802.3 Family 1992 World Network Data Book/Handbook' by AMD
+ for documentation on the AM7990 LANCE
+
+ 'SKNET Personal Technisches Manual', Version 1.2 by Schneider&Koch
+ for documentation on the Junior board
+
+ 'SK-NET MC2+ Technical Manual", Version 1.1 by Schneider&Koch for
+ documentation on the MC2 bord
+
+ A big thank you to the S&K support for providing me so quickly with
+ documentation!
+
+ Also see http://www.syskonnect.com/
+
+ Missing things:
+
+ -> set debug level via ioctl instead of compile-time switches
+ -> I didn't follow the development of the 2.1.x kernels, so my
+ assumptions about which things changed with which kernel version
+ are probably nonsense
+
+History:
+ May 16th, 1999
+ startup
+ May 22st, 1999
+ added private structure, methods
+ begun building data structures in RAM
+ May 23nd, 1999
+ can receive frames, send frames
+ May 24th, 1999
+ modularized intialization of LANCE
+ loadable as module
+ still Tx problem :-(
+ May 26th, 1999
+ MC2 works
+ support for multiple devices
+ display media type for MC2+
+ May 28th, 1999
+ fixed problem in GetLANCE leaving interrupts turned off
+ increase TX queue to 4 packets to improve send performance
+ May 29th, 1999
+ a few corrections in statistics, caught rcvr overruns
+ reinitialization of LANCE/board in critical situations
+ MCA info implemented
+ implemented LANCE multicast filter
+ Jun 6th, 1999
+ additions for Linux 2.2
+
+ *************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/mca.h>
+#include <asm/processor.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+
+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+#endif


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

echo 'End of part 10'
echo 'File patch-2.3.6 is continued in part 11'
echo 11 > _shar_seq_.tmp
exit 0

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.3/patch-2.3.6/part14

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


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.6 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.3.6'
else
echo 'x - continuing with patch-2.3.6'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.6' &&

+ if (sc->device_flags[i] & CFSYNCHISULTRA)
+ {
+ p->ultraenb |= mask;
+ }
X }
X else if (sc->adapter_control & CFULTRAEN)
X {
@@ -8364,18 +8829,54 @@
X p->ultraenb &= ~mask;
X p->transinfo[i].user_offset = 0;
X p->transinfo[i].user_period = 0;
+ p->transinfo[i].user_options = 0;
X p->transinfo[i].cur_offset = 0;
X p->transinfo[i].cur_period = 0;
+ p->transinfo[i].cur_options = 0;


X p->needsdtr_copy &= ~mask;
X }

X else
X {


- if (p->features & AHC_ULTRA2)
+ if (p->features & AHC_ULTRA3)

+ {
+ p->transinfo[i].user_offset = MAX_OFFSET_ULTRA2;
+ p->transinfo[i].cur_offset = aic_inb(p, TARG_OFFSET + i);
+ if( (sc->device_flags[i] & CFXFER) < 0x03 )
+ {
+ scsirate = (sc->device_flags[i] & CFXFER);
+ p->transinfo[i].user_options = MSG_EXT_PPR_OPTION_DT_CRC;
+ if( (aic_inb(p, TARG_SCSIRATE + i) & CFXFER) < 0x03 )
+ {
+ p->transinfo[i].cur_options =
+ ((aic_inb(p, TARG_SCSIRATE + i) & 0x40) ?
+ MSG_EXT_PPR_OPTION_DT_CRC : MSG_EXT_PPR_OPTION_DT_UNITS);
+ }
+ else
+ {
+ p->transinfo[i].cur_options = 0;


+ }
+ }
+ else
+ {

+ scsirate = (sc->device_flags[i] & CFXFER) |
+ ((p->ultraenb & mask) ? 0x18 : 0x10);
+ p->transinfo[i].user_options = 0;
+ p->transinfo[i].cur_options = 0;
+ }
+ p->transinfo[i].user_period = aic7xxx_find_period(p, scsirate,
+ AHC_SYNCRATE_ULTRA3);
+ p->transinfo[i].cur_period = aic7xxx_find_period(p,
+ aic_inb(p, TARG_SCSIRATE + i),
+ AHC_SYNCRATE_ULTRA3);
+ }
+ else if (p->features & AHC_ULTRA2)
X {
X p->transinfo[i].user_offset = MAX_OFFSET_ULTRA2;
X p->transinfo[i].cur_offset = aic_inb(p, TARG_OFFSET + i);
X scsirate = (sc->device_flags[i] & CFXFER) |
X ((p->ultraenb & mask) ? 0x18 : 0x10);
+ p->transinfo[i].user_options = 0;
+ p->transinfo[i].cur_options = 0;
X p->transinfo[i].user_period = aic7xxx_find_period(p, scsirate,
X AHC_SYNCRATE_ULTRA2);
X p->transinfo[i].cur_period = aic7xxx_find_period(p,
@@ -8385,10 +8886,9 @@
X else
X {
X scsirate = (sc->device_flags[i] & CFXFER) << 4;
- if (sc->device_flags[i] & CFWIDEB)
- p->transinfo[i].user_offset = MAX_OFFSET_16BIT;
- else
- p->transinfo[i].user_offset = MAX_OFFSET_8BIT;
+ p->transinfo[i].user_options = 0;
+ p->transinfo[i].cur_options = 0;
+ p->transinfo[i].user_offset = MAX_OFFSET_8BIT;
X if (p->features & AHC_ULTRA)
X {
X short ultraenb;
@@ -8427,9 +8927,10 @@
X }
X aic_outb(p, ~(p->discenable & 0xFF), DISC_DSB);
X aic_outb(p, ~((p->discenable >> 8) & 0xFF), DISC_DSB + 1);
+ p->needppr = p->needppr_copy = p->needdv = 0;
X p->needwdtr = p->needwdtr_copy;
X p->needsdtr = p->needsdtr_copy;
- p->wdtr_pending = p->sdtr_pending = 0;
+ p->dtr_pending = 0;
X
X /*
X * We set the p->ultraenb from the SEEPROM to begin with, but now we make
@@ -8453,6 +8954,7 @@
X {
X case AHC_AIC7895:
X case AHC_AIC7896:
+ case AHC_AIC7899:
X if (p->adapter_control & CFBPRIMARY)
X p->flags |= AHC_CHANNEL_B_PRIMARY;
X default:
@@ -8783,6 +9285,14 @@
X {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7855, AHC_AIC7850,
X AHC_PAGESCBS, AHC_AIC7850_FE, 6,
X 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7821, AHC_AIC7860,
+ AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
+ AHC_AIC7860_FE, 7,
+ 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_3860, AHC_AIC7860,
+ AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
+ AHC_AIC7860_FE, 7,
+ 32, C46 },
X {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7860, AHC_AIC7860,
X AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
X AHC_AIC7860_FE, 7,
@@ -8825,6 +9335,18 @@
X {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7884, AHC_AIC7880,
X AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
X 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7885, AHC_AIC7880,
+ AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
+ 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7886, AHC_AIC7880,
+ AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
+ 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7887, AHC_AIC7880,
+ AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
+ 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7888, AHC_AIC7880,
+ AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18,
+ 32, C46 },
X {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7895, AHC_AIC7895,
X AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
X AHC_AIC7895_FE, 19,
@@ -8833,30 +9355,66 @@
X AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
X AHC_AIC7890_FE, 20,
X 32, C46 },
- {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_78902, AHC_AIC7890,
+ {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7890B, AHC_AIC7890,
X AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
X AHC_AIC7890_FE, 20,
X 32, C46 },
- {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_2940U2, AHC_AIC7890,
+ {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_2930U2, AHC_AIC7890,
X AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
X AHC_AIC7890_FE, 21,
X 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_2940U2, AHC_AIC7890,
+ AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
+ AHC_AIC7890_FE, 22,
+ 32, C46 },
X {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7896, AHC_AIC7896,
X AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
- AHC_AIC7896_FE, 22,
+ AHC_AIC7896_FE, 23,
X 32, C56_66 },
X {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_3940U2, AHC_AIC7896,
X AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
- AHC_AIC7896_FE, 23,
+ AHC_AIC7896_FE, 24,
X 32, C56_66 },
X {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_3950U2D, AHC_AIC7896,
X AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
- AHC_AIC7896_FE, 24,
+ AHC_AIC7896_FE, 25,
X 32, C56_66 },
X {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_1480A, AHC_AIC7860,
X AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
- AHC_AIC7860_FE, 25,
+ AHC_AIC7860_FE, 26,
+ 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892A, AHC_AIC7892,
+ AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
+ AHC_AIC7892_FE, 27,
+ 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892B, AHC_AIC7892,
+ AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
+ AHC_AIC7892_FE, 27,
+ 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892D, AHC_AIC7892,
+ AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
+ AHC_AIC7892_FE, 27,
+ 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892P, AHC_AIC7892,
+ AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
+ AHC_AIC7892_FE, 27,
X 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899A, AHC_AIC7899,
+ AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
+ AHC_AIC7899_FE, 28,
+ 32, C56_66 },
+ {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899B, AHC_AIC7899,
+ AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
+ AHC_AIC7899_FE, 28,
+ 32, C56_66 },
+ {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899D, AHC_AIC7899,
+ AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
+ AHC_AIC7899_FE, 28,
+ 32, C56_66 },
+ {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899P, AHC_AIC7899,
+ AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL,
+ AHC_AIC7899_FE, 28,
+ 32, C56_66 },
X };
X
X unsigned short command;
@@ -8926,11 +9484,11 @@
X }
X #ifdef AIC7XXX_STRICT_PCI_SETUP
X command |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
- PCI_COMMAND_INVALIDATE | PCI_COMMAND_MASTER |
- PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+ PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
X #else
X command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
X #endif
+ command &= ~PCI_COMMAND_INVALIDATE;
X if (aic7xxx_pci_parity == 0)
X command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
X pci_write_config_word(pdev, PCI_COMMAND, command);
@@ -8940,15 +9498,7 @@
X {
X printk("aic7xxx: Initial DEVCONFIG value was 0x%x\n", devconfig);
X }
- devconfig |= 0x80000000;
- if ((aic7xxx_pci_parity == 0) || (aic7xxx_pci_parity == -1))
- {
- devconfig &= ~(0x00000008);
- }
- else
- {
- devconfig |= 0x00000008;
- }
+ devconfig |= 0x80000040;
X pci_write_config_dword(pdev, DEVCONFIG, devconfig);
X #endif /* AIC7XXX_STRICT_PCI_SETUP */
X #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) */
@@ -8976,11 +9526,11 @@
X }
X #ifdef AIC7XXX_STRICT_PCI_SETUP
X command |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
- PCI_COMMAND_INVALIDATE | PCI_COMMAND_MASTER |
- PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+ PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
X #else
X command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
X #endif
+ command &= ~PCI_COMMAND_INVALIDATE;
X if (aic7xxx_pci_parity == 0)
X command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
X pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND, command);
@@ -8990,15 +9540,7 @@
X {
X printk("aic7xxx: Initial DEVCONFIG value was 0x%x\n", devconfig);
X }
- devconfig |= 0x80000000;
- if ((aic7xxx_pci_parity == 0) || (aic7xxx_pci_parity == -1))
- {
- devconfig &= ~(0x00000008);
- }
- else
- {
- devconfig |= 0x00000008;
- }
+ devconfig |= 0x80000040;
X pcibios_write_config_dword(pci_bus, pci_devfn, DEVCONFIG, devconfig);
X #endif /* AIC7XXX_STRICT_PCI_SETUP */
X #endif /* LINUIX_VERSION_CODE > KERNEL_VERSION(2,1,92) */
@@ -9137,6 +9679,7 @@
X
X case AHC_AIC7895: /* 7895 */
X case AHC_AIC7896: /* 7896/7 */
+ case AHC_AIC7899: /* 7899 */
X #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
X if (PCI_FUNC(temp_p->pdev->devfn) != 0)
X {
@@ -9185,43 +9728,38 @@
X */
X switch (temp_p->chip & AHC_CHIPID_MASK)
X {
- case AHC_AIC7890:
- case AHC_AIC7896:
+ case AHC_AIC7892:
+ case AHC_AIC7899:
X aic_outb(temp_p, 0, SCAMCTL);
X /*
- * We used to set DPARCKEN in this register, but after talking
- * to a tech from Adaptec, I found out they don't use that
- * particular bit in their own register settings, and when you
- * combine that with the fact that I determined that we were
- * seeing Data-Path Parity Errors on things we shouldn't see
- * them on, I think there is a bug in the silicon and the way
- * to work around it is to disable this particular check. Also
- * This bug only showed up on certain commands, so it seems to
- * be pattern related or some such. The commands we would
- * typically send as a linux TEST_UNIT_READY or INQUIRY command
- * could cause it to be triggered, while regular commands that
- * actually made reasonable use of the SG array capabilities
- * seemed not to cause the problem.
+ * Switch to the alt mode of the chip...
+ */
+ aic_outb(temp_p, aic_inb(temp_p, SFUNCT) | ALT_MODE, SFUNCT);
+ /*
+ * Set our options...the last two items set our CRC after x byte
+ * count in target mode...
X */
+ aic_outb(temp_p, AUTO_MSGOUT_DE | DIS_MSGIN_DUALEDGE, OPTIONMODE);
+ aic_outb(temp_p, 0x00, 0x0b);
+ aic_outb(temp_p, 0x10, 0x0a);
X /*
- aic_outb(temp_p, aic_inb(temp_p, DSCOMMAND0) |
- CACHETHEN | DPARCKEN | MPARCKEN |
- USCBSIZE32 | CIOPARCKEN,
- DSCOMMAND0);
+ * switch back to normal mode...
X */
+ aic_outb(temp_p, aic_inb(temp_p, SFUNCT) & ~ALT_MODE, SFUNCT);
+ aic_outb(temp_p, CRCVALCHKEN | CRCENDCHKEN | CRCREQCHKEN |
+ TARGCRCENDEN | TARGCRCCNTEN,
+ CRCCONTROL1);
+ aic_outb(temp_p, ((aic_inb(temp_p, DSCOMMAND0) | USCBSIZE32 |
+ MPARCKEN | CIOPARCKEN | CACHETHEN) &
+ ~DPARCKEN), DSCOMMAND0);
+ aic7xxx_load_seeprom(temp_p, &sxfrctl1);
+ break;
+ case AHC_AIC7890:
+ case AHC_AIC7896:
+ aic_outb(temp_p, 0, SCAMCTL);
X aic_outb(temp_p, (aic_inb(temp_p, DSCOMMAND0) |
X CACHETHEN | MPARCKEN | USCBSIZE32 |
X CIOPARCKEN) & ~DPARCKEN, DSCOMMAND0);
- /* FALLTHROUGH */
- default:
- /*
- * We attempt to read a SEEPROM on *everything*. If we fail,
- * then we fail, but this covers things like 2910c cards that
- * now have SEEPROMs with their 7856 chipset that we would
- * otherwise ignore. They still don't have a BIOS, but they
- * have a SEEPROM that the SCSISelect utility on the Adaptec
- * diskettes can configure.
- */
X aic7xxx_load_seeprom(temp_p, &sxfrctl1);
X break;
X case AHC_AIC7850:
@@ -9233,14 +9771,13 @@
X aic_outb(temp_p, (aic_inb(temp_p, DSCOMMAND0) |
X CACHETHEN | MPARCKEN) & ~DPARCKEN,
X DSCOMMAND0);
+ /* FALLTHROUGH */
+ default:
X aic7xxx_load_seeprom(temp_p, &sxfrctl1);
X break;
X case AHC_AIC7880:
X /*
- * Only set the DSCOMMAND0 register if this is a Rev B.
- * chipset. For those, we also enable Ultra mode by
- * force due to brain-damage on the part of some BIOSes
- * We overload the devconfig variable here since we can.
+ * Check the rev of the chipset before we change DSCOMMAND0
X */
X #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
X pci_read_config_dword(pdev, DEVCONFIG, &devconfig);
@@ -9272,6 +9809,7 @@
X {
X case AHC_AIC7895:
X case AHC_AIC7896:
+ case AHC_AIC7899:
X current_p = list_p;
X while(current_p != NULL)
X {
@@ -9315,6 +9853,7 @@
X break;
X case AHC_AIC7895:
X case AHC_AIC7896:
+ case AHC_AIC7899:
X #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
X pci_read_config_dword(pdev, DEVCONFIG, &devconfig);
X #else
@@ -9364,7 +9903,7 @@
X */
X if (temp_p->features & AHC_ULTRA2)
X {
- aic_outb(temp_p, RD_DFTHRSH_75 | WR_DFTHRSH_75, DFF_THRSH);
+ aic_outb(temp_p, RD_DFTHRSH_MAX | WR_DFTHRSH_MAX, DFF_THRSH);
X }
X else
X {
@@ -9512,7 +10051,7 @@
X }
X }
X /*
- * Are we dealing with a 7985 where we need to sort the
+ * Are we dealing with a 7895/6/7/9 where we need to sort the
X * channels as well, if so, the bios_address values should
X * be the same
X */
@@ -9603,7 +10142,54 @@
X return (found);
X }
X
-#ifdef AIC7XXX_FAKE_NEGOTIATION_CMDS
+static void aic7xxx_build_negotiation_cmnd(struct aic7xxx_host *p,
+ Scsi_Cmnd *old_cmd, int tindex);


+
+/*+F*************************************************************************
+ * Function:

+ * aic7xxx_allocate_negotiation_command


+ *
+ * Description:

+ * allocate the actual command struct and fill in the gaps...
+ *-F*************************************************************************/
+static Scsi_Cmnd *
+aic7xxx_allocate_negotiation_command(struct aic7xxx_host *p,
+ Scsi_Cmnd *old_cmd, int tindex)
+{
+ Scsi_Cmnd *cmd;
+ char *buffer;
+
+ if (!(p->dev_dtr_cmnd[tindex] = kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC)) )
+ {
+ return(NULL);
+ }
+ if (!(buffer = kmalloc(256, GFP_ATOMIC)))
+ {
+ kfree(p->dev_dtr_cmnd[tindex]);
+ p->dev_dtr_cmnd[tindex] = NULL;
+ return(NULL);
+ }
+ cmd = p->dev_dtr_cmnd[tindex];
+ memset(cmd, 0, sizeof(Scsi_Cmnd));
+ memcpy(cmd, old_cmd, sizeof(Scsi_Cmnd));
+ memset(&cmd->cmnd[0], 0, sizeof(cmd->cmnd));
+ memset(&cmd->data_cmnd[0], 0, sizeof(cmd->data_cmnd));
+ cmd->lun = 0;
+ cmd->request_bufflen = 255;
+ cmd->request_buffer = buffer;
+ cmd->use_sg = cmd->old_use_sg = cmd->sglist_len = 0;
+ cmd->bufflen = 0;
+ cmd->buffer = NULL;
+ cmd->underflow = 0;
+ cmd->cmd_len = 6;
+ cmd->cmnd[0] = cmd->data_cmnd[0] = INQUIRY;
+ cmd->cmnd[1] = cmd->data_cmnd[1] = 0;
+ cmd->cmnd[2] = cmd->data_cmnd[2] = 0;
+ cmd->cmnd[3] = cmd->data_cmnd[3] = 0;
+ cmd->cmnd[4] = cmd->data_cmnd[4] = 255; /* match what scsi.c does here */
+ cmd->cmnd[5] = cmd->data_cmnd[5] = 0;
+ return(cmd);
+}


X
X /*+F*************************************************************************
X * Function:

@@ -9616,6 +10202,117 @@
X static void
X aic7xxx_negotiation_complete(Scsi_Cmnd *cmd)
X {
+ unsigned int checksum;
+ int i;
+ int *ibuffer;
+ struct aic7xxx_host *p = (struct aic7xxx_host *)cmd->host->hostdata;
+ int tindex = TARGET_INDEX(cmd);


+ struct aic7xxx_syncrate *syncrate;
+

+ /*
+ * perform our minimalistic domain validation
+ */
+ if(p->dev_flags[tindex] & DEVICE_SCANNED)
+ {
+ ibuffer = (int *)cmd->request_buffer;
+ checksum = 0;
+ for(i = 0; i < (cmd->request_bufflen >> 2); i++)


+ {
+ checksum += ibuffer[i];
+ }

+ if( (checksum != p->dev_checksum[tindex]) &&
+ (p->transinfo[tindex].cur_offset != 0) )
+ {


+ unsigned int period = p->transinfo[tindex].cur_period;
+ unsigned char options = p->transinfo[tindex].cur_options;
+

+ if (p->needdv & (1<<tindex))
+ {


+ /*
+ * oops, we had a failure, lower the transfer rate and try again. It's
+ * worth noting here that it might be wise to also check for typical
+ * wide setting on narrow cable type problems and try disabling wide
+ * instead of slowing down if those exist. That's hard to do with simple
+ * checksums though.
+ */

+ if(aic7xxx_verbose & VERBOSE_NEGOTIATION)
+ {
+ printk(INFO_LEAD "reducing SCSI transfer speed due to Domain "
+ "validation failure.\n", p->host_no, CTL_OF_CMD(cmd));
+ }


+ if((syncrate = aic7xxx_find_syncrate(p, &period, 0, &options)) != NULL)
+ {
+ syncrate++;
+ if( (syncrate->rate[0] != NULL) &&
+ (!(p->features & AHC_ULTRA2) || (syncrate->sxfr_ultra2 == 0)) )
+ {
+ p->transinfo[tindex].goal_period = syncrate->period;
+ if( !(syncrate->sxfr_ultra2 & 0x40) )
+ {
+ p->transinfo[tindex].goal_options = 0;
+ }
+ }
+ else
+ {
+ p->transinfo[tindex].goal_offset = 0;
+ p->transinfo[tindex].goal_period = 0;
+ p->transinfo[tindex].goal_options = 0;
+ }
+ p->needppr |= (p->needppr_copy & (1<<tindex));
+ p->needsdtr |= (p->needsdtr_copy & (1<<tindex));
+ p->needwdtr |= (p->needwdtr_copy & (1<<tindex));
+ }

+ p->needdv &= ~(1<<tindex);
+ }
+ else
+ {
+ if(aic7xxx_verbose & VERBOSE_NEGOTIATION)
+ {
+ printk(INFO_LEAD "Performing Domain validation.\n",
+ p->host_no, CTL_OF_CMD(cmd));
+ }
+ /*
+ * Update the checksum in case the INQUIRY data has changed, maybe
+ * in relation to a change in the mode pages, or whatever.
+ */


+ p->dev_checksum[tindex] = checksum;

+ /*
+ * Signal that we are trying out the domain validation
+ */
+ p->needdv |= (1<<tindex);
+ /*
+ * Signal that we need to re-negotiate things, this also gets us our
+ * INQUIRY command to re-checksum off of.
+ */


+ p->needppr |= (p->needppr_copy & (1<<tindex));
+ p->needsdtr |= (p->needsdtr_copy & (1<<tindex));
+ p->needwdtr |= (p->needwdtr_copy & (1<<tindex));
+ }
+ }

+ else
+ {
+ if( (aic7xxx_verbose & VERBOSE_NEGOTIATION) &&
+ (p->needdv & (1<<tindex)) )
+ {
+ printk(INFO_LEAD "Successfully completed Domain validation.\n",
+ p->host_no, CTL_OF_CMD(cmd));
+ }
+ /*
+ * We successfully did our checksum, so don't leave the needdv flag set
+ * in case we might have set it last time through.
+ */
+ p->needdv &= ~(1<<tindex);
+ }
+ }
+
+ p->dtr_pending &= ~(0x01 << tindex);
+ /*
+ * This looks recursive in the extreme, but if this was a WDTR negotiation
+ * and we didn't follow up with SDTR yet, then this will get it started.
+ * For all other cases, this should work out to be a no-op, unless we are
+ * doing domain validation and happen to need a new negotiation command.
+ */
+ aic7xxx_build_negotiation_cmnd(p, cmd->next, tindex);
X return;
X }
X
@@ -9632,81 +10329,63 @@
X int tindex)
X {
X
- if ( (p->needwdtr & (1<<tindex)) && !(p->wdtr_pending & (1<<tindex)) )
+ if ( !(p->dtr_pending & (1<<tindex)) &&
+ ( (p->needppr & (1<<tindex)) ||


+ (p->needwdtr & (1<<tindex)) ||

+ (p->needsdtr & (1<<tindex)) ) )
X {
- if(p->dev_wdtr_cmnd[tindex] == NULL)
+ if ( (p->dev_dtr_cmnd[tindex] == NULL) &&
+ (aic7xxx_allocate_negotiation_command(p, old_cmd, tindex) == NULL) )
X {
- Scsi_Cmnd *cmd;
-
- if (!(p->dev_wdtr_cmnd[tindex] = kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC)) )
- {
- return;
- }
- cmd = p->dev_wdtr_cmnd[tindex];
- memset(cmd, 0, sizeof(Scsi_Cmnd));
- memcpy(cmd, old_cmd, sizeof(Scsi_Cmnd));
- memset(&cmd->cmnd[0], 0, sizeof(cmd->cmnd));
- memset(&cmd->data_cmnd[0], 0, sizeof(cmd->data_cmnd));
- cmd->lun = 0;
- cmd->request_bufflen = 0;
- cmd->request_buffer = NULL;
- cmd->use_sg = cmd->old_use_sg = cmd->sglist_len = 0;
- cmd->bufflen = 0;
- cmd->buffer = NULL;
- cmd->underflow = 0;
- cmd->cmd_len = 6;
+ return;
X }
X /*
- * Before sending this thing out, we also amke the cmd->next pointer
+ * Before sending this thing out, we also make the cmd->next pointer
X * point to the real command so we can stuff any possible SENSE data
- * intp the real command instead of this fake command. This has to be
+ * into the real command instead of this fake command. This has to be
X * done each time the command is built, not just the first time, hence
X * it's outside of the above if()...
X */
- p->dev_wdtr_cmnd[tindex]->next = old_cmd;
- aic7xxx_queue(p->dev_wdtr_cmnd[tindex],
- aic7xxx_negotiation_complete);
- }
- else if ( (p->needsdtr & (1<<tindex)) && !(p->sdtr_pending & (1<<tindex)) &&
- !(p->wdtr_pending & (1<<tindex)) )
- {
- if(p->dev_sdtr_cmnd[tindex] == NULL)
+ p->dev_dtr_cmnd[tindex]->next = old_cmd;
+ /*
+ * Clear the buffer so checksums come out right....
+ */
+ memset(p->dev_dtr_cmnd[tindex]->request_buffer, 0,
+ p->dev_dtr_cmnd[tindex]->request_bufflen);
+ /*
+ * Remove any commands for this particular device that might be on the
+ * waiting_scbs queue or qinfifo so that this command goes out first.
+ * This is vital for our implementation of domain validation.
+ */
+ pause_sequencer(p);
+ aic7xxx_search_qinfifo(p, old_cmd->target, old_cmd->channel, ALL_LUNS,
+ SCB_LIST_NULL, 0, TRUE, &p->delayed_scbs[tindex]);
+ unpause_sequencer(p, FALSE);
X {
- Scsi_Cmnd *cmd;
+ struct aic7xxx_scb *scb, *next;
X
- if (!(p->dev_sdtr_cmnd[tindex] = kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC)) )
+ scb = p->waiting_scbs.head;
+ while(scb != NULL)
X {
- return;
+ if( aic7xxx_match_scb(p, scb, old_cmd->target, old_cmd->channel,
+ ALL_LUNS, SCB_LIST_NULL) )
+ {
+ next = scb->q_next;
+ scbq_remove(&p->waiting_scbs, scb);
+ scbq_insert_tail(&p->delayed_scbs[tindex], scb);
+ scb = next;
+ }
+ else
+ {
+ scb = scb->q_next;
+ }
X }
- cmd = p->dev_sdtr_cmnd[tindex];
- memset(cmd, 0, sizeof(Scsi_Cmnd));
- memcpy(cmd, old_cmd, sizeof(Scsi_Cmnd));
- memset(&cmd->cmnd[0], 0, sizeof(cmd->cmnd));
- memset(&cmd->data_cmnd[0], 0, sizeof(cmd->data_cmnd));
- cmd->lun = 0;
- cmd->request_bufflen = 0;
- cmd->request_buffer = NULL;
- cmd->use_sg = cmd->old_use_sg = cmd->sglist_len = 0;
- cmd->bufflen = 0;
- cmd->buffer = NULL;
- cmd->underflow = 0;
- cmd->cmd_len = 6;
X }
- /*
- * Before sending this thing out, we also amke the cmd->next pointer
- * point to the real command so we can stuff any possible SENSE data
- * intp the real command instead of this fake command. This has to be
- * done each time the command is built, not just the first time, hence
- * it's outside of the above if()...
- */
- p->dev_sdtr_cmnd[tindex]->next = old_cmd;
- aic7xxx_queue(p->dev_sdtr_cmnd[tindex],
+ aic7xxx_queue(p->dev_dtr_cmnd[tindex],
X aic7xxx_negotiation_complete);
X }
X }
X
-#endif
-
X #ifdef AIC7XXX_VERBOSE_DEBUGGING


X /*+F*************************************************************************
X * Function:

@@ -9744,8 +10423,9 @@


X {
X unsigned short mask;

X struct aic7xxx_hwscb *hscb;
+ unsigned char tindex = TARGET_INDEX(cmd);
X
- mask = (0x01 << TARGET_INDEX(cmd));
+ mask = (0x01 << tindex);
X hscb = scb->hscb;
X
X /*
@@ -9757,11 +10437,12 @@
X if (p->discenable & mask)
X {
X hscb->control |= DISCENB;
- if (p->tagenable & mask)
+ if ( (p->tagenable & mask) &&
+ (cmd->cmnd[0] != TEST_UNIT_READY) )
X {
X cmd->tag = hscb->tag;
- p->dev_commands_sent[TARGET_INDEX(cmd)]++;
- if (p->dev_commands_sent[TARGET_INDEX(cmd)] < 200)
+ p->dev_commands_sent[tindex]++;
+ if (p->dev_commands_sent[tindex] < 200)
X {
X hscb->control |= MSG_SIMPLE_Q_TAG;
X scb->tag_action = MSG_SIMPLE_Q_TAG;
@@ -9778,74 +10459,38 @@
X hscb->control |= MSG_SIMPLE_Q_TAG;
X scb->tag_action = MSG_SIMPLE_Q_TAG;
X }
- p->dev_commands_sent[TARGET_INDEX(cmd)] = 0;
+ p->dev_commands_sent[tindex] = 0;
X }
X }
X }
- if (p->dev_flags[TARGET_INDEX(cmd)] & DEVICE_SCANNED)
+ if ( cmd == p->dev_dtr_cmnd[tindex] )
X {
-#ifdef AIC7XXX_FAKE_NEGOTIATION_CMDS
- if ( (p->needwdtr & mask) && !(p->wdtr_pending & mask) )
+ p->dtr_pending |= mask;


+ scb->tag_action = 0;

+ if (p->dev_flags[tindex] & DEVICE_SCANNED)
X {
- if (cmd == p->dev_wdtr_cmnd[TARGET_INDEX(cmd)])
+ hscb->control &= DISCENB;
+ hscb->control |= MK_MESSAGE;
+ if(p->needppr & mask)
X {
- p->wdtr_pending |= mask;


- scb->flags |= SCB_MSGOUT_WDTR;

- hscb->control &= DISCENB;


- hscb->control |= MK_MESSAGE;

- scb->tag_action = 0;
+ scb->flags |= SCB_MSGOUT_PPR;
X }
- else
+ else if(p->needwdtr & mask)
X {
- aic7xxx_build_negotiation_cmnd(p, cmd, TARGET_INDEX(cmd));


+ scb->flags |= SCB_MSGOUT_WDTR;
X }

- }
- else if ( (p->needsdtr & mask) && !(p->sdtr_pending & mask) &&
- !(p->wdtr_pending & mask) )
- {
- if (cmd == p->dev_sdtr_cmnd[TARGET_INDEX(cmd)])
+ else if(p->needsdtr & mask)
X {
- p->sdtr_pending |= mask;


X scb->flags |= SCB_MSGOUT_SDTR;

- hscb->control &= DISCENB;


- hscb->control |= MK_MESSAGE;

- scb->tag_action = 0;
- }
- else if (cmd != p->dev_wdtr_cmnd[TARGET_INDEX(cmd)])
- {
- aic7xxx_build_negotiation_cmnd(p, cmd, TARGET_INDEX(cmd));
X }
X }
-#else
- if ( (p->needwdtr & mask) && !(p->wdtr_pending & mask) &&
- !(p->sdtr_pending & mask) && (cmd->lun == 0) )
- {
- p->wdtr_pending |= mask;


- scb->flags |= SCB_MSGOUT_WDTR;

- hscb->control &= DISCENB;


- hscb->control |= MK_MESSAGE;

- scb->tag_action = 0;


-#ifdef AIC7XXX_VERBOSE_DEBUGGING
- if (aic7xxx_verbose > 0xffff)

- printk(INFO_LEAD "Building WDTR command.\n", p->host_no,
- CTL_OF_CMD(cmd));
-#endif
- }
- else if ( (p->needsdtr & mask) && !(p->wdtr_pending & mask) &&
- !(p->sdtr_pending & mask) && (cmd->lun == 0) )
- {
- p->sdtr_pending |= mask;


- scb->flags |= SCB_MSGOUT_SDTR;

- hscb->control &= DISCENB;


- hscb->control |= MK_MESSAGE;

- scb->tag_action = 0;


-#ifdef AIC7XXX_VERBOSE_DEBUGGING
- if (aic7xxx_verbose > 0xffff)

- printk(INFO_LEAD "Building SDTR command.\n", p->host_no,
- CTL_OF_CMD(cmd));
-#endif
- }
-#endif
+ }
+ if ( !(p->dtr_pending & mask) &&
+ ( (p->needppr & mask) ||
+ (p->needwdtr & mask) ||
+ (p->needsdtr & mask) ) )
+ {
+ aic7xxx_build_negotiation_cmnd(p, cmd, tindex);
X }
X hscb->target_channel_lun = ((cmd->target << 4) & 0xF0) |
X ((cmd->channel & 0x01) << 3) | (cmd->lun & 0x07);
@@ -9897,7 +10542,6 @@
X scb->sg_count = cmd->use_sg;
X hscb->SG_segment_count = cmd->use_sg;
X hscb->SG_list_pointer = cpu_to_le32(VIRT_TO_BUS(&scb->sg_list[1]));
-
X }
X else
X {
@@ -9922,12 +10566,6 @@
X hscb->data_pointer = 0;
X }
X }
-#ifdef AIC7XXX_VERBOSE_DEBUGGING
- if((cmd->cmnd[0] == TEST_UNIT_READY) && (aic7xxx_verbose & VERBOSE_PROBE2))
- {
- aic7xxx_print_scb(p, scb);
- }
-#endif
X }
X
X /*+F*************************************************************************
@@ -10262,13 +10900,14 @@
X if(p->dev_flags[i] & DEVICE_PRESENT)
X {


X mask = (0x01 << i);

- printk(INFO_LEAD "dev_flags=0x%x, WDTR:%c/%c/%c, SDTR:%c/%c/%c,"
- " q_depth=%d:%d\n",
+ printk(INFO_LEAD "dev_flags=0x%x, Pending:%c, PPR:%c/%c, WDTR:%c/%c, "
+ "SDTR:%c/%c, q_depth=%d:%d\n",
X p->host_no, 0, i, 0, p->dev_flags[i],
- (p->wdtr_pending & mask) ? 'Y' : 'N',
+ (p->dtr_pending & mask) ? 'Y' : 'N',
+ (p->needppr & mask) ? 'Y' : 'N',
+ (p->needppr_copy & mask) ? 'Y' : 'N',
X (p->needwdtr & mask) ? 'Y' : 'N',
X (p->needwdtr_copy & mask) ? 'Y' : 'N',
- (p->sdtr_pending & mask) ? 'Y' : 'N',
X (p->needsdtr & mask) ? 'Y' : 'N',
X (p->needsdtr_copy & mask) ? 'Y' : 'N',
X p->dev_active_cmds[i],
@@ -10347,13 +10986,13 @@
X * We haven't found the offending SCB yet, and it should be around
X * somewhere, so go look for it in the cards SCBs.
X */
- printk("SCBPTR CONTROL TAG PREV NEXT\n");
+ printk("SCBPTR CONTROL TAG NEXT\n");
X for(i=0; i<p->scb_data->maxhscbs; i++)
X {
X aic_outb(p, i, SCBPTR);
- printk(" %3d %02x %02x %02x %02x\n", i,
+ printk(" %3d %02x %02x %02x\n", i,
X aic_inb(p, SCB_CONTROL), aic_inb(p, SCB_TAG),
- aic_inb(p, SCB_PREV), aic_inb(p, SCB_NEXT));
+ aic_inb(p, SCB_NEXT));
X }
X }
X
@@ -10569,21 +11208,13 @@
X if ((found == 0) && (scb->flags & SCB_WAITINGQ))
X {
X int tindex = TARGET_INDEX(cmd);
-#ifdef AIC7XXX_FAKE_NEGOTIATION_CMDS


X unsigned short mask;
X

X mask = (1 << tindex);
X
- if (p->wdtr_pending & mask)
- {
- if (p->dev_wdtr_cmnd[tindex]->next != cmd)
- found = 1;
- else
- found = 0;
- }
- else if (p->sdtr_pending & mask)
+ if (p->dtr_pending & mask)
X {
- if (p->dev_sdtr_cmnd[tindex]->next != cmd)
+ if (p->dev_dtr_cmnd[tindex]->next != cmd)
X found = 1;
X else
X found = 0;
@@ -10606,7 +11237,6 @@
X DRIVER_UNLOCK
X return(SCSI_ABORT_PENDING);
X }
-#endif
X if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
X printk(INFO_LEAD "SCB found on waiting list and "
X "aborted.\n", p->host_no, CTL_OF_SCB(scb));
@@ -10864,6 +11494,8 @@
X if(aic7xxx_verbose & VERBOSE_RESET_RETURN)
X printk(INFO_LEAD "SCB on qoutfifo, returning.\n", p->host_no,
X CTL_OF_SCB(scb));
+ aic7xxx_run_done_queue(p, TRUE);
+ aic7xxx_run_waiting_queues(p);
X unpause_sequencer(p, FALSE);
X DRIVER_UNLOCK
X return(SCSI_RESET_NOT_RUNNING);
@@ -11034,16 +11666,21 @@
X int
X aic7xxx_biosparam(Disk *disk, kdev_t dev, int geom[])
X {
- int heads, sectors, cylinders;
+ int heads, sectors, cylinders, ret;
X struct aic7xxx_host *p;
+ struct buffer_head *bh;
X
X p = (struct aic7xxx_host *) disk->device->host->hostdata;
+ bh = bread(MKDEV(MAJOR(dev), MINOR(dev)&~0xf), 0, 1024);
X
- /*
- * XXX - if I could portably find the card's configuration
- * information, then this could be autodetected instead
- * of left to a boot-time switch.
- */
+ if ( bh )
+ {
+ ret = scsi_partsize(bh, disk->capacity, &geom[2], &geom[0], &geom[1]);
+ brelse(bh);
+ if ( ret != -1 )
+ return(ret);
+ }
+
X heads = 64;
X sectors = 32;
X cylinders = disk->capacity / (heads * sectors);
@@ -11150,6 +11787,12 @@
X 0x84, 0x8e, 0x90, 0x95, 0x97, 0x97, 0x9a, 0x9a, 0x9f, 0x9f,
X 0xe0, 0xf1, 0xf4, 0xf4, 0xf6, 0xf6, 0xf8, 0xf8, 0xfa, 0xfc,
X 0xfe, 0xff} },
+ {12, {0x00, 0x05, 0x08, 0x11, 0x18, 0x1f, 0x60, 0x60, 0x62, 0x66, /*7892*/
+ 0x84, 0x8e, 0x90, 0x95, 0x97, 0x97, 0x9a, 0x9a, 0x9c, 0x9f,
+ 0xe0, 0xf1, 0xf4, 0xfc} },
+ {12, {0x00, 0x05, 0x08, 0x11, 0x18, 0x1f, 0x60, 0x60, 0x62, 0x66, /*7899*/
+ 0x84, 0x8e, 0x90, 0x95, 0x97, 0x97, 0x9a, 0x9a, 0x9c, 0x9f,
+ 0xe0, 0xf1, 0xf4, 0xfc} },
X };
X #ifdef CONFIG_PCI
X static struct register_ranges cards_ns[] = {
@@ -11164,6 +11807,10 @@
X { 5, {0x04, 0x08, 0x0c, 0x1b, 0x30, 0x34, 0x3c, 0x43, 0xdc, 0xe3} },
X { 6, {0x04, 0x08, 0x0c, 0x0e, 0x10, 0x17, 0x30, 0x34, 0x3c, 0x47,
X 0xdc, 0xe3} },
+ { 6, {0x04, 0x08, 0x0c, 0x1b, 0x30, 0x34, 0x3c, 0x43, 0xdc, 0xe3,
+ 0xff, 0xff} },
+ { 6, {0x04, 0x08, 0x0c, 0x1b, 0x30, 0x34, 0x3c, 0x43, 0xdc, 0xe3,
+ 0xff, 0xff} },
X { 6, {0x04, 0x08, 0x0c, 0x1b, 0x30, 0x34, 0x3c, 0x43, 0xdc, 0xe3,
X 0xff, 0xff} }
X };
diff -u --recursive --new-file v2.3.5/linux/drivers/scsi/aic7xxx_proc.c linux/drivers/scsi/aic7xxx_proc.c
--- v2.3.5/linux/drivers/scsi/aic7xxx_proc.c Mon Jan 4 12:57:44 1999
+++ linux/drivers/scsi/aic7xxx_proc.c Wed Jun 9 16:59:15 1999
@@ -160,21 +160,17 @@
X size += sprintf(BLS, "%s", AIC7XXX_H_VERSION);
X size += sprintf(BLS, "\n");
X size += sprintf(BLS, "Compile Options:\n");
-#ifdef AIC7XXX_RESET_DELAY
- size += sprintf(BLS, " AIC7XXX_RESET_DELAY : %d\n", AIC7XXX_RESET_DELAY);
+#ifdef CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
+ size += sprintf(BLS, " TCQ Enabled By Default : Enabled\n");
+#else
+ size += sprintf(BLS, " TCQ Enabled By Default : Disabled\n");
X #endif
- size += sprintf(BLS, " AIC7XXX_TAGGED_QUEUEING: Adapter Support Enabled\n");
- size += sprintf(BLS, " Check below to see "
- "which\n"
- " devices use tagged "
- "queueing\n");
- size += sprintf(BLS, " AIC7XXX_PAGE_ENABLE : Enabled (This is no longer "
- "an option)\n");
X #ifdef AIC7XXX_PROC_STATS
X size += sprintf(BLS, " AIC7XXX_PROC_STATS : Enabled\n");
X #else
X size += sprintf(BLS, " AIC7XXX_PROC_STATS : Disabled\n");
X #endif
+ size += sprintf(BLS, " AIC7XXX_RESET_DELAY : %d\n", AIC7XXX_RESET_DELAY);
X size += sprintf(BLS, "\n");
X size += sprintf(BLS, "Adapter Configuration:\n");
X size += sprintf(BLS, " SCSI Adapter: %s\n",
@@ -194,8 +190,21 @@
X }
X if (p->features & AHC_WIDE)
X wide = "Wide ";


- if (p->features & AHC_ULTRA2)

- ultra = "Ultra2-LVD/SE ";


+ if (p->features & AHC_ULTRA3)

+ {
+ switch(p->chip & AHC_CHIPID_MASK)
+ {
+ case AHC_AIC7892:
+ case AHC_AIC7899:
+ ultra = "Ultra-160/m LVD/SE ";
+ break;
+ default:
+ ultra = "Ultra-3 LVD/SE ";
+ break;
+ }
+ }


+ else if (p->features & AHC_ULTRA2)

+ ultra = "Ultra-2 LVD/SE ";


X else if (p->features & AHC_ULTRA)

X ultra = "Ultra ";
X size += sprintf(BLS, " %s%sController%s\n",
@@ -250,11 +259,7 @@
X }
X size += sprintf(BLS, " Tag Queue Enable Flags: 0x%04x\n", p->tagenable);
X size += sprintf(BLS, "Ordered Queue Tag Flags: 0x%04x\n", p->orderedtag);
-#ifdef AIC7XXX_CMDS_PER_LUN
- size += sprintf(BLS, "Default Tag Queue Depth: %d\n", AIC7XXX_CMDS_PER_LUN);
-#else
- size += sprintf(BLS, "Default Tag Queue Depth: %d\n", 8);
-#endif
+ size += sprintf(BLS, "Default Tag Queue Depth: %d\n", AIC7XXX_CMDS_PER_DEVICE);
X size += sprintf(BLS, " Tagged Queue By Device array for aic7xxx host "
X "instance %d:\n", p->instance);
X size += sprintf(BLS, " {");
@@ -295,11 +300,12 @@
X if (p->transinfo[target].cur_offset != 0)
X {
X struct aic7xxx_syncrate *sync_rate;
+ unsigned char options = p->transinfo[target].cur_options;
X int period = p->transinfo[target].cur_period;
X int rate = (p->transinfo[target].cur_width ==
X MSG_EXT_WDTR_BUS_16_BIT) ? 1 : 0;
X
- sync_rate = aic7xxx_find_syncrate(p, &period, AHC_SYNCRATE_ULTRA2);
+ sync_rate = aic7xxx_find_syncrate(p, &period, 0, &options);
X if (sync_rate != NULL)
X {
X size += sprintf(BLS, "%s MByte/sec, offset %d\n",
@@ -313,18 +319,21 @@
X }
X }
X size += sprintf(BLS, " Transinfo settings: ");
- size += sprintf(BLS, "current(%d/%d/%d), ",
+ size += sprintf(BLS, "current(%d/%d/%d/%d), ",
X p->transinfo[target].cur_period,
X p->transinfo[target].cur_offset,
- p->transinfo[target].cur_width);
- size += sprintf(BLS, "goal(%d/%d/%d), ",
+ p->transinfo[target].cur_width,
+ p->transinfo[target].cur_options);
+ size += sprintf(BLS, "goal(%d/%d/%d/%d), ",
X p->transinfo[target].goal_period,
X p->transinfo[target].goal_offset,
- p->transinfo[target].goal_width);
- size += sprintf(BLS, "user(%d/%d/%d)\n",
+ p->transinfo[target].goal_width,
+ p->transinfo[target].goal_options);
+ size += sprintf(BLS, "user(%d/%d/%d/%d)\n",
X p->transinfo[target].user_period,
X p->transinfo[target].user_offset,
- p->transinfo[target].user_width);
+ p->transinfo[target].user_width,
+ p->transinfo[target].user_options);
X #ifdef AIC7XXX_PROC_STATS
X size += sprintf(BLS, " Total transfers %ld (%ld reads and %ld writes)\n",
X sp->r_total + sp->w_total, sp->r_total, sp->w_total);
diff -u --recursive --new-file v2.3.5/linux/drivers/scsi/aic7xxx_reg.h linux/drivers/scsi/aic7xxx_reg.h
--- v2.3.5/linux/drivers/scsi/aic7xxx_reg.h Thu Oct 8 08:07:34 1998
+++ linux/drivers/scsi/aic7xxx_reg.h Wed Jun 9 16:59:15 1999
@@ -63,6 +63,16 @@
X
X #define STCNT 0x08
X
+#define OPTIONMODE 0x08
+#define AUTORATEEN 0x80
+#define AUTOACKEN 0x40
+#define ATNMGMNTEN 0x20
+#define BUSFREEREV 0x10
+#define EXPPHASEDIS 0x08
+#define SCSIDATL_IMGEN 0x04
+#define AUTO_MSGOUT_DE 0x02
+#define DIS_MSGIN_DUALEDGE 0x01
+
X #define CLRSINT0 0x0b
X #define CLRSELDO 0x40
X #define CLRSELDI 0x20
@@ -102,8 +112,14 @@
X
X #define SSTAT2 0x0d
X #define OVERRUN 0x80
+#define SHVALID 0x40
+#define WIDE_RES 0x20
X #define SFCNT 0x1f
X #define EXP_ACTIVE 0x10
+#define CRCVALERR 0x08
+#define CRCENDERR 0x04
+#define CRCREQERR 0x02
+#define DUAL_EDGE_ERROR 0x01
X
X #define SSTAT3 0x0e
X #define SCSICNT 0xf0
@@ -412,6 +428,7 @@
X #define DPARERR 0x10
X #define SQPARERR 0x08
X #define ILLOPCODE 0x04
+#define DSCTMOUT 0x02
X #define ILLSADDR 0x02
X #define ILLHADDR 0x01
X
@@ -436,11 +453,30 @@
X
X #define QINCNT 0x9c
X
+#define SCSIDATL_IMG 0x9c
+
X #define QOUTFIFO 0x9d
X
+#define CRCCONTROL1 0x9d
+#define CRCONSEEN 0x80
+#define TARGCRCCNTEN 0x40
+#define CRCVALCHKEN 0x40
+#define CRCENDCHKEN 0x20
+#define CRCREQCHKEN 0x10
+#define TARGCRCENDEN 0x08
+
+#define SCSIPHASE 0x9e
+#define SP_STATUS 0x20
+#define SP_COMMAND 0x10
+#define SP_MSG_IN 0x08
+#define SP_MSG_OUT 0x04
+#define SP_DATA_IN 0x02
+#define SP_DATA_OUT 0x01
+
X #define QOUTCNT 0x9e
X
X #define SFUNCT 0x9f
+#define ALT_MODE 0x80
X
X #define SCB_CONTROL 0xa0
X #define MK_MESSAGE 0x80
@@ -525,14 +561,20 @@
X
X #define HNSCB_QOFF 0xf4
X
+#define HESCB_QOFF 0xf5
+
X #define SNSCB_QOFF 0xf6
X
+#define SESCB_QOFF 0xf7
+
X #define SDSCB_QOFF 0xf8
X
X #define QOFF_CTLSTA 0xfa
+#define ESTABLISH_SCB_AVAIL 0x80
X #define SCB_AVAIL 0x40
X #define SNSCB_ROLLOVER 0x20
X #define SDSCB_ROLLOVER 0x10
+#define SESCB_ROLLOVER 0x08
X #define SCB_QSIZE 0x07
X #define SCB_QSIZE_256 0x06
X
diff -u --recursive --new-file v2.3.5/linux/drivers/scsi/aic7xxx_seq.c linux/drivers/scsi/aic7xxx_seq.c
--- v2.3.5/linux/drivers/scsi/aic7xxx_seq.c Thu Oct 8 08:07:34 1998
+++ linux/drivers/scsi/aic7xxx_seq.c Wed Jun 9 16:59:16 1999
@@ -3,38 +3,44 @@
X */
X static unsigned char seqprog[] = {
X 0xff, 0x6a, 0x06, 0x08,
+ 0x7f, 0x02, 0x04, 0x08,
X 0x32, 0x6a, 0x00, 0x00,
X 0x12, 0x6a, 0x00, 0x00,
X 0xff, 0x6a, 0xd6, 0x09,
X 0xff, 0x6a, 0xdc, 0x09,
- 0x00, 0x65, 0x38, 0x59,
+ 0x00, 0x65, 0x42, 0x59,
X 0xf7, 0x01, 0x02, 0x08,
X 0xff, 0x4e, 0xc8, 0x08,
X 0xbf, 0x60, 0xc0, 0x08,
- 0x60, 0x0b, 0x7c, 0x68,
+ 0x60, 0x0b, 0x86, 0x68,
X 0x40, 0x00, 0x0e, 0x68,
X 0x08, 0x1f, 0x3e, 0x10,
- 0x60, 0x0b, 0x7c, 0x68,
+ 0x60, 0x0b, 0x86, 0x68,
X 0x40, 0x00, 0x0e, 0x68,
X 0x08, 0x1f, 0x3e, 0x10,
- 0xff, 0x3e, 0x3e, 0x60,
- 0x40, 0xfa, 0x10, 0x78,
+ 0xff, 0x3e, 0x4a, 0x60,
+ 0x40, 0xfa, 0x12, 0x78,
X 0xff, 0xf6, 0xd4, 0x08,
X 0x01, 0x4e, 0x9c, 0x18,
X 0x40, 0x60, 0xc0, 0x00,
- 0x00, 0x4d, 0x10, 0x70,
+ 0x00, 0x4d, 0x12, 0x70,
X 0x01, 0x4e, 0x9c, 0x18,
X 0xbf, 0x60, 0xc0, 0x08,
- 0x00, 0x6a, 0x72, 0x5c,
+ 0x00, 0x6a, 0x92, 0x5c,
X 0xff, 0x4e, 0xc8, 0x18,
- 0x02, 0x6a, 0x88, 0x5b,
+ 0x02, 0x6a, 0xa8, 0x5b,
X 0xff, 0x52, 0x20, 0x09,
X 0x0d, 0x6a, 0x6a, 0x00,
- 0x00, 0x52, 0xfe, 0x5b,
+ 0x00, 0x52, 0x1e, 0x5c,
+ 0x03, 0xb0, 0x52, 0x31,
+ 0xff, 0xb0, 0x52, 0x09,
+ 0xff, 0xb1, 0x54, 0x09,
+ 0xff, 0xb2, 0x56, 0x09,
+ 0xff, 0xa3, 0x50, 0x09,
X 0xff, 0x3e, 0x74, 0x09,
X 0xff, 0x90, 0x7c, 0x08,
X 0xff, 0x3e, 0x20, 0x09,
- 0x00, 0x65, 0x44, 0x58,
+ 0x00, 0x65, 0x50, 0x58,
X 0x00, 0x65, 0x0e, 0x40,
X 0xf7, 0x1f, 0xca, 0x08,
X 0x08, 0xa1, 0xc8, 0x08,
@@ -47,51 +53,50 @@
X 0x0f, 0x05, 0x0a, 0x08,
X 0x00, 0x05, 0x0a, 0x00,
X 0x5a, 0x6a, 0x00, 0x04,
- 0x12, 0x65, 0xc8, 0x00,
- 0x00, 0x01, 0x02, 0x00,
+ 0x12, 0x65, 0x02, 0x00,
X 0x31, 0x6a, 0xca, 0x00,
- 0x80, 0x37, 0x64, 0x68,
+ 0x80, 0x37, 0x6e, 0x68,
X 0xff, 0x65, 0xca, 0x18,
X 0xff, 0x37, 0xdc, 0x08,
X 0xff, 0x6e, 0xc8, 0x08,
- 0x00, 0x6c, 0x6c, 0x78,
+ 0x00, 0x6c, 0x76, 0x78,
X 0x20, 0x01, 0x02, 0x00,
X 0x4c, 0x37, 0xc8, 0x28,
- 0x08, 0x1f, 0x74, 0x78,
+ 0x08, 0x1f, 0x7e, 0x78,
X 0x08, 0x37, 0x6e, 0x00,
X 0x08, 0x64, 0xc8, 0x00,
X 0x70, 0x64, 0xca, 0x18,
X 0xff, 0x6c, 0x0a, 0x08,
X 0x20, 0x64, 0xca, 0x18,
X 0xff, 0x6c, 0x08, 0x0c,
- 0x40, 0x0b, 0x04, 0x69,
- 0x80, 0x0b, 0xf6, 0x78,
+ 0x40, 0x0b, 0x0e, 0x69,
+ 0x80, 0x0b, 0x00, 0x79,
X 0xa4, 0x6a, 0x06, 0x00,
X 0x40, 0x6a, 0x16, 0x00,
- 0x10, 0x03, 0xf2, 0x78,
+ 0x10, 0x03, 0xfc, 0x78,
X 0xff, 0x50, 0xc8, 0x08,
X 0x88, 0x6a, 0xcc, 0x00,
- 0x49, 0x6a, 0xee, 0x5b,
+ 0x49, 0x6a, 0x0e, 0x5c,
X 0x01, 0x6a, 0x26, 0x01,
X 0xff, 0x6a, 0xca, 0x08,
X 0x08, 0x01, 0x02, 0x00,
- 0x02, 0x0b, 0x92, 0x78,
+ 0x02, 0x0b, 0x9c, 0x78,
X 0xf7, 0x01, 0x02, 0x08,
X 0xff, 0x06, 0xcc, 0x08,
X 0xff, 0x66, 0x32, 0x09,
X 0x01, 0x65, 0xca, 0x18,
- 0x80, 0x66, 0xa0, 0x78,
+ 0x80, 0x66, 0xaa, 0x78,
X 0xff, 0x66, 0xa2, 0x08,
- 0x10, 0x03, 0x90, 0x68,
+ 0x10, 0x03, 0x9a, 0x68,
X 0xfc, 0x65, 0xc8, 0x18,
- 0x00, 0x65, 0xa8, 0x48,
+ 0x00, 0x65, 0xb2, 0x48,
X 0xff, 0x6a, 0x32, 0x01,
X 0x01, 0x64, 0x18, 0x19,
X 0xff, 0x6a, 0x1a, 0x09,
X 0xff, 0x6a, 0x1c, 0x09,
X 0x84, 0x6a, 0x06, 0x00,
X 0x08, 0x01, 0x02, 0x00,
- 0x02, 0x0b, 0xb2, 0x78,
+ 0x02, 0x0b, 0xbc, 0x78,
X 0xff, 0x06, 0xc8, 0x08,
X 0xff, 0x64, 0x32, 0x09,
X 0xff, 0x6a, 0xca, 0x08,
@@ -105,33 +110,33 @@
X 0x0b, 0x65, 0xca, 0x18,
X 0xff, 0x65, 0xc8, 0x08,
X 0x00, 0x8c, 0x18, 0x19,
- 0x02, 0x0b, 0xce, 0x78,
- 0x01, 0x65, 0xd4, 0x60,
+ 0x02, 0x0b, 0xd8, 0x78,
+ 0x01, 0x65, 0xde, 0x60,
X 0xf7, 0x01, 0x02, 0x08,
X 0xff, 0x06, 0x32, 0x09,
X 0xff, 0x65, 0xca, 0x18,
- 0xff, 0x65, 0xce, 0x68,
+ 0xff, 0x65, 0xd8, 0x68,
X 0x0a, 0x93, 0x26, 0x01,
- 0x00, 0x65, 0x64, 0x5c,
- 0x40, 0x51, 0xe6, 0x78,
+ 0x00, 0x65, 0x84, 0x5c,
+ 0x40, 0x51, 0xf0, 0x78,
X 0xe4, 0x6a, 0x06, 0x00,
X 0x08, 0x01, 0x02, 0x00,
- 0x04, 0x6a, 0x18, 0x5b,
+ 0x04, 0x6a, 0x40, 0x5b,
X 0x01, 0x50, 0xa0, 0x18,
- 0x00, 0x50, 0xec, 0xe0,
+ 0x00, 0x50, 0xf6, 0xe0,
X 0xff, 0x6a, 0xa0, 0x08,
X 0xff, 0x6a, 0x3a, 0x01,
X 0x02, 0x6a, 0x22, 0x01,
- 0x40, 0x51, 0xf2, 0x68,
+ 0x40, 0x51, 0xfc, 0x68,
X 0xff, 0x6a, 0x06, 0x08,
X 0x00, 0x65, 0x0e, 0x40,
X 0x20, 0x6a, 0x16, 0x00,
X 0xf0, 0x19, 0x6e, 0x08,
X 0x08, 0x6a, 0x18, 0x00,
X 0x08, 0x11, 0x22, 0x00,
- 0x08, 0x6a, 0x5a, 0x58,
+ 0x08, 0x6a, 0x66, 0x58,
X 0x08, 0x6a, 0x68, 0x00,
- 0x00, 0x65, 0x18, 0x41,
+ 0x00, 0x65, 0x22, 0x41,
X 0x12, 0x6a, 0x00, 0x00,
X 0x40, 0x6a, 0x16, 0x00,
X 0xff, 0x3e, 0x20, 0x09,
@@ -139,362 +144,373 @@
X 0xff, 0xa1, 0x6e, 0x08,
X 0x08, 0x6a, 0x18, 0x00,
X 0x08, 0x11, 0x22, 0x00,
- 0x08, 0x6a, 0x5a, 0x58,
+ 0x08, 0x6a, 0x66, 0x58,
X 0x80, 0x6a, 0x68, 0x00,
X 0x80, 0x36, 0x6c, 0x00,
- 0x00, 0x65, 0xd2, 0x5b,
+ 0x00, 0x65, 0xf2, 0x5b,
X 0xff, 0x3d, 0xc8, 0x08,
- 0xbf, 0x64, 0x48, 0x79,
- 0x80, 0x64, 0xf0, 0x71,
- 0xa0, 0x64, 0x0e, 0x72,
- 0xc0, 0x64, 0x08, 0x72,
- 0xe0, 0x64, 0x52, 0x72,
+ 0xbf, 0x64, 0x58, 0x79,
+ 0x80, 0x64, 0x0e, 0x72,
+ 0xa0, 0x64, 0x3a, 0x72,
+ 0xc0, 0x64, 0x32, 0x72,
+ 0xe0, 0x64, 0x7a, 0x72,
X 0x01, 0x6a, 0x22, 0x01,
- 0x00, 0x65, 0x18, 0x41,
+ 0x00, 0x65, 0x22, 0x41,
X 0xf7, 0x11, 0x22, 0x08,
- 0x00, 0x65, 0x38, 0x59,
+ 0x00, 0x65, 0x42, 0x59,
X 0xff, 0x06, 0xd4, 0x08,
X 0xf7, 0x01, 0x02, 0x08,
- 0x09, 0x0c, 0x32, 0x79,
+ 0x09, 0x0c, 0x3c, 0x79,
X 0x08, 0x0c, 0x0e, 0x68,
X 0x01, 0x6a, 0x22, 0x01,
X 0xff, 0x6a, 0x26, 0x09,
+ 0x02, 0x6a, 0x08, 0x30,
X 0xff, 0x6a, 0x08, 0x08,
X 0xdf, 0x01, 0x02, 0x08,
X 0x01, 0x6a, 0x7a, 0x00,
- 0x03, 0x36, 0x6c, 0x0c,
+ 0xff, 0x6a, 0x6c, 0x0c,
+ 0x03, 0xa9, 0x18, 0x31,
+ 0x03, 0xa9, 0x10, 0x30,
X 0x08, 0x6a, 0xcc, 0x00,
- 0xa9, 0x6a, 0xe8, 0x5b,
- 0x00, 0x65, 0x66, 0x41,
+ 0xa9, 0x6a, 0x08, 0x5c,
+ 0x00, 0x65, 0x78, 0x41,
X 0xa8, 0x6a, 0x6a, 0x00,
X 0x79, 0x6a, 0x6a, 0x00,
- 0x40, 0x3d, 0x50, 0x69,
+ 0x40, 0x3d, 0x60, 0x69,
X 0x04, 0x35, 0x6a, 0x00,
- 0x00, 0x65, 0x3a, 0x5b,
+ 0x00, 0x65, 0x62, 0x5b,
X 0x80, 0x6a, 0xd4, 0x01,
- 0x10, 0x36, 0x42, 0x69,
+ 0x10, 0x36, 0x4e, 0x69,
X 0x10, 0x36, 0x6c, 0x00,
X 0x07, 0xac, 0x10, 0x31,
+ 0x03, 0x8c, 0x10, 0x30,
+ 0x05, 0xa3, 0x70, 0x30,
X 0x88, 0x6a, 0xcc, 0x00,
- 0xac, 0x6a, 0xe0, 0x5b,
- 0x00, 0x65, 0xda, 0x5b,
- 0xff, 0xa3, 0x70, 0x08,
- 0x39, 0x6a, 0xcc, 0x00,
- 0xa4, 0x6a, 0xe6, 0x5b,
- 0xff, 0x38, 0x74, 0x69,
+ 0xac, 0x6a, 0x00, 0x5c,
+ 0x00, 0x65, 0xfa, 0x5b,
+ 0x38, 0x6a, 0xcc, 0x00,
+ 0xa3, 0x6a, 0x04, 0x5c,
+ 0xff, 0x38, 0x88, 0x69,
X 0x80, 0x02, 0x04, 0x00,
X 0xe7, 0x35, 0x6a, 0x08,
X 0x03, 0x69, 0x18, 0x31,
+ 0x03, 0x69, 0x10, 0x30,
X 0xff, 0x6a, 0x10, 0x00,
X 0xff, 0x6a, 0x12, 0x00,
X 0xff, 0x6a, 0x14, 0x00,
- 0x01, 0x38, 0x7a, 0x61,
- 0x02, 0xfc, 0xf8, 0x01,
+ 0x01, 0x38, 0x8c, 0x61,
X 0xbf, 0x35, 0x6a, 0x08,
X 0xff, 0x69, 0xca, 0x08,
X 0xff, 0x35, 0x26, 0x09,
- 0x04, 0x0b, 0x7e, 0x69,
- 0x04, 0x0b, 0x8a, 0x69,
- 0x10, 0x0c, 0x80, 0x79,
- 0x04, 0x0b, 0x88, 0x69,
+ 0x04, 0x0b, 0x90, 0x69,
+ 0x04, 0x0b, 0x9c, 0x69,
+ 0x10, 0x0c, 0x92, 0x79,
+ 0x04, 0x0b, 0x9a, 0x69,
X 0xff, 0x6a, 0xca, 0x08,
- 0x00, 0x35, 0x22, 0x5b,
- 0x80, 0x02, 0xd6, 0x69,
- 0xff, 0x65, 0xc8, 0x79,
+ 0x00, 0x35, 0x4a, 0x5b,
+ 0x80, 0x02, 0xf0, 0x69,
+ 0xff, 0x65, 0xe0, 0x79,
X 0xff, 0x38, 0x70, 0x18,
- 0xff, 0x38, 0xc8, 0x79,
- 0x80, 0xea, 0xaa, 0x61,
+ 0xff, 0x38, 0xe0, 0x79,
+ 0x80, 0xea, 0xbc, 0x61,
X 0xef, 0x38, 0xc8, 0x18,
X 0x80, 0x6a, 0xc8, 0x00,
- 0x00, 0x65, 0x9c, 0x49,
+ 0x00, 0x65, 0xae, 0x49,
X 0x33, 0x38, 0xc8, 0x28,
X 0xff, 0x64, 0xd0, 0x09,
X 0x04, 0x39, 0xc0, 0x31,
X 0x09, 0x6a, 0xd6, 0x01,
- 0x80, 0xeb, 0xa2, 0x79,
+ 0x80, 0xeb, 0xb4, 0x79,
X 0xf7, 0xeb, 0xd6, 0x09,
- 0x08, 0xeb, 0xa6, 0x69,
+ 0x08, 0xeb, 0xb8, 0x69,
X 0x01, 0x6a, 0xd6, 0x01,
X 0x08, 0xe9, 0x10, 0x31,
+ 0x03, 0x8c, 0x10, 0x30,
X 0x88, 0x6a, 0xcc, 0x00,
- 0x39, 0x6a, 0xe6, 0x5b,
+ 0x39, 0x6a, 0x06, 0x5c,
X 0x08, 0x6a, 0x18, 0x01,
X 0xff, 0x6a, 0x1a, 0x09,
X 0xff, 0x6a, 0x1c, 0x09,
X 0x0d, 0x93, 0x26, 0x01,
- 0x00, 0x65, 0x64, 0x5c,
- 0x88, 0x6a, 0x54, 0x5c,
- 0x00, 0x65, 0xda, 0x5b,
+ 0x00, 0x65, 0x84, 0x5c,
+ 0x88, 0x6a, 0x74, 0x5c,
+ 0x00, 0x65, 0xfa, 0x5b,
X 0xff, 0x6a, 0xc8, 0x08,
X 0x08, 0x39, 0x72, 0x18,
X 0x00, 0x3a, 0x74, 0x20,
- 0x10, 0x0c, 0x66, 0x79,
- 0x80, 0x93, 0x26, 0x01,
- 0x00, 0x65, 0xe0, 0x59,
+ 0x01, 0x0c, 0xd8, 0x79,
+ 0x10, 0x0c, 0x78, 0x79,
+ 0xff, 0x35, 0x26, 0x09,
+ 0x04, 0x0b, 0xde, 0x69,
+ 0x00, 0x65, 0xf8, 0x59,
+ 0x03, 0x08, 0x52, 0x31,
+ 0xff, 0x38, 0x50, 0x09,
X 0xff, 0x08, 0x52, 0x09,
X 0xff, 0x09, 0x54, 0x09,
X 0xff, 0x0a, 0x56, 0x09,
X 0xff, 0x38, 0x50, 0x09,
- 0x12, 0x01, 0x02, 0x00,
- 0x00, 0x65, 0x18, 0x41,
- 0x00, 0x65, 0xe0, 0x59,
- 0x12, 0x01, 0x02, 0x00,
+ 0x00, 0x65, 0x22, 0x41,
+ 0x00, 0x65, 0xf8, 0x59,
X 0x7f, 0x02, 0x04, 0x08,
X 0xe1, 0x6a, 0x22, 0x01,
- 0x00, 0x65, 0x18, 0x41,
- 0x04, 0x93, 0xea, 0x69,
+ 0x00, 0x65, 0x22, 0x41,
+ 0x04, 0x93, 0x02, 0x6a,
X 0xdf, 0x93, 0x26, 0x09,
- 0x20, 0x93, 0xe4, 0x69,
+ 0x20, 0x93, 0xfc, 0x69,
X 0x02, 0x93, 0x26, 0x01,
- 0x01, 0x94, 0xe6, 0x79,
+ 0x01, 0x94, 0xfe, 0x79,
X 0xd7, 0x93, 0x26, 0x09,
- 0x08, 0x93, 0xec, 0x69,
+ 0x08, 0x93, 0x04, 0x6a,
+ 0x03, 0x08, 0x52, 0x31,
+ 0xff, 0x38, 0x50, 0x09,
+ 0x12, 0x01, 0x02, 0x00,
X 0xff, 0x6a, 0xd4, 0x0c,
- 0x00, 0x65, 0x3a, 0x5b,
- 0x02, 0xfc, 0xf8, 0x01,
+ 0x00, 0x65, 0x62, 0x5b,
X 0x05, 0xb4, 0x10, 0x31,
X 0x02, 0x6a, 0x1a, 0x31,
+ 0x03, 0x8c, 0x10, 0x30,
X 0x88, 0x6a, 0xcc, 0x00,
- 0xb4, 0x6a, 0xe4, 0x5b,
+ 0xb4, 0x6a, 0x04, 0x5c,
X 0xff, 0x6a, 0x1a, 0x09,
X 0xff, 0x6a, 0x1c, 0x09,
- 0x00, 0x65, 0xda, 0x5b,
- 0x3d, 0x6a, 0x22, 0x5b,
- 0xac, 0x6a, 0x22, 0x5b,
- 0x00, 0x65, 0x18, 0x41,
- 0x00, 0x65, 0x3a, 0x5b,
+ 0x00, 0x65, 0xfa, 0x5b,
+ 0x3d, 0x6a, 0x4a, 0x5b,
+ 0xac, 0x6a, 0x26, 0x01,
+ 0x04, 0x0b, 0x24, 0x6a,
+ 0x01, 0x0b, 0x2a, 0x6a,
+ 0x10, 0x0c, 0x26, 0x7a,
+ 0xd7, 0x93, 0x26, 0x09,
+ 0x08, 0x93, 0x2c, 0x6a,
+ 0x12, 0x01, 0x02, 0x00,
+ 0x00, 0x65, 0x22, 0x41,
+ 0x00, 0x65, 0x62, 0x5b,
X 0xff, 0x06, 0x44, 0x09,
- 0x00, 0x65, 0x18, 0x41,
+ 0x00, 0x65, 0x22, 0x41,
+ 0x10, 0x3d, 0x06, 0x00,
X 0xff, 0x34, 0xca, 0x08,
- 0x80, 0x65, 0x32, 0x62,
+ 0x80, 0x65, 0x5e, 0x62,
X 0x0f, 0xa1, 0xca, 0x08,
X 0x07, 0xa1, 0xca, 0x08,
X 0x40, 0xa0, 0xc8, 0x08,
X 0x00, 0x65, 0xca, 0x00,
X 0x80, 0x65, 0xca, 0x00,
- 0x80, 0xa0, 0x22, 0x7a,
+ 0x80, 0xa0, 0x4e, 0x7a,
X 0xff, 0x65, 0x0c, 0x08,
- 0x00, 0x65, 0x34, 0x42,
- 0x20, 0xa0, 0x3a, 0x7a,
+ 0x00, 0x65, 0x60, 0x42,
+ 0x20, 0xa0, 0x66, 0x7a,
X 0xff, 0x65, 0x0c, 0x08,
- 0x00, 0x65, 0xd2, 0x5b,
- 0xa0, 0x3d, 0x46, 0x62,
+ 0x00, 0x65, 0xf2, 0x5b,
+ 0xa0, 0x3d, 0x6e, 0x62,
X 0x23, 0xa0, 0x0c, 0x08,
- 0x00, 0x65, 0xd2, 0x5b,
- 0xa0, 0x3d, 0x46, 0x62,
- 0x00, 0xb9, 0x3a, 0x42,
- 0xff, 0x65, 0x3a, 0x62,
+ 0x00, 0x65, 0xf2, 0x5b,
+ 0xa0, 0x3d, 0x6e, 0x62,
+ 0x00, 0xb9, 0x66, 0x42,
+ 0xff, 0x65, 0x66, 0x62,
X 0xa1, 0x6a, 0x22, 0x01,
X 0xff, 0x6a, 0xd4, 0x08,
- 0x10, 0x51, 0x46, 0x72,
+ 0x10, 0x51, 0x6e, 0x72,
X 0x40, 0x6a, 0x18, 0x00,
X 0xff, 0x65, 0x0c, 0x08,
- 0x00, 0x65, 0xd2, 0x5b,
- 0xa0, 0x3d, 0x46, 0x62,
- 0x10, 0x3d, 0x06, 0x00,
- 0x00, 0x65, 0x0e, 0x42,
+ 0x00, 0x65, 0xf2, 0x5b,
+ 0xa0, 0x3d, 0x38, 0x72,
X 0x40, 0x6a, 0x18, 0x00,
X 0xff, 0x34, 0xa6, 0x08,
- 0x80, 0x34, 0x4e, 0x62,
+ 0x80, 0x34, 0x76, 0x62,
X 0x7f, 0xa0, 0x40, 0x09,
X 0x08, 0x6a, 0x68, 0x00,
- 0x00, 0x65, 0x18, 0x41,
- 0x64, 0x6a, 0x12, 0x5b,
- 0x80, 0x64, 0xbe, 0x6a,
- 0x04, 0x64, 0xa4, 0x72,
- 0x02, 0x64, 0xaa, 0x72,
- 0x00, 0x6a, 0x6c, 0x72,
- 0x03, 0x64, 0xba, 0x72,
- 0x01, 0x64, 0xa0, 0x72,
- 0x07, 0x64, 0x00, 0x73,
- 0x08, 0x64, 0x68, 0x72,
+ 0x00, 0x65, 0x22, 0x41,
+ 0x64, 0x6a, 0x3a, 0x5b,
+ 0x80, 0x64, 0xea, 0x6a,
+ 0x04, 0x64, 0xcc, 0x72,
+ 0x02, 0x64, 0xd2, 0x72,
+ 0x00, 0x6a, 0x94, 0x72,
+ 0x03, 0x64, 0xe6, 0x72,
+ 0x01, 0x64, 0xc8, 0x72,
+ 0x07, 0x64, 0x28, 0x73,
+ 0x08, 0x64, 0x90, 0x72,
X 0x11, 0x6a, 0x22, 0x01,
- 0x07, 0x6a, 0x04, 0x5b,
+ 0x07, 0x6a, 0x2c, 0x5b,
X 0xff, 0x06, 0xd4, 0x08,
- 0x00, 0x65, 0x18, 0x41,
- 0xff, 0xa8, 0x70, 0x6a,
- 0xff, 0xa2, 0x88, 0x7a,
+ 0x00, 0x65, 0x22, 0x41,
+ 0xff, 0xa8, 0x98, 0x6a,
+ 0xff, 0xa2, 0xb0, 0x7a,
X 0x01, 0x6a, 0x6a, 0x00,
- 0x00, 0xb9, 0xfe, 0x5b,
- 0xff, 0xa2, 0x88, 0x7a,
+ 0x00, 0xb9, 0x1e, 0x5c,
+ 0xff, 0xa2, 0xb0, 0x7a,
X 0x71, 0x6a, 0x22, 0x01,
X 0xff, 0x6a, 0xd4, 0x08,
- 0x40, 0x51, 0x88, 0x62,
+ 0x40, 0x51, 0xb0, 0x62,
X 0x0d, 0x6a, 0x6a, 0x00,
- 0x00, 0xb9, 0xfe, 0x5b,
+ 0x00, 0xb9, 0x1e, 0x5c,
X 0xff, 0x3e, 0x74, 0x09,
X 0xff, 0x90, 0x7c, 0x08,
- 0x00, 0x65, 0x44, 0x58,
- 0x00, 0x65, 0x2a, 0x41,
- 0x20, 0xa0, 0x90, 0x6a,
+ 0x00, 0x65, 0x50, 0x58,
+ 0x00, 0x65, 0x34, 0x41,
+ 0x20, 0xa0, 0xb8, 0x6a,
X 0xff, 0x37, 0xc8, 0x08,
- 0x00, 0x6a, 0xa8, 0x5b,
- 0xff, 0x6a, 0xbe, 0x5b,
+ 0x00, 0x6a, 0xc8, 0x5b,
+ 0xff, 0x6a, 0xde, 0x5b,
X 0xff, 0xf8, 0xc8, 0x08,
X 0xff, 0x4f, 0xc8, 0x08,
- 0x01, 0x6a, 0xa8, 0x5b,
- 0x00, 0xb9, 0xbe, 0x5b,
+ 0x01, 0x6a, 0xc8, 0x5b,
+ 0x00, 0xb9, 0xde, 0x5b,
X 0x01, 0x4f, 0x9e, 0x18,
X 0x02, 0x6a, 0x22, 0x01,
- 0x00, 0x65, 0x6c, 0x5c,
- 0x00, 0x65, 0x2a, 0x41,
+ 0x00, 0x65, 0x8c, 0x5c,
+ 0x00, 0x65, 0x34, 0x41,
X 0x41, 0x6a, 0x22, 0x01,
- 0x00, 0x65, 0x18, 0x41,
+ 0x00, 0x65, 0x22, 0x41,
X 0x04, 0xa0, 0x40, 0x01,
- 0x00, 0x65, 0x84, 0x5c,
- 0x00, 0x65, 0x2a, 0x41,
- 0x10, 0x36, 0x68, 0x7a,
- 0xff, 0x38, 0x46, 0x09,
- 0xa4, 0x6a, 0xcc, 0x00,
- 0x39, 0x6a, 0xe6, 0x5b,
+ 0x00, 0x65, 0xa4, 0x5c,
+ 0x00, 0x65, 0x34, 0x41,
+ 0x10, 0x36, 0x90, 0x7a,
+ 0x05, 0x38, 0x46, 0x31,
+ 0x04, 0x14, 0x58, 0x31,
+ 0x03, 0xa9, 0x60, 0x31,
+ 0xa3, 0x6a, 0xcc, 0x00,
+ 0x38, 0x6a, 0x04, 0x5c,
X 0xac, 0x6a, 0xcc, 0x00,
- 0x14, 0x6a, 0xe6, 0x5b,
- 0xa9, 0x6a, 0xe8, 0x5b,


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

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

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.3/patch-2.3.6/part16

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


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.6 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.3.6'
else
echo 'x - continuing with patch-2.3.6'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.6' &&

+ if(schp->use_sg > 0) {
+ int k, mem_src;
+ struct scatterlist * sclp = (struct scatterlist *)schp->buffer;
+
+ for (k = 0; (k < schp->use_sg) && sclp->address; ++k, ++sclp) {
X mem_src = (int)(long)sclp->alt_address;
X SCSI_LOG_TIMEOUT(5,
- printk("sg_sc_undo_rem: k=%d, a=0x%p, len=%d, ms=%d\n",
+ printk("sg_remove_scat: k=%d, a=0x%p, len=%d, ms=%d\n",
X k, sclp->address, sclp->length, mem_src));
- sg_free(srp, sclp->address, sclp->length, mem_src);
+ sg_free(sclp->address, sclp->length, mem_src);
+ sclp->address = NULL;
+ sclp->length = 0;
+ }
+ sg_free(schp->buffer, schp->sglist_len, schp->mem_src);
+ }
+ else if (schp->buffer)
+ sg_free(schp->buffer, schp->b_malloc_len, schp->mem_src);
+ schp->buffer = NULL;
+ schp->bufflen = 0;
+ schp->use_sg = 0;
+ schp->sglist_len = 0;
+}
+
+static void sg_read_xfer(Sg_scatter_hold * schp, char * outp,
+ int num_read_xfer)
+{
+ SCSI_LOG_TIMEOUT(4, printk("sg_read_xfer: num_read_xfer=%d\n",
+ num_read_xfer));
+ if ((! outp) || (num_read_xfer <= 0))
+ return;
+ if(schp->use_sg > 0) {
+ int k, num;
+ struct scatterlist * sclp = (struct scatterlist *)schp->buffer;
+
+ for (k = 0; (k < schp->use_sg) && sclp->address; ++k, ++sclp) {
+ num = (int)sclp->length;
+ if (num > num_read_xfer) {
+ __copy_to_user(outp, sclp->address, num_read_xfer);
+ break;
+ }
+ else {
+ __copy_to_user(outp, sclp->address, num);
+ num_read_xfer -= num;
+ if (num_read_xfer <= 0)
+ break;
+ outp += num;
+ }
X }
- sg_free(srp, srp->data.buffer, srp->data.sglist_len,
- srp->data.mem_src);
+ }
+ else
+ __copy_to_user(outp, schp->buffer, num_read_xfer);
+}
+
+static void sg_build_reserve(Sg_fd * sfp, int req_size)
+{
+ Sg_scatter_hold * schp = &sfp->reserve;
+
+ SCSI_LOG_TIMEOUT(4, printk("sg_build_reserve: req_size=%d\n", req_size));
+ do {
+ if (req_size < PAGE_SIZE)
+ req_size = PAGE_SIZE;
+ if (0 == sg_build_scat(schp, req_size, sfp))
+ return;
+ else
+ sg_remove_scat(schp);
+ req_size >>= 1; /* divide by 2 */
+ } while (req_size > (PAGE_SIZE / 2));
+}
+
+static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
+{
+ Sg_scatter_hold * req_schp = &srp->data;
+ Sg_scatter_hold * rsv_schp = &sfp->reserve;
+
+ SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
+ if (rsv_schp->use_sg > 0) {
+ int k, num;
+ int rem = size;
+ struct scatterlist * sclp = (struct scatterlist *)rsv_schp->buffer;
+
+ for (k = 0; k < rsv_schp->use_sg; ++k, ++sclp) {
+ num = (int)sclp->length;
+ if (rem <= num) {
+ sfp->save_scat_len = num;
+ sclp->length = (unsigned)rem;
+ break;
+ }
+ else
+ rem -= num;
+ }
+ if (k < rsv_schp->use_sg) {
+ req_schp->use_sg = k + 1; /* adjust scatter list length */
+ req_schp->bufflen = size;
+ req_schp->sglist_len = rsv_schp->sglist_len;
+ req_schp->buffer = rsv_schp->buffer;
+ req_schp->mem_src = rsv_schp->mem_src;
+ req_schp->b_malloc_len = rsv_schp->b_malloc_len;
+ }
+ else
+ SCSI_LOG_TIMEOUT(1, printk("sg_link_reserve: BAD size\n"));
X }
X else {
- if (num_read_xfer > 0)
- __copy_to_user(outp, srp->data.buffer, num_read_xfer);
- sg_free(srp, srp->data.buffer, srp->data.b_malloc_len,
- srp->data.mem_src);
- }
- if (0 == sg_remove_request(srp->parentfp, srp)) {
- SCSI_LOG_TIMEOUT(1, printk("sg_sc_undo_rem: srp=0x%p not found\n",
- srp));
+ req_schp->use_sg = 0;
+ req_schp->bufflen = size;
+ req_schp->buffer = rsv_schp->buffer;
+ req_schp->mem_src = rsv_schp->mem_src;
+ req_schp->use_sg = rsv_schp->use_sg;
+ req_schp->b_malloc_len = rsv_schp->b_malloc_len;
X }
- return 0;
+ srp->res_used = 1;
+}
+
+static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp)
+{
+ Sg_scatter_hold * req_schp = &srp->data;
+ Sg_scatter_hold * rsv_schp = &sfp->reserve;
+
+ SCSI_LOG_TIMEOUT(4, printk("sg_unlink_reserve: req->use_sg=%d\n",
+ (int)req_schp->use_sg));
+ if (rsv_schp->use_sg > 0) {
+ struct scatterlist * sclp = (struct scatterlist *)rsv_schp->buffer;
+
+ if (sfp->save_scat_len > 0)
+ (sclp + (req_schp->use_sg - 1))->length =
+ (unsigned)sfp->save_scat_len;
+ else
+ SCSI_LOG_TIMEOUT(1, printk(
+ "sg_unlink_reserve: BAD save_scat_len\n"));
+ }
+ req_schp->use_sg = 0;
+ req_schp->bufflen = 0;
+ req_schp->buffer = NULL;
+ req_schp->sglist_len = 0;
+ sfp->save_scat_len = 0;
+ srp->res_used = 0;
X }
X
X static Sg_request * sg_get_request(const Sg_fd * sfp, int pack_id)
@@ -1292,7 +1449,7 @@
X if (resp) {
X resp->parentfp = sfp;
X resp->nextrp = NULL;
- resp->fb_used = 0;
+ resp->res_used = 0;
X memset(&resp->data, 0, sizeof(Sg_scatter_hold));
X memset(&resp->header, 0, sizeof(struct sg_header));
X resp->my_cmdp = NULL;
@@ -1347,13 +1504,6 @@
X sdp->device->host->unchecked_isa_dma : 1;
X sfp->cmd_q = SG_DEF_COMMAND_Q;
X sfp->underrun_flag = SG_DEF_UNDERRUN_FLAG;
- if (get_reserved)
- sfp->fst_buf = sg_low_malloc(SG_SCATTER_SZ, sfp->low_dma,
- SG_HEAP_PAGE, &sfp->fb_size);
- else
- sfp->fst_buf = NULL;
- if (! sfp->fst_buf)
- sfp->fb_size = 0;
X sfp->parentdp = sdp;
X if (! sdp->headfp)
X sdp->headfp = sfp;
@@ -1363,11 +1513,14 @@
X pfp = pfp->nextfp;
X pfp->nextfp = sfp;
X }
- sg_big_buff = sfp->fb_size; /* show sysctl most recent "fb" size */
X SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p, m_s=%d\n",
X sfp, (int)sfp->my_mem_src));
- SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: fb_sz=%d, fst_buf=0x%p\n",
- sfp->fb_size, sfp->fst_buf));
+ if (get_reserved) {
+ sg_build_reserve(sfp, SG_DEF_RESERVED_SIZE);
+ sg_big_buff = sfp->reserve.bufflen; /* sysctl shows most recent size */
+ SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: bufflen=%d, use_sg=%d\n",
+ sfp->reserve.bufflen, sfp->reserve.use_sg));
+ }
X return sfp;
X }
X
@@ -1388,7 +1541,7 @@
X while (srp) {
X tsrp = srp->nextrp;
X if (! srp->my_cmdp)
- sg_sc_undo_rem(srp, NULL, 0);
+ sg_finish_rem_req(srp, NULL, 0);
X else
X ++dirty;
X srp = tsrp;
@@ -1409,12 +1562,12 @@
X prev_fp = fp;
X }
X }
-SCSI_LOG_TIMEOUT(6, printk("sg_remove_sfp: fb_sz=%d, fst_buf=0x%p\n",
- sfp->fb_size, sfp->fst_buf));
- sg_low_free(sfp->fst_buf, sfp->fb_size, SG_HEAP_PAGE);
+ if (sfp->reserve.bufflen > 0) {
+SCSI_LOG_TIMEOUT(6, printk("sg_remove_sfp: bufflen=%d, use_sg=%d\n",
+ (int)sfp->reserve.bufflen, (int)sfp->reserve.use_sg));
+ sg_remove_scat(&sfp->reserve);
+ }
X sfp->parentdp = NULL;
- sfp->fst_buf = NULL;
- sfp->fb_size = 0;
X SCSI_LOG_TIMEOUT(6, printk("sg_remove_sfp: sfp=0x%p\n", sfp));
X sg_low_free((char *)sfp, sizeof(Sg_fd), sfp->my_mem_src);
X res = 1;
@@ -1427,12 +1580,12 @@
X return res;
X }
X
-static int sg_fb_in_use(const Sg_fd * sfp)
+static int sg_res_in_use(const Sg_fd * sfp)
X {
X const Sg_request * srp = sfp->headrp;
X
X while (srp) {
- if (srp->fb_used)
+ if (srp->res_used)
X return 1;
X srp = srp->nextrp;
X }
@@ -1511,7 +1664,7 @@
X return resp;
X }
X
-static char * sg_malloc(Sg_request * srp, int size, int * retSzp,
+static char * sg_malloc(const Sg_fd * sfp, int size, int * retSzp,
X int * mem_srcp)
X {
X char * resp = NULL;
@@ -1520,26 +1673,16 @@
X if (size <= 0)
X ;
X else {
- Sg_fd * sfp = srp->parentfp;
X int low_dma = sfp->low_dma;
X int l_ms = -1; /* invalid value */
X
X switch (*mem_srcp)
X {
X case SG_HEAP_PAGE:
- case SG_HEAP_FB:
X l_ms = (size < PAGE_SIZE) ? SG_HEAP_POOL : SG_HEAP_PAGE;
X resp = sg_low_malloc(size, low_dma, l_ms, 0);
X if (resp)
X break;
- if ((size <= sfp->fb_size) && (0 == sg_fb_in_use(sfp))) {
- SCSI_LOG_TIMEOUT(6,
- printk("sg_malloc: scsi_malloc failed, get fst_buf\n"));
- resp = sfp->fst_buf;
- srp->fb_used = 1;
- l_ms = SG_HEAP_FB;
- break;
- }
X resp = sg_low_malloc(size, low_dma, l_ms, &size);
X if (! resp) {
X l_ms = (SG_HEAP_POOL == l_ms) ? SG_HEAP_PAGE : SG_HEAP_POOL;
@@ -1595,18 +1738,12 @@
X mem_src, buff, size);
X }
X
-static void sg_free(Sg_request * srp, char * buff, int size, int mem_src)
+static void sg_free(char * buff, int size, int mem_src)
X {
- Sg_fd * sfp = srp->parentfp;
-
X SCSI_LOG_TIMEOUT(6,
X printk("sg_free: buff=0x%p, size=%d\n", buff, size));
- if ((! sfp) || (! buff) || (size <= 0))
+ if ((! buff) || (size <= 0))
X ;
- else if (sfp->fst_buf == buff) {
- srp->fb_used = 0;
- SCSI_LOG_TIMEOUT(6, printk("sg_free: left cause fst_buf\n"));
- }
X else
X sg_low_free(buff, size, mem_src);
X }
diff -u --recursive --new-file v2.3.5/linux/drivers/sound/dmasound.c linux/drivers/sound/dmasound.c
--- v2.3.5/linux/drivers/sound/dmasound.c Fri May 14 18:55:22 1999
+++ linux/drivers/sound/dmasound.c Mon Jun 7 12:12:22 1999
@@ -784,6 +784,7 @@
X
X struct sound_mixer {
X int busy;
+ int modify_counter;
X };
X
X static struct sound_mixer mixer;
@@ -3811,10 +3812,23 @@
X u_long arg)
X {
X int data;
+ if (_SIOC_DIR(cmd) & _SIOC_WRITE)
+ mixer.modify_counter++;
+ if (cmd == OSS_GETVERSION)
+ return IOCTL_OUT(arg, SOUND_VERSION);
X switch (sound.mach.type) {
X #ifdef CONFIG_ATARI
X case DMASND_FALCON:
X switch (cmd) {
+ case SOUND_MIXER_INFO: {
+ mixer_info info;
+ strncpy(info.id, "FALCON", sizeof(info.id));
+ strncpy(info.name, "FALCON", sizeof(info.name));
+ info.name[sizeof(info.name)-1] = 0;
+ info.modify_counter = mixer.modify_counter;
+ copy_to_user_ret((int *)arg, &info, sizeof(info), -EFAULT);
+ return 0;
+ }
X case SOUND_MIXER_READ_DEVMASK:
X return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER);
X case SOUND_MIXER_READ_RECMASK:
@@ -3866,6 +3880,15 @@
X
X case DMASND_TT:
X switch (cmd) {
+ case SOUND_MIXER_INFO: {
+ mixer_info info;
+ strncpy(info.id, "TT", sizeof(info.id));
+ strncpy(info.name, "TT", sizeof(info.name));
+ info.name[sizeof(info.name)-1] = 0;
+ info.modify_counter = mixer.modify_counter;
+ copy_to_user_ret((int *)arg, &info, sizeof(info), -EFAULT);
+ return 0;
+ }
X case SOUND_MIXER_READ_DEVMASK:
X return IOCTL_OUT(arg,
X SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
@@ -3927,6 +3950,15 @@
X #ifdef CONFIG_AMIGA
X case DMASND_AMIGA:
X switch (cmd) {
+ case SOUND_MIXER_INFO: {
+ mixer_info info;
+ strncpy(info.id, "AMIGA", sizeof(info.id));
+ strncpy(info.name, "AMIGA", sizeof(info.name));
+ info.name[sizeof(info.name)-1] = 0;
+ info.modify_counter = mixer.modify_counter;
+ copy_to_user_ret((int *)arg, &info, sizeof(info), -EFAULT);
+ return 0;
+ }
X case SOUND_MIXER_READ_DEVMASK:
X return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_TREBLE);
X case SOUND_MIXER_READ_RECMASK:
@@ -3953,6 +3985,16 @@
X case DMASND_AWACS:
X if (awacs_revision<AWACS_BURGUNDY) { /* Different IOCTLS for burgundy*/
X switch (cmd) {
+ case SOUND_MIXER_INFO: {
+ mixer_info info;
+ strncpy(info.id, "AWACS", sizeof(info.id));
+ strncpy(info.name, "AWACS", sizeof(info.name));
+ info.name[sizeof(info.name)-1] = 0;
+ info.modify_counter = mixer.modify_counter;
+ copy_to_user_ret((int *)arg, &info,
+ sizeof(info), -EFAULT);
+ return 0;
+ }
X case SOUND_MIXER_READ_DEVMASK:
X data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER
X | SOUND_MASK_LINE | SOUND_MASK_MIC
@@ -