]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.38pre1 2.3.38pre1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:29:54 +0000 (15:29 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:29:54 +0000 (15:29 -0500)
173 files changed:
CREDITS
Documentation/Configure.help
Documentation/kmod.txt
Documentation/networking/cops.txt
Documentation/networking/ethertap.txt
Documentation/networking/filter.txt
Documentation/networking/ipddp.txt
Documentation/networking/sktr.txt [deleted file]
Documentation/networking/smctr.txt [new file with mode: 0644]
Documentation/networking/tms380tr.txt [new file with mode: 0644]
Documentation/sound/via82cxxx.txt [new file with mode: 0644]
Documentation/video4linux/API.html
Documentation/video4linux/README.buz
Documentation/video4linux/bttv/Insmod-options
Documentation/video4linux/bttv/PROBLEMS
Documentation/video4linux/bttv/README
Documentation/video4linux/bttv/Sound-FAQ
Documentation/video4linux/radiotrack.txt
Documentation/video4linux/zr36120.txt
MAINTAINERS
Makefile
README
arch/i386/config.in
arch/i386/kernel/mtrr.c
arch/i386/kernel/setup.c
arch/sparc/kernel/sys_sunos.c
arch/sparc/lib/rwsem.S
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci_common.c
arch/sparc64/kernel/pci_sabre.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/sys_sunos32.c
arch/sparc64/kernel/systbls.S
arch/sparc64/solaris/fs.c
drivers/block/Config.in
drivers/net/Space.c
drivers/net/cops.c
drivers/net/cops.h
drivers/net/cops_ffdrv.h
drivers/net/cops_ltdrv.h
drivers/net/de4x5.c
drivers/net/ipddp.c
drivers/net/irda/Config.in
drivers/net/irda/Makefile
drivers/net/irda/actisys.c
drivers/net/irda/esi.c
drivers/net/irda/girbil.c
drivers/net/irda/irport.c
drivers/net/irda/irtty.c
drivers/net/irda/litelink.c
drivers/net/irda/nsc_fir.c [new file with mode: 0644]
drivers/net/irda/old_belkin.c
drivers/net/irda/pc87108.c [deleted file]
drivers/net/irda/smc-ircc.c
drivers/net/irda/tekram.c
drivers/net/irda/toshoboe.c
drivers/net/irda/w83977af_ir.c
drivers/net/tokenring/Config.in
drivers/net/tokenring/Makefile
drivers/net/tokenring/smctr.c [new file with mode: 0644]
drivers/net/tokenring/smctr.h [new file with mode: 0644]
drivers/net/tokenring/smctr_firmware.h [new file with mode: 0644]
drivers/net/tokenring/tms380tr.c
drivers/pci/setup.c
drivers/pcmcia/cardbus.c
drivers/pcmcia/cs.c
drivers/pnp/Makefile
drivers/pnp/isapnp.c
drivers/pnp/isapnp_proc.c
drivers/pnp/quirks.c [new file with mode: 0644]
drivers/sound/Makefile
drivers/sound/ac97.c
drivers/sound/nm256_audio.c
drivers/sound/sb_audio.c
drivers/sound/sb_card.c
drivers/sound/trident.c
drivers/sound/trident.h
drivers/sound/via82cxxx.c
drivers/usb/Config.in
drivers/usb/acm.c
drivers/usb/dabusb.c
drivers/usb/dabusb.h
drivers/usb/dc2xx.c
drivers/usb/hub.c
drivers/usb/mousedev.c
drivers/usb/scanner.c
drivers/usb/uhci-debug.c
drivers/usb/uhci.c
drivers/usb/uhci.h
drivers/usb/usb-debug.c
drivers/usb/usb-serial.c
drivers/usb/usb.c
drivers/usb/usb.h
drivers/usb/usbkbd.c
drivers/video/atyfb.c
drivers/video/fbmem.c
drivers/video/matroxfb.c
fs/buffer.c
fs/dcache.c
fs/ext2/file.c
fs/inode.c
fs/open.c
fs/udf/file.c
include/asm-alpha/fcntl.h
include/asm-i386/checksum.h
include/asm-sparc/checksum.h
include/asm-sparc/unistd.h
include/asm-sparc64/checksum.h
include/asm-sparc64/fcntl.h
include/asm-sparc64/unistd.h
include/linux/blk.h
include/linux/dcache.h
include/linux/errqueue.h
include/linux/if.h
include/linux/ip.h
include/linux/irda.h
include/linux/isapnp.h
include/linux/mm.h
include/linux/mmzone.h
include/linux/netdevice.h
include/linux/rtnetlink.h
include/linux/sched.h
include/linux/socket.h
include/linux/swap.h
include/linux/tcp.h
include/net/checksum.h
include/net/irda/irda.h
include/net/irda/iriap.h
include/net/irda/irlap_frame.h
include/net/irda/irlmp_frame.h
include/net/irda/irport.h
include/net/irda/nsc_fir.h [new file with mode: 0644]
include/net/irda/pc87108.h [deleted file]
include/net/irda/smc-ircc.h
include/net/route.h
init/main.c
ipc/shm.c
ipc/util.c
kernel/kmod.c
kernel/ksyms.c
kernel/sched.c
mm/filemap.c
mm/highmem.c
mm/page_alloc.c
mm/slab.c
mm/vmscan.c
net/README
net/core/filter.c
net/decnet/dn_route.c
net/ipv4/route.c
net/ipv4/udp.c
net/ipv6/udp.c
net/ipx/af_spx.c
net/irda/af_irda.c
net/irda/ircomm/ircomm_core.c
net/irda/ircomm/ircomm_tty.c
net/irda/ircomm/ircomm_tty_attach.c
net/irda/ircomm/ircomm_tty_ioctl.c
net/irda/irda_device.c
net/irda/iriap.c
net/irda/iriap_event.c
net/irda/irlan/irlan_client_event.c
net/irda/irlan/irlan_common.c
net/irda/irlan/irlan_eth.c
net/irda/irlap.c
net/irda/irlap_event.c
net/irda/irlap_frame.c
net/irda/irlmp.c
net/irda/irlmp_event.c
net/irda/irmod.c
net/irda/irttp.c

diff --git a/CREDITS b/CREDITS
index c84cd45b1689dc6201072af5d6d7eafebb5fbe21..3fdb1c2577c49ab106e7cf51bef7cf4a4c91176c 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -287,9 +287,9 @@ N: Erik Inge Bols
 E: knan@mo.himolde.no
 D: Misc kernel hacks
 
-N: Zoltan Boszormenyi
-E: zboszor@mol.hu
-D: MTRR emulation with Cyrix style ARR registers
+N: Zoltán Böszörményi
+E: zboszor@mail.externet.hu
+D: MTRR emulation with Cyrix style ARR registers, Athlon MTRR support
 
 N: John Boyd
 E: boyd@cis.ohio-state.edu
index 848974d1e5c51c75845b8c80557dab41105a924d..df5ce1d9d24841eab15dfde02dbb7e8044d191d9 100644 (file)
@@ -7487,9 +7487,18 @@ CONFIG_TMS380TR
   read the Token-Ring mini-HOWTO, available from
   http://metalab.unc.edu/mdw/linux.html#howto .
 
-  Also read the file linux/Documentation/networking/sktr.txt or check
+  Also read the file linux/Documentation/networking/tms380tr.txt or check
   http://www.auk.cx/tms380tr/
 
+SMC ISA TokenRing adapter support
+CONFIG_SMCTR
+  This is support for the ISA SMC Token Ring cards, specifically
+  SMC TokenCard Elite (8115T) and SMC TokenCard Elite/A (8115T/A) adapters.
+
+  If you have such an adapter and would like to use it, say Y or M and
+  read the Token-Ring mini-HOWTO, available from
+  http://metalab.unc.edu/mdw/linux.html#howto .
+
 Traffic Shaper (EXPERIMENTAL)
 CONFIG_SHAPER
   The traffic shaper is a virtual network device that allows you to
index 759a300b18cb2dfb9980ca9252c47015bd6d90b7..be1a9a5183ee44fe4e4579761e9eb9c3ca82f400 100644 (file)
@@ -45,3 +45,24 @@ If kerneld worked, why replace it?
 
 - kmod reports errors through the normal kernel mechanisms, which avoids
   the chicken and egg problem of kerneld and modular Unix domain sockets
+
+
+Keith Owens <kaos@ocs.com.au> December 1999
+
+The combination of kmod and modprobe can loop, especially if modprobe uses a
+system call that requires a module.  If modules.dep does not exist and modprobe
+was started with the -s option (kmod does this), modprobe tries to syslog() a
+message.  syslog() needs Unix sockets, if Unix sockets are modular then kmod
+runs "modprobe -s net-pf-1".  This runs a second copy of modprobe which
+complains that modules.dep does not exist, tries to use syslog() and starts yet
+another copy of modprobe.  This is not the only possible kmod/modprobe loop,
+just the most common.
+
+To detect loops caused by "modprobe needs a service which is in a module", kmod
+limits the number of concurrent kmod issued modprobes.  See MAX_KMOD_CONCURRENT
+in kernel/kmod.c.  When this limit is exceeded, the kernel issues message "kmod:
+runaway modprobe loop assumed and stopped".
+
+Note for users building a heavily modularised system.  It is a good idea to
+create modules.dep after installing the modules and before booting a kernel for
+the first time.  "depmod -ae m.n.p" where m.n.p is the new kernel version.
index 3251a247c7c885ff680dff1d820548c724f7fa77..b7e06c55fc5f36be210b5706fa4370757e90305b 100644 (file)
@@ -1,5 +1,5 @@
 Text File for the COPS LocalTalk Linux driver (cops.c).
-       By Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
+       By Jay Schulist <jschlst@turbolinux.com>
 
 This driver has two modes and they are: Dayna mode and Tangent mode.
 Each mode corresponds with the type of card. It has been found
index 27202efbaf1f64c10a9fe2ece1f1e418ce517efc..7af37a00484bc92c063d5b541858a9b86a566d82 100644 (file)
@@ -1,6 +1,6 @@
 Documentation on setup and use of EtherTap.
 
-Contact Jay Schulist <Jay.Schulist@spacs.k12.wi.us> if you
+Contact Jay Schulist <jschlst@turbolinux.com> if you
 have questions or need futher assistance.
 
 Introduction
index 86fc021af374d3c3cf0ac10778cf38ef53efaf78..76ee084589341fae7a3a57cc4d6cca7d5711421c 100644 (file)
@@ -1,5 +1,5 @@
 filter.txt: Linux Socket Filtering
-Written by: Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
+Written by: Jay Schulist <jschlst@turbolinux.com>
 
 Introduction
 ============
index c2cabb682df809407e6fdf603c95798a29bfa46c..8df88a7df809ffd62d8e663896c0569614334960 100644 (file)
@@ -1,7 +1,7 @@
 Text file for ipddp.c:
        AppleTalk-IP Decapsulation and AppleTalk-IP Encapsulation
 
-This text file writen by Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
+This text file writen by Jay Schulist <jschlst@turbolinux.com>
 
 Introduction
 ------------
@@ -38,7 +38,7 @@ Basic instructions for user space tools
 
 To enable AppleTalk-IP decapsulation/encapsulation you will need the 
 proper tools. You can get the tools for decapsulation from
-http://spacs1.spacs.k12.wi.us/~jschlst/MacGate and for encapsulation
+http://spacs1.spacs.k12.wi.us/~jschlst/index.html and for encapsulation
 from http://www.maths.unm.edu/~bradford/ltpc.html
 
 I will briefly describe the operation of the tools, but you will
@@ -72,7 +72,7 @@ EtherTalk only network.
 
 Further Assistance
 -------------------
-You can contact me (Jay Schulist <Jay.Schulist@spacs.k12.wi.us>) with any
+You can contact me (Jay Schulist <jschlst@turbolinux.com>) with any
 questions regarding decapsulation or encapsulation. Bradford W. Johnson
 <johns393@maroon.tc.umn.edu> originally wrote the ipddp.c driver for IP
 encapsulation in AppleTalk.
diff --git a/Documentation/networking/sktr.txt b/Documentation/networking/sktr.txt
deleted file mode 100644 (file)
index a35332a..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-Text file for the Linux SysKonnect Token Ring ISA/PCI Adapter Driver.
-       Text file by: Jay Schulist <jschlst@samba.anu.edu.au>
-
-The Linux SysKonnect Token Ring driver works with the SysKonnect TR4/16(+) ISA,
-SysKonnect TR4/16(+) PCI, SysKonnect TR4/16 PCI, and older revisions of the
-SK NET TR4/16 ISA card.
-
-Latest information on this driver can be obtained on the Linux-SNA WWW site.
-Please point your browser to: 
-http://samba.anu.edu.au/linux-sna/documents/drivers/SysKonnect/
-
-Many thanks to Christoph Goos for his excellent work on this driver and
-SysKonnect for donating the adapters to Linux-SNA for the testing and maintaince
-of this device driver.
-
-Important information to be noted:
-1. Adapters can be slow to open (~20 secs) and close (~5 secs), please be 
-   patient.
-2. This driver works very well when autoprobing for adapters. Why even 
-   think about those nasty io/int/dma settings of modprobe when the driver 
-   will do it all for you!
-
-This driver is rather simple to use. Select Y to Token Ring adapter support
-in the kernel configuration. A choice for SysKonnect Token Ring adapters will
-appear. This drives supports all SysKonnect ISA and PCI adapters. Choose this
-option. I personally recommend compiling the driver as a module (M), but if you
-you would like to compile it staticly answer Y instead.
-
-This driver supports multiple adapters without the need to load multiple copies
-of the driver. You should be able to load up to 7 adapters without any kernel
-modifications, if you are in need of more please contact the maintainer of this
-driver.
-
-Load the driver either by lilo/loadlin or as a module. When a module using the
-following command will suffice for most:
-
-# modprobe sktr
-
-This will produce output similar to the following: (Output is user specific)
-
-sktr.c: v1.01 08/29/97 by Christoph Goos
-tr0: SK NET TR 4/16 PCI found at 0x6100, using IRQ 17.
-tr1: SK NET TR 4/16 PCI found at 0x6200, using IRQ 16.
-tr2: SK NET TR 4/16 ISA found at 0xa20, using IRQ 10 and DMA 5.
-
-Now just setup the device via ifconfig and set and routes you may have. After
-this you are ready to start sending some tokens.
-
-Errata:
-For anyone wondering where to pick up the SysKonnect adapters please browse
-to http://www.syskonnect.com
-
-This driver is under the GNU General Public License. Its Firmware image is 
-included as an initialized C-array and is licensed by SysKonnect to the Linux 
-users of this driver. However no waranty about its fitness is expressed or 
-implied by SysKonnect.
-
-Below find attached the setting for the SK NET TR 4/16 ISA adapters
--------------------------------------------------------------------
-
-                    ***************************
-                    ***   C O N T E N T S   ***
-                    ***************************
-
-                1) Location of DIP-Switch W1
-                2) Default settings
-                3) DIP-Switch W1 description
-
-
-  ==============================================================
-  CHAPTER 1     LOCATION OF DIP-SWITCH
-  ==============================================================
-
-UÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
-þUÄÄÄÄÄÄ¿                         UÄÄÄÄÄ¿            UÄÄÄ¿         Ã¾
-þAÄÄÄÄÄÄU                      W1 AÄÄÄÄÄU     UÄÄÄÄ¿ Ã¾   Ã¾         Ã¾
-þUÄÄÄÄÄÄ¿                                     Ã¾    Ã¾ Ã¾   Ã¾      UÄÄÅ¿
-þAÄÄÄÄÄÄU              UÄÄÄÄÄÄÄÄÄÄÄ¿          AÄÄÄÄU Ã¾   Ã¾      Ã¾  Ã¾Ã¾
-þUÄÄÄÄÄÄ¿              Ã¾           Ã¾          UÄÄÄ¿  AÄÄÄU      AÄÄÅU
-þAÄÄÄÄÄÄU              Ã¾ TMS380C26 Ã¾          Ã¾   Ã¾                Ã¾
-þUÄÄÄÄÄÄ¿              Ã¾           Ã¾          AÄÄÄU                AÄ¿
-þAÄÄÄÄÄÄU              Ã¾           Ã¾                               Ã¾ Ã¾
-þ                      AÄÄÄÄÄÄÄÄÄÄÄU                               Ã¾ Ã¾
-þ                                                                  Ã¾ Ã¾
-þ                                                                  AÄU
-þ                                                                  Ã¾
-þ                                                                  Ã¾
-þ                                                                  Ã¾
-þ                                                                  Ã¾
-AÄÄÄÄÄÄÄÄÄÄÄÄAÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄAÄÄAÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄAÄÄÄÄÄÄÄÄÄU
-             AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄU  AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄU
-
-  ==============================================================
-  CHAPTER 2     DEFAULT SETTINGS
-  ==============================================================
-
-          W1    1  2  3  4  5  6  7  8
-        +------------------------------+
-        | ON    X                      |
-        | OFF      X  X  X  X  X  X  X |
-        +------------------------------+
-
-        W1.1 = ON               Adapter drives address lines SA17..19
-        W1.2 - 1.5 = OFF        BootROM disabled
-        W1.6 - 1.8 = OFF        I/O address 0A20h
-
-  ==============================================================
-  CHAPTER 3     DIP SWITCH W1 DESCRIPTION
-  ==============================================================
-
-      UÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄ¿  ON
-      Ã¾ 1 Ã¾ 2 Ã¾ 3 Ã¾ 4 Ã¾ 5 Ã¾ 6 Ã¾ 7 Ã¾ 8 Ã¾
-      AÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄU  OFF
-      |AD | BootROM Addr. |  I/O      |
-      +-+-+-------+-------+-----+-----+
-        |         |             |
-        |         |             +------ 6     7     8
-        |         |                     ON    ON    ON       1900h
-        |         |                     ON    ON    OFF      0900h
-        |         |                     ON    OFF   ON       1980h
-        |         |                     ON    OFF   OFF      0980h
-        |         |                     OFF   ON    ON       1b20h
-        |         |                     OFF   ON    OFF      0b20h
-        |         |                     OFF   OFF   ON       1a20h
-        |         |                     OFF   OFF   OFF      0a20h    (+)
-        |         |
-        |         |
-        |         +-------- 2     3     4     5
-        |                   OFF   x     x     x       disabled  (+)
-        |                   ON    ON    ON    ON      C0000
-        |                   ON    ON    ON    OFF     C4000
-        |                   ON    ON    OFF   ON      C8000
-        |                   ON    ON    OFF   OFF     CC000
-        |                   ON    OFF   ON    ON      D0000
-        |                   ON    OFF   ON    OFF     D4000
-        |                   ON    OFF   OFF   ON      D8000
-        |                   ON    OFF   OFF   OFF     DC000
-        |
-        |
-        +----- 1
-               OFF    adapter does NOT drive SA<17..19>
-               ON     adapter drives SA<17..19>  (+)
-
-
-        (+) means default setting
-
-                       ********************************
diff --git a/Documentation/networking/smctr.txt b/Documentation/networking/smctr.txt
new file mode 100644 (file)
index 0000000..f93c514
--- /dev/null
@@ -0,0 +1,68 @@
+Text File for the SMC TokenCard TokenRing Linux driver (smctr.c).
+        By Jay Schulist <jschlst@turbolinux.com>
+
+The Linux SMC Token Ring driver works with the SMC TokenCard Elite (8115T) 
+ISA adapters. Preliminary support for the SMC TokenCard Elite/A (8115T/A) 
+MCA adapter has been started but is not complete. (Contact me for information
+if you have the proper setup to finish the MCA parts).
+
+Latest information on this driver can be obtained on the Linux-SNA WWW site.
+Please point your browser to: http://www.linux-sna.org
+
+This driver is rather simple to use. Select Y to Token Ring adapter support
+in the kernel configuration. A choice for SMC Token Ring adapters will
+appear. This drives supports all SMC ISA/MCA adapters. Choose this
+option. I personally recommend compiling the driver as a module (M), but if you
+you would like to compile it staticly answer Y instead.
+
+This driver supports multiple adapters without the need to load multiple copies
+of the driver. You should be able to load up to 7 adapters without any kernel
+modifications, if you are in need of more please contact the maintainer of this
+driver.
+
+Load the driver either by lilo/loadlin or as a module. When a module using the
+following command will suffice for most:
+
+# modprobe smctr
+smctr.c: v1.00 12/6/99 by jschlst@turbolinux.com
+tr0: SMC TokenCard 8115T at Io 0x300, Irq 10, Rom 0xd8000, Ram 0xcc000.
+
+Now just setup the device via ifconfig and set and routes you may have. After
+this you are ready to start sending some tokens.
+
+Errata:
+1). For anyone wondering where to pick up the SMC adapters please browse
+    to http://www.smc.com
+
+2). If you are the first/only Token Ring Client on a Token Ring LAN, please
+    specify the ringspeed with the ringspeed=[4/16] module option. If no
+    ringspeed is specified the driver will attempt to autodetect the ring
+    speed and/or if the adapter is the first/only station on the ring take
+    the appropriate actions. 
+
+    NOTE: Default ring speed is 16MB UTP.
+
+3). PnP support for this adapter sucks. I recommend hard setting the 
+    IO/MEM/IRQ by the jumpers on the adapter. If this is not possible
+    load the module with the following io=[ioaddr] mem=[mem_addr]
+    irq=[irq_num].
+
+    The following IRQ, IO, and MEM settings are supported.
+
+    IO ports:
+    0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300,
+    0x320, 0x340, 0x360, 0x380.
+
+    IRQs:
+    2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15
+
+    Memory addresses:
+    0xA0000, 0xA4000, 0xA8000, 0xAC000, 0xB0000, 0xB4000,
+    0xB8000, 0xBC000, 0xC0000, 0xC4000, 0xC8000, 0xCC000,
+    0xD0000, 0xD4000, 0xD8000, 0xDC000, 0xE0000, 0xE4000,
+    0xE8000, 0xEC000, 0xF0000, 0xF4000, 0xF8000, 0xFC000
+
+This driver is under the GNU General Public License. Its Firmware image is
+included as an initialized C-array and is licensed by SMC to the Linux
+users of this driver. However no waranty about its fitness is expressed or
+implied by SMC.
diff --git a/Documentation/networking/tms380tr.txt b/Documentation/networking/tms380tr.txt
new file mode 100644 (file)
index 0000000..f73895f
--- /dev/null
@@ -0,0 +1,147 @@
+Text file for the Linux SysKonnect Token Ring ISA/PCI Adapter Driver.
+       Text file by: Jay Schulist <jschlst@turbolinux.com>
+
+The Linux SysKonnect Token Ring driver works with the SysKonnect TR4/16(+) ISA,
+SysKonnect TR4/16(+) PCI, SysKonnect TR4/16 PCI, and older revisions of the
+SK NET TR4/16 ISA card.
+
+Latest information on this driver can be obtained on the Linux-SNA WWW site.
+Please point your browser to: 
+http://www.linux-sna.org
+
+Many thanks to Christoph Goos for his excellent work on this driver and
+SysKonnect for donating the adapters to Linux-SNA for the testing and maintaince
+of this device driver.
+
+Important information to be noted:
+1. Adapters can be slow to open (~20 secs) and close (~5 secs), please be 
+   patient.
+2. This driver works very well when autoprobing for adapters. Why even 
+   think about those nasty io/int/dma settings of modprobe when the driver 
+   will do it all for you!
+
+This driver is rather simple to use. Select Y to Token Ring adapter support
+in the kernel configuration. A choice for SysKonnect Token Ring adapters will
+appear. This drives supports all SysKonnect ISA and PCI adapters. Choose this
+option. I personally recommend compiling the driver as a module (M), but if you
+you would like to compile it staticly answer Y instead.
+
+This driver supports multiple adapters without the need to load multiple copies
+of the driver. You should be able to load up to 7 adapters without any kernel
+modifications, if you are in need of more please contact the maintainer of this
+driver.
+
+Load the driver either by lilo/loadlin or as a module. When a module using the
+following command will suffice for most:
+
+# modprobe sktr
+
+This will produce output similar to the following: (Output is user specific)
+
+sktr.c: v1.01 08/29/97 by Christoph Goos
+tr0: SK NET TR 4/16 PCI found at 0x6100, using IRQ 17.
+tr1: SK NET TR 4/16 PCI found at 0x6200, using IRQ 16.
+tr2: SK NET TR 4/16 ISA found at 0xa20, using IRQ 10 and DMA 5.
+
+Now just setup the device via ifconfig and set and routes you may have. After
+this you are ready to start sending some tokens.
+
+Errata:
+For anyone wondering where to pick up the SysKonnect adapters please browse
+to http://www.syskonnect.com
+
+This driver is under the GNU General Public License. Its Firmware image is 
+included as an initialized C-array and is licensed by SysKonnect to the Linux 
+users of this driver. However no waranty about its fitness is expressed or 
+implied by SysKonnect.
+
+Below find attached the setting for the SK NET TR 4/16 ISA adapters
+-------------------------------------------------------------------
+
+                    ***************************
+                    ***   C O N T E N T S   ***
+                    ***************************
+
+                1) Location of DIP-Switch W1
+                2) Default settings
+                3) DIP-Switch W1 description
+
+
+  ==============================================================
+  CHAPTER 1     LOCATION OF DIP-SWITCH
+  ==============================================================
+
+UÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
+þUÄÄÄÄÄÄ¿                         UÄÄÄÄÄ¿            UÄÄÄ¿         Ã¾
+þAÄÄÄÄÄÄU                      W1 AÄÄÄÄÄU     UÄÄÄÄ¿ Ã¾   Ã¾         Ã¾
+þUÄÄÄÄÄÄ¿                                     Ã¾    Ã¾ Ã¾   Ã¾      UÄÄÅ¿
+þAÄÄÄÄÄÄU              UÄÄÄÄÄÄÄÄÄÄÄ¿          AÄÄÄÄU Ã¾   Ã¾      Ã¾  Ã¾Ã¾
+þUÄÄÄÄÄÄ¿              Ã¾           Ã¾          UÄÄÄ¿  AÄÄÄU      AÄÄÅU
+þAÄÄÄÄÄÄU              Ã¾ TMS380C26 Ã¾          Ã¾   Ã¾                Ã¾
+þUÄÄÄÄÄÄ¿              Ã¾           Ã¾          AÄÄÄU                AÄ¿
+þAÄÄÄÄÄÄU              Ã¾           Ã¾                               Ã¾ Ã¾
+þ                      AÄÄÄÄÄÄÄÄÄÄÄU                               Ã¾ Ã¾
+þ                                                                  Ã¾ Ã¾
+þ                                                                  AÄU
+þ                                                                  Ã¾
+þ                                                                  Ã¾
+þ                                                                  Ã¾
+þ                                                                  Ã¾
+AÄÄÄÄÄÄÄÄÄÄÄÄAÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄAÄÄAÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄAÄÄÄÄÄÄÄÄÄU
+             AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄU  AÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄU
+
+  ==============================================================
+  CHAPTER 2     DEFAULT SETTINGS
+  ==============================================================
+
+          W1    1  2  3  4  5  6  7  8
+        +------------------------------+
+        | ON    X                      |
+        | OFF      X  X  X  X  X  X  X |
+        +------------------------------+
+
+        W1.1 = ON               Adapter drives address lines SA17..19
+        W1.2 - 1.5 = OFF        BootROM disabled
+        W1.6 - 1.8 = OFF        I/O address 0A20h
+
+  ==============================================================
+  CHAPTER 3     DIP SWITCH W1 DESCRIPTION
+  ==============================================================
+
+      UÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄ¿  ON
+      Ã¾ 1 Ã¾ 2 Ã¾ 3 Ã¾ 4 Ã¾ 5 Ã¾ 6 Ã¾ 7 Ã¾ 8 Ã¾
+      AÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄAÄÄÄU  OFF
+      |AD | BootROM Addr. |  I/O      |
+      +-+-+-------+-------+-----+-----+
+        |         |             |
+        |         |             +------ 6     7     8
+        |         |                     ON    ON    ON       1900h
+        |         |                     ON    ON    OFF      0900h
+        |         |                     ON    OFF   ON       1980h
+        |         |                     ON    OFF   OFF      0980h
+        |         |                     OFF   ON    ON       1b20h
+        |         |                     OFF   ON    OFF      0b20h
+        |         |                     OFF   OFF   ON       1a20h
+        |         |                     OFF   OFF   OFF      0a20h    (+)
+        |         |
+        |         |
+        |         +-------- 2     3     4     5
+        |                   OFF   x     x     x       disabled  (+)
+        |                   ON    ON    ON    ON      C0000
+        |                   ON    ON    ON    OFF     C4000
+        |                   ON    ON    OFF   ON      C8000
+        |                   ON    ON    OFF   OFF     CC000
+        |                   ON    OFF   ON    ON      D0000
+        |                   ON    OFF   ON    OFF     D4000
+        |                   ON    OFF   OFF   ON      D8000
+        |                   ON    OFF   OFF   OFF     DC000
+        |
+        |
+        +----- 1
+               OFF    adapter does NOT drive SA<17..19>
+               ON     adapter drives SA<17..19>  (+)
+
+
+        (+) means default setting
+
+                       ********************************
diff --git a/Documentation/sound/via82cxxx.txt b/Documentation/sound/via82cxxx.txt
new file mode 100644 (file)
index 0000000..62877fd
--- /dev/null
@@ -0,0 +1,146 @@
+                       Via motherboard audio driver
+       Copyright 1999,2000 Jeff Garzik <jgarzik@mandrakesoft.com>
+
+Driver software and documentation distributed under the GNU GENERAL
+PUBLIC LICENSE (GPL) Version 2. See the "COPYING" file distributed with
+this software for more info.
+
+
+
+Introduction
+------------------------------------------------------------------------
+The via82cxxx audio driver found in the drivers/sound directory
+of the kernel source tree is a PCI audio driver for audio chips
+found on Via-based motherboards, such as the MVP4.
+
+Currently the driver provides audio via SoundBlaster Pro compatibility,
+and MIDI via MPU-401 compatibility.  An AC97 mixing device is also
+supported, and is generally preferred over the SoundBlaster mixer.
+
+IMPORTANT NOTE:  Some users report that the SoundBlaster mixer does
+not work at all -- use the AC97 mixer if possible.
+
+Please send bug reports to the mailing list linux-via@gtf.org.
+To subscribe, e-mail majordomo@gtf.org with "subscribe linux-via" in the
+body of the message.
+
+
+Thanks
+------------------------------------------------------------------------
+Via for providing e-mail support, specs, and NDA's source code.
+
+MandrakeSoft for providing hacking time.
+
+AC97 mixer interface fixes and debugging by Ron Cemer <roncemer@gte.net>
+
+
+
+Installation
+------------------------------------------------------------------------
+If the driver is being statically compiled into the kernel, no
+configuration should be necessary.
+
+If the driver is being compiled as a module, generally two lines must
+be added to your /etc/conf.modules (or /etc/modules.conf) file:
+
+       alias sound via82cxxx
+       options sb support=1
+
+The second line is very important:  it tells the required 'sb' module
+not to load SoundBlaster support, but to instead let the Via driver
+do so at a later time.
+
+
+
+Driver notes
+------------------------------------------------------------------------
+This driver by default supports all PCI audio devices which report
+a vendor id of 0x1106, and a device id of 0x3058.  Subsystem vendor
+and device ids are not examined.
+
+Only supports a single sound chip, as this is a motherboard chipset.
+Some architecture remains for multiple cards, feel free to submit
+a patch to clean some of that up.  Ideally, 
+
+No consideration for SMP, this chipset is not known to be found on
+any SMP motherboards.  However, this will change when we start handling
+our own interrupts in "native mode."
+
+GNU indent formatting options:  -kr -i8 -pcs
+
+
+
+Tested Hardware
+------------------------------------------------------------------------
+The following is an _incomplete_ list of motherboards supported by this
+audio driver.  If your motherboard (or notebook) is not listed here,
+please e-mail the maintainer with details.
+
+       AOpen MX59 Pro (Apollo MVP4)
+
+
+
+The Future
+------------------------------------------------------------------------
+Via has graciously donated e-mail support and source code to help further
+the development of this driver.  Their assistance has been invaluable
+in the design and coding of the next major version of this driver.
+
+This audio chip supports a DirectSound(tm)-style hardware interface,
+with a single 16-bit stereo input channel, and a single 16-bit stereo
+output channel.  Data is transferred to/from the hardware using
+table-driven scatter-gather DMA buffers.
+
+Work is currently underway to support this "native mode" of the chip.
+When complete, SoundBlaster legacy mode will be completely removed.
+After a round of testing, this code will become version 2.0.0.
+
+Following the 2.0.0 release, the last major task to complete is
+MIDI support.  MPU-401 legacy support is available currently, but
+not well tested at all.
+
+The Via audio chip apparently provides a second PCM scatter-gather
+DMA channel just for FM data, but does not have a full hardware MIDI
+processor.  I haven't put much thought towards a solution here, but it
+might involve using SoftOSS midi wave table, or simply disabling MIDI
+support altogether and using the FM PCM channel as a second (input? output?)
+
+
+
+General To-do List (patches/suggestions welcome)
+------------------------------------------------------------------------
+Better docs
+
+Code review by sound guru(s)
+
+Native DSP audio driver using scatter-gather DMA, as described above
+
+Native MIDI driver, as described above
+
+
+
+Known bugs (patches/suggestions welcome)
+------------------------------------------------------------------------
+1) Two MIDI devices are loaded by the sound driver.  Eliminate one of them. 
+Sample /proc/sound output:
+
+       Midi devices:
+       0: Sound Blaster
+       1: VIA 82Cxxx Audio driver 1.1.2
+
+2) Two mixer devices are loaded by the sound driver.  Eliminate one of
+them.  At least one bug report says that SB mixer does not work at all,
+only AC97 mixer.  Sample /proc/sound output:
+
+       Mixers:
+       0: via82cxxxAC97Mixer
+       1: Sound Blaster
+
+3) After unloading the driver, a SoundBlaster MIDI device is still 
+listed in /proc/sound.  Investigate what is not being unloaded,
+and fix it.  Sample /proc/sound output, after 'rmmod via82cxxx':
+
+       Midi devices:
+       0: Sound Blaster
+
+
index b4b9d0dcc61ff9e184f8f150f31c00d1dbc78824..7f144ad9ceb1a77d97755984e123ecfda96ce5d5 100644 (file)
@@ -30,7 +30,7 @@ passed to the ioctl is completed and returned. It contains the following
 information
 <P>
 <TABLE>
-<TR><TD><b>name[32]</b><TD>Cannonical name for this interface</TD>
+<TR><TD><b>name[32]</b><TD>Canonical name for this interface</TD>
 <TR><TD><b>type</b><TD>Type of interface</TD>
 <TR><TD><b>channels</b><TD>Number of radio/tv channels if appropriate</TD>
 <TR><TD><b>audios</b><TD>Number of audio devices if appropriate</TD>
@@ -125,7 +125,7 @@ disabled by passing it a value of 0.
 <P>
 Some capture devices can capture a subfield of the image they actually see.
 This is indicated when VIDEO_TYPE_SUBCAPTURE is defined.
-The video_capture describes the time and spacial subfields to capture.
+The video_capture describes the time and special subfields to capture.
 The video_capture structure contains the following fields.
 <P>
 <TABLE>
@@ -235,7 +235,7 @@ giving the tuner to use. A struct tuner has the following fields
 <P>
 <TABLE>
 <TR><TD><b>tuner</b><TD>Number of the tuner</TD>
-<TR><TD><b>name</b><TD>Cannonical name for this tuner (eg FM/AM/TV)</TD>
+<TR><TD><b>name</b><TD>Canonical name for this tuner (eg FM/AM/TV)</TD>
 <TR><TD><b>rangelow</b><TD>Lowest tunable frequency</TD>
 <TR><TD><b>rangehigh</b><TD>Highest tunable frequency</TD>
 <TR><TD><b>flags</b><TD>Flags describing the tuner</TD>
@@ -279,7 +279,7 @@ The structure contains the following fields
 <P>
 <TABLE>
 <TR><TD><b>audio</b><TD>The channel number</TD>
-<TR><TD><b>volume</b><TD>The voume level</TD>
+<TR><TD><b>volume</b><TD>The volume level</TD>
 <TR><TD><b>bass</b><TD>The bass level</TD>
 <TR><TD><b>treble</b><TD>The treble level</TD>
 <TR><TD><b>flags</b><TD>Flags describing the audio channel</TD>
@@ -359,13 +359,13 @@ For radio devices that support it, it is possible to receive Radio Data
 System (RDS) data by means of a read() on the device.  The data is packed in
 groups of three, as follows:
 <TABLE>
-<TR><TD>First Octet</TD><TD>Least Siginificant Byte of RDS Block</TD></TR>
-<TR><TD>Second Octet</TD><TD>Most Siginificant Byte of RDS Block
+<TR><TD>First Octet</TD><TD>Least Significant Byte of RDS Block</TD></TR>
+<TR><TD>Second Octet</TD><TD>Most Significant Byte of RDS Block
 <TR><TD>Third Octet</TD><TD>Bit 7:</TD><TD>Error bit.  Indicates that
-an uncorrectable error occured during reception of this block.</TD></TR>
+an uncorrectable error occurred during reception of this block.</TD></TR>
 <TR><TD>&nbsp;</TD><TD>Bit 6:</TD><TD>Corrected bit.  Indicates that  
 an error was corrected for this data block.</TD></TR>
-<TR><TD>&nbsp;</TD><TD>Bits 5-3:</TD><TD>Reeived Offset.  Indicates the  
+<TR><TD>&nbsp;</TD><TD>Bits 5-3:</TD><TD>Received Offset.  Indicates the  
 offset received by the sync system.</TD></TR>
 <TR><TD>&nbsp;</TD><TD>Bits 2-0:</TD><TD>Offset Name.  Indicates the  
 offset applied to this data.</TD></TR>
index b9eb9cd74f3f7d507aeb273caeab39c180dc0122..5eaf517bc7366e0db8f57c0a9618daff08e7348f 100644 (file)
@@ -41,7 +41,7 @@ grabbing facilities, you must either
   various kernel versions floating around in the net,
   you may obtain one e.g. from:
   http://www.polyware.nl/~middelin/patch/bigphysarea-2.2.1.tar.gz
-  You also have to compile your driber AFTER installing that patch
+  You also have to compile your driver AFTER installing that patch
   in order to get it working
 
   or
@@ -91,9 +91,9 @@ These values do not affect the MJPEG grabbing facilities of the driver,
 they are needed for uncompressed image grabbing only!!!
 
 v4l_nbufs is the number of buffers to allocate, a value of 2 (the default)
-should be sufficient in allmost all cases. Only special applications
+should be sufficient in almost all cases. Only special applications
 (streaming captures) will need more buffers and then mostly the
-MJPEG capturing features of the Buz will be more apropriate.
+MJPEG capturing features of the Buz will be more appropriate.
 So leave this parameter at it's default unless you know what you do.
 
 The things for v4l_bufsize are more complicated:
@@ -107,7 +107,7 @@ In order to be able to capture bigger images you have either to
   the necessary memory during boot time or
 - start your kernel with the mem=xxx option, where xxx is your
   real memory minus the memory needed for the buffers.
-In that case, usefull settings for v4l_bufsize are
+In that case, useful settings for v4l_bufsize are
 - 1296 [Kb] for grabbing 24 bit images of max size 768*576
 - 1728 [Kb] for 32bit images of same size (4*768*576 = 1728 Kb!)
 You may reduce these numbers accordingly if you know you are only
@@ -137,7 +137,7 @@ triton, natoma
 --------------
 
 The driver tries to detect if you have a triton or natome chipset
-in order to take special messures for these chipsets.
+in order to take special measures for these chipsets.
 If this detection fails but you are sure you have such a chipset,
 set the corresponding variable to 1.
 This is a very special option and may go away in the future.
@@ -151,7 +151,7 @@ This driver should be fully compliant to Video for Linux, so all
 tools working with Video for Linux should work with (hopefully)
 no problems.
 
-A description of the Video for Linux programming interace can be found at:
+A description of the Video for Linux programming interface can be found at:
 http://roadrunner.swansea.linux.org.uk/v4lapi.shtml
 
 Besides the Video for Linux interface, the driver has a "proprietary"
@@ -162,7 +162,7 @@ The ioctls for that interface are as follows:
 BUZIOC_G_PARAMS
 BUZIOC_S_PARAMS
 
-Get and set the parameters of the buz. The user should allways
+Get and set the parameters of the buz. The user should always
 do a BUZIOC_G_PARAMS (with a struct buz_params) to obtain the default
 settings, change what he likes and then make a BUZIOC_S_PARAMS call.
 A typical application should at least set the members
index 43dbdf53d804784c68954493d8e7ad26480bb0a1..838413146dd00f85df1e0fee438d1fe05e9a4e5e 100644 (file)
@@ -20,7 +20,7 @@ bttv.o
                autoload=0/1    autoload helper modules (tuner, audio).
                                default is 1 (on).
 
-       remap, card, radio and pll accept up to four comma-separted arguments
+       remap, card, radio and pll accept up to four comma-separated arguments
        (for multiple boards).
 
 msp3400.o
index 0371d2e74e75ae39dc5d14792427b0a42d53e74d..8e31e9e36bf7ee2f123d7125959f1980e1df1c03 100644 (file)
@@ -4,7 +4,7 @@
 
 - The memory of some S3 cards is not recognized right:
   
-  First of all, if you are not using Xfree-3.2 or newer, upgrade AT LEAST to
+  First of all, if you are not using XFree-3.2 or newer, upgrade AT LEAST to
   XFree-3.2A! This solved the problem for most people.
 
   Start up X11 like this: "XF86_S3 -probeonly" and write down where the
index 7b087654f94c15f0f25d6f2480e5f39e337a76b3..00b23c52ae283a20f883b1ca9f9a691dfd4edc31 100644 (file)
@@ -36,7 +36,7 @@ else ;-)
 Make bttv work with your card
 -----------------------------
 
-Of cource you have to load the modules as very first thing.  The
+Of course you have to load the modules as very first thing.  The
 separate bttv bundle comes with a script called "update".  I use this
 one to load a new version while doing driver hacking.  You can use it
 too, but check the module arguments first.  They work for my setup,
@@ -49,7 +49,7 @@ Insmod-options:       list of all insmod options available for bttv and
 MAKEDEV:       a script to create the special files for v4l
 CARDLIST:      List of all supported cards
 
-Loading just the bttv modules is'nt enouth for most cards.  The
+Loading just the bttv modules isn't enough for most cards.  The
 drivers for the i2c tuner/sound chips must also be loaded.  bttv tries
 to load them automagically by calling request_module() now, but this
 obviously works only with kmod enabled.
@@ -59,15 +59,15 @@ correct card type.  If you get video but no sound you've very likely
 specified the wrong (or no) card type.  A list of supported cards is
 in CARDLIST.
 
-If your card is'nt listed in CARDLIST, you should read the Sound-FAQ.
+If your card isn't listed in CARDLIST, you should read the Sound-FAQ.
 
 
-Still does'nt work?
+Still doesn't work?
 -------------------
 
 I do NOT have a lab with 30+ different grabber boards and a
 PAL/NTSC/SECAM test signal generator at home, so I often can't
-reproduce your problems.  This makes debugging very difficuilt for me.
+reproduce your problems.  This makes debugging very difficult for me.
 If you have some knowledge and spare time, please try to fix this
 yourself (patches very welcome of course...)  You know: The linux
 slogan is "Do it yourself".
index cf774575831e2f20d850c4a8ef56c660d1233e88..ce8895700c64c559d31e059c9f3d9bacd5df5de9 100644 (file)
@@ -38,7 +38,7 @@ mixer settings too...
 How sound works in detail
 =========================
 
-Still does'nt work?  Looks like some driver hacking is required.
+Still doesn't work?  Looks like some driver hacking is required.
 Below is a do-it-yourself description for you.
 
 The bt8xx chips have 32 general purpose pins, and registers to control
index fe942e8a9ff5bfb1f7c66ed7f7ee0b116102b76d..a3f2347f0b33542472c3e38fca95132b3ef68b70 100644 (file)
@@ -10,7 +10,7 @@ This document was made based on 'C' code for Linux from Gideon le Grange
 (legrang@active.co.za or legrang@cs.sun.ac.za) in 1994, and elaborations from
 Frans Brinkman (brinkman@esd.nl) in 1996.  The results reported here are from
 experiments that the author performed on his own setup, so your mileage may
-vary... I make no guarantees, claims or warrantees to the suitability or
+vary... I make no guarantees, claims or warranties to the suitability or
 validity of this information.  No other documentation on the AIMS
 Lab (http://www.aimslab.com/) RadioTrack card was made available to the
 author.  This document is offered in the hopes that it might help users who
index a028f2b543cac8e6a6436906c5ac0ac4eea44ef0..54e46326a1e0e230e7168fb5fe3be32e556ed3ee 100644 (file)
@@ -31,20 +31,20 @@ After some testing, I discovered that the carddesigner messed up
 on the I2C interface. The Zoran chip includes 2 lines SDA and SCL
 which (s)he connected reversely. So we have to clock on the SDA
 and r/w data on the SCL pin. Life is fun... Each cardtype now has
-a bit which signifies if you have a card with the same deficiancy.
+a bit which signifies if you have a card with the same deficiency.
 
-Oh, for the completness of this story I must mention that my
+Oh, for the completeness of this story I must mention that my
 card delivers the VSYNC pulse of the SAA chip to GIRQ1, not
-GIRQ0 as some other cards have. This is also incorperated in
+GIRQ0 as some other cards have. This is also incorporated in
 the driver be clearing/setting the 'useirq1' bit in the tvcard
 description.
 
-Another problems of contingious capturing data with a Zoran chip
+Another problems of continuous capturing data with a Zoran chip
 is something nasty inside the chip. It effectively halves the
 fps we ought to get... Here is the scenario: capturing frames
 to memory is done in the so-called snapshot mode. In this mode
 the Zoran stops after capturing a frame worth of data and wait
-till the application set GRAB bit to indicate readyness for the
+till the application set GRAB bit to indicate readiness for the
 next frame. After detecting a set bit, the chip neetly waits
 till the start of a frame, captures it and it goes back to off.
 Smart ppl will notice the problem here. Its the waiting on the
@@ -101,7 +101,7 @@ After making the modules check if you have the much needed
        mknod /dev/video3 c 81 3
        mknod /dev/video4 c 81 4
 
-After makeing/checking the devices do:
+After making/checking the devices do:
        modprobe i2c
        modprobe videodev
        modprobe saa7110        (optional)
index a56a30e690155a3f7c90898166b4b3af35c7a6ef..87030a1584238d99bf7d16492d13d942afc80c95 100644 (file)
@@ -135,7 +135,7 @@ S:  Supported
 
 APPLETALK NETWORK LAYER
 P:     Jay Schulist
-M:     Jay.Schulist@spacs.k12.wi.us
+M:     jschlst@turbolinux.com
 L:     linux-atalk@netspace.org
 S:     Maintained
 
@@ -469,7 +469,7 @@ S:  Maintained
 
 IPX/SPX NETWORK LAYER
 P:     Jay Schulist
-M:     Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
+M:     jschlst@turbolinux.com
 L:     linux-net@vger.rutgers.edu
 S:     Maintained
 
@@ -580,8 +580,8 @@ L:  linux-kernel@vger.rutgers.edu
 S:     Maintained
 
 MODULE SUPPORT [GENERAL], KERNELD
-P:     Richard Henderson
-M:     richard@gnu.ai.mit.edu
+P:     Keith Owens
+M:     kaos@ocs.com.au
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
@@ -869,10 +869,17 @@ S:        Supported
 
 SPX NETWORK LAYER
 P:     Jay Schulist
-M:     Jay.Schulist@spacs.k12.wi.us
+M:     jschlst@turbolinux.com
 L:     linux-net@vger.rutgers.edu
 S:     Supported
 
+SNA NETWORK LAYER
+P:     Jay Schulist
+M:     jschlst@turbolinux.com
+L:     linux-sna@turbolinux.com
+W:     http://www.linux-sna.org
+S:     Supported
+
 STALLION TECHNOLOGIES MULTIPORT SERIAL BOARDS
 M:     support@stallion.oz.au
 W:     http://www.stallion.com
index e8afdf387a479106ef069a911788659d9a6b7d21..3a13e541eb5624303efc950f0711cac1012adacf 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 3
-SUBLEVEL = 37
+SUBLEVEL = 38
 EXTRAVERSION =
 
 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 a1f137898f155c961b39cba1dc50e59a8558e50f..e77f3a3e84fb3487930b2863aa3f597b0baa7730 100644 (file)
--- a/README
+++ b/README
@@ -9,7 +9,7 @@ public use.  Different releases may have various and sometimes severe
 bugs.  It is *strongly* recommended that you back up the previous kernel
 before installing any new 2.3.xx release.
 
-If you need to use a proven and stable Linux kernel, please use 2.0.37
+If you need to use a proven and stable Linux kernel, please use 2.0.38
 or 2.2.xx.  All features which will be in the 2.3.xx releases will be
 contained in 2.4.xx when the code base has stabilized again. 
 
index 1db3bec2e9347f42db57d8e69b2909cf8146c825..654602855d72febb7e314d2cd8180684bf52bba4 100644 (file)
@@ -122,7 +122,7 @@ source drivers/parport/Config.in
 bool 'ACPI support' CONFIG_ACPI
 if [ "$CONFIG_ACPI" != "n" ]; then
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-     bool '  Enter S1 for sleep' CONFIG_ACPI_S1_SLEEP
+      bool '  Enter S1 for sleep (EXPERIMENTAL)' CONFIG_ACPI_S1_SLEEP
    fi
 fi
 
index 1c1f6b74bb5b3f86e80c19d3cc14c2a912a861d6..6de34e798323471d12f2fcc9f5b623850ed73eda 100644 (file)
               Changed locking to spin with reschedule.
               Made use of new <smp_call_function>.
   v1.28
-    19990201   Zoltan Boszormenyi <zboszor@mol.hu>
+    19990201   Zoltán Böszörményi <zboszor@mail.externet.hu>
               Extended the driver to be able to use Cyrix style ARRs.
     19990204   Richard Gooch <rgooch@atnf.csiro.au>
               Restructured Cyrix support.
   v1.29
-    19990204   Zoltan Boszormenyi <zboszor@mol.hu>
+    19990204   Zoltán Böszörményi <zboszor@mail.externet.hu>
               Refined ARR support: enable MAPEN in set_mtrr_prepare()
               and disable MAPEN in set_mtrr_done().
     19990205   Richard Gooch <rgooch@atnf.csiro.au>
               Minor cleanups.
   v1.30
-    19990208   Zoltan Boszormenyi <zboszor@mol.hu>
+    19990208   Zoltán Böszörményi <zboszor@mail.externet.hu>
                Protect plain 6x86s (and other processors without the
                Page Global Enable feature) against accessing CR4 in
                set_mtrr_prepare() and set_mtrr_done().
     19990210   Richard Gooch <rgooch@atnf.csiro.au>
               Turned <set_mtrr_up> and <get_mtrr> into function pointers.
   v1.31
-    19990212   Zoltan Boszormenyi <zboszor@mol.hu>
+    19990212   Zoltán Böszörményi <zboszor@mail.externet.hu>
                Major rewrite of cyrix_arr_init(): do not touch ARRs,
                leave them as the BIOS have set them up.
                Enable usage of all 8 ARRs.
                Avoid multiplications by 3 everywhere and other
                code clean ups/speed ups.
-    19990213   Zoltan Boszormenyi <zboszor@mol.hu>
+    19990213   Zoltán Böszörményi <zboszor@mail.externet.hu>
                Set up other Cyrix processors identical to the boot cpu.
                Since Cyrix don't support Intel APIC, this is l'art pour l'art.
                Weigh ARRs by size:
                If size <= 32M is given, set up ARR# we were given.
                If size >  32M is given, set up ARR7 only if it is free,
                fail otherwise.
-    19990214   Zoltan Boszormenyi <zboszor@mol.hu>
+    19990214   Zoltán Böszörményi <zboszor@mail.externet.hu>
                Also check for size >= 256K if we are to set up ARR7,
                mtrr_add() returns the value it gets from set_mtrr()
-    19990218   Zoltan Boszormenyi <zboszor@mol.hu>
+    19990218   Zoltán Böszörményi <zboszor@mail.externet.hu>
                Remove Cyrix "coma bug" workaround from here.
                Moved to linux/arch/i386/kernel/setup.c and
                linux/include/asm-i386/bugs.h
     19990305   Richard Gooch <rgooch@atnf.csiro.au>
               Temporarily disable AMD support now MTRR capability flag is set.
   v1.32
-    19990308   Zoltan Boszormenyi <zboszor@mol.hu>
+    19990308   Zoltán Böszörményi <zboszor@mail.externet.hu>
               Adjust my changes (19990212-19990218) to Richard Gooch's
               latest changes. (19990228-19990305)
   v1.33
     19990512   Richard Gooch <rgooch@atnf.csiro.au>
               Minor cleanups.
   v1.35
-    19990707   Zoltan Boszormenyi <zboszor@mol.hu>
+    19990707   Zoltán Böszörményi <zboszor@mail.externet.hu>
                Check whether ARR3 is protected in cyrix_get_free_region()
                and mtrr_del(). The code won't attempt to delete or change it
                from now on if the BIOS protected ARR3. It silently skips ARR3
                in cyrix_get_free_region() or returns with an error code from
                mtrr_del().
-    19990711   Zoltan Boszormenyi <zboszor@mol.hu>
+    19990711   Zoltán Böszörményi <zboszor@mail.externet.hu>
                Reset some bits in the CCRs in cyrix_arr_init() to disable SMM
                if ARR3 isn't protected. This is needed because if SMM is active
                and ARR3 isn't protected then deleting and setting ARR3 again
                may lock up the processor. With SMM entirely disabled, it does
                not happen.
-    19990812   Zoltan Boszormenyi <zboszor@mol.hu>
+    19990812   Zoltán Böszörményi <zboszor@mail.externet.hu>
                Rearrange switch() statements so the driver accomodates to
                the fact that the AMD Athlon handles its MTRRs the same way
                as Intel does.
-    19990814   Zoltan Boszormenyi <zboszor@mol.hu>
+    19990814   Zoltán Böszörményi <zboszor@mail.externet.hu>
               Double check for Intel in mtrr_add()'s big switch() because
               that revision check is only valid for Intel CPUs.
     19990819   Alan Cox <alan@redhat.com>
@@ -957,11 +957,11 @@ static void set_mtrr_smp (unsigned int reg, unsigned long base,
     wait_barrier_execute = TRUE;
     wait_barrier_cache_enable = TRUE;
     atomic_set (&undone_count, smp_num_cpus - 1);
-    /*  Flush and disable the local CPU's cache        and start the ball rolling on
-       other CPUs  */
-    set_mtrr_prepare (&ctxt);
+    /*  Start the ball rolling on other CPUs  */
     if (smp_call_function (ipi_handler, &data, 1, 0) != 0)
        panic ("mtrr: timed out waiting for other CPUs\n");
+    /* Flush and disable the local CPU's cache */
+    set_mtrr_prepare (&ctxt);
     /*  Wait for all other CPUs to flush and disable their caches  */
     while (atomic_read (&undone_count) > 0) barrier ();
     /* Set up for completion wait and then release other CPUs to change MTRRs*/
index 59128c4c4897d9401044081870f52f68d2e82bcf..cd80009d4a17a6aa8318c89a8896cc8fd7633d32 100644 (file)
@@ -7,8 +7,8 @@
  *  and Martin Mares, November 1997.
  *
  *  Force Cyrix 6x86(MX) and M II processors to report MTRR capability
- *  and fix against Cyrix "coma bug" by
- *      Zoltan Boszormenyi <zboszor@mol.hu> February 1999.
+ *  and Cyrix "coma bug" recognition by
+ *      Zoltán Böszörményi <zboszor@mail.externet.hu> February 1999.
  * 
  *  Force Centaur C6 processors to report MTRR capability.
  *      Bart Hartgers <bart@etpmod.phys.tue.nl>, May 1999.
index 9dcde0a971519a16662bf1fa7500f570ea1ab927..ddac348fe76a789bcb3c4363fb4ed5139342b462 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.107 1999/12/27 06:08:37 anton Exp $
+/* $Id: sys_sunos.c,v 1.108 2000/01/06 23:51:46 davem Exp $
  * sys_sunos.c: SunOS specific syscall compatibility support.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
index e4e8eebecc4c04e6d510715b911acdfa8c2f49c3..0d5f7413964cd0235b746fd00dae00fe57e47201 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: rwsem.S,v 1.1 1999/12/28 11:50:39 jj Exp $
+/* $Id: rwsem.S,v 1.2 2000/01/05 01:00:38 davem Exp $
  * Assembly part of rw semaphores.
  *
  * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com)
index 11c29f971558bd051984f0772124a961832462e6..c102a62058d1ec6dbef1378aa2a21386935ff154 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.12 2000/01/01 03:32:50 davem Exp $
+/* $Id: pci.c,v 1.13 2000/01/06 23:51:49 davem Exp $
  * pci.c: UltraSparc PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com)
@@ -161,25 +161,19 @@ static void pci_scan_each_controller_bus(void)
  */
 static void __init pci_reorder_devs(void)
 {
-       struct pci_dev **pci_onboard = &pci_devices;
-       struct pci_dev **pci_tail = &pci_devices;
-       struct pci_dev *pdev = pci_devices, *pci_other = NULL;
+       struct list_head *pci_onboard = &pci_devices;
+       struct list_head *walk = pci_onboard->next;
+
+       while (walk != pci_onboard) {
+               struct pci_dev *pdev = pci_dev_g(walk);
+               struct list_head *walk_next = walk->next;
 
-       while (pdev) {
                if (pdev->irq && (__irq_ino(pdev->irq) & 0x20)) {
-                       if (pci_other) {
-                               *pci_onboard = pdev;
-                               pci_onboard = &pdev->next;
-                               pdev = pdev->next;
-                               *pci_onboard = pci_other;
-                               *pci_tail = pdev;
-                               continue;
-                       } else
-                               pci_onboard = &pdev->next;
-               } else if (!pci_other)
-                       pci_other = pdev;
-               pci_tail = &pdev->next;
-               pdev = pdev->next;
+                       list_del(walk);
+                       list_add(walk, pci_onboard);
+               }
+
+               walk = walk_next;
        }
 }
 
index 42a0cc963081ad1fa09349fd11e810d107869d04..154ee0181d56653cb437abf3a008c431a481fc7f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pci_common.c,v 1.5 1999/12/20 05:02:11 davem Exp $
+/* $Id: pci_common.c,v 1.6 2000/01/06 23:51:49 davem Exp $
  * pci_common.c: PCI controller common support.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -59,29 +59,8 @@ static int __init find_device_prom_node(struct pci_pbm_info *pbm,
  */
 static void pci_device_delete(struct pci_dev *pdev)
 {
-       struct pci_dev **dpp;
-
-       /* First, unlink from list of all devices. */
-       dpp = &pci_devices;
-       while (*dpp != NULL) {
-               if (*dpp == pdev) {
-                       *dpp = pdev->next;
-                       pdev->next = NULL;
-                       break;
-               }
-               dpp = &(*dpp)->next;
-       }
-
-       /* Next, unlink from bus sibling chain. */
-       dpp = &pdev->bus->devices;
-       while (*dpp != NULL) {
-               if (*dpp == pdev) {
-                       *dpp = pdev->sibling;
-                       pdev->sibling = NULL;
-                       break;
-               }
-               dpp = &(*dpp)->sibling;
-       }
+       list_del(&pdev->global_list);
+       list_del(&pdev->bus_list);
 
        /* Ok, all references are gone, free it up. */
        kfree(pdev);
@@ -175,23 +154,31 @@ void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus,
                                    struct pci_pbm_info *pbm,
                                    int prom_node)
 {
-       struct pci_dev *pdev;
+       struct list_head *walk = &pbus->devices;
 
        /* This loop is coded like this because the cookie
         * fillin routine can delete devices from the tree.
         */
-       pdev = pbus->devices;
-       while (pdev != NULL) {
-               struct pci_dev *next = pdev->sibling;
+       walk = walk->next;
+       while (walk != &pbus->devices) {
+               struct pci_dev *pdev = pci_dev_b(walk);
+               struct list_head *walk_next = walk->next;
 
                pdev_cookie_fillin(pbm, pdev, prom_node);
 
-               pdev = next;
+               walk = walk_next;
        }
 
-       for (pbus = pbus->children; pbus; pbus = pbus->next) {
-               struct pcidev_cookie *pcp = pbus->self->sysdata;
-               pci_fill_in_pbm_cookies(pbus, pbm, pcp->prom_node);
+       walk = &pbus->children;
+       walk = walk->next;
+       while (walk != &pbus->children) {
+               struct pci_bus *this_pbus = pci_bus_b(walk);
+               struct pcidev_cookie *pcp = this_pbus->self->sysdata;
+               struct list_head *walk_next = walk->next;
+
+               pci_fill_in_pbm_cookies(this_pbus, pbm, pcp->prom_node);
+
+               walk = walk_next;
        }
 }
 
@@ -315,13 +302,14 @@ static void __init pdev_record_assignments(struct pci_pbm_info *pbm,
 void __init pci_record_assignments(struct pci_pbm_info *pbm,
                                   struct pci_bus *pbus)
 {
-       struct pci_dev *pdev;
+       struct list_head *walk = &pbus->devices;
 
-       for (pdev = pbus->devices; pdev; pdev = pdev->sibling)
-               pdev_record_assignments(pbm, pdev);
+       for (walk = walk->next; walk != &pbus->devices; walk = walk->next)
+               pdev_record_assignments(pbm, pci_dev_b(walk));
 
-       for (pbus = pbus->children; pbus; pbus = pbus->next)
-               pci_record_assignments(pbm, pbus);
+       walk = &pbus->children;
+       for (walk = walk->next; walk != &pbus->children; walk = walk->next)
+               pci_record_assignments(pbm, pci_bus_b(walk));
 }
 
 static void __init pdev_assign_unassigned(struct pci_pbm_info *pbm,
@@ -415,13 +403,14 @@ static void __init pdev_assign_unassigned(struct pci_pbm_info *pbm,
 void __init pci_assign_unassigned(struct pci_pbm_info *pbm,
                                  struct pci_bus *pbus)
 {
-       struct pci_dev *pdev;
+       struct list_head *walk = &pbus->devices;
 
-       for (pdev = pbus->devices; pdev; pdev = pdev->sibling)
-               pdev_assign_unassigned(pbm, pdev);
+       for (walk = walk->next; walk != &pbus->devices; walk = walk->next)
+               pdev_assign_unassigned(pbm, pci_dev_b(walk));
 
-       for (pbus = pbus->children; pbus; pbus = pbus->next)
-               pci_assign_unassigned(pbm, pbus);
+       walk = &pbus->children;
+       for (walk = walk->next; walk != &pbus->children; walk = walk->next)
+               pci_assign_unassigned(pbm, pci_bus_b(walk));
 }
 
 static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt)
@@ -566,13 +555,14 @@ have_irq:
 void __init pci_fixup_irq(struct pci_pbm_info *pbm,
                          struct pci_bus *pbus)
 {
-       struct pci_dev *pdev;
+       struct list_head *walk = &pbus->devices;
 
-       for (pdev = pbus->devices; pdev; pdev = pdev->sibling)
-               pdev_fixup_irq(pdev);
+       for (walk = walk->next; walk != &pbus->devices; walk = walk->next)
+               pdev_fixup_irq(pci_dev_b(walk));
 
-       for (pbus = pbus->children; pbus; pbus = pbus->next)
-               pci_fixup_irq(pbm, pbus);
+       walk = &pbus->children;
+       for (walk = walk->next; walk != &pbus->children; walk = walk->next)
+               pci_fixup_irq(pbm, pci_bus_b(walk));
 }
 
 /* Generic helper routines for PCI error reporting. */
@@ -580,9 +570,10 @@ void pci_scan_for_target_abort(struct pci_controller_info *p,
                               struct pci_pbm_info *pbm,
                               struct pci_bus *pbus)
 {
-       struct pci_dev *pdev;
+       struct list_head *walk = &pbus->devices;
 
-       for (pdev = pbus->devices; pdev; pdev = pdev->sibling) {
+       for (walk = walk->next; walk != &pbus->devices; walk = walk->next) {
+               struct pci_dev *pdev = pci_dev_b(walk);
                u16 status, error_bits;
 
                pci_read_config_word(pdev, PCI_STATUS, &status);
@@ -597,17 +588,19 @@ void pci_scan_for_target_abort(struct pci_controller_info *p,
                }
        }
 
-       for (pbus = pbus->children; pbus; pbus = pbus->next)
-               pci_scan_for_target_abort(p, pbm, pbus);
+       walk = &pbus->children;
+       for (walk = walk->next; walk != &pbus->children; walk = walk->next)
+               pci_scan_for_target_abort(p, pbm, pci_bus_b(walk));
 }
 
 void pci_scan_for_master_abort(struct pci_controller_info *p,
                               struct pci_pbm_info *pbm,
                               struct pci_bus *pbus)
 {
-       struct pci_dev *pdev;
+       struct list_head *walk = &pbus->devices;
 
-       for (pdev = pbus->devices; pdev; pdev = pdev->sibling) {
+       for (walk = walk->next; walk != &pbus->devices; walk = walk->next) {
+               struct pci_dev *pdev = pci_dev_b(walk);
                u16 status, error_bits;
 
                pci_read_config_word(pdev, PCI_STATUS, &status);
@@ -621,17 +614,19 @@ void pci_scan_for_master_abort(struct pci_controller_info *p,
                }
        }
 
-       for (pbus = pbus->children; pbus; pbus = pbus->next)
-               pci_scan_for_master_abort(p, pbm, pbus);
+       walk = &pbus->children;
+       for (walk = walk->next; walk != &pbus->children; walk = walk->next)
+               pci_scan_for_master_abort(p, pbm, pci_bus_b(walk));
 }
 
 void pci_scan_for_parity_error(struct pci_controller_info *p,
                               struct pci_pbm_info *pbm,
                               struct pci_bus *pbus)
 {
-       struct pci_dev *pdev;
+       struct list_head *walk = &pbus->devices;
 
-       for (pdev = pbus->devices; pdev; pdev = pdev->sibling) {
+       for (walk = walk->next; walk != &pbus->devices; walk = walk->next) {
+               struct pci_dev *pdev = pci_dev_b(walk);
                u16 status, error_bits;
 
                pci_read_config_word(pdev, PCI_STATUS, &status);
@@ -646,6 +641,7 @@ void pci_scan_for_parity_error(struct pci_controller_info *p,
                }
        }
 
-       for (pbus = pbus->children; pbus; pbus = pbus->next)
-               pci_scan_for_parity_error(p, pbm, pbus);
+       walk = &pbus->children;
+       for (walk = walk->next; walk != &pbus->children; walk = walk->next)
+               pci_scan_for_parity_error(p, pbm, pci_bus_b(walk));
 }
index 3068363cc88ef59a250799023f321d7cdc9b7b1e..3788f71d3561407ad83775e2df0ff2ff1009fb39 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pci_sabre.c,v 1.7 1999/12/19 09:17:51 davem Exp $
+/* $Id: pci_sabre.c,v 1.8 2000/01/06 23:51:49 davem Exp $
  * pci_sabre.c: Sabre specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -1032,12 +1032,15 @@ static void __init sabre_base_address_update(struct pci_dev *pdev, int resource)
 
 static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus)
 {
-       struct pci_dev *pdev;
-       u16 word;
+       struct list_head *walk = &sabre_bus->devices;
+
+       for (walk = walk->next; walk != &sabre_bus->devices; walk = walk->next) {
+               struct pci_dev *pdev = pci_dev_b(walk);
 
-       for (pdev = sabre_bus->devices; pdev; pdev = pdev->sibling) {
                if (pdev->vendor == PCI_VENDOR_ID_SUN &&
                    pdev->device == PCI_DEVICE_ID_SUN_SIMBA) {
+                       u16 word;
+
                        sabre_read_word(pdev, PCI_COMMAND, &word);
                        word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
                                PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY |
@@ -1054,7 +1057,8 @@ static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre
 static void __init sabre_scan_bus(struct pci_controller_info *p)
 {
        static int once = 0;
-       struct pci_bus *sabre_bus, *pbus;
+       struct pci_bus *sabre_bus;
+       struct list_head *walk;
 
        /* Unlike for PSYCHO, we can only have one SABRE
         * in a system.  Having multiple SABREs is thus
@@ -1077,7 +1081,9 @@ static void __init sabre_scan_bus(struct pci_controller_info *p)
                                 &p->pbm_A);
        apb_init(p, sabre_bus);
 
-       for (pbus = sabre_bus->children; pbus; pbus = pbus->next) {
+       walk = &sabre_bus->children;
+       for (walk = walk->next; walk != &sabre_bus->children; walk = walk->next) {
+               struct pci_bus *pbus = pci_bus_b(walk);
                struct pci_pbm_info *pbm;
 
                if (pbus->number == p->pbm_A.pci_first_busno) {
index 86503092fd682b8ef8001c251249570de3e14b4e..811159400e399ff32953b689b44fbf573c38d6f2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.68 1999/12/17 12:32:05 jj Exp $
+/* $Id: sparc64_ksyms.c,v 1.69 2000/01/04 23:54:44 davem Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -80,6 +80,7 @@ extern int svr4_setcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
 extern int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
 extern int sys32_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
 extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
+extern long sparc32_open(const char * filename, int flags, int mode);
                 
 extern void bcopy (const char *, char *, int);
 extern int __ashrdi3(int, int);
@@ -275,6 +276,7 @@ EXPORT_SYMBOL(svr4_setcontext);
 EXPORT_SYMBOL(prom_cpu_nodes);
 EXPORT_SYMBOL(sys_ioctl);
 EXPORT_SYMBOL(sys32_ioctl);
+EXPORT_SYMBOL(sparc32_open);
 EXPORT_SYMBOL(move_addr_to_kernel);
 EXPORT_SYMBOL(move_addr_to_user);
 #endif
index 53d2d8c2d02b525242546e7722e45b7251f8fdba..486a09d9915276e9add23580a4c29350aa91b2b8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.31 1999/12/21 14:09:25 jj Exp $
+/* $Id: sys_sparc.c,v 1.32 2000/01/05 01:00:40 davem Exp $
  * linux/arch/sparc64/kernel/sys_sparc.c
  *
  * This file contains various random system calls that
index bcd978ab4c2b50b6d97c4b906c85a0b779bae04b..f9be1320ee4e9b92290546bb3c82e0812812fb1d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.126 1999/12/21 14:09:21 jj Exp $
+/* $Id: sys_sparc32.c,v 1.127 2000/01/04 23:54:41 davem Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -3999,3 +3999,37 @@ asmlinkage int sys32_adjtimex(struct timex32 *utp)
 
        return ret;
 }
+
+/* This is just a version for 32-bit applications which does
+ * not force O_LARGEFILE on.
+ */
+
+asmlinkage long sparc32_open(const char * filename, int flags, int mode)
+{
+       char * tmp;
+       int fd, error;
+
+       tmp = getname(filename);
+       fd = PTR_ERR(tmp);
+       if (!IS_ERR(tmp)) {
+               fd = get_unused_fd();
+               if (fd >= 0) {
+                       struct file * f;
+                       lock_kernel();
+                       f = filp_open(tmp, flags, mode);
+                       unlock_kernel();
+                       error = PTR_ERR(f);
+                       if (IS_ERR(f))
+                               goto out_error;
+                       fd_install(fd, f);
+               }
+out:
+               putname(tmp);
+       }
+       return fd;
+
+out_error:
+       put_unused_fd(fd);
+       fd = error;
+       goto out;
+}
index 5ce1cfb93db153246abb7479d4a8443db0934526..ffc72b74d4d9358b91568f531f276e381825aed8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos32.c,v 1.33 1999/12/15 14:24:25 davem Exp $
+/* $Id: sys_sunos32.c,v 1.35 2000/01/06 23:51:50 davem Exp $
  * sys_sunos32.c: SunOS binary compatability layer on sparc64.
  *
  * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -762,7 +762,6 @@ static int get_default (int value, int def_value)
 /* XXXXXXXXXXXXXXXXXXXX */
 asmlinkage int sunos_nfs_mount(char *dir_name, int linux_flags, void *data)
 {
-       int  ret = -ENODEV;
        int  server_fd;
        char *the_name;
        struct nfs_mount_data linux_nfs_mount;
@@ -1267,15 +1266,14 @@ asmlinkage int sunos_shmsys(int op, u32 arg1, u32 arg2, u32 arg3)
        return rval;
 }
 
-asmlinkage int sunos_open(u32 filename, int flags, int mode)
+extern asmlinkage long sparc32_open(const char * filename, int flags, int mode);
+
+asmlinkage int sunos_open(u32 fname, int flags, int mode)
 {
-       int ret;
+       const char *filename = (const char *)(long)fname;
 
-       lock_kernel();
        current->personality |= PER_BSD;
-       ret = sys_open ((char *)A(filename), flags, mode);
-       unlock_kernel();
-       return ret;
+       return sparc32_open(filename, flags, mode);
 }
 
 #define SUNOS_EWOULDBLOCK 35
index 6b2125e4454aed35f67d8def6142ed2c755d049f..27355da96dde42884a60a727fe4184a5bf29268f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.61 1999/12/21 14:09:15 jj Exp $
+/* $Id: systbls.S,v 1.62 2000/01/04 23:54:43 davem Exp $
  * systbls.S: System call entry point tables for OS compatibility.
  *            The native Linux system call table lives here also.
  *
@@ -20,7 +20,7 @@
        .globl sys_call_table32
 sys_call_table32:
 /*0*/  .word sys_nis_syscall, sparc_exit, sys_fork, sys_read, sys_write
-/*5*/  .word sys_open, sys_close, sys32_wait4, sys_creat, sys_link
+/*5*/  .word sparc32_open, sys_close, sys32_wait4, sys_creat, sys_link
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys32_chown, sys32_mknod
 /*15*/ .word sys32_chmod, sys32_lchown, sparc_brk, sys_perfctr, sys32_lseek
 /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid
index 479298a0934c217a2bd7bfa2370078fa0290e957..86b0df2831a22b179dd5f9b453818ff29d30200e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fs.c,v 1.14 1999/09/22 09:28:49 davem Exp $
+/* $Id: fs.c,v 1.15 2000/01/04 23:54:47 davem Exp $
  * fs.c: fs related syscall emulation for Solaris
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -575,20 +575,24 @@ out:
        return error;
 }
 
-asmlinkage int solaris_open(u32 filename, int flags, u32 mode)
+extern asmlinkage long sparc32_open(const char * filename, int flags, int mode);
+
+asmlinkage int solaris_open(u32 fname, int flags, u32 mode)
 {
-       int (*sys_open)(const char *,int,int) = 
-               (int (*)(const char *,int,int))SYS(open);
+       const char *filename = (const char *)(long)fname;
        int fl = flags & 0xf;
 
-/*     if (flags & 0x2000) - allow LFS                 */
+       /* Translate flags first. */
+       if (flags & 0x2000) fl |= O_LARGEFILE;
        if (flags & 0x8050) fl |= O_SYNC;
        if (flags & 0x80) fl |= O_NONBLOCK;
        if (flags & 0x100) fl |= O_CREAT;
        if (flags & 0x200) fl |= O_TRUNC;
        if (flags & 0x400) fl |= O_EXCL;
        if (flags & 0x800) fl |= O_NOCTTY;
-       return sys_open((const char *)A(filename), fl, mode);
+       flags = fl;
+
+       return sparc32_open(filename, flags, mode);
 }
 
 #define SOL_F_SETLK    6
index 0c0c1048186b3b4f10300fb16d31475b6402bd83..c47050df90b02d2331360075346fecd99dac043f 100644 (file)
@@ -98,7 +98,7 @@ else
            if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
               bool '    Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290
               if [ "$CONFIG_X86" = "y" ]; then
-                 bool '      VIA82CXXX chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82CXXX
+                 bool '    VIA82CXXX chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82CXXX
               fi
            fi
          fi
index bd5749a004cb5c36a5ef9d28f720b885ab04b629..3235466eb4672273a390c35d032afbe79557ec29 100644 (file)
@@ -570,6 +570,7 @@ static struct net_device eth0_dev = {
 extern int ibmtr_probe(struct net_device *);
 extern int olympic_probe(struct net_device *);
 extern int tms380tr_probe(struct net_device *);
+extern int smctr_probe(struct net_device *);
 
 static int
 trif_probe(struct net_device *dev)
index 5f9c727a3c1fd70ee403b5f5d08f828061f560d9..c15a1937c0178941ff4df064735296243f014a2c 100644 (file)
@@ -1,7 +1,7 @@
 /*      cops.c: LocalTalk driver for Linux.
  *
  *     Authors:
- *      - Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
+ *      - Jay Schulist <jschlst@turbolinux.com>
  *
  *     With more than a little help from;
  *     - Alan Cox <Alan.Cox@linux.org> 
@@ -33,7 +33,7 @@
  */
 
 static const char *version =
-"cops.c:v0.04 6/7/98 Jay Schulist <Jay.Schulist@spacs.k12.wi.us>\n";
+"cops.c:v0.04 6/7/98 Jay Schulist <jschlst@turbolinux.com>\n";
 /*
  *  Sources:
  *      COPS Localtalk SDK. This provides almost all of the information
index 69721566f943f5682d756c1a35e7fb371fb140fa..43863491222af7808d21dacd5370f87135ac5718 100644 (file)
@@ -1,7 +1,7 @@
 /*      cops.h: LocalTalk driver for Linux.
  *
  *      Authors:
- *      - Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
+ *      - Jay Schulist <jschlst@turbolinux.com>
  */
 
 #ifndef __LINUX_COPSLTALK_H
index 2560866dd24d0cec9ece162298991e5c6591cc36..3a20437b59a2a748c1face9589f3e07eaddc6612 100644 (file)
@@ -21,7 +21,7 @@
 /*      cops_ffdrv.h: LocalTalk driver firmware dump for Linux.
  *
  *      Authors:
- *      - Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
+ *      - Jay Schulist <jschlst@turbolinux.com>
  */
 
 #include <linux/config.h>
index 5d38fb68c8167a4daaff041689f5951084ce0726..e3e850c3148f8261d5f87376b877a04d398ecfae 100644 (file)
@@ -20,7 +20,7 @@
 /*      cops_ltdrv.h: LocalTalk driver firmware dump for Linux.
  *
  *      Authors:
- *      - Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
+ *      - Jay Schulist <jschlst@turbolinux.com>
  */
  
 #include <linux/config.h>
index 19613e8833cf73d356581df8db978fb0ead9a33e..d2bfbbbf03e9ad3e40bfd79769db4437925ba3a3 100644 (file)
@@ -2260,18 +2260,21 @@ srom_search(struct pci_dev *dev)
     u_long iobase = 0;                     /* Clear upper 32 bits in Alphas */
     int i, j;
     struct bus_type *lp = &bus;
+    struct list_head *walk = &dev->bus_list;
 
-    for (; (dev=dev->sibling)!= NULL;) {
-       pb = dev->bus->number;
-       vendor = dev->vendor;
-       device = dev->device << 8;
+    for (walk = walk->next; walk != &dev->bus_list; walk = walk->next) {
+       struct pci_dev *this_dev = pci_dev_b(walk);
+
+       pb = this_dev->bus->number;
+       vendor = this_dev->vendor;
+       device = this_dev->device << 8;
        if (!(is_DC21040 || is_DC21041 || is_DC21140 || is_DC2114x)) continue;
 
        /* Get the chip configuration revision register */
-       pcibios_read_config_dword(pb, dev->devfn, PCI_REVISION_ID, &cfrv);
+       pcibios_read_config_dword(pb, this_dev->devfn, PCI_REVISION_ID, &cfrv);
 
        /* Set the device number information */
-       lp->device = PCI_SLOT(dev->devfn);
+       lp->device = PCI_SLOT(this_dev->devfn);
        lp->bus_num = pb;
            
        /* Set the chipset information */
@@ -2281,14 +2284,14 @@ srom_search(struct pci_dev *dev)
        lp->chipset = device;
 
        /* Get the board I/O address (64 bits on sparc64) */
-       iobase = dev->resource[0].start;
+       iobase = this_dev->resource[0].start;
 
        /* Fetch the IRQ to be used */
-       irq = dev->irq;
+       irq = this_dev->irq;
        if ((irq == 0) || (irq == 0xff) || ((int)irq == -1)) continue;
            
        /* Check if I/O accesses are enabled */
-       pcibios_read_config_word(pb, dev->devfn, PCI_COMMAND, &status);
+       pcibios_read_config_word(pb, this_dev->devfn, PCI_COMMAND, &status);
        if (!(status & PCI_COMMAND_IO)) continue;
 
        /* Search for a valid SROM attached to this DECchip */
index 5e739b298f28ca88c32822d51213f750ddc3a22d..a089ed9e27c765f72c38649123bffb7e9f76e532 100644 (file)
@@ -4,7 +4,7 @@
  *
  *     Authors:
  *      - DDP-IP Encap by: Bradford W. Johnson <johns393@maroon.tc.umn.edu>
- *     - DDP-IP Decap by: Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
+ *     - DDP-IP Decap by: Jay Schulist <jschlst@turbolinux.com>
  *
  *     Derived from:
  *     - Almost all code already existed in net/appletalk/ddp.c I just
@@ -14,7 +14,7 @@
  *        Written 1993-94 by Donald Becker.
  *     - dummy.c: A dummy net driver. By Nick Holloway.
  *     - MacGate: A user space Daemon for Appletalk-IP Decap for
- *       Linux by Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
+ *       Linux by Jay Schulist <jschlst@turbolinux.com>
  *
  *      Copyright 1993 United States Government as represented by the
  *      Director, National Security Agency.
@@ -113,7 +113,7 @@ int ipddp_init(struct net_device *dev)
                printk("%s: Appletalk-IP Encap. mode by Bradford W. Johnson <johns393@maroon.tc.umn.edu>\n", 
                        dev->name);
        if(ipddp_mode == IPDDP_DECAP)
-               printk("%s: Appletalk-IP Decap. mode by Jay Schulist <Jay.Schulist@spacs.k12.wi.us>\n", 
+               printk("%s: Appletalk-IP Decap. mode by Jay Schulist <jschlst@turbolinux.com>\n", 
                        dev->name);
 
        /* Fill in the device structure with ethernet-generic values. */
index 9cb908c8538d6d2a76c8f48bb2454c445dae288e..da1df253c9f397b699f020a65a4da453cc59a928 100644 (file)
@@ -6,7 +6,7 @@ dep_tristate 'IrTTY (uses Linux serial driver)' CONFIG_IRTTY_SIR $CONFIG_IRDA
 dep_tristate 'IrPORT (IrDA serial driver)' CONFIG_IRPORT_SIR $CONFIG_IRDA
 
 comment 'FIR device drivers'
-dep_tristate 'NSC PC87108' CONFIG_NSC_FIR  $CONFIG_IRDA
+dep_tristate 'NSC PC87108/PC97338' CONFIG_NSC_FIR  $CONFIG_IRDA
 dep_tristate 'Winbond W83977AF (IR)' CONFIG_WINBOND_FIR $CONFIG_IRDA
 dep_tristate 'Toshiba Type-O IR Port' CONFIG_TOSHIBA_FIR $CONFIG_IRDA
 dep_tristate 'SMC IrCC' CONFIG_SMC_IRCC_FIR $CONFIG_IRDA
index 338fe1b293aa99df594b68c09a9353621a282987..bf5628ebd355d1c2d64fe273e23090716d6a1115 100644 (file)
@@ -29,10 +29,10 @@ else
 endif
 
 ifeq ($(CONFIG_NSC_FIR),y)
-L_OBJS += pc87108.o
+L_OBJS += nsc_fir.o
 else
   ifeq ($(CONFIG_NSC_FIR),m)
-  M_OBJS += pc87108.o
+  M_OBJS += nsc_fir.o
   endif
 endif
 
index fee2b86a19a5ce7d8a8e0a8779e2ccd899877473..e7cf517f48d9f64dd4dfc4df0acf25c8a69650c7 100644 (file)
@@ -8,7 +8,7 @@
  * Authors:       Dag Brattli <dagb@cs.uit.no> (initially)
  *               Jean Tourrilhes <jt@hpl.hp.com> (new version)
  * Created at:    Wed Oct 21 20:02:35 1998
- * Modified at:   Fri Dec 17 09:16:09 1999
+ * Modified at:   Fri Dec 17 09:10:43 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
index 27a8d6d26da5176c4890a89a686e261e2c1855ef..100b0772db13463ee55cd1ead9bd8eda24c9c644 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Feb 21 18:54:38 1998
- * Modified at:   Fri Dec 17 09:17:05 1999
+ * Modified at:   Fri Dec 17 09:14:04 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, <dagb@cs.uit.no>,
index 46dc3df6c28672d3eb91ceb1b7d572072b958696..f4aafc3249a7aa11421927a49ade945267463d41 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Feb  6 21:02:33 1999
- * Modified at:   Fri Dec 17 09:16:52 1999
+ * Modified at:   Fri Dec 17 09:13:20 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
index 2948b9d32943d4361fa87b567a2bf563e271658a..352dddecc0b0f92b8ff76bdc242a18771b91f72c 100644 (file)
@@ -6,11 +6,11 @@
  * Status:       Experimental.
  * Author:       Dag Brattli <dagb@cs.uit.no>
  * Created at:   Sun Aug  3 13:49:59 1997
- * Modified at:   Tue Dec 21 21:51:23 1999
+ * Modified at:   Wed Jan  5 13:59:38 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:      serial.c by Linus Torvalds 
  * 
- *     Copyright (c) 1997, 1998, 1999 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1997, 1998, 1999-2000 Dag Brattli, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -153,16 +153,16 @@ irport_open(int i, unsigned int iobase, unsigned int irq)
                return NULL;
        }
        memset(self, 0, sizeof(struct irport_cb));
-   
        spin_lock_init(&self->lock);
 
        /* Need to store self somewhere */
        dev_self[i] = self;
        self->priv = self;
+       self->index = i;
 
        /* Initialize IO */
-       self->io.iobase   = iobase;
-        self->io.irq      = irq;
+       self->io.iobase    = iobase;
+        self->io.irq       = irq;
         self->io.io_ext    = IO_EXTENT;
         self->io.fifo_size = 16;
 
@@ -218,6 +218,7 @@ irport_open(int i, unsigned int iobase, unsigned int irq)
                ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
                return NULL;
        }
+
        self->netdev = dev;
 
        /* May be overridden by piggyback drivers */
@@ -275,7 +276,9 @@ int irport_close(struct irport_cb *self)
        
        if (self->rx_buff.head)
                kfree(self->rx_buff.head);
-       
+
+       /* Remove ourselves */
+       dev_self[self->index] = NULL;
        kfree(self);
 
        return 0;
index 0205f0e266891b5f1bffc7ac7bde2d4c60083b6d..2ec4eba14b030e3a52640c232888c1065b5f1fb4 100644 (file)
@@ -6,12 +6,12 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Dec  9 21:18:38 1997
- * Modified at:   Tue Dec 21 21:50:59 1999
+ * Modified at:   Wed Jan  5 14:00:13 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  * 
- *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
index d42254479e1528b29fa516b0332bb2a1dda01090..7120b5647063c2de6a0fec3561508892fdfba335 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Stable
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Fri May  7 12:50:33 1999
- * Modified at:   Fri Dec 17 09:16:23 1999
+ * Modified at:   Fri Dec 17 09:14:23 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
diff --git a/drivers/net/irda/nsc_fir.c b/drivers/net/irda/nsc_fir.c
new file mode 100644 (file)
index 0000000..ce9b04b
--- /dev/null
@@ -0,0 +1,1825 @@
+/*********************************************************************
+ *                
+ * Filename:      nsc_fir.c
+ * Version:       1.0
+ * Description:   Driver for the NSC PC'108 and PC'338 IrDA chipsets
+ * Status:        Stable.
+ * Author:        Dag Brattli <dagb@cs.uit.no>
+ * Created at:    Sat Nov  7 21:43:15 1998
+ * Modified at:   Wed Jan  5 13:59:21 2000
+ * Modified by:   Dag Brattli <dagb@cs.uit.no>
+ * 
+ *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>
+ *     Copyright (c) 1998 Lichen Wang, <lwang@actisys.com>
+ *     Copyright (c) 1998 Actisys Corp., www.actisys.com
+ *     All Rights Reserved
+ *      
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version.
+ *  
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     provide warranty for any of this software. This material is 
+ *     provided "AS-IS" and at no charge.
+ *
+ *     Notice that all functions that needs to access the chip in _any_
+ *     way, must save BSR register on entry, and restore it on exit. 
+ *     It is _very_ important to follow this policy!
+ *
+ *         __u8 bank;
+ *     
+ *         bank = inb(iobase+BSR);
+ *  
+ *         do_your_stuff_here();
+ *
+ *         outb(bank, iobase+BSR);
+ *
+ *    If you find bugs in this file, its very likely that the same bug
+ *    will also be in w83977af_ir.c since the implementations are quite
+ *    similar.
+ *     
+ ********************************************************************/
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/malloc.h>
+#include <linux/init.h>
+#include <linux/rtnetlink.h>
+
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/byteorder.h>
+
+#ifdef CONFIG_APM
+#include <linux/apm_bios.h>
+#endif
+
+#include <net/irda/wrapper.h>
+#include <net/irda/irda.h>
+#include <net/irda/irmod.h>
+#include <net/irda/irlap_frame.h>
+#include <net/irda/irda_device.h>
+
+#include <net/irda/nsc_fir.h>
+
+#define CHIP_IO_EXTENT 8
+#define BROKEN_DONGLE_ID
+
+/* 
+ * Define if you have multiple NSC IrDA controllers in your machine. Not
+ * enabled by default since some single chips detects at multiple addresses
+ */
+#undef  CONFIG_NSC_FIR_MULTIPLE 
+
+static char *driver_name = "nsc_fir";
+
+/* Module parameters */
+static int qos_mtt_bits = 0x07;  /* 1 ms or more */
+static int dongle_id = 0;
+
+static unsigned int io[]  = { 0x2f8, 0x2f8, 0x2f8, 0x2f8, 0x2f8 };
+static unsigned int io2[] = { 0x150, 0x398, 0xea, 0x15c, 0x2e };
+static unsigned int irq[] = { 3, 3, 3, 3, 3 };
+static unsigned int dma[] = { 0, 0, 0, 0, 3 };
+
+static struct nsc_fir_cb *dev_self[] = { NULL, NULL, NULL, NULL, NULL };
+
+static char *dongle_types[] = {
+       "Differential serial interface",
+       "Differential serial interface",
+       "Reserved",
+       "Reserved",
+       "Sharp RY5HD01",
+       "Reserved",
+       "Single-ended serial interface",
+       "Consumer-IR only",
+       "HP HSDL-2300, HP HSDL-3600/HSDL-3610",
+       "IBM31T1100 or Temic TFDS6000/TFDS6500",
+       "Reserved",
+       "Reserved",
+       "HP HSDL-1100/HSDL-2100",
+       "HP HSDL-1100/HSDL-2100"
+       "Supports SIR Mode only",
+       "No dongle connected",
+};
+
+/* Some prototypes */
+static int  nsc_fir_open(int i, unsigned int iobase, unsigned int board_addr, 
+                        unsigned int irq, unsigned int dma);
+#ifdef MODULE
+static int  nsc_fir_close(struct nsc_fir_cb *self);
+#endif /* MODULE */
+static int  nsc_fir_probe(int iobase, int board_addr, int irq, int dma);
+static void nsc_fir_pio_receive(struct nsc_fir_cb *self);
+static int  nsc_fir_dma_receive(struct nsc_fir_cb *self); 
+static int  nsc_fir_dma_receive_complete(struct nsc_fir_cb *self, int iobase);
+static int  nsc_fir_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev);
+static int  nsc_fir_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev);
+static int  nsc_fir_pio_write(int iobase, __u8 *buf, int len, int fifo_size);
+static void nsc_fir_dma_xmit(struct nsc_fir_cb *self, int iobase);
+static void nsc_fir_change_speed(struct nsc_fir_cb *self, __u32 baud);
+static void nsc_fir_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static int  nsc_fir_is_receiving(struct nsc_fir_cb *self);
+static int  nsc_fir_read_dongle_id (int iobase);
+static void nsc_fir_init_dongle_interface (int iobase, int dongle_id);
+
+static int  nsc_fir_net_init(struct net_device *dev);
+static int  nsc_fir_net_open(struct net_device *dev);
+static int  nsc_fir_net_close(struct net_device *dev);
+static int  nsc_fir_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static struct net_device_stats *nsc_fir_net_get_stats(struct net_device *dev);
+#ifdef CONFIG_APM
+static int nsc_fir_apmproc(apm_event_t event);
+#endif /* CONFIG_APM */
+/*
+ * Function nsc_fir_init ()
+ *
+ *    Initialize chip. Just try to find out how many chips we are dealing with
+ *    and where they are
+ */
+int __init nsc_fir_init(void)
+{
+       int ret = -ENODEV;
+       int ioaddr;
+       int i;
+
+#ifdef CONFIG_APM
+       apm_register_callback(nsc_fir_apmproc);
+#endif /* CONFIG_APM */
+
+       for (i=0; (io[i] < 2000) && (i < 5); i++) {
+               ioaddr = io[i];
+               if (check_region(ioaddr, CHIP_IO_EXTENT) < 0)
+                       continue;
+               if (nsc_fir_open(i, io[i], io2[i], irq[i], dma[i]) == 0)
+               {
+#ifdef CONFIG_NSC_FIR_MULTIPLE
+                       ret = 0;
+#else
+                       return 0;
+#endif
+               }
+       }
+
+       return ret;
+}
+
+/*
+ * Function nsc_fir_cleanup ()
+ *
+ *    Close all configured chips
+ *
+ */
+#ifdef MODULE
+static void nsc_fir_cleanup(void)
+{
+       int i;
+
+        IRDA_DEBUG(4, __FUNCTION__ "()\n");
+
+#ifdef CONFIG_APM
+       apm_unregister_callback(nsc_fir_apmproc);
+#endif /* CONFIG_APM */
+
+
+       for (i=0; i < 5; i++) {
+               if (dev_self[i])
+                       nsc_fir_close(dev_self[i]);
+       }
+}
+#endif /* MODULE */
+
+/*
+ * Function nsc_fir_open (iobase, irq)
+ *
+ *    Open driver instance
+ *
+ */
+static int 
+nsc_fir_open(int i, unsigned int iobase, unsigned int board_addr, 
+            unsigned int irq, unsigned int dma)
+{
+       struct net_device *dev;
+       struct nsc_fir_cb *self;
+       int dongle_id;
+       int ret;
+       int err;
+
+       IRDA_DEBUG(2, __FUNCTION__ "()\n");
+
+       if ((dongle_id = nsc_fir_probe(iobase, board_addr, irq, dma)) == -1)
+               return -1;
+
+       /*
+        *  Allocate new instance of the driver
+        */
+       self = kmalloc(sizeof(struct nsc_fir_cb), GFP_KERNEL);
+       if (self == NULL) {
+               ERROR(__FUNCTION__ "(), can't allocate memory for "
+                      "control block!\n");
+               return -ENOMEM;
+       }
+       memset(self, 0, sizeof(struct nsc_fir_cb));
+       spin_lock_init(&self->lock);
+   
+       /* Need to store self somewhere */
+       dev_self[i] = self;
+
+       /* Initialize IO */
+       self->io.iobase    = iobase;
+        self->io.irq       = irq;
+        self->io.io_ext    = CHIP_IO_EXTENT;
+        self->io.dma       = dma;
+        self->io.fifo_size = 32;
+
+       /* Lock the port that we need */
+       ret = check_region(self->io.iobase, self->io.io_ext);
+       if (ret < 0) { 
+               IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
+                     self->io.iobase);
+               /* nsc_fir_cleanup(self->self);  */
+               return -ENODEV;
+       }
+       request_region(self->io.iobase, self->io.io_ext, driver_name);
+
+       /* Initialize QoS for this device */
+       irda_init_max_qos_capabilies(&self->qos);
+       
+       /* The only value we must override it the baudrate */
+       self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
+               IR_115200|IR_576000|IR_1152000 |(IR_4000000 << 8);
+       
+       self->qos.min_turn_time.bits = qos_mtt_bits;
+       irda_qos_bits_to_value(&self->qos);
+       
+       self->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO|IFF_DONGLE;
+
+       /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
+       self->rx_buff.truesize = 14384; 
+       self->tx_buff.truesize = 14384;
+
+       /* Allocate memory if needed */
+       self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
+                                             GFP_KERNEL|GFP_DMA);
+       if (self->rx_buff.head == NULL)
+               return -ENOMEM;
+       memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+       
+       self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
+                                             GFP_KERNEL|GFP_DMA);
+       if (self->tx_buff.head == NULL) {
+               kfree(self->rx_buff.head);
+               return -ENOMEM;
+       }
+       memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+
+       self->rx_buff.in_frame = FALSE;
+       self->rx_buff.state = OUTSIDE_FRAME;
+       self->tx_buff.data = self->tx_buff.head;
+       self->rx_buff.data = self->rx_buff.head;
+       
+       /* Reset Tx queue info */
+       self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+       self->tx_fifo.tail = self->tx_buff.head;
+
+       if (!(dev = dev_alloc("irda%d", &err))) {
+               ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
+               return -ENOMEM;
+       }
+
+       dev->priv = (void *) self;
+       self->netdev = dev;
+
+       /* Override the network functions we need to use */
+       dev->init            = nsc_fir_net_init;
+       dev->hard_start_xmit = nsc_fir_hard_xmit_sir;
+       dev->open            = nsc_fir_net_open;
+       dev->stop            = nsc_fir_net_close;
+       dev->do_ioctl        = nsc_fir_net_ioctl;
+       dev->get_stats       = nsc_fir_net_get_stats;
+
+       rtnl_lock();
+       err = register_netdevice(dev);
+       rtnl_unlock();
+       if (err) {
+               ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
+               return -1;
+       }
+
+       MESSAGE("IrDA: Registered device %s\n", dev->name);
+       
+       self->io.dongle_id = dongle_id;
+       nsc_fir_init_dongle_interface(iobase, dongle_id);
+
+       return 0;
+}
+
+#ifdef MODULE
+/*
+ * Function nsc_fir_close (self)
+ *
+ *    Close driver instance
+ *
+ */
+static int nsc_fir_close(struct nsc_fir_cb *self)
+{
+       int iobase;
+
+       IRDA_DEBUG(4, __FUNCTION__ "()\n");
+
+       ASSERT(self != NULL, return -1;);
+
+        iobase = self->io.iobase;
+
+       /* Remove netdevice */
+       if (self->netdev) {
+               rtnl_lock();
+               unregister_netdevice(self->netdev);
+               rtnl_unlock();
+       }
+
+       /* Release the PORT that this driver is using */
+       IRDA_DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", 
+                  self->io.iobase);
+       release_region(self->io.iobase, self->io.io_ext);
+
+       if (self->tx_buff.head)
+               kfree(self->tx_buff.head);
+       
+       if (self->rx_buff.head)
+               kfree(self->rx_buff.head);
+
+       kfree(self);
+
+       return 0;
+}
+#endif /* MODULE */
+
+/*
+ * Function nsc_fir_init_807 (iobase, board_addr, irq, dma)
+ *
+ *    Initialize the NSC '108 chip
+ *
+ */
+static void nsc_fir_init_807(int iobase, int board_addr, int irq, int dma)
+{
+       __u8 temp=0;
+
+       outb(2, board_addr);      /* Mode Control Register (MCTL) */
+       outb(0x00, board_addr+1); /* Disable device */
+       
+       /* Base Address and Interrupt Control Register (BAIC) */
+       outb(0, board_addr);
+       switch (iobase) {
+       case 0x3e8: outb(0x14, board_addr+1); break;
+       case 0x2e8: outb(0x15, board_addr+1); break;
+               case 0x3f8: outb(0x16, board_addr+1); break;
+       case 0x2f8: outb(0x17, board_addr+1); break;
+       default: ERROR(__FUNCTION__ "(), invalid base_address");
+       }
+       
+       /* Control Signal Routing Register (CSRT) */
+       switch (irq) {
+       case 3:  temp = 0x01; break;
+       case 4:  temp = 0x02; break;
+       case 5:  temp = 0x03; break;
+       case 7:  temp = 0x04; break;
+       case 9:  temp = 0x05; break;
+       case 11: temp = 0x06; break;
+       case 15: temp = 0x07; break;
+       default: ERROR(__FUNCTION__ "(), invalid irq");
+       }
+       outb(1, board_addr);
+       
+       switch (dma) {  
+       case 0: outb(0x08+temp, board_addr+1); break;
+       case 1: outb(0x10+temp, board_addr+1); break;
+       case 3: outb(0x18+temp, board_addr+1); break;
+       default: ERROR(__FUNCTION__ "(), invalid dma");
+       }
+       
+       outb(2, board_addr);      /* Mode Control Register (MCTL) */
+       outb(0x03, board_addr+1); /* Enable device */
+}
+
+/*
+ * Function nsc_fir_init_338 (iobase, board_addr, irq, dma)
+ *
+ *    Initialize the NSC '338 chip. Remember that the 87338 needs two 
+ *    consecutive writes to the data registers while CPU interrupts are
+ *    disabled. The 97338 does not require this, but shouldn't be any
+ *    harm if we do it anyway.
+ */
+static void nsc_fir_init_338(int iobase, int board_addr, int irq, int dma)
+{
+       /* No init yet */
+}
+
+static int nsc_fir_find_chip(int board_addr)
+{
+       __u8 index, id;
+
+       IRDA_DEBUG(4, __FUNCTION__ "()\n");
+
+       /* Read index register */
+       index = inb(board_addr);
+       if (index == 0xff) {
+               IRDA_DEBUG(0, __FUNCTION__ "(), no chip at 0x%03x\n", 
+                          board_addr);
+               return -1;
+       }
+
+       /* Read chip identification register (SID) for the PC97338 */
+       outb(8, board_addr);
+       id = inb(board_addr+1);
+       if ((id & 0xf0) == PC97338) {
+               MESSAGE("%s, Found NSC PC97338 chip, revision=%d\n", 
+                       driver_name, id & 0x0f);
+               return PC97338;         
+       } 
+
+       /* Read device identification (DID) for the PC87108 */
+       outb(5, board_addr);
+       id = inb(board_addr+1);
+       if ((id & 0xf0) == PC87108) {
+               MESSAGE("%s, Found NSC PC87108 chip, revision=%d\n", 
+                       driver_name, id & 0x0f);
+               return PC87108;
+       }
+
+       return -1;
+}
+
+/*
+ * Function nsc_fir_probe (iobase, board_addr, irq, dma)
+ *
+ *    Returns non-negative on success.
+ *
+ */
+static int nsc_fir_probe(int iobase, int board_addr, int irq, int dma)
+{
+       int version;
+       __u8 chip;
+
+       chip = nsc_fir_find_chip(board_addr);
+       switch (chip) {
+       case PC87108:
+               nsc_fir_init_807(iobase, board_addr, irq, dma);
+               break;
+       case PC97338:
+               nsc_fir_init_338(iobase, board_addr, irq, dma);
+               break;
+       default:
+               /* Found no chip */
+               return -1;
+       }
+
+       /* Read the Module ID */
+       switch_bank(iobase, BANK3);
+       version = inb(iobase+MID);
+
+       /* Should be 0x2? */
+       if (0x20 != (version & 0xf0)) {
+               ERROR("%s, Wrong chip version %02x\n", driver_name, version);
+               return -1;
+       }
+       MESSAGE("%s, Found chip at base=0x%04x\n", driver_name, board_addr);
+
+       /* Switch to advanced mode */
+       switch_bank(iobase, BANK2);
+       outb(ECR1_EXT_SL, iobase+ECR1);
+       switch_bank(iobase, BANK0);
+
+       /* Check if user has supplied the dongle id or not */
+       if (!dongle_id) {
+               dongle_id = nsc_fir_read_dongle_id(iobase);
+               
+               MESSAGE("%s, Found dongle: %s\n", driver_name,
+                       dongle_types[dongle_id]);
+       } else {
+               MESSAGE("%s, Using dongle: %s\n", driver_name,
+                       dongle_types[dongle_id]);
+       }
+       
+       /* Set FIFO threshold to TX17, RX16, reset and enable FIFO's */
+       switch_bank(iobase, BANK0);     
+       outb(FCR_RXTH|FCR_TXTH|FCR_TXSR|FCR_RXSR|FCR_FIFO_EN, iobase+FCR);
+       
+       /* Set FIFO size to 32 */
+       switch_bank(iobase, BANK2);
+       outb(EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2);
+
+       /* IRCR2: FEND_MD is set */
+       switch_bank(iobase, BANK5);
+       outb(0x2a, iobase+4);
+
+       /* Make sure that some defaults are OK */
+       switch_bank(iobase, BANK6);
+       outb(0x20, iobase+0); /* Set 32 bits FIR CRC */
+       outb(0x0a, iobase+1); /* Set MIR pulse width */
+       outb(0x0d, iobase+2); /* Set SIR pulse width */
+       outb(0x2a, iobase+4); /* Set beginning frag, and preamble length */
+
+       MESSAGE("%s, driver loaded (Dag Brattli)\n", driver_name);
+
+       /* Enable receive interrupts */
+       switch_bank(iobase, BANK0);
+       outb(IER_RXHDL_IE, iobase+IER);
+
+       return dongle_id;
+}
+
+/*
+ * Function nsc_fir_read_dongle_id (void)
+ *
+ * Try to read dongle indentification. This procedure needs to be executed
+ * once after power-on/reset. It also needs to be used whenever you suspect
+ * that the user may have plugged/unplugged the IrDA Dongle.
+ * 
+ */
+static int nsc_fir_read_dongle_id (int iobase)
+{
+       int dongle_id;
+       __u8 bank;
+
+       IRDA_DEBUG(4, __FUNCTION__ "()\n");
+
+       bank = inb(iobase+BSR);
+
+       /* Select Bank 7 */
+       switch_bank(iobase, BANK7);
+       
+       /* IRCFG4: IRSL0_DS and IRSL21_DS are cleared */
+       outb(0x00, iobase+7);
+       
+       /* ID0, 1, and 2 are pulled up/down very slowly */
+       udelay(50);
+       
+       /* IRCFG1: read the ID bits */
+       dongle_id = inb(iobase+4) & 0x0f;
+
+#ifdef BROKEN_DONGLE_ID
+       if (dongle_id == 0x0a)
+               dongle_id = 0x09;
+#endif
+       
+       /* Go back to  bank 0 before returning */
+       switch_bank(iobase, BANK0);
+
+       outb(bank, iobase+BSR);
+
+       return dongle_id;
+}
+
+/*
+ * Function nsc_fir_init_dongle_interface (iobase, dongle_id)
+ *
+ *     This function initializes the dongle for the transceiver that is
+ *     used. This procedure needs to be executed once after
+ *     power-on/reset. It also needs to be used whenever you suspect that
+ *     the dongle is changed. 
+ */
+static void nsc_fir_init_dongle_interface (int iobase, int dongle_id)
+{
+       int bank;
+
+       /* Save current bank */
+       bank = inb(iobase+BSR);
+
+       /* Select Bank 7 */
+       switch_bank(iobase, BANK7);
+       
+       /* IRCFG4: set according to dongle_id */
+       switch (dongle_id) {
+       case 0x00: /* same as */
+       case 0x01: /* Differential serial interface */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x02: /* same as */
+       case 0x03: /* Reserved */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x04: /* Sharp RY5HD01 */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x05: /* Reserved, but this is what the Thinkpad reports */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x06: /* Single-ended serial interface */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x07: /* Consumer-IR only */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s is not for IrDA mode\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x08: /* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x09: /* IBM31T1100 or Temic TFDS6000/TFDS6500 */
+               outb_p(0x28, iobase+7); /* Set irsl[0-2] as output */
+               break;
+       case 0x0A: /* same as */
+       case 0x0B: /* Reserved */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x0C: /* same as */
+       case 0x0D: /* HP HSDL-1100/HSDL-2100 */
+               /* 
+                * Set irsl0 as input, irsl[1-2] as output, and separate 
+                * inputs are used for SIR and MIR/FIR 
+                */
+               outb(0x48, iobase+7); 
+               break;
+       case 0x0E: /* Supports SIR Mode only */
+               outb(0x28, iobase+7); /* Set irsl[0-2] as output */
+               break;
+       case 0x0F: /* No dongle connected */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s\n",
+                          dongle_types[dongle_id]); 
+
+               switch_bank(iobase, BANK0);
+               outb(0x62, iobase+MCR);
+               break;
+       default: 
+               IRDA_DEBUG(0, __FUNCTION__ "(), invalid dongle_id %#x", 
+                          dongle_id);
+       }
+       
+       /* IRCFG1: IRSL1 and 2 are set to IrDA mode */
+       outb(0x00, iobase+4);
+
+       /* Restore bank register */
+       outb(bank, iobase+BSR);
+       
+} /* set_up_dongle_interface */
+
+/*
+ * Function nsc_fir_change_dongle_speed (iobase, speed, dongle_id)
+ *
+ *    Change speed of the attach dongle
+ *
+ */
+static void nsc_fir_change_dongle_speed(int iobase, int speed, int dongle_id)
+{
+       unsigned long flags;
+       __u8 bank;
+
+       IRDA_DEBUG(4, __FUNCTION__ "()\n");
+
+       /* Save current bank */
+       bank = inb(iobase+BSR);
+
+       /* Select Bank 7 */
+       switch_bank(iobase, BANK7);
+       
+       /* IRCFG1: set according to dongle_id */
+       switch (dongle_id) {
+       case 0x00: /* same as */
+       case 0x01: /* Differential serial interface */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x02: /* same as */
+       case 0x03: /* Reserved */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x04: /* Sharp RY5HD01 */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n",
+                          dongle_types[dongle_id]); 
+       case 0x05: /* Reserved */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x06: /* Single-ended serial interface */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x07: /* Consumer-IR only */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s is not for IrDA mode\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x08: /* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n",
+                          dongle_types[dongle_id]); 
+       case 0x09: /* IBM31T1100 or Temic TFDS6000/TFDS6500 */
+               switch_bank(iobase, BANK7);
+               outb_p(0x01, iobase+4);
+
+               if (speed == 4000000) {
+                       save_flags(flags);
+                       cli();
+                       outb(0x81, iobase+4);
+                       outb(0x80, iobase+4);
+                       restore_flags(flags);
+               } else
+                       outb_p(0x00, iobase+4);
+               break;
+       case 0x0A: /* same as */
+       case 0x0B: /* Reserved */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
+                          dongle_types[dongle_id]); 
+               break;
+       case 0x0C: /* same as */
+       case 0x0D: /* HP HSDL-1100/HSDL-2100 */
+               break;
+       case 0x0E: /* Supports SIR Mode only */
+               break;
+       case 0x0F: /* No dongle connected */
+               IRDA_DEBUG(0, __FUNCTION__ "(), %s is not for IrDA mode\n",
+                          dongle_types[dongle_id]);
+
+               switch_bank(iobase, BANK0); 
+               outb(0x62, iobase+MCR);
+               break;
+       default: 
+               IRDA_DEBUG(0, __FUNCTION__ "(), invalid data_rate\n");
+       }
+       /* Restore bank register */
+       outb(bank, iobase+BSR);
+}
+
+/*
+ * Function nsc_fir_change_speed (self, baud)
+ *
+ *    Change the speed of the device
+ *
+ */
+static void nsc_fir_change_speed(struct nsc_fir_cb *self, __u32 speed)
+{
+       struct net_device *dev = self->netdev;
+       __u8 mcr = MCR_SIR;
+       int iobase; 
+       __u8 bank;
+
+       IRDA_DEBUG(2, __FUNCTION__ "(), speed=%d\n", speed);
+
+       ASSERT(self != NULL, return;);
+
+       iobase = self->io.iobase;
+
+       /* Update accounting for new speed */
+       self->io.speed = speed;
+
+       /* Save current bank */
+       bank = inb(iobase+BSR);
+
+       /* Disable interrupts */
+       switch_bank(iobase, BANK0);
+       outb(0, iobase+IER);
+
+       /* Select Bank 2 */
+       switch_bank(iobase, BANK2);
+
+       outb(0x00, iobase+BGDH);
+       switch (speed) {
+       case 9600:   outb(0x0c, iobase+BGDL); break;
+       case 19200:  outb(0x06, iobase+BGDL); break;
+       case 38400:  outb(0x03, iobase+BGDL); break;
+       case 57600:  outb(0x02, iobase+BGDL); break;
+       case 115200: outb(0x01, iobase+BGDL); break;
+       case 576000:
+               switch_bank(iobase, BANK5);
+               
+               /* IRCR2: MDRS is set */
+               outb(inb(iobase+4) | 0x04, iobase+4);
+              
+               mcr = MCR_MIR;
+               IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n");
+               break;
+       case 1152000:
+               mcr = MCR_MIR;
+               IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n");
+               break;
+       case 4000000:
+               mcr = MCR_FIR;
+               IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n");
+               break;
+       default:
+               mcr = MCR_FIR;
+               IRDA_DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", 
+                          speed);
+               break;
+       }
+
+       /* Set appropriate speed mode */
+       switch_bank(iobase, BANK0);
+       outb(mcr | MCR_TX_DFR, iobase+MCR);
+
+       /* Give some hits to the transceiver */
+       nsc_fir_change_dongle_speed(iobase, speed, self->io.dongle_id);
+
+       /* Set FIFO threshold to TX17, RX16 */
+       switch_bank(iobase, BANK0);
+       outb(0x00, iobase+FCR);
+       outb(FCR_FIFO_EN, iobase+FCR);
+       outb(FCR_RXTH|     /* Set Rx FIFO threshold */
+            FCR_TXTH|     /* Set Tx FIFO threshold */
+            FCR_TXSR|     /* Reset Tx FIFO */
+            FCR_RXSR|     /* Reset Rx FIFO */
+            FCR_FIFO_EN,  /* Enable FIFOs */
+            iobase+FCR);
+       
+       /* Set FIFO size to 32 */
+       switch_bank(iobase, BANK2);
+       outb(EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2);
+       
+       self->netdev->tbusy = 0;
+       
+       /* Enable some interrupts so we can receive frames */
+       switch_bank(iobase, BANK0); 
+       if (speed > 115200) {
+               /* Install FIR xmit handler */
+               dev->hard_start_xmit = nsc_fir_hard_xmit_fir;
+               outb(IER_SFIF_IE, iobase+IER);
+               nsc_fir_dma_receive(self);
+       } else {
+               /* Install SIR xmit handler */
+               dev->hard_start_xmit = nsc_fir_hard_xmit_sir;
+               outb(IER_RXHDL_IE, iobase+IER);
+       }
+       
+       /* Restore BSR */
+       outb(bank, iobase+BSR);
+}
+
+/*
+ * Function nsc_fir_hard_xmit (skb, dev)
+ *
+ *    Transmit the frame!
+ *
+ */
+static int nsc_fir_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
+{
+       struct nsc_fir_cb *self;
+       unsigned long flags;
+       int iobase;
+       __u32 speed;
+       __u8 bank;
+       
+       self = (struct nsc_fir_cb *) dev->priv;
+
+       ASSERT(self != NULL, return 0;);
+
+       iobase = self->io.iobase;
+
+       /* Lock transmit buffer */
+       if (irda_lock((void *) &dev->tbusy) == FALSE)
+               return -EBUSY;
+       
+       /* Check if we need to change the speed */
+       if ((speed = irda_get_speed(skb)) != self->io.speed)
+               self->new_speed = speed;
+       
+       spin_lock_irqsave(&self->lock, flags);
+       
+       /* Save current bank */
+       bank = inb(iobase+BSR);
+       
+       self->tx_buff.data = self->tx_buff.head;
+       
+       self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, 
+                                          self->tx_buff.truesize);
+       
+       /* Add interrupt on tx low level (will fire immediately) */
+       switch_bank(iobase, BANK0);
+       outb(IER_TXLDL_IE, iobase+IER);
+       
+       /* Restore bank register */
+       outb(bank, iobase+BSR);
+
+       spin_unlock_irqrestore(&self->lock, flags);
+
+       dev_kfree_skb(skb);
+
+       return 0;
+}
+
+static int nsc_fir_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
+{
+       struct nsc_fir_cb *self;
+       unsigned long flags;
+       int iobase;
+       __u32 speed;
+       __u8 bank;
+       int mtt, diff;
+       
+       self = (struct nsc_fir_cb *) dev->priv;
+
+       ASSERT(self != NULL, return 0;);
+
+       iobase = self->io.iobase;
+
+       /* Lock transmit buffer */
+       if (irda_lock((void *) &dev->tbusy) == FALSE)
+               return -EBUSY;
+
+       /* Check if we need to change the speed */
+       if ((speed = irda_get_speed(skb)) != self->io.speed)
+               self->new_speed = speed;
+
+       spin_lock_irqsave(&self->lock, flags);
+
+       /* Save current bank */
+       bank = inb(iobase+BSR);
+
+       /* Register and copy this frame to DMA memory */
+       self->tx_fifo.queue[self->tx_fifo.free].start = self->tx_fifo.tail;
+       self->tx_fifo.queue[self->tx_fifo.free].len = skb->len;
+       self->tx_fifo.tail += skb->len;
+
+       memcpy(self->tx_fifo.queue[self->tx_fifo.free].start, skb->data, 
+              skb->len);
+       
+       self->tx_fifo.len++;
+       self->tx_fifo.free++;
+
+       /* Start transmit only if there is currently no transmit going on */
+       if (self->tx_fifo.len == 1) {
+               mtt = irda_get_mtt(skb);
+               if (mtt) {
+                       /* Check how much time we have used already */
+                       do_gettimeofday(&self->now);
+                       diff = self->now.tv_usec - self->stamp.tv_usec;
+                       if (diff < 0) 
+                               diff += 1000000;
+                       
+                       /* Check if the mtt is larger than the time we have
+                        * already used by all the protocol processing
+                        */
+                       if (mtt > diff) {
+                               mtt -= diff;
+                               if (mtt > 125) {
+                                       /* Adjust for timer resolution */
+                                       mtt = mtt / 125 + 1;
+                                       
+                                       /* Setup timer */
+                                       switch_bank(iobase, BANK4);
+                                       outb(mtt & 0xff, iobase+TMRL);
+                                       outb((mtt >> 8) & 0x0f, iobase+TMRH);
+                                       
+                                       /* Start timer */
+                                       outb(IRCR1_TMR_EN, iobase+IRCR1);
+                                       self->io.direction = IO_XMIT;
+                                       
+                                       /* Enable timer interrupt */
+                                       switch_bank(iobase, BANK0);
+                                       outb(IER_TMR_IE, iobase+IER);
+                                       
+                                       /* Timer will take care of the rest */
+                                       goto out; 
+                               } else
+                                       udelay(mtt);
+                       }
+               }
+               
+               /* Enable DMA interrupt */
+               switch_bank(iobase, BANK0);
+               outb(IER_DMA_IE, iobase+IER);
+               nsc_fir_dma_xmit(self, iobase);
+       }
+       /* Not busy transmitting anymore if window is not full */
+       if (self->tx_fifo.len < MAX_WINDOW)
+               dev->tbusy = 0;
+ out:
+       /* Restore bank register */
+       outb(bank, iobase+BSR);
+
+       spin_unlock_irqrestore(&self->lock, flags);
+
+       dev_kfree_skb(skb);
+
+       return 0;
+}
+
+/*
+ * Function nsc_fir_dma_xmit (self, iobase)
+ *
+ *    Transmit data using DMA
+ *
+ */
+static void nsc_fir_dma_xmit(struct nsc_fir_cb *self, int iobase)
+{
+       int bsr;
+
+       /* Save current bank */
+       bsr = inb(iobase+BSR);
+
+       /* Disable DMA */
+       switch_bank(iobase, BANK0);
+       outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR);
+       
+       self->io.direction = IO_XMIT;
+       
+       /* Choose transmit DMA channel  */ 
+       switch_bank(iobase, BANK2);
+       outb(ECR1_DMASWP|ECR1_DMANF|ECR1_EXT_SL, iobase+ECR1);
+       
+       setup_dma(self->io.dma, 
+                 self->tx_fifo.queue[self->tx_fifo.ptr].start, 
+                 self->tx_fifo.queue[self->tx_fifo.ptr].len, 
+                 DMA_TX_MODE);
+
+       /* Enable DMA and SIR interaction pulse */
+       switch_bank(iobase, BANK0);     
+       outb(inb(iobase+MCR)|MCR_TX_DFR|MCR_DMA_EN|MCR_IR_PLS, iobase+MCR);
+
+       /* Restore bank register */
+       outb(bsr, iobase+BSR);
+}
+
+/*
+ * Function nsc_fir_pio_xmit (self, iobase)
+ *
+ *    Transmit data using PIO. Returns the number of bytes that actually
+ *    got transfered
+ *
+ */
+static int nsc_fir_pio_write(int iobase, __u8 *buf, int len, int fifo_size)
+{
+       int actual = 0;
+       __u8 bank;
+       
+       IRDA_DEBUG(4, __FUNCTION__ "()\n");
+
+       /* Save current bank */
+       bank = inb(iobase+BSR);
+
+       switch_bank(iobase, BANK0);
+       if (!(inb_p(iobase+LSR) & LSR_TXEMP)) {
+               IRDA_DEBUG(4, __FUNCTION__ 
+                          "(), warning, FIFO not empty yet!\n");
+
+               fifo_size -= 17;
+       }
+
+       /* Fill FIFO with current frame */
+       while ((fifo_size-- > 0) && (actual < len)) {
+               /* Transmit next byte */
+               outb(buf[actual++], iobase+TXD);
+       }
+        
+       IRDA_DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", 
+                  fifo_size, actual, len);
+       
+       /* Restore bank */
+       outb(bank, iobase+BSR);
+
+       return actual;
+}
+
+/*
+ * Function nsc_fir_dma_xmit_complete (self)
+ *
+ *    The transfer of a frame in finished. This function will only be called 
+ *    by the interrupt handler
+ *
+ */
+static int nsc_fir_dma_xmit_complete(struct nsc_fir_cb *self)
+{
+       int iobase;
+       __u8 bank;
+       int ret = TRUE;
+
+       IRDA_DEBUG(2, __FUNCTION__ "()\n");
+
+       iobase = self->io.iobase;
+
+       /* Save current bank */
+       bank = inb(iobase+BSR);
+
+       /* Disable DMA */
+       switch_bank(iobase, BANK0);
+        outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR);
+       
+       /* Check for underrrun! */
+       if (inb(iobase+ASCR) & ASCR_TXUR) {
+               self->stats.tx_errors++;
+               self->stats.tx_fifo_errors++;
+               
+               /* Clear bit, by writing 1 into it */
+               outb(ASCR_TXUR, iobase+ASCR);
+       } else {
+               self->stats.tx_packets++;
+               self->stats.tx_bytes += self->tx_buff.len;
+       }
+       
+       if (self->new_speed) {
+               nsc_fir_change_speed(self, self->new_speed);
+               self->new_speed = 0;
+       }
+
+       /* Finished with this frame, so prepare for next */
+       self->tx_fifo.ptr++;
+       self->tx_fifo.len--;
+
+       /* Any frames to be sent back-to-back? */
+       if (self->tx_fifo.len) {
+               nsc_fir_dma_xmit(self, iobase);
+               
+               /* Not finished yet! */
+               ret = FALSE;
+       }
+
+       /* Not busy transmitting anymore */
+       self->netdev->tbusy = 0;
+
+       /* Tell the network layer, that we can accept more frames */
+       mark_bh(NET_BH);
+
+       /* Restore bank */
+       outb(bank, iobase+BSR);
+       
+       return ret;
+}
+
+/*
+ * Function nsc_fir_dma_receive (self)
+ *
+ *    Get ready for receiving a frame. The device will initiate a DMA
+ *    if it starts to receive a frame.
+ *
+ */
+static int nsc_fir_dma_receive(struct nsc_fir_cb *self) 
+{
+       int iobase;
+       __u8 bsr;
+
+       ASSERT(self != NULL, return -1;);
+
+       iobase = self->io.iobase;
+
+       /* Reset Tx FIFO info */
+       self->tx_fifo.len = self->tx_fifo.ptr = self->tx_fifo.free = 0;
+       self->tx_fifo.tail = self->tx_buff.head;
+
+       /* Save current bank */
+       bsr = inb(iobase+BSR);
+
+       /* Disable DMA */
+       switch_bank(iobase, BANK0);
+       outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR);
+
+       /* Choose DMA Rx, DMA Fairness, and Advanced mode */
+       switch_bank(iobase, BANK2);
+       outb(ECR1_DMANF|ECR1_EXT_SL, iobase+ECR1);
+
+       self->io.direction = IO_RECV;
+       self->rx_buff.data = self->rx_buff.head;
+       
+       /* Reset Rx FIFO. This will also flush the ST_FIFO */
+       switch_bank(iobase, BANK0);
+       outb(FCR_RXSR|FCR_FIFO_EN, iobase+FCR);
+       self->st_fifo.len = self->st_fifo.tail = self->st_fifo.head = 0;
+       
+       setup_dma(self->io.dma, self->rx_buff.data, self->rx_buff.truesize, 
+                 DMA_RX_MODE);
+
+       /* Enable DMA */
+       switch_bank(iobase, BANK0);
+       outb(inb(iobase+MCR)|MCR_DMA_EN, iobase+MCR);
+
+       /* Restore bank register */
+       outb(bsr, iobase+BSR);
+       
+       return 0;
+}
+
+/*
+ * Function nsc_fir_dma_receive_complete (self)
+ *
+ *    Finished with receiving frames
+ *
+ *    
+ */
+static int nsc_fir_dma_receive_complete(struct nsc_fir_cb *self, int iobase)
+{
+       struct sk_buff *skb;
+       struct st_fifo *st_fifo;
+       __u8 bank;
+       __u8 status;
+       int len;
+
+       st_fifo = &self->st_fifo;
+
+       /* Save current bank */
+       bank = inb(iobase+BSR);
+       
+       /* Read status FIFO */
+       switch_bank(iobase, BANK5);
+       while ((status = inb(iobase+FRM_ST)) & FRM_ST_VLD) {
+               st_fifo->entries[st_fifo->tail].status = status;
+
+               st_fifo->entries[st_fifo->tail].len  = inb(iobase+RFLFL);
+               st_fifo->entries[st_fifo->tail].len |= inb(iobase+RFLFH) << 8;
+               
+               st_fifo->tail++;
+               st_fifo->len++;
+       }
+       /* Try to process all entries in status FIFO */
+       while (st_fifo->len) {
+               /* Get first entry */
+               status = st_fifo->entries[st_fifo->head].status;
+               len    = st_fifo->entries[st_fifo->head].len;
+               st_fifo->head++;
+               st_fifo->len--;
+
+               /* Check for errors */
+               if (status & FRM_ST_ERR_MSK) {
+                       if (status & FRM_ST_LOST_FR) {
+                               /* Add number of lost frames to stats */
+                               self->stats.rx_errors += len;   
+                       } else {
+                               /* Skip frame */
+                               self->stats.rx_errors++;
+                               
+                               self->rx_buff.data += len;
+                       
+                               if (status & FRM_ST_MAX_LEN)
+                                       self->stats.rx_length_errors++;
+                               
+                               if (status & FRM_ST_PHY_ERR) 
+                                       self->stats.rx_frame_errors++;
+                               
+                               if (status & FRM_ST_BAD_CRC) 
+                                       self->stats.rx_crc_errors++;
+                       }
+                       /* The errors below can be reported in both cases */
+                       if (status & FRM_ST_OVR1)
+                               self->stats.rx_fifo_errors++;                  
+                       
+                       if (status & FRM_ST_OVR2)
+                               self->stats.rx_fifo_errors++;
+               } else {
+                       /* Check if we have transfered all data to memory */
+                       switch_bank(iobase, BANK0);
+                       if (inb(iobase+LSR) & LSR_RXDA) {
+                               /* Put this entry back in fifo */
+                               st_fifo->head--;
+                               st_fifo->len++;
+                               st_fifo->entries[st_fifo->head].status = status;
+                               st_fifo->entries[st_fifo->head].len = len;
+                               
+                               /* Restore bank register */
+                               outb(bank, iobase+BSR);
+                               
+                               return FALSE;   /* I'll be back! */
+                       }
+
+                       /* 
+                        * Remember when we received this frame, so we can
+                        * reduce the min turn time a bit since we will know
+                        * how much time we have used for protocol processing
+                        */
+                       do_gettimeofday(&self->stamp);
+
+                       skb = dev_alloc_skb(len+1);
+                       if (skb == NULL)  {
+                               WARNING(__FUNCTION__ "(), memory squeeze, "
+                                       "dropping frame.\n");
+                               
+                               /* Restore bank register */
+                               outb(bank, iobase+BSR);
+                               
+                               return FALSE;
+                       }
+                       
+                       /* Make sure IP header gets aligned */
+                       skb_reserve(skb, 1); 
+
+                       /* Copy frame without CRC */
+                       if (self->io.speed < 4000000) {
+                               skb_put(skb, len-2);
+                               memcpy(skb->data, self->rx_buff.data, len-2);
+                       } else {
+                               skb_put(skb, len-4);
+                               memcpy(skb->data, self->rx_buff.data, len-4);
+                       }
+
+                       /* Move to next frame */
+                       self->rx_buff.data += len;
+                       self->stats.rx_packets++;
+
+                       skb->dev = self->netdev;
+                       skb->mac.raw  = skb->data;
+                       skb->protocol = htons(ETH_P_IRDA);
+                       netif_rx(skb);
+               }
+       }
+       /* Restore bank register */
+       outb(bank, iobase+BSR);
+
+       return TRUE;
+}
+
+/*
+ * Function nsc_fir_pio_receive (self)
+ *
+ *    Receive all data in receiver FIFO
+ *
+ */
+static void nsc_fir_pio_receive(struct nsc_fir_cb *self) 
+{
+       __u8 byte = 0x00;
+       int iobase;
+
+       IRDA_DEBUG(4, __FUNCTION__ "()\n");
+
+       ASSERT(self != NULL, return;);
+       
+       iobase = self->io.iobase;
+       
+       /*  Receive all characters in Rx FIFO */
+       do {
+               byte = inb(iobase+RXD);
+               async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, 
+                                 byte);
+       } while (inb(iobase+LSR) & LSR_RXDA); /* Data available */      
+}
+
+/*
+ * Function nsc_fir_sir_interrupt (self, eir)
+ *
+ *    Handle SIR interrupt
+ *
+ */
+static __u8 nsc_fir_sir_interrupt(struct nsc_fir_cb *self, int eir)
+{
+       int actual;
+       __u8 new_ier = 0;
+
+       /* Check if transmit FIFO is low on data */
+       if (eir & EIR_TXLDL_EV) {
+               /* Write data left in transmit buffer */
+               actual = nsc_fir_pio_write(self->io.iobase, 
+                                          self->tx_buff.data, 
+                                          self->tx_buff.len, 
+                                          self->io.fifo_size);
+               self->tx_buff.data += actual;
+               self->tx_buff.len  -= actual;
+               
+               self->io.direction = IO_XMIT;
+
+               /* Check if finished */
+               if (self->tx_buff.len > 0)
+                       new_ier |= IER_TXLDL_IE;
+               else { 
+                       self->netdev->tbusy = 0; /* Unlock */
+                       self->stats.tx_packets++;
+                       
+                       mark_bh(NET_BH);        
+
+                       new_ier |= IER_TXEMP_IE;
+               }
+                       
+       }
+       /* Check if transmission has completed */
+       if (eir & EIR_TXEMP_EV) {
+               /* Check if we need to change the speed? */
+               if (self->new_speed) {
+                       IRDA_DEBUG(2, __FUNCTION__ "(), Changing speed!\n");
+                       nsc_fir_change_speed(self, self->new_speed);
+                       self->new_speed = 0;
+               }
+
+               /* Turn around and get ready to receive some data */
+               self->io.direction = IO_RECV;
+               new_ier |= IER_RXHDL_IE;
+       }
+
+       /* Rx FIFO threshold or timeout */
+       if (eir & EIR_RXHDL_EV) {
+               nsc_fir_pio_receive(self);
+
+               /* Keep receiving */
+               new_ier |= IER_RXHDL_IE;
+       }
+       return new_ier;
+}
+
+/*
+ * Function nsc_fir_fir_interrupt (self, eir)
+ *
+ *    Handle MIR/FIR interrupt
+ *
+ */
+static __u8 nsc_fir_fir_interrupt(struct nsc_fir_cb *self, int iobase, int eir)
+{
+       __u8 new_ier = 0;
+       __u8 bank;
+
+       bank = inb(iobase+BSR);
+       
+       /* Status event, or end of frame detected in FIFO */
+       if (eir & (EIR_SFIF_EV|EIR_LS_EV)) {
+               if (nsc_fir_dma_receive_complete(self, iobase)) {
+
+                       /* Wait for next status FIFO interrupt */
+                       new_ier |= IER_SFIF_IE;
+               } else {
+                       /* DMA not finished yet */
+
+                       /* Set timer value, resolution 125 us */
+                       switch_bank(iobase, BANK4);
+                       outb(0x0f, iobase+TMRL); /* 125 us * 15 */
+                       outb(0x00, iobase+TMRH);
+
+                       /* Start timer */
+                       outb(IRCR1_TMR_EN, iobase+IRCR1);
+
+                       new_ier |= IER_TMR_IE;
+               }
+       } else if (eir & EIR_TMR_EV) { /* Timer finished */
+               /* Disable timer */
+               switch_bank(iobase, BANK4);
+               outb(0, iobase+IRCR1);
+
+               /* Clear timer event */
+               switch_bank(iobase, BANK0);
+               outb(ASCR_CTE, iobase+ASCR);
+
+               /* Check if this is a TX timer interrupt */
+               if (self->io.direction == IO_XMIT) {
+                       nsc_fir_dma_xmit(self, iobase);
+
+                       /*  Interrupt on DMA */
+                       new_ier |= IER_DMA_IE;
+               } else {
+                       /* Check if DMA has now finished */
+                       nsc_fir_dma_receive_complete(self, iobase);
+
+                       new_ier |= IER_SFIF_IE;
+               }
+       } else if (eir & EIR_DMA_EV) { /* Finished with transmission */
+               if (nsc_fir_dma_xmit_complete(self)) {          
+                       /* Check if there are more frames to be transmitted */
+                       if (irda_device_txqueue_empty(self->netdev)) {
+                               /* Prepare for receive */
+                               nsc_fir_dma_receive(self);
+                       
+                               new_ier = IER_LS_IE|IER_SFIF_IE;
+                       }
+               } else {
+                       /*  Not finished yet, so interrupt on DMA again */
+                       new_ier |= IER_DMA_IE;
+               }
+       }
+       outb(bank, iobase+BSR);
+
+       return new_ier;
+}
+
+/*
+ * Function nsc_fir_interrupt (irq, dev_id, regs)
+ *
+ *    An interrupt from the chip has arrived. Time to do some work
+ *
+ */
+static void nsc_fir_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct net_device *dev = (struct net_device *) dev_id;
+       struct nsc_fir_cb *self;
+       __u8 bsr, eir, ier;
+       int iobase;
+
+       if (!dev) {
+               printk(KERN_WARNING "%s: irq %d for unknown device.\n", 
+                      driver_name, irq);
+               return;
+       }
+       self = (struct nsc_fir_cb *) dev->priv;
+
+       spin_lock(&self->lock); 
+       dev->interrupt = 1;
+
+       iobase = self->io.iobase;
+
+       bsr = inb(iobase+BSR);  /* Save current bank */
+
+       switch_bank(iobase, BANK0);     
+       ier = inb(iobase+IER); 
+       eir = inb(iobase+EIR) & ier; /* Mask out the interesting ones */ 
+
+       outb(0, iobase+IER); /* Disable interrupts */
+       
+       if (eir) {
+               /* Dispatch interrupt handler for the current speed */
+               if (self->io.speed > 115200)
+                       ier = nsc_fir_fir_interrupt(self, iobase, eir);
+               else
+                       ier = nsc_fir_sir_interrupt(self, eir);
+       }
+
+       outb(ier, iobase+IER);   /* Restore interrupts */
+       outb(bsr, iobase+BSR);   /* Restore bank register */
+
+       dev->interrupt = 0;
+       spin_unlock(&self->lock);
+}
+
+/*
+ * Function nsc_fir_is_receiving (self)
+ *
+ *    Return TRUE is we are currently receiving a frame
+ *
+ */
+static int nsc_fir_is_receiving(struct nsc_fir_cb *self)
+{
+       int status = FALSE;
+       int iobase;
+       __u8 bank;
+
+       ASSERT(self != NULL, return FALSE;);
+
+       if (self->io.speed > 115200) {
+               iobase = self->io.iobase;
+
+               /* Check if rx FIFO is not empty */
+               bank = inb(iobase+BSR);
+               switch_bank(iobase, BANK2);
+               if ((inb(iobase+RXFLV) & 0x3f) != 0) {
+                       /* We are receiving something */
+                       status =  TRUE;
+               }
+               outb(bank, iobase+BSR);
+       } else 
+               status = (self->rx_buff.state != OUTSIDE_FRAME);
+       
+       return status;
+}
+
+/*
+ * Function nsc_fir_net_init (dev)
+ *
+ *    Initialize network device
+ *
+ */
+static int nsc_fir_net_init(struct net_device *dev)
+{
+       IRDA_DEBUG(4, __FUNCTION__ "()\n");
+
+       /* Setup to be a normal IrDA network device driver */
+       irda_device_setup(dev);
+
+       /* Insert overrides below this line! */
+
+       return 0;
+}
+
+/*
+ * Function nsc_fir_net_open (dev)
+ *
+ *    Start the device
+ *
+ */
+static int nsc_fir_net_open(struct net_device *dev)
+{
+       struct nsc_fir_cb *self;
+       int iobase;
+       __u8 bank;
+       
+       IRDA_DEBUG(4, __FUNCTION__ "()\n");
+       
+       ASSERT(dev != NULL, return -1;);
+       self = (struct nsc_fir_cb *) dev->priv;
+       
+       ASSERT(self != NULL, return 0;);
+       
+       iobase = self->io.iobase;
+
+       if (request_irq(self->io.irq, nsc_fir_interrupt, 0, dev->name, 
+                       (void *) dev)) 
+       {
+               return -EAGAIN;
+       }
+       /*
+        * Always allocate the DMA channel after the IRQ, and clean up on 
+        * failure.
+        */
+       if (request_dma(self->io.dma, dev->name)) {
+               free_irq(self->io.irq, self);
+               return -EAGAIN;
+       }
+       
+       /* Save current bank */
+       bank = inb(iobase+BSR);
+       
+       /* turn on interrupts */
+       switch_bank(iobase, BANK0);
+       outb(IER_LS_IE | IER_RXHDL_IE, iobase+IER);
+
+       /* Restore bank register */
+       outb(bank, iobase+BSR);
+
+       /* Ready to play! */
+       dev->tbusy = 0;
+       dev->interrupt = 0;
+       dev->start = 1;
+
+       /* 
+        * Open new IrLAP layer instance, now that everything should be
+        * initialized properly 
+        */
+       self->irlap = irlap_open(dev, &self->qos);
+
+       MOD_INC_USE_COUNT;
+
+       return 0;
+}
+
+/*
+ * Function nsc_fir_net_close (dev)
+ *
+ *    Stop the device
+ *
+ */
+static int nsc_fir_net_close(struct net_device *dev)
+{
+       struct nsc_fir_cb *self;
+       int iobase;
+       __u8 bank;
+
+       IRDA_DEBUG(4, __FUNCTION__ "()\n");
+       
+       ASSERT(dev != NULL, return -1;);
+       self = (struct nsc_fir_cb *) dev->priv;
+       
+       ASSERT(self != NULL, return 0;);
+
+       /* Stop device */
+       dev->tbusy = 1;
+       dev->start = 0;
+
+       /* Stop and remove instance of IrLAP */
+       if (self->irlap)
+               irlap_close(self->irlap);
+       self->irlap = NULL;
+       
+       iobase = self->io.iobase;
+
+       disable_dma(self->io.dma);
+
+       /* Save current bank */
+       bank = inb(iobase+BSR);
+
+       /* Disable interrupts */
+       switch_bank(iobase, BANK0);
+       outb(0, iobase+IER); 
+       
+       free_irq(self->io.irq, dev);
+       free_dma(self->io.dma);
+
+       /* Restore bank register */
+       outb(bank, iobase+BSR);
+
+       MOD_DEC_USE_COUNT;
+
+       return 0;
+}
+
+/*
+ * Function nsc_fir_net_ioctl (dev, rq, cmd)
+ *
+ *    Process IOCTL commands for this device
+ *
+ */
+static int nsc_fir_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       struct if_irda_req *irq = (struct if_irda_req *) rq;
+       struct nsc_fir_cb *self;
+       unsigned long flags;
+       int ret = 0;
+
+       ASSERT(dev != NULL, return -1;);
+
+       self = dev->priv;
+
+       ASSERT(self != NULL, return -1;);
+
+       IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
+       
+       /* Disable interrupts & save flags */
+       save_flags(flags);
+       cli();
+       
+       switch (cmd) {
+       case SIOCSBANDWIDTH: /* Set bandwidth */
+               nsc_fir_change_speed(self, irq->ifr_baudrate);
+               break;
+       case SIOCSMEDIABUSY: /* Set media busy */
+               irda_device_set_media_busy(self->netdev, TRUE);
+               break;
+       case SIOCGRECEIVING: /* Check if we are receiving right now */
+               irq->ifr_receiving = nsc_fir_is_receiving(self);
+               break;
+       default:
+               ret = -EOPNOTSUPP;
+       }
+       
+       restore_flags(flags);
+       
+       return ret;
+}
+
+static struct net_device_stats *nsc_fir_net_get_stats(struct net_device *dev)
+{
+       struct nsc_fir_cb *self = (struct nsc_fir_cb *) dev->priv;
+       
+       return &self->stats;
+}
+
+#ifdef CONFIG_APM
+static void nsc_fir_suspend(struct nsc_fir_cb *self)
+{
+       int i = 10;
+
+       MESSAGE("%s, Suspending\n", driver_name);
+
+       if (self->suspend)
+               return;
+
+       self->suspend = 1;
+}
+
+
+static void nsc_fir_wakeup(struct nsc_fir_cb *self)
+{
+       struct net_device *dev = self->netdev;
+       unsigned long flags;
+
+       if (!self->suspend)
+               return;
+
+       save_flags(flags);
+       cli();
+
+       restore_flags(flags);
+       MESSAGE("%s, Waking up\n", driver_name);
+}
+
+static int nsc_fir_apmproc(apm_event_t event)
+{
+       static int down = 0;          /* Filter out double events */
+       int i;
+
+       switch (event) {
+       case APM_SYS_SUSPEND:
+       case APM_USER_SUSPEND:
+               if (!down) {                    
+                       for (i = 0; i < 4; i++) {
+                               if (dev_self[i])
+                                       nsc_fir_suspend(dev_self[i]);
+                       }
+               }
+               down = 1;
+               break;
+       case APM_NORMAL_RESUME:
+       case APM_CRITICAL_RESUME:
+               if (down) {
+                       for (i = 0; i < 4; i++) {
+                               if (dev_self[i])
+                                       nsc_fir_wakeup(dev_self[i]);
+                       }
+               }
+               down = 0;
+               break;
+       }
+       return 0;
+}
+#endif /* CONFIG_APM */
+
+#ifdef MODULE
+MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
+MODULE_DESCRIPTION("NSC FIR IrDA Device Driver");
+
+MODULE_PARM(qos_mtt_bits, "i");
+MODULE_PARM(io, "1-4i");
+MODULE_PARM(io2, "1-4i");
+MODULE_PARM(irq, "1-4i");
+MODULE_PARM(dongle_id, "i");
+
+int init_module(void)
+{
+       return nsc_fir_init();
+}
+
+void cleanup_module(void)
+{
+       nsc_fir_cleanup();
+}
+#endif /* MODULE */
+
index 6e37ba1652cacbd6f35a3184399ebde05ae4e800..dbbaa50a1d6991cde3f3405c204c16cc04365323 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental...
  * Author:        Jean Tourrilhes <jt@hpl.hp.com>
  * Created at:    22/11/99
- * Modified at:   Fri Dec 17 09:17:30 1999
+ * Modified at:   Fri Dec 17 09:13:32 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Jean Tourrilhes, All Rights Reserved.
diff --git a/drivers/net/irda/pc87108.c b/drivers/net/irda/pc87108.c
deleted file mode 100644 (file)
index 47da35d..0000000
+++ /dev/null
@@ -1,1592 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      pc87108.c
- * Version:       0.8
- * Description:   FIR/MIR driver for the NS PC87108 chip
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Sat Nov  7 21:43:15 1998
- * Modified at:   Tue Dec 21 21:51:54 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>
- *     Copyright (c) 1998 Lichen Wang, <lwang@actisys.com>
- *     Copyright (c) 1998 Actisys Corp., www.actisys.com
- *     All Rights Reserved
- *      
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
- *
- *     Notice that all functions that needs to access the chip in _any_
- *     way, must save BSR register on entry, and restore it on exit. 
- *     It is _very_ important to follow this policy!
- *
- *         __u8 bank;
- *     
- *         bank = inb(iobase+BSR);
- *  
- *         do_your_stuff_here();
- *
- *         outb(bank, iobase+BSR);
- *
- *    If you find bugs in this file, its very likely that the same bug
- *    will also be in w83977af_ir.c since the implementations are quite
- *    similar.
- *     
- ********************************************************************/
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/malloc.h>
-#include <linux/init.h>
-#include <linux/rtnetlink.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/byteorder.h>
-
-#include <net/irda/wrapper.h>
-#include <net/irda/irda.h>
-#include <net/irda/irmod.h>
-#include <net/irda/irlap_frame.h>
-#include <net/irda/irda_device.h>
-
-#include <net/irda/pc87108.h>
-
-#define BROKEN_DONGLE_ID
-
-static char *driver_name = "pc87108";
-static int qos_mtt_bits = 0x07;  /* 1 ms or more */
-
-#define CHIP_IO_EXTENT 8
-
-static unsigned int io[]  = { 0x2f8, ~0, ~0, ~0 };
-static unsigned int io2[] = { 0x150, 0, 0, 0 };
-static unsigned int irq[] = { 3, 0, 0, 0 };
-static unsigned int dma[] = { 0, 0, 0, 0 };
-
-static struct pc87108 *dev_self[] = { NULL, NULL, NULL, NULL};
-
-static char *dongle_types[] = {
-       "Differential serial interface",
-       "Differential serial interface",
-       "Reserved",
-       "Reserved",
-       "Sharp RY5HD01",
-       "Reserved",
-       "Single-ended serial interface",
-       "Consumer-IR only",
-       "HP HSDL-2300, HP HSDL-3600/HSDL-3610",
-       "IBM31T1100 or Temic TFDS6000/TFDS6500",
-       "Reserved",
-       "Reserved",
-       "HP HSDL-1100/HSDL-2100",
-       "HP HSDL-1100/HSDL-2100"
-       "Supports SIR Mode only",
-       "No dongle connected",
-};
-
-/* Some prototypes */
-static int  pc87108_open(int i, unsigned int iobase, unsigned int board_addr, 
-                        unsigned int irq, unsigned int dma);
-#ifdef MODULE
-static int  pc87108_close(struct pc87108 *self);
-#endif /* MODULE */
-static int  pc87108_probe(int iobase, int board_addr, int irq, int dma);
-static void pc87108_pio_receive(struct pc87108 *self);
-static int  pc87108_dma_receive(struct pc87108 *self); 
-static int  pc87108_dma_receive_complete(struct pc87108 *self, int iobase);
-static int  pc87108_hard_xmit(struct sk_buff *skb, struct net_device *dev);
-static int  pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size);
-static void pc87108_dma_write(struct pc87108 *self, int iobase);
-static void pc87108_change_speed(struct pc87108 *self, __u32 baud);
-static void pc87108_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static int  pc87108_is_receiving(struct pc87108 *self);
-static int  pc87108_read_dongle_id (int iobase);
-static void pc87108_init_dongle_interface (int iobase, int dongle_id);
-
-static int  pc87108_net_init(struct net_device *dev);
-static int  pc87108_net_open(struct net_device *dev);
-static int  pc87108_net_close(struct net_device *dev);
-static int  pc87108_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-
-/*
- * Function pc87108_init ()
- *
- *    Initialize chip. Just try to find out how many chips we are dealing with
- *    and where they are
- */
-int __init pc87108_init(void)
-{
-       int i;
-
-       for (i=0; (io[i] < 2000) && (i < 4); i++) {
-               int ioaddr = io[i];
-               if (check_region(ioaddr, CHIP_IO_EXTENT) < 0)
-                       continue;
-               if (pc87108_open(i, io[i], io2[i], irq[i], dma[i]) == 0)
-                       return 0;
-       }
-       return -ENODEV;
-}
-
-/*
- * Function pc87108_cleanup ()
- *
- *    Close all configured chips
- *
- */
-#ifdef MODULE
-static void pc87108_cleanup(void)
-{
-       int i;
-
-        IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-       for (i=0; i < 4; i++) {
-               if (dev_self[i])
-                       pc87108_close(dev_self[i]);
-       }
-}
-#endif /* MODULE */
-
-/*
- * Function pc87108_open (iobase, irq)
- *
- *    Open driver instance
- *
- */
-static int pc87108_open(int i, unsigned int iobase, unsigned int board_addr, 
-                       unsigned int irq, unsigned int dma)
-{
-       struct net_device *dev;
-       struct pc87108 *self;
-       int dongle_id;
-       int ret;
-       int err;
-
-       IRDA_DEBUG(0, __FUNCTION__ "()\n");
-
-       if ((dongle_id = pc87108_probe(iobase, board_addr, irq, dma)) == -1)
-               return -1;
-
-       /*
-        *  Allocate new instance of the driver
-        */
-       self = kmalloc(sizeof(struct pc87108), GFP_KERNEL);
-       if (self == NULL) {
-               printk(KERN_ERR "IrDA: Can't allocate memory for "
-                      "IrDA control block!\n");
-               return -ENOMEM;
-       }
-       memset(self, 0, sizeof(struct pc87108));
-   
-       /* Need to store self somewhere */
-       dev_self[i] = self;
-
-       /* Initialize IO */
-       self->io.iobase    = iobase;
-        self->io.irq       = irq;
-        self->io.io_ext    = CHIP_IO_EXTENT;
-        self->io.dma       = dma;
-        self->io.fifo_size = 32;
-
-       /* Lock the port that we need */
-       ret = check_region(self->io.iobase, self->io.io_ext);
-       if (ret < 0) { 
-               IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
-                     self->io.iobase);
-               /* pc87108_cleanup(self->self);  */
-               return -ENODEV;
-       }
-       request_region(self->io.iobase, self->io.io_ext, driver_name);
-
-       /* Initialize QoS for this device */
-       irda_init_max_qos_capabilies(&self->qos);
-       
-       /* The only value we must override it the baudrate */
-       self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
-               IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);
-       
-       self->qos.min_turn_time.bits = qos_mtt_bits;
-       irda_qos_bits_to_value(&self->qos);
-       
-       self->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO|IFF_DONGLE;
-
-       /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
-       self->rx_buff.truesize = 14384; 
-       self->tx_buff.truesize = 4000;
-
-       /* Allocate memory if needed */
-       if (self->rx_buff.truesize > 0) {
-               self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
-                                                     GFP_KERNEL|GFP_DMA);
-               if (self->rx_buff.head == NULL)
-                       return -ENOMEM;
-               memset(self->rx_buff.head, 0, self->rx_buff.truesize);
-       }
-       if (self->tx_buff.truesize > 0) {
-               self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
-                                                     GFP_KERNEL|GFP_DMA);
-               if (self->tx_buff.head == NULL) {
-                       kfree(self->rx_buff.head);
-                       return -ENOMEM;
-               }
-               memset(self->tx_buff.head, 0, self->tx_buff.truesize);
-       }
-
-       self->rx_buff.in_frame = FALSE;
-       self->rx_buff.state = OUTSIDE_FRAME;
-       self->tx_buff.data = self->tx_buff.head;
-       self->rx_buff.data = self->rx_buff.head;
-       
-       if (!(dev = dev_alloc("irda%d", &err))) {
-               ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
-               return -ENOMEM;
-       }
-       dev->priv = (void *) self;
-       self->netdev = dev;
-
-       /* Override the network functions we need to use */
-       dev->init            = pc87108_net_init;
-       dev->hard_start_xmit = pc87108_hard_xmit;
-       dev->open            = pc87108_net_open;
-       dev->stop            = pc87108_net_close;
-       dev->do_ioctl        = pc87108_net_ioctl;
-
-       rtnl_lock();
-       err = register_netdevice(dev);
-       rtnl_unlock();
-       if (err) {
-               ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
-               return -1;
-       }
-
-       MESSAGE("IrDA: Registered device %s\n", dev->name);
-       
-       self->io.dongle_id = dongle_id;
-       pc87108_init_dongle_interface(iobase, dongle_id);
-
-       return 0;
-}
-
-#ifdef MODULE
-/*
- * Function pc87108_close (self)
- *
- *    Close driver instance
- *
- */
-static int pc87108_close(struct pc87108 *self)
-{
-       int iobase;
-
-       IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-       ASSERT(self != NULL, return -1;);
-
-        iobase = self->io.iobase;
-
-       /* Remove netdevice */
-       if (self->netdev) {
-               rtnl_lock();
-               unregister_netdevice(self->netdev);
-               rtnl_unlock();
-       }
-
-       /* Release the PORT that this driver is using */
-       IRDA_DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", 
-                  self->io.iobase);
-       release_region(self->io.iobase, self->io.io_ext);
-
-       if (self->tx_buff.head)
-               kfree(self->tx_buff.head);
-       
-       if (self->rx_buff.head)
-               kfree(self->rx_buff.head);
-
-       kfree(self);
-
-       return 0;
-}
-#endif /* MODULE */
-
-/*
- * Function pc87108_probe (iobase, board_addr, irq, dma)
- *
- *    Returns non-negative on success.
- *
- */
-static int pc87108_probe(int iobase, int board_addr, int irq, int dma) 
-{
-       int version;
-       __u8 temp=0;
-       int dongle_id;
-       
-       IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-       /* Base Address and Interrupt Control Register BAIC */
-       outb(0, board_addr);
-       switch (iobase) {
-       case 0x3E8: outb(0x14, board_addr+1); break;
-       case 0x2E8: outb(0x15, board_addr+1); break;
-       case 0x3F8: outb(0x16, board_addr+1); break;
-       case 0x2F8: outb(0x17, board_addr+1); break;
-       default:    ERROR(__FUNCTION__ "(), invalid base_address");
-       }
-       
-       /* Control Signal Routing Register CSRT */
-       switch (irq) {
-       case 3:  temp = 0x01; break;
-       case 4:  temp = 0x02; break;
-       case 5:  temp = 0x03; break;
-       case 7:  temp = 0x04; break;
-       case 9:  temp = 0x05; break;
-       case 11: temp = 0x06; break;
-       case 15: temp = 0x07; break;
-       default: ERROR(__FUNCTION__ "(), invalid irq");
-       }
-       outb(1, board_addr);
-       
-       switch (dma) {  
-       case 0: outb(0x08+temp, board_addr+1); break;
-       case 1: outb(0x10+temp, board_addr+1); break;
-       case 3: outb(0x18+temp, board_addr+1); break;
-       default: IRDA_DEBUG(0, __FUNCTION__ "(), invalid dma");
-       }
-
-       /* Mode Control Register MCTL */
-       outb(2, board_addr);
-       outb(0x03, board_addr+1);
-               
-       /* read the Module ID */
-       switch_bank(iobase, BANK3);
-       version = inb(iobase+MID);
-       
-       /* should be 0x2? */
-       if (0x20 != (version & 0xf0)) {
-               ERROR(__FUNCTION__ "(), Wrong chip version %02x\n", version);
-               return -1;
-       }
-       
-       /* Switch to advanced mode */
-       switch_bank(iobase, BANK2);
-       outb(ECR1_EXT_SL, iobase+ECR1);
-       switch_bank(iobase, BANK0);
-
-       dongle_id = pc87108_read_dongle_id(iobase);
-       IRDA_DEBUG(0, __FUNCTION__ "(), Found dongle: %s\n", 
-                  dongle_types[dongle_id]);
-       
-       /* Set FIFO threshold to TX17, RX16, reset and enable FIFO's */
-       switch_bank(iobase, BANK0);     
-       outb(FCR_RXTH|FCR_TXTH|FCR_TXSR|FCR_RXSR|FCR_FIFO_EN, iobase+FCR);
-       
-       /* Set FIFO size to 32 */
-       switch_bank(iobase, BANK2);
-       outb(EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2);    
-
-       /* IRCR2: FEND_MD is set */
-       switch_bank(iobase, BANK5);
-       outb(0x2a, iobase+4);
-
-       /* Make sure that some defaults are OK */
-       switch_bank(iobase, BANK6);
-       outb(0x20, iobase+0); /* Set 32 bits FIR CRC */
-       outb(0x0a, iobase+1); /* Set MIR pulse width */
-       outb(0x0d, iobase+2); /* Set SIR pulse width */
-       outb(0x2a, iobase+4); /* Set beginning frag, and preamble length */
-
-       /* Receiver frame length */
-       switch_bank(iobase, BANK4);
-       outb(2048 & 0xff, iobase+6);
-       outb((2048 >> 8) & 0x1f, iobase+7);
-
-       /* Transmitter frame length */
-       outb(2048 & 0xff, iobase+4);
-       outb((2048 >> 8) & 0x1f, iobase+5);
-       
-       IRDA_DEBUG(0, "PC87108 driver loaded. Version: 0x%02x\n", version);
-
-       /* Enable receive interrupts */
-       switch_bank(iobase, BANK0);
-       outb(IER_RXHDL_IE, iobase+IER);
-
-       return dongle_id;
-}
-
-/*
- * Function pc87108_read_dongle_id (void)
- *
- * Try to read dongle indentification. This procedure needs to be executed
- * once after power-on/reset. It also needs to be used whenever you suspect
- * that the user may have plugged/unplugged the IrDA Dongle.
- * 
- */
-static int pc87108_read_dongle_id (int iobase)
-{
-       int dongle_id;
-       __u8 bank;
-
-       IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-       bank = inb(iobase+BSR);
-
-       /* Select Bank 7 */
-       switch_bank(iobase, BANK7);
-       
-       /* IRCFG4: IRSL0_DS and IRSL21_DS are cleared */
-       outb(0x00, iobase+7);
-       
-       /* ID0, 1, and 2 are pulled up/down very slowly */
-       udelay(50);
-       
-       /* IRCFG1: read the ID bits */
-       dongle_id = inb(iobase+4) & 0x0f;
-
-#ifdef BROKEN_DONGLE_ID
-       if (dongle_id == 0x0a)
-               dongle_id = 0x09;
-#endif
-       
-       /* Go back to  bank 0 before returning */
-       switch_bank(iobase, BANK0);
-
-       IRDA_DEBUG(0, __FUNCTION__ "(), Dongle = %#x\n", dongle_id);
-
-       outb(bank, iobase+BSR);
-
-       return dongle_id;
-}
-
-/*
- * Function pc87108_init_dongle_interface (iobase, dongle_id)
- *
- *     This function initializes the dongle for the transceiver that is
- *     used. This procedure needs to be executed once after
- *     power-on/reset. It also needs to be used whenever you suspect that
- *     the dongle is changed. 
- */
-static void pc87108_init_dongle_interface (int iobase, int dongle_id)
-{
-       int bank;
-
-       /* Save current bank */
-       bank = inb(iobase+BSR);
-
-       /* Select Bank 7 */
-       switch_bank(iobase, BANK7);
-       
-       /* IRCFG4: set according to dongle_id */
-       switch (dongle_id) {
-       case 0x00: /* same as */
-       case 0x01: /* Differential serial interface */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x02: /* same as */
-       case 0x03: /* Reserved */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x04: /* Sharp RY5HD01 */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x05: /* Reserved */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x06: /* Single-ended serial interface */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x07: /* Consumer-IR only */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s is not for IrDA mode\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x08: /* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x09: /* IBM31T1100 or Temic TFDS6000/TFDS6500 */
-               outb_p(0x28, iobase+7); /* Set irsl[0-2] as output */
-               break;
-       case 0x0A: /* same as */
-       case 0x0B: /* Reserved */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x0C: /* same as */
-       case 0x0D: /* HP HSDL-1100/HSDL-2100 */
-               /* 
-                * Set irsl0 as input, irsl[1-2] as output, and separate 
-                * inputs are used for SIR and MIR/FIR 
-                */
-               outb(0x48, iobase+7); 
-               break;
-       case 0x0E: /* Supports SIR Mode only */
-               outb(0x28, iobase+7); /* Set irsl[0-2] as output */
-               break;
-       case 0x0F: /* No dongle connected */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s\n",
-                      dongle_types[dongle_id]); 
-               IRDA_DEBUG(0, "***\n");
-
-               switch_bank(iobase, BANK0);
-               outb(0x62, iobase+MCR);
-               break;
-       default: 
-               IRDA_DEBUG(0, __FUNCTION__ "(), invalid dongle_id %#x", 
-                          dongle_id);
-       }
-       
-       /* IRCFG1: IRSL1 and 2 are set to IrDA mode */
-       outb(0x00, iobase+4);
-
-       /* Restore bank register */
-       outb(bank, iobase+BSR);
-       
-} /* set_up_dongle_interface */
-
-/*
- * Function pc87108_change_dongle_speed (iobase, speed, dongle_id)
- *
- *    Change speed of the attach dongle
- *
- */
-static void pc87108_change_dongle_speed(int iobase, int speed, int dongle_id)
-{
-       unsigned long flags;
-       __u8 bank;
-
-       IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-       /* Save current bank */
-       bank = inb(iobase+BSR);
-
-       /* Select Bank 7 */
-       switch_bank(iobase, BANK7);
-       
-       /* IRCFG1: set according to dongle_id */
-       switch (dongle_id) {
-       case 0x00: /* same as */
-       case 0x01: /* Differential serial interface */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x02: /* same as */
-       case 0x03: /* Reserved */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x04: /* Sharp RY5HD01 */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n",
-                      dongle_types[dongle_id]); 
-       case 0x05: /* Reserved */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x06: /* Single-ended serial interface */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x07: /* Consumer-IR only */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s is not for IrDA mode\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x08: /* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n",
-                      dongle_types[dongle_id]); 
-       case 0x09: /* IBM31T1100 or Temic TFDS6000/TFDS6500 */
-               switch_bank(iobase, BANK7);
-               outb_p(0x01, iobase+4);
-
-               if (speed == 4000000) {
-                       save_flags(flags);
-                       cli();
-                       outb(0x81, iobase+4);
-                       outb(0x80, iobase+4);
-                       restore_flags(flags);
-               }
-               else
-                       outb_p(0x00, iobase+4);
-               break;
-       case 0x0A: /* same as */
-       case 0x0B: /* Reserved */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n",
-                      dongle_types[dongle_id]); 
-               break;
-       case 0x0C: /* same as */
-       case 0x0D: /* HP HSDL-1100/HSDL-2100 */
-               break;
-       case 0x0E: /* Supports SIR Mode only */
-               break;
-       case 0x0F: /* No dongle connected */
-               IRDA_DEBUG(0, __FUNCTION__ "(), %s is not for IrDA mode\n",
-                      dongle_types[dongle_id]);
-
-               switch_bank(iobase, BANK0); 
-               outb(0x62, iobase+MCR);
-               break;
-       default: 
-               IRDA_DEBUG(0, __FUNCTION__ "(), invalid data_rate\n");
-       }
-       /* Restore bank register */
-       outb(bank, iobase+BSR);
-}
-
-/*
- * Function pc87108_change_speed (self, baud)
- *
- *    Change the speed of the device
- *
- */
-static void pc87108_change_speed(struct pc87108 *self, __u32 speed)
-{
-       __u8 mcr = MCR_SIR;
-       __u8 bank;
-       int iobase; 
-
-       IRDA_DEBUG(2, __FUNCTION__ "(), speed=%d\n", speed);
-
-       ASSERT(self != NULL, return;);
-
-       iobase = self->io.iobase;
-
-       /* Update accounting for new speed */
-       self->io.speed = speed;
-
-       /* Save current bank */
-       bank = inb(iobase+BSR);
-
-       /* Disable interrupts */
-       switch_bank(iobase, BANK0);
-       outb(0, iobase+IER);
-
-         /* Select Bank 2 */
-       switch_bank(iobase, BANK2);
-
-       outb(0x00, iobase+BGDH);
-       switch (speed) {
-       case 9600:   outb(0x0c, iobase+BGDL); break;
-       case 19200:  outb(0x06, iobase+BGDL); break;
-       case 37600:  outb(0x03, iobase+BGDL); break;
-       case 57600:  outb(0x02, iobase+BGDL); break;
-       case 115200: outb(0x01, iobase+BGDL); break;
-       case 576000:
-               switch_bank(iobase, BANK5);
-               
-               /* IRCR2: MDRS is set */
-               outb(inb(iobase+4) | 0x04, iobase+4);
-              
-               mcr = MCR_MIR;
-               IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n");
-               break;
-       case 1152000:
-               mcr = MCR_MIR;
-               IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n");
-               break;
-       case 4000000:
-               mcr = MCR_FIR;
-               IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n");
-               break;
-       default:
-               mcr = MCR_FIR;
-               IRDA_DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", 
-                          speed);
-               break;
-       }
-
-       /* Set appropriate speed mode */
-       switch_bank(iobase, BANK0);
-       outb(mcr | MCR_TX_DFR, iobase+MCR);
-
-       /* Give some hits to the transceiver */
-       pc87108_change_dongle_speed(iobase, speed, self->io.dongle_id);
-
-       /* Set FIFO threshold to TX17, RX16 */
-       switch_bank(iobase, BANK0);
-       outb(FCR_RXTH|     /* Set Rx FIFO threshold */
-             FCR_TXTH|     /* Set Tx FIFO threshold */
-             FCR_TXSR|     /* Reset Tx FIFO */
-             FCR_RXSR|     /* Reset Rx FIFO */
-             FCR_FIFO_EN,  /* Enable FIFOs */
-             iobase+FCR);
-       /* outb(0xa7, iobase+FCR); */
-       
-       /* Set FIFO size to 32 */
-       switch_bank(iobase, BANK2);
-       outb(EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2);    
-       
-       self->netdev->tbusy = 0;
-       
-       /* Enable some interrupts so we can receive frames */
-       switch_bank(iobase, BANK0); 
-       if (speed > 115200) {
-               outb(IER_SFIF_IE, iobase+IER);
-               pc87108_dma_receive(self);
-       } else
-               outb(IER_RXHDL_IE, iobase+IER);
-       
-       /* Restore BSR */
-       outb(bank, iobase+BSR);
-}
-
-/*
- * Function pc87108_hard_xmit (skb, dev)
- *
- *    Transmit the frame!
- *
- */
-static int pc87108_hard_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct pc87108 *self;
-       int iobase;
-       __u32 speed;
-       __u8 bank;
-       int mtt;
-       
-       self = (struct pc87108 *) dev->priv;
-
-       ASSERT(self != NULL, return 0;);
-
-       iobase = self->io.iobase;
-
-       IRDA_DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, 
-                  (int) skb->len);
-       
-       /* Lock transmit buffer */
-       if (irda_lock((void *) &dev->tbusy) == FALSE)
-               return -EBUSY;
-
-       /* Check if we need to change the speed */
-       if ((speed = irda_get_speed(skb)) != self->io.speed)
-               self->new_speed = speed;
-
-       /* Save current bank */
-       bank = inb(iobase+BSR);
-
-       /* Decide if we should use PIO or DMA transfer */
-       if (self->io.speed > 115200) {
-               self->tx_buff.data = self->tx_buff.head;
-               memcpy(self->tx_buff.data, skb->data, skb->len);
-               self->tx_buff.len = skb->len;
-
-               mtt = irda_get_mtt(skb);
-               if (mtt > 50) {
-                       /* Adjust for timer resolution */
-                       mtt = mtt / 125 + 1;
-
-                       /* Setup timer */
-                       switch_bank(iobase, BANK4);
-                       outb(mtt & 0xff, iobase+TMRL);
-                       outb((mtt >> 8) & 0x0f, iobase+TMRH);
-                       
-                       /* Start timer */
-                       outb(IRCR1_TMR_EN, iobase+IRCR1);
-                       self->io.direction = IO_XMIT;
-                       
-                       /* Enable timer interrupt */
-                       switch_bank(iobase, BANK0);
-                       outb(IER_TMR_IE, iobase+IER);
-               } else {
-                       /* Use udelay for delays less than 50 us. */
-                       if (mtt)
-                               udelay(mtt);
-
-                       /* Enable DMA interrupt */
-                       switch_bank(iobase, BANK0);
-                       outb(IER_DMA_IE, iobase+IER);
-                       pc87108_dma_write(self, iobase);
-               }
-        } else {
-               self->tx_buff.data = self->tx_buff.head;
-
-               self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, 
-                                                  self->tx_buff.truesize);
-                               
-               /* Add interrupt on tx low level (will fire immediately) */
-               switch_bank(iobase, BANK0);
-               outb(IER_TXLDL_IE, iobase+IER);
-       }
-       dev_kfree_skb(skb);
-
-       /* Restore bank register */
-       outb(bank, iobase+BSR);
-
-       return 0;
-}
-
-/*
- * Function pc87108_dma_xmit (self, iobase)
- *
- *    Transmit data using DMA
- *
- */
-static void pc87108_dma_write(struct pc87108 *self, int iobase)
-{
-       int bsr;
-
-       IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-       /* Save current bank */
-       bsr = inb(iobase+BSR);
-
-       /* Disable DMA */
-       switch_bank(iobase, BANK0);
-       outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR);
-
-       setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, 
-                 DMA_MODE_WRITE);
-       
-       self->io.direction = IO_XMIT;
-       
-       /* Choose transmit DMA channel  */ 
-       switch_bank(iobase, BANK2);
-       outb(inb(iobase+ECR1) | ECR1_DMASWP|ECR1_DMANF|ECR1_EXT_SL, 
-            iobase+ECR1);
-       
-       /* Enable DMA */
-       switch_bank(iobase, BANK0);     
-       outb(inb(iobase+MCR)|MCR_DMA_EN, iobase+MCR);
-
-       /* Restore bank register */
-       outb(bsr, iobase+BSR);
-}
-
-/*
- * Function pc87108_pio_xmit (self, iobase)
- *
- *    Transmit data using PIO. Returns the number of bytes that actually
- *    got transfered
- *
- */
-static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size)
-{
-       int actual = 0;
-       __u8 bank;
-       
-       IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-       /* Save current bank */
-       bank = inb(iobase+BSR);
-
-       switch_bank(iobase, BANK0);
-       if (!(inb_p(iobase+LSR) & LSR_TXEMP)) {
-               IRDA_DEBUG(4, __FUNCTION__ 
-                          "(), warning, FIFO not empty yet!\n");
-
-               fifo_size -= 17;
-               IRDA_DEBUG(4, __FUNCTION__ "(), %d bytes left in tx fifo\n", 
-                          fifo_size);
-       }
-
-       /* Fill FIFO with current frame */
-       while ((fifo_size-- > 0) && (actual < len)) {
-               /* Transmit next byte */
-               outb(buf[actual++], iobase+TXD);
-       }
-        
-       IRDA_DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", 
-                  fifo_size, actual, len);
-       
-       /* Restore bank */
-       outb(bank, iobase+BSR);
-
-       return actual;
-}
-
-/*
- * Function pc87108_dma_xmit_complete (self)
- *
- *    The transfer of a frame in finished. This function will only be called 
- *    by the interrupt handler
- *
- */
-static void pc87108_dma_xmit_complete(struct pc87108 *self)
-{
-       int iobase;
-       __u8 bank;
-
-       IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-       ASSERT(self != NULL, return;);
-
-       iobase = self->io.iobase;
-
-       /* Save current bank */
-       bank = inb(iobase+BSR);
-
-       /* Disable DMA */
-       switch_bank(iobase, BANK0);
-       outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR);
-       
-       /* Check for underrrun! */
-       if (inb(iobase+ASCR) & ASCR_TXUR) {
-               self->stats.tx_errors++;
-               self->stats.tx_fifo_errors++;
-               
-               /* Clear bit, by writing 1 into it */
-               outb(ASCR_TXUR, iobase+ASCR);
-       } else {
-               self->stats.tx_packets++;
-               self->stats.tx_bytes +=  self->tx_buff.len;
-       }
-       
-       if (self->new_speed) {
-               pc87108_change_speed(self, self->new_speed);
-               self->new_speed = 0;
-       }
-
-       /* Unlock tx_buff and request another frame */
-       self->netdev->tbusy = 0; /* Unlock */
-       
-       /* Tell the network layer, that we can accept more frames */
-       mark_bh(NET_BH);
-
-       /* Restore bank */
-       outb(bank, iobase+BSR);
-}
-
-/*
- * Function pc87108_dma_receive (self)
- *
- *    Get ready for receiving a frame. The device will initiate a DMA
- *    if it starts to receive a frame.
- *
- */
-static int pc87108_dma_receive(struct pc87108 *self) 
-{
-       int iobase;
-       __u8 bsr;
-
-       ASSERT(self != NULL, return -1;);
-
-       IRDA_DEBUG(4, __FUNCTION__ "\n");
-
-       iobase = self->io.iobase;
-
-       /* Save current bank */
-       bsr = inb(iobase+BSR);
-
-       /* Disable DMA */
-       switch_bank(iobase, BANK0);
-       outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR);
-
-       self->rx_buff.data = self->rx_buff.head;
-
-       setup_dma(self->io.dma, self->rx_buff.data, 
-                 self->rx_buff.truesize, DMA_MODE_READ);
-       
-       /* driver->media_busy = FALSE; */
-       self->io.direction = IO_RECV;
-
-       /* Reset Rx FIFO. This will also flush the ST_FIFO */
-       outb(FCR_RXTH|FCR_TXTH|FCR_RXSR|FCR_FIFO_EN, iobase+FCR);
-       self->st_fifo.len = self->st_fifo.tail = self->st_fifo.head = 0;
-
-       /* Choose DMA Rx, DMA Fairness, and Advanced mode */
-       switch_bank(iobase, BANK2);
-       outb((inb(iobase+ECR1) & ~ECR1_DMASWP)|ECR1_DMANF|ECR1_EXT_SL, 
-            iobase+ECR1);
-       
-       /* enable DMA */
-       switch_bank(iobase, BANK0);
-       outb(inb(iobase+MCR)|MCR_DMA_EN, iobase+MCR);
-
-       /* Restore bank register */
-       outb(bsr, iobase+BSR);
-       
-       IRDA_DEBUG(4, __FUNCTION__ "(), done!\n");      
-       
-       return 0;
-}
-
-/*
- * Function pc87108_dma_receive_complete (self)
- *
- *    Finished with receiving frames
- *
- *    
- */
-static int pc87108_dma_receive_complete(struct pc87108 *self, int iobase)
-{
-       struct sk_buff *skb;
-       struct st_fifo *st_fifo;
-       __u8 bank;
-       __u8 status;
-       int len;
-
-       st_fifo = &self->st_fifo;
-
-       /* Save current bank */
-       bank = inb(iobase+BSR);
-       
-       /* Read status FIFO */
-       switch_bank(iobase, BANK5);
-       while ((status = inb(iobase+FRM_ST)) & FRM_ST_VLD) {
-               st_fifo->entries[st_fifo->tail].status = status;
-
-               st_fifo->entries[st_fifo->tail].len  = inb(iobase+RFLFL);
-               st_fifo->entries[st_fifo->tail].len |= inb(iobase+RFLFH) << 8;
-               
-               st_fifo->tail++;
-               st_fifo->len++;
-       }
-       
-       /* Try to process all entries in status FIFO */
-       switch_bank(iobase, BANK0);
-       while (st_fifo->len) {
-      
-               /* Get first entry */
-               status = st_fifo->entries[st_fifo->head].status;
-               len    = st_fifo->entries[st_fifo->head].len;
-               st_fifo->head++;
-               st_fifo->len--;
-
-               /* Check for errors */
-               if (status & FRM_ST_ERR_MSK) {
-                       if (status & FRM_ST_LOST_FR) {
-                               /* Add number of lost frames to stats */
-                               self->stats.rx_errors += len;   
-                       } else {
-                               /* Skip frame */
-                               self->stats.rx_errors++;
-                               
-                               self->rx_buff.data += len;
-                       
-                               if (status & FRM_ST_MAX_LEN)
-                                       self->stats.rx_length_errors++;
-                               
-                               if (status & FRM_ST_PHY_ERR) 
-                                       self->stats.rx_frame_errors++;
-                               
-                               if (status & FRM_ST_BAD_CRC) 
-                                       self->stats.rx_crc_errors++;
-                       }
-                       /* The errors below can be reported in both cases */
-                       if (status & FRM_ST_OVR1)
-                               self->stats.rx_fifo_errors++;
-                       
-                       if (status & FRM_ST_OVR2)
-                               self->stats.rx_fifo_errors++;
-                       
-               } else {
-                       /* Check if we have transfered all data to memory */
-                       if (inb(iobase+LSR) & LSR_RXDA) {
-                               /* Put this entry back in fifo */
-                               st_fifo->head--;
-                               st_fifo->len++;
-                               st_fifo->entries[st_fifo->head].status = status;
-                               st_fifo->entries[st_fifo->head].len = len;
-
-                               /* Restore bank register */
-                               outb(bank, iobase+BSR);
-                       
-                               return FALSE;   /* I'll be back! */
-                       }
-
-                       /* Should be OK then */                 
-                       skb = dev_alloc_skb(len+1);
-                       if (skb == NULL)  {
-                               printk(KERN_INFO __FUNCTION__ 
-                                       "(), memory squeeze, dropping frame.\n");
-                               /* Restore bank register */
-                               outb(bank, iobase+BSR);
-
-                               return FALSE;
-                       }
-                       
-                       /* Make sure IP header gets aligned */
-                       skb_reserve(skb, 1); 
-
-                       /* Copy frame without CRC */
-                       if (self->io.speed < 4000000) {
-                               skb_put(skb, len-2);
-                               memcpy(skb->data, self->rx_buff.data, len-2);
-                       } else {
-                               skb_put(skb, len-4);
-                               memcpy(skb->data, self->rx_buff.data, len-4);
-                       }
-
-                       /* Move to next frame */
-                       self->rx_buff.data += len;
-                       self->stats.rx_packets++;
-
-                       skb->dev = self->netdev;
-                       skb->mac.raw  = skb->data;
-                       skb->protocol = htons(ETH_P_IRDA);
-                       netif_rx(skb);
-               }
-       }
-       /* Restore bank register */
-       outb(bank, iobase+BSR);
-
-       return TRUE;
-}
-
-/*
- * Function pc87108_pio_receive (self)
- *
- *    Receive all data in receiver FIFO
- *
- */
-static void pc87108_pio_receive(struct pc87108 *self) 
-{
-       __u8 byte = 0x00;
-       int iobase;
-
-       IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-       ASSERT(self != NULL, return;);
-       
-       iobase = self->io.iobase;
-       
-       /*  Receive all characters in Rx FIFO */
-       do {
-               byte = inb(iobase+RXD);
-               async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, byte);
-       } while (inb(iobase+LSR) & LSR_RXDA); /* Data available */      
-}
-
-/*
- * Function pc87108_sir_interrupt (self, eir)
- *
- *    Handle SIR interrupt
- *
- */
-static __u8 pc87108_sir_interrupt(struct pc87108 *self, int eir)
-{
-       int actual;
-       __u8 new_ier = 0;
-
-       /* Transmit FIFO low on data */
-       if (eir & EIR_TXLDL_EV) {
-               /* Write data left in transmit buffer */
-               actual = pc87108_pio_write(self->io.iobase, 
-                                          self->tx_buff.data, 
-                                          self->tx_buff.len, 
-                                          self->io.fifo_size);
-               self->tx_buff.data += actual;
-               self->tx_buff.len  -= actual;
-               
-               self->io.direction = IO_XMIT;
-
-               /* Check if finished */
-               if (self->tx_buff.len > 0)
-                       new_ier |= IER_TXLDL_IE;
-               else { 
-                       self->netdev->tbusy = 0; /* Unlock */
-                       self->stats.tx_packets++;
-
-                       /* Check if we need to change the speed? */
-                       if (self->new_speed) {
-                               IRDA_DEBUG(2, __FUNCTION__ 
-                                          "(), Changing speed!\n");
-                               pc87108_change_speed(self, self->new_speed);
-                               self->new_speed = 0;
-                       }
-                       
-                       mark_bh(NET_BH);        
-
-                       new_ier |= IER_TXEMP_IE;
-               }
-                       
-       }
-       /* Check if transmission has completed */
-       if (eir & EIR_TXEMP_EV) {
-               /* Check if we need to change the speed? */
-               if (self->new_speed) {
-                       IRDA_DEBUG(2, __FUNCTION__ 
-                                  "(), Changing speed!\n");
-                       pc87108_change_speed(self, self->new_speed);
-                       self->new_speed = 0;
-               }
-
-               /* Turn around and get ready to receive some data */
-               self->io.direction = IO_RECV;
-               new_ier |= IER_RXHDL_IE;
-       }
-
-       /* Rx FIFO threshold or timeout */
-       if (eir & EIR_RXHDL_EV) {
-               pc87108_pio_receive(self);
-
-               /* Keep receiving */
-               new_ier |= IER_RXHDL_IE;
-       }
-       return new_ier;
-}
-
-/*
- * Function pc87108_fir_interrupt (self, eir)
- *
- *    Handle MIR/FIR interrupt
- *
- */
-static __u8 pc87108_fir_interrupt(struct pc87108 *self, int iobase,
-                                 int eir)
-{
-       __u8 new_ier = 0;
-       __u8 bank;
-
-       bank = inb(iobase+BSR);
-       
-       /* Status event, or end of frame detected in FIFO */
-       if (eir & (EIR_SFIF_EV|EIR_LS_EV)) {
-               if (pc87108_dma_receive_complete(self, iobase)) {
-
-                       /* Wait for next status FIFO interrupt */
-                       new_ier |= IER_SFIF_IE;
-               } else {
-                       /* DMA not finished yet */
-
-                       /* Set timer value, resolution 125 us */
-                       switch_bank(iobase, BANK4);
-                       outb(0x0f, iobase+TMRL); /* 125 us */
-                       outb(0x00, iobase+TMRH);
-
-                       /* Start timer */
-                       outb(IRCR1_TMR_EN, iobase+IRCR1);
-
-                       new_ier |= IER_TMR_IE;
-               }
-       }
-       /* Timer finished */
-       if (eir & EIR_TMR_EV) {
-               /* Disable timer */
-               switch_bank(iobase, BANK4);
-               outb(0, iobase+IRCR1);
-
-               /* Clear timer event */
-               switch_bank(iobase, BANK0);
-               outb(ASCR_CTE, iobase+ASCR);
-
-               /* Check if this is a TX timer interrupt */
-               if (self->io.direction == IO_XMIT) {
-                       pc87108_dma_write(self, iobase);
-
-                       /*  Interrupt on DMA */
-                       new_ier |= IER_DMA_IE;
-               } else {
-                       /* Check if DMA has now finished */
-                       pc87108_dma_receive_complete(self, iobase);
-
-                       new_ier |= IER_SFIF_IE;
-               }
-       }       
-       /* Finished with transmission */
-       if (eir & EIR_DMA_EV) {
-               pc87108_dma_xmit_complete(self);
-               
-               /* Check if there are more frames to be transmitted */
-               if (irda_device_txqueue_empty(self->netdev)) {
-                       /* Prepare for receive */
-                       pc87108_dma_receive(self);
-                       
-                       new_ier = IER_LS_IE|IER_SFIF_IE;
-               }
-       }
-       outb(bank, iobase+BSR);
-
-       return new_ier;
-}
-
-/*
- * Function pc87108_interrupt (irq, dev_id, regs)
- *
- *    An interrupt from the chip has arrived. Time to do some work
- *
- */
-static void pc87108_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct net_device *dev = (struct net_device *) dev_id;
-       struct pc87108 *self;
-       __u8 bsr, eir, ier;
-       int iobase;
-
-       if (!dev) {
-               printk(KERN_WARNING "%s: irq %d for unknown device.\n", 
-                       driver_name, irq);
-               return;
-       }
-       self = (struct pc87108 *) dev->priv;
-
-       dev->interrupt = 1;
-
-       iobase = self->io.iobase;
-
-       /* Save current bank */
-       bsr = inb(iobase+BSR);
-
-       switch_bank(iobase, BANK0);     
-       ier = inb(iobase+IER); 
-       eir = inb(iobase+EIR) & ier; /* Mask out the interesting ones */ 
-
-       outb(0, iobase+IER); /* Disable interrupts */
-       
-       if (eir) {
-               /* Dispatch interrupt handler for the current speed */
-               if (self->io.speed > 115200)
-                       ier = pc87108_fir_interrupt(self, iobase, eir);
-               else
-                       ier = pc87108_sir_interrupt(self, eir);
-       }
-
-       outb(ier, iobase+IER);   /* Restore interrupts */
-       outb(bsr, iobase+BSR);   /* Restore bank register */
-
-       dev->interrupt = 0;
-}
-
-/*
- * Function pc87108_is_receiving (self)
- *
- *    Return TRUE is we are currently receiving a frame
- *
- */
-static int pc87108_is_receiving(struct pc87108 *self)
-{
-       int status = FALSE;
-       int iobase;
-       __u8 bank;
-
-       ASSERT(self != NULL, return FALSE;);
-
-       if (self->io.speed > 115200) {
-               iobase = self->io.iobase;
-
-               /* Check if rx FIFO is not empty */
-               bank = inb(iobase+BSR);
-               switch_bank(iobase, BANK2);
-               if ((inb(iobase+RXFLV) & 0x3f) != 0) {
-                       /* We are receiving something */
-                       status =  TRUE;
-               }
-               outb(bank, iobase+BSR);
-       } else 
-               status = (self->rx_buff.state != OUTSIDE_FRAME);
-       
-       return status;
-}
-
-/*
- * Function pc87108_net_init (dev)
- *
- *    Initialize network device
- *
- */
-static int pc87108_net_init(struct net_device *dev)
-{
-       IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-       /* Setup to be a normal IrDA network device driver */
-       irda_device_setup(dev);
-
-       /* Insert overrides below this line! */
-
-       return 0;
-}
-
-
-/*
- * Function pc87108_net_open (dev)
- *
- *    Start the device
- *
- */
-static int pc87108_net_open(struct net_device *dev)
-{
-       struct pc87108 *self;
-       int iobase;
-       __u8 bank;
-       
-       IRDA_DEBUG(4, __FUNCTION__ "()\n");
-       
-       ASSERT(dev != NULL, return -1;);
-       self = (struct pc87108 *) dev->priv;
-       
-       ASSERT(self != NULL, return 0;);
-       
-       iobase = self->io.iobase;
-
-       if (request_irq(self->io.irq, pc87108_interrupt, 0, dev->name, 
-                       (void *) dev)) 
-       {
-               return -EAGAIN;
-       }
-       /*
-        * Always allocate the DMA channel after the IRQ,
-        * and clean up on failure.
-        */
-       if (request_dma(self->io.dma, dev->name)) {
-               free_irq(self->io.irq, self);
-               return -EAGAIN;
-       }
-       
-       /* Save current bank */
-       bank = inb(iobase+BSR);
-       
-       /* turn on interrupts */
-       switch_bank(iobase, BANK0);
-       outb(IER_LS_IE | IER_RXHDL_IE, iobase+IER);
-
-       /* Restore bank register */
-       outb(bank, iobase+BSR);
-
-       /* Ready to play! */
-       dev->tbusy = 0;
-       dev->interrupt = 0;
-       dev->start = 1;
-
-       /* 
-        * Open new IrLAP layer instance, now that everything should be
-        * initialized properly 
-        */
-       self->irlap = irlap_open(dev, &self->qos);
-
-       MOD_INC_USE_COUNT;
-
-       return 0;
-}
-
-/*
- * Function pc87108_net_close (dev)
- *
- *    Stop the device
- *
- */
-static int pc87108_net_close(struct net_device *dev)
-{
-       struct pc87108 *self;
-       int iobase;
-       __u8 bank;
-
-       IRDA_DEBUG(4, __FUNCTION__ "()\n");
-       
-       ASSERT(dev != NULL, return -1;);
-       self = (struct pc87108 *) dev->priv;
-       
-       ASSERT(self != NULL, return 0;);
-
-       /* Stop device */
-       dev->tbusy = 1;
-       dev->start = 0;
-
-       /* Stop and remove instance of IrLAP */
-       if (self->irlap)
-               irlap_close(self->irlap);
-       self->irlap = NULL;
-       
-       iobase = self->io.iobase;
-
-       disable_dma(self->io.dma);
-
-       /* Save current bank */
-       bank = inb(iobase+BSR);
-
-       /* Disable interrupts */
-       switch_bank(iobase, BANK0);
-       outb(0, iobase+IER); 
-       
-       free_irq(self->io.irq, dev);
-       free_dma(self->io.dma);
-
-       /* Restore bank register */
-       outb(bank, iobase+BSR);
-
-       MOD_DEC_USE_COUNT;
-
-       return 0;
-}
-
-/*
- * Function pc87108_net_ioctl (dev, rq, cmd)
- *
- *    Process IOCTL commands for this device
- *
- */
-static int pc87108_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-       struct if_irda_req *irq = (struct if_irda_req *) rq;
-       struct pc87108 *self;
-       unsigned long flags;
-       int ret = 0;
-
-       ASSERT(dev != NULL, return -1;);
-
-       self = dev->priv;
-
-       ASSERT(self != NULL, return -1;);
-
-       IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
-       
-       /* Disable interrupts & save flags */
-       save_flags(flags);
-       cli();
-       
-       switch (cmd) {
-       case SIOCSBANDWIDTH: /* Set bandwidth */
-               pc87108_change_speed(self, irq->ifr_baudrate);
-               break;
-       case SIOCSMEDIABUSY: /* Set media busy */
-               irda_device_set_media_busy(self->netdev, TRUE);
-               break;
-       case SIOCGRECEIVING: /* Check if we are receiving right now */
-               irq->ifr_receiving = pc87108_is_receiving(self);
-               break;
-       default:
-               ret = -EOPNOTSUPP;
-       }
-       
-       restore_flags(flags);
-       
-       return ret;
-}
-
-#ifdef MODULE
-
-MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
-MODULE_DESCRIPTION("NSC PC87108 IrDA Device Driver");
-
-MODULE_PARM(qos_mtt_bits, "i");
-MODULE_PARM(io, "1-4i");
-MODULE_PARM(io2, "1-4i");
-MODULE_PARM(irq, "1-4i");
-
-/*
- * Function init_module (void)
- *
- *    
- *
- */
-int init_module(void)
-{
-       return pc87108_init();
-}
-
-/*
- * Function cleanup_module (void)
- *
- *    
- *
- */
-void cleanup_module(void)
-{
-       pc87108_cleanup();
-}
-#endif /* MODULE */
-
index 6c96ef73d1d5d4c1a84ebbd2bbc0106e2c3a685f..1d857c2b064c514e699cdbd32e2c7675f21bf4a6 100644 (file)
@@ -1,26 +1,35 @@
 /*********************************************************************
  *                
  * Filename:      smc-ircc.c
- * Version:       0.1
- * Description:   Driver for the SMC Infrared Communications Controller (SMC)
+ * Version:       0.3
+ * Description:   Driver for the SMC Infrared Communications Controller
  * Status:        Experimental.
  * Author:        Thomas Davis (tadavis@jps.net)
  * Created at:    
- * Modified at:   Sat Dec 11 14:38:26 1999
+ * Modified at:   Wed Jan  5 12:38:06 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998-1999 Thomas Davis, All Rights Reserved.
+ *     Copyright (c) 1999-2000 Dag Brattli
+ *     Copyright (c) 1998-1999 Thomas Davis, 
+ *     All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
- *  
- *     I, Thomas Davis, admit no liability nor provide warranty for any
- *     of this software. This material is provided "AS-IS" and at no charge.
+ * 
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *     GNU General Public License for more details.
+ * 
+ *     You should have received a copy of the GNU General Public License 
+ *     along with this program; if not, write to the Free Software 
+ *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ *     MA 02111-1307 USA
  *
- *     Applicable Models : Fujitsu Lifebook 635t
- *                        Sony PCG-505TX (gets DMA wrong.)
+ *     SIO's: SMC FDC37N869, FDC37C669
+ *     Applicable Models : Fujitsu Lifebook 635t, Sony PCG-505TX
  *
  ********************************************************************/
 
@@ -53,8 +62,8 @@ static char *driver_name = "smc-ircc";
 
 #define CHIP_IO_EXTENT 8
 
-static unsigned int io[]  = { 0x2e8, 0x140, 0x118, ~0 }; 
-static unsigned int io2[] = { 0x2f8, 0x3e8, 0x2e8, 0};
+static unsigned int io[]  = { 0x2e8, 0x140, 0x118, 0x240 }; 
+static unsigned int io2[] = { 0x2f8, 0x3e8, 0x2e8, 0x3e8 };
 
 static struct ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL};
 
@@ -64,10 +73,11 @@ static int  ircc_open(int i, unsigned int iobase, unsigned int board_addr);
 static int  ircc_close(struct ircc_cb *self);
 #endif /* MODULE */
 static int  ircc_probe(int iobase, int board_addr);
+static int  ircc_probe_smc(int *ioaddr, int *ioaddr2);
 static int  ircc_dma_receive(struct ircc_cb *self); 
 static int  ircc_dma_receive_complete(struct ircc_cb *self, int iobase);
 static int  ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev);
-static void ircc_dma_write(struct ircc_cb *self, int iobase);
+static void ircc_dma_xmit(struct ircc_cb *self, int iobase);
 static void ircc_change_speed(void *priv, __u32 speed);
 static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int  ircc_is_receiving(struct ircc_cb *self);
@@ -75,24 +85,13 @@ static int  ircc_is_receiving(struct ircc_cb *self);
 static int  ircc_net_open(struct net_device *dev);
 static int  ircc_net_close(struct net_device *dev);
 
-static int ircc_debug=3;
 static int ircc_irq=255;
 static int ircc_dma=255;
 
-static inline void register_bank(int port, int bank)
-{
-        outb(((inb(port+UART_MASTER) & 0xF0) | (bank & 0x07)),
-             port+UART_MASTER);
-}
-
-static inline unsigned int serial_in(int port, int offset)
+static inline void register_bank(int iobase, int bank)
 {
-        return inb(port+offset);
-}
-
-static inline void serial_out(int port, int offset, int value)
-{
-        outb(value, port+offset);
+        outb(((inb(iobase+IRCC_MASTER) & 0xf0) | (bank & 0x07)),
+               iobase+IRCC_MASTER);
 }
 
 /*
@@ -103,9 +102,10 @@ static inline void serial_out(int port, int offset, int value)
  */
 int __init ircc_init(void)
 {
+       int ioaddr, ioaddr2;
        int i;
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(0, __FUNCTION__ "\n");
        for (i=0; (io[i] < 2000) && (i < 4); i++) {
                int ioaddr = io[i];
                if (check_region(ioaddr, CHIP_IO_EXTENT))
@@ -113,7 +113,13 @@ int __init ircc_init(void)
                if (ircc_open(i, io[i], io2[i]) == 0)
                        return 0;
        }
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
+
+       /* last chance saloon, see what the controller says */
+       if (ircc_probe_smc(&ioaddr, &ioaddr2) == 0) {
+                  if (check_region(ioaddr, CHIP_IO_EXTENT) == 0)
+                          if (ircc_open(0, ioaddr, ioaddr2) == 0)
+                                  return 0; 
+       }
 
        return -ENODEV;
 }
@@ -129,13 +135,12 @@ static void ircc_cleanup(void)
 {
        int i;
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(0, __FUNCTION__ "\n");
 
        for (i=0; i < 4; i++) {
                if (dev_self[i])
                        ircc_close(dev_self[i]);
        }
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 }
 #endif /* MODULE */
 
@@ -152,11 +157,11 @@ static int ircc_open(int i, unsigned int iobase, unsigned int iobase2)
        int config;
        int ret;
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(0, __FUNCTION__ "\n");
 
        if ((config = ircc_probe(iobase, iobase2)) == -1) {
-               IRDA_DEBUG(ircc_debug, 
-                     __FUNCTION__ ": addr 0x%04x - no device found!\n", iobase);
+               IRDA_DEBUG(0, __FUNCTION__ 
+                          "(), addr 0x%04x - no device found!\n", iobase);
                return -1;
        }
        
@@ -165,11 +170,12 @@ static int ircc_open(int i, unsigned int iobase, unsigned int iobase2)
         */
        self = kmalloc(sizeof(struct ircc_cb), GFP_KERNEL);
        if (self == NULL) {
-               printk(KERN_ERR "IrDA: Can't allocate memory for "
-                       "IrDA control block!\n");
+               ERROR("%s, Can't allocate memory for control block!\n",
+                      driver_name);
                return -ENOMEM;
        }
        memset(self, 0, sizeof(struct ircc_cb));
+       spin_lock_init(&self->lock);
    
        /* Need to store self somewhere */
        dev_self[i] = self;
@@ -188,16 +194,16 @@ static int ircc_open(int i, unsigned int iobase, unsigned int iobase2)
         self->io.iobase2   = iobase2; /* Used by irport */
         self->io.irq       = config >> 4 & 0x0f;
        if (ircc_irq < 255) {
-               MESSAGE("smc_ircc: Overriding IRQ - chip says %d, using %d\n",
-                       self->io.irq, ircc_irq);
+               MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n",
+                       driver_name, self->io.irq, ircc_irq);
                self->io.irq = ircc_irq;
        }
         self->io.io_ext    = CHIP_IO_EXTENT;
         self->io.io_ext2   = 8;       /* Used by irport */
         self->io.dma       = config & 0x0f;
        if (ircc_dma < 255) {
-               MESSAGE("smc: Overriding DMA - chip says %d, using %d\n",
-                       self->io.dma, ircc_dma);
+               MESSAGE("%s, Overriding DMA - chip says %d, using %d\n",
+                       driver_name, self->io.dma, ircc_dma);
                self->io.dma = ircc_dma;
        }
         self->io.fifo_size = 16;
@@ -206,7 +212,7 @@ static int ircc_open(int i, unsigned int iobase, unsigned int iobase2)
        ret = check_region(self->io.iobase, self->io.io_ext);
        if (ret < 0) { 
                IRDA_DEBUG(0, __FUNCTION__ ": can't get iobase of 0x%03x\n",
-                      self->io.iobase);
+                          self->io.iobase);
                /* ircc_cleanup(self->self);  */
                return -ENODEV;
        }
@@ -214,17 +220,11 @@ static int ircc_open(int i, unsigned int iobase, unsigned int iobase2)
        request_region(self->io.iobase, self->io.io_ext, driver_name);
 
        /* Initialize QoS for this device */
-       irda_init_max_qos_capabilies(&self->qos);
+       irda_init_max_qos_capabilies(&irport->qos);
        
-#if 1
        /* The only value we must override it the baudrate */
-       self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
+       irport->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
                IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);
-#else
-       /* The only value we must override it the baudrate */
-       self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
-               IR_115200;
-#endif
 
        irport->qos.min_turn_time.bits = 0x07;
        irda_qos_bits_to_value(&irport->qos);
@@ -235,23 +235,19 @@ static int ircc_open(int i, unsigned int iobase, unsigned int iobase2)
        self->rx_buff.truesize = 4000; 
        self->tx_buff.truesize = 4000;
 
-       /* Allocate memory if needed */
-       if (self->rx_buff.truesize > 0) {
-               self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
-                                                     GFP_KERNEL|GFP_DMA);
-               if (self->rx_buff.head == NULL)
-                       return -ENOMEM;
-               memset(self->rx_buff.head, 0, self->rx_buff.truesize);
-       }
-       if (self->tx_buff.truesize > 0) {
-               self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
-                                                     GFP_KERNEL|GFP_DMA);
-               if (self->tx_buff.head == NULL) {
-                       kfree(self->rx_buff.head);
-                       return -ENOMEM;
-               }
-               memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+       self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
+                                             GFP_KERNEL|GFP_DMA);
+       if (self->rx_buff.head == NULL)
+               return -ENOMEM;
+       memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+       
+       self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
+                                             GFP_KERNEL|GFP_DMA);
+       if (self->tx_buff.head == NULL) {
+               kfree(self->rx_buff.head);
+               return -ENOMEM;
        }
+       memset(self->tx_buff.head, 0, self->tx_buff.truesize);
 
        self->rx_buff.in_frame = FALSE;
        self->rx_buff.state = OUTSIDE_FRAME;
@@ -260,12 +256,11 @@ static int ircc_open(int i, unsigned int iobase, unsigned int iobase2)
        
        /* Override the speed change function, since we must control it now */
        irport->change_speed = &ircc_change_speed;
-       self->netdev->open  = &ircc_net_open;
-       self->netdev->stop = &ircc_net_close;
+       self->netdev->open   = &ircc_net_open;
+       self->netdev->stop   = &ircc_net_close;
 
        irport_start(self->irport);
 
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
        return 0;
 }
 
@@ -280,7 +275,7 @@ static int ircc_close(struct ircc_cb *self)
 {
        int iobase;
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(0, __FUNCTION__ "\n");
 
        ASSERT(self != NULL, return -1;);
 
@@ -289,18 +284,16 @@ static int ircc_close(struct ircc_cb *self)
        irport_close(self->irport);
 
        register_bank(iobase, 0);
-       serial_out(iobase, UART_IER, 0);
-       serial_out(iobase, UART_MASTER, UART_MASTER_RESET);
+       outb(0, iobase+IRCC_IER);
+       outb(IRCC_MASTER_RESET, iobase+IRCC_MASTER);
 
        register_bank(iobase, 1);
 
-        serial_out(iobase, UART_SCE_CFGA, 
-                  UART_CFGA_IRDA_SIR_A | UART_CFGA_TX_POLARITY);
-        serial_out(iobase, UART_SCE_CFGB, UART_CFGB_IR);
+        outb(IRCC_CFGA_IRDA_SIR_A|IRCC_CFGA_TX_POLARITY, iobase+IRCC_SCE_CFGA);
+        outb(IRCC_CFGB_IR, iobase+IRCC_SCE_CFGB);
  
        /* Release the PORT that this driver is using */
-       IRDA_DEBUG(ircc_debug, 
-              __FUNCTION__ ": releasing 0x%03x\n", self->io.iobase);
+       IRDA_DEBUG(0, __FUNCTION__ "(), releasing 0x%03x\n", self->io.iobase);
 
        release_region(self->io.iobase, self->io.io_ext);
 
@@ -312,12 +305,66 @@ static int ircc_close(struct ircc_cb *self)
 
        kfree(self);
 
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
-
        return 0;
 }
 #endif /* MODULE */
 
+/*
+ * Function ircc_probe_smc (ioaddr, ioaddr2)
+ *
+ *    Probe the SMC Chip for an IrDA port
+ *
+ */
+static int ircc_probe_smc(int *ioaddr, int *ioaddr2)
+{
+        static int smcreg[] = { 0x3f0, 0x370 };
+       __u8 devid, mode;
+       __u8 conf_reg;
+       int ret = -1;
+       int fir_io;
+        int i;
+       
+       IRDA_DEBUG(0, __FUNCTION__ "()\n");
+
+        for (i = 0; i < 2 && ret == -1; i++) {
+               conf_reg = smcreg[i];
+        
+               /* Enter configuration */
+                outb(0x55, conf_reg);
+                outb(0x55, conf_reg);
+    
+               outb(0x0d, conf_reg);
+               devid = inb(conf_reg+1);
+               IRDA_DEBUG(0, __FUNCTION__ "(), devid=0x%02x\n",devid);
+               
+               /* Check for expected device ID; are there others? */
+               if (devid == 0x29) {    
+                       outb(0x0c, conf_reg);
+                       mode = inb(conf_reg+1);
+                       mode = (mode & 0x38) >> 3;
+
+                       /* Value for IR port */
+                       if (mode && mode < 4) {
+                               /* SIR iobase */
+                               outb(0x25, conf_reg);
+                               *ioaddr2 = inb(conf_reg+1) << 2;
+
+                               /* FIR iobase */
+                               outb(0x2b, conf_reg);
+                               fir_io = inb(conf_reg+1) << 3;
+                               if (fir_io) {
+                                       ret = 0;
+                                       *ioaddr = fir_io;
+                               }
+                       }
+               }
+
+               /* Exit configuration */
+               outb(0xaa, conf_reg);
+        }
+       return ret;
+}
+
 /*
  * Function ircc_probe (iobase, board_addr, irq, dma)
  *
@@ -329,14 +376,18 @@ static int ircc_probe(int iobase, int iobase2)
        int version = 1;
        int low, high, chip, config, dma, irq;
        
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(0, __FUNCTION__ "\n");
+
+       /* Power on device */
+       outb(inb(iobase+IRCC_MASTER) & ~IRCC_MASTER_POWERDOWN, 
+            iobase+IRCC_MASTER);
 
        register_bank(iobase, 3);
-       high = serial_in(iobase, UART_ID_HIGH);
-       low = serial_in(iobase, UART_ID_LOW);
-       chip = serial_in(iobase, UART_CHIP_ID);
-       version = serial_in(iobase, UART_VERSION);
-       config = serial_in(iobase, UART_INTERFACE);
+       high = inb(iobase+IRCC_ID_HIGH);
+       low = inb(iobase+IRCC_ID_LOW);
+       chip = inb(iobase+IRCC_CHIP_ID);
+       version = inb(iobase+IRCC_VERSION);
+       config = inb(iobase+IRCC_INTERFACE);
        irq = config >> 4 & 0x0f;
        dma = config & 0x0f;
 
@@ -344,13 +395,10 @@ static int ircc_probe(int iobase, int iobase2)
                 IRDA_DEBUG(0, "SMC IrDA Controller found; IrCC version %d.%d, "
                      "port 0x%04x, dma %d, interrupt %d\n",
                       chip & 0x0f, version, iobase, dma, irq);
-       } else {
+       } else
                return -1;
-       }
 
-       serial_out(iobase, UART_MASTER, 0);
-
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
+       outb(0, iobase+IRCC_MASTER);
 
        return config;
 }
@@ -367,7 +415,7 @@ static void ircc_change_speed(void *priv, __u32 speed)
        struct ircc_cb *self = (struct ircc_cb *) priv;
        struct net_device *dev;
 
-       IRDA_DEBUG(ircc_debug+1, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(0, __FUNCTION__ "\n");
 
        ASSERT(self != NULL, return;);
 
@@ -380,16 +428,16 @@ static void ircc_change_speed(void *priv, __u32 speed)
        switch (speed) {
        case 9600:
        case 19200:
-       case 37600:
+       case 38400:
        case 57600:
        case 115200:
-               IRDA_DEBUG(ircc_debug+1, 
-                     __FUNCTION__ ": using irport to change speed to %d\n",
-                     speed);
+               IRDA_DEBUG(0, __FUNCTION__ 
+                          "(), using irport to change speed to %d\n", speed);
+
                register_bank(iobase, 0);
-               serial_out(iobase, UART_IER, 0);
-               serial_out(iobase, UART_MASTER, UART_MASTER_RESET);
-               serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN);
+               outb(0, iobase+IRCC_IER);
+               outb(IRCC_MASTER_RESET, iobase+IRCC_MASTER);
+               outb(IRCC_MASTER_INT_EN, iobase+IRCC_MASTER);
 
                dev->hard_start_xmit = &irport_hard_xmit;
 
@@ -400,27 +448,23 @@ static void ircc_change_speed(void *priv, __u32 speed)
                irport_change_speed(self->irport, speed);
                return;
                break;
-
        case 576000:            
-               ir_mode = UART_CFGA_IRDA_HDLC;
+               ir_mode = IRCC_CFGA_IRDA_HDLC;
                select = 0;
                fast = 0;
-               IRDA_DEBUG(ircc_debug, __FUNCTION__ 
-                          "(), handling baud of 576000\n");
+               IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n");
                break;
        case 1152000:
-               ir_mode = UART_CFGA_IRDA_HDLC;
-               select = UART_1152;
+               ir_mode = IRCC_CFGA_IRDA_HDLC;
+               select = IRCC_1152;
                fast = 0;
-               IRDA_DEBUG(ircc_debug, __FUNCTION__ 
-                          "(), handling baud of 1152000\n");
+               IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n");
                break;
        case 4000000:
-               ir_mode = UART_CFGA_IRDA_4PPM;
+               ir_mode = IRCC_CFGA_IRDA_4PPM;
                select = 0;
-               fast = UART_LCR_A_FAST;
-               IRDA_DEBUG(ircc_debug, __FUNCTION__ 
-                          "(), handling baud of 4000000\n");
+               fast = IRCC_LCR_A_FAST;
+               IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n");
                break;
        default:
                IRDA_DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", 
@@ -428,14 +472,10 @@ static void ircc_change_speed(void *priv, __u32 speed)
                return;
        }
 
-#if 0
-       serial_out(self->io.iobase2, 4, 0x08);
-#endif
-
-       serial_out(iobase, UART_MASTER, UART_MASTER_RESET);
+       outb(IRCC_MASTER_RESET, iobase+IRCC_MASTER);
 
        register_bank(iobase, 0);
-       serial_out(iobase, UART_IER, 0);
+       outb(0, iobase+IRCC_IER);
        
                irport_stop(self->irport);      
 
@@ -448,27 +488,23 @@ static void ircc_change_speed(void *priv, __u32 speed)
        dev->tbusy = 0;
        
        register_bank(iobase, 1);
+       outb(((inb(iobase+IRCC_SCE_CFGA) & 0x87) | ir_mode), 
+            iobase+IRCC_SCE_CFGA);
+       
+       outb(((inb(iobase+IRCC_SCE_CFGB) & 0x3f) | IRCC_CFGB_IR), 
+            iobase+IRCC_SCE_CFGB);
 
-       serial_out(iobase, UART_SCE_CFGA, 
-                  ((serial_in(iobase, UART_SCE_CFGA) & 0x87) | ir_mode));
-
-       serial_out(iobase, UART_SCE_CFGB,
-                  ((serial_in(iobase, UART_SCE_CFGB) & 0x3f) | UART_CFGB_IR));
-
-       (void) serial_in(iobase, UART_FIFO_THRESHOLD);
-       serial_out(iobase, UART_FIFO_THRESHOLD, 64);
+       (void) inb(iobase+IRCC_FIFO_THRESHOLD);
+       outb(64, iobase+IRCC_FIFO_THRESHOLD);
 
        register_bank(iobase, 4);
 
-       serial_out(iobase, UART_CONTROL,
-                  (serial_in(iobase, UART_CONTROL) & 0x30) 
-                  | select | UART_CRC );
+       outb((inb(iobase+IRCC_CONTROL) & 0x30) | select | IRCC_CRC, 
+            iobase+IRCC_CONTROL);
 
        register_bank(iobase, 0);
 
-       serial_out(iobase, UART_LCR_A, fast);
-
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
+       outb(fast, iobase+IRCC_LCR_A);
 }
 
 /*
@@ -485,7 +521,6 @@ static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev)
        int mtt;
        __u32 speed;
 
-       IRDA_DEBUG(ircc_debug+1, __FUNCTION__ " -->\n");
        irport = (struct irport_cb *) dev->priv;
        self = (struct ircc_cb *) irport->priv;
 
@@ -493,15 +528,13 @@ static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 
        iobase = self->io.iobase;
 
-       IRDA_DEBUG(ircc_debug+1, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies,
+       IRDA_DEBUG(2, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies,
                   (int) skb->len);
 
        /* Check if we need to change the speed */
        if ((speed = irda_get_speed(skb)) != self->io.speed)
                self->new_speed = speed;
        
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ ": using dma; len=%d\n", skb->len);
-
        /* Lock transmit buffer */
        if (irda_lock((void *) &dev->tbusy) == FALSE)
                return -EBUSY;
@@ -514,21 +547,15 @@ static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 
        self->tx_buff.len = skb->len;
        self->tx_buff.data = self->tx_buff.head;
-#if 0
-       self->tx_buff.offset = 0;
-#endif
        
-       mtt = irda_get_mtt(skb);
-       
-       /* Use udelay for delays less than 50 us. */
+       mtt = irda_get_mtt(skb);        
        if (mtt)
                udelay(mtt);
        
-       ircc_dma_write(self, iobase);
+       ircc_dma_xmit(self, iobase);
        
        dev_kfree_skb(skb);
 
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
        return 0;
 }
 
@@ -538,48 +565,44 @@ static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev)
  *    Transmit data using DMA
  *
  */
-static void ircc_dma_write(struct ircc_cb *self, int iobase)
+static void ircc_dma_xmit(struct ircc_cb *self, int iobase)
 {
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(2, __FUNCTION__ "\n");
 
        ASSERT(self != NULL, return;);
 
        iobase = self->io.iobase;
 
        setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, 
-                  DMA_MODE_WRITE);
+                 DMA_TX_MODE);
        
        self->io.direction = IO_XMIT;
 
-       serial_out(self->io.iobase2, 4, 0x08);
-
+       outb(0x08, self->io.iobase2+4);
+       
        register_bank(iobase, 4);
-       serial_out(iobase, UART_CONTROL, 
-                  (serial_in(iobase, UART_CONTROL) & 0xF0));
-
-       serial_out(iobase, UART_BOF_COUNT_LO, 2);
-       serial_out(iobase, UART_BRICKWALL_CNT_LO, 0);
+       outb((inb(iobase+IRCC_CONTROL) & 0xf0), iobase+IRCC_CONTROL);
+       
+       outb(2, iobase+IRCC_BOF_COUNT_LO);
+       outb(0, iobase+IRCC_BRICKWALL_CNT_LO);
 #if 1
-       serial_out(iobase, UART_BRICKWALL_TX_CNT_HI, self->tx_buff.len >> 8);
-       serial_out(iobase, UART_TX_SIZE_LO, self->tx_buff.len & 0xff);
+       outb(self->tx_buff.len >> 8, iobase+IRCC_BRICKWALL_TX_CNT_HI);
+       outb(self->tx_buff.len & 0xff, iobase+IRCC_TX_SIZE_LO);
 #else
-       serial_out(iobase, UART_BRICKWALL_TX_CNT_HI, 0);
-       serial_out(iobase, UART_TX_SIZE_LO, 0);
+       outb(0, iobase+IRCC_BRICKWALL_TX_CNT_HI);
+       outb(0, iobase+IRCC_TX_SIZE_LO);
 #endif
 
        register_bank(iobase, 1);
-       serial_out(iobase, UART_SCE_CFGB,
-                  serial_in(iobase, UART_SCE_CFGB) | UART_CFGB_DMA_ENABLE);
+       outb(inb(iobase+IRCC_SCE_CFGB) | IRCC_CFGB_DMA_ENABLE,
+            iobase+IRCC_SCE_CFGB);
 
        register_bank(iobase, 0);
 
-       serial_out(iobase, UART_IER, UART_IER_ACTIVE_FRAME | UART_IER_EOM);
-       serial_out(iobase, UART_LCR_B,
-                  UART_LCR_B_SCE_TRANSMIT|UART_LCR_B_SIP_ENABLE);
-
-       serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN);
+       outb(IRCC_IER_ACTIVE_FRAME | IRCC_IER_EOM, iobase+IRCC_IER);
+       outb(IRCC_LCR_B_SCE_TRANSMIT|IRCC_LCR_B_SIP_ENABLE, iobase+IRCC_LCR_B);
 
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
+       outb(IRCC_MASTER_INT_EN, iobase+IRCC_MASTER);
 }
 
 /*
@@ -593,20 +616,20 @@ static void ircc_dma_xmit_complete(struct ircc_cb *self, int underrun)
 {
        int iobase, d;
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(2, __FUNCTION__ "\n");
 
        ASSERT(self != NULL, return;);
 
        register_bank(self->io.iobase, 1);
 
-       serial_out(self->io.iobase, UART_SCE_CFGB,
-                  serial_in(self->io.iobase, UART_SCE_CFGB) &
-                  ~UART_CFGB_DMA_ENABLE);
+       outb(inb(self->io.iobase+IRCC_SCE_CFGB) & IRCC_CFGB_DMA_ENABLE,
+            self->io.iobase+IRCC_SCE_CFGB);
 
        d = get_dma_residue(self->io.dma);
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ ": dma residue = %d, len=%d, sent=%d\n", 
-             d, self->tx_buff.len, self->tx_buff.len - d);
+       IRDA_DEBUG(0, __FUNCTION__ 
+                  ": dma residue = %d, len=%d, sent=%d\n", 
+                  d, self->tx_buff.len, self->tx_buff.len - d);
 
        iobase = self->io.iobase;
 
@@ -630,8 +653,6 @@ static void ircc_dma_xmit_complete(struct ircc_cb *self, int underrun)
        
        /* Tell the network layer, that we can accept more frames */
        mark_bh(NET_BH);
-
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 }
 
 /*
@@ -645,14 +666,14 @@ static int ircc_dma_receive(struct ircc_cb *self)
 {
        int iobase;
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(2, __FUNCTION__ "\n");
 
        ASSERT(self != NULL, return -1;);
 
        iobase= self->io.iobase;
 
        setup_dma(self->io.dma, self->rx_buff.data, self->rx_buff.truesize, 
-                  DMA_MODE_READ);
+                  DMA_RX_MODE);
        
        /* driver->media_busy = FALSE; */
        self->io.direction = IO_RECV;
@@ -662,25 +683,22 @@ static int ircc_dma_receive(struct ircc_cb *self)
 #endif
 
        register_bank(iobase, 4);
-       serial_out(iobase, UART_CONTROL, 
-                  (serial_in(iobase, UART_CONTROL) &0xF0));
-       serial_out(iobase, UART_BOF_COUNT_LO, 2);
-       serial_out(iobase, UART_BRICKWALL_CNT_LO, 0);
-       serial_out(iobase, UART_BRICKWALL_TX_CNT_HI, 0);
-       serial_out(iobase, UART_TX_SIZE_LO, 0);
-       serial_out(iobase, UART_RX_SIZE_HI, 0);
-       serial_out(iobase, UART_RX_SIZE_LO, 0);
+       outb(inb(iobase+IRCC_CONTROL) & 0xf0, iobase+IRCC_CONTROL);
+       outb(2, iobase+IRCC_BOF_COUNT_LO);
+       outb(0, iobase+IRCC_BRICKWALL_CNT_LO);
+       outb(0, iobase+IRCC_BRICKWALL_TX_CNT_HI);
+       outb(0, iobase+IRCC_TX_SIZE_LO);
+       outb(0, iobase+IRCC_RX_SIZE_HI);
+       outb(0, iobase+IRCC_RX_SIZE_LO);
 
        register_bank(iobase, 0);
-       serial_out(iobase
-                  UART_LCR_B, UART_LCR_B_SCE_RECEIVE | UART_LCR_B_SIP_ENABLE);
+       outb(IRCC_LCR_B_SCE_RECEIVE | IRCC_LCR_B_SIP_ENABLE
+            iobase+IRCC_LCR_B);
        
        register_bank(iobase, 1);
-       serial_out(iobase, UART_SCE_CFGB,
-                  serial_in(iobase, UART_SCE_CFGB) | 
-                  UART_CFGB_DMA_ENABLE | UART_CFGB_DMA_BURST);
+       outb(inb(iobase+IRCC_SCE_CFGB) | IRCC_CFGB_DMA_ENABLE | 
+            IRCC_CFGB_DMA_BURST, iobase+IRCC_SCE_CFGB);
 
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
        return 0;
 }
 
@@ -696,22 +714,20 @@ static int ircc_dma_receive_complete(struct ircc_cb *self, int iobase)
        struct sk_buff *skb;
        int len, msgcnt;
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(2, __FUNCTION__ "\n");
 
-       msgcnt = serial_in(self->io.iobase, UART_LCR_B) & 0x08;
+       msgcnt = inb(self->io.iobase+IRCC_LCR_B) & 0x08;
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n",
-             get_dma_residue(self->io.dma));
+       IRDA_DEBUG(0, __FUNCTION__ ": dma count = %d\n",
+                  get_dma_residue(self->io.dma));
 
        len = self->rx_buff.truesize - get_dma_residue(self->io.dma) - 4;
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ ": msgcnt = %d, len=%d\n", msgcnt, len);
+       IRDA_DEBUG(0, __FUNCTION__ ": msgcnt = %d, len=%d\n", msgcnt, len);
 
        skb = dev_alloc_skb(len+1);
-
-       if (skb == NULL)  {
-               printk(KERN_INFO __FUNCTION__ 
-                       ": memory squeeze, dropping frame.\n");
+       if (!skb)  {
+               WARNING(__FUNCTION__ "(), memory squeeze, dropping frame.\n");
                return FALSE;
        }
                        
@@ -728,11 +744,9 @@ static int ircc_dma_receive_complete(struct ircc_cb *self, int iobase)
        netif_rx(skb);
 
        register_bank(self->io.iobase, 1);
-       serial_out(self->io.iobase, UART_SCE_CFGB,
-                  serial_in(self->io.iobase, UART_SCE_CFGB) &
-                  ~UART_CFGB_DMA_ENABLE);
+       outb(inb(self->io.iobase+IRCC_SCE_CFGB) & ~IRCC_CFGB_DMA_ENABLE, 
+            self->io.iobase+IRCC_SCE_CFGB);
 
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
        return TRUE;
 }
 
@@ -748,11 +762,9 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        struct net_device *dev = (struct net_device *) dev_id;
        struct ircc_cb *self;
 
-       IRDA_DEBUG(ircc_debug+1, __FUNCTION__ " -->\n");
-
        if (dev == NULL) {
                printk(KERN_WARNING "%s: irq %d for unknown device.\n", 
-                       driver_name, irq);
+                      driver_name, irq);
                return;
        }
        
@@ -762,45 +774,42 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        dev->interrupt = 1;
 
-       serial_out(iobase, UART_MASTER, 0);
+       outb(0, iobase+IRCC_MASTER);
 
        register_bank(iobase, 0);
+       iir = inb(iobase+IRCC_IIR);
 
-       iir = serial_in(iobase, UART_IIR);
+       /* Disable interrupts */
+       outb(0, iobase+IRCC_IER);
 
-       serial_out(iobase, UART_IER, 0);
+       IRDA_DEBUG(0, __FUNCTION__ "(), iir = 0x%02x\n", iir);
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ ": iir = 0x%02x\n", iir);
+       if (iir & IRCC_IIR_EOM) {
+               IRDA_DEBUG(0, __FUNCTION__ "(), IRCC_IIR_EOM\n");
 
-       if (iir & UART_IIR_EOM) {
-               IRDA_DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_EOM\n");
-               if (self->io.direction == IO_RECV) {
+               if (self->io.direction == IO_RECV)
                        ircc_dma_receive_complete(self, iobase);
-               } else {
+               else
                        ircc_dma_xmit_complete(self, iobase);
-               }
+               
                ircc_dma_receive(self);
        }
-
-       if (iir & UART_IIR_ACTIVE_FRAME) {
-               IRDA_DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_ACTIVE_FRAME\n");
+       if (iir & IRCC_IIR_ACTIVE_FRAME) {
+               IRDA_DEBUG(0, __FUNCTION__ "(), IRCC_IIR_ACTIVE_FRAME\n");
                self->rx_buff.state = INSIDE_FRAME;
 #if 0
                ircc_dma_receive(self);
 #endif
        }
-
-       if (iir & UART_IIR_RAW_MODE) {
-               IRDA_DEBUG(ircc_debug, __FUNCTION__ ": IIR RAW mode interrupt.\n");
+       if (iir & IRCC_IIR_RAW_MODE) {
+               IRDA_DEBUG(0, __FUNCTION__ "(), IIR RAW mode interrupt.\n");
        }
 
-       dev->interrupt = 0;
-
        register_bank(iobase, 0);
-       serial_out(iobase, UART_IER, UART_IER_ACTIVE_FRAME|UART_IER_EOM);
-       serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN);
+       outb(IRCC_IER_ACTIVE_FRAME|IRCC_IER_EOM, iobase+IRCC_IER);
+       outb(IRCC_MASTER_INT_EN, iobase+IRCC_MASTER);
 
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
+       dev->interrupt = 0;
 }
 
 /*
@@ -814,17 +823,15 @@ static int ircc_is_receiving(struct ircc_cb *self)
        int status = FALSE;
        /* int iobase; */
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(0, __FUNCTION__ "\n");
 
        ASSERT(self != NULL, return FALSE;);
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n",
-             get_dma_residue(self->io.dma));
+       IRDA_DEBUG(0, __FUNCTION__ ": dma count = %d\n",
+                  get_dma_residue(self->io.dma));
 
        status = (self->rx_buff.state != OUTSIDE_FRAME);
        
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
-
        return status;
 }
 
@@ -840,7 +847,7 @@ static int ircc_net_open(struct net_device *dev)
        struct ircc_cb *self;
        int iobase;
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(0, __FUNCTION__ "\n");
        
        ASSERT(dev != NULL, return -1;);
        irport = (struct irport_cb *) dev->priv;
@@ -850,20 +857,20 @@ static int ircc_net_open(struct net_device *dev)
        
        iobase = self->io.iobase;
 
-       irport_net_open(dev);
+       irport_net_open(dev); /* irport allocates the irq */
 
        /*
         * Always allocate the DMA channel after the IRQ,
         * and clean up on failure.
         */
        if (request_dma(self->io.dma, dev->name)) {
-               free_irq(self->io.irq, dev);
+               irport_net_close(dev);
+
                return -EAGAIN;
        }
        
        MOD_INC_USE_COUNT;
 
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
        return 0;
 }
 
@@ -879,7 +886,7 @@ static int ircc_net_close(struct net_device *dev)
        struct ircc_cb *self;
        int iobase;
 
-       IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
+       IRDA_DEBUG(0, __FUNCTION__ "\n");
        
        ASSERT(dev != NULL, return -1;);
        irport = (struct irport_cb *) dev->priv;
@@ -897,15 +904,12 @@ static int ircc_net_close(struct net_device *dev)
 
        MOD_DEC_USE_COUNT;
 
-       IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
        return 0;
 }
 
 #ifdef MODULE
-
 MODULE_AUTHOR("Thomas Davis <tadavis@jps.net>");
 MODULE_DESCRIPTION("SMC IrCC controller driver");
-MODULE_PARM(ircc_debug,"1i");
 MODULE_PARM(ircc_dma, "1i");
 MODULE_PARM(ircc_irq, "1i");
 
@@ -919,4 +923,4 @@ void cleanup_module(void)
        ircc_cleanup();
 }
 
-#endif
+#endif /* MODULE */
index 39e69803cc62d59243bd635cb8ddfa21b46410fb..c6aa648c019526e27e54b6af1e44ff103b3b7ab4 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Wed Oct 21 20:02:35 1998
- * Modified at:   Fri Dec 17 09:17:45 1999
+ * Modified at:   Fri Dec 17 09:13:09 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
index 982ddb4f73e95daf21c8ac4cb36aec7b92279157..fd47ec6890843563696ab890bc9a5b03097cbf52 100644 (file)
@@ -10,7 +10,7 @@
  * Modified:      Paul Bristow <paul.bristow@technologist.com>
  * Modified:      Mon Nov 11 19:10:05 1999
  * 
- *     Copyright (c) 1999 James McKenzie, All Rights Reserved.
+ *     Copyright (c) 1999-2000 James McKenzie, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -87,7 +87,7 @@ static char *rcsid = "$Id: toshoboe.c,v 1.91 1999/06/29 14:21:06 root Exp $";
 /* No user servicable parts below here */
 
 #include <linux/module.h>
-#include <linux/config.h>
+
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/skbuff.h>
index 717ada5cee2edf9028b02c4039287e99d45c0f64..eee54faf194e7016ea31091c44f473a39a1f9884 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Paul VanderSpek
  * Created at:    Wed Nov  4 11:46:16 1998
- * Modified at:   Tue Dec 21 21:53:09 1999
+ * Modified at:   Wed Jan  5 15:11:21 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>
+ *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>
  *     Copyright (c) 1998-1999 Rebel.com
  *      
  *     This program is free software; you can redistribute it and/or 
@@ -40,7 +40,7 @@
  ********************************************************************/
 
 #include <linux/module.h>
-#include <linux/config.h> 
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/skbuff.h>
@@ -62,9 +62,9 @@
 #include <net/irda/w83977af.h>
 #include <net/irda/w83977af_ir.h>
 
-#ifdef  CONFIG_ARCH_VNC            /* Adjust to NetWinder differences */
-#undef  CONFIG_VNC_TX_DMA_PROBLEMS /* Not needed */
-#define CONFIG_VNC_RX_DMA_PROBLEMS /* Must have this one! */
+#ifdef  CONFIG_ARCH_NETWINDER            /* Adjust to NetWinder differences */
+#undef  CONFIG_NETWINDER_TX_DMA_PROBLEMS /* Not needed */
+#define CONFIG_NETWINDER_RX_DMA_PROBLEMS /* Must have this one! */
 #endif
 #undef  CONFIG_USE_INTERNAL_TIMER  /* Just cannot make that timer work */
 #define CONFIG_USE_W977_PNP        /* Currently needed */
@@ -76,7 +76,7 @@ static int  qos_mtt_bits = 0x07;   /* 1 ms or more */
 #define CHIP_IO_EXTENT 8
 
 static unsigned int io[] = { 0x180, ~0, ~0, ~0 };
-#ifdef CONFIG_ARCH_VNC             /* Adjust to NetWinder differences */
+#ifdef CONFIG_ARCH_NETWINDER             /* Adjust to NetWinder differences */
 static unsigned int irq[] = { 6, 0, 0, 0 };
 #else
 static unsigned int irq[] = { 11, 0, 0, 0 };
@@ -105,6 +105,7 @@ static int  w83977af_net_init(struct net_device *dev);
 static int  w83977af_net_open(struct net_device *dev);
 static int  w83977af_net_close(struct net_device *dev);
 static int  w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static struct net_device_stats *w83977af_net_get_stats(struct net_device *dev);
 
 /*
  * Function w83977af_init ()
@@ -218,22 +219,20 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq,
        self->tx_buff.truesize = 4000;
        
        /* Allocate memory if needed */
-       if (self->rx_buff.truesize > 0) {
-               self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
-                                                     GFP_KERNEL|GFP_DMA);
-               if (self->rx_buff.head == NULL)
-                       return -ENOMEM;
-               memset(self->rx_buff.head, 0, self->rx_buff.truesize);
-       }
-       if (self->tx_buff.truesize > 0) {
-               self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
-                                                     GFP_KERNEL|GFP_DMA);
-               if (self->tx_buff.head == NULL) {
-                       kfree(self->rx_buff.head);
-                       return -ENOMEM;
-               }
-               memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+       self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
+                                             GFP_KERNEL|GFP_DMA);
+       if (self->rx_buff.head == NULL)
+               return -ENOMEM;
+
+       memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+       
+       self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
+                                             GFP_KERNEL|GFP_DMA);
+       if (self->tx_buff.head == NULL) {
+               kfree(self->rx_buff.head);
+               return -ENOMEM;
        }
+       memset(self->tx_buff.head, 0, self->tx_buff.truesize);
 
        self->rx_buff.in_frame = FALSE;
        self->rx_buff.state = OUTSIDE_FRAME;
@@ -244,6 +243,9 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq,
                ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
                return -ENOMEM;
        }
+       /* dev_alloc doesn't clear the struct, so lets do a little hack */
+       memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct net_device)-sizeof(char*));
+
        dev->priv = (void *) self;
        self->netdev = dev;
 
@@ -253,6 +255,7 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq,
        dev->open            = w83977af_net_open;
        dev->stop            = w83977af_net_close;
        dev->do_ioctl        = w83977af_net_ioctl;
+       dev->get_stats       = w83977af_net_get_stats;
 
        rtnl_lock();
        err = register_netdev(dev);
@@ -298,6 +301,8 @@ static int w83977af_close(struct w83977af_ir *self)
                rtnl_lock();
                unregister_netdevice(self->netdev);
                rtnl_unlock();
+               /* Must free the old-style 2.2.x device */
+               kfree(self->netdev);
        }
 
        /* Release the PORT that this driver is using */
@@ -334,12 +339,12 @@ int w83977af_probe( int iobase, int irq, int dma)
                w977_write_reg(0x61, (iobase) & 0xff, efbase[i]);
   
                w977_write_reg(0x70, irq, efbase[i]);
-#ifdef CONFIG_ARCH_VNC
+#ifdef CONFIG_ARCH_NETWINDER
                /* Netwinder uses 1 higher than Linux */
                w977_write_reg(0x74, dma+1, efbase[i]);
 #else
                w977_write_reg(0x74, dma, efbase[i]);   
-#endif /*CONFIG_ARCH_VNC */
+#endif /*CONFIG_ARCH_NETWINDER */
                w977_write_reg(0x75, 0x04, efbase[i]);  /* Disable Tx DMA */
        
                /* Set append hardware CRC, enable IR bank selection */ 
@@ -440,7 +445,7 @@ void w83977af_change_speed(struct w83977af_ir *self, __u32 speed)
        switch (speed) {
        case 9600:   outb(0x0c, iobase+ABLL); break;
        case 19200:  outb(0x06, iobase+ABLL); break;
-       case 37600:  outb(0x03, iobase+ABLL); break;
+       case 38400:  outb(0x03, iobase+ABLL); break;
        case 57600:  outb(0x02, iobase+ABLL); break;
        case 115200: outb(0x01, iobase+ABLL); break;
        case 576000:
@@ -471,7 +476,6 @@ void w83977af_change_speed(struct w83977af_ir *self, __u32 speed)
        
        /* set FIFO threshold to TX17, RX16 */
        switch_bank(iobase, SET0);
-
        outb(0x00, iobase+UFR);        /* Reset */
        outb(UFR_EN_FIFO, iobase+UFR); /* First we must enable FIFO */
        outb(0xa7, iobase+UFR);
@@ -508,7 +512,8 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 
        iobase = self->io.iobase;
 
-       IRDA_DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len);
+       IRDA_DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, 
+                  (int) skb->len);
        
        /* Lock transmit buffer */
        if (irda_lock((void *) &dev->tbusy) == FALSE)
@@ -584,7 +589,7 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 static void w83977af_dma_write(struct w83977af_ir *self, int iobase)
 {
        __u8 set;
-#ifdef CONFIG_VNC_TX_DMA_PROBLEMS
+#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS
        unsigned long flags;
        __u8 hcr;
 #endif
@@ -600,7 +605,7 @@ static void w83977af_dma_write(struct w83977af_ir *self, int iobase)
        /* Choose transmit DMA channel  */ 
        switch_bank(iobase, SET2);
        outb(ADCR1_D_CHSW|/*ADCR1_DMA_F|*/ADCR1_ADV_SL, iobase+ADCR1);
-#ifdef CONFIG_VNC_TX_DMA_PROBLEMS
+#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS
        save_flags(flags);
        cli();
 
@@ -617,7 +622,7 @@ static void w83977af_dma_write(struct w83977af_ir *self, int iobase)
        
        /* Enable DMA */
        switch_bank(iobase, SET0);
-#ifdef CONFIG_VNC_TX_DMA_PROBLEMS
+#ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS
        hcr = inb(iobase+HCR);
        outb(hcr | HCR_EN_DMA, iobase+HCR);
        enable_dma(self->io.dma);
@@ -648,10 +653,12 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size)
 
        switch_bank(iobase, SET0);
        if (!(inb_p(iobase+USR) & USR_TSRE)) {
-               IRDA_DEBUG(4, __FUNCTION__ "(), warning, FIFO not empty yet!\n");
+               IRDA_DEBUG(4, __FUNCTION__ 
+                          "(), warning, FIFO not empty yet!\n");
 
                fifo_size -= 17;
-               IRDA_DEBUG(4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size);
+               IRDA_DEBUG(4, __FUNCTION__ "%d bytes left in tx fifo\n", 
+                          fifo_size);
        }
 
        /* Fill FIFO with current frame */
@@ -733,11 +740,10 @@ int w83977af_dma_receive(struct w83977af_ir *self)
 {
        int iobase;
        __u8 set;
-#ifdef CONFIG_VNC_RX_DMA_PROBLEMS
+#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
        unsigned long flags;
        __u8 hcr;
 #endif
-
        ASSERT(self != NULL, return -1;);
 
        IRDA_DEBUG(4, __FUNCTION__ "\n");
@@ -759,7 +765,7 @@ int w83977af_dma_receive(struct w83977af_ir *self)
        self->io.direction = IO_RECV;
        self->rx_buff.data = self->rx_buff.head;
 
-#ifdef CONFIG_VNC_RX_DMA_PROBLEMS
+#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
        save_flags(flags);
        cli();
 
@@ -783,7 +789,7 @@ int w83977af_dma_receive(struct w83977af_ir *self)
        
        /* Enable DMA */
        switch_bank(iobase, SET0);
-#ifdef CONFIG_VNC_RX_DMA_PROBLEMS
+#ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS
        hcr = inb(iobase+HCR);
        outb(hcr | HCR_EN_DMA, iobase+HCR);
        enable_dma(self->io.dma);
@@ -993,14 +999,6 @@ static __u8 w83977af_sir_interrupt(struct w83977af_ir *self, int isr)
                        self->netdev->tbusy = 0; /* Unlock */
                        self->stats.tx_packets++;
 
-                       /* Check if we need to change the speed? */
-                       if (self->new_speed) {
-                               IRDA_DEBUG(2, __FUNCTION__ 
-                                          "(), Changing speed!\n");
-                               w83977af_change_speed(self, self->new_speed);
-                               self->new_speed = 0;
-                       }
-
                        /* Schedule network layer */
                        mark_bh(NET_BH);        
 
@@ -1112,7 +1110,7 @@ static __u8 w83977af_fir_interrupt(struct w83977af_ir *self, int isr)
 }
 
 /*
- * Function pc87108_interrupt (irq, dev_id, regs)
+ * Function w83977af_interrupt (irq, dev_id, regs)
  *
  *    An interrupt from the chip has arrived. Time to do some work
  *
@@ -1367,12 +1365,22 @@ static int w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        return ret;
 }
 
+static struct net_device_stats *w83977af_net_get_stats(struct net_device *dev)
+{
+       struct w83977af_ir *self = (struct w83977af_ir *) dev->priv;
+       
+       return &self->stats;
+}
+
 #ifdef MODULE
 
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("Winbond W83977AF IrDA Device Driver");
 
 MODULE_PARM(qos_mtt_bits, "i");
+MODULE_PARM(io, "1-4i");
+MODULE_PARM(io2, "1-4i");
+MODULE_PARM(irq, "1-4i");
 
 /*
  * Function init_module (void)
index 2a4e4907d641449620b21fdab3c2c0fa740ab7c7..a862c247b7a91917e040273bf8e0c7c1bd14b639 100644 (file)
@@ -10,6 +10,7 @@ if [ "$CONFIG_TR" = "y" ]; then
    tristate '  IBM Tropic chipset based adapter support' CONFIG_IBMTR
    tristate '  IBM Olympic chipset PCI adapter support' CONFIG_IBMOL
    tristate '  Generic TMS380 Token Ring ISA/PCI adapter support' CONFIG_TMS380TR
+   tristate '  SMC ISA adapter support' CONFIG_SMCTR
 fi
 
 endmenu
index f76e996ffe9d766e11f8af01e0ea7f88f5eb3f2f..72629233b97827c46f162f47fa999e3fe89590dc 100644 (file)
@@ -47,5 +47,13 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_SMCTR),y)
+  L_OBJS += smctr.o
+else
+  ifeq ($(CONFIG_SMCTR),m)
+    M_OBJS += smctr.o
+  endif
+endif
+
 include $(TOPDIR)/Rules.make
 
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
new file mode 100644 (file)
index 0000000..a08587d
--- /dev/null
@@ -0,0 +1,5714 @@
+/*
+ *  smctr.c: A network driver for the SMC Token Ring Adapters.
+ *
+ *  Written by Jay Schulist <jschlst@turbolinux.com>
+ *
+ *  This software may be used and distributed according to the terms
+ *  of the GNU Public License, incorporated herein by reference.
+ *
+ *  This device driver works with the following SMC adapters:
+ *      - SMC TokenCard Elite   (8115T)
+ *      - SMC TokenCard Elite/A MCA (8115T/A)
+ *
+ *  Source(s):
+ *     - SMC TokenCard SDK.
+ *
+ *  Maintainer(s):
+ *    JS        Jay Schulist <jschlst@turbolinux.com>
+ *
+ *  To do:
+ *    1. MCA SMC TokenCard Support. (Some support is already done).
+ *    4. Multicast support.
+ */
+
+static const char *version = "smctr.c: v1.0 1/1/00 by jschlst@turbolinux.com\n";
+static const char *cardname = "smctr";
+
+#include <linux/config.h>
+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+#endif
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <linux/time.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/trdevice.h>
+
+#include "smctr.h"               /* Our Stuff */
+#include "smctr_firmware.h"      /* SMC adapter firmware */
+
+#define SMCTR_IO_EXTENT   20
+
+/* A zero-terminated list of I/O addresses to be probed. */
+static unsigned int smctr_portlist[] __initdata = {
+        0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300,
+        0x320, 0x340, 0x360, 0x380,
+        0
+};
+
+static int ringspeed = 0;
+
+/* SMC Name of the Adapter. */
+static char *smctr_name = "SMC TokenCard";
+char *smctr_model = "Unknown";
+
+/* Use 0 for production, 1 for verification, 2 for debug, and
+ * 3 for very verbose debug.
+ */
+#ifndef SMCTR_DEBUG
+#define SMCTR_DEBUG 1
+#endif
+static unsigned int smctr_debug = SMCTR_DEBUG;
+
+/* smctr.c prototypes and functions are arranged alphabeticly 
+ * for clearity, maintainability and pure old fashion fun. 
+ */
+/* A */
+static int smctr_alloc_shared_memory(struct net_device *dev);
+
+/* B */
+static int smctr_bypass_state(struct net_device *dev);
+
+/* C */
+static int smctr_checksum_firmware(struct net_device *dev);
+static int smctr_chg_rx_mask(struct net_device *dev);
+static int smctr_clear_int(struct net_device *dev);
+static int smctr_clear_trc_reset(int ioaddr);
+static int smctr_close(struct net_device *dev);
+
+/* D */
+static int smctr_decode_firmware(struct net_device *dev);
+static int smctr_disable_16bit(struct net_device *dev);
+static int smctr_disable_adapter_ctrl_store(struct net_device *dev);
+static int smctr_disable_adapter_ram(struct net_device *dev);
+static int smctr_disable_bic_int(struct net_device *dev);
+
+/* E */
+static int smctr_enable_16bit(struct net_device *dev);
+static int smctr_enable_adapter_ctrl_store(struct net_device *dev);
+static int smctr_enable_adapter_ram(struct net_device *dev);
+static int smctr_enable_bic_int(struct net_device *dev);
+
+/* F */
+static int __init smctr_find_adapter(struct net_device *dev);
+
+/* G */
+static int __init smctr_get_boardid(struct net_device *dev);
+static int smctr_get_group_address(struct net_device *dev);
+static int smctr_get_functional_address(struct net_device *dev);
+static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev);
+static int smctr_get_physical_drop_number(struct net_device *dev);
+static __u8 *smctr_get_rx_pointer(struct net_device *dev, short queue);
+static int smctr_get_station_id(struct net_device *dev);
+static struct enet_statistics *smctr_get_stats(struct net_device *dev);
+static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue,
+        __u16 bytes_count);
+static int smctr_get_upstream_neighbor_addr(struct net_device *dev);
+
+/* H */
+static int smctr_hardware_send_packet(struct net_device *dev,
+        struct net_local *tp);
+
+/* I */
+static int smctr_init_acbs(struct net_device *dev);
+static int smctr_init_adapter(struct net_device *dev);
+static int __init smctr_init_card(struct net_device *dev);
+static int smctr_init_card_real(struct net_device *dev);
+static int smctr_init_rx_bdbs(struct net_device *dev);
+static int smctr_init_rx_fcbs(struct net_device *dev);
+static int smctr_init_shared_memory(struct net_device *dev);
+static int smctr_init_tx_bdbs(struct net_device *dev);
+static int smctr_init_tx_fcbs(struct net_device *dev);
+static int smctr_internal_self_test(struct net_device *dev);
+static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static int smctr_issue_enable_int_cmd(struct net_device *dev,
+        __u16 interrupt_enable_mask);
+static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code,
+        __u16 ibits);
+static int smctr_issue_init_timers_cmd(struct net_device *dev);
+static int smctr_issue_init_txrx_cmd(struct net_device *dev);
+static int smctr_issue_insert_cmd(struct net_device *dev);
+static int smctr_issue_read_ring_status_cmd(struct net_device *dev);
+static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt);
+static int smctr_issue_remove_cmd(struct net_device *dev);
+static int smctr_issue_resume_acb_cmd(struct net_device *dev);
+static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue);
+static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue);
+static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue);
+static int smctr_issue_test_internal_rom_cmd(struct net_device *dev);
+static int smctr_issue_test_hic_cmd(struct net_device *dev);
+static int smctr_issue_test_mac_reg_cmd(struct net_device *dev);
+static int smctr_issue_trc_loopback_cmd(struct net_device *dev);
+static int smctr_issue_tri_loopback_cmd(struct net_device *dev);
+static int smctr_issue_write_byte_cmd(struct net_device *dev,
+        short aword_cnt, void *byte);
+static int smctr_issue_write_word_cmd(struct net_device *dev,
+        short aword_cnt, void *word);
+
+/* J */
+static int smctr_join_complete_state(struct net_device *dev);
+
+/* L */
+static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev);
+static int smctr_load_firmware(struct net_device *dev);
+static int smctr_load_node_addr(struct net_device *dev);
+static int smctr_lobe_media_test(struct net_device *dev);
+static int smctr_lobe_media_test_cmd(struct net_device *dev);
+static int smctr_lobe_media_test_state(struct net_device *dev);
+
+/* M */
+static int smctr_make_8025_hdr(struct net_device *dev,
+        MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc);
+static int smctr_make_access_pri(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv);
+static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv);
+static int smctr_make_auth_funct_class(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv);
+static int smctr_make_corr(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv, __u16 correlator);
+static int smctr_make_funct_addr(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv);
+static int smctr_make_group_addr(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv);
+static int smctr_make_phy_drop_num(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv);
+static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv);
+static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv);
+static int smctr_make_ring_station_status(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv);
+static int smctr_make_ring_station_version(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv);
+static int smctr_make_tx_status_code(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv, __u16 tx_fstatus);
+static int smctr_make_upstream_neighbor_addr(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv);
+static int smctr_make_wrap_data(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv);
+
+/* O */
+static int smctr_open(struct net_device *dev);
+static int smctr_open_tr(struct net_device *dev);
+
+/* P */
+int __init smctr_probe (struct net_device *dev);
+static int __init smctr_probe1(struct net_device *dev, int ioaddr);
+static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
+        struct net_device *dev, __u16 rx_status);
+
+/* R */
+static int smctr_ram_conflict_test(struct net_device *dev);
+static int smctr_ram_memory_test(struct net_device *dev);
+static unsigned int __init smctr_read_584_chksum(int ioaddr);
+static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 *correlator);
+static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 *correlator);
+static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf);
+static int smctr_rcv_rq_addr_state_attch(struct net_device *dev,
+        MAC_HEADER *rmf, __u16 *correlator);
+static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 *correlator);
+static int smctr_reset_adapter(struct net_device *dev);
+static int smctr_restart_tx_chain(struct net_device *dev, short queue);
+static int smctr_ring_status_chg(struct net_device *dev);
+static int smctr_rom_conflict_test(struct net_device *dev);
+static int smctr_rx_frame(struct net_device *dev);
+
+/* S */
+static int smctr_send_dat(struct net_device *dev);
+static int smctr_send_packet(struct sk_buff *skb, struct net_device *dev);
+static int smctr_send_lobe_media_test(struct net_device *dev);
+static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 correlator);
+static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 correlator);
+static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 correlator);
+static int smctr_send_rpt_tx_forward(struct net_device *dev,
+        MAC_HEADER *rmf, __u16 tx_fstatus);
+static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 rcode, __u16 correlator);
+static int smctr_send_rq_init(struct net_device *dev);
+static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 *tx_fstatus);
+static int smctr_set_auth_access_pri(struct net_device *dev,
+        MAC_SUB_VECTOR *rsv);
+static int smctr_set_auth_funct_class(struct net_device *dev,
+        MAC_SUB_VECTOR *rsv);
+static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv,
+       __u16 *correlator);
+static int smctr_set_error_timer_value(struct net_device *dev,
+        MAC_SUB_VECTOR *rsv);
+static int smctr_set_frame_forward(struct net_device *dev,
+        MAC_SUB_VECTOR *rsv, __u8 dc_sc);
+static int smctr_set_local_ring_num(struct net_device *dev,
+        MAC_SUB_VECTOR *rsv);
+static unsigned short smctr_set_ctrl_attention(struct net_device *dev);
+static void smctr_set_multicast_list(struct net_device *dev);
+static int smctr_set_page(struct net_device *dev, __u8 *buf);
+static int smctr_set_phy_drop(struct net_device *dev,
+        MAC_SUB_VECTOR *rsv);
+static int smctr_set_ring_speed(struct net_device *dev);
+static int smctr_set_rx_look_ahead(struct net_device *dev);
+static int smctr_set_trc_reset(int ioaddr);
+static int smctr_setup_single_cmd(struct net_device *dev,
+        __u16 command, __u16 subcommand);
+static int smctr_setup_single_cmd_w_data(struct net_device *dev,
+        __u16 command, __u16 subcommand);
+static char *smctr_malloc(struct net_device *dev, __u16 size);
+static int smctr_status_chg(struct net_device *dev);
+
+/* T */
+static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb,
+        __u16 queue);
+static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue);
+static unsigned short smctr_tx_move_frame(struct net_device *dev,
+        struct sk_buff *skb, __u8 *pbuff, unsigned int bytes);
+
+/* U */
+static int smctr_update_err_stats(struct net_device *dev);
+static int smctr_update_rx_chain(struct net_device *dev, __u16 queue);
+static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb,
+        __u16 queue);
+
+/* W */
+static int smctr_wait_cmd(struct net_device *dev);
+static int smctr_wait_while_cbusy(struct net_device *dev);
+
+#define TO_256_BYTE_BOUNDRY(X)  (((X + 0xff) & 0xff00) - X)
+#define TO_PARAGRAPH_BOUNDRY(X) (((X + 0x0f) & 0xfff0) - X)
+#define PARAGRAPH_BOUNDRY(X)    smctr_malloc(dev, TO_PARAGRAPH_BOUNDRY(X))
+
+/* Allocate Adapter Shared Memory.
+ * IMPORTANT NOTE: Any changes to this function MUST be mirrored in the
+ * function "get_num_rx_bdbs" below!!!
+ *
+ * Order of memory allocation:
+ *
+ *       0. Initial System Configuration Block Pointer
+ *       1. System Configuration Block
+ *       2. System Control Block
+ *       3. Action Command Block
+ *       4. Interrupt Status Block
+ *
+ *       5. MAC TX FCB'S
+ *       6. NON-MAC TX FCB'S
+ *       7. MAC TX BDB'S
+ *       8. NON-MAC TX BDB'S
+ *       9. MAC RX FCB'S
+ *      10. NON-MAC RX FCB'S
+ *      11. MAC RX BDB'S
+ *      12. NON-MAC RX BDB'S
+ *      13. MAC TX Data Buffer( 1, 256 byte buffer)
+ *      14. MAC RX Data Buffer( 1, 256 byte buffer)
+ *
+ *      15. NON-MAC TX Data Buffer
+ *      16. NON-MAC RX Data Buffer
+ */
+static int smctr_alloc_shared_memory(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_alloc_shared_memory\n", dev->name);
+
+        /* Allocate initial System Control Block pointer.
+         * This pointer is located in the last page, last offset - 4.
+         */
+        tp->iscpb_ptr = (ISCPBlock *)(tp->ram_access + ((__u32)64 * 0x400)
+                - (long)ISCP_BLOCK_SIZE);
+
+        /* Allocate System Control Blocks. */
+        tp->scgb_ptr = (SCGBlock *)smctr_malloc(dev, sizeof(SCGBlock));
+        PARAGRAPH_BOUNDRY(tp->sh_mem_used);
+
+        tp->sclb_ptr = (SCLBlock *)smctr_malloc(dev, sizeof(SCLBlock));
+        PARAGRAPH_BOUNDRY(tp->sh_mem_used);
+
+        tp->acb_head = (ACBlock *)smctr_malloc(dev,
+                sizeof(ACBlock)*tp->num_acbs);
+        PARAGRAPH_BOUNDRY(tp->sh_mem_used);
+
+        tp->isb_ptr = (ISBlock *)smctr_malloc(dev, sizeof(ISBlock));
+        PARAGRAPH_BOUNDRY(tp->sh_mem_used);
+
+        tp->misc_command_data = (__u16 *)smctr_malloc(dev, MISC_DATA_SIZE);
+        PARAGRAPH_BOUNDRY(tp->sh_mem_used);
+
+        /* Allocate transmit FCBs. */
+        tp->tx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev,
+                sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE]);
+
+        tp->tx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev,
+                sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE]);
+
+        tp->tx_fcb_head[BUG_QUEUE] = (FCBlock *)smctr_malloc(dev,
+                sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE]);
+
+        /* Allocate transmit BDBs. */
+        tp->tx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev,
+                sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE]);
+
+        tp->tx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev,
+                sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE]);
+
+        tp->tx_bdb_head[BUG_QUEUE] = (BDBlock *)smctr_malloc(dev,
+                sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE]);
+
+        /* Allocate receive FCBs. */
+        tp->rx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev,
+                sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE]);
+
+        tp->rx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev,
+                sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE]);
+
+        /* Allocate receive BDBs. */
+        tp->rx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev,
+                sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE]);
+
+        tp->rx_bdb_end[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0);
+
+        tp->rx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev,
+                sizeof(BDBlock) * tp->num_rx_bdbs[NON_MAC_QUEUE]);
+
+        tp->rx_bdb_end[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0);
+
+        /* Allocate MAC transmit buffers.
+         * MAC Tx Buffers doen't have to be on an ODD Boundry.
+         */
+        tp->tx_buff_head[MAC_QUEUE]
+                = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[MAC_QUEUE]);
+        tp->tx_buff_curr[MAC_QUEUE] = tp->tx_buff_head[MAC_QUEUE];
+        tp->tx_buff_end [MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0);
+
+        /* Allocate BUG transmit buffers. */
+        tp->tx_buff_head[BUG_QUEUE]
+                = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[BUG_QUEUE]);
+        tp->tx_buff_curr[BUG_QUEUE] = tp->tx_buff_head[BUG_QUEUE];
+        tp->tx_buff_end[BUG_QUEUE] = (__u16 *)smctr_malloc(dev, 0);
+
+        /* Allocate MAC receive data buffers.
+         * MAC Rx buffer doesn't have to be on a 256 byte boundry.
+         */
+        tp->rx_buff_head[MAC_QUEUE] = (__u16 *)smctr_malloc(dev,
+                RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE]);
+        tp->rx_buff_end[MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0);
+
+        /* Allocate Non-MAC transmit buffers.
+         * ?? For maximum Netware performance, put Tx Buffers on
+         * ODD Boundry and then restore malloc to Even Boundrys.
+         */
+        smctr_malloc(dev, 1L);
+        tp->tx_buff_head[NON_MAC_QUEUE]
+                = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[NON_MAC_QUEUE]);
+        tp->tx_buff_curr[NON_MAC_QUEUE] = tp->tx_buff_head[NON_MAC_QUEUE];
+        tp->tx_buff_end [NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0);
+        smctr_malloc(dev, 1L);
+
+        /* Allocate Non-MAC receive data buffers.
+         * To guarantee a minimum of 256 contigous memory to
+         * UM_Receive_Packet's lookahead pointer, before a page
+         * change or ring end is encountered, place each rx buffer on
+         * a 256 byte boundry.
+         */
+        smctr_malloc(dev, TO_256_BYTE_BOUNDRY(tp->sh_mem_used));
+        tp->rx_buff_head[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev,
+                RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[NON_MAC_QUEUE]);
+        tp->rx_buff_end[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0);
+
+        return (0);
+}
+
+/* Enter Bypass state. */
+static int smctr_bypass_state(struct net_device *dev)
+{
+        int err;
+
+       if(smctr_debug > 10)
+               printk("%s: smctr_bypass_state\n", dev->name);
+
+        err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE,
+                JS_BYPASS_STATE);
+
+        return (err);
+}
+
+static int smctr_checksum_firmware(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        __u16 i, checksum = 0;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_checksum_firmware\n", dev->name);
+
+        smctr_enable_adapter_ctrl_store(dev);
+
+        for(i = 0; i < CS_RAM_SIZE; i += 2)
+                checksum += *((__u16 *)(tp->ram_access + i));
+
+        tp->microcode_version = *(__u16 *)(tp->ram_access
+                + CS_RAM_VERSION_OFFSET);
+        tp->microcode_version >>= 8;
+
+        smctr_disable_adapter_ctrl_store(dev);
+
+        if(checksum)
+                return (checksum);
+
+        return (0);
+}
+
+static int smctr_chg_rx_mask(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int err = 0;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_chg_rx_mask\n", dev->name);
+
+        smctr_enable_16bit(dev);
+        smctr_set_page(dev, (__u8 *)tp->ram_access);
+
+        if(tp->mode_bits & LOOPING_MODE_MASK)
+                tp->config_word0 |= RX_OWN_BIT;
+        else
+                tp->config_word0 &= ~RX_OWN_BIT;
+
+        if(tp->receive_mask & PROMISCUOUS_MODE)
+                tp->config_word0 |= PROMISCUOUS_BIT;
+        else
+                tp->config_word0 &= ~PROMISCUOUS_BIT;
+
+        if(tp->receive_mask & ACCEPT_ERR_PACKETS)
+                tp->config_word0 |= SAVBAD_BIT;
+        else
+                tp->config_word0 &= ~SAVBAD_BIT;
+
+        if(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES)
+                tp->config_word0 |= RXATMAC;
+        else
+                tp->config_word0 &= ~RXATMAC;
+
+        if(tp->receive_mask & ACCEPT_MULTI_PROM)
+                tp->config_word1 |= MULTICAST_ADDRESS_BIT;
+        else
+                tp->config_word1 &= ~MULTICAST_ADDRESS_BIT;
+
+        if(tp->receive_mask & ACCEPT_SOURCE_ROUTING_SPANNING)
+                tp->config_word1 |= SOURCE_ROUTING_SPANNING_BITS;
+        else
+        {
+                if(tp->receive_mask & ACCEPT_SOURCE_ROUTING)
+                        tp->config_word1 |= SOURCE_ROUTING_EXPLORER_BIT;
+                else
+                        tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS;
+        }
+
+        if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_0,
+                &tp->config_word0)))
+        {
+                return (err);
+        }
+
+        if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_1,
+                &tp->config_word1)))
+        {
+                return (err);
+        }
+
+        smctr_disable_16bit(dev);
+
+        return (0);
+}
+
+static int smctr_clear_int(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        outb((tp->trc_mask | CSR_CLRTINT), dev->base_addr + CSR);
+
+        return (0);
+}
+
+static int smctr_clear_trc_reset(int ioaddr)
+{
+        __u8 r;
+
+        r = inb(ioaddr + MSR);
+        outb(~MSR_RST & r, ioaddr + MSR);
+
+        return (0);
+}
+
+/*
+ * The inverse routine to smctr_open().
+ */
+static int smctr_close(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        struct sk_buff *skb;
+        int err;
+
+        dev->tbusy = 1;
+        dev->start = 0;
+
+#ifdef MODULE
+        MOD_DEC_USE_COUNT;
+#endif
+
+       tp->cleanup = 1;
+
+        /* Check to see if adapter is already in a closed state. */
+        if(tp->status != OPEN)
+                return (0);
+
+        smctr_enable_16bit(dev);
+        smctr_set_page(dev, (__u8 *)tp->ram_access);
+
+        if((err = smctr_issue_remove_cmd(dev)))
+        {
+                smctr_disable_16bit(dev);
+                return (err);
+        }
+
+        for(;;)
+        {
+                skb = skb_dequeue(&tp->SendSkbQueue);
+                if(skb == NULL)
+                        break;
+                tp->QueueSkb++;
+                dev_kfree_skb(skb);
+        }
+
+
+        return (0);
+}
+
+static int smctr_decode_firmware(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        short bit = 0x80, shift = 12;
+        DECODE_TREE_NODE *tree;
+        short branch, tsize;
+        __u16 buff = 0;
+        long weight;
+        __u8 *ucode;
+        __u16 *mem;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_decode_firmware\n", dev->name);
+
+        weight  = *(long *)(tp->ptr_ucode + WEIGHT_OFFSET);
+        tsize   = *(__u8 *)(tp->ptr_ucode + TREE_SIZE_OFFSET);
+        tree    = (DECODE_TREE_NODE *)(tp->ptr_ucode + TREE_OFFSET);
+        ucode   = (__u8 *)(tp->ptr_ucode + TREE_OFFSET
+                        + (tsize * sizeof(DECODE_TREE_NODE)));
+        mem     = (__u16 *)(tp->ram_access);
+
+        while(weight)
+        {
+                branch = ROOT;
+                while((tree + branch)->tag != LEAF && weight)
+                {
+                        branch = *ucode & bit ? (tree + branch)->llink
+                                : (tree + branch)->rlink;
+
+                        bit >>= 1;
+                        weight--;
+
+                        if(bit == 0)
+                        {
+                                bit = 0x80;
+                                ucode++;
+                        }
+                }
+
+                buff |= (tree + branch)->info << shift;
+                shift -= 4;
+
+                if(shift < 0)
+                {
+                        *(mem++) = SWAP_BYTES(buff);
+                        buff    = 0;
+                        shift   = 12;
+                }
+        }
+
+        /* The following assumes the Control Store Memory has
+         * been initialized to zero. If the last partial word
+         * is zero, it will not be written.
+         */
+        if(buff)
+                *(mem++) = SWAP_BYTES(buff);
+
+        return (0);
+}
+
+static int smctr_disable_16bit(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        __u8 r;
+
+        if(tp->adapter_bus == BUS_ISA16_TYPE
+                && ((tp->adapter_flags & FORCED_16BIT_MODE) == 0))
+        {
+                r = inb(dev->base_addr + LAAR);
+                outb((r & ~LAAR_MEM16ENB), dev->base_addr + LAAR);
+        }
+
+        return (0);
+}
+
+/*
+ * On Exit, Adapter is:
+ * 1. TRC is in a reset state and un-initialized.
+ * 2. Adapter memory is enabled.
+ * 3. Control Store memory is out of context (-WCSS is 1).
+ */
+static int smctr_disable_adapter_ctrl_store(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int ioaddr = dev->base_addr;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_disable_adapter_ctrl_store\n", dev->name);
+
+        tp->trc_mask |= CSR_WCSS;
+        outb(tp->trc_mask, ioaddr + CSR);
+
+        return (0);
+}
+
+static int smctr_disable_adapter_ram(struct net_device *dev)
+{
+        int ioaddr = dev->base_addr;
+        __u8 r;
+
+        /* First disable memory enable bit. */
+        r = inb(ioaddr + MSR);
+        outb(~MSR_MEMB & r, ioaddr + MSR);
+
+        /* Now disable 16 bit memory enable bit. */
+        r = inb(ioaddr + LAAR);
+        outb(~LAAR_MEM16ENB & r, ioaddr + LAAR);
+
+        return (0);
+}
+
+static int smctr_disable_bic_int(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int ioaddr = dev->base_addr;
+
+        tp->trc_mask = CSR_MSK_ALL | CSR_MSKCBUSY
+               | CSR_MSKTINT | CSR_WCSS;
+        outb(tp->trc_mask, ioaddr + CSR);
+
+        return (0);
+}
+
+static int smctr_enable_16bit(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        __u8    r;
+
+        if(tp->adapter_bus == BUS_ISA16_TYPE)
+        {
+                r = inb(dev->base_addr + LAAR);
+                outb((r | LAAR_MEM16ENB), dev->base_addr + LAAR);
+        }
+
+        return (0);
+}
+
+/*
+ * To enable the adapter control store memory:
+ * 1. Adapter must be in a RESET state.
+ * 2. Adapter memory must be enabled.
+ * 3. Control Store Memory is in context (-WCSS is 0).
+ */
+static int smctr_enable_adapter_ctrl_store(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int ioaddr = dev->base_addr;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_enable_adapter_ctrl_store\n", dev->name);
+
+        smctr_set_trc_reset(ioaddr);
+        smctr_enable_adapter_ram(dev);
+
+        tp->trc_mask &= ~CSR_WCSS;
+        outb(tp->trc_mask, ioaddr + CSR);
+
+        return (0);
+}
+
+static int smctr_enable_adapter_ram(struct net_device *dev)
+{
+        int ioaddr = dev->base_addr;
+        __u8 r;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_enable_adapter_ram\n", dev->name);
+
+        r = inb(ioaddr + MSR);
+        outb(MSR_MEMB | r, ioaddr + MSR);
+
+        return (0);
+}
+
+static int smctr_enable_bic_int(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int ioaddr = dev->base_addr;
+        __u8 r;
+
+        switch(tp->bic_type)
+        {
+                case (BIC_584_CHIP):
+                        tp->trc_mask = CSR_MSKCBUSY | CSR_WCSS;
+                        outb(tp->trc_mask, ioaddr + CSR);
+                        r = inb(ioaddr + IRR);
+                        outb(r | IRR_IEN, ioaddr + IRR);
+                        break;
+
+                case (BIC_594_CHIP):
+                        tp->trc_mask = CSR_MSKCBUSY | CSR_WCSS;
+                        outb(tp->trc_mask, ioaddr + CSR);
+                        r = inb(ioaddr + IMCCR);
+                        outb(r | IMCCR_EIL, ioaddr + IMCCR);
+                        break;
+        }
+
+        return (0);
+}
+
+static int __init smctr_find_adapter(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int ioaddr = dev->base_addr;
+        __u8 r1, r2, b, chksum = 0;
+        __u16 r;
+       int i;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_find_adapter %#4x\n", dev->name, ioaddr);
+
+        /* Checksum SMC node address */
+        for(i = 0; i < 8; i++)
+        {
+                b = inb(ioaddr + LAR0 + i);
+                chksum += b;
+        }
+
+        if(chksum != NODE_ADDR_CKSUM)
+                return (-1);            /* Adapter Not Found */
+
+        /* Grab the region so that no one else tries to probe our ioports. */
+        request_region(ioaddr, SMCTR_IO_EXTENT, smctr_name);
+
+        b = inb(ioaddr + BDID);
+
+        /* Check for 8115T Board ID */
+        r2 = 0;
+        for(r = 0; r < 8; r++)
+        {
+            r1 = inb(ioaddr + 0x8 + r);
+            r2 += r1;
+        }
+
+        /* value of RegF adds up the sum to 0xFF */
+        if((r2 != 0xFF) && (r2 != 0xEE))
+                return (-1);
+
+        /* Get adapter ID */
+        tp->board_id = smctr_get_boardid(dev);
+        switch(tp->board_id & 0xffff)
+        {
+                case WD8115TA:
+                        smctr_model = "8115T/A";
+                        break;
+
+                case WD8115T:
+                        smctr_model = "8115T";
+                        break;
+
+                default:
+                        smctr_model = "Unknown";
+                        break;
+        }
+
+        /* Store BIC type. */
+        tp->bic_type = BIC_584_CHIP;
+        tp->nic_type = NIC_825_CHIP;
+
+        /* Copy Ram Size */
+        tp->ram_usable  = CNFG_SIZE_16KB;
+        tp->ram_size    = CNFG_SIZE_64KB;
+
+        /* Get 58x Ram Base */
+        r1 = inb(ioaddr);
+        r1 &= 0x3F;
+
+        r2 = inb(ioaddr + CNFG_LAAR_584);
+        r2 &= CNFG_LAAR_MASK;
+        r2 <<= 3;
+        r2 |= ((r1 & 0x38) >> 3);
+
+        tp->ram_base = ((__u32)r2 << 16) + (((__u32)(r1 & 0x7)) << 13);
+
+        /* Get 584 Irq */
+        r1 = 0;
+        r1 = inb(ioaddr + CNFG_ICR_583);
+        r1 &= CNFG_ICR_IR2_584;
+
+        r2 = inb(ioaddr + CNFG_IRR_583);
+        r2 &= CNFG_IRR_IRQS;     /* 0x60 */
+        r2 >>= 5;
+
+        switch(r2)
+        {
+                case 0:
+                        if(r1 == 0)
+                                dev->irq = 2;
+                        else
+                                dev->irq = 10;
+                        break;
+
+                case 1:
+                        if(r1 == 0)
+                                dev->irq = 3;
+                        else
+                                dev->irq = 11;
+                        break;
+
+                case 2:
+                        if(r1 == 0)
+                        {
+                                if(tp->extra_info & ALTERNATE_IRQ_BIT)
+                                        dev->irq = 5;
+                                else
+                                        dev->irq = 4;
+                        }
+                        else
+                                dev->irq = 15;
+                        break;
+
+                case 3:
+                        if(r1 == 0)
+                                dev->irq = 7;
+                        else
+                                dev->irq = 4;
+                        break;
+
+                default:
+                        printk("%s: No IRQ found aborting\n", dev->name);
+                        return(-1);
+         }
+
+        if(request_irq(dev->irq, smctr_interrupt, SA_SHIRQ, smctr_name, dev))
+                return (-ENODEV);
+
+        /* Get 58x Rom Base */
+        r1 = inb(ioaddr + CNFG_BIO_583);
+        r1 &= 0x3E;
+        r1 |= 0x40;
+
+        tp->rom_base = (__u32)r1 << 13;
+
+        /* Get 58x Rom Size */
+        r1 = inb(ioaddr + CNFG_BIO_583);
+        r1 &= 0xC0;
+        if(r1 == 0)
+                tp->rom_size = ROM_DISABLE;
+        else
+        {
+                r1 >>= 6;
+                tp->rom_size = (__u16)CNFG_SIZE_8KB << r1;
+        }
+
+        /* Get 58x Boot Status */
+        r1 = inb(ioaddr + CNFG_GP2);
+
+        tp->mode_bits &= (~BOOT_STATUS_MASK);
+
+        if(r1 & CNFG_GP2_BOOT_NIBBLE)
+                tp->mode_bits |= BOOT_TYPE_1;
+
+        /* Get 58x Zero Wait State */
+        tp->mode_bits &= (~ZERO_WAIT_STATE_MASK);
+
+        r1 = inb(ioaddr + CNFG_IRR_583);
+
+        if(r1 & CNFG_IRR_ZWS)
+                 tp->mode_bits |= ZERO_WAIT_STATE_8_BIT;
+
+        if(tp->board_id & BOARD_16BIT)
+        {
+                r1 = inb(ioaddr + CNFG_LAAR_584);
+
+                if(r1 & CNFG_LAAR_ZWS)
+                        tp->mode_bits |= ZERO_WAIT_STATE_16_BIT;
+        }
+
+        /* Get 584 Media Menu */
+        tp->media_menu = 14;
+        r1 = inb(ioaddr + CNFG_IRR_583);
+
+        tp->mode_bits &= 0xf8ff;       /* (~CNFG_INTERFACE_TYPE_MASK) */
+        if((tp->board_id & TOKEN_MEDIA) == TOKEN_MEDIA)
+        {
+                /* Get Advanced Features */
+                if(((r1 & 0x6) >> 1) == 0x3)
+                        tp->media_type |= MEDIA_UTP_16;
+                else
+                {
+                        if(((r1 & 0x6) >> 1) == 0x2)
+                                tp->media_type |= MEDIA_STP_16;
+                        else
+                        {
+                                if(((r1 & 0x6) >> 1) == 0x1)
+                                        tp->media_type |= MEDIA_UTP_4;
+
+                                else
+                                        tp->media_type |= MEDIA_STP_4;
+                        }
+                }
+
+                r1 = inb(ioaddr + CNFG_GP2);
+                if(!(r1 & 0x2) )           /* GP2_ETRD */
+                        tp->mode_bits |= EARLY_TOKEN_REL;
+
+                /* see if the chip is corrupted */
+                if(smctr_read_584_chksum(ioaddr))
+                {
+                        printk("%s: EEPROM Checksum Failure\n", dev->name);
+                        return(-1);
+                }
+        }
+
+        return (0);
+}
+
+static int __init smctr_get_boardid(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int ioaddr = dev->base_addr;
+        __u8 r, r1, IdByte;
+        __u16 BoardIdMask;
+
+        tp->board_id = BoardIdMask = 0;
+
+        BoardIdMask |= (INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT);
+        tp->extra_info |= (INTERFACE_584_CHIP + RAM_SIZE_64K
+                + NIC_825_BIT + ALTERNATE_IRQ_BIT);
+
+        r = inb(ioaddr + BID_REG_1);
+        r &= 0x0c;
+        outb(r, ioaddr + BID_REG_1);
+        r = inb(ioaddr + BID_REG_1);
+
+        if(r & BID_SIXTEEN_BIT_BIT)
+        {
+                tp->extra_info |= SLOT_16BIT;
+                tp->adapter_bus = BUS_ISA16_TYPE;
+        }
+        else
+                tp->adapter_bus = BUS_ISA8_TYPE;
+
+        /* Get Board Id Byte */
+        IdByte = inb(ioaddr + BID_BOARD_ID_BYTE);
+
+        /* if Major version > 1.0 then
+         *      return;
+         */
+        if(IdByte & 0xF8)
+                return (-1);
+
+        r1 = inb(ioaddr + BID_REG_1);
+        r1 &= BID_ICR_MASK;
+        r1 |= BID_OTHER_BIT;
+
+        outb(r1, ioaddr + BID_REG_1);
+        r1 = inb(ioaddr + BID_REG_3);
+
+        r1 &= BID_EAR_MASK;
+        r1 |= BID_ENGR_PAGE;
+
+        outb(r1, ioaddr + BID_REG_3);
+        r1 = inb(ioaddr + BID_REG_1);
+        r1 &= BID_ICR_MASK;
+        r1 |= (BID_RLA | BID_OTHER_BIT);
+
+        outb(r1, ioaddr + BID_REG_1);
+
+        r1 = inb(ioaddr + BID_REG_1);
+        while(r1 & BID_RECALL_DONE_MASK)
+                r1 = inb(ioaddr + BID_REG_1);
+
+        r = inb(ioaddr + BID_LAR_0 + BID_REG_6);
+
+        /* clear chip rev bits */
+        tp->extra_info &= ~CHIP_REV_MASK;
+        tp->extra_info |= ((r & BID_EEPROM_CHIP_REV_MASK) << 6);
+
+        r1 = inb(ioaddr + BID_REG_1);
+        r1 &= BID_ICR_MASK;
+        r1 |= BID_OTHER_BIT;
+
+        outb(r1, ioaddr + BID_REG_1);
+        r1 = inb(ioaddr + BID_REG_3);
+
+        r1 &= BID_EAR_MASK;
+        r1 |= BID_EA6;
+
+        outb(r1, ioaddr + BID_REG_3);
+        r1 = inb(ioaddr + BID_REG_1);
+
+        r1 &= BID_ICR_MASK;
+        r1 |= BID_RLA;
+
+        outb(r1, ioaddr + BID_REG_1);
+        r1 = inb(ioaddr + BID_REG_1);
+
+        while(r1 & BID_RECALL_DONE_MASK)
+                r1 = inb(ioaddr + BID_REG_1);
+
+        return (BoardIdMask);
+}
+
+static int smctr_get_group_address(struct net_device *dev)
+{
+        smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_GROUP_ADDR);
+
+        return(smctr_wait_cmd(dev));
+}
+
+static int smctr_get_functional_address(struct net_device *dev)
+{
+        smctr_issue_read_word_cmd(dev, RW_FUNCTIONAL_ADDR);
+
+        return(smctr_wait_cmd(dev));
+}
+
+/* Calculate number of Non-MAC receive BDB's and data buffers.
+ * This function must simulate allocateing shared memory exactly
+ * as the allocate_shared_memory function above.
+ */
+static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int mem_used = 0;
+
+        /* Allocate System Control Blocks. */
+        mem_used += sizeof(SCGBlock);
+
+        mem_used += TO_PARAGRAPH_BOUNDRY(mem_used);
+        mem_used += sizeof(SCLBlock);
+
+        mem_used += TO_PARAGRAPH_BOUNDRY(mem_used);
+        mem_used += sizeof(ACBlock) * tp->num_acbs;
+
+        mem_used += TO_PARAGRAPH_BOUNDRY(mem_used);
+        mem_used += sizeof(ISBlock);
+
+        mem_used += TO_PARAGRAPH_BOUNDRY(mem_used);
+        mem_used += MISC_DATA_SIZE;
+
+        /* Allocate transmit FCB's. */
+        mem_used += TO_PARAGRAPH_BOUNDRY(mem_used);
+
+        mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE];
+        mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE];
+        mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE];
+
+        /* Allocate transmit BDBs. */
+        mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE];
+        mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE];
+        mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE];
+
+        /* Allocate receive FCBs. */
+        mem_used += sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE];
+        mem_used += sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE];
+
+        /* Allocate receive BDBs. */
+        mem_used += sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE];
+
+        /* Allocate MAC transmit buffers.
+         * MAC transmit buffers don't have to be on an ODD Boundry.
+         */
+        mem_used += tp->tx_buff_size[MAC_QUEUE];
+
+        /* Allocate BUG transmit buffers. */
+        mem_used += tp->tx_buff_size[BUG_QUEUE];
+
+        /* Allocate MAC receive data buffers.
+         * MAC receive buffers don't have to be on a 256 byte boundry.
+         */
+        mem_used += RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE];
+
+        /* Allocate Non-MAC transmit buffers.
+         * For maximum Netware performance, put Tx Buffers on
+         * ODD Boundry,and then restore malloc to Even Boundrys.
+         */
+        mem_used += 1L;
+        mem_used += tp->tx_buff_size[NON_MAC_QUEUE];
+        mem_used += 1L;
+
+        /* CALCULATE NUMBER OF NON-MAC RX BDB'S
+         * AND NON-MAC RX DATA BUFFERS
+         *
+         * Make sure the mem_used offset at this point is the
+         * same as in allocate_shared memory or the following
+         * boundry adjustment will be incorrect (i.e. not allocating
+         * the non-mac recieve buffers above cannot change the 256
+         * byte offset).
+         *
+         * Since this cannot be guaranteed, adding the full 256 bytes
+         * to the amount of shared memory used at this point will guaranteed
+         * that the rx data buffers do not overflow shared memory.
+         */
+        mem_used += 0x100;
+
+        return((0xffff - mem_used) / (RX_DATA_BUFFER_SIZE + sizeof(BDBlock)));
+}
+
+static int smctr_get_physical_drop_number(struct net_device *dev)
+{
+        smctr_issue_read_word_cmd(dev, RW_PHYSICAL_DROP_NUMBER);
+
+        return(smctr_wait_cmd(dev));
+}
+
+static __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        BDBlock *bdb;
+
+        bdb = (BDBlock *)((__u32)tp->ram_access
+                + (__u32)(tp->rx_fcb_curr[queue]->trc_bdb_ptr));
+
+        tp->rx_fcb_curr[queue]->bdb_ptr = bdb;
+
+        return ((__u8 *)bdb->data_block_ptr);
+}
+
+static int smctr_get_station_id(struct net_device *dev)
+{
+        smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_MAC_ADDRESS);
+
+        return(smctr_wait_cmd(dev));
+}
+
+/*
+ * Get the current statistics. This may be called with the card open
+ * or closed.
+ */
+static struct enet_statistics *smctr_get_stats(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        return ((struct enet_statistics *)&tp->MacStat);
+}
+
+static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue,
+        __u16 bytes_count)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        FCBlock *pFCB;
+        BDBlock *pbdb;
+        unsigned short alloc_size;
+        unsigned short *temp;
+
+        if(smctr_debug > 20)
+                printk("smctr_get_tx_fcb\n");
+
+        /* check if there is enough FCB blocks */
+        if(tp->num_tx_fcbs_used[queue] >= tp->num_tx_fcbs[queue])
+                return ((FCBlock *)(-1L));
+
+        /* round off the input pkt size to the nearest even number */
+        alloc_size = (bytes_count + 1) & 0xfffe;
+
+        /* check if enough mem */
+        if((tp->tx_buff_used[queue] + alloc_size) > tp->tx_buff_size[queue])
+                return ((FCBlock *)(-1L));
+
+        /* check if past the end ;
+         * if exactly enough mem to end of ring, alloc from front.
+         * this avoids update of curr when curr = end
+         */
+        if(((unsigned long)(tp->tx_buff_curr[queue]) + alloc_size)
+                >= (unsigned long)(tp->tx_buff_end[queue]))
+        {
+                /* check if enough memory from ring head */
+                alloc_size = alloc_size +
+                        (__u16)((__u32)tp->tx_buff_end[queue]
+                        - (__u32)tp->tx_buff_curr[queue]);
+
+                if((tp->tx_buff_used[queue] + alloc_size)
+                        > tp->tx_buff_size[queue])
+                {
+                        return ((FCBlock *)(-1L));
+                }
+
+                /* ring wrap */
+                tp->tx_buff_curr[queue] = tp->tx_buff_head[queue];
+        }
+
+        tp->tx_buff_used[queue] += alloc_size;
+        tp->num_tx_fcbs_used[queue]++;
+        tp->tx_fcb_curr[queue]->frame_length = bytes_count;
+        tp->tx_fcb_curr[queue]->memory_alloc = alloc_size;
+        temp = tp->tx_buff_curr[queue];
+        tp->tx_buff_curr[queue]
+                = (__u16 *)((__u32)temp + (__u32)((bytes_count + 1) & 0xfffe));
+
+        pbdb = tp->tx_fcb_curr[queue]->bdb_ptr;
+        pbdb->buffer_length = bytes_count;
+        pbdb->data_block_ptr = temp;
+        pbdb->trc_data_block_ptr = TRC_POINTER(temp);
+
+        pFCB = tp->tx_fcb_curr[queue];
+        tp->tx_fcb_curr[queue] = tp->tx_fcb_curr[queue]->next_ptr;
+
+        return (pFCB);
+}
+
+static int smctr_get_upstream_neighbor_addr(struct net_device *dev)
+{
+        smctr_issue_read_word_cmd(dev, RW_UPSTREAM_NEIGHBOR_ADDRESS);
+
+        return(smctr_wait_cmd(dev));
+}
+
+static int smctr_hardware_send_packet(struct net_device *dev,
+        struct net_local *tp)
+{
+        struct tr_statistics *tstat = &tp->MacStat;
+        struct sk_buff *skb;
+        FCBlock *fcb;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_hardware_send_packet\n", dev->name);
+
+        if(tp->status != OPEN)
+                return (-1);
+
+        if(tp->monitor_state_ready != 1)
+                return (-1);
+
+        for(;;)
+        {
+                /* Send first buffer from queue */
+                skb = skb_dequeue(&tp->SendSkbQueue);
+                if(skb == NULL)
+                        return (-1);
+
+                tp->QueueSkb++;
+
+                if(skb->len < SMC_HEADER_SIZE || skb->len > tp->max_packet_size)                        return (-1);
+
+                smctr_enable_16bit(dev);
+                smctr_set_page(dev, (__u8 *)tp->ram_access);
+
+                if((fcb = smctr_get_tx_fcb(dev, NON_MAC_QUEUE, skb->len))
+                        == (FCBlock *)(-1L))
+                {
+                        smctr_disable_16bit(dev);
+                        return (-1);
+                }
+
+                smctr_tx_move_frame(dev, skb,
+                        (__u8 *)fcb->bdb_ptr->data_block_ptr, skb->len);
+
+                smctr_set_page(dev, (__u8 *)fcb);
+
+                smctr_trc_send_packet(dev, fcb, NON_MAC_QUEUE);
+                dev_kfree_skb(skb);
+
+                tstat->tx_packets++;
+
+                smctr_disable_16bit(dev);
+        }
+
+        return (0);
+}
+
+static int smctr_init_acbs(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i;
+        ACBlock *acb;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_init_acbs\n", dev->name);
+
+        acb                     = tp->acb_head;
+        acb->cmd_done_status    = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL);
+        acb->cmd_info           = ACB_CHAIN_END;
+        acb->cmd                = 0;
+        acb->subcmd             = 0;
+        acb->data_offset_lo     = 0;
+        acb->data_offset_hi     = 0;
+        acb->next_ptr
+                = (ACBlock *)(((char *)acb) + sizeof(ACBlock));
+        acb->trc_next_ptr       = TRC_POINTER(acb->next_ptr);
+
+        for(i = 1; i < tp->num_acbs; i++)
+        {
+                acb             = acb->next_ptr;
+                acb->cmd_done_status
+                        = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL);
+                acb->cmd_info = ACB_CHAIN_END;
+                acb->cmd        = 0;
+                acb->subcmd     = 0;
+                acb->data_offset_lo = 0;
+                acb->data_offset_hi = 0;
+                acb->next_ptr
+                        = (ACBlock *)(((char *)acb) + sizeof(ACBlock));
+                acb->trc_next_ptr = TRC_POINTER(acb->next_ptr);
+        }
+
+        acb->next_ptr           = tp->acb_head;
+        acb->trc_next_ptr       = TRC_POINTER(tp->acb_head);
+        tp->acb_next            = tp->acb_head->next_ptr;
+        tp->acb_curr            = tp->acb_head->next_ptr;
+        tp->num_acbs_used       = 0;
+
+        return (0);
+}
+
+static int smctr_init_adapter(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int err;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_init_adapter\n", dev->name);
+
+        tp->status              = CLOSED;
+        tp->page_offset_mask    = (tp->ram_usable * 1024) - 1;
+        skb_queue_head_init(&tp->SendSkbQueue);
+        tp->QueueSkb = MAX_TX_QUEUE;
+
+        if(!(tp->group_address_0 & 0x0080))
+                tp->group_address_0 |= 0x00C0;
+
+        if(!(tp->functional_address_0 & 0x00C0))
+                tp->functional_address_0 |= 0x00C0;
+
+        tp->functional_address[0] &= 0xFF7F;
+
+        if(tp->authorized_function_classes == 0)
+                tp->authorized_function_classes = 0x7FFF;
+
+        if(tp->authorized_access_priority == 0)
+                tp->authorized_access_priority = 0x06;
+
+        smctr_disable_bic_int(dev);
+        smctr_set_trc_reset(dev->base_addr);
+
+        /* By default the adapter will operate in 16-bit mode only. If
+         * there are two or more adapters in a box, switching between
+         * 16-bit and 8-bit mode may cause problems. In short the adapters
+         * will interfere with each other. XXX - smc.
+         */
+        smctr_disable_adapter_ram(dev);
+        if((err = smctr_rom_conflict_test(dev)))
+                return (err);
+
+        if((err = smctr_ram_conflict_test(dev)))
+                return (err);
+
+        smctr_enable_adapter_ram(dev);
+        smctr_enable_16bit(dev);
+        smctr_set_page(dev, (__u8 *)tp->ram_access);
+
+        if(smctr_checksum_firmware(dev))
+                return (UCODE_NOT_PRESENT);
+
+        if((err = smctr_ram_memory_test(dev)))
+                return (err);
+
+        smctr_enable_16bit(dev);
+        if(smctr_checksum_firmware(dev))
+                return (-1);
+
+        if((err = smctr_ram_memory_test(dev)))
+                return (-1);
+
+        smctr_set_rx_look_ahead(dev);
+        smctr_load_node_addr(dev);
+
+        /* Initialize adapter for Internal Self Test. */
+        smctr_reset_adapter(dev);
+
+        if((err = smctr_init_card_real(dev)))
+                return (err);
+
+        /* This routine clobbers the TRC's internal registers. */
+        if((err = smctr_internal_self_test(dev)))
+                return (err);
+
+        /* Re-Initialize adapter's internal registers */
+        smctr_reset_adapter(dev);
+
+        if((err = smctr_init_card_real(dev)))
+                return (err);
+
+        smctr_enable_bic_int(dev);
+
+        if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK)))
+                return (err);
+
+        smctr_disable_16bit(dev);
+
+        return (0);
+}
+
+/* Dummy function */
+static int __init smctr_init_card(struct net_device *dev)
+{
+        if(smctr_debug > 10)
+                printk("%s: smctr_init_card\n", dev->name);
+
+        return (0);
+}
+
+static int smctr_init_card_real(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int err = 0;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_init_card_real\n", dev->name);
+
+        tp->sh_mem_used = 0;
+        tp->num_acbs    = NUM_OF_ACBS;
+
+        /* Range Check Max Packet Size */
+        if(tp->max_packet_size < 256)
+                tp->max_packet_size = 256;
+        else
+        {
+                if(tp->max_packet_size > NON_MAC_TX_BUFFER_MEMORY)
+                        tp->max_packet_size = NON_MAC_TX_BUFFER_MEMORY;
+        }
+
+        tp->num_of_tx_buffs = (NON_MAC_TX_BUFFER_MEMORY
+                / tp->max_packet_size) - 1;
+
+        if(tp->num_of_tx_buffs > NUM_NON_MAC_TX_FCBS)
+                tp->num_of_tx_buffs = NUM_NON_MAC_TX_FCBS;
+        else
+        {
+                if(tp->num_of_tx_buffs == 0)
+                        tp->num_of_tx_buffs = 1;
+        }
+
+        /* Tx queue constants */
+        tp->num_tx_fcbs        [BUG_QUEUE]     = NUM_BUG_TX_FCBS;
+        tp->num_tx_bdbs        [BUG_QUEUE]     = NUM_BUG_TX_BDBS;
+        tp->tx_buff_size       [BUG_QUEUE]     = BUG_TX_BUFFER_MEMORY;
+        tp->tx_buff_used       [BUG_QUEUE]     = 0;
+        tp->tx_queue_status    [BUG_QUEUE]     = NOT_TRANSMITING;
+
+        tp->num_tx_fcbs        [MAC_QUEUE]     = NUM_MAC_TX_FCBS;
+        tp->num_tx_bdbs        [MAC_QUEUE]     = NUM_MAC_TX_BDBS;
+        tp->tx_buff_size       [MAC_QUEUE]     = MAC_TX_BUFFER_MEMORY;
+        tp->tx_buff_used       [MAC_QUEUE]     = 0;
+        tp->tx_queue_status    [MAC_QUEUE]     = NOT_TRANSMITING;
+
+        tp->num_tx_fcbs        [NON_MAC_QUEUE] = NUM_NON_MAC_TX_FCBS;
+        tp->num_tx_bdbs        [NON_MAC_QUEUE] = NUM_NON_MAC_TX_BDBS;
+        tp->tx_buff_size       [NON_MAC_QUEUE] = NON_MAC_TX_BUFFER_MEMORY;
+        tp->tx_buff_used       [NON_MAC_QUEUE] = 0;
+        tp->tx_queue_status    [NON_MAC_QUEUE] = NOT_TRANSMITING;
+
+        /* Receive Queue Constants */
+        tp->num_rx_fcbs[MAC_QUEUE] = NUM_MAC_RX_FCBS;
+        tp->num_rx_bdbs[MAC_QUEUE] = NUM_MAC_RX_BDBS;
+
+        if(tp->extra_info & CHIP_REV_MASK)
+                tp->num_rx_fcbs[NON_MAC_QUEUE] = 78;    /* 825 Rev. XE */
+        else
+                tp->num_rx_fcbs[NON_MAC_QUEUE] = 7;     /* 825 Rev. XD */
+
+        tp->num_rx_bdbs[NON_MAC_QUEUE] = smctr_get_num_rx_bdbs(dev);
+
+        smctr_alloc_shared_memory(dev);
+        smctr_init_shared_memory(dev);
+
+        if((err = smctr_issue_init_timers_cmd(dev)))
+                return (err);
+
+        if((err = smctr_issue_init_txrx_cmd(dev)))
+                return (err);
+
+        return (0);
+}
+
+static int smctr_init_rx_bdbs(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i, j;
+        BDBlock *bdb;
+        __u16 *buf;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_init_rx_bdbs\n", dev->name);
+
+        for(i = 0; i < NUM_RX_QS_USED; i++)
+        {
+                bdb = tp->rx_bdb_head[i];
+                buf = tp->rx_buff_head[i];
+                bdb->info = (BDB_CHAIN_END | BDB_NO_WARNING);
+                bdb->buffer_length = RX_DATA_BUFFER_SIZE;
+                bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock));
+                bdb->data_block_ptr = buf;
+                bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr);
+
+                if(i == NON_MAC_QUEUE)
+                        bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf);
+                else
+                        bdb->trc_data_block_ptr = TRC_POINTER(buf);
+
+                for(j = 1; j < tp->num_rx_bdbs[i]; j++)
+                {
+                        bdb->next_ptr->back_ptr = bdb;
+                        bdb = bdb->next_ptr;
+                        buf = (__u16 *)((char *)buf + RX_DATA_BUFFER_SIZE);
+                        bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING);
+                        bdb->buffer_length = RX_DATA_BUFFER_SIZE;
+                        bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock));
+                        bdb->data_block_ptr = buf;
+                        bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr);
+
+                        if(i == NON_MAC_QUEUE)
+                                bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf);
+                        else
+                                bdb->trc_data_block_ptr = TRC_POINTER(buf);
+                }
+
+                bdb->next_ptr           = tp->rx_bdb_head[i];
+                bdb->trc_next_ptr       = TRC_POINTER(tp->rx_bdb_head[i]);
+
+                tp->rx_bdb_head[i]->back_ptr    = bdb;
+                tp->rx_bdb_curr[i]              = tp->rx_bdb_head[i]->next_ptr;
+        }
+
+        return (0);
+}
+
+static int smctr_init_rx_fcbs(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i, j;
+        FCBlock *fcb;
+
+        for(i = 0; i < NUM_RX_QS_USED; i++)
+        {
+                fcb               = tp->rx_fcb_head[i];
+                fcb->frame_status = 0;
+                fcb->frame_length = 0;
+                fcb->info         = FCB_CHAIN_END;
+                fcb->next_ptr     = (FCBlock *)(((char*)fcb) + sizeof(FCBlock));
+                if(i == NON_MAC_QUEUE)
+                        fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr);
+                else
+                        fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr);
+
+                for(j = 1; j < tp->num_rx_fcbs[i]; j++)
+                {
+                        fcb->next_ptr->back_ptr = fcb;
+                        fcb                     = fcb->next_ptr;
+                        fcb->frame_status       = 0;
+                        fcb->frame_length       = 0;
+                        fcb->info               = FCB_WARNING;
+                        fcb->next_ptr
+                                = (FCBlock *)(((char *)fcb) + sizeof(FCBlock));
+
+                        if(i == NON_MAC_QUEUE)
+                                fcb->trc_next_ptr
+                                        = RX_FCB_TRC_POINTER(fcb->next_ptr);
+                        else
+                                fcb->trc_next_ptr
+                                        = TRC_POINTER(fcb->next_ptr);
+                }
+
+                fcb->next_ptr = tp->rx_fcb_head[i];
+
+                if(i == NON_MAC_QUEUE)
+                        fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr);
+                else
+                        fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr);
+
+                tp->rx_fcb_head[i]->back_ptr    = fcb;
+                tp->rx_fcb_curr[i]              = tp->rx_fcb_head[i]->next_ptr;
+        }
+
+        return(0);
+}
+
+static int smctr_init_shared_memory(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i;
+        __u32 *iscpb;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_init_shared_memory\n", dev->name);
+
+        smctr_set_page(dev, (__u8 *)(unsigned int)tp->iscpb_ptr);
+
+        /* Initialize Initial System Configuration Point. (ISCP) */
+        iscpb = (__u32 *)PAGE_POINTER(&tp->iscpb_ptr->trc_scgb_ptr);
+        *iscpb = (__u32)(SWAP_WORDS(TRC_POINTER(tp->scgb_ptr)));
+
+        smctr_set_page(dev, (__u8 *)tp->ram_access);
+
+        /* Initialize System Configuration Pointers. (SCP) */
+        tp->scgb_ptr->config = (SCGB_ADDRESS_POINTER_FORMAT
+                | SCGB_MULTI_WORD_CONTROL | SCGB_DATA_FORMAT
+                | SCGB_BURST_LENGTH);
+
+        tp->scgb_ptr->trc_sclb_ptr      = TRC_POINTER(tp->sclb_ptr);
+        tp->scgb_ptr->trc_acb_ptr       = TRC_POINTER(tp->acb_head);
+        tp->scgb_ptr->trc_isb_ptr       = TRC_POINTER(tp->isb_ptr);
+        tp->scgb_ptr->isbsiz            = (sizeof(ISBlock)) - 2;
+
+        /* Initialize System Control Block. (SCB) */
+        tp->sclb_ptr->valid_command    = SCLB_VALID | SCLB_CMD_NOP;
+        tp->sclb_ptr->iack_code        = 0;
+        tp->sclb_ptr->resume_control   = 0;
+        tp->sclb_ptr->int_mask_control = 0;
+        tp->sclb_ptr->int_mask_state   = 0;
+
+        /* Initialize Interrupt Status Block. (ISB) */
+        for(i = 0; i < NUM_OF_INTERRUPTS; i++)
+        {
+                tp->isb_ptr->IStatus[i].IType = 0xf0;
+                tp->isb_ptr->IStatus[i].ISubtype = 0;
+        }
+
+        tp->current_isb_index = 0;
+
+        /* Initialize Action Command Block. (ACB) */
+        smctr_init_acbs(dev);
+
+        /* Initialize transmit FCB's and BDB's. */
+        smctr_link_tx_fcbs_to_bdbs(dev);
+        smctr_init_tx_bdbs(dev);
+        smctr_init_tx_fcbs(dev);
+
+        /* Initialize receive FCB's and BDB's. */
+        smctr_init_rx_bdbs(dev);
+        smctr_init_rx_fcbs(dev);
+
+        return (0);
+}
+
+static int smctr_init_tx_bdbs(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i, j;
+        BDBlock *bdb;
+
+        for(i = 0; i < NUM_TX_QS_USED; i++)
+        {
+                bdb = tp->tx_bdb_head[i];
+                bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING);
+                bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock));
+                bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr);
+
+                for(j = 1; j < tp->num_tx_bdbs[i]; j++)
+                {
+                        bdb->next_ptr->back_ptr = bdb;
+                        bdb = bdb->next_ptr;
+                        bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING);
+                        bdb->next_ptr
+                                = (BDBlock *)(((char *)bdb) + sizeof( BDBlock));                        bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr);
+                }
+
+                bdb->next_ptr = tp->tx_bdb_head[i];
+                bdb->trc_next_ptr = TRC_POINTER(tp->tx_bdb_head[i]);
+                tp->tx_bdb_head[i]->back_ptr = bdb;
+        }
+
+        return (0);
+}
+
+static int smctr_init_tx_fcbs(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i, j;
+        FCBlock *fcb;
+
+        for(i = 0; i < NUM_TX_QS_USED; i++)
+        {
+                fcb               = tp->tx_fcb_head[i];
+                fcb->frame_status = 0;
+                fcb->frame_length = 0;
+                fcb->info         = FCB_CHAIN_END;
+                fcb->next_ptr = (FCBlock *)(((char *)fcb) + sizeof(FCBlock));
+                fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr);
+
+                for(j = 1; j < tp->num_tx_fcbs[i]; j++)
+                {
+                        fcb->next_ptr->back_ptr = fcb;
+                        fcb                     = fcb->next_ptr;
+                        fcb->frame_status       = 0;
+                        fcb->frame_length       = 0;
+                        fcb->info               = FCB_CHAIN_END;
+                        fcb->next_ptr
+                                = (FCBlock *)(((char *)fcb) + sizeof(FCBlock));
+                        fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr);
+                }
+
+                fcb->next_ptr           = tp->tx_fcb_head[i];
+                fcb->trc_next_ptr       = TRC_POINTER(tp->tx_fcb_head[i]);
+
+                tp->tx_fcb_head[i]->back_ptr    = fcb;
+                tp->tx_fcb_end[i]               = tp->tx_fcb_head[i]->next_ptr;
+                tp->tx_fcb_curr[i]              = tp->tx_fcb_head[i]->next_ptr;
+                tp->num_tx_fcbs_used[i]         = 0;
+        }
+
+        return (0);
+}
+
+static int smctr_internal_self_test(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int err;
+
+        if((err = smctr_issue_test_internal_rom_cmd(dev)))
+                return (err);
+
+        if((err = smctr_wait_cmd(dev)))
+                return (err);
+
+        if(tp->acb_head->cmd_done_status & 0xff)
+                return (-1);
+
+        if((err = smctr_issue_test_hic_cmd(dev)))
+                return (err);
+
+        if((err = smctr_wait_cmd(dev)))
+                return (err);
+
+        if(tp->acb_head->cmd_done_status & 0xff)
+                return (-1);
+
+        if((err = smctr_issue_test_mac_reg_cmd(dev)))
+                return (err);
+
+        if((err = smctr_wait_cmd(dev)))
+                return (err);
+
+        if(tp->acb_head->cmd_done_status & 0xff)
+                return (-1);
+
+        return (0);
+}
+
+/*
+ * The typical workload of the driver: Handle the network interface interrupts.
+ */
+static void smctr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+        struct net_device *dev = dev_id;
+        struct net_local *tp;
+        int ioaddr;
+        __u16 interrupt_unmask_bits = 0, interrupt_ack_code = 0xff00;
+        __u16 err1, err = NOT_MY_INTERRUPT;
+        __u8 isb_type, isb_subtype;
+        __u16 isb_index;
+
+        if(dev == NULL)
+        {
+                printk("%s: irq %d for unknown device.\n", dev->name, irq);
+                return;
+        }
+
+        dev->interrupt = 1;
+
+        ioaddr = dev->base_addr;
+        tp = (struct net_local *)dev->priv;
+
+        dev->interrupt = 0;
+
+        if(tp->status == NOT_INITIALIZED)
+                return;
+
+        smctr_disable_bic_int(dev);
+        smctr_enable_16bit(dev);
+
+        smctr_clear_int(dev);
+
+        /* First read the LSB */
+        while((tp->isb_ptr->IStatus[tp->current_isb_index].IType & 0xf0) == 0)
+        {
+                isb_index       = tp->current_isb_index;
+                isb_type        = tp->isb_ptr->IStatus[isb_index].IType;
+                isb_subtype     = tp->isb_ptr->IStatus[isb_index].ISubtype;
+
+                (tp->current_isb_index)++;
+                if(tp->current_isb_index == NUM_OF_INTERRUPTS)
+                        tp->current_isb_index = 0;
+
+                if(isb_type >= 0x10)
+                {
+                        smctr_disable_16bit(dev);
+                        return;
+                }
+
+                err = HARDWARE_FAILED;
+                interrupt_ack_code = isb_index;
+                tp->isb_ptr->IStatus[isb_index].IType |= 0xf0;
+
+                interrupt_unmask_bits |= (1 << (__u16)isb_type);
+
+                switch(isb_type)
+                {
+                        case ISB_IMC_MAC_TYPE_3:
+                                smctr_disable_16bit(dev);
+
+                                switch(isb_subtype)
+                                {
+                                        case 0:
+                                                tp->monitor_state
+                                                = MS_MONITOR_FSM_INACTIVE;
+                                                break;
+
+                                        case 1:
+                                                tp->monitor_state
+                                                = MS_REPEAT_BEACON_STATE;
+                                                break;
+
+                                        case 2:
+                                                tp->monitor_state
+                                                = MS_REPEAT_CLAIM_TOKEN_STATE;
+                                                break;
+
+                                        case 3:
+                                                tp->monitor_state
+                                                = MS_TRANSMIT_CLAIM_TOKEN_STATE;                                                break;
+
+                                        case 4:
+                                                tp->monitor_state
+                                                = MS_STANDBY_MONITOR_STATE;
+                                                break;
+
+                                        case 5:
+                                                tp->monitor_state
+                                                = MS_TRANSMIT_BEACON_STATE;
+                                                break;
+
+                                        case 6:
+                                                tp->monitor_state
+                                                = MS_ACTIVE_MONITOR_STATE;
+                                                break;
+
+                                        case 7:
+                                                tp->monitor_state
+                                                = MS_TRANSMIT_RING_PURGE_STATE;
+                                                break;
+
+                                        case 8:   /* diagnostic state */
+                                                break;
+
+                                        case 9:
+                                                tp->monitor_state
+                                                = MS_BEACON_TEST_STATE;
+                                                if(smctr_lobe_media_test(dev))
+                                                {
+                                                        tp->ring_status_flags
+                                                        = RING_STATUS_CHANGED;
+                                                        tp->ring_status
+                                                        = AUTO_REMOVAL_ERROR;
+                                                        smctr_ring_status_chg(dev);
+                                                        smctr_bypass_state(dev);
+                                                }
+                                                else
+                                                        smctr_issue_insert_cmd(dev);
+                                                break;
+
+                                        /* case 0x0a-0xff, illegal states */
+                                        default:
+                                                break;
+                                }
+
+                                tp->ring_status_flags = MONITOR_STATE_CHANGED;
+                                err = smctr_ring_status_chg(dev);
+
+                                smctr_enable_16bit(dev);
+                                break;
+
+                        /* Type 0x02 - MAC Error Counters Interrupt
+                         * One or more MAC Error Counter is half full
+                         *      MAC Error Counters
+                         *      Lost_FR_Error_Counter
+                         *      RCV_Congestion_Counter
+                         *      FR_copied_Error_Counter
+                         *      FREQ_Error_Counter
+                         *      Token_Error_Counter
+                         *      Line_Error_Counter
+                         *      Internal_Error_Count
+                         */
+                        case ISB_IMC_MAC_ERROR_COUNTERS:
+                                /* Read 802.5 Error Counters */
+                                err = smctr_issue_read_ring_status_cmd(dev);
+                                break;
+
+                        /* Type 0x04 - MAC Type 2 Interrupt
+                         * HOST needs to enqueue MAC Frame for transmission
+                         * SubType Bit 15 - RQ_INIT_PDU( Request Initialization)                         * Changed from RQ_INIT_PDU to
+                         * TRC_Status_Changed_Indicate
+                         */
+                        case ISB_IMC_MAC_TYPE_2:
+                                err = smctr_issue_read_ring_status_cmd(dev);
+                                break;
+
+
+                        /* Type 0x05 - TX Frame Interrupt (FI). */
+                        case ISB_IMC_TX_FRAME:
+                                /* BUG QUEUE for TRC stuck receive BUG */
+                                if(isb_subtype & TX_PENDING_PRIORITY_2)
+                                {
+                                        if((err = smctr_tx_complete(dev,
+                                                BUG_QUEUE)) != SUCCESS)
+                                                break;
+                                }
+
+                                /* NON-MAC frames only */
+                                if(isb_subtype & TX_PENDING_PRIORITY_1)
+                                {
+                                        if((err = smctr_tx_complete(dev,
+                                                NON_MAC_QUEUE)) != SUCCESS)
+                                                break;
+                                }
+
+                                /* MAC frames only */
+                                if(isb_subtype & TX_PENDING_PRIORITY_0)
+                                        err = smctr_tx_complete(dev, MAC_QUEUE);                                break;
+
+                        /* Type 0x06 - TX END OF QUEUE (FE) */
+                        case ISB_IMC_END_OF_TX_QUEUE:
+                                /* BUG queue */
+                                if(isb_subtype & TX_PENDING_PRIORITY_2)
+                                {
+                                        /* ok to clear Receive FIFO overrun
+                                         * imask send_BUG now completes.
+                                         */
+                                        interrupt_unmask_bits |= 0x800;
+
+                                        tp->tx_queue_status[BUG_QUEUE]
+                                                = NOT_TRANSMITING;
+                                        if((err = smctr_tx_complete(dev,
+                                                BUG_QUEUE)) != SUCCESS)
+                                                break;
+                                        if((err = smctr_restart_tx_chain(dev,
+                                                BUG_QUEUE)) != SUCCESS)
+                                                break;
+                                }
+
+                                /* NON-MAC queue only */
+                                if(isb_subtype & TX_PENDING_PRIORITY_1)
+                                {
+                                        tp->tx_queue_status[NON_MAC_QUEUE]
+                                                = NOT_TRANSMITING;
+                                        if((err = smctr_tx_complete(dev,
+                                                NON_MAC_QUEUE)) != SUCCESS)
+                                                break;
+                                        if((err = smctr_restart_tx_chain(dev,
+                                                NON_MAC_QUEUE)) != SUCCESS)
+                                                break;
+                                }
+
+                                /* MAC queue only */
+                                if(isb_subtype & TX_PENDING_PRIORITY_0)
+                                {
+                                        tp->tx_queue_status[MAC_QUEUE]
+                                                = NOT_TRANSMITING;
+                                        if((err = smctr_tx_complete(dev,
+                                                MAC_QUEUE)) != SUCCESS)
+                                                break;
+
+                                        err = smctr_restart_tx_chain(dev,
+                                                MAC_QUEUE);
+                                }
+                                break;
+
+                        /* Type 0x07 - NON-MAC RX Resource Interrupt
+                         *   Subtype bit 12 - (BW) BDB warning
+                         *   Subtype bit 13 - (FW) FCB warning
+                         *   Subtype bit 14 - (BE) BDB End of chain
+                         *   Subtype bit 15 - (FE) FCB End of chain
+                         */
+                        case ISB_IMC_NON_MAC_RX_RESOURCE:
+                                tp->rx_fifo_overrun_count = 0;
+                                tp->receive_queue_number = NON_MAC_QUEUE;
+                                err1 = smctr_rx_frame(dev);
+
+                                if(isb_subtype & NON_MAC_RX_RESOURCE_FE)
+                                {
+                                        if((err = smctr_issue_resume_rx_fcb_cmd(                                                dev, NON_MAC_QUEUE)) != SUCCESS)                                                break;
+
+                                        if(tp->ptr_rx_fcb_overruns)
+                                                (*tp->ptr_rx_fcb_overruns)++;
+                                }
+
+                                if(isb_subtype & NON_MAC_RX_RESOURCE_BE)
+                                {
+                                        if((err = smctr_issue_resume_rx_bdb_cmd(                                                dev, NON_MAC_QUEUE)) != SUCCESS)                                                break;
+
+                                        if(tp->ptr_rx_bdb_overruns)
+                                                (*tp->ptr_rx_bdb_overruns)++;
+                                }
+                                err = err1;
+                                break;
+
+                        /* Type 0x08 - MAC RX Resource Interrupt
+                         *   Subtype bit 12 - (BW) BDB warning
+                         *   Subtype bit 13 - (FW) FCB warning
+                         *   Subtype bit 14 - (BE) BDB End of chain
+                         *   Subtype bit 15 - (FE) FCB End of chain
+                         */
+                        case ISB_IMC_MAC_RX_RESOURCE:
+                                tp->receive_queue_number = MAC_QUEUE;
+                                err1 = smctr_rx_frame(dev);
+
+                                if(isb_subtype & MAC_RX_RESOURCE_FE)
+                                {
+                                        if((err = smctr_issue_resume_rx_fcb_cmd(                                                dev, MAC_QUEUE)) != SUCCESS)
+                                                break;
+
+                                        if(tp->ptr_rx_fcb_overruns)
+                                                (*tp->ptr_rx_fcb_overruns)++;
+                                }
+
+                                if(isb_subtype & MAC_RX_RESOURCE_BE)
+                                {
+                                        if((err = smctr_issue_resume_rx_bdb_cmd(                                                dev, MAC_QUEUE)) != SUCCESS)
+                                                break;
+
+                                        if(tp->ptr_rx_bdb_overruns)
+                                                (*tp->ptr_rx_bdb_overruns)++;
+                                }
+                                err = err1;
+                                break;
+
+                        /* Type 0x09 - NON_MAC RX Frame Interrupt */
+                        case ISB_IMC_NON_MAC_RX_FRAME:
+                                tp->rx_fifo_overrun_count = 0;
+                                tp->receive_queue_number = NON_MAC_QUEUE;
+                                err = smctr_rx_frame(dev);
+                                break;
+
+                        /* Type 0x0A - MAC RX Frame Interrupt */
+                        case ISB_IMC_MAC_RX_FRAME:
+                                tp->receive_queue_number = MAC_QUEUE;
+                                err = smctr_rx_frame(dev);
+                                break;
+
+                        /* Type 0x0B - TRC status
+                         * TRC has encountered an error condition
+                         * subtype bit 14 - transmit FIFO underrun
+                         * subtype bit 15 - receive FIFO overrun
+                         */
+                        case ISB_IMC_TRC_FIFO_STATUS:
+                                if(isb_subtype & TRC_FIFO_STATUS_TX_UNDERRUN)
+                                {
+                                        if(tp->ptr_tx_fifo_underruns)
+                                                (*tp->ptr_tx_fifo_underruns)++;
+                                }
+
+                                if(isb_subtype & TRC_FIFO_STATUS_RX_OVERRUN)
+                                {
+                                        /* update overrun stuck receive counter
+                                         * if >= 3, has to clear it by sending
+                                         * back to back frames. We pick
+                                         * DAT(duplicate address MAC frame)
+                                         */
+                                        tp->rx_fifo_overrun_count++;
+
+                                        if(tp->rx_fifo_overrun_count >= 3)
+                                        {
+                                                tp->rx_fifo_overrun_count = 0;
+
+                                                /* delay clearing fifo overrun
+                                                 * imask till send_BUG tx
+                                                 * complete posted
+                                                 */
+                                                interrupt_unmask_bits &= (~0x800);
+                                                printk("Jay please send bug\n");//                                              smctr_send_bug(dev);
+                                        }
+
+                                        if(tp->ptr_rx_fifo_overruns)
+                                                (*tp->ptr_rx_fifo_overruns)++;
+                                }
+
+                                err = SUCCESS;
+                                break;
+
+                        /* Type 0x0C - Action Command Status Interrupt
+                         * Subtype bit 14 - CB end of command chain (CE)
+                         * Subtype bit 15 - CB command interrupt (CI)
+                         */
+                        case ISB_IMC_COMMAND_STATUS:
+                                err = SUCCESS;
+                                if(tp->acb_head->cmd == ACB_CMD_HIC_NOP)
+                                {
+                                        printk("i1\n");
+                                        smctr_disable_16bit(dev);
+
+                                        /* XXXXXXXXXXXXXXXXX */
+                                /*      err = UM_Interrupt(dev); */
+
+                                        smctr_enable_16bit(dev);
+                                }
+                                else
+                                {
+                                        if((tp->acb_head->cmd
+                                                == ACB_CMD_READ_TRC_STATUS)
+                                                && (tp->acb_head->subcmd
+                                                == RW_TRC_STATUS_BLOCK))
+                                        {
+                                                if(tp->ptr_bcn_type != 0)
+                                                {
+                                                        *(tp->ptr_bcn_type)
+                                                                = (__u32)((SBlock *)tp->misc_command_data)->BCN_Type;
+                                                }
+
+                                                if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & ERROR_COUNTERS_CHANGED)
+                                                {
+                                                        smctr_update_err_stats(dev);
+                                                }
+
+                                                if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & TI_NDIS_RING_STATUS_CHANGED)
+                                                {
+                                                        tp->ring_status
+                                                                = ((SBlock*)tp->misc_command_data)->TI_NDIS_Ring_Status;
+                                                        smctr_disable_16bit(dev);
+                                                        err = smctr_ring_status_chg(dev);
+                                                        smctr_enable_16bit(dev);
+                                                        if((tp->ring_status & REMOVE_RECEIVED)
+                                                                && (tp->config_word0 & NO_AUTOREMOVE))
+                                                        {
+                                                                smctr_issue_remove_cmd(dev);
+                                                        }
+
+                                                        if(err != SUCCESS)
+                                                        {
+                                                                tp->acb_pending
+= 0;
+                                                                break;
+                                                        }
+                                                }
+
+                                                if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & UNA_CHANGED)
+                                                {
+                                                        if(tp->ptr_una)
+                                                        {
+                                                                tp->ptr_una[0]
+                                                                        = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[0]);
+                                                                tp->ptr_una[1]
+                                                                        = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[1]);
+                                                                tp->ptr_una[2]
+                                                                        = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[2]);
+                                                        }
+
+                                                }
+
+                                                if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate
+                                                        & READY_TO_SEND_RQ_INIT)                                                {
+                                                        err = smctr_send_rq_init(dev);
+                                                }
+                                        }
+                                }
+
+                                tp->acb_pending = 0;
+                                break;
+
+                        /* Type 0x0D - MAC Type 1 interrupt
+                         * Subtype -- 00 FR_BCN received at S12
+                         *            01 FR_BCN received at S21
+                         *            02 FR_DAT(DA=MA, A<>0) received at S21
+                         *            03 TSM_EXP at S21
+                         *            04 FR_REMOVE received at S42
+                         *            05 TBR_EXP, BR_FLAG_SET at S42
+                         *            06 TBT_EXP at S53
+                         */
+                        case ISB_IMC_MAC_TYPE_1:
+                                if(isb_subtype > 8)
+                                {
+                                        err = HARDWARE_FAILED;
+                                        break;
+                                }
+
+                                err = SUCCESS;
+                                switch(isb_subtype)
+                                {
+                                        case 0:
+                                                tp->join_state = JS_BYPASS_STATE;
+                                                if(tp->status != CLOSED)
+                                                {
+                                                        tp->status = CLOSED;
+                                                        err = smctr_status_chg(dev);
+                                                }
+                                                break;
+
+                                        case 1:
+                                                tp->join_state
+                                                        = JS_LOBE_TEST_STATE;
+                                                break;
+
+                                        case 2:
+                                                tp->join_state
+                                                        = JS_DETECT_MONITOR_PRESENT_STATE;
+                                                break;
+
+                                        case 3:
+                                                tp->join_state
+                                                        = JS_AWAIT_NEW_MONITOR_STATE;
+                                                break;
+
+                                        case 4:
+                                                tp->join_state
+                                                        = JS_DUPLICATE_ADDRESS_TEST_STATE;
+                                                break;
+
+                                        case 5:
+                                                tp->join_state
+                                                        = JS_NEIGHBOR_NOTIFICATION_STATE;
+                                                break;
+
+                                        case 6:
+                                                tp->join_state
+                                                        = JS_REQUEST_INITIALIZATION_STATE;
+                                                break;
+
+                                        case 7:
+                                                tp->join_state
+                                                        = JS_JOIN_COMPLETE_STATE;
+                                                tp->status = OPEN;
+                                                err = smctr_status_chg(dev);
+                                                break;
+
+                                        case 8:
+                                                tp->join_state
+                                                        = JS_BYPASS_WAIT_STATE;
+                                                break;
+                                }
+                                break ;
+
+                        /* Type 0x0E - TRC Initialization Sequence Interrupt
+                         * Subtype -- 00-FF Initializatin sequence complete
+                         */
+                        case ISB_IMC_TRC_INTRNL_TST_STATUS:
+                                tp->status = INITIALIZED;
+                                smctr_disable_16bit(dev);
+                                err = smctr_status_chg(dev);
+                                smctr_enable_16bit(dev);
+                                break;
+
+                        /* other interrupt types, illegal */
+                        default:
+                                break;
+                }
+
+                if(err != SUCCESS)
+                        break;
+        }
+
+        /* Checking the ack code instead of the unmask bits here is because :
+         * while fixing the stuck receive, DAT frame are sent and mask off
+         * FIFO overrun interrupt temporarily (interrupt_unmask_bits = 0)
+         * but we still want to issue ack to ISB
+         */
+        if(!(interrupt_ack_code & 0xff00))
+                smctr_issue_int_ack(dev, interrupt_ack_code,
+                        interrupt_unmask_bits);
+
+        smctr_disable_16bit(dev);
+        smctr_enable_bic_int(dev);
+
+        return;
+}
+
+static int smctr_issue_enable_int_cmd(struct net_device *dev,
+        __u16 interrupt_enable_mask)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int err;
+
+        if((err = smctr_wait_while_cbusy(dev)))
+                return (err);
+
+        tp->sclb_ptr->int_mask_control  = interrupt_enable_mask;
+        tp->sclb_ptr->valid_command     = SCLB_VALID
+                | SCLB_CMD_CLEAR_INTERRUPT_MASK;
+
+        smctr_set_ctrl_attention(dev);
+
+        return (0);
+}
+
+static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code,
+        __u16 ibits)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        if(smctr_wait_while_cbusy(dev))
+                return (-1);
+
+        tp->sclb_ptr->int_mask_control = ibits;
+        tp->sclb_ptr->iack_code = iack_code << 1; /* use the offset from base */        tp->sclb_ptr->resume_control = 0;
+        tp->sclb_ptr->valid_command =
+                SCLB_VALID | SCLB_IACK_CODE_VALID
+                | SCLB_CMD_CLEAR_INTERRUPT_MASK;
+
+        smctr_set_ctrl_attention(dev);
+
+        return (0);
+}
+
+static int smctr_issue_init_timers_cmd(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i;
+        int err;
+        __u16 *pTimer_Struc = (__u16 *)tp->misc_command_data;
+
+        if((err = smctr_wait_while_cbusy(dev)))
+                return (err);
+
+        if((err = smctr_wait_cmd(dev)))
+                return (err);
+
+        tp->config_word0 = THDREN | DMA_TRIGGER | USETPT | NO_AUTOREMOVE;
+        tp->config_word1 = 0;
+
+        if((tp->media_type == MEDIA_STP_16)
+                || (tp->media_type == MEDIA_UTP_16)
+                || (tp->media_type == MEDIA_STP_16_UTP_16))
+        {
+                tp->config_word0 |= FREQ_16MB_BIT;
+        }
+
+        if(tp->mode_bits & EARLY_TOKEN_REL)
+                tp->config_word0 |= ETREN;
+
+        if(tp->mode_bits & LOOPING_MODE_MASK)
+                tp->config_word0 |= RX_OWN_BIT;
+        else
+                tp->config_word0 &= ~RX_OWN_BIT;
+
+        if(tp->receive_mask & PROMISCUOUS_MODE)
+                tp->config_word0 |= PROMISCUOUS_BIT;
+        else
+                tp->config_word0 &= ~PROMISCUOUS_BIT;
+
+        if(tp->receive_mask & ACCEPT_ERR_PACKETS)
+                tp->config_word0 |= SAVBAD_BIT;
+        else
+                tp->config_word0 &= ~SAVBAD_BIT;
+
+        if(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES)
+                tp->config_word0 |= RXATMAC;
+        else
+                tp->config_word0 &= ~RXATMAC;
+
+        if(tp->receive_mask & ACCEPT_MULTI_PROM)
+                tp->config_word1 |= MULTICAST_ADDRESS_BIT;
+        else
+                tp->config_word1 &= ~MULTICAST_ADDRESS_BIT;
+
+        if(tp->receive_mask & ACCEPT_SOURCE_ROUTING_SPANNING)
+                tp->config_word1 |= SOURCE_ROUTING_SPANNING_BITS;
+        else
+        {
+                if(tp->receive_mask & ACCEPT_SOURCE_ROUTING)
+                        tp->config_word1 |= SOURCE_ROUTING_EXPLORER_BIT;
+                else
+                        tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS;
+        }
+
+        if((tp->media_type == MEDIA_STP_16)
+                || (tp->media_type == MEDIA_UTP_16)
+                || (tp->media_type == MEDIA_STP_16_UTP_16))
+        {
+                tp->config_word1 |= INTERFRAME_SPACING_16;
+        }
+        else
+                tp->config_word1 |= INTERFRAME_SPACING_4;
+
+        *pTimer_Struc++ = tp->config_word0;
+        *pTimer_Struc++ = tp->config_word1;
+
+        if((tp->media_type == MEDIA_STP_4)
+                || (tp->media_type == MEDIA_UTP_4)
+                || (tp->media_type == MEDIA_STP_4_UTP_4))
+        {
+                *pTimer_Struc++ = 0x00FA;       /* prescale */
+                *pTimer_Struc++ = 0x2710;       /* TPT_limit */
+                *pTimer_Struc++ = 0x2710;       /* TQP_limit */
+                *pTimer_Struc++ = 0x0A28;       /* TNT_limit */
+                *pTimer_Struc++ = 0x3E80;       /* TBT_limit */
+                *pTimer_Struc++ = 0x3A98;       /* TSM_limit */
+                *pTimer_Struc++ = 0x1B58;       /* TAM_limit */
+                *pTimer_Struc++ = 0x00C8;       /* TBR_limit */
+                *pTimer_Struc++ = 0x07D0;       /* TER_limit */
+                *pTimer_Struc++ = 0x000A;       /* TGT_limit */
+                *pTimer_Struc++ = 0x1162;       /* THT_limit */
+                *pTimer_Struc++ = 0x07D0;       /* TRR_limit */
+                *pTimer_Struc++ = 0x1388;       /* TVX_limit */
+                *pTimer_Struc++ = 0x0000;       /* reserved */
+        }
+        else
+        {
+                *pTimer_Struc++ = 0x03E8;       /* prescale */
+                *pTimer_Struc++ = 0x9C40;       /* TPT_limit */
+                *pTimer_Struc++ = 0x9C40;       /* TQP_limit */
+                *pTimer_Struc++ = 0x0A28;       /* TNT_limit */
+                *pTimer_Struc++ = 0x3E80;       /* TBT_limit */
+                *pTimer_Struc++ = 0x3A98;       /* TSM_limit */
+                *pTimer_Struc++ = 0x1B58;       /* TAM_limit */
+                *pTimer_Struc++ = 0x00C8;       /* TBR_limit */
+                *pTimer_Struc++ = 0x07D0;       /* TER_limit */
+                *pTimer_Struc++ = 0x000A;       /* TGT_limit */
+                *pTimer_Struc++ = 0x4588;       /* THT_limit */
+                *pTimer_Struc++ = 0x1F40;       /* TRR_limit */
+                *pTimer_Struc++ = 0x4E20;       /* TVX_limit */
+                *pTimer_Struc++ = 0x0000;       /* reserved */
+        }
+
+        /* Set node address. */
+        *pTimer_Struc++ = dev->dev_addr[0] << 8
+                | (dev->dev_addr[1] & 0xFF);
+        *pTimer_Struc++ = dev->dev_addr[2] << 8
+                | (dev->dev_addr[3] & 0xFF);
+        *pTimer_Struc++ = dev->dev_addr[4] << 8
+                | (dev->dev_addr[5] & 0xFF);
+
+        /* Set group address. */
+        *pTimer_Struc++ = tp->group_address_0 << 8
+                | tp->group_address_0 >> 8;
+        *pTimer_Struc++ = tp->group_address[0] << 8
+                | tp->group_address[0] >> 8;
+        *pTimer_Struc++ = tp->group_address[1] << 8
+                | tp->group_address[1] >> 8;
+
+        /* Set functional address. */
+        *pTimer_Struc++ = tp->functional_address_0 << 8
+                | tp->functional_address_0 >> 8;
+        *pTimer_Struc++ = tp->functional_address[0] << 8
+                | tp->functional_address[0] >> 8;
+        *pTimer_Struc++ = tp->functional_address[1] << 8
+                | tp->functional_address[1] >> 8;
+
+        /* Set Bit-Wise group address. */
+        *pTimer_Struc++ = tp->bitwise_group_address[0] << 8
+                | tp->bitwise_group_address[0] >> 8;
+        *pTimer_Struc++ = tp->bitwise_group_address[1] << 8
+                | tp->bitwise_group_address[1] >> 8;
+
+        /* Set ring number address. */
+        *pTimer_Struc++ = tp->source_ring_number;
+        *pTimer_Struc++ = tp->target_ring_number;
+
+        /* Physical drop number. */
+        *pTimer_Struc++ = (unsigned short)0;
+        *pTimer_Struc++ = (unsigned short)0;
+
+        /* Product instance ID. */
+        for(i = 0; i < 9; i++)
+                *pTimer_Struc++ = (unsigned short)0;
+
+        err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TRC_TIMERS, 0);
+
+        return (err);
+}
+
+static int smctr_issue_init_txrx_cmd(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i;
+        int err;
+        void **txrx_ptrs = (void *)tp->misc_command_data;
+
+        if((err = smctr_wait_while_cbusy(dev)))
+                return (err);
+
+        if((err = smctr_wait_cmd(dev)))
+                return (err);
+
+        /* Initialize Transmit Queue Pointers that are used, to point to
+         * a single FCB.
+         */
+        for(i = 0; i < NUM_TX_QS_USED; i++)
+                *txrx_ptrs++ = (void *)TRC_POINTER(tp->tx_fcb_head[i]);
+
+        /* Initialize Transmit Queue Pointers that are NOT used to ZERO. */
+        for(; i < MAX_TX_QS; i++)
+                *txrx_ptrs++ = (void *)0;
+
+        /* Initialize Receive Queue Pointers (MAC and Non-MAC) that are
+         * used, to point to a single FCB and a BDB chain of buffers.
+         */
+        for(i = 0; i < NUM_RX_QS_USED; i++)
+        {
+                *txrx_ptrs++ = (void *)TRC_POINTER(tp->rx_fcb_head[i]);
+                *txrx_ptrs++ = (void *)TRC_POINTER(tp->rx_bdb_head[i]);
+        }
+
+        /* Initialize Receive Queue Pointers that are NOT used to ZERO. */
+        for(; i < MAX_RX_QS; i++)
+        {
+                *txrx_ptrs++ = (void *)0;
+                *txrx_ptrs++ = (void *)0;
+        }
+
+        err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TX_RX, 0);
+
+        return (err);
+}
+
+static int smctr_issue_insert_cmd(struct net_device *dev)
+{
+        int err;
+
+        err = smctr_setup_single_cmd(dev, ACB_CMD_INSERT, ACB_SUB_CMD_NOP);
+
+        return (err);
+}
+
+static int smctr_issue_read_ring_status_cmd(struct net_device *dev)
+{
+        int err;
+
+        if((err = smctr_wait_while_cbusy(dev)))
+                return (err);
+
+        if((err = smctr_wait_cmd(dev)))
+                return (err);
+
+        err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_READ_TRC_STATUS,
+                RW_TRC_STATUS_BLOCK);
+
+        return (err);
+}
+
+static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt)
+{
+        int err;
+
+        if((err = smctr_wait_while_cbusy(dev)))
+                return (err);
+
+        if((err = smctr_wait_cmd(dev)))
+                return (err);
+
+        err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_READ_VALUE,
+                aword_cnt);
+
+        return (err);
+}
+
+static int smctr_issue_remove_cmd(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int err;
+
+        if((err = smctr_wait_while_cbusy(dev)))
+                return (err);
+
+        tp->sclb_ptr->resume_control    = 0;
+        tp->sclb_ptr->valid_command     = SCLB_VALID | SCLB_CMD_REMOVE;
+
+        smctr_set_ctrl_attention(dev);
+
+        return (0);
+}
+
+static int smctr_issue_resume_acb_cmd(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int err;
+
+        if((err = smctr_wait_while_cbusy(dev)))
+                return (err);
+
+        tp->sclb_ptr->resume_control = SCLB_RC_ACB;
+        tp->sclb_ptr->valid_command  = SCLB_VALID | SCLB_RESUME_CONTROL_VALID;
+
+        tp->acb_pending = 1;
+
+        smctr_set_ctrl_attention(dev);
+
+        return (0);
+}
+
+static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int err;
+
+        if((err = smctr_wait_while_cbusy(dev)))
+                return (err);
+
+        if(queue == MAC_QUEUE)
+                tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_BDB;
+        else
+                tp->sclb_ptr->resume_control = SCLB_RC_RX_NON_MAC_BDB;
+
+        tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID;
+
+        smctr_set_ctrl_attention(dev);
+
+        return (0);
+}
+
+static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_issue_resume_rx_fcb_cmd\n", dev->name);
+
+        if(smctr_wait_while_cbusy(dev))
+                return (-1);
+
+        if(queue == MAC_QUEUE)
+                tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_FCB;
+        else
+                tp->sclb_ptr->resume_control = SCLB_RC_RX_NON_MAC_FCB;
+
+        tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID;
+
+        smctr_set_ctrl_attention(dev);
+
+        return (0);
+}
+
+static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_issue_resume_tx_fcb_cmd\n", dev->name);
+
+        if(smctr_wait_while_cbusy(dev))
+                return (-1);
+
+        tp->sclb_ptr->resume_control = (SCLB_RC_TFCB0 << queue);
+        tp->sclb_ptr->valid_command = SCLB_RESUME_CONTROL_VALID | SCLB_VALID;
+
+        smctr_set_ctrl_attention(dev);
+
+        return (0);
+}
+
+static int smctr_issue_test_internal_rom_cmd(struct net_device *dev)
+{
+        int err;
+
+        err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
+                TRC_INTERNAL_ROM_TEST);
+
+        return (err);
+}
+
+static int smctr_issue_test_hic_cmd(struct net_device *dev)
+{
+        int err;
+
+        err = smctr_setup_single_cmd(dev, ACB_CMD_HIC_TEST,
+                TRC_HOST_INTERFACE_REG_TEST);
+
+        return (err);
+}
+
+static int smctr_issue_test_mac_reg_cmd(struct net_device *dev)
+{
+        int err;
+
+        err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
+                TRC_MAC_REGISTERS_TEST);
+
+        return (err);
+}
+
+static int smctr_issue_trc_loopback_cmd(struct net_device *dev)
+{
+        int err;
+
+        err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
+                TRC_INTERNAL_LOOPBACK);
+
+        return (err);
+}
+
+static int smctr_issue_tri_loopback_cmd(struct net_device *dev)
+{
+        int err;
+
+        err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
+                TRC_TRI_LOOPBACK);
+
+        return (err);
+}
+
+static int smctr_issue_write_byte_cmd(struct net_device *dev,
+        short aword_cnt, void *byte)
+{
+       struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int iword, ibyte;
+       int err;
+
+        if((err = smctr_wait_while_cbusy(dev)))
+                return (err);
+
+        if((err = smctr_wait_cmd(dev)))
+                return (err);
+
+        for(iword = 0, ibyte = 0; iword < (unsigned int)(aword_cnt & 0xff);
+               iword++, ibyte += 2)
+        {
+                tp->misc_command_data[iword] = (*((__u8 *)byte + ibyte) << 8)
+                       | (*((__u8 *)byte + ibyte + 1));
+        }
+
+        return (smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, 
+               aword_cnt));
+}
+
+static int smctr_issue_write_word_cmd(struct net_device *dev,
+        short aword_cnt, void *word)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i, err;
+
+        if((err = smctr_wait_while_cbusy(dev)))
+                return (err);
+
+        if((err = smctr_wait_cmd(dev)))
+                return (err);
+
+        for(i = 0; i < (unsigned int)(aword_cnt & 0xff); i++)
+                tp->misc_command_data[i] = *((__u16 *)word + i);
+
+        err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE,
+                aword_cnt);
+
+        return (err);
+}
+
+static int smctr_join_complete_state(struct net_device *dev)
+{
+        int err;
+
+        err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE,
+                JS_JOIN_COMPLETE_STATE);
+
+        return (err);
+}
+
+static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i, j;
+        FCBlock *fcb;
+        BDBlock *bdb;
+
+        for(i = 0; i < NUM_TX_QS_USED; i++)
+        {
+                fcb = tp->tx_fcb_head[i];
+                bdb = tp->tx_bdb_head[i];
+
+                for(j = 0; j < tp->num_tx_fcbs[i]; j++)
+                {
+                        fcb->bdb_ptr            = bdb;
+                        fcb->trc_bdb_ptr        = TRC_POINTER(bdb);
+                        fcb = (FCBlock *)((char *)fcb + sizeof(FCBlock));
+                        bdb = (BDBlock *)((char *)bdb + sizeof(BDBlock));
+                }
+        }
+
+        return (0);
+}
+
+static int smctr_load_firmware(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        __u16 i, checksum = 0;
+        int err = 0;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_load_firmware\n", dev->name);
+
+        tp->ptr_ucode           = smctr_code;
+        tp->num_of_tx_buffs     = 4;
+        tp->mode_bits          |= UMAC;
+        tp->receive_mask        = 0;
+        tp->max_packet_size     = 4177;
+
+        /* Can only upload the firmware once per adapter reset. */
+        if(tp->microcode_version != 0)
+                return (UCODE_PRESENT);
+
+        /* Verify the firmware exists and is there in the right amount. */
+        if((tp->ptr_ucode == 0L)
+                || (*(tp->ptr_ucode + UCODE_VERSION_OFFSET) < UCODE_VERSION))
+        {
+                return (UCODE_NOT_PRESENT);
+        }
+
+        /* UCODE_SIZE is not included in Checksum. */
+        for(i = 0; i < *((__u16 *)(tp->ptr_ucode + UCODE_SIZE_OFFSET)); i += 2)
+                checksum += *((__u16 *)(tp->ptr_ucode + 2 + i));
+        if(checksum)
+                return (UCODE_NOT_PRESENT);
+
+        /* At this point we have a valid firmware image, lets kick it on up. */
+        smctr_enable_adapter_ram(dev);
+        smctr_enable_16bit(dev);
+        smctr_set_page(dev, (__u8 *)tp->ram_access);
+
+        if((smctr_checksum_firmware(dev))
+                || (*(tp->ptr_ucode + UCODE_VERSION_OFFSET)
+                > tp->microcode_version))
+        {
+                smctr_enable_adapter_ctrl_store(dev);
+
+                /* Zero out ram space for firmware. */
+                for(i = 0; i < CS_RAM_SIZE; i += 2)
+                        *((__u16 *)(tp->ram_access + i)) = 0;
+
+                smctr_decode_firmware(dev);
+
+                tp->microcode_version = *(tp->ptr_ucode + UCODE_VERSION_OFFSET);                *((__u16 *)(tp->ram_access + CS_RAM_VERSION_OFFSET))
+                        = (tp->microcode_version << 8);
+                *((__u16 *)(tp->ram_access + CS_RAM_CHECKSUM_OFFSET))
+                        = ~(tp->microcode_version << 8) + 1;
+
+                smctr_disable_adapter_ctrl_store(dev);
+
+                if(smctr_checksum_firmware(dev))
+                        err = HARDWARE_FAILED;
+        }
+        else
+                err = UCODE_PRESENT;
+
+        smctr_disable_16bit(dev);
+
+        return (err);
+}
+
+static int smctr_load_node_addr(struct net_device *dev)
+{
+        int ioaddr = dev->base_addr;
+        unsigned int i;
+        __u8 r;
+
+        /* Check if node address has been specified by user. (non-0) */
+        for(i = 0; ((i < 6) && (dev->dev_addr[i] == 0)); i++);
+        {
+                if(i != 6)
+                {
+                        for(i = 0; i < 6; i++)
+                        {
+                                r = inb(ioaddr + LAR0 + i);
+                                dev->dev_addr[i] = (char)r;
+                        }
+                        dev->addr_len = 6;
+                }
+                else    /* Node addr. not given by user, read it from board. */
+                {
+                        for(i = 0; i < 6; i++)
+                        {
+                                r = inb(ioaddr + LAR0 + i);
+                                dev->dev_addr[i] = (char)r;
+                        }
+                        dev->addr_len = 6;
+                }
+        }
+
+        return (0);
+}
+
+/* Lobe Media Test.
+ * During the transmission of the initial 1500 lobe media MAC frames,
+ * the phase lock loop in the 805 chip may lock, and then un-lock, causing
+ * the 825 to go into a PURGE state. When performing a PURGE, the MCT
+ * microcode will not transmit any frames given to it by the host, and
+ * will consequently cause a timeout.
+ *
+ * NOTE 1: If the monitor_state is MS_BEACON_TEST_STATE, all transmit
+ * queues other then the one used for the lobe_media_test should be
+ * disabled.!?
+ *
+ * NOTE 2: If the monitor_state is MS_BEACON_TEST_STATE and the receive_mask
+ * has any multi-cast or promiscous bits set, the receive_mask needs to
+ * be changed to clear the multi-cast or promiscous mode bits, the lobe_test
+ * run, and then the receive mask set back to its original value if the test
+ * is successful.
+ */
+static int smctr_lobe_media_test(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i, perror = 0;
+        unsigned short saved_rcv_mask;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_lobe_media_test\n", dev->name);
+
+        /* Clear receive mask for lobe test. */
+        saved_rcv_mask          = tp->receive_mask;
+        tp->receive_mask        = 0;
+
+        smctr_chg_rx_mask(dev);
+
+        /* Setup the lobe media test. */
+        smctr_lobe_media_test_cmd(dev);
+        if(smctr_wait_cmd(dev))
+        {
+                smctr_reset_adapter(dev);
+                tp->status = CLOSED;
+                return (LOBE_MEDIA_TEST_FAILED);
+        }
+
+        /* Tx lobe media test frames. */
+        for(i = 0; i < 1500; ++i)
+        {
+                if(smctr_send_lobe_media_test(dev))
+                {
+                        if(perror)
+                        {
+                                smctr_reset_adapter(dev);
+                                tp->state = CLOSED;
+                                return (LOBE_MEDIA_TEST_FAILED);
+                        }
+                        else
+                        {
+                                perror = 1;
+                                if(smctr_lobe_media_test_cmd(dev))
+                                {
+                                        smctr_reset_adapter(dev);
+                                        tp->state = CLOSED;
+                                        return (LOBE_MEDIA_TEST_FAILED);
+                                }
+                        }
+                }
+        }
+
+        if(smctr_send_dat(dev))
+        {
+                if(smctr_send_dat(dev))
+                {
+                        smctr_reset_adapter(dev);
+                        tp->state = CLOSED;
+                        return (LOBE_MEDIA_TEST_FAILED);
+                }
+        }
+
+        /* Check if any frames received during test. */
+        if((tp->rx_fcb_curr[MAC_QUEUE]->frame_status)
+                || (tp->rx_fcb_curr[NON_MAC_QUEUE]->frame_status))
+        {
+                smctr_reset_adapter(dev);
+                tp->state = CLOSED;
+                return (LOBE_MEDIA_TEST_FAILED);
+        }
+
+        /* Set receive mask to "Promisc" mode. */
+        tp->receive_mask = saved_rcv_mask;
+
+        smctr_chg_rx_mask(dev);
+
+        return (0);
+}
+
+static int smctr_lobe_media_test_cmd(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int err;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_lobe_media_test_cmd\n", dev->name);
+
+        /* Change to lobe media test state. */
+        if(tp->monitor_state != MS_BEACON_TEST_STATE)
+        {
+                smctr_lobe_media_test_state(dev);
+                if(smctr_wait_cmd(dev))
+                {
+                        printk("Lobe Failed test state\n");
+                        return (LOBE_MEDIA_TEST_FAILED);
+                }
+        }
+
+        err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
+                TRC_LOBE_MEDIA_TEST);
+
+        return (err);
+}
+
+static int smctr_lobe_media_test_state(struct net_device *dev)
+{
+        int err;
+
+        err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE,
+                JS_LOBE_TEST_STATE);
+
+        return (err);
+}
+
+static int smctr_make_8025_hdr(struct net_device *dev,
+        MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc)
+{
+        tmf->ac = MSB(ac_fc);                 /* msb is access control */
+        tmf->fc = LSB(ac_fc);                 /* lsb is frame control */
+
+        tmf->sa[0] = dev->dev_addr[0];
+        tmf->sa[1] = dev->dev_addr[1];
+        tmf->sa[2] = dev->dev_addr[2];
+        tmf->sa[3] = dev->dev_addr[3];
+        tmf->sa[4] = dev->dev_addr[4];
+        tmf->sa[5] = dev->dev_addr[5];
+
+        switch(tmf->vc)
+        {
+               /* Send RQ_INIT to RPS */
+                case RQ_INIT:
+                        tmf->da[0] = 0xc0;
+                        tmf->da[1] = 0x00;
+                        tmf->da[2] = 0x00;
+                        tmf->da[3] = 0x00;
+                        tmf->da[4] = 0x00;
+                        tmf->da[5] = 0x02;
+                        break;
+
+               /* Send RPT_TX_FORWARD to CRS */
+                case RPT_TX_FORWARD:
+                        tmf->da[0] = 0xc0;
+                        tmf->da[1] = 0x00;
+                        tmf->da[2] = 0x00;
+                        tmf->da[3] = 0x00;
+                        tmf->da[4] = 0x00;
+                        tmf->da[5] = 0x10;
+                        break;
+
+               /* Everything else goes to sender */
+                default:
+                        tmf->da[0] = rmf->sa[0];
+                        tmf->da[1] = rmf->sa[1];
+                        tmf->da[2] = rmf->sa[2];
+                        tmf->da[3] = rmf->sa[3];
+                        tmf->da[4] = rmf->sa[4];
+                        tmf->da[5] = rmf->sa[5];
+                        break;
+        }
+
+        return (0);
+}
+
+static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        tsv->svi = AUTHORIZED_ACCESS_PRIORITY;
+        tsv->svl = S_AUTHORIZED_ACCESS_PRIORITY;
+
+        tsv->svv[0] = MSB(tp->authorized_access_priority);
+        tsv->svv[1] = LSB(tp->authorized_access_priority);
+
+       return (0);
+}
+
+static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv)
+{
+        tsv->svi = ADDRESS_MODIFER;
+        tsv->svl = S_ADDRESS_MODIFER;
+
+        tsv->svv[0] = 0;
+        tsv->svv[1] = 0;
+
+        return (0);
+}
+
+static int smctr_make_auth_funct_class(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        tsv->svi = AUTHORIZED_FUNCTION_CLASS;
+        tsv->svl = S_AUTHORIZED_FUNCTION_CLASS;
+
+        tsv->svv[0] = MSB(tp->authorized_function_classes);
+        tsv->svv[1] = LSB(tp->authorized_function_classes);
+
+        return (0);
+}
+
+static int smctr_make_corr(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv, __u16 correlator)
+{
+        tsv->svi = CORRELATOR;
+        tsv->svl = S_CORRELATOR;
+
+        tsv->svv[0] = MSB(correlator);
+        tsv->svv[1] = LSB(correlator);
+
+        return (0);
+}
+
+static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        smctr_get_functional_address(dev);
+
+        tsv->svi = FUNCTIONAL_ADDRESS;
+        tsv->svl = S_FUNCTIONAL_ADDRESS;
+
+        tsv->svv[0] = MSB(tp->misc_command_data[0]);
+        tsv->svv[1] = LSB(tp->misc_command_data[0]);
+
+        tsv->svv[2] = MSB(tp->misc_command_data[1]);
+        tsv->svv[3] = LSB(tp->misc_command_data[1]);
+
+        return (0);
+}
+
+static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        smctr_get_group_address(dev);
+
+        tsv->svi = GROUP_ADDRESS;
+        tsv->svl = S_GROUP_ADDRESS;
+
+        tsv->svv[0] = MSB(tp->misc_command_data[0]);
+        tsv->svv[1] = LSB(tp->misc_command_data[0]);
+
+        tsv->svv[2] = MSB(tp->misc_command_data[1]);
+        tsv->svv[3] = LSB(tp->misc_command_data[1]);
+
+        /* Set Group Address Sub-vector to all zeros if only the
+         * Group Address/Functional Address Indicator is set.
+         */
+        if(tsv->svv[0] == 0x80 && tsv->svv[1] == 0x00
+               && tsv->svv[2] == 0x00 && tsv->svv[3] == 0x00)
+                tsv->svv[0] = 0x00;
+
+        return (0);
+}
+
+static int smctr_make_phy_drop_num(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        smctr_get_physical_drop_number(dev);
+
+        tsv->svi = PHYSICAL_DROP;
+        tsv->svl = S_PHYSICAL_DROP;
+
+        tsv->svv[0] = MSB(tp->misc_command_data[0]);
+        tsv->svv[1] = LSB(tp->misc_command_data[0]);
+
+        tsv->svv[2] = MSB(tp->misc_command_data[1]);
+        tsv->svv[3] = LSB(tp->misc_command_data[1]);
+
+        return (0);
+}
+
+static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv)
+{
+        int i;
+
+        tsv->svi = PRODUCT_INSTANCE_ID;
+        tsv->svl = S_PRODUCT_INSTANCE_ID;
+
+        for(i = 0; i < 18; i++)
+                tsv->svv[i] = 0xF0;
+
+        return (0);
+}
+
+static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        smctr_get_station_id(dev);
+
+        tsv->svi = STATION_IDENTIFER;
+        tsv->svl = S_STATION_IDENTIFER;
+
+        tsv->svv[0] = MSB(tp->misc_command_data[0]);
+        tsv->svv[1] = LSB(tp->misc_command_data[0]);
+
+        tsv->svv[2] = MSB(tp->misc_command_data[1]);
+        tsv->svv[3] = LSB(tp->misc_command_data[1]);
+
+        tsv->svv[4] = MSB(tp->misc_command_data[2]);
+        tsv->svv[5] = LSB(tp->misc_command_data[2]);
+
+        return (0);
+}
+
+static int smctr_make_ring_station_status(struct net_device *dev,
+        MAC_SUB_VECTOR * tsv)
+{
+        tsv->svi = RING_STATION_STATUS;
+        tsv->svl = S_RING_STATION_STATUS;
+
+        tsv->svv[0] = 0;
+        tsv->svv[1] = 0;
+        tsv->svv[2] = 0;
+        tsv->svv[3] = 0;
+        tsv->svv[4] = 0;
+        tsv->svv[5] = 0;
+
+        return (0);
+}
+
+static int smctr_make_ring_station_version(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        tsv->svi = RING_STATION_VERSION_NUMBER;
+        tsv->svl = S_RING_STATION_VERSION_NUMBER;
+
+        tsv->svv[0] = 0xe2;            /* EBCDIC - S */
+        tsv->svv[1] = 0xd4;            /* EBCDIC - M */
+        tsv->svv[2] = 0xc3;            /* EBCDIC - C */
+        tsv->svv[3] = 0x40;            /* EBCDIC -   */
+        tsv->svv[4] = 0xe5;            /* EBCDIC - V */
+        tsv->svv[5] = 0xF0 + (tp->microcode_version >> 4);
+        tsv->svv[6] = 0xF0 + (tp->microcode_version & 0x0f);
+        tsv->svv[7] = 0x40;            /* EBCDIC -   */
+        tsv->svv[8] = 0xe7;            /* EBCDIC - X */
+
+        if(tp->extra_info & CHIP_REV_MASK)
+                tsv->svv[9] = 0xc5;    /* EBCDIC - E */
+        else
+                tsv->svv[9] = 0xc4;    /* EBCDIC - D */
+
+        return (0);
+}
+
+static int smctr_make_tx_status_code(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv, __u16 tx_fstatus)
+{
+        tsv->svi = TRANSMIT_STATUS_CODE;
+        tsv->svl = S_TRANSMIT_STATUS_CODE;
+
+        tsv->svv[0] = ((tx_fstatus & 0x0100 >> 6) || IBM_PASS_SOURCE_ADDR);
+
+        /* Stripped frame status of Transmitted Frame */
+        tsv->svv[1] = tx_fstatus & 0xff;
+
+        return (0);
+}
+
+static int smctr_make_upstream_neighbor_addr(struct net_device *dev,
+        MAC_SUB_VECTOR *tsv)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        smctr_get_upstream_neighbor_addr(dev);
+
+        tsv->svi = UPSTREAM_NEIGHBOR_ADDRESS;
+        tsv->svl = S_UPSTREAM_NEIGHBOR_ADDRESS;
+
+        tsv->svv[0] = MSB(tp->misc_command_data[0]);
+        tsv->svv[1] = LSB(tp->misc_command_data[0]);
+
+        tsv->svv[2] = MSB(tp->misc_command_data[1]);
+        tsv->svv[3] = LSB(tp->misc_command_data[1]);
+
+        tsv->svv[4] = MSB(tp->misc_command_data[2]);
+        tsv->svv[5] = LSB(tp->misc_command_data[2]);
+
+        return (0);
+}
+
+static int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv)
+{
+        tsv->svi = WRAP_DATA;
+        tsv->svl = S_WRAP_DATA;
+
+        return (0);
+}
+
+/*
+ * Open/initialize the board. This is called sometime after
+ * booting when the 'ifconfig' program is run.
+ *
+ * This routine should set everything up anew at each open, even
+ * registers that "should" only need to be set once at boot, so that
+ * there is non-reboot way to recover if something goes wrong.
+ */
+static int smctr_open(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int err;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_open\n", dev->name);
+
+        tp->status = NOT_INITIALIZED;
+
+        err = smctr_load_firmware(dev);
+        if(err < 0)
+                return (err);
+
+        err = smctr_init_adapter(dev);
+        if(err < 0)
+                return (err);
+
+#ifdef MODULE
+        MOD_INC_USE_COUNT;
+#endif
+
+        return (err);
+}
+
+/* Interrupt driven open of Token card. */
+static int smctr_open_tr(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned long flags;
+        int err;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_open_tr\n", dev->name);
+
+        /* Now we can actually open the adapter. */
+        if(tp->status == OPEN)
+                return (0);
+        if(tp->status != INITIALIZED)
+                return (-1);
+
+        save_flags(flags);
+        cli();
+
+        smctr_set_page(dev, (__u8 *)tp->ram_access);
+
+        if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)MAC_QUEUE)))
+                return (err);
+
+        if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)MAC_QUEUE)))
+                return (err);
+
+        if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)NON_MAC_QUEUE)))
+                return (err);
+
+        if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)NON_MAC_QUEUE)))
+                return (err);
+
+        tp->status = CLOSED;
+
+        /* Insert into the Ring or Enter Loopback Mode. */
+        if((tp->mode_bits & LOOPING_MODE_MASK) == LOOPBACK_MODE_1)
+        {
+                tp->status = CLOSED;
+
+                if(!(err = smctr_issue_trc_loopback_cmd(dev)))
+                {
+                        if(!(err = smctr_wait_cmd(dev)))
+                                tp->status = OPEN;
+                }
+
+                smctr_status_chg(dev);
+        }
+        else
+        {
+                if((tp->mode_bits & LOOPING_MODE_MASK) == LOOPBACK_MODE_2)
+                {
+                        tp->status = CLOSED;
+                        if(!(err = smctr_issue_tri_loopback_cmd(dev)))
+                        {
+                                if(!(err = smctr_wait_cmd(dev)))
+                                        tp->status = OPEN;
+                        }
+
+                        smctr_status_chg(dev);
+                }
+                else
+                {
+                        if((tp->mode_bits & LOOPING_MODE_MASK)
+                                == LOOPBACK_MODE_3)
+                        {
+                                tp->status = CLOSED;
+                                if(!(err = smctr_lobe_media_test_cmd(dev)))
+                                {
+                                        if(!(err = smctr_wait_cmd(dev)))
+                                                tp->status = OPEN;
+                                }
+                                smctr_status_chg(dev);
+                        }
+                        else
+                        {
+                                if(!(err = smctr_lobe_media_test(dev)))
+                                        err = smctr_issue_insert_cmd(dev);
+                        }
+                }
+        }
+
+        restore_flags(flags);
+
+        return (err);
+}
+
+/* Check for a network adapter of this type, and return '0 if one exists.
+ * If dev->base_addr == 0, probe all likely locations.
+ * If dev->base_addr == 1, always return failure.
+ */
+int __init smctr_probe (struct net_device *dev)
+{
+        int i;
+        int base_addr = dev ? dev->base_addr : 0;
+
+        if(base_addr > 0x1ff)    /* Check a single specified location. */
+                return (smctr_probe1(dev, base_addr));
+        else if(base_addr != 0)  /* Don't probe at all. */
+                return (-ENXIO);
+
+        for(i = 0; smctr_portlist[i]; i++)
+        {
+                int ioaddr = smctr_portlist[i];
+                if(check_region(ioaddr, SMCTR_IO_EXTENT))
+                        continue;
+                if(smctr_probe1(dev, ioaddr))
+                {
+#ifndef MODULE
+                        tr_freedev(dev);
+#endif
+                }
+                else
+                        return (0);
+        }
+
+        return (-ENODEV);
+}
+
+static int __init smctr_probe1(struct net_device *dev, int ioaddr)
+{
+        static unsigned version_printed = 0;
+        struct net_local *tp;
+        int err;
+        __u32 *ram;
+
+        if(smctr_debug && version_printed++ == 0)
+                printk("%s", version);
+
+#ifndef MODULE
+        dev = init_trdev(dev, 0);
+        if(dev == NULL)
+                return (-ENOMEM);
+#endif
+
+        /* See if we have a SMCTR card floating around. */
+        if((ioaddr & 0x1F) != 0)
+                return (-ENODEV);            /* No Adapter */
+
+        /* Setup this devices private information structure */
+        tp = (struct net_local *)kmalloc(sizeof(struct net_local),
+                GFP_KERNEL);
+        if(tp == NULL)
+                return (-ENOMEM);
+        memset(tp, 0, sizeof(struct net_local));
+        dev->priv = tp;
+        dev->base_addr = ioaddr;
+
+        err = smctr_find_adapter(dev);
+        if(err < 0)
+        {
+                kfree_s(tp, sizeof(struct net_local));
+                return (-ENODEV);
+        }
+
+        tp = (struct net_local *)dev->priv;
+        dev->rmem_start = dev->mem_start = tp->ram_base;
+        dev->rmem_end = dev->mem_end = dev->mem_start + 0x10000;
+        ram = (__u32 *)phys_to_virt(dev->mem_start);
+        tp->ram_access = *(__u32 *)&ram;
+
+       /* Allow user to specify ring speed on module insert. */
+       if(ringspeed == 4)
+               tp->media_type = MEDIA_UTP_4;
+       else
+               tp->media_type = MEDIA_UTP_16;
+
+        printk("%s: %s %s at Io %#4x, Irq %d, Rom %#4x, Ram %#4x.\n",
+                dev->name, smctr_name, smctr_model,
+                (unsigned int)dev->base_addr,
+                dev->irq, tp->rom_base, tp->ram_base);
+
+        dev->init               = smctr_init_card;
+        dev->open               = smctr_open;
+        dev->stop               = smctr_close;
+        dev->hard_start_xmit    = smctr_send_packet;
+        dev->get_stats          = smctr_get_stats;
+        dev->set_multicast_list = &smctr_set_multicast_list;
+
+        return (0);
+}
+
+static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
+        struct net_device *dev, __u16 rx_status)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        struct sk_buff *skb;
+        __u16 rcode, correlator;
+        int err = 0;
+        __u8 xframe = 1;
+        __u16 tx_fstatus;
+
+        rmf->vl = SWAP_BYTES(rmf->vl);
+        if(rx_status & FCB_RX_STATUS_DA_MATCHED)
+        {
+                switch(rmf->vc)
+                {
+                        /* Received MAC Frames Processed by RS. */
+                        case INIT:
+                                if((rcode = smctr_rcv_init(dev, rmf,
+                                        &correlator)) == HARDWARE_FAILED)
+                                {
+                                        return (rcode);
+                                }
+
+                                if((err = smctr_send_rsp(dev, rmf, rcode,
+                                        correlator)))
+                                {
+                                        return (err);
+                                }
+                                break;
+
+                        case CHG_PARM:
+                                if((rcode = smctr_rcv_chg_param(dev, rmf,
+                                        &correlator)) ==HARDWARE_FAILED)
+                                {
+                                        return (rcode);
+                                }
+
+                                if((err = smctr_send_rsp(dev, rmf, rcode,
+                                        correlator)))
+                                {
+                                        return (err);
+                                }
+                                break;
+
+                        case RQ_ADDR:
+                                if((rcode = smctr_rcv_rq_addr_state_attch(dev,
+                                        rmf, &correlator)) != POSITIVE_ACK)
+                                {
+                                        if(rcode == HARDWARE_FAILED)
+                                                return (rcode);
+                                        else
+                                                return (smctr_send_rsp(dev, rmf,
+                                                        rcode, correlator));
+                                }
+
+                                if((err = smctr_send_rpt_addr(dev, rmf,
+                                        correlator)))
+                                {
+                                        return (err);
+                                }
+                                break;
+
+                        case RQ_ATTCH:
+                                if((rcode = smctr_rcv_rq_addr_state_attch(dev,
+                                        rmf, &correlator)) != POSITIVE_ACK)
+                                {
+                                        if(rcode == HARDWARE_FAILED)
+                                                return (rcode);
+                                        else
+                                                return (smctr_send_rsp(dev, rmf,
+                                                        rcode,
+                                                        correlator));
+                                }
+
+                                if((err = smctr_send_rpt_attch(dev, rmf,
+                                        correlator)))
+                                {
+                                        return (err);
+                                }
+                                break;
+
+                        case RQ_STATE:
+                                if((rcode = smctr_rcv_rq_addr_state_attch(dev,
+                                        rmf, &correlator)) != POSITIVE_ACK)
+                                {
+                                        if(rcode == HARDWARE_FAILED)
+                                                return (rcode);
+                                        else
+                                                return (smctr_send_rsp(dev, rmf,
+                                                        rcode,
+                                                        correlator));
+                                }
+
+                                if((err = smctr_send_rpt_state(dev, rmf,
+                                        correlator)))
+                                {
+                                        return (err);
+                                }
+                                break;
+
+                        case TX_FORWARD:
+                                if((rcode = smctr_rcv_tx_forward(dev, rmf))
+                                        != POSITIVE_ACK)
+                                {
+                                        if(rcode == HARDWARE_FAILED)
+                                                return (rcode);
+                                        else
+                                                return (smctr_send_rsp(dev, rmf,
+                                                        rcode,
+                                                        correlator));
+                                }
+
+                                if((err = smctr_send_tx_forward(dev, rmf,
+                                        &tx_fstatus)) == HARDWARE_FAILED)
+                                {
+                                        return (err);
+                                }
+
+                                if(err == A_FRAME_WAS_FORWARDED)
+                                {
+                                        if((err = smctr_send_rpt_tx_forward(dev,
+                                               rmf, tx_fstatus))
+                                                == HARDWARE_FAILED)
+                                        {
+                                                return (err);
+                                        }
+                                }
+                                break;
+
+                        /* Received MAC Frames Processed by CRS/REM/RPS. */
+                        case RSP:
+                        case RQ_INIT:
+                        case RPT_NEW_MON:
+                        case RPT_SUA_CHG:
+                        case RPT_ACTIVE_ERR:
+                        case RPT_NN_INCMP:
+                        case RPT_ERROR:
+                        case RPT_ATTCH:
+                        case RPT_STATE:
+                        case RPT_ADDR:
+                                break;
+
+                        /* Rcvd Att. MAC Frame (if RXATMAC set) or UNKNOWN */
+                        default:
+                                xframe = 0;
+                                if(!(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES))
+                                {
+                                        rcode = smctr_rcv_unknown(dev, rmf,
+                                                &correlator);
+                                        if((err = smctr_send_rsp(dev, rmf,rcode,
+                                                correlator)))
+                                        {
+                                                return (err);
+                                        }
+                                }
+
+                                break;
+                }
+        }
+        else
+        {
+                /* 1. DA doesn't match (Promiscuous Mode).
+                 * 2. Parse for Extended MAC Frame Type.
+                 */
+                switch(rmf->vc)
+                {
+                        case RSP:
+                        case INIT:
+                        case RQ_INIT:
+                        case RQ_ADDR:
+                        case RQ_ATTCH:
+                        case RQ_STATE:
+                        case CHG_PARM:
+                        case RPT_ADDR:
+                        case RPT_ERROR:
+                        case RPT_ATTCH:
+                        case RPT_STATE:
+                        case RPT_NEW_MON:
+                        case RPT_SUA_CHG:
+                        case RPT_NN_INCMP:
+                        case RPT_ACTIVE_ERR:
+                                break;
+
+                        default:
+                                xframe = 0;
+                                break;
+                }
+        }
+
+        /* NOTE: UNKNOWN MAC frames will NOT be passed up unless
+         * ACCEPT_ATT_MAC_FRAMES is set.
+         */
+        if(((tp->receive_mask & ACCEPT_ATT_MAC_FRAMES)
+                && (xframe == (__u8)0))
+                || ((tp->receive_mask & ACCEPT_EXT_MAC_FRAMES)
+                && (xframe == (__u8)1)))
+        {
+                rmf->vl = SWAP_BYTES(rmf->vl);
+
+                skb = dev_alloc_skb(size);
+                skb->len = size;
+
+                /* Slide data into a sleek skb. */
+                skb_put(skb, skb->len);
+                memcpy(skb->data, rmf, skb->len);
+
+                /* Update Counters */
+                tp->MacStat.rx_packets++;
+                tp->MacStat.rx_bytes += skb->len;
+
+                /* Kick the packet on up. */
+                skb->dev = dev;
+                skb->protocol = tr_type_trans(skb, dev);
+                netif_rx(skb);
+                err = 0;
+        }
+
+        return (err);
+}
+
+/* Test for RAM in adapter RAM space. */
+static int smctr_ram_conflict_test(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i;
+        __u16 sword;
+
+        for(i = 0; i < (unsigned int)(tp->ram_usable * 1024); i += 1024)
+        {
+                sword = *(__u16 *)(tp->ram_access + i);
+                *(__u16 *)(tp->ram_access + i) = 0x1234;
+                if(*(__u16 *)(tp->ram_access + i) == 0x1234)
+                {
+                        *(__u16 *)(tp->ram_access + i) = sword;
+                        return (-1);
+                }
+        }
+
+        return (0);
+}
+
+/* Adapter RAM test. Incremental word ODD boundry data test. */
+static int smctr_ram_memory_test(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        __u16 page, pages_of_ram, start_pattern = 0, word_pattern = 0,
+                word_read = 0, err_word = 0, err_pattern = 0;
+        unsigned int err_offset;
+        __u32 j, pword;
+        __u8 err = 0;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_ram_memory_test\n", dev->name);
+
+        start_pattern   = 0x0001;
+        pages_of_ram    = tp->ram_size / tp->ram_usable;
+        pword           = tp->ram_access;
+
+        /* Incremental word ODD boundry test. */
+        for(page = 0; (page < pages_of_ram) && (~err);
+                page++, start_pattern += 0x8000)
+        {
+                smctr_set_page(dev, (__u8 *)(tp->ram_access
+                        + (page * tp->ram_usable * 1024) + 1));
+                word_pattern = start_pattern;
+
+                for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1; j += 2)
+                        *(__u16 *)(pword + j) = word_pattern++;
+
+                word_pattern = start_pattern;
+
+                for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1
+                        && (~err); j += 2, word_pattern++)
+                {
+                        word_read = *(__u16 *)(pword + j);
+                        if(word_read != word_pattern)
+                        {
+                                err             = (__u8)1;
+                                err_offset      = j;
+                                err_word        = word_read;
+                                err_pattern     = word_pattern;
+                                return (-1);
+                        }
+                }
+        }
+
+        /* Zero out memory. */
+        for(page = 0; page < pages_of_ram && (~err); page++)
+        {
+                smctr_set_page(dev, (__u8 *)(tp->ram_access
+                        + (page * tp->ram_usable * 1024)));
+                word_pattern = 0;
+
+                for(j = 0; j < (__u32)tp->ram_usable * 1024; j +=2)
+                        *(__u16 *)(pword + j) = word_pattern;
+
+                for(j =0; j < (__u32)tp->ram_usable * 1024
+                        && (~err); j += 2)
+                {
+                        word_read = *(__u16 *)(pword + j);
+                        if(word_read != word_pattern)
+                        {
+                                err             = (__u8)1;
+                                err_offset      = j;
+                                err_word        = word_read;
+                                err_pattern     = word_pattern;
+                                return (-1);
+                        }
+                }
+        }
+
+        smctr_set_page(dev, (__u8 *)tp->ram_access);
+
+        return (0);
+}
+
+static unsigned int __init smctr_read_584_chksum(int ioaddr)
+{
+        __u8 pg_no, r1, r2;
+        __u16 byte_no, csum_val = 0;
+
+        for(pg_no = 0; pg_no < 16; pg_no++)
+        {
+                r1 = inb(ioaddr + 0x01);
+                r1 &= 0x04;
+                r1 |= 0x02;
+
+                outb(r1, ioaddr + 0x01);
+
+                r1 = inb(ioaddr + 0x03);
+                r1 &= 0x0f;
+                r1 |= (pg_no << 4);
+
+                outb(r1, ioaddr + 0x03);
+
+                r1 = inb(ioaddr + 0x01);
+                r1 &= 0x04;
+                r1 |= 0x12;
+
+                outb(r1, ioaddr + 0x01);
+
+                do {
+                        r1 = inb(ioaddr + 0x01);
+                } while(r1 & 0x10);
+
+                r2 = 0;
+                for(byte_no = 0x08; byte_no < 0x10; byte_no++)
+                {
+                        r1 = inb(ioaddr + byte_no);
+                        r2 += r1;
+                }
+
+                csum_val += r2;
+        }
+
+        r1 = inb(ioaddr + 0x01);
+        r1 &= 0x04;
+        r1 |= 0x10;
+        outb(r1, ioaddr + 0x01);
+
+        csum_val &= 0xff;
+        if(csum_val == 0xff)
+                return (0);
+        else
+                return (-1);
+}
+
+static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 *correlator)
+{
+        MAC_SUB_VECTOR *rsv;
+        signed short vlen;
+        __u16 rcode = POSITIVE_ACK;
+        unsigned int svectors = F_NO_SUB_VECTORS_FOUND;
+
+        /* This Frame can only come from a CRS */
+        if((rmf->dc_sc & SC_MASK) != SC_CRS)
+                return(E_INAPPROPRIATE_SOURCE_CLASS);
+
+        /* Remove MVID Length from total length. */
+        vlen = (signed short)rmf->vl - 4;
+
+        /* Point to First SVID */
+        rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER));
+
+        /* Search for Appropriate SVID's. */
+        while((vlen > 0) && (rcode == POSITIVE_ACK))
+        {
+                switch(rsv->svi)
+                {
+                        case CORRELATOR:
+                                svectors |= F_CORRELATOR;
+                                rcode = smctr_set_corr(dev, rsv, correlator);
+                                break;
+
+                        case LOCAL_RING_NUMBER:
+                                svectors |= F_LOCAL_RING_NUMBER;
+                                rcode = smctr_set_local_ring_num(dev, rsv);
+                                break;
+
+                        case ASSIGN_PHYSICAL_DROP:
+                                svectors |= F_ASSIGN_PHYSICAL_DROP;
+                                rcode = smctr_set_phy_drop(dev, rsv);
+                                break;
+
+                        case ERROR_TIMER_VALUE:
+                                svectors |= F_ERROR_TIMER_VALUE;
+                                rcode = smctr_set_error_timer_value(dev, rsv);
+                                break;
+
+                        case AUTHORIZED_FUNCTION_CLASS:
+                                svectors |= F_AUTHORIZED_FUNCTION_CLASS;
+                                rcode = smctr_set_auth_funct_class(dev, rsv);
+                                break;
+
+                        case AUTHORIZED_ACCESS_PRIORITY:
+                                svectors |= F_AUTHORIZED_ACCESS_PRIORITY;
+                                rcode = smctr_set_auth_access_pri(dev, rsv);
+                                break;
+
+                        default:
+                                rcode = E_SUB_VECTOR_UNKNOWN;
+                                break;
+                }
+
+                /* Let Sender Know if SUM of SV length's is
+                 * larger then length in MVID length field
+                 */
+                if((vlen -= rsv->svl) < 0)
+                        rcode = E_VECTOR_LENGTH_ERROR;
+
+                rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl);
+        }
+
+        if(rcode == POSITIVE_ACK)
+        {
+                /* Let Sender Know if MVID length field
+                 * is larger then SUM of SV length's
+                 */
+                if(vlen != 0)
+                        rcode = E_VECTOR_LENGTH_ERROR;
+                else
+               {
+                       /* Let Sender Know if Expected SVID Missing */
+                       if((svectors & R_CHG_PARM) ^ R_CHG_PARM)
+                               rcode = E_MISSING_SUB_VECTOR;
+               }
+        }
+
+        return (rcode);
+}
+
+static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 *correlator)
+{
+        MAC_SUB_VECTOR *rsv;
+        signed short vlen;
+        __u16 rcode = POSITIVE_ACK;
+        unsigned int svectors = F_NO_SUB_VECTORS_FOUND;
+
+        /* This Frame can only come from a RPS */
+        if((rmf->dc_sc & SC_MASK) != SC_RPS)
+                return (E_INAPPROPRIATE_SOURCE_CLASS);
+
+        /* Remove MVID Length from total length. */
+        vlen = (signed short)rmf->vl - 4;
+
+        /* Point to First SVID */
+        rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER));
+
+        /* Search for Appropriate SVID's */
+        while((vlen > 0) && (rcode == POSITIVE_ACK))
+        {
+                switch(rsv->svi)
+                {
+                        case CORRELATOR:
+                                svectors |= F_CORRELATOR;
+                                rcode = smctr_set_corr(dev, rsv, correlator);
+                                break;
+
+                        case LOCAL_RING_NUMBER:
+                                svectors |= F_LOCAL_RING_NUMBER;
+                                rcode = smctr_set_local_ring_num(dev, rsv);
+                                break;
+
+                        case ASSIGN_PHYSICAL_DROP:
+                                svectors |= F_ASSIGN_PHYSICAL_DROP;
+                                rcode = smctr_set_phy_drop(dev, rsv);
+                                break;
+
+                        case ERROR_TIMER_VALUE:
+                                svectors |= F_ERROR_TIMER_VALUE;
+                                rcode = smctr_set_error_timer_value(dev, rsv);
+                                break;
+
+                        default:
+                                rcode = E_SUB_VECTOR_UNKNOWN;
+                                break;
+                }
+
+                /* Let Sender Know if SUM of SV length's is
+                 * larger then length in MVID length field
+                */
+                if((vlen -= rsv->svl) < 0)
+                        rcode = E_VECTOR_LENGTH_ERROR;
+
+                rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl);
+        }
+
+        if(rcode == POSITIVE_ACK)
+        {
+                /* Let Sender Know if MVID length field
+                 * is larger then SUM of SV length's
+                 */
+                if(vlen != 0)
+                        rcode = E_VECTOR_LENGTH_ERROR;
+                else
+               {
+                       /* Let Sender Know if Expected SV Missing */
+                       if((svectors & R_INIT) ^ R_INIT)
+                               rcode = E_MISSING_SUB_VECTOR;
+               }
+        }
+
+        return (rcode);
+}
+
+static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf)
+{
+        MAC_SUB_VECTOR *rsv;
+        signed short vlen;
+        __u16 rcode = POSITIVE_ACK;
+        unsigned int svectors = F_NO_SUB_VECTORS_FOUND;
+
+        /* This Frame can only come from a CRS */
+        if((rmf->dc_sc & SC_MASK) != SC_CRS)
+                return (E_INAPPROPRIATE_SOURCE_CLASS);
+
+        /* Remove MVID Length from total length */
+        vlen = (signed short)rmf->vl - 4;
+
+        /* Point to First SVID */
+        rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER));
+
+        /* Search for Appropriate SVID's */
+        while((vlen > 0) && (rcode == POSITIVE_ACK))
+        {
+                switch(rsv->svi)
+                {
+                        case FRAME_FORWARD:
+                                svectors |= F_FRAME_FORWARD;
+                                rcode = smctr_set_frame_forward(dev, rsv, 
+                                       rmf->dc_sc);
+                                break;
+
+                        default:
+                                rcode = E_SUB_VECTOR_UNKNOWN;
+                                break;
+                }
+
+                /* Let Sender Know if SUM of SV length's is
+                 * larger then length in MVID length field
+                */
+                if((vlen -= rsv->svl) < 0)
+                        rcode = E_VECTOR_LENGTH_ERROR;
+
+                rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl);
+        }
+
+        if(rcode == POSITIVE_ACK)
+        {
+                /* Let Sender Know if MVID length field
+                 * is larger then SUM of SV length's
+                 */
+                if(vlen != 0)
+                        rcode = E_VECTOR_LENGTH_ERROR;
+                else
+               {
+                       /* Let Sender Know if Expected SV Missing */
+                       if((svectors & R_TX_FORWARD) ^ R_TX_FORWARD)
+                               rcode = E_MISSING_SUB_VECTOR;
+               }
+        }
+
+        return (rcode);
+}
+
+static int smctr_rcv_rq_addr_state_attch(struct net_device *dev,
+        MAC_HEADER *rmf, __u16 *correlator)
+{
+        MAC_SUB_VECTOR *rsv;
+        signed short vlen;
+        __u16 rcode = POSITIVE_ACK;
+        unsigned int svectors = F_NO_SUB_VECTORS_FOUND;
+
+        /* Remove MVID Length from total length */
+        vlen = (signed short)rmf->vl - 4;
+
+        /* Point to First SVID */
+        rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER));
+
+        /* Search for Appropriate SVID's */
+        while((vlen > 0) && (rcode == POSITIVE_ACK))
+        {
+                switch(rsv->svi)
+                {
+                        case CORRELATOR:
+                                svectors |= F_CORRELATOR;
+                                rcode = smctr_set_corr(dev, rsv, correlator);
+                                break;
+
+                        default:
+                                rcode = E_SUB_VECTOR_UNKNOWN;
+                                break;
+                }
+
+                /* Let Sender Know if SUM of SV length's is
+                 * larger then length in MVID length field
+                 */
+                if((vlen -= rsv->svl) < 0)
+                        rcode = E_VECTOR_LENGTH_ERROR;
+
+                rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl);
+        }
+
+        if(rcode == POSITIVE_ACK)
+        {
+                /* Let Sender Know if MVID length field
+                 * is larger then SUM of SV length's
+                 */
+                if(vlen != 0)
+                        rcode = E_VECTOR_LENGTH_ERROR;
+                else
+               {
+                       /* Let Sender Know if Expected SVID Missing */
+                       if((svectors & R_RQ_ATTCH_STATE_ADDR) 
+                               ^ R_RQ_ATTCH_STATE_ADDR)
+                               rcode = E_MISSING_SUB_VECTOR;
+                       }
+        }
+
+        return (rcode);
+}
+
+static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 *correlator)
+{
+        MAC_SUB_VECTOR *rsv;
+        signed short vlen;
+
+        *correlator = 0;
+
+        /* Remove MVID Length from total length */
+        vlen = (signed short)rmf->vl - 4;
+
+        /* Point to First SVID */
+        rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER));
+
+        /* Search for CORRELATOR for RSP to UNKNOWN */
+        while((vlen > 0) && (*correlator == 0))
+        {
+                switch(rsv->svi)
+                {
+                        case CORRELATOR:
+                                smctr_set_corr(dev, rsv, correlator);
+                                break;
+
+                        default:
+                                break;
+                }
+
+                vlen -= rsv->svl;
+                rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl);
+        }
+
+        return (E_UNRECOGNIZED_VECTOR_ID);
+}
+
+/*
+ * Reset the 825 NIC and exit w:
+ * 1. The NIC reset cleared (non-reset state), halted and un-initialized.
+ * 2. TINT masked.
+ * 3. CBUSY masked.
+ * 4. TINT clear.
+ * 5. CBUSY clear.
+ */
+static int smctr_reset_adapter(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int ioaddr = dev->base_addr;
+
+        /* Reseting the NIC will put it in a halted and un-initialized state. */        smctr_set_trc_reset(ioaddr);
+        udelay(200000); /* ~2 ms */
+
+        smctr_clear_trc_reset(ioaddr);
+        udelay(200000); /* ~2 ms */
+
+        /* Remove any latched interrupts that occured prior to reseting the
+         * adapter or possibily caused by line glitches due to the reset.
+         */
+        outb(tp->trc_mask | CSR_CLRTINT | CSR_CLRCBUSY, ioaddr + CSR);
+
+        return (0);
+}
+
+static int smctr_restart_tx_chain(struct net_device *dev, short queue)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int err = 0;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_restart_tx_chain\n", dev->name);
+
+        if(tp->num_tx_fcbs_used[queue] != 0
+                && tp->tx_queue_status[queue] == NOT_TRANSMITING)
+        {
+                tp->tx_queue_status[queue] = TRANSMITING;
+                err = smctr_issue_resume_tx_fcb_cmd(dev, queue);
+        }
+
+        return (err);
+}
+
+static int smctr_ring_status_chg(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_ring_status_chg\n", dev->name);
+
+        /* Check for ring_status_flag: whenever MONITOR_STATE_BIT
+         * Bit is set, check value of monitor_state, only then we
+         * enable and start transmit/receive timeout (if and only
+         * if it is MS_ACTIVE_MONITOR_STATE or MS_STANDBY_MONITOR_STATE)
+         */
+        if(tp->ring_status_flags == MONITOR_STATE_CHANGED)
+        {
+                if((tp->monitor_state == MS_ACTIVE_MONITOR_STATE)
+                        || (tp->monitor_state == MS_STANDBY_MONITOR_STATE))
+                {
+                        tp->monitor_state_ready = 1;
+                }
+                else
+                {
+                        /* if adapter is NOT in either active monitor
+                         * or standby monitor state => Disable
+                         * transmit/receive timeout.
+                         */
+                        tp->monitor_state_ready = 0;
+
+                       /* Ring speed problem, switching to auto mode. */
+                       if(tp->monitor_state == MS_MONITOR_FSM_INACTIVE
+                               && !tp->cleanup)
+                       {
+                               printk(KERN_INFO "%s: Incorrect ring speed switching.\n",
+                                       dev->name);
+                               smctr_set_ring_speed(dev);
+                       }
+                }
+        }
+
+        if(!(tp->ring_status_flags & RING_STATUS_CHANGED))
+                return (0);
+
+        switch(tp->ring_status)
+        {
+                case RING_RECOVERY:
+                        printk(KERN_INFO "%s: Ring Recovery\n", dev->name);
+                        tp->current_ring_status |= RING_RECOVERY;
+                        break;
+
+                case SINGLE_STATION:
+                        printk(KERN_INFO "%s: Single Statinon\n", dev->name);
+                        tp->current_ring_status |= SINGLE_STATION;
+                        break;
+
+                case COUNTER_OVERFLOW:
+                        printk(KERN_INFO "%s: Counter Overflow\n", dev->name);
+                        tp->current_ring_status |= COUNTER_OVERFLOW;
+                        break;
+
+                case REMOVE_RECEIVED:
+                        printk(KERN_INFO "%s: Remove Received\n", dev->name);
+                        tp->current_ring_status |= REMOVE_RECEIVED;
+                        break;
+
+                case AUTO_REMOVAL_ERROR:
+                        printk(KERN_INFO "%s: Auto Remove Error\n", dev->name);
+                        tp->current_ring_status |= AUTO_REMOVAL_ERROR;
+                        break;
+
+                case LOBE_WIRE_FAULT:
+                        printk(KERN_INFO "%s: Lobe Wire Fault\n", dev->name);
+                        tp->current_ring_status |= LOBE_WIRE_FAULT;
+                        break;
+
+                case TRANSMIT_BEACON:
+                        printk(KERN_INFO "%s: Transmit Beacon\n", dev->name);
+                        tp->current_ring_status |= TRANSMIT_BEACON;
+                        break;
+
+                case SOFT_ERROR:
+                        printk(KERN_INFO "%s: Soft Error\n", dev->name);
+                        tp->current_ring_status |= SOFT_ERROR;
+                        break;
+
+                case HARD_ERROR:
+                        printk(KERN_INFO "%s: Hard Error\n", dev->name);
+                        tp->current_ring_status |= HARD_ERROR;
+                        break;
+
+                case SIGNAL_LOSS:
+                        printk(KERN_INFO "%s: Singal Loss\n", dev->name);
+                        tp->current_ring_status |= SIGNAL_LOSS;
+                        break;
+
+                default:
+                       printk(KERN_INFO "%s: Unknown ring status change\n",
+                               dev->name);
+                        break;
+        }
+
+        return (0);
+}
+
+/* Test for ROM signature within adapter RAM space. */
+static int smctr_rom_conflict_test(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i;
+
+        for(i = 0; i < (unsigned int)tp->ram_usable * 1024; i += 4096)
+        {
+                if(*(__u16 *)(tp->ram_access + i) == 0xaa55)
+                        return (-1);
+        }
+
+        return (0);
+}
+
+static int smctr_rx_frame(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        __u16 queue, status, rx_size, err = 0;
+        __u8 *pbuff;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_rx_frame\n", dev->name);
+
+        cli();
+        queue = tp->receive_queue_number;
+
+        while((status = tp->rx_fcb_curr[queue]->frame_status) != SUCCESS)
+        {
+                err = HARDWARE_FAILED;
+
+                if(((status & 0x007f) == 0)
+                        || ((tp->receive_mask & ACCEPT_ERR_PACKETS) != 0))
+                {
+                        /* frame length less the CRC (4 bytes) + FS (1 byte) */
+                        rx_size = tp->rx_fcb_curr[queue]->frame_length - 5;
+
+                        pbuff = smctr_get_rx_pointer(dev, queue);
+
+                        smctr_set_page(dev, pbuff);
+                        smctr_disable_16bit(dev);
+
+                        /* pbuff points to addr within one page */
+                        pbuff = (__u8 *)PAGE_POINTER(pbuff);
+
+                        if(queue == NON_MAC_QUEUE)
+                        {
+                                struct sk_buff *skb;
+
+                                skb = dev_alloc_skb(rx_size);
+                                skb_put(skb, rx_size);
+
+                                memcpy(skb->data, pbuff, rx_size);
+                                sti();
+
+                                /* Update Counters */
+                                tp->MacStat.rx_packets++;
+                                tp->MacStat.rx_bytes += skb->len;
+
+                                /* Kick the packet on up. */
+                                skb->dev = dev;
+                                skb->protocol = tr_type_trans(skb, dev);
+                                netif_rx(skb);
+                        }
+                        else
+                                smctr_process_rx_packet((MAC_HEADER *)pbuff,
+                                        rx_size, dev, status);
+                }
+
+                smctr_enable_16bit(dev);
+                smctr_set_page(dev, (__u8 *)tp->ram_access);
+                smctr_update_rx_chain(dev, queue);
+
+                if(err != SUCCESS)
+                        break;
+        }
+
+        return (err);
+}
+
+static int smctr_send_dat(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int i, err;
+        MAC_HEADER *tmf;
+        FCBlock *fcb;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_send_dat\n", dev->name);
+
+        if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE,
+                sizeof(MAC_HEADER))) == (FCBlock *)(-1L))
+        {
+                return (OUT_OF_RESOURCES);
+        }
+
+        /* Initialize DAT Data Fields. */
+        tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
+        tmf->ac = MSB(AC_FC_DAT);
+        tmf->fc = LSB(AC_FC_DAT);
+
+        for(i = 0; i < 6; i++)
+        {
+                tmf->sa[i] = dev->dev_addr[i];
+                tmf->da[i] = dev->dev_addr[i];
+
+        }
+
+        tmf->vc        = DAT;
+        tmf->dc_sc     = DC_RS | SC_RS;
+        tmf->vl        = 4;
+        tmf->vl        = SWAP_BYTES(tmf->vl);
+
+        /* Start Transmit. */
+        if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE)))
+                return (err);
+
+        /* Wait for Transmit to Complete */
+        for(i = 0; i < 10000; i++)
+        {
+                if(fcb->frame_status & FCB_COMMAND_DONE)
+                        break;
+                udelay(1000);
+        }
+
+        /* Check if GOOD frame Tx'ed. */
+        if(!(fcb->frame_status &  FCB_COMMAND_DONE)
+                || fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS))
+        {
+                return (INITIALIZE_FAILED);
+        }
+
+        /* De-allocated Tx FCB and Frame Buffer
+         * The FCB must be de-allocated manually if executing with
+         * interrupts disabled, other wise the ISR (LM_Service_Events)
+         * will de-allocate it when the interrupt occurs.
+         */
+        tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING;
+        smctr_update_tx_chain(dev, fcb, MAC_QUEUE);
+
+        return (0);
+}
+
+/*
+ * Gets skb from system, queues it and checks if it can be sent
+ */
+static int smctr_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_send_packet\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.
+                 *
+                 * Resetting the token ring adapter takes a long time so just
+                 * fake transmission time and go on trying. Our own timeout
+                 * routine is in sktr_timer_chk()
+                 */
+                dev->tbusy       = 0;
+                dev->trans_start = jiffies;
+                return (1);
+        }
+
+        /*
+         * If some higher layer thinks we've missed an tx-done interrupt we
+         * are passed NULL.
+         */
+        if(skb == NULL)
+                return (0);
+
+        /*
+         * Block a timer-based transmit from overlapping. This could better be
+         * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
+         */
+        if(test_and_set_bit(0, (void*)&dev->tbusy) != 0)
+        {
+                printk("%s: Transmitter access conflict.\n", dev->name);
+                return (1);
+        }
+
+        if(tp->QueueSkb == 0)
+                return (1);     /* Return with tbusy set: queue full */
+
+        tp->QueueSkb--;
+        skb_queue_tail(&tp->SendSkbQueue, skb);
+        smctr_hardware_send_packet(dev, tp);
+        if(tp->QueueSkb > 0)
+                dev->tbusy = 0;
+
+        return (0);
+}
+
+static int smctr_send_lobe_media_test(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+       MAC_SUB_VECTOR *tsv;
+       MAC_HEADER *tmf;
+        FCBlock *fcb;
+       __u32 i;
+       int err;
+
+        if(smctr_debug > 15)
+                printk("%s: smctr_send_lobe_media_test\n", dev->name);
+
+        if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(struct trh_hdr)
+                + S_WRAP_DATA + S_WRAP_DATA)) == (FCBlock *)(-1L))
+        {
+                return (OUT_OF_RESOURCES);
+        }
+
+        /* Initialize DAT Data Fields. */
+        tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
+        tmf->ac = MSB(AC_FC_LOBE_MEDIA_TEST);
+        tmf->fc = LSB(AC_FC_LOBE_MEDIA_TEST);
+
+        for(i = 0; i < 6; i++)
+        {
+                tmf->da[i] = 0;
+                tmf->sa[i] = dev->dev_addr[i];
+        }
+
+        tmf->vc        = LOBE_MEDIA_TEST;
+        tmf->dc_sc     = DC_RS | SC_RS;
+        tmf->vl        = 4;
+
+        tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
+        smctr_make_wrap_data(dev, tsv);
+        tmf->vl += tsv->svl;
+
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_wrap_data(dev, tsv);
+        tmf->vl += tsv->svl;
+
+        /* Start Transmit. */
+        tmf->vl = SWAP_BYTES(tmf->vl);
+        if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE)))
+                return (err);
+
+        /* Wait for Transmit to Complete. (10 ms). */
+        for(i=0; i < 10000; i++)
+        {
+                if(fcb->frame_status & FCB_COMMAND_DONE)
+                        break;
+                udelay(1000);
+        }
+
+        /* Check if GOOD frame Tx'ed */
+        if(!(fcb->frame_status & FCB_COMMAND_DONE)
+                || fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS))
+        {
+                return (LOBE_MEDIA_TEST_FAILED);
+        }
+
+        /* De-allocated Tx FCB and Frame Buffer
+         * The FCB must be de-allocated manually if executing with
+         * interrupts disabled, other wise the ISR (LM_Service_Events)
+         * will de-allocate it when the interrupt occurs.
+         */
+        tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING;
+        smctr_update_tx_chain(dev, fcb, MAC_QUEUE);
+
+        return (0);
+}
+
+static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 correlator)
+{
+        MAC_HEADER *tmf;
+        MAC_SUB_VECTOR *tsv;
+        FCBlock *fcb;
+
+        if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
+               + S_CORRELATOR + S_PHYSICAL_DROP + S_UPSTREAM_NEIGHBOR_ADDRESS
+               + S_ADDRESS_MODIFER + S_GROUP_ADDRESS + S_FUNCTIONAL_ADDRESS))
+               == (FCBlock *)(-1L))
+        {
+                return (0);
+        }
+
+        tmf            = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
+        tmf->vc        = RPT_ADDR;
+        tmf->dc_sc     = (rmf->dc_sc & SC_MASK) << 4;
+        tmf->vl        = 4;
+
+        smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_ADDR);
+
+        tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
+        smctr_make_corr(dev, tsv, correlator);
+
+        tmf->vl += tsv->svl;
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_phy_drop_num(dev, tsv);
+
+        tmf->vl += tsv->svl;
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_upstream_neighbor_addr(dev, tsv);
+
+        tmf->vl += tsv->svl;
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_addr_mod(dev, tsv);
+
+        tmf->vl += tsv->svl;
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_group_addr(dev, tsv);
+
+        tmf->vl += tsv->svl;
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_funct_addr(dev, tsv);
+
+        tmf->vl += tsv->svl;
+
+        /* Subtract out MVID and MVL which is
+         * include in both vl and MAC_HEADER
+         */
+/*      fcb->frame_length           = tmf->vl + sizeof(MAC_HEADER) - 4;
+        fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4;
+*/
+        tmf->vl = SWAP_BYTES(tmf->vl);
+
+        return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE));
+}
+
+static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 correlator)
+{
+        MAC_HEADER *tmf;
+        MAC_SUB_VECTOR *tsv;
+        FCBlock *fcb;
+
+        if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
+               + S_CORRELATOR + S_PRODUCT_INSTANCE_ID + S_FUNCTIONAL_ADDRESS
+               + S_AUTHORIZED_FUNCTION_CLASS + S_AUTHORIZED_ACCESS_PRIORITY))
+               == (FCBlock *)(-1L))
+        {
+                return (0);
+        }
+
+        tmf       = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
+        tmf->vc    = RPT_ATTCH;
+        tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4;
+        tmf->vl    = 4;
+
+        smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_ATTCH);
+
+        tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
+        smctr_make_corr(dev, tsv, correlator);
+
+        tmf->vl += tsv->svl;
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_product_id(dev, tsv);
+
+        tmf->vl += tsv->svl;
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_funct_addr(dev, tsv);
+
+        tmf->vl += tsv->svl;
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_auth_funct_class(dev, tsv);
+
+        tmf->vl += tsv->svl;
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_access_pri(dev, tsv);
+
+        tmf->vl += tsv->svl;
+
+        /* Subtract out MVID and MVL which is
+         * include in both vl and MAC_HEADER
+         */
+/*      fcb->frame_length           = tmf->vl + sizeof(MAC_HEADER) - 4;
+        fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4;
+*/
+        tmf->vl = SWAP_BYTES(tmf->vl);
+
+        return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE));
+}
+
+static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 correlator)
+{
+        MAC_HEADER *tmf;
+        MAC_SUB_VECTOR *tsv;
+        FCBlock *fcb;
+
+        if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
+               + S_CORRELATOR + S_RING_STATION_VERSION_NUMBER
+               + S_RING_STATION_STATUS + S_STATION_IDENTIFER))
+               == (FCBlock *)(-1L))
+        {
+                return (0);
+        }
+
+        tmf       = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
+        tmf->vc    = RPT_STATE;
+        tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4;
+        tmf->vl    = 4;
+
+        smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_STATE);
+
+        tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
+        smctr_make_corr(dev, tsv, correlator);
+
+        tmf->vl += tsv->svl;
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_ring_station_version(dev, tsv);
+
+        tmf->vl += tsv->svl;
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_ring_station_status(dev, tsv);
+
+        tmf->vl += tsv->svl;
+        tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+        smctr_make_station_id(dev, tsv);
+
+        tmf->vl += tsv->svl;
+
+        /* Subtract out MVID and MVL which is
+         * include in both vl and MAC_HEADER
+         */
+/*      fcb->frame_length           = tmf->vl + sizeof(MAC_HEADER) - 4;
+        fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4;
+*/
+        tmf->vl = SWAP_BYTES(tmf->vl);
+
+        return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE));
+}
+
+static int smctr_send_rpt_tx_forward(struct net_device *dev,
+        MAC_HEADER *rmf, __u16 tx_fstatus)
+{
+        MAC_HEADER *tmf;
+        MAC_SUB_VECTOR *tsv;
+        FCBlock *fcb;
+
+        if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
+               + S_TRANSMIT_STATUS_CODE)) == (FCBlock *)(-1L))
+        {
+                return (0);
+        }
+
+        tmf       = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
+        tmf->vc    = RPT_TX_FORWARD;
+        tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4;
+        tmf->vl    = 4;
+
+        smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_TX_FORWARD);
+
+        tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
+        smctr_make_tx_status_code(dev, tsv, tx_fstatus);
+
+        tmf->vl += tsv->svl;
+
+        /* Subtract out MVID and MVL which is
+         * include in both vl and MAC_HEADER
+         */
+/*      fcb->frame_length           = tmf->vl + sizeof(MAC_HEADER) - 4;
+        fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4;
+*/
+        tmf->vl = SWAP_BYTES(tmf->vl);
+
+        return(smctr_trc_send_packet(dev, fcb, MAC_QUEUE));
+}
+
+static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 rcode, __u16 correlator)
+{
+        MAC_HEADER *tmf;
+        MAC_SUB_VECTOR *tsv;
+        FCBlock *fcb;
+
+        if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
+               + S_CORRELATOR + S_RESPONSE_CODE)) == (FCBlock *)(-1L))
+        {
+                return (0);
+        }
+
+        tmf       = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
+        tmf->vc    = RSP;
+        tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4;
+        tmf->vl    = 4;
+
+        smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RSP);
+
+        tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
+        smctr_make_corr(dev, tsv, correlator);
+
+        return (0);
+}
+
+static int smctr_send_rq_init(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        MAC_HEADER *tmf;
+        MAC_SUB_VECTOR *tsv;
+        FCBlock *fcb;
+       unsigned int i, count = 0;
+       __u16 fstatus;
+       int err;
+
+        do {
+               if(((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
+                       + S_PRODUCT_INSTANCE_ID + S_UPSTREAM_NEIGHBOR_ADDRESS
+                       + S_RING_STATION_VERSION_NUMBER + S_ADDRESS_MODIFER))
+                       == (FCBlock *)(-1L)))
+                {
+                        return (0);
+                }
+
+                tmf       = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
+                tmf->vc    = RQ_INIT;
+                tmf->dc_sc = DC_RPS | SC_RS;
+                tmf->vl    = 4;
+
+                smctr_make_8025_hdr(dev, 0L, tmf, AC_FC_RQ_INIT);
+
+                tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
+                smctr_make_product_id(dev, tsv);
+
+                tmf->vl += tsv->svl;
+                tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+                smctr_make_upstream_neighbor_addr(dev, tsv);
+
+                tmf->vl += tsv->svl;
+                tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+                smctr_make_ring_station_version(dev, tsv);
+
+                tmf->vl += tsv->svl;
+                tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
+                smctr_make_addr_mod(dev, tsv);
+
+                tmf->vl += tsv->svl;
+
+                /* Subtract out MVID and MVL which is
+                 * include in both vl and MAC_HEADER
+                 */
+/*              fcb->frame_length           = tmf->vl + sizeof(MAC_HEADER) - 4;
+                fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4;
+*/
+                tmf->vl = SWAP_BYTES(tmf->vl);
+
+                if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE)))
+                        return (err);
+
+                /* Wait for Transmit to Complete */
+               for(i = 0; i < 10000; i++) 
+               {
+                       if(fcb->frame_status & FCB_COMMAND_DONE)
+                               break;
+                       udelay(1000);
+               }
+
+                /* Check if GOOD frame Tx'ed */
+                fstatus = fcb->frame_status;
+
+                if(!(fstatus & FCB_COMMAND_DONE))
+                        return (HARDWARE_FAILED);
+
+                if(!(fstatus & FCB_TX_STATUS_E))
+                        count++;
+
+                /* De-allocated Tx FCB and Frame Buffer
+                 * The FCB must be de-allocated manually if executing with
+                 * interrupts disabled, other wise the ISR (LM_Service_Events)
+                 * will de-allocate it when the interrupt occurs.
+                 */
+                tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING;
+                smctr_update_tx_chain(dev, fcb, MAC_QUEUE);
+        } while(count < 4 && ((fstatus & FCB_TX_AC_BITS) ^ FCB_TX_AC_BITS));
+
+       return (smctr_join_complete_state(dev));
+}
+
+static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf,
+        __u16 *tx_fstatus)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        FCBlock *fcb;
+        unsigned int i;
+       int err;
+
+        /* Check if this is the END POINT of the Transmit Forward Chain. */
+        if(rmf->vl <= 18)
+                return (0);
+
+        /* Allocate Transmit FCB only by requesting 0 bytes
+         * of data buffer.
+         */
+        if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, 0)) == (FCBlock *)(-1L))
+                return (0);
+
+        /* Set pointer to Transmit Frame Buffer to the data
+         * portion of the received TX Forward frame, making
+         * sure to skip over the Vector Code (vc) and Vector
+         * length (vl).
+         */
+        fcb->bdb_ptr->trc_data_block_ptr = TRC_POINTER((__u32)rmf 
+               + sizeof(MAC_HEADER) + 2);
+        fcb->bdb_ptr->data_block_ptr     = (__u16 *)((__u32)rmf 
+               + sizeof(MAC_HEADER) + 2);
+
+        fcb->frame_length                = rmf->vl - 4 - 2;
+        fcb->bdb_ptr->buffer_length      = rmf->vl - 4 - 2;
+
+        if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE)))
+                return (err);
+
+        /* Wait for Transmit to Complete */
+       for(i = 0; i < 10000; i++) 
+       {
+                       if(fcb->frame_status & FCB_COMMAND_DONE)
+                       break;
+               udelay(1000);
+       }
+
+        /* Check if GOOD frame Tx'ed */
+        if(!(fcb->frame_status & FCB_COMMAND_DONE))
+        {
+                if((err = smctr_issue_resume_tx_fcb_cmd(dev, MAC_QUEUE)))
+                        return (err);
+
+               for(i = 0; i < 10000; i++) 
+               {
+                       if(fcb->frame_status & FCB_COMMAND_DONE)
+                               break;
+                       udelay(1000);
+               }
+
+                if(!(fcb->frame_status & FCB_COMMAND_DONE))
+                        return (HARDWARE_FAILED);
+        }
+
+        *tx_fstatus = fcb->frame_status;
+
+        return (A_FRAME_WAS_FORWARDED);
+}
+
+static int smctr_set_auth_access_pri(struct net_device *dev,
+        MAC_SUB_VECTOR *rsv)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        if(rsv->svl != S_AUTHORIZED_ACCESS_PRIORITY)
+                return (E_SUB_VECTOR_LENGTH_ERROR);
+
+        tp->authorized_access_priority = (rsv->svv[0] << 8 | rsv->svv[1]);
+
+        return (POSITIVE_ACK);
+}
+
+static int smctr_set_auth_funct_class(struct net_device *dev,
+        MAC_SUB_VECTOR *rsv)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        if(rsv->svl != S_AUTHORIZED_FUNCTION_CLASS)
+                return (E_SUB_VECTOR_LENGTH_ERROR);
+
+        tp->authorized_function_classes = (rsv->svv[0] << 8 | rsv->svv[1]);
+
+        return (POSITIVE_ACK);
+}
+
+static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv,
+        __u16 *correlator)
+{
+        if(rsv->svl != S_CORRELATOR)
+                return (E_SUB_VECTOR_LENGTH_ERROR);
+
+        *correlator = (rsv->svv[0] << 8 | rsv->svv[1]);
+
+        return (POSITIVE_ACK);
+}
+
+static int smctr_set_error_timer_value(struct net_device *dev,
+        MAC_SUB_VECTOR *rsv)
+{
+       __u16 err_tval;
+       int err;
+
+        if(rsv->svl != S_ERROR_TIMER_VALUE)
+                return (E_SUB_VECTOR_LENGTH_ERROR);
+
+        err_tval = (rsv->svv[0] << 8 | rsv->svv[1])*10;
+
+        smctr_issue_write_word_cmd(dev, RW_TER_THRESHOLD, &err_tval);
+
+        if((err = smctr_wait_cmd(dev)))
+                return (err);
+
+        return (POSITIVE_ACK);
+}
+
+static int smctr_set_frame_forward(struct net_device *dev,
+        MAC_SUB_VECTOR *rsv, __u8 dc_sc)
+{
+        if((rsv->svl < 2) || (rsv->svl > S_FRAME_FORWARD))
+                return (E_SUB_VECTOR_LENGTH_ERROR);
+
+        if((dc_sc & DC_MASK) != DC_CRS)
+        {
+                if(rsv->svl >= 2 && rsv->svl < 20)
+                       return (E_TRANSMIT_FORWARD_INVALID);
+
+                if((rsv->svv[0] != 0) || (rsv->svv[1] != 0))
+                        return (E_TRANSMIT_FORWARD_INVALID);
+        }
+
+        return (POSITIVE_ACK);
+}
+
+static int smctr_set_local_ring_num(struct net_device *dev,
+        MAC_SUB_VECTOR *rsv)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        if(rsv->svl != S_LOCAL_RING_NUMBER)
+                return (E_SUB_VECTOR_LENGTH_ERROR);
+
+        if(tp->ptr_local_ring_num)
+                *(__u16 *)(tp->ptr_local_ring_num) 
+                       = (rsv->svv[0] << 8 | rsv->svv[1]);
+
+        return (POSITIVE_ACK);
+}
+
+static unsigned short smctr_set_ctrl_attention(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int ioaddr = dev->base_addr;
+
+        if(tp->bic_type == BIC_585_CHIP)
+                outb((tp->trc_mask | HWR_CA), ioaddr + HWR);
+        else
+        {
+                outb((tp->trc_mask | CSR_CA), ioaddr + CSR);
+                outb(tp->trc_mask, ioaddr + CSR);
+        }
+
+        return (0);
+}
+
+static void smctr_set_multicast_list(struct net_device *dev)
+{
+        if(smctr_debug > 10)
+                printk("%s: smctr_set_multicast_list\n", dev->name);
+
+        return;
+}
+
+static int smctr_set_page(struct net_device *dev, __u8 *buf)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        __u8 amask;
+        __u32 tptr;
+
+        tptr = (__u32)buf - (__u32)tp->ram_access;
+        amask = (__u8)((tptr & PR_PAGE_MASK) >> 8);
+        outb(amask, dev->base_addr + PR);
+
+        return (0);
+}
+
+static int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv)
+{
+       int err;
+
+        if(rsv->svl != S_PHYSICAL_DROP)
+                return (E_SUB_VECTOR_LENGTH_ERROR);
+
+        smctr_issue_write_byte_cmd(dev, RW_PHYSICAL_DROP_NUMBER, &rsv->svv[0]);
+        if((err = smctr_wait_cmd(dev)))
+                return (err);
+
+        return (POSITIVE_ACK);
+}
+
+/* Reset the ring speed to the oposite of what it was. This auto-pilot
+ * mode requires a complete reset and re-init of the adapter.
+ */
+static int smctr_set_ring_speed(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+       int err;
+
+        if(tp->media_type == MEDIA_UTP_16)
+                tp->media_type = MEDIA_UTP_4;
+        else
+                tp->media_type = MEDIA_UTP_16;
+
+        smctr_enable_16bit(dev);
+
+        /* Re-Initialize adapter's internal registers */
+        smctr_reset_adapter(dev);
+
+        if((err = smctr_init_card_real(dev)))
+                return (err);
+
+        smctr_enable_bic_int(dev);
+
+        if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK)))
+                return (err);
+
+        smctr_disable_16bit(dev);
+
+       return (0);
+}
+
+static int smctr_set_rx_look_ahead(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        __u16 sword, rword;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_set_rx_look_ahead_flag\n", dev->name);
+
+        tp->adapter_flags &= ~(FORCED_16BIT_MODE);
+        tp->adapter_flags |= RX_VALID_LOOKAHEAD;
+
+        if(tp->adapter_bus == BUS_ISA16_TYPE)
+        {
+                sword = *((__u16 *)(tp->ram_access));
+                *((__u16 *)(tp->ram_access)) = 0x1234;
+
+                smctr_disable_16bit(dev);
+                rword = *((__u16 *)(tp->ram_access));
+                smctr_enable_16bit(dev);
+
+                if(rword != 0x1234)
+                        tp->adapter_flags |= FORCED_16BIT_MODE;
+
+                *((__u16 *)(tp->ram_access)) = sword;
+        }
+
+        return (0);
+}
+
+static int smctr_set_trc_reset(int ioaddr)
+{
+        __u8 r;
+
+        r = inb(ioaddr + MSR);
+        outb(MSR_RST | r, ioaddr + MSR);
+
+        return (0);
+}
+
+/*
+ * This function can be called if the adapter is busy or not.
+ */
+static int smctr_setup_single_cmd(struct net_device *dev,
+        __u16 command, __u16 subcommand)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int err;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_setup_single_cmd\n", dev->name);
+
+        if((err = smctr_wait_while_cbusy(dev)))
+                return (err);
+
+        if((err = (unsigned int)smctr_wait_cmd(dev)))
+                return (err);
+
+        tp->acb_head->cmd_done_status   = 0;
+        tp->acb_head->cmd               = command;
+        tp->acb_head->subcmd            = subcommand;
+
+        err = smctr_issue_resume_acb_cmd(dev);
+
+        return (err);
+}
+
+/*
+ * This function can not be called with the adapter busy.
+ */
+static int smctr_setup_single_cmd_w_data(struct net_device *dev,
+        __u16 command, __u16 subcommand)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        tp->acb_head->cmd_done_status   = 0;
+        tp->acb_head->cmd               = command;
+        tp->acb_head->subcmd            = subcommand;
+        tp->acb_head->data_offset_lo
+                = (__u16)TRC_POINTER(tp->misc_command_data);
+
+        return(smctr_issue_resume_acb_cmd(dev));
+}
+
+static char *smctr_malloc(struct net_device *dev, __u16 size)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        char *m;
+
+        m = (char *)(tp->ram_access + tp->sh_mem_used);
+        tp->sh_mem_used += (__u32)size;
+
+        return (m);
+}
+
+static int smctr_status_chg(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_status_chg\n", dev->name);
+
+        switch(tp->status)
+        {
+                case OPEN:
+                        break;
+
+                case CLOSED:
+                        break;
+
+                /* Interrupt driven open() completion. XXX */
+                case INITIALIZED:
+                        tp->group_address_0 = 0;
+                        tp->group_address[0] = 0;
+                        tp->group_address[1] = 0;
+                        tp->functional_address_0 = 0;
+                        tp->functional_address[0] = 0;
+                        tp->functional_address[1] = 0;
+                        smctr_open_tr(dev);
+                        break;
+
+                default:
+                        printk(KERN_INFO "%s: status change unknown %x\n",
+                                dev->name, tp->status);
+                        break;
+        }
+
+        return (0);
+}
+
+static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb,
+        __u16 queue)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        int err = 0;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_trc_send_packet\n", dev->name);
+
+        fcb->info = FCB_CHAIN_END | FCB_ENABLE_TFS;
+        if(tp->num_tx_fcbs[queue] != 1)
+                fcb->back_ptr->info = FCB_INTERRUPT_ENABLE | FCB_ENABLE_TFS;
+
+        if(tp->tx_queue_status[queue] == NOT_TRANSMITING)
+        {
+                tp->tx_queue_status[queue] = TRANSMITING;
+                err = smctr_issue_resume_tx_fcb_cmd(dev, queue);
+        }
+
+        return (err);
+}
+
+static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        __u16 status, err = 0;
+        int cstatus;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_tx_complete\n", dev->name);
+
+        while((status = tp->tx_fcb_end[queue]->frame_status) != SUCCESS)
+        {
+                if(status & 0x7e00 )
+                {
+                        err = HARDWARE_FAILED;
+                        break;
+                }
+
+                if((err = smctr_update_tx_chain(dev, tp->tx_fcb_end[queue],
+                        queue)) != SUCCESS)
+                        break;
+
+                smctr_disable_16bit(dev);
+
+                if(tp->mode_bits & UMAC)
+                {
+                        if(!(status & (FCB_TX_STATUS_AR1 | FCB_TX_STATUS_AR2)))
+                                cstatus = NO_SUCH_DESTINATION;
+                        else
+                        {
+                                if(!(status & (FCB_TX_STATUS_CR1 | FCB_TX_STATUS_CR2)))
+                                        cstatus = DEST_OUT_OF_RESOURCES;
+                                else
+                                {
+                                        if(status & FCB_TX_STATUS_E)
+                                                cstatus = MAX_COLLISIONS;
+                                        else
+                                                cstatus = SUCCESS;
+                                }
+                        }
+                }
+                else
+                        cstatus = SUCCESS;
+
+                if(queue == BUG_QUEUE)
+                        err = SUCCESS;
+
+                smctr_enable_16bit(dev);
+                if(err != SUCCESS)
+                        break;
+        }
+
+        return (err);
+}
+
+static unsigned short smctr_tx_move_frame(struct net_device *dev,
+        struct sk_buff *skb, __u8 *pbuff, unsigned int bytes)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int ram_usable;
+        __u32 flen, len, offset = 0;
+        __u8 *frag, *page;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_tx_move_frame\n", dev->name);
+
+        ram_usable = ((unsigned int)tp->ram_usable) << 10;
+        frag       = skb->data;
+        flen       = skb->len;
+
+        while(flen > 0 && bytes > 0)
+        {
+                smctr_set_page(dev, pbuff);
+
+                offset = SMC_PAGE_OFFSET(pbuff);
+
+                if(offset + flen > ram_usable)
+                        len = ram_usable - offset;
+                else
+                        len = flen;
+
+                if(len > bytes)
+                        len = bytes;
+
+                page = (char *) (offset + tp->ram_access);
+                memcpy(page, frag, len);
+
+                flen -=len;
+                bytes -= len;
+                frag += len;
+                pbuff += len;
+        }
+
+        return (0);
+}
+
+/* Update the error statistic counters for this adapter. */
+static int smctr_update_err_stats(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        struct tr_statistics *tstat = &tp->MacStat;
+
+        if(tstat->internal_errors)
+                tstat->internal_errors
+                        += *(tp->misc_command_data + 0) & 0x00ff;
+
+        if(tstat->line_errors)
+                tstat->line_errors += *(tp->misc_command_data + 0) >> 8;
+
+        if(tstat->A_C_errors)
+                tstat->A_C_errors += *(tp->misc_command_data + 1) & 0x00ff;
+
+        if(tstat->burst_errors)
+                tstat->burst_errors += *(tp->misc_command_data + 1) >> 8;
+
+        if(tstat->abort_delimiters)
+                tstat->abort_delimiters += *(tp->misc_command_data + 2) >> 8;
+
+        if(tstat->recv_congest_count)
+                tstat->recv_congest_count
+                        += *(tp->misc_command_data + 3) & 0x00ff;
+
+        if(tstat->lost_frames)
+                tstat->lost_frames
+                        += *(tp->misc_command_data + 3) >> 8;
+
+        if(tstat->frequency_errors)
+                tstat->frequency_errors += *(tp->misc_command_data + 4) & 0x00ff;
+
+        if(tstat->frame_copied_errors)
+                 tstat->frame_copied_errors
+                        += *(tp->misc_command_data + 4) >> 8;
+
+        if(tstat->token_errors)
+                tstat->token_errors += *(tp->misc_command_data + 5) >> 8;
+
+        return (0);
+}
+
+static int smctr_update_rx_chain(struct net_device *dev, __u16 queue)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        FCBlock *fcb;
+        BDBlock *bdb;
+        __u16 size, len;
+
+        fcb = tp->rx_fcb_curr[queue];
+        len = fcb->frame_length;
+
+        fcb->frame_status = 0;
+        fcb->info = FCB_CHAIN_END;
+        fcb->back_ptr->info = FCB_WARNING;
+
+        tp->rx_fcb_curr[queue] = tp->rx_fcb_curr[queue]->next_ptr;
+
+        /* update RX BDBs */
+        size = (len >> RX_BDB_SIZE_SHIFT);
+        if(len & RX_DATA_BUFFER_SIZE_MASK)
+                size += sizeof(BDBlock);
+        size &= (~RX_BDB_SIZE_MASK);
+
+        /* check if wrap around */
+        bdb = (BDBlock *)((__u32)(tp->rx_bdb_curr[queue]) + (__u32)(size));
+        if((__u32)bdb >= (__u32)tp->rx_bdb_end[queue])
+        {
+                bdb = (BDBlock *)((__u32)(tp->rx_bdb_head[queue])
+                        + (__u32)(bdb) - (__u32)(tp->rx_bdb_end[queue]));
+        }
+
+        bdb->back_ptr->info = BDB_CHAIN_END;
+        tp->rx_bdb_curr[queue]->back_ptr->info = BDB_NOT_CHAIN_END;
+        tp->rx_bdb_curr[queue] = bdb;
+
+        return (0);
+}
+
+static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb,
+        __u16 queue)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+
+        if(smctr_debug > 20)
+                printk("smctr_update_tx_chain\n");
+
+        if(tp->num_tx_fcbs_used[queue] <= 0)
+                return (HARDWARE_FAILED);
+        else
+        {
+                if(tp->tx_buff_used[queue] < fcb->memory_alloc)
+                {
+                        tp->tx_buff_used[queue] = 0;
+                        return (HARDWARE_FAILED);
+                }
+
+                tp->tx_buff_used[queue] -= fcb->memory_alloc;
+
+                /* if all transmit buffer are cleared
+                 * need to set the tx_buff_curr[] to tx_buff_head[]
+                 * otherwise, tx buffer will be segregate and cannot
+                 * accomodate and buffer greater than (curr - head) and
+                 * (end - curr) since we do not allow wrap around allocation.
+                 */
+                if(tp->tx_buff_used[queue] == 0)
+                        tp->tx_buff_curr[queue] = tp->tx_buff_head[queue];
+
+                tp->num_tx_fcbs_used[queue]--;
+                fcb->frame_status = 0;
+                tp->tx_fcb_end[queue] = fcb->next_ptr;
+
+                return (0);
+        }
+}
+
+static int smctr_wait_cmd(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int loop_count = 0x20000;
+
+        if(smctr_debug > 10)
+                printk("%s: smctr_wait_cmd\n", dev->name);
+
+        while(loop_count)
+        {
+                if(tp->acb_head->cmd_done_status & ACB_COMMAND_DONE)
+                        break;
+                loop_count--;
+        }
+
+        if(loop_count == 0)
+                return(-1);
+
+        if(tp->acb_head->cmd_done_status & 0xff)
+                return(-1);
+
+        return (0);
+}
+
+static int smctr_wait_while_cbusy(struct net_device *dev)
+{
+        struct net_local *tp = (struct net_local *)dev->priv;
+        unsigned int timeout = 0x20000;
+        int ioaddr = dev->base_addr;
+        __u8 r;
+
+        if(tp->bic_type == BIC_585_CHIP)
+        {
+                while(timeout)
+                {
+                        r = inb(ioaddr + HWR);
+                        if((r & HWR_CBUSY) == 0)
+                                break;
+                        timeout--;
+                }
+        }
+        else
+        {
+                while(timeout)
+                {
+                        r = inb(ioaddr + CSR);
+                        if((r & CSR_CBUSY) == 0)
+                                break;
+                        timeout--;
+                }
+        }
+
+        if(timeout)
+                return (0);
+        else
+                return (-1);
+}
+
+#ifdef MODULE
+
+static struct net_device* dev_smctr[SMCTR_MAX_ADAPTERS];
+static int io[SMCTR_MAX_ADAPTERS]        = { 0, 0 };
+static int irq[SMCTR_MAX_ADAPTERS]       = { 0, 0 };
+static int mem[SMCTR_MAX_ADAPTERS]       = { 0, 0 };
+
+MODULE_PARM(io,  "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
+MODULE_PARM(mem, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
+MODULE_PARM(ringspeed, "1-" __MODULE_STRING(SMCTR_MAX_ADAPTERS) "i");
+
+int init_module(void)
+{
+        int i;
+
+        for(i = 0; i < SMCTR_MAX_ADAPTERS; i++)
+        {
+                irq[i] = 0;
+                mem[i] = 0;
+                dev_smctr[i] = NULL;
+                dev_smctr[i] = init_trdev(dev_smctr[i], 0);
+                if(dev_smctr[i] == NULL)
+                        return (-ENOMEM);
+
+                dev_smctr[i]->base_addr = io[i];
+                dev_smctr[i]->irq       = irq[i];
+                dev_smctr[i]->mem_start = mem[i];
+                dev_smctr[i]->init      = &smctr_probe;
+
+                if(register_trdev(dev_smctr[i]) != 0)
+                {
+                        kfree_s(dev_smctr[i], sizeof(struct net_device));
+                        dev_smctr[i] = NULL;
+                        if(i == 0)
+                        {
+                                printk("%s: register_trdev() returned (<0).\n",
+                                        cardname);
+                                return (-EIO);
+                        }
+                        else
+                                return (0);
+                }
+        }
+
+        return (0);
+}
+
+void cleanup_module(void)
+{
+        int i;
+
+        for(i = 0; i < SMCTR_MAX_ADAPTERS; i++)
+        {
+                if(dev_smctr[i])
+                {
+                        unregister_trdev(dev_smctr[i]);
+                        release_region(dev_smctr[i]->base_addr,
+                                SMCTR_IO_EXTENT);
+                        if(dev_smctr[i]->irq)
+                                free_irq(dev_smctr[i]->irq, dev_smctr[i]);
+                        if(dev_smctr[i]->priv)
+                                kfree_s(dev_smctr[i]->priv,
+                                        sizeof(struct net_local));
+                        kfree_s(dev_smctr[i], sizeof(struct net_device));
+                        dev_smctr[i] = NULL;
+                }
+        }
+}
+#endif /* MODULE */
diff --git a/drivers/net/tokenring/smctr.h b/drivers/net/tokenring/smctr.h
new file mode 100644 (file)
index 0000000..4a7c8c3
--- /dev/null
@@ -0,0 +1,1583 @@
+/* smctr.h: SMC Token Ring driver header for Linux
+ *
+ * Authors:
+ *  - Jay Schulist <jschlst@turbolinux.com>
+ */
+
+#ifndef __LINUX_SMCTR_H
+#define __LINUX_SMCTR_H
+
+#ifdef __KERNEL__
+
+#define MAX_TX_QUEUE 10
+
+#define SMC_HEADER_SIZE 14
+
+#define SMC_PAGE_OFFSET(X)          (((unsigned long)(X) - tp->ram_access) & tp->page_offset_mask)
+
+#define INIT            0x0D
+#define RQ_ATTCH        0x10
+#define RQ_STATE        0x0F
+#define RQ_ADDR         0x0E
+#define CHG_PARM        0x0C
+#define RSP             0x00
+#define TX_FORWARD      0x09
+
+#define AC_FC_DAT      ((3<<13) | 1)
+#define      DAT             0x07
+
+#define RPT_NEW_MON     0x25
+#define RPT_SUA_CHG     0x26
+#define RPT_ACTIVE_ERR  0x28
+#define RPT_NN_INCMP    0x27
+#define RPT_ERROR       0x29
+
+#define RQ_INIT         0x20
+#define RPT_ATTCH       0x24
+#define RPT_STATE       0x23
+#define RPT_ADDR        0x22
+
+#define POSITIVE_ACK                    0x0001
+#define A_FRAME_WAS_FORWARDED           0x8888
+
+#define      GROUP_ADDRESS                   0x2B
+#define      PHYSICAL_DROP                   0x0B
+#define      AUTHORIZED_ACCESS_PRIORITY      0x07
+#define      AUTHORIZED_FUNCTION_CLASS       0x06
+#define      FUNCTIONAL_ADDRESS              0x2C
+#define      RING_STATION_STATUS             0x29
+#define      TRANSMIT_STATUS_CODE            0x2A
+#define      IBM_PASS_SOURCE_ADDR    0x01
+#define      AC_FC_RPT_TX_FORWARD            ((0<<13) | 0)
+#define      AC_FC_RPT_STATE                 ((0<<13) | 0)
+#define      AC_FC_RPT_ADDR                  ((0<<13) | 0)
+#define      CORRELATOR                      0x09
+
+#define POSITIVE_ACK                    0x0001          /*             */
+#define E_MAC_DATA_INCOMPLETE           0x8001          /* not used    */
+#define E_VECTOR_LENGTH_ERROR           0x8002          /*             */
+#define E_UNRECOGNIZED_VECTOR_ID        0x8003          /*             */
+#define E_INAPPROPRIATE_SOURCE_CLASS    0x8004          /*             */
+#define E_SUB_VECTOR_LENGTH_ERROR       0x8005          /*             */
+#define E_TRANSMIT_FORWARD_INVALID      0x8006          /* def. by IBM */
+#define E_MISSING_SUB_VECTOR            0x8007          /*             */
+#define E_SUB_VECTOR_UNKNOWN            0x8008          /*             */
+#define E_MAC_HEADER_TOO_LONG           0x8009          /*             */
+#define E_FUNCTION_DISABLED             0x800A          /* not used    */
+
+#define A_FRAME_WAS_FORWARDED           0x8888          /* used by send_TX_FORWARD */
+
+#define UPSTREAM_NEIGHBOR_ADDRESS       0x02
+#define LOCAL_RING_NUMBER               0x03
+#define ASSIGN_PHYSICAL_DROP            0x04
+#define ERROR_TIMER_VALUE               0x05
+#define AUTHORIZED_FUNCTION_CLASS       0x06
+#define AUTHORIZED_ACCESS_PRIORITY      0x07
+#define CORRELATOR                      0x09
+#define PHYSICAL_DROP                   0x0B
+#define RESPONSE_CODE                   0x20
+#define ADDRESS_MODIFER                 0x21
+#define PRODUCT_INSTANCE_ID             0x22
+#define RING_STATION_VERSION_NUMBER     0x23
+#define WRAP_DATA                       0x26
+#define FRAME_FORWARD                   0x27
+#define STATION_IDENTIFER               0x28
+#define RING_STATION_STATUS             0x29
+#define TRANSMIT_STATUS_CODE            0x2A
+#define GROUP_ADDRESS                   0x2B
+#define FUNCTIONAL_ADDRESS              0x2C
+
+#define F_NO_SUB_VECTORS_FOUND                  0x0000
+#define F_UPSTREAM_NEIGHBOR_ADDRESS             0x0001
+#define F_LOCAL_RING_NUMBER                     0x0002
+#define F_ASSIGN_PHYSICAL_DROP                  0x0004
+#define F_ERROR_TIMER_VALUE                     0x0008
+#define F_AUTHORIZED_FUNCTION_CLASS             0x0010
+#define F_AUTHORIZED_ACCESS_PRIORITY            0x0020
+#define F_CORRELATOR                            0x0040
+#define F_PHYSICAL_DROP                         0x0080
+#define F_RESPONSE_CODE                         0x0100
+#define F_PRODUCT_INSTANCE_ID                   0x0200
+#define F_RING_STATION_VERSION_NUMBER           0x0400
+#define F_STATION_IDENTIFER                     0x0800
+#define F_RING_STATION_STATUS                   0x1000
+#define F_GROUP_ADDRESS                         0x2000
+#define F_FUNCTIONAL_ADDRESS                    0x4000
+#define F_FRAME_FORWARD                         0x8000
+
+#define R_INIT                                  0x00
+#define R_RQ_ATTCH_STATE_ADDR                   0x00
+#define R_CHG_PARM                              0x00
+#define R_TX_FORWARD                            F_FRAME_FORWARD
+
+
+#define      UPSTREAM_NEIGHBOR_ADDRESS       0x02
+#define      ADDRESS_MODIFER                 0x21
+#define      RING_STATION_VERSION_NUMBER     0x23
+#define      PRODUCT_INSTANCE_ID             0x22
+
+#define      RPT_TX_FORWARD  0x2A
+
+#define AC_FC_INIT                      (3<<13) | 0 /*                     */
+#define AC_FC_RQ_INIT                   ((3<<13) | 0) /*                     */
+#define AC_FC_RQ_ATTCH                  (3<<13) | 0 /* DC = SC of rx frame */
+#define AC_FC_RQ_STATE                  (3<<13) | 0 /* DC = SC of rx frame */
+#define AC_FC_RQ_ADDR                   (3<<13) | 0 /* DC = SC of rx frame */
+#define AC_FC_CHG_PARM                  (3<<13) | 0 /*                     */
+#define AC_FC_RSP                       (0<<13) | 0 /* DC = SC of rx frame */
+#define AC_FC_RPT_ATTCH                 (0<<13) | 0
+
+#define S_UPSTREAM_NEIGHBOR_ADDRESS               6 + 2
+#define S_LOCAL_RING_NUMBER                       2 + 2
+#define S_ASSIGN_PHYSICAL_DROP                    4 + 2
+#define S_ERROR_TIMER_VALUE                       2 + 2
+#define S_AUTHORIZED_FUNCTION_CLASS               2 + 2
+#define S_AUTHORIZED_ACCESS_PRIORITY              2 + 2
+#define S_CORRELATOR                              2 + 2
+#define S_PHYSICAL_DROP                           4 + 2
+#define S_RESPONSE_CODE                           4 + 2
+#define S_ADDRESS_MODIFER                         2 + 2
+#define S_PRODUCT_INSTANCE_ID                    18 + 2
+#define S_RING_STATION_VERSION_NUMBER            10 + 2
+#define S_STATION_IDENTIFER                       6 + 2
+#define S_RING_STATION_STATUS                     6 + 2
+#define S_GROUP_ADDRESS                           4 + 2
+#define S_FUNCTIONAL_ADDRESS                      4 + 2
+#define S_FRAME_FORWARD                         252 + 2
+#define S_TRANSMIT_STATUS_CODE                    2 + 2
+
+#define ISB_IMC_RES0                    0x0000  /* */
+#define ISB_IMC_MAC_TYPE_3              0x0001  /* MAC_ARC_INDICATE */
+#define ISB_IMC_MAC_ERROR_COUNTERS      0x0002  /* */
+#define ISB_IMC_RES1                    0x0003  /* */
+#define ISB_IMC_MAC_TYPE_2              0x0004  /* QUE_MAC_INDICATE */
+#define ISB_IMC_TX_FRAME                0x0005  /* */
+#define ISB_IMC_END_OF_TX_QUEUE         0x0006  /* */
+#define ISB_IMC_NON_MAC_RX_RESOURCE     0x0007  /* */
+#define ISB_IMC_MAC_RX_RESOURCE         0x0008  /* */
+#define ISB_IMC_NON_MAC_RX_FRAME        0x0009  /* */
+#define ISB_IMC_MAC_RX_FRAME            0x000A  /* */
+#define ISB_IMC_TRC_FIFO_STATUS         0x000B  /* */
+#define ISB_IMC_COMMAND_STATUS          0x000C  /* */
+#define ISB_IMC_MAC_TYPE_1              0x000D  /* Self Removed */
+#define ISB_IMC_TRC_INTRNL_TST_STATUS   0x000E  /* */
+#define ISB_IMC_RES2                    0x000F  /* */
+
+#define NON_MAC_RX_RESOURCE_BW          0x10    /* shifted right 8 bits */
+#define NON_MAC_RX_RESOURCE_FW          0x20    /* shifted right 8 bits */
+#define NON_MAC_RX_RESOURCE_BE          0x40    /* shifted right 8 bits */
+#define NON_MAC_RX_RESOURCE_FE          0x80    /* shifted right 8 bits */
+#define RAW_NON_MAC_RX_RESOURCE_BW      0x1000  /* */
+#define RAW_NON_MAC_RX_RESOURCE_FW      0x2000  /* */
+#define RAW_NON_MAC_RX_RESOURCE_BE      0x4000  /* */
+#define RAW_NON_MAC_RX_RESOURCE_FE      0x8000  /* */
+
+#define MAC_RX_RESOURCE_BW              0x10    /* shifted right 8 bits */
+#define MAC_RX_RESOURCE_FW              0x20    /* shifted right 8 bits */
+#define MAC_RX_RESOURCE_BE              0x40    /* shifted right 8 bits */
+#define MAC_RX_RESOURCE_FE              0x80    /* shifted right 8 bits */
+#define RAW_MAC_RX_RESOURCE_BW          0x1000  /* */
+#define RAW_MAC_RX_RESOURCE_FW          0x2000  /* */
+#define RAW_MAC_RX_RESOURCE_BE          0x4000  /* */
+#define RAW_MAC_RX_RESOURCE_FE          0x8000  /* */
+
+#define TRC_FIFO_STATUS_TX_UNDERRUN     0x40    /* shifted right 8 bits */
+#define TRC_FIFO_STATUS_RX_OVERRUN      0x80    /* shifted right 8 bits */
+#define RAW_TRC_FIFO_STATUS_TX_UNDERRUN 0x4000  /* */
+#define RAW_TRC_FIFO_STATUS_RX_OVERRUN  0x8000  /* */
+
+#define       CSR_CLRTINT             0x08
+
+#define MSB(X)                  ((__u8)((__u16) X >> 8))
+#define LSB(X)                  ((__u8)((__u16) X &  0xff))
+
+#define AC_FC_LOBE_MEDIA_TEST           ((3<<13) | 0)
+#define S_WRAP_DATA                             248 + 2 /* 500 + 2 */
+#define      WRAP_DATA                       0x26
+#define LOBE_MEDIA_TEST 0x08
+
+/* Destination Class (dc) */
+
+#define DC_MASK         0xF0
+#define DC_RS           0x00
+#define DC_CRS          0x40
+#define DC_RPS          0x50
+#define DC_REM          0x60
+
+/* Source Classes (sc) */
+
+#define SC_MASK         0x0F
+#define SC_RS           0x00
+#define SC_CRS          0x04
+#define SC_RPS          0x05
+#define SC_REM          0x06
+
+#define PR             0x11
+#define PR_PAGE_MASK   0x0C000
+
+#define MICROCHANNEL   0x0008
+#define INTERFACE_CHIP 0x0010
+#define BOARD_16BIT    0x0040
+#define PAGED_RAM      0x0080
+#define WD8115TA       (TOKEN_MEDIA | MICROCHANNEL | INTERFACE_CHIP | PAGED_RAM)
+#define WD8115T                (TOKEN_MEDIA | INTERFACE_CHIP | BOARD_16BIT | PAGED_RAM)
+
+#define BRD_ID_8316    0x50
+
+#define r587_SER       0x001
+#define SER_DIN                0x80
+#define SER_DOUT       0x40
+#define SER_CLK                0x20
+#define SER_ECS                0x10
+#define SER_E806       0x08
+#define SER_PNP                0x04
+#define SER_BIO                0x02
+#define SER_16B                0x01
+
+#define r587_IDR       0x004
+#define IDR_IRQ_MASK   0x0F0
+#define IDR_DCS_MASK   0x007
+#define IDR_RWS                0x008
+
+
+#define r587_BIO       0x003
+#define BIO_ENB                0x080
+#define BIO_MASK       0x03F
+
+#define r587_PCR       0x005
+#define PCR_RAMS       0x040
+
+
+
+#define NUM_ADDR_BITS  8
+
+#define ISA_MAX_ADDRESS                0x00ffffff
+
+#define SMCTR_MAX_ADAPTERS     7
+
+#define MC_TABLE_ENTRIES      16
+
+#define MAXFRAGMENTS          32
+
+#define CHIP_REV_MASK         0x3000
+
+#define MAX_TX_QS             8
+#define NUM_TX_QS_USED        3
+
+#define MAX_RX_QS             2
+#define NUM_RX_QS_USED        2
+
+#define INTEL_DATA_FORMAT      0x4000
+#define INTEL_ADDRESS_POINTER_FORMAT   0x8000
+#define PAGE_POINTER(X)                ((((unsigned long)(X) - tp->ram_access) & tp->page_offset_mask) + tp->ram_access)
+#define SWAP_WORDS(X)          (((X & 0xFFFF) << 16) | (X >> 16))
+
+#define INTERFACE_CHIP          0x0010          /* Soft Config Adapter */
+#define ADVANCED_FEATURES       0x0020          /* Adv. netw. interface features */
+#define BOARD_16BIT             0x0040          /* 16 bit capability */
+#define PAGED_RAM               0x0080          /* Adapter has paged RAM */
+
+#define PAGED_ROM               0x0100          /* Adapter has paged ROM */
+
+#define RAM_SIZE_UNKNOWN        0x0000          /* Unknown RAM size */
+#define RAM_SIZE_0K             0x0001          /* 0K  RAM */
+#define RAM_SIZE_8K             0x0002          /* 8k  RAM */
+#define RAM_SIZE_16K            0x0003          /* 16k RAM */
+#define RAM_SIZE_32K            0x0004          /* 32k RAM */
+#define RAM_SIZE_64K            0x0005          /* 64k RAM */
+#define RAM_SIZE_RESERVED_6     0x0006          /* Reserved RAM size */
+#define RAM_SIZE_RESERVED_7     0x0007          /* Reserved RAM size */
+#define RAM_SIZE_MASK           0x0007          /* Isolates RAM Size */
+
+#define TOKEN_MEDIA           0x0005
+
+#define BID_REG_0       0x00
+#define BID_REG_1       0x01
+#define BID_REG_2       0x02
+#define BID_REG_3       0x03
+#define BID_REG_4       0x04
+#define BID_REG_5       0x05
+#define BID_REG_6       0x06
+#define BID_REG_7       0x07
+#define BID_LAR_0       0x08
+#define BID_LAR_1       0x09
+#define BID_LAR_2       0x0A
+#define BID_LAR_3       0x0B
+#define BID_LAR_4       0x0C
+#define BID_LAR_5       0x0D
+
+#define BID_BOARD_ID_BYTE       0x0E
+#define BID_CHCKSM_BYTE         0x0F
+#define BID_LAR_OFFSET          0x08  
+
+#define BID_MSZ_583_BIT         0x08
+#define BID_SIXTEEN_BIT_BIT     0x01
+
+#define BID_BOARD_REV_MASK      0x1E
+
+#define BID_MEDIA_TYPE_BIT      0x01
+#define BID_SOFT_CONFIG_BIT     0x20
+#define BID_RAM_SIZE_BIT        0x40
+#define BID_BUS_TYPE_BIT        0x80
+
+#define BID_CR          0x10
+
+#define BID_TXP         0x04            /* Transmit Packet Command */
+
+#define BID_TCR_DIFF    0x0D    /* Transmit Configuration Register */
+
+#define BID_TCR_VAL     0x18            /* Value to Test 8390 or 690 */
+#define BID_PS0         0x00            /* Register Page Select 0 */
+#define BID_PS1         0x40            /* Register Page Select 1 */
+#define BID_PS2         0x80            /* Register Page Select 2 */
+#define BID_PS_MASK     0x3F            /* For Masking Off Page Select Bits */
+
+#define BID_EEPROM_0                    0x08
+#define BID_EEPROM_1                    0x09
+#define BID_EEPROM_2                    0x0A
+#define BID_EEPROM_3                    0x0B
+#define BID_EEPROM_4                    0x0C
+#define BID_EEPROM_5                    0x0D
+#define BID_EEPROM_6                    0x0E
+#define BID_EEPROM_7                    0x0F
+
+#define BID_OTHER_BIT                   0x02
+#define BID_ICR_MASK                    0x0C
+#define BID_EAR_MASK                    0x0F
+#define BID_ENGR_PAGE                   0x0A0
+#define BID_RLA                         0x10
+#define BID_EA6                         0x80
+#define BID_RECALL_DONE_MASK            0x10
+#define BID_BID_EEPROM_OVERRIDE         0xFFB0
+#define BID_EXTRA_EEPROM_OVERRIDE       0xFFD0
+#define BID_EEPROM_MEDIA_MASK           0x07
+#define BID_STARLAN_TYPE                0x00
+#define BID_ETHERNET_TYPE               0x01
+#define BID_TP_TYPE                     0x02
+#define BID_EW_TYPE                     0x03
+#define BID_TOKEN_RING_TYPE             0x04
+#define BID_UTP2_TYPE                   0x05
+#define BID_EEPROM_IRQ_MASK             0x18
+#define BID_PRIMARY_IRQ                 0x00
+#define BID_ALTERNATE_IRQ_1             0x08
+#define BID_ALTERNATE_IRQ_2             0x10
+#define BID_ALTERNATE_IRQ_3             0x18
+#define BID_EEPROM_RAM_SIZE_MASK        0xE0
+#define BID_EEPROM_RAM_SIZE_RES1        0x00
+#define BID_EEPROM_RAM_SIZE_RES2        0x20
+#define BID_EEPROM_RAM_SIZE_8K          0x40
+#define BID_EEPROM_RAM_SIZE_16K         0x60
+#define BID_EEPROM_RAM_SIZE_32K         0x80
+#define BID_EEPROM_RAM_SIZE_64K         0xA0
+#define BID_EEPROM_RAM_SIZE_RES3        0xC0
+#define BID_EEPROM_RAM_SIZE_RES4        0xE0
+#define BID_EEPROM_BUS_TYPE_MASK        0x07
+#define BID_EEPROM_BUS_TYPE_AT          0x00
+#define BID_EEPROM_BUS_TYPE_MCA         0x01
+#define BID_EEPROM_BUS_TYPE_EISA        0x02
+#define BID_EEPROM_BUS_TYPE_NEC         0x03
+#define BID_EEPROM_BUS_SIZE_MASK        0x18
+#define BID_EEPROM_BUS_SIZE_8BIT        0x00
+#define BID_EEPROM_BUS_SIZE_16BIT       0x08
+#define BID_EEPROM_BUS_SIZE_32BIT       0x10
+#define BID_EEPROM_BUS_SIZE_64BIT       0x18
+#define BID_EEPROM_BUS_MASTER           0x20
+#define BID_EEPROM_RAM_PAGING           0x40
+#define BID_EEPROM_ROM_PAGING           0x80
+#define BID_EEPROM_PAGING_MASK          0xC0
+#define BID_EEPROM_LOW_COST             0x08
+#define BID_EEPROM_IO_MAPPED            0x10
+#define BID_EEPROM_HMI                  0x01
+#define BID_EEPROM_AUTO_MEDIA_DETECT    0x01
+#define BID_EEPROM_CHIP_REV_MASK        0x0C
+
+#define BID_EEPROM_LAN_ADDR             0x30
+
+#define BID_EEPROM_MEDIA_OPTION         0x54
+#define BID_EEPROM_MEDIA_UTP            0x01
+#define BID_EEPROM_4MB_RING             0x08
+#define BID_EEPROM_16MB_RING            0x10
+#define BID_EEPROM_MEDIA_STP            0x40
+
+#define BID_EEPROM_MISC_DATA            0x56
+#define BID_EEPROM_EARLY_TOKEN_RELEASE  0x02
+
+#define CNFG_ID_8003E           0x6fc0
+#define CNFG_ID_8003S           0x6fc1
+#define CNFG_ID_8003W           0x6fc2
+#define CNFG_ID_8115TRA         0x6ec6
+#define CNFG_ID_8013E           0x61C8
+#define CNFG_ID_8013W           0x61C9
+#define CNFG_ID_BISTRO03E       0xEFE5
+#define CNFG_ID_BISTRO13E       0xEFD5
+#define CNFG_ID_BISTRO13W       0xEFD4
+#define CNFG_MSR_583    0x0
+#define CNFG_ICR_583    0x1
+#define CNFG_IAR_583    0x2
+#define CNFG_BIO_583    0x3
+#define CNFG_EAR_583    0x3
+#define CNFG_IRR_583    0x4
+#define CNFG_LAAR_584   0x5
+#define CNFG_GP2                0x7
+#define CNFG_LAAR_MASK          0x1F
+#define CNFG_LAAR_ZWS           0x20
+#define CNFG_LAAR_L16E          0x40
+#define CNFG_ICR_IR2_584        0x04
+#define CNFG_ICR_MASK       0x08
+#define CNFG_ICR_MSZ        0x08
+#define CNFG_ICR_RLA        0x10
+#define CNFG_ICR_STO        0x80
+#define CNFG_IRR_IRQS           0x60
+#define CNFG_IRR_IEN            0x80
+#define CNFG_IRR_ZWS            0x01
+#define CNFG_GP2_BOOT_NIBBLE    0x0F
+#define CNFG_IRR_OUT2       0x04
+#define CNFG_IRR_OUT1       0x02
+
+#define CNFG_SIZE_8KB           8
+#define CNFG_SIZE_16KB          16
+#define CNFG_SIZE_32KB          32
+#define CNFG_SIZE_64KB          64
+#define CNFG_SIZE_128KB     128
+#define CNFG_SIZE_256KB     256
+#define ROM_DISABLE             0x0
+
+#define CNFG_SLOT_ENABLE_BIT    0x08
+
+#define CNFG_POS_CONTROL_REG    0x096
+#define CNFG_POS_REG0           0x100
+#define CNFG_POS_REG1           0x101
+#define CNFG_POS_REG2           0x102
+#define CNFG_POS_REG3           0x103
+#define CNFG_POS_REG4           0x104
+#define CNFG_POS_REG5           0x105
+
+#define CNFG_ADAPTER_TYPE_MASK  0x0e
+
+#define SLOT_16BIT              0x0008
+#define INTERFACE_5X3_CHIP      0x0000          /* 0000 = 583 or 593 chips */
+#define NIC_690_BIT                     0x0010          /* NIC is 690 */
+#define ALTERNATE_IRQ_BIT       0x0020          /* Alternate IRQ is used */
+#define INTERFACE_584_CHIP      0x0040          /* 0001 = 584 chip */
+#define INTERFACE_594_CHIP      0x0080          /* 0010 = 594 chip */
+#define INTERFACE_585_CHIP      0x0100          /* 0100 = 585/790 chip */
+#define INTERFACE_CHIP_MASK     0x03C0          /* Isolates Intfc Chip Type */
+
+#define BOARD_16BIT             0x0040
+#define NODE_ADDR_CKSUM        0xEE
+#define BRD_ID_8115T           0x04
+
+#define NIC_825_BIT             0x0400          /* TRC 83C825 NIC */
+#define NIC_790_BIT             0x0800          /* NIC is 83C790 Ethernet */
+
+#define CHIP_REV_MASK           0x3000
+
+#define HWR_CBUSY                      0x02
+#define HWR_CA                         0x01
+
+#define MAC_QUEUE                       0
+#define NON_MAC_QUEUE                   1
+#define BUG_QUEUE                       2       /* NO RECEIVE QUEUE, ONLY TX */
+
+#define NUM_MAC_TX_FCBS                 8
+#define NUM_MAC_TX_BDBS                 NUM_MAC_TX_FCBS
+#define NUM_MAC_RX_FCBS                 7
+#define NUM_MAC_RX_BDBS                 8
+
+#define NUM_NON_MAC_TX_FCBS             6
+#define NUM_NON_MAC_TX_BDBS             NUM_NON_MAC_TX_FCBS
+
+#define NUM_NON_MAC_RX_BDBS             0       /* CALCULATED DYNAMICALLY */
+
+#define NUM_BUG_TX_FCBS                 8
+#define NUM_BUG_TX_BDBS                 NUM_BUG_TX_FCBS
+
+#define MAC_TX_BUFFER_MEMORY            1024
+#define NON_MAC_TX_BUFFER_MEMORY        (20 * 1024)
+#define BUG_TX_BUFFER_MEMORY            (NUM_BUG_TX_FCBS * 32)
+
+#define RX_BUFFER_MEMORY                0       /* CALCULATED DYNAMICALLY */
+#define RX_DATA_BUFFER_SIZE             256
+#define RX_BDB_SIZE_SHIFT               3       /* log2(RX_DATA_BUFFER_SIZE)-log2(sizeof(BDBlock)) */
+#define RX_BDB_SIZE_MASK                (sizeof(BDBlock) - 1)
+#define RX_DATA_BUFFER_SIZE_MASK        (RX_DATA_BUFFER_SIZE-1)
+
+#define NUM_OF_INTERRUPTS               0x20
+
+#define NOT_TRANSMITING                 0
+#define TRANSMITING                    1
+
+#define TRC_INTERRUPT_ENABLE_MASK       0x7FF6
+
+#define UCODE_VERSION                   0x58
+
+#define UCODE_SIZE_OFFSET               0x0000  /* WORD */
+#define UCODE_CHECKSUM_OFFSET           0x0002  /* WORD */
+#define UCODE_VERSION_OFFSET            0x0004  /* BYTE */
+
+#define CS_RAM_SIZE                     0X2000
+#define CS_RAM_CHECKSUM_OFFSET          0x1FFE  /* WORD 1FFE(MSB)-1FFF(LSB)*/
+#define CS_RAM_VERSION_OFFSET           0x1FFC  /* WORD 1FFC(MSB)-1FFD(LSB)*/
+
+#define MISC_DATA_SIZE                  128
+#define NUM_OF_ACBS                     1
+
+#define ACB_COMMAND_NOT_DONE            0x0000  /* Init, command not done */
+#define ACB_COMMAND_DONE                0x8000  /* TRC says command done */
+#define ACB_COMMAND_STATUS_MASK         0x00FF  /* low byte is status */
+#define ACB_COMMAND_SUCCESSFUL          0x0000  /* means cmd was successful */
+#define ACB_NOT_CHAIN_END               0x0000  /* tell TRC more CBs in chain */
+#define ACB_CHAIN_END                   0x8000  /* tell TRC last CB in chain */
+#define ACB_COMMAND_NO_INTERRUPT        0x0000  /* tell TRC no INT after CB */
+#define ACB_COMMAND_INTERRUPT           0x2000  /* tell TRC to INT after CB */
+#define ACB_SUB_CMD_NOP                 0x0000
+#define ACB_CMD_HIC_NOP                 0x0080
+#define ACB_CMD_MCT_NOP                 0x0000
+#define ACB_CMD_MCT_TEST                0x0001
+#define ACB_CMD_HIC_TEST                0x0081
+#define ACB_CMD_INSERT                  0x0002
+#define ACB_CMD_REMOVE                  0x0003
+#define ACB_CMD_MCT_WRITE_VALUE         0x0004
+#define ACB_CMD_HIC_WRITE_VALUE         0x0084
+#define ACB_CMD_MCT_READ_VALUE          0x0005
+#define ACB_CMD_HIC_READ_VALUE          0x0085
+#define ACB_CMD_INIT_TX_RX              0x0086
+#define ACB_CMD_INIT_TRC_TIMERS         0x0006
+#define ACB_CMD_READ_TRC_STATUS         0x0007
+#define ACB_CMD_CHANGE_JOIN_STATE       0x0008
+#define ACB_CMD_RESERVED_9              0x0009
+#define ACB_CMD_RESERVED_A              0x000A
+#define ACB_CMD_RESERVED_B              0x000B
+#define ACB_CMD_RESERVED_C              0x000C
+#define ACB_CMD_RESERVED_D              0x000D
+#define ACB_CMD_RESERVED_E              0x000E
+#define ACB_CMD_RESERVED_F              0x000F
+
+#define TRC_MAC_REGISTERS_TEST          0x0000
+#define TRC_INTERNAL_LOOPBACK           0x0001
+#define TRC_TRI_LOOPBACK                0x0002
+#define TRC_INTERNAL_ROM_TEST           0x0003
+#define TRC_LOBE_MEDIA_TEST             0x0004
+#define TRC_ANALOG_TEST                 0x0005
+#define TRC_HOST_INTERFACE_REG_TEST     0x0003
+
+#define TEST_DMA_1                      0x0000
+#define TEST_DMA_2                      0x0001
+#define TEST_MCT_ROM                    0x0002
+#define HIC_INTERNAL_DIAG               0x0003
+
+#define ABORT_TRANSMIT_PRIORITY_0       0x0001
+#define ABORT_TRANSMIT_PRIORITY_1       0x0002
+#define ABORT_TRANSMIT_PRIORITY_2       0x0004
+#define ABORT_TRANSMIT_PRIORITY_3       0x0008
+#define ABORT_TRANSMIT_PRIORITY_4       0x0010
+#define ABORT_TRANSMIT_PRIORITY_5       0x0020
+#define ABORT_TRANSMIT_PRIORITY_6       0x0040
+#define ABORT_TRANSMIT_PRIORITY_7       0x0080
+
+#define TX_PENDING_PRIORITY_0           0x0001
+#define TX_PENDING_PRIORITY_1           0x0002
+#define TX_PENDING_PRIORITY_2           0x0004
+#define TX_PENDING_PRIORITY_3           0x0008
+#define TX_PENDING_PRIORITY_4           0x0010
+#define TX_PENDING_PRIORITY_5           0x0020
+#define TX_PENDING_PRIORITY_6           0x0040
+#define TX_PENDING_PRIORITY_7           0x0080
+
+#define FCB_FRAME_LENGTH                0x100
+#define FCB_COMMAND_DONE                0x8000  /* FCB Word 0 */
+#define FCB_NOT_CHAIN_END               0x0000  /* FCB Word 1 */
+#define FCB_CHAIN_END                   0x8000
+#define FCB_NO_WARNING                  0x0000
+#define FCB_WARNING                     0x4000
+#define FCB_INTERRUPT_DISABLE           0x0000
+#define FCB_INTERRUPT_ENABLE            0x2000
+
+#define FCB_ENABLE_IMA                  0x0008
+#define FCB_ENABLE_TES                  0x0004  /* Guarantee Tx before Int */
+#define FCB_ENABLE_TFS                  0x0002  /* Post Tx Frame Status */
+#define FCB_ENABLE_NTC                  0x0001  /* No Tx CRC */
+
+#define FCB_TX_STATUS_CR2               0x0004
+#define FCB_TX_STATUS_AR2               0x0008
+#define FCB_TX_STATUS_CR1               0x0040
+#define FCB_TX_STATUS_AR1               0x0080
+#define FCB_TX_AC_BITS                  (FCB_TX_STATUS_AR1+FCB_TX_STATUS_AR2+FCB_TX_STATUS_CR1+FCB_TX_STATUS_CR2)
+#define FCB_TX_STATUS_E                 0x0100
+
+#define FCB_RX_STATUS_ANY_ERROR         0x0001
+#define FCB_RX_STATUS_FCS_ERROR         0x0002
+
+#define FCB_RX_STATUS_IA_MATCHED        0x0400
+#define FCB_RX_STATUS_IGA_BSGA_MATCHED  0x0500
+#define FCB_RX_STATUS_FA_MATCHED        0x0600
+#define FCB_RX_STATUS_BA_MATCHED        0x0700
+#define FCB_RX_STATUS_DA_MATCHED        0x0400
+#define FCB_RX_STATUS_SOURCE_ROUTING    0x0800
+
+#define BDB_BUFFER_SIZE                 0x100
+#define BDB_NOT_CHAIN_END               0x0000
+#define BDB_CHAIN_END                   0x8000
+#define BDB_NO_WARNING                  0x0000
+#define BDB_WARNING                     0x4000
+
+#define ERROR_COUNTERS_CHANGED          0x0001
+#define TI_NDIS_RING_STATUS_CHANGED     0x0002
+#define UNA_CHANGED                     0x0004
+#define READY_TO_SEND_RQ_INIT           0x0008
+
+#define SCGB_ADDRESS_POINTER_FORMAT     INTEL_ADDRESS_POINTER_FORMAT
+#define SCGB_DATA_FORMAT                INTEL_DATA_FORMAT
+#define SCGB_MULTI_WORD_CONTROL         0
+#define SCGB_BURST_LENGTH               0x000E  /* DMA Burst Length */
+
+#define SCGB_CONFIG                     (INTEL_ADDRESS_POINTER_FORMAT+INTEL_DATA_FORMAT+SCGB_BURST_LENGTH)
+
+#define ISCP_BLOCK_SIZE                 0x0A
+#define RAM_SIZE                        0x10000
+#define INIT_SYS_CONFIG_PTR_OFFSET      (RAM_SIZE-ISCP_BLOCK_SIZE)
+#define SCGP_BLOCK_OFFSET               0
+
+#define SCLB_NOT_VALID                  0x0000  /* Initially, SCLB not valid */
+#define SCLB_VALID                      0x8000  /* Host tells TRC SCLB valid */
+#define SCLB_PROCESSED                  0x0000  /* TRC says SCLB processed */
+#define SCLB_RESUME_CONTROL_NOT_VALID   0x0000  /* Initially, RC not valid */
+#define SCLB_RESUME_CONTROL_VALID       0x4000  /* Host tells TRC RC valid */
+#define SCLB_IACK_CODE_NOT_VALID        0x0000  /* Initially, IACK not valid */
+#define SCLB_IACK_CODE_VALID            0x2000  /* Host tells TRC IACK valid */
+#define SCLB_CMD_NOP                    0x0000
+#define SCLB_CMD_REMOVE                 0x0001
+#define SCLB_CMD_SUSPEND_ACB_CHAIN      0x0002
+#define SCLB_CMD_SET_INTERRUPT_MASK     0x0003
+#define SCLB_CMD_CLEAR_INTERRUPT_MASK   0x0004
+#define SCLB_CMD_RESERVED_5             0x0005
+#define SCLB_CMD_RESERVED_6             0x0006
+#define SCLB_CMD_RESERVED_7             0x0007
+#define SCLB_CMD_RESERVED_8             0x0008
+#define SCLB_CMD_RESERVED_9             0x0009
+#define SCLB_CMD_RESERVED_A             0x000A
+#define SCLB_CMD_RESERVED_B             0x000B
+#define SCLB_CMD_RESERVED_C             0x000C
+#define SCLB_CMD_RESERVED_D             0x000D
+#define SCLB_CMD_RESERVED_E             0x000E
+#define SCLB_CMD_RESERVED_F             0x000F
+
+#define SCLB_RC_ACB                     0x0001  /* Action Command Block Chain */
+#define SCLB_RC_RES0                    0x0002  /* Always Zero */
+#define SCLB_RC_RES1                    0x0004  /* Always Zero */
+#define SCLB_RC_RES2                    0x0008  /* Always Zero */
+#define SCLB_RC_RX_MAC_FCB              0x0010  /* RX_MAC_FCB Chain */
+#define SCLB_RC_RX_MAC_BDB              0x0020  /* RX_MAC_BDB Chain */
+#define SCLB_RC_RX_NON_MAC_FCB          0x0040  /* RX_NON_MAC_FCB Chain */
+#define SCLB_RC_RX_NON_MAC_BDB          0x0080  /* RX_NON_MAC_BDB Chain */
+#define SCLB_RC_TFCB0                   0x0100  /* TX Priority 0 FCB Chain */
+#define SCLB_RC_TFCB1                   0x0200  /* TX Priority 1 FCB Chain */
+#define SCLB_RC_TFCB2                   0x0400  /* TX Priority 2 FCB Chain */
+#define SCLB_RC_TFCB3                   0x0800  /* TX Priority 3 FCB Chain */
+#define SCLB_RC_TFCB4                   0x1000  /* TX Priority 4 FCB Chain */
+#define SCLB_RC_TFCB5                   0x2000  /* TX Priority 5 FCB Chain */
+#define SCLB_RC_TFCB6                   0x4000  /* TX Priority 6 FCB Chain */
+#define SCLB_RC_TFCB7                   0x8000  /* TX Priority 7 FCB Chain */
+
+#define SCLB_IMC_RES0                   0x0001  /* */
+#define SCLB_IMC_MAC_TYPE_3             0x0002  /* MAC_ARC_INDICATE */
+#define SCLB_IMC_MAC_ERROR_COUNTERS     0x0004  /* */
+#define SCLB_IMC_RES1                   0x0008  /* */
+#define SCLB_IMC_MAC_TYPE_2             0x0010  /* QUE_MAC_INDICATE */
+#define SCLB_IMC_TX_FRAME               0x0020  /* */
+#define SCLB_IMC_END_OF_TX_QUEUE        0x0040  /* */
+#define SCLB_IMC_NON_MAC_RX_RESOURCE    0x0080  /* */
+#define SCLB_IMC_MAC_RX_RESOURCE        0x0100  /* */
+#define SCLB_IMC_NON_MAC_RX_FRAME       0x0200  /* */
+#define SCLB_IMC_MAC_RX_FRAME           0x0400  /* */
+#define SCLB_IMC_TRC_FIFO_STATUS        0x0800  /* */
+#define SCLB_IMC_COMMAND_STATUS         0x1000  /* */
+#define SCLB_IMC_MAC_TYPE_1             0x2000  /* Self Removed */
+#define SCLB_IMC_TRC_INTRNL_TST_STATUS  0x4000  /* */
+#define SCLB_IMC_RES2                   0x8000  /* */
+
+#define DMA_TRIGGER                     0x0004
+#define FREQ_16MB_BIT                   0x0010
+#define THDREN                          0x0020
+#define CFG0_RSV1                       0x0040
+#define CFG0_RSV2                       0x0080
+#define ETREN                           0x0100
+#define RX_OWN_BIT                      0x0200
+#define RXATMAC                         0x0400
+#define PROMISCUOUS_BIT                 0x0800
+#define USETPT                          0x1000
+#define SAVBAD_BIT                      0x2000
+#define ONEQUE                          0x4000
+#define NO_AUTOREMOVE                   0x8000
+
+#define RX_FCB_AREA_8316        0x00000000
+#define RX_BUFF_AREA_8316       0x00000000
+
+#define TRC_POINTER(X)          ((unsigned long)(X) - tp->ram_access)
+#define RX_FCB_TRC_POINTER(X)   ((unsigned long)(X) - tp->ram_access + RX_FCB_AREA_8316)
+#define RX_BUFF_TRC_POINTER(X) ((unsigned long)(X) - tp->ram_access + RX_BUFF_AREA_8316)
+
+// Offset 0: MSR - Memory Select Register
+//
+#define r587_MSR        0x000   // Register Offset
+//#define       MSR_RST         0x080   // LAN Controller Reset
+#define MSR_MENB        0x040   // Shared Memory Enable
+#define MSR_RA18        0x020   // Ram Address bit 18   (583, 584, 587)
+#define MSR_RA17        0x010   // Ram Address bit 17   (583, 584, 585/790)
+#define MSR_RA16        0x008   // Ram Address bit 16   (583, 584, 585/790)
+#define MSR_RA15        0x004   // Ram Address bit 15   (583, 584, 585/790)
+#define MSR_RA14        0x002   // Ram Address bit 14   (583, 584, 585/790)
+#define MSR_RA13        0x001   // Ram Address bit 13   (583, 584, 585/790)
+
+#define MSR_MASK        0x03F   // Mask for Address bits RA18-RA13 (583, 584, 587)
+
+#define MSR                     0x00
+#define IRR                     0x04
+#define HWR                     0x04
+#define LAAR                    0x05
+#define IMCCR                   0x05
+#define LAR0                    0x08
+#define BDID                    0x0E    // Adapter ID byte register offset
+#define CSR                     0x10
+#define PR                      0x11
+
+#define MSR_RST                 0x80
+#define MSR_MEMB                0x40
+#define MSR_0WS                 0x20
+
+#define FORCED_16BIT_MODE       0x0002
+
+#define INTERFRAME_SPACING_16           0x0003  /* 6 bytes */
+#define INTERFRAME_SPACING_4            0x0001  /* 2 bytes */
+#define MULTICAST_ADDRESS_BIT           0x0010
+#define NON_SRC_ROUTING_BIT             0x0020
+
+#define LOOPING_MODE_MASK       0x0007
+
+/*
+ * Decode firmware defines.
+ */
+#define SWAP_BYTES(X)          ((X & 0xff) << 8) | (X >> 8)
+#define WEIGHT_OFFSET          5
+#define TREE_SIZE_OFFSET       9
+#define TREE_OFFSET            11
+
+/* The Huffman Encoding Tree is constructed of these nodes. */
+typedef struct {
+       __u8    llink;  /* Short version of above node. */
+       __u8    tag;
+       __u8    info;   /* This node is used on decodes. */
+       __u8    rlink;
+} DECODE_TREE_NODE;
+
+#define ROOT   0       /* Branch value. */
+#define LEAF   0       /* Tag field value. */
+#define BRANCH 1       /* Tag field value. */
+
+/*
+ * Multicast Table Structure
+ */
+typedef struct {
+        __u8    address[6];
+        __u8    instance_count;
+} McTable;
+
+/*
+ * Fragment Descriptor Definition
+ */
+typedef struct {
+        __u8  *fragment_ptr;
+        __u32   fragment_length;
+} FragmentStructure;
+
+/*
+ * Data Buffer Structure Definition
+ */
+typedef struct {
+        __u32 fragment_count;
+        FragmentStructure       fragment_list[MAXFRAGMENTS];
+} DataBufferStructure;
+
+#pragma pack(1)
+typedef struct {
+                __u8    IType;
+                __u8    ISubtype;
+} Interrupt_Status_Word;
+
+#pragma pack(1)
+typedef struct BDBlockType {
+                __u16                   info;                   /* 02 */
+                __u32                   trc_next_ptr;           /* 06 */
+                __u32                   trc_data_block_ptr;     /* 10 */
+                __u16                   buffer_length;          /* 12 */
+
+                __u16                   *data_block_ptr;        /* 16 */
+                struct  BDBlockType     *next_ptr;              /* 20 */
+                struct  BDBlockType     *back_ptr;              /* 24 */
+                __u8                    filler[8];              /* 32 */
+} BDBlock;
+
+#pragma pack(1)
+typedef struct FCBlockType {
+                __u16                   frame_status;           /* 02 */
+                __u16                   info;                   /* 04 */
+                __u32                   trc_next_ptr;           /* 08 */
+                __u32                   trc_bdb_ptr;            /* 12 */
+                __u16                   frame_length;           /* 14 */
+
+                BDBlock                 *bdb_ptr;               /* 18 */
+                struct  FCBlockType     *next_ptr;              /* 22 */
+                struct  FCBlockType     *back_ptr;              /* 26 */
+                __u16                   memory_alloc;           /* 28 */
+                __u8                    filler[4];              /* 32 */
+
+} FCBlock;
+
+#pragma pack(1)
+typedef struct SBlockType{
+                __u8                           Internal_Error_Count;
+                __u8                           Line_Error_Count;
+                __u8                           AC_Error_Count;
+                __u8                           Burst_Error_Count;
+                __u8                            RESERVED_COUNTER_0;
+                __u8                            AD_TRANS_Count;
+                __u8                            RCV_Congestion_Count;
+                __u8                            Lost_FR_Error_Count;
+                __u8                            FREQ_Error_Count;
+                __u8                            FR_Copied_Error_Count;
+                __u8                            RESERVED_COUNTER_1;
+                __u8                            Token_Error_Count;
+
+                __u16                           TI_NDIS_Ring_Status;
+                __u16                           BCN_Type;
+                __u16                           Error_Code;
+                __u16                           SA_of_Last_AMP_SMP[3];
+                __u16                           UNA[3];
+                __u16                           Ucode_Version_Number;
+                __u16                           Status_CHG_Indicate;
+                __u16                           RESERVED_STATUS_0;
+} SBlock;
+
+#pragma pack(1)
+typedef struct ACBlockType {
+                __u16                   cmd_done_status;    /* 02 */
+                __u16                   cmd_info;           /* 04 */
+                __u32                   trc_next_ptr;           /* 08 */
+                __u16                   cmd;                /* 10 */
+                __u16                   subcmd;             /* 12 */
+                __u16                   data_offset_lo;         /* 14 */
+                __u16                   data_offset_hi;         /* 16 */
+
+                struct  ACBlockType     *next_ptr;              /* 20 */
+
+                __u8                    filler[12];             /* 32 */
+} ACBlock;
+
+#define NUM_OF_INTERRUPTS               0x20
+
+#pragma pack(1)
+typedef struct {
+                Interrupt_Status_Word   IStatus[NUM_OF_INTERRUPTS];
+} ISBlock;
+
+#pragma pack(1)
+typedef struct {
+                __u16                   valid_command;          /* 02 */
+                __u16                   iack_code;              /* 04 */
+                __u16                   resume_control;         /* 06 */
+                __u16                   int_mask_control;       /* 08 */
+                __u16                   int_mask_state;         /* 10 */
+
+                __u8                    filler[6];              /* 16 */
+} SCLBlock;
+
+#pragma pack(1)
+typedef struct
+{
+                __u16                   config;                 /* 02 */
+                __u32                   trc_sclb_ptr;           /* 06 */
+                __u32                   trc_acb_ptr;            /* 10 */
+                __u32                   trc_isb_ptr;            /* 14 */
+                __u16                   isbsiz;                 /* 16 */
+
+                SCLBlock                *sclb_ptr;              /* 20 */
+                ACBlock                 *acb_ptr;               /* 24 */
+                ISBlock                 *isb_ptr;               /* 28 */
+
+                __u16                   Non_Mac_Rx_Bdbs;        /* 30 DEBUG */
+                __u8                    filler[2];              /* 32 */
+
+} SCGBlock;
+
+#pragma pack(1)
+typedef struct
+{
+       __u32           trc_scgb_ptr;
+       SCGBlock        *scgb_ptr;
+} ISCPBlock;
+#pragma pack()
+
+typedef struct net_local {
+       ISCPBlock       *iscpb_ptr;
+        SCGBlock        *scgb_ptr;
+        SCLBlock        *sclb_ptr;
+        ISBlock         *isb_ptr;
+
+       ACBlock         *acb_head;
+        ACBlock         *acb_curr;
+        ACBlock         *acb_next;
+
+       __u8            adapter_name[12];
+
+       __u16           num_rx_bdbs     [NUM_RX_QS_USED];
+       __u16           num_rx_fcbs     [NUM_RX_QS_USED];
+
+       __u16           num_tx_bdbs     [NUM_TX_QS_USED];
+       __u16           num_tx_fcbs     [NUM_TX_QS_USED];
+
+       __u16           num_of_tx_buffs;
+
+       __u16           tx_buff_size    [NUM_TX_QS_USED];
+       __u16           tx_buff_used    [NUM_TX_QS_USED];
+       __u16           tx_queue_status [NUM_TX_QS_USED];
+
+       FCBlock         *tx_fcb_head[NUM_TX_QS_USED];
+       FCBlock         *tx_fcb_curr[NUM_TX_QS_USED];
+       FCBlock         *tx_fcb_end[NUM_TX_QS_USED];
+       BDBlock         *tx_bdb_head[NUM_TX_QS_USED];
+       __u16           *tx_buff_head[NUM_TX_QS_USED];
+       __u16           *tx_buff_end[NUM_TX_QS_USED];
+       __u16           *tx_buff_curr[NUM_TX_QS_USED];
+       __u16           num_tx_fcbs_used[NUM_TX_QS_USED];
+
+       FCBlock         *rx_fcb_head[NUM_RX_QS_USED];
+       FCBlock         *rx_fcb_curr[NUM_RX_QS_USED];
+       BDBlock         *rx_bdb_head[NUM_RX_QS_USED];
+       BDBlock         *rx_bdb_curr[NUM_RX_QS_USED];
+       BDBlock         *rx_bdb_end[NUM_RX_QS_USED];
+       __u16           *rx_buff_head[NUM_RX_QS_USED];
+       __u16           *rx_buff_end[NUM_RX_QS_USED];
+
+       __u32           *ptr_local_ring_num;
+
+       __u32           sh_mem_used;
+
+       __u16           page_offset_mask;
+
+       __u16           authorized_function_classes;
+       __u16           authorized_access_priority;
+
+        __u16            num_acbs;
+        __u16            num_acbs_used;
+        __u16            acb_pending;
+
+       __u16           current_isb_index;
+
+       __u8            monitor_state;
+       __u8            monitor_state_ready;
+       __u16           ring_status;
+       __u8            ring_status_flags;
+       __u8            current_ring_status;
+       __u8            state;
+
+       __u8            join_state;
+
+       __u32           *ptr_una;
+       __u32           *ptr_bcn_type;
+       __u32           *ptr_tx_fifo_underruns;
+       __u32           *ptr_rx_fifo_underruns;
+       __u32           *ptr_rx_fifo_overruns;
+       __u32           *ptr_tx_fifo_overruns;
+       __u32           *ptr_tx_fcb_overruns;
+       __u32           *ptr_rx_fcb_overruns;
+       __u32           *ptr_tx_bdb_overruns;
+       __u32           *ptr_rx_bdb_overruns;
+
+       __u16           receive_queue_number;
+
+       __u8            rx_fifo_overrun_count;
+       __u8            tx_fifo_overrun_count;
+
+       __u16            adapter_flags;
+       __u16           adapter_flags1;
+       __u16            *misc_command_data;
+       __u16            max_packet_size;
+
+       __u16            config_word0;
+        __u16            config_word1;
+
+       __u8            trc_mask;
+
+       __u16            source_ring_number;
+        __u16            target_ring_number;
+
+       __u16           microcode_version;
+
+       __u16            bic_type;
+        __u16            nic_type;
+        __u16            board_id;
+
+       __u16            rom_size;
+       __u32           rom_base;
+        __u16            ram_size;
+        __u16            ram_usable;
+       __u32           ram_base;
+       __u32           ram_access;
+
+       __u16            extra_info;
+        __u16            mode_bits;
+       __u16           media_menu;
+       __u16           media_type;
+       __u16           adapter_bus;
+
+       __u16           status;
+       __u16            receive_mask;
+
+       __u16            group_address_0;
+        __u16            group_address[2];
+        __u16            functional_address_0;
+        __u16            functional_address[2];
+        __u16            bitwise_group_address[2];
+
+       __u8            *ptr_ucode;
+
+       __u8            cleanup;
+
+       struct sk_buff_head SendSkbQueue;
+        __u16 QueueSkb;
+
+       struct tr_statistics MacStat;   /* MAC statistics structure */
+} NET_LOCAL;
+
+/************************************
+ * SNMP-ON-BOARD Agent Link Structure
+ ************************************/
+
+typedef struct {
+        __u8           LnkSigStr[12]; /* signature string "SmcLinkTable" */
+        __u8           LnkDrvTyp;     /* 1=Redbox ODI, 2=ODI DOS, 3=ODI OS/2, 4=NDIS DOS */
+        __u8           LnkFlg;        /* 0 if no agent linked, 1 if agent linked */
+        void           *LnkNfo;       /* routine which returns pointer to NIC info */
+        void           *LnkAgtRcv;    /* pointer to agent receive trap entry */
+        void           *LnkAgtXmt;            /* pointer to agent transmit trap
+entry  */
+void           *LnkGet;                  /* pointer to NIC receive data
+copy routine */
+        void           *LnkSnd;                  /* pointer to NIC send routine
+*/
+        void           *LnkRst;                  /* pointer to NIC driver reset
+routine */
+        void           *LnkMib;                  /* pointer to MIB data base */
+        void           *LnkMibAct;            /* pointer to MIB action routine list */
+        __u16           LnkCntOffset;  /* offset to error counters */
+        __u16           LnkCntNum;     /* number of error counters */
+        __u16           LnkCntSize;    /* size of error counters i.e. 32 = 32 bits */
+        void           *LnkISR;       /* pointer to interrupt vector */
+        __u8           LnkFrmTyp;     /* 1=Ethernet, 2=Token Ring */
+        __u8           LnkDrvVer1 ;   /* driver major version */
+        __u8           LnkDrvVer2 ;   /* driver minor version */
+} AgentLink;
+
+/*
+ * Definitions for pcm_card_flags(bit_mapped)
+ */
+#define REG_COMPLETE   0x0001
+#define INSERTED       0x0002
+#define PCC_INSERTED   0x0004         /* 1=currently inserted, 0=cur removed */
+
+/*
+ * Adapter RAM test patterns
+ */
+#define RAM_PATTERN_1  0x55AA
+#define RAM_PATTERN_2  0x9249
+#define RAM_PATTERN_3  0xDB6D
+
+/*
+ * definitions for RAM test
+ */
+#define ROM_SIGNATURE  0xAA55
+#define MIN_ROM_SIZE   0x2000
+
+/*
+ * Return Codes
+ */
+#define SUCCESS                 0x0000
+#define ADAPTER_AND_CONFIG      0x0001
+#define ADAPTER_NO_CONFIG       0x0002
+#define NOT_MY_INTERRUPT        0x0003
+#define FRAME_REJECTED          0x0004
+#define EVENTS_DISABLED         0x0005
+#define OUT_OF_RESOURCES        0x0006
+#define INVALID_PARAMETER       0x0007
+#define INVALID_FUNCTION        0x0008
+#define INITIALIZE_FAILED       0x0009
+#define CLOSE_FAILED            0x000A
+#define MAX_COLLISIONS          0x000B
+#define NO_SUCH_DESTINATION     0x000C
+#define BUFFER_TOO_SMALL_ERROR  0x000D
+#define ADAPTER_CLOSED          0x000E
+#define UCODE_NOT_PRESENT       0x000F
+#define FIFO_UNDERRUN           0x0010
+#define DEST_OUT_OF_RESOURCES   0x0011
+#define ADAPTER_NOT_INITIALIZED 0x0012
+#define PENDING                 0x0013
+#define UCODE_PRESENT           0x0014
+#define NOT_INIT_BY_BRIDGE      0x0015
+
+#define OPEN_FAILED             0x0080
+#define HARDWARE_FAILED         0x0081
+#define SELF_TEST_FAILED        0x0082
+#define RAM_TEST_FAILED         0x0083
+#define RAM_CONFLICT            0x0084
+#define ROM_CONFLICT            0x0085
+#define UNKNOWN_ADAPTER         0x0086
+#define CONFIG_ERROR            0x0087
+#define CONFIG_WARNING          0x0088
+#define NO_FIXED_CNFG           0x0089
+#define EEROM_CKSUM_ERROR       0x008A
+#define ROM_SIGNATURE_ERROR     0x008B
+#define ROM_CHECKSUM_ERROR      0x008C
+#define ROM_SIZE_ERROR          0x008D
+#define UNSUPPORTED_NIC_CHIP    0x008E
+#define NIC_REG_ERROR           0x008F
+#define BIC_REG_ERROR           0x0090
+#define MICROCODE_TEST_ERROR    0x0091
+#define LOBE_MEDIA_TEST_FAILED  0x0092
+
+#define ADAPTER_FOUND_LAN_CORRUPT 0x009B
+
+#define ADAPTER_NOT_FOUND       0xFFFF
+
+#define ILLEGAL_FUNCTION        INVALID_FUNCTION
+
+/* Errors */
+#define IO_BASE_INVALID         0x0001
+#define IO_BASE_RANGE           0x0002
+#define IRQ_INVALID             0x0004
+#define IRQ_RANGE               0x0008
+#define RAM_BASE_INVALID        0x0010
+#define RAM_BASE_RANGE          0x0020
+#define RAM_SIZE_RANGE          0x0040
+#define MEDIA_INVALID           0x0800
+
+/* Warnings */
+#define IRQ_MISMATCH            0x0080
+#define RAM_BASE_MISMATCH       0x0100
+#define RAM_SIZE_MISMATCH       0x0200
+#define BUS_MODE_MISMATCH       0x0400
+
+#define RX_CRC_ERROR                            0x01
+#define RX_ALIGNMENT_ERROR              0x02
+#define RX_HW_FAILED                            0x80
+
+/*
+ * Definitions for the field RING_STATUS_FLAGS
+ */
+#define RING_STATUS_CHANGED                     0X01
+#define MONITOR_STATE_CHANGED                   0X02
+#define JOIN_STATE_CHANGED                      0X04
+
+/*
+ * Definitions for the field JOIN_STATE
+ */
+#define JS_BYPASS_STATE                         0x00
+#define JS_LOBE_TEST_STATE                      0x01
+#define JS_DETECT_MONITOR_PRESENT_STATE         0x02
+#define JS_AWAIT_NEW_MONITOR_STATE              0x03
+#define JS_DUPLICATE_ADDRESS_TEST_STATE         0x04
+#define JS_NEIGHBOR_NOTIFICATION_STATE          0x05
+#define JS_REQUEST_INITIALIZATION_STATE         0x06
+#define JS_JOIN_COMPLETE_STATE                  0x07
+#define JS_BYPASS_WAIT_STATE                    0x08
+
+/*
+ * Definitions for the field MONITOR_STATE
+ */
+#define MS_MONITOR_FSM_INACTIVE                 0x00
+#define MS_REPEAT_BEACON_STATE                  0x01
+#define MS_REPEAT_CLAIM_TOKEN_STATE             0x02
+#define MS_TRANSMIT_CLAIM_TOKEN_STATE           0x03
+#define MS_STANDBY_MONITOR_STATE                0x04
+#define MS_TRANSMIT_BEACON_STATE                0x05
+#define MS_ACTIVE_MONITOR_STATE                 0x06
+#define MS_TRANSMIT_RING_PURGE_STATE            0x07
+#define MS_BEACON_TEST_STATE                    0x09
+
+/*
+ * Definitions for the bit-field RING_STATUS
+ */
+#define SIGNAL_LOSS                             0x8000
+#define HARD_ERROR                              0x4000
+#define SOFT_ERROR                              0x2000
+#define TRANSMIT_BEACON                         0x1000
+#define LOBE_WIRE_FAULT                         0x0800
+#define AUTO_REMOVAL_ERROR                      0x0400
+#define REMOVE_RECEIVED                         0x0100
+#define COUNTER_OVERFLOW                        0x0080
+#define SINGLE_STATION                          0x0040
+#define RING_RECOVERY                           0x0020
+
+/*
+ * Definitions for the field BUS_TYPE
+ */
+#define AT_BUS                  0x00
+#define MCA_BUS                 0x01
+#define EISA_BUS                0x02
+#define PCI_BUS                 0x03
+#define PCMCIA_BUS              0x04
+
+/*
+ * Definitions for adapter_flags
+ */
+#define RX_VALID_LOOKAHEAD      0x0001
+#define FORCED_16BIT_MODE       0x0002
+#define ADAPTER_DISABLED        0x0004
+#define TRANSMIT_CHAIN_INT      0x0008
+#define EARLY_RX_FRAME          0x0010
+#define EARLY_TX                0x0020
+#define EARLY_RX_COPY           0x0040
+#define USES_PHYSICAL_ADDR      0x0080         /* Rsvd for DEC PCI and 9232 */
+#define NEEDS_PHYSICAL_ADDR    0x0100          /* Reserved*/
+#define RX_STATUS_PENDING       0x0200
+#define ERX_DISABLED           0x0400          /* EARLY_RX_ENABLE rcv_mask */
+#define ENABLE_TX_PENDING       0x0800
+#define ENABLE_RX_PENDING       0x1000
+#define PERM_CLOSE              0x2000  
+#define IO_MAPPED               0x4000         /* IOmapped bus interface 795 */
+#define ETX_DISABLED            0x8000
+
+
+/*
+ * Definitions for adapter_flags1
+ */
+#define TX_PHY_RX_VIRT          0x0001 
+#define NEEDS_HOST_RAM          0x0002
+#define NEEDS_MEDIA_TYPE        0x0004
+#define EARLY_RX_DONE           0x0008
+#define PNP_BOOT_BIT            0x0010  /* activates PnP & config on power-up */
+                                        /* clear => regular PnP operation */
+#define PNP_ENABLE              0x0020  /* regular PnP operation clear => */
+                                        /* no PnP, overrides PNP_BOOT_BIT */
+#define SATURN_ENABLE           0x0040
+
+#define ADAPTER_REMOVABLE       0x0080         /* adapter is hot swappable */
+#define TX_PHY                  0x0100  /* Uses physical address for tx bufs */
+#define RX_PHY                  0x0200  /* Uses physical address for rx bufs */
+#define TX_VIRT                 0x0400  /* Uses virtual addr for tx bufs */
+#define RX_VIRT                 0x0800 
+#define NEEDS_SERVICE           0x1000 
+
+/*
+ * Adapter Status Codes
+ */
+#define OPEN                    0x0001
+#define INITIALIZED             0x0002
+#define CLOSED                  0x0003
+#define FAILED                  0x0005
+#define NOT_INITIALIZED         0x0006
+#define IO_CONFLICT             0x0007
+#define CARD_REMOVED            0x0008
+#define CARD_INSERTED           0x0009
+
+/*
+ * Mode Bit Definitions
+ */
+#define INTERRUPT_STATUS_BIT    0x8000  /* PC Interrupt Line: 0 = Not Enabled */
+#define BOOT_STATUS_MASK        0x6000  /* Mask to isolate BOOT_STATUS */
+#define BOOT_INHIBIT            0x0000  /* BOOT_STATUS is 'inhibited' */
+#define BOOT_TYPE_1             0x2000  /* Unused BOOT_STATUS value */
+#define BOOT_TYPE_2             0x4000  /* Unused BOOT_STATUS value */
+#define BOOT_TYPE_3             0x6000  /* Unused BOOT_STATUS value */
+#define ZERO_WAIT_STATE_MASK    0x1800  /* Mask to isolate Wait State flags */
+#define ZERO_WAIT_STATE_8_BIT   0x1000  /* 0 = Disabled (Inserts Wait States) */
+#define ZERO_WAIT_STATE_16_BIT  0x0800  /* 0 = Disabled (Inserts Wait States) */
+#define LOOPING_MODE_MASK       0x0007
+#define LOOPBACK_MODE_0         0x0000
+#define LOOPBACK_MODE_1         0x0001
+#define LOOPBACK_MODE_2         0x0002
+#define LOOPBACK_MODE_3         0x0003
+#define LOOPBACK_MODE_4         0x0004
+#define LOOPBACK_MODE_5         0x0005
+#define LOOPBACK_MODE_6         0x0006
+#define LOOPBACK_MODE_7         0x0007
+#define AUTO_MEDIA_DETECT       0x0008
+#define MANUAL_CRC              0x0010
+#define EARLY_TOKEN_REL         0x0020  /* Early Token Release for Token Ring */
+#define UMAC               0x0040 
+#define UTP2_PORT               0x0080  /* For 8216T2, 0=port A, 1=Port B. */
+#define BNC_10BT_INTERFACE      0x0600  /* BNC and UTP current media set */
+#define UTP_INTERFACE           0x0500  /* Ethernet UTP Only. */
+#define BNC_INTERFACE           0x0400
+#define AUI_INTERFACE           0x0300
+#define AUI_10BT_INTERFACE      0x0200
+#define STARLAN_10_INTERFACE    0x0100
+#define INTERFACE_TYPE_MASK     0x0700
+
+/*
+ * Media Type Bit Definitions
+ *
+ * legend:      TP = Twisted Pair
+ *              STP = Shielded twisted pair
+ *              UTP = Unshielded twisted pair
+ */
+
+#define CNFG_MEDIA_TYPE_MASK    0x001e  /* POS Register 3 Mask         */
+
+#define MEDIA_S10               0x0000  /* Ethernet adapter, TP.        */
+#define MEDIA_AUI_UTP           0x0001  /* Ethernet adapter, AUI/UTP media */
+#define MEDIA_BNC               0x0002  /* Ethernet adapter, BNC media. */
+#define MEDIA_AUI               0x0003  /* Ethernet Adapter, AUI media. */
+#define MEDIA_STP_16            0x0004  /* TokenRing adap, 16Mbit STP.  */
+#define MEDIA_STP_4             0x0005  /* TokenRing adap, 4Mbit STP.   */
+#define MEDIA_UTP_16            0x0006  /* TokenRing adap, 16Mbit UTP.  */
+#define MEDIA_UTP_4             0x0007  /* TokenRing adap, 4Mbit UTP.   */
+#define MEDIA_UTP               0x0008  /* Ethernet adapter, UTP media (no AUI)
+*/
+#define MEDIA_BNC_UTP           0x0010  /* Ethernet adapter, BNC/UTP media */
+#define MEDIA_UTPFD             0x0011  /* Ethernet adapter, TP full duplex */
+#define MEDIA_UTPNL             0x0012  /* Ethernet adapter, TP with link integrity test disabled */
+#define MEDIA_AUI_BNC           0x0013  /* Ethernet adapter, AUI/BNC media */
+#define MEDIA_AUI_BNC_UTP       0x0014  /* Ethernet adapter, AUI_BNC/UTP */
+#define MEDIA_UTPA              0x0015  /* Ethernet UTP-10Mbps Ports A */
+#define MEDIA_UTPB              0x0016  /* Ethernet UTP-10Mbps Ports B */
+#define MEDIA_STP_16_UTP_16     0x0017  /* Token Ring STP-16Mbps/UTP-16Mbps */
+#define MEDIA_STP_4_UTP_4       0x0018  /* Token Ring STP-4Mbps/UTP-4Mbps */
+
+#define MEDIA_STP100_UTP100     0x0020  /* Ethernet STP-100Mbps/UTP-100Mbps */
+#define MEDIA_UTP100FD          0x0021  /* Ethernet UTP-100Mbps, full duplex */
+#define MEDIA_UTP100            0x0022  /* Ethernet UTP-100Mbps */
+
+
+#define MEDIA_UNKNOWN           0xFFFF  /* Unknown adapter/media type   */
+
+/*
+ * Definitions for the field:
+ * media_type2
+ */
+#define MEDIA_TYPE_MII              0x0001
+#define MEDIA_TYPE_UTP              0x0002
+#define MEDIA_TYPE_BNC              0x0004
+#define MEDIA_TYPE_AUI              0x0008
+#define MEDIA_TYPE_S10              0x0010
+#define MEDIA_TYPE_AUTO_SENSE       0x1000
+#define MEDIA_TYPE_AUTO_DETECT      0x4000
+#define MEDIA_TYPE_AUTO_NEGOTIATE   0x8000
+
+/*
+ * Definitions for the field:
+ * line_speed
+ */
+#define LINE_SPEED_UNKNOWN          0x0000
+#define LINE_SPEED_4                0x0001
+#define LINE_SPEED_10               0x0002
+#define LINE_SPEED_16               0x0004
+#define LINE_SPEED_100              0x0008
+#define LINE_SPEED_T4               0x0008  /* 100BaseT4 aliased for 9332BVT */
+#define LINE_SPEED_FULL_DUPLEX      0x8000
+
+/*
+ * Definitions for the field:
+ * bic_type (Bus interface chip type)
+ */
+#define BIC_NO_CHIP             0x0000  /* Bus interface chip not implemented */#define BIC_583_CHIP            0x0001  /* 83C583 bus interface chip */
+#define BIC_584_CHIP            0x0002  /* 83C584 bus interface chip */
+#define BIC_585_CHIP            0x0003  /* 83C585 bus interface chip */
+#define BIC_593_CHIP            0x0004  /* 83C593 bus interface chip */
+#define BIC_594_CHIP            0x0005  /* 83C594 bus interface chip */
+#define BIC_564_CHIP            0x0006  /* PCMCIA Bus interface chip */
+#define BIC_790_CHIP            0x0007  /* 83C790 bus i-face/Ethernet NIC chip */
+#define BIC_571_CHIP            0x0008  /* 83C571 EISA bus master i-face */
+#define BIC_587_CHIP            0x0009  /* Token Ring AT bus master i-face */
+#define BIC_574_CHIP            0x0010  /* FEAST bus interface chip */
+#define BIC_8432_CHIP           0x0011  /* 8432 bus i-face/Ethernet NIC(DEC PCI) */
+#define BIC_9332_CHIP           0x0012  /* 9332 bus i-face/100Mbps Ether NIC(DEC PCI) */
+#define BIC_8432E_CHIP          0x0013  /* 8432 Enhanced bus iface/Ethernet NIC(DEC) */
+#define BIC_EPIC100_CHIP        0x0014  /* EPIC/100 10/100 Mbps Ethernet BIC/NIC */
+#define BIC_C94_CHIP            0x0015  /* 91C94 bus i-face in PCMCIA mode */
+#define BIC_X8020_CHIP          0x0016  /* Xilinx PCMCIA multi-func i-face */
+
+/*
+ * Definitions for the field:
+ * nic_type (Bus interface chip type)
+ */
+#define NIC_UNK_CHIP            0x0000  /* Unknown NIC chip      */
+#define NIC_8390_CHIP           0x0001  /* DP8390 Ethernet NIC   */
+#define NIC_690_CHIP            0x0002  /* 83C690 Ethernet NIC   */
+#define NIC_825_CHIP            0x0003  /* 83C825 Token Ring NIC */
+/*      #define NIC_???_CHIP    0x0004  */ /* Not used           */
+/*      #define NIC_???_CHIP    0x0005  */ /* Not used           */
+/*      #define NIC_???_CHIP    0x0006  */ /* Not used           */
+#define NIC_790_CHIP            0x0007  /* 83C790 bus i-face/Ethernet NIC chip */
+#define NIC_C100_CHIP           0x0010  /* FEAST 100Mbps Ethernet NIC */
+#define NIC_8432_CHIP           0x0011  /* 8432 bus i-face/Ethernet NIC(DEC PCI) */
+#define NIC_9332_CHIP           0x0012  /* 9332 bus i-face/100Mbps Ether NIC(DEC PCI) */
+#define NIC_8432E_CHIP          0x0013  /* 8432 enhanced bus iface/Ethernet NIC(DEC) */
+#define NIC_EPIC100_CHIP        0x0014   /* EPIC/100 10/100 Mbps Ethernet BIC/NIC */
+#define NIC_C94_CHIP            0x0015  /* 91C94 PC Card with multi func */
+
+/*
+ * Definitions for the field:
+ * adapter_type The adapter_type field describes the adapter/bus
+ *              configuration.
+ */
+#define BUS_UNK_TYPE            0x0000  /*  */
+#define BUS_ISA16_TYPE          0x0001  /* 16 bit adap in 16 bit (E)ISA slot  */
+#define BUS_ISA8_TYPE           0x0002  /* 8/16b adap in 8 bit XT/(E)ISA slot */
+#define BUS_MCA_TYPE            0x0003  /* Micro Channel adapter              */#define BUS_EISA32M_TYPE        0x0004  /* EISA 32 bit bus master adapter     */#define BUS_EISA32S_TYPE        0x0005  /* EISA 32 bit bus slave adapter      */#define BUS_PCMCIA_TYPE         0x0006  /* PCMCIA adapter */
+#define BUS_PCI_TYPE            0x0007  /* PCI bus */
+
+/*
+ * Receive Mask definitions
+ */
+#define ACCEPT_MULTICAST                0x0001
+#define ACCEPT_BROADCAST                0x0002
+#define PROMISCUOUS_MODE                0x0004
+#define ACCEPT_SOURCE_ROUTING           0x0008
+#define ACCEPT_ERR_PACKETS              0x0010
+#define ACCEPT_ATT_MAC_FRAMES           0x0020
+#define ACCEPT_MULTI_PROM               0x0040
+#define TRANSMIT_ONLY                   0x0080
+#define ACCEPT_EXT_MAC_FRAMES           0x0100
+#define EARLY_RX_ENABLE                 0x0200
+#define PKT_SIZE_NOT_NEEDED             0x0400
+#define ACCEPT_SOURCE_ROUTING_SPANNING  0x0808
+
+#define ACCEPT_ALL_MAC_FRAMES           0x0120
+
+/*
+ * config_mode defs
+ */
+#define STORE_EEROM             0x0001  /* Store config in EEROM. */
+#define STORE_REGS              0x0002  /* Store config in register set. */
+
+/*
+ * equates for lmac_flags in adapter structure (Ethernet)
+ */
+#define         MEM_DISABLE     0x0001
+#define         RX_STATUS_POLL  0x0002
+#define         USE_RE_BIT      0x0004
+/*#define       RESERVED        0x0008 */
+/*#define       RESERVED        0x0010 */
+/*#define       RESERVED        0x0020 */
+/*#define       RESERVED        0x0040 */
+/*#define       RESERVED        0x0080 */
+/*#define       RESERVED        0x0100 */
+/*#define       RESERVED        0x0200 */
+/*#define       RESERVED        0x0400 */
+/*#define       RESERVED        0x0800 */
+/*#define       RESERVED        0x1000 */
+/*#define       RESERVED        0x2000 */
+/*#define       RESERVED        0x4000 */
+/*#define       RESERVED        0x8000 */
+
+/* media_opts & media_set Fields bit defs for Ethernet ... */
+#define         MED_OPT_BNC     0x01
+#define         MED_OPT_UTP     0x02
+#define         MED_OPT_AUI     0x04
+#define         MED_OPT_10MB    0x08
+#define         MED_OPT_100MB   0x10
+#define         MED_OPT_S10     0x20
+
+/* media_opts & media_set Fields bit defs for Token Ring ... */
+#define         MED_OPT_4MB     0x08
+#define         MED_OPT_16MB    0x10
+#define         MED_OPT_STP     0x40
+
+#define MAX_8023_SIZE           1500    /* Max 802.3 size of frame. */
+#define DEFAULT_ERX_VALUE       4       /* Number of 16-byte blocks for 790B early Rx. */
+#define DEFAULT_ETX_VALUE       32      /* Number of bytes for 790B early Tx. */#define DEFAULT_TX_RETRIES      3       /* Number of transmit retries */
+#define LPBK_FRAME_SIZE         1024    /* Default loopback frame for Rx calibration test. */
+#define MAX_LOOKAHEAD_SIZE      252     /* Max lookahead size for ethernet. */
+
+#define RW_MAC_STATE                    0x1101
+#define RW_SA_OF_LAST_AMP_OR_SMP        0x2803
+#define RW_PHYSICAL_DROP_NUMBER         0x3B02
+#define RW_UPSTREAM_NEIGHBOR_ADDRESS    0x3E03
+#define RW_PRODUCT_INSTANCE_ID          0x4B09
+
+#define RW_TRC_STATUS_BLOCK             0x5412
+
+#define RW_MAC_ERROR_COUNTERS_NO_CLEAR  0x8006
+#define RW_MAC_ERROR_COUNTER_CLEAR      0x7A06
+#define RW_CONFIG_REGISTER_0            0xA001
+#define RW_CONFIG_REGISTER_1            0xA101
+#define RW_PRESCALE_TIMER_THRESHOLD     0xA201
+#define RW_TPT_THRESHOLD                0xA301
+#define RW_TQP_THRESHOLD                0xA401
+#define RW_TNT_THRESHOLD                0xA501
+#define RW_TBT_THRESHOLD                0xA601
+#define RW_TSM_THRESHOLD                0xA701
+#define RW_TAM_THRESHOLD                0xA801
+#define RW_TBR_THRESHOLD                0xA901
+#define RW_TER_THRESHOLD                0xAA01
+#define RW_TGT_THRESHOLD                0xAB01
+#define RW_THT_THRESHOLD                0xAC01
+#define RW_TRR_THRESHOLD                0xAD01
+#define RW_TVX_THRESHOLD                0xAE01
+#define RW_INDIVIDUAL_MAC_ADDRESS       0xB003
+
+#define RW_INDIVIDUAL_GROUP_ADDRESS     0xB303  /* all of group addr */
+#define RW_INDIVIDUAL_GROUP_ADDR_WORD_0 0xB301  /* 1st word of group addr */
+#define RW_INDIVIDUAL_GROUP_ADDR        0xB402  /* 2nd-3rd word of group addr */
+#define RW_FUNCTIONAL_ADDRESS           0xB603  /* all of functional addr */
+#define RW_FUNCTIONAL_ADDR_WORD_0       0xB601  /* 1st word of func  addr */
+#define RW_FUNCTIONAL_ADDR              0xB702  /* 2nd-3rd word func addr */
+
+#define RW_BIT_SIGNIFICANT_GROUP_ADDR   0xB902
+#define RW_SOURCE_RING_BRIDGE_NUMBER    0xBB01
+#define RW_TARGET_RING_NUMBER           0xBC01
+
+#define RW_HIC_INTERRUPT_MASK           0xC601
+
+#define SOURCE_ROUTING_SPANNING_BITS    0x00C0  /* Spanning Tree Frames */
+#define SOURCE_ROUTING_EXPLORER_BIT     0x0040  /* Explorer and Single Route */
+
+        /* write */
+
+#define CSR_MSK_ALL             0x80    // Bic 587 Only
+#define CSR_MSKTINT             0x20
+#define CSR_MSKCBUSY            0x10
+#define CSR_CLRTINT             0x08
+#define CSR_CLRCBUSY            0x04
+#define CSR_WCSS                0x02
+#define CSR_CA                  0x01
+
+        /* read */
+
+#define CSR_TINT                0x20
+#define CSR_CINT                0x10
+#define CSR_TSTAT               0x08
+#define CSR_CSTAT               0x04
+#define CSR_FAULT               0x02
+#define CSR_CBUSY               0x01
+
+#define LAAR_MEM16ENB           0x80
+#define Zws16                   0x20
+
+#define IRR_IEN                 0x80
+#define Zws8                    0x01
+
+#define IMCCR_EIL               0x04
+
+typedef struct {
+        __u8            ac;                             /* Access Control */
+        __u8            fc;                             /* Frame Control */
+        __u8            da[6];                          /* Dest Addr */
+        __u8            sa[6];                          /* Source Addr */
+
+        __u16            vl;                             /* Vector Length */
+        __u8            dc_sc;                          /* Dest/Source Class */
+        __u8            vc;                             /* Vector Code */
+        } MAC_HEADER;
+
+#define MAX_SUB_VECTOR_INFO     (RX_DATA_BUFFER_SIZE - sizeof(MAC_HEADER) - 2)
+
+typedef struct
+        {
+        __u8            svl;                            /* Sub-vector Length */
+        __u8            svi;                            /* Sub-vector Code */
+        __u8            svv[MAX_SUB_VECTOR_INFO];       /* Sub-vector Info */
+        } MAC_SUB_VECTOR;
+
+#endif /* __KERNEL__ */
+#endif /* __LINUX_SMCTR_H */
diff --git a/drivers/net/tokenring/smctr_firmware.h b/drivers/net/tokenring/smctr_firmware.h
new file mode 100644 (file)
index 0000000..8bfbc51
--- /dev/null
@@ -0,0 +1,979 @@
+/*
+ * The firmware this driver downloads into the tokenring card is a
+ * seperate 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
+ * with the use of SMC TokenRing adapters. There is no waranty
+ * expressed or implied about its fitness for any purpose.
+ */
+
+/* smctr_firmware.h: SMC TokenRing driver firmware dump for Linux.
+ *
+ * Notes:
+ *  - This is an 8K binary image. (MCT.BIN v6.3C1 03/01/95)
+ *
+ * Authors:
+ *  - Jay Schulist <jschlst@turbolinux.com>
+ */
+
+#include <linux/config.h>
+
+#if defined(CONFIG_SMCTR) || defined(CONFIG_SMCTR_MODULE)
+
+unsigned char smctr_code[] = {
+       0x0BC, 0x01D, 0x012, 0x03B, 0x063, 0x0B4, 0x0E9, 0x000,
+       0x000, 0x01F, 0x000, 0x001, 0x001, 0x000, 0x002, 0x005,
+       0x001, 0x000, 0x006, 0x003, 0x001, 0x000, 0x004, 0x009,
+       0x001, 0x000, 0x00A, 0x007, 0x001, 0x000, 0x008, 0x00B,
+       0x001, 0x000, 0x00C, 0x000, 0x000, 0x000, 0x000, 0x00F,
+       0x001, 0x000, 0x010, 0x00D, 0x001, 0x000, 0x00E, 0x013,
+       0x001, 0x000, 0x014, 0x011, 0x001, 0x000, 0x012, 0x000,
+       0x000, 0x005, 0x000, 0x015, 0x001, 0x000, 0x016, 0x019,
+       0x001, 0x000, 0x01A, 0x017, 0x001, 0x000, 0x018, 0x000,
+       0x000, 0x00E, 0x000, 0x000, 0x000, 0x001, 0x000, 0x000,
+       0x000, 0x004, 0x000, 0x01B, 0x001, 0x000, 0x01C, 0x000,
+       0x000, 0x007, 0x000, 0x000, 0x000, 0x00F, 0x000, 0x000,
+       0x000, 0x00B, 0x000, 0x01D, 0x001, 0x000, 0x01E, 0x000,
+       0x000, 0x008, 0x000, 0x000, 0x000, 0x002, 0x000, 0x000,
+       0x000, 0x00C, 0x000, 0x000, 0x000, 0x006, 0x000, 0x000,
+       0x000, 0x00D, 0x000, 0x000, 0x000, 0x003, 0x000, 0x000,
+       0x000, 0x00A, 0x000, 0x000, 0x000, 0x009, 0x000, 0x004,
+       0x078, 0x0C6, 0x0BC, 0x001, 0x094, 0x004, 0x093, 0x080,
+       0x0C8, 0x040, 0x062, 0x0E9, 0x0DA, 0x01C, 0x02C, 0x015,
+       0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x058,
+       0x00B, 0x0E9, 0x0E5, 0x0D5, 0x095, 0x0C1, 0x09D, 0x077,
+       0x0CE, 0x0BB, 0x0A0, 0x06E, 0x01C, 0x005, 0x0F6, 0x077,
+       0x0C6, 0x002, 0x0FA, 0x096, 0x070, 0x0E8, 0x01D, 0x0C0,
+       0x017, 0x00E, 0x002, 0x0FA, 0x058, 0x07D, 0x0C0, 0x05F,
+       0x072, 0x0CE, 0x0EC, 0x0A4, 0x0C3, 0x084, 0x090, 0x07A,
+       0x030, 0x0CD, 0x08D, 0x079, 0x019, 0x0E7, 0x06C, 0x024,
+       0x027, 0x09C, 0x008, 0x039, 0x007, 0x038, 0x0A8, 0x04A,
+       0x04C, 0x0EA, 0x04D, 0x098, 0x09B, 0x024, 0x04C, 0x0C0,
+       0x026, 0x0D3, 0x0E7, 0x054, 0x05A, 0x04D, 0x0F2, 0x04C,
+       0x00C, 0x013, 0x023, 0x049, 0x090, 0x032, 0x06E, 0x0A4,
+       0x0DF, 0x093, 0x071, 0x013, 0x077, 0x026, 0x0E1, 0x026,
+       0x0F8, 0x026, 0x00C, 0x04C, 0x012, 0x026, 0x008, 0x009,
+       0x082, 0x082, 0x060, 0x0A9, 0x030, 0x079, 0x036, 0x0B0,
+       0x0B2, 0x0A8, 0x0A7, 0x072, 0x064, 0x08F, 0x09B, 0x033,
+       0x033, 0x0F9, 0x0B8, 0x039, 0x0D5, 0x011, 0x073, 0x0AA,
+       0x075, 0x026, 0x05D, 0x026, 0x051, 0x093, 0x02A, 0x049,
+       0x094, 0x0C9, 0x095, 0x089, 0x0BC, 0x04D, 0x0C8, 0x09B,
+       0x080, 0x09B, 0x0A0, 0x099, 0x006, 0x04C, 0x086, 0x026,
+       0x058, 0x09B, 0x0A4, 0x09B, 0x099, 0x037, 0x062, 0x06C,
+       0x067, 0x09B, 0x033, 0x030, 0x0BF, 0x036, 0x066, 0x061,
+       0x0BF, 0x036, 0x0EC, 0x0C5, 0x0BD, 0x066, 0x082, 0x05A,
+       0x050, 0x031, 0x0D5, 0x09D, 0x098, 0x018, 0x029, 0x03C,
+       0x098, 0x086, 0x04C, 0x017, 0x026, 0x03E, 0x02C, 0x0B8,
+       0x069, 0x03B, 0x049, 0x02E, 0x0B4, 0x008, 0x043, 0x01A,
+       0x0A4, 0x0F9, 0x0B3, 0x051, 0x0F1, 0x010, 0x0F3, 0x043,
+       0x0CD, 0x008, 0x06F, 0x063, 0x079, 0x0B3, 0x033, 0x00E,
+       0x013, 0x098, 0x049, 0x098, 0x004, 0x0DA, 0x07C, 0x0E0,
+       0x052, 0x079, 0x031, 0x00C, 0x098, 0x02E, 0x04D, 0x0AC,
+       0x02C, 0x084, 0x014, 0x0EE, 0x04C, 0x0FE, 0x067, 0x05E,
+       0x0E4, 0x09A, 0x075, 0x029, 0x0D7, 0x0A9, 0x035, 0x03A,
+       0x094, 0x05B, 0x0D5, 0x09B, 0x058, 0x0B4, 0x0AF, 0x075,
+       0x066, 0x0AF, 0x014, 0x0A9, 0x0EF, 0x040, 0x095, 0x025,
+       0x008, 0x0B9, 0x0AD, 0x042, 0x0FC, 0x0D8, 0x0D9, 0x08C,
+       0x033, 0x00E, 0x013, 0x098, 0x066, 0x01E, 0x045, 0x0AC,
+       0x0B0, 0x00C, 0x042, 0x0D3, 0x0CC, 0x0A6, 0x012, 0x062,
+       0x0DE, 0x0B4, 0x0B1, 0x080, 0x049, 0x07D, 0x0A2, 0x0DE,
+       0x0B4, 0x018, 0x0C0, 0x024, 0x084, 0x0E6, 0x054, 0x0F5,
+       0x083, 0x046, 0x001, 0x068, 0x01A, 0x063, 0x00C, 0x0C6,
+       0x012, 0x064, 0x0FA, 0x04C, 0x035, 0x01C, 0x02C, 0x00E,
+       0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA,
+       0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AD, 0x0D7, 0x002,
+       0x070, 0x0E0, 0x04C, 0x0F3, 0x0A1, 0x0C1, 0x0D5, 0x0C0,
+       0x03C, 0x0B9, 0x069, 0x039, 0x060, 0x04E, 0x058, 0x077,
+       0x002, 0x067, 0x093, 0x03C, 0x099, 0x0E4, 0x0CF, 0x038,
+       0x01C, 0x097, 0x02E, 0x040, 0x01B, 0x090, 0x031, 0x046,
+       0x0A3, 0x05E, 0x00E, 0x088, 0x034, 0x06A, 0x035, 0x0E0,
+       0x0E8, 0x0AA, 0x035, 0x01A, 0x0A9, 0x0F5, 0x015, 0x046,
+       0x0A3, 0x0EA, 0x07D, 0x04A, 0x0A3, 0x051, 0x0AA, 0x09F,
+       0x070, 0x054, 0x0A6, 0x057, 0x02E, 0x0B4, 0x0CD, 0x0C8,
+       0x0A3, 0x00C, 0x0C1, 0x0DA, 0x0C6, 0x0E1, 0x0CB, 0x07A,
+       0x0D4, 0x01C, 0x068, 0x0FF, 0x0CF, 0x055, 0x0A8, 0x0C0,
+       0x02D, 0x085, 0x011, 0x017, 0x044, 0x02A, 0x030, 0x00B,
+       0x04A, 0x088, 0x0C2, 0x04D, 0x0B5, 0x020, 0x0D5, 0x026,
+       0x001, 0x069, 0x051, 0x069, 0x052, 0x019, 0x052, 0x060,
+       0x016, 0x095, 0x016, 0x082, 0x096, 0x054, 0x098, 0x005,
+       0x0A5, 0x045, 0x0F3, 0x0DD, 0x06A, 0x0F9, 0x028, 0x018,
+       0x0EF, 0x000, 0x030, 0x030, 0x051, 0x04E, 0x044, 0x05D,
+       0x012, 0x0D1, 0x043, 0x0E6, 0x012, 0x06F, 0x09E, 0x0BA,
+       0x0CC, 0x0DF, 0x025, 0x003, 0x01D, 0x0E0, 0x006, 0x006,
+       0x00A, 0x030, 0x0CC, 0x0A9, 0x0EB, 0x02D, 0x000, 0x086,
+       0x0A6, 0x012, 0x065, 0x04F, 0x056, 0x0D6, 0x065, 0x049,
+       0x05F, 0x03D, 0x0E8, 0x037, 0x0C9, 0x040, 0x0C7, 0x078,
+       0x001, 0x081, 0x082, 0x08C, 0x033, 0x018, 0x049, 0x080,
+       0x0AE, 0x040, 0x0C5, 0x018, 0x005, 0x09C, 0x06D, 0x018,
+       0x066, 0x00E, 0x0F3, 0x0A0, 0x0C6, 0x012, 0x062, 0x0DE,
+       0x0F5, 0x004, 0x0B4, 0x0AC, 0x06B, 0x0C6, 0x019, 0x091,
+       0x073, 0x005, 0x048, 0x02E, 0x072, 0x094, 0x080, 0x073,
+       0x0A1, 0x0C8, 0x047, 0x036, 0x066, 0x064, 0x02F, 0x036,
+       0x066, 0x064, 0x007, 0x099, 0x002, 0x091, 0x08E, 0x072,
+       0x0D1, 0x00F, 0x09D, 0x006, 0x031, 0x073, 0x0A0, 0x0C3,
+       0x051, 0x06A, 0x01A, 0x020, 0x0BF, 0x03A, 0x00C, 0x02C,
+       0x073, 0x087, 0x043, 0x05E, 0x060, 0x002, 0x023, 0x0FC,
+       0x0E0, 0x0D6, 0x035, 0x0EF, 0x09E, 0x0F5, 0x0EF, 0x092,
+       0x081, 0x08E, 0x0F0, 0x003, 0x003, 0x005, 0x018, 0x066,
+       0x045, 0x0CC, 0x00B, 0x048, 0x02E, 0x070, 0x00A, 0x040,
+       0x039, 0x0D0, 0x0E4, 0x023, 0x09B, 0x033, 0x032, 0x017,
+       0x09B, 0x033, 0x032, 0x003, 0x0CC, 0x085, 0x048, 0x0C7,
+       0x038, 0x014, 0x0A5, 0x0CE, 0x029, 0x07E, 0x0D2, 0x080,
+       0x0A1, 0x0A8, 0x0B4, 0x048, 0x088, 0x02F, 0x0CE, 0x083,
+       0x00B, 0x01C, 0x0E1, 0x0D0, 0x0D7, 0x098, 0x004, 0x088,
+       0x087, 0x0CE, 0x096, 0x031, 0x073, 0x0A5, 0x08F, 0x0F3,
+       0x083, 0x058, 0x0D7, 0x0BE, 0x07B, 0x082, 0x0AF, 0x092,
+       0x081, 0x08E, 0x0F0, 0x003, 0x003, 0x005, 0x018, 0x066,
+       0x045, 0x0CC, 0x015, 0x020, 0x0B9, 0x0C8, 0x029, 0x000,
+       0x0E7, 0x043, 0x090, 0x08E, 0x06C, 0x0CC, 0x0C8, 0x05E,
+       0x06C, 0x0CC, 0x0C8, 0x00F, 0x032, 0x005, 0x023, 0x01C,
+       0x0E4, 0x050, 0x0D4, 0x05A, 0x017, 0x088, 0x02F, 0x0CE,
+       0x083, 0x010, 0x0F9, 0x0D0, 0x023, 0x017, 0x03A, 0x004,
+       0x035, 0x0E6, 0x000, 0x022, 0x016, 0x039, 0x0C3, 0x0A3,
+       0x0FC, 0x0E0, 0x0D6, 0x035, 0x0E0, 0x0BF, 0x0F4, 0x018,
+       0x0F2, 0x02D, 0x04D, 0x043, 0x051, 0x06E, 0x05A, 0x022,
+       0x01F, 0x030, 0x0D4, 0x017, 0x0E7, 0x041, 0x091, 0x073,
+       0x005, 0x048, 0x02E, 0x077, 0x069, 0x000, 0x0E7, 0x043,
+       0x090, 0x08E, 0x06C, 0x0CC, 0x0C8, 0x05E, 0x06C, 0x0CC,
+       0x0C8, 0x00F, 0x032, 0x005, 0x023, 0x01C, 0x0EF, 0x04C,
+       0x04E, 0x006, 0x004, 0x0C9, 0x09E, 0x00B, 0x0FF, 0x041,
+       0x08F, 0x022, 0x0D4, 0x0D4, 0x035, 0x016, 0x0E5, 0x0A2,
+       0x021, 0x0F3, 0x05A, 0x082, 0x0FC, 0x0E8, 0x032, 0x02E,
+       0x060, 0x0A9, 0x005, 0x0CE, 0x013, 0x048, 0x007, 0x03A,
+       0x01C, 0x084, 0x073, 0x066, 0x066, 0x042, 0x0F3, 0x066,
+       0x066, 0x040, 0x079, 0x090, 0x029, 0x018, 0x0E7, 0x00A,
+       0x098, 0x09C, 0x00A, 0x09E, 0x0B5, 0x012, 0x05C, 0x07C,
+       0x0C3, 0x031, 0x08B, 0x098, 0x02A, 0x07C, 0x0D3, 0x0ED,
+       0x038, 0x0E9, 0x0D3, 0x04E, 0x074, 0x0ED, 0x049, 0x09E,
+       0x00B, 0x0FF, 0x041, 0x08F, 0x022, 0x0D4, 0x0D4, 0x035,
+       0x016, 0x0E5, 0x0A2, 0x02D, 0x0EB, 0x045, 0x033, 0x08F,
+       0x0FC, 0x0F7, 0x0A0, 0x05F, 0x025, 0x003, 0x01D, 0x0E4,
+       0x00E, 0x006, 0x00A, 0x030, 0x0CC, 0x00C, 0x0F3, 0x0EB,
+       0x040, 0x0DE, 0x061, 0x0A8, 0x070, 0x092, 0x00A, 0x000,
+       0x0E1, 0x024, 0x01E, 0x000, 0x0E1, 0x024, 0x01E, 0x000,
+       0x0E1, 0x024, 0x01E, 0x000, 0x0E1, 0x024, 0x01E, 0x000,
+       0x0E1, 0x024, 0x01E, 0x001, 0x00F, 0x098, 0x02A, 0x00B,
+       0x0F3, 0x0A0, 0x0C8, 0x0B9, 0x0A2, 0x0A4, 0x017, 0x03A,
+       0x069, 0x000, 0x0E7, 0x043, 0x090, 0x08E, 0x075, 0x048,
+       0x05E, 0x070, 0x069, 0x001, 0x0E6, 0x000, 0x052, 0x031,
+       0x0CC, 0x018, 0x014, 0x0A5, 0x0CC, 0x009, 0x082, 0x094,
+       0x073, 0x00C, 0x0A0, 0x091, 0x0F5, 0x025, 0x0CC, 0x007,
+       0x006, 0x084, 0x084, 0x09F, 0x030, 0x0A2, 0x0A4, 0x07D,
+       0x050, 0x075, 0x0A6, 0x065, 0x001, 0x04A, 0x08E, 0x0B4,
+       0x0CC, 0x0C4, 0x035, 0x054, 0x075, 0x066, 0x0A4, 0x097,
+       0x07A, 0x089, 0x050, 0x053, 0x013, 0x080, 0x019, 0x0E3,
+       0x049, 0x05C, 0x06D, 0x0CE, 0x0A9, 0x040, 0x035, 0x006,
+       0x078, 0x0D2, 0x057, 0x006, 0x0F1, 0x0B3, 0x02A, 0x08D,
+       0x097, 0x023, 0x062, 0x092, 0x05D, 0x069, 0x099, 0x01C,
+       0x06A, 0x036, 0x0E6, 0x0CD, 0x046, 0x012, 0x06F, 0x09E,
+       0x0E1, 0x0AB, 0x0E4, 0x0A3, 0x00C, 0x0C0, 0x0DE, 0x0AC,
+       0x0D4, 0x00D, 0x028, 0x01B, 0x0D0, 0x012, 0x0A5, 0x000,
+       0x0F8, 0x04B, 0x0AD, 0x033, 0x028, 0x006, 0x0A0, 0x0DE,
+       0x014, 0x097, 0x03A, 0x089, 0x05D, 0x0C0, 0x00D, 0x0E3,
+       0x006, 0x090, 0x092, 0x05D, 0x069, 0x098, 0x066, 0x0B9,
+       0x019, 0x095, 0x0E4, 0x0A8, 0x0CF, 0x09D, 0x033, 0x018,
+       0x049, 0x0BE, 0x07B, 0x086, 0x0AF, 0x092, 0x08C, 0x033,
+       0x024, 0x014, 0x00C, 0x0F4, 0x083, 0x024, 0x021, 0x0C2,
+       0x070, 0x0BF, 0x0F4, 0x018, 0x0F2, 0x02D, 0x04D, 0x043,
+       0x051, 0x06E, 0x05A, 0x022, 0x01F, 0x032, 0x0A8, 0x02F,
+       0x0CE, 0x083, 0x022, 0x0E6, 0x005, 0x0A4, 0x017, 0x03A,
+       0x069, 0x000, 0x0E7, 0x043, 0x090, 0x08E, 0x075, 0x048,
+       0x05E, 0x070, 0x069, 0x001, 0x0E6, 0x042, 0x0A4, 0x063,
+       0x098, 0x002, 0x029, 0x04B, 0x09A, 0x029, 0x078, 0x0E9,
+       0x040, 0x053, 0x013, 0x081, 0x081, 0x032, 0x067, 0x082,
+       0x0FF, 0x0D0, 0x063, 0x0C8, 0x0B5, 0x035, 0x00D, 0x045,
+       0x0AE, 0x050, 0x008, 0x07C, 0x0E0, 0x0D0, 0x05F, 0x09D,
+       0x006, 0x045, 0x0CC, 0x001, 0x0A4, 0x017, 0x03A, 0x069,
+       0x000, 0x0E7, 0x043, 0x090, 0x08E, 0x075, 0x048, 0x05E,
+       0x070, 0x069, 0x001, 0x0E6, 0x059, 0x0A4, 0x063, 0x098,
+       0x01C, 0x052, 0x097, 0x03B, 0x030, 0x052, 0x08E, 0x07D,
+       0x02A, 0x009, 0x01F, 0x051, 0x0EB, 0x0A4, 0x0A4, 0x00A,
+       0x0B9, 0x094, 0x087, 0x0AE, 0x0C5, 0x031, 0x038, 0x002,
+       0x0FF, 0x0D0, 0x063, 0x0C8, 0x0B5, 0x035, 0x00D, 0x045,
+       0x0AE, 0x050, 0x008, 0x07C, 0x0EA, 0x020, 0x0BF, 0x03A,
+       0x00C, 0x08B, 0x09A, 0x016, 0x090, 0x05C, 0x0E9, 0x0A4,
+       0x003, 0x09D, 0x00E, 0x042, 0x039, 0x0D5, 0x021, 0x079,
+       0x095, 0x048, 0x00F, 0x030, 0x00A, 0x091, 0x08E, 0x060,
+       0x0EB, 0x029, 0x073, 0x000, 0x009, 0x054, 0x004, 0x0CA,
+       0x082, 0x065, 0x052, 0x065, 0x0E4, 0x0CA, 0x022, 0x065,
+       0x072, 0x065, 0x009, 0x032, 0x0E0, 0x099, 0x072, 0x04C,
+       0x0C4, 0x0E0, 0x00B, 0x0FF, 0x041, 0x08F, 0x022, 0x0D4,
+       0x0D4, 0x035, 0x016, 0x0B9, 0x040, 0x021, 0x0F3, 0x08A,
+       0x082, 0x0FC, 0x0E8, 0x032, 0x02E, 0x060, 0x0A9, 0x005,
+       0x0CE, 0x09A, 0x040, 0x039, 0x0D0, 0x0E4, 0x023, 0x09D,
+       0x052, 0x017, 0x099, 0x054, 0x061, 0x099, 0x001, 0x0E6,
+       0x040, 0x0A4, 0x063, 0x098, 0x004, 0x0B1, 0x084, 0x098,
+       0x018, 0x0EF, 0x02D, 0x003, 0x005, 0x031, 0x038, 0x002,
+       0x0FF, 0x0D0, 0x063, 0x0C8, 0x0B5, 0x035, 0x00D, 0x045,
+       0x0B9, 0x068, 0x088, 0x07C, 0x0E0, 0x050, 0x05F, 0x09D,
+       0x006, 0x045, 0x0CC, 0x081, 0x048, 0x02E, 0x071, 0x034,
+       0x08F, 0x048, 0x001, 0x048, 0x015, 0x021, 0x005, 0x021,
+       0x0E9, 0x00A, 0x052, 0x003, 0x0CE, 0x05A, 0x046, 0x039,
+       0x0CF, 0x047, 0x08E, 0x060, 0x0AB, 0x01A, 0x0F3, 0x053,
+       0x043, 0x0EB, 0x035, 0x024, 0x0B8, 0x01B, 0x030, 0x007,
+       0x009, 0x08A, 0x074, 0x02F, 0x07E, 0x041, 0x074, 0x01E,
+       0x01D, 0x00D, 0x087, 0x046, 0x049, 0x0D5, 0x095, 0x0D1,
+       0x0D5, 0x0D5, 0x0BB, 0x0A9, 0x04E, 0x082, 0x09D, 0x005,
+       0x03A, 0x00A, 0x074, 0x014, 0x0E8, 0x029, 0x0D0, 0x042,
+       0x074, 0x05B, 0x0CE, 0x050, 0x0C4, 0x007, 0x045, 0x0BC,
+       0x0E2, 0x00C, 0x040, 0x074, 0x05B, 0x0CE, 0x083, 0x004,
+       0x0F9, 0x095, 0x04D, 0x013, 0x063, 0x05E, 0x06F, 0x031,
+       0x03B, 0x0A0, 0x08B, 0x0A2, 0x0C5, 0x039, 0x08D, 0x078,
+       0x03A, 0x022, 0x0A0, 0x000, 0x06B, 0x0C1, 0x0D1, 0x054,
+       0x060, 0x016, 0x0D9, 0x091, 0x0A2, 0x0E7, 0x043, 0x08C,
+       0x024, 0x0DC, 0x01C, 0x0E0, 0x051, 0x017, 0x039, 0x06B,
+       0x03B, 0x0CC, 0x04B, 0x042, 0x02E, 0x06B, 0x050, 0x0BF,
+       0x036, 0x036, 0x065, 0x04F, 0x07A, 0x018, 0x055, 0x025,
+       0x078, 0x098, 0x023, 0x0E7, 0x050, 0x03E, 0x0F3, 0x081,
+       0x04C, 0x002, 0x06D, 0x03E, 0x071, 0x053, 0x0AF, 0x078,
+       0x0A9, 0x0D4, 0x0A6, 0x029, 0x0B1, 0x0BC, 0x0D9, 0x099,
+       0x0B2, 0x08E, 0x062, 0x08F, 0x022, 0x02E, 0x075, 0x016,
+       0x0B0, 0x0B2, 0x0AB, 0x023, 0x028, 0x016, 0x054, 0x052,
+       0x031, 0x0BC, 0x0D9, 0x099, 0x0B2, 0x08E, 0x066, 0x019,
+       0x002, 0x02E, 0x075, 0x016, 0x050, 0x02C, 0x0A9, 0x0C8,
+       0x0C6, 0x0F5, 0x020, 0x0D3, 0x0E4, 0x07F, 0x04F, 0x09C,
+       0x00A, 0x0D6, 0x016, 0x07F, 0x090, 0x0EE, 0x04C, 0x0EB,
+       0x0CF, 0x0E2, 0x088, 0x0BA, 0x02F, 0x042, 0x086, 0x0AE,
+       0x0BD, 0x0E5, 0x0A7, 0x052, 0x09F, 0x093, 0x063, 0x079,
+       0x0EB, 0x033, 0x008, 0x0F9, 0x094, 0x052, 0x047, 0x0CD,
+       0x099, 0x025, 0x06F, 0x03A, 0x00C, 0x013, 0x0E6, 0x055,
+       0x034, 0x04C, 0x05A, 0x04D, 0x0B5, 0x023, 0x095, 0x0A5,
+       0x048, 0x011, 0x05A, 0x00A, 0x043, 0x095, 0x0AC, 0x02C,
+       0x0BA, 0x024, 0x005, 0x049, 0x0B1, 0x0BC, 0x0CA, 0x0A7,
+       0x072, 0x06C, 0x06B, 0x0C5, 0x0BD, 0x0E8, 0x031, 0x069,
+       0x052, 0x05D, 0x006, 0x012, 0x065, 0x03E, 0x0B1, 0x050,
+       0x04C, 0x07D, 0x04F, 0x0AC, 0x00A, 0x030, 0x00B, 0x036,
+       0x064, 0x011, 0x073, 0x08A, 0x083, 0x08E, 0x075, 0x012,
+       0x09F, 0x07B, 0x0D2, 0x099, 0x058, 0x0EE, 0x082, 0x02E,
+       0x077, 0x0A0, 0x0E3, 0x09D, 0x05D, 0x04F, 0x0BC, 0x02A,
+       0x053, 0x029, 0x053, 0x0DE, 0x093, 0x024, 0x0BA, 0x0B3,
+       0x036, 0x0AA, 0x04A, 0x0C6, 0x079, 0x0D4, 0x0B9, 0x0DE,
+       0x062, 0x05A, 0x011, 0x073, 0x050, 0x050, 0x0BF, 0x037,
+       0x036, 0x06F, 0x013, 0x023, 0x0BA, 0x00C, 0x024, 0x0CE,
+       0x0BD, 0x0E2, 0x0A7, 0x052, 0x0B2, 0x08E, 0x06B, 0x060,
+       0x062, 0x02E, 0x075, 0x013, 0x030, 0x0AC, 0x0A0, 0x059,
+       0x0CA, 0x064, 0x063, 0x079, 0x0B3, 0x033, 0x065, 0x01C,
+       0x0CC, 0x032, 0x004, 0x05C, 0x0EA, 0x02C, 0x0A0, 0x059,
+       0x0DF, 0x023, 0x01B, 0x0D4, 0x083, 0x052, 0x047, 0x0DD,
+       0x079, 0x096, 0x0D4, 0x09E, 0x0B3, 0x052, 0x04B, 0x0A2,
+       0x05A, 0x01A, 0x08D, 0x05D, 0x07B, 0x082, 0x0A7, 0x052,
+       0x0B2, 0x08E, 0x066, 0x019, 0x002, 0x02E, 0x075, 0x016,
+       0x050, 0x02C, 0x08C, 0x032, 0x01D, 0x07B, 0x08E, 0x0A7,
+       0x052, 0x0B1, 0x0BC, 0x0D9, 0x099, 0x098, 0x004, 0x0DA,
+       0x07C, 0x0E2, 0x0AC, 0x0FE, 0x066, 0x019, 0x002, 0x02E,
+       0x065, 0x050, 0x0BF, 0x033, 0x066, 0x064, 0x0FE, 0x074,
+       0x018, 0x086, 0x04C, 0x017, 0x026, 0x0D6, 0x016, 0x052,
+       0x039, 0x018, 0x0DE, 0x07A, 0x0CC, 0x0C2, 0x03E, 0x065,
+       0x014, 0x091, 0x0F3, 0x066, 0x049, 0x008, 0x06E, 0x083,
+       0x009, 0x033, 0x0AF, 0x031, 0x0ED, 0x00D, 0x09D, 0x006,
+       0x012, 0x062, 0x02A, 0x031, 0x08D, 0x06D, 0x0E7, 0x041,
+       0x082, 0x07C, 0x0CA, 0x0A6, 0x089, 0x087, 0x009, 0x02E,
+       0x029, 0x0B1, 0x0AF, 0x010, 0x039, 0x0D6, 0x064, 0x097,
+       0x030, 0x01D, 0x042, 0x075, 0x093, 0x044, 0x002, 0x08C,
+       0x024, 0x0D2, 0x07A, 0x0B3, 0x050, 0x0F6, 0x089, 0x005,
+       0x043, 0x05E, 0x061, 0x098, 0x0C0, 0x02C, 0x092, 0x025,
+       0x03C, 0x08B, 0x024, 0x089, 0x049, 0x005, 0x049, 0x0E7,
+       0x00C, 0x0B9, 0x084, 0x098, 0x0B7, 0x0AD, 0x033, 0x044,
+       0x0AE, 0x05A, 0x051, 0x086, 0x060, 0x09F, 0x038, 0x0A9,
+       0x0A2, 0x06C, 0x06B, 0x0C4, 0x08E, 0x0F4, 0x05E, 0x049,
+       0x046, 0x012, 0x062, 0x0DE, 0x0B4, 0x0CD, 0x021, 0x05C,
+       0x0B4, 0x0A3, 0x00C, 0x0C1, 0x03E, 0x072, 0x029, 0x0A2,
+       0x06C, 0x06B, 0x0C6, 0x012, 0x062, 0x047, 0x0F0, 0x0E8,
+       0x0C3, 0x032, 0x004, 0x035, 0x040, 0x092, 0x0A4, 0x082,
+       0x088, 0x010, 0x092, 0x07C, 0x0CB, 0x0D4, 0x02F, 0x0A4,
+       0x002, 0x011, 0x084, 0x098, 0x0B7, 0x0AD, 0x033, 0x044,
+       0x0AE, 0x05A, 0x051, 0x086, 0x060, 0x09F, 0x038, 0x0A9,
+       0x0A2, 0x06C, 0x06B, 0x0C4, 0x08E, 0x0F4, 0x05E, 0x049,
+       0x044, 0x008, 0x049, 0x03E, 0x065, 0x0EA, 0x017, 0x0D2,
+       0x001, 0x008, 0x0C2, 0x04C, 0x05B, 0x0D6, 0x099, 0x0A4,
+       0x02B, 0x096, 0x094, 0x061, 0x098, 0x027, 0x0CE, 0x045,
+       0x034, 0x04D, 0x08D, 0x078, 0x081, 0x009, 0x027, 0x0CC,
+       0x0BD, 0x012, 0x028, 0x06C, 0x058, 0x0AF, 0x0B6, 0x0F3,
+       0x0A0, 0x0C1, 0x03E, 0x065, 0x053, 0x044, 0x0D8, 0x0D7,
+       0x092, 0x08E, 0x07D, 0x04B, 0x0C2, 0x0FA, 0x061, 0x026,
+       0x006, 0x03A, 0x0B3, 0x06B, 0x003, 0x005, 0x049, 0x0E7,
+       0x00C, 0x0B9, 0x06F, 0x05A, 0x066, 0x095, 0x05C, 0x0B4,
+       0x0A3, 0x00C, 0x0C1, 0x03E, 0x070, 0x029, 0x0A2, 0x06E,
+       0x0A4, 0x0DF, 0x093, 0x071, 0x013, 0x077, 0x026, 0x0E1,
+       0x026, 0x0F8, 0x026, 0x0C6, 0x0BC, 0x094, 0x073, 0x0F9,
+       0x02F, 0x00B, 0x0E9, 0x084, 0x098, 0x018, 0x0EA, 0x0CC,
+       0x0EC, 0x00C, 0x015, 0x027, 0x09C, 0x032, 0x0FF, 0x03D,
+       0x056, 0x0AF, 0x092, 0x08B, 0x07A, 0x0D3, 0x035, 0x0D5,
+       0x0CB, 0x04A, 0x030, 0x0CC, 0x013, 0x0E7, 0x002, 0x09A,
+       0x026, 0x0C6, 0x0BC, 0x094, 0x073, 0x041, 0x097, 0x091,
+       0x0F4, 0x083, 0x0CE, 0x004, 0x020, 0x062, 0x08B, 0x005,
+       0x016, 0x049, 0x08C, 0x024, 0x0C0, 0x0C7, 0x056, 0x090,
+       0x0C0, 0x0C1, 0x052, 0x079, 0x0C3, 0x02E, 0x05B, 0x0D5,
+       0x0A6, 0x072, 0x0D2, 0x094, 0x0FA, 0x0AD, 0x058, 0x0C8,
+       0x0FA, 0x09F, 0x054, 0x0B3, 0x032, 0x04B, 0x0B9, 0x054,
+       0x0A6, 0x051, 0x086, 0x06B, 0x079, 0x0D0, 0x060, 0x09F,
+       0x032, 0x005, 0x034, 0x04D, 0x08D, 0x07A, 0x04D, 0x01E,
+       0x07A, 0x0B3, 0x051, 0x000, 0x0A9, 0x03D, 0x059, 0x0A8,
+       0x07B, 0x044, 0x082, 0x0A1, 0x0AF, 0x04A, 0x08D, 0x052,
+       0x0A9, 0x052, 0x041, 0x049, 0x04F, 0x03A, 0x02E, 0x040,
+       0x0A4, 0x099, 0x050, 0x0BE, 0x090, 0x008, 0x052, 0x079,
+       0x0C3, 0x02E, 0x061, 0x026, 0x02D, 0x0EB, 0x04C, 0x0D0,
+       0x015, 0x0CB, 0x04A, 0x030, 0x0CC, 0x013, 0x0E7, 0x002,
+       0x09A, 0x026, 0x0C6, 0x0BC, 0x048, 0x0FE, 0x01D, 0x025,
+       0x046, 0x0A9, 0x054, 0x0A9, 0x020, 0x0A4, 0x0A7, 0x09D,
+       0x017, 0x020, 0x052, 0x04C, 0x0A8, 0x05F, 0x048, 0x004,
+       0x023, 0x009, 0x031, 0x06F, 0x05A, 0x066, 0x080, 0x0AE,
+       0x05A, 0x051, 0x086, 0x060, 0x09F, 0x038, 0x014, 0x0D1,
+       0x036, 0x035, 0x0E4, 0x0A7, 0x09D, 0x017, 0x020, 0x052,
+       0x04C, 0x0A2, 0x045, 0x00D, 0x08B, 0x015, 0x0F4, 0x091,
+       0x0DE, 0x08B, 0x0C9, 0x028, 0x0C2, 0x04C, 0x05B, 0x0D6,
+       0x099, 0x0A9, 0x05C, 0x0B4, 0x0A3, 0x00C, 0x0D6, 0x0F3,
+       0x0A0, 0x0C1, 0x03E, 0x064, 0x00A, 0x068, 0x09B, 0x01A,
+       0x0F1, 0x06D, 0x04C, 0x0AA, 0x092, 0x0E0, 0x036, 0x094,
+       0x070, 0x09B, 0x029, 0x078, 0x013, 0x0AE, 0x0B3, 0x0AA,
+       0x085, 0x0D4, 0x043, 0x075, 0x009, 0x03A, 0x0C9, 0x0EB,
+       0x035, 0x024, 0x0B8, 0x01B, 0x032, 0x08E, 0x013, 0x048,
+       0x07E, 0x04E, 0x0FD, 0x040, 0x0FD, 0x040, 0x0FD, 0x040,
+       0x0FD, 0x040, 0x0FD, 0x040, 0x0FC, 0x013, 0x0F4, 0x021,
+       0x0F9, 0x017, 0x045, 0x08A, 0x030, 0x00B, 0x033, 0x05F,
+       0x083, 0x0A2, 0x02A, 0x030, 0x00B, 0x033, 0x05F, 0x083,
+       0x0A2, 0x0A8, 0x0C0, 0x02D, 0x0B3, 0x020, 0x070, 0x092,
+       0x013, 0x09A, 0x0DE, 0x074, 0x018, 0x027, 0x0CC, 0x0AA,
+       0x068, 0x09B, 0x01A, 0x0F7, 0x007, 0x045, 0x051, 0x080,
+       0x05B, 0x066, 0x047, 0x007, 0x038, 0x0A8, 0x023, 0x0E7,
+       0x051, 0x011, 0x03F, 0x0E0, 0x0E8, 0x085, 0x046, 0x001,
+       0x06D, 0x099, 0x006, 0x012, 0x065, 0x04F, 0x07A, 0x020,
+       0x024, 0x0BA, 0x0B3, 0x032, 0x015, 0x025, 0x07B, 0x0AD,
+       0x033, 0x078, 0x0AE, 0x00E, 0x073, 0x0D0, 0x047, 0x0CE,
+       0x0A7, 0x030, 0x0CC, 0x044, 0x0FF, 0x083, 0x0A2, 0x0A8,
+       0x0C0, 0x02C, 0x0D9, 0x091, 0x0C1, 0x0D1, 0x015, 0x018,
+       0x005, 0x09B, 0x032, 0x008, 0x0BA, 0x02C, 0x051, 0x080,
+       0x059, 0x0B3, 0x020, 0x070, 0x092, 0x0E2, 0x098, 0x089,
+       0x0FD, 0x0BC, 0x0EE, 0x018, 0x090, 0x0FC, 0x08B, 0x0A2,
+       0x0C5, 0x02B, 0x00D, 0x078, 0x03A, 0x022, 0x0A5, 0x061,
+       0x0AF, 0x007, 0x045, 0x051, 0x080, 0x05B, 0x066, 0x044,
+       0x09E, 0x0B3, 0x052, 0x04B, 0x083, 0x0AD, 0x0C7, 0x009,
+       0x0BE, 0x01F, 0x09F, 0x074, 0x065, 0x05D, 0x00A, 0x017,
+       0x07C, 0x0AB, 0x0A0, 0x0C2, 0x04C, 0x038, 0x049, 0x012,
+       0x02E, 0x038, 0x049, 0x007, 0x0A3, 0x00C, 0x0C1, 0x03E,
+       0x065, 0x053, 0x044, 0x0D8, 0x0D7, 0x0AD, 0x0E7, 0x000,
+       0x032, 0x04B, 0x09B, 0x033, 0x034, 0x04A, 0x003, 0x000,
+       0x09D, 0x025, 0x0CE, 0x083, 0x024, 0x0B8, 0x019, 0x099,
+       0x08C, 0x002, 0x012, 0x04B, 0x0A1, 0x099, 0x0D8, 0x0C0,
+       0x027, 0x049, 0x073, 0x0CF, 0x0F9, 0x03C, 0x0F4, 0x07C,
+       0x0E7, 0x098, 0x004, 0x0E9, 0x02E, 0x07F, 0x039, 0x0E3,
+       0x04F, 0x046, 0x053, 0x0C0, 0x060, 0x013, 0x0A4, 0x0B9,
+       0x0E5, 0x03C, 0x003, 0x0DE, 0x08F, 0x09C, 0x0F3, 0x000,
+       0x09C, 0x06F, 0x0CF, 0x03E, 0x085, 0x0F9, 0x0A3, 0x036,
+       0x002, 0x01E, 0x060, 0x038, 0x092, 0x03E, 0x063, 0x01A,
+       0x010, 0x09F, 0x0CF, 0x018, 0x010, 0x092, 0x0BC, 0x0D0,
+       0x0A4, 0x00C, 0x0DC, 0x0C0, 0x00F, 0x09C, 0x097, 0x034,
+       0x062, 0x0B6, 0x0E7, 0x0F3, 0x0F3, 0x0A5, 0x0CF, 0x018,
+       0x042, 0x034, 0x01C, 0x0C2, 0x0CA, 0x0FA, 0x08E, 0x068,
+       0x052, 0x006, 0x0AF, 0x03C, 0x0A3, 0x00D, 0x0BF, 0x09E,
+       0x050, 0x0E1, 0x0D1, 0x073, 0x0CA, 0x0E0, 0x03A, 0x0FC,
+       0x0C1, 0x009, 0x01A, 0x01E, 0x06A, 0x05C, 0x05B, 0x08E,
+       0x063, 0x04E, 0x077, 0x073, 0x0CC, 0x061, 0x067, 0x0DD,
+       0x0E6, 0x06C, 0x048, 0x0D1, 0x0F3, 0x01B, 0x024, 0x069,
+       0x051, 0x008, 0x0D4, 0x042, 0x01B, 0x0F4, 0x067, 0x0D1,
+       0x080, 0x04E, 0x02F, 0x0D0, 0x08C, 0x0D8, 0x030, 0x009,
+       0x0C2, 0x01E, 0x080, 0x01C, 0x046, 0x001, 0x03A, 0x047,
+       0x0D0, 0x031, 0x0A1, 0x006, 0x001, 0x03A, 0x07F, 0x046,
+       0x030, 0x021, 0x018, 0x004, 0x0E9, 0x05E, 0x084, 0x029,
+       0x000, 0x0C0, 0x027, 0x0CD, 0x0D0, 0x000, 0x07C, 0x098,
+       0x004, 0x0F9, 0x02E, 0x084, 0x062, 0x08C, 0x002, 0x07D,
+       0x0BA, 0x03E, 0x07E, 0x04C, 0x002, 0x07D, 0x02E, 0x08C,
+       0x061, 0x008, 0x030, 0x009, 0x0F4, 0x01D, 0x001, 0x065,
+       0x073, 0x000, 0x09F, 0x051, 0x0D0, 0x085, 0x020, 0x018,
+       0x004, 0x0FA, 0x0BD, 0x019, 0x046, 0x018, 0x0C0, 0x027,
+       0x0DF, 0x0D1, 0x094, 0x038, 0x04C, 0x002, 0x07D, 0x017,
+       0x046, 0x057, 0x001, 0x030, 0x009, 0x0F5, 0x0FA, 0x001,
+       0x009, 0x006, 0x001, 0x03E, 0x087, 0x0A1, 0x04B, 0x088,
+       0x0C0, 0x027, 0x0DC, 0x074, 0x00D, 0x039, 0x0D3, 0x000,
+       0x09F, 0x073, 0x0D0, 0x030, 0x0B3, 0x098, 0x004, 0x0FB,
+       0x0BD, 0x006, 0x0C4, 0x083, 0x000, 0x09F, 0x047, 0x0D0,
+       0x036, 0x048, 0x0CC, 0x002, 0x071, 0x0BF, 0x03F, 0x09A,
+       0x017, 0x0E6, 0x03F, 0x008, 0x021, 0x0E6, 0x092, 0x0A4,
+       0x08F, 0x09A, 0x010, 0x031, 0x0A7, 0x0F3, 0x010, 0x0B1,
+       0x084, 0x0AF, 0x03A, 0x0AC, 0x0DC, 0x0F7, 0x073, 0x0F2,
+       0x05C, 0x0C6, 0x02A, 0x0DB, 0x09E, 0x07E, 0x07E, 0x097,
+       0x031, 0x008, 0x063, 0x0D0, 0x073, 0x07B, 0x043, 0x0A8,
+       0x0E6, 0x03D, 0x034, 0x0EA, 0x0F3, 0x0E3, 0x015, 0x0BF,
+       0x09F, 0x018, 0x05F, 0x045, 0x0CF, 0x0E8, 0x09F, 0x05F,
+       0x09A, 0x05B, 0x003, 0x0D0, 0x0F3, 0x0D3, 0x0CE, 0x037,
+       0x01C, 0x0D0, 0x00F, 0x0BB, 0x09E, 0x068, 0x078, 0x03B,
+       0x0BC, 0x0CA, 0x031, 0x0E8, 0x0F9, 0x0A2, 0x002, 0x012,
+       0x0A2, 0x073, 0x051, 0x008, 0x06F, 0x0D1, 0x0F3, 0x046,
+       0x001, 0x038, 0x0BF, 0x040, 0x0FC, 0x023, 0x000, 0x09C,
+       0x021, 0x0E8, 0x049, 0x051, 0x080, 0x04E, 0x091, 0x0F4,
+       0x021, 0x003, 0x019, 0x080, 0x04E, 0x09F, 0x0D0, 0x021,
+       0x063, 0x006, 0x001, 0x03A, 0x056, 0x08C, 0x002, 0x074,
+       0x0FE, 0x075, 0x049, 0x05E, 0x063, 0x0D3, 0x04A, 0x054,
+       0x042, 0x035, 0x013, 0x0A7, 0x0D1, 0x080, 0x04E, 0x095,
+       0x0E8, 0x01E, 0x09A, 0x04C, 0x002, 0x07C, 0x0DD, 0x01B,
+       0x0B9, 0x0E6, 0x001, 0x03E, 0x04B, 0x0A0, 0x062, 0x0A3,
+       0x000, 0x09F, 0x06E, 0x08C, 0x0FC, 0x0F3, 0x000, 0x09F,
+       0x04B, 0x0A0, 0x042, 0x018, 0x0CC, 0x002, 0x07D, 0x007,
+       0x043, 0x0DA, 0x013, 0x000, 0x09F, 0x051, 0x0D0, 0x03D,
+       0x034, 0x098, 0x004, 0x0FA, 0x0BD, 0x01C, 0x062, 0x08C,
+       0x002, 0x07D, 0x0FD, 0x01C, 0x061, 0x073, 0x000, 0x09F,
+       0x045, 0x0D1, 0x0F4, 0x04E, 0x060, 0x013, 0x0EB, 0x0F4,
+       0x025, 0x0B0, 0x033, 0x000, 0x09F, 0x043, 0x0D1, 0x0A7,
+       0x09C, 0x018, 0x004, 0x0FB, 0x08E, 0x084, 0x003, 0x0E9,
+       0x080, 0x04F, 0x0B9, 0x0E8, 0x043, 0x0C1, 0x030, 0x009,
+       0x0F7, 0x07A, 0x00A, 0x031, 0x098, 0x004, 0x0FA, 0x03E,
+       0x084, 0x040, 0x041, 0x080, 0x04E, 0x082, 0x0E7, 0x041,
+       0x087, 0x009, 0x023, 0x004, 0x023, 0x000, 0x09D, 0x005,
+       0x0CE, 0x096, 0x01C, 0x024, 0x08C, 0x010, 0x08C, 0x002,
+       0x074, 0x017, 0x03A, 0x004, 0x038, 0x049, 0x018, 0x021,
+       0x018, 0x004, 0x0E8, 0x02E, 0x074, 0x050, 0x0E1, 0x024,
+       0x060, 0x084, 0x060, 0x013, 0x0A0, 0x0B9, 0x0D4, 0x011,
+       0x0C2, 0x048, 0x0C1, 0x008, 0x0C0, 0x027, 0x041, 0x073,
+       0x0A8, 0x023, 0x084, 0x091, 0x082, 0x011, 0x080, 0x04E,
+       0x082, 0x0E7, 0x052, 0x08E, 0x012, 0x046, 0x008, 0x046,
+       0x001, 0x03A, 0x00B, 0x09D, 0x040, 0x01C, 0x024, 0x08C,
+       0x010, 0x08C, 0x002, 0x074, 0x017, 0x03A, 0x009, 0x00E,
+       0x012, 0x046, 0x008, 0x046, 0x001, 0x03A, 0x00B, 0x098,
+       0x06A, 0x01C, 0x024, 0x0B0, 0x0E1, 0x018, 0x004, 0x0E8,
+       0x02E, 0x06B, 0x050, 0x0E1, 0x025, 0x087, 0x008, 0x0C0,
+       0x027, 0x041, 0x073, 0x005, 0x043, 0x084, 0x096, 0x01C,
+       0x023, 0x000, 0x09D, 0x005, 0x0CC, 0x0AA, 0x01C, 0x024,
+       0x0B0, 0x0E1, 0x018, 0x004, 0x0E8, 0x02E, 0x070, 0x068,
+       0x070, 0x092, 0x0C3, 0x084, 0x060, 0x013, 0x0E5, 0x044,
+       0x0F9, 0x040, 0x09D, 0x005, 0x0CE, 0x05A, 0x01C, 0x024,
+       0x0B0, 0x0E1, 0x018, 0x004, 0x0F9, 0x0D1, 0x03E, 0x070,
+       0x027, 0x0CF, 0x013, 0x0E5, 0x044, 0x02C, 0x0A0, 0x042,
+       0x0CB, 0x089, 0x0F2, 0x021, 0x03A, 0x00B, 0x09C, 0x00A,
+       0x01C, 0x024, 0x0B0, 0x0E1, 0x018, 0x004, 0x0F9, 0x0D1,
+       0x00B, 0x038, 0x010, 0x0B3, 0x0C4, 0x021, 0x039, 0x036,
+       0x05C, 0x042, 0x0C8, 0x084, 0x02B, 0x079, 0x0D0, 0x061,
+       0x0C2, 0x074, 0x015, 0x024, 0x0BA, 0x0D3, 0x031, 0x0E5,
+       0x059, 0x008, 0x029, 0x008, 0x0E0, 0x066, 0x063, 0x042,
+       0x095, 0x012, 0x081, 0x000, 0x029, 0x00B, 0x0C1, 0x051,
+       0x024, 0x0B8, 0x019, 0x099, 0x090, 0x022, 0x090, 0x0B4,
+       0x018, 0x0A0, 0x091, 0x041, 0x001, 0x041, 0x041, 0x041,
+       0x052, 0x083, 0x0CA, 0x040, 0x028, 0x068, 0x029, 0x008,
+       0x0BA, 0x016, 0x010, 0x09C, 0x099, 0x00B, 0x056, 0x094,
+       0x090, 0x052, 0x015, 0x074, 0x0C0, 0x027, 0x01A, 0x02A,
+       0x0D2, 0x090, 0x025, 0x0D3, 0x000, 0x09D, 0x028, 0x0AB,
+       0x04A, 0x042, 0x017, 0x04C, 0x002, 0x070, 0x0D4, 0x084,
+       0x02E, 0x098, 0x004, 0x0E1, 0x02A, 0x042, 0x017, 0x04C,
+       0x002, 0x070, 0x082, 0x090, 0x04B, 0x0A6, 0x001, 0x038,
+       0x051, 0x048, 0x042, 0x0E9, 0x080, 0x04E, 0x015, 0x0A4,
+       0x021, 0x074, 0x0C0, 0x027, 0x00F, 0x0A4, 0x012, 0x0E9,
+       0x080, 0x04E, 0x082, 0x0AC, 0x080, 0x0AC, 0x0A0, 0x0AC,
+       0x0A9, 0x059, 0x0E5, 0x064, 0x045, 0x065, 0x0CA, 0x0C8,
+       0x04A, 0x0CE, 0x00A, 0x0CE, 0x04A, 0x0CE, 0x095, 0x091,
+       0x095, 0x094, 0x095, 0x093, 0x029, 0x025, 0x0C0, 0x0CC,
+       0x0CC, 0x088, 0x0A4, 0x097, 0x056, 0x036, 0x064, 0x072,
+       0x090, 0x054, 0x08A, 0x09C, 0x045, 0x008, 0x0B9, 0x0B7,
+       0x066, 0x012, 0x093, 0x009, 0x0C9, 0x0B2, 0x074, 0x08E,
+       0x0BA, 0x060, 0x013, 0x0E5, 0x034, 0x08E, 0x0BA, 0x060,
+       0x013, 0x0E4, 0x074, 0x08E, 0x0BA, 0x060, 0x013, 0x0E5,
+       0x069, 0x01D, 0x074, 0x0C0, 0x027, 0x0CA, 0x029, 0x01D,
+       0x074, 0x0C0, 0x027, 0x0CE, 0x0D2, 0x025, 0x0D3, 0x000,
+       0x09F, 0x038, 0x0A4, 0x04B, 0x0A6, 0x001, 0x03E, 0x05E,
+       0x091, 0x02E, 0x098, 0x004, 0x0F9, 0x015, 0x022, 0x05D,
+       0x030, 0x009, 0x0F3, 0x0E9, 0x012, 0x0E9, 0x080, 0x04F,
+       0x090, 0x052, 0x025, 0x0D3, 0x000, 0x09D, 0x0C5, 0x048,
+       0x025, 0x0D3, 0x000, 0x09C, 0x045, 0x0CE, 0x0CD, 0x009,
+       0x0C9, 0x0B2, 0x01A, 0x044, 0x0BA, 0x060, 0x013, 0x0E7,
+       0x034, 0x089, 0x074, 0x0C0, 0x027, 0x01C, 0x027, 0x0B7,
+       0x09C, 0x080, 0x0C2, 0x0D7, 0x076, 0x059, 0x09B, 0x093,
+       0x00C, 0x064, 0x0C3, 0x01D, 0x01B, 0x0F4, 0x045, 0x04B,
+       0x0C7, 0x0C6, 0x03A, 0x037, 0x0E8, 0x081, 0x04B, 0x0C7,
+       0x0C6, 0x03A, 0x037, 0x0E8, 0x091, 0x04B, 0x0C7, 0x0C6,
+       0x032, 0x061, 0x08E, 0x0B3, 0x0BC, 0x0C3, 0x04A, 0x022,
+       0x0E6, 0x0B5, 0x024, 0x097, 0x071, 0x0C9, 0x087, 0x0B4,
+       0x031, 0x0AE, 0x073, 0x0A2, 0x0CF, 0x039, 0x0D2, 0x05D,
+       0x004, 0x044, 0x042, 0x0C0, 0x0D6, 0x0DE, 0x071, 0x006,
+       0x016, 0x0BB, 0x0DB, 0x0CE, 0x083, 0x00C, 0x064, 0x0C3,
+       0x01D, 0x031, 0x013, 0x004, 0x0F9, 0x095, 0x04D, 0x013,
+       0x032, 0x093, 0x063, 0x05E, 0x066, 0x014, 0x0CC, 0x029,
+       0x02A, 0x053, 0x030, 0x0A6, 0x061, 0x04C, 0x0C2, 0x099,
+       0x085, 0x03A, 0x072, 0x0CC, 0x0C2, 0x099, 0x085, 0x006,
+       0x01B, 0x0B3, 0x00A, 0x066, 0x014, 0x014, 0x024, 0x099,
+       0x085, 0x033, 0x00A, 0x008, 0x0B1, 0x086, 0x061, 0x04C,
+       0x0C2, 0x084, 0x021, 0x068, 0x073, 0x03B, 0x030, 0x0A6,
+       0x061, 0x041, 0x04E, 0x0A5, 0x098, 0x053, 0x030, 0x0AC,
+       0x059, 0x076, 0x061, 0x04C, 0x0C2, 0x0B0, 0x08D, 0x0D6,
+       0x061, 0x04C, 0x0C2, 0x0B0, 0x02C, 0x0F6, 0x061, 0x04C,
+       0x0C2, 0x0B1, 0x08C, 0x0A5, 0x098, 0x053, 0x030, 0x0AC,
+       0x00F, 0x024, 0x0CC, 0x029, 0x098, 0x056, 0x00F, 0x028,
+       0x066, 0x015, 0x092, 0x01A, 0x019, 0x085, 0x033, 0x00A,
+       0x0CA, 0x085, 0x00C, 0x0C2, 0x099, 0x085, 0x065, 0x0C3,
+       0x0D9, 0x085, 0x033, 0x00A, 0x0CE, 0x070, 0x086, 0x061,
+       0x04C, 0x0C2, 0x0B3, 0x097, 0x071, 0x00C, 0x099, 0x03B,
+       0x0CC, 0x083, 0x058, 0x00B, 0x0EA, 0x077, 0x09D, 0x006,
+       0x04A, 0x0BE, 0x004, 0x074, 0x060, 0x0E0, 0x0D1, 0x04E,
+       0x038, 0x04C, 0x03E, 0x0EE, 0x03E, 0x0EE, 0x03E, 0x0EE,
+       0x03E, 0x0EE, 0x030, 0x0BB, 0x0CA, 0x0E1, 0x01F, 0x077,
+       0x01F, 0x077, 0x01F, 0x077, 0x01F, 0x077, 0x027, 0x070,
+       0x08F, 0x0BB, 0x080, 0x00E, 0x011, 0x0F7, 0x071, 0x0F7,
+       0x07C, 0x06F, 0x03C, 0x0B3, 0x036, 0x002, 0x0FB, 0x08D,
+       0x0E6, 0x055, 0x070, 0x07F, 0x02D, 0x024, 0x069, 0x055,
+       0x04F, 0x058, 0x0A9, 0x023, 0x01F, 0x054, 0x0F7, 0x08A,
+       0x095, 0x025, 0x02B, 0x075, 0x00C, 0x0CC, 0x0AC, 0x056,
+       0x051, 0x0CC, 0x051, 0x0E4, 0x045, 0x0CE, 0x0A2, 0x012,
+       0x039, 0x0C0, 0x0A0, 0x0AF, 0x056, 0x06A, 0x049, 0x07F,
+       0x002, 0x08C, 0x009, 0x0F8, 0x00B, 0x0EB, 0x0AF, 0x056,
+       0x076, 0x067, 0x052, 0x0B2, 0x08E, 0x069, 0x0A7, 0x011,
+       0x073, 0x0A8, 0x0B1, 0x0BC, 0x0CA, 0x0A0, 0x0A9, 0x036,
+       0x050, 0x02C, 0x098, 0x0E7, 0x00A, 0x0F5, 0x066, 0x0A4,
+       0x097, 0x0E2, 0x05A, 0x030, 0x027, 0x0BA, 0x0F7, 0x083,
+       0x04E, 0x0A5, 0x033, 0x00A, 0x066, 0x015, 0x08D, 0x0E6,
+       0x055, 0x039, 0x0D2, 0x0A7, 0x0AC, 0x054, 0x060, 0x016,
+       0x070, 0x01B, 0x072, 0x08E, 0x062, 0x08F, 0x022, 0x02E,
+       0x075, 0x016, 0x002, 0x0FB, 0x08D, 0x0E6, 0x00A, 0x095,
+       0x03D, 0x062, 0x0A3, 0x000, 0x0B7, 0x001, 0x0B5, 0x053,
+       0x0DE, 0x02A, 0x054, 0x094, 0x0AD, 0x0D4, 0x033, 0x032,
+       0x0B1, 0x059, 0x047, 0x031, 0x047, 0x091, 0x017, 0x03A,
+       0x088, 0x048, 0x0E7, 0x002, 0x0B0, 0x017, 0x0DC, 0x067,
+       0x09D, 0x04B, 0x08D, 0x0E7, 0x052, 0x0AA, 0x07B, 0x0D4,
+       0x0AA, 0x092, 0x0BD, 0x0D6, 0x099, 0x0BC, 0x056, 0x002,
+       0x0FB, 0x08C, 0x0F3, 0x066, 0x066, 0x0C6, 0x0F3, 0x066,
+       0x066, 0x062, 0x099, 0x02A, 0x0F8, 0x018, 0x068, 0x070,
+       0x0B0, 0x08A, 0x00D, 0x055, 0x055, 0x055, 0x055, 0x052,
+       0x032, 0x0E1, 0x040, 0x05C, 0x038, 0x00B, 0x0EA, 0x09B,
+       0x087, 0x001, 0x07D, 0x0C0, 0x05F, 0x070, 0x017, 0x0DC,
+       0x005, 0x0F5, 0x0DC, 0x09B, 0x001, 0x07D, 0x061, 0x04D,
+       0x080, 0x0BE, 0x0A7, 0x079, 0x082, 0x0A2, 0x01F, 0x050,
+       0x015, 0x02A, 0x08F, 0x08B, 0x01C, 0x0E5, 0x0A5, 0x013,
+       0x084, 0x058, 0x0E7, 0x002, 0x091, 0x054, 0x005, 0x002,
+       0x04B, 0x0BD, 0x022, 0x01A, 0x094, 0x07F, 0x09C, 0x01A,
+       0x0C0, 0x05F, 0x042, 0x01A, 0x021, 0x0D1, 0x080, 0x059,
+       0x0C0, 0x06D, 0x01C, 0x02C, 0x00A, 0x083, 0x055, 0x055,
+       0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055,
+       0x055, 0x054, 0x01C, 0x0B8, 0x05C, 0x06E, 0x017, 0x09C,
+       0x02F, 0x038, 0x05E, 0x070, 0x0E7, 0x0B8, 0x05E, 0x070,
+       0x0BC, 0x0E1, 0x079, 0x0C2, 0x0F3, 0x085, 0x0E7, 0x00B,
+       0x0CE, 0x017, 0x09C, 0x029, 0x09C, 0x029, 0x09C, 0x029,
+       0x09C, 0x023, 0x00F, 0x058, 0x014, 0x0EE, 0x035, 0x077,
+       0x026, 0x021, 0x093, 0x005, 0x0C9, 0x0B0, 0x017, 0x0D2,
+       0x01D, 0x018, 0x08A, 0x021, 0x093, 0x005, 0x0C9, 0x0B0,
+       0x017, 0x0D1, 0x087, 0x0AC, 0x00A, 0x074, 0x00F, 0x0AE,
+       0x0F5, 0x05A, 0x082, 0x0A3, 0x0E4, 0x03A, 0x031, 0x014,
+       0x0BB, 0x0D7, 0x059, 0x099, 0x074, 0x0A2, 0x019, 0x030,
+       0x05C, 0x09B, 0x001, 0x07D, 0x018, 0x07A, 0x0C0, 0x0A7,
+       0x040, 0x0F8, 0x043, 0x0D4, 0x063, 0x089, 0x025, 0x0D0,
+       0x010, 0x0D6, 0x01C, 0x06A, 0x010, 0x0F5, 0x055, 0x089,
+       0x025, 0x0D1, 0x051, 0x066, 0x01F, 0x051, 0x0F5, 0x091,
+       0x049, 0x02E, 0x089, 0x015, 0x098, 0x06A, 0x0A3, 0x0E0,
+       0x08A, 0x094, 0x065, 0x064, 0x00E, 0x013, 0x017, 0x038,
+       0x0A8, 0x086, 0x04C, 0x017, 0x026, 0x0C0, 0x05F, 0x046,
+       0x01E, 0x0B0, 0x028, 0x063, 0x01F, 0x008, 0x07A, 0x08C,
+       0x071, 0x024, 0x0BA, 0x002, 0x01A, 0x0D0, 0x00D, 0x042,
+       0x01E, 0x0AA, 0x0B1, 0x024, 0x0BA, 0x02A, 0x02D, 0x031,
+       0x0F5, 0x01F, 0x058, 0x074, 0x092, 0x0E8, 0x087, 0x05A,
+       0x063, 0x052, 0x0DE, 0x0F4, 0x051, 0x069, 0x04A, 0x03E,
+       0x009, 0x069, 0x046, 0x050, 0x0F0, 0x0E1, 0x031, 0x073,
+       0x005, 0x045, 0x0BD, 0x059, 0x08D, 0x08B, 0x04A, 0x07C,
+       0x0D3, 0x0ED, 0x038, 0x0E9, 0x0D3, 0x04E, 0x074, 0x0ED,
+       0x044, 0x032, 0x060, 0x0B9, 0x036, 0x002, 0x0FA, 0x05B,
+       0x0DE, 0x08A, 0x02D, 0x029, 0x0D0, 0x0E1, 0x021, 0x0F5,
+       0x0A3, 0x092, 0x021, 0x0F2, 0x019, 0x030, 0x05C, 0x09B,
+       0x001, 0x07D, 0x021, 0x0F5, 0x0A0, 0x0C6, 0x001, 0x067,
+       0x001, 0x0B4, 0x045, 0x0CE, 0x0A5, 0x012, 0x039, 0x0D4,
+       0x01C, 0x005, 0x0F4, 0x040, 0x0A1, 0x0C2, 0x0C3, 0x050,
+       0x06A, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA,
+       0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x0AA, 0x081, 0x0AF,
+       0x086, 0x09F, 0x019, 0x01B, 0x0E7, 0x081, 0x0F3, 0x065,
+       0x0F2, 0x080, 0x0BE, 0x070, 0x017, 0x0DF, 0x0DF, 0x038,
+       0x00B, 0x0EB, 0x00D, 0x0C3, 0x080, 0x0BE, 0x0A7, 0x00F,
+       0x095, 0x04F, 0x05A, 0x094, 0x0C0, 0x02C, 0x0D8, 0x0B1,
+       0x0A7, 0x0CE, 0x05A, 0x011, 0x073, 0x0A8, 0x03A, 0x0C2,
+       0x0CC, 0x0B6, 0x030, 0x017, 0x0DC, 0x06F, 0x035, 0x0A9,
+       0x080, 0x04D, 0x0A7, 0x0CE, 0x02A, 0x018, 0x079, 0x0C5,
+       0x049, 0x0DE, 0x061, 0x0A8, 0x022, 0x0E7, 0x050, 0x033,
+       0x0F9, 0x098, 0x064, 0x008, 0x0B9, 0x095, 0x042, 0x0FC,
+       0x0CC, 0x0D9, 0x095, 0x03D, 0x062, 0x0A2, 0x048, 0x0D4,
+       0x048, 0x0E7, 0x002, 0x088, 0x0B9, 0x0C1, 0x0A0, 0x0E3,
+       0x09D, 0x04E, 0x062, 0x0E6, 0x0CC, 0x0C6, 0x06B, 0x0CE,
+       0x083, 0x010, 0x0C9, 0x082, 0x0E4, 0x0DA, 0x0C2, 0x0C8,
+       0x01E, 0x0C3, 0x0B9, 0x036, 0x002, 0x0FA, 0x0A9, 0x0EB,
+       0x04E, 0x030, 0x030, 0x0FA, 0x00D, 0x0F0, 0x0A9, 0x0EB,
+       0x040, 0x0B9, 0x00F, 0x0AA, 0x07A, 0x0D2, 0x0C2, 0x0C8,
+       0x0FA, 0x0A7, 0x0AD, 0x041, 0x00A, 0x047, 0x0D5, 0x03D,
+       0x068, 0x0AC, 0x0F1, 0x0F5, 0x04F, 0x05A, 0x097, 0x054,
+       0x07D, 0x04F, 0x0A8, 0x0AA, 0x055, 0x01F, 0x011, 0x073,
+       0x05A, 0x0B0, 0x017, 0x0DE, 0x05D, 0x059, 0x0A9, 0x025,
+       0x0D0, 0x055, 0x02A, 0x046, 0x0BC, 0x0B8, 0x022, 0x0AE,
+       0x045, 0x029, 0x03E, 0x014, 0x0FA, 0x0E1, 0x099, 0x094,
+       0x0CA, 0x04A, 0x0BE, 0x03D, 0x0D6, 0x099, 0x092, 0x05D,
+       0x015, 0x017, 0x0C8, 0x0D7, 0x0DC, 0x015, 0x017, 0x08A,
+       0x040, 0x01F, 0x00A, 0x09E, 0x0AC, 0x0C9, 0x065, 0x049,
+       0x05C, 0x01D, 0x010, 0x068, 0x04A, 0x03E, 0x05B, 0x0DE,
+       0x083, 0x016, 0x095, 0x080, 0x0BE, 0x091, 0x074, 0x058,
+       0x0A4, 0x000, 0x07C, 0x038, 0x0E7, 0x056, 0x030, 0x017,
+       0x0DF, 0x075, 0x0A6, 0x064, 0x097, 0x045, 0x020, 0x09D,
+       0x003, 0x05F, 0x070, 0x054, 0x05E, 0x029, 0x01D, 0x0F0,
+       0x0A9, 0x0EA, 0x0CC, 0x086, 0x054, 0x095, 0x0C1, 0x0D1,
+       0x006, 0x083, 0x00F, 0x0AA, 0x07B, 0x0D0, 0x065, 0x049,
+       0x045, 0x0BD, 0x0E9, 0x062, 0x0D2, 0x091, 0x0DF, 0x004,
+       0x05D, 0x016, 0x029, 0x01C, 0x07D, 0x04F, 0x0AC, 0x01A,
+       0x047, 0x01A, 0x0A9, 0x0F5, 0x067, 0x066, 0x053, 0x028,
+       0x0B7, 0x0BD, 0x02C, 0x05A, 0x052, 0x03B, 0x0E3, 0x0DD,
+       0x059, 0x0A9, 0x025, 0x0D1, 0x0A8, 0x0AC, 0x008, 0x06B,
+       0x0EE, 0x008, 0x0AB, 0x0C5, 0x020, 0x02F, 0x085, 0x04F,
+       0x056, 0x066, 0x075, 0x049, 0x05C, 0x01C, 0x018, 0x01D,
+       0x081, 0x0C2, 0x064, 0x005, 0x0F0, 0x080, 0x0BE, 0x035,
+       0x05C, 0x0D0, 0x017, 0x0C2, 0x055, 0x0F0, 0x095, 0x07C,
+       0x025, 0x05F, 0x008, 0x00B, 0x0E1, 0x001, 0x07C, 0x07B,
+       0x0AB, 0x035, 0x024, 0x0BA, 0x010, 0x055, 0x093, 0x01A,
+       0x0FB, 0x082, 0x02A, 0x0F1, 0x048, 0x0D7, 0x0C2, 0x0A7,
+       0x0AB, 0x031, 0x0B2, 0x0A4, 0x0AC, 0x063, 0x09D, 0x04A,
+       0x08D, 0x07C, 0x07B, 0x0AB, 0x035, 0x024, 0x0BA, 0x010,
+       0x054, 0x030, 0x08D, 0x07D, 0x0C1, 0x015, 0x078, 0x0AC,
+       0x06F, 0x05A, 0x094, 0x060, 0x01A, 0x0E3, 0x079, 0x0D4,
+       0x0AA, 0x04F, 0x085, 0x04F, 0x056, 0x066, 0x0D5, 0x049,
+       0x058, 0x0C7, 0x03A, 0x095, 0x049, 0x0F0, 0x045, 0x0D1,
+       0x062, 0x094, 0x086, 0x0BC, 0x01D, 0x013, 0x0D2, 0x090,
+       0x0FF, 0x0CF, 0x07A, 0x083, 0x0F2, 0x050, 0x031, 0x0DE,
+       0x000, 0x060, 0x060, 0x0A1, 0x017, 0x035, 0x0A8, 0x05F,
+       0x09B, 0x01B, 0x037, 0x007, 0x044, 0x01A, 0x030, 0x00B,
+       0x038, 0x00D, 0x0BC, 0x01C, 0x0E0, 0x0D0, 0x047, 0x0CE,
+       0x0A0, 0x0AA, 0x07A, 0x0A1, 0x098, 0x06A, 0x092, 0x095,
+       0x03D, 0x068, 0x031, 0x080, 0x05B, 0x080, 0x0DA, 0x0A9,
+       0x0EF, 0x041, 0x095, 0x025, 0x016, 0x0F7, 0x0A5, 0x08B,
+       0x04A, 0x0C6, 0x079, 0x0B3, 0x033, 0x060, 0x02F, 0x0AA,
+       0x09E, 0x0B1, 0x051, 0x080, 0x059, 0x09E, 0x0CA, 0x0A7,
+       0x0AC, 0x00A, 0x030, 0x00B, 0x067, 0x0B2, 0x0AD, 0x0D5,
+       0x0DA, 0x092, 0x05D, 0x017, 0x0A3, 0x000, 0x0B3, 0x02D,
+       0x095, 0x06E, 0x008, 0x0A9, 0x058, 0x0A1, 0x017, 0x03A,
+       0x08B, 0x001, 0x07D, 0x054, 0x0F7, 0x08E, 0x095, 0x025,
+       0x008, 0x01C, 0x0E0, 0x056, 0x002, 0x0FB, 0x0C1, 0x0D1,
+       0x015, 0x018, 0x005, 0x092, 0x06B, 0x03C, 0x01D, 0x012,
+       0x028, 0x0C0, 0x02C, 0x0A5, 0x06C, 0x011, 0x070, 0x017,
+       0x0B2, 0x038, 0x04D, 0x080, 0x0BE, 0x0E0, 0x02F, 0x0B4,
+       0x0EC, 0x04A, 0x0ED, 0x0B3, 0x09E, 0x002, 0x0FB, 0x080,
+       0x0BE, 0x0E0, 0x02F, 0x0B1, 0x039, 0x093, 0x03E, 0x06D,
+       0x0E7, 0x010, 0x060, 0x09F, 0x032, 0x0A9, 0x0A2, 0x06C,
+       0x005, 0x0F4, 0x040, 0x0E6, 0x00A, 0x095, 0x03D, 0x06A,
+       0x023, 0x000, 0x0B3, 0x080, 0x0DA, 0x0A7, 0x0D6, 0x02A,
+       0x003, 0x00D, 0x070, 0x017, 0x0D2, 0x02E, 0x076, 0x029,
+       0x04F, 0x0BC, 0x054, 0x0A6, 0x051, 0x06F, 0x07A, 0x058,
+       0x0B4, 0x0AC, 0x005, 0x0F4, 0x08B, 0x0A2, 0x0F4, 0x00E,
+       0x035, 0x00D, 0x049, 0x02E, 0x0B4, 0x0CC, 0x018, 0x0A5,
+       0x0C8, 0x0F8, 0x04A, 0x097, 0x023, 0x0E1, 0x005, 0x02E,
+       0x047, 0x0C2, 0x08A, 0x05C, 0x08F, 0x085, 0x069, 0x072,
+       0x03E, 0x01F, 0x04A, 0x0C3, 0x055, 0x01F, 0x056, 0x043,
+       0x032, 0x08C, 0x0A3, 0x05E, 0x060, 0x0A8, 0x045, 0x0CE,
+       0x00D, 0x060, 0x02F, 0x0A3, 0x084, 0x09D, 0x0D8, 0x0F0,
+       0x017, 0x0D2, 0x02E, 0x00E, 0x01B, 0x023, 0x084, 0x0D8,
+       0x00B, 0x0EB, 0x089, 0x0F3, 0x080, 0x0BE, 0x0E0, 0x02F,
+       0x0BB, 0x039, 0x085, 0x0DF, 0x022, 0x003, 0x0E7, 0x001,
+       0x07D, 0x0C0, 0x05F, 0x070, 0x017, 0x0D1, 0x017, 0x038,
+       0x014, 0x05B, 0x0D6, 0x0A2, 0x074, 0x00D, 0x04B, 0x07A,
+       0x0B3, 0x031, 0x096, 0x094, 0x06B, 0x0CC, 0x035, 0x023,
+       0x0D7, 0x049, 0x048, 0x015, 0x073, 0x029, 0x00F, 0x05D,
+       0x08A, 0x0C0, 0x05F, 0x04D, 0x079, 0x084, 0x035, 0x080,
+       0x0BE, 0x088, 0x01C, 0x0C3, 0x052, 0x09F, 0x059, 0x068,
+       0x0C0, 0x02C, 0x0E0, 0x036, 0x0AA, 0x07B, 0x0CD, 0x04A,
+       0x092, 0x0BE, 0x0F3, 0x081, 0x04A, 0x07D, 0x05B, 0x059,
+       0x094, 0x0CA, 0x01C, 0x024, 0x0EE, 0x0C7, 0x080, 0x0BE,
+       0x088, 0x01C, 0x0C3, 0x052, 0x09F, 0x059, 0x068, 0x0C0,
+       0x02C, 0x0E0, 0x036, 0x0AA, 0x07B, 0x0CD, 0x04A, 0x092,
+       0x0BE, 0x0F3, 0x081, 0x043, 0x084, 0x09C, 0x07B, 0x038,
+       0x00B, 0x0EB, 0x0AF, 0x070, 0x0D4, 0x0EA, 0x053, 0x000,
+       0x09B, 0x04F, 0x09C, 0x054, 0x030, 0x0F3, 0x08A, 0x094,
+       0x0FA, 0x0B6, 0x0B3, 0x029, 0x094, 0x022, 0x0E6, 0x01A,
+       0x085, 0x0F9, 0x0B0, 0x059, 0x093, 0x0F9, 0x0D2, 0x0C4,
+       0x032, 0x060, 0x0B9, 0x036, 0x0B0, 0x0B3, 0x090, 0x0D9,
+       0x077, 0x026, 0x01C, 0x027, 0x022, 0x0E8, 0x096, 0x0B4,
+       0x023, 0x0EA, 0x09E, 0x0B5, 0x011, 0x080, 0x059, 0x065,
+       0x086, 0x020, 0x073, 0x096, 0x08D, 0x079, 0x0AD, 0x058,
+       0x00B, 0x0E9, 0x017, 0x044, 0x08A, 0x04A, 0x007, 0x0D7,
+       0x07A, 0x082, 0x0A1, 0x090, 0x0FA, 0x0EF, 0x001, 0x054,
+       0x0BA, 0x050, 0x0D4, 0x059, 0x01E, 0x02C, 0x0E9, 0x0F3,
+       0x08A, 0x099, 0x085, 0x06B, 0x00B, 0x023, 0x015, 0x097,
+       0x072, 0x061, 0x017, 0x030, 0x0D4, 0x02C, 0x073, 0x087,
+       0x048, 0x0AA, 0x002, 0x081, 0x025, 0x0DE, 0x091, 0x00D,
+       0x04A, 0x0C0, 0x05F, 0x07E, 0x0D2, 0x080, 0x0A5, 0x03E,
+       0x0B2, 0x0D0, 0x0C8, 0x06B, 0x080, 0x0BE, 0x088, 0x01C,
+       0x0EA, 0x009, 0x017, 0x044, 0x01A, 0x037, 0x01A, 0x091,
+       0x074, 0x058, 0x0A3, 0x071, 0x0AF, 0x007, 0x044, 0x054,
+       0x06E, 0x035, 0x0E0, 0x0E8, 0x0AA, 0x064, 0x00F, 0x090,
+       0x0FA, 0x0D0, 0x063, 0x000, 0x0B3, 0x080, 0x0DA, 0x02C,
+       0x073, 0x087, 0x048, 0x0AA, 0x002, 0x081, 0x025, 0x0DE,
+       0x091, 0x00D, 0x04A, 0x0C0, 0x05F, 0x048, 0x0BA, 0x027,
+       0x0A3, 0x000, 0x0B7, 0x001, 0x0B7, 0x04F, 0x09C, 0x0B4,
+       0x06B, 0x0CC, 0x035, 0x016, 0x0F5, 0x066, 0x063, 0x02D,
+       0x029, 0x01E, 0x0BA, 0x04A, 0x040, 0x0AB, 0x099, 0x048,
+       0x07A, 0x0EC, 0x050, 0x08B, 0x09C, 0x008, 0x022, 0x0FC,
+       0x0F9, 0x0B2, 0x055, 0x03D, 0x062, 0x0A9, 0x023, 0x051,
+       0x023, 0x09C, 0x00A, 0x03C, 0x073, 0x00D, 0x044, 0x05C,
+       0x0E1, 0x050, 0x071, 0x0CE, 0x0A1, 0x01F, 0x0E7, 0x015,
+       0x06B, 0x00B, 0x025, 0x0ED, 0x00B, 0x093, 0x060, 0x02F,
+       0x0AA, 0x09E, 0x0AC, 0x036, 0x065, 0x049, 0x05F, 0x07A,
+       0x020, 0x050, 0x008, 0x07F, 0x0EF, 0x039, 0x014, 0x049,
+       0x001, 0x011, 0x081, 0x004, 0x060, 0x040, 0x0CC, 0x059,
+       0x0C0, 0x0AD, 0x023, 0x0EB, 0x041, 0x0B0, 0x081, 0x0F2,
+       0x03A, 0x041, 0x0AA, 0x050, 0x043, 0x0E4, 0x0D4, 0x086,
+       0x054, 0x0A0, 0x087, 0x0C1, 0x052, 0x0CA, 0x093, 0x001,
+       0x032, 0x054, 0x09D, 0x024, 0x002, 0x000, 0x000, 0x052,
+       0x0AF, 0x016, 0x046, 0x0A7, 0x091, 0x067, 0x008, 0x0B4,
+       0x004, 0x051, 0x0F1, 0x065, 0x019, 0x0B4, 0x06E, 0x02D,
+       0x0C0, 0x0AD, 0x049, 0x000, 0x092, 0x057, 0x01B, 0x074,
+       0x045, 0x05F, 0x023, 0x051, 0x0B7, 0x044, 0x00A, 0x010,
+       0x006, 0x0A3, 0x06E, 0x08B, 0x06B, 0x008, 0x01F, 0x019,
+       0x0D1, 0x0E6, 0x080, 0x082, 0x080, 0x054, 0x004, 0x02A,
+       0x045, 0x091, 0x0A9, 0x0E4, 0x059, 0x0C2, 0x02D, 0x001,
+       0x014, 0x004, 0x050, 0x0D3, 0x0FC, 0x055, 0x084, 0x061,
+       0x0D9, 0x080, 0x051, 0x02F, 0x0E2, 0x01F, 0x046, 0x05F,
+       0x040, 0x0E0, 0x020, 0x015, 0x04A, 0x0BC, 0x059, 0x01A,
+       0x09E, 0x045, 0x09C, 0x022, 0x0D0, 0x011, 0x048, 0x0CB,
+       0x0E8, 0x014, 0x008, 0x001, 0x054, 0x015, 0x0E2, 0x0C8,
+       0x0D4, 0x0F2, 0x02C, 0x0E1, 0x016, 0x080, 0x08A, 0x046,
+       0x05F, 0x052, 0x07C, 0x0D9, 0x0A8, 0x0F8, 0x088, 0x0D0,
+       0x05A, 0x03C, 0x0D2, 0x05C, 0x05B, 0x080, 0x0DA, 0x0A7,
+       0x0D6, 0x05A, 0x008, 0x086, 0x0A4, 0x05D, 0x017, 0x0A0,
+       0x0C3, 0x052, 0x02E, 0x088, 0x0A8, 0x022, 0x01F, 0x053,
+       0x0EA, 0x0DA, 0x0CC, 0x0A6, 0x050, 0x0E1, 0x027, 0x076,
+       0x03C, 0x005, 0x0F5, 0x04F, 0x0AB, 0x06B, 0x032, 0x099,
+       0x043, 0x084, 0x09C, 0x07B, 0x038, 0x00B, 0x0E9, 0x027,
+       0x0AC, 0x0D4, 0x092, 0x0E0, 0x00E, 0x0DA, 0x038, 0x04D,
+       0x080, 0x0BE, 0x0E6, 0x07D, 0x050, 0x0BA, 0x051, 0x0AE,
+       0x066, 0x0EF, 0x0BC, 0x0DC, 0x07B, 0x087, 0x01E, 0x002,
+       0x0FA, 0x093, 0x0E6, 0x0CD, 0x047, 0x0C4, 0x043, 0x0CD,
+       0x00F, 0x034, 0x09D, 0x0A3, 0x000, 0x0B0, 0x055, 0x001,
+       0x0AE, 0x003, 0x084, 0x004, 0x0CE, 0x001, 0x0D0, 0x0E1,
+       0x070, 0x002, 0x080, 0x00E, 0x089, 0x0E9, 0x022, 0x01F,
+       0x0E0, 0x0E8, 0x096, 0x0B0, 0x011, 0x0F4, 0x0C2, 0x0CE,
+       0x003, 0x06A, 0x044, 0x02D, 0x0C0, 0x06D, 0x048, 0x005,
+       0x0B8, 0x00D, 0x0A3, 0x000, 0x0B7, 0x076, 0x0D5, 0x0DE,
+       0x0B1, 0x050, 0x0DC, 0x07D, 0x077, 0x0BC, 0x054, 0x0BA,
+       0x052, 0x07F, 0x058, 0x014, 0x034, 0x00F, 0x09A, 0x0F3,
+       0x081, 0x058, 0x00B, 0x0EA, 0x0EF, 0x058, 0x014, 0x060,
+       0x016, 0x0A5, 0x06C, 0x02E, 0x0F7, 0x081, 0x04B, 0x0A5,
+       0x06F, 0x07D, 0x05D, 0x0EE, 0x0B5, 0x02E, 0x095, 0x080,
+       0x0BE, 0x0F0, 0x073, 0x0BD, 0x004, 0x07C, 0x0EA, 0x0FE,
+       0x0EB, 0x04C, 0x0DE, 0x029, 0x053, 0x0DD, 0x06A, 0x054,
+       0x094, 0x0A9, 0x0EA, 0x00A, 0x08C, 0x002, 0x0D6, 0x04C,
+       0x03C, 0x005, 0x0F4, 0x000, 0x0EA, 0x0CD, 0x056, 0x0AF,
+       0x0C0, 0x047, 0x0D2, 0x09C, 0x08D, 0x029, 0x0CA, 0x0E0,
+       0x02F, 0x0AE, 0x0BD, 0x075, 0x099, 0x09D, 0x04A, 0x0F9,
+       0x0EF, 0x051, 0x07C, 0x094, 0x00C, 0x077, 0x080, 0x018,
+       0x018, 0x029, 0x02A, 0x0F8, 0x0E0, 0x0E8, 0x0AA, 0x030,
+       0x00B, 0x02A, 0x098, 0x07C, 0x01D, 0x011, 0x051, 0x080,
+       0x059, 0x054, 0x0C3, 0x051, 0x0F5, 0x01B, 0x033, 0x024,
+       0x0BB, 0x082, 0x0A5, 0x019, 0x05C, 0x01D, 0x010, 0x028,
+       0x0C0, 0x02C, 0x09A, 0x0C7, 0x0C1, 0x0D1, 0x022, 0x08C,
+       0x002, 0x0C9, 0x094, 0x064, 0x05C, 0x00C, 0x0D6, 0x08E,
+       0x013, 0x060, 0x02F, 0x0B8, 0x00B, 0x0EA, 0x030, 0x0E3,
+       0x0C0, 0x05F, 0x048, 0x0DC, 0x078, 0x00B, 0x0E8, 0x000,
+       0x0E3, 0x0C0, 0x05F, 0x06C, 0x038, 0x0D5, 0x02E, 0x035,
+       0x04F, 0x05A, 0x08A, 0x061, 0x0AA, 0x09F, 0x056, 0x01B,
+       0x032, 0x099, 0x046, 0x042, 0x0C8, 0x001, 0x00C, 0x045,
+       0x0CE, 0x0A5, 0x017, 0x0E6, 0x0C6, 0x0CE, 0x0A9, 0x0EB,
+       0x015, 0x016, 0x046, 0x0A2, 0x047, 0x038, 0x014, 0x043,
+       0x026, 0x022, 0x0E7, 0x03D, 0x060, 0x02F, 0x0AA, 0x09E,
+       0x0B5, 0x012, 0x0E0, 0x07F, 0x001, 0x07D, 0x0E3, 0x0E7,
+       0x002, 0x093, 0x0F9, 0x095, 0x044, 0x05C, 0x0E5, 0x0A0,
+       0x0E3, 0x09D, 0x04A, 0x07F, 0x09C, 0x054, 0x0A9, 0x0EB,
+       0x051, 0x005, 0x046, 0x0B9, 0x0FC, 0x0C0, 0x01B, 0x022,
+       0x02E, 0x064, 0x054, 0x02F, 0x0CD, 0x046, 0x0CC, 0x0A7,
+       0x0D5, 0x086, 0x0CC, 0x0A6, 0x050, 0x055, 0x0C6, 0x045,
+       0x0CE, 0x05A, 0x00E, 0x039, 0x0D4, 0x0A7, 0x0F9, 0x0C5,
+       0x04A, 0x09E, 0x0B5, 0x011, 0x080, 0x059, 0x0C0, 0x06D,
+       0x0CF, 0x0E6, 0x000, 0x0D9, 0x011, 0x073, 0x022, 0x0A1,
+       0x07E, 0x06A, 0x036, 0x065, 0x03E, 0x0AC, 0x036, 0x065,
+       0x032, 0x0B0, 0x017, 0x0DD, 0x03E, 0x072, 0x0D2, 0x079,
+       0x031, 0x00C, 0x098, 0x02E, 0x04C, 0x020, 0x073, 0x02A,
+       0x08F, 0x0F3, 0x08A, 0x0AD, 0x0E7, 0x041, 0x082, 0x07C,
+       0x0CA, 0x0A6, 0x089, 0x0B5, 0x085, 0x09F, 0x0B0, 0x0F0,
+       0x017, 0x0D5, 0x01F, 0x054, 0x054, 0x025, 0x01A, 0x0A8,
+       0x0FF, 0x02A, 0x094, 0x065, 0x011, 0x0D7, 0x049, 0x044,
+       0x0D5, 0x0CC, 0x0A0, 0x055, 0x0D8, 0x0AE, 0x00E, 0x088,
+       0x014, 0x060, 0x016, 0x04D, 0x063, 0x022, 0x0E0, 0x072,
+       0x086, 0x038, 0x04D, 0x080, 0x0BE, 0x0E0, 0x02F, 0x0B8,
+       0x00B, 0x0EE, 0x002, 0x0FB, 0x081, 0x038, 0x0F0, 0x017,
+       0x0D7, 0x0D7, 0x01E, 0x002, 0x0FA, 0x0FA, 0x0E3, 0x0C0,
+       0x05F, 0x04C, 0x085, 0x090, 0x002, 0x018, 0x0C8, 0x05B,
+       0x080, 0x0DA, 0x030, 0x00B, 0x070, 0x01B, 0x04C, 0x022,
+       0x0D3, 0x04C, 0x033, 0x003, 0x08C, 0x02E, 0x04C, 0x043,
+       0x026, 0x0D0, 0x0F5, 0x063, 0x066, 0x0D0, 0x095, 0x0A7,
+       0x0CE, 0x045, 0x033, 0x00A, 0x0D6, 0x016, 0x042, 0x038,
+       0x06E, 0x0E4, 0x0CE, 0x0BD, 0x059, 0x02C, 0x0D2, 0x0AB,
+       0x0BA, 0x094, 0x09D, 0x0E6, 0x01A, 0x0B0, 0x017, 0x0D5,
+       0x04F, 0x05A, 0x08B, 0x009, 0x01A, 0x088, 0x0B9, 0x0C5,
+       0x042, 0x047, 0x030, 0x0D4, 0x032, 0x016, 0x072, 0x088,
+       0x065, 0x0BD, 0x059, 0x099, 0x025, 0x0A5, 0x060, 0x02F,
+       0x0B8, 0x060, 0x0F3, 0x008, 0x0B7, 0x04A, 0x01A, 0x08F,
+       0x0AB, 0x00D, 0x099, 0x046, 0x051, 0x0AF, 0x038, 0x0A8,
+       0x08E, 0x090, 0x065, 0x013, 0x052, 0x018, 0x0A0, 0x054,
+       0x0B1, 0x042, 0x02E, 0x061, 0x0A8, 0x048, 0x0E7, 0x02D,
+       0x016, 0x0F7, 0x0A8, 0x005, 0x0A5, 0x060, 0x02F, 0x0A4,
+       0x075, 0x0D2, 0x051, 0x035, 0x073, 0x028, 0x015, 0x076,
+       0x02B, 0x083, 0x0A2, 0x005, 0x018, 0x005, 0x093, 0x058,
+       0x0C8, 0x0B8, 0x006, 0x028, 0x063, 0x084, 0x0D8, 0x00B,
+       0x0EE, 0x002, 0x0FB, 0x080, 0x0BE, 0x0E0, 0x02F, 0x0A0,
+       0x043, 0x0A7, 0x001, 0x07D, 0x04C, 0x0E3, 0x0C0, 0x05F,
+       0x070, 0x017, 0x0DC, 0x005, 0x0F4, 0x064, 0x02D, 0x0C0,
+       0x06D, 0x018, 0x005, 0x0B8, 0x00D, 0x0A5, 0x0BD, 0x06A,
+       0x023, 0x086, 0x0AA, 0x09E, 0x0B5, 0x011, 0x0A4, 0x06A,
+       0x0A3, 0x0EA, 0x08A, 0x08D, 0x023, 0x0E1, 0x017, 0x038,
+       0x034, 0x069, 0x071, 0x098, 0x045, 0x0A6, 0x098, 0x06A,
+       0x03E, 0x0AC, 0x036, 0x065, 0x019, 0x046, 0x0BC, 0x0E2,
+       0x0A2, 0x03A, 0x041, 0x094, 0x04D, 0x048, 0x062, 0x081,
+       0x052, 0x0C5, 0x016, 0x0F7, 0x0A8, 0x08B, 0x04A, 0x054,
+       0x0F5, 0x0A8, 0x08C, 0x002, 0x0DC, 0x006, 0x0D1, 0x003,
+       0x09C, 0x0B4, 0x0A9, 0x0EE, 0x00A, 0x095, 0x025, 0x02A,
+       0x07A, 0x0AD, 0x046, 0x001, 0x067, 0x001, 0x0B5, 0x0D7,
+       0x0AC, 0x00A, 0x030, 0x00B, 0x06C, 0x049, 0x035, 0x0E6,
+       0x0B5, 0x067, 0x0F3, 0x000, 0x06C, 0x088, 0x0B9, 0x091,
+       0x050, 0x0BF, 0x031, 0x01B, 0x032, 0x0A7, 0x0B8, 0x068,
+       0x095, 0x025, 0x07B, 0x0AD, 0x033, 0x078, 0x0A7, 0x0CD,
+       0x03E, 0x0D3, 0x08E, 0x09D, 0x034, 0x0E7, 0x04E, 0x0D4,
+       0x022, 0x0E7, 0x006, 0x084, 0x08E, 0x060, 0x0A8, 0x0FF,
+       0x038, 0x0AB, 0x083, 0x09C, 0x02A, 0x008, 0x0F9, 0x0D4,
+       0x020, 0x063, 0x0BC, 0x01A, 0x006, 0x00A, 0x0C0, 0x05F,
+       0x046, 0x042, 0x0DC, 0x006, 0x0D1, 0x080, 0x05B, 0x080,
+       0x0DA, 0x022, 0x0E6, 0x01A, 0x084, 0x08E, 0x072, 0x0D1,
+       0x06F, 0x05A, 0x080, 0x087, 0x01A, 0x0AA, 0x07A, 0x0D4,
+       0x048, 0x0C8, 0x0D5, 0x047, 0x0D5, 0x015, 0x023, 0x023,
+       0x0E1, 0x017, 0x038, 0x034, 0x08C, 0x0BA, 0x04B, 0x07B,
+       0x0D4, 0x002, 0x0D2, 0x08C, 0x022, 0x0DC, 0x006, 0x0D5,
+       0x01F, 0x056, 0x01B, 0x032, 0x08C, 0x0A3, 0x05E, 0x071,
+       0x051, 0x01D, 0x020, 0x0CA, 0x026, 0x0A4, 0x031, 0x040,
+       0x0A9, 0x062, 0x0B0, 0x017, 0x0DF, 0x09E, 0x0F4, 0x0B7,
+       0x0C9, 0x040, 0x0C7, 0x078, 0x001, 0x081, 0x082, 0x0B8,
+       0x038, 0x039, 0x049, 0x01C, 0x026, 0x0C0, 0x05F, 0x070,
+       0x017, 0x0D4, 0x0AB, 0x0E1, 0x02A, 0x0F8, 0x04A, 0x0BE,
+       0x012, 0x0AF, 0x08F, 0x097, 0x04F, 0x0CB, 0x0A7, 0x001,
+       0x07D, 0x0DA, 0x080, 0x0AA, 0x091, 0x064, 0x07F, 0x04A,
+       0x081, 0x0D5, 0x022, 0x0C8, 0x0FE, 0x082, 0x080, 0x025,
+       0x048, 0x0B2, 0x03E, 0x0BB, 0x0DC, 0x035, 0x02E, 0x094,
+       0x007, 0x0E8, 0x08A, 0x09C, 0x003, 0x0E2, 0x04B, 0x0A5,
+       0x077, 0x0AB, 0x0B3, 0x032, 0x0E9, 0x04B, 0x0BD, 0x059,
+       0x086, 0x084, 0x097, 0x07A, 0x004, 0x0BA, 0x053, 0x0E1,
+       0x032, 0x0EF, 0x050, 0x0D4, 0x0E6, 0x035, 0x053, 0x0EB,
+       0x002, 0x09C, 0x0C7, 0x0D7, 0x07A, 0x0B3, 0x030, 0x0D2,
+       0x05D, 0x0EA, 0x002, 0x0E9, 0x044, 0x05D, 0x016, 0x028,
+       0x0C0, 0x02C, 0x0E0, 0x036, 0x091, 0x074, 0x045, 0x059,
+       0x018, 0x0D5, 0x04F, 0x0AC, 0x00A, 0x0C4, 0x035, 0x030,
+       0x08B, 0x038, 0x069, 0x02B, 0x0BD, 0x059, 0x098, 0x069,
+       0x02E, 0x0F5, 0x012, 0x0E9, 0x058, 0x067, 0x04A, 0x0EF,
+       0x050, 0x0D5, 0x08E, 0x03E, 0x01C, 0x0A4, 0x0B0, 0x0CE,
+       0x093, 0x021, 0x06E, 0x01A, 0x048, 0x01F, 0x0A2, 0x02A,
+       0x0C3, 0x00D, 0x057, 0x07A, 0x0B3, 0x00D, 0x009, 0x02E,
+       0x0F4, 0x043, 0x05D, 0x028, 0x08B, 0x083, 0x020, 0x092,
+       0x038, 0x04D, 0x080, 0x0BE, 0x0E0, 0x02F, 0x0AC, 0x017,
+       0x049, 0x0B3, 0x0A5, 0x082, 0x0E9, 0x03E, 0x0E9, 0x036,
+       0x074, 0x0E0, 0x02F, 0x0A6, 0x0CE, 0x09C, 0x005, 0x0F4,
+       0x0C2, 0x02C, 0x08C, 0x052, 0x057, 0x07A, 0x0D4, 0x08D,
+       0x048, 0x0FA, 0x0EF, 0x050, 0x0D5, 0x0AE, 0x035, 0x053,
+       0x0EB, 0x002, 0x086, 0x021, 0x0AA, 0x0EF, 0x056, 0x066,
+       0x01A, 0x04B, 0x0BD, 0x044, 0x0BA, 0x050, 0x0C4, 0x0E9,
+       0x053, 0x0EB, 0x002, 0x086, 0x081, 0x0F5, 0x0DE, 0x0A1,
+       0x0A8, 0x062, 0x01F, 0x05D, 0x0FE, 0x0A2, 0x05D, 0x029,
+       0x077, 0x0A8, 0x06A, 0x061, 0x08D, 0x040, 0x0FD, 0x011,
+       0x053, 0x00C, 0x06A, 0x0A7, 0x0D6, 0x005, 0x030, 0x0C7,
+       0x0D7, 0x07F, 0x0A9, 0x057, 0x04A, 0x05D, 0x0EB, 0x048,
+       0x01B, 0x00C, 0x07C, 0x08B, 0x09D, 0x08A, 0x053, 0x0EF,
+       0x066, 0x094, 0x0CA, 0x054, 0x0F5, 0x0A0, 0x0C6, 0x001,
+       0x06E, 0x003, 0x06A, 0x09F, 0x056, 0x076, 0x065, 0x032,
+       0x08B, 0x07B, 0x0D2, 0x0C5, 0x0A5, 0x060, 0x02F, 0x0AA,
+       0x07D, 0x065, 0x0A3, 0x000, 0x0B7, 0x001, 0x0B4, 0x0C8,
+       0x05A, 0x007, 0x08F, 0x0ED, 0x001, 0x0D5, 0x027, 0x091,
+       0x067, 0x001, 0x0B4, 0x08B, 0x09C, 0x054, 0x01C, 0x073,
+       0x0A8, 0x084, 0x05C, 0x0C1, 0x050, 0x0BF, 0x036, 0x056,
+       0x060, 0x0AB, 0x08C, 0x08B, 0x09C, 0x054, 0x01C, 0x073,
+       0x0A8, 0x084, 0x05C, 0x0C1, 0x050, 0x0BF, 0x036, 0x056,
+       0x06C, 0x005, 0x0F5, 0x053, 0x0D6, 0x0A2, 0x030, 0x00B,
+       0x029, 0x05B, 0x019, 0x0FC, 0x0F6, 0x094, 0x045, 0x0CF,
+       0x015, 0x00B, 0x0F3, 0x03C, 0x0B3, 0x02A, 0x07A, 0x0C5,
+       0x046, 0x001, 0x064, 0x08A, 0x031, 0x023, 0x09C, 0x00A,
+       0x05D, 0x0EA, 0x034, 0x033, 0x02E, 0x095, 0x0C7, 0x0CE,
+       0x02A, 0x04F, 0x0E6, 0x050, 0x020, 0x0B9, 0x031, 0x00C,
+       0x09B, 0x0EF, 0x039, 0x014, 0x045, 0x0CE, 0x045, 0x007,
+       0x01C, 0x0EA, 0x046, 0x087, 0x0AB, 0x01B, 0x036, 0x084,
+       0x0A7, 0x05E, 0x0AC, 0x096, 0x067, 0x052, 0x0B0, 0x017,
+       0x0DC, 0x0FE, 0x07B, 0x04A, 0x022, 0x0E7, 0x08A, 0x085,
+       0x0F9, 0x09E, 0x059, 0x097, 0x07A, 0x08D, 0x00C, 0x0CB,
+       0x0A5, 0x027, 0x0F3, 0x0A0, 0x044, 0x032, 0x060, 0x0B9,
+       0x037, 0x0DE, 0x072, 0x028, 0x08B, 0x09C, 0x08A, 0x00E,
+       0x039, 0x0D4, 0x08C, 0x005, 0x0F7, 0x0E7, 0x0B8, 0x02A,
+       0x0F9, 0x028, 0x018, 0x0EF, 0x000, 0x030, 0x030, 0x057,
+       0x007, 0x044, 0x00A, 0x050, 0x08F, 0x0F0, 0x073, 0x091,
+       0x041, 0x01F, 0x03A, 0x090, 0x045, 0x0C0, 0x0BB, 0x018,
+       0x0E1, 0x036, 0x002, 0x0FB, 0x0FB, 0x09E, 0x002, 0x0FA,
+       0x0EE, 0x0E7, 0x0F5, 0x0CF, 0x001, 0x07D, 0x010, 0x05C,
+       0x0F0, 0x017, 0x0D1, 0x005, 0x0CF, 0x001, 0x07D, 0x053,
+       0x0EB, 0x02D, 0x018, 0x005, 0x0B8, 0x00D, 0x0A6, 0x042,
+       0x0DC, 0x006, 0x0D3, 0x017, 0x035, 0x0A8, 0x08B, 0x09C,
+       0x00A, 0x00E, 0x039, 0x0D4, 0x00C, 0x0FE, 0x07B, 0x04A,
+       0x022, 0x0E6, 0x055, 0x00B, 0x0F3, 0x031, 0x0B3, 0x060,
+       0x02F, 0x0BC, 0x07C, 0x0E2, 0x0A4, 0x0FE, 0x065, 0x051,
+       0x017, 0x038, 0x014, 0x01C, 0x073, 0x0A8, 0x019, 0x0FC,
+       0x0F6, 0x094, 0x045, 0x0CC, 0x0AA, 0x017, 0x0E6, 0x063,
+       0x066, 0x00A, 0x0B8, 0x0CC, 0x085, 0x0A1, 0x058, 0x0F6,
+       0x0A2, 0x035, 0x048, 0x048, 0x07F, 0x04A, 0x089, 0x095,
+       0x021, 0x021, 0x0FD, 0x005, 0x002, 0x054, 0x09E, 0x045,
+       0x091, 0x00E, 0x03C, 0x005, 0x0F5, 0x007, 0x040, 0x055,
+       0x048, 0x052, 0x03E, 0x086, 0x0A0, 0x075, 0x048, 0x052,
+       0x03E, 0x0B5, 0x000, 0x04A, 0x09C, 0x000, 0x06B, 0x0C7,
+       0x0CE, 0x045, 0x027, 0x0F3, 0x02A, 0x084, 0x037, 0x035,
+       0x0DE, 0x0A0, 0x0AB, 0x023, 0x01A, 0x0AE, 0x0F5, 0x083,
+       0x059, 0x018, 0x0D7, 0x043, 0x0DE, 0x02A, 0x0D0, 0x094,
+       0x0EB, 0x0DE, 0x005, 0x03A, 0x095, 0x09F, 0x0CC, 0x0C3,
+       0x020, 0x045, 0x0CC, 0x0AA, 0x017, 0x0E6, 0x066, 0x0CC,
+       0x043, 0x026, 0x04F, 0x0E7, 0x041, 0x022, 0x02E, 0x070,
+       0x068, 0x038, 0x0E7, 0x053, 0x0E0, 0x02F, 0x0AB, 0x0BC,
+       0x012, 0x0D2, 0x0E9, 0x058, 0x00B, 0x0EA, 0x0A7, 0x0AD,
+       0x045, 0x0A1, 0x01F, 0x0C0, 0x05F, 0x078, 0x039, 0x0C8,
+       0x0A0, 0x08F, 0x09D, 0x048, 0x01C, 0x024, 0x0EE, 0x0C7,
+       0x080, 0x0BE, 0x0BA, 0x0F5, 0x06D, 0x066, 0x049, 0x077,
+       0x00D, 0x04E, 0x0A5, 0x030, 0x009, 0x0B4, 0x0F9, 0x0C5,
+       0x043, 0x00F, 0x038, 0x0A9, 0x03F, 0x09D, 0x002, 0x0FB,
+       0x0CE, 0x045, 0x011, 0x073, 0x091, 0x041, 0x0C7, 0x03A,
+       0x091, 0x09F, 0x0CF, 0x069, 0x044, 0x05C, 0x0F1, 0x050,
+       0x0BF, 0x033, 0x0CB, 0x032, 0x0A7, 0x0AC, 0x054, 0x090,
+       0x08D, 0x044, 0x08E, 0x070, 0x029, 0x077, 0x0A8, 0x0D0,
+       0x0CC, 0x0BA, 0x056, 0x0B0, 0x0B2, 0x09D, 0x08C, 0x086,
+       0x04C, 0x017, 0x026, 0x077, 0x026, 0x01C, 0x027, 0x01C,
+       0x024, 0x09E, 0x023, 0x061, 0x0BE, 0x08E, 0x012, 0x04F,
+       0x011, 0x087, 0x01C, 0x0EA, 0x05C, 0x005, 0x0F5, 0x0D7,
+       0x0B8, 0x06A, 0x075, 0x029, 0x077, 0x0AB, 0x00D, 0x099,
+       0x074, 0x0A5, 0x04F, 0x072, 0x0A0, 0x0AA, 0x04A, 0x0C6,
+       0x0F3, 0x066, 0x066, 0x0C6, 0x039, 0x082, 0x0AF, 0x075,
+       0x0A6, 0x06F, 0x014, 0x06B, 0x0CE, 0x005, 0x070, 0x073,
+       0x096, 0x082, 0x03E, 0x075, 0x028, 0x0E1, 0x03A, 0x0A7,
+       0x0AD, 0x044, 0x060, 0x016, 0x052, 0x0B6, 0x01D, 0x07A,
+       0x0B6, 0x0B3, 0x024, 0x0BB, 0x086, 0x0A7, 0x052, 0x098,
+       0x004, 0x0DA, 0x07C, 0x0E2, 0x0A1, 0x087, 0x09C, 0x055,
+       0x0F7, 0x09C, 0x0B5, 0x0AC, 0x02C, 0x095, 0x033, 0x0B9,
+       0x031, 0x005, 0x0D9, 0x053, 0x0D6, 0x0A2, 0x030, 0x00B,
+       0x029, 0x05B, 0x002, 0x02E, 0x061, 0x05A, 0x017, 0x0E6,
+       0x09C, 0x0B3, 0x02A, 0x07A, 0x0C5, 0x040, 0x021, 0x0A8,
+       0x091, 0x0CE, 0x005, 0x027, 0x0F3, 0x0A5, 0x088, 0x064,
+       0x0C1, 0x072, 0x065, 0x04F, 0x058, 0x014, 0x00C, 0x08D,
+       0x07E, 0x0F3, 0x081, 0x044, 0x05C, 0x0EF, 0x041, 0x0C7,
+       0x03A, 0x0BE, 0x002, 0x0FA, 0x0A9, 0x0EA, 0x0CE, 0x0CC,
+       0x0A9, 0x029, 0x053, 0x0D6, 0x0A2, 0x046, 0x047, 0x0DD,
+       0x07A, 0x0C0, 0x0A3, 0x000, 0x086, 0x0E2, 0x09B, 0x029,
+       0x078, 0x08B, 0x081, 0x009, 0x098, 0x070, 0x09B, 0x029,
+       0x079, 0x05D, 0x0D9, 0x072, 0x0ED, 0x094, 0x0BC, 0x0B9,
+       0x076, 0x013, 0x03B, 0x02A, 0x05D, 0x0B2, 0x097, 0x095,
+       0x02E, 0x0D9, 0x04B, 0x0CA, 0x07D, 0x05B, 0x059, 0x094,
+       0x0CA, 0x01C, 0x024, 0x0EE, 0x0C7, 0x094, 0x0BC, 0x0C0,
+       0x026, 0x0D3, 0x0E7, 0x015, 0x00C, 0x03C, 0x0E2, 0x0AC,
+       0x0FE, 0x07B, 0x04A, 0x022, 0x0E7, 0x08A, 0x085, 0x0F9,
+       0x09E, 0x059, 0x097, 0x07A, 0x08D, 0x00C, 0x0CB, 0x0A5,
+       0x027, 0x0F3, 0x0A0, 0x041, 0x072, 0x062, 0x019, 0x037,
+       0x0DE, 0x070, 0x028, 0x08B, 0x09C, 0x08A, 0x00E, 0x039,
+       0x0D4, 0x08D, 0x00F, 0x056, 0x036, 0x06D, 0x009, 0x04E,
+       0x0BD, 0x059, 0x02C, 0x0CE, 0x0A5, 0x06B, 0x00B, 0x022,
+       0x0D9, 0x09D, 0x0C9, 0x0B2, 0x097, 0x0BE, 0x0F3, 0x081,
+       0x04A, 0x07D, 0x065, 0x0A3, 0x000, 0x093, 0x08F, 0x067,
+       0x029, 0x078, 0x0C2, 0x04D, 0x0C1, 0x0D1, 0x006, 0x082,
+       0x031, 0x0AF, 0x007, 0x038, 0x034, 0x011, 0x0F3, 0x0A8,
+       0x02A, 0x09E, 0x0A8, 0x066, 0x01A, 0x0A4, 0x0A5, 0x04F,
+       0x05A, 0x00C, 0x011, 0x08F, 0x0AA, 0x07B, 0x0D0, 0x065,
+       0x049, 0x045, 0x0BD, 0x0E9, 0x062, 0x0D2, 0x0B1, 0x09E,
+       0x06C, 0x0CC, 0x0C6, 0x019, 0x087, 0x009, 0x0C3, 0x08E,
+       0x075, 0x041, 0x01F, 0x03A, 0x0A5, 0x013, 0x0D5, 0x055,
+       0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055,
+       0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055,
+       0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055,
+       0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055,
+       0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055, 0x055,
+       0x055, 0x055, 0x055, 0x05A, 0x0CC, 0x090
+ };
+
+#endif /* defined(CONFIG_SMCTR) || defined(CONFIG_SMCTR_MODULE) */
index 1371c31abf82cf883f434637a7a076ea4b4cfd46..13d431b469184509b562655ae9f13c75055f27ed 100644 (file)
@@ -31,7 +31,7 @@
  *     - David Hein at Texas Instruments 
  *
  *  Maintainer(s):
- *    JS       Jay Schulist            jschlst@samba.anu.edu.au
+ *    JS       Jay Schulist            jschlst@turbolinux.com
  *    CG       Christoph Goos          cgoos@syskonnect.de
  *    AF       Adam Fritzler           mid@auk.cx
  *
index bb4d3cf443480f1252eb76795aee2a498313d5c0..96d35c2ba3867a2730bd1c42d421f37cc3ce5a0d 100644 (file)
@@ -157,9 +157,8 @@ static void __init
 pbus_set_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *outer)
 {
        struct pbus_set_ranges_data inner;
-       struct pci_bus *child;
        struct pci_dev *dev;
-       struct list_node *ln;
+       struct list_head *ln;
 
        inner.found_vga = 0;
        inner.mem_start = inner.io_start = ~0UL;
@@ -275,10 +274,10 @@ pbus_set_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *outer)
 void __init
 pci_set_bus_ranges(void)
 {
-       struct list_node *ln;
+       struct list_head *ln;
 
        for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next)
-               pci_set_ranges(pci_bus_b(ln), NULL);
+               pbus_set_ranges(pci_bus_b(ln), NULL);
 }
 
 static void __init
index 4642ff91368989742530d341dcdaeed82c6277ad..622f187cd59951d86c396e7d21f52fc4dcbf592c 100644 (file)
@@ -99,6 +99,11 @@ static int pc_debug = PCMCIA_DEBUG;
 #define PCDATA_CODE_TYPE       0x0014
 #define PCDATA_INDICATOR       0x0015
 
+#ifndef CONFIG_PROC_FS
+#define pci_proc_attach_device(dev)    do { } while (0)
+#define pci_proc_detach_device(dev)    do { } while (0)
+#endif
+
 typedef struct cb_config_t {
        struct pci_dev dev;
 } cb_config_t;
@@ -313,19 +318,11 @@ int cb_alloc(socket_info_t * s)
                                res->start = 0;
                                pci_assign_resource(dev, r);
                        }
-                       printk("Resource %d at %08lx-%08lx (%04lx)\n",
-                              r,
-                              res->start,
-                              res->end,
-                              res->flags);
                }
 
                list_add_tail(&dev->bus_list, &bus->devices);
                list_add_tail(&dev->global_list, &pci_devices);
-#ifdef CONFIG_PROC_FS
                pci_proc_attach_device(dev);
-#endif
-
                pci_enable_device(dev);
        }
 
@@ -350,17 +347,18 @@ void cb_free(socket_info_t * s)
        int i;
 
        if (c) {
+               int i;
+
+               s->cb_config = NULL;
                for(i=0; i<s->functions; i++) {
                        struct pci_dev *dev = &c[i].dev;
+
                        list_del(&dev->bus_list);
                        list_del(&dev->global_list);
                        free_resources(dev);
-#ifdef CONFIG_PROC_FS
                        pci_proc_detach_device(dev);
-#endif
                }
-               kfree(s->cb_config);
-               s->cb_config = NULL;
+               kfree(c);
                printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number);
        }
 }
index 7d883c87a59b3682ec6bc46d4968917e11206884..d44d505ca8924196cbad4e7d03a33f8e9c32c5a6 100644 (file)
@@ -446,7 +446,6 @@ static void shutdown_socket(u_long i)
     s->state &= SOCKET_PRESENT|SOCKET_SETUP_PENDING;
     init_socket(s);
     s->irq.AssignedIRQ = s->irq.Config = 0;
-    s->functions = 0;
     s->lock_count = 0;
     s->cis_used = 0;
     if (s->fake_cis) {
@@ -457,6 +456,7 @@ static void shutdown_socket(u_long i)
     cb_release_cis_mem(s);
     cb_free(s);
 #endif
+    s->functions = 0;
     if (s->config) {
        kfree(s->config);
        s->config = NULL;
index f12b5686d1d53c8524044c53f69e2fc8f2c372a5..9a8ad136cc4d66edd54a0969ed94901c1e4188f7 100644 (file)
@@ -19,10 +19,10 @@ MI_OBJS  :=
 MIX_OBJS :=
 
 ifeq ($(CONFIG_ISAPNP),y)
-  LX_OBJS += isapnp.o
+  LX_OBJS += isapnp.o quirks.o
 else
   ifeq ($(CONFIG_ISAPNP),m)
-    MX_OBJS += isapnp.o
+    MX_OBJS += isapnp.o quirks.o
   endif
 endif
 
index 5d99f4c992368681e354e5dfe2f8c198f4438902..38bd430767322f1afeae0df3baff895357e285be 100644 (file)
@@ -17,6 +17,9 @@
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
+ *  Changelog:
+ *  2000-01-01 Added ISAPnP quirks handling
+ *             Peter Denison <peterd@pnd-pc.demon.co.uk>
  */
 
 #include <linux/config.h>
@@ -184,7 +187,7 @@ void isapnp_write_dword(unsigned char idx, unsigned int val)
        isapnp_write_byte(idx+3, val);
 }
 
-static void *isapnp_alloc(long size)
+void *isapnp_alloc(long size)
 {
        void *result;
 
@@ -964,6 +967,7 @@ static int __init isapnp_build_device_list(void)
        int csn;
        unsigned char header[9], checksum;
        struct pci_bus *card;
+       struct pci_dev *dev;
 
        isapnp_wait();
        isapnp_key();
@@ -993,6 +997,9 @@ static int __init isapnp_build_device_list(void)
 
                list_add_tail(&card->node, &isapnp_cards);
        }
+       for (dev = isapnp_devices; dev ; dev = dev->next) {
+               isapnp_fixup_device(dev);
+       }
        return 0;
 }
 
index 0f0eb6a39a516a4419029ec906e418f5752c9485..81c4df548f940cf1bbc77dd99234f2274baac081 100644 (file)
@@ -19,7 +19,8 @@
  *
  */
 
-static void *isapnp_alloc(long size);
+struct pci_bus *isapnp_cards;
+struct pci_dev *isapnp_devices;
 
 struct isapnp_info_buffer {
        char *buffer;           /* pointer to begin of buffer */
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
new file mode 100644 (file)
index 0000000..028eda7
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  This file contains quirk handling code for ISAPnP devices
+ *  Some devices do not report all their resources, and need to have extra
+ *  resources added. This is most easily accomplished at initialisation time
+ *  when building up the resource structure for the first time.
+ *
+ *  Copyright (c) 2000 Peter Denison <peterd@pnd-pc.demon.co.uk>
+ *
+ *  Heavily based on PCI quirks handling which is
+ *
+ *  Copyright (c) 1999 Martin Mares <mj@suse.cz>
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/isapnp.h>
+
+static void __init quirk_awe32_resources(struct pci_dev *dev)
+{
+       struct isapnp_port *port, *port2, *port3;
+       struct isapnp_resources *res = dev->sysdata;
+
+       /*
+        * Unfortunately the isapnp_add_port_resource is too tightly bound
+        * into the PnP discovery sequence, and cannot be used. Link in the
+        * two extra ports (at offset 0x400 and 0x800 from the one given) by
+        * hand.
+        */
+       for ( ; res ; res = res->alt ) {
+               port2 = isapnp_alloc(sizeof(struct isapnp_port));
+               port3 = isapnp_alloc(sizeof(struct isapnp_port));
+               if (!port2 || !port3)
+                       return;
+               port = res->port;
+               memcpy(port2, port, sizeof(struct isapnp_port));
+               memcpy(port3, port, sizeof(struct isapnp_port));
+               port->next = port2;
+               port2->next = port3;
+               port2->min += 0x400;
+               port2->max += 0x400;
+               port3->min += 0x800;
+               port3->max += 0x800;
+       }
+       printk(KERN_INFO "ISAPnP: AWE32 quirk - adding two ports\n");
+}
+
+
+/*
+ *  ISAPnP Quirks
+ *  Cards or devices that need some tweaking due to broken hardware
+ */
+
+static struct isapnp_fixup isapnp_fixups[] __initdata = {
+       { ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0021),
+               quirk_awe32_resources },
+       { 0 }
+};
+
+void isapnp_fixup_device(struct pci_dev *dev)
+{
+       int i = 0;
+
+       while (isapnp_fixups[i].vendor != 0) {
+               if ((isapnp_fixups[i].vendor == dev->vendor) &&
+                   (isapnp_fixups[i].device == dev->device)) {
+                       printk(KERN_DEBUG "PnP: Calling quirk for %s\n",
+                              dev->slot_name);
+                       isapnp_fixups[i].quirk_function(dev);
+               }
+               i++;
+       }
+}
+
index 999abb5d7ae84d5725a35f6b69892913c9a301a0..50ba920b93c955945983426764964da68d17211b 100644 (file)
@@ -25,7 +25,7 @@ endif
 export-objs    :=  ad1848.o audio_syms.o midi_syms.o mpu401.o \
                    msnd.o opl3.o sb_card.o sequencer_syms.o \
                    sound_core.o sound_syms.o uart401.o ad1816.o \
-                   nm256_audio.o
+                   nm256_audio.o ac97.o
 
 
 
@@ -53,7 +53,7 @@ obj-$(CONFIG_SOUND_CS4232)    += cs4232.o ad1848.o
 obj-$(CONFIG_SOUND_CS4232)     += uart401.o
 obj-$(CONFIG_SOUND_GUS)                += gus.o ad1848.o
 obj-$(CONFIG_SOUND_MAD16)      += mad16.o ad1848.o sb.o uart401.o
-obj-$(CONFIG_SOUND_VIA82CXXX)  += via82cxxx.o sb.o uart401.o
+obj-$(CONFIG_SOUND_VIA82CXXX)  += via82cxxx.o sb.o uart401.o ac97.o
 obj-$(CONFIG_SOUND_MAUI)       += maui.o mpu401.o
 obj-$(CONFIG_SOUND_MPU401)     += mpu401.o
 obj-$(CONFIG_SOUND_MSNDCLAS)   += msnd.o msnd_classic.o
index b54e62f769547d04639a38c9e7c5fdbdc0dd8922..babf98b21307dafd44c78787ae4f67bda870052b 100644 (file)
@@ -1,3 +1,6 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
 #include "ac97.h"
 
 /* Flag for mono controls. */
@@ -434,6 +437,14 @@ ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd, caddr_t arg)
        return put_user(ret, (int *) arg);
 }
 
+EXPORT_SYMBOL(ac97_init);
+EXPORT_SYMBOL(ac97_set_values);
+EXPORT_SYMBOL(ac97_set_mixer);
+EXPORT_SYMBOL(ac97_get_register);
+EXPORT_SYMBOL(ac97_put_register);
+EXPORT_SYMBOL(ac97_get_mixer_scaled);
+EXPORT_SYMBOL(ac97_mixer_ioctl);
+EXPORT_SYMBOL(ac97_reset);
 \f
 /*
  * Local variables:
index 4c817739d23b2b95cc1560f31394948ac13de7f2..5394e0e1cc1e531342453142044fe53d5a2ffc3d 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/config.h>
+#define __NO_VERSION__
 #include <linux/pci.h>
 #include <linux/module.h>
 #ifdef CONFIG_APM
index f91d3dcdfd39a73399c32aee58efd81c26139d4b..84d35b444ca43019b80b55b787293e51f56f94c9 100644 (file)
@@ -460,7 +460,7 @@ static int sb201_audio_set_speed(int dev, int speed)
                        speed = 44100;
                if (devc->opened & OPEN_READ && speed > 15000)
                        speed = 15000;
-               devc->tconst = ((65536 - ((256000000 + s / 2) / s)) >> 8) & 0xff;
+               devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff;
                tmp = 256 - devc->tconst;
                speed = ((1000000 + tmp / 2) / tmp) / devc->channels;
 
@@ -591,7 +591,7 @@ static int jazz16_audio_set_speed(int dev, int speed)
                if (speed > 44100)
                        speed = 44100;
 
-               devc->tconst = ((65536 - ((256000000 + s / 2) / s)) >> 8) & 0xff;
+               devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff;
 
                tmp = 256 - devc->tconst;
                speed = ((1000000 + tmp / 2) / tmp) / devc->channels;
index 5afbf1e3e3070c9554cfa72b8c51ead604fae1c2..106ff23e17f6de61cff9bf45794f2fe55c2f3306 100644 (file)
@@ -145,11 +145,6 @@ int pas2 = 0;              /* Set pas2=1 to load this as support for pas2 */
 int support = 0;       /* Set support to load this as a support module */
 int sm_games = 0;      /* Mixer - see sb_mixer.c */
 int acer = 0;          /* Do acer notebook init */
-#ifdef CONFIG_ISAPNP
-int isapnp = 1;
-#else
-int isapnp = 0;
-#endif
 
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
@@ -163,9 +158,6 @@ MODULE_PARM(trix, "i");
 MODULE_PARM(pas2, "i");
 MODULE_PARM(sm_games, "i");
 MODULE_PARM(esstype, "i");
-#ifdef CONFIG_ISAPNP
-MODULE_PARM(isapnp, "i");
-#endif
 
 void *smw_free = NULL;
 
@@ -233,12 +225,7 @@ int init_module(void)
        if (mad16 == 0 && trix == 0 && pas2 == 0 && support == 0)
        {
 #ifdef CONFIG_ISAPNP                   
-               if (isapnp == 1 && sb_probe_isapnp(&config, &config_mpu)<0)
-               {
-                       printk(KERN_ERR "sb_card: No ISAPnP cards found\n");
-                       return -EINVAL;
-               }
-               else
+               if (sb_probe_isapnp(&config, &config_mpu)<0)
                {
 #endif                 
                        if (io == -1 || dma == -1 || irq == -1)
@@ -251,6 +238,9 @@ int init_module(void)
                        config.dma = dma;
                        config.dma2 = dma16;
                        config.card_subtype = type;
+#ifdef CONFIG_MIDI
+                       config_mpu.io_base = mpu_io;
+#endif
 #ifdef CONFIG_ISAPNP
                }
 #endif
@@ -261,8 +251,6 @@ int init_module(void)
                if(config.slots[0]==-1)
                        return -ENODEV;
 #ifdef CONFIG_MIDI
-               if (isapnp == 0) 
-                       config_mpu.io_base = mpu_io;
                if (probe_sbmpu(&config_mpu))
                        sbmpu = 1;
                if (sbmpu)
index af0c1c9dff16cf4d5a951d8927929717bf17fd9a..e012280730da602c15b924de1f891c7870775ecc 100644 (file)
@@ -29,6 +29,8 @@
  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *  History
+ *  v0.04 Dec 31 1999 Ollie Lho
+ *     Multiple Open, useing Middle Loop Interrupt to smooth playback
  *  v0.03 Dec 24 1999 Ollie Lho
  *     mem leak in prog_dmabuf and dealloc_dmabuf removed
  *  v0.02 Dec 15 1999 Ollie Lho
 #include "trident.h"
 #include "ac97.h"
 
-/* --------------------------------------------------------------------- */
-
 #undef DEBUG
 
-/* --------------------------------------------------------------------- */
 #define DRIVER_VERSION "0.03"
 
-#define TRIDENT_FMT_STEREO     0x01
-#define TRIDENT_FMT_16BIT      0x02
-#define TRIDENT_FMT_MASK       0x03
-#define TRIDENT_DAC_SHIFT      0   
-#define TRIDENT_ADC_SHIFT      4
-
-#define TRIDENT_ENABLE_PE              1
-#define TRIDENT_ENABLE_RE              2
-#define DAC_RUNNING            1
-#define ADC_RUNNING            2
+#define TRIDENT_FMT_STEREO     0x01
+#define TRIDENT_FMT_16BIT      0x02
+#define TRIDENT_FMT_MASK       0x03
+#define TRIDENT_DAC_SHIFT      0   
+#define TRIDENT_ADC_SHIFT      4
 
+#define TRIDENT_ENABLE_PE      1
+#define TRIDENT_ENABLE_RE      2
+#define DAC_RUNNING            1
+#define ADC_RUNNING            2
 
 #define TRIDENT_CARD_MAGIC     0x5072696E /* "Prin" */
 #define TRIDENT_STATE_MAGIC    0x63657373 /* "cess" */
 
-
-#define NR_DSPS                8
+/* number of instances of opening /dev/dsp, can your CPU handle this ? */
+#define NR_DSPS                32
 
 #define SND_DEV_DSP16  5 
 
 static const unsigned sample_size[] = { 1, 2, 2, 4 };
 static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+static const char *sample_format[] = {"8 bits Mono", "8 bits Stereo", "16 bits Mono", "16 bits Stereo"};
 static const char invalid_magic[] = KERN_CRIT "trident: invalid magic value in %s\n";
 
 struct pci_audio_info {
@@ -143,29 +142,34 @@ typedef struct tChannelControl
 
 } CHANNELCONTROL;
 
-/* --------------------------------------------------------------------- */
-
+/* "software" or virtual channel, an instance of opened /dev/dsp */
 struct trident_state {
        unsigned int magic;
-       int channel;
        struct trident_card *card;      /* Card info */
+
        /* wave stuff */
        unsigned int rateadc, ratedac;
        unsigned char fmt, enable;
 
+       /* single opne lock mechanism, should be removed */
        struct semaphore open_sem;
-       mode_t open_mode;
        wait_queue_head_t open_wait;
 
-       /* soundcore stuff */
-       int dev_audio;
+       /* file mode */
+       mode_t open_mode;
+
+       /* virtual channel number */
+       int virt;
 
        struct dmabuf {
                void *rawbuf;
                unsigned buforder;
                unsigned numfrag;
                unsigned fragshift;
-               int chan[2];    /* Hardware channel */
+
+               /* hardware channel number */
+               int chan;
+
                /* XXX zab - swptr only in here so that it can be referenced by
                   clear_advance, as far as I can tell :( */
                unsigned hwptr, swptr;
@@ -173,6 +177,7 @@ struct trident_state {
                int count;
                unsigned error; /* over/underrun */
                wait_queue_head_t wait;
+
                /* redundant, but makes calculations easier */
                unsigned fragsize;
                unsigned dmasize;
@@ -184,13 +189,22 @@ struct trident_state {
                unsigned ossfragshift;
                int ossmaxfrags;
                unsigned subdivision;
-               u16 base;               /* Offset for ptr */
        } dma_dac, dma_adc;
-       
+
        u8 bDMAStart;
 
 };
 
+/* hardware channels */
+struct trident_channel {
+       int chan; /* channel number */
+       u32 lba;
+       u32 eso;
+       u32 delta;
+       u16 attribute;
+       
+};
+
 struct trident_pcm_bank {
        /* registers to control bank operations */
        u32 start;
@@ -207,6 +221,7 @@ struct trident_mixer {
        int supported_mixers;
        int stereo_mixers;
        int record_sources;
+
        /* the caller must guarantee arg sanity before calling these */
        /* int (*read_mixer)(struct trident_card *card, int index);*/
        void (*write_mixer)(struct trident_card *card,int mixer, unsigned int left,
@@ -225,32 +240,26 @@ struct trident_card {
           so we use a single per card lock */     
        spinlock_t lock;
 
+       /* PCI device stuff */
        struct pci_audio_info *pci_info;
        struct pci_dev * pci_dev;
        u16 pci_id;
 
-       /* as most of this is static,
-          perhaps it should be a pointer to a global struct */
+       /* soundcore stuff */
+       int dev_audio;
        int dev_mixer;
-       struct mixer_goo {
-               int modcnt;
-               int supported_mixers;
-               int stereo_mixers;
-               int record_sources;
-               /* the caller must guarantee arg sanity before calling these */
-               /* int (*read_mixer)(struct trident_card *card, int index);*/
-               void (*write_mixer)(struct trident_card *card,int mixer, unsigned int left,unsigned int right);
-               int (*recmask_io)(struct trident_card *card,int rw,int mask);
-               unsigned int mixer_state[SOUND_MIXER_NRDEVICES];
-       } mix;
-       
-       struct trident_state channels[NR_DSPS];
+
+       struct trident_mixer mix;
+       struct trident_state *channels[NR_DSPS];
 
        /* hardware resources */
        unsigned long iobase;
        u32 irq;
 
+       /* hardware channel allocation bitmap */
        u32 bitmap[2];
+
+       /* ugly stupid thing, remove ASAP */
        CHANNELCONTROL ChRegs;
        int ChanDwordCount;
 };
@@ -303,53 +312,53 @@ static void ResetAinten(struct trident_card * trident, int ChannelNum)
 
 static int trident_enable_end_interrupts(struct trident_card * trident)
 {
-       u32 GlobalControl;
+       u32 global_control;
 
-       GlobalControl = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
+       global_control = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
 
        switch (trident->pci_id)
        {
        case PCI_DEVICE_ID_SI_7018:
-               GlobalControl |= (ENDLP_IE | BANK_B_EN);
+               global_control |= (ENDLP_IE | BANK_B_EN);
                break;
        case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
        case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
-               GlobalControl |= ENDLP_IE;
+               global_control |= ENDLP_IE;
                break;
        default:
                return FALSE;
        }
 
-       outl(GlobalControl, TRID_REG(trident, T4D_LFO_GC_CIR));
+       outl(global_control, TRID_REG(trident, T4D_LFO_GC_CIR));
 
 #ifdef DEBUG
-       printk("trident: Enable End Interrupts, globctl = 0x%08X\n", GlobalControl);
+       printk("trident: Enable End Interrupts, globctl = 0x%08X\n", global_control);
 #endif
        return (TRUE);
 }
 
 static int trident_enable_middle_interrupts(struct trident_card * trident)
 {
-       u32 GlobalControl;
+       u32 global_control;
 
-       GlobalControl = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
+       global_control = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
 
        switch (trident->pci_id)
        {
        case PCI_DEVICE_ID_SI_7018:
-               GlobalControl |= (MIDLP_IE | BANK_B_EN);
+               global_control |= (MIDLP_IE | BANK_B_EN);
                break;
        case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
        case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
        default:
-               GlobalControl |= MIDLP_IE;
+               global_control |= MIDLP_IE;
                break;
        }
 
-       outl(GlobalControl, TRID_REG(trident, T4D_LFO_GC_CIR));
+       outl(global_control, TRID_REG(trident, T4D_LFO_GC_CIR));
 
 #ifdef DEBUG
-       printk("trident: Enable Middle Interrupts, globctl = 0x%08X\n", GlobalControl);
+       printk("trident: Enable Middle Interrupts, globctl = 0x%08X\n", global_control);
 #endif
        return (TRUE);
 }
@@ -369,28 +378,28 @@ static int trident_enable_middle_interrupts(struct trident_card * trident)
 
 static int trident_disable_end_interrupts(struct trident_card * trident)
 {
-       u32 GlobalControl;
+       u32 global_control;
 
-       GlobalControl = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
-       GlobalControl &= ~ENDLP_IE;
-       outl(GlobalControl, TRID_REG(trident, T4D_LFO_GC_CIR));
+       global_control = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
+       global_control &= ~ENDLP_IE;
+       outl(global_control, TRID_REG(trident, T4D_LFO_GC_CIR));
 
 #ifdef DEBUG
-       printk("trident: Disabled End Interrupts, globctl = 0x%08X\n", GlobalControl);
+       printk("trident: Disabled End Interrupts, globctl = 0x%08X\n", global_control);
 #endif
        return (TRUE);
 }
 
 static int trident_disable_middle_interrupts(struct trident_card * trident)
 {
-       u32 GlobalControl;
+       u32 global_control;
 
-       GlobalControl = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
-       GlobalControl &= ~MIDLP_IE;
-       outl(GlobalControl, TRID_REG(trident, T4D_LFO_GC_CIR));
+       global_control = inl(TRID_REG(trident, T4D_LFO_GC_CIR));
+       global_control &= ~MIDLP_IE;
+       outl(global_control, TRID_REG(trident, T4D_LFO_GC_CIR));
 
 #ifdef DEBUG
-       printk("trident: Disabled Middle Interrupts, globctl = 0x%08X\n", GlobalControl);
+       printk("trident: Disabled Middle Interrupts, globctl = 0x%08X\n", global_control);
 #endif
        return (TRUE);
 }
@@ -475,7 +484,7 @@ static int trident_alloc_pcm_channel(struct trident_card *trident)
        int idx;
 
        if (trident->bitmap[BANK_B] == ~0UL) {
-               /* not more free channels avaliable */
+               /* no more free channels avaliable */
                printk(KERN_ERR "trident: no more channels available on Bank B.\n");
                return -1;
        }
@@ -490,7 +499,7 @@ static int trident_alloc_pcm_channel(struct trident_card *trident)
        /* channels in Bank A should be reserved for synthesizer 
           not for normal use (channels in Bank A can't record) */
        if (trident->bitmap[BANK_A] == ~0UL) {
-               /* not more free channels avaliable */
+               /* no more free channels avaliable */
                printk(KERN_ERR "trident: no channels available on Bank A.\n");
                return -1;
        }
@@ -800,7 +809,7 @@ static unsigned int trident_set_dac_rate(struct trident_state * trident,
        trident->ratedac = rate;
 
        if (set)
-               trident_load_hw_delta(trident->card, trident->dma_dac.chan[1],
+               trident_load_hw_delta(trident->card, trident->dma_dac.chan,
                                      delta);
 #ifdef DEBUG    
        printk("trident: called trident_set_dac_rate : rate = %d, "
@@ -838,7 +847,7 @@ static unsigned int trident_set_adc_rate(struct trident_state * trident,
 
 #if 0 /* It seems that 4D-Wave can not use wave tables channels for recording */
        if (set)
-               trident_load_hw_delta(trident->card, trident->dma_dac.chan[0],
+               trident_load_hw_delta(trident->card, trident->dma_adc.chan,
                                      delta);
 #endif
 #ifdef DEBUG    
@@ -1109,7 +1118,6 @@ static void ac97_write_mixer(struct trident_card *card, int mixer,
 #ifdef DEBUG
        printk(" 0x%04x", val);
 #endif
-
        trident_ac97_set(card, mh->offset, val);
 
 #ifdef DEBUG
@@ -1237,12 +1245,12 @@ static u16 trident_ac97_init(struct trident_card *trident)
        return 0;
 }
 
-/* this only fixes the output apu mode to be later set by start_dac and
-   company.  output apu modes are set in trident_rec_setup */
+/* this function only update fmt field in trident_state, the hardware channel attribute
+   will be update in trident_play(rec)_setup() which will be called every time a new
+   sample is played(recorded) */
 static void set_fmt(struct trident_state *s, unsigned char mask, unsigned char data)
 {
        s->fmt = (s->fmt & mask) | data;
-       /* Set the chip ? */
 }
 
 /* the mode passed should be already shifted and masked */
@@ -1276,13 +1284,17 @@ static void trident_play_setup(struct trident_state *trident, int mode, u32 rate
                ESO /= 2;
        ESO = ESO - 1;
 
+       /* loop mode enable */
        CTRL = 0x00000001;
        if (mode & TRIDENT_FMT_16BIT) {
-               CTRL |= 0x00000008;     // 16-bit data
-               CTRL |= 0x00000002;     // signed data
+               /* 16-bits */
+               CTRL |= 0x00000008;
+               /* signed */
+               CTRL |= 0x00000002;
        }
        if (mode & TRIDENT_FMT_STEREO)
-               CTRL |= 0x00000004;     // stereo data
+               /* stereo */
+               CTRL |= 0x00000004;
        
        /* FIXME: some difference between 4D and 7018 in FMC_RVOL_CVOL */
        /* right vol: mute, ledt vol: mute */
@@ -1293,7 +1305,7 @@ static void trident_play_setup(struct trident_state *trident, int mode, u32 rate
        EC = 0;
 
        trident_write_voice_regs(trident->card,
-                                trident->dma_dac.chan[1],
+                                trident->dma_dac.chan,
                                 LBA,
                                 0,     /* cso */
                                 ESO,
@@ -1314,7 +1326,8 @@ static void trident_play_setup(struct trident_state *trident, int mode, u32 rate
 /* FIXME: Not exammed yet */
 /* again, passed mode is alrady shifted/masked */
 
-static void trident_rec_setup(struct trident_state *trident, int mode, u32 rate, void *buffer, int size)
+static void trident_rec_setup(struct trident_state *trident, int mode, u32 rate,
+                             void *buffer, int size)
 {
        unsigned int LBA;
        unsigned int Delta;
@@ -1432,7 +1445,7 @@ static void trident_rec_setup(struct trident_state *trident, int mode, u32 rate,
        EC = 0;
 
        trident_write_voice_regs(card,
-                            trident->dma_adc.chan[0],
+                            trident->dma_adc.chan,
                             LBA,
                             0, /* cso */
                             ESO,
@@ -1457,7 +1470,7 @@ __inline__ unsigned int get_dmaa(struct trident_state *trident)
        if (!(trident->enable & ADC_RUNNING))
                return 0;
 #endif
-       outb(trident->dma_dac.chan[1], TRID_REG(trident->card, T4D_LFO_GC_CIR));
+       outb(trident->dma_dac.chan, TRID_REG(trident->card, T4D_LFO_GC_CIR));
 
        switch (trident->card->pci_id) 
        {
@@ -1477,9 +1490,9 @@ __inline__ unsigned int get_dmaa(struct trident_state *trident)
        }
 
 #ifdef DEBUG
-       printk("trident: get_dmaa: chip reported esc = %d, cso = %d\n", cso, eso);
+       printk("trident: get_dmaa: chip reported channel: %d, cso = %d, eso = %d\n",
+              trident->dma_dac.chan, cso, eso);
 #endif
-       cso++;
        /* ESO and CSO are in units of Samples, convert to byte offset */
        if (cso > eso)
                cso = eso;
@@ -1496,10 +1509,10 @@ extern __inline__ unsigned get_dmac(struct trident_state *trident)
        u32 cso;
 #if 0
        /* FIXME: does this mean that FULL duplex is not supported ? */
-       if (!(trident->enable&DAC_RUNNING))
+       if (!(trident->enable & DAC_RUNNING))
                return 0;
 #endif
-       outb(trident->dma_adc.chan[0], TRID_REG(trident->card, T4D_LFO_GC_CIR));
+       outb(trident->dma_adc.chan, TRID_REG(trident->card, T4D_LFO_GC_CIR));
 
        switch (trident->card->pci_id) 
        {
@@ -1518,7 +1531,6 @@ extern __inline__ unsigned get_dmac(struct trident_state *trident)
 #ifdef DEBUG
        printk("(trident) get_dmac: chip reported cso = %d\n", cso);
 #endif
-       cso++;
        /* ESO and CSO are in units of Samples, convert to byte offset */
        if (trident->fmt & TRIDENT_FMT_16BIT)
                cso *= 2;
@@ -1535,11 +1547,11 @@ extern inline void __stop_adc(struct trident_state *s)
        printk("(trident) stopping ADC\n");
 #endif
        s->enable &= ~ADC_RUNNING;
-       trident_disable_voice_irq(trident, s->dma_adc.chan[0]);
+       trident_disable_voice_irq(trident, s->dma_adc.chan);
        outb(0x00, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));
-       trident_disable_voice_irq(trident, s->dma_adc.chan[0]);
-       trident_stop_voice(trident, s->dma_adc.chan[0]);
-       ResetAinten(trident, s->dma_adc.chan[0]);
+       trident_disable_voice_irq(trident, s->dma_adc.chan);
+       trident_stop_voice(trident, s->dma_adc.chan);
+       ResetAinten(trident, s->dma_adc.chan);
 }      
 
 extern inline void stop_adc(struct trident_state *s)
@@ -1553,47 +1565,36 @@ extern inline void stop_adc(struct trident_state *s)
 }      
 
 /* stop playback (lock held) */
-
-extern inline void __stop_dac(struct trident_state *s)
+extern inline void __stop_dac(struct trident_state *state)
 {
-       struct trident_card *trident = s->card;
-#ifdef DEBUG
-       printk("(trident) stopping DAC\n");
-#endif 
-       //trident_stop_voice(trident, s->dma_dac.chan[0]);
-       //trident_disable_voice_irq(trident, s->dma_dac.chan[0]);
-       trident_stop_voice(trident, s->dma_dac.chan[1]);
-       trident_disable_voice_irq(trident, s->dma_dac.chan[1]);
-       s->enable &= ~DAC_RUNNING;
+       struct trident_card *trident = state->card;
+       trident_stop_voice(trident, state->dma_dac.chan);
+       trident_disable_voice_irq(trident, state->dma_dac.chan);
+       state->enable &= ~DAC_RUNNING;
 }      
 
-extern inline void stop_dac(struct trident_state *s)
+extern inline void stop_dac(struct trident_state *state)
 {
-       struct trident_card *trident = s->card;
+       struct trident_card *trident = state->card;
        unsigned long flags;
 
        spin_lock_irqsave(&trident->lock, flags);
-       __stop_dac(s);
+       __stop_dac(state);
        spin_unlock_irqrestore(&trident->lock, flags);
 }      
 
-static void start_dac(struct trident_state *s)
+static void start_dac(struct trident_state *state)
 {
        unsigned long flags;
-       struct trident_card *trident = s->card;
+       struct trident_card *trident = state->card;
 
-       spin_lock_irqsave(&s->card->lock, flags);
-       if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) 
-       {
-               s->enable |= DAC_RUNNING;
-               trident_enable_voice_irq(trident, s->dma_dac.chan[1]);
-               trident_start_voice(trident, s->dma_dac.chan[1]);
-               //trident_start_voice(trident, s->dma_dac.chan[0]);
-#ifdef DEBUG
-               printk("(trident) starting DAC\n");
-#endif
+       spin_lock_irqsave(&state->card->lock, flags);
+       if ((state->dma_dac.mapped || state->dma_dac.count > 0) && state->dma_dac.ready) {
+               state->enable |= DAC_RUNNING;
+               trident_enable_voice_irq(trident, state->dma_dac.chan);
+               trident_start_voice(trident, state->dma_dac.chan);
        }
-       spin_unlock_irqrestore(&s->card->lock, flags);
+       spin_unlock_irqrestore(&state->card->lock, flags);
 }      
 
 static void start_adc(struct trident_state *s)
@@ -1604,9 +1605,9 @@ static void start_adc(struct trident_state *s)
        if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
            && s->dma_adc.ready) {
                s->enable |= ADC_RUNNING;
-               trident_enable_voice_irq(s->card, s->dma_adc.chan[0]);
+               trident_enable_voice_irq(s->card, s->dma_adc.chan);
                outb(s->bDMAStart, TRID_REG(s->card, T4D_SBCTRL_SBE2R_SBDD));
-               trident_start_voice(s->card, s->dma_adc.chan[0]);
+               trident_start_voice(s->card, s->dma_adc.chan);
 #ifdef DEBUG
                printk("(trident) starting ADC\n");
 #endif 
@@ -1615,7 +1616,7 @@ static void start_adc(struct trident_state *s)
 }      
 
 #define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
-#define DMABUF_MINORDER 2
+#define DMABUF_MINORDER 1
 
 /* allocate DMA buffer, playback and recording buffer should be allocated seperately */
 static int alloc_dmabuf(struct trident_state *state, unsigned rec)
@@ -1626,10 +1627,14 @@ static int alloc_dmabuf(struct trident_state *state, unsigned rec)
 
        /* alloc as big a chunk as we can, FIXME: is this necessary ?? */
        for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-               if ((rawbuf = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, order)))
+               if ((rawbuf = (void *)__get_free_pages(GFP_KERNEL, order)))
                        break;
        if (!rawbuf)
                return -ENOMEM;
+#ifdef DEBUG
+       printk("trident: allocated %ld (%d) bytes at %p\n",
+              PAGE_SIZE << order, order, rawbuf);
+#endif
 
        /* for 4DWave and 7018, there are only 30 (31) siginifcan bits for Loop Begin Address
           (LBA) which limits the address space to 1 (2) GB, bad T^2 design */
@@ -1744,10 +1749,15 @@ static int prog_dmabuf(struct trident_state *state, unsigned rec)
        /* set the ready flag for the dma buffer */
        db->ready = 1;
 
+#ifdef DEBUG
+       printk("trident: prog_dmabuf, sample rate = %d, format = %d, numfrag = %d, "
+              "fragsize = %d dmasize = %d\n",
+              rate, fmt, db->numfrag, db->fragsize, db->dmasize);
+#endif
+
        return 0;
 }
 
-/* only called by trident_write */
 extern __inline__ void clear_advance(struct trident_state *s)
 {
        unsigned char c = ((s->fmt >> TRIDENT_DAC_SHIFT) & TRIDENT_FMT_16BIT) ? 0 : 0x80;
@@ -1775,7 +1785,8 @@ static void trident_update_ptr(struct trident_state *s)
        /* update ADC pointer */
        if (s->dma_adc.ready) {
                hwptr = get_dmac(s) % s->dma_adc.dmasize;
-               diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
+               diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % 
+                       s->dma_adc.dmasize;
                s->dma_adc.hwptr = hwptr;
                s->dma_adc.total_bytes += diff;
                s->dma_adc.count += diff;
@@ -1791,30 +1802,20 @@ static void trident_update_ptr(struct trident_state *s)
        }
 
        /* update DAC pointer */
-       if (s->dma_dac.ready) 
-       {
-               /* this is so gross.  */
-               hwptr = (/*s->dma_dac.dmasize -*/ get_dmaa(s)) % s->dma_dac.dmasize; 
-               diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-#ifdef DEBUG
-               printk("(trident) updating dac: hwptr: %d diff: %d\n",hwptr,diff);
-#endif
+       if (s->dma_dac.ready) {
+               hwptr = get_dmaa(s) % s->dma_dac.dmasize; 
+               diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % 
+                       s->dma_dac.dmasize;
                s->dma_dac.hwptr = hwptr;
                s->dma_dac.total_bytes += diff;
-               if (s->dma_dac.mapped) 
-               {
+               if (s->dma_dac.mapped) {
                        s->dma_dac.count += diff;
                        if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
                                wake_up(&s->dma_dac.wait);
                } 
-               else 
-               {
+               else {
                        s->dma_dac.count -= diff;
-#ifdef DEBUG
-                       printk("(trident) trident_update_ptr: diff: %d, count: %d\n", diff, s->dma_dac.count); 
-#endif
-                       if (s->dma_dac.count <= 0) 
-                       {
+                       if (s->dma_dac.count <= 0) {
                                s->enable &= ~TRIDENT_ENABLE_PE;
                                /* Lock already held */
                                __stop_dac(s);
@@ -1825,8 +1826,7 @@ static void trident_update_ptr(struct trident_state *s)
                                s->dma_dac.error++;
                        } 
                        else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && 
-                                       !s->dma_dac.endcleared) 
-                       {
+                                !s->dma_dac.endcleared) {
                                clear_advance(s);
                                s->dma_dac.endcleared = 1;
                        }
@@ -1856,13 +1856,12 @@ static void trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        if (event & ADDRESS_IRQ) {
                /* Update the pointers for all channels we are running. */
-               /* the index variable i is the main bug make the original driver crash,
-                  the code mix "software" channel with "hardware" channel */
+               /* FIXME: improve interrupt latency !!! */
                for (i = 0; i < NR_DSPS; i++) {
-                       state = &card->channels[i];
+                       state = card->channels[i];
                        if (trident_check_channel_interrupt(card, 63 - i)) {
                                trident_ack_channel_interrupt(card, 63 - i);
-                               if (state->dev_audio != -1)
+                               if (state != NULL)
                                        trident_update_ptr(state);
                                else {
                                        /* Spurious ? */
@@ -2040,7 +2039,6 @@ static int trident_ioctl_mixdev(struct inode *inode, struct file *file, unsigned
        struct trident_card *card = (struct trident_card *)file->private_data;
 
        VALIDATE_CARD(card);
-
        return mixer_ioctl(card, cmd, arg);
 }
 
@@ -2080,9 +2078,9 @@ static int drain_dac(struct trident_state *s, int nonblock)
 
        if (s->dma_dac.mapped || !s->dma_dac.ready)
                return 0;
+
        current->state = TASK_INTERRUPTIBLE;
        add_wait_queue(&s->dma_dac.wait, &wait);
-
        for (;;) {
                spin_lock_irqsave(&s->card->lock, flags);
                count = s->dma_dac.count;
@@ -2107,12 +2105,15 @@ static int drain_dac(struct trident_state *s, int nonblock)
                   or schedule_timeout is broken.
                   or something.  who cares. - zach */
                if (!schedule_timeout(tmo ? tmo : 1) && tmo)
-                       printk(KERN_ERR "trident: dma timed out?? %ld\n", jiffies);
+                       printk(KERN_ERR "trident: drain_dac, "
+                              "dma timed out? jiffies = %ld\n",
+                              jiffies);
        }
        remove_wait_queue(&s->dma_dac.wait, &wait);
        current->state = TASK_RUNNING;
        if (signal_pending(current))
                return -ERESTARTSYS;
+
        return 0;
 }
 
@@ -2168,8 +2169,6 @@ static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_
                                stop_adc(state);
 
                                spin_lock_irqsave(&state->card->lock, flags);
-                               /*set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), 
-                                 s->dma_adc.numfrag << s->dma_adc.fragshift); */
                                state->dma_adc.count = 0;
                                state->dma_adc.hwptr = 0;
                                state->dma_adc.swptr = 0;
@@ -2211,7 +2210,7 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count
        int mode = (state->fmt >> TRIDENT_DAC_SHIFT) & TRIDENT_FMT_MASK;
 
 #ifdef DEBUG
-       printk("(trident) trident_write: count %d\n", count);
+       printk("trident: trident_write called, count = %d\n", count);
 #endif 
 
        VALIDATE_STATE(state);
@@ -2247,7 +2246,7 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count
                                return ret;
                        }
                        if (!interruptible_sleep_on_timeout(&state->dma_dac.wait, HZ)) {
-                               printk(KERN_DEBUG 
+                               printk(KERN_ERR 
                                       "trident: write: chip lockup? "
                                       "dmasz %u fragsz %u count %i "
                                       "hwptr %u swptr %u\n", 
@@ -2258,8 +2257,6 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count
                                       state->dma_dac.swptr);
                                stop_dac(state);
                                spin_lock_irqsave(&state->card->lock, flags);
-                               /* set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), 
-                                  s->dma_dac.numfrag << s->dma_dac.fragshift); */
                                state->dma_dac.count = 0;
                                state->dma_dac.hwptr = 0;
                                state->dma_dac.swptr = 0;
@@ -2304,8 +2301,10 @@ static unsigned int trident_poll(struct file *file, struct poll_table_struct *wa
                poll_wait(file, &s->dma_dac.wait, wait);
        if (file->f_mode & FMODE_READ)
                poll_wait(file, &s->dma_adc.wait, wait);
+
        spin_lock_irqsave(&s->card->lock, flags);
        trident_update_ptr(s);
+
        if (file->f_mode & FMODE_READ) {
                if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
                        mask |= POLLIN | POLLRDNORM;
@@ -2367,6 +2366,10 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
        VALIDATE_STATE(s);
        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
                ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+#ifdef DEBUG
+       printk("trident: trident_ioctl, command = %2d, arg = 0x%08x\n",_IOC_NR(cmd), 
+              arg ? *(int *)arg : 0);
+#endif
 
        switch (cmd) 
        {
@@ -2674,61 +2677,73 @@ static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cm
 
 static int trident_open(struct inode *inode, struct file *file)
 {
+       int i = 0;
        int minor = MINOR(inode->i_rdev);
        struct trident_card *card = devs;
-       struct trident_state *state = NULL, *sp;
-       int i;
+       struct trident_state *state = NULL;
        unsigned char fmtm = ~0, fmts = 0;
 
-       /* Scan the cards and find the channel. 
-          We only do this at open time so it is ok */
+       /* find an avaiable virtual channel (instance of /dev/dsp) */
        while (card != NULL) {
                for (i = 0; i < NR_DSPS; i++) {
-                       sp = &card->channels[i];
-                       if (sp->dev_audio < 0)
-                               continue;
-                       if ((sp->dev_audio ^ minor) & ~0xf)
-                               continue;
-                       state = sp;
+                       if (card->channels[i] == NULL) {
+                               state = card->channels[i] = (struct trident_state *)
+                                       kmalloc(sizeof(struct trident_state), GFP_KERNEL);
+                               if (state == NULL)
+                                       return -ENOMEM;
+                               memset(state, 0, sizeof(struct trident_state));
+                               goto found_virt;
+                       }
                }
                card = card->next;
        }
-
+       /* no more virtual channel avaiable */
        if (!state)
                return -ENODEV;
 
-       VALIDATE_STATE(state);
+ found_virt:
+       /* found a free virtual channel, allocate hardware channels */
+       if (file->f_mode & FMODE_READ)
+               if ((state->dma_adc.chan = trident_alloc_pcm_channel(card)) == -1) {
+                       kfree (card->channels[i]);
+                       card->channels[i] = NULL;;
+                       return -ENODEV;
+               }
+       if (file->f_mode & FMODE_WRITE)
+               if ((state->dma_dac.chan = trident_alloc_pcm_channel(card)) == -1) {
+                       kfree (card->channels[i]);
+                       card->channels[i] = NULL;
+                       if (file->f_mode & FMODE_READ)
+                               /* free previously allocated hardware channel */
+                               trident_free_pcm_channel(card, state->dma_adc.chan);
+                       return -ENODEV;
+               }
+
+       /* initialize the virtual channel */
+       state->virt = i;
+       state->card = card;
+       state->magic = TRIDENT_STATE_MAGIC;
+       init_waitqueue_head(&state->dma_adc.wait);
+       init_waitqueue_head(&state->dma_dac.wait);
+       init_MUTEX(&state->open_sem);
        file->private_data = state;
 
        down(&state->open_sem);
 
-       while (state->open_mode & file->f_mode) {
-               /* the channel has been open for the same mode before */
-               if (file->f_flags & O_NONBLOCK) {
-                       /* Non-blocking mode, return immediately */
-                       up(&state->open_sem);
-                       return -EWOULDBLOCK;
-               }
-               up(&state->open_sem);
-               /* blocking, wait for device to become free */
-               interruptible_sleep_on(&state->open_wait);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               down(&state->open_sem);
-       }
-
+       /* set default sample format, Refer to  OSS Programmer's Guide */
        if (file->f_mode & FMODE_READ) {
                /* fmtm &= ~((TRIDENT_FMT_STEREO | TRIDENT_FMT_16BIT) << TRIDENT_ADC_SHIFT);
                if ((minor & 0xf) == SND_DEV_DSP16)
                        fmts |= TRIDENT_FMT_16BIT << TRIDENT_ADC_SHIFT; */
-
                fmtm = (TRIDENT_FMT_STEREO|TRIDENT_FMT_16BIT) << TRIDENT_ADC_SHIFT;
-
                state->dma_adc.ossfragshift = 0;
                state->dma_adc.ossmaxfrags  = 0;
                state->dma_adc.subdivision  = 0;
                trident_set_adc_rate(state, 8000, 0);
        }
+
+       /* according to OSS document, /dev/dsp should be default to unsigned 8-bits, 
+          mono, with sample rate 8kHz and /dev/dspW will accept 16-bits sample */
        if (file->f_mode & FMODE_WRITE) {
                fmtm &= ~((TRIDENT_FMT_STEREO | TRIDENT_FMT_16BIT) << TRIDENT_DAC_SHIFT);
                if ((minor & 0xf) == SND_DEV_DSP16)
@@ -2756,27 +2771,31 @@ static int trident_release(struct inode *inode, struct file *file)
        if (file->f_mode & FMODE_WRITE)
                drain_dac(state, file->f_flags & O_NONBLOCK);
 
-       /* stop DMA state machine and free DMA buffers */
+       /* stop DMA state machine and free DMA buffers/channels */
        down(&state->open_sem);
+
        if (file->f_mode & FMODE_WRITE) {
                stop_dac(state);
                dealloc_dmabuf(&state->dma_dac);
+               trident_free_pcm_channel(state->card, state->dma_dac.chan);
        }
        if (file->f_mode & FMODE_READ) {
                stop_adc(state);
                dealloc_dmabuf(&state->dma_adc);
+               trident_free_pcm_channel(state->card, state->dma_adc.chan);
        }
+
+       kfree(state->card->channels[state->virt]);
+       state->card->channels[state->virt] = NULL;
        state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
+
        /* we're covered by the open_sem */
        up(&state->open_sem);
 
-       wake_up(&state->open_wait);
-
        //FIXME put back in
        //MOD_DEC_USE_COUNT;
        return 0;
 }
-
 static /*const*/ struct file_operations trident_audio_fops = {
        &trident_llseek,
        &trident_read,
@@ -2795,83 +2814,54 @@ static /*const*/ struct file_operations trident_audio_fops = {
        NULL,   /* lock */
 };
 
-#ifdef CONFIG_APM
-int trident_apm_callback(apm_event_t ae) {
-       return 0;
-}
-#endif
-
-/* --------------------------------------------------------------------- */
-
+/* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered 
+   untill open time */
 static int trident_install(struct pci_dev *pcidev, struct pci_audio_info *pci_info)
 {
+       int i;
        u16 w;
        unsigned long iobase;
-       int i;
        struct trident_card *card;
-       struct trident_state *trident;
-       int num = 0;
-       u32 ChanDwordCount;
-       
+       u32 ChanDwordCount;
+
        iobase = pcidev->resource[0].start;
-       
-       if(check_region(iobase, 256)) {
-               printk(KERN_WARNING "trident: can't allocate I/O space at 0x%4.4lx\n",
+       if (check_region(iobase, 256)) {
+               printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n",
                       iobase);
                return 0;
        }
 
-       /* this was tripping up some machines */
-       if (pcidev->irq == 0) {
-               printk(KERN_WARNING "trident: pci subsystem reports irq 0,"
-                      " this might not be correct.\n");
-       }
-
-       /* just to be sure */
-       pci_set_master(pcidev);
-       
+       /* just to be sure that IO space and bus master is on */
+       pci_set_master(pcidev); 
        pci_read_config_word(pcidev, PCI_COMMAND, &w);
-       if((w&(PCI_COMMAND_IO|PCI_COMMAND_MASTER)) != (PCI_COMMAND_IO|PCI_COMMAND_MASTER))
-       {
-               printk(KERN_WARNING "trident: BIOS did not enable I/O access.\n");
-               w|=PCI_COMMAND_IO|PCI_COMMAND_MASTER;
-               pci_write_config_word(pcidev, PCI_COMMAND, w);
-       }
-       
-       card = kmalloc(sizeof(struct trident_card), GFP_KERNEL);
+       w |= PCI_COMMAND_IO|PCI_COMMAND_MASTER;
+       pci_write_config_word(pcidev, PCI_COMMAND, w);
 
-       if (card == NULL) {
-               printk(KERN_WARNING "trident: out of memory\n");
+       if ((card = kmalloc(sizeof(struct trident_card), GFP_KERNEL)) == NULL) {
+               printk(KERN_ERR "trident: out of memory\n");
                return 0;
        }
-       
        memset(card, 0, sizeof(*card));
 
-#ifdef CONFIG_APM
-       printk("trident: apm_reg_callback: %d\n",
-              apm_register_callback(trident_apm_callback));
-#endif
-
        card->iobase = iobase;
        card->pci_info = pci_info;
        card->pci_id = pci_info->device;
        card->irq = pcidev->irq;
        card->next = devs;
        card->magic = TRIDENT_CARD_MAGIC;
+       spin_lock_init(&card->lock);
        devs = card;
 
+       /* ungly stupid thing, remove ASAP */
        ChanDwordCount = card->ChanDwordCount = 2;
-
        card->ChRegs.lpChStart = card->ChRegs.data;
        card->ChRegs.lpChStop = card->ChRegs.lpChStart + ChanDwordCount;
        card->ChRegs.lpChAint = card->ChRegs.lpChStop + ChanDwordCount;
        card->ChRegs.lpChAinten = card->ChRegs.lpChAint + ChanDwordCount;
-
        card->ChRegs.lpAChStart = card->ChRegs.lpChAinten + ChanDwordCount;
        card->ChRegs.lpAChStop = card->ChRegs.lpAChStart + ChanDwordCount;
        card->ChRegs.lpAChAint = card->ChRegs.lpAChStop + ChanDwordCount;
        card->ChRegs.lpAChAinten = card->ChRegs.lpAChAint + ChanDwordCount;
-
        // Assign Bank A addresses.
        card->ChRegs.lpAChStart[0] = T4D_START_A;
        card->ChRegs.lpAChStop[0] = T4D_STOP_A;
@@ -2883,68 +2873,43 @@ static int trident_install(struct pci_dev *pcidev, struct pci_audio_info *pci_in
        card->ChRegs.lpAChAint[1] = T4D_AINT_B;
        card->ChRegs.lpAChAinten[1] = T4D_AINTEN_B;
 
-       outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL));
-       
-
-       spin_lock_init(&card->lock);
-       
-       for (i = 0; i < NR_DSPS; i++) {
-               struct trident_state *s=&card->channels[i];
-
-               s->card = card;
-               init_waitqueue_head(&s->dma_adc.wait);
-               init_waitqueue_head(&s->dma_dac.wait);
-               init_waitqueue_head(&s->open_wait);
-               init_MUTEX(&s->open_sem);
-               s->magic = TRIDENT_STATE_MAGIC;
-               s->channel = i;
-
-               if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf)
-                       printk(KERN_ERR "trident: BOTCH!\n");
-
-               /*
-                *      Now allocate the hardware resources
-                */
-
-               //s->dma_dac.chan[0] = AllocateChannelPCM(card);
-               //s->dma_adc.chan[0] = AllocateChannelPCM(card);
-               s->dma_dac.chan[1] = trident_alloc_pcm_channel(card);
-               /* register devices */
-               if ((s->dev_audio = register_sound_dsp(&trident_audio_fops, -1)) < 0)
-                       break;
-       }
-
-       num = i;
-
-       /* clear the rest if we ran out of slots to register */
-       for (;i < NR_DSPS; i++){
-               struct trident_state *s=&card->channels[i];
-               s->dev_audio = -1;
-       }
-
-       trident = &card->channels[0];
-
-       /*
-        *      Ok card ready. Begin setup proper
-        */
 
-       printk(KERN_INFO "trident: %s found at IO 0x%04lx, IRQ %d\n", 
+       printk(KERN_INFO "trident: %s found at IO 0x%04lx, IRQ %d\n",
               card->pci_info->name, card->iobase, card->irq);
 
+       /* claim our iospace and irq */
+       request_region(card->iobase, 256, card->pci_info->name);
+       if (request_irq(card->irq, &trident_interrupt, SA_SHIRQ, card->pci_info->name, card)) {
+               printk(KERN_ERR "trident: unable to allocate irq %d\n", card->irq);
+               release_region(card->iobase, 256);
+               kfree(card);
+               return 0;
+       }
 
-       /* stake our claim on the iospace */
-       request_region(iobase, 256, card->pci_info->name);
-
+       /* initilize AC97 codec */
        trident_ac97_init(card);
+       outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL));
 
+       /* register /dev/dsp */
+       if ((card->dev_audio = register_sound_dsp(&trident_audio_fops, -1)) < 0) {
+               printk(KERN_ERR "trident: coundn't register DSP device!\n");
+               release_region(iobase, 256);
+               free_irq(card->irq, card);
+               kfree(card);
+               return 0;
+       }
+       /* register /dev/mixer */
        if ((card->dev_mixer = register_sound_mixer(&trident_mixer_fops, -1)) < 0) {
                printk(KERN_ERR "trident: couldn't register mixer!\n");
-       } 
-       else {
-               int i;
-               for (i = 0 ; i < SOUND_MIXER_NRDEVICES ; i++) {
+               unregister_sound_dsp(card->dev_audio);
+               release_region(iobase, 256);
+               free_irq(card->irq, card);
+               kfree(card);
+               return 0;
+       } else {
+               /* initilize mixer channels */
+               for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
                        struct mixer_defaults *md = &mixer_defaults[i];
-
                        if (md->mixer == -1) 
                                break;
                        if (!supported_mixer(card, md->mixer)) 
@@ -2953,24 +2918,13 @@ static int trident_install(struct pci_dev *pcidev, struct pci_audio_info *pci_in
                }
        }
 
-       if (request_irq(card->irq, &trident_interrupt, SA_SHIRQ, card->pci_info->name, card)) {
-               printk(KERN_ERR "trident: unable to allocate irq %d,\n", card->irq);
-               unregister_sound_mixer(card->dev_mixer);
-               for (i = 0; i < NR_DSPS; i++) {
-                       struct trident_state *s = &card->channels[i];
-                       if(s->dev_audio != -1)
-                               unregister_sound_dsp(s->dev_audio);
-               }
-               release_region(card->iobase, 256);
-               kfree(card);
-               return 0;
-       }
-
+       /* Enable Address Engine Interrupts */
        trident_enable_end_interrupts(card);
+       trident_enable_middle_interrupts(card);
+
        return 1; 
 }
 
-
 #ifdef MODULE
 int init_module(void)
 #else
@@ -3001,40 +2955,33 @@ int __init init_trident(void)
        return 0;
 }
 
-/* --------------------------------------------------------------------- */
-
 #ifdef MODULE
-
 MODULE_AUTHOR("Alan Cox <alan@redhat.com>");
 MODULE_DESCRIPTION("Trident 4DWave/SiS 7018 PCI Audio Driver");
+
 #ifdef DEBUG
 MODULE_PARM(debug,"i");
 #endif
 
 void cleanup_module(void)
 {
-#ifdef CONFIG_APM
-       apm_unregister_callback(trident_apm_callback);
-#endif
-
        while (devs != NULL) {
-               int i;
-
                /* Kill interrupts, and SP/DIF */
                trident_disable_end_interrupts(devs);
+               trident_enable_middle_interrupts(devs);
+
+               /* free hardware resources */
                free_irq(devs->irq, devs);
-               unregister_sound_mixer(devs->dev_mixer);
-               for (i = 0; i < NR_DSPS; i++) {
-                       struct trident_state *trident = &devs->channels[i];
-                       if (trident->dev_audio != -1)
-                               unregister_sound_dsp(trident->dev_audio);
-               }
                release_region(devs->iobase, 256);
+
+               /* unregister audio devices */
+               unregister_sound_mixer(devs->dev_mixer);
+               unregister_sound_dsp(devs->dev_audio);
+
                kfree(devs);
                devs = devs->next;
        }
 }
-
 #endif /* MODULE */
 
 
index f283793d100425174b60b7eeeda4821f6ac88a1e..a22e60650d47f4e0e7172ab1770d2c240afbfbf6 100644 (file)
 #define DX_AC97_BUSY_WRITE 0x8000
 #define NX_AC97_BUSY_WRITE 0x0800
 #define SI_AC97_BUSY_READ  0x8000
-#define DX_AC97_BUSY_READ 0x8000
-#define NX_AC97_BUSY_READ 0x0800
+#define DX_AC97_BUSY_READ  0x8000
+#define NX_AC97_BUSY_READ  0x0800
 #define AC97_REG_ADDR      0x000000ff
-#define DX_AC97_REG_ADDR   0x000000ff
-#define NX_AC97_REG_ADDR   0x000000ff
+
+enum serial_intf_ctrl_bits {
+       WARM_REST   = 0x00000001, COLD_RESET  = 0x00000002,
+       I2S_CLOCK   = 0x00000004, PCM_SEC_AC97= 0x00000008,
+       AC97_DBL_RATE = 0x00000010, SPDIF_EN  = 0x00000020,
+       I2S_OUTPUT_EN = 0x00000040, I2S_INPUT_EN = 0x00000080,
+       PCMIN       = 0x00000100, LINE1IN     = 0x00000200,
+       MICIN       = 0x00000400, LINE2IN     = 0x00000800,
+};
 
 enum global_control_bits {
-       CHANNLE_IDX = 0x0000003f, PB_RESET   = 0x00000100,
+       CHANNLE_IDX = 0x0000003f, PB_RESET    = 0x00000100,
        PAUSE_ENG   = 0x00000200,
        OVERRUN_IE  = 0x00000400, UNDERRUN_IE = 0x00000800,
-       ENDLP_IE    = 0x00001000, MIDLP_IE   = 0x00002000,
+       ENDLP_IE    = 0x00001000, MIDLP_IE    = 0x00002000,
        ETOG_IE     = 0x00004000,
-       EDROP_IE    = 0x00008000, BANK_B_EN  = 0x00010000
+       EDROP_IE    = 0x00008000, BANK_B_EN   = 0x00010000
 };
 
 enum miscint_bits {
index 79d87e2e00cf85807943c96a5596e63bccf1600a..cf0fce7c36a2085b3515f83fb02a4892cc1b6c2e 100644 (file)
 /*
  * Support for VIA 82Cxxx Audio Codecs
- * Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
+ * Copyright 1999,2000 Jeff Garzik <jgarzik@mandrakesoft.com>
  *
  * Distributed under the GNU GENERAL PUBLIC LICENSE (GPL) Version 2.
  * See the "COPYING" file distributed with this software for more info.
  *
- ********************************************************************
- *
- * TODO:
- *
- *     - Integrate AC'97 support, when AC'97 interface released
+ * Documentation for this driver available as
+ * linux/Documentation/sound/via82cxxx.txt.
  *
+ * Since the mixer is called from the OSS glue the kernel lock is always held
+ * on our AC97 mixing
  */
  
+
+#define VIA_VERSION    "1.1.2"
+
+
+
 #include <linux/module.h>
+#include <linux/config.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/proc_fs.h>
 
 #include <asm/io.h>
 
 #include "sound_config.h"
 #include "soundmodule.h"
 #include "sb.h"
+#include "ac97.h"
 
 #ifndef SOUND_LOCK
 #define SOUND_LOCK do {} while (0)
 #define SOUND_LOCK_END do {} while (0)
 #endif
 
+#define VIA_DEBUG 0    /* define to 1 to enable debugging output and checks */
+#if VIA_DEBUG
+/* note: prints function name for you */
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define VIA_NDEBUG 0   /* define to 1 to disable lightweight runtime checks */
+#if VIA_NDEBUG
+#define assert(expr)
+#else
+#define assert(expr) \
+        if(!(expr)) {                                  \
+        printk( "Assertion failed! %s,%s,%s,line=%d\n",        \
+        #expr,__FILE__,__FUNCTION__,__LINE__);         \
+        }
+#endif
+
+#define arraysize(x)            (sizeof(x)/sizeof(*(x)))
+
 #define MAX_CARDS      2
 
-#define PFX            "via82cxxx: "
+#define        LINE_SIZE       10
 
-#define VIA_VERSION    "1.0.0"
 #define VIA_CARD_NAME  "VIA 82Cxxx Audio driver " VIA_VERSION
+#define VIA_MODULE_NAME "via82cxxx"
+#define PFX            VIA_MODULE_NAME ": "
+
+#define VIA_COUNTER_LIMIT      100000
 
+/* 82C686 function 5 (audio codec) PCI configuration registers */
 #define VIA_FUNC_ENABLE                0x42
 #define VIA_PNP_CONTROL                0x43
+#define VIA_AC97_CTRL          0x80
+
+/* PCI configuration register bits and masks */
+#define VIA_CR40_AC97_READY    0x01
+#define VIA_CR40_AC97_LOW_POWER        0x02
+#define VIA_CR40_SECONDARY_READY 0x04
+
+#define VIA_CR41_ACLINK_ENABLE 0x80
 
 #define VIA_CR42_SB_ENABLE     0x01
 #define VIA_CR42_MIDI_ENABLE   0x02
 #define VIA_CR42_FM_ENABLE     0x04
+#define VIA_CR42_GAME_ENABLE   0x08
+
+#define VIA_CR44_SECOND_CODEC_SUPPORT  (1 << 6)
+#define VIA_CR44_AC_LINK_ACCESS                (1 << 7)
+
+#define VIA_CR80_FIRST_CODEC           0
+#define VIA_CR80_SECOND_CODEC          (1 << 30)
+#define VIA_CR80_FIRST_CODEC_VALID     (1 << 25)
+#define VIA_CR80_SECOND_CODEC_VALID    (1 << 27)
+#define VIA_CR80_BUSY                  (1 << 24)
+#define VIA_CR80_READ_MODE             (1 << 23)
+#define VIA_CR80_WRITE_MODE            0
+#define VIA_CR80_REG_IDX(idx)          (((idx) & 0x7E) << 16)
+
+struct via_info {
+       struct address_info sb_data;
+       struct address_info opl3_data;
+       struct pci_dev *pdev;
+       struct ac97_hwint ac97;
+       int mixer_oss_dev;
+       int have_ac97;
+};
+static struct via_info         cards [MAX_CARDS];
+static unsigned                        num_cards = 0;
+
+
+static const struct {
+       int revision;
+       const char *rev_name;
+} via_chip_revs[] __initdata = {
+       { 0x10, "A" },
+       { 0x11, "B" },
+       { 0x12, "C" },
+       { 0x13, "D" },
+       { 0x14, "E" },
+       { 0x20, "H" },
+};
+
+static inline void via_ac97_write32 (struct pci_dev *pdev, int port, u32 data)
+{
+       struct resource *rsrc = &pdev->resource[0];
+       outw ((u16)data,rsrc->start+port);      
+       outw ((u16)(data>>16),rsrc->start+port+2);      
+}
+
+static inline u32 via_ac97_read32 (struct pci_dev *pdev, int port)
+{
+       struct resource *rsrc = &pdev->resource[0];
+       return
+               ((u32)inw (rsrc->start+port)) |
+               (((u32)inw (rsrc->start+port+2)) << 16);
+}
+
+/****************************************************************
+ *
+ * Intel Audio Codec '97 interface
+ *
+ *
+ */
+static inline void via_ac97_wait_idle (struct pci_dev *pdev)
+{
+       u32 tmp;
+       int counter = VIA_COUNTER_LIMIT;
+       
+       DPRINTK ("ENTER\n");
+
+       assert (pdev != NULL);
+       
+       do {
+               tmp = via_ac97_read32 (pdev,VIA_AC97_CTRL);
+       } while ((tmp & VIA_CR80_BUSY) && (counter-- > 0));
+
+       DPRINTK ("EXIT%s\n", counter > 0 ? "" : ", counter limit reached");
+}
+
+
+static int via_ac97_read_reg (struct ac97_hwint *dev, u8 reg)
+{
+       u32 data;
+       struct via_info *card;
+       struct pci_dev *pdev;
+       
+       DPRINTK ("ENTER\n");
+
+       assert (dev != NULL);
+       assert (dev->driver_private != NULL);
+
+       card = (struct via_info *) dev->driver_private;
+       pdev = card->pdev;
+       assert (pdev != NULL);
+
+       via_ac97_wait_idle (pdev);
+       data =  VIA_CR80_FIRST_CODEC | VIA_CR80_FIRST_CODEC_VALID |
+               VIA_CR80_READ_MODE | VIA_CR80_REG_IDX(reg);
+       via_ac97_write32 (pdev,VIA_AC97_CTRL,data);
+       via_ac97_wait_idle (pdev);
+       data = via_ac97_read32 (pdev,VIA_AC97_CTRL);
+
+#if 0
+       if (! (data & VIA_CR80_FIRST_CODEC_VALID)) {
+               DPRINTK ("EXIT, first codec not valid, returning -1\n");
+               return -1;
+       }
+#endif
+
+       DPRINTK ("EXIT, returning %d\n", data & 0xFFFF);
+       return data & 0xFFFF;
+}
+
+
+static int via_ac97_write_reg (struct ac97_hwint *dev, u8 reg, u16 value)
+{
+       u32 data;
+       struct via_info *card;
+       struct pci_dev *pdev;
+       
+       DPRINTK ("ENTER\n");
+
+       assert (dev != NULL);
+       assert (dev->driver_private != NULL);
 
-#define via_probe_midi probe_uart401
-#define via_attach_midi attach_uart401
-#define via_unload_midi unload_uart401
+       card = (struct via_info *) dev->driver_private;
+       pdev = card->pdev;
+       assert (pdev != NULL);
 
-static struct address_info     sb_data[MAX_CARDS];
-static struct address_info     opl3_data[MAX_CARDS];
-static unsigned                        cards = 0;
+       via_ac97_wait_idle (pdev);
+       data =  VIA_CR80_FIRST_CODEC | VIA_CR80_FIRST_CODEC_VALID |
+               VIA_CR80_WRITE_MODE | VIA_CR80_REG_IDX(reg) | value;
+       via_ac97_write32 (pdev,VIA_AC97_CTRL,data);
 
+#if 0
+       if (! (data & VIA_CR80_FIRST_CODEC_VALID)) {
+               DPRINTK ("EXIT, first codec invalid, returning -1\n");
+               return -1;
+       }
+#endif
+
+       DPRINTK ("EXIT, returning 0\n");
+       return 0;
+}
+
+
+static int via_ac97_reset (struct ac97_hwint *dev)
+{
+       struct via_info *card;
+       struct pci_dev *pdev;
+       
+       DPRINTK ("ENTER\n");
+
+       assert (dev != NULL);
+       assert (dev->driver_private != NULL);
+
+       card = (struct via_info *) dev->driver_private;
+       pdev = card->pdev;
+       assert (pdev != NULL);
+       
+       pci_write_config_word (pdev, PCI_COMMAND, PCI_COMMAND_IO);
+
+       DPRINTK ("EXIT, returning 0\n");
+       return 0;
+}
+
+
+static struct via_info *via_ac97_find_card_for_mixer (int dev)
+{
+       int x;
+
+       DPRINTK ("ENTER\n");
+
+       for (x = 0; x < num_cards; x++)
+               if (cards[x].mixer_oss_dev == dev) {
+                       DPRINTK ("EXIT, returning %p\n", cards + x);
+                       return cards + x;
+               }
+
+       DPRINTK ("EXIT, returning 0\n");
+       return NULL;
+}
+
+
+static int
+via_ac97_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
+{
+       int rc;
+       struct via_info *card = via_ac97_find_card_for_mixer (dev);
+
+       DPRINTK ("ENTER\n");
+
+       if (card != NULL) {
+               rc = ac97_mixer_ioctl (&card->ac97, cmd, arg);
+               DPRINTK ("EXIT, returning %d\n", rc);
+               return rc;
+       }
+       
+       DPRINTK ("EXIT, returning -ENODEV\n");
+       return -ENODEV;
+
+}
+
+static struct mixer_operations via_ac97_mixer_operations =
+{
+       "VIA82Cxxx",
+       "via82cxxxAC97Mixer",
+       via_ac97_default_mixer_ioctl
+};
+
+static int __init via_attach_ac97 (struct via_info *card)
+{
+       int mixer;
+       struct ac97_hwint *mdev;
+
+       DPRINTK ("ENTER\n");
+
+       assert (card != NULL);
+
+       mdev = &card->ac97;
+
+       memset (mdev, 0, sizeof (*mdev));
+       mdev->reset_device = via_ac97_reset;
+       mdev->read_reg = via_ac97_read_reg;
+       mdev->write_reg = via_ac97_write_reg;
+       mdev->driver_private = (void *) card;
+
+       if (ac97_init (mdev)) {
+               printk (KERN_ERR PFX "Unable to init AC97\n");
+               DPRINTK ("EXIT, returning -1\n");
+               return -1;
+       }
+       mixer = sound_alloc_mixerdev ();
+       if (mixer < 0 || num_mixers >= MAX_MIXER_DEV) {
+               printk (KERN_ERR PFX "Unable to alloc mixerdev\n");
+               DPRINTK ("EXIT, returning -1\n");
+               return -1;
+       }
+       mixer_devs[mixer] = &via_ac97_mixer_operations;
+       card->mixer_oss_dev = mixer;
+
+       /* Some reasonable default values.  */
+       ac97_set_mixer (mdev, SOUND_MIXER_VOLUME, (85 << 8) | 85);
+       ac97_set_mixer (mdev, SOUND_MIXER_SPEAKER, 100);
+       ac97_set_mixer (mdev, SOUND_MIXER_PCM, (65 << 8) | 65);
+       ac97_set_mixer (mdev, SOUND_MIXER_CD, (65 << 8) | 65);
+
+       printk (KERN_INFO PFX "Initialized AC97 mixer\n");
+       
+       card->have_ac97 = mixer;
+       
+       DPRINTK ("EXIT, returning 0\n");
+       return 0;
+}
+
+
+static void via_unload_ac97 (struct via_info *card)
+{
+       DPRINTK ("ENTER\n");
+
+       assert (card != NULL);
+
+       if (card->have_ac97 >= 0)
+               sound_unload_mixerdev (card->have_ac97);
+
+       DPRINTK ("EXIT\n");
+}
+
+
+#ifdef CONFIG_PROC_FS
+
+/****************************************************************
+ *
+ * /proc/driver/via82cxxx/info
+ *
+ *
+ */
+
+static int via_info_read_proc (char *page, char **start, off_t off,
+                              int count, int *eof, void *data)
+{
+#define YN(val,bit) (((val) & (bit)) ? "yes" : "no")
+
+       int len = 0, i;
+       u8 r40, r41, r42, r44;
+       
+       DPRINTK ("ENTER\n");
+
+       len += sprintf (page+len, VIA_CARD_NAME "\n\n");
+       
+       for (i = 0; i < num_cards; i++) {
+               pci_read_config_byte (cards[i].pdev, 0x40, &r40);
+               pci_read_config_byte (cards[i].pdev, 0x42, &r41);
+               pci_read_config_byte (cards[i].pdev, 0x42, &r42);
+               pci_read_config_byte (cards[i].pdev, 0x44, &r44);
+       
+               len += sprintf (page+len,
+                       "40  AC97 Codec Ready: %s\n"
+                       "    AC97 Codec Low-power: %s\n"
+                       "    Secondary Codec Ready: %s\n"
+
+                       "41  AC-Link Interface Enable: %s\n"
+
+                       "42  Game port enabled: %s\n"
+                       "    SoundBlaster enabled: %s\n"
+                       "    FM enabled: %s\n"
+                       "    MIDI enabled: %s\n"
+                       
+                       "44  AC-Link Interface Access: %s\n"
+                       "    Secondary Codec Support: %s\n"
+                       
+                       "\n",
+                       
+                       YN (r40, VIA_CR40_AC97_READY),
+                       YN (r40, VIA_CR40_AC97_LOW_POWER),
+                       YN (r40, VIA_CR40_SECONDARY_READY),
+
+                       YN (r41, VIA_CR41_ACLINK_ENABLE),
+
+                       YN (r42, VIA_CR42_GAME_ENABLE),
+                       YN (r42, VIA_CR42_SB_ENABLE),
+                       YN (r42, VIA_CR42_FM_ENABLE),
+                       YN (r42, VIA_CR42_MIDI_ENABLE),
+
+                       YN (r44, VIA_CR44_AC_LINK_ACCESS),
+                       YN (r44, VIA_CR44_SECOND_CODEC_SUPPORT)
+                       
+                       );
+       }
+       
+       DPRINTK("EXIT, returning %d\n", len);
+       return len;
+
+#undef YN
+}
+
+
+/****************************************************************
+ *
+ * /proc/driver/via82cxxx
+ *
+ *
+ */
+
+static int __init via_init_proc (void)
+{
+       DPRINTK ("ENTER\n");
+
+       proc_mkdir ("driver/via_audio", 0);
+       create_proc_read_entry ("driver/via_audio/info", 0, 0, via_info_read_proc, NULL);
+       
+       DPRINTK("EXIT\n");
+       return 0;
+}
+
+
+
+static void __exit via_cleanup_proc (void)
+{
+       DPRINTK ("ENTER\n");
+       remove_proc_entry ("driver/via_audio/info", NULL);
+       remove_proc_entry ("driver/via_audio", NULL);
+       DPRINTK("EXIT\n");
+}
+
+
+#else
+
+static inline int via_init_proc (void) { return 0; }
+static inline void via_cleanup_proc (void) {}
+
+#endif /* CONFIG_PROC_FS */
+
+
+/****************************************************************
+ *
+ * Legacy SoundBlaster Pro, FM support via OSS
+ *
+ *
+ */
 
 static void __init via_attach_sb(struct address_info *hw_config)
 {
+       DPRINTK ("ENTER\n");
+
        if(!sb_dsp_init(hw_config))
                hw_config->slots[0] = -1;
+
+       DPRINTK("EXIT\n");
 }
 
 
 static int __init via_probe_sb(struct address_info *hw_config)
 {
+       DPRINTK ("ENTER\n");
+
        if (check_region(hw_config->io_base, 16))
        {
                printk(KERN_DEBUG PFX "SBPro port 0x%x is already in use\n",
                       hw_config->io_base);
                return 0;
        }
+       DPRINTK("EXIT after sb_dsp_detect\n");
        return sb_dsp_detect(hw_config, 0, 0);
 }
 
 
-static void __exit via_unload_sb(struct address_info *hw_config, int unload_mpu)
+static void __exit via_unload_sb(struct address_info *hw_config)
 {
-       if(hw_config->slots[0]!=-1)
-               sb_dsp_unload(hw_config, unload_mpu);
+       DPRINTK ("ENTER\n");
+
+       if(hw_config->slots[0] != -1)
+               sb_dsp_unload(hw_config, 1);
+
+       DPRINTK("EXIT\n");
 }
 
 
+static const struct {
+       int sb_irq,
+           sb_dma,
+           midi_base,
+           sb_io_base;
+} via_pnp_data[] __initdata = {
+       { 5, 0, 0x300, 0x220 },
+       { 7, 1, 0x310, 0x240 },
+       { 9, 2, 0x320, 0x260 },
+       { 10,3, 0x330, 0x280 },
+};
+
+
+/****************************************************************
+ *
+ * Chip setup and kernel registration
+ *
+ *
+ */
+
 static int __init via82cxxx_install (struct pci_dev *pcidev)
 {
-       int sb_io_base = 0;
-       int sb_irq = 0;
-       int sb_dma = 0;
-       int midi_base = 0;
+       int sb_io_base;
+       int sb_irq;
+       int sb_dma;
+       int midi_base, rc;
        u8 tmp8;
+       struct via_info *card = &cards[num_cards];
        
-       memset (&sb_data[cards], 0, sizeof (struct address_info));
-       memset (&opl3_data[cards], 0, sizeof (struct address_info));
+       DPRINTK ("ENTER\n");
 
-       sb_data[cards].name = opl3_data[cards].name = VIA_CARD_NAME;
-       opl3_data[cards].irq = -1;
+       card->pdev = pcidev;
+       card->have_ac97 = -1;
+       
+       /* turn off legacy features, if not already */
+       pci_read_config_byte (pcidev, VIA_FUNC_ENABLE, &tmp8);
+       tmp8 &= ~(VIA_CR42_SB_ENABLE | VIA_CR42_MIDI_ENABLE |
+                 VIA_CR42_FM_ENABLE);
+       pci_write_config_byte (pcidev, VIA_FUNC_ENABLE, tmp8);
 
-       /* turn on features, if not already */
+       /* 
+        * try to init AC97 mixer device
+        */
+       rc = via_attach_ac97 (card);
+       if (rc) {
+               printk (KERN_WARNING PFX
+                       "AC97 init failed, SB legacy mode only\n");
+       }
+       
+       /* turn on legacy features */
        pci_read_config_byte (pcidev, VIA_FUNC_ENABLE, &tmp8);
        tmp8 |= VIA_CR42_SB_ENABLE | VIA_CR42_MIDI_ENABLE |
                VIA_CR42_FM_ENABLE;
@@ -105,34 +559,10 @@ static int __init via82cxxx_install (struct pci_dev *pcidev)
        pci_read_config_byte (pcidev, VIA_PNP_CONTROL, &tmp8);
        pci_write_config_byte (pcidev, VIA_PNP_CONTROL, tmp8);
        
-       switch ((tmp8 >> 6) & 0x03) {
-               case 0: sb_irq = 5; break;
-               case 1: sb_irq = 7; break;
-               case 2: sb_irq = 9; break;
-               case 3: sb_irq = 10; break;
-               default: /* do nothing */ break;
-       }
-       switch ((tmp8 >> 4) & 0x03) {
-               case 0: sb_dma = 0; break;
-               case 1: sb_dma = 1; break;
-               case 2: sb_dma = 2; break;
-               case 3: sb_dma = 3; break;
-               default: /* do nothing */ break;
-       }
-       switch ((tmp8 >> 2) & 0x03) {
-               case 0: midi_base = 0x300; break;
-               case 1: midi_base = 0x310; break;
-               case 2: midi_base = 0x320; break;
-               case 3: midi_base = 0x330; break;
-               default: /* do nothing */ break;
-       }
-       switch (tmp8 & 0x03) {
-               case 0: sb_io_base = 0x220; break;
-               case 1: sb_io_base = 0x240; break;
-               case 2: sb_io_base = 0x260; break;
-               case 3: sb_io_base = 0x280; break;
-               default: /* do nothing */ break;
-       }
+       sb_irq = via_pnp_data[((tmp8 >> 6) & 0x03)].sb_irq;
+       sb_dma = via_pnp_data[((tmp8 >> 4) & 0x03)].sb_dma;
+       midi_base = via_pnp_data[((tmp8 >> 2) & 0x03)].midi_base;
+       sb_io_base = via_pnp_data[(tmp8 & 0x03)].sb_io_base;
 
        udelay(100);
        
@@ -140,33 +570,38 @@ static int __init via82cxxx_install (struct pci_dev *pcidev)
               "MIDI: 0x%X, SB: 0x%X / %d IRQ / %d DMA\n",
                midi_base, sb_io_base, sb_irq, sb_dma);
                
-       sb_data[cards].card_subtype = MDL_SBPRO;
-       sb_data[cards].io_base = sb_io_base;
-       sb_data[cards].irq = sb_irq;
-       sb_data[cards].dma = sb_dma;
-       
-       opl3_data[cards].io_base = midi_base;
+       card->sb_data.name = VIA_CARD_NAME;
+       card->sb_data.card_subtype = MDL_SBPRO;
+       card->sb_data.io_base = sb_io_base;
+       card->sb_data.irq = sb_irq;
+       card->sb_data.dma = sb_dma;
        
        /* register legacy SoundBlaster Pro */
-       if (!via_probe_sb (&sb_data[cards])) {
+       if (!via_probe_sb (&card->sb_data)) {
                printk (KERN_ERR PFX
                        "SB probe @ 0x%X failed, aborting\n",
                        sb_io_base);
+               DPRINTK ("EXIT, returning -1\n");
                return -1;
        }
-       via_attach_sb (&sb_data[cards]);
+       via_attach_sb (&card->sb_data);
 
+       card->opl3_data.name = card->sb_data.name;
+       card->opl3_data.io_base = midi_base;
+       card->opl3_data.irq = -1;
+       
        /* register legacy MIDI */
-       if (!via_probe_midi (&opl3_data[cards])) {
-               printk (KERN_ERR PFX
-                       "MIDI probe @ 0x%X failed, aborting\n",
+       if (!probe_uart401 (&card->opl3_data)) {
+               printk (KERN_WARNING PFX
+                       "MIDI probe @ 0x%X failed, continuing\n",
                        midi_base);
-               via_unload_sb (&sb_data[cards], 0);
-               return -1;
+               card->opl3_data.io_base = 0;
+       } else {
+               attach_uart401 (&card->opl3_data);
        }
-       via_attach_midi (&opl3_data[cards]);
 
-       cards++;        
+       num_cards++;    
+       DPRINTK ("EXIT, returning 0\n");
        return 0;
 }
 
@@ -174,27 +609,28 @@ static int __init via82cxxx_install (struct pci_dev *pcidev)
 /*
  *     This loop walks the PCI configuration database and finds where
  *     the sound cards are.
+ *
+ *     Note - only a single PCI scan occurs, eliminating possibility
+ *     of multiple audio chips
+ *
  */
  
 static int __init probe_via82cxxx (void)
 {
        struct pci_dev *pcidev = NULL;
 
-       while ((pcidev = pci_find_device (PCI_VENDOR_ID_VIA,
-                                         PCI_DEVICE_ID_VIA_82C686_5,
-                                         pcidev)) != NULL) {
+       DPRINTK ("ENTER\n");
 
-                 if (via82cxxx_install (pcidev) != 0) {
-                         printk (KERN_ERR PFX "audio init failed\n");
-                         return -1;
-                 }
+       pcidev = pci_find_device (PCI_VENDOR_ID_VIA,
+                                 PCI_DEVICE_ID_VIA_82C686_5, NULL);
 
-                 if (cards == MAX_CARDS) {
-                         printk (KERN_DEBUG PFX "maximum number of cards reached\n");
-                         break;
-                 }
+       if (!pcidev || via82cxxx_install (pcidev) != 0) {
+               printk (KERN_ERR PFX "audio init failed\n");
+               DPRINTK ("EXIT, returning -1\n");
+               return -1;
        }
 
+       DPRINTK ("EXIT, returning 0\n");
        return 0;
 }
 
@@ -207,28 +643,49 @@ static int __init probe_via82cxxx (void)
 
 static int __init init_via82cxxx_module(void)
 {
+       u8 tmp;
+       int i;
+       const char *rev = "unknown!";
+       
+       memset (cards, 0, sizeof (cards));
+       
+       DPRINTK ("ENTER\n");
+
        if (!pci_present ()) {
                printk (KERN_DEBUG PFX "PCI not present, exiting\n");
+               DPRINTK ("EXIT, returning -ENODEV\n");
                return -ENODEV;
        }
 
        if (probe_via82cxxx() != 0) {
                printk(KERN_ERR PFX "probe failed, aborting\n");
                /* XXX unload cards registered so far, if any */
+               DPRINTK ("EXIT, returning -ENODEV\n");
                return -ENODEV;
        }
 
-       if (cards == 0) {
-               printk(KERN_DEBUG PFX "No chips found, aborting\n");
-               return -ENODEV;
-       }
-
+       pci_read_config_byte (cards[0].pdev, PCI_REVISION_ID, &tmp);
+       for (i = 0; i < arraysize(via_chip_revs); i++)
+               if (via_chip_revs[i].revision == tmp) {
+                       rev = via_chip_revs[i].rev_name;
+                       break;
+               }
        printk (KERN_INFO PFX VIA_CARD_NAME " loaded\n");
+       printk (KERN_INFO PFX "Chip rev %s.  Features: SBPro compat%s%s\n",
+               rev,
+               cards[0].opl3_data.io_base == 0 ? "" : ", MPU-401 MIDI",
+               cards[0].have_ac97 == -1 ? "" : ", AC97 mixer");
        
+       if (via_init_proc () != 0) {
+               printk (KERN_WARNING PFX
+                       "Unable to init experimental /proc, ignoring\n");
+       }
+
        /*
         *      Binds us to the sound subsystem 
         */
        SOUND_LOCK;
+       DPRINTK ("EXIT, returning 0\n");
        return 0;
 }
 
@@ -240,15 +697,23 @@ static int __init init_via82cxxx_module(void)
  
 static void __exit cleanup_via82cxxx_module(void)
 {
-       int i;
+       DPRINTK("ENTER\n");
+       
+       if (cards[0].opl3_data.io_base)
+               unload_uart401 (&cards[0].opl3_data);
+
+       via_unload_sb (&cards[0].sb_data);
        
-       for (i = 0; i < cards; i++)
-               via_unload_sb (&sb_data[i], 1);
+       via_unload_ac97 (&cards[0]);
 
+       via_cleanup_proc ();
+       
        /*
         *      Final clean up with the sound layer
         */
        SOUND_LOCK_END;
+
+       DPRINTK("EXIT\n");
 }
 
 module_init(init_via82cxxx_module);
index b7292d9a26287173922b601d6d6ef0afeeaf1a79..9b5fc4f55bd34defc45da7cc29ac92b831de374a 100644 (file)
@@ -32,10 +32,6 @@ comment 'USB Devices'
       fi
       dep_tristate '    Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_USB_HID
       dep_tristate '    Event interface support' CONFIG_INPUT_EVDEV $CONFIG_USB_HID
-      bool '    USB HID debug output' CONFIG_USB_HID_DEBUG
-      if [ "$CONFIG_USB_HID_DEBUG" != "n" ]; then
-        bool '      USB HID lots of debug output' CONFIG_USB_HID_DEBUG_LOTS
-      fi
    fi
    dep_tristate '  USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
    dep_tristate '  USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
index ae392db7ed92d6f5f1aa86e57d949b2b6c0bb863..d55abf31d97ef4d9bc560771bb25feb643ad1bb9 100644 (file)
 #include <linux/module.h>
 #include <linux/config.h>
 
-#include "usb.h"
+#undef DEBUG
 
-#ifdef CONFIG_USB_ACM_DEBUG
-#define acm_debug(fmt,arg...)  printk(KERN_DEBUG "acm: " fmt "\n" , ##arg)
-#else
-#define acm_debug(fmt,arg...)  do {} while(0)
-#endif
+#include "usb.h"
 
 /*
  * Major and minor numbers.
@@ -120,9 +116,9 @@ static struct acm acm_table[ACM_TTY_MINORS];
 static void acm_set_control(unsigned int status, struct acm *acm)
 {
        if (usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0), 0x22, 0x22, status, 0, NULL, 0, HZ) < 0)
-               acm_debug("acm_set_control() failed");
+               dbg("acm_set_control() failed");
 
-       acm_debug("output control lines: dtr%c rts%c",
+       dbg("output control lines: dtr%c rts%c",
                acm->ctrlout & ACM_CTRL_DTR ? '+' : '-', acm->ctrlout & ACM_CTRL_RTS ? '+' : '-');
 }
 
@@ -130,13 +126,13 @@ static void acm_set_control(unsigned int status, struct acm *acm)
 static void acm_set_coding(struct acm_coding *coding, struct acm *acm)
 {
        if (usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0), 0x30, 0x22, 0, 0, coding, sizeof(struct acm_coding), HZ) < 0)
-               acm_debug("acm_set_coding() failed");
+               dbg("acm_set_coding() failed");
 }
 
 static void acm_send_break(int ms, struct acm *acm)
 {
        if (usb_control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0), 0x30, 0x33, ms, 0, NULL, 0, HZ) < 0)
-               acm_debug("acm_send_break() failed");
+               dbg("acm_send_break() failed");
 }
 #endif
 
@@ -151,7 +147,7 @@ static void acm_ctrl_irq(struct urb *urb)
        unsigned char *data = (unsigned char *)(dr + 1);
 
        if (urb->status < 0) {
-               acm_debug("nonzero ctrl irq status received: %d", urb->status);
+               dbg("nonzero ctrl irq status received: %d", urb->status);
                return;
        }
 
@@ -162,13 +158,13 @@ static void acm_ctrl_irq(struct urb *urb)
                case 0x20: /* Set serial line state */
 
                        if ((dr->index != 1) || (dr->length != 2)) {
-                               acm_debug("unknown set serial line request: index %d len %d", dr->index, dr->length);
+                               dbg("unknown set serial line request: index %d len %d", dr->index, dr->length);
                                return;
                        }
 
                        acm->ctrlin = data[0] | (((unsigned int) data[1]) << 8);
 
-                       acm_debug("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c",
+                       dbg("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c",
                                acm->ctrlin & ACM_CTRL_DCD ? '+' : '-', acm->ctrlin & ACM_CTRL_DSR ? '+' : '-',
                                acm->ctrlin & ACM_CTRL_BRK ? '+' : '-', acm->ctrlin & ACM_CTRL_RI  ? '+' : '-',
                                acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-',     acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-',
@@ -177,7 +173,7 @@ static void acm_ctrl_irq(struct urb *urb)
                        return;
 
                default:
-                       acm_debug("unknown control event received: request %d index %d len %d data0 %d data1 %d",
+                       dbg("unknown control event received: request %d index %d len %d data0 %d data1 %d",
                                dr->request, dr->index, dr->length, data[0], data[1]);
                        return;
        }
@@ -193,7 +189,7 @@ static void acm_read_bulk(struct urb *urb)
        int i;
 
        if (urb->status) {
-               acm_debug("nonzero read bulk status received: %d", urb->status);
+               dbg("nonzero read bulk status received: %d", urb->status);
                return;
        }
 
@@ -205,7 +201,7 @@ static void acm_read_bulk(struct urb *urb)
        tty_flip_buffer_push(tty);
 
        if (usb_submit_urb(urb))
-               acm_debug("failed resubmitting read urb");
+               dbg("failed resubmitting read urb");
 
        return;
 }
@@ -216,7 +212,7 @@ static void acm_write_bulk(struct urb *urb)
        struct tty_struct *tty = acm->tty;
 
        if (urb->status) {
-               acm_debug("nonzero write bulk status received: %d", urb->status);
+               dbg("nonzero write bulk status received: %d", urb->status);
                return;
        }
 
@@ -248,10 +244,10 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
        if (acm->used++) return 0;
 
        if (usb_submit_urb(&acm->ctrlurb))
-               acm_debug("usb_submit_urb(ctrl irq) failed");
+               dbg("usb_submit_urb(ctrl irq) failed");
 
        if (usb_submit_urb(&acm->readurb))
-               acm_debug("usb_submit_urb(read bulk) failed");
+               dbg("usb_submit_urb(read bulk) failed");
 
        acm_set_control(acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS, acm);
 
@@ -293,7 +289,7 @@ static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned c
        acm->writeurb.transfer_buffer_length = count;
 
        if (usb_submit_urb(&acm->writeurb))
-               acm_debug("usb_submit_urb(write bulk) failed");
+               dbg("usb_submit_urb(write bulk) failed");
 
        return count;
 }
@@ -330,7 +326,7 @@ static void acm_tty_unthrottle(struct tty_struct *tty)
 
 static void acm_tty_set_termios(struct tty_struct *tty, struct termios *old)
 {
-       acm_debug("set_termios called, but not there yet");
+       dbg("set_termios called, but not there yet");
        return;
 }
 
@@ -349,7 +345,7 @@ static void *acm_probe(struct usb_device *dev, unsigned int ifnum)
        for (minor = 0; minor < ACM_TTY_MINORS &&
                (acm_table[minor].present || acm_table[minor].used); minor++);
        if (acm_table[minor].present || acm_table[minor].used) {
-               acm_debug("no more free acm devices");
+               dbg("no more free acm devices");
                return NULL;
        }
        acm = acm_table + minor;
@@ -364,7 +360,7 @@ static void *acm_probe(struct usb_device *dev, unsigned int ifnum)
 
        for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
 
-               acm_debug("probing config %d", i);
+               dbg("probing config %d", i);
                acm->cfg = dev->config + i;
 
                ifcom = acm->cfg->interface[0].altsetting + 0;
@@ -434,7 +430,7 @@ static void acm_disconnect(struct usb_device *dev, void *ptr)
        struct acm *acm = ptr;
 
        if (!acm->present) {
-               acm_debug("disconnect on nonexisting interface");
+               dbg("disconnect on nonexisting interface");
                return;
        }
 
index e55d28afdb81ee934428c51759e440d5ef4f5bda..df9a9e0683cfa09c0c7936d8bb78a99ee801e998 100644 (file)
@@ -38,6 +38,9 @@
 #include <asm/atomic.h>
 #include <linux/delay.h>
 
+#undef DEBUG
+#undef DEBUG_ALL
+
 #include "usb.h"
 
 #include "dabusb.h"
@@ -80,22 +83,22 @@ static int dabusb_add_buf_tail (pdabusb_t s, struct list_head *dst, struct list_
 #ifdef DEBUG
 static void dump_urb (purb_t purb)
 {
-       printk ("urb                   :%p\n", purb);
-       printk ("next                  :%p\n", purb->next);
-       printk ("dev                   :%p\n", purb->dev);
-       printk ("pipe                  :%08X\n", purb->pipe);
-       printk ("status                :%d\n", purb->status);
-       printk ("transfer_flags        :%08X\n", purb->transfer_flags);
-       printk ("transfer_buffer       :%p\n", purb->transfer_buffer);
-       printk ("transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-       printk ("actual_length         :%d\n", purb->actual_length);
-       printk ("setup_packet          :%p\n", purb->setup_packet);
-       printk ("start_frame           :%d\n", purb->start_frame);
-       printk ("number_of_packets     :%d\n", purb->number_of_packets);
-       printk ("interval              :%d\n", purb->interval);
-       printk ("error_count           :%d\n", purb->error_count);
-       printk ("context               :%p\n", purb->context);
-       printk ("complete              :%p\n", purb->complete);
+       dbg("urb                   :%p", purb);
+       dbg("next                  :%p", purb->next);
+       dbg("dev                   :%p", purb->dev);
+       dbg("pipe                  :%08X", purb->pipe);
+       dbg("status                :%d", purb->status);
+       dbg("transfer_flags        :%08X", purb->transfer_flags);
+       dbg("transfer_buffer       :%p", purb->transfer_buffer);
+       dbg("transfer_buffer_length:%d", purb->transfer_buffer_length);
+       dbg("actual_length         :%d", purb->actual_length);
+       dbg("setup_packet          :%p", purb->setup_packet);
+       dbg("start_frame           :%d", purb->start_frame);
+       dbg("number_of_packets     :%d", purb->number_of_packets);
+       dbg("interval              :%d", purb->interval);
+       dbg("error_count           :%d", purb->error_count);
+       dbg("context               :%p", purb->context);
+       dbg("complete              :%p", purb->complete);
 }
 #endif
 /*-------------------------------------------------------------------*/
@@ -105,9 +108,7 @@ static int dabusb_cancel_queue (pdabusb_t s, struct list_head *q)
        struct list_head *p;
        pbuff_t b;
 
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "dabusb_cancel_queue\n");
-#endif
+       dbg("dabusb_cancel_queue");
        spin_lock_irqsave (&s->lock, flags);
 
        for (p = q->next; p != q; p = p->next) {
@@ -127,9 +128,7 @@ static int dabusb_free_queue (struct list_head *q)
        struct list_head *p;
        pbuff_t b;
 
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "dabusb_free_queue\n");
-#endif
+       dbg("dabusb_free_queue");
        for (p = q->next; p != q;) {
                b = list_entry (p, buff_t, buff_list);
 #ifdef DEBUG
@@ -149,9 +148,7 @@ static int dabusb_free_queue (struct list_head *q)
 /*-------------------------------------------------------------------*/
 static int dabusb_free_buffers (pdabusb_t s)
 {
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "dabusb_free_buffers\n");
-#endif
+       dbg("dabusb_free_buffers");
        dabusb_free_queue (&s->free_buff_list);
        dabusb_free_queue (&s->rec_buff_list);
        s->got_mem = 0;
@@ -168,7 +165,7 @@ static void dabusb_iso_complete (purb_t purb)
        void *buf = purb->transfer_buffer;
 
 #ifdef DEBUG_ALL
-       printk(KERN_DEBUG MODSTR"dabusb_iso_complete\n");
+       dbg("dabusb_iso_complete");
 #endif
        if (purb->status != USB_ST_URB_KILLED) {
                unsigned int pipe = usb_rcvisocpipe (purb->dev, _DABUSB_ISOPIPE);
@@ -181,15 +178,15 @@ static void dabusb_iso_complete (purb_t purb)
                                        dst += len;
                                }
                                else
-                                       printk (KERN_ERR MODSTR "dabusb_iso_complete: invalid len %d\n", len);
+                                       err("dabusb_iso_complete: invalid len %d", len);
                        }
                if (dst != purb->actual_length)
-                       printk (KERN_ERR MODSTR "dst!=purb->actual_length:%d!=%d\n", dst, purb->actual_length);
+                       err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length);
        }
 
        if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) {
                s->overruns++;
-               printk (KERN_ERR MODSTR "overrun (%d)\n", s->overruns);
+               err("overrun (%d)", s->overruns);
        }
        wake_up (&s->wait);
 }
@@ -205,22 +202,20 @@ static int dabusb_alloc_buffers (pdabusb_t s)
        int i;
        int len = sizeof (urb_t) + packets * sizeof (iso_packet_descriptor_t);
 
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "dabusb_alloc_buffers len:%d pipesize:%d packets:%d transfer_buffer_len:%d\n",
+       dbg("dabusb_alloc_buffers len:%d pipesize:%d packets:%d transfer_buffer_len:%d",
                len, pipesize, packets, transfer_buffer_length);
-#endif
 
        while (buffers < (s->total_buffer_size << 10)) {
                b = (pbuff_t) kmalloc (sizeof (buff_t), GFP_KERNEL);
                if (!b) {
-                       printk (KERN_ERR MODSTR "kmalloc(sizeof(buff_t))==NULL\n");
+                       err("kmalloc(sizeof(buff_t))==NULL");
                        goto err;
                }
                memset (b, sizeof (buff_t), 0);
                b->s = s;
                b->purb = (purb_t) kmalloc (len, GFP_KERNEL);
                if (!b->purb) {
-                       printk (KERN_ERR MODSTR "kmalloc(sizeof(urb_t)+packets*sizeof(iso_packet_descriptor_t))==NULL\n");
+                       err("kmalloc(sizeof(urb_t)+packets*sizeof(iso_packet_descriptor_t))==NULL");
                        kfree (b);
                        goto err;
                }
@@ -229,7 +224,7 @@ static int dabusb_alloc_buffers (pdabusb_t s)
                if (!b->purb->transfer_buffer) {
                        kfree (b->purb);
                        kfree (b);
-                       printk (KERN_ERR MODSTR "kmalloc(%d)==NULL\n", transfer_buffer_length);
+                       err("kmalloc(%d)==NULL", transfer_buffer_length);
                        goto err;
                }
 
@@ -260,9 +255,7 @@ err:
 /*-------------------------------------------------------------------*/
 static int dabusb_reset_pipe (struct usb_device *usbdev, unsigned int ep)
 {
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "dabusb_reset_pipe\n");
-#endif
+       dbg("dabusb_reset_pipe");
        if ((ep & ~0x80) >= 16)
                return -EINVAL;
 
@@ -285,12 +278,12 @@ static int dabusb_submit_urb (pdabusb_t s, purb_t purb)
 
        ret = usb_submit_urb (purb);
        if (ret < 0) {
-               printk (KERN_DEBUG MODSTR "dabusb_bulk: usb_submit_urb returned %d\n", ret);
+               dbg("dabusb_bulk: usb_submit_urb returned %d", ret);
                return -EINVAL;
        }
        interruptible_sleep_on_timeout (&context.wait, HZ);
        if (purb->status == USB_ST_URB_PENDING) {
-               printk (KERN_ERR MODSTR "dabusb_usb_submit_urb: %p timed out\n", purb);
+               err("dabusb_usb_submit_urb: %p timed out", purb);
                usb_unlink_urb (purb);
                dabusb_reset_pipe(purb->dev, purb->pipe);
                return -ETIMEDOUT;
@@ -303,7 +296,7 @@ static void dabusb_bulk_complete (purb_t purb)
        pbulk_completion_context_t context = purb->context;
 
 #ifdef DEBUG_ALL
-       printk(KERN_DEBUG MODSTR"dabusb_bulk_complete\n");
+       dbg("dabusb_bulk_complete");
        dump_urb(purb);
 #endif
        wake_up (&context->wait);
@@ -317,7 +310,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
        unsigned int pipe;
 
 #ifdef DEBUG_ALL
-       printk(KERN_DEBUG MODSTR"dabusb_bulk\n");
+       dbg("dabusb_bulk");
 #endif
 
        if (!pb->pipe)
@@ -342,12 +335,12 @@ static int dabusb_writemem (pdabusb_t s, int pos, unsigned char *data, int len)
        unsigned char *transfer_buffer;
 
        if (!setup) {
-               printk (KERN_ERR MODSTR "dabusb_writemem: kmalloc(8) failed.\n");
+               err("dabusb_writemem: kmalloc(8) failed.");
                return -ENOMEM;
        }
        transfer_buffer = kmalloc (len, GFP_KERNEL);
        if (!transfer_buffer) {
-               printk (KERN_ERR MODSTR "dabusb_writemem: kmalloc(%d) failed.\n", len);
+               err("dabusb_writemem: kmalloc(%d) failed.", len);
                kfree (setup);
                return -ENOMEM;
        }
@@ -377,9 +370,7 @@ static int dabusb_writemem (pdabusb_t s, int pos, unsigned char *data, int len)
 /* --------------------------------------------------------------------- */
 static int dabusb_8051_reset (pdabusb_t s, unsigned char reset_bit)
 {
-#ifdef DEBUG
-       printk("dabusb_8051_reset: %d\n",reset_bit);
-#endif
+       dbg("dabusb_8051_reset: %d",reset_bit);
        return dabusb_writemem (s, CPUCS_REG, &reset_bit, 1);
 }
 /* --------------------------------------------------------------------- */
@@ -388,25 +379,22 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname)
        int ret;
        PINTEL_HEX_RECORD ptr = firmware;
 
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "Enter dabusb_loadmem (internal)\n");
-#endif
+       dbg("Enter dabusb_loadmem (internal)");
+
        ret = dabusb_8051_reset (s, 1);
        while (ptr->Type == 0) {
 #ifdef DEBUG_ALL
-               printk(KERN_ERR MODSTR"dabusb_writemem: %04X %p %d)\n", ptr->Address, ptr->Data, ptr->Length);
+               err("dabusb_writemem: %04X %p %d)", ptr->Address, ptr->Data, ptr->Length);
 #endif
                ret = dabusb_writemem (s, ptr->Address, ptr->Data, ptr->Length);
                if (ret < 0) {
-                       printk (KERN_ERR MODSTR "dabusb_writemem failed (%04X %p %d)\n", ptr->Address, ptr->Data, ptr->Length);
+                       err("dabusb_writemem failed (%04X %p %d)", ptr->Address, ptr->Data, ptr->Length);
                        break;
                }
                ptr++;
        }
        ret = dabusb_8051_reset (s, 0);
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "dabusb_loadmem: exit\n");
-#endif
+       dbg("dabusb_loadmem: exit");
        return ret;
 }
 /* --------------------------------------------------------------------- */
@@ -418,9 +406,7 @@ static int dabusb_fpga_clear (pdabusb_t s, pbulk_transfer_t b)
        b->data[2] = 0;
        b->data[3] = 0;
 
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "dabusb_fpga_clear\n");
-#endif
+       dbg("dabusb_fpga_clear");
        return dabusb_bulk (s, b);
 }
 /* --------------------------------------------------------------------- */
@@ -432,9 +418,7 @@ static int dabusb_fpga_init (pdabusb_t s, pbulk_transfer_t b)
        b->data[2] = 0;
        b->data[3] = 0;
 
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "dabusb_fpga_init\n");
-#endif
+       dbg("dabusb_fpga_init");
        return dabusb_bulk (s, b);
 }
 /* --------------------------------------------------------------------- */
@@ -445,11 +429,9 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
        int ret;
        unsigned char *buf = bitstream;
 
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "Enter dabusb_fpga_download (internal)\n");
-#endif
+       dbg("Enter dabusb_fpga_download (internal)");
        if (!b) {
-               printk (KERN_ERR MODSTR "kmalloc(sizeof(bulk_transfer_t))==NULL\n");
+               err("kmalloc(sizeof(bulk_transfer_t))==NULL");
                return -ENOMEM;
        }
 
@@ -457,9 +439,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
        ret = dabusb_fpga_clear (s, b);
        mdelay (10);
        blen = buf[73] + (buf[72] << 8);
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "Bitstream len: %i\n", blen);
-#endif
+       dbg("Bitstream len: %i", blen);
        b->data[0] = 0x2b;
        b->data[1] = 0;
        b->data[2] = 0;
@@ -471,7 +451,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
                memcpy (b->data + 4, buf + 74 + n, 60);
                ret = dabusb_bulk (s, b);
                if (ret < 0) {
-                       printk (KERN_ERR MODSTR "dabusb_bulk failed.\n");
+                       err("dabusb_bulk failed.");
                        break;
                }
                mdelay (1);
@@ -480,9 +460,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
        ret = dabusb_fpga_init (s, b);
        kfree (b);
 
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "exit dabusb_fpga_download\n");
-#endif
+       dbg("exit dabusb_fpga_download");
        return ret;
 }
 
@@ -493,16 +471,12 @@ static loff_t dabusb_llseek (struct file *file, loff_t offset, int origin)
 
 static int dabusb_stop (pdabusb_t s)
 {
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "dabusb_stop\n");
-#endif
+       dbg("dabusb_stop");
 
        s->state = _stopped;
        dabusb_cancel_queue (s, &s->rec_buff_list);
 
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "pending_io: %d\n", s->pending_io.counter);
-#endif
+       dbg("pending_io: %d", s->pending_io.counter);
 
        s->pending_io.counter = 0;
        return 0;
@@ -511,9 +485,7 @@ static int dabusb_stop (pdabusb_t s)
 static int dabusb_startrek (pdabusb_t s)
 {
        if (!s->got_mem && s->state != _started) {
-#ifdef DEBUG
-               printk (KERN_DEBUG MODSTR "dabusb_startrek\n");
-#endif
+               dbg("dabusb_startrek");
 
                if (dabusb_alloc_buffers (s) < 0)
                        return -ENOMEM;
@@ -529,21 +501,21 @@ static int dabusb_startrek (pdabusb_t s)
 
                while (!dabusb_add_buf_tail (s, &s->rec_buff_list, &s->free_buff_list)) {
 #ifdef DEBUG_ALL
-                       printk("submitting: end:%p s->rec_buff_list:%p\n", s->rec_buff_list.prev, &s->rec_buff_list);
+                       dbg("submitting: end:%p s->rec_buff_list:%p", s->rec_buff_list.prev, &s->rec_buff_list);
 #endif
                        end = list_entry (s->rec_buff_list.prev, buff_t, buff_list);
 
                        ret = usb_submit_urb (end->purb);
                        if (ret) {
-                               printk (KERN_ERR MODSTR "usb_submit_urb returned:%d\n", ret);
+                               err("usb_submit_urb returned:%d", ret);
                                if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
-                                       printk (KERN_ERR MODSTR "startrek: dabusb_add_buf_tail failed");
+                                       err("startrek: dabusb_add_buf_tail failed");
                        }
                        else
                                atomic_inc (&s->pending_io);
                }
 #ifdef DEBUG_ALL
-               printk(KERN_DEBUG MODSTR"pending_io: %d\n",s->pending_io.counter);
+               dbg("pending_io: %d",s->pending_io.counter);
 #endif
        }
        return 0;
@@ -559,7 +531,7 @@ static ssize_t dabusb_read (struct file *file, char *buf, size_t count, loff_t *
        purb_t purb = NULL;
 
 #ifdef DEBUG_ALL
-       printk(KERN_DEBUG MODSTR"dabusb_read\n");
+       dbg("dabusb_read");
 #endif
 
        if (*ppos)
@@ -575,7 +547,7 @@ static ssize_t dabusb_read (struct file *file, char *buf, size_t count, loff_t *
        while (count > 0) {
                dabusb_startrek (s);
                if (list_empty (&s->rec_buff_list)) {
-                       printk (KERN_ERR MODSTR "error: rec_buf_list is empty\n");
+                       err("error: rec_buf_list is empty");
                        goto err;
                }
                b = list_entry (s->rec_buff_list.next, buff_t, buff_list);
@@ -597,7 +569,7 @@ static ssize_t dabusb_read (struct file *file, char *buf, size_t count, loff_t *
                                goto err;
                        }
                        if (list_empty (&s->rec_buff_list)) {
-                               printk (KERN_ERR MODSTR "error: still no buffer available.\n");
+                               err("error: still no buffer available.");
                                goto err;
                        }
                        s->readptr = 0;
@@ -615,11 +587,11 @@ static ssize_t dabusb_read (struct file *file, char *buf, size_t count, loff_t *
                        cnt = count;
 
 #ifdef DEBUG_ALL
-               printk("copy_to_user:%p %p %d\n",buf, purb->transfer_buffer + s->readptr, cnt);
+               dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt);
 #endif
 
                if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) {
-                       printk (KERN_ERR MODSTR "read: copy_to_user failed\n");
+                       err("read: copy_to_user failed");
                        if (!ret)
                                ret = -EFAULT;
                        goto err;
@@ -633,7 +605,7 @@ static ssize_t dabusb_read (struct file *file, char *buf, size_t count, loff_t *
                if (s->readptr == purb->actual_length) {
                        // finished, take next buffer
                        if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
-                               printk (KERN_ERR MODSTR "read: dabusb_add_buf_tail failed");
+                               err("read: dabusb_add_buf_tail failed");
                        s->readptr = 0;
                }
        }
@@ -652,7 +624,7 @@ static int dabusb_open (struct inode *inode, struct file *file)
        MOD_INC_USE_COUNT;
        s = &dabusb[devnum - DABUSB_MINOR];
 
-       printk (KERN_DEBUG MODSTR "dabusb_open\n");
+       dbg("dabusb_open");
        down (&s->mutex);
 
        while (!s->usbdev || s->opened) {
@@ -674,7 +646,7 @@ static int dabusb_open (struct inode *inode, struct file *file)
        up (&s->mutex);
 
        if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
-               printk (KERN_ERR "dabusb: set_interface failed\n");
+               err("dabusb: set_interface failed");
                MOD_DEC_USE_COUNT;
                return -EINVAL;
        }
@@ -688,7 +660,7 @@ static int dabusb_release (struct inode *inode, struct file *file)
 {
        pdabusb_t s = (pdabusb_t) file->private_data;
 
-       printk (KERN_DEBUG MODSTR "dabusb_release\n");
+       dbg("dabusb_release");
 
        down (&s->mutex);
        dabusb_stop (s);
@@ -697,7 +669,7 @@ static int dabusb_release (struct inode *inode, struct file *file)
 
        if (!s->remove_pending) {
                if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
-                       printk (KERN_ERR "dabusb: set_interface failed\n");
+                       err("dabusb: set_interface failed");
        }
        else
                wake_up (&s->remove_ok);
@@ -715,7 +687,7 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
        int version = DABUSB_VERSION;
        DECLARE_WAITQUEUE (wait, current);
 
-//        printk(KERN_DEBUG MODSTR"dabusb_ioctl\n");
+//        dbg("dabusb_ioctl");
 
        if (s->remove_pending)
                return -EIO;
@@ -801,10 +773,8 @@ static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum)
        int devnum;
        pdabusb_t s;
 
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d\n",
+       dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
          usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum);
-#endif
 
        /* the 1234:5678 is just a self assigned test ID */
        if ((usbdev->descriptor.idVendor != 0x0547 || usbdev->descriptor.idProduct != 0x2131) &&
@@ -829,7 +799,7 @@ static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum)
        s->usbdev = usbdev;
 
        if (usb_set_configuration (usbdev, usbdev->config[0].bConfigurationValue) < 0) {
-               printk (KERN_ERR MODSTR "set_configuration failed\n");
+               err("set_configuration failed");
                goto reject;
        }
        if (usbdev->descriptor.idProduct == 0x2131)
@@ -838,11 +808,11 @@ static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum)
                dabusb_fpga_download (s, NULL);
 
                if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) {
-                       printk (KERN_ERR MODSTR "set_interface failed\n");
+                       err("set_interface failed");
                        goto reject;
                }
        }
-       printk (KERN_DEBUG MODSTR "bound to interface: %d\n", ifnum);
+       dbg("bound to interface: %d", ifnum);
        up (&s->mutex);
        MOD_INC_USE_COUNT;
        return s;
@@ -857,7 +827,7 @@ static void dabusb_disconnect (struct usb_device *usbdev, void *ptr)
 {
        pdabusb_t s = (pdabusb_t) ptr;
 
-       printk (KERN_DEBUG MODSTR "dabusb_disconnect\n");
+       dbg("dabusb_disconnect");
 
        s->remove_pending = 1;
        wake_up (&s->wait);
@@ -901,17 +871,13 @@ int __init dabusb_init (void)
        /* register misc device */
        usb_register (&dabusb_driver);
 
-#ifdef DEBUG
-       printk (KERN_INFO "dabusb_init: driver registered\n");
-#endif
+       dbg("dabusb_init: driver registered");
        return 0;
 }
 
 void __exit dabusb_cleanup (void)
 {
-#ifdef DEBUG
-       printk (KERN_DEBUG MODSTR "dabusb_cleanup\n");
-#endif
+       dbg("dabusb_cleanup");
        usb_deregister (&dabusb_driver);
 }
 
index 8d9aadbc01e5009ff29812aeb4c3a4f6e64721cc..722b4026c27abc3c54febe78d1112576da25d97d 100644 (file)
@@ -14,14 +14,8 @@ typedef struct
 
 #ifdef __KERNEL__
 
-#ifdef MODSTR
-#undef MODSTR
-#endif
-#define MODSTR "dabusb: "
-
 typedef enum { _stopped=0, _started } driver_state_t;
 
-
 typedef struct
 {
        struct semaphore mutex;
@@ -88,4 +82,4 @@ typedef struct _INTEL_HEX_RECORD
    BYTE  Data[MAX_INTEL_HEX_RECORD_LENGTH];
 } INTEL_HEX_RECORD, *PINTEL_HEX_RECORD;
 
-#endif
\ No newline at end of file
+#endif
index 1c4a4812a8d8afa10212ce3c4edca3f936a6a736..491fcabfafebda3a98551356249b2d5e73fffcbf 100644 (file)
 #include <linux/malloc.h>
 #include <linux/module.h>
 
-#include "usb.h"
-
-
-// #define     CAMERA_DEBUG
+#undef DEBUG
 
+#include "usb.h"
 
 /* XXX need to get registered minor number, cdev 10/MINOR */
 /* XXX or: cdev USB_MAJOR(180)/USB_CAMERA_MINOR */
@@ -163,9 +161,8 @@ static ssize_t camera_read (struct file *file,
                          usb_rcvbulkpipe (camera->dev, camera->inEP),
                          camera->buf, len, &count, HZ*10);
 
-#ifdef CAMERA_DEBUG
-               printk ("camera.r (%d) - 0x%x %ld\n", len, result, count);
-#endif
+               dbg("read (%d) - 0x%x %ld", len, result, count);
+
                if (!result) {
                        if (copy_to_user (buf, camera->buf, count))
                                return -EFAULT;
@@ -175,9 +172,8 @@ static ssize_t camera_read (struct file *file,
                if (result != USB_ST_TIMEOUT)
                        break;
                interruptible_sleep_on_timeout (&camera->wait, RETRY_TIMEOUT);
-#ifdef CAMERA_DEBUG
-               printk ("camera.r (%d) - retry\n", len);
-#endif
+
+               dbg("read (%d) - retry", len);
        }
        camera->isActive = 0;
        return -EIO;
@@ -230,10 +226,10 @@ static ssize_t camera_write (struct file *file,
                        result = usb_bulk_msg (camera->dev,
                                 usb_sndbulkpipe (camera->dev, camera->outEP),
                                 obuf, thistime, &count, HZ*10);
-#ifdef CAMERA_DEBUG
+
                        if (result)
-                               printk ("camera.w USB err - %x\n", result);
-#endif
+                               dbg("write USB err - %x", result);
+
                        if (count) {
                                obuf += count;
                                thistime -= count;
@@ -262,9 +258,9 @@ static ssize_t camera_write (struct file *file,
        }
 done:
        camera->isActive = 0;
-#ifdef CAMERA_DEBUG
-       printk ("camera.w %d\n", bytes_written); 
-#endif
+
+       dbg("write %d", bytes_written); 
+
        return bytes_written;
 }
 
@@ -280,9 +276,8 @@ static int camera_open (struct inode *inode, struct file *file)
                camera->isOpen = 0;
                return -ENOMEM;
        }
-#ifdef CAMERA_DEBUG
-       printk ("camera.open\n"); 
-#endif
+
+       dbg("open"); 
        
        /* Keep driver from being unloaded while it's in use */
        MOD_INC_USE_COUNT;
@@ -300,9 +295,8 @@ static int camera_release (struct inode *inode, struct file *file)
        kfree (camera->buf);
        camera->isOpen = 0;
        MOD_DEC_USE_COUNT;
-#ifdef CAMERA_DEBUG
-       printk ("camera.close\n"); 
-#endif
+
+       dbg("close"); 
 
        return 0;
 }
@@ -363,7 +357,7 @@ static void * camera_probe(struct usb_device *dev, unsigned int ifnum)
        /* these have one config, one interface */
        if (dev->descriptor.bNumConfigurations != 1
                        || dev->config[0].bNumInterfaces != 1) {
-               printk (KERN_INFO "Bogus camera config info\n");
+               dbg("Bogus camera config info");
                return NULL;
        }
 
@@ -375,16 +369,16 @@ static void * camera_probe(struct usb_device *dev, unsigned int ifnum)
                        || interface->bInterfaceProtocol != 0
                        || interface->bNumEndpoints != 2
                        ) {
-               printk (KERN_INFO "Bogus camera interface info\n");
+               dbg("Bogus camera interface info");
                return NULL;
        }
 
        /* can only show one camera at a time through /dev ... */
        if (!camera->dev) {
                camera->dev = dev;
-               printk(KERN_INFO "USB Camera is connected\n");
+               info("USB Camera is connected");
        } else {
-               printk(KERN_INFO "Ignoring additional USB Camera\n");
+               info("Ignoring additional USB Camera");
                return NULL;
        }
 
@@ -410,14 +404,14 @@ static void * camera_probe(struct usb_device *dev, unsigned int ifnum)
                        || endpoint [0].bmAttributes != USB_ENDPOINT_XFER_BULK
                        || endpoint [1].bmAttributes != USB_ENDPOINT_XFER_BULK
                        ) {
-               printk (KERN_INFO "Bogus camera endpoints\n");
+               dbg("Bogus camera endpoints");
                camera->dev = NULL;
                return NULL;
        }
 
 
        if (usb_set_configuration (dev, dev->config[0].bConfigurationValue)) {
-               printk (KERN_INFO "Failed usb_set_configuration: camera\n");
+               err("Failed usb_set_configuration");
                camera->dev = NULL;
                return NULL;
        }
@@ -443,7 +437,7 @@ static void camera_disconnect(struct usb_device *dev, void *ptr)
        camera->info = NULL;
        camera->dev = NULL;
 
-       printk (KERN_INFO "USB Camera disconnected\n");
+       info("USB Camera disconnected");
 }
 
 static /* const */ struct usb_driver camera_driver = {
index 25b4991dcd067bc208d89dec810ab8b4bb16914c..4cd3960acfa60b78309afc04540ab43c9e28f2b5 100644 (file)
 #include <linux/list.h>
 #include <linux/malloc.h>
 #include <linux/smp_lock.h>
-//#include <linux/spinlock.h>
 
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 
+#define DEBUG
+
 #include "usb.h"
 #include "hub.h"
 
@@ -47,11 +48,13 @@ static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
                USB_DT_HUB << 8, 0, data, size, HZ);
 }
 
+#if 0
 static int usb_clear_hub_feature(struct usb_device *dev,  int feature)
 {
        return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
                USB_REQ_CLEAR_FEATURE, USB_RT_HUB, feature, 0 , NULL, 0, HZ);
 }
+#endif
 
 static int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
 {
@@ -137,48 +140,44 @@ static int usb_hub_configure(struct usb_hub *hub)
        descriptor = (struct usb_hub_descriptor *)bitmap;
 
        hub->nports = dev->maxchild = descriptor->bNbrPorts;
-       printk(KERN_INFO "hub: %d port%s detected\n", hub->nports,
-               (hub->nports == 1) ? "" : "s");
+       info("%d port%s detected", hub->nports, (hub->nports == 1) ? "" : "s");
 
        switch (descriptor->wHubCharacteristics & HUB_CHAR_LPSM) {
                case 0x00:
-                       printk(KERN_INFO "hub: ganged power switching\n");
+                       dbg("ganged power switching");
                        break;
                case 0x01:
-                       printk(KERN_INFO "hub: individual port power switching\n");
+                       dbg("individual port power switching");
                        break;
                case 0x02:
                case 0x03:
-                       printk(KERN_INFO "hub: unknown reserved power switching mode\n");
+                       dbg("unknown reserved power switching mode");
                        break;
        }
 
        if (descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND)
-               printk(KERN_INFO "hub: part of a compound device\n");
+               dbg("part of a compound device");
        else
-               printk(KERN_INFO "hub: standalone hub\n");
+               dbg("standalone hub");
 
        switch (descriptor->wHubCharacteristics & HUB_CHAR_OCPM) {
                case 0x00:
-                       printk(KERN_INFO "hub: global over-current protection\n");
+                       dbg("global over-current protection");
                        break;
                case 0x08:
-                       printk(KERN_INFO "hub: individual port over-current protection\n");
+                       dbg("individual port over-current protection");
                        break;
                case 0x10:
                case 0x18:
-                       printk(KERN_INFO "hub: no over-current protection\n");
+                       dbg("no over-current protection");
                         break;
        }
 
-       printk(KERN_INFO "hub: power on to power good time: %dms\n",
-               descriptor->bPwrOn2PwrGood * 2);
-
-       printk(KERN_INFO "hub: hub controller current requirement: %dmA\n",
-               descriptor->bHubContrCurrent);
+       dbg("power on to power good time: %dms", descriptor->bPwrOn2PwrGood * 2);
+       dbg("hub controller current requirement: %dmA", descriptor->bHubContrCurrent);
 
        for (i = 0; i < dev->maxchild; i++)
-               printk(KERN_INFO "hub:  port %d is%s removable\n", i + 1,
+               dbg("port %d is%s removable", i + 1,
                        bitmap[7 + ((i + 1)/8)] & (1 << ((i + 1) % 8))
                        ? " not" : "");
 
@@ -188,14 +187,14 @@ static int usb_hub_configure(struct usb_hub *hub)
                return -1;
 
        hubsts = (struct usb_hub_status *)buffer;
-       printk(KERN_INFO "hub: local power source is %s\n",
+       dbg("local power source is %s",
                (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" : "good");
 
-       printk(KERN_INFO "hub: %sover-current condition exists\n",
+       dbg("%sover-current condition exists",
                (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? "" : "no ");
 
        /* Enable power to the ports */
-       printk(KERN_INFO "hub: enabling power on all ports\n");
+       dbg("enabling power on all ports");
        for (i = 0; i < hub->nports; i++)
                usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
        return 0;
@@ -236,10 +235,10 @@ static void * hub_probe(struct usb_device *dev, unsigned int i)
                return NULL;
 
        /* We found a hub */
-       printk(KERN_INFO "USB hub found\n");
+       info("USB hub found");
 
        if ((hub = kmalloc(sizeof(*hub), GFP_KERNEL)) == NULL) {
-               printk(KERN_ERR "couldn't kmalloc hub struct\n");
+               err("couldn't kmalloc hub struct");
                return NULL;
        }
 
@@ -260,7 +259,7 @@ static void * hub_probe(struct usb_device *dev, unsigned int i)
                        hub_irq, endpoint->bInterval,
                        hub, &hub->irq_handle);
                if (ret) {
-                       printk (KERN_WARNING "hub: usb_request_irq failed (%d)\n", ret);
+                       err("usb_request_irq failed (%d)", ret);
                        /* free hub, but first clean up its list. */
                        spin_lock_irqsave(&hub_event_lock, flags);
 
@@ -317,14 +316,14 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port)
        wait_ms(100);
        /* Check status */
        if (usb_get_port_status(hub, port + 1, &portsts)<0) {
-               printk(KERN_ERR "get_port_status failed\n");
+               err("get_port_status failed");
                return;
        }
 
        portstatus = le16_to_cpu(portsts.wPortStatus);
        portchange = le16_to_cpu(portsts.wPortChange);
-       printk("hub.c: portstatus %x, change %x, %s\n",portstatus,portchange,
-       (portstatus&(1<<USB_PORT_FEAT_LOWSPEED)?"Low Speed":"High Speed"));
+       dbg("portstatus %x, change %x, %s", portstatus, portchange,
+               portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
        /* If it's not in CONNECT and ENABLE state, we're done */
        if ((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
            (!(portstatus & USB_PORT_STAT_ENABLE))) {
@@ -345,13 +344,13 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port)
                wait_ms(200);   
                
                if (usb_get_port_status(hub, port + 1, &portsts)<0) {
-                       printk(KERN_ERR "get_port_status failed\n");
+                       err("get_port_status failed");
                        return;
                }
                portstatus = le16_to_cpu(portsts.wPortStatus);
                portchange = le16_to_cpu(portsts.wPortChange);
-               printk("hub.c: portstatus %x, change %x, %s\n",portstatus,portchange,
-               (portstatus&(1<<USB_PORT_FEAT_LOWSPEED)?"Low Speed":"High Speed"));
+               dbg("portstatus %x, change %x, %s", portstatus ,portchange,
+                       portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
 
                if ((portstatus&(1<<USB_PORT_FEAT_ENABLE))) 
                        break;
@@ -360,14 +359,14 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port)
        }
 
        if (tries==MAX_TRIES) {
-               printk("hub.c: Can not enable port %i after %i retries, disabling port\n",port+1,MAX_TRIES);
+               err("can not enable port %i after %i retries, disabling port", port+1, MAX_TRIES);
                return;
        }
        /* Allocate a new device struct for it */
 
        usb = usb_alloc_dev(hub, hub->bus);
        if (!usb) {
-               printk(KERN_ERR "couldn't allocate usb_device\n");
+               err("couldn't allocate usb_device");
                return;
        }
 
@@ -381,8 +380,7 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port)
        /* Run it through the hoops (find a driver, etc) */
        if (usb_new_device(usb)) {
                /* Woops, disable the port */
-               printk(KERN_DEBUG "hub: disabling port %d\n",
-                       port + 1);
+               dbg("hub: disabling port %d", port + 1);
                usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_ENABLE);
        }
 }
@@ -423,7 +421,7 @@ static void usb_hub_events(void)
                        unsigned short portstatus, portchange;
 
                        if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
-                               printk(KERN_ERR "get_port_status failed\n");
+                               err("get_port_status failed");
                                continue;
                        }
 
@@ -431,35 +429,27 @@ static void usb_hub_events(void)
                        portchange = le16_to_cpu(portsts.wPortChange);
 
                        if (portchange & USB_PORT_STAT_C_CONNECTION) {
-                               printk(KERN_INFO "hub: port %d connection change\n",
-                                       i + 1);
+                               dbg("port %d connection change", i + 1);
 
-                               usb_clear_port_feature(dev, i + 1,
-                                       USB_PORT_FEAT_C_CONNECTION);
+                               usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_CONNECTION);
 
                                usb_hub_port_connect_change(dev, i);
                        }
 
                        if (portchange & USB_PORT_STAT_C_ENABLE) {
-                               printk(KERN_INFO "hub: port %d enable change\n",
-                                       i + 1);
-                               usb_clear_port_feature(dev, i + 1,
-                                       USB_PORT_FEAT_C_ENABLE);
+                               dbg("port %d enable change", i + 1);
+                               usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_ENABLE);
                        }
 
                        if (portchange & USB_PORT_STAT_C_SUSPEND)
-                               printk(KERN_INFO "hub: port %d suspend change\n",
-                                       i + 1);
+                               dbg("port %d suspend change", i + 1);
 
                        if (portchange & USB_PORT_STAT_C_OVERCURRENT)
-                               printk(KERN_INFO "hub: port %d over-current change\n",
-                                       i + 1);
+                               dbg("port %d over-current change", i + 1);
 
                        if (portchange & USB_PORT_STAT_C_RESET) {
-                               printk(KERN_INFO "hub: port %d reset change\n",
-                                       i + 1);
-                               usb_clear_port_feature(dev, i + 1,
-                                       USB_PORT_FEAT_C_RESET);
+                               dbg("port %d reset change", i + 1);
+                               usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_RESET);
                        }
                } /* end for i */
         } /* end while (1) */
@@ -499,7 +489,7 @@ static int usb_hub_thread(void *__hub)
        MOD_DEC_USE_COUNT;
 */
 
-       printk("usb_hub_thread exiting\n");
+       dbg("usb_hub_thread exiting");
        khubd_running = 0;
 
        return 0;
@@ -552,7 +542,7 @@ void usb_hub_cleanup(void)
                }
 
                if (!count)
-                       printk(KERN_ERR "hub: giving up on killing khubd\n");
+                       err("giving up on killing khubd");
        }
 
        /*
index c0ed6b8c3090246c2dedafa21f5eb87a2cf39ced..b52609bf098492ef7be7be259789db8d512f2c88 100644 (file)
@@ -212,10 +212,6 @@ static ssize_t mousedev_write(struct file * file, const char * buffer, size_t co
 
                c = buffer[i];
 
-#ifdef MOUSEDEV_DEBUG
-               printk(KERN_DEBUG "mousedev: received char %#x\n", c);
-#endif
-
                if (c == mousedev_genius_seq[list->genseq]) {
                        if (++list->genseq == MOUSEDEV_GENIUS_LEN) {
                                list->genseq = 0;
index ac3674335804a4594eb216874db591cc527bed7e..806e15ab3aadd1e42c34f7c4c5464b08e974747e 100644 (file)
 #include <linux/malloc.h>
 #include <linux/delay.h>
 
-#include "usb.h"
-
-// #define SCN_DBG /* Enable to print results of read/write_scanner() calls */
-// #define RD_DATA_DUMP /* Enable to dump data - limited to 24 bytes */
-// #define WR_DATA_DUMP
+#undef DEBUG           /* Enable to print results of read/write_scanner() calls */
+#undef RD_DATA_DUMP    /* Enable to dump data - limited to 24 bytes */
+#undef WR_DATA_DUMP
 
-#ifdef SCN_DBG
-#define SCN_DEBUG(X) X
-#else
-#define SCN_DEBUG(X)
-#endif
+#include "usb.h"
 
 #define IBUF_SIZE 32768
 #define OBUF_SIZE 4096
@@ -207,14 +201,14 @@ write_scanner(struct file * file, const char * buffer,
                }
 
                result = usb_bulk_msg(hps->hpscan_dev,usb_sndbulkpipe(hps->hpscan_dev, hps->oep), obuf, copy_size, &partial, 30*HZ);
-               SCN_DEBUG(printk(KERN_DEBUG "write stats: result:%d copy_size:%lu partial:%lu\n", (int)result, copy_size, partial);)
+               dbg("write stats: result:%d copy_size:%lu partial:%lu", (int)result, copy_size, partial);
 
                if (result == USB_ST_TIMEOUT) { /* NAK -- shouldn't happen */
-                       printk(KERN_WARNING "write_scanner: NAK recieved.\n");
+                       warn("write_scanner: NAK recieved.");
                        ret = -ETIME;
                        break;
                } else if (result < 0) { /* We should not get any I/O errors */
-                       printk(KERN_WARNING "write_scanner: funky result: %d. Please notify the maintainer.\n", result);
+                       warn("write_scanner: funky result: %d. Please notify the maintainer.", result);
                        ret = -EIO;
                        break;
                } 
@@ -223,7 +217,7 @@ write_scanner(struct file * file, const char * buffer,
                if (partial) {
                        unsigned char cnt, cnt_max;
                        cnt_max = (partial > 24) ? 24 : partial;
-                       printk(KERN_DEBUG "dump: ");
+                       printk(KERN_DEBUG __FILE__ ": dump: ");
                        for (cnt=0; cnt < cnt_max; cnt++) {
                                printk("%X ", obuf[cnt]);
                        }
@@ -277,14 +271,14 @@ read_scanner(struct file * file, char * buffer,
                this_read = (count > IBUF_SIZE) ? IBUF_SIZE : count;
                
                result = usb_bulk_msg(hps->hpscan_dev, usb_rcvbulkpipe(hps->hpscan_dev, hps->iep), ibuf, this_read, &partial, 60*HZ);
-               SCN_DEBUG(printk(KERN_DEBUG "read stats: result:%d this_read:%u partial:%lu\n", (int)result, this_read, partial);)
+               dbg("read stats: result:%d this_read:%u partial:%lu", (int)result, this_read, partial);
 
                if (result == USB_ST_TIMEOUT) { /* NAK -- shouldn't happen */
-                       printk(KERN_WARNING "read_scanner: NAK received\n");
+                       warn("read_scanner: NAK received");
                        ret = -ETIME;
                        break;
                } else if ((result < 0) && (result != USB_ST_DATAUNDERRUN)) {
-                       printk(KERN_WARNING "read_scanner: funky result: %d. Please notify the maintainer.\n", (int)result);
+                       warn("read_scanner: funky result: %d. Please notify the maintainer.", (int)result);
                        ret = -EIO;
                        break;
                }
@@ -293,7 +287,7 @@ read_scanner(struct file * file, char * buffer,
                if (partial) {
                        unsigned char cnt, cnt_max;
                        cnt_max = (partial > 24) ? 24 : partial;
-                       printk(KERN_DEBUG "dump: ");
+                       printk(KERN_DEBUG __FILE__ ": dump: ");
                        for (cnt=0; cnt < cnt_max; cnt++) {
                                printk("%X ", ibuf[cnt]);
                        }
@@ -333,9 +327,8 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum)
 
        hps->present = 0;
 
-       if (vendor != 0 || product != 0) {
-               printk(KERN_INFO "USB Scanner Vendor:Product - %x:%x\n", vendor, product);
-       }
+       if (vendor != 0 || product != 0)
+               info("USB Scanner Vendor:Product - %x:%x\n", vendor, product);
 
 /* There doesn't seem to be an imaging class defined in the USB
  * Spec. (yet).  If there is, HP isn't following it and it doesn't
@@ -377,7 +370,7 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum)
 
        if (dev->descriptor.bNumConfigurations != 1 || 
            dev->config[0].bNumInterfaces != 1) {
-               printk(KERN_INFO "probe_scanner: only simple configurations supported\n");
+               dbg("probe_scanner: only simple configurations supported");
                return NULL;
        }
 
@@ -385,12 +378,12 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum)
 
        if (endpoint[0].bmAttributes != USB_ENDPOINT_XFER_BULK
            || endpoint [1].bmAttributes != USB_ENDPOINT_XFER_BULK) {
-               printk(KERN_INFO "probe_scanner: invalid bulk endpoints\n");
+               dbg("probe_scanner: invalid bulk endpoints");
                return NULL;
        }
 
        if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) {
-                printk (KERN_INFO "probe_scanner: failed usb_set_configuration\n");
+                dbg("probe_scanner: failed usb_set_configuration");
                hps->hpscan_dev = NULL;
                 return NULL;
         }
@@ -418,10 +411,10 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum)
        }
 
        ident = usb_string(dev, dev->descriptor.iProduct); /* usb_string allocates memory using kmalloc() so kfree() needs to be called afterwards when the pointer is no longer needed. */
-       printk(KERN_INFO "USB Scanner (%s) found at address %d\n", ident, dev->devnum);
+       info("USB Scanner (%s) found at address %d", ident, dev->devnum);
        kfree(ident);
 
-       SCN_DEBUG(printk(KERN_DEBUG "probe_scanner: using bulk endpoints - In: %x  Out: %x\n", hps->iep, hps->oep);)
+       dbg("probe_scanner: using bulk endpoints - In: %x  Out: %x", hps->iep, hps->oep);
 
        hps->present = 1;
        hps->hpscan_dev = dev;
@@ -485,7 +478,7 @@ usb_scanner_init(void)
         if (usb_register(&scanner_driver) < 0)
                 return -1;
 
-       printk(KERN_INFO "USB Scanner support registered.\n");
+       info("USB Scanner support registered.");
        return 0;
 }
 
index 3d2f621950451932538d747e6e4f2d7152100d0c..2ecd611e6e62659386ce154133625dfd87abf373 100644 (file)
@@ -1,40 +1,34 @@
 /*
  * $Id: uhci-debug.c,v 1.12 1999/12/13 15:24:42 fliegl Exp $
  */
+
 #include <linux/version.h>
 #include <linux/kernel.h>
 #include <asm/io.h>
 
+#define DEBUG
+
 #include "usb.h"
 #include "uhci.h"
-#define DEBUG
-#ifdef DEBUG
-#define dbg printk
-#else
-#define dbg nix
-static void nix (const char *format,...)
-{
-}
 
-#endif
 void dump_urb (purb_t purb)
 {
-       printk ("urb                   :%p\n", purb);
-       printk ("next                  :%p\n", purb->next);
-       printk ("dev                   :%p\n", purb->dev);
-       printk ("pipe                  :%08X\n", purb->pipe);
-       printk ("status                :%d\n", purb->status);
-       printk ("transfer_flags        :%08X\n", purb->transfer_flags);
-       printk ("transfer_buffer       :%p\n", purb->transfer_buffer);
-       printk ("transfer_buffer_length:%d\n", purb->transfer_buffer_length);
-       printk ("actual_length         :%d\n", purb->actual_length);
-       printk ("setup_packet          :%p\n", purb->setup_packet);
-       printk ("start_frame           :%d\n", purb->start_frame);
-       printk ("number_of_packets     :%d\n", purb->number_of_packets);
-       printk ("interval              :%d\n", purb->interval);
-       printk ("error_count           :%d\n", purb->error_count);
-       printk ("context               :%p\n", purb->context);
-       printk ("complete              :%p\n", purb->complete);
+       dbg("urb                   :%p", purb);
+       dbg("next                  :%p", purb->next);
+       dbg("dev                   :%p", purb->dev);
+       dbg("pipe                  :%08X", purb->pipe);
+       dbg("status                :%d", purb->status);
+       dbg("transfer_flags        :%08X", purb->transfer_flags);
+       dbg("transfer_buffer       :%p", purb->transfer_buffer);
+       dbg("transfer_buffer_length:%d", purb->transfer_buffer_length);
+       dbg("actual_length         :%d", purb->actual_length);
+       dbg("setup_packet          :%p", purb->setup_packet);
+       dbg("start_frame           :%d", purb->start_frame);
+       dbg("number_of_packets     :%d", purb->number_of_packets);
+       dbg("interval              :%d", purb->interval);
+       dbg("error_count           :%d", purb->error_count);
+       dbg("context               :%p", purb->context);
+       dbg("complete              :%p", purb->complete);
 }
 
 void beep (long freq)
@@ -61,37 +55,36 @@ void beep (long freq)
 void uhci_show_qh (puhci_desc_t qh)
 {
        if (qh->type != QH_TYPE) {
-               dbg (KERN_DEBUG MODSTR "qh has not QH_TYPE\n");
+               dbg("qh has not QH_TYPE");
                return;
        }
-       dbg (KERN_DEBUG MODSTR "uhci_show_qh %p (%08lX):\n", qh, virt_to_bus (qh));
+       dbg("uhci_show_qh %p (%08lX):", qh, virt_to_bus (qh));
 
        if (qh->hw.qh.head & UHCI_PTR_TERM)
-               dbg (KERN_DEBUG MODSTR "Head Terminate\n");
+               dbg("Head Terminate");
        else {
                if (qh->hw.qh.head & UHCI_PTR_QH)
-                       dbg (KERN_DEBUG MODSTR "Head points to QH\n");
+                       dbg("Head points to QH");
                else
-                       dbg (KERN_DEBUG MODSTR "Head points to TD\n");
+                       dbg("Head points to TD");
 
-               dbg (KERN_DEBUG MODSTR "head: %08X\n", qh->hw.qh.head & ~UHCI_PTR_BITS);
+               dbg("head: %08X", qh->hw.qh.head & ~UHCI_PTR_BITS);
        }
        if (qh->hw.qh.element & UHCI_PTR_TERM)
-               dbg (KERN_DEBUG MODSTR "Element Terminate\n");
+               dbg("Element Terminate");
        else {
 
                if (qh->hw.qh.element & UHCI_PTR_QH)
-                       dbg (KERN_DEBUG MODSTR "Element points to QH\n");
+                       dbg("Element points to QH");
                else
-                       dbg (KERN_DEBUG MODSTR "Element points to TD\n");
-               dbg (KERN_DEBUG MODSTR "element: %08X\n", qh->hw.qh.element & ~UHCI_PTR_BITS);
+                       dbg("Element points to TD");
+               dbg("element: %08X", qh->hw.qh.element & ~UHCI_PTR_BITS);
        }
 }
 
 void uhci_show_td (puhci_desc_t td)
 {
        char *spid;
-       dbg (KERN_DEBUG MODSTR "uhci_show_td %p (%08lX) ", td, virt_to_bus (td));
 
        switch (td->hw.td.info & 0xff) {
        case USB_PID_SETUP:
@@ -108,7 +101,9 @@ void uhci_show_td (puhci_desc_t td)
                break;
        }
 
-       dbg ("MaxLen=%02x DT%d EndPt=%x Dev=%x, PID=%x(%s) (buf=%08x)\n",
+       dbg("uhci_show_td %p (%08lX) MaxLen=%02x DT%d EndPt=%x Dev=%x, PID=%x(%s) (buf=%08x)",
+            td,
+            virt_to_bus(td),
             td->hw.td.info >> 21,
             ((td->hw.td.info >> 19) & 1),
             (td->hw.td.info >> 15) & 15,
@@ -117,7 +112,7 @@ void uhci_show_td (puhci_desc_t td)
             spid,
             td->hw.td.buffer);
 
-       dbg (KERN_DEBUG MODSTR "Len=%02x e%d %s%s%s%s%s%s%s%s%s%s\n",
+       dbg("Len=%02x e%d %s%s%s%s%s%s%s%s%s%s",
             td->hw.td.status & 0x7ff,
             ((td->hw.td.status >> 27) & 3),
             (td->hw.td.status & TD_CTRL_SPD) ? "SPD " : "",
@@ -131,25 +126,24 @@ void uhci_show_td (puhci_desc_t td)
             (td->hw.td.status & TD_CTRL_CRCTIMEO) ? "CRC/Timeo " : "",
             (td->hw.td.status & TD_CTRL_BITSTUFF) ? "BitStuff " : ""
                );
-#if 1
+
        if (td->hw.td.link & UHCI_PTR_TERM)
-               dbg (KERN_DEBUG MODSTR "Link Terminate\n");
+               dbg("Link Terminate");
        else {
                if (td->hw.td.link & UHCI_PTR_QH)
-                       dbg (KERN_DEBUG MODSTR "%s, link points to QH @ %08x\n",
+                       dbg("%s, link points to QH @ %08x",
                             (td->hw.td.link & UHCI_PTR_DEPTH ? "Depth first" : " Breadth first"),
                             td->hw.td.link & ~UHCI_PTR_BITS);
                else
-                       dbg (KERN_DEBUG MODSTR "%s, link points to TD @ %08x \n",
+                       dbg("%s, link points to TD @ %08x",
                             (td->hw.td.link & UHCI_PTR_DEPTH ? "Depth first" : " Breadth first"),
                             td->hw.td.link & ~UHCI_PTR_BITS);
        }
-#endif
 }
 
 void uhci_show_td_queue (puhci_desc_t td)
 {
-       dbg (KERN_DEBUG MODSTR "uhci_show_td_queue %p (%08lX):\n", td, virt_to_bus (td));
+       dbg("uhci_show_td_queue %p (%08lX):", td, virt_to_bus (td));
        while (1) {
                uhci_show_td (td);
                if (td->hw.td.link & UHCI_PTR_TERM)
@@ -159,7 +153,7 @@ void uhci_show_td_queue (puhci_desc_t td)
                if (td != bus_to_virt (td->hw.td.link & ~UHCI_PTR_BITS))
                        td = bus_to_virt (td->hw.td.link & ~UHCI_PTR_BITS);
                else {
-                       dbg (KERN_DEBUG MODSTR "td points to itself!\n");
+                       dbg("td points to itself!");
                        break;
                }
 //              schedule();
@@ -168,12 +162,12 @@ void uhci_show_td_queue (puhci_desc_t td)
 
 void uhci_show_queue (puhci_desc_t qh)
 {
-       dbg (KERN_DEBUG MODSTR "uhci_show_queue %p:\n", qh);
+       dbg("uhci_show_queue %p:", qh);
        while (1) {
                uhci_show_qh (qh);
 
                if (qh->hw.qh.element & UHCI_PTR_QH)
-                       dbg (KERN_DEBUG MODSTR "Warning: qh->element points to qh!\n");
+                       dbg("Warning: qh->element points to qh!");
                else if (!(qh->hw.qh.element & UHCI_PTR_TERM))
                        uhci_show_td_queue (bus_to_virt (qh->hw.qh.element & ~UHCI_PTR_BITS));
 
@@ -183,7 +177,7 @@ void uhci_show_queue (puhci_desc_t qh)
                if (qh != bus_to_virt (qh->hw.qh.head & ~UHCI_PTR_BITS))
                        qh = bus_to_virt (qh->hw.qh.head & ~UHCI_PTR_BITS);
                else {
-                       dbg (KERN_DEBUG MODSTR "qh points to itself!\n");
+                       dbg("qh points to itself!");
                        break;
                }
        }
@@ -191,7 +185,7 @@ void uhci_show_queue (puhci_desc_t qh)
 
 static void uhci_show_sc (int port, unsigned short status)
 {
-       dbg ("  stat%d     =     %04x   %s%s%s%s%s%s%s%s\n",
+       dbg("  stat%d     =     %04x   %s%s%s%s%s%s%s%s",
             port,
             status,
             (status & USBPORTSC_SUSP) ? "PortSuspend " : "",
@@ -221,7 +215,7 @@ void uhci_show_status (puhci_t s)
        portsc1 = inw (io_addr + 16);
        portsc2 = inw (io_addr + 18);
 
-       dbg ("  usbcmd    =     %04x   %s%s%s%s%s%s%s%s\n",
+       dbg("  usbcmd    =     %04x   %s%s%s%s%s%s%s%s",
             usbcmd,
             (usbcmd & USBCMD_MAXP) ? "Maxp64 " : "Maxp32 ",
             (usbcmd & USBCMD_CF) ? "CF " : "",
@@ -232,7 +226,7 @@ void uhci_show_status (puhci_t s)
             (usbcmd & USBCMD_HCRESET) ? "HCRESET " : "",
             (usbcmd & USBCMD_RS) ? "RS " : "");
 
-       dbg ("  usbstat   =     %04x   %s%s%s%s%s%s\n",
+       dbg("  usbstat   =     %04x   %s%s%s%s%s%s",
             usbstat,
             (usbstat & USBSTS_HCH) ? "HCHalted " : "",
             (usbstat & USBSTS_HCPE) ? "HostControllerProcessError " : "",
@@ -241,11 +235,11 @@ void uhci_show_status (puhci_t s)
             (usbstat & USBSTS_ERROR) ? "USBError " : "",
             (usbstat & USBSTS_USBINT) ? "USBINT " : "");
 
-       dbg ("  usbint    =     %04x\n", usbint);
-       dbg ("  usbfrnum  =   (%d)%03x\n", (usbfrnum >> 10) & 1,
+       dbg("  usbint    =     %04x", usbint);
+       dbg("  usbfrnum  =   (%d)%03x", (usbfrnum >> 10) & 1,
             0xfff & (4 * (unsigned int) usbfrnum));
-       dbg ("  flbaseadd = %08x\n", flbaseadd);
-       dbg ("  sof       =       %02x\n", sof);
+       dbg("  flbaseadd = %08x", flbaseadd);
+       dbg("  sof       =       %02x", sof);
        uhci_show_sc (1, portsc1);
        uhci_show_sc (2, portsc2);
 }
index c071f5192e5cfc67c7bdd10a359d219ff9dd6e1b..09dc04283837509b4be89760b157ce8ba0e6a3c3 100644 (file)
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
-//#include <asm/spinlock.h>
+
+#undef DEBUG
 
 #include "usb.h"
 #include "uhci.h"
 #include "uhci-debug.h"
 
-//#define DEBUG
-#ifdef DEBUG
-#define dbg(format, args...) printk(format, ## args)
-#else
-#define dbg(format, args...)
-#endif
-
-#define _static static
-
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
 #define __init 
 #define __exit
@@ -85,7 +77,7 @@ static int rh_unlink_urb (purb_t purb);
 static puhci_t devs = NULL;
 
 /*-------------------------------------------------------------------*/
-_static void queue_urb (puhci_t s, struct list_head *p, int do_lock)
+static void queue_urb (puhci_t s, struct list_head *p, int do_lock)
 {
        unsigned long flags=0;
 
@@ -99,7 +91,7 @@ _static void queue_urb (puhci_t s, struct list_head *p, int do_lock)
 }
 
 /*-------------------------------------------------------------------*/
-_static void dequeue_urb (puhci_t s, struct list_head *p, int do_lock)
+static void dequeue_urb (puhci_t s, struct list_head *p, int do_lock)
 {
        unsigned long flags=0;
        
@@ -113,7 +105,7 @@ _static void dequeue_urb (puhci_t s, struct list_head *p, int do_lock)
 }
 
 /*-------------------------------------------------------------------*/
-_static int alloc_td (puhci_desc_t * new, int flags)
+static int alloc_td (puhci_desc_t * new, int flags)
 {
 #ifdef _UHCI_SLAB
        *new= kmem_cache_alloc(uhci_desc_kmem, in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL);
@@ -134,7 +126,7 @@ _static int alloc_td (puhci_desc_t * new, int flags)
 }
 /*-------------------------------------------------------------------*/
 /* insert td at last position in td-list of qh (vertical) */
-_static int insert_td (puhci_t s, puhci_desc_t qh, puhci_desc_t new, int flags)
+static int insert_td (puhci_t s, puhci_desc_t qh, puhci_desc_t new, int flags)
 {
        uhci_desc_t *prev;
        unsigned long xxx;
@@ -160,7 +152,7 @@ _static int insert_td (puhci_t s, puhci_desc_t qh, puhci_desc_t new, int flags)
 }
 /*-------------------------------------------------------------------*/
 /* insert new_td after td (horizontal) */
-_static int insert_td_horizontal (puhci_t s, puhci_desc_t td, puhci_desc_t new, int flags)
+static int insert_td_horizontal (puhci_t s, puhci_desc_t td, puhci_desc_t new, int flags)
 {
        uhci_desc_t *next;
        unsigned long xxx;
@@ -177,7 +169,7 @@ _static int insert_td_horizontal (puhci_t s, puhci_desc_t td, puhci_desc_t new,
        return 0;
 }
 /*-------------------------------------------------------------------*/
-_static int unlink_td (puhci_t s, puhci_desc_t element)
+static int unlink_td (puhci_t s, puhci_desc_t element)
 {
        uhci_desc_t *next, *prev;
        int dir = 0;
@@ -213,7 +205,7 @@ _static int unlink_td (puhci_t s, puhci_desc_t element)
        return 0;
 }
 /*-------------------------------------------------------------------*/
-_static int delete_desc (puhci_desc_t element)
+static int delete_desc (puhci_desc_t element)
 {
 #ifdef _UHCI_SLAB
        kmem_cache_free(uhci_desc_kmem, element);
@@ -224,7 +216,7 @@ _static int delete_desc (puhci_desc_t element)
 }
 /*-------------------------------------------------------------------*/
 // Allocates qh element
-_static int alloc_qh (puhci_desc_t * new)
+static int alloc_qh (puhci_desc_t * new)
 {
 #ifdef _UHCI_SLAB
        *new= kmem_cache_alloc(uhci_desc_kmem, in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL);
@@ -241,14 +233,14 @@ _static int alloc_qh (puhci_desc_t * new)
        INIT_LIST_HEAD (&(*new)->horizontal);
        INIT_LIST_HEAD (&(*new)->vertical);
        
-       dbg (KERN_DEBUG MODSTR "Allocated qh @ %p\n", *new);
+       dbg("Allocated qh @ %p", *new);
        
        return 0;
 }
 /*-------------------------------------------------------------------*/
 // inserts new qh before/after the qh at pos
 // flags: 0: insert before pos, 1: insert after pos (for low speed transfers)
-_static int insert_qh (puhci_t s, puhci_desc_t pos, puhci_desc_t new, int flags)
+static int insert_qh (puhci_t s, puhci_desc_t pos, puhci_desc_t new, int flags)
 {
        puhci_desc_t old;
        unsigned long xxx;
@@ -279,7 +271,7 @@ _static int insert_qh (puhci_t s, puhci_desc_t pos, puhci_desc_t new, int flags)
        return 0;
 }
 /*-------------------------------------------------------------------*/
-_static int unlink_qh (puhci_t s, puhci_desc_t element)
+static int unlink_qh (puhci_t s, puhci_desc_t element)
 {
        puhci_desc_t next, prev;
        unsigned long xxx;
@@ -297,7 +289,7 @@ _static int unlink_qh (puhci_t s, puhci_desc_t element)
        return 0;
 }
 /*-------------------------------------------------------------------*/
-_static int delete_qh (puhci_t s, puhci_desc_t qh)
+static int delete_qh (puhci_t s, puhci_desc_t qh)
 {
        puhci_desc_t td;
        struct list_head *p;
@@ -332,12 +324,12 @@ void clean_td_chain (puhci_desc_t td)
 }
 /*-------------------------------------------------------------------*/
 // Removes ALL qhs in chain (paranoia!)
-_static void cleanup_skel (puhci_t s)
+static void cleanup_skel (puhci_t s)
 {
        unsigned int n;
        puhci_desc_t td;
 
-       printk (KERN_DEBUG MODSTR "Cleanup_skel\n");
+       dbg("cleanup_skel");
        
        for (n = 0; n < 8; n++) {
                td = s->int_chain[n];
@@ -379,12 +371,12 @@ _static void cleanup_skel (puhci_t s)
 /*-------------------------------------------------------------------*/
 // allocates framelist and qh-skeletons
 // only HW-links provide continous linking, SW-links stay in their domain (ISO/INT)
-_static int init_skel (puhci_t s)
+static int init_skel (puhci_t s)
 {
        int n, ret;
        puhci_desc_t qh, td;
        
-       dbg (KERN_DEBUG MODSTR "init_skel\n");
+       dbg("init_skel");
        
        s->framelist = (__u32 *) get_free_page (GFP_KERNEL);
 
@@ -393,7 +385,7 @@ _static int init_skel (puhci_t s)
 
        memset (s->framelist, 0, 4096);
 
-       dbg (KERN_DEBUG MODSTR "allocating iso desc pointer list\n");
+       dbg("allocating iso desc pointer list");
        s->iso_td = (puhci_desc_t *) kmalloc (1024 * sizeof (puhci_desc_t), GFP_KERNEL);
        
        if (!s->iso_td)
@@ -403,7 +395,7 @@ _static int init_skel (puhci_t s)
        s->bulk_chain = NULL;
        s->chain_end = NULL;
 
-       dbg (KERN_DEBUG MODSTR "allocating iso descs\n");
+       dbg("allocating iso descs");
        for (n = 0; n < 1024; n++) {
                // allocate skeleton iso/irq-tds
                ret = alloc_td (&td, 0);
@@ -413,7 +405,7 @@ _static int init_skel (puhci_t s)
                s->framelist[n] = ((__u32) virt_to_bus (td));
        }
 
-       dbg (KERN_DEBUG MODSTR "allocating qh: chain_end\n");
+       dbg("allocating qh: chain_end");
        ret = alloc_qh (&qh);
        
        if (ret)
@@ -421,7 +413,7 @@ _static int init_skel (puhci_t s)
        
        s->chain_end = qh;
 
-       dbg (KERN_DEBUG MODSTR "allocating qh: bulk_chain\n");
+       dbg("allocating qh: bulk_chain");
        ret = alloc_qh (&qh);
        
        if (ret)
@@ -429,7 +421,7 @@ _static int init_skel (puhci_t s)
        
        insert_qh (s, s->chain_end, qh, 0);
        s->bulk_chain = qh;
-       dbg (KERN_DEBUG MODSTR "allocating qh: control_chain\n");
+       dbg("allocating qh: control_chain");
        ret = alloc_qh (&qh);
        
        if (ret)
@@ -440,7 +432,7 @@ _static int init_skel (puhci_t s)
        for (n = 0; n < 8; n++)
                s->int_chain[n] = 0;
 
-       dbg (KERN_DEBUG MODSTR "Allocating skeleton INT-TDs\n");
+       dbg("allocating skeleton INT-TDs");
        
        for (n = 0; n < 8; n++) {
                puhci_desc_t td;
@@ -457,12 +449,12 @@ _static int init_skel (puhci_t s)
                }
        }
 
-       dbg (KERN_DEBUG MODSTR "Linking skeleton INT-TDs\n");
+       dbg("linking skeleton INT-TDs");
        
        for (n = 0; n < 1024; n++) {
                // link all iso-tds to the interrupt chains
                int m, o;
-               //dbg("framelist[%i]=%x\n",n,s->framelist[n]);
+               //dbg("framelist[%i]=%x",n,s->framelist[n]);
                for (o = 1, m = 2; m <= 128; o++, m += m) {
                        // n&(m-1) = n%m
                        if ((n & (m - 1)) == ((m - 1) / 2)) {
@@ -472,7 +464,7 @@ _static int init_skel (puhci_t s)
        }
 
        //uhci_show_queue(s->control_chain);   
-       dbg (KERN_DEBUG MODSTR "init_skel exit\n");
+       dbg("init_skel exit");
        return 0;               // OK
 
       init_skel_cleanup:
@@ -481,7 +473,7 @@ _static int init_skel (puhci_t s)
 }
 
 /*-------------------------------------------------------------------*/
-_static void fill_td (puhci_desc_t td, int status, int info, __u32 buffer)
+static void fill_td (puhci_desc_t td, int status, int info, __u32 buffer)
 {
        td->hw.td.status = status;
        td->hw.td.info = info;
@@ -492,7 +484,7 @@ _static void fill_td (puhci_desc_t td, int status, int info, __u32 buffer)
 //                         LOW LEVEL STUFF
 //          assembles QHs und TDs for control, bulk and iso
 /*-------------------------------------------------------------------*/
-_static int uhci_submit_control_urb (purb_t purb)
+static int uhci_submit_control_urb (purb_t purb)
 {
        puhci_desc_t qh, td;
        puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
@@ -502,7 +494,7 @@ _static int uhci_submit_control_urb (purb_t purb)
        unsigned long len, bytesrequested;
        char *data;
 
-       dbg (KERN_DEBUG MODSTR "uhci_submit_control start\n");
+       dbg("uhci_submit_control start");
        alloc_qh (&qh);         // alloc qh for this request
 
        if (!qh)
@@ -535,7 +527,7 @@ _static int uhci_submit_control_urb (purb_t purb)
 
        insert_td (s, qh, td, 0);       // queue 'setup stage'-td in qh
 #if 0
-       printk ("SETUP to pipe %x: %x %x %x %x %x %x %x %x\n", purb->pipe,
+       dbg("SETUP to pipe %x: %x %x %x %x %x %x %x %x", purb->pipe,
                purb->setup_packet[0], purb->setup_packet[1], purb->setup_packet[2], purb->setup_packet[3],
                purb->setup_packet[4], purb->setup_packet[5], purb->setup_packet[6], purb->setup_packet[7]);
        //uhci_show_td(td);
@@ -602,11 +594,11 @@ _static int uhci_submit_control_urb (purb_t purb)
                insert_qh (s, s->bulk_chain, qh, 0);    // insert before bulk chain
        //uhci_show_queue(s->control_chain);
 
-       dbg (KERN_DEBUG MODSTR "uhci_submit_control end\n");
+       dbg("uhci_submit_control end");
        return 0;
 }
 /*-------------------------------------------------------------------*/
-_static int uhci_submit_bulk_urb (purb_t purb)
+static int uhci_submit_bulk_urb (purb_t purb)
 {
        puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
        purb_priv_t purb_priv = purb->hcpriv;
@@ -641,7 +633,7 @@ _static int uhci_submit_bulk_urb (purb_t purb)
        /* Build the TDs for the bulk request */
        len = purb->transfer_buffer_length;
        data = purb->transfer_buffer;
-       dbg (KERN_DEBUG MODSTR "uhci_submit_bulk_urb: pipe %x, len %d\n", pipe, len);
+       dbg("uhci_submit_bulk_urb: pipe %x, len %d", pipe, len);
        
        while (len > 0) {
                int pktsze = len;
@@ -667,7 +659,7 @@ _static int uhci_submit_bulk_urb (purb_t purb)
 
                if (!len)
                        td->hw.td.status |= TD_CTRL_IOC;        // last one generates INT
-               //dbg("insert td %p, len %i\n",td,pktsze);
+               //dbg("insert td %p, len %i",td,pktsze);
 
                insert_td (s, qh, td, UHCI_PTR_DEPTH);
                
@@ -680,14 +672,14 @@ _static int uhci_submit_bulk_urb (purb_t purb)
        insert_qh (s, s->chain_end, qh, 0);     // insert before end marker
        //uhci_show_queue(s->bulk_chain);
 
-       dbg (KERN_DEBUG MODSTR "uhci_submit_bulk_urb: exit\n");
+       dbg("uhci_submit_bulk_urb: exit");
        return 0;
 }
 /*-------------------------------------------------------------------*/
 // unlinks an urb by dequeuing its qh, waits some frames and forgets it
 // Problem: unlinking in interrupt requires waiting for one frame (udelay)
 // to allow the whole structures to be safely removed
-_static int uhci_unlink_urb (purb_t purb)
+static int uhci_unlink_urb (purb_t purb)
 {
        puhci_t s;
        puhci_desc_t qh;
@@ -709,7 +701,7 @@ _static int uhci_unlink_urb (purb_t purb)
                spin_lock_irqsave (&s->unlink_urb_lock, flags);         // do not allow interrupts
        }
        
-       //dbg("unlink_urb called %p\n",purb);
+       //dbg("unlink_urb called %p",purb);
        if (purb->status == USB_ST_URB_PENDING) {
                // URB probably still in work
                purb_priv = purb->hcpriv;
@@ -760,7 +752,7 @@ _static int uhci_unlink_urb (purb_t purb)
                kfree (purb->hcpriv);
 #endif
                if (purb->complete) {
-                       dbg (KERN_DEBUG MODSTR "unlink_urb: calling completion\n");
+                       dbg("unlink_urb: calling completion");
                        purb->complete ((struct urb *) purb);
                        usb_dec_dev_use (purb->dev);
                }
@@ -777,7 +769,7 @@ _static int uhci_unlink_urb (purb_t purb)
 // In case of ASAP iso transfer, search the URB-list for already queued URBs
 // for this EP and calculate the earliest start frame for the new
 // URB (easy seamless URB continuation!)
-_static int find_iso_limits (purb_t purb, unsigned int *start, unsigned int *end)
+static int find_iso_limits (purb_t purb, unsigned int *start, unsigned int *end)
 {
        purb_t u, last_urb = NULL;
        puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
@@ -811,18 +803,18 @@ _static int find_iso_limits (purb_t purb, unsigned int *start, unsigned int *end
 /*-------------------------------------------------------------------*/
 // adjust start_frame according to scheduling constraints (ASAP etc)
 
-_static void jnx_show_desc (puhci_desc_t d)
+static void jnx_show_desc (puhci_desc_t d)
 {
        switch (d->type) {
        case TD_TYPE:
-               printk (KERN_DEBUG MODSTR "td @ 0x%08lx: link 0x%08x status 0x%08x info 0x%08x buffer 0x%08x\n",
+               dbg("td @ 0x%08lx: link 0x%08x status 0x%08x info 0x%08x buffer 0x%08x",
                        (unsigned long) d, d->hw.td.link, d->hw.td.status, d->hw.td.info, d->hw.td.buffer);
                if (!(d->hw.td.link & UHCI_PTR_TERM))
                        jnx_show_desc ((puhci_desc_t) bus_to_virt (d->hw.td.link & ~UHCI_PTR_BITS));
                break;
 
        case QH_TYPE:
-               printk (KERN_DEBUG MODSTR "qh @ 0x%08lx: head 0x%08x element 0x%08x\n",
+               dbg("qh @ 0x%08lx: head 0x%08x element 0x%08x",
                        (unsigned long) d, d->hw.qh.head, d->hw.qh.element);
                if (!(d->hw.qh.element & UHCI_PTR_TERM))
                        jnx_show_desc ((puhci_desc_t) bus_to_virt (d->hw.qh.element & ~UHCI_PTR_BITS));
@@ -831,13 +823,12 @@ _static void jnx_show_desc (puhci_desc_t d)
                break;
 
        default:
-               printk (KERN_DEBUG MODSTR "desc @ 0x%08lx: invalid type %u\n",
-                       (unsigned long) d, d->type);
+               dbg("desc @ 0x%08lx: invalid type %u", (unsigned long) d, d->type);
        }
 }
 
 /*-------------------------------------------------------------------*/
-_static int iso_find_start (purb_t purb)
+static int iso_find_start (purb_t purb)
 {
        puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
        unsigned int now;
@@ -862,8 +853,8 @@ _static int iso_find_start (purb_t purb)
                        purb->start_frame = stop_limit;         //seamless linkage
 
                        if (((now - purb->start_frame) & 1023) <= (unsigned) purb->number_of_packets) {
-                               printk (KERN_DEBUG MODSTR "iso_find_start: warning, ASAP gap, should not happen\n");
-                               printk (KERN_DEBUG MODSTR "iso_find_start: now %u start_frame %u number_of_packets %u pipe 0x%08x\n",
+                               dbg("iso_find_start: warning, ASAP gap, should not happen");
+                               dbg("iso_find_start: now %u start_frame %u number_of_packets %u pipe 0x%08x",
                                        now, purb->start_frame, purb->number_of_packets, purb->pipe);
                                {
                                        puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
@@ -879,7 +870,7 @@ _static int iso_find_start (purb_t purb)
                                                u = list_entry (p, urb_t, urb_list);
                                                if (purb->dev != u->dev)
                                                        continue;
-                                               printk (KERN_DEBUG MODSTR "urb: pipe 0x%08x status %d start_frame %u number_of_packets %u\n",
+                                               dbg("urb: pipe 0x%08x status %d start_frame %u number_of_packets %u",
                                                        u->pipe, u->status, u->start_frame, u->number_of_packets);
                                                if (!usb_pipeisoc (u->pipe))
                                                        continue;
@@ -907,7 +898,7 @@ _static int iso_find_start (purb_t purb)
        else {
                purb->start_frame &= 1023;
                if (((now - purb->start_frame) & 1023) < (unsigned) purb->number_of_packets) {
-                       printk (KERN_DEBUG MODSTR "iso_find_start: now between start_frame and end\n");
+                       dbg("iso_find_start: now between start_frame and end");
                        return -EAGAIN;
                }
        }
@@ -917,7 +908,7 @@ _static int iso_find_start (purb_t purb)
                return 0;
        if (((purb->start_frame - start_limit) & 1023) < queued_size ||
            ((purb->start_frame + purb->number_of_packets - 1 - start_limit) & 1023) < queued_size) {
-               printk (KERN_DEBUG MODSTR "iso_find_start: start_frame %u number_of_packets %u start_limit %u stop_limit %u\n",
+               dbg("iso_find_start: start_frame %u number_of_packets %u start_limit %u stop_limit %u",
                        purb->start_frame, purb->number_of_packets, start_limit, stop_limit);
                return -EAGAIN;
        }
@@ -929,7 +920,7 @@ _static int iso_find_start (purb_t purb)
 // ASAP-flag set implicitely
 // if period==0, the the transfer is only done once (usb_scsi need this...)
 
-_static int uhci_submit_int_urb (purb_t purb)
+static int uhci_submit_int_urb (purb_t purb)
 {
        puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
        purb_priv_t purb_priv = purb->hcpriv;
@@ -940,7 +931,7 @@ _static int uhci_submit_int_urb (purb_t purb)
        int info;
        unsigned int pipe = purb->pipe;
 
-       //printk("SUBMIT INT\n");
+       //dbg("SUBMIT INT");
 
        if (purb->interval < 0 || purb->interval >= 256)
                return -EINVAL;
@@ -957,7 +948,7 @@ _static int uhci_submit_int_urb (purb_t purb)
                }
                nint--;
        }
-       dbg(KERN_INFO "Rounded interval to %i, chain  %i\n", purb->interval, nint);
+       dbg("Rounded interval to %i, chain  %i", purb->interval, nint);
 
        now = UHCI_GET_CURRENT_FRAME (s) & 1023;
        purb->start_frame = now;        // remember start frame, just in case...
@@ -998,7 +989,7 @@ _static int uhci_submit_int_urb (purb_t purb)
        return 0;
 }
 /*-------------------------------------------------------------------*/
-_static int uhci_submit_iso_urb (purb_t purb)
+static int uhci_submit_iso_urb (purb_t purb)
 {
        puhci_t s = (puhci_t) purb->dev->bus->hcpriv;
        purb_priv_t purb_priv = purb->hcpriv;
@@ -1025,7 +1016,7 @@ _static int uhci_submit_iso_urb (purb_t purb)
 
        // First try to get all TDs
        for (n = 0; n < purb->number_of_packets; n++) {
-               dbg (KERN_DEBUG MODSTR "n:%d purb->iso_frame_desc[n].length:%d\n", n, purb->iso_frame_desc[n].length);
+               dbg("n:%d purb->iso_frame_desc[n].length:%d", n, purb->iso_frame_desc[n].length);
                if (!purb->iso_frame_desc[n].length) {
                        // allows ISO striping by setting length to zero in iso_descriptor
                        tdm[n] = 0;
@@ -1066,7 +1057,7 @@ _static int uhci_submit_iso_urb (purb_t purb)
        }
 
        kfree (tdm);
-       dbg ("ISO-INT# %i, start %i, now %i\n", purb->number_of_packets, purb->start_frame, UHCI_GET_CURRENT_FRAME (s) & 1023);
+       dbg("ISO-INT# %i, start %i, now %i", purb->number_of_packets, purb->start_frame, UHCI_GET_CURRENT_FRAME (s) & 1023);
        ret = 0;
 
       err:
@@ -1075,18 +1066,18 @@ _static int uhci_submit_iso_urb (purb_t purb)
 
 }
 /*-------------------------------------------------------------------*/
-_static int search_dev_ep (puhci_t s, purb_t purb)
+static int search_dev_ep (puhci_t s, purb_t purb)
 {
        unsigned long flags;
        struct list_head *p = s->urb_list.next;
        purb_t tmp;
 
-       dbg (KERN_DEBUG MODSTR "search_dev_ep:\n");
+       dbg("search_dev_ep:");
        spin_lock_irqsave (&s->urb_list_lock, flags);
 
        for (; p != &s->urb_list; p = p->next) {
                tmp = list_entry (p, urb_t, urb_list);
-               dbg (KERN_DEBUG MODSTR "urb: %p\n", tmp);
+               dbg("urb: %p", tmp);
                // we can accept this urb if it is not queued at this time 
                // or if non-iso transfer requests should be scheduled for the same device and pipe
                if ((usb_pipetype (purb->pipe) != PIPE_ISOCHRONOUS &&
@@ -1101,7 +1092,7 @@ _static int search_dev_ep (puhci_t s, purb_t purb)
        return 0;
 }
 /*-------------------------------------------------------------------*/
-_static int uhci_submit_urb (purb_t purb)
+static int uhci_submit_urb (purb_t purb)
 {
        puhci_t s;
        purb_priv_t purb_priv;
@@ -1111,7 +1102,7 @@ _static int uhci_submit_urb (purb_t purb)
                return -ENODEV;
 
        s = (puhci_t) purb->dev->bus->hcpriv;
-       //printk( MODSTR"submit_urb: %p type %d\n",purb,usb_pipetype(purb->pipe));
+       //dbg("submit_urb: %p type %d",purb,usb_pipetype(purb->pipe));
 
        if (usb_pipedevice (purb->pipe) == s->rh.devnum)
                return rh_submit_urb (purb);    /* virtual root hub */
@@ -1137,7 +1128,7 @@ _static int uhci_submit_urb (purb_t purb)
        purb->hcpriv = purb_priv;
        INIT_LIST_HEAD (&purb_priv->desc_list);
        purb_priv->short_control_packet=0;
-       dbg (KERN_DEBUG MODSTR "submit_urb: scheduling %p\n", purb);
+       dbg("submit_urb: scheduling %p", purb);
 
        switch (usb_pipetype (purb->pipe)) {
        case PIPE_ISOCHRONOUS:
@@ -1157,7 +1148,7 @@ _static int uhci_submit_urb (purb_t purb)
                ret = -EINVAL;
        }
 
-       dbg (KERN_DEBUG MODSTR "submit_urb: scheduled with ret: %d\n", ret);
+       dbg("submit_urb: scheduled with ret: %d", ret);
 
        if (ret != USB_ST_NOERROR) {
                usb_dec_dev_use (purb->dev);
@@ -1171,7 +1162,7 @@ _static int uhci_submit_urb (purb_t purb)
 
        purb->status = USB_ST_URB_PENDING;
        queue_urb (s, &purb->urb_list,1);
-       dbg (KERN_DEBUG MODSTR "submit_urb: exit\n");
+       dbg("submit_urb: exit");
 
        return 0;
 }
@@ -1179,7 +1170,7 @@ _static int uhci_submit_urb (purb_t purb)
  Virtual Root Hub
  -------------------------------------------------------------------*/
 
-_static __u8 root_hub_dev_des[] =
+static __u8 root_hub_dev_des[] =
 {
        0x12,                   /*  __u8  bLength; */
        0x01,                   /*  __u8  bDescriptorType; Device */
@@ -1203,7 +1194,7 @@ _static __u8 root_hub_dev_des[] =
 
 
 /* Configuration descriptor */
-_static __u8 root_hub_config_des[] =
+static __u8 root_hub_config_des[] =
 {
        0x09,                   /*  __u8  bLength; */
        0x02,                   /*  __u8  bDescriptorType; Configuration */
@@ -1238,7 +1229,7 @@ _static __u8 root_hub_config_des[] =
 };
 
 
-_static __u8 root_hub_hub_des[] =
+static __u8 root_hub_hub_des[] =
 {
        0x09,                   /*  __u8  bLength; */
        0x29,                   /*  __u8  bDescriptorType; Hub-descriptor */
@@ -1253,7 +1244,7 @@ _static __u8 root_hub_hub_des[] =
 
 /*-------------------------------------------------------------------------*/
 /* prepare Interrupt pipe transaction data; HUB INTERRUPT ENDPOINT */
-_static int rh_send_irq (purb_t purb)
+static int rh_send_irq (purb_t purb)
 {
 
        int len = 1;
@@ -1272,7 +1263,7 @@ _static int rh_send_irq (purb_t purb)
        purb->status = USB_ST_NOERROR;
 
        if ((data > 0) && (uhci->rh.send != 0)) {
-               dbg (KERN_DEBUG MODSTR "Root-Hub INT complete: port1: %x port2: %x data: %x\n",
+               dbg("Root-Hub INT complete: port1: %x port2: %x data: %x",
                     inw (io_addr + USBPORTSC1), inw (io_addr + USBPORTSC2), data);
                purb->complete (purb);
 
@@ -1282,9 +1273,9 @@ _static int rh_send_irq (purb_t purb)
 
 /*-------------------------------------------------------------------------*/
 /* Virtual Root Hub INTs are polled by this timer every "intervall" ms */
-_static int rh_init_int_timer (purb_t purb);
+static int rh_init_int_timer (purb_t purb);
 
-_static void rh_int_timer_do (unsigned long ptr)
+static void rh_int_timer_do (unsigned long ptr)
 {
        int len;
 
@@ -1304,7 +1295,7 @@ _static void rh_int_timer_do (unsigned long ptr)
 
 /*-------------------------------------------------------------------------*/
 /* Root Hub INTs are polled by this timer */
-_static int rh_init_int_timer (purb_t purb)
+static int rh_init_int_timer (purb_t purb)
 {
        puhci_t uhci = purb->dev->bus->hcpriv;
 
@@ -1338,7 +1329,7 @@ _static int rh_init_int_timer (purb_t purb)
  *************************/
 
 
-_static int rh_submit_urb (purb_t purb)
+static int rh_submit_urb (purb_t purb)
 {
        struct usb_device *usb_dev = purb->dev;
        puhci_t uhci = usb_dev->bus->hcpriv;
@@ -1359,7 +1350,7 @@ _static int rh_submit_urb (purb_t purb)
        __u16 wLength;
 
        if (usb_pipetype (pipe) == PIPE_INTERRUPT) {
-               dbg (KERN_DEBUG MODSTR "Root-Hub submit IRQ: every %d ms\n", purb->interval);
+               dbg("Root-Hub submit IRQ: every %d ms", purb->interval);
                uhci->rh.urb = purb;
                uhci->rh.send = 1;
                uhci->rh.interval = purb->interval;
@@ -1377,7 +1368,7 @@ _static int rh_submit_urb (purb_t purb)
        for (i = 0; i < 8; i++)
                uhci->rh.c_p_r[i] = 0;
 
-       dbg(KERN_DEBUG MODSTR "Root-Hub: adr: %2x cmd(%1x): %04x %04x %04x %04x\n",
+       dbg("Root-Hub: adr: %2x cmd(%1x): %04x %04x %04x %04x",
             uhci->rh.devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
 
        switch (bmRType_bReq) {
@@ -1517,7 +1508,7 @@ _static int rh_submit_urb (purb_t purb)
        }
 
 
-       printk (KERN_DEBUG MODSTR "Root-Hub stat port1: %x port2: %x \n",
+       dbg("Root-Hub stat port1: %x port2: %x",
             inw (io_addr + USBPORTSC1), inw (io_addr + USBPORTSC2));
 
        purb->actual_length = len;
@@ -1528,11 +1519,11 @@ _static int rh_submit_urb (purb_t purb)
 }
 /*-------------------------------------------------------------------------*/
 
-_static int rh_unlink_urb (purb_t purb)
+static int rh_unlink_urb (purb_t purb)
 {
        puhci_t uhci = purb->dev->bus->hcpriv;
 
-       dbg (KERN_DEBUG MODSTR "Root-Hub unlink IRQ\n");
+       dbg("Root-Hub unlink IRQ");
        uhci->rh.send = 0;
        del_timer (&uhci->rh.rh_int_timer);
        return 0;
@@ -1547,7 +1538,7 @@ _static int rh_unlink_urb (purb_t purb)
  * <status> is (td->status & 0xFE0000) [a.k.a. uhci_status_bits(td->status)
  * <dir_out> is True for output TDs and False for input TDs.
  */
-_static int uhci_map_status (int status, int dir_out)
+static int uhci_map_status (int status, int dir_out)
 {
        if (!status)
                return USB_ST_NOERROR;
@@ -1576,12 +1567,12 @@ _static int uhci_map_status (int status, int dir_out)
 /*
  * Only the USB core should call uhci_alloc_dev and uhci_free_dev
  */
-_static int uhci_alloc_dev (struct usb_device *usb_dev)
+static int uhci_alloc_dev (struct usb_device *usb_dev)
 {
        return 0;
 }
 
-_static int uhci_free_dev (struct usb_device *usb_dev)
+static int uhci_free_dev (struct usb_device *usb_dev)
 {
        return 0;
 }
@@ -1591,7 +1582,7 @@ _static int uhci_free_dev (struct usb_device *usb_dev)
  *
  * returns the current frame number for a USB bus/controller.
  */
-_static int uhci_get_current_frame_number (struct usb_device *usb_dev)
+static int uhci_get_current_frame_number (struct usb_device *usb_dev)
 {
        return UHCI_GET_CURRENT_FRAME ((puhci_t) usb_dev->bus->hcpriv);
 }
@@ -1615,7 +1606,7 @@ struct usb_operations uhci_device_operations =
  * when the transfered length fits exactly in maxsze-packets. A bit
  * more intelligence is needed to detect this and finish without error.
  */
-_static int process_transfer (puhci_t s, purb_t purb)
+static int process_transfer (puhci_t s, purb_t purb)
 {
        int ret = USB_ST_NOERROR;
        purb_priv_t purb_priv = purb->hcpriv;
@@ -1632,7 +1623,7 @@ _static int process_transfer (puhci_t s, purb_t purb)
        int actual_length;
        int status = USB_ST_NOERROR;
 
-       dbg (KERN_DEBUG MODSTR "process_transfer: urb contains bulk/control request\n");
+       dbg("process_transfer: urb contains bulk/control request");
 
 
        /* if the status phase has been retriggered and the
@@ -1683,7 +1674,7 @@ _static int process_transfer (puhci_t s, purb_t purb)
                if ( (actual_length < maxlength)) {
                        if (purb->transfer_flags & USB_DISABLE_SPD) {
                                ret = USB_ST_SHORT_PACKET;      // treat as real error
-                               printk (KERN_DEBUG MODSTR "process_transfer: SPD!!\n");
+                               dbg("process_transfer: SPD!!");
                                break;  // exit after this TD because SP was detected
                        }
 
@@ -1692,7 +1683,7 @@ _static int process_transfer (puhci_t s, purb_t purb)
                                if (uhci_packetid(last_desc->hw.td.info) == USB_PID_OUT) {
                                        uhci_show_td (last_desc);
                                        qh->hw.qh.element = virt_to_bus (last_desc);  // re-trigger status stage
-                                       printk("uhci: short packet during control transfer, retrigger status stage @ %p\n",last_desc);
+                                       info("short packet during control transfer, retrigger status stage @ %p",last_desc);
                                        purb_priv->short_control_packet=1;
                                        return 0;
                                }
@@ -1703,7 +1694,7 @@ _static int process_transfer (puhci_t s, purb_t purb)
                }
 
                data_toggle = uhci_toggle (desc->hw.td.info);
-               //printk(KERN_DEBUG MODSTR"process_transfer: len:%d status:%x mapped:%x toggle:%d\n", actual_length, desc->hw.td.status,status, data_toggle);      
+               //dbg("process_transfer: len:%d status:%x mapped:%x toggle:%d", actual_length, desc->hw.td.status,status, data_toggle);      
 
        }
        usb_settoggle (purb->dev, usb_pipeendpoint (purb->pipe), usb_pipeout (purb->pipe), !data_toggle);
@@ -1725,13 +1716,13 @@ _static int process_transfer (puhci_t s, purb_t purb)
 
        purb->status = status;
                                                                
-       dbg(KERN_DEBUG MODSTR"process_transfer: urb %p, wanted len %d, len %d status %x err %d\n",
+       dbg("process_transfer: urb %p, wanted len %d, len %d status %x err %d",
                purb,purb->transfer_buffer_length,purb->actual_length, purb->status, purb->error_count);
-       //dbg(KERN_DEBUG MODSTR"process_transfer: exit\n");
+       //dbg("process_transfer: exit");
        return ret;
 }
 
-_static int process_interrupt (puhci_t s, purb_t purb)
+static int process_interrupt (puhci_t s, purb_t purb)
 {
        int i, ret = USB_ST_URB_PENDING;
        purb_priv_t purb_priv = purb->hcpriv;
@@ -1744,7 +1735,7 @@ _static int process_interrupt (puhci_t s, purb_t purb)
        int actual_length;
        int status = USB_ST_NOERROR;
 
-       //printk(KERN_DEBUG MODSTR"urb contains interrupt request\n");
+       //dbg("urb contains interrupt request");
 
        for (i = 0; p != &purb_priv->desc_list; p = p->next, i++)       // Maybe we allow more than one TD later ;-)
        {
@@ -1752,7 +1743,7 @@ _static int process_interrupt (puhci_t s, purb_t purb)
 
                if (desc->hw.td.status & TD_CTRL_ACTIVE) {
                        // do not process active TDs
-                       //printk("TD ACT Status @%p %08x\n",desc,desc->hw.td.status);
+                       //dbg("TD ACT Status @%p %08x",desc,desc->hw.td.status);
                        break;
                }
 
@@ -1785,7 +1776,7 @@ _static int process_interrupt (puhci_t s, purb_t purb)
 
                if (purb->complete && status != USB_ST_TIMEOUT) {
                        // for last td, no user completion is needed
-                       dbg (KERN_DEBUG MODSTR "process_interrupt: calling completion\n");
+                       dbg("process_interrupt: calling completion");
                        purb->status = status;
                        purb->complete ((struct urb *) purb);
                        purb->status = USB_ST_URB_PENDING;
@@ -1808,7 +1799,7 @@ _static int process_interrupt (puhci_t s, purb_t purb)
 }
 
 
-_static int process_iso (puhci_t s, purb_t purb)
+static int process_iso (puhci_t s, purb_t purb)
 {
        int i;
        int ret = USB_ST_NOERROR;
@@ -1816,7 +1807,7 @@ _static int process_iso (puhci_t s, purb_t purb)
        struct list_head *p = purb_priv->desc_list.next;
        puhci_desc_t desc = list_entry (purb_priv->desc_list.prev, uhci_desc_t, desc_list);
 
-       dbg ( /*KERN_DEBUG */ MODSTR "urb contains iso request\n");
+       dbg("urb contains iso request");
        if (desc->hw.td.status & TD_CTRL_ACTIVE)
                return USB_ST_PARTIAL_ERROR;    // last TD not finished
 
@@ -1830,7 +1821,7 @@ _static int process_iso (puhci_t s, purb_t purb)
                //uhci_show_td(desc);
                if (desc->hw.td.status & TD_CTRL_ACTIVE) {
                        // means we have completed the last TD, but not the TDs before
-                       printk (KERN_DEBUG MODSTR "TD still active (%x)- grrr. paranoia!\n", desc->hw.td.status);
+                       dbg("TD still active (%x)- grrr. paranoia!", desc->hw.td.status);
                        ret = USB_ST_PARTIAL_ERROR;
                        purb->iso_frame_desc[i].status = ret;
                        unlink_td (s, desc);
@@ -1840,14 +1831,14 @@ _static int process_iso (puhci_t s, purb_t purb)
                unlink_td (s, desc);
 
                if (purb->number_of_packets <= i) {
-                       dbg (KERN_DEBUG MODSTR "purb->number_of_packets (%d)<=(%d)\n", purb->number_of_packets, i);
+                       dbg("purb->number_of_packets (%d)<=(%d)", purb->number_of_packets, i);
                        ret = USB_ST_URB_INVALID_ERROR;
                        goto err;
                }
 
                if (purb->iso_frame_desc[i].offset + purb->transfer_buffer != bus_to_virt (desc->hw.td.buffer)) {
                        // Hm, something really weird is going on
-                       dbg (KERN_DEBUG MODSTR "Pointer Paranoia: %p!=%p\n", purb->iso_frame_desc[i].offset + purb->transfer_buffer, bus_to_virt (desc->hw.td.buffer));
+                       dbg("Pointer Paranoia: %p!=%p", purb->iso_frame_desc[i].offset + purb->transfer_buffer, bus_to_virt (desc->hw.td.buffer));
                        ret = USB_ST_URB_INVALID_ERROR;
                        purb->iso_frame_desc[i].status = ret;
                        goto err;
@@ -1862,25 +1853,25 @@ _static int process_iso (puhci_t s, purb_t purb)
                        purb->error_count++;
                        purb->status = purb->iso_frame_desc[i].status;
                }
-               dbg (KERN_DEBUG MODSTR "process_iso: len:%d status:%x\n",
+               dbg("process_iso: len:%d status:%x",
                     purb->iso_frame_desc[i].length, purb->iso_frame_desc[i].status);
 
                delete_desc (desc);
                list_del (p);
        }
-       dbg ( /*KERN_DEBUG */ MODSTR "process_iso: exit %i (%d)\n", i, ret);
+       dbg("process_iso: exit %i (%d)", i, ret);
        return ret;
 }
 
 
-_static int process_urb (puhci_t s, struct list_head *p)
+static int process_urb (puhci_t s, struct list_head *p)
 {
        int ret = USB_ST_NOERROR;
        purb_t purb;
 
        spin_lock(&s->urb_list_lock);
        purb=list_entry (p, urb_t, urb_list);
-       dbg ( /*KERN_DEBUG */ MODSTR "found queued urb: %p\n", purb);
+       dbg("found queued urb: %p", purb);
 
        switch (usb_pipetype (purb->pipe)) {
        case PIPE_CONTROL:
@@ -1899,7 +1890,7 @@ _static int process_urb (puhci_t s, struct list_head *p)
 
        if (purb->status != USB_ST_URB_PENDING) {
                int proceed = 0;
-               dbg ( /*KERN_DEBUG */ MODSTR "dequeued urb: %p\n", purb);
+               dbg("dequeued urb: %p", purb);
                dequeue_urb (s, p, 1);
 
 #ifdef _UHCI_SLAB
@@ -1927,7 +1918,7 @@ _static int process_urb (puhci_t s, struct list_head *p)
 
                        // In case you need the current URB status for your completion handler
                        if (purb->complete && (!proceed || (purb->transfer_flags & USB_URB_EARLY_COMPLETE))) {
-                               dbg (KERN_DEBUG MODSTR "process_transfer: calling early completion\n");
+                               dbg("process_transfer: calling early completion");
                                purb->complete ((struct urb *) purb);
                                if (!proceed && is_ring && (purb->status != USB_ST_URB_KILLED))
                                        uhci_submit_urb (purb);
@@ -1945,7 +1936,7 @@ _static int process_urb (puhci_t s, struct list_head *p)
                                while (tmp != NULL && tmp != purb->next);       // submit until we reach NULL or our own pointer or submit fails
 
                                if (purb->complete && !(purb->transfer_flags & USB_URB_EARLY_COMPLETE)) {
-                                       dbg ( /*KERN_DEBUG */ MODSTR "process_transfer: calling completion\n");
+                                       dbg("process_transfer: calling completion");
                                        purb->complete ((struct urb *) purb);
                                }
                        }
@@ -1956,7 +1947,7 @@ _static int process_urb (puhci_t s, struct list_head *p)
        return ret;
 }
 
-_static void uhci_interrupt (int irq, void *__uhci, struct pt_regs *regs)
+static void uhci_interrupt (int irq, void *__uhci, struct pt_regs *regs)
 {
        puhci_t s = __uhci;
        unsigned int io_addr = s->io_addr;
@@ -1967,14 +1958,14 @@ _static void uhci_interrupt (int irq, void *__uhci, struct pt_regs *regs)
         * Read the interrupt status, and write it back to clear the
         * interrupt cause
         */
-       dbg ("interrupt\n");
+       dbg("interrupt");
        status = inw (io_addr + USBSTS);
 
        if (!status)            /* shared interrupt, not mine */
                return;
 
        if (status != 1) {
-               printk (KERN_DEBUG MODSTR "interrupt, status %x\n", status);
+               dbg("interrupt, status %x", status);
                //uhci_show_status (s);
        }
        //beep(1000);           
@@ -2004,10 +1995,10 @@ _static void uhci_interrupt (int irq, void *__uhci, struct pt_regs *regs)
 #ifdef __alpha
        mb ();                  // ?
 #endif
-       dbg ("done\n");
+       dbg("done");
 }
 
-_static void reset_hc (puhci_t s)
+static void reset_hc (puhci_t s)
 {
        unsigned int io_addr = s->io_addr;
 
@@ -2019,7 +2010,7 @@ _static void reset_hc (puhci_t s)
        wait_ms (10);
 }
 
-_static void start_hc (puhci_t s)
+static void start_hc (puhci_t s)
 {
        unsigned int io_addr = s->io_addr;
        int timeout = 1000;
@@ -2034,7 +2025,7 @@ _static void start_hc (puhci_t s)
 
        while (inw (io_addr + USBCMD) & USBCMD_HCRESET) {
                if (!--timeout) {
-                       printk (KERN_ERR MODSTR "USBCMD_HCRESET timed out!\n");
+                       err("USBCMD_HCRESET timed out!");
                        break;
                }
        }
@@ -2051,7 +2042,7 @@ _static void start_hc (puhci_t s)
        s->apm_state = 1;
 }
 
-_static void __exit uhci_cleanup_dev(puhci_t s)
+static void __exit uhci_cleanup_dev(puhci_t s)
 {
        struct usb_device *root_hub = s->bus->root_hub;
        if (root_hub)
@@ -2068,7 +2059,7 @@ _static void __exit uhci_cleanup_dev(puhci_t s)
 
 }
 
-_static int __init uhci_start_usb (puhci_t s)
+static int __init uhci_start_usb (puhci_t s)
 {                              /* start it up */
        /* connect the virtual root hub */
        struct usb_device *usb_dev;
@@ -2088,7 +2079,7 @@ _static int __init uhci_start_usb (puhci_t s)
        return 0;
 }
 
-_static int __init alloc_uhci (int irq, unsigned int io_addr, unsigned int io_size)
+static int __init alloc_uhci (int irq, unsigned int io_addr, unsigned int io_size)
 {
        puhci_t s;
        struct usb_bus *bus;
@@ -2127,17 +2118,17 @@ _static int __init alloc_uhci (int irq, unsigned int io_addr, unsigned int io_si
                unsigned int portstatus;
 
                portstatus = inw (io_addr + 0x10 + (s->maxports * 2));
-               printk ("port %i, adr %x status %x\n", s->maxports,
+               dbg("port %i, adr %x status %x", s->maxports,
                        io_addr + 0x10 + (s->maxports * 2), portstatus);
                if (!(portstatus & 0x0080))
                        break;
        }
-       dbg (KERN_DEBUG MODSTR "Detected %d ports\n", s->maxports);
+       dbg("Detected %d ports", s->maxports);
 
        /* This is experimental so anything less than 2 or greater than 8 is */
        /*  something weird and we'll ignore it */
        if (s->maxports < 2 || s->maxports > 8) {
-               dbg (KERN_DEBUG "Port count misdetected, forcing to 2 ports\n");
+               dbg("Port count misdetected, forcing to 2 ports");
                s->maxports = 2;
        }
 
@@ -2156,7 +2147,7 @@ _static int __init alloc_uhci (int irq, unsigned int io_addr, unsigned int io_si
        start_hc (s);
 
        if (request_irq (irq, uhci_interrupt, SA_SHIRQ, MODNAME, s)) {
-               printk(MODSTR KERN_ERR"request_irq %d failed!\n",irq);
+               err("request_irq %d failed!",irq);
                usb_free_bus (bus);
                reset_hc (s);
                release_region (s->io_addr, s->io_size);
@@ -2178,7 +2169,7 @@ _static int __init alloc_uhci (int irq, unsigned int io_addr, unsigned int io_si
        return 0;
 }
 
-_static int __init start_uhci (struct pci_dev *dev)
+static int __init start_uhci (struct pci_dev *dev)
 {
        int i;
 
@@ -2210,16 +2201,16 @@ _static int __init start_uhci (struct pci_dev *dev)
 }
 
 #ifdef CONFIG_APM
-_static int handle_apm_event (apm_event_t event)
+static int handle_apm_event (apm_event_t event)
 {
        static int down = 0;
        puhci_t s = devs;
-       printk ("handle_apm_event(%d)\n", event);
+       dbg("handle_apm_event(%d)", event);
        switch (event) {
        case APM_SYS_SUSPEND:
        case APM_USER_SUSPEND:
                if (down) {
-                       dbg (KERN_DEBUG MODSTR "received extra suspend event\n");
+                       dbg("received extra suspend event");
                        break;
                }
                while (s) {
@@ -2231,7 +2222,7 @@ _static int handle_apm_event (apm_event_t event)
        case APM_NORMAL_RESUME:
        case APM_CRITICAL_RESUME:
                if (!down) {
-                       dbg (KERN_DEBUG MODSTR "received bogus resume event\n");
+                       dbg("received bogus resume event");
                        break;
                }
                down = 0;
@@ -2262,7 +2253,7 @@ int __init uhci_init (void)
        uhci_desc_kmem = kmem_cache_create(slabname, sizeof(uhci_desc_t), 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
        
        if(!uhci_desc_kmem) {
-               printk(KERN_ERR MODSTR"kmem_cache_create for uhci_desc failed (out of memory)\n");
+               err("kmem_cache_create for uhci_desc failed (out of memory)");
                return -ENOMEM;
        }
 
@@ -2275,11 +2266,11 @@ int __init uhci_init (void)
        urb_priv_kmem = kmem_cache_create(slabname, sizeof(urb_priv_t), 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
        
        if(!urb_priv_kmem) {
-               printk(KERN_ERR MODSTR"kmem_cache_create for urb_priv_t failed (out of memory)\n");
+               err("kmem_cache_create for urb_priv_t failed (out of memory)");
                return -ENOMEM;
        }
 #endif 
-       printk (KERN_INFO MODSTR VERSTR "\n");
+       info(VERSTR);
 
        for (;;) {
                dev = pci_find_class (PCI_CLASS_SERIAL_USB << 8, dev);
@@ -2296,7 +2287,7 @@ int __init uhci_init (void)
 #endif
                if(!dev->irq)
                {
-                       printk(KERN_ERR MODSTR"Found UHCI device with no IRQ assigned. Check BIOS settings!\n");
+                       err("Found UHCI device with no IRQ assigned. Check BIOS settings!");
                        continue;
                }
 
index 1902786bbb2cec378b00b945dd7e11a469e97b16..d8ef7f038dbe7fa1f80f9aeecaf81a5c016ede9d 100644 (file)
@@ -5,7 +5,6 @@
    $Id: uhci.h,v 1.30 1999/12/15 17:57:25 fliegl Exp $
  */
 #define MODNAME "usb-uhci"
-#define MODSTR MODNAME": "
 #define VERSTR "version v0.9 time " __TIME__ " " __DATE__
 
 /* Command register */
index 6f0c5221bac5d1abb0aa2b9b096fb550708d3883..b321fdff3a408fb9f7a9f54a39f361907ff54059 100644 (file)
@@ -6,6 +6,9 @@
  */
 #include <linux/version.h>
 #include <linux/kernel.h>
+
+#define DEBUG
+
 #include "usb.h"
 
 static void usb_show_endpoint(struct usb_endpoint_descriptor *endpoint)
index 47b98f472ac0e1fa51f7a4a7b6eb95a0d9300fc7..0cb3bdcba8c29f7d0befafb22c4a4e75c5615ba0 100644 (file)
 #include <linux/module.h>
 #include <linux/spinlock.h>
 
-#include "usb.h"
-
-/*#define SERIAL_DEBUG 1*/
-
-#ifdef SERIAL_DEBUG
-       #define debug_info(format,arg...)       printk(KERN_DEBUG "USB Serial: " format "\n" , ##arg)
-#else
-       #define debug_info(format,arg...)       do {} while (0)
-#endif
-
+#undef DEBUG
 
+#include "usb.h"
 
 /* Module information */
 MODULE_AUTHOR("Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux-usb/");
@@ -393,18 +385,15 @@ static void serial_read_bulk (struct urb *urb)
                unsigned char *data = urb->transfer_buffer;
        int i;
 
-       debug_info("serial_read_irq");
+       dbg("serial_read_irq");
 
        if (urb->status) {
-               debug_info("nonzero read bulk status received: %d", urb->status);
+               dbg("nonzero read bulk status received: %d", urb->status);
                return;
        }
 
-#ifdef SERIAL_DEBUG
-       if (urb->actual_length) {
-               debug_info("%d %s\n", urb->actual_length, data);
-       }
-#endif
+       if (urb->actual_length)
+               dbg("%d %s", urb->actual_length, data);
 
        if (urb->actual_length) {
                for (i = 0; i < urb->actual_length ; ++i) {
@@ -415,7 +404,7 @@ static void serial_read_bulk (struct urb *urb)
 
        /* Continue trying to always read  */
        if (usb_submit_urb(urb))
-               debug_info("failed resubmitting read urb");
+               dbg("failed resubmitting read urb");
 
        return;
 }
@@ -426,10 +415,10 @@ static void serial_write_bulk (struct urb *urb)
        struct usb_serial_state *serial = (struct usb_serial_state *) urb->context; 
                struct tty_struct *tty = serial->tty; 
 
-       debug_info("serial_write_irq");
+       dbg("serial_write_irq");
 
        if (urb->status) {
-               debug_info("nonzero write bulk status received: %d", urb->status);
+               dbg("nonzero write bulk status received: %d", urb->status);
                return;
        }
 
@@ -450,18 +439,18 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
 {
        struct usb_serial_state *serial;
        
-       debug_info("serial_open");
+       dbg("serial_open");
 
        /* assign a serial object to the tty pointer */
        serial = &serial_state_table [MINOR(tty->device)-tty->driver.minor_start];
 
        /* do some sanity checking that we really have a device present */
        if (!serial) {
-               debug_info("serial == NULL!");
+               dbg("serial == NULL!");
                return (-ENODEV);
        }
        if (!serial->type) {
-               debug_info("serial->type == NULL!");
+               dbg("serial->type == NULL!");
                return (-ENODEV);
        }
 
@@ -481,23 +470,23 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
 static void serial_close(struct tty_struct *tty, struct file * filp)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 
-       debug_info("serial_close");
+       dbg("serial_close");
        
        /* do some sanity checking that we really have a device present */
        if (!serial) {
-               debug_info("serial == NULL!");
+               dbg("serial == NULL!");
                return;
        }
        if (!serial->type) {
-               debug_info("serial->type == NULL!");
+               dbg("serial->type == NULL!");
                return;
        }
        if (!serial->present) {
-               debug_info("no device registered");
+               dbg("no device registered");
                return;
        }
        if (!serial->active) {
-               debug_info ("device already open");
+               dbg ("device already open");
                return;
        }
 
@@ -512,23 +501,23 @@ static int serial_write (struct tty_struct * tty, int from_user, const unsigned
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 
        
-       debug_info("serial_write");
+       dbg("serial_write");
 
        /* do some sanity checking that we really have a device present */
        if (!serial) {
-               debug_info("serial == NULL!");
+               dbg("serial == NULL!");
                return (-ENODEV);
        }
        if (!serial->type) {
-               debug_info("serial->type == NULL!");
+               dbg("serial->type == NULL!");
                return (-ENODEV);
        }
        if (!serial->present) {
-               debug_info("device not registered");
+               dbg("device not registered");
                return (-EINVAL);
        }
        if (!serial->active) {
-               debug_info ("device not opened");
+               dbg ("device not opened");
                return (-EINVAL);
        }
        
@@ -546,23 +535,23 @@ static void serial_put_char (struct tty_struct *tty, unsigned char ch)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; 
        
-       debug_info("serial_put_char");
+       dbg("serial_put_char");
        
        /* do some sanity checking that we really have a device present */
        if (!serial) {
-               debug_info("serial == NULL!");
+               dbg("serial == NULL!");
                return;
        }
        if (!serial->type) {
-               debug_info("serial->type == NULL!");
+               dbg("serial->type == NULL!");
                return;
        }
        if (!serial->present) {
-               debug_info("no device registered");
+               dbg("no device registered");
                return;
        }
        if (!serial->active) {
-               debug_info ("device not open");
+               dbg ("device not open");
                return;
        }
 
@@ -579,23 +568,23 @@ static int serial_write_room (struct tty_struct *tty)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; 
 
-       debug_info("serial_write_room");
+       dbg("serial_write_room");
        
        /* do some sanity checking that we really have a device present */
        if (!serial) {
-               debug_info("serial == NULL!");
+               dbg("serial == NULL!");
                return (-ENODEV);
        }
        if (!serial->type) {
-               debug_info("serial->type == NULL!");
+               dbg("serial->type == NULL!");
                return (-ENODEV);
        }
        if (!serial->present) {
-               debug_info("no device registered");
+               dbg("no device registered");
                return (-EINVAL);
        }
        if (!serial->active) {
-               debug_info ("device not open");
+               dbg ("device not open");
                return (-EINVAL);
        }
        
@@ -612,23 +601,23 @@ static int serial_chars_in_buffer (struct tty_struct *tty)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; 
 
-       debug_info("serial_chars_in_buffer");
+       dbg("serial_chars_in_buffer");
        
        /* do some sanity checking that we really have a device present */
        if (!serial) {
-               debug_info("serial == NULL!");
+               dbg("serial == NULL!");
                return (-ENODEV);
        }
        if (!serial->type) {
-               debug_info("serial->type == NULL!");
+               dbg("serial->type == NULL!");
                return (-ENODEV);
        }
        if (!serial->present) {
-               debug_info("no device registered");
+               dbg("no device registered");
                return (-EINVAL);
        }
        if (!serial->active) {
-               debug_info ("device not open");
+               dbg ("device not open");
                return (-EINVAL);
        }
        
@@ -645,23 +634,23 @@ static void serial_throttle (struct tty_struct * tty)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 
 
-       debug_info("serial_throttle");
+       dbg("serial_throttle");
        
        /* do some sanity checking that we really have a device present */
        if (!serial) {
-               debug_info("serial == NULL!");
+               dbg("serial == NULL!");
                return;
        }
        if (!serial->type) {
-               debug_info("serial->type == NULL!");
+               dbg("serial->type == NULL!");
                return;
        }
        if (!serial->present) {
-               debug_info("no device registered");
+               dbg("no device registered");
                return;
        }
        if (!serial->active) {
-               debug_info ("device not open");
+               dbg ("device not open");
                return;
        }
 
@@ -678,23 +667,23 @@ static void serial_unthrottle (struct tty_struct * tty)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 
 
-       debug_info("serial_unthrottle");
+       dbg("serial_unthrottle");
        
        /* do some sanity checking that we really have a device present */
        if (!serial) {
-               debug_info("serial == NULL!");
+               dbg("serial == NULL!");
                return;
        }
        if (!serial->type) {
-               debug_info("serial->type == NULL!");
+               dbg("serial->type == NULL!");
                return;
        }
        if (!serial->present) {
-               debug_info("no device registered");
+               dbg("no device registered");
                return;
        }
        if (!serial->active) {
-               debug_info ("device not open");
+               dbg ("device not open");
                return;
        }
 
@@ -715,22 +704,22 @@ static int etek_serial_open (struct tty_struct *tty, struct file *filp)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 
 
-       debug_info("etek_serial_open");
+       dbg("etek_serial_open");
 
        if (!serial->present) {
-               debug_info("no device registered");
+               dbg("no device registered");
                return -EINVAL;
        }
 
        if (serial->active) {
-               debug_info ("device already open");
+               dbg ("device already open");
                return -EINVAL;
        }
        serial->active = 1;
  
        /*Start reading from the device*/
        if (usb_submit_urb(&serial->read_urb))
-               debug_info("usb_submit_urb(read bulk) failed");
+               dbg("usb_submit_urb(read bulk) failed");
 
        /* Need to do device specific setup here (control lines, baud rate, etc.) */
        /* FIXME!!! */
@@ -742,7 +731,7 @@ static int etek_serial_open (struct tty_struct *tty, struct file *filp)
 static void etek_serial_close(struct tty_struct *tty, struct file * filp)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 
-       debug_info("etek_serial_close");
+       dbg("etek_serial_close");
        
        /* Need to change the control lines here */
        /* FIXME */
@@ -761,22 +750,22 @@ static int whiteheat_serial_open (struct tty_struct *tty, struct file *filp)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 
 
-       debug_info("whiteheat_serial_open");
+       dbg("whiteheat_serial_open");
 
        if (!serial->present) {
-               debug_info("no device registered");
+               dbg("no device registered");
                return -EINVAL;
        }
 
        if (serial->active) {
-               debug_info ("device already open");
+               dbg ("device already open");
                return -EINVAL;
        }
        serial->active = 1;
  
        /*Start reading from the device*/
        if (usb_submit_urb(&serial->read_urb))
-               debug_info("usb_submit_urb(read bulk) failed");
+               dbg("usb_submit_urb(read bulk) failed");
 
        /* Need to do device specific setup here (control lines, baud rate, etc.) */
        /* FIXME!!! */
@@ -788,7 +777,7 @@ static int whiteheat_serial_open (struct tty_struct *tty, struct file *filp)
 static void whiteheat_serial_close(struct tty_struct *tty, struct file * filp)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 
-       debug_info("whiteheat_serial_close");
+       dbg("whiteheat_serial_close");
        
        /* Need to change the control lines here */
        /* FIXME */
@@ -802,7 +791,7 @@ static void whiteheat_serial_close(struct tty_struct *tty, struct file * filp)
 
 static void whiteheat_throttle (struct tty_struct * tty)
 {
-       debug_info("whiteheat_throttle");
+       dbg("whiteheat_throttle");
        
        /* Change the control signals */
        /* FIXME!!! */
@@ -813,7 +802,7 @@ static void whiteheat_throttle (struct tty_struct * tty)
 
 static void whiteheat_unthrottle (struct tty_struct * tty)
 {
-       debug_info("whiteheat_unthrottle");
+       dbg("whiteheat_unthrottle");
        
        /* Change the control signals */
        /* FIXME!!! */
@@ -828,15 +817,15 @@ static void whiteheat_unthrottle (struct tty_struct * tty)
 static int visor_serial_open (struct tty_struct *tty, struct file *filp)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data;
-       debug_info("visor_serial_open");
+       dbg("visor_serial_open");
 
        if (!serial->present) {
-               debug_info("no device registered");
+               dbg("no device registered");
                return -EINVAL;
        }
 
        if (serial->active) {
-               debug_info ("device already open");
+               dbg ("device already open");
                return -EINVAL;
        }
 
@@ -844,7 +833,7 @@ static int visor_serial_open (struct tty_struct *tty, struct file *filp)
 
        /*Start reading from the device*/
        if (usb_submit_urb(&serial->read_urb))
-               debug_info("usb_submit_urb(read bulk) failed");
+               dbg("usb_submit_urb(read bulk) failed");
 
        return (0);
 }
@@ -853,7 +842,7 @@ static void visor_serial_close(struct tty_struct *tty, struct file * filp)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data;
        
-       debug_info("USB: visor_serial_close");
+       dbg("USB: visor_serial_close");
                         
        /* shutdown our bulk reads and writes */
        usb_unlink_urb (&serial->write_urb);
@@ -866,7 +855,7 @@ static void visor_throttle (struct tty_struct * tty)
 {
 /*     struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; */
 
-       debug_info("visor_throttle");
+       dbg("visor_throttle");
 
        /* Change the control signals */
        /* FIXME!!! */
@@ -878,7 +867,7 @@ static void visor_unthrottle (struct tty_struct * tty)
 {
 /*     struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; */
 
-       debug_info("visor_unthrottle");
+       dbg("visor_unthrottle");
 
        /* Change the control signals */
        /* FIXME!!! */
@@ -894,15 +883,15 @@ static int generic_serial_open (struct tty_struct *tty, struct file *filp)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 
 
-       debug_info("generic_serial_open");
+       dbg("generic_serial_open");
 
        if (!serial->present) {
-               debug_info("no device registered");
+               dbg("no device registered");
                return -EINVAL;
        }
 
        if (serial->active) {
-               debug_info ("device already open");
+               dbg ("device already open");
                return -EINVAL;
        }
        serial->active = 1;
@@ -911,7 +900,7 @@ static int generic_serial_open (struct tty_struct *tty, struct file *filp)
        if (serial->num_bulk_in) {
                /*Start reading from the device*/
                if (usb_submit_urb(&serial->read_urb))
-                       debug_info("usb_submit_urb(read bulk) failed");
+                       dbg("usb_submit_urb(read bulk) failed");
        }
 
        return (0);
@@ -921,7 +910,7 @@ static int generic_serial_open (struct tty_struct *tty, struct file *filp)
 static void generic_serial_close(struct tty_struct *tty, struct file * filp)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 
-       debug_info("generic_serial_close");
+       dbg("generic_serial_close");
        
        /* shutdown any bulk reads that might be going on */
        if (serial->num_bulk_out) {
@@ -939,17 +928,17 @@ static int generic_serial_write (struct tty_struct * tty, int from_user, const u
 {
        struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; 
        
-       debug_info("generic_serial_write");
+       dbg("generic_serial_write");
 
        if (count == 0) {
-               debug_info("write request of 0 bytes");
+               dbg("write request of 0 bytes");
                return (0);
        }
 
        /* only do something if we have a bulk out endpoint */
        if (serial->num_bulk_out) {
                if (serial->write_urb.status == -EINPROGRESS) {
-                       debug_info ("already writing");
+                       dbg ("already writing");
                        return (0);
                }
 
@@ -966,7 +955,7 @@ static int generic_serial_write (struct tty_struct * tty, int from_user, const u
                serial->write_urb.transfer_buffer_length = count;
 
                if (usb_submit_urb(&serial->write_urb))
-                       debug_info("usb_submit_urb(write bulk) failed");
+                       dbg("usb_submit_urb(write bulk) failed");
 
                return (count);
        }
@@ -980,7 +969,7 @@ static void generic_serial_put_char (struct tty_struct *tty, unsigned char ch)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; 
        
-       debug_info("generic_serial_put_char");
+       dbg("generic_serial_put_char");
        
        /* if we have a bulk out endpoint, then shove a character out it */
        if (serial->num_bulk_out) {
@@ -989,7 +978,7 @@ static void generic_serial_put_char (struct tty_struct *tty, unsigned char ch)
                serial->write_urb.transfer_buffer_length = 1;
 
                if (usb_submit_urb(&serial->write_urb))
-                       debug_info("usb_submit_urb(write bulk) failed");
+                       dbg("usb_submit_urb(write bulk) failed");
 
        }
 
@@ -1002,14 +991,14 @@ static int generic_write_room (struct tty_struct *tty)
        struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; 
        int room;
 
-       debug_info("generic_write_room");
+       dbg("generic_write_room");
        
        if (serial->num_bulk_out) {
                if (serial->write_urb.status == -EINPROGRESS)
                        room = 0;
                else
                        room = serial->bulk_out_size[0];
-               debug_info("generic_write_room returns %d", room);
+               dbg("generic_write_room returns %d", room);
                return (room);
        }
        
@@ -1021,7 +1010,7 @@ static int generic_chars_in_buffer (struct tty_struct *tty)
 {
        struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; 
 
-       debug_info("generic_chars_in_buffer");
+       dbg("generic_chars_in_buffer");
        
        if (serial->num_bulk_out) {
                if (serial->write_urb.status == -EINPROGRESS) {
@@ -1068,13 +1057,13 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
        device_num = 0;
        while (usb_serial_devices[device_num] != NULL) {
                type = usb_serial_devices[device_num];
-               debug_info ("Looking at %s Vendor id=%.4x Product id=%.4x", type->name, *(type->idVendor), *(type->idProduct));
+               dbg ("Looking at %s Vendor id=%.4x Product id=%.4x", type->name, *(type->idVendor), *(type->idProduct));
 
                /* look at the device descriptor */
                if ((dev->descriptor.idVendor == *(type->idVendor)) &&
                    (dev->descriptor.idProduct == *(type->idProduct))) {
 
-                       debug_info("descriptor matches...looking at the endpoints");
+                       dbg("descriptor matches...looking at the endpoints");
 
                        /* descriptor matches, let's try to find the endpoints needed */
                        interrupt_pipe = bulk_in_pipe = bulk_out_pipe = HAS_NOT;
@@ -1087,7 +1076,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                                if ((endpoint->bEndpointAddress & 0x80) &&
                                    ((endpoint->bmAttributes & 3) == 0x02)) {
                                        /* we found a bulk in endpoint */
-                                       debug_info("found bulk in");
+                                       dbg("found bulk in");
                                        bulk_in_pipe = HAS;
                                        bulk_in_endpoint[num_bulk_in] = endpoint;
                                        ++num_bulk_in;
@@ -1096,7 +1085,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                                if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
                                    ((endpoint->bmAttributes & 3) == 0x02)) {
                                        /* we found a bulk out endpoint */
-                                       debug_info("found bulk out");
+                                       dbg("found bulk out");
                                        bulk_out_pipe = HAS;
                                        bulk_out_endpoint[num_bulk_out] = endpoint;
                                        ++num_bulk_out;
@@ -1105,7 +1094,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                                if ((endpoint->bEndpointAddress & 0x80) &&
                                    ((endpoint->bmAttributes & 3) == 0x03)) {
                                        /* we found a interrupt in endpoint */
-                                       debug_info("found interrupt in");
+                                       dbg("found interrupt in");
                                        interrupt_pipe = HAS;
                                        interrupt_in_endpoint[num_interrupt_in] = endpoint;
                                        ++num_interrupt_in;
@@ -1118,10 +1107,10 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                            (bulk_in_pipe & type->needs_bulk_in) &&
                            (bulk_out_pipe & type->needs_bulk_out)) {
                                /* found all that we need */
-                               printk (KERN_INFO "USB Serial: %s converter detected.\n", type->name);
+                               info("%s converter detected", type->name);
 
                                if (0>(serial_num = Get_Free_Serial())) {
-                                       debug_info("Too many devices connected");
+                                       dbg("Too many devices connected");
                                        return NULL;
                                }
        
@@ -1143,7 +1132,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                                        serial->bulk_in_pipe[i] = usb_rcvbulkpipe (dev, serial->bulk_in_endpoint[i]);
                                        serial->bulk_in_buffer[i] = kmalloc (serial->bulk_in_size[i], GFP_KERNEL);
                                        if (!serial->bulk_in_buffer[i]) {
-                                               printk("USB Serial: Couldn't allocate bulk_in_buffer\n");
+                                               err("Couldn't allocate bulk_in_buffer");
                                                goto probe_error;
                                        }
                                }
@@ -1158,7 +1147,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                                        serial->bulk_out_pipe[i] = usb_rcvbulkpipe (dev, serial->bulk_out_endpoint[i]);
                                        serial->bulk_out_buffer[i] = kmalloc (serial->bulk_out_size[i], GFP_KERNEL);
                                        if (!serial->bulk_out_buffer[i]) {
-                                               printk("USB Serial: Couldn't allocate bulk_out_buffer\n");
+                                               err("Couldn't allocate bulk_out_buffer");
                                                goto probe_error;
                                        }
                                }
@@ -1174,7 +1163,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                                        /* serial->interrupt_in_pipe = usb_rcvbulkpipe (dev, serial->bulk_in_endpoint); */
                                        serial->interrupt_in_buffer[i] = kmalloc (serial->bulk_in_size[i], GFP_KERNEL);
                                        if (!serial->interrupt_in_buffer[i]) {
-                                               printk("USB Serial: Couldn't allocate interrupt_in_buffer\n");
+                                               err("Couldn't allocate interrupt_in_buffer");
                                                goto probe_error;
                                        }
                                }
@@ -1188,7 +1177,7 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                                /* set up our interrupt to be the time for the bulk in read */
                                ret = usb_request_irq (dev, serial->bulk_in_pipe, usb_serial_irq, serial->bulk_in_interval, serial, &serial->irq_handle);
                                if (ret) {
-                                       printk(KERN_INFO "USB Serial: failed usb_request_irq (0x%x)\n", ret);
+                                       info("failed usb_request_irq (0x%x)", ret);
                                        goto probe_error;
                                }
                                #endif
@@ -1196,10 +1185,10 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum)
                                serial->present = 1;
                                MOD_INC_USE_COUNT;
 
-                               printk(KERN_INFO "USB Serial: %s converter now attached to ttyUSB%d\n", type->name, serial_num);
+                               info("%s converter now attached to ttyUSB%d", type->name, serial_num);
                                return serial;
                        } else {
-                               printk(KERN_INFO "USB Serial: descriptors matched, but endpoints did not\n");
+                               info("descriptors matched, but endpoints did not");
                        }
                }
 
@@ -1231,7 +1220,7 @@ static void usb_serial_disconnect(struct usb_device *dev, void *ptr)
        if (serial) {
                if (!serial->present) {
                        /* something strange is going on */
-                       debug_info("disconnect but not present?");
+                       dbg("disconnect but not present?");
                        return;
                        }
 
@@ -1253,10 +1242,10 @@ static void usb_serial_disconnect(struct usb_device *dev, void *ptr)
                serial->present = 0;
                serial->active = 0;
 
-               printk (KERN_INFO "USB Serial: %s converter now disconnected from ttyUSB%d\n", serial->type->name, serial->number);
+               info("%s converter now disconnected from ttyUSB%d", serial->type->name, serial->number);
 
        } else {
-               printk (KERN_INFO "USB Serial: device disconnected.\n");
+               info("device disconnected");
        }
        
        MOD_DEC_USE_COUNT;
@@ -1317,7 +1306,7 @@ int usb_serial_init(void)
        serial_tty_driver.init_termios          = tty_std_termios;
        serial_tty_driver.init_termios.c_cflag  = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
        if (tty_register_driver (&serial_tty_driver)) {
-               printk( "USB Serial: failed to register tty driver\n" );
+               err("failed to register tty driver");
                return -EPERM;
        }
        
@@ -1327,7 +1316,7 @@ int usb_serial_init(void)
                return -1;
        }
 
-       printk(KERN_INFO "USB Serial: support registered.\n");
+       info("support registered");
        return 0;
 }
 
index 8be60046a0ec45c6379509be19d1caa3b2ac3471..cc970c0f5c017be19df0bb5251b4f1788ac9b29f 100644 (file)
@@ -18,8 +18,6 @@
  * $Id: usb.c,v 1.39 1999/12/27 15:17:47 acher Exp $
  */
 
-#define USB_DEBUG      1
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/malloc.h>
 #include <linux/interrupt.h>  /* for in_interrupt() */
 
-#include "usb.h"
-
-#define MODSTR "usbcore: "
+#define DEBUG
 
-#ifdef USB_DEBUG
-       #define dbg(format, arg...) printk(format, ## arg)
-#else
-       #define dbg(format, arg...)
-#endif
+#include "usb.h"
 
 /*
  * Prototypes for the device driver probing/loading functions
@@ -218,7 +210,7 @@ static int check_bandwidth_alloc (unsigned int old_alloc, long bustime)
        new_alloc = old_alloc + bustime;
                /* what new total allocated bus time would be */
 
-       PRINTD ("usb-bandwidth-alloc: was: %u, new: %u, "
+       dbg("usb-bandwidth-alloc: was: %u, new: %u, "
                "bustime = %ld us, Pipe allowed: %s",
                old_alloc, new_alloc, bustime,
                (new_alloc <= FRAME_TIME_MAX_USECS_ALLOC) ?
@@ -335,7 +327,7 @@ void usb_driver_claim_interface(struct usb_driver *driver, struct usb_interface
        if (!iface || !driver)
                return;
 
-       printk(KERN_DEBUG "usbcore: %s driver claimed interface %p\n", driver->name, iface);
+       dbg("%s driver claimed interface %p", driver->name, iface);
 
        iface->driver = driver;
        iface->private_data = priv;
@@ -428,7 +420,11 @@ static void usb_find_drivers(struct usb_device *dev)
        }
  
        if (rejected)
-               printk(KERN_DEBUG "usbcore: unhandled interfaces on device.\n");
+               dbg("unhandled interfaces on device");
+
+#ifdef DEBUG
+       usb_show_device(dev);
+#endif
 }
 
 /*
@@ -478,7 +474,7 @@ urb_t* usb_alloc_urb(int iso_packets)
              in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
        if (!urb)
        {
-               printk(KERN_ERR MODSTR"alloc_urb: kmalloc failed\n");
+               err("alloc_urb: kmalloc failed");
                return 0;
        }
        memset(urb,0,sizeof(urb_t));
@@ -522,7 +518,7 @@ static void usb_api_blocking_completion(urb_t *urb)
                wake_up(awd->wakeup);
 #if 0
        else
-               dbg(KERN_DEBUG MODSTR "(blocking_completion): waitqueue empty!\n"); 
+               dbg("(blocking_completion): waitqueue empty!"); 
                // even occurs if urb was unlinked by timeout...
 #endif
 }
@@ -573,7 +569,7 @@ static int usb_start_wait_urb(urb_t *urb, int timeout, unsigned long* rval)
 
        if (!status) {
                // timeout
-               printk(KERN_DEBUG MODSTR"usb_control/bulk_msg: timeout\n");
+               dbg("usb_control/bulk_msg: timeout");
                usb_unlink_urb(urb);  // remove urb safely
                status=-ETIMEDOUT;
        }
@@ -621,7 +617,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u
        dr.value = cpu_to_le16p(&value);
        dr.index = cpu_to_le16p(&index);
        dr.length = cpu_to_le16p(&size);
-       //dbg(KERN_DEBUG MODSTR"usb_control_msg\n");    
+       //dbg("usb_control_msg");       
        return usb_internal_control_msg(dev, pipe, &dr, data, size, timeout);
 }
 
@@ -683,7 +679,7 @@ void *usb_request_bulk(struct usb_device *dev, unsigned int pipe, usb_device_irq
 int usb_terminate_bulk(struct usb_device *dev, void *first)
 {
        urb_t *urb=(urb_t*)first;
-       dbg(KERN_DEBUG MODSTR"usb_terminate_bulk: urb:%p\n",urb);
+       dbg("usb_terminate_bulk: urb:%p",urb);
        if (!urb) // none found? there is nothing to remove!
                return -ENODEV;
   
@@ -702,7 +698,7 @@ void usb_release_bandwidth(struct usb_device *dev, int bw_alloc)
 {
        dev->bus->bandwidth_allocated -= bw_alloc;
        dev->bus->bandwidth_int_reqs--;
-       PRINTD ("bw_alloc reduced to %d for %d requesters",
+       dbg("bw_alloc reduced to %d for %d requesters",
                dev->bus->bandwidth_allocated,
                dev->bus->bandwidth_int_reqs +
                dev->bus->bandwidth_isoc_reqs);
@@ -776,7 +772,7 @@ int usb_request_irq(struct usb_device *dev, unsigned int pipe, usb_device_irq ha
        if (!ret) {
                dev->bus->bandwidth_allocated += bustime;
                dev->bus->bandwidth_int_reqs++;
-               PRINTD ("bw_alloc bumped to %d for %d requesters",
+               dbg("bw_alloc bumped to %d for %d requesters",
                        dev->bus->bandwidth_allocated,
                        dev->bus->bandwidth_int_reqs +
                        dev->bus->bandwidth_isoc_reqs);
@@ -1065,7 +1061,6 @@ int usb_parse_configuration(struct usb_device *dev, struct usb_config_descriptor
        struct usb_descriptor_header *header;
 
        memcpy(config, buffer, USB_DT_INTERFACE_SIZE);
-       usb_show_config_descriptor(config);
        le16_to_cpus(&config->wTotalLength);
        size = config->wTotalLength;
 
index 6233b160160b4ded8258028f9fa9bb218e4a6d92..15bf6a664bbb49400480340719aba98e2ec1bc7b 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/ioctl.h>
 #include <linux/version.h>
 
-
 /* USB constants */
 
 /*
@@ -784,13 +783,15 @@ void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor *);
 void usb_show_device(struct usb_device *);
 void usb_show_string(struct usb_device *dev, char *id, int index);
 
-#ifdef USB_DEBUG
-#define PRINTD(format, args...) printk(KERN_DEBUG "usb: " format "\n" , ## args);
-#else /* NOT DEBUGGING */
-#define PRINTD(fmt, arg...) do {} while (0)
-#endif /* USB_DEBUG */
-/* A simple way to change one line from DEBUG to NOT DEBUG: */
-#define XPRINTD(fmt, arg...)   do {} while (0)
+#ifdef DEBUG
+#define dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format "\n", ## arg)
+#else
+#define dbg(format, arg...)
+#endif
+#define err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n", ## arg)
+#define info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n", ## arg)
+#define warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n", ## arg)
+
 
 /*
  * procfs stuff
index 461294bbae46bcb8c4da1c949561c89d9de41fb5..733f9d78838fb73524cb76964b695b6ebd67bb5f 100644 (file)
@@ -79,14 +79,14 @@ static void usb_kbd_irq(struct urb *urb)
                        if (usb_kbd_keycode[kbd->old[i]])
                                input_report_key(&kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
                        else
-                               printk(KERN_DEBUG "usbkbd.c: Unknown key (scancode %#x) released.\n", kbd->old[i]);
+                               info("Unknown key (scancode %#x) released.", kbd->old[i]);
                }
 
                if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
                        if (usb_kbd_keycode[kbd->new[i]])
                                input_report_key(&kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
                        else
-                               printk(KERN_DEBUG "usbkbd.c: Unknown key (scancode %#x) pressed.\n", kbd->new[i]);
+                               info("Unknown key (scancode %#x) pressed.", kbd->new[i]);
                }
        }
 
index 2e44f209a7c90b87043952d239700291666f91b6..cf83c755ec163d161bbeabfe1e9f976075883d21 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: atyfb.c,v 1.134 1999/12/23 21:32:09 geert Exp $
+/*  $Id: atyfb.c,v 1.136 2000/01/06 23:53:29 davem Exp $
  *  linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
  *
  *     Copyright (C) 1997-1998  Geert Uytterhoeven
@@ -3657,7 +3657,7 @@ int __init atyfb_init(void)
     u16 tmp;
 #endif
 
-    while ((pdev = pci_find_device(PCI_VENDOR_ID_ATY, PCI_ANY_ID, pdev))) {
+    while ((pdev = pci_find_device(PCI_VENDOR_ID_ATI, PCI_ANY_ID, pdev))) {
        if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
            struct resource *rp;
 
index 9e93437b3ad7f23454c5ed9b0767e1fe05dcc60f..4a497adb35f2d293c3c5f7258146b9f7ed58ef52 100644 (file)
@@ -143,6 +143,9 @@ static struct {
 #ifdef CONFIG_FB_CLGEN
        { "clgen", clgenfb_init, clgenfb_setup },
 #endif
+#ifdef CONFIG_FB_SBUS
+       { "sbus", sbusfb_init, sbusfb_setup },
+#endif
 #ifdef CONFIG_FB_ATY
        { "atyfb", atyfb_init, atyfb_setup },
 #endif
@@ -153,9 +156,6 @@ static struct {
         */
        { "offb", offb_init, offb_setup },
 #endif
-#ifdef CONFIG_FB_SBUS
-       { "sbus", sbusfb_init, sbusfb_setup },
-#endif
 #ifdef CONFIG_FB_ATY128
        { "aty128fb", aty128fb_init, aty128fb_setup },
 #endif
index 5e1fc620a6ca9c7be69188221f4a100e57f59fd0..946270f45fce2bdeb37d3c1d35eecea5458ba06b 100644 (file)
@@ -6020,8 +6020,8 @@ static int __init matrox_init(void){
                u_int16_t sid;
 
                pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
-               svid = dev->subsystem_vendor;
-               sid = dev->subsystem_device;
+               svid = pdev->subsystem_vendor;
+               sid = pdev->subsystem_device;
                for (b = dev_list; b->vendor; b++) {
                        if ((b->vendor != pdev->vendor) || (b->device != pdev->device) || (b->rev < rev)) continue;
                        if (b->svid)
index 48dfff0661283b7e90ed9f54184d4aa5c253d39e..b2bc7670f5e6a773b90ab6d7a3c8c4a31d4999a2 100644 (file)
@@ -1629,7 +1629,6 @@ int brw_kiovec(int rw, int nr, struct kiobuf *iovec[],
        int             offset;
        unsigned long   blocknr;
        struct kiobuf * iobuf = NULL;
-       unsigned long   page;
        struct page *   map;
        struct buffer_head *tmp, *bh[KIO_MAX_SECTORS];
 
@@ -1661,11 +1660,6 @@ int brw_kiovec(int rw, int nr, struct kiobuf *iovec[],
 
                for (pageind = 0; pageind < iobuf->nr_pages; pageind++) {
                        map  = iobuf->maplist[pageind];
-                       if (map && PageHighMem(map)) {
-                               err = -EIO;
-                               goto error;
-                       }
-                       page = page_address(map);
 
                        while (length > 0) {
                                blocknr = b[bufind++];
index 75a44c8d953ef9f8205ed3a1a6e122c889f70d79..a9a81328a107ff500639d42008443123378bc5ec 100644 (file)
@@ -410,7 +410,7 @@ void shrink_dcache_parent(struct dentry * parent)
  *  ...
  *   6 - base-level: try to shrink a bit.
  */
-int shrink_dcache_memory(int priority, unsigned int gfp_mask)
+int shrink_dcache_memory(int priority, unsigned int gfp_mask, zone_t * zone)
 {
        if (gfp_mask & __GFP_IO) {
                int count = 0;
index d78e57562b4a5a4833b9b579e49ecaec29fad594..4c31957d9eae8be7ea267a78b2b9755aaf8e3362 100644 (file)
@@ -29,9 +29,7 @@
 #define MAX(a,b) (((a)>(b))?(a):(b))
 
 static long long ext2_file_lseek(struct file *, long long, int);
-#if BITS_PER_LONG < 64
 static int ext2_open_file (struct inode *, struct file *);
-#endif
 
 #define EXT2_MAX_SIZE(bits)                                                    \
        (((EXT2_NDIR_BLOCKS + (1LL << (bits - 2)) +                             \
@@ -121,11 +119,11 @@ static int ext2_release_file (struct inode * inode, struct file * filp)
        return 0;
 }
 
-#if BITS_PER_LONG < 64
 /*
  * Called when an inode is about to be open.
  * We use this to disallow opening RW large files on 32bit systems if
- * the caller didn't specify O_LARGEFILE.
+ * the caller didn't specify O_LARGEFILE.  On 64bit systems we force
+ * on this flag in sys_open.
  */
 static int ext2_open_file (struct inode * inode, struct file * filp)
 {
@@ -133,7 +131,6 @@ static int ext2_open_file (struct inode * inode, struct file * filp)
                return -EFBIG;
        return 0;
 }
-#endif
 
 /*
  * We have mostly NULL's here: the current defaults are ok for
@@ -147,11 +144,7 @@ static struct file_operations ext2_file_operations = {
        NULL,                   /* poll - default */
        ext2_ioctl,             /* ioctl */
        generic_file_mmap,      /* mmap */
-#if BITS_PER_LONG == 64        
-       NULL,                   /* no special open is needed */
-#else
        ext2_open_file,
-#endif
        NULL,                   /* flush */
        ext2_release_file,      /* release */
        ext2_sync_file,         /* fsync */
index f1a9ebb88d35d1363c45aa9d7aa478f33eb27086..4990b049725af373d91264e8ce5cad97edad0735 100644 (file)
@@ -395,7 +395,7 @@ void prune_icache(int goal)
        dispose_list(freeable);
 }
 
-int shrink_icache_memory(int priority, int gfp_mask)
+int shrink_icache_memory(int priority, int gfp_mask, zone_t *zone)
 {
        if (gfp_mask & __GFP_IO)
        {
index c5f571ce1fb745f60e3e9d5bf1c83e81002e1490..82260bd5d83032fb48f3daf49e69f4541ec59aac 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -789,6 +789,9 @@ asmlinkage long sys_open(const char * filename, int flags, int mode)
        char * tmp;
        int fd, error;
 
+#if BITS_PER_LONG != 32
+       flags |= O_LARGEFILE;
+#endif
        tmp = getname(filename);
        fd = PTR_ERR(tmp);
        if (!IS_ERR(tmp)) {
index 2e17d81d499fff3a683128a6fd3a3f61b74994c9..15eb7420f7f2a30eb400ef60bdd4e9f8d4d1ec7f 100644 (file)
 static loff_t udf_file_llseek(struct file *, loff_t, int);
 static ssize_t udf_file_read_adinicb (struct file *, char *, size_t, loff_t *);
 static ssize_t udf_file_write (struct file *, const char *, size_t, loff_t *);
-#if BITS_PER_LONG < 64
 static int udf_open_file(struct inode *, struct file *);
-#endif
 static int udf_release_file(struct inode *, struct file *);
 
 static struct file_operations udf_file_operations = {
        udf_file_llseek,        /* llseek */
        generic_file_read,      /* read */
        udf_file_write,         /* write */
-       NULL,                           /* readdir */
-       NULL,                           /* poll */
-       udf_ioctl,                      /* ioctl */
+       NULL,                   /* readdir */
+       NULL,                   /* poll */
+       udf_ioctl,              /* ioctl */
        generic_file_mmap,      /* mmap */
-#if BITS_PER_LONG == 64
-       NULL,                           /* open */
-#else
        udf_open_file,          /* open */
-#endif
-       NULL,                           /* flush */
+       NULL,                   /* flush */
        udf_release_file,       /* release */
        udf_sync_file,          /* fsync */
-       NULL,                           /* fasync */
-       NULL,                           /* check_media_change */
-       NULL,                           /* revalidate */
-       NULL                            /* lock */
+       NULL,                   /* fasync */
+       NULL,                   /* check_media_change */
+       NULL,                   /* revalidate */
+       NULL                    /* lock */
 };
 
 struct inode_operations udf_file_inode_operations = {
@@ -426,7 +420,6 @@ static int udf_release_file(struct inode * inode, struct file * filp)
        return 0;
 }
 
-#if BITS_PER_LONG < 64
 /*
  * udf_open_file
  *
@@ -435,6 +428,7 @@ static int udf_release_file(struct inode * inode, struct file * filp)
  *
  * DESCRIPTION
  *  Use this to disallow opening RW large files on 32 bit systems.
+ *  On 64 bit systems we force on O_LARGEFILE in sys_open.
  *
  * HISTORY
  *
@@ -445,4 +439,3 @@ static int udf_open_file(struct inode * inode, struct file * filp)
                return -EFBIG;
        return 0;
 }
-#endif
index 9ba84dbf2cd6e4160e370a5bbc9a4a997d970502..9d7a09fe1f616302ea0803f700076dc1e49dab24 100644 (file)
@@ -20,6 +20,7 @@
 #define O_DIRECT       040000  /* direct disk access - should check with OSF/1 */
 #define O_DIRECTORY    0100000 /* must be a directory */
 #define O_NOFOLLOW     0200000 /* don't follow links */
+#define O_LARGEFILE    0400000 /* will be set by the kernel on every open */
 
 #define F_DUPFD                0       /* dup */
 #define F_GETFD                1       /* get f_flags */
index addaea876b28ed711fa789b7695a5d366bd1b71f..6cd9c0992a3fc0ed1125e50e4fd97d1eb08b8c43 100644 (file)
@@ -48,24 +48,6 @@ unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
        return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL);
 }
 
-#if 0
-
-/* Not used at the moment. It is difficult to imagine for what purpose
-   it can be used :-) Please, do not forget to verify_area before it --ANK
- */
-
-/*
- * This combination is currently not used, but possible:
- */
-
-extern __inline__
-unsigned int csum_partial_copy_to_user ( const char *src, char *dst,
-                                       int len, int sum, int *err_ptr)
-{
-       return csum_partial_copy_generic ( src, dst, len, sum, NULL, err_ptr);
-}
-#endif
-
 /*
  * These are the old (and unsafe) way of doing checksums, a warning message will be
  * printed if they are used and an exeption occurs.
index e552cfc6af38473d8626080bf7fca3407063cd46..625ff3bda7e97ebc63c467aee2b102bb721720f7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: checksum.h,v 1.29 1999/03/21 05:22:07 davem Exp $ */
+/* $Id: checksum.h,v 1.30 2000/01/05 21:27:39 davem Exp $ */
 #ifndef __SPARC_CHECKSUM_H
 #define __SPARC_CHECKSUM_H
 
@@ -30,7 +30,7 @@
  *
  * it's best to have buff aligned on a 32-bit boundary
  */
-extern unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum);
+extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
 
 /* the same as csum_partial, but copies from fs:src while it
  * checksums
index 002cd6218ec82abcd0142bd88c1f8a55d3aaeb49..757012fc546d7261e971c74002a45abe4af9ea45 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.59 1999/12/21 14:09:43 jj Exp $ */
+/* $Id: unistd.h,v 1.60 2000/01/05 07:37:50 jj Exp $ */
 #ifndef _SPARC_UNISTD_H
 #define _SPARC_UNISTD_H
 
 type name(void) \
 { \
 long __res; \
-__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
-                     "t 0x10\n\t" \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+__asm__ __volatile__ ("t 0x10\n\t" \
                      "bcc 1f\n\t" \
-                     "or %%g0, %%o0, %0\n\t" \
+                     "mov %%o0, %0\n\t" \
                      "sub %%g0, %%o0, %0\n\t" \
                      "1:\n\t" \
                      : "=r" (__res)\
-                     : "0" (__NR_##name) \
-                     : "g1", "o0", "cc"); \
+                     : "r" (__g1) \
+                     : "o0", "cc"); \
 if (__res < -255 || __res >= 0) \
     return (type) __res; \
 errno = -__res; \
@@ -295,16 +295,16 @@ return -1; \
 type name(type1 arg1) \
 { \
 long __res; \
-__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
-                     "or %%g0, %1, %%o0\n\t" \
-                     "t 0x10\n\t" \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+register long __o0 __asm__ ("o0") = (long)(arg1); \
+__asm__ __volatile__ ("t 0x10\n\t" \
                      "bcc 1f\n\t" \
-                     "or %%g0, %%o0, %0\n\t" \
+                     "mov %%o0, %0\n\t" \
                      "sub %%g0, %%o0, %0\n\t" \
                      "1:\n\t" \
-                     : "=r" (__res), "=r" ((long)(arg1)) \
-                     : "0" (__NR_##name),"1" ((long)(arg1)) \
-                     : "g1", "o0", "cc"); \
+                     : "=r" (__res), "=&r" (__o0) \
+                     : "1" (__o0), "r" (__g1) \
+                     : "cc"); \
 if (__res < -255 || __res >= 0) \
        return (type) __res; \
 errno = -__res; \
@@ -315,17 +315,17 @@ return -1; \
 type name(type1 arg1,type2 arg2) \
 { \
 long __res; \
-__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
-                     "or %%g0, %1, %%o0\n\t" \
-                     "or %%g0, %2, %%o1\n\t" \
-                     "t 0x10\n\t" \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+register long __o0 __asm__ ("o0") = (long)(arg1); \
+register long __o1 __asm__ ("o1") = (long)(arg2); \
+__asm__ __volatile__ ("t 0x10\n\t" \
                      "bcc 1f\n\t" \
-                     "or %%g0, %%o0, %0\n\t" \
+                     "mov %%o0, %0\n\t" \
                      "sub %%g0, %%o0, %0\n\t" \
                      "1:\n\t" \
-                     : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)) \
-                     : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)) \
-                     : "g1", "o0", "o1", "cc"); \
+                     : "=r" (__res), "=&r" (__o0) \
+                     : "1" (__o0), "r" (__o1), "r" (__g1) \
+                     : "cc"); \
 if (__res < -255 || __res >= 0) \
        return (type) __res; \
 errno = -__res; \
@@ -336,20 +336,18 @@ return -1; \
 type name(type1 arg1,type2 arg2,type3 arg3) \
 { \
 long __res; \
-__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
-                     "or %%g0, %1, %%o0\n\t" \
-                     "or %%g0, %2, %%o1\n\t" \
-                     "or %%g0, %3, %%o2\n\t" \
-                     "t 0x10\n\t" \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+register long __o0 __asm__ ("o0") = (long)(arg1); \
+register long __o1 __asm__ ("o1") = (long)(arg2); \
+register long __o2 __asm__ ("o2") = (long)(arg3); \
+__asm__ __volatile__ ("t 0x10\n\t" \
                      "bcc 1f\n\t" \
-                     "or %%g0, %%o0, %0\n\t" \
+                     "mov %%o0, %0\n\t" \
                      "sub %%g0, %%o0, %0\n\t" \
                      "1:\n\t" \
-                     : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
-                       "=r" ((long)(arg3)) \
-                     : "0" (__NR_##name), "1" ((long)(arg1)), "2" ((long)(arg2)), \
-                       "3" ((long)(arg3)) \
-                     : "g1", "o0", "o1", "o2", "cc"); \
+                     : "=r" (__res), "=&r" (__o0) \
+                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \
+                     : "cc"); \
 if (__res < -255 || __res>=0) \
        return (type) __res; \
 errno = -__res; \
@@ -360,21 +358,19 @@ return -1; \
 type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
 { \
 long __res; \
-__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
-                     "or %%g0, %1, %%o0\n\t" \
-                     "or %%g0, %2, %%o1\n\t" \
-                     "or %%g0, %3, %%o2\n\t" \
-                     "or %%g0, %4, %%o3\n\t" \
-                     "t 0x10\n\t" \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+register long __o0 __asm__ ("o0") = (long)(arg1); \
+register long __o1 __asm__ ("o1") = (long)(arg2); \
+register long __o2 __asm__ ("o2") = (long)(arg3); \
+register long __o3 __asm__ ("o3") = (long)(arg4); \
+__asm__ __volatile__ ("t 0x10\n\t" \
                      "bcc 1f\n\t" \
-                     "or %%g0, %%o0, %0\n\t" \
-                     "sub %%g0,%%o0, %0\n\t" \
+                     "mov %%o0, %0\n\t" \
+                     "sub %%g0, %%o0, %0\n\t" \
                      "1:\n\t" \
-                     : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
-                       "=r" ((long)(arg3)), "=r" ((long)(arg4)) \
-                     : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \
-                       "3" ((long)(arg3)),"4" ((long)(arg4)) \
-                     : "g1", "o0", "o1", "o2", "o3", "cc"); \
+                     : "=r" (__res), "=&r" (__o0) \
+                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \
+                     : "cc"); \
 if (__res < -255 || __res>=0) \
        return (type) __res; \
 errno = -__res; \
@@ -385,24 +381,21 @@ return -1; \
          type5,arg5) \
 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
 { \
-      long __res; \
-\
-__asm__ __volatile__ ("or %%g0, %1, %%o0\n\t" \
-                     "or %%g0, %2, %%o1\n\t" \
-                     "or %%g0, %3, %%o2\n\t" \
-                     "or %%g0, %4, %%o3\n\t" \
-                     "or %%g0, %5, %%o4\n\t" \
-                     "or %%g0, %6, %%g1\n\t" \
-                     "t 0x10\n\t" \
+long __res; \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+register long __o0 __asm__ ("o0") = (long)(arg1); \
+register long __o1 __asm__ ("o1") = (long)(arg2); \
+register long __o2 __asm__ ("o2") = (long)(arg3); \
+register long __o3 __asm__ ("o3") = (long)(arg4); \
+register long __o4 __asm__ ("o4") = (long)(arg5); \
+__asm__ __volatile__ ("t 0x10\n\t" \
                      "bcc 1f\n\t" \
-                     "or %%g0, %%o0, %0\n\t" \
+                     "mov %%o0, %0\n\t" \
                      "sub %%g0, %%o0, %0\n\t" \
                      "1:\n\t" \
-                     : "=r" (__res) \
-                     : "r" ((long)(arg1)),"r" ((long)(arg2)), \
-                       "r" ((long)(arg3)),"r" ((long)(arg4)),"r" ((long)(arg5)), \
-                       "i" (__NR_##name)  \
-                     : "g1", "o0", "o1", "o2", "o3", "o4", "cc"); \
+                     : "=r" (__res), "=&r" (__o0) \
+                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \
+                     : "cc"); \
 if (__res < -255 || __res>=0) \
        return (type) __res; \
 errno = -__res; \
index 519074118437e9f079dbbcf12c12e2b62de6c976..6f6f8fe06a660087b8cf45aa5430c30e7af0cfcc 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: checksum.h,v 1.13 1999/07/30 09:31:13 davem Exp $ */
+/* $Id: checksum.h,v 1.14 2000/01/05 21:27:42 davem Exp $ */
 #ifndef __SPARC64_CHECKSUM_H
 #define __SPARC64_CHECKSUM_H
 
@@ -29,7 +29,7 @@
  *
  * it's best to have buff aligned on a 32-bit boundary
  */
-extern unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum);
+extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
 
 /* the same as csum_partial, but copies from user space while it
  * checksums
@@ -67,7 +67,7 @@ csum_partial_copy_from_user(const char *src, char *dst, int len,
 }
 
 #if 0
-/* Not implemented, but nobody uses it yet... */
+/* XXX should implement this now... -DaveM */
 extern __inline__ unsigned int 
 csum_partial_copy_to_user(const char *src, char *dst, int len, 
                          unsigned int sum, int *err)
index e0352b8d921b88b35a57492735c0ebc2f0a7bcc5..a5538694477508c8f23dc099a588a8becb2c92d5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fcntl.h,v 1.5 1998/10/26 20:03:15 davem Exp $ */
+/* $Id: fcntl.h,v 1.7 2000/01/04 23:54:58 davem Exp $ */
 #ifndef _SPARC64_FCNTL_H
 #define _SPARC64_FCNTL_H
 
@@ -19,6 +19,7 @@
 #define O_NOCTTY       0x8000  /* not fcntl */
 #define O_DIRECTORY    0x10000 /* must be a directory */
 #define O_NOFOLLOW     0x20000 /* don't follow links */
+#define O_LARGEFILE    0x40000
 
 #define F_DUPFD                0       /* dup */
 #define F_GETFD                1       /* get f_flags */
index 6d3ce0f2137f7714bb79ce69db51efc3c55b5ccc..8c9b29bc6ffceb33ac1c12dc2f83bbf6f2d859ca 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.36 1999/12/21 14:09:51 jj Exp $ */
+/* $Id: unistd.h,v 1.37 2000/01/05 07:37:55 jj Exp $ */
 #ifndef _SPARC64_UNISTD_H
 #define _SPARC64_UNISTD_H
 
 type name(void) \
 { \
 long __res; \
-__asm__ __volatile__ ("mov %0, %%g1\n\t" \
-                     "t 0x6d\n\t" \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+__asm__ __volatile__ ("t 0x6d\n\t" \
                      "sub %%g0, %%o0, %0\n\t" \
                      "movcc %%xcc, %%o0, %0\n\t" \
                      : "=r" (__res)\
-                     : "0" (__NR_##name) \
-                     : "g1", "o0", "cc"); \
+                     : "r" (__g1) \
+                     : "o0", "cc"); \
 if (__res >= 0) \
     return (type) __res; \
 errno = -__res; \
@@ -293,14 +293,14 @@ return -1; \
 type name(type1 arg1) \
 { \
 long __res; \
-__asm__ __volatile__ ("mov %0, %%g1\n\t" \
-                     "mov %1, %%o0\n\t" \
-                     "t 0x6d\n\t" \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+register long __o0 __asm__ ("o0") = (long)(arg1); \
+__asm__ __volatile__ ("t 0x6d\n\t" \
                      "sub %%g0, %%o0, %0\n\t" \
                      "movcc %%xcc, %%o0, %0\n\t" \
-                     : "=r" (__res), "=r" ((long)(arg1)) \
-                     : "0" (__NR_##name),"1" ((long)(arg1)) \
-                     : "g1", "o0", "cc"); \
+                     : "=r" (__res), "=&r" (__o0) \
+                     : "1" (__o0), "r" (__g1) \
+                     : "cc"); \
 if (__res >= 0) \
        return (type) __res; \
 errno = -__res; \
@@ -311,15 +311,15 @@ return -1; \
 type name(type1 arg1,type2 arg2) \
 { \
 long __res; \
-__asm__ __volatile__ ("mov %0, %%g1\n\t" \
-                     "mov %1, %%o0\n\t" \
-                     "mov %2, %%o1\n\t" \
-                     "t 0x6d\n\t" \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+register long __o0 __asm__ ("o0") = (long)(arg1); \
+register long __o1 __asm__ ("o1") = (long)(arg2); \
+__asm__ __volatile__ ("t 0x6d\n\t" \
                      "sub %%g0, %%o0, %0\n\t" \
                      "movcc %%xcc, %%o0, %0\n\t" \
-                     : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)) \
-                     : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)) \
-                     : "g1", "o0", "o1", "cc"); \
+                     : "=r" (__res), "=&r" (__o0) \
+                     : "1" (__o0), "r" (__o1), "r" (__g1) \
+                     : "cc"); \
 if (__res >= 0) \
        return (type) __res; \
 errno = -__res; \
@@ -330,18 +330,16 @@ return -1; \
 type name(type1 arg1,type2 arg2,type3 arg3) \
 { \
 long __res; \
-__asm__ __volatile__ ("mov %0, %%g1\n\t" \
-                     "mov %1, %%o0\n\t" \
-                     "mov %2, %%o1\n\t" \
-                     "mov %3, %%o2\n\t" \
-                     "t 0x6d\n\t" \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+register long __o0 __asm__ ("o0") = (long)(arg1); \
+register long __o1 __asm__ ("o1") = (long)(arg2); \
+register long __o2 __asm__ ("o2") = (long)(arg3); \
+__asm__ __volatile__ ("t 0x6d\n\t" \
                      "sub %%g0, %%o0, %0\n\t" \
                      "movcc %%xcc, %%o0, %0\n\t" \
-                     : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
-                       "=r" ((long)(arg3)) \
-                     : "0" (__NR_##name), "1" ((long)(arg1)), "2" ((long)(arg2)), \
-                       "3" ((long)(arg3)) \
-                     : "g1", "o0", "o1", "o2", "cc"); \
+                     : "=r" (__res), "=&r" (__o0) \
+                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \
+                     : "cc"); \
 if (__res>=0) \
        return (type) __res; \
 errno = -__res; \
@@ -352,19 +350,17 @@ return -1; \
 type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
 { \
 long __res; \
-__asm__ __volatile__ ("mov %0, %%g1\n\t" \
-                     "mov %1, %%o0\n\t" \
-                     "mov %2, %%o1\n\t" \
-                     "mov %3, %%o2\n\t" \
-                     "mov %4, %%o3\n\t" \
-                     "t 0x6d\n\t" \
-                     "sub %%g0,%%o0, %0\n\t" \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+register long __o0 __asm__ ("o0") = (long)(arg1); \
+register long __o1 __asm__ ("o1") = (long)(arg2); \
+register long __o2 __asm__ ("o2") = (long)(arg3); \
+register long __o3 __asm__ ("o3") = (long)(arg4); \
+__asm__ __volatile__ ("t 0x6d\n\t" \
+                     "sub %%g0, %%o0, %0\n\t" \
                      "movcc %%xcc, %%o0, %0\n\t" \
-                     : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
-                       "=r" ((long)(arg3)), "=r" ((long)(arg4)) \
-                     : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \
-                       "3" ((long)(arg3)),"4" ((long)(arg4)) \
-                     : "g1", "o0", "o1", "o2", "o3", "cc"); \
+                     : "=r" (__res), "=&r" (__o0) \
+                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \
+                     : "cc"); \
 if (__res>=0) \
        return (type) __res; \
 errno = -__res; \
@@ -375,22 +371,19 @@ return -1; \
          type5,arg5) \
 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
 { \
-      long __res; \
-\
-__asm__ __volatile__ ("mov %1, %%o0\n\t" \
-                     "mov %2, %%o1\n\t" \
-                     "mov %3, %%o2\n\t" \
-                     "mov %4, %%o3\n\t" \
-                     "mov %5, %%o4\n\t" \
-                     "mov %6, %%g1\n\t" \
-                     "t 0x6d\n\t" \
+long __res; \
+register long __g1 __asm__ ("g1") = __NR_##name; \
+register long __o0 __asm__ ("o0") = (long)(arg1); \
+register long __o1 __asm__ ("o1") = (long)(arg2); \
+register long __o2 __asm__ ("o2") = (long)(arg3); \
+register long __o3 __asm__ ("o3") = (long)(arg4); \
+register long __o4 __asm__ ("o4") = (long)(arg5); \
+__asm__ __volatile__ ("t 0x6d\n\t" \
                      "sub %%g0, %%o0, %0\n\t" \
                      "movcc %%xcc, %%o0, %0\n\t" \
-                     : "=r" (__res) \
-                     : "r" ((long)(arg1)),"r" ((long)(arg2)), \
-                       "r" ((long)(arg3)),"r" ((long)(arg4)),"r" ((long)(arg5)), \
-                       "i" (__NR_##name)  \
-                     : "g1", "o0", "o1", "o2", "o3", "o4", "cc"); \
+                     : "=r" (__res), "=&r" (__o0) \
+                     : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \
+                     : "cc"); \
 if (__res>=0) \
        return (type) __res; \
 errno = -__res; \
index 594f891afb5bcf86fe8b9da021c3d80175908447..aba8430a246ccc1ea33a1ef275c5f598f789968f 100644 (file)
@@ -360,16 +360,6 @@ static void floppy_off(unsigned int nr);
 
 #elif (MAJOR_NR == COMPAQ_SMART2_MAJOR)
 
-#define DEVICE_NAME "ida"
-#define DEVICE_INTR do_ida
-#define TIMEOUT_VALUE (25*HZ)
-#define DEVICE_REQUEST do_ida_request0
-#define DEVICE_NR(device) (MINOR(device) >> 4)
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == COMPAQ_SMART2_MAJOR)
-
 #define DEVICE_NAME "ida"
 #define TIMEOUT_VALUE (25*HZ)
 #define DEVICE_REQUEST do_ida_request0
index 0ae06753fc518d744c1b0a865c85287ce5e29efa..3dfa8f67dd1994a73f83e514756d40973a427c52 100644 (file)
@@ -136,13 +136,13 @@ extern void shrink_dcache_parent(struct dentry *);
 extern int d_invalidate(struct dentry *);
 
 #define shrink_dcache() prune_dcache(0)
-
+struct zone_struct;
 /* dcache memory management */
-extern int shrink_dcache_memory(int, unsigned int);
+extern int shrink_dcache_memory(int, unsigned int, struct zone_struct *);
 extern void prune_dcache(int);
 
 /* icache memory management (defined in linux/fs/inode.c) */
-extern int shrink_icache_memory(int, int);
+extern int shrink_icache_memory(int, int, struct zone_struct *);
 extern void prune_icache(int);
 
 /* only used at mount-time */
index 4a16756d9623767f0939fdd55402fa826d51de2e..0d87e62ec9e71ca9c61c7953126b1c7bdc0143d1 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef _LINUX_ERRQUEUE_H
 #define _LINUX_ERRQUEUE_H 1
 
-#include <linux/config.h>
-
 struct sock_extended_err
 {
        __u32   ee_errno;       
@@ -22,6 +20,9 @@ struct sock_extended_err
 #define SO_EE_OFFENDER(ee)     ((struct sockaddr*)((ee)+1))
 
 #ifdef __KERNEL__
+
+#include <linux/config.h>
+
 #define SKB_EXT_ERR(skb) ((struct sock_exterr_skb *) ((skb)->cb))
 
 struct sock_exterr_skb
index cd5f3139164e8656009570bec524c54248fa64b5..a9c9ef5f03f924ae3fd6d394997780b705e688ec 100644 (file)
 
 #define IFF_MULTICAST  0x1000          /* Supports multicast           */
 
-#define IFF_VOLATILE   (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ALLMULTI)
+#define IFF_VOLATILE   (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_MASTER|IFF_SLAVE|IFF_RUNNING)
 
 #define IFF_PORTSEL    0x2000          /* can set media type           */
 #define IFF_AUTOMEDIA  0x4000          /* auto media select active     */
 #define IFF_DYNAMIC    0x8000          /* dialup device with changing addresses*/
 
-#ifdef __KERNEL__
-/*
- * The ifaddr structure contains information about one address
- * of an interface.  They are maintained by the different address
- * families, are allocated and attached when an address is set,
- * and are linked together so all addresses for an interface can
- * be located.
- */
-struct ifaddr 
-{
-       struct sockaddr ifa_addr;       /* address of interface         */
-       union {
-               struct sockaddr ifu_broadaddr;
-               struct sockaddr ifu_dstaddr;
-       } ifa_ifu;
-       struct iface            *ifa_ifp;       /* back-pointer to interface    */
-       struct ifaddr           *ifa_next;      /* next address for interface   */
-};
-
-#define        ifa_broadaddr   ifa_ifu.ifu_broadaddr   /* broadcast address    */
-#define        ifa_dstaddr     ifa_ifu.ifu_dstaddr     /* other end of link    */
-
-#endif /* __KERNEL__ */ 
-
 /*
  *     Device mapping structure. I'd just gone off and designed a 
  *     beautiful scheme using only loadable modules with arguments
index 6675cee9582ee5895572d706b51a1baee65a4a2e..7b642728ae9e1f94c413b690c9af06790dafa478 100644 (file)
@@ -88,6 +88,8 @@
 #define        IPOPT_TS_TSANDADDR      1               /* timestamps and addresses */
 #define        IPOPT_TS_PRESPEC        3               /* specified modules only */
 
+#ifdef __KERNEL__
+
 struct ip_options {
   __u32                faddr;                          /* Saved first hop address */
   unsigned char        optlen;
@@ -108,7 +110,6 @@ struct ip_options {
   unsigned char __data[0];
 };
 
-#ifdef __KERNEL__
 #define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
 #endif
 
index d01a0216ad0e85eb1c8f7332ed482aee1ec5c7a8..d8532c2fc45e9840c5b2184f8255cbdaa176d184 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Mar  8 14:06:12 1999
- * Modified at:   Tue Dec 21 09:00:59 1999
+ * Modified at:   Sat Dec 25 16:06:42 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -20,9 +20,6 @@
  *     provide warranty for any of this software. This material is 
  *     provided "AS-IS" and at no charge.
  *
- *     You probably need to include <sys/types.h> before this one if your
- *     including this file from user-space 
- *
  ********************************************************************/
 
 #ifndef KERNEL_IRDA_H
@@ -100,22 +97,22 @@ enum {
 #define LSAP_ANY              0xff
 
 struct sockaddr_irda {
-       sa_family_t   sir_family;   /* AF_IRDA */
-       u_int8_t      sir_lsap_sel; /* LSAP selector */
-       u_int32_t     sir_addr;     /* Device address */
-       char          sir_name[25]; /* Usually <service>:IrDA:TinyTP */
+       sa_family_t sir_family;   /* AF_IRDA */
+       __u8        sir_lsap_sel; /* LSAP selector */
+       __u32       sir_addr;     /* Device address */
+       char        sir_name[25]; /* Usually <service>:IrDA:TinyTP */
 };
 
 struct irda_device_info {
-       u_int32_t     saddr;    /* Address of local interface */
-       u_int32_t     daddr;    /* Address of remote device */
-       char          info[22]; /* Description */
-       u_int8_t      charset;  /* Charset used for description */
-       u_int8_t      hints[2]; /* Hint bits */
+       __u32       saddr;    /* Address of local interface */
+       __u32       daddr;    /* Address of remote device */
+       char        info[22]; /* Description */
+       __u8        charset;  /* Charset used for description */
+       __u8        hints[2]; /* Hint bits */
 };
 
 struct irda_device_list {
-       u_int32_t len;
+       __u32 len;
        struct irda_device_info dev[1];
 };
 
@@ -127,12 +124,12 @@ struct irda_ias_set {
                unsigned int irda_attrib_int;
                struct {
                        unsigned short len;
-                       u_char OctetSeq[IAS_MAX_OCTET_STRING];
+                       __u8 octet_seq[IAS_MAX_OCTET_STRING];
                } irda_attrib_octet_seq;
                struct {
-                       unsigned char len;
-                       unsigned char charset;
-                       unsigned char string[IAS_MAX_STRING];
+                       __u8 len;
+                       __u8 charset;
+                       __u8 string[IAS_MAX_STRING];
                } irda_attrib_string;
        } attribute;
 };
@@ -165,8 +162,8 @@ struct if_irda_qos {
 
 /* For setting RTS and DTR lines of a dongle */
 struct if_irda_line {
-       unsigned char dtr;
-       unsigned char rts;
+       __u8 dtr;
+       __u8 rts;
 };
 
 /* IrDA interface configuration (data part must not exceed 16 bytes) */
index 1ec294a3b5a47b5d4c4425d078127c9a7fdd571e..66368dfcb48179a1749da80aaffb750a5d90ff62 100644 (file)
@@ -103,6 +103,13 @@ struct isapnp_mem32 {
        struct isapnp_mem32 *next;      /* next 32-bit memory resource */
 };
 
+struct isapnp_fixup {
+       unsigned short vendor;          /* matching vendor */
+       unsigned short device;          /* matching device */
+       void (*quirk_function)(struct pci_dev *dev);    /* fixup function */
+};
+
+
 #define ISAPNP_RES_PRIORITY_PREFERRED  0
 #define ISAPNP_RES_PRIORITY_ACCEPTABLE 1
 #define ISAPNP_RES_PRIORITY_FUNCTIONAL 2
@@ -137,6 +144,8 @@ void isapnp_wake(unsigned char csn);
 void isapnp_device(unsigned char device);
 void isapnp_activate(unsigned char device);
 void isapnp_deactivate(unsigned char device);
+void isapnp_fixup_device(struct pci_dev *dev);
+void *isapnp_alloc(long size);
 /* manager */
 struct pci_bus *isapnp_find_card(unsigned short vendor,
                                 unsigned short device,
index f33f47eb770de41045f37db41b2be6313c54e9c0..b2f7487bff105195617618fde18d70bad5d6172c 100644 (file)
@@ -183,7 +183,6 @@ typedef struct page {
 #define ClearPageError(page)   clear_bit(PG_error, &(page)->flags)
 #define PageReferenced(page)   test_bit(PG_referenced, &(page)->flags)
 #define PageDecrAfter(page)    test_bit(PG_decr_after, &(page)->flags)
-#define PageDMA(page)          (contig_page_data.node_zones + ZONE_DMA == (page)->zone)
 #define PageSlab(page)         test_bit(PG_slab, &(page)->flags)
 #define PageSwapCache(page)    test_bit(PG_swap_cache, &(page)->flags)
 #define PageReserved(page)     test_bit(PG_reserved, &(page)->flags)
@@ -432,10 +431,11 @@ out:
 extern int do_munmap(unsigned long, size_t);
 extern unsigned long do_brk(unsigned long, unsigned long);
 
+struct zone_t;
 /* filemap.c */
 extern void remove_inode_page(struct page *);
 extern unsigned long page_unuse(struct page *);
-extern int shrink_mmap(int, int);
+extern int shrink_mmap(int, int, zone_t *);
 extern void truncate_inode_pages(struct inode *, loff_t);
 
 /* generic vm_area_ops exported for stackable file systems */
index 79c206282dc689a511ae1ddf8e4255979f27c496..540bd8adab6bbcb795b22300953dcadcbd9c2b67 100644 (file)
@@ -25,6 +25,8 @@ typedef struct free_area_struct {
        unsigned int * map;
 } free_area_t;
 
+struct pglist_data;
+
 typedef struct zone_struct {
        /*
         * Commonly accessed fields:
@@ -34,6 +36,7 @@ typedef struct zone_struct {
        unsigned long free_pages;
        int low_on_memory;
        unsigned long pages_low, pages_high;
+       struct pglist_data *zone_pgdat;
 
        /*
         * free areas of different sizes
@@ -81,6 +84,10 @@ typedef struct pglist_data {
 
 extern int numnodes;
 
+#define memclass(pgzone, tzone)        (((pgzone)->zone_pgdat == (tzone)->zone_pgdat) \
+                       && (((pgzone) - (pgzone)->zone_pgdat->node_zones) <= \
+                       ((tzone) - (pgzone)->zone_pgdat->node_zones)))
+
 #ifndef CONFIG_DISCONTIGMEM
 
 extern pg_data_t contig_page_data;
index 1f4db9eec4c897afac5eaaceba62ad9b20581352..c6e6bc61c0ff9303eca38c1b0775f74a8582d0b7 100644 (file)
@@ -24,7 +24,6 @@
 #ifndef _LINUX_NETDEVICE_H
 #define _LINUX_NETDEVICE_H
 
-#include <linux/config.h>
 #include <linux/if.h>
 #include <linux/if_ether.h>
 #include <linux/if_packet.h>
@@ -32,6 +31,7 @@
 #include <asm/atomic.h>
 
 #ifdef __KERNEL__
+#include <linux/config.h>
 #ifdef CONFIG_NET_PROFILE
 #include <net/profile.h>
 #endif
index 432741a475a25cbb2b9c165b5ae4b04f2ee8ebdc..e8f6c7328fe431fdd1ca121304fe60a6381086b6 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef __LINUX_RTNETLINK_H
 #define __LINUX_RTNETLINK_H
 
-#include <linux/config.h>
 #include <linux/netlink.h>
 
 #define RTNL_DEBUG 1
@@ -530,6 +529,8 @@ enum
 
 #ifdef __KERNEL__
 
+#include <linux/config.h>
+
 extern __inline__ int rtattr_strcmp(struct rtattr *rta, char *str)
 {
        int len = strlen(str) + 1;
index 36590d49cbdc8582f99e1e28d1f118c8a4098ed0..04e23d8276093045dfa6290fc1efe7ff6475063a 100644 (file)
@@ -507,10 +507,12 @@ extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q,
                                                    signed long timeout));
 extern void FASTCALL(wake_up_process(struct task_struct * tsk));
 
-#define wake_up(x)                     __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE)
-#define wake_up_sync(x)                        __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE)
-#define wake_up_interruptible(x)       __wake_up((x),TASK_INTERRUPTIBLE)
-#define wake_up_interruptible_sync(x)  __wake_up_sync((x),TASK_INTERRUPTIBLE)
+#define wake_up(x)                     __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE | TASK_EXCLUSIVE)
+#define wake_up_all(x)                 __wake_up_all((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE)
+#define wake_up_sync(x)                        __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE | TASK_EXCLUSIVE)
+#define wake_up_interruptible(x)       __wake_up((x),TASK_INTERRUPTIBLE | TASK_EXCLUSIVE)
+#define wake_up_interruptible_all(x)   __wake_up_all((x),TASK_INTERRUPTIBLE)
+#define wake_up_interruptible_sync(x)  __wake_up_sync((x),TASK_INTERRUPTIBLE | TASK_EXCLUSIVE)
 
 extern int in_group_p(gid_t);
 extern int in_egroup_p(gid_t);
index 353cba2708f869ea354abf7ccaecee1b22df5a1d..e81efcaf8032d34ae7d9168641e1132caa4a980d 100644 (file)
@@ -106,7 +106,7 @@ __KINLINE struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
 
        __ptr = (struct cmsghdr*)(((unsigned char *) __cmsg) +  CMSG_ALIGN(__cmsg->cmsg_len));
        if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
-               return NULL;
+               return (struct cmsghdr *)0;
 
        return __ptr;
 }
@@ -248,15 +248,6 @@ struct ucred {
 /* IPX options */
 #define IPX_TYPE       1
 
-/* TCP options - this way around because someone left a set in the c library includes */
-#define TCP_NODELAY    1
-#define TCP_MAXSEG     2
-#define TCP_CORK       3       /* Linux specific (for use with sendfile) */
-#define TCP_KEEPIDLE   4
-#define TCP_KEEPINTVL  5
-#define TCP_KEEPCNT    6
-#define TCP_SYNCNT     7
-
 #ifdef __KERNEL__
 extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
 extern int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, 
index 18ea45e63b1e8a5a5749b1f03c3c29bf2b3a8698..2e7e27e252fb47d5ab7c88f5d19adc7603299aeb 100644 (file)
@@ -78,14 +78,15 @@ struct task_struct;
 struct vm_area_struct;
 struct sysinfo;
 
+struct zone_t;
 /* linux/ipc/shm.c */
-extern int shm_swap (int, int);
+extern int shm_swap (int, int, zone_t *);
 
 /* linux/mm/swap.c */
 extern void swap_setup (void);
 
 /* linux/mm/vmscan.c */
-extern int try_to_free_pages(unsigned int gfp_mask);
+extern int try_to_free_pages(unsigned int gfp_mask, zone_t *zone);
 
 /* linux/mm/page_io.c */
 extern void rw_swap_page(int, struct page *, int);
index 73796d6c431a60c70b23ebd4b652ff5d4a29f77c..1e78e322c0227963b2c257bffcd3b51d91a17ee8 100644 (file)
@@ -34,11 +34,13 @@ struct tcphdr {
                psh:1,
                ack:1,
                urg:1,
-               res2:2;
+               ece:1,
+               cwr:1;
 #elif defined(__BIG_ENDIAN_BITFIELD)
        __u16   doff:4,
                res1:4,
-               res2:2,
+               cwr:1,
+               ece:1,
                urg:1,
                ack:1,
                psh:1,
@@ -100,6 +102,8 @@ union tcp_word_hdr {
 #define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3]) 
 
 enum { 
+       TCP_FLAG_CWR = __constant_htonl(0x00800000), 
+       TCP_FLAG_ECE = __constant_htonl(0x00400000), 
        TCP_FLAG_URG = __constant_htonl(0x00200000), 
        TCP_FLAG_ACK = __constant_htonl(0x00100000), 
        TCP_FLAG_PSH = __constant_htonl(0x00080000), 
@@ -110,4 +114,15 @@ enum {
        TCP_DATA_OFFSET = __constant_htonl(0xF0000000)
 }; 
 
+/* TCP socket options */
+#define TCP_NODELAY            1       /* Turn off Nagle's algorithm. */
+#define TCP_MAXSEG             2       /* Limit MSS */
+#define TCP_CORK               3       /* Never send partially complete segments */
+#define TCP_KEEPIDLE           4       /* Start keeplives after this period */
+#define TCP_KEEPINTVL          5       /* Interval between keepalives */
+#define TCP_KEEPCNT            6       /* Number of keepalives before death */
+#define TCP_SYNCNT             7       /* Number of SYN retransmits */
+#define TCP_LINGER2            8       /* Life time of orphaned FIN-WAIT-2 state */
+#define TCP_DEFER_ACCEPT       9       /* Wake up listener only when data arrive */
+
 #endif /* _LINUX_TCP_H */
index 041d476082f5c75ebcfb97808575c53c4c2f0655..de32869444c4e1983a619c8dc72772d3a81db4cb 100644 (file)
@@ -107,4 +107,22 @@ unsigned int csum_and_copy_from_user (const char *src, char *dst,
 }
 #endif
 
+#ifndef HAVE_CSUM_COPY_USER
+static __inline__ unsigned int csum_and_copy_to_user
+(const char *src, char *dst, int len, unsigned int sum, int *err_ptr)
+{
+       sum = csum_partial(src, len, sum);
+
+       if (access_ok(VERIFY_WRITE, dst, len)) {
+               if (copy_to_user(dst, src, len) == 0)
+                       return sum;
+       }
+       if (len)
+               *err_ptr = -EFAULT;
+
+       return -1; /* invalid checksum */
+}
+#endif
+
+
 #endif
index 1aba3faaea50f947d09286ad1afbbc278aa9987e..4222d5fa105cf8e93d33491c20715b6d4594b7e0 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Stable
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Dec  9 21:13:12 1997
- * Modified at:   Tue Dec 14 19:01:26 1999
+ * Modified at:   Sat Dec 25 18:58:49 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
@@ -101,7 +101,7 @@ if(!(expr)) { \
 #define IAS_ATTRIB_MAGIC   0x45232
 #define IRDA_TASK_MAGIC    0x38423
 
-#define IAS_DEVICE_ID 0x5342 
+#define IAS_DEVICE_ID 0x0000 /* Defined by IrDA, IrLMP section 4.1 (page 68) */
 #define IAS_PNP_ID    0xd342
 #define IAS_OBEX_ID   0x34323
 #define IAS_IRLAN_ID  0x34234
index 486897842dd2e161b4c07d85fda0664f897d35bc..cd0dff5a925f09eba25c00dccc40c2aa617f44b8 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Aug 21 00:02:07 1997
- * Modified at:   Tue Dec 14 21:55:18 1999
+ * Modified at:   Sat Dec 25 16:42:09 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1997-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -99,7 +99,7 @@ int iriap_getvaluebyclass_request(struct iriap_cb *self,
                                  __u32 saddr, __u32 daddr,
                                  char *name, char *attr);
 void iriap_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb);
-
+void iriap_connect_request(struct iriap_cb *self);
 void iriap_send_ack( struct iriap_cb *self);
 void iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb);
 
index e1d36e2fafa31406c1dfee66fad259050553eacb..2c28accc1e00a30d8dff1274b3db011cecd8a8ab 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Aug 19 10:27:26 1997
- * Modified at:   Tue Dec 21 11:10:12 1999
+ * Modified at:   Sat Dec 25 21:07:26 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1997-1999 Dag Brattli <dagb@cs.uit.no>,
@@ -113,7 +113,7 @@ struct snrm_frame {
 void irlap_send_discovery_xid_frame(struct irlap_cb *, int S, __u8 s, 
                                    __u8 command, discovery_t *discovery);
 void irlap_send_snrm_frame(struct irlap_cb *, struct qos_info *);
-void irlap_send_test_frame(struct irlap_cb *self, __u32 daddr, 
+void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr, 
                           struct sk_buff *cmd);
 void irlap_send_ua_response_frame(struct irlap_cb *, struct qos_info *);
 void irlap_send_dm_frame(struct irlap_cb *self);
index 779d34acc394b0cba42ddd69f1f43878d2bc838e..3df2aad31477f10bb3dfcf91cab9329d91fcf5d3 100644 (file)
@@ -26,7 +26,6 @@
 #ifndef IRMLP_FRAME_H
 #define IRMLP_FRAME_H
 
-#include <linux/config.h>
 #include <linux/skbuff.h>
 
 #include <net/irda/discovery.h>
index e219aafcf60b9ae909c37c2bcb8cddc48e1e5f0b..e79b45339723e6259947c90e7337737f773efac6 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug  3 13:49:59 1997
- * Modified at:   Sat Dec 11 14:34:18 1999
+ * Modified at:   Mon Jan  3 10:23:34 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997, 1998-1999 Dag Brattli <dagb@cs.uit.no>
+ *     Copyright (c) 1997, 1998-2000 Dag Brattli <dagb@cs.uit.no>
  *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
@@ -66,6 +66,7 @@ struct irport_cb {
        __u32 flags;               /* Interface flags */
        __u32 new_speed;
        int mode;
+       int index;                 /* Instance index */
 
        spinlock_t lock;           /* For serializing operations */
 
diff --git a/include/net/irda/nsc_fir.h b/include/net/irda/nsc_fir.h
new file mode 100644 (file)
index 0000000..bbfb4d7
--- /dev/null
@@ -0,0 +1,238 @@
+/*********************************************************************
+ *                
+ * Filename:      nsc_fir.h
+ * Version:       
+ * Description:   
+ * Status:        Experimental.
+ * Author:        Dag Brattli <dagb@cs.uit.no>
+ * Created at:    Fri Nov 13 14:37:40 1998
+ * Modified at:   Wed Jan  5 12:00:16 2000
+ * Modified by:   Dag Brattli <dagb@cs.uit.no>
+ * 
+ *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>
+ *     Copyright (c) 1998 Lichen Wang, <lwang@actisys.com>
+ *     Copyright (c) 1998 Actisys Corp., www.actisys.com
+ *     All Rights Reserved
+ *      
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version.
+ *  
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     provide warranty for any of this software. This material is 
+ *     provided "AS-IS" and at no charge.
+ *     
+ ********************************************************************/
+
+#ifndef NSC_FIR_H
+#define NSC_FIR_H
+
+#include <linux/time.h>
+
+#include <linux/spinlock.h>
+#include <asm/io.h>
+
+#define PC87108         0x10
+#define PC97338         0xb0
+
+/* DMA modes needed */
+#define DMA_TX_MODE     0x08    /* Mem to I/O, ++, demand. */
+#define DMA_RX_MODE     0x04    /* I/O to mem, ++, demand. */
+
+/* Flags for configuration register CRF0 */
+#define APEDCRC                0x02
+#define ENBNKSEL       0x01
+
+/* Set 0 */
+#define TXD             0x00 /* Transmit data port */
+#define RXD             0x00 /* Receive data port */
+
+/* Register 1 */
+#define IER            0x01 /* Interrupt Enable Register*/
+#define IER_RXHDL_IE    0x01 /* Receiver high data level interrupt */
+#define IER_TXLDL_IE    0x02 /* Transeiver low data level interrupt */
+#define IER_LS_IE      0x04//* Link Status Interrupt */
+#define IER_ETXURI      0x04 /* Tx underrun */
+#define IER_DMA_IE     0x10 /* DMA finished interrupt */
+#define IER_TXEMP_IE    0x20
+#define IER_SFIF_IE     0x40 /* Frame status FIFO intr */
+#define IER_TMR_IE      0x80 /* Timer event */
+
+#define FCR            0x02 /* (write only) */
+#define FCR_FIFO_EN     0x01 /* Enable FIFO's */
+#define FCR_RXSR        0x02 /* Rx FIFO soft reset */
+#define FCR_TXSR        0x04 /* Tx FIFO soft reset */
+#define FCR_RXTH       0x40 /* Rx FIFO threshold (set to 16) */
+#define FCR_TXTH       0x20 /* Tx FIFO threshold (set to 17) */
+
+#define EIR            0x02 /* (read only) */
+#define EIR_RXHDL_EV   0x01
+#define EIR_TXLDL_EV    0x02
+#define EIR_LS_EV      0x04
+#define EIR_DMA_EV     0x10
+#define EIR_TXEMP_EV   0x20
+#define EIR_SFIF_EV     0x40
+#define EIR_TMR_EV      0x80
+
+#define LCR             0x03 /* Link control register */
+#define LCR_WLS_8       0x03 /* 8 bits */
+
+#define BSR            0x03 /* Bank select register */
+#define BSR_BKSE        0x80
+#define BANK0          LCR_WLS_8 /* Must make sure that we set 8N1 */
+#define BANK1          0x80
+#define BANK2          0xe0
+#define BANK3          0xe4
+#define BANK4          0xe8
+#define BANK5          0xec
+#define BANK6          0xf0
+#define BANK7          0xf4
+
+#define MCR            0x04 /* Mode Control Register */
+#define MCR_MODE_MASK  ~(0xd0)
+#define MCR_UART        0x00
+#define MCR_RESERVED   0x20    
+#define MCR_SHARP_IR    0x40
+#define MCR_SIR         0x60
+#define MCR_MIR        0x80
+#define MCR_FIR                0xa0
+#define MCR_CEIR        0xb0
+#define MCR_IR_PLS      0x10
+#define MCR_DMA_EN     0x04
+#define MCR_EN_IRQ     0x08
+#define MCR_TX_DFR     0x08
+
+#define LSR             0x05 /* Link status register */
+#define LSR_RXDA        0x01 /* Receiver data available */
+#define LSR_TXRDY       0x20 /* Transmitter ready */
+#define LSR_TXEMP       0x40 /* Transmitter empty */
+
+#define ASCR            0x07 /* Auxillary Status and Control Register */
+#define ASCR_RXF_TOUT   0x01 /* Rx FIFO timeout */
+#define ASCR_FEND_INF   0x02 /* Frame end bytes in rx FIFO */
+#define ASCR_S_EOT      0x04 /* Set end of transmission */
+#define ASCT_RXBSY      0x20 /* Rx busy */
+#define ASCR_TXUR       0x40 /* Transeiver underrun */
+#define ASCR_CTE        0x80 /* Clear timer event */
+
+/* Bank 2 */
+#define BGDL            0x00 /* Baud Generator Divisor Port (Low Byte) */
+#define BGDH            0x01 /* Baud Generator Divisor Port (High Byte) */
+
+#define ECR1           0x02 /* Extended Control Register 1 */
+#define ECR1_EXT_SL    0x01 /* Extended Mode Select */
+#define ECR1_DMANF     0x02 /* DMA Fairness */
+#define ECR1_DMATH      0x04 /* DMA Threshold */
+#define ECR1_DMASWP    0x08 /* DMA Swap */
+
+#define EXCR2          0x04
+#define EXCR2_TFSIZ    0x01 /* Rx FIFO size = 32 */
+#define EXCR2_RFSIZ    0x04 /* Tx FIFO size = 32 */
+
+#define TXFLV           0x06 /* Tx FIFO level */
+#define RXFLV           0x07 /* Rx FIFO level */
+
+/* Bank 3 */
+#define MID            0x00
+
+/* Bank 4 */
+#define TMRL            0x00 /* Timer low byte */
+#define TMRH            0x01 /* Timer high byte */
+#define IRCR1           0x02 /* Infrared control register 1 */
+#define IRCR1_TMR_EN    0x01 /* Timer enable */
+
+#define TFRLL          0x04
+#define TFRLH          0x05
+#define RFRLL          0x06
+#define RFRLH          0x07
+
+/* Bank 5 */
+#define IRCR2           0x04 /* Infrared control register 2 */
+#define IRCR2_MDRS      0x04 /* MIR data rate select */
+#define IRCR2_FEND_MD   0x20 /* */
+
+#define FRM_ST          0x05 /* Frame status FIFO */
+#define FRM_ST_VLD      0x80 /* Frame status FIFO data valid */
+#define FRM_ST_ERR_MSK  0x5f
+#define FRM_ST_LOST_FR  0x40 /* Frame lost */
+#define FRM_ST_MAX_LEN  0x10 /* Max frame len exceeded */
+#define FRM_ST_PHY_ERR  0x08 /* Physical layer error */
+#define FRM_ST_BAD_CRC  0x04 
+#define FRM_ST_OVR1     0x02 /* Rx FIFO overrun */
+#define FRM_ST_OVR2     0x01 /* Frame status FIFO overrun */
+
+#define RFLFL           0x06
+#define RFLFH           0x07
+
+/* Bank 6 */
+#define IR_CFG2                0x00
+#define IR_CFG2_DIS_CRC        0x02
+
+/* Bank 7 */
+#define IRM_CR         0x07 /* Infrared module control register */
+#define IRM_CR_IRX_MSL 0x40
+#define IRM_CR_AF_MNT   0x80 /* Automatic format */
+
+/* For storing entries in the status FIFO */
+struct st_fifo_entry {
+       int status;
+       int len;
+};
+
+struct st_fifo {
+       struct st_fifo_entry entries[10];
+       int head;
+       int tail;
+       int len;
+};
+
+struct frame_cb {
+       void *start; /* Start of frame in DMA mem */
+       int len;     /* Lenght of frame in DMA mem */
+};
+
+#define MAX_WINDOW 7
+
+struct tx_fifo {
+       struct frame_cb queue[MAX_WINDOW]; /* Info about frames in queue */
+       int             ptr;               /* Currently being sent */
+       int             len;               /* Lenght of queue */
+       int             free;              /* Next free slot */
+       void           *tail;              /* Next free start in DMA mem */
+};
+
+/* Private data for each instance */
+struct nsc_fir_cb {
+       struct st_fifo st_fifo;    /* Info about received frames */
+       struct tx_fifo tx_fifo;    /* Info about frames to be transmitted */
+
+       int tx_buff_offsets[10];   /* Offsets between frames in tx_buff */
+       int tx_len;                /* Number of frames in tx_buff */
+
+       struct net_device *netdev;     /* Yes! we are some kind of netdevice */
+       struct net_device_stats stats;
+       
+       struct irlap_cb *irlap;    /* The link layer we are binded to */
+       
+       struct chipio_t io;        /* IrDA controller information */
+       struct iobuff_t tx_buff;   /* Transmit buffer */
+       struct iobuff_t rx_buff;   /* Receive buffer */
+       struct qos_info qos;       /* QoS capabilities for this device */
+
+       struct timeval  stamp;
+       struct timeval  now;
+
+       spinlock_t lock;           /* For serializing operations */
+       
+       __u32 flags;               /* Interface flags */
+       __u32 new_speed;
+       int suspend;
+};
+
+static inline void switch_bank(int iobase, int bank)
+{
+               outb(bank, iobase+BSR);
+}
+
+#endif /* NSC_FIR_H */
diff --git a/include/net/irda/pc87108.h b/include/net/irda/pc87108.h
deleted file mode 100644 (file)
index d7b63a3..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      pc87108.h
- * Version:       
- * Description:   
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Fri Nov 13 14:37:40 1998
- * Modified at:   Mon Nov  8 10:00:27 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>
- *     Copyright (c) 1998 Lichen Wang, <lwang@actisys.com>
- *     Copyright (c) 1998 Actisys Corp., www.actisys.com
- *     All Rights Reserved
- *      
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
- *     
- ********************************************************************/
-
-#ifndef PC87108_H
-#define PC87108_H
-
-#include <asm/io.h>
-
-/* Flags for configuration register CRF0 */
-#define APEDCRC                0x02
-#define ENBNKSEL       0x01
-
-/* Set 0 */
-#define TXD             0x00 /* Transmit data port */
-#define RXD             0x00 /* Receive data port */
-
-/* Register 1 */
-#define IER            0x01 /* Interrupt Enable Register*/
-#define IER_RXHDL_IE    0x01 /* Receiver high data level interrupt */
-#define IER_TXLDL_IE    0x02 /* Transeiver low data level interrupt */
-#define IER_LS_IE      0x04//* Link Status Interrupt */
-#define IER_ETXURI      0x04 /* Tx underrun */
-#define IER_DMA_IE     0x10 /* DMA finished interrupt */
-#define IER_TXEMP_IE    0x20
-#define IER_SFIF_IE     0x40 /* Frame status FIFO intr */
-#define IER_TMR_IE      0x80 /* Timer event */
-
-#define FCR            0x02 /* (write only) */
-#define FCR_FIFO_EN     0x01 /* Enable FIFO's */
-#define FCR_RXSR        0x02 /* Rx FIFO soft reset */
-#define FCR_TXSR        0x04 /* Tx FIFO soft reset */
-#define FCR_RXTH       0x80 /* Rx FIFO threshold (set to 16) */
-#define FCR_TXTH       0x20 /* Tx FIFO threshold (set to 17) */
-
-#define EIR            0x02 /* (read only) */
-#define EIR_RXHDL_EV   0x01
-#define EIR_TXLDL_EV    0x02
-#define EIR_LS_EV      0x04
-#define EIR_DMA_EV     0x10
-#define EIR_TXEMP_EV   0x20
-#define EIR_SFIF_EV     0x40
-#define EIR_TMR_EV      0x80
-
-#define LCR             0x03 /* Link control register */
-#define LCR_WLS_8       0x03 /* 8 bits */
-
-#define BSR            0x03 /* Bank select register */
-#define BSR_BKSE        0x80
-#define BANK0          LCR_WLS_8 /* Must make sure that we set 8N1 */
-#define BANK1          0x80
-#define BANK2          0xe0
-#define BANK3          0xe4
-#define BANK4          0xe8
-#define BANK5          0xec
-#define BANK6          0xf0
-#define BANK7          0xf4
-
-#define MCR            0x04 /* Mode Control Register */
-#define MCR_MODE_MASK  ~(0xd0)
-#define MCR_UART        0x00
-#define MCR_RESERVED   0x20    
-#define MCR_SHARP_IR    0x40
-#define MCR_SIR         0x60
-#define MCR_MIR        0x80
-#define MCR_FIR                0xa0
-#define MCR_CEIR        0xb0
-#define MCR_DMA_EN     0x04
-#define MCR_EN_IRQ     0x08
-#define MCR_TX_DFR     0x08
-
-#define LSR             0x05 /* Link status register */
-#define LSR_RXDA        0x01 /* Receiver data available */
-#define LSR_TXRDY       0x20 /* Transmitter ready */
-#define LSR_TXEMP       0x40 /* Transmitter empty */
-
-#define ASCR            0x07 /* Auxillary Status and Control Register */
-#define ASCR_RXF_TOUT   0x01 /* Rx FIFO timeout */
-#define ASCR_FEND_INF   0x02 /* Frame end bytes in rx FIFO */
-#define ASCR_S_EOT      0x04 /* Set end of transmission */
-#define ASCT_RXBSY      0x20 /* Rx busy */
-#define ASCR_TXUR       0x40 /* Transeiver underrun */
-#define ASCR_CTE        0x80 /* Clear timer event */
-
-/* Bank 2 */
-#define BGDL            0x00 /* Baud Generator Divisor Port (Low Byte) */
-#define BGDH            0x01 /* Baud Generator Divisor Port (High Byte) */
-
-#define ECR1           0x02 /* Extended Control Register 1 */
-#define ECR1_EXT_SL    0x01 /* Extended Mode Select */
-#define ECR1_DMANF     0x02 /* DMA Fairness */
-#define ECR1_DMATH      0x04
-#define ECR1_DMASWP    0x08 /* DMA Swap */
-
-#define EXCR2          0x04
-#define EXCR2_TFSIZ    0x01 /* Rx FIFO size = 32 */
-#define EXCR2_RFSIZ    0x04 /* Tx FIFO size = 32 */
-
-#define TXFLV           0x06 /* Tx FIFO level */
-#define RXFLV           0x07 /* Rx FIFO level */
-
-/* Bank 3 */
-#define MID            0x00
-
-/* Bank 4 */
-#define TMRL            0x00 /* Timer low byte */
-#define TMRH            0x01 /* Timer high byte */
-#define IRCR1           0x02 /* Infrared control register 1 */
-#define IRCR1_TMR_EN    0x01 /* Timer enable */
-
-#define TFRLL          0x04
-#define TFRLH          0x05
-#define RFRLL          0x06
-#define RFRLH          0x07
-
-/* Bank 5 */
-#define IRCR2           0x04 /* Infrared control register 2 */
-#define IRCR2_MDRS      0x04 /* MIR data rate select */
-#define IRCR2_FEND_MD   0x20 /* */
-
-#define FRM_ST          0x05 /* Frame status FIFO */
-#define FRM_ST_VLD      0x80 /* Frame status FIFO data valid */
-#define FRM_ST_ERR_MSK  0x5f
-#define FRM_ST_LOST_FR  0x40 /* Frame lost */
-#define FRM_ST_MAX_LEN  0x10 /* Max frame len exceeded */
-#define FRM_ST_PHY_ERR  0x08 /* Physical layer error */
-#define FRM_ST_BAD_CRC  0x04 
-#define FRM_ST_OVR1     0x02 /* Receive overrun */
-#define FRM_ST_OVR2     0x01 /* Frame status FIFO overrun */
-
-#define RFLFL           0x06
-#define RFLFH           0x07
-
-/* Bank 6 */
-#define IR_CFG2                0x00
-#define IR_CFG2_DIS_CRC        0x02
-
-/* Bank 7 */
-#define IRM_CR         0x07 /* Infrared module control register */
-#define IRM_CR_IRX_MSL 0x40
-#define IRM_CR_AF_MNT   0x80 /* Automatic format */
-
-/* For storing entries in the status FIFO */
-struct st_fifo_entry {
-       int status;
-       int len;
-};
-
-struct st_fifo {
-       struct st_fifo_entry entries[10];
-       int head;
-       int tail;
-       int len;
-};
-
-/* Private data for each instance */
-struct pc87108 {
-       struct st_fifo st_fifo;
-
-       int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */
-       int tx_len;          /* Number of frames in tx_buff */
-
-       struct net_device *netdev; /* Yes! we are some kind of netdevice */
-       struct net_device_stats stats;
-       
-       struct irlap_cb    *irlap; /* The link layer we are binded to */
-       
-       struct chipio_t io;        /* IrDA controller information */
-       struct iobuff_t tx_buff;   /* Transmit buffer */
-       struct iobuff_t rx_buff;   /* Receive buffer */
-       struct qos_info qos;       /* QoS capabilities for this device */
-       
-       __u32 flags;               /* Interface flags */
-       __u32 new_speed;
-};
-
-static inline void switch_bank(int iobase, int bank)
-{
-               outb(bank, iobase+BSR);
-}
-
-#endif
index d380373b1067c178ea2a8f239a80f394f9d05492..e5df56bc0b713145de432eaee0a37bc4102afcfe 100644 (file)
 /*********************************************************************
  *                
  * Filename:      smc-ircc.h
- * Version:       
- * Description:   
+ * Version:       0.3
+ * Description:   Definitions for the SMC IrCC chipset
  * Status:        Experimental.
  * Author:        Thomas Davis (tadavis@jps.net)
  *
- *     Copyright (c) 1998, 1999 Thomas Davis (tadavis@jps.net>
+ *     Copyright (c) 1999-2000, Dag Brattli <dagb@cs.uit.no>
+ *     Copyright (c) 1998-1999, Thomas Davis (tadavis@jps.net>
  *     All Rights Reserved
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
  *     published by the Free Software Foundation; either version 2 of 
  *     the License, or (at your option) any later version.
- *  
- *     I, Thomas Davis, admit no liability nor provide warranty for any
- *     of this software. This material is provided "AS-IS" and at no charge.
- *     
- * Definitions for the SMC IrCC controller.
+ * 
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *     GNU General Public License for more details.
+ * 
+ *     You should have received a copy of the GNU General Public License 
+ *     along with this program; if not, write to the Free Software 
+ *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ *     MA 02111-1307 USA
  *
  ********************************************************************/
 
-#include <net/irda/irport.h>
-
 #ifndef SMC_IRCC_H
 #define SMC_IRCC_H
 
-#define UART_MASTER                    0x07
-#define UART_MASTER_POWERDOWN  1<<7
-#define UART_MASTER_RESET              1<<6
-#define UART_MASTER_INT_EN             1<<5
-#define UART_MASTER_ERROR_RESET        1<<4
+#include <linux/spinlock.h>
 
-/* Register block 0 */
+#include <net/irda/irport.h>
 
-#define UART_IIR       0x01
-#define UART_IER       0x02
-#define UART_LSR       0x03
-#define UART_LCR_A     0x04
-#define UART_LCR_B     0x05
-#define UART_BSR       0x06
-
-#define UART_IIR_ACTIVE_FRAME  1<<7
-#define UART_IIR_EOM           1<<6
-#define UART_IIR_RAW_MODE              1<<5
-#define UART_IIR_FIFO          1<<4
-
-#define UART_IER_ACTIVE_FRAME  1<<7
-#define UART_IER_EOM           1<<6
-#define UART_IER_RAW_MODE              1<<5
-#define UART_IER_FIFO          1<<4
-
-#define UART_LSR_UNDERRUN              1<<7
-#define UART_LSR_OVERRUN               1<<6
-#define UART_LSR_FRAME_ERROR   1<<5
-#define UART_LSR_SIZE_ERROR            1<<4
-#define UART_LSR_CRC_ERROR             1<<3
-#define UART_LSR_FRAME_ABORT   1<<2
-
-#define UART_LCR_A_FIFO_RESET        1<<7
-#define UART_LCR_A_FAST              1<<6
-#define UART_LCR_A_GP_DATA           1<<5
-#define UART_LCR_A_RAW_TX            1<<4
-#define UART_LCR_A_RAW_RX            1<<3
-#define UART_LCR_A_ABORT             1<<2
-#define UART_LCR_A_DATA_DONE         1<<1
-
-#define UART_LCR_B_SCE_DISABLED        0x00<<6
-#define UART_LCR_B_SCE_TRANSMIT        0x01<<6
-#define UART_LCR_B_SCE_RECEIVE         0x02<<6
-#define UART_LCR_B_SCE_UNDEFINED       0x03<<6
-#define UART_LCR_B_SIP_ENABLE          1<<5
-#define UART_LCR_B_BRICK_WALL          1<<4
-
-#define UART_BSR_NOT_EMPTY     1<<7
-#define UART_BSR_FIFO_FULL     1<<6
-#define UART_BSR_TIMEOUT       1<<5
+/* DMA modes needed */
+#define DMA_TX_MODE              0x08    /* Mem to I/O, ++, demand. */
+#define DMA_RX_MODE              0x04    /* I/O to mem, ++, demand. */
 
-/* Register block 1 */
+#define IRCC_MASTER              0x07
+#define IRCC_MASTER_POWERDOWN   1<<7
+#define IRCC_MASTER_RESET        1<<6
+#define IRCC_MASTER_INT_EN       1<<5
+#define IRCC_MASTER_ERROR_RESET         1<<4
 
-#define UART_SCE_CFGA  0x00
-#define UART_SCE_CFGB  0x01
-#define UART_FIFO_THRESHOLD    0x02
-
-#define UART_CFGA_AUX_IR       0x01<<7
-#define UART_CFGA_HALF_DUPLEX  0x01<<2
-#define UART_CFGA_TX_POLARITY  0x01<<1
-#define UART_CFGA_RX_POLARITY  0x01
-
-#define UART_CFGA_COM          0x00<<3
-#define UART_CFGA_IRDA_SIR_A   0x01<<3
-#define UART_CFGA_ASK_SIR      0x02<<3
-#define UART_CFGA_IRDA_SIR_B   0x03<<3
-#define UART_CFGA_IRDA_HDLC    0x04<<3
-#define UART_CFGA_IRDA_4PPM    0x05<<3
-#define UART_CFGA_CONSUMER     0x06<<3
-#define UART_CFGA_RAW_IR       0x07<<3
-#define UART_CFGA_OTHER                0x08<<3
-
-#define UART_IR_HDLC                   0x04
-#define UART_IR_4PPM                   0x01
-#define UART_IR_CONSUMER               0x02
-
-#define UART_CFGB_LOOPBACK      0x01<<5
-#define UART_CFGB_LPBCK_TX_CRC 0x01<<4
-#define UART_CFGB_NOWAIT       0x01<<3
-#define UART_CFGB_STRING_MOVE  0x01<<2
-#define UART_CFGB_DMA_BURST    0x01<<1
-#define UART_CFGB_DMA_ENABLE   0x01
-
-#define UART_CFGB_COM          0x00<<6
-#define UART_CFGB_IR           0x01<<6
-#define UART_CFGB_AUX          0x02<<6
-#define UART_CFGB_INACTIVE     0x03<<6
-
-/* Register block 2 - Consumer IR - not used */
+/* Register block 0 */
+#define IRCC_IIR                 0x01
+#define IRCC_IER                 0x02
+#define IRCC_LSR                 0x03
+#define IRCC_LCR_A               0x04
+#define IRCC_LCR_B               0x05
+#define IRCC_BSR                 0x06
+
+#define IRCC_IIR_ACTIVE_FRAME    1<<7
+#define IRCC_IIR_EOM             1<<6
+#define IRCC_IIR_RAW_MODE        1<<5
+#define IRCC_IIR_FIFO           1<<4
+
+#define IRCC_IER_ACTIVE_FRAME   1<<7
+#define IRCC_IER_EOM            1<<6
+#define IRCC_IER_RAW_MODE        1<<5
+#define IRCC_IER_FIFO           1<<4
+
+#define IRCC_LSR_UNDERRUN        1<<7
+#define IRCC_LSR_OVERRUN         1<<6
+#define IRCC_LSR_FRAME_ERROR     1<<5
+#define IRCC_LSR_SIZE_ERROR      1<<4
+#define IRCC_LSR_CRC_ERROR       1<<3
+#define IRCC_LSR_FRAME_ABORT    1<<2
+
+#define IRCC_LCR_A_FIFO_RESET    1<<7
+#define IRCC_LCR_A_FAST          1<<6
+#define IRCC_LCR_A_GP_DATA       1<<5
+#define IRCC_LCR_A_RAW_TX        1<<4
+#define IRCC_LCR_A_RAW_RX        1<<3
+#define IRCC_LCR_A_ABORT         1<<2
+#define IRCC_LCR_A_DATA_DONE     1<<1
+
+#define IRCC_LCR_B_SCE_DISABLED  0x00<<6
+#define IRCC_LCR_B_SCE_TRANSMIT  0x01<<6
+#define IRCC_LCR_B_SCE_RECEIVE  0x02<<6
+#define IRCC_LCR_B_SCE_UNDEFINED 0x03<<6
+#define IRCC_LCR_B_SIP_ENABLE   1<<5
+#define IRCC_LCR_B_BRICK_WALL    1<<4
+
+#define IRCC_BSR_NOT_EMPTY      1<<7
+#define IRCC_BSR_FIFO_FULL      1<<6
+#define IRCC_BSR_TIMEOUT        1<<5
 
-/* Register block 3 - Identification Registers! */
+/* Register block 1 */
+#define IRCC_SCE_CFGA           0x00
+#define IRCC_SCE_CFGB           0x01
+#define IRCC_FIFO_THRESHOLD     0x02
+
+#define IRCC_CFGA_AUX_IR        0x01<<7
+#define IRCC_CFGA_HALF_DUPLEX   0x01<<2
+#define IRCC_CFGA_TX_POLARITY   0x01<<1
+#define IRCC_CFGA_RX_POLARITY   0x01
+
+#define IRCC_CFGA_COM           0x00<<3
+#define IRCC_CFGA_IRDA_SIR_A    0x01<<3
+#define IRCC_CFGA_ASK_SIR       0x02<<3
+#define IRCC_CFGA_IRDA_SIR_B    0x03<<3
+#define IRCC_CFGA_IRDA_HDLC     0x04<<3
+#define IRCC_CFGA_IRDA_4PPM     0x05<<3
+#define IRCC_CFGA_CONSUMER      0x06<<3
+#define IRCC_CFGA_RAW_IR        0x07<<3
+#define IRCC_CFGA_OTHER                 0x08<<3
+
+#define IRCC_IR_HDLC             0x04
+#define IRCC_IR_4PPM             0x01
+#define IRCC_IR_CONSUMER         0x02
+
+#define IRCC_CFGB_LOOPBACK       0x01<<5
+#define IRCC_CFGB_LPBCK_TX_CRC  0x01<<4
+#define IRCC_CFGB_NOWAIT        0x01<<3
+#define IRCC_CFGB_STRING_MOVE   0x01<<2
+#define IRCC_CFGB_DMA_BURST     0x01<<1
+#define IRCC_CFGB_DMA_ENABLE    0x01
+
+#define IRCC_CFGB_COM           0x00<<6
+#define IRCC_CFGB_IR            0x01<<6
+#define IRCC_CFGB_AUX           0x02<<6
+#define IRCC_CFGB_INACTIVE      0x03<<6
 
-#define UART_ID_HIGH   0x00   /* 0x10 */
-#define UART_ID_LOW    0x01   /* 0xB8 */
-#define UART_CHIP_ID   0x02   /* 0xF1 */
-#define UART_VERSION   0x03   /* 0x01 */
-#define UART_INTERFACE 0x04   /* low 4 = DMA, high 4 = IRQ */
+/* Register block 3 - Identification Registers! */
+#define IRCC_ID_HIGH            0x00   /* 0x10 */
+#define IRCC_ID_LOW             0x01   /* 0xB8 */
+#define IRCC_CHIP_ID            0x02   /* 0xF1 */
+#define IRCC_VERSION            0x03   /* 0x01 */
+#define IRCC_INTERFACE          0x04   /* low 4 = DMA, high 4 = IRQ */
 
 /* Register block 4 - IrDA */
-#define UART_CONTROL             0x00
-#define UART_BOF_COUNT_LO        0x01
-#define UART_BRICKWALL_CNT_LO    0x02
-#define UART_BRICKWALL_TX_CNT_HI 0x03
-#define UART_TX_SIZE_LO          0x04
-#define UART_RX_SIZE_HI          0x05
-#define UART_RX_SIZE_LO          0x06
+#define IRCC_CONTROL             0x00
+#define IRCC_BOF_COUNT_LO        0x01
+#define IRCC_BRICKWALL_CNT_LO    0x02
+#define IRCC_BRICKWALL_TX_CNT_HI 0x03
+#define IRCC_TX_SIZE_LO          0x04
+#define IRCC_RX_SIZE_HI          0x05
+#define IRCC_RX_SIZE_LO          0x06
 
-#define UART_1152     0x01<<7
-#define UART_CRC      0x01<<6
+#define IRCC_1152                0x01<<7
+#define IRCC_CRC                 0x01<<6
 
 /* For storing entries in the status FIFO */
 struct st_fifo_entry {
@@ -157,17 +164,18 @@ struct ircc_cb {
        struct chipio_t io;        /* IrDA controller information */
        struct iobuff_t tx_buff;   /* Transmit buffer */
        struct iobuff_t rx_buff;   /* Receive buffer */
-       struct qos_info qos;       /* QoS capabilities for this device */
 
        struct irport_cb *irport;
+
+       spinlock_t lock;           /* For serializing operations */
        
        __u32 new_speed;
        __u32 flags;               /* Interface flags */
 
        struct st_fifo st_fifo;
 
-       int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */
-       int tx_len;              /* Number of frames in tx_buff */
+       int tx_buff_offsets[10];   /* Offsets between frames in tx_buff */
+       int tx_len;                /* Number of frames in tx_buff */
 };
 
-#endif
+#endif /* SMC_IRCC_H */
index 8bbdcd263d3a0ba4e02bcf89826b8f4082749584..9ccfd3bea9cd82aaa47864877f6dac52d4c40836 100644 (file)
@@ -34,8 +34,6 @@
 #warning This file is not supposed to be used outside of kernel.
 #endif
 
-#define RT_HASH_DIVISOR                256
-
 #define RTO_ONLINK     0x01
 #define RTO_TPROXY     0x80000000
 
index 0470f031895f74142cc735fac0aeb8d523697081..4249307cf9402da7c4520e533945274f3aa72031 100644 (file)
@@ -88,6 +88,7 @@ extern void ppc_init(void);
 extern void sysctl_init(void);
 extern void filescache_init(void);
 extern void signals_init(void);
+extern void bdev_init(void);
 extern int init_pcmcia_ds(void);
 
 extern void free_initmem(void);
index 8d5ae6189550cb149e72a1bdd2c44c110e638cb3..4d70545ab3a2cdddfbe050c5bfb5fd8696008376 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -799,7 +799,7 @@ oom:
 static unsigned long swap_id = 0; /* currently being swapped */
 static unsigned long swap_idx = 0; /* next to swap */
 
-int shm_swap (int prio, int gfp_mask)
+int shm_swap (int prio, int gfp_mask, zone_t *zone)
 {
        pte_t page;
        struct shmid_kernel *shp;
@@ -849,9 +849,7 @@ check_table:
        if (!pte_present(page))
                goto check_table;
        page_map = pte_page(page);
-       if ((gfp_mask & __GFP_DMA) && !PageDMA(page_map))
-               goto check_table;
-       if (!(gfp_mask & __GFP_HIGHMEM) && PageHighMem(page_map))
+       if (zone && (!memclass(page_map->zone, zone)))
                goto check_table;
        swap_attempts++;
 
index e5f110e6779e828e8a588890f1cdc090eb9d53ea..6008b0d9935c4c152f1f2568c67b165ed79232e8 100644 (file)
@@ -214,7 +214,7 @@ void sem_exit (void)
     return;
 }
 
-int shm_swap (int prio, int gfp_mask)
+int shm_swap (int prio, int gfp_mask, zone_t *zone)
 {
     return 0;
 }
index 36d75438053ddf36c55370ab5bd8321c5292d0ae..22c7509a877f6e72b14c8ecefbbbf40de6be33dc 100644 (file)
@@ -7,6 +7,10 @@
 
        Modified to avoid chroot and file sharing problems.
        Mikael Pettersson
+
+       Limit the concurrent number of kmod modprobes to catch loops from
+       "modprobe needs a service that is in a module".
+       Keith Owens <kaos@ocs.com.au> December 1999
 */
 
 #define __KERNEL_SYSCALLS__
@@ -22,6 +26,8 @@
 */
 char modprobe_path[256] = "/sbin/modprobe";
 
+extern int max_threads;
+
 static inline void
 use_init_fs_context(void)
 {
@@ -113,6 +119,10 @@ int request_module(const char * module_name)
        int pid;
        int waitpid_result;
        sigset_t tmpsig;
+       int i;
+       static atomic_t kmod_concurrent = ATOMIC_INIT(0);
+#define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */
+       static int kmod_loop_msg;
 
        /* Don't allow request_module() before the root fs is mounted!  */
        if ( ! current->fs->root ) {
@@ -121,9 +131,31 @@ int request_module(const char * module_name)
                return -EPERM;
        }
 
+       /* If modprobe needs a service that is in a module, we get a recursive
+        * loop.  Limit the number of running kmod threads to max_threads/2 or
+        * MAX_KMOD_CONCURRENT, whichever is the smaller.  A cleaner method
+        * would be to run the parents of this process, counting how many times
+        * kmod was invoked.  That would mean accessing the internals of the
+        * process tables to get the command line, proc_pid_cmdline is static
+        * and it is not worth changing the proc code just to handle this case. 
+        * KAO.
+        */
+       i = max_threads/2;
+       if (i > MAX_KMOD_CONCURRENT)
+               i = MAX_KMOD_CONCURRENT;
+       atomic_inc(&kmod_concurrent);
+       if (atomic_read(&kmod_concurrent) > i) {
+               if (kmod_loop_msg++ < 5)
+                       printk(KERN_ERR
+                              "kmod: runaway modprobe loop assumed and stopped\n");
+               atomic_dec(&kmod_concurrent);
+               return -ENOMEM;
+       }
+
        pid = kernel_thread(exec_modprobe, (void*) module_name, 0);
        if (pid < 0) {
                printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid);
+               atomic_dec(&kmod_concurrent);
                return pid;
        }
 
@@ -135,6 +167,7 @@ int request_module(const char * module_name)
        spin_unlock_irq(&current->sigmask_lock);
 
        waitpid_result = waitpid(pid, NULL, __WCLONE);
+       atomic_dec(&kmod_concurrent);
 
        /* Allow signals again.. */
        spin_lock_irq(&current->sigmask_lock);
index 43551c553029027c57a1e494c65b04b284d82237..b5e1c04a44a69894eb5cdcf949602e89264667ec 100644 (file)
@@ -97,6 +97,7 @@ EXPORT_SYMBOL(__free_pages_ok);
 #ifndef CONFIG_DISCONTIGMEM
 EXPORT_SYMBOL(contig_page_data);
 #endif
+EXPORT_SYMBOL(num_physpages);
 EXPORT_SYMBOL(kmem_find_general_cachep);
 EXPORT_SYMBOL(kmem_cache_create);
 EXPORT_SYMBOL(kmem_cache_destroy);
index eb29bf649f820367c7b302212892220c387e4e9b..98feadf65b69adfaf26e2ac5bbc54dc6a4f9007b 100644 (file)
@@ -673,7 +673,7 @@ static inline void __wake_up_common(wait_queue_head_t *q, unsigned int mode, con
 #endif
                p = curr->task;
                state = p->state;
-               if (state & mode) {
+               if (state & (mode & ~TASK_EXCLUSIVE)) {
 #if WAITQUEUE_DEBUG
                        curr->__waker = (long)__builtin_return_address(0);
 #endif
@@ -681,7 +681,7 @@ static inline void __wake_up_common(wait_queue_head_t *q, unsigned int mode, con
                                wake_up_process_synchronous(p);
                        else
                                wake_up_process(p);
-                       if (state & TASK_EXCLUSIVE)
+                       if (state & mode & TASK_EXCLUSIVE)
                                break;
                }
        }
index f4f0ce6c3e5f7e2920e16c42ad3988a4c850c1ee..35a4b6d37a7953f4ceb2c546e4582dd9a0e96a05 100644 (file)
@@ -211,7 +211,7 @@ repeat:
        spin_unlock(&pagecache_lock);
 }
 
-int shrink_mmap(int priority, int gfp_mask)
+int shrink_mmap(int priority, int gfp_mask, zone_t *zone)
 {
        int ret = 0, count;
        LIST_HEAD(young);
@@ -239,9 +239,7 @@ int shrink_mmap(int priority, int gfp_mask)
 
                dispose = &old;
                /* don't account passes over not DMA pages */
-               if ((gfp_mask & __GFP_DMA) && !PageDMA(page))
-                       goto dispose_continue;
-               if (!(gfp_mask & __GFP_HIGHMEM) && PageHighMem(page))
+               if (zone && (!memclass(page->zone, zone)))
                        goto dispose_continue;
 
                count--;
index b2eab8252258def1765ef4e679df89cbc156942b..5d42a49222c397f0b42c5b1cd529ed56e94c0a54 100644 (file)
@@ -131,13 +131,17 @@ static void flush_all_zero_pkmaps(void)
 static unsigned long map_new_virtual(struct page *page)
 {
        unsigned long vaddr;
-       int count = LAST_PKMAP;
+       int count;
 
+start:
+       count = LAST_PKMAP;
        /* Find an empty entry */
        for (;;) {
                last_pkmap_nr = (last_pkmap_nr + 1) & LAST_PKMAP_MASK;
-               if (!last_pkmap_nr)
+               if (!last_pkmap_nr) {
                        flush_all_zero_pkmaps();
+                       count = LAST_PKMAP;
+               }
                if (!pkmap_count[last_pkmap_nr])
                        break;  /* Found a usable entry */
                if (--count)
@@ -161,7 +165,7 @@ static unsigned long map_new_virtual(struct page *page)
                                return page->virtual;
 
                        /* Re-start */
-                       count = LAST_PKMAP;
+                       goto start;
                }
        }
        vaddr = PKMAP_ADDR(last_pkmap_nr);
index c607af403237cb4936f802088d84b3d3724520c0..1c6ced2beed52760b8a630f8e50b5988f86cb961 100644 (file)
@@ -224,7 +224,7 @@ static inline int zone_balance_memory (zone_t *zone, int gfp_mask)
                return 1;
 
        current->flags |= PF_MEMALLOC;
-       freed = try_to_free_pages(gfp_mask);
+       freed = try_to_free_pages(gfp_mask, zone);
        current->flags &= ~PF_MEMALLOC;
 
        if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
@@ -235,7 +235,7 @@ static inline int zone_balance_memory (zone_t *zone, int gfp_mask)
 /*
  * We are still balancing memory in a global way:
  */
-static inline int balance_memory (int gfp_mask)
+static inline int balance_memory (zone_t *zone, int gfp_mask)
 {
        unsigned long free = nr_free_pages();
        static int low_on_memory = 0;
@@ -264,7 +264,7 @@ static inline int balance_memory (int gfp_mask)
                return 1;
 
        current->flags |= PF_MEMALLOC;
-       freed = try_to_free_pages(gfp_mask);
+       freed = try_to_free_pages(gfp_mask, zone);
        current->flags &= ~PF_MEMALLOC;
 
        if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
@@ -340,7 +340,7 @@ nopage:
  * The main chunk of the balancing code is in this offline branch:
  */
 balance:
-       if (!balance_memory(gfp_mask))
+       if (!balance_memory(z, gfp_mask))
                goto nopage;
        goto ready;
 }
@@ -533,9 +533,9 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
                i = 10;
        if (i > 256)
                i = 256;
-       freepages.min = i;
-       freepages.low = i * 2;
-       freepages.high = i * 3;
+       freepages.min += i;
+       freepages.low += i * 2;
+       freepages.high += i * 3;
 
        /*
         * Some architectures (with lots of mem and discontinous memory
@@ -574,6 +574,7 @@ void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
                zone->size = size;
                zone->name = zone_names[j];
                zone->lock = SPIN_LOCK_UNLOCKED;
+               zone->zone_pgdat = pgdat;
                if (!size)
                        continue;
 
index b477cb41362ce3dacae5fba826d0b81f45f55e47..41e19028a0e8917985419afadc6f4e9877f8388d 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -503,6 +503,11 @@ kmem_getpages(kmem_cache_t *cachep, unsigned long flags, unsigned int *dma)
 {
        void    *addr;
 
+       /*
+        * If we requested dmaable memory, we will get it. Even if we 
+        * did not request dmaable memory, we might get it, but that
+        * would be relatively rare and ignorable.
+        */
        *dma = flags & SLAB_DMA;
        addr = (void*) __get_free_pages(flags, cachep->c_gfporder);
        /* Assume that now we have the pages no one else can legally
@@ -511,18 +516,6 @@ kmem_getpages(kmem_cache_t *cachep, unsigned long flags, unsigned int *dma)
         * it is a named-page or buffer-page.  The members it tests are
         * of no interest here.....
         */
-       if (!*dma && addr) {
-               /* Need to check if can dma. */
-               struct page *page = mem_map + MAP_NR(addr);
-               *dma = 1<<cachep->c_gfporder;
-               while ((*dma)--) {
-                       if (!PageDMA(page)) {
-                               *dma = 0;
-                               break;
-                       }
-                       page++;
-               }
-       }
        return addr;
 }
 
index bd3ece5008983b07ba5307e8b928132adaf82256..7e064d0fadf73a4c30886c1129b361e3ead1e19a 100644 (file)
@@ -33,7 +33,7 @@
  * using a process that no longer actually exists (it might
  * have died while we slept).
  */
-static int try_to_swap_out(struct vm_area_struct* vma, unsigned long address, pte_t * page_table, int gfp_mask)
+static int try_to_swap_out(struct vm_area_struct* vma, unsigned long address, pte_t * page_table, int gfp_mask, zone_t *zone)
 {
        pte_t pte;
        swp_entry_t entry;
@@ -60,8 +60,7 @@ static int try_to_swap_out(struct vm_area_struct* vma, unsigned long address, pt
 
        if (PageReserved(page)
            || PageLocked(page)
-           || ((gfp_mask & __GFP_DMA) && !PageDMA(page))
-           || (!(gfp_mask & __GFP_HIGHMEM) && PageHighMem(page)))
+           || (zone && (!memclass(page->zone, zone))))
                goto out_failed;
 
        /*
@@ -196,7 +195,7 @@ out_failed:
  * (C) 1993 Kai Petzke, wpp@marie.physik.tu-berlin.de
  */
 
-static inline int swap_out_pmd(struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int gfp_mask)
+static inline int swap_out_pmd(struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int gfp_mask, zone_t *zone)
 {
        pte_t * pte;
        unsigned long pmd_end;
@@ -218,7 +217,7 @@ static inline int swap_out_pmd(struct vm_area_struct * vma, pmd_t *dir, unsigned
        do {
                int result;
                vma->vm_mm->swap_address = address + PAGE_SIZE;
-               result = try_to_swap_out(vma, address, pte, gfp_mask);
+               result = try_to_swap_out(vma, address, pte, gfp_mask, zone);
                if (result)
                        return result;
                address += PAGE_SIZE;
@@ -227,7 +226,7 @@ static inline int swap_out_pmd(struct vm_area_struct * vma, pmd_t *dir, unsigned
        return 0;
 }
 
-static inline int swap_out_pgd(struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int gfp_mask)
+static inline int swap_out_pgd(struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int gfp_mask, zone_t *zone)
 {
        pmd_t * pmd;
        unsigned long pgd_end;
@@ -247,7 +246,7 @@ static inline int swap_out_pgd(struct vm_area_struct * vma, pgd_t *dir, unsigned
                end = pgd_end;
        
        do {
-               int result = swap_out_pmd(vma, pmd, address, end, gfp_mask);
+               int result = swap_out_pmd(vma, pmd, address, end, gfp_mask, zone);
                if (result)
                        return result;
                address = (address + PMD_SIZE) & PMD_MASK;
@@ -256,7 +255,7 @@ static inline int swap_out_pgd(struct vm_area_struct * vma, pgd_t *dir, unsigned
        return 0;
 }
 
-static int swap_out_vma(struct vm_area_struct * vma, unsigned long address, int gfp_mask)
+static int swap_out_vma(struct vm_area_struct * vma, unsigned long address, int gfp_mask, zone_t *zone)
 {
        pgd_t *pgdir;
        unsigned long end;
@@ -271,7 +270,7 @@ static int swap_out_vma(struct vm_area_struct * vma, unsigned long address, int
        if (address >= end)
                BUG();
        do {
-               int result = swap_out_pgd(vma, pgdir, address, end, gfp_mask);
+               int result = swap_out_pgd(vma, pgdir, address, end, gfp_mask, zone);
                if (result)
                        return result;
                address = (address + PGDIR_SIZE) & PGDIR_MASK;
@@ -280,7 +279,7 @@ static int swap_out_vma(struct vm_area_struct * vma, unsigned long address, int
        return 0;
 }
 
-static int swap_out_mm(struct mm_struct * mm, int gfp_mask)
+static int swap_out_mm(struct mm_struct * mm, int gfp_mask, zone_t *zone)
 {
        unsigned long address;
        struct vm_area_struct* vma;
@@ -301,7 +300,7 @@ static int swap_out_mm(struct mm_struct * mm, int gfp_mask)
                        address = vma->vm_start;
 
                for (;;) {
-                       int result = swap_out_vma(vma, address, gfp_mask);
+                       int result = swap_out_vma(vma, address, gfp_mask, zone);
                        if (result)
                                return result;
                        vma = vma->vm_next;
@@ -323,7 +322,7 @@ static int swap_out_mm(struct mm_struct * mm, int gfp_mask)
  * N.B. This function returns only 0 or 1.  Return values != 1 from
  * the lower level routines result in continued processing.
  */
-static int swap_out(unsigned int priority, int gfp_mask)
+static int swap_out(unsigned int priority, int gfp_mask, zone_t *zone)
 {
        struct task_struct * p;
        int counter;
@@ -384,7 +383,7 @@ static int swap_out(unsigned int priority, int gfp_mask)
                        int ret;
 
                        atomic_inc(&best->mm_count);
-                       ret = swap_out_mm(best, gfp_mask);
+                       ret = swap_out_mm(best, gfp_mask, zone);
                        mmdrop(best);
 
                        if (!ret)
@@ -410,7 +409,7 @@ out:
  * cluster them so that we get good swap-out behaviour. See
  * the "free_memory()" macro for details.
  */
-static int do_try_to_free_pages(unsigned int gfp_mask)
+static int do_try_to_free_pages(unsigned int gfp_mask, zone_t *zone)
 {
        int priority;
        int count = SWAP_CLUSTER_MAX;
@@ -420,7 +419,7 @@ static int do_try_to_free_pages(unsigned int gfp_mask)
 
        priority = 6;
        do {
-               while (shrink_mmap(priority, gfp_mask)) {
+               while (shrink_mmap(priority, gfp_mask, zone)) {
                        if (!--count)
                                goto done;
                }
@@ -428,21 +427,21 @@ static int do_try_to_free_pages(unsigned int gfp_mask)
                /* don't be too light against the d/i cache since
                   shrink_mmap() almost never fail when there's
                   really plenty of memory free. */
-               count -= shrink_dcache_memory(priority, gfp_mask);
-               count -= shrink_icache_memory(priority, gfp_mask);
+               count -= shrink_dcache_memory(priority, gfp_mask, zone);
+               count -= shrink_icache_memory(priority, gfp_mask, zone);
                if (count <= 0)
                        goto done;
 
                /* Try to get rid of some shared memory pages.. */
                if (gfp_mask & __GFP_IO) {
-                       while (shm_swap(priority, gfp_mask)) {
+                       while (shm_swap(priority, gfp_mask, zone)) {
                                if (!--count)
                                        goto done;
                        }
                }
 
                /* Then, try to page stuff out.. */
-               while (swap_out(priority, gfp_mask)) {
+               while (swap_out(priority, gfp_mask, zone)) {
                        if (!--count)
                                goto done;
                }
@@ -506,7 +505,7 @@ int kswapd(void *unused)
                           allocations (not GFP_HIGHMEM ones). */
                        if (nr_free_buffer_pages() >= freepages.high)
                                break;
-                       if (!do_try_to_free_pages(GFP_KSWAPD))
+                       if (!do_try_to_free_pages(GFP_KSWAPD, 0))
                                break;
                        run_task_queue(&tq_disk);
                } while (!tsk->need_resched);
@@ -530,13 +529,13 @@ int kswapd(void *unused)
  * can be done by just dropping cached pages without having
  * any deadlock issues.
  */
-int try_to_free_pages(unsigned int gfp_mask)
+int try_to_free_pages(unsigned int gfp_mask, zone_t *zone)
 {
        int retval = 1;
 
        wake_up_process(kswapd_process);
        if (gfp_mask & __GFP_WAIT)
-               retval = do_try_to_free_pages(gfp_mask);
+               retval = do_try_to_free_pages(gfp_mask, zone);
        return retval;
 }
 
index 8c8bd45e605a28c14e52c9078906c9640b7d47e0..d54d8526b8bcede607b3bf1733c6931f842a4b1a 100644 (file)
@@ -5,14 +5,14 @@ Code Section          Bug Report Contact
 -------------------+-------------------------------------------
 802 [other     ]       alan@lxorguk.ukuu.org.uk        
     [token ring        ]       p.norton@computer.org
-appletalk              Jay.Schulist@spacs.k12.wi.us
+appletalk              jschlst@turbolinux.com
 ax25                   g4klx@g4klx.demon.co.uk
 core                   alan@lxorguk.ukuu.org.uk
 decnet                 SteveW@ACM.org
 ethernet               alan@lxorguk.ukuu.org.uk
 ipv4                   davem@caip.rutgers.edu,Eric.Schenk@dna.lth.se
 ipv6                   davem@caip.rutgers.edu,Eric.Schenk@dna.lth.se
-ipx/spx                        Jay.Schulist@spacs.k12.wi.us
+ipx/spx                        jschlst@turbolinux.com
 irda                    dagb@cs.uit.no
 lapb                   g4klx@g4klx.demon.co.uk
 netrom                 g4klx@g4klx.demon.co.uk
index d9939e3a4201504a706ad4b2f2a34cef7b6ab641..8749e8c7b511c49de4c94ec3282330a4528586a9 100644 (file)
@@ -2,7 +2,7 @@
  * Linux Socket Filter - Kernel level socket filtering
  *
  * Author:
- *     Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
+ *     Jay Schulist <jschlst@turbolinux.com>
  *
  * Based on the design of:
  *     - The Berkeley Packet Filter
index 679c3dfb024d640d0f82ae26287c479b9cea42bf..c4f8341578f5cdac523f8275d344954b28257b46 100644 (file)
@@ -22,6 +22,9 @@
  *              Steve Whitehouse : More SMP locking changes & dn_cache_dump()
  *              Steve Whitehouse : Prerouting NF hook, now really is prerouting.
  *                                Fixed possible skb leak in rtnetlink funcs.
+ *              Steve Whitehouse : Dave Miller's dynamic hash table sizing and
+ *                                 Alexey Kuznetsov's finer grained locking
+ *                                 from ipv4/route.c.
  */
 
 /******************************************************************************
@@ -44,7 +47,6 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/kernel.h>
-#include <linux/timer.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
 #include <linux/netdevice.h>
 #include <net/dn_fib.h>
 #include <net/dn_raw.h>
 
+struct dn_rt_hash_bucket
+{
+       struct dn_route *chain;
+       rwlock_t lock;
+} __attribute__((__aligned__(8)));
+
 extern struct neigh_table dn_neigh_table;
 
-#define DN_HASHBUCKETS 16
 
 static unsigned char dn_hiord_addr[6] = {0xAA,0x00,0x04,0x00,0x00,0x00};
 
@@ -82,8 +89,8 @@ static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
 static void dn_dst_link_failure(struct sk_buff *);
 static int dn_route_input(struct sk_buff *);
 
-static struct dn_route *dn_route_cache[DN_HASHBUCKETS];
-static rwlock_t dn_hash_lock = RW_LOCK_UNLOCKED;
+static struct dn_rt_hash_bucket *dn_rt_hash_table;
+static unsigned dn_rt_hash_mask;
 
 static struct timer_list dn_route_timer = { NULL, NULL, 0, 0L, NULL };
 int decnet_dst_gc_interval = 2;
@@ -104,8 +111,11 @@ static struct dst_ops dn_dst_ops = {
 
 static __inline__ unsigned dn_hash(unsigned short dest)
 {
-       unsigned short tmp = (dest&0xff) ^ (dest>>8);
-       return (tmp&0x0f) ^ (tmp>>4);
+       unsigned short tmp = dest;
+       tmp ^= (dest >> 3);
+       tmp ^= (dest >> 5);
+       tmp ^= (dest >> 10);
+       return dn_rt_hash_mask & (unsigned)tmp;
 }
 
 static void dn_dst_check_expire(unsigned long dummy)
@@ -115,10 +125,10 @@ static void dn_dst_check_expire(unsigned long dummy)
        unsigned long now = jiffies;
        unsigned long expire = 120 * HZ;
 
-       for(i = 0; i < DN_HASHBUCKETS; i++) {
-               rtp = &dn_route_cache[i];
+       for(i = 0; i <= dn_rt_hash_mask; i++) {
+               rtp = &dn_rt_hash_table[i].chain;
 
-               write_lock(&dn_hash_lock);
+               write_lock(&dn_rt_hash_table[i].lock);
                for(;(rt=*rtp); rtp = &rt->u.rt_next) {
                        if (atomic_read(&rt->u.dst.__refcnt) ||
                                        (now - rt->u.dst.lastuse) < expire)
@@ -127,7 +137,7 @@ static void dn_dst_check_expire(unsigned long dummy)
                        rt->u.rt_next = NULL;
                        dst_free(&rt->u.dst);
                }
-               write_unlock(&dn_hash_lock);
+               write_unlock(&dn_rt_hash_table[i].lock);
 
                if ((jiffies - now) > 0)
                        break;
@@ -144,9 +154,9 @@ static int dn_dst_gc(void)
        unsigned long now = jiffies;
        unsigned long expire = 10 * HZ;
 
-       write_lock_bh(&dn_hash_lock);
-       for(i = 0; i < DN_HASHBUCKETS; i++) {
-               rtp = &dn_route_cache[i];
+       for(i = 0; i <= dn_rt_hash_mask; i++) {
+               write_lock_bh(&dn_rt_hash_table[i].lock);
+               rtp = &dn_rt_hash_table[i].chain;
                for(; (rt=*rtp); rtp = &rt->u.rt_next) {
                        if (atomic_read(&rt->u.dst.__refcnt) ||
                                        (now - rt->u.dst.lastuse) < expire)
@@ -156,8 +166,8 @@ static int dn_dst_gc(void)
                        dst_free(&rt->u.dst);
                        break;
                }
+               write_unlock_bh(&dn_rt_hash_table[i].lock);
        }
-       write_unlock_bh(&dn_hash_lock);
 
        return 0;
 }
@@ -194,15 +204,15 @@ static void dn_insert_route(struct dn_route *rt)
        unsigned hash = dn_hash(rt->rt_daddr);
        unsigned long now = jiffies;
 
-       write_lock_bh(&dn_hash_lock);
-       rt->u.rt_next = dn_route_cache[hash];
-       dn_route_cache[hash] = rt;
+       write_lock_bh(&dn_rt_hash_table[hash].lock);
+       rt->u.rt_next = dn_rt_hash_table[hash].chain;
+       dn_rt_hash_table[hash].chain = rt;
        
        dst_hold(&rt->u.dst);
        rt->u.dst.__use++;
        rt->u.dst.lastuse = now;
 
-       write_unlock_bh(&dn_hash_lock);
+       write_unlock_bh(&dn_rt_hash_table[hash].lock);
 }
 
 void dn_run_flush(unsigned long dummy)
@@ -210,18 +220,21 @@ void dn_run_flush(unsigned long dummy)
        int i;
        struct dn_route *rt, *next;
 
-       write_lock_bh(&dn_hash_lock);
-       for(i = 0; i < DN_HASHBUCKETS; i++) {
-               if ((rt = xchg(&dn_route_cache[i], NULL)) == NULL)
-                       continue;
+       for(i = 0; i < dn_rt_hash_mask; i++) {
+               write_lock_bh(&dn_rt_hash_table[i].lock);
+
+               if ((rt = xchg(&dn_rt_hash_table[i].chain, NULL)) == NULL)
+                       goto nothing_to_declare;
 
                for(; rt; rt=next) {
                        next = rt->u.rt_next;
                        rt->u.rt_next = NULL;
                        dst_free((struct dst_entry *)rt);
                }
+
+nothing_to_declare:
+               write_unlock_bh(&dn_rt_hash_table[i].lock);
        }
-       write_unlock_bh(&dn_hash_lock);
 }
 
 static int dn_route_rx_packet(struct sk_buff *skb)
@@ -607,8 +620,8 @@ int dn_route_output(struct dst_entry **pprt, dn_address dst, dn_address src, int
        struct dn_route *rt = NULL;
 
        if (!(flags & MSG_TRYHARD)) {
-               read_lock_bh(&dn_hash_lock);
-               for(rt = dn_route_cache[hash]; rt; rt = rt->u.rt_next) {
+               read_lock_bh(&dn_rt_hash_table[hash].lock);
+               for(rt = dn_rt_hash_table[hash].chain; rt; rt = rt->u.rt_next) {
                        if ((dst == rt->rt_daddr) &&
                                        (src == rt->rt_saddr) &&
                                        (rt->rt_iif == 0) &&
@@ -616,12 +629,12 @@ int dn_route_output(struct dst_entry **pprt, dn_address dst, dn_address src, int
                                rt->u.dst.lastuse = jiffies;
                                dst_hold(&rt->u.dst);
                                rt->u.dst.__use++;
-                               read_unlock_bh(&dn_hash_lock);
+                               read_unlock_bh(&dn_rt_hash_table[hash].lock);
                                *pprt = &rt->u.dst;
                                return 0;
                        }
                }
-               read_unlock_bh(&dn_hash_lock);
+               read_unlock_bh(&dn_rt_hash_table[hash].lock);
        }
 
        return dn_route_output_slow(pprt, dst, src, flags);
@@ -731,8 +744,8 @@ int dn_route_input(struct sk_buff *skb)
        if (skb->dst)
                return 0;
 
-       read_lock_bh(&dn_hash_lock);
-       for(rt = dn_route_cache[hash]; rt != NULL; rt = rt->u.rt_next) {
+       read_lock(&dn_rt_hash_table[hash].lock);
+       for(rt = dn_rt_hash_table[hash].chain; rt != NULL; rt = rt->u.rt_next) {
                if ((rt->rt_saddr == cb->dst) &&
                                (rt->rt_daddr == cb->src) &&
                                (rt->rt_oif == 0) &&
@@ -740,12 +753,12 @@ int dn_route_input(struct sk_buff *skb)
                        rt->u.dst.lastuse = jiffies;
                        dst_hold(&rt->u.dst);
                        rt->u.dst.__use++;
-                       read_unlock_bh(&dn_hash_lock);
+                       read_unlock(&dn_rt_hash_table[hash].lock);
                        skb->dst = (struct dst_entry *)rt;
                        return 0;
                }
        }
-       read_unlock_bh(&dn_hash_lock);
+       read_unlock(&dn_rt_hash_table[hash].lock);
 
        return dn_route_input_slow(skb);
 }
@@ -831,7 +844,9 @@ int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg)
                skb->rx_dev = dev;
                cb->src = src;
                cb->dst = dst;
+               local_bh_disable();
                err = dn_route_input(skb);
+               local_bh_enable();
                memset(cb, 0, sizeof(struct dn_skb_cb));
                rt = (struct dn_route *)skb->dst;
        } else {
@@ -885,25 +900,25 @@ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb)
 
        s_h = cb->args[0];
        s_idx = idx = cb->args[1];
-       for(h = 0; h < DN_HASHBUCKETS; h++) {
+       for(h = 0; h <= dn_rt_hash_mask; h++) {
                if (h < s_h)
                        continue;
                if (h > s_h)
                        s_idx = 0;
-               read_lock_bh(&dn_hash_lock);
-               for(rt = dn_route_cache[h], idx = 0; rt; rt = rt->u.rt_next, idx++) {
+               read_lock_bh(&dn_rt_hash_table[h].lock);
+               for(rt = dn_rt_hash_table[h].chain, idx = 0; rt; rt = rt->u.rt_next, idx++) {
                        if (idx < s_idx)
                                continue;
                        skb->dst = dst_clone(&rt->u.dst);
                        if (dn_rt_fill_info(skb, NETLINK_CB(cb->skb).pid,
                                        cb->nlh->nlmsg_seq, RTM_NEWROUTE, 1) <= 0) {
                                dst_release(xchg(&skb->dst, NULL));
-                               read_unlock_bh(&dn_hash_lock);
+                               read_unlock_bh(&dn_rt_hash_table[h].lock);
                                goto done;
                        }
                        dst_release(xchg(&skb->dst, NULL));
                }
-               read_unlock_bh(&dn_hash_lock);
+               read_unlock_bh(&dn_rt_hash_table[h].lock);
        }
 
 done:
@@ -924,9 +939,9 @@ static int decnet_cache_get_info(char *buffer, char **start, off_t offset, int l
        int i;
        char buf1[DN_ASCBUF_LEN], buf2[DN_ASCBUF_LEN];
 
-       read_lock_bh(&dn_hash_lock);
-       for(i = 0; i < DN_HASHBUCKETS; i++) {
-               rt = dn_route_cache[i];
+       for(i = 0; i <= dn_rt_hash_mask; i++) {
+               read_lock_bh(&dn_rt_hash_table[i].lock);
+               rt = dn_rt_hash_table[i].chain;
                for(; rt != NULL; rt = rt->u.rt_next) {
                        len += sprintf(buffer + len, "%-8s %-7s %-7s %04d %04d %04d\n",
                                        rt->u.dst.dev ? rt->u.dst.dev->name : "*",
@@ -937,6 +952,7 @@ static int decnet_cache_get_info(char *buffer, char **start, off_t offset, int l
                                        (int)rt->u.dst.rtt
                                        );
 
+
                        pos = begin + len;
        
                        if (pos < offset) {
@@ -946,10 +962,10 @@ static int decnet_cache_get_info(char *buffer, char **start, off_t offset, int l
                        if (pos > offset + length)
                                break;
                }
+               read_unlock_bh(&dn_rt_hash_table[i].lock);
                if (pos > offset + length)
                        break;
        }
-       read_unlock_bh(&dn_hash_lock);
 
         *start = buffer + (offset - begin);
         len   -= (offset - begin);
@@ -963,17 +979,55 @@ static int decnet_cache_get_info(char *buffer, char **start, off_t offset, int l
 
 void __init dn_route_init(void)
 {
-       memset(dn_route_cache, 0, sizeof(struct dn_route *) * DN_HASHBUCKETS);
+       int i, goal, order;
 
        dn_dst_ops.kmem_cachep = kmem_cache_create("dn_dst_cache",
                                                   sizeof(struct dn_route),
                                                   0, SLAB_HWCACHE_ALIGN,
                                                   NULL, NULL);
 
+       if (!dn_dst_ops.kmem_cachep)
+               panic("DECnet: Failed to allocate dn_dst_cache\n");
+
        dn_route_timer.function = dn_dst_check_expire;
        dn_route_timer.expires = jiffies + decnet_dst_gc_interval * HZ;
        add_timer(&dn_route_timer);
 
+       goal = num_physpages >> (26 - PAGE_SHIFT);
+
+       for(order = 0; (1UL << order) < goal; order++)
+               /* NOTHING */;
+
+       /*
+        * Only want 1024 entries max, since the table is very, very unlikely
+        * to be larger than that.
+        */
+       while(order && ((((1UL << order) * PAGE_SIZE) / 
+                               sizeof(struct dn_rt_hash_bucket)) >= 2048))
+               order--;
+
+       do {
+               dn_rt_hash_mask = (1UL << order) * PAGE_SIZE /
+                       sizeof(struct dn_rt_hash_bucket);
+               while(dn_rt_hash_mask & (dn_rt_hash_mask - 1))
+                       dn_rt_hash_mask--;
+               dn_rt_hash_table = (struct dn_rt_hash_bucket *)
+                       __get_free_pages(GFP_ATOMIC, order);
+       } while (dn_rt_hash_table == NULL && --order > 0);
+
+       if (!dn_rt_hash_table)
+               panic("Failed to allocate DECnet route cache hash table\n");
+
+       printk(KERN_INFO "DECnet: Routing cache hash table of %u buckets, %dKbytes\n", dn_rt_hash_mask, (dn_rt_hash_mask*sizeof(struct dn_rt_hash_bucket))/1024);
+
+       dn_rt_hash_mask--;
+       for(i = 0; i <= dn_rt_hash_mask; i++) {
+               dn_rt_hash_table[i].lock = RW_LOCK_UNLOCKED;
+               dn_rt_hash_table[i].chain = NULL;
+       }
+
+       dn_dst_ops.gc_thresh = (dn_rt_hash_mask + 1);
+
 #ifdef CONFIG_PROC_FS
        proc_net_create("decnet_cache",0,decnet_cache_get_info);
 #endif /* CONFIG_PROC_FS */
index 3d000201b5633752e2ffa242189b5bd38bd948bd..5acfa8953072f8dd7fd37ea85e904d76ee00eaf8 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             ROUTE - implementation of the IP router.
  *
- * Version:    $Id: route.c,v 1.75 1999/12/23 01:41:44 davem Exp $
+ * Version:    $Id: route.c,v 1.77 2000/01/06 00:41:59 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 
 int ip_rt_min_delay = 2*HZ;
 int ip_rt_max_delay = 10*HZ;
-int ip_rt_gc_thresh = RT_HASH_DIVISOR;
-int ip_rt_max_size = RT_HASH_DIVISOR*16;
+int ip_rt_max_size;
 int ip_rt_gc_timeout = RT_GC_TIMEOUT;
 int ip_rt_gc_interval = 60*HZ;
 int ip_rt_gc_min_interval = 5*HZ;
@@ -122,12 +121,8 @@ static unsigned long rt_deadline = 0;
 
 #define RTprint(a...)  printk(KERN_DEBUG a)
 
-static void rt_run_flush(unsigned long dummy);
-
-static struct timer_list rt_flush_timer =
-       { NULL, NULL, 0, 0L, rt_run_flush };
-static struct timer_list rt_periodic_timer =
-       { NULL, NULL, 0, 0L, NULL };
+static struct timer_list rt_flush_timer;
+static struct timer_list rt_periodic_timer;
 
 /*
  *     Interface to generic destination cache.
@@ -146,7 +141,7 @@ struct dst_ops ipv4_dst_ops =
 {
        AF_INET,
        __constant_htons(ETH_P_IP),
-       RT_HASH_DIVISOR,
+       0,
 
        rt_garbage_collect,
        ipv4_dst_check,
@@ -183,7 +178,7 @@ __u8 ip_tos2prio[16] = {
 
 /* The locking scheme is rather straight forward:
  *
- * 1) A BH protected rwlock protects the central route hash.
+ * 1) A BH protected rwlocks protect buckets of the central route hash.
  * 2) Only writers remove entries, and they hold the lock
  *    as they look at rtable reference counts.
  * 3) Only readers acquire references to rtable entries,
@@ -191,17 +186,23 @@ __u8 ip_tos2prio[16] = {
  *    lock held.
  */
 
-static struct rtable   *rt_hash_table[RT_HASH_DIVISOR];
-static rwlock_t                 rt_hash_lock = RW_LOCK_UNLOCKED;
+struct rt_hash_bucket {
+       struct rtable   *chain;
+       rwlock_t        lock;
+} __attribute__((__aligned__(8)));
+
+static struct rt_hash_bucket   *rt_hash_table;
+static unsigned                        rt_hash_mask;
+static int                     rt_hash_log;
 
 static int rt_intern_hash(unsigned hash, struct rtable * rth, struct rtable ** res);
 
 static __inline__ unsigned rt_hash_code(u32 daddr, u32 saddr, u8 tos)
 {
        unsigned hash = ((daddr&0xF0F0F0F0)>>4)|((daddr&0x0F0F0F0F)<<4);
-       hash = hash^saddr^tos;
-       hash = hash^(hash>>16);
-       return (hash^(hash>>8)) & 0xFF;
+       hash ^= saddr^tos;
+       hash ^= (hash>>16);
+       return (hash^(hash>>8)) & rt_hash_mask;
 }
 
 #ifndef CONFIG_PROC_FS
@@ -222,11 +223,9 @@ static int rt_cache_get_info(char *buffer, char **start, off_t offset, int lengt
                len = 128;
        }
        
-       
-       read_lock_bh(&rt_hash_lock);
-
-       for (i = 0; i<RT_HASH_DIVISOR; i++) {
-               for (r = rt_hash_table[i]; r; r = r->u.rt_next) {
+       for (i = rt_hash_mask; i>=0; i--) {
+               read_lock_bh(&rt_hash_table[i].lock);
+               for (r = rt_hash_table[i].chain; r; r = r->u.rt_next) {
                        /*
                         *      Spin through entries until we are ready
                         */
@@ -253,14 +252,15 @@ static int rt_cache_get_info(char *buffer, char **start, off_t offset, int lengt
                                r->rt_spec_dst);
                        sprintf(buffer+len,"%-127s\n",temp);
                        len += 128;
-                       if (pos >= offset+length)
+                       if (pos >= offset+length) {
+                               read_unlock_bh(&rt_hash_table[i].lock);
                                goto done;
+                       }
                }
+               read_unlock_bh(&rt_hash_table[i].lock);
         }
 
 done:
-       read_unlock_bh(&rt_hash_lock);
-       
        *start = buffer+len-(pos-offset);
        len = pos-offset;
        if (len>length)
@@ -315,21 +315,23 @@ static __inline__ int rt_may_expire(struct rtable *rth, int tmo1, int tmo2)
 /* This runs via a timer and thus is always in BH context. */
 static void rt_check_expire(unsigned long dummy)
 {
-       int i;
+       int i, t;
        static int rover;
        struct rtable *rth, **rthp;
        unsigned long now = jiffies;
 
-       for (i=0; i<RT_HASH_DIVISOR/5; i++) {
+       i = rover;
+
+       for (t=(ip_rt_gc_interval<<rt_hash_log); t>=0; t -= ip_rt_gc_timeout) {
                unsigned tmo = ip_rt_gc_timeout;
 
-               rover = (rover + 1) & (RT_HASH_DIVISOR-1);
-               rthp = &rt_hash_table[rover];
+               i = (i + 1) & rt_hash_mask;
+               rthp = &rt_hash_table[i].chain;
 
-               write_lock(&rt_hash_lock);
+               write_lock(&rt_hash_table[i].lock);
                while ((rth = *rthp) != NULL) {
                        if (rth->u.dst.expires) {
-                               /* Entrie is expired even if it is in use */
+                               /* Entry is expired even if it is in use */
                                if ((long)(now - rth->u.dst.expires) <= 0) {
                                        tmo >>= 1;
                                        rthp = &rth->u.rt_next;
@@ -347,14 +349,14 @@ static void rt_check_expire(unsigned long dummy)
                        *rthp = rth->u.rt_next;
                        rt_free(rth);
                }
-               write_unlock(&rt_hash_lock);
+               write_unlock(&rt_hash_table[i].lock);
 
                /* Fallback loop breaker. */
                if ((jiffies - now) > 0)
                        break;
        }
-       rt_periodic_timer.expires = now + ip_rt_gc_interval;
-       add_timer(&rt_periodic_timer);
+       rover = i;
+       mod_timer(&rt_periodic_timer, now + ip_rt_gc_interval);
 }
 
 /* This can run from both BH and non-BH contexts, the latter
@@ -367,11 +369,12 @@ static void rt_run_flush(unsigned long dummy)
 
        rt_deadline = 0;
 
-       for (i=0; i<RT_HASH_DIVISOR; i++) {
-               write_lock_bh(&rt_hash_lock);
-               rth = rt_hash_table[i];
-               rt_hash_table[i] = NULL;
-               write_unlock_bh(&rt_hash_lock);
+       for (i=rt_hash_mask; i>=0; i--) {
+               write_lock_bh(&rt_hash_table[i].lock);
+               rth = rt_hash_table[i].chain;
+               if (rth)
+                       rt_hash_table[i].chain = NULL;
+               write_unlock_bh(&rt_hash_table[i].lock);
 
                for (; rth; rth=next) {
                        next = rth->u.rt_next;
@@ -418,8 +421,7 @@ void rt_cache_flush(int delay)
        if (rt_deadline == 0)
                rt_deadline = now + ip_rt_max_delay;
 
-       rt_flush_timer.expires = now + delay;
-       add_timer(&rt_flush_timer);
+       mod_timer(&rt_flush_timer, now+delay);
        spin_unlock_bh(&rt_flush_lock);
 }
 
@@ -455,20 +457,20 @@ static int rt_garbage_collect(void)
                return 0;
 
        /* Calculate number of entries, which we want to expire now. */
-       goal = atomic_read(&ipv4_dst_ops.entries) - RT_HASH_DIVISOR*ip_rt_gc_elasticity;
+       goal = atomic_read(&ipv4_dst_ops.entries) - (ip_rt_gc_elasticity<<rt_hash_log);
        if (goal <= 0) {
                if (equilibrium < ipv4_dst_ops.gc_thresh)
                        equilibrium = ipv4_dst_ops.gc_thresh;
                goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium;
                if (goal > 0) {
-                       equilibrium += min(goal/2, RT_HASH_DIVISOR);
+                       equilibrium += min(goal/2, rt_hash_mask+1);
                        goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium;
                }
        } else {
                /* We are in dangerous area. Try to reduce cache really
                 * aggressively.
                 */
-               goal = max(goal/2, RT_HASH_DIVISOR);
+               goal = max(goal/2, rt_hash_mask+1);
                equilibrium = atomic_read(&ipv4_dst_ops.entries) - goal;
        }
 
@@ -483,15 +485,12 @@ static int rt_garbage_collect(void)
        do {
                int i, k;
 
-               /* The write lock is held during the entire hash
-                * traversal to ensure consistent state of the rover.
-                */
-               write_lock_bh(&rt_hash_lock);
-               for (i=0, k=rover; i<RT_HASH_DIVISOR; i++) {
+               for (i=rt_hash_mask, k=rover; i>=0; i--) {
                        unsigned tmo = expire;
 
-                       k = (k + 1) & (RT_HASH_DIVISOR-1);
-                       rthp = &rt_hash_table[k];
+                       k = (k + 1) & rt_hash_mask;
+                       rthp = &rt_hash_table[k].chain;
+                       write_lock_bh(&rt_hash_table[k].lock);
                        while ((rth = *rthp) != NULL) {
                                if (!rt_may_expire(rth, tmo, expire)) {
                                        tmo >>= 1;
@@ -502,11 +501,11 @@ static int rt_garbage_collect(void)
                                rt_free(rth);
                                goal--;
                        }
+                       write_unlock_bh(&rt_hash_table[k].lock);
                        if (goal <= 0)
                                break;
                }
                rover = k;
-               write_unlock_bh(&rt_hash_lock);
 
                if (goal <= 0)
                        goto work_done;
@@ -556,20 +555,20 @@ static int rt_intern_hash(unsigned hash, struct rtable * rt, struct rtable ** rp
        int attempts = !in_interrupt();
 
 restart:
-       rthp = &rt_hash_table[hash];
+       rthp = &rt_hash_table[hash].chain;
 
-       write_lock_bh(&rt_hash_lock);
+       write_lock_bh(&rt_hash_table[hash].lock);
        while ((rth = *rthp) != NULL) {
                if (memcmp(&rth->key, &rt->key, sizeof(rt->key)) == 0) {
                        /* Put it first */
                        *rthp = rth->u.rt_next;
-                       rth->u.rt_next = rt_hash_table[hash];
-                       rt_hash_table[hash] = rth;
+                       rth->u.rt_next = rt_hash_table[hash].chain;
+                       rt_hash_table[hash].chain = rth;
 
                        rth->u.dst.__use++;
                        dst_hold(&rth->u.dst);
                        rth->u.dst.lastuse = now;
-                       write_unlock_bh(&rt_hash_lock);
+                       write_unlock_bh(&rt_hash_table[hash].lock);
 
                        rt_drop(rt);
                        *rp = rth;
@@ -584,7 +583,7 @@ restart:
         */
        if (rt->rt_type == RTN_UNICAST || rt->key.iif == 0) {
                if (!arp_bind_neighbour(&rt->u.dst)) {
-                       write_unlock_bh(&rt_hash_lock);
+                       write_unlock_bh(&rt_hash_table[hash].lock);
 
                        /* Neighbour tables are full and nothing
                           can be released. Try to shrink route cache,
@@ -613,7 +612,7 @@ restart:
                }
        }
 
-       rt->u.rt_next = rt_hash_table[hash];
+       rt->u.rt_next = rt_hash_table[hash].chain;
 #if RT_CACHE_DEBUG >= 2
        if (rt->u.rt_next) {
                struct rtable * trt;
@@ -623,8 +622,8 @@ restart:
                printk("\n");
        }
 #endif
-       rt_hash_table[hash] = rt;
-       write_unlock_bh(&rt_hash_lock);
+       rt_hash_table[hash].chain = rt;
+       write_unlock_bh(&rt_hash_table[hash].lock);
        *rp = rt;
        return 0;
 }
@@ -692,16 +691,16 @@ static void rt_del(unsigned hash, struct rtable *rt)
 {
        struct rtable **rthp;
 
-       write_lock_bh(&rt_hash_lock);
+       write_lock_bh(&rt_hash_table[hash].lock);
        ip_rt_put(rt);
-       for (rthp = &rt_hash_table[hash]; *rthp; rthp = &(*rthp)->u.rt_next) {
+       for (rthp = &rt_hash_table[hash].chain; *rthp; rthp = &(*rthp)->u.rt_next) {
                if (*rthp == rt) {
                        *rthp = rt->u.rt_next;
                        rt_free(rt);
                        break;
                }
        }
-       write_unlock_bh(&rt_hash_lock);
+       write_unlock_bh(&rt_hash_table[hash].lock);
 }
 
 void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
@@ -736,9 +735,9 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
                for (k=0; k<2; k++) {
                        unsigned hash = rt_hash_code(daddr, skeys[i]^(ikeys[k]<<5), tos);
 
-                       rthp=&rt_hash_table[hash];
+                       rthp=&rt_hash_table[hash].chain;
 
-                       read_lock(&rt_hash_lock);
+                       read_lock(&rt_hash_table[hash].lock);
                        while ( (rth = *rthp) != NULL) {
                                struct rtable *rt;
 
@@ -759,7 +758,7 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
                                        break;
 
                                dst_clone(&rth->u.dst);
-                               read_unlock(&rt_hash_lock);
+                               read_unlock(&rt_hash_table[hash].lock);
 
                                rt = dst_alloc(&ipv4_dst_ops);
                                if (rt == NULL) {
@@ -806,7 +805,7 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
                                        ip_rt_put(rt);
                                goto do_next;
                        }
-                       read_unlock(&rt_hash_lock);
+                       read_unlock(&rt_hash_table[hash].lock);
                do_next:
                        ;
                }
@@ -974,8 +973,8 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
        for (i=0; i<2; i++) {
                unsigned hash = rt_hash_code(daddr, skeys[i], tos);
 
-               read_lock(&rt_hash_lock);
-               for (rth = rt_hash_table[hash]; rth; rth = rth->u.rt_next) {
+               read_lock(&rt_hash_table[hash].lock);
+               for (rth = rt_hash_table[hash].chain; rth; rth = rth->u.rt_next) {
                        if (rth->key.dst == daddr &&
                            rth->key.src == skeys[i] &&
                            rth->rt_dst == daddr &&
@@ -1008,7 +1007,7 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
                                }
                        }
                }
-               read_unlock(&rt_hash_lock);
+               read_unlock(&rt_hash_table[hash].lock);
        }
        return est_mtu ? : new_mtu;
 }
@@ -1550,8 +1549,8 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
        tos &= IPTOS_TOS_MASK;
        hash = rt_hash_code(daddr, saddr^(iif<<5), tos);
 
-       read_lock_bh(&rt_hash_lock);
-       for (rth=rt_hash_table[hash]; rth; rth=rth->u.rt_next) {
+       read_lock(&rt_hash_table[hash].lock);
+       for (rth=rt_hash_table[hash].chain; rth; rth=rth->u.rt_next) {
                if (rth->key.dst == daddr &&
                    rth->key.src == saddr &&
                    rth->key.iif == iif &&
@@ -1565,12 +1564,12 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
                        rth->u.dst.lastuse = jiffies;
                        dst_hold(&rth->u.dst);
                        rth->u.dst.__use++;
-                       read_unlock_bh(&rt_hash_lock);
+                       read_unlock(&rt_hash_table[hash].lock);
                        skb->dst = (struct dst_entry*)rth;
                        return 0;
                }
        }
-       read_unlock_bh(&rt_hash_lock);
+       read_unlock(&rt_hash_table[hash].lock);
 
        /* Multicast recognition logic is moved from route cache to here.
           The problem was that too many Ethernet cards have broken/missing
@@ -1885,8 +1884,8 @@ int ip_route_output(struct rtable **rp, u32 daddr, u32 saddr, u32 tos, int oif)
 
        hash = rt_hash_code(daddr, saddr^(oif<<5), tos);
 
-       read_lock_bh(&rt_hash_lock);
-       for (rth=rt_hash_table[hash]; rth; rth=rth->u.rt_next) {
+       read_lock_bh(&rt_hash_table[hash].lock);
+       for (rth=rt_hash_table[hash].chain; rth; rth=rth->u.rt_next) {
                if (rth->key.dst == daddr &&
                    rth->key.src == saddr &&
                    rth->key.iif == 0 &&
@@ -1897,12 +1896,12 @@ int ip_route_output(struct rtable **rp, u32 daddr, u32 saddr, u32 tos, int oif)
                        rth->u.dst.lastuse = jiffies;
                        dst_hold(&rth->u.dst);
                        rth->u.dst.__use++;
-                       read_unlock_bh(&rt_hash_lock);
+                       read_unlock_bh(&rt_hash_table[hash].lock);
                        *rp = rth;
                        return 0;
                }
        }
-       read_unlock_bh(&rt_hash_lock);
+       read_unlock_bh(&rt_hash_table[hash].lock);
 
        return ip_route_output_slow(rp, daddr, saddr, tos, oif);
 }
@@ -2043,7 +2042,9 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
                        return -ENODEV;
                skb->protocol = __constant_htons(ETH_P_IP);
                skb->dev = dev;
+               local_bh_disable();
                err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev);
+               local_bh_enable();
                rt = (struct rtable*)skb->dst;
                if (!err && rt->u.dst.error)
                        err = -rt->u.dst.error;
@@ -2085,24 +2086,24 @@ int ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb)
 
        s_h = cb->args[0];
        s_idx = idx = cb->args[1];
-       for (h=0; h < RT_HASH_DIVISOR; h++) {
+       for (h=0; h <= rt_hash_mask; h++) {
                if (h < s_h) continue;
                if (h > s_h)
                        s_idx = 0;
-               read_lock_bh(&rt_hash_lock);
-               for (rt = rt_hash_table[h], idx = 0; rt; rt = rt->u.rt_next, idx++) {
+               read_lock_bh(&rt_hash_table[h].lock);
+               for (rt = rt_hash_table[h].chain, idx = 0; rt; rt = rt->u.rt_next, idx++) {
                        if (idx < s_idx)
                                continue;
                        skb->dst = dst_clone(&rt->u.dst);
                        if (rt_fill_info(skb, NETLINK_CB(cb->skb).pid,
                                         cb->nlh->nlmsg_seq, RTM_NEWROUTE, 1) <= 0) {
                                dst_release(xchg(&skb->dst, NULL));
-                               read_unlock_bh(&rt_hash_lock);
+                               read_unlock_bh(&rt_hash_table[h].lock);
                                goto done;
                        }
                        dst_release(xchg(&skb->dst, NULL));
                }
-               read_unlock_bh(&rt_hash_lock);
+               read_unlock_bh(&rt_hash_table[h].lock);
        }
 
 done:
@@ -2231,17 +2232,56 @@ static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
 #endif
 #endif
 
-
 void __init ip_rt_init(void)
 {
+       int i, order, goal;
+
        ipv4_dst_ops.kmem_cachep = kmem_cache_create("ip_dst_cache",
                                                     sizeof(struct rtable),
                                                     0, SLAB_HWCACHE_ALIGN,
                                                     NULL, NULL);
-       
+
+       if (!ipv4_dst_ops.kmem_cachep)
+               panic("IP: failed to allocate ip_dst_cache\n");
+
+       goal = num_physpages >> (26 - PAGE_SHIFT);
+
+       for (order = 0; (1UL << order) < goal; order++)
+               /* NOTHING */;
+
+       do {
+               rt_hash_mask = (1UL << order) * PAGE_SIZE /
+                       sizeof(struct rt_hash_bucket);
+               while (rt_hash_mask & (rt_hash_mask-1))
+                       rt_hash_mask--;
+               rt_hash_table = (struct rt_hash_bucket *)
+                       __get_free_pages(GFP_ATOMIC, order);
+       } while (rt_hash_table == NULL && --order > 0);
+
+       if (!rt_hash_table)
+               panic("Failed to allocate IP route cache hash table\n");
+
+       printk("IP: routing cache hash table of %u buckets, %dKbytes\n",
+              rt_hash_mask, (rt_hash_mask*sizeof(struct rt_hash_bucket))/1024);
+
+       for (rt_hash_log=0; (1<<rt_hash_log) != rt_hash_mask; rt_hash_log++)
+               /* NOTHING */;
+
+       rt_hash_mask--;
+       for (i = 0; i <= rt_hash_mask; i++) {
+               rt_hash_table[i].lock = RW_LOCK_UNLOCKED;
+               rt_hash_table[i].chain = NULL;
+       }
+
+       ipv4_dst_ops.gc_thresh = (rt_hash_mask+1);
+       ip_rt_max_size = (rt_hash_mask+1)*16;
+
        devinet_init();
        ip_fib_init();
+
+       rt_flush_timer.function = rt_run_flush;
        rt_periodic_timer.function = rt_check_expire;
+
        /* All the timers, started at system startup tend
           to synchronize. Perturb it a bit.
         */
index 5672bcbacef55829b8cdf776784c647ae62c24a7..27df3243d44e9eb6d9b0cf4a7a319fb46713acdb 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             The User Datagram Protocol (UDP).
  *
- * Version:    $Id: udp.c,v 1.75 1999/12/15 22:39:34 davem Exp $
+ * Version:    $Id: udp.c,v 1.76 2000/01/05 21:27:51 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -665,10 +665,6 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
        return(0);
 }
 
-#ifndef HAVE_CSUM_COPY_USER
-#undef CONFIG_UDP_DELAY_CSUM
-#endif
-
 /*
  *     This should be easy, if there is something there we
  *     return it, otherwise we block.
index c6539ee896f25adf42de87104a1d86922f2f5b1b..7bc3a3914b254587934dc7a0657a1042fd19af59 100644 (file)
@@ -7,7 +7,7 @@
  *
  *     Based on linux/ipv4/udp.c
  *
- *     $Id: udp.c,v 1.46 1999/12/15 22:40:03 davem Exp $
+ *     $Id: udp.c,v 1.47 2000/01/05 21:27:54 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -341,10 +341,6 @@ static void udpv6_close(struct sock *sk, long timeout)
        inet_sock_release(sk);
 }
 
-#ifndef HAVE_CSUM_COPY_USER
-#undef CONFIG_UDP_DELAY_CSUM
-#endif
-
 /*
  *     This should be easy, if there is something there we
  *     return it, otherwise we block.
index 60dbdc2886b83b1bfe5b6bc43dc69efb01d73b1b..9f52dfe4e020d63a67fcebfbca0d7fa256c67bca 100644 (file)
@@ -6,7 +6,7 @@
  *              Revision Date:  February 9, 1993
  *
  *     Developers:
- *      Jay Schulist    <Jay.Schulist@spacs.k12.wi.us>
+ *      Jay Schulist    <jschlst@turbolinux.com>
  *     Jim Freeman     <jfree@caldera.com>
  *
  *     Changes:
index ded65eb9c2b1425342c334e0c7626710a09c2b55..ab556cf8ce7ab0c707917f574df63cef3f204fb1 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Stable
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun May 31 10:12:43 1998
- * Modified at:   Fri Dec 17 22:37:53 1999
+ * Modified at:   Sat Dec 25 21:10:23 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc.
  * 
@@ -42,7 +42,6 @@
  *     
  ********************************************************************/
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
@@ -324,13 +323,13 @@ static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow)
 }
 
 /*
- * Function irda_get_value_confirm (obj_id, value, priv)
+ * Function irda_getvalue_confirm (obj_id, value, priv)
  *
  *    Got answer from remote LM-IAS
  *
  */
-static void irda_get_value_confirm(int result, __u16 obj_id, 
-                                  struct ias_value *value, void *priv)
+static void irda_getvalue_confirm(int result, __u16 obj_id, 
+                                 struct ias_value *value, void *priv)
 {
        struct irda_sock *self;
        
@@ -348,12 +347,12 @@ static void irda_get_value_confirm(int result, __u16 obj_id,
        iriap_close(self->iriap);
        self->iriap = NULL;
 
+       self->errno = result;
+
        /* Check if request succeeded */
        if (result != IAS_SUCCESS) {
                IRDA_DEBUG(0, __FUNCTION__ "(), IAS query failed!\n");
 
-               self->errno = result;
-
                /* Wake up any processes waiting for result */
                wake_up_interruptible(&self->ias_wait);
 
@@ -483,7 +482,7 @@ static int irda_find_lsap_sel(struct irda_sock *self, char *name)
        }
 
        self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
-                                irda_get_value_confirm);
+                                irda_getvalue_confirm);
 
        /* Query remote LM-IAS */
        iriap_getvaluebyclass_request(self->iriap, self->saddr, self->daddr,
@@ -1652,7 +1651,7 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
                        irias_add_octseq_attrib(
                              ias_obj,
                              ias_opt.irda_attrib_name, 
-                             ias_opt.attribute.irda_attrib_octet_seq.OctetSeq,
+                             ias_opt.attribute.irda_attrib_octet_seq.octet_seq,
                              ias_opt.attribute.irda_attrib_octet_seq.len);
                        break;
                case IAS_STRING:
@@ -1716,14 +1715,14 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
 }
 
  /*
- * Function irda_simple_get_value_confirm (obj_id, value, priv)
+ * Function irda_simple_getvalue_confirm (obj_id, value, priv)
  *
  *    Got answer from remote LM-IAS, just copy object to requester...
  *
  * Note : duplicate from above, but we need our own version that
  * doesn't touch the dtsap_sel and save the full value structure...
  */
-static void irda_simple_get_value_confirm(int result, __u16 obj_id, 
+static void irda_simple_getvalue_confirm(int result, __u16 obj_id, 
                                          struct ias_value *value, void *priv)
 {
        struct irda_sock *self;
@@ -1746,7 +1745,7 @@ static void irda_simple_get_value_confirm(int result, __u16 obj_id,
        if (result != IAS_SUCCESS) {
                IRDA_DEBUG(0, __FUNCTION__ "(), IAS query failed!\n");
 
-               self->errno = result;
+               self->errno = -EHOSTUNREACH;
 
                /* Wake up any processes waiting for result */
                wake_up_interruptible(&self->ias_wait);
@@ -1757,6 +1756,9 @@ static void irda_simple_get_value_confirm(int result, __u16 obj_id,
        /* Clone the object (so the requester can free it) */
        self->ias_result = kmalloc(sizeof(struct ias_value), GFP_ATOMIC);
        memcpy(self->ias_result, value, sizeof(struct ias_value));
+       irias_delete_value(value);
+
+       self->errno = 0;
 
        /* Wake up any processes waiting for result */
        wake_up_interruptible(&self->ias_wait);
@@ -1778,7 +1780,7 @@ static int irda_extract_ias_value(struct irda_ias_set *ias_opt,
                                  struct ias_value *ias_value)
 {
        /* Look at the type */
-       switch(ias_value->type) {
+       switch (ias_value->type) {
        case IAS_INTEGER:
                /* Copy the integer */
                ias_opt->attribute.irda_attrib_int = ias_value->t.integer;
@@ -1787,7 +1789,7 @@ static int irda_extract_ias_value(struct irda_ias_set *ias_opt,
                /* Set length */
                ias_opt->attribute.irda_attrib_octet_seq.len = ias_value->len;
                /* Copy over */
-               memcpy(ias_opt->attribute.irda_attrib_octet_seq.OctetSeq,
+               memcpy(ias_opt->attribute.irda_attrib_octet_seq.octet_seq,
                       ias_value->t.oct_seq, ias_value->len);
                break;
        case IAS_STRING:
@@ -1803,10 +1805,10 @@ static int irda_extract_ias_value(struct irda_ias_set *ias_opt,
        default :
                return -EINVAL;
        }
-
+       
        /* Copy type over */
        ias_opt->irda_attrib_type = ias_value->type;
-
+       
        return 0;
 }
 
@@ -1827,7 +1829,6 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
        struct irda_ias_set     ias_opt;        /* IAS get/query params */
        struct ias_object *     ias_obj;        /* Object in IAS */
        struct ias_attrib *     ias_attr;       /* Attribute in IAS object */
-       int daddr = 0;          /* Destination address for IAS queries */
        int val = 0;
        int len = 0;
        int err;
@@ -1962,21 +1963,6 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
                if (copy_from_user((char *) &ias_opt, (char *)optval, len))
                        return -EFAULT;
 
-               /* Check the destination address requested */
-               daddr = ias_opt.attribute.irda_attrib_int;
-               if(self->daddr != DEV_ADDR_ANY) {
-                       /* If we are connected, we must use the correct
-                        * destination address (or leave it unspecified) */
-                       if((daddr != DEV_ADDR_ANY) || (daddr != self->daddr))
-                               return -EINVAL;
-                       daddr = self->daddr;
-               } else {
-                       /* If we are not connected, we must specify a valid
-                        * destination address */
-                       if(daddr == DEV_ADDR_ANY)
-                               return -EINVAL;
-               }
-
                /* Check that we can proceed with IAP */
                if (self->iriap) {
                        WARNING(__FUNCTION__
@@ -1985,24 +1971,27 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
                }
 
                self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
-                                        irda_simple_get_value_confirm);
+                                        irda_simple_getvalue_confirm);
+
+               /* Treat unexpected signals as disconnect */
+               self->errno = -EHOSTUNREACH;
 
                /* Query remote LM-IAS */
-               self->errno = 0;
-               iriap_getvaluebyclass_request(self->iriap, self->saddr,
-                                             daddr,
+               iriap_getvaluebyclass_request(self->iriap, 
+                                             self->saddr, self->daddr,
                                              ias_opt.irda_class_name,
                                              ias_opt.irda_attrib_name);
                /* Wait for answer */
                interruptible_sleep_on(&self->ias_wait);
                /* Check what happened */
-               if(self->errno)
-                       return(self->errno);
+               if (self->errno)
+                       return (self->errno);
 
                /* Translate from internal to user structure */
                err = irda_extract_ias_value(&ias_opt, self->ias_result);
-               kfree(self->ias_result); /* Cleanup (need to be *here*) */
-               if(err)
+               if (self->ias_result)
+                       kfree(self->ias_result);
+               if (err)
                        return err;
 
                /* Copy reply to the user */
@@ -2014,7 +2003,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname,
        default:
                return -ENOPROTOOPT;
        }
-
+       
        return 0;
 }
 
index 09a4d34c724270cae098f83d82961605a587b5a0..80518612874f48de57e2883de39c5cafcf3a1a96 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 20:37:34 1999
- * Modified at:   Thu Dec 16 21:15:26 1999
+ * Modified at:   Tue Dec 21 13:26:41 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
index c21107813a03f54ea55678a86bbdc0a254af0ca4..b53f8a8cf2cf653e52575e0d000c587de23e06c1 100644 (file)
@@ -6,11 +6,11 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 21:00:56 1999
- * Modified at:   Thu Dec 16 22:07:37 1999
+ * Modified at:   Tue Jan  4 14:12:06 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       serial.c and previous IrCOMM work by Takahide Higuchi
  * 
- *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -280,13 +280,15 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
        }
 
        if (self->flags & ASYNC_CALLOUT_ACTIVE) {
-               if (self->normal_termios.c_cflag & CLOCAL)
+               if (self->normal_termios.c_cflag & CLOCAL) {
                        IRDA_DEBUG(1, __FUNCTION__ "(), doing CLOCAL!\n");
                        do_clocal = 1;
+               }
        } else {
-               if (tty->termios->c_cflag & CLOCAL)
+               if (tty->termios->c_cflag & CLOCAL) {
                        IRDA_DEBUG(1, __FUNCTION__ "(), doing CLOCAL!\n");
                        do_clocal = 1;
+               }
        }
        
        /* Wait for carrier detect and the line to become
@@ -459,10 +461,12 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
        /* Check if this is a "normal" ircomm device, or an irlpt device */
        if (line < 0x10) {
                self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE;
+               self->settings.service_type = IRCOMM_9_WIRE; /* Default */
                IRDA_DEBUG(2, __FUNCTION__ "(), IrCOMM device\n");
        } else {
                IRDA_DEBUG(2, __FUNCTION__ "(), IrLPT device\n");
                self->service_type = IRCOMM_3_WIRE_RAW;
+               self->settings.service_type = IRCOMM_3_WIRE_RAW; /* Default */
        }
 
        ret = ircomm_tty_startup(self);
index 374ddbb7e3c9ba7c3af95f837e80b7572bc112c2..94c9fee0947318ed03e63b85d0187b489e02bb2f 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Jun  5 17:42:00 1999
- * Modified at:   Wed Dec 15 23:32:08 1999
+ * Modified at:   Tue Jan  4 14:20:49 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -496,10 +496,11 @@ void ircomm_tty_link_established(struct ircomm_tty_cb *self)
        
        del_timer(&self->watchdog_timer);
 
-       /*  
+       /* 
         * IrCOMM link is now up, and if we are not using hardware
-        * flow-control, then declare the hardware as running. Otherwise
-        * the client will have to wait for the CTS to be set.
+        * flow-control, then declare the hardware as running. Otherwise we
+        * will have to wait for the peer device (DCE) to raise the CTS
+        * line.  
         */
        if (self->flags & ASYNC_CTS_FLOW) {
                IRDA_DEBUG(0, __FUNCTION__ "(), waiting for CTS ...\n");
index 411da7c4e379f7528792e1247ce1900c3e170749..107ceb612ef1022a2a1813a5ba0c4601d463703f 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Jun 10 14:39:09 1999
- * Modified at:   Tue Dec 14 18:08:09 1999
+ * Modified at:   Wed Jan  5 14:45:43 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -93,10 +93,11 @@ void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
        /* CTS flow control flag and modem status interrupts */
        if (cflag & CRTSCTS) {
                self->flags |= ASYNC_CTS_FLOW;
-               /* self->settings.flow_control |= IRCOMM_RTS_CTS_IN; */
-       } else
+               self->settings.flow_control |= IRCOMM_RTS_CTS_IN;
+       } else {
                self->flags &= ~ASYNC_CTS_FLOW;
-       
+               self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN;
+       }
        if (cflag & CLOCAL)
                self->flags &= ~ASYNC_CHECK_CD;
        else
index 1d95a69b47f09366986c5c6966405a6b578598a9..0e272947d4ff7d8bdd970ab6f9c95200583b591f 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Oct  9 09:22:27 1999
- * Modified at:   Tue Dec 21 21:53:45 1999
+ * Modified at:   Wed Jan  5 14:17:16 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
index 3da2e514ad8a135f6934d18aba2da8975f2cee3c..5f1140525aa324af74a1a355d9a236e360cd5064 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Aug 21 00:02:07 1997
- * Modified at:   Fri Dec 17 15:58:16 1999
+ * Modified at:   Sat Dec 25 16:42:42 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -85,6 +85,7 @@ int __init iriap_init(void)
 {
        struct ias_object *obj;
        struct iriap_cb *server;
+       __u8 oct_seq[6];
        __u16 hints;
 
        /* Allocate master array */
@@ -102,14 +103,19 @@ int __init iriap_init(void)
         *  Register some default services for IrLMP 
         */
        hints  = irlmp_service_to_hint(S_COMPUTER);
-       /*hints |= irlmp_service_to_hint(S_PNP);*/
        service_handle = irlmp_register_service(hints);
 
-       /* 
-        *  Register the Device object with LM-IAS
-        */
+       /* Register the Device object with LM-IAS */
        obj = irias_new_object("Device", IAS_DEVICE_ID);
        irias_add_string_attrib(obj, "DeviceName", "Linux");
+
+       oct_seq[0] = 0x01;  /* Version 1 */
+       oct_seq[1] = 0x00;  /* IAS support bits */
+       oct_seq[2] = 0x00;  /* LM-MUX support bits */
+#ifdef CONFIG_IRDA_ULTRA
+       oct_seq[2] |= 0x04; /* Connectionless Data support */
+#endif
+       irias_add_octseq_attrib(obj, "IrLMPSupport", oct_seq, 3);
        irias_insert_object(obj);
 
        /*  
@@ -580,7 +586,7 @@ void iriap_getvaluebyclass_response(struct iriap_cb *self, __u16 obj_id,
        tmp_be16 = cpu_to_be16(obj_id);
        memcpy(fp+n, &tmp_be16, 2); n += 2;
 
-       switch(value->type) {
+       switch (value->type) {
        case IAS_STRING:
                skb_put(skb, 3 + value->len);
                fp[n++] = value->type;
@@ -710,6 +716,22 @@ void iriap_send_ack(struct iriap_cb *self)
        irlmp_data_request(self->lsap, skb);
 }
 
+void iriap_connect_request(struct iriap_cb *self)
+{
+       int ret;
+
+       ASSERT(self != NULL, return;);
+       ASSERT(self->magic == IAS_MAGIC, return;);
+
+       ret = irlmp_connect_request(self->lsap, LSAP_IAS, 
+                                   self->saddr, self->daddr, 
+                                   NULL, NULL);
+       if (ret < 0) {
+               IRDA_DEBUG(0, __FUNCTION__ "(), connect failed!\n");
+               self->confirm(IAS_DISCONNECT, 0, NULL, self->priv);
+       }
+}
+
 /*
  * Function iriap_connect_confirm (handle, skb)
  *
@@ -734,9 +756,7 @@ static void iriap_connect_confirm(void *instance, void *sap,
        
        del_timer(&self->watchdog_timer);
 
-       iriap_do_client_event(self, IAP_LM_CONNECT_CONFIRM, NULL);
-
-       dev_kfree_skb(userdata);
+       iriap_do_client_event(self, IAP_LM_CONNECT_CONFIRM, userdata);
 }
 
 /*
@@ -855,7 +875,7 @@ static int iriap_data_indication(void *instance, void *sap,
                         * no to use self anymore after calling confirm 
                         */
                        if (self->confirm)
-                               self->confirm(IAS_CLASS_UNKNOWN, 0, NULL, 
+                               self->confirm(IAS_CLASS_UNKNOWN, 0, NULL,
                                              self->priv);
                        dev_kfree_skb(skb);
                        break;
index c03de649049978552caf57a09b92635eb4b97b0a..eb8463b73f610baff1186b05ea237a32d98bf2c4 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Aug 21 00:02:07 1997
- * Modified at:   Fri Dec 17 15:59:13 1999
+ * Modified at:   Sat Dec 25 21:09:47 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -168,8 +168,6 @@ void iriap_do_r_connect_event(struct iriap_cb *self, IRIAP_EVENT event,
 static void state_s_disconnect(struct iriap_cb *self, IRIAP_EVENT event, 
                               struct sk_buff *skb) 
 {
-       int ret;
-
        ASSERT(self != NULL, return;);
        ASSERT(self->magic == IAS_MAGIC, return;);
 
@@ -178,9 +176,7 @@ static void state_s_disconnect(struct iriap_cb *self, IRIAP_EVENT event,
                iriap_next_client_state(self, S_CONNECTING);
                ASSERT(self->skb == NULL, return;);
                self->skb = skb;
-               ret = irlmp_connect_request(self->lsap, LSAP_IAS, 
-                                           self->saddr, self->daddr, 
-                                           NULL, NULL);
+               iriap_connect_request(self);
                break;
        case IAP_LM_DISCONNECT_INDICATION:
                break;
@@ -207,7 +203,7 @@ static void state_s_connecting(struct iriap_cb *self, IRIAP_EVENT event,
                /*
                 *  Jump to S-Call FSM
                 */
-               iriap_do_call_event(self, IAP_CALL_REQUEST, NULL);
+               iriap_do_call_event(self, IAP_CALL_REQUEST, skb);
                /* iriap_call_request(self, 0,0,0); */
                iriap_next_client_state(self, S_CALL);
                break;
@@ -261,12 +257,14 @@ static void state_s_make_call(struct iriap_cb *self, IRIAP_EVENT event,
        case IAP_CALL_REQUEST:
                skb = self->skb;
                self->skb = NULL;
-
+               
                irlmp_data_request(self->lsap, skb);
                iriap_next_call_state(self, S_OUTSTANDING);
                break;
        default:
                IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %d\n", event);
+               if (skb)
+                       dev_kfree_skb(skb);
                break;
        }
 }
index 3a1aac69935247cdec28f0a7ea446f820f7117d7..a06b18582677dcdbc9f32cd23c77f1935df41202 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Sun Oct 31 19:41:55 1999
+ * Modified at:   Sun Dec 26 21:52:24 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -194,7 +194,7 @@ static int irlan_client_state_conn(struct irlan_cb *self, IRLAN_EVENT event,
        
        ASSERT(self != NULL, return -1;);
        
-       switch(event) {
+       switch (event) {
        case IRLAN_CONNECT_COMPLETE:
                /* Send getinfo cmd */
                irlan_get_provider_info(self);
index 30f6b5df20be43c0598d34ff6e0da061912e67ba..9d276e0a1296b751d5969e2f850c3f0ef9b13e6d 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Thu Dec 16 21:16:14 1999
+ * Modified at:   Sun Dec 26 21:53:10 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -705,7 +705,6 @@ void irlan_get_provider_info(struct irlan_cb *self)
        frame[0] = CMD_GET_PROVIDER_INFO;
        frame[1] = 0x00;                 /* Zero parameters */
        
-       /* irttp_data_request(self->client.tsap_ctrl, skb); */
        irlan_ctrl_data_request(self, skb);
 }
 
index 8b14c608279a8b3b819262f6a262b4c013ef08c5..c2037ad74e7ed6eb126972dddba410081ca1f86e 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Oct 15 08:37:58 1998
- * Modified at:   Thu Dec 16 21:21:53 1999
+ * Modified at:   Thu Nov  4 14:50:52 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
  *                slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
index e698f8201c7d3d3aea31e2ab1284bd3aff7a1f2e..1c2958c4be72c34aa7fd0decea8e19c0ba671b9b 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Stable
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Thu Dec 16 22:59:17 1999
+ * Modified at:   Tue Dec 14 09:26:44 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
index 1680b31a8d08c16763439c04f8f69f17fd902770..08501162e859dcb0cca0ec46cf211a418e8ffb66 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Aug 16 00:59:29 1997
- * Modified at:   Tue Dec 21 11:27:22 1999
+ * Modified at:   Sat Dec 25 21:07:57 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>,
@@ -446,7 +446,7 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event,
                 * Send response. This skb will not be sent out again, and
                 * will only be used to send out the same info as the cmd
                 */
-               irlap_send_test_frame(self, info->daddr, skb);
+               irlap_send_test_frame(self, CBROADCAST, info->daddr, skb);
                dev_kfree_skb(skb);
                break;
        case RECV_TEST_RSP:
@@ -1963,13 +1963,12 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event,
                irlap_start_wd_timer(self, self->wd_timeout);
 
                /* Send response (info will be copied) */
-               irlap_send_test_frame(self, info->daddr, skb);
+               irlap_send_test_frame(self, self->caddr, info->daddr, skb);
                dev_kfree_skb(skb);
                break;
        default:
                IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n", 
                           event, irlap_event[event]);
-
                if (skb)
                        dev_kfree_skb(skb);
 
index 53f9ccbd4d9cd68be4959e3c28923ba9fe44c909..830fe6ef766352fd606d78d47df31a2ba5ab851a 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Stable
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Aug 19 10:27:26 1997
- * Modified at:   Tue Dec 21 11:19:19 1999
+ * Modified at:   Wed Jan  5 08:59:04 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
+ *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
  *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
@@ -440,7 +440,7 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self,
                text = (char *) &discovery_info[2];
        }
        /* 
-        *  Terminate string, should be safe since this is where the 
+        *  Terminate info string, should be safe since this is where the 
         *  FCS bytes resides.
         */
        skb->data[skb->len] = '\0'; 
@@ -1205,7 +1205,7 @@ static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb,
  *    Send a test frame response
  *
  */
-void irlap_send_test_frame(struct irlap_cb *self, __u32 daddr, 
+void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr, 
                           struct sk_buff *cmd)
 {
        struct sk_buff *skb;
@@ -1216,22 +1216,20 @@ void irlap_send_test_frame(struct irlap_cb *self, __u32 daddr,
        if (!skb)
                return;
 
-       skb_put(skb, sizeof(struct test_frame));
+       /* Broadcast frames must include saddr and daddr fields */
+       if (caddr == CBROADCAST) {
+               frame = (struct test_frame *) 
+                       skb_put(skb, sizeof(struct test_frame));
 
-       frame = (struct test_frame *) skb->data;
-
-       /* Build header */
-       if (self->state == LAP_NDM)
-               frame->caddr = CBROADCAST; /* Send response */
-       else
-               frame->caddr = self->caddr;
+               /* Insert the swapped addresses */
+               frame->saddr = cpu_to_le32(self->saddr);
+               frame->daddr = cpu_to_le32(daddr);
+       } else
+               frame = (struct test_frame *) skb_put(skb, LAP_MAX_HEADER);
 
+       frame->caddr = caddr;
        frame->control = TEST_RSP;
 
-       /* Insert the swapped addresses */
-       frame->saddr = cpu_to_le32(self->saddr);
-       frame->daddr = cpu_to_le32(daddr);
-
        /* Copy info */
        info = skb_put(skb, cmd->len);
        memcpy(info, cmd->data, cmd->len);
@@ -1254,22 +1252,27 @@ static void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb,
 
        IRDA_DEBUG(2, __FUNCTION__ "()\n");
        
-       if (skb->len < sizeof(struct test_frame)) {
-               IRDA_DEBUG(0, __FUNCTION__ "() test frame to short!\n");
-               dev_kfree_skb(skb);
-               return;
-       }
-
        frame = (struct test_frame *) skb->data;
+               
+       /* Broadcast frames must carry saddr and daddr fields */
+       if (info->caddr == CBROADCAST) {
+               if (skb->len < sizeof(struct test_frame)) {
+                       IRDA_DEBUG(0, __FUNCTION__ 
+                                  "() test frame to short!\n");
+                       dev_kfree_skb(skb);
+                       return;
+               }
+               
+               /* Read and swap addresses */
+               info->daddr = le32_to_cpu(frame->saddr);
+               info->saddr = le32_to_cpu(frame->daddr);
 
-       /* Read and swap addresses */
-       info->daddr = le32_to_cpu(frame->saddr);
-       info->saddr = le32_to_cpu(frame->daddr);
-
-       /* Make sure frame is addressed to us */
-       if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
-               dev_kfree_skb(skb);
-               return;
+               /* Make sure frame is addressed to us */
+               if ((info->saddr != self->saddr) && 
+                   (info->saddr != BROADCAST)) {
+                       dev_kfree_skb(skb);
+                       return;
+               }
        }
 
        if (command)
@@ -1378,7 +1381,7 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
        case DM_RSP:
                irlap_do_event(self, RECV_DM_RSP, skb, &info);
                break;
-       case DISC_CMD: /* And RD_RSP */
+       case DISC_CMD: /* And RD_RSP since they have the same value */
                irlap_recv_disc_frame(self, skb, &info, command);
                break;
        case TEST_CMD:
index fdd2c92b58860d1d03b3b2cb38511e0454acb153..5be0298a9fa830f7e68ca44f6c7035f2b9e32754 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Stable.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 17 20:54:32 1997
- * Modified at:   Thu Dec 16 22:59:40 1999
+ * Modified at:   Wed Jan  5 11:26:03 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
+ *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
  *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
@@ -69,20 +69,19 @@ int irlmp_proc_read(char *buf, char **start, off_t offst, int len);
 /*
  * Function irlmp_init (void)
  *
- *    Create (allocate) the main IrLMP structure and the pointer array
- *    which will contain pointers to each instance of a LSAP.
+ *    Create (allocate) the main IrLMP structure
+ *
  */
 int __init irlmp_init(void)
 {
        /* Initialize the irlmp structure. */
-       if ( irlmp == NULL) {
-               irlmp = kmalloc( sizeof(struct irlmp_cb), GFP_KERNEL);
-               if ( irlmp == NULL)
-                       return -ENOMEM;
-       }
-       memset( irlmp, 0, sizeof(struct irlmp_cb));
+       irlmp = kmalloc( sizeof(struct irlmp_cb), GFP_KERNEL);
+       if (irlmp == NULL)
+               return -ENOMEM;
+       memset(irlmp, 0, sizeof(struct irlmp_cb));
        
        irlmp->magic = LMP_MAGIC;
+       spin_lock_init(&irlmp->lock);
 
        irlmp->clients = hashbin_new(HB_GLOBAL);
        irlmp->services = hashbin_new(HB_GLOBAL);
@@ -377,9 +376,18 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel,
         * device with the given daddr 
         */
        if (!saddr) {
-               discovery = hashbin_find(irlmp->cachelog, daddr, NULL);
-               if (discovery)
+               if (daddr != DEV_ADDR_ANY)
+                       discovery = hashbin_find(irlmp->cachelog, daddr, NULL);
+               else {
+                       IRDA_DEBUG(2, __FUNCTION__ "(), no daddr\n");
+                       discovery = (discovery_t *) 
+                               hashbin_get_first(irlmp->cachelog);
+               }
+
+               if (discovery) {
                        saddr = discovery->saddr;
+                       daddr = discovery->daddr;
+               }
        }
        lap = hashbin_find(irlmp->links, saddr, NULL);  
        if (lap == NULL) {
index ace20d70e061ea53447df1466cf1970cc8c9aa8a..a9ef0c9cf511dd953b03756991cb2ea5aed1e5af 100644 (file)
@@ -23,7 +23,6 @@
  *
  ********************************************************************/
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 
 #include <net/irda/irda.h>
index 0928e2ff9deb4bf81f7ba737777b1a67e0786aa5..c26433f8018a84afbd47ec9a7de729ba99e0a521 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Dec 15 13:55:39 1997
- * Modified at:   Tue Dec 21 21:39:31 1999
+ * Modified at:   Wed Jan  5 15:12:41 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997, 1999 Dag Brattli, All Rights Reserved.
+ *     Copyright (c) 1997, 1999-2000 Dag Brattli, All Rights Reserved.
  *      
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -332,8 +332,7 @@ void irda_execute_as_process( void *self, TODO_CALLBACK callback, __u32 param)
        struct irmanager_event event;
 
        /* Make sure irmanager is running */
-       if ( !irda.in_use) {
-               printk( KERN_ERR "irmanager is not running!\n");
+       if (!irda.in_use) {
                return;
        }
 
@@ -372,7 +371,6 @@ void irmanager_notify( struct irmanager_event *event)
        
        /* Make sure irmanager is running */
        if (!irda.in_use) {
-               printk( KERN_ERR "irmanager is not running!\n");
                return;
        }
 
index c775863fb23283983cd23d953555bebf047dc191..46c2ae85e85a5bb63d69f694d9da2879a885ae62 100644 (file)
@@ -6,10 +6,10 @@
  * Status:        Stable
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:31 1997
- * Modified at:   Thu Dec 16 23:00:03 1999
+ * Modified at:   Wed Jan  5 11:31:27 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
+ *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
  *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
@@ -144,6 +144,7 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
                return NULL;
        }
        memset(self, 0, sizeof(struct tsap_cb));
+       spin_lock_init(&self->lock);
 
        init_timer(&self->todo_timer);