]> git.neil.brown.name Git - history.git/commitdiff
Import 2.2.0pre6 2.2.0pre6
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:17:59 +0000 (15:17 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:17:59 +0000 (15:17 -0500)
237 files changed:
CREDITS
Documentation/cdrom/mcdx
Documentation/digiboard.txt
Documentation/digiepca.txt
Documentation/fb/matroxfb.txt
Documentation/isdn/README.act2000
Documentation/isdn/README.concap
Documentation/isdn/README.x25
Documentation/locks.txt
Documentation/m68k/kernel-options.txt
Documentation/networking/6pack.txt
Documentation/networking/arcnet-hardware.txt
Documentation/networking/cops.txt
Documentation/networking/de4x5.txt
Documentation/sound/AudioExcelDSP16
Documentation/sound/OPL3-SA2
Documentation/sound/VIA-chipset [new file with mode: 0644]
Documentation/sysctl/README
Documentation/video4linux/API.html
Makefile
README
REPORTING-BUGS [new file with mode: 0644]
arch/alpha/kernel/process.c
arch/i386/config.in
arch/i386/kernel/apm.c
arch/i386/kernel/entry.S
arch/i386/kernel/process.c
arch/i386/kernel/ptrace.c
arch/i386/kernel/setup.c
arch/m68k/amiga/amiints.c
arch/m68k/apollo/dn_ints.c
arch/m68k/kernel/signal.c
arch/ppc/amiga/amiints.c
arch/ppc/boot/ns16550.c [new file with mode: 0644]
arch/ppc/boot/ns16550.h [new file with mode: 0644]
arch/ppc/common_defconfig
arch/ppc/kernel/mbx_setup.c
arch/ppc/kernel/pci.c
arch/ppc/kernel/ppc_ksyms.c
arch/ppc/kernel/process.c
arch/ppc/kernel/setup.c
arch/ppc/mm/init.c
arch/sparc/lib/checksum.S
drivers/acorn/block/fd1772.c
drivers/block/ide-dma.c
drivers/block/ide-tape.c
drivers/block/xd.c
drivers/cdrom/cdrom.c
drivers/cdrom/sonycd535.c
drivers/char/README.epca
drivers/char/console.c
drivers/char/keyboard.c
drivers/char/n_tty.c
drivers/char/radio-zoltrix.c
drivers/char/tty_io.c
drivers/isdn/icn/icn.h
drivers/isdn/isdn_x25iface.c
drivers/misc/Makefile
drivers/misc/parport_arc.c
drivers/misc/parport_ax.c
drivers/misc/parport_procfs.c
drivers/net/3c515.c
drivers/net/3c523.c
drivers/net/3c59x.c
drivers/net/82596.c
drivers/net/8390.c
drivers/net/Makefile
drivers/net/acenic.c
drivers/net/acenic.h
drivers/net/acenic_firmware.h
drivers/net/ariadne2.c
drivers/net/at1700.c
drivers/net/cops.h
drivers/net/dgrs_i82596.h
drivers/net/eepro.c
drivers/net/eexpress.c
drivers/net/eth16i.c
drivers/net/hp100.c
drivers/net/ne2.c
drivers/net/rcmtl.h
drivers/net/sdladrv.c
drivers/net/sktr.c
drivers/net/sktr_firmware.h
drivers/net/sonic.c
drivers/net/tlan.c
drivers/net/z85230.c
drivers/net/znet.c
drivers/pci/quirks.c
drivers/sbus/audio/amd7930.c
drivers/sbus/audio/dbri.h
drivers/sbus/char/vfc_i2c.c
drivers/scsi/README.ncr53c8xx
drivers/scsi/aic7xxx/aic7xxx.reg
drivers/scsi/eata_dma_proc.c
drivers/scsi/eata_pio_proc.c
drivers/scsi/imm.h
drivers/scsi/ppa.h
drivers/scsi/scsi.c
drivers/scsi/scsi_error.c
drivers/scsi/wd7000.c
drivers/sound/ad1848.c
drivers/sound/dev_table.h
drivers/sound/es1370.c
drivers/sound/es1371.c
drivers/sound/gus_card.c
drivers/sound/gus_wave.c
drivers/sound/lowlevel/awe_compat.h
drivers/sound/mad16.c
drivers/sound/opl3sa2.c
drivers/sound/sb.h
drivers/sound/sb_audio.c
drivers/sound/sb_common.c
drivers/sound/sb_mixer.c
drivers/sound/sb_mixer.h
drivers/sound/sonicvibes.c
drivers/sound/sound_core.c
drivers/sound/waveartist.c [new file with mode: 0644]
drivers/sound/waveartist.h [new file with mode: 0644]
drivers/video/matroxfb.c
fs/buffer.c
fs/coda/psdev.c
fs/coda/upcall.c
fs/dcache.c
fs/nfsd/stats.c
fs/super.c
fs/ufs/dir.c
fs/ufs/super.c
include/asm-alpha/pci.h
include/asm-alpha/termbits.h
include/asm-arm/a.out.h
include/asm-arm/arch-arc/a.out.h
include/asm-arm/arch-arc/dma.h
include/asm-arm/arch-arc/hardware.h
include/asm-arm/arch-arc/io.h
include/asm-arm/arch-arc/processor.h
include/asm-arm/arch-arc/system.h
include/asm-arm/arch-ebsa110/a.out.h
include/asm-arm/arch-ebsa110/dma.h
include/asm-arm/arch-ebsa110/hardware.h
include/asm-arm/arch-ebsa110/io.h
include/asm-arm/arch-ebsa110/processor.h
include/asm-arm/arch-ebsa110/system.h
include/asm-arm/arch-ebsa110/time.h
include/asm-arm/arch-ebsa285/a.out.h
include/asm-arm/arch-ebsa285/dma.h
include/asm-arm/arch-ebsa285/hardware.h
include/asm-arm/arch-ebsa285/io.h
include/asm-arm/arch-ebsa285/irq.h
include/asm-arm/arch-ebsa285/mmu.h
include/asm-arm/arch-ebsa285/processor.h
include/asm-arm/arch-ebsa285/serial.h
include/asm-arm/arch-ebsa285/system.h
include/asm-arm/arch-ebsa285/time.h
include/asm-arm/arch-ebsa285/uncompress.h
include/asm-arm/arch-nexuspci/a.out.h
include/asm-arm/arch-nexuspci/dma.h
include/asm-arm/arch-nexuspci/hardware.h
include/asm-arm/arch-nexuspci/processor.h
include/asm-arm/arch-nexuspci/system.h
include/asm-arm/arch-rpc/a.out.h
include/asm-arm/arch-rpc/dma.h
include/asm-arm/arch-rpc/hardware.h
include/asm-arm/arch-rpc/io.h
include/asm-arm/arch-rpc/processor.h
include/asm-arm/arch-rpc/system.h
include/asm-arm/arch-vnc/a.out.h
include/asm-arm/arch-vnc/dma.h
include/asm-arm/arch-vnc/hardware.h
include/asm-arm/arch-vnc/io.h
include/asm-arm/arch-vnc/irqs.h
include/asm-arm/arch-vnc/processor.h
include/asm-arm/arch-vnc/system.h
include/asm-arm/arch-vnc/time.h
include/asm-arm/atomic.h
include/asm-arm/byteorder.h
include/asm-arm/dec21285.h
include/asm-arm/dma.h
include/asm-arm/hardware.h
include/asm-arm/init.h
include/asm-arm/io.h
include/asm-arm/ioc.h [new file with mode: 0644]
include/asm-arm/iomd.h [new file with mode: 0644]
include/asm-arm/leds.h
include/asm-arm/memc.h [new file with mode: 0644]
include/asm-arm/proc-armo/pgtable.h
include/asm-arm/proc-armo/system.h
include/asm-arm/proc-armv/mm-init.h
include/asm-arm/proc-armv/page.h
include/asm-arm/proc-armv/semaphore.h
include/asm-arm/proc-armv/system.h
include/asm-arm/proc-armv/uaccess.h
include/asm-arm/semaphore.h
include/asm-arm/signal.h
include/asm-arm/softirq.h
include/asm-arm/spinlock.h
include/asm-arm/termbits.h
include/asm-arm/timex.h
include/asm-arm/unistd.h
include/asm-i386/termbits.h
include/asm-i386/unistd.h
include/asm-m68k/termbits.h
include/asm-mips/termbits.h
include/asm-ppc/bitops.h
include/asm-ppc/dma.h
include/asm-ppc/ide.h
include/asm-ppc/pgtable.h
include/asm-ppc/termbits.h
include/linux/mm.h
include/linux/nls.h
include/linux/sched.h
include/linux/sunrpc/stats.h
include/linux/sunrpc/xprt.h
include/linux/tty.h
include/linux/ufs_fs.h
include/net/br.h
include/net/ip_masq.h
kernel/exit.c
kernel/fork.c
mm/page_alloc.c
mm/vmscan.c
net/bridge/br.c
net/bridge/br_tree.c
net/core/dev.c
net/ipv4/ip_fw.c
net/ipv4/tcp.c
net/netrom/af_netrom.c
net/netsyms.c
net/sched/sch_api.c
net/sched/sch_csz.c
net/sunrpc/sched.c
net/sunrpc/sysctl.c
net/sunrpc/xprt.c
net/wanrouter/patchlevel
scripts/header.tk
scripts/mkdep.c
scripts/tkgen.c
scripts/ver_linux [new file with mode: 0644]

diff --git a/CREDITS b/CREDITS
index 3c603eb20744ac285215f3cb44198183dc26f80a..a16af041e068dfe89db4b64e026718ffa881e9b7 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1581,8 +1581,8 @@ S: 75019 Paris
 S: France
 
 N: Rik van Riel
-E: H.H.vanRiel@phys.uu.nl
-W: http://www.phys.uu.nl/~riel/
+E: H.H.vanRiel@humbolt.geo.uu.nl
+W: http://humbolt.geo.uu.nl/
 D: Maintainer of the mm-patches page (see www.linuxhq.com)
 D: Documentation/sysctl/*, kswapd fixes, random kernel hacker
 S: Vorenkampsweg 1
@@ -1631,6 +1631,14 @@ N: Alessandro Rubini
 E: rubini@ipvvis.unipv.it
 D: the gpm mouse server and kernel support for it
 
+N: Philipp Rumpf
+E: prumpf@jcsbs.lanobis.de
+D: ipi_count for x86
+D: random bugfixes
+S: Rueting 4
+S: 23743 Groemitz
+S: Germany
+
 N: Paul Russell
 E: Paul.Russell@rustcorp.com.au
 W: http://www.rustcorp.com
@@ -1720,6 +1728,16 @@ D: wd33c93 SCSI driver (linux-m68k)
 S: San Jose, California
 S: USA
 
+N: Jaspreet Singh
+E: jaspreet@sangoma.com
+W: www.sangoma.com
+D: WANPIPE driver for Sangoma S508/FT1 cards 
+S: Sangoma Technologies Inc.,
+S: 1001 Denison Street
+S: Suite 101
+S: Markham, Ontario L3R 2Z6
+S: Canada
+
 N: Rick Sladkey
 E: jrs@world.std.com
 D: utility hacker: Emacs, NFS server, mount, kmem-ps, UPS debugger, strace, GDB
index 3c0fee5e2721df1653226523b07743928425c1a4..4ea89e32373e702de21a67ef469e82c01182cb40 100644 (file)
@@ -21,13 +21,13 @@ This will override the configuration in mcdx.h.
 
 This driver:
 
-    o   handles XA (and hopefully) multi session CDs as well as
+    o   handles XA and (hopefully) multi session CDs as well as
         ordinary CDs;
     o   supports up to 5 drives (of course, you'll need free 
         IRQs, i/o ports and slots);
     o   uses much less kernel memory than the standard mcd driver
         (no extra driver internal buffers!).
-        o   plays audio (like the `old' driver, I hope)
+    o   plays audio (like the `old' driver, I hope)
 
 This version doesn't support yet:
 
index 03292883469c0a0f6db3914d1e26a09fa5f3f8f6..32d78266c73031063d649cf3210792e728036434 100644 (file)
@@ -10,7 +10,7 @@ The Digiboard Driver for Linux supports the following boards:
 
 In case you have problems with this version (1.6.1) of this driver, please
 email directly to me as I made the last update. It you have a report about
-runnning it on other architectures than intel, email me, so I can document
+running it on other architectures than intel, email me, so I can document
 it here.
 
 A version of this driver has been taken by Digiboard to make a driver
index 9904afb392bbcd42df75b96c6b14a290160d40a6..09f6ea2bfaf856d5867a4da94dcd2cea31bb7562 100644 (file)
@@ -27,7 +27,7 @@ Device names start at 0 and continue up.  Beware of this as previous Digi
 drivers started device names with 1.
 
 PCI boards are auto-detected and configured by the driver.  PCI boards will
-be allocated device numbers (internally) begining with the lowest PCI slot
+be allocated device numbers (internally) beginning with the lowest PCI slot
 first.  In other words a PCI card in slot 3 will always have higher device
 nodes than a PCI card in slot 1. 
 
@@ -46,7 +46,7 @@ are:
    Base of memory window (in HEX if using string identifiers), 
 
 NOTE : PCI boards are auto-detected and configured.  Do not attempt to 
-configure PCI boards with the LILO append comand.  If you wish to override
+configure PCI boards with the LILO append command.  If you wish to override
 previous configuration data (As set by digiConfig), but you do not wish to
 configure any specific card (Example if there are PCI cards in the system) 
 the following override command will accomplish this:
index cb1b9b2091acb5a90ccade6989f37208da4c53cc..feb29154084c6666a7c9579e8e3dc0e46a7ff340 100644 (file)
@@ -118,8 +118,17 @@ bios     - preserve state of BIOS ROM. It is default. Driver does not enable BIO
 noinit   - tells driver, that devices were already initialized. You should use it
            if you have G100 and/or if driver cannot detect memory, you see strange
           pattern on screen and so on. Devices not enabled by BIOS are still
-          initialized.
-init     - driver initializes every device it knows about. It is default.
+          initialized. It is default.
+init     - driver initializes every device it knows about.
+nomtrr   - disables write combining on frame buffer. This slows down driver but
+           there is reported minor incompatibility between GUS DMA and XFree under
+          high loads if write combining is enabled (sound dropouts).
+mtrr     - enables write combining on frame buffer. It speeds up video accesses
+           much. It is default. You must have MTRR support enabled in kernel and
+          your CPU must have MTRR (f.e. Pentium II have them).
+sgram    - tells to driver that you have G200 with SGRAM memory. It has no effect 
+           without `init'.
+sdram    - tells to driver that you have G200 with SDRAM memory. It is a default.
 inv24    - change timings parameters for 24bpp modes on Millenium and Millenium II.
            Specify this if you see strange color shadows around characters.
 noinv24  - use standard timmings. It is default.
@@ -200,6 +209,7 @@ Currently there are following known bugs:
  + 24bpp does not support correctly XF-FBDev on big-endian architectures.
  + interlaced text mode is not supported; it looks like hardware limitiation,
    but I'm not sure.
+ + G200 SGRAM/SDRAM is not autodetected.
  + maybe more...
 And following misfeatures:
  + SVGALib does not restore screen on exit.
index 155095db162ee476f33c0aefc237fa3dbca7c0b3..eb5d6749b2b3d9ebd597be928b1622448e8ce9aa 100644 (file)
@@ -7,7 +7,7 @@ There are 3 Types of this card available. A ISA-, MCA-, and PCMCIA-Bus
 Version. Currently, only the ISA-Bus version of the card is supported.
 However MCA and PCMCIA will follow soon.
 
-The ISA-Bus Version uses 8 IO-ports. The base port adress has to be set
+The ISA-Bus Version uses 8 IO-ports. The base port address has to be set
 manually using the DIP switches.
 
 Setting up the DIP switches for the IBM Active 2000 ISDN card:
index 1e46096caff1fad2361214dd6312adcb8019892b..7728692fcbc2cd16228f6e3fff97d7ef20b1e787 100644 (file)
@@ -229,7 +229,7 @@ protocols (e.g. by a member struct concap_proto* in struct device)
 then the interface of the service function could be changed
 by passing a pointer of type (struct device*) instead of
 type (struct concap_proto*). Doing so would make many of the service
-functions compatible to network device support fuctions.
+functions compatible to network device support functions.
 
 e.g. instead of the concap protocol's service function
 
@@ -241,7 +241,7 @@ we could have
 
 As this is compatible to the dev->hard_start_xmit() method, the device
 driver could directly register the concap protocol's encap_and_xmit()
-fuction as its hard_start_xmit() method. This would eliminate one
+function as its hard_start_xmit() method. This would eliminate one
 procedure call layer.
 
 
index cc1b701208c09e94f93adf22d2c81a780af66760..0964f734c34b1a97d5658f918ca88b7b5d83845f 100644 (file)
@@ -210,7 +210,7 @@ The latter problem could be reproduced by using hisax as well as the
 isdnloop driver. It seems that it is not caused by the isdn code.
 Somehow, the inode of a socket is freed while a process still refers
 the socket's wait queue. This causes problems when the process tries to
-remove itself from the wait queue (refered by the dangling
+remove itself from the wait queue (referred by the dangling
 sock->sleep pointer) before returning from a select() system call.
 
 - Henner
index 91a01676172a510443252358bd7f28718fdfb126..d2a797e0b18174634a799d02d7ae9215d7e2aea7 100644 (file)
@@ -45,7 +45,7 @@ exists, and neither will have any effect on the other.
 I wanted the two lock styles to be cooperative, but there were so many
 race and deadlock conditions that the current solution was the only
 practical one. It puts us in the same position as, for example, SunOS
-4.1.x and serveral other commercial Unices. The only OS's that support
+4.1.x and several other commercial Unices. The only OS's that support
 cooperative flock()/fcntl() are those that emulate flock() using
 fcntl(), with all the problems that implies.
 
index 8d3994d424c80fe123107f4ec780a23ddbac7f2b..22a35a3016844c6b904d24649630dde0db8ffe86 100644 (file)
@@ -617,7 +617,7 @@ ignored (others aren't affected).
     Legal values are between 0 and 255. Default: 255/0. Note: This
     value is forced to 0 on a Falcon, since scatter-gather isn't
     possible with the ST-DMA. Not using scatter-gather hurts
-    perfomance significantly.
+    performance significantly.
 
   <host-id>:
     The SCSI ID to be used by the initiator (your Atari). This is
index 2f8446381d14b950408265e8704ed852b1fe6813..48ed2b711bd270cce9ccd9fb454bee17a40e3dd6 100644 (file)
@@ -16,7 +16,7 @@ the TNC over a serial line. It can be used as an alternative to KISS.
 - The PC is given full control over the radio
   channel. Special control data is exchanged between the PC and the TNC so
   that the PC knows at any time if the TNC is receiving data, if a TNC
-  buffer underrun or overrun has occured, if the PTT is
+  buffer underrun or overrun has occurred, if the PTT is
   set and so on. This control data is processed at a higher priority than
   normal data, so a data stream can be interrupted at any time to issue an
   important event. This helps to improve the channel access and timing 
@@ -167,7 +167,7 @@ I haven't modified or removed them yet -- sorry! The code itself needs
 some cleaning and optimizing. This will be done in a later release.
 
 If you encounter a bug or if you have a question or suggestion concerning the
-driver, feel free to mail me, using the adresses given at the beginning of
+driver, feel free to mail me, using the addresses given at the beginning of
 this file.
 
 Have fun!
index ffebd188e9bee0da132459721a560a5347d6aabb..0c1dbcea9b8ff2bd801d711d2443b239779a6667 100644 (file)
@@ -2560,7 +2560,7 @@ Setting the Timeouts
 --------------------
 
 The two jumpers labeled ET1 and ET2 are used to determine the timeout
-parameters (respons and reconfiguration time). Every node in a network
+parameters (response and reconfiguration time). Every node in a network
 must be set to the same timeout values.
 
    ET1 ET2 | Response Time (us) | Reconfiguration Time (ms)
index 23723dfe52083a410986820a35815513a213e9ed..3251a247c7c885ff680dff1d820548c724f7fa77 100644 (file)
@@ -17,7 +17,7 @@ TANGENT driver mode:
 DAYNA driver mode:
        Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95,
        Farallon PhoneNET PC III, Farallon PhoneNET PC II
-Other cards possibly supported mode unkown though:
+Other cards possibly supported mode unknown though:
        Dayna DL2000 (Full length)
 
 The COPS driver defaults to using Dayna mode. To change the driver's 
index 88378de77109654248868c35680a96dea0a068c2..c8e4ca9b2c3e69f212a99dae80d9f964f0ab3ff3 100644 (file)
     autonegotiation feature in  the SROM autoconf  code, this detection will
     occur automatically for that case.
 
-    Command line arguements are  now allowed, similar to  passing arguements
+    Command line  arguments are  now allowed, similar to  passing  arguments
     through LILO. This will allow a per adapter board set  up of full duplex
     and media. The only lexical constraints are:  the board name (dev->name)
     appears in  the list before its parameters.  The list of parameters ends
index df9fc86a7c374ced6560a25ccf7fb8569af3a678..9915b8713bc329d1924847b9caa239f637441189 100644 (file)
@@ -51,7 +51,7 @@ Where the aedsp16 options are the options for this driver while opl3 and
 ad1848 are the corresponding options for the MSS and OPL3 modules.
 
 Loading MSS and OPL3 needs to pre load the aedsp16 module to set up correctly
-the sound card. Installation dependancies must be written in the conf.modules
+the sound card. Installation dependencies must be written in the conf.modules
 file:
 
 pre-install ad1848 modprobe aedsp16
index 1e3bf058253af52bd3f62d13fc5c49896a0b2398..337d94bfbd1243f5864f967d9879b5d80704396f 100644 (file)
@@ -2,7 +2,7 @@ Documentation for the OPL3-SA2, SA3, and SAx driver (opl3sa2.o)
 ---------------------------------------------------------------
 
 Scott Murray, scottm@interlog.com
-December, 1998
+January 5, 1998
 
 NOTE: All trade-marked terms mentioned below are properties of their
       respective owners.
@@ -97,25 +97,12 @@ butting heads with another device.
 
 If you still cannot get the module to load, look at the contents of
 your system log file, usually /var/log/messages.  If you see the
-message "No Yamaha audio controller found", then you have a different
-chipset than I've encountered so far.  Look for a line in the log file
-that says "opl3sa2.c: chipset version = <some number>".  If you want
-me to add support for your card, send me the number from this line and
-any information you have on the make and chipset of your sound card,
-and I should be able to work up a permanent fix.
-
-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.
+message "Unknown Yamaha audio controller version", then you have a
+different chipset than I've encountered so far.  Look for a line in
+the log file that says "opl3sa2.c: chipset version = <some number>".
+If you want me to add support for your card, send me the number from
+this line and any information you have on the make and chipset of your
+sound card, and I should be able to work up a permanent fix.
 
 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
diff --git a/Documentation/sound/VIA-chipset b/Documentation/sound/VIA-chipset
new file mode 100644 (file)
index 0000000..178eda5
--- /dev/null
@@ -0,0 +1,43 @@
+Running sound cards on VIA chipsets
+
+o      There are problems with VIA chipsets and sound cards that appear to
+       lock the hardware solidly. Test programs under DOS have verified the
+       problem exists on at least some (but apparently not all) VIA boards
+
+o      VIA have so far failed to bother to answer support mail on the subject
+       so if you are a VIA engineer feeling aggrieved as you read this 
+       document go chase your own people. If there is a workaround please
+       let us know so we can implement it.
+
+
+Certain patterns of ISA DMA access used for most PC sound cards cause the
+VIA chipsets to lock up. From the collected reports this appears to cover a
+wide range of boards. Some also lock up with sound cards under Win* as well.
+
+Linux implements a workaround providing your chipset is PCI and you compiled
+with PCI Quirks enabled. If so you will see a message
+       "Activating ISA DMA bug workarounds"
+
+during booting. If you have a VIA PCI chipset that hangs when you use the
+sound and is not generating this message even with PCI quirks enabled
+please report the information to the linux-kernel list (see REPORTING-BUGS).
+
+If you are one of the tiny number of unfortunates with a 486 ISA/VLB VIA
+chipset board you need to do the following to build a special kernel for
+your board
+
+       edit linux/include/asm-i386/dma.h
+
+change
+
+#define isa_dma_bridge_buggy   (0)
+
+to
+
+#define isa_dma_bridge_buggy   (1)
+
+and rebuild a kernel without PCI quirk support.
+
+
+Other than this paticular glitch the VIA [M]VP* chipsets appear to work
+perfectly with Linux.
index 11d3f3f0bd877251f768a49043bbb6d8b22e3876..ba53359ffe9792a447fa37dce8f74ce869f016e1 100644 (file)
@@ -13,7 +13,7 @@ Furthermore, the programmers who built sysctl have built it to
 be actually used, not just for the fun of programming it :-)
 
 If you prefer HTML, feel free to visit the Linux-MM homepage
-<http://www.phys.uu.nl/~riel/mm-patch/>...
+<http://humbolt.geo.uu.nl/Linux-MM/>...
 
 ==============================================================
 
index 5b3780cc308be3c8bd5b97ad73815deb96f7addc..1af60ed4eb39de60268a2f3e5227869eca3351ce 100644 (file)
@@ -314,7 +314,7 @@ A second way to handle image capture is via the mmap interface if supported.
 To use the mmap interface a user first sets the desired image size and depth
 properties. Next the VIDIOCGMBUF ioctl is issued. This reports the size
 of buffer to mmap and the offset within the buffer for each frame. The
-number of frames supported is device dependant and may only be one. 
+number of frames supported is device dependent and may only be one. 
 <P>
 The video_mbuf structure contains the following fields
 <P>
index 1126e7805a2231c745fb83e85fb28644497b0dc8..c0ae7a862acbcb2130d4e28d41c8401c8f5457ac 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 0
-EXTRAVERSION =-pre5
+EXTRAVERSION =-pre6
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
diff --git a/README b/README
index 11a3016678fe72044bb99f58375252f124542837..b1bac81558f52408d07247ef4a82dec59188aad6 100644 (file)
--- a/README
+++ b/README
@@ -48,12 +48,12 @@ INSTALLING the kernel:
  - If you install the full sources, do a
 
                cd /usr/src
-               gzip -cd linux-2.1.XX.tar.gz | tar xfv -
+               gzip -cd linux-2.2.XX.tar.gz | tar xfv -
 
    to get it all put in place. Replace "XX" with the version number of the
    latest kernel.
 
- - You can also upgrade between 2.1.xx releases by patching.  Patches are
+ - You can also upgrade between 2.2.xx releases by patching.  Patches are
    distributed in the traditional gzip and the new bzip2 format.  To
    install by patching, get all the newer patch files and do
 
@@ -91,7 +91,7 @@ INSTALLING the kernel:
 
 SOFTWARE REQUIREMENTS
 
-   Compiling and running the 2.1.x kernels requires up-to-date
+   Compiling and running the 2.2.x kernels requires up-to-date
    versions of various software packages.  Consult
    ./Documentation/Changes for the minimum version numbers required
    and how to get updates for these packages.  Beware that using
@@ -145,7 +145,7 @@ CONFIGURING the kernel:
 
 COMPILING the kernel:
 
- - Make sure you have gcc-2.7.0 or newer available.  It seems older gcc
+ - Make sure you have gcc-2.7.2 or newer available.  It seems older gcc
    versions can have problems compiling newer versions of Linux.  This
    is mainly because the older compilers can only generate "a.out"-format
    executables.  As of Linux 2.1.0, the kernel must be compiled as an
diff --git a/REPORTING-BUGS b/REPORTING-BUGS
new file mode 100644 (file)
index 0000000..7c75d94
--- /dev/null
@@ -0,0 +1,56 @@
+[Some of this is taken from Frohwalt Egerer's original linux-kernel FAQ]
+
+     What follows is a suggested proceedure for reporting Linux bugs. You
+aren't obliged to use the bug reporting format, it is provided as a guide
+to the kind of information that can be useful to developers - no more.
+
+     If the failure includes an "OOPS:" type message in your log or on
+screen please read "Documentation/oops-tracing.txt" before posting your
+bug report. This explains what you should do with the "Oops" information
+to make it useful to the recipient.
+
+      Send the output the maintainer of the kernel area that seems to
+be involved with the problem. Don't worry too much about getting the
+wrong person. If you are unsure send it to the person responsible for the
+code relevant to what you were doing. If it occurs repeatably try and
+describe how to recreate it. That is worth even more than the oops itself.
+The list of maintainers is in the MAINTAINERS file in this directory.
+
+      If you are totally stumped as to whom to send the report, send it to
+linux-kernel@vger.rutgers.edu. (For more information on the linux-kernel
+mailing list see http://www.tux.org/lkml/).
+
+This is a suggested format for a bug report sent to the Linux kernel mailing 
+list. Having a standardized bug report form makes it easier  for you not to 
+overlook things, and easier for the developers to find the pieces of 
+information they're really interested in.
+
+   First run the ver_linux script included as scripts/ver_linux or
+at <URL:ftp://ftp.sai.msu.su//sai2/ftp/pub/Linux/ver_linux> It checks out
+the version of some important subsystems. Run it with the commnd
+"sh scripts/ver_linux"
+
+Use that information to fill in all fields of the bug report form, and
+post it to the mailing list with a subject of "ISSUE: <one line
+summary from [1.]>" for easy identification by the developers    
+
+[1.] One line summary of the problem:    
+[2.] Full description of the problem/report:
+[3.] Keywords (i.e., modules, networking, kernel):
+[4.] Kernel version (from /proc/version):
+[5.] Output of Oops.. message (if applicable) with symbolic information 
+     resolved (see Documentation/oops-tracing.txt)
+[6.] A small shell script or example program which triggers the
+     problem (if possible)
+[7.] Environment
+[7.1.] Software (add the output of the ver_linux script here)
+[7.2.] Processor information (from /proc/cpuinfo):
+[7.3.] Module information (from /proc/modules):
+[7.4.] SCSI information (from /proc/scsi/scsi)
+[7.5.] Other information that might be relevant to the problem
+       (please look in /proc and include all information that you
+       think to be relevant):
+[X.] Other notes, patches, fixes, workarounds:
+
+
+Thank you
index 562778366da8586fb7530a4acff5acc75e7f3cf3..918f9c59d970181106e481b0b6a3044342f6b73c 100644 (file)
@@ -55,7 +55,6 @@
 unsigned long init_user_stack[1024] = { STACK_MAGIC, };
 static struct vm_area_struct init_mmap = INIT_MMAP;
 static struct fs_struct init_fs = INIT_FS;
-static struct file * init_fd_array[NR_OPEN] = { NULL, };
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS;
 struct mm_struct init_mm = INIT_MM;
index 41267ab281353e1ae82731188faae547600e477c..9114c3618383e76844e865779ba4f00cc658ea5e 100644 (file)
@@ -97,6 +97,8 @@ if [ "$CONFIG_APM" = "y" ]; then
   bool '   Power off on shutdown' CONFIG_APM_POWER_OFF
   bool '   Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
   bool '   Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+  bool '   RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT
+  bool '   Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS
 fi
 
 endmenu
index 1cbc824f51d43a56988e15ea0ca9fa3210b27703..4faf49f4cbc0048f3868244c0d9e865ad3c7d690 100644 (file)
@@ -31,6 +31,7 @@
  * Aug 1998, Version 1.5
  * Sep 1998, Version 1.6
  * Nov 1998, Version 1.7
+ * Jan 1999, Version 1.8
  *
  * History:
  *    0.6b: first version in official kernel, Linux 1.3.46
  *         Make boot messages far less verbose by default
  *         Make asm safer
  *         Stephen Rothwell
+ *    1.8: Add CONFIG_APM_RTC_IS_GMT
+ *         Richard Gooch <rgooch@atnf.csiro.au>
+ *         change APM_NOINTS to CONFIG_APM_ALLOW_INTS
+ *         remove dependency on CONFIG_PROC_FS
+ *         Stephen Rothwell
  *
  * APM 1.1 Reference:
  *
 #include <linux/fcntl.h>
 #include <linux/malloc.h>
 #include <linux/linkage.h>
-#ifdef CONFIG_PROC_FS
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
-#endif
 #include <linux/miscdevice.h>
 #include <linux/apm_bios.h>
 #include <linux/init.h>
@@ -201,13 +205,6 @@ extern unsigned long get_cmos_time(void);
  */
 #define ALWAYS_CALL_BUSY
 
-/*
- * Define to disable interrupts in APM BIOS calls (the CPU Idle BIOS call
- * should turn interrupts on before it does a 'hlt').
- * This reportedly needs undefining for the ThinkPad 600.
- */
-#define APM_NOINTS
-
 /*
  * Define to make the APM BIOS calls zero all data segment registers (so
  * that an incorrect BIOS implementation will cause a kernel panic if it
@@ -266,9 +263,7 @@ static ssize_t      do_read(struct file *, char *, size_t , loff_t *);
 static unsigned int do_poll(struct file *, poll_table *);
 static int     do_ioctl(struct inode *, struct file *, u_int, u_long);
 
-#ifdef CONFIG_PROC_FS
 static int     apm_get_info(char *, char **, off_t, int, int);
-#endif
 
 extern int     apm_register_callback(int (*)(apm_event_t));
 extern void    apm_unregister_callback(int (*)(apm_event_t));
@@ -290,8 +285,13 @@ static int                 standbys_pending = 0;
 static int                     waiting_for_resume = 0;
 #endif
 
+#ifdef CONFIG_APM_RTC_IS_GMT
+#      define  clock_cmos_diff 0
+#      define  got_clock_diff  1
+#else
 static long                    clock_cmos_diff;
 static int                     got_clock_diff = 0;
+#endif
 static int                     debug = 0;
 static int                     apm_disabled = 0;
 
@@ -300,7 +300,7 @@ static struct apm_bios_struct *     user_list = NULL;
 
 static struct timer_list       apm_timer;
 
-static char                    driver_version[] = "1.7";       /* no spaces */
+static char                    driver_version[] = "1.8";       /* no spaces */
 
 #ifdef APM_DEBUG
 static char *  apm_event_name[] = {
@@ -375,22 +375,22 @@ static const lookup_t error_table[] = {
 #define ERROR_COUNT    (sizeof(error_table)/sizeof(lookup_t))
 
 /*
- * These are the actual BIOS calls.  Depending on APM_ZERO_SEGS
- * and APM_NOINTS, we are being really paranoid here!  Not only are
- * interrupts disabled, but all the segment registers (except SS) are
- * saved and zeroed this means that if the BIOS tries to reference any
- * data without explicitly loading the segment registers, the kernel will
- * fault immediately rather than have some unforeseen circumstances for
- * the rest of the kernel.  And it will be very obvious!  :-) Doing this
- * depends on CS referring to the same physical memory as DS so that DS
- * can be zeroed before the call. Unfortunately, we can't do anything
+ * These are the actual BIOS calls.  Depending on APM_ZERO_SEGS and
+ * CONFIG_APM_ALLOW_INTS, we are being really paranoid here!  Not only
+ * are interrupts disabled, but all the segment registers (except SS)
+ * are saved and zeroed this means that if the BIOS tries to reference
+ * any data without explicitly loading the segment registers, the kernel
+ * will fault immediately rather than have some unforeseen circumstances
+ * for the rest of the kernel.  And it will be very obvious!  :-) Doing
+ * this depends on CS referring to the same physical memory as DS so that
+ * DS can be zeroed before the call. Unfortunately, we can't do anything
  * about the stack segment/pointer.  Also, we tell the compiler that
  * everything could change.
  *
  * Also, we KNOW that for the non error case of apm_bios_call, there
  * is no useful data returned in the low order 8 bits of eax.
  */
-#ifdef APM_NOINTS
+#ifndef CONFIG_APM_ALLOW_INTS
 #      define APM_DO_CLI       __cli()
 #else
 #      define APM_DO_CLI
@@ -747,14 +747,17 @@ static void suspend(void)
        unsigned long   flags;
        int             err;
 
-                               /* Estimate time zone so that set_time can
-                                   update the clock */
+#ifndef CONFIG_APM_RTC_IS_GMT
+       /*
+        * Estimate time zone so that set_time can update the clock
+        */
        save_flags(flags);
        clock_cmos_diff = -get_cmos_time();
        cli();
        clock_cmos_diff += CURRENT_TIME;
        got_clock_diff = 1;
        restore_flags(flags);
+#endif
 
        err = apm_set_power_state(APM_STATE_SUSPEND);
        if (err)
@@ -826,7 +829,7 @@ static void check_events(void)
        apm_event_t             event;
 #ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
        static unsigned long    last_resume = 0;
-       static int              did_resume = 0;
+       static int              ignore_bounce = 0;
 #endif
 
        while ((event = get_event()) != 0) {
@@ -837,6 +840,10 @@ static void check_events(void)
                else
                        printk(KERN_DEBUG "apm: received unknown "
                               "event 0x%02x\n", event);
+#endif
+#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+               if (ignore_bounce && ((jiffies - last_resume) > HZ))
+                       ignore_bounce = 0;
 #endif
                switch (event) {
                case APM_SYS_STANDBY:
@@ -859,7 +866,7 @@ static void check_events(void)
 #endif
                case APM_SYS_SUSPEND:
 #ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
-                       if (did_resume && ((jiffies - last_resume) < HZ))
+                       if (ignore_bounce)
                                break;
 #endif
 #ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
@@ -880,7 +887,7 @@ static void check_events(void)
 #endif
 #ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
                        last_resume = jiffies;
-                       did_resume = 1;
+                       ignore_bounce = 1;
 #endif
                        set_time();
                        send_event(event, 0, NULL);
@@ -1139,7 +1146,6 @@ static int do_open(struct inode * inode, struct file * filp)
        return 0;
 }
 
-#ifdef CONFIG_PROC_FS
 int apm_get_info(char *buf, char **start, off_t fpos, int length, int dummy)
 {
        char *          p;
@@ -1228,7 +1234,6 @@ int apm_get_info(char *buf, char **start, off_t fpos, int length, int dummy)
 
        return p - buf;
 }
-#endif
 
 void __init apm_setup(char *str, int *dummy)
 {
@@ -1422,10 +1427,9 @@ void __init apm_bios_init(void)
        apm_timer.expires = APM_CHECK_TIMEOUT + jiffies;
        add_timer(&apm_timer);
 
-#ifdef CONFIG_PROC_FS
        ent = create_proc_entry("apm", 0, 0);
-       ent->get_info = apm_get_info;
-#endif
+       if (ent != NULL)
+               ent->get_info = apm_get_info;
 
        misc_register(&apm_device);
 
index 1b0ef412ac9b4c4b1e8ecb46e018eaf5049a8a62..0153c4b40218af9bafc33fd618249193393d23b9 100644 (file)
@@ -559,13 +559,14 @@ ENTRY(sys_call_table)
        .long SYMBOL_NAME(sys_sendfile)
        .long SYMBOL_NAME(sys_ni_syscall)               /* streams1 */
        .long SYMBOL_NAME(sys_ni_syscall)               /* streams2 */
+       .long SYMBOL_NAME(sys_vfork)            /* 190 */
 
        /*
-        * NOTE!! This doesn' thave to be exact - we just have
+        * NOTE!! This doesn'have to be exact - we just have
         * to make sure we have _enough_ of the "sys_ni_syscall"
         * entries. Don't panic if you notice that this hasn't
         * been shrunk every time we add a new system call.
         */
-       .rept NR_syscalls-189
+       .rept NR_syscalls-190
                .long SYMBOL_NAME(sys_ni_syscall)
        .endr
index b7d00ea493bc62e9c113b056fea16b70070fa088..69548a950cb508dcbeba4f248a20a8dce18c23b1 100644 (file)
@@ -781,6 +781,18 @@ asmlinkage int sys_clone(struct pt_regs regs)
        return do_fork(clone_flags, newsp, &regs);
 }
 
+asmlinkage int sys_vfork(struct pt_regs regs)
+{
+       int     child;
+
+       child = do_fork(CLONE_VM | SIGCHLD, regs.esp, &regs);
+
+       if (child > 0)
+               sleep_on(&current->vfork_sleep);
+
+       return child;
+}
+
 /*
  * sys_execve() executes a new program.
  */
index 3420ef51d5ec22c191d7404fe8129a22e80cbd45..70eec52d2edd9375743ceb34493d9d9e9f79d792 100644 (file)
@@ -70,7 +70,7 @@ static inline int put_stack_long(struct task_struct *task, int offset,
 extern int _stext, _etext;
 static void print_child_state(struct task_struct *task)
 {
-       unsigned int * stack = (unsigned int *) task->tss.esp0;
+       unsigned int * stack = (unsigned int *) task->tss.esp;
        int count = 40;
 
        printk("Process: %s (stack=%p, task=%p)\n", task->comm, stack, task);
@@ -78,7 +78,7 @@ static void print_child_state(struct task_struct *task)
                unsigned int data;
                if ((unsigned int) stack < (unsigned int) task)
                        break;
-               if ((unsigned int) stack >= PAGE_SIZE + (unsigned int) task)
+               if ((unsigned int) stack >= 2*PAGE_SIZE + (unsigned int) task)
                        break;
                data = *stack;
                stack++;
@@ -394,15 +394,16 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                ret = 0;
                goto out;
        }
-       if (pid == 1)           /* you may not mess with init */
-               goto out;
        ret = -ESRCH;
        read_lock(&tasklist_lock);
        child = find_task_by_pid(pid);
        read_unlock(&tasklist_lock);    /* FIXME!!! */
        if (!child)
                goto out;
+print_child_state(child);
        ret = -EPERM;
+       if (pid == 1)           /* you may not mess with init */
+               goto out;
        if (request == PTRACE_ATTACH) {
                if (child == current)
                        goto out;
@@ -435,8 +436,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
        if (!(child->flags & PF_PTRACED))
                goto out;
        if (child->state != TASK_STOPPED) {
-print_child_state(child);
-goto out;
                if (request != PTRACE_KILL)
                        goto out;
        }
index 2fd9c39eba3935fb680b11abcecd7fa601197d02..cfab3ecfc7a026457b26f18a34ffd32694b66eda 100644 (file)
@@ -619,7 +619,7 @@ __initfunc(void print_cpu_info(struct cpuinfo_x86 *c))
        else
                printk("%s", c->x86_model_id);
 
-       if (c->x86_mask) 
+       if (c->x86_mask || c->cpuid_level>=0
                printk(" stepping %02x", c->x86_mask);
 
        if(c->x86_vendor == X86_VENDOR_CENTAUR)
index 25955213e8705460b59fc1cc4b31200000e75672..4fb8864568502edac750247e534ead4cf4cf77dd 100644 (file)
@@ -15,7 +15,7 @@
  *           - IRQ_FLG_SLOW: handler is inserted at bottom of list and before
  *                           they're executed irq level is set to the previous
  *                           one, but handlers don't need to be reentrant, if
- *                           reentrance occured, slow handlers will be just
+ *                           reentrance occurred, slow handlers will be just
  *                           called again.
  *           The whole interrupt handling for CIAs is moved to cia.c
  *           /Roman Zippel
@@ -367,7 +367,7 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server)
        for (;;) {
                for (; node; node = node->next)
                        node->handler(irq, node->dev_id, fp);
-               /* if reentrance occured, serve slow handlers again */
+               /* if reentrance occurred, serve slow handlers again */
                custom.intena = ami_intena_vals[irq];
                if (!server->reentrance) {
                        server->count--;
index c4cffcdf9e81609625c8747d562da0ed8276cc0d..18e29814e44d3bcd2c153629ccf0d6d054897d4a 100644 (file)
@@ -30,7 +30,7 @@ void dn_process_int(int irq, struct pt_regs *fp) {
     dn_irqs[irq-160].handler(irq,dn_irqs[irq-160].dev_id,fp);
   }
   else {
-    printk("spurious irq %d occured\n",irq);
+    printk("spurious irq %d occurred\n",irq);
   }
 
 #if 0  
index af5af69b62f49c351b55096cfb8d61a11abb1666..a2b9ce1d4102bc150f5f707b4075016e5f43c466 100644 (file)
@@ -361,7 +361,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
                         : "a0");
 #undef frame_offset
                /*
-                * If we ever get here an exception occured while
+                * If we ever get here an exception occurred while
                 * building the above stack-frame.
                 */
                goto badframe;
@@ -460,7 +460,7 @@ rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
                         : "a0");
 #undef frame_offset
                /*
-                * If we ever get here an exception occured while
+                * If we ever get here an exception occurred while
                 * building the above stack-frame.
                 */
                goto badframe;
index 690173cc9f81a9203f3d046572f0eaeaa3491950..e8f72f298ce01b3875195ad23377d33e3c299dbe 100644 (file)
@@ -19,7 +19,7 @@
  *           - IRQ_FLG_SLOW: handler is inserted at bottom of list and before
  *                           they're executed irq level is set to the previous
  *                           one, but handlers don't need to be reentrant, if
- *                           reentrance occured, slow handlers will be just
+ *                           reentrance occurred, slow handlers will be just
  *                           called again.
  *           The whole interrupt handling for CIAs is moved to cia.c
  *           /Roman Zippel
@@ -396,7 +396,7 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server)
        for (;;) {
                for (; node; node = node->next)
                        node->handler(irq, node->dev_id, fp);
-               /* if reentrance occured, serve slow handlers again */
+               /* if reentrance occurred, serve slow handlers again */
                custom.intena = ami_intena_vals[irq];
                if (!server->reentrance) {
                        server->count--;
diff --git a/arch/ppc/boot/ns16550.c b/arch/ppc/boot/ns16550.c
new file mode 100644 (file)
index 0000000..db0b94d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * COM1 NS16550 support
+ */
+
+#include "ns16550.h"
+typedef struct NS16550 *NS16550_t;
+
+const NS16550_t COM_PORTS[] = { (NS16550_t) COM1,
+    (NS16550_t) COM2,
+    (NS16550_t) COM3,
+    (NS16550_t) COM4 };
+
+volatile struct NS16550 *
+NS16550_init(int chan)
+{
+ volatile struct NS16550 *com_port;
+ volatile unsigned char xx;
+ com_port = (struct NS16550 *) COM_PORTS[chan];
+ /* See if port is present */
+ com_port->lcr = 0x00;
+ com_port->ier = 0xFF;
+#if 0
+ if (com_port->ier != 0x0F) return ((struct NS16550 *)0);
+#endif
+ com_port->ier = 0x00;
+ com_port->lcr = 0x80;  /* Access baud rate */
+ com_port->dll = 0xc;  /* 9600 baud */
+ com_port->dlm = 0xc >> 8;
+ com_port->lcr = 0x03;  /* 8 data, 1 stop, no parity */
+ com_port->mcr = 0x03;  /* RTS/DTR */
+ com_port->fcr = 0x07;  /* Clear & enable FIFOs */
+ return (com_port);
+}
+
+
+NS16550_putc(volatile struct NS16550 *com_port, unsigned char c)
+{
+ volatile int i;
+ while ((com_port->lsr & LSR_THRE) == 0) ;
+ com_port->thr = c;
+}
+
+unsigned char
+NS16550_getc(volatile struct NS16550 *com_port)
+{
+ while ((com_port->lsr & LSR_DR) == 0) ;
+ return (com_port->rbr);
+}
+
+NS16550_tstc(volatile struct NS16550 *com_port)
+{
+ return ((com_port->lsr & LSR_DR) != 0);
+}
+
+
+
diff --git a/arch/ppc/boot/ns16550.h b/arch/ppc/boot/ns16550.h
new file mode 100644 (file)
index 0000000..4baf4c1
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * NS16550 Serial Port
+ */
+
+struct NS16550
+ {
+  unsigned char rbr;  /* 0 */
+  unsigned char ier;  /* 1 */
+  unsigned char fcr;  /* 2 */
+  unsigned char lcr;  /* 3 */
+  unsigned char mcr;  /* 4 */
+  unsigned char lsr;  /* 5 */
+  unsigned char msr;  /* 6 */
+  unsigned char scr;  /* 7 */
+ };
+
+#define thr rbr
+#define iir fcr
+#define dll rbr
+#define dlm ier
+
+#define LSR_DR   0x01  /* Data ready */
+#define LSR_OE   0x02  /* Overrun */
+#define LSR_PE   0x04  /* Parity error */
+#define LSR_FE   0x08  /* Framing error */
+#define LSR_BI   0x10  /* Break */
+#define LSR_THRE 0x20  /* Xmit holding register empty */
+#define LSR_TEMT 0x40  /* Xmitter empty */
+#define LSR_ERR  0x80  /* Error */
+
+#define COM1 0x800003F8
+#define COM2 0x800002F8
+#define COM3 0x800003F8
+#define COM4 0x80000388
index 3c0a423452cfc076fc1fb24bb5bc6df8223e6dbd..f589657093028d66c8c92054e0a63a7d8d00512b 100644 (file)
@@ -253,16 +253,17 @@ CONFIG_FB_OF=y
 CONFIG_FB_CONTROL=y
 CONFIG_FB_PLATINUM=y
 CONFIG_FB_VALKYRIE=y
-# CONFIG_FB_ATY is not set
+CONFIG_FB_ATY=y
 CONFIG_FB_IMSTT=y
 CONFIG_FB_CT65550=y
 # CONFIG_FB_S3TRIO is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_ATY is not set
+CONFIG_FB_ATY=y
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB8=y
 CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
 CONFIG_FBCON_CFB32=y
 # CONFIG_FBCON_FONTWIDTH8_ONLY is not set
 CONFIG_FBCON_FONTS=y
index 30cd01a860b6f4a3e6bb39877b81a9fd4faf78d5..90647dcd986bd9d7f6ae862ea6b7b153a9091030 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: mbx_setup.c,v 1.4 1998/11/15 19:58:55 cort Exp $
+ * $Id: mbx_setup.c,v 1.5 1998/12/29 18:55:07 cort Exp $
  *
  *  linux/arch/ppc/kernel/setup.c
  *
@@ -59,18 +59,21 @@ extern void m8xx_cpm_reset(uint);
 void __init powermac_init(void)
 {
 }
+
 void __init adbdev_init(void)
 {
 }
 
 void __init mbx_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq)
 {
-
-       *p = 0;
-       *irq = 0;
-
-       if (base != 0)          /* Only map the first ATA flash drive */
-               return;
+       ide_ioreg_t port = base;
+       int i = 8;
+
+       while (i--)
+               *p++ = port++;
+       *p++ = base + 0x206;
+       if (irq != NULL)
+               *irq = 0;
 #ifdef ATA_FLASH
        base = (unsigned long) ioremap(PCMCIA_MEM_ADDR, 0x200);
        for (i = 0; i < 8; ++i)
index 197e8344113a2505e9fe1c86ec799026b9ebe4b5..1dfa3a6c8ba1e124e239ee233d8cf23107b03083 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: pci.c,v 1.42 1998/12/04 14:31:37 cort Exp $
+ * $Id: pci.c,v 1.43 1998/12/29 18:55:11 cort Exp $
  * Common pmac/prep/chrp pci routines. -- Cort
  */
 
@@ -123,8 +123,8 @@ __initfunc(void pcibios_init(void))
 __initfunc(void
           setup_pci_ptrs(void))
 {
-       PPC_DEVICE *hostbridge;
 #ifndef CONFIG_MBX  
+       PPC_DEVICE *hostbridge;
        switch (_machine) {
        case _MACH_prep:
                hostbridge=residual_find_device(PROCESSORDEVICE, NULL,
@@ -188,6 +188,7 @@ __initfunc(void pcibios_fixup(void))
        extern struct bridge_data **bridges;
        extern unsigned char *Motherboard_map;
        extern unsigned char *Motherboard_routes;
+       unsigned char i;
 #ifndef CONFIG_MBX
        switch (_machine )
        {
@@ -200,7 +201,7 @@ __initfunc(void pcibios_fixup(void))
                         * irq this device uses.  This is necessary on things
                         * without residual data. -- Cort
                         */
-                       unsigned char d = PCI_SLOT(dev->devfn), i;
+                       unsigned char d = PCI_SLOT(dev->devfn);
                        dev->irq = Motherboard_routes[Motherboard_map[d]];
                        for ( i = 0 ; i <= 5 ; i++ )
                        {
index 9720bacfa000d06f5585e444692a17be2c00a453..1b7753dd00895be9297990c6c8c796ec7cbb2183 100644 (file)
@@ -194,6 +194,7 @@ EXPORT_SYMBOL(find_compatible_devices);
 EXPORT_SYMBOL(find_path_device);
 EXPORT_SYMBOL(find_phandle);
 EXPORT_SYMBOL(get_property);
+EXPORT_SYMBOL(device_is_compatible);
 EXPORT_SYMBOL(pci_io_base);
 EXPORT_SYMBOL(pci_device_loc);
 EXPORT_SYMBOL(feature_set);
index 29d70bdfb8026084fe02caae47a0ac44ea5f0481..ebe64a4296ba43886fcc7e97cff89d39a38efd5a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: process.c,v 1.69 1998/12/28 10:28:49 paulus Exp $
+ * $Id: process.c,v 1.70 1999/01/07 16:28:59 cort Exp $
  *
  *  linux/arch/ppc/kernel/process.c
  *
@@ -191,19 +191,6 @@ switch_to(struct task_struct *prev, struct task_struct *new)
        _enable_interrupts(s);
 }
 
-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");
-}
-
 void show_regs(struct pt_regs * regs)
 {
        int i;
@@ -244,6 +231,19 @@ void show_regs(struct pt_regs * regs)
 out:
 }
 
+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");
+}
+
 void exit_thread(void)
 {
        if (last_task_used_math == current)
index b52f6d92b1c462cc904baf6691c4875b121d9514..50cd70889f2de0bbc2e7ece6344546cf2f0eb9a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: setup.c,v 1.120 1998/12/10 00:24:28 cort Exp $
+ * $Id: setup.c,v 1.122 1998/12/31 20:51:19 cort Exp $
  * Common prep/pmac/chrp boot and setup code.
  */
 
@@ -259,6 +259,9 @@ void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq)
                break;
        }
 #endif
+#if defined(CONFIG_MBX)
+       mbx_ide_init_hwif_ports(p,base,irq);
+#endif 
 }
 EXPORT_SYMBOL(ide_init_hwif_ports);
 #endif
@@ -464,9 +467,9 @@ int get_cpuinfo(char *buffer)
  * Find out what kind of machine we're on and save any data we need
  * from the early boot process (devtree is copied on pmac by prom_init() )
  */
-__initfunc(unsigned long
+unsigned long __init
 identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
-                unsigned long r6, unsigned long r7))
+                unsigned long r6, unsigned long r7)
 {
        extern void setup_pci_ptrs(void);
        
@@ -491,6 +494,9 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
                char *model;
 
                have_of = 1;
+               
+               /* prom_init has already been called from __start */
+               finish_device_tree();
                /* ask the OF info if we're a chrp or pmac */
                model = get_property(find_path_device("/"), "device_type", NULL);
                if ( model && !strncmp("chrp",model,4) )
@@ -510,8 +516,10 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
 
        if ( have_of )
        {
+#ifdef CONFIG_MACH_SPECIFIC
                /* prom_init has already been called from __start */
                finish_device_tree();
+#endif /* CONFIG_MACH_SPECIFIC */
                /*
                 * If we were booted via quik, r3 points to the physical
                 * address of the command-line parameters.
index 72bffcc5764e1e8429dfc60d65ff59cbb52e1eb2..b80d4c21cce5c2909eba67abf1db9b577b219d68 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  $Id: init.c,v 1.138 1998/12/15 17:34:43 cort Exp $
+ *  $Id: init.c,v 1.139 1998/12/29 19:53:49 cort Exp $
  *
  *  PowerPC version 
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
@@ -1027,6 +1027,8 @@ __initfunc(void MMU_init(void))
         ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE);
         ioremap(IMAP_ADDR, IMAP_SIZE);
         ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE);
+       /* ide needs to be able to get at PCI space -- Cort */
+        ioremap(0x80000000, 0x4000);
 #endif /* CONFIG_8xx */
 }
 
@@ -1297,7 +1299,7 @@ __initfunc(unsigned long *pmac_find_end_of_memory(void))
 /*
  * This finds the amount of physical ram and does necessary
  * setup for prep.  This is pretty architecture specific so
- * this will likely stay seperate from the pmac.
+ * this will likely stay separate from the pmac.
  * -- Cort
  */
 __initfunc(unsigned long *prep_find_end_of_memory(void))
index 2f0c78168bf0c692ab0494e77d3e96ed8dca5cc3..d02b6dfb2d87b0bf0fd9d81c363dc45204a8e9aa 100644 (file)
@@ -535,7 +535,7 @@ C_LABEL(__csum_partial_copy_end):
 /* %o1 is dst
  * %o3 is # bytes to zero out
  * %o4 is faulting address
- * %o5 is %pc where fault occured */
+ * %o5 is %pc where fault occurred */
        clr     %o2
 31:
 /* %o0 is src
@@ -543,7 +543,7 @@ C_LABEL(__csum_partial_copy_end):
  * %o2 is # of bytes to copy from src to dst
  * %o3 is # bytes to zero out
  * %o4 is faulting address
- * %o5 is %pc where fault occured */
+ * %o5 is %pc where fault occurred */
        save    %sp, -104, %sp
         mov     %i5, %o0
         mov     %i7, %o1
index 9597bd51aeb1cd0b74b2e3cfc85ea809e52bd3f1..8cf2614b9c46e4ee952005ff7370885546f83b78 100644 (file)
@@ -1039,7 +1039,7 @@ static void fd_rwsec_done(int status)
 static void fd_times_out(unsigned long dummy)
 {
        SET_IRQ_HANDLER(NULL);
-       /* If the timeout occured while the readtrack_check timer was
+       /* If the timeout occurred while the readtrack_check timer was
         * active, we need to cancel it, else bad things will happen */
        del_timer( &readtrack_timer ); 
        FDC1772_WRITE(FDC1772REG_CMD, FDC1772CMD_FORCI);
index cbde66a81b0ca162ec77d18d516ba45c8801aa8c..7f8f1a64a6b5fe5aa0cb5f6b69e6ad23c7803c8c 100644 (file)
@@ -100,11 +100,18 @@ const char *good_dma_drives[] = {"Micropolis 2112A",
  * bad_dma_drives() lists the model names (from "hdparm -i")
  * of drives which supposedly support (U)DMA but which are
  * known to corrupt data with this interface under Linux.
+ *
+ * This is an empirical list. Its generated from bug reports. That means
+ * while it reflects actual problem distributions it doesn't answer whether
+ * the drive or the controller, or cabling, or software, or some combination
+ * thereof is the fault. If you don't happen to agree with the kernel's 
+ * opinion of your drive - use hdparm to turn DMA on.
  */
 const char *bad_dma_drives[] = {"WDC AC11000H",
                                "WDC AC22100H",
                                "WDC AC32500H",
                                "WDC AC33100H",
+                               "WDC AC31600H",
                                NULL};
 
 /*
@@ -246,7 +253,7 @@ int check_drive_lists (ide_drive_t *drive, int good_bad)
                list = bad_dma_drives;
                while (*list) {
                        if (!strcmp(*list++,id->model)) {
-                               printk("%s: (U)DMA capability is broken for %s\n",
+                               printk("%s: Disabling (U)DMA for %s\n",
                                        drive->name, id->model);
                                return 1;
                        }
index cb33f73383099cdc2daa3bb14c61fe705d09ca83..5b618d8f2beaa3ffd3440ea110fd2d6eb098a1b4 100644 (file)
 /*
  *     Some tape drives require a long irq timeout
  */
-#define IDETAPE_WAIT_CMD               60
+#define IDETAPE_WAIT_CMD               (60*HZ)
 
 /*
  *     DSC timings.
index 2ea4bf393d7adf4344db5e52231346d425f23434..8adc37fcb8863bd678ca48ed305380d748823a18 100644 (file)
@@ -894,7 +894,7 @@ __initfunc(static void xd_wd_init_drive (u_char drive))
                                xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
                                        ((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);
                }
-       /* 1002 based RLL controler requests converted adressing, but reports physical 
+       /* 1002 based RLL controler requests converted addressing, but reports physical 
           (physical 26 sec., logical 17 sec.) 
           1004 based ???? */
                if (rll & wd_1002) {
index 8b32ddb7d63f77963a8c3858cd440717f9d30d3d..a0ab135ec6eae4f06c3ee5596f71f343c304fef9 100644 (file)
@@ -417,7 +417,7 @@ int open_for_data(struct cdrom_device_info * cdi)
                        cdo->lock_door(cdi, 1);
                        cdinfo(CD_OPEN, "door locked.\n");
        }       
-       cdinfo(CD_OPEN, "device opened sucessfully.\n"); 
+       cdinfo(CD_OPEN, "device opened successfully.\n"); 
        return ret;
 
        /* Something failed.  Try to unlock the drive, because some drivers
@@ -699,7 +699,7 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
                sanitize_format(&ms_info.addr, &ms_info.addr_format,
                                requested_format);
                IOCTL_OUT(arg, struct cdrom_multisession, ms_info);
-               cdinfo(CD_DO_IOCTL, "CDROMMULTISESSION sucessful\n"); 
+               cdinfo(CD_DO_IOCTL, "CDROMMULTISESSION successful\n"); 
                return 0;
                }
 
@@ -789,7 +789,7 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
                if ((ret=cdo->get_mcn(cdi, &mcn)))
                        return ret;
                IOCTL_OUT(arg, struct cdrom_mcn, mcn);
-               cdinfo(CD_DO_IOCTL, "CDROM_GET_MCN sucessful\n"); 
+               cdinfo(CD_DO_IOCTL, "CDROM_GET_MCN successful\n"); 
                return 0;
                }
 
@@ -895,7 +895,7 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
                        sanitize_format(&q.cdsc_absaddr, &back, requested);
                        sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
                        IOCTL_OUT(arg, struct cdrom_subchnl, q);
-                       /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL sucessful\n"); */ 
+                       /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */ 
                        return 0;
                        }
                case CDROMREADTOCHDR: {
@@ -908,7 +908,7 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
                        if ((ret=cdo->audio_ioctl(cdi, cmd, &header)))
                                return ret;
                        IOCTL_OUT(arg, struct cdrom_tochdr, header);
-                       /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR sucessful\n"); */ 
+                       /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */ 
                        return 0;
                        }
                case CDROMREADTOCENTRY: {
@@ -930,7 +930,7 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
                        sanitize_format(&entry.cdte_addr,
                        &entry.cdte_format, requested_format);
                        IOCTL_OUT(arg, struct cdrom_tocentry, entry);
-                       /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY sucessful\n"); */ 
+                       /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */ 
                        return 0;
                        }
                case CDROMPLAYMSF: {
index f9a321b6f20f3a4187832db1c54c9540506020f6..f16b5b1d0c5e919d5099ffd5df4b3237d32e5861 100644 (file)
 # define CDU535_MESSAGE_NAME   "Sony CDU-535"
 #endif
 
+#define CDU535_BLOCK_SIZE      2048 
 #ifndef MAX_SPINUP_RETRY
 # define MAX_SPINUP_RETRY              3       /* 1 is sufficient for most drives... */
 #endif
@@ -591,7 +593,6 @@ static int
 seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
                                           Byte **buff, int buf_size)
 {
-       const int block_size = 2048;
        Byte cmd_buff[7];
        int  i;
        int  read_status;
@@ -599,7 +600,7 @@ seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
        Byte *data_buff;
        int  sector_count = 0;
 
-       if (buf_size < ((long)block_size) * n_blocks)
+       if (buf_size < CDU535_BLOCK_SIZE * n_blocks)
                return NO_ROOM;
 
        set_drive_mode(SONY535_CDROM_DRIVE_MODE, status);
@@ -625,7 +626,7 @@ seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
                        if ((read_status & SONY535_DATA_NOT_READY_BIT) == 0) {
                                /* data is ready, read it */
                                data_buff = buff[sector_count++];
-                               for (i = 0; i < block_size; i++)
+                               for (i = 0; i < CDU535_BLOCK_SIZE; i++)
                                        *data_buff++ = inb(data_reg);   /* unrolling this loop does not seem to help */
                                data_valid = 1;
                                break;                  /* exit the timeout loop */
@@ -639,7 +640,7 @@ seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
        /* read all the data, now read the status */
        if ((i = read_exec_status(status)) != 0)
                return i;
-       return block_size * sector_count;
+       return CDU535_BLOCK_SIZE * sector_count;
 }      /* seek_and_read_N_blocks() */
 
 /****************************************************************************
@@ -776,7 +777,7 @@ size_to_buf(unsigned int size, Byte *buf)
  * The OS calls this to perform a read or write operation to the drive.
  * Write obviously fail.  Reads to a read ahead of sony_buffer_size
  * bytes to help speed operations.  This especially helps since the OS
- * uses 1024 byte blocks and the drive uses 2048 byte blocks.  Since most
+ * may use 1024 byte blocks and the drive uses 2048 byte blocks.  Since most
  * data access on a CD is done sequentially, this saves a lot of operations.
  */
 static void
@@ -873,7 +874,7 @@ do_cdu535_request(void)
                                                 * seek_and_read_N_blocks for the various cases.
                                                 */
                                                int readStatus = seek_and_read_N_blocks(params, read_size,
-                                                                       status, sony_buffer, (read_size * 2048));
+                                                                       status, sony_buffer, (read_size * CDU535_BLOCK_SIZE));
                                                if (0 <= readStatus)    /* Good data; common case, placed first */
                                                        break;
                                                if (readStatus == NO_ROOM || spin_up_retry == MAX_SPINUP_RETRY) {
@@ -1480,6 +1481,8 @@ static struct file_operations cdu_fops =
        NULL                                            /* revalidate */
 };
 
+static int sonycd535_block_size = CDU535_BLOCK_SIZE;
+
 /*
  * Initialize the driver.
  */
@@ -1580,7 +1583,7 @@ sony535_init(void))
                        if (do_sony_cmd(cmd_buff, 2, status, ret_buff, 1, 1) == 0) {
                                /* set the drive mode successful, we are set! */
                                sony_buffer_size = SONY535_BUFFER_SIZE;
-                               sony_buffer_sectors = sony_buffer_size / 2048;
+                               sony_buffer_sectors = sony_buffer_size / CDU535_BLOCK_SIZE;
 
                                printk(KERN_INFO CDU535_MESSAGE_NAME " I/F CDROM : %8.8s %16.16s %4.4s",
                                           drive_config.vendor_id,
@@ -1597,6 +1600,7 @@ sony535_init(void))
                                        return -EIO;
                                }
                                blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
+                               blksize_size[MAJOR_NR] = &sonycd535_block_size;
                                read_ahead[MAJOR_NR] = 8;       /* 8 sector (4kB) read-ahead */
 
                                sony_toc = (struct s535_sony_toc *)
@@ -1617,7 +1621,8 @@ sony535_init(void))
                                        return -ENOMEM;
                                }
                                for (i = 0; i < sony_buffer_sectors; i++) {
-                                       sony_buffer[i] = (Byte *)kmalloc(2048, GFP_KERNEL);
+                                       sony_buffer[i] =
+                                                               (Byte *)kmalloc(CDU535_BLOCK_SIZE, GFP_KERNEL);
                                        if (sony_buffer[i] == NULL) {
                                                while (--i>=0)
                                                        kfree(sony_buffer[i]);
@@ -1680,7 +1685,7 @@ cleanup_module(void)
 
        release_region(sony535_cd_base_io, 4);
        for (i = 0; i < sony_buffer_sectors; i++)
-               kfree_s(sony_buffer[i], 2048);
+               kfree_s(sony_buffer[i], CDU535_BLOCK_SIZE);
        kfree_s(sony_buffer, 4 * sony_buffer_sectors);
        kfree_s(last_sony_subcode, sizeof *last_sony_subcode);
        kfree_s(sony_toc, sizeof *sony_toc);
index 0efccae58809a25191f0b3aa4377a9ba60be4807..ac91d56ddac35efb15c85ce6f742bc8871542349 100644 (file)
@@ -155,7 +155,7 @@ The four user programs listed below are described in this document:
    current digiConfig application does not provide this function for PCI cards
    (Though it does build device nodes for non-PCI cards).  To use this program
    execute the following:first install the driver, and execute digiDload (See above).  After digiDload
-   has sucessfully loaded, execute the following:
+   has successfully loaded, execute the following:
 
         buildPCI <arg1> <arg2>
 
@@ -295,7 +295,7 @@ Description (Verbose) : Made the following modifications:
                             Linux kernels support higher baud rates by using
                             0x1000 bit.  When the returned value (ored with
                             0x1000) was used to reference our fbaud table a 
-                            serious memory problem occured.  This has been fixed.
+                            serious memory problem occurred.  This has been fixed.
 
                         4.  Added a request_region call to post_fep_init.  This
                             should cause the i/o ports being used to be 
@@ -401,8 +401,8 @@ Description (Verbose) : Made the following modifications:
                            found in epcaconfig.h; if so it DOESN'T load
                            epcaconfig data depending on epca_setup to handle 
                            board configuration.  pc_open has been modified 
-                           such that it checks to insure that no errors
-                           occured during the LILO boot process.  If a 
+                           such that it checks to ensure that no errors
+                           occurred during the LILO boot process.  If a 
                            user attempts to boot the driver (via. LILO)
                            with incorrect data, the open will fail. 
 
index aab3f377ddad40ccbf370267455cba388e3ffe8d..88f959138a5509ff7dcfb1994e4f73858211de58 100644 (file)
@@ -2231,6 +2231,12 @@ static int con_open(struct tty_struct *tty, struct file * filp)
        return 0;
 }
 
+static void con_close(struct tty_struct *tty, struct file * filp)
+{
+       if (tty->count == 1)
+               tty->driver_data = 0;
+}
+
 static void vc_init(unsigned int currcons, unsigned int rows, unsigned int cols, int do_clear)
 {
        int j, k ;
@@ -2292,6 +2298,7 @@ __initfunc(unsigned long con_init(unsigned long kmem_start))
        console_driver.termios_locked = console_termios_locked;
 
        console_driver.open = con_open;
+       console_driver.close = con_close;
        console_driver.write = con_write;
        console_driver.write_room = con_write_room;
        console_driver.put_char = con_put_char;
index 38042ee458f63f0af6115063dd740b181052dbb1..fa7040e36b2d8c3eeed52f9f63869e3f6791154d 100644 (file)
@@ -202,8 +202,13 @@ void handle_scancode(unsigned char scancode)
 
        tty = ttytab? ttytab[fg_console]: NULL;
        if (tty && (!tty->driver_data)) {
-               /* This is to workaround ugly bug in tty_io.c, which
-                   does not do locking when it should */
+               /*
+                * We touch the tty structure via the the ttytab array
+                * without knowing whether or not tty is open, which
+                * is inherently dangerous.  We currently rely on that
+                * fact that console_open sets tty->driver_data when
+                * it opens it, and clears it when it closes it.
+                */
                tty = NULL;
        }
        kbd = kbd_table + fg_console;
index 5456640cb661cb2b13facd24b591c60eb3e92f2e..40c64872649dce36a6ef26331867bff4a792f615 100644 (file)
@@ -73,7 +73,8 @@ static inline void put_tty_queue(unsigned char c, struct tty_struct *tty)
  */
 static void check_unthrottle(struct tty_struct * tty)
 {
-       if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && 
+       if (tty->count &&
+           test_and_clear_bit(TTY_THROTTLED, &tty->flags) && 
            tty->driver.unthrottle)
                tty->driver.unthrottle(tty);
 }
@@ -923,15 +924,19 @@ do_it_again:
 
        add_wait_queue(&tty->read_wait, &wait);
 
-       disable_bh(TQUEUE_BH);
+       if (down_interruptible(&tty->atomic_read))
+               return -ERESTARTSYS;
+       set_bit(TTY_DONT_FLIP, &tty->flags);
        while (nr) {
                /* First test for status change. */
                if (tty->packet && tty->link->ctrl_status) {
+                       unsigned char cs;
                        if (b != buf)
                                break;
-                       put_user(tty->link->ctrl_status, b++);
-                       nr--;
+                       cs = tty->link->ctrl_status;
                        tty->link->ctrl_status = 0;
+                       put_user(cs, b++);
+                       nr--;
                        break;
                }
                /* This statement must be first before checking for input
@@ -960,9 +965,9 @@ do_it_again:
                                retval = -ERESTARTSYS;
                                break;
                        }
-                       enable_bh(TQUEUE_BH);
+                       clear_bit(TTY_DONT_FLIP, &tty->flags);
                        timeout = schedule_timeout(timeout);
-                       disable_bh(TQUEUE_BH);
+                       set_bit(TTY_DONT_FLIP, &tty->flags);
                        continue;
                }
                current->state = TASK_RUNNING;
@@ -1024,7 +1029,8 @@ do_it_again:
                if (time)
                        timeout = time;
        }
-       enable_bh(TQUEUE_BH);
+       clear_bit(TTY_DONT_FLIP, &tty->flags);
+       up(&tty->atomic_read);
        remove_wait_queue(&tty->read_wait, &wait);
 
        if (!waitqueue_active(&tty->read_wait))
index 115606ac33127eaf986b31b97867744a91723c13..80a72d4b4c4d403661c9b21949e375db294e29ad 100644 (file)
  *  to get fine volume control over the low volume range.
  *
  *  Some code derived from code by Frans Brinkman
+ *
+ * 1999-01-05 - (C. van Schaik)
+ *           - Changed tuning to 1/160Mhz accuracy
+ *           - Added stereo support
+ *             (card defaults to stereo)
+ *             (can explicitly force mono on the card)
+ *             (can detect if station is in stereo)
+ *           - Added unmute function
+ *           - Reworked ioctl functions
  */
 
 #include <linux/module.h>      /* Modules                        */
@@ -35,6 +44,7 @@ struct zol_device {
        int curvol;
        unsigned long curfreq;
        int muted;
+       unsigned int stereo;
 };
 
 
@@ -54,61 +64,63 @@ static void sleep_delay(long n)
        }
 }
 
+static int zol_setvol(struct zol_device *dev, int vol)
+{
+       dev->curvol = vol;
+       if (dev->muted)
+               return 0;
+
+       if (vol == 0) {
+               outb(0, io);
+               outb(0, io);
+               inb(io + 3);    /* Zoltrix needs to be read to confirm */
+               return 0;
+       }
+
+       outb(dev->curvol-1, io);
+       sleep_delay(10000);
+       inb(io + 2);
+
+       return 0;
+}
+
 static void zol_mute(struct zol_device *dev)
 {
        dev->muted = 1;
        outb(0, io);
        outb(0, io);
-       inb(io + 3);            /* Zoltrix needs to be read to confirm */
-}
-
-static void zol_on(int vol)
-{
-        int l;
-        outb(vol, io);
-        sleep_delay(10000);
-        l = inb(io + 2);
+       inb(io + 3);            /* Zoltrix needs to be read to confirm */
 }
 
-static int zol_setvol(struct zol_device *dev, int vol)
+static void zol_unmute(struct zol_device *dev)
 {
-       if (vol == dev->curvol) {       /* requested volume = current */
-               if (dev->muted) {       /* user is unmuting the card  */
-                       dev->muted = 0;
-                        zol_on(vol);
-               }
-               return 0;
-       }
-       if (vol == 0) {         /* volume = 0 means mute the card */
-                zol_mute(dev);
-               return 0;
-       }
        dev->muted = 0;
-       dev->curvol = vol;
-
-       zol_on(vol);
-
-       return 0;
+       zol_setvol(dev, dev->curvol);
 }
 
 static int zol_setfreq(struct zol_device *dev, unsigned long freq)
 {
        /* tunes the radio to the desired frequency */
        unsigned long long bitmask, f, m;
+       unsigned int stereo = dev->stereo;
        int i;
 
-       m = (freq * 25 / 4 - 8800) * 2;
+       if (freq == 0)
+               return 1;
+       m = (freq / 160 - 8800) * 2;
        f = (unsigned long long) m + 0x4d1c;
 
        bitmask = 0xc480402c10080000ull;
        i = 45;
 
-       zol_mute(dev);
+       outb(0, io);
+       outb(0, io);
+       inb(io + 3);            /* Zoltrix needs to be read to confirm */
 
        outb(0x40, io);
        outb(0xc0, io);
 
-       bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ ( /*stereo */ 0 << 31));
+       bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ ( stereo << 31));
        while (i--) {
                if ((bitmask & 0x8000000000000000ull) != 0) {
                        outb(0x80, io);
@@ -131,7 +143,18 @@ static int zol_setfreq(struct zol_device *dev, unsigned long freq)
        outb(0x80, io);
        outb(0xc0, io);
        outb(0x40, io);
-        zol_on(dev->curvol);
+       sleep_delay(1000);
+       inb(io+2);
+
+        sleep_delay(1000);
+       if (dev->muted)
+       {
+               outb(0, io);
+               outb(0, io);
+               inb(io + 3);
+               sleep_delay(1000);
+       } else
+        zol_setvol(dev, dev->curvol);
        return 0;
 }
 
@@ -149,27 +172,42 @@ int zol_getsigstr(struct zol_device *dev)
        sleep_delay(1000);
        b = inb(io);
 
-        if ((a == b) && (a == 0xdf))  /* I found this out by playing */
-                                      /* with a binary scanner on the card io */
-               return (1);
-       else
+       if (a != b)
                return (0);
 
-       if (inb(io) & 2)        /* bit set = no signal present    */
-               return 0;
-       return 1;               /* signal present               */
+        if ((a == 0xcf) || (a == 0xdf)  /* I found this out by playing */
+               || (a == 0xef))       /* with a binary scanner on the card io */
+               return (1);
+       return (0);
+}
+
+int zol_is_stereo (struct zol_device *dev)
+{
+       int x1, x2;
+
+       outb(0x00, io);
+       outb(dev->curvol, io);
+       sleep_delay(20000);
+
+       x1 = inb(io);
+       sleep_delay(1000);
+       x2 = inb(io);
+
+       if ((x1 == x2) && (x1 == 0xcf))
+               return 1;
+       return 0;
 }
 
 static int zol_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
 {
-       struct zol_device *rt = dev->priv;
+       struct zol_device *zol = dev->priv;
 
        switch (cmd) {
        case VIDIOCGCAP:
                {
                        struct video_capability v;
                        v.type = VID_TYPE_TUNER;
-                       v.channels = 1;
+                       v.channels = 1 + zol->stereo;
                        v.audios = 1;
                        /* No we don't do pictures */
                        v.maxwidth = 0;
@@ -184,15 +222,21 @@ static int zol_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
        case VIDIOCGTUNER:
                {
                        struct video_tuner v;
-                       if (copy_from_user(&v, arg, sizeof(v)) != 0)
+/*
+                       if (copy_from_user(&v, arg, sizeof(v)))
                                return -EFAULT;
-                       if (v.tuner)    /* Only 1 tuner */
+                       if (v.tuner)    
                                return -EINVAL;
-                       v.rangelow = (int) (88.0 * 16);
-                       v.rangehigh = (int) (108.0 * 16);
-                       v.flags = 0;
+*/
+                       v.tuner = 0;
+                       strcpy(v.name, "Zoltrix Radio");
+                       v.rangelow = (int) (88.0 * 16000);
+                       v.rangehigh = (int) (108.0 * 16000);
+                       v.flags = zol_is_stereo(zol)
+                                       ? VIDEO_TUNER_STEREO_ON : 0;
+                       v.flags |= VIDEO_TUNER_LOW;
                        v.mode = VIDEO_MODE_AUTO;
-                       v.signal = 0xFFFF * zol_getsigstr(rt);
+                       v.signal = 0xFFFF * zol_getsigstr(zol);
                        if (copy_to_user(arg, &v, sizeof(v)))
                                return -EFAULT;
                        return 0;
@@ -208,22 +252,24 @@ static int zol_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        return 0;
                }
        case VIDIOCGFREQ:
-               if (copy_to_user(arg, &rt->curfreq, sizeof(rt->curfreq)))
+               if (copy_to_user(arg, &zol->curfreq, sizeof(zol->curfreq)))
                        return -EFAULT;
                return 0;
        case VIDIOCSFREQ:
-               if (copy_from_user(&rt->curfreq, arg, sizeof(rt->curfreq)))
+               if (copy_from_user(&zol->curfreq, arg, sizeof(zol->curfreq)))
                        return -EFAULT;
-               zol_setfreq(rt, rt->curfreq);
+               zol_setfreq(zol, zol->curfreq);
                return 0;
        case VIDIOCGAUDIO:
                {
                        struct video_audio v;
                        memset(&v, 0, sizeof(v));
                        v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME;
-                       v.volume = rt->curvol * 4096;
+                       v.mode != zol_is_stereo(zol)
+                               ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
+                       v.volume = zol->curvol * 4096;
                        v.step = 4096;
-                       strcpy(v.name, "Radio");
+                       strcpy(v.name, "Zoltrix Radio");
                        if (copy_to_user(arg, &v, sizeof(v)))
                                return -EFAULT;
                        return 0;
@@ -237,9 +283,23 @@ static int zol_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                return -EINVAL;
 
                        if (v.flags & VIDEO_AUDIO_MUTE)
-                               zol_mute(rt);
+                               zol_mute(zol);
                        else
-                               zol_setvol(rt, v.volume / 4096);
+                               zol_unmute(zol);
+
+                       if (v.flags & VIDEO_AUDIO_VOLUME)
+                               zol_setvol(zol, v.volume / 4096);
+
+                       if (v.mode & VIDEO_SOUND_STEREO)
+                       {
+                               zol->stereo = 1;
+                               zol_setfreq(zol, zol->curfreq);
+                       }
+                       if (v.mode & VIDEO_SOUND_MONO)
+                       {
+                               zol->stereo = 0;
+                               zol_setfreq(zol, zol->curfreq);
+                       }
 
                        return 0;
                }
@@ -286,6 +346,10 @@ __initfunc(int zoltrix_init(struct video_init *v))
                printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io);
                return -EBUSY;
        }
+       if ((io != 0x20c) && (io != 0x30c)) {
+               printk(KERN_ERR "zoltrix: invalid port, try 0x20c or 0x30c\n");
+               return -ENXIO;
+       }
        zoltrix_radio.priv = &zoltrix_unit;
 
        if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO) == -1)
@@ -304,6 +368,7 @@ __initfunc(int zoltrix_init(struct video_init *v))
        inb(io + 3);
 
        zoltrix_unit.curvol = 0;
+       zoltrix_unit.stereo = 1;
 
        return 0;
 }
index 007dd9048907b28599f9207f36070f017932e083..23a5b681689b6cbed85c69e4e71c4ec5de99b004 100644 (file)
@@ -866,12 +866,7 @@ static int init_dev(kdev_t device, struct tty_struct **ret_tty)
         * Failures after this point use release_mem to clean up, so 
         * there's no need to null out the local pointers.
         */
-       driver->table[idx] = tty;       /* FIXME: this is broken and
-       probably causes ^D bug. tty->private_date does not (yet) point
-       to a console, if keypress comes now, await armagedon. 
-
-       also, driver->table is accessed from interrupt for vt case,
-       and this does not look like atomic access at all. */
+       driver->table[idx] = tty;
        
        if (!*tp_loc)
                *tp_loc = tp;
@@ -1846,6 +1841,10 @@ static void flush_to_ldisc(void *private_)
        int             count;
        unsigned long flags;
 
+       if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
+               queue_task(&tty->flip.tqueue, &tq_timer);
+               return;
+       }
        if (tty->flip.buf_num) {
                cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
                fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
@@ -1872,14 +1871,22 @@ static void flush_to_ldisc(void *private_)
 
 /*
  * Routine which returns the baud rate of the tty
- */
-
-/*
- * This is used to figure out the divisor speeds and the timeouts
+ *
+ * Note that the baud_table needs to be kept in sync with the
+ * include/asm/termbits.h file.
  */
 static int baud_table[] = {
        0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
-       9600, 19200, 38400, 57600, 115200, 230400, 460800, 0 };
+       9600, 19200, 38400, 57600, 115200, 230400, 460800,
+#ifdef __sparc__
+       76800, 153600, 307200, 614400, 921600
+#else
+       500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
+       2500000, 3000000, 3500000, 4000000
+#endif
+};
+
+static int n_baud_table = sizeof(baud_table)/sizeof(int);
 
 int tty_get_baud_rate(struct tty_struct *tty)
 {
@@ -1890,7 +1897,7 @@ int tty_get_baud_rate(struct tty_struct *tty)
        i = cflag & CBAUD;
        if (i & CBAUDEX) {
                i &= ~CBAUDEX;
-               if (i < 1 || i > 4
+               if (i < 1 || i+15 >= n_baud_table
                        tty->termios->c_cflag &= ~CBAUDEX;
                else
                        i += 15;
@@ -1930,6 +1937,7 @@ static void initialize_tty_struct(struct tty_struct *tty)
        tty->flip.pty_sem = MUTEX;
        tty->tq_hangup.routine = do_tty_hangup;
        tty->tq_hangup.data = tty;
+       sema_init(&tty->atomic_read, 1);
 }
 
 /*
index 3bd2819cedb85b3d97c9f6acf81e795027a33aa5..4aba68b38fe0bb124dbd0863bc009598b4e9a8a8 100644 (file)
@@ -318,9 +318,9 @@ static char *icn_id2 = "\0";
 #ifdef MODULE
 MODULE_AUTHOR("Fritz Elfert");
 MODULE_PARM(portbase, "i");
-MODULE_PARM_DESC(portbase, "Port adress of first card");
+MODULE_PARM_DESC(portbase, "Port address of first card");
 MODULE_PARM(membase, "i");
-MODULE_PARM_DESC(membase, "Shared memory adress of all cards");
+MODULE_PARM_DESC(membase, "Shared memory address of all cards");
 MODULE_PARM(icn_id, "s");
 MODULE_PARM_DESC(icn_id, "ID-String of first card");
 MODULE_PARM(icn_id2, "s");
index c7471d36139bbeb3f430fa6186c077931fdc9216..2ae21fcf38ef26470195a392d1cd13ee9d27f461 100644 (file)
@@ -65,7 +65,7 @@ static struct concap_proto_ops ix25_pops = {
        &isdn_x25iface_disconn_ind
 };
 
-/* error message helper fuction */
+/* error message helper function */
 static void illegal_state_warn( unsigned state, unsigned char firstbyte) 
 {
        printk( KERN_WARNING "isdn_x25iface: firstbyte %x illegal in"
index 9b4aab9194051634cba43bf70b637f936cfac77c..174c8d413a8b0b4655c0519dd53d88e7063811fc 100644 (file)
@@ -19,10 +19,7 @@ MI_OBJS  :=
 MIX_OBJS :=
 
 ifeq ($(CONFIG_PARPORT),y)
-  L_OBJS += parport_share.o parport_ieee1284.o
-  ifeq ($(CONFIG_PROC_FS),y)
-    L_OBJS += parport_procfs.o
-  endif
+  L_OBJS += parport_share.o parport_ieee1284.o parport_procfs.o
   ifeq ($(CONFIG_PARPORT_PC),y)
     LX_OBJS += parport_pc.o
   else
index f9c4ee46bb890a9d8591ae1b9afa4aa35e58a550..37c1e4e9ae856aa79e448ff17804fc8ad3aad383 100644 (file)
@@ -14,7 +14,6 @@
  * a subset of the standard printer control lines connected.
  */
 
-#include <linux/config.h>
 #include <linux/tasks.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
index d7697eff2759287582e7438a08b9c624887840e8..77738b0e1bfd5a98647b57147ccbdae50da4b6ac 100644 (file)
@@ -11,7 +11,6 @@
  *          Grant Guenther <grant@torque.net>
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
index 4acc2c542922e8669e9c5e9c5807ca18305086de..2d276a573d08890f379b0529e9dabb827d63a68d 100644 (file)
@@ -12,6 +12,7 @@
  * Cleaned up include files - Russell King <linux@arm.uk.linux.org>
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
index 80743eaba4cd038ec9d8cebdcb2ce4773a50eec3..7dc831e58f69f3c8cef7c1202a3a290025c0d8f7 100644 (file)
@@ -747,7 +747,7 @@ vortex_open(struct device *dev)
                        vp->tx_skbuff[i] = 0;
                outl(0, ioaddr + DownListPtr);
        }
-       /* Set reciever mode: presumably accept b-case and phys addr only. */
+       /* Set receiver mode: presumably accept b-case and phys addr only. */
        set_rx_mode(dev);
        outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
 
index 37843e6df594f00d8506a43d9083bf092e6e07d1..dd0b3826783a13d63ff85d67e8db9f5596f80504 100644 (file)
@@ -521,7 +521,7 @@ __initfunc(int elmc_probe(struct device *dev))
        /* The 3c523 has a 24K chunk of memory.  The first 16K is the
           shared memory, while the last 8K is for the EtherStart BIOS ROM.
           Which we don't care much about here.  We'll just tell Linux that
-          we're using 16K.  MCA won't permit adress space conflicts caused
+          we're using 16K.  MCA won't permit address space conflicts caused
           by not mapping the other 8K. */
        dev->mem_start = shm_table[(status & ELMC_STATUS_MEMORY_SELECT) >> 3];
 
index 547d0497cd3265f4de313267b9fa9a8162e67ae6..b6fa0be727b3f8a54cd97a2464006c785434624c 100644 (file)
 */
 
 static char *version =
-"3c59x.c:v0.99E 5/12/98 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html\n";
+"3c59x.c:v0.99H 11/17/98 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html\n";
 
 /* "Knobs" that adjust features and parameters. */
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
    Setting to > 1512 effectively disables this feature. */
-static const rx_copybreak = 200;
+static const int rx_copybreak = 200;
 /* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
-static const mtu = 1500;
+static const int mtu = 1500;
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 20;
 
 /* Put out somewhat more debugging messages. (0: no msg, 1 minimal .. 6). */
+#define vortex_debug debug
 #ifdef VORTEX_DEBUG
 static int vortex_debug = VORTEX_DEBUG;
 #else
@@ -37,15 +38,6 @@ static int vortex_debug = 1;
    debugging. */
 static int rx_nocopy = 0, rx_copy = 0, queued_packet = 0, rx_csumhits;
 
-/* Enable the automatic media selection code -- usually set. */
-#define AUTOMEDIA 1
-
-/* Allow the use of fragment bus master transfers instead of only
-   programmed-I/O for Vortex cards.  Full-bus-master transfers are always
-   enabled by default on Boomerang cards.  If VORTEX_BUS_MASTER is defined,
-   the feature may be turned on using 'options'. */
-#define VORTEX_BUS_MASTER
-
 /* A few values that may be tweaked. */
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT  ((400*HZ)/1000)
@@ -56,12 +48,12 @@ static int rx_nocopy = 0, rx_copy = 0, queued_packet = 0, rx_csumhits;
 #define PKT_BUF_SZ             1536                    /* Size of each temporary Rx buffer.*/
 
 #include <linux/config.h>
+#include <linux/version.h>
 #ifdef MODULE
 #ifdef MODVERSIONS
 #include <linux/modversions.h>
 #endif
 #include <linux/module.h>
-#include <linux/version.h>
 #else
 #define MOD_INC_USE_COUNT
 #define MOD_DEC_USE_COUNT
@@ -70,41 +62,53 @@ static int rx_nocopy = 0, rx_copy = 0, queued_packet = 0, rx_csumhits;
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
-#include <linux/ptrace.h>
+#include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/ioport.h>
 #include <linux/malloc.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/timer.h>
-
-#include <asm/byteorder.h>
-#include <asm/irq.h>                   /* For NR_IRQS only. */
-#include <asm/bitops.h>
-#include <asm/io.h>
-
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#if LINUX_VERSION_CODE < 0x20155  ||  defined(CARDBUS)
+#include <linux/bios32.h>
+#endif
+#include <asm/irq.h>                   /* For NR_IRQS only. */
+#include <asm/bitops.h>
+#include <asm/io.h>
 
-/* Kernel compatibility defines, common to David Hind's PCMCIA package.
+/* Kernel compatibility defines, some common to David Hinds' PCMCIA package.
    This is only in the support-all-kernels source code. */
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>             /* Redundant above, here for easy clean-up. */
+
+#define RUN_AT(x) (jiffies + (x))
+
+#include <linux/delay.h>
+
+#if (LINUX_VERSION_CODE >= 0x20100)
+char kernel_version[] = UTS_RELEASE;
+#else
+#ifndef __alpha__
+#define ioremap(a,b) \
+       (((a)<0x100000) ? (void *)((u_long)(a)) : vremap(a,b))
+#define iounmap(v) \
+       do { if ((u_long)(v) > 0x100000) vfree(v); } while (0)
 #endif
-#if LINUX_VERSION_CODE < 0x10300
-#define RUN_AT(x) (x)                  /* What to put in timer->expires.  */
-#define DEV_ALLOC_SKB(len) alloc_skb(len, GFP_ATOMIC)
-#if defined(__alpha)
-#error "The Alpha architecture is only support with kernel version 2.0."
 #endif
-#define virt_to_bus(addr)  ((unsigned long)addr)
-#define bus_to_virt(addr) ((void*)addr)
-#define NR_IRQS 16
-#else  /* 1.3.0 and later */
-#define RUN_AT(x) (jiffies + (x))
-#define DEV_ALLOC_SKB(len) dev_alloc_skb(len)
+#if LINUX_VERSION_CODE <= 0x20139
+#define        net_device_stats enet_statistics
+#define NETSTATS_VER2
+#endif
+#if LINUX_VERSION_CODE < 0x20138
+#define test_and_set_bit(val, addr) set_bit(val, addr)
+#define le32_to_cpu(val) (val)
+#define cpu_to_le32(val) (val)
+#endif
+#if LINUX_VERSION_CODE < 0x20155
+#define PCI_SUPPORT_VER1
+#else
+#define PCI_SUPPORT_VER2
 #endif
 #if LINUX_VERSION_CODE < 0x20159
 #define DEV_FREE_SKB(skb) dev_kfree_skb (skb, FREE_WRITE);
@@ -112,27 +116,7 @@ static int rx_nocopy = 0, rx_copy = 0, queued_packet = 0, rx_csumhits;
 #define DEV_FREE_SKB(skb) dev_kfree_skb(skb);
 #endif
 
-#ifdef SA_SHIRQ
-#define FREE_IRQ(irqnum, dev) free_irq(irqnum, dev)
-#define REQUEST_IRQ(i,h,f,n, instance) request_irq(i,h,f,n, instance)
-#define IRQ(irq, dev_id, pt_regs) (irq, dev_id, pt_regs)
-#else
-#define FREE_IRQ(irqnum, dev) free_irq(irqnum)
-#define REQUEST_IRQ(i,h,f,n, instance) request_irq(i,h,f,n)
-#define IRQ(irq, dev_id, pt_regs) (irq, pt_regs)
-#endif
-
-#if (LINUX_VERSION_CODE >= 0x10344)
-#define NEW_MULTICAST
-#include <linux/delay.h>
-#else
-#define udelay(microsec)       do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
-#endif
-
-#if LINUX_VERSION_CODE < 0x20138
-#define test_and_set_bit(val, addr) set_bit(val, addr)
-#endif
-#if defined(MODULE) && (LINUX_VERSION_CODE >= 0x20115)
+#if defined(MODULE) && LINUX_VERSION_CODE > 0x20115
 MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
 MODULE_DESCRIPTION("3Com 3c590/3c900 series Vortex/Boomerang driver");
 MODULE_PARM(debug, "i");
@@ -142,7 +126,7 @@ MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(compaq_ioaddr, "i");
 MODULE_PARM(compaq_irq, "i");
-MODULE_PARM(compaq_prod_id, "i");
+MODULE_PARM(compaq_device_id, "i");
 #endif
 
 /* Operational parameter that usually are not changed. */
@@ -154,35 +138,11 @@ MODULE_PARM(compaq_prod_id, "i");
 #define VORTEX_TOTAL_SIZE 0x20
 #define BOOMERANG_TOTAL_SIZE 0x40
 
-#ifdef HAVE_DEVLIST
-struct netdev_entry tc59x_drv =
-{"Vortex", vortex_pci_probe, VORTEX_TOTAL_SIZE, NULL};
-#endif
-
 /* Set iff a MII transceiver on any interface requires mdio preamble.
    This only set with the original DP83840 on older 3c905 boards, so the extra
    code size of a per-interface flag is not worthwhile. */
 static char mii_preamble_required = 0;
 
-/* Caution!  These entries must be consistent. */
-static const int product_ids[] = {
-       0x5900, 0x5920, 0x5970, 0x5950, 0x5951, 0x5952, 0x9000, 0x9001,
-       0x9050, 0x9051, 0x9055, 0x5057, 0 };
-static const char *product_names[] = {
-       "3c590 Vortex 10Mbps",
-       "3c592 EISA 10mbps Demon/Vortex",
-       "3c597 EISA Fast Demon/Vortex",
-       "3c595 Vortex 100baseTX",
-       "3c595 Vortex 100baseT4",
-       "3c595 Vortex 100base-MII",
-       "3c900 Boomerang 10baseT",
-       "3c900 Boomerang 10Mbps/Combo",
-       "3c905 Boomerang 100baseTx",
-       "3c905 Boomerang 100baseT4",
-       "3c905B Cyclone 100baseTx",
-       "3c575",                                                /* Cardbus Boomerang */
-};
-
 /*
                                Theory of Operation
 
@@ -193,17 +153,19 @@ XL, 3Com's PCI to 10/100baseT adapters.  It also works with the 10Mbs
 versions of the FastEtherLink cards.  The supported product IDs are
   3c590, 3c592, 3c595, 3c597, 3c900, 3c905
 
-The ISA 3c515 is supported with a seperate driver, 3c515.c, included with
-the kernel source or available from
+The related ISA 3c515 is supported with a separate driver, 3c515.c, included
+with the kernel source or available from
     cesdis.gsfc.nasa.gov:/pub/linux/drivers/3c515.html
 
 II. Board-specific settings
 
 PCI bus devices are configured by the system at boot time, so no jumpers
 need to be set on the board.  The system BIOS should be set to assign the
-PCI INTA signal to an otherwise unused system IRQ line.  While it's
-physically possible to shared PCI interrupt lines, the 1.2.0 kernel doesn't
-support it.
+PCI INTA signal to an otherwise unused system IRQ line.
+
+The EEPROM settings for media type and forced-full-duplex are observed.
+The EEPROM media type should be left at the default "autoselect" unless using
+10base2 or AUI connections which cannot be reliably detected.
 
 III. Driver operation
 
@@ -211,10 +173,10 @@ The 3c59x series use an interface that's very similar to the previous 3c5x9
 series.  The primary interface is two programmed-I/O FIFOs, with an
 alternate single-contiguous-region bus-master transfer (see next).
 
-The 3c900 "Boomerang" series uses a full-bus-master interface with seperate
+The 3c900 "Boomerang" series uses a full-bus-master interface with separate
 lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet,
 DEC Tulip and Intel Speedo3.  The first chip version retains a compatible
-programmed-I/O interface that will be removed in the 'B' and subsequent
+programmed-I/O interface that has been removed in 'B' and subsequent board
 revisions.
 
 One extension that is advertised in a very large font is that the adapters
@@ -232,7 +194,7 @@ packets may be reordered and receive buffer groups are associated with a
 single frame.
 
 With full-bus-master support, this driver uses a "RX_COPYBREAK" scheme.
-Tather than a fixed intermediate receive buffer, this scheme allocates
+Rather than a fixed intermediate receive buffer, this scheme allocates
 full-sized skbuffs as receive buffers.  The value RX_COPYBREAK is used as
 the copying breakpoint: it is chosen to trade-off the memory wasted by
 passing the full-sized skbuff to the queue layer for all frames vs. the
@@ -258,7 +220,66 @@ This driver only supports ethernet packets because of the skbuff allocation
 limit of 4K.
 */
 
-#define TCOM_VENDOR_ID 0x10B7          /* 3Com's manufacturer's ID. */
+/* This table drives the PCI probe routines.  It's mostly boilerplate in all
+   of the drivers, and will likely be provided by some future kernel.
+*/
+enum pci_flags_bit {
+       PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
+       PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
+};
+struct pci_id_info {
+       const char *name;
+       u16     vendor_id, device_id, device_id_mask, flags;
+       int drv_flags, io_size;
+       struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev,
+                                                        long ioaddr, int irq, int chip_idx, int fnd_cnt);
+};
+
+enum { IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4,
+          HAS_PWR_CTRL=0x10, HAS_MII=0x20, HAS_NWAY=0x40, HAS_CB_FNS=0x80, };
+static struct device *vortex_probe1(int pci_bus, int pci_devfn,
+                                                                       struct device *dev, long ioaddr,
+                                                                       int irq, int dev_id, int card_idx);
+static struct pci_id_info pci_tbl[] = {
+       {"3c590 Vortex 10Mbps",                 0x10B7, 0x5900, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, vortex_probe1},
+       {"3c595 Vortex 100baseTx",              0x10B7, 0x5950, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, vortex_probe1},
+       {"3c595 Vortex 100baseT4",              0x10B7, 0x5951, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, vortex_probe1},
+       {"3c595 Vortex 100base-MII",    0x10B7, 0x5952, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, vortex_probe1},
+       {"3Com Vortex",                                 0x10B7, 0x5900, 0xff00,
+        PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG, 64, vortex_probe1},
+       {"3c900 Boomerang 10baseT",             0x10B7, 0x9000, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG, 64, vortex_probe1},
+       {"3c900 Boomerang 10Mbps Combo", 0x10B7, 0x9001, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG, 64, vortex_probe1},
+       {"3c900 Cyclone 10Mbps Combo", 0x10B7, 0x9005, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1},
+       {"3c900B-FL Cyclone 10base-FL", 0x10B7, 0x900A, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1},
+       {"3c905 Boomerang 100baseTx",   0x10B7, 0x9050, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1},
+       {"3c905 Boomerang 100baseT4",   0x10B7, 0x9051, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1},
+       {"3c905B Cyclone 100baseTx",    0x10B7, 0x9055, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY, 128, vortex_probe1},
+       {"3c905B-FX Cyclone 100baseFx", 0x10B7, 0x905A, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1},
+       {"3c980 Cyclone",       0x10B7, 0x9800, 0xfff0,
+        PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1},
+       {"3c575 Boomerang CardBus",             0x10B7, 0x5057, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1},
+       {"3CCFE575 Cyclone CardBus",    0x10B7, 0x5157, 0xffff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS,
+        128, vortex_probe1},
+       {"3c575 series CardBus (unknown version)", 0x10B7, 0x5057, 0xf0ff,
+        PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1},
+       {"3Com Boomerang (unknown version)",    0x10B7, 0x9000, 0xff00,
+        PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG, 64, vortex_probe1},
+       {0,},                                           /* 0 terminated list. */
+};
 
 /* Operational definitions.
    These are not used by other compilation units and thus are not
@@ -287,7 +308,7 @@ enum vortex_cmd {
        SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
        SetTxThreshold = 18<<11, SetTxStart = 19<<11,
        StartDMAUp = 20<<11, StartDMADown = (20<<11)+1, StatsEnable = 21<<11,
-       StatsDisable = 22<<11, StopCoax = 23<<11,};
+       StatsDisable = 22<<11, StopCoax = 23<<11, SetFilterBit = 25<<11,};
 
 /* The SetRxFilter command accepts the following classes: */
 enum RxFilter {
@@ -327,26 +348,19 @@ enum eeprom_offset {
        NodeAddr01=10, NodeAddr23=11, NodeAddr45=12,
        DriverTune=13, Checksum=15};
 
+enum Window2 {                 /* Window 2. */
+       Wn2_ResetOptions=12,
+};
 enum Window3 {                 /* Window 3: MAC/config bits. */
        Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8,
 };
 union wn3_config {
        int i;
        struct w3_config_fields {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
                unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2;
                int pad8:8;
                unsigned int ram_split:2, pad18:2, xcvr:4, autoselect:1;
                int pad24:7;
-#elif defined(__BIG_ENDIAN_BITFIELD)
-               unsigned int rom_size:2, ram_speed:2, ram_width:1, ram_size:3;
-               int pad8:8;
-               unsigned int xcvr:4, pad18:2, ram_split:2;
-               int pad24:7;
-               unsigned int autoselect:1;
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
        } u;
 };
 
@@ -404,37 +418,37 @@ enum tx_desc_status {
 enum ChipCaps { CapBusMaster=0x20 };
 
 struct vortex_private {
-       char devname[8];                        /* "ethN" string, also for kernel debug. */
-       const char *product_name;
-       struct device *next_module;
-       /* The Rx and Tx rings are here to keep them quad-word-aligned. */
+       /* The Rx and Tx rings should be quad-word-aligned. */
        struct boom_rx_desc rx_ring[RX_RING_SIZE];
        struct boom_tx_desc tx_ring[TX_RING_SIZE];
        /* The addresses of transmit- and receive-in-place skbuffs. */
        struct sk_buff* rx_skbuff[RX_RING_SIZE];
        struct sk_buff* tx_skbuff[TX_RING_SIZE];
+       struct device *next_module;
+       void *priv_addr;
        unsigned int cur_rx, cur_tx;            /* The next free ring entry */
        unsigned int dirty_rx, dirty_tx;        /* The ring entries to be free()ed. */
-       struct enet_statistics stats;
+       struct net_device_stats stats;
        struct sk_buff *tx_skb;         /* Packet being eaten by bus master ctrl.  */
 
        /* PCI configuration space information. */
-       u8 pci_bus, pci_dev_fn;         /* PCI bus location, for power management. */
-       u16 pci_device_id;
+       u8 pci_bus, pci_devfn;          /* PCI bus location, for power management. */
+       char *cb_fn_base;                       /* CardBus function status addr space. */
+       int chip_id;
 
        /* The remainder are related to chip state, mostly media selection. */
-       int in_interrupt;
+       unsigned long in_interrupt;
        struct timer_list timer;        /* Media selection timer. */
        int options;                            /* User-settable misc. driver options. */
-       unsigned int
-         media_override:3,                     /* Passed-in media type. */
-         default_media:3,                              /* Read from the EEPROM/Wn3_Config. */
-         full_duplex:1, autoselect:1,
-         bus_master:1,                         /* Vortex can only do a fragment bus-m. */
-         full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang  */
-         hw_csums:1,                           /* Has hardware checksums. */
-      tx_full:1;
+       unsigned int media_override:3,                  /* Passed-in media type. */
+               default_media:4,                                /* Read from the EEPROM/Wn3_Config. */
+               full_duplex:1, force_fd:1, autoselect:1,
+               bus_master:1,                           /* Vortex can only do a fragment bus-m. */
+               full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang  */
+               hw_csums:1,                             /* Has hardware checksums. */
+               tx_full:1;
        u16 status_enable;
+       u16 intr_enable;
        u16 available_media;                            /* From Wn3_Options. */
        u16 capabilities, info1, info2;         /* Various, from EEPROM. */
        u16 advertising;                                        /* NWay media advertisement */
@@ -469,61 +483,39 @@ static struct media_table {
   { "Default",  0,                     0xFF, XCVR_10baseT, 10000},
 };
 
-static int vortex_scan(struct device *dev);
-static struct device *vortex_found_device(struct device *dev, int ioaddr,
-                                                                                 int irq, int device_id,
-                                                                                 int options, int card_idx);
-static int vortex_probe1(struct device *dev);
-static int vortex_open(struct device *dev);
-static void mdio_sync(int ioaddr, int bits);
-static int mdio_read(int ioaddr, int phy_id, int location);
-#ifdef HAVE_PRIVATE_IOCTL
-static void mdio_write(int ioaddr, int phy_id, int location, int value);
+#ifndef CARDBUS
+static int vortex_scan(struct device *dev, struct pci_id_info pci_tbl[]);
 #endif
+static int vortex_open(struct device *dev);
+static void mdio_sync(long ioaddr, int bits);
+static int mdio_read(long ioaddr, int phy_id, int location);
+static void mdio_write(long ioaddr, int phy_id, int location, int value);
 static void vortex_timer(unsigned long arg);
 static int vortex_start_xmit(struct sk_buff *skb, struct device *dev);
 static int boomerang_start_xmit(struct sk_buff *skb, struct device *dev);
 static int vortex_rx(struct device *dev);
 static int boomerang_rx(struct device *dev);
-static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs);
+static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int vortex_close(struct device *dev);
-static void update_stats(int addr, struct device *dev);
-static struct enet_statistics *vortex_get_stats(struct device *dev);
+static void update_stats(long ioaddr, struct device *dev);
+static struct net_device_stats *vortex_get_stats(struct device *dev);
 static void set_rx_mode(struct device *dev);
-#ifdef HAVE_PRIVATE_IOCTL
 static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd);
-#endif
-#ifndef NEW_MULTICAST
-static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
-#endif
 \f
 
-/* Unlike the other PCI cards the 59x cards don't need a large contiguous
-   memory region, so making the driver a loadable module is feasible.
-
-   Unfortunately maximizing the shared code between the integrated and
-   module version of the driver results in a complicated set of initialization
-   procedures.
-   init_module() -- modules /  tc59x_init()  -- built-in
-               The wrappers for vortex_scan()
-   vortex_scan()                The common routine that scans for PCI and EISA cards
-   vortex_found_device() Allocate a device structure when we find a card.
-                                       Different versions exist for modules and built-in.
-   vortex_probe1()             Fill in the device structure -- this is separated
-                                       so that the modules code can put it in dev->init.
-*/
 /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
-/* Note: this is the only limit on the number of cards supported!! */
-static int options[8] = { -1, -1, -1, -1, -1, -1, -1, -1,};
-static int full_duplex[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
+/* Option count limit only -- unlimited interfaces are supported. */
+#define MAX_UNITS 8
+static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1,};
+static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 /* A list of all installed Vortex devices, for removing the driver module. */
 static struct device *root_vortex_dev = NULL;
 
 #ifdef MODULE
+#ifndef CARDBUS
 /* Variables to work-around the Compaq PCI BIOS32 problem. */
 static int compaq_ioaddr = 0, compaq_irq = 0, compaq_device_id = 0x5900;
-
-static int debug = -1;
+#endif
 
 #ifdef CARDBUS
 
@@ -531,19 +523,38 @@ static int debug = -1;
 
 static dev_node_t *vortex_attach(dev_locator_t *loc)
 {
-       u16 dev_id;
+       u16 dev_id, vendor_id;
        u32 io;
        u8 bus, devfn, irq;
        struct device *dev;
+       int chip_idx;
 
        if (loc->bus != LOC_PCI) return NULL;
        bus = loc->b.pci.bus; devfn = loc->b.pci.devfn;
-       printk(KERN_INFO "vortex_attach(bus %d, function %d)\n", bus, devfn);
        pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &io);
        pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq);
+       pcibios_read_config_word(bus, devfn, PCI_VENDOR_ID, &vendor_id);
        pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &dev_id);
+       printk(KERN_INFO "vortex_attach(bus %d, function %d, device %4.4x)\n",
+                  bus, devfn, dev_id);
        io &= ~3;
-       dev = vortex_found_device(NULL, io, irq, dev_id, 0, -1);
+       if (io == 0 || irq == 0) {
+               printk(KERN_ERR "The 3Com CardBus Ethernet interface was not "
+                          "assigned an %s.\n" KERN_ERR "  It will not be activated.\n",
+                          io == 0 ? "I/O address" : "IRQ");
+               return NULL;
+       }
+       for (chip_idx = 0; pci_tbl[chip_idx].vendor_id; chip_idx++)
+               if (vendor_id == pci_tbl[chip_idx].vendor_id
+                       && (dev_id & pci_tbl[chip_idx].device_id_mask) ==
+                       pci_tbl[chip_idx].device_id)
+                       break;
+       if (pci_tbl[chip_idx].vendor_id == 0) {                 /* Compiled out! */
+               printk(KERN_INFO "Unable to match chip type %4.4x %4.4x in "
+                          "vortex_attach().\n", vendor_id, dev_id);
+               return NULL;
+       }
+       dev = vortex_probe1(bus, devfn, NULL, io, irq, chip_idx, MAX_UNITS+1);
        if (dev) {
                dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL);
                strcpy(node->dev_name, dev->name);
@@ -565,61 +576,52 @@ static void vortex_detach(dev_node_t *node)
        }
        if (*devp) {
                struct device *dev = *devp;
+               struct vortex_private *vp = dev->priv;
                if (dev->flags & IFF_UP)
                        vortex_close(dev);
                dev->flags &= ~(IFF_UP|IFF_RUNNING);
                unregister_netdev(dev);
+               if (vp->cb_fn_base) iounmap(vp->cb_fn_base);
                kfree(dev);
                *devp = *next;
+               kfree(vp);
                kfree(node);
                MOD_DEC_USE_COUNT;
        }
 }
 
 struct driver_operations vortex_ops = {
-       "3c59x_cb", vortex_attach, NULL, NULL, vortex_detach
+       "3c575_cb", vortex_attach, NULL, NULL, vortex_detach
 };
 
 #endif  /* Cardbus support */
 
 
-int
-init_module(void)
+int init_module(void)
 {
-       if (debug >= 0)
-               vortex_debug = debug;
        if (vortex_debug)
-               printk(version);
-
-       root_vortex_dev = NULL;
+               printk(KERN_INFO "%s", version);
 #ifdef CARDBUS
        register_driver(&vortex_ops);
        return 0;
 #else
-       {
-               int cards_found = vortex_scan(0);
-               if (cards_found == 0)
-                       printk("No 3Com Vortex/Boomerang cards found.\n");
-               return cards_found ? 0 : -ENODEV;
-       }
+       return vortex_scan(0, pci_tbl);
 #endif
 }
 
 #else
 int tc59x_probe(struct device *dev)
 {
-       int cards_found = 0;
-
-       cards_found = vortex_scan(dev);
-
-       if (vortex_debug > 0  &&  cards_found)
-               printk(version);
-
-       return cards_found ? 0 : -ENODEV;
+       static int scanned=0;
+       if(scanned++)
+               return -ENODEV;
+       printk(KERN_INFO "%s", version);
+       return vortex_scan(dev, pci_tbl);
 }
 #endif  /* not MODULE */
 
-static int vortex_scan(struct device *dev)
+#ifndef CARDBUS
+static int vortex_scan(struct device *dev, struct pci_id_info pci_tbl[])
 {
        int cards_found = 0;
 
@@ -634,25 +636,30 @@ static int vortex_scan(struct device *dev)
                unsigned char pci_bus, pci_device_fn;
 
                for (;pci_index < 0xff; pci_index++) {
-                       u8 pci_latency;
-                       u16 pci_command, new_command, vendor, device;
-                       int irq;
+                       u16 vendor, device, pci_command, new_command, pwr_cmd;
+                       int chip_idx, irq;
                        long ioaddr;
 
-                       if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
-                                                                       pci_index, &pci_bus, &pci_device_fn)
+                       if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pci_index,
+                                                                       &pci_bus, &pci_device_fn)
                                != PCIBIOS_SUCCESSFUL)
                                break;
                        pcibios_read_config_word(pci_bus, pci_device_fn,
                                                                         PCI_VENDOR_ID, &vendor);
                        pcibios_read_config_word(pci_bus, pci_device_fn,
                                                                         PCI_DEVICE_ID, &device);
-                       pcibios_read_config_word(pci_bus, pci_device_fn,
-                                                                        PCI_COMMAND, &pci_command);
+                       for (chip_idx = 0; pci_tbl[chip_idx].vendor_id; chip_idx++)
+                               if (vendor == pci_tbl[chip_idx].vendor_id
+                                       && (device & pci_tbl[chip_idx].device_id_mask) ==
+                                       pci_tbl[chip_idx].device_id)
+                                       break;
+                       if (pci_tbl[chip_idx].vendor_id == 0)           /* Compiled out! */
+                               continue;
+
                        {
 #if LINUX_VERSION_CODE >= 0x20155
                                struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn);
-                               ioaddr = pdev->base_address[0];
+                               ioaddr = pdev->base_address[0] & ~3;
                                irq = pdev->irq;
 #else
                                u32 pci_ioaddr;
@@ -661,15 +668,28 @@ static int vortex_scan(struct device *dev)
                                                                                 PCI_INTERRUPT_LINE, &pci_irq_line);
                                pcibios_read_config_dword(pci_bus, pci_device_fn,
                                                                                  PCI_BASE_ADDRESS_0, &pci_ioaddr);
-                               ioaddr = pci_ioaddr;
+                               ioaddr = pci_ioaddr & ~3;;
                                irq = pci_irq_line;
 #endif
                        }
-                       /* Remove I/O space marker in bit 0. */
-                       ioaddr &= ~3;
 
-                       if (vendor != TCOM_VENDOR_ID)
-                               continue;
+                       /* Power-up the card. */
+                       pcibios_read_config_word(pci_bus, pci_device_fn,
+                                                                                0xe0, &pwr_cmd);
+                       if (pwr_cmd & 0x3) {
+                               /* Save the ioaddr and IRQ info! */
+                               printk(KERN_INFO "  A 3Com network adapter is powered down!"
+                                          "  Setting the power state %4.4x->%4.4x.\n",
+                                          pwr_cmd, pwr_cmd & ~3);
+                               pcibios_write_config_word(pci_bus, pci_device_fn,
+                                                                                 0xe0, pwr_cmd & ~3);
+                               printk(KERN_INFO "  Setting the IRQ to %d, IOADDR to %#lx.\n",
+                                          irq, ioaddr);
+                               pcibios_write_config_byte(pci_bus, pci_device_fn,
+                                                                                PCI_INTERRUPT_LINE, irq);
+                               pcibios_write_config_dword(pci_bus, pci_device_fn,
+                                                                                 PCI_BASE_ADDRESS_0, ioaddr);
+                       }
 
                        if (ioaddr == 0) {
                                printk(KERN_WARNING "  A 3Com network adapter has been found, "
@@ -679,34 +699,31 @@ static int vortex_scan(struct device *dev)
                                continue;
                        }
 
-                       if (check_region(ioaddr, VORTEX_TOTAL_SIZE))
+                       if (check_region(ioaddr, pci_tbl[chip_idx].io_size))
                                continue;
 
                        /* Activate the card. */
+                       pcibios_read_config_word(pci_bus, pci_device_fn,
+                                                                        PCI_COMMAND, &pci_command);
                        new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
                        if (pci_command != new_command) {
-                               printk(KERN_INFO "  The PCI BIOS has not enabled this"
-                                          " device!  Updating PCI command %4.4x->%4.4x.\n",
-                                          pci_command, new_command);
+                               printk(KERN_INFO "  The PCI BIOS has not enabled the device "
+                                          "at %d/%d. Updating PCI command %4.4x->%4.4x.\n",
+                                          pci_bus, pci_device_fn, pci_command, new_command);
                                pcibios_write_config_word(pci_bus, pci_device_fn,
                                                                                  PCI_COMMAND, new_command);
                        }
 
-                       dev = vortex_found_device(dev, ioaddr, irq,
-                                                                         device, dev && dev->mem_start
-                                                                         ? dev->mem_start : options[cards_found],
-                                                                         cards_found);
+                       dev = vortex_probe1(pci_bus, pci_device_fn, dev, ioaddr, irq,
+                                                               chip_idx, cards_found);
 
                        if (dev) {
-                               struct vortex_private *vp = (struct vortex_private *)dev->priv;
                                /* Get and check the latency values.  On the 3c590 series
                                   the latency timer must be set to the maximum value to avoid
                                   data corruption that occurs when the timer expires during
                                   a transfer -- a bug in the Vortex chip only. */
-                               u8 new_latency = (device&0xff00) == 0x5900 ? 248 : 32;
-                               vp->pci_bus = pci_bus;
-                               vp->pci_dev_fn = pci_device_fn;
-                               vp->pci_device_id = device;
+                               u8 pci_latency;
+                               u8 new_latency = (device & 0xff00) == 0x5900 ? 248 : 32;
                                
                                pcibios_read_config_byte(pci_bus, pci_device_fn,
                                                                                 PCI_LATENCY_TIMER, &pci_latency);
@@ -726,7 +743,7 @@ static int vortex_scan(struct device *dev)
 
        /* Now check all slots of the EISA bus. */
        if (EISA_bus) {
-               static int ioaddr = 0x1000;
+               static long ioaddr = 0x1000;
                for ( ; ioaddr < 0x9000; ioaddr += 0x1000) {
                        int device_id;
                        if (check_region(ioaddr, VORTEX_TOTAL_SIZE))
@@ -738,10 +755,8 @@ static int vortex_scan(struct device *dev)
                        device_id = (inb(ioaddr + 0xC82)<<8) + inb(ioaddr + 0xC83);
                        if ((device_id & 0xFF00) != 0x5900)
                                continue;
-                       vortex_found_device(dev, ioaddr, inw(ioaddr + 0xC88) >> 12,
-                                                               device_id,  dev && dev->mem_start
-                                                               ? dev->mem_start : options[cards_found],
-                                                               cards_found);
+                       vortex_probe1(0, 0, dev, ioaddr, inw(ioaddr + 0xC88) >> 12,
+                                                 4, cards_found);
                        dev = 0;
                        cards_found++;
                }
@@ -750,97 +765,58 @@ static int vortex_scan(struct device *dev)
 #ifdef MODULE
        /* Special code to work-around the Compaq PCI BIOS32 problem. */
        if (compaq_ioaddr) {
-               vortex_found_device(dev, compaq_ioaddr, compaq_irq, compaq_device_id,
-                                                       dev && dev->mem_start ? dev->mem_start
-                                                       : options[cards_found], cards_found);
-               cards_found++;
+               vortex_probe1(0, 0, dev, compaq_ioaddr, compaq_irq,
+                                         compaq_device_id, cards_found++);
                dev = 0;
        }
 #endif
 
-       /* 3c515 cards are now supported by the 3c515.c driver. */
-
-       return cards_found;
+       return cards_found ? 0 : -ENODEV;
 }
+#endif  /* ! Cardbus */
 
-static struct device *
-vortex_found_device(struct device *dev, int ioaddr, int irq,
-                                       int device_id, int option, int card_idx)
+static struct device *vortex_probe1(int pci_bus, int pci_devfn,
+                                                                       struct device *dev, long ioaddr,
+                                                                       int irq, int chip_idx, int card_idx)
 {
        struct vortex_private *vp;
-       const char *product_name;
-       int board_index = 0;
+       int option;
+       unsigned int eeprom[0x40], checksum = 0;                /* EEPROM contents */
+       int i;
 
-       for (board_index = 0; product_ids[board_index]; board_index++) {
-               if (device_id == product_ids[board_index])
-                       break;
-       }
-       /* Handle products we don't recognize, but might still work with. */
-       if (product_ids[board_index])
-               product_name = product_names[board_index];
-       else if ((device_id & 0xff00) == 0x5900)
-               product_name = "3c590 Vortex";
-       else if ((device_id & 0xfff0) == 0x9000)
-               product_name = "3c900";
-       else if ((device_id & 0xfff0) == 0x9050)
-               product_name = "3c905";
-       else {
-               printk(KERN_WARNING "Unknown 3Com PCI ethernet adapter type %4.4x detected:"
-                          " not configured.\n", device_id);
-               return 0;
-       }
+       dev = init_etherdev(dev, 0);
 
-#ifdef MODULE
-       /* Allocate and fill new device structure. */
-       {
-               int dev_size = sizeof(struct device) +
-                       sizeof(struct vortex_private) + 15;             /* Pad for alignment */
+       printk(KERN_INFO "%s: 3Com %s at 0x%lx, ",
+                  dev->name, pci_tbl[chip_idx].name, ioaddr);
 
-               dev = (struct device *) kmalloc(dev_size, GFP_KERNEL);
-               memset(dev, 0, dev_size);
-       }
-       /* Align the Rx and Tx ring entries.  */
-       dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15);
-       vp = (struct vortex_private *)dev->priv;
-       dev->name = vp->devname; /* An empty string. */
        dev->base_addr = ioaddr;
        dev->irq = irq;
-       dev->init = vortex_probe1;
-       vp->product_name = product_name;
-       vp->options = option;
-       if (card_idx >= 0) {
-               if (full_duplex[card_idx] >= 0)
-                       vp->full_duplex = full_duplex[card_idx];
-       } else
-               vp->full_duplex = (option > 0 && (option & 0x10) ? 1 : 0);
+       dev->mtu = mtu;
 
-       if (option > 0) {
-               vp->media_override = ((option & 7) == XCVR_10baseTOnly) ?
-                       XCVR_10baseT  :  option & 7;
-               vp->bus_master = (option & 16) ? 1 : 0;
-       } else {
-               vp->media_override = 7;
-               vp->bus_master = 0;
+       /* Make certain the descriptor lists are aligned. */
+       {
+               void *mem = kmalloc(sizeof(*vp) + 15, GFP_KERNEL);
+               vp =  (void *)(((long)mem + 15) & ~15);
+               vp->priv_addr = mem;
        }
-       ether_setup(dev);
+       memset(vp, 0, sizeof(*vp));
+       dev->priv = vp;
+
        vp->next_module = root_vortex_dev;
        root_vortex_dev = dev;
-       if (register_netdev(dev) != 0)
-               return 0;
-#else  /* not a MODULE */
-       if (dev) {
-               /* Caution: quad-word alignment required for rings! */
-               dev->priv = kmalloc(sizeof (struct vortex_private), GFP_KERNEL);
-               memset(dev->priv, 0, sizeof (struct vortex_private));
-       }
-       dev = init_etherdev(dev, sizeof(struct vortex_private));
-       dev->base_addr = ioaddr;
-       dev->irq = irq;
-       dev->mtu = mtu;
 
-       vp  = (struct vortex_private *)dev->priv;
-       vp->product_name = product_name;
-       vp->options = option;
+       vp->chip_id = chip_idx;
+       vp->pci_bus = pci_bus;
+       vp->pci_devfn = pci_devfn;
+
+       /* The lower four bits are the media type. */
+       if (dev->mem_start)
+               option = dev->mem_start;
+       else if (card_idx < MAX_UNITS)
+               option = options[card_idx];
+       else
+               option = -1;
+
        if (option >= 0) {
                vp->media_override = ((option & 7) == 2)  ?  0  :  option & 7;
                vp->full_duplex = (option & 8) ? 1 : 0;
@@ -850,22 +826,11 @@ vortex_found_device(struct device *dev, int ioaddr, int irq,
                vp->full_duplex = 0;
                vp->bus_master = 0;
        }
+       if (card_idx < MAX_UNITS  &&  full_duplex[card_idx] > 0)
+               vp->full_duplex = 1;
 
-       vortex_probe1(dev);
-#endif /* MODULE */
-       return dev;
-}
-
-static int vortex_probe1(struct device *dev)
-{
-       int ioaddr = dev->base_addr;
-       struct vortex_private *vp = (struct vortex_private *)dev->priv;
-       u16 *ether_addr = (u16 *)dev->dev_addr;
-       unsigned int eeprom[0x40], checksum = 0;                /* EEPROM contents */
-       int i;
-
-       printk(KERN_INFO "%s: 3Com %s at %#3x,",
-                  dev->name, vp->product_name, ioaddr);
+       vp->force_fd = vp->full_duplex;
+       vp->options = option;
 
        /* Read the station address from the EEPROM. */
        EL3WINDOW(0);
@@ -896,14 +861,30 @@ static int vortex_probe1(struct device *dev)
                printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
 
        for (i = 0; i < 3; i++)
-               ether_addr[i] = htons(eeprom[i + 10]);
+               ((u16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
        for (i = 0; i < 6; i++)
                printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
+#ifdef __sparc__
+       printk(", IRQ %s\n", __irq_itoa(dev->irq));
+#else
        printk(", IRQ %d\n", dev->irq);
        /* Tell them about an invalid IRQ. */
        if (vortex_debug && (dev->irq <= 0 || dev->irq >= NR_IRQS))
                printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n",
                           dev->irq);
+#endif
+
+       if (pci_tbl[vp->chip_id].drv_flags & HAS_CB_FNS) {
+               u32 fn_st_addr;                 /* Cardbus function status space */
+               pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_2,
+                                                                 &fn_st_addr);
+               if (fn_st_addr)
+                       vp->cb_fn_base = ioremap(fn_st_addr & ~3, 128);
+               printk("%s: CardBus functions mapped %8.8x->%p (PCMCIA committee"
+                          " brain-damage).\n", dev->name, fn_st_addr, vp->cb_fn_base);
+               EL3WINDOW(2);
+               outw(0x10 | inw(ioaddr + Wn2_ResetOptions), ioaddr + Wn2_ResetOptions);
+       }
 
        /* Extract our information from the EEPROM data. */
        vp->info1 = eeprom[13];
@@ -929,7 +910,7 @@ static int vortex_probe1(struct device *dev)
                           config.u.ram_width ? "word" : "byte",
                           ram_split[config.u.ram_split],
                           config.u.autoselect ? "autoselect/" : "",
-                          config.u.xcvr ? "NWay Autonegotiation" :
+                          config.u.xcvr > XCVR_ExtMII ? "<invalid transceiver>" :
                           media_tbl[config.u.xcvr].name);
                vp->default_media = config.u.xcvr;
                vp->autoselect = config.u.autoselect;
@@ -942,22 +923,24 @@ static int vortex_probe1(struct device *dev)
        } else
                dev->if_port = vp->default_media;
 
-       if (dev->if_port == XCVR_MII) {
+       if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
                int phy, phy_idx = 0;
                EL3WINDOW(4);
-               for (phy = 0; phy < 32 && phy_idx < sizeof(vp->phys); phy++) {
-                       int mii_status;
-                       mdio_sync(ioaddr, 32);
-                       mii_status = mdio_read(ioaddr, phy, 1);
+               mii_preamble_required++;
+               mii_preamble_required++;
+               mdio_read(ioaddr, 24, 1);
+               for (phy = 1; phy <= 32 && phy_idx < sizeof(vp->phys); phy++) {
+                       int mii_status, phyx = phy & 0x1f;
+                       mii_status = mdio_read(ioaddr, phyx, 1);
                        if (mii_status  &&  mii_status != 0xffff) {
-                               vp->phys[phy_idx++] = phy;
-                               printk(KERN_INFO "  MII transceiver found at address %d, status %4x.\n",
-                                          phy, mii_status);
-                               mdio_sync(ioaddr, 32);
-                               if ((mdio_read(ioaddr, phy, 1) & 0x0040) == 0)
-                                       mii_preamble_required = 1;
+                               vp->phys[phy_idx++] = phyx;
+                               printk(KERN_INFO "  MII transceiver found at address %d,"
+                                          " status %4x.\n", phyx, mii_status);
+                               if ((mii_status & 0x0040) == 0)
+                                       mii_preamble_required++;
                        }
                }
+               mii_preamble_required--;
                if (phy_idx == 0) {
                        printk(KERN_WARNING"  ***WARNING*** No MII transceivers found!\n");
                        vp->phys[0] = 24;
@@ -965,7 +948,7 @@ static int vortex_probe1(struct device *dev)
                        vp->advertising = mdio_read(ioaddr, vp->phys[0], 4);
                        if (vp->full_duplex) {
                                /* Only advertise the FD media types. */
-                               vp->advertising &= 0x015F;
+                               vp->advertising &= ~0x02A0;
                                mdio_write(ioaddr, vp->phys[0], 4, vp->advertising);
                        }
                }
@@ -979,30 +962,24 @@ static int vortex_probe1(struct device *dev)
        }
 
        /* We do a request_region() to register /proc/ioports info. */
-       request_region(ioaddr, VORTEX_TOTAL_SIZE, vp->product_name);
+       request_region(ioaddr, pci_tbl[chip_idx].io_size, dev->name);
 
        /* The 3c59x-specific entries in the device structure. */
        dev->open = &vortex_open;
        dev->hard_start_xmit = &vortex_start_xmit;
        dev->stop = &vortex_close;
        dev->get_stats = &vortex_get_stats;
-#ifdef HAVE_PRIVATE_IOCTL
        dev->do_ioctl = &vortex_ioctl;
-#endif
-#ifdef NEW_MULTICAST
        dev->set_multicast_list = &set_rx_mode;
-#else
-       dev->set_multicast_list = &set_multicast_list;
-#endif
 
-       return 0;
+       return dev;
 }
 
 \f
 static int
 vortex_open(struct device *dev)
 {
-       int ioaddr = dev->base_addr;
+       long ioaddr = dev->base_addr;
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
        union wn3_config config;
        int i;
@@ -1017,28 +994,31 @@ vortex_open(struct device *dev)
                                   dev->name, vp->media_override,
                                   media_tbl[vp->media_override].name);
                dev->if_port = vp->media_override;
+       } else if (vp->autoselect && pci_tbl[vp->chip_id].drv_flags & HAS_NWAY) {
+                       dev->if_port = XCVR_NWAY;
        } else if (vp->autoselect) {
                /* Find first available media type, starting with 100baseTx. */
                dev->if_port = XCVR_100baseTx;
                while (! (vp->available_media & media_tbl[dev->if_port].mask))
                        dev->if_port = media_tbl[dev->if_port].next;
-
-               if (vortex_debug > 1)
-                       printk(KERN_DEBUG "%s: Initial media type %s.\n",
-                                  dev->name, media_tbl[dev->if_port].name);
-
-               init_timer(&vp->timer);
-               vp->timer.expires = RUN_AT(media_tbl[dev->if_port].wait);
-               vp->timer.data = (unsigned long)dev;
-               vp->timer.function = &vortex_timer;    /* timer handler */
-               add_timer(&vp->timer);
        } else
                dev->if_port = vp->default_media;
 
+       init_timer(&vp->timer);
+       vp->timer.expires = RUN_AT(media_tbl[dev->if_port].wait);
+       vp->timer.data = (unsigned long)dev;
+       vp->timer.function = &vortex_timer;             /* timer handler */
+       add_timer(&vp->timer);
+
+       if (vortex_debug > 1)
+               printk(KERN_DEBUG "%s: Initial media type %s.\n",
+                          dev->name, media_tbl[dev->if_port].name);
+
+       vp->full_duplex = vp->force_fd;
        config.u.xcvr = dev->if_port;
        outl(config.i, ioaddr + Wn3_Config);
 
-       if (dev->if_port == XCVR_MII) {
+       if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
                int mii_reg1, mii_reg5;
                EL3WINDOW(4);
                /* Read BMSR (reg1) only to clear old status. */
@@ -1078,20 +1058,10 @@ vortex_open(struct device *dev)
 
        outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
 
-#ifdef SA_SHIRQ
        /* Use the now-standard shared IRQ implementation. */
        if (request_irq(dev->irq, &vortex_interrupt, SA_SHIRQ, dev->name, dev)) {
                return -EAGAIN;
        }
-#else
-       if (dev->irq == 0  ||  irq2dev_map[dev->irq] != NULL)
-               return -EAGAIN;
-       irq2dev_map[dev->irq] = dev;
-       if (request_irq(dev->irq, &vortex_interrupt, 0, vp->product_name)) {
-               irq2dev_map[dev->irq] = NULL;
-               return -EAGAIN;
-       }
-#endif
 
        if (vortex_debug > 1) {
                EL3WINDOW(4);
@@ -1109,9 +1079,11 @@ vortex_open(struct device *dev)
        if (dev->if_port == XCVR_10base2)
                /* Start the thinnet transceiver. We should really wait 50ms...*/
                outw(StartCoax, ioaddr + EL3_CMD);
-       EL3WINDOW(4);
-       outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
-                media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
+       if (dev->if_port != XCVR_NWAY) {
+               EL3WINDOW(4);
+               outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
+                        media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
+       }
 
        /* Switch to the stats window, and clear all stats by reading. */
        outw(StatsDisable, ioaddr + EL3_CMD);
@@ -1138,22 +1110,23 @@ vortex_open(struct device *dev)
                        printk(KERN_DEBUG "%s:  Filling in the Rx ring.\n", dev->name);
                for (i = 0; i < RX_RING_SIZE; i++) {
                        struct sk_buff *skb;
-                       vp->rx_ring[i].next = virt_to_bus(&vp->rx_ring[i+1]);
+                       vp->rx_ring[i].next = cpu_to_le32(virt_to_bus(&vp->rx_ring[i+1]));
                        vp->rx_ring[i].status = 0;      /* Clear complete bit. */
-                       vp->rx_ring[i].length = PKT_BUF_SZ | LAST_FRAG;
-                       skb = DEV_ALLOC_SKB(PKT_BUF_SZ);
+                       vp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ | LAST_FRAG);
+                       skb = dev_alloc_skb(PKT_BUF_SZ);
                        vp->rx_skbuff[i] = skb;
                        if (skb == NULL)
                                break;                  /* Bad news!  */
                        skb->dev = dev;                 /* Mark as being used by this device. */
 #if LINUX_VERSION_CODE >= 0x10300
                        skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
-                       vp->rx_ring[i].addr = virt_to_bus(skb->tail);
+                       vp->rx_ring[i].addr = cpu_to_le32(virt_to_bus(skb->tail));
 #else
                        vp->rx_ring[i].addr = virt_to_bus(skb->data);
 #endif
                }
-               vp->rx_ring[i-1].next = virt_to_bus(&vp->rx_ring[0]); /* Wrap the ring. */
+               /* Wrap the ring. */
+               vp->rx_ring[i-1].next = cpu_to_le32(virt_to_bus(&vp->rx_ring[0]));
                outl(virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
        }
        if (vp->full_bus_master_tx) {           /* Boomerang bus master Tx. */
@@ -1181,14 +1154,16 @@ vortex_open(struct device *dev)
                (vp->full_bus_master_tx ? DownComplete : TxAvailable) |
                (vp->full_bus_master_rx ? UpComplete : RxComplete) |
                (vp->bus_master ? DMADone : 0);
+       vp->intr_enable = SetIntrEnb | IntLatch | TxAvailable | RxComplete |
+               StatsFull | HostError | TxComplete | IntReq
+               | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete;
        outw(vp->status_enable, ioaddr + EL3_CMD);
        /* Ack all pending events, and set active indicator mask. */
        outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
                 ioaddr + EL3_CMD);
-       outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull
-                | HostError | TxComplete
-                | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete,
-                       ioaddr + EL3_CMD);
+       outw(vp->intr_enable, ioaddr + EL3_CMD);
+       if (vp->cb_fn_base)                     /* The PCMCIA people are idiots.  */
+               writel(0x8000, vp->cb_fn_base + 4);
 
        MOD_INC_USE_COUNT;
 
@@ -1197,24 +1172,23 @@ vortex_open(struct device *dev)
 
 static void vortex_timer(unsigned long data)
 {
-#ifdef AUTOMEDIA
        struct device *dev = (struct device *)data;
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
-       int ioaddr = dev->base_addr;
-       unsigned long flags;
+       long ioaddr = dev->base_addr;
+       int next_tick = 0;
        int ok = 0;
+       int media_status, mii_status, old_window;
 
        if (vortex_debug > 1)
                printk(KERN_DEBUG "%s: Media selection timer tick happened, %s.\n",
                           dev->name, media_tbl[dev->if_port].name);
 
-       save_flags(flags);      cli(); {
-         int old_window = inw(ioaddr + EL3_CMD) >> 13;
-         int media_status;
-         EL3WINDOW(4);
-         media_status = inw(ioaddr + Wn4_Media);
-         switch (dev->if_port) {
-         case XCVR_10baseT:  case XCVR_100baseTx:  case XCVR_100baseFx:
+       disable_irq(dev->irq);
+       old_window = inw(ioaddr + EL3_CMD) >> 13;
+       EL3WINDOW(4);
+       media_status = inw(ioaddr + Wn4_Media);
+       switch (dev->if_port) {
+       case XCVR_10baseT:  case XCVR_100baseTx:  case XCVR_100baseFx:
                if (media_status & Media_LnkBeat) {
                  ok = 1;
                  if (vortex_debug > 1)
@@ -1223,27 +1197,40 @@ static void vortex_timer(unsigned long data)
                } else if (vortex_debug > 1)
                  printk(KERN_DEBUG "%s: Media %s is has no link beat, %x.\n",
                                   dev->name, media_tbl[dev->if_port].name, media_status);
-
                break;
-         case XCVR_MII:
-                 {
-                         int mii_reg1 = mdio_read(ioaddr, vp->phys[0], 1);
+         case XCVR_MII: case XCVR_NWAY:
+                 mii_status = mdio_read(ioaddr, vp->phys[0], 1);
+                 ok = 1;
+                 if (debug > 1)
+                         printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n",
+                                        dev->name, mii_status);
+                 if (mii_status & 0x0004) {
                          int mii_reg5 = mdio_read(ioaddr, vp->phys[0], 5);
-                         if (vortex_debug > 1)
-                                 printk(KERN_DEBUG "%s: MII #%d status register is %4.4x, "
-                                                "link partner capability %4.4x.\n",
-                                                dev->name, vp->phys[0], mii_reg1, mii_reg5);
-                         if (mii_reg1 & 0x0004)
-                                 ok = 1;
-                         break;
+                         if (! vp->force_fd  &&  mii_reg5 != 0xffff) {
+                                 int duplex = (mii_reg5&0x0100) ||
+                                         (mii_reg5 & 0x01C0) == 0x0040;
+                                 if (vp->full_duplex != duplex) {
+                                         vp->full_duplex = duplex;
+                                         printk(KERN_INFO "%s: Setting %s-duplex based on MII "
+                                                        "#%d link partner capability of %4.4x.\n",
+                                                        dev->name, vp->full_duplex ? "full" : "half",
+                                                        vp->phys[0], mii_reg5);
+                                         /* Set the full-duplex bit. */
+                                         outb((vp->full_duplex ? 0x20 : 0) |
+                                                  (dev->mtu > 1500 ? 0x40 : 0),
+                                                  ioaddr + Wn3_MAC_Ctrl);
+                                 }
+                                 next_tick = 60*HZ;
+                         }
                  }
+                 break;
          default:                                      /* Other media types handled by Tx timeouts. */
                if (vortex_debug > 1)
                  printk(KERN_DEBUG "%s: Media %s is has no indication, %x.\n",
                                 dev->name, media_tbl[dev->if_port].name, media_status);
                ok = 1;
-         }
-         if ( ! ok) {
+       }
+       if ( ! ok) {
                union wn3_config config;
 
                do {
@@ -1260,8 +1247,7 @@ static void vortex_timer(unsigned long data)
                        printk(KERN_DEBUG "%s: Media selection failed, now trying "
                                   "%s port.\n",
                                   dev->name, media_tbl[dev->if_port].name);
-                 vp->timer.expires = RUN_AT(media_tbl[dev->if_port].wait);
-                 add_timer(&vp->timer);
+                 next_tick = RUN_AT(media_tbl[dev->if_port].wait);
                }
                outw((media_status & ~(Media_10TP|Media_SQE)) |
                         media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
@@ -1273,21 +1259,25 @@ static void vortex_timer(unsigned long data)
 
                outw(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
                         ioaddr + EL3_CMD);
-         }
-         EL3WINDOW(old_window);
-       }   restore_flags(flags);
-       if (vortex_debug > 1)
+       }
+       EL3WINDOW(old_window);
+       enable_irq(dev->irq);
+
+       if (vortex_debug > 2)
          printk(KERN_DEBUG "%s: Media selection timer finished, %s.\n",
                         dev->name, media_tbl[dev->if_port].name);
 
-#endif /* AUTOMEDIA*/
+       if (next_tick) {
+               vp->timer.expires = RUN_AT(next_tick);
+               add_timer(&vp->timer);
+       }
        return;
 }
 
 static void vortex_tx_timeout(struct device *dev)
 {
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
-       int ioaddr = dev->base_addr;
+       long ioaddr = dev->base_addr;
        int j;
 
        printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
@@ -1301,7 +1291,7 @@ static void vortex_tx_timeout(struct device *dev)
                printk(KERN_ERR "%s: Interrupt posted but not delivered --"
                           " IRQ blocked by another device?\n", dev->name);
                /* Bad idea here.. but we might as well handle a few events. */
-               vortex_interrupt IRQ(dev->irq, dev, 0);
+               vortex_interrupt(dev->irq, dev, 0);
        }
        outw(TxReset, ioaddr + EL3_CMD);
        for (j = 200; j >= 0 ; j--)
@@ -1320,8 +1310,8 @@ static void vortex_tx_timeout(struct device *dev)
                for (i = 0; i < TX_RING_SIZE; i++) {
                        printk(KERN_DEBUG "  %d: @%p  length %8.8x status %8.8x\n", i,
                                   &vp->tx_ring[i],
-                                  vp->tx_ring[i].length,
-                                  vp->tx_ring[i].status);
+                                  le32_to_cpu(vp->tx_ring[i].length),
+                                  le32_to_cpu(vp->tx_ring[i].status));
                }
        }
 #endif
@@ -1351,14 +1341,14 @@ static void vortex_tx_timeout(struct device *dev)
 }
 
 /*
- * Handle uncommon interrupt sources.  This is a seperate routine to minimize
+ * Handle uncommon interrupt sources.  This is a separate routine to minimize
  * the cache impact.
  */
 static void
 vortex_error(struct device *dev, int status)
 {
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
-       int ioaddr = dev->base_addr;
+       long ioaddr = dev->base_addr;
        int do_tx_reset = 0;
        int i;
 
@@ -1398,8 +1388,10 @@ vortex_error(struct device *dev, int status)
                        DoneDidThat++;
                }
        }
-       if (status & IntReq)            /* Restore all interrupt sources.  */
-               outw(ioaddr + EL3_CMD, vp->status_enable);
+       if (status & IntReq) {          /* Restore all interrupt sources.  */
+               outw(vp->status_enable, ioaddr + EL3_CMD);
+               outw(vp->intr_enable, ioaddr + EL3_CMD);
+       }
        if (status & HostError) {
                u16 fifo_diag;
                EL3WINDOW(4);
@@ -1445,7 +1437,7 @@ static int
 vortex_start_xmit(struct sk_buff *skb, struct device *dev)
 {
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
-       int ioaddr = dev->base_addr;
+       long ioaddr = dev->base_addr;
 
        if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
                if (jiffies - dev->trans_start >= TX_TIMEOUT)
@@ -1455,7 +1447,6 @@ vortex_start_xmit(struct sk_buff *skb, struct device *dev)
 
        /* Put out the doubleword header... */
        outl(skb->len, ioaddr + TX_FIFO);
-#ifdef VORTEX_BUS_MASTER
        if (vp->bus_master) {
                /* Set the bus-master controller to transfer the packet. */
                outl(virt_to_bus(skb->data), ioaddr + Wn7_MasterAddr);
@@ -1473,16 +1464,6 @@ vortex_start_xmit(struct sk_buff *skb, struct device *dev)
                        /* Interrupt us when the FIFO has room for max-sized packet. */
                        outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
        }
-#else
-       /* ... and the packet rounded to a doubleword. */
-       outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
-       DEV_FREE_SKB(skb);
-       if (inw(ioaddr + TxFree) > 1536) {
-               clear_bit(0, (void*)&dev->tbusy);
-       } else
-               /* Interrupt us when the FIFO has room for max-sized packet. */
-               outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
-#endif  /* bus master */
 
        dev->trans_start = jiffies;
 
@@ -1517,7 +1498,7 @@ static int
 boomerang_start_xmit(struct sk_buff *skb, struct device *dev)
 {
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
-       int ioaddr = dev->base_addr;
+       long ioaddr = dev->base_addr;
 
        if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
                if (jiffies - dev->trans_start >= TX_TIMEOUT)
@@ -1539,13 +1520,12 @@ boomerang_start_xmit(struct sk_buff *skb, struct device *dev)
                                printk(KERN_WARNING "%s: Tx Ring full, refusing to send buffer.\n",
                                           dev->name);
                        return 1;
-               } 
-               /* end change 06/25/97 M. Sievers */    
+               }
                vp->tx_skbuff[entry] = skb;
                vp->tx_ring[entry].next = 0;
-               vp->tx_ring[entry].addr = virt_to_bus(skb->data);
-               vp->tx_ring[entry].length = skb->len | LAST_FRAG;
-               vp->tx_ring[entry].status = skb->len | TxIntrUploaded;
+               vp->tx_ring[entry].addr = cpu_to_le32(virt_to_bus(skb->data));
+               vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG);
+               vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
 
                save_flags(flags);
                cli();
@@ -1554,7 +1534,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct device *dev)
                for (i = 600; i >= 0 ; i--)
                        if ( (inw(ioaddr + EL3_STATUS) & CmdInProgress) == 0)
                                break;
-               prev_entry->next = virt_to_bus(&vp->tx_ring[entry]);
+               prev_entry->next = cpu_to_le32(virt_to_bus(&vp->tx_ring[entry]));
                if (inl(ioaddr + DownListPtr) == 0) {
                        outl(virt_to_bus(&vp->tx_ring[entry]), ioaddr + DownListPtr);
                        queued_packet++;
@@ -1566,7 +1546,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct device *dev)
                if (vp->cur_tx - vp->dirty_tx > TX_RING_SIZE - 1)
                        vp->tx_full = 1;
                else {                                  /* Clear previous interrupt enable. */
-                       prev_entry->status &= ~TxIntrUploaded;
+                       prev_entry->status &= cpu_to_le32(~TxIntrUploaded);
                        clear_bit(0, (void*)&dev->tbusy);
                }
                dev->trans_start = jiffies;
@@ -1576,28 +1556,33 @@ boomerang_start_xmit(struct sk_buff *skb, struct device *dev)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs)
+static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-#ifdef SA_SHIRQ                /* Use the now-standard shared IRQ implementation. */
        struct device *dev = dev_id;
-#else
-       struct device *dev = (struct device *)(irq2dev_map[irq]);
-#endif
-       struct vortex_private *vp;
-       int ioaddr, status;
-       int latency;
+       struct vortex_private *vp = (struct vortex_private *)dev->priv;
+       long ioaddr;
+       int latency, status;
        int work_done = max_interrupt_work;
 
-       vp = (struct vortex_private *)dev->priv;
-       if (test_and_set_bit(0, (void*)&vp->in_interrupt)) {
+#if defined(__i386__)
+       /* A lock to prevent simultaneous entry bug on Intel SMP machines. */
+       if (test_and_set_bit(0, (void*)&dev->interrupt)) {
+               printk(KERN_ERR"%s: SMP simultaneous entry of an interrupt handler.\n",
+                          dev->name);
+               dev->interrupt = 0;     /* Avoid halting machine. */
+               return;
+       }
+#else
+       if (dev->interrupt) {
                printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name);
                return;
        }
+       dev->interrupt = 1;
+#endif
 
        dev->interrupt = 1;
        ioaddr = dev->base_addr;
        latency = inb(ioaddr + Timer);
-
        status = inw(ioaddr + EL3_STATUS);
 
        if (vortex_debug > 4)
@@ -1646,17 +1631,23 @@ static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs)
                                mark_bh(NET_BH);
                        }
                }
-#ifdef VORTEX_BUS_MASTER
                if (status & DMADone) {
-                       outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
-                       clear_bit(0, (void*)&dev->tbusy);
-                       DEV_FREE_SKB(vp->tx_skb); /* Release the transfered buffer */
-                       mark_bh(NET_BH);
+                       if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
+                               outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
+                               DEV_FREE_SKB(vp->tx_skb); /* Release the transfered buffer */
+                               if (inw(ioaddr + TxFree) > 1536) {
+                                       clear_bit(0, (void*)&dev->tbusy);
+                                       mark_bh(NET_BH);
+                               } else /* Interrupt when FIFO has room for max-sized packet. */
+                                       outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+                       }
                }
-#endif
                /* Check for all uncommon interrupts at once. */
-               if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq))
+               if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) {
+                       if (status == 0xffff)
+                               break;
                        vortex_error(dev, status);
+               }
 
                if (--work_done < 0) {
                        if ((status & (0x7fe - (UpComplete | DownComplete))) == 0) {
@@ -1669,13 +1660,14 @@ static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs)
                                /* Disable all pending interrupts. */
                                outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD);
                                outw(AckIntr | 0x7FF, ioaddr + EL3_CMD);
-                               /* Set a timer to reenable interrupts. */
-                               
+                               /* The timer will reenable interrupts. */
                                break;
                        }
                }
                /* Acknowledge the IRQ. */
                outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
+               if (vp->cb_fn_base)                     /* The PCMCIA people are idiots.  */
+                       writel(0x8000, vp->cb_fn_base + 4);
 
        } while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
 
@@ -1683,16 +1675,18 @@ static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs)
                printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
                           dev->name, status);
 
+#if defined(__i386__)
+       clear_bit(0, (void*)&dev->interrupt);
+#else
        dev->interrupt = 0;
-       clear_bit(0, (void*)&vp->in_interrupt);
+#endif
        return;
 }
 
-static int
-vortex_rx(struct device *dev)
+static int vortex_rx(struct device *dev)
 {
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
-       int ioaddr = dev->base_addr;
+       long ioaddr = dev->base_addr;
        int i;
        short rx_status;
 
@@ -1715,25 +1709,28 @@ vortex_rx(struct device *dev)
                        int pkt_len = rx_status & 0x1fff;
                        struct sk_buff *skb;
 
-                       skb = DEV_ALLOC_SKB(pkt_len + 5);
+                       skb = dev_alloc_skb(pkt_len + 5);
                        if (vortex_debug > 4)
                                printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n",
                                           pkt_len, rx_status);
                        if (skb != NULL) {
                                skb->dev = dev;
-#if LINUX_VERSION_CODE >= 0x10300
                                skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
                                /* 'skb_put()' points to the start of sk_buff data area. */
-                               insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
-                                        (pkt_len + 3) >> 2);
+                               if (vp->bus_master &&
+                                       ! (inw(ioaddr + Wn7_MasterStatus) & 0x8000)) {
+                                       outl(virt_to_bus(skb_put(skb, pkt_len)),
+                                                ioaddr + Wn7_MasterAddr);
+                                       outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
+                                       outw(StartDMAUp, ioaddr + EL3_CMD);
+                                       while (inw(ioaddr + Wn7_MasterStatus) & 0x8000)
+                                               ;
+                               } else {
+                                       insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
+                                                (pkt_len + 3) >> 2);
+                               }
                                outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
                                skb->protocol = eth_type_trans(skb, dev);
-#else
-                               skb->len = pkt_len;
-                               /* 'skb->data' points to the start of sk_buff data area. */
-                               insl(ioaddr + RX_FIFO, skb->data, (pkt_len + 3) >> 2);
-                               outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
-#endif  /* KERNEL_1_3_0 */
                                netif_rx(skb);
                                dev->last_rx = jiffies;
                                vp->stats.rx_packets++;
@@ -1762,7 +1759,7 @@ boomerang_rx(struct device *dev)
 {
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
        int entry = vp->cur_rx % RX_RING_SIZE;
-       int ioaddr = dev->base_addr;
+       long ioaddr = dev->base_addr;
        int rx_status;
        int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
 
@@ -1770,8 +1767,9 @@ boomerang_rx(struct device *dev)
                printk(KERN_DEBUG "  In boomerang_rx(), status %4.4x, rx_status "
                           "%4.4x.\n",
                           inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
-       while ((--rx_work_limit >= 0) &&
-                       ((rx_status = vp->rx_ring[entry].status) & RxDComplete)) {
+       while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
+               if (--rx_work_limit < 0)
+                       break;
                if (rx_status & RxDError) { /* Error, update stats. */
                        unsigned char rx_error = rx_status >> 16;
                        if (vortex_debug > 2)
@@ -1794,41 +1792,28 @@ boomerang_rx(struct device *dev)
                        /* Check if the packet is long enough to just accept without
                           copying to a properly sized skbuff. */
                        if (pkt_len < rx_copybreak
-                               && (skb = DEV_ALLOC_SKB(pkt_len + 2)) != 0) {
+                               && (skb = dev_alloc_skb(pkt_len + 2)) != 0) {
                                skb->dev = dev;
-#if LINUX_VERSION_CODE >= 0x10300
                                skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
                                /* 'skb_put()' points to the start of sk_buff data area. */
                                memcpy(skb_put(skb, pkt_len),
-                                          bus_to_virt(vp->rx_ring[entry].addr),
+                                          bus_to_virt(le32_to_cpu(vp->rx_ring[entry].addr)),
                                           pkt_len);
-#else
-                               memcpy(skb->data, bus_to_virt(vp->rx_ring[entry].addr), pkt_len);
-                               skb->len = pkt_len;
-#endif
                                rx_copy++;
-                       } else{
+                       } else {
                                void *temp;
                                /* Pass up the skbuff already on the Rx ring. */
                                skb = vp->rx_skbuff[entry];
-                               if (skb == NULL) {
-                                       printk(KERN_WARNING "%s: in boomerang_rx -- attempt to use NULL skb caught\n", dev->name);
-                                       break;
-                               }
                                vp->rx_skbuff[entry] = NULL;
-#if LINUX_VERSION_CODE >= 0x10300
                                temp = skb_put(skb, pkt_len);
-#else
-                               temp = skb->data;
-#endif
                                /* Remove this checking code for final release. */
-                               if (bus_to_virt(vp->rx_ring[entry].addr) != temp)
+                               if (bus_to_virt(le32_to_cpu(vp->rx_ring[entry].addr)) != temp)
                                        printk(KERN_ERR "%s: Warning -- the skbuff addresses do not match"
                                                   " in boomerang_rx: %p vs. %p.\n", dev->name,
-                                                  bus_to_virt(vp->rx_ring[entry].addr), temp);
+                                                  bus_to_virt(le32_to_cpu(vp->rx_ring[entry].addr)),
+                                                  temp);
                                rx_nocopy++;
                        }
-#if LINUX_VERSION_CODE > 0x10300
                        skb->protocol = eth_type_trans(skb, dev);
                        {                                       /* Use hardware checksum info. */
                                int csum_bits = rx_status & 0xee000000;
@@ -1839,9 +1824,6 @@ boomerang_rx(struct device *dev)
                                        rx_csumhits++;
                                }
                        }
-#else
-                       skb->len = pkt_len;
-#endif
                        netif_rx(skb);
                        dev->last_rx = jiffies;
                        vp->stats.rx_packets++;
@@ -1853,29 +1835,17 @@ boomerang_rx(struct device *dev)
                struct sk_buff *skb;
                entry = vp->dirty_rx % RX_RING_SIZE;
                if (vp->rx_skbuff[entry] == NULL) {
-                       skb = DEV_ALLOC_SKB(PKT_BUF_SZ);
-                       if (skb == NULL) {
-                               printk(KERN_DEBUG "%s: in boomerang_rx -- could not allocate skbuff\n", dev->name);
+                       skb = dev_alloc_skb(PKT_BUF_SZ);
+                       if (skb == NULL)
                                break;                  /* Bad news!  */
-                       }
                        skb->dev = dev;                 /* Mark as being used by this device. */
-#if LINUX_VERSION_CODE > 0x10300
                        skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
-                       vp->rx_ring[entry].addr = virt_to_bus(skb->tail);
-#else
-                       vp->rx_ring[entry].addr = virt_to_bus(skb->data);
-#endif
+                       vp->rx_ring[entry].addr = cpu_to_le32(virt_to_bus(skb->tail));
                        vp->rx_skbuff[entry] = skb;
                }
                vp->rx_ring[entry].status = 0;  /* Clear complete bit. */
                outw(UpUnstall, ioaddr + EL3_CMD);
        }
-
-       if (vp->dirty_rx >= RX_RING_SIZE ) {
-               vp->cur_rx -= RX_RING_SIZE;
-               vp->dirty_rx -= RX_RING_SIZE;
-       }
-
        return 0;
 }
 
@@ -1883,7 +1853,7 @@ static int
 vortex_close(struct device *dev)
 {
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
-       int ioaddr = dev->base_addr;
+       long ioaddr = dev->base_addr;
        int i;
 
        dev->start = 0;
@@ -1910,12 +1880,7 @@ vortex_close(struct device *dev)
                /* Turn off thinnet power.  Green! */
                outw(StopCoax, ioaddr + EL3_CMD);
 
-#ifdef SA_SHIRQ
        free_irq(dev->irq, dev);
-#else
-       free_irq(dev->irq);
-       irq2dev_map[dev->irq] = 0;
-#endif
 
        outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
 
@@ -1945,8 +1910,7 @@ vortex_close(struct device *dev)
        return 0;
 }
 
-static struct enet_statistics *
-vortex_get_stats(struct device *dev)
+static struct net_device_stats *vortex_get_stats(struct device *dev)
 {
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
        unsigned long flags;
@@ -1967,7 +1931,7 @@ vortex_get_stats(struct device *dev)
        table.  This is done by checking that the ASM (!) code generated uses
        atomic updates with '+='.
        */
-static void update_stats(int ioaddr, struct device *dev)
+static void update_stats(long ioaddr, struct device *dev)
 {
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
 
@@ -1998,20 +1962,14 @@ static void update_stats(int ioaddr, struct device *dev)
        return;
 }
 
-#ifdef HAVE_PRIVATE_IOCTL
 static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd)
 {
        struct vortex_private *vp = (struct vortex_private *)dev->priv;
-       int ioaddr = dev->base_addr;
+       long ioaddr = dev->base_addr;
        u16 *data = (u16 *)&rq->ifr_data;
        int phy = vp->phys[0] & 0x1f;
 
-       if (vortex_debug > 2)
-               printk(KERN_DEBUG "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
-                          dev->name, rq->ifr_ifrn.ifrn_name, cmd,
-                          data[0], data[1], data[2], data[3]);
-
-    switch(cmd) {
+       switch(cmd) {
        case SIOCDEVPRIVATE:            /* Get the address of the PHY in use. */
                data[0] = phy;
        case SIOCDEVPRIVATE+1:          /* Read the specified MII register. */
@@ -2021,22 +1979,20 @@ static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        case SIOCDEVPRIVATE+2:          /* Write the specified MII register */
                if (!suser())
                        return -EPERM;
+               EL3WINDOW(4);
                mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]);
                return 0;
        default:
                return -EOPNOTSUPP;
        }
 }
-#endif  /* HAVE_PRIVATE_IOCTL */
 
-/* This new version of set_rx_mode() supports v1.4 kernels.
-   The Vortex chip has no documented multicast filter, so the only
+/* Pre-Cyclone chips have no documented multicast filter, so the only
    multicast setting is to receive all multicast frames.  At least
    the chip has a very clean way to set the mode, unlike many others. */
-static void
-set_rx_mode(struct device *dev)
+static void set_rx_mode(struct device *dev)
 {
-       int ioaddr = dev->base_addr;
+       long ioaddr = dev->base_addr;
        int new_mode;
 
        if (dev->flags & IFF_PROMISC) {
@@ -2050,14 +2006,6 @@ set_rx_mode(struct device *dev)
 
        outw(new_mode, ioaddr + EL3_CMD);
 }
-#ifndef NEW_MULTICAST
-/* The old interface to set the Rx mode. */
-static void
-set_multicast_list(struct device *dev, int num_addrs, void *addrs)
-{
-       set_rx_mode(dev);
-}
-#endif
 
 \f
 /* MII transceiver control section.
@@ -2068,7 +2016,7 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs)
 /* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
    met by back-to-back PCI I/O cycles, but we insert a delay to avoid
    "overclocking" issues. */
-#define mdio_delay() udelay(1)
+#define mdio_delay() inl(mdio_addr)
 
 #define MDIO_SHIFT_CLK 0x01
 #define MDIO_DIR_WRITE 0x04
@@ -2079,11 +2027,11 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs)
 
 /* Generate the preamble required for initial synchronization and
    a few older transceivers. */
-static void mdio_sync(int ioaddr, int bits)
+static void mdio_sync(long ioaddr, int bits)
 {
-       int mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+       long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 
-       /* Establish sync by sending at least 32 logic ones. */ 
+       /* Establish sync by sending at least 32 logic ones. */
        while (-- bits >= 0) {
                outw(MDIO_DATA_WRITE1, mdio_addr);
                mdio_delay();
@@ -2092,12 +2040,12 @@ static void mdio_sync(int ioaddr, int bits)
        }
 }
 
-static int mdio_read(int ioaddr, int phy_id, int location)
+static int mdio_read(long ioaddr, int phy_id, int location)
 {
        int i;
        int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
        unsigned int retval = 0;
-       int mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+       long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 
        if (mii_preamble_required)
                mdio_sync(ioaddr, 32);
@@ -2118,13 +2066,17 @@ static int mdio_read(int ioaddr, int phy_id, int location)
                outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
                mdio_delay();
        }
-       return retval>>1 & 0xffff;
+#if 0
+       return (retval>>1) & 0x1ffff;
+#else
+       return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
+#endif
 }
 
-static void mdio_write(int ioaddr, int phy_id, int location, int value)
+static void mdio_write(long ioaddr, int phy_id, int location, int value)
 {
        int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
-       int mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+       long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
        int i;
 
        if (mii_preamble_required)
@@ -2151,8 +2103,7 @@ static void mdio_write(int ioaddr, int phy_id, int location, int value)
 
 \f
 #ifdef MODULE
-void
-cleanup_module(void)
+void cleanup_module(void)
 {
        struct device *next_dev;
 
@@ -2162,11 +2113,14 @@ cleanup_module(void)
 
        /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
        while (root_vortex_dev) {
-               next_dev = ((struct vortex_private *)root_vortex_dev->priv)->next_module;
+               struct vortex_private *vp=(void *)(root_vortex_dev->priv);
+               next_dev = vp->next_module;
                unregister_netdev(root_vortex_dev);
                outw(TotalReset, root_vortex_dev->base_addr + EL3_CMD);
-               release_region(root_vortex_dev->base_addr, VORTEX_TOTAL_SIZE);
+               release_region(root_vortex_dev->base_addr,
+                                          pci_tbl[vp->chip_id].io_size);
                kfree(root_vortex_dev);
+               kfree(vp->priv_addr);
                root_vortex_dev = next_dev;
        }
 }
@@ -2177,7 +2131,7 @@ cleanup_module(void)
  * Local variables:
  *  compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c59x.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
  *  SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c59x.c"
- *  compile-command-alt1: "gcc -DCARDBUS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c59x.c -o 3c59x_cb.o"
+ *  cardbus-compile-command: "gcc -DCARDBUS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c59x.c -o 3c575_cb.o -I/usr/src/pcmcia-cs-3.0.5/include/"
  *  c-indent-level: 4
  *  c-basic-offset: 4
  *  tab-width: 4
index 6a9c0990c004a414ded3c81d04823820b762a9c7..cd3ab6bd6a369b607af98d55f07f96018e212e04 100644 (file)
@@ -67,7 +67,7 @@ static const char *version = "82596.c:v1.0 15/07/98\n";
 #endif
 
 /*
- * Define various macros for Channel Attention, word swapping etc., dependant
+ * Define various macros for Channel Attention, word swapping etc., dependent
  * on architecture.  MVME and BVME are 680x0 based, otherwise it is Intel.
  */
 
index 54045db1eb27669e959949143a97e6191f91ea8d..064edb07f598694597ff598fa2ff62112321cb37 100644 (file)
@@ -1107,6 +1107,12 @@ static void NS8390_trigger_send(struct device *dev, unsigned int length,
 
 #ifdef MODULE
 
+EXPORT_SYMBOL(ei_open);
+EXPORT_SYMBOL(ei_close);
+EXPORT_SYMBOL(ei_interrupt);
+EXPORT_SYMBOL(ethdev_init);
+EXPORT_SYMBOL(NS8390_init);
+
 struct module *NS8390_module = NULL;
 
 int init_module(void)
index 73f6f30feb9a59e5f1a4419b651739e0ff2562fa..39b8fdc6b08cfe1acafcbc79d49fbb3cef91ac27 100644 (file)
@@ -826,7 +826,7 @@ ifdef CONFIG_8390_BUILTIN
 L_OBJS += 8390.o
 else
   ifdef CONFIG_8390_MODULE
-  M_OBJS += 8390.o
+  MX_OBJS += 8390.o
   endif
 endif
 
index 385bfec8f7620eaea2af410f2d2f2aa4cdf10ad5..5ad1ea8d890abca039b25847948940eea1aab2fd 100644 (file)
@@ -7,6 +7,11 @@
  * Thanks to Alteon and 3Com for providing hardware and documentation
  * enabling me to write this driver.
  *
+ * A mailing list for discussing the use of this driver has been
+ * setup, please subscribe to the lists if you have any questions
+ * about the driver. Send mail to linux-acenic-help@sunsite.auc.dk to
+ * see how to subscribe.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * firmware. Also the programming interface is quite neat, except for
  * the parts dealing with the i2c eeprom on the card ;-)
  *
- * A number of standard Ethernet receive skb's are now allocated at
- * init time and not released before the driver is unloaded. This
- * makes it possible to do ifconfig down/up.
- *
  * Using jumbo frames:
  *
  * To enable jumbo frames, simply specify an mtu between 1500 and 9000
@@ -132,7 +133,7 @@ static int rx_coal_tick[8] = {0, };
 static int max_tx_desc[8] = {0, };
 static int max_rx_desc[8] = {0, };
 
-static const char *version = "acenic.c: v0.19 12/17/98  Jes Sorensen (Jes.Sorensen@cern.ch)\n";
+static const char *version = "acenic.c: v0.22 01/07/99  Jes Sorensen (Jes.Sorensen@cern.ch)\n";
 
 static struct device *root_dev = NULL;
 
@@ -143,37 +144,28 @@ __initfunc(int acenic_probe (struct device *dev))
        static int i = 0;
        int boards_found = 0;
        int version_disp;
-       u32 tmp;
        struct ace_private *ap;
+       u8 pci_latency;
+#if 0
        u16 vendor, device;
        u8 pci_bus;
        u8 pci_dev_fun;
-       u8 pci_latency;
        u8 irq;
+#endif
+       struct pci_dev *pdev = NULL;
 
        if (!pci_present())             /* is PCI support present? */
                return -ENODEV;
 
        version_disp = 0;
 
-       for (; i < 255; i++)
+       while((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev)))
        {
                dev = NULL;
 
-               if (pcibios_find_class(PCI_CLASS_NETWORK_ETHERNET << 8,
-                                      i, &pci_bus, &pci_dev_fun) !=
-                   PCIBIOS_SUCCESSFUL)
-                       break;
-
-               pcibios_read_config_word(pci_bus, pci_dev_fun,
-                                        PCI_VENDOR_ID, &vendor);
-
-               pcibios_read_config_word(pci_bus, pci_dev_fun,
-                                        PCI_DEVICE_ID, &device);
-
-               if ((vendor != PCI_VENDOR_ID_ALTEON) &&
-                   !((vendor == PCI_VENDOR_ID_3COM) &&
-                     (device == PCI_DEVICE_ID_3COM_3C985)))
+               if ((pdev->vendor != PCI_VENDOR_ID_ALTEON) &&
+                   !((pdev->vendor == PCI_VENDOR_ID_3COM) &&
+                     (pdev->device == PCI_DEVICE_ID_3COM_3C985)))
                        continue;
 
                dev = init_etherdev(dev, sizeof(struct ace_private));
@@ -188,37 +180,12 @@ __initfunc(int acenic_probe (struct device *dev))
                        dev->priv = kmalloc(sizeof(*ap), GFP_KERNEL);
 
                ap = dev->priv;
-               ap->vendor = vendor;
-
-               /* Read register base address from
-                  PCI Configuration Space */
+               ap->pdev = pdev;
+               ap->vendor = pdev->vendor;
 
-               pcibios_read_config_dword(pci_bus, pci_dev_fun,
-                                         PCI_BASE_ADDRESS_0, &tmp);
+               pci_set_master(pdev);
 
-               pcibios_read_config_byte(pci_bus, pci_dev_fun,
-                                        PCI_INTERRUPT_LINE, &irq);
-
-               pcibios_read_config_word(pci_bus, pci_dev_fun,
-                                        PCI_COMMAND, &ap->pci_command);
-
-               if (!(ap->pci_command & PCI_COMMAND_MASTER)){
-                       ap->pci_command |= PCI_COMMAND_MASTER;
-
-                       pcibios_write_config_word(pci_bus, pci_dev_fun,
-                                                 PCI_COMMAND,
-                                                 ap->pci_command);
-               }
-
-               if (!(ap->pci_command & PCI_COMMAND_MEMORY)){
-                       printk(KERN_ERR "Shared mem not enabled - "
-                              "unable to configure AceNIC\n");
-                       break;
-               }
-
-               dev->irq = irq;
-               ap->pci_bus = pci_bus;
-               ap->pci_dev_fun = pci_dev_fun;
+               dev->irq = pdev->irq;
 #ifdef __SMP__
                spin_lock_init(&ap->lock);
 #endif
@@ -245,13 +212,13 @@ __initfunc(int acenic_probe (struct device *dev))
                        printk(version);
                }
 
-               pcibios_read_config_byte(pci_bus, pci_dev_fun,
-                                        PCI_LATENCY_TIMER, &pci_latency);
+               pci_read_config_word(pdev, PCI_COMMAND, &ap->pci_command);
+
+               pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
                if (pci_latency <= 0x40){
                        pci_latency = 0x40;
-                       pcibios_write_config_byte(pci_bus, pci_dev_fun,
-                                                 PCI_LATENCY_TIMER,
-                                                 pci_latency);
+                       pci_write_config_byte(pdev, PCI_LATENCY_TIMER,
+                                             pci_latency);
                }
 
                switch(ap->vendor){
@@ -268,14 +235,15 @@ __initfunc(int acenic_probe (struct device *dev))
                        printk(KERN_INFO "%s: Unknown AceNIC ", dev->name);
                        break;
                }
-               printk("Gigabit Ethernet at 0x%08x, irq %i, PCI latency %i "
-                      "clks\n", tmp, dev->irq, pci_latency);
+               printk("Gigabit Ethernet at 0x%08lx, irq %i, PCI latency %i "
+                      "clks\n", pdev->base_address[0], dev->irq, pci_latency);
 
                /*
                 * Remap the regs into kernel space.
                 */
 
-               ap->regs = (struct ace_regs *)ioremap(tmp, 0x4000);
+               ap->regs = (struct ace_regs *)ioremap(pdev->base_address[0],
+                                                     0x4000);
                if (!ap->regs){
                        printk(KERN_ERR "%s:  Unable to map I/O register, "
                               "AceNIC %i will be disabled.\n", dev->name, i);
@@ -404,7 +372,7 @@ __initfunc(static int ace_init(struct device *dev, int board_idx))
        struct ace_private *ap;
        struct ace_regs *regs;
        struct ace_info *info;
-       u32 tig_ver, mac1 = 0, mac2 = 0, tmp;
+       u32 tig_ver, mac1, mac2, tmp;
        unsigned long tmp_ptr, myjif;
        short i;
 
@@ -471,10 +439,12 @@ __initfunc(static int ace_init(struct device *dev, int board_idx))
                return -ENODEV;
        }
 
+       mac1 = 0;
        for(i = 0; i < 4; i++){
                mac1 = mac1 << 8;
                mac1 |= read_eeprom_byte(regs, 0x8c+i);
        }
+       mac2 = 0;
        for(i = 4; i < 8; i++){
                mac2 = mac2 << 8;
                mac2 |= read_eeprom_byte(regs, 0x8c+i);
@@ -527,10 +497,8 @@ __initfunc(static int ace_init(struct device *dev, int board_idx))
                                       "supported, PCI write and invalidate "
                                       "disabled\n", L1_CACHE_BYTES);
                                ap->pci_command &= ~PCI_COMMAND_INVALIDATE;
-                               pcibios_write_config_word(ap->pci_bus,
-                                                         ap->pci_dev_fun,
-                                                         PCI_COMMAND,
-                                                         ap->pci_command);
+                               pci_write_config_word(ap->pdev, PCI_COMMAND,
+                                                     ap->pci_command);
                        }
                }
        }
@@ -646,10 +614,6 @@ __initfunc(static int ace_init(struct device *dev, int board_idx))
 #if 0
 {
        u32 tmp;
-       tmp = regs->AssistState;
-       tmp &= ~2;
-       tmp |= 1;
-       regs->AssistState = tmp;
 
        tmp = regs->MacRxState;
        tmp &= ~4;
@@ -659,35 +623,43 @@ __initfunc(static int ace_init(struct device *dev, int board_idx))
 
        regs->TuneStatTicks = 2 * TICKS_PER_SEC;
 
-       if ((board_idx < 8) && tx_coal_tick[board_idx])
-               regs->TuneTxCoalTicks = tx_coal_tick[board_idx] *
-                       TICKS_PER_SEC / 1000;
-       else
+       if (board_idx >= 0) {
+               if ((board_idx < 8) && tx_coal_tick[board_idx])
+                       regs->TuneTxCoalTicks = tx_coal_tick[board_idx] *
+                               TICKS_PER_SEC / 1000;
+               else
+                       regs->TuneTxCoalTicks = TICKS_PER_SEC / 500;
+               if ((board_idx < 8) && max_tx_desc[board_idx])
+                       regs->TuneMaxTxDesc = max_tx_desc[board_idx];
+               else
+                       regs->TuneMaxTxDesc = 7;
+
+               if ((board_idx < 8) && rx_coal_tick[board_idx])
+                       regs->TuneRxCoalTicks = rx_coal_tick[board_idx] *
+                               TICKS_PER_SEC / 1000;
+               else
+                       regs->TuneRxCoalTicks = TICKS_PER_SEC / 10000;
+               if ((board_idx < 8) && max_rx_desc[board_idx])
+                       regs->TuneMaxRxDesc = max_rx_desc[board_idx];
+               else
+                       regs->TuneMaxRxDesc = 2;
+
+               if (board_idx < 8)
+                       regs->TuneTrace = trace[board_idx];
+               else
+                       regs->TuneTrace = 0;
+       }else{
                regs->TuneTxCoalTicks = TICKS_PER_SEC / 500;
-       if ((board_idx < 8) && max_tx_desc[board_idx])
-               regs->TuneMaxTxDesc = max_tx_desc[board_idx];
-       else
                regs->TuneMaxTxDesc = 7;
-
-       if ((board_idx < 8) && rx_coal_tick[board_idx])
-               regs->TuneRxCoalTicks = rx_coal_tick[board_idx] *
-                       TICKS_PER_SEC / 1000;
-       else
                regs->TuneRxCoalTicks = TICKS_PER_SEC / 10000;
-       if ((board_idx < 8) && max_rx_desc[board_idx])
-               regs->TuneMaxRxDesc = max_rx_desc[board_idx];
-       else
                regs->TuneMaxRxDesc = 2;
-
-       if (board_idx < 8)
-               regs->TuneTrace = trace[board_idx];
-       else
                regs->TuneTrace = 0;
+       }
 
        tmp = LNK_ENABLE;
 
-       if ((board_idx > 7) || !(link[board_idx])){
-               if (board_idx > 8)
+       if ((board_idx > 7) || (board_idx < 0) || !(link[board_idx])){
+               if (board_idx > 7)
                        printk(KERN_WARNING "%s: more then 8 NICs detected, "
                               "ignoring link options!\n", dev->name);
                /*
@@ -700,6 +672,7 @@ __initfunc(static int ace_init(struct device *dev, int board_idx))
                        tmp |= LNK_TX_FLOW_CTL_Y;
        } else {
                int option = link[board_idx];
+
                if (option & 0x01){
                        printk(KERN_INFO "%s: Setting half duplex link\n",
                               dev->name);
@@ -756,7 +729,7 @@ __initfunc(static int ace_init(struct device *dev, int board_idx))
        myjif = jiffies + 3 * HZ;
        while (time_before(jiffies, myjif) && !ap->fw_running);
        if (!ap->fw_running){
-               printk(KERN_ERR "%s: firmware NOT running!\n", dev->name);
+               printk(KERN_ERR "%s: Firmware NOT running!\n", dev->name);
                ace_dump_trace(ap);
                regs->CpuCtrl |= CPU_HALT;
                return -EBUSY;
@@ -1501,11 +1474,14 @@ static struct net_device_stats *ace_get_stats(struct device *dev)
 }
 
 
-__initfunc(int ace_copy(struct ace_regs *regs, void *src, u32 dest, int size))
+__initfunc(void ace_copy(struct ace_regs *regs, void *src, u32 dest, int size))
 {
        int tsize;
        u32 tdest;
 
+       if (size <= 0)
+               return;
+
        while(size > 0){
                tsize = min(((~dest & (ACE_WINDOW_SIZE - 1)) + 1),
                            min(size, ACE_WINDOW_SIZE));
@@ -1524,15 +1500,18 @@ __initfunc(int ace_copy(struct ace_regs *regs, void *src, u32 dest, int size))
                size -= tsize;
        }
 
-       return 0;
+       return;
 }
 
 
-__initfunc(int ace_clear(struct ace_regs *regs, u32 dest, int size))
+__initfunc(void ace_clear(struct ace_regs *regs, u32 dest, int size))
 {
-       int tsize;
+       int tsize = 0;
        u32 tdest;
 
+       if (size <= 0)
+               return;
+
        while(size > 0){
                tsize = min(((~dest & (ACE_WINDOW_SIZE - 1)) + 1),
                            min(size, ACE_WINDOW_SIZE));
@@ -1545,7 +1524,7 @@ __initfunc(int ace_clear(struct ace_regs *regs, u32 dest, int size))
                size -= tsize;
        }
 
-       return 0;
+       return;
 }
 
 
index bcd5b21fa6a1a0294be42b9489e763e4f5bf8c33..deca3e8959f0c585a06380521580c602450bac02 100644 (file)
@@ -581,8 +581,11 @@ struct ace_private
        int                     flags;
        u16                     vendor;
        u16                     pci_command;
+       struct pci_dev          *pdev;
+#if 0
        u8                      pci_bus;
        u8                      pci_dev_fun;
+#endif
        char                    name[24];
        struct net_device_stats stats;
 };
index b35d3219334b83d92d26cb8274778532aa9f07a3..7e2472c51e74b6c8f00c4a9523c9d72d5ebc0c7d 100644 (file)
@@ -2799,7 +2799,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
 0x3c010001, 0x220821, 0xac317120, 0x8fbf0024, 0x8fb40020, 0x8fb3001c, 
 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0028, 0x0, 
 0x0 };
-u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __init = {
+u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __initdata = {
 0x416c7465, 0x6f6e2041, 0x63654e49, 0x43205600, 0x416c7465, 0x6f6e2041, 
 0x63654e49, 0x43205600, 0x42424242, 0x0, 0x0, 0x0, 
 0x135430, 0x13e7fc, 0x0, 0x0, 0x0, 0x0, 
@@ -2814,7 +2814,7 @@ u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __init = {
 0x12000060, 0x12000180, 0x120001e0, 0x0, 0x0, 0x0, 
 0x0, 0x0, 0x0, 0x0, 0x30001, 0x1, 
 0x30201, 0x0, 0x0 };
-u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __init = {
+u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = {
 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 
 0x772f6765, 0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f66, 0x776d6169, 
 0x6e2e632c, 0x7620312e, 0x312e322e, 0x31312031, 0x3939382f, 0x30342f32, 
@@ -2939,7 +2939,7 @@ u32 tigon2FwBssAddr = 0x13550;
 int tigon2FwBssLen = 0x20c0;
 u32 tigon2FwSbssAddr = 0x134a0;
 int tigon2FwSbssLen = 0xa8;
-u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __init = {
+u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
 0x0, 0x10000003, 0x0, 0xd, 0xd, 0x3c1d0001, 
 0x8fbd3380, 0x3a0f021, 0x3c100000, 0x26104000, 0xc0010c0, 0x0, 
 0xd, 0x3c1d0001, 0x8fbd3384, 0x3a0f021, 0x3c100000, 0x26104000, 
@@ -5391,7 +5391,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __init = {
 0xaf820044, 0x8f820044, 0x451024, 0xaf820044, 0x24630001, 0x28620008, 
 0x5440ffee, 0x641007, 0x3e00008, 0x0, 0x0, 0x0, 
 0x0 };
-u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] __init = {
+u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] __initdata = {
 0x1, 0x1, 0x1, 0xc001fc, 0x3ffc, 0xc00000, 
 0x416c7465, 0x6f6e2041, 0x63654e49, 0x43205600, 0x0, 0x0, 
 0x416c7465, 0x6f6e2041, 0x63654e49, 0x43205600, 0x42424242, 0x0, 
@@ -5408,7 +5408,7 @@ u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] __init = {
 0x12000060, 0x12000180, 0x120001e0, 0x0, 0x0, 0x0, 
 0x0, 0x0, 0x0, 0x0, 0x30001, 0x1, 
 0x30201, 0x0, 0x0 };
-u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __init = {
+u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = {
 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 
 0x772f6765, 0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, 0x66776d61, 
 0x696e2e63, 0x2c762031, 0x2e312e34, 0x372e3420, 0x31393938, 0x2f31302f, 
index f73d491e1c6fa33674d4af9319f14178bedb75c7..c58a9093266874972e0fc0a58456981e9db4890c 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/amigaints.h>
+#include <asm/amigahw.h>
 
 #include "8390.h"
 
@@ -417,7 +418,7 @@ void cleanup_module(void)
     unsigned int key = ((struct ei_device *)ariadne2_dev.priv)->priv;
     free_irq(IRQ_AMIGA_PORTS, &ariadne2_dev);
     unregister_netdev(&ariadne2_dev);
-    zorro_config_board(key, 0);
+    zorro_unconfig_board(key, 0);
     unlock_8390_module();
 }
 
index 77641a0f46d0f8d58622d93943e5bb88f179049a..47770e4e7b7107d4b0e0b1a9f8e567fec9ba51b3 100644 (file)
@@ -838,10 +838,12 @@ cleanup_module(void)
 {
        struct net_local *lp = dev_at1700.priv;
        unregister_netdev(&dev_at1700);
+#ifdef CONFIG_MCA      
        if(lp->mca_slot)
        {
                mca_mark_as_unused(lp->mca_slot);
        }
+#endif 
        kfree(dev_at1700.priv);
        dev_at1700.priv = NULL;
 
index a064bc12b9f33c6fa0a7653b9f53032acad064ef..69721566f943f5682d756c1a35e7fb371fb140fa 100644 (file)
@@ -34,7 +34,7 @@
 /* Same on both card types */
 #define COPS_CLEAR_INT  1
 
-/* LAP response codes recieved from the cards. */
+/* LAP response codes received from the cards. */
 #define LAP_INIT        1       /* Init cmd */
 #define LAP_INIT_RSP    2       /* Init response */
 #define LAP_WRITE       3       /* Write cmd */
index 614efe746ad3aa62a39d7c81fb25ae78bdee50ad..b1c83b5b980a61e7e01edc8ed9aea56a9f5cb46d 100644 (file)
@@ -393,7 +393,7 @@ typedef volatile struct
        /* cmd halfword values */
 #define        I596_SCB_ACK            0xF000  /* ACKNOWLEDGMENTS */
 #define        I596_SCB_ACK_CX         0x8000  /* Ack command completion */
-#define        I596_SCB_ACK_FR         0x4000  /* Ack recieved frame */
+#define        I596_SCB_ACK_FR         0x4000  /* Ack received frame */
 #define        I596_SCB_ACK_CNA        0x2000  /* Ack command unit not active */
 #define        I596_SCB_ACK_RNR        0x1000  /* Ack rcv unit not ready */
 #define        I596_SCB_ACK_ALL        0xF000  /* Ack everything */
@@ -419,7 +419,7 @@ typedef volatile struct
        /* status halfword values */
 #define        I596_SCB_STAT           0xF000  /* STATUS */
 #define        I596_SCB_CX             0x8000  /* command completion */
-#define        I596_SCB_FR             0x4000  /* recieved frame */
+#define        I596_SCB_FR             0x4000  /* received frame */
 #define        I596_SCB_CNA            0x2000  /* command unit not active */
 #define        I596_SCB_RNR            0x1000  /* rcv unit not ready */
 
index edb80ac1ea63abe9d5c5c7d10a3dd51ade8ff5c5..08a9a17ace6b30cf6532500454938e46f27809ce 100644 (file)
        This is a compatibility hardware problem.
 
        Versions:
-       0.11b   Pascal Dupuis : works as a module under 2.1.xx
-               debug messages are flagged as KERN_DEBUG to avoid console 
-               flooding 
-               added locking at critical parts
+       0.11d   added __initdata, __initfunc stuff; call spin_lock_init
+               in eepro_probe1. Replaced "eepro" by dev->name. Augmented 
+               the code protected by spin_lock in interrupt routine 
+               (PdP, 12/12/1998)
+       0.11c   minor cleanup (PdP, RMC, 09/12/1998)  
+       0.11b   Pascal Dupuis (dupuis@lei.ucl.ac.be): works as a module 
+               under 2.1.xx. Debug messages are flagged as KERN_DEBUG to 
+               avoid console flooding. Added locking at critical parts. Now 
+               the dawn thing is SMP safe.
        0.11a   Attempt to get 2.1.xx support up (RMC)
        0.11    Brian Candler added support for multiple cards. Tested as
                a module, no idea if it works when compiled into kernel.
@@ -87,7 +92,7 @@
 */
 
 static const char *version =
-       "eepro.c: v0.11b 08/12/1998 dupuis@lei.ucl.ac.be\n";
+       "eepro.c: v0.11d 08/12/1998 dupuis@lei.ucl.ac.be\n";
 
 #include <linux/module.h>
 
@@ -127,9 +132,6 @@ static const char *version =
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
-#include <asm/spinlock.h>
-#endif
 #include <linux/errno.h>
 
 #include <linux/netdevice.h>
@@ -147,6 +149,7 @@ static const char *version =
 /* For linux 2.1.xx */
 #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
 
+#include <asm/spinlock.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 
@@ -154,6 +157,8 @@ static const char *version =
 /* I had reports of looong delays with SLOW_DOWN defined as udelay(2) */
 #define SLOW_DOWN inb(0x80)
 /* udelay(2) */
+#define compat_init_func(X)  __initfunc(X)
+#define compat_init_data     __initdata
 
 #else 
 /* for 2.x */
@@ -161,13 +166,15 @@ static const char *version =
 #define compat_dev_kfree_skb( skb, mode ) dev_kfree_skb( (skb), (mode) )
 #define test_and_set_bit(a,b) set_bit((a),(b))
 #define SLOW_DOWN SLOW_DOWN_IO
+#define compat_init_func(X) X
+#define compat_init_data
 
 #endif
 
 
 /* First, a few definitions that the brave might change. */
 /* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int eepro_portlist[] =
+static unsigned int eepro_portlist[] compat_init_data =
    { 0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0};
 /* note: 0x300 is default, the 595FX supports ALL IO Ports 
   from 0x000 to 0x3F0, some of which are reserved in PCs */
@@ -205,7 +212,7 @@ struct eepro_local {
                                   version of the 82595 chip. */
        int stepping;
 #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
-        spinlock_t lock; /* to prevent interrupt within interrupts */ 
+       spinlock_t lock; /* Serializing lock  */ 
 #endif
 };
 
@@ -313,7 +320,7 @@ static void hardware_send_packet(struct device *dev, void *buf, short length);
 static int     eepro_grab_irq(struct device *dev);
 
 /*
-                       Details of the i82595.
+                       Details of the i82595.
 
 You will need either the datasheet or the user manual to understand what
 is going on here.  The 82595 is very different from the 82586, 82593.
@@ -344,7 +351,7 @@ buffer (transmit-buffer = 32K - receive-buffer).
 */
 #define        RAM_SIZE        0x8000
 #define        RCV_HEADER      8
-#define RCV_RAM         0x6000  /* 24KB default for RCV buffer */
+#define RCV_RAM        0x6000  /* 24KB default for RCV buffer */
 #define RCV_LOWER_LIMIT 0x00    /* 0x0000 */
 /* #define RCV_UPPER_LIMIT ((RCV_RAM - 2) >> 8) */    /* 0x5ffe */
 #define RCV_UPPER_LIMIT (((rcv_ram) - 2) >> 8)   
@@ -454,8 +461,7 @@ buffer (transmit-buffer = 32K - receive-buffer).
 struct netdev_entry netcard_drv =
 {"eepro", eepro_probe1, EEPRO_IO_EXTENT, eepro_portlist};
 #else
-int
-eepro_probe(struct device *dev)
+compat_init_func(int eepro_probe(struct device *dev))
 {
        int i;
        int base_addr = dev ? dev->base_addr : 0;
@@ -467,9 +473,9 @@ eepro_probe(struct device *dev)
        /* Wakeup: */
        #define WakeupPort 0x279
        #define WakeupSeq    {0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE,\
-                              0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61,\
-                              0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1,\
-                              0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x43}
+                             0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61,\
+                             0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1,\
+                             0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x43}
 
        {
                unsigned short int WS[32]=WakeupSeq;
@@ -485,19 +491,21 @@ eepro_probe(struct device *dev)
                                outb_p(WS[i],WakeupPort);
                                if (net_debug>5) printk(KERN_DEBUG ": %#x ",WS[i]);
                        }
-               } else printk("Checkregion Failed!\n");
+               } else printk(KERN_WARNING "Checkregion Failed!\n");
        }
 #endif
 
 
        if (base_addr > 0x1ff)          /* Check a single specified location. */
                return eepro_probe1(dev, base_addr);
+
        else if (base_addr != 0)        /* Don't probe at all. */
                return ENXIO;
 
 
        for (i = 0; eepro_portlist[i]; i++) {
                int ioaddr = eepro_portlist[i];
+
                if (check_region(ioaddr, EEPRO_IO_EXTENT))
                        continue;
                if (eepro_probe1(dev, ioaddr) == 0)
@@ -512,11 +520,11 @@ void printEEPROMInfo(short ioaddr)
 {
        unsigned short Word;
        int i,j;
-  
+
        for (i=0, j=ee_Checksum; i<ee_SIZE; i++)
                j+=read_eeprom(ioaddr,i);
        printk("Checksum: %#x\n",j&0xffff);
-     
+
        Word=read_eeprom(ioaddr, 0);
        printk(KERN_DEBUG "Word0:\n");
        printk(KERN_DEBUG " Plug 'n Pray: %d\n",GetBit(Word,ee_PnP));
@@ -533,10 +541,10 @@ void printEEPROMInfo(short ioaddr)
                printk(KERN_DEBUG " TPE/AUI: %d\n", GetBit(Word,ee_TPE_AUI));
                printk(KERN_DEBUG " Jabber: %d\n", GetBit(Word,ee_Jabber));
                printk(KERN_DEBUG " AutoPort: %d\n", GetBit(!Word,ee_Jabber));
-               printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex));  
+               printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex));
        }
 
-  Word=read_eeprom(ioaddr, 5);
+       Word=read_eeprom(ioaddr, 5);
        printk(KERN_DEBUG "Word5:\n");
        printk(KERN_DEBUG " BNC: %d\n",GetBit(Word,ee_BNC_TPE));
        printk(KERN_DEBUG " NumConnectors: %d\n",GetBit(Word,ee_NumConn));
@@ -546,18 +554,19 @@ void printEEPROMInfo(short ioaddr)
        if (GetBit(Word,ee_PortAUI)) printk("AUI ");
        printk("port(s) \n");
 
-  Word=read_eeprom(ioaddr, 6);
+       Word=read_eeprom(ioaddr, 6);
        printk(KERN_DEBUG "Word6:\n");
        printk(KERN_DEBUG " Stepping: %d\n",Word & ee_StepMask);
        printk(KERN_DEBUG " BoardID: %d\n",Word>>ee_BoardID);
 
-  Word=read_eeprom(ioaddr, 7);
+       Word=read_eeprom(ioaddr, 7);
        printk(KERN_DEBUG "Word7:\n");
        printk(KERN_DEBUG " INT to IRQ:\n");
 
        printk(KERN_DEBUG);
-  for (i=0, j=0; i<15; i++)
-     if (GetBit(Word,i)) printk(" INT%d -> IRQ %d;",j++,i);
+
+       for (i=0, j=0; i<15; i++)
+               if (GetBit(Word,i)) printk(" INT%d -> IRQ %d;",j++,i);
 
        printk("\n");
 }
@@ -577,11 +586,10 @@ int eepro_probe1(struct device *dev, short ioaddr)
        /* Now, we are going to check for the signature of the
           ID_REG (register 2 of bank 0) */
 
-
- id=inb(ioaddr + ID_REG);
+       id=inb(ioaddr + ID_REG);
  
- printk(KERN_DEBUG " id: %#x ",id);
- printk(" io: %#x ",ioaddr);
      printk(KERN_DEBUG " id: %#x ",id);
      printk(" io: %#x ",ioaddr);
  
        if (((id) & ID_REG_MASK) == ID_REG_SIG) {
 
@@ -606,7 +614,7 @@ int eepro_probe1(struct device *dev, short ioaddr)
                        if (net_debug>3)
                                printEEPROMInfo(ioaddr);
                                
-                       if (read_eeprom(ioaddr,7)== ee_FX_INT2IRQ) { /* int to IRQ Mask */
+                       if (read_eeprom(ioaddr,7)== ee_FX_INT2IRQ) { /* int to IRQ Mask */
                                eepro = 2;
                                printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", 
                                        dev->name, ioaddr);
@@ -622,7 +630,7 @@ int eepro_probe1(struct device *dev, short ioaddr)
                                        dev->name, ioaddr);
                        }
 
-                       /* Fill in the 'dev' fields. */
+                       /* Fill in the 'dev' fields. */
                        dev->base_addr = ioaddr;
                        
                        for (i=0; i < 6; i++) {
@@ -641,24 +649,13 @@ int eepro_probe1(struct device *dev, short ioaddr)
                                printk(", %dK RCV buffer", (int)(dev->mem_end)/1024);
                                
                                
-//                     outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
-//                     id = inb(ioaddr + REG3);
-//                     if (id & TPE_BIT)
-//                             dev->if_port = TPE;
-//                     else dev->if_port = BNC;
-                       
-                       
                        /* ............... */
 
-                       if (GetBit(  read_eeprom(ioaddr, 5),ee_BNC_TPE))
+                       if (GetBit( read_eeprom(ioaddr, 5),ee_BNC_TPE))
                                dev->if_port = BNC;
                        else dev->if_port = TPE;
-                
-                       
-                       /* ............... */
 
-//                     if (net_debug>3) 
-//                             printk("id: %x\n", id);
+                       /* ............... */
 
 
                        if ((dev->irq < 2) && (eepro!=0)) {
@@ -668,14 +665,14 @@ int eepro_probe1(struct device *dev, short ioaddr)
                                
                                for (j=0; ((j<16) && (i>=0)); j++) {
                                        if ((irqMask & (1<<j))!=0) {
-                                               if (i==0) {
-                                                       dev->irq = j;
-                                                       break; /* found bit corresponding to irq */
-                                               }
+                                               if (i==0) {
+                                                       dev->irq = j;
+                                                       break; /* found bit corresponding to irq */
+                                               }
                                                i--; /* count bits set in irqMask */
-                                       }
-                               }
-                               if (dev -> irq<2) {
+                                       }
+                               }
+                               if (dev -> irq<2) {
                                        printk(" Duh! illegal interrupt vector stored in EEPROM.\n");
                                                return ENODEV;
                                } else 
@@ -685,14 +682,10 @@ int eepro_probe1(struct device *dev, short ioaddr)
                                else if (dev->irq == 2)
                                dev->irq = 9;
                        }
-
+                       
                        if (dev->irq > 2) {
                                printk(", IRQ %d, %s.\n", dev->irq,
                                                ifmap[dev->if_port]);
-                               /*if (request_irq(dev->irq, &eepro_interrupt, 0, "eepro", dev)) {
-                                       printk("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
-                                       return -EAGAIN;
-                               }*/
                        }
                        else printk(", %s.\n", ifmap[dev->if_port]);
                        
@@ -702,7 +695,7 @@ int eepro_probe1(struct device *dev, short ioaddr)
                        if (net_debug > 3) {
                                i = read_eeprom(ioaddr, 5);
                                if (i & 0x2000) /* bit 13 of EEPROM word 5 */
-                                 printk(KERN_DEBUG "%s: Concurrent Processing is enabled but not used!\n",
+                                       printk(KERN_DEBUG "%s: Concurrent Processing is enabled but not used!\n",
                                                dev->name);
                        }
 
@@ -710,7 +703,7 @@ int eepro_probe1(struct device *dev, short ioaddr)
                                printk(version);
 
                        /* Grab the region so we can find another board if autoIRQ fails. */
-                       request_region(ioaddr, EEPRO_IO_EXTENT, "eepro");
+                       request_region(ioaddr, EEPRO_IO_EXTENT, dev->name);
 
                        /* Initialize the device structure */
                        dev->priv = kmalloc(sizeof(struct eepro_local), GFP_KERNEL);
@@ -718,6 +711,9 @@ int eepro_probe1(struct device *dev, short ioaddr)
                                return -ENOMEM;
                        memset(dev->priv, 0, sizeof(struct eepro_local));
 
+#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
+                       spin_lock_init(&(((struct eepro_local *)dev->priv)->lock));
+#endif
                        dev->open               = eepro_open;
                        dev->stop               = eepro_close;
                        dev->hard_start_xmit    = eepro_send_packet;
@@ -754,11 +750,8 @@ static int eepro_grab_irq(struct device *dev)
 {
        int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12 };
        int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr;
-
-       outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
        
-       /* Set the spinlock before activating  IRQ! */
-       ((struct eepro_local *)dev->priv)->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
+       outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
 
        /* Enable the interrupt line. */
        temp_reg = inb(ioaddr + REG1);
@@ -768,6 +761,7 @@ static int  eepro_grab_irq(struct device *dev)
 
        /* clear all interrupts */
        outb(ALL_MASK, ioaddr + STATUS_REG);
+
        /* Let EXEC event to interrupt */
        outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG);
 
@@ -785,11 +779,8 @@ static int eepro_grab_irq(struct device *dev)
 
                        outb(DIAGNOSE_CMD, ioaddr); /* RESET the 82595 */
                                
-                       if (*irqp == autoirq_report(2) )//&&  /* It's a good IRQ line */
-                               /* We don't take irqs on detection anymore.
-                                       only when actually turning on the driver (ifconfig) */
-                               /* //(request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro", dev) == 0)) */
-                                       break;
+                       if (*irqp == autoirq_report(2))  /* It's a good IRQ line */
+                               break;
 
                        /* clear all interrupts */
                        outb(ALL_MASK, ioaddr + STATUS_REG); 
@@ -821,14 +812,14 @@ static int eepro_open(struct device *dev)
        struct eepro_local *lp = (struct eepro_local *)dev->priv;
 
        if (net_debug > 3)
-               printk(KERN_DEBUG "eepro: entering eepro_open routine.\n");
+               printk(KERN_DEBUG "%s: entering eepro_open routine.\n", dev->name);
 
        if ((irqMask=read_eeprom(ioaddr,7))== ee_FX_INT2IRQ) /* INT to IRQ Mask */
                {
-                       lp->eepro = 2; /* Yes, an Intel EtherExpress Pro/10+ */
-                       if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 2;\n"); 
+                       lp->eepro = 2; /* Yes, an Intel EtherExpress Pro/10+ */
+                       if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 2;\n"); 
                }
-       
+
        else if ((dev->dev_addr[0] == SA_ADDR0 &&
                        dev->dev_addr[1] == SA_ADDR1 &&
                        dev->dev_addr[2] == SA_ADDR2))
@@ -845,7 +836,7 @@ static int eepro_open(struct device *dev)
                return -EAGAIN;
        }
                
-       if (request_irq(dev->irq , &eepro_interrupt, 0, "eepro", dev)) {
+       if (request_irq(dev->irq , &eepro_interrupt, 0, dev->name, dev)) {
                printk("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
                return -EAGAIN;
        }
@@ -854,8 +845,8 @@ static int eepro_open(struct device *dev)
        if  (((irq2dev_map[dev->irq] != 0)
                || (irq2dev_map[dev->irq] = dev) == 0) && 
                (irq2dev_map[dev->irq]!=dev)) {
-           /* printk("%s: IRQ map wrong\n", dev->name); */
-               return -EAGAIN;
+               /* printk("%s: IRQ map wrong\n", dev->name); */
+               return -EAGAIN;
        }
 #endif
 
@@ -894,15 +885,14 @@ static int eepro_open(struct device *dev)
        else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG); 
 
 
-    temp_reg = inb(ioaddr + INT_NO_REG);
-    if (lp->eepro == 2)
-       outb((temp_reg & 0xf0) | irqrmap2[dev->irq] | 0x08,ioaddr+INT_NO_REG);
-    else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG);
+       temp_reg = inb(ioaddr + INT_NO_REG);
+       if (lp->eepro == 2)
+               outb((temp_reg & 0xf0) | irqrmap2[dev->irq] | 0x08,ioaddr+INT_NO_REG);
+       else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG);
+
+       if (net_debug > 3)
+               printk(KERN_DEBUG "eepro_open: content of INT Reg is %x\n", temp_reg);
 
-    if (net_debug > 3)
-       printk(KERN_DEBUG "eepro_open: content of INT Reg is %x\n", temp_reg);
-       
-       
 
        /* Initialize the RCV and XMT upper and lower limits */
        outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG); 
@@ -918,6 +908,7 @@ static int eepro_open(struct device *dev)
 
        /* Let RX and TX events to interrupt */
        outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
+
        /* clear all interrupts */
        outb(ALL_MASK, ioaddr + STATUS_REG); 
 
@@ -932,6 +923,7 @@ static int eepro_open(struct device *dev)
        /* Check for the i82595TX and i82595FX */
        old8 = inb(ioaddr + 8);
        outb(~old8, ioaddr + 8);
+
        if ((temp_reg = inb(ioaddr + 8)) == old8) {
                if (net_debug > 3)
                        printk(KERN_DEBUG "i82595 detected!\n");
@@ -965,25 +957,26 @@ static int eepro_open(struct device *dev)
                        }
                }
                else if (net_debug > 3) {
-                       printk(KERN_DEBUG "temp_reg: %#x  ~old9: %#x\n",temp_reg,((~old9)&0xff));
+                       printk(KERN_DEBUG "temp_reg: %#x  ~old9: %#x\n",temp_reg,((~old9)&0xff));
                        printk(KERN_DEBUG "i82595TX detected!\n");
                }
        }
        
        outb(SEL_RESET_CMD, ioaddr);
+
        /* We are supposed to wait for 2 us after a SEL_RESET */
        SLOW_DOWN;
        SLOW_DOWN;
 
        lp->tx_start = lp->tx_end = XMT_LOWER_LIMIT << 8; /* or = RCV_RAM */
-       lp->tx_last = 0;  
+       lp->tx_last = 0;
        
        dev->tbusy = 0;
        dev->interrupt = 0;
        dev->start = 1;
 
        if (net_debug > 3)
-               printk(KERN_DEBUG "eepro: exiting eepro_open routine.\n");
+               printk(KERN_DEBUG "%s: exiting eepro_open routine.\n", dev->name);
 
        outb(RCV_ENABLE_CMD, ioaddr);
 
@@ -997,39 +990,43 @@ static int eepro_send_packet(struct sk_buff *skb, struct device *dev)
        int ioaddr = dev->base_addr;
        int rcv_ram = dev->mem_end;
 
+#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
+       unsigned long flags;
+#endif
+       
        if (net_debug > 5)
-         printk(KERN_DEBUG  "eepro: entering eepro_send_packet routine.\n");
+               printk(KERN_DEBUG  "%s: entering eepro_send_packet routine.\n", dev->name);
        
        if (dev->tbusy) {
-         /* If we get here, some higher level has decided we are broken.
-            There should really be a "kick me" function call instead. */
-         int tickssofar = jiffies - dev->trans_start;
-         if (tickssofar < 40)
-           return 1;
-        
-         /* if (net_debug > 1) */
-         printk("%s: transmit timed out, %s?\n", dev->name, 
-                "network cable problem");
-         /* This is not a duplicate. One message for the console, one for the
-            the log file  */
-         printk(KERN_DEBUG "%s: transmit timed out, %s?\n", dev->name,
-                "network cable problem");
-         lp->stats.tx_errors++;
-
-         /* Try to restart the adaptor. */
-         outb(SEL_RESET_CMD, ioaddr); 
-         /* We are supposed to wait for 2 us after a SEL_RESET */
-         SLOW_DOWN;
-         SLOW_DOWN;
-         
-         /* Do I also need to flush the transmit buffers here? YES? */
-         lp->tx_start = lp->tx_end = rcv_ram; 
-         lp->tx_last = 0;
+               /* If we get here, some higher level has decided we are broken.
+                  There should really be a "kick me" function call instead. */
+               int tickssofar = jiffies - dev->trans_start;
+               if (tickssofar < 40)
+                       return 1;
+       
+               /* if (net_debug > 1) */
+               printk(KERN_ERR "%s: transmit timed out, %s?\n", dev->name, 
+                       "network cable problem");
+               /* This is not a duplicate. One message for the console, 
+                  one for the the log file  */
+               printk(KERN_DEBUG "%s: transmit timed out, %s?\n", dev->name,
+                       "network cable problem");
+               lp->stats.tx_errors++;
+
+               /* Try to restart the adaptor. */
+               outb(SEL_RESET_CMD, ioaddr); 
+               /* We are supposed to wait for 2 us after a SEL_RESET */
+               SLOW_DOWN;
+               SLOW_DOWN;
+
+               /* Do I also need to flush the transmit buffers here? YES? */
+               lp->tx_start = lp->tx_end = rcv_ram; 
+               lp->tx_last = 0;
        
-         dev->tbusy=0;
-         dev->trans_start = jiffies;
-         
-         outb(RCV_ENABLE_CMD, ioaddr);
+               dev->tbusy=0;
+               dev->trans_start = jiffies;
+
+               outb(RCV_ENABLE_CMD, ioaddr);
 
        }
 
@@ -1037,37 +1034,35 @@ static int eepro_send_packet(struct sk_buff *skb, struct device *dev)
        /* If some higher layer thinks we've missed an tx-done interrupt
           we are passed NULL. Caution: dev_tint() handles the cli()/sti()
           itself. */
-       //      if (skb == NULL) {
-       //      dev_tint(dev);
-       //      return 0;
-       // FIXME : what's this code for ?
-       }
+       /*      if (skb == NULL) {
+               dev_tint(dev);
+               return 0;
+       }*/
+       /* according to A. Cox, this is obsolete since 1.0 */
 #endif
 
-       /* Block a timer-based transmit from overlapping. */
-       if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
-         printk("%s: Transmitter access conflict.\n", dev->name);
-       else {
-          short length; unsigned char *buf;
 #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
-         unsigned long flags;
-
-         /* Spin on the lock, until we're clear of an IRQ */
-         spin_lock_irqsave(&lp->lock, flags);     
+       spin_lock_irqsave(&lp->lock, flags);
 #endif
-         length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-         buf = skb->data;
+
+       /* Block a timer-based transmit from overlapping. */
+       if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
+               printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
 
 #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
-         lp->stats.tx_bytes+=skb->len;
+               spin_unlock_irqrestore(&lp->lock, flags);
 #endif
-         hardware_send_packet(dev, buf, length);
-         
-         dev->trans_start = jiffies;
+       } else {
+               short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+               unsigned char *buf = skb->data;
 
 #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
-         spin_unlock_irqrestore(&lp->lock, flags);     
-#endif 
+               lp->stats.tx_bytes+=skb->len;
+#endif
+
+               hardware_send_packet(dev, buf, length);
+               dev->trans_start = jiffies;
+
        }
 
        compat_dev_kfree_skb (skb, FREE_WRITE);
@@ -1076,75 +1071,83 @@ static int eepro_send_packet(struct sk_buff *skb, struct device *dev)
        /* lp->stats.tx_aborted_errors++; */
 
        if (net_debug > 5)
-               printk(KERN_DEBUG "eepro: exiting eepro_send_packet routine.\n");
+               printk(KERN_DEBUG "%s: exiting eepro_send_packet routine.\n", dev->name);
+
+#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
+       spin_unlock_irqrestore(&lp->lock, flags);
+#endif
        
        return 0;
 }
 
+
 /*     The typical workload of the driver:
        Handle the network interface interrupts. */
+
 static void
 eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
        struct device *dev =  (struct device *)dev_id;
                              /* (struct device *)(irq2dev_map[irq]);*/
-#ifdef __SMP__
        struct eepro_local *lp = (struct eepro_local *)dev->priv;
-#endif 
        int ioaddr, status, boguscount = 20;
 
-       if (test_and_set_bit(0, (void*)&dev->interrupt)) 
-       {
-               printk(KERN_ERR"%s: SMP simultaneous entry of an interrupt handler.\n",
-                       dev->name);
-               dev->interrupt = 0; /* Avoid halting machine. */
-               return;
-       }
-
-       if (net_debug > 5)
-               printk(KERN_DEBUG "eepro: entering eepro_interrupt routine.\n");
-       
        if (dev == NULL) {
-               printk ("eepro_interrupt(): irq %d for unknown device.\n", irq);
+                printk (KERN_ERR "eepro_interrupt(): irq %d for unknown device.\\n", irq);
+                return;
+        }
+
+#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
+        spin_lock(&lp->lock);
+#endif
+
+       if (dev->interrupt) {
+               printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name);
+
+#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
+               spin_unlock(&lp->lock);
+               /* FIXME : with the lock, could this ever happen ? */
+#endif
+
                return;
        }
-       /* dev->interrupt = 1; */
+       dev->interrupt = 1;
 
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
-       spin_lock(&lp->lock);
-#endif 
-        ioaddr = dev->base_addr;
+       if (net_debug > 5)
+               printk(KERN_DEBUG "%s: entering eepro_interrupt routine.\n", dev->name);
+       
+       ioaddr = dev->base_addr;
 
-        do { 
-         status = inb(ioaddr + STATUS_REG);
+       do { 
+               status = inb(ioaddr + STATUS_REG);
                
-         if (status & RX_INT) {
-           if (net_debug > 4)
-             printk(KERN_DEBUG "eepro: packet received interrupt.\n");
-
-           /* Acknowledge the RX_INT */
-           outb(RX_INT, ioaddr + STATUS_REG);   
-           /* Get the received packets */
-           eepro_rx(dev);
-         }
-
-         else if (status & TX_INT) {
-           if (net_debug > 4)
-             printk(KERN_DEBUG "eepro: packet transmit interrupt.\n");
-
-           /* Acknowledge the TX_INT */
-           outb(TX_INT, ioaddr + STATUS_REG); 
-           
-           /* Process the status of transmitted packets */
-           eepro_transmit_interrupt(dev);
-         }
+               if (status & RX_INT) {
+                       if (net_debug > 4)
+                       printk(KERN_DEBUG "%s: packet received interrupt.\n", dev->name);
+
+                       /* Acknowledge the RX_INT */
+                       outb(RX_INT, ioaddr + STATUS_REG);
+                       /* Get the received packets */
+                       eepro_rx(dev);
+               }
+
+               else if (status & TX_INT) {
+                       if (net_debug > 4)
+                       printk(KERN_DEBUG "%s: packet transmit interrupt.\n", dev->name);
+
+                       /* Acknowledge the TX_INT */
+                       outb(TX_INT, ioaddr + STATUS_REG); 
+
+                       /* Process the status of transmitted packets */
+                       eepro_transmit_interrupt(dev);
+               }
        
        } while ((boguscount-- > 0) && (status & 0x06));
 
        dev->interrupt = 0; 
 
        if (net_debug > 5)
-               printk(KERN_DEBUG "eepro: exiting eepro_interrupt routine.\n");
+               printk(KERN_DEBUG "%s: exiting eepro_interrupt routine.\n", dev->name);
 
 #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
        spin_unlock(&lp->lock);
@@ -1173,7 +1176,7 @@ static int eepro_close(struct device *dev)
        /* Flush the Tx and disable Rx. */
        outb(STOP_RCV_CMD, ioaddr); 
        lp->tx_start = lp->tx_end = rcv_ram ;
-       lp->tx_last = 0;  
+       lp->tx_last = 0;
 
        /* Mask all the interrupts. */
        outb(ALL_MASK, ioaddr + INT_MASK_REG); 
@@ -1238,7 +1241,8 @@ set_multicast_list(struct device *dev)
                outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
                outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
                printk("%s: promiscuous mode enabled.\n", dev->name);
-       } 
+       }
+       
        else if (dev->mc_count==0 ) 
        {
                outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
@@ -1248,6 +1252,7 @@ set_multicast_list(struct device *dev)
                outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
                outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
        }
+       
        else 
        {
                unsigned short status, *eaddrs;
@@ -1269,6 +1274,7 @@ set_multicast_list(struct device *dev)
                outw(0, ioaddr + IO_PORT);
                outw(0, ioaddr + IO_PORT);
                outw(6*(dev->mc_count + 1), ioaddr + IO_PORT);
+               
                for (i = 0; i < dev->mc_count; i++) 
                {
                        eaddrs=(unsigned short *)dmi->dmi_addr;
@@ -1277,6 +1283,7 @@ set_multicast_list(struct device *dev)
                        outw(*eaddrs++, ioaddr + IO_PORT);
                        outw(*eaddrs++, ioaddr + IO_PORT);
                }
+               
                eaddrs = (unsigned short *) dev->dev_addr;
                outw(eaddrs[0], ioaddr + IO_PORT);
                outw(eaddrs[1], ioaddr + IO_PORT);
@@ -1286,8 +1293,9 @@ set_multicast_list(struct device *dev)
 
                /* Update the transmit queue */
                i = lp->tx_end + XMT_HEADER + 6*(dev->mc_count + 1);
+               
                if (lp->tx_start != lp->tx_end) 
-               { 
+               {
                        /* update the next address and the chain bit in the 
                           last packet */
                        outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
@@ -1309,14 +1317,15 @@ set_multicast_list(struct device *dev)
                        {
                                i = inb(ioaddr);
                                outb(0x08, ioaddr + STATUS_REG);
+                               
                                if (i & 0x20) { /* command ABORTed */
                                        printk("%s: multicast setup failed.\n", 
                                                dev->name);
                                        break;
                                } else if ((i & 0x0f) == 0x03)  { /* MC-Done */
-                                 printk("%s: set Rx mode to %d address%s.\n",
-                                        dev->name, dev->mc_count,
-                                        dev->mc_count > 1 ? "es":"");
+                                       printk("%s: set Rx mode to %d address%s.\n",
+                                               dev->name, dev->mc_count,
+                                               dev->mc_count > 1 ? "es":"");
                                        break;
                                }
                        }
@@ -1333,7 +1342,7 @@ set_multicast_list(struct device *dev)
 /* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */
 
 /* The delay between EEPROM clock transitions. */
-#define eeprom_delay() { int _i = 40; while (--_i > 0) { SLOW_DOWN; }}
+#define eeprom_delay() { udelay(40); }
 #define EE_READ_CMD (6 << 6)
 
 int
@@ -1385,16 +1394,16 @@ hardware_send_packet(struct device *dev, void *buf, short length)
        unsigned status, tx_available, last, end, boguscount = 100;
 
        if (net_debug > 5)
-               printk(KERN_DEBUG "eepro: entering hardware_send_packet routine.\n");
+               printk(KERN_DEBUG "%s: entering hardware_send_packet routine.\n", dev->name);
 
        while (boguscount-- > 0) {
 
                /* Disable RX and TX interrupts.  Necessary to avoid
-               corruption of the HOST_ADDRESS_REG by interrupt
-               service routines. */
+               corruption of the HOST_ADDRESS_REG by interrupt
+               service routines. */
                outb(ALL_MASK, ioaddr + INT_MASK_REG);
 
-               if (dev->interrupt == 1) {  
+               if (dev->interrupt == 1) {
                        /* Enable RX and TX interrupts */
                        outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
                        continue;
@@ -1421,12 +1430,15 @@ hardware_send_packet(struct device *dev, void *buf, short length)
                end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
 
                if (end >= RAM_SIZE) { /* the transmit buffer is wrapped around */
+               
                        if ((RAM_SIZE - last) <= XMT_HEADER) {  
-                       /* Arrrr!!!, must keep the xmt header together,
-                         several days were lost to chase this one down. */
+                               /* Arrrr!!!, must keep the xmt header together,
+                               several days were lost to chase this one down. */
+                               
                                last = rcv_ram;
                                end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
-                       }       
+                       }
+                       
                        else end = rcv_ram + (end - RAM_SIZE);
                }
 
@@ -1454,18 +1466,20 @@ hardware_send_packet(struct device *dev, void *buf, short length)
                        lp->tx_start = last;   /* I don't like to change tx_start here */
                }
                else {
-                 /* update the next address and the chain bit in the 
-                    last packet */
-                 if (lp->tx_end != last) {
-                   outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
-                   outw(last, ioaddr + IO_PORT); 
-                 }
-                 outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG);
-                 status = inw(ioaddr + IO_PORT); 
-                 outw(status | CHAIN_BIT, ioaddr + IO_PORT);
-
-                 /* Continue the transmit command */
-                 outb(RESUME_XMT_CMD, ioaddr);
+                       /* update the next address and the chain bit in the 
+                       last packet */
+                       
+                       if (lp->tx_end != last) {
+                               outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
+                               outw(last, ioaddr + IO_PORT); 
+                       }
+                       
+                       outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG);
+                       status = inw(ioaddr + IO_PORT); 
+                       outw(status | CHAIN_BIT, ioaddr + IO_PORT);
+
+                       /* Continue the transmit command */
+                       outb(RESUME_XMT_CMD, ioaddr);
                }
 
                lp->tx_last = last;
@@ -1476,16 +1490,16 @@ hardware_send_packet(struct device *dev, void *buf, short length)
                }
                
                /* Enable RX and TX interrupts */
-                outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
+               outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
 
                if (net_debug > 5)
-                       printk(KERN_DEBUG "eepro: exiting hardware_send_packet routine.\n");
+                       printk(KERN_DEBUG "%s: exiting hardware_send_packet routine.\n", dev->name);
                return;
        }
 
        dev->tbusy = 1;
        if (net_debug > 5)
-               printk(KERN_DEBUG "eepro: exiting hardware_send_packet routine.\n");
+               printk(KERN_DEBUG "%s: exiting hardware_send_packet routine.\n", dev->name);
 }
 
 static void
@@ -1498,77 +1512,88 @@ eepro_rx(struct device *dev)
        unsigned rcv_event, rcv_status, rcv_next_frame, rcv_size;
 
        if (net_debug > 5)
-               printk(KERN_DEBUG "eepro: entering eepro_rx routine.\n");
+               printk(KERN_DEBUG "%s: entering eepro_rx routine.\n", dev->name);
        
        /* Set the read pointer to the start of the RCV */
        outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
+       
        rcv_event = inw(ioaddr + IO_PORT);
 
        while (rcv_event == RCV_DONE) {
-         rcv_status = inw(ioaddr + IO_PORT); 
-         rcv_next_frame = inw(ioaddr + IO_PORT);
-         rcv_size = inw(ioaddr + IO_PORT); 
+       
+               rcv_status = inw(ioaddr + IO_PORT); 
+               rcv_next_frame = inw(ioaddr + IO_PORT);
+               rcv_size = inw(ioaddr + IO_PORT); 
 
-         if ((rcv_status & (RX_OK | RX_ERROR)) == RX_OK) {
-           /* Malloc up new buffer. */
-           struct sk_buff *skb;
+               if ((rcv_status & (RX_OK | RX_ERROR)) == RX_OK) {
+               
+                       /* Malloc up new buffer. */
+                       struct sk_buff *skb;
 
 #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20155
-           lp->stats.rx_bytes+=rcv_size;
-#endif                        
-           rcv_size &= 0x3fff;
-           skb = dev_alloc_skb(rcv_size+5);
-           if (skb == NULL) {
-             printk("%s: Memory squeeze, dropping packet.\n", dev->name);
-             lp->stats.rx_dropped++;
-             break;
-           }
-           skb->dev = dev;
-           skb_reserve(skb,2);
-
-           if (lp->version == LAN595)
-             insw(ioaddr+IO_PORT, skb_put(skb,rcv_size), (rcv_size + 3) >> 1);
-           else { /* LAN595TX or LAN595FX, capable of 32-bit I/O processing */
-             unsigned short temp = inb(ioaddr + INT_MASK_REG);
-             outb(temp | IO_32_BIT, ioaddr + INT_MASK_REG);
-             insl(ioaddr+IO_PORT_32_BIT, skb_put(skb,rcv_size), 
-                  (rcv_size + 3) >> 2);
-             outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG);
-           }
+                       lp->stats.rx_bytes+=rcv_size;
+#endif
+                       rcv_size &= 0x3fff;
+                       skb = dev_alloc_skb(rcv_size+5);
+                       if (skb == NULL) {
+                               printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
+                               lp->stats.rx_dropped++;
+                               break;
+                       }
+                       skb->dev = dev;
+                       skb_reserve(skb,2);
+
+                       if (lp->version == LAN595)
+                               insw(ioaddr+IO_PORT, skb_put(skb,rcv_size), (rcv_size + 3) >> 1);
+                       else { /* LAN595TX or LAN595FX, capable of 32-bit I/O processing */
+                               unsigned short temp = inb(ioaddr + INT_MASK_REG);
+                               outb(temp | IO_32_BIT, ioaddr + INT_MASK_REG);
+                               insl(ioaddr+IO_PORT_32_BIT, skb_put(skb,rcv_size), 
+                                       (rcv_size + 3) >> 2);
+                               outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG);
+                       }
        
-           skb->protocol = eth_type_trans(skb,dev);    
-           netif_rx(skb);
-           lp->stats.rx_packets++;
-         }
-         else { /* Not sure will ever reach here, 
-                   I set the 595 to discard bad received frames */
-           lp->stats.rx_errors++;
-           if (rcv_status & 0x0100)
-             lp->stats.rx_over_errors++;
-           else if (rcv_status & 0x0400)
-             lp->stats.rx_frame_errors++;
-           else if (rcv_status & 0x0800)
-             lp->stats.rx_crc_errors++;
-           printk("%s: event = %#x, status = %#x, next = %#x, size = %#x\n", 
-                  dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
-         }
-         if (rcv_status & 0x1000)
-           lp->stats.rx_length_errors++;
-         if (--boguscount == 0)
-           break;
-         
-         rcv_car = lp->rx_start + RCV_HEADER + rcv_size;
-         lp->rx_start = rcv_next_frame;
-         outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG);
-         rcv_event = inw(ioaddr + IO_PORT);
-         
+                       skb->protocol = eth_type_trans(skb,dev);        
+                       netif_rx(skb);
+                       lp->stats.rx_packets++;
+               }
+               
+               else { /* Not sure will ever reach here, 
+                       I set the 595 to discard bad received frames */
+                       lp->stats.rx_errors++;
+                       
+                       if (rcv_status & 0x0100)
+                               lp->stats.rx_over_errors++;
+                       
+                       else if (rcv_status & 0x0400)
+                               lp->stats.rx_frame_errors++;
+                       
+                       else if (rcv_status & 0x0800)
+                               lp->stats.rx_crc_errors++;
+                       
+                       printk("%s: event = %#x, status = %#x, next = %#x, size = %#x\n", 
+                               dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
+               }
+
+               if (rcv_status & 0x1000)
+                       lp->stats.rx_length_errors++;
+
+               if (--boguscount == 0)
+                       break;
+
+               rcv_car = lp->rx_start + RCV_HEADER + rcv_size;
+               lp->rx_start = rcv_next_frame;
+               outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG);
+               rcv_event = inw(ioaddr + IO_PORT);
+
        } 
        if (rcv_car == 0)
-         rcv_car = (RCV_UPPER_LIMIT << 8) | 0xff;
+               rcv_car = (RCV_UPPER_LIMIT << 8) | 0xff;
+               
        outw(rcv_car - 1, ioaddr + RCV_STOP);
 
        if (net_debug > 5)
-         printk(KERN_DEBUG "eepro: exiting eepro_rx routine.\n");
+               printk(KERN_DEBUG "%s: exiting eepro_rx routine.\n", dev->name);
 }
 
 static void
@@ -1581,47 +1606,53 @@ eepro_transmit_interrupt(struct device *dev)
        
        /*
        if (dev->tbusy == 0) {
-         printk("%s: transmit_interrupt called with tbusy = 0 ??\n",
-                dev->name);
-         printk(KERN_DEBUG "%s: transmit_interrupt called with tbusy = 0 ??\n",
-                dev->name);
+               printk("%s: transmit_interrupt called with tbusy = 0 ??\n",
+                       dev->name);
+               printk(KERN_DEBUG "%s: transmit_interrupt called with tbusy = 0 ??\n",
+                       dev->name);
        }
        */
+
        while (lp->tx_start != lp->tx_end) { 
-         outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG); 
-         xmt_status = inw(ioaddr+IO_PORT);
-         if ((xmt_status & TX_DONE_BIT) == 0) break;
-
-         xmt_status = inw(ioaddr+IO_PORT); 
-         lp->tx_start = inw(ioaddr+IO_PORT);
-
-         dev->tbusy = 0;
-         mark_bh(NET_BH);
-
-         if (xmt_status & 0x2000)
-           lp->stats.tx_packets++; 
-         else {
-           lp->stats.tx_errors++;
-           if (xmt_status & 0x0400)
-             lp->stats.tx_carrier_errors++;
-           printk("%s: XMT status = %#x\n",
-                  dev->name, xmt_status);
-           printk(KERN_DEBUG "%s: XMT status = %#x\n",
-                  dev->name, xmt_status);
-         }
-         if (xmt_status & 0x000f) {
-           lp->stats.collisions += (xmt_status & 0x000f);
-         }
-         if ((xmt_status & 0x0040) == 0x0) {
-           lp->stats.tx_heartbeat_errors++;
-         }
-         
-         if (--boguscount == 0)
-           break;  
+       
+               outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG); 
+               xmt_status = inw(ioaddr+IO_PORT);
+               
+               if ((xmt_status & TX_DONE_BIT) == 0) break;
+
+               xmt_status = inw(ioaddr+IO_PORT); 
+               lp->tx_start = inw(ioaddr+IO_PORT);
+
+               dev->tbusy = 0;
+               mark_bh(NET_BH);
+
+               if (xmt_status & 0x2000)
+                       lp->stats.tx_packets++; 
+               else {
+                       lp->stats.tx_errors++;
+                       if (xmt_status & 0x0400)
+                               lp->stats.tx_carrier_errors++;
+                       printk("%s: XMT status = %#x\n",
+                               dev->name, xmt_status);
+                       printk(KERN_DEBUG "%s: XMT status = %#x\n",
+                               dev->name, xmt_status);
+               }
+               
+               if (xmt_status & 0x000f) {
+                       lp->stats.collisions += (xmt_status & 0x000f);
+               }
+               
+               if ((xmt_status & 0x0040) == 0x0) {
+                       lp->stats.tx_heartbeat_errors++;
+               }
+
+               if (--boguscount == 0)
+                       break;
        }
 }
 
 #ifdef MODULE
+
 #define MAX_EEPRO 8
 static char devicename[MAX_EEPRO][9];
 static struct device dev_eepro[MAX_EEPRO];
@@ -1655,10 +1686,12 @@ MODULE_PARM(irq, "i");
 MODULE_PARM(mem, "i");
 #endif 
 
-int init_module(void)
+int 
+init_module(void)
 {
        if (io[0] == 0)
-               printk("eepro: You should not use auto-probing with insmod!\n");
+               printk("eepro_init_module: You should not use auto-probing with insmod!\n");
+
        while (n_eepro < MAX_EEPRO && io[n_eepro] >= 0) {
                struct device *d = &dev_eepro[n_eepro];
                d->name         = devicename[n_eepro]; /* inserted by drivers/net/net_init.c */
@@ -1682,6 +1715,7 @@ cleanup_module(void)
        for (i=0; i<n_eepro; i++) {
                struct device *d = &dev_eepro[i];
                unregister_netdev(d);
+
                kfree_s(d->priv,sizeof(struct eepro_local));
                d->priv=NULL;
 
index 057fe5b86d5d901c37e6018ac221a0d314ce8f11..30d34254af2494807bfdbdf06ee2496ab3869bd7 100644 (file)
@@ -506,7 +506,7 @@ static int eexp_xmit(struct sk_buff *buf, struct device *dev)
        printk(KERN_DEBUG "%s: eexp_xmit()\n", dev->name);
 #endif
 
-       outb(SIRQ_dis|irqrmap[dev->irq],dev->base_addr+SET_IRQ);
+       disable_irq(dev->irq);
 
        /* If dev->tbusy is set, all our tx buffers are full but the kernel
         * is calling us anyway.  Check that nothing bad is happening.
@@ -543,7 +543,7 @@ static int eexp_xmit(struct sk_buff *buf, struct device *dev)
                eexp_hw_tx_pio(dev,data,length);
        }
        dev_kfree_skb(buf);
-       outb(SIRQ_en|irqrmap[dev->irq],dev->base_addr+SET_IRQ);
+       enable_irq(dev->irq);
        return 0;
 }
 
index 59921bfc228f65ed8f555d2707475c4408f01dc3..391f6194a072ff4b8357e40abf3632ef3c887c79 100644 (file)
@@ -799,12 +799,12 @@ static int eth16i_receive_probe_packet(int ioaddr)
                if( (jiffies - starttime) > TX_TIMEOUT) {
 
                        if(eth16i_debug > 1)
-                               printk(KERN_DEBUG "Timeout occured waiting transmit packet received\n");
+                               printk(KERN_DEBUG "Timeout occurred waiting transmit packet received\n");
                        starttime = jiffies;
                        while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) {
                                if( (jiffies - starttime) > TX_TIMEOUT) {
                                        if(eth16i_debug > 1)
-                                               printk(KERN_DEBUG "Timeout occured waiting receive packet\n");
+                                               printk(KERN_DEBUG "Timeout occurred waiting receive packet\n");
                                        return -1;
                                }
                        }
index b504bcd51ef245794be6da773db75e63bb8db694..ee0c4f8ca9e046051d338665bde027eaf906e883 100644 (file)
@@ -1365,7 +1365,7 @@ static void hp100_init_pdls( struct device *dev )
 /* They return how much memory the fragments need.            */
 static int hp100_init_rxpdl( struct device *dev, register hp100_ring_t *ringptr, register u32 *pdlptr )
 {
-  /* pdlptr is starting adress for this pdl */
+  /* pdlptr is starting address for this pdl */
 
   if( 0!=( ((unsigned)pdlptr) & 0xf) )
     printk("hp100: %s: Init rxpdl: Unaligned pdlptr 0x%x.\n",dev->name,(unsigned)pdlptr);
index 1bcaac3b44d389f731c2eaa9662a12c98f80625c..60a729f24e359b4bdc8307f097024a284c647182 100644 (file)
@@ -43,6 +43,9 @@
    - Added code that unregisters irq and proc-info
    - Version# bump
 
+   Mon Nov 16 15:28:23 CET 1998 (Wim Dumon)
+   - pass 'dev' as last parameter of request_irq in stead of 'NULL'   
+   
    *    WARNING
        -------
        This is alpha-test software.  It is not guaranteed to work. As a
@@ -51,8 +54,7 @@
        If it doesn't work, be sure to send me a mail with the problems !
 */
 
-static const char *version =
-"ne2.c:v0.90 Oct 14 1998 David Weinehall <tao@acc.umu.se>\n";
+static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon <wimpie@kotnet.org>\n";
 
 #include <linux/module.h>
 #include <linux/version.h>
@@ -317,7 +319,7 @@ __initfunc (static int ne2_probe1(struct device *dev, int slot))
           share and the board will usually be enabled. */
        {
                int irqval = request_irq(dev->irq, ei_interrupt, 
-                               0, name, NULL);
+                               0, name, dev);
                if (irqval) {
                        printk (" unable to get IRQ %d (irqval=%d).\n", 
                                        dev->irq, +irqval);
@@ -330,7 +332,7 @@ __initfunc (static int ne2_probe1(struct device *dev, int slot))
        /* Allocate dev->priv and fill in 8390 specific dev fields. */
        if (ethdev_init(dev)) {
                printk (" unable to get memory for dev->priv.\n");
-               free_irq(dev->irq, NULL);
+               free_irq(dev->irq, dev);
                return -ENOMEM;
        }
 
index cfd14e0fa888349cf635b3b61edeac499cedaf66..30bf43c9ab7c2cbac6ce94a13a332b6d5289bf95 100644 (file)
@@ -355,7 +355,7 @@ void RCProcMsgQ(U16 AdapterID);
  /*
  ** Disable and Enable Adapter interrupts.  Adapter interrupts are enabled at 
  ** Init time but can be disabled and re-enabled through these two function calls.
- ** Packets will still be put into any posted recieved buffers and packets will
+ ** Packets will still be put into any posted received buffers and packets will
  ** be sent through RCSendPacket() functions.  Disabling Adapter interrupts
  ** will prevent hardware interrupt to host even though the outbound msg
  ** queue is not emtpy.
index 46992d97ac4fdd748d8fe3366fbb272d8831b531..1ddf31a98fdae2b5f91ec0990ff4f9a94f7154df 100644 (file)
@@ -493,7 +493,7 @@ int sdla_down (sdlahw_t* hw)
 }
 
 /*============================================================================
- * Map shared memory window into SDLA adress space.
+ * Map shared memory window into SDLA address space.
  */
 
 EXPORT_SYMBOL(sdla_mapmem);
index 7a4920f9f08b0870807da5660f48f4c91dbf91c3..7bc4f256f095e49e15a92a1d9b86f2b16a18bad6 100644 (file)
@@ -1068,7 +1068,7 @@ static void sktr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
                if(!sktr_chk_ssb(tp, irq_type))
                {
-                       printk(KERN_INFO "%s: DATA LATE occured\n", dev->name);
+                       printk(KERN_INFO "%s: DATA LATE occurred\n", dev->name);
                        break;
                }
 
@@ -1583,7 +1583,7 @@ static int sktr_reset_adapter(struct device *dev)
                        c |= ACL_SPEED16;               /* Set 16Mbps */
        }
 
-       /* In case a comand is pending - forget it */
+       /* In case a command is pending - forget it */
        tp->ScbInUse = 0;
 
        c &= ~ACL_ARESET;               /* Clear adapter reset bit */
@@ -1672,7 +1672,7 @@ static int sktr_bringup_diags(struct device *dev)
        } while(retry_cnt > 0);
 
        Status = inw(ioaddr + SIFSTS);
-       Status &= STS_ERROR_MASK;       /* Hardware error occured! */
+       Status &= STS_ERROR_MASK;       /* Hardware error occurred! */
 
        printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n",
                dev->name, Status);
@@ -1761,7 +1761,7 @@ static int sktr_init_adapter(struct device *dev)
                {
                        if((Status & STS_ERROR) != 0)
                        {
-                               /* Initialization error occured */
+                               /* Initialization error occurred */
                                Status = inw(ioaddr + SIFSTS);
                                Status &= STS_ERROR_MASK;
                                /* ShowInitialisationErrorCode(Status); */
index bef17faa448ff0cd785f0f7c1be9f9a6b64afb6b..25dd973d41be9622b8d8ab63c0a5c3db9b6d9643 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * The firmware this driver downloads into the tokenring card is a
- * seperate program and is not GPL'd source code, even though the Linux
+ * separate program and is not GPL'd source code, even though the Linux
  * side driver and the routine that loads this data into the card are.
  *
  * This firmware is licensed to you strictly for use in conjunction
index 243ba687217258e48cdcaa6157598112cb0f02f8..e4e650ba36c6ad7069a353384f82239072cbbd14 100644 (file)
@@ -425,7 +425,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct device *dev)
     lp->tda[entry].tx_frag_ptr_h = laddr >> 16;
     lp->tda[entry].tx_frag_size  = length;
     
-    /* if there are already packets queued, allow sending serveral packets at once */
+    /* if there are already packets queued, allow sending several packets at once */
     if (lp->dirty_tx != lp->cur_tx)
        lp->tda[(lp->cur_tx-1) % SONIC_TDS_MASK].link &= ~SONIC_END_OF_LINKS;
     
index e932073392acb55113eff9201cc90aab481936be..d3d2fba46ef24a274d941a13c8505bd6fd9782dd 100644 (file)
@@ -2797,7 +2797,7 @@ void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
         *
         *      Returns:
         *              No error = 0, else, the stage at which the error
-        *              occured.
+        *              occurred.
         *      Parms:
         *              io_base         The IO port base address for the
         *                              TLAN device with the EEPROM to
index 9fd3dd20ad1efce0c32153b313b76b856bf12748..7e7cc5d14f1d2cca89109330441016db12521f7d 100644 (file)
@@ -227,7 +227,7 @@ static void z8530_rtsdtr(struct z8530_channel *c, int set)
  *     Receive handler. This is much like the async one but not quite the
  *     same or as complex
  *
- *     Note: Its intended that this handler can easily be seperated from
+ *     Note: Its intended that this handler can easily be separated from
  *     the main code to run realtime. That'll be needed for some machines
  *     (eg to ever clock 64kbits on a sparc ;)).
  *
index 2dff6d16b15a4070b3799d0bcda473ec17632e11..ff7564eb99a7b86dd62e62f5c598b58b78e9c747 100644 (file)
@@ -207,11 +207,11 @@ __initfunc(int znet_probe(struct device *dev))
        char *p;
 
        /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */
-       for(p = (char *)0xf0000; p < (char *)0x100000; p++)
+       for(p = phys_to_virt(0xf0000); p < phys_to_virt(0x100000); p++)
                if (*p == 'N'  &&  strncmp(p, "NETIDBLK", 8) == 0)
                        break;
 
-       if (p >= (char *)0x100000) {
+       if (p >= pyhs_to_virt(0x100000)) {
                if (znet_debug > 1)
                        printk(KERN_INFO "No Z-Note ethernet adaptor found.\n");
                return ENODEV;
index 18e27f46a705e4c7f4f37b7de75f4d3aeaa9e5d1..3fe63303089ca9ce15a5f1ff751d731f4591f308 100644 (file)
@@ -129,7 +129,7 @@ __initfunc(static void quirk_passive_release(struct pci_dev *dev, int arg))
     but VIA don't answer queries. If you happen to have good contacts at VIA
     ask them for me please -- Alan 
     
-    This appears to be BIOS not version dependant. So presumably there is a 
+    This appears to be BIOS not version dependent. So presumably there is a 
     chipset level fix */
     
 
index 4a0064f55c8b3bb236a4c8084ebf8e9601190a0f..9b71e0a809955e822d87dc13fb904d5b79307a73 100644 (file)
@@ -1021,7 +1021,7 @@ static int amd7930_ioctl(struct inode * inode, struct file * file,
  *
  *       0 - successful reception
  *   non-0 - error value from chip's DER (D-Channel Error Register):
- *       1 - recieved packet abort
+ *       1 - received packet abort
  *       2 - framing error; non-integer number of bytes received
  *       8 - FCS error; CRC sequence indicated corrupted data
  *      16 - overflow error; packet exceeded size of buffer
index af3a8a4d7356f210ee58cb46435b4fc39e0ded27..363d0b225d1847b36d535eb6fcfc00bf40504baa 100644 (file)
@@ -305,7 +305,7 @@ struct dbri {
 #define DBRI_RD_M      (1<<14) /* Marker interrupt */
 #define DBRI_RD_BCNT(v)        v       /* Buffer size */
 #define DBRI_RD_CRC    (1<<7)  /* 0: CRC is correct */
-#define DBRI_RD_BBC    (1<<6)  /* 1: Bad Byte recieved */
+#define DBRI_RD_BBC    (1<<6)  /* 1: Bad Byte received */
 #define DBRI_RD_ABT    (1<<5)  /* Abort: frame aborted */
 #define DBRI_RD_OVRN   (1<<3)  /* Overrun: data lost */
 #define DBRI_RD_STATUS(v)      ((v)&0xff)      /* Receive status */
index 68cfc44051f380e26de2a8bdfab42c8d37c37aa9..8302316aab6d46d99247aa7f182e21f484597fc5 100644 (file)
@@ -156,7 +156,7 @@ int vfc_i2c_xmit_addr(struct vfc_dev *dev, unsigned char addr, char mode)
        switch(mode) {
        case VFC_I2C_READ:
                dev->regs->i2c_reg=raddr=SHIFT((unsigned int)addr | 0x1);
-               VFC_I2C_DEBUG_PRINTK(("vfc%d: recieving from i2c addr 0x%x\n",
+               VFC_I2C_DEBUG_PRINTK(("vfc%d: receiving from i2c addr 0x%x\n",
                                  dev->instance,addr | 0x1));
                break;
        case VFC_I2C_WRITE:
@@ -255,7 +255,7 @@ int vfc_i2c_recvbuf(struct vfc_dev *dev, unsigned char addr,
                if(!count) last=1;
                if((ret=vfc_i2c_recv_byte(dev,buf,last))) {
                        printk(KERN_ERR "vfc%d: "
-                              "VFC error while recieving byte\n",
+                              "VFC error while receiving byte\n",
                               dev->instance);
                        dev->regs->i2c_s1=SEND_I2C_STOP;
                        ret=-EINVAL;
index 409967d0ee6c75e0a6b59d705d8c28431dd1342d..47bbe19ba6bfe202c3e6eecea7811774b96e7292 100644 (file)
@@ -33,7 +33,7 @@ Written by Gerard Roudier <groudier@club-internet.fr>
       10.6 SCSI BUS checking boot option
 11. Some constants and flags of the ncr53c8xx.h header file
 12. Installation
-13. Architecture dependant features
+13. Architecture dependent features
 14. Known problems
       14.1 Tagged commands with Iomega Jaz device
       14.2 Device names change when another controller is added
@@ -948,7 +948,7 @@ patches:
       ftp://ftp.tux.org/pub/people/gerard-roudier/README
 
 
-13. Architecture dependant features.
+13. Architecture dependent features.
 
 <Not yet written>
 
index 7cb4dbaa379190af3f3dc736469647af6aecd9e8..945cefbcc8348dd7da6df244d9eea9af86751b9f 100644 (file)
@@ -461,7 +461,7 @@ register SEQCTL {
  * Sequencer RAM Data (p. 3-34)
  * Single byte window into the Scratch Ram area starting at the address
  * specified by SEQADDR0 and SEQADDR1.  To write a full word, simply write
- * four bytes in sucessesion.  The SEQADDRs will increment after the most
+ * four bytes in succession.  The SEQADDRs will increment after the most
  * significant byte is written
  */
 register SEQRAM {
index 762cdff6bb68c01793a5c00585e620f965ea82ce..15aa4d9fa996b974d1962fbc9150a84b9bf3c738 100644 (file)
@@ -1,5 +1,3 @@
-#include <linux/config.h>
-
 void swap_statistics(u8 *p)
 {
     u32 y;
index 4023c184e85fd28d450c31639a19b2a0a94c07b1..a6c59d7c69feebd3a10e4195055d4dde7598df1c 100644 (file)
@@ -1,5 +1,3 @@
-#include <linux/config.h>
-
 /*
  * eata_set_info
  * buffer : pointer to the data that has been written to the hostfile
index 87f724e058fb2dda120712f2f729bf43301d5718..feba4c773cb74d83aced9fd94fed8425961226eb 100644 (file)
@@ -63,6 +63,7 @@
 /* ------ END OF USER CONFIGURABLE PARAMETERS ----- */
 
 #ifdef IMM_CODE
+#include  <linux/config.h>
 #include  <linux/stddef.h>
 #include  <linux/module.h>
 #include  <linux/kernel.h>
index 58416c4c7a04b0009d5114059b9ac1831d6264f6..b3beb9f5d7b6058b1b73599e40a6d87ec7f94c1f 100644 (file)
@@ -55,6 +55,7 @@
 /* ------ END OF USER CONFIGURABLE PARAMETERS ----- */
 
 #ifdef PPA_CODE
+#include  <linux/config.h>
 #include  <linux/stddef.h>
 #include  <linux/module.h>
 #include  <linux/kernel.h>
index 98791e972729bda78976478a67d08291245fc75a..34060e9460810aceb603116d0f2759fc1ff08c28 100644 (file)
@@ -531,7 +531,7 @@ static void scan_scsis (struct Scsi_Host *shpnt,
       for (dev = 0; dev < shpnt->max_id; ++dev) {
         if( shpnt->reverse_ordering)
                /* Shift to scanning 15,14,13... or 7,6,5,4, */
-               order_dev = shpnt->max_channel-dev-1;
+               order_dev = shpnt->max_id-dev-1;
         else
                order_dev = dev;
                
index ed3942efde4cda22cf92852c06526a5850f3fc01..a3d7c3538a589b3f672c86e79c80170b77020c25 100644 (file)
@@ -969,7 +969,7 @@ int scsi_decide_disposition (Scsi_Cmnd * SCpnt)
       /*
        * Note - this means that we just report the status back to the
        * top level driver, not that we actually think that it indicates
-       * sucess.
+       * success.
        */
       return SUCCESS;
       /*
index 0488cb353a26c79839a63dfff8405dd2afcabefc..7338feeecf7300e9fa3e78de4c962c6810fbbfb5 100644 (file)
  *  08/24/1996.
  *
  *  Enhancement for wd7000_detect function has been made, so you don't have
- *  to enter BIOS ROM adress in initialisation data (see struct Config).
+ *  to enter BIOS ROM address in initialisation data (see struct Config).
  *  We cannot detect IRQ, DMA and I/O base address for now, so we have to
  *  enter them as arguments while wd_7000 is detected. If someone has IRQ,
  *  DMA or I/O base address set to some other value, he can enter them in
index f24c33fe2ccc83c5392c8f2c5d55a1e4946d631a..6fb4c2433d6fcd7b62553f91622c43eedc7de201 100644 (file)
@@ -52,7 +52,7 @@ typedef struct
        int             dma1, dma2;
        int             dual_dma;       /* 1, when two DMA channels allocated */
        unsigned char   MCE_bit;
-       unsigned char   saved_regs[16];
+       unsigned char   saved_regs[32];
        int             debug_flag;
 
        int             audio_flags;
@@ -1601,6 +1601,9 @@ int ad1848_detect(int io_base, int *ad_flags, int *osp)
                                /*
                                 *      It's at least CS4231
                                 */
+
+                               devc->chip_name = "CS4231";
+                               devc->model = MD_4231;
                                
                                /*
                                 * It could be an AD1845 or CS4231A as well.
index eff3d1300fcc47bae692694d3a02c217a7c67017..019b915c5d046caac88ed68dea302ed3c4b8c313 100644 (file)
@@ -33,6 +33,7 @@
 #define SNDCARD_WAVEFRONT               41
 #define SNDCARD_OPL3SA2                 42
 #define SNDCARD_OPL3SA2_MPU             43
+#define SNDCARD_WAVEARTIST             44
 #define SNDCARD_AD1816                  88
 
 void attach_opl3sa_wss (struct address_info *hw_config);
@@ -502,6 +503,9 @@ probe_ad1816, unload_ad1816},
 #endif
 #ifdef CONFIG_SOUND_VIDC
        {"VIDC", 0, SNDCARD_VIDC, "ARM VIDC 16-bit D/A", attach_vidc, probe_vidc, unload_vidc },
+#endif
+#ifdef CONFIG_SOUND_WAVEARTIST
+       {"WaveArtist", 0, SNDCARD_WAVEARTIST, "NetWinder WaveArtist", attach_waveartist, probe_waveartist, unload_waveartist },
 #endif
        {NULL, 0, 0,            "*?*",                  NULL, NULL, NULL}
 };
@@ -678,6 +682,10 @@ struct card_info snd_installed_cards[] =
 #ifdef CONFIG_SOUND_VIDC
        { SNDCARD_VIDC, {0, 0, 0, 0}, SND_DEFAULT_ENABLE },
 #endif
+
+#ifdef CONFIG_SOUND_WAVEARTIST
+       { SNDCARD_WAVEARTIST, { CONFIG_WAVEARTIST_BASE, CONFIG_WAVEARTIST_IRQ, CONFIG_WAVEARTIST_DMA, CONFIG_WAVEARTIST_DMA2 }, SND_DEFAULT_ENABLE },
+#endif
        {0, {0}, 0}
 };
 
index f0837aa5546de553fdcae8e6eed9186f4d005dd1..37d1fc38fb1ec4f17d5ae8aea82679144fec545e 100644 (file)
@@ -81,6 +81,8 @@
  *                    -- Oliver Neukum <c188@org.chemie.uni-muenchen.de>
  *    10.12.98   0.15  Fix drain_dac trying to wait on not yet initialized DMA
  *    16.12.98   0.16  Don't wake up app until there are fragsize bytes to read/write
+ *    06.01.99   0.17  remove the silly SA_INTERRUPT flag.
+ *                     hopefully killed the egcs section type conflict
  *
  * some important things missing in Ensoniq documentation:
  *
@@ -2241,7 +2243,7 @@ static int micz[NR_DEVICE] = { 0, };
 
 /* --------------------------------------------------------------------- */
 
-static const struct initvol {
+static struct initvol {
        int mixch;
        int vol;
 } initvol[] __initdata = {
@@ -2270,7 +2272,7 @@ __initfunc(int init_es1370(void))
 
        if (!pci_present())   /* No PCI bus in this machine! */
                return -ENODEV;
-       printk(KERN_INFO "es1370: version v0.16 time " __TIME__ " " __DATE__ "\n");
+       printk(KERN_INFO "es1370: version v0.17 time " __TIME__ " " __DATE__ "\n");
        while (index < NR_DEVICE && 
               (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, pcidev))) {
                if (pcidev->base_address[0] == 0 || 
@@ -2298,7 +2300,7 @@ __initfunc(int init_es1370(void))
                        goto err_region;
                }
                request_region(s->io, ES1370_EXTENT, "es1370");
-               if (request_irq(s->irq, es1370_interrupt, SA_INTERRUPT|SA_SHIRQ, "es1370", s)) {
+               if (request_irq(s->irq, es1370_interrupt, SA_SHIRQ, "es1370", s)) {
                        printk(KERN_ERR "es1370: irq %u in use\n", s->irq);
                        goto err_irq;
                }
index 3154cddd6e9e1937dd8785b7e8724ba10c619c76..e52f47d149d95dfeb104add8b38a658adfff6084 100644 (file)
@@ -52,6 +52,8 @@
  *    10.12.98   0.6   Fix drain_dac trying to wait on not yet initialized DMA
  *    23.12.98   0.7   Fix a few f_file & FMODE_ bugs
  *                     Don't wake up app until there are fragsize bytes to read/write
+ *    06.01.99   0.8   remove the silly SA_INTERRUPT flag.
+ *                     hopefully killed the egcs section type conflict
  *
  */
 
@@ -2710,7 +2712,7 @@ __initfunc(int init_es1371(void))
 
        if (!pci_present())   /* No PCI bus in this machine! */
                return -ENODEV;
-       printk(KERN_INFO "es1371: version v0.7 time " __TIME__ " " __DATE__ "\n");
+       printk(KERN_INFO "es1371: version v0.8 time " __TIME__ " " __DATE__ "\n");
        while (index < NR_DEVICE && 
               (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, pcidev))) {
                if (pcidev->base_address[0] == 0 || 
@@ -2738,7 +2740,7 @@ __initfunc(int init_es1371(void))
                        goto err_region;
                }
                request_region(s->io, ES1371_EXTENT, "es1371");
-               if (request_irq(s->irq, es1371_interrupt, SA_INTERRUPT|SA_SHIRQ, "es1371", s)) {
+               if (request_irq(s->irq, es1371_interrupt, SA_SHIRQ, "es1371", s)) {
                        printk(KERN_ERR "es1371: irq %u in use\n", s->irq);
                        goto err_irq;
                }
index 3c46d7adad2fcab376abc212e08dda757d41baad..a00ffb63a021fdcc98dea363b2c0d0552a5eaa8e 100644 (file)
@@ -128,17 +128,20 @@ void gusintr(int irq, void *dev_id, struct pt_regs *dummy)
 {
        unsigned char src;
        extern int gus_timer_enabled;
-       struct address_info *hw_config=dev_id;
 
        sti();
 
 #ifdef CONFIG_GUSMAX
-       if (have_gus_max)
+       if (have_gus_max) {
+               struct address_info *hw_config = dev_id;
                adintr(irq, (void *)hw_config->slots[1], NULL);
+       }
 #endif
 #ifdef CONFIG_GUS16
-       if (db16)
+       if (db16) {
+               struct address_info *hw_config = dev_id;
                adintr(irq, (void *)hw_config->slots[3], NULL);
+       }
 #endif
 
        while (1)
index 6d6fee19fbdaa95a355cbce501a1e1c496f1cbf4..3b15a961602daac63c3cebd38fe430ac7c705648 100644 (file)
@@ -2932,7 +2932,6 @@ void gus_wave_init(struct address_info *hw_config)
        int gus_type = 0x24;    /* 2.4 */
 
        int irq = hw_config->irq, dma = hw_config->dma, dma2 = hw_config->dma2;
-       int dev;
        int sdev;
 
        hw_config->slots[0] = -1;       /* No wave */
index b496edd5654d7dc619f6fc96d1f87e3678d683bf..0ad4fb0622dcab9274c2a1fde46eac5f580908e5 100644 (file)
@@ -150,7 +150,6 @@ static int _mem_start;  /* memory pointer for permanent buffers */
 #define my_malloc_init(memptr) _mem_start = (memptr)
 #define my_malloc_memptr()     _mem_start
 #define my_free(ptr)   /* do nothing */
-#define my_realloc(buf,oldsize,size)   NULL    /* no realloc */
 
 static void *my_malloc(int size)
 {
@@ -177,16 +176,6 @@ buffer = my_malloc(sizeof(type) * (nums)); index = (nums);\
 #define my_kmalloc(size)       kmalloc(size,GFP_KERNEL)
 #define my_kfree(ptr)          kfree(ptr)
 
-static void *my_realloc(void *buf, int oldsize, int size)
-{
-       void *ptr;
-       if ((ptr = vmalloc(size)) == NULL)
-               return NULL;
-       memcpy(ptr, buf, ((oldsize < size) ? oldsize : size) );
-       vfree(buf);
-       return ptr;
-}
-
 /* do not allocate buffer at beginning */
 #define INIT_TABLE(buffer,index,nums,type) {buffer=NULL; index=0;}
 
index f1843f76ab6ae823e70b05d5e1fe2c55eded311e..41533aedaf24b0291d5a702f2b6764c82a2b7142 100644 (file)
@@ -495,17 +495,24 @@ static int chip_detect(void)
 
                                for (i = 0xf8d; i <= 0xf93; i++)
                                        DDB(printk("port %03x = %02x\n", i, mad_read(i)));
+                                if(!detect_mad16()) {
+
+                                 /* The C931 has the password reg at F8D */
+                                 outb((0xE4), 0xF8D);
+                                 outb((0x80), 0xF8D);
+                                 DDB(printk("Detect using password = 0xE4 for C931\n"));
 
-                               if (!detect_mad16()) {
-                                 board_type = C924;
-                                 c924pnp++;
-                                 DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n"));
                                  if (!detect_mad16()) {
-                                   c924pnp=0;
-                                   return 0;
-                                 }
+                                   board_type = C924;
+                                   c924pnp++;
+                                   DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n"));
+                                   if (!detect_mad16()) {
+                                     c924pnp=0;
+                                     return 0;
+                                   }
                                  
-                                 DDB(printk("mad16.c: 82C924 PnP detected\n"));
+                                   DDB(printk("mad16.c: 82C924 PnP detected\n"));
+                                 }
                                }
                                else
                                  DDB(printk("mad16.c: 82C930 detected\n"));
index eda25872ebc7d7fc479c0ca9b5d92b2c3e2eeb70..2c996da64201b918b8aa999984a2fd756eb3bd87 100644 (file)
@@ -4,7 +4,7 @@
  * A low level driver for Yamaha OPL3-SA2 and SA3 cards.
  * SAx cards should work, as they are just variants of the SA3.
  *
- * Copyright 1998 Scott Murray <scottm@interlog.com>
+ * Copyright 1998, 1999 Scott Murray <scottm@interlog.com>
  *
  * Originally based on the CS4232 driver (in cs4232.c) by Hannu Savolainen
  * and others.  Now incorporates code/ideas from pss.c, also by Hannu
@@ -29,6 +29,9 @@
  * Scott Murray            Changed detection code to be more forgiving,
  *                         added force option as last resort,
  *                         fixed ioctl return values. (Dec 30, 1998)
+ * Scott Murray            Simpler detection code should work all the time now
+ *                         (with thanks to Ben Hutchings for the heuristic),
+ *                         removed now unnecessary force option. (Jan 5, 1999)
  *
  */
 
 #define DEFAULT_MIC    50
 #define DEFAULT_TIMBRE 0
 
+#define CHIPSET_UNKNOWN -1
+
 /*
- * NOTE: CHIPSET_UNKNOWN should match the default value of
- *       CONFIG_OPL3SA2_CHIPSET in Config.in to make everything
- *       work right in all situations.
+ * These are used both as masks against what the card returns,
+ * and as constants.
  */
-#define CHIPSET_UNKNOWN -1
 #define CHIPSET_OPL3SA2  1
 #define CHIPSET_OPL3SA3  2
 #define CHIPSET_OPL3SAX  4
 #ifdef CONFIG_OPL3SA2
 
 /* What's my version? */
-#ifdef CONFIG_OPL3SA2_CHIPSET
-/* Set chipset if compiled into the kernel */
-static int chipset = CONFIG_OPL3SA2_CHIPSET;
-#else
 static int chipset = CHIPSET_UNKNOWN;
-#endif
 
 /* Oh well, let's just cache the name */
 static char chipset_name[16];
@@ -526,14 +524,6 @@ static void unload_opl3sa2_mss(struct address_info *hw_config)
 
 int probe_opl3sa2(struct address_info *hw_config)
 {
-       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;
        char tag;
 
@@ -551,107 +541,55 @@ int probe_opl3sa2(struct address_info *hw_config)
 
        /*
         * 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
         */
-       if(chipset == 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 */
+       if(version & CHIPSET_OPL3SAX)
+       {
+               chipset = CHIPSET_OPL3SAX;
+               tag = 'x';
+               printk(KERN_INFO "Found OPL3-SAx (YMF719)\n");
+       }
+       else
        {
-               if(hw_config->card_subtype == CHIPSET_UNKNOWN)
+               if(version & CHIPSET_OPL3SA3)
                {
-                       /*
-                        * 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];
+                       chipset = CHIPSET_OPL3SA3;
+                       tag = '3';
+                       printk(KERN_INFO "Found OPL3-SA3 (YMF715)\n");
                }
                else
                {
-                       /* Use user specified chipset */
-                       switch(hw_config->card_subtype)
+                       if(version & CHIPSET_OPL3SA2)
                        {
-                               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)
-       {
-               case CHIPSET_OPL3SA2:
-                       printk(KERN_INFO "Found OPL3-SA2 (YMF711)\n");
-                       tag = '2';
-                       break;
-
-               case CHIPSET_OPL3SA3:
-                       printk(KERN_INFO "Found OPL3-SA3 (YMF715)\n");
-                       tag = '3';
-                       break;
-
-               case CHIPSET_OPL3SAX:
-                       printk(KERN_INFO "Found OPL3-SAx (YMF719)\n");
-                       tag = 'x';
-                       break;
-
-               default:
-                       printk(KERN_ERR "No Yamaha audio controller found\n");
-
-                       /* If we've actually checked the version, print it out */
-                       if(version)
+                               tag = '2';
+                               printk(KERN_INFO "Found OPL3-SA2 (YMF711)\n");
+                       }
+                       else
                        {
+                               chipset = CHIPSET_UNKNOWN;
+                               tag = '?';
+                               printk(KERN_ERR
+                                      "Unknown Yamaha audio controller version\n");
                                printk(KERN_INFO
                                       "%s: chipset version = %x\n",
                                       __FILE__,
                                       version);
                        }
-                       
-                       /* Set some sane values */
-                       chipset = CHIPSET_UNKNOWN;
-                       tag = '?';
-                       break;
+               }
        }
 
-       if(chipset != CHIPSET_UNKNOWN) {
+       if(chipset != CHIPSET_UNKNOWN)
+       {
                /* Generate a pretty name */
                sprintf(chipset_name, "OPL3-SA%c", tag);
                return 1;
@@ -687,7 +625,6 @@ int mpu_io  = -1;
 int irq     = -1;
 int dma     = -1;
 int dma2    = -1;
-int force   = -1;
 
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "Set i/o base of OPL3-SA2 or SA3 card (usually 0x370)");
@@ -707,9 +644,6 @@ MODULE_PARM_DESC(dma, "Set MSS (audio) first DMA channel (0, 1, 3)");
 MODULE_PARM(dma2, "i");
 MODULE_PARM_DESC(dma2, "Set MSS (audio) second DMA channel (0, 1, 3)");
 
-MODULE_PARM(force, "i");
-MODULE_PARM_DESC(force, "Force audio controller chipset (2, 3)");
-
 MODULE_DESCRIPTION("Module for OPL3-SA2 and SA3 sound cards (uses AD1848 MSS driver).");
 MODULE_AUTHOR("Scott Murray <scottm@interlog.com>");
 
@@ -731,7 +665,8 @@ int init_module(void)
 
        if(io == -1 || irq == -1 || dma == -1 || dma2 == -1 || mss_io == -1)
        {
-               printk(KERN_ERR "%s: 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__);
                return -EINVAL;
        }
@@ -742,12 +677,6 @@ int init_module(void)
        cfg.dma     = dma;
        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;
-
         /* The MSS config: */
        mss_cfg.io_base      = mss_io;
        mss_cfg.irq          = irq;
index ec471f9583735f2351ae5343da3d02b127b7916b..da0d91655c1b1b04ff61362fa170a4d37ad744cb 100644 (file)
 #define MDL_ES1868MIDI 14      /* MIDI port of ESS1868 */
 #define MDL_AEDSP      15      /* Audio Excel DSP 16 */
 
-#define SUBMDL_ES188X  0x10    /* Subtype ES188X for specific handling */
+#define SUBMDL_ES1788  0x10    /* Subtype ES1788 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 */
+#define SUBMDL_ES188X  0x14    /* Subtype ES1887 for specific handling */
 #define SUBMDL_ALS007  42      /* ALS-007 differs from SB16 only in mixer */
                                /* register assignment */
 /*
index 81ed977c619aad754da814f1afd01b6a90aae09b..2512ebb24dbafd44dcd78afd93f95d0925b8d9e1 100644 (file)
@@ -67,7 +67,12 @@ static int sb_audio_open(int dev, int mode)
        devc->fullduplex = devc->duplex &&
                ((mode & OPEN_READ) && (mode & OPEN_WRITE));
        sb_dsp_reset(devc);
-       ess_mixer_reload (devc, SOUND_MIXER_RECLEV);
+
+       /* At first glance this check isn't enough, some ESS chips might not 
+        * have a RECLEV. However if they don't common_mixer_set will refuse 
+        * cause devc->iomap has no register mapping for RECLEV
+        */
+       if (devc->model == MDL_ESS) ess_mixer_reload (devc, SOUND_MIXER_RECLEV);
 
        /* The ALS007 seems to require that the DSP be removed from the output */
        /* in order for recording to be activated properly.  This is done by   */
@@ -659,6 +664,43 @@ static void ess_speed(sb_devc * devc)
        return;
 }
 
+static void ess_change
+       (sb_devc *devc, unsigned int reg, unsigned int mask, unsigned int val)
+{
+       int value;
+
+       value = ess_read(devc, reg);
+       value = (value & ~mask) | (val & mask);
+       ess_write(devc, reg, value);
+}
+
+struct ess_command {int cmd; int data;};
+
+static void ess_exec_commands
+       (sb_devc *devc, struct ess_command *cmdtab[])
+{
+       struct ess_command *cmd;
+
+       cmd = cmdtab [ ((devc->channels != 1) << 1) + (devc->bits != AFMT_U8) ];
+
+       while (cmd->cmd != -1) {
+               ess_write (devc, cmd->cmd, cmd->data);
+               cmd++;
+       }
+}
+
+static struct ess_command ess_i08m[] =         /* input 8 bit mono */
+       { {0xb7, 0x51}, {0xb7, 0xd0}, {-1, 0} };
+static struct ess_command ess_i16m[] =         /* input 16 bit mono */
+       { {0xb7, 0x71}, {0xb7, 0xf4}, {-1, 0} };
+static struct ess_command ess_i08s[] =         /* input 8 bit stereo */
+       { {0xb7, 0x51}, {0xb7, 0x98}, {-1, 0} };
+static struct ess_command ess_i16s[] =         /* input 16 bit stereo */
+       { {0xb7, 0x71}, {0xb7, 0xbc}, {-1, 0} };
+
+static struct ess_command *ess_inp_cmds[] =
+       { ess_i08m, ess_i16m, ess_i08s, ess_i16s };
+
 static int ess_audio_prepare_for_input(int dev, int bsize, int bcount)
 {
        sb_devc *devc = audio_devs[dev]->devc;
@@ -666,46 +708,31 @@ static int ess_audio_prepare_for_input(int dev, int bsize, int bcount)
        sb_dsp_command(devc, DSP_CMD_SPKOFF);
 
        ess_write(devc, 0xb8, 0x0e);    /* Auto init DMA mode */
-       ess_write(devc, 0xa8, (ess_read(devc, 0xa8) & ~0x03) | (3 - devc->channels));   /* Mono/stereo */
+       ess_change (devc, 0xa8, 0x03, 3 - devc->channels);      /* Mono/stereo */
        ess_write(devc, 0xb9, 2);       /* Demand mode (4 bytes/DMA request) */
 
-       if (devc->channels == 1)
-       {
-               if (devc->bits == AFMT_U8)
-               {       
-                       /* 8 bit mono */
-                       ess_write(devc, 0xb7, 0x51);
-                       ess_write(devc, 0xb7, 0xd0);
-               }
-               else
-               {
-                       /* 16 bit mono */
-                       ess_write(devc, 0xb7, 0x71);
-                       ess_write(devc, 0xb7, 0xf4);
-               }
-       }
-       else
-       {       
-               /* Stereo */
-               if (devc->bits == AFMT_U8)
-               {
-                       /* 8 bit stereo */
-                       ess_write(devc, 0xb7, 0x51);
-                       ess_write(devc, 0xb7, 0x98);
-               }
-               else
-               {       
-                       /* 16 bit stereo */
-                       ess_write(devc, 0xb7, 0x71);
-                       ess_write(devc, 0xb7, 0xbc);
-               }
-       }
-       ess_write(devc, 0xb1, (ess_read(devc, 0xb1) & 0x0f) | 0x50);
-       ess_write(devc, 0xb2, (ess_read(devc, 0xb2) & 0x0f) | 0x50);
+       ess_exec_commands (devc, ess_inp_cmds);
+
+       ess_change (devc, 0xb1, 0xf0, 0x50);
+       ess_change (devc, 0xb2, 0xf0, 0x50);
+
        devc->trigger_bits = 0;
        return 0;
 }
 
+static struct ess_command ess_o08m[] =          /* output 8 bit mono */
+        { {0xb6, 0x80}, {0xb7, 0x51}, {0xb7, 0xd0}, {-1, 0} };
+static struct ess_command ess_o16m[] =          /* output 16 bit mono */
+        { {0xb6, 0x00}, {0xb7, 0x71}, {0xb7, 0xf4}, {-1, 0} };
+static struct ess_command ess_o08s[] =          /* output 8 bit stereo */
+        { {0xb6, 0x80}, {0xb7, 0x51}, {0xb7, 0x98}, {-1, 0} };
+static struct ess_command ess_o16s[] =          /* output 16 bit stereo */
+        { {0xb6, 0x00}, {0xb7, 0x71}, {0xb7, 0xbc}, {-1, 0} };
+
+
+static struct ess_command *ess_out_cmds[] =
+        { ess_o08m, ess_o16m, ess_o08s, ess_o16s };
+
 static int ess_audio_prepare_for_output(int dev, int bsize, int bcount)
 {
        sb_devc *devc = audio_devs[dev]->devc;
@@ -714,42 +741,14 @@ static int ess_audio_prepare_for_output(int dev, int bsize, int bcount)
        ess_speed(devc);
 
        ess_write(devc, 0xb8, 4);       /* Auto init DMA mode */
-       ess_write(devc, 0xa8, (ess_read(devc, 0xa8) & ~0x03) | (3 - devc->channels));   /* Mono/stereo */
+       ess_change (devc, 0xa8, 0x03, 3 - devc->channels);      /* Mono/stereo */
        ess_write(devc, 0xb9, 2);       /* Demand mode (4 bytes/request) */
 
-       if (devc->channels == 1)
-       {
-               if (devc->bits == AFMT_U8)
-               {       /* 8 bit mono */
-                       ess_write(devc, 0xb6, 0x80);
-                       ess_write(devc, 0xb7, 0x51);
-                       ess_write(devc, 0xb7, 0xd0);
-               }
-               else
-               {       /* 16 bit mono */
-                       ess_write(devc, 0xb6, 0x00);
-                       ess_write(devc, 0xb7, 0x71);
-                       ess_write(devc, 0xb7, 0xf4);
-               }
-       }
-       else
-       {       /* Stereo */
-               if (devc->bits == AFMT_U8)
-               {       /* 8 bit stereo */
-                       ess_write(devc, 0xb6, 0x80);
-                       ess_write(devc, 0xb7, 0x51);
-                       ess_write(devc, 0xb7, 0x98);
-               }
-               else
-               {               /* 16 bit stereo */
-                       ess_write(devc, 0xb6, 0x00);
-                       ess_write(devc, 0xb7, 0x71);
-                       ess_write(devc, 0xb7, 0xbc);
-               }
-       }
+       ess_exec_commands (devc, ess_out_cmds);
+
+       ess_change (devc, 0xb1, 0xf0, 0x50);
+       ess_change (devc, 0xb2, 0xf0, 0x50);
 
-       ess_write(devc, 0xb1, (ess_read(devc, 0xb1) & 0x0f) | 0x50);
-       ess_write(devc, 0xb2, (ess_read(devc, 0xb2) & 0x0f) | 0x50);
        sb_dsp_command(devc, DSP_CMD_SPKON);
 
        devc->trigger_bits = 0;
@@ -774,7 +773,7 @@ static void ess_audio_output_block(int dev, unsigned long buf, int nr_bytes,
        ess_write(devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
        ess_write(devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));
 
-       ess_write(devc, 0xb8, ess_read(devc, 0xb8) | 0x05);     /* Go */
+       ess_change (devc, 0xb8, 0x05, 0x05);    /* Go */
        devc->intr_active = 1;
 }
 
@@ -798,8 +797,8 @@ static void ess_audio_start_input(int dev, unsigned long buf, int nr_bytes, int
 
        ess_write(devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
        ess_write(devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));
-
-       ess_write(devc, 0xb8, ess_read(devc, 0xb8) | 0x0f);     /* Go */
+       ess_change (devc, 0xb8, 0x0f, 0x0f);    /* Go */
        devc->intr_active = 1;
 }
 
index 7902f3ae24fb11bbebb43046ffa5e03c2535f0bc..14d857b99c9254fd0fdbb6c1caa9905059da56f2 100644 (file)
@@ -13,7 +13,7 @@
 /*
  * Daniel J. Rodriksson: Modified sbintr to handle 8 and 16 bit interrupts
  *                       for full duplex support ( only sb16 by now )
- * Rolf Fokkens:        Added (BETA?) support for ES188x chips.
+ * Rolf Fokkens:        Added (BETA?) support for ES1887 chips.
  * (fokkensr@vertis.nl)         Which means: You can adjust the recording levels.
  */
 #include <linux/config.h>
@@ -554,6 +554,15 @@ static int ess_init(sb_devc * devc, struct address_info *hw_config)
        /*
         * This the detection heuristic of ESS technology, though somewhat
         * changed to actually make it work.
+        * This results in the following detection steps:
+        * - distinct between ES688 and ES1688+ (as always done in this driver)
+        *   if ES688 we're ready
+        * - try to detect ES1868, ES1869 or ES1878 (ess_identify)
+        *   if successful we're ready
+        * - try to detect ES1888, ES1887 or ES1788 (aim: detect ES1887)
+        *   if successful we're ready
+        * - Dunno. Must be 1688. Will do in general
+        *
         * This is the most BETA part of the software: Will the detection
          * always work?
         */
@@ -568,7 +577,7 @@ static int ess_init(sb_devc * devc, struct address_info *hw_config)
                        chip = "ES688";
                };
                if (chip == NULL) {
-                       int type, dummy;
+                       int type;
 
                        type = ess_identify (devc);
 
@@ -587,12 +596,18 @@ static int ess_init(sb_devc * devc, struct address_info *hw_config)
                                break;
                        };
                };
-               if (chip == NULL) {
-                       if (  !ess_probe (devc, 0x64, (1 << 3))
-                           && ess_probe (devc, 0x70, 0x7f)) {
-                               chip = "ES188x";
+               if (chip == NULL && !ess_probe(devc, 0x64, (1 << 3))) {
+                       if (ess_probe (devc, 0x70, 0x7f)) {
+                               if (ess_probe (devc, 0x64, (1 << 5))) {
+                                       chip = "ES1887";
+                               } else {
+                                       chip = "ES1888";
+                               }
                                devc->submodel = SUBMDL_ES188X;
-                       };
+                       } else {
+                               chip = "ES1788";
+                               devc->submodel = SUBMDL_ES1788;
+                       }
                };
                if (chip == NULL) {
                        chip = "ES1688";
@@ -1066,7 +1081,7 @@ void sb_dsp_unload(struct address_info *hw_config, int sbmpu)
 /*
  *     Mixer access routines
  *
- *     ES188x modifications: some mixer registers reside in the
+ *     ES1887 modifications: some mixer registers reside in the
  *     range above 0xa0. These must be accessed in another way.
  */
 
@@ -1107,7 +1122,10 @@ unsigned int sb_getmixer(sb_devc * devc, unsigned int port)
 
        return val;
 }
-
+/*
+ * Some PnP chips can be identified by repeatedly reading mixer register 0x40.
+ * This is done by ess_identify
+ */
 static unsigned int ess_identify (sb_devc * devc)
 {
        unsigned int val;
index b8415f0656641a13ce3e373d08e890abeae21c1f..c97935570e8a1ef4e5c1d98a7d0f300f14caa638 100644 (file)
  *
  * 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
+ *                               input basis.
+ *              (Dec 24 1998)  : Recognition of ES1788, ES1887, ES1888,
+ *                               ES1868, ES1869 and ES1878. Could be used for
+ *                               specific handling in the future. All except
+ *                               ES1887 and ES1888 and ES688 are handled like
+ *                               ES1688.
+ *              (Dec 27 1998)  : RECLEV for all (?) ES1688+ chips. ES188x now
+ *                               have the "Dec 20" support + RECLEV
  */
 
 /*
- * About ES188x support:
+ * About the documentation
+ *
+ * I don't know if the chips all are OK, but the documentation is buggy. 'cause
+ * I don't have all the cips myself, there's a lot I cannot verify. I'll try to
+ * keep track of my latest insights about his here. If you have additional info,
+ * please enlighten me (fokkensr@vertis.nl)!
  *
- * The standard ES1688 support doesn't take care of the ES188x recording
- * levels very well. Whenever a device is selected (recmask) for recording
- * it's recording level is loud, and it cannot be changed.
+ * I had the impression that ES1688 also has 6 bit master volume control. The
+ * documentation about ES1888 (rev C, october '95) claims that ES1888 has
+ * the following features ES1688 doesn't have:
+ * - 6 bit master volume
+ * - Full Duplex
+ * So ES1688 apparently doesn't have 6 bit master volume control, but the
+ * ES1688 does have RECLEV control. Makes me wonder: does ES688 have it too?
+ * Without RECLEV ES688 won't be much fun I guess.
  *
- * The ES188x has separate registers to control the recording levels. The
- * ES188x specific software makes these level the same as their corresponding
- * playback levels, unless recmask says they aren't recorded. In the latter
- * case the recording volumes are 0.
+ * From the ES1888 (rev C, october '95) documentation I got the impression
+ * that registers 0x68 to 0x6e don't exist which means: no recording volume
+ * controls. To my surprise the ES888 documentation (1/14/96) claims that
+ * ES888 does have these record mixer registers, but that ES1888 doesn't have
+ * 0x69 and 0x6b. So the rest should be there.
+ * 
+ */
+
+/*
+ * About recognition of ESS chips
+ *
+ * The distinction of ES688, ES1688, ES1788, ES1887 and ES1888 is described in
+ * a (preliminary ??) datasheet on ES1887. It's aim is to identify ES1887, but
+ * during detection the text claims that "this chip may be ..." when a step
+ * fails. This scheme is used to distinct between the above chips.
+ * It appears however that some PnP chips like ES1868 are recognized as ES1788
+ * by the ES1887 detection scheme. These PnP chips can be detected in another
+ * way however: ES1868, ES1869 and ES1878 can be recognized (full proof I think)
+ * by repeatedly reading mixer register 0x40. This is done by ess_identify in
+ * sb_common.c.
+ * This results in the following detection steps:
+ * - distinct between ES688 and ES1688+ (as always done in this driver)
+ *   if ES688 we're ready
+ * - try to detect ES1868, ES1869 or ES1878
+ *   if successful we're ready
+ * - try to detect ES1888, ES1887 or ES1788
+ *   if successful we're ready
+ * - Dunno. Must be 1688. Will do in general
+ *
+ * About RECLEV support:
+ *
+ * The existing ES1688 support didn't take care of the ES1688+ recording
+ * levels very well. Whenever a device was selected (recmask) for recording
+ * it's recording level was loud, and it couldn't be changed. The fact that
+ * internal register 0xb4 could take care of RECLEV, didn't work meaning until
+ * it's value was restored every time the chip was reset; this reset the
+ * value of 0xb4 too. I guess that's what 4front also had (have?) trouble with.
+ *
+ * About ES188x support:
  *
+ * The ES188x has separate registers to control the recording levels, for all
+ * inputs. The ES188x specific software makes these levels the same as their
+ * corresponding playback levels, unless recmask says they aren't recorded. In
+ * the latter case the recording volumes are 0.
  * Now recording levels of inputs can be controlled, by changing the playback
  * levels. Futhermore several devices can be recorded together (which is not
  * possible with the ES1688.
+ * Besides the separate recording level control for each input, the common
+ * recordig level can also be controlled by RECLEV as described above.
  */
 
 #include <linux/config.h>
 #include "sb.h"
 #include "sb_mixer.h"
 
+#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)
+
 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),
@@ -88,11 +210,12 @@ MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
 /*
  * The ES1688 specifics... hopefully correct...
  * - 6 bit master volume
+ *   I was wrong, ES1888 docs say ES1688 didn't have it.
  * - 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_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),
@@ -111,11 +234,30 @@ MIX_ENT(SOUND_MIXER_LINE2,        0x3a, 7, 4, 0x3a, 3, 4),
 MIX_ENT(SOUND_MIXER_LINE3,     0x00, 0, 0, 0x00, 0, 0)
 };
 
+static mixer_tab es1688later_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....
+ * registers. These seem to work OK on 1868 too.
  * 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!
@@ -314,78 +456,6 @@ static char     smw_mix_regs[] =   /* Left mixer registers */
   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)
-
-
 static int      sbmixnum = 1;
 
 static void     sb_mixer_reset(sb_devc * devc);
@@ -944,11 +1014,19 @@ int sb_mixer_init(sb_devc * devc)
                                                = ES688_RECORDING_DEVICES;
                                        devc->iomap = &es688_mix;
                                } else {
+                                       /*
+                                        * es1688 has 4 bits master vol.
+                                        * later chips have 6 bits (?)
+                                        */
                                        devc->supported_devices
                                                = ES1688_MIXER_DEVICES;
                                        devc->supported_rec_devices
                                                = ES1688_RECORDING_DEVICES;
-                                       devc->iomap = &es1688_mix;
+                                       if (devc->submodel < 0x10) {
+                                               devc->iomap = &es1688_mix;
+                                       } else {
+                                               devc->iomap = &es1688later_mix;
+                                       }
                                }
                        }
 
index 70685f53549498d7107acaf8983875acba3c0f10..f8627ce6ca1c9e5defadc9334f155f0c1582babe 100644 (file)
 
 #ifdef CONFIG_SBDSP
 
-#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
  * 
 #define LEFT_CHN       0
 #define RIGHT_CHN      1
 
-/*
- * 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)
-
 /*
  * Mixer registers of ALS007
  */
 #define ALS007_SYNTH   7
 
 #endif
+
index 75d93a4626b41011f8dcff0c1625e900ccf9f240..b1899e143944f4657efc29d609f6e0206faf1176 100644 (file)
@@ -49,6 +49,8 @@
  *    31.08.98   0.7   Fix realplayer problems - dac.count issues
  *    10.12.98   0.8   Fix drain_dac trying to wait on not yet initialized DMA
  *    16.12.98   0.9   Fix a few f_file & FMODE_ bugs
+ *    06.01.99   0.10  remove the silly SA_INTERRUPT flag.
+ *                     hopefully killed the egcs section type conflict
  *
  */
 
@@ -2243,7 +2245,7 @@ static unsigned dmaio = 0xac00;
 
 /* --------------------------------------------------------------------- */
 
-static const struct initvol {
+static struct initvol {
        int mixch;
        int vol;
 } initvol[] __initdata = {
@@ -2271,7 +2273,7 @@ __initfunc(int init_sonicvibes(void))
 
        if (!pci_present())   /* No PCI bus in this machine! */
                return -ENODEV;
-       printk(KERN_INFO "sv: version v0.9 time " __TIME__ " " __DATE__ "\n");
+       printk(KERN_INFO "sv: version v0.10 time " __TIME__ " " __DATE__ "\n");
 #if 0
        if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
                printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
@@ -2382,7 +2384,7 @@ __initfunc(int init_sonicvibes(void))
                wrindir(s, SV_CIPCMSR1, ((8000 * 65536 / FULLRATE) >> 8) & 0xff);
                wrindir(s, SV_CIADCOUTPUT, 0);
                /* request irq */
-               if (request_irq(s->irq, sv_interrupt, SA_INTERRUPT|SA_SHIRQ, "S3 SonicVibes", s)) {
+               if (request_irq(s->irq, sv_interrupt, SA_SHIRQ, "S3 SonicVibes", s)) {
                        printk(KERN_ERR "sv: irq %u in use\n", s->irq);
                        goto err_irq;
                }
index c4531e275ed07cfdc7ead2f181ea48cd9a0917f7..4ce5f06bdc958f394eafe5123f0b0fc71c3a390f 100644 (file)
@@ -349,15 +349,14 @@ int soundcore_open(struct inode *inode, struct file *file)
        return -ENODEV;
 }
 
+extern int mod_firmware_load(const char *, char **);
+EXPORT_SYMBOL(mod_firmware_load);
+
 #ifdef MODULE
 
 MODULE_DESCRIPTION("Core sound module");
 MODULE_AUTHOR("Alan Cox");
 
-extern int mod_firmware_load(const char *, char **);
-EXPORT_SYMBOL(mod_firmware_load);
-
-
 void cleanup_module(void)
 {
        /* We have nothing to really do here - we know the lists must be
diff --git a/drivers/sound/waveartist.c b/drivers/sound/waveartist.c
new file mode 100644 (file)
index 0000000..5a707a4
--- /dev/null
@@ -0,0 +1,1956 @@
+/*
+ * drivers/sound/waveartist.c
+ *
+ * The low level driver for the RWA010 Rockwell Wave Artist
+ * codec chip used in the Corel Computer NetWinder.
+ *
+ * Cleaned up and integrated into 2.1 by Russell King (rmk@arm.linux.org.uk)
+ */
+
+/*
+ * Copyright (C) by Corel Computer 1998
+ *
+ * RWA010 specs received under NDA from Rockwell
+ *
+ * Copyright (C) by Hannu Savolainen 1993-1997
+ *
+ * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
+ * Version 2 (June 1991). See the "COPYING" file distributed with this software
+ * for more info.
+ */
+
+/* Debugging */
+#define DEBUG_CMD      1
+#define DEBUG_OUT      2
+#define DEBUG_IN       4
+#define DEBUG_INTR     8
+#define DEBUG_MIXER    16
+#define DEBUG_TRIGGER  32
+
+#define debug_flg (0)
+
+#define DEB(x)
+#define DDB(x)
+#define DEB1(x)
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+
+#include <asm/hardware.h>
+
+#include "soundmodule.h"
+#include "sound_config.h"
+#include "waveartist.h"
+
+#define        VNC_TIMER_PERIOD (HZ/4) //check slider 4 times/sec
+
+#define        MIXER_PRIVATE3_RESET    0x53570000
+#define        MIXER_PRIVATE3_READ     0x53570001
+#define        MIXER_PRIVATE3_WRITE    0x53570002
+
+#define        VNC_INTERNAL_SPKR       0x01    //the sw mute on/off control bit
+#define        VNC_INTERNAL_MIC        0x10    //the hw internal/handset mic bit
+
+/* Use RECSRC = speaker to mark the internal microphone
+ *
+ * Some cheating involved here: there is no way to relay
+ * to the system, which microphone in in use
+ * (left = handset, or right = internal)
+ *
+ * So while I do not flag SPEAKER in the Recording Devices
+ * Mask, when on internal
+ *
+ * mike - I set the speaker bit hi. Some mixers can be
+ * confused a bit...
+ */
+
+#define POSSIBLE_RECORDING_DEVICES     (SOUND_MASK_LINE |\
+                                        SOUND_MASK_MIC |\
+                                        SOUND_MASK_LINE1)      //Line1 = analog phone
+
+#define SUPPORTED_MIXER_DEVICES                (SOUND_MASK_SYNTH |\
+                                        SOUND_MASK_PCM |\
+                                        SOUND_MASK_LINE |\
+                                        SOUND_MASK_MIC | \
+                                        SOUND_MASK_LINE1 |\
+                                        SOUND_MASK_RECLEV |\
+                                        SOUND_MASK_VOLUME)
+
+static unsigned short levels[SOUND_MIXER_NRDEVICES] = {
+       0x5555,         /* Master Volume         */
+       0x0000,         /* Bass                  */
+       0x0000,         /* Treble                */
+       0x5555,         /* Synth (FM)            */
+       0x4b4b,         /* PCM                   */
+       0x0000,         /* PC Speaker            */
+       0x0000,         /* Ext Line              */
+       0x0000,         /* Mic                   */
+       0x0000,         /* CD                    */
+       0x0000,         /* Recording monitor     */
+       0x0000,         /* SB PCM (ALT PCM)      */
+       0x0000,         /* Recording level       */
+       0x0000,         /* Input gain            */
+       0x0000,         /* Output gain           */
+       0x0000,         /* Line1 (Aux1)          */
+       0x0000,         /* Line2 (Aux2)          */
+       0x0000,         /* Line3 (Aux3)          */
+       0x0000,         /* Digital1              */
+       0x0000,         /* Digital2              */
+       0x0000,         /* Digital3              */
+       0x0000,         /* Phone In              */
+       0x0000,         /* Phone Out             */
+       0x0000,         /* Video                 */
+       0x0000,         /* Radio                 */
+       0x0000          /* Monitor               */
+};
+
+typedef struct {
+       struct address_info  hw;        /* hardware */
+       char            *chip_name;
+
+       int             xfer_count;
+       int             audio_mode;
+       int             open_mode;
+       int             audio_flags;
+       int             record_dev;
+       int             playback_dev;
+       int             dev_no;
+
+       /* Mixer parameters */
+       unsigned short  *levels;
+       int             handset_state;
+       signed int      slider_vol;        /* hardware slider volume */
+       int             recmask;           /* currently enabled recording device! */
+       int             supported_devices; /* SUPPORTED_MIXER_DEVICES */
+       int             rec_devices;       /* POSSIBLE_RECORDING_DEVICES */
+       int             handset_mute_sw :1;/* 1 - handset controlled in sw */
+       int             use_slider      :1;/* use slider setting for o/p vol */
+       int             mute_state      :1;
+} wavnc_info;
+
+typedef struct wavnc_port_info {
+       int             open_mode;
+       int             speed;
+       int             channels;
+       int             audio_format;
+} wavnc_port_info;
+
+static int              nr_waveartist_devs;
+static wavnc_info       adev_info[MAX_AUDIO_DEV];
+static struct timer_list vnc_timer;
+
+
+static inline void
+waveartist_set_ctlr(struct address_info *hw, unsigned char clear, unsigned char set)
+{
+       unsigned int ctlr_port = hw->io_base + CTLR;
+
+       clear = ~clear & inb(ctlr_port);
+
+       outb(clear | set, ctlr_port);
+}
+
+/* Toggle IRQ acknowledge line
+ */
+static inline void
+waveartist_iack(wavnc_info *devc)
+{
+       unsigned int ctlr_port = devc->hw.io_base + CTLR;
+       int old_ctlr;
+
+       old_ctlr = inb(ctlr_port) & ~IRQ_ACK;
+
+       outb(old_ctlr | IRQ_ACK, ctlr_port);
+       outb(old_ctlr, ctlr_port);
+}
+
+static inline int
+waveartist_sleep(int timeout_ms)
+{
+       unsigned int timeout = timeout_ms * 10 * HZ / 100;
+
+       do {
+               current->state = TASK_INTERRUPTIBLE;
+               timeout = schedule_timeout(timeout);
+       } while (timeout);
+
+       return 0;
+}
+
+static int
+waveartist_reset(wavnc_info *devc)
+{
+       struct address_info *hw = &devc->hw;
+       unsigned int timeout, res = -1;
+
+       waveartist_set_ctlr(hw, -1, RESET);
+       waveartist_sleep(2);
+       waveartist_set_ctlr(hw, RESET, 0);
+
+       timeout = 500;
+       do {
+               mdelay(2);
+
+               if (inb(hw->io_base + STATR) & CMD_RF) {
+                       res = inw(hw->io_base + CMDR);
+                       if (res == 0x55aa)
+                               break;
+               }
+       } while (timeout--);
+
+       if (timeout == 0) {
+               printk("WaveArtist: reset timeout ");
+               if (res != (unsigned int)-1)
+                       printk("(res=%04X)", res);
+               printk("\n");
+               return 1;
+       }
+       return 0;
+}
+
+static int
+waveartist_cmd(wavnc_info *devc,
+               int nr_cmd, unsigned int *cmd,
+               int nr_resp, unsigned int *resp)
+{
+       unsigned int io_base = devc->hw.io_base;
+       unsigned int timed_out = 0;
+       unsigned int i;
+
+       if (debug_flg & DEBUG_CMD) {
+               printk("waveartist_cmd: cmd=");
+
+               for (i = 0; i < nr_cmd; i++)
+                       printk("%04X ", cmd[i]);
+
+               printk("\n");
+       }
+
+       if (inb(io_base + STATR) & CMD_RF) {
+               int old_data;
+
+               /* flush the port
+                */
+
+               old_data = inw(io_base + CMDR);
+
+               if (debug_flg & DEBUG_CMD)
+                       printk("flushed %04X...", old_data);
+
+               udelay(10);
+       }
+
+       for (i = 0; !timed_out && i < nr_cmd; i++) {
+               int count;
+
+               for (count = 5000; count; count--)
+                       if (inb(io_base + STATR) & CMD_WE)
+                               break;
+
+               if (!count)
+                       timed_out = 1;
+               else
+                       outw(cmd[i], io_base + CMDR);
+       }
+
+       for (i = 0; !timed_out && i < nr_resp; i++) {
+               int count;
+
+               for (count = 5000; count; count--)
+                       if (inb(io_base + STATR) & CMD_RF)
+                               break;
+
+               if (!count)
+                       timed_out = 1;
+               else
+                       resp[i] = inw(io_base + CMDR);
+       }
+
+       if (debug_flg & DEBUG_CMD) {
+               if (!timed_out) {
+                       printk("waveartist_cmd: resp=");
+
+                       for (i = 0; i < nr_resp; i++)
+                               printk("%04X ", resp[i]);
+
+                       printk("\n");
+               } else
+                       printk("waveartist_cmd: timed out\n");
+       }
+
+       return timed_out ? 1 : 0;
+}
+
+static inline int
+waveartist_cmd2(wavnc_info *devc, unsigned int cmd, unsigned int arg)
+{
+       unsigned int vals[2];
+
+       vals[0] = cmd;
+       vals[1] = arg;
+
+       waveartist_cmd(devc, 2, vals, 1, vals);
+
+       return 0;
+}
+
+static inline int
+waveartist_cmd3(wavnc_info *devc, unsigned int cmd,
+               unsigned int arg1, unsigned int arg2)
+{
+       unsigned int vals[3];
+
+       vals[0] = cmd;
+       vals[1] = arg1;
+       vals[2] = arg2;
+
+       return waveartist_cmd(devc, 3, vals, 0, NULL);
+}
+
+static int
+waveartist_sendcmd(struct address_info *hw, unsigned int cmd)
+{
+       int count;
+
+       if (debug_flg & DEBUG_CMD)
+               printk("waveartist_sendcmd: cmd=0x%04X...", cmd);
+
+       udelay(10);
+
+       if (inb(hw->io_base + STATR) & CMD_RF) {
+               /*
+                * flush the port
+                */
+               count = inw(hw->io_base + CMDR);
+
+               udelay(10);
+
+               if (debug_flg & DEBUG_CMD)
+                       printk(" flushed %04X...", count);
+       }
+
+       /*
+        * preset timeout at 5000 loops
+        */
+       count = 5000;
+
+       while (count --)
+               if (inb(hw->io_base + STATR) & CMD_WE) {
+                       /* wait till CMD_WE is high
+                        * then output the command
+                        */
+                       outw(cmd, hw->io_base + CMDR);
+                       break;
+               }
+
+       /* ready BEFORE timeout?
+        */
+       if (debug_flg & DEBUG_CMD)
+               printk(" %s\n", count ? "Done OK." : "Error!");
+
+       udelay(10);
+
+       return count ? 0 : 1;
+}
+
+static int
+waveartist_getrev(struct address_info *hw, char *rev)
+{
+       int temp;
+
+       waveartist_sendcmd(hw, 0);
+       udelay(20);
+       temp = inw(hw->io_base + CMDR);
+       udelay(20);
+       inw(hw->io_base + CMDR);        // discard second word == 0
+
+       rev[0] = temp >> 8;
+       rev[1] = temp & 255;
+       rev[2] = '\0';
+
+       return temp;
+}
+
+inline void
+waveartist_mute(wavnc_info *devc, int mute)
+{
+}
+
+static void waveartist_halt_output(int dev);
+static void waveartist_halt_input(int dev);
+static void waveartist_halt(int dev);
+static void waveartist_trigger(int dev, int state);
+
+static int
+waveartist_open(int dev, int mode)
+{
+       wavnc_info      *devc;
+       wavnc_port_info *portc;
+       unsigned long   flags;
+
+       if (dev < 0 || dev >= num_audiodevs)
+               return -ENXIO;
+
+       devc  = (wavnc_info *) audio_devs[dev]->devc;
+       portc = (wavnc_port_info *) audio_devs[dev]->portc;
+
+       save_flags(flags);
+       cli();
+       if (portc->open_mode || (devc->open_mode & mode)) {
+               restore_flags(flags);
+               return -EBUSY;
+       }
+
+       devc->audio_mode  = 0;
+       devc->open_mode  |= mode;
+       portc->open_mode  = mode;
+       waveartist_trigger(dev, 0);
+
+       if (mode & OPEN_READ)
+               devc->record_dev = dev;
+       if (mode & OPEN_WRITE)
+               devc->playback_dev = dev;
+       restore_flags(flags);
+
+       /*
+        * Mute output until the playback really starts. This
+        * decreases clicking (hope so).
+        */
+       waveartist_mute(devc, 1);
+
+       return 0;
+}
+
+static void
+waveartist_close(int dev)
+{
+       wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
+       wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
+       unsigned long   flags;
+
+       save_flags(flags);
+       cli();
+
+       waveartist_halt(dev);
+
+       devc->audio_mode = 0;
+       devc->open_mode &= ~portc->open_mode;
+       portc->open_mode = 0;
+
+       waveartist_mute(devc, 1);
+
+       restore_flags(flags);
+}
+
+static void
+waveartist_output_block(int dev, unsigned long buf, int __count, int intrflag)
+{
+       wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
+       wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
+       unsigned long   flags;
+       unsigned int    count = __count; 
+
+       if (debug_flg & DEBUG_OUT)
+               printk("waveartist: output block, buf=0x%lx, count=0x%x...\n",
+                       buf, count);
+       /*
+        * 16 bit data
+        */
+       if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE))
+               count >>= 1;
+
+       if (portc->channels > 1)
+               count >>= 1;
+
+       count -= 1;
+
+       if (devc->audio_mode & PCM_ENABLE_OUTPUT &&
+           audio_devs[dev]->flags & DMA_AUTOMODE &&
+           intrflag &&
+           count == devc->xfer_count) {
+               devc->audio_mode |= PCM_ENABLE_OUTPUT;
+               return; /*
+                        * Auto DMA mode on. No need to react
+                        */
+       }
+
+       save_flags(flags);
+       cli();
+
+       /*
+        * set sample count
+        */
+       waveartist_cmd2(devc, 0x0024, count);
+
+       devc->xfer_count = count;
+       devc->audio_mode |= PCM_ENABLE_OUTPUT;
+
+       restore_flags(flags);
+}
+
+static void
+waveartist_start_input(int dev, unsigned long buf, int __count, int intrflag)
+{
+       wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
+       wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
+       unsigned long   flags;
+       unsigned int    count = __count;
+
+       if (debug_flg & DEBUG_IN)
+               printk("waveartist: start input, buf=0x%lx, count=0x%x...\n",
+                       buf, count);
+
+       if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE))  /* 16 bit data */
+               count >>= 1;
+
+       if (portc->channels > 1)
+               count >>= 1;
+
+       count -= 1;
+
+       if (devc->audio_mode & PCM_ENABLE_INPUT &&
+           audio_devs[dev]->flags & DMA_AUTOMODE &&
+           intrflag &&
+           count == devc->xfer_count) {
+               devc->audio_mode |= PCM_ENABLE_INPUT;
+               return; /*
+                        * Auto DMA mode on. No need to react
+                        */
+       }
+
+       save_flags(flags);
+       cli();
+
+       /*
+        * set sample count
+        */
+       waveartist_cmd2(devc, 0x0014, count);
+       waveartist_mute(devc, 0);
+
+       devc->xfer_count = count;
+       devc->audio_mode |= PCM_ENABLE_INPUT;
+
+       restore_flags(flags);
+}
+
+static int
+waveartist_ioctl(int dev, unsigned int cmd, caddr_t arg)
+{
+       return -EINVAL;
+}
+
+static unsigned int
+waveartist_get_speed(wavnc_port_info *portc)
+{
+       unsigned int speed;
+
+       /*
+        * program the speed, channels, bits
+        */
+       if (portc->speed == 8000)
+               speed = 0x2E71;
+       else if (portc->speed == 11025)
+               speed = 0x4000;
+       else if (portc->speed == 22050)
+               speed = 0x8000;
+       else if (portc->speed == 44100)
+               speed = 0x0;
+       else {
+               /*
+                * non-standard - just calculate
+                */
+               speed = portc->speed << 16;
+
+               speed = (speed / 44100) & 65535;
+       }
+
+       return speed;
+}
+
+static unsigned int
+waveartist_get_bits(wavnc_port_info *portc)
+{
+       unsigned int bits;
+
+       if (portc->audio_format == AFMT_S16_LE)
+               bits = 1;
+       else if (portc->audio_format == AFMT_S8)
+               bits = 0;
+       else
+               bits = 2;       //default AFMT_U8
+
+       return bits;
+}
+
+static int
+waveartist_prepare_for_input(int dev, int bsize, int bcount)
+{
+       unsigned long   flags;
+       wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
+       wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
+       unsigned int    speed, bits;
+
+       if (devc->audio_mode)
+               return 0;
+
+       speed = waveartist_get_speed(portc);
+       bits  = waveartist_get_bits(portc);
+
+       save_flags(flags);
+       cli();
+
+       if (waveartist_cmd2(devc, WACMD_INPUTFORMAT, bits))
+               printk("waveartist: error setting the record format to %d\n",
+                      portc->audio_format);
+
+       if (waveartist_cmd2(devc, WACMD_INPUTCHANNELS, portc->channels))
+               printk("waveartist: error setting record to %d channels\n",
+                      portc->channels);
+
+       /*
+        * write cmd SetSampleSpeedTimeConstant
+        */
+       if (waveartist_cmd2(devc, WACMD_INPUTSPEED, speed))
+               printk("waveartist: error setting the record speed "
+                      "to %dHz.\n", portc->speed);
+
+       if (waveartist_cmd2(devc, WACMD_INPUTDMA, 1))
+               printk("waveartist: error setting the record data path "
+                      "to 0x%X\n", 1);
+
+       if (waveartist_cmd2(devc, WACMD_INPUTFORMAT, bits))
+               printk("waveartist: error setting the record format to %d\n",
+                      portc->audio_format);
+
+       devc->xfer_count = 0;
+       restore_flags(flags);
+       waveartist_halt_input(dev);
+
+       if (debug_flg & DEBUG_INTR) {
+               printk("WA CTLR reg: 0x%02X.\n",inb(devc->hw.io_base + CTLR));
+               printk("WA STAT reg: 0x%02X.\n",inb(devc->hw.io_base + STATR));
+               printk("WA IRQS reg: 0x%02X.\n",inb(devc->hw.io_base + IRQSTAT));
+       }
+
+       return 0;
+}
+
+static int
+waveartist_prepare_for_output(int dev, int bsize, int bcount)
+{
+       unsigned long   flags;
+       wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
+       wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
+       unsigned int    speed, bits;
+
+       /*
+        * program the speed, channels, bits
+        */
+       speed = waveartist_get_speed(portc);
+       bits  = waveartist_get_bits(portc);
+
+       save_flags(flags);
+       cli();
+
+       if (waveartist_cmd2(devc, WACMD_OUTPUTSPEED, speed) &&
+           waveartist_cmd2(devc, WACMD_OUTPUTSPEED, speed))
+               printk("waveartist: error setting the playback speed "
+                      "to %dHz.\n", portc->speed);
+
+       if (waveartist_cmd2(devc, WACMD_OUTPUTCHANNELS, portc->channels))
+               printk("waveartist: error setting the playback to"
+                      " %d channels\n", portc->channels);
+
+       if (waveartist_cmd2(devc, WACMD_OUTPUTDMA, 0))
+               printk("waveartist: error setting the playback data path "
+                      "to 0x%X\n", 0);
+
+       if (waveartist_cmd2(devc, WACMD_OUTPUTFORMAT, bits))
+               printk("waveartist: error setting the playback format to %d\n",
+                      portc->audio_format);
+
+       devc->xfer_count = 0;
+       restore_flags(flags);
+       waveartist_halt_output(dev);
+
+       if (debug_flg & DEBUG_INTR) {
+               printk("WA CTLR reg: 0x%02X.\n",inb(devc->hw.io_base + CTLR));
+               printk("WA STAT reg: 0x%02X.\n",inb(devc->hw.io_base + STATR));
+               printk("WA IRQS reg: 0x%02X.\n",inb(devc->hw.io_base + IRQSTAT));
+       }
+
+       return 0;
+}
+
+static void
+waveartist_halt(int dev)
+{
+       wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
+       wavnc_info      *devc;
+
+
+       if (portc->open_mode & OPEN_WRITE)
+               waveartist_halt_output(dev);
+
+       if (portc->open_mode & OPEN_READ)
+               waveartist_halt_input(dev);
+
+       devc = (wavnc_info *) audio_devs[dev]->devc;
+       devc->audio_mode = 0;
+}
+
+static void
+waveartist_halt_input(int dev)
+{
+       wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
+       unsigned long   flags;
+
+       save_flags(flags);
+       cli();
+
+       waveartist_mute(devc, 1);
+
+//RMK  disable_dma(audio_devs[dev]->dmap_in->dma);
+
+       /*
+        * Stop capture
+        */
+       waveartist_sendcmd(&devc->hw, 0x17);
+
+//RMK  enable_dma(audio_devs[dev]->dmap_in->dma);
+       devc->audio_mode &= ~PCM_ENABLE_INPUT;
+
+       /*
+        * Clear interrupt by toggling
+        * the IRQ_ACK bit in CTRL
+        */
+       if (inb(devc->hw.io_base + STATR) & IRQ_REQ)
+               waveartist_iack(devc);
+
+//     devc->audio_mode &= ~PCM_ENABLE_INPUT;
+
+       restore_flags(flags);
+}
+
+static void
+waveartist_halt_output(int dev)
+{
+       wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
+       unsigned long   flags;
+
+       save_flags(flags);
+       cli();
+
+       waveartist_mute(devc, 1);
+
+//RMK  disable_dma(audio_devs[dev]->dmap_out->dma);
+
+       waveartist_sendcmd(&devc->hw, 0x27);
+
+//RMK  enable_dma(audio_devs[dev]->dmap_out->dma);
+
+       devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
+
+       /*
+        * Clear interrupt by toggling
+        * the IRQ_ACK bit in CTRL
+        */
+       if (inb(devc->hw.io_base + STATR) & IRQ_REQ)
+               waveartist_iack(devc);
+
+//     devc->audio_mode &= ~PCM_ENABLE_OUTPUT;
+
+       restore_flags(flags);
+}
+
+static void
+waveartist_trigger(int dev, int state)
+{
+       wavnc_info      *devc = (wavnc_info *) audio_devs[dev]->devc;
+       wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
+       unsigned long   flags;
+
+       if (debug_flg & DEBUG_TRIGGER) {
+               printk("wavnc: audio trigger ");
+               if (state & PCM_ENABLE_INPUT)
+                       printk("in ");
+               if (state & PCM_ENABLE_OUTPUT)
+                       printk("out");
+               printk("\n");
+       }
+
+       save_flags(flags);
+       cli();
+
+       state &= devc->audio_mode;
+
+       if (portc->open_mode & OPEN_READ &&
+           state & PCM_ENABLE_INPUT)
+               /*
+                * enable ADC Data Transfer to PC
+                */
+               waveartist_sendcmd(&devc->hw, 0x15);
+
+       if (portc->open_mode & OPEN_WRITE &&
+           state & PCM_ENABLE_OUTPUT)
+               /*
+                * enable DAC data transfer from PC
+                */
+               waveartist_sendcmd(&devc->hw, 0x25);
+
+       waveartist_mute(devc, 0);
+
+       restore_flags(flags);
+}
+
+static int
+waveartist_set_speed(int dev, int arg)
+{
+       wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
+
+       if (arg <= 0)
+               return portc->speed;
+
+       if (arg < 5000)
+               arg = 5000;
+       if (arg > 44100)
+               arg = 44100;
+
+       portc->speed = arg;
+       return portc->speed;
+
+}
+
+static short
+waveartist_set_channels(int dev, short arg)
+{
+       wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
+
+       if (arg != 1 && arg != 2)
+               return portc->channels;
+
+       portc->channels = arg;
+       return arg;
+}
+
+static unsigned int
+waveartist_set_bits(int dev, unsigned int arg)
+{
+       wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
+
+       if (arg == 0)
+               return portc->audio_format;
+
+       if ((arg != AFMT_U8) && (arg != AFMT_S16_LE) && (arg != AFMT_S8))
+               arg = AFMT_U8;
+
+       portc->audio_format = arg;
+
+       return arg;
+}
+
+static struct audio_driver waveartist_audio_driver = {
+       waveartist_open,
+       waveartist_close,
+       waveartist_output_block,
+       waveartist_start_input,
+       waveartist_ioctl,
+       waveartist_prepare_for_input,
+       waveartist_prepare_for_output,
+       waveartist_halt,
+       NULL,
+       NULL,
+       waveartist_halt_input,
+       waveartist_halt_output,
+       waveartist_trigger,
+       waveartist_set_speed,
+       waveartist_set_bits,
+       waveartist_set_channels
+};
+
+
+static void
+waveartist_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+       wavnc_info *devc = (wavnc_info *)dev_id;
+       int        irqstatus, status;
+
+       irqstatus = inb(devc->hw.io_base + IRQSTAT);
+       status    = inb(devc->hw.io_base + STATR);
+
+       if (debug_flg & DEBUG_INTR)
+               printk("waveartist_intr: stat=%02x, irqstat=%02x\n",
+                      status, irqstatus);
+
+       if (status & IRQ_REQ)   /* Clear interrupt */
+               waveartist_iack(devc);
+       else
+               printk("waveartist: unexpected interrupt\n");
+
+#ifdef CONFIG_AUDIO
+       if (irqstatus & 0x01) {
+               int temp = 1;
+
+               /* PCM buffer done
+                */
+               if ((status & DMA0) && (devc->audio_mode & PCM_ENABLE_OUTPUT)) {
+                       DMAbuf_outputintr(devc->playback_dev, 1);
+                       temp = 0;
+               }
+               if ((status & DMA1) && (devc->audio_mode & PCM_ENABLE_INPUT)) {
+                       DMAbuf_inputintr(devc->record_dev);
+                       temp = 0;
+               }
+               if (temp)       //default:
+                       printk("WaveArtist: Unknown interrupt\n");
+       }
+#endif
+       if (irqstatus & 0x2)
+               // We do not use SB mode natively...
+               printk("WaveArtist: Unexpected SB interrupt...\n");
+}
+
+/* -------------------------------------------------------------------------
+ * Mixer stuff
+ */
+static void
+waveartist_mixer_update(wavnc_info *devc, int whichDev)
+{
+       unsigned int mask, reg_l, reg_r;
+       unsigned int lev_left, lev_right;
+       unsigned int vals[3];
+
+       lev_left  = devc->levels[whichDev] & 0xff;
+       lev_right = devc->levels[whichDev] >> 8;
+
+#define SCALE(lev,max) ((lev) * (max) / 100)
+
+       switch(whichDev) {
+       case SOUND_MIXER_VOLUME:
+               mask  = 0x000e;
+               reg_l = 0x200;
+               reg_r = 0x600;
+               lev_left  = SCALE(lev_left,  7) << 1;
+               lev_right = SCALE(lev_right, 7) << 1;
+               break;
+
+       case SOUND_MIXER_LINE:
+               mask  = 0x07c0;
+               reg_l = 0x000;
+               reg_r = 0x400;
+               lev_left  = SCALE(lev_left,  31) << 6;
+               lev_right = SCALE(lev_right, 31) << 6;
+               break;
+
+       case SOUND_MIXER_MIC:
+               mask  = 0x0030;
+               reg_l = 0x200;
+               reg_r = 0x600;
+               lev_left  = SCALE(lev_left,  3) << 4;
+               lev_right = SCALE(lev_right, 3) << 4;
+               break;
+
+       case SOUND_MIXER_RECLEV:
+               mask  = 0x000f;
+               reg_l = 0x300;
+               reg_r = 0x700;
+               lev_left  = SCALE(lev_left,  10);
+               lev_right = SCALE(lev_right, 10);
+               break;
+
+       case SOUND_MIXER_LINE1:
+               mask  = 0x003e;
+               reg_l = 0x000;
+               reg_r = 0x400;
+               lev_left  = SCALE(lev_left,  31) << 1;
+               lev_right = SCALE(lev_right, 31) << 1;
+               break;
+
+       case SOUND_MIXER_PCM:
+               waveartist_cmd3(devc, 0x0031, SCALE(lev_left,  32767),
+                               SCALE(lev_right, 32767));
+               return;
+
+       case SOUND_MIXER_SYNTH:
+               waveartist_cmd3(devc, 0x0131, SCALE(lev_left,  32767),
+                               SCALE(lev_right, 32767));
+               return;
+
+       default:
+               return;
+       }
+
+       /* read left setting */
+       vals[0] = reg_l + 0x30;
+       waveartist_cmd(devc, 1, vals, 1, vals + 1);
+
+       /* read right setting */
+       vals[0] = reg_r + 0x30;
+       waveartist_cmd(devc, 1, vals, 1, vals + 2);
+
+       vals[1] = (vals[1] & ~mask) | (lev_left  & mask);
+       vals[2] = (vals[2] & ~mask) | (lev_right & mask);
+
+       /* write left,right back */
+       vals[0] = 0x32;
+       waveartist_cmd(devc, 3, vals, 0, NULL);
+}
+
+static void
+waveartist_select_input(wavnc_info *devc, unsigned int input)
+{
+       unsigned int vals[3];
+#if 1
+       /* New mixer programming - switch recording source
+        * using R/L_ADC_Mux_Select.  We are playing with
+        * left/right mux bit fields in reg 9.
+        *
+        * We can not switch Mux_Select while recording, so
+        * for microphones, enable both left and right and
+        * play with levels only!
+        *
+        * Unfortunately, we need to select the src of mono
+        * recording (left or right) before starting the
+        * recording - so can not dynamically switch between
+        * handset amd internal microphones...
+        */
+
+       /*
+        * Get reg 9
+        */
+       vals[0] = 0x0830;
+       waveartist_cmd(devc, 1, vals, 1, vals + 1);
+
+       /*
+        * Get reg 10, only so that we can write it back.
+        */
+       vals[0] = 0x0930;
+       waveartist_cmd(devc, 1, vals, 1, vals + 2);
+
+       if (debug_flg & DEBUG_MIXER)
+               printk("RECSRC: old left: 0x%04X, old right: 0x%04X.\n",
+                       vals[1] & 0x07, (vals[1] >> 3) & 0x07);
+
+       vals[1] &= ~0x03F;      //kill current left/right mux input select
+
+       switch (input) {
+               /*
+                * Handset or internal MIC
+                */
+       case SOUND_MASK_MIC:
+               /*
+                * handset not plugged in?
+                */
+               if (devc->handset_state & VNC_INTERNAL_MIC) {
+                       /*
+                        * set mono recording from right mic
+                        */
+                       waveartist_sendcmd(&devc->hw, 0x0134);
+#if 0
+                       /*
+                        * right=mic, left=none
+                        */
+                       vals[1] |= 0x0028;
+                       /*
+                        * pretend int mic
+                        */
+                       devc->rec_devices |= SOUND_MASK_SPEAKER;
+#endif
+               } else {
+                       /*
+                        * set mono rec from left mic
+                        */
+                       waveartist_sendcmd(&devc->hw, 0x0034);
+#if 0
+                       /*
+                        * right=none, left=mic
+                        */
+                       vals[1] |= 0x0005;
+                       /*
+                        * show no int mic
+                        */
+                       devc->rec_devices &= ~SOUND_MASK_SPEAKER;
+#endif
+               }
+               /*
+                * right=mic, left=mic
+                */
+               vals[1] |= 0x002D;
+               break;
+
+       case SOUND_MASK_LINE1:
+               /*
+                * set mono rec from left aux1
+                */
+               waveartist_sendcmd(&devc->hw, 0x0034);
+               /*
+                * right=none, left=Aux1;
+                */
+               vals[1] |= 0x0004;
+               break;
+
+       case SOUND_MASK_LINE:
+               /*
+                * set mono rec from left (default)
+                */
+               waveartist_sendcmd(&devc->hw, 0x0034);
+               /*
+                * right=Line, left=Line;
+                */
+               vals[1] |= 0x0012;
+               break;
+       }
+
+       if (debug_flg & DEBUG_MIXER)
+               printk("RECSRC %d: left=0x%04X, right=0x%04X.\n", input,
+                       vals[1] & 0x07, (vals[1] >> 3) & 0x07);
+
+#else
+       /* This part is good, if input connected to
+        * a mixer, so can be used for record-only modes...
+        */
+
+       /*
+        * get reg 4
+        */
+       vals[0] = 0x0330;
+       waveartist_cmd(devc, 1, vals, 1, vals + 1);
+
+       /*
+        * get reg 8
+        */
+       vals[0] = 0x0730;
+       waveartist_cmd(devc, 1, vals, 1, vals + 2);
+
+       if (debug_flg & DEBUG_MIXER)
+               printk("RECSRC: old left: 0x%04X, old right: 0x%04X.\n",
+                       vals[1], vals[2]);
+
+       /*
+        * kill current left/right mux input select
+        */
+       vals[1] &= ~0x07F8;
+       vals[2] &= ~0x07F8;
+
+       switch (input) {
+               /*
+                * handset or internal mic
+                */
+       case SOUND_MASK_MIC:
+               /*
+                * handset not plugged in?
+                */
+               if (devc->handset_state & VNC_INTERNAL_MIC) {
+                       /*
+                        * set mono recording from right mic
+                        */
+                       waveartist_sendcmd(&devc->hw, 0x0134);
+                       /*
+                        * left = none, right = mic, RX filter gain
+                        */
+                       vals[1] |= 0x0C00;
+                       vals[2] |= 0x0C88;
+                       /*
+                        * pretend int mic
+                        */
+                       devc->rec_devices |= SOUND_MASK_SPEAKER;
+               } else {
+                       /*
+                        * set mono rec from left mic
+                        */
+                       waveartist_sendcmd(&devc->hw, 0x0034);
+                       /*
+                        * left = mic, RX filter gain, right = none;
+                        */
+                       vals[1] |= 0x0C88;
+                       vals[2] |= 0x0C00;
+                       /*
+                        * show no int mic
+                        */
+                       devc->rec_devices &= ~SOUND_MASK_SPEAKER;
+               }
+               break;
+
+       case SOUND_MASK_LINE1:
+               /*
+                * set mono rec from left aux1
+                */
+               waveartist_sendcmd(&devc->hw, 0x0034);
+               /*
+                * left = Aux1, right = none
+                */
+               vals[1] |= 0x0C40;
+               vals[2] |= 0x0C00;
+               break;
+       
+       case SOUND_MASK_LINE:
+               /*
+                * left = Line, right = Line
+                */
+               vals[1] |= 0x0C10;
+               vals[2] |= 0x0C10;
+               break;
+       }
+
+       if (debug_flg & DEBUG_MIXER)
+               printk("RECSRC %d: left(4) 0x%04X, right(8) 0x%04X.\n",
+                       level, vals[1], vals[2]);
+#endif
+       /*
+        * and finally - write the reg pair back....
+        */
+       vals[0] = 0x32;
+
+       waveartist_cmd(devc, 3, vals, 0, NULL);
+}
+
+static int
+waveartist_mixer_set(wavnc_info *devc, int whichDev, unsigned int level)
+{
+       unsigned int lev_left  = level & 0x007f;
+       unsigned int lev_right = (level & 0x7f00) >> 8;
+
+       int left, right, devmask, changed, i;
+
+       left = level & 0x7f;
+       right = (level & 0x7f00) >> 8;
+
+       if (debug_flg & DEBUG_MIXER)
+               printk("wa_mixer_set(dev=%d, level=%X)\n",
+                       whichDev, level);
+
+       switch (whichDev) {
+       /* Master volume (0-7)
+        * We have 3 bits on the Left/Right Mixer Gain,
+        * bits 3,2,1 on 3 and 7
+        */
+       case SOUND_MIXER_VOLUME:
+               devc->levels[whichDev] = lev_left | lev_right << 8;
+               waveartist_mixer_update(devc, whichDev);
+               break;
+
+
+       /* External line (0-31)
+        * use LOUT/ROUT bits 10...6, reg 1 and 5
+        */
+       case SOUND_MIXER_LINE:
+               devc->levels[whichDev] = lev_left | lev_right << 8;
+               waveartist_mixer_update(devc, whichDev);
+               break;
+
+       /* Mono microphone (0-3) mute,
+        * 0db,10db,20db
+        */
+       case SOUND_MIXER_MIC:
+#if 1
+               devc->levels[whichDev] = lev_left | lev_right << 8;
+#else
+               /* we do not need to mute volume of
+                * an unused mic - it is simply unused...
+                */
+               if (devc->handset_state & VNC_INTERNAL_MIC)
+                       devc->levels[whichDev] = lev_right << 8;
+               else
+                       levels[whichDev] = lev_left;
+#endif
+               waveartist_mixer_update(devc, whichDev);
+               break;
+
+       /* Recording level (0-7)
+        */
+       case SOUND_MIXER_RECLEV:
+               devc->levels[whichDev] = lev_left | lev_right << 8;
+               waveartist_mixer_update(devc, whichDev);
+               break;
+
+       /* Mono External Aux1 (0-31)
+        * use LINE1 bits 5...1, reg 1 and 5
+        */
+       case SOUND_MIXER_LINE1:
+               devc->levels[whichDev] = lev_left | lev_right << 8;
+               waveartist_mixer_update(devc, whichDev);
+               break;
+
+       /* WaveArtist PCM (0-32767)
+        */
+       case SOUND_MIXER_PCM:
+               devc->levels[whichDev] = lev_left | lev_right << 8;
+               waveartist_mixer_update(devc, whichDev);
+               break;
+
+       /* Internal synthesizer (0-31)
+        */
+       case SOUND_MIXER_SYNTH:
+               devc->levels[whichDev] = lev_left | lev_right << 8;
+               waveartist_mixer_update(devc, whichDev);
+               break;
+
+
+       /* Select recording input source
+        */
+       case SOUND_MIXER_RECSRC:
+               devmask = level & POSSIBLE_RECORDING_DEVICES;
+
+               changed = devmask ^ devc->recmask;
+               devc->recmask = devmask;
+
+               for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+                       if (changed & (1 << i))
+                               waveartist_mixer_update(devc, i);
+
+               waveartist_select_input(devc, level);
+               /*
+                * do not save in "levels", return current setting
+                */
+               return devc->recmask;
+
+       default:
+               return -EINVAL;
+       }
+
+       return devc->levels[whichDev];
+}
+
+static void
+waveartist_mixer_reset(wavnc_info *devc)
+{
+       int i;
+
+       if (debug_flg & DEBUG_MIXER)
+               printk("%s: mixer_reset\n", devc->hw.name);
+
+       /*
+        * reset mixer cmd
+        */
+       waveartist_sendcmd(&devc->hw, 0x33);
+
+       /*
+        * set input for ADC to come from
+        * a mux (left and right) == reg 9,
+        * initially none
+        */
+       waveartist_cmd3(devc, 0x0032, 0x9800, 0xa836);
+
+       /*
+        * set mixer input select to none, RX filter gains 0 db
+        */
+       waveartist_cmd3(devc, 0x0032, 0x4c00, 0x8c00);
+
+       /*
+        * set bit 0 reg 2 to 1 - unmute MonoOut
+        */
+       waveartist_cmd3(devc, 0x0032, 0x2801, 0x6800);
+
+       for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+               waveartist_mixer_update(devc, i);
+
+       /* set default input device = internal mic
+        * current recording device = none
+        * no handset
+        */
+       devc->recmask = 0;
+       devc->handset_state = VNC_INTERNAL_MIC;
+//     waveartist_mixer_set(devc, SOUND_MIXER_RECSRC, SOUND_MASK_MIC);
+
+       /*
+        * start from enabling the hw setting
+        */
+       devc->handset_mute_sw = 0;
+       devc->supported_devices = SUPPORTED_MIXER_DEVICES;
+       devc->rec_devices = POSSIBLE_RECORDING_DEVICES;
+}
+
+static int
+waveartist_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
+{
+       wavnc_info *devc = (wavnc_info *)audio_devs[dev]->devc;
+#if 0
+       //use this call to override the automatic handset behaviour - ignore handset
+       //bit 0x80 = total control over handset - do not react to plug/unplug
+       //bit 0x10 = 1 == internal mic, otherwise handset mic
+       //bit 0x01 = 1 == mute internal speaker, otherwise unmute
+
+       if (cmd == SOUND_MIXER_PRIVATE1) {
+               int             val, temp;
+
+               val = *(int *) arg;
+
+//             printk("MIXER_PRIVATE1: passed parameter = 0x%X.\n",val);
+               return -EINVAL;         //check if parameter is logical...
+
+               devc->soft_mute_flag = val;
+
+               temp = val & VNC_INTERNAL_SPKR;
+               if (temp != devc->mute_state) {
+//                     printk("MIXER_PRIVATE1: mute_mono(0x%X).\n",temp);
+                       vnc_mute(devc, temp);
+               }
+
+//             temp = devc->handset_state;
+
+               // do not check if it is not already in
+               // the right setting, since we are
+               // laying about the current state...
+
+//             if ((val & VNC_INTERNAL_MIC) != temp) {
+                       devc->handset_state = val & VNC_INTERNAL_MIC;
+//                     printk("MIXER_PRIVATE1: mixer_set(0x%X).\n",devc->handset_state);
+                       wa_mixer_set(devc, SOUND_MIXER_RECSRC, SOUND_MASK_MIC);
+//                     devc->handset_state = temp;
+               }
+               return 0;
+       }
+#if 0
+       if (cmd == SOUND_MIXER_PRIVATE2) {
+#define VNC_SOUND_PAUSE         0x53    //to pause the DSP
+#define VNC_SOUND_RESUME        0x57    //to unpause the DSP
+               int             val;
+
+               val = *(int *) arg;
+
+               printk("MIXER_PRIVATE2: passed parameter = 0x%X.\n",val);
+
+               if (val == VNC_SOUND_PAUSE) {
+                       wa_sendcmd(0x16);    //PAUSE the ADC
+               } else if (val == VNC_SOUND_RESUME) {
+                       wa_sendcmd(0x18);    //RESUME the ADC
+               } else {
+                       return -EINVAL;      //invalid parameters...
+               }
+               return 0;
+       }
+#endif
+
+       if (cmd == SOUND_MIXER_PRIVATE3) {
+               long unsigned   flags;
+               int             mixer_reg[15];  //reg 14 is actually a command: read,write,reset
+
+               int             val;
+               int             i;
+
+               val = *(int *) arg;
+
+               if (verify_area(VERIFY_READ, (void *) val, sizeof(mixer_reg) == -EFAULT))
+                       return (-EFAULT);
+
+               memcpy_fromfs(&mixer_reg, (void *) val, sizeof(mixer_reg));
+
+               if (mixer_reg[0x0E] == MIXER_PRIVATE3_RESET) {  //reset command??
+                       wavnc_mixer_reset(devc);
+                       return (0);
+               } else if (mixer_reg[0x0E] == MIXER_PRIVATE3_WRITE) {   //write command??
+//                     printk("WaveArtist Mixer: Private write command.\n");
+
+                       wa_sendcmd(0x32);       //Pair1 - word 1 and 5
+                       wa_sendcmd(mixer_reg[0]);
+                       wa_sendcmd(mixer_reg[4]);
+
+                       wa_sendcmd(0x32);       //Pair2 - word 2 and 6
+                       wa_sendcmd(mixer_reg[1]);
+                       wa_sendcmd(mixer_reg[5]);
+
+                       wa_sendcmd(0x32);       //Pair3 - word 3 and 7
+                       wa_sendcmd(mixer_reg[2]);
+                       wa_sendcmd(mixer_reg[6]);
+
+                       wa_sendcmd(0x32);       //Pair4 - word 4 and 8
+                       wa_sendcmd(mixer_reg[3]);
+                       wa_sendcmd(mixer_reg[7]);
+
+                       wa_sendcmd(0x32);       //Pair5 - word 9 and 10
+                       wa_sendcmd(mixer_reg[8]);
+                       wa_sendcmd(mixer_reg[9]);
+
+                       wa_sendcmd(0x0031);             //set left and right PCM
+                       wa_sendcmd(mixer_reg[0x0A]);
+                       wa_sendcmd(mixer_reg[0x0B]);
+
+                       wa_sendcmd(0x0131);             //set left and right FM
+                       wa_sendcmd(mixer_reg[0x0C]);
+                       wa_sendcmd(mixer_reg[0x0D]);
+
+                       return 0;
+               } else if (mixer_reg[0x0E] == MIXER_PRIVATE3_READ) {    //read command?
+//                     printk("WaveArtist Mixer: Private read command.\n");
+
+                       //first read all current values...
+                       save_flags(flags);
+                       cli();
+
+                       for (i = 0; i < 14; i++) {
+                               wa_sendcmd((i << 8) + 0x30);    // get ready for command nn30H
+
+                               while (!(inb(STATR) & CMD_RF)) {
+                               };      //wait for response ready...
+
+                               mixer_reg[i] = inw(CMDR);
+                       }
+                       restore_flags(flags);
+
+                       if (verify_area(VERIFY_WRITE, (void *) val, sizeof(mixer_reg) == -EFAULT))
+                               return (-EFAULT);
+
+                       memcpy_tofs((void *) val, &mixer_reg, sizeof(mixer_reg));
+                       return 0;
+               } else
+                       return -EINVAL;
+       }
+#endif
+       if (((cmd >> 8) & 0xff) == 'M') {
+               if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
+                       int val;
+
+                       if (get_user(val, (int *)arg))
+                               return -EFAULT;
+
+                       /*
+                        * special case for master volume: if we
+                        * received this call - switch from hw
+                        * volume control to a software volume
+                        * control, till the hw volume is modified
+                        * to signal that user wants to be back in
+                        * hardware...
+                        */
+                       if ((cmd & 0xff) == SOUND_MIXER_VOLUME)
+                               devc->use_slider = 0;
+
+                       return waveartist_mixer_set(devc, cmd & 0xff, val);
+               } else {
+                       int ret;
+
+                       /*
+                        * Return parameters
+                        */
+                       switch (cmd & 0xff) {
+                       case SOUND_MIXER_RECSRC:
+                               ret = devc->recmask;
+
+                               if (devc->handset_state & VNC_INTERNAL_MIC)
+                                       ret |= SOUND_MASK_SPEAKER;
+                               break;
+
+                       case SOUND_MIXER_DEVMASK:
+                               ret = devc->supported_devices;
+                               break;
+
+                       case SOUND_MIXER_STEREODEVS:
+                               ret = devc->supported_devices &
+                                       ~(SOUND_MASK_SPEAKER|SOUND_MASK_IMIX);
+                               break;
+
+                       case SOUND_MIXER_RECMASK:
+                               ret = devc->rec_devices;
+                               break;
+
+                       case SOUND_MIXER_CAPS:
+                               ret = SOUND_CAP_EXCL_INPUT;
+                               break;
+
+                       default:
+                               if ((cmd & 0xff) < SOUND_MIXER_NRDEVICES)
+                                       ret = devc->levels[cmd & 0xff];
+                               else
+                                       return -EINVAL;
+                       }
+
+                       return put_user(ret, (int *)arg) ? -EINVAL : 0;
+               }
+       }
+
+       return -ENOIOCTLCMD;
+}
+
+static struct mixer_operations waveartist_mixer_operations =
+{
+       "WaveArtist",
+       "WaveArtist NetWinder",
+       waveartist_mixer_ioctl
+};
+
+static int
+waveartist_init(wavnc_info *devc)
+{
+       wavnc_port_info *portc;
+       char rev[3], dev_name[64];
+       int my_dev;
+
+       waveartist_reset(devc);
+
+       sprintf(dev_name, "%s (%s", devc->hw.name, devc->chip_name);
+
+       if (waveartist_getrev(&devc->hw, rev)) {
+               strcat(dev_name, " rev. ");
+               strcat(dev_name, rev);
+       }
+       strcat(dev_name, ")");
+
+       conf_printf2(dev_name, devc->hw.io_base, devc->hw.irq,
+                    devc->hw.dma, devc->hw.dma2);
+
+       portc = (wavnc_port_info *)kmalloc(sizeof(wavnc_port_info), GFP_KERNEL);
+       if (portc == NULL)
+               goto nomem;
+
+       memset(portc, 0, sizeof(wavnc_port_info));
+
+       my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION, dev_name,
+                       &waveartist_audio_driver, sizeof(struct audio_driver),
+                       devc->audio_flags, AFMT_U8 | AFMT_S16_LE | AFMT_S8,
+                       devc, devc->hw.dma, devc->hw.dma2);
+
+       if (my_dev < 0)
+               goto free;
+
+       audio_devs[my_dev]->portc = portc;
+
+       waveartist_mixer_reset(devc);
+
+       /*
+        * clear any pending interrupt
+        */
+       waveartist_iack(devc);
+
+       if (request_irq(devc->hw.irq, waveartist_intr, 0, devc->hw.name, devc) < 0) {
+               printk("%s: IRQ %d in use\n",
+                       devc->hw.name, devc->hw.irq);
+               goto uninstall;
+       }
+
+       if (sound_alloc_dma(devc->hw.dma, devc->hw.name)) {
+               printk("%s: Can't allocate DMA%d\n",
+                       devc->hw.name, devc->hw.dma);
+               goto uninstall_irq;
+       }
+
+       if (devc->hw.dma != devc->hw.dma2 && devc->hw.dma2 != NO_DMA)
+               if (sound_alloc_dma(devc->hw.dma2, devc->hw.name)) {
+                       printk("%s: can't allocate DMA%d\n",
+                               devc->hw.name, devc->hw.dma2);
+                       goto uninstall_dma;
+               }
+
+       waveartist_set_ctlr(&devc->hw, 0, DMA1_IE | DMA0_IE);
+
+       audio_devs[my_dev]->mixer_dev =
+               sound_install_mixer(MIXER_DRIVER_VERSION,
+                               dev_name,
+                               &waveartist_mixer_operations,
+                               sizeof(struct mixer_operations),
+                               devc);
+
+       return my_dev;
+
+uninstall_dma:
+       sound_free_dma(devc->hw.dma);
+
+uninstall_irq:
+       free_irq(devc->hw.irq, devc);
+
+uninstall:
+       sound_unload_audiodev(my_dev);
+
+free:
+       kfree(portc);
+
+nomem:
+       return -1;
+}
+
+/*
+ * Corel Netwinder specifics...
+ */
+static void
+vnc_mute(wavnc_info *devc, int mute)
+{
+       extern spinlock_t gpio_lock;
+       unsigned long flags;
+
+       spin_lock_irqsave(&gpio_lock, flags);
+       cpld_modify(CPLD_UNMUTE, mute ? 0 : CPLD_UNMUTE);
+       spin_unlock_irqrestore(&gpio_lock, flags);
+
+       devc->mute_state = mute;
+}
+
+static int
+vnc_volume_slider(wavnc_info *devc)
+{
+       static signed int old_slider_volume;
+       unsigned long flags;
+       signed int volume = 255;
+
+       *CSR_TIMER1_LOAD = 0x00ffffff;
+
+       save_flags(flags);
+       cli();
+
+       outb(0xFF, 0x201);
+       *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV1;
+
+       while (volume && (inb(0x201) & 0x01))
+               volume--;
+
+       *CSR_TIMER1_CNTL = 0;
+
+       restore_flags(flags);
+       
+       volume = 0x00ffffff - *CSR_TIMER1_VALUE;
+
+
+#ifndef REVERSE
+       volume = 150 - (volume >> 5);
+#else
+       volume = (volume >> 6) - 25;
+#endif
+
+       if (volume < 0)
+               volume = 0;
+
+       if (volume > 100)
+               volume = 100;
+
+       /*
+        * slider quite often reads +-8, so debounce this random noise
+        */
+       if ((volume - old_slider_volume) > 7 ||
+           (old_slider_volume - volume) > 7) {
+               old_slider_volume = volume;
+
+               DEB(printk("Slider volume: %d.\n", old_slider_volume));
+       }
+
+       return old_slider_volume;
+}
+
+static int
+vnc_slider(wavnc_info *devc)
+{
+       signed int slider_volume;
+       unsigned int temp;
+
+       /*
+        * read the "buttons" state.
+        *  Bit 4 = handset present,
+        *  Bit 5 = offhook
+        */
+       // the state should be "querable" via a private IOCTL call
+       temp = inb(0x201) & 0x30;
+
+       if (!devc->handset_mute_sw &&
+           (temp ^ devc->handset_state) & VNC_INTERNAL_MIC) {
+               devc->handset_state = temp;
+               devc->handset_mute_sw = 0;
+
+               vnc_mute(devc, (temp & VNC_INTERNAL_MIC) ? 1 : 0);
+       }
+
+       slider_volume = vnc_volume_slider(devc);
+
+       /*
+        * If we're using software controlled volume, and
+        * the slider moves by more than 20%, then we
+        * switch back to slider controlled volume.
+        */
+       if (devc->slider_vol > slider_volume) {
+               if (devc->slider_vol - slider_volume > 20)
+                       devc->use_slider = 1;
+       } else {
+               if (slider_volume - devc->slider_vol > 20)
+                       devc->use_slider = 1;
+       }
+
+       /*
+        * use only left channel
+        */
+       temp = levels[SOUND_MIXER_VOLUME] & 0xFF;
+
+       if (slider_volume != temp && devc->use_slider) {
+               devc->slider_vol = slider_volume;
+
+               waveartist_mixer_set(devc, SOUND_MIXER_VOLUME,
+                       slider_volume | slider_volume << 8);
+
+               return 1;
+       }
+
+       return 0;
+}
+
+static void
+vnc_slider_tick(unsigned long data)
+{
+       int next_timeout;
+
+       if (vnc_slider(adev_info + data))
+               next_timeout = 5;       // mixer reported change
+       else
+               next_timeout = VNC_TIMER_PERIOD;
+
+       mod_timer(&vnc_timer, jiffies + next_timeout);
+}
+
+int
+probe_waveartist(struct address_info *hw_config)
+{
+       wavnc_info *devc = &adev_info[nr_waveartist_devs];
+
+       if (nr_waveartist_devs >= MAX_AUDIO_DEV) {
+               printk("waveartist: too many audio devices\n");
+               return 0;
+       }
+
+       if (check_region(hw_config->io_base, 15))  {
+               printk("WaveArtist: I/O port conflict\n");
+               return 0;
+       }
+
+       if (hw_config->irq > 31 || hw_config->irq < 16) {
+               printk("WaveArtist: Bad IRQ %d\n", hw_config->irq);
+               return 0;
+       }
+
+       if (hw_config->dma != 3) {
+               printk("WaveArtist: Bad DMA %d\n", hw_config->dma);
+               return 0;
+       }
+
+       hw_config->name = "WaveArtist";
+       devc->hw = *hw_config;
+       devc->open_mode = 0;
+       devc->chip_name = "RWA-010";
+
+       return 1;
+}
+
+void
+attach_waveartist(struct address_info *hw)
+{
+       wavnc_info *devc = &adev_info[nr_waveartist_devs];
+
+       /*
+        * NOTE! If irq < 0, there is another driver which has allocated the
+        *   IRQ so that this driver doesn't need to allocate/deallocate it.
+        *   The actually used IRQ is ABS(irq).
+        */
+       devc->hw = *hw;
+       devc->hw.irq = (hw->irq > 0) ? hw->irq : 0;
+       devc->open_mode = 0;
+       devc->playback_dev = 0;
+       devc->record_dev = 0;
+       devc->audio_flags = DMA_AUTOMODE;
+       devc->levels = levels;
+
+       if (hw->dma != hw->dma2 && hw->dma2 != NO_DMA)
+               devc->audio_flags |= DMA_DUPLEX;
+
+       request_region(hw->io_base, 15, devc->hw.name);
+
+       devc->dev_no = waveartist_init(devc);
+
+       if (devc->dev_no < 0)
+               release_region(hw->io_base, 15);
+       else {
+               init_timer(&vnc_timer);
+               vnc_timer.function = vnc_slider_tick;
+               vnc_timer.expires  = jiffies;
+               vnc_timer.data     = nr_waveartist_devs;
+               add_timer(&vnc_timer);
+
+               nr_waveartist_devs += 1;
+
+               vnc_mute(devc, 0);
+       }
+}
+
+void
+unload_waveartist(struct address_info *hw)
+{
+       wavnc_info *devc = NULL;
+       int i;
+
+       for (i = 0; i < nr_waveartist_devs; i++)
+               if (hw->io_base == adev_info[i].hw.io_base) {
+                       devc = adev_info + i;
+                       break;
+               }
+
+       if (devc != NULL) {
+               int mixer;
+
+               release_region(devc->hw.io_base, 15);
+
+               waveartist_set_ctlr(&devc->hw, DMA1_IE|DMA0_IE, 0);
+
+               if (devc->hw.irq >= 0)
+                       free_irq(devc->hw.irq, devc);
+
+               sound_free_dma(devc->hw.dma);
+
+               if (devc->hw.dma != devc->hw.dma2 &&
+                   devc->hw.dma2 != NO_DMA)
+                       sound_free_dma(devc->hw.dma2);
+
+               del_timer(&vnc_timer);
+
+               mixer = audio_devs[devc->dev_no]->mixer_dev;
+
+               if (mixer >= 0)
+                       sound_unload_mixerdev(mixer);
+
+               if (devc->dev_no >= 0)
+                       sound_unload_audiodev(devc->dev_no);
+
+               nr_waveartist_devs -= 1;
+
+               for (; i < nr_waveartist_devs; i++)
+                       adev_info[i] = adev_info[i + 1];
+       } else
+               printk("waveartist: can't find device to unload\n");
+}
+
+#ifdef MODULE
+
+MODULE_PARM(io, "i");          /* IO base */
+MODULE_PARM(irq, "i");         /* IRQ */
+MODULE_PARM(dma, "i");         /* DMA */
+MODULE_PARM(dma2, "i");                /* DMA2 */
+
+int io   = CONFIG_WAVEARTIST_BASE;
+int irq  = CONFIG_WAVEARTIST_IRQ;
+int dma  = CONFIG_WAVEARTIST_DMA;
+int dma2 = CONFIG_WAVEARTIST_DMA2;
+
+static int attached;
+
+struct address_info hw_config;
+
+int init_module(void)
+{
+       hw_config.io_base = io;
+       hw_config.irq = irq;
+       hw_config.dma = dma;
+       hw_config.dma2 = dma2;
+
+       if (!probe_waveartist(&hw_config))
+               return -ENODEV;
+
+       attach_waveartist(&hw_config);
+       attached = 1;
+
+       SOUND_LOCK;
+       return 0;
+}
+
+void cleanup_module(void)
+{
+       if (attached) {
+               SOUND_LOCK_END;
+
+               unload_waveartist(&hw_config);
+       }
+}
+#endif
diff --git a/drivers/sound/waveartist.h b/drivers/sound/waveartist.h
new file mode 100644 (file)
index 0000000..360bc95
--- /dev/null
@@ -0,0 +1,68 @@
+
+// def file for Rockwell RWA010 chip set, as installed in Corel NetWinder
+
+//registers
+#define        WA_BASE 0
+//x250
+
+#define CMDR   WA_BASE+0
+#define DATR   WA_BASE+2
+
+#define CTLR   WA_BASE+4
+#define        STATR   WA_BASE+5
+
+#define        IRQSTAT WA_BASE+12
+
+//bit defs
+//reg STATR
+#define        CMD_WE  0x80
+#define        CMD_RF  0x40
+#define        DAT_WE  0x20
+#define        DAT_RF  0x10
+
+#define        IRQ_REQ 0x08
+#define        DMA1    0x04
+#define        DMA0    0x02
+
+//bit defs
+//reg CTLR
+#define        CMD_WEIE        0x80
+#define        CMD_RFIE        0x40
+#define        DAT_WEIE        0x20
+#define        DAT_RFIE        0x10
+
+#define        RESET   0x08
+#define        DMA1_IE 0x04
+#define        DMA0_IE 0x02
+#define        IRQ_ACK 0x01
+
+//commands
+
+#define        WACMD_SYSTEMID  0
+#define        WACMD_INPUTFORMAT       0x10    //0-8S, 1-16S, 2-8U
+#define        WACMD_INPUTCHANNELS     0x11    //1-Mono, 2-Stereo
+#define        WACMD_INPUTSPEED        0x12    //sampling rate
+#define        WACMD_INPUTDMA          0x13    //0-8bit, 1-16bit, 2-PIO
+#define        WACMD_INPUTSIZE         0x14    //samples to interrupt
+#define        WACMD_INPUTSTART        0x15    //start ADC
+#define        WACMD_INPUTPAUSE        0x16    //pause ADC
+#define        WACMD_INPUTSTOP         0x17    //stop ADC
+#define        WACMD_INPUTRESUME       0x18    //resume ADC
+#define        WACMD_INPUTPIO          0x19    //PIO ADC
+
+#define        WACMD_OUTPUTFORMAT      0x20    //0-8S, 1-16S, 2-8U
+#define        WACMD_OUTPUTCHANNELS    0x21    //1-Mono, 2-Stereo
+#define        WACMD_OUTPUTSPEED       0x22    //sampling rate
+#define        WACMD_OUTPUTDMA         0x23    //0-8bit, 1-16bit, 2-PIO
+#define        WACMD_OUTPUTSIZE        0x24    //samples to interrupt
+#define        WACMD_OUTPUTSTART       0x25    //start ADC
+#define        WACMD_OUTPUTPAUSE       0x26    //pause ADC
+#define        WACMD_OUTPUTSTOP        0x27    //stop ADC
+#define        WACMD_OUTPUTRESUME      0x28    //resume ADC
+#define        WACMD_OUTPUTPIO         0x29    //PIO ADC
+
+
+
+
+int             wa_sendcmd(unsigned int cmd);
+int             wa_writecmd(unsigned int cmd, unsigned int arg);
index b658e96cfe39726442450bde8b70974b3e8e173d..6e831420aff04ca68abcf3188c42aa9d8ea58542 100644 (file)
 
 #include <asm/io.h>
 #include <asm/spinlock.h>
+#include <asm/unaligned.h>
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
 #endif
 #include <video/fbcon-cfb24.h>
 #include <video/fbcon-cfb32.h>
 
-#if defined(CONFIG_PPC)
+#if defined(CONFIG_FB_OF)
 #if defined(CONFIG_FB_COMPAT_XPMAC)
 #include <asm/vc_ioctl.h>
 #endif
 /* I benchmarked PII/350MHz with G200... MEMCPY, MEMCPYTOIO and WRITEL are on same speed ( <2% diff) */
 /* so that means that G200 speed (or AGP speed?) is our limit... I do not have benchmark to test, how */
 /* much of PCI bandwidth is used during transfers... */
-#if defined(__i386__) || defined(__ppc__)
+#if defined(__i386__)
 #define MEMCPYTOIO_MEMCPY
 #else
 #define MEMCPYTOIO_WRITEL
 #error "Sorry, I have no idea how to do this on sparc... There is mapioaddr... With bus_type parameter..."
 #endif
 
-#ifdef __m68k__
+#if defined(__m68k__)
 #define MAP_BUSTOVIRT
 #else
+#if defined(CONFIG_PPC) && defined(CONFIG_PREP) && defined(_ISA_MEM_BASE)
+/* do not tell me that PPC is not broken... if ioremap() oops with
+   invalid value written to msr... */
+#define MAP_ISAMEMBASE
+#else
 #define MAP_IOREMAP
 #endif
+#endif
 
 #ifdef DEBUG
 #define dprintk(X...)  printk(X)
@@ -344,8 +351,12 @@ static inline int mga_ioremap(unsigned long phys, unsigned long size, int flags,
 #ifdef MAP_BUSTOVIRT
        virt->vaddr = bus_to_virt(phys);
 #else
+#ifdef MAP_ISAMEMBASE
+       virt->vaddr = (void*)(phys + _ISA_MEM_BASE);
+#else
 #error "Your architecture does not have neither ioremap nor bus_to_virt... Giving up"
 #endif
+#endif
 #endif
        return (virt->vaddr == 0); /* 0, !0... 0, error_code in future */
 }
@@ -554,6 +565,7 @@ struct matrox_fb_info {
                int             inverse;
                int             hwcursor;
                int             blink;
+               int             sgram;
 
                int             accelerator;
                int             text_type_aux;
@@ -592,15 +604,13 @@ struct matrox_fb_info {
        } cmap;
 #endif
        struct { unsigned red, green, blue, transp; } palette[256];
-#if defined(CONFIG_PPC) && defined(CONFIG_FB_COMPAT_XPMAC)
+#if defined(CONFIG_FB_OF) && defined(CONFIG_FB_COMPAT_XPMAC)
        char    matrox_name[32];
 #endif
 };
 
-#if defined(CONFIG_PPC)
-unsigned char nvram_read_byte(int);
-#endif
 #if defined(CONFIG_FB_OF)
+unsigned char nvram_read_byte(int);
 int matrox_of_init(struct device_node *dp);
 #endif
 
@@ -3116,7 +3126,7 @@ static const unsigned char MGA1064_DAC[] = {
                0x00, 0,  
                M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL, 
                M1064_XGENCTRL_VS_0 | M1064_XGENCTRL_ALPHA_DIS | M1064_XGENCTRL_BLACK_0IRE | M1064_XGENCTRL_NO_SYNC_ON_GREEN, 
-               M1064_XMISCCTRL_DAC_EN | M1064_XMISCCTRL_MFC_VGA | M1064_XMISCCTRL_DAC_8BIT | M1064_XMISCCTRL_LUT_EN,
+               M1064_XMISCCTRL_DAC_EN | M1064_XMISCCTRL_MFC_DIS | M1064_XMISCCTRL_DAC_8BIT | M1064_XMISCCTRL_LUT_EN,
                0x10, 0x3F, M1064_XZOOMCTRL_1, M1064_XSENSETEST_BCOMP | M1064_XSENSETEST_GCOMP | M1064_XSENSETEST_RCOMP | M1064_XSENSETEST_PDOWN, 
                0x00,
                0x00, 0x00, 0xFF, 0xFF};
@@ -3200,7 +3210,7 @@ static int DAC1064_init_1(CPMINFO struct matrox_hw_state* hw, struct my_timming*
        memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs));
        if (p->type == FB_TYPE_TEXT) {
                hw->DACreg[POS1064_XMISCCTRL] = M1064_XMISCCTRL_DAC_EN
-                                             | M1064_XMISCCTRL_MFC_VGA
+                                             | M1064_XMISCCTRL_MFC_DIS
                                              | M1064_XMISCCTRL_DAC_6BIT
                                              | M1064_XMISCCTRL_LUT_EN;
                hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP 
@@ -3969,10 +3979,8 @@ __initfunc(static int MGAG100_preinit(WPMINFO struct matrox_hw_state* hw)) {
        pci_read_config_dword(ACCESS_FBINFO(pcidev), 0x50, &reg50);
        reg50 &= ~0x3000;
        pci_write_config_dword(ACCESS_FBINFO(pcidev), 0x50, reg50);
-       if (!(x7AF4 & 0x10))
-               hw->MXoptionReg |= 0x4000;
        if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100) {
-               hw->MXoptionReg |= 0x1080;
+               hw->MXoptionReg |= 0x5080;
                pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
                mga_outl(M_CTLWTST, 0x01032521);
                /* mga_outl(M_CTLWTST, 0x03258A31); */ 
@@ -3999,6 +4007,8 @@ __initfunc(static int MGAG100_preinit(WPMINFO struct matrox_hw_state* hw)) {
                }
        } else {
                hw->MXoptionReg |= 0x00000C00;
+               if (ACCESS_FBINFO(devflags.sgram))
+                       hw->MXoptionReg |= 0x4000;
                mga_outl(M_CTLWTST, 0x042450A1);
                mga_outb(0x1E47, 0x00);
                mga_outb(0x1E46, 0x00);
@@ -4513,7 +4523,7 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
                        ACCESS_FBINFO(newhw) = ohw;
                        matrox_cfbX_init(PMINFO display);
                        do_install_cmap(PMINFO display);
-#if defined(CONFIG_PPC) && defined(CONFIG_FB_COMPAT_XPMAC)
+#if defined(CONFIG_FB_OF) && defined(CONFIG_FB_COMPAT_XPMAC)
                        if (console_fb_info == &ACCESS_FBINFO(fbcon)) {
                                int vmode, cmode;
 
@@ -4531,7 +4541,7 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
                                display_info.cmap_data_address = 0;
                                display_info.disp_reg_address = ACCESS_FBINFO(mmio.base);
                        }
-#endif /* CONFIG_PPC && CONFIG_FB_COMPAT_XPMAC */
+#endif /* CONFIG_FB_OF && CONFIG_FB_COMPAT_XPMAC */
                }
        }
        return 0;
@@ -4845,6 +4855,8 @@ static int noinit = 1;                    /* "matrox:noinit" */
 static int inverse = 0;                        /* "matrox:inverse" */
 static int hwcursor = 1;               /* "matrox:nohwcursor" */
 static int blink = 1;                  /* "matrox:noblink" */
+static int sgram = 0;                  /* "matrox:sgram" */
+static int mtrr = 1;                   /* "matrox:nomtrr" */
 static int grayscale = 0;              /* "matrox:grayscale" */
 static unsigned int fastfont = 0;      /* "matrox:fastfont:xxxxx" */
 static int dev = -1;                   /* "matrox:dev:xxxxx" */
@@ -4935,6 +4947,10 @@ __initfunc(void matroxfb_setup(char *options, int *ints)) {
                        disabled = 1;
                else if (!strcmp(this_opt, "enabled"))  /* noenabled does not exist */
                        disabled = 0;
+               else if (!strcmp(this_opt, "sgram"))    /* nosgram == sdram */
+                       sgram = 1;
+               else if (!strcmp(this_opt, "sdram"))
+                       sgram = 0;
                else {
                        int value = 1;
        
@@ -4956,6 +4972,8 @@ __initfunc(void matroxfb_setup(char *options, int *ints)) {
                                nobios = !value;
                        else if (!strcmp(this_opt, "init"))
                                noinit = !value;
+                       else if (!strcmp(this_opt, "mtrr"))
+                               mtrr = value;
                        else if (!strcmp(this_opt, "inv24"))
                                inv24 = value;
                        else if (!strcmp(this_opt, "cross4MB"))
@@ -5441,9 +5459,11 @@ __initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
        if (ACCESS_FBINFO(video.len_usable) > 0x08000000)
                ACCESS_FBINFO(video.len_usable) = 0x08000000;
 #ifdef CONFIG_MTRR
-       ACCESS_FBINFO(mtrr.vram) = mtrr_add(video_base_phys, ACCESS_FBINFO(video.len), MTRR_TYPE_WRCOMB, 1);
-       ACCESS_FBINFO(mtrr.vram_valid) = 1;
-       printk(KERN_INFO "matroxfb: MTRR's turned on\n");
+       if (mtrr) {
+               ACCESS_FBINFO(mtrr.vram) = mtrr_add(video_base_phys, ACCESS_FBINFO(video.len), MTRR_TYPE_WRCOMB, 1);
+               ACCESS_FBINFO(mtrr.vram_valid) = 1;
+               printk(KERN_INFO "matroxfb: MTRR's turned on\n");
+       }
 #endif /* CONFIG_MTRR */
 
 /* validate params, autodetect k, M */
@@ -5563,7 +5583,7 @@ __initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
        ACCESS_FBINFO(fbcon.flags) = FBINFO_FLAG_DEFAULT;
        ACCESS_FBINFO(hw_switch->reset(PMINFO hw));
        ACCESS_FBINFO(video.len_usable) &= PAGE_MASK;
-#if defined(CONFIG_PPC)
+#if defined(CONFIG_FB_OF)
 #if defined(CONFIG_FB_COMPAT_XPMAC)
        strcpy(ACCESS_FBINFO(matrox_name), "MTRX,");    /* OpenFirmware naming convension */
        strncat(ACCESS_FBINFO(matrox_name), b->name, 26);
@@ -5679,6 +5699,7 @@ __initfunc(static int matrox_init(void)) {
                                ACCESS_FBINFO(devflags.precise_width) = option_precise_width;
                                ACCESS_FBINFO(devflags.hwcursor) = hwcursor;
                                ACCESS_FBINFO(devflags.blink) = blink;
+                               ACCESS_FBINFO(devflags.sgram) = sgram;
                                ACCESS_FBINFO(capable.cross4MB) = cross4MB;
 
                                ACCESS_FBINFO(fastfont.size) = fastfont;
@@ -5756,6 +5777,10 @@ MODULE_PARM(nobios, "i");
 MODULE_PARM_DESC(nobios, "Disables ROM BIOS (0 or 1=disabled) (default=do not change BIOS state)"); 
 MODULE_PARM(noinit, "i");
 MODULE_PARM_DESC(noinit, "Disables W/SG/SD-RAM and bus interface initialization (0 or 1=do not initialize) (default=0)");
+MODULE_PARM(mtrr, "i");
+MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)");
+MODULE_PARM(sgram, "i");
+MODULE_PARM_DESC(sgram, "Indicates that G200 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
 MODULE_PARM(inv24, "i");
 MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)");
 MODULE_PARM(inverse, "i");
index 99a8b9b1a9b649c16607f1b99da18c1869bde591..97724120590f7b2fd3da71b474087154e6d49289 100644 (file)
@@ -60,7 +60,7 @@ static char buffersize_index[65] =
  */
 static unsigned long bh_hash_mask = 0;
 
-static int grow_buffers(int pri, int size);
+static int grow_buffers(int size);
 
 static struct buffer_head ** hash_table;
 static struct buffer_head * lru_list[NR_LIST] = {NULL, };
@@ -689,7 +689,7 @@ void set_blocksize(kdev_t dev, int size)
  */
 static void refill_freelist(int size)
 {
-       if (!grow_buffers(GFP_KERNEL, size)) {
+       if (!grow_buffers(size)) {
                wakeup_bdflush(1);
                current->policy |= SCHED_YIELD;
                schedule();
@@ -1396,7 +1396,7 @@ int generic_readpage(struct file * file, struct page * page)
  * Try to increase the number of buffers available: the size argument
  * is used to determine what kind of buffers we want.
  */
-static int grow_buffers(int pri, int size)
+static int grow_buffers(int size)
 {
        unsigned long page;
        struct buffer_head *bh, *tmp;
@@ -1408,7 +1408,7 @@ static int grow_buffers(int pri, int size)
                return 0;
        }
 
-       if (!(page = __get_free_page(pri)))
+       if (!(page = __get_free_page(GFP_BUFFER)))
                return 0;
        bh = create_buffers(page, size, 0);
        if (!bh) {
@@ -1571,7 +1571,7 @@ void __init buffer_init(void)
        }
 
        lru_list[BUF_CLEAN] = 0;
-       grow_buffers(GFP_KERNEL, BLOCK_SIZE);
+       grow_buffers(BLOCK_SIZE);
 }
 
 
index aafc813834b940a41a61b236fc542ddbcb6ce198..a252cb46b5e0f1ba5b9a45534468ac447b9baf93 100644 (file)
@@ -375,7 +375,7 @@ MODULE_AUTHOR("Peter J. Braam <braam@cs.cmu.edu>");
 int init_module(void)
 {
        int status;
-       printk(KERN_INFO "Coda Kernel/Venus communications (module), v4.7.5, braam@cs.cmu.edu.\n");
+       printk(KERN_INFO "Coda Kernel/Venus communications (module), v5.0-pre1, braam@cs.cmu.edu.\n");
 
        status = init_coda_psdev();
        if ( status ) {
index ddb27c3d4b2440f3a525736de91a1f46c6fb52a3..4c640892d9350a226a77e739d08b38882ef8abb1 100644 (file)
@@ -807,7 +807,7 @@ int coda_downcall(int opcode, union outputArgs * out, struct super_block *sb)
 {
 
        /* Handle invalidation requests. */
-          if ( !sb ) { 
+          if ( !sb || !sb->s_root || !sb->s_root->d_inode) { 
                  printk("coda_downcall: opcode %d, no sb!\n", opcode);
                  return 0; 
          }
index 6f676d46d1543161fa1cf79b74b99aef26cb1f70..95b763e3e5fd3af8b7454afbc586fcc018fbd878 100644 (file)
@@ -166,10 +166,26 @@ out:
  */
 int d_invalidate(struct dentry * dentry)
 {
-       /* Check whether to do a partial shrink_dcache */
+       /*
+        * Check whether to do a partial shrink_dcache
+        * to get rid of unused child entries.
+        */
        if (!list_empty(&dentry->d_subdirs)) {
                shrink_dcache_parent(dentry);
-               if (!list_empty(&dentry->d_subdirs))
+       }
+
+       /*
+        * Somebody still using it?
+        *
+        * If it's a directory, we can't drop it
+        * for fear of somebody re-populating it
+        * with children (even though dropping it
+        * would make it unreachable from the root,
+        * we might still populate it if it was a
+        * working directory or similar).
+        */
+       if (dentry->d_count) {
+               if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode))
                        return -EBUSY;
        }
 
index ca5d7714454868c9a5703d3f9055a27ef35322b4..accd0aadc3dfc3a3ed27fa698f0418c60bc5a69c 100644 (file)
@@ -13,7 +13,6 @@
  * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
index 2784d646201943990abca4df1ff5bb2fa27cdaa1..7c5d2904c65f186edc2f5726aa17427c62232019 100644 (file)
@@ -1129,17 +1129,16 @@ void __init mount_root(void)
                if ((fs_type = get_fs_type("nfs"))) {
                        sb = get_empty_super(); /* "can't fail" */
                        sb->s_dev = get_unnamed_dev();
-                       sb->s_flags = root_mountflags & ~MS_RDONLY;
+                       sb->s_flags = root_mountflags;
                        vfsmnt = add_vfsmnt(sb, "/dev/root", "/");
                        if (vfsmnt) {
                                if (nfs_root_mount(sb) >= 0) {
-                                       sb->s_rd_only = 0;
                                        sb->s_dirt = 0;
                                        sb->s_type = fs_type;
                                        current->fs->root = dget(sb->s_root);
                                        current->fs->pwd = dget(sb->s_root);
                                        ROOT_DEV = sb->s_dev;
-                                       printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
+                                       printk (KERN_NOTICE "VFS: Mounted root (NFS filesystem)%s.\n", (sb->s_flags & MS_RDONLY) ? " readonly" : "");
                                        return;
                                }
                                remove_vfsmnt(sb->s_dev);
index 6fc2245120128e85ddc1503b4b253419cacee5b9..ecd16f0e0cf5bb6da68b57020617c39b988a4b71 100644 (file)
@@ -110,9 +110,7 @@ revalidate:
                                brelse(bh);
                                return stored;
                        }
-#if 0 /* XXX */
-                       if (!ext2_check_dir_entry ("ext2_readdir", inode, de,
-                       /* XXX - beware about de having to be swabped somehow */
+                       if (!ufs_check_dir_entry ("ufs_readdir", inode, de,
                                                   bh, offset)) {
                                /* On error, skip the f_pos to the
                                   next block. */
@@ -122,7 +120,6 @@ revalidate:
                                brelse (bh);
                                return stored;
                        }
-#endif /* XXX */
                        offset += SWAB16(de->d_reclen);
                        if (de->d_ino) {
                        /* SWAB16() was unneeded -- compare to 0 */
index d08e51e80b9b85ab05eda530688258e5c8bcd4ca..9adca74eaf46de22a2f57edde3e34adeb057ee5e 100644 (file)
@@ -58,6 +58,7 @@
  */
 
 
+#include <linux/config.h>
 #include <linux/module.h>
 
 #include <stdarg.h>
@@ -274,6 +275,8 @@ static int ufs_parse_options (char * options, unsigned * mount_options)
                                ufs_set_opt (*mount_options, UFSTYPE_44BSD);
                        else if (!strcmp (value, "next"))
                                ufs_set_opt (*mount_options, UFSTYPE_NEXT);
+                       else if (!strcmp (value, "openstep"))
+                               ufs_set_opt (*mount_options, UFSTYPE_OPENSTEP);
                        else {
                                printk ("UFS-fs: Invalid type option: %s\n", value);
                                return 0;
@@ -464,7 +467,7 @@ struct super_block * ufs_read_super (struct super_block * sb, void * data,
        }
        if (!(sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE)) {
                printk("You didn't specify type of your ufs file system\n\n"
-               "       mount -t ufs -o ufstype=sun|44bsd|old|next ....\n\n"
+               "       mount -t ufs -o ufstype=sun|44bsd|old|next|openstep ....\n\n"
                "!!! WARNING !!! wrong value may corrupt you file system\n"
                "default value is ufstype=old\n");
                ufs_set_opt (sb->u.ufs_sb.s_mount_opt, UFSTYPE_OLD);
@@ -506,7 +509,7 @@ struct super_block * ufs_read_super (struct super_block * sb, void * data,
                flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
                if (!(sb->s_flags & MS_RDONLY)) {
                        printk("old type of ufs is supported read-only\n"); 
-                       goto failed;
+                       sb->s_flags |= MS_RDONLY;
                }
                break;
        
@@ -520,10 +523,23 @@ struct super_block * ufs_read_super (struct super_block * sb, void * data,
                flags |= UFS_DE_OLD | UFS_UID_OLD | UFS_ST_OLD | UFS_CG_OLD;
                if (!(sb->s_flags & MS_RDONLY)) {
                        printk("nextstep type of ufs is supported read-only\n");
-                       goto failed;
+                       sb->s_flags |= MS_RDONLY;
                }
                break;
        
+       case UFS_MOUNT_UFSTYPE_OPENSTEP:
+               UFSD(("openstep ufstype\n"))
+               uspi->s_fsize = block_size = 1024;
+               uspi->s_fmask = ~(1024 - 1);
+               uspi->s_fshift = 10;
+               uspi->s_sbsize = super_block_size = 2048;
+               uspi->s_sbbase = 0;
+               flags |= UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
+               if (!(sb->s_flags & MS_RDONLY)) {
+                       printk("openstep type of ufs is supported read-only\n");
+                       sb->s_flags |= MS_RDONLY;
+               }
+               break;
        
        default:
                printk("this fs type of ufs is not supported\n");
@@ -567,8 +583,10 @@ again:
        }
 #endif
 
-       if ((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) == 
-       UFS_MOUNT_UFSTYPE_NEXT && uspi->s_sbbase < 256) {
+       if ((((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) == 
+       UFS_MOUNT_UFSTYPE_NEXT) ||
+       ((sb->u.ufs_sb.s_mount_opt & UFS_MOUNT_UFSTYPE) ==
+       UFS_MOUNT_UFSTYPE_OPENSTEP)) && uspi->s_sbbase < 256) {
                ubh_brelse_uspi(uspi);
                ubh = NULL;
                uspi->s_sbbase += 8;
index 2ed4cacc2de94dcc850991593194f9515f3ea6e6..fa6bd17e108cac8449261a20045e7fe8a6fef898 100644 (file)
@@ -8,7 +8,7 @@
 /*
  * The following structure is used to manage multiple PCI busses.
  *
- * XXX: We should solve thos problem in an architecture independant
+ * XXX: We should solve this problem in an architecture independent
  * way, rather than hacking something up here.
  */
 
index 0d0a332519b310788cb7ab1801cd1cd7a60d793f..675231bca0485bd715c54e12b1d532051d332a29 100644 (file)
@@ -125,6 +125,17 @@ struct termios {
 #define  B115200  00021
 #define  B230400  00022
 #define  B460800  00023
+#define  B500000  00024
+#define  B576000  00025
+#define  B921600  00026
+#define B1000000  00027
+#define B1152000  00030
+#define B1500000  00031
+#define B2000000  00032
+#define B2500000  00033
+#define B3000000  00034
+#define B3500000  00035
+#define B4000000  00036
 
 #define CSIZE  00001400
 #define   CS5  00000000
index 12df46a9a7daacadacbc59f09e9d2510140a9c7a..489d76eb52344e9ea3b693fd64ac2e1b60ec356f 100644 (file)
@@ -27,4 +27,9 @@ struct exec
 #define M_ARM 103
 
 #include <asm/arch/a.out.h>
+
+#ifndef LIBRARY_START_TEXT
+#define LIBRARY_START_TEXT     (0x00c00000)
+#endif
+
 #endif /* __A_OUT_GNU_H__ */
index a8ef7645f58dd0aba3c10192a5311f9bcd64da18..e00511463b2e4329f92efc2de5d14fe170cf8e65 100644 (file)
@@ -10,7 +10,6 @@
 
 #ifdef __KERNEL__
 #define STACK_TOP              (0x01a00000)
-#define LIBRARY_START_TEXT     (0x00c00000)
 #endif
 
 #endif
index 459c2ba11c9efb3747e3f6bc9df0dc04af436945..49e184769e7f411b82c97a71b04a69a20985c09a 100644 (file)
 
 #define MAX_DMA_ADDRESS                0x03000000
 
-/*
- * DMA modes - we have two, IN and OUT
- */
-typedef enum {
-       DMA_MODE_READ,
-       DMA_MODE_WRITE
-} dmamode_t;
-
 #ifdef CONFIG_ARCH_ARC
 #define MAX_DMA_CHANNELS       3
 
index 07b3679e0b22e7218edffd9c4ef0fe154e6da880..c59007f3cabbc8694b5886c26cf1479f4db615dc 100644 (file)
@@ -20,7 +20,9 @@
  * source.
  */
 #define HAS_IOC
+#include <asm/ioc.h>
 #define HAS_MEMC
+#include <asm/memc.h>
 #define HAS_MEMC1A
 #define HAS_VIDC
 
index 0b77060c5b477c57475f094f86489d5bb52e573c..4e984bd3c30c9a80c44a79126e160d4aaa3b6475 100644 (file)
@@ -35,7 +35,7 @@ extern __inline__ void __outb (unsigned int value, unsigned int port)
        "tst    %2, #0x80000000\n\t"
        "mov    %0, %4\n\t"
        "addeq  %0, %0, %3\n\t"
-       "strb   %1, [%0, %2, lsl #2]"
+       "strb   %1, [%0, %2, lsl #2]    @ outb"
        : "=&r" (temp)
        : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
        : "cc");
@@ -48,7 +48,7 @@ extern __inline__ void __outw (unsigned int value, unsigned int port)
        "tst    %2, #0x80000000\n\t"
        "mov    %0, %4\n\t"
        "addeq  %0, %0, %3\n\t"
-       "str    %1, [%0, %2, lsl #2]"
+       "str    %1, [%0, %2, lsl #2]    @ outw"
        : "=&r" (temp)
        : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
        : "cc");
@@ -61,7 +61,7 @@ extern __inline__ void __outl (unsigned int value, unsigned int port)
        "tst    %2, #0x80000000\n\t"
        "mov    %0, %4\n\t"
        "addeq  %0, %0, %3\n\t"
-       "str    %1, [%0, %2, lsl #2]"
+       "str    %1, [%0, %2, lsl #2]    @ outl"
        : "=&r" (temp)
        : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
        : "cc");
@@ -75,7 +75,7 @@ extern __inline__ unsigned sz __in##fnsuffix (unsigned int port)              \
        "tst    %2, #0x80000000\n\t"                                            \
        "mov    %0, %4\n\t"                                                     \
        "addeq  %0, %0, %3\n\t"                                                 \
-       "ldr" ##instr## "       %1, [%0, %2, lsl #2]"                           \
+       "ldr" ##instr## "       %1, [%0, %2, lsl #2]    @ in"###fnsuffix        \
        : "=&r" (temp), "=r" (value)                                            \
        : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)                \
        : "cc");                                                                \
@@ -110,11 +110,11 @@ DECLARE_IO(long,l,"")
 ({                                                                             \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "strb   %0, [%1, %2]"                                           \
+               "strb   %0, [%1, %2]    @ outbc"                                \
                : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2));          \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "strb   %0, [%1, %2]"                                           \
+               "strb   %0, [%1, %2]    @ outbc"                                \
                : : "r" (value), "r" (IO_BASE), "r" ((port) << 2));             \
 })
 
@@ -123,11 +123,11 @@ DECLARE_IO(long,l,"")
        unsigned char result;                                                   \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "ldrb   %0, [%1, %2]"                                           \
+               "ldrb   %0, [%1, %2]    @ inbc"                                 \
                : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "ldrb   %0, [%1, %2]"                                           \
+               "ldrb   %0, [%1, %2]    @ inbc"                                 \
                : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
        result;                                                                 \
 })
@@ -137,11 +137,11 @@ DECLARE_IO(long,l,"")
        unsigned long v = value;                                                \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]"                                           \
+               "str    %0, [%1, %2]    @ outwc"                                \
                : : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2));        \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]"                                           \
+               "str    %0, [%1, %2]    @ outwc"                                \
                : : "r" (v|v<<16), "r" (IO_BASE), "r" ((port) << 2));           \
 })
 
@@ -150,11 +150,11 @@ DECLARE_IO(long,l,"")
        unsigned short result;                                                  \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]"                                           \
+               "ldr    %0, [%1, %2]    @ inwc"                                 \
                : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]"                                           \
+               "ldr    %0, [%1, %2]    @ inwc"                                 \
                : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
        result & 0xffff;                                                        \
 })
@@ -164,11 +164,11 @@ DECLARE_IO(long,l,"")
        unsigned long v = value;                                                \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]"                                           \
+               "str    %0, [%1, %2]    @ outlc"                                \
                : : "r" (v), "r" (PCIO_BASE), "Jr" ((port) << 2));              \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]"                                           \
+               "str    %0, [%1, %2]    @ outlc"                                \
                : : "r" (v), "r" (IO_BASE), "r" ((port) << 2));                 \
 })
 
@@ -177,11 +177,11 @@ DECLARE_IO(long,l,"")
        unsigned long result;                                                   \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]"                                           \
+               "ldr    %0, [%1, %2]    @ inlc"                                 \
                : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]"                                           \
+               "ldr    %0, [%1, %2]    @ inlc"                                 \
                : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
        result;                                                                 \
 })
index 33462ca98feba2d3ead11a3ac5e270b60e8b2271..cb63936e4e1117929424cdf308268fc55b7bb3ab 100644 (file)
@@ -27,7 +27,6 @@
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
-#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
 
 #define INIT_MMAP \
 { &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
index 3becc7b2f81f74fdaf621bcdd1d8b74ef6f25f7c..9e2e99cfdc644fae5b0d9d4e61a6b2414a1ed953 100644 (file)
 
 #endif
 
-extern __inline__ void arch_hard_reset (void)
+extern __inline__ void arch_reset(char mode)
 {
-       extern void ecard_reset (int card);
+       extern void ecard_reset(int card);
+
+       /*
+        * Do any cleanups that the processor may require
+        */
+       processor._proc_fin();
 
        /*
         * Reset all expansion cards.
         */
-       ecard_reset (-1);
+       ecard_reset(-1);
 
        /*
         * copy branch instruction to reset location and call it
         */
        *(unsigned long *)0 = *(unsigned long *)0x03800000;
        ((void(*)(void))0)();
-
-       /*
-        * If that didn't work, loop endlessly
-        */
-       while (1);
 }
 
 #endif
index 0123eb29a1998e8dd09e58bf789dec819e624dcd..2746584c8a17089f670cf4e7c4174f7509eec337 100644 (file)
@@ -9,7 +9,6 @@
 
 #ifdef __KERNEL__
 #define STACK_TOP              ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#define LIBRARY_START_TEXT     (0x00c00000)
 #endif
 
 #endif
index 96a265927c0eeaec4fc3fd33eb446f0df793c6e7..971369789881bee70ed378b5c17fd761c9959fc5 100644 (file)
  * bytes of RAM.
  */
 #define MAX_DMA_ADDRESS                0xd0000000
-
-/*
- * DMA modes - we have two, IN and OUT
- */
-typedef enum {
-       DMA_MODE_READ,
-       DMA_MODE_WRITE
-} dmamode_t;
-
 #define MAX_DMA_CHANNELS       8
 
 #endif /* _ASM_ARCH_DMA_H */
index d04eb9835b0d6017f97e15c9bbcf3709d230020f..e502b0fc6691764233d5fbdffcbaf62acc32c335 100644 (file)
@@ -38,7 +38,7 @@
 #define MAPTOPHYS(a)           ((unsigned long)(a) - PAGE_OFFSET)
 #define KERNTOPHYS(a)          ((unsigned long)(&a))
 #define KERNEL_BASE            (0xc0008000)
-#define SAFE_ADDR              0x40000000
+#define FLUSH_BASE_PHYS                0x40000000
 
 #else
 
index 39f574d555a0cc18bb4b8ac0f017039952ae750a..32fc49c1ad6aa6af3465dc74d876da0e47081329 100644 (file)
@@ -36,7 +36,7 @@ extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port)        \
        "tst    %2, #0x80000000\n\t"                                            \
        "mov    %0, %4\n\t"                                                     \
        "addeq  %0, %0, %3\n\t"                                                 \
-       "str" ##instr## "       %1, [%0, %2, lsl #2]"                           \
+       "str" ##instr## "       %1, [%0, %2, lsl #2]    @ out"###fnsuffix       \
        : "=&r" (temp)                                                          \
        : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)   \
        : "cc");                                                                \
@@ -50,7 +50,7 @@ extern __inline__ unsigned sz __in##fnsuffix (unsigned int port)              \
        "tst    %2, #0x80000000\n\t"                                            \
        "mov    %0, %4\n\t"                                                     \
        "addeq  %0, %0, %3\n\t"                                                 \
-       "ldr" ##instr## "       %1, [%0, %2, lsl #2]"                           \
+       "ldr" ##instr## "       %1, [%0, %2, lsl #2]    @ in"###fnsuffix        \
        : "=&r" (temp), "=r" (value)                                            \
        : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)                \
        : "cc");                                                                \
@@ -87,11 +87,11 @@ DECLARE_IO(long,l,"")
 ({                                                                             \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "strb   %0, [%1, %2]"                                           \
+               "strb   %0, [%1, %2]            @ outbc"                        \
                : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2));          \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "strb   %0, [%1, %2]"                                           \
+               "strb   %0, [%1, %2]            @ outbc"                        \
                : : "r" (value), "r" (IO_BASE), "r" ((port) << 2));             \
 })
 
@@ -100,11 +100,11 @@ DECLARE_IO(long,l,"")
        unsigned char result;                                                   \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "ldrb   %0, [%1, %2]"                                           \
+               "ldrb   %0, [%1, %2]            @ inbc"                         \
                : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "ldrb   %0, [%1, %2]"                                           \
+               "ldrb   %0, [%1, %2]            @ inbc"                         \
                : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
        result;                                                                 \
 })
@@ -114,11 +114,11 @@ DECLARE_IO(long,l,"")
        unsigned long v = value;                                                \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]"                                           \
+               "str    %0, [%1, %2]            @ outwc"                        \
                : : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2));        \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]"                                           \
+               "str    %0, [%1, %2]            @ outwc"                        \
                : : "r" (v|v<<16), "r" (IO_BASE), "r" ((port) << 2));           \
 })
 
@@ -127,11 +127,11 @@ DECLARE_IO(long,l,"")
        unsigned short result;                                                  \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]"                                           \
+               "ldr    %0, [%1, %2]            @ inwc"                         \
                : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]"                                           \
+               "ldr    %0, [%1, %2]            @ inwc"                         \
                : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
        result & 0xffff;                                                        \
 })
@@ -141,11 +141,11 @@ DECLARE_IO(long,l,"")
        unsigned long v = value;                                                \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]"                                           \
+               "str    %0, [%1, %2]            @ outlc"                        \
                : : "r" (v), "r" (PCIO_BASE), "Jr" ((port) << 2));              \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]"                                           \
+               "str    %0, [%1, %2]            @ outlc"                        \
                : : "r" (v), "r" (IO_BASE), "r" ((port) << 2));                 \
 })
 
@@ -154,11 +154,11 @@ DECLARE_IO(long,l,"")
        unsigned long result;                                                   \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]"                                           \
+               "ldr    %0, [%1, %2]            @ inlc"                         \
                : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]"                                           \
+               "ldr    %0, [%1, %2]            @ inlc"                         \
                : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
        result;                                                                 \
 })
index 95ce641c428123bb70de1d98f220041cc940714c..e98d1ff33f0e72390411f841bbe8ba57ace06539 100644 (file)
@@ -24,7 +24,6 @@
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
-#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
 
 #define INIT_MMAP \
 { &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
index a28161cb2a4fd03affd65e2c7cc7449dede1f1f6..ba0c992582e01bd94efa8071da4cfad631a5b876 100644 (file)
@@ -6,13 +6,12 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-extern __inline__ void arch_hard_reset (void)
+extern __inline__ void arch_reset(char mode)
 {
        /*
         * loop endlessly
         */
        cli();
-       while (1);
 }
 
 #endif
index 5b1447b7e1c0d515e9f8d4817c013fcf36a04ea1..1f21a02e6a34f7d2911c9c9ba40e692e8f3c738f 100644 (file)
@@ -9,8 +9,10 @@
  *  10-Oct-1996        RMK     Created
  *  04-Dec-1997        RMK     Updated for new arch/arm/kernel/time.c
  *  07-Aug-1998        RMK     Updated for arch/arm/kernel/leds.c
+ *  28-Dec-1998        APH     Made leds code optional
  */
 
+#include <linux/config.h>
 #include <asm/leds.h>
 
 #define IRQ_TIMER IRQ_EBSA110_TIMER0
@@ -47,15 +49,19 @@ extern __inline__ int reset_timer (void)
 extern __inline__ int reset_timer (void)
 {
        static unsigned int divisor;
+#ifdef CONFIG_LEDS     
        static int count = 50;
+#endif
 
        *PIT_T1 = (PIT1_COUNT) & 0xff;
        *PIT_T1 = (PIT1_COUNT) >> 8;
 
+#ifdef CONFIG_LEDS
        if (--count == 0) {
                count = 50;
                leds_event(led_timer);
        }
+#endif
 
        if (divisor == 0) {
                divisor = DIVISOR - 1;
index 0123eb29a1998e8dd09e58bf789dec819e624dcd..2746584c8a17089f670cf4e7c4174f7509eec337 100644 (file)
@@ -9,7 +9,6 @@
 
 #ifdef __KERNEL__
 #define STACK_TOP              ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#define LIBRARY_START_TEXT     (0x00c00000)
 #endif
 
 #endif
index d3a2aa0c99e26fc1697c59a03789dca72d3b4dbd..28c093aec3eed2a6dc892af2d28d2b4184024041 100644 (file)
  */
 #define MAX_DMA_ADDRESS                0xffffffff
 
-/*
- * DMA modes - we have two, IN and OUT
- */
-
-typedef int dmamode_t;
-#define DMA_MODE_READ          0x44
-#define DMA_MODE_WRITE         0x48
-
 /*
  * The 21285 has two internal DMA channels; we call these 0 and 1.
  * On CATS hardware we have an additional eight ISA dma channels
  * numbered 2..9.
  */
 #define MAX_DMA_CHANNELS       10
-
 #define DMA_ISA_BASE           2
 #define DMA_FLOPPY             (DMA_ISA_BASE + 2)
 
index 4884821e38db5f9285ffd1e0f6669e89eb34455d..e08c5b823011c06e5c605722e5b7f679703e58a1 100644 (file)
  * 0xf8000000  0x7b010000      PCI Config type 0
  * 
  */
+
+#include <asm/dec21285.h>
  
 #define IO_BASE                        0xe0000000
 #define PCIO_BASE              0xffe00000
+#define PCI_IACK               0xfc000000 
 
 #define XBUS_LEDS              ((volatile unsigned char *)0xfff12000)
 #define XBUS_LED_AMBER         (1 << 0)
 #define XBUS_SWITCH_J17_11     ((*XBUS_SWITCH) & (1 << 5))
 #define XBUS_SWITCH_J17_9      ((*XBUS_SWITCH) & (1 << 6))
 
-#define CSR_SA110_CNTL         ((volatile unsigned long *)0xfe00013c)
-#define CSR_PCIADDR_EXTN       ((volatile unsigned long *)0xfe000140)
-#define CSR_PREFETCHMEMRANGE   ((volatile unsigned long *)0xfe000144)
-#define CSR_XBUS_CYCLE         ((volatile unsigned long *)0xfe000148)
-#define CSR_XBUS_IOSTROBE      ((volatile unsigned long *)0xfe00014c)
-#define CSR_DOORBELL_PCI       ((volatile unsigned long *)0xfe000150)
-#define CSR_DOORBELL_SA110     ((volatile unsigned long *)0xfe000154)
-
-
-#define CSR_UARTDR             ((volatile unsigned long *)0xfe000160)
-#define CSR_RXSTAT             ((volatile unsigned long *)0xfe000164)
-#define CSR_H_UBRLCR           ((volatile unsigned long *)0xfe000168)
-#define CSR_M_UBRLCR           ((volatile unsigned long *)0xfe00016c)
-#define CSR_L_UBRLCR           ((volatile unsigned long *)0xfe000170)
-#define CSR_UARTCON            ((volatile unsigned long *)0xfe000174)
-#define CSR_UARTFLG            ((volatile unsigned long *)0xfe000178)
-
-#define CSR_IRQ_STATUS         ((volatile unsigned long *)0xfe000180)
-#define CSR_IRQ_RAWSTATUS      ((volatile unsigned long *)0xfe000184)
-#define CSR_IRQ_ENABLE         ((volatile unsigned long *)0xfe000188)
-#define CSR_IRQ_DISABLE                ((volatile unsigned long *)0xfe00018c)
-#define CSR_IRQ_SOFT           ((volatile unsigned long *)0xfe000190)
-
-#define CSR_FIQ_STATUS         ((volatile unsigned long *)0xfe000280)
-#define CSR_FIQ_RAWSTATUS      ((volatile unsigned long *)0xfe000284)
-#define CSR_FIQ_ENABLE         ((volatile unsigned long *)0xfe000288)
-#define CSR_FIQ_DISABLE                ((volatile unsigned long *)0xfe00028c)
-#define CSR_FIQ_SOFT           ((volatile unsigned long *)0xfe000290)
-
-#define CSR_TIMER1_LOAD                ((volatile unsigned long *)0xfe000300)
-#define CSR_TIMER1_VALUE       ((volatile unsigned long *)0xfe000304)
-#define CSR_TIMER1_CNTL                ((volatile unsigned long *)0xfe000308)
-#define CSR_TIMER1_CLR         ((volatile unsigned long *)0xfe00030c)
-
-#define CSR_TIMER2_LOAD                ((volatile unsigned long *)0xfe000320)
-#define CSR_TIMER2_VALUE       ((volatile unsigned long *)0xfe000324)
-#define CSR_TIMER2_CNTL                ((volatile unsigned long *)0xfe000328)
-#define CSR_TIMER2_CLR         ((volatile unsigned long *)0xfe00032c)
-
-#define CSR_TIMER3_LOAD                ((volatile unsigned long *)0xfe000340)
-#define CSR_TIMER3_VALUE       ((volatile unsigned long *)0xfe000344)
-#define CSR_TIMER3_CNTL                ((volatile unsigned long *)0xfe000348)
-#define CSR_TIMER3_CLR         ((volatile unsigned long *)0xfe00034c)
-
-#define CSR_TIMER4_LOAD                ((volatile unsigned long *)0xfe000360)
-#define CSR_TIMER4_VALUE       ((volatile unsigned long *)0xfe000364)
-#define CSR_TIMER4_CNTL                ((volatile unsigned long *)0xfe000368)
-#define CSR_TIMER4_CLR         ((volatile unsigned long *)0xfe00036c)
-
-
-#define TIMER_CNTL_ENABLE      (1 << 7)
-#define TIMER_CNTL_AUTORELOAD  (1 << 6)
-#define TIMER_CNTL_DIV1                (0)
-#define TIMER_CNTL_DIV16       (1 << 2)
-#define TIMER_CNTL_DIV256      (2 << 2)
-#define TIMER_CNTL_CNTEXT      (3 << 2)
-
-
 #define KERNTOPHYS(a)          ((unsigned long)(&a))
 
 #define PARAMS_OFFSET          0x0100
 #define PARAMS_BASE            (PAGE_OFFSET + PARAMS_OFFSET)
 
-#define SAFE_ADDR              0x50000000
+#define FLUSH_BASE_PHYS                0x50000000
 
index f427173507880f9b17823088acd2c1e602dab6d5..1be73879d12edf4f9b28c706a9e5e41b9f99b806 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/arch-ebsa110/io.h
+ * linux/include/asm-arm/arch-ebsa285/io.h
  *
  * Copyright (C) 1997,1998 Russell King
  *
@@ -9,6 +9,8 @@
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
+#include <asm/dec21285.h>
+
 /*
  * This architecture does not require any delayed IO, and
  * has the constant-optimised IO
@@ -23,7 +25,7 @@
 extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port) \
 {                                                                              \
        __asm__ __volatile__(                                                   \
-       "str" ##instr## "       %0, [%1, %2]"                                   \
+       "str%?" ##instr## "     %0, [%1, %2]            @ out"###fnsuffix       \
        :                                                                       \
        : "r" (value), "r" (PCIO_BASE), typ (port));                            \
 }
@@ -33,7 +35,7 @@ extern __inline__ unsigned sz __in##fnsuffix (unsigned int port)              \
 {                                                                              \
        unsigned long value;                                                    \
        __asm__ __volatile__(                                                   \
-       "ldr" ##instr## "       %0, [%1, %2]"                                   \
+       "ldr%?" ##instr## "     %0, [%1, %2]            @ in"###fnsuffix        \
        : "=&r" (value)                                                         \
        : "r" (PCIO_BASE), typ (port));                                         \
        return (unsigned sz)value;                                              \
@@ -65,7 +67,7 @@ DECLARE_IO(long,l,"","Jr")
 #define __outbc(value,port)                                                    \
 ({                                                                             \
        __asm__ __volatile__(                                                   \
-       "strb   %0, [%1, %2]"                                                   \
+       "str%?b %0, [%1, %2]                            @ outbc"                \
        :                                                                       \
        : "r" (value), "r" (PCIO_BASE), "Jr" (port));                           \
 })
@@ -74,7 +76,7 @@ DECLARE_IO(long,l,"","Jr")
 ({                                                                             \
        unsigned char result;                                                   \
        __asm__ __volatile__(                                                   \
-       "ldrb   %0, [%1, %2]"                                                   \
+       "ldr%?b %0, [%1, %2]                            @ inbc"                 \
        : "=r" (result)                                                         \
        : "r" (PCIO_BASE), "Jr" (port));                                        \
        result;                                                                 \
@@ -83,7 +85,7 @@ DECLARE_IO(long,l,"","Jr")
 #define __outwc(value,port)                                                    \
 ({                                                                             \
        __asm__ __volatile__(                                                   \
-       "strh   %0, [%1, %2]"                                                   \
+       "str%?h %0, [%1, %2]                            @ outwc"                \
        :                                                                       \
        : "r" (value), "r" (PCIO_BASE), "r" (port));                            \
 })
@@ -92,7 +94,7 @@ DECLARE_IO(long,l,"","Jr")
 ({                                                                             \
        unsigned short result;                                                  \
        __asm__ __volatile__(                                                   \
-       "ldrh   %0, [%1, %2]"                                                   \
+       "ldr%?h %0, [%1, %2]                            @ inwc"                 \
        : "=r" (result)                                                         \
        : "r" (PCIO_BASE), "r" (port));                                         \
        result & 0xffff;                                                        \
@@ -101,7 +103,7 @@ DECLARE_IO(long,l,"","Jr")
 #define __outlc(value,port)                                                    \
 ({                                                                             \
        __asm__ __volatile__(                                                   \
-       "str    %0, [%1, %2]"                                                   \
+       "str%?  %0, [%1, %2]                            @ outlc"                \
        :                                                                       \
        : "r" (value), "r" (PCIO_BASE), "Jr" (port));                           \
 })
@@ -110,7 +112,7 @@ DECLARE_IO(long,l,"","Jr")
 ({                                                                             \
        unsigned long result;                                                   \
        __asm__ __volatile__(                                                   \
-       "ldr    %0, [%1, %2]"                                                   \
+       "ldr%?  %0, [%1, %2]                            @ inlc"                 \
        : "=r" (result)                                                         \
        : "r" (PCIO_BASE), "Jr" (port));                                        \
        result;                                                                 \
@@ -141,25 +143,68 @@ DECLARE_IO(long,l,"","Jr")
        (*(volatile unsigned long *)(p))
 
 /*
- * This is not sufficient... (and it's a hack anyway)
+ * ioremap support
+ */
+#define valid_ioaddr(iomem,size) ((iomem) < 0x80000000 && (iomem) + (size) <= 0x80000000)
+#define io_to_phys(iomem)      ((iomem) + DC21285_PCI_MEM)
+
+/*
+ * Fudge up IO addresses by this much.  Once we're confident that nobody
+ * is using read*() and so on with addresses they didn't get from ioremap
+ * this can go away.
+ */
+#define IO_FUDGE_FACTOR                0xe0000000
+
+extern inline void *ioremap(unsigned long iomem_addr, unsigned long size)
+{
+       unsigned long phys_addr;
+
+       if (!valid_ioaddr(iomem_addr, size))
+               return NULL;
+
+       phys_addr = io_to_phys(iomem_addr & PAGE_MASK);
+
+       return (void *)((unsigned long)__ioremap(phys_addr, size, 0) 
+                       - IO_FUDGE_FACTOR);
+}
+
+#define ioremap_nocache(iomem_addr,size) ioremap((iomem_addr),(size))
+
+extern void iounmap(void *addr);
+
+/*
+ * We'd probably be better off with these as macros rather than functions.
+ * Firstly that would be more efficient and secondly we could do with the
+ * ability to stop GCC whinging about type conversions.  --philb
  */
 static inline void writeb(unsigned char b, unsigned int addr)
 {
-       *(volatile unsigned char *)(0xe0000000 + (addr)) = b;
+       *(volatile unsigned char *)(IO_FUDGE_FACTOR + (addr)) = b;
 }
 
 static inline unsigned char readb(unsigned int addr)
 {
-       return *(volatile unsigned char *)(0xe0000000 + (addr));
+       return *(volatile unsigned char *)(IO_FUDGE_FACTOR + (addr));
 }
 
 static inline void writew(unsigned short b, unsigned int addr)
 {
-       *(volatile unsigned short *)(0xe0000000 + (addr)) = b;
+       *(volatile unsigned short *)(IO_FUDGE_FACTOR + (addr)) = b;
 }
 
 static inline unsigned short readw(unsigned int addr)
 {
-       return *(volatile unsigned short *)(0xe0000000 + (addr));
+       return *(volatile unsigned short *)(IO_FUDGE_FACTOR + (addr));
 }
+
+static inline void writel(unsigned long b, unsigned int addr)
+{
+       *(volatile unsigned long *)(IO_FUDGE_FACTOR + (addr)) = b;
+}
+
+static inline unsigned short readl(unsigned int addr)
+{
+       return *(volatile unsigned long *)(IO_FUDGE_FACTOR + (addr));
+}
+
 #endif
index 03b5e3c0d6f0fbbf0b59d0d061ede91b6ba199c9..74bc33c58e466277b1b825c739f9dc30db1ecba9 100644 (file)
@@ -7,7 +7,6 @@
  *   22-08-1998        RMK     Restructured IRQ routines
  *   03-09-1998        PJB     Merged CATS support
  */
-
 #include <linux/config.h>
 
 static void ebsa285_mask_irq(unsigned int irq)
index ad7b2f558428acaf1a85fadf97eeaf8108ccb66d..b26aa8f66790c755ad12066be57c828cee0bec7d 100644 (file)
  * On ebsa285, the dram is contiguous
  */
 #define __virt_to_phys__is_a_macro
-#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
+#define __virt_to_phys(vpage) ((unsigned long)(vpage) - PAGE_OFFSET)
 #define __phys_to_virt__is_a_macro
-#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
+#define __phys_to_virt(ppage) ((unsigned long)(ppage) + PAGE_OFFSET)
 
 #define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x)       (x - 0xe0000000)
+#define __virt_to_bus(x)       ((x) - 0xe0000000)
 #define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x)       (x + 0xe0000000)
+#define __bus_to_virt(x)       ((x) + 0xe0000000)
 
 #endif
index 95ce641c428123bb70de1d98f220041cc940714c..e98d1ff33f0e72390411f841bbe8ba57ace06539 100644 (file)
@@ -24,7 +24,6 @@
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
-#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
 
 #define INIT_MMAP \
 { &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
index fa4fc73c054d67b956d1df6ee3b7332cb080c2e0..c874f9dfa14ff87342bff360c57d728bdd42c32e 100644 (file)
@@ -11,6 +11,7 @@
 #define __ASM_ARCH_SERIAL_H
 
 #include <linux/config.h>
+
 #include <asm/irq.h>
 
 /*
index a3fed312c23bbeee1fd27c7a7f02e905071d9395..40d540dbae79ae2fa8f543007e8be539eb4444cb 100644 (file)
@@ -6,19 +6,26 @@
 #include <asm/hardware.h>
 #include <asm/leds.h>
 
-/* To reboot, we set up the 21285 watchdog and enable it.
- * We then wait for it to timeout.
- */
-extern __inline__ void arch_hard_reset (void)
+extern __inline__ void arch_reset(char mode)
 {
        cli();
-       *CSR_TIMER4_LOAD = 0x8000;
-       *CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
-       *CSR_SA110_CNTL |= 1 << 13;
-       while(1);
-}
 
-#define ARCH_IDLE_OK
+       if (mode == 's') {
+               __asm__ volatile (
+               "mov    lr, #0x41000000         @ prepare to jump to ROM
+                mov    r0, #0x130
+                mcr    p15, 0, r0, c1, c0      @ MMU off
+                mcr    p15, 0, ip, c7, c7      @ flush caches
+                mov    pc, lr");
+       } else {
+               /* To reboot, we set up the 21285 watchdog and enable it.
+                * We then wait for it to timeout.
+                */
+               *CSR_TIMER4_LOAD = 0x8000;
+               *CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
+               *CSR_SA110_CNTL |= 1 << 13;
+       }
+}
 
 #define arch_start_idle()      leds_event(led_idle_start)
 #define arch_end_idle()                leds_event(led_idle_end)
index ff14bdf68280f964c37d8fe30bcabdf042e1de96..342e9528ff1a64ae2b1fb05d855aa8081309ae03 100644 (file)
@@ -9,24 +9,29 @@
  * Changelog:
  *  21-Mar-1998        RMK     Created
  *  27-Aug-1998        PJB     CATS support
+ *  28-Dec-1998        APH     Made leds optional
  */
 
 #define RTC_PORT(x)            (0x72+(x))
 #define RTC_ALWAYS_BCD         1
 
+#include <linux/config.h>
 #include <asm/leds.h>
 #include <asm/system.h>
 #include <linux/mc146818rtc.h>
 
 extern __inline__ unsigned long gettimeoffset (void)
 {
-       return 0;
+       unsigned long value = LATCH - *CSR_TIMER1_VALUE;
+
+       return (tick * value) / LATCH;
 }
 
 extern __inline__ int reset_timer (void)
 {
        *CSR_TIMER1_CLR = 0;
 
+#ifdef CONFIG_LEDS
        /*
         * Do the LEDs thing on EBSA-285 hardware.
         */
@@ -47,7 +52,8 @@ extern __inline__ int reset_timer (void)
                        leds_event(led_timer);
                }
        }
-
+#endif
+       
        return 1;
 }
 
index d6097d43ff1122ce8f8d5f22dae75a75e113d1d6..7f655745f463c4de1624a89b641487be42f9a1e0 100644 (file)
@@ -4,27 +4,25 @@
  * Copyright (C) 1996,1997,1998 Russell King
  */
 
+#define BASE 0x42000160
+
+static __inline__ void putc(char c)
+{
+       while (*((volatile unsigned int *)(BASE + 0x18)) & 8);
+       *((volatile unsigned int *)(BASE)) = c;
+}
+
 /*
  * This does not append a newline
  */
 static void puts(const char *s)
 {
-       __asm__ __volatile__("
-       ldrb    %0, [%2], #1
-       teq     %0, #0
-       beq     3f
-1:     strb    %0, [%3]
-2:     ldrb    %1, [%3, #0x14]
-       and     %1, %1, #0x60
-       teq     %1, #0x60
-       bne     2b
-       teq     %0, #'\n'
-       moveq   %0, #'\r'
-       beq     1b
-       ldrb    %0, [%2], #1
-       teq     %0, #0
-       bne     1b
-3:     " : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc");
+       while (*s) {
+               putc(*s);
+               if (*s == '\n')
+                       putc('\r');
+               s++;
+       }
 }
 
 /*
index 9051eb0c94ab9f3a9d510d12bdb90f173ef5a77c..4972f5f707de35aefe8996d5d02811c5b010e81f 100644 (file)
@@ -9,7 +9,6 @@
 
 #ifdef __KERNEL__
 #define STACK_TOP              ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#define LIBRARY_START_TEXT     (0x00c00000)
 #endif
 
 #endif
index 83931f5661c767150636e36385a54a68630ab6cb..6d0a46e172bb083b8ca80e1cf3b80f1cdf4f4d19 100644 (file)
@@ -7,6 +7,3 @@
  * Copyright (C) 1998 Philip Blundell
  */
 
-/* Need this to keep <asm/dma.h> happy. */
-typedef unsigned int dmamode_t;
-
index 57607681c30171bdfa1d425591df7116c5ca93ae..6141bbf4c22661eb8e8cac169fcceb1fae7f8241 100644 (file)
@@ -34,6 +34,6 @@
  */
 #define RAM_BASE               0x40000000
 #define KERNTOPHYS(a)          ((unsigned long)(&a))
-#define SAFE_ADDR              0x40000000
+#define FLUSH_BASE_PHYS                0x40000000
 
 #endif
index 5489c8267842b3594af0bc4bad91b0d30339b8c2..f722be87cf11e2311a66afb7e1a88c7632f6f917 100644 (file)
@@ -25,7 +25,6 @@
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
-#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
 
 #define INIT_MMAP \
 { &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
index 7042dc4369e0a7934aa95ea4450aaa2b8e27d8b6..b5a2464b25b6e7f759af263dfcb170b58a8d8e7d 100644 (file)
@@ -6,13 +6,12 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-extern __inline__ void arch_hard_reset (void)
+extern __inline__ void arch_reset(char mode)
 {
        /*
         * loop endlessly - the watchdog will reset us if it's enabled.
         */
        cli();
-       while (1);
 }
 
 #endif
index 6b55ee0764d3eb108660fa76754592e9f6980363..598614f23e56b54f020e696d16e18316c59a016f 100644 (file)
@@ -9,7 +9,6 @@
 
 #ifdef __KERNEL__
 #define STACK_TOP              ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#define LIBRARY_START_TEXT     (0x00c00000)
 #endif
 
 #endif
index 0f556e8564b8ce0989064e95ae9072f6fa67c1a7..c6b6679af11d70bdd54b6ecbc4ee0a550cd47d3b 100644 (file)
@@ -7,15 +7,6 @@
  * bytes of RAM.
  */
 #define MAX_DMA_ADDRESS                0xd0000000
-
-/*
- * DMA modes - we have two, IN and OUT
- */
-typedef enum {
-       DMA_MODE_READ,
-       DMA_MODE_WRITE
-} dmamode_t;
-
 #define MAX_DMA_CHANNELS       8
 
 #define DMA_0                  0
index a846834fca5a12363a16172a6c953bafa0c39545..8ca6273ff711c3f7e881a8fec680664a2ee43691 100644 (file)
@@ -13,6 +13,7 @@
  * What hardware must be present
  */
 #define HAS_IOMD
+#include <asm/iomd.h>
 #define HAS_VIDC20
 
 /* Hardware addresses of major areas.
index 43d787b9656729d3d94b7fcbdbfb377e9923d661..ecf07c17c88368a45e3847112f21a5e2ed4590f8 100644 (file)
@@ -36,7 +36,7 @@ extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port)        \
        "tst    %2, #0x80000000\n\t"                                            \
        "mov    %0, %4\n\t"                                                     \
        "addeq  %0, %0, %3\n\t"                                                 \
-       "str" ##instr## "       %1, [%0, %2, lsl #2]"                           \
+       "str" ##instr## "       %1, [%0, %2, lsl #2]    @ out"###fnsuffix       \
        : "=&r" (temp)                                                          \
        : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)   \
        : "cc");                                                                \
@@ -50,7 +50,7 @@ extern __inline__ unsigned sz __in##fnsuffix (unsigned int port)              \
        "tst    %2, #0x80000000\n\t"                                            \
        "mov    %0, %4\n\t"                                                     \
        "addeq  %0, %0, %3\n\t"                                                 \
-       "ldr" ##instr## "       %1, [%0, %2, lsl #2]"                           \
+       "ldr" ##instr## "       %1, [%0, %2, lsl #2]    @ in"###fnsuffix        \
        : "=&r" (temp), "=r" (value)                                            \
        : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)                \
        : "cc");                                                                \
@@ -87,11 +87,11 @@ DECLARE_IO(long,l,"")
 ({                                                                             \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "strb   %0, [%1, %2]"                                           \
+               "strb   %0, [%1, %2]    @ outbc"                                \
                : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2));          \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "strb   %0, [%1, %2]"                                           \
+               "strb   %0, [%1, %2]    @ outbc"                                \
                : : "r" (value), "r" (IO_BASE), "r" ((port) << 2));             \
 })
 
@@ -100,11 +100,11 @@ DECLARE_IO(long,l,"")
        unsigned char result;                                                   \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "ldrb   %0, [%1, %2]"                                           \
+               "ldrb   %0, [%1, %2]    @ inbc"                                 \
                : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "ldrb   %0, [%1, %2]"                                           \
+               "ldrb   %0, [%1, %2]    @ inbc"                                 \
                : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
        result;                                                                 \
 })
@@ -114,11 +114,11 @@ DECLARE_IO(long,l,"")
        unsigned long v = value;                                                \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]"                                           \
+               "str    %0, [%1, %2]    @ outwc"                                \
                : : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2));        \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]"                                           \
+               "str    %0, [%1, %2]    @ outwc"                                \
                : : "r" (v|v<<16), "r" (IO_BASE), "r" ((port) << 2));           \
 })
 
@@ -127,11 +127,11 @@ DECLARE_IO(long,l,"")
        unsigned short result;                                                  \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]"                                           \
+               "ldr    %0, [%1, %2]    @ inwc"                                 \
                : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]"                                           \
+               "ldr    %0, [%1, %2]    @ inwc"                                 \
                : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
        result & 0xffff;                                                        \
 })
@@ -141,11 +141,11 @@ DECLARE_IO(long,l,"")
        unsigned long v = value;                                                \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]"                                           \
+               "str    %0, [%1, %2]    @ outlc"                                \
                : : "r" (v), "r" (PCIO_BASE), "Jr" ((port) << 2));              \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "str    %0, [%1, %2]"                                           \
+               "str    %0, [%1, %2]    @ outlc"                                \
                : : "r" (v), "r" (IO_BASE), "r" ((port) << 2));                 \
 })
 
@@ -154,11 +154,11 @@ DECLARE_IO(long,l,"")
        unsigned long result;                                                   \
        if (__PORT_PCIO((port)))                                                \
                __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]"                                           \
+               "ldr    %0, [%1, %2]    @ inlc"                                 \
                : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2));         \
        else                                                                    \
                __asm__ __volatile__(                                           \
-               "ldr    %0, [%1, %2]"                                           \
+               "ldr    %0, [%1, %2]    @ inlc"                                 \
                : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2));            \
        result;                                                                 \
 })
index 86e999db97df831caa998bc3e6724f626e9d1488..2fd9155b266a2e3adb430dd5b95b17363894c1dd 100644 (file)
@@ -27,7 +27,6 @@
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
-#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
 
 #define INIT_MMAP \
 { &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
index aa6e645c61ee1f4a0b2b60ab4eb71dd7d4cdbbd8..e0a16f61d51f7658ff6740fc97108a6e87b56ff5 100644 (file)
@@ -8,10 +8,10 @@
 
 #include <asm/proc-fns.h>
 
-#define arch_hard_reset() {                                            \
+#define arch_reset(mode) {                                             \
        extern void ecard_reset (int card);                             \
        outb (0, IOMD_ROMCR0);                                          \
-       ecard_reset (-1);                                               \
+       ecard_reset(-1);                                                \
        cli();                                                          \
        __asm__ __volatile__("msr  spsr, r1;"                           \
                             "mcr  p15, 0, %0, c1, c0, 0;"              \
index 05f7c1d5891722ef60a33c9943cd6b3c736cb37d..011b08373ba4c70346abdf57cfe2a0efd7cd2783 100644 (file)
@@ -9,7 +9,6 @@
 
 #ifdef __KERNEL__
 #define STACK_TOP              ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#define LIBRARY_START_TEXT     (0x00c00000)
 #endif
 
 #endif
index e6d04267586113582734add1e79781a4d0ac87d6..f205f03768725d7ce7fa8795b6d8791d432b165d 100644 (file)
  * bytes of RAM.
  */
 #define MAX_DMA_ADDRESS                0xd0000000
-
-/*
- * DMA modes - we have two, IN and OUT
- */
-typedef enum {
-       DMA_MODE_READ,
-       DMA_MODE_WRITE
-} dmamode_t;
-
 #define MAX_DMA_CHANNELS       8
 
 #endif /* _ASM_ARCH_DMA_H */
index 4cf253088a544f02358f6dadd00c3d2a6fe2706e..e95b1e7b690abfb86e5dff0b8ed524897d1f6b24 100644 (file)
 //#define PARAMS_OFFSET                0x0100
 //#define PARAMS_BASE          (PAGE_OFFSET + PARAMS_OFFSET)
 
-#define SAFE_ADDR              0x50000000
+#define FLUSH_BASE_PHYS                0x50000000
+
+/* GPIO pins */
+#define GPIO_CCLK              0x800
+#define GPIO_DSCLK             0x400
+#define GPIO_E2CLK             0x200
+#define GPIO_IOLOAD            0x100
+#define GPIO_RED_LED           0x080
+#define GPIO_WDTIMER           0x040
+#define GPIO_DATA              0x020
+#define GPIO_IOCLK             0x010
+#define GPIO_DONE              0x008
+#define GPIO_FAN               0x004
+#define GPIO_GREEN_LED         0x002
+#define GPIO_RESET             0x001
+
+/* CPLD pins */
+#define CPLD_DSRESET           8
+#define CPLD_UNMUTE            2
+
+#ifndef __ASSEMBLY__
+extern void gpio_modify_op(int mask, int set);
+extern void gpio_modify_io(int mask, int in);
+extern int  gpio_read(void);
+extern void cpld_modify(int mask, int set);
+#endif
index f5cd3fd9593bc2e04e8cfd42f6d263b02295d3c5..da1b48599fbdab480062cdad9fb76aa861801b6d 100644 (file)
@@ -23,7 +23,7 @@
 extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port) \
 {                                                                              \
        __asm__ __volatile__(                                                   \
-       "str" ##instr## "       %0, [%1, %2]"                                   \
+       "str%?" ##instr## "     %0, [%1, %2]            @ out"###fnsuffix       \
        :                                                                       \
        : "r" (value), "r" (PCIO_BASE), typ (port));                            \
 }
@@ -33,7 +33,7 @@ extern __inline__ unsigned sz __in##fnsuffix (unsigned int port)              \
 {                                                                              \
        unsigned long value;                                                    \
        __asm__ __volatile__(                                                   \
-       "ldr" ##instr## "       %0, [%1, %2]"                                   \
+       "ldr%?" ##instr## "     %0, [%1, %2]            @ in"###fnsuffix        \
        : "=&r" (value)                                                         \
        : "r" (PCIO_BASE), typ (port));                                         \
        return (unsigned sz)value;                                              \
@@ -65,7 +65,7 @@ DECLARE_IO(long,l,"","Jr")
 #define __outbc(value,port)                                                    \
 ({                                                                             \
        __asm__ __volatile__(                                                   \
-       "strb   %0, [%1, %2]"                                                   \
+       "strb   %0, [%1, %2]                            @ outbc"                \
        :                                                                       \
        : "r" (value), "r" (PCIO_BASE), "Jr" (port));                           \
 })
@@ -74,7 +74,7 @@ DECLARE_IO(long,l,"","Jr")
 ({                                                                             \
        unsigned char result;                                                   \
        __asm__ __volatile__(                                                   \
-       "ldrb   %0, [%1, %2]"                                                   \
+       "ldrb   %0, [%1, %2]                            @ inbc"                 \
        : "=r" (result)                                                         \
        : "r" (PCIO_BASE), "Jr" (port));                                        \
        result;                                                                 \
@@ -83,7 +83,7 @@ DECLARE_IO(long,l,"","Jr")
 #define __outwc(value,port)                                                    \
 ({                                                                             \
        __asm__ __volatile__(                                                   \
-       "strh   %0, [%1, %2]"                                                   \
+       "strh   %0, [%1, %2]                            @ outwc"                \
        :                                                                       \
        : "r" (value), "r" (PCIO_BASE), "r" (port));                            \
 })
@@ -92,7 +92,7 @@ DECLARE_IO(long,l,"","Jr")
 ({                                                                             \
        unsigned short result;                                                  \
        __asm__ __volatile__(                                                   \
-       "ldrh   %0, [%1, %2]"                                                   \
+       "ldrh   %0, [%1, %2]                            @ inwc"                 \
        : "=r" (result)                                                         \
        : "r" (PCIO_BASE), "r" (port));                                         \
        result & 0xffff;                                                        \
@@ -101,7 +101,7 @@ DECLARE_IO(long,l,"","Jr")
 #define __outlc(value,port)                                                    \
 ({                                                                             \
        __asm__ __volatile__(                                                   \
-       "str    %0, [%1, %2]"                                                   \
+       "str    %0, [%1, %2]                            @ outlc"                \
        :                                                                       \
        : "r" (value), "r" (PCIO_BASE), "Jr" (port));                           \
 })
@@ -110,7 +110,7 @@ DECLARE_IO(long,l,"","Jr")
 ({                                                                             \
        unsigned long result;                                                   \
        __asm__ __volatile__(                                                   \
-       "ldr    %0, [%1, %2]"                                                   \
+       "ldr    %0, [%1, %2]                            @ inlc"                 \
        : "=r" (result)                                                         \
        : "r" (PCIO_BASE), "Jr" (port));                                        \
        result;                                                                 \
index 715439d1160e9b04832560317b8f4b00b82afce9..e9df93f5cdec5038de8fef27fb90e7959b0a4c16 100644 (file)
@@ -39,7 +39,7 @@
 #define IRQ_HARDDISK           30      /* from 553.14 */
 
 /* These defines handle the translation from the above FB #defines
- * into physical buts for the FootBridge IRQ registers
+ * into physical bits for the FootBridge IRQ registers
  */
 #define IRQ_MASK_SOFTIRQ       0x00000002
 #define IRQ_MASK_UART_DEBUG    0x0000000C
 #define IRQ_MASK_VIDCOMP       0x00000400
 #define IRQ_MASK_EXTERN_IRQ    0x00000800
 #define IRQ_MASK_DMA1          0x00030000
-#define IRQ_MASK_PCI_ERR       0xf0000000
+#define IRQ_MASK_PCI_ERR       0xf8800000
 
 /*
  * Now map them to the Linux interrupts
  */
+#undef IRQ_TIMER
 #define IRQ_TIMER              IRQ_TIMER0
+#undef RTC_IRQ
+#define RTC_IRQ                        IRQ_RTC_ALARM
+#undef AUX_IRQ
+#define AUX_IRQ                        IRQ_MOUSE
 
 #define irq_cannonicalize(i)   (i)
index e752df4c01df4d195d9af2064864ab44520dd914..5d84ad49881a6791f9f6bbaea5a85b0fb50f6bf9 100644 (file)
@@ -24,7 +24,6 @@
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
-#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
 
 #define INIT_MMAP \
 { &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
index 7fe88446096b848b4b6bdad28a95bd5a5d931157..dc21f08d8457689cc849ea63af05300daec7db69 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/include/asm-arm/arch-ebsa285/system.h
+ * linux/include/asm-arm/arch-vnc/system.h
  *
  * Copyright (c) 1996,1997,1998 Russell King.
  * Copyright (c) 1998 Corel Computer Corp.
@@ -9,7 +9,7 @@
 #include <asm/leds.h>
 #include <asm/io.h>
 
-extern __inline__ void arch_hard_reset (void)
+extern __inline__ void arch_reset(char mode)
 {
        cli();
 
@@ -31,11 +31,7 @@ extern __inline__ void arch_hard_reset (void)
        /* set a RED LED and toggle WD_TIMER for rebooting...
         */
        outb(0xC4, 0x338);
-       
-       while(1);
 }
 
-#define ARCH_IDLE_OK
-
 #define arch_start_idle()      leds_event(led_idle_start)
 #define arch_end_idle()                leds_event(led_idle_end)
index 595672e7b0d57029dfe442d86c9801cb08640b0d..c55000bdc8094d1183b40a3e8a50c7cabf2556a7 100644 (file)
@@ -4,20 +4,80 @@
  * Copyright (c) 1997 Corel Computer Corp.
  * Slight modifications to bring in line with ebsa285 port.
  *  -- Russell King.
+ *  Added LED driver (based on the ebsa285 code) - Alex Holden 28/12/98.
  */
 
+#include <linux/config.h>
 #include <linux/mc146818rtc.h>
 
+#include <asm/leds.h>
+#include <asm/system.h>
+
 #undef IRQ_TIMER
 #define IRQ_TIMER              IRQ_TIMER4
 
+#define mSEC_10_from_14 ((14318180 + 100) / 200)
+
 extern __inline__ unsigned long gettimeoffset (void)
 {
-       return 0;
+       int count;
+
+       static int count_p = (mSEC_10_from_14/6);    /* for the first call after boot */
+       static unsigned long jiffies_p = 0;
+
+       /*
+        * cache volatile jiffies temporarily; we have IRQs turned off. 
+        */
+       unsigned long jiffies_t;
+
+       /* timer count may underflow right here */
+       outb_p(0x00, 0x43);     /* latch the count ASAP */
+
+       count = inb_p(0x40);    /* read the latched count */
+
+       /*
+        * We do this guaranteed double memory access instead of a _p 
+        * postfix in the previous port access. Wheee, hackady hack
+        */
+       jiffies_t = jiffies;
+
+       count |= inb_p(0x40) << 8;
+
+       /* Detect timer underflows.  If we haven't had a timer tick since 
+          the last time we were called, and time is apparently going
+          backwards, the counter must have wrapped during this routine. */
+       if ((jiffies_t == jiffies_p) && (count > count_p))
+               count -= (mSEC_10_from_14/6);
+       else
+               jiffies_p = jiffies_t;
+
+       count_p = count;
+
+       count = (((mSEC_10_from_14/6)-1) - count) * tick;
+       count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6);
+
+       return count;
 }
 
 extern __inline__ int reset_timer (void)
 {
+#ifdef CONFIG_LEDS
+       static unsigned int count = 50;
+       static int last_pid;
+
+       if (current->pid != last_pid) {
+               last_pid = current->pid;
+               if (last_pid)
+                       leds_event(led_idle_end);
+               else
+                       leds_event(led_idle_start);
+       }
+
+       if (--count == 0) {
+               count = 50;
+               leds_event(led_timer);
+       }
+#endif
        return 1;
 }
 
@@ -138,8 +198,6 @@ extern __inline__ unsigned long get_cmos_time(void)
        return mktime(year, mon, day, hour, min, sec);
 }
 
-#define mSEC_10_from_14 ((14318180 + 100) / 200)
-
 /*
  * Set up timer interrupt, and return the current time in seconds.
  */
index 48d688eb16eb5a218e3c73a3332233614366dbac..4311942346caa89910d9b5d86334b549a0443440 100644 (file)
 #ifndef __ASM_ARM_ATOMIC_H
 #define __ASM_ARM_ATOMIC_H
 
+#ifdef __SMP__
+#error SMP not supported
+#endif
+
+#include <linux/config.h>
+
+#ifdef CONFIG_ARCH_CO285
+typedef struct { volatile int counter; } atomic_t;
+#else
 typedef struct { int counter; } atomic_t;
+#endif
 
 #define ATOMIC_INIT(i) { (i) }
 
 #ifdef __KERNEL__
 #include <asm/system.h>
 
-#ifdef __SMP__
-#error SMP not supported
-#endif
-
 #define atomic_read(v) ((v)->counter)
 #define atomic_set(v,i)        (((v)->counter) = (i))
 
index 14273481bd8ff09f0c836338fac8ec3b583e03c2..60a191cc378d5911efb7640c0645a63c4900fb0e 100644 (file)
@@ -3,10 +3,14 @@
 
 #include <asm/types.h>
 
-#if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ < 80
+#if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ < 8
 
-/* Recent versions of GCC can do as well or better than this
-   on their own - we shouldn't interfere.  */
+/* Recent versions of GCC can open code the swaps at least as well
+   as we can write them by hand, so the "optimisations" here only 
+   make sense for older compilers.  Worse, some versions of GCC
+   actually go wrong in the presence of the assembler versions.
+   We play it safe and only turn them on for compilers older than
+   GCC 2.8.0.  */
 
 static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
 {
@@ -36,6 +40,11 @@ static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
 
 #endif /* __GNUC__ */
 
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
 #include <linux/byteorder/little_endian.h>
 
 #endif
index eadab0ee667ca0d43d1018ab799241118bc196e6..0facd0b7cfd5c6c670beb894f60e68151c573669 100644 (file)
@@ -2,6 +2,8 @@
  * include/asm-arm/dec21285.h
  *
  * Copyright (C) 1998 Russell King
+ *
+ * DC21285 registers
  */
 #define DC21285_PCI_IACK               0x79000000
 #define DC21285_ARMCSR_BASE            0x42000000
 #define DC21285_PCI_MEM                        0x80000000
 
 #ifndef __ASSEMBLY__
-
-/*
- * DEC21285
- */
-#define CSR_SA110_CNTL         ((volatile unsigned long *)0xfe00013c)
-#define CSR_PCIADDR_EXTN       ((volatile unsigned long *)0xfe000140)
-#define CSR_PREFETCHMEMRANGE   ((volatile unsigned long *)0xfe000144)
-#define CSR_XBUS_CYCLE         ((volatile unsigned long *)0xfe000148)
-#define CSR_XBUS_IOSTROBE      ((volatile unsigned long *)0xfe00014c)
-#define CSR_DOORBELL_PCI       ((volatile unsigned long *)0xfe000150)
-#define CSR_DOORBELL_SA110     ((volatile unsigned long *)0xfe000154)
-
-#define CSR_UARTDR             ((volatile unsigned long *)0xfe000160)
-#define CSR_RXSTAT             ((volatile unsigned long *)0xfe000164)
-#define CSR_H_UBRLCR           ((volatile unsigned long *)0xfe000168)
-#define CSR_M_UBRLCR           ((volatile unsigned long *)0xfe00016c)
-#define CSR_L_UBRLCR           ((volatile unsigned long *)0xfe000170)
-#define CSR_UARTCON            ((volatile unsigned long *)0xfe000174)
-#define CSR_UARTFLG            ((volatile unsigned long *)0xfe000178)
-
-#define CSR_IRQ_STATUS         ((volatile unsigned long *)0xfe000180)
-#define CSR_IRQ_RAWSTATUS      ((volatile unsigned long *)0xfe000184)
-#define CSR_IRQ_ENABLE         ((volatile unsigned long *)0xfe000188)
-#define CSR_IRQ_DISABLE                ((volatile unsigned long *)0xfe00018c)
-#define CSR_IRQ_SOFT           ((volatile unsigned long *)0xfe000190)
-
-#define CSR_FIQ_STATUS         ((volatile unsigned long *)0xfe000280)
-#define CSR_FIQ_RAWSTATUS      ((volatile unsigned long *)0xfe000284)
-#define CSR_FIQ_ENABLE         ((volatile unsigned long *)0xfe000288)
-#define CSR_FIQ_DISABLE                ((volatile unsigned long *)0xfe00028c)
-#define CSR_FIQ_SOFT           ((volatile unsigned long *)0xfe000290)
-
-#define CSR_TIMER1_LOAD                ((volatile unsigned long *)0xfe000300)
-#define CSR_TIMER1_VALUE       ((volatile unsigned long *)0xfe000304)
-#define CSR_TIMER1_CNTL                ((volatile unsigned long *)0xfe000308)
-#define CSR_TIMER1_CLR         ((volatile unsigned long *)0xfe00030c)
-
-#define CSR_TIMER2_LOAD                ((volatile unsigned long *)0xfe000320)
-#define CSR_TIMER2_VALUE       ((volatile unsigned long *)0xfe000324)
-#define CSR_TIMER2_CNTL                ((volatile unsigned long *)0xfe000328)
-#define CSR_TIMER2_CLR         ((volatile unsigned long *)0xfe00032c)
-
-#define CSR_TIMER3_LOAD                ((volatile unsigned long *)0xfe000340)
-#define CSR_TIMER3_VALUE       ((volatile unsigned long *)0xfe000344)
-#define CSR_TIMER3_CNTL                ((volatile unsigned long *)0xfe000348)
-#define CSR_TIMER3_CLR         ((volatile unsigned long *)0xfe00034c)
-
-#define CSR_TIMER4_LOAD                ((volatile unsigned long *)0xfe000360)
-#define CSR_TIMER4_VALUE       ((volatile unsigned long *)0xfe000364)
-#define CSR_TIMER4_CNTL                ((volatile unsigned long *)0xfe000368)
-#define CSR_TIMER4_CLR         ((volatile unsigned long *)0xfe00036c)
-
+#define DC21285_IO(x)          ((volatile unsigned long *)(0xfe000000+(x)))
 #else
-
-#define CSR_SA110_CNTL         0x13c
-#define CSR_PCIADDR_EXTN       0x140
-#define CSR_PREFETCHMEMRANGE   0x144
-#define CSR_XBUS_CYCLE         0x148
-#define CSR_XBUS_IOSTROBE      0x14c
-#define CSR_DOORBELL_PCI       0x150
-#define CSR_DOORBELL_SA110     0x154
-
-#define CSR_UARTDR             0x160
-#define CSR_RXSTAT             0x164
-#define CSR_H_UBRLCR           0x168
-#define CSR_M_UBRLCR           0x16c
-#define CSR_L_UBRLCR           0x170
-#define CSR_UARTCON            0x174
-#define CSR_UARTFLG            0x178
-
-#define CSR_IRQ_STATUS         0x180
-#define CSR_IRQ_RAWSTATUS      0x184
-#define CSR_IRQ_ENABLE         0x188
-#define CSR_IRQ_DISABLE                0x18c
-#define CSR_IRQ_SOFT           0x190
-
-#define CSR_FIQ_STATUS         0x280
-#define CSR_FIQ_RAWSTATUS      0x284
-#define CSR_FIQ_ENABLE         0x288
-#define CSR_FIQ_DISABLE                0x28c
-#define CSR_FIQ_SOFT           0x290
-
-#define CSR_TIMER1_LOAD                0x300
-#define CSR_TIMER1_VALUE       0x304
-#define CSR_TIMER1_CNTL                0x308
-#define CSR_TIMER1_CLR         0x30c
-
-#define CSR_TIMER2_LOAD                0x320
-#define CSR_TIMER2_VALUE       0x324
-#define CSR_TIMER2_CNTL                0x328
-#define CSR_TIMER2_CLR         0x32c
-
-#define CSR_TIMER3_LOAD                0x340
-#define CSR_TIMER3_VALUE       0x344
-#define CSR_TIMER3_CNTL                0x348
-#define CSR_TIMER3_CLR         0x34c
-
-#define CSR_TIMER4_LOAD                0x360
-#define CSR_TIMER4_VALUE       0x364
-#define CSR_TIMER4_CNTL                0x368
-#define CSR_TIMER4_CLR         0x36c
-
+#define DC21285_IO(x)          (x)
 #endif
 
+#define CSR_PCICMD             DC21285_IO(0x0004)
+#define CSR_PCICACHELINESIZE   DC21285_IO(0x000c)
+#define CSR_PCICSRBASE         DC21285_IO(0x0010)
+#define CSR_PCICSRIOBASE       DC21285_IO(0x0014)
+#define CSR_PCISDRAMBASE       DC21285_IO(0x0018)
+#define CSR_PCIROMBASE         DC21285_IO(0x0030)
+#define CSR_CSRBASEMASK                DC21285_IO(0x00f8)
+#define CSR_CSRBASEOFFSET      DC21285_IO(0x00fc)
+#define CSR_SDRAMBASEMASK      DC21285_IO(0x0100)
+#define CSR_SDRAMBASEOFFSET    DC21285_IO(0x0104)
+#define CSR_ROMBASEMASK                DC21285_IO(0x0108)
+#define CSR_SDRAMTIMING                DC21285_IO(0x010c)
+#define CSR_SDRAMADDRSIZE0     DC21285_IO(0x0110)
+#define CSR_SDRAMADDRSIZE1     DC21285_IO(0x0114)
+#define CSR_SDRAMADDRSIZE2     DC21285_IO(0x0118)
+#define CSR_SDRAMADDRSIZE3     DC21285_IO(0x011c)
+#define CSR_I2O_INFREEHEAD     DC21285_IO(0x0120)
+#define CSR_I2O_INPOSTTAIL     DC21285_IO(0x0124)
+#define CSR_I2O_OUTPOSTHEAD    DC21285_IO(0x0128)
+#define CSR_I2O_OUTFREETAIL    DC21285_IO(0x012c)
+#define CSR_I2O_INFREECOUNT    DC21285_IO(0x0130)
+#define CSR_I2O_OUTPOSTCOUNT   DC21285_IO(0x0134)
+#define CSR_I2O_INPOSTCOUNT    DC21285_IO(0x0138)
+#define CSR_SA110_CNTL         DC21285_IO(0x013c)
+#define CSR_PCIADDR_EXTN       DC21285_IO(0x0140)
+#define CSR_PREFETCHMEMRANGE   DC21285_IO(0x0144)
+#define CSR_XBUS_CYCLE         DC21285_IO(0x0148)
+#define CSR_XBUS_IOSTROBE      DC21285_IO(0x014c)
+#define CSR_DOORBELL_PCI       DC21285_IO(0x0150)
+#define CSR_DOORBELL_SA110     DC21285_IO(0x0154)
+#define CSR_UARTDR             DC21285_IO(0x0160)
+#define CSR_RXSTAT             DC21285_IO(0x0164)
+#define CSR_H_UBRLCR           DC21285_IO(0x0168)
+#define CSR_M_UBRLCR           DC21285_IO(0x016c)
+#define CSR_L_UBRLCR           DC21285_IO(0x0170)
+#define CSR_UARTCON            DC21285_IO(0x0174)
+#define CSR_UARTFLG            DC21285_IO(0x0178)
+#define CSR_IRQ_STATUS         DC21285_IO(0x0180)
+#define CSR_IRQ_RAWSTATUS      DC21285_IO(0x0184)
+#define CSR_IRQ_ENABLE         DC21285_IO(0x0188)
+#define CSR_IRQ_DISABLE                DC21285_IO(0x018c)
+#define CSR_IRQ_SOFT           DC21285_IO(0x0190)
+#define CSR_FIQ_STATUS         DC21285_IO(0x0280)
+#define CSR_FIQ_RAWSTATUS      DC21285_IO(0x0284)
+#define CSR_FIQ_ENABLE         DC21285_IO(0x0288)
+#define CSR_FIQ_DISABLE                DC21285_IO(0x028c)
+#define CSR_FIQ_SOFT           DC21285_IO(0x0290)
+#define CSR_TIMER1_LOAD                DC21285_IO(0x0300)
+#define CSR_TIMER1_VALUE       DC21285_IO(0x0304)
+#define CSR_TIMER1_CNTL                DC21285_IO(0x0308)
+#define CSR_TIMER1_CLR         DC21285_IO(0x030c)
+#define CSR_TIMER2_LOAD                DC21285_IO(0x0320)
+#define CSR_TIMER2_VALUE       DC21285_IO(0x0324)
+#define CSR_TIMER2_CNTL                DC21285_IO(0x0328)
+#define CSR_TIMER2_CLR         DC21285_IO(0x032c)
+#define CSR_TIMER3_LOAD                DC21285_IO(0x0340)
+#define CSR_TIMER3_VALUE       DC21285_IO(0x0344)
+#define CSR_TIMER3_CNTL                DC21285_IO(0x0348)
+#define CSR_TIMER3_CLR         DC21285_IO(0x034c)
+#define CSR_TIMER4_LOAD                DC21285_IO(0x0360)
+#define CSR_TIMER4_VALUE       DC21285_IO(0x0364)
+#define CSR_TIMER4_CNTL                DC21285_IO(0x0368)
+#define CSR_TIMER4_CLR         DC21285_IO(0x036c)
+
 #define TIMER_CNTL_ENABLE      (1 << 7)
 #define TIMER_CNTL_AUTORELOAD  (1 << 6)
 #define TIMER_CNTL_DIV1                (0)
index bb5ab18597ac5b840deb75d05ff135f9c23360df..9fb7a0242aceddb7eb08f0d86321dc0ab4cbbc04 100644 (file)
@@ -3,10 +3,24 @@
 
 typedef unsigned int dmach_t;
 
+#include <linux/config.h>
+#include <linux/kernel.h>
 #include <asm/irq.h>
+#include <asm/system.h>
 #include <asm/spinlock.h>
 #include <asm/arch/dma.h>
 
+/*
+ * DMA modes - we have two, IN and OUT
+ */
+typedef unsigned int dmamode_t;
+
+#define DMA_MODE_MASK  1
+
+#define DMA_MODE_READ  0
+#define DMA_MODE_WRITE 1
+#define DMA_AUTOINIT   2
+
 typedef struct {
        unsigned long address;
        unsigned long length;
@@ -117,4 +131,10 @@ extern int  get_dma_residue(dmach_t channel);
 #define NO_DMA 255
 #endif
 
+#ifdef CONFIG_PCI_QUIRKS
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy    (0)
+#endif
+
 #endif /* _ARM_DMA_H */
index b83032fcad6c97881fdde080b1d2aaec21ed162b..cd4528235518e62fe37802c3e8884fc6a6a1dfb7 100644 (file)
 
 #include <asm/arch/hardware.h>
 
-/*
- * Use these macros to read/write the IOC.  All it does is perform the actual
- * read/write.
- */
-#ifdef HAS_IOC
-#ifndef __ASSEMBLER__
-#define __IOC(offset)  (IOC_BASE + (offset >> 2))
-#else
-#define __IOC(offset)  offset
-#endif
-
-#define IOC_CONTROL    __IOC(0x00)
-#define IOC_KARTTX     __IOC(0x04)
-#define IOC_KARTRX     __IOC(0x04)
-
-#define IOC_IRQSTATA   __IOC(0x10)
-#define IOC_IRQREQA    __IOC(0x14)
-#define IOC_IRQCLRA    __IOC(0x14)
-#define IOC_IRQMASKA   __IOC(0x18)
-
-#define IOC_IRQSTATB   __IOC(0x20)
-#define IOC_IRQREQB    __IOC(0x24)
-#define IOC_IRQMASKB   __IOC(0x28)
-
-#define IOC_FIQSTAT    __IOC(0x30)
-#define IOC_FIQREQ     __IOC(0x34)
-#define IOC_FIQMASK    __IOC(0x38)
-
-#define IOC_T0CNTL     __IOC(0x40)
-#define IOC_T0LTCHL    __IOC(0x40)
-#define IOC_T0CNTH     __IOC(0x44)
-#define IOC_T0LTCHH    __IOC(0x44)
-#define IOC_T0GO       __IOC(0x48)
-#define IOC_T0LATCH    __IOC(0x4c)
-
-#define IOC_T1CNTL     __IOC(0x50)
-#define IOC_T1LTCHL    __IOC(0x50)
-#define IOC_T1CNTH     __IOC(0x54)
-#define IOC_T1LTCHH    __IOC(0x54)
-#define IOC_T1GO       __IOC(0x58)
-#define IOC_T1LATCH    __IOC(0x5c)
-
-#define IOC_T2CNTL     __IOC(0x60)
-#define IOC_T2LTCHL    __IOC(0x60)
-#define IOC_T2CNTH     __IOC(0x64)
-#define IOC_T2LTCHH    __IOC(0x64)
-#define IOC_T2GO       __IOC(0x68)
-#define IOC_T2LATCH    __IOC(0x6c)
-
-#define IOC_T3CNTL     __IOC(0x70)
-#define IOC_T3LTCHL    __IOC(0x70)
-#define IOC_T3CNTH     __IOC(0x74)
-#define IOC_T3LTCHH    __IOC(0x74)
-#define IOC_T3GO       __IOC(0x78)
-#define IOC_T3LATCH    __IOC(0x7c)
-#endif
-
-#ifdef HAS_MEMC
-#define VDMA_ALIGNMENT PAGE_SIZE
-#define VDMA_XFERSIZE  16
-#define VDMA_INIT      0
-#define VDMA_START     1
-#define VDMA_END       2
-
-#define video_set_dma(start,end,offset)                                \
-do {                                                           \
-       memc_write (VDMA_START, (start >> 2));                  \
-       memc_write (VDMA_END, (end - VDMA_XFERSIZE) >> 2);      \
-       memc_write (VDMA_INIT, (offset >> 2));                  \
-} while (0)
-#endif
-
-#ifdef HAS_IOMD
-#ifndef __ASSEMBLER__
-#define __IOMD(offset) (IO_IOMD_BASE + (offset >> 2))
-#else
-#define __IOMD(offset) offset
-#endif
-
-#define IOMD_CONTROL   __IOMD(0x000)
-#define IOMD_KARTTX    __IOMD(0x004)
-#define IOMD_KARTRX    __IOMD(0x004)
-#define IOMD_KCTRL     __IOMD(0x008)
-
-#define IOMD_IRQSTATA  __IOMD(0x010)
-#define IOMD_IRQREQA   __IOMD(0x014)
-#define IOMD_IRQCLRA   __IOMD(0x014)
-#define IOMD_IRQMASKA  __IOMD(0x018)
-
-#define IOMD_IRQSTATB  __IOMD(0x020)
-#define IOMD_IRQREQB   __IOMD(0x024)
-#define IOMD_IRQMASKB  __IOMD(0x028)
-
-#define IOMD_FIQSTAT   __IOMD(0x030)
-#define IOMD_FIQREQ    __IOMD(0x034)
-#define IOMD_FIQMASK   __IOMD(0x038)
-
-#define IOMD_T0CNTL    __IOMD(0x040)
-#define IOMD_T0LTCHL   __IOMD(0x040)
-#define IOMD_T0CNTH    __IOMD(0x044)
-#define IOMD_T0LTCHH   __IOMD(0x044)
-#define IOMD_T0GO      __IOMD(0x048)
-#define IOMD_T0LATCH   __IOMD(0x04c)
-
-#define IOMD_T1CNTL    __IOMD(0x050)
-#define IOMD_T1LTCHL   __IOMD(0x050)
-#define IOMD_T1CNTH    __IOMD(0x054)
-#define IOMD_T1LTCHH   __IOMD(0x054)
-#define IOMD_T1GO      __IOMD(0x058)
-#define IOMD_T1LATCH   __IOMD(0x05c)
-
-#define IOMD_ROMCR0    __IOMD(0x080)
-#define IOMD_ROMCR1    __IOMD(0x084)
-#define IOMD_DRAMCR    __IOMD(0x088)
-#define IOMD_VREFCR    __IOMD(0x08C)
-
-#define IOMD_FSIZE     __IOMD(0x090)
-#define IOMD_ID0       __IOMD(0x094)
-#define IOMD_ID1       __IOMD(0x098)
-#define IOMD_VERSION   __IOMD(0x09C)
-
-#define IOMD_MOUSEX    __IOMD(0x0A0)
-#define IOMD_MOUSEY    __IOMD(0x0A4)
-
-#define IOMD_DMATCR    __IOMD(0x0C0)
-#define IOMD_IOTCR     __IOMD(0x0C4)
-#define IOMD_ECTCR     __IOMD(0x0C8)
-#define IOMD_DMAEXT    __IOMD(0x0CC)
-
-#define DMA_EXT_IO0    1
-#define DMA_EXT_IO1    2
-#define DMA_EXT_IO2    4
-#define DMA_EXT_IO3    8
-
-#define IOMD_IO0CURA   __IOMD(0x100)
-#define IOMD_IO0ENDA   __IOMD(0x104)
-#define IOMD_IO0CURB   __IOMD(0x108)
-#define IOMD_IO0ENDB   __IOMD(0x10C)
-#define IOMD_IO0CR     __IOMD(0x110)
-#define IOMD_IO0ST     __IOMD(0x114)
-
-#define IOMD_IO1CURA   __IOMD(0x120)
-#define IOMD_IO1ENDA   __IOMD(0x124)
-#define IOMD_IO1CURB   __IOMD(0x128)
-#define IOMD_IO1ENDB   __IOMD(0x12C)
-#define IOMD_IO1CR     __IOMD(0x130)
-#define IOMD_IO1ST     __IOMD(0x134)
-
-#define IOMD_IO2CURA   __IOMD(0x140)
-#define IOMD_IO2ENDA   __IOMD(0x144)
-#define IOMD_IO2CURB   __IOMD(0x148)
-#define IOMD_IO2ENDB   __IOMD(0x14C)
-#define IOMD_IO2CR     __IOMD(0x150)
-#define IOMD_IO2ST     __IOMD(0x154)
-
-#define IOMD_IO3CURA   __IOMD(0x160)
-#define IOMD_IO3ENDA   __IOMD(0x164)
-#define IOMD_IO3CURB   __IOMD(0x168)
-#define IOMD_IO3ENDB   __IOMD(0x16C)
-#define IOMD_IO3CR     __IOMD(0x170)
-#define IOMD_IO3ST     __IOMD(0x174)
-
-#define IOMD_SD0CURA   __IOMD(0x180)
-#define IOMD_SD0ENDA   __IOMD(0x184)
-#define IOMD_SD0CURB   __IOMD(0x188)
-#define IOMD_SD0ENDB   __IOMD(0x18C)
-#define IOMD_SD0CR     __IOMD(0x190)
-#define IOMD_SD0ST     __IOMD(0x194)
-
-#define IOMD_SD1CURA   __IOMD(0x1A0)
-#define IOMD_SD1ENDA   __IOMD(0x1A4)
-#define IOMD_SD1CURB   __IOMD(0x1A8)
-#define IOMD_SD1ENDB   __IOMD(0x1AC)
-#define IOMD_SD1CR     __IOMD(0x1B0)
-#define IOMD_SD1ST     __IOMD(0x1B4)
-
-#define IOMD_CURSCUR   __IOMD(0x1C0)
-#define IOMD_CURSINIT  __IOMD(0x1C4)
-
-#define IOMD_VIDCUR    __IOMD(0x1D0)
-#define IOMD_VIDEND    __IOMD(0x1D4)
-#define IOMD_VIDSTART  __IOMD(0x1D8)
-#define IOMD_VIDINIT   __IOMD(0x1DC)
-#define IOMD_VIDCR     __IOMD(0x1E0)
-
-#define IOMD_DMASTAT   __IOMD(0x1F0)
-#define IOMD_DMAREQ    __IOMD(0x1F4)
-#define IOMD_DMAMASK   __IOMD(0x1F8)
-
-#define DMA_END_S      (1 << 31)
-#define DMA_END_L      (1 << 30)
-
-#define DMA_CR_C       0x80
-#define DMA_CR_D       0x40
-#define DMA_CR_E       0x20
-
-#define DMA_ST_OFL     4
-#define DMA_ST_INT     2
-#define DMA_ST_AB      1
-/*
- * IOC compatability
- */
-#define IOC_CONTROL    IOMD_CONTROL
-#define IOC_IRQSTATA   IOMD_IRQSTATA
-#define IOC_IRQREQA    IOMD_IRQREQA
-#define IOC_IRQCLRA    IOMD_IRQCLRA
-#define IOC_IRQMASKA   IOMD_IRQMASKA
-
-#define IOC_IRQSTATB   IOMD_IRQSTATB
-#define IOC_IRQREQB    IOMD_IRQREQB
-#define IOC_IRQMASKB   IOMD_IRQMASKB
-
-#define IOC_FIQSTAT    IOMD_FIQSTAT
-#define IOC_FIQREQ     IOMD_FIQREQ
-#define IOC_FIQMASK    IOMD_FIQMASK
-
-#define IOC_T0CNTL     IOMD_T0CNTL
-#define IOC_T0LTCHL    IOMD_T0LTCHL
-#define IOC_T0CNTH     IOMD_T0CNTH
-#define IOC_T0LTCHH    IOMD_T0LTCHH
-#define IOC_T0GO       IOMD_T0GO
-#define IOC_T0LATCH    IOMD_T0LATCH
-
-#define IOC_T1CNTL     IOMD_T1CNTL
-#define IOC_T1LTCHL    IOMD_T1LTCHL
-#define IOC_T1CNTH     IOMD_T1CNTH
-#define IOC_T1LTCHH    IOMD_T1LTCHH
-#define IOC_T1GO       IOMD_T1GO
-#define IOC_T1LATCH    IOMD_T1LATCH
-
-/*
- * DMA (MEMC) compatability
- */
-#define HALF_SAM       vram_half_sam
-#define VDMA_ALIGNMENT (HALF_SAM * 2)
-#define VDMA_XFERSIZE  (HALF_SAM)
-#define VDMA_INIT      IOMD_VIDINIT
-#define VDMA_START     IOMD_VIDSTART
-#define VDMA_END       IOMD_VIDEND
-
-#ifndef __ASSEMBLER__
-extern unsigned int vram_half_sam;
-#define video_set_dma(start,end,offset)                                \
-do {                                                           \
-       outl (SCREEN_START + start, VDMA_START);                \
-       outl (SCREEN_START + end - VDMA_XFERSIZE, VDMA_END);    \
-       if (offset >= end - VDMA_XFERSIZE)                      \
-               offset |= 0x40000000;                           \
-       outl (SCREEN_START + offset, VDMA_INIT);                \
-} while (0)
-#endif
+#ifndef FLUSH_BASE
+#define FLUSH_BASE     0xdf000000
 #endif
 
 #ifdef HAS_EXPMASK
index 6105bbe886d84ced393690545764d09027412b22..c0aa97f7fe0143087c1c5049cf1e7812300e2a36 100644 (file)
@@ -5,7 +5,7 @@
 
 /* C routines */
 
-#ifdef CONFIG_BINUTILS_NEW
+#ifdef CONFIG_TEXT_INIT_SECTION
 
 #define __init __attribute__ ((__section__ (".text.init")))
 #define __initfunc(__arginit) \
@@ -26,4 +26,7 @@
 #define __INITDATA     .section        ".data.init",@alloc,@write
 #define __FINIT        .previous
 
+#define __cacheline_aligned __attribute__ \
+                        ((__aligned__ (L1_CACHE_BYTES)))
+
 #endif
index 10b20184a997118acb82c59b4e9bcfda4085dd99..e87744b7163147f891924d3a5bb190a80c7f69f5 100644 (file)
@@ -31,7 +31,7 @@
  *              to an address that the kernel can use.
  */
 #define virt_to_bus(x) (__virt_to_bus((unsigned long)(x)))
-#define bus_to_virt(x) ((void *)(__bus_to_virt(x)))
+#define bus_to_virt(x) ((void *)(__bus_to_virt((unsigned long)(x))))
 
 /*
  * These macros actually build the multi-value IO function prototypes
@@ -173,6 +173,8 @@ __IO(l,"",long)
 
 #ifdef __KERNEL__
 
+extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+
 /*
  * String version of IO memory access ops:
  */
diff --git a/include/asm-arm/ioc.h b/include/asm-arm/ioc.h
new file mode 100644 (file)
index 0000000..2b3d606
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Use these macros to read/write the IOC.  All it does is perform the actual
+ * read/write.
+ */
+
+#ifndef __ASSEMBLER__
+#define __IOC(offset)  (IOC_BASE + (offset >> 2))
+#else
+#define __IOC(offset)  offset
+#endif
+
+#define IOC_CONTROL    __IOC(0x00)
+#define IOC_KARTTX     __IOC(0x04)
+#define IOC_KARTRX     __IOC(0x04)
+
+#define IOC_IRQSTATA   __IOC(0x10)
+#define IOC_IRQREQA    __IOC(0x14)
+#define IOC_IRQCLRA    __IOC(0x14)
+#define IOC_IRQMASKA   __IOC(0x18)
+
+#define IOC_IRQSTATB   __IOC(0x20)
+#define IOC_IRQREQB    __IOC(0x24)
+#define IOC_IRQMASKB   __IOC(0x28)
+
+#define IOC_FIQSTAT    __IOC(0x30)
+#define IOC_FIQREQ     __IOC(0x34)
+#define IOC_FIQMASK    __IOC(0x38)
+
+#define IOC_T0CNTL     __IOC(0x40)
+#define IOC_T0LTCHL    __IOC(0x40)
+#define IOC_T0CNTH     __IOC(0x44)
+#define IOC_T0LTCHH    __IOC(0x44)
+#define IOC_T0GO       __IOC(0x48)
+#define IOC_T0LATCH    __IOC(0x4c)
+
+#define IOC_T1CNTL     __IOC(0x50)
+#define IOC_T1LTCHL    __IOC(0x50)
+#define IOC_T1CNTH     __IOC(0x54)
+#define IOC_T1LTCHH    __IOC(0x54)
+#define IOC_T1GO       __IOC(0x58)
+#define IOC_T1LATCH    __IOC(0x5c)
+
+#define IOC_T2CNTL     __IOC(0x60)
+#define IOC_T2LTCHL    __IOC(0x60)
+#define IOC_T2CNTH     __IOC(0x64)
+#define IOC_T2LTCHH    __IOC(0x64)
+#define IOC_T2GO       __IOC(0x68)
+#define IOC_T2LATCH    __IOC(0x6c)
+
+#define IOC_T3CNTL     __IOC(0x70)
+#define IOC_T3LTCHL    __IOC(0x70)
+#define IOC_T3CNTH     __IOC(0x74)
+#define IOC_T3LTCHH    __IOC(0x74)
+#define IOC_T3GO       __IOC(0x78)
+#define IOC_T3LATCH    __IOC(0x7c)
+
diff --git a/include/asm-arm/iomd.h b/include/asm-arm/iomd.h
new file mode 100644 (file)
index 0000000..375c6fd
--- /dev/null
@@ -0,0 +1,180 @@
+
+#ifndef __ASSEMBLER__
+#define __IOMD(offset) (IO_IOMD_BASE + (offset >> 2))
+#else
+#define __IOMD(offset) offset
+#endif
+
+#define IOMD_CONTROL   __IOMD(0x000)
+#define IOMD_KARTTX    __IOMD(0x004)
+#define IOMD_KARTRX    __IOMD(0x004)
+#define IOMD_KCTRL     __IOMD(0x008)
+
+#define IOMD_IRQSTATA  __IOMD(0x010)
+#define IOMD_IRQREQA   __IOMD(0x014)
+#define IOMD_IRQCLRA   __IOMD(0x014)
+#define IOMD_IRQMASKA  __IOMD(0x018)
+
+#define IOMD_IRQSTATB  __IOMD(0x020)
+#define IOMD_IRQREQB   __IOMD(0x024)
+#define IOMD_IRQMASKB  __IOMD(0x028)
+
+#define IOMD_FIQSTAT   __IOMD(0x030)
+#define IOMD_FIQREQ    __IOMD(0x034)
+#define IOMD_FIQMASK   __IOMD(0x038)
+
+#define IOMD_T0CNTL    __IOMD(0x040)
+#define IOMD_T0LTCHL   __IOMD(0x040)
+#define IOMD_T0CNTH    __IOMD(0x044)
+#define IOMD_T0LTCHH   __IOMD(0x044)
+#define IOMD_T0GO      __IOMD(0x048)
+#define IOMD_T0LATCH   __IOMD(0x04c)
+
+#define IOMD_T1CNTL    __IOMD(0x050)
+#define IOMD_T1LTCHL   __IOMD(0x050)
+#define IOMD_T1CNTH    __IOMD(0x054)
+#define IOMD_T1LTCHH   __IOMD(0x054)
+#define IOMD_T1GO      __IOMD(0x058)
+#define IOMD_T1LATCH   __IOMD(0x05c)
+
+#define IOMD_ROMCR0    __IOMD(0x080)
+#define IOMD_ROMCR1    __IOMD(0x084)
+#define IOMD_DRAMCR    __IOMD(0x088)
+#define IOMD_VREFCR    __IOMD(0x08C)
+
+#define IOMD_FSIZE     __IOMD(0x090)
+#define IOMD_ID0       __IOMD(0x094)
+#define IOMD_ID1       __IOMD(0x098)
+#define IOMD_VERSION   __IOMD(0x09C)
+
+#define IOMD_MOUSEX    __IOMD(0x0A0)
+#define IOMD_MOUSEY    __IOMD(0x0A4)
+
+#define IOMD_DMATCR    __IOMD(0x0C0)
+#define IOMD_IOTCR     __IOMD(0x0C4)
+#define IOMD_ECTCR     __IOMD(0x0C8)
+#define IOMD_DMAEXT    __IOMD(0x0CC)
+
+#define DMA_EXT_IO0    1
+#define DMA_EXT_IO1    2
+#define DMA_EXT_IO2    4
+#define DMA_EXT_IO3    8
+
+#define IOMD_IO0CURA   __IOMD(0x100)
+#define IOMD_IO0ENDA   __IOMD(0x104)
+#define IOMD_IO0CURB   __IOMD(0x108)
+#define IOMD_IO0ENDB   __IOMD(0x10C)
+#define IOMD_IO0CR     __IOMD(0x110)
+#define IOMD_IO0ST     __IOMD(0x114)
+
+#define IOMD_IO1CURA   __IOMD(0x120)
+#define IOMD_IO1ENDA   __IOMD(0x124)
+#define IOMD_IO1CURB   __IOMD(0x128)
+#define IOMD_IO1ENDB   __IOMD(0x12C)
+#define IOMD_IO1CR     __IOMD(0x130)
+#define IOMD_IO1ST     __IOMD(0x134)
+
+#define IOMD_IO2CURA   __IOMD(0x140)
+#define IOMD_IO2ENDA   __IOMD(0x144)
+#define IOMD_IO2CURB   __IOMD(0x148)
+#define IOMD_IO2ENDB   __IOMD(0x14C)
+#define IOMD_IO2CR     __IOMD(0x150)
+#define IOMD_IO2ST     __IOMD(0x154)
+
+#define IOMD_IO3CURA   __IOMD(0x160)
+#define IOMD_IO3ENDA   __IOMD(0x164)
+#define IOMD_IO3CURB   __IOMD(0x168)
+#define IOMD_IO3ENDB   __IOMD(0x16C)
+#define IOMD_IO3CR     __IOMD(0x170)
+#define IOMD_IO3ST     __IOMD(0x174)
+
+#define IOMD_SD0CURA   __IOMD(0x180)
+#define IOMD_SD0ENDA   __IOMD(0x184)
+#define IOMD_SD0CURB   __IOMD(0x188)
+#define IOMD_SD0ENDB   __IOMD(0x18C)
+#define IOMD_SD0CR     __IOMD(0x190)
+#define IOMD_SD0ST     __IOMD(0x194)
+
+#define IOMD_SD1CURA   __IOMD(0x1A0)
+#define IOMD_SD1ENDA   __IOMD(0x1A4)
+#define IOMD_SD1CURB   __IOMD(0x1A8)
+#define IOMD_SD1ENDB   __IOMD(0x1AC)
+#define IOMD_SD1CR     __IOMD(0x1B0)
+#define IOMD_SD1ST     __IOMD(0x1B4)
+
+#define IOMD_CURSCUR   __IOMD(0x1C0)
+#define IOMD_CURSINIT  __IOMD(0x1C4)
+
+#define IOMD_VIDCUR    __IOMD(0x1D0)
+#define IOMD_VIDEND    __IOMD(0x1D4)
+#define IOMD_VIDSTART  __IOMD(0x1D8)
+#define IOMD_VIDINIT   __IOMD(0x1DC)
+#define IOMD_VIDCR     __IOMD(0x1E0)
+
+#define IOMD_DMASTAT   __IOMD(0x1F0)
+#define IOMD_DMAREQ    __IOMD(0x1F4)
+#define IOMD_DMAMASK   __IOMD(0x1F8)
+
+#define DMA_END_S      (1 << 31)
+#define DMA_END_L      (1 << 30)
+
+#define DMA_CR_C       0x80
+#define DMA_CR_D       0x40
+#define DMA_CR_E       0x20
+
+#define DMA_ST_OFL     4
+#define DMA_ST_INT     2
+#define DMA_ST_AB      1
+/*
+ * IOC compatability
+ */
+#define IOC_CONTROL    IOMD_CONTROL
+#define IOC_IRQSTATA   IOMD_IRQSTATA
+#define IOC_IRQREQA    IOMD_IRQREQA
+#define IOC_IRQCLRA    IOMD_IRQCLRA
+#define IOC_IRQMASKA   IOMD_IRQMASKA
+
+#define IOC_IRQSTATB   IOMD_IRQSTATB
+#define IOC_IRQREQB    IOMD_IRQREQB
+#define IOC_IRQMASKB   IOMD_IRQMASKB
+
+#define IOC_FIQSTAT    IOMD_FIQSTAT
+#define IOC_FIQREQ     IOMD_FIQREQ
+#define IOC_FIQMASK    IOMD_FIQMASK
+
+#define IOC_T0CNTL     IOMD_T0CNTL
+#define IOC_T0LTCHL    IOMD_T0LTCHL
+#define IOC_T0CNTH     IOMD_T0CNTH
+#define IOC_T0LTCHH    IOMD_T0LTCHH
+#define IOC_T0GO       IOMD_T0GO
+#define IOC_T0LATCH    IOMD_T0LATCH
+
+#define IOC_T1CNTL     IOMD_T1CNTL
+#define IOC_T1LTCHL    IOMD_T1LTCHL
+#define IOC_T1CNTH     IOMD_T1CNTH
+#define IOC_T1LTCHH    IOMD_T1LTCHH
+#define IOC_T1GO       IOMD_T1GO
+#define IOC_T1LATCH    IOMD_T1LATCH
+
+/*
+ * DMA (MEMC) compatability
+ */
+#define HALF_SAM       vram_half_sam
+#define VDMA_ALIGNMENT (HALF_SAM * 2)
+#define VDMA_XFERSIZE  (HALF_SAM)
+#define VDMA_INIT      IOMD_VIDINIT
+#define VDMA_START     IOMD_VIDSTART
+#define VDMA_END       IOMD_VIDEND
+
+#ifndef __ASSEMBLER__
+extern unsigned int vram_half_sam;
+#define video_set_dma(start,end,offset)                                \
+do {                                                           \
+       outl (SCREEN_START + start, VDMA_START);                \
+       outl (SCREEN_START + end - VDMA_XFERSIZE, VDMA_END);    \
+       if (offset >= end - VDMA_XFERSIZE)                      \
+               offset |= 0x40000000;                           \
+       outl (SCREEN_START + offset, VDMA_INIT);                \
+} while (0)
+#endif
+
index d253e2abf1d14a1bd9b6217a1e919ba558c8dcf3..f69aa7fce222e5d9595a4d3484f4ec1ede21240c 100644 (file)
@@ -4,6 +4,8 @@
  * Copyright (C) 1998 Russell King
  *
  * Event-driven interface for LEDs on machines
+ *
+ * Added led_start and led_stop- Alex Holden, 28th Dec 1998.
  */
 #ifndef ASM_ARM_LEDS_H
 #define ASM_ARM_LEDS_H
@@ -11,7 +13,9 @@
 typedef enum {
        led_idle_start,
        led_idle_end,
-       led_timer
+       led_timer,
+       led_start,
+       led_stop
 } led_event_t;
 
 /* Use this routine to handle LEDs */
diff --git a/include/asm-arm/memc.h b/include/asm-arm/memc.h
new file mode 100644 (file)
index 0000000..820738a
--- /dev/null
@@ -0,0 +1,13 @@
+#define VDMA_ALIGNMENT PAGE_SIZE
+#define VDMA_XFERSIZE  16
+#define VDMA_INIT      0
+#define VDMA_START     1
+#define VDMA_END       2
+
+#define video_set_dma(start,end,offset)                                \
+do {                                                           \
+       memc_write (VDMA_START, (start >> 2));                  \
+       memc_write (VDMA_END, (end - VDMA_XFERSIZE) >> 2);      \
+       memc_write (VDMA_INIT, (offset >> 2));                  \
+} while (0)
+
index 84bea09825996af86acaddae410e0fdfdaab94e4..934902052a5d406785e366fbc1bd13779fb84d6f 100644 (file)
@@ -94,10 +94,6 @@ extern __inline__ void update_memc_addr(struct mm_struct *mm, unsigned long addr
 
 #define __flush_entry_to_ram(entry)
 
-/* Certain architectures need to do special things when pte's
- * within a page table are directly modified.  Thus, the following
- * hook is made available.
- */
 /* PMD_SHIFT determines the size of the area a second-level page table can map */
 #define PMD_SHIFT       20
 #define PMD_SIZE        (1UL << PMD_SHIFT)
@@ -273,6 +269,10 @@ extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot)
        return pte;
 }
 
+/* Certain architectures need to do special things when pte's
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
 #define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
 
 extern __inline__ unsigned long pte_page(pte_t pte)
index dee91008c277725d4d9e53ad2c37a163cd09b49c..471daf65430a0f2bf9d43d0b94c02080d5264f43 100644 (file)
@@ -40,74 +40,74 @@ extern __inline__ unsigned long __xchg(unsigned long x, volatile void *ptr, int
 /*
  * Save the current interrupt enable state & disable IRQs
  */
-#define __save_flags_cli(x)            \
-       do {                            \
-         unsigned long temp;           \
-         __asm__ __volatile__(         \
-"      mov     %0, pc\n"               \
-"      orr     %1, %0, #0x08000000\n"  \
-"      and     %0, %0, #0x0c000000\n"  \
-"      teqp    %1, #0\n"               \
-         : "=r" (x), "=r" (temp)       \
-         :                             \
-         : "memory");                  \
+#define __save_flags_cli(x)                            \
+       do {                                            \
+         unsigned long temp;                           \
+         __asm__ __volatile__(                         \
+"      mov     %0, pc          @ save_flags_cli\n"     \
+"      orr     %1, %0, #0x08000000\n"                  \
+"      and     %0, %0, #0x0c000000\n"                  \
+"      teqp    %1, #0\n"                               \
+         : "=r" (x), "=r" (temp)                       \
+         :                                             \
+         : "memory");                                  \
        } while (0)
        
 /*
  * Enable IRQs
  */
-#define __sti()                                \
-       do {                            \
-         unsigned long temp;           \
-         __asm__ __volatile__(         \
-"      mov     %0, pc\n"               \
-"      bic     %0, %0, #0x08000000\n"  \
-"      teqp    %0, #0\n"               \
-         : "=r" (temp)                 \
-         :                             \
-         : "memory");                  \
+#define __sti()                                        \
+       do {                                    \
+         unsigned long temp;                   \
+         __asm__ __volatile__(                 \
+"      mov     %0, pc          @ sti\n"        \
+"      bic     %0, %0, #0x08000000\n"          \
+"      teqp    %0, #0\n"                       \
+         : "=r" (temp)                         \
+         :                                     \
+         : "memory");                          \
        } while(0)
 
 /*
  * Disable IRQs
  */
-#define __cli()                                \
-       do {                            \
-         unsigned long temp;           \
-         __asm__ __volatile__(         \
-"      mov     %0, pc\n"               \
-"      orr     %0, %0, #0x08000000\n"  \
-"      teqp    %0, #0\n"               \
-         : "=r" (temp)                 \
-         :                             \
-         : "memory");                  \
+#define __cli()                                        \
+       do {                                    \
+         unsigned long temp;                   \
+         __asm__ __volatile__(                 \
+"      mov     %0, pc          @ cli\n"        \
+"      orr     %0, %0, #0x08000000\n"          \
+"      teqp    %0, #0\n"                       \
+         : "=r" (temp)                         \
+         :                                     \
+         : "memory");                          \
        } while(0)
 
 /*
  * save current IRQ & FIQ state
  */
-#define __save_flags(x)                        \
-       do {                            \
-         __asm__ __volatile__(         \
-"      mov     %0, pc\n"               \
-"      and     %0, %0, #0x0c000000\n"  \
-         : "=r" (x));                  \
+#define __save_flags(x)                                \
+       do {                                    \
+         __asm__ __volatile__(                 \
+"      mov     %0, pc          @ save_flags\n" \
+"      and     %0, %0, #0x0c000000\n"          \
+         : "=r" (x));                          \
        } while (0)
 
 /*
  * restore saved IRQ & FIQ state
  */
-#define __restore_flags(x)             \
-       do {                            \
-         unsigned long temp;           \
-         __asm__ __volatile__(         \
-"      mov     %0, pc\n"               \
-"      bic     %0, %0, #0x0c000000\n"  \
-"      orr     %0, %0, %1\n"           \
-"      teqp    %0, #0\n"               \
-         : "=r" (temp)                 \
-         : "r" (x)                     \
-         : "memory");                  \
+#define __restore_flags(x)                             \
+       do {                                            \
+         unsigned long temp;                           \
+         __asm__ __volatile__(                         \
+"      mov     %0, pc          @ restore_flags\n"      \
+"      bic     %0, %0, #0x0c000000\n"                  \
+"      orr     %0, %0, %1\n"                           \
+"      teqp    %0, #0\n"                               \
+         : "=r" (temp)                                 \
+         : "r" (x)                                     \
+         : "memory");                                  \
        } while (0)
 
 #ifdef __SMP__
index 2e861b213ed438735bbf8a340d9612b6add82d96..a3f5c327f13b4780902bc14a8966b2ebd8e2be74 100644 (file)
@@ -136,7 +136,7 @@ setup_pagetables(unsigned long start_mem, unsigned long end_mem)
        /*
         * An area to invalidate the cache
         */
-       alloc_init_section(&start_mem, 0xdf000000, SAFE_ADDR, DOMAIN_KERNEL,
+       alloc_init_section(&start_mem, FLUSH_BASE, FLUSH_BASE_PHYS, DOMAIN_KERNEL,
                           PMD_SECT_CACHEABLE | PMD_SECT_AP_READ);
 
        /*
index fd8768939295ab79146e517863f96c5ae048b25a..8acec4c754eb8cebcd83cb2de5839f9be574cb86 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef __ASM_PROC_PAGE_H
 #define __ASM_PROC_PAGE_H
 
+#include <asm/hardware.h>
+
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT     12
 #define PAGE_SIZE       (1UL << PAGE_SHIFT)
@@ -60,7 +62,10 @@ typedef unsigned long pgprot_t;
 #define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
 /* This handles the memory map.. */
+#ifndef PAGE_OFFSET
 #define PAGE_OFFSET            0xc0000000
+#endif
+
 #define MAP_NR(addr)           (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT)
 
 #endif /* __KERNEL__ */
index fb1ad746f37c5662e79e3575ecdb98412bb679c4..3da31f536bb9937d6e5b31dc3ff33f2d10756ad5 100644 (file)
  */
 extern inline void down(struct semaphore * sem)
 {
+       unsigned int cpsr, temp;
+
        __asm__ __volatile__ ("
        @ atomic down operation
-       mrs     r0, cpsr
-       orr     r1, r0, #128            @ disable IRQs
-       bic     r0, r0, #0x80000000     @ clear N
-       msr     cpsr, r1
-       ldr     r1, [%0]
-       subs    r1, r1, #1
-       str     r1, [%0]
-       orrmi   r0, r0, #0x80000000     @ set N
-       msr     cpsr, r0
-       movmi   r0, %0
-       blmi    " SYMBOL_NAME_STR(__down)
-               : : "r" (sem) : "r0", "r1", "r2", "r3", "ip", "lr", "cc");
+       mrs     %0, cpsr
+       orr     %1, %0, #128            @ disable IRQs
+       bic     %0, %0, #0x80000000     @ clear N
+       msr     cpsr, %1
+       ldr     %1, [%2]
+       subs    %1, %1, #1
+       orrmi   %0, %0, #0x80000000     @ set N
+       str     %1, [%2]
+       msr     cpsr, %0
+       movmi   r0, %2
+       blmi    " SYMBOL_NAME_STR(__down_failed)
+               : "=&r" (cpsr), "=&r" (temp)
+               : "r" (sem)
+               : "r0", "lr", "cc");
 }
 
 /*
@@ -32,26 +36,28 @@ extern inline void down(struct semaphore * sem)
  */
 extern inline int down_interruptible (struct semaphore * sem)
 {
-       int result;
+       unsigned int cpsr, temp;
+
        __asm__ __volatile__ ("
-       @ atomic down operation
-       mrs     r0, cpsr
-       orr     r1, r0, #128            @ disable IRQs
-       bic     r0, r0, #0x80000000     @ clear N
-       msr     cpsr, r1
-       ldr     r1, [%1]
-       subs    r1, r1, #1
-       str     r1, [%1]
-       orrmi   r0, r0, #0x80000000     @ set N
-       msr     cpsr, r0
-       movmi   r0, %1
+       @ atomic down interruptible operation
+       mrs     %0, cpsr
+       orr     %1, %0, #128            @ disable IRQs
+       bic     %0, %0, #0x80000000     @ clear N
+       msr     cpsr, %1
+       ldr     %1, [%2]
+       subs    %1, %1, #1
+       orrmi   %0, %0, #0x80000000     @ set N
+       str     %1, [%2]
+       msr     cpsr, %0
+       movmi   r0, %2
        movpl   r0, #0
-       blmi    " SYMBOL_NAME_STR(__down_interruptible) "
-       mov     %0, r0"
-               : "=r" (result)
+       blmi    " SYMBOL_NAME_STR(__down_interruptible_failed) "
+       mov     %1, r0"
+               : "=&r" (cpsr), "=&r" (temp)
                : "r" (sem)
-               : "r0", "r1", "r2", "r3", "ip", "lr", "cc");
-       return result;
+               : "r0", "lr", "cc");
+
+       return temp;
 }
 
 /*
@@ -62,20 +68,24 @@ extern inline int down_interruptible (struct semaphore * sem)
  */
 extern inline void up(struct semaphore * sem)
 {
+       unsigned int cpsr, temp;
+
        __asm__ __volatile__ ("
        @ atomic up operation
-       mrs     r0, cpsr
-       orr     r1, r0, #128            @ disable IRQs
-       bic     r0, r0, #0x80000000     @ clear N
-       msr     cpsr, r1
-       ldr     r1, [%0]
-       adds    r1, r1, #1
-       str     r1, [%0]
-       orrls   r0, r0, #0x80000000     @ set N
-       msr     cpsr, r0
-       movmi   r0, %0
-       blmi    " SYMBOL_NAME_STR(__up)
-               : : "r" (sem) : "r0", "r1", "r2", "r3", "ip", "lr", "cc");
+       mrs     %0, cpsr
+       orr     %1, %0, #128            @ disable IRQs
+       bic     %0, %0, #0x80000000     @ clear N
+       msr     cpsr, %1
+       ldr     %1, [%2]
+       adds    %1, %1, #1
+       orrls   %0, %0, #0x80000000     @ set N
+       str     %1, [%2]
+       msr     cpsr, %0
+       movmi   r0, %2
+       blmi    " SYMBOL_NAME_STR(__up_wakeup)
+               : "=&r" (cpsr), "=&r" (temp)
+               : "r" (sem)
+               : "r0", "lr", "cc");
 }
 
 #endif
index 0ef12de11dd4592f23c9a605dd2e7fdfbdef515e..9de0fccc5ea8a6896655be56d1c9ecbb430aa4f0 100644 (file)
@@ -22,22 +22,24 @@ extern __inline__ unsigned long __xchg(unsigned long x, volatile void *ptr, int
        return x;
 }
 
-/*
- * This processor does not need anything special before reset,
- * but RPC may do...
- */
-extern __inline__ void proc_hard_reset(void)
-{
-}
+#define set_cr(x)                                      \
+       do {                                            \
+       __asm__ __volatile__(                           \
+       "mcr    p15, 0, %0, c1, c0      @ set CR"       \
+         : : "r" (x));                                 \
+       } while (0)
+
+extern unsigned long cr_no_alignment;  /* defined in entry-armv.S */
+extern unsigned long cr_alignment;     /* defined in entry-armv.S */
 
 /*
  * We can wait for an interrupt...
  */
-#define proc_idle()                    \
-       do {                            \
-       __asm__ __volatile__(           \
-"      mcr     p15, 0, %0, c15, c8, 2" \
-         : : "r" (0));                 \
+#define proc_idle()                                            \
+       do {                                                    \
+       __asm__ __volatile__(                                   \
+"      mcr     p15, 0, %0, c15, c8, 2  @ proc_idle"            \
+         : : "r" (0));                                         \
        } while (0)
 
 /*
@@ -47,75 +49,75 @@ extern __inline__ void proc_hard_reset(void)
 /*
  * Save the current interrupt enable state & disable IRQs
  */
-#define __save_flags_cli(x)            \
-       do {                            \
-         unsigned long temp;           \
-         __asm__ __volatile__(         \
-       "mrs    %1, cpsr\n"             \
-"      and     %0, %1, #192\n"         \
-"      orr     %1, %1, #128\n"         \
-"      msr     cpsr, %1"               \
-         : "=r" (x), "=r" (temp)       \
-         :                             \
-         : "memory");                  \
+#define __save_flags_cli(x)                                    \
+       do {                                                    \
+         unsigned long temp;                                   \
+         __asm__ __volatile__(                                 \
+       "mrs    %1, cpsr                @ save_flags_cli\n"     \
+"      and     %0, %1, #192\n"                                 \
+"      orr     %1, %1, #128\n"                                 \
+"      msr     cpsr, %1"                                       \
+         : "=r" (x), "=r" (temp)                               \
+         :                                                     \
+         : "memory");                                          \
        } while (0)
        
 /*
  * Enable IRQs
  */
-#define __sti()                                \
-       do {                            \
-         unsigned long temp;           \
-         __asm__ __volatile__(         \
-       "mrs    %0, cpsr\n"             \
-"      bic     %0, %0, #128\n"         \
-"      msr     cpsr, %0"               \
-         : "=r" (temp)                 \
-         :                             \
-         : "memory");                  \
+#define __sti()                                                        \
+       do {                                                    \
+         unsigned long temp;                                   \
+         __asm__ __volatile__(                                 \
+       "mrs    %0, cpsr                @ sti\n"                \
+"      bic     %0, %0, #128\n"                                 \
+"      msr     cpsr, %0"                                       \
+         : "=r" (temp)                                         \
+         :                                                     \
+         : "memory");                                          \
        } while(0)
 
 /*
  * Disable IRQs
  */
-#define __cli()                                \
-       do {                            \
-         unsigned long temp;           \
-         __asm__ __volatile__(         \
-       "mrs    %0, cpsr\n"             \
-"      orr     %0, %0, #128\n"         \
-"      msr     cpsr, %0"               \
-         : "=r" (temp)                 \
-         :                             \
-         : "memory");                  \
+#define __cli()                                                        \
+       do {                                                    \
+         unsigned long temp;                                   \
+         __asm__ __volatile__(                                 \
+       "mrs    %0, cpsr                @ cli\n"                \
+"      orr     %0, %0, #128\n"                                 \
+"      msr     cpsr, %0"                                       \
+         : "=r" (temp)                                         \
+         :                                                     \
+         : "memory");                                          \
        } while(0)
 
 /*
  * save current IRQ & FIQ state
  */
-#define __save_flags(x)                        \
-       do {                            \
-         __asm__ __volatile__(         \
-       "mrs    %0, cpsr\n"             \
-"      and     %0, %0, #192"           \
-         : "=r" (x)                    \
-         :                             \
-         : "memory");                  \
+#define __save_flags(x)                                                \
+       do {                                                    \
+         __asm__ __volatile__(                                 \
+       "mrs    %0, cpsr                @ save_flags\n"         \
+"      and     %0, %0, #192"                                   \
+         : "=r" (x)                                            \
+         :                                                     \
+         : "memory");                                          \
        } while (0)
 
 /*
  * restore saved IRQ & FIQ state
  */
-#define __restore_flags(x)             \
-       do {                            \
-         unsigned long temp;           \
-         __asm__ __volatile__(         \
-       "mrs    %0, cpsr\n"             \
-"      bic     %0, %0, #192\n"         \
-"      orr     %0, %0, %1\n"           \
-"      msr     cpsr, %0"               \
-         : "=r" (temp)                 \
-         : "r" (x)                     \
+#define __restore_flags(x)                                     \
+       do {                                                    \
+         unsigned long temp;                                   \
+         __asm__ __volatile__(                                 \
+       "mrs    %0, cpsr                @ restore_flags\n"      \
+"      bic     %0, %0, #192\n"                                 \
+"      orr     %0, %0, %1\n"                                   \
+"      msr     cpsr, %0"                                       \
+         : "=r" (temp)                                         \
+         : "r" (x)                                             \
          : "memory");                  \
        } while (0)
 
index d5e187407a76195ea731df40b0a7518922292ff3..a8dce67397c2320798016ca389b5f470f043c507 100644 (file)
@@ -55,7 +55,7 @@ extern __inline__ void set_fs (mm_segment_t fs)
 /* We use 33-bit arithmetic here... */
 #define __range_ok(addr,size) ({ \
        unsigned long flag, sum; \
-       __asm__ __volatile__("adds %1, %2, %3; sbccs %1, %1, %0; movcc %0, #0" \
+       __asm__ __volatile__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
                : "=&r" (flag), "=&r" (sum) \
                : "r" (addr), "Ir" (size), "0" (current->addr_limit) \
                : "cc"); \
index 3186aac19e331beffb7d9b694488f353b958ed64..b8d4ae398f7e96cd10cdf7fe663fa628d491cf65 100644 (file)
@@ -18,10 +18,11 @@ struct semaphore {
 #define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), 0, NULL })
 
 asmlinkage void __down_failed (void /* special register calling convention */);
-asmlinkage int  __down_failed_interruptible (void /* special register calling convention */);
+asmlinkage int  __down_interruptible_failed (void /* special register calling convention */);
 asmlinkage void __up_wakeup (void /* special register calling convention */);
 
 extern void __down(struct semaphore * sem);
+extern int  __down_interruptible(struct semaphore * sem);
 extern void __up(struct semaphore * sem);
 
 #define sema_init(sem, val)    atomic_set(&((sem)->count), (val))
index 0045494741c72e776057d57f312890e151f5ce24..12ec642aaf1c3a8042483a7fcc408c77a1ec08a3 100644 (file)
@@ -21,7 +21,7 @@ typedef struct {
 } sigset_t;
 
 #else
-/* Here we must cater to lics that poke about in kernel headers.  */
+/* Here we must cater to libcs that poke about in kernel headers.  */
 
 #define NSIG           32
 typedef unsigned long sigset_t;
@@ -69,6 +69,8 @@ typedef unsigned long sigset_t;
 #define SIGRTMIN       32
 #define SIGRTMAX       (_NSIG-1)
 
+#define SIGSWI         32
+
 /*
  * SA_FLAGS values:
  *
@@ -96,6 +98,8 @@ typedef unsigned long sigset_t;
 #define SA_INTERRUPT   0x20000000 /* dummy -- ignored */
 
 #define SA_RESTORER    0x04000000
+#define SA_THIRTYTWO   0x02000000 /* deliver signal in 32-bit mode even if
+                                     task is running 26 bits. */
 
 /* 
  * sigaltstack controls
index ba99f96f640bc168443e5766d60830cd54e83d97..6bad79dd4a7d452de330572884f3cce395b627dd 100644 (file)
@@ -13,7 +13,7 @@ extern unsigned int local_bh_count[NR_CPUS];
 extern inline void init_bh(int nr, void (*routine)(void))
 {
        bh_base[nr] = routine;
-       bh_mask_count[nr] = 0;
+       atomic_set(&bh_mask_count[nr], 0);
        bh_mask |= 1 << nr;
 }
 
@@ -58,13 +58,13 @@ extern inline void end_bh_atomic(void)
 extern inline void disable_bh(int nr)
 {
        bh_mask &= ~(1 << nr);
-       bh_mask_count[nr]++;
+       atomic_inc(&bh_mask_count[nr]);
        synchronize_bh();
 }
 
 extern inline void enable_bh(int nr)
 {
-       if (!--bh_mask_count[nr])
+       if (atomic_dec_and_test(&bh_mask_count[nr]))
                bh_mask |= 1 << nr;
 }
 
index 5a53935c0bf30d853751f9a86651f4c5b1c97ae5..33e1fe183ffc3fdbfd93b042fc33b5dfc3a83a9e 100644 (file)
@@ -3,12 +3,20 @@
 
 #ifndef __SMP__
 
+/*
+ * To be safe, we assume the only compiler that can cope with
+ * empty initialisers is EGCS.
+ */
+#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 90))
+#define EMPTY_INIT_OK
+#endif
+
 /*
  * Your basic spinlocks, allowing only a single CPU anywhere
  */
-#if (__GNUC__ > 2) || (__GNUC_MINOR__ >= 8)
+#ifdef EMPTY_INIT_OK
   typedef struct { } spinlock_t;
-# define SPIN_LOCK_UNLOCKED { }
+# define SPIN_LOCK_UNLOCKED (spinlock_t) { }
 #else
   typedef unsigned char spinlock_t;
 # define SPIN_LOCK_UNLOCKED 0
@@ -37,9 +45,9 @@
  * irq-safe write-lock, but readers can get non-irqsafe
  * read-locks.
  */
-#if (__GNUC__ > 2) || (__GNUC_MINOR__ >= 8)
+#ifdef EMPTY_INIT_OK
   typedef struct { } rwlock_t;
-# define RW_LOCK_UNLOCKED { }
+# define RW_LOCK_UNLOCKED (rwlock_t) { }
 #else
   typedef unsigned char rwlock_t;
 # define RW_LOCK_UNLOCKED 0
index 435833937626b6483ab38f60501c07644db5edca..9922760e490fbe40e5a949f23e63728374cb8e18 100644 (file)
@@ -117,10 +117,21 @@ struct termios {
 #define HUPCL  0002000
 #define CLOCAL 0004000
 #define CBAUDEX 0010000
-#define  B57600  0010001
-#define  B115200 0010002
-#define  B230400 0010003
-#define  B460800 0010004
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
 #define CIBAUD   002003600000  /* input baud rate (not used) */
 #define CMSPAR    010000000000         /* mark or space (stick) parity */
 #define CRTSCTS          020000000000          /* flow control */
index 29ae27df265d78036cabdf7d44c66679c2a5f55a..d9a3303beaeea8f9b9ab0a82645a44d0c140abc1 100644 (file)
 
 #include <asm/arch/timex.h>
 
+typedef unsigned long cycles_t;
+
+extern cycles_t cacheflush_time;
+
+static inline cycles_t get_cycles (void)
+{
+       return 0;
+}
+
 #endif
index 780b7a13cf8f02d9b407334f9687f2634c0ec32f..601af3b0abaa4c5cc55f4b0b337f0ef0b7336fb5 100644 (file)
@@ -23,7 +23,7 @@
 #define __NR_time                      (__NR_SYSCALL_BASE+ 13)
 #define __NR_mknod                     (__NR_SYSCALL_BASE+ 14)
 #define __NR_chmod                     (__NR_SYSCALL_BASE+ 15)
-#define __NR_chown                     (__NR_SYSCALL_BASE+ 16)
+#define __NR_lchown                    (__NR_SYSCALL_BASE+ 16)
 #define __NR_break                     (__NR_SYSCALL_BASE+ 17)
 #define __NR_oldstat                   (__NR_SYSCALL_BASE+ 18)
 #define __NR_lseek                     (__NR_SYSCALL_BASE+ 19)
 #define __NR_rt_sigsuspend             (__NR_SYSCALL_BASE+179)
 #define __NR_pread                     (__NR_SYSCALL_BASE+180)
 #define __NR_pwrite                    (__NR_SYSCALL_BASE+181)
-#define __NR_xstat                     (__NR_SYSCALL_BASE+182)
-#define __NR_xmknod                    (__NR_SYSCALL_BASE+183)
+#define __NR_chown                     (__NR_SYSCALL_BASE+182)
+#define __NR_getcwd                    (__NR_SYSCALL_BASE+183)
+#define __NR_capget                    (__NR_SYSCALL_BASE+184)
+#define __NR_capset                    (__NR_SYSCALL_BASE+185)
+#define __NR_sigaltstack               (__NR_SYSCALL_BASE+186)
+#define __NR_sendfile                  (__NR_SYSCALL_BASE+187)
 
 #define __sys2(x) #x
 #define __sys1(x) __sys2(x)
@@ -299,41 +303,94 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) {                   \
 
 #ifdef __KERNEL_SYSCALLS__
 
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(int,idle);
-static inline _syscall0(int,pause);
-static inline _syscall1(int,setup,int,magic);
-static inline _syscall0(int,sync);
-static inline _syscall0(pid_t,setsid);
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count);
-static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count);
-static inline _syscall1(int,dup,int,fd);
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp);
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode);
-static inline _syscall1(int,close,int,fd);
-static inline _syscall1(int,_exit,int,exitcode);
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options);
-static inline _syscall1(int,delete_module,const char *,name)
+static inline int idle(void)
+{
+       extern int sys_idle(void);
+       return sys_idle();
+}
 
-static inline pid_t wait(int * wait_stat)
+static inline int pause(void)
+{
+       extern int sys_pause(void);
+       return sys_pause();
+}
+
+static inline int sync(void)
+{
+       extern int sys_sync(void);
+       return sys_sync();
+}
+
+static inline pid_t setsid(void)
+{
+       extern int sys_setsid(void);
+       return sys_setsid();
+}
+
+static inline int write(int fd, const char *buf, off_t count)
+{
+       extern int sys_write(int, const char *, int);
+       return sys_write(fd, buf, count);
+}
+
+static inline int read(int fd, char *buf, off_t count)
+{
+       extern int sys_read(int, char *, int);
+       return sys_read(fd, buf, count);
+}
+
+static inline off_t lseek(int fd, off_t offset, int count)
+{
+       extern off_t sys_lseek(int, off_t, int);
+       return sys_lseek(fd, offset, count);
+}
+
+static inline int dup(int fd)
+{
+       extern int sys_dup(int);
+       return sys_dup(fd);
+}
+
+static inline int open(const char *file, int flag, int mode)
+{
+       extern int sys_open(const char *, int, int);
+       return sys_open(file, flag, mode);
+}
+
+static inline int close(int fd)
 {
-       return waitpid(-1,wait_stat,0);
+       return sys_close(fd);
 }
 
+static inline int _exit(int exitcode)
+{
+       extern int sys_exit(int);
+       return sys_exit(exitcode);
+}
 
+static inline pid_t waitpid(pid_t pid, int *wait_stat, int options)
+{
+       extern int sys_wait4(int, int *, int, struct rusage *);
+       return sys_wait4((int)pid, wait_stat, options, NULL);
+}
+
+static inline int delete_module(const char *name)
+{
+       extern int sys_delete_module(const char *name);
+       return sys_delete_module(name);
+}
+
+static inline pid_t wait(int * wait_stat)
+{
+       extern int sys_wait4(int, int *, int, struct rusage *);
+       return sys_wait4(-1, wait_stat, 0, NULL);
+}
+
+/*
+ * The following two can't be eliminated yet - they rely on
+ * specific conditions.
+ */
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp);
 
 /*
  * This is the mechanism for creating a new kernel thread.
index b89188b8c0d113c7fbd59f015996076306cba4a4..5ccd7d8f071e9a79e2aa3d715bbea3d783989f14 100644 (file)
@@ -117,10 +117,21 @@ struct termios {
 #define HUPCL  0002000
 #define CLOCAL 0004000
 #define CBAUDEX 0010000
-#define  B57600  0010001
-#define  B115200 0010002
-#define  B230400 0010003
-#define  B460800 0010004
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
 #define CIBAUD   002003600000  /* input baud rate (not used) */
 #define CMSPAR   010000000000          /* mark or space (stick) parity */
 #define CRTSCTS          020000000000          /* flow control */
index 76c7241bfe378815ecc3b9d25c598d25fdee02b2..73d05673b9f7dd816a7265f400615db84ce41f73 100644 (file)
 #define __NR_sendfile          187
 #define __NR_getpmsg           188     /* some people actually want streams */
 #define __NR_putpmsg           189     /* some people actually want streams */
+#define __NR_vfork             190
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
 
index 0a3080a7699f2019c417ac3a2b19460d3322a913..c43bb869a4cf759a71ac5c9d80ee4ad9cffc1ef5 100644 (file)
@@ -118,10 +118,21 @@ struct termios {
 #define HUPCL  0002000
 #define CLOCAL 0004000
 #define CBAUDEX 0010000
-#define  B57600  0010001
-#define  B115200 0010002
-#define  B230400 0010003
-#define  B460800 0010004
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
 #define CIBAUD   002003600000  /* input baud rate (not used) */
 #define CMSPAR   010000000000          /* mark or space (stick) parity */
 #define CRTSCTS          020000000000          /* flow control */
index fbce44aeec1218f82ba21f4b42febec0a149a2d5..ccf5e85ec2bb8a3476808dc3225fe3346bf33fa6 100644 (file)
@@ -153,10 +153,21 @@ struct termios {
 #define CLOCAL 0004000         /* Ignore modem status lines.  */
 #if defined (__USE_BSD) || defined (__KERNEL__)
 #define CBAUDEX 0010000
-#define  B57600  0010001
-#define  B115200 0010002
-#define  B230400 0010003
-#define  B460800 0010004
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
 #define CIBAUD   002003600000  /* input baud rate (not used) */
 #define CMSPAR    010000000000 /* mark or space (stick) parity */
 #define CRTSCTS          020000000000          /* flow control */
index 9e0614ae2bf687e6a6b8fa284a9a5552ed2ac959..95b59cafc5df6a5f2b5cd84cba3953209222d576 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: bitops.h,v 1.10 1998/08/16 21:56:53 geert Exp $
+ * $Id: bitops.h,v 1.11 1999/01/03 20:16:48 cort Exp $
  * bitops.h: Bit string operations on the ppc
  */
 
@@ -16,6 +16,16 @@ extern int test_and_set_bit(int nr, volatile void *addr);
 extern int test_and_clear_bit(int nr, volatile void *addr);
 extern int test_and_change_bit(int nr, volatile void *addr);
 
+
+/* Returns the number of 0's to the left of the most significant 1 bit */
+extern __inline__  int cntlzw(int bits)
+{
+       int lz;
+
+       asm ("cntlzw %0,%1" : "=r" (lz) : "r" (bits));
+       return lz;
+}
+
 /*
  * These are if'd out here because using : "cc" as a constraint
  * results in errors from gcc. -- Cort
index 8560c7d882c23f6a178b1f08c20d6f2282a6c533..b817e055acf6805d27c804af9230a2816a0b2a0d 100644 (file)
@@ -204,6 +204,7 @@ extern long ppc_cs4232_dma, ppc_cs4232_dma2;
 #define DMA2_EXT_REG               0x4D6
 
 #define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
+#define DMA_AUTOINIT   0x10
 
 extern spinlock_t  dma_spin_lock;
 
@@ -393,4 +394,10 @@ static __inline__ int get_dma_residue(unsigned int dmanr)
 extern int request_dma(unsigned int dmanr, const char * device_id);    /* reserve a DMA channel */
 extern void free_dma(unsigned int dmanr);      /* release it again */
 
+#ifdef CONFIG_PCI_QUIRKS
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy    (0)
+#endif
+
 #endif /* _ASM_DMA_H */
index 6df9a99d452924c1485f7bb91fc06df08e49e520..cad526b12e42b88c37f3505c9bf8d82b0e83bff9 100644 (file)
@@ -80,8 +80,11 @@ extern void chrp_ide_probe(void);
 
 static __inline__ int ide_default_irq(ide_ioreg_t base)
 {
-       if ( (_machine == _MACH_Pmac) || (_machine == _MACH_mbx) )
+       if ( _machine == _MACH_Pmac )
                return 0;
+       else if ( _machine == _MACH_mbx )
+               /* hardcode IRQ 14 on the MBX */
+               return 14+16;                
         else if ( _machine == _MACH_chrp) {
                 if (chrp_ide_ports_known == 0) 
                        chrp_ide_probe();
@@ -142,7 +145,7 @@ static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent
 }
 
 /* Convert the shorts/longs in hd_driveid from little to big endian;
-   chars are endian independant, of course, but strings need to be flipped.
+   chars are endian independent, of course, but strings need to be flipped.
    (Despite what it says in drivers/block/ide.h, they come up as little endian...)
    Changes to linux/hdreg.h may require changes here. */
 static __inline__ void ide_fix_driveid (struct hd_driveid *id) {
@@ -252,14 +255,14 @@ static __inline__ void ide_fix_driveid (struct hd_driveid *id) {
        }
 }
 
-
 #undef insw
 #define insw(port, buf, ns)    do {                    \
        if ( _machine == _MACH_chrp)  {\
                 ide_insw((port)+_IO_BASE, (buf), (ns));  \
        }\
        else if ( (_machine == _MACH_Pmac) || (_machine == _MACH_mbx) )                 \
-               ide_insw((port), (buf), (ns));          \
+               ide_insw((port)+((_machine==_MACH_mbx)? 0x80000000: 0), \
+                        (buf), (ns));          \
        else                                            \
                /* this must be the same as insw in io.h!! */   \
                _insw((unsigned short *)((port)+_IO_BASE), (buf), (ns)); \
@@ -270,8 +273,9 @@ static __inline__ void ide_fix_driveid (struct hd_driveid *id) {
        if ( _machine == _MACH_chrp) {\
                ide_outsw((port)+_IO_BASE, (buf), (ns)); \
        }\
-       else if ( (_machine == _MACH_Pmac) || (_machine == _MACH_mbx) )                 \
-               ide_outsw((port), (buf), (ns));         \
+       else if ( (_machine == _MACH_Pmac) || (_machine == _MACH_mbx) )  \
+               ide_outsw((port)+((_machine==_MACH_mbx)? 0x80000000: 0), \
+                          (buf), (ns));                \
        else                                            \
                /* this must be the same as outsw in io.h!! */  \
                _outsw((unsigned short *)((port)+_IO_BASE), (buf), (ns)); \
@@ -279,13 +283,17 @@ static __inline__ void ide_fix_driveid (struct hd_driveid *id) {
 
 #undef inb
 #define inb(port)      \
-       in_8((unsigned char *)((port) + ((_machine==_MACH_Pmac)? 0: _IO_BASE)))
+       in_8((unsigned char *)((port) + \
+                              ((_machine==_MACH_Pmac)? 0: _IO_BASE) + \
+                              ((_machine==_MACH_mbx)? 0x80000000: 0)) )
 #undef inb_p
 #define inb_p(port)    inb(port)
 
 #undef outb
 #define outb(val, port)        \
-       out_8((unsigned char *)((port) + ((_machine==_MACH_Pmac)? 0: _IO_BASE)), (val))
+       out_8((unsigned char *)((port) + \
+                               ((_machine==_MACH_Pmac)? 0: _IO_BASE) + \
+                               ((_machine==_MACH_mbx)? 0x80000000: 0)), (val) )
 #undef outb_p
 #define outb_p(val, port)      outb(val, port)
 
index ebad8d5f02cbb7d3cbf955d85a950c54a17ca6c7..9e8e36d60c93ae37fd6cd34f0e186a9a308f44e3 100644 (file)
@@ -226,7 +226,7 @@ extern unsigned long empty_zero_page[1024];
  do { \
        unsigned long __pgdir = (unsigned long)pgdir; \
        ((tsk)->tss.pg_tables = (unsigned long *)(__pgdir)); \
-       asm("mtspr %0,%1 \n\t" :: "i"(M_TWB), "r"(__pa(__pgdir))); \
+       asm("mtspr %0,%1 \n\t" : : "i"(M_TWB), "r"(__pa(__pgdir))); \
  } while (0)
 #endif /* CONFIG_8xx */
      
@@ -637,5 +637,7 @@ extern void kernel_set_cachemode (unsigned long address, unsigned long size,
 
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define PageSkip(page)         (0)
+#define kern_addr_valid(addr)  (1)
+
 #endif __ASSEMBLY__
 #endif /* _PPC_PGTABLE_H */
index df1014281ad1b03d8e4188b08d9d21f0fbbd98bc..0d387ca10676e94dc88f4853e90fdff4f377657a 100644 (file)
@@ -126,6 +126,17 @@ struct termios {
 #define  B115200  00021
 #define  B230400  00022
 #define  B460800  00023
+#define  B500000  00024
+#define  B576000  00025
+#define  B921600  00026
+#define B1000000  00027
+#define B1152000  00030
+#define B1500000  00031
+#define B2000000  00032
+#define B2500000  00033
+#define B3000000  00034
+#define B3500000  00035
+#define B4000000  00036
 
 #define CSIZE  00001400
 #define   CS5  00000000
index 95f519ad4dadc8e7d3409c9412db0b7b6df1ce78..af4a46aa586f9a0cdd9ecb7c78f86fdf85ac409b 100644 (file)
@@ -315,14 +315,15 @@ extern void put_cached_page(unsigned long);
 #define __GFP_LOW      0x02
 #define __GFP_MED      0x04
 #define __GFP_HIGH     0x08
+#define __GFP_IO       0x10
 
 #define __GFP_DMA      0x80
 
 #define GFP_BUFFER     (__GFP_LOW | __GFP_WAIT)
 #define GFP_ATOMIC     (__GFP_HIGH)
-#define GFP_USER       (__GFP_LOW | __GFP_WAIT)
-#define GFP_KERNEL     (__GFP_MED | __GFP_WAIT)
-#define GFP_NFS                (__GFP_HIGH | __GFP_WAIT)
+#define GFP_USER       (__GFP_LOW | __GFP_WAIT | __GFP_IO)
+#define GFP_KERNEL     (__GFP_MED | __GFP_WAIT | __GFP_IO)
+#define GFP_NFS                (__GFP_HIGH | __GFP_WAIT | __GFP_IO)
 
 /* Flag - indicates that the buffer will be suitable for DMA.  Ignored on some
    platforms, used as appropriate on others */
index 3321e29587fda06c7098cca2c8b1b18e7864f468..efcd5892051109ea1e39d022630fd0b38f62e5f8 100644 (file)
@@ -36,6 +36,7 @@ extern int init_nls_iso8859_6(void);
 extern int init_nls_iso8859_7(void);
 extern int init_nls_iso8859_8(void);
 extern int init_nls_iso8859_9(void);
+extern int init_nls_iso8859_15(void);
 extern int init_nls_cp437(void);
 extern int init_nls_cp737(void);
 extern int init_nls_cp775(void);
index 69b6634e31782aaabf2cc7b58e94a7f8f753eaf3..ebf339d0fe372ad2340a7ebd27048e0a9fa16904 100644 (file)
@@ -257,7 +257,8 @@ struct task_struct {
        /* Pointer to task[] array linkage. */
        struct task_struct **tarray_ptr;
 
-       struct wait_queue *wait_chldexit;       /* for wait4() */
+       struct wait_queue *wait_chldexit, *vfork_sleep; /* for wait4()/vfork */
+
        unsigned long policy, rt_priority;
        unsigned long it_real_value, it_prof_value, it_virt_value;
        unsigned long it_real_incr, it_prof_incr, it_virt_incr;
@@ -298,6 +299,7 @@ struct task_struct {
        struct files_struct *files;
 /* memory management info */
        struct mm_struct *mm;
+
 /* signal handlers */
        spinlock_t sigmask_lock;        /* Protects signal and blocked */
        struct signal_struct *sig;
@@ -348,7 +350,7 @@ struct task_struct {
 /* proc links*/ &init_task,&init_task,NULL,NULL,NULL, \
 /* pidhash */  NULL, NULL, \
 /* tarray */   &task[0], \
-/* chld wait */        NULL, \
+/* chld wait */        NULL, NULL, \
 /* timeout */  SCHED_OTHER,0,0,0,0,0,0,0, \
 /* timer */    { NULL, NULL, 0, 0, it_real_fn }, \
 /* utime */    {0,0,0,0},0, \
index ef921caef4f308a22d2388acf904041e6f9affd5..24da571cb52d9e43235213ffeaee145ba59ee49e 100644 (file)
@@ -9,6 +9,7 @@
 #ifndef _LINUX_SUNRPC_STATS_H
 #define _LINUX_SUNRPC_STATS_H
 
+#include <linux/config.h>
 #include <linux/proc_fs.h>
 
 struct rpc_stat {
index df16576d7d7eae650b34bc7aa068b8afb51539db..032293ea354861648f8c87180c94b1259018bee0 100644 (file)
@@ -158,7 +158,7 @@ struct rpc_xprt {
         */
        union {                                 /* record marker & XID */
                u32             header[2];
-               u8 *            data[8];
+               u8              data[8];
        }                       tcp_recm;
        struct rpc_rqst *       tcp_rqstp;
        struct iovec            tcp_iovec[MAX_IOVEC];
index dd3a4e436d7feffb2f9b2774b0f72a5b34fbdb0c..af54f7c5bf1ac01c2850e637d6d72f611b566482 100644 (file)
@@ -299,6 +299,7 @@ struct tty_struct {
        int canon_data;
        unsigned long canon_head;
        unsigned int canon_column;
+       struct semaphore atomic_read;
 };
 
 /* tty magic number */
@@ -320,6 +321,7 @@ struct tty_struct {
 #define TTY_DO_WRITE_WAKEUP 5
 #define TTY_PUSH 6
 #define TTY_CLOSING 7
+#define TTY_DONT_FLIP 8
 #define TTY_HW_COOK_OUT 14
 #define TTY_HW_COOK_IN 15
 #define TTY_PTY_LOCK 16
index 0f5975b6e5cba54806ae2b9e52239d71bb51ac0e..65d26195f0d4c7003b801764be23054b342f296f 100644 (file)
 #define UFS_MOUNT_ONERROR_UMOUNT       0x00000004
 #define UFS_MOUNT_ONERROR_REPAIR       0x00000008
 
-#define UFS_MOUNT_UFSTYPE              0x000000F0
+#define UFS_MOUNT_UFSTYPE              0x000001F0
 #define UFS_MOUNT_UFSTYPE_OLD          0x00000010
 #define UFS_MOUNT_UFSTYPE_44BSD                0x00000020
 #define UFS_MOUNT_UFSTYPE_SUN          0x00000040
 #define UFS_MOUNT_UFSTYPE_NEXT         0x00000080
-
+#define UFS_MOUNT_UFSTYPE_OPENSTEP     0x00000100
 
 #define ufs_clear_opt(o,opt)   o &= ~UFS_MOUNT_##opt
 #define ufs_set_opt(o,opt)     o |= UFS_MOUNT_##opt
index d9f6d109b72f9536b31d71975647aa8cdfe2a2e0..c0b69e54aa51b2aad01f1dd61e122256eb18a78c 100644 (file)
@@ -299,5 +299,5 @@ int br_tree_get_info(char *buffer, char **start, off_t offset, int length, int d
 /* externs */
 
 extern struct br_stat br_stats;
-
+extern Port_data port_info[];
 
index 03c65fddce5be09ef583bf0afcd9783a604d75f5..70b627305807f81b2ec7ac2e1de39a2fdd1a6096 100644 (file)
@@ -48,7 +48,8 @@
 #define IP_MASQ_F_NO_SADDR           0x0004    /* no sport set yet */
 #define IP_MASQ_F_NO_SPORT           0x0008    /* no sport set yet */
 
-#define IP_MASQ_F_NO_REPLY           0x0010    /* no reply yet from outside */
+#define IP_MASQ_F_DLOOSE             0x0010    /* loose dest binding */
+#define IP_MASQ_F_NO_REPLY           0x0080    /* no reply yet from outside */
 
 #define IP_MASQ_F_HASHED             0x0100    /* hashed entry */
 #define IP_MASQ_F_OUT_SEQ             0x0200   /* must do output seq adjust */
index 89440092e95ece4b98c50ece11b95618b2263e8c..30ef182bb37f9ce1d08db5ee035be824f863679f 100644 (file)
@@ -292,6 +292,7 @@ static void exit_notify(void)
                kill_pg(current->pgrp,SIGHUP,1);
                kill_pg(current->pgrp,SIGCONT,1);
        }
+
        /* Let father know we died */
        notify_parent(current, current->exit_signal);
 
index a972ec264843ed74b34e2d5fe7335593fab28d21..8aaa1ae2df7f8d105c314b8684b7f03930e2edc9 100644 (file)
@@ -283,6 +283,9 @@ struct mm_struct * mm_alloc(void)
  */
 void mmput(struct mm_struct *mm)
 {
+       /* notify parent sleeping on vfork() */
+       wake_up(&current->p_opptr->vfork_sleep);
+
        if (atomic_dec_and_test(&mm->count)) {
                release_segments(mm);
                exit_mmap(mm);
@@ -521,6 +524,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
        p->p_pptr = p->p_opptr = current;
        p->p_cptr = NULL;
        init_waitqueue(&p->wait_chldexit);
+       init_waitqueue(&p->vfork_sleep);
 
        p->sigpending = 0;
        sigemptyset(&p->signal);
index 822def38cec0b098b6a1efcd2f6d4dabbade941c..8d81064b917e28bab1b77de099c26e51e5052f9e 100644 (file)
@@ -258,9 +258,6 @@ unsigned long __get_free_pages(int gfp_mask, unsigned long order)
                 * a bad memory situation, we're better off trying
                 * to free things up until things are better.
                 *
-                * Normally we shouldn't ever have to do this, with
-                * kswapd doing this in the background.
-                *
                 * Most notably, this puts most of the onus of
                 * freeing up memory on the processes that _use_
                 * the most memory, rather than on everybody.
@@ -282,7 +279,7 @@ unsigned long __get_free_pages(int gfp_mask, unsigned long order)
                {
                        int freed;
                        current->flags |= PF_MEMALLOC;
-                       freed = try_to_free_pages(gfp_mask, SWAP_CLUSTER_MAX);
+                       freed = try_to_free_pages(gfp_mask, freepages.high - nr_free_pages);
                        current->flags &= ~PF_MEMALLOC;
                        if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
                                goto nopage;
index 7aa7f32ea3ff96e6e307853549424fb2a50e6ba3..3c4dc1d07bc8df9f60975ba2ef03138a09eba85a 100644 (file)
@@ -76,7 +76,6 @@ static int try_to_swap_out(struct task_struct * tsk, struct vm_area_struct* vma,
                set_pte(page_table, __pte(entry));
 drop_pte:
                vma->vm_mm->rss--;
-               tsk->nswap++;
                flush_tlb_page(vma, address);
                __free_page(page_map);
                return 0;
@@ -100,6 +99,14 @@ drop_pte:
                goto drop_pte;
        }
 
+       /*
+        * Don't go down into the swap-out stuff if
+        * we cannot do I/O! Avoid recursing on FS
+        * locks etc.
+        */
+       if (!(gfp_mask & __GFP_IO))
+               return 0;
+
        /*
         * Ok, it's really dirty. That means that
         * we should either create a new swap cache
index c4b35889bfb4fd8983b3375bdeaf87e613b6ed1b..204b00ca08e606e3e2c6bef34191f38037b8161f 100644 (file)
@@ -1197,8 +1197,8 @@ static struct sk_buff *alloc_bridge_skb(int port_no, int pdu_size, char *pdu_nam
                return NULL;
        }
        skb->dev = dev;
-       skb->mac.raw = skb->h.raw = skb_put(skb,size);
-       memset(skb->h.raw + 60 - pad_size, 0xa5, pad_size);
+       skb->mac.raw = skb->nh.raw = skb_put(skb,size);
+       memset(skb->nh.raw + 60 - pad_size, 0xa5, pad_size);
        eth = skb->mac.ethernet;
        memcpy(eth->h_dest, bridge_ula, ETH_ALEN);
        memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
@@ -1221,13 +1221,13 @@ static struct sk_buff *alloc_bridge_skb(int port_no, int pdu_size, char *pdu_nam
 #endif
        eth->h_proto = htons(pdu_size + BRIDGE_LLC1_HS);
   
-       skb->h.raw += skb->dev->hard_header_len;
-       llc_buffer = skb->h.raw;
+       skb->nh.raw += skb->dev->hard_header_len;
+       llc_buffer = skb->nh.raw;
        *llc_buffer++ = BRIDGE_LLC1_DSAP;
        *llc_buffer++ = BRIDGE_LLC1_SSAP;
        *llc_buffer++ = BRIDGE_LLC1_CTRL;
-       /* set h.raw to where the bpdu starts */
-       skb->h.raw += BRIDGE_LLC1_HS;
+       /* set nh.raw to where the bpdu starts */
+       skb->nh.raw += BRIDGE_LLC1_HS;
   
        /* mark that we've been here... */
        skb->pkt_bridged = IS_BRIDGED;
@@ -1248,18 +1248,18 @@ static int send_config_bpdu(int port_no, Config_bpdu *config_bpdu)
                return(-1);
 
        /* copy fields before "flags" */
-       memcpy(skb->h.raw, config_bpdu, BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET);
+       memcpy(skb->nh.raw, config_bpdu, BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET);
 
        /* build the "flags" field */
-       *(skb->h.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) = 0;
+       *(skb->nh.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) = 0;
        if (config_bpdu->top_change_ack)
-               *(skb->h.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) |= 0x80;
+               *(skb->nh.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) |= 0x80;
        if (config_bpdu->top_change)
-               *(skb->h.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) |= 0x01;
+               *(skb->nh.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET) |= 0x01;
 
        config_bpdu_hton(config_bpdu);
        /* copy the rest */
-       memcpy(skb->h.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET+1,
+       memcpy(skb->nh.raw+BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET+1,
                 (char*)&(config_bpdu->root_id),
                 BRIDGE_BPDU_8021_CONFIG_SIZE-1-BRIDGE_BPDU_8021_CONFIG_FLAG_OFFSET);
 
@@ -1275,7 +1275,7 @@ static int send_tcn_bpdu(int port_no, Tcn_bpdu *bpdu)
        if (skb == NULL)
                return(-1);
   
-       memcpy(skb->h.raw, bpdu, sizeof(Tcn_bpdu));
+       memcpy(skb->nh.raw, bpdu, sizeof(Tcn_bpdu));
   
        dev_queue_xmit(skb);
        return(0);
@@ -1376,7 +1376,7 @@ int br_receive_frame(struct sk_buff *skb) /* 3.5 */
        if(!port)
                return 0;
        
-       skb->h.raw = skb->mac.raw;
+       skb->nh.raw = skb->mac.raw;
        eth = skb->mac.ethernet;
        p = &port_info[port];
  
@@ -1480,7 +1480,7 @@ int br_tx_frame(struct sk_buff *skb)      /* 3.5 */
                return(0);
        }
        ++br_stats_cnt.port_not_disable;
-       skb->mac.raw = skb->h.raw = skb->data;
+       skb->mac.raw = skb->nh.raw = skb->data;
        eth = skb->mac.ethernet;
        port = 0;       /* an impossible port (locally generated) */    
        if (br_stats.flags & BR_DEBUG)
@@ -1735,7 +1735,7 @@ static int br_forward(struct sk_buff *skb, int port)      /* 3.7 */
                        skb->pkt_bridged = IS_BRIDGED;
                        
                        /* reset the skb->ip pointer */ 
-                       skb->h.raw = skb->data + ETH_HLEN;
+                       skb->nh.raw = skb->data + ETH_HLEN;
 
                        /*
                         *      Send the buffer out.
@@ -1804,7 +1804,7 @@ static int br_flood(struct sk_buff *skb, int port)
                           or have a received valid MAC header */
                        
 /*                     printk("Flood to port %d\n",i);*/
-                       nskb->h.raw = nskb->data + ETH_HLEN;
+                       nskb->nh.raw = nskb->data + ETH_HLEN;
 #if LINUX_VERSION_CODE >= 0x20100
                        nskb->priority = 1;
                        dev_queue_xmit(nskb);
index 31387f13c464f865d28eb6d6ed9370875c058d6c..0936a0f8b6b0f3b5a488dd5a0f5ba728a461a508 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/string.h>
 #include <linux/malloc.h>
 #include <linux/skbuff.h>
+#include <linux/netdevice.h>
 
 #include <net/br.h>
 #define _DEBUG_AVL
@@ -28,6 +29,10 @@ static struct fdb *fhp = &fdb_head;
 static struct fdb **fhpp = &fhp;
 static int fdb_inited = 0;
 
+#ifdef DEBUG_AVL
+static void printk_avl (struct fdb * tree);
+#endif
+
 static int addr_cmp(unsigned char *a1, unsigned char *a2);
 
 /*
@@ -80,7 +85,7 @@ struct fdb *br_avl_find_addr(unsigned char addr[6])
                addr[4],
                addr[5]);
 #endif /* DEBUG_AVL */
-       for (tree = &fdb_head ; ; ) {
+       for (tree = fhp ; ; ) {
                if (tree == avl_br_empty) {
 #if (DEBUG_AVL)
                        printk("search failed, returning node 0x%x\n", (unsigned int)result);
@@ -446,10 +451,10 @@ void sprintf_avl (char **pbuffer, struct fdb * tree, off_t *pos,
                /* don't write the local device */
                if(tree->port != 0){
                        size = sprintf(*pbuffer,
-                                  "%02x:%02x:%02x:%02x:%02x:%02x     eth%d       %d         %d\n",
+                                  "%02x:%02x:%02x:%02x:%02x:%02x     %s       %d         %ld\n",
                                   tree->ula[0],tree->ula[1],tree->ula[2],
                                   tree->ula[3],tree->ula[4],tree->ula[5], 
-                                  tree->port-1, tree->flags,CURRENT_TIME-tree->timer);
+                                  port_info[tree->port].dev->name, tree->flags,CURRENT_TIME-tree->timer);
 
                        (*pos)+=size;
                        (*len)+=size;
index d40b846c29b6640066851004172110112e86aa45..95178439b0e4e0602b5ef2074a1f3e375eaeb462 100644 (file)
@@ -1841,7 +1841,11 @@ extern void sdla_setup(void);
 extern void dlci_setup(void);
 extern int dmascc_init(void);
 extern int sm_init(void);
-extern int baycom_init(void);
+
+extern int baycom_ser_fdx_init(void);
+extern int baycom_ser_hdx_init(void);
+extern int baycom_par_init(void);
+
 extern int lapbeth_init(void);
 extern void arcnet_init(void);
 extern void ip_auto_config(void);
@@ -1912,8 +1916,14 @@ __initfunc(int net_dev_init(void))
 #if defined(CONFIG_SDLA)
        sdla_setup();
 #endif
-#if defined(CONFIG_BAYCOM)
-       baycom_init();
+#if defined(CONFIG_BAYCOM_PAR)
+       baycom_par_init();
+#endif
+#if defined(CONFIG_BAYCOM_SER_FDX)
+       baycom_ser_fdx_init();
+#endif
+#if defined(CONFIG_BAYCOM_SER_HDX)
+       baycom_ser_hdx_init();
 #endif
 #if defined(CONFIG_SOUNDMODEM)
        sm_init();
index 2baf45d21d40d68e550e3ba840c7b78e91badc32..0f264ac2fba154738ee068857ccccaab0bdd7945 100644 (file)
@@ -29,6 +29,9 @@
  * 1-May-1998:  Remove caching of device pointer.
  * 12-May-1998: Allow tiny fragment case for TCP/UDP.
  * 15-May-1998: Treat short packets as fragments, don't just block.
+ * 3-Jan-1999:  Fixed serious procfs security hole -- users should never
+ *              be allowed to view the chains!
+ *              Marc Santoro <ultima@snicker.emoti.com>
  */
 
 /*
@@ -509,7 +512,7 @@ static void cleanup(struct ip_chain *chain,
                printk("%s\n",chain->label);
 }
 
-static inline void
+static inline int
 ip_fw_domatch(struct ip_fwkernel *f,
              struct iphdr *ip, 
              const char *rif,
@@ -550,9 +553,15 @@ ip_fw_domatch(struct ip_fwkernel *f,
                               len-(sizeof(__u32)*2+IFNAMSIZ));
                        netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_KERNEL);
                }
-               else duprintf("netlink post failed - alloc_skb failed!\n");
+               else {
+                       if (net_ratelimit())
+                               printk(KERN_WARNING "ip_fw: packet drop due to "
+                                      "netlink failure\n");
+                       return 0;
+               }
        }
 #endif
+       return 1;
 }
 
 /*
@@ -695,9 +704,13 @@ ip_fw_check(struct iphdr *ip,
                for (; f; f = f->next) {
                        if (ip_rule_match(f,rif,ip,
                                          tcpsyn,src_port,dst_port,offset)) {
-                               if (!testing)
-                                       ip_fw_domatch(f, ip, rif, chain->label, skb,
-                                                     slot, src_port,dst_port);
+                               if (!testing
+                                   && !ip_fw_domatch(f, ip, rif, chain->label,
+                                                     skb, slot, 
+                                                     src_port, dst_port)) {
+                                       ret = FW_BLOCK;
+                                       goto out;
+                               }
                                break;
                        }
                }
@@ -759,6 +772,7 @@ ip_fw_check(struct iphdr *ip,
                }
        } while (ret == FW_SKIP+2);
 
+ out:
        if (!testing) FWC_READ_UNLOCK(&ip_fw_lock);
 
        /* Recalculate checksum if not going to reject, and TOS changed. */
@@ -1671,13 +1685,13 @@ struct firewall_ops ipfw_ops=
 #ifdef CONFIG_PROC_FS          
 static struct proc_dir_entry proc_net_ipfwchains_chain = {
        PROC_NET_IPFW_CHAINS, sizeof(IP_FW_PROC_CHAINS)-1, 
-       IP_FW_PROC_CHAINS, S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
+       IP_FW_PROC_CHAINS, S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0,
        0, &proc_net_inode_operations, ip_chain_procinfo
 };
 
 static struct proc_dir_entry proc_net_ipfwchains_chainnames = {
        PROC_NET_IPFW_CHAIN_NAMES, sizeof(IP_FW_PROC_CHAIN_NAMES)-1, 
-       IP_FW_PROC_CHAIN_NAMES, S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
+       IP_FW_PROC_CHAIN_NAMES, S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0,
        0, &proc_net_inode_operations, ip_chain_name_procinfo
 };
 
index bdd96afe721703ebe9c11500b06b4edccf9b4b80..77022dfd92edbce7a8b8389c78b942010cfdb7fe 100644 (file)
@@ -812,7 +812,7 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags)
                                         * FIXME: the *_user functions should
                                         *        return how much data was
                                         *        copied before the fault
-                                        *        occured and then a partial
+                                        *        occurred and then a partial
                                         *        packet with this data should
                                         *        be sent.  Unfortunately
                                         *        csum_and_copy_from_user doesn't
index 7813f30729fff4c0e2f4d97839f1af921ed848fe..a7732d76dafb3e2fd08f925e8fcbbc84f412d523 100644 (file)
@@ -891,12 +891,19 @@ int nr_rx_frame(struct sk_buff *skb, struct device *dev)
         * Now it should be a CONNREQ.
         */
        if (frametype != NR_CONNREQ) {
+               /*
+                * Here it would be nice to be able to send a reset but
+                * NET/ROM doesn't have one. The following hack would
+                * have been a way to extend the protocol but apparently
+                * it kills BPQ boxes... :-(
+                */
+#if 0
                /*
                 * Never reply to a CONNACK/CHOKE.
                 */
                if (frametype != NR_CONNACK || flags != NR_CHOKE_FLAG)
                        nr_transmit_refusal(skb, 1);
-
+#endif
                return 0;
        }
 
index 8c46a1b031fb81054214e5517280121d5b7702e2..4c6de6feea0de3807f08c2d8529e3507e714dd13 100644 (file)
@@ -67,7 +67,9 @@ extern int tcp_tw_death_row_slot;
        defined(CONFIG_E2100)   ||      defined(CONFIG_HPLAN_PLUS)      || \
        defined(CONFIG_HPLAN)   ||      defined(CONFIG_AC3200)          || \
        defined(CONFIG_ES3210)  ||      defined(CONFIG_ULTRA32)         || \
-       defined(CONFIG_LNE390)  ||      defined(CONFIG_NE3210)
+       defined(CONFIG_LNE390)  ||      defined(CONFIG_NE3210)          || \
+       defined(CONFIG_NE2K_PCI) ||     defined(CONFIG_APNE)            || \
+       defined(CONFIG_DAYNAPORT)
 #include "../drivers/net/8390.h"
 #endif
 
@@ -392,7 +394,9 @@ EXPORT_SYMBOL(arp_find);
        defined(CONFIG_E2100)   ||      defined(CONFIG_HPLAN_PLUS)      || \
        defined(CONFIG_HPLAN)   ||      defined(CONFIG_AC3200)          || \
        defined(CONFIG_ES3210)  ||      defined(CONFIG_ULTRA32)         || \
-       defined(CONFIG_LNE390)  ||      defined(CONFIG_NE3210)
+       defined(CONFIG_LNE390)  ||      defined(CONFIG_NE3210)          || \
+       defined(CONFIG_NE2K_PCI) ||     defined(CONFIG_APNE)            || \
+       defined(CONFIG_DAYNAPORT)
 /* If 8390 NIC support is built in, we will need these. */
 EXPORT_SYMBOL(ei_open);
 EXPORT_SYMBOL(ei_close);
index 0e314653ea172fe26863a6754764a183adb2dcc0..f166380816b8f227cd122885ad74ff6a7c1ccb19 100644 (file)
@@ -94,7 +94,7 @@ static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n,
    ---enqueue
 
    enqueue returns number of enqueued packets i.e. this number is 1,
-   if packet was enqueued sucessfully and <1 if something (not
+   if packet was enqueued successfully and <1 if something (not
    necessary THIS packet) was dropped.
 
    Auxiliary routines:
index 207a1dd51e8f14c11b33c6fcccff1ecac32152c9..9bdc656c9b903ea6472794b5ac8b31fb292904e2 100644 (file)
@@ -704,7 +704,7 @@ csz_dequeue(struct Qdisc* sch)
        }
 #ifdef CSZ_PLUS_TBF
        /* We are about to return no skb.
-          Schedule watchdog timer, if it occured because of shaping.
+          Schedule watchdog timer, if it occurred because of shaping.
         */
        if (q->wd_expires) {
                unsigned long delay = PSCHED_US2JIFFIE(q->wd_expires);
index cd51ed9aad634c693dd8a779b3bb576b40909d86..6a8330f859cc788a52c8cd5e32d2d7fbfc6612cd 100644 (file)
@@ -829,6 +829,10 @@ rpciod(void *ptr)
                }
                save_flags(oldflags); cli();
                if (!schedq.task) {
+                       /* following two lines added by airlied@linux.ie
+                               to make NFS over TCP work 5/1/99 */
+                       dprintk("RPC: rpciod running checking dispatch\n");
+                       rpciod_tcp_dispatcher();
                        dprintk("RPC: rpciod back to sleep\n");
                        interruptible_sleep_on(&rpciod_idle);
                        dprintk("RPC: switch to rpciod\n");
index 5d70975ce8652eb900c55a2e1c80a659674118b8..03bedba709ccb7702ce3958b19c4021f6a4bbc6a 100644 (file)
@@ -7,6 +7,7 @@
  * impossible at the moment.
  */
 
+#include <linux/config.h>
 #include <linux/version.h>
 #include <linux/types.h>
 #include <linux/linkage.h>
index 6b1dc373da4d0f32ed7321643ccf2f973ae32b45..246cfa94bf2eec73e844d6daf3d466435dc09435 100644 (file)
@@ -821,12 +821,19 @@ static void tcp_data_ready(struct sock *sk, int len)
         */
        if (!xprt->rx_pending_flag)
        {
-               dprintk("RPC:     xprt queue\n");
+               int start_queue=0;
+
+               dprintk("RPC:     xprt queue %p\n", rpc_xprt_pending);
                if(rpc_xprt_pending==NULL)
-                       tcp_rpciod_queue();
+                       start_queue=1;
                xprt->rx_pending_flag=1;
                xprt->rx_pending=rpc_xprt_pending;
                rpc_xprt_pending=xprt;
+               if (start_queue)
+                 {
+                   tcp_rpciod_queue();
+                   start_queue=0;
+                 }
        }
        else
                dprintk("RPC:     xprt queued already %p\n", xprt);
index b2292bed7c4cd048bf5abaa959945a3a74a4d3cd..50ffc5aa7f69fa0ffc74a36d81ac05273e116308 100644 (file)
@@ -1,2 +1 @@
-1.0.3-modified
-
+2.0.3
index 0e0f3c7253e51aeec4798a888f1e51bd0b1f4b6e..9a0534390b12fd7adb6028bc4e4e549e92df2ead 100644 (file)
@@ -207,7 +207,7 @@ proc read_config { filename } {
                        eval $cmd
                }
                if [regexp {([0-9A-Za-z_]+)="([^"]*)"} $line foo var value] {
-                       set cmd "global $var; set $var $value"
+                       set cmd "global $var; set $var \"$value\""
                        eval $cmd
                }
        }
index c5daad9d1c0bd7211841fe46a38c4d64ca325bce..9d889ca5165606d194d074ce3700fa60539daa9a 100644 (file)
@@ -208,9 +208,9 @@ void use_config(const char * name, int len)
 #define GETNEXT { \
        next_byte(__buf); \
        if ((unsigned long) next % sizeof(unsigned long) == 0) { \
-               __buf = * (unsigned long *) next; \
-               if (!__buf) \
+               if (next >= end) \
                        break; \
+               __buf = * (unsigned long *) next; \
        } \
        next++; \
 }
@@ -249,7 +249,7 @@ void use_config(const char * name, int len)
  * per memory read.  The MAX6 and MIN6 tests dispose of most
  * input characters with 1 or 2 comparisons.
  */
-void state_machine(const char * map)
+void state_machine(const char * map, const char * end)
 {
        const char * next = map;
        const char * map_dot;
@@ -441,7 +441,7 @@ void do_depend(const char * filename, const char * command)
                return;
        }
 
-       mapsize = st.st_size + 2*sizeof(unsigned long);
+       mapsize = st.st_size;
        mapsize = (mapsize+pagesizem1) & ~pagesizem1;
        map = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
        if ((long) map == -1) {
@@ -457,7 +457,7 @@ void do_depend(const char * filename, const char * command)
 
        hasdep = 0;
        clear_config();
-       state_machine(map);
+       state_machine(map, map+st.st_size);
        if (hasdep)
                puts(command);
 
index 3aa67da05e3540faf09ef991261b7955beabea33..d870315157436959f9f02a8d59a33f91fdb0f757 100644 (file)
@@ -905,6 +905,7 @@ void dump_tk_script(struct kconfig *scfg)
    * Generate the code to close out the last menu.
    */
   end_proc(menu_num);
+  clear_globalflags(config);
 
   /*
    * The top level menu also needs an update function.  When we exit a
diff --git a/scripts/ver_linux b/scripts/ver_linux
new file mode 100644 (file)
index 0000000..b589517
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/sh
+# Before running this script please ensure that your PATH is
+# typical as you use for compilation/istallation. I use
+# /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may
+# differs on your system.
+#
+echo '-- Versions installed: (if some fields are empty or looks'
+echo '-- unusual then possibly you have very old versions)'
+uname -a
+insmod -V 1>/tmp/ver_linux.tmp 2>>/tmp/ver_linux.tmp
+awk 'NR==1{print "Kernel modules        ",$NF}' /tmp/ver_linux.tmp
+rm -f /tmp/ver_linux.tmp
+echo "Gnu C                 " `gcc --version`
+ld -v 2>&1 | awk -F\) '{print $1}' | awk \
+      '/BFD/{print "Binutils              ",$NF}'
+ls -l `ldd /bin/sh | awk '/libc/{print $3}'` | sed -e 's/\.so$//' \
+  | awk -F'[.-]'   '{print "Linux C Library        " $(NF-2)"."$(NF-1)"."$NF}'
+echo -n "Dynamic linker         "
+ldd -v > /dev/null 2>&1 && ldd -v || ldd --version |head -1
+ls -l /usr/lib/lib{g,stdc}++.so  2>/dev/null | awk -F. \
+       '{print "Linux C++ Library      " $4"."$5"."$6}'
+ps --version 2>&1 | awk 'NR==1{print "Procps                ", $NF}'
+mount --version | awk -F\- '{print "Mount                 ", $NF}'
+netstat --version | awk \
+'NR==1{if ($5 != "") { n=split($5,buf,"-"); ver=buf[n]; done=1 }}
+ NR==2{if (done != 1) ver=$3 }
+ END{print "Net-tools             ",ver}'
+loadkeys -h 2>&1 | awk 'NR==1{print "Kbd                   ",$3}'
+expr --v | awk '{print "Sh-utils              ", $NF}'