]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.2.17pre14 2.2.17pre14
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:21:53 +0000 (15:21 -0500)
committerAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:21:53 +0000 (15:21 -0500)
o Hopefully fix esd and other i810 audio hangs (Alan Cox)
o Further fixes for the Alpha tree (Jay Estabrook)
o Further bond cleanup/init fix (Daniel Roesen)
o Fix initio redefine warnings (Arjan van de Ven)
o Fix warnings due to printk types (Arjan van de Ven)
o Fix warnings due to missing prototypes (Arjan van de Ven)
o Fix i2o warnings, code cleanup (Arjan van de Ven, Alan Cox)
o Fix warnings from missed includes (Arjan van de Ven)
o Fix ip2serial config ioctl bug (Arjan van de Ven)
o Update ipmasqadm tool locations (Rob Hudson)
o Fix yamaha build problems (Alan Cox)
o Change varesearch -> valinux in the kernel (H J Lu)
o Add /lib/modules/foo/build link as per l/k (Ted Ts'o)
o Bring the SX rio and generic_serial in line (Patrick)
with 2.4.test
o 3ware controller fixes/updates (Adam Radford
 Joel Jacobson)
o Fix appletalk kmalloc warnings (Benjamin Herrenschmidt)
o Fix imm/ppa handling with PCI ports (Gunther Mayer)
o Fix 16bit handling bug in NCPfs (Petr Vandrovec)
o Fix isofs offset by one error (Mikael Pettersson)
o Add byte counters to ewrk3 (Nathan Hand)
o SMBFS clean ups, fix OS/2 rename (Urban Widmark)
o HDLC driver bug backout (Krzysztof Halasa)
o Powermac pmu and gmac fixes (Paul Mackerras)
o Fix i2o block scan for multi drives (Boji Kannanthanam)
o Fix frag handling oddity on ipchains (Jan Echternach)
o Fix emu10k as non module (Mikael Pettersson)
o Scsi command raw requires RAWIO cap (Oliver Xymoron)
o IDE command raw or hwif add requires RAWIO (various)
o Fix isofs 2048 byte alignment bug (Go Taniguchi)
o Fix most remaining UMSDOS flaws (Matija Nalis)

90 files changed:
CREDITS
Documentation/Changes
Documentation/i386/boot.txt
MAINTAINERS
Makefile
arch/alpha/config.in
arch/alpha/kernel/setup.c
arch/alpha/kernel/sys_cabriolet.c
arch/alpha/kernel/sys_eb64p.c
drivers/block/ide-proc.c
drivers/block/ide.c
drivers/block/raid0.c
drivers/char/generic_serial.c
drivers/char/i2c.c
drivers/char/ip2main.c
drivers/char/misc.c
drivers/char/rio/func.h
drivers/char/rio/host.h
drivers/char/rio/linux_compat.h
drivers/char/rio/rio_linux.c
drivers/char/rio/rio_linux.h
drivers/char/rio/rioboot.c
drivers/char/rio/riocmd.c
drivers/char/rio/rioctrl.c
drivers/char/rio/riodrvr.h
drivers/char/rio/rioinit.c
drivers/char/rio/riointr.c
drivers/char/rio/rioparam.c
drivers/char/rio/rioroute.c
drivers/char/rio/riotable.c
drivers/char/rio/riotty.c
drivers/char/rio/unixrup.h
drivers/char/sx.c
drivers/char/tty_io.c
drivers/i2o/i2o_block.c
drivers/i2o/i2o_scsi.h
drivers/isdn/isdn_cards.c
drivers/isdn/isdn_ppp.h
drivers/macintosh/via-pmu.c
drivers/net/Space.c
drivers/net/bonding.c
drivers/net/c101.c
drivers/net/ewrk3.c
drivers/net/gmac.c
drivers/net/gmac.h
drivers/net/hd6457x.c
drivers/net/hdlc.c
drivers/net/n2.c
drivers/net/slhc.c
drivers/pnp/parport_probe.c
drivers/scsi/3w-xxxx.c
drivers/scsi/3w-xxxx.h
drivers/scsi/eata.c
drivers/scsi/imm.c
drivers/scsi/imm.h
drivers/scsi/ini9100u.h
drivers/scsi/inia100.h
drivers/scsi/ppa.c
drivers/scsi/ppa.h
drivers/scsi/scsi_ioctl.c
drivers/scsi/tmscsim.c
drivers/sound/Makefile
drivers/sound/emu10k1/main.c
drivers/sound/i810_audio.c
drivers/sound/maestro.c
drivers/sound/sound_core.c
fs/isofs/dir.c
fs/isofs/inode.c
fs/ncpfs/ncplib_kernel.h
fs/smbfs/ChangeLog [new file with mode: 0644]
fs/smbfs/cache.c
fs/smbfs/dir.c
fs/smbfs/file.c
fs/smbfs/inode.c
fs/smbfs/ioctl.c
fs/smbfs/proc.c
fs/smbfs/smb_debug.h
fs/smbfs/sock.c
fs/umsdos/README-WIP.txt
fs/umsdos/emd.c
fs/umsdos/inode.c
fs/umsdos/ioctl.c
fs/umsdos/namei.c
include/net/slhc_vj.h
init/main.c
net/appletalk/ddp.c
net/ipv4/ip_fw.c
net/irda/irda_device.c
net/irda/irmod.c
net/irda/irttp.c

diff --git a/CREDITS b/CREDITS
index 44b8e4fe5be441fff6eccb420b7d57983721c7d9..0bc7427478f25fcd30eb548c550469ffc992ad1a 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -371,7 +371,7 @@ S: Stanford, California 94305
 S: USA
 
 N: Juan Jose Ciarlante
-W: http://juanjox.linuxhq.com/
+W: http://juanjox.kernelnotes.org/
 E: jjciarla@raiz.uncu.edu.ar
 E: jjo@mendoza.gov.ar
 D: Network driver alias support
index 405b900ac5b853d5848b4eeb57a1f5f511f93196..da4e701e704fcc7f73eeddcc50ff6152f0d00687 100644 (file)
@@ -268,7 +268,7 @@ http://netfilter.filewatcher.org/ipchains/ , and use that instead of
 ipfwadm.
 
    To use masq forwarding you will need to obtain "ipmasqadm,"
-available from http://juanjox.linuxhq.com/ .
+available from http://juanjox.kernelnotes.org/ .
 
    DHCP clients for 2.0 do not work with the new networking code in the
 2.2 kernel.  You will need to upgrade your dhcpcd / dhcpclient.
@@ -523,14 +523,14 @@ Binutils
 ========
 
 The 2.9.1.0.25 release:
-ftp://ftp.varesearch.com/pub/support/hjl/binutils/2.9.1/binutils-2.9.1.0.25.tar.gz
+ftp://ftp.valinux.com/pub/support/hjl/binutils/2.9.1/binutils-2.9.1.0.25.tar.gz
 Installation notes:
-ftp://ftp.varesearch.com/pub/support/hjl/binutils/2.9.1/release.binutils-2.9.1.0.25
+ftp://ftp.valinux.com/pub/support/hjl/binutils/2.9.1/release.binutils-2.9.1.0.25
 
 The 2.9.5.0.16 release:
-ftp://ftp.varesearch.com/pub/support/hjl/binutils/binutils-2.9.5.0.16.tar.bz2
+ftp://ftp.valinux.com/pub/support/hjl/binutils/binutils-2.9.5.0.16.tar.bz2
 Installation notes:
-ftp://ftp.varesearch.com/pub/support/hjl/binutils/release.binutils-2.9.5.0.16
+ftp://ftp.valinux.com/pub/support/hjl/binutils/release.binutils-2.9.5.0.16
 
 Bin86
 =====
@@ -543,11 +543,11 @@ Gnu C
 =====
 
 The egcs-1.1.2 release:
-ftp://ftp.varesearch.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-glibc.x86.tar.bz2
-ftp://ftp.varesearch.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-libc5.x86.tar.bz2
-ftp://ftp.varesearch.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-alpha.x86.tar.bz2
+ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-glibc.x86.tar.bz2
+ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-libc5.x86.tar.bz2
+ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-alpha.x86.tar.bz2
 Installation notes:
-ftp://ftp.varesearch.com/pub/support/hjl/gcc/egcs-1.1.2/release.egcs-1.1.2
+ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/release.egcs-1.1.2
 
 Gnu C 2.7.2.3 source:
 ftp://ftp.gnu.org/gnu/gcc/gcc-2.7.2.3.tar.gz
@@ -726,7 +726,7 @@ IP Masq Adm
 ===========
 
 The 0.4.2 release:
-http://juanjox.linuxhq.com/ipmasqadm-0.4.2.tar.gz
+http://juanjox.kernelnotes.org/ipmasqadm-0.4.2.tar.gz
 
 DHCP clients
 ============
index 5b600161d2c37d741b249d011aba3481b9a734c2..1622e4af377cbdbdad63c303c816e3388f6dc53e 100644 (file)
@@ -16,15 +16,20 @@ Currently, four versions of the Linux/i386 boot protocol exist.
 Old kernels:   zImage/Image support only.  Some very early kernels
                may not even support a command line.
 
-Protocol 2.00: Added bzImage and initrd support, as well as a
-               formalized way to communicate between the boot loader
-               and the kernel.
+Protocol 2.00: (Kernel 1.3.73) Added bzImage and initrd support, as
+               well as a formalized way to communicate between the
+               boot loader and the kernel.  setup.S made relocatable,
+               although the traditional setup area still assumed
+               writable.
 
-Protocol 2.01: Added a heap overrun warning.
+Protocol 2.01: (Kernel 1.3.76) Added a heap overrun warning.
 
-Protocol 2.02: New command line protocol.  Lower the
-               conventional-memory ceiling.  zImage deprecated but
-               still supported.
+Protocol 2.02: (Kernel 2.4.0-test3-pre3) New command line protocol.
+               Lower the conventional memory ceiling.  No overwrite
+               of the traditional setup area, thus making booting
+               safe for systems which use the EBDA from SMM or 32-bit
+               BIOS entry points.  zImage deprecated but still
+               supported.
 
 
 **** MEMORY LAYOUT
@@ -136,7 +141,7 @@ setting fields in the header, you must make sure only to set fields
 supported by the protocol version in use.
 
 Most boot loaders will simply load the kernel at its target address
-directly.  Such a boot loader do not need to worry about filling in
+directly.  Such boot loaders do not need to worry about filling in
 most of the fields in the header.  The following fields should be
 filled out, however:
 
@@ -257,6 +262,8 @@ Such a boot loader should enter the following fields in the header:
                        memcpy(0x90000, base_ptr, (setup_sects+1)*512);
                        /* Copy the command line */
                        memcpy(0x99000, base_ptr+0x9000, 256);
+
+                       base_ptr = 0x90000;              /* Relocated */
                }
 
                /* It is recommended to clear memory up to the 32K mark */
@@ -338,19 +345,25 @@ real-mode kernel code (0x9000 if the code is loaded at 0x90000), and
 sp should be set up properly, normally pointing to the top of the
 heap.  In our example from above, we would do:
 
+       /* Note: in the case of the "old" kernel protocol, base_ptr must
+          be == 0x90000 at this point; see the previous sample code */
+
        seg = base_ptr >> 4;
 
        cli();  /* Enter with interrupts disabled! */
 
+       /* Set up the real-mode kernel stack */
        _SS = seg;
        _SP = 0x9000;   /* Load SP right after loading SS! */
+
        _DS = _ES = _FS = _GS = seg;
        jmp_far(seg+0x20, 0);   /* Run the kernel */
 
 If your boot sector accesses a floppy drive, it is recommended to
 switch off the floppy motor before running the kernel, since the
 kernel boot leaves interrupts off and thus the motor will not be
-switched off.
+switched off, especially if the loaded kernel has the floppy driver as
+a demand-loaded module!
 
 
 **** ADVANCED BOOT TIME HOOKS
index cd389ad0f4656ba0113d154f2cc6d936abf5ace2..487c000447876007876a8b8c71a96cefec9f8a0b 100644 (file)
@@ -811,8 +811,8 @@ M:  mingo@redhat.com
 S:     Maintained
 
 SMB FILESYSTEM
-P:     Andrew Tridgell
-M:     tridge@samba.org
+P:     Urban Widmark
+M:     urban@svenskatest.se
 W:     http://samba.org/
 L:     samba@samba.org
 S:     Maintained
@@ -911,7 +911,7 @@ S:  Maintained
 
 UMSDOS FILESYSTEM
 P:     Matija Nalis
-M:     mnalis@jagor.srce.hr
+M:     mnalis-umsdos@voyager.hr
 L:     linux-kernel@vger.rutgers.edu
 S:     Maintained
 
index a5da9d79ada965a4f4b0a65c196cbb445b1ab92f..7bc418919b8faa49710df678b059fa8d3515560b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 17
-EXTRAVERSION = pre13
+EXTRAVERSION = pre14
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
@@ -22,7 +22,7 @@ CROSS_COMPILE         =
 
 AS     =$(CROSS_COMPILE)as
 LD     =$(CROSS_COMPILE)ld
-CC     =$(CROSS_COMPILE)gcc -D__KERNEL__ -I$(HPATH)
+CC     =$(CROSS_COMPILE)cc -D__KERNEL__ -I$(HPATH)
 CPP    =$(CC) -E
 AR     =$(CROSS_COMPILE)ar
 NM     =$(CROSS_COMPILE)nm
@@ -325,13 +325,15 @@ $(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h
 modules_install:
        @( \
        MODLIB=$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE); \
+       mkdir -p $$MODLIB; \
+       rm -f $$MODLIB/build; \
+       ln -s `pwd` $$MODLIB/build; \
        cd modules; \
        MODULES=""; \
        inst_mod() { These="`cat $$1`"; MODULES="$$MODULES $$These"; \
                mkdir -p $$MODLIB/$$2; cp $$These $$MODLIB/$$2; \
                echo Installing modules under $$MODLIB/$$2; \
        }; \
-       mkdir -p $$MODLIB; \
        \
        if [ -f BLOCK_MODULES ]; then inst_mod BLOCK_MODULES block; fi; \
        if [ -f NET_MODULES   ]; then inst_mod NET_MODULES   net;   fi; \
index d26f0bff07c7f9c87f2d3d57bf21c7c3e21ce3ba..15c93d422658a504533d79827d5a1a328354e42e 100644 (file)
@@ -80,6 +80,10 @@ then
        define_bool CONFIG_ALPHA_EV4 y
        define_bool CONFIG_ALPHA_APECS y
 fi
+if [ "$CONFIG_ALPHA_CABRIOLET" = "y" ]
+then
+       define_bool CONFIG_ALPHA_EB64P y
+fi
 if [ "$CONFIG_ALPHA_EB164" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
        -o "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_XLT" = "y" \
        -o "$CONFIG_ALPHA_TAKARA" = "y" ]
@@ -161,7 +165,7 @@ if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \
         -o "$CONFIG_ALPHA_TAKARA" = "y" -o "$CONFIG_ALPHA_EB164" = "y" \
         -o "$CONFIG_ALPHA_ALCOR" = "y"  -o "$CONFIG_ALPHA_MIATA" = "y" \
         -o "$CONFIG_ALPHA_LX164" = "y"  -o "$CONFIG_ALPHA_SX164" = "y" \
-       -o "$CONFIG_ALPHA_NAUTILUS" = "y" ]
+        -o "$CONFIG_ALPHA_NAUTILUS" = "y" ]
 then
   bool 'Use SRM as bootloader' CONFIG_ALPHA_SRM
 #  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
index cd61bde288ac9770e2b451020700ab294bb25e48..4aa45c911cf74d54cb5d1fd90508bcd2cb28e2e0 100644 (file)
@@ -517,7 +517,7 @@ get_sysvec(long type, long variation, long cpu)
        {
                &eb64p_mv,
                &cabriolet_mv,
-               NULL            /* AlphaPCI64 */
+               &cabriolet_mv           /* AlphaPCI64 */
        };
 
        static struct alpha_machine_vector *eb66_vecs[] __initlocaldata =
index 37f29e1472d414b2a51f3e23250eff5f79bac5db..8c20579fe9a7d0866e885e645520c1c5fcf09a8f 100644 (file)
@@ -286,8 +286,10 @@ struct alpha_machine_vector cabriolet_mv __initmv = {
        pci_fixup:              cabriolet_pci_fixup,
        kill_arch:              generic_kill_arch,
 };
+#ifndef CONFIG_ALPHA_EB64P
 ALIAS_MV(cabriolet)
 #endif
+#endif
 
 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB164)
 struct alpha_machine_vector eb164_mv __initmv = {
index 683baa02e3e576066b52f9a48345fcaafa287285..c80a778a0b8051542d4e44f78c9ce2238d409adb 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/pgtable.h>
 #include <asm/core_apecs.h>
 #include <asm/core_lca.h>
+#include <asm/hwrpb.h>
 
 #include "proto.h"
 #include "irq.h"
@@ -74,7 +75,7 @@ eb64p_device_interrupt(unsigned long vector, struct pt_regs *regs)
 static void __init
 eb64p_init_irq(void)
 {
-#ifdef CONFIG_ALPHA_GENERIC
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_CABRIOLET)
        /*
         * CABRIO SRM may not set variation correctly, so here we test
         * the high word of the interrupt summary register for the RAZ
@@ -82,9 +83,12 @@ eb64p_init_irq(void)
         */
        if (inw(0x806) != 0xffff) {
                extern struct alpha_machine_vector cabriolet_mv;
-#if 1
-               printk("eb64p_init_irq: resetting for CABRIO\n");
-#endif
+
+               printk("Detected Cabriolet: correcting HWRPB.\n");
+
+               hwrpb->sys_variation |= 2L << 10;
+               hwrpb_update_checksum(hwrpb);
+
                alpha_mv = cabriolet_mv;
                alpha_mv.init_irq();
                return;
index 3f0ca608f6cae1fb9204f2db67b0457d365e498a..a0f664d9ecabcf9e0f3f7ca42d71671c684bc59e 100644 (file)
@@ -111,7 +111,7 @@ static int proc_ide_write_config
        unsigned long   startn = 0, n, flags;
        const char      *start = NULL, *msg = NULL;
 
-       if (!capable(CAP_SYS_ADMIN))
+       if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
                return -EACCES;
        /*
         * Skip over leading whitespace
index fd77a149d0112e3b6c78da190207e0c2579d2fdb..f47b7a59370cb01552279c2f689ce68526ebce4b 100644 (file)
@@ -2254,7 +2254,7 @@ static int ide_ioctl (struct inode *inode, struct file *file,
                {
                        byte args[4], *argbuf = args;
                        int argsize = 4;
-                       if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+                       if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES;
                        if (NULL == (void *) arg)
                                return ide_do_drive_cmd(drive, &rq, ide_wait);
                        if (copy_from_user(args, (void *)arg, 4))
@@ -2277,7 +2277,7 @@ static int ide_ioctl (struct inode *inode, struct file *file,
                case HDIO_SCAN_HWIF:
                {
                        int args[3];
-                       if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+                       if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES;
                        if (copy_from_user(args, (void *)arg, 3 * sizeof(int)))
                                return -EFAULT;
                        if (ide_register(args[0], args[1], args[2]) == -1)
index 37b2035cdc9c78448d42b7e62086339ad85e4d35..17c13342b7c1c31f7a7a69d7308262bc35e8e893 100644 (file)
@@ -184,7 +184,7 @@ static int raid0_map (struct md_dev *mddev, kdev_t *rdev,
 
   if (hash - data->hash_table > data->nr_zones) 
   { 
-         printk(KERN_DEBUG "raid0_map: invalid block %ul\n", block);
+         printk(KERN_DEBUG "raid0_map: invalid block %li\n", block);
          return -1;
   }
 
index a10a0fce5e8be8e4d3f2efefb79d0aaee98568a0..6c19753714bad50a843cf5be7316432f80bf1f44 100644 (file)
  *  Version 0.1 -- December, 1998. Initial version.
  *  Version 0.2 -- March, 1999.    Some more routines. Bugfixes. Etc.
  *  Version 0.5 -- August, 1999.   Some more fixes. Reformat for Linus.
- */
+ *
+ *  BitWizard is actively maintaining this file. We sometimes find
+ *  that someone submitted changes to this file. We really appreciate
+ *  your help, but please submit changes through us. We're doing our
+ *  best to be responsive.  -- REW
+ * */
 
 #include <linux/tty.h>
 #include <linux/serial.h>
 #include <linux/mm.h>
 #include <asm/semaphore.h>
+#include <asm/uaccess.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/compatmac.h>
@@ -40,8 +46,6 @@ int gs_debug = 0;
 #define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter " __FUNCTION__ "\n")
 #define func_exit()  gs_dprintk (GS_DEBUG_FLOW, "gs: exit  " __FUNCTION__ "\n")
 
-
-
 #if NEW_WRITE_LOCKING
 #define DECL      /* Nothing */
 #define LOCKIT    down (& port->port_write_sem);
@@ -52,6 +56,9 @@ int gs_debug = 0;
 #define RELEASEIT restore_flags (flags)
 #endif
 
+#ifdef MODULE
+MODULE_PARM(gs_debug, "i");
+#endif
 
 #ifdef DEBUG
 static void my_hd (unsigned char *addr, int len)
@@ -77,10 +84,18 @@ static void my_hd (unsigned char *addr, int len)
 
 void gs_put_char(struct tty_struct * tty, unsigned char ch)
 {
-       struct gs_port *port = tty->driver_data;
+       struct gs_port *port;
        DECL
 
-       /*  func_enter (); */
+       func_enter (); 
+
+       if (!tty) return;
+
+       port = tty->driver_data;
+
+       if (!port) return;
+
+       if (! (port->flags & ASYNC_INITIALIZED)) return;
 
        /* Take a lock on the serial tranmit buffer! */
        LOCKIT;
@@ -96,7 +111,7 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch)
        port->xmit_cnt++;  /* Characters in buffer */
 
        RELEASEIT;
-       /* func_exit ();*/
+       func_exit ();
 }
 
 
@@ -112,11 +127,17 @@ void gs_put_char(struct tty_struct * tty, unsigned char ch)
 int gs_write(struct tty_struct * tty, int from_user, 
                     const unsigned char *buf, int count)
 {
-       struct gs_port *port = tty->driver_data;
+       struct gs_port *port;
        int c, total = 0;
        int t;
 
-       /* func_enter (); */
+       func_enter ();
+
+       if (!tty) return 0;
+
+       port = tty->driver;
+
+       if (!port) return 0;
 
        if (! (port->flags & ASYNC_INITIALIZED))
                return 0;
@@ -167,7 +188,7 @@ int gs_write(struct tty_struct * tty, int from_user,
                port->flags |= GS_TX_INTEN;
                port->rd->enable_tx_interrupts (port);
        }
-       /* func_exit (); */
+       func_exit ();
        return total;
 }
 #else
@@ -210,12 +231,9 @@ int gs_write(struct tty_struct * tty, int from_user,
        if (!port || !port->xmit_buf || !tmp_buf)
                return -EIO;
 
-       /* printk ("from_user = %d.\n", from_user); */
        save_flags(flags);
        if (from_user) {
-               /* printk ("Going into the semaphore\n"); */
                down(&tmp_buf_sem);
-               /* printk ("got out of the semaphore\n"); */
                while (1) {
                        c = count;
 
@@ -309,11 +327,11 @@ int gs_write_room(struct tty_struct * tty)
        struct gs_port *port = tty->driver_data;
        int ret;
 
-       /* func_enter (); */
+       func_enter ();
        ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
        if (ret < 0)
                ret = 0;
-       /* func_exit (); */
+       func_exit ();
        return ret;
 }
 
@@ -330,7 +348,7 @@ int gs_chars_in_buffer(struct tty_struct *tty)
 
 int gs_real_chars_in_buffer(struct tty_struct *tty)
 {
-       struct gs_port *port = tty->driver_data;
+       struct gs_port *port;
        func_enter ();
 
        if (!tty) return 0;
@@ -361,22 +379,17 @@ static int gs_wait_tx_flushed (void * ptr, int timeout)
 
        if (!port || port->xmit_cnt < 0 || !port->xmit_buf) {
                gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n");
-       func_exit();
+               func_exit();
                return -EINVAL;  /* This is an error which we don't know how to handle. */
        }
-       gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 1\n");
 
        rcib = gs_real_chars_in_buffer(port->tty);
 
-       gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 2\n");
-
        if(rcib <= 0) {
                gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n");
                func_exit();
                return rv;
        }
-       gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 3\n");
-
        /* stop trying: now + twice the time it would normally take +  seconds */
        end_jiffies  = jiffies; 
        if (timeout !=  MAX_SCHEDULE_TIMEOUT)
@@ -424,17 +437,23 @@ static int gs_wait_tx_flushed (void * ptr, int timeout)
 
 void gs_flush_buffer(struct tty_struct *tty)
 {
-       struct gs_port *port = tty->driver_data;
+       struct gs_port *port;
        unsigned long flags;
 
        func_enter ();
+
+       if (!tty) return;
+
+       port = tty->driver_data;
+
+       if (!port) return;
+
        /* XXX Would the write semaphore do? */
        save_flags(flags); cli();
        port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
        restore_flags(flags);
 
        wake_up_interruptible(&tty->write_wait);
-       wake_up_interruptible(&tty->poll_wait);
        if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
            tty->ldisc.write_wakeup)
                (tty->ldisc.write_wakeup)(tty);
@@ -444,9 +463,16 @@ void gs_flush_buffer(struct tty_struct *tty)
 
 void gs_flush_chars(struct tty_struct * tty)
 {
-       struct gs_port *port = tty->driver_data;
+       struct gs_port *port;
 
        func_enter ();
+
+       if (!tty) return;
+
+       port = tty->driver_data;
+
+       if (!port) return;
+
        if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
            !port->xmit_buf) {
                func_exit ();
@@ -462,9 +488,16 @@ void gs_flush_chars(struct tty_struct * tty)
 
 void gs_stop(struct tty_struct * tty)
 {
-       struct gs_port *port = tty->driver_data;
+       struct gs_port *port;
 
        func_enter ();
+
+       if (!tty) return;
+
+       port = tty->driver_data;
+
+       if (!port) return;
+
        if (port->xmit_cnt && 
            port->xmit_buf && 
            (port->flags & GS_TX_INTEN) ) {
@@ -477,7 +510,13 @@ void gs_stop(struct tty_struct * tty)
 
 void gs_start(struct tty_struct * tty)
 {
-       struct gs_port *port = tty->driver_data;
+       struct gs_port *port;
+
+       if (!tty) return;
+
+       port = tty->driver_data;
+
+       if (!port) return;
 
        if (port->xmit_cnt && 
            port->xmit_buf && 
@@ -492,7 +531,11 @@ void gs_start(struct tty_struct * tty)
 void gs_shutdown_port (struct gs_port *port)
 {
        long flags;
+
        func_enter();
+       
+       if (!port) return;
+       
        if (!(port->flags & ASYNC_INITIALIZED))
                return;
 
@@ -517,10 +560,13 @@ void gs_shutdown_port (struct gs_port *port)
 
 void gs_hangup(struct tty_struct *tty)
 {
-       struct gs_port   *port = tty->driver_data;
+       struct gs_port   *port;
 
        func_enter ();
 
+       if (!tty) return;
+
+       port = tty->driver_data;
        tty = port->tty;
        if (!tty) return;
 
@@ -541,15 +587,19 @@ void gs_do_softint(void *private_)
        struct gs_port *port = private_;
        struct tty_struct *tty;
 
+       func_enter ();
+
+       if (!port) return;
+
        tty = port->tty;
-       if(!tty) return;
+
+       if (!tty) return;
 
        if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
                if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
                    tty->ldisc.write_wakeup)
                        (tty->ldisc.write_wakeup)(tty);
                wake_up_interruptible(&tty->write_wait);
-               wake_up_interruptible(&tty->poll_wait);
        }
        func_exit ();
 }
@@ -565,8 +615,13 @@ int block_til_ready(void *port_, struct file * filp)
        struct tty_struct *tty;
 
        func_enter ();
+
+       if (!port) return 0;
+
        tty = port->tty;
 
+       if (!tty) return 0;
+
        gs_dprintk (GS_DEBUG_BTR, "Entering block_till_ready.\n"); 
        /*
         * If the device is in the middle of being closed, then block
@@ -625,8 +680,6 @@ int block_til_ready(void *port_, struct file * filp)
                        do_clocal = 1;
        }
 
-       gs_dprintk (GS_DEBUG_BTR, "after clocal check.\n"); 
-
        /*
         * Block waiting for the carrier detect and the line to become
         * free (i.e., not in use by the callout).  While we are in
@@ -635,10 +688,10 @@ int block_til_ready(void *port_, struct file * filp)
         * exit, either normal or abnormal.
         */
        retval = 0;
+
        add_wait_queue(&port->open_wait, &wait);
 
        gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); 
-
        cli();
        if (!tty_hung_up_p(filp))
                port->count--;
@@ -690,15 +743,12 @@ void gs_close(struct tty_struct * tty, struct file * filp)
        struct gs_port *port;
 
        func_enter ();
-       port = (struct gs_port *) tty->driver_data;
 
-       gs_dprintk (GS_DEBUG_CLOSE, "tty=%p, port=%p port->tty=%p\n",
-                   tty, port, port->tty);
+       if (!tty) return;
 
-       if(! port) {
-               func_exit();
-               return;
-       }
+       port = (struct gs_port *) tty->driver_data;
+
+       if (!port) return;
 
        if (!port->tty) {
                /* This seems to happen when this is called from vhangup. */
@@ -706,7 +756,6 @@ void gs_close(struct tty_struct * tty, struct file * filp)
                port->tty = tty;
        }
 
-
        save_flags(flags); cli();
 
        if (tty_hung_up_p(filp)) {
@@ -800,14 +849,19 @@ static unsigned int     gs_baudrates[] = {
 void gs_set_termios (struct tty_struct * tty, 
                      struct termios * old_termios)
 {
-       struct gs_port *port = tty->driver_data;
+       struct gs_port *port;
        int baudrate, tmp, rv;
        struct termios *tiosp;
 
        func_enter();
 
-       tiosp = tty->termios;
+       if (!tty) return;
+
+       port = tty->driver_data;
 
+       if (!port) return;
+
+       tiosp = tty->termios;
 
        if (gs_debug & GS_DEBUG_TERMIOS) {
                gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp);
index 6da6bd6b2f1f245e67a0eb7932ed298df233a3c3..1e6ac0bc0ec0d8664f53f77923ade50cb9799faa 100644 (file)
@@ -38,8 +38,8 @@ static int bus_count = 0, driver_count = 0;
 
 #ifdef CONFIG_VIDEO_BT848
 extern int i2c_tuner_init(void);
-extern int msp3400c_init(void);
 #endif
+extern int msp3400c_init(void);
 #ifdef CONFIG_VIDEO_BUZ
 extern int saa7111_init(void);
 extern int saa7185_init(void);
index 3fd9b748f64618982a6d19c86d1a362f6601a615..8cd9636c1aa1f072a7ae2c403f7ffb3579c796f7 100644 (file)
@@ -2585,7 +2585,7 @@ set_serial_info( i2ChanStrPtr pCh, struct serial_struct *new_info )
         * base. Also line nunber as such is meaningless but we use it for our
         * array index so it is fixed also.
         */
-       if ( ns.irq         != ip2config.irq
+       if ( ns.irq         != ip2config.irq[pCh->port_index]
            || (int) ns.port      != ((int) pCh->pMyBord->i2eBase)
            || ns.baud_base != pCh->BaudBase
            || ns.line      != pCh->port_index ) {
index 23ad031610c5e2cfaa9682e1d671bffbd49c2e84..4d45be5062ef818ebdb1d396ff11d232c27f1e58 100644 (file)
@@ -74,6 +74,7 @@ extern void watchdog_init(void);
 extern void wdt_init(void);
 extern void acq_init(void);
 extern void wdt60xx_init(void);
+extern void sbc60xxwdt_init(void);
 extern void dtlk_init(void);
 extern void pcwatchdog_init(void);
 extern int rtc_init(void);
index f51eeb0bb5a4ccd1755c914487ee29f90994410f..3cf72f3e46327521ae31f6da9d863d7acad21443 100644 (file)
@@ -168,4 +168,6 @@ extern int rio_minor (kdev_t device);
 extern int rio_ismodem (kdev_t device);
 extern void rio_udelay (int usecs);
 
+extern void rio_start_card_running (struct Host * HostP);
+
 #endif /* __func_h_def */
index 9836ce5225a9fe58c61931211a6dce703a97d752..12c47eae2116cc3c191123fe556bbf8dacdebdcd 100644 (file)
@@ -56,16 +56,16 @@ struct    Host
     uchar                  Mode;      /* Control stuff */
     uchar                   Slot;      /* Slot */
     volatile caddr_t        Caddr;     /* KV address of DPRAM */
-    volatile struct DpRam   *CardP;    /* KV address of DPRAM, with overlay */
+    volatile struct DpRam  *CardP;     /* KV address of DPRAM, with overlay */
     paddr_t                PaddrP;    /* Phys. address of DPRAM */
     char                    Name[MAX_NAME_LEN];  /* The name of the host */
     uint                   UniqueNum; /* host unique number */
-    semtype        HostLock;  /* Lock structure for MPX */
-    /*struct pci_devinfo           PciDevInfo; *//* PCI Bus/Device/Function stuff */
+    spinlock_t             HostLock;  /* Lock structure for MPX */
+    /*struct pci_devinfo    PciDevInfo; *//* PCI Bus/Device/Function stuff */
     /*struct lockb         HostLock;  *//* Lock structure for MPX */
     uint                    WorkToBeDone; /* set to true each interrupt */
     uint                    InIntr;    /* Being serviced? */
-    uint                    IntSrvDone;        /* host's interrupt has been serviced */
+    uint                    IntSrvDone;/* host's interrupt has been serviced */
     int                            (*Copy)( caddr_t, caddr_t, int ); /* copy func */
     struct timer_list timer;
     /*
index 3656d93e7e8f677429ae034a4c8d65a5c1101471..3b6d2f3b1a93630018da9740f8114acd70871aa8 100644 (file)
@@ -47,9 +47,6 @@ struct ttystatics {
 
 #define SEM_SIGIGNORE 0x1234
 
-typedef struct semaphore semtype;
-
-
 #ifdef DEBUG_SEM
 #define swait(a,b)      printk ("waiting:    " __FILE__ " line %d\n", __LINE__)
 #define ssignal(sem)    printk ("signalling: " __FILE__ " line %d\n", __LINE__)
index aeed5f095251bc1ab039e2b95655c23f8bb18cc9..90bdb867cea5c220bbee51384a77999cade25bdf 100644 (file)
@@ -109,108 +109,6 @@ of boards in rio.h.  You'll have to allocate more majors if you need
 more than 512 ports.... */
 
 
-/* ************************************************************** */
-/* * This section can be removed when 2.0 becomes outdated....  * */
-/* ************************************************************** */
-
-#if LINUX_VERSION_CODE < 0x020100    /* Less than 2.1.0 */
-#define TWO_ZERO
-#else
-#if LINUX_VERSION_CODE < 0x020209   /* less than 2.2.x */
-#warning "Please use a recent 2.2.x kernel. "
-#endif
-#endif
-
-
-#ifdef TWO_ZERO
-
-/* Here is the section that makes the 2.2 compatible driver source 
-   work for 2.0 too! We mostly try to adopt the "new thingies" from 2.2, 
-   and provide for compatibility stuff here if possible. */
-
-#include <linux/bios32.h>
-
-#define Get_user(a,b)                a = get_user(b)
-#define Put_user(a,b)                0,put_user(a,b)
-#define copy_to_user(a,b,c)          memcpy_tofs(a,b,c)
-
-static inline int copy_from_user(void *to,const void *from, int c) 
-{
-  memcpy_fromfs(to, from, c);
-  return 0;
-}
-
-#define pci_present                  pcibios_present
-#define pci_read_config_word         pcibios_read_config_word
-#define pci_read_config_dword        pcibios_read_config_dword
-
-static inline unsigned char get_irq (unsigned char bus, unsigned char fn)
-{
-  unsigned char t; 
-  pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &t);
-  return t;
-}
-
-static inline void *ioremap(unsigned long base, long length)
-{
-  if (base < 0x100000) return (void *)base;
-  return vremap (base, length);
-}
-
-#define my_iounmap(x, b)             (((long)x<0x100000)?0:vfree ((void*)x))
-
-#define capable(x)                   suser()
-
-#define queue_task                   queue_task_irq_off
-#define tty_flip_buffer_push(tty)    queue_task(&tty->flip.tqueue, &tq_timer)
-#define signal_pending(current)      (current->signal & ~current->blocked)
-#define schedule_timeout(to)         do {current->timeout = jiffies + (to);schedule ();} while (0)
-#define time_after(t1,t2)            (((long)t1-t2) > 0)
-
-
-#define test_and_set_bit(nr, addr)   set_bit(nr, addr)
-#define test_and_clear_bit(nr, addr) clear_bit(nr, addr)
-
-/* Not yet implemented on 2.0 */
-#define ASYNC_SPD_SHI  -1
-#define ASYNC_SPD_WARP -1
-
-
-/* Ugly hack: the driver_name doesn't exist in 2.0.x . So we define it
-   to the "name" field that does exist. As long as the assignments are
-   done in the right order, there is nothing to worry about. */
-#define driver_name           name 
-
-/* Should be in a header somewhere. They are in tty.h on 2.2 */
-#define TTY_HW_COOK_OUT       14 /* Flag to tell ntty what we can handle */
-#define TTY_HW_COOK_IN        15 /* in hardware - output and input       */
-
-/* The return type of a "close" routine. */
-#define INT                   void
-#define NO_ERROR              /* Nothing */
-
-#else
-
-/* The 2.2.x compatibility section. */
-#include <asm/uaccess.h>
-
-#define Get_user(a,b)         get_user(a,b)
-#define Put_user(a,b)         put_user(a,b)
-#define get_irq(pdev)         pdev->irq
-
-#define INT                   int
-#define NO_ERROR              0              
-
-#define my_iounmap(x,b)       (iounmap((char *)(b)))
-
-#endif
-
-/* ************************************************************** */
-/* *                End of compatibility section..              * */
-/* ************************************************************** */
-
-
-
 /* Why the hell am I defining these here? */
 #define RIO_TYPE_NORMAL 1
 #define RIO_TYPE_CALLOUT 2
@@ -373,55 +271,15 @@ static struct real_driver rio_real_driver = {
   NULL
 };
 
-
-/* 
-   This driver can spew a whole lot of debugging output at you. If you
-   need maximum performance, you should disable the DEBUG define. To
-   aid in debugging in the field, I'm leaving the compile-time debug
-   features enabled, and disable them "runtime". That allows me to
-   instruct people with problems to enable debugging without requiring
-   them to recompile... 
-*/
-#define DEBUG
-
-#ifdef DEBUG
-#define rio_dprintk(f, str...) if (rio_debug & f) printk (str)
-#else
-#define rio_dprintk(f, str...) /* nothing */
-#endif
-
-
-#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ "\n")
-#define func_exit()  rio_dprintk (RIO_DEBUG_FLOW, "rio: exit  " __FUNCTION__ "\n")
-
-#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ \
-                                  "(port %d)\n", port->line)
-
-
-
-
 /* 
  *  Firmware loader driver specific routines
  *
  */
 
 static struct file_operations rio_fw_fops = {
-       NULL,   /*      lseek   */
-       NULL,   /*      read    */
-       NULL,   /*      write   */
-       NULL,   /*      readdir */
-       NULL,   /*      select  */
-       rio_fw_ioctl,
-       NULL,   /*      mmap    */
-       rio_fw_open,
-#ifndef TWO_ZERO
-       NULL,   /*      flush   */
-#endif
-       rio_fw_release,
-       NULL,   /*      fsync   */
-       NULL,   /*      fasync  */
-       NULL,   /*      check_media_change      */
-       NULL,   /*      revalidate      */
+        open:           rio_fw_open,
+        release:        rio_fw_release,
+       ioctl:          rio_fw_ioctl,
 };
 
 struct miscdevice rio_fw_device = {
@@ -446,11 +304,11 @@ static inline int rio_paranoia_check(struct rio_port const * port,
     KERN_ERR "rio: Warning: null rio port for device %s in %s\n";
  
   if (!port) {
-    printk(badinfo, kdevname(device), routine);
+    printk (badinfo, kdevname(device), routine);
     return 1;
   }
   if (port->magic != RIO_MAGIC) {
-    printk(badmagic, kdevname(device), routine);
+    printk (badmagic, kdevname(device), routine);
     return 1;
   }
 
@@ -468,15 +326,15 @@ void my_hd (void *ad, int len)
   unsigned char *addr = ad;
   
   for (i=0;i<len;i+=16) {
-    printk ("%08x ", (int) addr+i);
+    rio_dprintk (RIO_DEBUG_PARAM, "%08x ", (int) addr+i);
     for (j=0;j<16;j++) {
-      printk ("%02x %s", addr[j+i], (j==7)?" ":"");
+      rio_dprintk (RIO_DEBUG_PARAM, "%02x %s", addr[j+i], (j==7)?" ":"");
     }
     for (j=0;j<16;j++) {
       ch = addr[j+i];
-      printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
+      rio_dprintk (RIO_DEBUG_PARAM, "%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
     }
-    printk ("\n");
+    rio_dprintk (RIO_DEBUG_PARAM, "\n");
   }
 }
 #else
@@ -568,21 +426,26 @@ static int rio_set_real_termios (void *ptr)
 
 void rio_reset_interrupt (struct Host *HostP)
 {
+  func_enter();
+
   switch( HostP->Type ) {
   case RIO_AT:
   case RIO_MCA:
   case RIO_PCI:
     WBYTE(HostP->ResetInt , 0xff);
   }
+
+  func_exit();
 }
 
 
 static void rio_interrupt (int irq, void *ptr, struct pt_regs *regs)
 {
   struct Host *HostP;
+  func_enter ();
 
-  HostP = &p->RIOHosts[(long)ptr];
-  /*   func_enter ();  */
+  HostP = (struct Host*)ptr; /* &p->RIOHosts[(long)ptr]; */
+  
   rio_dprintk (RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", 
                irq, HostP->Ivec); 
 
@@ -627,7 +490,7 @@ static void rio_interrupt (int irq, void *ptr, struct pt_regs *regs)
     }
   }
 #endif
-
+  rio_dprintk (RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n"); 
   if (HostP->Ivec == irq) {
     /* Tell the card we've noticed the interrupt. */
     rio_reset_interrupt (HostP);
@@ -649,7 +512,7 @@ static void rio_interrupt (int irq, void *ptr, struct pt_regs *regs)
   clear_bit (RIO_BOARD_INTR_LOCK, &HostP->locks);
   rio_dprintk (RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", 
                irq, HostP->Ivec); 
-  /*  func_exit ();  */
+  func_exit ();
 }
 
 
@@ -657,7 +520,7 @@ static void rio_pollfunc (unsigned long data)
 {
   func_enter ();
 
-  rio_interrupt (0, (void *)data, NULL);
+  rio_interrupt (0, &p->RIOHosts[data], NULL);
   p->RIOHosts[data].timer.expires = jiffies + rio_poll;
   add_timer (&p->RIOHosts[data].timer);
 
@@ -756,11 +619,11 @@ static void rio_shutdown_port (void * ptr)
 #if 0
   port->gs.flags &= ~ GS_ACTIVE;
   if (!port->gs.tty) {
-    printk ("No tty.\n");
+    rio_dprintk (RIO_DBUG_TTY, "No tty.\n");
     return;
   }
   if (!port->gs.tty->termios) {
-    printk ("No termios.\n");
+    rio_dprintk (RIO_DEBUG_TTY, "No termios.\n");
     return;
   }
   if (port->gs.tty->termios->c_cflag & HUPCL) {
@@ -772,7 +635,6 @@ static void rio_shutdown_port (void * ptr)
 }
 
 
-
 /* ********************************************************************** *
  *                Here are the routines that actually                     *
  *               interface with the rest of the system                    *
@@ -1000,6 +862,8 @@ struct vpd_prom *get_VPD_PROM (struct Host *hp)
 
   if (rio_debug & RIO_DEBUG_PROBE)
     my_hd ((char *)&vpdp, 0x20);
+  
+  func_exit();
 
   return &vpdp;
 }
@@ -1099,7 +963,7 @@ static int rio_init_datastructures (void)
   /* However, the RIO driver allows users to configure their first
      RTA as the ports numbered 504-511. We therefore need to allocate 
      the whole range. :-(   -- REW */
-
+  
 #define RI_SZ   sizeof(struct rio_info)
 #define HOST_SZ sizeof(struct Host)
 #define PORT_SZ sizeof(struct Port *)
@@ -1138,11 +1002,14 @@ static int rio_init_datastructures (void)
     port->gs.close_delay = HZ/2;
     port->gs.closing_wait = 30 * HZ;
     port->gs.rd = &rio_real_driver;
+
   }
 #else
   /* We could postpone initializing them to when they are configured. */
 #endif
 
+
+  
   if (rio_debug & RIO_DEBUG_INIT) {
     my_hd (&rio_real_driver, sizeof (rio_real_driver));
   }
@@ -1165,7 +1032,7 @@ static int rio_init_datastructures (void)
   return -ENOMEM;
 }
 
-
+#ifdef MODULE
 static void rio_release_drivers(void)
 {
   func_enter();
@@ -1175,6 +1042,7 @@ static void rio_release_drivers(void)
   tty_unregister_driver (&rio_driver);
   func_exit();
 }
+#endif 
 
 #ifdef TWO_ZERO
 #define PDEV unsigned char pci_bus, unsigned pci_fun
@@ -1211,7 +1079,7 @@ void fix_rio_pci (PDEV)
   unsigned int t;
 
 #define CNTRL_REG_OFFSET        0x50
-#define CNTRL_REG_GOODVALUE     0x00260000
+#define CNTRL_REG_GOODVALUE     0x18260000
 
   pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase);
   hwbase &= PCI_BASE_ADDRESS_MEM_MASK;
@@ -1292,7 +1160,6 @@ int rio_init(void)
       pci_read_config_dword (pdev, 0x2c, &tint);
       tshort = (tint >> 16) & 0xffff;
       rio_dprintk (RIO_DEBUG_PROBE, "Got a specialix card: %x.\n", tint);
-      /* rio_dprintk (RIO_DEBUG_PROBE, "pdev = %d/%d  (%x)\n", pdev, tint); */ 
       if (tshort != 0x0100) {
         rio_dprintk (RIO_DEBUG_PROBE, "But it's not a RIO card (%d)...\n", 
                     tshort);
@@ -1305,49 +1172,51 @@ int rio_init(void)
       hp = &p->RIOHosts[p->RIONumHosts];
       hp->PaddrP =  tint & PCI_BASE_ADDRESS_MEM_MASK;
       hp->Ivec = get_irq (pdev);
-      if (((1 << hp->Ivec) & rio_irqmask) == 0) hp->Ivec = 0;
+      if (((1 << hp->Ivec) & rio_irqmask) == 0)
+              hp->Ivec = 0;
       hp->CardP        = (struct DpRam *)
       hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
       hp->Type  = RIO_PCI;
       hp->Copy  = rio_pcicopy; 
-      hp->Mode  = RIO_PCI_DEFAULT_MODE;
+      hp->Mode  = RIO_PCI_BOOT_FROM_RAM;
+      rio_reset_interrupt (hp);
+      rio_start_card_running (hp);
+
       rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
                    (void *)p->RIOHosts[p->RIONumHosts].PaddrP,
                    p->RIOHosts[p->RIONumHosts].Caddr);
       if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP,
                         p->RIOHosts[p->RIONumHosts].Caddr, 
                         RIO_PCI, 0 ) == RIO_SUCCESS) {
-        WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);
-        p->RIOHosts[p->RIONumHosts].UniqueNum  =
-          ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)|
-          ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) &0xFF)<< 8)|
-          ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) &0xFF)<<16)|
-          ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) &0xFF)<<24);
-        rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n",
-                   p->RIOHosts[p->RIONumHosts].UniqueNum);
-
-#if 1
-        fix_rio_pci (pdev);
-#endif
-        p->RIOLastPCISearch = RIO_SUCCESS;
-        p->RIONumHosts++;
-        found++;
+              rio_dprintk (RIO_DEBUG_INIT, "Done RIOBoardTest\n");
+              WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);
+              p->RIOHosts[p->RIONumHosts].UniqueNum  =
+                      ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)|
+                      ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) &0xFF)<< 8)|
+                      ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) &0xFF)<<16)|
+                      ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) &0xFF)<<24);
+              rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n",
+                           p->RIOHosts[p->RIONumHosts].UniqueNum);
+              
+              fix_rio_pci (pdev);
+              p->RIOLastPCISearch = RIO_SUCCESS;
+              p->RIONumHosts++;
+              found++;
       } else {
-        my_iounmap (p->RIOHosts[p->RIONumHosts].PaddrP, 
-                    p->RIOHosts[p->RIONumHosts].Caddr);
+              my_iounmap (p->RIOHosts[p->RIONumHosts].PaddrP, 
+                          p->RIOHosts[p->RIONumHosts].Caddr);
       }
-
+      
 #ifdef TWO_ZERO
     }  /* We have two variants with the opening brace, so to prevent */
 #else
     }  /* Emacs from getting confused we have two closing braces too. */
 #endif
     
-
     /* Then look for the older PCI card.... : */
 #ifndef TWO_ZERO
 
+
   /* These older PCI cards have problems (only byte-mode access is
      supported), which makes them a bit awkward to support. 
      They also have problems sharing interrupts. Be careful. 
@@ -1372,15 +1241,21 @@ int rio_init(void)
       hp = &p->RIOHosts[p->RIONumHosts];
       hp->PaddrP =  tint & PCI_BASE_ADDRESS_MEM_MASK;
       hp->Ivec = get_irq (pdev);
-      if (((1 << hp->Ivec) & rio_irqmask) == 0) hp->Ivec = 0;
+      if (((1 << hp->Ivec) & rio_irqmask) == 0) 
+       hp->Ivec = 0;
       hp->Ivec |= 0x8000; /* Mark as non-sharable */
       hp->CardP        = (struct DpRam *)
       hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
       hp->Type  = RIO_PCI;
       hp->Copy  = rio_pcicopy;
-      hp->Mode  = RIO_PCI_DEFAULT_MODE;
-      rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
+      hp->Mode  = RIO_PCI_BOOT_FROM_RAM;
+
+      rio_dprintk (RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec);
+      rio_dprintk (RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode);
+
+      rio_reset_interrupt (hp);
+      rio_start_card_running (hp);
+       rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
                    (void *)p->RIOHosts[p->RIONumHosts].PaddrP,
                    p->RIOHosts[p->RIONumHosts].Caddr);
       if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP,
@@ -1423,11 +1298,15 @@ int rio_init(void)
     hp->CardP = (struct DpRam *)
     hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
     hp->Type = RIO_AT;
-    hp->Copy = rio_pcicopy;
+    hp->Copy = rio_pcicopy; /* AT card PCI???? - PVDL
+                             * -- YES! this is now a normal copy. Only the 
+                             * old PCI card uses the special PCI copy. 
+                             * Moreover, the ISA card will work with the 
+                             * special PCI copy anyway. -- REW */
     hp->Mode = 0;
 
     vpdp = get_VPD_PROM (hp);
-
+    rio_dprintk (RIO_DEBUG_PROBE, "Got VPD ROM\n");
     okboard = 0;
     if ((strncmp (vpdp->identifier, RIO_ISA_IDENT, 16) == 0) ||
         (strncmp (vpdp->identifier, RIO_ISA2_IDENT, 16) == 0) ||
@@ -1458,11 +1337,21 @@ int rio_init(void)
     if (hp->Ivec) {
       int mode = SA_SHIRQ;
       if (hp->Ivec & 0x8000) {mode = 0; hp->Ivec &= 0x7fff;}
-      if (request_irq (hp->Ivec, rio_interrupt, mode, "rio", (void *)i)) {
-        printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec);
-        hp->Ivec = 0;
+      rio_dprintk (RIO_DEBUG_INIT, "Requesting interrupt hp: %p rio_interrupt: %d Mode: %x\n", hp,hp->Ivec, hp->Mode);
+      retval = request_irq (hp->Ivec, rio_interrupt, mode, "rio", hp);
+      rio_dprintk (RIO_DEBUG_INIT, "Return value from request_irq: %d\n", retval);
+      if (retval) {
+              printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec);
+              hp->Ivec = 0;
       }
       rio_dprintk (RIO_DEBUG_INIT, "Got irq %d.\n", hp->Ivec);
+      if (hp->Ivec != 0){
+              rio_dprintk (RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n"); 
+              hp->Mode |= RIO_PCI_INT_ENABLE;
+      } else
+              hp->Mode &= !RIO_PCI_INT_ENABLE;
+      rio_dprintk (RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode);
+      rio_start_card_running (hp);
     }
     /* Init the timer "always" to make sure that it can safely be 
        deleted when we unload... */
@@ -1479,7 +1368,7 @@ int rio_init(void)
   }
 
   if (found) {
-    printk (KERN_INFO "rio: total of %d boards detected.\n", found);
+    rio_dprintk (RIO_DEBUG_INIT, "rio: total of %d boards detected.\n", found);
 
     if (misc_register(&rio_fw_device) < 0) {
       printk(KERN_ERR "RIO: Unable to register firmware loader driver.\n");
@@ -1504,7 +1393,7 @@ void cleanup_module(void)
   for (i=0,hp=p->RIOHosts;i<p->RIONumHosts;i++, hp++) {
     RIOHostReset (hp->Type, hp->CardP, hp->Slot);
     if (hp->Ivec) {
-      free_irq (hp->Ivec, (void *)i);
+      free_irq (hp->Ivec, hp);
       rio_dprintk (RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec);
     }
     /* It is safe/allowed to del_timer a non-active timer */
index 3f7dcd2f003fcfe6907554e53ec732bd73ada486..c8b72bdce94ca4594430125428399ba83776ee0c 100644 (file)
@@ -23,6 +23,7 @@
  *  Version 1.0 -- July, 1999. 
  * 
  */
+#include <linux/config.h>
 
 #define RIO_NBOARDS        4
 #define RIO_PORTSPERBOARD 128
@@ -159,3 +160,28 @@ static inline void *rio_memcpy_fromio (void *dest, void *source, int n)
 #define rio_memcpy_fromio                      memcpy_fromio
 #endif
 
+#define DEBUG
+
+
+/* 
+   This driver can spew a whole lot of debugging output at you. If you
+   need maximum performance, you should disable the DEBUG define. To
+   aid in debugging in the field, I'm leaving the compile-time debug
+   features enabled, and disable them "runtime". That allows me to
+   instruct people with problems to enable debugging without requiring
+   them to recompile... 
+*/
+
+#ifdef DEBUG
+#define rio_dprintk(f, str...) if (rio_debug & f) printk (str)
+#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ "\n")
+#define func_exit()  rio_dprintk (RIO_DEBUG_FLOW, "rio: exit  " __FUNCTION__ "\n")
+#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ \
+                                   "(port %d)\n", port->line)
+#else
+#define rio_dprintk(f, str...) /* nothing */
+#define func_enter()
+#define func_exit()
+#define func_enter2()
+#endif
+
index 238d561a4a1d8c1dc8c7c4ffb84fbdcb19572d07..8168f213339f1b64031fae7de79bb604cf4e1358 100644 (file)
@@ -35,7 +35,6 @@ static char *_rioboot_c_sccs_ = "@(#)rioboot.c        1.3";
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -82,7 +81,6 @@ static char *_rioboot_c_sccs_ = "@(#)rioboot.c        1.3";
 #include "cmdblk.h"
 #include "route.h"
 
-
 static uchar
 RIOAtVec2Ctrl[] =
 {
@@ -114,6 +112,8 @@ struct DownLoad *   rbp;
 {
        int offset;
 
+       func_enter ();
+
        /* Linux doesn't allow you to disable interrupts during a
           "copyin". (Crash when a pagefault occurs). */
        /* disable(oldspl); */
@@ -127,6 +127,7 @@ struct DownLoad *   rbp;
                rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code Too Large!\n"));
                p->RIOError.Error = HOST_FILE_TOO_LARGE;
                /* restore(oldspl); */
+               func_exit ();
                return ENOMEM;
        }
 
@@ -134,6 +135,7 @@ struct DownLoad *   rbp;
                rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code : BUSY BUSY BUSY!\n"));
                p->RIOError.Error = BOOT_IN_PROGRESS;
                /* restore(oldspl); */
+               func_exit ();
                return EBUSY;
        }
 
@@ -161,6 +163,7 @@ struct DownLoad *   rbp;
                rio_dprint(RIO_DEBUG_BOOT, ("Bad data copy from user space\n"));
                p->RIOError.Error = COPYIN_FAILED;
                /* restore(oldspl); */
+               func_exit ();
                return EFAULT;
        }
 
@@ -172,9 +175,61 @@ struct DownLoad *  rbp;
        p->RIOBootCount   = rbp->Count;
 
        /* restore(oldspl); */
+       func_exit();
        return 0;
 }
 
+void rio_start_card_running (struct Host * HostP)
+{
+       func_enter ();
+
+       switch ( HostP->Type ) {
+       case RIO_AT:
+               rio_dprint(RIO_DEBUG_BOOT, ("Start ISA card running\n"));
+               WBYTE(HostP->Control, 
+                     BOOT_FROM_RAM | EXTERNAL_BUS_ON
+                     | HostP->Mode
+                     | RIOAtVec2Ctrl[HostP->Ivec & 0xF] );
+               break;
+               
+#ifdef FUTURE_RELEASE
+       case RIO_MCA:
+                               /*
+                               ** MCA handles IRQ vectors differently, so we don't write 
+                               ** them to this register.
+                               */
+               rio_dprint(RIO_DEBUG_BOOT, ("Start MCA card running\n"));
+               WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode);
+               break;
+
+       case RIO_EISA:
+                               /*
+                               ** EISA is totally different and expects OUTBZs to turn it on.
+                               */
+               rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_DAEMON,"Start EISA card running\n");
+               OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM );
+               break;
+#endif
+
+       case RIO_PCI:
+                               /*
+                               ** PCI is much the same as MCA. Everything is once again memory
+                               ** mapped, so we are writing to memory registers instead of io
+                               ** ports.
+                               */
+               rio_dprint(RIO_DEBUG_BOOT, ("Start PCI card running\n"));
+               WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode);
+               break;
+       default:
+               rio_dprint(RIO_DEBUG_BOOT, ("Unknown host type %d\n",HostP->Type));
+               break;
+       }
+/* 
+       printk (KERN_INFO "Done with starting the card\n");
+       func_exit ();
+*/
+       return;
+}
 
 /*
 ** Load in the host boot code - load it directly onto all halted hosts
@@ -207,6 +262,10 @@ register struct DownLoad *rbp;
        for ( host=0; host<p->RIONumHosts; host++ ) {
                rio_dprint(RIO_DEBUG_BOOT, ("Attempt to boot host %d\n",host));
                HostP = &p->RIOHosts[host];
+               
+               rio_dprint(RIO_DEBUG_BOOT,  ("Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
+                   HostP->Type, HostP->Mode, HostP->Ivec ) );
+
 
                if ( (HostP->Flags & RUN_STATE) != RC_WAITING ) {
                        rio_dprint(RIO_DEBUG_BOOT, ("%s %d already running\n","Host",host));
@@ -234,6 +293,7 @@ register struct DownLoad *rbp;
                if ( p->RIOConf.HostLoadBase < rbp->Count ) {
                        rio_dprint(RIO_DEBUG_BOOT, ("Bin too large\n"));
                        p->RIOError.Error = HOST_FILE_TOO_LARGE;
+                       func_exit ();
                        return EFBIG;
                }
                /*
@@ -260,6 +320,7 @@ register struct DownLoad *rbp;
                        if ( !DownCode ) {
                                rio_dprint(RIO_DEBUG_BOOT, ("No system memory available\n"));
                                p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY;
+                               func_exit ();
                                return ENOMEM;
                        }
                        bzero(DownCode, rbp->Count);
@@ -267,6 +328,7 @@ register struct DownLoad *rbp;
                        if ( copyin((int)rbp->DataP,DownCode,rbp->Count)==COPYFAIL ) {
                                rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n"));
                                p->RIOError.Error = COPYIN_FAILED;
+                               func_exit ();
                                return EFAULT;
                        }
 
@@ -277,6 +339,7 @@ register struct DownLoad *rbp;
                else if ( copyin((int)rbp->DataP,StartP,rbp->Count)==COPYFAIL ) {
                        rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n"));
                        p->RIOError.Error = COPYIN_FAILED;
+                       func_exit ();
                        return EFAULT;
                }
 
@@ -406,47 +469,8 @@ register struct DownLoad *rbp;
                rio_dprint(RIO_DEBUG_BOOT,  ("Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
                    HostP->Type, HostP->Mode, HostP->Ivec ) );
 
-               switch ( HostP->Type ) {
-                       case RIO_AT:
-                               rio_dprint(RIO_DEBUG_BOOT, ("Start ISA card running\n"));
-                               WBYTE(HostP->Control, 
-                                       BOOT_FROM_RAM | EXTERNAL_BUS_ON
-                                       | HostP->Mode
-                                       | RIOAtVec2Ctrl[HostP->Ivec & 0xF] );
-                               break;
+               rio_start_card_running(HostP);
 
-#ifdef FUTURE_RELEASE
-                       case RIO_MCA:
-                               /*
-                               ** MCA handles IRQ vectors differently, so we don't write 
-                               ** them to this register.
-                               */
-                               rio_dprint(RIO_DEBUG_BOOT, ("Start MCA card running\n"));
-                               WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode);
-                               break;
-
-                       case RIO_EISA:
-                               /*
-                               ** EISA is totally different and expects OUTBZs to turn it on.
-                               */
-                               rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_DAEMON,"Start EISA card running\n");
-                               OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM );
-                               break;
-#endif
-
-                       case RIO_PCI:
-                               /*
-                               ** PCI is much the same as MCA. Everything is once again memory
-                               ** mapped, so we are writing to memory registers instead of io
-                               ** ports.
-                               */
-                               rio_dprint(RIO_DEBUG_BOOT, ("Start PCI card running\n"));
-                               WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode);
-                               break;
-                       default:
-                               rio_dprint(RIO_DEBUG_BOOT, ("Unknown host type %d\n",HostP->Type));
-                               break;
-               }
                rio_dprint(RIO_DEBUG_BOOT, ("Set control port\n"));
 
                /*
@@ -454,9 +478,10 @@ register struct DownLoad *rbp;
                ** pointer:
                */
                for ( wait_count=0; (wait_count<p->RIOConf.StartupTime)&&
-                               (RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) {
+                       (RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) {
                        rio_dprint(RIO_DEBUG_BOOT, ("Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR)));
                        delay(HostP, HUNDRED_MS);
+
                }
 
                /*
@@ -614,6 +639,7 @@ register struct DownLoad *rbp;
        p->RIOSystemUp++;
        
        rio_dprint(RIO_DEBUG_BOOT, ("Done everything %x\n", HostP->Ivec));
+       func_exit ();
        return 0;
 }
 
index 5c720b7b6a054b9e80f8cfb7637cea984a47c0b3..835d815d35b03e2ce1afaf0e8cbed0e2071c8d50 100644 (file)
@@ -35,7 +35,6 @@ static char *_riocmd_c_sccs_ = "@(#)riocmd.c  1.2";
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -43,8 +42,6 @@ static char *_riocmd_c_sccs_ = "@(#)riocmd.c  1.2";
 #include <asm/system.h>
 #include <asm/string.h>
 #include <asm/semaphore.h>
-#include <asm/spinlock.h>
-
 
 #include <linux/termios.h>
 #include <linux/serial.h>
index 9113592c62b5c5b542f65828b6924cda4771c16d..fa68646d5c1da0ecab0999a06af9f446b9ab6462 100644 (file)
@@ -35,7 +35,6 @@ static char *_rioctrl_c_sccs_ = "@(#)rioctrl.c        1.3";
 
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -202,6 +201,8 @@ int         su;
        int             retval = 0;
        unsigned long flags;
        
+       func_enter ();
+       
        /* Confuse teh compiler to think that we've initialized these */
        Host=0;
        PortP = NULL;
@@ -1777,6 +1778,8 @@ RIO_DEBUG_CTRL,                           if (su)
        }
        rio_dprint(RIO_DEBUG_CTRL, ("INVALID DAEMON IOCTL 0x%x\n",cmd));
        p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
+
+       func_exit ();
        return EINVAL;
 }
 
index 2fcde39ee21d0f775f8faac21ba90741c19c304c..9a429e16bb41bfbe8f516435a620e4617a8be83b 100644 (file)
@@ -44,7 +44,7 @@ static char *_riodrvr_h_sccs_ = "@(#)riodrvr.h        1.3";
 
 struct rio_info {
        int                     mode;                   /* Intr or polled, word/byte */
-       semtype                 RIOIntrSem;             /* Interrupt thread sem */
+       spinlock_t              RIOIntrSem;             /* Interrupt thread sem */
        int                     current_chan;           /* current channel */
        int                     RIOFailed;              /* Not initialised ? */
        int                     RIOInstallAttempts;     /* no. of rio-install() calls */
index b90f8e4bab2408956900582b48c264aecd594e54..59cfdedd5cf87e49ae9cf70622032bcdf7698bb1 100644 (file)
@@ -1414,7 +1414,7 @@ struct rio_info * p;
            (int)p->RIOHosts, sizeof(struct Host) ) );
 
        for( host=0; host<RIO_HOSTS; host++ ) {
-               p->RIOHosts[host].HostLock = -1; /* Let the first guy takes it */
+               spin_lock_init (&p->RIOHosts[host].HostLock);
                p->RIOHosts[host].timeout_id = 0; /* Let the first guy takes it */
        }
        /*
index c389c4fb7563d1729838a037ee5bd5e8ae43cded..e92609839f9b6ce625247ea7addb27373aa1526c 100644 (file)
@@ -35,7 +35,6 @@ static char *_riointr_c_sccs_ = "@(#)riointr.c        1.2";
 
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -254,7 +253,6 @@ char *              en;
     rio_dprint (RIO_DEBUG_INTR, ("(%d/%d)\n",
                PortP->gs.wakeup_chars, PortP->gs.xmit_cnt)); 
     wake_up_interruptible(&PortP->gs.tty->write_wait);
-    wake_up_interruptible(&PortP->gs.tty->poll_wait);
   }
 
 }
index aa4b782d3c1c4db2c17afe4f0909db1c0622a38c..550e2c17d98dc77e21084b5f45f5617a3da1cf0f 100644 (file)
@@ -35,7 +35,6 @@ static char *_rioparam_c_sccs_ = "@(#)rioparam.c      1.3";
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
index aba66213b5394ac3ff0dc660d651d1cf1fde4932..2f13eb2732179999e6ef2c09912939e737b8a76f 100644 (file)
@@ -34,7 +34,6 @@ static char *_rioroute_c_sccs_ = "@(#)rioroute.c      1.3";
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
index 09f9d8f7ef85b14d7cbad63885d10ef42e8e6db5..6329a6e18dbabd764902c75828ed5d247a2ed471 100644 (file)
@@ -34,7 +34,6 @@ static char *_riotable_c_sccs_ = "@(#)riotable.c      1.2";
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
index 7fec8dd7c3314ab47e4bd2e491555aa90078f936..cda417f3f4da079042cf421eb168c235b90fdfbb 100644 (file)
@@ -37,7 +37,6 @@ static char *_riotty_c_sccs_ = "@(#)riotty.c  1.3";
 #define __EXPLICIT_DEF_H__
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -90,7 +89,6 @@ static char *_riotty_c_sccs_ = "@(#)riotty.c  1.3";
 #include "list.h"
 #include "sam.h"
 
-
 #if 0
 static void ttyseth_pv(struct Port *, struct ttystatics *, 
                                struct termios *sg, int);
@@ -155,13 +153,21 @@ riotopen(struct tty_struct * tty, struct file * filp)
        unsigned long flags;
        int retval = 0;
 
+       func_enter ();
+
+       /* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close
+          is going to oops.
+       */
+       tty->driver_data = NULL;
+        
        SysPort = rio_minor (tty->device);
        Modem   = rio_ismodem (tty->device);
 
        if ( p->RIOFailed ) {
                rio_dprint(RIO_DEBUG_TTY, ("System initialisation failed\n"));
                pseterr(ENXIO);
-               return 0;
+               func_exit ();
+               return -ENXIO;
        }
 
        rio_dprint(RIO_DEBUG_TTY, ("port open SysPort %d (%s) (mapped:%d)\n",
@@ -177,22 +183,24 @@ riotopen(struct tty_struct * tty, struct file * filp)
        if (SysPort >= RIO_PORTS) {     /* out of range ? */
                rio_dprint(RIO_DEBUG_TTY, ("Illegal port number %d\n",SysPort));
                pseterr(ENXIO);
-               return 0;
+               func_exit();
+               return -ENXIO;
        }
 
        /*
        ** Grab pointer to the port stucture
        */
        PortP = p->RIOPortp[SysPort];   /* Get control struc */
-
+       rio_dprintk (RIO_DEBUG_TTY, "PortP: %p\n", PortP);
        if ( !PortP->Mapped ) { /* we aren't mapped yet! */
                /*
                ** The system doesn't know which RTA this port
                ** corresponds to.
                */
                rio_dprint(RIO_DEBUG_TTY, ("port not mapped into system\n"));
+               func_exit ();
                pseterr(ENXIO);
-               return 0;
+               return -ENXIO;
        }
 
        tty->driver_data = PortP;
@@ -210,7 +218,8 @@ riotopen(struct tty_struct * tty, struct file * filp)
        if ( (PortP->HostP->Flags & RUN_STATE) != RC_RUNNING ) {
                rio_dprint(RIO_DEBUG_TTY, ("Host not running\n"));
                pseterr(ENXIO);
-               return 0;
+               func_exit ();
+               return -ENXIO;
        }
 
        /*
@@ -225,12 +234,14 @@ riotopen(struct tty_struct * tty, struct file * filp)
                        do {
                                if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
                                        rio_dprint(RIO_DEBUG_TTY, ("RTA EINTR in delay \n"));
+                                       func_exit ();
                                        return -EINTR;
                                }
                                if (repeat_this -- <= 0) {
                                        rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot timeout\n"));
                                        RIOPreemptiveCmd(p, PortP, FCLOSE ); 
                                        pseterr(EINTR);
+                                       func_exit ();
                                        return -EIO;
                                }
                        } while(!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED));
@@ -238,6 +249,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
                } else {
                        rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n"));
                        pseterr(ENXIO);
+                       func_exit ();
                        return 0;
                }
        }
@@ -250,6 +262,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
        while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
          if (!PortP->WaitUntilBooted) {
            rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n"));
+           func_exit ();
            return -ENXIO;
          }
 
@@ -259,10 +272,12 @@ riotopen(struct tty_struct * tty, struct file * filp)
          */
          if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
            rio_dprint(RIO_DEBUG_TTY, ("RTA_wait_for_boot: EINTR in delay \n"));
+           func_exit ();
            return -EINTR;
          }
          if (repeat_this -- <= 0) {
            rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot timeout\n"));
+           func_exit ();
            return -EIO;
          }
        }
@@ -277,8 +292,10 @@ riotopen(struct tty_struct * tty, struct file * filp)
        }
 #if 0
        retval = gs_init_port(&PortP->gs);
-       if (retval)
-         return retval;
+       if (retval){
+               func_exit ();
+               return retval;
+       }
 #endif
 
        /*
@@ -307,6 +324,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
                rio_dprint(RIO_DEBUG_TTY, ("Port unmapped while closing!\n"));
                rio_spin_unlock_irqrestore(&PortP->portSem, flags);
                retval = -ENXIO;
+               func_exit ();
                return retval;
        }
 
@@ -376,6 +394,7 @@ riotopen(struct tty_struct * tty, struct file * filp)
                        if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
                                rio_dprint(RIO_DEBUG_TTY, ("Waiting for open to finish broken by signal\n"));
                                RIOPreemptiveCmd(p, PortP, FCLOSE );
+                               func_exit ();
                                return -EINTR;
                        }
                        rio_spin_lock_irqsave(&PortP->portSem, flags);
@@ -426,6 +445,7 @@ bombout:
                                        tp->tm.c_state &= ~WOPEN;
                                        PortP->State &= ~RIO_WOPEN;
                                        rio_spin_unlock_irqrestore(&PortP->portSem, flags);
+                                       func_exit ();
                                        return -EINTR;
                                }
                        }
@@ -463,6 +483,7 @@ bombout:
 
        rio_spin_unlock_irqrestore(&PortP->portSem, flags);
        rio_dprint(RIO_DEBUG_TTY, ("Returning from open\n"));
+       func_exit ();
        return 0;
 }
 
index 2d3dab4c0aee390beebe7f13e794297dfb640397..eddf86278abca08e77ec8d45282baad08ba5069a 100644 (file)
@@ -49,7 +49,7 @@ struct    UnixRup
     uint             Id;               /* Id number */
     uint             BaseSysPort;      /* SysPort of first tty on this RTA */
     uint             ModTypes;         /* Modules on this RTA */
-  semtype      RupLock;                /* Lock structure for MPX */
+    spinlock_t      RupLock;           /* Lock structure for MPX */
 /*    struct lockb     RupLock;        */      /* Lock structure for MPX */
 };
 
index b12eb75bcfe548bf85e09f03cbee973ece5794c7..793f055f701b12fc6d47578264c5b4e2ec1e59c6 100644 (file)
  *
  * Revision history:
  * $Log: sx.c,v $
- * Revision 1.32  2000/03/07 90:00:00  wolff,pvdl
+ * Revision 1.33  2000/03/09 10:00:00  pvdl,wolff
+ * - Fixed module and port counting
+ * - Fixed signal handling
+ * - Fixed an Ooops
+ * 
+ * Revision 1.32  2000/03/07 09:00:00  wolff,pvdl
  * - Fixed some sx_dprintk typos
  * - added detection for an invalid board/module configuration
  *
  * */
 
 
-#define RCS_ID "$Id: sx.c,v 1.32 2000/03/07 17:01:02 wolff, pvdl Exp $"
-#define RCS_REV "$Revision: 1.32 $"
+#define RCS_ID "$Id: sx.c,v 1.33 2000/03/08 10:01:02 wolff, pvdl Exp $"
+#define RCS_REV "$Revision: 1.33 $"
 
 
 #include <linux/module.h>
@@ -414,22 +419,9 @@ static struct real_driver sx_real_driver = {
  */
 
 static struct file_operations sx_fw_fops = {
-       NULL,   /*      lseek   */
-       NULL,   /*      read    */
-       NULL,   /*      write   */
-       NULL,   /*      readdir */
-       NULL,   /*      select  */
-       sx_fw_ioctl,
-       NULL,   /*      mmap    */
-       sx_fw_open,
-#ifndef TWO_ZERO
-       NULL,   /*      flush   */
-#endif
-       sx_fw_release,
-       NULL,   /*      fsync   */
-       NULL,   /*      fasync  */
-       NULL,   /*      check_media_change      */
-       NULL,   /*      revalidate      */
+       open:           sx_fw_open,
+       release:        sx_fw_release,
+       ioctl:          sx_fw_ioctl
 };
 
 struct miscdevice sx_fw_device = {
@@ -781,6 +773,7 @@ static void sx_setsignals (struct sx_port *port, int dtr, int rts)
        if (rts >= 0) t = rts? (t | OP_RTS): (t & ~OP_RTS);
        sx_write_channel_byte (port, hi_op, t);
        sx_dprintk (SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts);
+
        func_exit ();
 }
 
@@ -1035,8 +1028,8 @@ void sx_transmit_chars (struct sx_port *port)
                if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail) 
                        c = SERIAL_XMIT_SIZE - port->gs.xmit_tail;
 
-               sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%d) \n", 
-                           c, SERIAL_XMIT_SIZE- port->gs.xmit_tail);
+               sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%ld) \n", 
+                           c, (long)SERIAL_XMIT_SIZE- port->gs.xmit_tail);
 
                /* If for one reason or another, we can't copy more data, we're done! */
                if (c == 0) break;
@@ -1060,14 +1053,13 @@ void sx_transmit_chars (struct sx_port *port)
                sx_disable_tx_interrupts (port);
        }
 
-       if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
+       if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) {
                if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
                    port->gs.tty->ldisc.write_wakeup)
                        (port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
                sx_dprintk (SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
                            port->gs.wakeup_chars); 
                wake_up_interruptible(&port->gs.tty->write_wait);
-               wake_up_interruptible(&port->gs.tty->poll_wait);
        }
 
        clear_bit (SX_PORT_TRANSMIT_LOCK, &port->locks);
@@ -1087,7 +1079,7 @@ inline void sx_receive_chars (struct sx_port *port)
        struct tty_struct *tty;
        int copied=0;
 
-       /* func_enter2 (); */
+       func_enter2 ();
        tty = port->gs.tty;
        while (1) {
                rx_op = sx_read_channel_byte (port, hi_rxopos);
@@ -1142,7 +1134,7 @@ inline void sx_receive_chars (struct sx_port *port)
                /*    tty_schedule_flip (tty); */
        }
 
-       /* func_exit (); */
+       func_exit ();
 }
 
 /* Inlined: it is called only once. Remove the inline if you add another 
@@ -1312,6 +1304,8 @@ static void sx_pollfunc (unsigned long data)
 
        sx_interrupt (0, board, NULL);
 
+       init_timer(&board->timer);
+
        board->timer.expires = jiffies + sx_poll;
        add_timer (&board->timer);
        func_exit ();
@@ -1407,7 +1401,7 @@ static void sx_shutdown_port (void * ptr)
        func_enter();
 
        port->gs.flags &= ~ GS_ACTIVE;
-       if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL) {
+       if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) {
                sx_setsignals (port, 0, 0);
                sx_reconfigure_port(port);
        }
@@ -1424,7 +1418,6 @@ static void sx_shutdown_port (void * ptr)
  *               interface with the rest of the system                    *
  * ********************************************************************** */
 
-
 static int sx_fw_open(struct inode *inode, struct file *filp)
 {
        func_enter ();
@@ -1443,6 +1436,7 @@ static INT sx_fw_release(struct inode *inode, struct file *filp)
 }
 
 
+
 static int sx_open  (struct tty_struct * tty, struct file * filp)
 {
        struct sx_port *port;
@@ -1470,6 +1464,8 @@ static int sx_open  (struct tty_struct * tty, struct file * filp)
 
        tty->driver_data = port;
        port->gs.tty = tty;
+       if (!port->gs.count)
+               MOD_INC_USE_COUNT;
        port->gs.count++;
 
        sx_dprintk (SX_DEBUG_OPEN, "starting port\n");
@@ -1481,19 +1477,13 @@ static int sx_open  (struct tty_struct * tty, struct file * filp)
        sx_dprintk (SX_DEBUG_OPEN, "done gs_init\n");
        if (retval) {
                port->gs.count--;
+               if (port->gs.count) MOD_DEC_USE_COUNT;
                return retval;
        }
 
        port->gs.flags |= GS_ACTIVE;
        sx_setsignals (port, 1,1);
 
-       sx_dprintk (SX_DEBUG_OPEN, "before inc_use_count (count=%d.\n", 
-                   port->gs.count);
-       if (port->gs.count == 1) {
-               MOD_INC_USE_COUNT;
-       }
-       sx_dprintk (SX_DEBUG_OPEN, "after inc_use_count\n");
-
 #if 0
        if (sx_debug & SX_DEBUG_OPEN)
                my_hd ((unsigned char *)port, sizeof (*port));
@@ -1505,8 +1495,8 @@ static int sx_open  (struct tty_struct * tty, struct file * filp)
 
        if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {
                printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n");
-               MOD_DEC_USE_COUNT;
                port->gs.count--;
+               if (!port->gs.count) MOD_DEC_USE_COUNT;
                return -EIO;
        }
 
@@ -1515,8 +1505,10 @@ static int sx_open  (struct tty_struct * tty, struct file * filp)
                    retval, port->gs.count);
 
        if (retval) {
-               MOD_DEC_USE_COUNT;
-               port->gs.count--;
+               /* 
+                * Don't lower gs.count here because sx_close() will be called later
+                */ 
+
                return retval;
        }
        /* tty->low_latency = 1; */
@@ -1548,25 +1540,15 @@ static int sx_open  (struct tty_struct * tty, struct file * filp)
    exit minicom.  I expect an "oops".  -- REW */
 static void sx_hungup (void *ptr)
 {
-/*
-       func_enter ();
-       MOD_DEC_USE_COUNT;
-       func_exit ();
-*/
-       /* 
-        * Got this from the 2.4.0-test1 serie. The port was closed before
-        * the lines were set in the proper condition. -- pvdl
-        */
        struct sx_port *port = ptr; 
        func_enter ();
 
-       /* 
-        *  Set the lines in the proper codition before closing the port.
-        *  Got the from 2.4.0-test1 series. -- pvdl
-        */
+       /* Don't force the SX card to close. mgetty doesn't like it !!!!!! -- pvdl */
+       /* For some reson we added this code. Don't know why anymore ;-) -- pvdl */
+       /*
        sx_setsignals (port, 0, 0);
        sx_reconfigure_port(port);      
-       sx_send_command (port, HS_CLOSE, -1, HS_IDLE_CLOSED);
+       sx_send_command (port, HS_CLOSE, 0, 0);
 
        if (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED) {
                if (sx_send_command (port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) != 1) {
@@ -1575,7 +1557,7 @@ static void sx_hungup (void *ptr)
                } else
                        sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n");
        }
-
+       */
        MOD_DEC_USE_COUNT;
        func_exit ();
 }
@@ -1611,6 +1593,11 @@ static void sx_close (void *ptr)
        sx_dprintk (SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", 
                    5 * HZ - to - 1, port->gs.count);
 
+       if(port->gs.count) {
+               sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", port->gs.count);
+               port->gs.count = 0;
+       }
+
        MOD_DEC_USE_COUNT;
        func_exit ();
 }
@@ -1953,10 +1940,7 @@ static int sx_init_board (struct sx_board *board)
        func_enter();
 
        /* This is preceded by downloading the download code. */
-       /* 
-        * The board should be set to initialized to make sure 
-        * we can boot the other cards. --pvdl
-        */ 
+
        board->flags |= SX_BOARD_INITIALIZED;
 
        if (read_sx_byte (board, 0))
@@ -2362,6 +2346,13 @@ static int sx_init_portstructs (int nboards, int nports)
 #ifdef NEW_WRITE_LOCKING
                        port->gs.port_write_sem = MUTEX;
 #endif
+                       /*
+                        * Initializing wait queue
+                        */
+                       /*
+                       init_waitqueue_head(&port->gs.open_wait);
+                       init_waitqueue_head(&port->gs.close_wait);              
+                       */
                        port++;
                }
        }
@@ -2403,7 +2394,7 @@ static int sx_init_portstructs (int nboards, int nports)
        return 0;
 }
 
-
+#ifdef MODULE
 static void sx_release_drivers(void)
 {
        func_enter();
@@ -2411,6 +2402,7 @@ static void sx_release_drivers(void)
        tty_unregister_driver(&sx_callout_driver);
        func_exit();
 }
+#endif
 
 #ifdef TWO_ZERO
 #define PDEV unsigned char pci_bus, unsigned pci_fun
@@ -2491,6 +2483,10 @@ int sx_init(void)
                while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
                                                PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, 
                                                      pdev))) {
+                 /*
+                       if (pci_enable_device(pdev))
+                               continue;
+                 */
 #else
                        for (i=0;i< SX_NBOARDS;i++) {
                                if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, 
@@ -2526,10 +2522,14 @@ int sx_init(void)
                                                      &tint);
                        else
                                pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
-                                                     &tint);
-                       board->hw_base = tint & PCI_BASE_ADDRESS_MEM_MASK;
+                                                     &tint);
                        board->base2 = 
                        board->base = (ulong) ioremap(board->hw_base, WINDOW_LEN (board));
+                       if (!board->base) {
+                               printk(KERN_ERR "ioremap failed\n");
+                               /* XXX handle error */
+                       }
+
                        /* Most of the stuff on the CF board is offset by
                           0x18000 ....  */
                        if (IS_CF_BOARD (board)) board->base += 0x18000;
index 8dc61ffdc12338841ea4e73519194164e0e979bf..19f2177bc0493c5f6ffea950cd77b0a623af28fc 100644 (file)
@@ -135,6 +135,8 @@ extern long con3215_init(long, long);
 #ifdef CONFIG_HWC_CONSOLE
 extern long hwc_console_init(long);
 #endif
+extern int rio_init(void);
+extern int sx_init(void);
 
 #ifndef MIN
 #define MIN(a,b)       ((a) < (b) ? (a) : (b))
index e5ef5dd322a286dd74024ff7b0d6b900af72133d..cd094ab56df76ac9ed302b81fa2e8697d9c47253 100644 (file)
@@ -166,13 +166,14 @@ static int i2ob_timer_started = 0;
 
 static int i2ob_install_device(struct i2o_controller *, struct i2o_device *, int);
 static void i2ob_end_request(struct request *);
-static void i2ob_request(struct request  * q);
+static void i2ob_request(void);
 static int do_i2ob_revalidate(kdev_t, int);
 static int i2ob_query_device(struct i2ob_device *, int, int, void*, int);
 static int i2ob_evt(void *);
 
 static int evt_pid = 0;
 static int evt_running = 0;
+static int scan_unit = 0;
 
 static void i2ob_new_device(struct i2o_controller *, struct i2o_device *);
 static void i2ob_del_device(struct i2o_controller *, struct i2o_device *);
@@ -375,14 +376,14 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
                
        }
 
-        if(msg->function == I2O_CMD_UTIL_EVT_REGISTER)
-        {
-                 spin_lock(&i2ob_evt_lock);
-                 memcpy(&evt_msg, m, msg->size);
-                 spin_unlock(&i2ob_evt_lock);
-                 wake_up_interruptible(&i2ob_evt_wait);
-                 return;
-        }
+       if(msg->function == I2O_CMD_UTIL_EVT_REGISTER)
+       {
+               spin_lock(&i2ob_evt_lock);
+               memcpy(&evt_msg, m, msg->size);
+               spin_unlock(&i2ob_evt_lock);
+               wake_up_interruptible(&i2ob_evt_wait);
+               return;
+       }
        if(!dev->i2odev)
        {
                /*
@@ -404,18 +405,17 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
                return;
        }
                 
-               /*
-                *      Lets see what is cooking. We stuffed the
-                *      request in the context.
-                */
+       /*
+        *      Lets see what is cooking. We stuffed the
+        *      request in the context.
+        */
 
-               ireq=&i2ob_queue[m[3]];
-               st=m[4]>>24;
+       ireq=&i2ob_queue[m[3]];
+       st=m[4]>>24;
        
-               if(st!=0)
-               {
-                       char *bsa_errors[] =
-                       {
+       if(st!=0)
+       {
+               char *bsa_errors[] = {
                        "Success",
                        "Media Error",
                        "Failure communicating to device",
@@ -430,59 +430,57 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
                        "Device is write protected",
                        "Device has reset",
                        "Volume has changed, waiting for acknowledgement"
-                       };
-                       printk(KERN_ERR "\n/dev/%s error: %s", dev->i2odev->dev_name, bsa_errors[m[4]&0XFFFF]);
+               };
 
-                       if(m[4]&0x00FF0000)
-                               printk(" - DDM attempted %d retries", (m[4]>>16)&0x00FF);
-                       printk("\n");
+               printk(KERN_ERR "\n/dev/%s error: %s", dev->i2odev->dev_name, bsa_errors[m[4]&0XFFFF]);
 
-                       ireq->req->errors++;    
+               if(m[4]&0x00FF0000)
+                       printk(" - DDM attempted %d retries", (m[4]>>16)&0x00FF);
+               printk("\n");
 
-                       if (ireq->req->errors < MAX_I2OB_RETRIES)
+               ireq->req->errors++;    
+               if (ireq->req->errors < MAX_I2OB_RETRIES)
+               {
+                       u32 retry_msg;
+                       printk(KERN_ERR "i2ob: attempting retry %d for request %p\n",ireq->req->errors+1,ireq->req);
+                               
+                       /* 
+                        * Get a message for this retry.
+                        */
+                       retry_msg = i2ob_get(dev);
+
+                       /* 
+                        * If we cannot get a message then
+                        * forget the retry and fail the
+                        * request.   Note that since this is
+                        * being called from the interrupt 
+                        * handler, a request has just been 
+                        * completed and there will most likely 
+                        * be space on the inbound message
+                        * fifo so this won't happen often.
+                        */
+                       if(retry_msg!=0xFFFFFFFF)
                        {
-                               u32 retry_msg;
-
-                               printk(KERN_ERR "i2ob: attempting retry %d for request %p\n",ireq->req->errors+1,ireq->req);
-                               
-                                 /* 
-                                * Get a message for this retry.
+                               /*
+                                * Decrement the queue depth since
+                                * this request has completed and
+                                * it will be incremented again when
+                                * i2ob_send is called below.
                                 */
-                               retry_msg = i2ob_get(dev);
-
-                               /* 
-                                * If we cannot get a message then
-                                * forget the retry and fail the
-                                * request.   Note that since this is
-                                * being called from the interrupt 
-                                * handler, a request has just been 
-                                * completed and there will most likely 
-                                * be space on the inbound message
-                                * fifo so this won't happen often.
+                               atomic_dec(&queue_depth);
+                               /*
+                                * Send the request again.
                                 */
-                               if(retry_msg!=0xFFFFFFFF)
-                               {
-                                         /*
-                                          * Decrement the queue depth since
-                                          * this request has completed and
-                                          * it will be incremented again when
-                                          * i2ob_send is called below.
-                                          */
-                                         atomic_dec(&queue_depth);
-
-                                         /*
-                                          * Send the request again.
-                                          */
-                                         i2ob_send(retry_msg, dev,ireq,i2ob[unit].start_sect, (unit&0xF0));
-                                       /*
-                                        * Don't fall through.
-                                        */
-                                       return;
-                               }
-                       }               
-               }
-               else
-                       ireq->req->errors = 0;
+                               i2ob_send(retry_msg, dev,ireq,i2ob[unit].start_sect, (unit&0xF0));
+                               /*
+                                * Don't fall through.
+                                */
+                               return;
+                       }
+               }               
+       }
+       else
+               ireq->req->errors = 0;
                
        /*
         *      Dequeue the request. We use irqsave locks as one day we
@@ -498,7 +496,7 @@ static void i2o_block_reply(struct i2o_handler *h, struct i2o_controller *c, str
         */
         
        atomic_dec(&queue_depth);
-       i2ob_request(NULL);
+       i2ob_request();
        spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
@@ -675,7 +673,7 @@ static void i2ob_timer_handler(unsigned long dummy)
        /* 
         * Restart any requests.
         */
-       i2ob_request(NULL);
+       i2ob_request();
 
        /* 
         * Free the lock.
@@ -691,7 +689,7 @@ static void i2ob_timer_handler(unsigned long dummy)
  *     we use it.
  */
 
-static void i2ob_request(struct request * q)
+static void i2ob_request(void)
 {
        unsigned long flags;
        struct request *req;
@@ -732,10 +730,9 @@ static void i2ob_request(struct request * q)
                        CURRENT = CURRENT->next;
                        req->sem = NULL;        
                        i2ob_end_request(req);  
+                       continue;
                }
 
-               else
-               {
                /* Get a message */
                m = i2ob_get(dev);
 
@@ -778,7 +775,6 @@ static void i2ob_request(struct request * q)
                ireq->req = req;
 
                i2ob_send(m, dev, ireq, i2ob[unit].start_sect, (unit&0xF0));
-               } 
        }
 }
 
@@ -1193,9 +1189,8 @@ static int i2ob_install_device(struct i2o_controller *c, struct i2o_device *d, i
 static int i2ob_scan(int bios)
 {
        int i;
-       int unit = 0;
        int warned = 0;
-       struct i2o_device *d, *b;
+       struct i2o_device *d, *b=NULL;
        struct i2o_controller *c;
        struct i2ob_device *dev;
                
@@ -1257,22 +1252,22 @@ static int i2ob_scan(int bios)
                                        bios?"Boot d":"D");
                                continue;
                        }
-                       if(unit<MAX_I2OB<<4)
+                       if(scan_unit<MAX_I2OB<<4)
                        {
                                /*
                                 * Get the device and fill in the
                                 * Tid and controller.
                                 */
-                               dev=&i2ob_dev[unit];
+                               dev=&i2ob_dev[scan_unit];
                                dev->i2odev = d;
                                dev->controller = c;
                                dev->unit = c->unit;
                                dev->tid = d->lct_data.tid;
-                               if(i2ob_install_device(c,d,unit))
+                               if(i2ob_install_device(c,d,scan_unit))
                                        printk(KERN_WARNING "Could not install I2O block device\n");
                                else
                                {
-                                       unit+=16;
+                                       scan_unit+=16;
                                        i2ob_dev_count++;
                                        /* We want to know when device goes away */
                                        i2o_device_notify_on(d, &i2o_block_handler);
@@ -1281,12 +1276,13 @@ static int i2ob_scan(int bios)
                        else
                        {
                                if(!warned++)
-                                       printk(KERN_WARNING "i2o_block: too many device, registering only %d.\n", unit>>4);
+                                       printk(KERN_WARNING "i2o_block: too many device, registering only %d.\n", scan_unit>>4);
                        }
                        i2o_release_device(d, &i2o_block_handler);
                }
                i2o_unlock_controller(c);
        }
+       return 0;
 }
 
 static void i2ob_probe(void)
index 7627e0ca89e54788ff5d37b2868b5e06e8791307..7c822b4cf2f7dcae16ecfaeb32504eafb6d3bbde 100644 (file)
@@ -5,7 +5,9 @@
 #include <linux/version.h>
 #endif
 
+#ifndef LinuxVersionCode
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+#endif
 
 #include <linux/types.h>
 #include <linux/kdev_t.h>
index bdbcd419188c9d76f40345fca8c038868d47291c..baa645a3bf5a45cd4b3df5e3c0605bf4a9cb4457 100644 (file)
@@ -75,6 +75,7 @@ extern void kcapi_init(void);
 extern void capi_init(void);
 extern void capidrv_init(void);
 #endif
+extern void act2000_init(void);
 
 void
 isdn_cards_init(void)
index 683325637bf76e337b4f9547a1d0439d2a58b316..dc5ed8781fc68ad3ea8125462f6a7b5ec15757d6 100644 (file)
@@ -76,6 +76,7 @@
  */
 
 #include <linux/ppp_defs.h>     /* for PPP_PROTOCOL */
+#include <linux/isdn_ppp.h>
 extern int isdn_ppp_read(int, struct file *, char *, int);
 extern int isdn_ppp_write(int, struct file *, const char *, int);
 extern int isdn_ppp_open(int, struct file *);
index cd608e60fdad8d07cf12e23ad7558b634d799ba2..c0c28c003cbca61c995d414678f1b94551d1869c 100644 (file)
@@ -107,6 +107,7 @@ static int pmu_fully_inited = 0;
 static int pmu_has_adb, pmu_has_backlight;
 static unsigned char *gpio_reg = NULL;
 static int gpio_irq = -1;
+static int irq_flag = 0;
 
 int asleep;
 
@@ -242,7 +243,7 @@ find_via_pmu()
 
                pmu_kind = PMU_KEYLARGO_BASED;
                pmu_has_adb = (find_type_devices("adb") != NULL);
-               pmu_has_backlight = (find_type_devices("backlight") != NULL);
+               pmu_has_backlight = 0; /* Not driven by PMU */
 
                gpiop = find_devices("gpio");
                if (gpiop && gpiop->n_addrs) {
@@ -303,6 +304,11 @@ via_pmu_init(void)
 
        /* Enable backlight */
        pmu_enable_backlight(1);
+
+       /* Make sure PMU settle down before continuing */
+       do {
+               pmu_poll();
+       } while (pmu_state != idle);
 }
 
 static int __openfirmware
@@ -632,44 +638,50 @@ via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
        int nloop = 0;
        unsigned long flags;
 
-       /* Currently, we use brute-force cli() for syncing with GPIO
-        * interrupt. I'll make this smarter later, along with some
-        * spinlocks for SMP */
-       save_flags(flags);cli();
-       ++disable_poll;
-       while ((intr = in_8(&via[IFR])) != 0) {
-               if (++nloop > 1000) {
-                       printk(KERN_DEBUG "PMU: stuck in intr loop, "
-                              "intr=%x pmu_state=%d\n", intr, pmu_state);
-                       break;
+       /* This is my 2 cents brain dead synchronisation mecanism */
+       if (test_and_set_bit(0, &irq_flag))
+               return;
+
+       while(test_and_clear_bit(0, &irq_flag)) {
+               ++disable_poll;
+               while ((intr = in_8(&via[IFR])) != 0) {
+                       if (++nloop > 1000) {
+                               printk(KERN_DEBUG "PMU: stuck in intr loop, "
+                                      "intr=%x pmu_state=%d\n", intr, pmu_state);
+                               break;
+                       }
+                       if (intr & SR_INT)
+                               pmu_sr_intr(regs);
+                       else if (intr & CB1_INT) {
+                               adb_int_pending = 1;
+                               out_8(&via[IFR], CB1_INT);
+                       }
+                       intr &= ~(SR_INT | CB1_INT);
+                       if (intr != 0) {
+                               out_8(&via[IFR], intr);
+                       }
                }
-               if (intr & SR_INT)
-                       pmu_sr_intr(regs);
-               else if (intr & CB1_INT) {
+               if (gpio_reg && (in_8(gpio_reg + 0x9) & 0x02) == 0)
                        adb_int_pending = 1;
-                       out_8(&via[IFR], CB1_INT);
-               }
-               intr &= ~(SR_INT | CB1_INT);
-               if (intr != 0) {
-                       out_8(&via[IFR], intr);
-               }
-       }
-       if (gpio_reg && (in_8(gpio_reg + 0x9) & 0x02) == 0)
-               adb_int_pending = 1;
-
-       if (pmu_state == idle) {
-               if (adb_int_pending) {
-                       pmu_state = intack;
-                       send_byte(PMU_INT_ACK);
-                       adb_int_pending = 0;
-               } else if (current_req) {
-                       pmu_start();
+
+               /* A spinlock would be nicer ... */
+               save_flags(flags);
+               cli();
+               if (pmu_state == idle) {
+                       if (adb_int_pending) {
+                               pmu_state = intack;
+                               send_byte(PMU_INT_ACK);
+                               adb_int_pending = 0;
+                       } else if (current_req) {
+                               pmu_start();
+                       }
                }
+               restore_flags(flags);
+               --disable_poll;
        }
-       --disable_poll;
-       restore_flags(flags);
 }
 
+
 static void __openfirmware
 gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
 {
index ef1a977221fcfdda9a6e4f7cc48812c08154a191..1dcff8a11ed2b65cd763d5dba15a08b0a9b1f0ac 100644 (file)
@@ -57,6 +57,7 @@ extern int eepro_probe(struct device *);
 extern int eepro100_probe(struct device *);
 extern int el3_probe(struct device *);
 extern int at1500_probe(struct device *);
+extern int bond_init(struct device *);
 extern int pcnet32_probe(struct device *);
 extern int at1700_probe(struct device *);
 extern int fmv18x_probe(struct device *);
@@ -122,6 +123,7 @@ extern int tc515_probe(struct device *dev);
 extern int lance_probe(struct device *dev);
 extern int rcpci_probe(struct device *);
 extern int dmfe_probe(struct device *);
+extern int sktr_probe(struct device *dev);
 
 /* Gigabit Ethernet adapters */
 extern int yellowfin_probe(struct device *dev);
index be84bbb6b83cb790b21723b5e991dfb5a5beeab7..9124d25ca9d3be42916675bfdb8059442226ada3 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright 1999, Thomas Davis, tadavis@lbl.gov.  
  * Licensed under the GPL. Based on dummy.c, and eql.c devices.
  *
- * bond.c: a bonding/etherchannel/sun trunking net driver
+ * bonding.c: a bonding/etherchannel/sun trunking net driver
  *
  * This is useful to talk to a Cisco 5500, running Etherchannel, aka:
  *     Linux Channel Bonding
index eb2a760cd063b09a662f221bdacb0a45fcf6e3c4..0860eb154c56d60e21b4583267d474aaba822ecd 100644 (file)
@@ -73,21 +73,21 @@ typedef struct card_s {
 typedef card_t port_t;
 
 
-#define sca_in(reg, card)           readb(card->win0base+C101_SCA+reg)
-#define sca_out(value, reg, card)    writeb(value, card->win0base+C101_SCA+reg)
-#define sca_inw(reg, card)          readw(card->win0base+C101_SCA+reg)
-#define sca_outw(value, reg, card)   writew(value, card->win0base+C101_SCA+reg)
+#define sca_in(reg, card)         readb((card)->win0base+C101_SCA+(reg))
+#define sca_out(value, reg, card)  writeb(value, (card)->win0base+C101_SCA+(reg))
+#define sca_inw(reg, card)        readw((card)->win0base+C101_SCA+(reg))
+#define sca_outw(value, reg, card) writew(value, (card)->win0base+C101_SCA+(reg))
 
 #define port_to_card(port)          (port)
 #define log_node(port)              (0)
 #define phy_node(port)              (0)
 #define winsize(card)               (C101_WINDOW_SIZE)
-#define win0base(card)              (card->win0base)
-#define winbase(card)               (card->win0base+0x2000)
-#define get_port(card, port)        (port == 0 ? card : NULL)
+#define win0base(card)              ((card)->win0base)
+#define winbase(card)               ((card)->win0base+0x2000)
+#define get_port(card, port)        ((port) == 0 ? (card) : NULL)
 
 
-static __inline__ u8 get_page(card_t *card)
+static __inline__ u8 sca_get_page(card_t *card)
 {
        return card->page;
 }
index 02b3b3634d6937339bb00dfe8f8286a378b03da2..2c60edb9ba41e4e321c919446262eb183d59d1c1 100644 (file)
@@ -846,9 +846,9 @@ static int ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev)
                                                }
                                        }
 
+                                       lp->stats.tx_bytes += skb->len;
                                        dev->trans_start = jiffies;
                                        dev_kfree_skb(skb);
-
                                } else {        /* return unused page to the free memory queue */
                                        outb(page, EWRK3_FMQ);
                                }
@@ -1029,6 +1029,7 @@ static int ewrk3_rx(struct device *dev)
                                                   ** Update stats
                                                 */
                                                lp->stats.rx_packets++;
+                                               lp->stats.rx_bytes += pkt_len;
                                                for (i = 1; i < EWRK3_PKT_STAT_SZ - 1; i++) {
                                                        if (pkt_len < i * EWRK3_PKT_BIN_SZ) {
                                                                lp->pktStats.bins[i]++;
index dd159b6be2211c7b8677ba7fe79f208808ea708d..76f92dc9b7972195d61c887444caa602b963a242 100644 (file)
@@ -290,7 +290,7 @@ gmac_set_power(struct gmac *gm, int power_up)
        if (power_up) {
                out_le32(gm->sysregs + 0x20/4,
                        in_le32(gm->sysregs + 0x20/4) | 0x02000000);
-               udelay(10);
+               udelay(20);
                if (gm->pci_devfn != 0xff) {
                        u16 cmd;
                        
@@ -310,6 +310,7 @@ gmac_set_power(struct gmac *gm, int power_up)
                gm->phy_type = 0;
                out_le32(gm->sysregs + 0x20/4,
                        in_le32(gm->sysregs + 0x20/4) & ~0x02000000);
+               udelay(20);
        }
 }
 
@@ -396,6 +397,7 @@ gmac_mac_init(struct gmac *gm, unsigned char *mac_addr)
        GM_OUT(GM_RX_CONF,
                (RX_OFFSET << GM_RX_CONF_FBYTE_OFF_SHIFT) |
                (0x22 << GM_RX_CONF_CHK_START_SHIFT) |
+               (GM_RX_CONF_DMA_THR_DEFAULT << GM_RX_CONF_DMA_THR_SHIFT) |
                NRX_CONF);
 
        /* Configure other bits of MAC */
@@ -495,6 +497,10 @@ gmac_init_rings(struct gmac *gm, int from_irq)
        ring = (struct gmac_dma_desc *) gm->txring;
        memset(ring, 0, NTX * sizeof(struct gmac_dma_desc));
 
+       gm->next_rx = 0;
+       gm->next_tx = 0;
+       gm->tx_gone = 0;
+
        /* set pointers in chip */
        mb();
        GM_OUT(GM_RX_DESC_HI, 0);
@@ -552,14 +558,13 @@ gmac_set_multicast(struct device *dev)
        unsigned long crc;
        int multicast_hash = 0;
        int multicast_all = 0;
-
+       int promisc = 0;
+       
        /* Lock out others. */
        set_bit(0, (void *) &dev->tbusy);
 
-       gm->promisc = 0;
-
        if (dev->flags & IFF_PROMISC)
-               gm->promisc = 1;
+               promisc = 1;
        else if ((dev->flags & IFF_ALLMULTI) /* || (dev->mc_count > XXX) */) {
                multicast_all = 1;
        } else {
@@ -591,7 +596,7 @@ gmac_set_multicast(struct device *dev)
                multicast_hash = 1;
        }
 
-       if (gm->promisc)
+       if (promisc)
                GM_BIS(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_RX_ALL);
        else
                GM_BIC(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_RX_ALL);
@@ -632,7 +637,6 @@ gmac_open(struct device *dev)
 
        gm->full_duplex = 0;
        gm->phy_status = 0;
-       gm->promisc = 0;
        
        /* Find a PHY */
        if (!mii_lookup_and_reset(gm))
@@ -641,12 +645,12 @@ gmac_open(struct device *dev)
        /* Configure the PHY */
        mii_setup_phy(gm);
        
-       /* Initialize the MAC */
-       gmac_mac_init(gm, dev->dev_addr);
-       
        /* Initialize the descriptor rings */
        gmac_init_rings(gm, 0);
 
+       /* Initialize the MAC */
+       gmac_mac_init(gm, dev->dev_addr);
+       
        /* Initialize the multicast tables & promisc mode if any */
        gmac_set_multicast(dev);
        
@@ -706,7 +710,7 @@ static void
 gmac_tx_timeout(struct device *dev)
 {
        struct gmac *gm = (struct gmac *) dev->priv;
-       int i;
+       int i, timeout;
        unsigned long flags;
 
        save_flags(flags);
@@ -731,8 +735,24 @@ gmac_tx_timeout(struct device *dev)
                        gm->rx_buff[i] = 0;
                }
        }
+       /* Perform a software reset */
+       GM_OUT(GM_RESET, GM_RESET_TX | GM_RESET_RX);
+       for (timeout = 100; timeout > 0; --timeout) {
+               mdelay(10);
+               if ((GM_IN(GM_RESET) & (GM_RESET_TX | GM_RESET_RX)) == 0) {
+                       /* Mask out all chips interrupts */
+                       GM_OUT(GM_IRQ_MASK, 0xffffffff);
+                       break;
+               }
+       }
+       if (!timeout)
+               printk(KERN_ERR "%s reset chip failed !\n", dev->name);
        /* Create fresh rings */
        gmac_init_rings(gm, 1);
+       /* re-initialize the MAC */
+       gmac_mac_init(gm, dev->dev_addr);       
+       /* re-initialize the multicast tables & promisc mode if any */
+       gmac_set_multicast(dev);
        /* Restart PHY auto-poll */
        mii_interrupt(gm);
        /* Restart chip */
@@ -832,10 +852,11 @@ gmac_receive(struct device *dev)
        int i = gm->next_rx;
        volatile struct gmac_dma_desc *dp;
        struct sk_buff *skb, *new_skb;
-       int len, flags, drop;
+       int len, flags, drop, last;
        unsigned char *data;
        u16 csum;
-       
+
+       last = -1;
        for (;;) {
                dp = &gm->rxring[i];
                if (ld_le32(&dp->size) & RX_SZ_OWN)
@@ -931,10 +952,15 @@ gmac_receive(struct device *dev)
                        ++gm->stats.rx_packets;
                }
                
+               last = i;
                if (++i >= NRX)
                        i = 0;
        }
        gm->next_rx = i;
+       if (last >= 0) {
+               mb();
+               GM_OUT(GM_RX_KICK, last & 0xfffffffc);
+       }
 }
 
 static void
@@ -952,7 +978,8 @@ gmac_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        }
 
        status = GM_IN(GM_IRQ_STATUS);
-       GM_OUT(GM_IRQ_ACK, status);
+       if (status & (GM_IRQ_BUS_ERROR | GM_IRQ_MIF))
+               GM_OUT(GM_IRQ_ACK, status & (GM_IRQ_BUS_ERROR | GM_IRQ_MIF));
        
        if (status & (GM_IRQ_RX_TAG_ERR | GM_IRQ_BUS_ERROR)) {
                printk(KERN_ERR "%s: IRQ Error status: 0x%08x\n",
index 859a557967d245cc5b2f7ec74c4c18d0b965c4ee..6473ec54eb1507d71d8bb609a2b79666543dd3a5 100644 (file)
 #define GM_RX_PTH_UNITS                        64
 
 /* -- 0x4100   RW      Rx Kick
- * d: 0x00000000       Written by the host with the last tx descriptor number +1 to send
- *                                     Must be a multiple of 4
+ * d: 0x00000000       The last valid RX descriptor is the one right before the value of the
+ *                      register. Initially set to 0 on reset. RX descriptors must be posted
+ *                      in multiples of 4. The first descriptor should be cache-line aligned
+ *                      for best performance.
  */
 #define GM_RX_KICK                     (0x4100 | REG_SZ_16)
 
 /* -- 0x4104   RW      Rx Completion
- * d: 0x00000000       Written by the gmac with the last tx descriptor number +1 sent
+ * d: 0x00000000       All descriptors upto but excluding the register value are ready to be
+ *                      processed by the host.
  */
 #define GM_RX_COMP                     (0x4104 | REG_SZ_16)
  
  *
  * Defines the values used for receive interrupt blanking.
  * For INTR_TIME field, every count is 2048 PCI clock time. For 66 Mhz, each
- * count is about 16 us.
+ * count is about 15 ns.
  */
 #define GM_RX_BLANK                    (0x4108 | REG_SZ_32)
                        /*
 
 /* -- 0x4120   RO      Rx fifo size
  *
- * This 11-bit RO register indicates the size, in 64-bit multiples, of the
+ * This 11-bit RO register indicates the size, in 64-byte multiples, of the
  * RX FIFO. Software should use it to properly configure the PAUSE thresholds.
  * The value read is 0x140, indicating a 20kbyte RX FIFO.
  * -------------------------------------------------------------------------
@@ -842,7 +845,6 @@ struct gmac {
        int                             phy_type;
        int                             phy_status;     /* Cached PHY status */
        int                             full_duplex;    /* Current set to full duplex */
-       int                             promisc;
        struct net_device_stats         stats;
        u8                              pci_bus;
        u8                              pci_devfn;
index 1f8149eaf020f144c0b981f73bf65d7fb14ae917..e916f7d70a798fa41ef72b705a2650eaca853536 100644 (file)
@@ -406,7 +406,7 @@ static void sca_intr(int irq, void* dev_id, struct pt_regs *regs)
        u8 stat;
 
 #ifndef ALL_PAGES_ALWAYS_MAPPED
-       u8 page = get_page(card);
+       u8 page = sca_get_page(card);
 #endif
   
        while((stat = sca_intr_status(card)) != 0) {
@@ -606,7 +606,7 @@ static int sca_ioctl(hdlc_device *hdlc, struct ifreq *ifr, int cmd)
 #ifdef DEBUG_RINGS
        default:
 #if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED)
-               page=get_page(card);
+               page=sca_get_page(card);
                openwin(card, 0);
 #endif
 
index f3718082c03285e42419c4668c20aed99db9d334..53d11427576510a85367e374b82927a7f6641a05 100644 (file)
@@ -41,7 +41,7 @@
 #ifndef MODULE
 static int version_printed=0;
 #endif
-static const char* version = "HDLC support routines revision: 1.0a1";
+static const char* version = "HDLC support routines revision: 1.0";
 
 
 #define CISCO_MULTICAST         0x8f    /* Cisco multicast address */
@@ -69,7 +69,10 @@ static int cisco_hard_header(struct sk_buff *skb, struct device *dev, u16 type,
        
        skb_push(skb, sizeof(hdlc_header));
        data=(hdlc_header*)skb->data;
-       data->address = CISCO_MULTICAST;
+       if (type == CISCO_KEEPALIVE)
+               data->address = CISCO_MULTICAST;
+       else
+               data->address = CISCO_UNICAST;
        data->control = 0;
        data->protocol = htons(type);
        
@@ -1025,20 +1028,9 @@ static int hdlc_set_mode(hdlc_device *hdlc, int mode)
 
                switch(mode & ~MODE_SOFT) {
                case MODE_CISCO:
-                       result = hdlc->set_mode ?
-                               hdlc->set_mode(hdlc, MODE_HDLC) : 0;
-                       break;
-
                case MODE_PPP:
-                       result = hdlc->set_mode ?
-                               hdlc->set_mode(hdlc, MODE_PPP) : 0;
-                       break;
-       
-               case MODE_X25:
-                       result = hdlc->set_mode ?
-                               hdlc->set_mode(hdlc, MODE_X25) : 0;
                        break;
-       
+
                case MODE_FR_ANSI:
                case MODE_FR_CCITT:
                case MODE_FR_ANSI  | MODE_DCE:
@@ -1046,13 +1038,14 @@ static int hdlc_set_mode(hdlc_device *hdlc, int mode)
                        hdlc_to_dev(hdlc)->addr_len=2;
                        *(u16*)hdlc_to_dev(hdlc)->dev_addr=htons(LMI_DLCI);
                        dlci_to_q922(hdlc_to_dev(hdlc)->broadcast, LMI_DLCI);
-                       result = hdlc->set_mode ?
-                               hdlc->set_mode(hdlc, MODE_HDLC) : 0;
                        break;
 
                default:
                        return -EINVAL;
                }
+
+               result = hdlc->set_mode ?
+                       hdlc->set_mode(hdlc, MODE_HDLC) : 0;
        }
 
        if (result)
index 81045317cf9185ffb47d929aac8a4e6774f72e70..1b494ccb884693f640833877fd215a1f790fd7aa 100644 (file)
@@ -122,23 +122,23 @@ typedef struct card_s {
 
 
 
-#define sca_reg(reg, card) (0x8000 | card->io | \
+#define sca_reg(reg, card) (0x8000 | (card)->io | \
                            ((reg)&0x0F) | (((reg)&0xF0) << 6))
 #define sca_in(reg, card)              readb(sca_reg(reg, card))
 #define sca_out(value, reg, card)      writeb(value, sca_reg(reg, card))
 #define sca_inw(reg, card)             readw(sca_reg(reg, card))
 #define sca_outw(value, reg, card)     writew(value, sca_reg(reg, card))
 
-#define port_to_card(port)             (port->card)
-#define log_node(port)                 (port->log_node)
-#define phy_node(port)                 (port->phy_node)
+#define port_to_card(port)             ((port)->card)
+#define log_node(port)                 ((port)->log_node)
+#define phy_node(port)                 ((port)->phy_node)
 #define winsize(card)                  (USE_WINDOWSIZE)
-#define winbase(card)                  (card->winbase)
-#define get_port(card, port)           (card->ports[port].valid ? \
-                                        &card->ports[port] : NULL)
+#define winbase(card)                  ((card)->winbase)
+#define get_port(card, port)           ((card)->ports[port].valid ? \
+                                        &(card)->ports[port] : NULL)
 
 
-static __inline__ u8 get_page(card_t *card)
+static __inline__ u8 sca_get_page(card_t *card)
 {
        return inb(card->io+N2_PSR) & PSR_PAGEBITS;
 }
index 735751dde392478a6ea34ffcb608f21fb05ed244..558c03090b01253c46b0731b7aa7cc2d8365c258 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <net/slhc_vj.h>
 
 #ifdef CONFIG_INET
 /* Entire module is for IP only */
@@ -79,7 +80,6 @@
 #include <asm/uaccess.h>
 #include <linux/mm.h>
 #include <net/checksum.h>
-#include <net/slhc_vj.h>
 #include <asm/unaligned.h>
 
 int last_retran;
index 11728ea9bc18c8d41009e44e908a64ced7c7afaf..ad50c7accb4c5ed7634cf5347695d8d4e02c87cb 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/tasks.h>
 #include <linux/parport.h>
+#include <linux/parport_pc.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
index 88fdfd6bd1224e7730e17224e12be519fd28dded..e1fb8e0a0d291afd599ea447cdc0a9b06f29e138 100644 (file)
@@ -2,6 +2,8 @@
    3w-xxxx.c -- 3ware Storage Controller device driver for Linux.
 
    Written By: Adam Radford <linux@3ware.com>
+   Modifications By: Joel Jacobson <linux@3ware.com>
+
    Copyright (C) 1999-2000 3ware Inc.
 
    Kernel compatablity By:     Andre Hedrick <andre@suse.com>
 
    For more information, goto:
    http://www.3ware.com
+
+   History
+   -------
+   0.1.000 -     Initial release.
+   0.4.000 -     Added support for Asynchronous Event Notification through
+                 ioctls for 3DM.
+   1.0.000 -     Added DPO & FUA bit support for WRITE_10 & WRITE_6 cdb
+                 to disable drive write-cache before writes.
+   1.1.000 -     Fixed performance bug with DPO & FUA not existing for WRITE_6.
+   1.2.000 -     Added support for clean shutdown notification/feature table.
+   1.02.00.001 - Added support for full command packet posts through ioctls
+                 for 3DM.
+                 Bug fix so hot spare drives don't show up.
 */
 
 #include <linux/module.h>
@@ -65,6 +80,7 @@ MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver");
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/smp.h>
+#include <linux/reboot.h>
 
 #include <asm/spinlock.h>
 #include <asm/errno.h>
@@ -83,6 +99,12 @@ MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver");
 static int tw_copy_info(TW_Info *info, char *fmt, ...);
 static void tw_copy_mem_info(TW_Info *info, char *data, int len);
 static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static int tw_halt(struct notifier_block *nb, ulong event, void *buf);
+
+/* Notifier block to get a notify on system shutdown/halt/reboot */
+static struct notifier_block tw_notifier = {
+  tw_halt, NULL, 0
+};
 
 struct proc_dir_entry tw_scsi_proc_entry = {
        PROC_SCSI_3W_XXXX,
@@ -91,7 +113,7 @@ struct proc_dir_entry tw_scsi_proc_entry = {
 };
 
 /* Globals */
-char *tw_driver_version="1.1.000";
+char *tw_driver_version="1.02.00.001";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -230,7 +252,7 @@ int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
                                if (command_packet->status != 0) {
                                        if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
                                                /* Bad response */
-                                               printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, flags = 0x%x.\n", command_packet->flags);
+                                               printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
                                                return 1;
                                        } else {
                                                /* We know this is a 3w-1x00, and doesn't support aen's */
@@ -568,6 +590,7 @@ int tw_findcards(Scsi_Host_Template *tw_host)
        TW_Device_Extension *tw_dev2;
        struct pci_dev *tw_pci_dev = pci_devices;
        u32 status_reg_value;
+       unsigned char c = 1;
 
        dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
        while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, TW_DEVICE_ID, tw_pci_dev))) {
@@ -666,7 +689,7 @@ int tw_findcards(Scsi_Host_Template *tw_host)
                        continue;
                }
 
-               error = tw_initconnection(tw_dev);
+               error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
                if (error) {
                        printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initconnection for card %d.\n", numcards);
                        release_region((tw_dev->tw_pci_dev->base_address[0]), TW_IO_ADDRESS_RANGE);
@@ -726,10 +749,14 @@ int tw_findcards(Scsi_Host_Template *tw_host)
                /* Free the temporary device extension */
                if (tw_dev)
                        kfree(tw_dev);
+               /* Tell the firmware we support shutdown notification*/
+               tw_setfeature(tw_dev, 2, 1, &c);
        }
 
        if (numcards == 0) 
                printk(KERN_WARNING "3w-xxxx: tw_findcards(): No cards found.\n");
+       else
+         register_reboot_notifier(&tw_notifier);
 
        return numcards;
 } /* End tw_findcards() */
@@ -751,8 +778,22 @@ void tw_free_device_extension(TW_Device_Extension *tw_dev)
        }
 } /* End tw_free_device_extension() */
 
+/* Clean shutdown routine */
+static int tw_halt(struct notifier_block *nb, ulong event, void *buf)
+{
+       int i;
+       
+       for (i=0;i<tw_device_extension_count;i++) {
+               printk(KERN_NOTICE "3w-xxxx: Notifying card #%d\n", i);
+               tw_shutdown_device(tw_device_extension_list[i]);
+       }
+       unregister_reboot_notifier(&tw_notifier);
+       
+       return NOTIFY_OK;
+} /* End tw_halt() */
+
 /* This function will send an initconnection command to controller */
-int tw_initconnection(TW_Device_Extension *tw_dev) 
+int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits
 {
        u32 command_que_addr, command_que_value;
        u32 status_reg_addr, status_reg_value;
@@ -784,7 +825,7 @@ int tw_initconnection(TW_Device_Extension *tw_dev)
        command_packet->byte3.host_id = 0x0;
        command_packet->status = 0x0;
        command_packet->flags = 0x0;
-       command_packet->byte6.message_credits = TW_INIT_MESSAGE_CREDITS
+       command_packet->byte6.message_credits = message_credits
        command_packet->byte8.init_connection.response_queue_pointer = 0x0;
        command_que_value = tw_dev->command_packet_physical_address[request_id];
 
@@ -815,7 +856,7 @@ int tw_initconnection(TW_Device_Extension *tw_dev)
                        }
                        if (command_packet->status != 0) {
                                /* bad response */
-                               printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, flags = 0x%x.\n", command_packet->flags);
+                               printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
                                return 1;
                        }
                        break;  /* Response was okay, so we exit */
@@ -962,7 +1003,7 @@ int tw_initialize_units(TW_Device_Extension *tw_dev)
                        }
                        if (command_packet->status != 0) {
                                /* bad response */
-                               printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, flags = 0x%x.\n", command_packet->flags);
+                               printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
                                return 1;
                        }
                        found = 1;
@@ -984,9 +1025,11 @@ int tw_initialize_units(TW_Device_Extension *tw_dev)
                if (is_unit_present[i] == 0) {
                        tw_dev->is_unit_present[i] = FALSE;
                } else {
+                 if (is_unit_present[i] & TW_UNIT_ONLINE) {
                        dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): Unit %d found.\n", i);
                        tw_dev->is_unit_present[i] = TRUE;
                        num_units++;
+                 }
                }
        }
        tw_dev->num_units = num_units;
@@ -1090,7 +1133,7 @@ static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                                request_id = response_que.u.response_id;
                                command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
                                if (command_packet->status != 0) {
-                                       printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, flags = 0x%x.\n", command_packet->flags);
+                                       printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
                                }
                                if (tw_dev->state[request_id] != TW_S_POSTED) {
                                        printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", request_id, command_packet->byte0.opcode);
@@ -1186,7 +1229,7 @@ int tw_ioctl(TW_Device_Extension *tw_dev, int request_id)
        /* Initialize command packet */
        command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
        if (command_packet == NULL) {
-               printk(KERN_WARNING "3w-xxxx: twioctl(): Bad command packet virtual address.\n");
+               printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad command packet virtual address.\n");
                tw_dev->state[request_id] = TW_S_COMPLETED;
                tw_state_request_finish(tw_dev, request_id);
                tw_dev->srb[request_id]->result = (DID_OK << 16);
@@ -1256,6 +1299,12 @@ int tw_ioctl(TW_Device_Extension *tw_dev, int request_id)
                        tw_dev->srb[request_id]->result = (DID_OK << 16);
                        tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
                        return 0;
+               case TW_CMD_PACKET:
+                 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
+                 command_packet->request_id = request_id;
+                 tw_post_command_packet(tw_dev, request_id);
+               
+                 return 0;
                default:
                        printk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
                        tw_dev->state[request_id] = TW_S_COMPLETED;
@@ -1480,7 +1529,7 @@ int tw_reset_sequence(TW_Device_Extension *tw_dev)
                return 1;
        }
 
-       error = tw_initconnection(tw_dev);
+       error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
        if (error) {
                printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
                return 1;
@@ -1804,6 +1853,11 @@ int tw_scsi_release(struct Scsi_Host *tw_host)
        /* Tell kernel scsi-layer we are gone */
        scsi_unregister(tw_host);
 
+       /* Fake like we just shut down, so notify the card that
+        * we "shut down cleanly".
+        */
+       tw_halt(0, 0, 0);  // parameters aren't actually used
+
        return 0;
 } /* End tw_scsi_release() */
 
@@ -1901,8 +1955,10 @@ int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
                if (is_unit_present[i] == 0) {
                        tw_dev->is_unit_present[i] = FALSE;
                } else {
+                 if (is_unit_present[i] & TW_UNIT_ONLINE) {
                        tw_dev->is_unit_present[i] = TRUE;
                        dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete: Unit %d found.\n", i);
+                 }
                }
        }
 
@@ -2125,6 +2181,92 @@ int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
        return 0;
 } /* End tw_scsiop_test_unit_ready() */
 
+/* Set a value in the features table */
+int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
+                  unsigned char *val)
+{
+       TW_Param *param;
+       TW_Command  *command_packet;
+       TW_Response_Queue response_queue;
+       int request_id = 0;
+       u32 command_que_value, command_que_addr;
+       u32 status_reg_addr, status_reg_value;
+       u32 response_que_addr;
+       u32 param_value;
+       int imax, i;
+
+       /* Initialize SetParam command packet */
+       if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
+               printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
+               return 1;
+       }
+       command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+       memset(command_packet, 0, sizeof(TW_Sector));
+       param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+
+       command_packet->byte0.opcode = TW_OP_SET_PARAM;
+       command_packet->byte0.sgl_offset  = 2;
+       param->table_id = 0x404;  /* Features table */
+       param->parameter_id = parm;
+       param->parameter_size_bytes = param_size;
+       memcpy(param->data, val, param_size);
+
+       param_value = tw_dev->alignment_physical_address[request_id];
+       if (param_value == 0) {
+               printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
+               tw_dev->state[request_id] = TW_S_COMPLETED;
+               tw_state_request_finish(tw_dev, request_id);
+               tw_dev->srb[request_id]->result = (DID_OK << 16);
+               tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+       }
+       command_packet->byte8.param.sgl[0].address = param_value;
+       command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+
+       command_packet->size = 4;
+       command_packet->request_id = request_id;
+       command_packet->byte6.parameter_count = 1;
+
+       command_que_value = tw_dev->command_packet_physical_address[request_id];
+       if (command_que_value == 0) {
+               printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
+               return 1;
+       }
+       command_que_addr = tw_dev->registers.command_que_addr;
+       status_reg_addr = tw_dev->registers.status_reg_addr;
+       response_que_addr = tw_dev->registers.response_que_addr;
+
+       /* Send command packet to the board */
+       outl(command_que_value, command_que_addr);
+
+       /* Poll for completion */
+       imax = TW_POLL_MAX_RETRIES;
+       for (i=0;i<imax;i++) {
+               mdelay(10);
+               status_reg_value = inl(status_reg_addr);
+               if (tw_check_bits(status_reg_value)) {
+                       printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n");
+                       return 1;
+               }
+               if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+                       response_queue.value = inl(response_que_addr);
+                       request_id = (unsigned char)response_queue.u.response_id;
+                       if (request_id != 0) {
+                               /* unexpected request id */
+                               printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
+                               return 1;
+                       }
+                       if (command_packet->status != 0) {
+                               /* bad response */
+                               printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
+                               return 1;
+                       }
+                       break; /* Response was okay, so we exit */
+               }
+       }
+
+       return 0;
+} /* End tw_setfeature() */
+
 /* This function will setup the interrupt handler */
 int tw_setup_irq(TW_Device_Extension *tw_dev)
 {
@@ -2141,6 +2283,29 @@ int tw_setup_irq(TW_Device_Extension *tw_dev)
        return 0;
 } /* End tw_setup_irq() */
 
+/* This function will tell the controller we're shutting down by sending
+   initconnection with a 1 */
+int tw_shutdown_device(TW_Device_Extension *tw_dev)
+{
+       int error;
+
+       /* Disable interrupts */
+       tw_disable_interrupts(tw_dev);
+
+       /* poke the board */
+       error = tw_initconnection(tw_dev, 1);
+       if (error) {
+               printk(KERN_WARNING "3w-xxxx: tw_shutdown_device(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
+       } else {
+               printk(KERN_NOTICE "3w-xxxx shutdown succeeded\n");
+       }
+
+       /* Re-enable interrupts */
+       tw_enable_interrupts(tw_dev);
+
+       return 0;
+} /* End tw_shutdown_device() */
+
 /* This function will soft reset the controller */
 void tw_soft_reset(TW_Device_Extension *tw_dev) 
 {
index b3989c71cf48920b323fa682010ce55480acafaf..a48dc9ea8801f5214a0905a687fc6e8cc1c45720 100644 (file)
@@ -2,7 +2,9 @@
    3w-xxxx.h -- 3ware Storage Controller device driver for Linux.
    
    Written By: Adam Radford <linux@3ware.com>
-   Copyright (C) 1999 3ware Inc.
+   Modifications By: Joel Jacobson <linux@3ware.com>
+
+   Copyright (C) 1999, 2000 3ware Inc.
 
    Kernel compatablity By:     Andre Hedrick <andre@suse.com>
    Non-Copyright (C) 2000      Andre Hedrick <andre@suse.com>
 #define TW_OP_SET_PARAM              0x13
 #define TW_OP_SECTOR_INFO     0x1a
 #define TW_OP_AEN_LISTEN      0x1c
+#define TW_CMD_PACKET         0x1d
 
 /* Asynchronous Event Notification (AEN) Codes */
 #define TW_AEN_QUEUE_EMPTY       0x0000
 #define TW_BLOCK_SIZE                        0x200 /* 512-byte blocks */
 #define TW_IOCTL                              0x80
 #define TW_MAX_AEN_TRIES                      100
-
+#define TW_UNIT_ONLINE                        1
 #define TW_IN_INTR                            1
 
 /* Macros */
@@ -305,7 +308,7 @@ int tw_empty_response_que(TW_Device_Extension *tw_dev);
 void tw_enable_interrupts(TW_Device_Extension *tw_dev);
 int tw_findcards(Scsi_Host_Template *tw_host);
 void tw_free_device_extension(TW_Device_Extension *tw_dev);
-int tw_initconnection(TW_Device_Extension *tw_dev);
+int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits);
 int tw_initialize_device_extension(TW_Device_Extension *tw_dev);
 int tw_initialize_units(TW_Device_Extension *tw_dev);
 int tw_ioctl(TW_Device_Extension *tw_dev, int request_id);
@@ -328,7 +331,9 @@ int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id);
+int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size, unsigned char *val);
 int tw_setup_irq(TW_Device_Extension *tw_dev);
+int tw_shutdown_device(TW_Device_Extension *tw_dev);
 void tw_soft_reset(TW_Device_Extension *tw_dev);
 int tw_state_request_finish(TW_Device_Extension *tw_dev,int request_id);
 int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id);
@@ -351,6 +356,8 @@ void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev);
        eh_strategy_handler : NULL,                     \
        eh_abort_handler : tw_scsi_eh_abort,            \
        eh_device_reset_handler : NULL,                 \
+        eh_bus_reset_handler : NULL,                    \
+        eh_host_reset_handler : tw_scsi_eh_reset,       \
        abort : NULL,                                   \
        reset : NULL,                                   \
        slave_attach : NULL,                            \
index bce089b6ad2f1dac5a2d00248a5d2c7917712b9d..f1e1da24e19c075761473923c9f5656f73e0e1c6 100644 (file)
@@ -915,7 +915,7 @@ static inline int port_detect \
    if (info.sign != EATA_SIGNATURE) return FALSE;
 
    if (DEV2H(info.data_len) < EATA_2_0A_SIZE) {
-      printk("%s: config structure size (%ld bytes) too short, detaching.\n",
+      printk("%s: config structure size (%d bytes) too short, detaching.\n",
              name, DEV2H(info.data_len));
       return FALSE;
       }
index fa8844b673eb355223680f3992331fef7d85582b..b15bc75f839961d68f8f151c70b09a8b94b20f67 100644 (file)
@@ -32,6 +32,7 @@ static int device_check(int host_no);
 typedef struct {
     struct pardevice *dev;     /* Parport device entry         */
     int base;                  /* Actual port address          */
+    int base_hi;               /* Hi Base address for ECP-ISA chipset */
     int mode;                  /* Transfer mode                */
     int host;                  /* Host number (for proc)       */
     Scsi_Cmnd *cur_cmd;                /* Current queued command       */
@@ -46,6 +47,7 @@ typedef struct {
 #define IMM_EMPTY \
 {      dev:            NULL,           \
        base:           -1,             \
+       base_hi:        0,              \
        mode:           IMM_AUTODETECT, \
        host:           -1,             \
        cur_cmd:        NULL,           \
@@ -63,6 +65,7 @@ static imm_struct imm_hosts[NO_HOSTS] =
 {IMM_EMPTY, IMM_EMPTY, IMM_EMPTY, IMM_EMPTY};
 
 #define IMM_BASE(x)    imm_hosts[(x)].base
+#define IMM_BASE_HI(x)     imm_hosts[(x)].base_hi
 
 int parbus_base[NO_HOSTS] =
 {0x03bc, 0x0378, 0x0278, 0x0000};
@@ -133,7 +136,7 @@ int imm_detect(Scsi_Host_Template * host)
     }
   retry_entry:
     for (i = 0; pb; i++, pb = pb->next) {
-       int modes, ppb;
+       int modes, ppb, ppb_hi;
 
        imm_hosts[i].dev =
            parport_register_device(pb, "imm", NULL, imm_wakeup,
@@ -158,6 +161,7 @@ int imm_detect(Scsi_Host_Template * host)
            }
        }
        ppb = IMM_BASE(i) = imm_hosts[i].dev->port->base;
+       ppb_hi = IMM_BASE_HI(i) = imm_hosts[i].dev->port->base_hi;
        w_ctr(ppb, 0x0c);
        modes = imm_hosts[i].dev->port->modes;
 
@@ -169,12 +173,12 @@ int imm_detect(Scsi_Host_Template * host)
        if (modes & PARPORT_MODE_PCPS2)
            imm_hosts[i].mode = IMM_PS2;
 
-       if (modes & PARPORT_MODE_PCECPPS2) {
-           w_ecr(ppb, 0x20);
+       if (ppb_hi && modes & PARPORT_MODE_PCECPPS2) {
+           w_ecr(ppb_hi, 0x20);
            imm_hosts[i].mode = IMM_PS2;
        }
-       if (modes & PARPORT_MODE_PCECPEPP)
-           w_ecr(ppb, 0x80);
+       if (ppb_hi && modes & PARPORT_MODE_PCECPEPP)
+           w_ecr(ppb_hi, 0x80);
 
        /* Done configuration */
        imm_pb_release(i);
@@ -381,6 +385,9 @@ static int imm_negotiate(imm_struct * tmp)
     return a;
 }
 
+/* 
+ * Clear EPP timeout bit. 
+ */
 static inline void epp_reset(unsigned short ppb)
 {
     int i;
@@ -390,19 +397,23 @@ static inline void epp_reset(unsigned short ppb)
     w_str(ppb, i & 0xfe);
 }
 
-static inline void ecp_sync(unsigned short ppb)
+/* 
+ * Wait for empty ECP fifo (if we are in ECP fifo mode only)
+ */
+static inline void ecp_sync(unsigned short hostno)
 {
-    int i;
+    int i, ppb_hi=IMM_BASE_HI(hostno);
 
-    if ((r_ecr(ppb) & 0xe0) != 0x80)
-       return;
+    if (ppb_hi == 0) return;
 
-    for (i = 0; i < 100; i++) {
-       if (r_ecr(ppb) & 0x01)
-           return;
-       udelay(5);
+    if ((r_ecr(ppb_hi) & 0xe0) == 0x60) { /* mode 011 == ECP fifo mode */
+        for (i = 0; i < 100; i++) {
+           if (r_ecr(ppb_hi) & 0x01)
+               return;
+           udelay(5);
+       }
+        printk("imm: ECP sync failed as data still present in FIFO.\n");
     }
-    printk("imm: ECP sync failed as data still present in FIFO.\n");
 }
 
 static int imm_byte_out(unsigned short base, const char *buffer, int len)
@@ -490,7 +501,7 @@ static int imm_out(int host_no, char *buffer, int len)
        w_ctr(ppb, 0xc);
        r = !(r_str(ppb) & 0x01);
        w_ctr(ppb, 0xc);
-       ecp_sync(ppb);
+       ecp_sync(host_no);
        break;
 
     case IMM_NIBBLE:
@@ -552,7 +563,7 @@ static int imm_in(int host_no, char *buffer, int len)
        w_ctr(ppb, 0x2c);
        r = !(r_str(ppb) & 0x01);
        w_ctr(ppb, 0x2c);
-       ecp_sync(ppb);
+       ecp_sync(host_no);
        break;
 
     default:
@@ -1246,7 +1257,7 @@ static int device_check(int host_no)
            return 1;
        }
        imm_disconnect(host_no);
-       printk("imm: Communication established with ID %i using %s\n", loop,
+       printk("imm: Communication established at 0x%x with ID %i using %s\n", ppb, loop,
               IMM_MODE_STRING[imm_hosts[host_no].mode]);
        imm_connect(host_no, CONNECT_EPP_MAYBE);
        imm_reset_pulse(IMM_BASE(host_no));
index feba4c773cb74d83aced9fd94fed8425961226eb..909f46e16deefdeb351ae3ea0ca446562b7ca434 100644 (file)
@@ -125,14 +125,15 @@ int imm_sg = SG_ALL;              /* enable/disable scatter-gather. */
 #define r_str(x)        (unsigned char)inb((x)+1)
 #define r_ctr(x)        (unsigned char)inb((x)+2)
 #define r_epp(x)        (unsigned char)inb((x)+4)
-#define r_fifo(x)       (unsigned char)inb((x)+0x400)
-#define r_ecr(x)        (unsigned char)inb((x)+0x402)
+#define r_fifo(x)       (unsigned char)inb((x))   /* x must be base_hi */
+                                       /* On PCI is: base+0x400 != base_hi */
+#define r_ecr(x)        (unsigned char)inb((x)+2) /* x must be base_hi */
 
 #define w_dtr(x,y)      outb(y, (x))
 #define w_str(x,y)      outb(y, (x)+1)
 #define w_epp(x,y)      outb(y, (x)+4)
-#define w_fifo(x,y)     outb(y, (x)+0x400)
-#define w_ecr(x,y)      outb(y, (x)+0x402)
+#define w_fifo(x,y)     outb(y, (x))     /* x must be base_hi */
+#define w_ecr(x,y)      outb(y, (x)+0x2) /* x must be base_hi */
 
 #ifdef CONFIG_SCSI_IZIP_SLOW_CTR
 #define w_ctr(x,y)      outb_p(y, (x)+2)
index 189d0c4141b84523273dd322bec4c347777a6de1..23c401192888dd6d78cf8a360d53eb0d21f4545d 100644 (file)
@@ -175,7 +175,9 @@ extern int i91u_biosparam(Disk *, int, int *);      /*for linux v1.13 */
 #endif
 
 
+#ifndef VIRT_TO_BUS
 #define VIRT_TO_BUS(i)  (unsigned int) virt_to_bus((void *)(i))
+#endif
 #define ULONG   unsigned long
 #define USHORT  unsigned short
 #define UCHAR   unsigned char
index 1ef0f82845e192960b8e6d74888fbd5e665a9e82..6ad90d4cf9d55379826448143de0d3053e97ba69 100644 (file)
@@ -168,7 +168,9 @@ ENABLE_CLUSTERING \
 #endif
 #endif
 
+#ifndef VIRT_TO_BUS
 #define VIRT_TO_BUS(i)  (unsigned int) virt_to_bus((void *)(i))
+#endif
 #define ULONG   unsigned long
 #define PVOID   void *
 #define USHORT  unsigned short
index 5904c881cf47b5379d48131685a1ceb729614f09..8eb8d489e3285a132b0d86da6eb0e8ddcf9e1ee0 100644 (file)
@@ -125,7 +125,7 @@ int ppa_detect(Scsi_Host_Template * host)
     }
   retry_entry:
     for (i = 0; pb; i++, pb = pb->next) {
-       int modes, ppb;
+       int modes, ppb, ppb_hi;
 
        ppa_hosts[i].dev =
            parport_register_device(pb, "ppa", NULL, ppa_wakeup,
@@ -150,6 +150,7 @@ int ppa_detect(Scsi_Host_Template * host)
            }
        }
        ppb = PPA_BASE(i) = ppa_hosts[i].dev->port->base;
+       ppb_hi =  ppa_hosts[i].dev->port->base_hi;
        w_ctr(ppb, 0x0c);
        modes = ppa_hosts[i].dev->port->modes;
 
@@ -162,11 +163,11 @@ int ppa_detect(Scsi_Host_Template * host)
            ppa_hosts[i].mode = PPA_PS2;
 
        if (modes & PARPORT_MODE_PCECPPS2) {
-           w_ecr(ppb, 0x20);
+           w_ecr(ppb_hi, 0x20);
            ppa_hosts[i].mode = PPA_PS2;
        }
        if (modes & PARPORT_MODE_PCECPEPP)
-           w_ecr(ppb, 0x80);
+           w_ecr(ppb_hi, 0x80);
 
        /* Done configuration */
        ppa_pb_release(i);
@@ -322,8 +323,7 @@ static unsigned char ppa_wait(int host_no)
 }
 
 /*
- * output a string, in whatever mode is available, according to the
- * PPA protocol. 
+ * Clear EPP Timeout Bit 
  */
 static inline void epp_reset(unsigned short ppb)
 {
@@ -334,19 +334,23 @@ static inline void epp_reset(unsigned short ppb)
     w_str(ppb, i & 0xfe);
 }
 
-static inline void ecp_sync(unsigned short ppb)
+/* 
+ * Wait for empty ECP fifo (if we are in ECP fifo mode only)
+ */
+static inline void ecp_sync(unsigned short hostno)
 {
-    int i;
+    int i, ppb_hi=ppa_hosts[hostno].dev->port->base_hi;
 
-    if ((r_ecr(ppb) & 0xe0) != 0x80)
-       return;
+    if (ppb_hi == 0) return;
 
-    for (i = 0; i < 100; i++) {
-       if (r_ecr(ppb) & 0x01)
-           return;
-       udelay(5);
+    if ((r_ecr(ppb_hi) & 0xe0) == 0x60) { /* mode 011 == ECP fifo mode */
+        for (i = 0; i < 100; i++) {
+            if (r_ecr(ppb_hi) & 0x01)
+                return;
+            udelay(5);
+        }
+        printk("ppa: ECP sync failed as data still present in FIFO.\n");
     }
-    printk("ppa: ECP sync failed as data still present in FIFO.\n");
 }
 
 static int ppa_byte_out(unsigned short base, const char *buffer, int len)
@@ -421,7 +425,7 @@ static int ppa_out(int host_no, char *buffer, int len)
        w_ctr(ppb, 0xc);
        r = !(r_str(ppb) & 0x01);
        w_ctr(ppb, 0xc);
-       ecp_sync(ppb);
+       ecp_sync(host_no);
        break;
 
     default:
@@ -474,7 +478,7 @@ static int ppa_in(int host_no, char *buffer, int len)
        w_ctr(ppb, 0x2c);
        r = !(r_str(ppb) & 0x01);
        w_ctr(ppb, 0x2c);
-       ecp_sync(ppb);
+       ecp_sync(host_no);
        break;
 
     default:
index 58aba3473e29d25cb0b8a0cdc7be418d0f1663cf..618cf518a3e39a14853cefe6623f17ddf5a86927 100644 (file)
@@ -117,14 +117,15 @@ int ppa_sg = SG_ALL;              /* enable/disable scatter-gather. */
 #define r_str(x)        (unsigned char)inb((x)+1)
 #define r_ctr(x)        (unsigned char)inb((x)+2)
 #define r_epp(x)        (unsigned char)inb((x)+4)
-#define r_fifo(x)       (unsigned char)inb((x)+0x400)
-#define r_ecr(x)        (unsigned char)inb((x)+0x402)
+#define r_fifo(x)       (unsigned char)inb((x)) /* x must be base_hi */
+                                       /* On PCI is base+0x400 != base_hi */
+#define r_ecr(x)        (unsigned char)inb((x)+0x2) /* x must be base_hi */
 
 #define w_dtr(x,y)      outb(y, (x))
 #define w_str(x,y)      outb(y, (x)+1)
 #define w_epp(x,y)      outb(y, (x)+4)
-#define w_fifo(x,y)     outb(y, (x)+0x400)
-#define w_ecr(x,y)      outb(y, (x)+0x402)
+#define w_fifo(x,y)     outb(y, (x))   /* x must be base_hi */
+#define w_ecr(x,y)      outb(y, (x)+0x2)/* x must be base_hi */
 
 #ifdef CONFIG_SCSI_IZIP_SLOW_CTR
 #define w_ctr(x,y)      outb_p(y, (x)+2)
index e31230b7e440686eadfb575b80c74193a55b61b8..6c0030146b85f0dc4b9204414c594f5e93ae4722 100644 (file)
@@ -403,6 +403,7 @@ int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
        return ioctl_probe(dev->host, arg);
     case SCSI_IOCTL_SEND_COMMAND:
        if(!capable(CAP_SYS_ADMIN))  return -EACCES;
+       if(!capable(CAP_SYS_RAWIO))  return -EACCES;
        return scsi_ioctl_send_command((Scsi_Device *) dev,
                                       (Scsi_Ioctl_Command *) arg);
     case SCSI_IOCTL_DOORLOCK:
index af47e706c70e76864b04d9a4fcebaf2be03de211..25964d64c4a9877e21e5a8db906643d08ca19dae 100644 (file)
 #include "constants.h"
 #include "sd.h"
 #include <linux/stat.h>
+#include <scsi/scsicam.h>
 
 #include "dc390.h"
 
index fa2ffaef50f2fa44d58e1e651da06da58ed7ed7e..83bf380ffcc23e94cc36d7335988b33ebe6b9738 100644 (file)
@@ -61,7 +61,7 @@ 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_YMPCI)      += ymf_sb.o sb.o uart401.o ac97.o
+obj-$(CONFIG_SOUND_YMPCI)      += ymfsb.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
@@ -105,7 +105,7 @@ endif
 # Declare multi-part drivers.
 
 list-multi     := sound.o gus.o pas2.o sb.o softoss2.o vidc_mod.o \
-    soundcore.o wavefront.o nm256.o via82cxxx.o \
+    soundcore.o wavefront.o nm256.o ymfsb.o via82cxxx.o \
 
 sound-objs     :=                                                      \
     dev_table.o soundcard.o sound_syms.o               \
@@ -123,7 +123,8 @@ softoss2-objs       := softoss.o softoss_rs.o
 vidc_mod-objs  := vidc.o vidc_audio.o vidc_fill.o vidc_mixer.o vidc_synth.o
 wavefront-objs  := wavfront.o wf_midi.o yss225.o
 nm256-objs     := nm256_audio.o ac97.o
-via82cxxx-objs := via82cxxx_audio.o ac97.o
+via82cxxx-objs  := via82cxxx_audio.o ac97.o
+ymfsb-objs     := ymf_sb.o ac97.o
 
 
 # Extract lists of the multi-part drivers.
@@ -215,6 +216,9 @@ nm256.o: $(nm256-objs)
 via82cxxx.o: $(via82cxxx-objs)
        $(LD) -r -o $@ $(via82cxxx-objs)
 
+ymfsb.o: $(ymfsb-objs)
+       $(LD) -r -o $@ $(ymfsb-objs)
+
 # Firmware files that need translation
 #
 # The translated files are protected by a file that keeps track
index b5ba59cc89b4c59d645551342169a7ec598b0d50..c87d0acf958dc10bdb1e1cd795029837b7174783 100644 (file)
@@ -768,3 +768,10 @@ static void __exit emu10k1_cleanup_module(void)
 
 module_init(emu10k1_init_module);
 module_exit(emu10k1_cleanup_module);
+
+#ifndef MODULE
+int __init init_emu10k1(void)
+{
+       return emu10k1_init_module();
+}
+#endif
index 08e33a2ea5ce8c098fcfd1fbcf3df502526e577a..0c79a35105605fd182c773c45ad4a705fe028254 100644 (file)
@@ -721,6 +721,9 @@ static int prog_dmabuf(struct i810_state *state, unsigned rec)
        outl(virt_to_bus(&dmabuf->channel->sg[0]), state->card->iobase+dmabuf->channel->port+OFF_BDBAR);
        outb(16, state->card->iobase+dmabuf->channel->port+OFF_LVI);
        outb(0, state->card->iobase+dmabuf->channel->port+OFF_CIV);
+       
+       resync_dma_ptrs(state);
+       
        if (rec) {
                i810_rec_setup(state);
        } else {
@@ -1561,7 +1564,7 @@ static int i810_open(struct inode *inode, struct file *file)
                dmabuf->ossfragshift = 0;
                dmabuf->ossmaxfrags  = 0;
                dmabuf->subdivision  = 0;
-               i810_set_dac_rate(state, 48000);
+               i810_set_dac_rate(state, 8000);
        }
 
        if (file->f_mode & FMODE_READ) {
@@ -1570,7 +1573,7 @@ static int i810_open(struct inode *inode, struct file *file)
                dmabuf->ossfragshift = 0;
                dmabuf->ossmaxfrags  = 0;
                dmabuf->subdivision  = 0;
-               i810_set_adc_rate(state, 48000);
+               i810_set_adc_rate(state, 8000);
        }
 
        state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
@@ -1734,6 +1737,8 @@ static int __init i810_ac97_init(struct i810_card *card)
                return 0;
        }
        
+       udelay(500);
+       
        inw(card->ac97base);
 
        for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
index 31fa969f41d037d76816ca0f02e291f6f1093e42..0af9a2222e78f5f8a3c0ad544d92443399304b5c 100644 (file)
@@ -3476,7 +3476,7 @@ maestro_install(struct pci_dev *pcidev, int card_type)
 #ifdef MODULE
 int init_module(void)
 #else
-int SILLY_MAKE_INIT(init_maestro(void))
+SILLY_MAKE_INIT(int init_maestro(void))
 #endif
 {
        struct pci_dev *pcidev = NULL;
index ed9a2e94d17e058166debfc0e58eaa6121799d5c..1ad86f6a7816e915f16e49825f9ec75260409885 100644 (file)
@@ -85,6 +85,9 @@ extern int init_ymf7xxsb_module(void);
 #ifdef CONFIG_SOUND_FUSION
 extern int cs_probe(void);
 #endif
+#ifdef CONFIG_SOUND_EMU10K1
+extern int init_emu10k1(void);
+#endif
 
 /*
  *     Low level list operator. Scan the ordered list, find a hole and
@@ -448,6 +451,9 @@ int soundcore_init(void)
 #endif
 #ifdef CONFIG_SOUND_FUSION
        cs_probe();
+#endif
+#ifdef CONFIG_SOUND_EMU10K1
+       init_emu10k1();
 #endif
        return 0;
 }
index 23ca159c75a293d5511afcd024b8b1e1c2ddbb27..90ad4ee21ee4381b9761397c752f3206ebc9b41c 100644 (file)
@@ -7,6 +7,9 @@
  *
  *  Steve Beynon                      : Missing last directory entries fixed
  *  (stephen@askone.demon.co.uk)      : 21st June 1996
+ *
+ *  Go Taniguchi                       : Move sector and boundarie error fixed
+ *  (go@turbolinux.co.jp)              : Jul 21 2000
  * 
  *  isofs directory handling functions
  */
@@ -160,9 +163,11 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                de = (struct iso_directory_record *) (bh->b_data + offset);
                if(first_de) inode_number = (block << bufbits) + (offset & (bufsize - 1));
 
-               de_len = *(unsigned char *) de;
+               /* Check boundaries and get length. by GO! */
+               if (offset < bufsize) de_len = *(unsigned char *) de;
 #ifdef DEBUG
-               printk("de_len = %ld\n", de_len);
+               if (offset < bufsize) printk("de_len = %ld\n", de_len);
+               else printk("Move to next sector\n");
 #endif
            
 
@@ -170,15 +175,15 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                   CDROM sector.  If we are at the end of the directory, we
                   kick out of the while loop. */
 
-               if ((de_len == 0) || (offset >= bufsize) ) {
+               if ((offset >= bufsize) || (de_len == 0) ) {
                        brelse(bh);
-                       if (de_len == 0) {
+                       if (offset >= bufsize) {        /*Check first. by GO!*/
+                               offset -= bufsize;
+                               filp->f_pos += offset;
+                       } else {
                                filp->f_pos = ((filp->f_pos & ~(ISOFS_BLOCK_SIZE - 1))
                                               + ISOFS_BLOCK_SIZE);
                                offset = 0;
-                       } else {
-                               offset -= bufsize;
-                               filp->f_pos += offset;
                        }
 
                        if (filp->f_pos >= inode->i_size)
index 25744b5e256607f323d04515c3c5db9c2d080f8a..e10d808dd0448f404edf2d4011bbdf5c68811bc3 100644 (file)
@@ -915,7 +915,7 @@ int isofs_bmap(struct inode * inode,int block)
         * If we are beyond the end of this file, don't give out any
         * blocks.
         */
-       if( b_off > inode->i_size )
+       if( b_off >= inode->i_size )
          {
            off_t       max_legal_read_offset;
 
index bd09c716d1c20d25e2696bef74dd1f00f5a65431..90bd7433fb3ed9e98e1b4dffada421b5b155b457 100644 (file)
@@ -130,7 +130,7 @@ io2vol(struct ncp_server *server, char *name, int case_trans)
                nc[0] = toupperif(*np, case_trans);
                nc[1] = 0x00;
                nls_in->char2uni(nc, &len, &uc.uni2, &uc.uni1);
-               nls_out->uni2char(0x00, uc.uni2, np, 1, &len);
+               nls_out->uni2char(uc.uni1, uc.uni2, np, 1, &len);
                np++;
        }
 }
@@ -154,7 +154,7 @@ vol2io(struct ncp_server *server, char *name, int case_trans)
                nc[0] = *np;
                nc[1] = 0;
                nls_in->char2uni(nc, &len, &uc.uni2, &uc.uni1);
-               nls_out->uni2char(0x00, uc.uni2, nc, 1, &len);
+               nls_out->uni2char(uc.uni1, uc.uni2, nc, 1, &len);
                *np = tolowerif(nc[0], case_trans);
                np++;
        }
diff --git a/fs/smbfs/ChangeLog b/fs/smbfs/ChangeLog
new file mode 100644 (file)
index 0000000..2ce92a0
--- /dev/null
@@ -0,0 +1,49 @@
+ChangeLog for smbfs.
+
+2000-07-20 Urban Widmark <urban@svenskatest.se>
+
+       * proc.c: fix 2 places where bad server responses could cause an Oops.
+
+2000-07-15 Urban Widmark <urban@svenskatest.se>
+
+       * *.c: more debug printk fixes
+
+2000-06-24: Matt Maynard <matthewm@corel.com>
+
+       * dir.c: dentry->d_inode->i_mtime isn't updated for all servers
+         (NT?) and all operations (mv oldfile.txt newfile.txt) Removed for
+         less efficient but better working directory cache.
+       * proc.c: included aDIR smbclient fix for renaming directories on
+         OS/2 servers (win95/98?) (orig by John Janosik)
+
+2000-07-01 Urban Widmark <urban@svenskatest.se>
+
+       * *.c: replace ugly #ifdef's with less ugly debug macros.
+
+2000-03-?? Andrew Tridgell
+
+       * proc.c: removed support for old protocol levels. It didn't work
+         anyway and was cluttering things up a lot.
+
+2000-01-?? cpg@aladdin.de
+
+       * proc.c: added posix semantics for unlink
+
+1999-11-16 Andrew Tridgell
+
+       * proc.c: use level 260 for most conns, or level 1 for <NT1
+       * proc.c: don't sleep every time with win95 on a FINDNEXT
+       * proc.c: fixed loop_count bug
+       * proc.c: got rid of resume_key
+
+[there are a few missing here :) ]
+
+1997-09-28 Riccardo Facchetti
+
+       * proc.c: Fixed smb_d_path [now smb_build_path()] to be non-recursive
+
+1996-06-28 Yuri Per
+
+       * proc.c: Fixed long file name support (smb_proc_readdir_long)
+
+You are in the wrong end for adding new entries. New entries at the top.
index 44ee38f270b28883129ee6d5ee4133a11e5b5117..a4a23743790ec21f0e8b6d1301620a033155b718 100644 (file)
@@ -6,6 +6,8 @@
  * Routines to support directory cacheing using the page cache.
  * Right now this only works for smbfs, but will be generalized
  * for use with other filesystems.
+ *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/sched.h>
@@ -17,9 +19,6 @@
 
 #include <asm/page.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-
 #include "smb_debug.h"
 
 
@@ -40,8 +39,7 @@ smb_get_dircache(struct dentry * dentry)
        struct inode * inode = dentry->d_inode;
        struct cache_head * cachep;
 
-       VERBOSE("smb_get_dircache: finding cache for %s/%s\n",
-               dentry->d_parent->d_name.name, dentry->d_name.name);
+       VERBOSE("finding cache for %s/%s\n", DENTRY_PATH(dentry));
        cachep = (struct cache_head *) get_cached_page(inode, 0, 1);
        if (!cachep)
                goto out;
@@ -60,9 +58,8 @@ smb_get_dircache(struct dentry * dentry)
                for (i = 0; i < cachep->pages; i++, index++) {
 #ifdef SMBFS_PARANOIA
                        if (index->block)
-                               PARANOIA("smb_get_dircache: cache %s/%s has existing block!\n",
-                                        dentry->d_parent->d_name.name,
-                                        dentry->d_name.name);
+                               PARANOIA("cache %s/%s has existing block!\n",
+                                        DENTRY_PATH(dentry));
 #endif
                        offset = PAGE_SIZE + (i << PAGE_SHIFT);
                        block = (struct cache_block *) get_cached_page(inode,
@@ -86,7 +83,7 @@ smb_free_cache_blocks(struct cache_head * cachep)
        struct cache_index * index = cachep->index;
        int i;
 
-       VERBOSE("smb_free_cache_blocks: freeing %d blocks\n", cachep->pages);
+       VERBOSE("freeing %d blocks\n", cachep->pages);
        for (i = 0; i < cachep->pages; i++, index++)
        {
                if (index->block)
@@ -103,7 +100,7 @@ smb_free_cache_blocks(struct cache_head * cachep)
 void
 smb_free_dircache(struct cache_head * cachep)
 {
-       VERBOSE("smb_free_dircache: freeing cache\n");
+       VERBOSE("freeing cache\n");
        smb_free_cache_blocks(cachep);
        put_cached_page((unsigned long) cachep);
 }
@@ -115,8 +112,7 @@ smb_free_dircache(struct cache_head * cachep)
 void
 smb_init_dircache(struct cache_head * cachep)
 {
-       VERBOSE("smb_init_dircache: initializing cache, %d blocks\n", 
-               cachep->pages);
+       VERBOSE("initializing cache, %d blocks\n", cachep->pages);
        smb_free_cache_blocks(cachep);
        memset(cachep, 0, sizeof(struct cache_head));
 }
@@ -136,8 +132,8 @@ smb_add_to_cache(struct cache_head * cachep, struct cache_dirent *entry,
        unsigned int nent, offset, len = entry->len;
        unsigned int needed = len + sizeof(struct cache_entry);
 
-       VERBOSE("smb_add_to_cache: cache inode %p, status %d, adding %s at %ld\n",
-               inode, cachep->status, entry->name, fpos);
+       VERBOSE("cache inode %p, status %d, adding %.*s at %ld\n",
+               inode, cachep->status, entry->len, entry->name, fpos);
        /*
         * Don't do anything if we've had an error ...
         */
@@ -163,8 +159,8 @@ smb_add_to_cache(struct cache_head * cachep, struct cache_dirent *entry,
                block->cb_data.table[nent].offset = offset;
                block->cb_data.table[nent].ino = entry->ino;
                cachep->entries++;
-               VERBOSE("smb_add_to_cache: added entry %s, len=%d, pos=%ld, entries=%d\n",
-                       entry->name, len, fpos, cachep->entries);
+               VERBOSE("added entry %.*s, len=%d, pos=%ld, entries=%d\n",
+                       entry->len, entry->name, len, fpos, cachep->entries);
                return;
        }
        /*
@@ -176,7 +172,7 @@ smb_add_to_cache(struct cache_head * cachep, struct cache_dirent *entry,
        index++;
 #ifdef SMBFS_PARANOIA
        if (index->block)
-               PARANOIA("smb_add_to_cache: new index already has block!\n");
+               PARANOIA("new index already has block!\n");
 #endif
 
        /*
@@ -190,7 +186,7 @@ get_block:
        {
                index->block = block;
                index->space = PAGE_SIZE;
-               VERBOSE("smb_add_to_cache: inode=%p, pages=%d, block at %ld\n",
+               VERBOSE("inode=%p, pages=%d, block at %ld\n",
                        inode, cachep->pages, page_off);
                goto add_entry;
        }
@@ -212,8 +208,7 @@ smb_find_in_cache(struct cache_head * cachep, off_t pos,
        unsigned int i, nent, offset = 0;
        off_t next_pos = 2;
 
-       VERBOSE("smb_find_in_cache: cache %p, looking for pos=%ld\n", 
-               cachep, pos);
+       VERBOSE("cache %p, looking for pos=%ld\n", cachep, pos);
        for (i = 0; i < cachep->pages; i++, index++)
        {
                if (pos < next_pos)
@@ -231,8 +226,8 @@ smb_find_in_cache(struct cache_head * cachep, off_t pos,
                entry->len = block->cb_data.table[nent].namelen;
                offset = block->cb_data.table[nent].offset;
                entry->name = &block->cb_data.names[offset];
-               VERBOSE("smb_find_in_cache: found %s, len=%d, pos=%ld\n",
-                       entry->name, entry->len, pos);
+               VERBOSE("found %.*s, len=%d, pos=%ld\n",
+                       entry->len, entry->name, entry->len, pos);
                break;
        }
        return offset;
@@ -244,9 +239,7 @@ smb_refill_dircache(struct cache_head * cachep, struct dentry *dentry)
        struct inode * inode = dentry->d_inode;
        int result;
 
-       VERBOSE("smb_refill_dircache: cache %s/%s, blocks=%d\n",
-               dentry->d_parent->d_name.name, dentry->d_name.name, 
-               cachep->pages);
+       VERBOSE("cache %s/%s, blocks=%d\n", DENTRY_PATH(dentry), cachep->pages);
        /*
         * Fill the cache, starting at position 2.
         */
@@ -255,8 +248,7 @@ retry:
        result = smb_proc_readdir(dentry, 2, cachep);
        if (result < 0)
        {
-               PARANOIA("smb_refill_dircache: readdir failed, result=%d\n", 
-                        result);
+               PARANOIA("readdir failed, result=%d\n", result);
                goto out;
        }
 
@@ -266,7 +258,7 @@ retry:
         */
        if (!(inode->u.smbfs_i.cache_valid & SMB_F_CACHEVALID))
        {
-               PARANOIA("smb_refill_dircache: cache invalidated, retrying\n");
+               PARANOIA("cache invalidated, retrying\n");
                goto retry;
        }
 
@@ -276,9 +268,8 @@ retry:
                cachep->valid = 1;
                cachep->mtime = dentry->d_inode->i_mtime;
        }
-       VERBOSE("smb_refill_cache: cache %s/%s status=%d, entries=%d\n",
-               dentry->d_parent->d_name.name, dentry->d_name.name,
-               cachep->status, cachep->entries);
+       VERBOSE("cache %s/%s status=%d, entries=%d\n",
+               DENTRY_PATH(dentry), cachep->status, cachep->entries);
 
 out:
        return result;
index 0ac3762ec6858c441e57817bccd0c7783edb3dbd..d60f2ad52d491eb533165f00567438b88c99ef3f 100644 (file)
@@ -4,18 +4,17 @@
  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/ctype.h>
 
 #include <linux/smb_fs.h>
 #include <linux/smbno.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-
 #include "smb_debug.h"
 
 #define SMBFS_MAX_AGE 5*HZ
@@ -85,8 +84,7 @@ smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
        struct cache_head *cachep = NULL;
        int result;
 
-       VERBOSE("smb_readdir: reading %s/%s, f_pos=%d\n",
-               dentry->d_parent->d_name.name, dentry->d_name.name,
+       VERBOSE("reading %s/%s, f_pos=%d\n", DENTRY_PATH(dentry),
                (int) filp->f_pos);
 
        result = 0;
@@ -118,10 +116,13 @@ smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
                goto out;
        /*
         * Make sure the cache is up-to-date.
+        *
+        * To detect changes on the server we refill on each "new" access.
+        *
+        * Directory mtime would be nice to use for finding changes,
+        * unfortunately some servers (NT4) doesn't update on local changes.
         */
-       if (!cachep->valid ||
-           (cachep->mtime != dentry->d_inode->i_mtime &&
-            filp->f_pos == 2))
+       if (!cachep->valid || filp->f_pos == 2)
        {
                result = smb_refill_dircache(cachep, dentry);
                if (result)
@@ -176,7 +177,7 @@ smb_dir_open(struct inode *dir, struct file *file)
        struct smb_sb_info *server = server_from_dentry(dentry);
        int error = 0;
 
-       VERBOSE("smb_dir_open: (%s/%s)\n", dentry->d_parent->d_name.name, 
+       VERBOSE("(%s/%s)\n", dentry->d_parent->d_name.name, 
                file->f_dentry->d_name.name);
        if (server->conn_pid)
                error = smb_revalidate_inode(dentry);
@@ -217,36 +218,23 @@ smb_lookup_validate(struct dentry * dentry, int flags)
        valid = (age <= SMBFS_MAX_AGE);
 #ifdef SMBFS_DEBUG_VERBOSE
        if (!valid)
-               VERBOSE("smb_lookup_validate: %s/%s not valid, age=%lu\n", 
-                       dentry->d_parent->d_name.name, dentry->d_name.name,
-                       age);
+               VERBOSE("%s/%s not valid, age=%lu\n", DENTRY_PATH(dentry), age);
 #endif
 
-       if (inode)
-       {
-               if (is_bad_inode(inode))
-               {
-                       PARANOIA("smb_lookup_validate: %s/%s has dud inode\n", 
-                                dentry->d_parent->d_name.name,
-                                dentry->d_name.name);
+       if (inode) {
+               if (is_bad_inode(inode)) {
+                       PARANOIA("%s/%s has dud inode\n", DENTRY_PATH(dentry));
                        valid = 0;
                } else if (!valid)
                        valid = (smb_revalidate_inode(dentry) == 0);
-       } else
-       {
-       /*
-        * What should we do for negative dentries?
-        */
+       } else {
+               /*
+                * What should we do for negative dentries?
+                */
        }
        return valid;
 }
 
-/*
- * XXX: It would be better to use the tolower from linux/ctype.h,
- * but _ctype is needed and it is not exported.
- */
-#define tolower(c) (((c) >= 'A' && (c) <= 'Z') ? (c)-('A'-'a') : (c))
-
 static int 
 smb_hash_dentry(struct dentry *dir, struct qstr *this)
 {
@@ -285,19 +273,15 @@ out:
 static void
 smb_delete_dentry(struct dentry * dentry)
 {
-       if (dentry->d_inode)
-       {
-               if (is_bad_inode(dentry->d_inode))
-               {
-                       PARANOIA("smb_delete_dentry: bad inode, unhashing %s/%s\n", 
-                                dentry->d_parent->d_name.name,
-                                dentry->d_name.name);
+       if (dentry->d_inode) {
+               if (is_bad_inode(dentry->d_inode)) {
+                       PARANOIA("bad inode, unhashing %s/%s\n", 
+                                DENTRY_PATH(dentry));
                        d_drop(dentry);
                }
                smb_close_dentry(dentry);
-       } else
-       {
-       /* N.B. Unhash negative dentries? */
+       } else {
+               /* N.B. Unhash negative dentries? */
        }
 }
 
@@ -332,9 +316,8 @@ smb_lookup(struct inode *dir, struct dentry *dentry)
        error = smb_proc_getattr(dentry, &finfo);
 #ifdef SMBFS_PARANOIA
        if (error && error != -ENOENT)
-               PARANOIA("smb_lookup: find %s/%s failed, error=%d\n",
-                        dentry->d_parent->d_name.name, dentry->d_name.name,
-                        error);
+               PARANOIA("find %s/%s failed, error=%d\n",
+                        DENTRY_PATH(dentry), error);
 #endif
 
        inode = NULL;
@@ -369,8 +352,7 @@ smb_instantiate(struct dentry *dentry, __u16 fileid, int have_id)
        int error;
        struct smb_fattr fattr;
 
-       VERBOSE("smb_instantiate: file %s/%s, fileid=%u\n",
-               dentry->d_parent->d_name.name, dentry->d_name.name, fileid);
+       VERBOSE("file %s/%s, fileid=%u\n", DENTRY_PATH(dentry), fileid);
        error = smb_proc_getattr(dentry, &fattr);
        if (error)
                goto out_close;
@@ -396,9 +378,8 @@ out_no_inode:
 out_close:
        if (have_id)
        {
-               PARANOIA("smb_instantiate: %s/%s failed, error=%d, closing %u\n",
-                        dentry->d_parent->d_name.name, dentry->d_name.name,
-                        error, fileid);
+               PARANOIA("%s/%s failed, error=%d, closing %u\n",
+                        DENTRY_PATH(dentry), error, fileid);
                smb_close_fileid(dentry, fileid);
        }
        goto out;
@@ -411,18 +392,14 @@ smb_create(struct inode *dir, struct dentry *dentry, int mode)
        __u16 fileid;
        int error;
 
-       VERBOSE("smb_create: creating %s/%s, mode=%d\n",
-               dentry->d_parent->d_name.name, dentry->d_name.name, mode);
+       VERBOSE("creating %s/%s, mode=%d\n", DENTRY_PATH(dentry), mode);
 
        error = smb_proc_create(dentry, 0, CURRENT_TIME, &fileid);
-       if (!error)
-       {
+       if (!error) {
                error = smb_instantiate(dentry, fileid, 1);
-       } else
-       {
-               PARANOIA("smb_create: %s/%s failed, error=%d\n",
-                        dentry->d_parent->d_name.name, dentry->d_name.name,
-                        error);
+       } else {
+               PARANOIA("%s/%s failed, error=%d\n",
+                        DENTRY_PATH(dentry), error);
        }
        return error;
 }
@@ -502,9 +479,8 @@ smb_rename(struct inode *old_dir, struct dentry *old_dentry,
                error = smb_proc_unlink(new_dentry);
                if (error)
                {
-                       VERBOSE("smb_rename: unlink %s/%s, error=%d\n",
-                               new_dentry->d_parent->d_name.name,
-                               new_dentry->d_name.name, error);
+                       VERBOSE("unlink %s/%s, error=%d\n",
+                               DENTRY_PATH(new_dentry), error);
                        goto out;
                }
                /* FIXME */
index 0b0c4e3a7f190138a7748197d00a2d9711b501ec..c91e20e4b564aee256e57d11bf694e6cdce9e9d9 100644 (file)
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995, 1996, 1997 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/sched.h>
 #include <linux/smbno.h>
 #include <linux/smb_fs.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-
 #include "smb_debug.h"
 
-static inline int
-min(int a, int b)
-{
-       return a < b ? a : b;
-}
 
 static inline void
 smb_unlock_page(struct page *page)
@@ -43,8 +36,7 @@ smb_unlock_page(struct page *page)
 static int
 smb_fsync(struct file *file, struct dentry * dentry)
 {
-       VERBOSE("smb_fsync: sync file %s/%s\n", 
-               dentry->d_parent->d_name.name, dentry->d_name.name);
+       VERBOSE("sync file %s/%s\n", DENTRY_PATH(dentry));
        return 0;
 }
 
@@ -62,15 +54,13 @@ smb_readpage_sync(struct dentry *dentry, struct page *page)
 
        clear_bit(PG_error, &page->flags);
 
-       VERBOSE("smb_readpage_sync: file %s/%s, count=%d@%ld, rsize=%d\n",
-               dentry->d_parent->d_name.name, dentry->d_name.name, count,
-               offset, rsize);
+       VERBOSE("file %s/%s, count=%d@%ld, rsize=%d\n",
+               DENTRY_PATH(dentry), count, offset, rsize);
        result = smb_open(dentry, SMB_O_RDONLY);
        if (result < 0)
        {
-               PARANOIA("smb_readpage_sync: %s/%s open failed, error=%d\n",
-                        dentry->d_parent->d_name.name, dentry->d_name.name,
-                        result);
+               PARANOIA("%s/%s open failed, error=%d\n",
+                        DENTRY_PATH(dentry), result);
                goto io_error;
        }
 
@@ -109,7 +99,7 @@ smb_readpage(struct file *file, struct page *page)
        DEBUG1("SMB: smb_readpage %08lx\n", page_address(page));
 #ifdef SMBFS_PARANOIA
        if (test_bit(PG_locked, &page->flags))
-               DEBUG1("smb_readpage: page already locked!\n");
+               PARANOIA("page already locked!\n");
 #endif
        set_bit(PG_locked, &page->flags);
        atomic_inc(&page->count);
@@ -132,9 +122,8 @@ smb_writepage_sync(struct dentry *dentry, struct page *page,
        int result, written = 0;
 
        offset += page->offset;
-       VERBOSE("smb_writepage_sync: file %s/%s, count=%d@%ld, wsize=%d\n",
-               dentry->d_parent->d_name.name, dentry->d_name.name,
-               count, offset, wsize);
+       VERBOSE("file %s/%s, count=%d@%ld, wsize=%d\n",
+               DENTRY_PATH(dentry), count, offset, wsize);
 
        do {
                if (count < wsize)
@@ -146,7 +135,8 @@ smb_writepage_sync(struct dentry *dentry, struct page *page,
                /* N.B. what if result < wsize?? */
 #ifdef SMBFS_PARANOIA
                if (result < wsize)
-                       printk(KERN_DEBUG "smb_writepage_sync: short write, wsize=%d, result=%d\n", wsize, result);
+                       printk(KERN_DEBUG "short write, wsize=%d, result=%d\n",
+                              wsize, result);
 #endif
                buffer += wsize;
                offset += wsize;
@@ -175,7 +165,7 @@ smb_writepage(struct file *file, struct page *page)
 
 #ifdef SMBFS_PARANOIA
        if (test_bit(PG_locked, &page->flags))
-               DEBUG1("smb_writepage: page already locked!\n");
+               PARANOIA("page already locked!\n");
 #endif
        set_bit(PG_locked, &page->flags);
        atomic_inc(&page->count);
@@ -190,9 +180,8 @@ smb_updatepage(struct file *file, struct page *page, unsigned long offset, unsig
 {
        struct dentry *dentry = file->f_dentry;
 
-       DEBUG1("SMBFS: smb_updatepage(%s/%s %d@%ld, sync=%d)\n",
-              dentry->d_parent->d_name.name, dentry->d_name.name,
-              count, page->offset+offset, sync);
+       DEBUG1("(%s/%s %d@%ld, sync=%d)\n",
+              DENTRY_PATH(dentry), count, page->offset+offset, sync);
 
        return smb_writepage_sync(dentry, page, offset, count);
 }
@@ -203,23 +192,21 @@ smb_file_read(struct file * file, char * buf, size_t count, loff_t *ppos)
        struct dentry * dentry = file->f_dentry;
        ssize_t status;
 
-       VERBOSE("smb_file_read: file %s/%s, count=%lu@%lu\n",
-               dentry->d_parent->d_name.name, dentry->d_name.name,
+       VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry),
                (unsigned long) count, (unsigned long) *ppos);
 
        status = smb_revalidate_inode(dentry);
        if (status)
        {
-               PARANOIA("smb_file_read: %s/%s validation failed, error=%d\n",
-                        dentry->d_parent->d_name.name, dentry->d_name.name,
-                        status);
+               PARANOIA("%s/%s validation failed, error=%d\n",
+                        DENTRY_PATH(dentry), status);
                goto out;
        }
 
-       VERBOSE("smb_file_read: before read, size=%ld, pages=%ld, flags=%x, atime=%ld\n",
+       VERBOSE("before read, size=%ld, pages=%ld, flags=%x, atime=%ld\n",
                dentry->d_inode->i_size, dentry->d_inode->i_nrpages,
-               dentry->d_inode->i_flags,
-               dentry->d_inode->i_atime);
+               dentry->d_inode->i_flags, dentry->d_inode->i_atime);
+
        status = generic_file_read(file, buf, count, ppos);
 out:
        return status;
@@ -231,16 +218,14 @@ smb_file_mmap(struct file * file, struct vm_area_struct * vma)
        struct dentry * dentry = file->f_dentry;
        int     status;
 
-       VERBOSE("smb_file_mmap: file %s/%s, address %lu - %lu\n",
-               dentry->d_parent->d_name.name, dentry->d_name.name,
-               vma->vm_start, vma->vm_end);
+       VERBOSE("file %s/%s, address %lu - %lu\n",
+               DENTRY_PATH(dentry), vma->vm_start, vma->vm_end);
 
        status = smb_revalidate_inode(dentry);
        if (status)
        {
-               PARANOIA("smb_file_mmap: %s/%s validation failed, error=%d\n",
-                        dentry->d_parent->d_name.name, dentry->d_name.name,
-                        status);
+               PARANOIA("%s/%s validation failed, error=%d\n",
+                        DENTRY_PATH(dentry), status);
                goto out;
        }
        status = generic_file_mmap(file, vma);
@@ -257,18 +242,16 @@ smb_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
        struct dentry * dentry = file->f_dentry;
        ssize_t result;
 
-       VERBOSE("smb_file_write: file %s/%s, count=%lu@%lu, pages=%ld\n",
-               dentry->d_parent->d_name.name, dentry->d_name.name,
+       VERBOSE("file %s/%s, count=%lu@%lu, pages=%ld\n", DENTRY_PATH(dentry),
                (unsigned long) count, (unsigned long) *ppos,
                dentry->d_inode->i_nrpages);
 
        result = smb_revalidate_inode(dentry);
        if (result)
        {
-               PARANOIA("smb_file_write: %s/%s validation failed, error=%d\n",
-                        dentry->d_parent->d_name.name, dentry->d_name.name,
-                        result);
-                       goto out;
+               PARANOIA("%s/%s validation failed, error=%d\n",
+                        DENTRY_PATH(dentry), result);
+               goto out;
        }
 
        result = smb_open(dentry, SMB_O_WRONLY);
@@ -278,7 +261,7 @@ smb_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
        if (count > 0)
        {
                result = generic_file_write(file, buf, count, ppos);
-               VERBOSE("smb_file_write: pos=%ld, size=%ld, mtime=%ld, atime=%ld\n",
+               VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n",
                        (long) file->f_pos, dentry->d_inode->i_size,
                        dentry->d_inode->i_mtime, dentry->d_inode->i_atime);
        }
@@ -289,9 +272,8 @@ out:
 static int
 smb_file_open(struct inode *inode, struct file * file)
 {
-       VERBOSE("smb_file_open: opening %s/%s, d_count=%d\n",
-               file->f_dentry->d_parent->d_name.name,
-               file->f_dentry->d_name.name, file->f_dentry->d_count);
+       VERBOSE("opening %s/%s, d_count=%d\n",
+               DENTRY_PATH(file->f_dentry), file->f_dentry->d_count);
        return 0;
 }
 
@@ -300,14 +282,12 @@ smb_file_release(struct inode *inode, struct file * file)
 {
        struct dentry * dentry = file->f_dentry;
 
-       VERBOSE("smb_file_release: closing %s/%s, d_count=%d\n",
-               dentry->d_parent->d_name.name, dentry->d_name.name,
-               dentry->d_count);
-       
+       VERBOSE("closing %s/%s, d_count=%d\n",
+               DENTRY_PATH(dentry), dentry->d_count);
+
        if (dentry->d_count == 1)
-       {
                smb_close(inode);
-       }
+
        return 0;
 }
 
@@ -322,7 +302,7 @@ smb_file_permission(struct inode *inode, int mask)
        int mode = inode->i_mode;
        int error = 0;
 
-       VERBOSE("smb_file_permission: mode=%x, mask=%x\n", mode, mask);
+       VERBOSE("mode=%x, mask=%x\n", mode, mask);
 
        /* Look at user permissions */
        mode >>= 6;
index dfc65f90e14fb3d064f02186d6e71fafc5cae0a8..18d18c2dcfed4c294d416e29237dcc40807811a5 100644 (file)
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/config.h>
@@ -28,9 +29,6 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-
 #include "smb_debug.h"
 
 static void smb_read_inode(struct inode *);
@@ -76,7 +74,7 @@ smb_iget(struct super_block *sb, struct smb_fattr *fattr)
 {
        struct inode *result;
 
-       DEBUG1("smb_iget: %p\n", fattr);
+       DEBUG1("fattr @ %p\n", fattr);
 
        result = get_empty_inode();
        result->i_sb = sb;
@@ -169,7 +167,7 @@ smb_read_inode(struct inode *inode)
 void
 smb_invalidate_inodes(struct smb_sb_info *server)
 {
-       VERBOSE("smb_invalidate_inodes\n");
+       VERBOSE("\n");
        shrink_dcache_sb(SB_of(server));
        invalidate_inodes(SB_of(server));
 }
@@ -204,9 +202,8 @@ smb_refresh_inode(struct dentry *dentry)
                         * To limit damage, mark the inode as bad so that
                         * subsequent lookup validations will fail.
                         */
-                       PARANOIA("smb_refresh_inode: %s/%s changed mode, %07o to %07o\n",
-                                dentry->d_parent->d_name.name,
-                                dentry->d_name.name,
+                       PARANOIA("%s/%s changed mode, %07o to %07o\n",
+                                DENTRY_PATH(dentry),
                                 inode->i_mode, fattr.f_mode);
 
                        fattr.f_mode = inode->i_mode; /* save mode */
@@ -239,7 +236,7 @@ smb_revalidate_inode(struct dentry *dentry)
        time_t last_time;
        int error = 0;
 
-       DEBUG1("smb_revalidate_inode\n");
+       DEBUG1("\n");
 
        /*
         * If this is a file opened with write permissions,
@@ -256,7 +253,7 @@ smb_revalidate_inode(struct dentry *dentry)
         */
        if (time_before(jiffies, inode->u.smbfs_i.oldmtime + HZ/10))
        {
-               VERBOSE("smb_revalidate_inode: up-to-date, jiffies=%lu, oldtime=%lu\n",
+               VERBOSE("up-to-date, jiffies=%lu, oldtime=%lu\n",
                        jiffies, inode->u.smbfs_i.oldmtime);
                goto out;
        }
@@ -269,8 +266,8 @@ smb_revalidate_inode(struct dentry *dentry)
        error = smb_refresh_inode(dentry);
        if (error || inode->i_mtime != last_time)
        {
-               VERBOSE("smb_revalidate: %s/%s changed, old=%ld, new=%ld\n",
-                       dentry->d_parent->d_name.name, dentry->d_name.name,
+               VERBOSE("%s/%s changed, old=%ld, new=%ld\n",
+                       DENTRY_PATH(dentry),
                        (long) last_time, (long) inode->i_mtime);
                if (!S_ISDIR(inode->i_mode))
                        invalidate_inode_pages(inode);
@@ -286,7 +283,7 @@ out:
 static void
 smb_put_inode(struct inode *ino)
 {
-       DEBUG1("smb_put_inode: count = %d\n", ino->i_count);
+       DEBUG1("count = %d\n", ino->i_count);
        if (ino->i_count == 1)
                ino->i_nlink = 0;
 }
@@ -298,10 +295,9 @@ smb_put_inode(struct inode *ino)
 static void
 smb_delete_inode(struct inode *ino)
 {
-       DEBUG1("smb_delete_inode\n");
+       DEBUG1("\n");
        if (smb_close(ino))
-               PARANOIA("smb_delete_inode: could not close inode %ld\n",
-                        ino->i_ino);
+               PARANOIA("could not close inode %ld\n", ino->i_ino);
        clear_inode(ino);
 }
 
@@ -317,7 +313,7 @@ smb_put_super(struct super_block *sb)
        }
 
        if (server->conn_pid)
-              kill_proc(server->conn_pid, SIGTERM, 1);
+               kill_proc(server->conn_pid, SIGTERM, 1);
 
        kfree(server->mnt);
        kfree(sb->u.smbfs_sb.temp_buf);
@@ -370,7 +366,7 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent)
        if (!mnt)
                goto out_no_mount;
        *mnt = *((struct smb_mount_data *) raw_data);
-       /* ** temp ** pass config flags in file mode */
+       /* FIXME: ** temp ** pass config flags in file mode */
        mnt->version = (mnt->file_mode >> 9);
        mnt->file_mode &= (S_IRWXU | S_IRWXG | S_IRWXO);
        mnt->file_mode |= S_IFREG;
@@ -408,7 +404,7 @@ out_wrong_data:
        printk(KERN_ERR "SMBFS: need mount version %d\n", SMB_MOUNT_VERSION);
        goto out_fail;
 out_no_data:
-       printk(KERN_DEBUG "smb_read_super: missing data argument\n");
+       printk(KERN_ERR "smb_read_super: missing data argument\n");
 out_fail:
        sb->s_dev = 0;
        MOD_DEC_USE_COUNT;
@@ -459,8 +455,8 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr)
 
        if ((attr->ia_valid & ATTR_SIZE) != 0)
        {
-               VERBOSE("smb_notify_change: changing %s/%s, old size=%ld, new size=%ld\n",
-                       dentry->d_parent->d_name.name, dentry->d_name.name,
+               VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n",
+                       DENTRY_PATH(dentry),
                        (long) inode->i_size, (long) attr->ia_size);
                error = smb_open(dentry, O_WRONLY);
                if (error)
@@ -513,9 +509,8 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr)
         */
        if ((attr->ia_valid & ATTR_MODE) != 0)
        {
-               VERBOSE("smb_notify_change: %s/%s mode change, old=%x, new=%lx\n",
-                       dentry->d_parent->d_name.name, dentry->d_name.name,
-                       fattr.f_mode,attr->ia_mode);
+               VERBOSE("%s/%s mode change, old=%x, new=%lx\n",
+                       DENTRY_PATH(dentry), fattr.f_mode,attr->ia_mode);
                changed = 0;
                if (attr->ia_mode & S_IWUSR)
                {
@@ -572,7 +567,7 @@ EXPORT_NO_SYMBOLS;
 int
 init_module(void)
 {
-       DEBUG1("smbfs: init_module called\n");
+       DEBUG1("registering ...\n");
 
 #ifdef DEBUG_SMB_MALLOC
        smb_malloced = 0;
@@ -586,7 +581,7 @@ init_module(void)
 void
 cleanup_module(void)
 {
-       DEBUG1("smbfs: cleanup_module called\n");
+       DEBUG1("unregistering ...\n");
        unregister_filesystem(&smb_fs_type);
 #ifdef DEBUG_SMB_MALLOC
        printk(KERN_DEBUG "smb_malloced: %d\n", smb_malloced);
index b403c248ddaf058008042fb426ebed4c89a670f1..c99392e3d2a42f67f3f595d6fe48c74d9d28f554 100644 (file)
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995, 1996 by Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/errno.h>
@@ -23,30 +24,25 @@ smb_ioctl(struct inode *inode, struct file *filp,
          unsigned int cmd, unsigned long arg)
 {
        struct smb_sb_info *server = SMB_SERVER(inode);
+       struct smb_conn_opt opt;
        int result = -EINVAL;
 
-       switch (cmd)
-       {
+       switch (cmd) {
        case SMB_IOC_GETMOUNTUID:
                result = put_user(server->mnt->mounted_uid, (uid_t *) arg);
                break;
 
        case SMB_IOC_NEWCONN:
-       {
-               struct smb_conn_opt opt;
-
                /* require an argument == the mount data, else it is EINVAL */
                if (!arg)
-                       goto out;
+                       break;
 
                result = -EFAULT;
                if (!copy_from_user(&opt, (void *)arg, sizeof(opt)))
                        result = smb_newconn(server, &opt);
                break;
-       }
        default:
        }
 
-out:
        return result;
 }
index 4964ea38d5aefd89f7def99816fab99979a536a9..f412b76ff4446347414c8edaf98b58b1bc296098 100644 (file)
@@ -4,19 +4,7 @@
  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
- *  28/06/96 - Fixed long file name support (smb_proc_readdir_long) by Yuri Per
- *  28/09/97 - Fixed smb_d_path [now smb_build_path()] to be non-recursive
- *             by Riccardo Facchetti
- *  16/11/99 (tridge) 
- *           - use level 260 for most conns, or level 1 for <NT1
- *           - don't sleep every time with win95 on a FINDNEXT
- *           - fixed loop_count bug
- *           - got rid of resume_key
- *  Jan 2000, cpg@aladdin.de
- *           - added posix semantics for unlink
- *  March 2000, tridge
- *           - removed support for old protocol levels. It didn't work anyway 
- *             and was cluttering things up a lot. 
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/types.h>
    config option. */
 #define SMBFS_POSIX_UNLINK 1
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_TIMESTAMP 1 */
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-
 #include "smb_debug.h"
 
 #define SMB_VWV(packet)  ((packet) + SMB_HEADER_LEN)
 #define SMB_DIRINFO_SIZE 43
 #define SMB_STATUS_SIZE  21
 
-/* This makes a dentry parent/child pair. Useful for debugging printk's */
-#define DENTRY_PATH(dentry) \
-       (dentry)->d_parent->d_name.name,(dentry)->d_name.name
-
-
 static int smb_proc_setattr_ext(struct smb_sb_info *, struct inode *,
                                struct smb_fattr *);
 static int
 smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
                      __u16 attr);
-
 static int
-smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,struct smb_sb_info *server);
+smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,
+                   struct smb_sb_info *server);
+
 
 /* reverse a string inline. This is used by the dircache walking routines */
 static void reverse_string(char *buf, int len) {
@@ -320,7 +300,7 @@ smb_get_rsize(struct smb_sb_info *server)
 {
        int overhead = SMB_HEADER_LEN + 5 * sizeof(__u16) + 2 + 1 + 2;
        int size = smb_get_xmitsize(server, overhead);
-       VERBOSE("smb_get_rsize: packet=%d, xmit=%d, size=%d\n",
+       VERBOSE("packet=%d, xmit=%d, size=%d\n",
                server->packet_size, server->opt.max_xmit, size);
        return size;
 }
@@ -333,7 +313,7 @@ smb_get_wsize(struct smb_sb_info *server)
 {
        int overhead = SMB_HEADER_LEN + 5 * sizeof(__u16) + 2 + 1 + 2;
        int size = smb_get_xmitsize(server, overhead);
-       VERBOSE("smb_get_wsize: packet=%d, xmit=%d, size=%d\n",
+       VERBOSE("packet=%d, xmit=%d, size=%d\n",
                server->packet_size, server->opt.max_xmit, size);
        return size;
 }
@@ -345,7 +325,7 @@ smb_errno(struct smb_sb_info *server)
        int error  = server->err;
        char *class = "Unknown";
 
-       VERBOSE("smb_errno: errcls %d  code %d  from command 0x%x\n",
+       VERBOSE("errcls %d  code %d  from command 0x%x\n",
                errcls, error, SMB_CMD(server->packet));
 
        if (errcls == ERRDOS)
@@ -506,7 +486,7 @@ smb_retry(struct smb_sb_info *server)
                printk(KERN_ERR "smb_retry: signal failed, error=%d\n", error);
                goto out_restore;
        }
-       VERBOSE("smb_retry: signalled pid %d, waiting for new connection\n",
+       VERBOSE("signalled pid %d, waiting for new connection\n",
                server->conn_pid);
 
        /*
@@ -514,14 +494,14 @@ smb_retry(struct smb_sb_info *server)
         */
        interruptible_sleep_on_timeout(&server->wait,  5*HZ);
        if (signal_pending(current))
-               printk(KERN_INFO "smb_retry: caught signal\n");
+               printk(KERN_INFO "caught signal\n");
 
        /*
         * Check for a valid connection.
         */
        if (server->state == CONN_VALID)
        {
-               PARANOIA("smb_retry: new pid=%d, generation=%d\n",
+               PARANOIA("sucessful, new pid=%d, generation=%d\n",
                         server->conn_pid, server->generation);
                result = 1;
        }
@@ -564,7 +544,7 @@ smb_request_ok(struct smb_sb_info *s, int command, int wct, int bcc)
        }
        if (smb_valid_packet(s->packet) != 0)
        {
-               PARANOIA("smb_request_ok: invalid packet!\n");
+               PARANOIA("invalid packet!\n");
                goto out;
        }
 
@@ -605,7 +585,7 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt)
        struct file *filp;
        int error;
 
-       VERBOSE("smb_newconn: fd=%d, pid=%d\n", opt->fd, current->pid);
+       VERBOSE("fd=%d, pid=%d\n", opt->fd, current->pid);
 
        /*
         * Make sure we don't already have a pid ...
@@ -654,7 +634,7 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt)
 #endif
        }
 
-       VERBOSE("smb_newconn: protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
+       VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
                server->opt.protocol, server->opt.max_xmit, server->conn_pid,
                server->opt.capabilities);
 
@@ -757,7 +737,7 @@ smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish)
                if (mode == read_write &&
                    (error == -EACCES || error == -ETXTBSY || error == -EROFS))
                {
-                       VERBOSE("smb_proc_open: %s/%s R/W failed, error=%d, retrying R/O\n",
+                       VERBOSE("%s/%s R/W failed, error=%d, retrying R/O\n",
                                DENTRY_PATH(dentry), error);
                        mode = read_only;
                        goto retry;
@@ -810,7 +790,7 @@ smb_open(struct dentry *dentry, int wish)
                smb_unlock_server(server);
                if (result)
                {
-                       PARANOIA("smb_open: %s/%s open failed, result=%d\n",
+                       PARANOIA("%s/%s open failed, result=%d\n",
                                 DENTRY_PATH(dentry), result);
                        goto out;
                }
@@ -827,7 +807,7 @@ smb_open(struct dentry *dentry, int wish)
        if (inode->u.smbfs_i.access != wish && 
            inode->u.smbfs_i.access != SMB_O_RDWR)
        {
-               PARANOIA("smb_open: %s/%s access denied, access=%x, wish=%x\n",
+               PARANOIA("%s/%s access denied, access=%x, wish=%x\n",
                         DENTRY_PATH(dentry), inode->u.smbfs_i.access, wish);
                result = -EACCES;
        }
@@ -936,13 +916,13 @@ smb_close_dentry(struct dentry * dentry)
                         */
                        if (dentry->d_count <= 1)
                        {
-                               VERBOSE("smb_close_dentry: closing %s/%s, count=%d\n",
+                               VERBOSE("closing %s/%s, count=%d\n",
                                        DENTRY_PATH(dentry), dentry->d_count);
                                smb_proc_close_inode(server, ino);
                        }
                        smb_unlock_server(server);
                }
-               VERBOSE("smb_close_dentry: closed %s/%s, count=%d\n",
+               VERBOSE("closed %s/%s, count=%d\n",
                        DENTRY_PATH(dentry), dentry->d_count);
        }
 }
@@ -971,7 +951,7 @@ smb_proc_read(struct dentry *dentry, off_t offset, int count, char *data)
 {
        struct smb_sb_info *server = server_from_dentry(dentry);
        __u16 returned_count, data_len;
-       char *buf;
+       unsigned char *buf;
        int result;
 
        smb_lock_server(server);
@@ -989,10 +969,19 @@ smb_proc_read(struct dentry *dentry, off_t offset, int count, char *data)
 
        buf = SMB_BUF(server->packet);
        data_len = WVAL(buf, 1);
+
+       /* we can NOT simply trust the data_len given by the server ... */
+       if (data_len > server->packet_size - (buf+3 - server->packet)) {
+               printk(KERN_ERR "smb_proc_read: invalid data length!! "
+                      "%d > %d - (%p - %p)\n",
+                      data_len, server->packet_size, buf+3, server->packet);
+               result = -EIO;
+               goto out;
+       }
+
        memcpy(data, buf+3, data_len);
 
-       if (returned_count != data_len)
-       {
+       if (returned_count != data_len) {
                printk(KERN_NOTICE "smb_proc_read: returned != data_len\n");
                printk(KERN_NOTICE "smb_proc_read: ret_c=%d, data_len=%d\n",
                       returned_count, data_len);
@@ -1000,7 +989,7 @@ smb_proc_read(struct dentry *dentry, off_t offset, int count, char *data)
        result = data_len;
 
 out:
-       VERBOSE("smb_proc_read: file %s/%s, count=%d, result=%d\n",
+       VERBOSE("file %s/%s, count=%d, result=%d\n",
                DENTRY_PATH(dentry), count, result);
        smb_unlock_server(server);
        return result;
@@ -1013,7 +1002,7 @@ smb_proc_write(struct dentry *dentry, off_t offset, int count, const char *data)
        int result;
        __u8 *p;
 
-       VERBOSE("smb_proc_write: file %s/%s, count=%d@%ld, packet_size=%d\n",
+       VERBOSE("file %s/%s, count=%d@%ld, packet_size=%d\n",
                DENTRY_PATH(dentry), count, offset, server->packet_size);
 
        smb_lock_server(server);
@@ -1078,7 +1067,7 @@ smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry)
 
       retry:
        p = smb_setup_header(server, SMBmv, 1, 0);
-       WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);
+       WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN | aDIR);
        *p++ = 4;
        p = smb_encode_path(server, p, old_dentry, NULL);
        *p++ = 4;
@@ -1141,6 +1130,7 @@ smb_proc_rmdir(struct dentry *dentry)
 }
 
 
+#if SMBFS_POSIX_UNLINK
 /*
  * Note: called with the server locked.
  * removes readonly attribute from a file. Used by unlink to give posix semantics
@@ -1163,6 +1153,7 @@ smb_set_rw(struct dentry *dentry,struct smb_sb_info *server)
         }
         return result;
 }
+#endif
 
 int
 smb_proc_unlink(struct dentry *dentry)
@@ -1313,15 +1304,16 @@ smb_decode_long_dirent(struct smb_sb_info *server, char *p,
 
        result = p + WVAL(p, 0);
        len = DVAL(p, 60);
-       if (len > 255) len = 255;
+       if (len > SMB_MAXNAMELEN)
+               len = SMB_MAXNAMELEN;
        /* NT4 null terminates */
        entry->name = p + 94;
        if (len && entry->name[len-1] == '\0')
                len--;
        entry->len = len;
 
-       VERBOSE("smb_decode_long_dirent: info 260 at %p, len=%d, name=%s\n",
-               p, entry->len, entry->name);
+       VERBOSE("info 260 at %p, len=%d, name=%.*s\n",
+               p, entry->len, entry->len, entry->name);
 
        return result;
 }
@@ -1343,7 +1335,8 @@ static int
 smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos,
                      void *cachep)
 {
-       char *p, *mask, *param = server->temp_buf;
+       unsigned char *p;
+       char *mask, *param = server->temp_buf;
        __u16 command;
        int first, entries, entries_seen;
        int info_level = 260;
@@ -1370,8 +1363,7 @@ smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos,
        mask_len = smb_encode_path(server, mask, dir, &star) - mask;
        first = 1;
 
-       VERBOSE("smb_proc_readdir_long: starting fpos=%d, mask=%s\n",
-               fpos, mask);
+       VERBOSE("starting fpos=%d, mask=%s\n", fpos, mask);
 
        /*
         * We must reinitialize the dircache when retrying.
@@ -1381,19 +1373,16 @@ smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos,
        entries_seen = 2;
        ff_eos = 0;
 
-       while (ff_eos == 0)
-       {
+       while (ff_eos == 0) {
                loop_count += 1;
-               if (loop_count > 10)
-               {
+               if (loop_count > 10) {
                        printk(KERN_WARNING "smb_proc_readdir_long: "
                               "Looping in FIND_NEXT??\n");
                        entries = -EIO;
                        break;
                }
 
-               if (first != 0)
-               {
+               if (first != 0) {
                        command = TRANSACT2_FINDFIRST;
                        WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
                        WSET(param, 2, max_matches);    /* max count */
@@ -1401,15 +1390,14 @@ smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos,
                             SMB_CONTINUE_BIT|SMB_CLOSE_IF_END); 
                        WSET(param, 6, info_level);
                        DSET(param, 8, 0);
-               } else
-               {
+               } else {
                        /* we don't need the mask after the first bit */
                        mask_len = 0;
                        mask[0] = 0;
 
                        command = TRANSACT2_FINDNEXT;
 
-                       VERBOSE("smb_proc_readdir_long: handle=0x%X, mask=%s\n",
+                       VERBOSE("handle=0x%X, mask=%s\n",
                                ff_dir_handle, mask);
 
                        WSET(param, 0, ff_dir_handle);  /* search handle */
@@ -1425,14 +1413,12 @@ smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos,
                                            &resp_data_len, &resp_data,
                                            &resp_param_len, &resp_param);
 
-               if (result < 0)
-               {
-                       if (smb_retry(server))
-                       {
-                               PARANOIA("smb_proc_readdir_long: error=%d, retrying\n", result);
+               if (result < 0) {
+                       if (smb_retry(server)) {
+                               PARANOIA("error=%d, retrying\n", result);
                                goto retry;
                        }
-                       PARANOIA("smb_proc_readdir_long: error=%d, breaking\n", result);
+                       PARANOIA("error=%d, breaking\n", result);
                        entries = result;
                        break;
                }
@@ -1446,64 +1432,68 @@ smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos,
                        continue;
                }
 
-               if (server->rcls != 0)
-               { 
-                       PARANOIA("smb_proc_readdir_long: name=%s, entries=%d, rcls=%d, err=%d\n",
+               if (server->rcls != 0) {
+                       PARANOIA("name=%s, entries=%d, rcls=%d, err=%d\n",
                                 mask, entries, server->rcls, server->err);
                        entries = -smb_errno(server);
                        break;
                }
 
                /* parse out some important return info */
-               if (first != 0)
-               {
+               if (first != 0) {
                        ff_dir_handle = WVAL(resp_param, 0);
                        ff_searchcount = WVAL(resp_param, 2);
                        ff_eos = WVAL(resp_param, 4);
-               } else
-               {
+               } else {
                        ff_searchcount = WVAL(resp_param, 0);
                        ff_eos = WVAL(resp_param, 2);
                }
 
                if (ff_searchcount == 0)
-               {
                        break;
-               }
 
                /* Now we are ready to parse smb directory entries. */
 
                /* point to the data bytes */
                p = resp_data;
-               for (i = 0; i < ff_searchcount; i++)
-               {
+               for (i = 0; i < ff_searchcount; i++) {
                        struct cache_dirent this_ent, *entry = &this_ent;
 
+                       /* make sure we stay within the buffer */
+                       if (p >= resp_data + resp_data_len) {
+                               printk(KERN_ERR "smb_proc_readdir_long: "
+                                      "dirent pointer outside buffer! "
+                                      "%p  %d@%p  %d@%p\n",
+                                      p, resp_data_len, resp_data,
+                                      server->packet_size, server->packet);
+                               result = -EIO; /* always a comm. error? */
+                               goto unlock_return;
+                       }
+
                        p = smb_decode_long_dirent(server, p, entry);
 
                        /* ignore . and .. from the server */
-                       if (entries_seen == 2 && entry->name[0] == '.')
-                       {
+                       if (entries_seen == 2 && entry->name[0] == '.') {
                                if (entry->len == 1)
                                        continue;
                                if (entry->name[1] == '.' && entry->len == 2)
                                        continue;
                        }
-                       if (entries_seen >= fpos)
-                       {
+                       if (entries_seen >= fpos) {
                                smb_add_to_cache(cachep, entry, entries_seen);
                                entries += 1;
                        }
                        entries_seen++;
                }
 
-               VERBOSE("smb_proc_readdir_long: received %d entries, eos=%d\n",
+               VERBOSE("received %d entries, eos=%d\n",
                        ff_searchcount, ff_eos);
 
                first = 0;
                loop_count = 0;
        }
 
+unlock_return:
        smb_unlock_server(server);
        return entries;
 }
@@ -1533,8 +1523,7 @@ smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir,
        p = smb_encode_path(server, p, dir, NULL);
        smb_setup_bcc(server, p);
 
-       if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0)
-       {
+       if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0) {
                if (smb_retry(server))
                        goto retry;
                goto out;
@@ -1599,7 +1588,7 @@ smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir,
        }
        if (server->rcls != 0)
        {
-               VERBOSE("smb_proc_getattr_trans2: for %s: result=%d, rcls=%d, err=%d\n",
+               VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
                        &param[6], result, server->rcls, server->err);
                result = -smb_errno(server);
                goto out;
@@ -1607,7 +1596,7 @@ smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir,
        result = -ENOENT;
        if (resp_data_len < 22)
        {
-               PARANOIA("smb_proc_getattr_trans2: not enough data for %s, len=%d\n",
+               PARANOIA("not enough data for %s, len=%d\n",
                         &param[6], resp_data_len);
                goto out;
        }
@@ -1649,7 +1638,8 @@ out:
  * get the file attribute
  */
 static int
-smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,struct smb_sb_info *server)
+smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,
+                   struct smb_sb_info *server)
 {
        int result;
 
@@ -1740,8 +1730,8 @@ smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr)
        struct smb_sb_info *server = server_from_dentry(dir);
        int result;
 
-       VERBOSE("smb_proc_setattr: setting %s/%s, open=%d\n", 
-               DENTRY_PATH(dir), smb_is_open(dir->d_inode));
+       VERBOSE("setting %s/%s, open=%d\n", DENTRY_PATH(dir),
+               smb_is_open(dir->d_inode));
 
        smb_lock_server(server);
        result = smb_proc_setattr_core(server, dir, fattr->attr);
@@ -1872,26 +1862,23 @@ smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr)
        struct inode *inode = dentry->d_inode;
        int result;
 
-       VERBOSE("smb_proc_settime: setting %s/%s, open=%d\n", 
-               DENTRY_PATH(dentry), smb_is_open(inode));
+       VERBOSE("setting %s/%s, open=%d\n", DENTRY_PATH(dentry),
+               smb_is_open(inode));
 
        smb_lock_server(server);
        /* setting the time on a Win95 server fails (tridge) */
-       if (!(server->mnt->version & SMB_FIX_WIN95))
-       {
+       if (!(server->mnt->version & SMB_FIX_WIN95)) {
                if (smb_is_open(inode) &&
                    inode->u.smbfs_i.access != SMB_O_RDONLY)
                        result = smb_proc_setattr_ext(server, inode, fattr);
                else
                        result = smb_proc_setattr_trans2(server, dentry, fattr);
-       } else
-       {
+       } else {
                /*
                 * Fail silently on directories ... timestamp can't be set?
                 */
                result = 0;
-               if (S_ISREG(inode->i_mode))
-               {
+               if (S_ISREG(inode->i_mode)) {
                        /*
                         * Set the mtime by opening and closing the file.
                         * Note that the file is opened read-only, but this
@@ -1900,8 +1887,7 @@ smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr)
                        result = -EACCES;
                        if (!smb_is_open(inode))
                                smb_proc_open(server, dentry, SMB_O_RDONLY);
-                       if (smb_is_open(inode))
-                       {
+                       if (smb_is_open(inode)) {
                                inode->i_mtime = fattr->f_mtime;
                                result = smb_proc_close_inode(server, inode);
                        }
@@ -1924,8 +1910,7 @@ smb_proc_dskattr(struct super_block *sb, struct statfs *attr)
       retry:
        smb_setup_header(server, SMBdskattr, 0, 0);
 
-       if ((error = smb_request_ok(server, SMBdskattr, 5, 0)) < 0)
-       {
+       if ((error = smb_request_ok(server, SMBdskattr, 5, 0)) < 0) {
                if (smb_retry(server))
                        goto retry;
                goto out;
index 0a8d13fd33bd1aba14352c5744e8b367473f679a..1fd2cfd65912c6dbead43a51b1de45449b57c3a5 100644 (file)
@@ -2,19 +2,23 @@
  * Defines some debug macros for smbfs.
  */
 
+/* This makes a dentry parent/child pair. Useful for debugging printk's */
+#define DENTRY_PATH(dentry) \
+       (dentry)->d_parent->d_name.name,(dentry)->d_name.name
+
 /*
  * safety checks that should never happen ??? 
  * these are normally enabled.
  */
 #ifdef SMBFS_PARANOIA
-#define PARANOIA(x...) printk(KERN_NOTICE ## x);
+#define PARANOIA(x...) printk(KERN_NOTICE __FUNCTION__ ": " ## x)
 #else
 #define PARANOIA(x...) do { ; } while(0)
 #endif
 
 /* lots of debug messages */
 #ifdef SMBFS_DEBUG_VERBOSE
-#define VERBOSE(x...) printk(KERN_DEBUG ## x);
+#define VERBOSE(x...) printk(KERN_DEBUG __FUNCTION__ ": " ## x)
 #else
 #define VERBOSE(x...) do { ; } while(0)
 #endif
@@ -24,7 +28,7 @@
  * too common name.
  */
 #ifdef SMBFS_DEBUG
-#define DEBUG1(x...) printk(KERN_DEBUG ## x);
+#define DEBUG1(x...) printk(KERN_DEBUG __FUNCTION__ ": " ## x)
 #else
 #define DEBUG1(x...) do { ; } while(0)
 #endif
index 76d4a1709661d378f3ac6e0a10cba448a346d06c..fa0a3b2e3a7deec0eb7d93e6acb9ff044bde9ec1 100644 (file)
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/sched.h>
@@ -25,9 +26,6 @@
 
 #include <asm/uaccess.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-
 #include "smb_debug.h"
 
 static int
@@ -120,7 +118,7 @@ smb_data_callback(void* ptr)
                result = -EIO;
                if (job->sk->dead)
                {
-                       PARANOIA("smb_data_callback: sock dead!\n");
+                       PARANOIA("sock dead!\n");
                        break;
                }
 
@@ -135,7 +133,7 @@ smb_data_callback(void* ptr)
                result = _recvfrom(socket, (void *) peek_buf, 4,
                                   MSG_DONTWAIT);
 
-               DEBUG1("smb_data_callback: got SESSION KEEPALIVE\n");
+               DEBUG1("got SESSION KEEPALIVE\n");
 
                if (result == -EAGAIN)
                        break;
@@ -154,7 +152,7 @@ smb_data_ready(struct sock *sk, int len)
        struct data_callback* job;
        job = kmalloc(sizeof(struct data_callback),GFP_ATOMIC);
        if(job == 0) {
-               printk("smb_data_ready(): lost SESSION KEEPALIVE due to OOM.\n");
+               printk("smb_data_ready: lost SESSION KEEPALIVE due to OOM.\n");
                found_data(sk);
                return;
        }
@@ -182,7 +180,7 @@ server_sock(struct smb_sb_info *server)
        {
 #ifdef SMBFS_PARANOIA
                if (!smb_valid_socket(file->f_dentry->d_inode))
-                       PARANOIA("smb_server_sock: bad socket!\n");
+                       PARANOIA("bad socket!\n");
 #endif
                return &file->f_dentry->d_inode->u.socket_i;
        }
@@ -209,11 +207,11 @@ smb_catch_keepalive(struct smb_sb_info *server)
        sk = socket->sk;
        if (sk == NULL)
        {
-               DEBUG1("smb_catch_keepalive: sk == NULL");
+               DEBUG1("sk == NULL");
                server->data_ready = NULL;
                goto out;
        }
-       DEBUG1("smb_catch_keepalive.: sk->d_r = %x, server->d_r = %x\n",
+       DEBUG1("sk->d_r = %x, server->d_r = %x\n",
               (unsigned int) (sk->data_ready),
               (unsigned int) (server->data_ready));
 
@@ -261,9 +259,9 @@ smb_dont_catch_keepalive(struct smb_sb_info *server)
                       "server->data_ready == NULL\n");
                goto out;
        }
-       pr_debug("smb_dont_catch_keepalive: sk->d_r = %x, server->d_r = %x\n",
-                (unsigned int) (sk->data_ready),
-                (unsigned int) (server->data_ready));
+       DEBUG1("sk->d_r = %x, server->d_r = %x\n",
+              (unsigned int) (sk->data_ready),
+              (unsigned int) (server->data_ready));
 
        /*
         * Restore the original callback atomically to avoid races ...
@@ -272,7 +270,7 @@ smb_dont_catch_keepalive(struct smb_sb_info *server)
        server->data_ready = NULL;
        if (data_ready != smb_data_ready)
        {
-               printk("smb_dont_catch_keepalive: "
+               printk(KERN_ERR "smb_dont_catch_keepalive: "
                       "sk->data_ready != smb_data_ready\n");
        }
        error = 0;
@@ -288,13 +286,11 @@ smb_close_socket(struct smb_sb_info *server)
 {
        struct file * file = server->sock_file;
 
-       if (file)
-       {
-               VERBOSE("smb_close_socket: closing socket %p\n",
-                       server_sock(server));
+       if (file) {
+               VERBOSE("closing socket %p\n", server_sock(server));
 #ifdef SMBFS_PARANOIA
                if (server_sock(server)->sk->data_ready == smb_data_ready)
-                       PARANOIA("smb_close_socket: still catching keepalives!\n");
+                       PARANOIA("still catching keepalives!\n");
 #endif
                server->sock_file = NULL;
                fput(file);
@@ -319,7 +315,7 @@ smb_send_raw(struct socket *socket, unsigned char *source, int length)
                }
                if (result < 0)
                {
-                       DEBUG1("smb_send_raw: sendto error = %d\n", -result);
+                       DEBUG1("sendto error = %d\n", -result);
                        return result;
                }
                already_sent += result;
@@ -345,8 +341,7 @@ smb_receive_raw(struct socket *socket, unsigned char *target, int length)
                }
                if (result < 0)
                {
-                       DEBUG1("smb_receive_raw: recvfrom error = %d\n",
-                              -result);
+                       DEBUG1("recvfrom error = %d\n", -result);
                        return result;
                }
                already_read += result;
@@ -369,7 +364,7 @@ smb_get_length(struct socket *socket, unsigned char *header)
 
        if (result < 0)
        {
-               PARANOIA("smb_get_length: recv error = %d\n", -result);
+               PARANOIA("recv error = %d\n", -result);
                return result;
        }
        switch (peek_buf[0])
@@ -379,12 +374,11 @@ smb_get_length(struct socket *socket, unsigned char *header)
                break;
 
        case 0x85:
-               DEBUG1("smb_get_length: Got SESSION KEEP ALIVE\n");
+               DEBUG1("Got SESSION KEEP ALIVE\n");
                goto re_recv;
 
        default:
-               PARANOIA("smb_get_length: Invalid NBT packet, code=%x\n",
-                        peek_buf[0]);
+               PARANOIA("Invalid NBT packet, code=%x\n", peek_buf[0]);
                return -EIO;
        }
 
@@ -443,7 +437,7 @@ smb_receive(struct smb_sb_info *server)
        result = smb_receive_raw(socket, packet + 4, len);
        if (result < 0)
        {
-               VERBOSE("smb_receive: receive error: %d\n", result);
+               VERBOSE("receive error: %d\n", result);
                goto out;
        }
        server->rcls = *(packet + smb_rcls);
@@ -451,8 +445,7 @@ smb_receive(struct smb_sb_info *server)
 
 #ifdef SMBFS_DEBUG_VERBOSE
        if (server->rcls != 0)
-               VERBOSE("smb_receive: rcls=%d, err=%d\n",
-                       server->rcls, server->err);
+               VERBOSE("rcls=%d, err=%d\n", server->rcls, server->err);
 #endif
 out:
        return result;
@@ -515,7 +508,7 @@ smb_receive_trans2(struct smb_sb_info *server,
                         */
                        if (parm_count == parm_tot && data_count == data_tot)
                        {
-                               VERBOSE("smb_receive_trans2: fast track, parm=%u %u %u, data=%u %u %u\n",
+                               VERBOSE("fast track, parm=%u %u %u, data=%u %u %u\n",
                                        parm_disp, parm_offset, parm_count, 
                                        data_disp, data_offset, data_count);
 
@@ -555,7 +548,7 @@ smb_receive_trans2(struct smb_sb_info *server,
                memcpy(*parm + parm_disp, base + parm_offset, parm_count);
                memcpy(*data + data_disp, base + data_offset, data_count);
 
-               PARANOIA("smb_receive_trans2: copied, parm=%u of %u, data=%u of %u\n",
+               PARANOIA("copied, parm=%u of %u, data=%u of %u\n",
                         parm_len, parm_tot, data_len, data_tot);
 
                /*
@@ -577,9 +570,8 @@ smb_receive_trans2(struct smb_sb_info *server,
                server->packet_size = buf_len;
                server->packet = rcv_buf;
                rcv_buf = inbuf;
-       } else
-       {
-               PARANOIA("smb_receive_trans2: copying data, old size=%d, new size=%u\n",
+       } else {
+               PARANOIA("copying data, old size=%d, new size=%u\n",
                         server->packet_size, buf_len);
                memcpy(inbuf, rcv_buf, parm_len + data_len);
        }
@@ -593,7 +585,7 @@ out:
        return result;
 
 out_no_mem:
-       PARANOIA("smb_receive_trans2: couldn't allocate data area\n");
+       printk(KERN_ERR "smb_receive_trans2: couldn't allocate data area\n");
        result = -ENOMEM;
        goto out;
 out_too_long:
@@ -640,7 +632,7 @@ smb_request(struct smb_sb_info *server)
                goto bad_conn;
 
        len = smb_len(buffer) + 4;
-       DEBUG1("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]);
+       DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]);
 
        spin_lock_irqsave(&current->sigmask_lock, flags);
        sigpipe = sigismember(&current->signal, SIGPIPE);
@@ -692,14 +684,14 @@ smb_request(struct smb_sb_info *server)
        }
 
 out:
-       DEBUG1("smb_request: result = %d\n", result);
+       DEBUG1("result = %d\n", result);
        return result;
        
 bad_conn:
-       PARANOIA("smb_request: result %d, setting invalid\n", result);
+       PARANOIA("result %d, setting invalid\n", result);
        server->state = CONN_INVALID;
        smb_invalidate_inodes(server);
-       goto out;               
+       goto out;
 bad_no_packet:
        printk(KERN_ERR "smb_request: no packet!\n");
        goto out;
@@ -806,8 +798,7 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
        mm_segment_t fs;
        int result;
 
-       DEBUG1("smb_trans2_request: com=%d, ld=%d, lp=%d\n",
-              trans2_command, ldata, lparam);
+       DEBUG1("com=%d, ld=%d, lp=%d\n", trans2_command, ldata, lparam);
 
        /*
         * These are initialized in smb_request_ok, but not here??
@@ -876,7 +867,7 @@ out:
        return result;
 
 bad_conn:
-       PARANOIA("smb_trans2_request: result=%d, setting invalid\n", result);
+       PARANOIA("result=%d, setting invalid\n", result);
        server->state = CONN_INVALID;
        smb_invalidate_inodes(server);
        goto out;
index 79347c2dc732396419374c0150e084f431501a90..27067efb8b3a6487dc32efe814f28fa2591af924 100644 (file)
@@ -5,20 +5,16 @@ Changes by Matija Nalis (mnalis@jagor.srce.hr) on umsdos dentry fixing
 There is no warning any more.
 Both read-only and read-write stuff is fixed, both in
 msdos-compatibile mode, and in umsdos EMD mode, and it seems stable.
-There are still few hardlink nuisances, but those are not fatal.
-
-I'd call it pre-release, and ask for as many people as possible to
-come and test it! See notes below for some more information, or if
-you are trying to use UMSDOS as root partition.
 
 Userland NOTE: new umsdos_progs (umssync, umssetup, udosctl & friends) that
-will compile and work on 2.2.x kernels and glibc based systems may be found
-at http://cvs.linux.hr/
+will compile and work on 2.2.x+ kernels and glibc based systems, as well as
+kernel patches and other umsdos related information may be found at
+http://linux.voyager.hr/umsdos/
 
 Legend: those lines marked with '+' on the beggining of line indicates it
 passed all of my tests, and performed perfect in all of them.
 
-Current status (000123) - UMSDOS 0.85g:
+Current status (000729) - UMSDOS 0.85i:
 
 (1) pure MSDOS (no --linux-.--- EMD file):
 
@@ -29,7 +25,7 @@ READ:
 
 WRITE:
 + creat file                   - works
-+ delete file                  - works
++ unlink file                  - works
 + write file                   - works
 + rename file (same dir)       - works
 + rename file (dif. dir)       - works
@@ -49,7 +45,7 @@ READ:
 + read file                    - works
 + switching MSDOS/UMSDOS       - works
 + switching UMSDOS/MSDOS       - works
-- pseudo root things           - works mostly. See notes below.
+- pseudo root things           - works. See notes below.
 + resolve symlink              - works
 + dereference symlink          - works
 + dangling symlink             - works
@@ -60,21 +56,21 @@ READ:
 
 WRITE:
 + create symlink               - works
-- create hardlink              - works for same DIR (see notes)
++ create hardlink              - works
 + create file                  - works
 + create special file          - works
 + write to file                        - works
 + rename file (same dir)       - works
 + rename file (dif. dir)       - works
 + rename hardlink (same dir)   - works
-- rename hardlink (dif. dir)   -
++ rename hardlink (dif. dir)   - works
 + rename symlink (same dir)    - works
 + rename symlink (dif. dir)    - works
 + rename dir (same dir)                - works
 + rename dir (dif. dir)                - works
 + delete file                  - works
 + notify_change (chown,perms)  - works
-- delete hardlink              - works for same DIR (see notes)
++ delete hardlink              - works
 + mkdir                                - works
 + rmdir                        - works
 + umssyncing (many ioctls)     - works
@@ -91,26 +87,13 @@ Some current notes:
 Note: creating and using pseudo-hardlinks is always non-perfect, especially
 in filesystems that might be externally modified like umsdos. There is
 example is specs file about it. Specifically, moving directory which
-contains hardlinks will break them.
-
-Note: (about pseudoroot) If you are currently trying to use UMSDOS as root
-partition (with linux installed in c:\linux) it will boot, but there may be
-some problems. Volunteers ready to test pseudoroot are needed (preferably
-ones with working backups or unimportant data).  For example, '/DOS' pseudo
-directory is only partially re-implemented and buggy. It works most of the
-time, though. Update: should work ok in 0.84, although it still does not
-work correctly in combination with initrd featere. Working on this!
+contains hardlinks will break them in some cases.
 
 Note: (about creating hardlinks in pseudoroot mode) - hardlinks created in
 pseudoroot mode are now again compatibile with 'normal' hardlinks, and vice
 versa. Thanks to Sorin Iordachescu <sorin@rodae.ro> for providing fix.
-
-Warning: (about hardlinks) - modifying hardlinks (esp. if they are in
-different directories) are currently somewhat broken, I'm working on it.
-Problem seems to be that code uses and updates EMD of directory where 'real
-hardlink' is stored, not EMD of directory where our pseudo-hardlink is
-located! I'm looking for ideas how to work around this in clean way, since
-without it modifying hardlinks in any but most simple ways is broken!
+See http://linux.voyager.hr/umsdos/hlbug.html for more info and upgrade
+procedure if you used broken versions...
 
 ------------------------------------------------------------------------------
 
@@ -124,6 +107,5 @@ or panics which force you to reboot etc.)
 I'm unfortunately somewhat out of time to read linux-kernel@vger, but I do
 check for messages having "UMSDOS" in the subject, and read them.  I might
 miss some in all that volume, though.  I should reply to any direct e-mail
-in few days.  If I don't, probably I never got your message.  You can try
-mnalis-umsdos@voyager.hr; however mnalis@jagor.srce.hr is preferable.
+in few days.  If I don't, probably I never got your message.
 
index 1cd61bfda293b6c6dfd7dcbceb760e474e65f345..33c2056a2cacd1e8e9a3a0364249bd04b517210d 100644 (file)
@@ -273,6 +273,16 @@ int umsdos_emd_dir_readentry (struct file *filp, struct umsdos_dirent *entry)
        Printk ((KERN_DEBUG "umsdos_emd_dir_readentry /mn/: entering.\n"));
 
        ret = umsdos_emd_dir_read (filp, (char *) entry, UMSDOS_REC_SIZE);
+
+       /* if this is an invalid entry (invalid name length), ignore it */
+       if( entry->name_len > UMSDOS_MAXNAME )
+       {
+               printk (KERN_WARNING "Ignoring invalid EMD entry with size %d\n", entry->name_len);
+               entry->name_len = 0; 
+               ret = -ENAMETOOLONG; /* notify umssync(8) code that something is wrong */
+       }
+
+
        if (ret == 0) { /* if no error */
                /* Variable size record. Maybe, we have to read some more */
                int recsize = umsdos_evalrecsize (entry->name_len);
index 6aaa5002ec32795c2216dc1ee5a3fe85da77995a..78b0f28f7239b095baeefb02386b9a16578df952 100644 (file)
@@ -56,8 +56,7 @@ void UMSDOS_put_inode (struct inode *inode)
                 ,inode->i_count));
 
        if (inode == pseudo_root) {
-               printk (KERN_ERR "Umsdos: Oops releasing pseudo_root."
-                       " Notify jacques@solucorp.qc.ca\n");
+               printk (KERN_ERR "Umsdos: debug: releasing pseudo_root - ino=%lu count=%d\n", inode->i_ino, inode->i_count);
        }
 
        if (inode->i_count == 1)
@@ -180,21 +179,6 @@ dentry, f_pos));
 }
 
 
-int umsdos_notify_change_locked(struct dentry *, struct iattr *);
-/*
- * lock the parent dir before starting ...
- */
-int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
-{
-       struct inode *dir = dentry->d_parent->d_inode;
-       int ret;
-
-       down(&dir->i_sem);
-       ret = umsdos_notify_change_locked(dentry, attr);
-       up(&dir->i_sem);
-       return ret;
-}
-
 /*
  * Must be called with the parent lock held.
  */
@@ -299,6 +283,65 @@ out:
 }
 
 
+/*
+ * lock the parent dir before starting ...
+ * also handles hardlink converting
+ */
+int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
+{
+       struct inode *dir;
+       struct umsdos_info info;
+       struct dentry *temp, *old_dentry = NULL;
+       int ret;
+
+       ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len,
+                               &info);
+       if (ret)
+               goto out;
+       ret = umsdos_findentry (dentry->d_parent, &info, 0);
+       if (ret) {
+printk("UMSDOS_notify_change: %s/%s not in EMD, ret=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, ret);
+               goto out;
+       }
+
+       if (info.entry.flags & UMSDOS_HLINK) {
+               /*
+                * In order to get the correct (real) inode, we just drop
+                * the original dentry.
+                */ 
+               d_drop(dentry);
+Printk(("UMSDOS_notify_change: hard link %s/%s, fake=%s\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, info.fake.fname));
+       
+               /* Do a real lookup to get the short name dentry */
+               temp = umsdos_covered(dentry->d_parent, info.fake.fname,
+                                               info.fake.len);
+               ret = PTR_ERR(temp);
+               if (IS_ERR(temp))
+                       goto out;
+       
+               /* now resolve the link ... */
+               temp = umsdos_solve_hlink(temp);
+               ret = PTR_ERR(temp);
+               if (IS_ERR(temp))
+                       goto out;
+               old_dentry = dentry;
+               dentry = temp;  /* so umsdos_notify_change_locked will operate on that */
+       }
+
+       dir = dentry->d_parent->d_inode;
+
+       down(&dir->i_sem);
+       ret = umsdos_notify_change_locked(dentry, attr);
+       up(&dir->i_sem);
+out:
+       if (old_dentry)
+               dput (dentry);  /* if we had to use fake dentry for hardlinks, dput() it now */
+       return ret;
+}
+
+
 /*
  * Update the disk with the inode content
  */
@@ -332,11 +375,28 @@ static struct super_operations umsdos_sops =
        UMSDOS_notify_change,   /* notify_change */
        UMSDOS_put_super,       /* put_super */
        NULL,                   /* write_super */
-       fat_statfs,             /* statfs */
+       UMSDOS_statfs,          /* statfs */
        NULL,                   /* remount_fs */
        fat_clear_inode,        /* clear_inode */
 };
 
+
+int UMSDOS_statfs(struct super_block *sb,struct statfs *buf, int bufsiz)
+{
+       int ret;
+       struct statfs tmp;
+       
+       ret = fat_statfs (sb, buf, bufsiz);
+       copy_from_user (&tmp, buf, bufsiz);
+       if (!ret) {
+               copy_from_user (&tmp, buf, bufsiz);
+               tmp.f_namelen = UMSDOS_MAXNAME;
+               copy_to_user (buf, &tmp, bufsiz);
+       }
+       return ret;
+}
+
+
 /*
  * Read the super block of an Extended MS-DOS FS.
  */
@@ -356,7 +416,7 @@ struct super_block *UMSDOS_read_super (struct super_block *sb, void *data,
        if (!res)
                goto out_fail;
 
-       printk (KERN_INFO "UMSDOS 0.85g "
+       printk (KERN_INFO "UMSDOS 0.85i "
                "(compatibility level %d.%d, fast msdos)\n", 
                UMSDOS_VERSION, UMSDOS_RELEASE);
 
index cc73078dd1c30fc1f7a32a96f4f63ab69ee9d3ce..9bdf87a8ab05491bec805ecc6ee8f7262631b7ac 100644 (file)
@@ -179,6 +179,17 @@ dentry->d_parent->d_name.name, dentry->d_name.name, cmd, data_ptr));
                        struct umsdos_info info;
 
                        ret = umsdos_emd_dir_readentry (&new_filp, &entry);
+
+                       if (ret == -ENAMETOOLONG) {
+                               printk (KERN_INFO "Fixing EMD entry with invalid size -- zeroing out\n");
+                               fill_new_filp (&new_filp, demd);
+                               new_filp.f_pos = f_pos;
+                               new_filp.f_reada = 0;
+                               memset (&entry, 0, sizeof (entry));
+                               ret = umsdos_emd_dir_write (&new_filp, (char *) &entry, UMSDOS_REC_SIZE);
+                               continue;
+                       }
+
                        if (ret)
                                break;
                        if (entry.name_len <= 0)
index ef64d7268f9b78ba9368266d15ac955d56dddea2..7c156e49256f350c175d2894f9a4ee01ea810680 100644 (file)
@@ -715,17 +715,35 @@ out_unlock:
        if (ret == 0) {
                struct iattr newattrs;
 
+               /* Do a real lookup to get the short name dentry */
+               temp = umsdos_covered(olddentry->d_parent,
+                                       old_info.fake.fname,
+                                       old_info.fake.len);
+               ret = PTR_ERR(temp);
+               if (IS_ERR(temp))
+                       goto out_unlock2;
+
+               /* now resolve the link ... */
+               temp = umsdos_solve_hlink(temp);
+               ret = PTR_ERR(temp);
+               if (IS_ERR(temp))
+                       goto out_unlock2;
+
 #ifdef UMSDOS_PARANOIA
 if (!oldinode->u.umsdos_i.i_is_hlink)
 printk("UMSDOS_link: %s/%s, ino=%ld, not marked as hlink!\n",
 olddentry->d_parent->d_name.name, olddentry->d_name.name, oldinode->i_ino);
 #endif
-               oldinode->i_nlink++;
+               temp->d_inode->i_nlink++;
 Printk(("UMSDOS_link: linked %s/%s, ino=%ld, nlink=%d\n",
 olddentry->d_parent->d_name.name, olddentry->d_name.name,
 oldinode->i_ino, oldinode->i_nlink));
                newattrs.ia_valid = 0;
-               ret = umsdos_notify_change_locked(olddentry, &newattrs);
+               ret = umsdos_notify_change_locked(temp, &newattrs);
+               if (ret == 0)
+                       mark_inode_dirty(temp->d_inode);
+               dput(temp);
+out_unlock2:   
        }
        if (olddir != dir)
                up(&olddir->i_sem);
index 04387d8a8d008116fb804ab1bf83d0ff8a4bfb16..59a617c315ef5d1ccfc5b2f480fad479ec5aab68 100644 (file)
 typedef __u8 byte_t;
 typedef __u32 int32;
 
+
+#include <linux/ip.h>
+#include <linux/tcp.h>
 /*
  * "state" data for each active tcp conversation on the wire.  This is
  * basically a copy of the entire IP/TCP header from the last packet
index c4a88b4819ac0e018e3c33dd1fd5ae310632f706..4f577970c2a0306aacdc587775b786f9f0f37765 100644 (file)
@@ -58,6 +58,8 @@
 extern void nubus_init(void);
 #endif
 
+extern int irda_device_init(void);
+
 /*
  * Versions of gcc older than that listed below may actually compile
  * and link okay, but the end product can have subtle run time bugs.
index 67e674a15745e26102da3df8b5bbca979ff02b6c..59940e7f6feaabdac606f38e63db07150005479f 100644 (file)
@@ -729,7 +729,7 @@ static int atrtr_create(struct rtentry *r, struct device *devhint)
 
        if(rt == NULL)
        {
-               rt = (struct atalk_route *)kmalloc(sizeof(struct atalk_route), GFP_KERNEL);
+               rt = (struct atalk_route *)kmalloc(sizeof(struct atalk_route), GFP_ATOMIC);
                if(rt == NULL) {
                        SOCKHASH_UNLOCK();
                        return (-ENOBUFS);
index 400f46c0f8c6361c4613eb35b246f362ea40b6af..6ff3bb1867426c27a68cec5fc88948273a3055a2 100644 (file)
@@ -740,7 +740,7 @@ ip_fw_check(struct iphdr *ip,
                for (; f; f = f->next) {
                        count++;
                        if (ip_rule_match(f,rif,ip,
-                                         tcpsyn,src_port,dst_port,offset)) {
+                                         tcpsyn,src_port,dst_port,offset!=0)) {
                                if (!testing
                                    && !ip_fw_domatch(f, ip, rif, chain->label,
                                                      skb, slot, 
index d753c2b5ee1ef8e57fd01878e368e5ba0326de84..f4c1f2b70eb6c7576c6a244ace5a9f7b45946116 100644 (file)
@@ -63,6 +63,8 @@ extern int esi_init(void);
 extern int tekram_init(void);
 extern int actisys_init(void);
 extern int girbil_init(void);
+extern int toshoboe_init(void);
+extern int litelink_init(void);
 
 static void __irda_task_delete(struct irda_task *task);
 
index d8c0445d8cbca3a71f34b76fa761d894285bd521..41dc7fac9627c3370595b9f85cea9a3614923f3d 100644 (file)
@@ -73,7 +73,7 @@ extern int irlpt_server_init(void);
 
 #ifdef CONFIG_IRDA_COMPRESSION
 #ifdef CONFIG_IRDA_DEFLATE
-extern irda_deflate_init();
+extern irda_deflate_init(void);
 #endif /* CONFIG_IRDA_DEFLATE */
 #endif /* CONFIG_IRDA_COMPRESSION */
 
index b2e3750b2b9c0b057cd5a1cdf51388beb8619bf0..6d4c64d6bff5a5909a910a231d86483ed8792a8c 100644 (file)
@@ -1528,9 +1528,9 @@ int irttp_proc_read(char *buf, char **start, off_t offset, int len, int unused)
                               self->remote_credit);
                len += sprintf(buf+len, "send credit: %d\n",
                               self->send_credit);
-               len += sprintf(buf+len, "  tx packets: %d, ",
+               len += sprintf(buf+len, "  tx packets: %ld, ",
                               self->stats.tx_packets);
-               len += sprintf(buf+len, "rx packets: %d, ",
+               len += sprintf(buf+len, "rx packets: %ld, ",
                               self->stats.rx_packets);
                len += sprintf(buf+len, "tx_queue len: %d ", 
                               skb_queue_len(&self->tx_queue));