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

6 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,
+