]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Sat, 10 Mar 2007 06:00:51 +0000 (22:00 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Sat, 10 Mar 2007 06:00:51 +0000 (22:00 -0800)
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6:
  [IA64] refresh config files
  [IA64] put kdump_find_rsvd_region in __init
  [IA64] Remove sparse warning from unwind code
  [IA64] add missing syscall trace clear
  [IA64] Cleanup in crash.c
  [IA64] kexec: declare ia64_mca_pal_base in mca.h rather than kexec.h
  [IA64] pci_get_legacy_ide_irq should return irq (not GSI)
  [IA64] whitespace fixes for include/asm-ia64/sal.h
  [IA64] Cache error recovery
  [IA64] Proper handling of TLB errors from duplicate itr.d dropins

106 files changed:
Documentation/kernel-parameters.txt
Documentation/sparse.txt
MAINTAINERS
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/acpi/earlyquirk.c
arch/ia64/sn/kernel/io_acpi_init.c
arch/ia64/sn/kernel/setup.c
arch/mips/dec/prom/init.c
arch/mips/sibyte/Kconfig
arch/mips/sibyte/sb1250/bcm1250_tbprof.c
arch/mips/sibyte/sb1250/setup.c
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/prom_parse.c
arch/powerpc/platforms/83xx/mpc834x_mds.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/celleb/scc_epci.c
arch/powerpc/platforms/embedded6xx/Kconfig
arch/powerpc/platforms/powermac/feature.c
arch/powerpc/platforms/powermac/pci.c
arch/powerpc/xmon/xmon.c
arch/x86_64/kernel/early-quirks.c
drivers/acpi/Kconfig
drivers/acpi/blacklist.c
drivers/acpi/ec.c
drivers/acpi/events/evmisc.c
drivers/acpi/ibm_acpi.c
drivers/acpi/power.c
drivers/acpi/resources/rscreate.c
drivers/acpi/video.c
drivers/ata/ata_piix.c
drivers/ata/libata-acpi.c
drivers/ata/libata-core.c
drivers/ata/sata_nv.c
drivers/base/core.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/ucma.c
drivers/infiniband/hw/cxgb3/cxio_hal.c
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/infiniband/hw/cxgb3/iwch_ev.c
drivers/infiniband/hw/cxgb3/iwch_provider.c
drivers/infiniband/hw/cxgb3/iwch_provider.h
drivers/infiniband/hw/cxgb3/iwch_qp.c
drivers/infiniband/hw/ehca/ehca_classes.h
drivers/infiniband/hw/ehca/ehca_cq.c
drivers/infiniband/hw/ehca/ehca_irq.c
drivers/infiniband/hw/ehca/ehca_main.c
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/infiniband/ulp/ipoib/ipoib_verbs.c
drivers/misc/asus-laptop.c
drivers/misc/sony-laptop.c
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/chips/cfi_cmdset_0020.c
drivers/mtd/maps/dilnetpc.c
drivers/mtd/maps/esb2rom.c
drivers/mtd/mtdconcat.c
drivers/mtd/mtdpart.c
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/nand_base.c
drivers/mtd/onenand/onenand_base.c
drivers/net/3c59x.c
drivers/net/mv643xx_eth.c
drivers/net/myri10ge/myri10ge.c
drivers/net/netxen/netxen_nic_hw.c
drivers/net/r8169.c
drivers/net/sky2.c
drivers/net/tokenring/ibmtr.c
drivers/net/via-rhine.c
drivers/net/wan/z85230.c
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/bcm43xx/bcm43xx_phy.c
drivers/net/wireless/bcm43xx/bcm43xx_wx.c
drivers/pci/pci.c
drivers/pci/pcie/aer/aerdrv.c
drivers/pci/pcie/portdrv_pci.c
drivers/pci/search.c
drivers/pnp/pnpacpi/rsparser.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/devio.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/goku_udc.c
drivers/usb/gadget/pxa2xx_udc.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/uhci-hub.c
drivers/usb/misc/ftdi-elan.c
drivers/usb/net/dm9601.c
drivers/usb/serial/airprime.c
drivers/usb/serial/cp2101.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/ipaq.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/unusual_devs.h
fs/jffs2/background.c
fs/jffs2/readinode.c
fs/jffs2/scan.c
fs/jffs2/wbuf.c
include/asm-mips/sibyte/trace_prof.h [deleted file]
include/asm-sparc64/parport.h
include/linux/mtd/mtd.h
include/linux/mtd/onenand.h
kernel/module.c
lib/kobject.c
net/sctp/ipv6.c

index 914119309ddbdcf045793ea7fceabf7fd5183ac1..856c8b114e71698731c93503f19a32bd1b10c481 100644 (file)
@@ -126,7 +126,8 @@ and is between 256 and 4096 characters. It is defined in the file
                        See header of drivers/scsi/53c7xx.c.
                        See also Documentation/scsi/ncr53c7xx.txt.
 
-       acpi=           [HW,ACPI] Advanced Configuration and Power Interface
+       acpi=           [HW,ACPI,X86-64,i386]
+                       Advanced Configuration and Power Interface
                        Format: { force | off | ht | strict | noirq }
                        force -- enable ACPI if default was off
                        off -- disable ACPI if default was on
index f9c99c9a54f937616903a5fa5d0b8fee2fd020ae..1a3bdc27d95e98ce49c07791b02515e38ef678a5 100644 (file)
@@ -45,11 +45,15 @@ special.
 Getting sparse
 ~~~~~~~~~~~~~~
 
-With git, you can just get it from
+You can get latest released versions from the Sparse homepage at
+http://www.kernel.org/pub/linux/kernel/people/josh/sparse/
 
-        rsync://rsync.kernel.org/pub/scm/devel/sparse/sparse.git
+Alternatively, you can get snapshots of the latest development version
+of sparse using git to clone..
 
-and DaveJ has tar-balls at
+        git://git.kernel.org/pub/scm/linux/kernel/git/josh/sparse.git
+
+DaveJ has hourly generated tarballs of the git tree available at..
 
         http://www.codemonkey.org.uk/projects/git-snapshots/sparse/
 
index 9993b90094155cb181fe2006e2a914a0b7af3776..17555bba20af84bc071d7cd8d553d06b3598e4f3 100644 (file)
@@ -1103,9 +1103,6 @@ W:        http://lanana.org/docs/device-list/index.html
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
-DEVICE FILESYSTEM
-S:     Obsolete
-
 DIGI INTL. EPCA DRIVER
 P:     Digi International, Inc
 M:     Eng.Linux@digi.com
index e5eb97a910ed8d82f74fc67802e04321eacdc82c..9ea5b8ecc7e1d61918da7043a15b55400c121735 100644 (file)
@@ -1072,7 +1072,28 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
                               "ASUS A7V ACPI BIOS Revision 1007"),
                     },
         },
-
+       {
+               /*
+                * Latest BIOS for IBM 600E (1.16) has bad pcinum
+                * for LPC bridge, which is needed for the PCI
+                * interrupt links to work. DSDT fix is in bug 5966.
+                * 2645, 2646 model numbers are shared with 600/600E/600X
+                */
+        .callback = disable_acpi_irq,
+        .ident = "IBM Thinkpad 600 Series 2645",
+        .matches = {
+                    DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+                    DMI_MATCH(DMI_BOARD_NAME, "2645"),
+                    },
+        },
+       {
+        .callback = disable_acpi_irq,
+        .ident = "IBM Thinkpad 600 Series 2646",
+        .matches = {
+                    DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+                    DMI_MATCH(DMI_BOARD_NAME, "2646"),
+                    },
+        },
        /*
         * Boxes that need ACPI PCI IRQ routing and PCI scan disabled
         */
index bf86f7662d8b7a4c6210ff6e537502db624e27b6..a7d22d9f3d7e50d13ae2c4d6a43aba093a920b8a 100644 (file)
 
 #ifdef CONFIG_ACPI
 
-static int nvidia_hpet_detected __initdata;
-
 static int __init nvidia_hpet_check(struct acpi_table_header *header)
 {
-       nvidia_hpet_detected = 1;
        return 0;
 }
 #endif
@@ -29,9 +26,7 @@ static int __init check_bridge(int vendor, int device)
        /* According to Nvidia all timer overrides are bogus unless HPET
           is enabled. */
        if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) {
-               nvidia_hpet_detected = 0;
-               acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check);
-               if (nvidia_hpet_detected == 0) {
+               if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) {
                        acpi_skip_timer_override = 1;
                          printk(KERN_INFO "Nvidia board "
                        "detected. Ignoring ACPI "
index 8c331ca6e5c9088a8a8542ebae195306f4d9a6bc..c6216f454ffb5ee81d2246bb05361a073ff51268 100644 (file)
@@ -53,12 +53,15 @@ sal_ioif_init(u64 *result)
 }
 
 /*
- * sn_hubdev_add - The 'add' function of the acpi_sn_hubdev_driver.
- *                Called for every "SGIHUB" or "SGITIO" device defined
- *                in the ACPI namespace.
+ * sn_acpi_hubdev_init() - This function is called by acpi_ns_get_device_callback()
+ *                        for all SGIHUB and SGITIO acpi devices defined in the
+ *                        DSDT. It obtains the hubdev_info pointer from the
+ *                        ACPI vendor resource, which the PROM setup, and sets up the
+ *                        hubdev_info in the pda.
  */
-static int __init
-sn_hubdev_add(struct acpi_device *device)
+
+static acpi_status __init
+sn_acpi_hubdev_init(acpi_handle handle, u32 depth, void *context, void **ret)
 {
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        u64 addr;
@@ -67,18 +70,19 @@ sn_hubdev_add(struct acpi_device *device)
        int i;
        u64 nasid;
        struct acpi_resource *resource;
-       int ret = 0;
        acpi_status status;
        struct acpi_resource_vendor_typed *vendor;
        extern void sn_common_hubdev_init(struct hubdev_info *);
 
-       status = acpi_get_vendor_resource(device->handle, METHOD_NAME__CRS,
+       status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
                                          &sn_uuid, &buffer);
        if (ACPI_FAILURE(status)) {
                printk(KERN_ERR
-                      "sn_hubdev_add: acpi_get_vendor_resource() failed: %d\n",
-                       status);
-               return 1;
+                      "sn_acpi_hubdev_init: acpi_get_vendor_resource() "
+                      "(0x%x) failed for: ", status);
+               acpi_ns_print_node_pathname(handle, NULL);
+               printk("\n");
+               return AE_OK;           /* Continue walking namespace */
        }
 
        resource = buffer.pointer;
@@ -86,9 +90,10 @@ sn_hubdev_add(struct acpi_device *device)
        if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
            sizeof(struct hubdev_info *)) {
                printk(KERN_ERR
-                      "sn_hubdev_add: Invalid vendor data length: %d\n",
+                      "sn_acpi_hubdev_init: Invalid vendor data length: %d for: ",
                        vendor->byte_length);
-               ret = 1;
+               acpi_ns_print_node_pathname(handle, NULL);
+               printk("\n");
                goto exit;
        }
 
@@ -103,7 +108,7 @@ sn_hubdev_add(struct acpi_device *device)
 
 exit:
        kfree(buffer.pointer);
-       return ret;
+       return AE_OK;           /* Continue walking namespace */
 }
 
 /*
@@ -441,14 +446,6 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
 
 EXPORT_SYMBOL(sn_acpi_slot_fixup);
 
-static struct acpi_driver acpi_sn_hubdev_driver = {
-       .name = "SGI HUBDEV Driver",
-       .ids = "SGIHUB,SGITIO",
-       .ops = {
-               .add = sn_hubdev_add,
-               },
-};
-
 
 /*
  * sn_acpi_bus_fixup -  Perform SN specific setup of software structs
@@ -492,7 +489,10 @@ sn_io_acpi_init(void)
        /* SN Altix does not follow the IOSAPIC IRQ routing model */
        acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM;
 
-       acpi_bus_register_driver(&acpi_sn_hubdev_driver);
+       /* Setup hubdev_info for all SGIHUB/SGITIO devices */
+       acpi_get_devices("SGIHUB", sn_acpi_hubdev_init, NULL, NULL);
+       acpi_get_devices("SGITIO", sn_acpi_hubdev_init, NULL, NULL);
+
        status = sal_ioif_init(&result);
        if (status || result)
                panic("sal_ioif_init failed: [%lx] %s\n",
index 8571e52c2efde6785b1927cb4540b8383fea44d2..bd5373d593e1034a3999c94ba2529f3c94087c36 100644 (file)
@@ -397,6 +397,8 @@ void __init sn_setup(char **cmdline_p)
        ia64_sn_set_os_feature(OSF_PCISEGMENT_ENABLE);
        ia64_sn_set_os_feature(OSF_ACPI_ENABLE);
 
+       /* Load the new DSDT and SSDT tables into the global table list. */
+       acpi_table_init();
 
 #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
        /*
index bf2858071f1fc79969b3e7d25e0d4b9a1fb61073..a217aafe59f6aa9e2d61bf78239fdc64e8e128a4 100644 (file)
@@ -103,9 +103,6 @@ void __init prom_init(void)
        if (prom_is_rex(magic))
                rex_clear_cache();
 
-       /* Register the early console.  */
-       register_prom_console();
-
        /* Were we compiled with the right CPU option? */
 #if defined(CONFIG_CPU_R3000)
        if ((current_cpu_data.cputype == CPU_R4000SC) ||
index 67dac6204b6da32cc9d76880ab5874716c80cd8d..bdf24a7b54941ce75132b83adc6861695e15b819 100644 (file)
@@ -1,31 +1,35 @@
 config SIBYTE_SB1250
        bool
        select HW_HAS_PCI
-       select SIBYTE_HAS_LDT
+       select SIBYTE_ENABLE_LDT_IF_PCI
        select SIBYTE_SB1xxx_SOC
        select SYS_SUPPORTS_SMP
 
 config SIBYTE_BCM1120
        bool
        select SIBYTE_BCM112X
+       select SIBYTE_HAS_ZBUS_PROFILING
        select SIBYTE_SB1xxx_SOC
 
 config SIBYTE_BCM1125
        bool
        select HW_HAS_PCI
        select SIBYTE_BCM112X
+       select SIBYTE_HAS_ZBUS_PROFILING
        select SIBYTE_SB1xxx_SOC
 
 config SIBYTE_BCM1125H
        bool
        select HW_HAS_PCI
        select SIBYTE_BCM112X
-       select SIBYTE_HAS_LDT
+       select SIBYTE_ENABLE_LDT_IF_PCI
+       select SIBYTE_HAS_ZBUS_PROFILING
        select SIBYTE_SB1xxx_SOC
 
 config SIBYTE_BCM112X
        bool
        select SIBYTE_SB1xxx_SOC
+       select SIBYTE_HAS_ZBUS_PROFILING
 
 config SIBYTE_BCM1x80
        bool
@@ -37,6 +41,7 @@ config SIBYTE_BCM1x55
        bool
        select HW_HAS_PCI
        select SIBYTE_SB1xxx_SOC
+       select SIBYTE_HAS_ZBUS_PROFILING
        select SYS_SUPPORTS_SMP
 
 config SIBYTE_SB1xxx_SOC
@@ -95,8 +100,10 @@ config CPU_SB1_PASS_2
 
 config SIBYTE_HAS_LDT
        bool
-       depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H)
-       default y
+
+config SIBYTE_ENABLE_LDT_IF_PCI
+       bool
+       select SIBYTE_HAS_LDT if PCI
 
 config SIMULATION
        bool "Running under simulation"
@@ -162,5 +169,8 @@ config SIBYTE_SB1250_PROF
        depends on SIBYTE_SB1xxx_SOC
 
 config SIBYTE_TBPROF
-       bool "Support for ZBbus profiling"
-       depends on SIBYTE_SB1xxx_SOC
+       tristate "Support for ZBbus profiling"
+       depends on SIBYTE_HAS_ZBUS_PROFILING
+
+config SIBYTE_HAS_ZBUS_PROFILING
+       bool
index 212547c573102b0060955a3cd54d01b42c60c2e3..ea0ca131a3cfaceb770c6cfea3720a5ebd680b69 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
+ * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ *    written by Ralf Baechle <ralf@linux-mips.org>
  */
 
-#define SBPROF_TB_DEBUG 0
+#undef DEBUG
 
+#include <linux/device.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
 #include <linux/errno.h>
-#include <linux/reboot.h>
-#include <linux/smp_lock.h>
+#include <linux/types.h>
 #include <linux/wait.h>
-#include <asm/uaccess.h>
+
 #include <asm/io.h>
 #include <asm/sibyte/sb1250.h>
 #include <asm/sibyte/sb1250_regs.h>
 #include <asm/sibyte/sb1250_scd.h>
 #include <asm/sibyte/sb1250_int.h>
-#include <asm/sibyte/trace_prof.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
 
-#define DEVNAME "bcm1250_tbprof"
+#define SBPROF_TB_MAJOR 240
+
+typedef u64 tb_sample_t[6*256];
+
+enum open_status {
+       SB_CLOSED,
+       SB_OPENING,
+       SB_OPEN
+};
+
+struct sbprof_tb {
+       wait_queue_head_t       tb_sync;
+       wait_queue_head_t       tb_read;
+       struct mutex            lock;
+       enum open_status        open;
+       tb_sample_t             *sbprof_tbbuf;
+       int                     next_tb_sample;
+
+       volatile int            tb_enable;
+       volatile int            tb_armed;
+
+};
 
 static struct sbprof_tb sbp;
 
+#define MAX_SAMPLE_BYTES (24*1024*1024)
+#define MAX_TBSAMPLE_BYTES (12*1024*1024)
+
+#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t))
+#define TB_SAMPLE_SIZE (sizeof(tb_sample_t))
+#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE)
+
+/* ioctls */
+#define SBPROF_ZBSTART         _IOW('s', 0, int)
+#define SBPROF_ZBSTOP          _IOW('s', 1, int)
+#define SBPROF_ZBWAITFULL      _IOW('s', 2, int)
+
+/*
+ * Routines for using 40-bit SCD cycle counter
+ *
+ * Client responsible for either handling interrupts or making sure
+ * the cycles counter never saturates, e.g., by doing
+ * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs.
+ */
+
+/*
+ * Configures SCD counter 0 to count ZCLKs starting from val;
+ * Configures SCD counters1,2,3 to count nothing.
+ * Must not be called while gathering ZBbus profiles.
+ */
+
+#define zclk_timer_init(val) \
+  __asm__ __volatile__ (".set push;" \
+                       ".set mips64;" \
+                       "la   $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
+                       "sd   %0, 0x10($8);"   /* write val to counter0 */ \
+                       "sd   %1, 0($8);"      /* config counter0 for zclks*/ \
+                       ".set pop" \
+                       : /* no outputs */ \
+                                                    /* enable, counter0 */ \
+                       : /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \
+                       : /* modifies */ "$8" )
+
+
+/* Reads SCD counter 0 and puts result in value
+   unsigned long long val; */
+#define zclk_get(val) \
+  __asm__ __volatile__ (".set push;" \
+                       ".set mips64;" \
+                       "la   $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
+                       "ld   %0, 0x10($8);"   /* write val to counter0 */ \
+                       ".set pop" \
+                       : /* outputs */ "=r"(val) \
+                       : /* inputs */ \
+                       : /* modifies */ "$8" )
+
+#define DEVNAME "bcm1250_tbprof"
+
 #define TB_FULL (sbp.next_tb_sample == MAX_TB_SAMPLES)
 
-/************************************************************************
+/*
  * Support for ZBbus sampling using the trace buffer
  *
  * We use the SCD performance counter interrupt, caused by a Zclk counter
@@ -54,30 +132,36 @@ static struct sbprof_tb sbp;
  * overflow.
  *
  * We map the interrupt for trace_buffer_freeze to handle it on CPU 0.
- *
- ************************************************************************/
+ */
 
-static u_int64_t tb_period;
+static u64 tb_period;
 
 static void arm_tb(void)
 {
-        u_int64_t scdperfcnt;
-       u_int64_t next = (1ULL << 40) - tb_period;
-       u_int64_t tb_options = M_SCD_TRACE_CFG_FREEZE_FULL;
-       /* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to
-          trigger start of trace.  XXX vary sampling period */
+        u64 scdperfcnt;
+       u64 next = (1ULL << 40) - tb_period;
+       u64 tb_options = M_SCD_TRACE_CFG_FREEZE_FULL;
+
+       /*
+        * Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to trigger
+        *start of trace.  XXX vary sampling period
+        */
        __raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
        scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
-       /* Unfortunately, in Pass 2 we must clear all counters to knock down
-          a previous interrupt request.  This means that bus profiling
-          requires ALL of the SCD perf counters. */
+
+       /*
+        * Unfortunately, in Pass 2 we must clear all counters to knock down a
+        * previous interrupt request.  This means that bus profiling requires
+        * ALL of the SCD perf counters.
+        */
        __raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) |
-                                               // keep counters 0,2,3 as is
-                    M_SPC_CFG_ENABLE |         // enable counting
-                    M_SPC_CFG_CLEAR |          // clear all counters
-                    V_SPC_CFG_SRC1(1),         // counter 1 counts cycles
+                                               /* keep counters 0,2,3 as is */
+                    M_SPC_CFG_ENABLE |         /* enable counting */
+                    M_SPC_CFG_CLEAR |          /* clear all counters */
+                    V_SPC_CFG_SRC1(1),         /* counter 1 counts cycles */
                     IOADDR(A_SCD_PERF_CNT_CFG));
        __raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
+
        /* Reset the trace buffer */
        __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
 #if 0 && defined(M_SCD_TRACE_CFG_FORCECNT)
@@ -91,43 +175,45 @@ static void arm_tb(void)
 static irqreturn_t sbprof_tb_intr(int irq, void *dev_id)
 {
        int i;
-       DBG(printk(DEVNAME ": tb_intr\n"));
+
+       pr_debug(DEVNAME ": tb_intr\n");
+
        if (sbp.next_tb_sample < MAX_TB_SAMPLES) {
                /* XXX should use XKPHYS to make writes bypass L2 */
-               u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++];
+               u64 *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++];
                /* Read out trace */
                __raw_writeq(M_SCD_TRACE_CFG_START_READ,
                             IOADDR(A_SCD_TRACE_CFG));
                __asm__ __volatile__ ("sync" : : : "memory");
                /* Loop runs backwards because bundles are read out in reverse order */
                for (i = 256 * 6; i > 0; i -= 6) {
-                       // Subscripts decrease to put bundle in the order
-                       //   t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi
+                       /* Subscripts decrease to put bundle in the order */
+                       /*   t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi */
                        p[i - 1] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
-                                                               // read t2 hi
+                                                               /* read t2 hi */
                        p[i - 2] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
-                                                               // read t2 lo
+                                                               /* read t2 lo */
                        p[i - 3] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
-                                                               // read t1 hi
+                                                               /* read t1 hi */
                        p[i - 4] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
-                                                               // read t1 lo
+                                                               /* read t1 lo */
                        p[i - 5] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
-                                                               // read t0 hi
+                                                               /* read t0 hi */
                        p[i - 6] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
-                                                               // read t0 lo
+                                                               /* read t0 lo */
                }
                if (!sbp.tb_enable) {
-                       DBG(printk(DEVNAME ": tb_intr shutdown\n"));
+                       pr_debug(DEVNAME ": tb_intr shutdown\n");
                        __raw_writeq(M_SCD_TRACE_CFG_RESET,
                                     IOADDR(A_SCD_TRACE_CFG));
                        sbp.tb_armed = 0;
                        wake_up(&sbp.tb_sync);
                } else {
-                       arm_tb();       // knock down current interrupt and get another one later
+                       arm_tb();       /* knock down current interrupt and get another one later */
                }
        } else {
                /* No more trace buffer samples */
-               DBG(printk(DEVNAME ": tb_intr full\n"));
+               pr_debug(DEVNAME ": tb_intr full\n");
                __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
                sbp.tb_armed = 0;
                if (!sbp.tb_enable) {
@@ -135,6 +221,7 @@ static irqreturn_t sbprof_tb_intr(int irq, void *dev_id)
                }
                wake_up(&sbp.tb_read);
        }
+
        return IRQ_HANDLED;
 }
 
@@ -144,23 +231,30 @@ static irqreturn_t sbprof_pc_intr(int irq, void *dev_id)
        return IRQ_NONE;
 }
 
-int sbprof_zbprof_start(struct file *filp)
+/*
+ * Requires: Already called zclk_timer_init with a value that won't
+ *           saturate 40 bits.  No subsequent use of SCD performance counters
+ *           or trace buffer.
+ */
+
+static int sbprof_zbprof_start(struct file *filp)
 {
-       u_int64_t scdperfcnt;
+       u64 scdperfcnt;
+       int err;
 
-       if (sbp.tb_enable)
+       if (xchg(&sbp.tb_enable, 1))
                return -EBUSY;
 
-       DBG(printk(DEVNAME ": starting\n"));
+       pr_debug(DEVNAME ": starting\n");
 
-       sbp.tb_enable = 1;
        sbp.next_tb_sample = 0;
        filp->f_pos = 0;
 
-       if (request_irq
-           (K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, DEVNAME " trace freeze", &sbp)) {
+       err = request_irq(K_INT_TRACE_FREEZE, sbprof_tb_intr, 0,
+                       DEVNAME " trace freeze", &sbp);
+       if (err)
                return -EBUSY;
-       }
+
        /* Make sure there isn't a perf-cnt interrupt waiting */
        scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
        /* Disable and clear counters, override SRC_1 */
@@ -168,18 +262,21 @@ int sbprof_zbprof_start(struct file *filp)
                     M_SPC_CFG_ENABLE | M_SPC_CFG_CLEAR | V_SPC_CFG_SRC1(1),
                     IOADDR(A_SCD_PERF_CNT_CFG));
 
-       /* We grab this interrupt to prevent others from trying to use
-           it, even though we don't want to service the interrupts
-           (they only feed into the trace-on-interrupt mechanism) */
-       if (request_irq
-           (K_INT_PERF_CNT, sbprof_pc_intr, 0, DEVNAME " scd perfcnt", &sbp)) {
-               free_irq(K_INT_TRACE_FREEZE, &sbp);
-               return -EBUSY;
-       }
-
-       /* I need the core to mask these, but the interrupt mapper to
-          pass them through.  I am exploiting my knowledge that
-          cp0_status masks out IP[5]. krw */
+       /*
+        * We grab this interrupt to prevent others from trying to use it, even
+        * though we don't want to service the interrupts (they only feed into
+        * the trace-on-interrupt mechanism)
+        */
+       err = request_irq(K_INT_PERF_CNT, sbprof_pc_intr, 0,
+                       DEVNAME " scd perfcnt", &sbp);
+       if (err)
+               goto out_free_irq;
+
+       /*
+        * I need the core to mask these, but the interrupt mapper to pass them
+        * through.  I am exploiting my knowledge that cp0_status masks out
+        * IP[5]. krw
+        */
        __raw_writeq(K_INT_MAP_I3,
                     IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
                            (K_INT_PERF_CNT << 3)));
@@ -201,7 +298,7 @@ int sbprof_zbprof_start(struct file *filp)
        __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
 
        /* Initialize Trace Event 0-7 */
-       //                              when interrupt
+       /*                              when interrupt */
        __raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
        __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
        __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
@@ -212,10 +309,10 @@ int sbprof_zbprof_start(struct file *filp)
        __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
 
        /* Initialize Trace Sequence 0-7 */
-       //                                   Start on event 0 (interrupt)
+       /*                                   Start on event 0 (interrupt) */
        __raw_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
                     IOADDR(A_SCD_TRACE_SEQUENCE_0));
-       //                        dsamp when d used | asamp when a used
+       /*                        dsamp when d used | asamp when a used */
        __raw_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
                     K_SCD_TRSEQ_TRIGGER_ALL,
                     IOADDR(A_SCD_TRACE_SEQUENCE_1));
@@ -232,33 +329,41 @@ int sbprof_zbprof_start(struct file *filp)
 
        arm_tb();
 
-       DBG(printk(DEVNAME ": done starting\n"));
+       pr_debug(DEVNAME ": done starting\n");
 
        return 0;
+
+out_free_irq:
+       free_irq(K_INT_TRACE_FREEZE, &sbp);
+
+       return err;
 }
 
-int sbprof_zbprof_stop(void)
+static int sbprof_zbprof_stop(void)
 {
-       DEFINE_WAIT(wait);
-       DBG(printk(DEVNAME ": stopping\n"));
+       int err;
+
+       pr_debug(DEVNAME ": stopping\n");
 
        if (sbp.tb_enable) {
+               /*
+                * XXXKW there is a window here where the intr handler may run,
+                * see the disable, and do the wake_up before this sleep
+                * happens.
+                */
+               pr_debug(DEVNAME ": wait for disarm\n");
+               err = wait_event_interruptible(sbp.tb_sync, !sbp.tb_armed);
+               pr_debug(DEVNAME ": disarm complete, stat %d\n", err);
+
+               if (err)
+                       return err;
+
                sbp.tb_enable = 0;
-               /* XXXKW there is a window here where the intr handler
-                  may run, see the disable, and do the wake_up before
-                  this sleep happens. */
-               if (sbp.tb_armed) {
-                       DBG(printk(DEVNAME ": wait for disarm\n"));
-                       prepare_to_wait(&sbp.tb_sync, &wait, TASK_INTERRUPTIBLE);
-                       schedule();
-                       finish_wait(&sbp.tb_sync, &wait);
-                       DBG(printk(DEVNAME ": disarm complete\n"));
-               }
                free_irq(K_INT_TRACE_FREEZE, &sbp);
                free_irq(K_INT_PERF_CNT, &sbp);
        }
 
-       DBG(printk(DEVNAME ": done stopping\n"));
+       pr_debug(DEVNAME ": done stopping\n");
 
        return 0;
 }
@@ -268,42 +373,45 @@ static int sbprof_tb_open(struct inode *inode, struct file *filp)
        int minor;
 
        minor = iminor(inode);
-       if (minor != 0) {
+       if (minor != 0)
                return -ENODEV;
-       }
-       if (sbp.open) {
+
+       if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED)
                return -EBUSY;
-       }
 
        memset(&sbp, 0, sizeof(struct sbprof_tb));
+
        sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES);
-       if (!sbp.sbprof_tbbuf) {
+       if (!sbp.sbprof_tbbuf)
                return -ENOMEM;
-       }
+
        memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES);
        init_waitqueue_head(&sbp.tb_sync);
        init_waitqueue_head(&sbp.tb_read);
-       sbp.open = 1;
+       mutex_init(&sbp.lock);
+
+       sbp.open = SB_OPEN;
 
        return 0;
 }
 
 static int sbprof_tb_release(struct inode *inode, struct file *filp)
 {
-       int minor;
+       int minor = iminor(inode);
 
-       minor = iminor(inode);
-       if (minor != 0 || !sbp.open) {
+       if (minor != 0 || !sbp.open)
                return -ENODEV;
-       }
 
-       if (sbp.tb_armed || sbp.tb_enable) {
+       mutex_lock(&sbp.lock);
+
+       if (sbp.tb_armed || sbp.tb_enable)
                sbprof_zbprof_stop();
-       }
 
        vfree(sbp.sbprof_tbbuf);
        sbp.open = 0;
 
+       mutex_unlock(&sbp.lock);
+
        return 0;
 }
 
@@ -311,21 +419,35 @@ static ssize_t sbprof_tb_read(struct file *filp, char *buf,
                              size_t size, loff_t *offp)
 {
        int cur_sample, sample_off, cur_count, sample_left;
-       char *src;
-       int   count   =  0;
-       char *dest    =  buf;
        long  cur_off = *offp;
+       char *dest    =  buf;
+       int   count   =  0;
+       char *src;
+
+       if (!access_ok(VERIFY_WRITE, buf, size))
+               return -EFAULT;
+
+       mutex_lock(&sbp.lock);
 
        count = 0;
        cur_sample = cur_off / TB_SAMPLE_SIZE;
        sample_off = cur_off % TB_SAMPLE_SIZE;
        sample_left = TB_SAMPLE_SIZE - sample_off;
+
        while (size && (cur_sample < sbp.next_tb_sample)) {
+               int err;
+
                cur_count = size < sample_left ? size : sample_left;
                src = (char *)(((long)sbp.sbprof_tbbuf[cur_sample])+sample_off);
-               copy_to_user(dest, src, cur_count);
-               DBG(printk(DEVNAME ": read from sample %d, %d bytes\n",
-                          cur_sample, cur_count));
+               err = __copy_to_user(dest, src, cur_count);
+               if (err) {
+                       *offp = cur_off + cur_count - err;
+                       mutex_unlock(&sbp.lock);
+                       return err;
+               }
+
+               pr_debug(DEVNAME ": read from sample %d, %d bytes\n",
+                        cur_sample, cur_count);
                size -= cur_count;
                sample_left -= cur_count;
                if (!sample_left) {
@@ -339,37 +461,43 @@ static ssize_t sbprof_tb_read(struct file *filp, char *buf,
                dest += cur_count;
                count += cur_count;
        }
+
        *offp = cur_off;
+       mutex_unlock(&sbp.lock);
 
        return count;
 }
 
-static long sbprof_tb_ioctl(struct file *filp,
-                           unsigned int command,
-                           unsigned long arg)
+static long sbprof_tb_ioctl(struct file *filp, unsigned int command,
+       unsigned long arg)
 {
        int error = 0;
 
-       lock_kernel();
        switch (command) {
        case SBPROF_ZBSTART:
+               mutex_lock(&sbp.lock);
                error = sbprof_zbprof_start(filp);
+               mutex_unlock(&sbp.lock);
                break;
+
        case SBPROF_ZBSTOP:
+               mutex_lock(&sbp.lock);
                error = sbprof_zbprof_stop();
+               mutex_unlock(&sbp.lock);
                break;
+
        case SBPROF_ZBWAITFULL:
-               DEFINE_WAIT(wait);
-               prepare_to_wait(&sbp.tb_read, &wait, TASK_INTERRUPTIBLE);
-               schedule();
-               finish_wait(&sbp.tb_read, &wait);
-               /* XXXKW check if interrupted? */
-               return put_user(TB_FULL, (int *) arg);
+               error = wait_event_interruptible(sbp.tb_read, TB_FULL);
+               if (error)
+                       break;
+
+               error = put_user(TB_FULL, (int *) arg);
+               break;
+
        default:
                error = -EINVAL;
                break;
        }
-       unlock_kernel();
 
        return error;
 }
@@ -384,23 +512,60 @@ static const struct file_operations sbprof_tb_fops = {
        .mmap           = NULL,
 };
 
+static struct class *tb_class;
+static struct device *tb_dev;
+
 static int __init sbprof_tb_init(void)
 {
+       struct device *dev;
+       struct class *tbc;
+       int err;
+
        if (register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) {
                printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n",
                       SBPROF_TB_MAJOR);
                return -EIO;
        }
+
+       tbc = class_create(THIS_MODULE, "sb_tracebuffer");
+       if (IS_ERR(tbc)) {
+               err = PTR_ERR(tbc);
+               goto out_chrdev;
+       }
+
+       tb_class = tbc;
+
+       dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), "tb");
+       if (IS_ERR(dev)) {
+               err = PTR_ERR(dev);
+               goto out_class;
+       }
+       tb_dev = dev;
+
        sbp.open = 0;
        tb_period = zbbus_mhz * 10000LL;
-       printk(KERN_INFO DEVNAME ": initialized - tb_period = %lld\n", tb_period);
+       pr_info(DEVNAME ": initialized - tb_period = %lld\n", tb_period);
+
        return 0;
+
+out_class:
+       class_destroy(tb_class);
+out_chrdev:
+       unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME);
+
+       return err;
 }
 
 static void __exit sbprof_tb_cleanup(void)
 {
+       device_destroy(tb_class, MKDEV(SBPROF_TB_MAJOR, 0));
        unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME);
+       class_destroy(tb_class);
 }
 
 module_init(sbprof_tb_init);
 module_exit(sbprof_tb_cleanup);
+
+MODULE_ALIAS_CHARDEV_MAJOR(SBPROF_TB_MAJOR);
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_LICENSE("GPL");
index 1cb042eab7201941c4625d9ba179baf854672617..87188f0f6fbe1e4f7d61683c8cdc9bec1b5afb19 100644 (file)
@@ -16,6 +16,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/reboot.h>
 #include <linux/string.h>
@@ -32,6 +33,7 @@ unsigned int soc_pass;
 unsigned int soc_type;
 unsigned int periph_rev;
 unsigned int zbbus_mhz;
+EXPORT_SYMBOL(zbbus_mhz);
 
 static char *soc_str;
 static char *pass_str;
index 7ec4ac77c0fa0ee0eb24f92977d0b7740261a56b..e4006dc087ca3133b02639ea01b299d540bf56a3 100644 (file)
@@ -225,6 +225,22 @@ static struct cpu_spec cpu_specs[] = {
                .oprofile_type          = PPC_OPROFILE_POWER4,
                .platform               = "ppc970",
        },
+       {       /* PPC970MP DD1.0 - no DEEPNAP, use regular 970 init */
+               .pvr_mask               = 0xffffffff,
+               .pvr_value              = 0x00440100,
+               .cpu_name               = "PPC970MP",
+               .cpu_features           = CPU_FTRS_PPC970,
+               .cpu_user_features      = COMMON_USER_POWER4 |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .icache_bsize           = 128,
+               .dcache_bsize           = 128,
+               .num_pmcs               = 8,
+               .cpu_setup              = __setup_cpu_ppc970,
+               .cpu_restore            = __restore_cpu_ppc970,
+               .oprofile_cpu_type      = "ppc64/970MP",
+               .oprofile_type          = PPC_OPROFILE_POWER4,
+               .platform               = "ppc970",
+       },
        {       /* PPC970MP */
                .pvr_mask               = 0xffff0000,
                .pvr_value              = 0x00440000,
index ea6fd552c7eaf8023114958e093a172e2c2b3015..91b443c9a48857239b35428a85fe86e8953f5f8d 100644 (file)
@@ -916,7 +916,7 @@ EXPORT_SYMBOL_GPL(of_irq_map_raw);
 static int of_irq_map_oldworld(struct device_node *device, int index,
                               struct of_irq *out_irq)
 {
-       const u32 *ints;
+       const u32 *ints = NULL;
        int intlen;
 
        /*
index e5d819166874641f39d44e64d8c95dc56d2e8121..8aa9a93e2aa2c78a30c8920bd58c78e93799a7db 100644 (file)
@@ -55,9 +55,9 @@ static int mpc834x_usb_cfg(void)
        struct device_node *np = NULL;
        int port0_is_dr = 0;
 
-       if ((np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL)
+       if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr")) != NULL)
                port0_is_dr = 1;
-       if ((np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL){
+       if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph")) != NULL){
                if (port0_is_dr) {
                        printk(KERN_WARNING
                                "There is only one USB port on PB board! \n");
@@ -103,8 +103,8 @@ static int mpc834x_usb_cfg(void)
                return -1;
 
        /*
-        * if MDS board is plug into PIB board,
-        * force to use the PHY on MDS board
+        * if Processor Board is plugged into PIB board,
+        * force to use the PHY on Processor Board
         */
        bcsr5 = in_8(bcsr_regs + 5);
        if (!(bcsr5 & BCSR5_INT_USB))
index eb661ccf2dab6f80098ed485671863c5d2c66090..e764c0aced88ae6b3d7a752a6766dc6a6ef362c8 100644 (file)
@@ -47,6 +47,7 @@ config MPC85xx
        bool
        select PPC_UDBG_16550
        select PPC_INDIRECT_PCI
+       select SERIAL_8250_SHARE_IRQ if SERIAL_8250
        default y if MPC8540_ADS || MPC85xx_CDS || MPC8560_ADS || MPC85xx_MDS
 
 config PPC_INDIRECT_PCI_BE
index c11b39c3776a5565848a4e3c8d723cb314316579..fb23d53eb09c53cce17482905f95169c266de9b0 100644 (file)
 
 #define iob()  __asm__ __volatile__("eieio; sync":::"memory")
 
+static inline volatile void __iomem *celleb_epci_get_epci_base(
+                                       struct pci_controller *hose)
+{
+       /*
+        * Note:
+        * Celleb epci uses cfg_addr as a base address for
+        * epci control registers.
+        */
+
+       return hose->cfg_addr;
+}
+
+static inline volatile void __iomem *celleb_epci_get_epci_cfg(
+                                       struct pci_controller *hose)
+{
+       /*
+        * Note:
+        * Celleb epci uses cfg_data as a base address for
+        * configuration area for epci devices.
+        */
+
+       return hose->cfg_data;
+}
 
 #if 0 /* test code for epci dummy read */
 static void celleb_epci_dummy_read(struct pci_dev *dev)
 {
-       void __iomem *epci_base;
+       volatile void __iomem *epci_base;
        struct device_node *node;
        struct pci_controller *hose;
        u32 val;
@@ -58,7 +81,7 @@ static void celleb_epci_dummy_read(struct pci_dev *dev)
        if (!hose)
                return;
 
-       epci_base = hose->cfg_addr;
+       epci_base = celleb_epci_get_epci_base(hose);
 
        val = in_be32(epci_base + SCC_EPCI_WATRP);
        iosync();
@@ -70,19 +93,20 @@ static void celleb_epci_dummy_read(struct pci_dev *dev)
 static inline void clear_and_disable_master_abort_interrupt(
                                        struct pci_controller *hose)
 {
-       void __iomem *addr;
-       addr = hose->cfg_addr + PCI_COMMAND;
-       out_be32(addr, in_be32(addr) | (PCI_STATUS_REC_MASTER_ABORT << 16));
+       volatile void __iomem *epci_base, *reg;
+       epci_base = celleb_epci_get_epci_base(hose);
+       reg = epci_base + PCI_COMMAND;
+       out_be32(reg, in_be32(reg) | (PCI_STATUS_REC_MASTER_ABORT << 16));
 }
 
 static int celleb_epci_check_abort(struct pci_controller *hose,
-                                  void __iomem *addr)
+                                  volatile void __iomem *addr)
 {
-       void __iomem *reg, *epci_base;
+       volatile void __iomem *reg, *epci_base;
        u32 val;
 
        iob();
-       epci_base = hose->cfg_addr;
+       epci_base = celleb_epci_get_epci_base(hose);
 
        reg = epci_base + PCI_COMMAND;
        val = in_be32(reg);
@@ -108,20 +132,21 @@ static int celleb_epci_check_abort(struct pci_controller *hose,
        return PCIBIOS_SUCCESSFUL;
 }
 
-static void __iomem *celleb_epci_make_config_addr(struct pci_controller *hose,
+static volatile void __iomem *celleb_epci_make_config_addr(
+                                       struct pci_controller *hose,
                                        unsigned int devfn, int where)
 {
-       void __iomem *addr;
+       volatile void __iomem *addr;
        struct pci_bus *bus = hose->bus;
 
        if (bus->self)
-               addr = hose->cfg_data +
+               addr = celleb_epci_get_epci_cfg(hose) +
                       (((bus->number & 0xff) << 16)
                        | ((devfn & 0xff) << 8)
                        | (where & 0xff)
                        | 0x01000000);
        else
-               addr = hose->cfg_data +
+               addr = celleb_epci_get_epci_cfg(hose) +
                       (((devfn & 0xff) << 8) | (where & 0xff));
 
        pr_debug("EPCI: config_addr = 0x%p\n", addr);
@@ -132,7 +157,7 @@ static void __iomem *celleb_epci_make_config_addr(struct pci_controller *hose,
 static int celleb_epci_read_config(struct pci_bus *bus,
                        unsigned int devfn, int where, int size, u32 * val)
 {
-       void __iomem *addr;
+       volatile void __iomem *epci_base, *addr;
        struct device_node *node;
        struct pci_controller *hose;
 
@@ -142,13 +167,14 @@ static int celleb_epci_read_config(struct pci_bus *bus,
        node = (struct device_node *)bus->sysdata;
        hose = pci_find_hose_for_OF_device(node);
 
-       if (!hose->cfg_data)
+       if (!celleb_epci_get_epci_cfg(hose))
                return PCIBIOS_DEVICE_NOT_FOUND;
 
        if (bus->number == hose->first_busno && devfn == 0) {
                /* EPCI controller self */
 
-               addr = hose->cfg_addr + where;
+               epci_base = celleb_epci_get_epci_base(hose);
+               addr = epci_base + where;
 
                switch (size) {
                case 1:
@@ -185,7 +211,7 @@ static int celleb_epci_read_config(struct pci_bus *bus,
        }
 
        pr_debug("EPCI: "
-                "addr=0x%lx, devfn=0x%x, where=0x%x, size=0x%x, val=0x%x\n",
+                "addr=0x%p, devfn=0x%x, where=0x%x, size=0x%x, val=0x%x\n",
                 addr, devfn, where, size, *val);
 
        return celleb_epci_check_abort(hose, NULL);
@@ -194,7 +220,7 @@ static int celleb_epci_read_config(struct pci_bus *bus,
 static int celleb_epci_write_config(struct pci_bus *bus,
                        unsigned int devfn, int where, int size, u32 val)
 {
-       void __iomem *addr;
+       volatile void __iomem *epci_base, *addr;
        struct device_node *node;
        struct pci_controller *hose;
 
@@ -204,13 +230,15 @@ static int celleb_epci_write_config(struct pci_bus *bus,
        node = (struct device_node *)bus->sysdata;
        hose = pci_find_hose_for_OF_device(node);
 
-       if (!hose->cfg_data)
+
+       if (!celleb_epci_get_epci_cfg(hose))
                return PCIBIOS_DEVICE_NOT_FOUND;
 
        if (bus->number == hose->first_busno && devfn == 0) {
                /* EPCI controller self */
 
-               addr = hose->cfg_addr + where;
+               epci_base = celleb_epci_get_epci_base(hose);
+               addr = epci_base + where;
 
                switch (size) {
                case 1:
@@ -258,10 +286,10 @@ struct pci_ops celleb_epci_ops = {
 static int __devinit celleb_epci_init(struct pci_controller *hose)
 {
        u32 val;
-       void __iomem *reg, *epci_base;
+       volatile void __iomem *reg, *epci_base;
        int hwres = 0;
 
-       epci_base = hose->cfg_addr;
+       epci_base = celleb_epci_get_epci_base(hose);
 
        /* PCI core reset(Internal bus and PCI clock) */
        reg = epci_base + SCC_EPCI_CKCTRL;
@@ -382,6 +410,18 @@ int __devinit celleb_setup_epci(struct device_node *node,
 
        pr_debug("PCI: celleb_setup_epci()\n");
 
+       /*
+        * Note:
+        * Celleb epci uses cfg_addr and cfg_data member of
+        * pci_controller structure in irregular way.
+        *
+        * cfg_addr is used to map for control registers of
+        * celleb epci.
+        *
+        * cfg_data is used for configuration area of devices
+        * on Celleb epci buses.
+        */
+
        if (of_address_to_resource(node, 0, &r))
                goto error;
        hose->cfg_addr = ioremap(r.start, (r.end - r.start + 1));
index 886c522d78e94b5b9b417b8adeb104cdf333dec3..3410bcbc9dbe04030b6952ce537f1306a2186d18 100644 (file)
@@ -79,6 +79,7 @@ config LINKSTATION
        select MPIC
        select FSL_SOC
        select PPC_UDBG_16550 if SERIAL_8250
+       select DEFAULT_UIMAGE
        help
          Select LINKSTATION if configuring for one of PPC- (MPC8241)
          based NAS systems from Buffalo Technology. So far only
index c29a6a064d2244e70d23464ddae9302d3b3afd25..24cc50c1774ad5131429ed27caef9e7add3ed906 100644 (file)
@@ -810,6 +810,7 @@ core99_ata100_enable(struct device_node *node, long value)
        unsigned long flags;
        struct pci_dev *pdev = NULL;
        u8 pbus, pid;
+       int rc;
 
        if (uninorth_rev < 0x24)
                return -ENODEV;
@@ -828,7 +829,9 @@ core99_ata100_enable(struct device_node *node, long value)
                        pdev = pci_find_slot(pbus, pid);
                if (pdev == NULL)
                        return 0;
-               pci_enable_device(pdev);
+               rc = pci_enable_device(pdev);
+               if (rc)
+                       return rc;
                pci_set_master(pdev);
        }
        return 0;
index f42475b27c153c324f150d9e4ff3a352c4cafba3..6fbac308ded649ffcee13fbdacfe2ea04e55959e 100644 (file)
@@ -1191,8 +1191,11 @@ void __init pmac_pcibios_after_init(void)
         * -- BenH
         */
        for_each_pci_dev(dev) {
-               if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE)
-                       pci_enable_device(dev);
+               if ((dev->class >> 16) != PCI_BASE_CLASS_STORAGE)
+                       continue;
+               if (pci_enable_device(dev))
+                       printk(KERN_WARNING
+                              "pci: Failed to enable %s\n", pci_name(dev));
        }
 #endif /* CONFIG_BLK_DEV_IDE */
 
index 0183e5fbaf46bc7ccb7b159b0035a94c72b23c3c..bf299b66f3fc6c0198b0f88110ea718915251769 100644 (file)
@@ -218,7 +218,7 @@ Commands:\n\
 "  ss  stop execution on all spus\n\
   sr   restore execution on stopped spus\n\
   sf  #        dump spu fields for spu # (in hex)\n\
-  sd  #        dump spu local store for spu # (in hex)\
+  sd  #        dump spu local store for spu # (in hex)\n\
   sdi #        disassemble spu local store for spu # (in hex)\n"
 #endif
 "  S   print special registers\n\
index 8047ea8c2ab271e9e315547e3a77450d31edcab4..dec587b293bfcf9ccfed71798279fdd8408c9a9f 100644 (file)
@@ -30,11 +30,8 @@ static void via_bugs(void)
 
 #ifdef CONFIG_ACPI
 
-static int nvidia_hpet_detected __initdata;
-
 static int __init nvidia_hpet_check(struct acpi_table_header *header)
 {
-       nvidia_hpet_detected = 1;
        return 0;
 }
 #endif
@@ -52,11 +49,7 @@ static void nvidia_bugs(void)
        if (acpi_use_timer_override)
                return;
 
-       nvidia_hpet_detected = 0;
-       if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check))
-               return;
-
-       if (nvidia_hpet_detected == 0) {
+       if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) {
                acpi_skip_timer_override = 1;
                printk(KERN_INFO "Nvidia board "
                       "detected. Ignoring ACPI "
index 7c49e103cf8fee8003fbedd8ee36c484767bf6bb..e2ce4a9c1c9259adf6d16da21b0a8b313f15b906 100644 (file)
@@ -7,6 +7,7 @@ menu "ACPI (Advanced Configuration and Power Interface) Support"
        depends on !X86_VISWS
        depends on !IA64_HP_SIM
        depends on IA64 || X86
+       depends on PM
 
 config ACPI
        bool "ACPI Support"
@@ -243,6 +244,17 @@ config ACPI_IBM_DOCK
 
          If you are not sure, say N here.
 
+config ACPI_IBM_BAY
+       bool "Legacy Removable Bay Support"
+       depends on ACPI_IBM
+       default y
+       ---help---
+         Allows the ibm_acpi driver to handle removable bays.  It will allow
+         disabling the device in the bay, and also generate notifications when
+         the bay lever is ejected or inserted.
+
+         If you are not sure, say Y here.
+
 config ACPI_TOSHIBA
        tristate "Toshiba Laptop Extras"
        depends on X86
index f289fd41e77d5ef1bdb8d4d44359b08a43651930..3ec110ce00c8c3096b6f0ed7c379777b05e4822d 100644 (file)
@@ -79,11 +79,17 @@ static int __init blacklist_by_year(void)
 {
        int year = dmi_get_year(DMI_BIOS_DATE);
        /* Doesn't exist? Likely an old system */
-       if (year == -1)
+       if (year == -1) {
+               printk(KERN_ERR PREFIX "no DMI BIOS year, "
+                       "acpi=force is required to enable ACPI\n" );
                return 1;
+       }
        /* 0? Likely a buggy new BIOS */
-       if (year == 0)
+       if (year == 0) {
+               printk(KERN_ERR PREFIX "DMI BIOS year==0, "
+                       "assuming ACPI-capable machine\n" );
                return 0;
+       }
        if (year < CONFIG_ACPI_BLACKLIST_YEAR) {
                printk(KERN_ERR PREFIX "BIOS age (%d) fails cutoff (%d), "
                       "acpi=force is required to enable ACPI\n",
index ab688837379534b46ab194dacb41925215c3670b..a802962ff2b499fc2cc3489a5e28a02e58d2465d 100644 (file)
@@ -100,6 +100,7 @@ static struct acpi_ec {
        unsigned long global_lock;
        struct mutex lock;
        atomic_t query_pending;
+       atomic_t event_count;
        atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
        wait_queue_head_t wait;
 } *ec_ecdt;
@@ -131,10 +132,12 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
        outb(data, ec->data_addr);
 }
 
-static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
+static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event,
+                                      unsigned old_count)
 {
        u8 status = acpi_ec_read_status(ec);
-
+       if (old_count == atomic_read(&ec->event_count))
+               return 0;
        if (event == ACPI_EC_EVENT_OBF_1) {
                if (status & ACPI_EC_FLAG_OBF)
                        return 1;
@@ -146,19 +149,19 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
        return 0;
 }
 
-static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event)
+static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, unsigned count)
 {
        if (acpi_ec_mode == EC_POLL) {
                unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
                while (time_before(jiffies, delay)) {
-                       if (acpi_ec_check_status(ec, event))
+                       if (acpi_ec_check_status(ec, event, 0))
                                return 0;
                }
        } else {
                if (wait_event_timeout(ec->wait,
-                                      acpi_ec_check_status(ec, event),
+                                      acpi_ec_check_status(ec, event, count),
                                       msecs_to_jiffies(ACPI_EC_DELAY)) ||
-                   acpi_ec_check_status(ec, event)) {
+                   acpi_ec_check_status(ec, event, 0)) {
                        return 0;
                } else {
                        printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
@@ -225,21 +228,22 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
                                        u8 * rdata, unsigned rdata_len)
 {
        int result = 0;
-
+       unsigned count = atomic_read(&ec->event_count);
        acpi_ec_write_cmd(ec, command);
 
        for (; wdata_len > 0; --wdata_len) {
-               result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
+               result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count);
                if (result) {
                        printk(KERN_ERR PREFIX
                               "write_cmd timeout, command = %d\n", command);
                        goto end;
                }
+               count = atomic_read(&ec->event_count);
                acpi_ec_write_data(ec, *(wdata++));
        }
 
        if (!rdata_len) {
-               result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
+               result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count);
                if (result) {
                        printk(KERN_ERR PREFIX
                               "finish-write timeout, command = %d\n", command);
@@ -250,13 +254,13 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
        }
 
        for (; rdata_len > 0; --rdata_len) {
-               result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
+               result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, count);
                if (result) {
                        printk(KERN_ERR PREFIX "read timeout, command = %d\n",
                               command);
                        goto end;
                }
-
+               count = atomic_read(&ec->event_count);
                *(rdata++) = acpi_ec_read_data(ec);
        }
       end:
@@ -288,7 +292,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
        /* Make sure GPE is enabled before doing transaction */
        acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
 
-       status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
+       status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0);
        if (status) {
                printk(KERN_DEBUG PREFIX
                       "input buffer is not empty, aborting transaction\n");
@@ -369,8 +373,8 @@ int ec_write(u8 addr, u8 val)
 EXPORT_SYMBOL(ec_write);
 
 int ec_transaction(u8 command,
-                         const u8 * wdata, unsigned wdata_len,
-                         u8 * rdata, unsigned rdata_len)
+                  const u8 * wdata, unsigned wdata_len,
+                  u8 * rdata, unsigned rdata_len)
 {
        struct acpi_ec *ec;
 
@@ -435,7 +439,7 @@ static u32 acpi_ec_gpe_handler(void *data)
        acpi_status status = AE_OK;
        u8 value;
        struct acpi_ec *ec = (struct acpi_ec *)data;
-
+       atomic_inc(&ec->event_count);
        if (acpi_ec_mode == EC_INTR) {
                wake_up(&ec->wait);
        }
@@ -633,6 +637,7 @@ static int acpi_ec_add(struct acpi_device *device)
        ec->uid = -1;
        mutex_init(&ec->lock);
        atomic_set(&ec->query_pending, 0);
+       atomic_set(&ec->event_count, 1);
        if (acpi_ec_mode == EC_INTR) {
                atomic_set(&ec->leaving_burst, 1);
                init_waitqueue_head(&ec->wait);
@@ -807,6 +812,7 @@ acpi_fake_ecdt_callback(acpi_handle handle,
        acpi_status status;
 
        mutex_init(&ec_ecdt->lock);
+       atomic_set(&ec_ecdt->event_count, 1);
        if (acpi_ec_mode == EC_INTR) {
                init_waitqueue_head(&ec_ecdt->wait);
        }
@@ -888,6 +894,7 @@ static int __init acpi_ec_get_real_ecdt(void)
                return -ENOMEM;
 
        mutex_init(&ec_ecdt->lock);
+       atomic_set(&ec_ecdt->event_count, 1);
        if (acpi_ec_mode == EC_INTR) {
                init_waitqueue_head(&ec_ecdt->wait);
        }
@@ -1016,8 +1023,7 @@ static int __init acpi_ec_set_intr_mode(char *str)
                acpi_ec_mode = EC_POLL;
        }
        acpi_ec_driver.ops.add = acpi_ec_add;
-       printk(KERN_NOTICE PREFIX "%s mode.\n",
-                         intr ? "interrupt" : "polling");
+       printk(KERN_NOTICE PREFIX "%s mode.\n", intr ? "interrupt" : "polling");
 
        return 1;
 }
index d572700197f309d118ff302fde56c29a2c25fb1a..8dcade63b04bad04608b29eaab97f82ea2420b15 100644 (file)
@@ -423,6 +423,8 @@ static acpi_status acpi_ev_remove_global_lock_handler(void)
  * the global lock appear as a standard mutex on the OS side.
  *
  *****************************************************************************/
+static acpi_thread_id acpi_ev_global_lock_thread_id;
+static int acpi_ev_global_lock_acquired;
 
 acpi_status acpi_ev_acquire_global_lock(u16 timeout)
 {
@@ -435,11 +437,24 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
         * Only one thread can acquire the GL at a time, the global_lock_mutex
         * enforces this. This interface releases the interpreter if we must wait.
         */
-       status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout);
+       status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0);
+       if (status == AE_TIME) {
+               if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
+                       acpi_ev_global_lock_acquired++;
+                       return AE_OK;
+               }
+       }
+
+       if (ACPI_FAILURE(status)) {
+               status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout);
+       }
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
 
+       acpi_ev_global_lock_thread_id = acpi_os_get_thread_id();
+       acpi_ev_global_lock_acquired++;
+
        /*
         * Make sure that a global lock actually exists. If not, just treat
         * the lock as a standard mutex.
@@ -506,6 +521,11 @@ acpi_status acpi_ev_release_global_lock(void)
                return_ACPI_STATUS(AE_NOT_ACQUIRED);
        }
 
+       acpi_ev_global_lock_acquired--;
+       if (acpi_ev_global_lock_acquired > 0) {
+               return AE_OK;
+       }
+
        if (acpi_gbl_global_lock_present) {
 
                /* Allow any thread to release the lock */
@@ -529,7 +549,8 @@ acpi_status acpi_ev_release_global_lock(void)
        acpi_gbl_global_lock_acquired = FALSE;
 
        /* Release the local GL mutex */
-
+       acpi_ev_global_lock_thread_id = 0;
+       acpi_ev_global_lock_acquired = 0;
        acpi_os_release_mutex(acpi_gbl_global_lock_mutex);
        return_ACPI_STATUS(status);
 }
index 4cc534e36e81cb3308c8d4015bca2280fbe1f914..36901362fd24418917ab0727f1450bd217d58967 100644 (file)
@@ -86,6 +86,7 @@
 
 #include <linux/proc_fs.h>
 #include <linux/backlight.h>
+#include <linux/fb.h>
 #include <asm/uaccess.h>
 
 #include <linux/dmi.h>
@@ -157,6 +158,7 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK",        /* X30, X31, X40 */
           "\\_SB.PCI.ISA.SLCE",        /* 570 */
     );                         /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
 #endif
+#ifdef CONFIG_ACPI_IBM_BAY
 IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST",       /* 570 */
           "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */
           "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */ 
@@ -174,6 +176,7 @@ IBM_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */
 IBM_HANDLE(bay2_ej, bay2, "_EJ3",      /* 600e/x, 770e, A3x */
           "_EJ0",              /* 770x */
     );                         /* all others */
+#endif /* CONFIG_ACPI_IBM_BAY */
 
 /* don't list other alternatives as we install a notify handler on the 570 */
 IBM_HANDLE(pci, root, "\\_SB.PCI");    /* 570 */
@@ -1044,6 +1047,7 @@ static int light_write(char *buf)
        return 0;
 }
 
+#if defined(CONFIG_ACPI_IBM_DOCK) || defined(CONFIG_ACPI_IBM_BAY)
 static int _sta(acpi_handle handle)
 {
        int status;
@@ -1053,6 +1057,7 @@ static int _sta(acpi_handle handle)
 
        return status;
 }
+#endif
 
 #ifdef CONFIG_ACPI_IBM_DOCK
 #define dock_docked() (_sta(dock_handle) & 1)
@@ -1119,6 +1124,7 @@ static void dock_notify(struct ibm_struct *ibm, u32 event)
 }
 #endif
 
+#ifdef CONFIG_ACPI_IBM_BAY
 static int bay_status_supported;
 static int bay_status2_supported;
 static int bay_eject_supported;
@@ -1194,6 +1200,7 @@ static void bay_notify(struct ibm_struct *ibm, u32 event)
 {
        acpi_bus_generate_event(ibm->device, event, 0);
 }
+#endif /* CONFIG_ACPI_IBM_BAY */
 
 static int cmos_read(char *p)
 {
@@ -1701,7 +1708,10 @@ static int brightness_write(char *buf)
 
 static int brightness_update_status(struct backlight_device *bd)
 {
-       return brightness_set(bd->props.brightness);
+       return brightness_set(
+               (bd->props.fb_blank == FB_BLANK_UNBLANK &&
+                bd->props.power == FB_BLANK_UNBLANK) ?
+                               bd->props.brightness : 0);
 }
 
 static struct backlight_ops ibm_backlight_data = {
@@ -1711,6 +1721,12 @@ static struct backlight_ops ibm_backlight_data = {
 
 static int brightness_init(void)
 {
+       int b;
+
+       b = brightness_get(NULL);
+       if (b < 0)
+               return b;
+
        ibm_backlight_device = backlight_device_register("ibm", NULL, NULL,
                                                         &ibm_backlight_data);
        if (IS_ERR(ibm_backlight_device)) {
@@ -1718,7 +1734,9 @@ static int brightness_init(void)
                return PTR_ERR(ibm_backlight_device);
        }
 
-        ibm_backlight_device->props.max_brightness = 7;
+       ibm_backlight_device->props.max_brightness = 7;
+       ibm_backlight_device->props.brightness = b;
+       backlight_update_status(ibm_backlight_device);
 
        return 0;
 }
@@ -2353,6 +2371,7 @@ static struct ibm_struct ibms[] = {
         .type = ACPI_SYSTEM_NOTIFY,
         },
 #endif
+#ifdef CONFIG_ACPI_IBM_BAY
        {
         .name = "bay",
         .init = bay_init,
@@ -2362,6 +2381,7 @@ static struct ibm_struct ibms[] = {
         .handle = &bay_handle,
         .type = ACPI_SYSTEM_NOTIFY,
         },
+#endif /* CONFIG_ACPI_IBM_BAY */
        {
         .name = "cmos",
         .read = cmos_read,
@@ -2647,7 +2667,9 @@ IBM_PARAM(light);
 #ifdef CONFIG_ACPI_IBM_DOCK
 IBM_PARAM(dock);
 #endif
+#ifdef CONFIG_ACPI_IBM_BAY
 IBM_PARAM(bay);
+#endif /* CONFIG_ACPI_IBM_BAY */
 IBM_PARAM(cmos);
 IBM_PARAM(led);
 IBM_PARAM(beep);
@@ -2723,12 +2745,14 @@ static int __init acpi_ibm_init(void)
        IBM_HANDLE_INIT(dock);
 #endif
        IBM_HANDLE_INIT(pci);
+#ifdef CONFIG_ACPI_IBM_BAY
        IBM_HANDLE_INIT(bay);
        if (bay_handle)
                IBM_HANDLE_INIT(bay_ej);
        IBM_HANDLE_INIT(bay2);
        if (bay2_handle)
                IBM_HANDLE_INIT(bay2_ej);
+#endif /* CONFIG_ACPI_IBM_BAY */
        IBM_HANDLE_INIT(beep);
        IBM_HANDLE_INIT(ecrd);
        IBM_HANDLE_INIT(ecwr);
index 1ef338545dfef977034a490d56ae9c5f043eb948..4ffecd17970277f46967bb959bce94c15dacffe0 100644 (file)
@@ -436,8 +436,6 @@ int acpi_power_transition(struct acpi_device *device, int state)
        cl = &device->power.states[device->power.state].resources;
        tl = &device->power.states[state].resources;
 
-       device->power.state = ACPI_STATE_UNKNOWN;
-
        if (!cl->count && !tl->count) {
                result = -ENODEV;
                goto end;
@@ -468,12 +466,15 @@ int acpi_power_transition(struct acpi_device *device, int state)
                        goto end;
        }
 
-       /* We shouldn't change the state till all above operations succeed */
-       device->power.state = state;
-      end:
-       if (result)
+     end:
+       if (result) {
+               device->power.state = ACPI_STATE_UNKNOWN;
                printk(KERN_WARNING PREFIX "Transitioning device [%s] to D%d\n",
                              device->pnp.bus_id, state);
+       } else {
+       /* We shouldn't change the state till all above operations succeed */
+               device->power.state = state;
+       }
 
        return result;
 }
@@ -687,13 +688,6 @@ static int acpi_power_resume(struct acpi_device *device)
                return result;
 
        mutex_lock(&resource->resource_lock);
-       if ((resource->state == ACPI_POWER_RESOURCE_STATE_ON) &&
-           list_empty(&resource->reference)) {
-               mutex_unlock(&resource->resource_lock);
-               result = acpi_power_off_device(device->handle, NULL);
-               return result;
-       }
-
        if ((resource->state == ACPI_POWER_RESOURCE_STATE_OFF) &&
            !list_empty(&resource->reference)) {
                ref = container_of(resource->reference.next, struct acpi_power_reference, node);
index 1358c06a969c2b2d8d2a795556c4f6f3d169575f..cc48ab05676c5ccefd1b342cd8532260c48d6470 100644 (file)
@@ -191,6 +191,9 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
        user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
 
        for (index = 0; index < number_of_elements; index++) {
+               int source_name_index = 2;
+               int source_index_index = 3;
+
                /*
                 * Point user_prt past this current structure
                 *
@@ -260,11 +263,29 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
                        return_ACPI_STATUS(AE_BAD_DATA);
                }
 
+               /*
+                * If BIOS erroneously reversed the _PRT source_name and source_index,
+                * then reverse them back.
+                */
+               if (ACPI_GET_OBJECT_TYPE (sub_object_list[3]) != ACPI_TYPE_INTEGER) {
+                       if (acpi_gbl_enable_interpreter_slack) {
+                               source_name_index = 3;
+                               source_index_index = 2;
+                               printk(KERN_WARNING "ACPI: Handling Garbled _PRT entry\n");
+                       } else {
+                               ACPI_ERROR((AE_INFO,
+                                       "(PRT[%X].source_index) Need Integer, found %s",
+                                       index,
+                                       acpi_ut_get_object_type_name(sub_object_list[3])));
+                               return_ACPI_STATUS(AE_BAD_DATA);
+                       }
+               }
+
                /*
                 * 3) Third subobject: Dereference the PRT.source_name
                 * The name may be unresolved (slack mode), so allow a null object
                 */
-               obj_desc = sub_object_list[2];
+               obj_desc = sub_object_list[source_name_index];
                if (obj_desc) {
                        switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
                        case ACPI_TYPE_LOCAL_REFERENCE:
@@ -339,7 +360,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
 
                /* 4) Fourth subobject: Dereference the PRT.source_index */
 
-               obj_desc = sub_object_list[3];
+               obj_desc = sub_object_list[source_index_index];
                if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
                        user_prt->source_index = (u32) obj_desc->integer.value;
                } else {
index 0771b434feb2259542c9b293ed775e9424010e91..00d25b34725549e86b739354cf5f972e6a10831f 100644 (file)
@@ -102,9 +102,9 @@ struct acpi_video_bus_cap {
 
 struct acpi_video_device_attrib {
        u32 display_index:4;    /* A zero-based instance of the Display */
-       u32 display_port_attachment:4;  /*This field differenates displays type */
+       u32 display_port_attachment:4;  /*This field differentiates the display type */
        u32 display_type:4;     /*Describe the specific type in use */
-       u32 vendor_specific:4;  /*Chipset Vendor Specifi */
+       u32 vendor_specific:4;  /*Chipset Vendor Specific */
        u32 bios_can_detect:1;  /*BIOS can detect the device */
        u32 depend_on_vga:1;    /*Non-VGA output device whose power is related to 
                                   the VGA device. */
@@ -484,16 +484,16 @@ acpi_video_bus_POST_options(struct acpi_video_bus *video,
  *             0.      The system BIOS should NOT automatically switch(toggle)
  *                     the active display output.
  *             1.      The system BIOS should automatically switch (toggle) the
- *                     active display output. No swich event.
+ *                     active display output. No switch event.
  *             2.      The _DGS value should be locked.
  *             3.      The system BIOS should not automatically switch (toggle) the
  *                     active display output, but instead generate the display switch
  *                     event notify code.
  *     lcd_flag        :
  *             0.      The system BIOS should automatically control the brightness level
- *                     of the LCD, when the power changes from AC to DC
+ *                     of the LCD when the power changes from AC to DC
  *             1.      The system BIOS should NOT automatically control the brightness 
- *                     level of the LCD, when the power changes from AC to DC.
+ *                     level of the LCD when the power changes from AC to DC.
  * Return Value:
  *             -1      wrong arg.
  */
@@ -525,7 +525,7 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
  *  Return Value:
  *     None
  *
- *  Find out all required AML method defined under the output
+ *  Find out all required AML methods defined under the output
  *  device.
  */
 
@@ -636,7 +636,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
  *  Return Value:
  *     None
  *
- *  Find out all required AML method defined under the video bus device.
+ *  Find out all required AML methods defined under the video bus device.
  */
 
 static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
@@ -681,19 +681,19 @@ static int acpi_video_bus_check(struct acpi_video_bus *video)
         * to check well known required nodes.
         */
 
-       /* Does this device able to support video switching ? */
+       /* Does this device support video switching? */
        if (video->cap._DOS) {
                video->flags.multihead = 1;
                status = 0;
        }
 
-       /* Does this device able to retrieve a retrieve a video ROM ? */
+       /* Does this device support retrieving a video ROM? */
        if (video->cap._ROM) {
                video->flags.rom = 1;
                status = 0;
        }
 
-       /* Does this device able to configure which video device to POST ? */
+       /* Does this device support configuring which video device to POST? */
        if (video->cap._GPD && video->cap._SPD && video->cap._VPO) {
                video->flags.post = 1;
                status = 0;
@@ -860,7 +860,7 @@ acpi_video_device_write_brightness(struct file *file,
        if (level > 100)
                return -EFAULT;
 
-       /* validate though the list of available levels */
+       /* validate through the list of available levels */
        for (i = 0; i < dev->brightness->count; i++)
                if (level == dev->brightness->levels[i]) {
                        if (ACPI_SUCCESS
@@ -1065,10 +1065,10 @@ static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
                        printk(KERN_WARNING PREFIX
                               "The motherboard VGA device is not listed as a possible POST device.\n");
                        printk(KERN_WARNING PREFIX
-                              "This indicate a BIOS bug.  Please contact the manufacturer.\n");
+                              "This indicates a BIOS bug. Please contact the manufacturer.\n");
                }
                printk("%lx\n", options);
-               seq_printf(seq, "can POST: <intgrated video>");
+               seq_printf(seq, "can POST: <integrated video>");
                if (options & 2)
                        seq_printf(seq, " <PCI video>");
                if (options & 4)
@@ -1102,7 +1102,7 @@ static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
                seq_printf(seq, "<not supported>\n");
                goto end;
        }
-       seq_printf(seq, "device posted is <%s>\n", device_decode[id & 3]);
+       seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]);
 
       end:
        return 0;
@@ -1156,7 +1156,7 @@ acpi_video_bus_write_POST(struct file *file,
        if (opt > 3)
                return -EFAULT;
 
-       /* just in case an OEM 'forget' the motherboard... */
+       /* just in case an OEM 'forgot' the motherboard... */
        options |= 1;
 
        if (options & (1ul << opt)) {
@@ -1527,13 +1527,13 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
 /*
  *  Arg:
  *     video   : video bus device 
- *     event   : Nontify Event
+ *     event   : notify event
  *
  *  Return:
  *     < 0     : error
  *  
  *     1. Find out the current active output device.
- *     2. Identify the next output device to switch
+ *     2. Identify the next output device to switch to.
  *     3. call _DSS to do actual switch.
  */
 
@@ -1723,12 +1723,12 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
        device = video->device;
 
        switch (event) {
-       case ACPI_VIDEO_NOTIFY_SWITCH:  /* User request that a switch occur,
+       case ACPI_VIDEO_NOTIFY_SWITCH:  /* User requested a switch,
                                         * most likely via hotkey. */
                acpi_bus_generate_event(device, event, 0);
                break;
 
-       case ACPI_VIDEO_NOTIFY_PROBE:   /* User plug or remove a video
+       case ACPI_VIDEO_NOTIFY_PROBE:   /* User plugged in or removed a video
                                         * connector. */
                acpi_video_device_enumerate(video);
                acpi_video_device_rebind(video);
index dc42ba1b46f7220b833623be991a2b0b2d72c51e..b952c584338fb4fe3f797435a1f720c8b6070ef4 100644 (file)
@@ -93,7 +93,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "ata_piix"
-#define DRV_VERSION    "2.10"
+#define DRV_VERSION    "2.10ac1"
 
 enum {
        PIIX_IOCFG              = 0x54, /* IDE I/O configuration register */
@@ -667,14 +667,9 @@ static int ich_pata_prereset(struct ata_port *ap)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
-       if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) {
-               ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n");
-               ap->eh_context.i.action &= ~ATA_EH_RESET_MASK;
-               return 0;
-       }
-
+       if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
+               return -ENOENT;
        ich_pata_cbl_detect(ap);
-
        return ata_std_prereset(ap);
 }
 
index d14a48e75f1b50414c3cbfba2afff82ce8c853d2..c428a56e6f315e3e7e221f82c25206129af9acab 100644 (file)
@@ -34,6 +34,13 @@ struct taskfile_array {
        u8      tfa[REGS_PER_GTF];      /* regs. 0x1f1 - 0x1f7 */
 };
 
+/*
+ *     Helper - belongs in the PCI layer somewhere eventually
+ */
+static int is_pci_dev(struct device *dev)
+{
+       return (dev->bus == &pci_bus_type);
+}
 
 /**
  * sata_get_dev_handle - finds acpi_handle and PCI device.function
@@ -53,6 +60,9 @@ static int sata_get_dev_handle(struct device *dev, acpi_handle *handle,
        struct pci_dev  *pci_dev;
        acpi_integer    addr;
 
+       if (!is_pci_dev(dev))
+               return -ENODEV;
+
        pci_dev = to_pci_dev(dev);      /* NOTE: PCI-specific */
        /* Please refer to the ACPI spec for the syntax of _ADR. */
        addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
@@ -84,7 +94,12 @@ static int pata_get_dev_handle(struct device *dev, acpi_handle *handle,
        acpi_status status;
        struct acpi_device_info *dinfo = NULL;
        int ret = -ENODEV;
-       struct pci_dev *pdev = to_pci_dev(dev);
+       struct pci_dev *pdev;
+
+       if (!is_pci_dev(dev))
+               return -ENODEV;
+
+       pdev = to_pci_dev(dev);
 
        bus = pdev->bus->number;
        devnum = PCI_SLOT(pdev->devfn);
@@ -561,6 +576,13 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
 
        if (noacpi)
                return 0;
+       /*
+        * TBD - implement PATA support.  For now,
+        * we should not run GTF on PATA devices since some
+        * PATA require execution of GTM/STM before GTF.
+        */
+       if (!(ap->cbl == ATA_CBL_SATA))
+               return 0;
 
        for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
                if (!ata_dev_enabled(&ap->device[ix]))
index dc362fa01ca46f44680018fde3b5372f03d7f57b..3c1f8830ac8bf7dedef3d44b049beefcf695e811 100644 (file)
@@ -3455,7 +3455,8 @@ static void ata_dev_xfermask(struct ata_device *dev)
                               "device is on DMA blacklist, disabling DMA\n");
        }
 
-       if ((host->flags & ATA_HOST_SIMPLEX) && host->simplex_claimed != ap) {
+       if ((host->flags & ATA_HOST_SIMPLEX) &&
+            host->simplex_claimed && host->simplex_claimed != ap) {
                xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
                ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by "
                               "other device, disabling DMA\n");
@@ -5684,18 +5685,22 @@ static void ata_host_release(struct device *gendev, void *res)
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
 
-               if (!ap)
-                       continue;
-
-               if (ap->ops->port_stop)
+               if (ap && ap->ops->port_stop)
                        ap->ops->port_stop(ap);
-
-               scsi_host_put(ap->scsi_host);
        }
 
        if (host->ops->host_stop)
                host->ops->host_stop(host);
 
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+
+               if (ap)
+                       scsi_host_put(ap->scsi_host);
+
+               host->ports[i] = NULL;
+       }
+
        dev_set_drvdata(gendev, NULL);
 }
 
index 388d07fab5f7dcc465d1d962db09ac8a65909b24..9d9670a9b117e67d3689b8f5b2a1aa4b586f9ac6 100644 (file)
@@ -874,8 +874,14 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
 
                        if (status & (NV_ADMA_STAT_DONE |
                                      NV_ADMA_STAT_CPBERR)) {
-                               u32 check_commands = notifier | notifier_error;
+                               u32 check_commands;
                                int pos, error = 0;
+
+                               if(ata_tag_valid(ap->active_tag))
+                                       check_commands = 1 << ap->active_tag;
+                               else
+                                       check_commands = ap->sactive;
+
                                /** Check CPBs for completed commands */
                                while ((pos = ffs(check_commands)) && !error) {
                                        pos--;
index cf2a398aaaa1f6c0113bb1b58793e8d14b940129..f191afe62b4d06633dc84490ec6e630d983c6a1a 100644 (file)
@@ -584,17 +584,17 @@ int device_add(struct device *dev)
                if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
                        sysfs_create_link(&dev->class->subsys.kset.kobj,
                                          &dev->kobj, dev->bus_id);
-#ifdef CONFIG_SYSFS_DEPRECATED
                if (parent) {
                        sysfs_create_link(&dev->kobj, &dev->parent->kobj,
                                                        "device");
+#ifdef CONFIG_SYSFS_DEPRECATED
                        class_name = make_class_name(dev->class->name,
                                                        &dev->kobj);
                        if (class_name)
                                sysfs_create_link(&dev->parent->kobj,
                                                  &dev->kobj, class_name);
-               }
 #endif
+               }
        }
 
        if ((error = device_add_attrs(dev)))
@@ -651,17 +651,17 @@ int device_add(struct device *dev)
                if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
                        sysfs_remove_link(&dev->class->subsys.kset.kobj,
                                          dev->bus_id);
-#ifdef CONFIG_SYSFS_DEPRECATED
                if (parent) {
+#ifdef CONFIG_SYSFS_DEPRECATED
                        char *class_name = make_class_name(dev->class->name,
                                                           &dev->kobj);
                        if (class_name)
                                sysfs_remove_link(&dev->parent->kobj,
                                                  class_name);
                        kfree(class_name);
+#endif
                        sysfs_remove_link(&dev->kobj, "device");
                }
-#endif
 
                down(&dev->class->sem);
                /* notify any interfaces that the device is now gone */
@@ -761,17 +761,17 @@ void device_del(struct device * dev)
                if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
                        sysfs_remove_link(&dev->class->subsys.kset.kobj,
                                          dev->bus_id);
-#ifdef CONFIG_SYSFS_DEPRECATED
                if (parent) {
+#ifdef CONFIG_SYSFS_DEPRECATED
                        char *class_name = make_class_name(dev->class->name,
                                                           &dev->kobj);
                        if (class_name)
                                sysfs_remove_link(&dev->parent->kobj,
                                                  class_name);
                        kfree(class_name);
+#endif
                        sysfs_remove_link(&dev->kobj, "device");
                }
-#endif
 
                down(&dev->class->sem);
                /* notify any interfaces that the device is now gone */
@@ -787,6 +787,13 @@ void device_del(struct device * dev)
        device_remove_attrs(dev);
        bus_remove_device(dev);
 
+       /*
+        * Some platform devices are driven without driver attached
+        * and managed resources may have been acquired.  Make sure
+        * all resources are released.
+        */
+       devres_release_all(dev);
+
        /* Notify the platform of the removal, in case they
         * need to do anything...
         */
@@ -1058,14 +1065,14 @@ int device_rename(struct device *dev, char *new_name)
 
        return error;
 }
-
+EXPORT_SYMBOL_GPL(device_rename);
 
 static int device_move_class_links(struct device *dev,
                                   struct device *old_parent,
                                   struct device *new_parent)
 {
+       int error = 0;
 #ifdef CONFIG_SYSFS_DEPRECATED
-       int error;
        char *class_name;
 
        class_name = make_class_name(dev->class->name, &dev->kobj);
@@ -1093,7 +1100,12 @@ out:
        kfree(class_name);
        return error;
 #else
-       return 0;
+       if (old_parent)
+               sysfs_remove_link(&dev->kobj, "device");
+       if (new_parent)
+               error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
+                                         "device");
+       return error;
 #endif
 }
 
index d441815a3e0c908588b55ee9d271b11e7eff5791..fde92ce45153efc7eeb6a2cfc3f46e71bb9df82b 100644 (file)
@@ -1821,7 +1821,7 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
        struct rdma_bind_list *bind_list;
        int port, ret;
 
-       bind_list = kmalloc(sizeof *bind_list, GFP_KERNEL);
+       bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL);
        if (!bind_list)
                return -ENOMEM;
 
index b516b93b85505b5a243a88ad00a670defab4c452..c859134c1daa3a0d73306f517bebc1c3920a949d 100644 (file)
@@ -266,7 +266,7 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id,
        mutex_lock(&ctx->file->mut);
        if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) {
                if (!ctx->backlog) {
-                       ret = -EDQUOT;
+                       ret = -ENOMEM;
                        kfree(uevent);
                        goto out;
                }
index d737c738d8767683c21b010d63374e3811f50761..818cf1aee8c7b1e58bdf1dc229e3b6797799bb0e 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 
 #include "cxio_resource.h"
 #include "cxio_hal.h"
index b21fde8b659d327136bdd02fef1dd67b14eddb36..d0ed1d35ca3ebda4a171393fd1c6122aa916e9dd 100644 (file)
@@ -305,8 +305,7 @@ static int status2errno(int status)
  */
 static struct sk_buff *get_skb(struct sk_buff *skb, int len, gfp_t gfp)
 {
-       if (skb) {
-               BUG_ON(skb_cloned(skb));
+       if (skb && !skb_is_nonlinear(skb) && !skb_cloned(skb)) {
                skb_trim(skb, 0);
                skb_get(skb);
        } else {
@@ -1415,6 +1414,7 @@ static int peer_close(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
                wake_up(&ep->com.waitq);
                break;
        case FPDU_MODE:
+               start_ep_timer(ep);
                __state_set(&ep->com, CLOSING);
                attrs.next_state = IWCH_QP_STATE_CLOSING;
                iwch_modify_qp(ep->com.qp->rhp, ep->com.qp,
@@ -1425,7 +1425,6 @@ static int peer_close(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
                disconnect = 0;
                break;
        case CLOSING:
-               start_ep_timer(ep);
                __state_set(&ep->com, MORIBUND);
                disconnect = 0;
                break;
@@ -1487,8 +1486,10 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
        case CONNECTING:
                break;
        case MPA_REQ_WAIT:
+               stop_ep_timer(ep);
                break;
        case MPA_REQ_SENT:
+               stop_ep_timer(ep);
                connect_reply_upcall(ep, -ECONNRESET);
                break;
        case MPA_REP_SENT:
@@ -1507,9 +1508,10 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
                get_ep(&ep->com);
                break;
        case MORIBUND:
+       case CLOSING:
                stop_ep_timer(ep);
+               /*FALLTHROUGH*/
        case FPDU_MODE:
-       case CLOSING:
                if (ep->com.cm_id && ep->com.qp) {
                        attrs.next_state = IWCH_QP_STATE_ERROR;
                        ret = iwch_modify_qp(ep->com.qp->rhp,
@@ -1570,7 +1572,6 @@ static int close_con_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
        spin_lock_irqsave(&ep->com.lock, flags);
        switch (ep->com.state) {
        case CLOSING:
-               start_ep_timer(ep);
                __state_set(&ep->com, MORIBUND);
                break;
        case MORIBUND:
@@ -1586,6 +1587,8 @@ static int close_con_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
                __state_set(&ep->com, DEAD);
                release = 1;
                break;
+       case ABORTING:
+               break;
        case DEAD:
        default:
                BUG_ON(1);
@@ -1659,6 +1662,7 @@ static void ep_timeout(unsigned long arg)
                break;
        case MPA_REQ_WAIT:
                break;
+       case CLOSING:
        case MORIBUND:
                if (ep->com.cm_id && ep->com.qp) {
                        attrs.next_state = IWCH_QP_STATE_ERROR;
@@ -1687,12 +1691,11 @@ int iwch_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
                return -ECONNRESET;
        }
        BUG_ON(state_read(&ep->com) != MPA_REQ_RCVD);
-       state_set(&ep->com, CLOSING);
        if (mpa_rev == 0)
                abort_connection(ep, NULL, GFP_KERNEL);
        else {
                err = send_mpa_reject(ep, pdata, pdata_len);
-               err = send_halfclose(ep, GFP_KERNEL);
+               err = iwch_ep_disconnect(ep, 0, GFP_KERNEL);
        }
        return 0;
 }
@@ -1957,11 +1960,11 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp)
        case MPA_REQ_RCVD:
        case MPA_REP_SENT:
        case FPDU_MODE:
+               start_ep_timer(ep);
                ep->com.state = CLOSING;
                close = 1;
                break;
        case CLOSING:
-               start_ep_timer(ep);
                ep->com.state = MORIBUND;
                close = 1;
                break;
index 54362afbf72f6f410b5224e8c297afb92559a6e3..b40676662a8a88df1f46d21bac5c797475741cad 100644 (file)
@@ -47,12 +47,6 @@ static void post_qp_event(struct iwch_dev *rnicp, struct iwch_cq *chp,
        struct iwch_qp_attributes attrs;
        struct iwch_qp *qhp;
 
-       printk(KERN_ERR "%s - AE qpid 0x%x opcode %d status 0x%x "
-              "type %d wrid.hi 0x%x wrid.lo 0x%x \n", __FUNCTION__,
-              CQE_QPID(rsp_msg->cqe), CQE_OPCODE(rsp_msg->cqe),
-              CQE_STATUS(rsp_msg->cqe), CQE_TYPE(rsp_msg->cqe),
-              CQE_WRID_HI(rsp_msg->cqe), CQE_WRID_LOW(rsp_msg->cqe));
-
        spin_lock(&rnicp->lock);
        qhp = get_qhp(rnicp, CQE_QPID(rsp_msg->cqe));
 
@@ -73,6 +67,12 @@ static void post_qp_event(struct iwch_dev *rnicp, struct iwch_cq *chp,
                return;
        }
 
+       printk(KERN_ERR "%s - AE qpid 0x%x opcode %d status 0x%x "
+              "type %d wrid.hi 0x%x wrid.lo 0x%x \n", __FUNCTION__,
+              CQE_QPID(rsp_msg->cqe), CQE_OPCODE(rsp_msg->cqe),
+              CQE_STATUS(rsp_msg->cqe), CQE_TYPE(rsp_msg->cqe),
+              CQE_WRID_HI(rsp_msg->cqe), CQE_WRID_LOW(rsp_msg->cqe));
+
        atomic_inc(&qhp->refcnt);
        spin_unlock(&rnicp->lock);
 
index 9947a144a929551dfd740cab7a31b334e6ecf240..f2774ae906bf66f9ac8d55a298b43e0bc7486ea1 100644 (file)
@@ -331,6 +331,7 @@ static int iwch_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
        int ret = 0;
        struct iwch_mm_entry *mm;
        struct iwch_ucontext *ucontext;
+       u64 addr;
 
        PDBG("%s pgoff 0x%lx key 0x%x len %d\n", __FUNCTION__, vma->vm_pgoff,
             key, len);
@@ -345,10 +346,11 @@ static int iwch_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
        mm = remove_mmap(ucontext, key, len);
        if (!mm)
                return -EINVAL;
+       addr = mm->addr;
        kfree(mm);
 
-       if ((mm->addr >= rdev_p->rnic_info.udbell_physbase) &&
-           (mm->addr < (rdev_p->rnic_info.udbell_physbase +
+       if ((addr >= rdev_p->rnic_info.udbell_physbase) &&
+           (addr < (rdev_p->rnic_info.udbell_physbase +
                       rdev_p->rnic_info.udbell_len))) {
 
                /*
@@ -362,7 +364,7 @@ static int iwch_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
                vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND;
                vma->vm_flags &= ~VM_MAYREAD;
                ret = io_remap_pfn_range(vma, vma->vm_start,
-                                        mm->addr >> PAGE_SHIFT,
+                                        addr >> PAGE_SHIFT,
                                         len, vma->vm_page_prot);
        } else {
 
@@ -370,7 +372,7 @@ static int iwch_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
                 * Map WQ or CQ contig dma memory...
                 */
                ret = remap_pfn_range(vma, vma->vm_start,
-                                     mm->addr >> PAGE_SHIFT,
+                                     addr >> PAGE_SHIFT,
                                      len, vma->vm_page_prot);
        }
 
@@ -463,9 +465,6 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd,
        php = to_iwch_pd(pd);
        rhp = php->rhp;
 
-       acc = iwch_convert_access(acc);
-
-
        mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
        if (!mhp)
                return ERR_PTR(-ENOMEM);
@@ -491,12 +490,7 @@ static struct ib_mr *iwch_register_phys_mem(struct ib_pd *pd,
        mhp->attr.pdid = php->pdid;
        mhp->attr.zbva = 0;
 
-       /* NOTE: TPT perms are backwards from BIND WR perms! */
-       mhp->attr.perms = (acc & 0x1) << 3;
-       mhp->attr.perms |= (acc & 0x2) << 1;
-       mhp->attr.perms |= (acc & 0x4) >> 1;
-       mhp->attr.perms |= (acc & 0x8) >> 3;
-
+       mhp->attr.perms = iwch_ib_to_tpt_access(acc);
        mhp->attr.va_fbo = *iova_start;
        mhp->attr.page_size = shift - 12;
 
@@ -525,7 +519,6 @@ static int iwch_reregister_phys_mem(struct ib_mr *mr,
        struct iwch_mr mh, *mhp;
        struct iwch_pd *php;
        struct iwch_dev *rhp;
-       int new_acc;
        __be64 *page_list = NULL;
        int shift = 0;
        u64 total_size;
@@ -546,14 +539,12 @@ static int iwch_reregister_phys_mem(struct ib_mr *mr,
        if (rhp != php->rhp)
                return -EINVAL;
 
-       new_acc = mhp->attr.perms;
-
        memcpy(&mh, mhp, sizeof *mhp);
 
        if (mr_rereg_mask & IB_MR_REREG_PD)
                php = to_iwch_pd(pd);
        if (mr_rereg_mask & IB_MR_REREG_ACCESS)
-               mh.attr.perms = iwch_convert_access(acc);
+               mh.attr.perms = iwch_ib_to_tpt_access(acc);
        if (mr_rereg_mask & IB_MR_REREG_TRANS)
                ret = build_phys_page_list(buffer_list, num_phys_buf,
                                           iova_start,
@@ -568,7 +559,7 @@ static int iwch_reregister_phys_mem(struct ib_mr *mr,
        if (mr_rereg_mask & IB_MR_REREG_PD)
                mhp->attr.pdid = php->pdid;
        if (mr_rereg_mask & IB_MR_REREG_ACCESS)
-               mhp->attr.perms = acc;
+               mhp->attr.perms = iwch_ib_to_tpt_access(acc);
        if (mr_rereg_mask & IB_MR_REREG_TRANS) {
                mhp->attr.zbva = 0;
                mhp->attr.va_fbo = *iova_start;
@@ -613,8 +604,6 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, struct ib_umem *region,
                goto err;
        }
 
-       acc = iwch_convert_access(acc);
-
        i = n = 0;
 
        list_for_each_entry(chunk, &region->chunk_list, list)
@@ -630,10 +619,7 @@ static struct ib_mr *iwch_reg_user_mr(struct ib_pd *pd, struct ib_umem *region,
        mhp->rhp = rhp;
        mhp->attr.pdid = php->pdid;
        mhp->attr.zbva = 0;
-       mhp->attr.perms = (acc & 0x1) << 3;
-       mhp->attr.perms |= (acc & 0x2) << 1;
-       mhp->attr.perms |= (acc & 0x4) >> 1;
-       mhp->attr.perms |= (acc & 0x8) >> 3;
+       mhp->attr.perms = iwch_ib_to_tpt_access(acc);
        mhp->attr.va_fbo = region->virt_base;
        mhp->attr.page_size = shift - 12;
        mhp->attr.len = (u32) region->length;
@@ -736,10 +722,8 @@ static int iwch_destroy_qp(struct ib_qp *ib_qp)
        qhp = to_iwch_qp(ib_qp);
        rhp = qhp->rhp;
 
-       if (qhp->attr.state == IWCH_QP_STATE_RTS) {
-               attrs.next_state = IWCH_QP_STATE_ERROR;
-               iwch_modify_qp(rhp, qhp, IWCH_QP_ATTR_NEXT_STATE, &attrs, 0);
-       }
+       attrs.next_state = IWCH_QP_STATE_ERROR;
+       iwch_modify_qp(rhp, qhp, IWCH_QP_ATTR_NEXT_STATE, &attrs, 0);
        wait_event(qhp->wait, !qhp->ep);
 
        remove_handle(rhp, &rhp->qpidr, qhp->wq.qpid);
index de0fe1b93a0ce144a2d48db5421d7d651c5ff7b8..93bcc56756bd42a14cce112f51b1a7ba2b3f8797 100644 (file)
@@ -286,27 +286,20 @@ static inline int iwch_convert_state(enum ib_qp_state ib_state)
        }
 }
 
-enum iwch_mem_perms {
-       IWCH_MEM_ACCESS_LOCAL_READ = 1 << 0,
-       IWCH_MEM_ACCESS_LOCAL_WRITE = 1 << 1,
-       IWCH_MEM_ACCESS_REMOTE_READ = 1 << 2,
-       IWCH_MEM_ACCESS_REMOTE_WRITE = 1 << 3,
-       IWCH_MEM_ACCESS_ATOMICS = 1 << 4,
-       IWCH_MEM_ACCESS_BINDING = 1 << 5,
-       IWCH_MEM_ACCESS_LOCAL =
-           (IWCH_MEM_ACCESS_LOCAL_READ | IWCH_MEM_ACCESS_LOCAL_WRITE),
-       IWCH_MEM_ACCESS_REMOTE =
-           (IWCH_MEM_ACCESS_REMOTE_WRITE | IWCH_MEM_ACCESS_REMOTE_READ)
-           /* cannot go beyond 1 << 31 */
-} __attribute__ ((packed));
-
-static inline u32 iwch_convert_access(int acc)
+static inline u32 iwch_ib_to_tpt_access(int acc)
 {
-       return (acc & IB_ACCESS_REMOTE_WRITE ? IWCH_MEM_ACCESS_REMOTE_WRITE : 0)
-           | (acc & IB_ACCESS_REMOTE_READ ? IWCH_MEM_ACCESS_REMOTE_READ : 0) |
-           (acc & IB_ACCESS_LOCAL_WRITE ? IWCH_MEM_ACCESS_LOCAL_WRITE : 0) |
-           (acc & IB_ACCESS_MW_BIND ? IWCH_MEM_ACCESS_BINDING : 0) |
-           IWCH_MEM_ACCESS_LOCAL_READ;
+       return (acc & IB_ACCESS_REMOTE_WRITE ? TPT_REMOTE_WRITE : 0) |
+              (acc & IB_ACCESS_REMOTE_READ ? TPT_REMOTE_READ : 0) |
+              (acc & IB_ACCESS_LOCAL_WRITE ? TPT_LOCAL_WRITE : 0) |
+              TPT_LOCAL_READ;
+}
+
+static inline u32 iwch_ib_to_mwbind_access(int acc)
+{
+       return (acc & IB_ACCESS_REMOTE_WRITE ? T3_MEM_ACCESS_REM_WRITE : 0) |
+              (acc & IB_ACCESS_REMOTE_READ ? T3_MEM_ACCESS_REM_READ : 0) |
+              (acc & IB_ACCESS_LOCAL_WRITE ? T3_MEM_ACCESS_LOCAL_WRITE : 0) |
+              T3_MEM_ACCESS_LOCAL_READ;
 }
 
 enum iwch_mmid_state {
index 9ea00cc4a5f849b516199e88a935194acd669acb..0a472c9b44db1374f3b1111eb605c864b3935412 100644 (file)
@@ -439,7 +439,7 @@ int iwch_bind_mw(struct ib_qp *qp,
        wqe->bind.type = T3_VA_BASED_TO;
 
        /* TBD: check perms */
-       wqe->bind.perms = iwch_convert_access(mw_bind->mw_access_flags);
+       wqe->bind.perms = iwch_ib_to_mwbind_access(mw_bind->mw_access_flags);
        wqe->bind.mr_stag = cpu_to_be32(mw_bind->mr->lkey);
        wqe->bind.mw_stag = cpu_to_be32(mw->rkey);
        wqe->bind.mw_len = cpu_to_be32(mw_bind->length);
index 40404c9e28179558d45feccc83880feb8b4132b5..82ded44c6cee4c40a9bd88460311d1900d60e43c 100644 (file)
@@ -52,6 +52,8 @@ struct ehca_mw;
 struct ehca_pd;
 struct ehca_av;
 
+#include <linux/wait.h>
+
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_user_verbs.h>
 
@@ -153,7 +155,9 @@ struct ehca_cq {
        spinlock_t cb_lock;
        struct hlist_head qp_hashtab[QP_HASHTAB_LEN];
        struct list_head entry;
-       u32 nr_callbacks;
+       u32 nr_callbacks; /* #events assigned to cpu by scaling code */
+       u32 nr_events;    /* #events seen */
+       wait_queue_head_t wait_completion;
        spinlock_t task_lock;
        u32 ownpid;
        /* mmap counter for resources mapped into user space */
index 6ebfa27e4e16edadbe3a44e803a20c264dbb916d..e2cdc1a16fe9214685df23aa2a56dc57ebb8e137 100644 (file)
@@ -146,6 +146,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe,
        spin_lock_init(&my_cq->spinlock);
        spin_lock_init(&my_cq->cb_lock);
        spin_lock_init(&my_cq->task_lock);
+       init_waitqueue_head(&my_cq->wait_completion);
        my_cq->ownpid = current->tgid;
 
        cq = &my_cq->ib_cq;
@@ -302,6 +303,16 @@ create_cq_exit1:
        return cq;
 }
 
+static int get_cq_nr_events(struct ehca_cq *my_cq)
+{
+       int ret;
+       unsigned long flags;
+       spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+       ret = my_cq->nr_events;
+       spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+       return ret;
+}
+
 int ehca_destroy_cq(struct ib_cq *cq)
 {
        u64 h_ret;
@@ -329,10 +340,11 @@ int ehca_destroy_cq(struct ib_cq *cq)
        }
 
        spin_lock_irqsave(&ehca_cq_idr_lock, flags);
-       while (my_cq->nr_callbacks) {
+       while (my_cq->nr_events) {
                spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
-               yield();
+               wait_event(my_cq->wait_completion, !get_cq_nr_events(my_cq));
                spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+               /* recheck nr_events to assure no cqe has just arrived */
        }
 
        idr_remove(&ehca_cq_idr, my_cq->token);
index 3ec53c687d0823c2eb0e7d34409f8684d7bdbe5e..20f36bf8b2b63c7138b72895692b846a6da7aa6d 100644 (file)
@@ -404,10 +404,11 @@ static inline void process_eqe(struct ehca_shca *shca, struct ehca_eqe *eqe)
        u32 token;
        unsigned long flags;
        struct ehca_cq *cq;
+
        eqe_value = eqe->entry;
        ehca_dbg(&shca->ib_device, "eqe_value=%lx", eqe_value);
        if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT, eqe_value)) {
-               ehca_dbg(&shca->ib_device, "... completion event");
+               ehca_dbg(&shca->ib_device, "Got completion event");
                token = EHCA_BMASK_GET(EQE_CQ_TOKEN, eqe_value);
                spin_lock_irqsave(&ehca_cq_idr_lock, flags);
                cq = idr_find(&ehca_cq_idr, token);
@@ -419,16 +420,20 @@ static inline void process_eqe(struct ehca_shca *shca, struct ehca_eqe *eqe)
                        return;
                }
                reset_eq_pending(cq);
-               if (ehca_scaling_code) {
+               cq->nr_events++;
+               spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+               if (ehca_scaling_code)
                        queue_comp_task(cq);
-                       spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
-               } else {
-                       spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+               else {
                        comp_event_callback(cq);
+                       spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+                       cq->nr_events--;
+                       if (!cq->nr_events)
+                               wake_up(&cq->wait_completion);
+                       spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
                }
        } else {
-               ehca_dbg(&shca->ib_device,
-                        "Got non completion event");
+               ehca_dbg(&shca->ib_device, "Got non completion event");
                parse_identifier(shca, eqe_value);
        }
 }
@@ -478,6 +483,7 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
                                         "token=%x", token);
                                continue;
                        }
+                       eqe_cache[eqe_cnt].cq->nr_events++;
                        spin_unlock(&ehca_cq_idr_lock);
                } else
                        eqe_cache[eqe_cnt].cq = NULL;
@@ -504,12 +510,18 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
        /* call completion handler for cached eqes */
        for (i = 0; i < eqe_cnt; i++)
                if (eq->eqe_cache[i].cq) {
-                       if (ehca_scaling_code) {
-                               spin_lock(&ehca_cq_idr_lock);
+                       if (ehca_scaling_code)
                                queue_comp_task(eq->eqe_cache[i].cq);
-                               spin_unlock(&ehca_cq_idr_lock);
-                       } else
-                               comp_event_callback(eq->eqe_cache[i].cq);
+                       else {
+                               struct ehca_cq *cq = eq->eqe_cache[i].cq;
+                               comp_event_callback(cq);
+                               spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+                               cq->nr_events--;
+                               if (!cq->nr_events)
+                                       wake_up(&cq->wait_completion);
+                               spin_unlock_irqrestore(&ehca_cq_idr_lock,
+                                                      flags);
+                       }
                } else {
                        ehca_dbg(&shca->ib_device, "Got non completion event");
                        parse_identifier(shca, eq->eqe_cache[i].eqe->entry);
@@ -523,7 +535,6 @@ void ehca_process_eq(struct ehca_shca *shca, int is_irq)
                if (!eqe)
                        break;
                process_eqe(shca, eqe);
-               eqe_cnt++;
        } while (1);
 
 unlock_irq_spinlock:
@@ -567,8 +578,7 @@ static void __queue_comp_task(struct ehca_cq *__cq,
                list_add_tail(&__cq->entry, &cct->cq_list);
                cct->cq_jobs++;
                wake_up(&cct->wait_queue);
-       }
-       else
+       } else
                __cq->nr_callbacks++;
 
        spin_unlock(&__cq->task_lock);
@@ -577,18 +587,21 @@ static void __queue_comp_task(struct ehca_cq *__cq,
 
 static void queue_comp_task(struct ehca_cq *__cq)
 {
-       int cpu;
        int cpu_id;
        struct ehca_cpu_comp_task *cct;
+       int cq_jobs;
+       unsigned long flags;
 
-       cpu = get_cpu();
        cpu_id = find_next_online_cpu(pool);
        BUG_ON(!cpu_online(cpu_id));
 
        cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id);
        BUG_ON(!cct);
 
-       if (cct->cq_jobs > 0) {
+       spin_lock_irqsave(&cct->task_lock, flags);
+       cq_jobs = cct->cq_jobs;
+       spin_unlock_irqrestore(&cct->task_lock, flags);
+       if (cq_jobs > 0) {
                cpu_id = find_next_online_cpu(pool);
                cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id);
                BUG_ON(!cct);
@@ -608,11 +621,17 @@ static void run_comp_task(struct ehca_cpu_comp_task* cct)
                cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
                spin_unlock_irqrestore(&cct->task_lock, flags);
                comp_event_callback(cq);
-               spin_lock_irqsave(&cct->task_lock, flags);
 
+               spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+               cq->nr_events--;
+               if (!cq->nr_events)
+                       wake_up(&cq->wait_completion);
+               spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+
+               spin_lock_irqsave(&cct->task_lock, flags);
                spin_lock(&cq->task_lock);
                cq->nr_callbacks--;
-               if (cq->nr_callbacks == 0) {
+               if (!cq->nr_callbacks) {
                        list_del_init(cct->cq_list.next);
                        cct->cq_jobs--;
                }
index c1835121a82223612195fce09369ba0b58173e4a..059da9628bb56c3e103d81976dfeb0a3ce71079d 100644 (file)
@@ -52,7 +52,7 @@
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
 MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
-MODULE_VERSION("SVNEHCA_0021");
+MODULE_VERSION("SVNEHCA_0022");
 
 int ehca_open_aqp1     = 0;
 int ehca_debug_level   = 0;
@@ -810,7 +810,7 @@ int __init ehca_module_init(void)
        int ret;
 
        printk(KERN_INFO "eHCA Infiniband Device Driver "
-              "(Rel.: SVNEHCA_0021)\n");
+              "(Rel.: SVNEHCA_0022)\n");
        idr_init(&ehca_qp_idr);
        idr_init(&ehca_cq_idr);
        spin_lock_init(&ehca_qp_idr_lock);
index 71dc84bd425498cd968a33cfa6e005804861474f..1c6b63aca26846c04537ba92eea18af88ec7f058 100644 (file)
@@ -1088,21 +1088,21 @@ static void mthca_unmap_memfree(struct mthca_dev *dev,
 static int mthca_alloc_memfree(struct mthca_dev *dev,
                               struct mthca_qp *qp)
 {
-       int ret = 0;
-
        if (mthca_is_memfree(dev)) {
                qp->rq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_RQ,
                                                 qp->qpn, &qp->rq.db);
                if (qp->rq.db_index < 0)
-                       return ret;
+                       return -ENOMEM;
 
                qp->sq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_SQ,
                                                 qp->qpn, &qp->sq.db);
-               if (qp->sq.db_index < 0)
+               if (qp->sq.db_index < 0) {
                        mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
+                       return -ENOMEM;
+               }
        }
 
-       return ret;
+       return 0;
 }
 
 static void mthca_free_memfree(struct mthca_dev *dev,
index bb2e3d5eee20a8bb9fe502ae2dfb97112d0b97c3..56c87a81bb675d82a5c40c0c7f05d68ba9b80aaf 100644 (file)
@@ -407,6 +407,10 @@ static int ipoib_mcast_join_complete(int status,
                        queue_delayed_work(ipoib_workqueue,
                                           &priv->mcast_task, 0);
                mutex_unlock(&mcast_mutex);
+
+               if (mcast == priv->broadcast)
+                       netif_carrier_on(dev);
+
                return 0;
        }
 
@@ -594,7 +598,6 @@ void ipoib_mcast_join_task(struct work_struct *work)
        ipoib_dbg_mcast(priv, "successfully joined all multicast groups\n");
 
        clear_bit(IPOIB_MCAST_RUN, &priv->flags);
-       netif_carrier_on(dev);
 }
 
 int ipoib_mcast_start_thread(struct net_device *dev)
index 3cb551b8875625960654e587facebf02e3fcd838..7f3ec205e35f54980b2c00adc9aaac4538fd462c 100644 (file)
@@ -259,12 +259,13 @@ void ipoib_event(struct ib_event_handler *handler,
        struct ipoib_dev_priv *priv =
                container_of(handler, struct ipoib_dev_priv, event_handler);
 
-       if (record->event == IB_EVENT_PORT_ERR    ||
-           record->event == IB_EVENT_PKEY_CHANGE ||
-           record->event == IB_EVENT_PORT_ACTIVE ||
-           record->event == IB_EVENT_LID_CHANGE  ||
-           record->event == IB_EVENT_SM_CHANGE   ||
-           record->event == IB_EVENT_CLIENT_REREGISTER) {
+       if ((record->event == IB_EVENT_PORT_ERR    ||
+            record->event == IB_EVENT_PKEY_CHANGE ||
+            record->event == IB_EVENT_PORT_ACTIVE ||
+            record->event == IB_EVENT_LID_CHANGE  ||
+            record->event == IB_EVENT_SM_CHANGE   ||
+            record->event == IB_EVENT_CLIENT_REREGISTER) &&
+           record->element.port_num == priv->port) {
                ipoib_dbg(priv, "Port state change event\n");
                queue_work(ipoib_workqueue, &priv->flush_task);
        }
index 295e931c0dfbc9c3442e8d7d25bad333a982d021..4b232124a1abb0dea3b9e737062250e3988b968c 100644 (file)
@@ -211,7 +211,7 @@ static struct workqueue_struct *led_workqueue;
                                     enum led_brightness value);        \
        static void object##_led_update(struct work_struct *ignored);   \
        static int object##_led_wk;                                     \
-       DECLARE_WORK(object##_led_work, object##_led_update);           \
+       static DECLARE_WORK(object##_led_work, object##_led_update);    \
        static struct led_classdev object##_led = {                     \
                .name           = "asus:" ledname,                      \
                .brightness_set = object##_led_set,                     \
index 2ebe240dd53761f236007f0dd17fc46a09db26ad..ac708bc2f9f3ce3bf158c74cf376072d7ac8726b 100644 (file)
@@ -453,7 +453,7 @@ static int sony_acpi_resume(struct acpi_device *device)
 static int sony_acpi_add(struct acpi_device *device)
 {
        acpi_status status;
-       int result;
+       int result = 0;
        acpi_handle handle;
 
        sony_acpi_acpi_device = device;
index e3acd398fb37910c539dfb22fb0a8921748522ff..1f6445840461a844b51b869473001171105ba8d3 100644 (file)
@@ -359,6 +359,8 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
                cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
                cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
                cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
+               cfi->chips[i].ref_point_counter = 0;
+               init_waitqueue_head(&(cfi->chips[i].wq));
        }
 
        map->fldrv = &cfi_amdstd_chipdrv;
index 69d49e0250a9a3a532ff95f9ac7ce261862e314d..b344ff858b2d7a6c220216050b6124b99e603e2f 100644 (file)
@@ -158,6 +158,8 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
                cfi->chips[i].word_write_time = 128;
                cfi->chips[i].buffer_write_time = 128;
                cfi->chips[i].erase_time = 1024;
+               cfi->chips[i].ref_point_counter = 0;
+               init_waitqueue_head(&(cfi->chips[i].wq));
        }
 
        return cfi_staa_setup(map);
index b1104fe1f20723a4dfaca7400efc6d0e85bdab0b..1c3b34ad732511f56c5138a0ac92d9fad2b95263 100644 (file)
@@ -402,8 +402,8 @@ static int __init init_dnpc(void)
                        ++higlvl_partition_info[i].name;
        }
 
-       printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n",
-               is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys);
+       printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%llx\n",
+               is_dnp ? "DNPC" : "ADNP", dnpc_map.size, (unsigned long long)dnpc_map.phys);
 
        dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size);
 
index 0bc013fd66a3f08570be112bca66454bff67da9b..aa64a475278134eb3eafea4bb5cb7db40459b8da 100644 (file)
@@ -30,7 +30,7 @@
 
 #define ROM_PROBE_STEP_SIZE (64*1024) /* 64KiB */
 
-#define BIOS_CNTL      0xDC
+#define BIOS_CNTL              0xDC
 #define BIOS_LOCK_ENABLE       0x02
 #define BIOS_WRITE_ENABLE      0x01
 
@@ -145,7 +145,7 @@ static void esb2rom_cleanup(struct esb2rom_window *window)
 }
 
 static int __devinit esb2rom_init_one(struct pci_dev *pdev,
-                               const struct pci_device_id *ent)
+                                     const struct pci_device_id *ent)
 {
        static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
        struct esb2rom_window *window = &esb2rom_window;
@@ -185,7 +185,7 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev,
        /* Find a region continuous to the end of the ROM window  */
        window->phys = 0;
        pci_read_config_word(pdev, FWH_DEC_EN1, &word);
-       printk(KERN_DEBUG "pci_read_config_byte : %x\n", word);
+       printk(KERN_DEBUG "pci_read_config_word : %x\n", word);
 
        if ((word & FWH_8MiB) == FWH_8MiB)
                window->phys = 0xff400000;
@@ -212,6 +212,11 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev,
        else if ((word & FWH_0_5MiB) == FWH_0_5MiB)
                window->phys = 0xfff80000;
 
+       if (window->phys == 0) {
+               printk(KERN_ERR MOD_NAME ": Rom window is closed\n");
+               goto out;
+       }
+
        /* reserved  0x0020 and 0x0010 */
        window->phys -= 0x400000UL;
        window->size = (0xffffffffUL - window->phys) + 1UL;
index 880580c44e0134186d9a3df3fd1b81731359aa2b..41844ea02462486a3e3b4eedb978debbc6f7eb62 100644 (file)
@@ -727,6 +727,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],       /* subdevices to c
        concat->mtd.erasesize = subdev[0]->erasesize;
        concat->mtd.writesize = subdev[0]->writesize;
        concat->mtd.oobsize = subdev[0]->oobsize;
+       concat->mtd.oobavail = subdev[0]->oobavail;
        if (subdev[0]->writev)
                concat->mtd.writev = concat_writev;
        if (subdev[0]->read_oob)
index 633def3fb0875daf3a38bda7dea4cfb5d8adee77..1af989023c6644ca89c8e4107c21fcde8137904d 100644 (file)
@@ -200,6 +200,11 @@ static int part_erase (struct mtd_info *mtd, struct erase_info *instr)
                return -EINVAL;
        instr->addr += part->offset;
        ret = part->master->erase(part->master, instr);
+       if (ret) {
+               if (instr->fail_addr != 0xffffffff)
+                       instr->fail_addr -= part->offset;
+               instr->addr -= part->offset;
+       }
        return ret;
 }
 
@@ -338,6 +343,7 @@ int add_mtd_partitions(struct mtd_info *master,
                slave->mtd.size = parts[i].size;
                slave->mtd.writesize = master->writesize;
                slave->mtd.oobsize = master->oobsize;
+               slave->mtd.oobavail = master->oobavail;
                slave->mtd.subpage_sft = master->subpage_sft;
 
                slave->mtd.name = parts[i].name;
@@ -559,4 +565,3 @@ EXPORT_SYMBOL_GPL(deregister_mtd_parser);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
 MODULE_DESCRIPTION("Generic support for partitioning of MTD devices");
-
index 12608c13cce5b2365c3aaf5e77f2481ec9bef241..595208f965a55cdd31f5359cd704d283785a3d34 100644 (file)
@@ -114,7 +114,7 @@ module_param(no_autopart, int, 0);
 static int show_firmware_partition = 0;
 module_param(show_firmware_partition, int, 0);
 
-#ifdef MTD_NAND_DISKONCHIP_BBTWRITE
+#ifdef CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE
 static int inftl_bbt_write = 1;
 #else
 static int inftl_bbt_write = 0;
index acaf97bc80d18f89696987db2c0370fd8cac0b76..6af37b8cff65a039d7216203e2b5b9b7750d2bf1 100644 (file)
@@ -2524,6 +2524,7 @@ int nand_scan_tail(struct mtd_info *mtd)
        for (i = 0; chip->ecc.layout->oobfree[i].length; i++)
                chip->ecc.layout->oobavail +=
                        chip->ecc.layout->oobfree[i].length;
+       mtd->oobavail = chip->ecc.layout->oobavail;
 
        /*
         * Set the number of read / write steps for one page depending on ECC
index 7f1cb6e5dccb5b8463554cbf48e5227b66b1597d..9e14a26ca4e82ba07b4b328811f2f5f661eb1a60 100644 (file)
@@ -4,6 +4,11 @@
  *  Copyright (C) 2005-2007 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
+ *  Credits:
+ *     Adrian Hunter <ext-adrian.hunter@nokia.com>:
+ *     auto-placement support, read-while load support, various fixes
+ *     Copyright (C) Nokia Corporation, 2007
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
@@ -831,7 +836,7 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
        int readcol = column;
        int readend = column + thislen;
        int lastgap = 0;
-       uint8_t *oob_buf = this->page_buf + mtd->writesize;
+       uint8_t *oob_buf = this->oob_buf;
 
        for (free = this->ecclayout->oobfree; free->length; ++free) {
                if (readcol >= lastgap)
@@ -849,7 +854,8 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf, int col
                        int n = ed - st;
                        memcpy(buf, oob_buf + st, n);
                        buf += n;
-               }
+               } else
+                       break;
        }
        return 0;
 }
@@ -947,9 +953,9 @@ static int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
 
 /**
  * onenand_read_oob - [MTD Interface] NAND write data and/or out-of-band
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob operation description structure
+ * @param mtd:         MTD device structure
+ * @param from:                offset to read from
+ * @param ops:         oob operation description structure
  */
 static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
                            struct mtd_oob_ops *ops)
@@ -1017,7 +1023,7 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state)
  * onenand_bbt_read_oob - [MTD Interface] OneNAND read out-of-band for bbt scan
  * @param mtd          MTD device structure
  * @param from         offset to read from
- * @param @ops         oob operation description structure
+ * @param ops          oob operation description structure
  *
  * OneNAND read out-of-band data from the spare area for bbt scan
  */
@@ -1093,7 +1099,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
 static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
 {
        struct onenand_chip *this = mtd->priv;
-       char *readp = this->page_buf + mtd->writesize;
+       char oobbuf[64];
        int status, i;
 
        this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize);
@@ -1102,9 +1108,9 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to
        if (status)
                return status;
 
-       this->read_bufferram(mtd, ONENAND_SPARERAM, readp, 0, mtd->oobsize);
-       for(i = 0; i < mtd->oobsize; i++)
-               if (buf[i] != 0xFF && buf[i] != readp[i])
+       this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
+       for (i = 0; i < mtd->oobsize; i++)
+               if (buf[i] != 0xFF && buf[i] != oobbuf[i])
                        return -EBADMSG;
 
        return 0;
@@ -1290,7 +1296,8 @@ static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,
                        int n = ed - st;
                        memcpy(oob_buf + st, buf, n);
                        buf += n;
-               }
+               } else
+                       break;
        }
        return 0;
 }
@@ -1312,6 +1319,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
        struct onenand_chip *this = mtd->priv;
        int column, ret = 0, oobsize;
        int written = 0;
+       u_char *oobbuf;
 
        DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
 
@@ -1331,7 +1339,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
        }
 
        /* For compatibility with NAND: Do not allow write past end of page */
-       if (column + len > oobsize) {
+       if (unlikely(column + len > oobsize)) {
                printk(KERN_ERR "onenand_write_oob: "
                      "Attempt to write past end of page\n");
                return -EINVAL;
@@ -1348,6 +1356,8 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
        /* Grab the lock and see if the device is available */
        onenand_get_device(mtd, FL_WRITING);
 
+       oobbuf = this->oob_buf;
+
        /* Loop until all data write */
        while (written < len) {
                int thislen = min_t(int, oobsize, len - written);
@@ -1358,12 +1368,12 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
 
                /* We send data to spare ram with oobsize
                 * to prevent byte access */
-               memset(this->page_buf, 0xff, mtd->oobsize);
+               memset(oobbuf, 0xff, mtd->oobsize);
                if (mode == MTD_OOB_AUTO)
-                       onenand_fill_auto_oob(mtd, this->page_buf, buf, column, thislen);
+                       onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen);
                else
-                       memcpy(this->page_buf + column, buf, thislen);
-               this->write_bufferram(mtd, ONENAND_SPARERAM, this->page_buf, 0, mtd->oobsize);
+                       memcpy(oobbuf + column, buf, thislen);
+               this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
 
                this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
 
@@ -1375,7 +1385,7 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
                        break;
                }
 
-               ret = onenand_verify_oob(mtd, this->page_buf, to);
+               ret = onenand_verify_oob(mtd, oobbuf, to);
                if (ret) {
                        printk(KERN_ERR "onenand_write_oob: verify failed %d\n", ret);
                        break;
@@ -1400,9 +1410,9 @@ static int onenand_do_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
 
 /**
  * onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band
- * @mtd:       MTD device structure
- * @from:      offset to read from
- * @ops:       oob operation description structure
+ * @param mtd:         MTD device structure
+ * @param to:          offset to write
+ * @param ops:         oob operation description structure
  */
 static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
                             struct mtd_oob_ops *ops)
@@ -1616,6 +1626,7 @@ static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
  * @param mtd          MTD device structure
  * @param ofs          offset relative to mtd start
  * @param len          number of bytes to lock or unlock
+ * @param cmd          lock or unlock command
  *
  * Lock or unlock one or more blocks
  */
@@ -2117,10 +2128,11 @@ static void onenand_check_features(struct mtd_info *mtd)
 }
 
 /**
- * onenand_print_device_info - Print device ID
+ * onenand_print_device_info - Print device & version ID
  * @param device        device ID
+ * @param version      version ID
  *
- * Print device ID
+ * Print device & version ID
  */
 static void onenand_print_device_info(int device, int version)
 {
@@ -2320,15 +2332,25 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 
        /* Allocate buffers, if necessary */
        if (!this->page_buf) {
-               size_t len;
-               len = mtd->writesize + mtd->oobsize;
-               this->page_buf = kmalloc(len, GFP_KERNEL);
+               this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
                if (!this->page_buf) {
                        printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
                        return -ENOMEM;
                }
                this->options |= ONENAND_PAGEBUF_ALLOC;
        }
+       if (!this->oob_buf) {
+               this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
+               if (!this->oob_buf) {
+                       printk(KERN_ERR "onenand_scan(): Can't allocate oob_buf\n");
+                       if (this->options & ONENAND_PAGEBUF_ALLOC) {
+                               this->options &= ~ONENAND_PAGEBUF_ALLOC;
+                               kfree(this->page_buf);
+                       }
+                       return -ENOMEM;
+               }
+               this->options |= ONENAND_OOBBUF_ALLOC;
+       }
 
        this->state = FL_READY;
        init_waitqueue_head(&this->wq);
@@ -2367,6 +2389,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
        for (i = 0; this->ecclayout->oobfree[i].length; i++)
                this->ecclayout->oobavail +=
                        this->ecclayout->oobfree[i].length;
+       mtd->oobavail = this->ecclayout->oobavail;
 
        mtd->ecclayout = this->ecclayout;
 
@@ -2424,9 +2447,11 @@ void onenand_release(struct mtd_info *mtd)
                kfree(bbm->bbt);
                kfree(this->bbm);
        }
-       /* Buffer allocated by onenand_scan */
+       /* Buffers allocated by onenand_scan */
        if (this->options & ONENAND_PAGEBUF_ALLOC)
                kfree(this->page_buf);
+       if (this->options & ONENAND_OOBBUF_ALLOC)
+               kfree(this->oob_buf);
 }
 
 EXPORT_SYMBOL_GPL(onenand_scan);
index 72995777f8092747536aad01eae20da766ddd07a..b406ecfa7268910d9c6c124bbf08b2e124c0df5a 100644 (file)
@@ -858,19 +858,7 @@ static struct eisa_device_id vortex_eisa_ids[] = {
 };
 MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids);
 
-static int vortex_eisa_probe(struct device *device);
-static int vortex_eisa_remove(struct device *device);
-
-static struct eisa_driver vortex_eisa_driver = {
-       .id_table = vortex_eisa_ids,
-       .driver   = {
-               .name    = "3c59x",
-               .probe   = vortex_eisa_probe,
-               .remove  = vortex_eisa_remove
-       }
-};
-
-static int vortex_eisa_probe(struct device *device)
+static int __init vortex_eisa_probe(struct device *device)
 {
        void __iomem *ioaddr;
        struct eisa_device *edev;
@@ -893,7 +881,7 @@ static int vortex_eisa_probe(struct device *device)
        return 0;
 }
 
-static int vortex_eisa_remove(struct device *device)
+static int __devexit vortex_eisa_remove(struct device *device)
 {
        struct eisa_device *edev;
        struct net_device *dev;
@@ -918,7 +906,17 @@ static int vortex_eisa_remove(struct device *device)
        free_netdev(dev);
        return 0;
 }
-#endif
+
+static struct eisa_driver vortex_eisa_driver = {
+       .id_table = vortex_eisa_ids,
+       .driver   = {
+               .name    = "3c59x",
+               .probe   = vortex_eisa_probe,
+               .remove  = __devexit_p(vortex_eisa_remove)
+       }
+};
+
+#endif /* CONFIG_EISA */
 
 /* returns count found (>= 0), or negative on error */
 static int __init vortex_eisa_init(void)
index 9ba21e0f27c5150f0d923e6806661f1542fc2233..1ee27c360a4b845f0631824d9ea585729aa70bf4 100644 (file)
@@ -787,6 +787,12 @@ static int mv643xx_eth_open(struct net_device *dev)
        unsigned int size;
        int err;
 
+       /* Clear any pending ethernet port interrupts */
+       mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
+       mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
+       /* wait for previous write to complete */
+       mv_read (MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num));
+
        err = request_irq(dev->irq, mv643xx_eth_int_handler,
                        IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev);
        if (err) {
@@ -875,10 +881,6 @@ static int mv643xx_eth_open(struct net_device *dev)
 
        mv643xx_eth_rx_refill_descs(dev);       /* Fill RX ring with skb's */
 
-       /* Clear any pending ethernet port interrupts */
-       mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
-       mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
-
        eth_port_start(dev);
 
        /* Interrupt Coalescing */
index b05dc6ed7fb750a4186acc4bb547e1a13b7121f8..ac02b3b60f926e40f175aed8c1f2ac27adc090f4 100644 (file)
@@ -181,6 +181,7 @@ struct myri10ge_priv {
        int intr_coal_delay;
        __be32 __iomem *intr_coal_delay_ptr;
        int mtrr;
+       int wc_enabled;
        int wake_queue;
        int stop_queue;
        int down_cnt;
@@ -717,6 +718,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
        int status;
        size_t bytes;
        u32 len;
+       struct page *dmatest_page;
+       dma_addr_t dmatest_bus;
 
        /* try to send a reset command to the card to see if it
         * is alive */
@@ -726,6 +729,11 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
                dev_err(&mgp->pdev->dev, "failed reset\n");
                return -ENXIO;
        }
+       dmatest_page = alloc_page(GFP_KERNEL);
+       if (!dmatest_page)
+               return -ENOMEM;
+       dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
+                                  DMA_BIDIRECTIONAL);
 
        /* Now exchange information about interrupts  */
 
@@ -764,8 +772,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
 
        len = mgp->tx.boundary;
 
-       cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
-       cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+       cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+       cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
        cmd.data2 = len * 0x10000;
        status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
        if (status == 0)
@@ -774,8 +782,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
        else
                dev_warn(&mgp->pdev->dev, "DMA read benchmark failed: %d\n",
                         status);
-       cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
-       cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+       cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+       cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
        cmd.data2 = len * 0x1;
        status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
        if (status == 0)
@@ -785,8 +793,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
                dev_warn(&mgp->pdev->dev, "DMA write benchmark failed: %d\n",
                         status);
 
-       cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
-       cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+       cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+       cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
        cmd.data2 = len * 0x10001;
        status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
        if (status == 0)
@@ -796,6 +804,9 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
                dev_warn(&mgp->pdev->dev,
                         "DMA read/write benchmark failed: %d\n", status);
 
+       pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
+       put_page(dmatest_page);
+
        memset(mgp->rx_done.entry, 0, bytes);
 
        /* reset mcp/driver shared state back to 0 */
@@ -1375,7 +1386,7 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
                data[i] = ((unsigned long *)&mgp->stats)[i];
 
        data[i++] = (unsigned int)mgp->tx.boundary;
-       data[i++] = (unsigned int)(mgp->mtrr >= 0);
+       data[i++] = (unsigned int)mgp->wc_enabled;
        data[i++] = (unsigned int)mgp->pdev->irq;
        data[i++] = (unsigned int)mgp->msi_enabled;
        data[i++] = (unsigned int)mgp->read_dma;
@@ -1456,6 +1467,8 @@ static int myri10ge_allocate_rings(struct net_device *dev)
        status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd, 0);
        tx_ring_size = cmd.data0;
        status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0);
+       if (status != 0)
+               return status;
        rx_ring_size = cmd.data0;
 
        tx_ring_entries = tx_ring_size / sizeof(struct mcp_kreq_ether_send);
@@ -1463,6 +1476,8 @@ static int myri10ge_allocate_rings(struct net_device *dev)
        mgp->tx.mask = tx_ring_entries - 1;
        mgp->rx_small.mask = mgp->rx_big.mask = rx_ring_entries - 1;
 
+       status = -ENOMEM;
+
        /* allocate the host shadow rings */
 
        bytes = 8 + (MYRI10GE_MAX_SEND_DESC_TSO + 4)
@@ -1735,7 +1750,7 @@ static int myri10ge_open(struct net_device *dev)
                goto abort_with_irq;
        }
 
-       if (myri10ge_wcfifo && mgp->mtrr >= 0) {
+       if (myri10ge_wcfifo && mgp->wc_enabled) {
                mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4;
                mgp->rx_small.wc_fifo =
                    (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL;
@@ -2510,6 +2525,12 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
                                 bridge->vendor, bridge->device);
                        mgp->tx.boundary = 4096;
                        mgp->fw_name = myri10ge_fw_aligned;
+               } else if (bridge &&
+                          bridge->vendor == PCI_VENDOR_ID_SGI &&
+                          bridge->device == 0x4002 /* TIOCE pcie-port */ ) {
+                       /* this pcie bridge does not support 4K rdma request */
+                       mgp->tx.boundary = 2048;
+                       mgp->fw_name = myri10ge_fw_aligned;
                }
        } else {
                if (myri10ge_force_firmware == 1) {
@@ -2830,9 +2851,12 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        mgp->board_span = pci_resource_len(pdev, 0);
        mgp->iomem_base = pci_resource_start(pdev, 0);
        mgp->mtrr = -1;
+       mgp->wc_enabled = 0;
 #ifdef CONFIG_MTRR
        mgp->mtrr = mtrr_add(mgp->iomem_base, mgp->board_span,
                             MTRR_TYPE_WRCOMB, 1);
+       if (mgp->mtrr >= 0)
+               mgp->wc_enabled = 1;
 #endif
        /* Hack.  need to get rid of these magic numbers */
        mgp->sram_size =
@@ -2927,7 +2951,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n",
                 (mgp->msi_enabled ? "MSI" : "xPIC"),
                 netdev->irq, mgp->tx.boundary, mgp->fw_name,
-                (mgp->mtrr >= 0 ? "Enabled" : "Disabled"));
+                (mgp->wc_enabled ? "Enabled" : "Disabled"));
 
        return 0;
 
index a2877f33fa85d9f2bb5076d759e179ee0d89c7f7..1be55702557dc33e914fe8673a4b39f6827e0cdc 100644 (file)
@@ -228,7 +228,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
                            &adapter->ctx_desc_pdev);
 
        printk("ctx_desc_phys_addr: 0x%llx\n",
-              (u64) adapter->ctx_desc_phys_addr);
+              (unsigned long long) adapter->ctx_desc_phys_addr);
        if (addr == NULL) {
                DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
                err = -ENOMEM;
@@ -247,7 +247,8 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
                            adapter->max_tx_desc_count,
                            (dma_addr_t *) & hw->cmd_desc_phys_addr,
                            &adapter->ahw.cmd_desc_pdev);
-       printk("cmd_desc_phys_addr: 0x%llx\n", (u64) hw->cmd_desc_phys_addr);
+       printk("cmd_desc_phys_addr: 0x%llx\n",
+              (unsigned long long) hw->cmd_desc_phys_addr);
 
        if (addr == NULL) {
                DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
index 15d954e50cae6e816b534bf959c49a2920bef808..521b5f0618a4a904a4d736d2263a6573eb9dbd5e 100644 (file)
@@ -572,8 +572,8 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr)
 {
        unsigned int val;
 
-       mdio_write(ioaddr, MII_BMCR, BMCR_RESET);
-       val = mdio_read(ioaddr, MII_BMCR);
+       val = mdio_read(ioaddr, MII_BMCR) | BMCR_RESET;
+       mdio_write(ioaddr, MII_BMCR, val & 0xffff);
 }
 
 static void rtl8169_check_link_status(struct net_device *dev,
@@ -1368,11 +1368,7 @@ static inline void rtl8169_request_timer(struct net_device *dev)
            (tp->phy_version >= RTL_GIGA_PHY_VER_H))
                return;
 
-       init_timer(timer);
-       timer->expires = jiffies + RTL8169_PHY_TIMEOUT;
-       timer->data = (unsigned long)(dev);
-       timer->function = rtl8169_phy_timer;
-       add_timer(timer);
+       mod_timer(timer, jiffies + RTL8169_PHY_TIMEOUT);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1685,6 +1681,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        tp->mmio_addr = ioaddr;
        tp->align = rtl_cfg_info[ent->driver_data].align;
 
+       init_timer(&tp->timer);
+       tp->timer.data = (unsigned long) dev;
+       tp->timer.function = rtl8169_phy_timer;
+
        spin_lock_init(&tp->lock);
 
        rc = register_netdev(dev);
index 53839979cfb8fb1249dc27161b4cab2649fb994c..ab0ab92583fe427a0568cbb87c5571b918909998 100644 (file)
@@ -2165,9 +2165,27 @@ force_update:
                        /* fall through */
 #endif
                case OP_RXCHKS:
-                       skb = sky2->rx_ring[sky2->rx_next].skb;
-                       skb->ip_summed = CHECKSUM_COMPLETE;
-                       skb->csum = status & 0xffff;
+                       if (!sky2->rx_csum)
+                               break;
+
+                       /* Both checksum counters are programmed to start at
+                        * the same offset, so unless there is a problem they
+                        * should match. This failure is an early indication that
+                        * hardware receive checksumming won't work.
+                        */
+                       if (likely(status >> 16 == (status & 0xffff))) {
+                               skb = sky2->rx_ring[sky2->rx_next].skb;
+                               skb->ip_summed = CHECKSUM_COMPLETE;
+                               skb->csum = status & 0xffff;
+                       } else {
+                               printk(KERN_NOTICE PFX "%s: hardware receive "
+                                      "checksum problem (status = %#x)\n",
+                                      dev->name, status);
+                               sky2->rx_csum = 0;
+                               sky2_write32(sky2->hw,
+                                            Q_ADDR(rxqaddr[le->link], Q_CSR),
+                                            BMU_DIS_RX_CHKSUM);
+                       }
                        break;
 
                case OP_TXINDEXLE:
index 0d97e10ccac580e16d3dffbe4a9a88144360e64a..36202e94ee916330bb8a8ee32e712f70e2f897cb 100644 (file)
@@ -186,7 +186,6 @@ static char __devinit *adapter_def(char type)
 #define TRC_INITV 0x02         /*  verbose init trace points     */
 static unsigned char ibmtr_debug_trace = 0;
 
-static int     ibmtr_probe(struct net_device *dev);
 static int     ibmtr_probe1(struct net_device *dev, int ioaddr);
 static unsigned char get_sram_size(struct tok_info *adapt_info);
 static int     trdev_init(struct net_device *dev);
@@ -335,17 +334,6 @@ static void ibmtr_cleanup_card(struct net_device *dev)
 #endif         
 }
 
-int ibmtr_probe_card(struct net_device *dev)
-{
-       int err = ibmtr_probe(dev);
-       if (!err) {
-               err = register_netdev(dev);
-               if (err)
-                       ibmtr_cleanup_card(dev);
-       }
-       return err;
-}
-
 /****************************************************************************
  *     ibmtr_probe():  Routine specified in the network device structure
  *     to probe for an IBM Token Ring Adapter.  Routine outline:
@@ -358,7 +346,7 @@ int ibmtr_probe_card(struct net_device *dev)
  *     which references it.
  ****************************************************************************/
 
-static int ibmtr_probe(struct net_device *dev)
+static int __init ibmtr_probe(struct net_device *dev)
 {
        int i;
        int base_addr = dev->base_addr;
@@ -378,6 +366,17 @@ static int ibmtr_probe(struct net_device *dev)
        return -ENODEV;
 }
 
+int __init ibmtr_probe_card(struct net_device *dev)
+{
+       int err = ibmtr_probe(dev);
+       if (!err) {
+               err = register_netdev(dev);
+               if (err)
+                       ibmtr_cleanup_card(dev);
+       }
+       return err;
+}
+
 /*****************************************************************************/
 
 static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
index ebbda1d8f542539891087086855107a829e6e759..f3a972e74e9ada2983afd620b13fe29ccec6b880 100644 (file)
@@ -30,8 +30,8 @@
 */
 
 #define DRV_NAME       "via-rhine"
-#define DRV_VERSION    "1.4.2"
-#define DRV_RELDATE    "Sept-11-2006"
+#define DRV_VERSION    "1.4.3"
+#define DRV_RELDATE    "2007-03-06"
 
 
 /* A few user-configurable values.
@@ -105,6 +105,7 @@ static const int multicast_filter_limit = 32;
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
+#include <linux/dmi.h>
 
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
@@ -1995,6 +1996,23 @@ static struct pci_driver rhine_driver = {
        .shutdown =     rhine_shutdown,
 };
 
+static struct dmi_system_id __initdata rhine_dmi_table[] = {
+       {
+               .ident = "EPIA-M",
+               .matches = {
+                       DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
+                       DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+               },
+       },
+       {
+               .ident = "KV7",
+               .matches = {
+                       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+               },
+       },
+       { NULL }
+};
 
 static int __init rhine_init(void)
 {
@@ -2002,6 +2020,16 @@ static int __init rhine_init(void)
 #ifdef MODULE
        printk(version);
 #endif
+       if (dmi_check_system(rhine_dmi_table)) {
+               /* these BIOSes fail at PXE boot if chip is in D3 */
+               avoid_D3 = 1;
+               printk(KERN_WARNING "%s: Broken BIOS detected, avoid_D3 "
+                                   "enabled.\n",
+                      DRV_NAME);
+       }
+       else if (avoid_D3)
+               printk(KERN_INFO "%s: avoid_D3 set.\n", DRV_NAME);
+
        return pci_register_driver(&rhine_driver);
 }
 
index 8dbcf83bb5f360a96d4b2b1320489e7af78eb5e7..8b4540bfc1b0b3b7949b86ae5cd6de58ab043b2f 100644 (file)
@@ -407,7 +407,7 @@ static void z8530_tx(struct z8530_channel *c)
        while(c->txcount) {
                /* FIFO full ? */
                if(!(read_zsreg(c, R0)&4))
-                       break;
+                       return;
                c->txcount--;
                /*
                 *      Shovel out the byte
index e594af46ff055f2f59bca4555f64ea0321f3ef17..80cb88eb98c61d4dbbff27ecebaf48cb1e81c529 100644 (file)
@@ -1858,9 +1858,6 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id)
 
        spin_lock(&bcm->irq_lock);
 
-       assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
-       assert(bcm->current_core->id == BCM43xx_COREID_80211);
-
        reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
        if (reason == 0xffffffff) {
                /* irq not for us (shared irq) */
@@ -1871,6 +1868,9 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id)
        if (!reason)
                goto out;
 
+       assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
+       assert(bcm->current_core->id == BCM43xx_COREID_80211);
+
        bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
                             & 0x0001DC00;
        bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
index 3a5c9c2b2150aa4f9aba99ba40a29a24f01f8ca7..cae89258a64071df728c8f0f1878ad92348f593d 100644 (file)
@@ -859,6 +859,11 @@ static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
                bcm43xx_radio_write16(bcm, 0x005D, 0x0088);
                bcm43xx_radio_write16(bcm, 0x005E, 0x0088);
                bcm43xx_radio_write16(bcm, 0x007D, 0x0088);
+               bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
+                                   BCM43xx_UCODEFLAGS_OFFSET,
+                                   (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
+                                   BCM43xx_UCODEFLAGS_OFFSET)
+                                   | 0x00000200));
        }
        if (radio->revision == 8) {
                bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
@@ -941,7 +946,8 @@ static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
        bcm43xx_phy_write(bcm, 0x0038, 0x0668);
        bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
        if (radio->revision <= 5)
-               bcm43xx_phy_write(bcm, 0x005D, bcm43xx_phy_read(bcm, 0x005D) | 0x0003);
+               bcm43xx_phy_write(bcm, 0x005D, (bcm43xx_phy_read(bcm, 0x005D)
+                                 & 0xFF80) | 0x0003);
        if (radio->revision <= 2)
                bcm43xx_radio_write16(bcm, 0x005D, 0x000D);
        
@@ -958,7 +964,7 @@ static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
                bcm43xx_phy_write(bcm, 0x0016, 0x0410);
                bcm43xx_phy_write(bcm, 0x0017, 0x0820);
                bcm43xx_phy_write(bcm, 0x0062, 0x0007);
-               (void) bcm43xx_radio_calibrationvalue(bcm);
+               bcm43xx_radio_init2050(bcm);
                bcm43xx_phy_lo_g_measure(bcm);
                if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
                        bcm43xx_calc_nrssi_slope(bcm);
index 7b665e2386a8caaa888b355e80e58510d7e3a201..d6d9413d7f23cdd662eadf09cc675dd667b2fda1 100644 (file)
@@ -105,18 +105,24 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev,
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
        unsigned long flags;
        u8 channel;
+       s8 expon;
        int freq;
        int err = -EINVAL;
 
        mutex_lock(&bcm->mutex);
        spin_lock_irqsave(&bcm->irq_lock, flags);
 
-       if ((data->freq.m >= 0) && (data->freq.m <= 1000)) {
+       if ((data->freq.e == 0) &&
+           (data->freq.m >= 0) && (data->freq.m <= 1000)) {
                channel = data->freq.m;
                freq = bcm43xx_channel_to_freq(bcm, channel);
        } else {
-               channel = bcm43xx_freq_to_channel(bcm, data->freq.m);
                freq = data->freq.m;
+               expon = 6 - data->freq.e;
+               while (--expon >= 0)    /* scale down the frequency to MHz */
+                       freq /= 10;
+               assert(freq > 1000);
+               channel = bcm43xx_freq_to_channel(bcm, freq);
        }
        if (!ieee80211_is_valid_channel(bcm->ieee, channel))
                goto out_unlock;
index df495300ce3d39d24176a56b4bf3dc1b0a4b4225..a32db0628157126bd7c93f0860fd8d70c69e5640 100644 (file)
@@ -757,7 +757,8 @@ int pci_enable_device(struct pci_dev *dev)
  * when a device is enabled using managed PCI device enable interface.
  */
 struct pci_devres {
-       unsigned int disable:1;
+       unsigned int enabled:1;
+       unsigned int pinned:1;
        unsigned int orig_intx:1;
        unsigned int restore_intx:1;
        u32 region_mask;
@@ -781,7 +782,7 @@ static void pcim_release(struct device *gendev, void *res)
        if (this->restore_intx)
                pci_intx(dev, this->orig_intx);
 
-       if (this->disable)
+       if (this->enabled && !this->pinned)
                pci_disable_device(dev);
 }
 
@@ -820,12 +821,12 @@ int pcim_enable_device(struct pci_dev *pdev)
        dr = get_pci_dr(pdev);
        if (unlikely(!dr))
                return -ENOMEM;
-       WARN_ON(!!dr->disable);
+       WARN_ON(!!dr->enabled);
 
        rc = pci_enable_device(pdev);
        if (!rc) {
                pdev->is_managed = 1;
-               dr->disable = 1;
+               dr->enabled = 1;
        }
        return rc;
 }
@@ -843,9 +844,9 @@ void pcim_pin_device(struct pci_dev *pdev)
        struct pci_devres *dr;
 
        dr = find_pci_dr(pdev);
-       WARN_ON(!dr || !dr->disable);
+       WARN_ON(!dr || !dr->enabled);
        if (dr)
-               dr->disable = 0;
+               dr->pinned = 1;
 }
 
 /**
@@ -876,7 +877,7 @@ pci_disable_device(struct pci_dev *dev)
 
        dr = find_pci_dr(dev);
        if (dr)
-               dr->disable = 0;
+               dr->enabled = 0;
 
        if (atomic_sub_return(1, &dev->enable_cnt) != 0)
                return;
index b164de050d4f2635e129070a3eca66b31343023b..db6ad8e763ac91dd7d86a4ab55469e1e1dd8128b 100644 (file)
@@ -66,7 +66,7 @@ static struct pci_error_handlers aer_error_handlers = {
        .resume = aer_error_resume,
 };
 
-static struct pcie_port_service_driver aerdrv = {
+static struct pcie_port_service_driver aerdriver = {
        .name           = "aer",
        .id_table       = &aer_id[0],
 
@@ -328,7 +328,7 @@ static void aer_error_resume(struct pci_dev *dev)
  **/
 static int __init aer_service_init(void)
 {
-       return pcie_port_service_register(&aerdrv);
+       return pcie_port_service_register(&aerdriver);
 }
 
 /**
@@ -338,7 +338,7 @@ static int __init aer_service_init(void)
  **/
 static void __exit aer_service_exit(void)
 {
-       pcie_port_service_unregister(&aerdrv);
+       pcie_port_service_unregister(&aerdriver);
 }
 
 module_init(aer_service_init);
index f17e7ed2b2a5d8a81d169e313a3ff1514f09da95..0be5a0b307250802e40f1ed1577bf0d338621e23 100644 (file)
@@ -276,7 +276,7 @@ static struct pci_error_handlers pcie_portdrv_err_handler = {
                .resume = pcie_portdrv_err_resume,
 };
 
-static struct pci_driver pcie_portdrv = {
+static struct pci_driver pcie_portdriver = {
        .name           = (char *)device_name,
        .id_table       = &port_pci_ids[0],
 
@@ -298,7 +298,7 @@ static int __init pcie_portdrv_init(void)
                printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval);
                goto out;
        }
-       retval = pci_register_driver(&pcie_portdrv);
+       retval = pci_register_driver(&pcie_portdriver);
        if (retval)
                pcie_port_bus_unregister();
  out:
@@ -307,7 +307,7 @@ static int __init pcie_portdrv_init(void)
 
 static void __exit pcie_portdrv_exit(void) 
 {
-       pci_unregister_driver(&pcie_portdrv);
+       pci_unregister_driver(&pcie_portdriver);
        pcie_port_bus_unregister();
 }
 
index ff98eaddaa73868777ae19564122c5bff4d0cd3e..2dd8681d6b312a3b6c3c2362315dadddf9bf1de5 100644 (file)
@@ -15,7 +15,7 @@
 
 DECLARE_RWSEM(pci_bus_sem);
 
-static struct pci_bus * __devinit
+static struct pci_bus *
 pci_do_find_bus(struct pci_bus* bus, unsigned char busnr)
 {
        struct pci_bus* child;
index 7a535542fe9204a0bb5336f0e0c7894c38726f3e..118ac9779b3cf5bffc479a0ded1ba55db3e92da7 100644 (file)
@@ -89,6 +89,7 @@ pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi,
                return;
 
        res->irq_resource[i].flags = IORESOURCE_IRQ;  // Also clears _UNSET flag
+       res->irq_resource[i].flags |= irq_flags(triggering, polarity);
        irq = acpi_register_gsi(gsi, triggering, polarity);
        if (irq < 0) {
                res->irq_resource[i].flags |= IORESOURCE_DISABLED;
@@ -103,8 +104,52 @@ pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi,
        pcibios_penalize_isa_irq(irq, 1);
 }
 
+static int dma_flags(int type, int bus_master, int transfer)
+{
+       int flags = 0;
+
+       if (bus_master)
+               flags |= IORESOURCE_DMA_MASTER;
+       switch (type) {
+       case ACPI_COMPATIBILITY:
+               flags |= IORESOURCE_DMA_COMPATIBLE;
+               break;
+       case ACPI_TYPE_A:
+               flags |= IORESOURCE_DMA_TYPEA;
+               break;
+       case ACPI_TYPE_B:
+               flags |= IORESOURCE_DMA_TYPEB;
+               break;
+       case ACPI_TYPE_F:
+               flags |= IORESOURCE_DMA_TYPEF;
+               break;
+       default:
+               /* Set a default value ? */
+               flags |= IORESOURCE_DMA_COMPATIBLE;
+               pnp_err("Invalid DMA type");
+       }
+       switch (transfer) {
+       case ACPI_TRANSFER_8:
+               flags |= IORESOURCE_DMA_8BIT;
+               break;
+       case ACPI_TRANSFER_8_16:
+               flags |= IORESOURCE_DMA_8AND16BIT;
+               break;
+       case ACPI_TRANSFER_16:
+               flags |= IORESOURCE_DMA_16BIT;
+               break;
+       default:
+               /* Set a default value ? */
+               flags |= IORESOURCE_DMA_8AND16BIT;
+               pnp_err("Invalid DMA transfer type");
+       }
+
+       return flags;
+}
+
 static void
-pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma)
+pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma,
+       int type, int bus_master, int transfer)
 {
        int i = 0;
        while (i < PNP_MAX_DMA &&
@@ -112,6 +157,7 @@ pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma)
                i++;
        if (i < PNP_MAX_DMA) {
                res->dma_resource[i].flags = IORESOURCE_DMA;  // Also clears _UNSET flag
+               res->dma_resource[i].flags |= dma_flags(type, bus_master, transfer);
                if (dma == -1) {
                        res->dma_resource[i].flags |= IORESOURCE_DISABLED;
                        return;
@@ -123,7 +169,7 @@ pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma)
 
 static void
 pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res,
-       u64 io, u64 len)
+       u64 io, u64 len, int io_decode)
 {
        int i = 0;
        while (!(res->port_resource[i].flags & IORESOURCE_UNSET) &&
@@ -131,6 +177,8 @@ pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res,
                i++;
        if (i < PNP_MAX_PORT) {
                res->port_resource[i].flags = IORESOURCE_IO;  // Also clears _UNSET flag
+               if (io_decode == ACPI_DECODE_16)
+                       res->port_resource[i].flags |= PNP_PORT_FLAG_16BITADDR;
                if (len <= 0 || (io + len -1) >= 0x10003) {
                        res->port_resource[i].flags |= IORESOURCE_DISABLED;
                        return;
@@ -142,7 +190,7 @@ pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res,
 
 static void
 pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res,
-       u64 mem, u64 len)
+       u64 mem, u64 len, int write_protect)
 {
        int i = 0;
        while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) &&
@@ -154,6 +202,9 @@ pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res,
                        res->mem_resource[i].flags |= IORESOURCE_DISABLED;
                        return;
                }
+               if(write_protect == ACPI_READ_WRITE_MEMORY)
+                       res->mem_resource[i].flags |= IORESOURCE_MEM_WRITEABLE;
+
                res->mem_resource[i].start = mem;
                res->mem_resource[i].end = mem + len - 1;
        }
@@ -178,10 +229,11 @@ pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table,
 
        if (p->resource_type == ACPI_MEMORY_RANGE)
                pnpacpi_parse_allocated_memresource(res_table,
-                               p->minimum, p->address_length);
+                               p->minimum, p->address_length, p->info.mem.write_protect);
        else if (p->resource_type == ACPI_IO_RANGE)
                pnpacpi_parse_allocated_ioresource(res_table,
-                               p->minimum, p->address_length);
+                               p->minimum, p->address_length,
+                               p->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16);
 }
 
 static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
@@ -208,13 +260,17 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
        case ACPI_RESOURCE_TYPE_DMA:
                if (res->data.dma.channel_count > 0)
                        pnpacpi_parse_allocated_dmaresource(res_table,
-                                       res->data.dma.channels[0]);
+                                       res->data.dma.channels[0],
+                                       res->data.dma.type,
+                                       res->data.dma.bus_master,
+                                       res->data.dma.transfer);
                break;
 
        case ACPI_RESOURCE_TYPE_IO:
                pnpacpi_parse_allocated_ioresource(res_table,
                                res->data.io.minimum,
-                               res->data.io.address_length);
+                               res->data.io.address_length,
+                               res->data.io.io_decode);
                break;
 
        case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -224,7 +280,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
        case ACPI_RESOURCE_TYPE_FIXED_IO:
                pnpacpi_parse_allocated_ioresource(res_table,
                                res->data.fixed_io.address,
-                               res->data.fixed_io.address_length);
+                               res->data.fixed_io.address_length,
+                               ACPI_DECODE_10);
                break;
 
        case ACPI_RESOURCE_TYPE_VENDOR:
@@ -236,17 +293,20 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
        case ACPI_RESOURCE_TYPE_MEMORY24:
                pnpacpi_parse_allocated_memresource(res_table,
                                res->data.memory24.minimum,
-                               res->data.memory24.address_length);
+                               res->data.memory24.address_length,
+                               res->data.memory24.write_protect);
                break;
        case ACPI_RESOURCE_TYPE_MEMORY32:
                pnpacpi_parse_allocated_memresource(res_table,
                                res->data.memory32.minimum,
-                               res->data.memory32.address_length);
+                               res->data.memory32.address_length,
+                               res->data.memory32.write_protect);
                break;
        case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
                pnpacpi_parse_allocated_memresource(res_table,
                                res->data.fixed_memory32.address,
-                               res->data.fixed_memory32.address_length);
+                               res->data.fixed_memory32.address_length,
+                               res->data.fixed_memory32.write_protect);
                break;
        case ACPI_RESOURCE_TYPE_ADDRESS16:
        case ACPI_RESOURCE_TYPE_ADDRESS32:
@@ -304,42 +364,8 @@ static void pnpacpi_parse_dma_option(struct pnp_option *option, struct acpi_reso
 
        for(i = 0; i < p->channel_count; i++)
                dma->map |= 1 << p->channels[i];
-       dma->flags = 0;
-       if (p->bus_master)
-               dma->flags |= IORESOURCE_DMA_MASTER;
-       switch (p->type) {
-       case ACPI_COMPATIBILITY:
-               dma->flags |= IORESOURCE_DMA_COMPATIBLE;
-               break;
-       case ACPI_TYPE_A:
-               dma->flags |= IORESOURCE_DMA_TYPEA;
-               break;
-       case ACPI_TYPE_B:
-               dma->flags |= IORESOURCE_DMA_TYPEB;
-               break;
-       case ACPI_TYPE_F:
-               dma->flags |= IORESOURCE_DMA_TYPEF;
-               break;
-       default:
-               /* Set a default value ? */
-               dma->flags |= IORESOURCE_DMA_COMPATIBLE;
-               pnp_err("Invalid DMA type");
-       }
-       switch (p->transfer) {
-       case ACPI_TRANSFER_8:
-               dma->flags |= IORESOURCE_DMA_8BIT;
-               break;
-       case ACPI_TRANSFER_8_16:
-               dma->flags |= IORESOURCE_DMA_8AND16BIT;
-               break;
-       case ACPI_TRANSFER_16:
-               dma->flags |= IORESOURCE_DMA_16BIT;
-               break;
-       default:
-               /* Set a default value ? */
-               dma->flags |= IORESOURCE_DMA_8AND16BIT;
-               pnp_err("Invalid DMA transfer type");
-       }
+
+       dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
 
        pnp_register_dma_resource(option, dma);
        return;
index d38a25f36ea5839557b0328cd72940962d2d0dda..31ae661e586ad21731b58092146277fe0e0c99bb 100644 (file)
@@ -332,9 +332,9 @@ static void acm_rx_tasklet(unsigned long _acm)
        if (!ACM_READY(acm))
                return;
 
-       spin_lock(&acm->throttle_lock);
+       spin_lock_irqsave(&acm->throttle_lock, flags);
        throttled = acm->throttle;
-       spin_unlock(&acm->throttle_lock);
+       spin_unlock_irqrestore(&acm->throttle_lock, flags);
        if (throttled)
                return;
 
@@ -352,9 +352,9 @@ next_buffer:
        dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
 
        tty_buffer_request_room(tty, buf->size);
-       spin_lock(&acm->throttle_lock);
+       spin_lock_irqsave(&acm->throttle_lock, flags);
        throttled = acm->throttle;
-       spin_unlock(&acm->throttle_lock);
+       spin_unlock_irqrestore(&acm->throttle_lock, flags);
        if (!throttled)
                tty_insert_flip_string(tty, buf->base, buf->size);
        tty_flip_buffer_push(tty);
index 274f14f1633e8f348baff7c4ff8f138b3b2a803c..36e7a843bf9181fce7cb78bdca76584abe61a3e9 100644 (file)
@@ -912,7 +912,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
        struct async *as;
        struct usb_ctrlrequest *dr = NULL;
        unsigned int u, totlen, isofrmlen;
-       int ret, interval = 0, ifnum = -1;
+       int ret, ifnum = -1;
 
        if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK|
                           URB_NO_FSBR|URB_ZERO_PACKET))
@@ -992,7 +992,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
                                != USB_ENDPOINT_XFER_ISOC)
                        return -EINVAL;
-               interval = 1 << min (15, ep->desc.bInterval - 1);
                isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb->number_of_packets;
                if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL)))
                        return -ENOMEM;
@@ -1021,10 +1020,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
                                != USB_ENDPOINT_XFER_INT)
                        return -EINVAL;
-               if (ps->dev->speed == USB_SPEED_HIGH)
-                       interval = 1 << min (15, ep->desc.bInterval - 1);
-               else
-                       interval = ep->desc.bInterval;
                if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
                        return -EINVAL;
                if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length))
@@ -1053,7 +1048,11 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
        as->urb->setup_packet = (unsigned char*)dr;
        as->urb->start_frame = uurb->start_frame;
        as->urb->number_of_packets = uurb->number_of_packets;
-       as->urb->interval = interval;
+       if (uurb->type == USBDEVFS_URB_TYPE_ISO ||
+                       ps->dev->speed == USB_SPEED_HIGH)
+               as->urb->interval = 1 << min(15, ep->desc.bInterval - 1);
+       else
+               as->urb->interval = ep->desc.bInterval;
         as->urb->context = as;
         as->urb->complete = async_completed;
        for (totlen = u = 0; u < uurb->number_of_packets; u++) {
index 41400743ce2cc85b5a173d7360b6c0066cc54b8a..b89a98e613235ea715154f347a50763fb81b4e78 100644 (file)
@@ -1281,12 +1281,6 @@ int usb_new_device(struct usb_device *udev)
 {
        int err;
 
-       /* Lock ourself into memory in order to keep a probe sequence
-        * sleeping in a new thread from allowing us to be unloaded.
-        */
-       if (!try_module_get(THIS_MODULE))
-               return -EINVAL;
-
        /* Determine quirks */
        usb_detect_quirks(udev);
 
@@ -1390,7 +1384,6 @@ int usb_new_device(struct usb_device *udev)
                usb_autoresume_device(udev->parent);
 
 exit:
-       module_put(THIS_MODULE);
        return err;
 
 fail:
@@ -2443,7 +2436,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
 
        if (portchange & USB_PORT_STAT_C_CONNECTION) {
                status = hub_port_debounce(hub, port1);
-               if (status < 0) {
+               if (status < 0 && printk_ratelimit()) {
                        dev_err (hub_dev,
                                "connect-debounce failed, port %d disabled\n",
                                port1);
index 2f17468b5c1efe19fdfa8c7a52e3f9fc3a670865..217a3d6d0a06dedc020129e5d0444e5b1ed8dda2 100644 (file)
@@ -221,10 +221,15 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
 
        if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
                        USB_ENDPOINT_XFER_INT) {
+               int interval;
+
+               if (usb_dev->speed == USB_SPEED_HIGH)
+                       interval = 1 << min(15, ep->desc.bInterval - 1);
+               else
+                       interval = ep->desc.bInterval;
                pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
                usb_fill_int_urb(urb, usb_dev, pipe, data, len,
-                               usb_api_blocking_completion, NULL,
-                               ep->desc.bInterval);
+                               usb_api_blocking_completion, NULL, interval);
        } else
                usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
                                usb_api_blocking_completion, NULL);
index a4677802fb208dde66c4be9cd85500acfa9074e1..2a6e3163d944765b9addcca1d8520c066327c7f0 100644 (file)
@@ -1835,7 +1835,7 @@ static int at91udc_resume(struct platform_device *pdev)
 #define        at91udc_resume  NULL
 #endif
 
-static struct platform_driver at91_udc = {
+static struct platform_driver at91_udc_driver = {
        .remove         = __exit_p(at91udc_remove),
        .shutdown       = at91udc_shutdown,
        .suspend        = at91udc_suspend,
@@ -1848,13 +1848,13 @@ static struct platform_driver at91_udc = {
 
 static int __init udc_init_module(void)
 {
-       return platform_driver_probe(&at91_udc, at91udc_probe);
+       return platform_driver_probe(&at91_udc_driver, at91udc_probe);
 }
 module_init(udc_init_module);
 
 static void __exit udc_exit_module(void)
 {
-       platform_driver_unregister(&at91_udc);
+       platform_driver_unregister(&at91_udc_driver);
 }
 module_exit(udc_exit_module);
 
index 7b3a326b57ab55e7099675857f91a2aeb409be74..65c91d3735de9ca439b5b36d5c71877aac7e25f4 100644 (file)
@@ -297,27 +297,6 @@ goku_free_request(struct usb_ep *_ep, struct usb_request *_req)
 
 /*-------------------------------------------------------------------------*/
 
-#undef USE_KMALLOC
-
-/* many common platforms have dma-coherent caches, which means that it's
- * safe to use kmalloc() memory for all i/o buffers without using any
- * cache flushing calls.  (unless you're trying to share cache lines
- * between dma and non-dma activities, which is a slow idea in any case.)
- *
- * other platforms need more care, with 2.6 having a moderately general
- * solution except for the common "buffer is smaller than a page" case.
- */
-#if    defined(CONFIG_X86)
-#define USE_KMALLOC
-
-#elif  defined(CONFIG_MIPS) && !defined(CONFIG_DMA_NONCOHERENT)
-#define USE_KMALLOC
-
-#elif  defined(CONFIG_PPC) && !defined(CONFIG_NOT_COHERENT_CACHE)
-#define USE_KMALLOC
-
-#endif
-
 /* allocating buffers this way eliminates dma mapping overhead, which
  * on some platforms will mean eliminating a per-io buffer copy.  with
  * some kinds of system caches, further tweaks may still be needed.
@@ -334,11 +313,6 @@ goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
                return NULL;
        *dma = DMA_ADDR_INVALID;
 
-#if    defined(USE_KMALLOC)
-       retval = kmalloc(bytes, gfp_flags);
-       if (retval)
-               *dma = virt_to_phys(retval);
-#else
        if (ep->dma) {
                /* the main problem with this call is that it wastes memory
                 * on typical 1/N page allocations: it allocates 1-N pages.
@@ -348,7 +322,6 @@ goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
                                bytes, dma, gfp_flags);
        } else
                retval = kmalloc(bytes, gfp_flags);
-#endif
        return retval;
 }
 
@@ -356,7 +329,6 @@ static void
 goku_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma, unsigned bytes)
 {
        /* free memory into the right allocator */
-#ifndef        USE_KMALLOC
        if (dma != DMA_ADDR_INVALID) {
                struct goku_ep  *ep;
 
@@ -365,7 +337,6 @@ goku_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma, unsigned bytes)
                        return;
                dma_free_coherent(&ep->dev->pdev->dev, bytes, buf, dma);
        } else
-#endif
                kfree (buf);
 }
 
index f01890dc87515493393dcbf1ea05a8dd0dcd418f..571f3ebb70ab705fd95545853dda4a359c463ea4 100644 (file)
@@ -2616,7 +2616,7 @@ lubbock_fail0:
                if (retval != 0) {
                        printk(KERN_ERR "%s: can't get irq %i, err %d\n",
                                driver_name, vbus_irq, retval);
-                       free_irq(IRQ_USB, dev);
+                       free_irq(irq, dev);
                        return -EBUSY;
                }
        }
index 9af529d22b3e609ee8af02b5fa9fc5c03021f13a..1813b7cac294db103f01271406cb2d550c2195c0 100644 (file)
@@ -653,8 +653,7 @@ static int ehci_hub_control (
        if (status & ~0xffff)   /* only if wPortChange is interesting */
 #endif
                dbg_port (ehci, "GetStatus", wIndex + 1, temp);
-               // we "know" this alignment is good, caller used kmalloc()...
-               *((__le32 *) buf) = cpu_to_le32 (status);
+               put_unaligned(cpu_to_le32 (status), (__le32 *) buf);
                break;
        case SetHubFeature:
                switch (wValue) {
index bacc25c53ba3318c3626f1043ffb878706c85a69..8e4427aebb142e00d79b83e4624697b8d746ce33 100644 (file)
@@ -33,6 +33,9 @@ static __u8 root_hub_hub_des[] =
 /* status change bits:  nonzero writes will clear */
 #define RWC_BITS       (USBPORTSC_OCC | USBPORTSC_PEC | USBPORTSC_CSC)
 
+/* suspend/resume bits: port suspended or port resuming */
+#define SUSPEND_BITS   (USBPORTSC_SUSP | USBPORTSC_RD)
+
 /* A port that either is connected or has a changed-bit set will prevent
  * us from AUTO_STOPPING.
  */
@@ -96,8 +99,8 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
        int status;
        int i;
 
-       if (inw(port_addr) & (USBPORTSC_SUSP | USBPORTSC_RD)) {
-               CLR_RH_PORTSTAT(USBPORTSC_SUSP | USBPORTSC_RD);
+       if (inw(port_addr) & SUSPEND_BITS) {
+               CLR_RH_PORTSTAT(SUSPEND_BITS);
                if (test_bit(port, &uhci->resuming_ports))
                        set_bit(port, &uhci->port_c_suspend);
 
@@ -107,7 +110,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
                 * Experiments show that some controllers take longer, so
                 * we'll poll for completion. */
                for (i = 0; i < 10; ++i) {
-                       if (!(inw(port_addr) & USBPORTSC_RD))
+                       if (!(inw(port_addr) & SUSPEND_BITS))
                                break;
                        udelay(1);
                }
@@ -289,7 +292,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                        wPortStatus |= USB_PORT_STAT_CONNECTION;
                if (status & USBPORTSC_PE) {
                        wPortStatus |= USB_PORT_STAT_ENABLE;
-                       if (status & (USBPORTSC_SUSP | USBPORTSC_RD))
+                       if (status & SUSPEND_BITS)
                                wPortStatus |= USB_PORT_STAT_SUSPEND;
                }
                if (status & USBPORTSC_OC)
index 0c1d66ddb8125fcc04461fd51be5cb4bac89778c..bc3327e3dd78a9e62897814203a3e4385a104ea0 100644 (file)
@@ -2905,17 +2905,31 @@ static int __init ftdi_elan_init(void)
 {
         int result;
         printk(KERN_INFO "driver %s built at %s on %s\n", ftdi_elan_driver.name,
-                 __TIME__, __DATE__);
+              __TIME__, __DATE__);
         init_MUTEX(&ftdi_module_lock);
         INIT_LIST_HEAD(&ftdi_static_list);
         status_queue = create_singlethread_workqueue("ftdi-status-control");
+       if (!status_queue)
+               goto err1;
         command_queue = create_singlethread_workqueue("ftdi-command-engine");
+       if (!command_queue)
+               goto err2;
         respond_queue = create_singlethread_workqueue("ftdi-respond-engine");
+       if (!respond_queue)
+               goto err3;
         result = usb_register(&ftdi_elan_driver);
         if (result)
                 printk(KERN_ERR "usb_register failed. Error number %d\n",
-                        result);
+                      result);
         return result;
+
+ err3:
+       destroy_workqueue(command_queue);
+ err2:
+       destroy_workqueue(status_queue);
+ err1:
+       printk(KERN_ERR "%s couldn't create workqueue\n", ftdi_elan_driver.name);
+       return -ENOMEM;
 }
 
 static void __exit ftdi_elan_exit(void)
index 4a932e1cd93bd39622e87715f75464a038154ac8..c0bc52be5e1094b634dee18ec05677b060c4746b 100644 (file)
@@ -570,6 +570,10 @@ static const struct driver_info dm9601_info = {
 };
 
 static const struct usb_device_id products[] = {
+       {
+        USB_DEVICE(0x07aa, 0x9601),    /* Corega FEther USB-TXC */
+        .driver_info = (unsigned long)&dm9601_info,
+        },
        {
         USB_DEVICE(0x0a46, 0x9601),    /* Davicom USB-100 */
         .driver_info = (unsigned long)&dm9601_info,
index 18816bf96a4d6152da19a062c5f21d3247eaca60..310a8b5f5906a6f54b226b5e2dddab2453d3f48f 100644 (file)
@@ -44,8 +44,43 @@ struct airprime_private {
        int outstanding_urbs;
        int throttled;
        struct urb *read_urbp[NUM_READ_URBS];
+
+       /* Settings for the port */
+       int rts_state;  /* Handshaking pins (outputs) */
+       int dtr_state;
+       int cts_state;  /* Handshaking pins (inputs) */
+       int dsr_state;
+       int dcd_state;
+       int ri_state;
 };
 
+static int airprime_send_setup(struct usb_serial_port *port)
+{
+       struct usb_serial *serial = port->serial;
+       struct airprime_private *priv;
+
+       dbg("%s", __FUNCTION__);
+
+       if (port->number != 0)
+               return 0;
+
+       priv = usb_get_serial_port_data(port);
+
+       if (port->tty) {
+               int val = 0;
+               if (priv->dtr_state)
+                       val |= 0x01;
+               if (priv->rts_state)
+                       val |= 0x02;
+
+               return usb_control_msg(serial->dev,
+                               usb_rcvctrlpipe(serial->dev, 0),
+                               0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
+       }
+
+       return 0;
+}
+
 static void airprime_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port *port = urb->context;
@@ -118,6 +153,10 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
                usb_set_serial_port_data(port, priv);
        }
 
+       /* Set some sane defaults */
+       priv->rts_state = 1;
+       priv->dtr_state = 1;
+
        for (i = 0; i < NUM_READ_URBS; ++i) {
                buffer = kmalloc(buffer_size, GFP_KERNEL);
                if (!buffer) {
@@ -151,6 +190,9 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
                /* remember this urb so we can kill it when the port is closed */
                priv->read_urbp[i] = urb;
        }
+
+       airprime_send_setup(port);
+
        goto out;
 
  errout:
@@ -176,6 +218,11 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp)
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
+       priv->rts_state = 0;
+       priv->dtr_state = 0;
+
+       airprime_send_setup(port);
+
        for (i = 0; i < NUM_READ_URBS; ++i) {
                usb_kill_urb (priv->read_urbp[i]);
                kfree (priv->read_urbp[i]->transfer_buffer);
index db623e754899859bc88e043a23ee593bdd3a14cf..d7d0ba986a80be0a79c38dcd6c4867321524e3ed 100644 (file)
@@ -63,6 +63,8 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
        { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
        { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
+       { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
+       { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
        { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
        { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
        { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
index c525b42dadde28a3630c355aaaa7834884b5620a..1633a0fd48e82f54f838b2bcd702a7f96e578a60 100644 (file)
@@ -315,6 +315,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
@@ -420,6 +421,14 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_IBS_US485_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_IBS_PICPRO_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_IBS_PCMCIA_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_IBS_PK1_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_IBS_RS232MON_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_IBS_APP70_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) },
        /*
         * These will probably use user-space drivers.  Uncomment them if
         * you need them or use the user-specified vendor/product module
@@ -459,6 +468,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) },
        { USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) },
+       { USB_DEVICE(TTI_VID, TTI_QL355P_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
        { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
        { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
@@ -533,6 +543,7 @@ static const char *ftdi_chip_name[] = {
        [FT8U232AM] = "FT8U232AM",
        [FT232BM] = "FT232BM",
        [FT2232C] = "FT2232C",
+       [FT232RL] = "FT232RL",
 };
 
 
@@ -588,6 +599,8 @@ struct ftdi_private {
 static int  ftdi_sio_probe     (struct usb_serial *serial, const struct usb_device_id *id);
 static int  ftdi_sio_attach            (struct usb_serial *serial);
 static void ftdi_shutdown              (struct usb_serial *serial);
+static int  ftdi_sio_port_probe        (struct usb_serial_port *port);
+static int  ftdi_sio_port_remove       (struct usb_serial_port *port);
 static int  ftdi_open                  (struct usb_serial_port *port, struct file *filp);
 static void ftdi_close                 (struct usb_serial_port *port, struct file *filp);
 static int  ftdi_write                 (struct usb_serial_port *port, const unsigned char *buf, int count);
@@ -622,6 +635,8 @@ static struct usb_serial_driver ftdi_sio_device = {
        .num_bulk_out =         1,
        .num_ports =            1,
        .probe =                ftdi_sio_probe,
+       .port_probe =           ftdi_sio_port_probe,
+       .port_remove =          ftdi_sio_port_remove,
        .open =                 ftdi_open,
        .close =                ftdi_close,
        .throttle =             ftdi_throttle,
@@ -1024,11 +1039,10 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a
 {
        struct usb_serial_port *port = to_usb_serial_port(dev);
        struct ftdi_private *priv = usb_get_serial_port_data(port);
-       struct usb_device *udev;
+       struct usb_device *udev = port->serial->dev;
        unsigned short latency = 0;
        int rv = 0;
 
-       udev = to_usb_device(dev);
 
        dbg("%s",__FUNCTION__);
 
@@ -1052,13 +1066,11 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute *
 {
        struct usb_serial_port *port = to_usb_serial_port(dev);
        struct ftdi_private *priv = usb_get_serial_port_data(port);
-       struct usb_device *udev;
+       struct usb_device *udev = port->serial->dev;
        char buf[1];
        int v = simple_strtoul(valbuf, NULL, 10);
        int rv = 0;
 
-       udev = to_usb_device(dev);
-
        dbg("%s: setting latency timer = %i", __FUNCTION__, v);
 
        rv = usb_control_msg(udev,
@@ -1083,13 +1095,11 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att
 {
        struct usb_serial_port *port = to_usb_serial_port(dev);
        struct ftdi_private *priv = usb_get_serial_port_data(port);
-       struct usb_device *udev;
+       struct usb_device *udev = port->serial->dev;
        char buf[1];
        int v = simple_strtoul(valbuf, NULL, 10);
        int rv = 0;
 
-       udev = to_usb_device(dev);
-
        dbg("%s: setting event char = %i", __FUNCTION__, v);
 
        rv = usb_control_msg(udev,
@@ -1110,46 +1120,38 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att
 static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer, store_latency_timer);
 static DEVICE_ATTR(event_char, S_IWUSR, NULL, store_event_char);
 
-static int create_sysfs_attrs(struct usb_serial *serial)
+static int create_sysfs_attrs(struct usb_serial_port *port)
 {
-       struct ftdi_private *priv;
-       struct usb_device *udev;
+       struct ftdi_private *priv = usb_get_serial_port_data(port);
        int retval = 0;
 
        dbg("%s",__FUNCTION__);
 
-       priv = usb_get_serial_port_data(serial->port[0]);
-       udev = serial->dev;
-
        /* XXX I've no idea if the original SIO supports the event_char
         * sysfs parameter, so I'm playing it safe.  */
        if (priv->chip_type != SIO) {
                dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]);
-               retval = device_create_file(&udev->dev, &dev_attr_event_char);
+               retval = device_create_file(&port->dev, &dev_attr_event_char);
                if ((!retval) &&
                    (priv->chip_type == FT232BM || priv->chip_type == FT2232C)) {
-                       retval = device_create_file(&udev->dev,
+                       retval = device_create_file(&port->dev,
                                                    &dev_attr_latency_timer);
                }
        }
        return retval;
 }
 
-static void remove_sysfs_attrs(struct usb_serial *serial)
+static void remove_sysfs_attrs(struct usb_serial_port *port)
 {
-       struct ftdi_private *priv;
-       struct usb_device *udev;
+       struct ftdi_private *priv = usb_get_serial_port_data(port);
 
        dbg("%s",__FUNCTION__);
 
-       priv = usb_get_serial_port_data(serial->port[0]);
-       udev = serial->dev;
-
        /* XXX see create_sysfs_attrs */
        if (priv->chip_type != SIO) {
-               device_remove_file(&udev->dev, &dev_attr_event_char);
+               device_remove_file(&port->dev, &dev_attr_event_char);
                if (priv->chip_type == FT232BM || priv->chip_type == FT2232C) {
-                       device_remove_file(&udev->dev, &dev_attr_latency_timer);
+                       device_remove_file(&port->dev, &dev_attr_latency_timer);
                }
        }
 
@@ -1169,13 +1171,9 @@ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id
        return (0);
 }
 
-/* attach subroutine */
-static int ftdi_sio_attach (struct usb_serial *serial)
+static int ftdi_sio_port_probe(struct usb_serial_port *port)
 {
-       struct usb_serial_port *port = serial->port[0];
        struct ftdi_private *priv;
-       struct ftdi_sio_quirk *quirk;
-       int retval;
 
        dbg("%s",__FUNCTION__);
 
@@ -1215,19 +1213,21 @@ static int ftdi_sio_attach (struct usb_serial *serial)
        kfree(port->bulk_out_buffer);
        port->bulk_out_buffer = NULL;
 
-       usb_set_serial_port_data(serial->port[0], priv);
+       usb_set_serial_port_data(port, priv);
 
-       ftdi_determine_type (serial->port[0]);
-       retval = create_sysfs_attrs(serial);
-       if (retval)
-               dev_err(&serial->dev->dev, "Error creating sysfs files, "
-                       "continuing\n");
+       ftdi_determine_type (port);
+       create_sysfs_attrs(port);
+       return 0;
+}
 
+/* attach subroutine */
+static int ftdi_sio_attach (struct usb_serial *serial)
+{
        /* Check for device requiring special set up. */
-       quirk = (struct ftdi_sio_quirk *)usb_get_serial_data(serial);
-       if (quirk && quirk->setup) {
+       struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial);
+
+       if (quirk && quirk->setup)
                quirk->setup(serial);
-       }
 
        return 0;
 } /* ftdi_sio_attach */
@@ -1271,17 +1271,18 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
  *      calls __serial_close for each open of the port
  *      shutdown is called then (ie ftdi_shutdown)
  */
-
-
 static void ftdi_shutdown (struct usb_serial *serial)
-{ /* ftdi_shutdown */
+{
+       dbg("%s", __FUNCTION__);
+}
 
-       struct usb_serial_port *port = serial->port[0];
+static int ftdi_sio_port_remove(struct usb_serial_port *port)
+{
        struct ftdi_private *priv = usb_get_serial_port_data(port);
 
        dbg("%s", __FUNCTION__);
 
-       remove_sysfs_attrs(serial);
+       remove_sysfs_attrs(port);
 
        /* all open ports are closed at this point
          *    (by usbserial.c:__serial_close, which calls ftdi_close)
@@ -1291,8 +1292,9 @@ static void ftdi_shutdown (struct usb_serial *serial)
                usb_set_serial_port_data(port, NULL);
                kfree(priv);
        }
-} /* ftdi_shutdown */
 
+       return 0;
+}
 
 static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
 { /* ftdi_open */
index 1bdda935f7d991b34d7c812db78ea569b7e22856..513cfe1b768b1383cb7e82f69890d9a64e270589 100644 (file)
@@ -27,6 +27,7 @@
 #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */
 #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
 #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
+#define FTDI_232RL_PID  0xFBFA  /* Product ID for FT232RL */
 #define FTDI_RELAIS_PID        0xFA10  /* Relais device from Rudolf Gugler */
 #define FTDI_NF_RIC_VID        0x0DCD  /* Vendor Id */
 #define FTDI_NF_RIC_PID        0x0001  /* Product Id */
  */
 #define FTDI_SUUNTO_SPORTS_PID 0xF680  /* Suunto Sports instrument */
 
+/*
+ * TTi (Thurlby Thandar Instruments)
+ */
+#define TTI_VID                        0x103E  /* Vendor Id */
+#define TTI_QL355P_PID         0x03E8  /* TTi QL355P power supply */
+
 /*
  * Definitions for B&B Electronics products.
  */
 #define TELLDUS_VID                    0x1781  /* Vendor ID */
 #define TELLDUS_TELLSTICK_PID          0x0C30  /* RF control dongle 433 MHz using FT232RL */
 
+/*
+ * IBS elektronik product ids
+ * Submitted by Thomas Schleusener
+ */
+#define FTDI_IBS_US485_PID     0xff38  /* IBS US485 (USB<-->RS422/485 interface) */
+#define FTDI_IBS_PICPRO_PID    0xff39  /* IBS PIC-Programmer */
+#define FTDI_IBS_PCMCIA_PID    0xff3a  /* IBS Card reader for PCMCIA SRAM-cards */
+#define FTDI_IBS_PK1_PID       0xff3b  /* IBS PK1 - Particel counter */
+#define FTDI_IBS_RS232MON_PID  0xff3c  /* IBS RS232 - Monitor */
+#define FTDI_IBS_APP70_PID     0xff3d  /* APP 70 (dust monitoring system) */
+#define FTDI_IBS_PEDO_PID      0xff3e  /* IBS PEDO-Modem (RF modem 868.35 MHz) */
+#define FTDI_IBS_PROD_PID      0xff3f  /* future device */
+
 /* Commands */
 #define FTDI_SIO_RESET                 0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL    1 /* Set the modem control register */
@@ -620,6 +640,7 @@ typedef enum {
        FT8U232AM = 2,
        FT232BM = 3,
        FT2232C = 4,
+       FT232RL = 5,
 } ftdi_chip_type_t;
 
 typedef enum {
index a408184334ea9d829f7ecd3be632202c56cf0184..d16e2e1764adff84daae6697d5f7481dc6e77382 100644 (file)
@@ -247,6 +247,8 @@ static struct usb_device_id ipaq_id_table [] = {
        { USB_DEVICE(0x04AD, 0x0301) }, /* USB Sync 0301 */
        { USB_DEVICE(0x04AD, 0x0302) }, /* USB Sync 0302 */
        { USB_DEVICE(0x04AD, 0x0303) }, /* USB Sync 0303 */
+       { USB_DEVICE(0x04AD, 0x0306) }, /* GPS Pocket PC USB Sync */
+       { USB_DEVICE(0x04B7, 0x0531) }, /* MyGuide 7000 XL USB Sync */
        { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */
        { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */
        { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */
index 6bf22a28adb823db701965aef720e74dfc6c54eb..8511352251f33ea3f551438913b9a778bf0158db 100644 (file)
@@ -99,9 +99,12 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po
                        continue;
 
                *minor = i;
+               j = 0;
                dbg("%s - minor base = %d", __FUNCTION__, *minor);
-               for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
+               for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) {
                        serial_table[i] = serial;
+                       serial->port[j++]->number = i;
+               }
                spin_unlock(&table_lock);
                return serial;
        }
@@ -135,11 +138,6 @@ static void destroy_serial(struct kref *kref)
 
        dbg("%s - %s", __FUNCTION__, serial->type->description);
 
-       serial->type->shutdown(serial);
-
-       /* return the minor range that this device had */
-       return_serial(serial);
-
        for (i = 0; i < serial->num_ports; ++i)
                serial->port[i]->open_count = 0;
 
@@ -150,6 +148,12 @@ static void destroy_serial(struct kref *kref)
                        serial->port[i] = NULL;
                }
 
+       if (serial->type->shutdown)
+               serial->type->shutdown(serial);
+
+       /* return the minor range that this device had */
+       return_serial(serial);
+
        /* If this is a "fake" port, we have to clean it up here, as it will
         * not get cleaned up in port_release() as it was never registered with
         * the driver core */
@@ -826,7 +830,6 @@ int usb_serial_probe(struct usb_interface *interface,
                        num_ports = type->num_ports;
        }
 
-       serial->minor = minor;
        serial->num_ports = num_ports;
        serial->num_bulk_in = num_bulk_in;
        serial->num_bulk_out = num_bulk_out;
@@ -847,7 +850,6 @@ int usb_serial_probe(struct usb_interface *interface,
                port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
                if (!port)
                        goto probe_error;
-               port->number = i + serial->minor;
                port->serial = serial;
                spin_lock_init(&port->lock);
                mutex_init(&port->mutex);
@@ -980,6 +982,7 @@ int usb_serial_probe(struct usb_interface *interface,
                dev_err(&interface->dev, "No more free serial devices\n");
                goto probe_error;
        }
+       serial->minor = minor;
 
        /* register all of the individual ports with the driver core */
        for (i = 0; i < num_ports; ++i) {
@@ -1034,9 +1037,6 @@ probe_error:
                kfree(port->interrupt_out_buffer);
        }
 
-       /* return the minor range that this device had */
-       return_serial (serial);
-
        /* free up any memory that we allocated */
        for (i = 0; i < serial->num_port_pointers; ++i)
                kfree(serial->port[i]);
index 9644a8ea4aa71adfe794abf9cc75bdae12122b98..2dd31e3f5107abaaa61cd8c1851f249a451bd02e 100644 (file)
@@ -146,6 +146,13 @@ UNUSUAL_DEV(  0x0420, 0x0001, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE ),
 
+/* Reported by Andrew Nayenko <relan@bk.ru> */
+UNUSUAL_DEV(  0x0421, 0x0019, 0x0592, 0x0592,
+               "Nokia",
+               "Nokia 6288",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_MAX_SECTORS_64 ),
+
 /* Reported by Mario Rettig <mariorettig@web.de> */
 UNUSUAL_DEV(  0x0421, 0x042e, 0x0100, 0x0100,
                "Nokia",
@@ -1395,16 +1402,6 @@ UNUSUAL_DEV(  0x1652, 0x6600, 0x0201, 0x0201,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE ),
 
-/* Reported by Thomas Baechler <thomas@archlinux.org>
- * Fixes I/O errors with Teac HD-35PU devices
- */
-
-UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201,
-               "Super Top",
-               "USB 2.0  IDE DEVICE",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_IGNORE_RESIDUE),
-
 /* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
  * and Renato Perini <rperini@email.it>
  */
index 6eb3daebd56354ca4973093c9d5966c7e148ae0a..888f236e54948a77fdfd26736a80a1ffd99a35f7 100644 (file)
@@ -99,7 +99,13 @@ static int jffs2_garbage_collect_thread(void *_c)
                if (try_to_freeze())
                        continue;
 
-               cond_resched();
+               /* This thread is purely an optimisation. But if it runs when
+                  other things could be running, it actually makes things a
+                  lot worse. Use yield() and put it at the back of the runqueue
+                  every time. Especially during boot, pulling an inode in
+                  with read_inode() is much preferable to having the GC thread
+                  get there first. */
+               yield();
 
                /* Put_super will send a SIGKILL and then wait on the sem.
                 */
index 58a0b912e9d05ce5697ff1239711ead97671e152..717a48cf7df2aadbccde0432024dafde0e80a410 100644 (file)
@@ -373,7 +373,14 @@ free_out:
 static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un)
 {
        /* We don't mark unknown nodes as REF_UNCHECKED */
-       BUG_ON(ref_flags(ref) == REF_UNCHECKED);
+       if (ref_flags(ref) == REF_UNCHECKED) {
+               JFFS2_ERROR("REF_UNCHECKED but unknown node at %#08x\n",
+                           ref_offset(ref));
+               JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n",
+                            je16_to_cpu(un->magic), je16_to_cpu(un->nodetype),
+                            je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc));
+               return 1;
+       }
 
        un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype));
 
@@ -576,6 +583,13 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf
                        jffs2_mark_node_obsolete(c, ref);
                        goto cont;
                }
+               /* Due to poor choice of crc32 seed, an all-zero node will have a correct CRC */
+               if (!je32_to_cpu(node->u.hdr_crc) && !je16_to_cpu(node->u.nodetype) &&
+                   !je16_to_cpu(node->u.magic) && !je32_to_cpu(node->u.totlen)) {
+                       JFFS2_NOTICE("All zero node header at %#08x.\n", ref_offset(ref));
+                       jffs2_mark_node_obsolete(c, ref);
+                       goto cont;
+               }
 
                switch (je16_to_cpu(node->u.nodetype)) {
 
index 31c1475d922aa2d3f4eb5c75841838f1100a385b..7fb45bd4915c5c1f1cbc8ffb71bd226f5a99b24b 100644 (file)
@@ -734,6 +734,15 @@ scan_more:
                        ofs += 4;
                        continue;
                }
+               /* Due to poor choice of crc32 seed, an all-zero node will have a correct CRC */
+               if (!je32_to_cpu(node->hdr_crc) && !je16_to_cpu(node->nodetype) &&
+                   !je16_to_cpu(node->magic) && !je32_to_cpu(node->totlen)) {
+                       noisy_printk(&noise, "jffs2_scan_eraseblock(): All zero node header at 0x%08x.\n", ofs);
+                       if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
+                               return err;
+                       ofs += 4;
+                       continue;
+               }
 
                if (ofs + je32_to_cpu(node->totlen) >
                    jeb->offset + c->sector_size) {
index de718e3a169296c6c6dc526743f2498762205ee8..4fac6dd539545f91ef33fae876737202b93d2f55 100644 (file)
@@ -238,7 +238,10 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
        jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
 
        spin_lock(&c->erase_completion_lock);
-       jffs2_block_refile(c, jeb, REFILE_NOTEMPTY);
+       if (c->wbuf_ofs % c->mtd->erasesize)
+               jffs2_block_refile(c, jeb, REFILE_NOTEMPTY);
+       else
+               jffs2_block_refile(c, jeb, REFILE_ANYWAY);
        spin_unlock(&c->erase_completion_lock);
 
        BUG_ON(!ref_obsolete(jeb->last_node));
@@ -1087,7 +1090,7 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *
        if (!c->mtd->block_markbad)
                return 1; // What else can we do?
 
-       D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Marking bad block at %08x\n", bad_offset));
+       printk(KERN_WARNING "JFFS2: marking eraseblock at %08x\n as bad", bad_offset);
        ret = c->mtd->block_markbad(c->mtd, bad_offset);
 
        if (ret) {
diff --git a/include/asm-mips/sibyte/trace_prof.h b/include/asm-mips/sibyte/trace_prof.h
deleted file mode 100644 (file)
index 5577920..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2001 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef __ASM_SIBYTE_TRACE_PROF_H
-#define __ASM_SIBYTE_TRACE_PROF_H
-
-#undef DBG
-#if SBPROF_TB_DEBUG
-#define DBG(a) a
-#else
-#define DBG(a)
-#endif
-
-#define SBPROF_TB_MAJOR 240
-#define DEVNAME "bcm1250_tbprof"
-
-typedef u_int64_t tb_sample_t[6*256];
-
-struct sbprof_tb {
-       int          open;
-       tb_sample_t *sbprof_tbbuf;
-       int          next_tb_sample;
-
-       volatile int tb_enable;
-       volatile int tb_armed;
-
-       wait_queue_head_t tb_sync;
-       wait_queue_head_t tb_read;
-};
-
-#define MAX_SAMPLE_BYTES (24*1024*1024)
-#define MAX_TBSAMPLE_BYTES (12*1024*1024)
-
-#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t))
-#define TB_SAMPLE_SIZE (sizeof(tb_sample_t))
-#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE)
-
-/* IOCTLs */
-#define SBPROF_ZBSTART         _IOW('s', 0, int)
-#define SBPROF_ZBSTOP          _IOW('s', 1, int)
-#define SBPROF_ZBWAITFULL      _IOW('s', 2, int)
-
-/***************************************************************************
- * Routines for gathering ZBbus profiles using trace buffer
- ***************************************************************************/
-
-/* Requires: Already called zclk_timer_init with a value that won't
-            saturate 40 bits.  No subsequent use of SCD performance counters
-            or trace buffer.
-   Effect:   Starts gathering random ZBbus profiles using trace buffer. */
-extern int sbprof_zbprof_start(struct file *filp);
-
-/* Effect: Stops collection of ZBbus profiles */
-extern int sbprof_zbprof_stop(void);
-
-
-/***************************************************************************
- * Routines for using 40-bit SCD cycle counter
- *
- * Client responsible for either handling interrupts or making sure
- * the cycles counter never saturates, e.g., by doing
- * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs.
- ***************************************************************************/
-
-/* Configures SCD counter 0 to count ZCLKs starting from val;
-   Configures SCD counters1,2,3 to count nothing.
-   Must not be called while gathering ZBbus profiles.
-
-unsigned long long val; */
-#define zclk_timer_init(val) \
-  __asm__ __volatile__ (".set push;" \
-                       ".set mips64;" \
-                       "la   $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
-                       "sd   %0, 0x10($8);"   /* write val to counter0 */ \
-                       "sd   %1, 0($8);"      /* config counter0 for zclks*/ \
-                       ".set pop" \
-                       : /* no outputs */ \
-                                                    /* enable, counter0 */ \
-                       : /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \
-                       : /* modifies */ "$8" )
-
-
-/* Reads SCD counter 0 and puts result in value
-   unsigned long long val; */
-#define zclk_get(val) \
-  __asm__ __volatile__ (".set push;" \
-                       ".set mips64;" \
-                       "la   $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
-                       "ld   %0, 0x10($8);"   /* write val to counter0 */ \
-                       ".set pop" \
-                       : /* outputs */ "=r"(val) \
-                       : /* inputs */ \
-                       : /* modifies */ "$8" )
-
-#endif /* __ASM_SIBYTE_TRACE_PROF_H */
index be9509c8f8c10bc9dcaf54e91e4aae52c265d36d..284dfd01a33d5421cc7c96a4035e3aae0b375e9a 100644 (file)
  */
 #define HAS_DMA
 
+static DEFINE_SPINLOCK(dma_spin_lock);
+
+#define claim_dma_lock() \
+({     unsigned long flags; \
+       spin_lock_irqsave(&dma_spin_lock, flags); \
+       flags; \
+})
+
+#define release_dma_lock(__flags) \
+       spin_unlock_irqrestore(&dma_spin_lock, __flags);
+
 static struct sparc_ebus_info {
        struct ebus_dma_info info;
        unsigned int addr;
index 6a8570be331bbdb3deb587983953485427901ef5..3d956c3abb310d06867abd729f8aacd0433be00b 100644 (file)
@@ -121,6 +121,7 @@ struct mtd_info {
        u_int32_t writesize;
 
        u_int32_t oobsize;   // Amount of OOB data per block (e.g. 16)
+       u_int32_t oobavail;  // Available OOB bytes per block
 
        // Kernel-only stuff starts here.
        char *name;
index d8af8a95e58d86305227afb9a8385911b4b67b18..a56d24ada5057eacddc91cb51ee4254cfdcfed13 100644 (file)
@@ -82,7 +82,8 @@ struct onenand_bufferram {
  * @wq:                        [INTERN] wait queue to sleep on if a OneNAND
  *                     operation is in progress
  * @state:             [INTERN] the current state of the OneNAND device
- * @page_buf:          data buffer
+ * @page_buf:          [INTERN] page main data buffer
+ * @oob_buf:           [INTERN] page oob data buffer
  * @subpagesize:       [INTERN] holds the subpagesize
  * @ecclayout:         [REPLACEABLE] the default ecc placement scheme
  * @bbm:               [REPLACEABLE] pointer to Bad Block Management
@@ -122,6 +123,7 @@ struct onenand_chip {
        wait_queue_head_t       wq;
        onenand_state_t         state;
        unsigned char           *page_buf;
+       unsigned char           *oob_buf;
 
        int                     subpagesize;
        struct nand_ecclayout   *ecclayout;
@@ -156,6 +158,7 @@ struct onenand_chip {
 #define ONENAND_HAS_CONT_LOCK          (0x0001)
 #define ONENAND_HAS_UNLOCK_ALL         (0x0002)
 #define ONENAND_PAGEBUF_ALLOC          (0x1000)
+#define ONENAND_OOBBUF_ALLOC           (0x2000)
 
 /*
  * OneNAND Flash Manufacturer ID Codes
index f77e893e4620ce0db767b335058daf4744a6393b..fbc51de6444e4bbb9973a12a90698adf1db700b2 100644 (file)
@@ -2419,12 +2419,6 @@ void module_remove_driver(struct device_driver *drv)
                        kfree(driver_name);
                }
        }
-       /*
-        * Undo the additional reference we added in module_add_driver()
-        * via kset_find_obj()
-        */
-       if (drv->mod_name)
-               kobject_put(&drv->kobj);
 }
 EXPORT_SYMBOL(module_remove_driver);
 #endif
index f4f6176dcd1286313c57ae80239ec1f0f7bbf65e..057921c5945a551777f56706b397c5e4f737aaf3 100644 (file)
@@ -385,9 +385,11 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
                goto out;
        old_parent = kobj->parent;
        kobj->parent = new_parent;
+       new_parent = NULL;
        kobject_put(old_parent);
        kobject_uevent_env(kobj, KOBJ_MOVE, envp);
 out:
+       kobject_put(new_parent);
        kobject_put(kobj);
        kfree(devpath_string);
        kfree(devpath);
index 63fe1093b61635f06ecfc821e2c3caf6e68524eb..0b9c49b3a10000a07b391e164715cae8e322565f 100644 (file)
@@ -360,7 +360,7 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist,
                return;
        }
 
-       read_lock(&in6_dev->lock);
+       read_lock_bh(&in6_dev->lock);
        for (ifp = in6_dev->addr_list; ifp; ifp = ifp->if_next) {
                /* Add the address to the local list.  */
                addr = t_new(struct sctp_sockaddr_entry, GFP_ATOMIC);
@@ -374,7 +374,7 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist,
                }
        }
 
-       read_unlock(&in6_dev->lock);
+       read_unlock_bh(&in6_dev->lock);
        rcu_read_unlock();
 }