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

Linux Kernel Patch v2.2, patch-2.2.10 (00/22)

19 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.2/patch-2.2.10/part00

lines added deleted
linux/CREDITS : 45 16 2
linux/Documentation/Configure.help : 263 122 46
linux/Documentation/isdn/CREDITS : 8 1 1
linux/Documentation/kernel-parameters.txt : 336 336 0
linux/Documentation/networking/ethertap.txt : 23 4 4
linux/Documentation/networking/ltpc.txt : 8 1 1
linux/Documentation/scsi-generic.txt : 807 295 200
linux/Documentation/sound/CMI8330 : 104 33 21
linux/Documentation/svga.txt : 24 8 2
linux/Documentation/video4linux/API.html : 60 24 4
linux/Documentation/video4linux/bttv/CONTRIBUTORS : 8 1 1
linux/Documentation/video4linux/bttv/PROBLEMS : 31 7 7
linux/Documentation/video4linux/bttv/README.RADIO : 8 1 1
linux/Documentation/video4linux/bttv/README.WINVIEW : 33 33 0
linux/Documentation/video4linux/bttv/THANKS : 8 1 1
linux/MAINTAINERS : 11 5 0
linux/Makefile : 7 1 1
linux/README : 22 3 3
linux/arch/alpha/config.in : 20 6 1
linux/arch/alpha/defconfig : 203 57 25
linux/arch/alpha/kernel/alpha_ksyms.c : 18 3 2
linux/arch/alpha/kernel/core_cia.c : 19 5 1
linux/arch/alpha/kernel/fpreg.c : 21 3 3
linux/arch/alpha/kernel/head.S : 125 19 98
linux/arch/alpha/kernel/irq.c : 22 9 1
linux/arch/alpha/kernel/process.c : 62 29 16
linux/arch/alpha/kernel/proto.h : 17 3 1
linux/arch/alpha/kernel/setup.c : 40 8 2
linux/arch/alpha/kernel/signal.c : 9 3 0
linux/arch/alpha/kernel/smp.c : 1635 689 650
linux/arch/alpha/kernel/sys_dp264.c : 355 176 77
linux/arch/alpha/kernel/sys_takara.c : 139 70 20
linux/arch/alpha/kernel/time.c : 173 64 28
linux/arch/alpha/kernel/traps.c : 93 6 15
linux/arch/alpha/mm/init.c : 26 0 20
linux/arch/i386/boot/setup.S : 33 14 4
linux/arch/i386/boot/video.S : 31 9 4
linux/arch/i386/kernel/mca.c : 106 29 18
linux/arch/i386/kernel/mtrr.c : 340 115 26
linux/arch/i386/kernel/setup.c : 55 20 7
linux/arch/i386/kernel/signal.c : 7 1 0
linux/arch/i386/kernel/smp.c : 8 1 1
linux/arch/i386/lib/checksum.S : 8 1 1
linux/arch/ppc/Makefile : 10 4 0
linux/arch/ppc/boot/Makefile : 17 8 2
linux/arch/ppc/boot/misc.c : 17 2 2
linux/arch/ppc/chrpboot/Makefile : 53 13 7
linux/arch/ppc/chrpboot/main.c : 72 12 18
linux/arch/ppc/coffboot/Makefile : 18 8 2
linux/arch/ppc/coffboot/zlib.c : 20 6 1
linux/arch/ppc/common_defconfig : 193 51 29
linux/arch/ppc/config.in : 28 8 3
linux/arch/ppc/defconfig : 232 24 73
linux/arch/ppc/kernel/Makefile : 8 1 1
linux/arch/ppc/kernel/chrp_pci.c : 106 74 5
linux/arch/ppc/kernel/chrp_setup.c : 180 60 47
linux/arch/ppc/kernel/head.S : 231 89 14
linux/arch/ppc/kernel/idle.c : 14 2 1
linux/arch/ppc/kernel/irq.c : 14 1 2
linux/arch/ppc/kernel/misc.S : 27 4 9
linux/arch/ppc/kernel/prep_pci.c : 24 5 1
linux/arch/ppc/kernel/prep_setup.c : 21 3 5
linux/arch/ppc/kernel/prom.c : 94 23 7
linux/arch/ppc/kernel/ptrace.c : 13 5 1
linux/arch/ppc/kernel/residual.c : 6 1 1
linux/arch/ppc/kernel/setup.c : 14 1 2
linux/arch/ppc/kernel/smp.c : 19 4 1
linux/arch/ppc/kernel/softemu8xx.c : 20 7 0
linux/arch/ppc/kernel/syscalls.c : 40 6 13
linux/arch/ppc/kernel/time.c : 25 6 2
linux/arch/ppc/kernel/traps.c : 23 0 3
linux/arch/ppc/mm/fault.c : 15 0 2
linux/arch/ppc/mm/init.c : 33 4 4
linux/arch/sparc/defconfig : 7 1 0
linux/arch/sparc/kernel/signal.c : 13 2 1
linux/arch/sparc/kernel/sys_sunos.c : 14 2 2
linux/arch/sparc64/defconfig : 7 1 0
linux/arch/sparc64/kernel/ioctl32.c : 48 23 1
linux/arch/sparc64/kernel/setup.c : 15 3 1
linux/arch/sparc64/kernel/signal.c : 13 2 1
linux/arch/sparc64/kernel/signal32.c : 13 2 1
linux/arch/sparc64/kernel/sys_sparc32.c : 128 100 4
linux/arch/sparc64/kernel/sys_sunos32.c : 14 2 2
linux/arch/sparc64/solaris/fs.c : 73 12 16
linux/drivers/block/floppy.c : 17 1 3
linux/drivers/block/ide.c : 48 17 4
linux/drivers/block/loop.c : 8 2 0
linux/drivers/block/ns87415.c : 25 17 0
linux/drivers/char/acquirewdt.c : 19 3 3
linux/drivers/char/bttv.c : 106 65 0
linux/drivers/char/bttv.h : 55 28 1
linux/drivers/char/cyclades.c : 762 208 149
linux/drivers/char/n_hdlc.c : 69 26 15
linux/drivers/char/pc110pad.c : 14 3 3
linux/drivers/char/pms.c : 8 1 1
linux/drivers/char/radio-cadet.c : 35 7 8
linux/drivers/char/softdog.c : 10 2 2
linux/drivers/char/synclink.c : 906 420 102
linux/drivers/char/tuner.c : 10 3 1
linux/drivers/char/tuner.h : 7 1 0
linux/drivers/char/videodev.c : 8 1 1
linux/drivers/char/wdt.c : 28 5 3
linux/drivers/misc/parport_pc.c : 27 6 3
linux/drivers/misc/parport_share.c : 12 3 3
linux/drivers/net/3c515.c : 23 3 0
linux/drivers/net/Config.in : 7 1 0
linux/drivers/net/Makefile : 14 8 0
linux/drivers/net/Space.c : 17 4 0
linux/drivers/net/cosa.c : 63 17 1
linux/drivers/net/cs89x0.c : 8 1 1
linux/drivers/net/eexpress.c : 59 20 4
linux/drivers/net/ibmtr.c : 18 4 1
linux/drivers/net/irda/Config.in : 38 20 13
linux/drivers/net/irda/Makefile : 100 80 0
linux/drivers/net/irda/actisys.c : 272 55 95
linux/drivers/net/irda/esi.c : 167 28 50
linux/drivers/net/irda/girbil.c : 223 28 67
linux/drivers/net/irda/irport.c : 762 448 107
linux/drivers/net/irda/irtty.c : 278 43 125
linux/drivers/net/irda/litelink.c : 206 206 0
linux/drivers/net/irda/pc87108.c : 515 131 123
linux/drivers/net/irda/smc-ircc.c : 969 969 0
linux/drivers/net/irda/tekram.c : 224 33 73
linux/drivers/net/irda/toshoboe.c : 901 901 0
linux/drivers/net/irda/uircc.c : 75 11 7
linux/drivers/net/irda/w83977af_ir.c : 1126 291 242
linux/drivers/net/ni52.c : 8 1 1
linux/drivers/net/ni52.h : 8 1 1
linux/drivers/net/ni65.c : 36 6 2
linux/drivers/net/shaper.c : 10 2 2
linux/drivers/net/sk_mca.c : 1143 1143 0
linux/drivers/net/sk_mca.h : 175 174 0
linux/drivers/net/smc-ultra.c : 10 1 1
linux/drivers/net/sunhme.c : 8 1 1
linux/drivers/pci/oldproc.c : 81 23 1
linux/drivers/sbus/char/Config.in : 5 1 0
linux/drivers/sbus/char/Makefile : 14 8 0
linux/drivers/sbus/char/aurora.c : 2370 2370 0
linux/drivers/sbus/char/aurora.h : 278 278 0
linux/drivers/sbus/char/cd180.h : 240 240 0
linux/drivers/sbus/sbus.c : 25 7 1
linux/drivers/scsi/Config.in : 12 2 4
linux/drivers/scsi/README.aic7xxx : 63 17 12
linux/drivers/scsi/README.st : 24 1 10
linux/drivers/scsi/aic7xxx/aic7xxx.reg : 145 78 0
linux/drivers/scsi/aic7xxx/aic7xxx.seq : 509 137 112
linux/drivers/scsi/aic7xxx/scsi_message.h : 13 9 1
linux/drivers/scsi/aic7xxx.c : 3280 1316 669
linux/drivers/scsi/aic7xxx_proc.c : 105 32 23
linux/drivers/scsi/aic7xxx_reg.h : 91 42 0
linux/drivers/scsi/aic7xxx_seq.c : 986 344 315
linux/drivers/scsi/scsi.c : 39 12 0
linux/drivers/scsi/scsi.h : 7 1 0
linux/drivers/scsi/scsi_proc.c : 8 1 1
linux/drivers/scsi/scsi_syms.c : 22 2 3
linux/drivers/scsi/scsicam.c : 37 4 5
linux/drivers/scsi/sd.c : 28 4 4
linux/drivers/scsi/sg.c : 1160 407 270
linux/drivers/scsi/sr_ioctl.c : 12 1 3
linux/drivers/scsi/st.c : 33 2 4
linux/drivers/scsi/st.h : 7 0 1
linux/drivers/scsi/sym53c8xx.c : 8 2 0
linux/drivers/sound/es1370.c : 157 39 14
linux/drivers/sound/sound_core.c : 31 17 1
linux/drivers/video/cgsixfb.c : 55 20 5
linux/drivers/video/fbcon.c : 4 1 0
linux/drivers/video/mdacon.c : 8 1 1
linux/fs/Config.in : 22 3 6
linux/fs/adfs/dir.c : 9 0 3
linux/fs/adfs/namei.c : 19 0 6
linux/fs/autofs/dir.c : 8 0 2
linux/fs/autofs/root.c : 9 0 3
linux/fs/binfmt_elf.c : 8 2 0
linux/fs/block_dev.c : 8 2 0
linux/fs/coda/inode.c : 8 1 1
linux/fs/coda/psdev.c : 8 1 1
linux/fs/exec.c : 12 5 1
linux/fs/ext2/file.c : 77 39 10
linux/fs/ext2/namei.c : 9 2 1
linux/fs/ext2/truncate.c : 9 2 1
linux/fs/hfs/dir_cap.c : 10 0 4
linux/fs/hfs/dir_dbl.c : 10 0 4
linux/fs/hfs/dir_nat.c : 10 0 4
linux/fs/minix/namei.c : 133 11 52
linux/fs/ncpfs/dir.c : 44 3 16
linux/fs/ncpfs/file.c : 142 42 17
linux/fs/ncpfs/inode.c : 22 3 2
linux/fs/ncpfs/ioctl.c : 69 25 15
linux/fs/ncpfs/mmap.c : 72 12 27
linux/fs/ncpfs/ncplib_kernel.c : 127 49 38
linux/fs/ncpfs/ncplib_kernel.h : 30 10 6
linux/fs/ncpfs/sock.c : 106 18 14
linux/fs/nfs/read.c : 7 1 0
linux/fs/select.c : 13 5 1
linux/fs/smbfs/inode.c : 99 18 33
linux/fs/smbfs/proc.c : 383 75 53
linux/fs/super.c : 29 13 10
linux/fs/sysv/namei.c : 153 13 60
linux/include/asm-alpha/atomic.h : 15 2 0
linux/include/asm-alpha/bitops.h : 47 11 2
linux/include/asm-alpha/init.h : 17 3 1
linux/include/asm-alpha/io.h : 19 4 3
linux/include/asm-alpha/irq.h : 11 4 0
linux/include/asm-alpha/mmu_context.h : 9 2 1
linux/include/asm-alpha/smp.h : 41 11 4
linux/include/asm-alpha/spinlock.h : 50 14 8
linux/include/asm-alpha/system.h : 190 81 69
linux/include/asm-arm/arch-ebsa285/irq.h : 7 1 0
linux/include/asm-arm/arch-ebsa285/memory.h : 8 2 0
linux/include/asm-i386/bugs.h : 21 11 3
linux/include/asm-i386/locks.h : 8 1 1
linux/include/asm-ppc/system.h : 26 5 1
linux/include/asm-sparc/spinlock.h : 8 1 1
linux/include/asm-sparc64/spinlock.h : 8 1 1
linux/include/linux/cyclades.h : 9 2 1
linux/include/linux/if_ether.h : 8 1 1
linux/include/linux/if_fddi.h : 8 1 1
linux/include/linux/if_hippi.h : 8 1 1
linux/include/linux/interrupt.h : 7 1 0
linux/include/linux/lp.h : 35 10 6
linux/include/linux/major.h : 8 2 0
linux/include/linux/ncp.h : 9 0 3
linux/include/linux/ncp_fs.h : 12 5 1
linux/include/linux/ncp_fs_sb.h : 16 2 1
linux/include/linux/netdevice.h : 8 1 1
linux/include/linux/pci.h : 71 22 1
linux/include/linux/smb.h : 8 1 1
linux/include/linux/smb_fs.h : 22 16 0
linux/include/linux/smp.h : 8 1 1
linux/include/linux/synclink.h : 56 13 3
linux/include/net/irda/crc.h : 34 9 6
linux/include/net/irda/dongle.h : 40 8 6
linux/include/net/irda/ircomm_common.h : 60 8 11
linux/include/net/irda/irda.h : 34 6 4
linux/include/net/irda/irda_device.h : 125 48 14
linux/include/net/irda/iriap.h : 30 4 4
linux/include/net/irda/irlan_common.h : 120 30 16
linux/include/net/irda/irlan_eth.h : 20 3 2
linux/include/net/irda/irlan_provider.h : 26 2 8
linux/include/net/irda/irlap.h : 56 11 7
linux/include/net/irda/irlmp.h : 21 3 3
linux/include/net/irda/irlpt_common.h : 9 2 1
linux/include/net/irda/irport.h : 32 8 7
linux/include/net/irda/irqueue.h : 17 1 3
linux/include/net/irda/irttp.h : 50 7 7
linux/include/net/irda/irtty.h : 57 9 18
linux/include/net/irda/irvtd.h : 18 4 1
linux/include/net/irda/smc-ircc.h : 160 160 0
linux/include/net/irda/smc_ircc.h : 123 0 123
linux/include/net/irda/toshoboe.h : 165 165 0
linux/include/net/irda/w83977af_ir.h : 42 25 2
linux/include/net/irda/wrapper.h : 43 10 8
linux/include/net/tcp.h : 8 1 1
linux/include/scsi/scsicam.h : 6 2 0
linux/include/scsi/sg.h : 272 87 90
linux/kernel/signal.c : 24 3 1
linux/kernel/sys.c : 8 2 0
linux/mm/memory.c : 58 14 8
linux/mm/swapfile.c : 16 2 1
linux/net/core/datagram.c : 8 1 1
linux/net/core/filter.c : 8 1 1
linux/net/ipv4/af_inet.c : 54 4 22
linux/net/ipv4/icmp.c : 11 2 2
linux/net/ipv4/ip_fw.c : 93 20 7
linux/net/ipv4/ip_options.c : 16 1 2
linux/net/ipv4/ipmr.c : 17 2 2
linux/net/ipv4/tcp.c : 16 2 1
linux/net/ipv4/tcp_input.c : 168 91 13
linux/net/ipv4/tcp_ipv4.c : 35 6 2
linux/net/ipv4/tcp_output.c : 20 6 1
linux/net/ipv4/tcp_timer.c : 25 3 6
linux/net/ipv6/icmp.c : 24 3 1
linux/net/ipv6/tcp_ipv6.c : 36 7 2
linux/net/irda/Config.in : 54 20 23
linux/net/irda/af_irda.c : 488 276 33
linux/net/irda/crc.c : 19 4 4
linux/net/irda/discovery.c : 104 42 17
linux/net/irda/ircomm/ircomm_common.c : 561 124 116
linux/net/irda/ircomm/irvtd_driver.c : 470 129 56
linux/net/irda/irda_device.c : 524 320 34
linux/net/irda/iriap.c : 225 42 38
linux/net/irda/iriap_event.c : 24 4 4
linux/net/irda/irlan/irlan_client.c : 213 43 41
linux/net/irda/irlan/irlan_client_event.c : 48 6 6
linux/net/irda/irlan/irlan_common.c : 627 177 97
linux/net/irda/irlan/irlan_eth.c : 316 78 100
linux/net/irda/irlan/irlan_event.c : 41 8 8
linux/net/irda/irlan/irlan_filter.c : 78 15 9
linux/net/irda/irlan/irlan_provider.c : 211 86 35
linux/net/irda/irlan/irlan_provider_event.c : 50 4 10
linux/net/irda/irlap.c : 1069 273 273
linux/net/irda/irlap_comp.c : 27 4 4
linux/net/irda/irlap_event.c : 467 82 107
linux/net/irda/irlap_frame.c : 77 7 20
linux/net/irda/irlmp.c : 259 77 57
linux/net/irda/irlmp_frame.c : 155 32 30
linux/net/irda/irlpt/irlpt_cli.c : 79 12 12
linux/net/irda/irlpt/irlpt_cli_fsm.c : 27 6 6
linux/net/irda/irlpt/irlpt_common.c : 32 6 6
linux/net/irda/irlpt/irlpt_srvr.c : 115 25 4
linux/net/irda/irmod.c : 87 24 8
linux/net/irda/irproc.c : 104 26 21
linux/net/irda/irsysctl.c : 19 4 4
linux/net/irda/irttp.c : 427 73 83
linux/net/irda/qos.c : 27 6 5
linux/net/irda/wrapper.c : 412 178 158
linux/net/netlink/af_netlink.c : 17 2 2
linux/net/netlink/netlink_dev.c : 8 1 1
--
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.2/patch-2.2.10/part02

#!/bin/sh
# this is part 02 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.10 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.2.10'
else
echo 'x - continuing with patch-2.2.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.10' &&
X Note that a packet can be queued after write()ing but not available to be
X read(); this typically happens when a SCSI read command is issued while
-the data is being retreaved.
+the data is being retrieved.
X Poll() is per file descriptor unless SG_SET_MERGE_FD is set in which case
X it is per device.
X
X
-fcntl
------
+fcntl(int sg_fd, int cmd) or fcntl(int sg_fd, int cmd, long arg)
+----------------------------------------------------------------
X There are several uses for this system call in association with a sg
-file descriptor. The first pseudo code shows code that is useful for
+file descriptor. The following pseudo code shows code that is useful for
X scanning the sg devices, taking care not to be caught in a wait for
X an O_EXCL lock by another process, and when the appropriate device is
-found switching to normal blocked io. A working example of this logic
-is in the sg_scan.c utility program.
+found, switching to normal blocked io. A working example of this logic
+is in the sg_scan utility program.
X
X open("/dev/sga", O_RDONLY | O_NONBLOCK)
X /* check device, EBUSY means some other process has O_EXCL lock on it */
-/* one the device you want is found then ... */
+/* when the device you want is found then ... */
X flags = fcntl(sg_fd, F_GETFL)
X fcntl(sg_fd, F_SETFL, flags & (~ O_NONBLOCK))
-/* for simple apps is is easier to use normal blocked io */
+/* since, for simple apps, it is easier to use normal blocked io */
X
X
X Some work has to be done in Linux to set up for asynchronous notification.
-This is a non-blocking mode of operation in which when the driver receives
+This is a non-blocking mode of operation in which, when the driver receives
X data back from a device so that a read() can be done, it sends a SIGPOLL
X (aka SIGIO) signal to the owning process. A working example of this logic
-is in the sg_poll.c test program.
+is in the sg_poll test program.
X
X sigemptyset(&sig_set)
X sigaddset(&sig_set, SIGPOLL)
@@ -634,3 +641,91 @@
X
X Utility and Test Programs
X =========================
+See the README file in the sg_utils<date>.tgz tarball. At the time of
+writing this was sg_utils990527.tgz .
+
+Briefly, that tarball contains the following utilities:
+sg_dd512 'dd' like program that assumes 512 byte blocks size
+sg_dd2048 'dd' like program that assumes 2048 byte blocks size
+sgq_dd512 like 'sg_dd512' but does command queuing on "if"
+sg_scan outputs information (optionally Inquiry) on SCSI devices
+sg_rbuf tests SCSI bus transfer speed (without physical IO)
+sg_whoami outputs info (optionally capacity) of given SCSI device
+sginfo outputs "mode" information about SCSI devices (it is a
+ re-port of the scsiinfo program onto the sg interface)
+
+It also contains the following test programs:
+sg_debug outputs sg driver state to console/log file
+sg_poll tests asynchronous notification
+sg_inquiry does a SCSI Inquiry command (from original HOWTO)
+sg_tst_med checks presence of media (from original HOWTO)
+
+There are also 2 source files (sg_err.[hc]) for outputting and categorizing
+SCSI 2 errors and warnings. This code is used by most of the above
+utility and test programs.
+
+The following programs: sg_dd512, sg_dd2048, sg_scan, sg_rbuf, sg_tst_med,
+sg_inquiry and sginfo, can be compiled either for this new sg driver _or_
+the original sg driver.
+
+
+Header files
+============
+User applications need to find the correct "sg.h" header file matching
+their kernel in order to write code using the sg device driver. This is
+sometimes more difficult than it should be. The correct "sg.h" will usually
+be found at /usr/src/linux/include/scsi/sg.h . Another important header
+file is "scsi.h" which will be in the same directory.
+
+Several distributions have taken their own copies of these files and placed
+them in /usr/include/scsi which is where "#include <scsi/sg.h>" would go
+looking. The directory /usr/include/scsi _should_ be a symbolic link to
+/usr/src/linux/include/scsi/ . It was is Redhat 5.1 and 5.2 but it is
+not is Redhat 6.0 . Some other distributions have the same problem. To
+solve this (as root) do the following:
+
+# cd /usr/include
+# mv scsi scsi_orig
+# ln -s ../src/linux/include/scsi scsi
+
+This doesn't seem to be a problem with /usr/include/linux (at least in
+Redhat where it is a symbolic link) so it is hard to understand why
+/usr/include/scsi is defined the way it is. The fact the
+/usr/include/linux is a symbolic link opens up the following solution
+proposed by the author of cdparanoia (Monty):
+#include <linux/../scsi/sg.h>
+
+
+Extra information in scsi-generic_long.txt
+==========================================
+This document is an abridged form of a more comprehensive document called
+scsi-generic_long.txt (see www.torque.net/sg/p/scsi-generic_long.txt).
+
+The longer document contains additional sections on:
+ - memory issues
+ - ioctl()s in common with sd, st + sr
+ - distinguishing the original from the new driver
+ - SG_BIG_BUFF and friends
+ - shortcomings
+ - future directions
+ - an appendix with some SCSI 2 information in it
+
+
+Conclusion
+==========
+The SCSI generic packet device driver attempts to make as few assumptions
+as possible about the device it is connected to while giving applications
+using it as much flexibility as possible on the SCSI command level. Sg
+needs to hide the "messy" kernel related details while protecting
+the integrity of the kernel against sg "abuse". Some of these aims are
+contradictory and some compromises need to be made. For example: should
+a sg based application be able to reset a SCSI bus when that could cause
+collateral damage to a disk holding the root file system? There is no
+easy answer to this and many other related questions.
+
+If you have any suggestion about sg (or improving (the accuracy of) this
+document) please contact me.
+
+
+Douglas Gilbert
+dgil...@interlog.com
diff -u --recursive --new-file v2.2.9/linux/Documentation/sound/CMI8330 linux/Documentation/sound/CMI8330
--- v2.2.9/linux/Documentation/sound/CMI8330 Wed Mar 10 15:29:44 1999
+++ linux/Documentation/sound/CMI8330 Wed May 26 09:29:42 1999
@@ -1,46 +1,48 @@
-How to enable CMI 8330 soundchip on Linux
+How to enable CMI 8330 (SOUNDPRO) soundchip on Linux
X ------------------------------------------
X Stefan Laudat <Stefan...@asit.ro>
X
-Hello folks,
-
- The CMI8330 soundchip is a very small chip found on many recent
- motherboards. In order to use it you just have to use a proper
- isapnp.conf and a little bit of patience.
+[Note: The CMI 8338 is unrelated and right now unsupported]
+
X
- Of course you will have to compile kernel sound support as module,
- as shown below:
+ In order to use CMI8330 under Linux you just have to use a proper isapnp.conf, a good isapnp and a little bit of patience. I use isapnp 1.17, but
+you may get a better one I guess at http://www.roestock.demon.co.uk/isapnptools/.
+
+ Of course you will have to compile kernel sound support as module, as shown below:
X
X CONFIG_SOUND=m
X CONFIG_SOUND_OSS=m
X CONFIG_SOUND_SB=m
X CONFIG_SOUND_ADLIB=m
X CONFIG_SOUND_MPU401=m
-# Just for fun :)
+# Mikro$chaft sound system (kinda useful here ;))
X CONFIG_SOUND_MSS=m
X
X The /etc/isapnp.conf file will be:
X
X <snip below>
X
+
X (READPORT 0x0203)
X (ISOLATE PRESERVE)
X (IDENTIFY *)
X (VERBOSITY 2)
X (CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING
X (VERIFYLD N)
+
+
X # WSS
X
X (CONFIGURE CMI0001/16777472 (LD 0
X (IO 0 (SIZE 8) (BASE 0x0530))
X (IO 1 (SIZE 8) (BASE 0x0388))
-(INT 0 (IRQ 5 (MODE +E)))
+(INT 0 (IRQ 7 (MODE +E)))
X (DMA 0 (CHANNEL 0))
X (NAME "CMI0001/16777472[0]{CMI8330/C3D Audio Adapter}")
X (ACT Y)
X ))
X
-# Control device ?
+# MPU
X
X (CONFIGURE CMI0001/16777472 (LD 1
X (IO 0 (SIZE 2) (BASE 0x0330))
@@ -57,10 +59,11 @@
X (ACT Y)
X ))
X
-# SB...
+# SoundBlaster
+
X (CONFIGURE CMI0001/16777472 (LD 3
X (IO 0 (SIZE 16) (BASE 0x0220))
-(INT 0 (IRQ 7 (MODE +E)))
+(INT 0 (IRQ 5 (MODE +E)))
X (DMA 0 (CHANNEL 1))
X (DMA 1 (CHANNEL 5))
X (NAME "CMI0001/16777472[3]{CMI8330/C3D Audio Adapter}")
@@ -74,13 +77,22 @@
X
X The module sequence is trivial:
X
-/sbin/modprobe sound
-# You need to load the ad1848 module first. That matters, otherwise the
-# chip falls into soundblaster compatibility and you won't get it back out
-/sbin/insmod ad1848 io=0x530 dma=0 irq=5 soundpro=1
+/sbin/insmod soundcore
+/sbin/insmod sound
X /sbin/insmod uart401
-/sbin/insmod sb io=0x220 irq=5 dma=1 dma16=-1
-/sbin/insmod mpu401 io=0x330
-/sbin/insmod opl3 io=0x388
+# insert this first
+/sbin/insmod ad1848 io=0x530 irq=7 dma=0 soundpro=1
+# The sb module is an alternative to the ad1848 (Microsoft Sound System)
+# Anyhow, this is full duplex and has MIDI
+/sbin/insmod sb io=0x220 dma=1 dma16=5 irq=5 mpu_io=0x330
+
+
X
- The soundchip is now fully initialized. Enjoy it.
+Alma Chao <ely...@ethereal.torsion.org> suggests the following /etc/conf.modules:
+
+alias sound ad1848
+alias synth0 opl3
+options ad1848 io=0x530 irq=7 dma=0 soundpro=1
+options opl3 io=0x388
+
+
diff -u --recursive --new-file v2.2.9/linux/Documentation/svga.txt linux/Documentation/svga.txt
--- v2.2.9/linux/Documentation/svga.txt Thu Jul 16 18:09:22 1998
+++ linux/Documentation/svga.txt Fri May 14 12:47:07 1999
@@ -1,5 +1,5 @@
- Video Mode Selection Support 2.11
- (c) 1995--1997 Martin Mares, <m...@k332.feld.cvut.cz>
+ Video Mode Selection Support 2.13
+ (c) 1995--1999 Martin Mares, <m...@ucw.cz>
X --------------------------------------------------------------------------------
X
X 1. Intro
@@ -9,6 +9,11 @@
X to usage of the BIOS, the selection is limited to boot time (before the
X kernel decompression starts) and works only on 80X86 machines.
X
+ ** Short intro for the impatient: Just use vga=ask for the first time,
+ ** enter `scan' on the video mode prompt, pick the mode you want to use,
+ ** remember its mode ID (the four-digit hexadecimal number) and then
+ ** set the vga parameter to this number (converted to decimal first).
+
X The video mode to be used is selected by a kernel parameter which can be
X specified in the kernel Makefile (the SVGA_MODE=... line) or by the "vga=..."
X option of LILO (or some other boot loader you use) or by the "vidmode" utility
@@ -268,3 +273,4 @@
X - Removed the doc section describing adding of new probing
X functions as I try to get rid of _all_ hardware probing here.
X 2.12 (25-May-98)- Added support for VESA frame buffer graphics.
+2.13 (14-May-99)- Minor documentation fixes.
diff -u --recursive --new-file v2.2.9/linux/Documentation/video4linux/API.html linux/Documentation/video4linux/API.html
--- v2.2.9/linux/Documentation/video4linux/API.html Fri Jan 8 22:35:59 1999
+++ linux/Documentation/video4linux/API.html Mon Jun 7 16:13:07 1999
@@ -1,6 +1,9 @@
X <HTML><HEAD>
-<TITLE>Video4Linux Kernel API Reference v0.1:19980516</TITLE>
+<TITLE>Video4Linux Kernel API Reference v0.1:19990430</TITLE>
X </HEAD>
+<! Revision History: >
+<! 4/30/1999 - Fred Gleason (fr...@wava.com)>
+<! Documented extensions for the Radio Data System (RDS) extensions >
X <BODY bgcolor="#ffffff">
X <H3>Devices</H3>
X Video4Linux provides the following sets of device files. These live on the
@@ -117,7 +120,7 @@
X </TABLE>
X <P>
X Merely setting the window does not enable capturing. Overlay capturing
-is activatied by passing the <b>VIDIOCCAPTURE</b> ioctl a value of 1, and
+is activated by passing the <b>VIDIOCCAPTURE</b> ioctl a value of 1, and
X disabled by passing it a value of 0.
X <P>
X Some capture devices can capture a subfield of the image they actually see.
@@ -150,7 +153,7 @@
X nature of the channel itself.
X <P>
X The <b>VIDIOCSCHAN</b> ioctl takes an integer argument and switches the
-capture to this input. It is not defined whether paramters such as colour
+capture to this input. It is not defined whether parameters such as colour
X settings or tuning are maintained across a channel switch. The caller should
X maintain settings as desired for each channel. (This is reasonable as
X different video inputs may have different properties).
@@ -249,6 +252,8 @@
X <TR><TD><b>VIDEO_TUNER_LOW</b><TD>Frequency is in a lower range</TD>
X <TR><TD><b>VIDEO_TUNER_NORM</b><TD>The norm for this tuner is settable</TD>
X <TR><TD><b>VIDEO_TUNER_STEREO_ON</b><TD>The tuner is seeing stereo audio</TD>
+<TR><TD><b>VIDEO_TUNER_RDS_ON</b><TD>The tuner is seeing a RDS datastream</TD>
+<TR><TD><b>VIDEO_TUNER_MBS_ON</b><TD>The tuner is seeing a MBS datastream</TD>
X </TABLE>
X <P>
X The following modes are defined
@@ -349,6 +354,21 @@
X <TR><TD><b>teletext</b><TD>Teletext device</TD>
X </TABLE>
X <P>
-
+<H3>RDS Datastreams</H3>
+For radio devices that support it, it is possible to receive Radio Data
+System (RDS) data by means of a read() on the device. The data is packed in
+groups of three, as follows:
+<TABLE>
+<TR><TD>First Octet</TD><TD>Least Siginificant Byte of RDS Block</TD></TR>
+<TR><TD>Second Octet</TD><TD>Most Siginificant Byte of RDS Block
+<TR><TD>Third Octet</TD><TD>Bit 7:</TD><TD>Error bit. Indicates that
+an uncorrectable error occured during reception of this block.</TD></TR>
+<TR><TD>&nbsp;</TD><TD>Bit 6:</TD><TD>Corrected bit. Indicates that
+an error was corrected for this data block.</TD></TR>
+<TR><TD>&nbsp;</TD><TD>Bits 5-3:</TD><TD>Reeived Offset. Indicates the
+offset received by the sync system.</TD></TR>
+<TR><TD>&nbsp;</TD><TD>Bits 2-0:</TD><TD>Offset Name. Indicates the
+offset applied to this data.</TD></TR>
+</TABLE>
X </BODY>
X </HTML>
diff -u --recursive --new-file v2.2.9/linux/Documentation/video4linux/bttv/CONTRIBUTORS linux/Documentation/video4linux/bttv/CONTRIBUTORS
--- v2.2.9/linux/Documentation/video4linux/bttv/CONTRIBUTORS Wed Aug 26 11:37:33 1998
+++ linux/Documentation/video4linux/bttv/CONTRIBUTORS Wed Jun 2 11:29:27 1999
@@ -3,7 +3,7 @@
X Michael Chu <mm...@pobox.com>
X AverMedia fix and more flexible card recognition
X
-Alan Cox <al...@cymru.net>
+Alan Cox <al...@redhat.com>
X Video4Linux interface and 2.1.x kernel adaptation
X
X Chris Kleitsch
diff -u --recursive --new-file v2.2.9/linux/Documentation/video4linux/bttv/PROBLEMS linux/Documentation/video4linux/bttv/PROBLEMS
--- v2.2.9/linux/Documentation/video4linux/bttv/PROBLEMS Wed Aug 26 11:37:33 1998
+++ linux/Documentation/video4linux/bttv/PROBLEMS Mon Jun 7 16:13:07 1999
@@ -17,9 +17,9 @@
X If this 64MB area overlaps the IO memory of the Bt848 you also have to
X remap this. E.g.: insmod bttv vidmem=0xfb0 remap=0xfa0
X
- If the videomemory is found at the right place and there are no address
- conflicts but still no picture (or the computer even crashes.),
- try disabling features of your PCI chipset in the BIOS Setup.
+ If the video memory is found at the right place and there are no address
+ conflicts but still no picture (or the computer even crashes),
+ try disabling features of your PCI chipset in the BIOS setup.
X
X Frank Kapahnke <fr...@kapahnke.prima.ruhr.de> also reported that problems
X with his S3 868 went away when he upgraded to XFree 3.2.
@@ -50,13 +50,13 @@
X
X Disable backing store by starting X with the option "-bs"
X
-- When using 32bpp in XFree or 24+8bpp mode in AccelX 3.1 the system
+- When using 32 bpp in XFree or 24+8bpp mode in AccelX 3.1 the system
X can sometimes lock up if you use more than 1 bt848 card at the same time.
X You will always get pixel errors when e.g. using more than 1 card in full
X screen mode. Maybe we need something faster than the PCI bus ...
X
X
-- Some S3 cards and the Matrox Mystique will produce pixel erros with
- full resolution in 32bit mode.
+- Some S3 cards and the Matrox Mystique will produce pixel errors with
+ full resolution in 32-bit mode.
X
-- Some video cards have problems with Accelerated X 4.1
\ No newline at end of file
+- Some video cards have problems with Accelerated X 4.1
diff -u --recursive --new-file v2.2.9/linux/Documentation/video4linux/bttv/README.RADIO linux/Documentation/video4linux/bttv/README.RADIO
--- v2.2.9/linux/Documentation/video4linux/bttv/README.RADIO Wed Aug 26 11:37:33 1998
+++ linux/Documentation/video4linux/bttv/README.RADIO Mon Jun 7 16:13:07 1999
@@ -6,7 +6,7 @@
X
X So you should have TV with (stereo) sound now. Radio does _not_ work.
X It probably does not work with sat receivers. I can't test this and
-therefore hav'nt added support for it yet. If someone needs this and
+therefore have not added support for it yet. If someone needs this and
X can help testing the sat stuff, drop me a note.
X
X Gerd
diff -u --recursive --new-file v2.2.9/linux/Documentation/video4linux/bttv/README.WINVIEW linux/Documentation/video4linux/bttv/README.WINVIEW
--- v2.2.9/linux/Documentation/video4linux/bttv/README.WINVIEW Wed Dec 31 16:00:00 1969
+++ linux/Documentation/video4linux/bttv/README.WINVIEW Mon Jun 7 16:13:07 1999
@@ -0,0 +1,33 @@
+
+Support for the Leadtek WinView 601 TV/FM by Jon Tombs <j...@gte.esi.us.es>
+
+This card is basically the same as all the rest (Bt484A, Philips tuner),
+the main difference is that they have attached a programmable attenuator to 3
+GPIO lines in order to give some volume control. They have also stuck an
+infra-red remote control decoded on the board, I will add support for this
+when I get time (it simple generates an interrupt for each key press, with
+the key code is placed in the GPIO port).
+
+I don't yet have any application to test the radio support. The tuner
+frequency setting should work but it is possible that the audio multiplexer
+is wrong. If it doesn't work, send me email.
+
+
+- No Thanks to Leadtek they refused to answer any questions about their
+hardware. The driver was written by visual inspection of the card. If you
+use this driver, send an email insult to them, and tell them you won't
+continue buying their hardware unless they support Linux.
+
+- Little thanks to Princeton Technology Corp (http://www.princeton.com.tw)
+who make the audio attenuator. Their publicly available data-sheet available
+on their web site doesn't include the chip programming information! Hidden
+on their server are the full data-sheets, but don't ask how I found it.
+
+To use the driver I use the following options, the tuner and pll settings might
+be different in your country
+
+insmod videodev
+insmod i2c scan=1 i2c_debug=0 verbose=0
+insmod tuner type=1 debug=0
+insmod bttv pll=1 radio=1 card=17
+
diff -u --recursive --new-file v2.2.9/linux/Documentation/video4linux/bttv/THANKS linux/Documentation/video4linux/bttv/THANKS
--- v2.2.9/linux/Documentation/video4linux/bttv/THANKS Wed Aug 26 11:37:33 1998
+++ linux/Documentation/video4linux/bttv/THANKS Mon Jun 7 16:13:07 1999
@@ -17,7 +17,7 @@
X components on their cards. (E.g. how the tuner type is detected)
X Without their card I could not have debugged the NTSC mode.
X
-- Hauppauge for telling how the sound input is selected and what compenents
+- Hauppauge for telling how the sound input is selected and what components
X they do and will use on their radio cards.
X Also many thanks for faxing me the FM1216 data sheet.
X
diff -u --recursive --new-file v2.2.9/linux/MAINTAINERS linux/MAINTAINERS
--- v2.2.9/linux/MAINTAINERS Tue May 11 13:10:27 1999
+++ linux/MAINTAINERS Thu Jun 3 08:26:38 1999
@@ -385,6 +385,11 @@
X W: http://www.rustcorp.com/linux/ipchains
X S: Supported
X
+IP MASQUERADING:
+P: Juanjo Ciarlante
+M: jjci...@raiz.uncu.edu.ar
+S: Maintained
+
X IPX/SPX NETWORK LAYER
X P: Jay Schulist
X M: Jay Schulist <Jay.Sc...@spacs.k12.wi.us>
diff -u --recursive --new-file v2.2.9/linux/Makefile linux/Makefile
--- v2.2.9/linux/Makefile Thu May 13 23:10:29 1999
+++ linux/Makefile Fri May 28 18:10:19 1999
@@ -1,6 +1,6 @@
X VERSION = 2
X PATCHLEVEL = 2
-SUBLEVEL = 9
+SUBLEVEL = 10
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.2.9/linux/README linux/README
--- v2.2.9/linux/README Fri Jan 8 22:36:00 1999
+++ linux/README Sun May 30 10:17:03 1999
@@ -32,11 +32,11 @@
X - There is a lot of documentation available both in electronic form on
X the Internet and in books, both Linux-specific and pertaining to
X general UNIX questions. I'd recommend looking into the documentation
- subdirectories on any Linux ftp site for the LDP (Linux Documentation
+ subdirectories on any Linux FTP site for the LDP (Linux Documentation
X Project) books. This README is not meant to be documentation on the
X system: there are much better sources available.
X
- - There are various readme's in the kernel Documentation/ subdirectory:
+ - There are various README files in the Documentation/ subdirectory:
X these typically contain kernel-specific installation notes for some
X drivers for example. See ./Documentation/00-INDEX for a list of what
X is contained in each file. Please read the Changes file, as it
@@ -219,7 +219,7 @@
X isn't anyone listed there, then the second best thing is to mail
X them to me (torv...@transmeta.com), and possibly to any other
X relevant mailing-list or to the newsgroup. The mailing-lists are
- useful especially for SCSI and NETworking problems, as I can't test
+ useful especially for SCSI and networking problems, as I can't test
X either of those personally anyway.
X
X - In all bug-reports, *please* tell what kernel you are talking about,
diff -u --recursive --new-file v2.2.9/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.2.9/linux/arch/alpha/config.in Tue May 11 13:10:27 1999
+++ linux/arch/alpha/config.in Sat May 22 13:41:37 1999
@@ -142,6 +142,7 @@
X
X if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \
X -o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_JENSEN" = "y" \
+ -o "$CONFIG_ALPHA_TAKARA" = "y" -o "$CONFIG_ALPHA_EB164" = "y" \
X -o "$CONFIG_ALPHA_MIKASA" = "y" -o "$CONFIG_ALPHA_ALCOR" = "y" \
X -o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_MIATA" = "y" \
X -o "$CONFIG_ALPHA_NORITAKE" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
@@ -166,7 +167,11 @@
X define_bool CONFIG_ALPHA_AVANTI y
X fi
X
-bool 'Symmetric multi-processing support' CONFIG_SMP
+if [ "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \
+ -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_GENERIC" = "y" ]
+then
+ bool 'Symmetric multi-processing support' CONFIG_SMP
+fi
X
X if [ "$CONFIG_PCI" = "y" ]; then
X bool 'PCI quirks' CONFIG_PCI_QUIRKS
diff -u --recursive --new-file v2.2.9/linux/arch/alpha/defconfig linux/arch/alpha/defconfig
--- v2.2.9/linux/arch/alpha/defconfig Wed Mar 10 15:29:45 1999
+++ linux/arch/alpha/defconfig Sat Jun 12 11:52:51 1999
@@ -12,12 +12,11 @@
X #
X CONFIG_MODULES=y
X # CONFIG_MODVERSIONS is not set
-# CONFIG_KMOD is not set
+CONFIG_KMOD=y
X
X #
X # General setup
X #
-CONFIG_NATIVE=y
X CONFIG_ALPHA_GENERIC=y
X # CONFIG_ALPHA_ALCOR is not set
X # CONFIG_ALPHA_XL is not set
@@ -39,12 +38,12 @@
X # CONFIG_ALPHA_P2K is not set
X # CONFIG_ALPHA_RAWHIDE is not set
X # CONFIG_ALPHA_RUFFIAN is not set
+# CONFIG_ALPHA_RX164 is not set
X # CONFIG_ALPHA_SX164 is not set
X # CONFIG_ALPHA_SABLE is not set
X # CONFIG_ALPHA_TAKARA is not set
-# CONFIG_SMP is not set
X CONFIG_PCI=y
-CONFIG_ALPHA_NEED_ROUNDING_EMULATION=y
+# CONFIG_SMP is not set
X # CONFIG_PCI_QUIRKS is not set
X CONFIG_PCI_OLD_PROC=y
X CONFIG_NET=y
@@ -88,7 +87,7 @@
X #
X # Networking options
X #
-# CONFIG_PACKET is not set
+CONFIG_PACKET=y
X # CONFIG_NETLINK is not set
X # CONFIG_FIREWALL is not set
X # CONFIG_FILTER is not set
@@ -107,7 +106,6 @@
X # (it is safe to leave these untouched)
X #
X # CONFIG_INET_RARP is not set
-CONFIG_IP_NOSR=y
X CONFIG_SKB_LARGE=y
X
X #
@@ -141,6 +139,7 @@
X # SCSI low-level drivers
X #
X # CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
X # CONFIG_SCSI_AHA152X is not set
X # CONFIG_SCSI_AHA1542 is not set
X # CONFIG_SCSI_AHA1740 is not set
@@ -148,23 +147,29 @@
X # CONFIG_SCSI_ADVANSYS is not set
X # CONFIG_SCSI_IN2000 is not set
X # CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
X # CONFIG_SCSI_BUSLOGIC is not set
X # CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
X # CONFIG_SCSI_EATA_DMA is not set
X # CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_EATA is not set
X # CONFIG_SCSI_FUTURE_DOMAIN is not set
X # CONFIG_SCSI_GDTH is not set
X # CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
X # CONFIG_SCSI_NCR53C406A is not set
+# 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
X # CONFIG_SCSI_PAS16 is not set
X # CONFIG_SCSI_PCI2000 is not set
X # CONFIG_SCSI_PCI2220I is not set
X # CONFIG_SCSI_PSI240I is not set
X # CONFIG_SCSI_QLOGIC_FAS is not set
X CONFIG_SCSI_QLOGIC_ISP=y
+# CONFIG_SCSI_QLOGIC_FC is not set
X # CONFIG_SCSI_SEAGATE is not set
X # CONFIG_SCSI_DC390T is not set
X # CONFIG_SCSI_T128 is not set
@@ -194,6 +199,7 @@
X # CONFIG_EEXPRESS_PRO100 is not set
X # CONFIG_NE2K_PCI is not set
X # CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
X # CONFIG_NET_POCKET is not set
X # CONFIG_FDDI is not set
X # CONFIG_DLCI is not set
@@ -202,6 +208,8 @@
X # CONFIG_NET_RADIO is not set
X # CONFIG_TR is not set
X # CONFIG_HOSTESS_SV11 is not set
+# CONFIG_COSA is not set
+# CONFIG_RCPCI is not set
X # CONFIG_WAN_DRIVERS is not set
X # CONFIG_LAPBETHER is not set
X # CONFIG_X25_ASY is not set
@@ -217,7 +225,7 @@
X # CONFIG_ISDN is not set
X
X #
-# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+# Old CD-ROM drivers (not SCSI, not IDE)
X #
X # CONFIG_CD_NO_IDESCSI is not set
X
@@ -233,19 +241,31 @@
X CONFIG_UNIX98_PTYS=y
X CONFIG_UNIX98_PTY_COUNT=256
X CONFIG_MOUSE=y
+
+#
+# Mice
+#
X # CONFIG_ATIXL_BUSMOUSE is not set
X # CONFIG_BUSMOUSE is not set
X # CONFIG_MS_BUSMOUSE is not set
X CONFIG_PSMOUSE=y
X # CONFIG_82C710_MOUSE is not set
X # CONFIG_PC110_PAD is not set
-# CONFIG_UMISC is not set
X # CONFIG_QIC02_TAPE is not set
X # CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
X # CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
X # CONFIG_VIDEO_DEV is not set
-# CONFIG_NVRAM is not set
+
+#
+# Joystick support
+#
X # CONFIG_JOYSTICK is not set
+# CONFIG_DTLK is not set
X
X #
X # Ftape, the floppy tape device driver
@@ -256,31 +276,43 @@
X # Filesystems
X #
X # CONFIG_QUOTA is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
X # CONFIG_FAT_FS is not set
X # CONFIG_MSDOS_FS is not set
X # CONFIG_UMSDOS_FS is not set
X # CONFIG_VFAT_FS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
X CONFIG_PROC_FS=y
+CONFIG_DEVPTS_FS=y
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
X CONFIG_NFS_FS=y
-# CONFIG_NFSD is not set
+# CONFIG_NFSD_SUN is not set
X CONFIG_SUNRPC=y
X CONFIG_LOCKD=y
-# CONFIG_CODA_FS is not set
X # CONFIG_SMB_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_UFS_FS is not set
-CONFIG_DEVPTS_FS=y
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_BSD_DISKLABEL is not set
X # CONFIG_MAC_PARTITION is not set
+# CONFIG_SMD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
X # CONFIG_NLS is not set
X
X #
diff -u --recursive --new-file v2.2.9/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- v2.2.9/linux/arch/alpha/kernel/alpha_ksyms.c Tue Jan 19 11:32:50 1999
+++ linux/arch/alpha/kernel/alpha_ksyms.c Sat May 22 13:41:43 1999
@@ -52,6 +52,7 @@
X EXPORT_SYMBOL(local_irq_count);
X EXPORT_SYMBOL(enable_irq);
X EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(disable_irq_nosync);
X EXPORT_SYMBOL(screen_info);
X EXPORT_SYMBOL(perf_irq);
X
@@ -170,8 +171,8 @@
X EXPORT_SYMBOL(__global_restore_flags);
X #if DEBUG_SPINLOCK
X EXPORT_SYMBOL(spin_unlock);
-EXPORT_SYMBOL(spin_lock);
-EXPORT_SYMBOL(spin_trylock);
+EXPORT_SYMBOL(debug_spin_lock);
+EXPORT_SYMBOL(debug_spin_trylock);
X #endif
X #if DEBUG_RWLOCK
X EXPORT_SYMBOL(write_lock);
diff -u --recursive --new-file v2.2.9/linux/arch/alpha/kernel/core_cia.c linux/arch/alpha/kernel/core_cia.c
--- v2.2.9/linux/arch/alpha/kernel/core_cia.c Wed Sep 9 14:51:03 1998
+++ linux/arch/alpha/kernel/core_cia.c Sat May 22 13:41:43 1999
@@ -598,7 +598,7 @@
X {
X CIA_jd = *(vuip)CIA_IOC_CIA_ERR;
X DBGM(("CIA_pci_clr_err: CIA ERR after read 0x%x\n", CIA_jd));
- *(vuip)CIA_IOC_CIA_ERR = 0x0180;
+ *(vuip)CIA_IOC_CIA_ERR = CIA_jd;
X mb();
X return 0;
X }
@@ -698,6 +698,10 @@
X reason = buf;
X break;
X }
+ mb();
+ mb(); /* magic */
+ draina();
+ cia_pci_clr_err();
X wrmces(rdmces()); /* reset machine check pending flag */
X mb();
X
diff -u --recursive --new-file v2.2.9/linux/arch/alpha/kernel/fpreg.c linux/arch/alpha/kernel/fpreg.c
--- v2.2.9/linux/arch/alpha/kernel/fpreg.c Tue Aug 18 22:02:02 1998
+++ linux/arch/alpha/kernel/fpreg.c Sat May 22 13:41:47 1999
@@ -1,10 +1,10 @@
X /*
- * kernel/fpreg.c
+ * arch/alpha/kernel/fpreg.c
X *
X * (C) Copyright 1998 Linus Torvalds
X */
X
-#ifdef __alpha_cix__
+#if defined(__alpha_cix__) || defined(__alpha_fix__)
X #define STT(reg,val) asm volatile ("ftoit $f"#reg",%0" : "=r"(val));
X #else
X #define STT(reg,val) asm volatile ("stt $f"#reg",%0" : "=m"(val));
@@ -52,7 +52,7 @@
X return val;
X }
X
-#ifdef __alpha_cix__
+#if defined(__alpha_cix__) || defined(__alpha_fix__)
X #define LDT(reg,val) asm volatile ("itoft %0,$f"#reg : : "r"(val));
X #else
X #define LDT(reg,val) asm volatile ("ldt $f"#reg",%0" : : "m"(val));
diff -u --recursive --new-file v2.2.9/linux/arch/alpha/kernel/head.S linux/arch/alpha/kernel/head.S
--- v2.2.9/linux/arch/alpha/kernel/head.S Fri Oct 23 22:01:19 1998
+++ linux/arch/alpha/kernel/head.S Sat Jun 12 11:52:52 1999
@@ -32,106 +32,27 @@
X
X #ifdef __SMP__
X .align 3
- .globl __start_cpu
- .ent __start_cpu
- /* On entry here from SRM console, the HWPCB of this processor
- has been loaded, and $27 contains the task pointer */
-__start_cpu:
- .prologue 0
- /* First order of business, load the GP */
- br $26,1f
-1: ldgp $29,0($26)
- /* We need to get current loaded up with our first task... */
- mov $27,$8
- /* Set FEN */
- lda $16,1($31)
- call_pal PAL_wrfen
- /* ... and then we can start the processor. */
- jsr $26,start_secondary
+ .globl __smp_callin
+ .ent __smp_callin
+ /* On entry here from SRM console, the HWPCB of the per-cpu
+ slot for this processor has been loaded. We've arranged
+ for the UNIQUE value for this process to contain the PCBB
+ of the target idle task. */
+__smp_callin:
+ .prologue 1
+ ldgp $29,0($27) # First order of business, load the GP.
+
+ call_pal PAL_rduniq # Grab the target PCBB.
+ mov $0,$16 # Install it.
+ call_pal PAL_swpctx
+
+ lda $8,0x3fff # Find "current".
+ bic $30,$8,$8
+
+ jsr $26,smp_callin
X call_pal PAL_halt
- .end __start_cpu
+ .end __smp_callin
X #endif /* __SMP__ */
-
- .align 3
- .globl wrent
- .ent wrent
-wrent:
- .prologue 0
- call_pal PAL_wrent
- ret ($26)
- .end wrent
-
- .align 3
- .globl wrkgp
- .ent wrkgp
-wrkgp:
- .prologue 0
- call_pal PAL_wrkgp
- ret ($26)
- .end wrkgp
-
- .align 3
- .globl wrusp
- .ent wrusp
-wrusp:
- .prologue 0
- call_pal PAL_wrusp
- ret ($26)
- .end wrusp
-
- .align 3
- .globl rdusp
- .ent rdusp
-rdusp:
- .prologue 0
- call_pal PAL_rdusp
- ret ($26)
- .end rdusp
-
- .align 3
- .globl rdmces
- .ent rdmces
-rdmces:
- .prologue 0
- call_pal PAL_rdmces
- ret ($26)
- .end rdmces
-
- .align 3
- .globl wrmces
- .ent wrmces
-wrmces:
- .prologue 0
- call_pal PAL_wrmces
- ret ($26)
- .end wrmces
-
- .align 3
- .globl whami
- .ent whami
-whami:
- .prologue 0
- call_pal PAL_whami
- ret ($26)
- .end whami
-
- .align 3
- .globl wripir
- .ent wripir
-wripir:
- .prologue 0
- call_pal PAL_wripir
- ret ($26)
- .end wripir
-
- .align 3
- .globl wrvptptr
- .ent wrvptptr
-wrvptptr:
- .prologue 0
- call_pal PAL_wrvptptr
- ret ($26)
- .end wrvptptr
X
X #
X # The following two functions are needed for supporting SRM PALcode
diff -u --recursive --new-file v2.2.9/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
--- v2.2.9/linux/arch/alpha/kernel/irq.c Tue Jan 19 11:32:50 1999
+++ linux/arch/alpha/kernel/irq.c Sat May 22 13:42:26 1999
@@ -192,13 +192,21 @@
X }
X
X void
-disable_irq(unsigned int irq_nr)
+disable_irq_nosync(unsigned int irq_nr)
X {
X unsigned long flags;
X
X save_and_cli(flags);
X mask_irq(irq_nr);
X restore_flags(flags);
+}
+
+void
+disable_irq(unsigned int irq_nr)
+{
+ /* This works non-SMP, and SMP until we write code to distribute
+ interrupts to more that cpu 0. */
+ disable_irq_nosync(irq_nr);
X }
X
X void
diff -u --recursive --new-file v2.2.9/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c
--- v2.2.9/linux/arch/alpha/kernel/process.c Tue May 11 13:10:27 1999
+++ linux/arch/alpha/kernel/process.c Sat May 22 13:42:29 1999
@@ -75,33 +75,46 @@
X return 0;
X }
X
-static void __attribute__((noreturn))
-do_cpu_idle(void)
+#ifdef __SMP__
+void
+cpu_idle(void *unused)
X {
X /* An endless idle loop with no priority at all. */
X current->priority = 0;
+ current->counter = -100;
+
X while (1) {
- check_pgt_cache();
- run_task_queue(&tq_scheduler);
- current->counter = 0;
- schedule();
- }
-}
+ /* FIXME -- EV6 and LCA45 know how to power down
+ the CPU. */
X
-#ifdef __SMP__
-void
-cpu_idle(void *unused)
-{
- do_cpu_idle();
+ /* Although we are an idle CPU, we do not want to
+ get into the scheduler unnecessarily. */
+ if (current->need_resched) {
+ schedule();
+ check_pgt_cache();
+ }
+ }
X }
X #endif
X
X asmlinkage int
X sys_idle(void)
X {
- if (current->pid == 0)
- do_cpu_idle();
- return -EPERM;
+ if (current->pid != 0)
+ return -EPERM;
+
+ /* An endless idle loop with no priority at all. */
+ current->priority = 0;
+ current->counter = -100;
+ init_idle();
+
+ while (1) {
+ /* FIXME -- EV6 and LCA45 know how to power down
+ the CPU. */
+
+ schedule();
+ check_pgt_cache();
+ }
X }
X
X void
diff -u --recursive --new-file v2.2.9/linux/arch/alpha/kernel/proto.h linux/arch/alpha/kernel/proto.h
--- v2.2.9/linux/arch/alpha/kernel/proto.h Tue Feb 23 15:21:32 1999
+++ linux/arch/alpha/kernel/proto.h Sat Jun 12 11:52:52 1999
@@ -151,6 +151,8 @@
X extern void setup_smp(void);
X extern int smp_info(char *buffer);
X extern void handle_ipi(struct pt_regs *);
+extern void smp_percpu_timer_interrupt(struct pt_regs *);
+extern int smp_boot_cpuid;
X
X /* bios32.c */
X extern void reset_for_srm(void);
@@ -178,7 +180,7 @@
X extern void wrmces(unsigned long mces);
X extern void cserve_ena(unsigned long);
X extern void cserve_dis(unsigned long);
-extern void __start_cpu(unsigned long);
+extern void __smp_callin(unsigned long);
X
X /* entry.S */
X extern void entArith(void);
diff -u --recursive --new-file v2.2.9/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
--- v2.2.9/linux/arch/alpha/kernel/setup.c Wed Apr 28 11:37:29 1999
+++ linux/arch/alpha/kernel/setup.c Sat May 22 13:42:31 1999
@@ -106,6 +106,7 @@
X WEAK(alphabook1_mv);
X WEAK(avanti_mv);
X WEAK(cabriolet_mv);
+WEAK(clipper_mv);
X WEAK(dp264_mv);
X WEAK(eb164_mv);
X WEAK(eb64p_mv);
@@ -330,6 +331,10 @@
X
X /* Round it up to an even number of pages. */
X high = (high + PAGE_SIZE) & (PAGE_MASK*2);
+
+ /* Enforce maximum of 2GB even if there is more. Blah. */
+ if (high > 0x80000000UL)
+ high = 0x80000000UL;
X return PAGE_OFFSET + high;
X }
X
@@ -448,11 +453,11 @@
X static struct alpha_machine_vector *tsunami_vecs[] __initlocaldata =
X {
X NULL,
- &dp264_mv, /* dp164 */
+ &dp264_mv, /* dp264 */
X &dp264_mv, /* warhol */
X &dp264_mv, /* windjammer */
X &monet_mv, /* monet */
- &dp264_mv, /* clipper */
+ &clipper_mv, /* clipper */
X &dp264_mv, /* goldrush */
X &webbrick_mv, /* webbrick */
X &dp264_mv, /* catamaran */
@@ -537,6 +542,7 @@
X &alphabook1_mv,
X &avanti_mv,
X &cabriolet_mv,
+ &clipper_mv,
X &dp264_mv,
X &eb164_mv,
X &eb64p_mv,
diff -u --recursive --new-file v2.2.9/linux/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c
--- v2.2.9/linux/arch/alpha/kernel/signal.c Fri Oct 23 22:01:19 1998
+++ linux/arch/alpha/kernel/signal.c Sat Jun 12 11:52:52 1999
@@ -24,6 +24,9 @@
X #include <asm/sigcontext.h>
X #include <asm/ucontext.h>
X
+#include "proto.h"
+
+
X #define DEBUG_SIG 0
X
X #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
diff -u --recursive --new-file v2.2.9/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c
--- v2.2.9/linux/arch/alpha/kernel/smp.c Tue May 11 13:10:27 1999
+++ linux/arch/alpha/kernel/smp.c Sat Jun 12 11:52:52 1999
@@ -18,6 +18,7 @@
X #include <asm/ptrace.h>
X #include <asm/atomic.h>
X
+#include <asm/io.h>
X #include <asm/irq.h>
X #include <asm/bitops.h>
X #include <asm/pgtable.h>
@@ -29,6 +30,8 @@
X #include <asm/unistd.h>
X
X #include "proto.h"
+#include "irq.h"
+
X
X #define DEBUG_SMP 0
X #if DEBUG_SMP
@@ -37,62 +40,44 @@
X #define DBGS(args)
X #endif
X
-struct ipi_msg_flush_tb_struct {
- volatile unsigned int flush_tb_mask;
- union {
- struct mm_struct * flush_mm;
- struct vm_area_struct * flush_vma;
- } p;
- unsigned long flush_addr;
- unsigned long flush_end;
-};
-
-static struct ipi_msg_flush_tb_struct ipi_msg_flush_tb __cacheline_aligned;
-static spinlock_t flush_tb_lock = SPIN_LOCK_UNLOCKED;
-
+/* A collection of per-processor data. */
X struct cpuinfo_alpha cpu_data[NR_CPUS];
X
-spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED;
-spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
+/* A collection of single bit ipi messages. */
+static struct {
+ unsigned long bits __cacheline_aligned;
+} ipi_data[NR_CPUS];
X
-unsigned int boot_cpu_id = 0;
-static int smp_activated = 0;
-
-int smp_found_config = 0; /* Have we found an SMP box */
-static int max_cpus = -1;
+enum ipi_message_type {
+ IPI_RESCHEDULE,
+ IPI_CALL_FUNC,
+ IPI_CPU_STOP,
+};
X
-unsigned int cpu_present_map = 0;
+spinlock_t kernel_flag __cacheline_aligned = SPIN_LOCK_UNLOCKED;
X
-int smp_num_cpus = 1;
-int smp_num_probed = 0; /* Internal processor count */
+/* Set to a secondary's cpuid when it comes online. */
+static unsigned long smp_secondary_alive;
X
-int smp_threads_ready = 0;
-volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};
-volatile unsigned long smp_spinning[NR_CPUS] = { 0, };
+unsigned long cpu_present_mask; /* Which cpus ids came online. */
X
+static int max_cpus = -1; /* Command-line limitation. */
+int smp_boot_cpuid; /* Which processor we booted from. */
+int smp_num_probed; /* Internal processor count */
+int smp_num_cpus = 1; /* Number that came online. */
+int smp_threads_ready; /* True once the per process idle is forked. */
X cycles_t cacheflush_time;
X
-unsigned int prof_multiplier[NR_CPUS];
-unsigned int prof_counter[NR_CPUS];
-
-volatile int ipi_bits[NR_CPUS] __cacheline_aligned;
-
-unsigned long boot_cpu_palrev;
-
-volatile int smp_commenced = 0;
-volatile int smp_processors_ready = 0;
-
-volatile int cpu_number_map[NR_CPUS];
-volatile int cpu_logical_map[NR_CPUS];
+int cpu_number_map[NR_CPUS];
+int __cpu_logical_map[NR_CPUS];
X
X extern void calibrate_delay(void);
-extern struct thread_struct * original_pcb_ptr;
-
-static void smp_setup_percpu_timer(void);
-static void secondary_cpu_start(int, struct task_struct *);
-static void send_cpu_msg(char *, int);
+extern asmlinkage void entInt(void);
X
-/* Process bootcommand SMP options, like "nosmp" and "maxcpus=" */
+
+/*
+ * Process bootcommand SMP options, like "nosmp" and "maxcpus=".
+ */
X void __init
X smp_setup(char *str, int *ints)
X {
@@ -102,100 +87,87 @@
X max_cpus = 0;
X }
X
-static void __init
-smp_store_cpu_info(int id)
+/*
+ * Called by both boot and secondaries to move global data into
+ * per-processor storage.
+ */
+static inline void __init
+smp_store_cpu_info(int cpuid)
X {
- /* This is it on Alpha, so far. */
- cpu_data[id].loops_per_sec = loops_per_sec;
+ cpu_data[cpuid].loops_per_sec = loops_per_sec;
X }
X
-void __init
-smp_commence(void)
+/*
+ * Ideally sets up per-cpu profiling hooks. Doesn't do much now...
+ */
+static inline void __init
+smp_setup_percpu_timer(int cpuid)
X {
- /* Lets the callin's below out of their loop. */
- mb();
- smp_commenced = 1;
+ cpu_data[cpuid].prof_counter = 1;
+ cpu_data[cpuid].prof_multiplier = 1;
+
+#ifdef NOT_YET_PROFILING
+ load_profile_irq(mid_xlate[cpu], lvl14_resolution);
+ if (cpu == smp_boot_cpuid)
+ enable_pil_irq(14);
+#endif
X }
X
+/*
+ * Where secondaries begin a life of C.
+ */
X void __init
X smp_callin(void)
X {
X int cpuid = hard_smp_processor_id();
X
X DBGS(("CALLIN %d state 0x%lx\n", cpuid, current->state));
-#ifdef HUH
- local_flush_cache_all();
- local_flush_tlb_all();
-#endif
-#if 0
- set_irq_udt(mid_xlate[boot_cpu_id]);
-#endif
+
+ /* Turn on machine checks. */
+ wrmces(7);
+
+ /* Set trap vectors. */
+ trap_init();
+
+ /* Set interrupt vector. */
+ wrent(entInt, 0);
+
+ /* Setup the scheduler for this processor. */
+ init_idle();
X
X /* Get our local ticker going. */
- smp_setup_percpu_timer();
+ smp_setup_percpu_timer(cpuid);
X
-#if 0
+ /* Must have completely accurate bogos. */
+ __sti();
X calibrate_delay();
-#endif
X smp_store_cpu_info(cpuid);
-#ifdef HUH
- local_flush_cache_all();
- local_flush_tlb_all();
-#endif
X
X /* Allow master to continue. */
- set_bit(cpuid, (unsigned long *)&cpu_callin_map[cpuid]);
-#ifdef HUH
- local_flush_cache_all();
- local_flush_tlb_all();
-#endif
-
-#ifdef NOT_YET
- while(!task[cpuid] || current_set[cpuid] != task[cpuid])
- barrier();
-#endif
-
-#ifdef HUH
- local_flush_cache_all();
- local_flush_tlb_all();
-#endif
-#if 0
- __sti();
-#endif
-}
+ wmb();
+ smp_secondary_alive = cpuid;
X
-asmlinkage int __init
-start_secondary(void *unused)
-{
- extern asmlinkage void entInt(void);
- extern void paging_init_secondary(void);
+ /* Wait for the go code. */
+ while (!smp_threads_ready)
+ barrier();
X
- wrmces(7);
- paging_init_secondary();
- trap_init();
- wrent(entInt, 0);
+ DBGS(("smp_callin: commencing CPU %d current %p\n",
+ cpuid, current));
X
- smp_callin();
- while (!smp_commenced)
- barrier();
-#if 1
- printk("start_secondary: commencing CPU %d current %p\n",
- hard_smp_processor_id(), current);
-#endif
+ /* Do nothing. */
X cpu_idle(NULL);
X }
X
+
+/*
+ * Rough estimation for SMP scheduling, this is the number of cycles it
+ * takes for a fully memory-limited process to flush the SMP-local cache.
+ *
+ * We are not told how much cache there is, so we have to guess.
+ */
X static void __init
X smp_tune_scheduling (void)
X {
- /*
- * Rough estimation for SMP scheduling, this is the number of
- * cycles it takes for a fully memory-limited process to flush
- * the SMP-local cache.
- *
- * We are not told how much cache there is, so we have to guess.
- */
-
X struct percpu_struct *cpu;
X unsigned long on_chip_cache;
X unsigned long freq;
@@ -231,298 +203,18 @@
X cacheflush_time = freq / 1024 * on_chip_cache / 5000;
X }
X
-
X /*
- * Cycle through the processors sending START msgs to boot each.
+ * Send a message to a secondary's console. "START" is one such
+ * interesting message. ;-)
X */
-void __init
-smp_boot_cpus(void)
-{
- int cpucount = 0;
- int i, first, prev;
-
- printk("Entering SMP Mode.\n");
-
-#if 0
- __sti();
-#endif
-
- for(i=0; i < NR_CPUS; i++) {
- cpu_number_map[i] = -1;
- cpu_logical_map[i] = -1;
- prof_counter[i] = 1;
- prof_multiplier[i] = 1;
- ipi_bits[i] = 0;
- }
-
- cpu_number_map[boot_cpu_id] = 0;
- cpu_logical_map[0] = boot_cpu_id;
- current->processor = boot_cpu_id; /* ??? */
-
- smp_store_cpu_info(boot_cpu_id);
- smp_tune_scheduling();
-#ifdef NOT_YET
- printk("CPU%d: ", boot_cpu_id);
- print_cpu_info(&cpu_data[boot_cpu_id]);
- set_irq_udt(mid_xlate[boot_cpu_id]);
-#endif
- smp_setup_percpu_timer();
-#ifdef HUH
- local_flush_cache_all();
-#endif
- if (smp_num_probed == 1)
- return; /* Not an MP box. */
-
-#if NOT_YET
- /*
- * If SMP should be disabled, then really disable it!
- */
- if (!max_cpus)
- {
- smp_found_config = 0;
- printk(KERN_INFO "SMP mode deactivated.\n");
- }
-#endif
-
- for (i = 0; i < NR_CPUS; i++) {
-
- if (i == boot_cpu_id)
- continue;
-
- if (cpu_present_map & (1 << i)) {
- struct task_struct *idle;
- int timeout;
-
- /* Cook up an idler for this guy. */
- kernel_thread(start_secondary, NULL, CLONE_PID);
- idle = task[++cpucount];
- if (!idle)
- panic("No idle process for CPU %d", i);
- idle->processor = i;
-
- DBGS(("smp_boot_cpus: CPU %d state 0x%lx flags 0x%lx\n",
- i, idle->state, idle->flags));
-
- /* whirrr, whirrr, whirrrrrrrrr... */
-#ifdef HUH
- local_flush_cache_all();
-#endif
- secondary_cpu_start(i, idle);
-
- /* wheee... it's going... wait for 5 secs...*/
- for (timeout = 0; timeout < 50000; timeout++) {
- if (cpu_callin_map[i])
- break;
- udelay(100);
- }
- if (cpu_callin_map[i]) {
- /* Another "Red Snapper". */
- cpu_number_map[i] = cpucount;
- cpu_logical_map[cpucount] = i;
- } else {
- cpucount--;
- printk("smp_boot_cpus: Processor %d"
- " is stuck 0x%lx.\n", i, idle->flags);
- }
- }
- if (!(cpu_callin_map[i])) {
- cpu_present_map &= ~(1 << i);
- cpu_number_map[i] = -1;
- }
- }
-#ifdef HUH
- local_flush_cache_all();
-#endif
- if (cpucount == 0) {
- printk("smp_boot_cpus: ERROR - only one Processor found.\n");
- cpu_present_map = (1 << smp_processor_id());
- } else {
- unsigned long bogosum = 0;
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_present_map & (1 << i))
- bogosum += cpu_data[i].loops_per_sec;
- }
- printk("smp_boot_cpus: Total of %d Processors activated"
- " (%lu.%02lu BogoMIPS).\n",
- cpucount + 1,
- (bogosum + 2500)/500000,
- ((bogosum + 2500)/5000)%100);
- smp_activated = 1;
- smp_num_cpus = cpucount + 1;
- }
-
- /* Setup CPU list for IRQ distribution scheme. */
- first = prev = -1;
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_present_map & (1 << i)) {
- if (first == -1)
- first = i;
- if (prev != -1)
- cpu_data[i].next = i;
- prev = i;
- }
- }
- cpu_data[prev].next = first;
-
- /* Ok, they are spinning and ready to go. */
- smp_processors_ready = 1;
-}
-
-static void __init
-smp_setup_percpu_timer(void)
-{
- int cpu = smp_processor_id();
-
- prof_counter[cpu] = prof_multiplier[cpu] = 1;
-#ifdef NOT_YET
- load_profile_irq(mid_xlate[cpu], lvl14_resolution);
- if (cpu == boot_cpu_id)
- enable_pil_irq(14);
-#endif
-}
-
-extern void update_one_process(struct task_struct *p, unsigned long ticks,
- unsigned long user, unsigned long system,
- int cpu);
-
-void
-smp_percpu_timer_interrupt(struct pt_regs *regs)
-{
- int cpu = smp_processor_id();
-
-#ifdef NOT_YET
- clear_profile_irq(mid_xlate[cpu]);
- if(!user_mode(regs))
- alpha_do_profile(regs->pc);
-#endif
-
- if (!--prof_counter[cpu]) {
- int user = user_mode(regs);
- if (current->pid) {
- update_one_process(current, 1, user, !user, cpu);
-
- if (--current->counter < 0) {
- current->counter = 0;
- current->need_resched = 1;
- }
-
- spin_lock(&ticker_lock);
- if (user) {
- if (current->priority < DEF_PRIORITY) {
- kstat.cpu_nice++;
- kstat.per_cpu_nice[cpu]++;
- } else {
- kstat.cpu_user++;
- kstat.per_cpu_user[cpu]++;
- }
- } else {
- kstat.cpu_system++;
- kstat.per_cpu_system[cpu]++;
- }
- spin_unlock(&ticker_lock);
- }
- prof_counter[cpu] = prof_multiplier[cpu];
- }
-}
-
-int __init
-setup_profiling_timer(unsigned int multiplier)
-{
-#ifdef NOT_YET
- int i;
- unsigned long flags;
-
- /* Prevent level14 ticker IRQ flooding. */
- if((!multiplier) || (lvl14_resolution / multiplier) < 500)
- return -EINVAL;
-
- save_and_cli(flags);
- for(i = 0; i < NR_CPUS; i++) {
- if(cpu_present_map & (1 << i)) {
- load_profile_irq(mid_xlate[i], lvl14_resolution / multip
-lier);
- prof_multiplier[i] = multiplier;
- }
- }
- restore_flags(flags);
-
- return 0;
-
-#endif
- return -EINVAL;
-}
-
-/* Only broken Intel needs this, thus it should not even be
- referenced globally. */
-
-void __init
-initialize_secondary(void)
-{
-}
-
-static void __init
-secondary_cpu_start(int cpuid, struct task_struct *idle)
-{
- struct percpu_struct *cpu;
- int timeout;
-
- cpu = (struct percpu_struct *)
- ((char*)hwrpb
- + hwrpb->processor_offset
- + cpuid * hwrpb->processor_size);
-
- /* Set context to idle thread this CPU will use when running
- assumption is that the idle thread is all set to go... ??? */
- memcpy(&cpu->hwpcb[0], &idle->tss, sizeof(struct pcb_struct));
- cpu->hwpcb[4] = cpu->hwpcb[0]; /* UNIQUE set to KSP ??? */
-
- DBGS(("KSP 0x%lx PTBR 0x%lx VPTBR 0x%lx\n",
- cpu->hwpcb[0], cpu->hwpcb[2], hwrpb->vptb));
- DBGS(("Starting secondary cpu %d: state 0x%lx pal_flags 0x%lx\n",
- cpuid, idle->state, idle->tss.pal_flags));
-
- /* Setup HWRPB fields that SRM uses to activate secondary CPU */
- hwrpb->CPU_restart = __start_cpu;
- hwrpb->CPU_restart_data = (unsigned long) idle;
-
- /* Recalculate and update the HWRPB checksum */
- hwrpb_update_checksum(hwrpb);
-
- /*
- * Send a "start" command to the specified processor.
- */
-
- /* SRM III 3.4.1.3 */
- cpu->flags |= 0x22; /* turn on Context Valid and Restart Capable */
- cpu->flags &= ~1; /* turn off Bootstrap In Progress */
- mb();
-
- send_cpu_msg("START\r\n", cpuid);
-
- /* now, we wait... */
- for (timeout = 10000; !(cpu->flags & 1); timeout--) {
- if (timeout <= 0) {
- printk("Processor %d failed to start\n", cpuid);
- /* needed for pset_info to work */
-#if 0
- ipc_processor_enable(cpu_to_processor(cpunum));
-#endif
- return;
- }
- mdelay(1);
- barrier();
- }
- DBGS(("secondary_cpu_start: SUCCESS for CPU %d!!!\n", cpuid));
-}
-
X static void
-send_cpu_msg(char *str, int cpuid)
+send_secondary_console_msg(char *str, int cpuid)
X {
X struct percpu_struct *cpu;
X register char *cp1, *cp2;
X unsigned long cpumask;
X size_t len;
- int timeout;
+ long timeout;
X
X cpu = (struct percpu_struct *)
X ((char*)hwrpb
@@ -541,6 +233,7 @@
X memcpy(cp1, cp2, len);
X
X /* atomic test and set */
+ wmb();
X set_bit(cpuid, &hwrpb->rxrdy);
X
X if (hwrpb->txrdy & cpumask)
@@ -549,19 +242,21 @@
X return;
X
X delay1:
- for (timeout = 10000; timeout > 0; --timeout) {
+ /* Wait one second. Note that jiffies aren't ticking yet. */
+ for (timeout = 100000; timeout > 0; --timeout) {
X if (!(hwrpb->txrdy & cpumask))
X goto ready1;
- udelay(100);
+ udelay(10);
X barrier();
X }
X goto timeout;
X
X delay2:
- for (timeout = 10000; timeout > 0; --timeout) {
+ /* Wait one second. */
+ for (timeout = 100000; timeout > 0; --timeout) {
X if (!(hwrpb->txrdy & cpumask))
X goto ready2;
- udelay(100);
+ udelay(10);
X barrier();
X }
X goto timeout;
@@ -572,64 +267,17 @@
X }
X
X /*
- * setup_smp()
- *
- * called from arch/alpha/kernel/setup.c:setup_arch() when __SMP__ defined
+ * A secondary console wants to send a message. Receive it.
X */
-void __init
-setup_smp(void)
-{
- struct percpu_struct *cpubase, *cpu;
- int i;
-
- boot_cpu_id = hard_smp_processor_id();
- if (boot_cpu_id != 0) {
- printk("setup_smp: boot_cpu_id != 0 (%d).\n", boot_cpu_id);
- }
-
- if (hwrpb->nr_processors > 1) {
-
- DBGS(("setup_smp: nr_processors %ld\n",
- hwrpb->nr_processors));
-
- cpubase = (struct percpu_struct *)
- ((char*)hwrpb + hwrpb->processor_offset);
- boot_cpu_palrev = cpubase->pal_revision;
-
- for (i = 0; i < hwrpb->nr_processors; i++ ) {
- cpu = (struct percpu_struct *)
- ((char *)cpubase + i*hwrpb->processor_size);
- if ((cpu->flags & 0x1cc) == 0x1cc) {
- smp_num_probed++;
- /* assume here that "whami" == index */
- cpu_present_map |= (1 << i);
- if (i != boot_cpu_id)
- cpu->pal_revision = boot_cpu_palrev;
- }
-
- DBGS(("setup_smp: CPU %d: flags 0x%lx type 0x%lx\n",
- i, cpu->flags, cpu->type));
- DBGS(("setup_smp: CPU %d: PAL rev 0x%lx\n",
- i, cpu->pal_revision));
- }
- } else {
- smp_num_probed = 1;
- cpu_present_map = (1 << boot_cpu_id);
- }
- printk("setup_smp: %d CPUs probed, cpu_present_map 0x%x,"
- " boot_cpu_id %d\n",
- smp_num_probed, cpu_present_map, boot_cpu_id);
-}
-
X static void
-secondary_console_message(void)
+recv_secondary_console_msg(void)
X {
X int mycpu, i, cnt;
X unsigned long txrdy = hwrpb->txrdy;
X char *cp1, *cp2, buf[80];
X struct percpu_struct *cpu;
X
- DBGS(("secondary_console_message: TXRDY 0x%lx.\n", txrdy));
+ DBGS(("recv_secondary_console_msg: TXRDY 0x%lx.\n", txrdy));
X
X mycpu = hard_smp_processor_id();
X
@@ -637,7 +285,7 @@
X if (!(txrdy & (1L << i)))
X continue;
X
- DBGS(("secondary_console_message: "
+ DBGS(("recv_secondary_console_msg: "
X "TXRDY contains CPU %d.\n", i));
X
X cpu = (struct percpu_struct *)
@@ -645,9 +293,9 @@
X + hwrpb->processor_offset
X + i * hwrpb->processor_size);
X
- printk("secondary_console_message: on %d from %d"
- " HALT_REASON 0x%lx FLAGS 0x%lx\n",
- mycpu, i, cpu->halt_reason, cpu->flags);
+ DBGS(("recv_secondary_console_msg: on %d from %d"
+ " HALT_REASON 0x%lx FLAGS 0x%lx\n",
+ mycpu, i, cpu->halt_reason, cpu->flags));
X
X cnt = cpu->ipc_buffer[0] >> 32;
X if (cnt <= 0 || cnt >= 80)
@@ -664,85 +312,347 @@
X }
X }
X
- printk("secondary_console_message: on %d message is '%s'\n",
- mycpu, buf);
+ printk(KERN_INFO "recv_secondary_console_msg: on %d "
+ "message is '%s'\n", mycpu, buf);
X }
X
X hwrpb->txrdy = 0;
X }
X
-enum ipi_message_type {
- IPI_TLB_ALL,
- IPI_TLB_MM,
- IPI_TLB_PAGE,
- IPI_RESCHEDULE,
- IPI_CPU_STOP
-};
-
-void
-handle_ipi(struct pt_regs *regs)
+/*
+ * Convince the console to have a secondary cpu begin execution.
+ */
+static int __init
+secondary_cpu_start(int cpuid, struct task_struct *idle)
X {
- int this_cpu = smp_processor_id();
- volatile int * pending_ipis = &ipi_bits[this_cpu];
- unsigned long ops;
+ struct percpu_struct *cpu;
+ struct pcb_struct *hwpcb;
+ long timeout;
+
+ cpu = (struct percpu_struct *)
+ ((char*)hwrpb
+ + hwrpb->processor_offset
+ + cpuid * hwrpb->processor_size);
+ hwpcb = (struct pcb_struct *) cpu->hwpcb;
X
- DBGS(("handle_ipi: on CPU %d ops 0x%x PC 0x%lx\n",
- this_cpu, *pending_ipis, regs->pc));
+ /* Initialize the CPU's HWPCB to something just good enough for
+ us to get started. Immediately after starting, we'll swpctx
+ to the target idle task's tss. Reuse the stack in the mean
+ time. Precalculate the target PCBB. */
+ hwpcb->ksp = (unsigned long) idle + sizeof(union task_union) - 16;
+ hwpcb->usp = 0;
+ hwpcb->ptbr = idle->tss.ptbr;
+ hwpcb->pcc = 0;
+ hwpcb->asn = 0;
+ hwpcb->unique = virt_to_phys(&idle->tss);
+ hwpcb->flags = idle->tss.pal_flags;
+ hwpcb->res1 = hwpcb->res2 = 0;
X
- mb(); /* Order interrupt and bit testing. */
- while ((ops = xchg(pending_ipis, 0)) != 0) {
- mb(); /* Order bit clearing and data access. */
- do {
- unsigned long which;
+ DBGS(("KSP 0x%lx PTBR 0x%lx VPTBR 0x%lx UNIQUE 0x%lx\n",
+ hwpcb->ksp, hwpcb->ptbr, hwrpb->vptb, hwcpb->unique));
+ DBGS(("Starting secondary cpu %d: state 0x%lx pal_flags 0x%lx\n",
+ cpuid, idle->state, idle->tss.pal_flags));
X
- which = ops & -ops;
- ops &= ~which;
- which = ffz(~which);
+ /* Setup HWRPB fields that SRM uses to activate secondary CPU */
+ hwrpb->CPU_restart = __smp_callin;
+ hwrpb->CPU_restart_data = (unsigned long) __smp_callin;
X
- if (which < IPI_RESCHEDULE) {
- if (which == IPI_TLB_ALL)
- tbia();
- else if (which == IPI_TLB_MM) {
- struct mm_struct * mm;
- mm = ipi_msg_flush_tb.p.flush_mm;
- if (mm == current->mm)
- flush_tlb_current(mm);
- }
- else /* IPI_TLB_PAGE */ {
- struct vm_area_struct * vma;
- struct mm_struct * mm;
- unsigned long addr;
-
- vma = ipi_msg_flush_tb.p.flush_vma;
- mm = vma->vm_mm;
- addr = ipi_msg_flush_tb.flush_addr;
+ /* Recalculate and update the HWRPB checksum */
+ hwrpb_update_checksum(hwrpb);
+
+ /*
+ * Send a "start" command to the specified processor.
+ */
X
- if (mm == current->mm)
- flush_tlb_current_page(mm, vma, addr);
+ /* SRM III 3.4.1.3 */
+ cpu->flags |= 0x22; /* turn on Context Valid and Restart Capable */
+ cpu->flags &= ~1; /* turn off Bootstrap In Progress */
+ wmb();
+
+ send_secondary_console_msg("START\r\n", cpuid);
+
+ /* Wait 1 second for an ACK from the console. Note that jiffies
+ aren't ticking yet. */
+ for (timeout = 100000; timeout > 0; timeout--) {
+ if (cpu->flags & 1)
+ goto started;
+ udelay(10);
+ barrier();
+ }
+ printk(KERN_ERR "SMP: Processor %d failed to start.\n", cpuid);
+ return -1;
+
+started:
SHAR_EOF
true || echo 'restore of patch-2.2.10 failed'
fi
echo 'End of part 02'
echo 'File patch-2.2.10 is continued in part 03'
echo 03 > _shar_seq_.tmp
exit 0

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.2/patch-2.2.10/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 22 - 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.2.10 ==============
if test -f 'patch-2.2.10' -a X"$1" != X"-c"; then
echo 'x - skipping patch-2.2.10 (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting patch-2.2.10 (Text)'


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

diff -u --recursive --new-file v2.2.9/linux/CREDITS linux/CREDITS
--- v2.2.9/linux/CREDITS Tue May 11 13:10:26 1999
+++ linux/CREDITS Wed Jun 9 22:23:01 1999
@@ -611,6 +611,13 @@
X S: Oak Park, Illinois 60302
X S: USA
X
+N: Daniel J. Frasnelli
+E: dfra...@alphalinux.org
+W: http://www.alphalinux.org/
+P: 1024/3EF87611 B9 F1 44 50 D3 E8 C2 80 DA E5 55 AA 56 7C 42 DA
+D: DEC Alpha hacker
+D: Miscellaneous bug squisher
+
X N: Jim Freeman
X E: jf...@sovereign.org
X W: http://www.sovereign.org/
@@ -656,7 +663,7 @@
X E: rgo...@atnf.csiro.au
X D: parent process death signal to children
X D: prctl() syscall
-D: /proc/mtrr support to manipulate MTRRs on Pentium Pro's
+D: /proc/mtrr support to manipulate MTRRs on Intel P6 family
X S: CSIRO Australia Telescope National Facility
X S: P.O. Box 76, Epping
X S: New South Wales, 2121
@@ -754,6 +761,13 @@
X S: London SE16 1GD
X S: United Kingdom
X
+N: Bart Hartgers
+E: ba...@etpmod.phys.tue.nl
+D: MTRR emulation with Centaur MCRs
+S: Gen Stedmanstraat 212
+S: 5623 HZ Eindhoven
+S: The Netherlands
+
X N: Kai Harrekilde-Petersen
X E: k...@dolphinics.no
X D: Original author of the ftape-HOWTO, i82078 fdc detection code.
@@ -801,7 +815,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
diff -u --recursive --new-file v2.2.9/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.2.9/linux/Documentation/Configure.help Tue May 11 13:10:26 1999
+++ linux/Documentation/Configure.help Sun Jun 13 19:54:06 1999
@@ -3749,34 +3749,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
@@ -5213,7 +5228,7 @@
X section (except for CONFIG_IP_ROUTE_TOS and CONFIG_IP_ROUTE_FWMARK).
X At the moment, few devices support fast switching (tulip is one of
X them, modified 8390 can be found at
- ftp://ftp.inr.ac.ru/ip-routing/fastroute-8390.tar.gz).
+ ftp://ftp.inr.ac.ru/ip-routing/fastroute/fastroute-8390.tar.gz).
X
X If unsure, say N.
X
@@ -5223,8 +5238,8 @@
X during periods of extremal congestion. At the moment only a couple
X of device drivers support it (really only one -- tulip, modified
X 8390 can be found at
- ftp://ftp.inr.ac.ru/ip-routing/fastroute-8390.tar.gz). Really, this
- option is applicable to any machine attached to a fast enough
+ ftp://ftp.inr.ac.ru/ip-routing/fastroute/fastroute-8390.tar.gz).
+ Really, this option is applicable to any machine attached to a fast enough
X network, and even a 10 Mb NIC is able to kill a not very slow box,
X such as a 120MHz Pentium.
X
@@ -6160,6 +6175,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
@@ -6517,16 +6546,6 @@
X under Linux, say Y here (you must also remember to enable the driver
X for your HIPPI card below). Most people will say N here.
X
-CERN HIPPI PCI adapter support
-CONFIG_CERN_HIPPI
- Say Y here if this is your PCI HIPPI network card.
-
- This driver is also available as a module ( = code which can be
- inserted in and removed from the running kernel whenever you want).
- The module will be called cern_hippi.o. If you want to compile it as
- a module, say M here and read Documentation/modules.txt. If unsure,
- say N.
-
X Essential RoadRunner HIPPI PCI adapter support
X CONFIG_ROADRUNNER
X Say Y here if this is your PCI HIPPI network card.
@@ -6627,9 +6646,6 @@
X (PhotoCDs). There is a new driver (next question) which can do
X this. If you want that one, say N here.
X
- If the driver doesn't work out of the box, you might want to have a
- look at drivers/cdrom/mcd.h.
-
X If you say Y here, you should also say Y or M to "ISO 9660 CDROM
X filesystem support" below, because that's the filesystem used on
X CDROMs.
@@ -7463,13 +7479,6 @@
X want), say M here and read Documentation/modules.txt. The module
X will be called smbfs.o. Most people say N, however.
X
-SMB Win95 bug work-around
-CONFIG_SMB_WIN95
- If you want to connect to a share exported by Windows 95, you should
- say Y here. The Windows 95 server contains a bug that makes listing
- directories unreliable. This option slows down the listing of
- directories. This makes the Windows 95 server a bit more stable.
-
X Coda filesystem support
X CONFIG_CODA_FS
X Coda is an advanced network filesystem, similar to NFS in that it
@@ -8684,6 +8693,9 @@
X
X The AMD K6-2 (stepping 8 and above) and K6-3 processors have two
X MTRRs. These are supported.
+
+ The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These
+ are supported.
X
X Saying Y here also fixes a problem with buggy SMP BIOSes which only
X set the MTRRs for the boot CPU and not the secondary CPUs. This can
@@ -10759,6 +10771,30 @@
X haven't changed the setting of jumper JP3 on the card. Removing the
X jumper sets the card to 0x358.
X
+ADS Cadet AM/FM Radio Tuner Card
+CONFIG_RADIO_CADET
+ Choose Y here if you have one of these AM/FM radio cards, and then fill
+ in the port address below.
+
+ In order to control your radio card, you will need to use programs
+ that are compatible with the Video for Linux API. Information on
+ this API and pointers to "v4l" programs may be found on the WWW at
+ http://roadrunner.swansea.uk.linux.org/v4l.shtml; to browse the WWW,
+ you need to have access to a machine on the Internet that has a
+ program like lynx or netscape.
+
+ Further documentation on this driver can be found on the WWW at
+ http://linux.blackhawke.net/cadet.html.
+
+ If you want to compile this driver as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want),
+ say M here and read Documentation/modules.txt. The module will be
+ called radio-cadet.o.
+
+ADS Cadet AM/FM Radio Tuner Card I/O Port
+CONFIG_RADIO_CADET_PORT
+ Enter the I/O address of the card here (most commonly 330).
+
X SF16FMI Radio
X CONFIG_RADIO_SF16FMI
X Choose Y here if you have one of these FM radio cards, and then fill
@@ -10941,6 +10977,15 @@
X from the running kernel whenever you want). If you want to compile
X it as a module, say M here and read Documentation/modules.txt.
X
+PlanB Video-In for PowerMacs
+CONFIG_VIDEO_PLANB
+ PlanB is the V4L driver for the PowerMac 7x00/8x00 series video
+ input hardware. If you want to experiment with this, say Y.
+ Otherwise, or if you don't understand a word, say N.
+ See http://www.cpu.lu/~mlan/planb.html for more info.
+
+ Saying M will compile this driver as a module (planb.o).
+
X #
X # ARM options
X #
@@ -11238,6 +11283,21 @@
X
X If unsure, say Y.
X
+IrPORT IrDA Device Driver
+CONFIG_IRPORT_SIR
+ Say Y here if you want to build support for the IrPORT IrDA device
+ driver. If you want to compile it as a module, say M here and
+ read Documentation/modules.txt. IrPORT can be used instead of
+ IrTTY and sometimes this can be better. One example is if your
+ IrDA port does not have echo-canceling, which will work OK with
+ IrPORT since this driver is working in half-duplex mode only. You
+ don't need to use irattach with IrPORT, but you just insert it
+ the same way as FIR drivers (insmod irport io=0x3e8 irq=11).
+ Notice that IrPORT is a SIR device driver which means that speed
+ is limited to 115200 bps.
+
+ If unsure, say Y.
+
X Winbond W83977AF IrDA Device Driver
X CONFIG_WINBOND_FIR
X Say Y here if you want to build IrDA support for the Winbond
@@ -11261,6 +11321,13 @@
X read Documentation/modules.txt. This chipset is used by the Toshiba
X Tecra laptops.
X
+Toshiba Type-O IR Port Device Driver
+CONFIG_TOSHIBA_FIR
+ Say Y here if you want to build support for the Toshiba Type-O IR
+ chipset. If you want to compile it as a module, say M here and
+ read Documentation/modules.txt. This chipset is used by the Toshiba
+ Libretto 100CT, and many more laptops.
+
X ESI JetEye PC Dongle
X CONFIG_ESI_DONGLE
X Say Y here if you want to build support for the Extended Systems
@@ -11297,6 +11364,15 @@
X normal 9-pin serial port connector, and can currently only be used
X by IrTTY. To activate support for Greenwich dongles you will have to
X insert "irattach -d girbil" in the /etc/irda/drivers script.
+
+Parallax Litelink dongle
+CONFIG_LITELINK_DONGLE
+ Say Y here if you want to build support for the Parallax Litelink
+ dongle. If you want to compile it as a module, say M here and read
+ Documentation/modules.txt. The Parallax dongle attaches to the
+ normal 9-pin serial port connector, and can currently only be used
+ by IrTTY. To activate support for Parallax dongles you will have to
+ insert "irattach -d litelink" in the /etc/irda/drivers script.
X
X VME (Motorola and BVM) support
X CONFIG_VME
diff -u --recursive --new-file v2.2.9/linux/Documentation/isdn/CREDITS linux/Documentation/isdn/CREDITS
--- v2.2.9/linux/Documentation/isdn/CREDITS Wed Apr 1 20:11:47 1998
+++ linux/Documentation/isdn/CREDITS Wed Jun 2 11:29:27 1999
@@ -5,7 +5,7 @@
X Thomas Bogendörfer (tsbo...@bigbug.franken.de)
X Tester, lots of bugfixes and hints.
X
-Alan Cox (al...@cymru.net)
+Alan Cox (al...@redhat.com)
X For help getting into standard-kernel.
X
X Henner Eisen (e...@baty.hanse.de)
diff -u --recursive --new-file v2.2.9/linux/Documentation/kernel-parameters.txt linux/Documentation/kernel-parameters.txt
--- v2.2.9/linux/Documentation/kernel-parameters.txt Wed Dec 31 16:00:00 1969
+++ linux/Documentation/kernel-parameters.txt Mon Jun 7 16:13:07 1999
@@ -0,0 +1,336 @@
+June 1999 Kernel Parameters v2.2.9
+ ~~~~~~~~~~~~~~~~~
+
+The following is a consolidated list of the kernel parameters as defined
+in the file init/main.c and sorted into English Dictionary order (defined
+as ignoring all punctuation and sorting digits before letters in a case
+insensitive manner), and with descriptions where known.
+
+The text in square brackets at the beginning of the description state the
+restrictions on the kernel for the said kernel parameter to be valid. The
+restrictions referred to are that the relevant option is valid if:
+
+ APIC APIC support is enabled.
+ APM Automatic Power Management support is enabled.
+ AX25 Appropriate AX.25 support is enabled.
+ CD Appropriate CD support is enabled.
+ EIDE EIDE/ATAPI support is enabled.
+ FB The frame buffer device is enabled.
+ HW Appropriate hardware is enabled.
+ ISDN Appropriate ISDN support is enabled.
+ JOY Appropriate joystick support is enabled.
+ LPT Printer support is enabled.
+ MCA MCA bus support is enabled.
+ MDA The MDA console is enabled.
+ MOUSE Appropriate mouse support is enabled.
+ NET Appropriate network support is enabled.
+ NFS Appropriate NFS support is enabled.
+ PARIDE The ParIDE subsystem is enabled.
+ PCI PCI bus support is enabled.
+ PCMCIA The PCMCIA subsystem is enabled.
+ PNP Plug & Play support is enabled.
+ PS2 Appropriate PS/2 support is enabled.
+ RAM RAMdisc support is enabled.
+ SCSI Appropriate SCSI support is enabled.
+ SERIAL Serial support is enabled.
+ SMP The kernel is an SMP kernel.
+ SOUND Appropriate sound system support is enabled.
+ VGA The VGA console has been enabled.
+ VT Virtual terminal support is enabled.
+ XT IBM PC/XT MFM hard disk support is enabled.
+
+In addition, the following text indicates that the option:
+
+ BUGS= Relates to possible processor bugs on the said processor.
+ KNL Is a kernel start-up parameter.
+
+Note that ALL kernel parameters listed below are CASE SENSITIVE, and that
+a trailing = on the name of any parameter states that that parameter will
+be entered as an environment variable, whereas its absence indicates that
+it will appear as a kernel argument readable via /proc/cmdline by programs
+running once the system is up.
+
+ 53c7xx= [HW,SCSI]
+
+ adb_buttons= [HW,MOUSE]
+
+ advansys= [HW,SCSI]
+
+ aha152x= [HW,SCSI]
+
+ aha1542= [HW,SCSI]
+
+ aic7xxx= [HW,SCSI]
+
+ AM53C974= [HW,SCSI]
+
+ apm= [APM] Automatic Power Management.
+
+ arcrimi= [HW,NET]
+
+ atamouse= [HW,MOUSE] Atari Mouse.
+
+ atascsi= [HW,SCSI] Atari SCSI.
+
+ aztcd= [HW,CD] Aztec CD driver.
+
+ baycom_par= [HW,AX25] BayCom Parallel Port AX.25 Modem.
+
+ baycom_ser_fdx= [HW,AX25] BayCom Serial Port AX.25 Modem in Full
+ Duplex Mode.
+
+ baycom_ser_hdx= [HW,AX25] BayCom Serial Port AX.25 Modem in Half
+ Duplex Mode.
+
+ bmouse= [HW,MOUSE,PS2] Bus mouse.
+
+ BusLogic= [HW,SCSI]
+
+ cdu31a= [HW,CD]
+
+ cm206= [HW,CD]
+
+ com20020= [HW,NET]
+
+ com90io= [HW,NET]
+
+ com90xx= [HW,NET]
+
+ console=
+
+ cyclades= [HW,SERIAL] Cyclades multi-serial port adapter.
+
+ debug [KNL] Enable kernel debugging.
+
+ decnet= [HW,NET]
+
+ digi= [HW,SERIAL]
+
+ digiepca= [HW,SERIAL]
+
+ dmascc= [HW,AX25,SERIAL] AX.25 Z80SCC driver with DMA
+ support available.
+
+ dmasound= [HW,SOUND]
+
+ dtc3181e= [HW,SCSI]
+
+ eata= [HW,SCSI]
+
+ eda= [HW,PS2]
+
+ edb= [HW,PS2]
+
+ ether= [HW,NET] Ethernet.
+
+ fd_mcs= [HW,SCSI]
+
+ fdomain= [HW,SCSI]
+
+ floppy= [HW]
+
+ ftape= [HW] Floppy Tape subsystem.
+
+ gdth= [HW,SCSI]
+
+ gscd= [HW,CD]
+
+ gvp11= [HW,SCSI]
+
+ hd= [EIDE] IDE and EIDE hard drive subsystem.
+
+ hfmodem= [HW,AX25]
+
+ HiSax= [HW,ISDN]
+
+ hisax= [HW,ISDN]
+
+ ibmmcascsi= [HW,MCA,SCSI] IBM MicroChannel SCSI adapter.
+
+ icn= [HW,ISDN]
+
+ in2000= [HW,SCSI]
+
+ init= [KNL]
+
+ ip= [PNP]
+
+ isp16= [HW,CD]
+
+ js_14= [HW,JOY]
+
+ js_am= [HW,JOY]
+
+ js_an= [HW,JOY]
+
+ js_as= [HW.JOY]
+
+ js_console= [HW,JOY]
+
+ js_console2= [HW,JOY]
+
+ js_console3= [HW,JOY]
+
+ js_db9= [HW,JOY]
+
+ js_db9_2= [HW,JOY]
+
+ js_db9_3= [HW,JOY]
+
+ js_tg= [HW,JOY]
+
+ js_tg_2= [HW,JOY]
+
+ js_tg_3= [HW,JOY]
+
+ kbd-reset [VT]
+
+ load_ramdisk= [RAM]
+
+ lp= [LPT] Parallel Printer.
+
+ ltpc= [HW]
+
+ mac5380= [HW,SCSI]
+
+ maxcpus= [SMP] States the maximum number of processors that
+ an SMP kernel should make use of.
+
+ max_scsi_luns= [SCSI]
+
+ mca-pentium [BUGS=ix86]
+
+ mcd= [HW,CD]
+
+ mcdx= [HW,CD]
+
+ md= [HW]
+
+ mdacon= [MDA]
+
+ msmouse= [HW,MOUSE] Microsoft Mouse.
+
+ ncr5380= [HW,SCSI]
+
+ ncr53c400= [HW,SCSI]
+
+ ncr53c400a= [HW,SCSI]
+
+ ncr53c406a= [HW,SCSI]
+
+ ncr53c8xx= [HW,SCSI]
+
+ nfsaddrs= [NFS]
+
+ nfsroot= [NFS]
+
+ no387 [BUGS=ix86] Tells the kernel to use the 387 maths
+ emulation library even if a 387 maths coprocessor
+ is present.
+
+ noapic [SMP,APIC] Tells the kernel not to make use of any
+ APIC that may be present on the system.
+
+ no-halt [BUGS=ix86]
+
+ noinitrd [RAM] Tells the kernel not to load any configured
+ initial ramdisc.
+
+ no-scroll [VGA]
+
+ nosmp [SMP] Tells an SMP kernel to act as a UP kernel.
+
+ optcd= [HW,CD]
+
+ panic=
+
+ parport= [HW,LP]
+
+ pas16= [HW,SCSI]
+
+ pcbit= [HW,ISDN]
+
+ pcd. [PARIDE]
+
+ pci= [PCI]
+
+ pd. [PARIDE]
+
+ pf. [PARIDE]
+
+ pg. [PARIDE]
+
+ pirq= [SMP,APIC]
+
+ plip= [LP,NET] Parallel port network link.
+
+ profile=
+
+ prompt_ramdisk= [RAM] Whether to prompt for ramdisk before loading
+ its contents into memory.
+
+ pt. [PARIDE]
+
+ ramdisk= [RAM]
+
+ ramdisk_size= [RAM]
+
+ ramdisk_start= [RAM]
+
+ reboot= [BUGS=ix86]
+
+ reserve=
+
+ riscom8= [HW,SERIAL]
+
+ ro [KNL] Mount root device read-only on boot.
+
+ root=
+
+ rw [KNL] Mount root device read-write on boot.
+
+ sbpcd= [HW,CD] Soundblaster CD adapter.
+
+ scsi_logging= [SCSI]
+
+ sjcd= [HW,CD]
+
+ sonycd535= [HW,CD]
+
+ sound= [SOUND]
+
+ soundmodem= [HW,AX25,SOUND] Sound cards used as AX.25 modems.
+
+ specialix= [HW,SERIAL] Specialix multi-serial port adapter.
+
+ st= [HW]
+
+ st0x= [HW,SCSI]
+
+ stram_swap= [HW]
+
+ sym53c416= [HW,SCSI]
+
+ sym53c8xx= [HW,SCSI]
+
+ t128= [HW,SCSI]
+
+ tmc8xx= [HW,SCSI]
+
+ tmscsim= [HW,SCSI]
+
+ tp720= [HW,PS2]
+
+ u14-34f= [HW,SCSI]
+
+ video= [FB]
+
+ wd33c93= [HW,SCSI]
+
+ wd7000= [HW,SCSI]
+
+ wdt= [HW]
+
+ xd= [HW,XT]
+
+ xd_geo= [HW,XT]
diff -u --recursive --new-file v2.2.9/linux/Documentation/networking/ethertap.txt linux/Documentation/networking/ethertap.txt
--- v2.2.9/linux/Documentation/networking/ethertap.txt Sun Jun 7 11:16:26 1998
+++ linux/Documentation/networking/ethertap.txt Mon Jun 7 16:13:07 1999
@@ -1,7 +1,7 @@
X Documentation on setup and use of EtherTap.
X
X Contact Jay Schulist <Jay.Sc...@spacs.k12.wi.us> if you
-have questions or need futher assistance.
+have questions or need further assistance.
X
X Introduction
X ============
@@ -49,11 +49,11 @@
X
X 1.2.3.4 will be the router to the outside world
X 1.2.3.5 our box
- 2.0.0.1 our box (appletalk side)
- 2.0.0.* a pile of macintoys
+ 2.0.0.1 our box (AppleTalk side)
+ 2.0.0.* a pile of Macintoys
X
X
-[1.2.3.4]-------------1.2.3.5[Our Box]2.0.0.1---------> macs
+[1.2.3.4]-------------1.2.3.5[Our Box]2.0.0.1---------> Macs
X
X The routing on our box would be
X
diff -u --recursive --new-file v2.2.9/linux/Documentation/networking/ltpc.txt linux/Documentation/networking/ltpc.txt
--- v2.2.9/linux/Documentation/networking/ltpc.txt Thu Nov 19 09:56:27 1998
+++ linux/Documentation/networking/ltpc.txt Mon Jun 7 16:13:07 1999
@@ -65,7 +65,7 @@
X
X Card Configuration:
X
-The interrupts and so forth are configured via the dipswitch on the
+The interrupts and so forth are configured via the DIP switch on the
X board. Set the switches so as not to conflict with other hardware.
X
X Interrupts -- set at most one. If none are set, the driver uses
diff -u --recursive --new-file v2.2.9/linux/Documentation/scsi-generic.txt linux/Documentation/scsi-generic.txt
--- v2.2.9/linux/Documentation/scsi-generic.txt Wed Apr 28 11:37:29 1999
+++ linux/Documentation/scsi-generic.txt Mon Jun 7 16:13:07 1999
@@ -1,34 +1,38 @@
- Notes on Linux's SG driver version 2.1.30
+ Notes on Linux's SG driver version 2.1.34
X -----------------------------------------
- 990328
+ 990606
X
X Introduction
X ============
+Sg is one of the four "high level" SCSI device drivers along with
+sd, st and sr (disk, tape and CDROM respectively). Sg is more generalized
+(but lower level) than its siblings and tends to be used on SCSI devices
+that don't fit into the already serviced categories. Thus sg is used for
+scanners, cd writers and reading audio cds digitally amongst other things.
+
X These are notes on the Linux SCSI generic packet device driver (sg)
-describing version 2.1.30 . The original driver was written by Lawrence
-Foard and has remained in place with minimal changes since circa 1992.
+describing version 2.1.34 . The original driver was written by Lawrence
+Foard and remained in place with minimal changes since circa 1992.
X Version 2 of this driver remains backward compatible (binary and
X source **) with the original. It adds scatter gather, command queuing,
X per file descriptor sequencing, asynchronous notification and better
X error reporting.
X
-Sg is one of the four "high level" SCSI device drivers along with
-sd, st and sr (disk, tape and CDROM respectively). Sg is more generalized
-(but lower level) than its sibling and tends to be used on SCSI devices
-that don't fit into the already serviced categories. Thus sg is used for
-scanners, cd writers and reading audio cds amongst other things.
+This is an abridged version of the sg documentation that is targeted
+at the linux/Documentation directory. The full document can be found
+at http://www.torque.net/sg/p/scsi-generic_long.txt .
X
-The interface and usage of the original sg driver has been documented
+The interface and usage of the original sg driver have been documented
X by Heiko Eissfeldt in a HOWTO called SCSI-Programming-HOWTO. My copy
X of the document is version 1.5 dated 7th May 1996. It can found at
-ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/SCSI-Programming-HOWTO .
-Amongst other things it has a lot of tables from the SCSI-2 standard
-that are very useful for programming this interface.
+ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO-SCSI-Programming-HOWTO .
+A copy of this document can be found at:
+http://www.torque.net/sg/p/original/HOWTO-SCSI-Programming-HOWTO .
X
X ** It is possible to write applications that perform differently
X depending on whether they are using the original or this version of
-the sg device driver. The author is not aware of any useful applications
-that have problems with version 2 (yet).
+the sg device driver. The author is not aware of any useful
+pre-existing applications that have problems with version 2 (yet).
X
X
X Architecture
@@ -38,9 +42,11 @@
X the others are sd (for direct-access devices - disks), st (for tapes)
X and sr (for data cdroms). The other three devices are block devices.
X
-The unifying layer of the SCSI sub-system in the so-called mid-level.
-Below that are all the drivers for the various adapters supported by
-Linux.
+The unifying layer of the SCSI sub-system is the so-called mid-level.
+Below that are the "low level" drivers which are the drivers for the
+various adapters supported by Linux. Also at this level are pseudo
+adapter drivers such as ide-scsi which converts the SCSI protocol to
+ATAPI (which are similar to one another) for use by IDE devices.
X
X Since sg is a character device it supports the traditional Unix
X system calls of open(), close(), read(), write() and ioctl(). Two other
@@ -85,8 +91,9 @@
X unsigned char sense_buffer[16];
X }; /* this structure is 36 bytes long */
X
-The 'pack_len' is bizzare and ends up having the 'reply_len' put in it
-(perhaps it had a use at some stage).
+The 'pack_len' is bizarre and ends up having the 'reply_len' put in it
+(perhaps it had a use at some stage). Even though it looks like an
+input variable, it is not read by sg internally (only written).
X
X The 'reply_len' is the length of the data the corresponding read()
X will/should request (including the sg_header).
@@ -95,14 +102,14 @@
X back to the corresponding read() so it can be used for sequencing by an
X application.
X
-The 'result' is also bizzare, turning certain types of host codes it 0 (no
+The 'result' is also bizarre, turning certain types of host codes to 0 (no
X error), EBUSY or EIO. With better error reporting now available, the
X 'result' is best ignored.
X
-The 'twelve_byte' field overrides the internal SCSI command length "guessing"
+The 'twelve_byte' field overrides the internal SCSI command length detection
X algorithm for group 6 and 7 commands (ie when 1st byte >= 0xc0) and forces
-a command lenth of 12 bytes.
-The command length "guessing" algorithm is as follows:
+a command length of 12 bytes.
+The command length detection algorithm is as follows:
X Group: 0 1 2 3 4 5 6 7
X Length: 6 10 10 12 12 12 10 10
X
@@ -115,6 +122,7 @@
X buffer should be at least 18 bytes long and arguably 32 bytes; unfortunately
X this is unlikely to happen in the 2.2.x series of kernels.
X
+
X The new sg_header offered in this driver is:
X #define SG_MAX_SENSE 16
X struct sg_header
@@ -122,15 +130,17 @@
X int pack_len; /* [o] reply_len (ie useless) ignored as input */
X int reply_len; /* [i] max length of expected reply (inc. sg_header) */
X int pack_id; /* [io] id number of packet (use ints >= 0) */
- int result; /* [o] 0==ok, else (+ve) Unix errno code (e.g. EIO) */
+ int result; /* [o] 0==ok, else (+ve) Unix errno (best ignored) */
X unsigned int twelve_byte:1;
X /* [i] Force 12 byte command length for group 6 & 7 commands */
X unsigned int target_status:5; /* [o] scsi status from target */
X unsigned int host_status:8; /* [o] host status (see "DID" codes) */
X unsigned int driver_status:8; /* [o] driver status+suggestion */
X unsigned int other_flags:10; /* unused */
- unsigned char sense_buffer[SG_MAX_SENSE]; /* [o] when target_status is
- CHECK_CONDITION or COMMAND_TERMINATED this is output. */
+ unsigned char sense_buffer[SG_MAX_SENSE]; /* [o] Output in 3 cases:
+ when target_status is CHECK_CONDITION or
+ when target_status is COMMAND_TERMINATED or
+ when (driver_status & DRIVER_SENSE) is true. */
X }; /* This structure is 36 bytes long on i386 */
X
X Firstly the new header is binary compatible with the original. This is
@@ -146,6 +156,9 @@
X the value of 'pack_id' available after a read() is the value given to that
X variable in the prior, corresponding write().
X
+The SCSI command length can now be given directly using the SG_NEXT_CMD_LEN
+ioctl().
+
X The 'target_status' field is always output and is the (masked and shifted
X 1 bit right) SCSI status code from the target device. The allowable
X values are (found in <scsi/scsi.h>):
@@ -162,28 +175,28 @@
X When the 'target_status' is CHECK_CONDITION or COMMAND_TERMINATED the
X 'sense_buffer' is output. Note that when (driver_status & DRIVER_SENSE)
X is true then the 'sense_buffer' is also output (this seems to occur when
-the scsi ide emulation is used). When the 'sense_buffer' is output the
+the ide-scsi emulation is used). When the 'sense_buffer' is output the
X SCSI Sense Key can be found at (sense_buffer[2] & 0x0f) .
X
X The 'host_status' field is always output and has the following values
-whose "defines" are not visible outside the kernel (unfortunately):
+whose "defines" are not visible outside the kernel. A copy of these
+defines can be found in sg_err.h (see the utilities section):
X #define DID_OK 0x00 /* NO error */
X #define DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */
X #define DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */
X #define DID_TIME_OUT 0x03 /* TIMED OUT for other reason */
-#define DID_BAD_TARGET 0x04 /* BAD target. */
+#define DID_BAD_TARGET 0x04 /* BAD target, device not responding? */
X #define DID_ABORT 0x05 /* Told to abort for some other reason */
X #define DID_PARITY 0x06 /* Parity error */
-#define DID_ERROR 0x07 /* Internal error */
+#define DID_ERROR 0x07 /* Internal error [DMA underrun on aic7xxx]*/
X #define DID_RESET 0x08 /* Reset by somebody. */
X #define DID_BAD_INTR 0x09 /* Got an interrupt we weren't expecting. */
X #define DID_PASSTHROUGH 0x0a /* Force command past mid-layer */
-#define DID_SOFT_ERROR 0x0b /* The low level driver just wish a retry */
+#define DID_SOFT_ERROR 0x0b /* The low level driver wants a retry */
X
X The 'driver_status' field is always output. When ('driver_status' &
-DRIVER_SENSE) is true the 'sense_buffer' is also output. The following
-values whose "defines" are not visible outside the kernel (unfortunately)
-can occur:
+DRIVER_SENSE) is true the 'sense_buffer' is also output. A copy of these
+defines can be found in sg_err.h (see the utilities section):
X #define DRIVER_OK 0x00 /* Typically no suggestion */
X #define DRIVER_BUSY 0x01
X #define DRIVER_SOFT 0x02
@@ -192,7 +205,7 @@
X #define DRIVER_INVALID 0x05
X #define DRIVER_TIMEOUT 0x06
X #define DRIVER_HARD 0x07
-#define DRIVER_SENSE 0x08
+#define DRIVER_SENSE 0x08 /* Implies sense_buffer output */
X /* above status 'or'ed with one of the following suggestions */
X #define SUGGEST_RETRY 0x10
X #define SUGGEST_ABORT 0x20
@@ -200,55 +213,8 @@
X #define SUGGEST_DIE 0x40
X #define SUGGEST_SENSE 0x80
X
-'other_flags' still remains as a 10 bit field, so code that places 0 in it
-will still be happy. It is not used.
-
-
-memory
-======
-Memory is a scarce resource in any computer. Sg needs to reserve memory
-suitable for DMA roughly equal in size to the maximum of the write and
-read data buffers for each packet. This DMA memory is obtained at the time
-of a write() and released when the corresponding read() is called (although
-if memory is tight it may be using the buffer reserved by the open() ).
-
-Linux obtaining memory a challenge for several reasons. The memory pool
-that sg uses is in common with all other device drivers and all user
-processes. In this environment the only way to 99.9% guarantee a driver
-will have memory in Linux is to build it into the kernel (ie not as a
-module) and then reserve it on initialization before user processes get
-a chance. [Of course, another driver initialized before sg could take
-all available memory ...] Another problem is the biggest contiguous
-chunk of memory that can be obtained from the kernel is 32 * PAGE_SIZE
-(which is 128KBytes on i386). As memory gets "splintered" there is a good
-chance that buffers won't be available (my machine has 64 MBytes of RAM
-and has 3 available at the moment).
-
-The original sg driver used the following technique: grab a SG_BIG_BUFF
-sized buffer at driver initialization and use it for all requests greater
-than PAGE_SIZE (4096 bytes on i386). By default SG_BIG_BUFF is set to
-32 KBytes in the origianl driver but many applications suggest that the
-user increases this number. Linux limits the biggest single buffer of
-this type to 32 * PAGE_SIZE (128KBytes on i386). Unfortunately if the
-sg driver is a module then there is a high chance a contiguous block of
-that large size will not be available at module initialization.
-
-The author has found no "silver bullet" solution but uses multiple
-techniques hoping that at least one is able provide memory at the critical
-time. Listed below are some of these techniques:
- - use scatter gather: then instead of one large buffer needing to
- be found, multiple smaller buffer can be used
- - use memory above the 16MByte level: the original driver limited
- itself to obtaining memory below the 16MByte level (on the i386)
- due to the shortcomings of DMA on ISA adapters. Yet more and more
- people use PCI adapters that don't have this problem. So make
- the decision based on the capabilities of the host adpater
- associated with the current SCSI device
- - reserve some memory at open() for emergencies but otherwise
- fetch and release it on a per packet basis
- - if the kernel is short of memory then dip into the SCSI DMA
- pool (maintained by the mid-level driver) to a limited amount
-
+'other_flags' still remains as a 10 bit field (reduced from 31 bits), so
+code that places 0 in it will still be happy. It is not used.
X
X
X System Calls
@@ -257,16 +223,16 @@
X Unix operating system calls when applied to a SCSI generic device
X using this version of the device driver.
X
-open
-----
+open(const char * filename, int flags)
+--------------------------------------
X The filename should be an 'sg' device such as
X /dev/sg[a-z]
X /dev/sg[0,1,2,...]
X or a symbolic link to one of these. [Devfs has its own sub-directory for
-sg devices.] It seems as though SCSI devices are allocated to sg minor
-numbers in the same order as they appear in 'cat /proc/scsi/scsi'.
-Sg is a "character" based Linux device driver. This means it has an
-open/close/read/write/ioctl type interface.
+sg devices with entries like: /dev/sg/c1b2t3u4 .] It seems as though SCSI
+devices are allocated to sg minor numbers in the same order as they appear
+in 'cat /proc/scsi/scsi'. Sg is a "character" based Linux device driver.
+This means it has an open/close/read/write/ioctl type interface.
X
X Flags can be either O_RDONLY or O_RDWR or-ed with either
X O_EXCL waits for other opens on sg device to be closed before
@@ -279,7 +245,7 @@
X The original version of sg did not allow the O_RDONLY (yielding a EACCES
X error). This version allows it for accessing ioctls (e.g. doing an sg
X device scan with the SG_GET_SCSI_ID ioctl) but write()s will not be
-allowed.
+allowed. These flags are found in <fcntl.h> .
X
X By default, sequencing is per file descriptor in this version of sg. This
X means, for example that 2 processes can independently manipulate the same
@@ -290,32 +256,38 @@
X previous version of sg supported only per device sequencing and this can
X still be selected with the SG_SET_MERGE_FD,1 ioctl().
X
-The driver will attempt to reserve SG_SCATTER_SZ bytes (32KBytes in the
-current sg.h) on open() for "emergency" situations. If this is unavailable
-it will halve its request and try again. It gives up if PAGE_SIZE bytes
-(4096 bytes on i386) cannot be obtained so no memory is reserved. In this
-case open() will still return successfully. The actual amount of memory
-reserved can be found with the SG_GET_RESERVED_SIZE ioctl().
+The driver will attempt to reserve SG_DEF_RESERVED_SIZE bytes (32KBytes in
+the current sg.h) on open(). The size of this reserved buffer can
+subsequently be modified with the SG_SET_RESERVED_SIZE ioctl(). In both
+cases these are requests subject to various dynamic constraints. The actual
+amount of memory obtained can be found by the SG_GET_RESERVED_SIZE ioctl().
+The reserved buffer will be used if:
+ - it is not already in use (eg when command queuing is in use)
+ - a write() does not call for a buffer size larger than the
+ reserved size.
X
X Returns a file descriptor if >= 0 , otherwise -1 implies an error.
X
X Error codes (value in 'errno' after -1 returned):
-ENODEV sg not compiled into kernel or the kernel cannot find the
- sg module (or it can't initialize itself (low memory??))
-ENXIO either scsi sub-system is currently processing some error
- (eg doing a device reset) or the sg driver/module removed
- or corrupted
+EACCES Either the user doesn't have appropriate permissions on
+ 'filename' or attempted to use both O_RDONLY and O_EXCL
X EBUSY O_NONBLOCK set and some user of this sg device has O_EXCL
X set while someone is already using this device
X EINTR while waiting for an "exclusive" lock to clear, a signal
X is received, just try again ...
+ENODEV sg not compiled into kernel or the kernel cannot find the
+ sg module (or it can't initialize itself (low memory??))
+ENOENT given filename not found
X ENOMEM An attempt to get memory to store this open's context
X failed (this was _not_ a request to reserve DMA memory)
-EACCES An attempt to use both O_RDONLY and O_EXCL
+ENXIO either there is no attached device corresponding to given
+ filename or scsi sub-system is currently processing some
+ error (eg doing a device reset) or the sg driver/module
+ removed or corrupted
X
X
-write
------
+write(int sg_fd, const void * buffer, size_t count)
+---------------------------------------------------
X Even though sg is a character-based device driver it sends and receives
X packets to/from the associated scsi device. Write() is used to send a
X packet containing 2 mandatory parts and 1 optional part. The mandatory
@@ -343,32 +315,33 @@
X Returns number of bytes written if > 0 , otherwise -1 implies an error.
X
X Error codes (value in 'errno' after -1 returned):
-ENXIO either scsi sub-system is currently processing some error
- (eg doing a device reset) or the sg driver/module removed
- or corrupted
X EACCES opened with RD_ONLY flag
-EIO incoming buffer too short. It should be at least (6 +
- sizeof(struct sg_header))==42 bytes long
-EDOM a) command queuing off: a packet is already queued
- b) command queuing on: too many packets queued
- (SG_MAX_QUEUE exceeded)
X EAGAIN SCSI mid-level out of command blocks (rare), try again.
X This is more likely to happen when queuing commands,
X so wait a bit (eg usleep(10000) ) before trying again
+EDOM a) command queuing off: a packet is already queued
+ b) command queuing on: too many packets queued
+ (SG_MAX_QUEUE exceeded)
+ c) SCSI command length given in SG_NEXT_CMD_LEN too long
+EFAULT 'buffer' for 'count' bytes is an invalid memory range
+EIO incoming buffer too short. It should be at least (6 +
+ sizeof(struct sg_header))==42 bytes long
X ENOMEM can't get memory for DMA. Take evasive action ...
- (see section on memory)
+ENXIO either scsi sub-system is currently processing some error
+ (eg doing a device reset) or the sg driver/module removed
+ or corrupted
X
X
-read
-----
+read(int sg_fd, void * buffer, size_t count)
+--------------------------------------------
X Read() is used to receive a packet containing 1 mandatory part and 1
X optional part. The mandatory part is:
X - a control block (an instance of struct sg_header)
X The optional part is:
X - incoming data (eg if a SCSI read command was sent by earlier write() )
X The buffer given to a read() and its corresponding count should be
-sufficient to accommodate this packet to avoid truncation. Truncation has
-occurred if count < sg_header::replylen .
+sufficient to accommodate this packet to avoid truncation. Truncation occurs
+if count < sg_header::replylen .
X
X By default, read() will return the oldest packet queued up. If the
X SG_SET_FORCE_PACK_ID,1 ioctl() is active then read() will attempt to
@@ -377,7 +350,6 @@
X wait or yield EAGAIN. As a special case, -1 in sg_header::pack_id given
X to read() will match the oldest packet.
X
-
X Returns number of bytes read if > 0 , otherwise -1 implies an error.
X Unfortunately the return value in the non-error case is simply the
X same as the count argument. It is not the actual number of bytes
@@ -385,25 +357,26 @@
X such an underrun indication.
X
X Error codes (value in 'errno' after -1 returned):
-ENXIO either scsi sub-system is currently processing some error
- (eg doing a device reset) or the sg driver/module removed
- or corrupted
X EAGAIN either no waiting packet or requested packet is not
X available while O_NONBLOCK flag was set
+EFAULT 'buffer' for 'count' bytes is an invalid memory range
X EINTR while waiting for a packet, a signal is received, just
X try again ...
X EIO if the 'count' given to read() is < sizeof(struct sg_header)
X and the 'result' element in sg_header is non-zero. Not a
X recommended error reporting technique
+ENXIO either scsi sub-system is currently processing some error
+ (eg doing a device reset) or the sg driver/module removed
+ or corrupted
X
X
-close
------
+close(int sg_fd)
+----------------
X Preferably a close() should be done after all issued write()s have had
X their corresponding read() calls completed. Unfortunately this is not
X always possible. The semantics of close() in Unix are to return more
X or less immediately (ie not wait on any event) so the driver needs to
-arrange to an orderly cleanup of those packets that are still "in
+arrange for an orderly cleanup of those packets that are still "in
X flight".
X
X A process that has an open file descriptor to an sg device may be aborted
@@ -411,22 +384,22 @@
X (which is called 'sg_release()' in the version 2 driver) to facilitate
X the cleanup mentioned above.
X
-A problem persists in version 2.1.8 if the sg driver is a module and is
-removed while packets are still "in flight". Hopefully this will be soon
-fixed.
+A problem persists in version 2.1.34 if the sg driver is a module and is
+removed while packets are still "in flight".
X
X Returns 0 if successful, otherwise -1 implies an error.
X
X Error codes (value in 'errno' after -1 returned):
X ENXIO sg driver/module removed or corrupted
X
-ioctl (sg specific)
--------------------
+ioctl(int sg_fd, int command, ...) [sg specific]
+-------------------------------------------------
X Ken Thompson (or perhaps some other Unix luminary) described ioctl() as
X the "garbage bin of Unix". This driver compounds the situation by adding
-around 18 more commands. These commands either yield state information (10
-of them), change the driver's characteristics (8 of them) or allow direct
-communication with the common SCSI mid-level driver.
+more ...
+If a ioctl command is not recognized by sg (and the various lower levels
+that it may pass the command on to) then the error EINVAL occurs. If an
+invalid address is given (in the 3rd argument) then the error EFAULT occurs.
X
X Those commands with an appended "+" are new in version 2.
X
@@ -442,15 +415,38 @@
X SG_SET_TIMEOUT:
X Assumes 3rd argument points to an int containing the new timeout value
X for this file descriptor. The unit is a "jiffy". Packets that are
-already "in flight" will not be effected. The default value is set
-on open() and is SG_DEFAULT_TIMEOUT (defined in sg.h).
+already "in flight" will not be affected. The default value is set
+on open() and is SG_DEFAULT_TIMEOUT (defined in sg.h). This default is
+currently 1 minute and may not be long enough for formats.
X
X SG_EMULATED_HOST:
X Assumes 3rd argument points to an int and outputs a flag indicating
-whether the host (adapter) is connected to a real SCSI bus or is
+whether the host (adapter) is connected to a real SCSI bus or is an
X emulated one (eg ide-scsi device driver). A value of 1 means emulated
X while 0 is not.
X
+SG_SET_TRANSFORM W:
+Third argument is ignored. Only is meaningful when SG_EMULATED host has
+yielded 1 (ie the low-level is the ide-scsi device driver); otherwise
+an EINVAL error occurs. The default state is to _not_ transform SCSI
+commands to the corresponding ATAPI commands but pass them straight
+through as is. [Only certain classes of SCSI commands need to be
+transformed to their ATAPI equivalents.] Making this ioctl command causes
+transforms to occur thereafter. Subsequent calls to this ioctl command
+have no additional effect. Beware, this state will affect all devices
+(and hence all related sg file descriptors) associated with this ide-scsi
+"bus".
+The author of ide-scsi has pointed out that this is not the intended
+behaviour which is a 3rd argument of 0 to disable transforms and 1 to
+enable transforms. Note the 3rd argument is an 'int' not a 'int *'.
+Perhaps the intended behaviour will be implemented soon.
+
+SG_GET_TRANSFORM:
+Third argument is ignored. Only is meaningful when SG_EMULATED host has
+yielded 1 (ie the low-level is the ide-scsi device driver); otherwise
+an EINVAL error occurs. Returns 0 to indicate _not_ transforming SCSI
+to ATAPI commands (default). Returns 1 when it is transforming.
+
X SG_SET_FORCE_LOW_DMA +:
X Assumes 3rd argument points to an int containing 0 or 1. 0 (default)
X means sg decides whether to use memory above 16 Mbyte level (on i386)
@@ -459,10 +455,10 @@
X space.
X If 1 is given then the host adapter is overridden and only memory below
X the 16MB level is used for DMA. A requirement for this should be
-extremely rare. If the "reserve" buffer allocated on open() is not in
+extremely rare. If the "reserved" buffer allocated on open() is not in
X use then it will be de-allocated and re-allocated under the 16MB level
X (and the latter operation could fail yielding ENOMEM).
-Only the current file descriptor is effected.
+Only the current file descriptor is affected.
X
X SG_GET_LOW_DMA +:
X Assumes 3rd argument points to an int and places 0 or 1 in it. 0
@@ -472,11 +468,11 @@
X adapters setting has been overridden by SG_SET_FORCE_LOW_DMA,1 .
X
X SG_GET_SCSI_ID +:
-Assumes 3rd argument is pointing to an object of type Sg_scsi_id and
-populates it. That structure contains ints for host_no, channel,
-scsi_id, lun and scsi_type. Most of this information is available from
-other sources (eg SCSI_IOCTL_GET_IDLUN and SCSI_IOCTL_GET_BUS_NUMBER)
-but tends to be awkward to collect.
+Assumes 3rd argument is pointing to an object of type Sg_scsi_id (see
+sg.h) and populates it. That structure contains ints for host_no,
+channel, scsi_id, lun and scsi_type. Most of this information is
+available from other sources (eg SCSI_IOCTL_GET_IDLUN and
+SCSI_IOCTL_GET_BUS_NUMBER) but tends to be awkward to collect.
X
X SG_SET_FORCE_PACK_ID +:
X Assumes 3rd argument is pointing to an int. 0 (default) instructs read()
@@ -486,9 +482,9 @@
X oldest packet matching that pack_id or wait until it arrives (or yield
X EAGAIN if O_NONBLOCK is in force). As a special case the pack_id of -1
X given to read() in the mode will match the oldest packet.
-Only the current file descriptor is effected by this command.
+Only the current file descriptor is affected by this command.
X
-SG_GET_LOW_DMA +:
+SG_GET_PACK_ID +:
X Assumes 3rd argument points to an int and places the pack_id of the
X oldest (written) packet in it. If no packet is waiting to be read then
X yields -1.
@@ -503,30 +499,33 @@
X the adapter does support scatter gather.
X
X SG_SET_RESERVED_SIZE +W:
-This is not currently implemented. It is intended for reserving either a
-large buffer or scatter gather list that will be available until the
-current file descriptor is closed. The requested amount of memory may
-not be available so SG_GET_RESERVED_SIZE should be used after this call
-to see how much was reserved. (EBUSY error possible)
+Assumes 3rd argument is pointing to an int. That value will be used to
+request a new reserved buffer of that size. The previous reserved buffer
+is freed (if it is not in use; if it was in use -EBUSY is returned).
+A new reserved buffer is then allocated and its actual size can be found by
+calling the SG_GET_RESERVED_SIZE ioctl(). The reserved buffer is then used
+for DMA purposes by subsequent write() commands if it is not already in
+use and if the write() is not calling for a buffer size larger than that
+reserved. The reserved buffer may well be a series of kernel buffers if the
+adapter supports scatter-gather. Large buffers can be requested (eg 1 MB).
X
X SG_GET_RESERVED_SIZE +:
X Assumes 3rd argument points to an int and places the size in bytes of
-the DMA buffer reserved on open() for emergencies. If this is 0 then it
-is probably not wise to attempt on operation like burning a CD on this
-file descriptor.
+the reserved buffer from open() or the most recent SG_SET_RESERVED_SIZE
+ioctl() call on this fd. The result can be 0 if memory is very tight. In
+this case it may not be wise to attempt something like burning a CD on
+this file descriptor.
X
X SG_SET_MERGE_FD +W:
X Assumes 3rd argument is pointing to an int. 0 (the default) causes all
X subsequent sequencing to be per file descriptor. 1 causes all subsequent
X sequencing to be per device. If this command tries to change the current
-state and the is one or more _other_ file descriptors using this sg
-device then an EBUSY error occurs. Also if this file descriptor was not
-open()ed with the O_RDWR flag then an EACCES error occurs.
-Per device sequencing was the original semantics and allowed, for example
-different processes to "share" the device, one perhaps write()ing with
-the other one read()ing. This command is supplied if anyone needs those
-semantics. Per file descriptor sequencing, perhaps with the usage of
-the O_EXCL flag, seems more sensible.
+state and there is one or more _other_ file descriptors using this sg
+device then an EBUSY error occurs. Per device sequencing was the original
+semantics and allowed, for example different processes to "share" the
+device, one perhaps write()ing with the other one read()ing. This command
+is supplied if anyone needs those semantics. Per file descriptor
+sequencing, perhaps with the use of the O_EXCL flag, seems more sensible.
X
X SG_GET_MERGE_FD +:
X Assumes 3rd argument points to an int and places 0 or 1 in it. 0 implies
@@ -538,14 +537,42 @@
X SG_DEF_COMMAND_Q in sg.h) disables command queuing. Attempts to write()
X a packet while one is already queued will result in a EDOM error.
X 1 turns command queuing on.
-Changing the queuing state only effects write()s done after the change.
-Only the current file descriptor is effected by this command.
+Changing the queuing state only affects write()s done after the change.
+Only the current file descriptor is affected by this command.
X
X SG_GET_COMMAND_Q +:
X Assumes 3rd argument points to an int and places 0 or 1 in it. 0 implies
X that command queuing is off on this file descriptor. 1 implies command
X queuing is on.
X
+SG_SET_UNDERRUN_FLAG +:
+Assumes 3rd argument is pointing to an int. 0 (current default, set by
+SG_DEF_UNDERRUN_FLAG in sg.h) requests underruns be ignored. 1 requests
+that underruns be flagged. [The only low level driver that acts on this
+at the moment is the aic7xxx which yields a DID_ERROR error on underrun.]
+Only the current file descriptor is affected by this command (unless
+"per device" sequencing has been selected).
+
+SG_GET_UNDERRUN_FLAG +:
+Assumes 3rd argument points to an int and places 0 or 1 in it. 0 implies
+that underruns are not being reported. 1 implies that underruns are being
+reported (see SG_SET_UNDERRUN_FLAG for more details).
+
+SG_NEXT_CMD_LEN +:
+Assumes 3rd argument is pointing to an int. The value of the int (if > 0)
+will be used as the SCSI command length of the next SCSI command sent to
+a write() on this fd. After that write() the SCSI command length logic is
+reset to use automatic length detection (ie depending on SCSI command group
+and the 'twelve_byte' field). If the current SCSI command length maximum of
+12 is exceeded then the affected write() will yield an EDOM error.
+Giving this ioctl() a value of 0 will set automatic length detection for
+the next write(). N.B. Only the following write() on this fd is affected by
+this ioctl().
+
+SG_GET_VERSION_NUM +:
+Assumes 3rd argument points to an int. The version number is then placed
+in that int. A sg version such as 2.1.34 will yield "20134" from this ioctl.
+
X SG_SET_DEBUG +:
X Assumes 3rd argument is pointing to an int. 0 (default) turns debugging
X off. Values > 0 cause the SCSI sense buffer to be decoded and output
@@ -556,73 +583,53 @@
X the mid-level) then try 'echo "scsi dump 0" > /proc/scsi/scsi' and lots of
X debug will appear in your console/log.
X
-ioctl (in common with sd, st + sr)
-----------------------------------
-The following ioctl()s can be called from any high-level scsi device
-driver (ie sd, st, sr + sg). Access permissions may differ a bit from
-one device to another, the access information given below is specific to
-the sg device driver.
-
-SCSI_IOCTL_GET_IDLUN:
-SCSI_IOCTL_GET_BUS_NUMBER:
-
-SCSI_IOCTL_SEND_COMMAND: W
-If open()ed O_RDONLY yields an EACCESS error. Otherwise is forwarded onto
-the SCSI mid-level driver for processing.
-Don't know much about this one but it looks pretty powerful and
-dangerous. Some comments says it is also deprecated.
-
-<any_command_not matching_above>: W
-If open()ed O_RDONLY yields an EACCESS error. Otherwise is forwarded onto
-the SCSI mid-level driver for processing.
-
X
-poll
-----
+poll(struct pollfd * udfds, unsigned int nfds, int timeout_ms)
+--------------------------------------------------------------
X This is a native call in Linux 2.2 but most of its capabilities are available
X through the older select() call. Given a choice poll() should probably be
X used. Typically poll() is used when a sg scsi device is open()ed O_NONBLOCK
-for polling; or alternatively with asynchronous notification using the
-fcntl() system call (below) and the SIGPOLL (aka SIGIO) signal.
+for polling; and optionally with asynchronous notification as well using
+the fcntl() system call (below) and the SIGPOLL (aka SIGIO) signal.
X Only if something drastically is wrong (eg file handle gone stale) will
X POLLERR ever be set. POLLPRI, POLLHUP and POLLNVAL are never set.
X POLLIN is set when there is one or more packets waiting to be read.
-When POLLIN is set it implies that a read() will not block (or yield
+When POLLIN is set it implies that a read() will not block (nor yield
X EAGAIN in non-blocking mode) but return a packet immediately.
X POLLOUT (aka POLLWRNORM) is set when write() is able to accept a packet
-(ie will _not_ yield an EDOM error). The setting of POLLOUT is effected
+(ie will _not_ yield an EDOM error). The setting of POLLOUT is affected
X by the SG_SET_COMMAND_Q state: if the state is on then POLLOUT will remain
X set until the number of queued packets reaches SG_MAX_QUEUE, if the
X state is off then POLLOUT is only set when no packets are queued.


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

echo 'End of part 01'
echo 'File patch-2.2.10 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.2/patch-2.2.10/part07

#!/bin/sh
# this is part 07 of a 22 - part archive


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

# file patch-2.2.10 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 07; 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.2.10'
else
echo 'x - continuing with patch-2.2.10'

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

X #define IO_EXTENT 8
X
-/* static unsigned int io[] = { 0x3e8, ~0, ~0, ~0 }; */
-/* static unsigned int irq[] = { 11, 0, 0, 0 }; */
+/*
+ * Currently you'll need to set these values using insmod like this:
+ * insmod irport io=0x3e8 irq=11
+ */
+static unsigned int io[] = { ~0, ~0, ~0, ~0 };
+static unsigned int irq[] = { 0, 0, 0, 0 };
+
+static unsigned int qos_mtt_bits = 0x03;
+
+static struct irda_device *dev_self[] = { NULL, NULL, NULL, NULL};
+static char *driver_name = "irport";
+
+static int irport_open(int i, unsigned int iobase, unsigned int irq);
+static int irport_close(struct irda_device *idev);
X
X static void irport_write_wakeup(struct irda_device *idev);
X static int irport_write(int iobase, int fifo_size, __u8 *buf, int len);
X static void irport_receive(struct irda_device *idev);
X
+static int irport_net_init(struct device *dev);
+static int irport_net_open(struct device *dev);
+static int irport_net_close(struct device *dev);
+static int irport_is_receiving(struct irda_device *idev);
+static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts);
+static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len);
+
X __initfunc(int irport_init(void))
X {
-/* int i; */
+ int i;
X
-/* for ( i=0; (io[i] < 2000) && (i < 4); i++) { */
-/* int ioaddr = io[i]; */
-/* if (check_region(ioaddr, IO_EXTENT)) */
-/* continue; */
-/* if (irport_open( i, io[i], io2[i], irq[i], dma[i]) == 0) */
-/* return 0; */
-/* } */
-/* return -ENODEV; */
- return 0;
+ for (i=0; (io[i] < 2000) && (i < 4); i++) {
+ int ioaddr = io[i];
+ if (check_region(ioaddr, IO_EXTENT))
+ continue;
+ if (irport_open(i, io[i], irq[i]) == 0)
+ return 0;
+ }
+ /*
+ * Maybe something failed, but we can still be usable for FIR drivers
+ */
+ return 0;
X }
X
X /*
- * Function pc87108_cleanup ()
+ * Function irport_cleanup ()
X *
- * Close all configured chips
+ * Close all configured ports
X *
X */
X #ifdef MODULE
X static void irport_cleanup(void)
X {
-/* int i; */
+ int i;
X
X DEBUG( 4, __FUNCTION__ "()\n");
X
- /* for ( i=0; i < 4; i++) { */
-/* if ( dev_self[i]) */
-/* irport_close( &(dev_self[i]->idev)); */
-/* } */
+ for (i=0; i < 4; i++) {
+ if (dev_self[i])
+ irport_close(dev_self[i]);
+ }
X }
X #endif /* MODULE */
X
-/*
- * Function irport_open (void)
- *
- * Start IO port
- *
- */
-int irport_open(int iobase)
+static int irport_open(int i, unsigned int iobase, unsigned int irq)
X {
- DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase);
+ struct irda_device *idev;
+ int ret;
+
+ DEBUG( 0, __FUNCTION__ "()\n");
+
+/* if (irport_probe(iobase, irq) == -1) */
+/* return -1; */
+
+ /*
+ * Allocate new instance of the driver
+ */
+ idev = kmalloc(sizeof(struct irda_device), GFP_KERNEL);
+ if (idev == NULL) {
+ printk( KERN_ERR "IrDA: Can't allocate memory for "
+ "IrDA control block!\n");
+ return -ENOMEM;
+ }
+ memset(idev, 0, sizeof(struct irda_device));
+
+ /* Need to store self somewhere */
+ dev_self[i] = idev;
+
+ /* Initialize IO */
+ idev->io.iobase2 = iobase;
+ idev->io.irq2 = irq;
+ idev->io.io_ext = IO_EXTENT;
+ idev->io.fifo_size = 16;
+
+ idev->netdev.base_addr = iobase;
+ idev->netdev.irq = irq;
+
+ /* Lock the port that we need */
+ ret = check_region(idev->io.iobase2, idev->io.io_ext);
+ if (ret < 0) {
+ DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
+ idev->io.iobase2);
+ /* irport_cleanup(self->idev); */
+ return -ENODEV;
+ }
+ request_region(idev->io.iobase2, idev->io.io_ext, idev->name);
+
+ /* Initialize QoS for this device */
+ irda_init_max_qos_capabilies(&idev->qos);
+
+ idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
+ IR_115200;
+
+ idev->qos.min_turn_time.bits = qos_mtt_bits;
+ irda_qos_bits_to_value(&idev->qos);
+
+ idev->flags = IFF_SIR|IFF_PIO;
+
+ /* Specify which buffer allocation policy we need */
+ idev->rx_buff.flags = GFP_KERNEL;
+ idev->tx_buff.flags = GFP_KERNEL;
+
+ idev->rx_buff.truesize = 4000;
+ idev->tx_buff.truesize = 4000;
+
+ /* Initialize callbacks */
+ idev->change_speed = irport_change_speed;
+ idev->wait_until_sent = irport_wait_until_sent;
+ idev->is_receiving = irport_is_receiving;
+ idev->set_dtr_rts = irport_set_dtr_rts;
+ idev->raw_write = irport_raw_write;
+
+ /* Override the network functions we need to use */
+ idev->netdev.init = irport_net_init;
+ idev->netdev.hard_start_xmit = irport_hard_xmit;
+ idev->netdev.open = irport_net_open;
+ idev->netdev.stop = irport_net_close;
+
+ /* Open the IrDA device */
+ irda_device_open(idev, driver_name, NULL);
+
+ return 0;
+}
+
+static int irport_close(struct irda_device *idev)
+{
+ ASSERT(idev != NULL, return -1;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+
+ /* Release the IO-port that this driver is using */
+ DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n",
+ idev->io.iobase2);
+ release_region(idev->io.iobase2, idev->io.io_ext);
+
+ irda_device_close(idev);
+
+ kfree(idev);
+
+ return 0;
+}
+
+void irport_start(struct irda_device *idev, int iobase)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&idev->lock, flags);
+
+ irport_stop(idev, iobase);
X
X /* Initialize UART */
X outb(UART_LCR_WLEN8, iobase+UART_LCR); /* Reset DLAB */
X outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR);
X
X /* Turn on interrups */
- outb((UART_IER_RLSI | UART_IER_RDI), iobase+UART_IER);
+ outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, iobase+UART_IER);
X
- return 0;
+ spin_unlock_irqrestore(&idev->lock, flags);
X }
X
-/*
- * Function irport_cleanup ()
- *
- * Stop IO port
- *
- */
-void irport_close(int iobase)
+void irport_stop(struct irda_device *idev, int iobase)
X {
- DEBUG(4, __FUNCTION__ "()\n");
+ unsigned long flags;
+
+ spin_lock_irqsave(&idev->lock, flags);
X
X /* Reset UART */
X outb(0, iobase+UART_MCR);
-
+
X /* Turn off interrupts */
X outb(0, iobase+UART_IER);
+
+ spin_unlock_irqrestore(&idev->lock, flags);
+}
+
+/*
+ * Function irport_probe (void)
+ *
+ * Start IO port
+ *
+ */
+int irport_probe(int iobase)
+{
+ DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase);
+
+ return 0;
X }
X
X /*
X * Function irport_change_speed (idev, speed)
X *
- * Set speed of port to specified baudrate
+ * Set speed of IrDA port to specified baudrate
X *
X */
-void irport_change_speed( int iobase, int speed)
+void irport_change_speed(struct irda_device *idev, int speed)
X {
+ unsigned long flags;
+ int iobase;
X int fcr; /* FIFO control reg */
X int lcr; /* Line control reg */
X int divisor;
X
- DEBUG( 0, __FUNCTION__ "(), Setting speed to: %d\n", speed);
+ DEBUG(0, __FUNCTION__ "(), Setting speed to: %d\n", speed);
+
+ ASSERT(idev != NULL, return;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+ iobase = idev->io.iobase2;
+
+ /* Update accounting for new speed */
+ idev->io.baudrate = speed;
+
+ spin_lock_irqsave(&idev->lock, flags);
X
X /* Turn off interrupts */
X outb(0, iobase+UART_IER);
X
X divisor = SPEED_MAX/speed;
X
- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14;
+ fcr = UART_FCR_ENABLE_FIFO;
+
+ /*
+ * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
+ * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
+ * about this timeout since it will always be fast enough.
+ */
+ if (idev->io.baudrate < 38400)
+ fcr |= UART_FCR_TRIGGER_1;
+ else
+ fcr |= UART_FCR_TRIGGER_14;
X
X /* IrDA ports use 8N1 */
X lcr = UART_LCR_WLEN8;
@@ -173,8 +318,10 @@
X outb(lcr, iobase+UART_LCR); /* Set 8N1 */
X outb(fcr, iobase+UART_FCR); /* Enable FIFO's */
X
- /* Turn on receive interrups */
- outb(UART_IER_RLSI|UART_IER_RDI, iobase+UART_IER);
+ /* Turn on interrups */
+ outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, iobase+UART_IER);
+
+ spin_unlock_irqrestore(&idev->lock, flags);
X }
X
X /*
@@ -188,10 +335,13 @@
X {
X int actual = 0;
X int iobase;
+ int fcr;
X
X ASSERT(idev != NULL, return;);
X ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
X
+ DEBUG(4, __FUNCTION__ "()\n");
+
X /* Finished with frame? */
X if (idev->tx_buff.len > 0) {
X /* Write data left in transmit buffer */
@@ -211,9 +361,18 @@
X /* Schedule network layer, so we can get some more frames */
X mark_bh(NET_BH);
X
- outb(UART_FCR_ENABLE_FIFO |
- UART_FCR_TRIGGER_14 |
- UART_FCR_CLEAR_RCVR, iobase+UART_FCR); /* Enable FIFO's */
+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR;
+
+ if (idev->io.baudrate < 38400)
+ fcr |= UART_FCR_TRIGGER_1;
+ else
+ fcr |= UART_FCR_TRIGGER_14;
+
+ /*
+ * Reset Rx FIFO to make sure that all reflected transmit data
+ * will be discarded
+ */
+ outb(fcr, iobase+UART_FCR);
X
X /* Turn on receive interrupts */
X outb(UART_IER_RLSI|UART_IER_RDI, iobase+UART_IER);
@@ -223,7 +382,7 @@
X /*
X * Function irport_write (driver)
X *
- *
+ * Fill Tx FIFO with transmit data
X *
X */
X static int irport_write(int iobase, int fifo_size, __u8 *buf, int len)
@@ -232,21 +391,18 @@
X
X /* Tx FIFO should be empty! */
X if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
- DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n");
+ DEBUG(0, __FUNCTION__ "(), failed, fifo not empty!\n");
X return -1;
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+UART_TX);
+ outb(buf[actual], iobase+UART_TX);
X
X actual++;
X }
X
- DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n",
- fifo_size, actual, len);
-
X return actual;
X }
X
@@ -260,11 +416,10 @@
X int irport_hard_xmit(struct sk_buff *skb, struct device *dev)
X {
X struct irda_device *idev;
+ unsigned long flags;
X int actual = 0;
X int iobase;
X
- DEBUG(5, __FUNCTION__ "(), dev=%p\n", dev);
-
X ASSERT(dev != NULL, return 0;);
X
X idev = (struct irda_device *) dev->priv;
@@ -275,8 +430,19 @@
X iobase = idev->io.iobase2;
X
X /* Lock transmit buffer */
- if (irda_lock((void *) &dev->tbusy) == FALSE)
- return -EBUSY;
+ if (irda_lock((void *) &dev->tbusy) == FALSE) {
+ int tickssofar = jiffies - dev->trans_start;
+ if (tickssofar < 5)
+ return -EBUSY;
+
+ WARNING("%s: transmit timed out\n", dev->name);
+ irport_start(idev, iobase);
+ irport_change_speed(idev, idev->io.baudrate);
+
+ dev->trans_start = jiffies;
+ }
+
+ spin_lock_irqsave(&idev->lock, flags);
X
X /* Init tx buffer */
X idev->tx_buff.data = idev->tx_buff.head;
@@ -291,6 +457,8 @@
X /* Turn on transmit finished interrupt. Will fire immediately! */
X outb(UART_IER_THRI, iobase+UART_IER);
X
+ spin_unlock_irqrestore(&idev->lock, flags);
+
X dev_kfree_skb(skb);
X
X return 0;
@@ -307,10 +475,7 @@
X int iobase;
X int boguscount = 0;
X
- if (!idev)
- return;
-
- DEBUG(4, __FUNCTION__ "()\n");
+ ASSERT(idev != NULL, return;);
X
X iobase = idev->io.iobase2;
X
@@ -342,27 +507,42 @@
X int boguscount = 0;
X
X if (!idev) {
- printk(KERN_WARNING __FUNCTION__
- "() irq %d for unknown device.\n", irq);
+ WARNING(__FUNCTION__ "() irq %d for unknown device.\n", irq);
X return;
X }
X
+ spin_lock(&idev->lock);
+
X idev->netdev.interrupt = 1;
X
X iobase = idev->io.iobase2;
X
- iir = inb(iobase + UART_IIR) & UART_IIR_ID;
+ iir = inb(iobase+UART_IIR) & UART_IIR_ID;
X while (iir) {
X /* Clear interrupt */
X lsr = inb(iobase+UART_LSR);
X
- if ((iir & UART_IIR_THRI) && (lsr & UART_LSR_THRE)) {
- /* Transmitter ready for data */
- irport_write_wakeup(idev);
- } else if ((iir & UART_IIR_RDI) && (lsr & UART_LSR_DR)) {
- /* Receive interrupt */
- irport_receive(idev);
- }
+ DEBUG(4, __FUNCTION__ "(), iir=%02x, lsr=%02x, iobase=%#x\n",
+ iir, lsr, iobase);
+
+ switch (iir) {
+ case UART_IIR_RLSI:
+ DEBUG(0, __FUNCTION__ "(), RLSI\n");
+ break;
+ case UART_IIR_RDI:
+ if (lsr & UART_LSR_DR)
+ /* Receive interrupt */
+ irport_receive(idev);
+ break;
+ case UART_IIR_THRI:
+ if (lsr & UART_LSR_THRE)
+ /* Transmitter ready for data */
+ irport_write_wakeup(idev);
+ break;
+ default:
+ DEBUG(0, __FUNCTION__ "(), unhandled IIR=%#x\n", iir);
+ break;
+ }
X
X /* Make sure we don't stay here to long */
X if (boguscount++ > 32)
@@ -371,10 +551,175 @@
X iir = inb(iobase + UART_IIR) & UART_IIR_ID;
X }
X idev->netdev.interrupt = 0;
+
+ spin_unlock(&idev->lock);
+}
+
+static int irport_net_init(struct device *dev)
+{
+ /* Set up to be a normal IrDA network device driver */
+ irda_device_setup(dev);
+
+ /* Insert overrides below this line! */
+
+ return 0;
+}
+
+/*
+ * Function irport_net_open (dev)
+ *
+ *
+ *
+ */
+static int irport_net_open(struct device *dev)
+{
+ struct irda_device *idev;
+ int iobase;
+
+ ASSERT(dev != NULL, return -1;);
+ idev = (struct irda_device *) dev->priv;
+
+ iobase = idev->io.iobase2;
+
+ if (request_irq(idev->io.irq2, irport_interrupt, 0, idev->name,
+ (void *) idev))
+ return -EAGAIN;
+
+ irport_start(idev, iobase);
+
+ MOD_INC_USE_COUNT;
+
+ /* Ready to play! */
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 1;
+
+ /* Change speed to make sure dongles follow us again */
+ if (idev->change_speed)
+ idev->change_speed(idev, 9600);
+
+ return 0;
+}
+
+/*
+ * Function irport_net_close (idev)
+ *
+ *
+ *
+ */
+static int irport_net_close(struct device *dev)
+{
+ struct irda_device *idev;
+ int iobase;
+
+ ASSERT(dev != NULL, return -1;);
+ idev = (struct irda_device *) dev->priv;
+
+ DEBUG(4, __FUNCTION__ "()\n");
+
+ iobase = idev->io.iobase2;
+
+ /* Stop device */
+ dev->tbusy = 1;
+ dev->start = 0;
+
+ irport_stop(idev, iobase);
+
+ free_irq(idev->io.irq2, idev);
+
+ MOD_DEC_USE_COUNT;
+
+ return 0;
+}
+
+/*
+ * Function irport_wait_until_sent (idev)
+ *
+ * Delay exectution until finished transmitting
+ *
+ */
+void irport_wait_until_sent(struct irda_device *idev)
+{
+ 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));
+ }
+}
+
+/*
+ * Function irport_is_receiving (idev)
+ *
+ * Returns true is we are currently receiving data
+ *
+ */
+static int irport_is_receiving(struct irda_device *idev)
+{
+ return (idev->rx_buff.state != OUTSIDE_FRAME);
+}
+
+/*
+ * Function irtty_set_dtr_rts (tty, dtr, rts)
+ *
+ * This function can be used by dongles etc. to set or reset the status
+ * of the dtr and rts lines
+ */
+static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts)
+{
+ int iobase;
+
+ ASSERT(idev != NULL, return;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+ iobase = idev->io.iobase2;
+
+ if (dtr)
+ dtr = UART_MCR_DTR;
+ if (rts)
+ rts = UART_MCR_RTS;
+
+ outb(dtr|rts|UART_MCR_OUT2, iobase+UART_MCR);
+}
+
+static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len)
+{
+ int iobase;
+ int actual = 0;
+
+ ASSERT(idev != NULL, return -1;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+
+ iobase = idev->io.iobase2;
+
+ /* Tx FIFO should be empty! */
+ if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
+ DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n");
+ return -1;
+ }
+
+ /* Fill FIFO with current frame */
+ while (actual < len) {
+ /* Transmit next byte */
+ outb(buf[actual], iobase+UART_TX);
+ actual++;
+ }
+
+ return actual;
X }
X
X #ifdef MODULE
X
+MODULE_PARM(io, "1-4i");
+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 * Function cleanup_module (void)
X *
@@ -393,11 +738,7 @@
X */
X int init_module(void)
X {
- if (irport_init() < 0) {
- cleanup_module();
- return 1;
- }
- return(0);
+ return irport_init();
X }
X
X #endif /* MODULE */
diff -u --recursive --new-file v2.2.9/linux/drivers/net/irda/irtty.c linux/drivers/net/irda/irtty.c
--- v2.2.9/linux/drivers/net/irda/irtty.c Wed Apr 28 11:37:30 1999
+++ linux/drivers/net/irda/irtty.c Wed Jun 2 11:31:36 1999
@@ -6,12 +6,12 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Tue Dec 9 21:18:38 1997
- * Modified at: Thu Apr 22 09:20:24 1999
+ * Modified at: Mon May 10 15:45:50 1999
X * Modified by: Dag Brattli <da...@cs.uit.no>
X * Sources: slip.c by Laurence Culhane, <l...@holmes.demon.co.uk>
X * Fred N. van Kempen, <wal...@uwalt.nl.mugnet.org>
X *
- * Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License as
@@ -24,7 +24,6 @@
X *
X ********************************************************************/
X
-#include <linux/config.h>
X #include <linux/module.h>
X #include <asm/uaccess.h>
X #include <linux/kernel.h>
@@ -38,19 +37,21 @@
X #include <net/irda/irlap.h>
X #include <net/irda/timer.h>
X #include <net/irda/irda_device.h>
-#include <linux/kmod.h>
X
X static hashbin_t *irtty = NULL;
-static hashbin_t *dongles = NULL;
X
X static struct tty_ldisc irda_ldisc;
X
-static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev);
+static int qos_mtt_bits = 0x03; /* 5 ms or more */
+
+static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev);
X static void irtty_wait_until_sent(struct irda_device *driver);
-static int irtty_is_receiving(struct irda_device *idev);
-static int irtty_net_init(struct device *dev);
-static int irtty_net_open(struct device *dev);
-static int irtty_net_close(struct device *dev);
+static int irtty_is_receiving(struct irda_device *idev);
+static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts);
+static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len);
+static int irtty_net_init(struct device *dev);
+static int irtty_net_open(struct device *dev);
+static int irtty_net_close(struct device *dev);
X
X static int irtty_open(struct tty_struct *tty);
X static void irtty_close(struct tty_struct *tty);
@@ -73,13 +74,6 @@
X return -ENOMEM;
X }
X
- dongles = hashbin_new(HB_LOCAL);
- if (dongles == NULL) {
- printk(KERN_WARNING
- "IrDA: Can't allocate dongles hashbin!\n");
- return -ENOMEM;
- }
-
X /* Fill in our line protocol discipline, and register it */
X memset(&irda_ldisc, 0, sizeof( irda_ldisc));
X
@@ -132,7 +126,6 @@
X * function to hashbin_destroy().
X */
X hashbin_delete(irtty, NULL);
- hashbin_delete(dongles, NULL);
X }
X #endif /* MODULE */
X
@@ -201,7 +194,7 @@
X /* The only value we must override it the baudrate */
X self->idev.qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
X IR_115200;
- self->idev.qos.min_turn_time.bits = 0x0f;
+ self->idev.qos.min_turn_time.bits = qos_mtt_bits;
X self->idev.flags = IFF_SIR | IFF_PIO;
X irda_qos_bits_to_value(&self->idev.qos);
X
@@ -216,7 +209,8 @@
X /* Initialize callbacks */
X self->idev.change_speed = irtty_change_speed;
X self->idev.is_receiving = irtty_is_receiving;
- /* self->idev.is_tbusy = irtty_is_tbusy; */
+ self->idev.set_dtr_rts = irtty_set_dtr_rts;
+ self->idev.raw_write = irtty_raw_write;
X self->idev.wait_until_sent = irtty_wait_until_sent;
X
X /* Override the network functions we need to use */
@@ -248,10 +242,6 @@
X ASSERT(self != NULL, return;);
X ASSERT(self->magic == IRTTY_MAGIC, return;);
X
- /* We are not using any dongle anymore! */
- if (self->dongle_q)
- self->dongle_q->dongle->close(&self->idev);
-
X /* Remove driver */
X irda_device_close(&self->idev);
X
@@ -359,68 +349,6 @@
X }
X
X /*
- * Function irtty_init_dongle (self, type)
- *
- * Initialize attached dongle. Warning, must be called with a process
- * context!
- */
-static void irtty_init_dongle(struct irtty_cb *self, int type)
-{
- struct dongle_q *node;
-
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRTTY_MAGIC, return;);
-
-#ifdef CONFIG_KMOD
- /* Try to load the module needed */
- switch( type) {
- case ESI_DONGLE:
- MESSAGE("IrDA: Trying to initialize ESI dongle!\n");
- request_module("esi");
- break;
- case TEKRAM_DONGLE:
- MESSAGE("IrDA: Trying to initialize Tekram dongle!\n");
- request_module("tekram");
- break;
- case ACTISYS_DONGLE: /* FALLTHROUGH */
- case ACTISYS_PLUS_DONGLE:
- MESSAGE("IrDA: Trying to initialize ACTiSYS dongle!\n");
- request_module("actisys");
- break;
- case GIRBIL_DONGLE:
- MESSAGE("IrDA: Trying to initialize GIrBIL dongle!\n");
- request_module("girbil");
- break;
- default:
- ERROR("Unknown dongle type!\n");
- return;
- }
-#endif /* CONFIG_KMOD */
-
- node = hashbin_find(dongles, type, NULL);
- if ( !node) {
- ERROR("Unable to find requested dongle\n");
- return;
- }
- self->dongle_q = node;
-
- /* Use this change speed function instead of the default */
- self->idev.change_speed = node->dongle->change_speed;
-
- /*
- * Now initialize the dongle!
- */
- node->dongle->open(&self->idev, type);
- node->dongle->qos_init(&self->idev, &self->idev.qos);
-
- /* Reset dongle */
- node->dongle->reset(&self->idev, 0);
-
- /* Set to default baudrate */
- node->dongle->change_speed(&self->idev, 9600);
-}
-
-/*
X * Function irtty_ioctl (tty, file, cmd, arg)
X *
X * The Swiss army knife of system calls :-)
@@ -452,7 +380,7 @@
X break;
X case IRTTY_IOCTDONGLE:
X /* Initialize dongle */
- irtty_init_dongle(self, (int) arg);
+ irda_device_init_dongle(&self->idev, (int) arg);
X break;
X default:
X return -ENOIOCTLCMD;
@@ -645,54 +573,23 @@
X tty_wait_until_sent(self->tty, 0);
X }
X
-int irtty_register_dongle(struct dongle *dongle)
-{
- struct dongle_q *new;
-
- /* Check if this compressor has been registred before */
- if ( hashbin_find ( dongles, dongle->type, NULL)) {
- DEBUG( 0, __FUNCTION__ "(), Dongle already registered\n");
- return 0;
- }
-
- /* Make new IrDA dongle */
- new = (struct dongle_q *) kmalloc(sizeof(struct dongle_q), GFP_KERNEL);
- if (new == NULL)
- return -1;
-
- memset(new, 0, sizeof( struct dongle_q));
- new->dongle = dongle;
-
- /* Insert IrDA dongle into hashbin */
- hashbin_insert(dongles, (QUEUE *) new, dongle->type, NULL);


-
- return 0;
-}
-

-void irtty_unregister_dongle(struct dongle *dongle)
-{
- struct dongle_q *node;
-
- node = hashbin_remove(dongles, dongle->type, NULL);
- if (!node) {
- ERROR(__FUNCTION__ "(), dongle not found!\n");
- return;
- }
- kfree(node);
-}
-
-
X /*
X * Function irtty_set_dtr_rts (tty, dtr, rts)
X *
X * This function can be used by dongles etc. to set or reset the status
X * of the dtr and rts lines
X */
-void irtty_set_dtr_rts(struct tty_struct *tty, int dtr, int rts)
+static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts)
X {
+ struct tty_struct *tty;
+ struct irtty_cb *self;
X mm_segment_t fs;
X int arg = 0;
X
+ self = (struct irtty_cb *) idev->priv;
+
+ tty = self->tty;
+
X #ifdef TIOCM_OUT2 /* Not defined for ARM */
X arg = TIOCM_OUT2;
X #endif
@@ -718,6 +615,25 @@
X set_fs(fs);
X }
X
+static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len)
+{
+ struct irtty_cb *self;
+ int actual = 0;
+
+ ASSERT(idev != NULL, return 0;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+
+ self = (struct irtty_cb *) idev->priv;
+
+ ASSERT(self != NULL, return 0;);
+ ASSERT(self->magic == IRTTY_MAGIC, return 0;);
+
+ if (self->tty->driver.write)
+ actual = self->tty->driver.write(self->tty, 0, buf, len);
+
+ return actual;
+}
+
X static int irtty_net_init(struct device *dev)
X {
X /* Set up to be a normal IrDA network device driver */
@@ -759,6 +675,8 @@
X
X MODULE_AUTHOR("Dag Brattli <da...@cs.uit.no>");
X MODULE_DESCRIPTION("IrDA TTY device driver");
+
+MODULE_PARM(qos_mtt_bits, "i");
X
X /*
X * Function init_module (void)
diff -u --recursive --new-file v2.2.9/linux/drivers/net/irda/litelink.c linux/drivers/net/irda/litelink.c
--- v2.2.9/linux/drivers/net/irda/litelink.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/irda/litelink.c Mon Jun 7 16:19:59 1999
@@ -0,0 +1,206 @@
+/*********************************************************************
+ *
+ * Filename: litelink.c
+ * Version: 1.0
+ * Description: Driver for the Parallax LiteLink dongle
+ * Status: Stable
+ * Author: Dag Brattli <da...@cs.uit.no>
+ * Created at: Fri May 7 12:50:33 1999
+ * Modified at: Wed May 19 07:25:15 1999
+ * Modified by: Dag Brattli <da...@cs.uit.no>
+ *
+ * Copyright (c) 1999 Dag Brattli, 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ********************************************************************/
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/irda_device.h>
+#include <net/irda/dongle.h>
+
+#define MIN_DELAY 25 /* 15 us, but wait a little more to be sure */
+#define MAX_DELAY 10000 /* 1 ms */
+
+static void litelink_open(struct irda_device *idev, int type);
+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);
+static void litelink_init_qos(struct irda_device *idev, struct qos_info *qos);
+
+/* These are the baudrates supported */
+static int baud_rates[] = { 115200, 57600, 38400, 19200, 9600 };
+
+static struct dongle dongle = {
+ LITELINK_DONGLE,
+ litelink_open,
+ litelink_close,
+ litelink_reset,
+ litelink_change_speed,
+ litelink_init_qos,
+};
+
+__initfunc(int litelink_init(void))
+{
+ return irda_device_register_dongle(&dongle);
+}
+
+void litelink_cleanup(void)
+{
+ irda_device_unregister_dongle(&dongle);
+}
+
+static void litelink_open(struct irda_device *idev, int type)
+{
+ strcat(idev->description, " <-> litelink");
+
+ idev->io.dongle_id = type;
+ idev->flags |= IFF_DONGLE;
+
+ MOD_INC_USE_COUNT;
+}
+
+static void litelink_close(struct irda_device *idev)
+{
+ /* Power off dongle */
+ irda_device_set_dtr_rts(idev, FALSE, FALSE);
+
+ MOD_DEC_USE_COUNT;
+}
+
+/*
+ * Function litelink_change_speed (tty, baud)
+ *
+ * Change speed of the Litelink dongle. To cycle through the available
+ * baud rates, pulse RTS low for a few ms.
+ */
+static void litelink_change_speed(struct irda_device *idev, int baudrate)
+{
+ int i;
+
+ ASSERT(idev != NULL, return;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+ /* Clear RTS to reset dongle */
+ irda_device_set_dtr_rts(idev, TRUE, FALSE);
+
+ /* Sleep a minimum of 15 us */
+ udelay(MIN_DELAY);
+
+ /* Go back to normal mode */
+ irda_device_set_dtr_rts(idev, TRUE, TRUE);
+
+ /* Sleep a minimum of 15 us */
+ udelay(MIN_DELAY);
+
+ /* Cycle through avaiable baudrates until we reach the correct one */
+ for (i=0; i<5 && baud_rates[i] != baudrate; i++) {
+
+ /* Set DTR, clear RTS */
+ irda_device_set_dtr_rts(idev, FALSE, TRUE);
+
+ /* Sleep a minimum of 15 us */
+ udelay(MIN_DELAY);
+
+ /* Set DTR, Set RTS */
+ irda_device_set_dtr_rts(idev, TRUE, TRUE);
+
+ /* Sleep a minimum of 15 us */
+ udelay(MIN_DELAY);
+ }
+}
+
+/*
+ * Function litelink_reset (dev)
+ *
+ * Reset the Litelink type dongle. Warning, this function must only be
+ * called with a process context!
+ *
+ */
+static void litelink_reset(struct irda_device *idev)
+{
+ ASSERT(idev != NULL, return;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+
+ /* Power on dongle */
+ irda_device_set_dtr_rts(idev, TRUE, TRUE);
+
+ /* Sleep a minimum of 15 us */
+ udelay(MIN_DELAY);
+
+ /* Clear RTS to reset dongle */
+ irda_device_set_dtr_rts(idev, TRUE, FALSE);
+
+ /* Sleep a minimum of 15 us */
+ udelay(MIN_DELAY);
+
+ /* Go back to normal mode */
+ irda_device_set_dtr_rts(idev, TRUE, TRUE);
+
+ /* Sleep a minimum of 15 us */
+ udelay(MIN_DELAY);
+
+ /* This dongles speed defaults to 115200 bps */
+ idev->qos.baud_rate.value = 115200;
+}
+
+/*
+ * Function litelink_init_qos (qos)
+ *
+ * Initialize QoS capabilities
+ *
+ */
+static void litelink_init_qos(struct irda_device *idev, struct qos_info *qos)
+{
+ qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+ qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */
+}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Dag Brattli <da...@cs.uit.no>");
+MODULE_DESCRIPTION("Parallax Litelink dongle driver");
+
+/*
+ * Function init_module (void)
+ *
+ * Initialize Litelink module
+ *
+ */
+int init_module(void)
+{
+ return litelink_init();
+}
+
+/*
+ * Function cleanup_module (void)
+ *
+ * Cleanup Litelink module
+ *
+ */
+void cleanup_module(void)
+{
+ litelink_cleanup();
+}
+
+#endif
diff -u --recursive --new-file v2.2.9/linux/drivers/net/irda/pc87108.c linux/drivers/net/irda/pc87108.c
--- v2.2.9/linux/drivers/net/irda/pc87108.c Wed Apr 28 11:37:30 1999
+++ linux/drivers/net/irda/pc87108.c Mon Jun 7 16:19:59 1999
@@ -6,10 +6,10 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Sat Nov 7 21:43:15 1998
- * Modified at: Tue Apr 20 11:11:39 1999
+ * Modified at: Mon May 24 15:19:21 1999
X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
- * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>
+ * Copyright (c) 1998-1999 Dag Brattli <da...@cs.uit.no>
X * Copyright (c) 1998 Lichen Wang, <lw...@actisys.com>
X * Copyright (c) 1998 Actisys Corp., www.actisys.com
X * All Rights Reserved
@@ -67,11 +67,12 @@
X #define BROKEN_DONGLE_ID
X
X static char *driver_name = "pc87108";
+static int qos_mtt_bits = 0x07; /* 1 ms or more */
X
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
@@ -97,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 ()
@@ -130,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;
@@ -166,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;
@@ -203,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
- idev->qos.min_turn_time.bits = 0x07;
- irda_qos_bits_to_value( &idev->qos);
+ idev->qos.min_turn_time.bits = qos_mtt_bits;
+ irda_qos_bits_to_value(&idev->qos);
X
X idev->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO|IFF_DONGLE;
X
@@ -244,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 }
@@ -259,23 +260,26 @@
X * Close driver instance
X *
X */
-static int pc87108_close( struct irda_device *idev)
+static int pc87108_close(struct irda_device *idev)
X {
+ struct pc87108 *self;
X int iobase;
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;
+ 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);
- release_region( idev->io.iobase, idev->io.io_ext);
+ DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase);
+ release_region(idev->io.iobase, idev->io.io_ext);
X
- irda_device_close( idev);
+ irda_device_close(idev);
+
+ kfree(self);
X
X return 0;
X }
@@ -287,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 */
@@ -314,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 }
@@ -404,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);
@@ -416,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 }
@@ -438,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
@@ -805,7 +808,6 @@
X setup_dma(idev->io.dma, idev->tx_buff.data, idev->tx_buff.len,
X DMA_MODE_WRITE);
X
- /* idev->media_busy = TRUE; */
X idev->io.direction = IO_XMIT;
X
X /* Choose transmit DMA channel */
@@ -814,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 /*
@@ -828,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;
@@ -847,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 }
@@ -973,7 +975,7 @@
X *
X *
X */
-static int pc87108_dma_receive_complete( struct irda_device *idev, int iobase)
+static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase)
X {
X struct sk_buff *skb;
X struct pc87108 *self;
@@ -988,8 +990,6 @@
X /* Save current bank */
X bank = inb( iobase+BSR);
X
- iobase = idev->io.iobase;
-
X /* Read status FIFO */
X switch_bank(iobase, BANK5);
X while (( status = inb( iobase+FRM_ST)) & FRM_ST_VLD) {
@@ -1003,18 +1003,18 @@
X }
X
X /* Try to process all entries in status FIFO */
- switch_bank( iobase, BANK0);
- while ( st_fifo->len) {
+ switch_bank(iobase, BANK0);
+ while (st_fifo->len) {
X
X /* Get first entry */
- status = st_fifo->entries[ st_fifo->head].status;
- len = st_fifo->entries[ st_fifo->head].len;
+ status = st_fifo->entries[st_fifo->head].status;
+ len = st_fifo->entries[st_fifo->head].len;
X st_fifo->head++;
X st_fifo->len--;
X
X /* Check for errors */
- if ( status & FRM_ST_ERR_MSK) {
- if ( status & FRM_ST_LOST_FR) {
+ if (status & FRM_ST_ERR_MSK) {
+ if (status & FRM_ST_LOST_FR) {
X /* Add number of lost frames to stats */
X idev->stats.rx_errors += len;
X } else {
@@ -1188,8 +1188,8 @@
X bank = inb( iobase+BSR);
X
X /* Status event, or end of frame detected in FIFO */
- if ( eir & (EIR_SFIF_EV|EIR_LS_EV)) {
- if ( pc87108_dma_receive_complete( idev, iobase)) {
+ if (eir & (EIR_SFIF_EV|EIR_LS_EV)) {
+ if (pc87108_dma_receive_complete( idev, iobase)) {
X
X /* Wait for next status FIFO interrupt */
X new_ier |= IER_SFIF_IE;
@@ -1459,6 +1459,14 @@
X }
X
X #ifdef MODULE
+
+MODULE_AUTHOR("Dag Brattli <da...@cs.uit.no>");
+MODULE_DESCRIPTION("NSC PC87108 IrDA Device Driver");
+
+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.2.9/linux/drivers/net/irda/smc-ircc.c linux/drivers/net/irda/smc-ircc.c
--- v2.2.9/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:19:59 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;


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

echo 'End of part 07'
echo 'File patch-2.2.10 is continued in part 08'
echo 08 > _shar_seq_.tmp
exit 0

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.2/patch-2.2.10/part06

#!/bin/sh
# this is part 06 of a 22 - part archive


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

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

+ else
+ info->input_signal_events.dsr_down++;
+ }
X if (status & MISCSTATUS_DCD_LATCHED) {
+ if ((info->dcd_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT)
+ usc_DisablestatusIrqs(info,SICR_DCD);
X icount->dcd++;
+ if ( status & MISCSTATUS_DCD )
+ info->input_signal_events.dcd_up++;
+ else
+ info->input_signal_events.dcd_down++;
X #ifdef CONFIG_HARD_PPS
X if ((info->flags & ASYNC_HARDPPS_CD) &&
X (status & MISCSTATUS_DCD_LATCHED))
@@ -1369,7 +1470,15 @@
X #endif
X }
X if (status & MISCSTATUS_CTS_LATCHED)
+ {
+ if ((info->cts_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT)
+ usc_DisablestatusIrqs(info,SICR_CTS);
X icount->cts++;
+ if ( status & MISCSTATUS_CTS )
+ info->input_signal_events.cts_up++;
+ else
+ info->input_signal_events.cts_down++;
+ }
X wake_up_interruptible(&info->status_event_wait_q);
X wake_up_interruptible(&info->event_wait_q);
X
@@ -1411,6 +1520,8 @@
X }
X }
X
+ mgsl_bh_queue_put(info, BH_TYPE_STATUS, status);
+
X /* for diagnostics set IRQ flag */
X if ( status & MISCSTATUS_TXC_LATCHED ){
X usc_OutReg( info, SICR,
@@ -1642,8 +1753,10 @@
X /* Post a receive event for BH processing. */
X mgsl_bh_queue_put( info, BH_TYPE_RECEIVE_DMA, status );
X
- if ( status & BIT3 )
+ if ( status & BIT3 ) {
X info->rx_overflow = 1;
+ info->icount.buf_overrun++;
+ }
X
X } /* end of mgsl_isr_receive_dma() */
X
@@ -1696,9 +1809,9 @@
X if ( info->isr_overflow ) {
X printk(KERN_ERR"%s(%d):%s isr overflow irq=%d\n",
X __FILE__,__LINE__,info->device_name, irq);
- /* Interrupt overflow. Reset adapter and exit. */
-// UscReset(info);
-// break;
+ usc_DisableMasterIrqBit(info);
+ usc_DisableDmaInterrupts(info,DICR_MASTER);
+ break;
X }
X }
X
@@ -1980,6 +2093,11 @@
X usc_set_async_mode(info);
X
X usc_set_serial_signals(info);
+
+ info->dcd_chkcount = 0;
+ info->cts_chkcount = 0;
+ info->ri_chkcount = 0;
+ info->dsr_chkcount = 0;
X
X /* enable modem signal IRQs and read initial signal states */
X usc_EnableStatusIrqs(info,SICR_CTS+SICR_DSR+SICR_DCD+SICR_RI);
@@ -2112,16 +2230,27 @@
X
X if ( info->params.mode == MGSL_MODE_HDLC ) {
X /* operating in synchronous (frame oriented) mode */
-
+
X if (info->tx_active) {
X ret = 0; goto cleanup;
X }
-
+
+ /* if operating in HDLC LoopMode and the adapter */
+ /* has yet to be inserted into the loop, we can't */
+ /* transmit */
+
+ if ( (info->params.flags & HDLC_FLAG_HDLC_LOOPMODE) &&
+ !usc_loopmode_active(info) )
+ {
+ ret = 0;
+ goto cleanup;
+ }
+
X if ( info->xmit_cnt ) {
X /* Send accumulated from send_char() calls */
X /* as frame and wait before accepting more data. */
X ret = 0;
-
+
X /* copy data from circular xmit_buf to */
X /* transmit DMA buffer. */
X mgsl_load_tx_dma_buffer(info,
@@ -2578,8 +2707,19 @@
X
X spin_lock_irqsave(&info->irq_spinlock,flags);
X if ( enable ) {
- if ( !info->tx_enabled )
+ if ( !info->tx_enabled ) {
+
X usc_start_transmitter(info);
+ /*--------------------------------------------------
+ * if HDLC/SDLC Loop mode, attempt to insert the
+ * station in the 'loop' by setting CMR:13. Upon
+ * receipt of the next GoAhead (RxAbort) sequence,
+ * the OnLoop indicator (CCSR:7) should go active
+ * to indicate that we are on the loop
+ *--------------------------------------------------*/
+ if ( info->params.flags & HDLC_FLAG_HDLC_LOOPMODE )
+ usc_loopmode_insert_request( info );
+ }
X } else {
X if ( info->tx_enabled )
X usc_stop_transmitter(info);
@@ -2604,7 +2744,12 @@
X
X spin_lock_irqsave(&info->irq_spinlock,flags);
X if ( info->tx_active && info->params.mode == MGSL_MODE_HDLC )
- usc_TCmd(info,TCmd_SendAbort);
+ {
+ if ( info->params.flags & HDLC_FLAG_HDLC_LOOPMODE )
+ usc_loopmode_cancel_transmit( info );
+ else
+ usc_TCmd(info,TCmd_SendAbort);
+ }
X spin_unlock_irqrestore(&info->irq_spinlock,flags);
X return 0;
X
@@ -2640,25 +2785,39 @@
X /* mgsl_wait_event() wait for specified event to occur
X *
X * Arguments: info pointer to device instance data
- * mask bitmask of events to wait for
- * Return Value: bit mask of triggering event, otherwise error code
+ * mask pointer to bitmask of events to wait for
+ * Return Value: 0 if successful and bit mask updated with
+ * of events triggerred,
+ * otherwise error code
X */
-static int mgsl_wait_event(struct mgsl_struct * info, int mask)
+static int mgsl_wait_event(struct mgsl_struct * info, int * mask_ptr)
X {
X unsigned long flags;
X int s;
X int rc=0;
X u16 regval;
X struct mgsl_icount cprev, cnow;
+ int events = 0;
+ int mask;
+ struct _input_signal_events signal_events_prev, signal_events_now;
+
+ COPY_FROM_USER(rc,&mask, mask_ptr, sizeof(int));
+ if (rc) {
+ return -EFAULT;
+ }
X
X if (debug_level >= DEBUG_LEVEL_INFO)
X printk("%s(%d):mgsl_wait_event(%s,%d)\n", __FILE__,__LINE__,
X info->device_name, mask);
-
+
X spin_lock_irqsave(&info->irq_spinlock,flags);
-
+
+ usc_get_serial_signals(info);
+ s = info->serial_signals;
+
X /* note the counters on entry */
X cprev = info->icount;
+ signal_events_prev = info->input_signal_events;
X
X if (mask & MgslEvent_ExitHuntMode) {
X /* enable exit hunt mode IRQ */
@@ -2676,7 +2835,22 @@
X
X spin_unlock_irqrestore(&info->irq_spinlock,flags);
X
- while(!rc) {
+ /* Determine if any user requested events for input signals is currently TRUE */
+
+ events |= (mask & ((s & SerialSignal_DSR) ?
+ MgslEvent_DsrActive:MgslEvent_DsrInactive));
+
+ events |= (mask & ((s & SerialSignal_DCD) ?
+ MgslEvent_DcdActive:MgslEvent_DcdInactive));
+
+ events |= (mask & ((s & SerialSignal_CTS) ?
+ MgslEvent_CtsActive:MgslEvent_CtsInactive));
+
+ events |= (mask & ((s & SerialSignal_RI) ?
+ MgslEvent_RiActive:MgslEvent_RiInactive));
+
+
+ while(!events) {
X /* sleep until event occurs */
X interruptible_sleep_on(&info->event_wait_q);
X
@@ -2687,44 +2861,57 @@
X }
X
X spin_lock_irqsave(&info->irq_spinlock,flags);
+
X /* get icount and serial signal states */
X cnow = info->icount;
- s = info->serial_signals;
+ signal_events_now = info->input_signal_events;
X spin_unlock_irqrestore(&info->irq_spinlock,flags);
+
+ if (signal_events_now.dsr_up != signal_events_prev.dsr_up &&
+ mask & MgslEvent_DsrActive )
+ events |= MgslEvent_DsrActive;
+
+ if (signal_events_now.dsr_down != signal_events_prev.dsr_down &&
+ mask & MgslEvent_DsrInactive )
+ events |= MgslEvent_DsrInactive;
+
+ if (signal_events_now.dcd_up != signal_events_prev.dcd_up &&
+ mask & MgslEvent_DcdActive )
+ events |= MgslEvent_DcdActive;
+
+ if (signal_events_now.dcd_down != signal_events_prev.dcd_down &&
+ mask & MgslEvent_DcdInactive )
+ events |= MgslEvent_DcdInactive;
+
+ if (signal_events_now.cts_up != signal_events_prev.cts_up &&
+ mask & MgslEvent_CtsActive )
+ events |= MgslEvent_CtsActive;
+
+ if (signal_events_now.cts_down != signal_events_prev.cts_down &&
+ mask & MgslEvent_CtsInactive )
+ events |= MgslEvent_CtsInactive;
+
+ if (signal_events_now.ri_up != signal_events_prev.ri_up &&
+ mask & MgslEvent_RiActive )
+ events |= MgslEvent_RiActive;
+
+ if (signal_events_now.ri_down != signal_events_prev.ri_down &&
+ mask & MgslEvent_RiInactive )
+ events |= MgslEvent_RiInactive;
X
- rc = 0;
-
- if (cnow.dsr != cprev.dsr)
- rc |= (mask & ((s & SerialSignal_DSR) ?
- MgslEvent_DsrActive:MgslEvent_DsrInactive));
-
- if (cnow.dcd != cprev.dcd)
- rc |= (mask & ((s & SerialSignal_DCD) ?
- MgslEvent_DcdActive:MgslEvent_DcdInactive));
-
- if (cnow.cts != cprev.cts)
- rc |= (mask & ((s & SerialSignal_CTS) ?
- MgslEvent_CtsActive:MgslEvent_CtsInactive));
-
- if (cnow.rng != cprev.rng)
- rc |= (mask & ((s & SerialSignal_RI) ?
- MgslEvent_RiActive:MgslEvent_RiInactive));
-
X if (cnow.exithunt != cprev.exithunt)
- rc |= (mask & MgslEvent_ExitHuntMode);
-
+ events |= (mask & MgslEvent_ExitHuntMode);
+
X if (cnow.rxidle != cprev.rxidle)
- rc |= (mask & MgslEvent_ExitHuntMode);
-
- if (!rc)
- rc = -EIO; /* no change => error */
-
+ events |= (mask & MgslEvent_IdleReceived);
+
X cprev = cnow;
+ signal_events_prev = signal_events_now;
X }
X
X if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) {
X spin_lock_irqsave(&info->irq_spinlock,flags);
- if (!info->event_wait_q) {
+ if (!waitqueue_active(&info->event_wait_q)) {
X /* disable enable exit hunt mode/idle rcvd IRQs */
X regval = usc_InReg(info,RICR);
X usc_OutReg(info, RICR, regval &
@@ -2732,7 +2919,10 @@
X }
X spin_unlock_irqrestore(&info->irq_spinlock,flags);
X }
-
+
+ if ( rc == 0 )
+ PUT_USER(rc, events, mask_ptr);
+
X return rc;
X
X } /* end of mgsl_wait_event() */
@@ -2772,7 +2962,7 @@
X
X if (debug_level >= DEBUG_LEVEL_INFO)
X printk("%s(%d):mgsl_get_modem_info %s value=%08X\n",
- __FILE__,__LINE__, info->device_name, *value );
+ __FILE__,__LINE__, info->device_name, result );
X
X PUT_USER(err,result,value);
X return err;
@@ -2928,7 +3118,9 @@
X case MGSL_IOCGSTATS:
X return mgsl_get_stats(info,(struct mgsl_icount*)arg);
X case MGSL_IOCWAITEVENT:
- return mgsl_wait_event(info,(int)arg);
+ return mgsl_wait_event(info,(int*)arg);
+ case MGSL_IOCLOOPTXDONE:
+ return mgsl_loopmode_send_done(info);
X case MGSL_IOCCLRMODCOUNT:
X while(MOD_IN_USE)
X MOD_DEC_USE_COUNT;
@@ -3626,11 +3818,6 @@
X }
X spin_unlock_irqrestore(&info->irq_spinlock,flags);
X
-#if 0 && LINUX_VERSION_CODE >= VERSION(2,1,0)
- ret += sprintf(buf+ret, "irq_spinlock=%08X\n",
- info->irq_spinlock.lock );
-#endif
-
X return ret;
X
X } /* end of line_info() */
@@ -4223,6 +4410,18 @@
X if ( PCIBIOS_SUCCESSFUL == pcibios_find_device(
X MICROGATE_VENDOR_ID, SYNCLINK_DEVICE_ID, i, &bus, &func) ) {
X
+#if LINUX_VERSION_CODE >= VERSION(2,1,0)
+ struct pci_dev *pdev = pci_find_slot(bus,func);
+ irq_line = pdev->irq;
+#else
+ if (pcibios_read_config_byte(bus,func,
+ PCI_INTERRUPT_LINE,&irq_line) ) {
+ printk( "%s(%d):USC I/O addr not set.\n",
+ __FILE__,__LINE__);
+ continue;
+ }
+#endif
+
X if (pcibios_read_config_dword(bus,func,
X PCI_BASE_ADDRESS_3,&shared_mem_base) ) {
X printk( "%s(%d):Shared mem addr not set.\n",
@@ -4244,13 +4443,6 @@
X continue;
X }
X
- if (pcibios_read_config_byte(bus,func,
- PCI_INTERRUPT_LINE,&irq_line) ) {
- printk( "%s(%d):USC I/O addr not set.\n",
- __FILE__,__LINE__);
- continue;
- }
-
X info = mgsl_allocate_device();
X if ( !info ) {
X /* error allocating device instance data */
@@ -4667,29 +4859,53 @@
X {
X u16 RegValue;
X
- /* Channel mode Register (CMR)
- *
- * <15..14> 00 Tx Sub modes, Underrun Action
- * <13> 0 1 = Send Preamble before opening flag
- * <12> 0 1 = Consecutive Idles share common 0
- * <11..8> 0110 Transmitter mode = HDLC/SDLC
- * <7..4> 0000 Rx Sub modes, addr/ctrl field handling
- * <3..0> 0110 Receiver mode = HDLC/SDLC
- *
- * 0000 0110 0000 0110 = 0x0606
- */
+ if ( info->params.flags & HDLC_FLAG_HDLC_LOOPMODE )
+ {
+ /*
+ ** Channel Mode Register (CMR)
+ **
+ ** <15..14> 10 Tx Sub Modes, Send Flag on Underrun
+ ** <13> 0 0 = Transmit Disabled (initially)
+ ** <12> 0 1 = Consecutive Idles share common 0
+ ** <11..8> 1110 Transmitter Mode = HDLC/SDLC Loop
+ ** <7..4> 0000 Rx Sub Modes, addr/ctrl field handling
+ ** <3..0> 0110 Receiver Mode = HDLC/SDLC
+ **
+ ** 1000 1110 0000 0110 = 0x8e06
+ */
+ RegValue = 0x8e06;
+
+ /*--------------------------------------------------
+ * ignore user options for UnderRun Actions and
+ * preambles
+ *--------------------------------------------------*/
+ }
+ else
+ {
+ /* Channel mode Register (CMR)
+ *
+ * <15..14> 00 Tx Sub modes, Underrun Action
+ * <13> 0 1 = Send Preamble before opening flag
+ * <12> 0 1 = Consecutive Idles share common 0
+ * <11..8> 0110 Transmitter mode = HDLC/SDLC
+ * <7..4> 0000 Rx Sub modes, addr/ctrl field handling
+ * <3..0> 0110 Receiver mode = HDLC/SDLC
+ *
+ * 0000 0110 0000 0110 = 0x0606
+ */
X
- RegValue = 0x0606;
+ RegValue = 0x0606;
X
- if ( info->params.flags & HDLC_FLAG_UNDERRUN_ABORT15 )
- RegValue |= BIT14;
- else if ( info->params.flags & HDLC_FLAG_UNDERRUN_FLAG )
- RegValue |= BIT15;
- else if ( info->params.flags & HDLC_FLAG_UNDERRUN_CRC )
- RegValue |= BIT15 + BIT14;
+ if ( info->params.flags & HDLC_FLAG_UNDERRUN_ABORT15 )
+ RegValue |= BIT14;
+ else if ( info->params.flags & HDLC_FLAG_UNDERRUN_FLAG )
+ RegValue |= BIT15;
+ else if ( info->params.flags & HDLC_FLAG_UNDERRUN_CRC )
+ RegValue |= BIT15 + BIT14;
X
- if ( info->params.preamble != HDLC_PREAMBLE_PATTERN_NONE )
- RegValue |= BIT13;
+ if ( info->params.preamble != HDLC_PREAMBLE_PATTERN_NONE )
+ RegValue |= BIT13;
+ }
X
X if ( info->params.flags & HDLC_FLAG_SHARE_ZERO )
X RegValue |= BIT12;
@@ -4858,6 +5074,8 @@
X RegValue |= 0x0003; /* RxCLK from DPLL */
X else if ( info->params.flags & HDLC_FLAG_RXC_BRG )
X RegValue |= 0x0004; /* RxCLK from BRG0 */
+ else if ( info->params.flags & HDLC_FLAG_RXC_TXCPIN)
+ RegValue |= 0x0006; /* RxCLK from TXC Input */
X else
X RegValue |= 0x0007; /* RxCLK from Port1 */
X
@@ -4865,6 +5083,8 @@
X RegValue |= 0x0018; /* TxCLK from DPLL */
X else if ( info->params.flags & HDLC_FLAG_TXC_BRG )
X RegValue |= 0x0020; /* TxCLK from BRG0 */
+ else if ( info->params.flags & HDLC_FLAG_TXC_RXCPIN)
+ RegValue |= 0x0038; /* RxCLK from TXC Input */
X else
X RegValue |= 0x0030; /* TxCLK from Port0 */
X
@@ -4918,10 +5138,24 @@
X /* of rounding up and then subtracting 1 we just don't subtract */
X /* the one in this case. */
X
- Tc = (u16)((XtalSpeed/DpllDivisor)/info->params.clock_speed);
- if ( !((((XtalSpeed/DpllDivisor) % info->params.clock_speed) * 2)
- / info->params.clock_speed) )
- Tc--;
+ /*--------------------------------------------------
+ * ejz: for DPLL mode, application should use the
+ * same clock speed as the partner system, even
+ * though clocking is derived from the input RxData.
+ * In case the user uses a 0 for the clock speed,
+ * default to 0xffffffff and don't try to divide by
+ * zero
+ *--------------------------------------------------*/
+ if ( info->params.clock_speed )
+ {
+ Tc = (u16)((XtalSpeed/DpllDivisor)/info->params.clock_speed);
+ if ( !((((XtalSpeed/DpllDivisor) % info->params.clock_speed) * 2)
+ / info->params.clock_speed) )
+ Tc--;
+ }
+ else
+ Tc = -1;
+
X
X /* Write 16-bit Time Constant for BRG1 */
X usc_OutReg( info, TC1R, Tc );
@@ -6324,6 +6558,13 @@
X if ( debug_level >= DEBUG_LEVEL_DATA )
X mgsl_trace_block(info,Buffer,BufferSize,1);
X
+ if (info->params.flags & HDLC_FLAG_HDLC_LOOPMODE) {
+ /* set CMR:13 to start transmit when
+ * next GoAhead (abort) is received
+ */
+ info->cmr_value |= BIT13;
+ }
+
X /* Setup the status and RCC (Frame Size) fields of the 1st */
X /* buffer entry in the transmit DMA buffer list. */
X
@@ -6377,7 +6618,7 @@
X unsigned int i;
X BOOLEAN rc = TRUE;
X unsigned long flags;
-
+
X spin_lock_irqsave(&info->irq_spinlock,flags);
X usc_reset(info);
X spin_unlock_irqrestore(&info->irq_spinlock,flags);
@@ -6467,7 +6708,7 @@
X usc_reset(info);
X spin_unlock_irqrestore(&info->irq_spinlock,flags);
X
- if ( !info->irq_occurred )
+ if ( !info->irq_occurred )
X return FALSE;
X else
X return TRUE;
@@ -6495,7 +6736,7 @@
X volatile unsigned long EndTime;
X unsigned long flags;
X MGSL_PARAMS tmp_params;
-
+
X /* save current port options */
X memcpy(&tmp_params,&info->params,sizeof(MGSL_PARAMS));
X /* load default port options */
@@ -6653,7 +6894,7 @@
X /**********************************/
X /* WAIT FOR TRANSMIT FIFO TO FILL */
X /**********************************/
-
+
X /* Wait 100ms */
X EndTime = jiffies + jiffies_from_ms(100);
X
@@ -6720,7 +6961,7 @@
X
X if ( rc == TRUE ){
X /* CHECK FOR TRANSMIT ERRORS */
- if ( status & (BIT5 + BIT1) )
+ if ( status & (BIT5 + BIT1) )
X rc = FALSE;
X }
X
@@ -6977,13 +7218,90 @@
X if(info->tx_active && info->params.mode == MGSL_MODE_HDLC) {
X info->icount.txtimeout++;
X }
-
X spin_lock_irqsave(&info->irq_spinlock,flags);
X info->tx_active = 0;
X info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+
+ if ( info->params.flags & HDLC_FLAG_HDLC_LOOPMODE )
+ usc_loopmode_cancel_transmit( info );
+
X spin_unlock_irqrestore(&info->irq_spinlock,flags);
X
X mgsl_bh_transmit_data(info,0);
X
X } /* end of mgsl_tx_timeout() */
+
+/* signal that there are no more frames to send, so that
+ * line is 'released' by echoing RxD to TxD when current
+ * transmission is complete (or immediately if no tx in progress).
+ */
+static int mgsl_loopmode_send_done( struct mgsl_struct * info )
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&info->irq_spinlock,flags);
+ if (info->params.flags & HDLC_FLAG_HDLC_LOOPMODE) {
+ if (info->tx_active)
+ info->loopmode_send_done_requested = TRUE;
+ else
+ usc_loopmode_send_done(info);
+ }
+ spin_unlock_irqrestore(&info->irq_spinlock,flags);


+
+ return 0;
+}
+

+/* release the line by echoing RxD to TxD
+ * upon completion of a transmit frame
+ */
+void usc_loopmode_send_done( struct mgsl_struct * info )
+{
+ info->loopmode_send_done_requested = FALSE;
+ /* clear CMR:13 to 0 to start echoing RxData to TxData */
+ info->cmr_value &= ~BIT13;
+ usc_OutReg(info, CMR, info->cmr_value);
+}
+
+/* abort a transmit in progress while in HDLC LoopMode
+ */
+void usc_loopmode_cancel_transmit( struct mgsl_struct * info )
+{
+ /* reset tx dma channel and purge TxFifo */
+ usc_RTCmd( info, RTCmd_PurgeTxFifo );
+ usc_DmaCmd( info, DmaCmd_ResetTxChannel );
+ usc_loopmode_send_done( info );
+}
+
+/* for HDLC/SDLC LoopMode, setting CMR:13 after the transmitter is enabled
+ * is an Insert Into Loop action. Upon receipt of a GoAhead sequence (RxAbort)
+ * we must clear CMR:13 to begin repeating TxData to RxData
+ */
+void usc_loopmode_insert_request( struct mgsl_struct * info )
+{
+ info->loopmode_insert_requested = TRUE;
+
+ /* enable RxAbort irq. On next RxAbort, clear CMR:13 to
+ * begin repeating TxData on RxData (complete insertion)
+ */
+ usc_OutReg( info, RICR,
+ (usc_InReg( info, RICR ) | RXSTATUS_ABORT_RECEIVED ) );
+
+ /* set CMR:13 to insert into loop on next GoAhead (RxAbort) */
+ info->cmr_value |= BIT13;
+ usc_OutReg(info, CMR, info->cmr_value);
+}
+
+/* return 1 if station is inserted into the loop, otherwise 0
+ */
+int usc_loopmode_active( struct mgsl_struct * info)
+{
+ return usc_InReg( info, CCSR ) & BIT7 ? 1 : 0 ;
+}
+
+/* return 1 if USC is in loop send mode, otherwise 0
+ */
+int usc_loopmode_send_active( struct mgsl_struct * info )
+{
+ return usc_InReg( info, CCSR ) & BIT6 ? 1 : 0 ;
+}
X
diff -u --recursive --new-file v2.2.9/linux/drivers/char/tuner.c linux/drivers/char/tuner.c
--- v2.2.9/linux/drivers/char/tuner.c Tue Jan 19 11:32:51 1999
+++ linux/drivers/char/tuner.c Mon Jun 7 16:18:17 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.2.9/linux/drivers/char/tuner.h linux/drivers/char/tuner.h
--- v2.2.9/linux/drivers/char/tuner.h Thu Nov 12 16:21:19 1998
+++ linux/drivers/char/tuner.h Mon Jun 7 16:18:17 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.2.9/linux/drivers/char/videodev.c linux/drivers/char/videodev.c
--- v2.2.9/linux/drivers/char/videodev.c Fri Apr 16 14:47:30 1999
+++ linux/drivers/char/videodev.c Wed Jun 2 11:29:28 1999
@@ -9,7 +9,7 @@
X * as published by the Free Software Foundation; either version
X * 2 of the License, or (at your option) any later version.
X *
- * Author: Alan Cox, <al...@cymru.net>
+ * Author: Alan Cox, <al...@redhat.com>
X *
X * Fixes:
X */
diff -u --recursive --new-file v2.2.9/linux/drivers/char/wdt.c linux/drivers/char/wdt.c
--- v2.2.9/linux/drivers/char/wdt.c Fri Oct 23 22:01:21 1998
+++ linux/drivers/char/wdt.c Wed Jun 2 11:29:28 1999
@@ -1,8 +1,8 @@
X /*
X * Industrial Computer Source WDT500/501 driver for Linux 2.1.x
X *
- * (c) Copyright 1996-1997 Alan Cox <al...@cymru.net>, All Rights Reserved.
- * http://www.cymru.net
+ * (c) Copyright 1996-1997 Alan Cox <al...@redhat.com>, All Rights Reserved.
+ * http://www.redhat.com


X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License

@@ -15,7 +15,7 @@
X *
X * (c) Copyright 1995 Alan Cox <al...@lxorguk.ukuu.org.uk>
X *
- * Release 0.07.
+ * Release 0.08.
X *
X * Fixes
X * Dave Gregorich : Modularisation and minor bugs
@@ -24,6 +24,8 @@
X * Matt Crocker).
X * Alan Cox : Added wdt= boot option
X * Alan Cox : Cleaned up copy/user stuff
+ * Tim Hockin : Added insmod parameters, comment cleanup
+ * Parameterized timeout
X */
X
X #include <linux/config.h>
diff -u --recursive --new-file v2.2.9/linux/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c
--- v2.2.9/linux/drivers/misc/parport_pc.c Tue May 11 13:10:29 1999
+++ linux/drivers/misc/parport_pc.c Tue Jun 1 16:43:43 1999
@@ -371,12 +371,12 @@
X * copy. Some ports _do_ allow reads, so bypass the software
X * copy here. In addition, some bits aren't writable. */
X r = inb (pb->base+CONTROL);
- if ((r & 0x3f) == w) {
+ if ((r & 0xf) == w) {
X w = 0xe;
X parport_pc_write_control (pb, w);
X r = inb (pb->base+CONTROL);
X parport_pc_write_control (pb, 0xc);
- if ((r & 0x3f) == w)
+ if ((r & 0xf) == w)
X return PARPORT_MODE_PCSPP;
X }
X
@@ -832,8 +832,11 @@
X * Put the ECP detected port in the more SPP like mode.
X */
X parport_pc_write_econtrol(p, 0x0);
- parport_pc_write_control(p, 0xc);
+ parport_pc_write_control(p, 0x8);
X parport_pc_write_data(p, 0);
+ udelay (50);
+ parport_pc_write_control(p, 0xc);
+ udelay (50);
X
X if (parport_probe_hook)
X (*parport_probe_hook)(p);
diff -u --recursive --new-file v2.2.9/linux/drivers/misc/parport_share.c linux/drivers/misc/parport_share.c
--- v2.2.9/linux/drivers/misc/parport_share.c Sun Nov 8 14:02:59 1998
+++ linux/drivers/misc/parport_share.c Mon Jun 7 14:49:10 1999
@@ -298,9 +298,9 @@
X port = dev->port;
X
X if (port->cad == dev) {
- printk(KERN_WARNING "%s: refused to unregister "
- "currently active device %s.\n", port->name, dev->name);
- return;
+ printk(KERN_DEBUG "%s: %s forgot to release port\n",
+ port->name, dev->name);
+ parport_release (dev);
X }
X
X spin_lock(&port->pardevice_lock);
diff -u --recursive --new-file v2.2.9/linux/drivers/net/3c515.c linux/drivers/net/3c515.c
--- v2.2.9/linux/drivers/net/3c515.c Fri Jan 8 22:36:06 1999
+++ linux/drivers/net/3c515.c Mon Jun 7 16:19:58 1999
@@ -1009,6 +1009,7 @@
X outb(0x00, ioaddr + TxStatus); /* Pop the status stack. */
X }
X }
+ vp->stats.tx_bytes+=skb->len;


X return 0;
X }
X

@@ -1209,6 +1210,7 @@
X netif_rx(skb);
X dev->last_rx = jiffies;
X vp->stats.rx_packets++;
+ vp->stats.rx_bytes+=skb->len;
X /* Wait a limited time to go to next packet. */
X for (i = 200; i >= 0; i--)
X if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
@@ -1256,6 +1258,7 @@
X short pkt_len = rx_status & 0x1fff;


X struct sk_buff *skb;
X

+ vp->stats.rx_bytes+=pkt_len;
X if (vortex_debug > 4)
X printk("Receiving packet size %d status %4.4x.\n",
X pkt_len, rx_status);
diff -u --recursive --new-file v2.2.9/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v2.2.9/linux/drivers/net/Config.in Tue Mar 23 14:35:47 1999
+++ linux/drivers/net/Config.in Mon Jun 7 14:35:22 1999
@@ -109,6 +109,7 @@
X fi
X if [ "$CONFIG_MCA" = "y" ]; then
X tristate 'NE/2 (ne2000 MCA version) support' CONFIG_NE2_MCA
+ tristate 'SKnet MCA support' CONFIG_SKMC
X fi
X bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA
X if [ "$CONFIG_NET_EISA" = "y" ]; then
diff -u --recursive --new-file v2.2.9/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v2.2.9/linux/drivers/net/Makefile Fri Apr 16 14:47:30 1999
+++ linux/drivers/net/Makefile Mon Jun 7 14:35:22 1999
@@ -486,6 +486,14 @@
X endif
X endif
X
+ifeq ($(CONFIG_SKMC),y)
+L_OBJS += sk_mca.o
+else
+ ifeq ($(CONFIG_SKMC),m)
+ M_OBJS += sk_mca.o
+ endif
+endif
+
X ifeq ($(CONFIG_ELMC_II),y)
X L_OBJS += 3c527.o
X else
diff -u --recursive --new-file v2.2.9/linux/drivers/net/Space.c linux/drivers/net/Space.c
--- v2.2.9/linux/drivers/net/Space.c Tue Mar 23 14:35:47 1999
+++ linux/drivers/net/Space.c Mon Jun 7 14:35:22 1999
@@ -69,6 +69,7 @@
X extern int wavelan_probe(struct device *);
X extern int el16_probe(struct device *);
X extern int elmc_probe(struct device *);
+extern int skmca_probe(struct device *);
X extern int elplus_probe(struct device *);
X extern int ac3200_probe(struct device *);
X extern int es_probe(struct device *);
@@ -266,6 +267,9 @@
X #endif
X #ifdef CONFIG_ELMC /* 3c523 */
X {elmc_probe, 0},
+#endif
+#ifdef CONFIG_SKMC /* SKnet Microchannel */
+ {skmca_probe, 0},
X #endif
X {NULL, 0},
X };
diff -u --recursive --new-file v2.2.9/linux/drivers/net/cosa.c linux/drivers/net/cosa.c
--- v2.2.9/linux/drivers/net/cosa.c Wed Mar 10 15:29:46 1999
+++ linux/drivers/net/cosa.c Mon Jun 7 16:19:58 1999
@@ -1,7 +1,10 @@
-/* $Id: cosa.c,v 1.21 1999/02/06 19:49:18 kas Exp $ */
+/* $Id: cosa.c,v 1.24 1999/05/28 17:28:34 kas Exp $ */
X
X /*
X * Copyright (C) 1995-1997 Jan "Yenya" Kasprzak <k...@fi.muni.cz>
+ *
+ * 5/25/1999 : Marcelo Tosatti <mar...@conectiva.com.br>
+ * fixed a deadlock in cosa_sppp_open
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
@@ -72,6 +75,10 @@
X * The Comtrol Hostess SV11 driver by Alan Cox
X * The Sync PPP/Cisco HDLC layer (syncppp.c) ported to Linux by Alan Cox
X */
+/*
+ * 5/25/1999 : Marcelo Tosatti <mar...@conectiva.com.br>
+ * fixed a deadlock in cosa_sppp_open
+ */
X
X /* ---------- Headers, macros, data structures ---------- */
X
@@ -598,6 +605,7 @@
X if (chan->usage != 0) {
X printk(KERN_WARNING "%s: sppp_open called with usage count %d\n",
X chan->name, chan->usage);
+ spin_unlock_irqrestore(&chan->cosa->lock, flags);
X return -EBUSY;
X }
X chan->setup_rx = sppp_setup_rx;
@@ -749,8 +757,13 @@
X
X static void chardev_channel_init(struct channel_data *chan)
X {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
X chan->rsem = MUTEX;
X chan->wsem = MUTEX;
+#else
+ init_MUTEX(&chan->rsem);
+ init_MUTEX(&chan->wsem);
+#endif
X }
X
X static long long cosa_lseek(struct file * file,
@@ -1260,8 +1273,10 @@
X debug_status_out(cosa, 0);
X #endif
X }
+ cosa_putdata8(cosa, 0);
X cosa_putdata8(cosa, status);
X #ifdef DEBUG_IO
+ debug_data_cmd(cosa, 0);
X debug_data_cmd(cosa, status);
X #endif
X }
@@ -1654,6 +1669,7 @@
X printk(KERN_WARNING
X "%s: No channel wants data in TX IRQ\n",
X cosa->name);
+ put_driver_status_nolock(cosa);
X clear_bit(TXBIT, &cosa->rxtx);
X spin_unlock_irqrestore(&cosa->lock, flags);
X return;
diff -u --recursive --new-file v2.2.9/linux/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c
--- v2.2.9/linux/drivers/net/cs89x0.c Tue Mar 23 14:35:47 1999
+++ linux/drivers/net/cs89x0.c Mon Jun 7 16:19:58 1999
@@ -739,7 +739,7 @@
X if (tickssofar < 5)
X return 1;
X if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name,
- tx_done(dev) ? "IRQ conflict" : "network cable problem");
+ tx_done(dev) ? "IRQ conflict ?" : "network cable problem");
X /* Try to restart the adaptor. */
X dev->tbusy=0;
X dev->trans_start = jiffies;
diff -u --recursive --new-file v2.2.9/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- v2.2.9/linux/drivers/net/eexpress.c Tue May 11 13:10:29 1999
+++ linux/drivers/net/eexpress.c Sun May 30 10:17:03 1999
@@ -81,7 +81,20 @@
X * ftp's, which is significantly better than I get in DOS, so the overhead of
X * stopping and restarting the CU with each transmit is not prohibitive in
X * practice.
+ *
+ * Update by David Woodhouse 11/5/99:
+ *
+ * I've seen "CU wedged" messages in 16-bit mode, on the Alpha architecture.
+ * I assume that this is because 16-bit accesses are actually handled as two
+ * 8-bit accesses.
X */
+
+#ifdef __alpha__
+#define LOCKUP16 1
+#endif
+#ifndef LOCKUP16
+#define LOCKUP16 0
+#endif
X
X #include <linux/config.h>
X #include <linux/module.h>
@@ -297,7 +310,7 @@
X outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config);
X }
X
-static inline short int SHADOW(short int addr)
+static inline unsigned short int SHADOW(short int addr)
X {
X addr &= 0x1f;
X if (addr > 0xf) addr += 0x3ff0;
@@ -400,7 +413,10 @@
X outb(0,ioaddr+SIGNAL_CA);
X free_irq(irq,dev);
X outb(i586_RST,ioaddr+EEPROM_Ctrl);
- release_region(ioaddr,16);
+ release_region(ioaddr, EEXP_IO_EXTENT);
+ release_region(ioaddr+0x4000, 16);
+ release_region(ioaddr+0x8000, 16);
+ release_region(ioaddr+0xc000, 16);
X
X MOD_DEC_USE_COUNT;
X return 0;
@@ -887,7 +903,7 @@
X struct net_local *lp = (struct net_local *)dev->priv;
X unsigned short ioaddr = dev->base_addr;
X
- if (lp->width) {
+ if (LOCKUP16 || lp->width) {
X /* Stop the CU so that there is no chance that it
X jumps off to a bogus address while we are writing the
X pointer to the next transmit packet in 8-bit mode --
@@ -927,7 +943,7 @@
X if (lp->tx_head != lp->tx_reap)
X dev->tbusy = 0;
X
- if (lp->width) {
+ if (LOCKUP16 || lp->width) {
X /* Restart the CU so that the packet can actually
X be transmitted. (Zoltan Szilagyi 10-12-96) */
X scb_command(dev, SCB_CUresume);
diff -u --recursive --new-file v2.2.9/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
--- v2.2.9/linux/drivers/net/ibmtr.c Tue May 11 13:10:29 1999
+++ linux/drivers/net/ibmtr.c Sun Jun 13 10:48:21 1999
@@ -513,7 +513,7 @@
X /* How much shared RAM is on adapter ? */
X #ifdef PCMCIA
X ti->avail_shared_ram = pcmcia_reality_check(get_sram_size(ti));
- ibmtr_mem_base = ti->sram_base ;
+ ibmtr_mem_base = ti->sram_base << 12 ;
X #else
X ti->avail_shared_ram = get_sram_size(ti);
X #endif
@@ -833,6 +833,9 @@
X (int)readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)));
X
X dev->start = 0;
+#ifdef PCMCIA
+ ti->sram = 0 ;
+#endif
X DPRINTK("Adapter closed.\n");
X MOD_DEC_USE_COUNT;
X
diff -u --recursive --new-file v2.2.9/linux/drivers/net/irda/Config.in linux/drivers/net/irda/Config.in
--- v2.2.9/linux/drivers/net/irda/Config.in Wed Mar 10 15:29:46 1999
+++ linux/drivers/net/irda/Config.in Mon Jun 7 16:19:58 1999
@@ -1,18 +1,25 @@
X mainmenu_option next_comment
X comment 'Infrared-port device drivers'
X
-dep_tristate 'IrTTY (uses serial driver)' CONFIG_IRTTY_SIR $CONFIG_IRDA
-if [ "$CONFIG_IRTTY_SIR" != "n" ]; then
- comment ' Dongle support'
- bool ' Serial dongle support' CONFIG_DONGLE
- if [ "$CONFIG_DONGLE" != "n" ]; then
- dep_tristate ' ESI JetEye PC dongle' CONFIG_ESI_DONGLE $CONFIG_IRTTY_SIR
- dep_tristate ' ACTiSYS IR-220L and IR220L+ dongle' CONFIG_ACTISYS_DONGLE $CONFIG_IRTTY_SIR
- dep_tristate ' Tekram IrMate 210B dongle' CONFIG_TEKRAM_DONGLE $CONFIG_IRTTY_SIR
- dep_tristate ' Greenwich GIrBIL dongle' CONFIG_GIRBIL_DONGLE $CONFIG_IRTTY_SIR
- fi
+comment 'SIR device drivers'
+dep_tristate 'IrTTY (uses Linux serial driver)' CONFIG_IRTTY_SIR $CONFIG_IRDA
+dep_tristate 'IrPORT (IrDA serial driver)' CONFIG_IRPORT_SIR $CONFIG_IRDA
+
+comment 'FIR device drivers'
+dep_tristate 'NSC PC87108' CONFIG_NSC_FIR $CONFIG_IRDA
+dep_tristate 'Winbond W83977AF (IR)' CONFIG_WINBOND_FIR $CONFIG_IRDA
+dep_tristate 'Sharp UIRCC' CONFIG_SHARP_FIR $CONFIG_IRDA
+dep_tristate 'Toshiba Type-O IR Port' CONFIG_TOSHIBA_FIR $CONFIG_IRDA
+dep_tristate 'SMC IrCC' CONFIG_SMC_IRCC_FIR $CONFIG_IRDA
+
+comment 'Dongle support'
+bool 'Serial dongle support' CONFIG_DONGLE
+if [ "$CONFIG_DONGLE" != "n" ]; then
+ dep_tristate ' ESI JetEye PC dongle' CONFIG_ESI_DONGLE $CONFIG_IRDA
+ dep_tristate ' ACTiSYS IR-220L and IR220L+ dongle' CONFIG_ACTISYS_DONGLE $CONFIG_IRDA
+ dep_tristate ' Tekram IrMate 210B dongle' CONFIG_TEKRAM_DONGLE $CONFIG_IRDA
+ dep_tristate ' Greenwich GIrBIL dongle' CONFIG_GIRBIL_DONGLE $CONFIG_IRDA
+ dep_tristate ' Parallax LiteLink dongle' CONFIG_LITELINK_DONGLE $CONFIG_IRDA
X fi
-dep_tristate ' NSC PC87108' CONFIG_NSC_FIR $CONFIG_IRDA
-dep_tristate ' Winbond W83977AF (IR)' CONFIG_WINBOND_FIR $CONFIG_IRDA
-dep_tristate ' Sharp UIRCC' CONFIG_SHARP_FIR $CONFIG_IRDA
+
X endmenu
diff -u --recursive --new-file v2.2.9/linux/drivers/net/irda/Makefile linux/drivers/net/irda/Makefile
--- v2.2.9/linux/drivers/net/irda/Makefile Fri Apr 16 14:47:30 1999
+++ linux/drivers/net/irda/Makefile Mon Jun 7 16:19:58 1999
@@ -20,6 +20,30 @@
X endif
X endif
X
+ifeq ($(CONFIG_IRPORT_SIR),y)
+L_OBJS += irport.o
+else
+ ifeq ($(CONFIG_IRPORT_SIR),m)
+ M_OBJS += irport.o
+ endif
+endif
+
+ifeq ($(CONFIG_IRPORT_SIR),y)
+L_OBJS += irport.o
+else
+ ifeq ($(CONFIG_IRPORT_SIR),m)
+ M_OBJS += irport.o
+ endif
+endif
+
+ifeq ($(CONFIG_IRPORT_SIR),y)
+L_OBJS += irport.o
+else
+ ifeq ($(CONFIG_IRPORT_SIR),m)
+ M_OBJS += irport.o
+ endif
+endif
+
X ifeq ($(CONFIG_NSC_FIR),y)
X L_OBJS += pc87108.o
X else
@@ -44,6 +68,38 @@
X endif
X endif
X
+ifeq ($(CONFIG_TOSHIBA_FIR),y)
+L_OBJS += toshoboe.o
+else
+ ifeq ($(CONFIG_TOSHIBA_FIR),m)
+ M_OBJS += toshoboe.o
+ endif
+endif
+
+ifeq ($(CONFIG_TOSHIBA_FIR),y)
+L_OBJS += toshoboe.o
+else
+ ifeq ($(CONFIG_TOSHIBA_FIR),m)
+ M_OBJS += toshoboe.o
+ endif
+endif
+
+ifeq ($(CONFIG_TOSHIBA_FIR),y)
+L_OBJS += toshoboe.o
+else
+ ifeq ($(CONFIG_TOSHIBA_FIR),m)
+ M_OBJS += toshoboe.o
+ endif
+endif
+
+ifeq ($(CONFIG_SMC_IRCC_FIR),y)
+L_OBJS += irport.o smc-ircc.o
+else
+ ifeq ($(CONFIG_SMC_IRCC_FIR),m)
+ M_OBJS += irport.o smc-ircc.o
+ endif
+endif
+
X ifeq ($(CONFIG_ESI_DONGLE),y)
X L_OBJS += esi.o
X else
@@ -73,6 +129,30 @@
X else
X ifeq ($(CONFIG_GIRBIL_DONGLE),m)
X M_OBJS += girbil.o
+ endif
+endif
+
+ifeq ($(CONFIG_LITELINK_DONGLE),y)
+L_OBJS += litelink.o
+else
+ ifeq ($(CONFIG_LITELINK_DONGLE),m)
+ M_OBJS += litelink.o
+ endif
+endif
+
+ifeq ($(CONFIG_LITELINK_DONGLE),y)
+L_OBJS += litelink.o
+else
+ ifeq ($(CONFIG_LITELINK_DONGLE),m)
+ M_OBJS += litelink.o
+ endif
+endif
+
+ifeq ($(CONFIG_LITELINK_DONGLE),y)
+L_OBJS += litelink.o
+else
+ ifeq ($(CONFIG_LITELINK_DONGLE),m)
+ M_OBJS += litelink.o
X endif
X endif
X
diff -u --recursive --new-file v2.2.9/linux/drivers/net/irda/actisys.c linux/drivers/net/irda/actisys.c
--- v2.2.9/linux/drivers/net/irda/actisys.c Wed Apr 28 11:37:30 1999
+++ linux/drivers/net/irda/actisys.c Mon Jun 7 16:19:58 1999
@@ -1,16 +1,16 @@
X /*********************************************************************
X *
X * Filename: actisys.c
- * Version: 0.5
+ * Version: 0.8
X * Description: Implementation for the ACTiSYS IR-220L and IR-220L+
X * dongles


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Wed Oct 21 20:02:35 1998
- * Modified at: Mon Apr 12 11:56:35 1999
+ * Modified at: Sun May 16 14:35:11 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

- * Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License as

@@ -29,22 +29,16 @@
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/irmod.h>
X #include <net/irda/irda_device.h>
-#include <net/irda/irtty.h>
X #include <net/irda/dongle.h>
X
-static void actisys_reset( struct irda_device *dev, int unused);
-static void actisys_open( struct irda_device *idev, int type);
-static void actisys_close( struct irda_device *dev);
+static void actisys_reset(struct irda_device *dev);
+static void actisys_open(struct irda_device *idev, int type);
+static void actisys_close(struct irda_device *dev);
X static void actisys_change_speed( struct irda_device *dev, int baudrate);
-static void actisys_reset( struct irda_device *dev, int unused);
-static void actisys_init_qos( struct irda_device *idev, struct qos_info *qos);
+static void actisys_init_qos(struct irda_device *idev, struct qos_info *qos);
X
X /* These are the baudrates supported */
X static int baud_rates[] = { 9600, 19200, 57600, 115200, 38400};
@@ -58,17 +52,37 @@
X actisys_init_qos,
X };
X
-__initfunc(void actisys_init(void))
+static struct dongle dongle_plus = {
+ ACTISYS_PLUS_DONGLE,
+ actisys_open,
+ actisys_close,
+ actisys_reset,
+ actisys_change_speed,
+ actisys_init_qos,
+};
+
+__initfunc(int actisys_init(void))
X {
- irtty_register_dongle(&dongle);
+ int ret;
+
+ ret = irda_device_register_dongle(&dongle);
+ if (ret < 0)
+ return ret;
+ ret = irda_device_register_dongle(&dongle_plus);
+ if (ret < 0) {
+ irda_device_unregister_dongle(&dongle);
+ return ret;


+ }
+ return 0;
X }
X

X void actisys_cleanup(void)
X {
- irtty_unregister_dongle(&dongle);
+ irda_device_unregister_dongle(&dongle);
+ irda_device_unregister_dongle(&dongle_plus);
X }
X
-static void actisys_open( struct irda_device *idev, int type)
+static void actisys_open(struct irda_device *idev, int type)
X {
X strcat(idev->description, " <-> actisys");
X
@@ -78,8 +92,11 @@
X MOD_INC_USE_COUNT;
X }
X
-static void actisys_close( struct irda_device *dev)
+static void actisys_close(struct irda_device *idev)
X {


+ /* Power off dongle */
+ irda_device_set_dtr_rts(idev, FALSE, FALSE);
+

X MOD_DEC_USE_COUNT;
X }
X
@@ -90,25 +107,16 @@
X * To cycle through the available baud rates, pulse RTS low for a few
X * ms.
X */
-static void actisys_change_speed( struct irda_device *idev, int baudrate)
+static void actisys_change_speed(struct irda_device *idev, int baudrate)
X {
- struct irtty_cb *self;
- struct tty_struct *tty;
- struct termios old_termios;
- int cflag;
X int current_baudrate;
X int index = 0;


X
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
X

- ASSERT( idev != NULL, return;);
- ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);


+ ASSERT(idev != NULL, return;);

+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);

X
- self = (struct irtty_cb *) idev->priv;
-
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == IRTTY_MAGIC, return;);
-
X current_baudrate = idev->qos.baud_rate.value;
X
X /* Find the correct baudrate index for the currently used baudrate */
@@ -117,69 +125,34 @@
X
X DEBUG( 4, __FUNCTION__ "(), index=%d\n", index);
X
- if ( !self->tty)
- return;
-
- tty = self->tty;
-
X /* Cycle through avaiable baudrates until we reach the correct one */
- while ( current_baudrate != baudrate) {
- DEBUG( 4, __FUNCTION__ "(), current baudrate = %d\n",
- baud_rates[index]);
+ while (current_baudrate != baudrate) {
+ DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n",
+ baud_rates[index]);
X
X /* Set DTR, clear RTS */
- irtty_set_dtr_rts(tty, TRUE, FALSE);
+ irda_device_set_dtr_rts(idev, TRUE, FALSE);
X
X /* Wait at a few ms */
X current->state = TASK_INTERRUPTIBLE;
X schedule_timeout(2);
X
X /* Set DTR, Set RTS */
- irtty_set_dtr_rts(tty, TRUE, TRUE);
+ irda_device_set_dtr_rts(idev, TRUE, TRUE);
X
X /* Wait at a few ms again */
X current->state = TASK_INTERRUPTIBLE;
- schedule_timeout( 2);
+ schedule_timeout(2);
X
X /* Go to next baudrate */
- if ( idev->io.dongle_id == ACTISYS_DONGLE)
+ if (idev->io.dongle_id == ACTISYS_DONGLE)
X index = (index+1) % 4; /* IR-220L */
X else
X index = (index+1) % 5; /* IR-220L+ */
X
X current_baudrate = baud_rates[index];
X }
- DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n",
- baud_rates[index]);
-
- /* Now change the speed of the serial port */
- old_termios = *(tty->termios);
- cflag = tty->termios->c_cflag;
-
- cflag &= ~CBAUD;
-
- switch ( baudrate) {
- case 9600:
- default:
- cflag |= B9600;
- break;
- case 19200:
- cflag |= B19200;
- break;
- case 38400:
- cflag |= B38400;
- break;
- case 57600:
- cflag |= B57600;
- break;
- case 115200:
- cflag |= B115200;
- break;
- }
-
- /* Change speed of serial port */
- tty->termios->c_cflag = cflag;
- tty->driver.set_termios( tty, &old_termios);
+ DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n",baud_rates[index]);
X }
X
X /*
@@ -191,32 +164,20 @@
X * 1. Clear DTR for a few ms.
X *
X */
-static void actisys_reset( struct irda_device *idev, int unused)
+static void actisys_reset(struct irda_device *idev)
X {
- struct irtty_cb *self;
- struct tty_struct *tty;
-
- ASSERT( idev != NULL, return;);
- ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
-
- self = (struct irtty_cb *) idev->priv;


+ ASSERT(idev != NULL, return;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);

X
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == IRTTY_MAGIC, return;);
-
- tty = self->tty;
- if ( !tty)
- return;
-
X /* Clear DTR */
- irtty_set_dtr_rts(tty, FALSE, TRUE);
+ irda_device_set_dtr_rts(idev, FALSE, TRUE);
X
X /* Sleep 10-20 ms*/
X current->state = TASK_INTERRUPTIBLE;
X schedule_timeout(2);
X
X /* Go back to normal mode */
- irtty_set_dtr_rts(tty, TRUE, TRUE);
+ irda_device_set_dtr_rts(idev, TRUE, TRUE);
X
X idev->qos.baud_rate.value = 9600;
X }
@@ -227,12 +188,12 @@
X * Initialize QoS capabilities
X *
X */
-static void actisys_init_qos( struct irda_device *idev, struct qos_info *qos)
+static void actisys_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
X /* Remove support for 38400 if this is not a 220L+ dongle */
- if ( idev->io.dongle_id == ACTISYS_DONGLE)
+ if (idev->io.dongle_id == ACTISYS_DONGLE)
X qos->baud_rate.bits &= ~IR_38400;
X
X qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */
@@ -251,8 +212,7 @@


X */
X int init_module(void)
X {

- actisys_init();
- return(0);
+ return actisys_init();
X }
X
X /*
diff -u --recursive --new-file v2.2.9/linux/drivers/net/irda/esi.c linux/drivers/net/irda/esi.c
--- v2.2.9/linux/drivers/net/irda/esi.c Wed Apr 28 11:37:30 1999
+++ linux/drivers/net/irda/esi.c Mon Jun 7 16:19:59 1999
@@ -1,17 +1,17 @@
X /*********************************************************************
X *
X * Filename: esi.c
- * Version: 1.2
+ * Version: 1.4
X * Description: Driver for the Extended Systems JetEye PC dongle
X * Status: Experimental.
X * Author: Thomas Davis, <rat...@radiks.net>
X * Created at: Sat Feb 21 18:54:38 1998
- * Modified at: Mon Apr 12 11:55:30 1999
+ * Modified at: Sun May 16 14:35:21 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>

X * Sources: esi.c
X *
+ * Copyright (c) 1998-1999, Dag Brattli, <da...@cs.uit.no>
X * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>,
- * Copyright (c) 1998, Dag Brattli, <da...@cs.uit.no>
X * All Rights Reserved.


X *
X * This program is free software; you can redistribute it and/or

@@ -31,21 +31,17 @@
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/irmod.h>
X #include <net/irda/irda_device.h>
X #include <net/irda/irtty.h>
X #include <net/irda/dongle.h>
X
-static void esi_open( struct irda_device *idev, int type);
-static void esi_close( struct irda_device *driver);
-static void esi_change_speed( struct irda_device *idev, int baud);
-static void esi_reset( struct irda_device *idev, int unused);
-static void esi_qos_init( struct irda_device *idev, struct qos_info *qos);
+static void esi_open(struct irda_device *idev, int type);
+static void esi_close(struct irda_device *driver);
+static void esi_change_speed(struct irda_device *idev, int baud);
+static void esi_reset(struct irda_device *idev);
+static void esi_qos_init(struct irda_device *idev, struct qos_info *qos);
X
X static struct dongle dongle = {
X ESI_DONGLE,
@@ -58,17 +54,17 @@
X
X __initfunc(int esi_init(void))
X {
- return irtty_register_dongle(&dongle);
+ return irda_device_register_dongle(&dongle);
X }
X
X void esi_cleanup(void)
X {
- irtty_unregister_dongle( &dongle);
+ irda_device_unregister_dongle(&dongle);
X }
X
-static void esi_open( struct irda_device *idev, int type)
+static void esi_open(struct irda_device *idev, int type)
X {
- strcat( idev->description, " <-> esi");
+ strcat(idev->description, " <-> esi");
X
X idev->io.dongle_id = type;
X idev->flags |= IFF_DONGLE;
@@ -76,8 +72,11 @@
X MOD_INC_USE_COUNT;
X }
X
-static void esi_close( struct irda_device *driver)
-{
+static void esi_close(struct irda_device *idev)


+{
+ /* Power off dongle */
+ irda_device_set_dtr_rts(idev, FALSE, FALSE);
+

X MOD_DEC_USE_COUNT;
X }
X
@@ -87,57 +86,33 @@
X * Set the speed for the Extended Systems JetEye PC ESI-9680 type dongle
X *
X */
-static void esi_change_speed( struct irda_device *idev, int baud)
+static void esi_change_speed(struct irda_device *idev, int baud)
X {
- struct irtty_cb *self;
- struct tty_struct *tty;
X int dtr, rts;
- struct termios old_termios;
- int cflag;
X
- ASSERT( idev != NULL, return;);
- ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);


+ ASSERT(idev != NULL, return;);

+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);

X
- self = (struct irtty_cb *) idev->priv;
-
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == IRTTY_MAGIC, return;);
-
- if ( !self->tty)
- return;
-
- tty = self->tty;
-
- old_termios = *(tty->termios);
- cflag = tty->termios->c_cflag;
-
- cflag &= ~CBAUD;
-
X switch (baud) {
X case 19200:
- cflag |= B19200;
X dtr = TRUE;
X rts = FALSE;
X break;
X case 115200:
- cflag |= B115200;
X dtr = rts = TRUE;
X break;
X case 9600:
X default:
- cflag |= B9600;
X dtr = FALSE;
X rts = TRUE;
X break;
X }
- /* Change speed of serial driver */
- tty->termios->c_cflag = cflag;
- tty->driver.set_termios(tty, &old_termios);
X
- irtty_set_dtr_rts(tty, dtr, rts);
+ /* Change speed of dongle */
+ irda_device_set_dtr_rts(idev, dtr, rts);
X }
X
-static void esi_reset( struct irda_device *idev, int unused)
+static void esi_reset( struct irda_device *idev)
X {
X /* Empty */
X }
@@ -148,14 +123,17 @@
X * Init QoS capabilities for the dongle
X *
X */
-static void esi_qos_init( struct irda_device *idev, struct qos_info *qos)
+static void esi_qos_init(struct irda_device *idev, struct qos_info *qos)
X {
X qos->baud_rate.bits &= IR_9600|IR_19200|IR_115200;
X qos->min_turn_time.bits &= 0x01; /* Needs at least 10 ms */


X }
X
X #ifdef MODULE

-

+
+MODULE_AUTHOR("Dag Brattli <da...@cs.uit.no>");

+MODULE_DESCRIPTION("Extended Systems JetEye PC dongle driver");
+
X /*
X * Function init_module (void)
X *
diff -u --recursive --new-file v2.2.9/linux/drivers/net/irda/girbil.c linux/drivers/net/irda/girbil.c
--- v2.2.9/linux/drivers/net/irda/girbil.c Wed Apr 28 11:37:30 1999
+++ linux/drivers/net/irda/girbil.c Mon Jun 7 16:19:59 1999
@@ -1,12 +1,12 @@
X /*********************************************************************
X *
X * Filename: girbil.c
- * Version: 1.0
+ * Version: 1.1
X * Description: Implementation for the Greenwich GIrBIL dongle


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sat Feb 6 21:02:33 1999
- * Modified at: Sat Apr 10 19:53:12 1999
+ * Modified at: Tue Jun 1 08:47:41 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

X * Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -28,17 +28,13 @@
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/irmod.h>
X #include <net/irda/irda_device.h>
X #include <net/irda/irtty.h>
X #include <net/irda/dongle.h>
X
-static void girbil_reset(struct irda_device *dev, int unused);
+static void girbil_reset(struct irda_device *dev);
X static void girbil_open(struct irda_device *dev, int type);
X static void girbil_close(struct irda_device *dev);
X static void girbil_change_speed(struct irda_device *dev, int baud);
@@ -80,19 +76,19 @@
X girbil_init_qos,
X };
X
-__initfunc(void girbil_init(void))
+__initfunc(int girbil_init(void))
X {
- irtty_register_dongle(&dongle);
+ return irda_device_register_dongle(&dongle);
X }
X
X void girbil_cleanup(void)
X {
- irtty_unregister_dongle(&dongle);
+ irda_device_unregister_dongle(&dongle);
X }
X
X static void girbil_open(struct irda_device *idev, int type)
X {
- strcat( idev->description, " <-> girbil");
+ strcat(idev->description, " <-> girbil");
X
X idev->io.dongle_id = type;
X idev->flags |= IFF_DONGLE;
@@ -100,8 +96,11 @@
X MOD_INC_USE_COUNT;
X }
X
-static void girbil_close(struct irda_device *dev)
+static void girbil_close(struct irda_device *idev)
X {


+ /* Power off dongle */
+ irda_device_set_dtr_rts(idev, FALSE, FALSE);
+

X MOD_DEC_USE_COUNT;
X }
X
@@ -114,71 +113,42 @@
X */
X static void girbil_change_speed(struct irda_device *idev, int speed)
X {
- struct irtty_cb *self;
- struct tty_struct *tty;
- struct termios old_termios;
- int cflag;
X __u8 control[2];


X
X ASSERT(idev != NULL, return;);
X ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
X

- self = (struct irtty_cb *) idev->priv;


-
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRTTY_MAGIC, return;);
-

- if (!self->tty)
- return;
-
- tty = self->tty;
-
- old_termios = *(tty->termios);
- cflag = tty->termios->c_cflag;
-
- cflag &= ~CBAUD;
-
X switch (speed) {
X case 9600:
X default:
- cflag |= B9600;
X control[0] = GIRBIL_9600;
X break;
X case 19200:
- cflag |= B19200;
X control[0] = GIRBIL_19200;
X break;
X case 34800:
- cflag |= B38400;
X control[0] = GIRBIL_38400;
X break;
X case 57600:
- cflag |= B57600;
X control[0] = GIRBIL_57600;
X break;
X case 115200:
- cflag |= B115200;
X control[0] = GIRBIL_115200;
X break;
X }
X control[1] = GIRBIL_LOAD;
X
X /* Set DTR and Clear RTS to enter command mode */
- irtty_set_dtr_rts(tty, FALSE, TRUE);
+ irda_device_set_dtr_rts(idev, FALSE, TRUE);
X
X /* Write control bytes */
- if (tty->driver.write)
- tty->driver.write(self->tty, 0, control, 2);
+ irda_device_raw_write(idev, control, 2);
X
X current->state = TASK_INTERRUPTIBLE;
X schedule_timeout(2);
X
X /* Go back to normal mode */
- irtty_set_dtr_rts(tty, TRUE, TRUE);
-
- /* Now change the speed of the serial port */
- tty->termios->c_cflag = cflag;
- tty->driver.set_termios(tty, &old_termios);
+ irda_device_set_dtr_rts(idev, TRUE, TRUE);
X }
X
X /*
@@ -191,46 +161,38 @@
X * 0. set RTS, and wait at least 5 ms
X * 1. clear RTS
X */
-void girbil_reset(struct irda_device *idev, int unused)
+void girbil_reset(struct irda_device *idev)
X {
- struct irtty_cb *self;
- struct tty_struct *tty;
X __u8 control = GIRBIL_TXEN | GIRBIL_RXEN;


X
X ASSERT(idev != NULL, return;);
X ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
X

- self = (struct irtty_cb *) idev->priv;


-
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRTTY_MAGIC, return;);
-

- tty = self->tty;
- if (!tty)
- return;
-
X /* Reset dongle */
- irtty_set_dtr_rts(tty, TRUE, FALSE);
+ irda_device_set_dtr_rts(idev, TRUE, FALSE);
X
X /* Sleep at least 5 ms */
X current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(2);
+ schedule_timeout(MSECS_TO_JIFFIES(20));
X
X /* Set DTR and clear RTS to enter command mode */
- irtty_set_dtr_rts(tty, FALSE, TRUE);
+ irda_device_set_dtr_rts(idev, FALSE, TRUE);
X
X current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(2);
+ schedule_timeout(MSECS_TO_JIFFIES(20));
X
X /* Write control byte */
- if (tty->driver.write)
- tty->driver.write(self->tty, 0, &control, 1);
+ irda_device_raw_write(idev, &control, 1);
X
X current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(2);
+ schedule_timeout(MSECS_TO_JIFFIES(20));
X
X /* Go back to normal mode */
- irtty_set_dtr_rts(tty, TRUE, TRUE);


+ irda_device_set_dtr_rts(idev, TRUE, TRUE);
+

+ /* Make sure the IrDA chip also goes to defalt speed */


+ if (idev->change_speed)
+ idev->change_speed(idev, 9600);

X }
X
X /*
@@ -242,7 +204,7 @@
X static void girbil_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;
- qos->min_turn_time.bits &= 0xfe; /* All except 0 ms */
+ qos->min_turn_time.bits &= 0x03;


X }
X
X #ifdef MODULE

@@ -258,8 +220,7 @@


X */
X int init_module(void)
X {

- girbil_init();
- return(0);
+ return girbil_init();
X }
X
X /*
diff -u --recursive --new-file v2.2.9/linux/drivers/net/irda/irport.c linux/drivers/net/irda/irport.c
--- v2.2.9/linux/drivers/net/irda/irport.c Wed Apr 28 11:37:30 1999
+++ linux/drivers/net/irda/irport.c Sun Jun 13 10:48:21 1999
@@ -1,43 +1,38 @@
X /*********************************************************************
- *
+ *
X * Filename: irport.c
- * Version: 0.9
- * Description: Serial driver for IrDA.
+ * Version: 1.0
+ * Description: Half duplex serial port SIR driver for IrDA.

X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sun Aug 3 13:49:59 1997
- * Modified at: Sat May 23 23:15:20 1998
+ * Modified at: Tue Jun 1 10:02:42 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>

X * Sources: serial.c by Linus Torvalds
X *
- * Copyright (c) 1997,1998 Dag Brattli <da...@cs.uit.no>
- * All Rights Reserved.
+ * Copyright (c) 1997, 1998, 1999 Dag Brattli, All Rights Reserved.


X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License as

X * published by the Free Software Foundation; either version 2 of
X * the License, or (at your option) any later version.
- *
- * Neither Dag Brattli nor University of Tromsø admit liability nor
- * provide warranty for any of this software. This material is
- * provided "AS-IS" and at no charge.
- *
- * NOTICE:


+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA

X *
X * This driver is ment to be a small half duplex serial driver to be
- * used for IR-chipsets that has a UART (16550) compatibility mode. If
- * your chipset is is UART only, you should probably use IrTTY instead
- * since the Linux serial driver is probably more robust and optimized.
- *
- * The functions in this file may be used by FIR drivers, but this
- * driver knows nothing about FIR drivers so don't ever insert such
- * code into this file. Instead you should code your FIR driver in a
- * separate file, and then call the functions in this file if
- * necessary. This is becase it is difficult to use the Linux serial
- * driver with a FIR driver becase they must share interrupts etc. Most
- * FIR chipsets can function in advanced SIR mode, and you should
- * probably use that mode instead of the UART compatibility mode (and
- * then just forget about this file)
+ * used for IR-chipsets that has a UART (16550) compatibility mode.
+ * Eventually it will replace irtty, because of irtty has some
+ * problems that is hard to get around when we don't have control
+ * over the serial driver. This driver may also be used by FIR
+ * drivers to handle SIR mode for them.


X *
X ********************************************************************/
X

@@ -48,14 +43,15 @@
X #include <linux/ioport.h>
X #include <linux/malloc.h>
X #include <linux/string.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
+#include <linux/skbuff.h>
+#include <linux/serial_reg.h>
X #include <linux/errno.h>
X #include <linux/init.h>
X
-#include <linux/skbuff.h>
-#include <linux/serial_reg.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/spinlock.h>
X
X #include <net/irda/irda.h>
X #include <net/irda/irmod.h>
@@ -64,105 +60,254 @@
X

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

echo 'End of part 06'
echo 'File patch-2.2.10 is continued in part 07'
echo 07 > _shar_seq_.tmp
exit 0

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.2/patch-2.2.10/part09

#!/bin/sh
# this is part 09 of a 22 - part archive


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

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

+ __u8 hcr;
+#endif
+ DEBUG(4, __FUNCTION__ "(), len=%d\n", idev->tx_buff.len);
X
X /* Save current set */
- set = inb( iobase+SSR);
+ set = inb(iobase+SSR);
X
X /* Disable DMA */
X switch_bank(iobase, SET0);
- outb( inb( iobase+HCR) & ~HCR_EN_DMA, iobase+HCR);
-
- setup_dma(idev->io.dma, idev->tx_buff.data, idev->tx_buff.len,
- DMA_MODE_WRITE);
-

- /* idev->media_busy = TRUE; */

- idev->io.direction = IO_XMIT;
-
+ outb(inb(iobase+HCR) & ~HCR_EN_DMA, iobase+HCR);
+


X /* Choose transmit DMA channel */

X switch_bank(iobase, SET2);
- outb(inb(iobase+ADCR1) | ADCR1_D_CHSW|ADCR1_DMA_F|ADCR1_ADV_SL,
- iobase+ADCR1);
+ outb(ADCR1_D_CHSW|/*ADCR1_DMA_F|*/ADCR1_ADV_SL, iobase+ADCR1);
+#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS
+ save_flags(flags);
+ cli();
+
+ disable_dma(idev->io.dma);
+ clear_dma_ff(idev->io.dma);
+ set_dma_mode(idev->io.dma, DMA_MODE_READ);
+ set_dma_addr(idev->io.dma, virt_to_bus(idev->tx_buff.data));
+ set_dma_count(idev->io.dma, idev->tx_buff.len);
+#else
+ setup_dma(idev->io.dma, idev->tx_buff.data, idev->tx_buff.len,
+ DMA_MODE_WRITE);
+#endif
+ idev->io.direction = IO_XMIT;
X
X /* Enable DMA */
X switch_bank(iobase, SET0);
- outb(inb(iobase+HCR) | HCR_EN_DMA, iobase+HCR);
-
+#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS
+ hcr = inb(iobase+HCR);
+ outb(hcr | HCR_EN_DMA, iobase+HCR);
+ enable_dma(idev->io.dma);
+ restore_flags(flags);
+#else
+ outb(inb(iobase+HCR) | HCR_EN_DMA | HCR_TX_WT, iobase+HCR);
+#endif
+
X /* Restore set register */
X outb(set, iobase+SSR);
X }
@@ -577,17 +603,17 @@


X int actual = 0;

X __u8 set;


X
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
X

X /* Save current bank */

- set = inb( iobase+SSR);
+ set = inb(iobase+SSR);
X
- switch_bank( iobase, SET0);
+ switch_bank(iobase, SET0);
X if (!(inb_p(iobase+USR) & USR_TSRE)) {
- DEBUG( 4, __FUNCTION__ "(), warning, FIFO not empty yet!\n");
+ DEBUG(4, __FUNCTION__ "(), warning, FIFO not empty yet!\n");
X
X fifo_size -= 17;
- DEBUG( 4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size);
+ DEBUG(4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size);


X }
X
X /* Fill FIFO with current frame */

@@ -597,7 +623,7 @@
X }

X
X DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n",
- fifo_size, actual, len);


+ fifo_size, actual, len);
X
X /* Restore bank */

X outb(set, iobase+SSR);
@@ -617,7 +643,7 @@
X int iobase;
X __u8 set;
X
- DEBUG(4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "(%ld)\n", jiffies);


X
X ASSERT(idev != NULL, return;);
X ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);

@@ -663,9 +689,10 @@
X */
X int w83977af_dma_receive(struct irda_device *idev)
X {
+ struct w83977af_ir *self;
X int iobase;
X __u8 set;
-#ifdef NETWINDER
+#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
X unsigned long flags;
X __u8 hcr;
X #endif
@@ -673,62 +700,60 @@
X ASSERT(idev != NULL, return -1;);
X ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
X
- DEBUG(0, __FUNCTION__ "\n");
+ DEBUG(4, __FUNCTION__ "\n");
X

+ self = idev->priv;

X iobase= idev->io.iobase;
X
X /* Save current set */
- set = inb( iobase+SSR);
+ set = inb(iobase+SSR);
X
X /* Disable DMA */
- switch_bank( iobase, SET0);
- outb( inb( iobase+HCR) & ~HCR_EN_DMA, iobase+HCR);
+ switch_bank(iobase, SET0);
+ outb(inb(iobase+HCR) & ~HCR_EN_DMA, iobase+HCR);
+
+ /* Choose DMA Rx, DMA Fairness, and Advanced mode */
+ switch_bank(iobase, SET2);
+ outb((inb(iobase+ADCR1) & ~ADCR1_D_CHSW)/*|ADCR1_DMA_F*/|ADCR1_ADV_SL,
+ iobase+ADCR1);
+
+ idev->io.direction = IO_RECV;
+ idev->rx_buff.data = idev->rx_buff.head;
X
-#ifdef NETWINDER
+#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
X save_flags(flags);
X cli();
X
- disable_dma( idev->io.dma);
- clear_dma_ff( idev->io.dma);
- set_dma_mode( idev->io.dma, DMA_MODE_READ);
- set_dma_addr( idev->io.dma, virt_to_bus(idev->rx_buff.data));
- set_dma_count( idev->io.dma, idev->rx_buff.truesize);
+ disable_dma(idev->io.dma);
+ clear_dma_ff(idev->io.dma);
+ set_dma_mode(idev->io.dma, DMA_MODE_READ);
+ set_dma_addr(idev->io.dma, virt_to_bus(idev->rx_buff.data));
+ set_dma_count(idev->io.dma, idev->rx_buff.truesize);
X #else
- setup_dma(idev->io.dma, idev->rx_buff.data,
- idev->rx_buff.truesize, DMA_MODE_READ);
+ setup_dma(idev->io.dma, idev->rx_buff.data, idev->rx_buff.truesize,
+ DMA_MODE_READ);
X #endif
- /* driver->media_busy = FALSE; */
- idev->io.direction = IO_RECV;
- idev->rx_buff.data = idev->rx_buff.head;
-
X /*
X * Reset Rx FIFO. This will also flush the ST_FIFO, it's very
X * important that we don't reset the Tx FIFO since it might not
X * be finished transmitting yet
X */
- outb( UFR_RXTL|UFR_TXTL|UFR_RXF_RST|UFR_EN_FIFO, iobase+UFR);
- prev.status = 0;
-
- /* Choose DMA Rx, DMA Fairness, and Advanced mode */
- switch_bank(iobase, SET2);
- outb(( inb( iobase+ADCR1) & ~ADCR1_D_CHSW)|ADCR1_DMA_F|ADCR1_ADV_SL,
- iobase+ADCR1);
+ switch_bank(iobase, SET0);
+ outb(UFR_RXTL|UFR_TXTL|UFR_RXF_RST|UFR_EN_FIFO, iobase+UFR);
+ self->st_fifo.len = self->st_fifo.tail = self->st_fifo.head = 0;
X
X /* Enable DMA */
X switch_bank(iobase, SET0);
-#ifdef NETWINDER
- hcr = inb( iobase+HCR);
- enable_dma( idev->io.dma);
- outb( hcr | HCR_EN_DMA, iobase+HCR);
+#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
+ hcr = inb(iobase+HCR);
+ outb(hcr | HCR_EN_DMA, iobase+HCR);
+ enable_dma(idev->io.dma);
X restore_flags(flags);
X #else
- outb( inb( iobase+HCR) | HCR_EN_DMA, iobase+HCR);
+ outb(inb(iobase+HCR) | HCR_EN_DMA, iobase+HCR);
X #endif
-
X /* Restore set */
- outb( set, iobase+SSR);
-
- DEBUG( 4, __FUNCTION__ "(), done!\n");
+ outb(set, iobase+SSR);
X
X return 0;
X }
@@ -742,12 +767,17 @@
X int w83977af_dma_receive_complete(struct irda_device *idev)


X {
X struct sk_buff *skb;

+ struct w83977af_ir *self;
+ struct st_fifo *st_fifo;
X int len;
X int iobase;
X __u8 set;
X __u8 status;
X
- DEBUG(0, __FUNCTION__ "\n");
+ DEBUG(4, __FUNCTION__ "\n");


+
+ self = idev->priv;

+ st_fifo = &self->st_fifo;


X
X iobase = idev->io.iobase;

X
@@ -756,22 +786,28 @@


X
X iobase = idev->io.iobase;

X
+ /* Read status FIFO */
X switch_bank(iobase, SET5);
- if (prev.status & FS_FO_FSFDR) {
- status = prev.status;
- len = prev.len;
+ while ((status = inb(iobase+FS_FO)) & FS_FO_FSFDR) {
+ st_fifo->entries[st_fifo->tail].status = status;
X
- prev.status = 0;
- } else {
- status = inb(iobase+FS_FO);
- len = inb(iobase+RFLFL);
- len |= inb(iobase+RFLFH) << 8;
+ st_fifo->entries[st_fifo->tail].len = inb(iobase+RFLFL);
+ st_fifo->entries[st_fifo->tail].len |= inb(iobase+RFLFH) << 8;
+
+ st_fifo->tail++;
+ st_fifo->len++;
X }
+
+ while (st_fifo->len) {
+ /* Get first entry */


+ status = st_fifo->entries[st_fifo->head].status;
+ len = st_fifo->entries[st_fifo->head].len;

+ st_fifo->head++;
+ st_fifo->len--;
X
- while (status & FS_FO_FSFDR) {


X /* Check for errors */

X if (status & FS_FO_ERR_MSK) {
- if ( status & FS_FO_LST_FR) {
+ if (status & FS_FO_LST_FR) {


X /* Add number of lost frames to stats */
X idev->stats.rx_errors += len;
X } else {

@@ -800,14 +836,20 @@
X /* Check if we have transfered all data to memory */
X switch_bank(iobase, SET0);
X if (inb(iobase+USR) & USR_RDR) {
+#ifdef CONFIG_USE_INTERNAL_TIMER
X /* Put this entry back in fifo */
- prev.status = status;
- prev.len = len;
-
+ st_fifo->head--;
+ st_fifo->len++;
+ st_fifo->entries[st_fifo->head].status = status;
+ st_fifo->entries[st_fifo->head].len = len;
+
X /* Restore set register */
- outb( set, iobase+SSR);
+ outb(set, iobase+SSR);
X
X return FALSE; /* I'll be back! */
+#else
+ udelay(80); /* Should be enough!? */
+#endif
X }
X
X skb = dev_alloc_skb(len+1);
@@ -824,28 +866,23 @@
X skb_reserve(skb, 1);
X
X /* Copy frame without CRC */
- if ( idev->io.baudrate < 4000000) {
- skb_put( skb, len-2);
- memcpy( skb->data, idev->rx_buff.data, len-2);
+ if (idev->io.baudrate < 4000000) {
+ skb_put(skb, len-2);
+ memcpy(skb->data, idev->rx_buff.data, len-2);
X } else {
- skb_put( skb, len-4);
- memcpy( skb->data, idev->rx_buff.data, len-4);
+ skb_put(skb, len-4);
+ memcpy(skb->data, idev->rx_buff.data, len-4);
X }
X
X /* Move to next frame */
X idev->rx_buff.data += len;
+ idev->stats.rx_packets++;
X
X skb->dev = &idev->netdev;
X skb->mac.raw = skb->data;
X skb->protocol = htons(ETH_P_IRDA);
- netif_rx( skb);
- idev->stats.rx_packets++;
+ netif_rx(skb);
X }
- /* Read next entry in ST_FIFO */
- switch_bank(iobase, SET5);
- status = inb( iobase+FS_FO);
- len = inb( iobase+RFLFL);
- len |= inb( iobase+RFLFH) << 8;
X }
X /* Restore set register */
X outb(set, iobase+SSR);
@@ -875,7 +912,6 @@
X do {
X byte = inb(iobase+RBR);
X async_unwrap_char(idev, byte);
-
X } while (inb(iobase+USR) & USR_RDR); /* Data available */
X }
X
@@ -889,9 +925,12 @@
X {
X int actual;
X __u8 new_icr = 0;
+ __u8 set;
+ int iobase;
X
X DEBUG(4, __FUNCTION__ "(), isr=%#x\n", isr);
X

+ iobase = idev->io.iobase;

X /* Transmit FIFO low on data */
X if (isr & ISR_TXTH_I) {


X /* Write data left in transmit buffer */

@@ -899,16 +938,21 @@
X idev->tx_buff.data,
X idev->tx_buff.len,
X idev->io.fifo_size);
+
X idev->tx_buff.data += actual;
X idev->tx_buff.len -= actual;
X

X idev->io.direction = IO_XMIT;
X

X /* Check if finished */
- if (idev->tx_buff.len > 0)
+ if (idev->tx_buff.len > 0) {
X new_icr |= ICR_ETXTHI;
- else {
- DEBUG( 4, __FUNCTION__ "(), finished with frame!\n");
+ } else {
+ set = inb(iobase+SSR);
+ switch_bank(iobase, SET0);
+ outb(AUDR_SFEND, iobase+AUDR);
+ outb(set, iobase+SSR);
+
X idev->netdev.tbusy = 0; /* Unlock */
X idev->stats.tx_packets++;
X
@@ -917,7 +961,6 @@
X
X new_icr |= ICR_ETBREI;
X }
-
X }
X /* Check if transmission has completed */
X if (isr & ISR_TXEMP_I) {
@@ -943,22 +986,20 @@
X * Handle MIR/FIR interrupt
X *
X */
-static __u8 w83977af_fir_interrupt( struct irda_device *idev, int isr)
+static __u8 w83977af_fir_interrupt(struct irda_device *idev, int isr)
X {
X __u8 new_icr = 0;
X __u8 set;
X int iobase;
X
- DEBUG( 4, __FUNCTION__ "(), isr=%#x\n", isr);
-


X iobase = idev->io.iobase;

-
X set = inb(iobase+SSR);
X
X /* End of frame detected in FIFO */
X if (isr & (ISR_FEND_I|ISR_FSF_I)) {
X if (w83977af_dma_receive_complete(idev)) {
X
+ /* Wait for next status FIFO interrupt */
X new_icr |= ICR_EFSFI;
X } else {
X /* DMA not finished yet */


@@ -982,7 +1023,7 @@
X

X /* Clear timer event */
X /* switch_bank(iobase, SET0); */
-/* outb( ASCR_CTE, iobase+ASCR); */
+/* outb(ASCR_CTE, iobase+ASCR); */
X
X /* Check if this is a TX timer interrupt */
X if (idev->io.direction == IO_XMIT) {
@@ -998,15 +1039,18 @@
X }
X /* Finished with DMA */
X if (isr & ISR_DMA_I) {
- w83977af_dma_xmit_complete( idev);
-
+ w83977af_dma_xmit_complete(idev);
+
X /* Check if there are more frames to be transmitted */
- if (irda_device_txqueue_empty( idev)) {
+ /* if (irda_device_txqueue_empty(idev)) { */
X
- /* Prepare for receive */
- w83977af_dma_receive(idev);
- new_icr = ICR_EFSFI;
- }
+ /* Prepare for receive
+ *
+ * ** Netwinder Tx DMA likes that we do this anyway **
+ */
+ w83977af_dma_receive(idev);
+ new_icr = ICR_EFSFI;
+ /* } */
X }
X
X /* Restore set */
@@ -1030,7 +1074,7 @@
X
X if (idev == NULL) {
X printk(KERN_WARNING "%s: irq %d for unknown device.\n",
- driver_name, irq);
+ driver_name, irq);
X return;
X }
X
@@ -1049,7 +1093,7 @@
X
X if (isr) {
X /* Dispatch interrupt handler for the current speed */
- if ( idev->io.baudrate > 115200)
+ if (idev->io.baudrate > PIO_MAX_SPEED )
X icr = w83977af_fir_interrupt(idev, isr);
X else
X icr = w83977af_sir_interrupt(idev, isr);
@@ -1070,7 +1114,7 @@
X static void w83977af_wait_until_sent(struct irda_device *idev)


X {
X current->state = TASK_INTERRUPTIBLE;

- schedule_timeout(6);
+ schedule_timeout(60*HZ/1000);
X }
X
X /*
@@ -1085,16 +1129,16 @@
X int iobase;
X __u8 set;
X
- ASSERT( idev != NULL, return FALSE;);
- ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return FALSE;);
+ ASSERT(idev != NULL, return FALSE;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return FALSE;);
X
- if ( idev->io.baudrate > 115200) {
+ if (idev->io.baudrate > 115200) {


X iobase = idev->io.iobase;

X
X /* Check if rx FIFO is not empty */
X set = inb(iobase+SSR);
- switch_bank( iobase, SET2);
- if (( inb( iobase+RXFDTH) & 0x3f) != 0) {
+ switch_bank(iobase, SET2);
+ if ((inb(iobase+RXFDTH) & 0x3f) != 0) {
X /* We are receiving something */
X status = TRUE;
X }
@@ -1111,12 +1155,12 @@
X *
X *
X */
-static int w83977af_net_init( struct device *dev)
+static int w83977af_net_init(struct device *dev)
X {
X DEBUG(0, __FUNCTION__ "()\n");
X

X /* Set up to be a normal IrDA network device driver */

- irda_device_setup( dev);
+ irda_device_setup(dev);
X
X /* Insert overrides below this line! */
X
@@ -1130,7 +1174,7 @@
X * Start the device
X *
X */
-static int w83977af_net_open( struct device *dev)
+static int w83977af_net_open(struct device *dev)


X {
X struct irda_device *idev;

X int iobase;
@@ -1147,7 +1191,7 @@
X iobase = idev->io.iobase;
X
X if (request_irq(idev->io.irq, w83977af_interrupt, 0, idev->name,
- (void *) idev)) {
+ (void *) idev)) {
X return -EAGAIN;
X }
X /*
@@ -1170,13 +1214,13 @@
X /* Enable some interrupts so we can receive frames again */
X switch_bank(iobase, SET0);
X if (idev->io.baudrate > 115200) {
- outb( ICR_EFSFI, iobase+ICR);
- w83977af_dma_receive( idev);
+ outb(ICR_EFSFI, iobase+ICR);
+ w83977af_dma_receive(idev);
X } else
- outb( ICR_ERBRI, iobase+ICR);
+ outb(ICR_ERBRI, iobase+ICR);


X
X /* Restore bank register */

- outb( set, iobase+SSR);
+ outb(set, iobase+SSR);
X
X MOD_INC_USE_COUNT;
X
@@ -1195,34 +1239,34 @@
X int iobase;
X __u8 set;
X
- DEBUG( 0, __FUNCTION__ "()\n");
+ DEBUG(0, __FUNCTION__ "()\n");
X
X /* Stop device */
X dev->tbusy = 1;


X dev->start = 0;

X
- ASSERT( dev != NULL, return -1;);


+ ASSERT(dev != NULL, return -1;);

X idev = (struct irda_device *) dev->priv;

X
- ASSERT( idev != NULL, return 0;);
- ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+ ASSERT(idev != NULL, return 0;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;);


X
X iobase = idev->io.iobase;

X
- disable_dma( idev->io.dma);
+ disable_dma(idev->io.dma);
X
X /* Save current set */
- set = inb( iobase+SSR);
+ set = inb(iobase+SSR);
X
X /* Disable interrupts */
- switch_bank( iobase, SET0);
- outb( 0, iobase+ICR);
+ switch_bank(iobase, SET0);
+ outb(0, iobase+ICR);
X
- free_irq( idev->io.irq, idev);
- free_dma( idev->io.dma);
+ free_irq(idev->io.irq, idev);
+ free_dma(idev->io.dma);


X
X /* Restore bank register */

- outb( set, iobase+SSR);
+ outb(set, iobase+SSR);
X
X MOD_DEC_USE_COUNT;
X
@@ -1230,6 +1274,11 @@


X }
X
X #ifdef MODULE

+
+MODULE_AUTHOR("Dag Brattli <da...@cs.uit.no>");

+MODULE_DESCRIPTION("Winbond W83977AF IrDA Device Driver");
+
+MODULE_PARM(qos_mtt_bits, "i");
X
X /*


X * Function init_module (void)

diff -u --recursive --new-file v2.2.9/linux/drivers/net/ni52.c linux/drivers/net/ni52.c
--- v2.2.9/linux/drivers/net/ni52.c Fri Oct 9 13:27:09 1998
+++ linux/drivers/net/ni52.c Tue Jun 8 10:27:27 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.2.9/linux/drivers/net/ni52.h linux/drivers/net/ni52.h
--- v2.2.9/linux/drivers/net/ni52.h Thu Apr 11 23:49:38 1996
+++ linux/drivers/net/ni52.h Tue Jun 8 10:27:27 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.2.9/linux/drivers/net/ni65.c linux/drivers/net/ni65.c
--- v2.2.9/linux/drivers/net/ni65.c Fri Oct 23 22:01:21 1998
+++ linux/drivers/net/ni65.c Tue Jun 8 10:27:27 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.2.9/linux/drivers/net/shaper.c linux/drivers/net/shaper.c
--- v2.2.9/linux/drivers/net/shaper.c Tue Mar 23 14:35:48 1999
+++ linux/drivers/net/shaper.c Wed Jun 2 11:29:28 1999


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

X * Simple traffic shaper for Linux NET3.
X *
- * (c) Copyright 1996 Alan Cox <al...@cymru.net>, All Rights Reserved.
- * http://www.cymru.net
+ * (c) Copyright 1996 Alan Cox <al...@redhat.com>, All Rights Reserved.


+ * http://www.redhat.com
X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License

diff -u --recursive --new-file v2.2.9/linux/drivers/net/sk_mca.c linux/drivers/net/sk_mca.c
--- v2.2.9/linux/drivers/net/sk_mca.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/sk_mca.c Mon Jun 7 14:34:54 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
+
+#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.2.9/linux/drivers/net/sk_mca.h linux/drivers/net/sk_mca.h
--- v2.2.9/linux/drivers/net/sk_mca.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/sk_mca.h Mon Jun 7 14:34:54 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.2.9/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c
--- v2.2.9/linux/drivers/net/smc-ultra.c Wed Mar 10 15:29:46 1999


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

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

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.2/patch-2.2.10/part12

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


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

if test "$Scheck" != 12; then


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

X * Wait for DMA from host memory to data FIFO to complete, then disable
X * DMA and wait for it to acknowledge that it's off.
X */
+if ((p->features & AHC_CMD_CHAN) == 0) {
X dma_finish:
X test DFSTATUS,HDONE jz dma_finish;
X /* Turn off DMA */
X and DFCNTRL, ~HDMAEN;
X test DFCNTRL, HDMAEN jnz .;
X ret;
+}
X
X add_scb_to_free_list:
X if ((p->flags & AHC_PAGESCBS) != 0) {
@@ -1433,8 +1464,7 @@
X mvi DMAPARAMS, FIFORESET;
X mov SCB_TAG call dma_scb;
X unlink_disc_scb:
- /* jmp instead of call since we want to return anyway */
- mov SCBPTR jmp rem_scb_from_disc_list;
+ mov DISCONNECTED_SCBH, SCB_NEXT ret;
X dequeue_free_scb:
X mov SCBPTR, FREE_SCBH;
X mov FREE_SCBH, SCB_NEXT ret;
@@ -1446,10 +1476,5 @@
X * candidates for paging out an SCB if one is needed for a new command.
X * Modifying the disconnected list is a critical(pause dissabled) section.
X */
- mvi SCB_PREV, SCB_LIST_NULL;
X mov SCB_NEXT, DISCONNECTED_SCBH;
- mov DISCONNECTED_SCBH, SCBPTR;
- cmp SCB_NEXT,SCB_LIST_NULL je return;
- mov SCBPTR,SCB_NEXT;
- mov SCB_PREV,DISCONNECTED_SCBH;
- mov SCBPTR,DISCONNECTED_SCBH ret;
+ mov DISCONNECTED_SCBH, SCBPTR ret;
diff -u --recursive --new-file v2.2.9/linux/drivers/scsi/aic7xxx/scsi_message.h linux/drivers/scsi/aic7xxx/scsi_message.h
--- v2.2.9/linux/drivers/scsi/aic7xxx/scsi_message.h Tue Apr 14 14:29:21 1998
+++ linux/drivers/scsi/aic7xxx/scsi_message.h Wed Jun 9 16:59:34 1999
@@ -38,4 +38,12 @@
X #define MSG_EXT_WDTR_LEN 0x02
X #define MSG_EXT_WDTR_BUS_8_BIT 0x00
X #define MSG_EXT_WDTR_BUS_16_BIT 0x01
-#define MSG_EXT_WDTR_BUS_32_BIT 0x02
+#define MSG_EXT_WDTR_BUS_32_BIT 0x02
+
+#define MSG_EXT_PPR 0x04
+#define MSG_EXT_PPR_LEN 0x06
+#define MSG_EXT_PPR_OPTION_ST 0x00
+#define MSG_EXT_PPR_OPTION_DT_CRC 0x02
+#define MSG_EXT_PPR_OPTION_DT_UNITS 0x03
+#define MSG_EXT_PPR_OPTION_DT_CRC_QUICK 0x04
+#define MSG_EXT_PPR_OPTION_DT_UNITS_QUICK 0x05
diff -u --recursive --new-file v2.2.9/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
--- v2.2.9/linux/drivers/scsi/aic7xxx.c Tue Jan 19 11:32:51 1999
+++ linux/drivers/scsi/aic7xxx.c Wed Jun 9 16:59:34 1999
@@ -171,91 +171,6 @@


X */
X
X /*

- * AIC7XXX_FAKE_NEGOTIATION_CMDS
- * We now have two distinctly different methods of device negotiation
- * in this code. The two methods are selected by either defining or not
- * defining this option. The difference is as follows:
- *
- * With AIC7XXX_FAKE_NEGOTIATION_CMDS not set (commented out)
- * When the driver is in need of issuing a negotiation command for any
- * given device, it will add the negotiation message on to part of a
- * regular SCSI command for the device. In the process, if the device
- * is configured for and using tagged queueing, then the code will
- * also issue that single command as a non-tagged command, attach the
- * negotiation message to that one command, and use a temporary
- * queue depth of one to keep the untagged and tagged commands from
- * overlapping.
- * Pros: This doesn't use any extra SCB structures, it's simple, it
- * works most of the time (if not all of the time now), and
- * since we get the device capability info frmo the INQUIRY data
- * now, shouldn't cause any problems.
- * Cons: When we need to send a negotiation command to a device, we
- * must use a command that is being sent to LUN 0 of the device.
- * If we try sending one to high LUN numbers, then some devices
- * get noticeably upset. Since we have to wait for a command with
- * LUN == 0 to come along, we may not be able to renegotiate when
- * we want if the user is actually using say LUN 1 of a CD Changer
- * instead of using LUN 0 for an extended period of time.
- *
- * With AIC7XXX_FAKE_NEGOTIATION_CMDS defined
- * When we need to negotiate with a device, instead of attaching our
- * negotiation message to an existing command, we insert our own
- * fictional Scsi_Cmnd into the chain that has the negotiation message
- * attached to it. We send this one command as untagged regardless
- * of the device type, and we fiddle with the queue depth the same as
- * we would with the option unset to avoid overlapping commands. The
- * primary difference between this and the unset option is that the
- * negotiation message is no longer attached to a specific command,
- * instead it is its own command and is merely triggered by a
- * combination of both A) We need to negotiate and B) The mid level
- * SCSI code has sent us a command. We still don't do any negotiation
- * unless there is a valid SCSI command to be processed.
- * Pros: This fixes the problem above in the Cons section. Since we
- * issue our own fake command, we can set the LUN to 0 regardless
- * of what the LUN is in the real command. It also means that if
- * the device get's nasty over negotiation issues, it won't be
- * showing up on a regular command, so we won't get any SENSE buffer
- * data or STATUS_BYTE returns to the mid level code that are caused
- * by snits in the negotiation code.
- * Cons: We add more code, and more complexity. This means more ways
- * in which things could break. It means a larger driver. It means
- * more resource consumption for the fake commands. However, the
- * biggest problem is this. Take a system where there is a CD-ROM
- * on the SCSI bus. Someone has a CD in the CD-ROM and is using it.
- * For some reason the SCSI bus gets reset. We don't touch the
- * CD-ROM again for quite a period of time (so we don't renegotiate
- * after the reset until we do touch the CD-ROM again). In the
- * time while we aren't using the CD-ROM, the current disc is
- * removed and a new one put in. When we go to check that disc, we
- * will first have to renegotiate. In so doing, we issue our fake
- * SCSI command, which happens to be TEST_UNIT_READY. The CD-ROM
- * negotiates with us, then responds to our fake command with a
- * CHECK_CONDITION status. We REQUEST_SENSE from the CD-ROM, it
- * then sends the SENSE data to our fake command to tell it that
- * it has been through a disc change. There, now we've cleared out
- * the SENSE data along with our negotiation command, and when the
- * real command executes, it won't pick up that the CD was changed.
- * That's the biggest Con to this approach. In the future, I could
- * probably code around this problem though, so this option is still
- * viable.
- *
- * So, which command style should you use? I would appreciate it if people
- * could try out both types. I want to know about any cases where one
- * method works and the other doesn't. If one method works on significantly
- * more systems than another, then it will become the default. If the second
- * option turns out to work best, then I'll find a way to work around that
- * big con I listed.
- *
- * -- July 7, 02:33
- * OK...I just added some code that should make the Con listed for the
- * fake commands a non issue now. However, it needs testing. For now,
- * I'm going to make the default to use the fake commands, we'll see how
- * it goes.
- */
-
-#define AIC7XXX_FAKE_NEGOTIATION_CMDS
-
-/*
X * AIC7XXX_STRICT_PCI_SETUP
X * Should we assume the PCI config options on our controllers are set with
X * sane and proper values, or should we be anal about our PCI config
@@ -336,6 +251,7 @@
X #include "aic7xxx/sequencer.h"
X #include "aic7xxx/scsi_message.h"
X #include "aic7xxx_reg.h"
+#include <scsi/scsicam.h>
X
X #include <linux/stat.h>
X #include <linux/malloc.h> /* for kmalloc() */
@@ -354,7 +270,7 @@
X 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
X };
X
-#define AIC7XXX_C_VERSION "5.1.10"
+#define AIC7XXX_C_VERSION "5.1.17"
X
X #define NUMBER(arr) (sizeof(arr) / sizeof(arr[0]))
X #define MIN(a,b) (((a) < (b)) ? (a) : (b))
@@ -447,10 +363,10 @@
X * You can try raising me if tagged queueing is enabled, or lowering
X * me if you only have 4 SCBs.
X */
-#ifdef CONFIG_AIC7XXX_CMDS_PER_LUN
-#define AIC7XXX_CMDS_PER_LUN CONFIG_AIC7XXX_CMDS_PER_LUN
+#ifdef CONFIG_AIC7XXX_CMDS_PER_DEVICE
+#define AIC7XXX_CMDS_PER_DEVICE CONFIG_AIC7XXX_CMDS_PER_DEVICE
X #else
-#define AIC7XXX_CMDS_PER_LUN 24
+#define AIC7XXX_CMDS_PER_DEVICE 8
X #endif
X
X /* Set this to the delay in seconds after SCSI bus reset. */
@@ -495,7 +411,7 @@
X *
X * *** Determining commands per LUN ***
X *
- * When AIC7XXX_CMDS_PER_LUN is not defined, the driver will use its
+ * When AIC7XXX_CMDS_PER_DEVICE is not defined, the driver will use its
X * own algorithm to determine the commands/LUN. If SCB paging is
X * enabled, which is always now, the default is 8 commands per lun
X * that indicates it supports tagged queueing. All non-tagged devices
@@ -513,8 +429,13 @@
X * Make a define that will tell the driver not to use tagged queueing
X * by default.
X */
+#ifdef CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
+#define DEFAULT_TAG_COMMANDS {0, 0, 0, 0, 0, 0, 0, 0,\


+ 0, 0, 0, 0, 0, 0, 0, 0}

+#else
X #define DEFAULT_TAG_COMMANDS {255, 255, 255, 255, 255, 255, 255, 255,\
X 255, 255, 255, 255, 255, 255, 255, 255}
+#endif
X
X /*
X * Modify this as you see fit for your system. By setting tag_commands
@@ -553,6 +474,27 @@
X };
X */
X
+static adapter_tag_info_t aic7xxx_tag_info[] =
+{
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS},
+ {DEFAULT_TAG_COMMANDS}
+};
+
+
X /*
X * Define an array of board names that can be indexed by aha_type.
X * Don't forget to change this when changing the types!
@@ -579,11 +521,14 @@
X "Adaptec AHA-2944 Ultra SCSI host adapter", /* AIC_7884 */
X "Adaptec AIC-7895 Ultra SCSI host adapter", /* AIC_7895 */
X "Adaptec AIC-7890/1 Ultra2 SCSI host adapter", /* AIC_7890 */
+ "Adaptec AHA-293X Ultra2 SCSI host adapter", /* AIC_7890 */
X "Adaptec AHA-294X Ultra2 SCSI host adapter", /* AIC_7890 */
X "Adaptec AIC-7896/7 Ultra2 SCSI host adapter", /* AIC_7896 */
X "Adaptec AHA-394X Ultra2 SCSI host adapter", /* AIC_7897 */
X "Adaptec AHA-395X Ultra2 SCSI host adapter", /* AIC_7897 */
X "Adaptec PCMCIA SCSI controller", /* card bus stuff */
+ "Adaptec AIC-7892 Ultra 160/m SCSI host adapter", /* AIC_7892 */
+ "Adaptec AIC-7899 Ultra 160/m SCSI host adapter", /* AIC_7899 */
X };
X
X /*
@@ -851,15 +796,17 @@
X SCB_DEVICE_RESET = 0x0020,
X SCB_RESET = 0x0040,
X SCB_RECOVERY_SCB = 0x0080,
- SCB_WAS_BUSY = 0x0100,
+ SCB_MSGOUT_PPR = 0x0100,
X SCB_MSGOUT_SENT = 0x0200,
X SCB_MSGOUT_SDTR = 0x0400,
X SCB_MSGOUT_WDTR = 0x0800,
- SCB_MSGOUT_BITS = SCB_MSGOUT_SENT |
+ SCB_MSGOUT_BITS = SCB_MSGOUT_PPR |
+ SCB_MSGOUT_SENT |
X SCB_MSGOUT_SDTR |
X SCB_MSGOUT_WDTR,
X SCB_QUEUED_ABORT = 0x1000,
- SCB_QUEUED_FOR_DONE = 0x2000
+ SCB_QUEUED_FOR_DONE = 0x2000,
+ SCB_WAS_BUSY = 0x4000
X } scb_flag_type;
X
X typedef enum {
@@ -913,6 +860,8 @@
X AHC_AIC7890 = 0x0006,
X AHC_AIC7895 = 0x0007,
X AHC_AIC7896 = 0x0008,
+ AHC_AIC7892 = 0x0009,
+ AHC_AIC7899 = 0x000a,
X AHC_VL = 0x0100,
X AHC_EISA = 0x0200,
X AHC_PCI = 0x0400,
@@ -929,6 +878,7 @@
X AHC_QUEUE_REGS = 0x0040,
X AHC_SG_PRELOAD = 0x0080,
X AHC_SPIOCAP = 0x0100,
+ AHC_ULTRA3 = 0x0200,
X AHC_AIC7770_FE = AHC_FENONE,
X AHC_AIC7850_FE = AHC_SPIOCAP,
X AHC_AIC7860_FE = AHC_ULTRA|AHC_SPIOCAP,
@@ -938,6 +888,8 @@
X AHC_QUEUE_REGS|AHC_SG_PRELOAD,
X AHC_AIC7895_FE = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA,
X AHC_AIC7896_FE = AHC_AIC7890_FE,
+ AHC_AIC7892_FE = AHC_AIC7890_FE|AHC_ULTRA3,
+ AHC_AIC7899_FE = AHC_AIC7890_FE|AHC_ULTRA3,
X } ahc_feature;
X
X struct aic7xxx_scb {
@@ -1014,9 +966,12 @@
X unsigned char goal_period;
X unsigned char cur_offset;
X unsigned char goal_offset;
+ unsigned char cur_options;
+ unsigned char goal_options;
X unsigned char user_width;
X unsigned char user_period;
X unsigned char user_offset;
+ unsigned char user_options;
X } transinfo_type;
X
X /*
@@ -1045,10 +1000,11 @@
X unsigned long isr_count; /* Interrupt count */
X unsigned long spurious_int;
X scb_data_type *scb_data;
+ volatile unsigned short needdv;
+ volatile unsigned short needppr;
X volatile unsigned short needsdtr;
- volatile unsigned short sdtr_pending;
X volatile unsigned short needwdtr;
- volatile unsigned short wdtr_pending;
+ volatile unsigned short dtr_pending;
X struct aic7xxx_cmd_queue {
X Scsi_Cmnd *head;
X Scsi_Cmnd *tail;
@@ -1071,9 +1027,10 @@
X #define DEVICE_PRESENT 0x01
X #define BUS_DEVICE_RESET_PENDING 0x02
X #define DEVICE_RESET_DELAY 0x04
-#define DEVICE_PRINT_SDTR 0x08
-#define DEVICE_PRINT_WDTR 0x10
+#define DEVICE_PRINT_DTR 0x08
+#define DEVICE_PARITY_ERROR 0x10
X #define DEVICE_WAS_BUSY 0x20
+#define DEVICE_SCSI_3 0x40
X #define DEVICE_SCANNED 0x80
X volatile unsigned char dev_flags[MAX_TARGETS];
X volatile unsigned char dev_active_cmds[MAX_TARGETS];
@@ -1090,11 +1047,10 @@
X #endif
X
X
-#ifdef AIC7XXX_FAKE_NEGOTIATION_CMDS
- Scsi_Cmnd *dev_wdtr_cmnd[MAX_TARGETS];
- Scsi_Cmnd *dev_sdtr_cmnd[MAX_TARGETS];
-#endif
+ Scsi_Cmnd *dev_dtr_cmnd[MAX_TARGETS];
X
+ unsigned int dev_checksum[MAX_TARGETS];
+
X unsigned char dev_last_queue_full[MAX_TARGETS];
X unsigned char dev_last_queue_full_count[MAX_TARGETS];
X unsigned char dev_max_queue_depth[MAX_TARGETS];
@@ -1102,7 +1058,7 @@
X volatile scb_queue_type delayed_scbs[MAX_TARGETS];
X
X
- unsigned char msg_buf[9]; /* The message for the target */
+ unsigned char msg_buf[13]; /* The message for the target */
X unsigned char msg_type;
X #define MSG_TYPE_NONE 0x00
X #define MSG_TYPE_INITIATOR_MSGOUT 0x01
@@ -1132,6 +1088,7 @@
X int scsi_id_b; /* channel B for twin adapters */
X unsigned int bios_address;
X int board_name_index;
+ unsigned short needppr_copy; /* default config */
X unsigned short needsdtr_copy; /* default config */
X unsigned short needwdtr_copy; /* default config */
X unsigned short ultraenb; /* Ultra mode target list */
@@ -1192,9 +1149,12 @@
X * Provides a mapping of transfer periods in ns/4 to the proper value to
X * stick in the SCSIRATE reg to use that transfer rate.
X */
-#define AHC_SYNCRATE_ULTRA2 0
-#define AHC_SYNCRATE_ULTRA 2
-#define AHC_SYNCRATE_FAST 5
+#define AHC_SYNCRATE_ULTRA3 0
+#define AHC_SYNCRATE_ULTRA2 1
+#define AHC_SYNCRATE_ULTRA 3
+#define AHC_SYNCRATE_FAST 6
+#define AHC_SYNCRATE_CRC 0x40
+#define AHC_SYNCRATE_SE 0x10
X static struct aic7xxx_syncrate {
X /* Rates in Ultra mode have bit 8 of sxfr set */
X #define ULTRA_SXFR 0x100
@@ -1203,6 +1163,7 @@
X unsigned char period;
X const char *rate[2];
X } aic7xxx_syncrates[] = {
+ { 0x42, 0x000, 9, {"80.0", "160.0"} },
X { 0x13, 0x000, 10, {"40.0", "80.0"} },
X { 0x14, 0x000, 11, {"33.0", "66.6"} },
X { 0x15, 0x100, 12, {"20.0", "40.0"} },
@@ -1410,35 +1371,6 @@
X
X #endif
X
-/*
- * See the comments earlier in the file for what this item is all about
- * If you have more than 4 controllers, you will need to increase the
- * the number of items in the array below. Additionally, if you don't
- * want to have lilo pass a humongous config line to the aic7xxx driver,
- * then you can get in and manually adjust these instead of leaving them
- * at the default. Pay attention to the comments earlier in this file
- * concerning this array if you are going to hand modify these values.
- */
-static adapter_tag_info_t aic7xxx_tag_info[] =
-{
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS},
- {DEFAULT_TAG_COMMANDS}
-};
-
X #define VERBOSE_NORMAL 0x0000
X #define VERBOSE_NEGOTIATION 0x0001
X #define VERBOSE_SEQINT 0x0002
@@ -1920,6 +1852,7 @@
X aic_outb(p, ((instr.integer >> 8) & 0xff), SEQRAM);
X aic_outb(p, ((instr.integer >> 16) & 0xff), SEQRAM);
X aic_outb(p, ((instr.integer >> 24) & 0xff), SEQRAM);
+ udelay(15);
X break;
X
X default:
@@ -2084,28 +2017,101 @@
X *-F*************************************************************************/
X static struct aic7xxx_syncrate *
X aic7xxx_find_syncrate(struct aic7xxx_host *p, unsigned int *period,
- unsigned int maxsync)
+ unsigned int maxsync, unsigned char *options)
X {
X struct aic7xxx_syncrate *syncrate;
+ int done = FALSE;
X
+ switch(*options)
+ {
+ case MSG_EXT_PPR_OPTION_DT_CRC:
+ case MSG_EXT_PPR_OPTION_DT_UNITS:
+ if(!(p->features & AHC_ULTRA3))
+ {
+ *options = 0;
+ maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2);
+ }
+ break;
+ case MSG_EXT_PPR_OPTION_DT_CRC_QUICK:
+ case MSG_EXT_PPR_OPTION_DT_UNITS_QUICK:
+ if(!(p->features & AHC_ULTRA3))
+ {
+ *options = 0;
+ maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2);


+ }
+ else
+ {
+ /*

+ * we don't support the Quick Arbitration variants of dual edge
+ * clocking. As it turns out, we want to send back the
+ * same basic option, but without the QA attribute.
+ * We know that we are responding because we would never set
+ * these options ourself, we would only respond to them.
+ */
+ switch(*options)
+ {
+ case MSG_EXT_PPR_OPTION_DT_CRC_QUICK:
+ *options = MSG_EXT_PPR_OPTION_DT_CRC;
+ break;
+ case MSG_EXT_PPR_OPTION_DT_UNITS_QUICK:
+ *options = MSG_EXT_PPR_OPTION_DT_UNITS;
+ break;
+ }
+ }
+ break;
+ default:
+ *options = 0;
+ maxsync = MAX(maxsync, AHC_SYNCRATE_ULTRA2);
+ break;
+ }
X syncrate = &aic7xxx_syncrates[maxsync];
X while ( (syncrate->rate[0] != NULL) &&
X (!(p->features & AHC_ULTRA2) || syncrate->sxfr_ultra2) )
X {
- if ( *period <= syncrate->period )
+ if (*period <= syncrate->period)
X {
- /*
- * When responding to a target that requests sync, the requested rate
- * may fall between two rates that we can output, but still be a rate
- * that we can receive. Because of this, we want to respond with the
- * same rate that it sent to us even if the persiod we use to send
- * data to it is lower. Only lower the response period if we must.
- */
- if(syncrate == &aic7xxx_syncrates[maxsync])
+ switch(*options)
+ {
+ case MSG_EXT_PPR_OPTION_DT_CRC:
+ case MSG_EXT_PPR_OPTION_DT_UNITS:
+ if(!(syncrate->sxfr_ultra2 & AHC_SYNCRATE_CRC))
+ {
+ done = TRUE;
+ /*
+ * oops, we went too low for the CRC/DualEdge signalling, so
+ * clear the options byte
+ */
+ *options = 0;
+ /*
+ * We'll be sending a reply to this packet to set the options
+ * properly, so unilaterally set the period as well.
+ */
+ *period = syncrate->period;
+ }
+ else
+ {
+ done = TRUE;
+ if(syncrate == &aic7xxx_syncrates[maxsync])
+ {
+ *period = syncrate->period;
+ }
+ }
+ break;
+ default:
+ if(!(syncrate->sxfr_ultra2 & AHC_SYNCRATE_CRC))
+ {
+ done = TRUE;
+ if(syncrate == &aic7xxx_syncrates[maxsync])
+ {
+ *period = syncrate->period;
+ }
+ }
+ break;
+ }
+ if(done)
X {
- *period = syncrate->period;
+ break;
X }
- break;
X }
X syncrate++;
X }
@@ -2115,6 +2121,7 @@
X /*
X * Use async transfers for this target
X */
+ *options = 0;
X *period = 0;
X syncrate = NULL;
X }
@@ -2135,7 +2142,7 @@
X {
X struct aic7xxx_syncrate *syncrate;
X
- if ((p->features & AHC_ULTRA2) != 0)
+ if (p->features & AHC_ULTRA2)
X {
X scsirate &= SXFR_ULTRA2;
X }
@@ -2147,12 +2154,14 @@
X syncrate = &aic7xxx_syncrates[maxsync];
X while (syncrate->rate[0] != NULL)
X {
- if ((p->features & AHC_ULTRA2) != 0)
+ if (p->features & AHC_ULTRA2)
X {
X if (syncrate->sxfr_ultra2 == 0)
X break;
X else if (scsirate == syncrate->sxfr_ultra2)
X return (syncrate->period);
+ else if (scsirate == (syncrate->sxfr_ultra2 & ~AHC_SYNCRATE_CRC))
+ return (syncrate->period);
X }
X else if (scsirate == (syncrate->sxfr & ~ULTRA_SXFR))
X {
@@ -2206,11 +2215,11 @@
X static void
X aic7xxx_set_syncrate(struct aic7xxx_host *p, struct aic7xxx_syncrate *syncrate,
X int target, int channel, unsigned int period, unsigned int offset,
- unsigned int type)
+ unsigned char options, unsigned int type)
X {
X unsigned char tindex;
X unsigned short target_mask;
- unsigned char lun;
+ unsigned char lun, old_options;
X unsigned int old_period, old_offset;
X
X tindex = target | (channel << 3);
@@ -2225,6 +2234,7 @@
X
X old_period = p->transinfo[tindex].cur_period;
X old_offset = p->transinfo[tindex].cur_offset;
+ old_options = p->transinfo[tindex].cur_options;
X
X
X if (type & AHC_TRANS_CUR)
@@ -2237,7 +2247,18 @@
X scsirate &= ~SXFR_ULTRA2;
X if (syncrate != NULL)
X {
- scsirate |= syncrate->sxfr_ultra2;
+ switch(options)
+ {
+ case MSG_EXT_PPR_OPTION_DT_UNITS:
+ /*
+ * mask off the CRC bit in the xfer settings
+ */
+ scsirate |= (syncrate->sxfr_ultra2 & ~AHC_SYNCRATE_CRC);
+ break;
+ default:
+ scsirate |= syncrate->sxfr_ultra2;
+ break;
+ }
X }
X if (type & AHC_TRANS_ACTIVE)
X {
@@ -2278,9 +2299,10 @@
X aic_outb(p, scsirate, TARG_SCSIRATE + tindex);
X p->transinfo[tindex].cur_period = period;
X p->transinfo[tindex].cur_offset = offset;
+ p->transinfo[tindex].cur_options = options;
X if ( !(type & AHC_TRANS_QUITE) &&
X (aic7xxx_verbose & VERBOSE_NEGOTIATION) &&
- (p->dev_flags[tindex] & DEVICE_PRINT_SDTR) )
+ (p->dev_flags[tindex] & DEVICE_PRINT_DTR) )
X {
X if (offset)
X {
@@ -2295,7 +2317,7 @@
X printk(INFO_LEAD "Using asynchronous transfers.\n",
X p->host_no, channel, target, lun);
X }
- p->dev_flags[tindex] &= ~DEVICE_PRINT_SDTR;
+ p->dev_flags[tindex] &= ~DEVICE_PRINT_DTR;
X }
X }
X
@@ -2303,12 +2325,14 @@
X {
X p->transinfo[tindex].goal_period = period;
X p->transinfo[tindex].goal_offset = offset;
+ p->transinfo[tindex].goal_options = options;
X }
X
X if (type & AHC_TRANS_USER)
X {
X p->transinfo[tindex].user_period = period;
X p->transinfo[tindex].user_offset = offset;
+ p->transinfo[tindex].user_options = options;
X }
X }
X
@@ -2325,20 +2349,13 @@
X {
X unsigned char tindex;
X unsigned short target_mask;
- unsigned int old_width, new_offset;
+ unsigned int old_width;
X
X tindex = target | (channel << 3);
X target_mask = 1 << tindex;
X
X old_width = p->transinfo[tindex].cur_width;
X
- if (p->features & AHC_ULTRA2)
- new_offset = MAX_OFFSET_ULTRA2;
- else if (width == MSG_EXT_WDTR_BUS_16_BIT)
- new_offset = MAX_OFFSET_16BIT;
- else
- new_offset = MAX_OFFSET_8BIT;
-
X if (type & AHC_TRANS_CUR)
X {
X unsigned char scsirate;
@@ -2356,12 +2373,12 @@
X
X p->transinfo[tindex].cur_width = width;
X
- if ((aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
- (p->dev_flags[tindex] & DEVICE_PRINT_WDTR))
+ if ( !(type & AHC_TRANS_QUITE) &&
+ (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
+ (p->dev_flags[tindex] & DEVICE_PRINT_DTR) )
X {
X printk(INFO_LEAD "Using %s transfers\n", p->host_no, channel, target,
X lun, (scsirate & WIDEXFER) ? "Wide(16bit)" : "Narrow(8bit)" );
- p->dev_flags[tindex] &= ~DEVICE_PRINT_WDTR;
X }
X }
X
@@ -2370,14 +2387,21 @@
X if (type & AHC_TRANS_USER)
X p->transinfo[tindex].user_width = width;
X
- /*
- * Having just set the width, the SDTR should come next, and we need a valid
- * offset for the SDTR. So, we make sure we put a valid one in here now as
- * the goal_offset.
- */
X if (p->transinfo[tindex].goal_offset)
- p->transinfo[tindex].goal_offset = new_offset;
-
+ {
+ if (p->features & AHC_ULTRA2)
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
+ }
+ else if (width == MSG_EXT_WDTR_BUS_16_BIT)
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
+ }
+ else
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
+ }
+ }
X }
X
X /*+F*************************************************************************
@@ -2543,14 +2567,6 @@
X if (match != 0)
X match = ((tag == scb->hscb->tag) || (tag == SCB_LIST_NULL));
X
- if (aic7xxx_verbose & (VERBOSE_ABORT_PROCESS | VERBOSE_RESET_PROCESS))
- {
- printk(KERN_INFO "(scsi%d:%d:%d:%d:tag%d) %s search criteria"
- " (scsi%d:%d:%d:%d:tag%d)\n", p->host_no, CTL_OF_SCB(scb),
- scb->hscb->tag, (match) ? "matches" : "doesn't match",
- p->host_no, channel, target, lun, tag);
- }
-
X return (match);
X }
X
@@ -2584,14 +2600,13 @@
X * to the free list.
X *-F*************************************************************************/
X static unsigned char
-aic7xxx_rem_scb_from_disc_list(struct aic7xxx_host *p, unsigned char scbptr)
+aic7xxx_rem_scb_from_disc_list(struct aic7xxx_host *p, unsigned char scbptr,
+ unsigned char prev)
X {
X unsigned char next;
- unsigned char prev;
X
X aic_outb(p, scbptr, SCBPTR);
X next = aic_inb(p, SCB_NEXT);
- prev = aic_inb(p, SCB_PREV);
X aic7xxx_add_curscb_to_free_list(p);
X
X if (prev != SCB_LIST_NULL)
@@ -2604,11 +2619,6 @@
X aic_outb(p, next, DISCONNECTED_SCBH);
X }
X
- if (next != SCB_LIST_NULL)
- {
- aic_outb(p, next, SCBPTR);
- aic_outb(p, prev, SCB_PREV);
- }
X return next;
X }
X
@@ -2755,7 +2765,7 @@
X * Place in the scb array; never is removed
X */
X p->scb_data->scb_array[p->scb_data->numscbs++] = scbp;
- scbq_insert_head(&p->scb_data->free_scbs, scbp);
+ scbq_insert_tail(&p->scb_data->free_scbs, scbp);
X }
X scbp->kmalloc_ptr = scb_ap;
X }
@@ -2796,6 +2806,7 @@
X Scsi_Cmnd *cmd;
X #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
X unsigned int cpu_flags = 0;
+#endif
X
X DRIVER_LOCK
X while (p->completeq.head != NULL)
@@ -2803,20 +2814,9 @@
X cmd = p->completeq.head;
X p->completeq.head = (Scsi_Cmnd *)cmd->host_scribble;
X cmd->host_scribble = NULL;
- sti();
X cmd->scsi_done(cmd);
- cli();
X }
X DRIVER_UNLOCK
-#else
- while (p->completeq.head != NULL)
- {
- cmd = p->completeq.head;
- p->completeq.head = (Scsi_Cmnd *)cmd->host_scribble;
- cmd->host_scribble = NULL;
- cmd->scsi_done(cmd);
- }
-#endif
X }
X
X /*+F*************************************************************************
@@ -2889,16 +2889,13 @@
X }
X #define WIDE_INQUIRY_BITS 0x60
X #define SYNC_INQUIRY_BITS 0x10
+#define SCSI_VERSION_BITS 0x07
X if ( (buffer[7] & WIDE_INQUIRY_BITS) &&
X (p->features & AHC_WIDE) )
X {
X p->needwdtr |= (1<<tindex);
X p->needwdtr_copy |= (1<<tindex);
- if ( (p->flags & AHC_SEEPROM_FOUND) &&
- (p->transinfo[tindex].user_width != MSG_EXT_WDTR_BUS_16_BIT) )
- p->transinfo[tindex].goal_width = MSG_EXT_WDTR_BUS_8_BIT;
- else
- p->transinfo[tindex].goal_width = MSG_EXT_WDTR_BUS_16_BIT;
+ p->transinfo[tindex].goal_width = p->transinfo[tindex].user_width;
X }
X else
X {
@@ -2916,28 +2913,10 @@
X p->needsdtr |= (1<<tindex);
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 }


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

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

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

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

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


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

- 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.2.9/linux/drivers/scsi/aic7xxx_proc.c linux/drivers/scsi/aic7xxx_proc.c
--- v2.2.9/linux/drivers/scsi/aic7xxx_proc.c Thu Jan 7 15:11:37 1999
+++ linux/drivers/scsi/aic7xxx_proc.c Wed Jun 9 16:59:34 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.2.9/linux/drivers/scsi/aic7xxx_reg.h linux/drivers/scsi/aic7xxx_reg.h
--- v2.2.9/linux/drivers/scsi/aic7xxx_reg.h Fri Oct 9 13:27:11 1998
+++ linux/drivers/scsi/aic7xxx_reg.h Wed Jun 9 16:59:34 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.2.9/linux/drivers/scsi/aic7xxx_seq.c linux/drivers/scsi/aic7xxx_seq.c
--- v2.2.9/linux/drivers/scsi/aic7xxx_seq.c Fri Oct 9 13:27:11 1998
+++ linux/drivers/scsi/aic7xxx_seq.c Wed Jun 9 16:59:34 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,
- 0x00, 0x65, 0x68, 0x42,
+ 0x14, 0x6a, 0x06, 0x5c,
+ 0xa9, 0x6a, 0x08, 0x5c,
+ 0x00, 0x65, 0x90, 0x42,
X 0xef, 0x36, 0x6c, 0x08,
- 0x00, 0x65, 0x68, 0x42,
+ 0x00, 0x65, 0x90, 0x42,
X 0x0f, 0x64, 0xc8, 0x08,
X 0x07, 0x64, 0xc8, 0x08,
X 0x00, 0x37, 0x6e, 0x00,
- 0x00, 0x65, 0x78, 0x5b,
- 0xff, 0x51, 0xce, 0x72,
- 0x20, 0x36, 0xde, 0x7a,
- 0x00, 0x90, 0x5c, 0x5b,
- 0x00, 0x65, 0xe0, 0x42,
+ 0xff, 0x6a, 0xa4, 0x00,
+ 0x00, 0x65, 0x98, 0x5b,
+ 0xff, 0x51, 0xfc, 0x72,
+ 0x20, 0x36, 0x06, 0x7b,
+ 0x00, 0x90, 0x86, 0x5b,
+ 0x00, 0x65, 0x08, 0x43,
X 0xff, 0x06, 0xd4, 0x08,
- 0x00, 0x65, 0xd2, 0x5b,
- 0xe0, 0x3d, 0xfa, 0x62,
- 0x20, 0x12, 0xfa, 0x62,
- 0x51, 0x6a, 0x08, 0x5b,
- 0xff, 0x51, 0x20, 0x09,
- 0x20, 0xa0, 0xfa, 0x7a,
- 0x00, 0x90, 0x5c, 0x5b,
- 0x00, 0x65, 0x56, 0x5b,
+ 0x00, 0x65, 0xf2, 0x5b,
+ 0xe0, 0x3d, 0x22, 0x63,
+ 0x20, 0x12, 0x22, 0x63,
+ 0x51, 0x6a, 0x30, 0x5b,
+ 0x00, 0x65, 0x80, 0x5b,
X 0xff, 0x37, 0xc8, 0x08,
- 0x00, 0xa1, 0xf2, 0x62,
- 0x04, 0xa0, 0xf2, 0x7a,
+ 0x00, 0xa1, 0x1a, 0x63,
+ 0x04, 0xa0, 0x1a, 0x7b,
X 0xfb, 0xa0, 0x40, 0x09,
X 0x80, 0x36, 0x6c, 0x00,
- 0x80, 0xa0, 0x68, 0x7a,
+ 0x80, 0xa0, 0x90, 0x7a,
X 0x7f, 0xa0, 0x40, 0x09,
- 0xff, 0x6a, 0x04, 0x5b,
- 0x00, 0x65, 0x68, 0x42,
- 0x04, 0xa0, 0xf8, 0x7a,
- 0x00, 0x65, 0x84, 0x5c,
- 0x00, 0x65, 0xfa, 0x42,
- 0x00, 0x65, 0x6c, 0x5c,
+ 0xff, 0x6a, 0x2c, 0x5b,
+ 0x00, 0x65, 0x90, 0x42,
+ 0x04, 0xa0, 0x20, 0x7b,
+ 0x00, 0x65, 0xa4, 0x5c,
+ 0x00, 0x65, 0x22, 0x43,
+ 0x00, 0x65, 0x8c, 0x5c,
X 0x31, 0x6a, 0x22, 0x01,
- 0x0c, 0x6a, 0x04, 0x5b,
- 0x00, 0x65, 0x68, 0x42,
+ 0x0c, 0x6a, 0x2c, 0x5b,
+ 0x00, 0x65, 0x90, 0x42,
X 0x61, 0x6a, 0x22, 0x01,
- 0x00, 0x65, 0x68, 0x42,
+ 0x00, 0x65, 0x90, 0x42,
X 0x10, 0x3d, 0x06, 0x00,
X 0xff, 0x65, 0x68, 0x0c,
X 0xff, 0x06, 0xd4, 0x08,
- 0x01, 0x0c, 0x0a, 0x7b,
- 0x04, 0x0c, 0x0a, 0x6b,
+ 0x01, 0x0c, 0x32, 0x7b,
+ 0x04, 0x0c, 0x32, 0x6b,
X 0xe0, 0x03, 0x7a, 0x08,
- 0xe0, 0x3d, 0x1e, 0x63,
+ 0xe0, 0x3d, 0x46, 0x63,
X 0xff, 0x65, 0xcc, 0x08,
X 0xff, 0x12, 0xda, 0x0c,
X 0xff, 0x06, 0xd4, 0x0c,
X 0xff, 0x65, 0x0c, 0x08,
- 0x02, 0x0b, 0x1a, 0x7b,
+ 0x02, 0x0b, 0x42, 0x7b,
X 0xff, 0x6a, 0xd4, 0x0c,
X 0xd1, 0x6a, 0x22, 0x01,
- 0x00, 0x65, 0x18, 0x41,
+ 0x00, 0x65, 0x22, 0x41,
X 0xff, 0x65, 0x26, 0x09,
- 0x01, 0x0b, 0x32, 0x6b,
- 0x10, 0x0c, 0x24, 0x7b,
- 0x04, 0x0b, 0x2c, 0x6b,
+ 0x01, 0x0b, 0x5a, 0x6b,
+ 0x10, 0x0c, 0x4c, 0x7b,
+ 0x04, 0x0b, 0x54, 0x6b,
X 0xff, 0x6a, 0xca, 0x08,
- 0x04, 0x93, 0x30, 0x6b,
- 0x01, 0x94, 0x2e, 0x7b,
- 0x10, 0x94, 0x30, 0x6b,
+ 0x04, 0x93, 0x58, 0x6b,
+ 0x01, 0x94, 0x56, 0x7b,
+ 0x10, 0x94, 0x58, 0x6b,
X 0xc7, 0x93, 0x26, 0x09,
X 0xff, 0x99, 0xd4, 0x08,
- 0x08, 0x93, 0x34, 0x6b,
+ 0x38, 0x93, 0x5c, 0x6b,
X 0xff, 0x6a, 0xd4, 0x0c,
- 0x80, 0x36, 0x38, 0x6b,
+ 0x80, 0x36, 0x60, 0x6b,
X 0x21, 0x6a, 0x22, 0x05,
X 0xff, 0x65, 0x20, 0x09,
- 0xff, 0x51, 0x46, 0x63,
+ 0xff, 0x51, 0x6e, 0x63,
X 0xff, 0x37, 0xc8, 0x08,
- 0xa1, 0x6a, 0x50, 0x43,
+ 0xa1, 0x6a, 0x7a, 0x43,
X 0xff, 0x51, 0xc8, 0x08,
- 0xb9, 0x6a, 0x50, 0x43,
- 0xff, 0xba, 0x54, 0x73,
+ 0xb9, 0x6a, 0x7a, 0x43,
+ 0xff, 0x90, 0xa4, 0x08,
+ 0xff, 0xba, 0x7e, 0x73,
X 0xff, 0xba, 0x20, 0x09,
X 0xff, 0x65, 0xca, 0x18,
- 0x00, 0x6c, 0x4a, 0x63,
+ 0x00, 0x6c, 0x72, 0x63,
X 0xff, 0x90, 0xca, 0x0c,
X 0xff, 0x6a, 0xca, 0x04,
- 0x20, 0x36, 0x72, 0x7b,
- 0x00, 0x90, 0x3e, 0x5b,
- 0xff, 0x65, 0x72, 0x73,
- 0xff, 0xba, 0x66, 0x73,
- 0xff, 0xbb, 0xcc, 0x08,
- 0xff, 0xba, 0x20, 0x09,
- 0xff, 0x66, 0x76, 0x09,
- 0xff, 0x65, 0x20, 0x09,
- 0xff, 0xbb, 0x70, 0x73,
+ 0x20, 0x36, 0x92, 0x7b,
+ 0x00, 0x90, 0x66, 0x5b,
+ 0xff, 0x65, 0x92, 0x73,
+ 0xff, 0x52, 0x90, 0x73,
X 0xff, 0xba, 0xcc, 0x08,
- 0xff, 0xbb, 0x20, 0x09,
+ 0xff, 0x52, 0x20, 0x09,
X 0xff, 0x66, 0x74, 0x09,
X 0xff, 0x65, 0x20, 0x0d,
X 0xff, 0xba, 0x7e, 0x0c,
- 0x00, 0x6a, 0x72, 0x5c,
+ 0x00, 0x6a, 0x92, 0x5c,
X 0x0d, 0x6a, 0x6a, 0x00,
- 0x00, 0x51, 0xfe, 0x43,
- 0xff, 0x3f, 0xcc, 0x73,
+ 0x00, 0x51, 0x1e, 0x44,
+ 0xff, 0x3f, 0xec, 0x73,
X 0xff, 0x6a, 0xa2, 0x00,
- 0x00, 0x3f, 0x3e, 0x5b,
- 0xff, 0x65, 0xcc, 0x73,
+ 0x00, 0x3f, 0x66, 0x5b,
+ 0xff, 0x65, 0xec, 0x73,
X 0x20, 0x36, 0x6c, 0x00,
- 0x20, 0xa0, 0x86, 0x6b,
+ 0x20, 0xa0, 0xa6, 0x6b,
X 0xff, 0xb9, 0xa2, 0x0c,
X 0xff, 0x6a, 0xa2, 0x04,
X 0xff, 0x65, 0xa4, 0x08,
X 0xe0, 0x6a, 0xcc, 0x00,
- 0x45, 0x6a, 0xf2, 0x5b,
+ 0x45, 0x6a, 0x12, 0x5c,
X 0x01, 0x6a, 0xd0, 0x01,
X 0x09, 0x6a, 0xd6, 0x01,
- 0x80, 0xeb, 0x92, 0x7b,
+ 0x80, 0xeb, 0xb2, 0x7b,
X 0x01, 0x6a, 0xd6, 0x01,
X 0x01, 0xe9, 0xa4, 0x34,
X 0x88, 0x6a, 0xcc, 0x00,
- 0x45, 0x6a, 0xf2, 0x5b,
+ 0x45, 0x6a, 0x12, 0x5c,
X 0x01, 0x6a, 0x18, 0x01,
X 0xff, 0x6a, 0x1a, 0x09,
X 0xff, 0x6a, 0x1c, 0x09,
X 0x0d, 0x6a, 0x26, 0x01,
- 0x00, 0x65, 0x64, 0x5c,
+ 0x00, 0x65, 0x84, 0x5c,
X 0xff, 0x99, 0xa4, 0x0c,
X 0xff, 0x65, 0xa4, 0x08,
X 0xe0, 0x6a, 0xcc, 0x00,
- 0x45, 0x6a, 0xf2, 0x5b,
+ 0x45, 0x6a, 0x12, 0x5c,
X 0x01, 0x6a, 0xd0, 0x01,
X 0x01, 0x6a, 0xdc, 0x05,
X 0x88, 0x6a, 0xcc, 0x00,
- 0x45, 0x6a, 0xf2, 0x5b,
+ 0x45, 0x6a, 0x12, 0x5c,
X 0x01, 0x6a, 0x18, 0x01,
X 0xff, 0x6a, 0x1a, 0x09,
X 0xff, 0x6a, 0x1c, 0x09,
X 0x01, 0x6a, 0x26, 0x05,
X 0x01, 0x65, 0xd8, 0x31,
X 0x09, 0xee, 0xdc, 0x01,
- 0x80, 0xee, 0xc2, 0x7b,
+ 0x80, 0xee, 0xe2, 0x7b,
X 0xff, 0x6a, 0xdc, 0x0d,
X 0xff, 0x65, 0x32, 0x09,
X 0x0a, 0x93, 0x26, 0x01,
- 0x00, 0x65, 0x64, 0x44,
+ 0x00, 0x65, 0x84, 0x44,
X 0xff, 0x37, 0xc8, 0x08,
- 0x00, 0x6a, 0x88, 0x5b,
+ 0x00, 0x6a, 0xa8, 0x5b,
X 0xff, 0x52, 0xa2, 0x0c,
- 0x01, 0x0c, 0xd2, 0x7b,
- 0x04, 0x0c, 0xd2, 0x6b,
- 0xe0, 0x03, 0x7a, 0x08,
- 0xff, 0x3d, 0x06, 0x0c,
+ 0x01, 0x0c, 0xf2, 0x7b,
+ 0x04, 0x0c, 0xf2, 0x6b,
+ 0xe0, 0x03, 0x06, 0x08,
+ 0xe0, 0x03, 0x7a, 0x0c,
X 0xff, 0x8c, 0x10, 0x08,
X 0xff, 0x8d, 0x12, 0x08,
X 0xff, 0x8e, 0x14, 0x0c,
@@ -515,29 +531,29 @@
X 0x00, 0x6c, 0xda, 0x24,
X 0xff, 0x65, 0xc8, 0x08,
X 0xe0, 0x6a, 0xcc, 0x00,
- 0x41, 0x6a, 0xee, 0x5b,
+ 0x41, 0x6a, 0x0e, 0x5c,
X 0xff, 0x90, 0xe2, 0x09,
X 0x20, 0x6a, 0xd0, 0x01,
- 0x04, 0x35, 0x10, 0x7c,
+ 0x04, 0x35, 0x30, 0x7c,
X 0x1d, 0x6a, 0xdc, 0x01,
- 0xdc, 0xee, 0x0c, 0x64,
- 0x00, 0x65, 0x1c, 0x44,
+ 0xdc, 0xee, 0x2c, 0x64,
+ 0x00, 0x65, 0x3c, 0x44,
X 0x01, 0x6a, 0xdc, 0x01,
X 0x20, 0xa0, 0xd8, 0x31,
X 0x09, 0xee, 0xdc, 0x01,
- 0x80, 0xee, 0x16, 0x7c,
+ 0x80, 0xee, 0x36, 0x7c,
X 0x19, 0x6a, 0xdc, 0x01,
- 0xd8, 0xee, 0x1a, 0x64,
+ 0xd8, 0xee, 0x3a, 0x64,
X 0xff, 0x6a, 0xdc, 0x09,
- 0x18, 0xee, 0x1e, 0x6c,
+ 0x18, 0xee, 0x3e, 0x6c,
X 0xff, 0x6a, 0xd4, 0x0c,
X 0x88, 0x6a, 0xcc, 0x00,
- 0x41, 0x6a, 0xee, 0x5b,
+ 0x41, 0x6a, 0x0e, 0x5c,
X 0x20, 0x6a, 0x18, 0x01,
X 0xff, 0x6a, 0x1a, 0x09,
X 0xff, 0x6a, 0x1c, 0x09,
X 0xff, 0x35, 0x26, 0x09,
- 0x04, 0x35, 0x48, 0x6c,
+ 0x04, 0x35, 0x68, 0x6c,
X 0xa0, 0x6a, 0xca, 0x00,
X 0x20, 0x65, 0xc8, 0x18,
X 0xff, 0x6c, 0x32, 0x09,
@@ -548,14 +564,14 @@
X 0xff, 0x6c, 0x32, 0x09,
X 0xff, 0x6c, 0x32, 0x09,
X 0xff, 0x6c, 0x32, 0x09,
- 0x00, 0x65, 0x34, 0x64,
+ 0x00, 0x65, 0x54, 0x64,
X 0x0a, 0x93, 0x26, 0x01,
- 0x00, 0x65, 0x64, 0x5c,
- 0x04, 0x35, 0x38, 0x7b,
- 0xa0, 0x6a, 0x54, 0x5c,
- 0x00, 0x65, 0x56, 0x5c,
- 0x00, 0x65, 0x56, 0x5c,
- 0x00, 0x65, 0x56, 0x44,
+ 0x00, 0x65, 0x84, 0x5c,
+ 0x04, 0x35, 0x60, 0x7b,
+ 0xa0, 0x6a, 0x74, 0x5c,
+ 0x00, 0x65, 0x76, 0x5c,
+ 0x00, 0x65, 0x76, 0x5c,
+ 0x00, 0x65, 0x76, 0x44,
X 0xff, 0x65, 0xcc, 0x08,
X 0xff, 0x99, 0xda, 0x08,
X 0xff, 0x99, 0xda, 0x08,
@@ -564,37 +580,40 @@
X 0xff, 0x99, 0xda, 0x08,
X 0xff, 0x99, 0xda, 0x08,
X 0xff, 0x99, 0xda, 0x0c,
- 0x08, 0x94, 0x64, 0x7c,
+ 0x08, 0x94, 0x84, 0x7c,
X 0xf7, 0x93, 0x26, 0x09,
- 0x08, 0x93, 0x68, 0x6c,
+ 0x08, 0x93, 0x88, 0x6c,
X 0xff, 0x6a, 0xd4, 0x0c,
X 0xff, 0x40, 0x74, 0x09,
X 0xff, 0x90, 0x80, 0x08,
X 0xff, 0x6a, 0x72, 0x05,
- 0xff, 0x40, 0x80, 0x64,
- 0xff, 0x3f, 0x78, 0x64,
+ 0xff, 0x40, 0xa0, 0x64,
+ 0xff, 0x3f, 0x98, 0x64,
X 0xff, 0x6a, 0xca, 0x04,
X 0xff, 0x3f, 0x20, 0x09,
X 0x01, 0x6a, 0x6a, 0x00,
- 0x00, 0xb9, 0xfe, 0x5b,
- 0x00, 0x90, 0x5c, 0x43,
+ 0x00, 0xb9, 0x1e, 0x5c,
+ 0xff, 0xba, 0x7e, 0x0c,
X 0xff, 0x40, 0x20, 0x09,
X 0xff, 0xba, 0x80, 0x0c,
- 0xff, 0x6a, 0x76, 0x01,
X 0xff, 0x3f, 0x74, 0x09,
- 0xff, 0x90, 0x7e, 0x08,
- 0xff, 0xba, 0x38, 0x73,
- 0xff, 0xba, 0x20, 0x09,
- 0xff, 0x3f, 0x76, 0x09,
- 0xff, 0x3f, 0x20, 0x0d,
+ 0xff, 0x90, 0x7e, 0x0c,
X };
X
+static int aic7xxx_patch13_func(struct aic7xxx_host *p);
+
+static int
+aic7xxx_patch13_func(struct aic7xxx_host *p)
+{
+ return ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895);
+}
+
X static int aic7xxx_patch12_func(struct aic7xxx_host *p);
X
X static int
X aic7xxx_patch12_func(struct aic7xxx_host *p)
X {
- return ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895);
+ return ((p->features & AHC_CMD_CHAN) == 0);
X }
X
X static int aic7xxx_patch11_func(struct aic7xxx_host *p);
@@ -699,71 +718,81 @@
X skip_instr :10,
X skip_patch :12;
X } sequencer_patches[] = {
- { aic7xxx_patch1_func, 1, 1, 2 },
- { aic7xxx_patch0_func, 2, 1, 1 },
- { aic7xxx_patch2_func, 3, 2, 1 },
- { aic7xxx_patch3_func, 7, 1, 1 },
+ { aic7xxx_patch1_func, 2, 1, 2 },
+ { aic7xxx_patch0_func, 3, 1, 1 },
+ { aic7xxx_patch2_func, 4, 2, 1 },
X { aic7xxx_patch3_func, 8, 1, 1 },
- { aic7xxx_patch4_func, 11, 4, 1 },
- { aic7xxx_patch5_func, 16, 3, 2 },
- { aic7xxx_patch0_func, 19, 4, 1 },
- { aic7xxx_patch6_func, 23, 1, 1 },
- { aic7xxx_patch7_func, 26, 1, 1 },
- { aic7xxx_patch4_func, 34, 4, 1 },
- { aic7xxx_patch8_func, 38, 3, 2 },
- { aic7xxx_patch0_func, 41, 3, 1 },
- { aic7xxx_patch9_func, 47, 7, 1 },
- { aic7xxx_patch4_func, 55, 3, 1 },
- { aic7xxx_patch8_func, 58, 2, 1 },
- { aic7xxx_patch1_func, 63, 60, 1 },
- { aic7xxx_patch8_func, 164, 1, 2 },
- { aic7xxx_patch0_func, 165, 1, 1 },
- { aic7xxx_patch2_func, 169, 1, 1 },
- { aic7xxx_patch2_func, 172, 1, 2 },
- { aic7xxx_patch0_func, 173, 2, 1 },
- { aic7xxx_patch10_func, 175, 1, 1 },
- { aic7xxx_patch8_func, 182, 1, 2 },
- { aic7xxx_patch0_func, 183, 3, 1 },
- { aic7xxx_patch8_func, 187, 1, 2 },
- { aic7xxx_patch0_func, 188, 1, 1 },
- { aic7xxx_patch8_func, 189, 7, 2 },
- { aic7xxx_patch0_func, 196, 1, 1 },
- { aic7xxx_patch2_func, 201, 13, 2 },
- { aic7xxx_patch0_func, 214, 8, 1 },
- { aic7xxx_patch10_func, 222, 1, 1 },
- { aic7xxx_patch8_func, 227, 1, 1 },
- { aic7xxx_patch8_func, 228, 1, 1 },
- { aic7xxx_patch8_func, 233, 1, 1 },
- { aic7xxx_patch8_func, 235, 2, 1 },
- { aic7xxx_patch8_func, 240, 8, 1 },
- { aic7xxx_patch8_func, 249, 1, 1 },
- { aic7xxx_patch2_func, 250, 2, 2 },
- { aic7xxx_patch0_func, 252, 4, 1 },
- { aic7xxx_patch10_func, 256, 2, 2 },
- { aic7xxx_patch0_func, 258, 1, 1 },
- { aic7xxx_patch11_func, 265, 1, 2 },
- { aic7xxx_patch0_func, 266, 1, 1 },
- { aic7xxx_patch5_func, 328, 1, 2 },
- { aic7xxx_patch0_func, 329, 1, 1 },
- { aic7xxx_patch3_func, 332, 1, 1 },
- { aic7xxx_patch11_func, 351, 1, 2 },
- { aic7xxx_patch0_func, 352, 1, 1 },
- { aic7xxx_patch6_func, 356, 1, 1 },
- { aic7xxx_patch7_func, 364, 3, 2 },
- { aic7xxx_patch0_func, 367, 1, 1 },
- { aic7xxx_patch1_func, 396, 3, 1 },
- { aic7xxx_patch10_func, 410, 1, 1 },
- { aic7xxx_patch2_func, 453, 7, 2 },
- { aic7xxx_patch0_func, 460, 8, 1 },
- { aic7xxx_patch2_func, 469, 4, 2 },
- { aic7xxx_patch0_func, 473, 6, 1 },
- { aic7xxx_patch2_func, 479, 4, 2 },
- { aic7xxx_patch0_func, 483, 3, 1 },
- { aic7xxx_patch2_func, 512, 17, 4 },
- { aic7xxx_patch12_func, 520, 4, 2 },
- { aic7xxx_patch0_func, 524, 2, 1 },
- { aic7xxx_patch0_func, 529, 33, 1 },
- { aic7xxx_patch6_func, 566, 2, 1 },
- { aic7xxx_patch6_func, 569, 9, 1 },
+ { aic7xxx_patch3_func, 9, 1, 1 },
+ { aic7xxx_patch4_func, 12, 4, 1 },
+ { aic7xxx_patch5_func, 17, 3, 2 },
+ { aic7xxx_patch0_func, 20, 4, 1 },
+ { aic7xxx_patch6_func, 24, 1, 1 },
+ { aic7xxx_patch7_func, 27, 1, 1 },
+ { aic7xxx_patch2_func, 30, 1, 2 },
+ { aic7xxx_patch0_func, 31, 3, 1 },
+ { aic7xxx_patch4_func, 40, 4, 1 },
+ { aic7xxx_patch8_func, 44, 3, 2 },
+ { aic7xxx_patch0_func, 47, 3, 1 },
+ { aic7xxx_patch9_func, 52, 7, 1 },
+ { aic7xxx_patch4_func, 60, 3, 1 },
+ { aic7xxx_patch8_func, 63, 2, 1 },
+ { aic7xxx_patch1_func, 68, 60, 1 },
+ { aic7xxx_patch8_func, 162, 1, 2 },
+ { aic7xxx_patch0_func, 163, 2, 1 },
+ { aic7xxx_patch2_func, 167, 2, 3 },
+ { aic7xxx_patch8_func, 167, 1, 1 },
+ { aic7xxx_patch0_func, 169, 2, 1 },
+ { aic7xxx_patch8_func, 172, 1, 2 },
+ { aic7xxx_patch0_func, 173, 1, 1 },
+ { aic7xxx_patch2_func, 177, 1, 1 },
+ { aic7xxx_patch2_func, 180, 3, 2 },
+ { aic7xxx_patch0_func, 183, 5, 1 },
+ { aic7xxx_patch2_func, 191, 2, 3 },
+ { aic7xxx_patch8_func, 191, 1, 1 },
+ { aic7xxx_patch0_func, 193, 3, 1 },
+ { aic7xxx_patch10_func, 196, 2, 1 },
+ { aic7xxx_patch8_func, 198, 7, 2 },
+ { aic7xxx_patch0_func, 205, 1, 1 },
+ { aic7xxx_patch2_func, 210, 14, 3 },
+ { aic7xxx_patch10_func, 223, 1, 1 },
+ { aic7xxx_patch0_func, 224, 9, 1 },
+ { aic7xxx_patch8_func, 238, 2, 1 },
+ { aic7xxx_patch8_func, 240, 1, 1 },
+ { aic7xxx_patch10_func, 241, 6, 3 },
+ { aic7xxx_patch2_func, 241, 2, 2 },
+ { aic7xxx_patch0_func, 243, 4, 1 },
+ { aic7xxx_patch8_func, 248, 1, 1 },
+ { aic7xxx_patch8_func, 252, 11, 1 },
+ { aic7xxx_patch2_func, 264, 3, 3 },
+ { aic7xxx_patch10_func, 266, 1, 1 },
+ { aic7xxx_patch0_func, 267, 5, 1 },
+ { aic7xxx_patch10_func, 272, 1, 2 },
+ { aic7xxx_patch0_func, 273, 7, 1 },
+ { aic7xxx_patch11_func, 287, 1, 2 },
+ { aic7xxx_patch0_func, 288, 1, 1 },
+ { aic7xxx_patch5_func, 348, 1, 2 },
+ { aic7xxx_patch0_func, 349, 1, 1 },
+ { aic7xxx_patch3_func, 352, 1, 1 },
+ { aic7xxx_patch2_func, 362, 3, 2 },
+ { aic7xxx_patch0_func, 365, 5, 1 },
+ { aic7xxx_patch11_func, 373, 1, 2 },
+ { aic7xxx_patch0_func, 374, 1, 1 },
+ { aic7xxx_patch6_func, 379, 1, 1 },
+ { aic7xxx_patch1_func, 416, 3, 1 },
+ { aic7xxx_patch10_func, 421, 11, 1 },
+ { aic7xxx_patch2_func, 469, 7, 2 },
+ { aic7xxx_patch0_func, 476, 8, 1 },
+ { aic7xxx_patch2_func, 485, 4, 2 },
+ { aic7xxx_patch0_func, 489, 6, 1 },
+ { aic7xxx_patch2_func, 495, 4, 2 },
+ { aic7xxx_patch0_func, 499, 3, 1 },
+ { aic7xxx_patch12_func, 509, 10, 1 },
+ { aic7xxx_patch2_func, 528, 17, 4 },
+ { aic7xxx_patch13_func, 536, 4, 2 },
+ { aic7xxx_patch0_func, 540, 2, 1 },
+ { aic7xxx_patch0_func, 545, 33, 1 },
+ { aic7xxx_patch12_func, 578, 4, 1 },
+ { aic7xxx_patch6_func, 582, 2, 1 },
+ { aic7xxx_patch6_func, 585, 9, 1 },
X
X };
diff -u --recursive --new-file v2.2.9/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.2.9/linux/drivers/scsi/scsi.c Tue May 11 13:10:30 1999
+++ linux/drivers/scsi/scsi.c Mon Jun 7 10:53:03 1999
@@ -109,6 +109,7 @@
X #define BLIST_SINGLELUN 0x10
X #define BLIST_NOTQ 0x20
X #define BLIST_SPARSELUN 0x40
+#define BLIST_MAX5LUN 0x80
X
X /*
X * Data declarations.
@@ -262,6 +263,7 @@
X {"HP", "C1790A", "", BLIST_NOLUN}, /* scanjet iip */
X {"HP", "C2500A", "", BLIST_NOLUN}, /* scanjet iicx */
X {"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* extra reset */
+{"RELISYS", "Scorpio", "*", BLIST_NOLUN}, /* responds to all LUN */
X
X /*
X * Other types of devices that have special flags.
@@ -273,6 +275,7 @@
X {"INSITE","I325VM","*", BLIST_KEY},
X {"NRC","MBR-7","*", BLIST_FORCELUN | BLIST_SINGLELUN},
X {"NRC","MBR-7.4","*", BLIST_FORCELUN | BLIST_SINGLELUN},
+{"REGAL","CDC-4X","*", BLIST_MAX5LUN | BLIST_SINGLELUN},
X {"NAKAMICH","MJ-4.8S","*", BLIST_FORCELUN | BLIST_SINGLELUN},
X {"NAKAMICH","MJ-5.16S","*", BLIST_FORCELUN | BLIST_SINGLELUN},
X {"PIONEER","CD-ROM DRM-600","*", BLIST_FORCELUN | BLIST_SINGLELUN},
@@ -932,6 +935,15 @@
X *max_dev_lun = 8;
X return 1;
X }
+
+ /*
+ * REGAL CDC-4X: avoid hang after LUN 4
+ */
+ if (bflags & BLIST_MAX5LUN) {
+ *max_dev_lun = 5;
+ return 1;
+ }
+
X /*
X * We assume the device can't handle lun!=0 if: - it reports scsi-0 (ANSI
X * SCSI Revision 0) (old drives like MAXTOR XT-3280) or - it reports scsi-1
diff -u --recursive --new-file v2.2.9/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v2.2.9/linux/drivers/scsi/scsi.h Tue Mar 23 14:35:48 1999
+++ linux/drivers/scsi/scsi.h Wed Jun 9 16:59:34 1999
@@ -296,6 +296,7 @@
X #define SCSI_1 1
X #define SCSI_1_CCS 2
X #define SCSI_2 3
+#define SCSI_3 4
X
X /*
X * Every SCSI command starts with a one byte OP-code.
diff -u --recursive --new-file v2.2.9/linux/drivers/scsi/scsi_proc.c linux/drivers/scsi/scsi_proc.c
--- v2.2.9/linux/drivers/scsi/scsi_proc.c Mon Jan 4 15:08:17 1999
+++ linux/drivers/scsi/scsi_proc.c Wed Jun 9 16:59:34 1999
@@ -298,7 +298,7 @@
X scd->type < MAX_SCSI_DEVICE_CODE ?
X scsi_device_types[(int)scd->type] : "Unknown " );
X y += sprintf(buffer + len + y, " ANSI"
- " SCSI revision: %02x", (scd->scsi_level < 3)?1:2);
+ " SCSI revision: %02x", (scd->scsi_level - 1)?scd->scsi_level - 1:1);
X if (scd->scsi_level == 2)
X y += sprintf(buffer + len + y, " CCS\n");
X else
diff -u --recursive --new-file v2.2.9/linux/drivers/scsi/scsi_syms.c linux/drivers/scsi/scsi_syms.c
--- v2.2.9/linux/drivers/scsi/scsi_syms.c Mon Jan 4 15:08:17 1999
+++ linux/drivers/scsi/scsi_syms.c Wed Jun 9 16:59:34 1999
@@ -27,13 +27,11 @@
X #include "constants.h"
X
X #include "sd.h"
+#include <scsi/scsicam.h>
X /*
X * This source file contains the symbol table used by scsi loadable
X * modules.
X */
-extern int scsicam_bios_param (Disk * disk,
- int dev, int *ip );
-
X
X extern void print_command (unsigned char *command);
X extern void print_sense(const char * devclass, Scsi_Cmnd * SCpnt);
@@ -47,6 +45,7 @@
X EXPORT_SYMBOL(scsi_register);
X EXPORT_SYMBOL(scsi_unregister);
X EXPORT_SYMBOL(scsicam_bios_param);
+EXPORT_SYMBOL(scsi_partsize);
X EXPORT_SYMBOL(scsi_allocate_device);
X EXPORT_SYMBOL(scsi_do_cmd);
X EXPORT_SYMBOL(scsi_command_size);
diff -u --recursive --new-file v2.2.9/linux/drivers/scsi/scsicam.c linux/drivers/scsi/scsicam.c
--- v2.2.9/linux/drivers/scsi/scsicam.c Thu Nov 12 16:21:21 1998
+++ linux/drivers/scsi/scsicam.c Wed Jun 9 16:59:34 1999
@@ -21,9 +21,8 @@
X #include "scsi.h"
X #include "hosts.h"
X #include "sd.h"
+#include <scsi/scsicam.h>
X
-static int partsize(struct buffer_head *bh, unsigned long capacity,
- unsigned int *cyls, unsigned int *hds, unsigned int *secs);
X static int setsize(unsigned long capacity,unsigned int *cyls,unsigned int *hds,
X unsigned int *secs);
X
@@ -51,7 +50,7 @@
X return -1;
X
X /* try to infer mapping from partition table */
- ret_code = partsize (bh, (unsigned long) size, (unsigned int *) ip + 2,
+ ret_code = scsi_partsize (bh, (unsigned long) size, (unsigned int *) ip + 2,
X (unsigned int *) ip + 0, (unsigned int *) ip + 1);
X brelse (bh);
X
@@ -80,7 +79,7 @@
X }
X
X /*
- * Function : static int partsize(struct buffer_head *bh, unsigned long
+ * Function : static int scsi_partsize(struct buffer_head *bh, unsigned long
X * capacity,unsigned int *cyls, unsigned int *hds, unsigned int *secs);
X *
X * Purpose : to determine the BIOS mapping used to create the partition
@@ -90,7 +89,7 @@


X *
X */
X

-static int partsize(struct buffer_head *bh, unsigned long capacity,
+int scsi_partsize(struct buffer_head *bh, unsigned long capacity,
X unsigned int *cyls, unsigned int *hds, unsigned int *secs) {
X struct partition *p, *largest = NULL;
X int i, largest_cyl;
diff -u --recursive --new-file v2.2.9/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.2.9/linux/drivers/scsi/sd.c Tue May 11 13:10:30 1999
+++ linux/drivers/scsi/sd.c Mon Jun 7 16:51:01 1999
@@ -1729,7 +1729,7 @@
X static void sd_detach(Scsi_Device * SDp)
X {
X Scsi_Disk * dpnt;
- int i;
+ int i, j;
X int max_p;
X int start;
X
@@ -1741,8 +1741,8 @@
X max_p = sd_gendisk.max_p;
X start = i << sd_gendisk.minor_shift;
X
- for (i=max_p - 1; i >=0 ; i--) {
- int index = start+i;
+ for (j=max_p - 1; j >=0 ; j--) {
+ int index = start+j;
X kdev_t devi = MKDEV_SD_PARTITION(index);
X struct super_block *sb = get_super(devi);
X sync_dev(devi);
@@ -1759,7 +1759,7 @@
X SDp->attached--;
X sd_template.dev_noticed--;
X sd_template.nr_dev--;
- SD_GENDISK(start).nr_real--;
+ SD_GENDISK(i).nr_real--;
X return;
X }
X return;
diff -u --recursive --new-file v2.2.9/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- v2.2.9/linux/drivers/scsi/sg.c Tue May 11 13:10:30 1999
+++ linux/drivers/scsi/sg.c Mon Jun 7 16:27:06 1999
@@ -16,12 +16,10 @@
X *
X * Borrows code from st driver. Thanks to Alessandro Rubini's "dd" book.
X */
- static char * sg_version_str = "Version: 2.1.32 (990501)";
+ static char * sg_version_str = "Version: 2.1.34 (990603)";
+ static int sg_version_num = 20134; /* 2 digits for each component */
X /*
- * D. P. Gilbert (dgil...@interlog.com, do...@triode.net.au)
- * - scatter list logic replaces previous large atomic SG_BIG_BUFF
- * sized allocation. See notes in <scsi/sg.h> include file.
- *
+ * D. P. Gilbert (dgil...@interlog.com, do...@triode.net.au), notes:
X * - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
X * the kernel/module needs to be built with CONFIG_SCSI_LOGGING
X * (otherwise the macros compile to empty statements), then do
@@ -34,13 +32,27 @@
X * Should use hlcomplete but it is too "noisy" (sd uses it).
X *
X * - This driver obtains memory (heap) for the low-level driver to
- * transfer/dma to and from. It is obtained from up to 4 sources:
- * - 1 SG_SCATTER_SZ sized buffer on open() (per fd)
- * [could be less if SG_SCATTER_SZ bytes not available]
- * - obtain heap as required on write()s (get_free_pages)
+ * transfer/dma to and from. It is obtained from up to 3 sources:
+ * - obtain heap via get_free_pages()
X * - obtain heap from the shared scsi dma pool
X * - obtain heap from kernel directly (kmalloc) [last choice]
- * the 'alt_address' field in the scatter_list structure and the
+ * Each open() attempts to obtain a "reserve" buffer of
+ * SG_DEF_RESERVED_SIZE bytes (or 0 bytes if opened O_RDONLY). The
+ * amount actually obtained [which could be 0 bytes] can be found from
+ * the SG_GET_RESERVED_SIZE ioctl(). This reserved buffer size can
+ * be changed by calling the SG_SET_RESERVED_SIZE ioctl(). Since this
+ * is an ambit claim, it should be followed by a SG_GET_RESERVED_SIZE
+ * ioctl() to find out how much was actually obtained.
+ * A subsequent write() to this file descriptor will use the
+ * reserved buffer unless:
+ * - it is already in use (eg during command queuing)
+ * - or the write() needs a buffer size larger than the
+ * reserved size
+ * In these cases the write() will attempt to get the required memory
+ * for the duration of this request but, if memory is low, it may
+ * fail with ENOMEM.
+ *
+ * - The 'alt_address' field in the scatter_list structure and the
X * related 'mem_src' indicate the source of the heap allocation.
X *
X */
@@ -67,11 +79,11 @@
X #include <scsi/sg.h>
X
X
-int sg_big_buff = SG_SCATTER_SZ; /* sg_big_buff is ro through sysctl */
+int sg_big_buff = SG_DEF_RESERVED_SIZE; /* sg_big_buff is ro through sysctl */
X /* N.B. This global is here to keep existing software happy. It now holds
- the size of the "first buffer" of the most recent sucessful sg_open().
+ the size of the reserve buffer of the most recent sucessful sg_open().
X Only available when 'sg' compiled into kernel (rather than a module).
- This should probably be deprecated (use SG_GET_RESERVED_SIZE instead). */
+ This is deprecated (use SG_GET_RESERVED_SIZE ioctl() instead). */
X
X #define SG_SECTOR_SZ 512
X #define SG_SECTOR_MSK (SG_SECTOR_SZ - 1)
@@ -89,7 +101,6 @@
X static int sg_num_page = 0;
X #endif
X
-#define SG_HEAP_FB 0 /* heap obtained at open() (one buffer per fd) */
X #define SG_HEAP_PAGE 1 /* heap from kernel via get_free_pages() */
X #define SG_HEAP_KMAL 2 /* heap from kernel via kmalloc() */
X #define SG_HEAP_POOL 3 /* heap from scsi dma pool (mid-level) */
@@ -112,9 +123,9 @@
X {
X unsigned short use_sg; /* Number of pieces of scatter-gather */
X unsigned short sglist_len; /* size of malloc'd scatter-gather list */
- unsigned bufflen; /* Size of data buffer */
+ unsigned bufflen; /* Size of (aggregate) data buffer */
X unsigned b_malloc_len; /* actual len malloc'ed in buffer */
- void * buffer; /* Data buffer or scatter list (12 bytes) */
+ void * buffer; /* Data buffer or scatter list,12 bytes each*/
X char mem_src; /* heap whereabouts of 'buffer' */
X } Sg_scatter_hold; /* 20 bytes long on i386 */
X
@@ -126,10 +137,10 @@
X Scsi_Cmnd * my_cmdp; /* NULL -> ready to read, else id */
X struct sg_request * nextrp; /* NULL -> tail request (slist) */
X struct sg_fd * parentfp; /* NULL -> not in use */
- Sg_scatter_hold data; /* hold buffers, perhaps scatter list */
- struct sg_header header; /* scsi command+info <include/sg.h> */
- char fb_used; /* 1 -> using fst_buf, normally 0 (used) */
-} Sg_request; /* around 72 bytes long on i386 */
+ Sg_scatter_hold data; /* hold buffer, perhaps scatter list */
+ struct sg_header header; /* scsi command+info, see <scsi/sg.h> */
+ char res_used; /* 1 -> using reserve buffer, 0 -> not ... */
+} Sg_request; /* 72 bytes long on i386 */
X
X typedef struct sg_fd /* holds the state of a file descriptor */
X {
@@ -137,41 +148,52 @@
X struct sg_device * parentdp; /* owning device */
X struct wait_queue * read_wait; /* queue read until command done */
X int timeout; /* defaults to SG_DEFAULT_TIMEOUT */
- char * fst_buf; /* try to grab SG_SCATTER_SZ sized buffer on open */
- int fb_size; /* actual size of allocated fst_buf */
- Sg_request * headrp; /* head of request slist, NULL->empty */
+ Sg_scatter_hold reserve; /* buffer held for this file descriptor */
+ unsigned save_scat_len; /* original length of trunc. scat. element */
+ Sg_request * headrp; /* head of request slist, NULL->empty */
X struct fasync_struct * async_qp; /* used by asynchronous notification */
X Sg_request req_arr[SG_MAX_QUEUE]; /* used as singly-linked list */
- char low_dma; /* as in parent but possible overridden to 1 */
+ char low_dma; /* as in parent but possibly overridden to 1 */
X char force_packid; /* 1 -> pack_id input to read(), 0 -> ignored */
X char closed; /* 1 -> fd closed but request(s) outstanding */
- char my_mem_src; /* heap whereabouts of this sg_fb object */
+ char my_mem_src; /* heap whereabouts of this Sg_fd object */
X char cmd_q; /* 1 -> allow command queuing, 0 -> don't */
X char underrun_flag; /* 1 -> flag underruns, 0 -> don't, 2 -> test */
-} Sg_fd; /* around 1192 bytes long on i386 */
+ char next_cmd_len; /* 0 -> automatic (def), >0 -> use on next write() */
+} Sg_fd; /* 1208 bytes long on i386 */
X
X typedef struct sg_device /* holds the state of each scsi generic device */
X {
X Scsi_Device * device;
- struct wait_queue * generic_wait;/* queue open if O_EXCL on prev. open */
+ struct wait_queue * o_excl_wait; /* queue open() when O_EXCL in use */
X int sg_tablesize; /* adapter's max scatter-gather table size */
X Sg_fd * headfp; /* first open fd belonging to this device */
X kdev_t i_rdev; /* holds device major+minor number */
X char exclude; /* opened for exclusive access */
X char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */
- unsigned char merge_fd; /* 0->sequencing per fd (def) else fd count */
-} Sg_device; /* around 24 bytes long on i386 */
+ unsigned char merge_fd; /* 0->sequencing per fd, else fd count */
+} Sg_device; /* 24 bytes long on i386 */
X
X
X static int sg_fasync(int fd, struct file * filp, int mode);
X static void sg_command_done(Scsi_Cmnd * SCpnt);
-static int sg_sc_build(Sg_request * srp, int max_buff_size,
- const char * inp, int num_write_xfer);
-static int sg_sc_undo_rem(Sg_request * srp, char * outp,
- int num_read_xfer);


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

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

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.2/patch-2.2.10/part15

#!/bin/sh
# this is part 15 of a 22 - part archive


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

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

-static char * sg_malloc(Sg_request * srp, int size, int * retSzp,
+static int sg_start_req(Sg_request * srp, int max_buff_size,
+ const char * inp, int num_write_xfer);
+static void sg_finish_rem_req(Sg_request * srp, char * outp,
+ int num_read_xfer);
+static int sg_build_scat(Sg_scatter_hold * schp, int buff_size,
+ const Sg_fd * sfp);
+static void sg_write_xfer(Sg_scatter_hold * schp, const char * inp,
+ int num_write_xfer);
+static void sg_remove_scat(Sg_scatter_hold * schp);
+static void sg_read_xfer(Sg_scatter_hold * schp, char * outp,
+ int num_read_xfer);
+static void sg_build_reserve(Sg_fd * sfp, int req_size);
+static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
+static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
+static char * sg_malloc(const Sg_fd * sfp, int size, int * retSzp,
X int * mem_srcp);
-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 static char * sg_low_malloc(int rqSz, int lowDma, int mem_src,
X int * retSzp);
X static void sg_low_free(char * buff, int size, int mem_src);
@@ -180,7 +202,7 @@
X static Sg_request * sg_get_request(const Sg_fd * sfp, int pack_id);
X static Sg_request * sg_add_request(Sg_fd * sfp);
X static int sg_remove_request(Sg_fd * sfp, const Sg_request * srp);
-static int sg_fb_in_use(const Sg_fd * sfp);
+static int sg_res_in_use(const Sg_fd * sfp);
X static void sg_clr_scpnt(Scsi_Cmnd * SCpnt);
X static void sg_shorten_timeout(Scsi_Cmnd * scpnt);
X static void sg_debug(const Sg_device * sdp, const Sg_fd * sfp, int part_of);
@@ -197,6 +219,7 @@
X int flags = filp->f_flags;
X Sg_device * sdp;
X Sg_fd * sfp;
+ int res;
X
X if ((NULL == sg_dev_arr) || (dev < 0) || (dev >= sg_template.dev_max))
X return -ENXIO;
@@ -207,38 +230,35 @@
X printk("sg_open: inode maj=%d, min=%d sdp maj=%d, min=%d\n",
X MAJOR(inode->i_rdev), MINOR(inode->i_rdev),
X MAJOR(sdp->i_rdev), MINOR(sdp->i_rdev));
+ /* If we are in the middle of error recovery, don't let anyone
+ * else try and use this device. Also, if error recovery fails, it
+ * may try and take the device offline, in which case all further
+ * access to the device is prohibited. */
X if(! scsi_block_when_processing_errors(sdp->device))
X return -ENXIO;
-/* if (O_RDWR != (flags & O_ACCMODE)) */
-/* return -EACCES; May just want to get to a ioctl, so remove */
X
X SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags));
- /* If we want exclusive access, then wait until the device is not
- * busy, and then set the flag to prevent anyone else from using it. */
+
X if (flags & O_EXCL) {
X if (O_RDONLY == (flags & O_ACCMODE))
X return -EACCES; /* Can't lock it with read only access */
- while (sdp->headfp) {
- if (flags & O_NONBLOCK)
- return -EBUSY;
- interruptible_sleep_on(&sdp->generic_wait);
- if (signal_pending(current))
- return -ERESTARTSYS;
- }
- sdp->exclude = 1;
- }
- else { /* Wait until nobody has an exclusive open on this device. */
- while (sdp->exclude) {
- if (flags & O_NONBLOCK)
- return -EBUSY;
- interruptible_sleep_on(&sdp->generic_wait);
- if (signal_pending(current))
- return -ERESTARTSYS;
- }
+ if (sdp->headfp && (filp->f_flags & O_NONBLOCK))
+ return -EBUSY;
+ res = 0; /* following is a macro that beats race condition */
+ __wait_event_interruptible(sdp->o_excl_wait,
+ ((sdp->headfp || sdp->exclude) ? 0 : (sdp->exclude = 1)),
+ res);
+ if (res)
+ return res; /* -ERESTARTSYS because signal hit process */
+ }
+ else if (sdp->exclude) { /* some other fd has an exclusive lock on dev */
+ if (filp->f_flags & O_NONBLOCK)
+ return -EBUSY;
+ res = 0; /* following is a macro that beats race condition */
+ __wait_event_interruptible(sdp->o_excl_wait, (! sdp->exclude), res);
+ if (res)
+ return res; /* -ERESTARTSYS because signal hit process */
X }
- /* OK, we should have grabbed the device. Mark the thing so
- * that other processes know that we have it, and initialize the
- * state variables to known values. */
X if (! sdp->headfp) { /* no existing opens on this device */
X sdp->sgdebug = 0;
X sdp->sg_tablesize = sdp->device->host->sg_tablesize;
@@ -284,16 +304,14 @@
X if(sg_template.module)
X __MOD_DEC_USE_COUNT(sg_template.module);
X sdp->exclude = 0;
- wake_up_interruptible(&sdp->generic_wait);
+ wake_up_interruptible(&sdp->o_excl_wait);


X return 0;
X }
X

-/* Read back the results of a SCSI command which was sent in a prior
- write(). */
X static ssize_t sg_read(struct file * filp, char * buf,
X size_t count, loff_t *ppos)
X {
- int k;
+ int k, res;
X Sg_device * sdp;
X Sg_fd * sfp;
X Sg_request * srp;
@@ -305,13 +323,8 @@
X SCSI_LOG_TIMEOUT(3, printk("sg_read: dev=%d, count=%d\n",
X MINOR(sdp->i_rdev), (int)count));
X
- /* If we are in the middle of error recovery, don't let anyone
- * else try and use this device. Also, if error recovery fails, it
- * may try and take the device offline, in which case all further
- * access to the device is prohibited. */
X if(! scsi_block_when_processing_errors(sdp->device))
X return -ENXIO;
-
X if (ppos != &filp->f_pos)
X ; /* FIXME: Hmm. Seek to the right place, or fail? */
X if ((k = verify_area(VERIFY_WRITE, buf, count)))
@@ -319,13 +332,15 @@
X if (sfp->force_packid && (count >= size_sg_header))
X req_pack_id = shp->pack_id;
X srp = sg_get_request(sfp, req_pack_id);
- while(! srp) {
+ if (! srp) { /* now wait on packet to arrive */
X if (filp->f_flags & O_NONBLOCK)
X return -EAGAIN;
- interruptible_sleep_on(&sfp->read_wait);
- if (signal_pending(current))
- return -ERESTARTSYS;
- srp = sg_get_request(sfp, req_pack_id);
+ res = 0; /* following is a macro that beats race condition */
+ __wait_event_interruptible(sfp->read_wait,
+ (srp = sg_get_request(sfp, req_pack_id)),
+ res);
+ if (res)
+ return res; /* -ERESTARTSYS because signal hit process */
X }
X if (2 != sfp->underrun_flag)
X srp->header.pack_len = srp->header.reply_len; /* Why ????? */
@@ -337,13 +352,13 @@
X if (count > srp->header.reply_len)
X count = srp->header.reply_len;
X if (count > size_sg_header) /* release does copy_to_user */
- sg_sc_undo_rem(srp, buf, count - size_sg_header);
+ sg_finish_rem_req(srp, buf, count - size_sg_header);
X else
- sg_sc_undo_rem(srp, NULL, 0);
+ sg_finish_rem_req(srp, NULL, 0);
X }
X else {
X count = (srp->header.result == 0) ? 0 : -EIO;
- sg_sc_undo_rem(srp, NULL, 0);
+ sg_finish_rem_req(srp, NULL, 0);
X }
X return count;
X }
@@ -366,22 +381,15 @@
X SCSI_LOG_TIMEOUT(3, printk("sg_write: dev=%d, count=%d\n",
X MINOR(sdp->i_rdev), (int)count));
X
-/* If we are in the middle of error recovery, don't let anyone
- * else try and use this device. Also, if error recovery fails, it
- * may try and take the device offline, in which case all further
- * access to the device is prohibited. */
X if(! scsi_block_when_processing_errors(sdp->device) )
X return -ENXIO;
-
X if (ppos != &filp->f_pos)
X ; /* FIXME: Hmm. Seek to the right place, or fail? */
X
X if ((k = verify_area(VERIFY_READ, buf, count)))
X return k; /* protects following copy_from_user()s + get_user()s */
-/* The minimum scsi command length is 6 bytes. If we get anything
- * less than this, it is clearly bogus. */
X if (count < (size_sg_header + 6))
- return -EIO;
+ return -EIO; /* The minimum scsi command length is 6 bytes. */
X
X srp = sg_add_request(sfp);
X if (! srp) {
@@ -392,55 +400,54 @@
X buf += size_sg_header;
X srp->header.pack_len = count;
X __get_user(opcode, buf);
- cmd_size = COMMAND_SIZE(opcode);
- if ((opcode >= 0xc0) && srp->header.twelve_byte)
- cmd_size = 12;
+ if (sfp->next_cmd_len > 0) {
+ if (sfp->next_cmd_len > MAX_COMMAND_SIZE) {
+ SCSI_LOG_TIMEOUT(1, printk("sg_write: command length too long\n"));
+ sfp->next_cmd_len = 0;
+ return -EDOM;
+ }
+ cmd_size = sfp->next_cmd_len;
+ sfp->next_cmd_len = 0; /* reset so only this write() effected */
+ }
+ else {
+ cmd_size = COMMAND_SIZE(opcode); /* based on SCSI command group */
+ if ((opcode >= 0xc0) && srp->header.twelve_byte)
+ cmd_size = 12;
+ }
X SCSI_LOG_TIMEOUT(4, printk("sg_write: scsi opcode=0x%02x, cmd_size=%d\n",
X (int)opcode, cmd_size));
X /* Determine buffer size. */
X input_size = count - cmd_size;
X mxsize = (input_size > srp->header.reply_len) ? input_size :
X srp->header.reply_len;
-/* Don't include the command header itself in the size. */
X mxsize -= size_sg_header;
X input_size -= size_sg_header;
-/* Verify user has actually passed enough bytes for this command. */
X if (input_size < 0) {
- sg_sc_undo_rem(srp, NULL, 0);
- return -EIO;
+ sg_remove_request(sfp, srp);
+ return -EIO; /* User did not pass enough bytes for this command. */
X }
-
-/* If we cannot allocate the buffer, report an error. */
- if ((k = sg_sc_build(srp, mxsize, buf + cmd_size, input_size))) {
+ if ((k = sg_start_req(srp, mxsize, buf + cmd_size, input_size))) {
X SCSI_LOG_TIMEOUT(1, printk("sg_write: build err=%d\n", k));
- sg_sc_undo_rem(srp, NULL, 0);
- return k;
+ sg_finish_rem_req(srp, NULL, 0);
+ return k; /* probably out of space --> ENOMEM */
X }
-
X /* SCSI_LOG_TIMEOUT(7, printk("sg_write: allocating device\n")); */
-/* Grab a command pointer for the device we want to talk to. If we
- * don't want to block, just return with the appropriate message. */
X if (! (SCpnt = scsi_allocate_device(NULL, sdp->device,
X !(filp->f_flags & O_NONBLOCK)))) {
- sg_sc_undo_rem(srp, NULL, 0);
- return -EAGAIN;
+ sg_finish_rem_req(srp, NULL, 0);
+ return -EAGAIN; /* No available command blocks at the moment */
X }
X /* SCSI_LOG_TIMEOUT(7, printk("sg_write: device allocated\n")); */
-
X srp->my_cmdp = SCpnt;
X SCpnt->request.rq_dev = sdp->i_rdev;
X SCpnt->request.rq_status = RQ_ACTIVE;
X SCpnt->sense_buffer[0] = 0;
X SCpnt->cmd_len = cmd_size;
- /* Now copy the SCSI command from the user's address space. */
X __copy_from_user(cmnd, buf, cmd_size);
-
-/* Set the LUN field in the command structure. */
+/* Set the LUN field in the command structure, overriding user input */
X cmnd[1]= (cmnd[1] & 0x1f) | (sdp->device->lun << 5);
+
X /* SCSI_LOG_TIMEOUT(7, printk("sg_write: do cmd\n")); */
-/* Now pass the actual command down to the low-level driver. We
- * do not do any more here - when the interrupt arrives, we will
- * then do the post-processing. */
X spin_lock_irqsave(&io_request_lock, flags);
X SCpnt->use_sg = srp->data.use_sg;
X SCpnt->sglist_len = srp->data.sglist_len;
@@ -454,6 +461,8 @@
X srp->data.sglist_len = 0;
X srp->data.bufflen = 0;
X srp->data.buffer = NULL;
+/* Now send everything of to mid-level. The next time we hear about this
+ packet is when sg_command_done() is called (ie a callback). */
X scsi_do_cmd(SCpnt, (void *)cmnd,
X (void *)SCpnt->buffer, mxsize,
X sg_command_done, sfp->timeout, SG_DEFAULT_RETRIES);
@@ -475,9 +484,6 @@
X return -ENXIO;
X SCSI_LOG_TIMEOUT(3, printk("sg_ioctl: dev=%d, cmd=0x%x\n",
X MINOR(sdp->i_rdev), (int)cmd_in));
- /* If we are in the middle of error recovery, then don't allow any
- * access to this device. Also, error recovery *may* have taken the
- * device offline, in which case all further access is prohibited. */
X if(! scsi_block_when_processing_errors(sdp->device) )
X return -ENXIO;
X
@@ -485,20 +491,18 @@
X {
X case SG_SET_TIMEOUT:
X return get_user(sfp->timeout, (int *)arg);
- case SG_GET_TIMEOUT:
+ case SG_GET_TIMEOUT: /* N.B. User receives timeout as return value */
X return sfp->timeout; /* strange ..., for backward compatibility */
X case SG_SET_FORCE_LOW_DMA:
X result = get_user(val, (int *)arg);
X if (result) return result;
X if (val) {
- if ((0 == sfp->low_dma) && (0 == sg_fb_in_use(sfp))) {
- sg_low_free(sfp->fst_buf, sfp->fb_size, SG_HEAP_PAGE);
- sfp->fst_buf = sg_low_malloc(SG_SCATTER_SZ, 1,
- SG_HEAP_PAGE, &sfp->fb_size);
- }
X sfp->low_dma = 1;
- if (! sfp->fst_buf)
- return -ENOMEM;
+ if ((0 == sfp->low_dma) && (0 == sg_res_in_use(sfp))) {
+ val = (int)sfp->reserve.bufflen;
+ sg_remove_scat(&sfp->reserve);
+ sg_build_reserve(sfp, val);
+ }
X }
X else
X sfp->low_dma = sdp->device->host->unchecked_isa_dma;
@@ -550,15 +554,20 @@
X case SG_GET_SG_TABLESIZE:
X return put_user(sdp->sg_tablesize, (int *)arg);
X case SG_SET_RESERVED_SIZE:
- /* currently ignored, future extension */
X if (O_RDWR != (filp->f_flags & O_ACCMODE))
X return -EACCES;
X result = get_user(val, (int *)arg);
X if (result) return result;
- /* logic should go here */
+ if (val != sfp->reserve.bufflen) {
+ if (sg_res_in_use(sfp))
+ return -EBUSY;
+ sg_remove_scat(&sfp->reserve);
+ sg_build_reserve(sfp, val);
+ }
X return 0;
X case SG_GET_RESERVED_SIZE:
- return put_user(sfp->fb_size, (int *)arg);
+ val = (int)sfp->reserve.bufflen;
+ return put_user(val, (int *)arg);
X case SG_GET_MERGE_FD:
X return put_user((int)sdp->merge_fd, (int *)arg);
X case SG_SET_MERGE_FD:
@@ -587,6 +596,13 @@
X return 0;
X case SG_GET_UNDERRUN_FLAG:
X return put_user((int)sfp->underrun_flag, (int *)arg);
+ case SG_NEXT_CMD_LEN:
+ result = get_user(val, (int *)arg);
+ if (result) return result;
+ sfp->next_cmd_len = (val > 0) ? val : 0;
+ return 0;
+ case SG_GET_VERSION_NUM:
+ return put_user(sg_version_num, (int *)arg);
X case SG_EMULATED_HOST:
X return put_user(sdp->device->host->hostt->emulated, (int *)arg);
X case SCSI_IOCTL_SEND_COMMAND:
@@ -594,8 +610,7 @@
X user already has read/write access to the generic device and so
X can execute arbitrary SCSI commands. */
X if (O_RDWR != (filp->f_flags & O_ACCMODE))
- return -EACCES; /* require write access since these could be
- dangerous */
+ return -EACCES; /* very dangerous things can be done here */
X return scsi_ioctl_send_command(sdp->device, (void *)arg);
X case SG_SET_DEBUG:
X result = get_user(val, (int *)arg);
@@ -613,8 +628,7 @@
X return scsi_ioctl(sdp->device, cmd_in, (void *)arg);
X default:
X if (O_RDWR != (filp->f_flags & O_ACCMODE))
- return -EACCES; /* require write access since these could be
- dangerous */
+ return -EACCES; /* don't know so take safe approach */
X return scsi_ioctl(sdp->device, cmd_in, (void *)arg);
X }
X }
@@ -664,8 +678,7 @@
X }
X
X /* This function is called by the interrupt handler when we
- * actually have a command that is complete. Change the
- * flags to indicate that we have a result. */
+ * actually have a command that is complete. */


X static void sg_command_done(Scsi_Cmnd * SCpnt)

X {
X int dev = MINOR(SCpnt->request.rq_dev);
@@ -712,17 +725,16 @@
X sg_clr_scpnt(SCpnt);
X srp->my_cmdp = NULL;
X
- SCSI_LOG_TIMEOUT(4,
- printk("sg__done: dev=%d, scsi_stat=%d, res=0x%x\n",
+ SCSI_LOG_TIMEOUT(4, printk("sg__done: dev=%d, scsi_stat=%d, res=0x%x\n",
X dev, (int)status_byte(SCpnt->result), (int)SCpnt->result));
-/* See if the command completed normally, or whether something went wrong. */
X memcpy(srp->header.sense_buffer, SCpnt->sense_buffer,
X sizeof(SCpnt->sense_buffer));
X switch (host_byte(SCpnt->result))
- {
+ { /* This setup of 'result' is for backward compatibility and is best
+ ignored by the user who should use target, host + driver status */
X case DID_OK:
- case DID_PASSTHROUGH: /* just guessing */
- case DID_SOFT_ERROR: /* just guessing */
+ case DID_PASSTHROUGH:
+ case DID_SOFT_ERROR:
X srp->header.result = 0;
X break;
X case DID_NO_CONNECT:
@@ -738,12 +750,6 @@
X srp->header.result = EIO;
X break;
X case DID_ERROR:
- /* There really should be DID_UNDERRUN and DID_OVERRUN error values,
- * and a means for callers of scsi_do_cmd to indicate whether an
- * underrun or overrun should signal an error. Until that can be
- * implemented, this kludge allows for returning useful error values
- * except in cases that return DID_ERROR that might be due to an
- * underrun. */
X if (SCpnt->sense_buffer[0] == 0 &&
X status_byte(SCpnt->result) == GOOD)
X srp->header.result = 0;
@@ -767,8 +773,6 @@
X /* filesystems using this device. */
X sdp->device->changed = 1;
X }
-
-/* Pick up error and status information */
X srp->header.target_status = status_byte(SCpnt->result);
X if ((sdp->sgdebug > 0) &&
X ((CHECK_CONDITION == srp->header.target_status) ||
@@ -784,15 +788,14 @@
X SCSI_LOG_TIMEOUT(1,
X printk("sg__done: already closed, freeing ...\n"));
X /* should check if module is unloaded <<<<<<< */
- sg_sc_undo_rem(srp, NULL, 0);
+ sg_finish_rem_req(srp, NULL, 0);
X if (NULL == sfp->headrp) {
X SCSI_LOG_TIMEOUT(1,
X printk("sg__done: already closed, final cleanup\n"));
X sg_remove_sfp(sdp, sfp);
X }
X }
-/* Now wake up the process that is waiting for the result. */
- /* A. Rubini says this is preferable+faster than wake_up() */
+/* Now wake up any sg_read() that is waiting for this packet. */
X wake_up_interruptible(&sfp->read_wait);
X if ((sfp->async_qp) && (! closed))
X kill_fasync(sfp->async_qp, SIGPOLL);
@@ -873,17 +876,20 @@
X printk(" *** Following data belongs to invoking FD ***\n");
X else if (! fp->parentdp)
X printk(">> Following FD has NULL parent pointer ???\n");
- printk(" FD(%d): timeout=%d, fb_size=%d, cmd_q=%d\n",
- k, fp->timeout, fp->fb_size, (int)fp->cmd_q);
- printk(" low_dma=%d, force_packid=%d, urun_flag=%d, closed=%d\n",
- (int)fp->low_dma, (int)fp->force_packid,
- (int)fp->underrun_flag, (int)fp->closed);
+ printk(" FD(%d): timeout=%d, bufflen=%d, use_sg=%d\n",
+ k, fp->timeout, fp->reserve.bufflen, (int)fp->reserve.use_sg);
+ printk(" low_dma=%d, cmd_q=%d, s_sc_len=%d, f_packid=%d\n",
+ (int)fp->low_dma, (int)fp->cmd_q, (int)fp->save_scat_len,
+ (int)fp->force_packid);
+ printk(" urun_flag=%d, next_cmd_len=%d, closed=%d\n",
+ (int)fp->underrun_flag, (int)fp->next_cmd_len,
+ (int)fp->closed);
X srp = fp->headrp;
X if (NULL == srp)
X printk(" No requests active\n");
X while (srp) {
- if (srp->fb_used)
- printk("using 1st buff >> ");
+ if (srp->res_used)
+ printk("reserved buff >> ");
X else
X printk(" ");
X if (srp->my_cmdp)
@@ -988,7 +994,7 @@
X
X SCSI_LOG_TIMEOUT(3, printk("sg_attach: dev=%d \n", k));
X sdp->device = scsidp;
- sdp->generic_wait = NULL;
+ sdp->o_excl_wait = NULL;
X sdp->headfp= NULL;
X sdp->exclude = 0;
X sdp->merge_fd = 0; /* Cope with SG_DEF_MERGE_FD on open */
@@ -1041,10 +1047,8 @@
X }
X scsidp->attached--;
X sg_template.nr_dev--;
- /*
- * avoid associated device /dev/sg? bying incremented
- * each time module is inserted/removed , <d...@lectra.fr>
- */
+/* avoid associated device /dev/sg? being incremented
+ * each time module is inserted/removed , <d...@lectra.fr> */
X sg_template.dev_noticed--;
X return;
X }
@@ -1099,42 +1103,80 @@
X #endif
X }
X

-static int sg_sc_build(Sg_request * srp, int max_buff_size,
- const char * inp, int num_write_xfer)

+static int sg_start_req(Sg_request * srp, int max_buff_size,
+ const char * inp, int num_write_xfer)
+{
+ int res;
+ Sg_fd * sfp = srp->parentfp;
+ Sg_scatter_hold * req_schp = &srp->data;
+ Sg_scatter_hold * rsv_schp = &sfp->reserve;
+
+ SCSI_LOG_TIMEOUT(4, printk("sg_start_req: max_buff_size=%d\n",
+ max_buff_size));
+ if ((! sg_res_in_use(sfp)) && (max_buff_size <= rsv_schp->bufflen)) {
+ sg_link_reserve(sfp, srp, max_buff_size);
+ sg_write_xfer(req_schp, inp, num_write_xfer);
+ }
+ else {
+ res = sg_build_scat(req_schp, max_buff_size, sfp);
+ if (res) {
+ sg_remove_scat(req_schp);
+ return res;
+ }
+ sg_write_xfer(req_schp, inp, num_write_xfer);


+ }
+ return 0;
+}
+

+static void sg_finish_rem_req(Sg_request * srp, char * outp,
+ int num_read_xfer)
+{
+ Sg_fd * sfp = srp->parentfp;
+ Sg_scatter_hold * req_schp = &srp->data;
+
+ SCSI_LOG_TIMEOUT(4, printk("sg_finish_rem_req: res_used=%d\n",
+ (int)srp->res_used));
+ if (num_read_xfer > 0)
+ sg_read_xfer(req_schp, outp, num_read_xfer);
+ if (srp->res_used)
+ sg_unlink_reserve(sfp, srp);
+ else
+ sg_remove_scat(req_schp);
+ sg_remove_request(sfp, srp);
+}
+
+static int sg_build_scat(Sg_scatter_hold * schp, int buff_size,
+ const Sg_fd * sfp)
X {
X int ret_sz, mem_src;
- int blk_size = max_buff_size;
+ int blk_size = buff_size;
X char * p = NULL;
X
- if ((blk_size < 0) || (! srp))
+ if ((blk_size < 0) || (! sfp))
X return -EFAULT;
-
- SCSI_LOG_TIMEOUT(4, printk("sg_sc_build: m_b_s=%d, num_write_xfer=%d\n",
- max_buff_size, num_write_xfer));
X if (0 == blk_size)
X ++blk_size; /* don't know why */
X /* round request up to next highest SG_SECTOR_SZ byte boundary */
X blk_size = (blk_size + SG_SECTOR_MSK) & (~SG_SECTOR_MSK);
- SCSI_LOG_TIMEOUT(5, printk("sg_sc_build: blk_size=%d\n", blk_size));
-
+ SCSI_LOG_TIMEOUT(4, printk("sg_build_scat: buff_size=%d, blk_size=%d\n",
+ buff_size, blk_size));
X if (blk_size <= SG_SCATTER_SZ) {
- mem_src = SG_HEAP_FB;
- p = sg_malloc(srp, blk_size, &ret_sz, &mem_src);
+ mem_src = SG_HEAP_PAGE;
+ p = sg_malloc(sfp, blk_size, &ret_sz, &mem_src);
X if (! p)
X return -ENOMEM;
X if (blk_size == ret_sz) { /* got it on the first attempt */
- srp->data.buffer = p;
- srp->data.bufflen = blk_size;
- srp->data.mem_src = mem_src;
- srp->data.b_malloc_len = blk_size;
- if (inp && (num_write_xfer > 0))
- __copy_from_user(srp->data.buffer, inp, num_write_xfer);
+ schp->use_sg = 0;
+ schp->buffer = p;
+ schp->bufflen = blk_size;
+ schp->mem_src = mem_src;
+ schp->b_malloc_len = blk_size;


X return 0;
X }
X }

X else {
X mem_src = SG_HEAP_PAGE;
- p = sg_malloc(srp, SG_SCATTER_SZ, &ret_sz, &mem_src);
+ p = sg_malloc(sfp, SG_SCATTER_SZ, &ret_sz, &mem_src);
X if (! p)
X return -ENOMEM;
X }
@@ -1144,23 +1186,23 @@
X int k, rem_sz, num, nxt;
X int sc_bufflen = PAGE_SIZE;
X int mx_sc_elems = (sc_bufflen / sizeof(struct scatterlist)) - 1;
- int sg_tablesize = srp->parentfp->parentdp->sg_tablesize;
+ int sg_tablesize = sfp->parentdp->sg_tablesize;
X int first = 1;
X
X k = SG_HEAP_KMAL; /* want to protect mem_src, use k as scratch */
- srp->data.buffer = (struct scatterlist *)sg_malloc(srp,
+ schp->buffer = (struct scatterlist *)sg_malloc(sfp,
X sc_bufflen, &num, &k);
- srp->data.mem_src = (char)k;
+ schp->mem_src = (char)k;
X /* N.B. ret_sz and mem_src carried into this block ... */
- if (! srp->data.buffer)
+ if (! schp->buffer)
X return -ENOMEM;
X else if (num != sc_bufflen) {
X sc_bufflen = num;
X mx_sc_elems = (sc_bufflen / sizeof(struct scatterlist)) - 1;
X }
- srp->data.sglist_len = sc_bufflen;
- memset(srp->data.buffer, 0, sc_bufflen);
- for (k = 0, sclp = srp->data.buffer, rem_sz = blk_size, nxt =0;
+ schp->sglist_len = sc_bufflen;
+ memset(schp->buffer, 0, sc_bufflen);
+ for (k = 0, sclp = schp->buffer, rem_sz = blk_size, nxt =0;
X (k < sg_tablesize) && (rem_sz > 0) && (k < mx_sc_elems);
X ++k, rem_sz -= ret_sz, ++sclp) {
X if (first)
@@ -1168,7 +1210,7 @@
X else {
X num = (rem_sz > SG_SCATTER_SZ) ? SG_SCATTER_SZ : rem_sz;
X mem_src = SG_HEAP_PAGE;
- p = sg_malloc(srp, num, &ret_sz, &mem_src);
+ p = sg_malloc(sfp, num, &ret_sz, &mem_src);
X if (! p)
X break;
X }
@@ -1176,73 +1218,188 @@
X sclp->length = ret_sz;
X sclp->alt_address = (char *)(long)mem_src;
X
- if(inp && (num_write_xfer > 0)) {
- num = (ret_sz > num_write_xfer) ? num_write_xfer : ret_sz;
- __copy_from_user(sclp->address, inp, num);
- num_write_xfer -= num;
- inp += num;
- }
X SCSI_LOG_TIMEOUT(5,
- printk("sg_sc_build: k=%d, a=0x%p, len=%d, ms=%d\n",
+ printk("sg_build_build: k=%d, a=0x%p, len=%d, ms=%d\n",
X k, sclp->address, ret_sz, mem_src));
X } /* end of for loop */
- srp->data.use_sg = k;
+ schp->use_sg = k;
X SCSI_LOG_TIMEOUT(5,
- printk("sg_sc_build: use_sg=%d, rem_sz=%d\n", k, rem_sz));
- srp->data.bufflen = blk_size;
+ printk("sg_build_scat: use_sg=%d, rem_sz=%d\n", k, rem_sz));
+ schp->bufflen = blk_size;
X if (rem_sz > 0) /* must have failed */
X return -ENOMEM;


X }
X return 0;
X }

X

-static int sg_sc_undo_rem(Sg_request * srp, char * outp,
- int num_read_xfer)

+static void sg_write_xfer(Sg_scatter_hold * schp, const char * inp,
+ int num_write_xfer)
X {
- if (! srp)
- return -EFAULT;
- SCSI_LOG_TIMEOUT(4, printk("sg_sc_undo_rem: num_read_xfer=%d\n",
- num_read_xfer));
- if (! outp)
- num_read_xfer = 0;
- if(srp->data.use_sg) {
- int k, num, mem_src;
- struct scatterlist * sclp = (struct scatterlist *)srp->data.buffer;
-
- for (k = 0; (k < srp->data.use_sg) && sclp->address; ++k, ++sclp) {
- if (num_read_xfer > 0) {
- num = (int)sclp->length;
- if (num > num_read_xfer) {
- __copy_to_user(outp, sclp->address, num_read_xfer);
- outp += num_read_xfer;
- num_read_xfer = 0;
- }
- else {
- __copy_to_user(outp, sclp->address, num);
- outp += num;
- num_read_xfer -= num;
- }
+ SCSI_LOG_TIMEOUT(4, printk("sg_write_xfer: num_write_xfer=%d, use_sg=%d\n",
+ num_write_xfer, schp->use_sg));
+ if ((! inp) || (num_write_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_write_xfer) {
+ __copy_from_user(sclp->address, inp, num_write_xfer);
+ break;
X }
+ else {
+ __copy_from_user(sclp->address, inp, num);
+ num_write_xfer -= num;
+ if (num_write_xfer <= 0)
+ break;
+ inp += num;
+ }
+ }
+ }
+ else
+ __copy_from_user(schp->buffer, inp, num_write_xfer);
+}
+
+static void sg_remove_scat(Sg_scatter_hold * schp)
+{
+ SCSI_LOG_TIMEOUT(4, printk("sg_remove_scat: use_sg=%d\n", schp->use_sg));
+ 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.2.9/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- v2.2.9/linux/drivers/scsi/sr_ioctl.c Tue May 11 13:10:30 1999
+++ linux/drivers/scsi/sr_ioctl.c Fri May 14 16:04:16 1999
@@ -122,11 +122,9 @@
X if (!quiet)
X printk(KERN_ERR "sr%d: CDROM (ioctl) reports ILLEGAL "
X "REQUEST.\n", target);
- if ((SCpnt->sense_buffer[12] == 0x20 ||
- SCpnt->sense_buffer[12] == 0x24) &&
+ if (SCpnt->sense_buffer[12] == 0x20 &&
X SCpnt->sense_buffer[13] == 0x00) {
X /* sense: Invalid command operation code */
- /* or Invalid field in cdb */
X err = -EDRIVE_CANT_DO_THIS;
X } else {
X err = -EINVAL;
diff -u --recursive --new-file v2.2.9/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v2.2.9/linux/drivers/scsi/st.c Wed Mar 10 15:29:47 1999
+++ linux/drivers/scsi/st.c Sat May 22 14:51:26 1999
@@ -11,7 +11,7 @@
X Copyright 1992 - 1999 Kai Makisara
X email Kai.Ma...@metla.fi
X
- Last modified: Sun Mar 7 09:03:17 1999 by makisara@home
+ Last modified: Tue May 18 09:29:52 1999 by makisara@home
X Some small formal changes - aeb, 950809
X */
X
@@ -164,8 +164,6 @@
X SCpnt->request_bufflen);
X if (driver_byte(result) & DRIVER_SENSE)
X print_sense("st", SCpnt);
- else
- printk("\n");
X }
X else
X #endif
@@ -289,6 +287,7 @@
X }
X else
X bp = (STp->buffer)->b_data;
+ SCpnt->cmd_len = 0;
X SCpnt->request.sem = &(STp->sem);
X SCpnt->request.rq_status = RQ_SCSI_BUSY;
X SCpnt->request.rq_dev = STp->devt;
@@ -3380,7 +3379,6 @@
X
X tpnt->devt = MKDEV(SCSI_TAPE_MAJOR, i);
X tpnt->dirty = 0;
- tpnt->waiting = NULL;
X tpnt->in_use = 0;
X tpnt->drv_buffer = 1; /* Try buffering if no mode sense */
X tpnt->restr_dma = (SDp->host)->unchecked_isa_dma;
diff -u --recursive --new-file v2.2.9/linux/drivers/scsi/st.h linux/drivers/scsi/st.h
--- v2.2.9/linux/drivers/scsi/st.h Wed Sep 9 14:51:09 1998
+++ linux/drivers/scsi/st.h Sat May 22 14:51:26 1999
@@ -65,7 +65,6 @@
X typedef struct {
X kdev_t devt;
X unsigned capacity;
- struct wait_queue * waiting;
X Scsi_Device* device;
X struct semaphore sem;
X ST_buffer * buffer;
diff -u --recursive --new-file v2.2.9/linux/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c
--- v2.2.9/linux/drivers/scsi/sym53c8xx.c Fri Apr 16 14:47:31 1999
+++ linux/drivers/scsi/sym53c8xx.c Sat May 22 13:42:53 1999
@@ -572,6 +572,8 @@
X #define remap_pci_mem(base, size) ((u_long) __va(base))
X #define unmap_pci_mem(vaddr, size)
X #define pcivtobus(p) ((p) & pci_dvma_mask)
+#elif defined(__alpha__)
+#define pcivtobus(p) ((p) & 0xfffffffful)
X #else /* __sparc__ */
X #define pcivtobus(p) (p)
X
diff -u --recursive --new-file v2.2.9/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c
--- v2.2.9/linux/drivers/sound/es1370.c Fri Apr 16 14:47:31 1999
+++ linux/drivers/sound/es1370.c Sat May 22 13:05:43 1999
@@ -33,8 +33,8 @@
X * to make the card a four channel one: use dsp to output two
X * channels to LINE and dac to output the other two channels to
X * SPKR. Set the mixer to only output synth to SPKR.
- * micz it looks like this changes the MIC input impedance. I don't know
- * any detail though.
+ * micbias sets the +5V bias to the mic if using an electretmic.
+ *
X *
X * Note: sync mode is not yet supported (i.e. running dsp and dac from the same
X * clock source)
@@ -92,6 +92,12 @@
X * Alpha fixes reported by Peter Jones <pjo...@redhat.com>
X * Note: joystick address handling might still be wrong on archs
X * other than i386
+ * 10.05.99 0.21 Added support for an electret mic for SB PCI64
+ * to the Linux kernel sound driver. This mod also straighten
+ * out the question marks around the mic impedance setting
+ * (micz). From Kim....@fisub.mail.abb.com
+ * 11.05.99 0.22 Implemented the IMIX call to mute recording monitor.
+ * Guenter Geiger <gei...@epy.co.at>
X *
X * some important things missing in Ensoniq documentation:
X *
@@ -107,8 +113,8 @@
X * The card uses a 22.5792 MHz crystal.
X * The LINEIN jack may be converted to an AOUT jack by
X * setting pin 47 (XCTL0) of the ES1370 to high.
- * Pin 48 (XCTL1) of the ES1370 presumably changes the input impedance of the
- * MIC jack.
+ * Pin 48 (XCTL1) of the ES1370 sets the +5V bias for an electretmic
+ *

X *
X */
X

@@ -190,7 +196,7 @@
X #define DAC2_DIVTOSR(x) (1411200/((x)+2))
X
X #define CTRL_ADC_STOP 0x80000000 /* 1 = ADC stopped */
-#define CTRL_XCTL1 0x40000000 /* ? mic impedance */
+#define CTRL_XCTL1 0x40000000 /* electret mic bias */
X #define CTRL_OPEN 0x20000000 /* no function, can be read and written */
X #define CTRL_PCLKDIV 0x1fff0000 /* ADC/DAC2 clock divider */
X #define CTRL_SH_PCLKDIV 16
@@ -301,6 +307,7 @@
X unsigned int recsrc;
X unsigned int modcnt;
X unsigned short micpreamp;
+ unsigned int imix;
X } mix;
X
X /* wave stuff */
@@ -839,7 +846,8 @@
X return put_user(s->mix.recsrc, (int *)arg);
X
X case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
- for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ val = SOUND_MASK_IMIX;
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
X if (mixtable[i].avail)
X val |= 1 << i;
X return put_user(val, (int *)arg);
@@ -858,6 +866,9 @@
X
X case SOUND_MIXER_CAPS:
X return put_user(0, (int *)arg);
+
+ case SOUND_MIXER_IMIX:
+ return put_user(s->mix.imix, (int *)arg);
X
X default:
X i = _IOC_NR(cmd);
@@ -870,6 +881,14 @@
X return -EINVAL;
X s->mix.modcnt++;
X switch (_IOC_NR(cmd)) {
+
+ case SOUND_MIXER_IMIX:
+ if (arg == 0)
+ return -EFAULT;
+ get_user_ret(s->mix.imix,(int *)arg, -EFAULT);
+ val = s->mix.recsrc;
+ /* fall through */
+
X case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
X get_user_ret(val, (int *)arg, -EFAULT);
X for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
@@ -886,7 +905,10 @@
X wrcodec(s, 0x13, j & 0xaa);
X wrcodec(s, 0x14, (j >> 8) & 0x17);
X wrcodec(s, 0x15, (j >> 8) & 0x0f);
- i = (j & 0x37f) | ((j << 1) & 0x3000) | 0xc30;
+ i = (j & 0x37f) | ((j << 1) & 0x3000) | 0xc60;
+ if (!s->mix.imix) {
+ i &= 0xff60; /* mute record and line monitor */
+ }
X wrcodec(s, 0x10, i);
X wrcodec(s, 0x11, i >> 8);
X return 0;
@@ -2262,7 +2284,7 @@
X static int joystick[NR_DEVICE] = { 0, };
X #endif
X static int lineout[NR_DEVICE] = { 0, };
-static int micz[NR_DEVICE] = { 0, };
+static int micbias[NR_DEVICE] = { 0, };
X
X /* --------------------------------------------------------------------- */


X
@@ -2295,7 +2317,7 @@
X

X if (!pci_present()) /* No PCI bus in this machine! */
X return -ENODEV;
- printk(KERN_INFO "es1370: version v0.20 time " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO "es1370: version v0.22 time " __TIME__ " " __DATE__ "\n");
X while (index < NR_DEVICE &&
X (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, pcidev))) {
X if (pcidev->base_address[0] == 0 ||
@@ -2328,8 +2350,10 @@
X goto err_irq;
X }
X /* initialize codec registers */
- s->ctrl = CTRL_CDC_EN | CTRL_SERR_DIS | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV) | (1 << CTRL_SH_WTSRSEL);
- if (joystick[index]) {
+ /* note: setting CTRL_SERR_DIS is reported to break
+ * mic bias setting (by Kim....@fisub.mail.abb.com) */
+ s->ctrl = CTRL_CDC_EN | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV) | (1 << CTRL_SH_WTSRSEL);
+ if (joystick[index]) {
X if (check_region(0x200, JOY_EXTENT))
X printk(KERN_ERR "es1370: io port 0x200 in use\n");
X else
@@ -2337,7 +2361,7 @@
X }
X if (lineout[index])
X s->ctrl |= CTRL_XCTL0;
- if (micz[index])
+ if (micbias[index])
X s->ctrl |= CTRL_XCTL1;
X s->sctrl = 0;
X printk(KERN_INFO "es1370: found adapter at io %#lx irq %u\n"
@@ -2361,6 +2385,7 @@
X wrcodec(s, 0x17, 0); /* CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off the LRCLK2 PLL; program DAC_SYNC=0!! */
X wrcodec(s, 0x18, 0); /* recording source is mixer */
X wrcodec(s, 0x19, s->mix.micpreamp = 1); /* turn on MIC preamp */
+ s->mix.imix = 1;
X fs = get_fs();
X set_fs(KERNEL_DS);
X val = SOUND_MASK_LINE|SOUND_MASK_SYNTH|SOUND_MASK_CD;
@@ -2403,8 +2428,8 @@
X MODULE_PARM_DESC(joystick, "if 1 enables joystick interface (still need separate driver)");
X MODULE_PARM(lineout, "1-" __MODULE_STRING(NR_DEVICE) "i");
X MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out");
-MODULE_PARM(micz, "1-" __MODULE_STRING(NR_DEVICE) "i");
-MODULE_PARM_DESC(micz, "changes (??) the microphone impedance");
+MODULE_PARM(micbias, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone");
X
X MODULE_AUTHOR("Thomas M. Sailer, sai...@ife.ee.ethz.ch, hb9...@hb9w.che.eu");
X MODULE_DESCRIPTION("ES1370 AudioPCI Driver");
diff -u --recursive --new-file v2.2.9/linux/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c
--- v2.2.9/linux/drivers/sound/sound_core.c Wed Mar 10 15:29:47 1999
+++ linux/drivers/sound/sound_core.c Mon Jun 7 11:06:06 1999
@@ -52,6 +52,22 @@
X struct sound_unit *next;
X };
X
+#ifdef CONFIG_SOUND_SONICVIBES
+extern int init_sonicvibes(void);
+#endif
+#ifdef CONFIG_SOUND_ES1370
+extern int init_es1370(void);
+#endif
+#ifdef CONFIG_SOUND_ES1371
+extern int init_es1371(void);
+#endif
+#ifdef CONFIG_SOUND_MSNDCLAS
+extern int msnd_classic_init(void);
+#endif
+#ifdef CONFIG_SOUND_MSNDPIN
+extern int msnd_pinnacle_init(void);
+#endif
+
X /*
X * Low level list operator. Scan the ordered list, find a hole and
X * join into it. Called with the lock asserted
@@ -132,7 +148,7 @@
X * This lock guards the sound loader list.
X */
X
-static spinlock_t sound_loader_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t sound_loader_lock = SPIN_LOCK_UNLOCKED;
X
X /*
X * Allocate the controlling structure and add it to the sound driver
diff -u --recursive --new-file v2.2.9/linux/drivers/video/cgsixfb.c linux/drivers/video/cgsixfb.c
--- v2.2.9/linux/drivers/video/cgsixfb.c Tue Mar 23 14:35:48 1999
+++ linux/drivers/video/cgsixfb.c Sat May 29 11:10:15 1999
@@ -1,4 +1,4 @@
-/* $Id: cgsixfb.c,v 1.16 1999/03/09 14:01:49 davem Exp $
+/* $Id: cgsixfb.c,v 1.16.2.1 1999/05/25 00:59:35 davem Exp $
X * cgsixfb.c: CGsix (GX,GXplus) frame buffer driver
X *
X * Copyright (C) 1996,1998 Jakub Jelinek (j...@ultra.linux.cz)
@@ -588,7 +588,7 @@
X p->screen_base += (y_margin - fb->y_margin) * p->line_length + (x_margin - fb->x_margin);
X }
X
-static char idstring[60] __initdata = { 0 };
+static char idstring[70] __initdata = { 0 };
X
X __initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
X {
@@ -599,6 +599,7 @@
X unsigned long phys = fb->sbdp->reg_addrs[0].phys_addr;
X u32 conf;
X char *p;
+ char *cardtype;
X struct bt_regs *bt;
X
X strcpy(fb->info.modename, "CGsix");
@@ -656,15 +657,29 @@
X case CG6_FHC_CPU_68020: p = "68020"; break;
X default: p = "i386"; break;
X }
+
+ if (((conf >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK) >= 11) {
+ if (fix->smem_len <= 0x100000) {
+ cardtype = "TurboGX";
+ } else {
+ cardtype = "TurboGX+";
+ }
+ } else {
+ if (fix->smem_len <= 0x100000) {
+ cardtype = "GX";
+ } else {
+ cardtype = "GX+";
+ }
+ }
X
X sprintf(idstring,
X #ifdef __sparc_v9__
- "cgsix at %016lx TEC Rev %x CPU %s Rev %x", phys,
+ "cgsix at %016lx TEC Rev %x CPU %s Rev %x [%s]", phys,
X #else
- "cgsix at %x.%08lx TEC Rev %x CPU %s Rev %x", fb->iospace, phys,
+ "cgsix at %x.%08lx TEC Rev %x CPU %s Rev %x [%s]", fb->iospace, phys,
X #endif
X (fb->s.cg6.thc->thc_misc >> CG6_THC_MISC_REV_SHIFT) & CG6_THC_MISC_REV_MASK,
- p, conf >> CG6_FHC_REV_SHIFT & CG6_FHC_REV_MASK);
+ p, conf >> CG6_FHC_REV_SHIFT & CG6_FHC_REV_MASK, cardtype);
X
X cg6_reset(fb);
X
diff -u --recursive --new-file v2.2.9/linux/drivers/video/fbcon.c linux/drivers/video/fbcon.c
--- v2.2.9/linux/drivers/video/fbcon.c Wed Apr 28 11:37:30 1999
+++ linux/drivers/video/fbcon.c Fri May 14 12:49:59 1999
@@ -2300,3 +2300,4 @@
X EXPORT_SYMBOL(fb_display);
X EXPORT_SYMBOL(fbcon_redraw_bmove);
X EXPORT_SYMBOL(fbcon_dummy);
+EXPORT_SYMBOL(fb_con);
diff -u --recursive --new-file v2.2.9/linux/drivers/video/mdacon.c linux/drivers/video/mdacon.c
--- v2.2.9/linux/drivers/video/mdacon.c Wed Mar 10 15:29:48 1999
+++ linux/drivers/video/mdacon.c Fri May 14 17:46:16 1999
@@ -597,7 +597,7 @@
X if (mda_first_vc > mda_last_vc)
X return;
X
- take_over_console(&mda_con, mda_first_vc, mda_last_vc, 0);
+ take_over_console(&mda_con, mda_first_vc-1, mda_last_vc-1, 0);


X }
X
X #ifdef MODULE

diff -u --recursive --new-file v2.2.9/linux/fs/Config.in linux/fs/Config.in
--- v2.2.9/linux/fs/Config.in Wed Mar 10 15:29:48 1999
+++ linux/fs/Config.in Sun Jun 13 19:54:06 1999
@@ -69,9 +69,9 @@
X fi
X if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
X tristate 'NFS server support' CONFIG_NFSD
- fi
- if [ "$CONFIG_NFSD" != "n" ]; then
- bool ' Emulate SUN NFS server' CONFIG_NFSD_SUN
+ if [ "$CONFIG_NFSD" != "n" ]; then
+ bool ' Emulate SUN NFS server' CONFIG_NFSD_SUN
+ fi
X fi
X if [ "$CONFIG_NFS_FS" = "y" -o "$CONFIG_NFSD" = "y" ]; then
X define_bool CONFIG_SUNRPC y
@@ -86,9 +86,6 @@
X fi
X fi
X tristate 'SMB filesystem support (to mount WfW shares etc.)' CONFIG_SMB_FS
- if [ "$CONFIG_SMB_FS" != "n" ]; then
- bool 'SMB Win95 bug work-around' CONFIG_SMB_WIN95
- fi
X fi
X if [ "$CONFIG_IPX" != "n" -o "$CONFIG_INET" != "n" ]; then
X tristate 'NCP filesystem support (to mount NetWare volumes)' CONFIG_NCP_FS
diff -u --recursive --new-file v2.2.9/linux/fs/adfs/dir.c linux/fs/adfs/dir.c
--- v2.2.9/linux/fs/adfs/dir.c Thu May 13 23:10:30 1999
+++ linux/fs/adfs/dir.c Thu May 13 23:25:58 1999
@@ -138,9 +138,6 @@
X struct super_block *sb;
X int i, size;
X
- if (!inode)
- return 0;
-
X sb = inode->i_sb;
X
X size = 2048 >> sb->s_blocksize_bits;
diff -u --recursive --new-file v2.2.9/linux/fs/adfs/namei.c linux/fs/adfs/namei.c
--- v2.2.9/linux/fs/adfs/namei.c Tue May 11 13:10:30 1999
+++ linux/fs/adfs/namei.c Thu May 13 23:25:58 1999
@@ -46,9 +46,6 @@
X unsigned long parent_object_id, dir_object_id;
X int buffers, pos;
X
- if (!S_ISDIR(dir->i_mode))
- return 0;
-
X sb = dir->i_sb;
X
X if (adfs_inode_validate (dir)) {
@@ -56,9 +53,6 @@
X "invalid inode number: %lu", dir->i_ino);
X return 0;
X }
-
- if (namelen > ADFS_NAME_LEN)
- return 0;
X
X if (!(buffers = adfs_dir_read (dir, bh))) {
X adfs_error (sb, "adfs_find_entry", "unable to read directory");
diff -u --recursive --new-file v2.2.9/linux/fs/autofs/dir.c linux/fs/autofs/dir.c
--- v2.2.9/linux/fs/autofs/dir.c Wed Apr 28 11:37:30 1999
+++ linux/fs/autofs/dir.c Thu May 13 23:25:58 1999
@@ -16,8 +16,6 @@
X void *dirent, filldir_t filldir)
X {
X struct inode *inode=filp->f_dentry->d_inode;
- if (!inode || !S_ISDIR(inode->i_mode))
- return -ENOTDIR;
X
X switch((unsigned long) filp->f_pos)
X {
diff -u --recursive --new-file v2.2.9/linux/fs/autofs/root.c linux/fs/autofs/root.c
--- v2.2.9/linux/fs/autofs/root.c Tue May 11 13:10:30 1999
+++ linux/fs/autofs/root.c Thu May 13 23:25:58 1999
@@ -72,9 +72,6 @@
X struct inode * inode = filp->f_dentry->d_inode;
X off_t onr, nr;
X
- if (!inode || !S_ISDIR(inode->i_mode))
- return -ENOTDIR;
-
X sbi = autofs_sbi(inode->i_sb);
X dirhash = &sbi->dirhash;
X nr = filp->f_pos;
diff -u --recursive --new-file v2.2.9/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- v2.2.9/linux/fs/binfmt_elf.c Tue May 11 13:10:30 1999
+++ linux/fs/binfmt_elf.c Sun Jun 13 10:50:04 1999
@@ -449,6 +449,8 @@
X
X retval = -ENOMEM;
X size = elf_ex.e_phentsize * elf_ex.e_phnum;
+ if (size > 65536)
+ goto out;
X elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
X if (!elf_phdata)
X goto out;
diff -u --recursive --new-file v2.2.9/linux/fs/block_dev.c linux/fs/block_dev.c
--- v2.2.9/linux/fs/block_dev.c Thu Nov 19 09:56:28 1998
+++ linux/fs/block_dev.c Fri May 28 09:20:36 1999
@@ -273,6 +273,8 @@
X if (++bhe == &buflist[NBUF])
X bhe = buflist;
X } while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
+ if (bhe == bhb && !blocks)
+ break;
X } while (left > 0);
X
X /* Release the read-ahead blocks */
diff -u --recursive --new-file v2.2.9/linux/fs/coda/inode.c linux/fs/coda/inode.c
--- v2.2.9/linux/fs/coda/inode.c Tue Mar 23 14:35:48 1999
+++ linux/fs/coda/inode.c Mon Jun 7 16:27:06 1999
@@ -145,7 +145,7 @@
X sb->s_dev = 0;
X coda_cache_clear_all(sb);
X sb_info = coda_sbp(sb);
- sb_info->sbi_vcomm->vc_inuse = 0;
+/* sb_info->sbi_vcomm->vc_inuse = 0; You can not do this: psdev_release would see usagecount == 0 and would refuse to decrease MOD_USE_COUNT --pavel */
X coda_super_info.sbi_sb = NULL;
X printk("Coda: Bye bye.\n");
X memset(sb_info, 0, sizeof(* sb_info));
diff -u --recursive --new-file v2.2.9/linux/fs/coda/psdev.c linux/fs/coda/psdev.c
--- v2.2.9/linux/fs/coda/psdev.c Fri Jan 8 22:36:13 1999
+++ linux/fs/coda/psdev.c Wed Jun 2 11:29:28 1999
@@ -2,7 +2,7 @@
X * An implementation of a loadable kernel mode driver providing
X * multiple kernel/user space bidirectional communications links.


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

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

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

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

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


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

@@ -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 }
+ 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
SHAR_EOF
true || echo 'restore of patch-2.2.10 failed'
fi

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

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.2/patch-2.2.10/part04

#!/bin/sh
# this is part 04 of a 22 - part archive


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

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

X break;
+ case X86_VENDOR_CENTAUR:
+ get_mtrr = centaur_get_mcr;
+ set_mtrr_up = centaur_set_mcr_up;
+ break;
X }
X } /* End Function mtrr_setup */
X
@@ -1611,6 +1694,9 @@
X case X86_VENDOR_CYRIX:
X cyrix_arr_init ();
X break;
+ case X86_VENDOR_CENTAUR:
+ centaur_mcr_init ();
+ break;
X }
X } /* End Function mtrr_init_boot_cpu */
X
@@ -1675,6 +1761,9 @@
X case X86_VENDOR_CYRIX:
X cyrix_arr_init ();
X break;
+ case X86_VENDOR_CENTAUR:
+ centaur_mcr_init ();
+ break;
X }
X # endif /* !__SMP__ */
X
diff -u --recursive --new-file v2.2.9/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.2.9/linux/arch/i386/kernel/setup.c Tue May 11 13:10:27 1999
+++ linux/arch/i386/kernel/setup.c Tue Jun 8 10:43:21 1999
@@ -9,6 +9,11 @@
X * Force Cyrix 6x86(MX) and M II processors to report MTRR capability
X * and fix against Cyrix "coma bug" by
X * Zoltan Boszormenyi <zbo...@mol.hu> February 1999.
+ *
+ * Force Centaur C6 processors to report MTRR capability.
+ * Bart Hartgers <ba...@etpmod.phys.tue.nl>, May 199.
+ *
+ * Intel Mobile Pentium II detection fix. Sean Gilley, June 1999.


X */
X
X /*

@@ -685,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",
@@ -791,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 }
@@ -861,6 +872,8 @@
X /* lv|=(1<<6); - may help too if the board can cope */
X printk("now 0x%X", lv);
X wrmsr(0x107, lv, hv);
+ /* Emulate MTRRs using Centaur's MCR. */
+ c->x86_capability |= X86_FEATURE_MTRR;

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

diff -u --recursive --new-file v2.2.9/linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c
--- v2.2.9/linux/arch/i386/kernel/signal.c Wed Dec 16 10:32:54 1998
+++ linux/arch/i386/kernel/signal.c Mon Jun 7 16:14:20 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.2.9/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.2.9/linux/arch/i386/kernel/smp.c Tue May 11 13:10:27 1999
+++ linux/arch/i386/kernel/smp.c Wed Jun 2 11:29:27 1999
@@ -2,7 +2,7 @@
X * Intel MP v1.1/v1.4 specification support routines for multi-pentium
X * hosts.
X *
- * (c) 1995 Alan Cox, CymruNET Ltd <al...@cymru.net>
+ * (c) 1995 Alan Cox, Building #3 <al...@redhat.com>
X * (c) 1998 Ingo Molnar
X *
X * Supported by Caldera http://www.caldera.com.
diff -u --recursive --new-file v2.2.9/linux/arch/i386/lib/checksum.S linux/arch/i386/lib/checksum.S
--- v2.2.9/linux/arch/i386/lib/checksum.S Tue Jan 19 11:32:51 1999
+++ linux/arch/i386/lib/checksum.S Tue Jun 1 14:05:46 1999
@@ -369,7 +369,7 @@
X
X #define ROUND1(x) \
X SRC(movl x(%esi), %ebx ) ; \
- addl %ebx, %eax\n ; \
+ addl %ebx, %eax ; \
X DST(movl %ebx, x(%edi) ) ;
X
X #define ROUND(x) \
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/Makefile linux/arch/ppc/Makefile
--- v2.2.9/linux/arch/ppc/Makefile Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/Makefile Fri Jun 4 13:30:47 1999
@@ -29,6 +29,10 @@
X CFLAGS := $(CFLAGS) -mcpu=860
X endif
X
+ifdef CONFIG_PPC64
+CFLAGS := $(CFLAGS) -Wa,-mppc64bridge #-Wa,-mppc64
+#CFLAGS := $(CFLAGS) -Wa,-mppc64 -mpowerpc64
+endif
X
X HEAD := arch/ppc/kernel/head.o
X
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/boot/Makefile linux/arch/ppc/boot/Makefile
--- v2.2.9/linux/arch/ppc/boot/Makefile Tue May 11 13:10:28 1999
+++ linux/arch/ppc/boot/Makefile Fri Jun 4 13:30:47 1999
@@ -26,9 +26,15 @@
X ISZ = 0
X
X ifeq ($(CONFIG_SMP),y)
-TFTPIMAGE=/tftpboot/zImage.prep.smp
+TFTPIMAGE=/tftpboot/zImage.prep.smp$(MSIZE)
X else
-TFTPIMAGE=/tftpboot/zImage.prep
+TFTPIMAGE=/tftpboot/zImage.prep$(MSIZE)
+endif
+
+ifeq ($(CONFIG_PPC64),y)
+MSIZE=.64
+else
+MSIZE=
X endif
X
X ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00800000
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/boot/misc.c linux/arch/ppc/boot/misc.c
--- v2.2.9/linux/arch/ppc/boot/misc.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/boot/misc.c Fri Jun 4 13:30:47 1999
@@ -1,7 +1,7 @@
X /*
X * misc.c
X *
- * $Id: misc.c,v 1.64 1999/04/30 05:52:46 cort Exp $
+ * $Id: misc.c,v 1.64.2.2 1999/05/29 19:09:29 cort Exp $
X *
X * Adapted for PowerPC by Gary Thomas
X *
@@ -363,7 +363,7 @@
X if (board_type == 0xe0) {
X base_mod = inb(0x803);
X /* if a MVME2300/2400 or a Sitka then no keyboard */
- if((base_mod == 0x9) || (base_mod == 0xF9) ||
+ if((base_mod == 0xFA) || (base_mod == 0xF9) ||
X (base_mod == 0xE1)) {
X keyb_present = 0; /* no keyboard */
X }
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/chrpboot/Makefile linux/arch/ppc/chrpboot/Makefile
--- v2.2.9/linux/arch/ppc/chrpboot/Makefile Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/chrpboot/Makefile Fri Jun 4 13:30:47 1999
@@ -17,21 +17,27 @@
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
X LIBS = $(TOPDIR)/lib/lib.a
X
+ifeq ($(CONFIG_PPC64),y)
+MSIZE=.64
+else
+MSIZE=
+endif
+
X ifeq ($(CONFIG_ALL_PPC),y)
X # yes, we want to build chrp stuff
X CONFIG_CHRP = y
X endif
X
X ifeq ($(CONFIG_SMP),y)
-TFTPIMAGE=/tftpboot/zImage.chrp.smp
+TFTPIMAGE=/tftpboot/zImage.chrp.smp$(MSIZE)
X else
-TFTPIMAGE=/tftpboot/zImage.chrp
+TFTPIMAGE=/tftpboot/zImage.chrp$(MSIZE)
X endif
X
X all: $(TOPDIR)/zImage
@@ -59,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)
@@ -86,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.2.9/linux/arch/ppc/chrpboot/main.c linux/arch/ppc/chrpboot/main.c
--- v2.2.9/linux/arch/ppc/chrpboot/main.c Mon Oct 5 13:13:36 1998
+++ linux/arch/ppc/chrpboot/main.c Fri Jun 4 13:30:47 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.2.9/linux/arch/ppc/coffboot/Makefile linux/arch/ppc/coffboot/Makefile
--- v2.2.9/linux/arch/ppc/coffboot/Makefile Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/coffboot/Makefile Fri Jun 4 13:30:47 1999
@@ -23,10 +23,16 @@
X CONFIG_PMAC = y
X endif
X
+ifeq ($(CONFIG_PPC64),y)
+MSIZE=.64
+else
+MSIZE=
+endif
+
X ifeq ($(CONFIG_SMP),y)
-TFTPIMAGE=/tftpboot/zImage.pmac.smp
+TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE)
X else
-TFTPIMAGE=/tftpboot/zImage.pmac
+TFTPIMAGE=/tftpboot/zImage.pmac$(MSIZE)
X endif
X
X ifeq ($(CONFIG_PMAC),y)
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/coffboot/zlib.c linux/arch/ppc/coffboot/zlib.c
--- v2.2.9/linux/arch/ppc/coffboot/zlib.c Mon Oct 5 13:13:36 1998
+++ linux/arch/ppc/coffboot/zlib.c Fri Jun 4 13:30:47 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.2.2.1 1999/05/29 19:09:42 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.2.9/linux/arch/ppc/common_defconfig linux/arch/ppc/common_defconfig
--- v2.2.9/linux/arch/ppc/common_defconfig Tue May 11 13:10:28 1999
+++ linux/arch/ppc/common_defconfig Fri Jun 4 13:30:47 1999
@@ -7,6 +7,7 @@
X #
X CONFIG_PPC=y
X CONFIG_6xx=y
+# CONFIG_PPC64 is not set
X # CONFIG_8xx is not set
X # CONFIG_PMAC is not set
X # CONFIG_PREP is not set
@@ -15,13 +16,14 @@
X # CONFIG_APUS is not set
X # CONFIG_MBX is not set
X # CONFIG_SMP is not set
+CONFIG_6xx=y


X
X #
X # General setup
X #

X CONFIG_EXPERIMENTAL=y
X CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
+CONFIG_MODVERSIONS=y
X CONFIG_KMOD=y
X CONFIG_PCI=y
X # CONFIG_PCI_QUIRKS is not set
@@ -32,7 +34,7 @@
X # CONFIG_BSD_PROCESS_ACCT is not set
X CONFIG_BINFMT_ELF=y
X CONFIG_KERNEL_ELF=y
-CONFIG_BINFMT_MISC=m
+# CONFIG_BINFMT_MISC is not set
X # CONFIG_BINFMT_JAVA is not set
X # CONFIG_PARPORT is not set
X CONFIG_VGA_CONSOLE=y
@@ -58,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 #
@@ -73,15 +75,17 @@
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
-# CONFIG_BLK_DEV_IDEDMA_PMAC is not set
+CONFIG_BLK_DEV_IDEDMA_PMAC=y
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_PMAC_IDEDMA_AUTO=y
X # CONFIG_IDE_CHIPSETS is not set
X
X #
X # Additional Block Devices
X #
-CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_LOOP is not set
X # CONFIG_BLK_DEV_NBD is not set
X # CONFIG_BLK_DEV_MD is not set
X CONFIG_BLK_DEV_RAM=y
@@ -110,7 +114,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)

@@ -151,12 +155,12 @@
X CONFIG_CHR_DEV_ST=y
X CONFIG_BLK_DEV_SR=y
X CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SG is not set
X
X #
X # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
X #
-CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_MULTI_LUN is not set
X CONFIG_SCSI_CONSTANTS=y
X # CONFIG_SCSI_LOGGING is not set
X
@@ -191,13 +195,14 @@


X # CONFIG_SCSI_NCR53C406A is not set

X # CONFIG_SCSI_SYM53C416 is not set


X # CONFIG_SCSI_NCR53C7xx is not set

-CONFIG_SCSI_NCR53C8XX=y
-# CONFIG_SCSI_SYM53C8XX is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+CONFIG_SCSI_SYM53C8XX=y
X CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
X CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
X CONFIG_SCSI_NCR53C8XX_SYNC=20
X # CONFIG_SCSI_NCR53C8XX_PROFILE is not set
X # CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
X # CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set


X # CONFIG_SCSI_PAS16 is not set
X # CONFIG_SCSI_PCI2000 is not set

@@ -301,27 +306,17 @@
X CONFIG_FB_CT65550=y
X # CONFIG_FB_S3TRIO is not set
X CONFIG_FB_MATROX=y
-CONFIG_FB_MATROX_MILLENIUM=y
+# CONFIG_FB_MATROX_MILLENIUM is not set
X CONFIG_FB_MATROX_MYSTIQUE=y
-CONFIG_FB_MATROX_G100=y
+# CONFIG_FB_MATROX_G100 is not set
X # CONFIG_FB_MATROX_MULTIHEAD is not set
X # CONFIG_FB_ATY is not set
X # CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
+# CONFIG_FBCON_ADVANCED is not set
X CONFIG_FBCON_CFB8=y
X CONFIG_FBCON_CFB16=y
X CONFIG_FBCON_CFB24=y
X CONFIG_FBCON_CFB32=y
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA is not set
X # CONFIG_FBCON_FONTWIDTH8_ONLY is not set
X CONFIG_FBCON_FONTS=y
X # CONFIG_FONT_8x8 is not set
@@ -355,7 +350,7 @@


X # CONFIG_PC110_PAD is not set

X # CONFIG_QIC02_TAPE is not set
X # CONFIG_WATCHDOG is not set

-# CONFIG_NVRAM is not set

+CONFIG_NVRAM=y


X # CONFIG_RTC is not set

X
X #
@@ -390,10 +385,10 @@
X # CONFIG_ADFS_FS is not set
X # CONFIG_AFFS_FS is not set
X CONFIG_HFS_FS=y
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y


X # CONFIG_UMSDOS_FS is not set

-CONFIG_VFAT_FS=m
+CONFIG_VFAT_FS=y
X CONFIG_ISO9660_FS=y
X # CONFIG_JOLIET is not set
X # CONFIG_MINIX_FS is not set
@@ -470,7 +465,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.2.9/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v2.2.9/linux/arch/ppc/config.in Tue May 11 13:10:28 1999
+++ linux/arch/ppc/config.in Fri Jun 4 13:30:47 1999
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.92 1999/04/30 05:41:43 cort Exp $
+# $Id: config.in,v 1.92.2.1 1999/05/29 19:09:16 cort Exp $
X # For a description of the syntax of this configuration file,
X # see the Configure script.
X #
@@ -8,8 +8,9 @@
X comment 'Platform support'
X define_bool CONFIG_PPC y
X choice 'Processor type' \
- "6xx/7xx CONFIG_6xx \
- 860/821 CONFIG_8xx" 6xx/7xx
+ "6xx/7xx CONFIG_6xx \
+ 630/Power3(64-Bit) CONFIG_PPC64 \
+ 860/821 CONFIG_8xx" 6xx/7xx
X
X choice 'Machine Type' \
X "PowerMac CONFIG_PMAC \
@@ -22,6 +23,10 @@
X bool 'Symmetric multi-processing support' CONFIG_SMP
X if [ "$CONFIG_ALL_PPC" != "y" ];then
X define_bool CONFIG_MACH_SPECIFIC y
+fi
+
+if [ "$CONFIG_PPC64" != "y" ];then
+ define_bool CONFIG_6xx y
X fi
X endmenu
X
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/defconfig linux/arch/ppc/defconfig
--- v2.2.9/linux/arch/ppc/defconfig Tue May 11 13:10:28 1999
+++ linux/arch/ppc/defconfig Fri Jun 4 13:30:47 1999
@@ -8,12 +8,13 @@
X CONFIG_PPC=y
X CONFIG_6xx=y
X # CONFIG_8xx is not set
-# CONFIG_PMAC is not set
+CONFIG_PMAC=y
X # CONFIG_PREP is not set
X # CONFIG_CHRP is not set
-CONFIG_ALL_PPC=y
+# CONFIG_ALL_PPC is not set
X # CONFIG_APUS is not set
X # CONFIG_MBX is not set
+CONFIG_MACH_SPECIFIC=y
X # CONFIG_SMP is not set
X
X #
@@ -35,20 +36,20 @@
X CONFIG_BINFMT_MISC=m
X # CONFIG_BINFMT_JAVA is not set
X # CONFIG_PARPORT is not set
-CONFIG_VGA_CONSOLE=y
+# CONFIG_VGA_CONSOLE is not set
X CONFIG_FB=y
X CONFIG_FB_COMPAT_XPMAC=y
X CONFIG_PMAC_PBOOK=y
X CONFIG_MAC_KEYBOARD=y
X CONFIG_MAC_FLOPPY=y
X CONFIG_MAC_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
X CONFIG_ADBMOUSE=y
+CONFIG_BLK_DEV_IDE_PMAC=y
X CONFIG_PROC_DEVICETREE=y
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
X # CONFIG_TOTALMP is not set
X CONFIG_BOOTX_TEXT=y
-# CONFIG_MOTOROLA_HOTSWAP is not set
-# CONFIG_CMDLINE_BOOL is not set
X
X #
X # Plug and Play support
@@ -75,13 +76,15 @@
X # CONFIG_BLK_DEV_IDEPCI is not set
X # CONFIG_BLK_DEV_SL82C105 is not set
X CONFIG_BLK_DEV_IDE_PMAC=y
-# CONFIG_BLK_DEV_IDEDMA_PMAC is not set
+CONFIG_BLK_DEV_IDEDMA_PMAC=y
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_PMAC_IDEDMA_AUTO=y
X # CONFIG_IDE_CHIPSETS is not set
X
X #
X # Additional Block Devices
X #
-CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_LOOP is not set
X # CONFIG_BLK_DEV_NBD is not set
X # CONFIG_BLK_DEV_MD is not set
X CONFIG_BLK_DEV_RAM=y
@@ -116,6 +119,7 @@


X # (it is safe to leave these untouched)
X #

X CONFIG_INET_RARP=y
+CONFIG_IP_NOSR=y
X CONFIG_SKB_LARGE=y
X # CONFIG_IPV6 is not set
X
@@ -151,12 +155,12 @@
X CONFIG_CHR_DEV_ST=y
X CONFIG_BLK_DEV_SR=y
X CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SG is not set
X
X #
X # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
X #
-CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_MULTI_LUN is not set
X CONFIG_SCSI_CONSTANTS=y
X # CONFIG_SCSI_LOGGING is not set
X
@@ -184,28 +188,16 @@


X # CONFIG_SCSI_FUTURE_DOMAIN is not set
X # CONFIG_SCSI_GDTH is not set
X # CONFIG_SCSI_GENERIC_NCR5380 is not set

-# CONFIG_SCSI_G_NCR5380_PORT is not set
-# CONFIG_SCSI_G_NCR5380_MEM is not set
X # CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set


X # CONFIG_SCSI_NCR53C406A is not set

-# CONFIG_SCSI_SYM53C416 is not set


X # CONFIG_SCSI_NCR53C7xx is not set

-CONFIG_SCSI_NCR53C8XX=y
-# CONFIG_SCSI_SYM53C8XX is not set
-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_SYMBIOS_COMPAT is not set
+# CONFIG_SCSI_NCR53C8XX is not set


X # CONFIG_SCSI_PAS16 is not set
X # CONFIG_SCSI_PCI2000 is not set
X # CONFIG_SCSI_PCI2220I is not set
X # CONFIG_SCSI_PSI240I is not set
X # CONFIG_SCSI_QLOGIC_FAS is not set

X # CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set


X # CONFIG_SCSI_SEAGATE is not set
X # CONFIG_SCSI_DC390T is not set
X # CONFIG_SCSI_T128 is not set

@@ -236,7 +228,7 @@
X # CONFIG_ACENIC is not set
X # CONFIG_NET_ISA is not set
X CONFIG_NET_EISA=y
-CONFIG_PCNET32=y
+# CONFIG_PCNET32 is not set
X # CONFIG_AC3200 is not set
X # CONFIG_APRICOT is not set
X # CONFIG_CS89x0 is not set
@@ -283,7 +275,7 @@


X # CONFIG_ISDN is not set
X
X #

-# Old CD-ROM drivers (not SCSI, not IDE)
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)


X #
X # CONFIG_CD_NO_IDESCSI is not set
X

@@ -291,37 +283,22 @@
X # Console drivers
X #
X CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_PM2 is not set
X CONFIG_FB_OF=y
X CONFIG_FB_CONTROL=y
X CONFIG_FB_PLATINUM=y
X CONFIG_FB_VALKYRIE=y
-# CONFIG_FB_ATY is not set
+CONFIG_FB_ATY=y
X CONFIG_FB_IMSTT=y
X CONFIG_FB_CT65550=y
X # CONFIG_FB_S3TRIO is not set
-CONFIG_FB_MATROX=y
-CONFIG_FB_MATROX_MILLENIUM=y
-CONFIG_FB_MATROX_MYSTIQUE=y
-CONFIG_FB_MATROX_G100=y
-# CONFIG_FB_MATROX_MULTIHEAD is not set
-# CONFIG_FB_ATY is not set
+# CONFIG_FB_MATROX is not set
+CONFIG_FB_ATY=y
X # CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
+# CONFIG_FBCON_ADVANCED is not set
X CONFIG_FBCON_CFB8=y
X CONFIG_FBCON_CFB16=y
X CONFIG_FBCON_CFB24=y
X CONFIG_FBCON_CFB32=y
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA is not set
X # CONFIG_FBCON_FONTWIDTH8_ONLY is not set
X CONFIG_FBCON_FONTS=y
X # CONFIG_FONT_8x8 is not set
@@ -337,25 +314,15 @@
X #
X CONFIG_VT=y
X CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
+# CONFIG_SERIAL is not set
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=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
+# CONFIG_MOUSE is not set


X # CONFIG_QIC02_TAPE is not set
X # CONFIG_WATCHDOG is not set

-# CONFIG_NVRAM is not set

+CONFIG_NVRAM=y


X # CONFIG_RTC is not set

X
X #
@@ -367,20 +334,11 @@
X # Joystick support
X #


X # CONFIG_JOYSTICK is not set

-# CONFIG_DTLK is not set


X
X #
X # Ftape, the floppy tape device driver

X #
X # CONFIG_FTAPE is not set
-# CONFIG_FT_NORMAL_DEBUG is not set
-# CONFIG_FT_FULL_DEBUG is not set
-# CONFIG_FT_NO_TRACE is not set
-# CONFIG_FT_NO_TRACE_AT_ALL is not set
-# CONFIG_FT_STD_FDC is not set
-# CONFIG_FT_MACH2 is not set
-# CONFIG_FT_PROBE_FC10 is not set
-# CONFIG_FT_ALT_FDC is not set
X
X #
X # Filesystems
@@ -471,10 +429,3 @@
X # CONFIG_SOUND_MSNDCLAS is not set
X # CONFIG_SOUND_MSNDPIN is not set
X # CONFIG_SOUND_OSS is not set
-
-#
-# Kernel hacking
-#
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile
--- v2.2.9/linux/arch/ppc/kernel/Makefile Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/Makefile Fri Jun 4 13:30:47 1999
@@ -65,7 +65,7 @@
X $(HOSTCC) -o find_name find_name.c
X
X checks: checks.c
- $(HOSTCC) -fno-builtin -I$(TOPDIR)/include -D__KERNEL__ -o checks checks.c
+ $(HOSTCC) ${CFLAGS} -D__KERNEL__ -o checks checks.c
X ./checks
X
X include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/kernel/chrp_pci.c linux/arch/ppc/kernel/chrp_pci.c
--- v2.2.9/linux/arch/ppc/kernel/chrp_pci.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/chrp_pci.c Fri Jun 4 13:30:47 1999
@@ -166,6 +166,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
@@ -255,6 +311,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)
@@ -275,7 +332,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.
@@ -296,10 +353,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.2.9/linux/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c
--- v2.2.9/linux/arch/ppc/kernel/chrp_setup.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/chrp_setup.c Fri Jun 4 13:30:47 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>
@@ -64,6 +65,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
@@ -179,6 +181,7 @@
X return len;
X }
X
+#if 0
X /*
X * Fixes for the National Semiconductor PC78308VUL SuperI/O
X *
@@ -228,12 +231,13 @@
X /* select logical device 1 (KBC/Mouse) */
X sio_fixup_irq("mouse", 1, 12, 2);
X }
-
+#endif
X
X __initfunc(void
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;
@@ -273,80 +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);
- /*
- * The f50 has a lot of IO space - we need to map some in that
- * isn't covered by the BAT mappings in MMU_init() -- Cort
+ *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
X */
- if ( !strncmp("F5", get_property(find_path_device("/"),
- "ibm,model-class", NULL),2) )
+ if ( rtas_data )
X {
-#if 0
- /*
- * This ugly hack allows us to force ioremap() to
- * create a 1-to-1 mapping for us, even though
- * the address is < ioremap_base. This is necessary
- * since we want our PCI IO space to have contiguous
- * virtual addresses and I think it's worse to have
- * calls to map_page() here.
- * -- Cort
- */
- unsigned long hold = ioremap_base;
- ioremap_base = 0;
- __ioremap(0x90000000, 0x10000000, _PAGE_NO_CACHE);
- ioremap_base = hold;
-#endif
+ 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
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
@@ -668,5 +665,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.2.9/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
--- v2.2.9/linux/arch/ppc/kernel/head.S Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/head.S Fri Jun 4 13:30:47 1999
@@ -1,7 +1,7 @@
X /*
X * arch/ppc/kernel/head.S
X *
- * $Id: head.S,v 1.130 1999/05/09 19:16:43 cort Exp $
+ * $Id: head.S,v 1.130.2.1 1999/05/29 19:09:59 cort Exp $
X *
X * PowerPC version
X * Copyright (C) 1995-1996 Gary Thomas (g...@linuxppc.org)
@@ -97,18 +97,32 @@
X bdnz 0b
X #endif
X
+#ifdef CONFIG_PPC64
+#define LOAD_BAT(n, offset, reg, RA, RB) \
+ ld RA,offset+0(reg); \
+ ld RB,offset+8(reg); \
+ mtspr IBAT##n##U,RA; \
+ mtspr IBAT##n##L,RB; \
+ ld RA,offset+16(reg); \
+ ld RB,offset+24(reg); \
+ mtspr DBAT##n##U,RA; \
+ mtspr DBAT##n##L,RB; \
+
+#else /* CONFIG_PPC64 */
+
X /* 601 only have IBAT cr0.eq is set on 601 when using this macro */
X #define LOAD_BAT(n, offset, reg, RA, RB) \
- lwz RA,offset+0(reg); \
+ lwz RA,offset+0(reg); \
X lwz RB,offset+4(reg); \
- mtspr IBAT##n##U,RA; \
- mtspr IBAT##n##L,RB; \
- beq 1f; \
+ mtspr IBAT##n##U,RA; \
+ mtspr IBAT##n##L,RB; \
+ beq 1f; \
X lwz RA,offset+8(reg); \
X lwz RB,offset+12(reg); \
- mtspr DBAT##n##U,RA; \
- mtspr DBAT##n##L,RB; \
-1:
+ mtspr DBAT##n##U,RA; \
+ mtspr DBAT##n##L,RB; \
+1:
+#endif /* CONFIG_PPC64 */
X
X #ifndef CONFIG_APUS
X #define tophys(rd,rs,rt) addis rd,rs,-KERNELBASE@h
@@ -206,6 +220,16 @@
X
X .globl __start
X __start:
+#ifdef CONFIG_PPC64
+/*
+ * Go into 32-bit mode to boot. OF should do this for
+ * us already but just in case...
+ * -- Cort
+ */
+ mfmsr r10
+ clrldi r10,r10,3
+ mtmsr r10
+#endif
X /*
X * We have to do any OF calls before we map ourselves to KERNELBASE,
X * because OF may have I/O devices mapped in in that area
@@ -226,10 +250,11 @@
X * of RAM to KERNELBASE. From this point on we can't safely
X * call OF any more.
X */
+ lis r11,KERNELBASE@h
+#ifndef CONFIG_PPC64
X mfspr r9,PVR
X rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
X cmpi 0,r9,1
- lis r11,KERNELBASE@h
X bne 4f
X ori r11,r11,4 /* set up BAT registers for 601 */
X li r8,0x7f /* valid, block length = 8MB */
@@ -240,6 +265,7 @@
X mtspr IBAT1U,r9
X mtspr IBAT1L,r10
X b 5f
+#endif /* CONFIG_PPC64 */
X 4:
X #ifdef CONFIG_APUS
X ori r11,r11,BL_8M<<2|0x2 /* set up an 8MB mapping */
@@ -248,9 +274,17 @@
X lwz r8,0(r8)
X addis r8,r8,KERNELBASE@h
X addi r8,r8,2
-#else
+#else
X ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */
X li r8,2 /* R/W access */
+#ifdef CONFIG_PPC64
+ /* clear out the high 32 bits in the BAT */
+ clrldi r11,r11,32
+ clrldi r8,r8,32
+ /* turn off the pagetable mappings just in case */
+ clrldi r16,r16,63
+ mtsdr1 r16
+#else /* CONFIG_PPC64 */
X /*
X * allow secondary cpus to get at all of ram in early bootup
X * since their init_task may be up there -- Cort
@@ -268,6 +302,7 @@
X mtspr DBAT2U,r21 /* bit in upper BAT register */
X mtspr IBAT2L,r28
X mtspr IBAT2U,r21
+#endif /* CONFIG_PPC64 */
X #endif
X mtspr DBAT0L,r8 /* N.B. 6xx (not 601) have valid */
X mtspr DBAT0U,r11 /* bit in upper BAT register */
@@ -1246,7 +1281,7 @@
X eieio
X lis r2,hash_table_lock@h
X ori r2,r2,hash_table_lock@l
- tophys(r2,r2,r6)
+ tophys(r2,r2,r6)
X lis r6,100000000@h
X mtctr r6
X lwz r0,PROCESSOR-TSS(r5)
@@ -1294,6 +1329,11 @@
X stw r6,0(r2) /* update PTE (accessed/dirty bits) */
X
X /* Convert linux-style PTE to low word of PPC-style PTE */
+#ifdef CONFIG_PPC64
+ /* clear the high 32 bits just in case */
+ clrldi r6,r6,32
+ clrldi r4,r4,32
+#endif /* CONFIG_PPC64 */
X rlwinm r4,r6,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */
X rlwimi r6,r6,32-1,31,31 /* _PAGE_USER -> PP (both bits now) */
X ori r4,r4,0xe04 /* clear out reserved bits */
@@ -1301,16 +1341,34 @@
X
X /* Construct the high word of the PPC-style PTE */
X mfsrin r5,r3 /* get segment reg for segment */
+#ifdef CONFIG_PPC64
+ sldi r5,r5,12
+#else /* CONFIG_PPC64 */
X rlwinm r5,r5,7,1,24 /* put VSID in 0x7fffff80 bits */
+#endif /* CONFIG_PPC64 */
+
X #ifndef __SMP__ /* do this later for SMP */
+#ifdef CONFIG_PPC64
+ ori r5,r5,1 /* set V (valid) bit */
+#else /* CONFIG_PPC64 */
X oris r5,r5,0x8000 /* set V (valid) bit */
+#endif /* CONFIG_PPC64 */
X #endif
+
+#ifdef CONFIG_PPC64
+/* XXX: does this insert the api correctly? -- Cort */
+ rlwimi r5,r3,17,21,25 /* put in API (abbrev page index) */
+#else /* CONFIG_PPC64 */
X rlwimi r5,r3,10,26,31 /* put in API (abbrev page index) */
-
+#endif /* CONFIG_PPC64 */
X /* Get the address of the primary PTE group in the hash table */
X .globl hash_page_patch_A
X hash_page_patch_A:
X lis r4,Hash_base@h /* base address of hash table */
+#ifdef CONFIG_PPC64
+ /* just in case */
+ clrldi r4,r4,32
+#endif
X rlwimi r4,r5,32-1,26-Hash_bits,25 /* (VSID & hash_mask) << 6 */
X rlwinm r0,r3,32-6,26-Hash_bits,25 /* (PI & hash_mask) << 6 */
X xor r4,r4,r0 /* make primary hash */
@@ -1799,7 +1857,11 @@
X */
X #ifndef CONFIG_8xx
X lis r6,_SDR1@ha
+#ifdef CONFIG_PPC64
+ ld r6,_SDR1@l(r6)
+#else
X lwz r6,_SDR1@l(r6)
+#endif
X #else
X /* The right way to do this would be to track it down through
X * init's TSS like the context switch code does, but this is
@@ -1828,6 +1890,14 @@
X #endif
X #ifndef CONFIG_8xx
X mtspr SDR1,r6
+#ifdef CONFIG_PPC64
+ /* clear the v bit in the ASR so we can
+ * behave as if we have segment registers
+ * -- Cort
+ */
+ clrldi r6,r6,63
+ mtasr r6
+#endif /* CONFIG_PPC64 */
X li r0,16 /* load up segment register values */
X mtctr r0 /* for context 0 */
X lis r3,0x2000 /* Ku = 1, VSID = 0 */
@@ -1844,10 +1914,17 @@
X lis r3,BATS@ha
X addi r3,r3,BATS@l
X tophys(r3,r3,r4)
+#ifdef CONFIG_PPC64
+ LOAD_BAT(0,0,r3,r4,r5)
+ LOAD_BAT(1,32,r3,r4,r5)
+ LOAD_BAT(2,64,r3,r4,r5)
+ LOAD_BAT(3,96,r3,r4,r5)
+#else /* CONFIG_PPC64 */
X LOAD_BAT(0,0,r3,r4,r5)
X LOAD_BAT(1,16,r3,r4,r5)
X LOAD_BAT(2,32,r3,r4,r5)
X LOAD_BAT(3,48,r3,r4,r5)
+#endif /* CONFIG_PPC64 */
X #endif /* CONFIG_8xx */
X /* Set up for using our exception vectors */
X /* ptr to phys current tss */
@@ -2538,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
@@ -2559,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.2.9/linux/arch/ppc/kernel/idle.c linux/arch/ppc/kernel/idle.c
--- v2.2.9/linux/arch/ppc/kernel/idle.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/idle.c Fri Jun 4 13:30:47 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.61.2.1 1999/05/29 19:10:02 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.2.9/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- v2.2.9/linux/arch/ppc/kernel/irq.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/irq.c Fri Jun 4 13:30:47 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.105.2.1 1999/05/29 19:10:05 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.2.9/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
--- v2.2.9/linux/arch/ppc/kernel/misc.S Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/misc.S Fri Jun 4 13:30:47 1999
@@ -649,15 +649,6 @@
X blr
X
X /*
- * Fetch the current SR register
- * get_SR(int index)
- */
-_GLOBAL(get_SR)
- mfsrin r4,r3
- mr r3,r4
- blr
-
-/*
X * Create a kernel thread
X * __kernel_thread(flags, fn, arg)
X */
@@ -875,7 +866,11 @@
X .long sys_getresuid /* 165 */
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.2.9/linux/arch/ppc/kernel/prep_pci.c linux/arch/ppc/kernel/prep_pci.c
--- v2.2.9/linux/arch/ppc/kernel/prep_pci.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/prep_pci.c Fri Jun 4 13:30:47 1999
@@ -1,5 +1,5 @@
X /*
- * $Id: prep_pci.c,v 1.33 1999/05/09 20:15:54 cort Exp $
+ * $Id: prep_pci.c,v 1.35 1999/05/10 23:31:03 cort Exp $
X * PReP pci functions.
X * Originally by Gary Thomas
X * rewritten and updated by Cort Dougan (co...@cs.nmt.edu)
@@ -38,6 +38,8 @@
X /* Used for Motorola to store system config register */
X static unsigned long *ProcInfo;
X
+extern void chrp_do_IRQ(struct pt_regs *,int , int);
+
X /* Tables for known hardware */
X
X /* Motorola PowerStackII - Utah */
@@ -731,6 +733,8 @@
X OpenPIC_InitSenses = mvme2600_openpic_initsenses;
X OpenPIC_NumInitSenses = sizeof(mvme2600_openpic_initsenses);
X
+ ppc_md.do_IRQ = chrp_do_IRQ;
+
X /* If raven is present on Motorola store the system config register
X * for later use.
X */
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c
--- v2.2.9/linux/arch/ppc/kernel/prep_setup.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/prep_setup.c Fri Jun 4 13:30:47 1999
@@ -249,7 +249,7 @@
X ROOT_DEV = to_kdev_t(0x0801); /* sda1 */
X break;
X case _PREP_Radstone:
- ROOT_DEV = to_kdev_t(0x0801); /* sda1 */
+ ROOT_DEV = to_kdev_t(0x0802); /* sda2 */
X
X /*
X * Determine system type
@@ -767,10 +767,8 @@
X ppc_md.get_cpuinfo = prep_get_cpuinfo;
X ppc_md.irq_cannonicalize = prep_irq_cannonicalize;
X ppc_md.init_IRQ = prep_init_IRQ;
- if ( !OpenPIC )
- ppc_md.do_IRQ = prep_do_IRQ;
- else
- ppc_md.do_IRQ = chrp_do_IRQ;
+ /* this gets changed later on if we have an OpenPIC -- Cort */
+ ppc_md.do_IRQ = prep_do_IRQ;
X ppc_md.init = NULL;
X
X ppc_md.restart = prep_restart;
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
--- v2.2.9/linux/arch/ppc/kernel/prom.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/prom.c Fri Jun 4 13:30:47 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.54.2.1 1999/05/29 19:10:12 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.2.9/linux/arch/ppc/kernel/ptrace.c linux/arch/ppc/kernel/ptrace.c
--- v2.2.9/linux/arch/ppc/kernel/ptrace.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/ptrace.c Fri Jun 4 13:30:47 1999
@@ -330,8 +330,12 @@
X if ((!child->dumpable ||
X (current->uid != child->euid) ||
X (current->uid != child->uid) ||
+ (current->uid != child->suid) ||
X (current->gid != child->egid) ||
- (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
+ (current->gid != child->gid) ||
+ (current->gid != child->sgid) ||
+ (!cap_issubset(child->cap_permitted, current->cap_permitted)))
+ && !capable(CAP_SYS_PTRACE))
X goto out;
X /* the same process cannot be attached many times */
X if (child->flags & PF_PTRACED)
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/kernel/residual.c linux/arch/ppc/kernel/residual.c
--- v2.2.9/linux/arch/ppc/kernel/residual.c Thu Nov 19 09:56:27 1998
+++ linux/arch/ppc/kernel/residual.c Fri Jun 4 13:30:47 1999
@@ -1,5 +1,5 @@
X /*
- * $Id: residual.c,v 1.14 1998/10/11 17:38:10 cort Exp $
+ * $Id: residual.c,v 1.14.2.1 1999/05/29 19:10:17 cort Exp $
X *
X * Code to deal with the PReP residual data.
X *
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- v2.2.9/linux/arch/ppc/kernel/setup.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/setup.c Fri Jun 4 13:30:47 1999
@@ -1,5 +1,5 @@
X /*
- * $Id: setup.c,v 1.132 1999/03/24 00:32:19 cort Exp $
+ * $Id: setup.c,v 1.132.2.1 1999/06/03 03:03:45 paulus Exp $
X * Common prep/pmac/chrp boot and setup code.
X */
X
@@ -375,7 +375,6 @@
X else
X {
X _machine = _MACH_Pmac;
- is_prep = 1;
X }
X }
X
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
--- v2.2.9/linux/arch/ppc/kernel/smp.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/smp.c Fri Jun 4 13:30:47 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.49.2.1 1999/05/29 19:10:20 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.2.9/linux/arch/ppc/kernel/softemu8xx.c linux/arch/ppc/kernel/softemu8xx.c
--- v2.2.9/linux/arch/ppc/kernel/softemu8xx.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/softemu8xx.c Fri Jun 4 13:30:47 1999
@@ -34,6 +34,7 @@
X
X /* Eventually we may need a look-up table, but this works for now.
X */
+#define LFS 48
X #define LFD 50
X #define LFDU 51
X #define STFD 54
@@ -82,6 +83,12 @@
X retval = EFAULT;
X else
X regs->gpr[idxreg] = (uint)ea;
+ break;
+ case LFS:
+ sdisp = (instword & 0xffff);
+ ea = (uint *)(regs->gpr[idxreg] + sdisp);
+ if (copy_from_user(ip, ea, sizeof(float)))
+ retval = EFAULT;
X break;
X case STFD:
X /* this is a 16 bit quantity that is sign extended
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/kernel/syscalls.c linux/arch/ppc/kernel/syscalls.c
--- v2.2.9/linux/arch/ppc/kernel/syscalls.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/syscalls.c Fri Jun 4 13:30:47 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,
@@ -205,15 +201,12 @@
X
X lock_kernel();
X if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
- if (!file)
+ if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
X goto out;
X }
X
X flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
X ret = do_mmap(file, addr, len, prot, flags, offset);
- if (file)
- fput(file);
X out:
X unlock_kernel();
X return ret;
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c
--- v2.2.9/linux/arch/ppc/kernel/time.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/time.c Fri Jun 4 13:30:47 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.47.2.1 1999/05/29 19:10:23 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.2.9/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- v2.2.9/linux/arch/ppc/kernel/traps.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/kernel/traps.c Fri Jun 4 13:30:47 1999
@@ -79,7 +79,6 @@
X debugger(regs);
X #endif
X print_backtrace((unsigned long *)regs->gpr[1]);
- instruction_dump((unsigned long *)regs->nip);
X panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
X }
X force_sig(signr, current);
@@ -127,7 +126,6 @@
X debugger(regs);
X #endif
X print_backtrace((unsigned long *)regs->gpr[1]);
- instruction_dump((unsigned long *)regs->nip);
X panic("machine check");
X }
X _exception(SIGSEGV, regs);
@@ -216,7 +214,6 @@
X #endif
X show_regs(regs);
X print_backtrace((unsigned long *)regs->gpr[1]);
- instruction_dump((unsigned long *)regs->nip);
X panic("kernel stack overflow");
X }
X
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/mm/fault.c linux/arch/ppc/mm/fault.c
--- v2.2.9/linux/arch/ppc/mm/fault.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/mm/fault.c Fri Jun 4 13:30:47 1999
@@ -89,7 +89,6 @@
X printk("page fault in interrupt handler, addr=%lx\n",
X address);
X show_regs(regs);
- instruction_dump((unsigned long *)regs->nip);
X #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
X if (debugger_kernel_faults)
X debugger(regs);
@@ -176,7 +175,6 @@
X /* kernel has accessed a bad area */
X show_regs(regs);
X print_backtrace( (unsigned long *)regs->gpr[1] );
- instruction_dump((unsigned long *)regs->nip);
X #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
X if (debugger_kernel_faults)
X debugger(regs);
diff -u --recursive --new-file v2.2.9/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v2.2.9/linux/arch/ppc/mm/init.c Tue May 11 13:10:28 1999
+++ linux/arch/ppc/mm/init.c Fri Jun 4 13:30:47 1999
@@ -1,5 +1,5 @@
X /*
- * $Id: init.c,v 1.164 1999/05/05 17:33:55 cort Exp $
+ * $Id: init.c,v 1.164.2.2 1999/06/03 03:03:53 paulus Exp $
X *
X * PowerPC version
X * Copyright (C) 1995-1996 Gary Thomas (g...@linuxppc.org)
@@ -371,7 +371,7 @@
X * same virt address (and this is contiguous).
X * -- Cort
X */
- if ( (v = p_mapped_by_bats(addr)) /*&& p_mapped_by_bats(addr+(size-1))*/ )
+ if ( (v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ )
X goto out;
X #endif /* CONFIG_8xx */
X
@@ -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)
@@ -1510,7 +1510,7 @@
X for (h = 256<<10; h < ramsize / 256 && h < 4<<20; h *= 2, Hash_mask++)
X ;
X Hash_size = h;
- Hash_mask << 10; /* so setting _SDR1 works the same -- Cort */
+ Hash_mask <<= 10; /* so setting _SDR1 works the same -- Cort */
X #else
X for (h = 64<<10; h < ramsize / 256 && h < 2<<20; h *= 2)
X ;
diff -u --recursive --new-file v2.2.9/linux/arch/sparc/defconfig linux/arch/sparc/defconfig
--- v2.2.9/linux/arch/sparc/defconfig Wed Apr 28 11:37:30 1999
+++ linux/arch/sparc/defconfig Wed Jun 2 09:55:38 1999
@@ -62,6 +62,7 @@
X CONFIG_SUN_MOSTEK_RTC=y
X # CONFIG_SUN_BPP is not set
X # CONFIG_SUN_VIDEOPIX is not set
+CONFIG_SUN_AURORA=m
X
X #
X # Linux/SPARC audio subsystem (EXPERIMENTAL)
diff -u --recursive --new-file v2.2.9/linux/arch/sparc/kernel/signal.c linux/arch/sparc/kernel/signal.c
--- v2.2.9/linux/arch/sparc/kernel/signal.c Tue Mar 23 14:35:46 1999
+++ linux/arch/sparc/kernel/signal.c Sun Jun 13 19:42:01 1999
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.91 1999/01/26 11:00:44 jj Exp $
+/* $Id: signal.c,v 1.91.2.1 1999/06/14 00:36:13 davem Exp $
X * linux/arch/sparc/kernel/signal.c
X *
X * Copyright (C) 1991, 1992 Linus Torvalds
@@ -1194,6 +1194,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 /* NOT REACHED */
diff -u --recursive --new-file v2.2.9/linux/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c
--- v2.2.9/linux/arch/sparc/kernel/sys_sunos.c Sun Nov 8 14:02:45 1998
+++ linux/arch/sparc/kernel/sys_sunos.c Wed Jun 2 09:55:38 1999
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.94 1998/10/12 06:15:04 jj Exp $
+/* $Id: sys_sunos.c,v 1.94.2.1 1999/05/24 19:42:30 davem Exp $
X * sys_sunos.c: SunOS specific syscall compatibility support.
X *
X * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -1198,7 +1198,7 @@
X
X lock_kernel();
X ret = check_nonblock(sys_readv(fd,vector,count),fd);
- lock_kernel();
+ unlock_kernel();
X return ret;
X }
X
diff -u --recursive --new-file v2.2.9/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.2.9/linux/arch/sparc64/defconfig Wed Apr 28 11:37:30 1999
+++ linux/arch/sparc64/defconfig Wed Jun 2 09:55:38 1999
@@ -68,6 +68,7 @@
X CONFIG_OBP_FLASH=m
X # CONFIG_SUN_BPP is not set
X # CONFIG_SUN_VIDEOPIX is not set
+CONFIG_SUN_AURORA=m
X
X #
X # Linux/SPARC audio subsystem (EXPERIMENTAL)
diff -u --recursive --new-file v2.2.9/linux/arch/sparc64/kernel/ioctl32.c linux/arch/sparc64/kernel/ioctl32.c
--- v2.2.9/linux/arch/sparc64/kernel/ioctl32.c Tue May 11 13:10:28 1999
+++ linux/arch/sparc64/kernel/ioctl32.c Sun Jun 13 19:42:01 1999
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.62 1999/05/01 09:17:44 davem Exp $
+/* $Id: ioctl32.c,v 1.62.2.1 1999/06/09 04:53:03 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.2.9/linux/arch/sparc64/kernel/setup.c linux/arch/sparc64/kernel/setup.c
--- v2.2.9/linux/arch/sparc64/kernel/setup.c Wed Apr 28 11:37:30 1999
+++ linux/arch/sparc64/kernel/setup.c Sat May 29 11:10:15 1999
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.43 1999/04/12 08:08:24 davem Exp $
+/* $Id: setup.c,v 1.43.2.1 1999/05/28 02:18:13 davem Exp $
X * linux/arch/sparc64/kernel/setup.c
X *
X * Copyright (C) 1995,1996 David S. Miller (da...@caip.rutgers.edu)


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

echo 'End of part 04'
echo 'File patch-2.2.10 is continued in part 05'
echo 05 > _shar_seq_.tmp
exit 0

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.2/patch-2.2.10/part18

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


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

if test "$Scheck" != 18; then


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

+#define UART_RX_SIZE_HI 0x05
+#define UART_RX_SIZE_LO 0x06
+
+#define UART_1152 0x01<<7
+#define UART_CRC 0x01<<6
+
+/* For storing entries in the status FIFO */
+struct st_fifo_entry {
+ int status;
+ int len;
+};
+
+struct st_fifo {
+ struct st_fifo_entry entries[10];
+ int head;
+ int tail;
+ int len;
+};
+
+/* Private data for each instance */
+struct ircc_cb {
+ struct st_fifo st_fifo;
+
+ int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */
+ int tx_len; /* Number of frames in tx_buff */
+
+ struct irda_device idev;
+};
+
+#endif
diff -u --recursive --new-file v2.2.9/linux/include/net/irda/smc_ircc.h linux/include/net/irda/smc_ircc.h
--- v2.2.9/linux/include/net/irda/smc_ircc.h Tue Dec 22 14:16:58 1998
+++ linux/include/net/irda/smc_ircc.h Wed Dec 31 16:00:00 1969
@@ -1,123 +0,0 @@
-#if 0
-static char *rcsid = "$Id: smc_ircc.h,v 1.5 1998/07/27 01:25:29 ratbert Exp $";
-#endif
-
-#ifndef SMC_IRCC_H
-#define SMC_IRCC_H
-
-#define FIR_XMIT 1
-#define FIR_RECEIVE 2
-#define SIR_XMIT 3
-#define SIR_RECEIVE 4
-
-#define MASTER 0x07
-#define MASTER_POWERDOWN 1<<7
-#define MASTER_RESET 1<<6
-#define MASTER_INT_EN 1<<5
-#define MASTER_ERROR_RESET 1<<4
-
-/* Register block 0 */
-
-#define IIR 0x01
-#define IER 0x02
-#define LSR 0x03
-#define LCR_A 0x04
-#define LCR_B 0x05
-#define BSR 0x06
-
-#define IIR_ACTIVE_FRAME 1<<7
-#define IIR_EOM 1<<6
-#define IIR_RAW_MODE 1<<5
-#define IIR_FIFO 1<<4
-
-#define IER_ACTIVE_FRAME 1<<7
-#define IER_EOM 1<<6
-#define IER_RAW_MODE 1<<5
-#define IER_FIFO 1<<4
-
-#define LSR_UNDER_RUN 1<<7
-#define LSR_OVER_RUN 1<<6
-#define LSR_FRAME_ERROR 1<<5
-#define LSR_SIZE_ERROR 1<<4
-#define LSR_CRC_ERROR 1<<3
-#define LSR_FRAME_ABORT 1<<2
-
-#define LCR_A_FIFO_RESET 1<<7
-#define LCR_A_FAST 1<<6
-#define LCR_A_GP_DATA 1<<5
-#define LCR_A_RAW_TX 1<<4
-#define LCR_A_RAW_RX 1<<3
-#define LCR_A_ABORT 1<<2
-#define LCR_A_DATA_DONE 1<<1
-
-#define LCR_B_SCE_MODE_DISABLED 0x00<<6
-#define LCR_B_SCE_MODE_TRANSMIT 0x01<<6
-#define LCR_B_SCE_MODE_RECEIVE 0x02<<6
-#define LCR_B_SCE_MODE_UNDEFINED 0x03<<6
-#define LCR_B_SIP_ENABLE 1<<5
-#define LCR_B_BRICK_WALL 1<<4
-
-#define BSR_NOT_EMPTY 1<<7
-#define BSR_FIFO_FULL 1<<6
-#define BSR_TIMEOUT 1<<5
-
-/* Register block 1 */
-
-#define SCE_CFG_A 0x00
-#define SCE_CFG_B 0x01
-#define FIFO_THRESHOLD 0x02
-
-#define CFG_A_AUX_IR 0x01<<7
-#define CFG_A_HALF_DUPLEX 0x01<<2
-#define CFG_A_TX_POLARITY 0x01<<1
-#define CFG_A_RX_POLARITY 0x01
-
-#define CFG_A_COM 0x00<<3
-#define CFG_A_IRDA_SIR_A 0x01<<3
-#define CFG_A_ASK_SIR 0x02<<3
-#define CFG_A_IRDA_SIR_B 0x03<<3
-#define CFG_A_IRDA_HDLC 0x04<<3
-#define CFG_A_IRDA_4PPM 0x05<<3
-#define CFG_A_CONSUMER 0x06<<3
-#define CFG_A_RAW_IR 0x07<<3
-#define CFG_A_OTHER 0x08<<3
-
-#define IR_HDLC 0x04
-#define IR_4PPM 0x01
-#define IR_CONSUMER 0x02
-
-#define CFG_B_LOOPBACK 0x01<<5
-#define CFG_B_LPBCK_TX_CRC 0x01<<4
-#define CFG_B_NOWAIT 0x01<<3
-#define CFB_B_STRING_MOVE 0x01<<2
-#define CFG_B_DMA_BURST 0x01<<1
-#define CFG_B_DMA_ENABLE 0x01
-
-#define CFG_B_MUX_COM 0x00<<6
-#define CFG_B_MUX_IR 0x01<<6
-#define CFG_B_MUX_AUX 0x02<<6
-#define CFG_B_INACTIVE 0x03<<6
-
-/* Register block 2 - Consumer IR - not used */
-
-/* Register block 3 - Identification Registers! */
-
-#define SMSC_ID_HIGH 0x00 /* 0x10 */
-#define SMSC_ID_LOW 0x01 /* 0xB8 */
-#define CHIP_ID 0x02 /* 0xF1 */
-#define VERSION_NUMBER 0x03 /* 0x01 */
-#define HOST_INTERFACE 0x04 /* low 4 = DMA, high 4 = IRQ */
-
-/* Register block 4 - IrDA */
-#define IR_CONTROL 0x00
-#define BOF_COUNT_LO 0x01
-#define BRICK_WALL_CNT_LO 0x02
-#define BRICK_TX_CNT_HI 0x03
-#define TX_DATA_SIZE_LO 0x04
-#define RX_DATA_SIZE_HI 0x05
-#define RX_DATA_SIZE_LO 0x06
-
-#define SELECT_1152 0x01<<7
-#define CRC_SELECT 0x01<<6
-
-#endif
diff -u --recursive --new-file v2.2.9/linux/include/net/irda/toshoboe.h linux/include/net/irda/toshoboe.h
--- v2.2.9/linux/include/net/irda/toshoboe.h Wed Dec 31 16:00:00 1969
+++ linux/include/net/irda/toshoboe.h Sun May 30 10:17:03 1999
@@ -0,0 +1,165 @@
+/*********************************************************************
+ *
+ * Filename: toshoboe.h
+ * Version: 0.1
+ * Description: Driver for the Toshiba OBOE (or type-O)
+ * FIR Chipset.
+ * Status: Experimental.
+ * Author: James McKenzie <ja...@fishsoup.dhs.org>
+ * Created at: Sat May 8 12:35:27 1999
+ *
+ * Copyright (c) 1999 James McKenzie, 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.
+ *
+ * Neither James McKenzie nor Cambridge University admit liability nor
+ * provide warranty for any of this software. This material is
+ * provided "AS-IS" and at no charge.
+ *
+ * Applicable Models : Libretto 100CT. and many more


+ *
+ ********************************************************************/
+

+/*
+ * $Log: toshoboe.h,v $
+ * Revision 1.2 1999/05/09 01:43:08 root
+ * *** empty log message ***
+ *
+ * Revision 1.1 1999/05/09 01:25:58 root
+ * Initial revision
+ *
+ */
+
+#ifndef TOSHOBOE_H
+#define TOSHOBOE_H
+
+/* Registers */
+/*Receive and transmit task registers (read only) */
+#define OBOE_RCVT (0x00+(self->base))
+#define OBOE_XMTT (0x01+(self->base))
+#define OBOE_XMTT_OFFSET 0x40
+
+/*Page pointers to the TaskFile structure */
+#define OBOE_TFP2 (0x02+(self->base))
+#define OBOE_TFP0 (0x04+(self->base))
+#define OBOE_TFP1 (0x05+(self->base))
+
+/*Dunno */
+#define OBOE_REG_3 (0x03+(self->base))
+
+/*Number of tasks to use in Xmit and Recv queues */
+#define OBOE_NTR (0x07+(self->base))
+#define OBOE_NTR_XMIT4 0x00
+#define OBOE_NTR_XMIT8 0x10
+#define OBOE_NTR_XMIT16 0x30
+#define OBOE_NTR_XMIT32 0x70
+#define OBOE_NTR_XMIT64 0xf0
+#define OBOE_NTR_RECV4 0x00
+#define OBOE_NTR_RECV8 0x01
+#define OBOE_NTR_RECV6 0x03
+#define OBOE_NTR_RECV32 0x07
+#define OBOE_NTR_RECV64 0x0f
+
+/* Dunno */
+#define OBOE_REG_9 (0x09+(self->base))
+
+/* Interrupt Status Register */
+#define OBOE_ISR (0x0c+(self->base))
+#define OBOE_ISR_TXDONE 0x80
+#define OBOE_ISR_RXDONE 0x40
+#define OBOE_ISR_20 0x20
+#define OBOE_ISR_10 0x10
+#define OBOE_ISR_8 0x08 /*This is collision or parity or something */
+#define OBOE_ISR_4 0x08
+#define OBOE_ISR_2 0x08
+#define OBOE_ISR_1 0x08
+
+/*Dunno */
+#define OBOE_REG_D (0x0d+(self->base))
+
+/*Register Lock Register */
+#define OBOE_LOCK ((self->base)+0x0e)
+
+
+
+/*Speed control registers */
+#define OBOE_PMDL (0x10+(self->base))
+#define OBOE_PMDL_SIR 0x18
+#define OBOE_PMDL_MIR 0xa0
+#define OBOE_PMDL_FIR 0x40
+
+#define OBOE_SMDL (0x18+(self->base))
+#define OBOE_SMDL_SIR 0x20
+#define OBOE_SMDL_MIR 0x01
+#define OBOE_SMDL_FIR 0x0f
+
+#define OBOE_UDIV (0x19+(self->base))
+
+/*Dunno */
+#define OBOE_REG_11 (0x11+(self->base))
+
+/*Chip Reset Register */
+#define OBOE_RST (0x15+(self->base))
+#define OBOE_RST_WRAP 0x8
+
+/*Dunno */
+#define OBOE_REG_1A (0x1a+(self->base))
+#define OBOE_REG_1B (0x1b+(self->base))
+
+/* The PCI ID of the OBOE chip */
+#ifndef PCI_DEVICE_ID_FIR701
+#define PCI_DEVICE_ID_FIR701 0x0701
+#endif
+
+typedef unsigned int dword;
+typedef unsigned short int word;
+typedef unsigned char byte;
+typedef dword Paddr;
+
+struct OboeTask
+ {
+ __u16 len;
+ __u8 unused;
+ __u8 control;
+ __u32 buffer;
+ };
+
+#define OBOE_NTASKS 64
+
+struct OboeTaskFile
+ {
+ struct OboeTask recv[OBOE_NTASKS];
+ struct OboeTask xmit[OBOE_NTASKS];
+ };
+
+#define OBOE_TASK_BUF_LEN (sizeof(struct OboeTaskFile) << 1)
+
+/*These set the number of slots in use */
+#define TX_SLOTS 4
+#define RX_SLOTS 4
+
+/* You need also to change this, toshiba uses 4,8 and 4,4 */
+/* It makes no difference if you are only going to use ONETASK mode */
+/* remember each buffer use XX_BUF_SZ more _PHYSICAL_ memory */
+#define OBOE_NTR_VAL (OBOE_NTR_XMIT4 | OBOE_NTR_RECV4)
+
+struct toshoboe_cb
+ {
+ struct irda_device idev; /*IRDA device */
+ struct pci_dev *pdev; /*PCI device */
+ int base; /*IO base */
+ int txpending; /*how many tx's are pending */
+ int txs, rxs; /*Which slots are we at */
+ void *taskfilebuf; /*The unaligned taskfile buffer */
+ struct OboeTaskFile *taskfile; /*The taskfile */
+ void *xmit_bufs[TX_SLOTS]; /*The buffers */
+ void *recv_bufs[RX_SLOTS];
+ };
+
+
+#endif
+
+
diff -u --recursive --new-file v2.2.9/linux/include/net/irda/w83977af_ir.h linux/include/net/irda/w83977af_ir.h
--- v2.2.9/linux/include/net/irda/w83977af_ir.h Tue Dec 22 14:16:58 1998
+++ linux/include/net/irda/w83977af_ir.h Sun May 30 10:17:03 1999
@@ -6,10 +6,10 @@
X * Status: Experimental.
X * Author: Paul VanderSpek
X * Created at: Thu Nov 19 13:55:34 1998
- * Modified at: Thu Dec 10 14:06:18 1998
+ * Modified at: Mon May 3 12:07:25 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
- * Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.

X *
X * This program is free software; you can redistribute it and/or

X * modify it under the terms of the GNU General Public License as
@@ -149,6 +149,29 @@
X #define IRM_CR 0x07 /* Infrared module control register */
X #define IRM_CR_IRX_MSL 0x40
X #define IRM_CR_AF_MNT 0x80 /* Automatic format */
+
+/* For storing entries in the status FIFO */
+struct st_fifo_entry {
+ int status;
+ int len;
+};
+
+struct st_fifo {
+ struct st_fifo_entry entries[10];
+ int head;
+ int tail;
+ int len;
+};
+
+/* Private data for each instance */
+struct w83977af_ir {
+ struct st_fifo st_fifo;
+
+ int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */
+ int tx_len; /* Number of frames in tx_buff */
+
+ struct irda_device idev;
+};
X
X static inline void switch_bank( int iobase, int set)
X {
diff -u --recursive --new-file v2.2.9/linux/include/net/irda/wrapper.h linux/include/net/irda/wrapper.h
--- v2.2.9/linux/include/net/irda/wrapper.h Wed Mar 10 15:29:50 1999
+++ linux/include/net/irda/wrapper.h Sun May 30 10:17:03 1999
@@ -1,15 +1,16 @@
X /*********************************************************************
X *
X * Filename: wrapper.h
- * Version: 1.0
- * Description: IrDA Wrapper layer
+ * Version: 1.2
+ * Description: IrDA SIR async wrapper layer


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Mon Aug 4 20:40:53 1997
- * Modified at: Fri Jan 29 10:15:46 1999
+ * Modified at: Mon May 3 09:02:36 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

- * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
+ * Copyright (c) 1998-1999 Dag Brattli <da...@cs.uit.no>,
+ * All Rights Reserved.


X *
X * This program is free software; you can redistribute it and/or

X * modify it under the terms of the GNU General Public License as
@@ -38,17 +39,18 @@
X #define STA BOF /* Start flag */
X #define STO EOF /* End flag */
X
-#define IR_TRANS 0x20 /* Asynchronous transparency modifier */
+#define IRDA_TRANS 0x20 /* Asynchronous transparency modifier */
X
+/* States for receving a frame in async mode */
X enum {
- OUTSIDE_FRAME = 1,
+ OUTSIDE_FRAME,
X BEGIN_FRAME,
X LINK_ESCAPE,
X INSIDE_FRAME
X };
X
X /* Proto definitions */
-int async_wrap_skb( struct sk_buff *skb, __u8 *tx_buff, int buffsize);
-void async_unwrap_char( struct irda_device *, __u8 byte);
+int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize);
+inline void async_unwrap_char(struct irda_device *idev, __u8 byte);
X
X #endif
diff -u --recursive --new-file v2.2.9/linux/include/net/tcp.h linux/include/net/tcp.h
--- v2.2.9/linux/include/net/tcp.h Thu May 13 23:10:31 1999
+++ linux/include/net/tcp.h Thu Jun 3 08:26:38 1999
@@ -290,7 +290,7 @@
X #define TCP_PROBEWAIT_LEN (1*HZ)/* time to wait between probes when
X * I've got something to write and
X * there is no window */
-#define TCP_KEEPALIVE_TIME (180*60*HZ) /* two hours */
+#define TCP_KEEPALIVE_TIME (120*60*HZ) /* two hours */
X #define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */
X #define TCP_KEEPALIVE_PERIOD ((75*HZ)>>2) /* period of keepalive check */
X
diff -u --recursive --new-file v2.2.9/linux/include/scsi/scsicam.h linux/include/scsi/scsicam.h
--- v2.2.9/linux/include/scsi/scsicam.h Thu Jun 12 15:29:27 1997
+++ linux/include/scsi/scsicam.h Wed Jun 9 16:59:34 1999
@@ -14,4 +14,6 @@
X #define SCSICAM_H
X #include <linux/kdev_t.h>
X extern int scsicam_bios_param (Disk *disk, kdev_t dev, int *ip);
+extern int scsi_partsize(struct buffer_head *bh, unsigned long capacity,
+ unsigned int *cyls, unsigned int *hds, unsigned int *secs);
X #endif /* def SCSICAM_H */
diff -u --recursive --new-file v2.2.9/linux/include/scsi/sg.h linux/include/scsi/sg.h
--- v2.2.9/linux/include/scsi/sg.h Tue May 11 13:10:32 1999
+++ linux/include/scsi/sg.h Mon Jun 7 16:27:06 1999
@@ -12,10 +12,16 @@
X * Copyright (C) 1998, 1999 Douglas Gilbert
X
X
- Version: 2.1.32 (990501)
- This version for later 2.1.x series and 2.2.x kernels
+ Version: 2.1.34 (990603)
+ This version for later 2.1.x and 2.2.x series kernels
X D. P. Gilbert (dgil...@interlog.com, do...@triode.net.au)
X
+ Changes since 2.1.33 (990521)
+ - implement SG_SET_RESERVED_SIZE and associated memory re-org.
+ - add SG_NEXT_CMD_LEN to override SCSI command lengths
+ - add SG_GET_VERSION_NUM to get version expressed as an integer
+ Changes since 2.1.32 (990501)
+ - fix race condition in sg_read() and sg_open()
X Changes since 2.1.31 (990327)
X - add ioctls SG_GET_UNDERRUN_FLAG and _SET_. Change the default
X to _not_ flag underruns (affects aic7xxx driver)
@@ -25,24 +31,6 @@
X Changes since 2.1.30 (990320)
X - memory tweaks: change flags on kmalloc (GFP_KERNEL to GFP_ATOMIC)
X - increase max allowable mid-level pool usage
- Changes since 2.1.21 (990315)
- - skipped to 2.1.30 indicating interface change (revert to 2.1.9)
- - remove attempt to accomodate cdrecord 1.8, will fix app
- - keep SG_?ET_RESERVED_SIZE naming for clarity
- Changes since 2.1.20 (990313)
- - ommission: left out logic for SG_?ET_ALT_INTERFACE, now added
- Changes since 2.1.9 (990309)
- - skipped to version 2.1.20 to indicate some interface changes
- - incorporate sg changes to make cdrecord 1.8 work (had its
- own patches that were different from the original)
- - change SG_?ET_BUFF_SIZE to SG_?ET_RESERVED_SIZE for clarity
- Changes since 2.1.8 (990303)
- - debug ">9" option dumps debug for _all_ active sg devices
- - increase allowable dma pool usage + increase minimum threshhold
- - pad out sg_scsi_id structure
- Changes since 2.1.7 (990227)
- - command queuing now "non-default" [back. compat. with cdparanoia]
- - Tighten access on some ioctls
X
X
X New features and changes:
@@ -52,24 +40,32 @@
X - the SCSI target, host and driver status are returned
X in unused fields of sg_header (maintaining its original size).
X - asynchronous notification support added (SIGPOLL, SIGIO) for
- read()s ( write()s should never block).
- - pack_id logic added so read() can be made to wait for a specific
- pack_id.
+ read()s (write()s should never block).
+ - pack_id logic added so read() can wait for a specific pack_id.
X - uses memory > ISA_DMA_THRESHOLD if adapter allows it (e.g. a
X pci scsi adapter).
X - this driver no longer uses a single SG_BIG_BUFF sized buffer
- obtained at driver/module init time. Rather it obtains a
- SG_SCATTER_SZ buffer when a fd is open()ed and frees it at
- the corresponding release() (ie pr fd). Hence open() can return
- ENOMEM! If write() request > SG_SCATTER_SZ bytes for data then
- it can fail with ENOMEM as well (if so, scale back).
+ obtained at driver/module init time. Rather it tries to obtain a
+ SG_DEF_RESERVED_SIZE buffer when a fd is open()ed and frees it
+ at the corresponding release() (ie per fd). Actually the "buffer"
+ may be a collection of buffers if scatter-gather is being used.
+ - add SG_SET_RESERVED_SIZE ioctl allowing the user to request a
+ large buffer for duration of current file descriptor's lifetime.
+ - SG_GET_RESERVED_SIZE ioctl can be used to find out how much
+ actually has been reserved.
+ - add SG_NEXT_CMD_LEN ioctl to override SCSI command length on
+ the next write() to this file descriptor.
+ - SG_GET_RESERVED_SIZE's presence as a symbol can be used for
+ compile time identification of the version 2 sg driver.
+ However, it is recommended that run time identification based on
+ calling the ioctl of the same name is a more flexible and
+ safer approach.
X - adds several ioctl calls, see ioctl section below.
- - SG_SCATTER_SZ's presence indicates this version of "sg" driver.
X
X Good documentation on the original "sg" device interface and usage can be
- found in the Linux HOWTO document: "SCSI Programming HOWTO" by Heiko
- Eissfeldt; last updated 7 May 1996. I will add more info on using the
- extensions in this driver as required. A quick summary:
+ found in the Linux HOWTO document: "SCSI Programming HOWTO" (version 0.5)
+ by Heiko Eissfeldt; last updated 7 May 1996. Here is a quick summary of
+ sg basics:
X An SG device is accessed by writing SCSI commands plus any associated
X outgoing data to it; the resulting status codes and any incoming data
X are then obtained by a read call. The device can be opened O_NONBLOCK
@@ -88,38 +84,37 @@
X The given SCSI command has its LUN field overwritten internally by the
X value associated with the device that has been opened.
X
- Memory (RAM) is used within this driver for direct memory access (DMA)
- in transferring data to and from the SCSI device. The dreaded ENOMEM
- seems to be more prevalent under early 2.2.x kernels than under the
- 2.0.x kernel series. For a given (large) transfer the memory obtained by
- this driver must be contiguous or scatter-gather must be used (if
- supported by the adapter). [Furthermore, ISA SCSI adapters can only use
- memory below the 16MB level on a i386.]
- This driver tries hard to find some suitable memory before admitting
- defeat and returning ENOMEM. All is not lost if application writers
- then back off the amount they are requesting. The value returned by
- the SG_GET_RESERVED_SIZE ioctl is guaranteed to be available (one
- per fd). This driver does the following:
- - attempts to reserve a SG_SCATTER_SZ sized buffer on open(). The
- actual amount reserved is given by the SG_GET_RESERVED_SIZE ioctl().
- - each write() needs to reserve a DMA buffer of the size of the
- data buffer indicated (excluding sg_header and command overhead).
- This buffer, depending on its size, adapter type (ISA or not) and
- the amount of memory available will be obtained from the kernel
- directly (get_free_pages or kmalloc) or the from the scsi mid-level
- dma pool (taking care not to exhaust it).
- If the buffer requested is > SG_SCATTER_SZ or memory is tight then
- scatter-gather will be used if supported by the adapter.
- - write() will also attempt to use the buffer reserved on open()
- if it is large enough.
- The above strategy ensures that a write() can always depend on a buffer
- of the size indicated by the SG_GET_RESERVED_SIZE ioctl() (which could be
- 0, but at least the app knows things are tight in advance).
- Hence application writers can adopt quite aggressive strategies (e.g.
- requesting 512KB) and scale them back in the face of ENOMEM errors.
- N.B. Queuing up commands also ties up kernel memory.
+ This device currently uses "indirect IO" in the sense that data is
+ DMAed into kernel buffers from the hardware and afterwards is
+ transferred into the user space (or vice versa if you are writing).
+ Transfer speeds or up to 20 to 30MBytes/sec have been measured using
+ indirect IO. For faster throughputs "direct IO" which cuts out the
+ double handling of data is required. This will also need a new interface.
+
+ Grabbing memory for those kernel buffers used in this driver for DMA may
+ cause the dreaded ENOMEM error. This error seems to be more prevalent
+ under early 2.2.x kernels than under the 2.0.x kernel series. For a given
+ (large) transfer the memory obtained by this driver must be contiguous or
+ scatter-gather must be used (if supported by the adapter). [Furthermore,
+ ISA SCSI adapters can only use memory below the 16MB level on a i386.]
+
+ When a "sg" device is open()ed O_RDWR then this driver will attempt to
+ reserve a buffer of SG_DEF_RESERVED_SIZE that will be used by subsequent
+ write()s on this file descriptor as long as:


+ - it is not already in use (eg when command queuing is in use)

+ - the write() does not call for a buffer size larger than the
+ reserved size.
+ In these cases the write() will attempt to find the memory it needs for
+ DMA buffers dynamically and in the worst case will fail with ENOMEM.
+ The amount of memory actually reserved depends on various dynamic factors
+ and can be checked with the SG_GET_RESERVED_SIZE ioctl(). [In a very
+ tight memory situation it may yield 0!] The size of the reserved buffer
+ can be changed with the SG_SET_RESERVED_SIZE ioctl(). It should be
+ followed with a call to the SG_GET_RESERVED_SIZE ioctl() to find out how
+ much was actually reserved.
X
- More documentation can be found at www.torque.net/sg
+ More documentation plus test and utility programs can be found at
+ http://www.torque.net/sg
X */
X
X #define SG_MAX_SENSE 16 /* too little, unlikely to change in 2.2.x */
@@ -129,7 +124,7 @@
X int pack_len; /* [o] reply_len (ie useless), ignored as input */


X int reply_len; /* [i] max length of expected reply (inc. sg_header) */
X int pack_id; /* [io] id number of packet (use ints >= 0) */
- int result; /* [o] 0==ok, else (+ve) Unix errno code (e.g. EIO) */
+ int result; /* [o] 0==ok, else (+ve) Unix errno (best ignored) */
X unsigned int twelve_byte:1;
X /* [i] Force 12 byte command length for group 6 & 7 commands */
X unsigned int target_status:5; /* [o] scsi status from target */

@@ -154,9 +149,9 @@
X int unused3;
X } Sg_scsi_id;
X
-/* ioctls ( _GET_s yield result via 'int *' 3rd argument unless
- otherwise indicated */
-#define SG_SET_TIMEOUT 0x2201 /* unit: jiffies, 10ms on i386 */
+/* IOCTLs: ( _GET_s yield result via 'int *' 3rd argument unless
+ otherwise indicated) */
+#define SG_SET_TIMEOUT 0x2201 /* unit: jiffies (10ms on i386) */
X #define SG_GET_TIMEOUT 0x2202 /* yield timeout as _return_ value */
X
X #define SG_EMULATED_HOST 0x2203 /* true for emulated host adapter (ATAPI) */
@@ -165,23 +160,21 @@
X #define SG_SET_TRANSFORM 0x2204
X #define SG_GET_TRANSFORM 0x2205
X
-#define SG_SET_RESERVED_SIZE 0x2275 /* currently ignored, future addition */
-/* Following yields buffer reserved by open(): 0 <= x <= SG_SCATTER_SZ */
-#define SG_GET_RESERVED_SIZE 0x2272
+#define SG_SET_RESERVED_SIZE 0x2275 /* request a new reserved buffer size */
+#define SG_GET_RESERVED_SIZE 0x2272 /* actual size of reserved buffer */
X
X /* The following ioctl takes a 'Sg_scsi_id *' object as its 3rd argument. */
-#define SG_GET_SCSI_ID 0x2276 /* Yields fd's bus,chan,dev,lun+type */
+#define SG_GET_SCSI_ID 0x2276 /* Yields fd's bus, chan, dev, lun + type */
X /* SCSI id information can also be obtained from SCSI_IOCTL_GET_IDLUN */
X
-/* Override adapter setting and always DMA using low memory ( <16MB on i386).
- Default is 0 (off - use adapter setting) */
+/* Override host setting and always DMA using low memory ( <16MB on i386) */
X #define SG_SET_FORCE_LOW_DMA 0x2279 /* 0-> use adapter setting, 1-> force */
X #define SG_GET_LOW_DMA 0x227a /* 0-> use all ram for dma; 1-> low dma ram */
X
X /* When SG_SET_FORCE_PACK_ID set to 1, pack_id is input to read() which
X will attempt to read that pack_id or block (or return EAGAIN). If
X pack_id is -1 then read oldest waiting. When ...FORCE_PACK_ID set to 0
- (default) then pack_id ignored by read() and oldest readable fetched. */
+ then pack_id ignored by read() and oldest readable fetched. */
X #define SG_SET_FORCE_PACK_ID 0x227b
X #define SG_GET_PACK_ID 0x227c /* Yields oldest readable pack_id (or -1) */
X
@@ -194,43 +187,47 @@
X /* Yields max scatter gather tablesize allowed by current host adapter */
X #define SG_GET_SG_TABLESIZE 0x227F /* 0 implies can't do scatter gather */
X
-/* Control whether sequencing per file descriptor (default) or per device */
-#define SG_GET_MERGE_FD 0x2274 /* 0-> per fd (default), 1-> per device */
+/* Control whether sequencing per file descriptor or per device */
+#define SG_GET_MERGE_FD 0x2274 /* 0-> per fd, 1-> per device */
X #define SG_SET_MERGE_FD 0x2273 /* Attempt to change sequencing state,
- if more than 1 fd open on device, will fail with EBUSY */
+ if more than current fd open on device, will fail with EBUSY */
X
X /* Get/set command queuing state per fd (default is SG_DEF_COMMAND_Q) */
X #define SG_GET_COMMAND_Q 0x2270 /* Yields 0 (queuing off) or 1 (on) */
X #define SG_SET_COMMAND_Q 0x2271 /* Change queuing state with 0 or 1 */
X
-/* Get/set whether DMA underrun will cause an error (DID_ERROR) [this only
- currently applies to the [much-used] aic7xxx driver) */
+/* Get/set whether DMA underrun will cause an error (DID_ERROR). This only
+ currently applies to the [much-used] aic7xxx driver. */
X #define SG_GET_UNDERRUN_FLAG 0x2280 /* Yields 0 (don't flag) or 1 (flag) */
X #define SG_SET_UNDERRUN_FLAG 0x2281 /* Change flag underrun state */
X
+#define SG_GET_VERSION_NUM 0x2282 /* Example: version 2.1.34 yields 20134 */
+#define SG_NEXT_CMD_LEN 0x2283 /* override SCSI command length with given
+ number on the next write() on this file descriptor */
+
+
+#define SG_SCATTER_SZ (8 * 4096) /* PAGE_SIZE not available to user */
+/* Largest size (in bytes) a single scatter-gather list element can have.
+ The value must be a power of 2 and <= (PAGE_SIZE * 32) [131072 bytes on
+ i386]. The minimum value is PAGE_SIZE. If scatter-gather not supported
+ by adapter then this value is the largest data block that can be
+ read/written by a single scsi command. The user can find the value of
+ PAGE_SIZE by calling getpagesize() defined in unistd.h . */
X
X #define SG_DEFAULT_TIMEOUT (60*HZ) /* HZ == 'jiffies in 1 second' */
X #define SG_DEFAULT_RETRIES 1
X
-/* Default modes, commented if they differ from original sg driver */
+/* Defaults, commented if they differ from original sg driver */
X #define SG_DEF_COMMAND_Q 0
X #define SG_DEF_MERGE_FD 0 /* was 1 -> per device sequencing */
X #define SG_DEF_FORCE_LOW_DMA 0 /* was 1 -> memory below 16MB on i386 */
X #define SG_DEF_FORCE_PACK_ID 0
X #define SG_DEF_UNDERRUN_FLAG 0
+#define SG_DEF_RESERVED_SIZE SG_SCATTER_SZ
X
X /* maximum outstanding requests, write() yields EDOM if exceeded */
X #define SG_MAX_QUEUE 16
X
-#define SG_SCATTER_SZ (8 * 4096) /* PAGE_SIZE not available to user */
-/* Largest size (in bytes) a single scatter-gather list element can have.
- The value must be a power of 2 and <= (PAGE_SIZE * 32) [131072 bytes on
- i386]. The minimum value is PAGE_SIZE. If scatter-gather not supported
- by adapter then this value is the largest data block that can be
- read/written by a single scsi command. Max number of scatter-gather
- list elements seems to be limited to 255. */
-
-#define SG_BIG_BUFF SG_SCATTER_SZ /* for backward compatibility */
-/* #define SG_BIG_BUFF (SG_SCATTER_SZ * 8) */ /* =256KB, if you want */
+#define SG_BIG_BUFF SG_DEF_RESERVED_SIZE /* for backward compatibility */
X
X #endif
diff -u --recursive --new-file v2.2.9/linux/kernel/signal.c linux/kernel/signal.c
--- v2.2.9/linux/kernel/signal.c Tue May 11 13:10:32 1999
+++ linux/kernel/signal.c Mon Jun 7 16:14:21 1999
@@ -11,6 +11,7 @@
X #include <linux/unistd.h>
X #include <linux/smp_lock.h>
X #include <linux/init.h>
+#include <linux/sched.h>
X
X #include <asm/uaccess.h>
X
@@ -324,7 +325,7 @@
X
X if (nr_queued_signals < max_queued_signals) {
X q = (struct signal_queue *)
- kmem_cache_alloc(signal_queue_cachep, GFP_KERNEL);
+ kmem_cache_alloc(signal_queue_cachep, GFP_ATOMIC);
X }
X
X if (q) {
@@ -417,6 +418,7 @@
X if (t->sig->action[sig-1].sa.sa_handler == SIG_IGN)
X t->sig->action[sig-1].sa.sa_handler = SIG_DFL;
X sigdelset(&t->blocked, sig);
+ recalc_sigpending(t);
X spin_unlock_irqrestore(&t->sigmask_lock, flags);
X
X return send_sig_info(sig, info, t);
diff -u --recursive --new-file v2.2.9/linux/kernel/sys.c linux/kernel/sys.c
--- v2.2.9/linux/kernel/sys.c Fri Nov 27 13:09:30 1998
+++ linux/kernel/sys.c Mon Jun 7 16:18:16 1999
@@ -900,6 +900,8 @@
X return -EINVAL;
X if(copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
X return -EFAULT;
+ if (new_rlim.rlim_cur < 0 || new_rlim.rlim_max < 0)
+ return -EINVAL;
X old_rlim = current->rlim + resource;
X if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
X (new_rlim.rlim_max > old_rlim->rlim_max)) &&
diff -u --recursive --new-file v2.2.9/linux/mm/memory.c linux/mm/memory.c
--- v2.2.9/linux/mm/memory.c Fri Apr 16 14:47:31 1999
+++ linux/mm/memory.c Tue Jun 8 12:47:16 1999
@@ -622,7 +622,7 @@
X
X pte = *page_table;
X new_page = __get_free_page(GFP_USER);
- /* Did someone else copy this page for us while we slept? */
+ /* Did swap_out() unmapped the protected page while we slept? */
X if (pte_val(*page_table) != pte_val(pte))
X goto end_wp_page;
X if (!pte_present(pte))
@@ -652,36 +652,42 @@
X delete_from_swap_cache(page_map);
X /* FallThrough */
X case 1:
- /* We can release the kernel lock now.. */
- unlock_kernel();
-
X flush_cache_page(vma, address);
X set_pte(page_table, pte_mkdirty(pte_mkwrite(pte)));
X flush_tlb_page(vma, address);
X end_wp_page:
+ /*
+ * We can release the kernel lock now.. Now swap_out will see
+ * a dirty page and so won't get confused and flush_tlb_page
+ * won't SMP race. -Andrea
+ */
+ unlock_kernel();
+
X if (new_page)
X free_page(new_page);
X return 1;
X }
X
- unlock_kernel();
X if (!new_page)
- return 0;
+ goto no_new_page;
X
- if (PageReserved(mem_map + MAP_NR(old_page)))
+ if (PageReserved(page_map))
X ++vma->vm_mm->rss;
X copy_cow_page(old_page,new_page);
X flush_page_to_ram(old_page);
X flush_page_to_ram(new_page);
X flush_cache_page(vma, address);
X set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
- free_page(old_page);
X flush_tlb_page(vma, address);
+ unlock_kernel();
+ __free_page(page_map);
X return 1;
X
X bad_wp_page:
X printk("do_wp_page: bogus page at address %08lx (%08lx)\n",address,old_page);
X send_sig(SIGKILL, tsk, 1);
+no_new_page:
+ unlock_kernel();
X if (new_page)
X free_page(new_page);
X return 0;
diff -u --recursive --new-file v2.2.9/linux/mm/swapfile.c linux/mm/swapfile.c
--- v2.2.9/linux/mm/swapfile.c Wed Mar 10 15:29:50 1999
+++ linux/mm/swapfile.c Mon Jun 7 16:27:06 1999
@@ -5,6 +5,7 @@
X * Swap reorganised 29.12.95, Stephen Tweedie
X */
X
+#include <linux/config.h>
X #include <linux/malloc.h>
X #include <linux/smp_lock.h>
X #include <linux/kernel_stat.h>
@@ -554,7 +555,7 @@
X } else if (S_ISREG(swap_dentry->d_inode->i_mode)) {
X error = -EBUSY;
X for (i = 0 ; i < nr_swapfiles ; i++) {
- if (i == type)
+ if (i == type || !swap_info[i].swap_file)
X continue;
X if (swap_dentry->d_inode == swap_info[i].swap_file->d_inode)
X goto bad_swap;
diff -u --recursive --new-file v2.2.9/linux/net/core/datagram.c linux/net/core/datagram.c
--- v2.2.9/linux/net/core/datagram.c Mon Oct 5 13:13:47 1998
+++ linux/net/core/datagram.c Wed Jun 2 11:29:28 1999
@@ -6,7 +6,7 @@
X * This is used because UDP, RAW, PACKET, DDP, IPX, AX.25 and NetROM layer all have identical poll code and mostly
X * identical recvmsg() code. So we share it here. The poll was shared before but buried in udp.c so I moved it.
X *
- * Authors: Alan Cox <al...@cymru.net>. (datagram_poll() from old udp.c code)
+ * Authors: Alan Cox <al...@redhat.com>. (datagram_poll() from old udp.c code)


X *
X * Fixes:

X * Alan Cox : NULL return from skb_peek_copy() understood
diff -u --recursive --new-file v2.2.9/linux/net/core/filter.c linux/net/core/filter.c
--- v2.2.9/linux/net/core/filter.c Mon Mar 29 11:09:12 1999
+++ linux/net/core/filter.c Sat May 15 17:43:52 1999
@@ -106,7 +106,7 @@
X continue;
X
X case BPF_ALU|BPF_MUL|BPF_K:
- A *= X;
+ A *= fentry->k;
X continue;
X
X case BPF_ALU|BPF_DIV|BPF_X:
diff -u --recursive --new-file v2.2.9/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v2.2.9/linux/net/ipv4/af_inet.c Wed Apr 28 11:37:32 1999
+++ linux/net/ipv4/af_inet.c Wed Jun 2 09:55:22 1999
@@ -5,7 +5,7 @@
X *
X * PF_INET protocol family socket handler.
X *
- * Version: $Id: af_inet.c,v 1.87 1999/04/22 10:07:33 davem Exp $
+ * Version: $Id: af_inet.c,v 1.87.2.1 1999/05/29 04:32:01 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -147,14 +147,8 @@


X struct sk_buff *skb;
X

X /* First the read buffer. */
- while((skb = skb_dequeue(&sk->receive_queue)) != NULL) {
- /* This will take care of closing sockets that were
- * listening and didn't accept everything.
- */
- if (skb->sk != NULL && skb->sk != sk)
- skb->sk->prot->close(skb->sk, 0);
+ while((skb = skb_dequeue(&sk->receive_queue)) != NULL)
X kfree_skb(skb);
- }
X
X /* Next, the error queue. */
X while((skb = skb_dequeue(&sk->error_queue)) != NULL)
@@ -213,12 +207,6 @@
X
X kill_sk_queues(sk);
X
- /* Now if it has a half accepted/ closed socket. */
- if (sk->pair) {
- sk->pair->prot->close(sk->pair, 0);
- sk->pair = NULL;
- }
-
X /* Now if everything is gone we can free the socket
X * structure, otherwise we need to keep it around until
X * everything is gone.
@@ -684,14 +672,8 @@
X if (sk1->prot->accept == NULL)
X goto do_err;
X
- /* Restore the state if we have been interrupted, and then returned. */
- if (sk1->pair != NULL) {
- sk2 = sk1->pair;
- sk1->pair = NULL;
- } else {
- if((sk2 = sk1->prot->accept(sk1,flags)) == NULL)
- goto do_sk1_err;
- }
+ if((sk2 = sk1->prot->accept(sk1,flags)) == NULL)
+ goto do_sk1_err;
X
X /*
X * We've been passed an extra socket.
diff -u --recursive --new-file v2.2.9/linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c
--- v2.2.9/linux/net/ipv4/icmp.c Tue Mar 23 14:35:48 1999
+++ linux/net/ipv4/icmp.c Tue Jun 8 20:33:07 1999
@@ -1,9 +1,9 @@
X /*
X * NET3: Implementation of the ICMP protocol layer.
X *
- * Alan Cox, <al...@cymru.net>
+ * Alan Cox, <al...@redhat.com>
X *
- * Version: $Id: icmp.c,v 1.52 1999/03/21 12:04:11 davem Exp $
+ * Version: $Id: icmp.c,v 1.52.2.1 1999/06/09 01:56:07 davem Exp $
X *


X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License

diff -u --recursive --new-file v2.2.9/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
--- v2.2.9/linux/net/ipv4/ip_fw.c Wed Apr 28 11:37:32 1999
+++ linux/net/ipv4/ip_fw.c Tue Jun 8 20:33:07 1999
@@ -34,6 +34,9 @@
X * Marc Santoro <ult...@snicker.emoti.com>
X * 29-Jan-1999: Locally generated bogus IPs dealt with, rather than crash
X * during dump_packet. --RR.
+ * 19-May-1999: Star Wars: The Phantom Menace opened. Rule num
+ * printed in log (modified from Michael Hasenstein's patch).
+ * Added SYN in log message. --RR


X */
X
X /*

@@ -400,7 +403,9 @@
X struct ip_fwkernel *f,
X const ip_chainlabel chainlabel,
X __u16 src_port,
- __u16 dst_port)
+ __u16 dst_port,
+ unsigned int count,
+ int syn)
X {
X __u32 *opt = (__u32 *) (ip + 1);
X int opti;
@@ -432,7 +437,7 @@
X
X for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++)
X printk(" O=0x%8.8X", *opt++);
- printk("\n");
+ printk(" %s(#%d)\n", syn ? "SYN " : /* "PENANCE" */ "", count);
X }
X
X /* function for checking chain labels for user space. */
@@ -520,12 +525,14 @@
X const ip_chainlabel label,
X struct sk_buff *skb,
X unsigned int slot,
- __u16 src_port, __u16 dst_port)
+ __u16 src_port, __u16 dst_port,
+ unsigned int count,
+ int tcpsyn)
X {
X f->counters[slot].bcnt+=ntohs(ip->tot_len);
X f->counters[slot].pcnt++;
X if (f->ipfw.fw_flg & IP_FW_F_PRN) {
- dump_packet(ip,rif,f,label,src_port,dst_port);
+ dump_packet(ip,rif,f,label,src_port,dst_port,count,tcpsyn);
X }
X ip->tos = (ip->tos & f->ipfw.fw_tosand) ^ f->ipfw.fw_tosxor;
X
@@ -590,6 +597,7 @@
X unsigned char oldtos;
X struct ip_fwkernel *f;
X int ret = FW_SKIP+2;
+ unsigned int count;
X
X /* We handle fragments by dealing with the first fragment as
X * if it was a normal packet. All other fragments are treated
@@ -610,7 +618,7 @@
X if (offset == 1 && ip->protocol == IPPROTO_TCP) {
X if (!testing && net_ratelimit()) {
X printk("Suspect TCP fragment.\n");
- dump_packet(ip,rif,NULL,NULL,0,0);
+ dump_packet(ip,rif,NULL,NULL,0,0,0,0);
X }
X return FW_BLOCK;
X }
@@ -702,13 +710,16 @@
X
X f = chain->chain;
X do {
+ count = 0;
X for (; f; f = f->next) {
+ count++;
X if (ip_rule_match(f,rif,ip,
X tcpsyn,src_port,dst_port,offset)) {
X if (!testing
X && !ip_fw_domatch(f, ip, rif, chain->label,
X skb, slot,
- src_port, dst_port)) {
+ src_port, dst_port,
+ count, tcpsyn)) {
X ret = FW_BLOCK;
X goto out;
X }
@@ -1408,8 +1419,10 @@
X else if ((chain = find_label(new->fwc_label)) == NULL)
X ret = ENOENT;
X else if ((ip_fwkern = convert_ipfw(&new->fwc_rule, &ret))
- != NULL)
+ != NULL) {
X ret = del_rule_from_chain(chain, ip_fwkern);
+ kfree(ip_fwkern);
+ }
X }
X break;
X
diff -u --recursive --new-file v2.2.9/linux/net/ipv4/ip_options.c linux/net/ipv4/ip_options.c
--- v2.2.9/linux/net/ipv4/ip_options.c Tue Mar 23 14:35:48 1999
+++ linux/net/ipv4/ip_options.c Wed Jun 2 09:55:22 1999
@@ -5,7 +5,7 @@
X *
X * The options processing module for ip.c
X *
- * Version: $Id: ip_options.c,v 1.16 1999/03/21 05:22:40 davem Exp $
+ * Version: $Id: ip_options.c,v 1.16.2.1 1999/06/02 04:06:19 davem Exp $
X *
X * Authors: A.N.Kuznetsov
X *
@@ -452,7 +452,6 @@
X error:
X if (skb) {
X icmp_send(skb, ICMP_PARAMETERPROB, 0, htonl((pp_ptr-iph)<<24));
- kfree_skb(skb);
X }
X return -EINVAL;
X }
diff -u --recursive --new-file v2.2.9/linux/net/ipv4/ipmr.c linux/net/ipv4/ipmr.c
--- v2.2.9/linux/net/ipv4/ipmr.c Mon Mar 29 11:09:12 1999
+++ linux/net/ipv4/ipmr.c Tue Jun 8 20:33:07 1999


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

X * IP multicast routing support for mrouted 3.6/3.8
X *
- * (c) 1995 Alan Cox, <al...@cymru.net>
+ * (c) 1995 Alan Cox, <al...@redhat.com>
X * Linux Consultancy and Custom Driver Development


X *
X * This program is free software; you can redistribute it and/or

@@ -9,7 +9,7 @@
X * as published by the Free Software Foundation; either version
X * 2 of the License, or (at your option) any later version.
X *

- * Version: $Id: ipmr.c,v 1.40 1999/03/25 10:04:25 davem Exp $
+ * Version: $Id: ipmr.c,v 1.40.2.1 1999/06/09 01:56:17 davem Exp $
X *
X * Fixes:
X * Michael Chastain : Incorrect size of copying.
diff -u --recursive --new-file v2.2.9/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v2.2.9/linux/net/ipv4/tcp.c Wed Apr 28 11:37:32 1999
+++ linux/net/ipv4/tcp.c Wed Jun 2 09:55:22 1999
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp.c,v 1.140 1999/04/22 10:34:31 davem Exp $
+ * Version: $Id: tcp.c,v 1.140.2.1 1999/05/29 04:16:48 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -896,6 +896,7 @@
X err = -ERESTARTSYS;
X goto do_interrupted;
X }
+ tcp_push_pending_frames(sk, tp);
X wait_for_tcp_memory(sk);
X
X /* If SACK's were formed or PMTU events happened,
diff -u --recursive --new-file v2.2.9/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- v2.2.9/linux/net/ipv4/tcp_input.c Tue May 11 13:10:32 1999
+++ linux/net/ipv4/tcp_input.c Wed Jun 2 09:55:22 1999
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_input.c,v 1.164 1999/05/08 21:09:52 davem Exp $
+ * Version: $Id: tcp_input.c,v 1.164.2.3 1999/06/02 04:15:06 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -748,7 +748,6 @@
X static __inline__ void tcp_ack_packets_out(struct sock *sk, struct tcp_opt *tp)
X {
X struct sk_buff *skb = skb_peek(&sk->write_queue);
- __u32 when = tp->rto - (tcp_time_stamp - TCP_SKB_CB(skb)->when);
X
X /* Some data was ACK'd, if still retransmitting (due to a
X * timeout), resend more of the retransmit queue. The
@@ -758,6 +757,9 @@
X tcp_xmit_retransmit_queue(sk);
X tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
X } else {
+ __u32 when = tp->rto - (tcp_time_stamp - TCP_SKB_CB(skb)->when);
+ if ((__s32)when < 0)
+ when = 1;
X tcp_reset_xmit_timer(sk, TIME_RETRANS, when);
X }
X }
@@ -785,8 +787,6 @@
X if (after(ack, tp->snd_nxt) || before(ack, tp->snd_una))
X goto uninteresting_ack;
X
- dst_confirm(sk->dst_cache);
-
X /* If there is data set flag 1 */
X if (len != th->doff*4) {
X flag |= FLAG_DATA;
@@ -882,6 +882,24 @@
X /* Clear any aborted fast retransmit starts. */
X tp->dup_acks = 0;
X }
+ /* It is not a brain fart, I thought a bit now. 8)
+ *
+ * Forward progress is indicated, if:
+ * 1. the ack acknowledges new data.
+ * 2. or the ack is duplicate, but it is caused by new segment
+ * arrival. This case is filtered by:
+ * - it contains no data, syn or fin.
+ * - it does not update window.
+ * 3. or new SACK. It is difficult to check, so that we ignore it.
+ *
+ * Forward progress is also indicated by arrival new data,
+ * which was caused by window open from our side. This case is more
+ * difficult and it is made (alas, incorrectly) in tcp_data_queue().
+ * --ANK (990513)
+ */
+ if (ack != tp->snd_una || (flag == 0 && !th->fin))
+ dst_confirm(sk->dst_cache);
+
X /* Remember the highest ack received. */
X tp->snd_una = ack;
X return 1;
@@ -1801,7 +1819,7 @@
X }
X }
X
- flg = *(((u32 *)th) + 3) & ~htonl(0x8 << 16);
+ flg = *(((u32 *)th) + 3) & ~htonl(0xFC8 << 16);
X
X /* pred_flags is 0xS?10 << 16 + snd_wnd
X * if header_predition is to be made
@@ -2067,21 +2085,81 @@
X * not be in line code. [AC]
X */
X if(th->ack) {
- tp->snd_wl1 = TCP_SKB_CB(skb)->seq;
-
- /* We got an ack, but it's not a good ack. */
- if(!tcp_ack(sk,th, TCP_SKB_CB(skb)->seq,
- TCP_SKB_CB(skb)->ack_seq, len))
+ /* rfc793:
+ * "If the state is SYN-SENT then
+ * first check the ACK bit
+ * If the ACK bit is set
+ * If SEG.ACK =< ISS, or SEG.ACK > SND.NXT, send
+ * a reset (unless the RST bit is set, if so drop
+ * the segment and return)"
+ *
+ * I cite this place to emphasize one essential
+ * detail, this check is different of one
+ * in established state: SND.UNA <= SEG.ACK <= SND.NXT.
+ * SEG_ACK == SND.UNA == ISS is invalid in SYN-SENT,
+ * because we have no previous data sent before SYN.
+ * --ANK(990513)
+ *
+ * We do not send data with SYN, so that RFC-correct
+ * test reduces to:
+ */
+ if (sk->zapped ||
+ TCP_SKB_CB(skb)->ack_seq != tp->snd_nxt)
X return 1;
X
- if(th->rst) {
+ /* Now ACK is acceptable.
+ *
+ * "If the RST bit is set
+ * If the ACK was acceptable then signal the user "error:
+ * connection reset", drop the segment, enter CLOSED state,
+ * delete TCB, and return."
+ */
+
+ if (th->rst) {
X tcp_reset(sk);
X goto discard;
X }
X
- if(!th->syn)
+ /* rfc793:
+ * "fifth, if neither of the SYN or RST bits is set then
+ * drop the segment and return."
+ *
+ * See note below!
+ * --ANK(990513)
+ */
+
+ if (!th->syn)
X goto discard;
X
+ /* rfc793:
+ * "If the SYN bit is on ...
+ * are acceptable then ...
+ * (our SYN has been ACKed), change the connection
+ * state to ESTABLISHED..."
+ *
+ * Do you see? SYN-less ACKs in SYN-SENT state are
+ * completely ignored.
+ *
+ * The bug causing stalled SYN-SENT sockets
+ * was here: tcp_ack advanced snd_una and canceled
+ * retransmit timer, so that bare ACK received
+ * in SYN-SENT state (even with invalid ack==ISS,
+ * because tcp_ack check is too weak for SYN-SENT)
+ * causes moving socket to invalid semi-SYN-SENT,
+ * semi-ESTABLISHED state and connection hangs.
+ *
+ * There exist buggy stacks, which really send
+ * such ACKs: f.e. 202.226.91.94 (okigate.oki.co.jp)
+ * Actually, if this host did not try to get something
+ * from ftp.inr.ac.ru I'd never find this bug 8)
+ *
+ * --ANK (990514)
+ */
+
+ tp->snd_wl1 = TCP_SKB_CB(skb)->seq;
+ tcp_ack(sk,th, TCP_SKB_CB(skb)->seq,
+ TCP_SKB_CB(skb)->ack_seq, len);
+
X /* Ok.. it's good. Set up sequence numbers and
X * move to established.
X */
@@ -2206,8 +2284,8 @@
X !(th->fin && TCP_SKB_CB(skb)->end_seq == tp->rcv_nxt)) {
X if (!th->rst) {
X tcp_send_ack(sk);
- goto discard;
X }
+ goto discard;
X }
X
X /* step 2: check RST bit */
diff -u --recursive --new-file v2.2.9/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.2.9/linux/net/ipv4/tcp_ipv4.c Tue May 11 13:10:32 1999
+++ linux/net/ipv4/tcp_ipv4.c Wed Jun 2 09:55:22 1999
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_ipv4.c,v 1.175 1999/05/08 21:09:54 davem Exp $
+ * Version: $Id: tcp_ipv4.c,v 1.175.2.2 1999/06/02 04:06:15 davem Exp $
X *
X * IPv4 specific functions
X *
@@ -1328,7 +1328,6 @@
X
X newsk->done = 0;
X newsk->proc = 0;
- newsk->pair = NULL;
X skb_queue_head_init(&newsk->back_log);
X skb_queue_head_init(&newsk->error_queue);
X #ifdef CONFIG_FILTER
@@ -1648,6 +1647,7 @@
X /* Count it even if it's bad */
X tcp_statistics.TcpInSegs++;
X
+ len = skb->len;
X if (len < sizeof(struct tcphdr))
X goto bad_packet;
X
@@ -1673,6 +1673,10 @@
X default:
X /* CHECKSUM_UNNECESSARY */
X }
+
+ if((th->doff * 4) < sizeof(struct tcphdr) ||
+ len < (th->doff * 4))
+ goto bad_packet;
X
X #ifdef CONFIG_IP_TRANSPARENT_PROXY
X if (IPCB(skb)->redirport)
diff -u --recursive --new-file v2.2.9/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- v2.2.9/linux/net/ipv4/tcp_output.c Tue May 11 13:10:32 1999
+++ linux/net/ipv4/tcp_output.c Wed Jun 2 09:55:22 1999
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_output.c,v 1.108 1999/05/08 21:48:59 davem Exp $
+ * Version: $Id: tcp_output.c,v 1.108.2.1 1999/05/14 23:07:36 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>


@@ -239,6 +239,11 @@
X

X /* Rechecksum original buffer. */
X skb->csum = csum_partial(skb->data, skb->len, 0);
+
+ /* Looks stupid, but our code really uses when of
+ * skbs, which it never sent before. --ANK
+ */
+ TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when;
X
X /* Link BUFF into the send queue. */
X __skb_append(skb, buff);
diff -u --recursive --new-file v2.2.9/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
--- v2.2.9/linux/net/ipv4/tcp_timer.c Tue May 11 13:10:32 1999
+++ linux/net/ipv4/tcp_timer.c Wed Jun 2 09:55:22 1999
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_timer.c,v 1.62 1999/05/08 21:09:55 davem Exp $
+ * Version: $Id: tcp_timer.c,v 1.62.2.2 1999/06/02 04:06:21 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -537,14 +537,11 @@
X conn = req;
X req = req->dl_next;
X
- if (conn->sk) {
+ if (conn->sk ||
+ ((long)(now - conn->expires)) <= 0) {
X prev = conn;
X continue;
X }
-
- if ((long)(now - conn->expires) <= 0)
- break;
-
X
X tcp_synq_unlink(tp, conn, prev);
X if (conn->retrans >= sysctl_tcp_retries1) {
diff -u --recursive --new-file v2.2.9/linux/net/ipv6/icmp.c linux/net/ipv6/icmp.c
--- v2.2.9/linux/net/ipv6/icmp.c Tue Mar 23 14:35:48 1999
+++ linux/net/ipv6/icmp.c Sat May 29 11:10:33 1999
@@ -5,7 +5,7 @@
X * Authors:
X * Pedro Roque <ro...@di.fc.ul.pt>
X *
- * $Id: icmp.c,v 1.21 1999/03/21 05:22:51 davem Exp $
+ * $Id: icmp.c,v 1.21.2.1 1999/05/19 22:07:36 davem Exp $
X *
X * Based on net/ipv4/icmp.c
X *
@@ -315,6 +315,7 @@
X fl.nl_u.ip6_u.daddr = &hdr->saddr;
X fl.nl_u.ip6_u.saddr = saddr;
X fl.oif = iif;
+ fl.fl6_flowlabel = 0;
X fl.uli_u.icmpt.type = type;
X fl.uli_u.icmpt.code = code;
X
@@ -388,6 +389,7 @@
X fl.nl_u.ip6_u.daddr = &hdr->saddr;
X fl.nl_u.ip6_u.saddr = saddr;
X fl.oif = skb->dev->ifindex;
+ fl.fl6_flowlabel = 0;
X fl.uli_u.icmpt.type = ICMPV6_ECHO_REPLY;
X fl.uli_u.icmpt.code = 0;
X
diff -u --recursive --new-file v2.2.9/linux/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- v2.2.9/linux/net/ipv6/tcp_ipv6.c Wed Apr 28 11:37:32 1999
+++ linux/net/ipv6/tcp_ipv6.c Wed Jun 2 09:55:22 1999
@@ -5,7 +5,7 @@
X * Authors:
X * Pedro Roque <ro...@di.fc.ul.pt>
X *
- * $Id: tcp_ipv6.c,v 1.104 1999/04/24 00:27:25 davem Exp $
+ * $Id: tcp_ipv6.c,v 1.104.2.2 1999/06/02 04:06:27 davem Exp $
X *
X * Based on:
X * linux/net/ipv4/tcp.c
@@ -551,7 +551,7 @@
X
X failure:
X dst_release(xchg(&sk->dst_cache, NULL));
- memcpy(&np->daddr, 0, sizeof(struct in6_addr));
+ memset(&np->daddr, 0, sizeof(struct in6_addr));
X sk->daddr = 0;
X return err;
X }
@@ -1362,6 +1362,7 @@
X
X tcp_statistics.TcpInSegs++;
X
+ len = skb->len;
X if (len < sizeof(struct tcphdr))
X goto bad_packet;
X
@@ -1382,6 +1383,10 @@
X default:
X /* CHECKSUM_UNNECESSARY */
X };
+
+ if((th->doff * 4) < sizeof(struct tcphdr) ||
+ len < (th->doff * 4))
+ goto bad_packet;
X
X sk = __tcp_v6_lookup(th, saddr, th->source, daddr, th->dest, tcp_v6_iif(skb));
X
diff -u --recursive --new-file v2.2.9/linux/net/irda/Config.in linux/net/irda/Config.in
--- v2.2.9/linux/net/irda/Config.in Fri Apr 16 14:47:31 1999
+++ linux/net/irda/Config.in Mon Jun 7 16:19:59 1999
@@ -2,34 +2,31 @@
X # IrDA protocol configuration
X #
X
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- if [ "$CONFIG_NET" != "n" ] ; then
+if [ "$CONFIG_NET" != "n" ] ; then
X
- mainmenu_option next_comment
- comment 'IrDA subsystem support'
- dep_tristate 'IrDA subsystem support' CONFIG_IRDA $CONFIG_EXPERIMENTAL $CONFIG_NET
+ mainmenu_option next_comment
+ comment 'IrDA subsystem support'
+ dep_tristate 'IrDA subsystem support' CONFIG_IRDA $CONFIG_NET
X
- if [ "$CONFIG_IRDA" != "n" ] ; then
- comment 'IrDA protocols'
- source net/irda/irlan/Config.in
- source net/irda/ircomm/Config.in
- source net/irda/irlpt/Config.in
+ if [ "$CONFIG_IRDA" != "n" ] ; then
+ comment 'IrDA protocols'
+ source net/irda/irlan/Config.in
+ source net/irda/ircomm/Config.in
+ source net/irda/irlpt/Config.in
X
- bool 'IrDA protocol options' CONFIG_IRDA_OPTIONS
- if [ "$CONFIG_IRDA_OPTIONS" != "n" ] ; then
- comment ' IrDA options'
- bool ' Cache last LSAP' CONFIG_IRDA_CACHE_LAST_LSAP
- bool ' Fast RRs' CONFIG_IRDA_FAST_RR
- bool ' Debug information' CONFIG_IRDA_DEBUG
- fi
+ bool 'IrDA protocol options' CONFIG_IRDA_OPTIONS
+ if [ "$CONFIG_IRDA_OPTIONS" != "n" ] ; then
+ comment ' IrDA options'
+ bool ' Cache last LSAP' CONFIG_IRDA_CACHE_LAST_LSAP
+ bool ' Fast RRs' CONFIG_IRDA_FAST_RR
+ bool ' Debug information' CONFIG_IRDA_DEBUG
X fi
+ fi
X
- if [ "$CONFIG_IRDA" != "n" ] ; then
- source net/irda/compressors/Config.in
- source drivers/net/irda/Config.in
- fi
- endmenu
-
+ if [ "$CONFIG_IRDA" != "n" ] ; then
+ source net/irda/compressors/Config.in
+ source drivers/net/irda/Config.in
X fi
+ endmenu
X fi
X
diff -u --recursive --new-file v2.2.9/linux/net/irda/af_irda.c linux/net/irda/af_irda.c
--- v2.2.9/linux/net/irda/af_irda.c Wed Apr 28 11:37:32 1999
+++ linux/net/irda/af_irda.c Mon Jun 7 16:19:59 1999
@@ -6,7 +6,7 @@


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sun May 31 10:12:43 1998
- * Modified at: Thu Apr 22 12:08:04 1999
+ * Modified at: Wed May 19 16:12:06 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>

X * Sources: af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc.
X *
@@ -30,6 +30,7 @@
X #include <linux/if_arp.h>
X #include <linux/net.h>
X #include <linux/irda.h>
+#include <linux/poll.h>
X
X #include <asm/uaccess.h>
X
@@ -46,11 +47,12 @@
X extern int irlap_driver_rcv(struct sk_buff *, struct device *,
X struct packet_type *);
X
-static struct proto_ops irda_proto_ops;
+static struct proto_ops irda_stream_ops;
+static struct proto_ops irda_dgram_ops;
X static hashbin_t *cachelog = NULL;
X static struct wait_queue *discovery_wait; /* Wait for discovery */
X
-#define IRDA_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_HEADER)
+#define IRDA_MAX_HEADER (TTP_MAX_HEADER)
X
X /*
X * Function irda_data_indication (instance, sap, skb)
@@ -121,7 +123,8 @@
X */
X static void irda_connect_confirm(void *instance, void *sap,
X struct qos_info *qos,
- __u32 max_sdu_size, struct sk_buff *skb)
+ __u32 max_sdu_size, __u8 max_header_size,
+ struct sk_buff *skb)
X {
X struct irda_sock *self;
X struct sock *sk;
@@ -130,13 +133,28 @@
X
X self = (struct irda_sock *) instance;
X
+ /* How much header space do we need to reserve */
+ self->max_header_size = max_header_size;
+
+ /* IrTTP max SDU size in transmit direction */
X self->max_sdu_size_tx = max_sdu_size;
+
+ /* Find out what the largest chunk of data that we can transmit is */
+ if (max_sdu_size == SAR_DISABLE)
+ self->max_data_size = qos->data_size.value - max_header_size;
+ else
+ self->max_data_size = max_sdu_size;
+
+ DEBUG(1, __FUNCTION__ "(), max_data_size=%d\n", self->max_data_size);
+
X memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
X
X sk = self->sk;
X if (sk == NULL)
X return;
X
+ skb_queue_tail(&sk->receive_queue, skb);
+
X /* We are now connected! */
X sk->state = TCP_ESTABLISHED;
X sk->state_change(sk);
@@ -150,7 +168,7 @@
X */
X static void irda_connect_indication(void *instance, void *sap,
X struct qos_info *qos, __u32 max_sdu_size,
- struct sk_buff *skb)
+ __u8 max_header_size, struct sk_buff *skb)
X {
X struct irda_sock *self;
X struct sock *sk;
@@ -158,8 +176,21 @@
X DEBUG(1, __FUNCTION__ "()\n");
X
X self = (struct irda_sock *) instance;
-
- self->max_sdu_size_tx = max_sdu_size;
+
+ /* How much header space do we need to reserve */
+ self->max_header_size = max_header_size;
+
+ /* IrTTP max SDU size in transmit direction */
+ self->max_sdu_size_tx = max_sdu_size;
+
+ /* Find out what the largest chunk of data that we can transmit is */
+ if (max_sdu_size == SAR_DISABLE)
+ self->max_data_size = qos->data_size.value - max_header_size;
+ else
+ self->max_data_size = max_sdu_size;
+
+ DEBUG(1, __FUNCTION__ "(), max_data_size=%d\n", self->max_data_size);
+
X memcpy(&self->qos_tx, qos, sizeof(struct qos_info));
X
X sk = self->sk;


@@ -187,12 +218,12 @@
X

X skb = dev_alloc_skb(64);
X if (skb == NULL) {
- DEBUG( 0, __FUNCTION__ "() Could not allocate sk_buff!\n");
+ DEBUG(0, __FUNCTION__ "() Unable to allocate sk_buff!\n");
X return;
X }
X
X /* Reserve space for MUX_CONTROL and LAP header */
- skb_reserve(skb, TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER);
+ skb_reserve(skb, IRDA_MAX_HEADER);
X
X irttp_connect_response(self->tsap, self->max_sdu_size_rx, skb);
X }
@@ -219,12 +250,12 @@
X
X switch (flow) {
X case FLOW_STOP:
- DEBUG( 0, __FUNCTION__ "(), IrTTP wants us to slow down\n");
+ DEBUG(1, __FUNCTION__ "(), IrTTP wants us to slow down\n");
X self->tx_flow = flow;
X break;
X case FLOW_START:
X self->tx_flow = flow;
- DEBUG(0, __FUNCTION__ "(), IrTTP wants us to start again\n");
+ DEBUG(1, __FUNCTION__ "(), IrTTP wants us to start again\n");
X wake_up_interruptible(sk->sleep);
X break;
X default:
@@ -514,10 +545,13 @@
X new->stsap_sel = new->tsap->stsap_sel;
X new->dtsap_sel = new->tsap->dtsap_sel;
X new->saddr = irttp_get_saddr(new->tsap);
- new->saddr = irttp_get_saddr(new->tsap);
+ new->daddr = irttp_get_daddr(new->tsap);
X
X new->max_sdu_size_tx = self->max_sdu_size_tx;
X new->max_sdu_size_rx = self->max_sdu_size_rx;
+ new->max_data_size = self->max_data_size;


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

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

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.2/patch-2.2.10/part22

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


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

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

X
- len += sprintf( buf+len, "saddr: %#08x, daddr: %#08x, ",
- lap->saddr, lap->daddr);
- len += sprintf( buf+len, "\n");
+ len += sprintf(buf+len, "saddr: %#08x, daddr: %#08x, ",
+ lap->saddr, lap->daddr);
+ len += sprintf(buf+len, "\n");
X
X len += sprintf( buf+len, "\nConnected LSAPs:\n");
X self = (struct lsap_cb *) hashbin_get_first( lap->lsaps);
- while ( self != NULL) {
- ASSERT( self->magic == LMP_LSAP_MAGIC, return 0;);
- len += sprintf( buf+len, "lsap state: %s, ",
- irlsap_state[ self->lsap_state]);
- len += sprintf( buf+len,
- "slsap_sel: %#02x, dlsap_sel: %#02x, ",
- self->slsap_sel, self->dlsap_sel);
- len += sprintf( buf+len, "(%s)", self->notify.name);
- len += sprintf( buf+len, "\n");
+ while (self != NULL) {
+ ASSERT(self->magic == LMP_LSAP_MAGIC, return 0;);
+ len += sprintf(buf+len, "lsap state: %s, ",
+ irlsap_state[ self->lsap_state]);
+ len += sprintf(buf+len,
+ "slsap_sel: %#02x, dlsap_sel: %#02x, ",
+ self->slsap_sel, self->dlsap_sel);
+ len += sprintf(buf+len, "(%s)", self->notify.name);
+ len += sprintf(buf+len, "\n");
X
- self = ( struct lsap_cb *) hashbin_get_next(
+ self = (struct lsap_cb *) hashbin_get_next(
X lap->lsaps);
X }
+ len += sprintf(buf+len, "\n");
X
- lap = ( struct lap_cb *) hashbin_get_next(
- irlmp->links);
+ lap = (struct lap_cb *) hashbin_get_next(irlmp->links);
X }
X
X restore_flags( flags);
diff -u --recursive --new-file v2.2.9/linux/net/irda/irlmp_frame.c linux/net/irda/irlmp_frame.c
--- v2.2.9/linux/net/irda/irlmp_frame.c Wed Apr 28 11:37:32 1999
+++ linux/net/irda/irlmp_frame.c Mon Jun 7 16:19:59 1999
@@ -1,15 +1,15 @@
X /*********************************************************************
X *
X * Filename: irlmp_frame.c
- * Version: 0.8
+ * Version: 0.9
X * Description: IrLMP frame implementation


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Tue Aug 19 02:09:59 1997
- * Modified at: Fri Apr 23 09:12:23 1999
+ * Modified at: Mon May 31 09:53:16 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
- * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>

+ * Copyright (c) 1998-1999 Dag Brattli <da...@cs.uit.no>

X * All Rights Reserved.


X *
X * This program is free software; you can redistribute it and/or

@@ -59,16 +59,16 @@
X *
X * Send Link Control Frame to IrLAP
X */
-void irlmp_send_lcf_pdu( struct lap_cb *self, __u8 dlsap, __u8 slsap,
- __u8 opcode, struct sk_buff *skb)
+void irlmp_send_lcf_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
+ __u8 opcode, struct sk_buff *skb)
X {
X __u8 *frame;


X
- DEBUG( 4, __FUNCTION__ "()\n");

+ DEBUG(4, __FUNCTION__ "()\n");
X

- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LMP_LAP_MAGIC, return;);
- ASSERT( skb != NULL, return;);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == LMP_LAP_MAGIC, return;);
+ ASSERT(skb != NULL, return;);
X
X frame = skb->data;
X
@@ -82,8 +82,8 @@
X else
X frame[3] = 0x00; /* rsvd */
X
- ASSERT( self->irlap != NULL, return;);
- irlap_data_request( self->irlap, skb, TRUE);
+ ASSERT(self->irlap != NULL, return;);
+ irlap_data_request(self->irlap, skb, TRUE);
X }
X
X /*
@@ -112,7 +112,7 @@
X */
X slsap_sel = fp[0] & LSAP_MASK;
X dlsap_sel = fp[1];
-
+
X /*
X * Check if this is an incoming connection, since we must deal with
X * it in a different way than other established connections.
@@ -134,17 +134,17 @@
X self->lsaps);
X
X if (lsap == NULL) {
- DEBUG(0, "IrLMP, Sorry, no LSAP for received frame!\n");
- DEBUG(0, __FUNCTION__
+ DEBUG(2, "IrLMP, Sorry, no LSAP for received frame!\n");
+ DEBUG(2, __FUNCTION__
X "(), slsap_sel = %02x, dlsap_sel = %02x\n", slsap_sel,
X dlsap_sel);
X if (fp[0] & CONTROL_BIT) {
- DEBUG(0, __FUNCTION__
+ DEBUG(2, __FUNCTION__
X "(), received control frame %02x\n", fp[2]);
X } else {
- DEBUG(0, __FUNCTION__ "(), received data frame\n");
+ DEBUG(2, __FUNCTION__ "(), received data frame\n");
X }
- dev_kfree_skb( skb);
+ dev_kfree_skb(skb);
X return;
X }
X
@@ -224,11 +224,11 @@
X * Incoming LAP connection!
X *
X */
-void irlmp_link_connect_indication( struct lap_cb *self, __u32 saddr,
- __u32 daddr, struct qos_info *qos,
- struct sk_buff *skb)
+void irlmp_link_connect_indication(struct lap_cb *self, __u32 saddr,
+ __u32 daddr, struct qos_info *qos,


+ struct sk_buff *skb)
X {

- DEBUG( 4, __FUNCTION__ "()\n");

+ DEBUG(4, __FUNCTION__ "()\n");
X
X /* Copy QoS settings for this session */
X self->qos = qos;
@@ -237,7 +237,7 @@
X self->daddr = daddr;
X ASSERT(self->saddr == saddr, return;);
X
- irlmp_do_lap_event( self, LM_LAP_CONNECT_INDICATION, skb);
+ irlmp_do_lap_event(self, LM_LAP_CONNECT_INDICATION, skb);
X }
X
X /*
@@ -246,19 +246,19 @@
X * LAP connection confirmed!
X *
X */
-void irlmp_link_connect_confirm( struct lap_cb *self, struct qos_info *qos,
- struct sk_buff *userdata)
+void irlmp_link_connect_confirm(struct lap_cb *self, struct qos_info *qos,
+ struct sk_buff *userdata)
X {
- DEBUG( 4, "irlmp_link_connect_confirm()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
X

- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LMP_LAP_MAGIC, return;);
- ASSERT( qos != NULL, return;);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == LMP_LAP_MAGIC, return;);
+ ASSERT(qos != NULL, return;);
X
X /* Copy QoS settings for this session */
X self->qos = qos;
X
- irlmp_do_lap_event( self, LM_LAP_CONNECT_CONFIRM, NULL);
+ irlmp_do_lap_event(self, LM_LAP_CONNECT_CONFIRM, NULL);
X }
X
X /*
@@ -276,7 +276,9 @@
X irlmp_add_discovery(irlmp->cachelog, discovery);
X
X /* Just handle it the same way as a discovery confirm */
+#if 0
X irlmp_do_lap_event(self, LM_LAP_DISCOVERY_CONFIRM, NULL);
+#endif
X }
X
X /*
@@ -365,7 +367,7 @@
X #endif
X return lsap;
X }
- lsap = ( struct lsap_cb *) hashbin_get_next(queue);
+ lsap = (struct lsap_cb *) hashbin_get_next(queue);
X }
X
X /* Sorry not found! */
diff -u --recursive --new-file v2.2.9/linux/net/irda/irlpt/irlpt_cli.c linux/net/irda/irlpt/irlpt_cli.c
--- v2.2.9/linux/net/irda/irlpt/irlpt_cli.c Tue May 11 13:10:32 1999
+++ linux/net/irda/irlpt/irlpt_cli.c Sun May 30 10:17:04 1999
@@ -51,10 +51,11 @@
X static void irlpt_client_connect_confirm(void *instance, void *sap,
X struct qos_info *qos,
X __u32 max_seg_size,
+ __u8 max_header_size,
X struct sk_buff *skb);
-static void irlpt_client_disconnect_indication( void *instance, void *sap,
- LM_REASON reason,
- struct sk_buff *userdata);
+static void irlpt_client_disconnect_indication(void *instance, void *sap,
+ LM_REASON reason,
+ struct sk_buff *userdata);
X static void irlpt_client_expired(unsigned long data);
X
X #if 0
@@ -187,7 +188,7 @@
X
X #ifdef CONFIG_PROC_FS
X create_proc_entry("irlpt_client", 0, proc_irda)->get_info
- = irlpt_client_proc_read;
+ = irlpt_client_proc_read;
X #endif /* CONFIG_PROC_FS */
X
X DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
@@ -215,7 +216,6 @@
X #ifdef CONFIG_PROC_FS
X remove_proc_entry("irlpt_client", proc_irda);
X #endif
-
X DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");


X }
X #endif /* MODULE */

@@ -403,9 +403,8 @@
X

X irlpt_client_do_event( self, LMP_DISCONNECT, NULL, NULL);
X
- if (skb) {
+ if (skb)
X dev_kfree_skb( skb);
- }
X
X DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
X }
@@ -417,7 +416,8 @@
X */
X static void irlpt_client_connect_confirm(void *instance, void *sap,

X struct qos_info *qos,
- __u32 max_sdu_size,

+ __u32 max_seg_size,
+ __u8 max_header_size,
X struct sk_buff *skb)
X {
X struct irlpt_info info;
@@ -443,14 +443,14 @@
X }
X #endif
X
- self->irlap_data_size = (qos->data_size.value - IRLPT_MAX_HEADER);
+ self->max_data_size = max_seg_size;


+ self->max_header_size = max_header_size;

X self->connected = TRUE;
X
X irlpt_client_do_event( self, LMP_CONNECT, NULL, NULL);
X
- if (skb) {
+ if (skb)
X dev_kfree_skb( skb);
- }
X
X DEBUG( irlpt_client_debug, __FUNCTION__ " -->\n");
X }
@@ -603,7 +603,7 @@
X return;
X }
X
- skb_reserve( skb, LMP_CONTROL_HEADER+LAP_HEADER);
+ skb_reserve(skb, LMP_MAX_HEADER);
X irlmp_disconnect_request(self->lsap, skb);
X DEBUG(irlpt_client_debug, __FUNCTION__
X ": irlmp_close_slap(self->lsap)\n");
diff -u --recursive --new-file v2.2.9/linux/net/irda/irlpt/irlpt_cli_fsm.c linux/net/irda/irlpt/irlpt_cli_fsm.c
--- v2.2.9/linux/net/irda/irlpt/irlpt_cli_fsm.c Wed Mar 10 15:29:53 1999
+++ linux/net/irda/irlpt/irlpt_cli_fsm.c Sun May 30 10:17:04 1999


@@ -6,10 +6,10 @@
X * Status: Experimental.

X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Tue Jan 12 11:06:00 1999
- * Modified at: Tue Jan 26 12:02:31 1999
+ * Modified at: Sun May 9 13:36:13 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

- * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>
+ * Copyright (c) 1998-1999, Thomas Davis, <rat...@radiks.net>
X * Copyright (c) 1998, Dag Brattli, <da...@cs.uit.no>
X * All Rights Reserved.
X *
@@ -43,10 +43,10 @@
X IRLPT_EVENT event,
X struct sk_buff *skb,
X struct irlpt_info *info);
-static int irlpt_client_state_ready ( struct irlpt_cb *self,
- IRLPT_EVENT event,
- struct sk_buff *skb,
- struct irlpt_info *info);
+static int irlpt_client_state_ready ( struct irlpt_cb *self,
+ IRLPT_EVENT event,
+ struct sk_buff *skb,
+ struct irlpt_info *info);
X static int irlpt_client_state_waiti ( struct irlpt_cb *self,
X IRLPT_EVENT event,
X struct sk_buff *skb,
diff -u --recursive --new-file v2.2.9/linux/net/irda/irlpt/irlpt_common.c linux/net/irda/irlpt/irlpt_common.c
--- v2.2.9/linux/net/irda/irlpt/irlpt_common.c Wed Mar 10 15:29:53 1999
+++ linux/net/irda/irlpt/irlpt_common.c Sun May 30 10:17:04 1999
@@ -251,18 +251,18 @@
X }
X
X DEBUG( irlpt_common_debug, __FUNCTION__
- ": count = %d, irlap_data_size = %d, IRLPT_MAX_HEADER = %d\n",
- count, self->irlap_data_size, IRLPT_MAX_HEADER);
+ ": count = %d, max_data_size = %d, IRLPT_MAX_HEADER = %d\n",
+ count, self->max_data_size, IRLPT_MAX_HEADER);
X
- if (count > (self->irlap_data_size - IRLPT_MAX_HEADER)) {
- count = (self->irlap_data_size - IRLPT_MAX_HEADER);
+ if (count > self->max_data_size) {
+ count = self->max_data_size;
X DEBUG(irlpt_common_debug, __FUNCTION__
X ": setting count to %d\n", count);
X }
X
X DEBUG( irlpt_common_debug, __FUNCTION__ ": count = %d\n", count);
X
- skb = dev_alloc_skb(count + IRLPT_MAX_HEADER);
+ skb = dev_alloc_skb(count + self->max_header_size);
X if ( skb == NULL) {
X printk( KERN_INFO
X __FUNCTION__ ": couldn't allocate skbuff!\n");
@@ -417,7 +417,7 @@
X return 0;
X }
X
- skb_reserve( skb, LMP_CONTROL_HEADER+LAP_HEADER);
+ skb_reserve( skb, LMP_MAX_HEADER);
X irlmp_disconnect_request(self->lsap, skb);
X DEBUG(irlpt_common_debug, __FUNCTION__
X ": irlmp_close_slap(self->lsap)\n");
diff -u --recursive --new-file v2.2.9/linux/net/irda/irlpt/irlpt_srvr.c linux/net/irda/irlpt/irlpt_srvr.c
--- v2.2.9/linux/net/irda/irlpt/irlpt_srvr.c Tue May 11 13:10:32 1999
+++ linux/net/irda/irlpt/irlpt_srvr.c Sun May 30 10:17:04 1999
@@ -51,15 +51,21 @@
X static void irlpt_server_disconnect_indication(void *instance, void *sap,
X LM_REASON reason,
X struct sk_buff *skb);
+
+#if 0
X static void irlpt_server_connect_confirm(void *instance, void *sap,
X struct qos_info *qos,
X __u32 max_seg_size,
+ __u8 max_header_size,
X struct sk_buff *skb);
X static void irlpt_server_connect_indication(void *instance,
X void *sap,
X struct qos_info *qos,
X __u32 max_seg_size,
+ __u8 max_header_size,
X struct sk_buff *skb);
+#endif
+
X static int irlpt_server_data_indication(void *instance, void *sap,
X struct sk_buff *skb);
X static void register_irlpt_server(void);
@@ -161,7 +167,6 @@
X }
X
X extern struct proc_dir_entry *proc_irda;
-
X #endif /* CONFIG_PROC_FS */
X
X /*
@@ -171,9 +176,9 @@


X *
X */
X

-/*int irlpt_init( struct device *dev) {*/
X __initfunc(int irlpt_server_init(void))
X {
+ struct irmanager_event mgr_event;
X __u16 hints;
X
X DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
@@ -212,6 +217,10 @@
X = irlpt_server_proc_read;
X #endif /* CONFIG_PROC_FS */
X
+ mgr_event.event = EVENT_IRLPT_START;
+ sprintf(mgr_event.devname, "%s", irlpt_server->ifname);
+ irmanager_notify(&mgr_event);
+
X DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
X
X return 0;
@@ -225,6 +234,7 @@
X */
X static void irlpt_server_cleanup(void)
X {
+ struct irmanager_event mgr_event;


X struct sk_buff *skb;
X

X DEBUG( irlpt_server_debug, "--> " __FUNCTION__ "\n");
@@ -245,6 +255,10 @@
X remove_proc_entry("irlpt_server", proc_irda);
X #endif
X
+ mgr_event.event = EVENT_IRLPT_STOP;
+ sprintf( mgr_event.devname, "%s", irlpt_server->ifname);
+ irmanager_notify( &mgr_event);
+
X DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
X }
X
@@ -304,6 +318,7 @@
X void *sap,
X struct qos_info *qos,
X __u32 max_seg_size,
+ __u8 max_header_size,
X struct sk_buff *skb)
X {
X struct irlpt_cb *self;
@@ -314,6 +329,9 @@
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == IRLPT_MAGIC, return;);
X
+ self->max_data_size = max_seg_size;


+ self->max_header_size = max_header_size;
+

X self->connected = TRUE;
X
X irlpt_server_do_event( self, LMP_CONNECT, NULL, NULL);
@@ -329,6 +347,7 @@
X void *sap,
X struct qos_info *qos,
X __u32 max_seg_size,
+ __u8 max_header_size,
X struct sk_buff *skb)
X {
X struct irlpt_cb *self;
@@ -343,14 +362,16 @@
X ASSERT( self != NULL, return;);
X ASSERT( self->magic == IRLPT_MAGIC, return;);
X
+ self->max_data_size = max_seg_size;


+ self->max_header_size = max_header_size;
+

X self->connected = IRLPT_CONNECTED;
X self->eof = FALSE;
X
X irlpt_server_do_event( self, LMP_CONNECT, NULL, &info);
X
- if (skb) {
+ if (skb)
X dev_kfree_skb( skb);
- }
X
X DEBUG( irlpt_server_debug, __FUNCTION__ " -->\n");
X }
diff -u --recursive --new-file v2.2.9/linux/net/irda/irmod.c linux/net/irda/irmod.c
--- v2.2.9/linux/net/irda/irmod.c Wed Apr 28 11:37:32 1999
+++ linux/net/irda/irmod.c Mon Jun 7 16:19:59 1999


@@ -6,10 +6,10 @@
X * Status: Experimental.

X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Mon Dec 15 13:55:39 1997
- * Modified at: Mon Apr 12 11:31:01 1999
+ * Modified at: Fri May 14 13:46:02 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

- * Copyright (c) 1997 Dag Brattli, All Rights Reserved.
+ * Copyright (c) 1997, 1999 Dag Brattli, All Rights Reserved.


X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License as

@@ -45,7 +45,7 @@
X #include <net/irda/wrapper.h>
X #include <net/irda/timer.h>
X
-extern struct proc_dir_entry proc_irda;
+extern struct proc_dir_entry *proc_irda;
X
X struct irda_cb irda; /* One global instance */
X
@@ -110,6 +110,7 @@
X EXPORT_SYMBOL(irttp_flow_request);
X EXPORT_SYMBOL(irttp_connect_request);
X EXPORT_SYMBOL(irttp_udata_request);
+EXPORT_SYMBOL(irttp_dup);
X
X /* Main IrDA module */
X #ifdef CONFIG_IRDA_DEBUG
@@ -151,6 +152,7 @@
X EXPORT_SYMBOL(irlmp_disconnect_request);
X EXPORT_SYMBOL(irlmp_get_daddr);
X EXPORT_SYMBOL(irlmp_get_saddr);
+EXPORT_SYMBOL(irlmp_dup);
X EXPORT_SYMBOL(lmp_reasons);
X
X /* Queue */
@@ -174,10 +176,15 @@
X EXPORT_SYMBOL(irda_device_setup);
X EXPORT_SYMBOL(irda_device_set_media_busy);
X EXPORT_SYMBOL(irda_device_txqueue_empty);
+
+EXPORT_SYMBOL(irda_device_init_dongle);
+EXPORT_SYMBOL(irda_device_register_dongle);
+EXPORT_SYMBOL(irda_device_unregister_dongle);
+
X EXPORT_SYMBOL(async_wrap_skb);
X EXPORT_SYMBOL(async_unwrap_char);
X EXPORT_SYMBOL(irda_start_timer);
-EXPORT_SYMBOL(irda_get_mtt);
+/* EXPORT_SYMBOL(irda_get_mtt); */
X EXPORT_SYMBOL(setup_dma);
X
X #ifdef CONFIG_IRTTY
@@ -505,19 +512,28 @@
X #endif
X }
X
-#ifdef MODULE
-#ifdef CONFIG_PROC_FS
+/*
+ * Function irda_proc_modcount (inode, fill)
+ *
+ * Use by the proc file system functions to prevent the irda module
+ * being removed while the use is standing in the net/irda directory
+ */
X void irda_proc_modcount(struct inode *inode, int fill)
X {
+#ifdef MODULE
+#ifdef CONFIG_PROC_FS
X if (fill)
X MOD_INC_USE_COUNT;
X else
X MOD_DEC_USE_COUNT;
-}
X #endif /* CONFIG_PROC_FS */


+#endif /* MODULE */
+}
+

+#ifdef MODULE


X
X MODULE_AUTHOR("Dag Brattli <da...@cs.uit.no>");

-MODULE_DESCRIPTION("The Linux IrDA protocol subsystem");
+MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem");
X MODULE_PARM(irda_debug, "1l");
X
X /*
diff -u --recursive --new-file v2.2.9/linux/net/irda/irproc.c linux/net/irda/irproc.c
--- v2.2.9/linux/net/irda/irproc.c Tue May 11 13:10:32 1999
+++ linux/net/irda/irproc.c Sun May 30 10:17:04 1999


@@ -6,10 +6,10 @@
X * Status: Experimental.

X * Author: Thomas Davis, <rat...@radiks.net>

X * Created at: Sat Feb 21 21:33:24 1998
- * Modified at: Tue Apr 6 19:07:06 1999
+ * Modified at: Fri May 7 08:06:49 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

- * Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>,
+ * Copyright (c) 1998-1999, Thomas Davis, <rat...@radiks.net>,
X * All Rights Reserved.


X *
X * This program is free software; you can redistribute it and/or

@@ -20,8 +20,6 @@
X * I, Thomas Davis, provide no warranty for any of this software.
X * This material is provided "AS-IS" and at no charge.
X *
- * Portions lifted from the linux/fs/procfs/ files.
- *
X ********************************************************************/
X
X #include <linux/miscdevice.h>
@@ -44,28 +42,27 @@
X int unused);
X extern int discovery_proc_read(char *buf, char **start, off_t offset, int len,
X int unused);
+static int proc_discovery_read(char *buf, char **start, off_t offset, int len,
+ int unused);
X
-enum irda_directory_inos {
- PROC_IRDA_LAP = 1,
- PROC_IRDA_LMP,
- PROC_IRDA_TTP,
- PROC_IRDA_LPT,
- PROC_IRDA_COMM,
- PROC_IRDA_IRDA_DEVICE,
- PROC_IRDA_IRIAS
-};
+/* enum irda_directory_inos { */
+/* PROC_IRDA_LAP = 1, */
+/* PROC_IRDA_LMP, */
+/* PROC_IRDA_TTP, */
+/* PROC_IRDA_LPT, */
+/* PROC_IRDA_COMM, */
+/* PROC_IRDA_IRDA_DEVICE, */
+/* PROC_IRDA_IRIAS */
+/* }; */
X
X struct irda_entry {
X char *name;
- int (*fn)(char*,char**,off_t,int,int);
+ int (*fn)(char*, char**, off_t, int, int);
X };
X
X struct proc_dir_entry *proc_irda;
-
+
X static struct irda_entry dir[] = {
-#if 0
- {"lpt", irlpt_proc_read},
-#endif
X {"discovery", discovery_proc_read},
X {"irda_device", irda_device_proc_read},
X {"irttp", irttp_proc_read},
@@ -75,19 +72,22 @@
X };
X
X #define IRDA_ENTRIES_NUM (sizeof(dir)/sizeof(dir[0]))
-
+
X /*
X * Function irda_proc_register (void)
X *
X * Register irda entry in /proc file system
X *
X */
-void irda_proc_register(void) {
+void irda_proc_register(void)
+{
X int i;
+
X proc_irda = create_proc_entry("net/irda", S_IFDIR, NULL);
X #ifdef MODULE
X proc_irda->fill_inode = &irda_proc_modcount;


X #endif /* MODULE */

+
X for (i=0;i<IRDA_ENTRIES_NUM;i++)
X create_proc_entry(dir[i].name,0,proc_irda)->get_info=dir[i].fn;
X }
@@ -98,9 +98,14 @@
X * Unregister irda entry in /proc file system
X *
X */
-void irda_proc_unregister(void) {
+void irda_proc_unregister(void)
+{
X int i;
+
X for (i=0;i<IRDA_ENTRIES_NUM;i++)
X remove_proc_entry(dir[i].name, proc_irda);
+
X remove_proc_entry("net/irda", NULL);
X }
+
+
diff -u --recursive --new-file v2.2.9/linux/net/irda/irsysctl.c linux/net/irda/irsysctl.c
--- v2.2.9/linux/net/irda/irsysctl.c Wed Apr 28 11:37:32 1999
+++ linux/net/irda/irsysctl.c Sun May 30 10:17:04 1999
@@ -1,15 +1,15 @@
X /*********************************************************************
X *
X * Filename: irsysctl.c
- * Version:
- * Description:
+ * Version: 1.0
+ * Description: Sysctl interface for IrDA


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sun May 24 22:12:06 1998
- * Modified at: Fri Apr 23 09:46:38 1999
+ * Modified at: Thu May 6 21:32:46 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

- * Copyright (c) 1997 Dag Brattli, All Rights Reserved.
+ * Copyright (c) 1997, 1999 Dag Brattli, All Rights Reserved.


X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License as

diff -u --recursive --new-file v2.2.9/linux/net/irda/irttp.c linux/net/irda/irttp.c
--- v2.2.9/linux/net/irda/irttp.c Wed Apr 28 11:37:32 1999
+++ linux/net/irda/irttp.c Mon Jun 7 16:19:59 1999


@@ -6,10 +6,10 @@
X * Status: Experimental.

X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sun Aug 31 20:14:31 1997
- * Modified at: Sat Apr 10 10:32:21 1999
+ * Modified at: Mon May 31 10:29:56 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
- * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>,

+ * Copyright (c) 1998-1999 Dag Brattli <da...@cs.uit.no>,

X * All Rights Reserved.


X *
X * This program is free software; you can redistribute it and/or

@@ -35,7 +35,7 @@
X #include <net/irda/irlmp.h>
X #include <net/irda/irttp.h>
X
-struct irttp_cb *irttp = NULL;
+static struct irttp_cb *irttp = NULL;
X
X static void __irttp_close_tsap(struct tsap_cb *self);
X
@@ -44,19 +44,20 @@
X static int irttp_udata_indication(void *instance, void *sap,
X struct sk_buff *skb);
X static void irttp_disconnect_indication(void *instance, void *sap,
- LM_REASON reason,
- struct sk_buff *);
+ LM_REASON reason, struct sk_buff *);
X static void irttp_connect_indication(void *instance, void *sap,

X struct qos_info *qos, __u32 max_sdu_size,

- struct sk_buff *skb);
-
+ __u8 header_size, struct sk_buff *skb);
+static void irttp_connect_confirm(void *instance, void *sap,
+ struct qos_info *qos, __u32 max_sdu_size,
+ __u8 header_size, struct sk_buff *skb);
X static void irttp_run_tx_queue(struct tsap_cb *self);
X static void irttp_run_rx_queue(struct tsap_cb *self);
X
X static void irttp_flush_queues(struct tsap_cb *self);
X static void irttp_fragment_skb(struct tsap_cb *self, struct sk_buff *skb);
-static struct sk_buff *irttp_reassemble_skb(struct tsap_cb *self);
X static void irttp_start_todo_timer(struct tsap_cb *self, int timeout);
+static struct sk_buff *irttp_reassemble_skb(struct tsap_cb *self);
X
X /*
X * Function irttp_init (void)
@@ -296,7 +297,7 @@
X
X /* Check that nothing bad happens */
X if ((skb->len == 0) || (!self->connected)) {
- DEBUG(4, __FUNCTION__ "(), No data, or not connected\n");
+ ERROR(__FUNCTION__ "(), No data, or not connected\n");
X return -ENOTCONN;
X }
X
@@ -305,8 +306,8 @@
X * inside an IrLAP frame
X */
X if ((self->tx_max_sdu_size == 0) && (skb->len > self->max_seg_size)) {
- DEBUG(1, __FUNCTION__
- "(), SAR disabled, and data is to large for IrLAP!\n");
+ ERROR(__FUNCTION__
+ "(), SAR disabled, and data is to large for IrLAP!\n");
X return -EMSGSIZE;
X }
X
@@ -318,8 +319,8 @@
X (self->tx_max_sdu_size != SAR_UNBOUND) &&
X (skb->len > self->tx_max_sdu_size))
X {
- DEBUG(1, __FUNCTION__ "(), SAR enabled, "
- "but data is larger than TxMaxSduSize!\n");
+ ERROR(__FUNCTION__ "(), SAR enabled, "
+ "but data is larger than TxMaxSduSize!\n");
X return -EMSGSIZE;
X }
X /*
@@ -337,10 +338,10 @@
X /* Queue frame, or queue frame segments */
X if ((self->tx_max_sdu_size == 0) || (skb->len < self->max_seg_size)) {
X /* Queue frame */
+ ASSERT(skb_headroom(skb) >= TTP_HEADER, return -1;);
X frame = skb_push(skb, TTP_HEADER);
X frame[0] = 0x00; /* Clear more bit */
X
- DEBUG(4, __FUNCTION__ "(), queueing original skb\n");
X skb_queue_tail(&self->tx_queue, skb);
X } else {
X /*
@@ -360,8 +361,8 @@
X self->tx_sdu_busy = TRUE;
X
X if (self->notify.flow_indication) {
- self->notify.flow_indication(
- self->notify.instance, self, FLOW_STOP);
+ self->notify.flow_indication(self->notify.instance,
+ self, FLOW_STOP);
X }
X }
X
@@ -381,12 +382,8 @@
X {
X struct sk_buff *skb = NULL;
X unsigned long flags;
- __u8 *frame;
X int n;
X

- ASSERT(self != NULL, return;);

- ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
-
X if (irda_lock(&self->tx_queue_lock) == FALSE)
X return;
X
@@ -421,12 +418,7 @@
X * More bit must be set by the data_request() or fragment()
X * functions
X */
- frame = skb->data;
-
- DEBUG(4, __FUNCTION__ "(), More=%s\n", frame[0] & 0x80 ?
- "TRUE" : "FALSE" );
-
- frame[0] |= (__u8) (n & 0x7f);
+ skb->data[0] |= (n & 0x7f);
X
X irlmp_data_request(self->lsap, skb);
X self->stats.tx_packets++;
@@ -434,12 +426,12 @@
X /* Check if we can accept more frames from client */
X if ((self->tx_sdu_busy) &&
X (skb_queue_len(&self->tx_queue) < LOW_THRESHOLD))
- {
+ {
X self->tx_sdu_busy = FALSE;
X
X if (self->notify.flow_indication)
X self->notify.flow_indication(
- self->notify.instance, self,
+ self->notify.instance, self,
X FLOW_START);
X }
X }
@@ -472,7 +464,7 @@
X return;
X
X /* Reserve space for LMP, and LAP header */
- skb_reserve(tx_skb, LMP_HEADER+LAP_HEADER);
+ skb_reserve(tx_skb, self->max_header_size);
X
X /*
X * Since we can transmit and receive frames concurrently,
@@ -538,23 +530,14 @@
X struct sk_buff *skb)
X {
X struct tsap_cb *self;
- int more;
X int n;
- __u8 *frame;
-
+
X self = (struct tsap_cb *) instance;
X
X ASSERT(self != NULL, return -1;);
X ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;);
- ASSERT(skb != NULL, return -1;);
X
- frame = skb->data;
-
- n = frame[0] & 0x7f; /* Extract the credits */
- more = frame[0] & 0x80;
-
- DEBUG(3, __FUNCTION__"(), got %d credits, TSAP sel=%02x\n",
- n, self->stsap_sel);
+ n = skb->data[0] & 0x7f; /* Extract the credits */
X
X self->stats.rx_packets++;
X
@@ -562,10 +545,9 @@
X * Data or dataless frame? Dataless frames only contain the
X * TTP_HEADER
X */
- if (skb->len == 1) {
- /* Dataless flowdata TTP-PDU */
- self->send_credit += n;
- } else {
+ if (skb->len == 1)
+ self->send_credit += n; /* Dataless flowdata TTP-PDU */
+ else {
X /* Deal with inbound credit */
X self->send_credit += n;
X self->remote_credit--;
@@ -655,15 +637,14 @@
X return -ENOMEM;


X
X /* Reserve space for MUX_CONTROL and LAP header */

- skb_reserve(skb, (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER));
+ skb_reserve(skb, TTP_MAX_HEADER);
X } else {
X skb = userdata;
X /*
X * Check that the client has reserved enough space for
X * headers
X */
- ASSERT(skb_headroom(userdata) >=
- (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER), return -1;);
+ ASSERT(skb_headroom(userdata) >= TTP_MAX_HEADER, return -1;);
X }
X
X /* Initialize connection parameters */
@@ -691,12 +672,11 @@
X
X /* SAR enabled? */
X if (max_sdu_size > 0) {
- ASSERT(skb_headroom(skb) >=
- (TTP_HEADER_WITH_SAR+LMP_CONTROL_HEADER+LAP_HEADER),
- return -1;);
+ ASSERT(skb_headroom(skb) >= (TTP_MAX_HEADER + TTP_SAR_HEADER),
+ return -1;);
X
X /* Insert SAR parameters */
- frame = skb_push(skb, TTP_HEADER_WITH_SAR);
+ frame = skb_push(skb, TTP_HEADER+TTP_SAR_HEADER);
X
X frame[0] = TTP_PARAMETERS | n;
X frame[1] = 0x04; /* Length */
@@ -724,8 +704,10 @@
X * Sevice user confirms TSAP connection with peer.
X *
X */
-void irttp_connect_confirm(void *instance, void *sap, struct qos_info *qos,
- __u32 max_seg_size, struct sk_buff *skb)
+static void irttp_connect_confirm(void *instance, void *sap,
+ struct qos_info *qos,
+ __u32 max_seg_size, __u8 max_header_size,


+ struct sk_buff *skb)
X {

X struct tsap_cb *self;
X int parameters;
@@ -741,7 +723,8 @@
X ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
X ASSERT(skb != NULL, return;);
X
- self->max_seg_size = max_seg_size-LMP_HEADER-LAP_HEADER;
+ self->max_seg_size = max_seg_size;
+ self->max_header_size = max_header_size + TTP_HEADER;
X
X /*
X * Check if we have got some QoS parameters back! This should be the
@@ -764,6 +747,10 @@
X self->connected = TRUE;
X
X parameters = frame[0] & 0x80;
+
+ ASSERT(skb->len >= TTP_HEADER, return;);
+ skb_pull(skb, TTP_HEADER);
+
X if (parameters) {
X plen = frame[1];
X pi = frame[2];
@@ -789,17 +776,19 @@
X
X DEBUG(4, __FUNCTION__ "(), RxMaxSduSize=%d\n",
X self->tx_max_sdu_size);
+
+ /* Remove parameters */
+ ASSERT(skb->len >= (plen+1), return;);
+ skb_pull(skb, plen+1);
X }
X
X DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n",
X self->send_credit, self->avail_credit, self->remote_credit);
X
- skb_pull(skb, TTP_HEADER);
-
X if (self->notify.connect_confirm) {
- self->notify.connect_confirm(self->notify.instance, self,
- qos, self->tx_max_sdu_size,
- skb);
+ self->notify.connect_confirm(self->notify.instance, self, qos,
+ self->tx_max_sdu_size,
+ self->max_header_size, skb);
X }
X }
X
@@ -809,8 +798,8 @@
X * Some other device is connecting to this TSAP
X *
X */
-void irttp_connect_indication(void *instance, void *sap,
- struct qos_info *qos, __u32 max_seg_size,
+void irttp_connect_indication(void *instance, void *sap, struct qos_info *qos,
+ __u32 max_seg_size, __u8 max_header_size,
X struct sk_buff *skb)
X {
X struct tsap_cb *self;
@@ -828,7 +817,9 @@
X
X lsap = (struct lsap_cb *) sap;
X
- self->max_seg_size = max_seg_size-LMP_HEADER-LAP_HEADER;
+ self->max_seg_size = max_seg_size;
+
+ self->max_header_size = max_header_size+TTP_HEADER;
X
X DEBUG(4, __FUNCTION__ "(), TSAP sel=%02x\n", self->stsap_sel);
X
@@ -841,7 +832,11 @@
X self->send_credit = n;
X self->tx_max_sdu_size = 0;
X
- parameters = frame[0] & 0x80;
+ parameters = frame[0] & 0x80;
+
+ ASSERT(skb->len >= TTP_HEADER, return;);
+ skb_pull(skb, TTP_HEADER);
+
X if (parameters) {
X DEBUG(3, __FUNCTION__ "(), Contains parameters!\n");
X plen = frame[1];
@@ -850,7 +845,7 @@
X
X switch (pl) {
X case 1:
- self->tx_max_sdu_size = *(frame+4);
+ self->tx_max_sdu_size = frame[4];
X break;
X case 2:
X self->tx_max_sdu_size =
@@ -865,7 +860,10 @@
X "() illegal value length for max_sdu_size!\n");
X self->tx_max_sdu_size = 0;
X };
-
+
+ /* Remove parameters */
+ ASSERT(skb->len >= (plen+1), return;);
+ skb_pull(skb, plen+1);
X
X DEBUG(3, __FUNCTION__ "(), MaxSduSize=%d\n",
X self->tx_max_sdu_size);
@@ -873,12 +871,10 @@
X
X DEBUG(4, __FUNCTION__ "(), initial send_credit=%d\n", n);
X
- skb_pull(skb, 1); /* Remove TTP header */
-
X if (self->notify.connect_indication) {
X self->notify.connect_indication(self->notify.instance, self,
X qos, self->rx_max_sdu_size,
- skb);
+ self->max_header_size, skb);
X }
X }
X
@@ -909,15 +905,14 @@
X return;


X
X /* Reserve space for MUX_CONTROL and LAP header */

- skb_reserve(skb, (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER));
+ skb_reserve(skb, TTP_MAX_HEADER);
X } else {
X skb = userdata;
X /*
X * Check that the client has reserved enough space for
X * headers
X */
- ASSERT(skb_headroom(skb) >=
- (TTP_HEADER+LMP_CONTROL_HEADER+LAP_HEADER), return;);
+ ASSERT(skb_headroom(skb) >= TTP_MAX_HEADER, return;);
X }
X
X self->avail_credit = 0;
@@ -939,12 +934,11 @@
X
X /* SAR enabled? */
X if (max_sdu_size > 0) {
- ASSERT(skb_headroom(skb) >=
- (TTP_HEADER_WITH_SAR+LMP_CONTROL_HEADER+LAP_HEADER),
+ ASSERT(skb_headroom(skb) >= (TTP_MAX_HEADER+TTP_SAR_HEADER),
X return;);
X
X /* Insert TTP header with SAR parameters */
- frame = skb_push(skb, TTP_HEADER_WITH_SAR);
+ frame = skb_push(skb, TTP_HEADER+TTP_SAR_HEADER);
X
X frame[0] = TTP_PARAMETERS | n;
X frame[1] = 0x04; /* Length */
@@ -1079,7 +1073,7 @@
X /*
X * Reserve space for MUX and LAP header
X */
- skb_reserve(skb, LMP_CONTROL_HEADER+LAP_HEADER);
+ skb_reserve(skb, TTP_MAX_HEADER);
X
X userdata = skb;
X }
@@ -1357,13 +1351,11 @@
X }
X
X /* Make new segment */
- frag = dev_alloc_skb(self->max_seg_size+
- TTP_HEADER+LMP_HEADER+
- LAP_HEADER);
+ frag = dev_alloc_skb(self->max_seg_size+self->max_header_size);
X if (!frag)
X return;
X
- skb_reserve(frag, LMP_HEADER+LAP_HEADER);
+ skb_reserve(frag, self->max_header_size);
X
X /*
X * Copy data from the original skb into this fragment. We
@@ -1401,11 +1393,9 @@
X irttp_run_tx_queue(self);
X
X /* Give avay some credits to peer? */
- if ((skb_queue_empty(&self->tx_queue)) &&
- (self->remote_credit < LOW_THRESHOLD) &&
- (self->avail_credit > 0))
+ if ((self->remote_credit < LOW_THRESHOLD) &&
+ (self->avail_credit > 0) && (skb_queue_empty(&self->tx_queue)))
X {
- DEBUG(4, __FUNCTION__ "(), sending credit!\n");
X irttp_give_credit(self);
X }
X
diff -u --recursive --new-file v2.2.9/linux/net/irda/qos.c linux/net/irda/qos.c
--- v2.2.9/linux/net/irda/qos.c Wed Apr 28 11:37:32 1999
+++ linux/net/irda/qos.c Sun May 30 10:17:04 1999
@@ -6,10 +6,11 @@


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Tue Sep 9 00:00:26 1997
- * Modified at: Mon Apr 12 11:49:24 1999
+ * Modified at: Mon May 3 21:15:08 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
- * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
+ * Copyright (c) 1998-1999 Dag Brattli <da...@cs.uit.no>,
+ * All Rights Reserved.
X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License as

@@ -52,10 +53,10 @@
X * Compute the intersection of the old QoS capabilites with new ones
X *
X */
-void irda_qos_compute_intersection( struct qos_info *qos, struct qos_info *new)
+void irda_qos_compute_intersection(struct qos_info *qos, struct qos_info *new)
X {
- ASSERT( qos != NULL, return;);
- ASSERT( new != NULL, return;);
+ ASSERT(qos != NULL, return;);
+ ASSERT(new != NULL, return;);
X
X /* Apply */
X qos->baud_rate.bits &= new->baud_rate.bits;
diff -u --recursive --new-file v2.2.9/linux/net/irda/wrapper.c linux/net/irda/wrapper.c
--- v2.2.9/linux/net/irda/wrapper.c Wed Apr 28 11:37:32 1999
+++ linux/net/irda/wrapper.c Mon Jun 7 16:19:59 1999
@@ -1,15 +1,15 @@
X /*********************************************************************
X *
X * Filename: wrapper.c
- * Version: 1.1
- * Description: SIR wrapper layer


+ * Version: 1.2
+ * Description: IrDA SIR async wrapper layer
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X * Created at: Mon Aug 4 20:40:53 1997

- * Modified at: Wed Apr 21 12:45:55 1999
+ * Modified at: Fri May 28 20:30:24 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
- * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>,

+ * Copyright (c) 1998-1999 Dag Brattli <da...@cs.uit.no>,

X * All Rights Reserved.


X *
X * This program is free software; you can redistribute it and/or

@@ -34,7 +34,20 @@
X #include <net/irda/irlap_frame.h>
X #include <net/irda/irda_device.h>
X
-inline static int stuff_byte(__u8 byte, __u8 *buf);
+static inline int stuff_byte(__u8 byte, __u8 *buf);
+
+static void state_outside_frame(struct irda_device *idev, __u8 byte);
+static void state_begin_frame(struct irda_device *idev, __u8 byte);
+static void state_link_escape(struct irda_device *idev, __u8 byte);
+static void state_inside_frame(struct irda_device *idev, __u8 byte);
+
+static void (*state[])(struct irda_device *idev, __u8 byte) =
+{
+ state_outside_frame,
+ state_begin_frame,
+ state_link_escape,
+ state_inside_frame,
+};
X
X /*
X * Function async_wrap (skb, *tx_buff)
@@ -52,8 +65,6 @@
X __u8 bytes[2];
X } fcs;
X
- ASSERT(skb != NULL, return 0;);
-
X /* Initialize variables */
X fcs.value = INIT_FCS;
X n = 0;
@@ -74,13 +85,9 @@
X } else
X xbofs = ((struct irlap_skb_cb *)(skb->cb))->xbofs;
X
-#if 0
- for (i=0; i<xbofs; i++)
- tx_buff[n++] = XBOF;
-#else
X memset(tx_buff+n, XBOF, xbofs);
X n += xbofs;
-#endif
+
X /* Start of packet character BOF */
X tx_buff[n++] = BOF;
X
@@ -94,7 +101,7 @@
X ASSERT(n < (buffsize-5), return n;);
X
X n += stuff_byte(skb->data[i], tx_buff+n);
- fcs.value = IR_FCS(fcs.value, skb->data[i]);
+ fcs.value = irda_fcs(fcs.value, skb->data[i]);
X }
X
X /* Insert CRC in little endian format (LSB first) */
@@ -108,15 +115,6 @@
X #endif
X tx_buff[n++] = EOF;
X
-#if 0
- {
- int i;
-
- for (i=0;i<n;i++)
- printk("%02x", tx_buff[i]);
- printk("\n");
- }
-#endif
X return n;
X }
X
@@ -155,147 +153,13 @@
X }
X
X /*
- * Function async_unwrap (skb)
- *
- * Parse and de-stuff frame received from the IR-port
- *
- */
-void async_unwrap_char(struct irda_device *idev, __u8 byte)
-{
- /* State machine for receiving frames */
- switch (idev->rx_buff.state) {
- case OUTSIDE_FRAME:
- switch(byte) {
- case BOF:
- idev->rx_buff.state = BEGIN_FRAME;
- idev->rx_buff.in_frame = TRUE;
- break;
- case XBOF:
- /* idev->xbofs++; */
- break;
- case EOF:
- irda_device_set_media_busy( idev, TRUE);
- break;
- default:
- break;
- }
- break;
- case BEGIN_FRAME:
- switch (byte) {
- case BOF:
- /* Continue */
- break;
- case CE:
- /* Stuffed byte */
- idev->rx_buff.state = LINK_ESCAPE;
- break;
- case EOF:
- /* Abort frame */
- idev->rx_buff.state = OUTSIDE_FRAME;
-
- idev->stats.rx_errors++;
- idev->stats.rx_frame_errors++;
- break;
- default:
- /* Got first byte of frame */


- idev->rx_buff.data = idev->rx_buff.head;

- idev->rx_buff.len = 0;
-
- idev->rx_buff.data[idev->rx_buff.len++] = byte;
-
- idev->rx_buff.fcs = IR_FCS(INIT_FCS, byte);
- idev->rx_buff.state = INSIDE_FRAME;
- break;
- }
- break;
- case LINK_ESCAPE:
- switch (byte) {
- case BOF:
- /* New frame? */
- idev->rx_buff.state = BEGIN_FRAME;
- irda_device_set_media_busy(idev, TRUE);
- break;
- case CE:
- DEBUG(4, "WARNING: State not defined\n");
- break;
- case EOF:
- /* Abort frame */
- idev->rx_buff.state = OUTSIDE_FRAME;
- break;
- default:
- /*
- * Stuffed char, complement bit 5 of byte
- * following CE, IrLAP p.114
- */
- byte ^= IR_TRANS;
- if (idev->rx_buff.len < idev->rx_buff.truesize) {
- idev->rx_buff.data[idev->rx_buff.len++] = byte;
- idev->rx_buff.fcs = IR_FCS(idev->rx_buff.fcs,
- byte);
- idev->rx_buff.state = INSIDE_FRAME;
- } else {
- DEBUG(1, __FUNCTION__
- "(), Rx buffer overflow, aborting\n");
- idev->rx_buff.state = OUTSIDE_FRAME;
- }
- break;
- }
- break;
- case INSIDE_FRAME:
- switch (byte) {
- case BOF:
- /* New frame? */
- idev->rx_buff.state = BEGIN_FRAME;
- irda_device_set_media_busy(idev, TRUE);
- break;
- case CE:
- /* Stuffed char */
- idev->rx_buff.state = LINK_ESCAPE;
- break;
- case EOF:
- /* End of frame */
- idev->rx_buff.state = OUTSIDE_FRAME;
- idev->rx_buff.in_frame = FALSE;
-
- /*
- * Test FCS and deliver frame if it's good
- */
- if (idev->rx_buff.fcs == GOOD_FCS) {
- async_bump(idev, idev->rx_buff.data,
- idev->rx_buff.len);
- } else {
- /* Wrong CRC, discard frame! */
- irda_device_set_media_busy(idev, TRUE);
-
- idev->stats.rx_errors++;
- idev->stats.rx_crc_errors++;
- }
- break;
- default:
- /* Next byte of frame */
- if (idev->rx_buff.len < idev->rx_buff.truesize) {
- idev->rx_buff.data[idev->rx_buff.len++] = byte;
- idev->rx_buff.fcs = IR_FCS(idev->rx_buff.fcs,
- byte);
- } else {
- DEBUG(1, __FUNCTION__
- "(), Rx buffer overflow, aborting\n");
- idev->rx_buff.state = OUTSIDE_FRAME;
- }
- break;
- }


- break;
- }
-}
-

-/*
X * Function stuff_byte (byte, buf)
X *
X * Byte stuff one single byte and put the result in buffer pointed to by
X * buf. The buffer must at all times be able to have two bytes inserted.
X *
X */
-inline static int stuff_byte(__u8 byte, __u8 *buf)
+static inline int stuff_byte(__u8 byte, __u8 *buf)
X {
X switch (byte) {
X case BOF: /* FALLTHROUGH */
@@ -303,7 +167,7 @@
X case CE:
X /* Insert transparently coded */
X buf[0] = CE; /* Send link escape */
- buf[1] = byte^IR_TRANS; /* Complement bit 5 */
+ buf[1] = byte^IRDA_TRANS; /* Complement bit 5 */
X return 2;
X /* break; */
X default:
@@ -313,7 +177,163 @@
X /* break; */
X }
X }
+
+/*
+ * Function async_unwrap (skb)
+ *
+ * Parse and de-stuff frame received from the IrDA-port
+ *
+ */


+inline void async_unwrap_char(struct irda_device *idev, __u8 byte)

+{
+ (*state[idev->rx_buff.state]) (idev, byte);
+}
X
+/*
+ * Function state_outside_frame (idev, byte)


+ *
+ *
+ *
+ */

+static void state_outside_frame(struct irda_device *idev, __u8 byte)
+{
+ switch (byte) {
+ case BOF:
+ idev->rx_buff.state = BEGIN_FRAME;
+ idev->rx_buff.in_frame = TRUE;
+ break;
+ case XBOF:
+ /* idev->xbofs++; */
+ break;
+ case EOF:
+ irda_device_set_media_busy( idev, TRUE);
+ break;
+ default:


+ break;
+ }
+}
+

+/*
+ * Function state_begin_frame (idev, byte)
+ *
+ * Begin of frame detected
+ *
+ */
+static void state_begin_frame(struct irda_device *idev, __u8 byte)
+{
+ switch (byte) {
+ case BOF:
+ /* Continue */
+ break;
+ case CE:
+ /* Stuffed byte */
+ idev->rx_buff.state = LINK_ESCAPE;
+
+ /* Time to initialize receive buffer */


+ idev->rx_buff.data = idev->rx_buff.head;

+ idev->rx_buff.len = 0;
+ break;
+ case EOF:
+ /* Abort frame */
+ idev->rx_buff.state = OUTSIDE_FRAME;
+
+ idev->stats.rx_errors++;
+ idev->stats.rx_frame_errors++;
+ break;
+ default:
+ /* Time to initialize receive buffer */


+ idev->rx_buff.data = idev->rx_buff.head;

+ idev->rx_buff.len = 0;
+
+ idev->rx_buff.data[idev->rx_buff.len++] = byte;
+
+ idev->rx_buff.fcs = irda_fcs(INIT_FCS, byte);
+ idev->rx_buff.state = INSIDE_FRAME;
+ break;
+ }
+}
X
+/*
+ * Function state_link_escape (idev, byte)


+ *
+ *
+ *
+ */

+static void state_link_escape(struct irda_device *idev, __u8 byte)
+{
+ switch (byte) {
+ case BOF: /* New frame? */
+ idev->rx_buff.state = BEGIN_FRAME;
+ irda_device_set_media_busy(idev, TRUE);
+ break;
+ case CE:
+ DEBUG(4, "WARNING: State not defined\n");
+ break;
+ case EOF: /* Abort frame */
+ idev->rx_buff.state = OUTSIDE_FRAME;
+ break;
+ default:
+ /*
+ * Stuffed char, complement bit 5 of byte
+ * following CE, IrLAP p.114
+ */
+ byte ^= IRDA_TRANS;
+ if (idev->rx_buff.len < idev->rx_buff.truesize) {
+ idev->rx_buff.data[idev->rx_buff.len++] = byte;
+ idev->rx_buff.fcs = irda_fcs(idev->rx_buff.fcs, byte);
+ idev->rx_buff.state = INSIDE_FRAME;
+ } else {
+ DEBUG(1, __FUNCTION__
+ "(), Rx buffer overflow, aborting\n");
+ idev->rx_buff.state = OUTSIDE_FRAME;


+ }
+ break;
+ }
+}
+

+/*
+ * Function state_inside_frame (idev, byte)
+ *
+ * Handle bytes received within a frame
+ *
+ */
+static void state_inside_frame(struct irda_device *idev, __u8 byte)
+{
+ switch (byte) {
+ case BOF: /* New frame? */
+ idev->rx_buff.state = BEGIN_FRAME;
+ irda_device_set_media_busy(idev, TRUE);
+ break;
+ case CE: /* Stuffed char */
+ idev->rx_buff.state = LINK_ESCAPE;
+ break;
+ case EOF: /* End of frame */
+ idev->rx_buff.state = OUTSIDE_FRAME;
+ idev->rx_buff.in_frame = FALSE;
+
+ /* Test FCS and deliver frame if it's good */
+ if (idev->rx_buff.fcs == GOOD_FCS) {
+ async_bump(idev, idev->rx_buff.data,
+ idev->rx_buff.len);
+ } else {
+ /* Wrong CRC, discard frame! */
+ irda_device_set_media_busy(idev, TRUE);
+
+ idev->stats.rx_errors++;
+ idev->stats.rx_crc_errors++;
+ }
+ break;
+ default: /* Must be the next byte of the frame */
+ if (idev->rx_buff.len < idev->rx_buff.truesize) {
+ idev->rx_buff.data[idev->rx_buff.len++] = byte;
+ idev->rx_buff.fcs = irda_fcs(idev->rx_buff.fcs, byte);
+ } else {
+ DEBUG(1, __FUNCTION__
+ "(), Rx buffer overflow, aborting\n");
+ idev->rx_buff.state = OUTSIDE_FRAME;


+ }
+ break;
+ }
+}

X
X
diff -u --recursive --new-file v2.2.9/linux/net/netlink/af_netlink.c linux/net/netlink/af_netlink.c
--- v2.2.9/linux/net/netlink/af_netlink.c Fri Apr 16 14:47:31 1999
+++ linux/net/netlink/af_netlink.c Wed Jun 2 11:29:28 1999


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

X * NETLINK Kernel-user communication protocol.


X *
- * Authors: Alan Cox <al...@cymru.net>

+ * Authors: Alan Cox <al...@redhat.com>

X * Alexey Kuznetsov <kuz...@ms2.inr.ac.ru>


X *
X * This program is free software; you can redistribute it and/or

@@ -203,7 +203,7 @@
X */
X
X while (netlink_locked(sk)) {


- current->counter = 0;

+ current->policy |= SCHED_YIELD;
X schedule();
X }
X
diff -u --recursive --new-file v2.2.9/linux/net/netlink/netlink_dev.c linux/net/netlink/netlink_dev.c
--- v2.2.9/linux/net/netlink/netlink_dev.c Sat Sep 5 16:46:42 1998
+++ linux/net/netlink/netlink_dev.c Wed Jun 2 11:29:28 1999
@@ -2,7 +2,7 @@
X * NETLINK An implementation of a loadable kernel mode driver providing


X * multiple kernel/user space bidirectional communications links.

X *
- * Author: Alan Cox <al...@cymru.net>
+ * Author: Alan Cox <al...@redhat.com>


X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License

SHAR_EOF
true || echo 'restore of patch-2.2.10 failed'

echo 'File patch-2.2.10 is complete' &&
chmod 644 patch-2.2.10 ||


echo 'restore of patch-2.2.10 failed'

Cksum="`cksum < 'patch-2.2.10'`"
if ! test "2711436326 1251005" = "$Cksum"
then
echo 'patch-2.2.10: original Checksum 2711436326 1251005, current one' "$Cksum"
rm -f _shar_wnt_.tmp
rm -f _shar_seq_.tmp
exit 1
fi
rm -f _shar_wnt_.tmp
fi
rm -f _shar_seq_.tmp
echo 'You have unpacked the last part.'
exit 0

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

unread,
Jun 16, 1999, 3:00:00 AM6/16/99
to
Archive-name: v2.2/patch-2.2.10/part21

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


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

if test "$Scheck" != 21; then


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

X return -ENOMEM;
X }
X
X #ifdef CONFIG_IRDA_COMPRESSION
- irlap_compressors = hashbin_new( HB_LOCAL);
- if ( irlap_compressors == NULL) {
- printk( KERN_WARNING "IrLAP: Can't allocate compressors hashbin!\n");
+ irlap_compressors = hashbin_new(HB_LOCAL);
+ if (irlap_compressors == NULL) {
+ printk(KERN_WARNING "IrLAP: Can't allocate compressors hashbin!\n");
X return -ENOMEM;
X }
X #endif
@@ -86,12 +91,12 @@
X
X void irlap_cleanup(void)
X {
- ASSERT( irlap != NULL, return;);
+ ASSERT(irlap != NULL, return;);
X
- hashbin_delete( irlap, (FREE_FUNC) __irlap_close);
+ hashbin_delete(irlap, (FREE_FUNC) __irlap_close);
X
X #ifdef CONFIG_IRDA_COMPRESSION
- hashbin_delete( irlap_compressors, (FREE_FUNC) kfree);
+ hashbin_delete(irlap_compressors, (FREE_FUNC) kfree);
X #endif
X }
X
@@ -101,32 +106,32 @@
X * Initialize IrLAP layer
X *
X */
-struct irlap_cb *irlap_open( struct irda_device *irdev)
+struct irlap_cb *irlap_open(struct irda_device *irdev)
X {
X struct irlap_cb *self;


X
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
X

- ASSERT( irdev != NULL, return NULL;);
- ASSERT( irdev->magic == IRDA_DEVICE_MAGIC, return NULL;);
+ ASSERT(irdev != NULL, return NULL;);
+ ASSERT(irdev->magic == IRDA_DEVICE_MAGIC, return NULL;);
X
X /* Initialize the irlap structure. */
- self = kmalloc( sizeof( struct irlap_cb), GFP_KERNEL);


- if ( self == NULL)

+ self = kmalloc(sizeof(struct irlap_cb), GFP_KERNEL);


+ if (self == NULL)

X return NULL;
X
- memset( self, 0, sizeof(struct irlap_cb));
+ memset(self, 0, sizeof(struct irlap_cb));
X self->magic = LAP_MAGIC;
X
X /* Make a binding between the layers */
X self->irdev = irdev;
X self->netdev = &irdev->netdev;
X
- irlap_next_state( self, LAP_OFFLINE);
+ irlap_next_state(self, LAP_OFFLINE);
X
X /* Initialize transmitt queue */
- skb_queue_head_init( &self->tx_list);
- skb_queue_head_init( &self->wx_list);
+ skb_queue_head_init(&self->tx_list);
+ skb_queue_head_init(&self->wx_list);
X
X /* My unique IrLAP device address! */
X get_random_bytes(&self->saddr, sizeof(self->saddr));
@@ -140,21 +145,21 @@
X self->caddr &= 0xfe;
X }
X
- init_timer( &self->slot_timer);
- init_timer( &self->query_timer);
- init_timer( &self->discovery_timer);
- init_timer( &self->final_timer);
- init_timer( &self->poll_timer);
- init_timer( &self->wd_timer);
- init_timer( &self->backoff_timer);
+ init_timer(&self->slot_timer);
+ init_timer(&self->query_timer);
+ init_timer(&self->discovery_timer);
+ init_timer(&self->final_timer);
+ init_timer(&self->poll_timer);
+ init_timer(&self->wd_timer);
+ init_timer(&self->backoff_timer);
X
- irlap_apply_default_connection_parameters( self);
+ irlap_apply_default_connection_parameters(self);
X
- irlap_next_state( self, LAP_NDM);
+ irlap_next_state(self, LAP_NDM);
X
- hashbin_insert( irlap, (QUEUE *) self, self->saddr, NULL);
+ hashbin_insert(irlap, (QUEUE *) self, self->saddr, NULL);
X
- irlmp_register_link( self, self->saddr, &self->notify);
+ irlmp_register_link(self, self->saddr, &self->notify);
X
X return self;
X }
@@ -165,26 +170,26 @@
X * Remove IrLAP and all allocated memory. Stop any pending timers.
X *
X */
-static void __irlap_close( struct irlap_cb *self)
+static void __irlap_close(struct irlap_cb *self)


X {
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
X
X /* Stop timers */
- del_timer( &self->slot_timer);
- del_timer( &self->query_timer);
- del_timer( &self->discovery_timer);
- del_timer( &self->final_timer);
- del_timer( &self->poll_timer);
- del_timer( &self->wd_timer);
- del_timer( &self->backoff_timer);
+ del_timer(&self->slot_timer);
+ del_timer(&self->query_timer);
+ del_timer(&self->discovery_timer);
+ del_timer(&self->final_timer);
+ del_timer(&self->poll_timer);
+ del_timer(&self->wd_timer);
+ del_timer(&self->backoff_timer);
X
- irlap_flush_all_queues( self);
+ irlap_flush_all_queues(self);
X
X self->irdev = NULL;
X self->magic = 0;
X
- kfree( self);
+ kfree(self);
X }
X
X /*
@@ -193,27 +198,27 @@
X * Remove IrLAP instance
X *
X */
-void irlap_close( struct irlap_cb *self)
+void irlap_close(struct irlap_cb *self)
X {
X struct irlap_cb *lap;


X
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
X
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
X
- irlap_disconnect_indication( self, LAP_DISC_INDICATION);
+ irlap_disconnect_indication(self, LAP_DISC_INDICATION);
X
X irlmp_unregister_link(self->saddr);
X self->notify.instance = NULL;
X
X /* Be sure that we manage to remove ourself from the hash */
- lap = hashbin_remove( irlap, self->saddr, NULL);
- if ( !lap) {
- DEBUG( 1, __FUNCTION__ "(), Didn't find myself!\n");
+ lap = hashbin_remove(irlap, self->saddr, NULL);
+ if (!lap) {
+ DEBUG(1, __FUNCTION__ "(), Didn't find myself!\n");
X return;
X }
- __irlap_close( lap);
+ __irlap_close(lap);
X }
X
X /*
@@ -243,7 +248,7 @@
X */
X void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb)

X {
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
X

X irlap_do_event(self, CONNECT_RESPONSE, skb, NULL);
X }
@@ -324,23 +329,23 @@
X * Received some data that was sent unreliable
X *
X */
-void irlap_unit_data_indication( struct irlap_cb *self, struct sk_buff *skb)
+void irlap_unit_data_indication(struct irlap_cb *self, struct sk_buff *skb)
X {
- DEBUG( 1, __FUNCTION__ "()\n");
+ DEBUG(1, __FUNCTION__ "()\n");

X
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


- ASSERT( skb != NULL, return;);
+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);


+ ASSERT(skb != NULL, return;);
X

X /* Hide LAP header from IrLMP layer */
- skb_pull( skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
+ skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
X
X #ifdef CONFIG_IRDA_COMPRESSION
- if ( self->qos_tx.compression.value) {
+ if (self->qos_tx.compression.value) {
X
- skb = irlap_decompress_frame( self, skb);
- if ( !skb) {
- DEBUG( 1, __FUNCTION__ "(), Decompress error!\n");
+ skb = irlap_decompress_frame(self, skb);
+ if (!skb) {
+ DEBUG(1, __FUNCTION__ "(), Decompress error!\n");
X return;
X }
X }
@@ -354,40 +359,35 @@
X * Queue data for transmission, must wait until XMIT state
X *
X */
-inline void irlap_data_request( struct irlap_cb *self, struct sk_buff *skb,
+inline void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb,
X int reliable)


X {
- DEBUG( 4, __FUNCTION__ "()\n");

-

- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


- ASSERT( skb != NULL, return;);

-
- DEBUG( 4, __FUNCTION__ "(), tx_list=%d\n",
- skb_queue_len( &self->tx_list));


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);


+ ASSERT(skb != NULL, return;);
X

X #ifdef CONFIG_IRDA_COMPRESSION
- if ( self->qos_tx.compression.value) {
- skb = irlap_compress_frame( self, skb);
- if ( !skb) {
- DEBUG( 1, __FUNCTION__ "(), Compress error!\n");
+ if (self->qos_tx.compression.value) {
+ skb = irlap_compress_frame(self, skb);
+ if (!skb) {
+ DEBUG(1, __FUNCTION__ "(), Compress error!\n");
X return;
X }
X }
X #endif
X
- ASSERT( skb_headroom( skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER),
- return;);
- skb_push( skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
+ ASSERT(skb_headroom(skb) >= (LAP_ADDR_HEADER+LAP_CTRL_HEADER),
+ return;);
+ skb_push(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
X
X /*
X * Must set frame format now so that the rest of the code knows
X * if its dealing with an I or an UI frame
X */
- if ( reliable)
+ if (reliable)
X skb->data[1] = I_FRAME;
X else {
- DEBUG( 4, __FUNCTION__ "(), queueing unreliable frame\n");
+ DEBUG(4, __FUNCTION__ "(), queueing unreliable frame\n");
X skb->data[1] = UI_FRAME;
X }
X
@@ -395,20 +395,20 @@
X * Send event if this frame only if we are in the right state
X * FIXME: udata should be sent first! (skb_queue_head?)
X */
- if (( self->state == LAP_XMIT_P) || (self->state == LAP_XMIT_S)) {
+ if ((self->state == LAP_XMIT_P) || (self->state == LAP_XMIT_S)) {
X /*
X * Check if the transmit queue contains some unsent frames,
X * and if so, make sure they are sent first
X */
- if ( !skb_queue_empty( &self->tx_list)) {
- skb_queue_tail( &self->tx_list, skb);
- skb = skb_dequeue( &self->tx_list);
+ if (!skb_queue_empty(&self->tx_list)) {
+ skb_queue_tail(&self->tx_list, skb);
+ skb = skb_dequeue(&self->tx_list);
X

- ASSERT( skb != NULL, return;);

+ ASSERT(skb != NULL, return;);
X }
- irlap_do_event( self, SEND_I_CMD, skb, NULL);
+ irlap_do_event(self, SEND_I_CMD, skb, NULL);
X } else
- skb_queue_tail( &self->tx_list, skb);
+ skb_queue_tail(&self->tx_list, skb);
X }
X
X /*
@@ -444,33 +444,33 @@
X * Disconnect request from other device
X *
X */
-void irlap_disconnect_indication( struct irlap_cb *self, LAP_REASON reason)
+void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason)
X {
- DEBUG( 1, __FUNCTION__ "(), reason=%s\n", lap_reasons[reason]);
+ DEBUG(1, __FUNCTION__ "(), reason=%s\n", lap_reasons[reason]);

X
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
X
X #ifdef CONFIG_IRDA_COMPRESSION
- irda_free_compression( self);
+ irda_free_compression(self);
X #endif
X /* Flush queues */
- irlap_flush_all_queues( self);
+ irlap_flush_all_queues(self);
X
- switch( reason) {
+ switch(reason) {
X case LAP_RESET_INDICATION:
- DEBUG( 1, __FUNCTION__ "(), Sending reset request!\n");
- irlap_do_event( self, RESET_REQUEST, NULL, NULL);
+ DEBUG(1, __FUNCTION__ "(), Sending reset request!\n");
+ irlap_do_event(self, RESET_REQUEST, NULL, NULL);
X break;
X case LAP_NO_RESPONSE: /* FALLTROUGH */
X case LAP_DISC_INDICATION: /* FALLTROUGH */
X case LAP_FOUND_NONE: /* FALLTROUGH */
X case LAP_MEDIA_BUSY:
- irlmp_link_disconnect_indication( self->notify.instance,
+ irlmp_link_disconnect_indication(self->notify.instance,
X self, reason, NULL);
X break;
X default:
- DEBUG( 1, __FUNCTION__ "(), Reason %d not implemented!\n",
+ DEBUG(1, __FUNCTION__ "(), Reason %d not implemented!\n",
X reason);
X }
X }
@@ -485,22 +485,22 @@
X {
X struct irlap_info info;


X
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);
- ASSERT( discovery != NULL, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
+ ASSERT(discovery != NULL, return;);
X
- DEBUG( 4, __FUNCTION__ "(), nslots = %d\n", discovery->nslots);
+ DEBUG(4, __FUNCTION__ "(), nslots = %d\n", discovery->nslots);
X
- ASSERT(( discovery->nslots == 1) || ( discovery->nslots == 6) ||
- ( discovery->nslots == 8) || ( discovery->nslots == 16),
+ ASSERT((discovery->nslots == 1) || (discovery->nslots == 6) ||
+ (discovery->nslots == 8) || (discovery->nslots == 16),

X return;);
X
X /*

X * Discovery is only possible in NDM mode
X */
- if ( self->state == LAP_NDM) {
- ASSERT( self->discovery_log == NULL, return;);
- self->discovery_log= hashbin_new( HB_LOCAL);
+ if (self->state == LAP_NDM) {
+ ASSERT(self->discovery_log == NULL, return;);
+ self->discovery_log= hashbin_new(HB_LOCAL);
X
X info.S = discovery->nslots; /* Number of slots */
X info.s = 0; /* Current slot */
@@ -526,11 +526,11 @@
X
X self->slot_timeout = sysctl_slot_timeout * HZ / 1000;
X
- irlap_do_event( self, DISCOVERY_REQUEST, NULL, &info);
+ irlap_do_event(self, DISCOVERY_REQUEST, NULL, &info);
X } else {
- DEBUG( 4, __FUNCTION__
+ DEBUG(4, __FUNCTION__
X "(), discovery only possible in NDM mode\n");
- irlap_discovery_confirm( self, NULL);
+ irlap_discovery_confirm(self, NULL);
X }
X }
X
@@ -540,12 +540,12 @@
X * A device has been discovered in front of this station, we
X * report directly to LMP.
X */
-void irlap_discovery_confirm( struct irlap_cb *self, hashbin_t *discovery_log)
+void irlap_discovery_confirm(struct irlap_cb *self, hashbin_t *discovery_log)

X {
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
X
- ASSERT( self->notify.instance != NULL, return;);
+ ASSERT(self->notify.instance != NULL, return;);
X
X /*
X * Check for successful discovery, since we are then allowed to clear
@@ -556,7 +556,7 @@
X irda_device_set_media_busy(self->irdev, FALSE);
X
X /* Inform IrLMP */
- irlmp_link_discovery_confirm( self->notify.instance, discovery_log);
+ irlmp_link_discovery_confirm(self->notify.instance, discovery_log);
X
X /*
X * IrLMP has now the responsibilities for the discovery_log
@@ -572,13 +572,13 @@
X */
X void irlap_discovery_indication(struct irlap_cb *self, discovery_t *discovery)

X {
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
X
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);
- ASSERT( discovery != NULL, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
+ ASSERT(discovery != NULL, return;);
X
- ASSERT( self->notify.instance != NULL, return;);
+ ASSERT(self->notify.instance != NULL, return;);
X
X irlmp_link_discovery_indication(self->notify.instance, discovery);
X }
@@ -591,12 +591,12 @@
X */
X void irlap_status_indication(int quality_of_link)
X {
- switch( quality_of_link) {
+ switch(quality_of_link) {
X case STATUS_NO_ACTIVITY:
- printk( KERN_INFO "IrLAP, no activity on link!\n");
+ printk(KERN_INFO "IrLAP, no activity on link!\n");
X break;
X case STATUS_NOISY:
- printk( KERN_INFO "IrLAP, noisy link!\n");
+ printk(KERN_INFO "IrLAP, noisy link!\n");
X break;
X default:
X break;
@@ -610,17 +610,17 @@
X *
X *
X */
-void irlap_reset_indication( struct irlap_cb *self)
+void irlap_reset_indication(struct irlap_cb *self)
X {
- DEBUG( 1, __FUNCTION__ "()\n");
+ DEBUG(1, __FUNCTION__ "()\n");


X
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
X
- if ( self->state == LAP_RESET_WAIT)
- irlap_do_event( self, RESET_REQUEST, NULL, NULL);
+ if (self->state == LAP_RESET_WAIT)
+ irlap_do_event(self, RESET_REQUEST, NULL, NULL);
X else
- irlap_do_event( self, RESET_RESPONSE, NULL, NULL);
+ irlap_do_event(self, RESET_RESPONSE, NULL, NULL);
X }
X
X /*
@@ -631,7 +631,7 @@
X */
X void irlap_reset_confirm(void)
X {
- DEBUG( 1, __FUNCTION__ "()\n");
+ DEBUG(1, __FUNCTION__ "()\n");
X }
X
X /*
@@ -641,15 +641,15 @@
X * S = Number of slots (0 -> S-1)
X * s = Current slot
X */
-int irlap_generate_rand_time_slot( int S, int s)
+int irlap_generate_rand_time_slot(int S, int s)
X {
X int slot;
X
- ASSERT(( S - s) > 0, return 0;);
+ ASSERT((S - s) > 0, return 0;);
X
X slot = s + jiffies % (S-s);
X
- ASSERT(( slot >= s) || ( slot < S), return 0;);
+ ASSERT((slot >= s) || (slot < S), return 0;);
X
X return slot;
X }
@@ -661,51 +661,51 @@
X * not intuitive and you should not try to change it. If you think it
X * contains bugs, please mail a patch to the author instead.
X */
-void irlap_update_nr_received( struct irlap_cb *self, int nr)
+void irlap_update_nr_received(struct irlap_cb *self, int nr)

X {
X struct sk_buff *skb = NULL;

X int count = 0;


X
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
X
X /*
X * Remove all the ack-ed frames from the window queue.
X */
X
- DEBUG( 4, "--> wx_list=%d, va=%d, nr=%d\n",
- skb_queue_len( &self->wx_list), self->va, nr);
+ DEBUG(4, "--> wx_list=%d, va=%d, nr=%d\n",
+ skb_queue_len(&self->wx_list), self->va, nr);
X
X /*
X * Optimize for the common case. It is most likely that the receiver
X * will acknowledge all the frames we have sent! So in that case we
X * delete all frames stored in window.
X */
- if ( nr == self->vs) {
- while (( skb = skb_dequeue( &self->wx_list)) != NULL) {
+ if (nr == self->vs) {
+ while ((skb = skb_dequeue(&self->wx_list)) != NULL) {
X dev_kfree_skb(skb);
X }
X /* The last acked frame is the next to send minus one */
X self->va = nr - 1;
X } else {
X /* Remove all acknowledged frames in current window */
- while (( skb_peek( &self->wx_list) != NULL) &&
- ((( self->va+1) % 8) != nr))
+ while ((skb_peek(&self->wx_list) != NULL) &&
+ (((self->va+1) % 8) != nr))
X {
- skb = skb_dequeue( &self->wx_list);
+ skb = skb_dequeue(&self->wx_list);
X dev_kfree_skb(skb);
X
X self->va = (self->va + 1) % 8;
X count++;
X }
X
- DEBUG( 4, "irlap_update_nr_received(), removed %d\n", count);
- DEBUG( 4, "wx_list=%d, va=%d, nr=%d -->\n",
- skb_queue_len( &self->wx_list), self->va, nr);
+ DEBUG(4, "irlap_update_nr_received(), removed %d\n", count);
+ DEBUG(4, "wx_list=%d, va=%d, nr=%d -->\n",
+ skb_queue_len(&self->wx_list), self->va, nr);
X }
X
X /* Advance window */
- self->window = self->window_size - skb_queue_len( &self->wx_list);
+ self->window = self->window_size - skb_queue_len(&self->wx_list);
X }
X
X /*
@@ -713,14 +713,14 @@
X *
X * Validate the next to send (ns) field from received frame.
X */
-int irlap_validate_ns_received( struct irlap_cb *self, int ns)
+int irlap_validate_ns_received(struct irlap_cb *self, int ns)
X {
- ASSERT( self != NULL, return -ENODEV;);
- ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
+ ASSERT(self != NULL, return -ENODEV;);
+ ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
X
X /* ns as expected? */
- if ( ns == self->vr) {
- DEBUG( 4, __FUNCTION__ "(), expected!\n");
+ if (ns == self->vr) {
+ DEBUG(4, __FUNCTION__ "(), expected!\n");
X return NS_EXPECTED;
X }
X /*
@@ -737,14 +737,14 @@
X * Validate the next to receive (nr) field from received frame.
X *
X */
-int irlap_validate_nr_received( struct irlap_cb *self, int nr)
+int irlap_validate_nr_received(struct irlap_cb *self, int nr)
X {
- ASSERT( self != NULL, return -ENODEV;);
- ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
+ ASSERT(self != NULL, return -ENODEV;);
+ ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
X
X /* nr as expected? */
- if ( nr == self->vs) {
- DEBUG( 4, __FUNCTION__ "(), expected!\n");
+ if (nr == self->vs) {
+ DEBUG(4, __FUNCTION__ "(), expected!\n");
X return NR_EXPECTED;
X }
X
@@ -752,11 +752,11 @@
X * unexpected nr? (but within current window), first we check if the
X * ns numbers of the frames in the current window wrap.
X */
- if ( self->va < self->vs) {
- if (( nr >= self->va) && ( nr <= self->vs))
+ if (self->va < self->vs) {
+ if ((nr >= self->va) && (nr <= self->vs))
X return NR_UNEXPECTED;
X } else {
- if (( nr >= self->va) || ( nr <= self->vs))
+ if ((nr >= self->va) || (nr <= self->vs))
X return NR_UNEXPECTED;
X }
X
@@ -770,12 +770,12 @@
X * Initialize the connection state parameters
X *
X */
-void irlap_initiate_connection_state( struct irlap_cb *self)
+void irlap_initiate_connection_state(struct irlap_cb *self)

X {
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
X
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
X
X /* Next to send and next to receive */
X self->vs = self->vr = 0;
@@ -829,24 +829,24 @@
X * Flush all queues
X *
X */
-void irlap_flush_all_queues( struct irlap_cb *self)
+void irlap_flush_all_queues(struct irlap_cb *self)
X {
X struct sk_buff* skb;


X
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
X
X /* Free transmission queue */
- while (( skb = skb_dequeue( &self->tx_list)) != NULL)
- dev_kfree_skb( skb);
+ while ((skb = skb_dequeue(&self->tx_list)) != NULL)
+ dev_kfree_skb(skb);
X
X /* Free sliding window buffered packets */
- while (( skb = skb_dequeue( &self->wx_list)) != NULL)
- dev_kfree_skb( skb);
+ while ((skb = skb_dequeue(&self->wx_list)) != NULL)
+ dev_kfree_skb(skb);
X
X #ifdef CONFIG_IRDA_RECYCLE_RR
- if ( self->recycle_rr_skb) {
- dev_kfree_skb( self->recycle_rr_skb);
+ if (self->recycle_rr_skb) {
+ dev_kfree_skb(self->recycle_rr_skb);
X self->recycle_rr_skb = NULL;
X }
X #endif
@@ -866,7 +866,7 @@
X ASSERT(self->magic == LAP_MAGIC, return;);
X
X if (!self->irdev) {
- DEBUG( 1, __FUNCTION__ "(), driver missing!\n");
+ DEBUG(1, __FUNCTION__ "(), driver missing!\n");
X return;
X }
X
@@ -883,8 +883,8 @@
X __u8 mask; /* Current bit tested */
X int i;


X
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
X
X /*
X * Find out which compressors we support. We do this be checking that
@@ -892,24 +892,24 @@
X * actually been loaded. Ths is sort of hairy code but that is what
X * you get when you do a little bit flicking :-)
X */
- DEBUG( 4, __FUNCTION__ "(), comp bits 0x%02x\n",
+ DEBUG(4, __FUNCTION__ "(), comp bits 0x%02x\n",
X self->qos_rx.compression.bits);
X mask = 0x80; /* Start with testing MSB */
- for ( i=0;i<8;i++) {
- DEBUG( 4, __FUNCTION__ "(), testing bit %d\n", 8-i);
- if ( self->qos_rx.compression.bits & mask) {
- DEBUG( 4, __FUNCTION__ "(), bit %d is set by defalt\n",
+ for (i=0;i<8;i++) {
+ DEBUG(4, __FUNCTION__ "(), testing bit %d\n", 8-i);
+ if (self->qos_rx.compression.bits & mask) {
+ DEBUG(4, __FUNCTION__ "(), bit %d is set by defalt\n",
X 8-i);
- comp = hashbin_find( irlap_compressors,
+ comp = hashbin_find(irlap_compressors,
X compression[ msb_index(mask)],
X NULL);
- if ( !comp) {
+ if (!comp) {
X /* Protocol not supported, so clear the bit */
- DEBUG( 4, __FUNCTION__ "(), Compression "
+ DEBUG(4, __FUNCTION__ "(), Compression "
X "protocol %d has not been loaded!\n",
X compression[msb_index(mask)]);
X self->qos_rx.compression.bits &= ~mask;
- DEBUG( 4, __FUNCTION__
+ DEBUG(4, __FUNCTION__
X "(), comp bits 0x%02x\n",
X self->qos_rx.compression.bits);
X }
@@ -931,20 +931,20 @@
X void irlap_init_qos_capabilities(struct irlap_cb *self,
X struct qos_info *qos_user)


X {
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);
- ASSERT( self->irdev != NULL, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
+ ASSERT(self->irdev != NULL, return;);
X
X /* Start out with the maximum QoS support possible */
- irda_init_max_qos_capabilies( &self->qos_rx);
+ irda_init_max_qos_capabilies(&self->qos_rx);
X
X #ifdef CONFIG_IRDA_COMPRESSION
- irlap_init_comp_qos_capabilities( self);
+ irlap_init_comp_qos_capabilities(self);
X #endif
X
X /* Apply drivers QoS capabilities */
- irda_qos_compute_intersection( &self->qos_rx,
- irda_device_get_qos( self->irdev));
+ irda_qos_compute_intersection(&self->qos_rx,
+ irda_device_get_qos(self->irdev));
X
X /*
X * Check for user supplied QoS parameters. The service user is only
@@ -952,17 +952,17 @@
X * user may not have set all of them.
X */
X if (qos_user) {
- DEBUG( 1, __FUNCTION__ "(), Found user specified QoS!\n");
+ DEBUG(1, __FUNCTION__ "(), Found user specified QoS!\n");
X
- if ( qos_user->baud_rate.bits)
+ if (qos_user->baud_rate.bits)
X self->qos_rx.baud_rate.bits &= qos_user->baud_rate.bits;
X
- if ( qos_user->max_turn_time.bits)
+ if (qos_user->max_turn_time.bits)
X self->qos_rx.max_turn_time.bits &= qos_user->max_turn_time.bits;
- if ( qos_user->data_size.bits)
+ if (qos_user->data_size.bits)
X self->qos_rx.data_size.bits &= qos_user->data_size.bits;
X
- if ( qos_user->link_disc_time.bits)
+ if (qos_user->link_disc_time.bits)
X self->qos_rx.link_disc_time.bits &= qos_user->link_disc_time.bits;
X #ifdef CONFIG_IRDA_COMPRESSION
X self->qos_rx.compression.bits &= qos_user->compression.bits;
@@ -984,7 +984,7 @@
X /* Set disconnect time */
X self->qos_rx.link_disc_time.bits &= 0x07;
X
- irda_qos_bits_to_value( &self->qos_rx);
+ irda_qos_bits_to_value(&self->qos_rx);
X }
X
X /*
@@ -993,14 +993,14 @@
X * Use the default connection and transmission parameters
X *
X */
-void irlap_apply_default_connection_parameters( struct irlap_cb *self)
+void irlap_apply_default_connection_parameters(struct irlap_cb *self)


X {
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
X
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
X
- irlap_change_speed( self, 9600);
+ irlap_change_speed(self, 9600);
X
X /* Default value in NDM */
X self->bofs_count = 11;
@@ -1028,12 +1028,12 @@
X void irlap_apply_connection_parameters(struct irlap_cb *self,
X struct qos_info *qos)

X {
- DEBUG( 4, __FUNCTION__ "()\n");
+ DEBUG(4, __FUNCTION__ "()\n");
X
- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LAP_MAGIC, return;);
X
- irlap_change_speed( self, qos->baud_rate.value);
+ irlap_change_speed(self, qos->baud_rate.value);
X
X self->window_size = qos->window_size.value;
X self->window = qos->window_size.value;
@@ -1045,7 +1045,7 @@
X */
X self->window_bytes = qos->baud_rate.value
X * qos->max_turn_time.value / 10000;
- DEBUG( 4, "Setting window_bytes = %d\n", self->window_bytes);
+ DEBUG(4, "Setting window_bytes = %d\n", self->window_bytes);
X
X /*
X * Set N1 to 0 if Link Disconnect/Threshold Time = 3 and set it to
@@ -1058,10 +1058,10 @@
X else
X self->N1 = 3000 / qos->max_turn_time.value;
X
- DEBUG( 4, "Setting N1 = %d\n", self->N1);
+ DEBUG(4, "Setting N1 = %d\n", self->N1);
X
X self->N2 = qos->link_disc_time.value * 1000 / qos->max_turn_time.value;
- DEBUG( 4, "Setting N2 = %d\n", self->N2);
+ DEBUG(4, "Setting N2 = %d\n", self->N2);
X
X /*
X * Initialize timeout values, some of the rules are listed on
@@ -1072,11 +1072,11 @@
X self->wd_timeout = self->poll_timeout * 2;
X
X #ifdef CONFIG_IRDA_COMPRESSION
- if ( qos->compression.value) {
- DEBUG( 1, __FUNCTION__ "(), Initializing compression\n");
- irda_set_compression( self, qos->compression.value);
+ if (qos->compression.value) {
+ DEBUG(1, __FUNCTION__ "(), Initializing compression\n");
+ irda_set_compression(self, qos->compression.value);
X
- irlap_compressor_init( self, 0);
+ irlap_compressor_init(self, 0);
X }
X #endif


X }
@@ -1088,7 +1088,7 @@

X * Give some info to the /proc file system
X *
X */
-int irlap_proc_read( char *buf, char **start, off_t offset, int len,
+int irlap_proc_read(char *buf, char **start, off_t offset, int len,
X int unused)
X {
X struct irlap_cb *self;
@@ -1100,81 +1100,81 @@
X
X len = 0;
X
- self = (struct irlap_cb *) hashbin_get_first( irlap);


- while ( self != NULL) {

- ASSERT( self != NULL, return -ENODEV;);
- ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
+ self = (struct irlap_cb *) hashbin_get_first(irlap);


+ while (self != NULL) {

+ ASSERT(self != NULL, return -ENODEV;);
+ ASSERT(self->magic == LAP_MAGIC, return -EBADR;);
X
- len += sprintf( buf+len, "irlap%d <-> %s ",
+ len += sprintf(buf+len, "irlap%d <-> %s ",
X i++, self->irdev->name);
- len += sprintf( buf+len, "state: %s\n",
+ len += sprintf(buf+len, "state: %s\n",
X irlap_state[ self->state]);
X
- len += sprintf( buf+len, " caddr: %#02x, ", self->caddr);
- len += sprintf( buf+len, "saddr: %#08x, ", self->saddr);
- len += sprintf( buf+len, "daddr: %#08x\n", self->daddr);
+ len += sprintf(buf+len, " caddr: %#02x, ", self->caddr);
+ len += sprintf(buf+len, "saddr: %#08x, ", self->saddr);
+ len += sprintf(buf+len, "daddr: %#08x\n", self->daddr);
X
- len += sprintf( buf+len, " win size: %d, ",
+ len += sprintf(buf+len, " win size: %d, ",
X self->window_size);
- len += sprintf( buf+len, "win: %d, ", self->window);
- len += sprintf( buf+len, "win bytes: %d, ", self->window_bytes);
- len += sprintf( buf+len, "bytes left: %d\n", self->bytes_left);
-
- len += sprintf( buf+len, " tx queue len: %d ",
- skb_queue_len( &self->tx_list));
- len += sprintf( buf+len, "win queue len: %d ",
- skb_queue_len( &self->wx_list));
- len += sprintf( buf+len, "rbusy: %s\n", self->remote_busy ?
+ len += sprintf(buf+len, "win: %d, ", self->window);
+ len += sprintf(buf+len, "win bytes: %d, ", self->window_bytes);
+ len += sprintf(buf+len, "bytes left: %d\n", self->bytes_left);
+
+ len += sprintf(buf+len, " tx queue len: %d ",
+ skb_queue_len(&self->tx_list));
+ len += sprintf(buf+len, "win queue len: %d ",
+ skb_queue_len(&self->wx_list));
+ len += sprintf(buf+len, "rbusy: %s\n", self->remote_busy ?
X "TRUE" : "FALSE");
X
- len += sprintf( buf+len, " retrans: %d ", self->retry_count);
- len += sprintf( buf+len, "vs: %d ", self->vs);
- len += sprintf( buf+len, "vr: %d ", self->vr);
- len += sprintf( buf+len, "va: %d\n", self->va);
+ len += sprintf(buf+len, " retrans: %d ", self->retry_count);
+ len += sprintf(buf+len, "vs: %d ", self->vs);
+ len += sprintf(buf+len, "vr: %d ", self->vr);
+ len += sprintf(buf+len, "va: %d\n", self->va);
X
- len += sprintf( buf+len, " qos\tbps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\tcomp\n");
+ len += sprintf(buf+len, " qos\tbps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\tcomp\n");
X
- len += sprintf( buf+len, " tx\t%d\t",
+ len += sprintf(buf+len, " tx\t%d\t",
X self->qos_tx.baud_rate.value);
- len += sprintf( buf+len, "%d\t",
+ len += sprintf(buf+len, "%d\t",
X self->qos_tx.max_turn_time.value);
- len += sprintf( buf+len, "%d\t",
+ len += sprintf(buf+len, "%d\t",
X self->qos_tx.data_size.value);
- len += sprintf( buf+len, "%d\t",
+ len += sprintf(buf+len, "%d\t",
X self->qos_tx.window_size.value);
- len += sprintf( buf+len, "%d\t",
+ len += sprintf(buf+len, "%d\t",
X self->qos_tx.additional_bofs.value);
- len += sprintf( buf+len, "%d\t",
+ len += sprintf(buf+len, "%d\t",
X self->qos_tx.min_turn_time.value);
- len += sprintf( buf+len, "%d\t",
+ len += sprintf(buf+len, "%d\t",
X self->qos_tx.link_disc_time.value);
X #ifdef CONFIG_IRDA_COMPRESSION
- len += sprintf( buf+len, "%d",
+ len += sprintf(buf+len, "%d",
X self->qos_tx.compression.value);
X #endif


- len += sprintf( buf+len, "\n");

+ len += sprintf(buf+len, "\n");
X
- len += sprintf( buf+len, " rx\t%d\t",
+ len += sprintf(buf+len, " rx\t%d\t",
X self->qos_rx.baud_rate.value);
- len += sprintf( buf+len, "%d\t",
+ len += sprintf(buf+len, "%d\t",
X self->qos_rx.max_turn_time.value);
- len += sprintf( buf+len, "%d\t",
+ len += sprintf(buf+len, "%d\t",
X self->qos_rx.data_size.value);
- len += sprintf( buf+len, "%d\t",
+ len += sprintf(buf+len, "%d\t",
X self->qos_rx.window_size.value);
- len += sprintf( buf+len, "%d\t",
+ len += sprintf(buf+len, "%d\t",
X self->qos_rx.additional_bofs.value);
- len += sprintf( buf+len, "%d\t",
+ len += sprintf(buf+len, "%d\t",
X self->qos_rx.min_turn_time.value);
- len += sprintf( buf+len, "%d\t",
+ len += sprintf(buf+len, "%d\t",
X self->qos_rx.link_disc_time.value);
X #ifdef CONFIG_IRDA_COMPRESSION
- len += sprintf( buf+len, "%d",
+ len += sprintf(buf+len, "%d",
X self->qos_rx.compression.value);
X #endif


- len += sprintf( buf+len, "\n");

+ len += sprintf(buf+len, "\n");
X

- self = (struct irlap_cb *) hashbin_get_next( irlap);
+ self = (struct irlap_cb *) hashbin_get_next(irlap);
X }
X restore_flags(flags);
X
diff -u --recursive --new-file v2.2.9/linux/net/irda/irlap_comp.c linux/net/irda/irlap_comp.c
--- v2.2.9/linux/net/irda/irlap_comp.c Wed Mar 10 15:29:52 1999
+++ linux/net/irda/irlap_comp.c Sun May 30 10:17:04 1999
@@ -6,11 +6,11 @@


X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Fri Oct 9 09:18:07 1998
- * Modified at: Mon Feb 8 01:23:52 1999
+ * Modified at: Sun May 9 11:37:06 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>

X * Sources: ppp.c, isdn_ppp.c
X *
- * Copyright (c) 1998 Dag Brattli, All Rights Reserved.
+ * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.


X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License as

@@ -255,11 +255,11 @@
X }
X
X /* FIXME: Find out what is the max overhead (not 10) */
- new_skb = dev_alloc_skb( skb->len+LAP_HEADER+10);
+ new_skb = dev_alloc_skb( skb->len+LAP_MAX_HEADER+10);
X if(!new_skb)
X return skb;
X
- skb_reserve( new_skb, LAP_HEADER);
+ skb_reserve( new_skb, LAP_MAX_HEADER);
X skb_put( new_skb, skb->len+10);
X
X count = (self->compressor.cp->compress)( self->compressor.state,
diff -u --recursive --new-file v2.2.9/linux/net/irda/irlap_event.c linux/net/irda/irlap_event.c
--- v2.2.9/linux/net/irda/irlap_event.c Wed Apr 28 11:37:32 1999
+++ linux/net/irda/irlap_event.c Mon Jun 7 16:19:59 1999


@@ -6,10 +6,10 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sat Aug 16 00:59:29 1997
- * Modified at: Fri Apr 23 11:55:12 1999
+ * Modified at: Mon May 31 21:55:42 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
- * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>,
+ * Copyright (c) 1998-1999 Dag Brattli <da...@cs.uit.no>,

X * Thomas Davis <rat...@radiks.net>


X * All Rights Reserved.
X *

@@ -209,8 +209,8 @@
X * Rushes through the state machine without any delay. If state == XMIT
X * then send queued data frames.
X */
-void irlap_do_event( struct irlap_cb *self, IRLAP_EVENT event,
- struct sk_buff *skb, struct irlap_info *info)
+void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event,
+ struct sk_buff *skb, struct irlap_info *info)
X {
X int ret;
X
@@ -218,7 +218,7 @@
X return;
X
X DEBUG(4, __FUNCTION__ "(), event = %s, state = %s\n",
- irlap_event[ event], irlap_state[ self->state]);
+ irlap_event[event], irlap_state[self->state]);
X
X ret = (*state[ self->state]) (self, event, skb, info);
X
@@ -236,13 +236,12 @@
X if (skb_queue_len(&self->tx_list)) {
X /* Try to send away all queued data frames */
X while ((skb = skb_dequeue(&self->tx_list)) != NULL) {
- ret = (*state[ self->state])(self, SEND_I_CMD,
- skb, NULL);
+ ret = (*state[self->state])(self, SEND_I_CMD,
+ skb, NULL);
X if ( ret == -EPROTO)
X break; /* Try again later! */
X }
X } else if (self->disconnect_pending) {
- DEBUG(0, __FUNCTION__ "(), disconnecting!\n");
X self->disconnect_pending = FALSE;
X
X ret = (*state[self->state])(self, DISCONNECT_REQUEST,
@@ -274,22 +273,22 @@
X * Switches state and provides debug information
X *
X */
-void irlap_next_state( struct irlap_cb *self, IRLAP_STATE state)
+void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state)
X {
- if ( !self || self->magic != LAP_MAGIC)
+ if (!self || self->magic != LAP_MAGIC)
X return;
X
- DEBUG( 4, "next LAP state = %s\n", irlap_state[ state]);
+ DEBUG(4, "next LAP state = %s\n", irlap_state[ state]);
X
X self->state = state;
X
X /*
X * If we are swithing away from a XMIT state then we are allowed to
X * transmit a maximum number of bytes again when we enter the XMIT
- * state again. Since its possible to "switch" from XMIT to XMIT and
+ * state again. Since its possible to "switch" from XMIT to XMIT,
X * we cannot do this when swithing into the XMIT state :-)
X */
- if (( state != LAP_XMIT_P) && ( state != LAP_XMIT_S))
+ if ((state != LAP_XMIT_P) && (state != LAP_XMIT_S))
X self->bytes_left = self->window_bytes;
X }
X
@@ -310,7 +309,7 @@
X ASSERT( self != NULL, return -1;);
X ASSERT( self->magic == LAP_MAGIC, return -1;);
X
- switch( event) {
+ switch(event) {
X case CONNECT_REQUEST:
X ASSERT( self->irdev != NULL, return -1;);
X
@@ -393,7 +392,6 @@
X irlap_start_query_timer( self, QUERY_TIMEOUT);
X irlap_next_state( self, LAP_REPLY);
X }
-
X dev_kfree_skb(skb);
X break;
X
@@ -530,7 +528,7 @@
X irlap_send_discovery_xid_frame(self, info->S,
X self->slot, FALSE,
X discovery_rsp);
-
+
X self->frame_sent = TRUE;
X irlap_next_state(self, LAP_REPLY);
X }
@@ -568,27 +566,28 @@
X
X switch (event) {
X case CONNECT_RESPONSE:
- skb_pull( skb, 11);
+ /* skb_pull(skb, 11); */
+ skb_pull(skb, sizeof(struct snrm_frame));
X
- ASSERT( self->irdev != NULL, return -1;);
- irda_qos_negotiate( &self->qos_rx, &self->qos_tx, skb);
+ ASSERT(self->irdev != NULL, return -1;);
+ irda_qos_negotiate(&self->qos_rx, &self->qos_tx, skb);
X
X irlap_initiate_connection_state( self);
X
X /*
X * We are allowed to send two frames!
X */
- irlap_send_ua_response_frame( self, &self->qos_rx);
- irlap_send_ua_response_frame( self, &self->qos_rx);
+ irlap_send_ua_response_frame(self, &self->qos_rx);
+ irlap_send_ua_response_frame(self, &self->qos_rx);
X
- irlap_apply_connection_parameters( self, &self->qos_tx);
+ irlap_apply_connection_parameters(self, &self->qos_tx);
X
X /*
X * The WD-timer could be set to the duration of the P-timer
- * for this case, but it is recommomended to use twice the
+ * for this case, but it is recommended to use twice the
X * value (note 3 IrLAP p. 60).
X */
- irlap_start_wd_timer( self, self->wd_timeout);
+ irlap_start_wd_timer(self, self->wd_timeout);
X irlap_next_state( self, LAP_NRM_S);
X break;
X
@@ -669,28 +668,30 @@
X * The device with the largest device address wins the battle
X * (both have sent a SNRM command!)
X */
- if ( info->daddr > self->saddr) {
- del_timer( &self->final_timer);
- irlap_initiate_connection_state( self);
+ if (info->daddr > self->saddr) {
+ del_timer(&self->final_timer);
+ irlap_initiate_connection_state(self);
X
- ASSERT( self->irdev != NULL, return -1;);
- irda_qos_negotiate( &self->qos_rx, &self->qos_tx, skb);
+ ASSERT(self->irdev != NULL, return -1;);
+ /* skb_pull(skb, 11); */
+ skb_pull(skb, sizeof(struct snrm_frame));
+ irda_qos_negotiate(&self->qos_rx, &self->qos_tx, skb);
X
X irlap_send_ua_response_frame(self, &self->qos_rx);
- irlap_apply_connection_parameters( self, &self->qos_tx);
- irlap_connect_confirm( self, skb);
+ irlap_apply_connection_parameters(self, &self->qos_tx);
+ irlap_connect_confirm(self, skb);
X
X /*
X * The WD-timer could be set to the duration of the
- * P-timer for this case, but it is recommomended
+ * P-timer for this case, but it is recommended
X * to use twice the value (note 3 IrLAP p. 60).
X */
- irlap_start_wd_timer( self, self->wd_timeout);
+ irlap_start_wd_timer(self, self->wd_timeout);
X
- irlap_next_state( self, LAP_NRM_S);
+ irlap_next_state(self, LAP_NRM_S);
X } else {
X /* We just ignore the other device! */
- irlap_next_state( self, LAP_SETUP);
+ irlap_next_state(self, LAP_SETUP);
X }
X break;
X case RECV_UA_RSP:
@@ -702,9 +703,10 @@
X
X /* Negotiate connection parameters */
X ASSERT( skb->len > 10, return -1;);
- skb_pull( skb, 10);
+ /* skb_pull(skb, 10); */
+ skb_pull(skb, sizeof(struct ua_frame));
X
- ASSERT( self->irdev != NULL, return -1;);
+ ASSERT(self->irdev != NULL, return -1;);
X irda_qos_negotiate( &self->qos_rx, &self->qos_tx, skb);
X
X irlap_apply_connection_parameters( self, &self->qos_tx);
@@ -758,36 +760,30 @@
X * stations.
X *
X */
-static int irlap_state_xmit_p( struct irlap_cb *self, IRLAP_EVENT event,
- struct sk_buff *skb, struct irlap_info *info)
+static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event,
+ struct sk_buff *skb, struct irlap_info *info)
X {
X int ret = 0;
X
- ASSERT( self != NULL, return -ENODEV;);
- ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
-
- DEBUG( 4, __FUNCTION__ "(), event=%s, vs=%d, vr=%d",
- irlap_event[ event], self->vs, self->vr);
+ DEBUG(4, __FUNCTION__ "(), event=%s, vs=%d, vr=%d",
+ irlap_event[event], self->vs, self->vr);
X
X switch (event) {
X case SEND_I_CMD:
- ASSERT( skb != NULL, return -1;);
- DEBUG( 4, __FUNCTION__ "(), Window=%d\n", self->window);
-
X /*
X * Only send frame if send-window > 0.
X */
- if (( self->window > 0) && ( !self->remote_busy)) {
+ if ((self->window > 0) && (!self->remote_busy)) {
X
X /*
X * Test if we have transmitted more bytes over the
X * link than its possible to do with the current
X * speed and turn-around-time.
X */
- if (( skb->len+self->bofs_count) > self->bytes_left) {
- DEBUG( 4, __FUNCTION__ "(), Not allowed to "
- "transmit more bytes!\n");
- skb_queue_head( &self->tx_list, skb);
+ if ((skb->len+self->bofs_count) > self->bytes_left) {
+ DEBUG(4, __FUNCTION__ "(), Not allowed to "
+ "transmit more bytes!\n");
+ skb_queue_head(&self->tx_list, skb);
X
X /*
X * We should switch state to LAP_NRM_P, but
@@ -799,7 +795,7 @@
X */
X return -EPROTO;
X }
- self->bytes_left -= ( skb->len + self->bofs_count);
+ self->bytes_left -= (skb->len + self->bofs_count);
X
X /*
X * Send data with poll bit cleared only if window > 1
@@ -808,11 +804,9 @@
X if (( self->window > 1) &&
X skb_queue_len( &self->tx_list) > 0)
X {
- DEBUG( 4, __FUNCTION__ "(), window > 1\n");
X irlap_send_data_primary( self, skb);
X irlap_next_state( self, LAP_XMIT_P);
X } else {
- DEBUG( 4, __FUNCTION__ "(), window <= 1\n");
X irlap_send_data_primary_poll( self, skb);
X irlap_next_state( self, LAP_NRM_P);
X
@@ -930,9 +924,6 @@
X int ns_status;
X int nr_status;
X
- ASSERT(self != NULL, return -1;);
- ASSERT(self->magic == LAP_MAGIC, return -1;);
-
X switch (event) {
X case RECV_I_RSP: /* Optimize for the common case */
X /* FIXME: must check for remote_busy below */
@@ -944,7 +935,6 @@
X */
X self->fast_RR = FALSE;
X #endif
-
X ASSERT( info != NULL, return -1;);
X
X ns_status = irlap_validate_ns_received(self, info->ns);
@@ -1138,13 +1128,6 @@
X }
X break;
X case RECV_RR_RSP:
- DEBUG(4, __FUNCTION__ "(), RECV_RR_FRAME: "
- "Retrans:%d, nr=%d, va=%d, vs=%d, vr=%d\n",
- self->retry_count, info->nr, self->va, self->vs,
- self->vr);
-
- ASSERT(info != NULL, return -1;);
-
X /*
X * If you get a RR, the remote isn't busy anymore,
X * no matter what the NR
@@ -1191,14 +1174,6 @@
X /* Resend rejected frames */
X irlap_resend_rejected_frames( self, CMD_FRAME);
X
- /*
- * Start only if not running, DB
- * TODO: Should this one be here?
- */
- /* if ( !self->final_timer.prev) */
-/* irda_start_timer( FINAL_TIMER, self->final_timeout); */
-
- /* Keep state */
X irlap_next_state( self, LAP_NRM_P);
X } else if (ret == NR_INVALID) {
X DEBUG(1, "irlap_state_nrm_p: received RR with "
@@ -1207,8 +1182,7 @@
X
X irlap_next_state( self, LAP_RESET_WAIT);
X
- irlap_disconnect_indication( self,
- LAP_RESET_INDICATION);
+ irlap_disconnect_indication(self, LAP_RESET_INDICATION);
X self->xmitflag = TRUE;
X }
X if (skb)
@@ -1476,13 +1450,13 @@
X /*
X * Send frame only if send window > 1
X */
- if (( self->window > 0) && ( !self->remote_busy)) {
+ if ((self->window > 0) && ( !self->remote_busy)) {
X /*
X * Test if we have transmitted more bytes over the
X * link than its possible to do with the current
X * speed and turn-around-time.
X */
- if (( skb->len+self->bofs_count) > self->bytes_left) {
+ if ((skb->len+self->bofs_count) > self->bytes_left) {
X DEBUG( 4, "IrDA: Not allowed to transmit more bytes!\n");
X skb_queue_head( &self->tx_list, skb);
X /*
@@ -1504,11 +1478,9 @@
X if (( self->window > 1) &&
X skb_queue_len( &self->tx_list) > 0)
X {
- DEBUG( 4, __FUNCTION__ "(), window > 1\n");
X irlap_send_data_secondary( self, skb);
X irlap_next_state( self, LAP_XMIT_S);
X } else {
- DEBUG( 4, "(), window <= 1\n");
X irlap_send_data_secondary_final( self, skb);
X irlap_next_state( self, LAP_NRM_S);
X
@@ -1570,7 +1542,7 @@
X /*
X * poll bit cleared?
X */
- if ( !info->pf) {
+ if (!info->pf) {
X self->vr = (self->vr + 1) % 8;
X
X /* Update Nr received */
@@ -1600,35 +1572,39 @@
X * also before changing to XMIT_S
X * state. (note 1, IrLAP p. 82)
X */
- irlap_wait_min_turn_around( self, &self->qos_tx);
- /*
- * Any pending data requests?
+ irlap_wait_min_turn_around(self, &self->qos_tx);
+
+ /*
+ * Give higher layers a chance to
+ * immediately reply with some data before
+ * we decide if we should send a RR frame
+ * or not
X */
- if (( skb_queue_len( &self->tx_list) > 0) &&
- ( self->window > 0))
+ irlap_data_indication(self, skb);
+
+ /* Any pending data requests? */
+ if ((skb_queue_len(&self->tx_list) > 0) &&
+ (self->window > 0))
X {
X self->ack_required = TRUE;
X
- del_timer( &self->wd_timer);
+ del_timer(&self->wd_timer);
X
- irlap_next_state( self, LAP_XMIT_S);
+ irlap_next_state(self, LAP_XMIT_S);
X } else {
- irlap_send_rr_frame( self, RSP_FRAME);
- irlap_start_wd_timer( self, self->wd_timeout);
+ irlap_send_rr_frame(self, RSP_FRAME);
+ irlap_start_wd_timer(self, self->wd_timeout);
X
X /* Keep the state */
- irlap_next_state( self, LAP_NRM_S);
+ irlap_next_state(self, LAP_NRM_S);
X }
- irlap_data_indication( self, skb);
-
X break;
X }
X }
X /*
X * Check for Unexpected next to send (Ns)
X */
- if (( ns_status == NS_UNEXPECTED) &&
- ( nr_status == NR_EXPECTED))
+ if ((ns_status == NS_UNEXPECTED) && (nr_status == NR_EXPECTED))
X {
X /* Unexpected next to send, with final bit cleared */
X if ( !info->pf) {
@@ -1651,8 +1627,7 @@
X /*
X * Unexpected Next to Receive(NR) ?
X */
- if (( ns_status == NS_EXPECTED) &&
- ( nr_status == NR_UNEXPECTED))
+ if ((ns_status == NS_EXPECTED) && (nr_status == NR_UNEXPECTED))
X {
X if ( info->pf) {
X DEBUG( 4, "RECV_I_RSP: frame(s) lost\n");
@@ -1748,20 +1723,20 @@
X irlap_update_nr_received( self, info->nr);
X del_timer( &self->wd_timer);
X
- irlap_wait_min_turn_around( self, &self->qos_tx);
+ irlap_wait_min_turn_around(self, &self->qos_tx);
X irlap_next_state( self, LAP_XMIT_S);
X } else {
X self->remote_busy = FALSE;
X /* Update Nr received */
- irlap_update_nr_received( self, info->nr);
- irlap_wait_min_turn_around( self, &self->qos_tx);
+ irlap_update_nr_received(self, info->nr);
+ irlap_wait_min_turn_around(self, &self->qos_tx);
X
- irlap_send_rr_frame( self, RSP_FRAME);
+ irlap_send_rr_frame(self, RSP_FRAME);
X
- irlap_start_wd_timer( self, self->wd_timeout);
- irlap_next_state( self, LAP_NRM_S);
+ irlap_start_wd_timer(self, self->wd_timeout);
+ irlap_next_state(self, LAP_NRM_S);
X }
- } else if ( nr_status == NR_UNEXPECTED) {
+ } else if (nr_status == NR_UNEXPECTED) {
X self->remote_busy = FALSE;
X irlap_update_nr_received( self, info->nr);
X irlap_resend_rejected_frames( self, RSP_FRAME);
@@ -1773,8 +1748,8 @@
X } else {
X DEBUG(1, __FUNCTION__ "(), invalid nr not implemented!\n");
X }
- if ( skb)
- dev_kfree_skb( skb);
+ if (skb)
+ dev_kfree_skb(skb);
X
X break;
X case RECV_SNRM_CMD:
@@ -1886,7 +1861,7 @@
X ASSERT( self != NULL, return -ENODEV;);
X ASSERT( self->magic == LAP_MAGIC, return -EBADR;);
X
- switch( event) {
+ switch(event) {
X case RESET_RESPONSE:
X irlap_send_ua_response_frame( self, &self->qos_rx);
X irlap_initiate_connection_state( self);
diff -u --recursive --new-file v2.2.9/linux/net/irda/irlap_frame.c linux/net/irda/irlap_frame.c
--- v2.2.9/linux/net/irda/irlap_frame.c Wed Apr 28 11:37:32 1999
+++ linux/net/irda/irlap_frame.c Mon Jun 7 16:19:59 1999


@@ -6,10 +6,10 @@
X * Status: Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Tue Aug 19 10:27:26 1997
- * Modified at: Fri Apr 23 09:30:42 1999
+ * Modified at: Mon May 31 09:29:13 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *

- * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Resrved.
+ * Copyright (c) 1998-1999 Dag Brattli <da...@cs.uit.no>, All Rights Resrved.


X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License as

@@ -1001,10 +1001,6 @@


X {
X __u8 *frame;
X

- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LAP_MAGIC, return;);


- ASSERT( skb != NULL, return;);

-


X frame = skb->data;
X

X /* Insert connection address */
@@ -1014,15 +1010,6 @@
X /* Insert next to receive (Vr) */
X frame[1] |= (self->vr << 5); /* insert nr */
X
-#if 0
- {
- int ns;
- ns = (frame[1] >> 1) & 0x07; /* Next to send */
-
- DEBUG(0, __FUNCTION__ "(), ns=%d\n", ns);
- }
-#endif
-
X irlap_queue_xmit(self, skb);
X }
X
@@ -1056,8 +1043,8 @@
X * Receive and parse an Unnumbered Information (UI) frame
X *
X */
-static void irlap_recv_ui_frame( struct irlap_cb *self, struct sk_buff *skb,
- struct irlap_info *info)
+static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
+ struct irlap_info *info)


X {
X __u8 *frame;
X

@@ -1240,7 +1227,7 @@
X * Optimize for the common case and check if the frame is an
X * I(nformation) frame. Only I-frames have bit 0 set to 0
X */
- if(~control & 0x01) {
+ if (~control & 0x01) {
X irlap_recv_i_frame(self, skb, &info, command);
X self->stats.rx_packets++;
X return 0;
@@ -1254,7 +1241,7 @@
X * Received S(upervisory) frame, check which frame type it is
X * only the first nibble is of interest
X */
- switch(control & 0x0f) {
+ switch (control & 0x0f) {
X case RR:
X irlap_recv_rr_frame( self, skb, &info, command);
X self->stats.rx_packets++;
@@ -1279,7 +1266,7 @@
X /*
X * This must be a C(ontrol) frame
X */
- switch(control) {
+ switch (control) {
X case XID_RSP:
X irlap_recv_discovery_xid_rsp(self, skb, &info);
X break;
diff -u --recursive --new-file v2.2.9/linux/net/irda/irlmp.c linux/net/irda/irlmp.c
--- v2.2.9/linux/net/irda/irlmp.c Wed Apr 28 11:37:32 1999
+++ linux/net/irda/irlmp.c Mon Jun 7 16:19:59 1999
@@ -6,10 +6,10 @@
X * Status: Stable.


X * Author: Dag Brattli <da...@cs.uit.no>

X * Created at: Sun Aug 17 20:54:32 1997
- * Modified at: Fri Apr 23 09:13:24 1999
+ * Modified at: Mon May 31 21:49:41 1999


X * Modified by: Dag Brattli <da...@cs.uit.no>
X *
- * Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>,
+ * Copyright (c) 1998-1999 Dag Brattli <da...@cs.uit.no>,
X * All Rights Reserved.
X *
X * This program is free software; you can redistribute it and/or

@@ -197,7 +197,7 @@
X }
X
X /*
- * Function irlmp_close_lsap (self)
+ * Function __irlmp_close_lsap (self)
X *
X * Remove an instance of LSAP
X */
@@ -369,11 +369,11 @@
X if (!skb)
X return -ENOMEM;
X
- skb_reserve(skb, LMP_CONTROL_HEADER+LAP_HEADER);
+ skb_reserve(skb, LMP_MAX_HEADER);


X } else
X skb = userdata;
X

- /* Make room for MUX control header ( 3 bytes) */
+ /* Make room for MUX control header (3 bytes) */
X ASSERT(skb_headroom(skb) >= LMP_CONTROL_HEADER, return -1;);
X skb_push(skb, LMP_CONTROL_HEADER);
X
@@ -443,25 +443,35 @@
X void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb)
X {
X int max_seg_size;
-
- DEBUG(3, __FUNCTION__ "()\n");
+ int lap_header_size;
+ int max_header_size;
X
X ASSERT(self != NULL, return;);
X ASSERT(self->magic == LMP_LSAP_MAGIC, return;);


X ASSERT(skb != NULL, return;);

X ASSERT(self->lap != NULL, return;);
X
+ DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n",

+ self->slsap_sel, self->dlsap_sel);
+

X self->qos = *self->lap->qos;
X
- max_seg_size = self->lap->qos->data_size.value;
- DEBUG(4, __FUNCTION__ "(), max_seg_size=%d\n", max_seg_size);
+ max_seg_size = self->lap->qos->data_size.value-LMP_HEADER;
+ DEBUG(2, __FUNCTION__ "(), max_seg_size=%d\n", max_seg_size);
X
+ lap_header_size = irlap_get_header_size(self->lap->irlap);
+
+ max_header_size = LMP_HEADER + lap_header_size;
+
+ DEBUG(2, __FUNCTION__ "(), max_header_size=%d\n", max_header_size);
+
X /* Hide LMP_CONTROL_HEADER header from layer above */
X skb_pull(skb, LMP_CONTROL_HEADER);
X

X if (self->notify.connect_indication)
X self->notify.connect_indication(self->notify.instance, self,

- &self->qos, max_seg_size, skb);
+ &self->qos, max_seg_size,
+ max_header_size, skb);
X }
X
X /*
@@ -470,24 +480,22 @@
X * Service user is accepting connection
X *
X */
-void irlmp_connect_response( struct lsap_cb *self, struct sk_buff *userdata)
+void irlmp_connect_response(struct lsap_cb *self, struct sk_buff *userdata)
X {
- DEBUG(3, __FUNCTION__ "()\n");
-

- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LMP_LSAP_MAGIC, return;);
- ASSERT( userdata != NULL, return;);


+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
+ ASSERT(userdata != NULL, return;);
X

X self->connected = TRUE;
X

- DEBUG( 4, "irlmp_connect_response: slsap_sel=%02x, dlsap_sel=%02x\n",

- self->slsap_sel, self->dlsap_sel);

+ DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n",

+ self->slsap_sel, self->dlsap_sel);

X
X /* Make room for MUX control header ( 3 bytes) */
- ASSERT( skb_headroom( userdata) >= LMP_CONTROL_HEADER, return;);
- skb_push( userdata, LMP_CONTROL_HEADER);
+ ASSERT(skb_headroom(userdata) >= LMP_CONTROL_HEADER, return;);
+ skb_push(userdata, LMP_CONTROL_HEADER);
X
- irlmp_do_lsap_event( self, LM_CONNECT_RESPONSE, userdata);
+ irlmp_do_lsap_event(self, LM_CONNECT_RESPONSE, userdata);
X }
X
X /*
@@ -498,25 +506,34 @@
X void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb)
X {
X int max_seg_size;
+ int max_header_size;
+ int lap_header_size;
X
X DEBUG(3, __FUNCTION__ "()\n");
X

- ASSERT( skb != NULL, return;);

- ASSERT( self != NULL, return;);

- ASSERT( self->magic == LMP_LSAP_MAGIC, return;);


+ ASSERT(skb != NULL, return;);
+ ASSERT(self != NULL, return;);

+ ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
X
- ASSERT( self->lap != NULL, return;);
+ ASSERT(self->lap != NULL, return;);
X self->qos = *self->lap->qos;
X
- max_seg_size = self->qos.data_size.value;
- DEBUG( 4, __FUNCTION__ "(), max_seg_size=%d\n", max_seg_size);
+ max_seg_size = self->lap->qos->data_size.value-LMP_HEADER;
+ DEBUG(2, __FUNCTION__ "(), max_seg_size=%d\n", max_seg_size);
+
+ lap_header_size = irlap_get_header_size(self->lap->irlap);
X
+ max_header_size = LMP_HEADER + lap_header_size;
+
+ DEBUG(2, __FUNCTION__ "(), max_header_size=%d\n", max_header_size);
+
X /* Hide LMP_CONTROL_HEADER header from layer above */
- skb_pull( skb, LMP_CONTROL_HEADER);
+ skb_pull(skb, LMP_CONTROL_HEADER);
X
- if ( self->notify.connect_confirm) {
- self->notify.connect_confirm( self->notify.instance, self,
- &self->qos, max_seg_size, skb);
+ if (self->notify.connect_confirm) {


+ self->notify.connect_confirm(self->notify.instance, self,

+ &self->qos, max_seg_size,
+ max_header_size, skb);
X }
X }
X
@@ -620,8 +637,8 @@
X *
X * LSAP is being closed!
X */
-void irlmp_disconnect_indication( struct lsap_cb *self, LM_REASON reason,
- struct sk_buff *userdata)
+void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason,
+ struct sk_buff *userdata)
X {
X struct lsap_cb *lsap;
X
@@ -637,6 +654,10 @@
X self->connected = FALSE;
X self->dlsap_sel = LSAP_ANY;
X
+#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
+ irlmp->cache.valid = FALSE;
+#endif
+
X /*
X * Remove association between this LSAP and the link it used
X */
@@ -975,7 +996,7 @@
X DEBUG( 1, "irlmp_status_request(), Not implemented\n");
X }
X
-void irlmp_status_indication( LINK_STATUS link, LOCK_STATUS lock)
+void irlmp_status_indication(LINK_STATUS link, LOCK_STATUS lock)
X {
X DEBUG( 4, "irlmp_status_indication(), Not implemented\n");
X }
@@ -1418,14 +1439,14 @@
X * Give some info to the /proc file system
X *
X */
-int irlmp_proc_read( char *buf, char **start, off_t offset, int len,
- int unused)
+int irlmp_proc_read(char *buf, char **start, off_t offset, int len,
+ int unused)
X {
X struct lsap_cb *self;
X struct lap_cb *lap;


X unsigned long flags;
X

- ASSERT( irlmp != NULL, return 0;);
+ ASSERT(irlmp != NULL, return 0;);
X
X save_flags( flags);
X cli();
@@ -1449,35 +1470,34 @@
X }
X
X len += sprintf( buf+len, "\nRegistred Link Layers:\n");
- lap = (struct lap_cb *) hashbin_get_first( irlmp->links);
- while ( lap != NULL) {
- ASSERT( lap->magic == LMP_LAP_MAGIC, return 0;);
X
- len += sprintf( buf+len, "lap state: %s, ",
- irlmp_state[ lap->lap_state]);
+ lap = (struct lap_cb *) hashbin_get_first(irlmp->links);
+ while (lap != NULL) {
+ len += sprintf(buf+len, "lap state: %s, ",
+ irlmp_state[lap->lap_state]);


SHAR_EOF
true || echo 'restore of patch-2.2.10 failed'

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

0 new messages