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

Linux Kernel Patch v2.1, patch-2.2.0-pre5 (00/13)

5 views
Skip to first unread message

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

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to
Archive-name: v2.1/patch-2.2.0-pre5/part00

lines added deleted
linux/CREDITS : 10 2 2
linux/Documentation/Configure.help : 141 54 42
linux/Documentation/ide.txt : 138 25 26
linux/Documentation/kernel-docs.txt : 8 1 1
linux/Documentation/networking/ip-sysctl.txt : 5 1 1
linux/Documentation/oops-tracing.txt : 12 3 3
linux/Documentation/sound/AWE32 : 111 25 36
linux/Documentation/sound/OPL3-SA2 : 99 37 19
linux/MAINTAINERS : 12 3 3
linux/Makefile : 8 1 1
linux/arch/i386/config.in : 10 2 2
linux/arch/i386/kernel/ptrace.c : 42 29 0
linux/arch/i386/kernel/smp.c : 12 2 2
linux/arch/m68k/Makefile : 8 1 1
linux/arch/m68k/config.in : 10 2 2
linux/arch/m68k/kernel/m68k_defs.h : 9 3 3
linux/arch/m68k/kernel/m68k_ksyms.c : 8 2 0
linux/arch/m68k/kernel/process.c : 7 1 0
linux/arch/m68k/kernel/ptrace.c : 19 4 0
linux/arch/m68k/mac/config.c : 19 3 3
linux/arch/m68k/mac/debug.c : 18 4 0
linux/arch/m68k/mac/macboing.c : 393 262 99
linux/arch/m68k/mac/macints.c : 316 132 41
linux/arch/m68k/vmlinux.lds : 9 3 0
linux/arch/mips/kernel/traps.c : 163 72 47
linux/arch/ppc/common_defconfig : 209 63 28
linux/arch/ppc/defconfig : 27 5 2
linux/arch/ppc/kernel/process.c : 19 13 0
linux/arch/ppc/kernel/traps.c : 23 3 0
linux/arch/ppc/mm/fault.c : 15 2 0
linux/arch/ppc/pmac_defconfig : 27 5 2
linux/drivers/block/cmd640.c : 13 3 3
linux/drivers/block/genhd.c : 21 7 1
linux/drivers/block/ide-disk.c : 34 12 6
linux/drivers/block/ide-probe.c : 26 10 3
linux/drivers/block/ide-tape.c : 8 1 1
linux/drivers/block/ide.c : 12 4 2
linux/drivers/block/opti621.c : 148 58 27
linux/drivers/block/rz1000.c : 10 3 1
linux/drivers/cdrom/cdrom.c : 11 3 1
linux/drivers/char/cyclades.c : 52 0 13
linux/drivers/char/mem.c : 61 35 12
linux/drivers/char/serial.c : 17 11 0
linux/drivers/isdn/hisax/config.c : 10 2 0
linux/drivers/net/acenic_firmware.h : 8 1 1
linux/drivers/net/plip.c : 33 3 5
linux/drivers/net/sdla_fr.c : 26 6 0
linux/drivers/net/sdla_ppp.c : 15 2 0
linux/drivers/net/sdla_x25.c : 15 2 0
linux/drivers/net/tulip.c : 7 0 1
linux/drivers/pci/oldproc.c : 7 1 0
linux/drivers/scsi/README.aic7xxx : 113 45 20
linux/drivers/scsi/aic7xxx.c : 542 142 115
linux/drivers/scsi/aic7xxx_proc.c : 191 71 79
linux/drivers/scsi/scsi.c : 7 1 0
linux/drivers/sound/Config.in : 7 1 0
linux/drivers/sound/Makefile : 18 2 3
linux/drivers/sound/ad1848.c : 14 4 3
linux/drivers/sound/dev_table.c : 26 3 3
linux/drivers/sound/dmasound.c : 17 2 2
linux/drivers/sound/es1370.c : 17 4 4
linux/drivers/sound/es1371.c : 17 4 4
linux/drivers/sound/msnd_pinnacle.c : 17 2 2
linux/drivers/sound/opl3sa.c : 7 1 0
linux/drivers/sound/opl3sa2.c : 378 181 48
linux/drivers/sound/pas2_card.c : 60 15 5
linux/drivers/sound/pas2_midi.c : 280 74 84
linux/drivers/sound/sb.h : 17 4 0
linux/drivers/sound/sb_audio.c : 20 5 2
linux/drivers/sound/sb_common.c : 124 60 10
linux/drivers/sound/sb_mixer.c : 504 400 23
linux/drivers/sound/sb_mixer.h : 288 10 245
linux/drivers/sound/sonicvibes.c : 14 3 3
linux/drivers/sound/sound_calls.h : 7 2 2
linux/drivers/sound/sound_core.c : 198 83 41
linux/drivers/sound/sound_firmware.c : 4 0 1
linux/drivers/sound/sound_syms.c : 14 2 1
linux/drivers/sound/wavfront.c : 4103 1286 1297
linux/drivers/sound/wf_midi.c : 939 294 346
linux/drivers/video/atyfb.c : 7 1 0
linux/drivers/video/chipsfb.c : 269 71 56
linux/drivers/video/matroxfb.c : 20 3 3
linux/drivers/video/offb.c : 130 39 26
linux/fs/Config.in : 37 9 1
linux/fs/buffer.c : 45 3 8
linux/fs/dcache.c : 60 3 30
linux/fs/fat/inode.c : 59 15 15
linux/fs/inode.c : 22 2 6
linux/fs/lockd/clntlock.c : 13 1 6
linux/fs/nfs/inode.c : 8 1 1
linux/fs/ntfs/ntfsendian.h : 8 1 1
linux/fs/proc/array.c : 7 1 0
linux/fs/qnx4/symlinks.c : 17 2 2
linux/fs/ufs/acl.c : 14 6 3
linux/fs/ufs/namei.c : 268 84 77
linux/fs/ufs/super.c : 19 3 3
linux/fs/vfat/namei.c : 11 3 1
linux/include/asm-m68k/init.h : 17 4 0
linux/include/asm-m68k/resource.h : 8 1 1
linux/include/asm-m68k/softirq.h : 23 3 3
linux/include/asm-m68k/timex.h : 11 7 0
linux/include/asm-m68k/uaccess.h : 8 1 1
linux/include/linux/inetdevice.h : 8 0 2
linux/include/linux/ip_masq.h : 55 9 6
linux/include/linux/mm.h : 48 15 8
linux/include/linux/ntfs_fs_i.h : 22 9 5
linux/include/linux/pci.h : 7 1 0
linux/include/linux/sched.h : 8 2 0
linux/include/linux/sound.h : 16 5 5
linux/include/linux/swap.h : 12 0 5
linux/include/linux/sysctl.h : 9 2 1
linux/include/linux/wavefront.h : 41 11 2
linux/include/net/ipconfig.h : 19 5 3
linux/ipc/util.c : 8 0 2
linux/kernel/ksyms.c : 26 4 0
linux/kernel/sched.c : 134 62 39
linux/kernel/sysctl.c : 20 7 0
linux/mm/filemap.c : 69 25 10
linux/mm/memory.c : 67 30 20
linux/mm/page_alloc.c : 31 16 2
linux/mm/vmscan.c : 535 135 300
linux/net/TUNABLE : 8 1 1
linux/net/appletalk/ddp.c : 8 1 1
linux/net/ax25/af_ax25.c : 8 1 1
linux/net/bridge/br.c : 8 1 1
linux/net/ipv4/Config.in : 7 1 0
linux/net/ipv4/Makefile : 14 8 0
linux/net/ipv4/af_inet.c : 29 5 4
linux/net/ipv4/devinet.c : 62 4 38
linux/net/ipv4/fib_frontend.c : 24 3 3
linux/net/ipv4/icmp.c : 8 1 1
linux/net/ipv4/igmp.c : 25 3 2
linux/net/ipv4/ip_fw.c : 23 7 3
linux/net/ipv4/ip_masq.c : 237 84 21
linux/net/ipv4/ip_masq_mfw.c : 776 776 0
linux/net/ipv4/ip_masq_portfw.c : 35 12 9
linux/net/ipv4/ip_output.c : 17 2 2
linux/net/ipv4/ipconfig.c : 937 217 327
linux/net/ipv4/route.c : 19 1 5
linux/net/ipv4/sysctl_net_ipv4.c : 29 8 1
linux/net/ipv4/tcp_input.c : 26 3 3
linux/net/ipv4/tcp_ipv4.c : 32 10 9
linux/net/ipv6/af_inet6.c : 17 2 2
linux/net/ipx/af_ipx.c : 8 1 1
linux/net/ipx/af_spx.c : 8 1 1
linux/net/lapb/lapb_iface.c : 8 1 1
linux/net/socket.c : 9 2 1
linux/net/unix/af_unix.c : 17 2 2
linux/scripts/ksymoops/Makefile : 79 79 0
linux/scripts/ksymoops/README : 395 395 0
linux/scripts/ksymoops/io.c : 139 139 0
linux/scripts/ksymoops/ksymoops.c : 678 678 0
linux/scripts/ksymoops/ksymoops.h : 146 146 0
linux/scripts/ksymoops/ksyms.c : 294 294 0
linux/scripts/ksymoops/map.c : 251 251 0
linux/scripts/ksymoops/misc.c : 108 108 0
linux/scripts/ksymoops/object.c : 230 230 0
linux/scripts/ksymoops/oops.c : 1200 1200 0
linux/scripts/ksymoops/re.c : 145 145 0
linux/scripts/ksymoops/symbol.c : 444 444 0
linux/scripts/ksymoops-0.6/Makefile : 72 0 72
linux/scripts/ksymoops-0.6/README : 358 0 358
linux/scripts/ksymoops-0.6/io.c : 139 0 139
linux/scripts/ksymoops-0.6/ksymoops.c : 569 0 569
linux/scripts/ksymoops-0.6/ksymoops.h : 145 0 145
linux/scripts/ksymoops-0.6/ksyms.c : 287 0 287
linux/scripts/ksymoops-0.6/map.c : 251 0 251
linux/scripts/ksymoops-0.6/misc.c : 108 0 108
linux/scripts/ksymoops-0.6/object.c : 230 0 230
linux/scripts/ksymoops-0.6/oops.c : 1061 0 1061
linux/scripts/ksymoops-0.6/patches/README : 15 0 15
linux/scripts/ksymoops-0.6/patches/mips : 167 0 167
linux/scripts/ksymoops-0.6/patches/ppc : 67 0 67
linux/scripts/ksymoops-0.6/re.c : 145 0 145
linux/scripts/ksymoops-0.6/symbol.c : 440 0 440
linux/scripts/tkgen.c : 12 2 2
--
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,
Jan 7, 1999, 3:00:00 AM1/7/99
to
Archive-name: v2.1/patch-2.2.0-pre5/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 13 - 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.0-pre5 ==============
if test -f 'patch-2.2.0-pre5' -a X"$1" != X"-c"; then
echo 'x - skipping patch-2.2.0-pre5 (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting patch-2.2.0-pre5 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'patch-2.2.0-pre5' &&
diff -u --recursive --new-file v2.2.0-pre4/linux/CREDITS linux/CREDITS
--- v2.2.0-pre4/linux/CREDITS Thu Dec 31 10:28:58 1998
+++ linux/CREDITS Mon Jan 4 15:07:27 1999
@@ -1150,8 +1150,8 @@
X
X N: Mark Lord
X E: ml...@pobox.com
-D: Author of IDE driver (ide.c), hd.c support
-D: Triton Bus Master IDE driver
+D: EIDE driver, hd.c support
+D: EIDE PCI and bus-master DMA support
X D: Hard Disk Parameter (hdparm) utility
X S: 33 Ridgefield Cr
X S: Nepean, Ontario
diff -u --recursive --new-file v2.2.0-pre4/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.2.0-pre4/linux/Documentation/Configure.help Mon Jan 4 15:08:16 1999
+++ linux/Documentation/Configure.help Mon Jan 4 12:57:44 1999
@@ -3604,17 +3604,25 @@
X Adaptec AIC7xxx chipset SCSI controller support
X CONFIG_SCSI_AIC7XXX
X This is support for the various aic7xxx based Adaptec SCSI
- controllers. These include the 274x EISA cards, 284x VLB cards, 294x
- PCI cards, 394x PCI cards, 3985 PCI card, and several versions of
- the Adaptec built-in SCSI controllers on various PC motherboards.
+ controllers. These include the 274x EISA cards; 284x VLB cards; 2902,
+ 2910, 293x, 294x, 394x, 3985 and several other PCI and motherboard based
+ SCSI controllers from Adaptec. It does not support the AAA-13x RAID
+ controllers from Adaptec, nor will it likely ever support them. It
+ does not support the 2920 cards from Adaptec that use the Future Domain
+ SCSI controller chip. For those cards, you need the "Future Domain
+ 16xx SCSI support" driver.
+
+ In general, if the controller is based on an Adaptec SCSI controller
+ chip from the aic777x series or the aic78xx series, it should work. The
+ only exception is the 7810 which is specifically not supported (that's the
+ RAID controller chip on the AAA-13x cards).
+
X Information on the configuration options for this controller can be
X found by checking the help file for each of the available
- configuration options. You also want to read
- drivers/scsi/README.aic7xxx and the SCSI-HOWTO, available via FTP
- (user: anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
- Note that the AHA2920 SCSI host adapter is *not* supported by this
- driver; choose "Future Domain 16xx SCSI support" instead if you have
- one of those.
+ configuration options. You should read drivers/scsi/README.aic7xxx
+ at a minimum before contacting the maintainer with any questions.
+ The SCSI-HOWTO, available via FTP (user: anonymous) at
+ ftp://metalab.unc.edu/pub/Linux/docs/HOWTO can also be of great help.
X
X If you want to compile this driver as a module ( = code which can be
X inserted in and removed from the running kernel whenever you want),
@@ -3626,15 +3634,9 @@
X Say Y here if you want to override the default maximum number of
X commands that a single device on the aic7xxx controller is allowed
X to have active at one time. This option only affects tagged queueing
- capable devices. The driver uses a "failsafe" value of 8 by default.
- This is much lower than many devices can handle, but left in place
- for safety's sake. If you say Y here, you can adjust the number of
- commands per LUN with the following configuration option.
-
- NOTE: This does not actually enable tagged queueing on any
- particular device. The driver has changed in this respect. Please
- see the file drivers/scsi/README.aic7xxx for more information on how
- to get particular devices to use tagged command 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.
X
X If unsure, say N.
X
@@ -3771,16 +3773,21 @@
X
X enable elevator sorting
X CONFIG_SCSI_U14_34F_LINKED_COMMANDS
- This is a feature of SCSI-2 which improves performance: the host
- adapter can send a whole list of commands to a device in one
- batch. Some SCSI devices might not implement this properly, so the
- safe answer is N.
+ This option enables elevator sorting for all probed SCSI disks and
+ CDROMs. It definetly reduces the average seek distance when doing
+ random seeks, but this does not necessarily results in a noticeable
+ performance improvement: your mileage may vary...
+ The safe answer is N.
X
X maximum number of queued commands
X CONFIG_SCSI_U14_34F_MAX_TAGS
- This specifies how many SCSI commands can be maximally queued for a
- given SCSI device. Go with the default unless you know what you're
- doing. Minimum is 2 and maximum is 8.
+ This specifies how many SCSI commands can be maximally queued for each
+ probed SCSI device. You should reduce the default value of 8 only if
+ you have disks with buggy or limited tagged command support.
+ Minimum is 2 and maximum is 14. This value is also the window size
+ used by the elevator sorting option above.
+ The effective value used by the driver for each probed SCSI device is
+ reported at boot time.
X
X Future Domain 16xx SCSI/AHA-2920A support
X CONFIG_SCSI_FUTURE_DOMAIN
@@ -4237,13 +4244,13 @@
X
X EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support
X CONFIG_SCSI_EATA
- This driver supports all the EATA/DMA-compliant SCSI host adapters
- and does not need any BIOS32 service. DPT ISA and all EISA i/o
- addresses are probed looking for the "EATA" signature. If you said Y
- to "PCI BIOS support", the addresses of all the PCI SCSI controllers
- reported by BIOS32 are probed as well. You want to read the start of
- drivers/scsi/eata.c and the SCSI-HOWTO, available via FTP (user:
- anonymous) at ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
+ This driver supports all the EATA/DMA-compliant SCSI host adapters.
+ DPT ISA and all EISA i/o addresses are probed looking for the "EATA"
+ signature. If you said Y to "PCI support", the addresses of all the
+ PCI SCSI controllers reported by the PCI subsystem are probed as well.
+ You want to read the start of drivers/scsi/eata.c and the SCSI-HOWTO,
+ available via FTP (user: anonymous) at
+ ftp://metalab.unc.edu/pub/Linux/docs/HOWTO.
X
X Note that there is also another driver for the same hardware
X available: "EATA-DMA support". You should say Y to only one of them.
@@ -4257,22 +4264,27 @@
X CONFIG_SCSI_EATA_TAGGED_QUEUE
X This is a feature of SCSI-2 which improves performance: the host
X adapter can send several SCSI commands to a device's queue even if
- previous commands haven't finished yet. Some SCSI devices don't
- implement this properly, so the safe answer is N.
+ previous commands haven't finished yet. Most EATA adapters negotiate
+ this feature automatically with the device, even if your answer is N.
+ The safe answer is N.
X
X enable elevator sorting
X CONFIG_SCSI_EATA_LINKED_COMMANDS
- This is a feature of SCSI-2 which improves performance: the host
- adapter can send a whole list of commands to a device in one
- batch. Some SCSI devices might not implement this properly, so the
- safe answer is N.
+ This option enables elevator sorting for all probed SCSI disks and
+ CDROMs. It definetly reduces the average seek distance when doing
+ random seeks, but this does not necessarily results in a noticeable
+ performance improvement: your mileage may vary...
+ The safe answer is N.
X
X maximum number of queued commands
X CONFIG_SCSI_EATA_MAX_TAGS
- This specifies how many SCSI commands can be maximally queued for a
- given SCSI device. Go with the default unless you know what you're
- doing. Minimum is 2 and maximum is 16. This number will only have an
- effect if you said Y to "enable tagged command queuing", above.
+ This specifies how many SCSI commands can be maximally queued for each
+ probed SCSI device. You should reduce the default value of 16 only if
+ you have disks with buggy or limited tagged command support.
+ Minimum is 2 and maximum is 62. This value is also the window size
+ used by the elevator sorting option above.
+ The effective value used by the driver for each probed SCSI device is
+ reported at boot time.
X
X NCR53c406a SCSI support
X CONFIG_SCSI_NCR53C406A
diff -u --recursive --new-file v2.2.0-pre4/linux/Documentation/ide.txt linux/Documentation/ide.txt
--- v2.2.0-pre4/linux/Documentation/ide.txt Sun Jun 7 11:16:25 1998
+++ linux/Documentation/ide.txt Mon Jan 4 15:07:27 1999
@@ -1,9 +1,5 @@
-ide.txt -- Information regarding the Enhanced IDE drive in Linux 2.1.68+
+ide.txt -- Information regarding the Enhanced IDE drive in Linux 2.1/2.2
X ===============================================================================
-Supported by:
- Mark Lord <ml...@pobox.com> -- disks, interfaces, probing
- Gadi Oxman <ga...@netvision.net.il> -- tapes, disks, whatever
- Scott Snyder <sny...@fnald0.fnal.gov> -- cdroms, ATAPI, audio
X
X +-----------------------------------------------------------------+
X | The hdparm utility for controlling various IDE features is |
@@ -12,7 +8,7 @@
X
X See description later on below for handling BIG IDE drives with >1024 cyls.
X
-Major features of the 2.1.xx IDE driver ("NEW!" marks changes since 2.0.xx):
+Major features of the 2.1/2.2 IDE driver ("NEW!" marks changes since 2.0.xx):
X
X NEW! - support for IDE ATAPI *floppy* drives
X - support for IDE ATAPI *tape* drives, courtesy of Gadi Oxman
@@ -69,10 +65,9 @@
X NEW! - works with most Pentium PCI systems, chipsets, add-on cards
X NEW! - works with regular DMA as well as Ultra DMA
X NEW! - automatically probes for all PCI IDE interfaces
+NEW! - generic support for using BIOS-configured Ultra-DMA (UDMA) transfers
X
X
-For work in progress, see the comments in ide.c, ide-cd.c, triton.c, ...
-
X *** IMPORTANT NOTICES: BUGGY IDE CHIPSETS CAN CORRUPT DATA!!
X *** =================
X *** PCI versions of the CMD640 and RZ1000 interfaces are now detected
@@ -98,24 +93,26 @@
X *** Use of the "serialize" option is no longer necessary.
X
X This is the multiple IDE interface driver, as evolved from hd.c.
-It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15).
+It supports up to six IDE interfaces, on one or more IRQs (usually 14 & 15).
X There can be up to two drives per interface, as per the ATA-2 spec.
X
X Primary: ide0, port 0x1f0; major=3; hda is minor=0; hdb is minor=64
X Secondary: ide1, port 0x170; major=22; hdc is minor=0; hdd is minor=64
X Tertiary: ide2, port 0x1e8; major=33; hde is minor=0; hdf is minor=64
X Quaternary: ide3, port 0x168; major=34; hdg is minor=0; hdh is minor=64
+fifth.. ide4, usually PCI, probed
+sixth.. ide5, usually PCI, probed
X
-To access devices on the 2nd/3rd/4th interfaces, device entries must first be
+To access devices on interfaces > ide0, device entries must first be
X created in /dev for them. To create such entries, simply run the included
X shell script: /usr/src/linux/scripts/MAKEDEV.ide
X
-Apparently many releases of Slackware 2.2/2.3 have incorrect entries
+Apparently many older releases of Slackware had incorrect entries
X in /dev for hdc* and hdd* -- this can also be corrected by running MAKEDEV.ide
X
-ide.c automatically probes for the standard four IDE interfaces,
+ide.c automatically probes for most IDE interfaces (including all PCI ones),
X for the drives/geometries attached to those interfaces, and for the
-IRQ numbers being used by the interfaces (normally 14, 15, 11 and 10).
+IRQ numbers being used by the interfaces (normally 14, 15 for ide0/ide1).
X
X For special cases, interfaces may be specified using kernel "command line"
X options. For example,
@@ -179,7 +176,7 @@
X so ide.c now probes for both units, though success is more likely
X when the drive is jumpered correctly.
X
-Courtesy of Scott Snyder, the driver supports ATAPI cdrom drives
+Courtesy of Scott Snyder and others, the driver supports ATAPI cdrom drives
X such as the NEC-260 and the new MITSUMI triple/quad speed drives.
X Such drives will be identified at boot time, just like a hard disk.
X
@@ -227,8 +224,8 @@
X The kernel is able to execute binaries directly off of the cdrom,
X provided it is mounted with the default block size of 1024 (as above).
X
-Please pass on any feedback on the cdrom stuff to the author & maintainer,
-Scott Snyder (sny...@fnald0.fnal.gov).
+Please pass on any feedback on any of this stuff to the maintainer,
+whose address can be found in linux/MAINTAINERS.
X
X Note that if BOTH hd.c and ide.c are configured into the kernel,
X hd.c will normally be allowed to control the primary IDE interface.
@@ -256,8 +253,7 @@
X
X insmod ide.o options="ide0=serialize ide2=0x1e8;0x3ee;11"
X
-ml...@pobox.com
-sny...@fnald0.fnal.gov
+
X ================================================================================
X
X Summary of ide driver parameters for kernel "command line":
@@ -307,6 +303,7 @@
X except the cmd640.
X "idex=serialize" : do not overlap operations on idex and ide(x^1)
X "idex=reset" : reset interface after probe
+ "idex=dma" : automatically configure/use DMA if possible.
X
X The following are valid ONLY on ide0,
X and the defaults for the base,ctl ports must not be altered.
@@ -319,6 +316,8 @@
X "ide0=ali14xx" : probe/support ali14xx chipsets (ALI M1439/M1445)
X "ide0=umc8672" : probe/support umc8672 chipsets
X
+There may be more options than shown -- use the source, Luke!
+
X Everything else is rejected with a "BAD OPTION" message.
X
X ================================================================================
@@ -488,19 +487,19 @@
X
X - buy a motherboard that uses the Intel Triton chipset -- very common.
X - use IDE for the first two drives, placing them on separate interfaces.
+ - very fast 7200rpm drives are now available
+ (though many problems have been reported with Seagate ones).
X - place the IDE cdrom drive as slave on either interface.
X - if additional disks are to be connected, consider your needs:
X - fileserver? Buy a SC200 SCSI adaptor for the next few drives.
X - personal system? Use IDE for the next two drives.
X - still not enough? Keep adding SC200 SCSI cards as needed.
X
-Most manufacturers make both IDE and SCSI-2 versions of each of their drives.
-The IDE ones are usually faster and cheaper, due to the higher data transfer
-speed of PIO mode4 (ATA2), 16.6MBytes/sec versus 10Mbytes/sec for SCSI-2.
-
-In particular, I recommend Quantum FireBalls as cheap and exceptionally fast.
-The new WD1.6GB models are also cheap screamers.
-
-For really high end systems, go for fast/wide 7200rpm SCSI. But it'll cost ya!
+Most manufacturers make both IDE and SCSI versions of each of their drives.
+The IDE ones are usually as fast and cheaper, due to lower command overhead
+and the higher data transfer speed of UDMA2. But fast/ultrawide/superlative
+SCSI is still king of the heap, especially for servers, if you've got the bucks.
X
X ml...@pobox.com
+--
+For current maintainers of this stuff, see the linux/MAINTAINERS file.
diff -u --recursive --new-file v2.2.0-pre4/linux/Documentation/kernel-docs.txt linux/Documentation/kernel-docs.txt
--- v2.2.0-pre4/linux/Documentation/kernel-docs.txt Thu Dec 31 10:28:58 1998
+++ linux/Documentation/kernel-docs.txt Mon Jan 4 11:37:29 1999
@@ -28,7 +28,7 @@
X
X PLEASE, if you know any paper not listed here or write a new document,
X send me an e-mail, and I'll include a reference to it here. Any
- corrections, ideas or comments are also wellcomed.
+ corrections, ideas or comments are also welcomed.
X
X The papers that follow are listed in no particular order. All are
X catalogued with the following fields: the document's "Title", the
diff -u --recursive --new-file v2.2.0-pre4/linux/Documentation/networking/ip-sysctl.txt linux/Documentation/networking/ip-sysctl.txt
--- v2.2.0-pre4/linux/Documentation/networking/ip-sysctl.txt Tue Dec 22 14:16:53 1998
+++ linux/Documentation/networking/ip-sysctl.txt Mon Jan 4 15:31:35 1999
@@ -211,4 +211,4 @@
X Updated by:
X Andi Kleen
X a...@muc.de
-$Id: ip-sysctl.txt,v 1.7 1998/05/02 12:05:00 davem Exp $
+$Id: ip-sysctl.txt,v 1.8 1999/01/02 16:37:06 davem Exp $
diff -u --recursive --new-file v2.2.0-pre4/linux/Documentation/oops-tracing.txt linux/Documentation/oops-tracing.txt
--- v2.2.0-pre4/linux/Documentation/oops-tracing.txt Mon Jan 4 15:08:16 1999
+++ linux/Documentation/oops-tracing.txt Tue Jan 5 11:14:24 1999
@@ -1,9 +1,9 @@
X Quick Summary
X -------------
X
-cd /usr/src/linux/scripts
-g++ -o ksymoops ksymoops.cc
-./ksymoops ../System.map < the_oops.txt
+cd /usr/src/linux/scripts/ksymoops
+make ksymoops
+./ksymoops < the_oops.txt
X
X and send the output the maintainer of the kernel area that seems to be
X involved with the problem. Don't worry too much about getting the wrong
diff -u --recursive --new-file v2.2.0-pre4/linux/Documentation/sound/AWE32 linux/Documentation/sound/AWE32
--- v2.2.0-pre4/linux/Documentation/sound/AWE32 Mon Sep 28 10:51:32 1998
+++ linux/Documentation/sound/AWE32 Mon Jan 4 12:01:19 1999
@@ -6,21 +6,20 @@
X 1) Make sure you have an ORIGINAL Creative SB32, AWE32 or AWE64 card. This is
X important, because the driver works only with real Creative cards.
X
-2) If your card is NOT "Plug-n-Play" (I myself don't know Creative AWE non
-plug'n'play cards however) then go to 5th step now. In the other case
+2) If your card is NOT "Plug-n-Play" then go to 5th step now. In the other case
X proceed to step 3.
X
X 3) You should obtain isapnptools. I looked through other PnP packages
X for Linux, but all they are either in deep unstable beta/alpha releases or
X they are much worse than isapnptools. In my case isapnptools were included in
-a Linux distribution (Red Hat 5.0). If you also already have them then go to
+a Linux distribution (Red Hat 5.x). If you also already have them then go to
X step 4.
X
-The latest copy of isapnptools-1.15 is available from
-ftp://ftp.demon.co.uk/pub/unix/linux/utils/ (I tested isapnptools-1.15.tgz)
+The latest copy of isapnptools-1.17 is available from
+ftp://sunsite.unc.edu/pub/Linux/system/hardware/isapnptools-1.17.tgz
X You should gunzip/untar it to something like /usr/local/
-(cp isapnptools-1.15.tgz /usr/local/; cd /usr/local/;
-tar -xzf isapnptools-1.15.tgz).
+(cp isapnptools-1.17.tgz /usr/local/; cd /usr/local/;
+tar -xzf isapnptools-1.17.tgz).
X
X Compile the package (make) and install it (make install).
X If something goes wrong check the INSTALL file in isapnptools-1.15 directory.
@@ -59,26 +58,13 @@
X Now you can execute "isapnp /etc/isapnp.conf". No errors should be reported.
X If you correctly installed isapnptools, then isapnp will run every boot time.
X
-5) Now you should recompile the kernel. I recommend using development kernels,
-because the AWE32 driver is included in them. ATTENTION! In kernels 2.1.102,
-2.1.103, 2.1.104-pre1 and 2.1.104 (not the others) the lowlevel sound driver
-is not working. You should use the patch available at
-http://members.xoom.com/yar/history.html. If you are using stable kernel
-releases 2.0.x, then get the latest version (3.8s9) of
-OSS/Free at ftp://ftp.4front-tech.com/ossfree/ossfree38s9-linux20x.tar.gz
-and gunzip/untar it in /usr/src/ (assuming you keep your kernel source in
-/usr/src/linux). Then go to /usr/src/linux/ and view the README file. That
-file contains info about kernel compilation and installation.
+5) Now you should recompile the kernel.
X
X In "make (x,menu)config" select in "Sound":
X "Sound card support", "100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support",
X "Generic OPL2/OPL3 FM synthesizer support" and "FM synthesizer (YM3812/OPL-3)
X support" as <M> (module).
X
-If you use kernel version 2.0.x or version 2.1.y (y <= 2.1.104) skip substep a,
-on 2.1.105 or later go through it.
-
-substep a:
X In "make (x,menu)config" select in "Sound":
X select "OSS sound modules" as <M> (module)
X
@@ -86,23 +72,23 @@
X "Additional low level sound drivers", "AWE32 synth" as <M> (module).
X Select "Additional low level sound drivers" as [y] (or [*] (yes)) (If it is not
X available as [y], select it as <M> (module))
-Now recompile the kernel (make dep; make (b)zImage; make modules;
-make modules_install), update your boot loader and boot new kernel.
X
-6) Now download awesfx program from
-http://bahamut.mm.t.u-tokyo.ac.jp/~iwai/awedrv/index.html#Latest. Compile it.
-Copy sfxload program to /bin (or /sbin if you wish). To enable AWE midi
+Now recompile the kernel (make dep; make (b)zImage, b(z)lilo, etc...;
+make modules; make modules_install), update your boot loader (if required) and
+boot new kernel.
+
+6) If awesfx program is not included in your distribution, then download it
+from http://bahamut.mm.t.u-tokyo.ac.jp/~iwai/awedrv/index.html#Latest.
+Compile it. Copy sfxload program to /usr/bin. To enable AWE general midi
X synthesis you should also get the sound bank file for general midi from
-http://members.xoom.com/yar/synthgm.sbk.gz. Copy it to
-/usr and gunzip it there.
+http://members.xoom.com/yar/synthgm.sbk.gz. Copy it to /usr and gunzip it there.
X
-7) Edit /etc/rc.d/rc.local, inserting at the end of the file:
+7) Edit /etc/conf.modules, inserting at the end of the file:
X
-modprobe sound
-insmod uart401
-insmod sb io=0x220 irq=5 dma=1 dma16=5 mpu_io=0x330
-insmod awe_wave
-sfxload /usr/synthfm.sbk
+alias sound sb
+alias midi awe_wave
+post-install awe_wave /usr/bin/sfxload /usr/synthfm.sbk
+options sb io=0x220 irq=5 dma=1 dma16=5 mpu_io=0x330
X
X (on io=0xaaa irq=b.... you should use your own settings)
X That will enable the Sound Blaster and AWE wave synthesis.
@@ -110,13 +96,16 @@
X To play midi files you should get one of these programs:
X
X Playmidi 2.4 or higher: http://playmidi.openprojects.net
-Drvmidi 4.2.b: http://bahamut.mm.t.u-tokyo.ac.jp/~iwai/awedrv/index.html#Latest
+Drvmidi: http://bahamut.mm.t.u-tokyo.ac.jp/~iwai/awedrv/index.html#Latest
X
X (These are available at all major Linux FTP sites and may already be
X in your distribution)
+Remember to use -a switch if you have playmidi as a compiled binary (ex. RPM)
X
X If something goes wrong please e-mail me. All comments and suggestions are
X welcome.
X
X Yaroslav Rosomakho (alo...@dialup.ptt.ru)
- http://members.xoom.com/yar
+ http://www.yar.opennet.ru
+
+Last Updated: 3Jan99
diff -u --recursive --new-file v2.2.0-pre4/linux/Documentation/sound/OPL3-SA2 linux/Documentation/sound/OPL3-SA2
--- v2.2.0-pre4/linux/Documentation/sound/OPL3-SA2 Tue Dec 22 14:16:53 1998
+++ linux/Documentation/sound/OPL3-SA2 Mon Jan 4 11:37:29 1999
@@ -4,7 +4,7 @@
X Scott Murray, sco...@interlog.com
X December, 1998
X
-NOTE: All trademarked terms mentioned below are properties of their
+NOTE: All trade-marked terms mentioned below are properties of their
X respective owners.
X
X This driver is for PnP soundcards based on the following Yamaha audio
@@ -14,10 +14,10 @@
X YMF715 aka OPL3-SA3
X YMF719 aka OPL3-SAx (?)
X
-I'm a little fuzzy on what is classified a SAx, as I've seen the label
-used to refer to the whole 7xx family and as a specific identifier for
-the 719 on my no-name soundcard. To make matters worse, there seem to
-be several reversions of the 715 chipset.
+I'm a little fuzzy on what exactly is classified a SAx, as I've seen
+the label used to refer to the whole 7xx family and as a specific
+identifier for the 719 on my no-name soundcard. To make matters
+worse, there seem to be several revisions of the 715 chipset.
X
X Anyways, all of these chipsets implement the following devices:
X
@@ -35,18 +35,20 @@
X of doing this. The most common is to use the isapnptools package to
X initialize the card, and use the kernel module form of the sound
X subsystem and sound drivers. Alternatively, some BIOS's allow manual
-configuration of installed PnP devices in the BIOS menus, which should
+configuration of installed PnP devices in a BIOS menu, which should
X allow using the non-modular sound drivers, i.e. built into the kernel.
X
X I personally use isapnp and modules, and do not have access to a PnP
X BIOS machine to test. If you have such a beast, try building both the
-MSS driver and this driver into the kernel (appropiately configured,
-of course) and let me know if it works. If it does not, then email me
-if you are willing to experiment in an effort to make it work.
+MSS driver and this driver into the kernel (appropriately configured,
+of course). I have received reports of this working, so it should be
+possible for most people with PnP BIOS. If it does not work for you,
+then email me if you are willing to experiment in an effort to make it
+work.
X
X If you are using isapnp, follow the directions in its documentation to
-produce a configuration file. Here is the relevant excerpt for my SAx
-card from my isapnp.conf:
+produce a configuration file. Here is the relevant excerpt I use for
+my SAx card from my isapnp.conf:
X
X (CONFIGURE YMH0800/-1 (LD 0
X
@@ -80,11 +82,11 @@
X insmod opl3sa2 io=0x370 mss_io=0x530 mpu_io=0x330 irq=7 dma=0 dma2=3
X insmod opl3 io=0x388
X
-Remeber that the opl3sa2 module's io argument is for it's own control
+Remember that the opl3sa2 module's io argument is for it's own control
X port, which handles the card's master mixer for volume (on all cards),
-and bass and treble (on SA3 and SAx).
+and bass and treble (on SA3 and SAx cards).
X
-If all goes well an you see no error messages, you should be able to
+If all goes well and you see no error messages, you should be able to
X start using the sound capabilities of your system. If you get an
X error message while trying to insert the opl3sa2 module, then make
X sure that the values of the various arguments match what you specified
@@ -100,12 +102,28 @@
X that says "opl3sa2.c: chipset version = <some number>". If you want
X me to add support for your card, send me the number from this line and
X any information you have on the make and chipset of your sound card,
-and I may be able to work up something. If you do not see these
-messages, and any of the other messages present in the log are not
-helpful, email me some details and I'll try my best to help.
+and I should be able to work up a permanent fix.
X
-To set up automatic module loading with kmod, the kernel module loader,
-I currently use the following section in my conf.modules file:
+A temporary solution is to force the driver to act as either a SA2 or
+SA3. If you use the modular driver, this can be done with the "force"
+option. Using "force=2" makes the driver treat your card as a SA2,
+and "force=3" makes it treat your card as a SA3. Note that the driver
+does not really differentiate internally between the SA3 and SAx, so
+"force=3" is actually suitable for an SAx card.
+
+If you build the driver into the kernel, a similar option is
+available, "Chipset". Setting it to 2 or 3 will yield the same result
+as the "force" option does for the module. I recommend trying
+auto-probing first ("Chipset" equal to the default of -1) before
+forcing compatibility with a specific chipset.
+
+If you do not see the chipset version message, and none of the other
+messages present in the system log are helpful, email me some details
+and I'll try my best to help.
+
+Lastly, if you're using modules and want to set up automatic module
+loading with kmod, the kernel module loader, here is the section I
+currently use in my conf.modules file:
X
X # Sound
X alias char-major-14 opl3sa2
diff -u --recursive --new-file v2.2.0-pre4/linux/MAINTAINERS linux/MAINTAINERS
--- v2.2.0-pre4/linux/MAINTAINERS Thu Dec 31 10:28:58 1998
+++ linux/MAINTAINERS Mon Jan 4 15:31:35 1999
@@ -518,9 +518,9 @@
X
X NETWORKING [IPv4/IPv6]
X P: David S. Miller
-M: da...@caip.rutgers.edu
-P: Eric Schenk
-M: Eric....@dna.lth.se
+M: da...@dm.cobaltmicro.com
+P: Andi Kleen
+M: a...@muc.de
X P: Alexey Kuznetsov
X M: kuz...@ms2.inr.ac.ru
X L: net...@roxanne.nuclecu.unam.mx
diff -u --recursive --new-file v2.2.0-pre4/linux/Makefile linux/Makefile
--- v2.2.0-pre4/linux/Makefile Mon Jan 4 15:08:16 1999
+++ linux/Makefile Mon Jan 4 15:08:27 1999
@@ -1,7 +1,7 @@
X VERSION = 2
X PATCHLEVEL = 2
X SUBLEVEL = 0
-EXTRAVERSION =-pre4
+EXTRAVERSION =-pre5
X
X ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
X
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.2.0-pre4/linux/arch/i386/config.in Fri Jan 1 12:58:17 1999
+++ linux/arch/i386/config.in Mon Jan 4 14:28:02 1999
@@ -15,8 +15,8 @@
X "386 CONFIG_M386 \
X 486/Cx486 CONFIG_M486 \
X 586/K5/5x86/6x86 CONFIG_M586 \
- Pentium/TSC CONFIG_M586TSC \
- PPro/K6/6x86MX CONFIG_M686" PPro
+ Pentium/K6/TSC CONFIG_M586TSC \
+ PPro/6x86MX CONFIG_M686" PPro
X #
X # Define implied options from the CPU selection here
X #
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c
--- v2.2.0-pre4/linux/arch/i386/kernel/ptrace.c Thu Dec 31 10:28:59 1998
+++ linux/arch/i386/kernel/ptrace.c Wed Jan 6 10:09:31 1999
@@ -67,6 +67,33 @@
X return 0;
X }
X
+extern int _stext, _etext;
+static void print_child_state(struct task_struct *task)
+{
+ unsigned int * stack = (unsigned int *) task->tss.esp0;
+ int count = 40;
+
+ printk("Process: %s (stack=%p, task=%p)\n", task->comm, stack, task);
+ for (;;) {
+ unsigned int data;
+ if ((unsigned int) stack < (unsigned int) task)
+ break;
+ if ((unsigned int) stack >= PAGE_SIZE + (unsigned int) task)
+ break;
+ data = *stack;
+ stack++;
+ if (data < (unsigned long) &_stext)
+ continue;
+ if (data >= (unsigned long) &_etext)
+ continue;
+ printk("[<%08x>] ", data);
+ if (--count)
+ continue;
+ break;
+ }
+ printk("\n");
+}
+
X /*
X * This routine gets a long from any process space by following the page
X * tables. NOTE! You should check that the long isn't on a page boundary,
@@ -408,6 +435,8 @@
X if (!(child->flags & PF_PTRACED))
X goto out;
X if (child->state != TASK_STOPPED) {
+print_child_state(child);
+goto out;
X if (request != PTRACE_KILL)
X goto out;
X }
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.2.0-pre4/linux/arch/i386/kernel/smp.c Mon Jan 4 15:08:16 1999
+++ linux/arch/i386/kernel/smp.c Mon Jan 4 11:57:30 1999
@@ -1052,10 +1052,10 @@
X * the cache size)
X */
X
- if (boot_cpu_data.x86 <= 4) {
+ if (!cpu_hz) {
X /*
X * this basically disables processor-affinity
- * scheduling on <=i486 based SMP boards.
+ * scheduling on SMP without a TSC.
X */
X cacheflush_time = 0;
X return;
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/m68k/Makefile linux/arch/m68k/Makefile
--- v2.2.0-pre4/linux/arch/m68k/Makefile Tue Dec 22 14:16:54 1998
+++ linux/arch/m68k/Makefile Tue Jan 5 11:20:43 1999
@@ -116,7 +116,7 @@
X
X archclean:
X rm -f vmlinux.gz
- rm -f kernel/m68k_defs.h kernel/m68k_defs.d
+ rm -f arch/m68k/kernel/m68k_defs.h arch/m68k/kernel/m68k_defs.d
X
X archmrproper:
X
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/m68k/config.in linux/arch/m68k/config.in
--- v2.2.0-pre4/linux/arch/m68k/config.in Tue Dec 22 14:16:54 1998
+++ linux/arch/m68k/config.in Tue Jan 5 11:20:43 1999
@@ -215,8 +215,8 @@
X fi
X if [ "$CONFIG_MAC" = "y" ]; then
X bool 'Mac NS 8390 based ethernet cards' CONFIG_DAYNAPORT
- bool 'AV Macintosh onboard MACE ethernet' CONFIG_MACMACE
- bool 'Macintosh onboard SONIC ethernet' CONFIG_MACSONIC
+# bool 'Macintosh (AV) onboard MACE ethernet' CONFIG_MACMACE
+ bool 'Macintosh (Quadra) onboard SONIC ethernet' CONFIG_MACSONIC
X fi
X if [ "$CONFIG_VME" = "y" -a "$CONFIG_MVME16x" = "y" ]; then
X tristate 'MVME16x Ethernet support' CONFIG_MVME16x_NET
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/m68k/kernel/m68k_defs.h linux/arch/m68k/kernel/m68k_defs.h
--- v2.2.0-pre4/linux/arch/m68k/kernel/m68k_defs.h Thu Nov 12 16:21:18 1998
+++ linux/arch/m68k/kernel/m68k_defs.h Tue Jan 5 11:20:43 1999
@@ -3,6 +3,6 @@
X */
X
X #define TS_MAGICKEY 0x5a5a5a5a
-#define TS_TSS 478
-#define TS_ESP0 498
-#define TS_FPU 502
+#define TS_TSS 482
+#define TS_ESP0 502
+#define TS_FPU 506
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/m68k/kernel/m68k_ksyms.c linux/arch/m68k/kernel/m68k_ksyms.c
--- v2.2.0-pre4/linux/arch/m68k/kernel/m68k_ksyms.c Tue Dec 22 14:16:54 1998
+++ linux/arch/m68k/kernel/m68k_ksyms.c Tue Jan 5 11:20:43 1999
@@ -45,6 +45,8 @@
X EXPORT_SYMBOL(strnlen);
X EXPORT_SYMBOL(strrchr);
X EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strtok);
+EXPORT_SYMBOL(strpbrk);
X EXPORT_SYMBOL(local_irq_count);
X EXPORT_SYMBOL(local_bh_count);
X EXPORT_SYMBOL(enable_irq);
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c
--- v2.2.0-pre4/linux/arch/m68k/kernel/process.c Tue Dec 22 14:16:54 1998
+++ linux/arch/m68k/kernel/process.c Tue Jan 5 11:20:43 1999
@@ -40,6 +40,7 @@
X */
X static struct vm_area_struct init_mmap = INIT_MMAP;
X static struct fs_struct init_fs = INIT_FS;
+static struct file * init_fd_array[NR_OPEN] = { NULL, };
X static struct files_struct init_files = INIT_FILES;
X static struct signal_struct init_signals = INIT_SIGNALS;
X struct mm_struct init_mm = INIT_MM;
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c
--- v2.2.0-pre4/linux/arch/m68k/kernel/ptrace.c Thu Nov 12 16:21:18 1998
+++ linux/arch/m68k/kernel/ptrace.c Tue Jan 5 11:20:43 1999
@@ -375,7 +375,9 @@
X case PTRACE_PEEKDATA: {
X unsigned long tmp;
X
+ down(&child->mm->mmap_sem);
X ret = read_long(child, addr, &tmp);
+ up(&child->mm->mmap_sem);
X if (ret >= 0)
X ret = put_user(tmp, (unsigned long *) data);
X goto out;
@@ -408,7 +410,9 @@
X /* when I and D space are separate, this will have to be fixed. */
X case PTRACE_POKETEXT: /* write the word at location addr. */
X case PTRACE_POKEDATA:
+ down(&child->mm->mmap_sem);
X ret = write_long(child,addr,data);
+ up(&child->mm->mmap_sem);
X goto out;
X
X case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/m68k/mac/config.c linux/arch/m68k/mac/config.c
--- v2.2.0-pre4/linux/arch/m68k/mac/config.c Tue Dec 22 14:16:54 1998
+++ linux/arch/m68k/mac/config.c Tue Jan 5 11:20:43 1999
@@ -423,7 +423,7 @@
X */
X
X { MAC_MODEL_CLII, "Classic II", MAC_ADB_IISI, MAC_VIA_IIci, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS},
- { MAC_MODEL_CCL, "Color Classic", MAC_ADB_IISI, MAC_VIA_IIci, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS},
+ { MAC_MODEL_CCL, "Color Classic", MAC_ADB_CUDA, MAC_VIA_IIci, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS},
X
X /*
X * Some Mac LC machines. Basically the same as the IIci, ADB like IIsi
@@ -475,8 +475,8 @@
X * Centris - just guessing again; maybe like Quadra
X */
X
- { MAC_MODEL_C610, "Centris 610", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS},
- { MAC_MODEL_C650, "Centris 650", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS},
+ { MAC_MODEL_C610, "Centris 610", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_SONIC, MAC_NUBUS},
+ { MAC_MODEL_C650, "Centris 650", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_SONIC, MAC_NUBUS},
X { MAC_MODEL_C660, "Centris 660AV", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA3, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS},
X
X /*
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/m68k/mac/debug.c linux/arch/m68k/mac/debug.c
--- v2.2.0-pre4/linux/arch/m68k/mac/debug.c Tue Dec 22 14:16:54 1998
+++ linux/arch/m68k/mac/debug.c Tue Jan 5 11:20:43 1999
@@ -397,14 +397,18 @@
X /* Mac modem port */
X mac_init_scc_port( B9600|CS8, 0 );
X mac_console_driver.write = mac_scca_console_write;
+#ifdef CONFIG_SERIAL_CONSOLE
X mac_console_driver.wait_key = mac_scca_console_wait_key;
+#endif
X scc_port = 0;
X }
X else if (!strcmp( m68k_debug_device, "ser2" )) {
X /* Mac printer port */
X mac_init_scc_port( B9600|CS8, 1 );
X mac_console_driver.write = mac_sccb_console_write;
+#ifdef CONFIG_SERIAL_CONSOLE
X mac_console_driver.wait_key = mac_sccb_console_wait_key;
+#endif
X scc_port = 1;
X }
X #endif
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/m68k/mac/macboing.c linux/arch/m68k/mac/macboing.c
--- v2.2.0-pre4/linux/arch/m68k/mac/macboing.c Fri Oct 9 13:27:06 1998
+++ linux/arch/m68k/mac/macboing.c Tue Jan 5 11:20:43 1999
@@ -1,6 +1,12 @@
X /*
X * Mac bong noise generator. Note - we ought to put a boingy noise
X * here 8)
+ *
+ * ----------------------------------------------------------------------
+ * 16.11.98:
+ * rewrote some functions, added support for Enhanced ASC (Quadras)
+ * after the NetBSD asc.c console bell patch by Colin Wood/Frederick Bruck
+ * Juergen Mellinger (juergen....@t-online.de)
X */
X
X #include <linux/sched.h>
@@ -9,124 +15,281 @@
X #include <asm/macintosh.h>
X #include <asm/mac_asc.h>
X
+static int mac_asc_inited = 0;
+/*
+ * dumb triangular wave table
+ */
+static __u8 mac_asc_wave_tab[ 0x800 ];
+
+/*
+ * Alan's original sine table; needs interpolating to 0x800
+ * (hint: interpolate or hardwire [0 -> Pi/2[, it's symmetric)
+ */
X static const signed char sine_data[] = {
X 0, 39, 75, 103, 121, 127, 121, 103, 75, 39,
X 0, -39, -75, -103, -121, -127, -121, -103, -75, -39
X };
-#define DATA_SIZE (sizeof(sine_data)/sizeof(sine_data[0]))
X
-static void nosound( unsigned long ignored );
-static struct timer_list sound_timer = { NULL, NULL, 0, 0, nosound };
+/*
+ * where the ASC hides ...
+ */
+static volatile __u8* mac_asc_regs = ( void* )0x50F14000;
X
-static volatile unsigned char *asc_base=(void *)0x50F14000;
+/*
+ * sample rate; is this a good default value?
+ */
+static unsigned long mac_asc_samplespersec = 11050;
+static int mac_bell_duration = 0;
+static unsigned long mac_bell_phase; /* 0..2*Pi -> 0..0x800 (wavetable size) */
+static unsigned long mac_bell_phasepersample;
X
+/*
+ * some function protos
+ */
+static void mac_init_asc( void );
+static void mac_nosound( unsigned long );
+static void mac_quadra_start_bell( unsigned int, unsigned int, unsigned int );
+static void mac_quadra_ring_bell( unsigned long );
+static void mac_av_start_bell( unsigned int, unsigned int, unsigned int );
+static void ( *mac_special_bell )( unsigned int, unsigned int, unsigned int ) = NULL;
+
+/*
+ * our timer to start/continue/stop the bell
+ */
+static struct timer_list mac_sound_timer = { NULL, NULL, 0, 0, mac_nosound };
X
-void mac_mksound( unsigned int hz, unsigned int ticks )
-{
- static int inited = 0;
- unsigned long flags;
- int samples=512;
-
- if (macintosh_config->ident == MAC_MODEL_C660
- || macintosh_config->ident == MAC_MODEL_Q840)
- {
- /*
- * The Quadra 660AV and 840AV use the "Singer" custom ASIC for sound I/O.
- * It appears to be similar to the "AWACS" custom ASIC in the Power Mac
- * [678]100. Because Singer and AWACS may have a similar hardware
- * interface, this would imply that the code in drivers/sound/dmasound.c
- * for AWACS could be used as a basis for Singer support. All we have to
- * do is figure out how to do DMA on the 660AV/840AV through the PSC and
- * figure out where the Singer hardware sits in memory. (I'd look in the
- * vicinity of the AWACS location in a Power Mac [678]100 first, or the
- * current location of the Apple Sound Chip--ASC--in other Macs.) The
- * Power Mac [678]100 info can be found in MkLinux Mach kernel sources.
- *
- * Quoted from Apple's Tech Info Library, article number 16405:
- * "Among desktop Macintosh computers, only the 660AV, 840AV, and Power
- * Macintosh models have 16-bit audio input and output capability
- * because of the AT&T DSP3210 hardware circuitry and the 16-bit Singer
- * codec circuitry in the AVs. The Audio Waveform Amplifier and
- * Converter (AWAC) chip in the Power Macintosh performs the same
- * 16-bit I/O functionality. The PowerBook 500 series computers
- * support 16-bit stereo output, but only mono input."
- *
- * http://til.info.apple.com/techinfo.nsf/artnum/n16405
- *
- * --David Kilzer
- */
+/*
+ * Sort of initialize the sound chip (called from mac_mksound on the first
+ * beep).
+ */
+static void mac_init_asc( void )
+{
+ int i;
+
+ /*
+ * do some machine specific initialization
+ * BTW:
+ * the NetBSD Quadra patch identifies the Enhanced Apple Sound Chip via
+ * mac_asc_regs[ 0x800 ] & 0xF0 != 0
+ * this makes no sense here, because we have to set the default sample
+ * rate anyway if we want correct frequencies
+ */
+ switch ( macintosh_config->ident )
+ {
+ case MAC_MODEL_IIFX:
+ /*
+ * The IIfx is always special ...
+ */
+ mac_asc_regs = ( void* )0x50010000;
+ break;
+ /*
+ * not sure about how correct this list is
+ * machines with the EASC enhanced apple sound chip
+ */
+ case MAC_MODEL_Q630:
+ case MAC_MODEL_P475:
+ mac_special_bell = mac_quadra_start_bell;
+ mac_asc_samplespersec = 22150;
+ break;
+ case MAC_MODEL_Q650:
+ case MAC_MODEL_Q700:
+ case MAC_MODEL_Q800:
+ case MAC_MODEL_Q900:
+ case MAC_MODEL_Q950:
+ /*
+ * Currently not implemented!
+ */
+ /*
+ * The Quadra 660AV and 840AV use the "Singer" custom ASIC for sound I/O.
+ * It appears to be similar to the "AWACS" custom ASIC in the Power Mac
+ * [678]100. Because Singer and AWACS may have a similar hardware
+ * interface, this would imply that the code in drivers/sound/dmasound.c
+ * for AWACS could be used as a basis for Singer support. All we have to
+ * do is figure out how to do DMA on the 660AV/840AV through the PSC and
+ * figure out where the Singer hardware sits in memory. (I'd look in the
+ * vicinity of the AWACS location in a Power Mac [678]100 first, or the
+ * current location of the Apple Sound Chip--ASC--in other Macs.) The
+ * Power Mac [678]100 info can be found in MkLinux Mach kernel sources.
+ *
+ * Quoted from Apple's Tech Info Library, article number 16405:
+ * "Among desktop Macintosh computers, only the 660AV, 840AV, and Power
+ * Macintosh models have 16-bit audio input and output capability
+ * because of the AT&T DSP3210 hardware circuitry and the 16-bit Singer
+ * codec circuitry in the AVs. The Audio Waveform Amplifier and
+ * Converter (AWAC) chip in the Power Macintosh performs the same
+ * 16-bit I/O functionality. The PowerBook 500 series computers
+ * support 16-bit stereo output, but only mono input."
+ *
+ * http://til.info.apple.com/techinfo.nsf/artnum/n16405
+ *
+ * --David Kilzer
+ */
+ mac_special_bell = mac_av_start_bell;
+ break;
+ }
+
+ /*
+ * init the wave table with a simple triangular wave
+ * A sine wave would sure be nicer here ...
+ */
+ for ( i = 0; i < 0x400; i++ )
+ {
+ mac_asc_wave_tab[ i ] = i / 4;
+ mac_asc_wave_tab[ i + 0x400 ] = 0xFF - i / 4;
+ }
+ mac_asc_inited = 1;
+}
X
+/*
+ * Called to make noise; current single entry to the boing driver.
+ * Does the job for simple ASC, calls other routines else.
+ * XXX Fixme:
+ * Should be split into asc_mksound, easc_mksound, av_mksound and
+ * function pointer set in mac_init_asc which would be called at
+ * init time.
+ * _This_ is rather ugly ...
+ */
+void mac_mksound( unsigned int freq, unsigned int length )
+{
+ __u32 cfreq = ( freq << 5 ) / 468;
+ __u32 flags;
+ int i;
+
+ if ( !mac_asc_inited )
+ mac_init_asc();
+
+ if ( mac_special_bell )
+ {
+ mac_special_bell( freq, length, 128 );
X return;
X }
-
- if(!inited)
+
+ if ( freq < 20 || freq > 20000 || length == 0 )
X {
- int i=0;
- int j=0;
- int k=0;
- int l=0;
-
- /*
- * The IIfx strikes again!
- */
-
- if(macintosh_config->ident==MAC_MODEL_IIFX)
- asc_base=(void *)0x50010000;
+ mac_nosound( 0 );
+ return;
+ }
X
- for(i=0;i<samples;i++)
- {
- asc_base[i]=sine_data[j];
- asc_base[i+512]=sine_data[j];
- asc_base[i+1024]=sine_data[j];
- asc_base[i+1536]=sine_data[j];
- j++;
- if(j==DATA_SIZE)
- j=0;
- if(i&1)
- k++;
- if(k==DATA_SIZE)
- k=0;
- if((i&3)==3)
- l++;
- if(l==DATA_SIZE)
- l=0;
- }
- inited=1;
+ save_flags( flags );
+ cli();
+
+ del_timer( &mac_sound_timer );
+
+ for ( i = 0; i < 0x800; i++ )
+ mac_asc_regs[ i ] = 0;
+ for ( i = 0; i < 0x800; i++ )
+ mac_asc_regs[ i ] = mac_asc_wave_tab[ i ];
+
+ for ( i = 0; i < 8; i++ )
+ *( __u32* )( ( __u32 )mac_asc_regs + ASC_CONTROL + 0x814 + 8 * i ) = cfreq;
+
+ mac_asc_regs[ 0x807 ] = 0;
+ mac_asc_regs[ ASC_VOLUME ] = 128;
+ mac_asc_regs[ 0x805 ] = 0;
+ mac_asc_regs[ 0x80F ] = 0;
+ mac_asc_regs[ ASC_MODE ] = ASC_MODE_SAMPLE;
+ mac_asc_regs[ ASC_ENABLE ] = ASC_ENABLE_SAMPLE;
+
+ mac_sound_timer.expires = jiffies + length;
+ add_timer( &mac_sound_timer );
+
+ restore_flags( flags );
+}
+
+/*
+ * regular ASC: stop whining ..
+ */
+static void mac_nosound( unsigned long ignored )
+{
+ mac_asc_regs[ ASC_ENABLE ] = 0;
+}
+
+/*
+ * EASC entry; init EASC, don't load wavetable, schedule 'start whining'.
+ */
+static void mac_quadra_start_bell( unsigned int freq, unsigned int length, unsigned int volume )
+{
+ __u32 flags;
+
+ /* if the bell is already ringing, ring longer */
+ if ( mac_bell_duration > 0 )
+ {
+ mac_bell_duration += length;
+ return;
X }
- save_flags(flags);
+
+ mac_bell_duration = length;
+ mac_bell_phase = 0;
+ mac_bell_phasepersample = ( freq * sizeof( mac_asc_wave_tab ) ) / mac_asc_samplespersec;
+ /* this is reasonably big for small frequencies */
+
+ save_flags( flags );
X cli();
- del_timer( &sound_timer );
X
- if (hz > 20 && hz < 32767) {
- int i;
- u_long asc_pulses=((hz<<5)*samples)/468;
- for(i=0;i<4;i++)
+ /* set the volume */
+ mac_asc_regs[ 0x806 ] = volume;
+
+ /* set up the ASC registers */
+ if ( mac_asc_regs[ 0x801 ] != 1 )
+ {
+ /* select mono mode */
+ mac_asc_regs[ 0x807 ] = 0;
+ /* select sampled sound mode */
+ mac_asc_regs[ 0x802 ] = 0;
+ /* ??? */
+ mac_asc_regs[ 0x801 ] = 1;
+ mac_asc_regs[ 0x803 ] |= 0x80;
+ mac_asc_regs[ 0x803 ] &= 0x7F;
+ }
+
+ mac_sound_timer.function = mac_quadra_ring_bell;
+ mac_sound_timer.expires = jiffies + 1;
+ add_timer( &mac_sound_timer );
+
+ restore_flags( flags );
+}
+
+/*
+ * EASC 'start/continue whining'; I'm not sure why the above function didn't
+ * already load the wave table, or at least call this one...
+ * This piece keeps reloading the wave table until done.
+ */
+static void mac_quadra_ring_bell( unsigned long ignored )
+{
+ int i, count = mac_asc_samplespersec / HZ;
+ __u32 flags;
+
+ /*
+ * we neither want a sound buffer overflow nor underflow, so we need to match
+ * the number of samples per timer interrupt as exactly as possible.
+ * using the asc interrupt will give better results in the future
+ * ...and the possibility to use a real sample (a boingy noise, maybe...)
+ */
+
+ save_flags( flags );
+ cli();
+
+ del_timer( &mac_sound_timer );
+
+ if ( mac_bell_duration-- > 0 )
+ {
+ for ( i = 0; i < count; i++ )
X {
- asc_base[ASC_FREQ(i,0)]=0x00;
- asc_base[ASC_FREQ(i,1)]=20;
- asc_base[ASC_FREQ(i,2)]=0x00;
- asc_base[ASC_FREQ(i,3)]=20;
- asc_base[ASC_FREQ(i,4)]=(asc_pulses>>24)&0xFF;
- asc_base[ASC_FREQ(i,5)]=(asc_pulses>>16)&0xFF;
- asc_base[ASC_FREQ(i,6)]=(asc_pulses>>8)&0xFF;
- asc_base[ASC_FREQ(i,7)]=(asc_pulses>>0)&0xFF;
- }
- asc_base[ASC_CHAN]=0x03;
- asc_base[ASC_VOLUME]=128;
- asc_base[ASC_MODE]=ASC_MODE_SAMPLE;
- asc_base[ASC_ENABLE]=ASC_ENABLE_SAMPLE;
- if (ticks) {
- sound_timer.expires = jiffies + ticks;
- add_timer( &sound_timer );
+ mac_bell_phase += mac_bell_phasepersample;
+ mac_asc_regs[ 0 ] = mac_asc_wave_tab[ mac_bell_phase & ( sizeof( mac_asc_wave_tab ) - 1 ) ];
X }
- } else {
- nosound( 0 );
+ mac_sound_timer.expires = jiffies + 1;
+ add_timer( &mac_sound_timer );
X }
- restore_flags(flags);
+ else
+ mac_asc_regs[ 0x801 ] = 0;
+
+ restore_flags( flags );
X }
X
-
-static void nosound( unsigned long ignored )
+/*
+ * AV code - please fill in.
+ */
+static void mac_av_start_bell( unsigned int freq, unsigned int length, unsigned int volume )
X {
- asc_base[ASC_ENABLE]=0;
-}
+}
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/m68k/mac/macints.c linux/arch/m68k/mac/macints.c
--- v2.2.0-pre4/linux/arch/m68k/mac/macints.c Tue Dec 22 14:16:54 1998
+++ linux/arch/m68k/mac/macints.c Tue Jan 5 11:20:43 1999
@@ -163,6 +163,13 @@
X static unsigned long *mac_irqs[8];
X
X /*
+ * Some special nutcases ...
+ */
+
+static unsigned long mac_ide_irqs = 0;
+static unsigned long nubus_stuck_events = 0;
+
+/*
X * VIA/RBV/OSS/PSC register base pointers
X */
X
@@ -217,9 +224,13 @@
X static void via_do_nubus(int slot, void *via, struct pt_regs *regs);
X
X /* #define DEBUG_MACINTS */
-/* #define DEBUG_NUBUS_INT */
+
+#define DEBUG_SPURIOUS
+#define DEBUG_NUBUS_SPURIOUS
+#define DEBUG_NUBUS_INT
+
X /* #define DEBUG_VIA */
-/* #define DEBUG_VIA_NUBUS */
+#define DEBUG_VIA_NUBUS
X
X void mac_init_IRQ(void)
X {
@@ -351,6 +362,12 @@
X mac_irqs[7] = &nubus_irqs[0];
X
X /*
+ * Nubus Macs: turn off the Nubus dispatch interrupt for now
+ */
+
+ mac_turnoff_irq(IRQ_MAC_NUBUS);
+
+ /*
X * AV Macs: shutup the PSC ints
X */
X if (macintosh_config->ident == MAC_MODEL_C660
@@ -430,8 +447,10 @@
X return 0;
X }
X
- /* add similar hack for Nubus pseudo-irq here - hide nubus_request_irq */
-
+ /*
+ * code below: only for VIA irqs currently
+ * add similar hack for Nubus pseudo-irq here - hide nubus_request_irq
+ */
X via = (volatile unsigned char *) via_table[srcidx];
X if (!via)
X return -EINVAL;
@@ -697,12 +716,18 @@
X return (pending);
X }
X
+/*
+ * for /proc/interrupts: log interrupt stats broken down by
+ * autovector int first, then by actual interrupt source.
+ */
+
X int mac_get_irq_list (char *buf)
X {
X int i, len = 0;
X int srcidx, irqidx;
X
X for (i = VIA1_SOURCE_BASE; i < NUM_MAC_SOURCES+8; ++i) {
+ /* XXX fixme: IRQ_SRC_MASK should cover VIA1 - Nubus */
X srcidx = ((i & IRQ_SRC_MASK)>>3) - 1;
X irqidx = (i & IRQ_IDX_MASK);
X
@@ -767,6 +792,32 @@
X }
X if (num_spurious)
X len += sprintf(buf+len, "spurio.: %10u\n", num_spurious);
+
+ /*
+ * XXX Fixme: Nubus sources are never logged above ...
+ */
+
+ len += sprintf(buf+len, "Nubus interrupts:\n");
+
+ for (i = 0; i < 7; i++) {
+ if (nubus_handler[i].handler == nubus_wtf)
+ continue;
+ len += sprintf(buf+len, "nubus %01X: %10lu ",
+ i+9,
+ nubus_irqs[i]);
+ len += sprintf(buf+len, "%s\n",
+ nubus_param[i].devname);
+
+ }
+ len += sprintf(buf+len, "nubus spurious ints: %10lu\n",
+ nubus_irqs[7]);
+ len += sprintf(buf+len, "nubus stuck events : %10lu\n",
+ nubus_stuck_events);
+#ifdef CONFIG_BLK_DEV_IDE
+ len += sprintf(buf+len, "nubus/IDE interrupt: %10lu\n",
+ mac_ide_irqs);
+#endif
+
X return len;
X }
X
@@ -787,8 +838,9 @@
X
X void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs)
X {
-#ifdef DEBUG_VIA
- printk("Unexpected IRQ %d on device %p\n", irq, dev_id);
+#ifdef DEBUG_SPURIOUS
+ if (console_loglevel > 6)
+ printk("Unexpected IRQ %d on device %p\n", irq, dev_id);
X #endif
X }
X
@@ -864,6 +916,18 @@
X }
X
X /*
+ * Unexpected via interrupt
+ */
+
+void via_wtf(int slot, void *via, struct pt_regs *regs)
+{
+#ifdef DEBUG_SPURIOUS
+ if (console_loglevel > 6)
+ printk("Unexpected nubus event %d on via %p\n",slot,via);
+#endif
+}
+
+/*
X * The generic VIA interrupt routines (shamelessly stolen from Alan Cox's
X * via6522.c :-), disable/pending masks added.
X * The int *viaidx etc. is just to keep the prototype happy ...
@@ -1118,17 +1182,6 @@
X }
X
X /*
- * Unexpected via interrupt
- */
-
-void via_wtf(int slot, void *via, struct pt_regs *regs)
-{
-#ifdef DEBUG_VIA
- printk("Unexpected event %d on via %p\n",slot,via);
-#endif
-}
-
-/*
X * Nubus / SCSI interrupts; OSS style
X * The OSS is even more different than the RBV. OSS appears to stand for
X * Obscenely Screwed Silicon ...
@@ -1267,8 +1320,9 @@
X
X void nubus_wtf(int slot, void *via, struct pt_regs *regs)
X {
-#ifdef DEBUG_VIA_NUBUS
- printk("Unexpected interrupt on nubus slot %d\n",slot);
+#ifdef DEBUG_NUBUS_SPURIOUS
+ if (console_loglevel > 6)
+ printk("Unexpected interrupt on nubus slot %d\n",slot);
X #endif
X }
X
@@ -1282,9 +1336,10 @@
X int i;
X /* 1+2: compatibility with PSC ! */
X for (i = 1; i < 3; i++) /* currently only these two used */
- if (scc_handler[i].handler != mac_default_handler)
+ if (scc_handler[i].handler != mac_default_handler) {
X (scc_handler[i].handler)(i, scc_handler[i].dev_id, regs);
-
+ scc_irqs[i]++;
+ }
X }
X
X /*
@@ -1426,6 +1481,7 @@
X if (!nubus_active && !via2_is_oss) {
X request_irq(IRQ_MAC_NUBUS, via_do_nubus, IRQ_FLG_LOCK,
X "nubus dispatch", via_do_nubus);
+ mac_turnon_irq(IRQ_MAC_NUBUS);
X }
X
X nubus_active|=1<<slot;
@@ -1475,6 +1531,7 @@
X * IDE interrupt hook
X */
X extern void (*mac_ide_intr_hook)(int, void *, struct pt_regs *);
+extern int (*mac_ide_irq_p_hook)(void);
X #endif
X
X /*
@@ -1482,13 +1539,13 @@
X */
X static void via_do_nubus(int slot, void *via, struct pt_regs *regs)
X {
- unsigned char map;
+ unsigned char map, allints;
X int i;
X int ct=0;
-
-/* printk("nubus interrupt\n");*/
+ int ide_pending = 0;
X
X /* lock the nubus interrupt */
+ /* That's just 'clear Nubus IRQ bit in VIA2' BTW. Pretty obsolete ? */
X if (via2_is_rbv)
X via_write(rbv_regp, rIFR, 0x82);
X else
@@ -1496,37 +1553,69 @@
X
X #ifdef CONFIG_BLK_DEV_MAC_IDE
X /* IDE hack */
- if (mac_ide_intr_hook)
+ if (mac_ide_intr_hook) {
X /* 'slot' is lacking the machspec bit in 2.0 */
X /* need to pass proper dev_id = hwgroup here */
X mac_ide_intr_hook(IRQ_MAC_NUBUS, via, regs);
+ mac_ide_irqs++;
+ }
X #endif
X
X while(1)
X {
X if (via2_is_rbv)
- map = ~via_read(rbv_regp, rBufA);
+ allints = ~via_read(rbv_regp, rBufA);
X else
- map = ~via_read(via2_regp, vBufA);
+ allints = ~via_read(via2_regp, vBufA);
X
-#ifdef DEBUG_NUBUS_INT
- printk("nubus_irq: map %x mask %x\n", map, nubus_active);
+#ifdef CONFIG_BLK_DEV_MAC_IDE
+ if (mac_ide_irq_p_hook)
+ ide_pending = mac_ide_irq_p_hook();
X #endif
X
- if( (map = (map&nubus_active)) ==0 ) {
-#ifdef DEBUG_NUBUS_INT
- printk("nubus_irq: nothing pending, map %x mask %x\n",
- map, nubus_active);
+ if ( (map = (allints&nubus_active)) == 0
+#ifdef CONFIG_BLK_DEV_MAC_IDE
+ && !ide_pending
X #endif
- nubus_irqs[7]++;
+ )
+ {
+ if (ct == 0) {
+#ifdef DEBUG_VIA_NUBUS
+ if (console_loglevel > 5)
+ printk("nubus_irq: nothing pending, map %x mask %x active %x\n",
+ allints, nubus_active, map);
+#endif
+ nubus_irqs[7]++;
+ }
+ /* clear it */
+ if (allints)
+ if (via2_is_rbv)
+ via_write(rbv_regp, rIFR, 0x02);
+ else
+ via_write(via2_regp, vIFR, 0x02);
X break;
X }
X
+#ifdef DEBUG_VIA_NUBUS
+ if (console_loglevel > 6)
+ printk("nubus_irq: map %x mask %x active %x\n",
+ allints, nubus_active, map);
+#endif
+
+#ifdef CONFIG_BLK_DEV_MAC_IDE
+ if (mac_ide_intr_hook && ide_pending) {
+ mac_ide_intr_hook(IRQ_MAC_NUBUS, via, regs);
+ mac_ide_irqs++;
+ }
+#endif
+
X if(ct++>2)
X {
-#ifdef DEBUG_NUBUS_INT
- printk("nubus stuck events - %d/%d\n", map, nubus_active);
-#endif
+ if (console_loglevel > 5)
+ printk("nubus stuck events - %x/%x/%x ide %x\n",
+ allints, nubus_active, map, ide_pending);
+ nubus_stuck_events++;
+
X return;
X }
X
@@ -1583,12 +1672,14 @@
X printk("nubus_irq: map %x mask %x\n", map, nubus_active);
X #endif
X if( (map = (map&nubus_active)) ==0 ) {
+ if (ct == 0) {
X #ifdef CONFIG_BLK_DEV_MAC_IDE
- if (!mac_ide_intr_hook)
- printk("nubus_irq: nothing pending, map %x mask %x\n",
- map, nubus_active);
+ if (!mac_ide_intr_hook)
+ printk("nubus_irq: nothing pending, map %x mask %x\n",
+ map, nubus_active);
X #endif
- nubus_irqs[7]++;
+ nubus_irqs[7]++;
+ }
X break;
X }
X
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/m68k/vmlinux.lds linux/arch/m68k/vmlinux.lds
--- v2.2.0-pre4/linux/arch/m68k/vmlinux.lds Tue Feb 17 13:12:45 1998
+++ linux/arch/m68k/vmlinux.lds Tue Jan 5 11:20:43 1999
@@ -35,6 +35,9 @@
X
X _edata = .; /* End of data section */
X
+ . = ALIGN(16);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
X . = ALIGN(4096); /* Init code and data */
X __init_begin = .;
X .text.init : { *(.text.init) }
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/mips/kernel/traps.c linux/arch/mips/kernel/traps.c
--- v2.2.0-pre4/linux/arch/mips/kernel/traps.c Fri Oct 23 22:01:19 1998
+++ linux/arch/mips/kernel/traps.c Tue Jan 5 11:13:56 1999
@@ -6,6 +6,7 @@
X *
X * Copyright 1994, 1995, 1996, 1997, 1998 by Ralf Baechle
X * Modified for R3000 by Paul M. Antoine, 1995, 1996
+ * Complete output from die() by Ulf Carlsson, 1998
X */
X #include <linux/config.h>
X #include <linux/init.h>
@@ -80,50 +81,61 @@
X * This routine abuses get_user()/put_user() to reference pointers
X * with at least a bit of error checking ...
X */
-void show_registers(char * str, struct pt_regs * regs, long err)
+void show_stack(unsigned int *sp)
X {
- int i;
- int *stack;
- u32 *sp, *pc, addr, module_start, module_end;
- extern char start_kernel, _etext;
+ int i;
+ unsigned int *stack;
X
- sp = (u32 *)regs->regs[29];
- pc = (u32 *)regs->cp0_epc;
+ stack = sp;
+ i = 0;
X
- show_regs(regs);
+ printk("Stack:");
+ while ((unsigned long) stack & (PAGE_SIZE - 1)) {
+ unsigned long stackdata;
SHAR_EOF
true || echo 'restore of patch-2.2.0-pre5 failed'
fi
echo 'End of part 01'
echo 'File patch-2.2.0-pre5 is continued in part 02'
echo 02 > _shar_seq_.tmp
exit 0

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

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to
Archive-name: v2.1/patch-2.2.0-pre5/part05

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


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

# file patch-2.2.0-pre5 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 05; 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.0-pre5'
else
echo 'x - continuing with patch-2.2.0-pre5'


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

- "sample[%d] = %d\n",
- i, header->hdr.ms.SampleNumber[i]);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_DATA, "msample sample[%d] = %d\n",
+ i, header->hdr.ms.SampleNumber[i]);
X }
X
X return (0);
@@ -1473,21 +1450,16 @@
X
X
X static int
-wavefront_send_drum (struct wf_config *hw, wavefront_patch_info *header)
+wavefront_send_drum (wavefront_patch_info *header)
X
X {
X unsigned char drumbuf[WF_DRUM_BYTES];
X wavefront_drum *drum = &header->hdr.d;
X int i;
X
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_LOAD_PATCH) {
- printk (KERN_DEBUG
- "WaveFront: downloading edrum for MIDI "
- "note %d, patch = %d\n",
- header->number, drum->PatchNumber);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_LOAD_PATCH, "downloading edrum for MIDI "
+ "note %d, patch = %d\n",
+ header->number, drum->PatchNumber);
X
X drumbuf[0] = header->number & 0x7f;
X
@@ -1495,8 +1467,8 @@
X munge_int32 (((unsigned char *)drum)[i], &drumbuf[1+(i*2)], 2);
X }
X
- if (wavefront_cmd (hw, WFC_DOWNLOAD_EDRUM_PROGRAM, 0, drumbuf)) {
- printk (KERN_ERR "WaveFront: download drum failed.\n");
+ if (wavefront_cmd (WFC_DOWNLOAD_EDRUM_PROGRAM, 0, drumbuf)) {
+ printk (KERN_ERR LOGNAME "download drum failed.\n");
X return -(EIO);
X }
X
@@ -1504,32 +1476,32 @@
X }
X
X static int
-wavefront_find_free_sample (struct wf_config *hw)
+wavefront_find_free_sample (void)
X
X {
X int i;
X
X for (i = 0; i < WF_MAX_SAMPLE; i++) {
- if (!(hw->sample_status[i] & WF_SLOT_FILLED)) {
+ if (!(dev.sample_status[i] & WF_SLOT_FILLED)) {
X return i;
X }
X }
- printk (KERN_WARNING "WaveFront: no free sample slots!\n");
+ printk (KERN_WARNING LOGNAME "no free sample slots!\n");
X return -1;
X }
X
X static int
-wavefront_find_free_patch (struct wf_config *hw)
+wavefront_find_free_patch (void)
X
X {
X int i;
X
X for (i = 0; i < WF_MAX_PATCH; i++) {
- if (!(hw->patch_status[i] & WF_SLOT_FILLED)) {
+ if (!(dev.patch_status[i] & WF_SLOT_FILLED)) {
X return i;
X }
X }
- printk (KERN_WARNING "WaveFront: no free patch slots!\n");
+ printk (KERN_WARNING LOGNAME "no free patch slots!\n");
X return -1;
X }
X
@@ -1562,8 +1534,7 @@
X }
X
X static int
-wavefront_load_gus_patch (struct wf_config *hw,
- int dev, int format, const char *addr,
+wavefront_load_gus_patch (int devno, int format, const char *addr,
X int offs, int count, int pmgr_flag)
X {
X struct patch_info guspatch;
@@ -1581,14 +1552,14 @@
X copy_from_user (&((char *) &guspatch)[offs],
X &(addr)[offs], sizeof_patch - offs);
X
- if ((i = wavefront_find_free_patch (hw)) == -1) {
+ if ((i = wavefront_find_free_patch ()) == -1) {
X return -EBUSY;
X }
X pat.number = i;
X pat.subkey = WF_ST_PATCH;
X patp = &pat.hdr.p;
X
- if ((i = wavefront_find_free_sample (hw)) == -1) {
+ if ((i = wavefront_find_free_sample ()) == -1) {
X return -EBUSY;
X }
X samp.number = i;
@@ -1644,7 +1615,7 @@
X progp->layer[0].mix_level=127 /* guspatch.volume */;
X progp->layer[0].split_type=0;
X progp->layer[0].split_point=0;
- progp->layer[0].updown=0;
+ progp->layer[0].play_below=0;
X
X for (i = 1; i < 4; i++) {
X progp->layer[i].mute=0;
@@ -1685,11 +1656,11 @@
X
X /* Now ship it down */
X
- wavefront_send_sample (hw, &samp,
+ wavefront_send_sample (&samp,
X (unsigned short *) &(addr)[sizeof_patch],
X (guspatch.mode & WAVE_UNSIGNED) ? 1:0);
- wavefront_send_patch (hw, &pat);
- wavefront_send_program (hw, &prog);
+ wavefront_send_patch (&pat);
+ wavefront_send_program (&prog);
X
X /* Now pan as best we can ... use the slave/internal MIDI device
X number if it exists (since it talks to the WaveFront), or the
@@ -1697,8 +1668,8 @@
X */
X
X #ifdef CONFIG_MIDI
- if (hw->mididev > 0) {
- midi_synth_controller (hw->mididev, guspatch.instr_no, 10,
+ if (dev.mididev > 0) {
+ midi_synth_controller (dev.mididev, guspatch.instr_no, 10,
X ((guspatch.panning << 4) > 127) ?
X 127 : (guspatch.panning << 4));
X }
@@ -1707,60 +1678,26 @@
X return(0);
X }
X
-int
-wavefront_load_patch (int dev, int format, const char *addr,
- int offs, int count, int pmgr_flag)
-{
-
- struct wf_config *hw = &wavefront_configuration;
- wavefront_patch_info header;
-
- if (format == SYSEX_PATCH) { /* Handled by midi_synth.c */
- if (midi_load_patch == NULL) {
- printk (KERN_ERR
- "WaveFront: SYSEX not loadable: "
- "no midi patch loader!\n");
- return -(EINVAL);
- }
- return midi_load_patch (dev, format, addr,
- offs, count, pmgr_flag);
-
- } else if (format == GUS_PATCH) {
- return wavefront_load_gus_patch (hw, dev, format,
- addr, offs, count, pmgr_flag);
+static int
+wavefront_load_patch (const char *addr)
X
- } else if (format != WAVEFRONT_PATCH) {
- printk (KERN_ERR "WaveFront: unknown patch format %d\n", format);
- return -(EINVAL);
- }
X
- if (count < sizeof (wavefront_patch_info)) {
- printk (KERN_ERR "WaveFront: sample header too short\n");
+{
+ wavefront_patch_info header;
+
+ if (copy_from_user (&header, addr, sizeof(wavefront_patch_info) -
+ sizeof(wavefront_any))) {
+ printk (KERN_WARNING LOGNAME "bad address for load patch.\n");
X return -(EINVAL);
X }
X
- /* copied in so far: `offs' bytes from `addr'. We shouldn't copy
- them in again, and they correspond to header->key and header->devno.
- So now, copy the rest of the wavefront_patch_info struct, except
- for the 'hdr' field, since this is handled via indirection
- through the 'hdrptr' field.
- */
-
- copy_from_user (&((char *) &header)[offs], &(addr)[offs],
- sizeof(wavefront_patch_info) -
- sizeof(wavefront_any) - offs);
-
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_LOAD_PATCH) {
- printk (KERN_DEBUG "WaveFront: download "
- "Sample type: %d "
- "Sample number: %d "
- "Sample size: %d\n",
- header.subkey,
- header.number,
- header.size);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_LOAD_PATCH, "download "
+ "Sample type: %d "
+ "Sample number: %d "
+ "Sample size: %d\n",
+ header.subkey,
+ header.number,
+ header.size);
X
X switch (header.subkey) {
X case WF_ST_SAMPLE: /* sample or sample_header, based on patch->size */
@@ -1769,7 +1706,7 @@
X (unsigned char *) header.hdrptr,
X sizeof (wavefront_sample));
X
- return wavefront_send_sample (hw, &header, header.dataptr, 0);
+ return wavefront_send_sample (&header, header.dataptr, 0);
X
X case WF_ST_MULTISAMPLE:
X
@@ -1777,7 +1714,7 @@
X (unsigned char *) header.hdrptr,
X sizeof (wavefront_multisample));
X
- return wavefront_send_multisample (hw, &header);
+ return wavefront_send_multisample (&header);
X
X
X case WF_ST_ALIAS:
@@ -1786,31 +1723,31 @@
X (unsigned char *) header.hdrptr,
X sizeof (wavefront_alias));
X
- return wavefront_send_alias (hw, &header);
+ return wavefront_send_alias (&header);
X
X case WF_ST_DRUM:
X copy_from_user ((unsigned char *) &header.hdr.d,
X (unsigned char *) header.hdrptr,
X sizeof (wavefront_drum));
X
- return wavefront_send_drum (hw, &header);
+ return wavefront_send_drum (&header);
X
X case WF_ST_PATCH:
X copy_from_user ((unsigned char *) &header.hdr.p,
X (unsigned char *) header.hdrptr,
X sizeof (wavefront_patch));
X
- return wavefront_send_patch (hw, &header);
+ return wavefront_send_patch (&header);
X
X case WF_ST_PROGRAM:
X copy_from_user ((unsigned char *) &header.hdr.pr,
X (unsigned char *) header.hdrptr,
X sizeof (wavefront_program));
X
- return wavefront_send_program (hw, &header);
+ return wavefront_send_program (&header);
X
X default:
- printk (KERN_ERR "WaveFront: unknown patch type %d.\n",
+ printk (KERN_ERR LOGNAME "unknown patch type %d.\n",
X header.subkey);
X return -(EINVAL);
X }
@@ -1855,155 +1792,248 @@
X }
X
X static int
-wavefront_synth_control (int dev, int cmd, caddr_t arg)
+wavefront_synth_control (int cmd, wavefront_control *wc)
X
X {
- struct wf_config *hw = &wavefront_configuration;
- wavefront_control wc;
X unsigned char patchnumbuf[2];
X int i;
X
- copy_from_user (&wc, arg, sizeof (wc));
+ DPRINT (WF_DEBUG_CMD, "synth control with "
+ "cmd 0x%x\n", wc->cmd);
X
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_CMD) {
- printk (KERN_DEBUG "WaveFront: synth control with "
- "cmd 0x%x\n", wc.cmd);
- }
-#endif WF_DEBUG
-
- /* special case handling of or for various commands */
+ /* Pre-handling of or for various commands */
X
- switch (wc.cmd) {
+ switch (wc->cmd) {
X case WFC_DISABLE_INTERRUPTS:
- printk (KERN_INFO "WaveFront: interrupts disabled.\n");
- outb (0x80|0x20, hw->control_port);
- hw->interrupts_on = 0;
+ printk (KERN_INFO LOGNAME "interrupts disabled.\n");
+ outb (0x80|0x20, dev.control_port);
+ dev.interrupts_on = 0;
X return 0;
X
X case WFC_ENABLE_INTERRUPTS:
- printk (KERN_INFO "WaveFront: interrupts enabled.\n");
- outb (0x80|0x20|0x40, hw->control_port);
- hw->interrupts_on = 1;
+ printk (KERN_INFO LOGNAME "interrupts enabled.\n");
+ outb (0x80|0x40|0x20, dev.control_port);
+ dev.interrupts_on = 1;
X return 0;
X
X case WFC_INTERRUPT_STATUS:
- wc.rbuf[0] = hw->interrupts_on;
+ wc->rbuf[0] = dev.interrupts_on;
X return 0;
X
X case WFC_ROMSAMPLES_RDONLY:
- hw->rom_samples_rdonly = wc.wbuf[0];
- wc.status = 0;
+ dev.rom_samples_rdonly = wc->wbuf[0];
+ wc->status = 0;
X return 0;
X
X case WFC_IDENTIFY_SLOT_TYPE:
- i = wc.wbuf[0] | (wc.wbuf[1] << 7);
+ i = wc->wbuf[0] | (wc->wbuf[1] << 7);
X if (i <0 || i >= WF_MAX_SAMPLE) {
- printk (KERN_WARNING "WaveFront: invalid slot ID %d\n",
+ printk (KERN_WARNING LOGNAME "invalid slot ID %d\n",
X i);
- wc.status = EINVAL;
+ wc->status = EINVAL;
X return 0;
X }
- wc.rbuf[0] = hw->sample_status[i];
- wc.status = 0;
+ wc->rbuf[0] = dev.sample_status[i];
+ wc->status = 0;
X return 0;
X
X case WFC_DEBUG_DRIVER:
- hw->debug = wc.wbuf[0];
- printk (KERN_INFO "WaveFront: debug = 0x%x\n", hw->debug);
+ dev.debug = wc->wbuf[0];
+ printk (KERN_INFO LOGNAME "debug = 0x%x\n", dev.debug);
X return 0;
X
X case WFC_FX_IOCTL:
- wffx_ioctl (hw, (wavefront_fx_info *) &wc.wbuf[0]);
+ wffx_ioctl ((wavefront_fx_info *) &wc->wbuf[0]);
X return 0;
X
X case WFC_UPLOAD_PATCH:
- munge_int32 (*((UINT32 *) wc.wbuf), patchnumbuf, 2);
- memcpy (wc.wbuf, patchnumbuf, 2);
+ munge_int32 (*((UINT32 *) wc->wbuf), patchnumbuf, 2);
+ memcpy (wc->wbuf, patchnumbuf, 2);
X break;
X
X case WFC_UPLOAD_MULTISAMPLE:
+ /* multisamples have to be handled differently, and
+ cannot be dealt with properly by wavefront_cmd() alone.
+ */
+ wc->status = wavefront_fetch_multisample
+ ((wavefront_patch_info *) wc->rbuf);
+ return 0;
+
X case WFC_UPLOAD_SAMPLE_ALIAS:
- printk (KERN_INFO "WaveFront: support for various uploads "
+ printk (KERN_INFO LOGNAME "support for sample alias upload "
X "being considered.\n");
- wc.status = EINVAL;
+ wc->status = EINVAL;
X return -EINVAL;
X }
X
- wc.status = wavefront_cmd (hw, wc.cmd, wc.rbuf, wc.wbuf);
+ wc->status = wavefront_cmd (wc->cmd, wc->rbuf, wc->wbuf);
X
- /* Special case handling of certain commands.
+ /* Post-handling of certain commands.
X
X In particular, if the command was an upload, demunge the data
X so that the user-level doesn't have to think about it.
X */
X
- if (wc.status == 0) {
- switch (wc.cmd) {
+ if (wc->status == 0) {
+ switch (wc->cmd) {
X /* intercept any freemem requests so that we know
X we are always current with the user-level view
X of things.
X */
X
X case WFC_REPORT_FREE_MEMORY:
- hw->freemem = demunge_int32 (wc.rbuf, 4);
+ dev.freemem = demunge_int32 (wc->rbuf, 4);
X break;
X
X case WFC_UPLOAD_PATCH:
- demunge_buf (wc.rbuf, wc.rbuf, WF_PATCH_BYTES);
+ demunge_buf (wc->rbuf, wc->rbuf, WF_PATCH_BYTES);
X break;
X
X case WFC_UPLOAD_PROGRAM:
- demunge_buf (wc.rbuf, wc.rbuf, WF_PROGRAM_BYTES);
+ demunge_buf (wc->rbuf, wc->rbuf, WF_PROGRAM_BYTES);
X break;
X
X case WFC_UPLOAD_EDRUM_PROGRAM:
- demunge_buf (wc.rbuf, wc.rbuf, WF_DRUM_BYTES - 1);
+ demunge_buf (wc->rbuf, wc->rbuf, WF_DRUM_BYTES - 1);
X break;
X
X case WFC_UPLOAD_SAMPLE_HEADER:
- process_sample_hdr (wc.rbuf);
+ process_sample_hdr (wc->rbuf);
X break;
X
- case WFC_UPLOAD_MULTISAMPLE:
X case WFC_UPLOAD_SAMPLE_ALIAS:
- printk (KERN_INFO "WaveFront: support for "
- "various uploads "
+ printk (KERN_INFO LOGNAME "support for "
+ "sample aliases still "
X "being considered.\n");
X break;
X
X case WFC_VMIDI_OFF:
- virtual_midi_disable (hw->mididev);
+ if (virtual_midi_disable () < 0) {
+ return -(EIO);
+ }
X break;
X
X case WFC_VMIDI_ON:
- virtual_midi_enable (hw->mididev, 0);
- break;
-
+ if (virtual_midi_enable () < 0) {
+ return -(EIO);


+ }
X break;
X }
X }

X
- /* XXX It would be nice to avoid a complete copy of the whole
- struct sometimes. But I think its fast enough that this
- is a low priority fix.
- */
+ return 0;
+}
X
- copy_to_user (arg, &wc, sizeof (wc));
+
+/***********************************************************************/
+/* WaveFront: Linux file system interface (for access via raw synth) */
+/***********************************************************************/
+
+static loff_t
+wavefront_llseek(struct file *file, loff_t offset, int origin)
+{
+ return -ESPIPE;
+}
+
+static int
+wavefront_open (struct inode *inode, struct file *file)
+{
+ /* XXX fix me */
+ dev.opened = file->f_flags;
+ MOD_INC_USE_COUNT;


X return 0;
X }
X

+static int
+wavefront_release(struct inode *inode, struct file *file)
+{
+ dev.opened = 0;
+ dev.debug = 0;
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+static int
+wavefront_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ wavefront_control wc;
+ int err;
+
+ switch (cmd) {
+
+ case WFCTL_WFCMD:
+ copy_from_user (&wc, (void *) arg, sizeof (wc));
+
+ if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
+ copy_to_user ((void *) arg, &wc, sizeof (wc));
+ }
+
+ return err;
+
+ case WFCTL_LOAD_SPP:
+ return wavefront_load_patch ((const char *) arg);
+
+ default:
+ printk (KERN_WARNING LOGNAME "invalid ioctl %#x\n", cmd);
+ return -(EINVAL);
+
+ }
+ return 0;
+}
+
+static /*const*/ struct file_operations wavefront_fops = {
+ &wavefront_llseek,
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* readdir */
+ NULL, /* poll */
+ &wavefront_ioctl,
+ NULL, /* mmap */
+ &wavefront_open,
+ NULL, /* flush */
+ &wavefront_release,
+ NULL, /* fsync */
+ NULL, /* fasync */
+ NULL, /* check_media_change */
+ NULL, /* revalidate */
+ NULL, /* lock */
+};
+
X
-/***********************************************************************
-WaveFront: MIDI synth interface
-***********************************************************************/
+/***********************************************************************/
+/* WaveFront: OSS installation and support interface */
+/***********************************************************************/
+
+#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
+
+static struct synth_info wavefront_info =
+{"Turtle Beach WaveFront", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_WAVEFRONT,
+ 0, 32, 0, 0, SYNTH_CAP_INPUT};
+
+static int
+wavefront_oss_open (int devno, int mode)
+
+{
+ dev.opened = mode;
+ return 0;
+}
X
+static void
+wavefront_oss_close (int devno)
+
+{
+ dev.opened = 0;
+ dev.debug = 0;
+ return;
+}
X
X static int
-wavefront_ioctl (int dev, unsigned int cmd, caddr_t arg)
+wavefront_oss_ioctl (int devno, unsigned int cmd, caddr_t arg)
+
X {
- wf_config *hw = &wavefront_configuration;
- unsigned char rbuf[4];
+ wavefront_control wc;
+ int err;
X
X switch (cmd) {
X case SNDCTL_SYNTH_INFO:
@@ -2013,183 +2043,156 @@
X break;
X
X case SNDCTL_SEQ_RESETSAMPLES:
- printk (KERN_WARNING
- "WaveFront: cannot reset sample status in kernel.\n");
+ printk (KERN_WARNING LOGNAME "driver cannot reset samples.\n");
X return 0; /* don't force an error */
X break;
X
X case SNDCTL_SEQ_PERCMODE:
- /* XXX does this correspond to anything obvious ?*/
X return 0; /* don't force an error */
X break;
X
X case SNDCTL_SYNTH_MEMAVL:
- if (wavefront_cmd (hw, WFC_REPORT_FREE_MEMORY, rbuf, 0) != 0) {
- printk (KERN_ERR
- "WaveFront: cannot get free memory size\n");
- return 0;
+ if ((dev.freemem = wavefront_freemem ()) < 0) {
+ printk (KERN_ERR LOGNAME "cannot get memory size\n");
+ return -EIO;
X } else {
- hw->freemem = demunge_int32 (rbuf, 4);
- return hw->freemem;
+ return dev.freemem;
X }
+ break;
X
X case SNDCTL_SYNTH_CONTROL:
- return wavefront_synth_control (dev, cmd, arg);
+ copy_from_user (&wc, arg, sizeof (wc));
+
+ if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
+ copy_to_user (arg, &wc, sizeof (wc));
+ }
+
+ return err;
X
X default:
X return -(EINVAL);
X }
X }
X
-static int
-wavefront_open (int dev, int mode)
-
+int
+wavefront_oss_load_patch (int devno, int format, const char *addr,
+ int offs, int count, int pmgr_flag)
X {
- struct wf_config *hw = &wavefront_configuration;
X
- if (hw->opened) {
- printk (KERN_WARNING "WaveFront: warning: device in use\n");
- }
+ if (format == SYSEX_PATCH) { /* Handled by midi_synth.c */
+ if (midi_load_patch == NULL) {
+ printk (KERN_ERR LOGNAME
+ "SYSEX not loadable: "
+ "no midi patch loader!\n");
+ return -(EINVAL);
+ }
X
- hw->opened = mode;
- return (0);
-}
+ return midi_load_patch (devno, format, addr,
+ offs, count, pmgr_flag);
X
-static void wavefront_close (int dev)
-{
- struct wf_config *hw = &wavefront_configuration;
+ } else if (format == GUS_PATCH) {
+ return wavefront_load_gus_patch (devno, format,
+ addr, offs, count, pmgr_flag);
X
-#ifdef WF_STATS
- int i;
- printk ("Status during loop: %ld\n", hw->status_found_during_loop);
- for (i = 0; i < 4; i++) {
- printk ("Status during sleep[%d]: %ld\n",
- i, hw->status_found_during_sleep[i]);
+ } else if (format != WAVEFRONT_PATCH) {
+ printk (KERN_ERR LOGNAME "unknown patch format %d\n", format);
+ return -(EINVAL);
X }
-#endif WF_STATS
- hw->opened = 0;
- hw->debug = 0;
-
- return;
-}
X
-static void wavefront_aftertouch (int dev, int channel, int pressure)
-{
- midi_synth_aftertouch (wavefront_configuration.mididev,channel,pressure);
-};
+ if (count < sizeof (wavefront_patch_info)) {
+ printk (KERN_ERR LOGNAME "sample header too short\n");
+ return -(EINVAL);
+ }
X
-static void wavefront_bender (int dev, int chn, int value)
-{
- midi_synth_bender (wavefront_configuration.mididev, chn, value);
-};
+ /* "addr" points to a user-space wavefront_patch_info */
X
-static void wavefront_controller (int dev, int channel, int ctrl_num, int value)
-{
- if(ctrl_num==CTRL_PITCH_BENDER) wavefront_bender(0,channel,value);
- midi_synth_controller (wavefront_configuration.mididev,
- channel,ctrl_num,value);
-};
+ return wavefront_load_patch (addr);
+}
X
-static void wavefront_panning(int dev, int channel, int pressure)
+static struct synth_operations wavefront_operations =
X {
- midi_synth_controller (wavefront_configuration.mididev,
- channel,CTL_PAN,pressure);
+ "WaveFront",
+ &wavefront_info,
+ 0,
+ SYNTH_TYPE_SAMPLE,
+ SAMPLE_TYPE_WAVEFRONT,
+ wavefront_oss_open,
+ wavefront_oss_close,
+ wavefront_oss_ioctl,
+
+ midi_synth_kill_note,
+ midi_synth_start_note,
+ midi_synth_set_instr,
+ midi_synth_reset,
+ NULL, /* hw_control */
+ midi_synth_load_patch,
+ midi_synth_aftertouch,
+ midi_synth_controller,
+ midi_synth_panning,
+ NULL, /* volume method */
+ midi_synth_bender,
+ NULL, /* alloc voice */
+ midi_synth_setup_voice
X };
+#endif OSS_SUPPORT_SEQ
X
-static int wavefront_set_instr (int dev, int channel, int instr_no)
-{
- return(midi_synth_set_instr (wavefront_configuration.mididev,
- channel,instr_no));
-};
+#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_STATIC_INSTALL
X
-static int wavefront_kill_note (int dev, int channel, int note, int volume)
-{
- if (note==255)
- return (midi_synth_start_note (wavefront_configuration.mididev,
- channel, 0, 0));
- return(midi_synth_kill_note (wavefront_configuration.mididev,
- channel, note, volume));
-};
+void attach_wavefront (struct address_info *hw_config)
X
-static int wavefront_start_note (int dev, int channel, int note, int volume)
X {
- if (note==255) {
- midi_synth_aftertouch (wavefront_configuration.mididev,
- channel,volume);
- return(0);
- };
-
- if (volume==0) {
- volume=127;
- midi_synth_aftertouch
- (wavefront_configuration.mididev,
- channel,0);
- };
-
- midi_synth_start_note (wavefront_configuration.mididev,
- channel, note, volume);
- return(0);
-};
+ (void) install_wavefront ();
+}
X
-static void wavefront_setup_voice (int dev, int voice, int chn)
-{
-};
+int probe_wavefront (struct address_info *hw_config)
X
-static void wavefront_reset (int dev)


X {
- int i;
-

- for (i = 0; i < 16; i++) {
- midi_synth_kill_note (dev,i,0,0);
- };
-};
+ return !detect_wavefront (hw_config->irq, hw_config->io_base);
+}
X
-static struct synth_operations wavefront_operations =
+void unload_wavefront (struct address_info *hw_config)
X {
- "WaveFront",
- &wavefront_info,
- 0,
- SYNTH_TYPE_SAMPLE,
- SAMPLE_TYPE_WAVEFRONT,
- wavefront_open,
- wavefront_close,
- wavefront_ioctl,
- wavefront_kill_note,
- wavefront_start_note,
- wavefront_set_instr,
- wavefront_reset,
- NULL,
- wavefront_load_patch,
- wavefront_aftertouch,
- wavefront_controller,
- wavefront_panning,
- NULL,
- wavefront_bender,
- NULL,
- wavefront_setup_voice
-};
+ (void) uninstall_wavefront ();
+}
X
+#endif OSS_SUPPORT_STATIC_INSTALL
X
-/***********************************************************************
-WaveFront: OSS/Free and/or Linux kernel installation interface
-***********************************************************************/
+/***********************************************************************/
+/* WaveFront: Linux modular sound kernel installation interface */
+/***********************************************************************/
X
X void
X wavefrontintr (int irq, void *dev_id, struct pt_regs *dummy)
X {
- /* We don't use this handler except during device
- configuration. While the module is installed, the
- interrupt is used to signal MIDI interrupts, and is
- handled by the interrupt routine in wf_midi.c
- */
-
- wf_config *hw = (wf_config *) dev_id;
- hw->irq_ok = 1;
+ struct wf_config *hw = dev_id;
X
- if ((wavefront_status(hw) & STAT_INTR_WRITE) ||
- (wavefront_status(hw) & STAT_INTR_READ)) {
- wake_up (&hw->interrupt_sleeper);
+ /*
+ Some comments on interrupts. I attempted a version of this
+ driver that used interrupts throughout the code instead of
+ doing busy and/or sleep-waiting. Alas, it appears that once
+ the Motorola firmware is downloaded, the card *never*
+ generates an RX interrupt. These are successfully generated
+ during firmware loading, and after that wavefront_status()
+ reports that an interrupt is pending on the card from time
+ to time, but it never seems to be delivered to this
+ driver. Note also that wavefront_status() continues to
+ report that RX interrupts are enabled, suggesting that I
+ didn't goof up and disable them by mistake.
+
+ Thus, I stepped back to a prior version of
+ wavefront_wait(), the only place where this really
+ matters. Its sad, but I've looked through the code to check
+ on things, and I really feel certain that the Motorola
+ firmware prevents RX-ready interrupts.
+ */
+
+ if ((wavefront_status() & (STAT_INTR_READ|STAT_INTR_WRITE)) == 0) {
+ return;
X }
+
+ hw->irq_ok = 1;
+ hw->irq_cnt++;
+ wake_up_interruptible (&hw->interrupt_sleeper);
X }
X
X /* STATUS REGISTER
@@ -2202,16 +2205,6 @@
X 5 Host Tx Register empty (1=Empty)
X 6 Host Tx Interrupt Pending (1=Interrupt)
X 7 Unused
-
-11111001
- Rx Intr enable
- nothing to read from board
- no rx interrupt pending
- unused
- tx interrupt enabled
- space to transmit
- tx interrupt pending
-
X */
X
X int
@@ -2235,7 +2228,7 @@
X break;
X
X default:
- printk (KERN_WARNING "WaveFront: invalid IRQ %d\n", irq);
+ printk (KERN_WARNING LOGNAME "invalid IRQ %d\n", irq);
X bits = -1;
X }
X
@@ -2243,42 +2236,78 @@
X }
X
X void
-wavefront_should_cause_interrupt (wf_config *hw, int val, int port, int timeout)
+wavefront_should_cause_interrupt (int val, int port, int timeout)
X
X {
X unsigned long flags;
X
X save_flags (flags);
X cli();
- hw->irq_ok = 0;
+ dev.irq_ok = 0;
X outb (val,port);
- interruptible_sleep_on_timeout(&hw->interrupt_sleeper, timeout);
+ interruptible_sleep_on_timeout (&dev.interrupt_sleeper, timeout);
X restore_flags (flags);
X }
X
X static int
-wavefront_hw_reset (wf_config *hw)
+wavefront_hw_reset (void)
X
X {
X int bits;
X int hwv[2];
+ unsigned long irq_mask;
+ short reported_irq;
+
+ /* IRQ already checked in init_module() */
+
+ bits = wavefront_interrupt_bits (dev.irq);
+
+ printk (KERN_DEBUG LOGNAME "autodetecting WaveFront IRQ\n");
X
- /* Check IRQ is legal */
+ sti ();
X
- if ((bits = wavefront_interrupt_bits (hw->irq)) < 0) {
+ irq_mask = probe_irq_on ();
+
+ outb (0x0, dev.control_port);
+ outb (0x80 | 0x40 | bits, dev.data_port);
+ wavefront_should_cause_interrupt(0x80|0x40|0x10|0x1,
+ dev.control_port,
+ (reset_time*HZ)/100);
+
+ reported_irq = probe_irq_off (irq_mask);
+
+ if (reported_irq != dev.irq) {
+ if (reported_irq == 0) {
+ printk (KERN_ERR LOGNAME
+ "No unassigned interrupts detected "
+ "after h/w reset\n");
+ } else if (reported_irq < 0) {
+ printk (KERN_ERR LOGNAME
+ "Multiple unassigned interrupts detected "
+ "after h/w reset\n");
+ } else {
+ printk (KERN_ERR LOGNAME "autodetected IRQ %d not the "
+ "value provided (%d)\n", reported_irq,
+ dev.irq);
+ }
+ dev.irq = -1;
X return 1;
+ } else {
+ printk (KERN_INFO LOGNAME "autodetected IRQ at %d\n",
+ reported_irq);
X }
X
- if (request_irq (hw->irq, wavefrontintr,
- 0, "WaveFront", (void *) hw) < 0) {
- printk (KERN_WARNING "WaveFront: IRQ %d not available!\n",
- hw->irq);
+ if (request_irq (dev.irq, wavefrontintr,
+ SA_INTERRUPT|SA_SHIRQ,
+ "wavefront synth", &dev) < 0) {
+ printk (KERN_WARNING LOGNAME "IRQ %d not available!\n",
+ dev.irq);
X return 1;
X }
X
X /* try reset of port */
X
- outb (0x0, hw->control_port);
+ outb (0x0, dev.control_port);
X
X /* At this point, the board is in reset, and the H/W initialization
X register is accessed at the same address as the data port.
@@ -2291,8 +2320,8 @@
X
X 0 - Use the MIDI Input from the 26-pin WaveBlaster
X compatible header as the serial MIDI source
- 1 - Use the MIDI Input from the 9-pin D connector as the serial MIDI
- source.
+ 1 - Use the MIDI Input from the 9-pin D connector as the
+ serial MIDI source.
X
X Bits 5:3 - IRQ Selection
X 0 0 0 - IRQ 2/9
@@ -2316,7 +2345,7 @@
X plus external 9-pin MIDI interface selected
X */
X
- outb (0x80 | 0x40 | bits, hw->data_port);
+ outb (0x80 | 0x40 | bits, dev.data_port);
X
X /* CONTROL REGISTER
X
@@ -2329,85 +2358,28 @@
X 6 Master Interrupt Enable (1=Enabled) 0x40
X 7 Master Reset (0=Reset; 1=Run) 0x80
X
- Take us out of reset, unmute, master + TX + RX interrupts on.
+ Take us out of reset, mute output, master + TX + RX interrupts on.
X
X We'll get an interrupt presumably to tell us that the TX
- register is clear. However, this doesn't mean that the
- board is ready. We actually have to send it a command, and
- wait till it gets back to use. After a cold boot, this can
- take some time.
-
- I think this is because its only after a cold boot that the
- onboard ROM does its memory check, which can take "up to 4
- seconds" according to the WaveFront SDK. So, since sleeping
- doesn't cost us much, we'll give it *plenty* of time. It
- turns out that with 12MB of RAM, it can take up to 16
- seconds or so!! See the code after "ABOUT INTERRUPTS"
+ register is clear.
X */
X
- wavefront_should_cause_interrupt(hw,
- 0x80|0x40|0x10|0x1,
- hw->control_port,
- (2*HZ)/100);
+ wavefront_should_cause_interrupt(0x80|0x40|0x10|0x1,
+ dev.control_port,
+ (reset_time*HZ)/100);
X
X /* Note: data port is now the data port, not the h/w initialization
X port.
X */
X
- if (!hw->irq_ok) {
- printk (KERN_WARNING
- "WaveFront: intr not received after h/w un-reset.\n");
+ if (!dev.irq_ok) {
+ printk (KERN_WARNING LOGNAME
+ "intr not received after h/w un-reset.\n");
X goto gone_bad;
X }
X
- hw->interrupts_on = 1;
+ dev.interrupts_on = 1;
X
- /* ABOUT INTERRUPTS:
- -----------------
-
- When we talk about interrupts, there are two kinds
- generated by the ICS2115. The first is to signal MPU data
- ready to read, and the second is to signal RX or TX status
- changes. We *always* want interrupts for MPU stuff but we
- generally avoid using RX/TX interrupts.
-
- In theory, we could use the TX and RX interrupts for all
- communication with the card. However, there are 2 good
- reasons not to do this.
-
- First of all, the MIDI interface is going to use the same
- interrupt. This presents no practical problem since Linux
- allows us to share IRQ's. However, there are times when it
- makes sense for a user to ask the driver to disable
- interrupts, to avoid bothering Linux with a stream of MIDI
- interrupts that aren't going to be used because nothing
- cares about them. If we rely on them for communication with
- the WaveFront synth as well, this disabling would be
- crippling. Since being able to disable them can save quite
- a bit of overhead (consider the interrupt frequency of a
- physical MIDI controller like a modwheel being shunted back
- and forth - its higher than the mouse, and much of
- the time is of absolutely no interest to the kernel or any
- user space processes whatsoever), we don't want to do this.
-
- Secondly, much of the time, there's no reason to go to
- sleep on a TX or RX status: the WaveFront gets back to us
- quickly enough that its a lot more efficient to just busy
- wait on the relevant status. Once we go to sleep, all is
- lost anyway, and so interrupts don't really help us much anyway.
-
- Therefore, we don't use interrupts for communication with
- the WaveFront synth. We just poll the relevant RX/TX status.
-
- However, there is one broad exception to this. During module
- loading, to deal with several situations where timing would
- be an issue, we use TX/RX interrupts to help us avoid busy
- waiting for indeterminate and hard to manage periods of
- time. So, TX/RX interrupts are enabled until the end of
- wavefront_init(), and not used again after that.
-
- */
-
X /* Note: data port is now the data port, not the h/w initialization
X port.
X
@@ -2421,27 +2393,27 @@
X subsequent ISC2115 reboots (say, caused by module
X reloading) will get through this much faster.
X
- Interesting question: why is no RX interrupt received first ?
+ XXX Interesting question: why is no RX interrupt received first ?
X */
-
- wavefront_should_cause_interrupt(hw, WFC_HARDWARE_VERSION,
- hw->data_port, 20*HZ);
X
- if (!hw->irq_ok) {
- printk (KERN_WARNING
- "WaveFront: post-RAM-check interrupt not received.\n");
+ wavefront_should_cause_interrupt(WFC_HARDWARE_VERSION,
+ dev.data_port, ramcheck_time*HZ);
+
+ if (!dev.irq_ok) {
+ printk (KERN_WARNING LOGNAME
+ "post-RAM-check interrupt not received.\n");
X goto gone_bad;
X }
X
- if (!(wavefront_status(hw) & STAT_CAN_READ)) {
- printk (KERN_WARNING
- "WaveFront: no response to HW version cmd.\n");
+ if (!wavefront_wait (STAT_CAN_READ)) {
+ printk (KERN_WARNING LOGNAME
+ "no response to HW version cmd.\n");
X goto gone_bad;
X }
X
- if ((hwv[0] = wavefront_read (hw)) == -1) {
- printk (KERN_WARNING
- "WaveFront: board not responding correctly.\n");
+ if ((hwv[0] = wavefront_read ()) == -1) {
+ printk (KERN_WARNING LOGNAME
+ "board not responding correctly.\n");
X goto gone_bad;
X }
X
@@ -2451,13 +2423,11 @@
X and tell us about it either way.
X */
X
- if ((hwv[0] = wavefront_read (hw)) == -1) {
- printk (KERN_WARNING
- "WaveFront: on-board RAM test failed "
+ if ((hwv[0] = wavefront_read ()) == -1) {
+ printk (KERN_WARNING LOGNAME "on-board RAM test failed "
X "(bad error code).\n");
X } else {
- printk (KERN_WARNING
- "WaveFront: on-board RAM test failed "
+ printk (KERN_WARNING LOGNAME "on-board RAM test failed "
X "(error code: 0x%x).\n",
X hwv[0]);
X }
@@ -2466,85 +2436,66 @@
X
X /* We're OK, just get the next byte of the HW version response */
X
- if ((hwv[1] = wavefront_read (hw)) == -1) {
- printk (KERN_WARNING
- "WaveFront: board not responding correctly(2).\n");
+ if ((hwv[1] = wavefront_read ()) == -1) {
+ printk (KERN_WARNING LOGNAME "incorrect h/w response.\n");
X goto gone_bad;
X }
X
- printk (KERN_INFO "WaveFront: hardware version %d.%d\n",
+ printk (KERN_INFO LOGNAME "hardware version %d.%d\n",
X hwv[0], hwv[1]);
X

X return 0;
X
X

X gone_bad:
- free_irq (hw->irq, hw);
- return (1);
+ if (dev.irq >= 0) {
+ free_irq (dev.irq, &dev);
+ dev.irq = -1;
X }
+ return (1);
+}
X
-int
-probe_wavefront (struct address_info *hw_config)
+__initfunc (static int detect_wavefront (int irq, int io_base))
X
X {
X unsigned char rbuf[4], wbuf[4];
- wf_config *hw;
X
- if (hw_config->irq < 0 || hw_config->irq > 16) {
- printk (KERN_WARNING "WaveFront: impossible IRQ suggested(%d)\n",
- hw_config->irq);
- return 0;
- }
-
- /* Yeah yeah, TB docs say 8, but the FX device on the Tropez Plus
- takes up another 8 ...
+ /* TB docs say the device takes up 8 ports, but we know that
+ if there is an FX device present (i.e. a Tropez+) it really
+ consumes 16.
X */
X
- if (check_region (hw_config->io_base, 16)) {
- printk (KERN_ERR "WaveFront: IO address range 0x%x - 0x%x "
- "already in use - ignored\n", hw_config->io_base,
- hw_config->io_base+15);
- return 0;
+ if (check_region (io_base, 16)) {
+ printk (KERN_ERR LOGNAME "IO address range 0x%x - 0x%x "
+ "already in use - ignored\n", dev.base,
+ dev.base+15);
+ return -1;
X }
X
- hw = &wavefront_configuration;
-
- hw->irq = hw_config->irq;
- hw->base = hw_config->io_base;
-
- hw->israw = 0;
- hw->debug = debug_default;
- hw->interrupts_on = 0;
- hw->rom_samples_rdonly = 1; /* XXX default lock on ROM sample slots */
-
-#ifdef WF_STATS
- hw->status_found_during_sleep[0] = 0;
- hw->status_found_during_sleep[1] = 0;
- hw->status_found_during_sleep[2] = 0;
- hw->status_found_during_sleep[3] = 0;
- hw->status_found_during_loop = 0;
-#endif WF_STATS
-
- hw_config->slots[WF_SYNTH_SLOT] = hw->synthdev = -1;
- hw_config->slots[WF_INTERNAL_MIDI_SLOT] = hw->mididev = -1;
- hw_config->slots[WF_EXTERNAL_MIDI_SLOT] = hw->ext_mididev = -1;
-
- if (wavefront_cmd (hw, WFC_FIRMWARE_VERSION, rbuf, wbuf) == 0) {
-
- hw->fw_version[0] = rbuf[0];
- hw->fw_version[1] = rbuf[1];
- printk (KERN_INFO
- "WaveFront: firmware %d.%d already loaded.\n",
+ dev.irq = irq;
+ dev.base = io_base;
+ dev.israw = 0;
+ dev.debug = debug_default;
+ dev.interrupts_on = 0;
+ dev.irq_cnt = 0;
+ dev.rom_samples_rdonly = 1; /* XXX default lock on ROM sample slots */
+
+ if (wavefront_cmd (WFC_FIRMWARE_VERSION, rbuf, wbuf) == 0) {
+
+ dev.fw_version[0] = rbuf[0];
+ dev.fw_version[1] = rbuf[1];
+ printk (KERN_INFO LOGNAME
+ "firmware %d.%d already loaded.\n",
X rbuf[0], rbuf[1]);
X
X /* check that a command actually works */
X
- if (wavefront_cmd (hw, WFC_HARDWARE_VERSION,
+ if (wavefront_cmd (WFC_HARDWARE_VERSION,
X rbuf, wbuf) == 0) {
- hw->hw_version[0] = rbuf[0];
- hw->hw_version[1] = rbuf[1];
+ dev.hw_version[0] = rbuf[0];
+ dev.hw_version[1] = rbuf[1];
X } else {
- printk (KERN_INFO "WaveFront: not raw, but no "
+ printk (KERN_WARNING LOGNAME "not raw, but no "
X "hardware version!\n");
X return 0;
X }
@@ -2552,25 +2503,30 @@
X if (!wf_raw) {
X return 1;
X } else {
- printk (KERN_INFO
- "WaveFront: reloading firmware anyway.\n");
+ printk (KERN_INFO LOGNAME
+ "reloading firmware anyway.\n");
+ dev.israw = 1;
X }
X
X } else {
X
- hw->israw = 1;
- printk (KERN_INFO "WaveFront: no response to firmware probe, "
- "assume raw.\n");
+ dev.israw = 1;
+ printk (KERN_INFO LOGNAME
+ "no response to firmware probe, assume raw.\n");
X
X }
X
- init_waitqueue (&hw->interrupt_sleeper);
+ init_waitqueue (&dev.interrupt_sleeper);
X
- if (wavefront_hw_reset (hw)) {
- printk (KERN_WARNING "WaveFront: hardware reset failed\n");
+ if (wavefront_hw_reset ()) {
+ printk (KERN_WARNING LOGNAME "hardware reset failed\n");


X return 0;
X }
X

+ /* Check for FX device, present only on Tropez+ */
+
+ dev.has_fx = (detect_wffx () == 0);
+
X return 1;
X }
X
@@ -2585,7 +2541,7 @@
X static int errno;
X
X static int
-wavefront_download_firmware (wf_config *hw, char *path)
+wavefront_download_firmware (char *path)
X
X {
X unsigned char section[WF_SECTION_MAX];
@@ -2610,7 +2566,7 @@
X set_fs (get_ds());
X
X if ((fd = open (path, 0, 0)) < 0) {
- printk (KERN_WARNING "WaveFront: Unable to load \"%s\".\n",
+ printk (KERN_WARNING LOGNAME "Unable to load \"%s\".\n",
X path);
X return 1;
X }
@@ -2620,7 +2576,7 @@
X
X if ((x = read (fd, &section_length, sizeof (section_length))) !=
X sizeof (section_length)) {
- printk (KERN_ERR "WaveFront: firmware read error.\n");
+ printk (KERN_ERR LOGNAME "firmware read error.\n");
X goto failure;
X }
X
@@ -2629,58 +2585,46 @@
X }
X
X if (read (fd, section, section_length) != section_length) {
- printk (KERN_ERR "WaveFront: firmware section "
+ printk (KERN_ERR LOGNAME "firmware section "
X "read error.\n");
X goto failure;
X }
X
X /* Send command */
X
- if (!wavefront_write (hw, WFC_DOWNLOAD_OS)) {
+ if (wavefront_write (WFC_DOWNLOAD_OS)) {
X goto failure;
X }
X
X for (i = 0; i < section_length; i++) {
- if (!wavefront_write (hw, section[i])) {
+ if (wavefront_write (section[i])) {
X goto failure;
X }
X }
X
X /* get ACK */
X
- if (wavefront_wait (hw, STAT_CAN_READ)) {
+ if (wavefront_wait (STAT_CAN_READ)) {
X
- if ((c = inb (hw->data_port)) != WF_ACK) {
+ if ((c = inb (dev.data_port)) != WF_ACK) {
X
- printk (KERN_ERR "WaveFront: download "
+ printk (KERN_ERR LOGNAME "download "
X "of section #%d not "
X "acknowledged, ack = 0x%x\n",
X section_cnt_downloaded + 1, c);
X goto failure;
X
- } else {
-#ifdef WF_DEBUG
- if ((hw->debug & WF_DEBUG_IO) &&
- !(++section_cnt_downloaded % 10)) {
- printk (KERN_DEBUG ".");
- }
-#endif WF_DEBUG
X }
X
X } else {
- printk (KERN_ERR "WaveFront: timed out "
- "for download ACK.\n");
+ printk (KERN_ERR LOGNAME "time out for firmware ACK.\n");
+ goto failure;
X }
X
X }
X
X close (fd);
X set_fs (fs);
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_IO) {
- printk (KERN_DEBUG "\n");
- }
-#endif WF_DEBUG
X return 0;
X
X failure:
@@ -2690,38 +2634,33 @@
X return 1;
X }
X
-static int
-wavefront_config_midi (wf_config *hw, struct address_info *hw_config)
+__initfunc (static int wavefront_config_midi (void))
X
X {
X unsigned char rbuf[4], wbuf[4];
X
- if (!probe_wf_mpu (hw_config)) {
- printk (KERN_WARNING "WaveFront: could not install "
- "MPU-401 device.\n");
- return 1;
+ if (detect_wf_mpu (dev.irq, dev.base) < 0) {
+ printk (KERN_WARNING LOGNAME
+ "could not find working MIDI device\n");
+ return -1;
X }
X
- /* Attach an modified MPU-401 driver to the master MIDI interface */
-
- hw_config->name = "WaveFront Internal MIDI";
- attach_wf_mpu (hw_config);
-
- if (hw_config->slots[WF_INTERNAL_MIDI_SLOT] == -1) {
- printk (KERN_WARNING "WaveFront: MPU-401 not configured.\n");
- return 1;
+ if ((dev.mididev = install_wf_mpu ()) < 0) {
+ printk (KERN_WARNING LOGNAME
+ "MIDI interfaces not configured\n");
+ return -1;
X }
X
- hw->mididev = hw_config->slots[WF_INTERNAL_MIDI_SLOT];
-
X /* Route external MIDI to WaveFront synth (by default) */
X
- if (wavefront_cmd (hw, WFC_MISYNTH_ON, rbuf, wbuf)) {
- printk (KERN_WARNING
- "WaveFront: cannot enable MIDI-IN to synth routing.\n");
+ if (wavefront_cmd (WFC_MISYNTH_ON, rbuf, wbuf)) {
+ printk (KERN_WARNING LOGNAME
+ "cannot enable MIDI-IN to synth routing.\n");
X /* XXX error ? */
X }
X
+
+#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
X /* Get the regular MIDI patch loading function, so we can
X use it if we ever get handed a SYSEX patch. This is
X unlikely, because its so damn slow, but we may as well
@@ -2730,12 +2669,14 @@
X only use MIDI to do patch loading.
X */
X
- if (midi_devs[hw->mididev]->converter != NULL) {
- midi_load_patch = midi_devs[hw->mididev]->converter->load_patch;
- midi_devs[hw->mididev]->converter->load_patch =
- &wavefront_load_patch;
+ if (midi_devs[dev.mididev]->converter != NULL) {
+ midi_load_patch = midi_devs[dev.mididev]->converter->load_patch;
+ midi_devs[dev.mididev]->converter->load_patch =
+ &wavefront_oss_load_patch;
X }
X
+#endif OSS_SUPPORT_SEQ
+
X /* Turn on Virtual MIDI, but first *always* turn it off,
X since otherwise consectutive reloads of the driver will
X never cause the hardware to generate the initial "internal" or
@@ -2747,22 +2688,19 @@
X the internal interface. Duh.
X */
X
- if (wavefront_cmd (hw, WFC_VMIDI_OFF, rbuf, wbuf)) {
- printk (KERN_WARNING "WaveFront: cannot disable "
- "virtual MIDI mode\n");
- /* XXX go ahead and try anyway ? */
+ if (wavefront_cmd (WFC_VMIDI_OFF, rbuf, wbuf)) {
+ printk (KERN_WARNING LOGNAME
+ "virtual MIDI mode not disabled\n");
+ return 0; /* We're OK, but missing the external MIDI dev */
X }
X
- hw_config->name = "WaveFront External MIDI";
-
- if (virtual_midi_enable (hw->mididev, hw_config)) {
- printk (KERN_WARNING "WaveFront: no virtual MIDI access.\n");
+ if ((dev.ext_mididev = virtual_midi_enable ()) < 0) {
+ printk (KERN_WARNING LOGNAME "no virtual MIDI access.\n");
X } else {
- hw->ext_mididev = hw_config->slots[WF_EXTERNAL_MIDI_SLOT];
- if (wavefront_cmd (hw, WFC_VMIDI_ON, rbuf, wbuf)) {
- printk (KERN_WARNING
- "WaveFront: cannot enable virtual MIDI mode.\n");
- virtual_midi_disable (hw->mididev);
+ if (wavefront_cmd (WFC_VMIDI_ON, rbuf, wbuf)) {
+ printk (KERN_WARNING LOGNAME
+ "cannot enable virtual MIDI mode.\n");
+ virtual_midi_disable ();
X }
X }
X
@@ -2770,62 +2708,66 @@
X }
X
X static int
-wavefront_do_reset (wf_config *hw, int atboot)
+wavefront_do_reset (int atboot)
X
X {
X char voices[1];
X
- if (!atboot && wavefront_hw_reset (hw)) {
- printk (KERN_WARNING "WaveFront: hw reset failed.\n");
+ if (!atboot && wavefront_hw_reset ()) {
+ printk (KERN_WARNING LOGNAME "hw reset failed.\n");
X goto gone_bad;
X }
X
- if (hw->israw || wf_raw) {
- if (wavefront_download_firmware (hw, ospath)) {
+ if (dev.israw) {
+ if (wavefront_download_firmware (ospath)) {
X goto gone_bad;
X }
X
+ dev.israw = 0;
+
X /* Wait for the OS to get running. The protocol for
X this is non-obvious, and was determined by
X using port-IO tracing in DOSemu and some
X experimentation here.
X
- Rather than busy-wait, use interrupts creatively.
+ Rather than using timed waits, use interrupts creatively.
X */
X
- wavefront_should_cause_interrupt (hw, WFC_NOOP,
- hw->data_port, (10*HZ));
-
- if (!hw->irq_ok) {
- printk (KERN_WARNING
- "WaveFront: no post-OS interrupt.\n");
+ wavefront_should_cause_interrupt (WFC_NOOP,
+ dev.data_port,
+ (osrun_time*HZ));
+
+ if (!dev.irq_ok) {
+ printk (KERN_WARNING LOGNAME
+ "no post-OS interrupt.\n");
X goto gone_bad;
X }
X
X /* Now, do it again ! */
X
- wavefront_should_cause_interrupt (hw, WFC_NOOP,
- hw->data_port, (10*HZ));
+ wavefront_should_cause_interrupt (WFC_NOOP,
+ dev.data_port, (10*HZ));
X
- if (!hw->irq_ok) {
- printk (KERN_WARNING
- "WaveFront: no post-OS interrupt(2).\n");
+ if (!dev.irq_ok) {
+ printk (KERN_WARNING LOGNAME
+ "no post-OS interrupt(2).\n");
X goto gone_bad;
X }
X
X /* OK, no (RX/TX) interrupts any more, but leave mute
- on. Master interrupts get enabled when we're done here.
+ in effect.
X */
X
- outb (0x80, hw->control_port);
-
+ outb (0x80|0x40, dev.control_port);
+
X /* No need for the IRQ anymore */
X
- free_irq (hw->irq, hw);
+ free_irq (dev.irq, &dev);
+
X }
X
- if (/*XXX has_fx_device() && */ fx_raw) {
- wffx_init (hw);
+ if (dev.has_fx && fx_raw) {
+ wffx_init ();
X }
X
X /* SETUPSND.EXE asks for sample memory config here, but since i
@@ -2833,118 +2775,130 @@
X about it.
X */
X
- if ((hw->freemem = wavefront_freemem (hw)) < 0) {
+ if ((dev.freemem = wavefront_freemem ()) < 0) {
X goto gone_bad;
X }
X
- printk (KERN_INFO "WaveFront: available DRAM %dk\n", hw->freemem / 1024);
+ printk (KERN_INFO LOGNAME "available DRAM %dk\n", dev.freemem / 1024);
X
- if (!wavefront_write (hw, 0xf0) ||
- !wavefront_write (hw, 1) ||
- (wavefront_read (hw) < 0)) {
- hw->debug = 0;
- printk (KERN_WARNING "WaveFront: MPU emulation mode not set.\n");
+ if (wavefront_write (0xf0) ||
+ wavefront_write (1) ||
+ (wavefront_read () < 0)) {
+ dev.debug = 0;
+ printk (KERN_WARNING LOGNAME "MPU emulation mode not set.\n");
X goto gone_bad;
X }
X
X voices[0] = 32;
X
- if (wavefront_cmd (hw, WFC_SET_NVOICES, 0, voices)) {
- printk (KERN_WARNING
- "WaveFront: cannot set number of voices to 32.\n");
+ if (wavefront_cmd (WFC_SET_NVOICES, 0, voices)) {
+ printk (KERN_WARNING LOGNAME
+ "cannot set number of voices to 32.\n");
+ goto gone_bad;
X }
X
+
X return 0;
X
X gone_bad:
X /* reset that sucker so that it doesn't bother us. */
X
- outb (0x0, hw->control_port);
- free_irq (hw->irq, hw);
+ outb (0x0, dev.control_port);
+ dev.interrupts_on = 0;
+ if (dev.irq >= 0) {
+ free_irq (dev.irq, &dev);
+ }
X return 1;
X }
X
X static int
-wavefront_init (wf_config *hw, int atboot)
+wavefront_init (int atboot)
X
X {
X int samples_are_from_rom;
X
- if (hw->israw || wf_raw) {
+ if (dev.israw) {
X samples_are_from_rom = 1;
X } else {
+ /* XXX is this always true ? */
X samples_are_from_rom = 0;
X }
X
- if (hw->israw || wf_raw || fx_raw) {
- if (wavefront_do_reset (hw, atboot)) {
- return 1;
+ if (dev.israw || fx_raw) {
+ if (wavefront_do_reset (atboot)) {
+ return -1;
X }
X }
X
- wavefront_get_sample_status (hw, samples_are_from_rom);
- wavefront_get_program_status (hw);
- wavefront_get_patch_status (hw);
+ wavefront_get_sample_status (samples_are_from_rom);
+ wavefront_get_program_status ();
+ wavefront_get_patch_status ();
X
- /* Start normal operation: unreset, master interrupt enable
- (for MPU interrupts) no mute
+ /* Start normal operation: unreset, master interrupt enabled, no mute
X */
X
- outb (0x80|0x40|0x20, hw->control_port);
+ outb (0x80|0x40|0x20, dev.control_port);
X
X return (0);
X }
X
-void
-attach_wavefront (struct address_info *hw_config)
+__initfunc (static int install_wavefront (void))
+
X {
- int i;
- struct wf_config *hw = &wavefront_configuration;
+ if ((dev.synth_dev = register_sound_synth (&wavefront_fops, -1)) < 0) {
+ printk (KERN_ERR LOGNAME "cannot register raw synth\n");
+ return -1;
+ }
X
- if ((i = sound_alloc_synthdev()) == -1) {
- printk (KERN_ERR "WaveFront: Too many synthesizers\n");
- return;
+#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
+ if ((dev.oss_dev = sound_alloc_synthdev()) == -1) {
+ printk (KERN_ERR LOGNAME "Too many sequencers\n");
+ return -1;
X } else {
- hw_config->slots[WF_SYNTH_SLOT] = i;
- hw->synthdev = i;
- synth_devs[hw->synthdev] = &wavefront_operations;
+ synth_devs[dev.oss_dev] = &wavefront_operations;
X }
+#endif OSS_SUPPORT_SEQ
X
- if (wavefront_init (hw, 1)) {
- printk (KERN_WARNING "WaveFront: board could not "
- "be initialized.\n");
- sound_unload_synthdev (i);
- return;
+ if (wavefront_init (1) < 0) {
+ printk (KERN_WARNING LOGNAME "initialization failed.\n");
+
+#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
+ sound_unload_synthdev (dev.oss_dev);
+#endif OSS_SUPPORT_SEQ
+
+ return -1;
X }
X
- request_region (hw_config->io_base+2, 6, "WaveFront synth");
- request_region (hw_config->io_base+8, 8, "WaveFront FX");
+ request_region (dev.base+2, 6, "wavefront synth");
X
- conf_printf2 ("WaveFront Synth", hw_config->io_base, 0, -1, -1);
+ if (dev.has_fx) {
+ request_region (dev.base+8, 8, "wavefront fx");
+ }
X
-#if defined(CONFIG_MIDI)
- if (wavefront_config_midi (hw, hw_config)) {
- printk (KERN_WARNING "WaveFront: could not initialize MIDI.\n");
+ if (wavefront_config_midi ()) {
+ printk (KERN_WARNING LOGNAME "could not initialize MIDI.\n");
X }
-#else
- printk (KERN_WARNING
- "WaveFront: MIDI not configured at kernel-config time.\n");
-#endif CONFIG_MIDI
X
- return;
+ return dev.oss_dev;
X }
+
X void
-unload_wavefront (struct address_info *hw_config)
+uninstall_wavefront (void)
+
X {
- struct wf_config *hw = &wavefront_configuration;
+ /* the first two i/o addresses are freed by the wf_mpu code */
+ release_region (dev.base+2, 6);
X
- /* the first two are freed by the wf_mpu code */
- release_region (hw->base+2, 6);
- release_region (hw->base+8, 8);
- sound_unload_synthdev (hw->synthdev);
-#if defined(CONFIG_MIDI)
- unload_wf_mpu (hw_config);
-#endif
+ if (dev.has_fx) {
+ release_region (dev.base+8, 8);
+ }
+
+ unregister_sound_synth (dev.synth_dev);
+
+#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
+ sound_unload_synthdev (dev.oss_dev);
+#endif OSS_SUPPORT_SEQ
+ uninstall_wf_mpu ();
X }
X
X /***********************************************************************/
@@ -2961,83 +2915,111 @@
X #define FX_AUTO_INCR 0x04 /* auto-increment DSP address after transfer */
X
X static int
-wffx_idle (struct wf_config *hw)
+wffx_idle (void)
X
X {
X int i;
X unsigned int x = 0x80;
X
X for (i = 0; i < 1000; i++) {
- x = inb (hw->fx_status);
+ x = inb (dev.fx_status);
X if ((x & 0x80) == 0) {
X break;
X }
X }
X
X if (x & 0x80) {
- printk (KERN_ERR "WaveFront: FX device never idle.\n");
+ printk (KERN_ERR LOGNAME "FX device never idle.\n");


X return 0;
X }
X

X return (1);
X }
X
+__initfunc (static int detect_wffx (void))
+
+{
+ /* This is a crude check, but its the best one I have for now.
+ Certainly on the Maui and the Tropez, wffx_idle() will
+ report "never idle", which suggests that this test should
+ work OK.
+ */
+
+ if (inb (dev.fx_status) & 0x80) {
+ printk (KERN_INFO LOGNAME "Hmm, probably a Maui or Tropez.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+__initfunc (static int attach_wffx (void))
+
+{
+ if ((dev.fx_mididev = sound_alloc_mididev ()) < 0) {
+ printk (KERN_WARNING LOGNAME "cannot install FX Midi driver\n");
+ return -1;
+ }
+
+ return 0;
+}
+
X static void
-wffx_mute (struct wf_config *hw, int onoff)
+wffx_mute (int onoff)
X
X {
- if (!wffx_idle(hw)) {
+ if (!wffx_idle()) {
X return;
X }
X
- outb (onoff ? 0x02 : 0x00, hw->fx_op);
+ outb (onoff ? 0x02 : 0x00, dev.fx_op);
X }
X
X static int
-wffx_memset (struct wf_config *hw, int page,
+wffx_memset (int page,
X int addr, int cnt, unsigned short *data)
X {
X if (page < 0 || page > 7) {
- printk (KERN_ERR "WaveFront: FX memset: "
+ printk (KERN_ERR LOGNAME "FX memset: "
X "page must be >= 0 and <= 7\n");
X return -(EINVAL);
X }
X
X if (addr < 0 || addr > 0x7f) {
- printk (KERN_ERR "WaveFront: FX memset: "
+ printk (KERN_ERR LOGNAME "FX memset: "
X "addr must be >= 0 and <= 7f\n");
X return -(EINVAL);
X }
X
X if (cnt == 1) {
X
- outb (FX_LSB_TRANSFER, hw->fx_lcr);
- outb (page, hw->fx_dsp_page);
- outb (addr, hw->fx_dsp_addr);
- outb ((data[0] >> 8), hw->fx_dsp_msb);
- outb ((data[0] & 0xff), hw->fx_dsp_lsb);
+ outb (FX_LSB_TRANSFER, dev.fx_lcr);
+ outb (page, dev.fx_dsp_page);
+ outb (addr, dev.fx_dsp_addr);
+ outb ((data[0] >> 8), dev.fx_dsp_msb);
+ outb ((data[0] & 0xff), dev.fx_dsp_lsb);
X
- printk (KERN_INFO "WaveFront: FX: addr %d:%x set to 0x%x\n",
+ printk (KERN_INFO LOGNAME "FX: addr %d:%x set to 0x%x\n",
X page, addr, data[0]);
X
X } else {
X int i;
X
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);
- outb (page, hw->fx_dsp_page);
- outb (addr, hw->fx_dsp_addr);
+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
+ outb (page, dev.fx_dsp_page);
+ outb (addr, dev.fx_dsp_addr);
X
X for (i = 0; i < cnt; i++) {
- outb ((data[i] >> 8), hw->fx_dsp_msb);
- outb ((data[i] & 0xff), hw->fx_dsp_lsb);
- if (!wffx_idle (hw)) {
+ outb ((data[i] >> 8), dev.fx_dsp_msb);
+ outb ((data[i] & 0xff), dev.fx_dsp_lsb);
+ if (!wffx_idle ()) {
X break;
X }
X }
X
X if (i != cnt) {
- printk (KERN_WARNING
- "WaveFront: FX memset "
+ printk (KERN_WARNING LOGNAME
+ "FX memset "
X "(0x%x, 0x%x, 0x%x, %d) incomplete\n",
X page, addr, (int) data, cnt);
X return -(EIO);
@@ -3048,7 +3030,7 @@
X }
X
X static int
-wffx_ioctl (struct wf_config *hw, wavefront_fx_info *r)
+wffx_ioctl (wavefront_fx_info *r)
X
X {
X unsigned short page_data[256];
@@ -3056,20 +3038,20 @@
X
X switch (r->request) {
X case WFFX_MUTE:
- wffx_mute (hw, r->data[0]);
+ wffx_mute (r->data[0]);
X return 0;
X
X case WFFX_MEMSET:
X
X if (r->data[2] <= 0) {
- printk (KERN_ERR "WaveFront: cannot write "
+ printk (KERN_ERR LOGNAME "cannot write "
X "<= 0 bytes to FX\n");
X return -(EINVAL);
X } else if (r->data[2] == 1) {
X pd = (unsigned short *) &r->data[3];
X } else {
X if (r->data[2] > sizeof (page_data)) {
- printk (KERN_ERR "WaveFront: cannot write "
+ printk (KERN_ERR LOGNAME "cannot write "
X "> 255 bytes to FX\n");
X return -(EINVAL);
X }
@@ -3078,15 +3060,14 @@
X pd = page_data;
X }
X
- return wffx_memset (hw,
- r->data[0], /* page */
+ return wffx_memset (r->data[0], /* page */
X r->data[1], /* addr */
X r->data[2], /* cnt */
X pd);
X
X default:
- printk (KERN_WARNING
- "WaveFront: FX: ioctl %d not yet supported\n",
+ printk (KERN_WARNING LOGNAME
+ "FX: ioctl %d not yet supported\n",
X r->request);
X return -(EINVAL);
X }
@@ -3107,7 +3088,7 @@
X */
X
X static int
-wffx_init (struct wf_config *hw)
+wffx_init (void)
X
X {
X int i;
@@ -3119,147 +3100,147 @@
X for (j = 0; j < 2; j++) {
X for (i = 0x10; i <= 0xff; i++) {
X
- if (!wffx_idle (hw)) {
+ if (!wffx_idle ()) {
X return (-1);
X }
X
- outb (i, hw->fx_mod_addr);
- outb (0x0, hw->fx_mod_data);
+ outb (i, dev.fx_mod_addr);
+ outb (0x0, dev.fx_mod_data);
X }
X }
X
- if (!wffx_idle(hw)) return (-1);
- outb (0x02, hw->fx_op); /* mute on */
+ if (!wffx_idle()) return (-1);
+ outb (0x02, dev.fx_op); /* mute on */
X
- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);
- outb (0x44, hw->fx_dsp_addr);
- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);
- outb (0x42, hw->fx_dsp_addr);
- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);
- outb (0x43, hw->fx_dsp_addr);
- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);
- outb (0x7c, hw->fx_dsp_addr);
- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);
- outb (0x7e, hw->fx_dsp_addr);
- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);
- outb (0x46, hw->fx_dsp_addr);
- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);
- outb (0x49, hw->fx_dsp_addr);
- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);
- outb (0x47, hw->fx_dsp_addr);
- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);
- outb (0x4a, hw->fx_dsp_addr);
- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);
+ outb (0x44, dev.fx_dsp_addr);
+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);
+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);
+ outb (0x42, dev.fx_dsp_addr);
+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);
+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);
+ outb (0x43, dev.fx_dsp_addr);
+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);
+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);
+ outb (0x7c, dev.fx_dsp_addr);
+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);
+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);
+ outb (0x7e, dev.fx_dsp_addr);
+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);
+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);
+ outb (0x46, dev.fx_dsp_addr);
+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);
+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);
+ outb (0x49, dev.fx_dsp_addr);
+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);
+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);
+ outb (0x47, dev.fx_dsp_addr);
+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre5 failed'
fi

echo 'End of part 05'
echo 'File patch-2.2.0-pre5 is continued in part 06'
echo 06 > _shar_seq_.tmp
exit 0

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

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to
Archive-name: v2.1/patch-2.2.0-pre5/part02

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


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

# file patch-2.2.0-pre5 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.0-pre5'
else
echo 'x - continuing with patch-2.2.0-pre5'

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

X
- /*
- * Dump the stack
- */
- printk("Process %s (pid: %ld, stackpage=%08lx)\nStack: ",
- current->comm, current->pid, (unsigned long)current);
- for(i=0;i<5;i++)
- printk("%08x ", *sp++);
- stack = (int *) sp;
+ if (__get_user(stackdata, stack++)) {
+ printk(" (Bad stack address)");
+ break;
+ }
X
- for(i=0; i < kstack_depth_to_print; i++) {
- unsigned int stackdata;
+ printk(" %08lx", stackdata);
X
- if (((u32) stack & (PAGE_SIZE -1)) == 0)
- break;
- if (i && ((i % 8) == 0))
- printk("\n ");
- if (get_user(stackdata, stack++) < 0) {
- printk("(Bad stack address)");
+ if (++i > 40) {
+ printk(" ...");
X break;
X }
- printk("%08x ", stackdata);
+
+ if (i % 8 == 0)
+ printk("\n ");
X }
- printk("\nCall Trace: ");
- stack = (int *)sp;
- i = 1;
+}
+
+void show_trace(unsigned int *sp)
+{
+ int i;
+ unsigned int *stack;
+ unsigned long kernel_start, kernel_end;
+ unsigned long module_start, module_end;
+ extern char _stext, _etext;
+


+ stack = sp;
+ i = 0;

+
+ kernel_start = (unsigned long) &_stext;
+ kernel_end = (unsigned long) &_etext;
X module_start = VMALLOC_START;
X module_end = module_start + MODULE_RANGE;
- while (((unsigned long)stack & (PAGE_SIZE -1)) != 0) {
- if (get_user(addr, stack++) < 0) {
- printk("(Bad address)\n");
+
+ printk("\nCall Trace:");
+


+ while ((unsigned long) stack & (PAGE_SIZE -1)) {

+ unsigned long addr;
+
+ if (__get_user(addr, stack++)) {
+ printk(" (Bad stack address)\n");
X break;
X }
+
X /*
X * If the address is either in the text segment of the
X * kernel, or in the region which contains vmalloc'ed
@@ -132,26 +144,33 @@
X * down the cause of the crash will be able to figure
X * out the call path that was taken.
X */
- if (((addr >= (u32) &start_kernel) &&
- (addr <= (u32) &_etext)) ||
- ((addr >= module_start) && (addr <= module_end))) {
- if (i && ((i % 8) == 0))
- printk("\n ");
- printk("%08x ", addr);
- i++;
+
+ if ((addr >= kernel_start && addr < kernel_end) ||
+ (addr >= module_start && addr < module_end)) {
+
+ printk(" [<%08lx>]", addr);
+ if (++i > 40) {
+ printk(" ...");
+ break;
+ }
X }
X }
+}
X
- printk("\nCode : ");
- if ((KSEGX(pc) == KSEG0 || KSEGX(pc) == KSEG1) &&
- (((unsigned long) pc & 3) == 0))
- {
- for(i=0;i<5;i++)
- printk("%08x ", *pc++);
- printk("\n");
+void show_code(unsigned int *pc)
+{
+ long i;
+
+ printk("\nCode:");
+
+ for(i = -3 ; i < 6 ; i++) {
+ unsigned long insn;
+ if (__get_user(insn, pc + i)) {
+ printk(" (Bad address in epc)\n");
+ break;
+ }
+ printk("%c%08lx%c",(i?' ':'<'),insn,(i?' ':'>'));
X }
- else
- printk("(Bad address in epc)\n");
X }
X
X void die(const char * str, struct pt_regs * regs, unsigned long err)
@@ -162,6 +181,12 @@
X console_verbose();
X printk("%s: %04lx\n", str, err & 0xffff);
X show_regs(regs);
+ printk("Process %s (pid: %ld, stackpage=%08lx)\n",
+ current->comm, current->pid, (unsigned long) current);
+ show_stack((unsigned int *) regs->regs[29]);
+ show_trace((unsigned int *) regs->regs[29]);
+ show_code((unsigned int *) regs->cp0_epc);
+ printk("\n");
X do_exit(SIGSEGV);
X }
X
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/ppc/common_defconfig linux/arch/ppc/common_defconfig
--- v2.2.0-pre4/linux/arch/ppc/common_defconfig Mon Dec 28 15:00:52 1998
+++ linux/arch/ppc/common_defconfig Mon Jan 4 15:32:42 1999
@@ -48,7 +48,7 @@
X # CONFIG_KGDB is not set
X # CONFIG_XMON is not set
X # CONFIG_TOTALMP is not set
-# CONFIG_BOOTX_TEXT is not set
+CONFIG_BOOTX_TEXT=y
X
X #
X # Plug and Play support
@@ -114,6 +114,10 @@
X # CONFIG_NET_FASTROUTE is not set
X # CONFIG_NET_HW_FLOWCONTROL is not set
X # CONFIG_CPU_IS_SLOW is not set
+
+#
+# QoS and/or fair queueing
+#
X # CONFIG_NET_SCHED is not set
X
X #
@@ -133,6 +137,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
@@ -140,14 +145,16 @@
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
X # CONFIG_SCSI_NCR53C406A is not set
X # CONFIG_SCSI_NCR53C7xx is not set
X CONFIG_SCSI_NCR53C8XX=y
@@ -171,7 +178,7 @@
X # CONFIG_SCSI_DEBUG is not set
X CONFIG_SCSI_MESH=y
X CONFIG_SCSI_MESH_SYNC_RATE=5
-CONFIG_SCSI_MAC53C94=m
+CONFIG_SCSI_MAC53C94=y
X
X #
X # Network device support
@@ -221,6 +228,7 @@
X # CONFIG_TR is not set
X # CONFIG_SHAPER is not set
X # CONFIG_HOSTESS_SV11 is not set
+# CONFIG_COSA is not set
X
X #
X # Amateur Radio support
@@ -242,25 +250,29 @@
X #
X CONFIG_DUMMY_CONSOLE=y
X CONFIG_FB_OF=y
-# CONFIG_FB_CONTROL is not set
-# CONFIG_FB_PLATINUM is not set
-# CONFIG_FB_VALKYRIE is not set
-CONFIG_FB_ATY=y
+CONFIG_FB_CONTROL=y
+CONFIG_FB_PLATINUM=y
+CONFIG_FB_VALKYRIE=y
+# CONFIG_FB_ATY is not set
X CONFIG_FB_IMSTT=y
-# CONFIG_FB_CT65550 is not set
+CONFIG_FB_CT65550=y
X # CONFIG_FB_S3TRIO is not set
X # CONFIG_FB_MATROX is not set
-CONFIG_FB_ATY=y
+# CONFIG_FB_ATY is not set
X # CONFIG_FB_VIRTUAL is not set
X # CONFIG_FBCON_ADVANCED is not set
X CONFIG_FBCON_CFB8=y
X CONFIG_FBCON_CFB16=y
-CONFIG_FBCON_CFB24=y
X CONFIG_FBCON_CFB32=y
X # CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-# CONFIG_FBCON_FONTS is not set
+CONFIG_FBCON_FONTS=y
X CONFIG_FONT_8x8=y
X CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+CONFIG_FONT_SUN12x22=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
X
X #
X # Character devices
@@ -272,6 +284,10 @@
X # CONFIG_SERIAL_NONSTANDARD is not set
X # CONFIG_UNIX98_PTYS is not set
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
@@ -280,9 +296,17 @@
X # CONFIG_PC110_PAD is not set
X # CONFIG_QIC02_TAPE is not set
X # CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
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
X
X #
@@ -294,37 +318,46 @@
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_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+CONFIG_HFS_FS=y
X CONFIG_FAT_FS=m
X CONFIG_MSDOS_FS=m
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_QNX4FS_FS is not set
+# 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
X CONFIG_NFSD=m
X # 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
X # CONFIG_NCP_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=y
-# CONFIG_ROMFS_FS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
X # CONFIG_BSD_DISKLABEL is not set
+CONFIG_MAC_PARTITION=y
X # CONFIG_SMD_DISKLABEL is not set
X # CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-CONFIG_MAC_PARTITION=y
+# CONFIG_UNIXWARE_DISKLABEL is not set
X CONFIG_NLS=y
X
X #
@@ -355,6 +388,7 @@
X # CONFIG_NLS_ISO8859_7 is not set
X # CONFIG_NLS_ISO8859_8 is not set
X # CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_15 is not set
X # CONFIG_NLS_KOI8_R is not set
X
X #
@@ -383,6 +417,7 @@
X # CONFIG_SOUND_OPL3SA2 is not set
X # CONFIG_SOUND_MAUI is not set
X # CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_AD1816 is not set
X # CONFIG_SOUND_OPL3SA1 is not set
X # CONFIG_SOUND_SOFTOSS is not set
X # CONFIG_SOUND_YM3812 is not set
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/ppc/defconfig linux/arch/ppc/defconfig
--- v2.2.0-pre4/linux/arch/ppc/defconfig Thu Dec 31 10:28:59 1998
+++ linux/arch/ppc/defconfig Mon Jan 4 15:32:42 1999
@@ -138,6 +138,10 @@
X # CONFIG_NET_FASTROUTE is not set
X # CONFIG_NET_HW_FLOWCONTROL is not set
X # CONFIG_CPU_IS_SLOW is not set
+
+#
+# QoS and/or fair queueing
+#
X # CONFIG_NET_SCHED is not set
X
X #
@@ -195,7 +199,6 @@
X # CONFIG_SCSI_PSI240I is not set
X # CONFIG_SCSI_QLOGIC_FAS is not set
X # CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
X # CONFIG_SCSI_SEAGATE is not set
X # CONFIG_SCSI_DC390T is not set
X # CONFIG_SCSI_T128 is not set
@@ -311,7 +314,7 @@
X #
X CONFIG_VT=y
X CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
+# CONFIG_SERIAL is not set
X # CONFIG_SERIAL_EXTENDED is not set
X # CONFIG_SERIAL_NONSTANDARD is not set
X CONFIG_UNIX98_PTYS=y
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- v2.2.0-pre4/linux/arch/ppc/kernel/process.c Thu Dec 31 10:28:59 1998
+++ linux/arch/ppc/kernel/process.c Tue Jan 5 11:13:56 1999
@@ -191,6 +191,19 @@
X _enable_interrupts(s);
X }
X
+void instruction_dump (unsigned long *pc)


+{
+ int i;
+

+ if((((unsigned long) pc) & 3))
+ return;
+
+ printk("Instruction DUMP:");
+ for(i = -3; i < 6; i++)
+ printk("%c%08lx%c",i?' ':'<',pc[i],i?' ':'>');


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

X void show_regs(struct pt_regs * regs)
X {
X int i;
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- v2.2.0-pre4/linux/arch/ppc/kernel/traps.c Fri May 8 23:14:45 1998
+++ linux/arch/ppc/kernel/traps.c Tue Jan 5 11:13:56 1999
@@ -79,6 +79,7 @@
X debugger(regs);
X #endif
X print_backtrace((unsigned long *)regs->gpr[1]);
+ instruction_dump((unsigned long *)regs->nip);
X panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
X }
X force_sig(signr, current);
@@ -126,6 +127,7 @@
X debugger(regs);
X #endif
X print_backtrace((unsigned long *)regs->gpr[1]);
+ instruction_dump((unsigned long *)regs->nip);
X panic("machine check");
X }
X _exception(SIGSEGV, regs);
@@ -219,6 +221,7 @@
X #endif
X show_regs(regs);
X print_backtrace((unsigned long *)regs->gpr[1]);
+ instruction_dump((unsigned long *)regs->nip);
X panic("kernel stack overflow");
X }
X
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/ppc/mm/fault.c linux/arch/ppc/mm/fault.c
--- v2.2.0-pre4/linux/arch/ppc/mm/fault.c Thu Nov 19 09:56:27 1998
+++ linux/arch/ppc/mm/fault.c Tue Jan 5 11:13:56 1999
@@ -89,6 +89,7 @@
X printk("page fault in interrupt handler, addr=%lx\n",
X address);
X show_regs(regs);
+ instruction_dump((unsigned long *)regs->nip);
X #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
X if (debugger_kernel_faults)
X debugger(regs);
@@ -174,6 +175,7 @@
X /* kernel has accessed a bad area */
X show_regs(regs);
X print_backtrace( (unsigned long *)regs->gpr[1] );
+ instruction_dump((unsigned long *)regs->nip);
X #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
X if (debugger_kernel_faults)
X debugger(regs);
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/ppc/pmac_defconfig linux/arch/ppc/pmac_defconfig
--- v2.2.0-pre4/linux/arch/ppc/pmac_defconfig Thu Dec 31 10:28:59 1998
+++ linux/arch/ppc/pmac_defconfig Mon Jan 4 15:32:42 1999
@@ -138,6 +138,10 @@
X # CONFIG_NET_FASTROUTE is not set
X # CONFIG_NET_HW_FLOWCONTROL is not set
X # CONFIG_CPU_IS_SLOW is not set
+
+#
+# QoS and/or fair queueing
+#
X # CONFIG_NET_SCHED is not set
X
X #
@@ -195,7 +199,6 @@
X # CONFIG_SCSI_PSI240I is not set
X # CONFIG_SCSI_QLOGIC_FAS is not set
X # CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
X # CONFIG_SCSI_SEAGATE is not set
X # CONFIG_SCSI_DC390T is not set
X # CONFIG_SCSI_T128 is not set
@@ -311,7 +314,7 @@
X #
X CONFIG_VT=y
X CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
+# CONFIG_SERIAL is not set
X # CONFIG_SERIAL_EXTENDED is not set
X # CONFIG_SERIAL_NONSTANDARD is not set
X CONFIG_UNIX98_PTYS=y
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/block/cmd640.c linux/drivers/block/cmd640.c
--- v2.2.0-pre4/linux/drivers/block/cmd640.c Wed Dec 17 11:11:16 1997
+++ linux/drivers/block/cmd640.c Mon Jan 4 15:07:27 1999
@@ -5,10 +5,10 @@
X */
X
X /*
- * Original author: abr...@cecmow.enet.dec.com (Igor Abramov)
+ * Original authors: abr...@cecmow.enet.dec.com (Igor Abramov)
+ * ml...@pobox.com (Mark Lord)
X *
- * Maintained by: ml...@pobox.com (Mark Lord)
- * with fanatical support from a legion of hackers!
+ * See linux/MAINTAINERS for address of current maintainer.
X *
X * This file provides support for the advanced features and bugs
X * of IDE interfaces using the CMD Technologies 0640 IDE interface chip.
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.2.0-pre4/linux/drivers/block/genhd.c Mon Dec 28 15:00:52 1998
+++ linux/drivers/block/genhd.c Mon Jan 4 11:51:29 1999
@@ -570,6 +570,12 @@
X bsd_kdev = MKDEV(hd->major, minor);
X bsd_maxpart = OPENBSD_MAXPARTITIONS;
X }
+ } else if (SYS_IND(p) == NETBSD_PARTITION) {
+ printk("!");
+ if (!bsd_kdev) {
+ bsd_kdev = MKDEV(hd->major, minor);
+ bsd_maxpart = BSD_MAXPARTITIONS;
+ }
X }
X #endif
X #ifdef CONFIG_UNIXWARE_DISKLABEL
@@ -1336,7 +1342,7 @@
X int get_partition_list(char * page)
X {
X struct gendisk *p;
- char buf[8];
+ char buf[32];
X int n, len;
X
X len = sprintf(page, "major minor #blocks name\n\n");
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/block/ide-disk.c linux/drivers/block/ide-disk.c
--- v2.2.0-pre4/linux/drivers/block/ide-disk.c Thu Dec 31 10:28:59 1998
+++ linux/drivers/block/ide-disk.c Mon Jan 4 15:07:27 1999
@@ -5,9 +5,10 @@
X */
X
X /*
- * Maintained by Mark Lord <ml...@pobox.com>
- * and Gadi Oxman <ga...@netvision.net.il>
- * and Andre Hedrick <hed...@astro.dyer.vanderbilt.edu>
+ * Mostly written by Mark Lord <ml...@pobox.com>
+ * and Gadi Oxman <ga...@netvision.net.il>
+ *
+ * See linux/MAINTAINERS for address of current maintainer.
X *
X * This is the IDE/ATA disk driver, as evolved from hd.c and ide.c.
X *
@@ -101,12 +102,17 @@
X return 1; /* lba_capacity is our only option */
X }
X /*
- * very large drives (8GB+) may lie about the number of cylinders
X * This is a split test for drives less than 8 Gig only.
+ * Drives less than 8GB sometimes declare that they have 15 heads.
+ * This is an accounting trick (0-15) == (1-16), just an initial
+ * zero point difference.
X */
X if ((id->lba_capacity < 16514064) && (lba_sects > chs_sects) &&
- (id->heads == 16) && (id->sectors == 63)) {
- id->cyls = lba_sects / (16 * 63); /* correct cyls */
+ ((id->heads == 15) || (id->heads == 16)) && (id->sectors == 63)) {
+ if (id->heads == 15)
+ id->cyls = lba_sects / (15 * 63); /* correct cyls */
+ if (id->heads == 16)
+ id->cyls = lba_sects / (16 * 63); /* correct cyls */
X return 1; /* lba_capacity is our only option */
X }
X /* perform a rough sanity check on lba_sects: within 10% is "okay" */
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/block/ide-probe.c linux/drivers/block/ide-probe.c
--- v2.2.0-pre4/linux/drivers/block/ide-probe.c Mon Dec 28 15:00:52 1998
+++ linux/drivers/block/ide-probe.c Mon Jan 4 15:07:27 1999
@@ -5,8 +5,10 @@
X */
X
X /*
- * Maintained by Mark Lord <ml...@pobox.com>
- * and Gadi Oxman <ga...@netvision.net.il>
+ * Mostly written by Mark Lord <ml...@pobox.com>
+ * and Gadi Oxman <ga...@netvision.net.il>
+ *
+ * See linux/MAINTAINERS for address of current maintainer.
X *
X * This is the IDE probe module, as evolved from hd.c and ide.c.
X *
@@ -587,7 +589,12 @@
X drive->next = hwgroup->drive->next;
X hwgroup->drive->next = drive;
X }
- hwgroup->hwif = HWIF(hwgroup->drive);
+ if (!hwgroup->hwif) {
+ hwgroup->hwif = HWIF(hwgroup->drive);
+#ifdef DEBUG
+ printk("%s : Adding missed hwif to hwgroup!!\n", hwif->name);
+#endif
+ }
X restore_flags(flags); /* all CPUs; safe now that hwif->hwgroup is set up */
X
X #if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__)
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c
--- v2.2.0-pre4/linux/drivers/block/ide-tape.c Thu Dec 31 10:28:59 1998
+++ linux/drivers/block/ide-tape.c Mon Jan 4 11:37:29 1999
@@ -212,7 +212,7 @@
X * number of tape blocks.
X * Add support for INTERRUPT DRQ devices.
X * Ver 1.13 Jan 2 98 Add "speed == 0" work-around for HP COLORADO 5GB
- * Ver 1.14 Dec 30 99 Partial fixes for the Sony/AIWA tape drives.
+ * Ver 1.14 Dec 30 98 Partial fixes for the Sony/AIWA tape drives.
X * Replace cli()/sti() with hwgroup spinlocks.
X *
X * Here are some words from the first releases of hd.c, which are quoted
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v2.2.0-pre4/linux/drivers/block/ide.c Fri Jan 1 12:58:19 1999
+++ linux/drivers/block/ide.c Mon Jan 4 15:07:27 1999
@@ -5,8 +5,10 @@
X */
X
X /*
- * Maintained by Mark Lord <ml...@pobox.com>
- * and Gadi Oxman <ga...@netvision.net.il>
+ * Mostly written by Mark Lord <ml...@pobox.com>
+ * and Gadi Oxman <ga...@netvision.net.il>
+ *
+ * See linux/MAINTAINERS for address of current maintainer.
X *
X * This is the multiple IDE interface driver, as evolved from hd.c.
X * It supports up to MAX_HWIFS IDE interfaces, on one or more IRQs (usually 14 & 15).
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/block/opti621.c linux/drivers/block/opti621.c
--- v2.2.0-pre4/linux/drivers/block/opti621.c Thu May 7 22:51:48 1998
+++ linux/drivers/block/opti621.c Mon Jan 4 15:07:27 1999
@@ -1,20 +1,26 @@
X /*
- * linux/drivers/block/opti621.c Version 0.3 Nov 29, 1997
+ * linux/drivers/block/opti621.c Version 0.6 Jan 02, 1999
X *
- * Copyright (C) 1996-1998 Linus Torvalds & author (see below)
+ * Copyright (C) 1996-1998 Linus Torvalds & authors (see below)
X */
X
X /*
- * OPTi 82C621 chipset EIDE controller driver
- * Author: Jaromir Koutek (E-mail: Jaromir...@st.mff.cuni.cz)
- *
+ * Authors:
+ * Jaromir Koutek <mi...@punknet.cz>,
+ * Jan Harkes <jaha...@cwi.nl>,
+ * Mark Lord <ml...@pobox.com>
X * Some parts of code are from ali14xx.c and from rz1000.c.
+ *
+ * OPTi is trademark of OPTi, Octek is trademark of Octek.
+ *
X * I used docs from OPTi databook, from ftp.opti.com, file 9123-0002.ps
X * and disassembled/traced setupvic.exe (DOS program).
X * It increases kernel code about 2 kB.
+ * I don't have this card no more, but I hope I can get some in case
+ * of needed development.
X * My card is Octek PIDE 1.01 (on card) or OPTiViC (program).
X * It has a place for a secondary connector in circuit, but nothing
- * is there. It cost about $25. Also BIOS says no address for
+ * is there. Also BIOS says no address for
X * secondary controller (see bellow in ide_init_opti621).
X * I've only tested this on my system, which only has one disk.
X * It's Western Digital WDAC2850, with PIO mode 3. The PCI bus
@@ -26,8 +32,18 @@
X * with the third, 1GB drive: I got 3MB/s (hdparm), but sometimes
X * it slows to about 100kB/s! I don't know why and I have
X * not this drive now, so I can't try it again.
- * If you have two disk, please boot in single mode and carefully
- * (you can boot on read-only fs) try to set PIO mode 0 etc.
+ * I write this driver because I lost the paper ("manual") with
+ * settings of jumpers on the card and I have to boot Linux with
+ * Loadlin except LILO, cause I have to run the setupvic.exe program
+ * already or I get disk errors (my test: rpm -Vf
+ * /usr/X11R6/bin/XF86_SVGA - or any big file).
+ * Some numbers from hdparm -t /dev/hda:
+ * Timing buffer-cache reads: 32 MB in 3.02 seconds =10.60 MB/sec
+ * Timing buffered disk reads: 16 MB in 5.52 seconds = 2.90 MB/sec
+ * I have 4 Megs/s before, but I don't know why (maybe changes
+ * in hdparm test).
+ * After release of 0.1, I got some successful reports, so it might work.
+ *
X * The main problem with OPTi is that some timings for master
X * and slave must be the same. For example, if you have master
X * PIO 3 and slave PIO 0, driver have to set some timings of
@@ -38,25 +54,37 @@
X * for autoselect mode (you can change it to PIO 0, if you want).
X * If you then set the second drive to another PIO, the old value
X * (automatically selected) will be overrided by yours.
- * I don't know what there is a 25/33MHz switch in configuration
- * register, driver is written for use at any frequency which get
+ * There is a 25/33MHz switch in configuration
+ * register, but driver is written for use at any frequency which get
X * (use idebus=xx to select PCI bus speed).
X * Use ide0=autotune for automatical tune of the PIO modes.
X * If you get strange results, do not use this and set PIO manually
X * by hdparm.
- * I write this driver because I lost the paper ("manual") with
- * settings of jumpers on the card and I have to boot Linux with
- * Loadlin except LILO, cause I have to run the setupvic.exe program
- * already or I get disk errors (my test: rpm -Vf
- * /usr/X11R6/bin/XF86_SVGA - or any big file).
- * Some numbers from hdparm -t /dev/hda:
- * Timing buffer-cache reads: 32 MB in 3.02 seconds =10.60 MB/sec
- * Timing buffered disk reads: 16 MB in 5.52 seconds = 2.90 MB/sec
- * I have 4 Megs/s before, but I don't know why (maybe bad hdparm).
- * If you tried this driver, please send me a E-mail of your experiences.
- * My E-mail address is Jaromir...@st.mff.cuni.cz (I hope
- * till 30. 6. 2000), otherwise you can try mi...@atrey.karlin.mff.cuni.cz.
- * I think OPTi is trademark of OPTi, Octek is trademark of Octek and so on.
+ *
+ * Version 0.1, Nov 8, 1996
+ * by Jaromir Koutek, for 2.1.8.
+ * Initial version of driver.
+ *
+ * Version 0.2
+ * Number 0.2 skipped.
+ *
+ * Version 0.3, Nov 29, 1997
+ * by Mark Lord (probably), for 2.1.68
+ * Updates for use with new IDE block driver.
+ *
+ * Version 0.4, Dec 14, 1997
+ * by Jan Harkes
+ * Fixed some errors and cleaned the code.
+ *
+ * Version 0.5, Jan 2, 1998
+ * by Jaromir Koutek
+ * Updates for use with (again) new IDE block driver.
+ * Update of documentation.
+ *
+ * Version 0.6, Jan 2, 1999
+ * by Jaromir Koutek
+ * Reversed to version 0.3 of the driver, because
+ * 0.5 doesn't work.
X */
X
X #undef REALLY_SLOW_IO /* most systems can safely undef this */
@@ -98,8 +126,10 @@
X
X #define READ_REG 0 /* index of Read cycle timing register */
X #define WRITE_REG 1 /* index of Write cycle timing register */
-#define MISC_REG 6 /* index of Miscellaneous register */
X #define CNTRL_REG 3 /* index of Control register */
+#define STRAP_REG 5 /* index of Strap register */
+#define MISC_REG 6 /* index of Miscellaneous register */
+
X int reg_base;
X
X #define PIO_NOT_EXIST 254
@@ -203,9 +233,10 @@
X clks->recovery_time = 2;
X /* minimal values */
X }
+
X }
X
-/* Main tune procedure, hooked by tuneproc. */
+/* Main tune procedure, called from tuneproc. */
X static void opti621_tune_drive (ide_drive_t *drive, byte pio)
X {
X /* primary and secondary drives share some registers,
@@ -218,7 +249,7 @@
X byte cycle1, cycle2, misc;
X ide_hwif_t *hwif = HWIF(drive);
X
- /* set drive->drive_data for both drives */
+ /* sets drive->drive_data for both drives */
X compute_pios(drive, pio);
X pio1 = hwif->drives[0].drive_data;
X pio2 = hwif->drives[1].drive_data;
@@ -250,7 +281,7 @@
X outb(0xff, reg_base+5); /* hmm, setupvic.exe does this ;-) */
X inb(reg_base+CNTRL_REG); /* if reads 0xff, adapter not exist? */
X read_reg(CNTRL_REG); /* if reads 0xc0, no interface exist? */
- read_reg(5); /* read version, probably 0 */
+ read_reg(STRAP_REG); /* read version, probably 0 */
X
X /* program primary drive */
X write_reg(0, MISC_REG); /* select Index-0 for Register-A */
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/block/rz1000.c linux/drivers/block/rz1000.c
--- v2.2.0-pre4/linux/drivers/block/rz1000.c Tue Apr 14 14:29:20 1998
+++ linux/drivers/block/rz1000.c Mon Jan 4 15:07:27 1999
@@ -5,7 +5,9 @@
X */
X
X /*
- * Principal Author/Maintainer: ml...@pobox.com (Mark Lord)
+ * Principal Author: ml...@pobox.com (Mark Lord)
+ *
+ * See linux/MAINTAINERS for address of current maintainer.
X *
X * This file provides support for disabling the buggy read-ahead
X * mode of the RZ1000 IDE chipset, commonly used on Intel motherboards.
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c
--- v2.2.0-pre4/linux/drivers/cdrom/cdrom.c Mon Dec 28 15:00:52 1998
+++ linux/drivers/cdrom/cdrom.c Mon Jan 4 11:58:44 1999
@@ -376,8 +376,10 @@
X }
X cdinfo(CD_OPEN, "the tray is now closed.\n");
X }
- if (ret!=CDS_DISC_OK)
+ if (ret!=CDS_DISC_OK) {
+ ret = -ENOMEDIUM;
X goto clean_up_and_return;
+ }
X }
X cdrom_count_tracks(cdi, &tracks);
X if (tracks.error == CDS_NO_DISC) {
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
--- v2.2.0-pre4/linux/drivers/char/cyclades.c Fri Jan 1 12:58:19 1999
+++ linux/drivers/char/cyclades.c Mon Jan 4 11:37:29 1999
@@ -584,10 +584,8 @@
X #include <linux/pci.h>
X #include <linux/version.h>
X
-#ifdef CONFIG_PROC_FS
X #include <linux/stat.h>
X #include <linux/proc_fs.h>
-#endif
X
X #define cy_put_user put_user
X
@@ -781,9 +779,7 @@
X static void show_status(int);
X #endif
X
-#ifdef CONFIG_PROC_FS
X static int cyclades_get_proc_info(char *, char **, off_t , int , int *, void *);
-#endif
X
X /* The Cyclades-Z polling cycle is defined by this variable */
X static long cyz_polling_cycle = CZ_DEF_POLL;
@@ -4952,7 +4948,6 @@
X __DATE__, __TIME__);
X } /* show_version */
X
-#ifdef CONFIG_PROC_FS
X static int
X cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
X int *eof, void *data)
@@ -5009,7 +5004,6 @@
X len = 0;
X return len;
X }
-#endif
X
X
X /* The serial driver boot-time initialization code!
@@ -5281,15 +5275,8 @@
X #endif
X }
X
-#ifdef CONFIG_PROC_FS
X ent = create_proc_entry("cyclades", S_IFREG | S_IRUGO, 0);
X ent->read_proc = cyclades_get_proc_info;
-#endif
-#if 0
-#ifdef CONFIG_PROC_FS
- proc_register(&proc_root, &cyclades_proc_entry);
-#endif
-#endif
X
X return 0;
X
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/char/mem.c linux/drivers/char/mem.c
--- v2.2.0-pre4/linux/drivers/char/mem.c Tue Dec 22 14:16:55 1998
+++ linux/drivers/char/mem.c Tue Jan 5 11:35:20 1999
@@ -138,26 +138,49 @@
X return do_write_mem(file, __va(p), p, buf, count, ppos);
X }
X
+/*
+ * This should probably be per-architecture in <asm/pgtable.h>
+ */
+static inline unsigned long pgprot_noncached(unsigned long prot)
+{
+#if defined(__i386__)
+ if (boot_cpu_data.x86 > 3)
+ prot |= _PAGE_PCD;
+#elif defined(__powerpc__)
+ prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+#elif defined(__mc68000__)
+ if (CPU_IS_020_OR_030)
+ prot |= _PAGE_NOCACHE030;
+ /* Use no-cache mode, serialized */
+ if (CPU_IS_040_OR_060)
+ prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S;
+#elif defined(__mips__)
+ prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
+#endif
+
+ return prot;
+}
+
X static int mmap_mem(struct file * file, struct vm_area_struct * vma)
X {
X unsigned long offset = vma->vm_offset;
X
X if (offset & ~PAGE_MASK)
X return -ENXIO;
-#if defined(__i386__)
+
X /*
- * hmm.. This disables high-memory caching, as the XFree86 team
- * wondered about that at one time.
- * The surround logic should disable caching for the high device
- * addresses anyway, but right now this seems still needed.
+ * Accessing memory above the top the kernel knows about or
+ * through a file pointer that was marked O_SYNC will be
+ * done non-cached.
+ *
+ * Set VM_IO, as this is likely a non-cached access to an
+ * I/O area, and we don't want to include that in a core
+ * file.
X */
- if (boot_cpu_data.x86 > 3 && offset >= __pa(high_memory))
- pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-#endif
-#ifdef __powerpc__
- if (offset >= __pa(high_memory))
- pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;
-#endif
+ if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC)) {
+ pgprot_val(vma->vm_page_prot) = pgprot_noncached(pgprot_val(vma->vm_page_prot));
+ vma->vm_flags |= VM_IO;
+ }
X if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
X vma->vm_page_prot))
X return -EAGAIN;
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v2.2.0-pre4/linux/drivers/char/serial.c Mon Dec 28 15:00:52 1998
+++ linux/drivers/char/serial.c Mon Jan 4 11:37:29 1999
@@ -2356,6 +2356,17 @@
X char_time = 1;
X if (timeout)
X char_time = MIN(char_time, timeout);
+ /*
+ * If the transmitter hasn't cleared in twice the approximate
+ * amount of time to send the entire FIFO, it probably won't
+ * ever clear. This assumes the UART isn't doing flow
+ * control, which is currently the case. Hence, if it ever
+ * takes longer than info->timeout, this is probably due to a
+ * UART bug of some kind. So, we clamp the timeout parameter at
+ * 2*info->timeout.
+ */
+ if (!timeout || timeout > 2*info->timeout)
+ timeout = 2*info->timeout;
X #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
X printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
X printk("jiff=%lu...", jiffies);
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c
--- v2.2.0-pre4/linux/drivers/isdn/hisax/config.c Wed Apr 1 20:11:50 1998
+++ linux/drivers/isdn/hisax/config.c Mon Jan 4 11:37:29 1999
@@ -97,8 +97,10 @@
X #ifdef CONFIG_HISAX_ELSA
X #define DEFAULT_CARD ISDN_CTYPE_ELSA
X #define DEFAULT_CFG {0,0,0,0}
+#ifdef MODULE
X int elsa_init_pcmcia(void*, int, int*, int);
X EXPORT_SYMBOL(elsa_init_pcmcia);
+#endif
X #endif
X #ifdef CONFIG_HISAX_AVM_A1
X #undef DEFAULT_CARD
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/net/acenic_firmware.h linux/drivers/net/acenic_firmware.h
--- v2.2.0-pre4/linux/drivers/net/acenic_firmware.h Tue Dec 22 14:16:55 1998
+++ linux/drivers/net/acenic_firmware.h Wed Jan 6 09:39:23 1999
@@ -13,7 +13,7 @@
X int tigonFwBssLen = 0x2080;
X u32 tigonFwSbssAddr = 0x15090;
X int tigonFwSbssLen = 0x28;
-u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __init = {
+u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
X 0x10000003, 0x0, 0xd, 0xd, 0x3c1d0001, 0x8fbd4f84,
X 0x3a0f021, 0x3c100000, 0x26104000, 0xc00100c, 0x0, 0xd,
X 0x27bdffd8, 0x3c1cc000, 0x3c1b0013, 0x377bd800, 0xd021, 0x3c170013,
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/net/plip.c linux/drivers/net/plip.c
--- v2.2.0-pre4/linux/drivers/net/plip.c Thu Dec 31 10:29:00 1998
+++ linux/drivers/net/plip.c Mon Jan 4 16:06:00 1999
@@ -1227,7 +1227,6 @@
X plip_init(void))
X {
X struct parport *pb = parport_enumerate();
- int devices=0;
X int i=0;
X
X if (parport[0] == -2)
@@ -1238,7 +1237,7 @@
X timid = 0;
X }
X
- /* When user feeds parameters, use them */
+ /* If the user feeds parameters, use them */
X while (pb) {
X if ((parport[0] == -1 && (!timid || !pb->devices)) ||
X plip_searchfor(parport, i)) {
@@ -1266,14 +1265,13 @@
X kfree(dev_plip[i]->name);
X kfree(dev_plip[i]);
X } else {
- devices++;
+ i++;
X }
X }
- i++;
X pb = pb->next;
X }
X
- if (devices == 0) {
+ if (i == 0) {
X printk(KERN_INFO "plip: no devices registered\n");
X return -EIO;
X }
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/net/sdla_fr.c linux/drivers/net/sdla_fr.c
--- v2.2.0-pre4/linux/drivers/net/sdla_fr.c Fri Oct 23 22:01:21 1998
+++ linux/drivers/net/sdla_fr.c Mon Jan 4 11:37:29 1999
@@ -1078,6 +1078,8 @@
X ++chan->if_send_bfrs_passed_to_adptr;
X ++chan->ifstats.tx_packets;
X ++card->wandev.stats.tx_packets;
+ chan->ifstats.tx_bytes += skb->len;
+ card->wandev.stats.tx_bytes += skb->len;
X }
X }
X }
@@ -1501,6 +1503,8 @@
X netif_rx(skb);
X ++chan->ifstats.rx_packets;
X ++card->wandev.stats.rx_packets;
+ chan->ifstats.rx_bytes += skb->len;
+ card->wandev.stats.rx_bytes += skb->len;
X }
X }
X sdla_mapmem(&card->hw, FR_MB_VECTOR);
@@ -1621,6 +1625,8 @@
X ++chan->rx_intr_bfr_passed_to_stack;
X ++chan->ifstats.rx_packets;
X ++card->wandev.stats.rx_packets;
+ chan->ifstats.rx_bytes += skb->len;
+ card->wandev.stats.rx_bytes += skb->len;
X }
X }
X }
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/net/sdla_ppp.c linux/drivers/net/sdla_ppp.c
--- v2.2.0-pre4/linux/drivers/net/sdla_ppp.c Fri Oct 23 22:01:21 1998
+++ linux/drivers/net/sdla_ppp.c Mon Jan 4 11:37:29 1999
@@ -698,6 +698,7 @@
X } else {
X ++ppp_priv_area->if_send_bfr_passed_to_adptr;
X ++card->wandev.stats.tx_packets;
+ card->wandev.stats.tx_bytes += skb->len;
X }
X }
X tx_done:
@@ -1202,6 +1203,7 @@
X skb->mac.raw = skb->data;
X netif_rx(skb);
X ++card->wandev.stats.rx_packets;
+ card->wandev.stats.rx_bytes += skb->len;
X ++ppp_priv_area->rx_intr_bfr_passed_to_stack;
X }
X } else {
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/net/sdla_x25.c linux/drivers/net/sdla_x25.c
--- v2.2.0-pre4/linux/drivers/net/sdla_x25.c Fri Jan 1 12:58:20 1999
+++ linux/drivers/net/sdla_x25.c Mon Jan 4 11:37:29 1999
@@ -1028,6 +1028,7 @@
X {
X netif_rx(skb);
X ++chan->ifstats.rx_packets;
+ chan->ifstats.rx_bytes += skb->len;
X }
X }
X }
@@ -2122,6 +2123,7 @@
X return 1;
X }
X ++chan->ifstats.tx_packets;
+ chan->ifstats.tx_bytes += skb->len;
X break;
X
X case 0x33: /* Tx busy */
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/net/tulip.c linux/drivers/net/tulip.c
--- v2.2.0-pre4/linux/drivers/net/tulip.c Thu Dec 31 10:29:01 1998
+++ linux/drivers/net/tulip.c Mon Jan 4 11:37:29 1999
@@ -75,7 +75,6 @@
X #include <linux/malloc.h>
X #include <linux/interrupt.h>
X #include <linux/pci.h>
-#include <linux/bios32.h>
X
X #include <asm/processor.h> /* Processor type for cache alignment. */
X #include <asm/bitops.h>
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c
--- v2.2.0-pre4/linux/drivers/pci/oldproc.c Mon Jan 4 15:08:17 1999
+++ linux/drivers/pci/oldproc.c Mon Jan 4 12:57:44 1999
@@ -539,6 +539,7 @@
X DEVICE( ADAPTEC, ADAPTEC_7884, "AIC-7884U"),
X DEVICE( ADAPTEC, ADAPTEC_1030, "ABA-1030 DVB receiver"),
X DEVICE( ADAPTEC2, ADAPTEC2_2940U2,"AHA-2940U2"),
+ DEVICE( ADAPTEC2, ADAPTEC2_78902, "AIC-7890/1"),
X DEVICE( ADAPTEC2, ADAPTEC2_7890, "AIC-7890/1"),
X DEVICE( ADAPTEC2, ADAPTEC2_3940U2,"AHA-3940U2"),
X DEVICE( ADAPTEC2, ADAPTEC2_3950U2D,"AHA-3950U2D"),
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/scsi/README.aic7xxx linux/drivers/scsi/README.aic7xxx
--- v2.2.0-pre4/linux/drivers/scsi/README.aic7xxx Fri Oct 23 22:01:21 1998
+++ linux/drivers/scsi/README.aic7xxx Mon Jan 4 12:57:44 1999
@@ -37,8 +37,10 @@
X AHA-3940U
X AHA-3940W
X AHA-3940UW
+ AHA-3940AUW
X AHA-3940U2W
X AHA-3950U2B
+ AHA-3950U2D
X AHA-3985
X AHA-3985U
X AHA-3985W
@@ -52,6 +54,7 @@
X AIC-787x
X AIC-788x
X AIC-789x
+ AIC-3860
X
X Bus Types
X ----------------------------
@@ -69,8 +72,30 @@
X AHA-398x - PCI RAID controllers with three separate SCSI controllers
X on-board.
X
- NOTE: The AHA-2920 is NOT an AIC-7xxx based controller, and is not
- handled by this driver.
+ Not Supported Devices
+ ------------------------------
+ Adaptec Cards
+ ----------------------------
+ AHA-2920 (Only the cards that use the Future Domain chipset are not
+ supported, any 2920 cards based on Adaptec AIC chipsets are
+ supported)
+ AAA-13x Raid Adapters
+ AAA-113x Raid Port Card
+
+ Motherboard Chipsets
+ ----------------------------
+ AIC-7810
+
+ Bus Types
+ ----------------------------
+ R - Raid Port busses are not supported.
+
+ The hardware RAID devices sold by Adaptec are *NOT* supported by this
+ driver (and will people please stop emailing me about them, they are
+ a totally separate beast from the bare SCSI controllers and this driver
+ can not be retrofitted in any sane manner to support the hardware RAID
+ features on those cards - Doug Ledford).
+
X
X People
X ------------------------------
@@ -299,13 +324,12 @@
X binary->hex conversion then send an email to the aic7xxx mailing
X list and someone can help you out.
X
- "aic7xxx=tag_info:{{8,8..},{8,8..},..}" - This option is used to enable
- tagged queueing on specific devices. As of driver version 5.0.6, we
- now globally enable tagged queueing by default, but we also disable
- tagged queueing on all individual devices by default. In order to
- enable tagged queueing for certian devices at boot time, a user may
+ "aic7xxx=tag_info:{{8,8..},{8,8..},..}" - This option is used to disable
+ tagged queueing on specific devices. As of driver version 5.1.8, we
+ now globally enable tagged queueing by default. In order to
+ disable tagged queueing for certian devices at boot time, a user may
X use this boot param. The driver will then parse this message out
- and enable the specific device entries that are present based upon
+ and disable the specific device entries that are present based upon
X the value given. The param line is parsed in the following manner:
X
X { - first instance indicates the start of this parameter values
@@ -337,18 +361,13 @@
X commas with no value specified will simply increment to the next id
X without changing anything for the missing values.
X
- tag_info:{{8,8},,{8,8}}
- First adapter, scsi id 0 to 8, id 1 to 8, remainder stay at their
- default. Second adapter stays entirely at default. Third
- adapter, id 0 to 8, id 1 to 8, remainder at default (identical to
- first adapter).
-
- tag_info:{,,,{,,,64}}
+ tag_info:{,,,{,,,255}}
X First, second, and third adapters at default values. Fourth
- adapter, id 3 to 64. Notice that leading commas simply increment
- what the first number effects, and there are no need for trailing
- commas. When you close out an adapter, or the entire entry,
- anything not explicitly set stays at the default value.
+ adapter, id 3 is disabled. Notice that leading commas simply
+ increment what the first number effects, and there are no need
+ for trailing commas. When you close out an adapter, or the
+ entire entry, anything not explicitly set stays at the default
+ value.
X
X A final note on this option. The scanner I used for this isn't
X perfect or highly robust. If you mess the line up, the worst that
@@ -449,10 +468,16 @@
X ftp://ekf2.vsb.cz/pub/linux/kernel/aic7xxx/ftp.teleport.com/
X - European Linux mirror of Teleport site
X
+ Web sites
+ ------------------------------
+ http://developer.redhat.com/aic7xxx/
+ - Primary web site maintained by Doug Ledford. I haven't actually
+ put anything up yet....but I'm planning on it. This information
+ is put here as an add for the vapor page :)
X
X Dean W. Gehnert
X de...@teleport.com
X
X $Revision: 3.0 $
X
-Modified by Doug Ledford 1998
+Modified by Doug Ledford 1998-9
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
--- v2.2.0-pre4/linux/drivers/scsi/aic7xxx.c Mon Jan 4 15:08:17 1999
+++ linux/drivers/scsi/aic7xxx.c Tue Jan 5 23:58:35 1999
@@ -100,7 +100,7 @@
X *
X * Further driver modifications made by Doug Ledford <dled...@redhat.com>
X *
- * Copyright (c) 1997-1998 Doug Ledford
+ * Copyright (c) 1997-1999 Doug Ledford
X *
X * These changes are released under the same licensing terms as the FreeBSD
X * driver written by Justin Gibbs. Please see his Copyright notice above
@@ -354,7 +354,7 @@
X 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
X };
X
-#define AIC7XXX_C_VERSION "5.1.7"
+#define AIC7XXX_C_VERSION "5.1.9"
X
X #define NUMBER(arr) (sizeof(arr) / sizeof(arr[0]))
X #define MIN(a,b) (((a) < (b)) ? (a) : (b))
@@ -449,6 +449,8 @@
X */
X #ifdef CONFIG_AIC7XXX_CMDS_PER_LUN
X #define AIC7XXX_CMDS_PER_LUN CONFIG_AIC7XXX_CMDS_PER_LUN
+#else
+#define AIC7XXX_CMDS_PER_LUN 24
X #endif
X
X /* Set this to the delay in seconds after SCSI bus reset. */
@@ -511,8 +513,8 @@
X * Make a define that will tell the driver not to use tagged queueing
X * by default.
X */
-#define DEFAULT_TAG_COMMANDS {255, 255, 255, 255, 255, 255, 255, 255,\
- 255, 255, 255, 255, 255, 255, 255, 255}
+#define DEFAULT_TAG_COMMANDS {0, 0, 0, 0, 0, 0, 0, 0,\
+ 0, 0, 0, 0, 0, 0, 0, 0}
X
X /*
X * Modify this as you see fit for your system. By setting tag_commands
@@ -884,6 +886,7 @@
X * and what flags weren't. This way, I could clean up the flag usage on
X * a use by use basis. Doug Ledford
X */
+ AHC_RESET_DELAY = 0x00080000,
X AHC_A_SCANNED = 0x00100000,
X AHC_B_SCANNED = 0x00200000,
X AHC_MULTI_CHANNEL = 0x00400000,
@@ -1042,6 +1045,10 @@
X unsigned long isr_count; /* Interrupt count */
X unsigned long spurious_int;
X scb_data_type *scb_data;
+ volatile unsigned short needsdtr;
+ volatile unsigned short sdtr_pending;
+ volatile unsigned short needwdtr;
+ volatile unsigned short wdtr_pending;
X struct aic7xxx_cmd_queue {
X Scsi_Cmnd *head;
X Scsi_Cmnd *tail;
@@ -1073,12 +1080,15 @@
X volatile unsigned char dev_temp_queue_depth[MAX_TARGETS];
X unsigned char dev_commands_sent[MAX_TARGETS];
X
+ unsigned int dev_timer_active; /* Which devs have a timer set */
+ struct timer_list dev_timer;
+ unsigned long dev_expires[MAX_TARGETS];
+
X #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
X spinlock_t spin_lock;
X volatile unsigned char cpu_lock_count[NR_CPUS];
X #endif
X
- unsigned short dev_timer_active; /* Which devs have a timer set */
X
X #ifdef AIC7XXX_FAKE_NEGOTIATION_CMDS
X Scsi_Cmnd *dev_wdtr_cmnd[MAX_TARGETS];
@@ -1091,12 +1101,6 @@
X
X volatile scb_queue_type delayed_scbs[MAX_TARGETS];
X
- unsigned long dev_expires[MAX_TARGETS];
- struct timer_list dev_timer;
-
- /*
- * The next 64....
- */
X
X unsigned char msg_buf[9]; /* The message for the target */
X unsigned char msg_type;
@@ -1123,16 +1127,11 @@
X volatile unsigned char qoutfifo[256];
X volatile unsigned char qinfifo[256];
X unsigned int irq; /* IRQ for this adapter */
- volatile unsigned short needsdtr;
- volatile unsigned short sdtr_pending;
- volatile unsigned short needwdtr;
- volatile unsigned short wdtr_pending;
X int instance; /* aic7xxx instance number */
X int scsi_id; /* host adapter SCSI ID */
X int scsi_id_b; /* channel B for twin adapters */
X unsigned int bios_address;
X int board_name_index;
- unsigned long reset_start;
X unsigned short needsdtr_copy; /* default config */
X unsigned short needwdtr_copy; /* default config */
X unsigned short ultraenb; /* Ultra mode target list */
@@ -1150,7 +1149,6 @@
X struct Scsi_Host *host; /* pointer to scsi host */
X int host_no; /* SCSI host number */
X unsigned long mbase; /* I/O memory address */
- unsigned long last_reset;
X ahc_chip chip; /* chip type */
X
X /*
@@ -1166,21 +1164,21 @@
X *
X * NOTE: Enabling this feature is likely to cause a noticeable performance
X * decrease as the accesses into the stats structures blows apart multiple
- * cache lines and is CPU time consuming. We keep the xfer count always
- * for use by the aic7xxx_proc.c code, but only do the bins if the
- * proc stats code is enabled.
+ * cache lines and is CPU time consuming.
+ *
+ * NOTE: Since it doesn't really buy us much, but consumes *tons* of RAM
+ * and blows apart all sorts of cache lines, I modified this so that we
+ * no longer look at the LUN. All LUNs now go into the same bin on each
+ * device for stats purposes.
X */
X struct aic7xxx_xferstats {
- long w_total; /* total writes */
- long r_total; /* total reads */
+ long w_total; /* total writes */
+ long r_total; /* total reads */
X #ifdef AIC7XXX_PROC_STATS
- long xfers; /* total xfer count */
- long w_total512; /* 512 byte blocks written */
- long r_total512; /* 512 byte blocks read */
- long w_bins[10]; /* binned write */
- long r_bins[10]; /* binned reads */
+ long w_bins[8]; /* binned write */
+ long r_bins[8]; /* binned reads */
X #endif /* AIC7XXX_PROC_STATS */
- } stats[MAX_TARGETS][MAX_LUNS]; /* [(channel << 3)|target][lun] */
+ } stats[MAX_TARGETS]; /* [(channel << 3)|target] */
X
X #if 0
X struct target_cmd *targetcmds;
@@ -3092,7 +3090,7 @@
X int x;
X #endif /* AIC7XXX_PROC_STATS */
X
- sp = &p->stats[TARGET_INDEX(cmd)][cmd->lun & 0x7];
+ sp = &p->stats[TARGET_INDEX(cmd)];
X
X /*
X * For block devices, cmd->request.cmd is always == either READ or
@@ -3109,8 +3107,6 @@
X aic7xxx_verbose &= 0xffff;
X #endif
X #ifdef AIC7XXX_PROC_STATS
- sp->xfers++;
- sp->w_total512 += (actual >> 9);
X ptr = sp->w_bins;
X #endif /* AIC7XXX_PROC_STATS */
X }
@@ -3122,23 +3118,27 @@
X aic7xxx_verbose &= 0xffff;
X #endif
X #ifdef AIC7XXX_PROC_STATS
- sp->xfers++;
- sp->r_total512 += (actual >> 9);
X ptr = sp->r_bins;
X #endif /* AIC7XXX_PROC_STATS */
X }
X #ifdef AIC7XXX_PROC_STATS
- for (x = 9; x <= 17; x++)
+ x = -10;
+ while(actual)
X {
- if (actual < (1 << x))
- {
- ptr[x - 9]++;
- break;
- }
+ actual >>= 1;
+ x++;
+ }
+ if (x < 0)
+ {
+ ptr[0]++;
+ }
+ else if (x > 7)
+ {
+ ptr[7]++;
X }
- if (x > 17)
+ else
X {
- ptr[x - 9]++;
+ ptr[x]++;
X }
X #endif /* AIC7XXX_PROC_STATS */
X }
@@ -3486,13 +3486,13 @@
X "delayed_scbs queue!\n", p->host_no, channel, i, lun);
X scbq_init(&p->delayed_scbs[i]);
X }
- if ( !(p->dev_timer_active & (0x01 << p->scsi_id)) ||
+ if ( !(p->dev_timer_active & (0x01 << MAX_TARGETS)) ||
X time_after_eq(p->dev_timer.expires, p->dev_expires[i]) )
X {
X del_timer(&p->dev_timer);
X p->dev_timer.expires = p->dev_expires[i];
X add_timer(&p->dev_timer);
- p->dev_timer_active |= (0x01 << p->scsi_id);
+ p->dev_timer_active |= (0x01 << MAX_TARGETS);
X }
X }
X }
@@ -3958,12 +3958,6 @@
X */
X aic7xxx_reset_device(p, ALL_TARGETS, channel, ALL_LUNS, SCB_LIST_NULL);
X
- /*
- * Convince Mid Level SCSI code to leave us be for a little bit...
- */
- p->last_reset = jiffies;
- p->host->last_reset = (jiffies + (HZ * AIC7XXX_RESET_DELAY));
-
X if ( !(p->features & AHC_TWIN) )
X {
X restart_sequencer(p);
@@ -4009,7 +4003,8 @@
X }
X if ( (p->dev_active_cmds[tindex] >=
X p->dev_temp_queue_depth[tindex]) ||
- (p->dev_flags[tindex] & (DEVICE_RESET_DELAY|DEVICE_WAS_BUSY)) )
+ (p->dev_flags[tindex] & (DEVICE_RESET_DELAY|DEVICE_WAS_BUSY)) ||
+ (p->flags & AHC_RESET_DELAY) )
X {
X scbq_insert_tail(&p->delayed_scbs[tindex], scb);
X }
@@ -4128,14 +4123,17 @@
X #else
X spin_lock_irqsave(&io_request_lock, cpu_flags);
X #endif
- p->dev_timer_active &= ~(0x01 << p->scsi_id);
+ p->dev_timer_active &= ~(0x01 << MAX_TARGETS);
+ if ( (p->dev_timer_active & (0x01 << p->scsi_id)) &&
+ time_after_eq(jiffies, p->dev_expires[p->scsi_id]) )
+ {
+ p->flags &= ~AHC_RESET_DELAY;
+ p->dev_timer_active &= ~(0x01 << p->scsi_id);
+ }
X for(i=0; i<MAX_TARGETS; i++)
X {
- if ( i == p->scsi_id )
- {
- continue;
- }
- if ( (p->dev_timer_active & (0x01 << i)) &&
+ if ( (i != p->scsi_id) &&
+ (p->dev_timer_active & (0x01 << i)) &&
X time_after_eq(jiffies, p->dev_expires[i]) )
X {
X p->dev_timer_active &= ~(0x01 << i);
@@ -4161,7 +4159,7 @@
X }
X else if ( p->dev_timer_active & (0x01 << i) )
X {
- if ( p->dev_timer_active & (0x01 << p->scsi_id) )
+ if ( p->dev_timer_active & (0x01 << MAX_TARGETS) )
X {
X if ( time_after_eq(p->dev_timer.expires, p->dev_expires[i]) )
X {
@@ -4171,11 +4169,11 @@
X else
X {
X p->dev_timer.expires = p->dev_expires[i];
- p->dev_timer_active |= (0x01 << p->scsi_id);
+ p->dev_timer_active |= (0x01 << MAX_TARGETS);
X }
X }
X }
- if ( p->dev_timer_active & (0x01 << p->scsi_id) )
+ if ( p->dev_timer_active & (0x01 << MAX_TARGETS) )
X {
X add_timer(&p->dev_timer);
X }
@@ -4901,10 +4899,10 @@
X {
X p->dev_expires[tindex] = jiffies + (HZ / 10);
X }
- if ( !(p->dev_timer_active & (0x01 << p->scsi_id)) )
+ if ( !(p->dev_timer_active & (0x01 << MAX_TARGETS)) )
X {
X p->dev_timer.expires = p->dev_expires[tindex];
- p->dev_timer_active |= (0x01 << p->scsi_id);
+ p->dev_timer_active |= (0x01 << MAX_TARGETS);
X add_timer(&p->dev_timer);
X }
X else if ( time_after_eq(p->dev_timer.expires,
@@ -6398,11 +6396,7 @@
X {
X int tag_enabled = TRUE;
X
-#ifdef AIC7XXX_CMDS_PER_LUN
X default_depth = AIC7XXX_CMDS_PER_LUN;
-#else
- default_depth = 8; /* Not many SCBs to work with. */
-#endif
X
X if (!(p->discenable & target_mask))
X {
@@ -7448,7 +7442,6 @@
X }
X
X p->host = host;
- p->last_reset = jiffies;
X p->host_no = host->host_no;
X host->unique_id = p->instance;
X p->isr_count = 0;
@@ -7534,10 +7527,9 @@
X }
X aic_outb(p, 0, SEQ_FLAGS);
X
- /*
- * Detect SCB parameters and initialize the SCB array.
- */
X detect_maxscb(p);
+
+
X printk("%d/%d SCBs\n", p->scb_data->maxhscbs, p->scb_data->maxscbs);
X if (aic7xxx_verbose & VERBOSE_PROBE2)
X {
@@ -8841,6 +8833,10 @@
X AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
X AHC_AIC7890_FE, 20,
X 32, C46 },
+ {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_78902, AHC_AIC7890,
+ AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
+ AHC_AIC7890_FE, 20,
+ 32, C46 },
X {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_2940U2, AHC_AIC7890,
X AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED,
X AHC_AIC7890_FE, 21,
@@ -8865,9 +8861,6 @@
X
X unsigned short command;
X unsigned int devconfig, i, oldverbose;
-#ifdef MMAPIO
- unsigned long page_offset, base;
-#endif
X #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
X struct pci_dev *pdev = NULL;
X #else
@@ -9018,21 +9011,68 @@
X temp_p->mbase &= PCI_BASE_ADDRESS_MEM_MASK;
X temp_p->unpause = INTEN;
X temp_p->pause = temp_p->unpause | PAUSE;
+ if ( ((temp_p->base == 0) &&
+ (temp_p->mbase == 0)) ||
+ (temp_p->irq == 0) )
+ {
+ printk("aic7xxx: <%s> at PCI %d/%d\n",
+ board_names[aic_pdevs[i].board_name_index],
+ PCI_SLOT(temp_p->pdev->devfn),
+ PCI_FUNC(temp_p->pdev->devfn));
+ printk("aic7xxx: Controller disabled by BIOS, ignoring.\n");
+ kfree(temp_p);
+ temp_p = NULL;
+ continue;
+ }
X
X #ifdef MMAPIO
- base = temp_p->mbase & PAGE_MASK;
- page_offset = temp_p->mbase - base;
+ {
+ unsigned long page_offset, base;
+
+ base = temp_p->mbase & PAGE_MASK;
+ page_offset = temp_p->mbase - base;
X #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
- temp_p->maddr = ioremap_nocache(base, page_offset + 256);
+ temp_p->maddr = ioremap_nocache(base, page_offset + 256);
X #else
- temp_p->maddr = vremap(base, page_offset + 256);
+ temp_p->maddr = vremap(base, page_offset + 256);
X #endif
- if(temp_p->maddr)
- {
- temp_p->maddr += page_offset;
+ if(temp_p->maddr)
+ {
+ temp_p->maddr += page_offset;
+ /*
+ * We need to check the I/O with the MMAPed address. Some machines
+ * simply fail to work with MMAPed I/O and certain controllers.
+ */
+ if(aic_inb(temp_p, HCNTRL) == 0xff)
+ {
+ /*
+ * OK.....we failed our test....go back to programmed I/O
+ */
+ printk(KERN_INFO "aic7xxx: <%s> at PCI %d/%d\n",
+ board_names[aic_pdevs[i].board_name_index],
+ PCI_SLOT(temp_p->pdev->devfn),
+ PCI_FUNC(temp_p->pdev->devfn));
+ printk(KERN_INFO "aic7xxx: MMAPed I/O failed, reverting to "
+ "Programmed I/O.\n");
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
+ iounmap((void *) (((unsigned long) temp_p->maddr) & PAGE_MASK));
+#else
+ vfree((void *) (((unsigned long) temp_p->maddr) & PAGE_MASK));
+#endif
+ temp_p->maddr = 0;
+ }
+ }
X }
X #endif
X
+ /*
+ * We HAVE to make sure the first pause_sequencer() and all other
+ * subsequent I/O that isn't PCI config space I/O takes place
+ * after the MMAPed I/O region is configured and tested. The
+ * problem is the PowerPC architecture that doesn't support
+ * programmed I/O at all, so we have to have the MMAP I/O set up
+ * for this pause to even work on those machines.
+ */
X pause_sequencer(temp_p);
X
X /*
@@ -9067,30 +9107,20 @@
X }
X
X /*
- * Doing a switch based upon i is really gross, but since Justin
- * changed around the chip ID stuff, we can't use that any more.
- * Since we don't scan the devices the same way as FreeBSD, we end
- * up doing this gross hack in order to avoid totally splitting
- * away from Justin's init code in ahc_pci.c
+ * We need to set the CHNL? assignments before loading the SEEPROM
+ * The 3940 and 3985 cards (original stuff, not any of the later
+ * stuff) are 7870 and 7880 class chips. The Ultra2 stuff falls
+ * under 7896 and 7897. The 7895 is in a class by itself :)
X */
- switch (i)
+ switch (temp_p->chip & AHC_CHIPID_MASK)
X {
- case 7: /* 3940 */
- case 12: /* 3940-Ultra */
+ case AHC_AIC7870: /* 3840 / 3985 */
+ case AHC_AIC7880: /* 3840 UW / 3985 UW */
X switch(PCI_SLOT(temp_p->pci_device_fn))
X {
X case 5:
X temp_p->flags |= AHC_CHNLB;
X break;
- default:
- break;
- }
- break;
-
- case 8: /* 3985 */
- case 13: /* 3985-Ultra */
- switch(PCI_SLOT(temp_p->pci_device_fn))
- {
X case 8:
X temp_p->flags |= AHC_CHNLB;
X break;
@@ -9102,10 +9132,8 @@
X }
X break;
X
- case 15:
- case 18:
- case 19:
- case 20:
+ case AHC_AIC7895: /* 7895 */
+ case AHC_AIC7896: /* 7896/7 */
X #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92)
X if (PCI_FUNC(temp_p->pdev->devfn) != 0)
X {
@@ -10894,23 +10922,14 @@
X }
X action = BUS_RESET;
X }
- if ( ((jiffies - p->last_reset) < (HZ * 3)) &&
- (action & (HOST_RESET | BUS_RESET)) )
+ if ( (p->flags & AHC_RESET_DELAY) &&
+ (action & (HOST_RESET | BUS_RESET)) )
X {
X if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
X printk(INFO_LEAD "Reset called too soon after "
X "last bus reset, delaying.\n", p->host_no, CTL_OF_CMD(cmd));


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre5 failed'
fi

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

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

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to
Archive-name: v2.1/patch-2.2.0-pre5/part06

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


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

+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);

+ outb (0x4a, dev.fx_dsp_addr);


+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);

X
X /* either because of stupidity by TB's programmers, or because it
X actually does something, rezero the MOD page.
X */


X for (i = 0x10; i <= 0xff; i++) {
X
- if (!wffx_idle (hw)) {
+ if (!wffx_idle ()) {
X return (-1);
X }
X
- outb (i, hw->fx_mod_addr);
- outb (0x0, hw->fx_mod_data);
+ outb (i, dev.fx_mod_addr);
+ outb (0x0, dev.fx_mod_data);
X }

X /* load page zero */


X
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x00, hw->fx_dsp_page);
- outb (0x00, hw->fx_dsp_addr);


+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);

+ outb (0x00, dev.fx_dsp_page);
+ outb (0x00, dev.fx_dsp_addr);
X
X for (i = 0; i < sizeof (page_zero); i += 2) {
- outb (page_zero[i], hw->fx_dsp_msb);
- outb (page_zero[i+1], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_zero[i], dev.fx_dsp_msb);
+ outb (page_zero[i+1], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }
X
X /* Now load page one */


X
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x01, hw->fx_dsp_page);
- outb (0x00, hw->fx_dsp_addr);


+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);

+ outb (0x01, dev.fx_dsp_page);
+ outb (0x00, dev.fx_dsp_addr);
X
X for (i = 0; i < sizeof (page_one); i += 2) {
- outb (page_one[i], hw->fx_dsp_msb);
- outb (page_one[i+1], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_one[i], dev.fx_dsp_msb);
+ outb (page_one[i+1], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }


X
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x02, hw->fx_dsp_page);
- outb (0x00, hw->fx_dsp_addr);


+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);

+ outb (0x02, dev.fx_dsp_page);
+ outb (0x00, dev.fx_dsp_addr);
X
X for (i = 0; i < sizeof (page_two); i++) {
- outb (page_two[i], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_two[i], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }


X
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x03, hw->fx_dsp_page);
- outb (0x00, hw->fx_dsp_addr);


+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);

+ outb (0x03, dev.fx_dsp_page);
+ outb (0x00, dev.fx_dsp_addr);
X
X for (i = 0; i < sizeof (page_three); i++) {
- outb (page_three[i], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_three[i], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }


X
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x04, hw->fx_dsp_page);
- outb (0x00, hw->fx_dsp_addr);


+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);

+ outb (0x04, dev.fx_dsp_page);
+ outb (0x00, dev.fx_dsp_addr);
X
X for (i = 0; i < sizeof (page_four); i++) {
- outb (page_four[i], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_four[i], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }
X
X /* Load memory area (page six) */


X
- outb (FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x06, hw->fx_dsp_page);
+ outb (FX_LSB_TRANSFER, dev.fx_lcr);
+ outb (0x06, dev.fx_dsp_page);
X
X for (i = 0; i < sizeof (page_six); i += 3) {
- outb (page_six[i], hw->fx_dsp_addr);
- outb (page_six[i+1], hw->fx_dsp_msb);
- outb (page_six[i+2], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_six[i], dev.fx_dsp_addr);
+ outb (page_six[i+1], dev.fx_dsp_msb);
+ outb (page_six[i+2], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }


X
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x07, hw->fx_dsp_page);

- outb (0x00, hw->fx_dsp_addr);


+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);

+ outb (0x07, dev.fx_dsp_page);
+ outb (0x00, dev.fx_dsp_addr);
X
X for (i = 0; i < sizeof (page_seven); i += 2) {
- outb (page_seven[i], hw->fx_dsp_msb);
- outb (page_seven[i+1], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_seven[i], dev.fx_dsp_msb);
+ outb (page_seven[i+1], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }
X
X /* Now setup the MOD area. We do this algorithmically in order to
@@ -3268,192 +3249,192 @@
X */
X
X for (i = 0x00; i <= 0x0f; i++) {
- outb (0x01, hw->fx_mod_addr);
- outb (i, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

- outb (0x02, hw->fx_mod_addr);
- outb (0x00, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (0x01, dev.fx_mod_addr);
+ outb (i, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

+ outb (0x02, dev.fx_mod_addr);
+ outb (0x00, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X
X for (i = 0xb0; i <= 0xbf; i++) {


- outb (i, hw->fx_mod_addr);

- outb (0x20, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (i, dev.fx_mod_addr);
+ outb (0x20, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X
X for (i = 0xf0; i <= 0xff; i++) {


- outb (i, hw->fx_mod_addr);

- outb (0x20, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (i, dev.fx_mod_addr);
+ outb (0x20, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X
X for (i = 0x10; i <= 0x1d; i++) {


- outb (i, hw->fx_mod_addr);

- outb (0xff, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (i, dev.fx_mod_addr);
+ outb (0xff, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X
- outb (0x1e, hw->fx_mod_addr);
- outb (0x40, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (0x1e, dev.fx_mod_addr);
+ outb (0x40, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X
X for (i = 0x1f; i <= 0x2d; i++) {


- outb (i, hw->fx_mod_addr);

- outb (0xff, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (i, dev.fx_mod_addr);
+ outb (0xff, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X
- outb (0x2e, hw->fx_mod_addr);
- outb (0x00, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (0x2e, dev.fx_mod_addr);
+ outb (0x00, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X
X for (i = 0x2f; i <= 0x3e; i++) {


- outb (i, hw->fx_mod_addr);

- outb (0x00, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (i, dev.fx_mod_addr);
+ outb (0x00, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X
- outb (0x3f, hw->fx_mod_addr);
- outb (0x20, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (0x3f, dev.fx_mod_addr);
+ outb (0x20, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X
X for (i = 0x40; i <= 0x4d; i++) {


- outb (i, hw->fx_mod_addr);

- outb (0x00, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (i, dev.fx_mod_addr);
+ outb (0x00, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X
- outb (0x4e, hw->fx_mod_addr);
- outb (0x0e, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

- outb (0x4f, hw->fx_mod_addr);
- outb (0x0e, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (0x4e, dev.fx_mod_addr);
+ outb (0x0e, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

+ outb (0x4f, dev.fx_mod_addr);
+ outb (0x0e, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X
X
X for (i = 0x50; i <= 0x6b; i++) {


- outb (i, hw->fx_mod_addr);

- outb (0x00, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);
- }

-
- outb (0x6c, hw->fx_mod_addr);
- outb (0x40, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);
-

- outb (0x6d, hw->fx_mod_addr);
- outb (0x00, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);
-

- outb (0x6e, hw->fx_mod_addr);
- outb (0x40, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);
-

- outb (0x6f, hw->fx_mod_addr);
- outb (0x40, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (i, dev.fx_mod_addr);
+ outb (0x00, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);
+ }

+
+ outb (0x6c, dev.fx_mod_addr);
+ outb (0x40, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);
+

+ outb (0x6d, dev.fx_mod_addr);
+ outb (0x00, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);
+

+ outb (0x6e, dev.fx_mod_addr);
+ outb (0x40, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);
+

+ outb (0x6f, dev.fx_mod_addr);
+ outb (0x40, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X
X for (i = 0x70; i <= 0x7f; i++) {


- outb (i, hw->fx_mod_addr);

- outb (0xc0, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (i, dev.fx_mod_addr);
+ outb (0xc0, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X
X for (i = 0x80; i <= 0xaf; i++) {


- outb (i, hw->fx_mod_addr);

- outb (0x00, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (i, dev.fx_mod_addr);
+ outb (0x00, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X
X for (i = 0xc0; i <= 0xdd; i++) {


- outb (i, hw->fx_mod_addr);

- outb (0x00, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (i, dev.fx_mod_addr);
+ outb (0x00, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X
- outb (0xde, hw->fx_mod_addr);
- outb (0x10, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

- outb (0xdf, hw->fx_mod_addr);
- outb (0x10, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (0xde, dev.fx_mod_addr);
+ outb (0x10, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

+ outb (0xdf, dev.fx_mod_addr);
+ outb (0x10, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X
X for (i = 0xe0; i <= 0xef; i++) {


- outb (i, hw->fx_mod_addr);

- outb (0x00, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (i, dev.fx_mod_addr);
+ outb (0x00, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X
X for (i = 0x00; i <= 0x0f; i++) {
- outb (0x01, hw->fx_mod_addr);
- outb (i, hw->fx_mod_data);
- outb (0x02, hw->fx_mod_addr);
- outb (0x01, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (0x01, dev.fx_mod_addr);
+ outb (i, dev.fx_mod_data);
+ outb (0x02, dev.fx_mod_addr);
+ outb (0x01, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X

- outb (0x02, hw->fx_op); /* mute on */

+ outb (0x02, dev.fx_op); /* mute on */
X

X /* Now set the coefficients and so forth for the programs above */
X
X for (i = 0; i < sizeof (coefficients); i += 4) {
- outb (coefficients[i], hw->fx_dsp_page);
- outb (coefficients[i+1], hw->fx_dsp_addr);
- outb (coefficients[i+2], hw->fx_dsp_msb);
- outb (coefficients[i+3], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (coefficients[i], dev.fx_dsp_page);
+ outb (coefficients[i+1], dev.fx_dsp_addr);
+ outb (coefficients[i+2], dev.fx_dsp_msb);
+ outb (coefficients[i+3], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }
X
X /* Some settings (?) that are too small to bundle into loops */


X
- if (!wffx_idle(hw)) return (-1);

- outb (0x1e, hw->fx_mod_addr);
- outb (0x14, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

- outb (0xde, hw->fx_mod_addr);
- outb (0x20, hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

- outb (0xdf, hw->fx_mod_addr);
- outb (0x20, hw->fx_mod_data);


+ if (!wffx_idle()) return (-1);

+ outb (0x1e, dev.fx_mod_addr);
+ outb (0x14, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

+ outb (0xde, dev.fx_mod_addr);
+ outb (0x20, dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

+ outb (0xdf, dev.fx_mod_addr);
+ outb (0x20, dev.fx_mod_data);
X
X /* some more coefficients */


X
- if (!wffx_idle(hw)) return (-1);

- outb (0x06, hw->fx_dsp_page);
- outb (0x78, hw->fx_dsp_addr);


- outb (0x00, hw->fx_dsp_msb);

- outb (0x40, hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);

- outb (0x03, hw->fx_dsp_addr);
- outb (0x0f, hw->fx_dsp_msb);
- outb (0xff, hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);

- outb (0x0b, hw->fx_dsp_addr);
- outb (0x0f, hw->fx_dsp_msb);
- outb (0xff, hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);

- outb (0x02, hw->fx_dsp_addr);


- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);

- outb (0x0a, hw->fx_dsp_addr);


- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);
- outb (0x46, hw->fx_dsp_addr);
- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
- if (!wffx_idle(hw)) return (-1);
- outb (0x07, hw->fx_dsp_page);
- outb (0x49, hw->fx_dsp_addr);
- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);

+ if (!wffx_idle()) return (-1);

+ outb (0x06, dev.fx_dsp_page);
+ outb (0x78, dev.fx_dsp_addr);
+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x40, dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);

+ outb (0x03, dev.fx_dsp_addr);
+ outb (0x0f, dev.fx_dsp_msb);
+ outb (0xff, dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);

+ outb (0x0b, dev.fx_dsp_addr);
+ outb (0x0f, dev.fx_dsp_msb);
+ outb (0xff, dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);

+ outb (0x02, dev.fx_dsp_addr);


+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);
+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);

+ outb (0x0a, dev.fx_dsp_addr);


+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);
+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);
+ outb (0x46, dev.fx_dsp_addr);
+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);
+ if (!wffx_idle()) return (-1);
+ outb (0x07, dev.fx_dsp_page);
+ outb (0x49, dev.fx_dsp_addr);
+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);

X
X /* Now, for some strange reason, lets reload every page
X and all the coefficients over again. I have *NO* idea
@@ -3461,117 +3442,116 @@
X is this phase is omitted.
X */
X

- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x00, hw->fx_dsp_page);
- outb (0x10, hw->fx_dsp_addr);


+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);

+ outb (0x00, dev.fx_dsp_page);
+ outb (0x10, dev.fx_dsp_addr);
X
X for (i = 0; i < sizeof (page_zero_v2); i += 2) {
- outb (page_zero_v2[i], hw->fx_dsp_msb);
- outb (page_zero_v2[i+1], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_zero_v2[i], dev.fx_dsp_msb);
+ outb (page_zero_v2[i+1], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }


X
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x01, hw->fx_dsp_page);
- outb (0x10, hw->fx_dsp_addr);


+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);

+ outb (0x01, dev.fx_dsp_page);
+ outb (0x10, dev.fx_dsp_addr);
X
X for (i = 0; i < sizeof (page_one_v2); i += 2) {
- outb (page_one_v2[i], hw->fx_dsp_msb);
- outb (page_one_v2[i+1], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_one_v2[i], dev.fx_dsp_msb);
+ outb (page_one_v2[i+1], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }
X
- if (!wffx_idle(hw)) return (-1);

- if (!wffx_idle(hw)) return (-1);


+ if (!wffx_idle()) return (-1);

+ if (!wffx_idle()) return (-1);


X
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x02, hw->fx_dsp_page);
- outb (0x10, hw->fx_dsp_addr);


+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);

+ outb (0x02, dev.fx_dsp_page);
+ outb (0x10, dev.fx_dsp_addr);
X
X for (i = 0; i < sizeof (page_two_v2); i++) {
- outb (page_two_v2[i], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_two_v2[i], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x03, hw->fx_dsp_page);
- outb (0x10, hw->fx_dsp_addr);


+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);

+ outb (0x03, dev.fx_dsp_page);
+ outb (0x10, dev.fx_dsp_addr);
X
X for (i = 0; i < sizeof (page_three_v2); i++) {
- outb (page_three_v2[i], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_three_v2[i], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }


X
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x04, hw->fx_dsp_page);
- outb (0x10, hw->fx_dsp_addr);


+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);

+ outb (0x04, dev.fx_dsp_page);
+ outb (0x10, dev.fx_dsp_addr);
X
X for (i = 0; i < sizeof (page_four_v2); i++) {
- outb (page_four_v2[i], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_four_v2[i], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }


X
- outb (FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x06, hw->fx_dsp_page);
+ outb (FX_LSB_TRANSFER, dev.fx_lcr);
+ outb (0x06, dev.fx_dsp_page);
X
X /* Page six v.2 is algorithmic */
X
X for (i = 0x10; i <= 0x3e; i += 2) {
- outb (i, hw->fx_dsp_addr);


- outb (0x00, hw->fx_dsp_msb);
- outb (0x00, hw->fx_dsp_lsb);
- if (!wffx_idle(hw)) return (-1);

+ outb (i, dev.fx_dsp_addr);


+ outb (0x00, dev.fx_dsp_msb);
+ outb (0x00, dev.fx_dsp_lsb);
+ if (!wffx_idle()) return (-1);

X }


X
- outb (FX_AUTO_INCR|FX_LSB_TRANSFER, hw->fx_lcr);

- outb (0x07, hw->fx_dsp_page);

- outb (0x10, hw->fx_dsp_addr);


+ outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);

+ outb (0x07, dev.fx_dsp_page);
+ outb (0x10, dev.fx_dsp_addr);
X
X for (i = 0; i < sizeof (page_seven_v2); i += 2) {
- outb (page_seven_v2[i], hw->fx_dsp_msb);
- outb (page_seven_v2[i+1], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (page_seven_v2[i], dev.fx_dsp_msb);
+ outb (page_seven_v2[i+1], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }
X
X for (i = 0x00; i < sizeof(mod_v2); i += 2) {
- outb (mod_v2[i], hw->fx_mod_addr);
- outb (mod_v2[i+1], hw->fx_mod_data);


- if (!wffx_idle(hw)) return (-1);

+ outb (mod_v2[i], dev.fx_mod_addr);
+ outb (mod_v2[i+1], dev.fx_mod_data);


+ if (!wffx_idle()) return (-1);

X }
X
X for (i = 0; i < sizeof (coefficients2); i += 4) {
- outb (coefficients2[i], hw->fx_dsp_page);
- outb (coefficients2[i+1], hw->fx_dsp_addr);
- outb (coefficients2[i+2], hw->fx_dsp_msb);
- outb (coefficients2[i+3], hw->fx_dsp_lsb);


- if (!wffx_idle(hw)) return (-1);

+ outb (coefficients2[i], dev.fx_dsp_page);
+ outb (coefficients2[i+1], dev.fx_dsp_addr);
+ outb (coefficients2[i+2], dev.fx_dsp_msb);
+ outb (coefficients2[i+3], dev.fx_dsp_lsb);


+ if (!wffx_idle()) return (-1);

X }
X
- outb (0x00, hw->fx_op);


- if (!wffx_idle(hw)) return (-1);
-

X for (i = 0; i < sizeof (coefficients3); i += 2) {
X int x;
X

- outb (0x07, hw->fx_dsp_page);

+ outb (0x07, dev.fx_dsp_page);
X x = (i % 4) ? 0x4e : 0x4c;
- outb (x, hw->fx_dsp_addr);
- outb (coefficients3[i], hw->fx_dsp_msb);
- outb (coefficients3[i+1], hw->fx_dsp_lsb);
+ outb (x, dev.fx_dsp_addr);
+ outb (coefficients3[i], dev.fx_dsp_msb);
+ outb (coefficients3[i+1], dev.fx_dsp_lsb);
X }
X
- outb (0x00, hw->fx_op); /* mute off */
+ outb (0x00, dev.fx_op); /* mute off */


+ if (!wffx_idle()) return (-1);

X
X return (0);
X }
X

X EXPORT_NO_SYMBOLS;
-struct address_info cfg;
X
X int io = -1;
X int irq = -1;
X
-MODULE_PARM(io,"i");
-MODULE_PARM(irq,"i");
+MODULE_AUTHOR ("Paul Barton-Davis <p...@op.net>");
+MODULE_DESCRIPTION ("Turtle Beach WaveFront Linux Driver");
+MODULE_PARM (io,"i");
+MODULE_PARM (irq,"i");
X
X int init_module (void)
X
@@ -3580,19 +3560,27 @@
X "Copyright (C) by Hannu Solvainen, "
X "Paul Barton-Davis 1993-1998.\n");
X
+ /* XXX t'would be lovely to ask the CS4232 for these values, eh ? */
+
X if (io == -1 || irq == -1) {
- printk (KERN_INFO "WaveFront: irq and io "
- "options must be set.\n");
+ printk (KERN_INFO LOGNAME "irq and io options must be set.\n");


X return -EINVAL;
X }
X

- cfg.io_base = io;
- cfg.irq = irq;
+ if (wavefront_interrupt_bits (irq) < 0) {
+ printk (KERN_INFO LOGNAME
+ "IRQ must be 9, 5, 12 or 15 (not %d)\n", irq);
+ return -ENODEV;
+ }
X
- if (probe_wavefront (&cfg) == 0) {
+ if (detect_wavefront (irq, io) < 0) {
X return -ENODEV;
X }
- attach_wavefront (&cfg);
+
+ if (install_wavefront () < 0) {
+ return -EIO;
+ }
+
X SOUND_LOCK;
X return 0;
X }
@@ -3600,10 +3588,11 @@
X void cleanup_module (void)
X
X {
- unload_wavefront (&cfg);
+ uninstall_wavefront ();
+
X SOUND_LOCK_END;
X }
X
-#endif CONFIG_SOUND_WAVEFRONT_MODULE_AND_MODULE
+#endif CONFIG_SOUND_WAVEFRONT_MODULE && MODULE
X
X
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/wf_midi.c linux/drivers/sound/wf_midi.c
--- v2.2.0-pre4/linux/drivers/sound/wf_midi.c Thu Nov 12 16:21:22 1998
+++ linux/drivers/sound/wf_midi.c Mon Jan 4 11:37:30 1999
@@ -40,7 +40,7 @@
X
X /*
X * Copyright (C) by Paul Barton-Davis 1998
- * Substantial portions of this file are derived from work that is:
+ * Some portions of this file are derived from work that is:
X *
X * Copyright (C) by Hannu Savolainen 1993-1996
X *
@@ -50,17 +50,22 @@
X */
X
X #include <linux/config.h>
+#include <linux/init.h>
X #include "sound_config.h"
X #include "soundmodule.h"
X
X #include <linux/wavefront.h>
X
-#if (defined(CONFIG_WAVEFRONT) && defined(CONFIG_MIDI)) || defined(MODULE)
+#if defined(CONFIG_SOUND_WAVEFRONT_MODULE) && defined(MODULE)
X
X struct wf_mpu_config {
- int base; /* I/O base */
+ int base;
+#define DATAPORT(d) (d)->base
+#define COMDPORT(d) (d)->base+1
+#define STATPORT(d) (d)->base+1
+
X int irq;
- int opened; /* Open mode */
+ int opened;
X int devno;
X int synthno;
X int mode;
@@ -68,69 +73,54 @@
X #define MODE_SYNTH 2
X
X void (*inputintr) (int dev, unsigned char data);
-
- /* Virtual MIDI support */
-
- char configured_for_virtual; /* setup for virtual completed */
X char isvirtual; /* do virtual I/O stuff */
- char isexternal; /* i am an external interface */
- int internal; /* external interface midi_devno */
- int external; /* external interface midi_devno */
X };
X
-#define DATAPORT(base) (base)
-#define COMDPORT(base) (base+1)
-#define STATPORT(base) (base+1)
+static struct wf_mpu_config devs[2];
+static struct wf_mpu_config *phys_dev = &devs[0];
+static struct wf_mpu_config *virt_dev = &devs[1];
X
-static void start_uart_mode (struct wf_mpu_config *devc);
+static void start_uart_mode (void);
X
-static int
-wf_mpu_status (struct wf_mpu_config *devc)
-{
- return inb (STATPORT (devc->base));
-}
+#define OUTPUT_READY 0x40
+#define INPUT_AVAIL 0x80
+#define MPU_ACK 0xFE
+#define UART_MODE_ON 0x3F
+
+static inline int
+wf_mpu_status (void)
X
-static void
-wf_mpu_cmd (struct wf_mpu_config *devc, unsigned char cmd)
X {
- outb ((cmd), COMDPORT(devc->base));
+ return inb (STATPORT (phys_dev));
X }
X
-#define input_avail(devc) (!(wf_mpu_status(devc)&INPUT_AVAIL))
-#define output_ready(devc) (!(wf_mpu_status(devc)&OUTPUT_READY))
+static inline int
+input_avail (void)
X
-static int
-read_data (struct wf_mpu_config *devc)
X {
- return inb (DATAPORT (devc->base));
+ return !(wf_mpu_status() & INPUT_AVAIL);
X }
X
-static void
-write_data (struct wf_mpu_config *devc, unsigned char byte)
+static inline int
+output_ready (void)
+
X {
- outb (byte, DATAPORT (devc->base));
+ return !(wf_mpu_status() & OUTPUT_READY);
X }
X
-#define OUTPUT_READY 0x40
-#define INPUT_AVAIL 0x80
-#define MPU_ACK 0xFE
-#define MPU_RESET 0xFF
-#define UART_MODE_ON 0x3F
+static inline int
+read_data (void)
X
-static struct wf_mpu_config dev_conf[MAX_MIDI_DEV] =
X {
- {0}
-};
-
-static volatile int irq2dev[17] =
-{-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1};
+ return inb (DATAPORT (phys_dev));
+}
X
-static struct synth_info wf_mpu_synth_info_proto =
-{"WaveFront MPU-401 interface", 0,
- SYNTH_TYPE_MIDI, MIDI_TYPE_MPU401, 0, 128, 0, 128, SYNTH_CAP_INPUT};
+static inline void
+write_data (unsigned char byte)
X
-static struct synth_info wf_mpu_synth_info[MAX_MIDI_DEV];
+{
+ outb (byte, DATAPORT (phys_dev));
+}
X
X /*
X * States for the input scanner (should be in dev_table.h)
@@ -162,11 +152,10 @@


X };
X
X static int

-wf_mpu_input_scanner (struct wf_mpu_config *devc, unsigned char midic)
-{
- struct midi_input_info *mi;
+wf_mpu_input_scanner (int devno, int synthdev, unsigned char midic)
X
- mi = &midi_devs[devc->devno]->in_info;
+{
+ struct midi_input_info *mi = &midi_devs[devno]->in_info;
X
X switch (mi->m_state) {
X case MST_INIT:
@@ -236,8 +225,7 @@
X
X if (mi->m_left <= 0) {
X mi->m_state = MST_INIT;
- do_midi_msg (devc->synthno, mi->m_buf,
- mi->m_ptr);
+ do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
X mi->m_ptr = 0;
X }
X } else if (msg == 0xf) { /* MPU MARK */
@@ -266,8 +254,7 @@
X
X if (mi->m_left <= 0) {
X mi->m_state = MST_INIT;
- do_midi_msg (devc->synthno, mi->m_buf,
- mi->m_ptr);
+ do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
X mi->m_ptr = 0;
X }
X }
@@ -362,7 +349,7 @@
X mi->m_buf[mi->m_ptr++] = midic;
X if ((--mi->m_left) <= 0) {
X mi->m_state = MST_INIT;
- do_midi_msg (devc->synthno, mi->m_buf, mi->m_ptr);
+ do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
X mi->m_ptr = 0;
X }
X break;
@@ -375,78 +362,65 @@


X return 1;
X }
X

-void wf_mpuintr (int irq, void *dev_id, struct pt_regs *dummy)
+void
+wf_mpuintr (int irq, void *dev_id, struct pt_regs *dummy)
+
X {
- struct wf_mpu_config *devc;
- int dev;
- static struct wf_mpu_config *isrc = 0;
+ struct wf_mpu_config *physical_dev = dev_id;
+ static struct wf_mpu_config *input_dev = 0;
+ struct midi_input_info *mi = &midi_devs[physical_dev->devno]->in_info;
X int n;
- struct midi_input_info *mi;
X
- if (irq < 0 || irq > 15)
- {
- printk (KERN_ERR "WF-MPU: bogus interrupt #%d", irq);
+ if (!input_avail()) { /* not for us */
X return;
X }
- dev = irq2dev[irq];
- mi = &midi_devs[dev]->in_info;
- if (mi->m_busy)
- return;
+
+ if (mi->m_busy) return;
X mi->m_busy = 1;
-
X sti ();
X
- n = 50;
-
- /* guarantee that we're working with the "real" (internal)
- interface before doing anything physical.
- */
+ if (!input_dev) {
+ input_dev = physical_dev;
+ }
X
- devc = &dev_conf[dev];
- devc = &dev_conf[devc->internal];
+ n = 50; /* XXX why ? */
X
- if (isrc == 0) {
-
- /* This is just an initial setting. If Virtual MIDI mode is
- enabled on the ICS2115, we'll get a switch char before
- anything else, and if it isn't, then the guess will be
- correct for our purposes.
- */
-
- isrc = &dev_conf[devc->internal];
- }
-
- while (input_avail (devc) && n-- > 0) {
- unsigned char c = read_data (devc);
+ do {
+ unsigned char c = read_data ();
X
- if (devc->isvirtual) {
+ if (phys_dev->isvirtual) {
+
X if (c == WF_EXTERNAL_SWITCH) {
- isrc = &dev_conf[devc->external];
+ input_dev = virt_dev;
X continue;
X } else if (c == WF_INTERNAL_SWITCH) {
- isrc = &dev_conf[devc->internal];
+ input_dev = phys_dev;
X continue;
X } /* else just leave it as it is */
+
X } else {
- isrc = &dev_conf[devc->internal];
+ input_dev = phys_dev;
X }
X
- if (isrc->mode == MODE_SYNTH) {
+ if (input_dev->mode == MODE_SYNTH) {
X
- wf_mpu_input_scanner (isrc, c);
+ wf_mpu_input_scanner (input_dev->devno,
+ input_dev->synthno, c);
X
- } else if (isrc->opened & OPEN_READ) {
+ } else if (input_dev->opened & OPEN_READ) {
X
- if (isrc->inputintr) {
- isrc->inputintr (isrc->devno, c);
+ if (input_dev->inputintr) {
+ input_dev->inputintr (input_dev->devno, c);
X }
X }
- }
+
+ } while (input_avail() && n-- > 0);
X
X mi->m_busy = 0;
X }
X
-static int wf_mpu_open (int dev, int mode,
+static int
+wf_mpu_open (int dev, int mode,
X void (*input) (int dev, unsigned char data),
X void (*output) (int dev)
X )
@@ -456,7 +430,14 @@
X if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
X return -(ENXIO);
X
- devc = &dev_conf[dev];
+ if (phys_dev->devno == dev) {
+ devc = phys_dev;
+ } else if (phys_dev->isvirtual && virt_dev->devno == dev) {
+ devc = virt_dev;
+ } else {
+ printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);


+ return -(EINVAL);
+ }
X

X if (devc->opened) {
X return -(EBUSY);
@@ -475,7 +456,18 @@
X {
X struct wf_mpu_config *devc;
X
- devc = &dev_conf[dev];
+ if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
+ return;
+
+ if (phys_dev->devno == dev) {
+ devc = phys_dev;
+ } else if (phys_dev->isvirtual && virt_dev->devno == dev) {
+ devc = virt_dev;
+ } else {
+ printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
+ return;
+ }
+
X devc->mode = 0;
X devc->inputintr = NULL;
X devc->opened = 0;
@@ -487,40 +479,35 @@
X int timeout;
X unsigned long flags;
X static int lastoutdev = -1;
-
- struct wf_mpu_config *devc;
X unsigned char switchch;
X
- /* The actual output has to occur using the "internal" config info
- */
-
- devc = &dev_conf[dev_conf[dev].internal];
-
- if (devc->isvirtual && lastoutdev != dev) {
+ if (phys_dev->isvirtual && lastoutdev != dev) {
X
- if (dev == devc->internal) {
+ if (dev == phys_dev->devno) {
X switchch = WF_INTERNAL_SWITCH;
- } else if (dev == devc->external) {
+ } else if (dev == virt_dev->devno) {
X switchch = WF_EXTERNAL_SWITCH;
X } else {
X printk (KERN_ERR "WF-MPU: bad device number %d", dev);
X return (0);
X }


+
+ /* XXX fix me */

X
- for (timeout = 30000; timeout > 0 && !output_ready (devc);
+ for (timeout = 30000; timeout > 0 && !output_ready ();
X timeout--);


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

X
- if (!output_ready (devc)) {
+ if (!output_ready ()) {
X printk (KERN_WARNING "WF-MPU: Send switch "
X "byte timeout\n");
X restore_flags (flags);


X return 0;
X }
X

- write_data (devc, switchch);
+ write_data (switchch);


X restore_flags (flags);
X }
X

@@ -531,17 +518,19 @@
X * (After reset). Normally it takes just about 10 loops.
X */
X
- for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);


+ /* XXX fix me */
+

+ for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);


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

- if (!output_ready (devc)) {
+ if (!output_ready ()) {
X printk (KERN_WARNING "WF-MPU: Send data timeout\n");
X restore_flags (flags);


X return 0;
X }
X

- write_data (devc, midi_byte);
+ write_data (midi_byte);
X restore_flags (flags);
X
X return 1;
@@ -567,35 +556,63 @@


X return -(EINVAL);
X }
X

-static void
-wf_mpu_kick (int dev)
-{
-}
-
X static int
X wf_mpu_buffer_status (int dev)
X {
- return 0; /*
- * No data in buffers


- */
+ return 0;

X }
X
+static struct synth_operations wf_mpu_synth_operations[2];
+static struct midi_operations wf_mpu_midi_operations[2];
+
+static struct midi_operations wf_mpu_midi_proto =
+{
+ {"WF-MPU MIDI", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
+ NULL, /*converter*/
+ {0}, /* in_info */
+ wf_mpu_open,
+ wf_mpu_close,
+ wf_mpu_ioctl,
+ wf_mpu_out,
+ wf_mpu_start_read,
+ wf_mpu_end_read,
+ NULL,
+ NULL,
+ wf_mpu_buffer_status,
+ NULL
+};
+
+static struct synth_info wf_mpu_synth_info_proto =
+{"WaveFront MPU-401 interface", 0,
+ SYNTH_TYPE_MIDI, MIDI_TYPE_MPU401, 0, 128, 0, 128, SYNTH_CAP_INPUT};
+
+static struct synth_info wf_mpu_synth_info[2];
+
X static int
X wf_mpu_synth_ioctl (int dev,
X unsigned int cmd, caddr_t arg)
X {
X int midi_dev;
+ int index;
X
X midi_dev = synth_devs[dev]->midi_dev;
X
X if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL)
X return -(ENXIO);
X
+ if (midi_dev == phys_dev->devno) {
+ index = 0;
+ } else if (phys_dev->isvirtual && midi_dev == virt_dev->devno) {
+ index = 1;
+ } else {


+ return -(EINVAL);
+ }
+

X switch (cmd) {
X
X case SNDCTL_SYNTH_INFO:
X copy_to_user (&((char *) arg)[0],
- &wf_mpu_synth_info[midi_dev],
+ &wf_mpu_synth_info[index],
X sizeof (struct synth_info));
X
X return 0;
@@ -622,7 +639,15 @@
X return -(ENXIO);
X }
X
- devc = &dev_conf[midi_dev];
+ if (phys_dev->devno == midi_dev) {
+ devc = phys_dev;
+ } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
+ devc = virt_dev;
+ } else {
+ printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);


+ return -(EINVAL);
+ }
+

X if (devc->opened) {
X return -(EBUSY);
X }
@@ -642,7 +667,15 @@
X
X midi_dev = synth_devs[dev]->midi_dev;
X
- devc = &dev_conf[midi_dev];
+ if (phys_dev->devno == midi_dev) {
+ devc = phys_dev;
+ } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
+ devc = virt_dev;
+ } else {
+ printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
+ return;
+ }
+
X devc->inputintr = NULL;
X devc->opened = 0;
X devc->mode = 0;
@@ -678,233 +711,145 @@
X midi_synth_send_sysex
X };
X
-static struct synth_operations wf_mpu_synth_operations[2];
-static struct midi_operations wf_mpu_midi_operations[2];
-static int wfmpu_cnt = 0;
-
-static struct midi_operations wf_mpu_midi_proto =
-{
- {"WF-MPU MIDI", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
- NULL, /*converter*/
- {0}, /* in_info */
- wf_mpu_open,
- wf_mpu_close,
- wf_mpu_ioctl,
- wf_mpu_out,
- wf_mpu_start_read,
- wf_mpu_end_read,
- wf_mpu_kick,
- NULL,
- wf_mpu_buffer_status,
- NULL
-};
-
-
X static int
-config_wf_mpu (int dev, struct address_info *hw_config)
+config_wf_mpu (struct wf_mpu_config *dev)
X
X {
- struct wf_mpu_config *devc;
- int internal;
-
- if (wfmpu_cnt >= 2) {
- printk (KERN_ERR "WF-MPU: more MPU devices than cards ?!!\n");
- return (-1);
- }
-
- /* There is no synth available on the external interface,
- so do the synth stuff to the internal interface only.
- */
-
- internal = dev_conf[dev].internal;
- devc = &dev_conf[internal];
-
- if (!dev_conf[dev].isexternal) {
- memcpy ((char *) &wf_mpu_synth_operations[wfmpu_cnt],
+ int is_external;
+ char *name;
+ int index;
+
+ if (dev == phys_dev) {
+ name = "WaveFront internal MIDI";
+ is_external = 0;
+ index = 0;
+ memcpy ((char *) &wf_mpu_synth_operations[index],
X (char *) &wf_mpu_synth_proto,
X sizeof (struct synth_operations));
- }
-
- memcpy ((char *) &wf_mpu_midi_operations[wfmpu_cnt],
- (char *) &wf_mpu_midi_proto,
- sizeof (struct midi_operations));
-
- if (dev_conf[dev].isexternal) {
- wf_mpu_midi_operations[wfmpu_cnt].converter = NULL;
X } else {
- wf_mpu_midi_operations[wfmpu_cnt].converter =
- &wf_mpu_synth_operations[wfmpu_cnt];
+ name = "WaveFront external MIDI";
+ is_external = 1;
+ index = 1;
+ /* no synth operations for an external MIDI interface */
X }
X
- memcpy ((char *) &wf_mpu_synth_info[dev],
+ memcpy ((char *) &wf_mpu_synth_info[dev->devno],
X (char *) &wf_mpu_synth_info_proto,
X sizeof (struct synth_info));
X
- strcpy (wf_mpu_synth_info[dev].name, hw_config->name);
- strcpy (wf_mpu_midi_operations[wfmpu_cnt].info.name, hw_config->name);
+ strcpy (wf_mpu_synth_info[index].name, name);
X
- conf_printf (hw_config->name, hw_config);
+ wf_mpu_synth_operations[index].midi_dev = dev->devno;
+ wf_mpu_synth_operations[index].info = &wf_mpu_synth_info[index];
X
- if (!dev_conf[dev].isexternal) {
- wf_mpu_synth_operations[wfmpu_cnt].midi_dev = dev;
+ memcpy ((char *) &wf_mpu_midi_operations[index],
+ (char *) &wf_mpu_midi_proto,
+ sizeof (struct midi_operations));
+
+ if (is_external) {
+ wf_mpu_midi_operations[index].converter = NULL;
+ } else {
+ wf_mpu_midi_operations[index].converter =
+ &wf_mpu_synth_operations[index];
X }
- wf_mpu_synth_operations[wfmpu_cnt].info = &wf_mpu_synth_info[dev];
-
- midi_devs[dev] = &wf_mpu_midi_operations[wfmpu_cnt];
X
- dev_conf[dev].opened = 0;
- dev_conf[dev].mode = 0;
- dev_conf[dev].configured_for_virtual = 0;
- dev_conf[dev].devno = dev;
+ strcpy (wf_mpu_midi_operations[index].info.name, name);
X
- midi_devs[dev]->in_info.m_busy = 0;
- midi_devs[dev]->in_info.m_state = MST_INIT;
- midi_devs[dev]->in_info.m_ptr = 0;
- midi_devs[dev]->in_info.m_left = 0;
- midi_devs[dev]->in_info.m_prev_status = 0;
+ midi_devs[dev->devno] = &wf_mpu_midi_operations[index];
+ midi_devs[dev->devno]->in_info.m_busy = 0;
+ midi_devs[dev->devno]->in_info.m_state = MST_INIT;
+ midi_devs[dev->devno]->in_info.m_ptr = 0;
+ midi_devs[dev->devno]->in_info.m_left = 0;
+ midi_devs[dev->devno]->in_info.m_prev_status = 0;
X
- wfmpu_cnt++;
+ devs[index].opened = 0;
+ devs[index].mode = 0;


X
X return (0);
X }
X

-int
-virtual_midi_enable (int dev, struct address_info *hw_config)
+int virtual_midi_enable (void)
X
X {
- int idev;
- int edev;
- struct wf_mpu_config *devc;
-
- devc = &dev_conf[dev];
-
- if (devc->configured_for_virtual) {
-
- idev = devc->internal;
- edev = devc->external;
-
- } else {
-
- if (hw_config == NULL) {
- printk (KERN_ERR
- "WF-MPU: virtual midi first "
- "enabled without hw_config!\n");
- return -EINVAL;
- }
+ if ((virt_dev->devno < 0) &&
+ (virt_dev->devno = sound_alloc_mididev()) == -1) {
+ printk (KERN_ERR
+ "WF-MPU: too many midi devices detected\n");


+ return -1;
+ }
X

- idev = devc->internal;
+ config_wf_mpu (virt_dev);
X
- if ((edev = sound_alloc_mididev()) == -1) {
- printk (KERN_ERR
- "WF-MPU: too many midi devices detected\n");
- return -1;
- }
+ phys_dev->isvirtual = 1;
+ return virt_dev->devno;
+}
X
- hw_config->slots[WF_EXTERNAL_MIDI_SLOT] = edev;
- }
+int
+virtual_midi_disable (void)
X
- dev_conf[edev].isvirtual = 1;
- dev_conf[idev].isvirtual = 1;
-
- if (dev_conf[idev].configured_for_virtual) {
- return 0;
- }
+{
+ unsigned long flags;
X
- /* Configure external interface struct */
+ save_flags (flags);
+ cli();
X
- devc = &dev_conf[edev];
- devc->internal = idev;
- devc->external = edev;
- devc->isexternal = 1;
+ wf_mpu_close (virt_dev->devno);
+ /* no synth on virt_dev, so no need to call wf_mpu_synth_close() */
+ phys_dev->isvirtual = 0;
X
- /* Configure external interface struct
- (devc->isexternal and devc->internal set in attach_wf_mpu())
- */
+ restore_flags (flags);
X
- devc = &dev_conf[idev];
- devc->external = edev;


+ return 0;
+}
X

- /* Configure the tables for the external */
+__initfunc (static int detect_wf_mpu (int irq, int io_base))
X
- if (config_wf_mpu (edev, hw_config)) {
- printk (KERN_WARNING "WF-MPU: configuration for MIDI "
- "device %d failed\n", edev);
- return (-1);
+{
+ if (check_region (io_base, 2)) {
+ printk (KERN_WARNING "WF-MPU: I/O port %x already in use.\n",
+ io_base);


+ return -1;
X }
X

- /* Don't bother to do this again if we are toggled back and
- forth between virtual MIDI mode and "normal" operation.
- */
-
- dev_conf[edev].configured_for_virtual = 1;
- dev_conf[idev].configured_for_virtual = 1;
+ phys_dev->base = io_base;
+ phys_dev->irq = irq;
+ phys_dev->devno = -1;
+ virt_dev->devno = -1;


X
X return 0;
X }
X

-void
-virtual_midi_disable (int dev)
+__initfunc (int install_wf_mpu (void))
X
X {
- struct wf_mpu_config *devc;
- unsigned long flags;
+ if ((phys_dev->devno = sound_alloc_mididev()) < 0){
X
- save_flags (flags);
- cli();
-
- /* Assumes for logical purposes that the caller has taken
- care of fiddling with WaveFront hardware commands to
- turn off Virtual MIDI mode.
- */
-
- devc = &dev_conf[dev];
+ printk (KERN_ERR "WF-MPU: Too many MIDI devices detected.\n");
+ return -1;
X
- devc = &dev_conf[devc->internal];
- devc->isvirtual = 0;
+ }
X
- devc = &dev_conf[devc->external];
- devc->isvirtual = 0;
+ request_region (phys_dev->base, 2, "wavefront midi");
+ phys_dev->isvirtual = 0;
X
- restore_flags (flags);
-}
+ if (config_wf_mpu (phys_dev)) {
X
-void
-attach_wf_mpu (struct address_info *hw_config)
-{
- int m;
- struct wf_mpu_config *devc;
-
- if (request_irq (hw_config->irq, wf_mpuintr,
- 0, "WaveFront MIDI", NULL) < 0) {
- printk (KERN_ERR "WF-MPU: Failed to allocate IRQ%d\n",
- hw_config->irq);
- return;
- }
+ printk (KERN_WARNING
+ "WF-MPU: configuration for MIDI device %d failed\n",
+ phys_dev->devno);
+ sound_unload_mididev (phys_dev->devno);
X
- if ((m = sound_alloc_mididev()) == -1){
- printk (KERN_ERR "WF-MPU: Too many MIDI devices detected.\n");
- free_irq (hw_config->irq, NULL);
- release_region (hw_config->io_base, 2);
- return;
X }
X
- request_region (hw_config->io_base, 2, "WaveFront MPU");
+ /* OK, now we're configured to handle an interrupt ... */
X
- hw_config->slots[WF_INTERNAL_MIDI_SLOT] = m;
- devc = &dev_conf[m];
- devc->base = hw_config->io_base;
- devc->irq = hw_config->irq;
- devc->isexternal = 0;
- devc->internal = m;
- devc->external = -1;
- devc->isvirtual = 0;
+ if (request_irq (phys_dev->irq, wf_mpuintr, SA_INTERRUPT|SA_SHIRQ,
+ "wavefront midi", phys_dev) < 0) {
X
- irq2dev[devc->irq] = m;
+ printk (KERN_ERR "WF-MPU: Failed to allocate IRQ%d\n",
+ phys_dev->irq);
+ return -1;
X
- if (config_wf_mpu (m, hw_config)) {
- printk (KERN_WARNING
- "WF-MPU: configuration for MIDI device %d failed\n", m);
- sound_unload_mididev (m);
X }
X
X /* This being a WaveFront (ICS-2115) emulated MPU-401, we have
@@ -912,64 +857,43 @@
X won't do anything at all.
X */
X
- start_uart_mode (devc);
+ start_uart_mode ();
X
+ return phys_dev->devno;
X }
-
-int
-probe_wf_mpu (struct address_info *hw_config)
-
-{


- if (hw_config->irq < 0 || hw_config->irq > 16) {

- printk (KERN_WARNING "WF-MPU: bogus IRQ value requested (%d)\n",


- hw_config->irq);
- return 0;
- }
-

- if (check_region (hw_config->io_base, 2)) {
- printk (KERN_WARNING "WF-MPU: I/O port %x already in use\n\n",
- hw_config->io_base);


- return 0;
- }
-

- if (inb (hw_config->io_base + 1) == 0xff) { /* Just bus float? */
- printk ("WF-MPU: Port %x looks dead.\n", hw_config->io_base);


- return 0;
- }
-

- return 1;
-}
-
+
X void
-unload_wf_mpu (struct address_info *hw_config)
+uninstall_wf_mpu (void)
+
X {
+ release_region (phys_dev->base, 2);
+ free_irq (phys_dev->irq, phys_dev);
+ sound_unload_mididev (phys_dev->devno);
X
- release_region (hw_config->io_base, 2);
- sound_unload_mididev (hw_config->slots[WF_INTERNAL_MIDI_SLOT]);
- if (hw_config->irq > 0) {
- free_irq (hw_config->irq, NULL);
- }
- if (hw_config->slots[WF_EXTERNAL_MIDI_SLOT] > 0) {
- sound_unload_mididev (hw_config->slots[WF_EXTERNAL_MIDI_SLOT]);
+ if (virt_dev->devno >= 0) {
+ sound_unload_mididev (virt_dev->devno);
X }
X }
X
X static void
-start_uart_mode (struct wf_mpu_config *devc)
+start_uart_mode (void)
+
X {
- int ok, timeout;
+ int ok, i;


X unsigned long flags;
X
X save_flags (flags);
X cli ();

X
- for (timeout = 30000; timeout > 0 && !output_ready (devc); timeout--);


+ /* XXX fix me */

X
- wf_mpu_cmd (devc, UART_MODE_ON);
+ for (i = 0; i < 30000 && !output_ready (); i++);
X
- for (ok = 0, timeout = 50000; timeout > 0 && !ok; timeout--) {
- if (input_avail (devc)) {
- if (read_data (devc) == MPU_ACK) {
+ outb (UART_MODE_ON, COMDPORT(phys_dev));
+
+ for (ok = 0, i = 50000; i > 0 && !ok; i--) {
+ if (input_avail ()) {
+ if (read_data () == MPU_ACK) {
X ok = 1;
X }
X }
@@ -978,6 +902,30 @@


X restore_flags (flags);
X }
X

-#endif
+#ifdef OSS_SUPPORT
+
+int
+probe_wf_mpu (struct address_info *hw_config)
+
+{
+ return !detect_wf_mpu (hw_config->irq, hw_config->io_base);
+}
+
+void
+attach_wf_mpu (struct address_info *hw_config)
+
+{
+ (void) install_wf_mpu ();
+}
+
+void
+unload_wf_mpu (void)
+{
+ uninstall_wf_mpu ();
+}
+
+#endif OSS_SUPPORT
+
+#endif CONFIG_SOUND_WAVEFRONT_MODULE_AND_MODULE
X
X
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c
--- v2.2.0-pre4/linux/drivers/video/atyfb.c Tue Dec 22 14:16:56 1998
+++ linux/drivers/video/atyfb.c Mon Jan 4 10:09:59 1999
@@ -2752,6 +2752,7 @@
X addr = pdev->base_address[1];
X if (!addr)
X continue;
+ addr &= PCI_BASE_ADDRESS_MEM_MASK;
X
X #ifdef __sparc__
X /*
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/video/chipsfb.c linux/drivers/video/chipsfb.c
--- v2.2.0-pre4/linux/drivers/video/chipsfb.c Tue Dec 22 14:16:56 1998
+++ linux/drivers/video/chipsfb.c Mon Jan 4 10:09:59 1999
@@ -53,11 +53,14 @@
X struct {
X __u8 red, green, blue;
X } palette[256];
+ unsigned long frame_buffer_phys;
X __u8 *frame_buffer;
- __u8 *blitter_regs;
+ unsigned long blitter_regs_phys;
+ __u32 *blitter_regs;
+ unsigned long blitter_data_phys;
+ __u8 *blitter_data;
+ unsigned long io_base_phys;
X __u8 *io_base;
- unsigned long chips_base_phys;
- unsigned long chips_io_phys;
X struct fb_info_chips *next;
X #ifdef CONFIG_PMAC_PBOOK
X unsigned char *save_framebuffer;
@@ -214,27 +217,28 @@
X if (con == currcon) /* current console? */
X return fb_get_cmap(cmap, kspc, chipsfb_getcolreg, info);
X if (fb_display[con].cmap.len) /* non default colormap? */
- fb_copy_cmap(&fb_display[con].cmap, cmap, kspc? 0: 2);
- else
- fb_copy_cmap(fb_default_cmap(256), cmap, kspc? 0: 2);
+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+ else {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);


+ }
X return 0;
X }
X

X static int chips_set_cmap(struct fb_cmap *cmap, int kspc, int con,
X struct fb_info *info)
X {
- struct display *disp = &fb_display[con];
X int err;
X
- if (disp->cmap.len == 0) {
- err = fb_alloc_cmap(&disp->cmap, 256, 0);
- if (err)
+ if (!fb_display[con].cmap.len) { /* no colormap allocated? */
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0)))
X return err;
X }
-
- if (con == currcon)
+ if (con == currcon) /* current console? */
X return fb_set_cmap(cmap, kspc, chipsfb_setcolreg, info);
- fb_copy_cmap(cmap, &disp->cmap, kspc==0);
+ else
+ fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);


X return 0;
X }
X

@@ -244,24 +248,21 @@


X return -EINVAL;
X }
X

-static int chipsfb_switch(int con, struct fb_info *info)
+static int chipsfbcon_switch(int con, struct fb_info *info)
X {
X struct fb_info_chips *p = (struct fb_info_chips *) info;
- struct display* old_disp = &fb_display[currcon];
- struct display* new_disp = &fb_display[con];
- int bit_depth;
+ int new_bpp, old_bpp;
X
+ /* Do we have to save the colormap? */
X if (fb_display[currcon].cmap.len)
- fb_get_cmap(&old_disp->cmap, 1, chipsfb_getcolreg, info);
+ fb_get_cmap(&fb_display[currcon].cmap, 1, chipsfb_getcolreg, info);
X
- bit_depth = new_disp->var.bits_per_pixel;
- if (old_disp->var.bits_per_pixel != bit_depth)
- {
- currcon = con;
- chips_set_bitdepth(p, new_disp, con, bit_depth);
- }
- else
- currcon = con;
+ new_bpp = fb_display[con].var.bits_per_pixel;
+ old_bpp = fb_display[currcon].var.bits_per_pixel;
+ currcon = con;
+
+ if (new_bpp != old_bpp)
+ chips_set_bitdepth(p, &fb_display[con], con, new_bpp);
X
X do_install_cmap(con, info);
X return 0;
@@ -277,9 +278,10 @@
X struct fb_info_chips *p = (struct fb_info_chips *) info;
X int i;
X
- if (blank > 1) {
+ // used to disable backlight only for blank > 1, but it seems
+ // useful at blank = 1 too (saves battery, extends backlight life)
+ if (blank) {
X pmu_enable_backlight(0);
- } else if (blank) {
X for (i = 0; i < 256; ++i) {
X out_8(p->io_base + 0x3c8, i);
X udelay(1);
@@ -311,10 +313,8 @@
X u_int transp, struct fb_info *info)
X {
X struct fb_info_chips *p = (struct fb_info_chips *) info;
- int hr;
X
- hr = (p->fix.visual != FB_VISUAL_PSEUDOCOLOR)? (regno << 3): regno;
- if (hr > 255)
+ if (regno > 255)
X return 1;
X red >>= 8;
X green >>= 8;
@@ -322,18 +322,18 @@
X p->palette[regno].red = red;
X p->palette[regno].green = green;
X p->palette[regno].blue = blue;
- out_8(p->io_base + 0x3c8, hr);
+ out_8(p->io_base + 0x3c8, regno);
X udelay(1);
X out_8(p->io_base + 0x3c9, red);
X out_8(p->io_base + 0x3c9, green);
X out_8(p->io_base + 0x3c9, blue);
X
X #ifdef FBCON_HAS_CFB16
- if (regno < 16)
- p->fbcon_cfb16_cmap[regno] = (red << 10) | (green << 5) | blue;
+ if (regno < 16) p->fbcon_cfb16_cmap[regno] =
+ ((red & 0xf8) << 7) | ((green & 0xf8) << 2) | ((blue & 0xf8) >> 3);
X #endif
X
- return 0;
+ return 0;
X }
X
X static void do_install_cmap(int con, struct fb_info *info)
@@ -356,14 +356,14 @@
X
X if (bpp == 16) {
X if (con == currcon) {
- write_cr(0x13, 200); // 16 bit display width (decimal)
- write_xr(0x81, 0x14); // 15 bit (TrueColor) color mode
- write_xr(0x82, 0x00); // disable palettes
+ write_cr(0x13, 200); // Set line length (doublewords)
+ write_xr(0x81, 0x14); // 15 bit (555) color mode
+ write_xr(0x82, 0x00); // Disable palettes
X write_xr(0x20, 0x10); // 16 bit blitter mode
X }
X
X fix->line_length = 800*2;
- fix->visual = FB_VISUAL_DIRECTCOLOR;
+ fix->visual = FB_VISUAL_TRUECOLOR;
X
X var->red.offset = 10;
X var->green.offset = 5;
@@ -378,7 +378,7 @@
X #endif
X } else if (bpp == 8) {
X if (con == currcon) {
- write_cr(0x13, 100); // 8 bit display width (decimal)
+ write_cr(0x13, 100); // Set line length (doublewords)
X write_xr(0x81, 0x12); // 8 bit color mode
X write_xr(0x82, 0x08); // Graphics gamma enable
X write_xr(0x20, 0x00); // 8 bit blitter mode
@@ -402,7 +402,7 @@
X disp->visual = fix->visual;
X disp->var = *var;
X
-#ifdef CONFIG_PMAC_PBOOK
+#if (defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_FB_COMPAT_XPMAC))
X display_info.depth = bpp;
X display_info.pitch = fix->line_length;
X #endif
@@ -549,9 +549,17 @@
X int i;
X
X strcpy(p->fix.id, "C&T 65550");
- p->fix.smem_start = (char *) p->chips_base_phys;
- p->fix.smem_len = 800 * 600;
- p->fix.mmio_start = (char *) p->chips_io_phys;
+ p->fix.smem_start = (char *) p->frame_buffer_phys;
+
+// FIXME: Assumes 1MB frame buffer, but 65550 supports 1MB or 2MB.
+// * "3500" PowerBook G3 (the original PB G3) has 2MB.
+// * 2400 has 1MB composed of 2 Mitsubishi M5M4V4265CTP DRAM chips.
+// Motherboard actually supports 2MB -- there are two blank locations
+// for a second pair of DRAMs. (Thanks, Apple!)
+// * 3400 has 1MB (I think). Don't know if it's expandable.
+// -- Tim Seufert
+ p->fix.smem_len = 0x100000; // 1MB
+ p->fix.mmio_start = (char *) p->io_base_phys;
X p->fix.type = FB_TYPE_PACKED_PIXELS;
X p->fix.visual = FB_VISUAL_PSEUDOCOLOR;
X p->fix.line_length = 800;
@@ -574,7 +582,7 @@
X p->disp.cmap.green = NULL;
X p->disp.cmap.blue = NULL;
X p->disp.cmap.transp = NULL;
- p->disp.screen_base = (char *) p->frame_buffer;
+ p->disp.screen_base = p->frame_buffer;
X p->disp.visual = p->fix.visual;
X p->disp.type = p->fix.type;
X p->disp.type_aux = p->fix.type_aux;
@@ -589,7 +597,7 @@
X p->info.disp = &p->disp;
X p->info.fontname[0] = 0;
X p->info.changevar = NULL;
- p->info.switch_con = &chipsfb_switch;
+ p->info.switch_con = &chipsfbcon_switch;
X p->info.updatevar = &chipsfb_updatevar;
X p->info.blank = &chipsfb_blank;
X p->info.flags = FBINFO_FLAG_DEFAULT;
@@ -606,7 +614,8 @@
X return;
X }
X
- printk("fb%d: Chips 65550 frame buffer\n", GET_FB_IDX(p->info.node));
+ printk("fb%d: Chips 65550 frame buffer (%dK RAM detected)\n",
+ GET_FB_IDX(p->info.node), p->fix.smem_len / 1024);
X
X chips_hw_init(p);
X
@@ -619,10 +628,10 @@
X display_info.mode = VMODE_800_600_60;
X strncpy(display_info.name, "chips65550",
X sizeof(display_info.name));
- display_info.fb_address = p->chips_base_phys + 0x800000;
- display_info.cmap_adr_address = p->chips_io_phys + 0x3c8;
- display_info.cmap_data_address = p->chips_io_phys + 0x3c9;
- display_info.disp_reg_address = p->chips_base_phys + 0xc00000;
+ display_info.fb_address = p->frame_buffer_phys;
+ display_info.cmap_adr_address = p->io_base_phys + 0x3c8;
+ display_info.cmap_data_address = p->io_base_phys + 0x3c9;
+ display_info.disp_reg_address = p->blitter_regs_phys;
X console_fb_info = &p->info;
X }
X #endif /* CONFIG_FB_COMPAT_XPMAC */
@@ -661,17 +670,23 @@
X return;
X memset(p, 0, sizeof(*p));
X addr = dp->addrs[0].address;
- p->chips_base_phys = addr;
- p->frame_buffer = __ioremap(addr+0x800000, 0x100000, _PAGE_NO_CACHE);
- p->blitter_regs = ioremap(addr + 0xC00000, 0x1000);
+#ifdef __BIG_ENDIAN
+ addr += 0x800000; // Use big-endian aperture
+#endif
+ p->frame_buffer_phys = addr;
+ p->frame_buffer = __ioremap(addr, 0x200000, _PAGE_NO_CACHE);
+ p->blitter_regs_phys = addr + 0x400000;
+ p->blitter_regs = ioremap(addr + 0x400000, 0x1000);
+ p->blitter_data_phys = addr + 0x410000;
+ p->blitter_data = ioremap(addr + 0x410000, 0x10000);
X
X if (pci_device_loc(dp, &bus, &devfn) == 0) {
X pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd);
X cmd |= 3; /* enable memory and IO space */
X pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd);
- p->io_base = (unsigned char *) pci_io_base(bus);
+ p->io_base = (__u8 *) pci_io_base(bus);
X /* XXX really want the physical address here */
- p->chips_io_phys = (unsigned long) pci_io_base(bus);
+ p->io_base_phys = (unsigned long) pci_io_base(bus);
X }
X
X /* Clear the entire framebuffer */
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/video/matroxfb.c linux/drivers/video/matroxfb.c
--- v2.2.0-pre4/linux/drivers/video/matroxfb.c Tue Dec 22 14:16:57 1998
+++ linux/drivers/video/matroxfb.c Mon Jan 4 14:33:44 1999
@@ -2,9 +2,9 @@
X *
X * Hardware accelerated Matrox Millennium I, II, Mystique and G200
X *
- * (c) 1998 Petr Vandrovec <vand...@vc.cvut.cz>
+ * (c) 1998,1999 Petr Vandrovec <vand...@vc.cvut.cz>
X *
- * Version: 1.8 1998/12/11
+ * Version: 1.9 1999/01/04
X *
X * MTRR stuff: 1998 Tom Rini <tmr...@ntplx.net>
X *
@@ -4841,7 +4841,7 @@
X static int no_pci_retry = 0; /* "matrox:nopciretry" */
X static int novga = 0; /* "matrox:novga" */
X static int nobios = 0; /* "matrox:nobios" */
-static int noinit = 0; /* "matrox:noinit" */
+static int noinit = 1; /* "matrox:noinit" */
X static int inverse = 0; /* "matrox:inverse" */
X static int hwcursor = 1; /* "matrox:nohwcursor" */
X static int blink = 1; /* "matrox:noblink" */
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/video/offb.c linux/drivers/video/offb.c
--- v2.2.0-pre4/linux/drivers/video/offb.c Tue Dec 22 14:16:57 1998
+++ linux/drivers/video/offb.c Mon Jan 4 10:09:59 1999
@@ -68,7 +68,6 @@
X
X static int ofonly = 0;
X
-
X /*
X * Interface used by the world
X */
@@ -251,8 +250,10 @@
X else if (fb_display[con].cmap.len) /* non default colormap? */
X fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
X else
- fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
- cmap, kspc ? 0 : 2);
+ {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);


+ }
X return 0;
X }
X

@@ -270,8 +271,8 @@
X return -ENOSYS;
X
X if (!fb_display[con].cmap.len) { /* no colormap allocated? */
- if ((err = fb_alloc_cmap(&fb_display[con].cmap,
- 1<<fb_display[con].var.bits_per_pixel, 0)))
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0)))
X return err;
X }
X if (con == currcon) /* current console? */
@@ -522,18 +523,20 @@
X fix->type = FB_TYPE_PACKED_PIXELS;
X fix->type_aux = 0;
X
- /* XXX kludge for ati */
- if (strncmp(name, "ATY,", 4) == 0) {
- unsigned long base = address & 0xff000000UL;
- info->cmap_adr = ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
- info->cmap_data = info->cmap_adr + 1;
- }
-
X if (depth == 8)
- fix->visual = info->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
+ {
+ /* XXX kludge for ati */
+ if (strncmp(name, "ATY,", 4) == 0) {
+ unsigned long base = address & 0xff000000UL;
+ info->cmap_adr = ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
+ info->cmap_data = info->cmap_adr + 1;
+ }
+ fix->visual = info->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
X : FB_VISUAL_STATIC_PSEUDOCOLOR;
+ }
X else
- fix->visual = FB_VISUAL_TRUECOLOR;
+ fix->visual = /*info->cmap_adr ? FB_VISUAL_DIRECTCOLOR
+ : */FB_VISUAL_TRUECOLOR;
X
X var->xoffset = var->yoffset = 0;
X var->bits_per_pixel = depth;
@@ -611,10 +614,14 @@
X disp->dispsw = &fbcon_cfb16;
X disp->dispsw_data = info->fbcon_cmap.cfb16;
X for (i = 0; i < 16; i++)
- info->fbcon_cmap.cfb16[i] =
- (((default_blu[i] >> 3) & 0x1f) << 10) |
- (((default_grn[i] >> 3) & 0x1f) << 5) |
- ((default_red[i] >> 3) & 0x1f);
+ if (fix->visual == FB_VISUAL_TRUECOLOR)
+ info->fbcon_cmap.cfb16[i] =
+ (((default_blu[i] >> 3) & 0x1f) << 10) |
+ (((default_grn[i] >> 3) & 0x1f) << 5) |
+ ((default_red[i] >> 3) & 0x1f);
+ else
+ info->fbcon_cmap.cfb16[i] =
+ (i << 10) | (i << 5) | i;
X break;
X #endif
X #ifdef FBCON_HAS_CFB32
@@ -622,9 +629,14 @@
X disp->dispsw = &fbcon_cfb32;
X disp->dispsw_data = info->fbcon_cmap.cfb32;
X for (i = 0; i < 16; i++)
- info->fbcon_cmap.cfb32[i] = (default_blu[i] << 16) |
- (default_grn[i] << 8) |
- default_red[i];
+ if (fix->visual == FB_VISUAL_TRUECOLOR)
+ info->fbcon_cmap.cfb32[i] =
+ (default_blu[i] << 16) |
+ (default_grn[i] << 8) |
+ default_red[i];
+ else
+ info->fbcon_cmap.cfb32[i] =
+ (i << 16) | (i << 8) | i;
X break;
X #endif
X default:
@@ -791,7 +803,7 @@
X info2->palette[regno].green = green;
X info2->palette[regno].blue = blue;
X
- *info2->cmap_adr = regno;
+ *info2->cmap_adr = regno;/* On some chipsets, add << 3 in 15 bits */
X mach_eieio();
X *info2->cmap_data = red;
X mach_eieio();
@@ -804,8 +816,7 @@
X switch (info2->var.bits_per_pixel) {
X #ifdef FBCON_HAS_CFB16
X case 16:
- info2->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
- regno;
+ info2->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | regno;
X break;
X #endif
X #ifdef FBCON_HAS_CFB32
@@ -827,8 +838,10 @@
X if (fb_display[con].cmap.len)
X fb_set_cmap(&fb_display[con].cmap, 1, offb_setcolreg, info);
X else
- fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
- 1, offb_setcolreg, info);
+ {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ fb_set_cmap(fb_default_cmap(size), 1, offb_setcolreg, info);
+ }
X }
X
X
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/Config.in linux/fs/Config.in


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre5 failed'
fi

echo 'End of part 06'
echo 'File patch-2.2.0-pre5 is continued in part 07'
echo 07 > _shar_seq_.tmp

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

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to
Archive-name: v2.1/patch-2.2.0-pre5/part03

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


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

if test "$Scheck" != 03; then


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

X action = RESET_DELAY;
X }
- if ( (action & (BUS_RESET | HOST_RESET)) && (p->flags & AHC_IN_RESET)
- && ((jiffies - p->reset_start) > (2 * HZ * 3)) )
- {
- printk(KERN_ERR "(scsi%d:%d:%d:%d) Yikes!! Card must have left to go "
- "back to Adaptec!!\n", p->host_no, CTL_OF_CMD(cmd));
- unpause_sequencer(p, FALSE);
- DRIVER_UNLOCK
- return(SCSI_RESET_SNOOZE);
- }
X /*
X * By this point, we want to already know what we are going to do and
X * only have the following code implement our course of action.
@@ -10942,15 +10961,23 @@
X case BUS_RESET:
X case HOST_RESET:
X default:
- p->reset_start = jiffies;
- p->flags |= AHC_IN_RESET;
+ p->flags |= AHC_IN_RESET | AHC_RESET_DELAY;
+ p->dev_expires[p->scsi_id] = jiffies + (3 * HZ);
+ p->dev_timer_active |= (0x01 << p->scsi_id);


+ if ( !(p->dev_timer_active & (0x01 << MAX_TARGETS)) ||

+ time_after_eq(p->dev_timer.expires, p->dev_expires[p->scsi_id]) )
+ {
+ del_timer(&p->dev_timer);
+ p->dev_timer.expires = p->dev_expires[p->scsi_id];
+ add_timer(&p->dev_timer);


+ p->dev_timer_active |= (0x01 << MAX_TARGETS);

+ }
X aic7xxx_reset_channel(p, cmd->channel, TRUE);
X if ( (p->features & AHC_TWIN) && (action & HOST_RESET) )
X {
X aic7xxx_reset_channel(p, cmd->channel ^ 0x01, TRUE);
X restart_sequencer(p);
X }


- p->last_reset = jiffies;

X if (action != HOST_RESET)
X result = SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
X else
@@ -10974,7 +11001,7 @@
X */
X if ( flags & SCSI_RESET_SYNCHRONOUS )
X {
- cmd->result = DID_RESET << 16;
+ cmd->result = DID_BUS_BUSY << 16;
X cmd->done(cmd);
X }
X p->flags &= ~AHC_IN_RESET;
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/scsi/aic7xxx_proc.c linux/drivers/scsi/aic7xxx_proc.c
--- v2.2.0-pre4/linux/drivers/scsi/aic7xxx_proc.c Tue Dec 22 14:16:56 1998
+++ linux/drivers/scsi/aic7xxx_proc.c Mon Jan 4 12:57:44 1999
@@ -31,7 +31,7 @@
X
X #define BLS (&aic7xxx_buffer[size])
X #define HDRB \
-" < 512 512-1K 1-2K 2-4K 4-8K 8-16K 16-32K 32-64K 64-128K >128K"
+" < 2K 2K+ 4K+ 8K+ 16K+ 32K+ 64K+ 128K+"
X
X #ifdef PROC_DEBUG
X extern int vsprintf(char *, const char *, va_list);
@@ -86,7 +86,7 @@
X int size = 0;
X unsigned char i;
X struct aic7xxx_xferstats *sp;
- unsigned char target, lun;
+ unsigned char target;
X
X HBAptr = NULL;
X
@@ -130,15 +130,12 @@
X size = 4096;
X for (target = 0; target < MAX_TARGETS; target++)
X {
- for (lun = 0; lun < MAX_LUNS; lun++)
- {
- if (p->stats[target][lun].r_total != 0)
+ if (p->dev_flags[target] & DEVICE_PRESENT)
X #ifdef AIC7XXX_PROC_STATS
- size += 512;
+ size += 512;
X #else
- size += 256;
+ size += 256;
X #endif
- }
X }
X if (aic7xxx_buffer_size != size)
X {
@@ -272,88 +269,83 @@
X size += sprintf(BLS, "%d}\n", p->dev_max_queue_depth[i]);
X
X size += sprintf(BLS, "\n");
- size += sprintf(BLS, "Statistics:\n");
+ size += sprintf(BLS, "Statistics:\n\n");
X for (target = 0; target < MAX_TARGETS; target++)
X {
- for (lun = 0; lun < MAX_LUNS; lun++)
+ sp = &p->stats[target];
+ if ((p->dev_flags[target] & DEVICE_PRESENT) == 0)
X {
- sp = &p->stats[target][lun];
- if (sp->r_total == 0)
- {
- continue;
- }
- if (p->features & AHC_TWIN)
+ continue;
+ }
+ if (p->features & AHC_TWIN)
+ {
+ size += sprintf(BLS, "(scsi%d:%d:%d:%d)\n",
+ p->host_no, (target >> 3), (target & 0x7), 0);
+ }
+ else
+ {
+ size += sprintf(BLS, "(scsi%d:%d:%d:%d)\n",
+ p->host_no, 0, target, 0);
+ }
+ size += sprintf(BLS, " Device using %s/%s",
+ (p->transinfo[target].cur_width == MSG_EXT_WDTR_BUS_16_BIT) ?
+ "Wide" : "Narrow",
+ (p->transinfo[target].cur_offset != 0) ?
+ "Sync transfers at " : "Async transfers.\n" );
+ if (p->transinfo[target].cur_offset != 0)
+ {
+ struct aic7xxx_syncrate *sync_rate;
+ int period = p->transinfo[target].cur_period;
+ int rate = (p->transinfo[target].cur_width ==
+ MSG_EXT_WDTR_BUS_16_BIT) ? 1 : 0;
+
+ sync_rate = aic7xxx_find_syncrate(p, &period, AHC_SYNCRATE_ULTRA2);
+ if (sync_rate != NULL)
X {
- size += sprintf(BLS, "(scsi%d:%d:%d:%d)\n",
- p->host_no, (target >> 3), (target & 0x7), lun);
+ size += sprintf(BLS, "%s MByte/sec, offset %d\n",
+ sync_rate->rate[rate],
+ p->transinfo[target].cur_offset );
X }
X else
X {
- size += sprintf(BLS, "(scsi%d:%d:%d:%d)\n",
- p->host_no, 0, target, lun);
- }
- size += sprintf(BLS, " Device using %s/%s\n",
- (p->transinfo[target].cur_width == MSG_EXT_WDTR_BUS_16_BIT) ?
- "Wide" : "Narrow",
- (p->transinfo[target].cur_offset != 0) ?
- "Sync transfers at" : "Async transfers." );
- if (p->transinfo[target].cur_offset != 0)
- {
- struct aic7xxx_syncrate *sync_rate;
- int period = p->transinfo[target].cur_period;
- int rate = (p->transinfo[target].cur_width ==
- MSG_EXT_WDTR_BUS_16_BIT) ? 1 : 0;
-
- sync_rate = aic7xxx_find_syncrate(p, &period, AHC_SYNCRATE_ULTRA2);
- if (sync_rate != NULL)
- {
- size += sprintf(BLS, " %s MByte/sec, offset %d\n",
- sync_rate->rate[rate],
- p->transinfo[target].cur_offset );
- }
- else
- {
- size += sprintf(BLS, " 3.3 MByte/sec, offset %d\n",
- p->transinfo[target].cur_offset );
- }
+ size += sprintf(BLS, "3.3 MByte/sec, offset %d\n",
+ p->transinfo[target].cur_offset );
X }
- size += sprintf(BLS, " Device Negotiation Settings\n");
- size += sprintf(BLS, " Period Offset Bus Width\n");
- size += sprintf(BLS, "User %03d %03d %d\n",
- p->transinfo[target].user_period,
- p->transinfo[target].user_offset,
- p->transinfo[target].user_width);
- size += sprintf(BLS, "Goal %03d %03d %d\n",
- p->transinfo[target].goal_period,
- p->transinfo[target].goal_offset,
- p->transinfo[target].goal_width);
- size += sprintf(BLS, "Current %03d %03d %d\n",
- p->transinfo[target].cur_period,
- p->transinfo[target].cur_offset,
- p->transinfo[target].cur_width);
+ }
+ size += sprintf(BLS, " Transinfo settings: ");
+ size += sprintf(BLS, "current(%d/%d/%d), ",
+ p->transinfo[target].cur_period,
+ p->transinfo[target].cur_offset,
+ p->transinfo[target].cur_width);
+ size += sprintf(BLS, "goal(%d/%d/%d), ",
+ p->transinfo[target].goal_period,
+ p->transinfo[target].goal_offset,
+ p->transinfo[target].goal_width);
+ size += sprintf(BLS, "user(%d/%d/%d)\n",
+ p->transinfo[target].user_period,
+ p->transinfo[target].user_offset,
+ p->transinfo[target].user_width);
X #ifdef AIC7XXX_PROC_STATS
- size += sprintf(BLS, " Total transfers %ld (%ld read;%ld written)\n",
- sp->xfers, sp->r_total, sp->w_total);
- size += sprintf(BLS, " blks(512) rd=%ld; blks(512) wr=%ld\n",
- sp->r_total512, sp->w_total512);
- size += sprintf(BLS, "%s\n", HDRB);
- size += sprintf(BLS, " Reads:");
- for (i = 0; i < NUMBER(sp->r_bins); i++)
- {
- size += sprintf(BLS, "%6ld ", sp->r_bins[i]);
- }
- size += sprintf(BLS, "\n");
- size += sprintf(BLS, "Writes:");
- for (i = 0; i < NUMBER(sp->w_bins); i++)
- {
- size += sprintf(BLS, "%6ld ", sp->w_bins[i]);
- }
+ size += sprintf(BLS, " Total transfers %ld (%ld reads and %ld writes)\n",
+ sp->r_total + sp->w_total, sp->r_total, sp->w_total);
+ size += sprintf(BLS, "%s\n", HDRB);
+ size += sprintf(BLS, " Reads:");
+ for (i = 0; i < NUMBER(sp->r_bins); i++)
+ {
+ size += sprintf(BLS, " %7ld", sp->r_bins[i]);
+ }
+ size += sprintf(BLS, "\n");
+ size += sprintf(BLS, " Writes:");
+ for (i = 0; i < NUMBER(sp->w_bins); i++)
+ {
+ size += sprintf(BLS, " %7ld", sp->w_bins[i]);
+ }
+ size += sprintf(BLS, "\n");
X #else
- size += sprintf(BLS, " Total transfers: %ld/%ld read/written)\n",
- sp->r_total, sp->w_total);
+ size += sprintf(BLS, " Total transfers %ld (%ld reads and %ld writes)\n",
+ sp->r_total + sp->w_total, sp->r_total, sp->w_total);


X #endif /* AIC7XXX_PROC_STATS */

- size += sprintf(BLS, "\n\n");
- }
+ size += sprintf(BLS, "\n\n");
X }
X
X if (size >= aic7xxx_buffer_size)
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.2.0-pre4/linux/drivers/scsi/scsi.c Tue Dec 22 14:16:56 1998
+++ linux/drivers/scsi/scsi.c Mon Jan 4 12:57:44 1999
@@ -279,6 +279,7 @@
X {"MATSHITA","PD","*", BLIST_FORCELUN | BLIST_SINGLELUN},
X {"YAMAHA","CDR100","1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
X {"YAMAHA","CDR102","1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
+{"iomega","jaz 1GB","J.86", BLIST_NOTQ | BLIST_NOLUN},
X /*
X * Must be at end of list...
X */
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/Config.in linux/drivers/sound/Config.in
--- v2.2.0-pre4/linux/drivers/sound/Config.in Mon Dec 28 15:00:52 1998
+++ linux/drivers/sound/Config.in Mon Jan 4 11:37:29 1999
@@ -203,6 +203,7 @@
X
X dep_tristate 'Support for Yamaha OPL3-SA2, SA3, and SAx based PnP cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS
X if [ "$CONFIG_SOUND_OPL3SA2" = "y" ]; then
+ int 'Chipset (-1 for autoprobe, 2, or 3)' CONFIG_OPL3SA2_CHIPSET -1
X hex 'OPL3SA2 audio I/O base (530 - F48 valid)' CONFIG_OPL3SA2_BASE 530
X int 'OPL3SA2 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_OPL3SA2_IRQ 9
X int 'OPL3SA2 audio DMA 0, 1 or 3' CONFIG_OPL3SA2_DMA 0
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/Makefile linux/drivers/sound/Makefile
--- v2.2.0-pre4/linux/drivers/sound/Makefile Tue Dec 22 14:16:56 1998
+++ linux/drivers/sound/Makefile Mon Jan 4 11:37:29 1999
@@ -24,8 +24,7 @@
X
X export-objs := ad1848.o audio_syms.o midi_syms.o mpu401.o \
X msnd.o opl3.o sb_card.o sequencer_syms.o \
- sound_core.o sound_firmware.o sound_syms.o \
- uart401.o ad1816.o
+ sound_core.o sound_syms.o uart401.o ad1816.o
X
X
X
@@ -296,7 +295,7 @@
X
X ifeq ($(CONFIG_TRIX_HAVE_BOOT),y)
X trix_boot.h: $(patsubst "%", %, $(CONFIG_TRIX_BOOT_FILE)) hex2hex
- hex2hex -i trix_boot < $(CONFIG_TRIX_BOOT_FILE) > $@
+ ./hex2hex -i trix_boot < $(CONFIG_TRIX_BOOT_FILE) > $@
X else
X trix_boot.h:
X ( \
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- v2.2.0-pre4/linux/drivers/sound/ad1848.c Mon Dec 28 15:00:52 1998
+++ linux/drivers/sound/ad1848.c Mon Jan 4 11:37:29 1999
@@ -1944,10 +1944,11 @@
X if (devc->irq > 0) /* There is no point in freeing irq, if it wasn't allocated */
X free_irq(devc->irq, (void *)devc->dev_no);
X
- sound_free_dma(audio_devs[dev]->dmap_out->dma);
+ sound_free_dma(dma_playback);
+
+ if (dma_playback != dma_capture)
+ sound_free_dma(dma_capture);
X
- if (audio_devs[dev]->dmap_in->dma != audio_devs[dev]->dmap_out->dma)
- sound_free_dma(audio_devs[dev]->dmap_in->dma);
X }
X mixer = audio_devs[devc->dev_no]->mixer_dev;
X if(mixer>=0)
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/dev_table.c linux/drivers/sound/dev_table.c
--- v2.2.0-pre4/linux/drivers/sound/dev_table.c Thu Nov 12 16:21:22 1998
+++ linux/drivers/sound/dev_table.c Mon Jan 4 11:37:29 1999
@@ -524,7 +524,7 @@
X
X int sound_alloc_audiodev(void)
X {
- int i = register_sound_dsp(&oss_sound_fops);
+ int i = register_sound_dsp(&oss_sound_fops, -1);
X if(i==-1)
X return i;
X i>>=4;
@@ -536,7 +536,7 @@
X int sound_alloc_mididev(void)
X {
X #ifdef CONFIG_MIDI
- int i = register_sound_midi(&oss_sound_fops);
+ int i = register_sound_midi(&oss_sound_fops, -1);
X if(i==-1)
X return i;
X i>>=4;
@@ -566,7 +566,7 @@
X
X int sound_alloc_mixerdev(void)
X {
- int i = register_sound_mixer(&oss_sound_fops);
+ int i = register_sound_mixer(&oss_sound_fops, -1);
X if(i==-1)
X return -1;
X i>>=4;
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/dmasound.c linux/drivers/sound/dmasound.c
--- v2.2.0-pre4/linux/drivers/sound/dmasound.c Thu Dec 31 10:29:01 1998
+++ linux/drivers/sound/dmasound.c Mon Jan 4 11:37:30 1999
@@ -3853,7 +3853,7 @@
X #ifndef MODULE
X int mixer_unit;
X #endif
- mixer_unit = register_sound_mixer(&mixer_fops);
+ mixer_unit = register_sound_mixer(&mixer_fops, -1);
X if (mixer_unit < 0)
X return;
X
@@ -4258,7 +4258,7 @@
X #ifndef MODULE
X int sq_unit;
X #endif
- sq_unit = register_sound_dsp(&sq_fops);
+ sq_unit = register_sound_dsp(&sq_fops, -1);
X if (sq_unit < 0)
X return;
X
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c
--- v2.2.0-pre4/linux/drivers/sound/es1370.c Mon Dec 28 15:00:52 1998
+++ linux/drivers/sound/es1370.c Mon Jan 4 11:37:30 1999
@@ -2321,13 +2321,13 @@
X (s->ctrl & CTRL_XCTL0) ? "out" : "in",
X (s->ctrl & CTRL_XCTL1) ? "1" : "0");
X /* register devices */
- if ((s->dev_audio = register_sound_dsp(&es1370_audio_fops)) < 0)
+ if ((s->dev_audio = register_sound_dsp(&es1370_audio_fops, -1)) < 0)
X goto err_dev1;
- if ((s->dev_mixer = register_sound_mixer(&es1370_mixer_fops)) < 0)
+ if ((s->dev_mixer = register_sound_mixer(&es1370_mixer_fops, -1)) < 0)
X goto err_dev2;
- if ((s->dev_dac = register_sound_dsp(&es1370_dac_fops)) < 0)
+ if ((s->dev_dac = register_sound_dsp(&es1370_dac_fops, -1)) < 0)
X goto err_dev3;
- if ((s->dev_midi = register_sound_midi(&es1370_midi_fops)) < 0)
+ if ((s->dev_midi = register_sound_midi(&es1370_midi_fops, -1)) < 0)
X goto err_dev4;
X /* initialize the chips */
X outl(s->ctrl, s->io+ES1370_REG_CONTROL);
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c
--- v2.2.0-pre4/linux/drivers/sound/es1371.c Mon Dec 28 15:00:52 1998
+++ linux/drivers/sound/es1371.c Mon Jan 4 11:37:30 1999
@@ -2745,13 +2745,13 @@
X printk(KERN_INFO "es1371: found adapter at io %#06x irq %u\n"
X KERN_INFO "es1371: features: joystick 0x%x\n", s->io, s->irq, joystick[index]);
X /* register devices */
- if ((s->dev_audio = register_sound_dsp(&es1371_audio_fops)) < 0)
+ if ((s->dev_audio = register_sound_dsp(&es1371_audio_fops, -1)) < 0)
X goto err_dev1;
- if ((s->dev_mixer = register_sound_mixer(&es1371_mixer_fops)) < 0)
+ if ((s->dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1)) < 0)
X goto err_dev2;
- if ((s->dev_dac = register_sound_dsp(&es1371_dac_fops)) < 0)
+ if ((s->dev_dac = register_sound_dsp(&es1371_dac_fops, -1)) < 0)
X goto err_dev3;
- if ((s->dev_midi = register_sound_midi(&es1371_midi_fops)) < 0)
+ if ((s->dev_midi = register_sound_midi(&es1371_midi_fops, -1)) < 0)
X goto err_dev4;
X /* initialize codec registers */
X s->ctrl = 0;
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/msnd_pinnacle.c linux/drivers/sound/msnd_pinnacle.c
--- v2.2.0-pre4/linux/drivers/sound/msnd_pinnacle.c Tue Dec 22 14:16:56 1998
+++ linux/drivers/sound/msnd_pinnacle.c Mon Jan 4 11:37:30 1999
@@ -1450,7 +1450,7 @@


X return err;
X }
X

- if ((dev.dsp_minor = register_sound_dsp(&dev_fileops)) < 0) {
+ if ((dev.dsp_minor = register_sound_dsp(&dev_fileops, -1)) < 0) {
X printk(KERN_ERR LOGNAME ": Unable to register DSP operations\n");
X msnd_unregister(&dev);
X release_region(dev.io, dev.numio);
@@ -1458,7 +1458,7 @@
X return dev.dsp_minor;
X }
X
- if ((dev.mixer_minor = register_sound_mixer(&dev_fileops)) < 0) {
+ if ((dev.mixer_minor = register_sound_mixer(&dev_fileops, -1)) < 0) {
X printk(KERN_ERR LOGNAME ": Unable to register mixer operations\n");
X unregister_sound_mixer(dev.mixer_minor);
X msnd_unregister(&dev);
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/opl3sa.c linux/drivers/sound/opl3sa.c
--- v2.2.0-pre4/linux/drivers/sound/opl3sa.c Sun Jul 26 11:57:16 1998
+++ linux/drivers/sound/opl3sa.c Mon Jan 4 11:37:30 1999
@@ -260,6 +260,7 @@
X hw_config->dma,
X dma2,
X 0);
+ sound_unload_audiodev(hw_config->slots[0]);
X }
X
X void unload_opl3sa_mpu(struct address_info *hw_config)
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c
--- v2.2.0-pre4/linux/drivers/sound/opl3sa2.c Tue Dec 22 14:16:56 1998
+++ linux/drivers/sound/opl3sa2.c Mon Jan 4 11:37:30 1999
@@ -26,6 +26,9 @@
X * Scott Murray Original driver (Jun 14, 1998)
X * Paul J.Y. Lahaie Changed probing / attach code order
X * Scott Murray Added mixer support (Dec 03, 1998)
+ * Scott Murray Changed detection code to be more forgiving,
+ * added force option as last resort,
+ * fixed ioctl return values. (Dec 30, 1998)
X *
X */
X
@@ -50,6 +53,11 @@
X #define DEFAULT_MIC 50
X #define DEFAULT_TIMBRE 0
X
+/*
+ * NOTE: CHIPSET_UNKNOWN should match the default value of
+ * CONFIG_OPL3SA2_CHIPSET in Config.in to make everything
+ * work right in all situations.
+ */
X #define CHIPSET_UNKNOWN -1
X #define CHIPSET_OPL3SA2 1
X #define CHIPSET_OPL3SA3 2
@@ -59,7 +67,12 @@
X #ifdef CONFIG_OPL3SA2
X
X /* What's my version? */
-static int chipset_version = CHIPSET_UNKNOWN;
+#ifdef CONFIG_OPL3SA2_CHIPSET
+/* Set chipset if compiled into the kernel */
+static int chipset = CONFIG_OPL3SA2_CHIPSET;
+#else
+static int chipset = CHIPSET_UNKNOWN;
+#endif
X
X /* Oh well, let's just cache the name */
X static char chipset_name[16];
@@ -276,43 +289,47 @@
X return call_ad_mixer(devc, cmd, arg);
X else
X {
- if(*(int *)arg != 0)
+ if(*(int*)arg != 0)
X return -EINVAL;


X return 0;
X }
X

X case SOUND_MIXER_VOLUME:
- arg_to_volume_stereo(*(unsigned int *)arg,
+ arg_to_volume_stereo(*(unsigned int*)arg,
X &devc->volume_l,
X &devc->volume_r);
X opl3sa2_set_volume(devc, devc->volume_l,
X devc->volume_r);
- return ret_vol_stereo(devc->volume_l,
- devc->volume_r);
+ *(int*)arg = ret_vol_stereo(devc->volume_l,
+ devc->volume_r);
+ return 0;
X
X case SOUND_MIXER_MIC:
- arg_to_volume_mono(*(unsigned int *)arg,
+ arg_to_volume_mono(*(unsigned int*)arg,
X &devc->mic);
X opl3sa2_set_mic(devc, devc->mic);
- return ret_vol_mono(devc->mic);
+ *(int*)arg = ret_vol_mono(devc->mic);
+ return 0;
X
X case SOUND_MIXER_BASS:
- if(chipset_version != CHIPSET_OPL3SA2)
+ if(chipset != CHIPSET_OPL3SA2)
X {
- arg_to_volume_mono(*(unsigned int *)arg,
+ arg_to_volume_mono(*(unsigned int*)arg,
X &devc->bass);
X opl3sa3_set_bass(devc, devc->bass);
- return ret_vol_mono(devc->bass);
+ *(int*)arg = ret_vol_mono(devc->bass);
+ return 0;
X }
X return -EINVAL;
X
X case SOUND_MIXER_TREBLE:
- if(chipset_version != CHIPSET_OPL3SA2)
+ if(chipset != CHIPSET_OPL3SA2)
X {
X arg_to_volume_mono(*(unsigned int *)arg,
X &devc->treble);
X opl3sa3_set_treble(devc, devc->treble);
- return ret_vol_mono(devc->treble);
+ *(int*)arg = ret_vol_mono(devc->treble);
+ return 0;
X }
X return -EINVAL;
X
@@ -331,55 +348,83 @@
X if(call_ad_mixer(devc, cmd, arg) == -EINVAL)
X *(int*)arg = 0; /* no mixer devices */
X
- if(chipset_version != CHIPSET_OPL3SA2)
- return (*(int*)arg |= SOUND_MASK_VOLUME |
- SOUND_MASK_MIC |
- SOUND_MASK_BASS |
- SOUND_MASK_TREBLE);
+ *(int*)arg |= (SOUND_MASK_VOLUME | SOUND_MASK_MIC);
+
X /* OPL3-SA2 has no bass and treble mixers */
- return (*(int*)arg |= SOUND_MASK_VOLUME |
- SOUND_MASK_MIC);
+ if(chipset != CHIPSET_OPL3SA2)
+ *(int*)arg |= (SOUND_MASK_BASS |
+ SOUND_MASK_TREBLE);
+ return 0;
X
X case SOUND_MIXER_STEREODEVS:
X if(call_ad_mixer(devc, cmd, arg) == -EINVAL)
X *(int*)arg = 0; /* no stereo devices */
- return (*(int*)arg |= SOUND_MASK_VOLUME);
+ *(int*)arg |= SOUND_MASK_VOLUME;
+ return 0;
X
X case SOUND_MIXER_RECMASK:
X if(devc->ad_mixer_dev != -1)
+ {
X return call_ad_mixer(devc, cmd, arg);
+ }
X else
- return (*(int*)arg = 0); /* no record devices */
+ {
+ /* No recording devices */
+ return (*(int*)arg = 0);
+ }
X
X case SOUND_MIXER_CAPS:
X if(devc->ad_mixer_dev != -1)
+ {
X return call_ad_mixer(devc, cmd, arg);
+ }
X else
- return (*(int*)arg = SOUND_CAP_EXCL_INPUT);
+ {
+ *(int*)arg = SOUND_CAP_EXCL_INPUT;


+ return 0;
+ }
X

X case SOUND_MIXER_RECSRC:
X if(devc->ad_mixer_dev != -1)
+ {
X return call_ad_mixer(devc, cmd, arg);
+ }
X else
- return (*(int*)arg = 0); /* no record source */
+ {
+ /* No recording source */
+ return (*(int*)arg = 0);
+ }
X
X case SOUND_MIXER_VOLUME:
- return (*(int*)arg = ret_vol_stereo(devc->volume_l,
- devc->volume_r));
+ *(int*)arg = ret_vol_stereo(devc->volume_l,
+ devc->volume_r);
+ return 0;
X
X case SOUND_MIXER_MIC:
- return (*(int*)arg = ret_vol_mono(devc->mic));
+ *(int*)arg = ret_vol_mono(devc->mic);
+ return 0;
X
X case SOUND_MIXER_BASS:
- if(chipset_version != CHIPSET_OPL3SA2)
- return (*(int*)arg = ret_vol_mono(devc->bass));
- return -EINVAL;
-
+ if(chipset != CHIPSET_OPL3SA2)
+ {
+ *(int*)arg = ret_vol_mono(devc->bass);
+ return 0;
+ }
+ else
+ {
+ return -EINVAL;
+ }
X
X case SOUND_MIXER_TREBLE:
- if(chipset_version != CHIPSET_OPL3SA2)
- return (*(int*)arg = ret_vol_mono(devc->treble));
- return -EINVAL;
+ if(chipset != CHIPSET_OPL3SA2)
+ {
+ *(int*)arg = ret_vol_mono(devc->treble);
+ return 0;
+ }
+ else
+ {
+ return -EINVAL;
+ }
X
X default:
X return -EINVAL;
@@ -481,6 +526,15 @@
X
X int probe_opl3sa2(struct address_info *hw_config)
X {
+ unsigned char chipsets[8] = { CHIPSET_UNKNOWN, /* 0 */
+ CHIPSET_OPL3SA2, /* 1 */
+ CHIPSET_OPL3SA3, /* 2 */
+ CHIPSET_UNKNOWN, /* 3 */
+ CHIPSET_OPL3SAX, /* 4 */
+ CHIPSET_OPL3SAX, /* 5 */
+ CHIPSET_UNKNOWN, /* 6 */
+ CHIPSET_OPL3SA3, /* 7 */ };
+ unsigned char version = 0;
X char tag;
X
X /*
@@ -489,20 +543,80 @@
X if(check_region(hw_config->io_base, 2))
X {
X printk(KERN_ERR
- "opl3sa2.c: Control I/O port 0x%03x not free\n",
+ "%s: Control I/O port 0x%03x not free\n",
+ __FILE__,
X hw_config->io_base);
X return 0;
X }
X
X /*
- * Look at chipset version in lower 3 bits of index 0x0A, miscellaneous
+ * Determine chipset type (SA2, SA3, or SAx)
+ *
+ * Have to handle two possible override situations:
+ * 1) User compiled driver into the kernel and forced chipset type
+ * 2) User built a module, but wants to override the chipset type
X */
- chipset_version = 0;
- opl3sa2_read(hw_config->io_base,
- OPL3SA2_MISC,
- (unsigned char*) &chipset_version);
- chipset_version &= 0x0007;
- switch(chipset_version)
+ if(chipset == CHIPSET_UNKNOWN)
+ {
+ if(hw_config->card_subtype == CHIPSET_UNKNOWN)
+ {
+ /*
+ * Look at chipset version in lower 3 bits of index 0x0A, miscellaneous
+ */
+ opl3sa2_read(hw_config->io_base,
+ OPL3SA2_MISC,
+ (unsigned char*) &version);
+ version &= 0x07;
+
+ /* Match version number to appropiate chipset */
+ chipset = chipsets[version];
+ }
+ else
+ {
+ /* Use user specified chipset */
+ switch(hw_config->card_subtype)
+ {
+ case 2:
+ chipset = CHIPSET_OPL3SA2;
+ break;
+
+ case 3:
+ chipset = CHIPSET_OPL3SA3;
+ break;
+
+ default:
+ printk(KERN_ERR "%s: Unknown chipset %d\n",
+ __FILE__,
+ hw_config->card_subtype);
+ chipset = CHIPSET_UNKNOWN;


+ break;
+ }
+ }
+ }

+ else
+ {
+ /* Use user compiled in chipset */
+ switch(chipset)
+ {
+ case 2:
+ chipset = CHIPSET_OPL3SA2;
+ break;
+
+ case 3:
+ chipset = CHIPSET_OPL3SA3;
+ break;
+
+ default:
+ printk(KERN_ERR "%s: Unknown chipset %d\n",
+ __FILE__,
+ chipset);
+ chipset = CHIPSET_UNKNOWN;


+ break;
+ }
+ }
+

+ /* Do chipset specific stuff: */
+ switch(chipset)
X {
X case CHIPSET_OPL3SA2:
X printk(KERN_INFO "Found OPL3-SA2 (YMF711)\n");
@@ -521,15 +635,23 @@
X
X default:
X printk(KERN_ERR "No Yamaha audio controller found\n");
- printk(KERN_INFO
- "opl3sa2.c: chipset version = %x\n",
- chipset_version);
- chipset_version = CHIPSET_UNKNOWN;
+
+ /* If we've actually checked the version, print it out */
+ if(version)
+ {
+ printk(KERN_INFO
+ "%s: chipset version = %x\n",
+ __FILE__,
+ version);
+ }
+
+ /* Set some sane values */
+ chipset = CHIPSET_UNKNOWN;
X tag = '?';
X break;
X }
X
- if(chipset_version != CHIPSET_UNKNOWN) {
+ if(chipset != CHIPSET_UNKNOWN) {
X /* Generate a pretty name */
X sprintf(chipset_name, "OPL3-SA%c", tag);
X return 1;
@@ -565,6 +687,7 @@


X int irq = -1;

X int dma = -1;
X int dma2 = -1;
+int force = -1;
X
X MODULE_PARM(io, "i");
X MODULE_PARM_DESC(io, "Set i/o base of OPL3-SA2 or SA3 card (usually 0x370)");
@@ -581,9 +704,12 @@
X MODULE_PARM(dma, "i");
X MODULE_PARM_DESC(dma, "Set MSS (audio) first DMA channel (0, 1, 3)");
X
-MODULE_PARM(dma2,"i");
+MODULE_PARM(dma2, "i");
X MODULE_PARM_DESC(dma2, "Set MSS (audio) second DMA channel (0, 1, 3)");
X
+MODULE_PARM(force, "i");
+MODULE_PARM_DESC(force, "Force audio controller chipset (2, 3)");
+
X MODULE_DESCRIPTION("Module for OPL3-SA2 and SA3 sound cards (uses AD1848 MSS driver).");
X MODULE_AUTHOR("Scott Murray <sco...@interlog.com>");
X
@@ -605,7 +731,8 @@
X
X if(io == -1 || irq == -1 || dma == -1 || dma2 == -1 || mss_io == -1)
X {
- printk(KERN_ERR "opl3sa2.c: io, mss_io, irq, dma, and dma2 must be set.\n");
+ printk(KERN_ERR "%s: io, mss_io, irq, dma, and dma2 must be set.\n",
+ __FILE__);


X return -EINVAL;
X }
X

@@ -614,6 +741,12 @@
X cfg.irq = irq;
X cfg.dma = dma;
X cfg.dma2 = dma2;
+
+ /* Does the user want to override the chipset type? */
+ if(force != -1)
+ cfg.card_subtype = force;
+ else
+ cfg.card_subtype = CHIPSET_UNKNOWN;
X
X /* The MSS config: */
X mss_cfg.io_base = mss_io;
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/pas2_card.c linux/drivers/sound/pas2_card.c
--- v2.2.0-pre4/linux/drivers/sound/pas2_card.c Thu Jul 16 18:09:27 1998
+++ linux/drivers/sound/pas2_card.c Mon Jan 4 11:37:30 1999
@@ -73,12 +73,12 @@
X
X unsigned char pas_read(int ioaddr)
X {
- return inb(ioaddr ^ translate_code);
+ return inb(ioaddr + translate_code);
X }
X
X void pas_write(unsigned char data, int ioaddr)
X {
- outb((data), ioaddr ^ translate_code);
+ outb((data), ioaddr + translate_code);
X }
X
X /******************* Begin of the Interrupt Handler ********************/
@@ -168,7 +168,7 @@
X else
X {
X int_ptrs = pas_read(0xF38A);
- int_ptrs |= irq_bits[pas_irq] & 0xf;
+ int_ptrs = (int_ptrs & 0xf0) | irq_bits[pas_irq];
X pas_write(int_ptrs, 0xF38A);
X if (!irq_bits[pas_irq])
X {


@@ -297,7 +297,7 @@
X

X outb((0xBC), 0x9A01); /* Activate first board */
X outb((hw_config->io_base >> 2), 0x9A01); /* Set base address */
- translate_code = 0x388 ^ hw_config->io_base;
+ translate_code = hw_config->io_base - 0x388;
X pas_write(1, 0xBF88); /* Select one wait states */
X
X board_id = pas_read(0x0B8B);
@@ -347,7 +347,7 @@
X pas_pcm_init(hw_config);
X #endif
X
-#if !defined(DISABLE_SB_EMULATION) && defined(CONFIG_SB)
+#if !defined(MODULE) && !defined(DISABLE_SB_EMULATION) && defined(CONFIG_SB)
X
X sb_dsp_disable_midi(pas_sb_base); /* No MIDI capability */
X #endif
@@ -367,8 +367,18 @@
X
X void unload_pas(struct address_info *hw_config)
X {
+ extern int pas_audiodev;
+ extern int pas2_mididev;
+
X sound_free_dma(hw_config->dma);
X free_irq(hw_config->irq, NULL);
+
+ if(pas_audiodev!=-1)
+ sound_unload_mixerdev(audio_devs[pas_audiodev]->mixer_dev);
+ if(pas2_mididev!=-1)
+ sound_unload_mididev(pas2_mididev);
+ if(pas_audiodev)
+ sound_unload_audiodev(pas_audiodev);
X }
X
X #ifdef MODULE
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/pas2_midi.c linux/drivers/sound/pas2_midi.c
--- v2.2.0-pre4/linux/drivers/sound/pas2_midi.c Thu May 14 19:47:42 1998
+++ linux/drivers/sound/pas2_midi.c Mon Jan 4 11:37:30 1999
@@ -21,14 +21,15 @@
X static int midi_busy = 0, input_opened = 0;
X static int my_dev;
X
+int pas2_mididev;
+
X static unsigned char tmp_queue[256];
X static volatile int qlen;
X static volatile unsigned char qhead, qtail;
X
X static void (*midi_input_intr) (int dev, unsigned char data);
X
-static int
-pas_midi_open(int dev, int mode,
+static int pas_midi_open(int dev, int mode,


X void (*input) (int dev, unsigned char data),
X void (*output) (int dev)
X )

@@ -39,10 +40,8 @@
X
X
X if (midi_busy)
- {
- printk("PAS16: Midi busy\n");
- return -EBUSY;
- }
+ return -EBUSY;
+
X /*
X * Reset input and output FIFO pointers
X */
@@ -53,10 +52,10 @@
X cli();
X
X if ((err = pas_set_intr(0x10)) < 0)
- {
- restore_flags(flags);
- return err;
- }
+ {
+ restore_flags(flags);
+ return err;
+ }
X /*
X * Enable input available and output FIFO empty interrupts
X */
@@ -66,14 +65,14 @@
X midi_input_intr = input;
X
X if (mode == OPEN_READ || mode == OPEN_READWRITE)
- {
- ctrl |= 0x04; /* Enable input */
- input_opened = 1;
- }
+ {
+ ctrl |= 0x04; /* Enable input */
+ input_opened = 1;
+ }
X if (mode == OPEN_WRITE || mode == OPEN_READWRITE)
- {
- ctrl |= 0x08 | 0x10; /* Enable output */
- }
+ {
+ ctrl |= 0x08 | 0x10; /* Enable output */
+ }
X pas_write(ctrl, 0x178b);
X
X /*
@@ -89,8 +88,7 @@


X return 0;
X }
X

-static void
-pas_midi_close(int dev)
+static void pas_midi_close(int dev)
X {
X
X /*
@@ -102,35 +100,32 @@
X midi_busy = 0;
X }
X
-static int
-dump_to_midi(unsigned char midi_byte)
+static int dump_to_midi(unsigned char midi_byte)
X {
- int fifo_space, x;
+ int fifo_space, x;
X
X fifo_space = ((x = pas_read(0x1B89)) >> 4) & 0x0f;
X
-/*
- * The MIDI FIFO space register and it's documentation is nonunderstandable.
- * There seem to be no way to differentiate between buffer full and buffer
- * empty situations. For this reason we don't never write the buffer
- * completely full. In this way we can assume that 0 (or is it 15)
- * means that the buffer is empty.
- */
+ /*
+ * The MIDI FIFO space register and it's documentation is nonunderstandable.
+ * There seem to be no way to differentiate between buffer full and buffer
+ * empty situations. For this reason we don't never write the buffer
+ * completely full. In this way we can assume that 0 (or is it 15)
+ * means that the buffer is empty.
+ */
X
X if (fifo_space < 2 && fifo_space != 0) /* Full (almost) */
- {
- return 0; /* Ask upper layers to retry after some time */
- }
+ return 0; /* Ask upper layers to retry after some time */
+
X pas_write(midi_byte, 0x178A);
X

X return 1;
X }
X

-static int
-pas_midi_out(int dev, unsigned char midi_byte)
+static int pas_midi_out(int dev, unsigned char midi_byte)
X {
X
- unsigned long flags;
+ unsigned long flags;
X
X /*
X * Drain the local queue first
@@ -140,15 +135,15 @@
X cli();
X
X while (qlen && dump_to_midi(tmp_queue[qhead]))
- {
- qlen--;
- qhead++;
- }
+ {
+ qlen--;
+ qhead++;
+ }
X
X restore_flags(flags);
X
X /*
- * Output the byte if the local queue is empty.
+ * Output the byte if the local queue is empty.
X */
X
X if (!qlen)
@@ -156,7 +151,7 @@
X return 1;
X
X /*
- * Put to the local queue
+ * Put to the local queue
X */
X
X if (qlen >= 256)
@@ -174,25 +169,21 @@


X return 1;
X }
X

-static int
-pas_midi_start_read(int dev)
+static int pas_midi_start_read(int dev)


X {
X return 0;
X }

X
-static int
-pas_midi_end_read(int dev)
+static int pas_midi_end_read(int dev)


X {
X return 0;
X }

X
-static void
-pas_midi_kick(int dev)
+static void pas_midi_kick(int dev)


X {
X }
X
-static int

-pas_buffer_status(int dev)
+static int pas_buffer_status(int dev)
X {
X return qlen;
X }
@@ -218,23 +209,22 @@
X NULL
X };
X
-void
-pas_midi_init(void)
+void pas_midi_init(void)
X {
- int dev = sound_alloc_mididev();
+ int dev = sound_alloc_mididev();
X
X if (dev == -1)
- {
- printk(KERN_WARNING "pas_midi_init: Too many midi devices detected\n");
- return;
- }
+ {
+ printk(KERN_WARNING "pas_midi_init: Too many midi devices detected\n");
+ return;
+ }
X std_midi_synth.midi_dev = my_dev = dev;
X midi_devs[dev] = &pas_midi_operations;
+ pas2_mididev = dev;
X sequencer_init();
X }
X
-void
-pas_midi_interrupt(void)
+void pas_midi_interrupt(void)
X {
X unsigned char stat;
X int i, incount;
@@ -243,35 +233,35 @@
X stat = pas_read(0x1B88);
X
X if (stat & 0x04) /* Input data available */
- {
- incount = pas_read(0x1B89) & 0x0f; /* Input FIFO size */
- if (!incount)
- incount = 16;
-
- for (i = 0; i < incount; i++)
- if (input_opened)
- {
- midi_input_intr(my_dev, pas_read(0x178A));
- } else
- pas_read(0x178A); /* Flush */
- }
+ {
+ incount = pas_read(0x1B89) & 0x0f; /* Input FIFO size */
+ if (!incount)
+ incount = 16;
+
+ for (i = 0; i < incount; i++)
+ if (input_opened)
+ {
+ midi_input_intr(my_dev, pas_read(0x178A));
+ } else
+ pas_read(0x178A); /* Flush */
+ }
X if (stat & (0x08 | 0x10))
- {
- save_flags(flags);
- cli();
-
- while (qlen && dump_to_midi(tmp_queue[qhead]))
- {
- qlen--;
- qhead++;
- }
+ {
+ save_flags(flags);
+ cli();
+
+ while (qlen && dump_to_midi(tmp_queue[qhead]))
+ {
+ qlen--;
+ qhead++;
+ }
X
- restore_flags(flags);
- }
+ restore_flags(flags);
+ }
X if (stat & 0x40)
- {
- printk("MIDI output overrun %x,%x\n", pas_read(0x1B89), stat);
- }
+ {
+ printk(KERN_WARNING "MIDI output overrun %x,%x\n", pas_read(0x1B89), stat);
+ }
X pas_write(stat, 0x1B88); /* Acknowledge interrupts */
X }
X
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/sb.h linux/drivers/sound/sb.h
--- v2.2.0-pre4/linux/drivers/sound/sb.h Mon Dec 28 15:00:52 1998
+++ linux/drivers/sound/sb.h Mon Jan 4 11:37:30 1999
@@ -49,6 +49,9 @@
X #define MDL_AEDSP 15 /* Audio Excel DSP 16 */
X
X #define SUBMDL_ES188X 0x10 /* Subtype ES188X for specific handling */
+#define SUBMDL_ES1868 0x11 /* Subtype ES1868 for specific handling */
+#define SUBMDL_ES1869 0x12 /* Subtype ES1869 for specific handling */
+#define SUBMDL_ES1878 0x13 /* Subtype ES1878 for specific handling */
X #define SUBMDL_ALS007 42 /* ALS-007 differs from SB16 only in mixer */
X /* register assignment */
X /*
@@ -144,6 +147,7 @@
X void sb_midi_interrupt (sb_devc *devc);
X int ess_write (sb_devc *devc, unsigned char reg, unsigned char data);
X int ess_read (sb_devc *devc, unsigned char reg);
+void ess_mixer_reload (sb_devc * devc, int dev);
X
X extern int acer;
X extern sb_devc *last_sb;
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/sb_audio.c linux/drivers/sound/sb_audio.c
--- v2.2.0-pre4/linux/drivers/sound/sb_audio.c Tue Dec 22 14:16:56 1998
+++ linux/drivers/sound/sb_audio.c Mon Jan 4 11:37:30 1999
@@ -67,6 +67,7 @@
X devc->fullduplex = devc->duplex &&
X ((mode & OPEN_READ) && (mode & OPEN_WRITE));
X sb_dsp_reset(devc);
+ ess_mixer_reload (devc, SOUND_MIXER_RECLEV);
X
X /* The ALS007 seems to require that the DSP be removed from the output */
X /* in order for recording to be activated properly. This is done by */
@@ -91,8 +92,10 @@
X {
X sb_devc *devc = audio_devs[dev]->devc;
X
- /* if we did dma juggling put the right dmap in the right place */
- if(devc->duplex && audio_devs[dev]->dmap_out->dma != devc->dma8)
+ /* fix things if mmap turned off fullduplex */
+ if(devc->duplex
+ && !devc->fullduplex
+ && (devc->opened & OPEN_READ) && (devc->opened & OPEN_WRITE))
X {
X struct dma_buffparms *dmap_temp;
X dmap_temp = audio_devs[dev]->dmap_out;
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c
--- v2.2.0-pre4/linux/drivers/sound/sb_common.c Mon Dec 28 15:00:52 1998
+++ linux/drivers/sound/sb_common.c Mon Jan 4 11:37:30 1999
@@ -103,6 +103,13 @@
X return 0xffff;
X }
X
+inline void ess_extended (sb_devc * devc)
+{
+ /* Enable extended mode */
+
+ sb_dsp_command(devc, 0xc6);
+}
+
X int ess_write(sb_devc * devc, unsigned char reg, unsigned char data)
X {
X /* Write a byte to an extended mode register of ES1688 */
@@ -225,8 +232,7 @@
X DDB(printk("sb: No response to RESET\n"));
X return 0; /* Sorry */
X }
- if (devc->model == MDL_ESS)
- sb_dsp_command(devc, 0xc6); /* Enable extended mode */
+ if (devc->model == MDL_ESS) ess_extended (devc);
X
X DEB(printk("sb_dsp_reset() OK\n"));
X return 1;
@@ -491,6 +497,8 @@
X * fiddling with the bits in certain mixer registers. ess_probe is supposed
X * to help.
X */
+static unsigned int ess_identify (sb_devc * devc);
+
X static int ess_probe (sb_devc * devc, int reg, int xorval)
X {
X int val1, val2, val3;
@@ -554,18 +562,40 @@
X
X if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80)
X {
- char *chip = "ES688";
+ char *chip = NULL;
+
+ if ((ess_minor & 0x0f) < 8) {
+ chip = "ES688";
+ };
+ if (chip == NULL) {
+ int type, dummy;
+
+ type = ess_identify (devc);
X
- if ((ess_minor & 0x0f) >= 8) {
+ switch (type) {
+ case 0x1868:
+ chip = "ES1868";
+ devc->submodel = SUBMDL_ES1868;
+ break;
+ case 0x1869:
+ chip = "ES1869";
+ devc->submodel = SUBMDL_ES1869;
+ break;
+ case 0x1878:
+ chip = "ES1878";
+ devc->submodel = SUBMDL_ES1878;
+ break;
+ };
+ };
+ if (chip == NULL) {
X if ( !ess_probe (devc, 0x64, (1 << 3))
X && ess_probe (devc, 0x70, 0x7f)) {
X chip = "ES188x";
X devc->submodel = SUBMDL_ES188X;
- } else {
- chip = "ES1688";
X };
- } else {
- chip = "ES688";
+ };
+ if (chip == NULL) {
+ chip = "ES1688";
X };
X
X sprintf(name,"ESS %s AudioDrive (rev %d)",
@@ -750,7 +780,7 @@
X return 0;
X }
X memcpy((char *) detected_devc, (char *) devc, sizeof(sb_devc));
- MDB(printk("SB %d.%d detected OK (%x)\n", devc->major, devc->minor, hw_config->io_base));
+ MDB(printk(KERN_INFO "SB %d.%d detected OK (%x)\n", devc->major, devc->minor, hw_config->io_base));


X return 1;
X }
X

@@ -1048,7 +1078,8 @@
X
X save_flags(flags);
X cli();
- if (devc->model == MDL_ESS && port >= 0xa0 && port <= 0xbf) {
+ if (devc->model == MDL_ESS && port >= 0xa0) {
+ /* ess_extended (devc); */
X ess_write (devc, port, value);
X } else {
X outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
@@ -1071,6 +1102,25 @@
X
X udelay(20);
X val = inb(MIXER_DATA);
+ udelay(20);
+ restore_flags(flags);
+
+ return val;
+}
+
+static unsigned int ess_identify (sb_devc * devc)
+{
+ unsigned int val;
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+ outb(((unsigned char) (0x40 & 0xff)), MIXER_ADDR);
+
+ udelay(20);
+ val = inb(MIXER_DATA) << 8;
+ udelay(20);
+ val |= inb(MIXER_DATA);
X udelay(20);
X restore_flags(flags);
X
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/sb_mixer.c linux/drivers/sound/sb_mixer.c
--- v2.2.0-pre4/linux/drivers/sound/sb_mixer.c Mon Dec 28 15:00:52 1998
+++ linux/drivers/sound/sb_mixer.c Mon Jan 4 11:37:30 1999
@@ -12,8 +12,16 @@
X * for more info.
X *
X *
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * Rolf Fokkens : ES188x recording level support
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ * Rolf Fokkens (Dec 20 1998) : ES188x recording level support on a per
+ * input basis
+ * (Dec 24 1998) : Recognition of ES188x (?), ES1868, ES1869
+ * and ES1878. Could be used for specific
+ * handling in the future. All except ES188x
+ * and ES688 are handled like ES1688
+ * (Dec 27 1998) : RECLEV for all (?) ES1688+ chips, see
+ * ess_mixer_reload for more info. ES188x now
+ * has the "Dec 20" support + RECLEV


X */
X
X /*

@@ -42,14 +50,360 @@
X #include "sb.h"
X #include "sb_mixer.h"
X
+static mixer_tab sbpro_mix = {
+MIX_ENT(SOUND_MIXER_VOLUME, 0x22, 7, 4, 0x22, 3, 4),
+MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_SYNTH, 0x26, 7, 4, 0x26, 3, 4),
+MIX_ENT(SOUND_MIXER_PCM, 0x04, 7, 4, 0x04, 3, 4),
+MIX_ENT(SOUND_MIXER_SPEAKER, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE, 0x2e, 7, 4, 0x2e, 3, 4),
+MIX_ENT(SOUND_MIXER_MIC, 0x0a, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_CD, 0x28, 7, 4, 0x28, 3, 4),
+MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0)
+};
+
+static mixer_tab es688_mix = {
+MIX_ENT(SOUND_MIXER_VOLUME, 0x32, 7, 4, 0x32, 3, 4),
+MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
+MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
+MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
+MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
+MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
+MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
+MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
+};
+
+/*
+ * The ES1688 specifics... hopefully correct...
+ * - 6 bit master volume
+ * - RECLEV control
+ * These may apply to ES688 too. I have no idea.
+ */
+static mixer_tab es1688_mix = {
+MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6),
+MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
+MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
+MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
+MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
+MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
+MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
+MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
+MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
+};
+
+/*
+ * The ES188x specifics.
+ * Note that de master volume unlike ES688 is now controlled by two 6 bit
+ * registers. These seem to work OK on 1868 too, but I have no idea if it's
+ * compatible to 688 or 1688....
+ * Also Note that the recording levels (ES188X_MIXER_REC...) have own
+ * entries as if they were playback devices. They are used internally in the
+ * driver only!
+ */
+static mixer_tab es188x_mix = {
+MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6),
+MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
+MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
+MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
+MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
+MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
+MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
+MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
+MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES188X_MIXER_RECSYNTH, 0x6b, 7, 4, 0x6b, 3, 4),
+MIX_ENT(ES188X_MIXER_RECPCM, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES188X_MIXER_RECSPEAKER,0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES188X_MIXER_RECLINE, 0x6e, 7, 4, 0x6e, 3, 4),
+MIX_ENT(ES188X_MIXER_RECMIC, 0x68, 7, 4, 0x68, 3, 4),
+MIX_ENT(ES188X_MIXER_RECCD, 0x6a, 7, 4, 0x6a, 3, 4),
+MIX_ENT(ES188X_MIXER_RECIMIX, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES188X_MIXER_RECALTPCM, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES188X_MIXER_RECRECLEV, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES188X_MIXER_RECIGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES188X_MIXER_RECOGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES188X_MIXER_RECLINE1, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(ES188X_MIXER_RECLINE2, 0x6c, 7, 4, 0x6c, 3, 4),
+MIX_ENT(ES188X_MIXER_RECLINE3, 0x00, 0, 0, 0x00, 0, 0)
+};
+
+#ifdef __SGNXPRO__
+#if 0
+static mixer_tab sgnxpro_mix = { /* not used anywhere */
+MIX_ENT(SOUND_MIXER_VOLUME, 0x22, 7, 4, 0x22, 3, 4),
+MIX_ENT(SOUND_MIXER_BASS, 0x46, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_TREBLE, 0x44, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_SYNTH, 0x26, 7, 4, 0x26, 3, 4),
+MIX_ENT(SOUND_MIXER_PCM, 0x04, 7, 4, 0x04, 3, 4),
+MIX_ENT(SOUND_MIXER_SPEAKER, 0x42, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE, 0x2e, 7, 4, 0x2e, 3, 4),
+MIX_ENT(SOUND_MIXER_MIC, 0x0a, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_CD, 0x28, 7, 4, 0x28, 3, 4),
+MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0)
+};
+#endif
+#endif
+
+static mixer_tab sb16_mix = {
+MIX_ENT(SOUND_MIXER_VOLUME, 0x30, 7, 5, 0x31, 7, 5),
+MIX_ENT(SOUND_MIXER_BASS, 0x46, 7, 4, 0x47, 7, 4),
+MIX_ENT(SOUND_MIXER_TREBLE, 0x44, 7, 4, 0x45, 7, 4),
+MIX_ENT(SOUND_MIXER_SYNTH, 0x34, 7, 5, 0x35, 7, 5),
+MIX_ENT(SOUND_MIXER_PCM, 0x32, 7, 5, 0x33, 7, 5),
+MIX_ENT(SOUND_MIXER_SPEAKER, 0x3b, 7, 2, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE, 0x38, 7, 5, 0x39, 7, 5),
+MIX_ENT(SOUND_MIXER_MIC, 0x3a, 7, 5, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_CD, 0x36, 7, 5, 0x37, 7, 5),
+MIX_ENT(SOUND_MIXER_IMIX, 0x3c, 0, 1, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_RECLEV, 0x3f, 7, 2, 0x40, 7, 2), /* Obsolete. Use IGAIN */
+MIX_ENT(SOUND_MIXER_IGAIN, 0x3f, 7, 2, 0x40, 7, 2),
+MIX_ENT(SOUND_MIXER_OGAIN, 0x41, 7, 2, 0x42, 7, 2)
+};
+
+static mixer_tab als007_mix =
+{
+MIX_ENT(SOUND_MIXER_VOLUME, 0x62, 7, 4, 0x62, 3, 4),
+MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_SYNTH, 0x66, 7, 4, 0x66, 3, 4),
+MIX_ENT(SOUND_MIXER_PCM, 0x64, 7, 4, 0x64, 3, 4),
+MIX_ENT(SOUND_MIXER_SPEAKER, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE, 0x6e, 7, 4, 0x6e, 3, 4),
+MIX_ENT(SOUND_MIXER_MIC, 0x6a, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_CD, 0x68, 7, 4, 0x68, 3, 4),
+MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0), /* Obsolete. Use IGAIN */
+MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0)
+};
+
+
+/* SM_GAMES Master volume is lower and PCM & FM volumes
+ higher than with SB Pro. This improves the
+ sound quality */
+
+static int smg_default_levels[32] =
+{
+ 0x2020, /* Master Volume */
+ 0x4b4b, /* Bass */
+ 0x4b4b, /* Treble */
+ 0x6464, /* FM */
+ 0x6464, /* PCM */
+ 0x4b4b, /* PC Speaker */
+ 0x4b4b, /* Ext Line */
+ 0x0000, /* Mic */
+ 0x4b4b, /* CD */
+ 0x4b4b, /* Recording monitor */
+ 0x4b4b, /* SB PCM */
+ 0x4b4b, /* Recording level */
+ 0x4b4b, /* Input gain */
+ 0x4b4b, /* Output gain */
+ 0x4040, /* Line1 */
+ 0x4040, /* Line2 */
+ 0x1515 /* Line3 */
+};
+
+static int sb_default_levels[32] =
+{
+ 0x5a5a, /* Master Volume */
+ 0x4b4b, /* Bass */
+ 0x4b4b, /* Treble */
+ 0x4b4b, /* FM */
+ 0x4b4b, /* PCM */
+ 0x4b4b, /* PC Speaker */
+ 0x4b4b, /* Ext Line */
+ 0x1010, /* Mic */
+ 0x4b4b, /* CD */
+ 0x0000, /* Recording monitor */
+ 0x4b4b, /* SB PCM */
+ 0x4b4b, /* Recording level */
+ 0x4b4b, /* Input gain */
+ 0x4b4b, /* Output gain */
+ 0x4040, /* Line1 */
+ 0x4040, /* Line2 */
+ 0x1515 /* Line3 */
+};
+
+static unsigned char sb16_recmasks_L[SOUND_MIXER_NRDEVICES] =
+{
+ 0x00, /* SOUND_MIXER_VOLUME */
+ 0x00, /* SOUND_MIXER_BASS */
+ 0x00, /* SOUND_MIXER_TREBLE */
+ 0x40, /* SOUND_MIXER_SYNTH */
+ 0x00, /* SOUND_MIXER_PCM */
+ 0x00, /* SOUND_MIXER_SPEAKER */
+ 0x10, /* SOUND_MIXER_LINE */
+ 0x01, /* SOUND_MIXER_MIC */
+ 0x04, /* SOUND_MIXER_CD */
+ 0x00, /* SOUND_MIXER_IMIX */
+ 0x00, /* SOUND_MIXER_ALTPCM */
+ 0x00, /* SOUND_MIXER_RECLEV */
+ 0x00, /* SOUND_MIXER_IGAIN */
+ 0x00 /* SOUND_MIXER_OGAIN */
+};
+
+static unsigned char sb16_recmasks_R[SOUND_MIXER_NRDEVICES] =
+{
+ 0x00, /* SOUND_MIXER_VOLUME */
+ 0x00, /* SOUND_MIXER_BASS */
+ 0x00, /* SOUND_MIXER_TREBLE */
+ 0x20, /* SOUND_MIXER_SYNTH */
+ 0x00, /* SOUND_MIXER_PCM */
+ 0x00, /* SOUND_MIXER_SPEAKER */
+ 0x08, /* SOUND_MIXER_LINE */
+ 0x01, /* SOUND_MIXER_MIC */
+ 0x02, /* SOUND_MIXER_CD */
+ 0x00, /* SOUND_MIXER_IMIX */
+ 0x00, /* SOUND_MIXER_ALTPCM */
+ 0x00, /* SOUND_MIXER_RECLEV */
+ 0x00, /* SOUND_MIXER_IGAIN */
+ 0x00 /* SOUND_MIXER_OGAIN */
+};
+
+static char smw_mix_regs[] = /* Left mixer registers */
+{
+ 0x0b, /* SOUND_MIXER_VOLUME */
+ 0x0d, /* SOUND_MIXER_BASS */
+ 0x0d, /* SOUND_MIXER_TREBLE */
+ 0x05, /* SOUND_MIXER_SYNTH */
+ 0x09, /* SOUND_MIXER_PCM */
+ 0x00, /* SOUND_MIXER_SPEAKER */
+ 0x03, /* SOUND_MIXER_LINE */
+ 0x01, /* SOUND_MIXER_MIC */
+ 0x07, /* SOUND_MIXER_CD */
+ 0x00, /* SOUND_MIXER_IMIX */
+ 0x00, /* SOUND_MIXER_ALTPCM */
+ 0x00, /* SOUND_MIXER_RECLEV */
+ 0x00, /* SOUND_MIXER_IGAIN */
+ 0x00, /* SOUND_MIXER_OGAIN */
+ 0x00, /* SOUND_MIXER_LINE1 */
+ 0x00, /* SOUND_MIXER_LINE2 */
+ 0x00 /* SOUND_MIXER_LINE3 */
+};
+
+#define SBPRO_RECORDING_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD)
+
+/* Same as SB Pro, unless I find otherwise */
+#define SGNXPRO_RECORDING_DEVICES SBPRO_RECORDING_DEVICES
+
+#define SBPRO_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE | SOUND_MASK_MIC | \
+ SOUND_MASK_CD | SOUND_MASK_VOLUME)
+
+/* SG NX Pro has treble and bass settings on the mixer. The 'speaker'
+ * channel is the COVOX/DisneySoundSource emulation volume control
+ * on the mixer. It does NOT control speaker volume. Should have own
+ * mask eventually?
+ */
+#define SGNXPRO_MIXER_DEVICES (SBPRO_MIXER_DEVICES|SOUND_MASK_BASS| \
+ SOUND_MASK_TREBLE|SOUND_MASK_SPEAKER )
+
+#define SB16_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | SOUND_MASK_MIC | \
+ SOUND_MASK_CD)
+
+#define SB16_OUTFILTER_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | \
+ SOUND_MASK_CD)
+
+#define ES688_RECORDING_DEVICES SBPRO_RECORDING_DEVICES
+#define ES688_MIXER_DEVICES (SBPRO_MIXER_DEVICES|SOUND_MASK_LINE2|SOUND_MASK_SPEAKER)
+
+#define ES1688_RECORDING_DEVICES ES688_RECORDING_DEVICES
+#define ES1688_MIXER_DEVICES (ES688_MIXER_DEVICES|SOUND_MASK_RECLEV)
+
+#define ES188X_RECORDING_DEVICES (ES1688_RECORDING_DEVICES | SOUND_MASK_LINE2 \
+ |SOUND_MASK_SYNTH)
+#define ES188X_MIXER_DEVICES (ES1688_MIXER_DEVICES)
+
+#define SB16_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
+ SOUND_MASK_CD | \
+ SOUND_MASK_IGAIN | SOUND_MASK_OGAIN | \
+ SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | \
+ SOUND_MASK_IMIX)
+
+/* These are the only devices that are working at the moment. Others could
+ * be added once they are identified and a method is found to control them.
+ */
+#define ALS007_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | \
+ SOUND_MASK_PCM | SOUND_MASK_MIC | \
+ SOUND_MASK_CD | \
+ SOUND_MASK_VOLUME)
+
+/*
+ * Mixer registers of ES188x
+ *
+ * These registers specifically take care of recording levels. To make the
+ * mapping from playback devices to recording devices every recording
+ * devices = playback device + ES188X_MIXER_RECDIFF
+ */
+#define ES188X_MIXER_RECBASE (SOUND_MIXER_LINE3 + 1)
+#define ES188X_MIXER_RECDIFF (ES188X_MIXER_RECBASE - SOUND_MIXER_SYNTH)
+
+#define ES188X_MIXER_RECSYNTH (SOUND_MIXER_SYNTH + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECPCM (SOUND_MIXER_PCM + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECSPEAKER (SOUND_MIXER_SPEAKER + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECLINE (SOUND_MIXER_LINE + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECMIC (SOUND_MIXER_MIC + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECCD (SOUND_MIXER_CD + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECIMIX (SOUND_MIXER_IMIX + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECALTPCM (SOUND_MIXER_ALTPCM + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECRECLEV (SOUND_MIXER_RECLEV + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECIGAIN (SOUND_MIXER_IGAIN + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECOGAIN (SOUND_MIXER_OGAIN + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECLINE1 (SOUND_MIXER_LINE1 + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECLINE2 (SOUND_MIXER_LINE2 + ES188X_MIXER_RECDIFF)
+#define ES188X_MIXER_RECLINE3 (SOUND_MIXER_LINE3 + ES188X_MIXER_RECDIFF)
+
+
X static int sbmixnum = 1;
X
X static void sb_mixer_reset(sb_devc * devc);
X
+inline void sb_mixer_bits
+ (sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val)
+{
+ int value;
+
+ value = sb_getmixer(devc, reg);
+ value = (value & ~mask) | (val & mask);
+ sb_setmixer(devc, reg, value);
+}
+
+
X void sb_mixer_set_stereo(sb_devc * devc, int mode)
X {
- sb_setmixer(devc, OUT_FILTER, ((sb_getmixer(devc, OUT_FILTER) & ~STEREO_DAC)
- | (mode ? STEREO_DAC : MONO_DAC)));
+ sb_mixer_bits(devc, OUT_FILTER, STEREO_DAC, (mode ? STEREO_DAC : MONO_DAC));
X }
X
X static int detect_mixer(sb_devc * devc)
@@ -109,8 +463,6 @@
X val = sb_getmixer(devc, regoffs);
X change_bits(devc, &val, dev, LEFT_CHN, left);
X
- devc->levels[dev] = left | (left << 8);
-
X if ((*devc->iomap)[dev][RIGHT_CHN].regno != regoffs) /*
X * Change register
X */
@@ -133,11 +485,26 @@
X
X sb_setmixer(devc, regoffs, val);
X
- devc->levels[dev] = left | (right << 8);
X return left | (right << 8);
X }
X
X /*
+ * After a sb_dsp_reset extended register 0xb4 (RECLEV) is reset too. After
+ * sb_dsp_reset RECLEV has to be restored. This is where ess_mixer_reload
+ * helps.
+ */
+void ess_mixer_reload (sb_devc * devc, int dev)
+{
+ int left, right, value;
+
+ value = devc->levels[dev];
+ left = value & 0x000000ff;
+ right = (value & 0x0000ff00) >> 8;
+
+ common_mixer_set(devc, dev, left, right);
+}
+
+/*
X * Changing playback levels at ES188x means having to take care of recording
X * levels of recorded inputs (devc->recmask) too!
X */
@@ -191,6 +558,7 @@
X {
X int left = value & 0x000000ff;
X int right = (value & 0x0000ff00) >> 8;
+ int retval;
X
X if (left > 100)
X left = 100;
@@ -205,19 +573,24 @@
X */
X return -EINVAL;
X
- /* Differentiate dependong on the chipsets */
+ /* Differentiate depending on the chipsets */
X switch (devc->model) {
X case MDL_SMW:
- return smw_mixer_set(devc, dev, left, right);
+ retval = smw_mixer_set(devc, dev, left, right);
X break;
X case MDL_ESS:
X if (devc->submodel == SUBMDL_ES188X) {
- return es188x_mixer_set(devc, dev, left, right);
+ retval = es188x_mixer_set(devc, dev, left, right);
+ } else {
+ retval = common_mixer_set(devc, dev, left, right);
X }
X break;
+ default:
+ retval = common_mixer_set(devc, dev, left, right);
X }
+ if (retval >= 0) devc->levels[dev] = retval;
X
- return common_mixer_set(devc, dev, left, right);
+ return retval;
X }
X
X /*
@@ -496,7 +869,7 @@
X static void sb_mixer_reset(sb_devc * devc)
X {
X char name[32];
- int i, regval;
+ int i;
X extern int sm_games;
X
X sprintf(name, "SB_%d", devc->sbmixnum);
@@ -516,12 +889,8 @@
X * Then call set_recmask twice to do extra ES188x initializations
X */
X if (devc->model == MDL_ESS && devc->submodel == SUBMDL_ES188X) {
- regval = sb_getmixer(devc, 0x7a);
- regval = (regval & 0xe7) | 0x08;
- sb_setmixer(devc, 0x7a, regval);
- regval = sb_getmixer(devc, 0x1c);
- regval = (regval & 0xf8) | 0x07;
- sb_setmixer(devc, 0x1c, regval);
+ sb_mixer_bits(devc, 0x7a, 0x18, 0x08);


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre5 failed'
fi

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

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

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to
Archive-name: v2.1/patch-2.2.0-pre5/part04

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


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

if test "$Scheck" != 04; then


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

+ sb_mixer_bits(devc, 0x1c, 0x07, 0x07);
X
X set_recmask(devc, ES188X_RECORDING_DEVICES);
X set_recmask(devc, 0);
@@ -568,11 +937,19 @@
X devc->iomap = &es188x_mix;
X break;
X default:
- devc->supported_devices
- = ES688_MIXER_DEVICES;
- devc->supported_rec_devices
- = ES688_RECORDING_DEVICES;
- devc->iomap = &es688_mix;
+ if (devc->submodel < 8) {
+ devc->supported_devices
+ = ES688_MIXER_DEVICES;
+ devc->supported_rec_devices
+ = ES688_RECORDING_DEVICES;
+ devc->iomap = &es688_mix;
+ } else {
+ devc->supported_devices
+ = ES1688_MIXER_DEVICES;
+ devc->supported_rec_devices
+ = ES1688_RECORDING_DEVICES;
+ devc->iomap = &es1688_mix;
+ }
X }
X
X break;
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/sb_mixer.h linux/drivers/sound/sb_mixer.h
--- v2.2.0-pre4/linux/drivers/sound/sb_mixer.h Mon Dec 28 15:00:52 1998
+++ linux/drivers/sound/sb_mixer.h Mon Jan 4 11:37:30 1999
@@ -17,8 +17,10 @@
X * Added defines for the Sound Galaxy NX Pro mixer.
X *
X * Rolf Fokkens Dec 20 1998
- * Added (BETA?) support for ES188x chips.
- * Which means: you can adjust the recording levels.
+ * Added defines for some ES188x chips.
+ *
+ * Rolf Fokkens Dec 27 1998
+ * Moved static stuff to sb_mixer.c
X *
X */
X #include <linux/config.h>
@@ -51,9 +53,12 @@
X #define ES688_RECORDING_DEVICES SBPRO_RECORDING_DEVICES
X #define ES688_MIXER_DEVICES (SBPRO_MIXER_DEVICES|SOUND_MASK_LINE2|SOUND_MASK_SPEAKER)
X
-#define ES188X_RECORDING_DEVICES (ES688_RECORDING_DEVICES | SOUND_MASK_LINE2 \


+#define ES1688_RECORDING_DEVICES ES688_RECORDING_DEVICES
+#define ES1688_MIXER_DEVICES (ES688_MIXER_DEVICES|SOUND_MASK_RECLEV)
+
+#define ES188X_RECORDING_DEVICES (ES1688_RECORDING_DEVICES | SOUND_MASK_LINE2 \

X |SOUND_MASK_SYNTH)
-#define ES188X_MIXER_DEVICES (ES688_MIXER_DEVICES)
+#define ES188X_MIXER_DEVICES (ES1688_MIXER_DEVICES)
X
X #define SB16_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
X SOUND_MASK_CD | \
@@ -120,7 +125,7 @@
X /*
X * Mixer registers of ES188x
X *
- * These register specifically take care of recording levels. To make the


+ * These registers specifically take care of recording levels. To make the

X * mapping from playback devices to recording devices every recording
X * devices = playback device + ES188X_MIXER_RECDIFF
X */
@@ -152,245 +157,6 @@
X #define MIX_ENT(name, reg_l, bit_l, len_l, reg_r, bit_r, len_r) \
X {{reg_l, bit_l, len_l}, {reg_r, bit_r, len_r}}
X
-#ifdef __SB_MIXER_C__
-static mixer_tab sbpro_mix = {
-MIX_ENT(SOUND_MIXER_VOLUME, 0x22, 7, 4, 0x22, 3, 4),
-MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x26, 7, 4, 0x26, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM, 0x04, 7, 4, 0x04, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x2e, 7, 4, 0x2e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC, 0x0a, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_CD, 0x28, 7, 4, 0x28, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0)
-};
-static mixer_tab es688_mix = {
-MIX_ENT(SOUND_MIXER_VOLUME, 0x32, 7, 4, 0x32, 3, 4),
-MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
-MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
-MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
-};
-
-/*
- * The ES188x specifics.
- * Note that de master volume unlike ES688 is now controlled by two 6 bit
- * registers. These seem to work OK on 1868 too, but I have no idea if it's
- * compatible to 688 or 1688....
- * Also Note that the recording levels (ES188X_MIXER_REC...) have own
- * entries as if they were playback devices. They are used internally in the
- * driver only!
- */
-static mixer_tab es188x_mix = {
-MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6),
-MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
-MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
-MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES188X_MIXER_RECSYNTH, 0x6b, 7, 4, 0x6b, 3, 4),
-MIX_ENT(ES188X_MIXER_RECPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES188X_MIXER_RECSPEAKER,0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES188X_MIXER_RECLINE, 0x6e, 7, 4, 0x6e, 3, 4),
-MIX_ENT(ES188X_MIXER_RECMIC, 0x68, 7, 4, 0x68, 3, 4),
-MIX_ENT(ES188X_MIXER_RECCD, 0x6a, 7, 4, 0x6a, 3, 4),
-
-MIX_ENT(ES188X_MIXER_RECIMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES188X_MIXER_RECALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES188X_MIXER_RECRECLEV, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES188X_MIXER_RECIGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES188X_MIXER_RECOGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES188X_MIXER_RECLINE1, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(ES188X_MIXER_RECLINE2, 0x6c, 7, 4, 0x6c, 3, 4),
-MIX_ENT(ES188X_MIXER_RECLINE3, 0x00, 0, 0, 0x00, 0, 0)
-};
-
-#ifdef __SGNXPRO__
-#if 0
-static mixer_tab sgnxpro_mix = { /* not used anywhere */
-MIX_ENT(SOUND_MIXER_VOLUME, 0x22, 7, 4, 0x22, 3, 4),
-MIX_ENT(SOUND_MIXER_BASS, 0x46, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x44, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x26, 7, 4, 0x26, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM, 0x04, 7, 4, 0x04, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x42, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x2e, 7, 4, 0x2e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC, 0x0a, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_CD, 0x28, 7, 4, 0x28, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0)
-};
-#endif
-#endif
-
-static mixer_tab sb16_mix = {
-MIX_ENT(SOUND_MIXER_VOLUME, 0x30, 7, 5, 0x31, 7, 5),
-MIX_ENT(SOUND_MIXER_BASS, 0x46, 7, 4, 0x47, 7, 4),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x44, 7, 4, 0x45, 7, 4),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x34, 7, 5, 0x35, 7, 5),
-MIX_ENT(SOUND_MIXER_PCM, 0x32, 7, 5, 0x33, 7, 5),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x3b, 7, 2, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x38, 7, 5, 0x39, 7, 5),
-MIX_ENT(SOUND_MIXER_MIC, 0x3a, 7, 5, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_CD, 0x36, 7, 5, 0x37, 7, 5),
-MIX_ENT(SOUND_MIXER_IMIX, 0x3c, 0, 1, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0x3f, 7, 2, 0x40, 7, 2), /* Obsolete. Use IGAIN */
-MIX_ENT(SOUND_MIXER_IGAIN, 0x3f, 7, 2, 0x40, 7, 2),
-MIX_ENT(SOUND_MIXER_OGAIN, 0x41, 7, 2, 0x42, 7, 2)
-};
-
-static mixer_tab als007_mix =
-{
-MIX_ENT(SOUND_MIXER_VOLUME, 0x62, 7, 4, 0x62, 3, 4),
-MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_SYNTH, 0x66, 7, 4, 0x66, 3, 4),
-MIX_ENT(SOUND_MIXER_PCM, 0x64, 7, 4, 0x64, 3, 4),
-MIX_ENT(SOUND_MIXER_SPEAKER, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_LINE, 0x6e, 7, 4, 0x6e, 3, 4),
-MIX_ENT(SOUND_MIXER_MIC, 0x6a, 2, 3, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_CD, 0x68, 7, 4, 0x68, 3, 4),
-MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0), /* Obsolete. Use IGAIN */
-MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
-MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0)
-};
-
-
-/* SM_GAMES Master volume is lower and PCM & FM volumes
- higher than with SB Pro. This improves the
- sound quality */
-
-static int smg_default_levels[32] =
-{
- 0x2020, /* Master Volume */
- 0x4b4b, /* Bass */
- 0x4b4b, /* Treble */
- 0x6464, /* FM */
- 0x6464, /* PCM */
- 0x4b4b, /* PC Speaker */
- 0x4b4b, /* Ext Line */
- 0x0000, /* Mic */
- 0x4b4b, /* CD */
- 0x4b4b, /* Recording monitor */
- 0x4b4b, /* SB PCM */
- 0x4b4b, /* Recording level */
- 0x4b4b, /* Input gain */
- 0x4b4b, /* Output gain */
- 0x4040, /* Line1 */
- 0x4040, /* Line2 */
- 0x1515 /* Line3 */
-};
-
-static int sb_default_levels[32] =
-{
- 0x5a5a, /* Master Volume */
- 0x4b4b, /* Bass */
- 0x4b4b, /* Treble */
- 0x4b4b, /* FM */
- 0x4b4b, /* PCM */
- 0x4b4b, /* PC Speaker */
- 0x4b4b, /* Ext Line */
- 0x1010, /* Mic */
- 0x4b4b, /* CD */
- 0x0000, /* Recording monitor */
- 0x4b4b, /* SB PCM */
- 0x4b4b, /* Recording level */
- 0x4b4b, /* Input gain */
- 0x4b4b, /* Output gain */
- 0x4040, /* Line1 */
- 0x4040, /* Line2 */
- 0x1515 /* Line3 */
-};
-
-static unsigned char sb16_recmasks_L[SOUND_MIXER_NRDEVICES] =
-{
- 0x00, /* SOUND_MIXER_VOLUME */
- 0x00, /* SOUND_MIXER_BASS */
- 0x00, /* SOUND_MIXER_TREBLE */
- 0x40, /* SOUND_MIXER_SYNTH */
- 0x00, /* SOUND_MIXER_PCM */
- 0x00, /* SOUND_MIXER_SPEAKER */
- 0x10, /* SOUND_MIXER_LINE */
- 0x01, /* SOUND_MIXER_MIC */
- 0x04, /* SOUND_MIXER_CD */
- 0x00, /* SOUND_MIXER_IMIX */
- 0x00, /* SOUND_MIXER_ALTPCM */
- 0x00, /* SOUND_MIXER_RECLEV */
- 0x00, /* SOUND_MIXER_IGAIN */
- 0x00 /* SOUND_MIXER_OGAIN */
-};
-
-static unsigned char sb16_recmasks_R[SOUND_MIXER_NRDEVICES] =
-{
- 0x00, /* SOUND_MIXER_VOLUME */
- 0x00, /* SOUND_MIXER_BASS */
- 0x00, /* SOUND_MIXER_TREBLE */
- 0x20, /* SOUND_MIXER_SYNTH */
- 0x00, /* SOUND_MIXER_PCM */
- 0x00, /* SOUND_MIXER_SPEAKER */
- 0x08, /* SOUND_MIXER_LINE */
- 0x01, /* SOUND_MIXER_MIC */
- 0x02, /* SOUND_MIXER_CD */
- 0x00, /* SOUND_MIXER_IMIX */
- 0x00, /* SOUND_MIXER_ALTPCM */
- 0x00, /* SOUND_MIXER_RECLEV */
- 0x00, /* SOUND_MIXER_IGAIN */
- 0x00 /* SOUND_MIXER_OGAIN */
-};
-
-static char smw_mix_regs[] = /* Left mixer registers */
-{
- 0x0b, /* SOUND_MIXER_VOLUME */
- 0x0d, /* SOUND_MIXER_BASS */
- 0x0d, /* SOUND_MIXER_TREBLE */
- 0x05, /* SOUND_MIXER_SYNTH */
- 0x09, /* SOUND_MIXER_PCM */
- 0x00, /* SOUND_MIXER_SPEAKER */
- 0x03, /* SOUND_MIXER_LINE */
- 0x01, /* SOUND_MIXER_MIC */
- 0x07, /* SOUND_MIXER_CD */
- 0x00, /* SOUND_MIXER_IMIX */
- 0x00, /* SOUND_MIXER_ALTPCM */
- 0x00, /* SOUND_MIXER_RECLEV */
- 0x00, /* SOUND_MIXER_IGAIN */
- 0x00, /* SOUND_MIXER_OGAIN */
- 0x00, /* SOUND_MIXER_LINE1 */
- 0x00, /* SOUND_MIXER_LINE2 */
- 0x00 /* SOUND_MIXER_LINE3 */
-};
-
X /*
X * Recording sources (SB Pro)
X */
@@ -408,5 +174,4 @@
X #define ALS007_CD 2
X #define ALS007_SYNTH 7
X
-#endif
X #endif
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c
--- v2.2.0-pre4/linux/drivers/sound/sonicvibes.c Mon Dec 28 15:00:52 1998
+++ linux/drivers/sound/sonicvibes.c Mon Jan 4 11:37:30 1999
@@ -2389,11 +2389,11 @@
X printk(KERN_INFO "sv: found adapter at io %#06x irq %u dmaa %#06x dmac %#06x revision %u\n",
X s->ioenh, s->irq, s->iodmaa, s->iodmac, rdindir(s, SV_CIREVISION));


X /* register devices */

- if ((s->dev_audio = register_sound_dsp(&sv_audio_fops)) < 0)
+ if ((s->dev_audio = register_sound_dsp(&sv_audio_fops, -1)) < 0)
X goto err_dev1;
- if ((s->dev_mixer = register_sound_mixer(&sv_mixer_fops)) < 0)
+ if ((s->dev_mixer = register_sound_mixer(&sv_mixer_fops, -1)) < 0)
X goto err_dev2;
- if ((s->dev_midi = register_sound_midi(&sv_midi_fops)) < 0)
+ if ((s->dev_midi = register_sound_midi(&sv_midi_fops, -1)) < 0)
X goto err_dev3;
X if ((s->dev_dmfm = register_sound_special(&sv_dmfm_fops, 15 /* ?? */)) < 0)
X goto err_dev4;
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/sound_calls.h linux/drivers/sound/sound_calls.h
--- v2.2.0-pre4/linux/drivers/sound/sound_calls.h Tue Dec 22 14:16:56 1998
+++ linux/drivers/sound/sound_calls.h Mon Jan 4 11:37:30 1999
@@ -300,5 +300,5 @@
X void attach_wf_mpu(struct address_info * hw_config);
X int probe_wf_mpu(struct address_info *hw_config);
X void unload_wf_mpu(struct address_info *hw_config);
-int virtual_midi_enable (int mididev, struct address_info *);
-void virtual_midi_disable (int mididev);
+int virtual_midi_enable (void);
+int virtual_midi_disable (void);
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c
--- v2.2.0-pre4/linux/drivers/sound/sound_core.c Sat Sep 5 16:46:41 1998
+++ linux/drivers/sound/sound_core.c Mon Jan 4 11:37:30 1999
@@ -57,24 +57,32 @@
X * join into it. Called with the lock asserted
X */
X
-static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list, struct file_operations *fops, int low, int top)
+static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list, struct file_operations *fops, int index, int low, int top)
X {
X int n=low;
X
- while(n<top)
- {
- /* Found a hole ? */
- if(*list==NULL || (*list)->unit_minor>n)
- break;
- list=&((*list)->next);
- n+=16;
- }
-
- if(n==top)
- {
- return -1;
- }
-
+ if (index < 0) { /* first free */
+ while(n<top)
+ {
+ /* Found a hole ? */
+ if(*list==NULL || (*list)->unit_minor>n)
+ break;
+ list=&((*list)->next);
+ n+=16;
+ }
+
+ if(n>=top)
+ return -ENOMEM;
+ } else {
+ n = low+(index*16);
+ while (*list) {
+ if ((*list)->unit_minor==n)
+ return -EBUSY;
+ if ((*list)->unit_minor>n)
+ break;
+ list=&((*list)->next);
+ }
+ }
X
X /*
X * Fill it in
@@ -127,7 +135,7 @@
X * list. Acquires locks as needed
X */
X
-static int sound_insert_unit(struct sound_unit **list, struct file_operations *fops, int low, int top)
+static int sound_insert_unit(struct sound_unit **list, struct file_operations *fops, int index, int low, int top)
X {
X int r;
X struct sound_unit *s=(struct sound_unit *)kmalloc(sizeof(struct sound_unit), GFP_KERNEL);
@@ -135,7 +143,7 @@
X return -1;
X
X spin_lock(&sound_loader_lock);
- r=__sound_insert_unit(s,list,fops,low,top);
+ r=__sound_insert_unit(s,list,fops,index,low,top);
X spin_unlock(&sound_loader_lock);
X
X if(r==-1)


@@ -181,21 +189,21 @@
X

X int register_sound_special(struct file_operations *fops, int unit)
X {
- return sound_insert_unit(&chains[unit&15], fops, unit, unit+1);
+ return sound_insert_unit(&chains[unit&15], fops, -1, unit, unit+1);
X }
X
X EXPORT_SYMBOL(register_sound_special);
X
-int register_sound_mixer(struct file_operations *fops)
+int register_sound_mixer(struct file_operations *fops, int dev)
X {
- return sound_insert_unit(&chains[0], fops, 0, 128);
+ return sound_insert_unit(&chains[0], fops, dev, 0, 128);
X }
X
X EXPORT_SYMBOL(register_sound_mixer);
X
-int register_sound_midi(struct file_operations *fops)
+int register_sound_midi(struct file_operations *fops, int dev)
X {
- return sound_insert_unit(&chains[2], fops, 2, 130);
+ return sound_insert_unit(&chains[2], fops, dev, 2, 130);
X }
X
X EXPORT_SYMBOL(register_sound_midi);
@@ -205,16 +213,16 @@
X * in open - see below.
X */
X
-int register_sound_dsp(struct file_operations *fops)
+int register_sound_dsp(struct file_operations *fops, int dev)
X {
- return sound_insert_unit(&chains[3], fops, 3, 131);
+ return sound_insert_unit(&chains[3], fops, dev, 3, 131);
X }
X
X EXPORT_SYMBOL(register_sound_dsp);
X
-int register_sound_synth(struct file_operations *fops)
+int register_sound_synth(struct file_operations *fops, int dev)
X {
- return sound_insert_unit(&chains[9], fops, 9, 137);
+ return sound_insert_unit(&chains[9], fops, dev, 9, 137);
X }
X
X EXPORT_SYMBOL(register_sound_synth);
@@ -279,6 +287,20 @@
X NULL
X };
X
+static struct sound_unit *__look_for_unit(int chain, int unit)
+{
+ struct sound_unit *s;
+
+ s=chains[chain];
+ while(s && s->unit_minor <= unit)
+ {
+ if(s->unit_minor==unit)
+ return s;
+ s=s->next;
+ }
+ return NULL;
+}
+
X int soundcore_open(struct inode *inode, struct file *file)
X {
X int chain;
@@ -294,28 +316,48 @@
X }
X
X spin_lock(&sound_loader_lock);
+ s = __look_for_unit(chain, unit);
+#ifdef CONFIG_KMOD
+ if (s == NULL) {
+ char mod[32];
X
- s=chains[chain];
-
- while(s && s->unit_minor <= unit)
- {
- if(s->unit_minor==unit)
- {
- file->f_op=s->unit_fops;
- spin_unlock(&sound_loader_lock);
- if(file->f_op->open)
- return file->f_op->open(inode,file);
- else
- return 0;
- break;
- }
- s=s->next;
+ spin_unlock(&sound_loader_lock);
+ /*
+ * Please, don't change this order or code.
+ * For ALSA slot means soundcard and OSS emulation code
+ * comes as add-on modules which aren't depend on
+ * ALSA toplevel modules for soundcards, thus we need
+ * load them at first. [Jaroslav Kysela <pe...@jcu.cz>]
+ */
+ sprintf(mod, "sound-slot-%i", unit>>4);
+ request_module(mod);
+ sprintf(mod, "sound-service-%i-%i", unit>>4, chain);
+ request_module(mod);
+ spin_lock(&sound_loader_lock);
+ s = __look_for_unit(chain, unit);
+ }
+#endif
+ if (s) {
+ file->f_op=s->unit_fops;
+ spin_unlock(&sound_loader_lock);
+ if(file->f_op->open)
+ return file->f_op->open(inode,file);
+ else
+ return 0;
X }
X spin_unlock(&sound_loader_lock);
X return -ENODEV;


X }
X
X #ifdef MODULE

+
+MODULE_DESCRIPTION("Core sound module");
+MODULE_AUTHOR("Alan Cox");
+
+extern int mod_firmware_load(const char *, char **);
+EXPORT_SYMBOL(mod_firmware_load);
+
+
X void cleanup_module(void)
X {
X /* We have nothing to really do here - we know the lists must be
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/sound_firmware.c linux/drivers/sound/sound_firmware.c
--- v2.2.0-pre4/linux/drivers/sound/sound_firmware.c Tue Jun 9 11:57:30 1998
+++ linux/drivers/sound/sound_firmware.c Mon Jan 4 11:37:30 1999
@@ -58,4 +58,3 @@
X return r;
X }
X
-EXPORT_SYMBOL(mod_firmware_load);
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/sound_syms.c linux/drivers/sound/sound_syms.c
--- v2.2.0-pre4/linux/drivers/sound/sound_syms.c Tue Jun 9 11:57:30 1998
+++ linux/drivers/sound/sound_syms.c Mon Jan 4 11:37:30 1999
@@ -43,6 +43,7 @@
X
X EXPORT_SYMBOL(load_mixer_volumes);
X
+
X EXPORT_SYMBOL(conf_printf);
X EXPORT_SYMBOL(conf_printf2);
X
@@ -54,5 +55,5 @@
X EXPORT_SYMBOL(sound_locker);
X EXPORT_SYMBOL(sound_notifier_chain_register);
X
-MODULE_DESCRIPTION("Sound subsystem");
+MODULE_DESCRIPTION("OSS Sound subsystem");
X MODULE_AUTHOR("Hannu Savolainen, et al.");
diff -u --recursive --new-file v2.2.0-pre4/linux/drivers/sound/wavfront.c linux/drivers/sound/wavfront.c
--- v2.2.0-pre4/linux/drivers/sound/wavfront.c Thu Nov 12 16:21:22 1998
+++ linux/drivers/sound/wavfront.c Mon Jan 4 11:37:30 1999
@@ -22,10 +22,17 @@
X * now, you just get the YSS225 in the same state as Turtle Beach's
X * "SETUPSND.EXE" utility leaves it.
X *
- * The boards' CODEC (a Crystal CS4232) is supported by cs4232.[co],
+ * The boards' DAC/ADC (a Crystal CS4232) is supported by cs4232.[co],
X * This chip also controls the configuration of the card: the wavefront
X * synth is logical unit 4.
X *
+ *
+ * Supported devices:
+ *
+ * /dev/dsp - using cs4232+ad1848 modules, OSS compatible
+ * /dev/midiNN and /dev/midiNN+1 - using wf_midi code, OSS compatible
+ * /dev/synth00 - raw synth interface
+ *
X **********************************************************************
X *
X * Copyright (C) by Paul Barton-Davis 1998
@@ -36,9 +43,9 @@
X * Although the relevant code here is all new, the handling of
X * sample/alias/multi- samples is entirely based on a driver by Matt
X * Martin and Rutger Nijlunsing which demonstrated how to get things
- * to most aspects of this to work correctly. The GUS patch loading
- * code has been almost unaltered by me, except to fit formatting and
- * function names in the rest of the file. Many thanks to them.
+ * to work correctly. The GUS patch loading code has been almost
+ * unaltered by me, except to fit formatting and function names in the
+ * rest of the file. Many thanks to them.
X *
X * Appreciation and thanks to Hannu Savolainen for his early work on the Maui
X * driver, and answering a few questions while this one was developed.
@@ -49,16 +56,23 @@
X * aspects of configuring a WaveFront soundcard, particularly the
X * effects processor.
X *
- * $Id: wavfront.c,v 0.5 1998/07/22 16:16:41 pbd Exp $
+ * $Id: wavfront.c,v 0.7 1998/09/09 15:47:36 pbd Exp $
X *
X * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
X * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
+ * for more info. */
X
-#include <linux/config.h>
X #include <linux/module.h>
-#include <asm/init.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/fcntl.h>
+#include <linux/ioport.h>
+
+#include <linux/interrupt.h>
+#include <linux/config.h>
+#include <linux/init.h>
X

X #include "sound_config.h"
X #include "soundmodule.h"

@@ -69,7 +83,33 @@
X #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
X #include "midi_synth.h"
X
-/* This thing is meant to work as a module */
+/* Compile-time control of the extent to which OSS is supported.
+
+ I consider /dev/sequencer to be an anachronism, but given its
+ widespread usage by various Linux MIDI software, it seems worth
+ offering support to it if its not too painful. Instead of using
+ /dev/sequencer, I recommend:
+
+ for synth programming and patch loading: /dev/synthNN
+ for kernel-synchronized MIDI sequencing: the ALSA sequencer
+ for direct MIDI control: /dev/midiNN
+
+ I have never tried static compilation into the kernel. The #if's
+ for this are really just notes to myself about what the code is
+ for.
+*/
+
+#define OSS_SUPPORT_SEQ 0x1 /* use of /dev/sequencer */
+#define OSS_SUPPORT_STATIC_INSTALL 0x2 /* static compilation into kernel */
+
+#define OSS_SUPPORT_LEVEL 0x1 /* just /dev/sequencer for now */


+
+#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ

+static int (*midi_load_patch) (int devno, int format, const char *addr,
+ int offs, int count, int pmgr_flag) = NULL;
+#endif OSS_SUPPORT_SEQ
+
+/* This is meant to work as a module */
X
X #if defined(CONFIG_SOUND_WAVEFRONT_MODULE) && defined(MODULE)
X
@@ -81,14 +121,28 @@
X
X #define WF_DEBUG 1
X
+#ifdef WF_DEBUG
+
+/* Thank goodness for gcc's preprocessor ... */
+
+#define DPRINT(cond, format, args...) \
+ if ((dev.debug & (cond)) == (cond)) { \
+ printk (KERN_DEBUG LOGNAME format, ## args); \
+ }
+#else
+#define DPRINT(cond, format, args...)
+#endif
+
+#define LOGNAME "WaveFront: "
+
X /* bitmasks for WaveFront status port value */
X
-#define STAT_INTR_WRITE 0x40
-#define STAT_CAN_WRITE 0x20
-#define STAT_WINTR_ENABLED 0x10
-#define STAT_INTR_READ 0x04
-#define STAT_CAN_READ 0x02
X #define STAT_RINTR_ENABLED 0x01
+#define STAT_CAN_READ 0x02
+#define STAT_INTR_READ 0x04
+#define STAT_WINTR_ENABLED 0x10
+#define STAT_CAN_WRITE 0x20
+#define STAT_INTR_WRITE 0x40
X
X /*** Module-accessible parameters ***************************************/
X
@@ -117,9 +171,6 @@
X version of the WaveFront OS
X */
X
-int sleep_interval = 100; /* HZ/sleep_interval seconds per sleep */
-int sleep_tries = 50; /* number of times we'll try to sleep */
-
X int wait_usecs = 150; /* This magic number seems to give pretty optimal
X throughput based on my limited experimentation.
X If you want to play around with it and find a better
@@ -133,24 +184,40 @@
X status waits, only about 250 result in a sleep.
X */
X
+int sleep_interval = 100; /* HZ/sleep_interval seconds per sleep */
+int sleep_tries = 50; /* number of times we'll try to sleep */
+
+int reset_time = 2; /* hundreths of a second we wait after a HW reset for
+ the expected interrupt.
+ */
+
+int ramcheck_time = 20; /* time in seconds to wait while ROM code
+ checks on-board RAM.
+ */
+
+int osrun_time = 10; /* time in seconds we wait for the OS to
+ start running.
+ */
+
X MODULE_PARM(wf_raw,"i");
X MODULE_PARM(fx_raw,"i");
X MODULE_PARM(debug_default,"i");
+MODULE_PARM(wait_usecs,"i");
X MODULE_PARM(sleep_interval,"i");
X MODULE_PARM(sleep_tries,"i");
-MODULE_PARM(wait_usecs,"i");
X MODULE_PARM(ospath,"s");
+MODULE_PARM(reset_time,"i");
+MODULE_PARM(ramcheck_time,"i");
+MODULE_PARM(osrun_time,"i");
X
X /***************************************************************************/
X
-static struct synth_info wavefront_info =
-{"Turtle Beach WaveFront", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_WAVEFRONT,
- 0, 32, 0, 0, SYNTH_CAP_INPUT};
-
-static int (*midi_load_patch) (int dev, int format, const char *addr,
- int offs, int count, int pmgr_flag) = NULL;
+/* Note: because this module doesn't export any symbols, this really isn't
+ a global variable, even if it looks like one. I was quite confused by
+ this when I started writing this as a (newer) module -- pbd.
+*/
X
-typedef struct wf_config {
+struct wf_config {
X int devno; /* device number from kernel */
X int irq; /* "you were one, one of the few ..." */
X int base; /* low i/o port address */
@@ -181,15 +248,23 @@
X #define fx_mod_data base + 0xf
X
X volatile int irq_ok; /* set by interrupt handler */
- int opened; /* flag, holds open(1) mode */
+ volatile int irq_cnt; /* ditto */
+ int opened; /* flag, holds open(2) mode */
X char debug; /* debugging flags */
X int freemem; /* installed RAM, in bytes */
- int synthdev; /* OSS minor devnum for synth */
- int mididev; /* OSS minor devno for internal MIDI */
- int ext_mididev; /* OSS minor devno for external MIDI */
+
+ int synth_dev; /* devno for "raw" synth */
+ int mididev; /* devno for internal MIDI */
+ int ext_mididev; /* devno for external MIDI */
+ int fx_mididev; /* devno for FX MIDI interface */
+#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
+ int oss_dev; /* devno for OSS sequencer synth */
+#endif OSS_SUPPORT_SEQ
+
X char fw_version[2]; /* major = [0], minor = [1] */
X char hw_version[2]; /* major = [0], minor = [1] */
X char israw; /* needs Motorola microcode */
+ char has_fx; /* has FX processor (Tropez+) */
X char prog_status[WF_MAX_PROGRAM]; /* WF_SLOT_* */
X char patch_status[WF_MAX_PATCH]; /* WF_SLOT_* */
X char sample_status[WF_MAX_SAMPLE]; /* WF_ST_* | WF_SLOT_* */
@@ -197,27 +272,22 @@
X char interrupts_on; /* h/w MPU interrupts enabled ? */
X char rom_samples_rdonly; /* can we write on ROM samples */
X struct wait_queue *interrupt_sleeper;
-#ifdef WF_STATS
- unsigned long status_found_during_loop;
- unsigned long status_found_during_sleep[4];
-#endif WF_STATS
+} dev;
X
-} wf_config;
-
-/* Note: because this module doesn't export any symbols, this really isn't
- a global variable, even if it looks like one. I was quite confused by
- this when I started writing this as a (newer) module -- pbd.
-*/
-
-static wf_config wavefront_configuration;
-
-#define wavefront_status(hw) (inb (hw->status_port))
-
-/* forward references */
-
-static int wffx_ioctl (struct wf_config *, wavefront_fx_info *);
-static int wffx_init (struct wf_config *hw);
-static int wavefront_delete_sample (struct wf_config *hw, int sampnum);
+static int detect_wffx(void);
+static int wffx_ioctl (wavefront_fx_info *);
+static int wffx_init (void);
+
+static int wavefront_delete_sample (int sampnum);
+static int wavefront_find_free_sample (void);
+
+/* From wf_midi.c */
+
+extern int virtual_midi_enable (void);
+extern int virtual_midi_disable (void);
+extern int detect_wf_mpu (int, int);
+extern int install_wf_mpu (void);
+extern int uninstall_wf_mpu (void);
X
X typedef struct {
X int cmd;
@@ -339,92 +409,92 @@
X return (wavefront_command *) 0;
X }
X
+static inline int
+wavefront_status (void)
+
+{
+ return inb (dev.status_port);


+}
+
X static int

-wavefront_sleep (wf_config *hw, int limit)
+wavefront_sleep (int limit)
X
X {
X current->state = TASK_INTERRUPTIBLE;
X schedule_timeout(limit);
+
X return signal_pending(current);
X }
-
+
X static int
-wavefront_wait (wf_config *hw, int mask)
+wavefront_wait (int mask)


X
X {
X int i;

X static int short_loop_cnt = 0;
X
+ /* Compute the loop count that lets us sleep for about the
+ right amount of time, cache issues, bus speeds and all
+ other issues being unequal but largely irrelevant.
+ */
+
X if (short_loop_cnt == 0) {
- short_loop_cnt = (int) (((double) wait_usecs / 1000000.0) *
- (double) current_cpu_data.loops_per_sec);
+ short_loop_cnt = wait_usecs *
+ (current_cpu_data.loops_per_sec / 1000000);
X }
X
+ /* Spin for a short period of time, because >99% of all
+ requests to the WaveFront can be serviced inline like this.
+ */
+
X for (i = 0; i < short_loop_cnt; i++) {
- if (wavefront_status(hw) & mask) {
-#ifdef WF_STATS
- hw->status_found_during_loop++;
-#endif WF_STATS
+ if (wavefront_status() & mask) {


X return 1;
X }
X }

X
X for (i = 0; i < sleep_tries; i++) {
X
- if (wavefront_status(hw) & mask) {
-#ifdef WF_STATS
- if (i < 4) {
- hw->status_found_during_sleep[i]++;
- }
-#endif WF_STATS
+ if (wavefront_status() & mask) {


X return 1;
X }
X

- if (wavefront_sleep (hw, HZ/sleep_interval)) {
+ if (wavefront_sleep (HZ/sleep_interval)) {


X return (0);
X }
X }
X

- return 0;
+ return (0);


X }
X
X static int

-wavefront_read (wf_config *hw)
+wavefront_read (void)
+


X {
- if (wavefront_wait (hw, STAT_CAN_READ))

- return inb (hw->data_port);
+ if (wavefront_wait (STAT_CAN_READ))
+ return inb (dev.data_port);
X
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_DATA) {
- printk (KERN_DEBUG "WaveFront: read timeout.\n");
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_DATA, "read timeout.\n");
X
X return -1;


X }
X
X static int

-wavefront_write (wf_config *hw, unsigned char data)
+wavefront_write (unsigned char data)
X
X {
- if (wavefront_wait (hw, STAT_CAN_WRITE)) {
- outb (data, hw->data_port);
- return 1;
+ if (wavefront_wait (STAT_CAN_WRITE)) {
+ outb (data, dev.data_port);


+ return 0;
X }
X

-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_DATA) {
- printk (KERN_DEBUG "WaveFront: write timeout.\n");
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_DATA, "write timeout.\n");
X
- return 0;
+ return -1;


X }
X
X static int

-wavefront_cmd (wf_config *hw, int cmd,
- unsigned char *rbuf,
- unsigned char *wbuf)
+wavefront_cmd (int cmd, unsigned char *rbuf, unsigned char *wbuf)
X
X {
X int ack;
@@ -433,7 +503,7 @@
X wavefront_command *wfcmd;
X
X if ((wfcmd = wavefront_get_command (cmd)) == (wavefront_command *) 0) {
- printk (KERN_WARNING "WaveFront: command 0x%x not supported.\n",
+ printk (KERN_WARNING LOGNAME "command 0x%x not supported.\n",
X cmd);
X return 1;
X }
@@ -448,89 +518,59 @@
X rbuf = 0;
X }


X
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_CMD) {

- printk (KERN_DEBUG "Wavefront: 0x%x [%s] (%d,%d,%d)\n",
- cmd, wfcmd->action, wfcmd->read_cnt, wfcmd->write_cnt,
- wfcmd->need_ack);
- }
-#endif WF_DEBUG
-
- if (!wavefront_write (hw, cmd)) {
-#ifdef WF_DEBUG
- if (hw->debug & (WF_DEBUG_IO|WF_DEBUG_CMD)) {
- printk (KERN_DEBUG "WaveFront: cannot request "
- "0x%x [%s].\n",
- cmd, wfcmd->action);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_CMD, "0x%x [%s] (%d,%d,%d)\n",
+ cmd, wfcmd->action, wfcmd->read_cnt,
+ wfcmd->write_cnt, wfcmd->need_ack);
+
+ if (wavefront_write (cmd)) {
+ DPRINT ((WF_DEBUG_IO|WF_DEBUG_CMD), "cannot request "
+ "0x%x [%s].\n",
+ cmd, wfcmd->action);


X return 1;
X }
X

X if (wfcmd->write_cnt > 0) {
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_DATA) {
- printk (KERN_DEBUG "WaveFront: writing %d bytes "
- "for 0x%x\n",
- wfcmd->write_cnt, cmd);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_DATA, "writing %d bytes "
+ "for 0x%x\n",
+ wfcmd->write_cnt, cmd);
X
X for (i = 0; i < wfcmd->write_cnt; i++) {
- if (!wavefront_write (hw, wbuf[i])) {


-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_IO) {
- printk (KERN_DEBUG

- "WaveFront: bad write for byte %d of 0x%x [%s].\n",
- i, cmd, wfcmd->action);
- }
-#endif WF_DEBUG
+ if (wavefront_write (wbuf[i])) {
+ DPRINT (WF_DEBUG_IO, "bad write for byte "
+ "%d of 0x%x [%s].\n",
+ i, cmd, wfcmd->action);
X return 1;
X }
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_DATA) {
- printk (KERN_DEBUG
- "WaveFront: write[%d] = 0x%x\n",
- i, wbuf[i]);
-#endif WF_DEBUG
- }
+
+ DPRINT (WF_DEBUG_DATA, "write[%d] = 0x%x\n",
+ i, wbuf[i]);
X }
X }
X
X if (wfcmd->read_cnt > 0) {
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_DATA) {
- printk (KERN_DEBUG "WaveFront: reading %d ints "
- "for 0x%x\n",
- wfcmd->read_cnt, cmd);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_DATA, "reading %d ints "
+ "for 0x%x\n",
+ wfcmd->read_cnt, cmd);
X
X for (i = 0; i < wfcmd->read_cnt; i++) {
X
- if ((c = wavefront_read(hw)) == -1) {


-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_IO) {
- printk (KERN_DEBUG

- "WaveFront: bad read for byte %d of 0x%x [%s].\n",
- i, cmd, wfcmd->action);
- }
-#endif WF_DEBUG
+ if ((c = wavefront_read()) == -1) {
+ DPRINT (WF_DEBUG_IO, "bad read for byte "
+ "%d of 0x%x [%s].\n",
+ i, cmd, wfcmd->action);


X return 1;
X }
X

X /* Now handle errors. Lots of special cases here */
X
X if (c == 0xff) {
- if ((c = wavefront_read (hw)) == -1) {


-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_IO) {
- printk (KERN_DEBUG

- "WaveFront: bad read for error byte at "
- "read byte %d of 0x%x [%s].\n",
- i, cmd, wfcmd->action);
- }
-#endif WF_DEBUG
+ if ((c = wavefront_read ()) == -1) {
+ DPRINT (WF_DEBUG_IO, "bad read for "
+ "error byte at "
+ "read byte %d "
+ "of 0x%x [%s].\n",
+ i, cmd,
+ wfcmd->action);


X return 1;
X }
X

@@ -553,60 +593,44 @@
X
X } else {
X
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_IO) {
- printk (KERN_DEBUG
- "WaveFront: error %d (%s) during "
- "read for byte "
- "%d of 0x%x [%s].\n",
- c,
- wavefront_errorstr (c),
- i, cmd, wfcmd->action);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_IO, "error %d (%s) "
+ "during "
+ "read for byte "
+ "%d of 0x%x "
+ "[%s].\n",
+ c,
+ wavefront_errorstr (c),
+ i, cmd,
+ wfcmd->action);


X return 1;
X
X }

- } else {
+
+ } else {
X rbuf[i] = c;
X }
-
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_DATA) {
- printk (KERN_DEBUG
- "WaveFront: read[%d] = 0x%x\n",
- i, rbuf[i]);
- }
-#endif WF_DEBUG
+
+ DPRINT (WF_DEBUG_DATA, "read[%d] = 0x%x\n",i, rbuf[i]);
X }
X }
-
+
X if ((wfcmd->read_cnt == 0 && wfcmd->write_cnt == 0) || wfcmd->need_ack) {


X
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_CMD) {

- printk (KERN_DEBUG "WaveFront: reading ACK for 0x%x\n",
- cmd);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_CMD, "reading ACK for 0x%x\n", cmd);
X
X /* Some commands need an ACK, but return zero instead
X of the standard value.
X */
X
- if ((ack = wavefront_read(hw)) == 0) {
+ if ((ack = wavefront_read()) == 0) {
X ack = WF_ACK;
X }
X
X if (ack != WF_ACK) {
X if (ack == -1) {


-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_IO) {
- printk (KERN_DEBUG

- "WaveFront: cannot read ack for 0x%x [%s].\n",
- cmd, wfcmd->action);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_IO, "cannot read ack for "
+ "0x%x [%s].\n",
+ cmd, wfcmd->action);
X return 1;
X
X } else {
@@ -614,47 +638,32 @@
X
X if (ack == 0xff) { /* explicit error */
X
- if ((err = wavefront_read (hw)) == -1) {
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_DATA) {
- printk (KERN_DEBUG
- "WaveFront: cannot read err for 0x%x [%s].\n",
- cmd, wfcmd->action);
- }
-#endif WF_DEBUG
+ if ((err = wavefront_read ()) == -1) {
+ DPRINT (WF_DEBUG_DATA,
+ "cannot read err "
+ "for 0x%x [%s].\n",
+ cmd, wfcmd->action);
X }
X }
-
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_IO) {
- printk (KERN_DEBUG
- "WaveFront: 0x%x [%s] "
- "failed (0x%x, 0x%x, %s)\n",
- cmd, wfcmd->action, ack, err,
- wavefront_errorstr (err));
- }
-#endif WF_DEBUG
+
+ DPRINT (WF_DEBUG_IO, "0x%x [%s] "
+ "failed (0x%x, 0x%x, %s)\n",
+ cmd, wfcmd->action, ack, err,
+ wavefront_errorstr (err));
+
X return -err;
- }
- }
-
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_DATA) {
- printk (KERN_DEBUG "WaveFront: ack received "
- "for 0x%x [%s]\n",
- cmd, wfcmd->action);
+ }
X }
-#endif WF_DEBUG
+
+ DPRINT (WF_DEBUG_DATA, "ack received "
+ "for 0x%x [%s]\n",
+ cmd, wfcmd->action);
X } else {
-#ifdef WF_DEBUG


- if (hw->debug & WF_DEBUG_CMD) {
- printk (KERN_DEBUG

- "Wavefront: 0x%x [%s] does not need "
- "ACK (%d,%d,%d)\n",
- cmd, wfcmd->action, wfcmd->read_cnt,
- wfcmd->write_cnt, wfcmd->need_ack);
-#endif WF_DEBUG
- }
+
+ DPRINT (WF_DEBUG_CMD, "0x%x [%s] does not need "
+ "ACK (%d,%d,%d)\n",
+ cmd, wfcmd->action, wfcmd->read_cnt,
+ wfcmd->write_cnt, wfcmd->need_ack);
X }
X
X return 0;
@@ -749,7 +758,7 @@
X ***********************************************************************/
X
X static int
-wavefront_delete_sample (wf_config *hw, int sample_num)
+wavefront_delete_sample (int sample_num)
X
X {
X unsigned char wbuf[2];
@@ -758,15 +767,15 @@
X wbuf[0] = sample_num & 0x7f;
X wbuf[1] = sample_num >> 7;
X
- if ((x = wavefront_cmd (hw, WFC_DELETE_SAMPLE, 0, wbuf)) == 0) {
- hw->sample_status[sample_num] = WF_ST_EMPTY;
+ if ((x = wavefront_cmd (WFC_DELETE_SAMPLE, 0, wbuf)) == 0) {
+ dev.sample_status[sample_num] = WF_ST_EMPTY;
X }
X
X return x;


X }
X
X static int

-wavefront_get_sample_status (struct wf_config *hw, int assume_rom)
+wavefront_get_sample_status (int assume_rom)


X
X {
X int i;

@@ -775,29 +784,30 @@
X
X /* check sample status */
X
- if (wavefront_cmd (hw, WFC_GET_NSAMPLES, rbuf, wbuf)) {
- printk ("WaveFront: cannot request sample count.\n");
+ if (wavefront_cmd (WFC_GET_NSAMPLES, rbuf, wbuf)) {
+ printk (KERN_WARNING LOGNAME "cannot request sample count.\n");
+ return -1;
X }
X
- sc_real = sc_alias = sc_multi = hw->samples_used = 0;
+ sc_real = sc_alias = sc_multi = dev.samples_used = 0;
X
X for (i = 0; i < WF_MAX_SAMPLE; i++) {
X
X wbuf[0] = i & 0x7f;
X wbuf[1] = i >> 7;
X
- if (wavefront_cmd (hw, WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) {
- printk (KERN_WARNING
- "WaveFront: cannot identify sample "
+ if (wavefront_cmd (WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) {
+ printk (KERN_WARNING LOGNAME
+ "cannot identify sample "
X "type of slot %d\n", i);
- hw->sample_status[i] = WF_ST_EMPTY;
+ dev.sample_status[i] = WF_ST_EMPTY;
X continue;
X }
X
- hw->sample_status[i] = (WF_SLOT_FILLED|rbuf[0]);
+ dev.sample_status[i] = (WF_SLOT_FILLED|rbuf[0]);
X
X if (assume_rom) {
- hw->sample_status[i] |= WF_SLOT_ROM;
+ dev.sample_status[i] |= WF_SLOT_ROM;
X }
X
X switch (rbuf[0] & WF_ST_MASK) {
@@ -814,21 +824,20 @@


X break;
X
X default:
- printk (KERN_WARNING

- "WaveFront: unknown sample type for "
+ printk (KERN_WARNING LOGNAME "unknown sample type for "
X "slot %d (0x%x)\n",
X i, rbuf[0]);
X }
X
X if (rbuf[0] != WF_ST_EMPTY) {
- hw->samples_used++;
+ dev.samples_used++;
X }

X }
X
- printk (KERN_INFO

- "WaveFront: %d samples used (%d real, %d aliases, %d multi), "
- "%d empty\n", hw->samples_used, sc_real, sc_alias, sc_multi,
- WF_MAX_SAMPLE - hw->samples_used);
+ printk (KERN_INFO LOGNAME
+ "%d samples used (%d real, %d aliases, %d multi), "
+ "%d empty\n", dev.samples_used, sc_real, sc_alias, sc_multi,
+ WF_MAX_SAMPLE - dev.samples_used);


X
X
X return (0);

@@ -836,7 +845,8 @@


X }
X
X static int

-wavefront_get_patch_status (struct wf_config *hw)
+wavefront_get_patch_status (void)
+
X {
X unsigned char patchbuf[WF_PATCH_BYTES];
X unsigned char patchnum[2];
@@ -847,21 +857,21 @@
X patchnum[0] = i & 0x7f;
X patchnum[1] = i >> 7;
X
- if ((x = wavefront_cmd (hw, WFC_UPLOAD_PATCH, patchbuf,
+ if ((x = wavefront_cmd (WFC_UPLOAD_PATCH, patchbuf,
X patchnum)) == 0) {
X
- hw->patch_status[i] |= WF_SLOT_FILLED;
+ dev.patch_status[i] |= WF_SLOT_FILLED;
X p = (wavefront_patch *) patchbuf;
- hw->sample_status
+ dev.sample_status
X [p->sample_number|(p->sample_msb<<7)] |=
X WF_SLOT_USED;
X
X } else if (x == 3) { /* Bad patch number */
- hw->patch_status[i] = 0;
+ dev.patch_status[i] = 0;
X } else {
- printk (KERN_ERR "WaveFront: upload patch "
+ printk (KERN_ERR LOGNAME "upload patch "
X "error 0x%x\n", x);
- hw->patch_status[i] = 0;
+ dev.patch_status[i] = 0;


X return 1;
X }
X }

@@ -869,22 +879,23 @@
X /* program status has already filled in slot_used bits */
X
X for (i = 0, cnt = 0, cnt2 = 0; i < WF_MAX_PATCH; i++) {
- if (hw->patch_status[i] & WF_SLOT_FILLED) {
+ if (dev.patch_status[i] & WF_SLOT_FILLED) {
X cnt++;
X }
- if (hw->patch_status[i] & WF_SLOT_USED) {
+ if (dev.patch_status[i] & WF_SLOT_USED) {
X cnt2++;
X }


X
X }
- printk (KERN_INFO

- "WaveFront: %d patch slots filled, %d in use\n", cnt, cnt2);
+ printk (KERN_INFO LOGNAME
+ "%d patch slots filled, %d in use\n", cnt, cnt2);
X
X return (0);


X }
X
X static int

-wavefront_get_program_status (struct wf_config *hw)
+wavefront_get_program_status (void)
+
X {
X unsigned char progbuf[WF_PROGRAM_BYTES];
X wavefront_program prog;
@@ -894,64 +905,59 @@
X for (i = 0; i < WF_MAX_PROGRAM; i++) {
X prognum = i;
X
- if ((x = wavefront_cmd (hw, WFC_UPLOAD_PROGRAM, progbuf,
+ if ((x = wavefront_cmd (WFC_UPLOAD_PROGRAM, progbuf,
X &prognum)) == 0) {
X
- hw->prog_status[i] |= WF_SLOT_USED;
+ dev.prog_status[i] |= WF_SLOT_USED;
X
X demunge_buf (progbuf, (unsigned char *) &prog,
X WF_PROGRAM_BYTES);
X
X for (l = 0; l < WF_NUM_LAYERS; l++) {
X if (prog.layer[l].mute) {
- hw->patch_status
+ dev.patch_status
X [prog.layer[l].patch_number] |=
X WF_SLOT_USED;
X }
X }
X } else if (x == 1) { /* Bad program number */
- hw->prog_status[i] = 0;
+ dev.prog_status[i] = 0;
X } else {
- printk (KERN_ERR "WaveFront: upload program "
+ printk (KERN_ERR LOGNAME "upload program "
X "error 0x%x\n", x);
- hw->prog_status[i] = 0;
+ dev.prog_status[i] = 0;
X }
X }
X
X for (i = 0, cnt = 0; i < WF_MAX_PROGRAM; i++) {
- if (hw->prog_status[i]) {
+ if (dev.prog_status[i]) {
X cnt++;
X }
X }
X
- printk (KERN_INFO "WaveFront: %d programs slots in use\n", cnt);
+ printk (KERN_INFO LOGNAME "%d programs slots in use\n", cnt);
X
X return (0);


X }
X
X static int

-wavefront_send_patch (wf_config *hw,
- wavefront_patch_info *header)
+wavefront_send_patch (wavefront_patch_info *header)
X
X {
X unsigned char buf[WF_PATCH_BYTES+2];
X unsigned char *bptr;


X
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_LOAD_PATCH) {

- printk (KERN_DEBUG "WaveFront: downloading patch %d\n",
- header->number);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_LOAD_PATCH, "downloading patch %d\n",
+ header->number);
X
- hw->patch_status[header->number] |= WF_SLOT_FILLED;
+ dev.patch_status[header->number] |= WF_SLOT_FILLED;
X
X bptr = buf;
X bptr = munge_int32 (header->number, buf, 2);
X munge_buf ((unsigned char *)&header->hdr.p, bptr, WF_PATCH_BYTES);
X
- if (wavefront_cmd (hw, WFC_DOWNLOAD_PATCH, 0, buf)) {
- printk (KERN_ERR "WaveFront: download patch failed\n");
+ if (wavefront_cmd (WFC_DOWNLOAD_PATCH, 0, buf)) {
+ printk (KERN_ERR LOGNAME "download patch failed\n");
X return -(EIO);
X }
X
@@ -959,21 +965,16 @@


X }
X
X static int

-wavefront_send_program (wf_config *hw,
- wavefront_patch_info *header)
+wavefront_send_program (wavefront_patch_info *header)
X
X {
X unsigned char buf[WF_PROGRAM_BYTES+1];


X int i;
X
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_LOAD_PATCH) {
- printk (KERN_DEBUG

- "WaveFront: downloading program %d\n", header->number);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_LOAD_PATCH, "downloading program %d\n",
+ header->number);
X
- hw->prog_status[header->number] = WF_SLOT_USED;
+ dev.prog_status[header->number] = WF_SLOT_USED;
X
X /* XXX need to zero existing SLOT_USED bit for program_status[i]
X where `i' is the program that's being (potentially) overwritten.
@@ -981,7 +982,7 @@
X
X for (i = 0; i < WF_NUM_LAYERS; i++) {
X if (header->hdr.pr.layer[i].mute) {
- hw->patch_status[header->hdr.pr.layer[i].patch_number] |=
+ dev.patch_status[header->hdr.pr.layer[i].patch_number] |=
X WF_SLOT_USED;
X
X /* XXX need to mark SLOT_USED for sample used by
@@ -993,8 +994,8 @@
X buf[0] = header->number;
X munge_buf ((unsigned char *)&header->hdr.pr, &buf[1], WF_PROGRAM_BYTES);
X
- if (wavefront_cmd (hw, WFC_DOWNLOAD_PROGRAM, 0, buf)) {
- printk (KERN_WARNING "WaveFront: download patch failed\n");
+ if (wavefront_cmd (WFC_DOWNLOAD_PROGRAM, 0, buf)) {
+ printk (KERN_WARNING LOGNAME "download patch failed\n");
X return -(EIO);
X }
X
@@ -1002,13 +1003,13 @@


X }
X
X static int

-wavefront_freemem (wf_config *hw)
+wavefront_freemem (void)
X
X {
X char rbuf[8];
X
- if (wavefront_cmd (hw, WFC_REPORT_FREE_MEMORY, rbuf, 0)) {
- printk (KERN_WARNING "WaveFront: can't get memory stats.\n");
+ if (wavefront_cmd (WFC_REPORT_FREE_MEMORY, rbuf, 0)) {
+ printk (KERN_WARNING LOGNAME "can't get memory stats.\n");
X return -1;
X } else {
X return demunge_int32 (rbuf, 4);
@@ -1016,8 +1017,7 @@


X }
X
X static int

-wavefront_send_sample (wf_config *hw,
- wavefront_patch_info *header,
+wavefront_send_sample (wavefront_patch_info *header,
X UINT16 *dataptr,
X int data_is_unsigned)
X
@@ -1045,15 +1045,22 @@
X int skip = 0;
X int initial_skip = 0;


X
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_LOAD_PATCH) {

- printk (KERN_DEBUG "WaveFront: sample %sdownload for slot %d, "
- "type %d, %d bytes from 0x%x\n",
- header->size ? "" : "header ",
- header->number, header->subkey, header->size,
- (int) header->dataptr);
+ DPRINT (WF_DEBUG_LOAD_PATCH, "sample %sdownload for slot %d, "
+ "type %d, %d bytes from 0x%x\n",
+ header->size ? "" : "header ",
+ header->number, header->subkey,
+ header->size,
+ (int) header->dataptr);
+
+ if (header->number == WAVEFRONT_FIND_FREE_SAMPLE_SLOT) {
+ int x;
+
+ if ((x = wavefront_find_free_sample ()) < 0) {
+ return -ENOMEM;
+ }
+ printk (KERN_DEBUG LOGNAME "unspecified sample => %d\n", x);
+ header->number = x;
X }
-#endif WF_DEBUG
X
X if (header->size) {
X
@@ -1080,24 +1087,24 @@
X a copy of the patch/program/sample header data.
X */
X
- if (hw->rom_samples_rdonly) {
- if (hw->sample_status[header->number] & WF_SLOT_ROM) {
- printk (KERN_ERR "WaveFront: sample slot %d "
+ if (dev.rom_samples_rdonly) {
+ if (dev.sample_status[header->number] & WF_SLOT_ROM) {
+ printk (KERN_ERR LOGNAME "sample slot %d "
X "write protected\n",
X header->number);
X return -EACCES;
X }
X }
X
- wavefront_delete_sample (hw, header->number);
+ wavefront_delete_sample (header->number);
X }
X
X if (header->size) {
- hw->freemem = wavefront_freemem (hw);
+ dev.freemem = wavefront_freemem ();
X
- if (hw->freemem < header->size) {
- printk (KERN_ERR
- "WaveFront: insufficient memory to "
+ if (dev.freemem < header->size) {
+ printk (KERN_ERR LOGNAME
+ "insufficient memory to "
X "load %d byte sample.\n",
X header->size);
X return -ENOMEM;
@@ -1107,16 +1114,10 @@
X
X skip = WF_GET_CHANNEL(&header->hdr.s);
X
- if (skip > 0) {
- switch (header->hdr.s.SampleResolution) {
- case LINEAR_16BIT:
- break;
- default:
- printk (KERN_ERR
- "WaveFront: channel selection only possible "
- "on 16-bit samples");
- return -(EINVAL);
- }
+ if (skip > 0 && header->hdr.s.SampleResolution != LINEAR_16BIT) {
+ printk (KERN_ERR LOGNAME "channel selection only "
+ "possible on 16-bit samples");
+ return -(EINVAL);
X }
X
X switch (skip) {
@@ -1150,13 +1151,10 @@
X break;
X }
X

-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_LOAD_PATCH) {

- printk (KERN_DEBUG "WaveFront: channel selection: %d => "
- "initial skip = %d, skip = %d\n",
- WF_GET_CHANNEL (&header->hdr.s), initial_skip, skip);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_LOAD_PATCH, "channel selection: %d => "
+ "initial skip = %d, skip = %d\n",
+ WF_GET_CHANNEL (&header->hdr.s),
+ initial_skip, skip);
X
X /* Be safe, and zero the "Unused" bits ... */
X
@@ -1210,10 +1208,10 @@
X shptr = munge_int32 (*(&header->hdr.s.FrequencyBias+1),
X shptr, 2);
X
- if (wavefront_cmd (hw, header->size ?
+ if (wavefront_cmd (header->size ?
X WFC_DOWNLOAD_SAMPLE : WFC_DOWNLOAD_SAMPLE_HEADER,
X 0, sample_hdr)) {
- printk (KERN_WARNING "WaveFront: sample %sdownload refused.\n",
+ printk (KERN_WARNING LOGNAME "sample %sdownload refused.\n",
X header->size ? "" : "header ");
X return -(EIO);
X }
@@ -1238,8 +1236,8 @@
X blocksize = ((length-written+7)&~0x7);
X }
X
- if (wavefront_cmd (hw, WFC_DOWNLOAD_BLOCK, 0, 0)) {
- printk (KERN_WARNING "WaveFront: download block "
+ if (wavefront_cmd (WFC_DOWNLOAD_BLOCK, 0, 0)) {
+ printk (KERN_WARNING LOGNAME "download block "
X "request refused.\n");
X return -(EIO);
X }
@@ -1248,7 +1246,7 @@
X
X if (dataptr < data_end) {
X
- get_user (sample_short, dataptr);
+ __get_user (sample_short, dataptr);
X dataptr += skip;
X
X if (data_is_unsigned) { /* GUS ? */
@@ -1287,21 +1285,23 @@
X }
X
X if (i < blocksize - 1) {
- outw (sample_short, hw->block_port);
+ outw (sample_short, dev.block_port);
X } else {
- outw (sample_short, hw->last_block_port);
+ outw (sample_short, dev.last_block_port);
X }
X }
X
- /* Get "DMA page acknowledge" */
+ /* Get "DMA page acknowledge", even though its really
+ nothing to do with DMA at all.
+ */
X
- if ((dma_ack = wavefront_read (hw)) != WF_DMA_ACK) {
+ if ((dma_ack = wavefront_read ()) != WF_DMA_ACK) {
X if (dma_ack == -1) {
- printk (KERN_ERR "WaveFront: upload sample "
+ printk (KERN_ERR LOGNAME "upload sample "
X "DMA ack timeout\n");
X return -(EIO);
X } else {
- printk (KERN_ERR "WaveFront: upload sample "
+ printk (KERN_ERR LOGNAME "upload sample "
X "DMA ack error 0x%x\n",
X dma_ack);
X return -(EIO);


@@ -1309,7 +1309,7 @@
X }

X }
X
- hw->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_SAMPLE);
+ dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_SAMPLE);
X
X /* Note, label is here because sending the sample header shouldn't
X alter the sample_status info at all.
@@ -1320,20 +1320,15 @@


X }
X
X static int

-wavefront_send_alias (struct wf_config *hw,
- wavefront_patch_info *header)
+wavefront_send_alias (wavefront_patch_info *header)
X
X {
X unsigned char alias_hdr[WF_ALIAS_BYTES];


X
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_LOAD_PATCH) {

- printk (KERN_DEBUG "WaveFront: download alias, %d is "
- "alias for %d\n",
- header->number,
- header->hdr.a.OriginalSample);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_LOAD_PATCH, "download alias, %d is "
+ "alias for %d\n",
+ header->number,
+ header->hdr.a.OriginalSample);
X
X munge_int32 (header->number, &alias_hdr[0], 2);
X munge_int32 (header->hdr.a.OriginalSample, &alias_hdr[2], 2);
@@ -1348,19 +1343,18 @@
X munge_int32 (header->hdr.a.FrequencyBias, &alias_hdr[20], 3);
X munge_int32 (*(&header->hdr.a.FrequencyBias+1), &alias_hdr[23], 2);
X
- if (wavefront_cmd (hw, WFC_DOWNLOAD_SAMPLE_ALIAS, 0, alias_hdr)) {
- printk (KERN_ERR "WaveFront: download alias failed.\n");
+ if (wavefront_cmd (WFC_DOWNLOAD_SAMPLE_ALIAS, 0, alias_hdr)) {
+ printk (KERN_ERR LOGNAME "download alias failed.\n");


X return -(EIO);
X }
X

- hw->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_ALIAS);
+ dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_ALIAS);
X
X return (0);


X }
X
X static int

-wavefront_send_multisample (struct wf_config *hw,
- wavefront_patch_info *header)
+wavefront_send_multisample (wavefront_patch_info *header)
X {
X int i;
X int num_samples;
@@ -1376,23 +1370,16 @@
X num_samples = (1<<(header->hdr.ms.NumberOfSamples&7));
X msample_hdr[2] = (unsigned char) header->hdr.ms.NumberOfSamples;


X
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_LOAD_PATCH) {

- printk (KERN_DEBUG "WaveFront: multi %d with %d=%d samples\n",
- header->number, header->hdr.ms.NumberOfSamples, num_samples);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_LOAD_PATCH, "multi %d with %d=%d samples\n",
+ header->number,
+ header->hdr.ms.NumberOfSamples,
+ num_samples);
X
X for (i = 0; i < num_samples; i++) {
-#ifdef WF_DEBUG
- if ((hw->debug & (WF_DEBUG_LOAD_PATCH|WF_DEBUG_DATA)) ==
- (WF_DEBUG_LOAD_PATCH|WF_DEBUG_DATA)) {
- printk (KERN_DEBUG "WaveFront: sample[%d] = %d\n",


- i, header->hdr.ms.SampleNumber[i]);
- }
-#endif WF_DEBUG

+ DPRINT(WF_DEBUG_LOAD_PATCH|WF_DEBUG_DATA, "sample[%d] = %d\n",


+ i, header->hdr.ms.SampleNumber[i]);

X munge_int32 (header->hdr.ms.SampleNumber[i],
- &msample_hdr[3+(i*2)], 2);
+ &msample_hdr[3+(i*2)], 2);
X }
X
X /* Need a hack here to pass in the number of bytes
@@ -1400,21 +1387,20 @@
X one day, I'll fix it.
X */
X
- if (wavefront_cmd (hw, WFC_DOWNLOAD_MULTISAMPLE,
+ if (wavefront_cmd (WFC_DOWNLOAD_MULTISAMPLE,
X (unsigned char *) ((num_samples*2)+3),
X msample_hdr)) {
- printk (KERN_ERR "WaveFront: download of multisample failed.\n");
+ printk (KERN_ERR LOGNAME "download of multisample failed.\n");


X return -(EIO);
X }
X

- hw->sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_MULTISAMPLE);
+ dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_MULTISAMPLE);
X
X return (0);


X }
X
X static int

-wavefront_fetch_multisample (struct wf_config *hw,
- wavefront_patch_info *header)
+wavefront_fetch_multisample (wavefront_patch_info *header)
X {
X int i;
X unsigned char log_ns[1];
@@ -1423,17 +1409,13 @@
X
X munge_int32 (header->number, number, 2);
X
- if (wavefront_cmd (hw, WFC_UPLOAD_MULTISAMPLE, log_ns, number)) {
- printk (KERN_ERR "WaveFront: upload multisample failed.\n");
+ if (wavefront_cmd (WFC_UPLOAD_MULTISAMPLE, log_ns, number)) {
+ printk (KERN_ERR LOGNAME "upload multisample failed.\n");


X return -(EIO);
X }
X

-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_DATA) {
- printk (KERN_DEBUG "WaveFront: msample %d has %d samples\n",
- header->number, log_ns[0]);
- }
-#endif WF_DEBUG
+ DPRINT (WF_DEBUG_DATA, "msample %d has %d samples\n",
+ header->number, log_ns[0]);
X
X header->hdr.ms.NumberOfSamples = log_ns[0];
X
@@ -1444,14 +1426,14 @@
X for (i = 0; i < num_samples; i++) {
X char d[2];
X
- if ((d[0] = wavefront_read (hw)) == -1) {
- printk (KERN_ERR "WaveFront: upload multisample failed "
+ if ((d[0] = wavefront_read ()) == -1) {
+ printk (KERN_ERR LOGNAME "upload multisample failed "
X "during sample loop.\n");


X return -(EIO);
X }
X

- if ((d[1] = wavefront_read (hw)) == -1) {
- printk (KERN_ERR "WaveFront: upload multisample failed "
+ if ((d[1] = wavefront_read ()) == -1) {
+ printk (KERN_ERR LOGNAME "upload multisample failed "
X "during sample loop.\n");
X return -(EIO);
X }
@@ -1459,13 +1441,8 @@
X header->hdr.ms.SampleNumber[i] =
X demunge_int32 ((unsigned char *) d, 2);
X
-#ifdef WF_DEBUG
- if (hw->debug & WF_DEBUG_DATA) {
- printk (KERN_DEBUG "WaveFront: msample "


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre5 failed'
fi

echo 'End of part 04'
echo 'File patch-2.2.0-pre5 is continued in part 05'
echo 05 > _shar_seq_.tmp

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

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to
Archive-name: v2.1/patch-2.2.0-pre5/part07

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


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

--- v2.2.0-pre4/linux/fs/Config.in Thu Dec 31 10:29:01 1998
+++ linux/fs/Config.in Mon Jan 4 12:05:11 1999
@@ -22,12 +22,15 @@
X tristate 'ISO 9660 CDROM filesystem support' CONFIG_ISO9660_FS
X if [ "$CONFIG_ISO9660_FS" != "n" ]; then
X bool 'Microsoft Joliet CDROM extensions' CONFIG_JOLIET
+else
+ # needed by nls/Config.in
+ define_bool CONFIG_JOLIET n
X fi
X
X tristate 'Minix fs support' CONFIG_MINIX_FS
X tristate 'NTFS filesystem support (read only)' CONFIG_NTFS_FS
X if [ "$CONFIG_NTFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool ' NTFS read-write support (experimental)' CONFIG_NTFS_RW
+ bool ' NTFS read-write support (DANGEROUS)' CONFIG_NTFS_RW
X fi
X tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS
X bool '/proc filesystem support' CONFIG_PROC_FS
@@ -44,8 +47,12 @@
X tristate 'Second extended fs support' CONFIG_EXT2_FS
X tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS
X tristate 'UFS filesystem support' CONFIG_UFS_FS
+if [ "$CONFIG_UFS_FS" != "n" ]; then
+ bool ' UFS filesystem write support (experimental)' CONFIG_UFS_FS_WRITE
+fi
X
X
+if [ "$CONFIG_NET" = "y" ]; then
X
X mainmenu_option next_comment
X comment 'Network File Systems'
@@ -87,6 +94,7 @@
X fi
X
X endmenu
+fi
X
X if [ "$CONFIG_AFFS_FS" != "n" ]; then
X define_bool CONFIG_AMIGA_PARTITION y
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/buffer.c linux/fs/buffer.c
--- v2.2.0-pre4/linux/fs/buffer.c Fri Jan 1 12:58:20 1999
+++ linux/fs/buffer.c Wed Jan 6 00:01:36 1999
@@ -76,8 +76,6 @@
X static int nr_buffers_type[NR_LIST] = {0,};
X static int nr_buffer_heads = 0;
X static int nr_unused_buffer_heads = 0;
-static int refilled = 0; /* Set NZ when a buffer freelist is refilled
- this is used by the loop device */
X
X /* This is used by some architectures to estimate available memory. */
X int buffermem = 0;
@@ -113,8 +111,8 @@
X } bdf_prm = {{40, 500, 64, 256, 15, 30*HZ, 5*HZ, 1884, 2}};
X
X /* These are the min and max parameter values that we will allow to be assigned */
-int bdflush_min[N_PARAM] = { 0, 10, 5, 25, 0, 100, 100, 1, 1};
-int bdflush_max[N_PARAM] = {100,5000, 2000, 2000,100, 60000, 60000, 2047, 5};
+int bdflush_min[N_PARAM] = { 0, 10, 5, 25, 0, 1*HZ, 1*HZ, 1, 1};
+int bdflush_max[N_PARAM] = {100,5000, 2000, 2000,100, 600*HZ, 600*HZ, 2047, 5};
X
X void wakeup_bdflush(int);
X
@@ -1607,7 +1605,7 @@
X * and superblocks so that we could write back only the old ones as well
X */
X
-asmlinkage int sync_old_buffers(void)
+static int sync_old_buffers(void)
X {
X int i;
X int ndirty, nwritten;
@@ -1774,7 +1772,6 @@
X #endif
X {
X ndirty = 0;
- refilled = 0;
X repeat:
X
X bh = lru_list[nlist];
@@ -1801,8 +1798,6 @@
X major = MAJOR(bh->b_dev);
X /* Should we write back buffers that are shared or not??
X currently dirty buffers are not shared, so it does not matter */
- if (refilled && major == LOOP_MAJOR)
- continue;
X next->b_count++;
X bh->b_count++;
X ndirty++;
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/dcache.c linux/fs/dcache.c
--- v2.2.0-pre4/linux/fs/dcache.c Thu Dec 31 10:29:01 1998
+++ linux/fs/dcache.c Tue Jan 5 13:19:12 1999
@@ -190,9 +190,9 @@
X int select_dcache(int inode_count, int page_count)
X {
X struct list_head *next, *tail = &dentry_unused;
- int found = 0, forward = 0, young = 8;
+ int found = 0;
X int depth = dentry_stat.nr_unused >> 1;
- unsigned long min_value = 0, max_value = 4;
+ unsigned long max_value = 4;
X
X if (page_count)
X max_value = -1;
@@ -205,39 +205,12 @@
X unsigned long value = 0;
X
X next = tmp->prev;
- if (forward)
- next = tmp->next;
X if (dentry->d_count) {
X dentry_stat.nr_unused--;
X list_del(tmp);
X INIT_LIST_HEAD(tmp);
X continue;
X }
- /*
- * Check the dentry's age to see whether to change direction.
- */
- if (!forward) {
- int age = (jiffies - dentry->d_reftime) / HZ;
- if (age < dentry_stat.age_limit) {
- if (!--young) {
- forward = 1;
- next = dentry_unused.next;
- /*
- * Update the limits -- we don't want
- * files with too few or too many pages.
- */
- if (page_count) {
- min_value = 3;
- max_value = 15;
- }
-#ifdef DCACHE_DEBUG
-printk("select_dcache: %s/%s age=%d, scanning forward\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, age);
-#endif


- }
- continue;
- }
- }

X
X /*
X * Select dentries based on the page cache count ...
@@ -247,7 +220,7 @@
X */
X if (inode) {
X value = inode->i_nrpages;
- if (value >= max_value || value < min_value)
+ if (value >= max_value)
X continue;
X if (inode->i_state || inode->i_count > 1)
X continue;
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/fat/inode.c linux/fs/fat/inode.c
--- v2.2.0-pre4/linux/fs/fat/inode.c Mon Jan 4 15:08:17 1999
+++ linux/fs/fat/inode.c Mon Jan 4 10:08:28 1999
@@ -243,16 +243,16 @@
X ret = 0;
X }
X }
- else if (!strcmp(this_char,"cvf_format")) {
- if (!value)
- return 0;
- strncpy(cvf_format,value,20);
- }
- else if (!strcmp(this_char,"cvf_options")) {
- if (!value)
- return 0;
- strncpy(cvf_options,value,100);
- }
+ else if (!strcmp(this_char,"cvf_format")) {
+ if (!value)
+ return 0;
+ strncpy(cvf_format,value,20);
+ }
+ else if (!strcmp(this_char,"cvf_options")) {
+ if (!value)
+ return 0;
+ strncpy(cvf_options,value,100);
+ }
X
X if (this_char != options) *(this_char-1) = ',';
X if (value) *savep = save;
@@ -302,7 +302,7 @@
X
X opts.isvfat = MSDOS_SB(sb)->options.isvfat;
X if (!parse_options((char *) data, &fat, &blksize, &debug, &opts,
- cvf_format, cvf_options)
+ cvf_format, cvf_options)
X || (blksize != 512 && blksize != 1024 && blksize != 2048))
X goto out_fail;
X /* N.B. we should parse directly into the sb structure */
@@ -364,8 +364,8 @@
X MSDOS_SB(sb)->root_cluster = CF_LE_L(b->root_cluster);
X MSDOS_SB(sb)->fsinfo_offset =
X CF_LE_W(b->info_sector) * logical_sector_size + 0x1e0;
- if (MSDOS_SB(sb)->fsinfo_offset + sizeof(MSDOS_SB(sb)->fsinfo_offset) > sb->s_blocksize) {
- printk("fat_read_super: Bad fsinfo_offset 0x%x\n", MSDOS_SB(sb)->fsinfo_offset);
+ if (MSDOS_SB(sb)->fsinfo_offset + sizeof(struct fat_boot_fsinfo) > sb->s_blocksize) {
+ printk("fat_read_super: Bad fsinfo_offset\n");
X fat_brelse(sb, bh);
X goto out_invalid;
X }
@@ -524,10 +524,10 @@
X int free,nr;
X struct statfs tmp;
X
- if (MSDOS_SB(sb)->cvf_format &&
+ if (MSDOS_SB(sb)->cvf_format &&
X MSDOS_SB(sb)->cvf_format->cvf_statfs)
X return MSDOS_SB(sb)->cvf_format->cvf_statfs(sb,buf,bufsiz);
-
+
X lock_fat(sb);
X if (MSDOS_SB(sb)->free_clusters != -1)
X free = MSDOS_SB(sb)->free_clusters;
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/inode.c linux/fs/inode.c
--- v2.2.0-pre4/linux/fs/inode.c Fri Oct 23 22:01:22 1998
+++ linux/fs/inode.c Mon Jan 4 17:52:17 1999
@@ -147,12 +147,8 @@
X __wait_on_inode(inode);
X spin_lock(&inode_lock);
X } else {
- struct list_head *insert = &inode_in_use;
- if (!inode->i_count)
- insert = inode_in_use.prev;
X list_del(&inode->i_list);
- list_add(&inode->i_list, insert);
-
+ list_add(&inode->i_list, &inode_in_use);
X /* Set I_LOCK, reset I_DIRTY */
X inode->i_state ^= I_DIRTY | I_LOCK;
X spin_unlock(&inode_lock);
@@ -705,7 +701,7 @@
X }
X else if (!(inode->i_state & I_DIRTY)) {
X list_del(&inode->i_list);
- list_add(&inode->i_list, inode_in_use.prev);
+ list_add(&inode->i_list, &inode_in_use);
X }
X #ifdef INODE_PARANOIA
X if (inode->i_flock)
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/lockd/clntlock.c linux/fs/lockd/clntlock.c
--- v2.2.0-pre4/linux/fs/lockd/clntlock.c Sun Nov 8 14:03:06 1998
+++ linux/fs/lockd/clntlock.c Mon Jan 4 10:23:42 1999
@@ -71,12 +71,7 @@
X * a 1 minute timeout would do. See the comment before
X * nlmclnt_lock for an explanation.
X */
- /*
- * FIXME, can we be not interruptible and so be allowed to use
- * a timeout here? -arca
- */
-/* current->timeout = jiffies + 30 * HZ; */
- sleep_on(&block.b_wait);
+ sleep_on_timeout(&block.b_wait, 30*HZ);
X
X for (head = &nlm_blocked; *head; head = &(*head)->b_next) {
X if (*head == &block) {
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/nfs/inode.c linux/fs/nfs/inode.c
--- v2.2.0-pre4/linux/fs/nfs/inode.c Mon Dec 28 15:00:53 1998
+++ linux/fs/nfs/inode.c Tue Jan 5 13:04:08 1999
@@ -474,7 +474,7 @@
X * unhashed inode to avoid aliasing problems.
X */
X if ((dentry->d_parent->d_inode->u.nfs_i.flags & NFS_IS_SNAPSHOT) ||
- (IS_ROOT(dentry->d_parent) && dentry->d_name.len == 9 &&
+ (dentry->d_name.len == 9 &&
X memcmp(dentry->d_name.name, ".snapshot", 9) == 0)) {
X struct inode *inode = get_empty_inode();
X if (!inode)
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/ntfs/ntfsendian.h linux/fs/ntfs/ntfsendian.h
--- v2.2.0-pre4/linux/fs/ntfs/ntfsendian.h Mon Jan 4 15:08:17 1999
+++ linux/fs/ntfs/ntfsendian.h Mon Jan 4 10:41:35 1999
@@ -71,7 +71,7 @@
X #define NTFS_PUTU64(p,v) ((*(ntfs_u64*)(p))=CPU_TO_LE64(v))
X
X /* Macros reading signed integers */
-#define NTFS_GETS8(p) ((*(ntfs_u8*)(p)))
+#define NTFS_GETS8(p) ((*(ntfs_s8*)(p)))
X #define NTFS_GETS16(p) ((ntfs_s16)LE16_TO_CPU(*(short*)(p)))
X #define NTFS_GETS24(p) (NTFS_GETU24(p) < 0x800000 ? (int)NTFS_GETU24(p) : (int)(NTFS_GETU24(p) - 0x1000000))
X #define NTFS_GETS32(p) ((ntfs_s32)LE32_TO_CPU(*(int*)(p)))
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/proc/array.c linux/fs/proc/array.c
--- v2.2.0-pre4/linux/fs/proc/array.c Tue Dec 22 14:16:57 1998
+++ linux/fs/proc/array.c Wed Jan 6 09:26:15 1999
@@ -1397,6 +1397,7 @@
X case PROC_PID_STAT:
X case PROC_PID_MAPS:
X case PROC_PID_CMDLINE:
+ case PROC_PID_CPU:
X return 0;
X }
X if(capable(CAP_DAC_OVERRIDE) || current->fsuid == euid)
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/qnx4/symlinks.c linux/fs/qnx4/symlinks.c
--- v2.2.0-pre4/linux/fs/qnx4/symlinks.c Thu Nov 19 09:56:29 1998
+++ linux/fs/qnx4/symlinks.c Mon Jan 4 11:42:43 1999
@@ -23,7 +23,7 @@
X #include <asm/uaccess.h>
X
X static int qnx4_readlink(struct dentry *, char *, int);
-static struct dentry *qnx4_follow_link(struct dentry *, struct dentry *);
+static struct dentry *qnx4_follow_link(struct dentry *, struct dentry *, unsigned int follow);
X
X /*
X * symlinks can't do much...
@@ -50,7 +50,7 @@
X };
X
X static struct dentry *qnx4_follow_link(struct dentry *dentry,
- struct dentry *base)
+ struct dentry *base, unsigned int follow)
X {
X #if 0
X struct inode *inode = dentry->d_inode;
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/ufs/acl.c linux/fs/ufs/acl.c
--- v2.2.0-pre4/linux/fs/ufs/acl.c Sat Sep 5 16:46:41 1998
+++ linux/fs/ufs/acl.c Mon Jan 4 11:51:29 1999
@@ -58,8 +58,11 @@
X * Access is always granted for root. We now check last,
X * though, for BSD process accounting correctness
X */
- if (((mode & mask & S_IRWXO) == mask) || fsuser())
+ if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE))
X return 0;
- else
- return -EACCES;
+ if ((mask == S_IROTH) ||
+ (S_ISDIR(mode) && !(mask & ~(S_IROTH | S_IXOTH))))
+ if (capable(CAP_DAC_READ_SEARCH))
+ return 0;
+ return -EACCES;
X }
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/ufs/namei.c linux/fs/ufs/namei.c
--- v2.2.0-pre4/linux/fs/ufs/namei.c Tue Dec 22 14:16:57 1998
+++ linux/fs/ufs/namei.c Mon Jan 4 12:05:11 1999
@@ -34,6 +34,7 @@
X #include <linux/stat.h>
X #include <linux/string.h>
X #include <linux/locks.h>
+#include <linux/quotaops.h>
X
X #include "swab.h"
X #include "util.h"
@@ -55,21 +56,18 @@
X #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b))
X
X /*
- * NOTE! unlike strncmp, ufs_match returns 1 for success, 0 for failure.
+ * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
+ *
+ * Len <= UFS_MAXNAMLEN' is guaranteed by caller.
+ * De != NULL' is guaranteed by caller.
X */
-static int ufs_match (int len, const char * const name,
+static inline int ufs_match (int len, const char * const name,
X struct ufs_dir_entry * de, unsigned flags, unsigned swab)
X {
- if (!de || !SWAB32(de->d_ino) || len > UFS_MAXNAMLEN)
- return 0;
- /*
- * "" means "." ---> so paths like "/usr/lib//libc.a" work
- */
- if (!len && ufs_get_de_namlen(de) == 1 && (de->d_name[0] == '.') &&
- (de->d_name[1] == '\0'))
- return 1;
X if (len != ufs_get_de_namlen(de))
X return 0;
+ if (!de->d_ino)
+ return 0;
X return !memcmp(name, de->d_name, len);
X }
X
@@ -128,8 +126,9 @@
X }
X bh = bh_use[block % NAMEI_RA_SIZE];
X if (!bh) {
- ufs_error (sb, "ufs_find_entry",
- "directory #%lu contains a hole at offset %lu", dir->i_ino, offset);
+ ufs_error (sb, "ufs_find_entry",
+ "directory #%lu contains a hole at offset %lu",
+ dir->i_ino, offset);
X offset += sb->s_blocksize;
X continue;
X }
@@ -144,20 +143,30 @@
X de = (struct ufs_dir_entry *) bh->b_data;
X dlimit = bh->b_data + sb->s_blocksize;
X while ((char *) de < dlimit && offset < dir->i_size) {
- if (!ufs_check_dir_entry ("ufs_find_entry", dir, de, bh, offset))
- goto failed;
- if (SWAB32(de->d_ino) != 0 && ufs_match (namelen, name, de, flags, swab)) {
+ /* this code is executed quadratically often */
+ /* do minimal checking by hand' */
+ int de_len;
+
+ if ((char *) de + namelen <= dlimit &&
+ ufs_match (namelen, name, de, flags, swab)) {
+ /* found a match -
+ just to be sure, do a full check */
+ if (!ufs_check_dir_entry("ufs_find_entry",
+ dir, de, bh, offset))
+ goto failed;
X for (i = 0; i < NAMEI_RA_SIZE; ++i) {
X if (bh_use[i] != bh)
X brelse (bh_use[i]);
X }
X *res_dir = de;
- UFSD(("EXIT\n"))
X return bh;
X }
- offset += SWAB16(de->d_reclen);
- de = (struct ufs_dir_entry *)
- ((char *) de + SWAB16(de->d_reclen));
+ /* prevent looping on a bad block */
+ de_len = SWAB16(de->d_reclen);
+ if (de_len <= 0)
+ goto failed;
+ offset += de_len;
+ de = (struct ufs_dir_entry *) ((char *) de + de_len);
X }
X
X brelse (bh);
@@ -173,7 +182,7 @@
X
X failed:
X for (i = 0; i < NAMEI_RA_SIZE; ++i) brelse (bh_use[i]);
- UFSD(("EXIT (FAILED)\n"))
+ UFSD(("EXIT\n"))
X return NULL;
X }
X
@@ -298,7 +307,7 @@
X brelse (bh);
X return NULL;
X }
- if (SWAB32(de->d_ino) != 0 && ufs_match (namelen, name, de, flags, swab)) {
+ if (ufs_match (namelen, name, de, flags, swab)) {
X *err = -EEXIST;
X brelse (bh);
X return NULL;
@@ -673,8 +682,7 @@
X goto end_rmdir;
X
X inode = dentry->d_inode;
- if (inode->i_sb->dq_op)
- inode->i_sb->dq_op->initialize (inode, -1);
+ DQUOT_INIT(inode);
X
X retval = -EIO;
X if (SWAB32(de->d_ino) != inode->i_ino)
@@ -741,8 +749,7 @@
X goto end_unlink;
X
X inode = dentry->d_inode;
- if (inode->i_sb->dq_op)
- inode->i_sb->dq_op->initialize (inode, -1);
+ DQUOT_INIT(inode);
X
X retval = -EIO;
X if (SWAB32(de->d_ino) != inode->i_ino)
@@ -778,49 +785,6 @@
X }
X
X
-int ufs_link (struct dentry * old_dentry, struct inode * dir,
- struct dentry *dentry)
-{
- struct super_block * sb;
- struct inode *inode = old_dentry->d_inode;
- struct ufs_dir_entry * de;
- struct buffer_head * bh;
- int err;
- unsigned swab;
-
- inode = old_dentry->d_inode;
- sb = inode->i_sb;
- swab = sb->u.ufs_sb.s_swab;
-
- if (S_ISDIR(inode->i_mode))
- return -EPERM;
-
- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
- return -EPERM;
-
- if (inode->i_nlink >= UFS_LINK_MAX)
- return -EMLINK;
-
- bh = ufs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
- if (!bh)
- return err;
-
- de->d_ino = SWAB32(inode->i_ino);
- dir->i_version = ++event;
- mark_buffer_dirty(bh, 1);
- if (IS_SYNC(dir)) {
- ll_rw_block (WRITE, 1, &bh);
- wait_on_buffer (bh);
- }
- brelse (bh);
- inode->i_nlink++;
- inode->i_ctime = CURRENT_TIME;
- mark_inode_dirty(inode);
- inode->i_count++;
- d_instantiate(dentry, inode);


- return 0;
-}
-

X /*
X * Create symbolic link. We use only slow symlinks at this time.
X */
@@ -901,6 +865,49 @@


X goto out;
X }
X

+int ufs_link (struct dentry * old_dentry, struct inode * dir,
+ struct dentry *dentry)
+{
+ struct super_block * sb;
+ struct inode *inode = old_dentry->d_inode;
+ struct ufs_dir_entry * de;
+ struct buffer_head * bh;
+ int err;
+ unsigned swab;
+
+ inode = old_dentry->d_inode;
+ sb = inode->i_sb;
+ swab = sb->u.ufs_sb.s_swab;
+
+ if (S_ISDIR(inode->i_mode))
+ return -EPERM;
+
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ return -EPERM;
+
+ if (inode->i_nlink >= UFS_LINK_MAX)
+ return -EMLINK;
+
+ bh = ufs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
+ if (!bh)
+ return err;
+
+ de->d_ino = SWAB32(inode->i_ino);
+ dir->i_version = ++event;
+ mark_buffer_dirty(bh, 1);
+ if (IS_SYNC(dir)) {
+ ll_rw_block (WRITE, 1, &bh);
+ wait_on_buffer (bh);
+ }
+ brelse (bh);
+ inode->i_nlink++;
+ inode->i_ctime = CURRENT_TIME;
+ mark_inode_dirty(inode);
+ inode->i_count++;
+ d_instantiate(dentry, inode);


+ return 0;
+}
+

X
X #define PARENT_INO(buffer) \
X ((struct ufs_dir_entry *) ((char *) buffer + \
@@ -939,27 +946,26 @@
X if (old_dentry->d_name.len > UFS_MAXNAMLEN)
X goto end_rename;
X
- UFSD(("name %s, len %u\n", old_dentry->d_name.name, old_dentry->d_name.len))
X old_bh = ufs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len, &old_de);
- UFSD(("ino %u, reclen %u, namlen %u, name %s\n", SWAB32(old_de->d_ino),
- SWAB16(old_de->d_reclen), ufs_get_de_namlen(old_de), old_de->d_name))
-
- /* Arrrgh. See comments in ext2 */
+ /*
+ * Check for inode number is _not_ due to possible IO errors.
+ * We might rmdir the source, keep it as pwd of some process
+ * and merrily kill the link to whatever was created under the
+ * same name. Goodbye sticky bit ;-<
+ */
X retval = -ENOENT;
+ old_inode = old_dentry->d_inode;
X if (!old_bh || SWAB32(old_de->d_ino) != old_inode->i_ino)
X goto end_rename;
- old_inode = old_dentry->d_inode;
X
X new_inode = new_dentry->d_inode;
- UFSD(("name %s, len %u\n", new_dentry->d_name.name, new_dentry->d_name.len))
X new_bh = ufs_find_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len, &new_de);
X if (new_bh) {
X if (!new_inode) {
X brelse (new_bh);
X new_bh = NULL;
X } else {
- if (new_inode->i_sb->dq_op)
- new_inode->i_sb->dq_op->initialize (new_inode, -1);
+ DQUOT_INIT(new_inode);
X }
X }
X retval = 0;
@@ -970,6 +976,7 @@
X if (is_subdir(new_dentry, old_dentry))
X goto end_rename;
X if (new_inode) {
+ /* Prune any children before testing for busy */
X if (new_dentry->d_count > 1)
X shrink_dcache_parent(new_dentry);
X retval = -EBUSY;
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/ufs/super.c linux/fs/ufs/super.c
--- v2.2.0-pre4/linux/fs/ufs/super.c Fri Oct 23 22:01:22 1998
+++ linux/fs/ufs/super.c Mon Jan 4 12:05:11 1999
@@ -449,6 +449,9 @@
X MOD_INC_USE_COUNT;
X lock_super (sb);
X
+#ifndef CONFIG_UFS_FS_WRITE
+ sb->s_flags |= MS_RDONLY;
+#endif
X /*
X * Set default mount options
X * Parse mount options
@@ -527,9 +530,6 @@
X goto failed;
X }
X
- if (!(sb->s_flags & MS_RDONLY))
- printk("!!! warning !!! write support of ufs is still in experimental state\n");
-
X again:
X set_blocksize (sb->s_dev, block_size);
X
diff -u --recursive --new-file v2.2.0-pre4/linux/fs/vfat/namei.c linux/fs/vfat/namei.c
--- v2.2.0-pre4/linux/fs/vfat/namei.c Tue Dec 22 14:16:57 1998
+++ linux/fs/vfat/namei.c Wed Jan 6 09:27:14 1999
@@ -1549,8 +1549,10 @@
X res = -EBUSY;
X if (list_empty(&dentry->d_hash)) {
X res = vfat_rmdirx(dir, dentry);
- if (res >= 0)
+ if (res >= 0) {
X drop_replace_inodes(dentry, NULL);
+ d_delete(dentry);
+ }
X }
X return res;
X }
diff -u --recursive --new-file v2.2.0-pre4/linux/include/asm-m68k/init.h linux/include/asm-m68k/init.h
--- v2.2.0-pre4/linux/include/asm-m68k/init.h Tue Feb 17 13:12:49 1998
+++ linux/include/asm-m68k/init.h Tue Jan 5 11:20:43 1999
@@ -15,6 +15,9 @@
X #define __FINIT .previous
X #define __INITDATA .section ".data.init",#alloc,#write
X
+#define __cacheline_aligned __attribute__ \
+ ((__section__ (".data.cacheline_aligned")))
+
X #else
X
X /* gdb doesn't like it all if the code for one source file isn't together in
@@ -27,6 +30,7 @@
X #define __INIT
X #define __FINIT
X #define __INITDATA
+#define __cacheline_aligned
X
X #endif /* CONFIG_KGDB */
X
diff -u --recursive --new-file v2.2.0-pre4/linux/include/asm-m68k/resource.h linux/include/asm-m68k/resource.h
--- v2.2.0-pre4/linux/include/asm-m68k/resource.h Wed Sep 25 00:47:42 1996
+++ linux/include/asm-m68k/resource.h Tue Jan 5 11:20:43 1999
@@ -25,7 +25,7 @@
X {LONG_MAX, LONG_MAX}, \
X {LONG_MAX, LONG_MAX}, \
X {LONG_MAX, LONG_MAX}, \
- {_STK_LIM, _STK_LIM}, \
+ {_STK_LIM, LONG_MAX}, \
X { 0, LONG_MAX}, \
X {LONG_MAX, LONG_MAX}, \
X {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER}, \
diff -u --recursive --new-file v2.2.0-pre4/linux/include/asm-m68k/softirq.h linux/include/asm-m68k/softirq.h
--- v2.2.0-pre4/linux/include/asm-m68k/softirq.h Sat Sep 5 16:46:41 1998
+++ linux/include/asm-m68k/softirq.h Tue Jan 5 11:20:43 1999
@@ -13,7 +13,7 @@
X extern inline void init_bh(int nr, void (*routine)(void))
X {
X bh_base[nr] = routine;
- bh_mask_count[nr] = 0;
+ atomic_set(&bh_mask_count[nr], 0);
X bh_mask |= 1 << nr;
X }
X
@@ -29,12 +29,12 @@
X extern inline void disable_bh(int nr)
X {
X bh_mask &= ~(1 << nr);
- bh_mask_count[nr]++;
+ atomic_inc(&bh_mask_count[nr]);
X }
X
X extern inline void enable_bh(int nr)
X {
- if (!--bh_mask_count[nr])
+ if (atomic_dec_and_test(&bh_mask_count[nr]))
X bh_mask |= 1 << nr;
X }
X
diff -u --recursive --new-file v2.2.0-pre4/linux/include/asm-m68k/timex.h linux/include/asm-m68k/timex.h
--- v2.2.0-pre4/linux/include/asm-m68k/timex.h Fri May 8 23:14:55 1998
+++ linux/include/asm-m68k/timex.h Tue Jan 5 11:20:43 1999
@@ -12,4 +12,11 @@
X (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
X << (SHIFT_SCALE-SHIFT_HZ)) / HZ)
X
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{


+ return 0;
+}
+

X #endif
diff -u --recursive --new-file v2.2.0-pre4/linux/include/asm-m68k/uaccess.h linux/include/asm-m68k/uaccess.h
--- v2.2.0-pre4/linux/include/asm-m68k/uaccess.h Tue Dec 22 14:16:58 1998
+++ linux/include/asm-m68k/uaccess.h Tue Jan 5 11:20:43 1999
@@ -184,7 +184,7 @@
X " .long 5b,9b\n"
X ".previous"
X : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
- : "r"(n & 3), "0"(to), "1"(from), "2"(n/4)
+ : "d"(n & 3), "0"(to), "1"(from), "2"(n/4)
X : "d0", "memory");
X return n;
X }
diff -u --recursive --new-file v2.2.0-pre4/linux/include/linux/inetdevice.h linux/include/linux/inetdevice.h
--- v2.2.0-pre4/linux/include/linux/inetdevice.h Tue Mar 10 10:03:35 1998
+++ linux/include/linux/inetdevice.h Mon Jan 4 15:31:35 1999
@@ -76,8 +76,6 @@
X extern struct in_device *inetdev_by_index(int);
X extern u32 inet_select_addr(struct device *dev, u32 dst, int scope);
X extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, u32 prefix, u32 mask);
-extern int inet_add_bootp_addr(struct device *dev);
-extern void inet_del_bootp_addr(struct device *dev);
X extern void inet_forward_change(void);
X
X extern __inline__ int inet_ifa_match(u32 addr, struct in_ifaddr *ifa)
diff -u --recursive --new-file v2.2.0-pre4/linux/include/linux/ip_masq.h linux/include/linux/ip_masq.h
--- v2.2.0-pre4/linux/include/linux/ip_masq.h Mon Oct 5 13:13:44 1998
+++ linux/include/linux/ip_masq.h Mon Jan 4 15:31:35 1999
@@ -1,6 +1,6 @@
X /*
X * IP_MASQ user space control interface
- * $Id: ip_masq.h,v 1.1 1998/08/29 23:50:56 davem Exp $
+ * $Id: ip_masq.h,v 1.2 1998/12/08 05:41:48 davem Exp $
X */
X
X #ifndef _LINUX_IP_MASQ_H
@@ -90,16 +90,19 @@
X };
X
X /*
- * MARKFW stuff
+ * MFW stuff
X */
-struct ip_markfw_user {
+struct ip_mfw_user {
X u_int32_t fwmark; /* Firewalling mark */
X u_int32_t raddr; /* remote port */
X u_int16_t rport; /* remote port */
X u_int16_t dummy; /* Make up to multiple of 4 */
X int pref; /* Preference value */
+ unsigned flags; /* misc flags */
X };
X
+#define IP_MASQ_MFW_SCHED 0x01
+
X #define IP_FW_MASQCTL_MAX 256
X #define IP_MASQ_TNAME_MAX 32
X
@@ -110,7 +113,7 @@
X union {
X struct ip_portfw_user portfw_user;
X struct ip_autofw_user autofw_user;
- struct ip_markfw_user markfw_user;
+ struct ip_mfw_user mfw_user;
X struct ip_masq_user user;
X unsigned char m_raw[IP_FW_MASQCTL_MAX];
X } u;
@@ -123,14 +126,14 @@
X #define IP_MASQ_TARGET_USER 3
X #define IP_MASQ_TARGET_LAST 4
X
-#define IP_MASQ_CMD_NONE 0
+#define IP_MASQ_CMD_NONE 0 /* just peek */
X #define IP_MASQ_CMD_INSERT 1
X #define IP_MASQ_CMD_ADD 2
X #define IP_MASQ_CMD_SET 3
X #define IP_MASQ_CMD_DEL 4
X #define IP_MASQ_CMD_GET 5
X #define IP_MASQ_CMD_FLUSH 6
-#define IP_MASQ_CMD_LIST 7
+#define IP_MASQ_CMD_LIST 7 /* actually fake: done via /proc */
X #define IP_MASQ_CMD_ENABLE 8
X #define IP_MASQ_CMD_DISABLE 9
X
diff -u --recursive --new-file v2.2.0-pre4/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.2.0-pre4/linux/include/linux/mm.h Fri Jan 1 12:58:21 1999
+++ linux/include/linux/mm.h Wed Jan 6 10:07:46 1999
@@ -130,20 +130,22 @@
X #define PG_locked 0
X #define PG_error 1
X #define PG_referenced 2
-#define PG_uptodate 3
-#define PG_free_after 4
-#define PG_decr_after 5
-#define PG_swap_unlock_after 6
-#define PG_DMA 7
-#define PG_Slab 8
-#define PG_swap_cache 9
-#define PG_skip 10
+#define PG_dirty 3
+#define PG_uptodate 4
+#define PG_free_after 5
+#define PG_decr_after 6
+#define PG_swap_unlock_after 7
+#define PG_DMA 8
+#define PG_Slab 9
+#define PG_swap_cache 10
+#define PG_skip 11
X #define PG_reserved 31
X
X /* Make it prettier to test the above... */
X #define PageLocked(page) (test_bit(PG_locked, &(page)->flags))
X #define PageError(page) (test_bit(PG_error, &(page)->flags))
X #define PageReferenced(page) (test_bit(PG_referenced, &(page)->flags))
+#define PageDirty(page) (test_bit(PG_dirty, &(page)->flags))
X #define PageUptodate(page) (test_bit(PG_uptodate, &(page)->flags))
X #define PageFreeAfter(page) (test_bit(PG_free_after, &(page)->flags))
X #define PageDecrAfter(page) (test_bit(PG_decr_after, &(page)->flags))
@@ -155,12 +157,17 @@
X
X #define PageSetSlab(page) (set_bit(PG_Slab, &(page)->flags))
X #define PageSetSwapCache(page) (set_bit(PG_swap_cache, &(page)->flags))
+
+#define PageTestandSetDirty(page) \
+ (test_and_set_bit(PG_dirty, &(page)->flags))
X #define PageTestandSetSwapCache(page) \
X (test_and_set_bit(PG_swap_cache, &(page)->flags))
X
X #define PageClearSlab(page) (clear_bit(PG_Slab, &(page)->flags))
X #define PageClearSwapCache(page)(clear_bit(PG_swap_cache, &(page)->flags))
X
+#define PageTestandClearDirty(page) \
+ (test_and_clear_bit(PG_dirty, &(page)->flags))
X #define PageTestandClearSwapCache(page) \
X (test_and_clear_bit(PG_swap_cache, &(page)->flags))
X
diff -u --recursive --new-file v2.2.0-pre4/linux/include/linux/ntfs_fs_i.h linux/include/linux/ntfs_fs_i.h
--- v2.2.0-pre4/linux/include/linux/ntfs_fs_i.h Fri Dec 19 15:24:22 1997
+++ linux/include/linux/ntfs_fs_i.h Mon Jan 4 10:41:35 1999
@@ -5,13 +5,17 @@
X struct ntfs_attribute;
X struct ntfs_sb_info;
X
-/* Duplicate definitions from ntfs/types.h */
+/* Duplicate definitions from ntfs/ntfstypes.h */
X #ifndef NTFS_INTEGRAL_TYPES
X #define NTFS_INTEGRAL_TYPES
-typedef unsigned char ntfs_u8;
-typedef unsigned short ntfs_u16;
-typedef unsigned int ntfs_u32;
-typedef unsigned long long ntfs_u64;
+typedef u8 ntfs_u8;
+typedef u16 ntfs_u16;
+typedef u32 ntfs_u32;
+typedef u64 ntfs_u64;
+typedef s8 ntfs_s8;
+typedef s16 ntfs_s16;
+typedef s32 ntfs_s32;
+typedef s64 ntfs_s64;
X #endif
X
X #ifndef NTMODE_T
diff -u --recursive --new-file v2.2.0-pre4/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.2.0-pre4/linux/include/linux/pci.h Mon Jan 4 15:08:18 1999
+++ linux/include/linux/pci.h Wed Jan 6 10:07:41 1999
@@ -1055,6 +1055,7 @@
X
X #define PCI_VENDOR_ID_ADAPTEC2 0x9005
X #define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010
+#define PCI_DEVICE_ID_ADAPTEC2_78902 0x0013
X #define PCI_DEVICE_ID_ADAPTEC2_7890 0x001f
X #define PCI_DEVICE_ID_ADAPTEC2_3940U2 0x0050
X #define PCI_DEVICE_ID_ADAPTEC2_3950U2D 0x0051
diff -u --recursive --new-file v2.2.0-pre4/linux/include/linux/sched.h linux/include/linux/sched.h
--- v2.2.0-pre4/linux/include/linux/sched.h Fri Jan 1 12:58:21 1999
+++ linux/include/linux/sched.h Wed Jan 6 10:07:44 1999
@@ -458,6 +458,8 @@
X
X extern void FASTCALL(__wake_up(struct wait_queue ** p, unsigned int mode));
X extern void FASTCALL(sleep_on(struct wait_queue ** p));
+extern long FASTCALL(sleep_on_timeout(struct wait_queue ** p,
+ signed long timeout));
X extern void FASTCALL(interruptible_sleep_on(struct wait_queue ** p));
X extern long FASTCALL(interruptible_sleep_on_timeout(struct wait_queue ** p,
X signed long timeout));
diff -u --recursive --new-file v2.2.0-pre4/linux/include/linux/sound.h linux/include/linux/sound.h
--- v2.2.0-pre4/linux/include/linux/sound.h Wed Sep 9 14:51:13 1998
+++ linux/include/linux/sound.h Mon Jan 4 11:42:43 1999
@@ -2,11 +2,11 @@
X * Sound core interface functions
X */
X
-extern int register_sound_special(struct file_operations *, int);
-extern int register_sound_mixer(struct file_operations *fops);
-extern int register_sound_midi(struct file_operations *fops);
-extern int register_sound_dsp(struct file_operations *fops);
-extern int register_sound_synth(struct file_operations *fops);
+extern int register_sound_special(struct file_operations *fops, int unit);
+extern int register_sound_mixer(struct file_operations *fops, int dev);
+extern int register_sound_midi(struct file_operations *fops, int dev);
+extern int register_sound_dsp(struct file_operations *fops, int dev);
+extern int register_sound_synth(struct file_operations *fops, int dev);
X
X extern void unregister_sound_special(int unit);
X extern void unregister_sound_mixer(int unit);
diff -u --recursive --new-file v2.2.0-pre4/linux/include/linux/swap.h linux/include/linux/swap.h
--- v2.2.0-pre4/linux/include/linux/swap.h Mon Dec 28 15:00:53 1998
+++ linux/include/linux/swap.h Wed Jan 6 10:07:42 1999
@@ -166,12 +166,7 @@
X return 1;
X count = atomic_read(&page->count);
X if (PageSwapCache(page))
- {
- /* PARANOID */
- if (page->inode != &swapper_inode)
- panic("swap cache page has wrong inode\n");
X count += swap_count(page->offset) - 2;
- }
X if (PageFreeAfter(page))
X count--;
X return count > 1;
diff -u --recursive --new-file v2.2.0-pre4/linux/include/linux/sysctl.h linux/include/linux/sysctl.h
--- v2.2.0-pre4/linux/include/linux/sysctl.h Thu Dec 31 10:29:03 1998
+++ linux/include/linux/sysctl.h Mon Jan 4 15:31:35 1999
@@ -207,7 +207,8 @@
X NET_IPV4_ICMP_TIMEEXCEED_RATE=61,
X NET_IPV4_ICMP_PARAMPROB_RATE=62,
X NET_IPV4_ICMP_ECHOREPLY_RATE=63,
- NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES=64
+ NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES=64,
+ NET_IPV4_IGMP_MAX_MEMBERSHIPS=65
X };
X
X enum {
diff -u --recursive --new-file v2.2.0-pre4/linux/include/linux/wavefront.h linux/include/linux/wavefront.h
--- v2.2.0-pre4/linux/include/linux/wavefront.h Thu Sep 17 17:53:38 1998
+++ linux/include/linux/wavefront.h Mon Jan 4 11:42:43 1999
@@ -307,7 +307,7 @@
X UCHAR8 mute:1;
X
X UCHAR8 split_point:7;
- UCHAR8 updown:1;
+ UCHAR8 play_below:1;
X
X UCHAR8 pan_mod_src:2;
X UCHAR8 pan_or_mod:1;
@@ -507,9 +507,16 @@
X
X typedef struct wf_patch_info {
X
+ /* the first two fields are used by the OSS "patch loading" interface
+ only, and are unused by the current user-level library.
+ */
+
X INT16 key; /* Use WAVEFRONT_PATCH here */
X UINT16 devno; /* fill in when sending */
X UCHAR8 subkey; /* WF_ST_{SAMPLE,ALIAS,etc.} */
+
+#define WAVEFRONT_FIND_FREE_SAMPLE_SLOT 999
+
X UINT16 number; /* patch/sample/prog number */
X
X UINT32 size; /* size of any data included in
@@ -548,12 +555,14 @@
X */
X
X typedef struct wavefront_control {
- int devno; /* from /dev/sequencer interface */
X int cmd; /* WFC_* */
X char status; /* return status to user-space */
X unsigned char rbuf[WF_MAX_READ]; /* bytes read from card */
X unsigned char wbuf[WF_MAX_WRITE]; /* bytes written to card */
X } wavefront_control;
+
+#define WFCTL_WFCMD 0x1
+#define WFCTL_LOAD_SPP 0x2
X
X /* Modulator table */
X
diff -u --recursive --new-file v2.2.0-pre4/linux/include/net/ipconfig.h linux/include/net/ipconfig.h
--- v2.2.0-pre4/linux/include/net/ipconfig.h Sun Nov 30 14:00:39 1997
+++ linux/include/net/ipconfig.h Mon Jan 4 15:31:35 1999
@@ -1,5 +1,5 @@
X /*
- * $Id: ipconfig.h,v 1.2 1997/10/17 12:41:16 mj Exp $
+ * $Id: ipconfig.h,v 1.3 1999/01/04 20:13:29 davem Exp $
X *
X * Copyright (C) 1997 Martin Mares
X *
@@ -12,8 +12,10 @@
X extern u32 ic_servaddr;
X extern u32 ic_gateway;
X extern u32 ic_netmask;
-extern int ic_bootp_flag;
-extern int ic_rarp_flag;
X extern int ic_enable;
X extern int ic_host_name_set;
X extern int ic_set_manually;
+extern int ic_proto_enabled;
+
+#define IC_BOOTP 1
+#define IC_RARP 2
diff -u --recursive --new-file v2.2.0-pre4/linux/ipc/util.c linux/ipc/util.c
--- v2.2.0-pre4/linux/ipc/util.c Mon Jan 4 15:08:18 1999
+++ linux/ipc/util.c Mon Jan 4 14:38:48 1999
@@ -13,8 +13,6 @@
X #include <linux/shm.h>
X #include <linux/init.h>
X #include <linux/msg.h>
-#include <asm/ipc.h>
-#include <asm/uaccess.h>
X
X #if defined(CONFIG_SYSVIPC)
X
diff -u --recursive --new-file v2.2.0-pre4/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.2.0-pre4/linux/kernel/ksyms.c Thu Dec 31 10:29:03 1998
+++ linux/kernel/ksyms.c Wed Jan 6 09:41:00 1999
@@ -106,8 +106,10 @@
X EXPORT_SYMBOL(vmtruncate);
X
X /* filesystem internal functions */
+EXPORT_SYMBOL(in_group_p);
X EXPORT_SYMBOL(update_atime);
X EXPORT_SYMBOL(get_super);
+EXPORT_SYMBOL(get_fs_type);
X EXPORT_SYMBOL(getname);
X EXPORT_SYMBOL(__fput);
X EXPORT_SYMBOL(iget);
@@ -128,6 +130,7 @@
X EXPORT_SYMBOL(__mark_inode_dirty);
X EXPORT_SYMBOL(get_empty_filp);
X EXPORT_SYMBOL(init_private_file);
+EXPORT_SYMBOL(filp_open);
X EXPORT_SYMBOL(fput);
X EXPORT_SYMBOL(put_filp);
X EXPORT_SYMBOL(check_disk_change);
@@ -296,6 +299,7 @@
X /* process management */
X EXPORT_SYMBOL(__wake_up);
X EXPORT_SYMBOL(sleep_on);
+EXPORT_SYMBOL(sleep_on_timeout);
X EXPORT_SYMBOL(interruptible_sleep_on);
X EXPORT_SYMBOL(interruptible_sleep_on_timeout);
X EXPORT_SYMBOL(schedule);
diff -u --recursive --new-file v2.2.0-pre4/linux/kernel/sched.c linux/kernel/sched.c
--- v2.2.0-pre4/linux/kernel/sched.c Thu Dec 31 10:29:03 1998
+++ linux/kernel/sched.c Mon Jan 4 10:23:42 1999
@@ -161,8 +161,10 @@
X * In particular, if p1 and p2 both want the kernel
X * lock, there is no point in trying to make them
X * extremely parallel..
+ *
+ * (No lock - lock_depth < 0)
X */
-#define related(p1,p2) ((p1)->lock_depth && (p2)->lock_depth)
+#define related(p1,p2) ((p1)->lock_depth >= 0 && (p2)->lock_depth >= 0)
X
X static inline void reschedule_idle(struct task_struct * p)
X {
@@ -854,56 +856,64 @@
X * Either form may be used in conjunction with "up()".
X *
X */
-static inline int __do_down(struct semaphore * sem, int task_state)
-{
- struct task_struct *tsk = current;
- struct wait_queue wait = { tsk, NULL };
- int ret = 0;
X
- tsk->state = task_state;
- add_wait_queue(&sem->wait, &wait);
+#define DOWN_VAR \
+ struct task_struct *tsk = current; \
+ struct wait_queue wait = { tsk, NULL };
X
- /*
- * Ok, we're set up. sem->count is known to be less than zero
- * so we must wait.
- *
- * We can let go the lock for purposes of waiting.
- * We re-acquire it after awaking so as to protect
- * all semaphore operations.
- *
- * If "up()" is called before we call waking_non_zero() then
- * we will catch it right away. If it is called later then
- * we will have to go through a wakeup cycle to catch it.
- *
- * Multiple waiters contend for the semaphore lock to see
- * who gets to gate through and who has to wait some more.
- */
- for (;;) {
- if (waking_non_zero(sem)) /* are we waking up? */
+#define DOWN_HEAD(task_state) \
+ \
+ \
+ tsk->state = (task_state); \
+ add_wait_queue(&sem->wait, &wait); \
+ \
+ /* \
+ * Ok, we're set up. sem->count is known to be less than zero \
+ * so we must wait. \
+ * \
+ * We can let go the lock for purposes of waiting. \
+ * We re-acquire it after awaking so as to protect \
+ * all semaphore operations. \
+ * \
+ * If "up()" is called before we call waking_non_zero() then \
+ * we will catch it right away. If it is called later then \
+ * we will have to go through a wakeup cycle to catch it. \
+ * \
+ * Multiple waiters contend for the semaphore lock to see \
+ * who gets to gate through and who has to wait some more. \
+ */ \
+ for (;;) { \
+ if (waking_non_zero(sem)) /* are we waking up? */ \
X break; /* yes, exit loop */
X
- if (task_state == TASK_INTERRUPTIBLE && signal_pending(tsk)) {
- ret = -EINTR; /* interrupted */
- atomic_inc(&sem->count); /* give up on down operation */
- break;
- }
-
- schedule();
- tsk->state = task_state;
- }
- tsk->state = TASK_RUNNING;
+#define DOWN_TAIL(task_state) \
+ tsk->state = (task_state); \
+ } \
+ tsk->state = TASK_RUNNING; \
X remove_wait_queue(&sem->wait, &wait);
- return ret;
-}
X
X void __down(struct semaphore * sem)
X {
- __do_down(sem,TASK_UNINTERRUPTIBLE);
+ DOWN_VAR
+ DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+ schedule();
+ DOWN_TAIL(TASK_UNINTERRUPTIBLE)
X }
X
X int __down_interruptible(struct semaphore * sem)
X {
- return __do_down(sem,TASK_INTERRUPTIBLE);
+ DOWN_VAR
+ int ret = 0;
+ DOWN_HEAD(TASK_INTERRUPTIBLE)
+ if (signal_pending(tsk))
+ {
+ ret = -EINTR; /* interrupted */
+ atomic_inc(&sem->count); /* give up on down operation */
+ break;
+ }
+ schedule();
+ DOWN_TAIL(TASK_INTERRUPTIBLE)
+ return ret;
X }
X
X #define SLEEP_ON_VAR \
@@ -954,6 +964,19 @@
X SLEEP_ON_HEAD
X schedule();
X SLEEP_ON_TAIL
+}
+
+long sleep_on_timeout(struct wait_queue **p, long timeout)
+{
+ SLEEP_ON_VAR
+
+ current->state = TASK_UNINTERRUPTIBLE;
+
+ SLEEP_ON_HEAD
+ timeout = schedule_timeout(timeout);
+ SLEEP_ON_TAIL
+
+ return timeout;
X }
X
X void scheduling_functions_end_here(void) { }
diff -u --recursive --new-file v2.2.0-pre4/linux/kernel/sysctl.c linux/kernel/sysctl.c
--- v2.2.0-pre4/linux/kernel/sysctl.c Thu Dec 31 10:29:03 1998
+++ linux/kernel/sysctl.c Mon Jan 4 11:42:43 1999
@@ -44,6 +44,9 @@
X #ifdef CONFIG_CHR_DEV_SG
X extern int sg_big_buff;
X #endif
+#ifdef CONFIG_SYSVIPC
+extern int shmmax;
+#endif
X
X #ifdef __sparc__
X extern char reboot_command [];
@@ -205,6 +208,10 @@
X 0444, NULL, &proc_dointvec},
X {KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int),
X 0644, NULL, &proc_dointvec},
+#ifdef CONFIG_SYSVIPC
+ {KERN_SHMMAX, "shmmax", &shmmax, sizeof (int),
+ 0644, NULL, &proc_dointvec},
+#endif
X {0}
X };
X
diff -u --recursive --new-file v2.2.0-pre4/linux/mm/filemap.c linux/mm/filemap.c
--- v2.2.0-pre4/linux/mm/filemap.c Fri Jan 1 12:58:21 1999
+++ linux/mm/filemap.c Wed Jan 6 09:51:49 1999
@@ -125,10 +125,16 @@
X struct page * page;
X int count;
X
- count = limit >> priority;
+ count = (limit << 1) >> priority;
X
X page = mem_map + clock;
X do {
+ int referenced;
+
+ /* This works even in the presence of PageSkip because
+ * the first two entries at the beginning of a hole will
+ * be marked, not just the first.
+ */
X page++;
X clock++;
X if (clock >= max_mapnr) {
@@ -141,11 +147,9 @@
X clock = page->map_nr;
X }
X
- if (test_and_clear_bit(PG_referenced, &page->flags))
- continue;
-
- /* Decrement count only for non-referenced pages */
X count--;
+ referenced = test_and_clear_bit(PG_referenced, &page->flags);
+
X if (PageLocked(page))
X continue;
X
@@ -156,6 +160,21 @@
X if (atomic_read(&page->count) != 1)
X continue;
X
+ /*
+ * Is it a page swap page? If so, we want to
+ * drop it if it is no longer used, even if it
+ * were to be marked referenced..
+ */
+ if (PageSwapCache(page)) {
+ if (referenced && swap_count(page->offset) != 1)
+ continue;
+ delete_from_swap_cache(page);
+ return 1;
+ }
+
+ if (referenced)
+ continue;
+
X /* Is it a buffer page? */
X if (page->buffers) {
X if (buffer_under_min())
@@ -165,14 +184,10 @@


X return 1;
X }
X

- /* is it a swap-cache or page-cache page? */
+ /* is it a page-cache page? */
X if (page->inode) {
X if (pgcache_under_min())
X continue;
- if (PageSwapCache(page)) {
- delete_from_swap_cache(page);
- return 1;
- }
X remove_inode_page(page);
X return 1;
X }
diff -u --recursive --new-file v2.2.0-pre4/linux/mm/memory.c linux/mm/memory.c
--- v2.2.0-pre4/linux/mm/memory.c Fri Nov 27 13:09:30 1998
+++ linux/mm/memory.c Wed Jan 6 02:18:29 1999
@@ -642,37 +642,47 @@
X page_map = mem_map + MAP_NR(old_page);
X
X /*
- * Do we need to copy?
+ * We can avoid the copy if:
+ * - we're the only user (count == 1)
+ * - the only other user is the swap cache,
+ * and the only swap cache user is itself,
+ * in which case we can remove the page
+ * from the swap cache.
X */
- if (is_page_shared(page_map)) {
+ switch (atomic_read(&page_map->count)) {
+ case 2:
+ if (!PageSwapCache(page_map))
+ break;
+ if (swap_count(page_map->offset) != 1)
+ break;
+ delete_from_swap_cache(page_map);
+ /* FallThrough */
+ case 1:
+ /* We can release the kernel lock now.. */
X unlock_kernel();
- if (!new_page)
- return 0;
X
- if (PageReserved(mem_map + MAP_NR(old_page)))
- ++vma->vm_mm->rss;
- copy_cow_page(old_page,new_page);
- flush_page_to_ram(old_page);
- flush_page_to_ram(new_page);
X flush_cache_page(vma, address);
- set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
- free_page(old_page);
+ set_pte(page_table, pte_mkdirty(pte_mkwrite(pte)));
X flush_tlb_page(vma, address);
+end_wp_page:
+ if (new_page)
+ free_page(new_page);
X return 1;
X }
-
- if (PageSwapCache(page_map))
- delete_from_swap_cache(page_map);
-
- /* We can release the kernel lock now.. */
+
X unlock_kernel();
+ if (!new_page)
+ return 0;
X
+ if (PageReserved(mem_map + MAP_NR(old_page)))
+ ++vma->vm_mm->rss;
+ copy_cow_page(old_page,new_page);
+ flush_page_to_ram(old_page);
+ flush_page_to_ram(new_page);
X flush_cache_page(vma, address);
- set_pte(page_table, pte_mkdirty(pte_mkwrite(pte)));
+ set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
+ free_page(old_page);
X flush_tlb_page(vma, address);
-end_wp_page:
- if (new_page)
- free_page(new_page);
X return 1;
X
X bad_wp_page:
diff -u --recursive --new-file v2.2.0-pre4/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.2.0-pre4/linux/mm/page_alloc.c Mon Jan 4 15:08:18 1999
+++ linux/mm/page_alloc.c Tue Jan 5 17:55:58 1999
@@ -245,6 +245,14 @@
X }
X
X /*
+ * If this is a recursive call, we'd better
+ * do our best to just allocate things without
+ * further thought.
+ */
+ if (current->flags & PF_MEMALLOC)
+ goto ok_to_allocate;
+
+ /*
X * Avoid going back-and-forth between allocating
X * memory and trying to free it. If we get into
X * a bad memory situation, we're better off trying
@@ -271,8 +279,14 @@
X * memory.
X */
X current->trashing_memory = 1;
- if (!try_to_free_pages(gfp_mask, SWAP_CLUSTER_MAX) && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
- goto nopage;
+ {
+ int freed;
+ current->flags |= PF_MEMALLOC;
+ freed = try_to_free_pages(gfp_mask, SWAP_CLUSTER_MAX);
+ current->flags &= ~PF_MEMALLOC;
+ if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
+ goto nopage;
+ }
X }
X ok_to_allocate:
X spin_lock_irqsave(&page_alloc_lock, flags);
diff -u --recursive --new-file v2.2.0-pre4/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.2.0-pre4/linux/mm/vmscan.c Mon Jan 4 15:08:18 1999
+++ linux/mm/vmscan.c Wed Jan 6 02:03:12 1999
@@ -20,13 +20,6 @@
X
X #include <asm/pgtable.h>
X
-/*
- * The wait queue for waking up the pageout daemon:
- */
-static struct task_struct * kswapd_task = NULL;
-
-static void init_swap_timer(void);
-
X /*
X * The swap-out functions return 1 if they successfully
X * threw something out, and we got a free page. It returns
@@ -38,7 +31,7 @@
X * using a process that no longer actually exists (it might
X * have died while we slept).
X */
-static inline int try_to_swap_out(struct task_struct * tsk, struct vm_area_struct* vma,
+static int try_to_swap_out(struct task_struct * tsk, struct vm_area_struct* vma,
X unsigned long address, pte_t * page_table, int gfp_mask)
X {
X pte_t pte;
@@ -59,50 +52,6 @@
X || ((gfp_mask & __GFP_DMA) && !PageDMA(page_map)))
X return 0;
X
- /*
- * Deal with page aging. There are several special cases to
- * consider:
- *
- * Page has been accessed, but is swap cached. If the page is
- * getting sufficiently "interesting" --- its age is getting
- * high --- then if we are sufficiently short of free swap
- * pages, then delete the swap cache. We can only do this if
- * the swap page's reference count is one: ie. there are no
- * other references to it beyond the swap cache (as there must
- * still be PTEs pointing to it if count > 1).
- *
- * If the page has NOT been touched, and its age reaches zero,
- * then we are swapping it out:
- *
- * If there is already a swap cache page for this page, then
- * another process has already allocated swap space, so just
- * dereference the physical page and copy in the swap entry
- * from the swap cache.
- *
- * Note, we rely on all pages read in from swap either having
- * the swap cache flag set, OR being marked writable in the pte,
- * but NEVER BOTH. (It IS legal to be neither cached nor dirty,
- * however.)
- *
- * -- Stephen Tweedie 1998 */
-
- if (PageSwapCache(page_map)) {
- if (pte_write(pte)) {
- struct page *found;
- printk ("VM: Found a writable swap-cached page!\n");
- /* Try to diagnose the problem ... */
- found = find_page(&swapper_inode, page_map->offset);
- if (found) {
- printk("page=%p@%08lx, found=%p, count=%d\n",
- page_map, page_map->offset,
- found, atomic_read(&found->count));
- __free_page(found);
- } else
- printk ("Spurious, page not in cache\n");


- return 0;
- }
- }
-

X if (pte_young(pte)) {
X /*
X * Transfer the "accessed" bit from the page
@@ -110,109 +59,101 @@
X */
X set_pte(page_table, pte_mkold(pte));
X set_bit(PG_referenced, &page_map->flags);
-
- /*
- * We should test here to see if we want to recover any
- * swap cache page here. We do this if the page seeing
- * enough activity, AND we are sufficiently low on swap
- *
- * We need to track both the number of available swap
- * pages and the total number present before we can do
- * this...
- */


X return 0;
X }
X

- if (pte_dirty(pte)) {
- if (vma->vm_ops && vma->vm_ops->swapout) {
- pid_t pid = tsk->pid;
- vma->vm_mm->rss--;
- if (vma->vm_ops->swapout(vma, address - vma->vm_start + vma->vm_offset, page_table))
- kill_proc(pid, SIGBUS, 1);
- } else {
- /*
- * This is a dirty, swappable page. First of all,
- * get a suitable swap entry for it, and make sure
- * we have the swap cache set up to associate the
- * page with that swap entry.
- */
- entry = in_swap_cache(page_map);
- if (!entry) {
- entry = get_swap_page();
- if (!entry)
- return 0; /* No swap space left */
- }
-
- vma->vm_mm->rss--;
- tsk->nswap++;
- flush_cache_page(vma, address);
- set_pte(page_table, __pte(entry));
- flush_tlb_page(vma, address);
- swap_duplicate(entry);
-
- /* Now to write back the page. We have two
- * cases: if the page is already part of the
- * swap cache, then it is already on disk. Just
- * free the page and return (we release the swap
- * cache on the last accessor too).
- *
- * If we have made a new swap entry, then we
- * start the write out to disk. If the page is
- * shared, however, we still need to keep the
- * copy in memory, so we add it to the swap
- * cache. */
- if (PageSwapCache(page_map)) {
- __free_page(page_map);
- return (atomic_read(&page_map->count) == 0);
- }
- add_to_swap_cache(page_map, entry);
- /* We checked we were unlocked way up above, and we
- have been careful not to stall until here */
- set_bit(PG_locked, &page_map->flags);
- /* OK, do a physical write to swap. */
- rw_swap_page(WRITE, entry, (char *) page, (gfp_mask & __GFP_WAIT));
- }
- /* Now we can free the current physical page. We also
- * free up the swap cache if this is the last use of the
- * page. Note that there is a race here: the page may
- * still be shared COW by another process, but that
- * process may exit while we are writing out the page
- * asynchronously. That's no problem, shrink_mmap() can
- * correctly clean up the occassional unshared page
- * which gets left behind in the swap cache. */
+ /*
+ * Is the page already in the swap cache? If so, then
+ * we can just drop our reference to it without doing
+ * any IO - it's already up-to-date on disk.
+ *
+ * Return 0, as we didn't actually free any real
+ * memory, and we should just continue our scan.
+ */
+ if (PageSwapCache(page_map)) {
+ entry = page_map->offset;
+ swap_duplicate(entry);
+ set_pte(page_table, __pte(entry));
+drop_pte:
+ vma->vm_mm->rss--;
+ tsk->nswap++;
+ flush_tlb_page(vma, address);
X __free_page(page_map);
- return 1; /* we slept: the process may not exist any more */


+ return 0;
X }
X

- /* The page was _not_ dirty, but still has a zero age. It must
- * already be uptodate on disk. If it is in the swap cache,
- * then we can just unlink the page now. Remove the swap cache
- * too if this is the last user. */
- if ((entry = in_swap_cache(page_map))) {
+ /*
+ * Is it a clean page? Then it must be recoverable
+ * by just paging it in again, and we can just drop
+ * it..
+ *
+ * However, this won't actually free any real
+ * memory, as the page will just be in the page cache
+ * somewhere, and as such we should just continue
+ * our scan.
+ *
+ * Basically, this just makes it possible for us to do
+ * some real work in the future in "shrink_mmap()".
+ */
+ if (!pte_dirty(pte)) {
+ pte_clear(page_table);
+ goto drop_pte;
+ }
+
+ /*
+ * Ok, it's really dirty. That means that
+ * we should either create a new swap cache
+ * entry for it, or we should write it back
+ * to its own backing store.
+ *
+ * Note that in neither case do we actually
+ * know that we make a page available, but
+ * as we potentially sleep we can no longer
+ * continue scanning, so we migth as well
+ * assume we free'd something.
+ *
+ * NOTE NOTE NOTE! This should just set a
+ * dirty bit in page_map, and just drop the
+ * pte. All the hard work would be done by
+ * shrink_mmap().
+ *
+ * That would get rid of a lot of problems.
+ */
+ if (vma->vm_ops && vma->vm_ops->swapout) {
+ pid_t pid = tsk->pid;
X vma->vm_mm->rss--;
- flush_cache_page(vma, address);
- set_pte(page_table, __pte(entry));
- flush_tlb_page(vma, address);
- swap_duplicate(entry);
+ if (vma->vm_ops->swapout(vma, address - vma->vm_start + vma->vm_offset, page_table))
+ kill_proc(pid, SIGBUS, 1);
X __free_page(page_map);
- return (atomic_read(&page_map->count) == 0);
- }
- /*
- * A clean page to be discarded? Must be mmap()ed from
- * somewhere. Unlink the pte, and tell the filemap code to
- * discard any cached backing page if this is the last user.
- */
- if (PageSwapCache(page_map)) {
- printk ("VM: How can this page _still_ be cached?");
- return 0;
+ return 1;
X }
+
+ /*
+ * This is a dirty, swappable page. First of all,
+ * get a suitable swap entry for it, and make sure
+ * we have the swap cache set up to associate the
+ * page with that swap entry.
+ */
+ entry = get_swap_page();
+ if (!entry)
+ return 0; /* No swap space left */
+
X vma->vm_mm->rss--;
+ tsk->nswap++;
X flush_cache_page(vma, address);
- pte_clear(page_table);
+ set_pte(page_table, __pte(entry));
X flush_tlb_page(vma, address);
- entry = (atomic_read(&page_map->count) == 1);
+ swap_duplicate(entry); /* One for the process, one for the swap cache */
+ add_to_swap_cache(page_map, entry);
+ /* We checked we were unlocked way up above, and we
+ have been careful not to stall until here */
+ set_bit(PG_locked, &page_map->flags);
+
+ /* OK, do a physical asynchronous write to swap. */
+ rw_swap_page(WRITE, entry, (char *) page, 0);
+
X __free_page(page_map);
- return entry;
+ return 1;
X }
X
X /*
@@ -409,11 +350,7 @@
X goto out;
X }
X
- /*
- * Nonzero means we cleared out something, but only "1" means
- * that we actually free'd up a page as a result.
- */
- if (swap_out_process(pbest, gfp_mask) == 1)
+ if (swap_out_process(pbest, gfp_mask))
X return 1;
X }
X out:
@@ -441,71 +378,36 @@
X printk ("Starting kswapd v%.*s\n", i, s);
X }
X
-#define free_memory(fn) \
- count++; do { if (!--count) goto done; } while (fn)
-
-static int kswapd_free_pages(int kswapd_state)
-{
- unsigned long end_time;
-
- /* Always trim SLAB caches when memory gets low. */
- kmem_cache_reap(0);
-
- /* max one hundreth of a second */
- end_time = jiffies + (HZ-1)/100;
- do {
- int priority = 8;
- int count = pager_daemon.swap_cluster;
-
- switch (kswapd_state) {
- do {
- default:
- free_memory(shrink_mmap(priority, 0));
- free_memory(swap_out(priority, 0));
- kswapd_state++;
- case 1:
- free_memory(shm_swap(priority, 0));
- shrink_dcache_memory(priority, 0);
- kswapd_state = 0;
- } while (--priority >= 0);
- return kswapd_state;
- }
-done:
- if (nr_free_pages > freepages.high + pager_daemon.swap_cluster)
- break;
- } while (time_before_eq(jiffies,end_time));
- return kswapd_state;
-}
-
X /*
- * The background pageout daemon.
- * Started as a kernel thread from the init process.
+ * The background pageout daemon, started as a kernel thread
+ * from the init process.
+ *
+ * This basically executes once a second, trickling out pages
+ * so that we have _some_ free memory available even if there
+ * is no other activity that frees anything up. This is needed
+ * for things like routing etc, where we otherwise might have
+ * all activity going on in asynchronous contexts that cannot
+ * page things out.
+ *
+ * If there are applications that are active memory-allocators
+ * (most normal use), this basically shouldn't matter.
X */
X int kswapd(void *unused)
X {
X current->session = 1;
X current->pgrp = 1;
X strcpy(current->comm, "kswapd");
- sigfillset(&current->blocked);
-
- /*
- * As a kernel thread we want to tamper with system buffers
- * and other internals and thus be subject to the SMP locking
- * rules. (On a uniprocessor box this does nothing).
- */
- lock_kernel();
X
X /*
- * Set the base priority to something smaller than a
- * regular process. We will scale up the priority
- * dynamically depending on how much memory we need.
+ * Hey, if somebody wants to kill us, be our guest.
+ * Don't come running to mama if things don't work.
X */
- current->priority = (DEF_PRIORITY * 2) / 3;
-
+ siginitsetinv(&current->blocked, sigmask(SIGKILL));
+
X /*
X * Tell the memory management that we're a "memory allocator",
X * and that if we need more memory we should get access to it
- * regardless (see "try_to_free_pages()"). "kswapd" should
+ * regardless (see "__get_free_pages()"). "kswapd" should
X * never get caught in the normal page freeing logic.
X *
X * (Kswapd normally doesn't need memory anyway, but sometimes
@@ -516,21 +418,23 @@
X */
X current->flags |= PF_MEMALLOC;
X
- init_swap_timer();
- kswapd_task = current;
X while (1) {
- int state = 0;
-
+ if (signal_pending(current))
+ break;


X current->state = TASK_INTERRUPTIBLE;

- flush_signals(current);
X run_task_queue(&tq_disk);
- schedule();
- swapstats.wakeups++;
- state = kswapd_free_pages(state);
+ schedule_timeout(HZ);
+
+ /*
+ * kswapd isn't even meant to keep up with anything,
+ * so just a few pages per second is plenty: the only
+ * point is to make sure that the system doesn't stay
+ * forever in a really bad memory squeeze.
+ */
+ if (nr_free_pages < freepages.high)
+ try_to_free_pages(0, 16);
X }
- /* As if we could ever get here - maybe we want to make this killable */
- kswapd_task = NULL;
- unlock_kernel();


+
X return 0;
X }
X

@@ -539,111 +443,42 @@
X * now we need this so that we can do page allocations
X * without holding the kernel lock etc.
X *
- * The "PF_MEMALLOC" flag protects us against recursion:
- * if we need more memory as part of a swap-out effort we
- * will just silently return "success" to tell the page
- * allocator to accept the allocation.
- *
X * We want to try to free "count" pages, and we need to
X * cluster them so that we get good swap-out behaviour. See
X * the "free_memory()" macro for details.
X */
X int try_to_free_pages(unsigned int gfp_mask, int count)
X {
- int retval;


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre5 failed'
fi

echo 'End of part 07'
echo 'File patch-2.2.0-pre5 is continued in part 08'
echo 08 > _shar_seq_.tmp

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

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to
Archive-name: v2.1/patch-2.2.0-pre5/part09

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


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

+static int __init ic_dynamic(void)
X {
X int retries;
X unsigned long timeout, jiff;
X unsigned long start_jiffies;
+ int do_rarp = ic_proto_have_if & IC_RARP;
+ int do_bootp = ic_proto_have_if & IC_BOOTP;
X
X /*
X * If neither BOOTP nor RARP was selected, return with an error. This
@@ -805,30 +701,22 @@
X * sing, and without BOOTP and RARP we are not able to get that in-
X * formation.
X */
- if (!ic_bootp_flag && !ic_rarp_flag) {
+ if (!ic_proto_enabled) {
X printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n");
X return -1;
X }
X
X #ifdef CONFIG_IP_PNP_BOOTP
- if (ic_bootp_flag && !bootp_dev_count) {
+ if ((ic_proto_enabled ^ ic_proto_have_if) & IC_BOOTP)
X printk(KERN_ERR "BOOTP: No suitable device found.\n");
- ic_bootp_flag = 0;
- }
-#else
- ic_bootp_flag = 0;
X #endif
X
X #ifdef CONFIG_IP_PNP_RARP
- if (ic_rarp_flag && !rarp_dev_count) {
+ if ((ic_proto_enabled ^ ic_proto_have_if) & IC_RARP)
X printk(KERN_ERR "RARP: No suitable device found.\n");
- ic_rarp_flag = 0;
- }
-#else
- ic_rarp_flag = 0;
X #endif
X
- if (!ic_bootp_flag && !ic_rarp_flag)
+ if (!ic_proto_have_if)
X /* Error message already printed */
X return -1;
X
@@ -836,14 +724,12 @@
X * Setup RARP and BOOTP protocols
X */
X #ifdef CONFIG_IP_PNP_RARP
- if (ic_rarp_flag)
+ if (do_rarp)
X ic_rarp_init();
X #endif
X #ifdef CONFIG_IP_PNP_BOOTP
- if (ic_bootp_flag && ic_bootp_init() < 0) {
- ic_bootp_cleanup();
- return -1;
- }
+ if (do_bootp)
+ ic_bootp_init();


X #endif
X
X /*

@@ -855,36 +741,26 @@
X * applies.. - AC]
X */
X printk(KERN_NOTICE "Sending %s%s%s requests...",
- ic_bootp_flag ? "BOOTP" : "",
- ic_bootp_flag && ic_rarp_flag ? " and " : "",
- ic_rarp_flag ? "RARP" : "");
+ do_bootp ? "BOOTP" : "",
+ do_bootp && do_rarp ? " and " : "",
+ do_rarp ? "RARP" : "");
X start_jiffies = jiffies;
X retries = CONF_RETRIES;
X get_random_bytes(&timeout, sizeof(timeout));
X timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
X for(;;) {
X #ifdef CONFIG_IP_PNP_BOOTP
- if (ic_bootp_flag && ic_bootp_send(jiffies - start_jiffies) < 0) {
- printk(" BOOTP failed!\n");
- ic_bootp_cleanup();
- ic_bootp_flag = 0;
- if (!ic_rarp_flag)
- break;
- }
+ if (do_bootp)
+ ic_bootp_send(jiffies - start_jiffies);
X #endif
X #ifdef CONFIG_IP_PNP_RARP
- if (ic_rarp_flag)
+ if (do_rarp)
X ic_rarp_send();
X #endif
X printk(".");
X jiff = jiffies + timeout;
X while (jiffies < jiff && !ic_got_reply)
-#ifdef CONFIG_IP_PNP_BOOTP
- if (ic_bootp_flag)
- ic_bootp_recv();
-#else
X ;
-#endif
X if (ic_got_reply) {
X printk(" OK\n");
X break;
@@ -899,11 +775,11 @@
X }
X
X #ifdef CONFIG_IP_PNP_RARP
- if (ic_rarp_flag)
+ if (do_rarp)
X ic_rarp_cleanup();
X #endif
X #ifdef CONFIG_IP_PNP_BOOTP
- if (ic_bootp_flag)
+ if (do_bootp)
X ic_bootp_cleanup();
X #endif
X
@@ -911,7 +787,7 @@
X return -1;
X
X printk("IP-Config: Got %s answer from %s, ",
- (ic_got_reply == IC_GOT_BOOTP) ? "BOOTP" : "RARP",
+ (ic_got_reply & IC_BOOTP) ? "BOOTP" : "RARP",
X in_ntoa(ic_servaddr));
X printk("my address is %s\n", in_ntoa(ic_myaddr));
X
@@ -924,7 +800,7 @@
X * IP Autoconfig dispatcher.
X */
X
-__initfunc(int ip_auto_config(void))
+int __init ip_auto_config(void)
X {
X if (!ic_enable)
X return 0;
@@ -1000,25 +876,44 @@
X * <device> - use all available devices
X * <bootp|rarp|both|off> - use both protocols to determine my own address
X */
-__initfunc(void ip_auto_config_setup(char *addrs, int *ints))
+static int __init ic_proto_name(char *name)
+{
+ if (!strcmp(name, "off")) {
+ ic_proto_enabled = 0;
+ return 1;
+ }
+#ifdef CONFIG_IP_PNP_BOOTP
+ else if (!strcmp(name, "bootp")) {
+ ic_proto_enabled &= ~IC_RARP;
+ return 1;
+ }
+#endif
+#ifdef CONFIG_IP_PNP_RARP
+ else if (!strcmp(name, "rarp")) {
+ ic_proto_enabled &= ~IC_BOOTP;
+ return 1;
+ }
+#endif
+#ifdef CONFIG_IP_PNP_DYNAMIC
+ else if (!strcmp(name, "both")) {
+ return 1;
+ }
+#endif


+ return 0;
+}
+

+void __init ip_auto_config_setup(char *addrs, int *ints)
X {
X char *cp, *ip, *dp;
X int num = 0;
X
X ic_set_manually = 1;
-
- if (!strcmp(addrs, "bootp")) {
- ic_rarp_flag = 0;
- return;
- } else if (!strcmp(addrs, "rarp")) {
- ic_bootp_flag = 0;
- return;
- } else if (!strcmp(addrs, "both")) {
- return;
- } else if (!strcmp(addrs, "off")) {
+ if (!strcmp(addrs, "off")) {
X ic_enable = 0;
X return;
X }
+ if (ic_proto_name(addrs))
+ return;
X
X /* Parse the whole string */
X ip = addrs;
@@ -1059,12 +954,7 @@
X user_dev_name[IFNAMSIZ-1] = '\0';
X break;
X case 6:
- if (!strcmp(ip, "rarp"))
- ic_bootp_flag = 0;
- else if (!strcmp(ip, "bootp"))
- ic_rarp_flag = 0;
- else if (strcmp(ip, "both"))
- ic_bootp_flag = ic_rarp_flag = 0;
+ ic_proto_name(ip);
X break;
X }
X }
diff -u --recursive --new-file v2.2.0-pre4/linux/net/ipv4/route.c linux/net/ipv4/route.c
--- v2.2.0-pre4/linux/net/ipv4/route.c Thu Dec 31 10:29:03 1998
+++ linux/net/ipv4/route.c Mon Jan 4 15:31:35 1999
@@ -5,7 +5,7 @@
X *
X * ROUTE - implementation of the IP router.
X *
- * Version: $Id: route.c,v 1.58 1998/10/03 09:37:50 davem Exp $
+ * Version: $Id: route.c,v 1.60 1999/01/04 20:14:52 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -949,10 +949,6 @@
X
X if (BADCLASS(daddr) || ZERONET(daddr) || LOOPBACK(daddr))
X goto martian_destination;
-
- /* Accept anything arriving at 0.0.0.0 */
- if (in_dev->ifa_list && in_dev->ifa_list->ifa_local == 0)
- goto local_input;
X
X /*
X * Now we are ready to route packet.
diff -u --recursive --new-file v2.2.0-pre4/linux/net/ipv4/sysctl_net_ipv4.c linux/net/ipv4/sysctl_net_ipv4.c
--- v2.2.0-pre4/linux/net/ipv4/sysctl_net_ipv4.c Tue Dec 22 14:16:59 1998
+++ linux/net/ipv4/sysctl_net_ipv4.c Mon Jan 4 15:31:35 1999
@@ -1,7 +1,7 @@
X /*
X * sysctl_net_ipv4.c: sysctl interface to net IPV4 subsystem.
X *
- * $Id: sysctl_net_ipv4.c,v 1.36 1998/10/21 05:26:59 davem Exp $
+ * $Id: sysctl_net_ipv4.c,v 1.38 1999/01/02 16:51:48 davem Exp $
X *
X * Begun April 1, 1996, Mike Shaver.
X * Added /proc/sys/net/ipv4 directory entry (empty =) ). [MS]
@@ -67,6 +67,9 @@
X extern int sysctl_icmp_paramprob_time;
X extern int sysctl_icmp_echoreply_time;
X
+/* From igmp.c */
+extern int sysctl_igmp_max_memberships;
+
X int tcp_retr1_max = 255;
X
X struct ipv4_config ipv4_config;
@@ -177,6 +180,10 @@
X {NET_IPV4_ICMP_ECHOREPLY_RATE, "icmp_echoreply_rate",
X &sysctl_icmp_echoreply_time, sizeof(int), 0644, NULL, &proc_dointvec},
X {NET_IPV4_ROUTE, "route", NULL, 0, 0555, ipv4_route_table},
+#ifdef CONFIG_IP_MULTICAST
+ {NET_IPV4_IGMP_MAX_MEMBERSHIPS, "igmp_max_memberships",
+ &sysctl_igmp_max_memberships, sizeof(int), 0644, NULL, &proc_dointvec},


+#endif
X {0}
X };
X

diff -u --recursive --new-file v2.2.0-pre4/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- v2.2.0-pre4/linux/net/ipv4/tcp_input.c Fri Jan 1 12:58:21 1999
+++ linux/net/ipv4/tcp_input.c Mon Jan 4 15:31:35 1999
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_input.c,v 1.143 1998/12/20 20:20:20 davem Exp $
+ * Version: $Id: tcp_input.c,v 1.145 1999/01/04 20:49:11 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -301,7 +301,7 @@
X /* The retransmission queue is always in order, so
X * we can short-circuit the walk early.
X */
- if(after(TCP_SKB_CB(skb)->seq, start_seq))
+ if(after(TCP_SKB_CB(skb)->seq, end_seq))
X break;
X
X /* We play conservative, we don't allow SACKS to partially
@@ -1170,7 +1170,7 @@
X /* Zap SWALK, by moving every further SACK up by one slot.
X * Decrease num_sacks.
X */
- for(this_sack += 1; this_sack < num_sacks-1; this_sack++, swalk++) {
+ for(; this_sack < num_sacks-1; this_sack++, swalk++) {
X struct tcp_sack_block *next = (swalk + 1);
X swalk->start_seq = next->start_seq;
X swalk->end_seq = next->end_seq;
diff -u --recursive --new-file v2.2.0-pre4/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.2.0-pre4/linux/net/ipv4/tcp_ipv4.c Thu Dec 31 10:29:03 1998
+++ linux/net/ipv4/tcp_ipv4.c Mon Jan 4 15:31:35 1999
@@ -5,7 +5,7 @@
X *
X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_ipv4.c,v 1.163 1998/11/30 15:24:22 davem Exp $
+ * Version: $Id: tcp_ipv4.c,v 1.164 1999/01/04 20:36:55 davem Exp $
X *
X * IPv4 specific functions
X *
@@ -1642,14 +1642,15 @@
X skb->csum = csum_partial((char *)th, len, 0);
X case CHECKSUM_HW:
X if (tcp_v4_check(th,len,skb->nh.iph->saddr,skb->nh.iph->daddr,skb->csum)) {
- printk(KERN_DEBUG "TCPv4 bad checksum from %d.%d.%d.%d:%04x to %d.%d.%d.%d:%04x, "
- "len=%d/%d/%d\n",
- NIPQUAD(skb->nh.iph->saddr),
- ntohs(th->source),
- NIPQUAD(skb->nh.iph->daddr),
- ntohs(th->dest),
- len, skb->len,
- ntohs(skb->nh.iph->tot_len));
+ NETDEBUG(printk(KERN_DEBUG "TCPv4 bad checksum "
+ "from %d.%d.%d.%d:%04x to %d.%d.%d.%d:%04x, "
+ "len=%d/%d/%d\n",
+ NIPQUAD(skb->nh.iph->saddr),
+ ntohs(th->source),
+ NIPQUAD(skb->nh.iph->daddr),
+ ntohs(th->dest),
+ len, skb->len,
+ ntohs(skb->nh.iph->tot_len)));
X bad_packet:
X tcp_statistics.TcpInErrs++;
X goto discard_it;
diff -u --recursive --new-file v2.2.0-pre4/linux/net/ipv6/af_inet6.c linux/net/ipv6/af_inet6.c
--- v2.2.0-pre4/linux/net/ipv6/af_inet6.c Mon Dec 28 15:00:53 1998
+++ linux/net/ipv6/af_inet6.c Mon Jan 4 15:31:35 1999
@@ -7,7 +7,7 @@
X *
X * Adapted from linux/net/ipv4/af_inet.c
X *
- * $Id: af_inet6.c,v 1.39 1998/10/03 09:38:23 davem Exp $
+ * $Id: af_inet6.c,v 1.41 1999/01/02 16:51:50 davem Exp $
X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License
@@ -502,7 +502,7 @@
X __this_module.can_unload = &ipv6_unload;
X #endif
X
- printk(KERN_INFO "IPv6 v0.2 for NET3.037\n");
+ printk(KERN_INFO "IPv6 v0.8 for NET4.0\n");
X
X if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb))
X {
diff -u --recursive --new-file v2.2.0-pre4/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- v2.2.0-pre4/linux/net/ipx/af_ipx.c Mon Dec 28 15:00:53 1998
+++ linux/net/ipx/af_ipx.c Mon Jan 4 15:31:35 1999
@@ -2456,7 +2456,7 @@
X proc_net_register(&ipx_rt_procinfo);
X #endif
X
- printk(KERN_INFO "Swansea University Computer Society IPX 0.38 for NET3.037\n");
+ printk(KERN_INFO "NET4: Linux IPX 0.38 for NET4.0\n");
X printk(KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
X }
X
diff -u --recursive --new-file v2.2.0-pre4/linux/net/ipx/af_spx.c linux/net/ipx/af_spx.c
--- v2.2.0-pre4/linux/net/ipx/af_spx.c Fri Jan 1 12:58:21 1999
+++ linux/net/ipx/af_spx.c Mon Jan 4 15:31:35 1999
@@ -886,7 +886,7 @@
X
X /* route socket(PF_IPX, SOCK_SEQPACKET) calls through spx_create() */
X
- printk(KERN_INFO "Sequenced Packet eXchange (SPX) 0.02 for Linux NET3.037\n");
+ printk(KERN_INFO "NET4: Sequenced Packet eXchange (SPX) 0.02 for Linux NET4.0\n");
X return;
X }
X
diff -u --recursive --new-file v2.2.0-pre4/linux/net/lapb/lapb_iface.c linux/net/lapb/lapb_iface.c
--- v2.2.0-pre4/linux/net/lapb/lapb_iface.c Mon Jul 7 08:19:59 1997
+++ linux/net/lapb/lapb_iface.c Mon Jan 4 15:31:35 1999
@@ -403,7 +403,7 @@
X
X __initfunc(void lapb_proto_init(struct net_proto *pro))
X {
- printk(KERN_INFO "LAPB for Linux. Version 0.01 for Linux NET3.038 (Linux 2.1)\n");
+ printk(KERN_INFO "NET4: LAPB for Linux. Version 0.01 for NET4.0\n");


X }
X
X #ifdef MODULE

diff -u --recursive --new-file v2.2.0-pre4/linux/net/socket.c linux/net/socket.c
--- v2.2.0-pre4/linux/net/socket.c Fri Nov 27 13:09:31 1998
+++ linux/net/socket.c Mon Jan 4 15:31:35 1999
@@ -1466,7 +1466,8 @@


X {
X int i;
X

- printk(KERN_INFO "Swansea University Computer Society NET3.039 for Linux 2.1\n");
+ printk(KERN_INFO "Linux NET4.0 for Linux 2.2\n");
+ printk(KERN_INFO "Based upon Swansea University Computer Society NET3.039\n");
X
X /*
X * Initialize all address (protocol) families.
diff -u --recursive --new-file v2.2.0-pre4/linux/net/unix/af_unix.c linux/net/unix/af_unix.c
--- v2.2.0-pre4/linux/net/unix/af_unix.c Mon Oct 5 13:13:49 1998
+++ linux/net/unix/af_unix.c Mon Jan 4 15:31:35 1999
@@ -8,7 +8,7 @@
X * as published by the Free Software Foundation; either version
X * 2 of the License, or (at your option) any later version.
X *
- * Version: $Id: af_unix.c,v 1.71 1998/10/03 09:39:05 davem Exp $
+ * Version: $Id: af_unix.c,v 1.72 1998/11/21 06:50:00 davem Exp $
X *
X * Fixes:
X * Linus Torvalds : Assorted bug cures.
@@ -1536,7 +1536,7 @@
X struct sk_buff *dummy_skb;
X struct proc_dir_entry *ent;
X
- printk(KERN_INFO "NET3: Unix domain sockets 0.16 for Linux NET3.038.\n");
+ printk(KERN_INFO "NET4: Unix domain sockets 1.0 for Linux NET4.0.\n");
X if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb))
X {
X printk(KERN_CRIT "unix_proto_init: panic\n");
diff -u --recursive --new-file v2.2.0-pre4/linux/scripts/ksymoops/Makefile linux/scripts/ksymoops/Makefile
--- v2.2.0-pre4/linux/scripts/ksymoops/Makefile Wed Dec 31 16:00:00 1969
+++ linux/scripts/ksymoops/Makefile Tue Jan 5 11:13:56 1999
@@ -0,0 +1,79 @@
+# Description file for ksymoops
+
+# Thu Nov 26 16:37:46 EST 1998
+# Version 0.6c
+# Add -c option.
+
+# Tue Nov 3 02:31:01 EST 1998
+# Version 0.6
+# Read lsmod (/proc/modules).
+# Add Makefile defaults for vmlinux, ksyms, objects, System.map, lsmod.
+# Upper case variables.
+# Convert from a.out to bfd, using same format as ksymoops.
+
+DEFS = Makefile ksymoops.h
+
+# Defaults for vmlinux, ksyms, objects, lsmod, System.map. Externalised so
+# distributions can tweak to suit their own file system layout.
+
+# To default to not reading a source, set to any empty string.
+# To default to reading a source, supply a quoted and escaped string.
+
+# If the string contains *r (*m, *n, *s) then it is replaced at run time by
+# the current value of `uname -r` (-m, -n, -s). '*' was chosen as something
+# that rarely appears in filenames and does not cause problems like '%' or '$'.
+
+DEF_VMLINUX = # default no vmlinux
+DEF_OBJECTS = \"/lib/modules/*r/\" # default current modules
+DEF_KSYMS = \"/proc/ksyms\" # default current ksyms
+DEF_LSMOD = \"/proc/modules\" # default current lsmod
+DEF_MAP = \"/usr/src/linux/System.map\" # default current map
+DEF_CODE_BYTES = 1 # default bytes per code unit
+
+# RedHat users might want defaults like these
+# DEF_MAP = \"/boot/System.map-*r\"
+# DEF_OBJECTS = \"/boot/module-info-*r\"
+
+PROGS = ksymoops
+
+CC=gcc
+CFLAGS = -Dlinux \
+ -Wall \
+ -Wno-conversion \
+ -Waggregate-return \
+ -Wstrict-prototypes \
+ -Wmissing-prototypes \
+ $(DEBUG)
+
+ifneq ($(strip $(DEF_VMLINUX)),)
+ CFLAGS += -DDEF_VMLINUX=$(strip $(DEF_VMLINUX))
+endif
+ifneq ($(strip $(DEF_OBJECTS)),)
+ CFLAGS += -DDEF_OBJECTS=$(strip $(DEF_OBJECTS))
+endif
+ifneq ($(strip $(DEF_KSYMS)),)
+ CFLAGS += -DDEF_KSYMS=$(strip $(DEF_KSYMS))
+endif
+ifneq ($(strip $(DEF_LSMOD)),)
+ CFLAGS += -DDEF_LSMOD=$(strip $(DEF_LSMOD))
+endif
+ifneq ($(strip $(DEF_MAP)),)
+ CFLAGS += -DDEF_MAP=$(strip $(DEF_MAP))
+endif
+
+CFLAGS += -DDEF_CODE_BYTES=$(strip $(DEF_CODE_BYTES))
+
+OBJECTS = io.o ksyms.o ksymoops.o map.o misc.o object.o oops.o re.o symbol.o
+
+all: $(PROGS)
+
+: $(OBJECTS)
+
+$(OBJECTS): $(DEFS)
+
+$(PROGS): %: %.o $(DEFS) $(OBJECTS)
+ $(CC) $(OBJECTS) $(CFLAGS) -lbfd -liberty -o $@
+ -@size $@
+
+clean:
+ rm -f core *.o $(PROGS)
diff -u --recursive --new-file v2.2.0-pre4/linux/scripts/ksymoops/README linux/scripts/ksymoops/README
--- v2.2.0-pre4/linux/scripts/ksymoops/README Wed Dec 31 16:00:00 1969
+++ linux/scripts/ksymoops/README Tue Jan 5 11:13:56 1999
@@ -0,0 +1,395 @@
+ ksymoops.
+
+ Read a kernel Oops file and make the best stab at converting the code to
+ instructions and mapping stack values to kernel symbols.
+
+ Copyright Keith Owens <ka...@ocs.com.au>.
+ Released under the GNU Public Licence, Version 2.
+
+ To compile, simply type "make" in the ksymoops directory.
+
+ TESTERS WANTED.
+
+ ksymoops handles ix86. It appears to handle Alpha, Sparc, M68K, PPC,
+ MIPS but I have no machine to test on. I would appreciate feedback
+ from users of non ix86 machines. In particular, it would be nice if
+ you could run
+
+ ksymoops -VMO -k /proc/ksyms -dd <oops.file >/tmp/ksymoops.log 2>&1
+
+ and mail /tmp/ksymoops.log to ka...@ocs.com.au
+
+ TODO:
+ Clean up these docs.
+ Tweak System.map to include arch information.
+ Tweak modutils to log at least one symbol for each module loaded,
+ otherwise they are invisible to ksymoops. Also arch and version data.
+ Include sparc/sparc64 patches from Jakub Jelinek <j...@sunsite.mff.cuni.cz>.
+ Add object format override for sparc/soparc64 or any cross platform
+ oops debugging.
+
+ Mon Jan 4 09:48:13 EST 1999
+ Version 0.6e
+ Added to kernel.
+ Add ARM support.
+ Typo in oops_code.
+ Add -c option.
+ Add -1 option.
+ Report if options were specified or defaulted.
+ Remove false warnings when comparing ksyms and lsmod.
+ Performance inprovements.
+
+ Wed Oct 28 23:14:55 EST 1998
+ Version 0.5
+ No longer read vmlinux by default, it only duplicates System.map.
+
+ Wed Oct 28 13:46:39 EST 1998
+ Version 0.4
+ Split into separate sources.
+
+ Mon Oct 26 00:01:47 EST 1998
+ Version 0.3c
+ Add alpha (arm) processing.
+
+ Mon Oct 26 00:01:47 EST 1998
+ Version 0.3b
+ Add sparc processing.
+ Handle kernel symbol versions.
+
+ Fri Oct 23 13:11:20 EST 1998
+ Version 0.3
+ Add -follow to find command for people who use symlinks to modules.
+ Add Version_ checking.
+
+ Thu Oct 22 22:28:30 EST 1998
+ Version 0.2.
+ Generalise text prefix handling.
+ Handle messages on Code: line.
+ Format addresses with leading zeroes.
+ Minor bug fixes.
+
+ Wed Oct 21 23:28:48 EST 1998
+ Version 0.1. Rewrite from scratch in C.
+
+ CREDITS.
+ Oops disassembly based on ksymoops.cc,
+ Copyright (C) 1995 Greg McGary <g...@magilla.cichlid.com>
+ m68k code based on ksymoops.cc changes by
+ Andreas Schwab <sch...@issan.informatik.uni-dortmund.de>
+
+ This code subsumes the Perl script make_System.map.pl which is no longer
+ supported.
+
+ Why another ksymoops I hear you ask? Various complaints about
+ ksymoops.cc -
+
+ * It requires C++.
+ * It has hard wired limitations on the number of symbols.
+ * It does not handle modules at all.
+ * Very rigid requirements on the format of input, especially the Oops
+ log.
+ * No cross checking between ksyms, modules, System.map etc.
+ * Very little error checking, diagnostics are not suitable for
+ beginners.
+ * It only prints the trace and decoded code, users have to manually
+ extract the other lines from the Oops.
+ * Gives up on the slightest problem.
+ * Only handles i386 and possibly m68k. The code is difficult to extend
+ to other architectures.
+ * Stops after the first Oops, you have to manually extract each one and
+ run through ksymoops one at a time.
+
+ This version is -
+ * C.
+ * No hard wired limitations (malloc as far as the eye can see).
+ * Handles modules by default.
+ * Uses regular pattern matching so it is a lot more forgiving about
+ input formats.
+ * By default, cross checks ksyms, modules, System.map and vmlinux.
+ * Lots of diagnostics and error checking.
+ * Prints all relevant lines for a complete Oops report.
+ * Tries to provide output no matter how bad the input is. The level of
+ progress and error reporting is aimed at beginners.
+ * Handles i386, alpha, sparc, m68k. It is a lot easier to extend to
+ other architectures (patches and/or sample data gratefully accepted).
+ * Handles all Oops in the input file(s).
+
+
+ Usage: ksymoops
+ [-v vmlinux] Where to read vmlinux
+ [-V] No vmlinux is available
+ [-o object_dir] Directory containing modules
+ [-O] No modules is available
+ [-k ksyms] Where to read ksyms
+ [-K] No ksyms is available
+ [-l lsmod] Where to read lsmod
+ [-L] No lsmod is available
+ [-m system.map] Where to read System.map
+ [-M] No System.map is available
+ [-s save.map] Save consolidated map
+ [-c code_bytes] How many bytes in each unit of code
+ [-1] One shot toggle (exit after first Oops)
+ [-d] Increase debug level by 1
+ [-h] Print help text
+ Oops.file Oops to decode
+
+ All flags can occur more than once. With the exception of -o
+ and -d which are cumulative, the last occurrence of each flag is
+ used. Note that "-v my.vmlinux -V" will be taken as "No vmlinux
+ available" but "-V -v my.vmlinux" will read my.vmlinux. You
+ will be warned about such combinations.
+
+ Each occurrence of -d increases the debug level.
+
+ Each -o flag can refer to a directory or to a single object
+ file. If a directory is specified then all *.o files in that
+ directory and its subdirectories are assumed to be modules.
+
+ If any of the vmlinux, object_dir, ksyms or system.map options
+ contain the string *r (*m, *n, *s) then it is replaced at run time
+ by the current value of `uname -r` (-m, -n, -s).
+
+ The defaults can be changed in the Makefile, typical options are
+
+ Defaults: -V
+ -o /lib/modules/%r
+ -k /proc/ksyms
+ -l /proc/modules
+ -m /usr/src/linux/System.map
+ -c 1
+ Oops report is read from stdin
+
+ Note: Unless you tell ksymoops *NOT* to read a particular file, it
+ will try to read and reconcile almost all possible sources of kernel
+ symbol information. This is intended for beginners, they just
+ type
+
+ ksymoops < /var/log/syslog
+
+ no thinking required. Experts can point at different files or
+ suppress the input from selected files. For example, if you
+ save /proc/ksyms before doing a test that creates an Oops, you
+ can point ksymoops at the saved ksyms instead of using
+ /proc/ksyms.
+
+ vmlinux is not read by default, it only duplicates the
+ information in System.map. If you want to read vmlinux as well
+ as or instead of System.map, use -v.
+
+ To get the equivalent of the old ksymoops.cc (no vmlinux, no
+ modules objects, no ksyms, no System.map) just do ksymoops
+ -VOKLM. Or to just read System.map, ksymoops -VOKL -m mapfile.
+
+
+ Return codes: 0 - normal.
+ 1 - error(s) or warning(s) issued, results may not be
+ reliable.
+ 2 - fatal error, no useful results.
+ 3 - One shot mode, end of input reached.
+
+ Supported architectures
+
+ i386 tested.
+ m68k code derived from ksymoops.cc and reading traps.c, untested.
+ MIPS tested.
+ Sparc tested.
+ Alpha tested.
+ ARM tested.
+
+ The term "eip" is generic, for example it includes the i386 EIP
+ and the m68k PC. Remember that objdump output always says EIP,
+ no matter what the architecture, see objfile_head.
+
+ To support another arch, check the Oops_ procedures between
+ 'Start architecture sensitive code' and 'End architecture
+ sensitive code'.
+
+ The pattern matching should take care of different lengths for
+ the address, i.e. addresses should not be arch sensitive. I
+ assume that all addresses are at least 4 characters.
+
+ If nm output has a different format on your arch, check for uses
+ of re_nm.
+
+
+
+ Because ksymoops reads kernel information from multiple sources, there
+ could be mismatches. ksymoops does the following cross checks, but only
+ if the specified files exist -
+
+ * Compare Version_nnn numbers from all sources against each other. Pity
+ that only vmlinux and System.map have these symbols (as at 2.1.125),
+ however I check ksyms, modules and Oops as well. If somebody adds
+ symbol Version_nnn to ksyms or modules or adds a Version_nnn line to
+ the Oops log, this code is ready.
+
+ * Compare kernel ksyms against vmlinux. vmlinux takes precedence.
+
+ * Compare System.map against vmlinux. vmlinux takes precedence.
+
+ * Compare vmlinux against System.map. vmlinux takes precedence.
+
+ * Compare kernel ksyms against System.map. System.map takes precedence.
+
+ * Compare modules against module ksyms. modules take precedence. Only
+ if at least one module appears in ksyms.
+
+ * Compare module names in ksyms against lsmod. Warn if a module
+ appears in lsmod but not in ksyms. Error if a modules appears in
+ ksyms but is not in lsmod. Only if both ksyms and lsmod have being
+ read.
+
+ The precedence order is somewhat arbitrary, however it only applies if
+ there is any difference between the various sources.
+
+ Handling modules is awkward. They can be loaded under different names
+ (insmod -o dummy1 dummy.o) and the text, data and read only data are
+ loaded at different offsets. Although you can give the -m option to
+ insmod which will output the module map when it is loaded, this has a
+ few problems -
+
+ * No equivalent for removing a module. If you load and remove a lot of
+ modules, you end up with multiple sets of symbols around the same
+ offsets, which set is correct?
+
+ * "insmod -o dummy1 dummy.o" still reports as dummy. That is, there is
+ no way of telling which particular version of a multiply loaded
+ module the insmod output refers to. Therefore there is no way of
+ telling which instantiation failed.
+
+ * Even if the above problems are fixed, how do you tell what the module
+ environment looked like when the Oops occurred? What if a module is
+ loaded or removed just after Oops, how is the user expected to edit
+ the insmod log? Rule 1 - make ksymoops easy for beginners.
+
+ Although those problems could be fixed, they require changes to
+ modutils. Working from ksyms and the module objects can be done without
+ changing modutils and without confusing beginners.
+
+ Alas the ksyms plus object approach has another problem - matching ksyms
+ to module objects. Nowhere does the kernel say that module dummy1 came
+ from module /lib/modules/2.1.215/net/dummy.o, ksyms just says dummy1. I
+ have to match ksyms to the relevant object by finding a globally unique
+ external symbol in each module that can be used to map to the external
+ symbols in ksyms. This assumes that each module exports at least one
+ text symbol that is unique amongst all modules.
+
+ It may not be possible to correctly map other sections such as data and
+ readonly data for modules because they may not have exported symbols.
+ Since the main aim of ksymoops is to map a code Oops, this should not be
+ a problem.
+
+ Unfortunately some modules export no symbols. They are marked as
+ EXPORT_NO_SYMBOLS are simply do not export anything. It is
+ impossible to detect these in ksyms because, by definition, ksyms
+ only contains exported symbols for modules. Since all modules appear
+ in lsmod (/proc/modules), a cross check of lsmod against the module
+ names will find loaded modules with no symbols, at least I can warn
+ about these.
+
+ After merging the various sources, ksymoops has a (hopefully) accurate
+ map including modules. The -s option lets you save the merged
+ System.map, but remember that module data and readonly data sections may
+ not be correctly relocated, see above.
+
+ Environment Variables.
+ KSYMOOPS_NM path for nm, defaults to /usr/bin/nm.
+ KSYMOOPS_FIND path for find, defaults to /usr/bin/find.
+ KSYMOOPS_OBJDUMP path for objdump, defaults to /usr/bin/objdump.
+
+
+ Input Oops data.
+
+ The ideal input is to feed the syslog straight into this program. If
+ you cannot do that, you need to know what the program looks for.
+ Especially if you are typing in the Oops by hand :(. All input is case
+ insensitive.
+
+ * White space in this context means space or tab. It does not include
+ newline.
+
+ * Oops in syslog has a syslog prefix. Leading text up to and including
+ ' kernel: ' is always ignored, there is no need to edit syslog first.
+ This leading text need not exist but if it does, it must end in
+ ' kernel: '.
+
+ * An alternative prefix is <n> where n is the kernel print level. Also
+ ignored if present.
+
+ * Leading white space is treated as a prefix and ignored, the input is
+ not indentation sensitive.
+
+ * In the following paragraphs, assume that any prefixes have been
+ skipped. If there is more than one prefix, all are skipped, no matter
+ which order they appear in.
+
+ * A bracketed address is optional '[', required '<', at least 4 hex
+ digits, required '>', optional ']'. For example [<01234567>] or
+ <1234>.
+
+ * The ix86 EIP line is identified by optional white space followed by
+ 'EIP:', followed by a least one white space, followed by a bracketed
+ address.
+
+ * The m68k PC line is identified by optional white space followed by
+ 'PC', optionally followed by white space, followed by '=', optionally
+ followed by white space, followed by a bracketed address.
+
+ * The sparc PC line starts with PSR and PC is the second hex value, not
+ bracketed.
+
+ * A call trace line is identified by 'Call Trace:' followed by at least
+ one white space. Or it is a line starting with a bracketed address,
+ but only if the previous line was a call trace line (I hate multi line
+ output that relies on identation for recognition, especially when
+ lines can have a variable prefix).
+
+ * The Code line is identified by 'Code:' followed by a least one white
+ space character followed by at least one hex value. The line can
+ contain multiple hex values, each separated by at least one white
+ space. Each hex value must be 2 to 8 digits and must be a multiple of
+ 2 digits.
+
+ On some architectures the Code: data is a stream of single bytes,
+ in machine order. On other architectures, it is a stream of shorts
+ or ints in human readable order which does not always match the
+ machine order, endianess raises its ugly head. We are consistently
+ inconsistent.
+
+ To cater for these architecture inconsistencies, use the -c option.
+ If the Code: line is already in machine order, use -c 1. If the
+ Code: data is a stream of shorts or ints which do not match the
+ machine order, use -c 2 or -c 4. Each set of 'c' bytes are swapped
+ to (hopefully) reflect the machine order.
+
+ Special cases where Code: can be followed by text.
+ 'Code: general protection'
+ 'Code: <n>'
+ Dump the data anyway, the code was unavailable.
+
+ * Formatted data is only output when the Code: line is seen. If any
+ data has been stored and more than 5 lines other than Oops text (see
+ Oops_print) or end of file are encountered then ksymoops assumes that
+ the Code: line is missing or garbled and dumps the formatted data
+ anyway. Fail safe, I hope.
+
+ * By default, ksymoops reads its entire input file. If the -1 toggle
+ is set, it will run in one shot mode and exit after the first Oops.
+ This is useful for automatically mailing reports as they happen,
+ like this :-
+
+ #!/bin/sh
+ # ksymoops1
+ while (true)
+ do
+ ksymoops -1 > $HOME/oops1
+ if [ $? -eq 3 ]
+ then
+ exit 0
+ fi
+ mail -s Oops admin < $HOME/oops1
+ done
+
+ tail -f /var/log/messages | ksymoops1
+
+ Restarting after log rotation is left as an exercise for the reader.
diff -u --recursive --new-file v2.2.0-pre4/linux/scripts/ksymoops/io.c linux/scripts/ksymoops/io.c
--- v2.2.0-pre4/linux/scripts/ksymoops/io.c Wed Dec 31 16:00:00 1969
+++ linux/scripts/ksymoops/io.c Tue Jan 5 11:13:56 1999
@@ -0,0 +1,139 @@
+/*
+ io.c.
+
+ Local I/O routines for ksymoops.
+
+ Copyright Keith Owens <ka...@ocs.com.au>.
+ Released under the GNU Public Licence, Version 2.
+
+ Tue Nov 3 02:31:01 EST 1998
+ Version 0.6
+ fwrite_local is redundant, replaced by bfd.
+
+ Wed Oct 28 13:47:23 EST 1998
+ Version 0.4
+ Split into separate sources.
+
+ */
+
+#include "ksymoops.h"
+#include <errno.h>
+#include <malloc.h>
+#include <string.h>
+#include <sys/stat.h>
+
+int regular_file(const char *file, const char *msg)
+{
+ struct stat statbuf;
+ if (stat(file, &statbuf)) {
+ fprintf(stderr, "%s: %s stat %s failed",
+ prefix, msg, file);
+ perror(" ");
+ ++errors;


+ return 0;
+ }
+

+ if (!S_ISREG(statbuf.st_mode)) {
+ fprintf(stderr,
+ "%s: %s %s is not a regular file, ignored\n",
+ prefix, msg, file);
+ ++errors;
+ return 0;
+ }
+ return 1;
+}
+
+FILE *fopen_local(const char *file, const char *mode, const char *msg)
+{
+ FILE *f;
+ if (!(f = fopen(file, mode))) {
+ fprintf(stderr, "%s: %s fopen '%s' failed",
+ prefix, msg, file);
+ perror(" ");
+ ++errors;
+ }
+ return f;
+}
+
+void fclose_local(FILE *f, const char *msg)
+{
+ int i;
+ if ((i = fclose(f))) {
+ fprintf(stderr, "%s: %s fclose failed %d", prefix, msg, i);
+ perror(" ");
+ ++errors;
+ }
+}
+
+/* Read a line, increasing the size of the line as necessary until \n is read */
+#define INCREMENT 10 /* arbitrary */
+char *fgets_local(char **line, int *size, FILE *f, const char *msg)
+{
+ char *l, *p, *r;
+ int longline = 1;
+
+ if (!*line) {
+ *size = INCREMENT;
+ *line = malloc(*size);
+ if (!*line)
+ malloc_error("fgets_local alloc line");
+ }
+
+ l = *line;
+ while (longline) {
+ r = fgets(l, *size-(l-*line), f);
+ if (!r) {
+ if (ferror(f)) {
+ fprintf(stderr,
+ "%s: %s fgets failed", prefix, msg);
+ perror(" ");
+ ++errors;
+ }
+ if (l != *line)
+ return(*line);
+ else
+ return(r);
+ }
+ if (!(p = strchr(*line, '\n'))) {
+ *size += INCREMENT;
+ *line = realloc(*line, *size);
+ if (!*line)
+ malloc_error("fgets_local realloc line");
+ l = *line+*size-INCREMENT-1;
+ }
+ else {
+ *p = '\0';
+ longline = 0;
+ }
+ }
+
+ if (debug > 3)
+ fprintf(stderr, "DEBUG: %s line '%s'\n", msg, *line);
+ return(*line);
+}
+
+FILE *popen_local(const char *cmd, const char *msg)
+{
+ FILE *f;
+ if (!(f = popen(cmd, "r"))) {
+ fprintf(stderr, "%s: %s popen '%s' failed",
+ prefix, msg, cmd);
+ perror(" ");
+ ++errors;
+ }
+ return f;
+}
+
+void pclose_local(FILE *f, const char *msg)
+{
+ int i;
+ errno = 0;
+ if ((i = pclose(f))) {
+ fprintf(stderr, "%s: %s pclose failed 0x%x", prefix, msg, i);
+ if (errno)
+ perror(" ");
+ else
+ fprintf(stderr, "\n");
+ ++errors;
+ }
+}
diff -u --recursive --new-file v2.2.0-pre4/linux/scripts/ksymoops/ksymoops.c linux/scripts/ksymoops/ksymoops.c
--- v2.2.0-pre4/linux/scripts/ksymoops/ksymoops.c Wed Dec 31 16:00:00 1969
+++ linux/scripts/ksymoops/ksymoops.c Tue Jan 5 11:13:56 1999
@@ -0,0 +1,678 @@
+/*
+ ksymoops.c.
+
+ Read a kernel Oops file and make the best stab at converting the code to
+ instructions and mapping stack values to kernel symbols.
+
+ Copyright Keith Owens <ka...@ocs.com.au>.
+ Released under the GNU Public Licence, Version 2.
+*/
+
+#define VERSION "0.6e"
+
+/*
+
+ Tue Jan 5 19:26:02 EST 1999
+ Version 0.6e
+ Added to kernel.
+
+ Mon Jan 4 09:48:13 EST 1999
+ Version 0.6d
+ Add ARM support.
+
+ Thu Nov 26 16:37:46 EST 1998
+ Version 0.6c
+ Typo in oops_code.
+ Add -c option.
+ Add -1 option.
+ Report if options were specified or defaulted.
+
+ Fri Nov 6 10:38:42 EST 1998
+ Version 0.6b
+ Remove false warnings when comparing ksyms and lsmod.
+
+ Tue Nov 3 23:33:04 EST 1998
+ Version 0.6a
+ Performance inprovements.
+
+ Tue Nov 3 02:31:01 EST 1998
+ Version 0.6
+ Read lsmod (/proc/modules).
+ Ignore addresses 0-4095 when mapping address to symbol.
+ Discard default objects if -o specified.
+ Oops file must be regular.
+ Add "invalid operand" to Oops_print.
+ Move "Using_Version" copy to map.c.
+ Add Makefile defaults for vmlinux, ksyms, objects, System.map, lsmod.
+ Minor adjustment to re for ppc.
+ Minor adjustment to re for objdump lines with <_EIP+xxx>.
+ Convert from a.out to bfd, using same format as ksymoops.
+ Added MIPS.
+ PPC handling based on patches by "Ryan Nielsen" <r...@krazynet.com>
+
+ Wed Oct 28 23:14:55 EST 1998
+ Version 0.5
+ No longer read vmlinux by default, it only duplicates System.map.
+
+ Wed Oct 28 13:47:38 EST 1998
+ Version 0.4
+ Split into separate sources.
+
+ Mon Oct 26 00:01:47 EST 1998
+ Version 0.3c
+ Add alpha (arm) processing.
+
+ Mon Oct 26 00:01:47 EST 1998
+ Version 0.3b
+ Add sparc processing.
+ Handle kernel symbol versions.
+
+ Fri Oct 23 13:11:20 EST 1998
+ Version 0.3
+ Add -follow to find command for people who use symlinks to modules.
+ Add Version_ checking.
+
+ Thu Oct 22 22:28:30 EST 1998
+ Version 0.2.
+ Generalise text prefix handling.
+ Handle messages on Code: line.
+ Format addresses with leading zeroes.
+ Minor bug fixes.
+
+ Wed Oct 21 23:28:48 EST 1998
+ Version 0.1. Rewrite from scratch in C.
+
+ CREDITS.
+ Oops disassembly based on ksymoops.cc,
+ Copyright (C) 1995 Greg McGary <g...@magilla.cichlid.com>
+ m68k code based on ksymoops.cc changes by
+ Andreas Schwab <sch...@issan.informatik.uni-dortmund.de>
+ */
+
+#include "ksymoops.h"
+#include <ctype.h>
+#include <errno.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+
+char *prefix;
+char *path_nm = "/usr/bin/nm"; /* env KSYMOOPS_NM */
+char *path_find = "/usr/bin/find"; /* env KSYMOOPS_FIND */
+char *path_objdump = "/usr/bin/objdump"; /* env KSYMOOPS_OBJDUMP */
+int debug = 0;
+int errors = 0;
+int warnings = 0;
+
+SYMBOL_SET ss_vmlinux;
+SYMBOL_SET ss_ksyms_base;
+SYMBOL_SET *ss_ksyms_module;
+int ss_ksyms_modules;
+SYMBOL_SET ss_lsmod;
+SYMBOL_SET *ss_object;
+int ss_objects;
+SYMBOL_SET ss_system_map;
+
+SYMBOL_SET ss_merged; /* merged map with info from all sources */
+SYMBOL_SET ss_Version; /* Version_ numbers where available */
+
+/* Regular expression stuff */
+
+regex_t re_nm;
+regmatch_t *re_nm_pmatch;
+regex_t re_bracketed_address;
+regmatch_t *re_bracketed_address_pmatch;
+regex_t re_unbracketed_address;
+regmatch_t *re_unbracketed_address_pmatch;
+
+static void usage(void)
+{
+ fprintf(stderr, "Version " VERSION "\n");
+ fprintf(stderr, "usage: %s\n", prefix);
+ fprintf(stderr,
+ "\t\t[-v vmlinux]\tWhere to read vmlinux\n"
+ "\t\t[-V]\t\tNo vmlinux is available\n"
+ "\t\t[-o object_dir]\tDirectory containing modules\n"
+ "\t\t[-O]\t\tNo modules is available\n"
+ "\t\t[-k ksyms]\tWhere to read ksyms\n"
+ "\t\t[-K]\t\tNo ksyms is available\n"
+ "\t\t[-l lsmod]\tWhere to read lsmod\n"
+ "\t\t[-L]\t\tNo lsmod is available\n"
+ "\t\t[-m system.map]\tWhere to read System.map\n"
+ "\t\t[-M]\t\tNo System.map is available\n"
+ "\t\t[-s save.map]\tSave consolidated map\n"
+ "\t\t[-d]\t\tIncrease debug level by 1\n"
+ "\t\t[-h]\t\tPrint help text\n"
+ "\t\t[-c code_bytes]\tHow many bytes in each unit of code\n"
+ "\t\t[-1]\t\tOne shot toggle (exit after first Oops)\n"
+ "\t\t<Oops.file\tOops report to decode\n"
+ "\n"
+ "\t\tAll flags can occur more than once. With the exception "
+ "of -o\n"
+ "\t\tand -d which are cumulative, the last occurrence of each "
+ "flag is\n"
+ "\t\tused. Note that \"-v my.vmlinux -V\" will be taken as "
+ "\"No vmlinux\n"
+ "\t\tavailable\" but \"-V -v my.vmlinux\" will read "
+ "my.vmlinux. You\n"
+ "\t\twill be warned about such combinations.\n"
+ "\n"
+ "\t\tEach occurrence of -d increases the debug level.\n"
+ "\n"
+ "\t\tEach -o flag can refer to a directory or to a single "
+ "object\n"
+ "\t\tfile. If a directory is specified then all *.o files in "
+ "that\n"
+ "\t\tdirectory and its subdirectories are assumed to be "
+ "modules.\n"
+ "\n"
+ "\t\tIf any of the vmlinux, object_dir, ksyms or system.map "
+ "options\n"
+ "\t\tcontain the string *r (*m, *n, *s) then it is replaced "
+ "at run\n"
+ "\t\ttime by the current value of `uname -r` (-m, -n, -s).\n"
+ "\n"
+ "\t\tThe defaults can be changed in the Makefile, current "
+ "defaults\n"
+ "\t\tare\n\n"
+ "\t\t\t"
+#ifdef DEF_VMLINUX
+ "-v " DEF_LINUX
+#else
+ "-V"
+#endif
+ "\n"
+ "\t\t\t"
+#ifdef DEF_OBJECTS
+ "-o " DEF_OBJECTS
+#else
+ "-O"
+#endif
+ "\n"
+ "\t\t\t"
+#ifdef DEF_KSYMS
+ "-k " DEF_KSYMS
+#else
+ "-K"
+#endif
+ "\n"
+ "\t\t\t"
+#ifdef DEF_LSMOD
+ "-l " DEF_LSMOD
+#else
+ "-L"
+#endif
+ "\n"
+ "\t\t\t"
+#ifdef DEF_MAP
+ "-m " DEF_MAP
+#else
+ "-M"
+#endif
+ "\n"
+ "\t\t\t-c %d\n" /* DEF_CODE_BYTES */
+ "\t\t\tOops report is read from stdin\n"
+ "\n",
+ DEF_CODE_BYTES
+ );
+}
+
+/* Check if possibly conflicting options were specified */
+static void multi_opt(int specl, int specu, char type, const char *using)
+{
+ if (specl && specu) {
+ fprintf(stderr,
+ "Warning - you specified both -%c and -%c. Using '",
+ type, toupper(type));
+ ++warnings;
+ if (using) {
+ fprintf(stderr, "-%c %s", type, using);
+ if (type == 'o')
+ fprintf(stderr, " ...");
+ fprintf(stderr, "'\n");
+ }
+ else
+ fprintf(stderr, "-%c'\n", toupper(type));
+ }
+ else if (specl > 1 && type != 'o') {
+ fprintf(stderr,
+ "Warning - you specified -%c more than once. "
+ "Using '-%c %s'\n",
+ type, type, using);
+ ++warnings;
+ }
+ else if (specu > 1) {
+ fprintf(stderr,
+ "Warning - you specified -%c more than once. "
+ "Second and subsequent '-%c' ignored\n",
+ toupper(type), toupper(type));
+ ++warnings;
+ }
+}
+
+/* If a name contains *r (*m, *n, *s), replace with the current value of
+ * `uname -r` (-m, -n, -s). Actually uses uname system call rather than the
+ * uname command but the result is the same.
+ */
+static void convert_uname(char **name)
+{
+ char *p, *newname, *oldname, *replacement;
+ unsigned len;
+ int free_oldname = 0;
+ static char procname[] = "convert_uname";
+
+ if (!*name)
+ return;
+
+ while ((p = strchr(*name, '*'))) {
+ struct utsname buf;
+ int i = uname(&buf);
+ if (debug)
+ fprintf(stderr, "DEBUG: %s %s in\n", procname, *name);
+ if (i) {
+ fprintf(stderr,
+ "%s: uname failed, %s will not be processed\n",
+ prefix, *name);
+ perror(prefix);
+ ++errors;
+ return;
+ }
+ switch (*(p+1)) {
+ case 'r':
+ replacement = buf.release;
+ break;
+ case 'm':
+ replacement = buf.machine;
+ break;
+ case 'n':
+ replacement = buf.nodename;
+ break;
+ case 's':
+ replacement = buf.sysname;
+ break;
+ default:
+ fprintf(stderr,
+ "%s: invalid replacement character '*%c' "
+ "in %s\n",
+ prefix, *(p+1), *name);
+ ++errors;
+ return;
+ }
+ len = strlen(*name)-2+strlen(replacement)+1;
+ if (!(newname = malloc(len)))
+ malloc_error(procname);
+ strncpy(newname, *name, (p-*name));
+ strcpy(newname+(p-*name), replacement);
+ strcpy(newname+(p-*name)+strlen(replacement), p+2);
+ p = newname+(p-*name)+strlen(replacement); /* no rescan */
+ oldname = *name;
+ *name = newname;
+ if (free_oldname)
+ free(oldname);
+ free_oldname = 1;
+ if (debug)
+ fprintf(stderr, "DEBUG: %s %s out\n", procname, *name);
+ }
+ return;
+}
+
+/* Report if the option was specified or defaulted */
+static void spec_or_default(int spec, int *some_spec) {
+ if (spec) {
+ printf(" (specified)\n");
+ if (some_spec)
+ *some_spec = 1;
+ }
+ else
+ printf(" (default)\n");
+}
+
+/* Parse the options. Verbose but what's new with getopt? */
+static void parse(int argc,
+ char **argv,
+ char **vmlinux,
+ char ***object,
+ int *objects,
+ char **ksyms,
+ char **lsmod,
+ char **system_map,
+ char **save_system_map,
+ char ***filename,
+ int *filecount,
+ int *spec_h,
+ int *code_bytes,
+ int *one_shot
+ )
+{
+ int spec_v = 0, spec_V = 0;
+ int spec_o = 0, spec_O = 0;
+ int spec_k = 0, spec_K = 0;
+ int spec_l = 0, spec_L = 0;
+ int spec_m = 0, spec_M = 0;
+ int spec_s = 0;
+ int spec_c = 0;
+
+ int c, i, some_spec = 0;
+ char *p;
+
+ while ((c = getopt(argc, argv, "v:Vo:Ok:Kl:Lm:Ms:dhc:1")) != EOF) {
+ if (debug && c != 'd')
+ fprintf(stderr, "DEBUG: getopt '%c' '%s'\n", c, optarg);
+ switch(c) {
+ case 'v':
+ *vmlinux = optarg;
+ ++spec_v;
+ break;
+ case 'V':
+ *vmlinux = NULL;
+ ++spec_V;
+ break;
+ case 'o':
+ if (!spec_o) {
+ /* First -o, discard default value(s) */
+ for (i = 0; i < *objects; ++i)
+ free((*object)[i]);
+ free(*object);
+ *object = NULL;
+ *objects = 0;
+ }
+ *object = realloc(*object,
+ ((*objects)+1)*sizeof(**object));
+ if (!*object)
+ malloc_error("object");
+ if (!(p = strdup(optarg)))
+ malloc_error("strdup -o");
+ else {
+ (*object)[(*objects)++] = p;
+ ++spec_o;
+ }
+ break;
+ case 'O':
+ ++spec_O;
+ for (i = 0; i < *objects; ++i)
+ free((*object)[i]);
+ free(*object);
+ *object = NULL;
+ *objects = 0;
+ break;
+ case 'k':
+ *ksyms = optarg;
+ ++spec_k;
+ break;
+ case 'K':
+ *ksyms = NULL;
+ ++spec_K;
+ break;
+ case 'l':
+ *lsmod = optarg;
+ ++spec_l;
+ break;
+ case 'L':
+ *lsmod = NULL;
+ ++spec_L;
+ break;
+ case 'm':
+ *system_map = optarg;
+ ++spec_m;
+ break;
+ case 'M':
+ *system_map = NULL;
+ ++spec_M;
+ break;
+ case 's':
+ *save_system_map = optarg;
+ ++spec_s;
+ break;
+ case 'd':
+ ++debug;
+ break;
+ case 'h':
+ usage();
+ ++*spec_h;
+ break;
+ case 'c':
+ ++spec_c;
+ errno = 0;
+ *code_bytes = strtoul(optarg, &p, 10);
+ /* Oops_code_values assumes that code_bytes is a
+ * multiple of 2.
+ */
+ if (!*optarg || *p || errno ||
+ (*code_bytes != 1 &&
+ *code_bytes != 2 &&
+ *code_bytes != 4 &&
+ *code_bytes != 8)) {
+ fprintf(stderr,
+ "%s Invalid value for -c '%s'\n",
+ prefix, optarg);
+ ++errors;
+ if (errno)
+ perror(" ");
+ *code_bytes = DEF_CODE_BYTES;
+ }
+ break;
+ case '1':
+ *one_shot = !*one_shot;
+ break;
+ case '?':
+ usage();
+ exit(2);
+ }
+ }
+
+ *filecount = argc - optind;
+ *filename = argv + optind;
+
+ /* Expand any requests for the current uname values */
+ convert_uname(vmlinux);
+ if (*objects) {
+ for (i = 0; i < *objects; ++i)
+ convert_uname(*object+i);
+ }
+ convert_uname(ksyms);
+ convert_uname(lsmod);
+ convert_uname(system_map);
+
+ /* Check for multiple options specified */
+ multi_opt(spec_v, spec_V, 'v', *vmlinux);
+ multi_opt(spec_o, spec_O, 'o', *object ? **object : NULL);
+ multi_opt(spec_k, spec_K, 'k', *ksyms);
+ multi_opt(spec_l, spec_L, 'l', *lsmod);
+ multi_opt(spec_m, spec_M, 'm', *system_map);
+
+ printf("Options used:");
+ if (*vmlinux)
+ printf(" -v %s", *vmlinux);
+ else
+ printf(" -V");
+ spec_or_default(spec_v || spec_V, &some_spec);
+
+ printf(" ");
+ if (*objects) {
+ for (i = 0; i < *objects; ++i)
+ printf(" -o %s", (*object)[i]);
+ }
+ else
+ printf(" -O");
+ spec_or_default(spec_o || spec_O, &some_spec);
+
+ printf(" ");
+ if (*ksyms)
+ printf(" -k %s", *ksyms);
+ else
+ printf(" -K");
+ spec_or_default(spec_k || spec_K, &some_spec);
+
+ printf(" ");
+ if (*lsmod)
+ printf(" -l %s", *lsmod);
+ else
+ printf(" -L");
+ spec_or_default(spec_l || spec_L, &some_spec);
+
+ printf(" ");
+ if (*system_map)
+ printf(" -m %s", *system_map);
+ else
+ printf(" -M");
+ spec_or_default(spec_m || spec_M, &some_spec);
+
+ printf(" ");
+ printf(" -c %d", *code_bytes);
+ spec_or_default(spec_c, NULL);
+
+ if (*one_shot) {
+ printf(" ");
+ printf(" -1");
+ }
+
+ printf("\n");
+
+ if (!some_spec) {
+ printf(
+"You did not tell me where to find symbol information. I will assume\n"
+"that the log matches the kernel and modules that are running right now\n"
+"and I'll use the default options above for symbol resolution.\n"
+"If the current kernel and/or modules do not match the log, you can get\n"
+"more accurate output by telling me the kernel version and where to find\n"
+"map, modules, ksyms etc. ksymoops -h explains the options.\n"
+ "\n");
+ ++warnings;
+ }
+}
+
+/* Read environment variables */
+static void read_env(const char *external, char **internal)
+{
+ char *p;
+ if ((p = getenv(external))) {
+ *internal = p;
+ if (debug)
+ fprintf(stderr,
+ "DEBUG: env override %s=%s\n",
+ external, *internal);
+ }
+ else {
+ if (debug)
+ fprintf(stderr,
+ "DEBUG: env default %s=%s\n",
+ external, *internal);
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ char *vmlinux = NULL;
+ char **object = NULL;
+ int objects = 0;
+ char *ksyms = NULL;
+ char *lsmod = NULL;
+ char *system_map = NULL;
+ char *save_system_map = NULL;
+ char **filename;
+ int filecount = 0;
+ int spec_h = 0; /* -h was specified */
+ int code_bytes = DEF_CODE_BYTES;
+ int one_shot = 0;
+ int i, ret;
+
+ prefix = *argv;
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+#ifdef DEF_VMLINUX
+ vmlinux = DEF_LINUX;
+#endif
+#ifdef DEF_OBJECTS
+ {
+ char *p;
+ object = realloc(object, (objects+1)*sizeof(*object));
+ if (!object)
+ malloc_error("DEF_OBJECTS");
+ if (!(p = strdup(DEF_OBJECTS)))
+ malloc_error("DEF_OBJECTS");
+ else
+ object[objects++] = p;
+ }
+#endif
+#ifdef DEF_KSYMS
+ ksyms = DEF_KSYMS;
+#endif
+#ifdef DEF_LSMOD
+ lsmod = DEF_LSMOD;
+#endif
+#ifdef DEF_MAP
+ system_map = DEF_MAP;
+#endif
+
+ parse(argc,
+ argv,
+ &vmlinux,
+ &object,
+ &objects,
+ &ksyms,
+ &lsmod,
+ &system_map,
+ &save_system_map,
+ &filename,
+ &filecount,
+ &spec_h,
+ &code_bytes,
+ &one_shot
+ );
+
+ if (spec_h && filecount == 0)
+ return(0); /* just the help text */
+
+ if (errors)
+ return(1);
+
+ if (debug)
+ fprintf(stderr, "DEBUG: level %d\n", debug);
+
+ read_env("KSYMOOPS_NM", &path_nm);
+ read_env("KSYMOOPS_FIND", &path_find);
+ read_env("KSYMOOPS_OBJDUMP", &path_objdump);
+
+ re_compile_common();
+ ss_init_common();
+
+ read_vmlinux(vmlinux);
+ read_ksyms(ksyms);
+ /* No point in reading modules unless ksyms shows modules loaded */
+ if (ss_ksyms_modules) {
+ expand_objects(object, objects);
+ for (i = 0; i < ss_objects; ++i)
+ read_object(ss_object[i].source, i);
+ }
+ else if (objects)
+ printf("No modules in ksyms, skipping objects\n");
+ /* No point in reading lsmod without ksyms */
+ if (ss_ksyms_modules || ss_ksyms_base.used)
+ read_lsmod(lsmod);
+ else if (lsmod)
+ printf("No ksyms, skipping lsmod\n");
+ read_system_map(system_map);
+ merge_maps(save_system_map);
+
+ /* After all that work, it is finally time to read the Oops report */
+ ret = Oops_read(filecount, filename, code_bytes, one_shot);
+
+ if (warnings || errors) {
+ printf("\n");
+ if (warnings)
+ printf("%d warning%s ",
+ warnings, warnings == 1 ? "" : "s");
+ if (warnings && errors)
+ printf("and ");
+ if (errors)
+ printf("%d error%s ", errors, errors == 1 ? "" : "s");
+ printf("issued. Results may not be reliable.\n");
+ if (!ret)
+ return(1);
+ }
+
+ return(ret);
+}
diff -u --recursive --new-file v2.2.0-pre4/linux/scripts/ksymoops/ksymoops.h linux/scripts/ksymoops/ksymoops.h
--- v2.2.0-pre4/linux/scripts/ksymoops/ksymoops.h Wed Dec 31 16:00:00 1969
+++ linux/scripts/ksymoops/ksymoops.h Tue Jan 5 11:13:56 1999
@@ -0,0 +1,146 @@
+/*
+ ksymoops.h.
+
+ Copyright Keith Owens <ka...@ocs.com.au>.
+ Released under the GNU Public Licence, Version 2.
+
+ Tue Nov 3 02:31:01 EST 1998
+ Version 0.6
+ Read lsmod (/proc/modules).
+ Convert from a.out to bfd, using same format as ksymoops.
+ PPC trace addresses are not bracketed, add new re.
+
+ Wed Oct 28 13:47:23 EST 1998
+ Version 0.4
+ Split into separate sources.
+*/
+
+#include <sys/types.h>
+#include <regex.h>
+#include <stdio.h>
+
+
+/* Pity this is not externalised, see binfmt_elf.c */
+#define elf_addr_t unsigned long
+
+extern char *prefix;
+extern char *path_nm; /* env KSYMOOPS_NM */
+extern char *path_find; /* env KSYMOOPS_FIND */
+extern char *path_objdump; /* env KSYMOOPS_OBJDUMP */
+extern int debug;
+extern int errors;
+extern int warnings;
+
+typedef struct symbol SYMBOL;
+
+struct symbol {
+ char *name; /* name of symbol */
+ char type; /* type of symbol from nm/System.map */
+ char keep; /* keep this symbol in merged map? */
+ elf_addr_t address; /* address in kernel */
+};
+
+/* Header for symbols from one particular source */
+
+typedef struct symbol_set SYMBOL_SET;
+
+struct symbol_set {
+ char *source; /* where the symbols came from */
+ int used; /* number of symbols used */
+ int alloc; /* number of symbols allocated */
+ SYMBOL *symbol; /* dynamic array of symbols */
+ SYMBOL_SET *related; /* any related symbol set */
+};
+
+extern SYMBOL_SET ss_vmlinux;
+extern SYMBOL_SET ss_ksyms_base;
+extern SYMBOL_SET *ss_ksyms_module;
+extern int ss_ksyms_modules;
+extern SYMBOL_SET ss_lsmod;
+extern SYMBOL_SET *ss_object;
+extern int ss_objects;
+extern SYMBOL_SET ss_system_map;
+
+extern SYMBOL_SET ss_merged; /* merged map with info from all sources */
+extern SYMBOL_SET ss_Version; /* Version_ numbers where available */
+
+/* Regular expression stuff */
+
+extern regex_t re_nm;
+extern regmatch_t *re_nm_pmatch;
+extern regex_t re_bracketed_address;
+extern regmatch_t *re_bracketed_address_pmatch;
+extern regex_t re_unbracketed_address;
+extern regmatch_t *re_unbracketed_address_pmatch;
+
+/* Bracketed address: optional '[', required '<', at least 4 hex characters,
+ * required '>', optional ']', optional white space.
+ */
+#define BRACKETED_ADDRESS "\\[*<([0-9a-fA-F]{4,})>\\]*[ \t]*"
+
+#define UNBRACKETED_ADDRESS "([0-9a-fA-F]{4,})[ \t]*"
+
+/* io.c */
+extern int regular_file(const char *file, const char *msg);
+extern FILE *fopen_local(const char *file, const char *mode, const char *msg);
+extern void fclose_local(FILE *f, const char *msg);
+extern char *fgets_local(char **line, int *size, FILE *f, const char *msg);
+extern int fwrite_local(void const *ptr, size_t size, size_t nmemb,
+ FILE *stream, const char *msg);
+extern FILE *popen_local(const char *cmd, const char *msg);
+extern void pclose_local(FILE *f, const char *msg);
+
+/* ksyms.c */
+extern void read_ksyms(const char *ksyms);
+extern void map_ksyms_to_modules(void);
+extern void read_lsmod(const char *lsmod);
+extern void compare_ksyms_lsmod(void);
+
+/* misc.c */
+extern void malloc_error(const char *msg);
+extern const char *format_address(elf_addr_t address);
+extern char *find_fullpath(const char *program);
+
+/* map.c */
+extern void read_system_map(const char *system_map);
+extern void merge_maps(const char *save_system_map);
+extern void compare_maps(const SYMBOL_SET *ss1, const SYMBOL_SET *ss2,
+ int precedence);
+
+
+/* object.c */
+extern SYMBOL_SET *adjust_object_offsets(SYMBOL_SET *ss);
+extern void read_vmlinux(const char *vmlinux);
+extern void expand_objects(char * const *object, int objects);
+extern void read_object(const char *object, int i);
+
+/* oops.c */
+extern int Oops_read(int filecount, char * const *filename, int code_bytes,
+ int one_shot);
+
+/* re.c */
+extern void re_compile(regex_t *preg, const char *regex, int cflags,
+ regmatch_t **pmatch);
+extern void re_compile_common(void);
+extern void re_strings(regex_t *preg, const char *text, regmatch_t *pmatch,
+ char ***string);
+extern void re_strings_free(const regex_t *preg, char ***string);
+extern void re_string_check(int need, int available, const char *msg);
+
+/* symbol.c */
+extern void ss_init(SYMBOL_SET *ss, const char *msg);
+extern void ss_free(SYMBOL_SET *ss);
+extern void ss_init_common(void);
+extern SYMBOL *find_symbol_name(const SYMBOL_SET *ss, const char *symbol,
+ int *start);
+extern void add_symbol_n(SYMBOL_SET *ss, const elf_addr_t address,
+ const char type, const char keep, const char *symbol);
+extern void add_symbol(SYMBOL_SET *ss, const char *address, const char type,
+ const char keep, const char *symbol);
+extern char *map_address(const SYMBOL_SET *ss, const elf_addr_t address);
+extern void ss_sort_atn(SYMBOL_SET *ss);
+extern void ss_sort_na(SYMBOL_SET *ss);
+extern SYMBOL_SET *ss_copy(const SYMBOL_SET *ss);
+extern void add_Version(const char *version, const char *source);
+extern void extract_Version(SYMBOL_SET *ss);
+extern void compare_Version(void);
diff -u --recursive --new-file v2.2.0-pre4/linux/scripts/ksymoops/ksyms.c linux/scripts/ksymoops/ksyms.c
--- v2.2.0-pre4/linux/scripts/ksymoops/ksyms.c Wed Dec 31 16:00:00 1969
+++ linux/scripts/ksymoops/ksyms.c Tue Jan 5 11:13:56 1999
@@ -0,0 +1,294 @@
+/*
+ ksyms.c.
+
+ Process ksyms for ksymoops.
+
+ Copyright Keith Owens <ka...@ocs.com.au>.
+ Released under the GNU Public Licence, Version 2.
+
+ Fri Nov 6 10:38:42 EST 1998
+ Version 0.6b
+ Remove false warnings when comparing ksyms and lsmod.
+
+ Tue Nov 3 02:31:01 EST 1998
+ Version 0.6
+ Read lsmod (/proc/modules).
+ Move "Using_Version" copy to map.c.
+
+ Wed Oct 28 13:47:23 EST 1998
+ Version 0.4
+ Split into separate sources.
+ */
+
+#include "ksymoops.h"
+#include <malloc.h>
+#include <string.h>
+
+/* Scan one line from ksyms. Split lines into the base symbols and the module
+ * symbols. Separate ss for base and each module.
+ */
+static void scan_ksyms_line(const char *line)
+{
+ int i;
+ char **string = NULL;
+ SYMBOL_SET *ssp;
+ static char *prev_module = NULL;
+ static regex_t re_ksyms;
+ static regmatch_t *re_ksyms_pmatch;
+ static char const procname[] = "scan_ksyms_line";
+
+ /* ksyms: address, symbol, optional module */
+ re_compile(&re_ksyms,
+ "^([0-9a-fA-F]{4,}) +([^ \t]+)([ \t]+\\[([^ ]+)\\])?$",
+ REG_NEWLINE|REG_EXTENDED,
+ &re_ksyms_pmatch);
+
+ i = regexec(&re_ksyms, line,
+ re_ksyms.re_nsub+1, re_ksyms_pmatch, 0);
+ if (debug > 3)
+ fprintf(stderr, "DEBUG: %s regexec %d\n", procname, i);
+ if (i)
+ return;
+
+ /* string [1] - address, [2] - symbol, [3] - white space+module,
+ * [4] - module.
+ */
+ re_strings(&re_ksyms, line, re_ksyms_pmatch, &string);
+ if (string[4]) {
+ if (!prev_module || strcmp(prev_module, string[4])) {


SHAR_EOF
true || echo 'restore of patch-2.2.0-pre5 failed'
fi

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

0 new messages