From 36f8c7ef27dd599b25aeeb3171bc113847efb097 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 23 Nov 2007 15:21:53 -0500 Subject: [PATCH] Linux 2.2.17pre14 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) --- CREDITS | 2 +- Documentation/Changes | 20 +-- Documentation/i386/boot.txt | 31 +++- MAINTAINERS | 6 +- Makefile | 8 +- arch/alpha/config.in | 6 +- arch/alpha/kernel/setup.c | 2 +- arch/alpha/kernel/sys_cabriolet.c | 2 + arch/alpha/kernel/sys_eb64p.c | 12 +- drivers/block/ide-proc.c | 2 +- drivers/block/ide.c | 4 +- drivers/block/raid0.c | 2 +- drivers/char/generic_serial.c | 138 ++++++++++----- drivers/char/i2c.c | 2 +- drivers/char/ip2main.c | 2 +- drivers/char/misc.c | 1 + drivers/char/rio/func.h | 2 + drivers/char/rio/host.h | 8 +- drivers/char/rio/linux_compat.h | 3 - drivers/char/rio/rio_linux.c | 281 +++++++++--------------------- drivers/char/rio/rio_linux.h | 26 +++ drivers/char/rio/rioboot.c | 112 +++++++----- drivers/char/rio/riocmd.c | 3 - drivers/char/rio/rioctrl.c | 5 +- drivers/char/rio/riodrvr.h | 2 +- drivers/char/rio/rioinit.c | 2 +- drivers/char/rio/riointr.c | 2 - drivers/char/rio/rioparam.c | 1 - drivers/char/rio/rioroute.c | 1 - drivers/char/rio/riotable.c | 1 - drivers/char/rio/riotty.c | 39 ++++- drivers/char/rio/unixrup.h | 2 +- drivers/char/sx.c | 118 ++++++------- drivers/char/tty_io.c | 2 + drivers/i2o/i2o_block.c | 154 ++++++++-------- drivers/i2o/i2o_scsi.h | 2 + drivers/isdn/isdn_cards.c | 1 + drivers/isdn/isdn_ppp.h | 1 + drivers/macintosh/via-pmu.c | 78 +++++---- drivers/net/Space.c | 2 + drivers/net/bonding.c | 2 +- drivers/net/c101.c | 16 +- drivers/net/ewrk3.c | 3 +- drivers/net/gmac.c | 55 ++++-- drivers/net/gmac.h | 14 +- drivers/net/hd6457x.c | 4 +- drivers/net/hdlc.c | 25 +-- drivers/net/n2.c | 16 +- drivers/net/slhc.c | 2 +- drivers/pnp/parport_probe.c | 1 + drivers/scsi/3w-xxxx.c | 185 ++++++++++++++++++-- drivers/scsi/3w-xxxx.h | 13 +- drivers/scsi/eata.c | 2 +- drivers/scsi/imm.c | 45 +++-- drivers/scsi/imm.h | 9 +- drivers/scsi/ini9100u.h | 2 + drivers/scsi/inia100.h | 2 + drivers/scsi/ppa.c | 36 ++-- drivers/scsi/ppa.h | 9 +- drivers/scsi/scsi_ioctl.c | 1 + drivers/scsi/tmscsim.c | 1 + drivers/sound/Makefile | 10 +- drivers/sound/emu10k1/main.c | 7 + drivers/sound/i810_audio.c | 9 +- drivers/sound/maestro.c | 2 +- drivers/sound/sound_core.c | 6 + fs/isofs/dir.c | 19 +- fs/isofs/inode.c | 2 +- fs/ncpfs/ncplib_kernel.h | 4 +- fs/smbfs/ChangeLog | 49 ++++++ fs/smbfs/cache.c | 53 +++--- fs/smbfs/dir.c | 96 ++++------ fs/smbfs/file.c | 92 ++++------ fs/smbfs/inode.c | 47 +++-- fs/smbfs/ioctl.c | 12 +- fs/smbfs/proc.c | 185 +++++++++----------- fs/smbfs/smb_debug.h | 10 +- fs/smbfs/sock.c | 73 ++++---- fs/umsdos/README-WIP.txt | 44 ++--- fs/umsdos/emd.c | 10 ++ fs/umsdos/inode.c | 98 +++++++++-- fs/umsdos/ioctl.c | 11 ++ fs/umsdos/namei.c | 22 ++- include/net/slhc_vj.h | 3 + init/main.c | 2 + net/appletalk/ddp.c | 2 +- net/ipv4/ip_fw.c | 2 +- net/irda/irda_device.c | 2 + net/irda/irmod.c | 2 +- net/irda/irttp.c | 4 +- 90 files changed, 1381 insertions(+), 1028 deletions(-) create mode 100644 fs/smbfs/ChangeLog diff --git a/CREDITS b/CREDITS index 44b8e4fe5be4..0bc7427478f2 100644 --- 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 diff --git a/Documentation/Changes b/Documentation/Changes index 405b900ac5b8..da4e701e704f 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -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 ============ diff --git a/Documentation/i386/boot.txt b/Documentation/i386/boot.txt index 5b600161d2c3..1622e4af377c 100644 --- a/Documentation/i386/boot.txt +++ b/Documentation/i386/boot.txt @@ -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 diff --git a/MAINTAINERS b/MAINTAINERS index cd389ad0f465..487c00044787 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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 diff --git a/Makefile b/Makefile index a5da9d79ada9..7bc418919b8f 100644 --- 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; \ diff --git a/arch/alpha/config.in b/arch/alpha/config.in index d26f0bff07c7..15c93d422658 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -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 diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index cd61bde288ac..4aa45c911cf7 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -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 = diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c index 37f29e1472d4..8c20579fe9a7 100644 --- a/arch/alpha/kernel/sys_cabriolet.c +++ b/arch/alpha/kernel/sys_cabriolet.c @@ -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 = { diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c index 683baa02e3e5..c80a778a0b80 100644 --- a/arch/alpha/kernel/sys_eb64p.c +++ b/arch/alpha/kernel/sys_eb64p.c @@ -26,6 +26,7 @@ #include #include #include +#include #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; diff --git a/drivers/block/ide-proc.c b/drivers/block/ide-proc.c index 3f0ca608f6ca..a0f664d9ecab 100644 --- a/drivers/block/ide-proc.c +++ b/drivers/block/ide-proc.c @@ -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 diff --git a/drivers/block/ide.c b/drivers/block/ide.c index fd77a149d011..f47b7a59370c 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -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) diff --git a/drivers/block/raid0.c b/drivers/block/raid0.c index 37b2035cdc9c..17c13342b7c1 100644 --- a/drivers/block/raid0.c +++ b/drivers/block/raid0.c @@ -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; } diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index a10a0fce5e8b..6c19753714ba 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c @@ -12,12 +12,18 @@ * 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 #include #include #include +#include #include #include #include @@ -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); diff --git a/drivers/char/i2c.c b/drivers/char/i2c.c index 6da6bd6b2f1f..1e6ac0bc0ec0 100644 --- a/drivers/char/i2c.c +++ b/drivers/char/i2c.c @@ -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); diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c index 3fd9b748f646..8cd9636c1aa1 100644 --- a/drivers/char/ip2main.c +++ b/drivers/char/ip2main.c @@ -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 ) { diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 23ad031610c5..4d45be5062ef 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -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); diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h index f51eeb0bb5a4..3cf72f3e4632 100644 --- a/drivers/char/rio/func.h +++ b/drivers/char/rio/func.h @@ -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 */ diff --git a/drivers/char/rio/host.h b/drivers/char/rio/host.h index 9836ce5225a9..12c47eae2116 100644 --- a/drivers/char/rio/host.h +++ b/drivers/char/rio/host.h @@ -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; /* diff --git a/drivers/char/rio/linux_compat.h b/drivers/char/rio/linux_compat.h index 3656d93e7e8f..3b6d2f3b1a93 100644 --- a/drivers/char/rio/linux_compat.h +++ b/drivers/char/rio/linux_compat.h @@ -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__) diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index aeed5f095251..90bdb867cea5 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c @@ -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 - -#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 - -#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 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;iRIONumHosts;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 */ diff --git a/drivers/char/rio/rio_linux.h b/drivers/char/rio/rio_linux.h index 3f7dcd2f003f..c8b72bdce94c 100644 --- a/drivers/char/rio/rio_linux.h +++ b/drivers/char/rio/rio_linux.h @@ -23,6 +23,7 @@ * Version 1.0 -- July, 1999. * */ +#include #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 + diff --git a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c index 238d561a4a1d..8168f213339f 100644 --- a/drivers/char/rio/rioboot.c +++ b/drivers/char/rio/rioboot.c @@ -35,7 +35,6 @@ static char *_rioboot_c_sccs_ = "@(#)rioboot.c 1.3"; #endif #define __NO_VERSION__ -#include #include #include #include @@ -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; hostRIONumHosts; 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_countRIOConf.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; } diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c index 5c720b7b6a05..835d815d35b0 100644 --- a/drivers/char/rio/riocmd.c +++ b/drivers/char/rio/riocmd.c @@ -35,7 +35,6 @@ static char *_riocmd_c_sccs_ = "@(#)riocmd.c 1.2"; #endif #define __NO_VERSION__ -#include #include #include #include @@ -43,8 +42,6 @@ static char *_riocmd_c_sccs_ = "@(#)riocmd.c 1.2"; #include #include #include -#include - #include #include diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c index 9113592c62b5..fa68646d5c1d 100644 --- a/drivers/char/rio/rioctrl.c +++ b/drivers/char/rio/rioctrl.c @@ -35,7 +35,6 @@ static char *_rioctrl_c_sccs_ = "@(#)rioctrl.c 1.3"; #define __NO_VERSION__ -#include #include #include #include @@ -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; } diff --git a/drivers/char/rio/riodrvr.h b/drivers/char/rio/riodrvr.h index 2fcde39ee21d..9a429e16bb41 100644 --- a/drivers/char/rio/riodrvr.h +++ b/drivers/char/rio/riodrvr.h @@ -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 */ diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c index b90f8e4bab24..59cfdedd5cf8 100644 --- a/drivers/char/rio/rioinit.c +++ b/drivers/char/rio/rioinit.c @@ -1414,7 +1414,7 @@ struct rio_info * p; (int)p->RIOHosts, sizeof(struct Host) ) ); for( host=0; hostRIOHosts[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 */ } /* diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c index c389c4fb7563..e92609839f9b 100644 --- a/drivers/char/rio/riointr.c +++ b/drivers/char/rio/riointr.c @@ -35,7 +35,6 @@ static char *_riointr_c_sccs_ = "@(#)riointr.c 1.2"; #define __NO_VERSION__ -#include #include #include #include @@ -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); } } diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c index aa4b782d3c1c..550e2c17d98d 100644 --- a/drivers/char/rio/rioparam.c +++ b/drivers/char/rio/rioparam.c @@ -35,7 +35,6 @@ static char *_rioparam_c_sccs_ = "@(#)rioparam.c 1.3"; #endif #define __NO_VERSION__ -#include #include #include #include diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c index aba66213b539..2f13eb273217 100644 --- a/drivers/char/rio/rioroute.c +++ b/drivers/char/rio/rioroute.c @@ -34,7 +34,6 @@ static char *_rioroute_c_sccs_ = "@(#)rioroute.c 1.3"; #endif #define __NO_VERSION__ -#include #include #include #include diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c index 09f9d8f7ef85..6329a6e18dba 100644 --- a/drivers/char/rio/riotable.c +++ b/drivers/char/rio/riotable.c @@ -34,7 +34,6 @@ static char *_riotable_c_sccs_ = "@(#)riotable.c 1.2"; #endif #define __NO_VERSION__ -#include #include #include #include diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c index 7fec8dd7c331..cda417f3f4da 100644 --- a/drivers/char/rio/riotty.c +++ b/drivers/char/rio/riotty.c @@ -37,7 +37,6 @@ static char *_riotty_c_sccs_ = "@(#)riotty.c 1.3"; #define __EXPLICIT_DEF_H__ #define __NO_VERSION__ -#include #include #include #include @@ -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; } diff --git a/drivers/char/rio/unixrup.h b/drivers/char/rio/unixrup.h index 2d3dab4c0aee..eddf86278abc 100644 --- a/drivers/char/rio/unixrup.h +++ b/drivers/char/rio/unixrup.h @@ -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 */ }; diff --git a/drivers/char/sx.c b/drivers/char/sx.c index b12eb75bcfe5..793f055f701b 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -33,7 +33,12 @@ * * 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 * @@ -195,8 +200,8 @@ * */ -#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 @@ -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; diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 8dc61ffdc123..19f2177bc049 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -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)) diff --git a/drivers/i2o/i2o_block.c b/drivers/i2o/i2o_block.c index e5ef5dd322a2..cd094ab56df7 100644 --- a/drivers/i2o/i2o_block.c +++ b/drivers/i2o/i2o_block.c @@ -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(uniti2odev = 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) diff --git a/drivers/i2o/i2o_scsi.h b/drivers/i2o/i2o_scsi.h index 7627e0ca89e5..7c822b4cf2f7 100644 --- a/drivers/i2o/i2o_scsi.h +++ b/drivers/i2o/i2o_scsi.h @@ -5,7 +5,9 @@ #include #endif +#ifndef LinuxVersionCode #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) +#endif #include #include diff --git a/drivers/isdn/isdn_cards.c b/drivers/isdn/isdn_cards.c index bdbcd419188c..baa645a3bf5a 100644 --- a/drivers/isdn/isdn_cards.c +++ b/drivers/isdn/isdn_cards.c @@ -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) diff --git a/drivers/isdn/isdn_ppp.h b/drivers/isdn/isdn_ppp.h index 683325637bf7..dc5ed8781fc6 100644 --- a/drivers/isdn/isdn_ppp.h +++ b/drivers/isdn/isdn_ppp.h @@ -76,6 +76,7 @@ */ #include /* for PPP_PROTOCOL */ +#include 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 *); diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index cd608e60fdad..c0c28c003cbc 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -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) { diff --git a/drivers/net/Space.c b/drivers/net/Space.c index ef1a977221fc..1dcff8a11ed2 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -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); diff --git a/drivers/net/bonding.c b/drivers/net/bonding.c index be84bbb6b83c..9124d25ca9d3 100644 --- a/drivers/net/bonding.c +++ b/drivers/net/bonding.c @@ -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 diff --git a/drivers/net/c101.c b/drivers/net/c101.c index eb2a760cd063..0860eb154c56 100644 --- a/drivers/net/c101.c +++ b/drivers/net/c101.c @@ -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; } diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index 02b3b3634d69..2c60edb9ba41 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -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]++; diff --git a/drivers/net/gmac.c b/drivers/net/gmac.c index dd159b6be221..76f92dc9b797 100644 --- a/drivers/net/gmac.c +++ b/drivers/net/gmac.c @@ -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", diff --git a/drivers/net/gmac.h b/drivers/net/gmac.h index 859a557967d2..6473ec54eb15 100644 --- a/drivers/net/gmac.h +++ b/drivers/net/gmac.h @@ -216,13 +216,16 @@ #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) @@ -231,7 +234,7 @@ * * 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) /* @@ -251,7 +254,7 @@ /* -- 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; diff --git a/drivers/net/hd6457x.c b/drivers/net/hd6457x.c index 1f8149eaf020..e916f7d70a79 100644 --- a/drivers/net/hd6457x.c +++ b/drivers/net/hd6457x.c @@ -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 diff --git a/drivers/net/hdlc.c b/drivers/net/hdlc.c index f3718082c032..53d114275765 100644 --- a/drivers/net/hdlc.c +++ b/drivers/net/hdlc.c @@ -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) diff --git a/drivers/net/n2.c b/drivers/net/n2.c index 81045317cf91..1b494ccb8846 100644 --- a/drivers/net/n2.c +++ b/drivers/net/n2.c @@ -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; } diff --git a/drivers/net/slhc.c b/drivers/net/slhc.c index 735751dde392..558c03090b01 100644 --- a/drivers/net/slhc.c +++ b/drivers/net/slhc.c @@ -56,6 +56,7 @@ #include #include #include +#include #ifdef CONFIG_INET /* Entire module is for IP only */ @@ -79,7 +80,6 @@ #include #include #include -#include #include int last_retran; diff --git a/drivers/pnp/parport_probe.c b/drivers/pnp/parport_probe.c index 11728ea9bc18..ad50c7accb4c 100644 --- a/drivers/pnp/parport_probe.c +++ b/drivers/pnp/parport_probe.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 88fdfd6bd122..e1fb8e0a0d29 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -2,6 +2,8 @@ 3w-xxxx.c -- 3ware Storage Controller device driver for Linux. Written By: Adam Radford + Modifications By: Joel Jacobson + Copyright (C) 1999-2000 3ware Inc. Kernel compatablity By: Andre Hedrick @@ -47,6 +49,19 @@ 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 @@ -65,6 +80,7 @@ MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver"); #include #include #include +#include #include #include @@ -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;ibyte3.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;istatus != 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) { diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h index b3989c71cf48..a48dc9ea8801 100644 --- a/drivers/scsi/3w-xxxx.h +++ b/drivers/scsi/3w-xxxx.h @@ -2,7 +2,9 @@ 3w-xxxx.h -- 3ware Storage Controller device driver for Linux. Written By: Adam Radford - Copyright (C) 1999 3ware Inc. + Modifications By: Joel Jacobson + + Copyright (C) 1999, 2000 3ware Inc. Kernel compatablity By: Andre Hedrick Non-Copyright (C) 2000 Andre Hedrick @@ -106,6 +108,7 @@ #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 @@ -135,7 +138,7 @@ #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, \ diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index bce089b6ad2f..f1e1da24e19c 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c @@ -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; } diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index fa8844b673eb..b15bc75f8399 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -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)); diff --git a/drivers/scsi/imm.h b/drivers/scsi/imm.h index feba4c773cb7..909f46e16dee 100644 --- a/drivers/scsi/imm.h +++ b/drivers/scsi/imm.h @@ -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) diff --git a/drivers/scsi/ini9100u.h b/drivers/scsi/ini9100u.h index 189d0c4141b8..23c401192888 100644 --- a/drivers/scsi/ini9100u.h +++ b/drivers/scsi/ini9100u.h @@ -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 diff --git a/drivers/scsi/inia100.h b/drivers/scsi/inia100.h index 1ef0f82845e1..6ad90d4cf9d5 100644 --- a/drivers/scsi/inia100.h +++ b/drivers/scsi/inia100.h @@ -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 diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index 5904c881cf47..8eb8d489e328 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -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: diff --git a/drivers/scsi/ppa.h b/drivers/scsi/ppa.h index 58aba3473e29..618cf518a3e3 100644 --- a/drivers/scsi/ppa.h +++ b/drivers/scsi/ppa.h @@ -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) diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index e31230b7e440..6c0030146b85 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -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: diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index af47e706c70e..25964d64c4a9 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c @@ -165,6 +165,7 @@ #include "constants.h" #include "sd.h" #include +#include #include "dc390.h" diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile index fa2ffaef50f2..83bf380ffcc2 100644 --- a/drivers/sound/Makefile +++ b/drivers/sound/Makefile @@ -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 diff --git a/drivers/sound/emu10k1/main.c b/drivers/sound/emu10k1/main.c index b5ba59cc89b4..c87d0acf958d 100644 --- a/drivers/sound/emu10k1/main.c +++ b/drivers/sound/emu10k1/main.c @@ -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 diff --git a/drivers/sound/i810_audio.c b/drivers/sound/i810_audio.c index 08e33a2ea5ce..0c79a3510560 100644 --- a/drivers/sound/i810_audio.c +++ b/drivers/sound/i810_audio.c @@ -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++) { diff --git a/drivers/sound/maestro.c b/drivers/sound/maestro.c index 31fa969f41d0..0af9a2222e78 100644 --- a/drivers/sound/maestro.c +++ b/drivers/sound/maestro.c @@ -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; diff --git a/drivers/sound/sound_core.c b/drivers/sound/sound_core.c index ed9a2e94d17e..1ad86f6a7816 100644 --- a/drivers/sound/sound_core.c +++ b/drivers/sound/sound_core.c @@ -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; } diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c index 23ca159c75a2..90ad4ee21ee4 100644 --- a/fs/isofs/dir.c +++ b/fs/isofs/dir.c @@ -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) diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 25744b5e2566..e10d808dd044 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -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; diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h index bd09c716d1c2..90bd7433fb3e 100644 --- a/fs/ncpfs/ncplib_kernel.h +++ b/fs/ncpfs/ncplib_kernel.h @@ -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 index 000000000000..2ce92a04eb18 --- /dev/null +++ b/fs/smbfs/ChangeLog @@ -0,0 +1,49 @@ +ChangeLog for smbfs. + +2000-07-20 Urban Widmark + + * proc.c: fix 2 places where bad server responses could cause an Oops. + +2000-07-15 Urban Widmark + + * *.c: more debug printk fixes + +2000-06-24: Matt Maynard + + * 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 + + * *.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 @@ -17,9 +19,6 @@ #include -#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; diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index 0ac3762ec685..d60f2ad52d49 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -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 #include #include +#include #include #include -#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 */ diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index 0b0c4e3a7f19..c91e20e4b564 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -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 @@ -22,16 +23,8 @@ #include #include -#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; diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index dfc65f90e14f..18d18c2dcfed 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c @@ -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 @@ -28,9 +29,6 @@ #include #include -#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); diff --git a/fs/smbfs/ioctl.c b/fs/smbfs/ioctl.c index b403c248ddaf..c99392e3d2a4 100644 --- a/fs/smbfs/ioctl.c +++ b/fs/smbfs/ioctl.c @@ -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 @@ -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; } diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c index 4964ea38d5ae..f412b76ff444 100644 --- a/fs/smbfs/proc.c +++ b/fs/smbfs/proc.c @@ -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 @@ -39,10 +27,6 @@ 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) @@ -54,19 +38,15 @@ #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", ¶m[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", ¶m[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; diff --git a/fs/smbfs/smb_debug.h b/fs/smbfs/smb_debug.h index 0a8d13fd33bd..1fd2cfd65912 100644 --- a/fs/smbfs/smb_debug.h +++ b/fs/smbfs/smb_debug.h @@ -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 diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c index 76d4a1709661..fa0a3b2e3a7d 100644 --- a/fs/smbfs/sock.c +++ b/fs/smbfs/sock.c @@ -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 @@ -25,9 +26,6 @@ #include -#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(¤t->sigmask_lock, flags); sigpipe = sigismember(¤t->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; diff --git a/fs/umsdos/README-WIP.txt b/fs/umsdos/README-WIP.txt index 79347c2dc732..27067efb8b3a 100644 --- a/fs/umsdos/README-WIP.txt +++ b/fs/umsdos/README-WIP.txt @@ -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 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. diff --git a/fs/umsdos/emd.c b/fs/umsdos/emd.c index 1cd61bfda293..33c2056a2cac 100644 --- a/fs/umsdos/emd.c +++ b/fs/umsdos/emd.c @@ -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); diff --git a/fs/umsdos/inode.c b/fs/umsdos/inode.c index 6aaa5002ec32..78b0f28f7239 100644 --- a/fs/umsdos/inode.c +++ b/fs/umsdos/inode.c @@ -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); diff --git a/fs/umsdos/ioctl.c b/fs/umsdos/ioctl.c index cc73078dd1c3..9bdf87a8ab05 100644 --- a/fs/umsdos/ioctl.c +++ b/fs/umsdos/ioctl.c @@ -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) diff --git a/fs/umsdos/namei.c b/fs/umsdos/namei.c index ef64d7268f9b..7c156e49256f 100644 --- a/fs/umsdos/namei.c +++ b/fs/umsdos/namei.c @@ -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); diff --git a/include/net/slhc_vj.h b/include/net/slhc_vj.h index 04387d8a8d00..59a617c315ef 100644 --- a/include/net/slhc_vj.h +++ b/include/net/slhc_vj.h @@ -115,6 +115,9 @@ typedef __u8 byte_t; typedef __u32 int32; + +#include +#include /* * "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 diff --git a/init/main.c b/init/main.c index c4a88b4819ac..4f577970c2a0 100644 --- a/init/main.c +++ b/init/main.c @@ -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. diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 67e674a15745..59940e7f6fea 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -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); diff --git a/net/ipv4/ip_fw.c b/net/ipv4/ip_fw.c index 400f46c0f8c6..6ff3bb186742 100644 --- a/net/ipv4/ip_fw.c +++ b/net/ipv4/ip_fw.c @@ -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, diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c index d753c2b5ee1e..f4c1f2b70eb6 100644 --- a/net/irda/irda_device.c +++ b/net/irda/irda_device.c @@ -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); diff --git a/net/irda/irmod.c b/net/irda/irmod.c index d8c0445d8cbc..41dc7fac9627 100644 --- a/net/irda/irmod.c +++ b/net/irda/irmod.c @@ -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 */ diff --git a/net/irda/irttp.c b/net/irda/irttp.c index b2e3750b2b9c..6d4c64d6bff5 100644 --- a/net/irda/irttp.c +++ b/net/irda/irttp.c @@ -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)); -- 2.39.5