Merge branch 'for-linus' of git://github.com/chrismason/linux
Linus Torvalds [Tue, 20 Sep 2011 21:22:55 +0000 (14:22 -0700)]
* 'for-linus' of git://github.com/chrismason/linux:
  Btrfs: reserve sufficient space for ioctl clone

220 files changed:
Documentation/ABI/testing/sysfs-class-scsi_host [new file with mode: 0644]
Documentation/cgroups/memory.txt
Documentation/kernel-parameters.txt
Documentation/networking/dmfe.txt
MAINTAINERS
arch/alpha/Kconfig
arch/um/Kconfig.x86
arch/um/Makefile
arch/um/drivers/line.c
arch/um/drivers/xterm.c
arch/um/include/asm/ptrace-generic.h
arch/um/include/shared/line.h
arch/um/include/shared/registers.h
arch/um/kernel/process.c
arch/um/kernel/ptrace.c
arch/um/os-Linux/registers.c
arch/um/os-Linux/skas/mem.c
arch/um/os-Linux/skas/process.c
arch/um/sys-i386/asm/ptrace.h
arch/um/sys-i386/ptrace.c
arch/um/sys-i386/shared/sysdep/ptrace.h
arch/um/sys-x86_64/ptrace.c
arch/um/sys-x86_64/shared/sysdep/ptrace.h
arch/x86/include/asm/alternative-asm.h
arch/x86/include/asm/alternative.h
arch/x86/include/asm/cpufeature.h
arch/x86/xen/mmu.c
arch/x86/xen/setup.c
arch/x86/xen/smp.c
arch/x86/xen/time.c
drivers/acpi/acpica/acconfig.h
drivers/acpi/apei/Kconfig
drivers/acpi/apei/apei-base.c
drivers/cpufreq/pcc-cpufreq.c
drivers/firewire/ohci.c
drivers/gpio/gpio-generic.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r200.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/hid/hid-wacom.c
drivers/hwmon/coretemp.c
drivers/hwmon/pmbus/pmbus_core.c
drivers/input/keyboard/adp5588-keys.c
drivers/input/misc/cm109.c
drivers/input/mouse/bcm5974.c
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/input/touchscreen/wacom_w8001.c
drivers/iommu/dmar.c
drivers/leds/ledtrig-timer.c
drivers/mfd/max8997.c
drivers/mfd/omap-usb-host.c
drivers/mfd/tps65910-irq.c
drivers/mfd/twl4030-madc.c
drivers/mfd/wm8350-gpio.c
drivers/misc/pti.c
drivers/net/Kconfig
drivers/net/bnx2x/bnx2x.h
drivers/net/bnx2x/bnx2x_cmn.c
drivers/net/bnx2x/bnx2x_ethtool.c
drivers/net/bnx2x/bnx2x_link.c
drivers/net/bnx2x/bnx2x_main.c
drivers/net/bnx2x/bnx2x_reg.h
drivers/net/bnx2x/bnx2x_stats.c
drivers/net/can/ti_hecc.c
drivers/net/e1000/e1000_hw.c
drivers/net/ibmveth.c
drivers/net/pch_gbe/pch_gbe.h
drivers/net/pch_gbe/pch_gbe_main.c
drivers/net/sfc/efx.c
drivers/net/sfc/io.h
drivers/net/sfc/mcdi.c
drivers/net/sfc/nic.c
drivers/net/sfc/nic.h
drivers/net/sfc/siena.c
drivers/net/sfc/workarounds.h
drivers/net/usb/ipheth.c
drivers/net/wireless/ath/ath9k/ar9002_calib.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/iwlegacy/iwl-3945-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
drivers/net/wireless/rtlwifi/core.c
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
drivers/pci/probe.c
drivers/rtc/rtc-imxdi.c
drivers/rtc/rtc-s3c.c
drivers/scsi/bnx2i/bnx2i_hwi.c
drivers/scsi/fcoe/fcoe.c
drivers/scsi/hpsa.c
drivers/scsi/isci/host.c
drivers/scsi/isci/host.h
drivers/scsi/isci/init.c
drivers/scsi/isci/phy.c
drivers/scsi/isci/registers.h
drivers/scsi/isci/request.c
drivers/scsi/isci/unsolicited_frame_control.c
drivers/scsi/isci/unsolicited_frame_control.h
drivers/scsi/libfc/fc_exch.c
drivers/scsi/libfc/fc_fcp.c
drivers/scsi/libfc/fc_lport.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_fw.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_inline.h
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mid.c
drivers/scsi/qla2xxx/qla_nx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_version.h
drivers/staging/comedi/drivers/ni_labpc.c
drivers/staging/zcache/zcache-main.c
drivers/target/iscsi/iscsi_target_parameters.c
drivers/target/iscsi/iscsi_target_util.c
drivers/target/target_core_cdb.c
drivers/target/target_core_transport.c
drivers/target/tcm_fc/tcm_fc.h
drivers/target/tcm_fc/tfc_cmd.c
drivers/target/tcm_fc/tfc_conf.c
drivers/target/tcm_fc/tfc_io.c
drivers/tty/serial/crisv10.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-ring.c
drivers/watchdog/hpwdt.c
drivers/watchdog/lantiq_wdt.c
drivers/watchdog/sbc_epx_c3.c
drivers/watchdog/watchdog_dev.c
drivers/xen/events.c
fs/cifs/cifsencrypt.c
fs/cifs/cifsfs.c
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/hfsplus/super.c
fs/hfsplus/wrapper.c
fs/namei.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4proc.c
fs/nfs/nfs4renewd.c
fs/nfs/nfs4state.c
fs/nfs/super.c
fs/nfs/write.c
fs/xfs/xfs_aops.c
include/linux/basic_mmio_gpio.h
include/linux/memcontrol.h
include/linux/mfd/wm8994/pdata.h
include/linux/skbuff.h
include/linux/snmp.h
include/linux/swap.h
include/net/flow.h
include/net/request_sock.h
include/net/sctp/command.h
include/net/tcp.h
include/net/transp_v6.h
kernel/irq/chip.c
kernel/taskstats.c
kernel/tsacct.c
kernel/workqueue.c
lib/sha1.c
mm/filemap.c
mm/memcontrol.c
mm/mempolicy.c
mm/slub.c
mm/vmalloc.c
mm/vmscan.c
mm/vmstat.c
net/bridge/netfilter/Kconfig
net/caif/caif_dev.c
net/can/af_can.c
net/core/dev.c
net/core/flow.c
net/core/skbuff.c
net/ethernet/eth.c
net/ipv4/af_inet.c
net/ipv4/fib_semantics.c
net/ipv4/netfilter/ip_queue.c
net/ipv4/proc.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv6/datagram.c
net/ipv6/ip6_flowlabel.c
net/ipv6/ipv6_sockglue.c
net/ipv6/netfilter/ip6_queue.c
net/ipv6/raw.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/irda/irsysctl.c
net/irda/qos.c
net/mac80211/sta_info.c
net/netfilter/nf_conntrack_pptp.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nfnetlink_queue.c
net/netfilter/xt_rateest.c
net/sched/cls_rsvp.h
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
sound/core/pcm_lib.c
sound/pci/hda/hda_codec.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/blackfin/bf5xx-ad193x.c
sound/soc/fsl/mpc5200_dma.c
sound/soc/imx/imx-pcm-fiq.c
sound/soc/kirkwood/kirkwood-i2s.c
sound/soc/soc-cache.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/soc-jack.c

diff --git a/Documentation/ABI/testing/sysfs-class-scsi_host b/Documentation/ABI/testing/sysfs-class-scsi_host
new file mode 100644 (file)
index 0000000..29a4f89
--- /dev/null
@@ -0,0 +1,13 @@
+What:          /sys/class/scsi_host/hostX/isci_id
+Date:          June 2011
+Contact:       Dave Jiang <dave.jiang@intel.com>
+Description:
+               This file contains the enumerated host ID for the Intel
+               SCU controller. The Intel(R) C600 Series Chipset SATA/SAS
+               Storage Control Unit embeds up to two 4-port controllers in
+               a single PCI device.  The controllers are enumerated in order
+               which usually means the lowest number scsi_host corresponds
+               with the first controller, but this association is not
+               guaranteed.  The 'isci_id' attribute unambiguously identifies
+               the controller index: '0' for the first controller,
+               '1' for the second.
index 6f3c598..06eb6d9 100644 (file)
@@ -380,7 +380,7 @@ will be charged as a new owner of it.
 
 5.2 stat file
 
-5.2.1 memory.stat file includes following statistics
+memory.stat file includes following statistics
 
 # per-memory cgroup local status
 cache          - # of bytes of page cache memory.
@@ -438,89 +438,6 @@ Note:
         file_mapped is accounted only when the memory cgroup is owner of page
         cache.)
 
-5.2.2 memory.vmscan_stat
-
-memory.vmscan_stat includes statistics information for memory scanning and
-freeing, reclaiming. The statistics shows memory scanning information since
-memory cgroup creation and can be reset to 0 by writing 0 as
-
- #echo 0 > ../memory.vmscan_stat
-
-This file contains following statistics.
-
-[param]_[file_or_anon]_pages_by_[reason]_[under_heararchy]
-[param]_elapsed_ns_by_[reason]_[under_hierarchy]
-
-For example,
-
-  scanned_file_pages_by_limit indicates the number of scanned
-  file pages at vmscan.
-
-Now, 3 parameters are supported
-
-  scanned - the number of pages scanned by vmscan
-  rotated - the number of pages activated at vmscan
-  freed   - the number of pages freed by vmscan
-
-If "rotated" is high against scanned/freed, the memcg seems busy.
-
-Now, 2 reason are supported
-
-  limit - the memory cgroup's limit
-  system - global memory pressure + softlimit
-           (global memory pressure not under softlimit is not handled now)
-
-When under_hierarchy is added in the tail, the number indicates the
-total memcg scan of its children and itself.
-
-elapsed_ns is a elapsed time in nanosecond. This may include sleep time
-and not indicates CPU usage. So, please take this as just showing
-latency.
-
-Here is an example.
-
-# cat /cgroup/memory/A/memory.vmscan_stat
-scanned_pages_by_limit 9471864
-scanned_anon_pages_by_limit 6640629
-scanned_file_pages_by_limit 2831235
-rotated_pages_by_limit 4243974
-rotated_anon_pages_by_limit 3971968
-rotated_file_pages_by_limit 272006
-freed_pages_by_limit 2318492
-freed_anon_pages_by_limit 962052
-freed_file_pages_by_limit 1356440
-elapsed_ns_by_limit 351386416101
-scanned_pages_by_system 0
-scanned_anon_pages_by_system 0
-scanned_file_pages_by_system 0
-rotated_pages_by_system 0
-rotated_anon_pages_by_system 0
-rotated_file_pages_by_system 0
-freed_pages_by_system 0
-freed_anon_pages_by_system 0
-freed_file_pages_by_system 0
-elapsed_ns_by_system 0
-scanned_pages_by_limit_under_hierarchy 9471864
-scanned_anon_pages_by_limit_under_hierarchy 6640629
-scanned_file_pages_by_limit_under_hierarchy 2831235
-rotated_pages_by_limit_under_hierarchy 4243974
-rotated_anon_pages_by_limit_under_hierarchy 3971968
-rotated_file_pages_by_limit_under_hierarchy 272006
-freed_pages_by_limit_under_hierarchy 2318492
-freed_anon_pages_by_limit_under_hierarchy 962052
-freed_file_pages_by_limit_under_hierarchy 1356440
-elapsed_ns_by_limit_under_hierarchy 351386416101
-scanned_pages_by_system_under_hierarchy 0
-scanned_anon_pages_by_system_under_hierarchy 0
-scanned_file_pages_by_system_under_hierarchy 0
-rotated_pages_by_system_under_hierarchy 0
-rotated_anon_pages_by_system_under_hierarchy 0
-rotated_file_pages_by_system_under_hierarchy 0
-freed_pages_by_system_under_hierarchy 0
-freed_anon_pages_by_system_under_hierarchy 0
-freed_file_pages_by_system_under_hierarchy 0
-elapsed_ns_by_system_under_hierarchy 0
-
 5.3 swappiness
 
 Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
index 614d038..854ed5c 100644 (file)
@@ -2086,9 +2086,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        Override pmtimer IOPort with a hex value.
                        e.g. pmtmr=0x508
 
-       pnp.debug       [PNP]
-                       Enable PNP debug messages.  This depends on the
-                       CONFIG_PNP_DEBUG_MESSAGES option.
+       pnp.debug=1     [PNP]
+                       Enable PNP debug messages (depends on the
+                       CONFIG_PNP_DEBUG_MESSAGES option).  Change at run-time
+                       via /sys/module/pnp/parameters/debug.  We always show
+                       current resource usage; turning this on also shows
+                       possible settings and some assignment information.
 
        pnpacpi=        [ACPI]
                        { off }
index 8006c22..25320bf 100644 (file)
@@ -1,3 +1,5 @@
+Note: This driver doesn't have a maintainer.
+
 Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver for Linux.
 
 This program is free software; you can redistribute it and/or
@@ -55,7 +57,6 @@ Test and make sure PCI latency is now correct for all cases.
 Authors:
 
 Sten Wang <sten_wang@davicom.com.tw >   : Original Author
-Tobias Ringstrom <tori@unhappy.mine.nu> : Current Maintainer
 
 Contributors:
 
index 28f65c2..ae8820e 100644 (file)
@@ -1278,7 +1278,6 @@ F:        drivers/input/misc/ati_remote2.c
 ATLX ETHERNET DRIVERS
 M:     Jay Cliburn <jcliburn@gmail.com>
 M:     Chris Snook <chris.snook@gmail.com>
-M:     Jie Yang <jie.yang@atheros.com>
 L:     netdev@vger.kernel.org
 W:     http://sourceforge.net/projects/atl1
 W:     http://atl1.sourceforge.net
@@ -1574,7 +1573,6 @@ F:        drivers/scsi/bfa/
 
 BROCADE BNA 10 GIGABIT ETHERNET DRIVER
 M:     Rasesh Mody <rmody@brocade.com>
-M:     Debashis Dutt <ddutt@brocade.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 F:     drivers/net/bna/
@@ -1758,7 +1756,6 @@ F:        Documentation/zh_CN/
 
 CISCO VIC ETHERNET NIC DRIVER
 M:     Christian Benvenuti <benve@cisco.com>
-M:     Vasanthy Kolluri <vkolluri@cisco.com>
 M:     Roopa Prabhu <roprabhu@cisco.com>
 M:     David Wang <dwang2@cisco.com>
 S:     Supported
@@ -3262,6 +3259,17 @@ F:       Documentation/input/multi-touch-protocol.txt
 F:     drivers/input/input-mt.c
 K:     \b(ABS|SYN)_MT_
 
+INTEL C600 SERIES SAS CONTROLLER DRIVER
+M:     Intel SCU Linux support <intel-linux-scu@intel.com>
+M:     Dan Williams <dan.j.williams@intel.com>
+M:     Dave Jiang <dave.jiang@intel.com>
+M:     Ed Nadolski <edmund.nadolski@intel.com>
+L:     linux-scsi@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git
+S:     Maintained
+F:     drivers/scsi/isci/
+F:     firmware/isci/
+
 INTEL IDLE DRIVER
 M:     Len Brown <lenb@kernel.org>
 L:     linux-pm@lists.linux-foundation.org
@@ -4404,7 +4412,8 @@ L:        netfilter@vger.kernel.org
 L:     coreteam@netfilter.org
 W:     http://www.netfilter.org/
 W:     http://www.iptables.org/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next-2.6.git
 S:     Supported
 F:     include/linux/netfilter*
 F:     include/linux/netfilter/
@@ -4774,7 +4783,7 @@ F:        drivers/net/wireless/orinoco/
 
 OSD LIBRARY and FILESYSTEM
 M:     Boaz Harrosh <bharrosh@panasas.com>
-M:     Benny Halevy <bhalevy@panasas.com>
+M:     Benny Halevy <bhalevy@tonian.com>
 L:     osd-dev@open-osd.org
 W:     http://open-osd.org
 T:     git git://git.open-osd.org/open-osd.git
@@ -7200,6 +7209,9 @@ W:        http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices
 S:     Supported
 F:     Documentation/hwmon/wm83??
 F:     drivers/leds/leds-wm83*.c
+F:     drivers/input/misc/wm831x-on.c
+F:     drivers/input/touchscreen/wm831x-ts.c
+F:     drivers/input/touchscreen/wm97*.c
 F:     drivers/mfd/wm8*.c
 F:     drivers/power/wm83*.c
 F:     drivers/rtc/rtc-wm83*.c
@@ -7209,6 +7221,7 @@ F:        drivers/watchdog/wm83*_wdt.c
 F:     include/linux/mfd/wm831x/
 F:     include/linux/mfd/wm8350/
 F:     include/linux/mfd/wm8400*
+F:     include/linux/wm97xx.h
 F:     include/sound/wm????.h
 F:     sound/soc/codecs/wm*
 
index 60cde53..8bb9362 100644 (file)
@@ -51,7 +51,7 @@ config GENERIC_CMOS_UPDATE
         def_bool y
 
 config GENERIC_GPIO
-       def_bool y
+       bool
 
 config ZONE_DMA
        bool
index d31ecf3..21bebe6 100644 (file)
@@ -10,6 +10,10 @@ config CMPXCHG_LOCAL
        bool
        default n
 
+config CMPXCHG_DOUBLE
+       bool
+       default n
+
 source "arch/x86/Kconfig.cpu"
 
 endmenu
index fab8121..c0f712c 100644 (file)
@@ -41,7 +41,7 @@ KBUILD_CPPFLAGS += -I$(srctree)/$(ARCH_DIR)/sys-$(SUBARCH)
 KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
        $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap      \
        -Din6addr_loopback=kernel_in6addr_loopback \
-       -Din6addr_any=kernel_in6addr_any
+       -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr
 
 KBUILD_AFLAGS += $(ARCH_INCLUDE)
 
index d51c404..364c8a1 100644 (file)
@@ -399,8 +399,8 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
  * is done under a spinlock.  Checking whether the device is in use is
  * line->tty->count > 1, also under the spinlock.
  *
- * tty->count serves to decide whether the device should be enabled or
- * disabled on the host.  If it's equal to 1, then we are doing the
+ * line->count serves to decide whether the device should be enabled or
+ * disabled on the host.  If it's equal to 0, then we are doing the
  * first open or last close.  Otherwise, open and close just return.
  */
 
@@ -414,16 +414,16 @@ int line_open(struct line *lines, struct tty_struct *tty)
                goto out_unlock;
 
        err = 0;
-       if (tty->count > 1)
+       if (line->count++)
                goto out_unlock;
 
-       spin_unlock(&line->count_lock);
-
+       BUG_ON(tty->driver_data);
        tty->driver_data = line;
        line->tty = tty;
 
+       spin_unlock(&line->count_lock);
        err = enable_chan(line);
-       if (err)
+       if (err) /* line_close() will be called by our caller */
                return err;
 
        INIT_DELAYED_WORK(&line->task, line_timer_cb);
@@ -436,7 +436,7 @@ int line_open(struct line *lines, struct tty_struct *tty)
        chan_window_size(&line->chan_list, &tty->winsize.ws_row,
                         &tty->winsize.ws_col);
 
-       return err;
+       return 0;
 
 out_unlock:
        spin_unlock(&line->count_lock);
@@ -460,17 +460,16 @@ void line_close(struct tty_struct *tty, struct file * filp)
        flush_buffer(line);
 
        spin_lock(&line->count_lock);
-       if (!line->valid)
-               goto out_unlock;
+       BUG_ON(!line->valid);
 
-       if (tty->count > 1)
+       if (--line->count)
                goto out_unlock;
 
-       spin_unlock(&line->count_lock);
-
        line->tty = NULL;
        tty->driver_data = NULL;
 
+       spin_unlock(&line->count_lock);
+
        if (line->sigio) {
                unregister_winch(tty);
                line->sigio = 0;
@@ -498,7 +497,7 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio,
 
        spin_lock(&line->count_lock);
 
-       if (line->tty != NULL) {
+       if (line->count) {
                *error_out = "Device is already open";
                goto out;
        }
@@ -722,41 +721,53 @@ struct winch {
        int pid;
        struct tty_struct *tty;
        unsigned long stack;
+       struct work_struct work;
 };
 
-static void free_winch(struct winch *winch, int free_irq_ok)
+static void __free_winch(struct work_struct *work)
 {
-       if (free_irq_ok)
-               free_irq(WINCH_IRQ, winch);
-
-       list_del(&winch->list);
+       struct winch *winch = container_of(work, struct winch, work);
+       free_irq(WINCH_IRQ, winch);
 
        if (winch->pid != -1)
                os_kill_process(winch->pid, 1);
-       if (winch->fd != -1)
-               os_close_file(winch->fd);
        if (winch->stack != 0)
                free_stack(winch->stack, 0);
        kfree(winch);
 }
 
+static void free_winch(struct winch *winch)
+{
+       int fd = winch->fd;
+       winch->fd = -1;
+       if (fd != -1)
+               os_close_file(fd);
+       list_del(&winch->list);
+       __free_winch(&winch->work);
+}
+
 static irqreturn_t winch_interrupt(int irq, void *data)
 {
        struct winch *winch = data;
        struct tty_struct *tty;
        struct line *line;
+       int fd = winch->fd;
        int err;
        char c;
 
-       if (winch->fd != -1) {
-               err = generic_read(winch->fd, &c, NULL);
+       if (fd != -1) {
+               err = generic_read(fd, &c, NULL);
                if (err < 0) {
                        if (err != -EAGAIN) {
+                               winch->fd = -1;
+                               list_del(&winch->list);
+                               os_close_file(fd);
                                printk(KERN_ERR "winch_interrupt : "
                                       "read failed, errno = %d\n", -err);
                                printk(KERN_ERR "fd %d is losing SIGWINCH "
                                       "support\n", winch->tty_fd);
-                               free_winch(winch, 0);
+                               INIT_WORK(&winch->work, __free_winch);
+                               schedule_work(&winch->work);
                                return IRQ_HANDLED;
                        }
                        goto out;
@@ -828,7 +839,7 @@ static void unregister_winch(struct tty_struct *tty)
        list_for_each_safe(ele, next, &winch_handlers) {
                winch = list_entry(ele, struct winch, list);
                if (winch->tty == tty) {
-                       free_winch(winch, 1);
+                       free_winch(winch);
                        break;
                }
        }
@@ -844,7 +855,7 @@ static void winch_cleanup(void)
 
        list_for_each_safe(ele, next, &winch_handlers) {
                winch = list_entry(ele, struct winch, list);
-               free_winch(winch, 1);
+               free_winch(winch);
        }
 
        spin_unlock(&winch_handler_lock);
index 8ac7146..2e1de57 100644 (file)
@@ -123,6 +123,7 @@ static int xterm_open(int input, int output, int primary, void *d,
                err = -errno;
                printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n",
                       errno);
+               close(fd);
                return err;
        }
        close(fd);
index ae084ad..1a7d275 100644 (file)
@@ -42,10 +42,6 @@ extern long subarch_ptrace(struct task_struct *child, long request,
        unsigned long addr, unsigned long data);
 extern unsigned long getreg(struct task_struct *child, int regno);
 extern int putreg(struct task_struct *child, int regno, unsigned long value);
-extern int get_fpregs(struct user_i387_struct __user *buf,
-                     struct task_struct *child);
-extern int set_fpregs(struct user_i387_struct __user *buf,
-                     struct task_struct *child);
 
 extern int arch_copy_tls(struct task_struct *new);
 extern void clear_flushed_tls(struct task_struct *task);
index 72f4f25..63df3ca 100644 (file)
@@ -33,6 +33,7 @@ struct line_driver {
 struct line {
        struct tty_struct *tty;
        spinlock_t count_lock;
+       unsigned long count;
        int valid;
 
        char *init_str;
index b0b4589..f1e0aa5 100644 (file)
@@ -16,7 +16,7 @@ extern int restore_fpx_registers(int pid, unsigned long *fp_regs);
 extern int save_registers(int pid, struct uml_pt_regs *regs);
 extern int restore_registers(int pid, struct uml_pt_regs *regs);
 extern int init_registers(int pid);
-extern void get_safe_registers(unsigned long *regs);
+extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs);
 extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
 extern int get_fp_registers(int pid, unsigned long *regs);
 extern int put_fp_registers(int pid, unsigned long *regs);
index fab4371..21c1ae7 100644 (file)
@@ -202,7 +202,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
                arch_copy_thread(&current->thread.arch, &p->thread.arch);
        }
        else {
-               get_safe_registers(p->thread.regs.regs.gp);
+               get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
                p->thread.request.u.thread = current->thread.request.u.thread;
                handler = new_thread_handler;
        }
index 701b672..c9da32b 100644 (file)
@@ -50,23 +50,11 @@ long arch_ptrace(struct task_struct *child, long request,
        void __user *vp = p;
 
        switch (request) {
-       /* read word at location addr. */
-       case PTRACE_PEEKTEXT:
-       case PTRACE_PEEKDATA:
-               ret = generic_ptrace_peekdata(child, addr, data);
-               break;
-
        /* read the word at location addr in the USER area. */
        case PTRACE_PEEKUSR:
                ret = peek_user(child, addr, data);
                break;
 
-       /* write the word at location addr. */
-       case PTRACE_POKETEXT:
-       case PTRACE_POKEDATA:
-               ret = generic_ptrace_pokedata(child, addr, data);
-               break;
-
        /* write the word at location addr in the USER area */
        case PTRACE_POKEUSR:
                ret = poke_user(child, addr, data);
@@ -107,16 +95,6 @@ long arch_ptrace(struct task_struct *child, long request,
                break;
        }
 #endif
-#ifdef PTRACE_GETFPREGS
-       case PTRACE_GETFPREGS: /* Get the child FPU state. */
-               ret = get_fpregs(vp, child);
-               break;
-#endif
-#ifdef PTRACE_SETFPREGS
-       case PTRACE_SETFPREGS: /* Set the child FPU state. */
-               ret = set_fpregs(vp, child);
-               break;
-#endif
        case PTRACE_GET_THREAD_AREA:
                ret = ptrace_get_thread_area(child, addr, vp);
                break;
@@ -154,12 +132,6 @@ long arch_ptrace(struct task_struct *child, long request,
                break;
        }
 #endif
-#ifdef PTRACE_ARCH_PRCTL
-       case PTRACE_ARCH_PRCTL:
-               /* XXX Calls ptrace on the host - needs some SMP thinking */
-               ret = arch_prctl(child, data, (void __user *) addr);
-               break;
-#endif
        default:
                ret = ptrace_request(child, request, addr, data);
                if (ret == -EIO)
index 830fe6a..b866b9e 100644 (file)
@@ -8,6 +8,8 @@
 #include <string.h>
 #include <sys/ptrace.h>
 #include "sysdep/ptrace.h"
+#include "sysdep/ptrace_user.h"
+#include "registers.h"
 
 int save_registers(int pid, struct uml_pt_regs *regs)
 {
@@ -32,6 +34,7 @@ int restore_registers(int pid, struct uml_pt_regs *regs)
 /* This is set once at boot time and not changed thereafter */
 
 static unsigned long exec_regs[MAX_REG_NR];
+static unsigned long exec_fp_regs[FP_SIZE];
 
 int init_registers(int pid)
 {
@@ -42,10 +45,14 @@ int init_registers(int pid)
                return -errno;
 
        arch_init_registers(pid);
+       get_fp_registers(pid, exec_fp_regs);
        return 0;
 }
 
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
 {
        memcpy(regs, exec_regs, sizeof(exec_regs));
+
+       if (fp_regs)
+               memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs));
 }
index d261f17..e771398 100644 (file)
@@ -39,7 +39,7 @@ static unsigned long syscall_regs[MAX_REG_NR];
 
 static int __init init_syscall_regs(void)
 {
-       get_safe_registers(syscall_regs);
+       get_safe_registers(syscall_regs, NULL);
        syscall_regs[REGS_IP_INDEX] = STUB_CODE +
                ((unsigned long) &batch_syscall_stub -
                 (unsigned long) &__syscall_stub_start);
index d6e0a22..dee0e8c 100644 (file)
@@ -373,6 +373,9 @@ void userspace(struct uml_pt_regs *regs)
                if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp))
                        fatal_sigsegv();
 
+               if (put_fp_registers(pid, regs->fp))
+                       fatal_sigsegv();
+
                /* Now we set local_using_sysemu to be used for one loop */
                local_using_sysemu = get_using_sysemu();
 
@@ -399,6 +402,12 @@ void userspace(struct uml_pt_regs *regs)
                        fatal_sigsegv();
                }
 
+               if (get_fp_registers(pid, regs->fp)) {
+                       printk(UM_KERN_ERR "userspace -  get_fp_registers failed, "
+                              "errno = %d\n", errno);
+                       fatal_sigsegv();
+               }
+
                UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
 
                if (WIFSTOPPED(status)) {
@@ -457,10 +466,11 @@ void userspace(struct uml_pt_regs *regs)
 }
 
 static unsigned long thread_regs[MAX_REG_NR];
+static unsigned long thread_fp_regs[FP_SIZE];
 
 static int __init init_thread_regs(void)
 {
-       get_safe_registers(thread_regs);
+       get_safe_registers(thread_regs, thread_fp_regs);
        /* Set parent's instruction pointer to start of clone-stub */
        thread_regs[REGS_IP_INDEX] = STUB_CODE +
                                (unsigned long) stub_clone_handler -
@@ -503,6 +513,13 @@ int copy_context_skas0(unsigned long new_stack, int pid)
                return err;
        }
 
+       err = put_fp_registers(pid, thread_fp_regs);
+       if (err < 0) {
+               printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers "
+                      "failed, pid = %d, err = %d\n", pid, err);
+               return err;
+       }
+
        /* set a well known return code for detection of child write failure */
        child_data->err = 12345678;
 
index 0273e4d..5d2a591 100644 (file)
  */
 struct user_desc;
 
-extern int get_fpxregs(struct user_fxsr_struct __user *buf,
-                      struct task_struct *child);
-extern int set_fpxregs(struct user_fxsr_struct __user *buf,
-                      struct task_struct *tsk);
-
 extern int ptrace_get_thread_area(struct task_struct *child, int idx,
                                   struct user_desc __user *user_desc);
 
index d23b2d3..3375c27 100644 (file)
@@ -145,7 +145,7 @@ int peek_user(struct task_struct *child, long addr, long data)
        return put_user(tmp, (unsigned long __user *) data);
 }
 
-int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
+static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
 {
        int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
        struct user_i387_struct fpregs;
@@ -161,7 +161,7 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
        return n;
 }
 
-int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
+static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
 {
        int n, cpu = ((struct thread_info *) child->stack)->cpu;
        struct user_i387_struct fpregs;
@@ -174,7 +174,7 @@ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
                                    (unsigned long *) &fpregs);
 }
 
-int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
+static int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
 {
        int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
        struct user_fxsr_struct fpregs;
@@ -190,7 +190,7 @@ int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
        return n;
 }
 
-int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
+static int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
 {
        int n, cpu = ((struct thread_info *) child->stack)->cpu;
        struct user_fxsr_struct fpregs;
@@ -206,5 +206,23 @@ int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
 long subarch_ptrace(struct task_struct *child, long request,
                    unsigned long addr, unsigned long data)
 {
-       return -EIO;
+       int ret = -EIO;
+       void __user *datap = (void __user *) data;
+       switch (request) {
+       case PTRACE_GETFPREGS: /* Get the child FPU state. */
+               ret = get_fpregs(datap, child);
+               break;
+       case PTRACE_SETFPREGS: /* Set the child FPU state. */
+               ret = set_fpregs(datap, child);
+               break;
+       case PTRACE_GETFPXREGS: /* Get the child FPU state. */
+               ret = get_fpxregs(datap, child);
+               break;
+       case PTRACE_SETFPXREGS: /* Set the child FPU state. */
+               ret = set_fpxregs(datap, child);
+               break;
+       default:
+               ret = -EIO;
+       }
+       return ret;
 }
index d50e62e..c398a50 100644 (file)
@@ -53,6 +53,7 @@ extern int sysemu_supported;
 
 struct uml_pt_regs {
        unsigned long gp[MAX_REG_NR];
+       unsigned long fp[HOST_FPX_SIZE];
        struct faultinfo faultinfo;
        long syscall;
        int is_user;
index f436136..4005506 100644 (file)
@@ -145,7 +145,7 @@ int is_syscall(unsigned long addr)
        return instr == 0x050f;
 }
 
-int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
+static int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
 {
        int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
        long fpregs[HOST_FP_SIZE];
@@ -162,7 +162,7 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
        return n;
 }
 
-int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
+static int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
 {
        int n, cpu = ((struct thread_info *) child->stack)->cpu;
        long fpregs[HOST_FP_SIZE];
@@ -182,12 +182,16 @@ long subarch_ptrace(struct task_struct *child, long request,
        void __user *datap = (void __user *) data;
 
        switch (request) {
-       case PTRACE_GETFPXREGS: /* Get the child FPU state. */
+       case PTRACE_GETFPREGS: /* Get the child FPU state. */
                ret = get_fpregs(datap, child);
                break;
-       case PTRACE_SETFPXREGS: /* Set the child FPU state. */
+       case PTRACE_SETFPREGS: /* Set the child FPU state. */
                ret = set_fpregs(datap, child);
                break;
+       case PTRACE_ARCH_PRCTL:
+               /* XXX Calls ptrace on the host - needs some SMP thinking */
+               ret = arch_prctl(child, data, (void __user *) addr);
+               break;
        }
 
        return ret;
index fdba545..8ee8f8e 100644 (file)
@@ -85,6 +85,7 @@
 
 struct uml_pt_regs {
        unsigned long gp[MAX_REG_NR];
+       unsigned long fp[HOST_FP_SIZE];
        struct faultinfo faultinfo;
        long syscall;
        int is_user;
index 4554cc6..091508b 100644 (file)
@@ -16,7 +16,6 @@
 #endif
 
 .macro altinstruction_entry orig alt feature orig_len alt_len
-       .align 8
        .long \orig - .
        .long \alt - .
        .word \feature
index 23fb6d7..37ad100 100644 (file)
@@ -48,9 +48,6 @@ struct alt_instr {
        u16 cpuid;              /* cpuid bit set for replacement */
        u8  instrlen;           /* length of original instruction */
        u8  replacementlen;     /* length of new instruction, <= instrlen */
-#ifdef CONFIG_X86_64
-       u32 pad2;
-#endif
 };
 
 extern void alternative_instructions(void);
@@ -83,7 +80,6 @@ static inline int alternatives_text_reserved(void *start, void *end)
                                                                        \
       "661:\n\t" oldinstr "\n662:\n"                                   \
       ".section .altinstructions,\"a\"\n"                              \
-      _ASM_ALIGN "\n"                                                  \
       "         .long 661b - .\n"                      /* label           */   \
       "         .long 663f - .\n"                      /* new instruction */   \
       "         .word " __stringify(feature) "\n"      /* feature bit     */   \
index 4258aac..88b23a4 100644 (file)
@@ -332,7 +332,6 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
                asm goto("1: jmp %l[t_no]\n"
                         "2:\n"
                         ".section .altinstructions,\"a\"\n"
-                        _ASM_ALIGN "\n"
                         " .long 1b - .\n"
                         " .long 0\n"           /* no replacement */
                         " .word %P0\n"         /* feature bit */
@@ -350,7 +349,6 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
                asm volatile("1: movb $0,%0\n"
                             "2:\n"
                             ".section .altinstructions,\"a\"\n"
-                            _ASM_ALIGN "\n"
                             " .long 1b - .\n"
                             " .long 3f - .\n"
                             " .word %P1\n"             /* feature bit */
index 20a6142..3dd53f9 100644 (file)
@@ -1721,10 +1721,8 @@ void __init xen_setup_machphys_mapping(void)
                machine_to_phys_nr = MACH2PHYS_NR_ENTRIES;
        }
 #ifdef CONFIG_X86_32
-       if ((machine_to_phys_mapping + machine_to_phys_nr)
-           < machine_to_phys_mapping)
-               machine_to_phys_nr = (unsigned long *)NULL
-                                    - machine_to_phys_mapping;
+       WARN_ON((machine_to_phys_mapping + (machine_to_phys_nr - 1))
+               < machine_to_phys_mapping);
 #endif
 }
 
index c3b8d44..46d6d21 100644 (file)
@@ -306,10 +306,12 @@ char * __init xen_memory_setup(void)
        sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
 
        extra_limit = xen_get_max_pages();
-       if (extra_limit >= max_pfn)
-               extra_pages = extra_limit - max_pfn;
-       else
-               extra_pages = 0;
+       if (max_pfn + extra_pages > extra_limit) {
+               if (extra_limit > max_pfn)
+                       extra_pages = extra_limit - max_pfn;
+               else
+                       extra_pages = 0;
+       }
 
        extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820);
 
index d4fc6d4..041d4fe 100644 (file)
@@ -532,7 +532,6 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus)
        WARN_ON(xen_smp_intr_init(0));
 
        xen_init_lock_cpu(0);
-       xen_init_spinlocks();
 }
 
 static int __cpuinit xen_hvm_cpu_up(unsigned int cpu)
index 5158c50..163b467 100644 (file)
@@ -168,9 +168,10 @@ cycle_t xen_clocksource_read(void)
         struct pvclock_vcpu_time_info *src;
        cycle_t ret;
 
-       src = &get_cpu_var(xen_vcpu)->time;
+       preempt_disable_notrace();
+       src = &__get_cpu_var(xen_vcpu)->time;
        ret = pvclock_clocksource_read(src);
-       put_cpu_var(xen_vcpu);
+       preempt_enable_notrace();
        return ret;
 }
 
index bc533dd..f895a24 100644 (file)
 
 /* Maximum sleep allowed via Sleep() operator */
 
-#define ACPI_MAX_SLEEP                  20000  /* Two seconds */
+#define ACPI_MAX_SLEEP                  2000   /* Two seconds */
 
 /******************************************************************************
  *
index c34aa51..e3f4787 100644 (file)
@@ -13,6 +13,7 @@ config ACPI_APEI_GHES
        bool "APEI Generic Hardware Error Source"
        depends on ACPI_APEI && X86
        select ACPI_HED
+       select IRQ_WORK
        select LLIST
        select GENERIC_ALLOCATOR
        help
index 8041248..6154036 100644 (file)
@@ -618,7 +618,7 @@ int apei_osc_setup(void)
        };
 
        capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
-       capbuf[OSC_SUPPORT_TYPE] = 0;
+       capbuf[OSC_SUPPORT_TYPE] = 1;
        capbuf[OSC_CONTROL_TYPE] = 0;
 
        if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))
index 7b0603e..cdc02ac 100644 (file)
@@ -261,6 +261,9 @@ static int pcc_get_offset(int cpu)
        pr = per_cpu(processors, cpu);
        pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
 
+       if (!pr)
+               return -ENODEV;
+
        status = acpi_evaluate_object(pr->handle, "PCCP", NULL, &buffer);
        if (ACPI_FAILURE(status))
                return -ENODEV;
index 57cd3a4..fd7170a 100644 (file)
@@ -290,6 +290,9 @@ static const struct {
        {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID,
                QUIRK_CYCLE_TIMER},
 
+       {PCI_VENDOR_ID_O2, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_NO_MSI},
+
        {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID,
                QUIRK_CYCLE_TIMER},
 
index 231714d..4e24436 100644 (file)
@@ -351,7 +351,7 @@ static int bgpio_setup_direction(struct bgpio_chip *bgc,
        return 0;
 }
 
-int __devexit bgpio_remove(struct bgpio_chip *bgc)
+int bgpio_remove(struct bgpio_chip *bgc)
 {
        int err = gpiochip_remove(&bgc->gc);
 
@@ -361,15 +361,10 @@ int __devexit bgpio_remove(struct bgpio_chip *bgc)
 }
 EXPORT_SYMBOL_GPL(bgpio_remove);
 
-int __devinit bgpio_init(struct bgpio_chip *bgc,
-                        struct device *dev,
-                        unsigned long sz,
-                        void __iomem *dat,
-                        void __iomem *set,
-                        void __iomem *clr,
-                        void __iomem *dirout,
-                        void __iomem *dirin,
-                        bool big_endian)
+int bgpio_init(struct bgpio_chip *bgc, struct device *dev,
+              unsigned long sz, void __iomem *dat, void __iomem *set,
+              void __iomem *clr, void __iomem *dirout, void __iomem *dirin,
+              bool big_endian)
 {
        int ret;
 
index dc0a5b5..e8a7467 100644 (file)
@@ -1404,7 +1404,8 @@ int evergreen_cp_resume(struct radeon_device *rdev)
        /* Initialize the ring buffer's read and write pointers */
        WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
        WREG32(CP_RB_RPTR_WR, 0);
-       WREG32(CP_RB_WPTR, 0);
+       rdev->cp.wptr = 0;
+       WREG32(CP_RB_WPTR, rdev->cp.wptr);
 
        /* set the wb address wether it's enabled or not */
        WREG32(CP_RB_RPTR_ADDR,
@@ -1426,7 +1427,6 @@ int evergreen_cp_resume(struct radeon_device *rdev)
        WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
 
        rdev->cp.rptr = RREG32(CP_RB_RPTR);
-       rdev->cp.wptr = RREG32(CP_RB_WPTR);
 
        evergreen_cp_start(rdev);
        rdev->cp.ready = true;
@@ -3171,21 +3171,23 @@ int evergreen_suspend(struct radeon_device *rdev)
 }
 
 int evergreen_copy_blit(struct radeon_device *rdev,
-                       uint64_t src_offset, uint64_t dst_offset,
-                       unsigned num_pages, struct radeon_fence *fence)
+                       uint64_t src_offset,
+                       uint64_t dst_offset,
+                       unsigned num_gpu_pages,
+                       struct radeon_fence *fence)
 {
        int r;
 
        mutex_lock(&rdev->r600_blit.mutex);
        rdev->r600_blit.vb_ib = NULL;
-       r = evergreen_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE);
+       r = evergreen_blit_prepare_copy(rdev, num_gpu_pages * RADEON_GPU_PAGE_SIZE);
        if (r) {
                if (rdev->r600_blit.vb_ib)
                        radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
                mutex_unlock(&rdev->r600_blit.mutex);
                return r;
        }
-       evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE);
+       evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages * RADEON_GPU_PAGE_SIZE);
        evergreen_blit_done_copy(rdev, fence);
        mutex_unlock(&rdev->r600_blit.mutex);
        return 0;
index cbf57d7..99fbd79 100644 (file)
@@ -1187,7 +1187,8 @@ int cayman_cp_resume(struct radeon_device *rdev)
 
        /* Initialize the ring buffer's read and write pointers */
        WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
-       WREG32(CP_RB0_WPTR, 0);
+       rdev->cp.wptr = 0;
+       WREG32(CP_RB0_WPTR, rdev->cp.wptr);
 
        /* set the wb address wether it's enabled or not */
        WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
@@ -1207,7 +1208,6 @@ int cayman_cp_resume(struct radeon_device *rdev)
        WREG32(CP_RB0_BASE, rdev->cp.gpu_addr >> 8);
 
        rdev->cp.rptr = RREG32(CP_RB0_RPTR);
-       rdev->cp.wptr = RREG32(CP_RB0_WPTR);
 
        /* ring1  - compute only */
        /* Set ring buffer size */
@@ -1220,7 +1220,8 @@ int cayman_cp_resume(struct radeon_device *rdev)
 
        /* Initialize the ring buffer's read and write pointers */
        WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
-       WREG32(CP_RB1_WPTR, 0);
+       rdev->cp1.wptr = 0;
+       WREG32(CP_RB1_WPTR, rdev->cp1.wptr);
 
        /* set the wb address wether it's enabled or not */
        WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC);
@@ -1232,7 +1233,6 @@ int cayman_cp_resume(struct radeon_device *rdev)
        WREG32(CP_RB1_BASE, rdev->cp1.gpu_addr >> 8);
 
        rdev->cp1.rptr = RREG32(CP_RB1_RPTR);
-       rdev->cp1.wptr = RREG32(CP_RB1_WPTR);
 
        /* ring2 - compute only */
        /* Set ring buffer size */
@@ -1245,7 +1245,8 @@ int cayman_cp_resume(struct radeon_device *rdev)
 
        /* Initialize the ring buffer's read and write pointers */
        WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA);
-       WREG32(CP_RB2_WPTR, 0);
+       rdev->cp2.wptr = 0;
+       WREG32(CP_RB2_WPTR, rdev->cp2.wptr);
 
        /* set the wb address wether it's enabled or not */
        WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC);
@@ -1257,7 +1258,6 @@ int cayman_cp_resume(struct radeon_device *rdev)
        WREG32(CP_RB2_BASE, rdev->cp2.gpu_addr >> 8);
 
        rdev->cp2.rptr = RREG32(CP_RB2_RPTR);
-       rdev->cp2.wptr = RREG32(CP_RB2_WPTR);
 
        /* start the rings */
        cayman_cp_start(rdev);
index f2204cb..5b1837b 100644 (file)
@@ -721,11 +721,11 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
 int r100_copy_blit(struct radeon_device *rdev,
                   uint64_t src_offset,
                   uint64_t dst_offset,
-                  unsigned num_pages,
+                  unsigned num_gpu_pages,
                   struct radeon_fence *fence)
 {
        uint32_t cur_pages;
-       uint32_t stride_bytes = PAGE_SIZE;
+       uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE;
        uint32_t pitch;
        uint32_t stride_pixels;
        unsigned ndw;
@@ -737,7 +737,7 @@ int r100_copy_blit(struct radeon_device *rdev,
        /* radeon pitch is /64 */
        pitch = stride_bytes / 64;
        stride_pixels = stride_bytes / 4;
-       num_loops = DIV_ROUND_UP(num_pages, 8191);
+       num_loops = DIV_ROUND_UP(num_gpu_pages, 8191);
 
        /* Ask for enough room for blit + flush + fence */
        ndw = 64 + (10 * num_loops);
@@ -746,12 +746,12 @@ int r100_copy_blit(struct radeon_device *rdev,
                DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw);
                return -EINVAL;
        }
-       while (num_pages > 0) {
-               cur_pages = num_pages;
+       while (num_gpu_pages > 0) {
+               cur_pages = num_gpu_pages;
                if (cur_pages > 8191) {
                        cur_pages = 8191;
                }
-               num_pages -= cur_pages;
+               num_gpu_pages -= cur_pages;
 
                /* pages are in Y direction - height
                   page width in X direction - width */
@@ -773,8 +773,8 @@ int r100_copy_blit(struct radeon_device *rdev,
                radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16));
                radeon_ring_write(rdev, 0);
                radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16));
-               radeon_ring_write(rdev, num_pages);
-               radeon_ring_write(rdev, num_pages);
+               radeon_ring_write(rdev, cur_pages);
+               radeon_ring_write(rdev, cur_pages);
                radeon_ring_write(rdev, cur_pages | (stride_pixels << 16));
        }
        radeon_ring_write(rdev, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0));
@@ -990,7 +990,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
        /* Force read & write ptr to 0 */
        WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE);
        WREG32(RADEON_CP_RB_RPTR_WR, 0);
-       WREG32(RADEON_CP_RB_WPTR, 0);
+       rdev->cp.wptr = 0;
+       WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr);
 
        /* set the wb address whether it's enabled or not */
        WREG32(R_00070C_CP_RB_RPTR_ADDR,
@@ -1007,9 +1008,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
        WREG32(RADEON_CP_RB_CNTL, tmp);
        udelay(10);
        rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
-       rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR);
-       /* protect against crazy HW on resume */
-       rdev->cp.wptr &= rdev->cp.ptr_mask;
        /* Set cp mode to bus mastering & enable cp*/
        WREG32(RADEON_CP_CSQ_MODE,
               REG_SET(RADEON_INDIRECT2_START, indirect2_start) |
index f240583..a1f3ba0 100644 (file)
@@ -84,7 +84,7 @@ static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
 int r200_copy_dma(struct radeon_device *rdev,
                  uint64_t src_offset,
                  uint64_t dst_offset,
-                 unsigned num_pages,
+                 unsigned num_gpu_pages,
                  struct radeon_fence *fence)
 {
        uint32_t size;
@@ -93,7 +93,7 @@ int r200_copy_dma(struct radeon_device *rdev,
        int r = 0;
 
        /* radeon pitch is /64 */
-       size = num_pages << PAGE_SHIFT;
+       size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT;
        num_loops = DIV_ROUND_UP(size, 0x1FFFFF);
        r = radeon_ring_lock(rdev, num_loops * 4 + 64);
        if (r) {
index aa5571b..720dd99 100644 (file)
@@ -2209,7 +2209,8 @@ int r600_cp_resume(struct radeon_device *rdev)
        /* Initialize the ring buffer's read and write pointers */
        WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
        WREG32(CP_RB_RPTR_WR, 0);
-       WREG32(CP_RB_WPTR, 0);
+       rdev->cp.wptr = 0;
+       WREG32(CP_RB_WPTR, rdev->cp.wptr);
 
        /* set the wb address whether it's enabled or not */
        WREG32(CP_RB_RPTR_ADDR,
@@ -2231,7 +2232,6 @@ int r600_cp_resume(struct radeon_device *rdev)
        WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
 
        rdev->cp.rptr = RREG32(CP_RB_RPTR);
-       rdev->cp.wptr = RREG32(CP_RB_WPTR);
 
        r600_cp_start(rdev);
        rdev->cp.ready = true;
@@ -2353,21 +2353,23 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
 }
 
 int r600_copy_blit(struct radeon_device *rdev,
-                  uint64_t src_offset, uint64_t dst_offset,
-                  unsigned num_pages, struct radeon_fence *fence)
+                  uint64_t src_offset,
+                  uint64_t dst_offset,
+                  unsigned num_gpu_pages,
+                  struct radeon_fence *fence)
 {
        int r;
 
        mutex_lock(&rdev->r600_blit.mutex);
        rdev->r600_blit.vb_ib = NULL;
-       r = r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE);
+       r = r600_blit_prepare_copy(rdev, num_gpu_pages * RADEON_GPU_PAGE_SIZE);
        if (r) {
                if (rdev->r600_blit.vb_ib)
                        radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
                mutex_unlock(&rdev->r600_blit.mutex);
                return r;
        }
-       r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE);
+       r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages * RADEON_GPU_PAGE_SIZE);
        r600_blit_done_copy(rdev, fence);
        mutex_unlock(&rdev->r600_blit.mutex);
        return 0;
index 32807ba..c1e056b 100644 (file)
@@ -322,6 +322,7 @@ union radeon_gart_table {
 
 #define RADEON_GPU_PAGE_SIZE 4096
 #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1)
+#define RADEON_GPU_PAGE_SHIFT 12
 
 struct radeon_gart {
        dma_addr_t                      table_addr;
@@ -914,17 +915,17 @@ struct radeon_asic {
        int (*copy_blit)(struct radeon_device *rdev,
                         uint64_t src_offset,
                         uint64_t dst_offset,
-                        unsigned num_pages,
+                        unsigned num_gpu_pages,
                         struct radeon_fence *fence);
        int (*copy_dma)(struct radeon_device *rdev,
                        uint64_t src_offset,
                        uint64_t dst_offset,
-                       unsigned num_pages,
+                       unsigned num_gpu_pages,
                        struct radeon_fence *fence);
        int (*copy)(struct radeon_device *rdev,
                    uint64_t src_offset,
                    uint64_t dst_offset,
-                   unsigned num_pages,
+                   unsigned num_gpu_pages,
                    struct radeon_fence *fence);
        uint32_t (*get_engine_clock)(struct radeon_device *rdev);
        void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock);
index 3d7a0d7..3dedaa0 100644 (file)
@@ -75,7 +75,7 @@ uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg);
 int r100_copy_blit(struct radeon_device *rdev,
                   uint64_t src_offset,
                   uint64_t dst_offset,
-                  unsigned num_pages,
+                  unsigned num_gpu_pages,
                   struct radeon_fence *fence);
 int r100_set_surface_reg(struct radeon_device *rdev, int reg,
                         uint32_t tiling_flags, uint32_t pitch,
@@ -143,7 +143,7 @@ extern void r100_post_page_flip(struct radeon_device *rdev, int crtc);
 extern int r200_copy_dma(struct radeon_device *rdev,
                         uint64_t src_offset,
                         uint64_t dst_offset,
-                        unsigned num_pages,
+                        unsigned num_gpu_pages,
                         struct radeon_fence *fence);
 void r200_set_safe_registers(struct radeon_device *rdev);
 
@@ -311,7 +311,7 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
 int r600_ring_test(struct radeon_device *rdev);
 int r600_copy_blit(struct radeon_device *rdev,
                   uint64_t src_offset, uint64_t dst_offset,
-                  unsigned num_pages, struct radeon_fence *fence);
+                  unsigned num_gpu_pages, struct radeon_fence *fence);
 void r600_hpd_init(struct radeon_device *rdev);
 void r600_hpd_fini(struct radeon_device *rdev);
 bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
@@ -403,7 +403,7 @@ void evergreen_bandwidth_update(struct radeon_device *rdev);
 void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
 int evergreen_copy_blit(struct radeon_device *rdev,
                        uint64_t src_offset, uint64_t dst_offset,
-                       unsigned num_pages, struct radeon_fence *fence);
+                       unsigned num_gpu_pages, struct radeon_fence *fence);
 void evergreen_hpd_init(struct radeon_device *rdev);
 void evergreen_hpd_fini(struct radeon_device *rdev);
 bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
index 6cc17fb..6adb3e5 100644 (file)
@@ -473,8 +473,8 @@ pflip_cleanup:
        spin_lock_irqsave(&dev->event_lock, flags);
        radeon_crtc->unpin_work = NULL;
 unlock_free:
-       drm_gem_object_unreference_unlocked(old_radeon_fb->obj);
        spin_unlock_irqrestore(&dev->event_lock, flags);
+       drm_gem_object_unreference_unlocked(old_radeon_fb->obj);
        radeon_fence_unref(&work->fence);
        kfree(work);
 
index 9b86fb0..0b5468b 100644 (file)
@@ -277,7 +277,12 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
                DRM_ERROR("Trying to move memory with CP turned off.\n");
                return -EINVAL;
        }
-       r = radeon_copy(rdev, old_start, new_start, new_mem->num_pages, fence);
+
+       BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0);
+
+       r = radeon_copy(rdev, old_start, new_start,
+                       new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */
+                       fence);
        /* FIXME: handle copy error */
        r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL,
                                      evict, no_wait_reserve, no_wait_gpu, new_mem);
index a4d38d8..ef06194 100644 (file)
@@ -394,7 +394,8 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
 
        if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) {
                if (bo->ttm == NULL) {
-                       ret = ttm_bo_add_ttm(bo, false);
+                       bool zero = !(old_man->flags & TTM_MEMTYPE_FLAG_FIXED);
+                       ret = ttm_bo_add_ttm(bo, zero);
                        if (ret)
                                goto out_err;
                }
index a597039..72ca689 100644 (file)
@@ -373,6 +373,8 @@ static int wacom_probe(struct hid_device *hdev,
        hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
        input = hidinput->input;
 
+       __set_bit(INPUT_PROP_POINTER, input->propbit);
+
        /* Basics */
        input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL);
 
index 59d83e8..4112576 100644 (file)
@@ -601,7 +601,12 @@ static int create_core_data(struct platform_data *pdata,
        err = rdmsr_safe_on_cpu(cpu, tdata->intrpt_reg, &eax, &edx);
        if (!err) {
                tdata->attr_size += MAX_THRESH_ATTRS;
-               tdata->ttarget = tdata->tjmax - ((eax >> 16) & 0x7f) * 1000;
+               tdata->tmin = tdata->tjmax -
+                             ((eax & THERM_MASK_THRESHOLD0) >>
+                              THERM_SHIFT_THRESHOLD0) * 1000;
+               tdata->ttarget = tdata->tjmax -
+                                ((eax & THERM_MASK_THRESHOLD1) >>
+                                 THERM_SHIFT_THRESHOLD1) * 1000;
        }
 
        pdata->core_data[attr_no] = tdata;
index a561c3a..397fc59 100644 (file)
@@ -978,6 +978,8 @@ static void pmbus_find_max_attr(struct i2c_client *client,
 struct pmbus_limit_attr {
        u16 reg;                /* Limit register */
        bool update;            /* True if register needs updates */
+       bool low;               /* True if low limit; for limits with compare
+                                  functions only */
        const char *attr;       /* Attribute name */
        const char *alarm;      /* Alarm attribute name */
        u32 sbit;               /* Alarm attribute status bit */
@@ -1029,7 +1031,8 @@ static bool pmbus_add_limit_attrs(struct i2c_client *client,
                                if (attr->compare) {
                                        pmbus_add_boolean_cmp(data, name,
                                                l->alarm, index,
-                                               cbase, cindex,
+                                               l->low ? cindex : cbase,
+                                               l->low ? cbase : cindex,
                                                attr->sbase + page, l->sbit);
                                } else {
                                        pmbus_add_boolean_reg(data, name,
@@ -1366,11 +1369,13 @@ static const struct pmbus_sensor_attr power_attributes[] = {
 static const struct pmbus_limit_attr temp_limit_attrs[] = {
        {
                .reg = PMBUS_UT_WARN_LIMIT,
+               .low = true,
                .attr = "min",
                .alarm = "min_alarm",
                .sbit = PB_TEMP_UT_WARNING,
        }, {
                .reg = PMBUS_UT_FAULT_LIMIT,
+               .low = true,
                .attr = "lcrit",
                .alarm = "lcrit_alarm",
                .sbit = PB_TEMP_UT_FAULT,
@@ -1399,11 +1404,13 @@ static const struct pmbus_limit_attr temp_limit_attrs[] = {
 static const struct pmbus_limit_attr temp_limit_attrs23[] = {
        {
                .reg = PMBUS_UT_WARN_LIMIT,
+               .low = true,
                .attr = "min",
                .alarm = "min_alarm",
                .sbit = PB_TEMP_UT_WARNING,
        }, {
                .reg = PMBUS_UT_FAULT_LIMIT,
+               .low = true,
                .attr = "lcrit",
                .alarm = "lcrit_alarm",
                .sbit = PB_TEMP_UT_FAULT,
index 7b404e5..e34eeb8 100644 (file)
@@ -668,4 +668,3 @@ module_exit(adp5588_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("ADP5588/87 Keypad driver");
-MODULE_ALIAS("platform:adp5588-keys");
index b09c7d1..ab86051 100644 (file)
@@ -475,7 +475,7 @@ static void cm109_toggle_buzzer_sync(struct cm109_dev *dev, int on)
                                le16_to_cpu(dev->ctl_req->wIndex),
                                dev->ctl_data,
                                USB_PKT_LEN, USB_CTRL_SET_TIMEOUT);
-       if (error && error != EINTR)
+       if (error < 0 && error != -EINTR)
                err("%s: usb_control_msg() failed %d", __func__, error);
 }
 
index da28018..5ec617e 100644 (file)
 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI   0x0245
 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO    0x0246
 #define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS    0x0247
+/* MacbookAir4,1 (unibody, July 2011) */
+#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI  0x0249
+#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO   0x024a
+#define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS   0x024b
 /* MacbookAir4,2 (unibody, July 2011) */
 #define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI   0x024c
 #define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO    0x024d
@@ -112,6 +116,10 @@ static const struct usb_device_id bcm5974_table[] = {
        BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI),
        BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ISO),
        BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_JIS),
+       /* MacbookAir4,1 */
+       BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI),
+       BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO),
+       BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS),
        /* MacbookAir4,2 */
        BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI),
        BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_ISO),
@@ -334,6 +342,18 @@ static const struct bcm5974_config bcm5974_config_table[] = {
                { DIM_X, DIM_X / SN_COORD, -4750, 5280 },
                { DIM_Y, DIM_Y / SN_COORD, -150, 6730 }
        },
+       {
+               USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI,
+               USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO,
+               USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS,
+               HAS_INTEGRATED_BUTTON,
+               0x84, sizeof(struct bt_data),
+               0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
+               { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 },
+               { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
+               { DIM_X, DIM_X / SN_COORD, -4620, 5140 },
+               { DIM_Y, DIM_Y / SN_COORD, -150, 6600 }
+       },
        {}
 };
 
index d27c9d9..958b4eb 100644 (file)
@@ -229,13 +229,6 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
                                                        get_unaligned_le16(&report[i + 3]);
                                                i += 4;
                                        }
-                               } else if (usage == WCM_DIGITIZER) {
-                                       /* max pressure isn't reported
-                                       features->pressure_max = (unsigned short)
-                                                       (report[i+4] << 8  | report[i + 3]);
-                                       */
-                                       features->pressure_max = 255;
-                                       i += 4;
                                }
                                break;
 
@@ -291,13 +284,6 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
                                pen = 1;
                                i++;
                                break;
-
-                       case HID_USAGE_UNDEFINED:
-                               if (usage == WCM_DESKTOP && finger) /* capacity */
-                                       features->pressure_max =
-                                               get_unaligned_le16(&report[i + 3]);
-                               i += 4;
-                               break;
                        }
                        break;
 
index c1c2f7b..0dc97ec 100644 (file)
@@ -800,25 +800,26 @@ static int wacom_bpt_touch(struct wacom_wac *wacom)
        int i;
 
        for (i = 0; i < 2; i++) {
-               int p = data[9 * i + 2];
-               bool touch = p && !wacom->shared->stylus_in_proximity;
+               int offset = (data[1] & 0x80) ? (8 * i) : (9 * i);
+               bool touch = data[offset + 3] & 0x80;
 
-               input_mt_slot(input, i);
-               input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
                /*
                 * Touch events need to be disabled while stylus is
                 * in proximity because user's hand is resting on touchpad
                 * and sending unwanted events.  User expects tablet buttons
                 * to continue working though.
                 */
+               touch = touch && !wacom->shared->stylus_in_proximity;
+
+               input_mt_slot(input, i);
+               input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
                if (touch) {
-                       int x = get_unaligned_be16(&data[9 * i + 3]) & 0x7ff;
-                       int y = get_unaligned_be16(&data[9 * i + 5]) & 0x7ff;
+                       int x = get_unaligned_be16(&data[offset + 3]) & 0x7ff;
+                       int y = get_unaligned_be16(&data[offset + 5]) & 0x7ff;
                        if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
                                x <<= 5;
                                y <<= 5;
                        }
-                       input_report_abs(input, ABS_MT_PRESSURE, p);
                        input_report_abs(input, ABS_MT_POSITION_X, x);
                        input_report_abs(input, ABS_MT_POSITION_Y, y);
                }
@@ -1056,10 +1057,11 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
                             features->x_fuzz, 0);
        input_set_abs_params(input_dev, ABS_Y, 0, features->y_max,
                             features->y_fuzz, 0);
-       input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max,
-                            features->pressure_fuzz, 0);
 
        if (features->device_type == BTN_TOOL_PEN) {
+               input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max,
+                            features->pressure_fuzz, 0);
+
                /* penabled devices have fixed resolution for each model */
                input_abs_set_res(input_dev, ABS_X, features->x_resolution);
                input_abs_set_res(input_dev, ABS_Y, features->y_resolution);
@@ -1098,6 +1100,8 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
                __set_bit(BTN_TOOL_MOUSE, input_dev->keybit);
                __set_bit(BTN_STYLUS, input_dev->keybit);
                __set_bit(BTN_STYLUS2, input_dev->keybit);
+
+               __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
                break;
 
        case WACOM_21UX2:
@@ -1126,6 +1130,9 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
                }
 
                input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
+
+               __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+
                wacom_setup_cintiq(wacom_wac);
                break;
 
@@ -1150,6 +1157,8 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
                /* fall through */
 
        case INTUOS:
+               __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+
                wacom_setup_intuos(wacom_wac);
                break;
 
@@ -1165,6 +1174,8 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
 
                input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
                wacom_setup_intuos(wacom_wac);
+
+               __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
                break;
 
        case TABLETPC2FG:
@@ -1183,26 +1194,40 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
        case TABLETPC:
                __clear_bit(ABS_MISC, input_dev->absbit);
 
+               __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+
                if (features->device_type != BTN_TOOL_PEN)
                        break;  /* no need to process stylus stuff */
 
                /* fall through */
 
        case PL:
-       case PTU:
        case DTU:
                __set_bit(BTN_TOOL_PEN, input_dev->keybit);
+               __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
                __set_bit(BTN_STYLUS, input_dev->keybit);
                __set_bit(BTN_STYLUS2, input_dev->keybit);
+
+               __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+               break;
+
+       case PTU:
+               __set_bit(BTN_STYLUS2, input_dev->keybit);
                /* fall through */
 
        case PENPARTNER:
+               __set_bit(BTN_TOOL_PEN, input_dev->keybit);
                __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
+               __set_bit(BTN_STYLUS, input_dev->keybit);
+
+               __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
                break;
 
        case BAMBOO_PT:
                __clear_bit(ABS_MISC, input_dev->absbit);
 
+               __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+
                if (features->device_type == BTN_TOOL_DOUBLETAP) {
                        __set_bit(BTN_LEFT, input_dev->keybit);
                        __set_bit(BTN_FORWARD, input_dev->keybit);
index c14412e..9941d39 100644 (file)
@@ -383,6 +383,8 @@ static int w8001_setup(struct w8001 *w8001)
        dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
        strlcat(w8001->name, "Wacom Serial", sizeof(w8001->name));
 
+       __set_bit(INPUT_PROP_DIRECT, dev->propbit);
+
        /* penabled? */
        error = w8001_command(w8001, W8001_CMD_QUERY, true);
        if (!error) {
index 3dc9bef..6dcc7e2 100644 (file)
@@ -1388,7 +1388,7 @@ int dmar_set_interrupt(struct intel_iommu *iommu)
                return ret;
        }
 
-       ret = request_irq(irq, dmar_fault, 0, iommu->name, iommu);
+       ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu);
        if (ret)
                printk(KERN_ERR "IOMMU: can't request irq\n");
        return ret;
index d87c9d0..328c64c 100644 (file)
@@ -41,6 +41,7 @@ static ssize_t led_delay_on_store(struct device *dev,
 
        if (count == size) {
                led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off);
+               led_cdev->blink_delay_on = state;
                ret = count;
        }
 
@@ -69,6 +70,7 @@ static ssize_t led_delay_off_store(struct device *dev,
 
        if (count == size) {
                led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state);
+               led_cdev->blink_delay_off = state;
                ret = count;
        }
 
index 5d1fca0..f83103b 100644 (file)
@@ -135,10 +135,13 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
        max8997->dev = &i2c->dev;
        max8997->i2c = i2c;
        max8997->type = id->driver_data;
+       max8997->irq = i2c->irq;
 
        if (!pdata)
                goto err;
 
+       max8997->irq_base = pdata->irq_base;
+       max8997->ono = pdata->ono;
        max8997->wakeup = pdata->wakeup;
 
        mutex_init(&max8997->iolock);
@@ -152,6 +155,8 @@ static int max8997_i2c_probe(struct i2c_client *i2c,
 
        pm_runtime_set_active(max8997->dev);
 
+       max8997_irq_init(max8997);
+
        mfd_add_devices(max8997->dev, -1, max8997_devs,
                        ARRAY_SIZE(max8997_devs),
                        NULL, 0);
index 29601e7..86e1458 100644 (file)
@@ -17,6 +17,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -676,7 +677,6 @@ static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count)
                                | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
                                | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
 
-                       reg |= (1 << (i + 1));
                } else
                        continue;
 
index 2bfad5c..a56be93 100644 (file)
@@ -178,8 +178,10 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq,
        switch (tps65910_chip_id(tps65910)) {
        case TPS65910:
                tps65910->irq_num = TPS65910_NUM_IRQ;
+               break;
        case TPS65911:
                tps65910->irq_num = TPS65911_NUM_IRQ;
+               break;
        }
 
        /* Register with genirq */
index b5d598c..7cbf2aa 100644 (file)
@@ -510,8 +510,9 @@ int twl4030_madc_conversion(struct twl4030_madc_request *req)
        u8 ch_msb, ch_lsb;
        int ret;
 
-       if (!req)
+       if (!req || !twl4030_madc)
                return -EINVAL;
+
        mutex_lock(&twl4030_madc->lock);
        if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
                ret = -EINVAL;
@@ -706,6 +707,8 @@ static int __devinit twl4030_madc_probe(struct platform_device *pdev)
        if (!madc)
                return -ENOMEM;
 
+       madc->dev = &pdev->dev;
+
        /*
         * Phoenix provides 2 interrupt lines. The first one is connected to
         * the OMAP. The other one can be connected to the other processor such
index ebf99be..d584f6b 100644 (file)
@@ -37,7 +37,7 @@ static int gpio_set_dir(struct wm8350 *wm8350, int gpio, int dir)
        return ret;
 }
 
-static int gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db)
+static int wm8350_gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db)
 {
        if (db == WM8350_GPIO_DEBOUNCE_ON)
                return wm8350_set_bits(wm8350, WM8350_GPIO_DEBOUNCE,
@@ -210,7 +210,7 @@ int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func,
                goto err;
        if (gpio_set_polarity(wm8350, gpio, pol))
                goto err;
-       if (gpio_set_debounce(wm8350, gpio, debounce))
+       if (wm8350_gpio_set_debounce(wm8350, gpio, debounce))
                goto err;
        if (gpio_set_dir(wm8350, gpio, dir))
                goto err;
index 06df187..0b56e3f 100644 (file)
@@ -165,6 +165,11 @@ static void pti_write_to_aperture(struct pti_masterchannel *mc,
 static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc,
                                             const char *thread_name)
 {
+       /*
+        * Since we access the comm member in current's task_struct, we only
+        * need to be as large as what 'comm' in that structure is.
+        */
+       char comm[TASK_COMM_LEN];
        struct pti_masterchannel mccontrol = {.master = CONTROL_ID,
                                              .channel = 0};
        const char *thread_name_p;
@@ -172,13 +177,6 @@ static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc,
        u8 control_frame[CONTROL_FRAME_LEN];
 
        if (!thread_name) {
-               /*
-                * Since we access the comm member in current's task_struct,
-                * we only need to be as large as what 'comm' in that
-                * structure is.
-                */
-               char comm[TASK_COMM_LEN];
-
                if (!in_interrupt())
                        get_task_comm(comm, current);
                else
index 8d0314d..a44874e 100644 (file)
@@ -2535,7 +2535,7 @@ config S6GMAC
 source "drivers/net/stmmac/Kconfig"
 
 config PCH_GBE
-       tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GbE"
+       tristate "Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7223/ML7831) GbE"
        depends on PCI
        select MII
        ---help---
@@ -2548,10 +2548,11 @@ config PCH_GBE
          This driver enables Gigabit Ethernet function.
 
          This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
-         Output Hub), ML7223.
-         ML7223 IOH is for MP(Media Phone) use.
-         ML7223 is companion chip for Intel Atom E6xx series.
-         ML7223 is completely compatible for Intel EG20T PCH.
+         Output Hub), ML7223/ML7831.
+         ML7223 IOH is for MP(Media Phone) use. ML7831 IOH is for general
+         purpose use.
+         ML7223/ML7831 is companion chip for Intel Atom E6xx series.
+         ML7223/ML7831 is completely compatible for Intel EG20T PCH.
 
 config FTGMAC100
        tristate "Faraday FTGMAC100 Gigabit Ethernet support"
index c423504..e46df53 100644 (file)
@@ -315,6 +315,14 @@ union db_prod {
        u32             raw;
 };
 
+/* dropless fc FW/HW related params */
+#define BRB_SIZE(bp)           (CHIP_IS_E3(bp) ? 1024 : 512)
+#define MAX_AGG_QS(bp)         (CHIP_IS_E1(bp) ? \
+                                       ETH_MAX_AGGREGATION_QUEUES_E1 :\
+                                       ETH_MAX_AGGREGATION_QUEUES_E1H_E2)
+#define FW_DROP_LEVEL(bp)      (3 + MAX_SPQ_PENDING + MAX_AGG_QS(bp))
+#define FW_PREFETCH_CNT                16
+#define DROPLESS_FC_HEADROOM   100
 
 /* MC hsi */
 #define BCM_PAGE_SHIFT         12
@@ -331,15 +339,35 @@ union db_prod {
 /* SGE ring related macros */
 #define NUM_RX_SGE_PAGES       2
 #define RX_SGE_CNT             (BCM_PAGE_SIZE / sizeof(struct eth_rx_sge))
-#define MAX_RX_SGE_CNT         (RX_SGE_CNT - 2)
+#define NEXT_PAGE_SGE_DESC_CNT 2
+#define MAX_RX_SGE_CNT         (RX_SGE_CNT - NEXT_PAGE_SGE_DESC_CNT)
 /* RX_SGE_CNT is promised to be a power of 2 */
 #define RX_SGE_MASK            (RX_SGE_CNT - 1)
 #define NUM_RX_SGE             (RX_SGE_CNT * NUM_RX_SGE_PAGES)
 #define MAX_RX_SGE             (NUM_RX_SGE - 1)
 #define NEXT_SGE_IDX(x)                ((((x) & RX_SGE_MASK) == \
-                                 (MAX_RX_SGE_CNT - 1)) ? (x) + 3 : (x) + 1)
+                                 (MAX_RX_SGE_CNT - 1)) ? \
+                                       (x) + 1 + NEXT_PAGE_SGE_DESC_CNT : \
+                                       (x) + 1)
 #define RX_SGE(x)              ((x) & MAX_RX_SGE)
 
+/*
+ * Number of required  SGEs is the sum of two:
+ * 1. Number of possible opened aggregations (next packet for
+ *    these aggregations will probably consume SGE immidiatelly)
+ * 2. Rest of BRB blocks divided by 2 (block will consume new SGE only
+ *    after placement on BD for new TPA aggregation)
+ *
+ * Takes into account NEXT_PAGE_SGE_DESC_CNT "next" elements on each page
+ */
+#define NUM_SGE_REQ            (MAX_AGG_QS(bp) + \
+                                       (BRB_SIZE(bp) - MAX_AGG_QS(bp)) / 2)
+#define NUM_SGE_PG_REQ         ((NUM_SGE_REQ + MAX_RX_SGE_CNT - 1) / \
+                                               MAX_RX_SGE_CNT)
+#define SGE_TH_LO(bp)          (NUM_SGE_REQ + \
+                                NUM_SGE_PG_REQ * NEXT_PAGE_SGE_DESC_CNT)
+#define SGE_TH_HI(bp)          (SGE_TH_LO(bp) + DROPLESS_FC_HEADROOM)
+
 /* Manipulate a bit vector defined as an array of u64 */
 
 /* Number of bits in one sge_mask array element */
@@ -551,24 +579,43 @@ struct bnx2x_fastpath {
 
 #define NUM_TX_RINGS           16
 #define TX_DESC_CNT            (BCM_PAGE_SIZE / sizeof(union eth_tx_bd_types))
-#define MAX_TX_DESC_CNT                (TX_DESC_CNT - 1)
+#define NEXT_PAGE_TX_DESC_CNT  1
+#define MAX_TX_DESC_CNT                (TX_DESC_CNT - NEXT_PAGE_TX_DESC_CNT)
 #define NUM_TX_BD              (TX_DESC_CNT * NUM_TX_RINGS)
 #define MAX_TX_BD              (NUM_TX_BD - 1)
 #define MAX_TX_AVAIL           (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2)
 #define NEXT_TX_IDX(x)         ((((x) & MAX_TX_DESC_CNT) == \
-                                 (MAX_TX_DESC_CNT - 1)) ? (x) + 2 : (x) + 1)
+                                 (MAX_TX_DESC_CNT - 1)) ? \
+                                       (x) + 1 + NEXT_PAGE_TX_DESC_CNT : \
+                                       (x) + 1)
 #define TX_BD(x)               ((x) & MAX_TX_BD)
 #define TX_BD_POFF(x)          ((x) & MAX_TX_DESC_CNT)
 
 /* The RX BD ring is special, each bd is 8 bytes but the last one is 16 */
 #define NUM_RX_RINGS           8
 #define RX_DESC_CNT            (BCM_PAGE_SIZE / sizeof(struct eth_rx_bd))
-#define MAX_RX_DESC_CNT                (RX_DESC_CNT - 2)
+#define NEXT_PAGE_RX_DESC_CNT  2
+#define MAX_RX_DESC_CNT                (RX_DESC_CNT - NEXT_PAGE_RX_DESC_CNT)
 #define RX_DESC_MASK           (RX_DESC_CNT - 1)
 #define NUM_RX_BD              (RX_DESC_CNT * NUM_RX_RINGS)
 #define MAX_RX_BD              (NUM_RX_BD - 1)
 #define MAX_RX_AVAIL           (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2)
-#define MIN_RX_AVAIL           128
+
+/* dropless fc calculations for BDs
+ *
+ * Number of BDs should as number of buffers in BRB:
+ * Low threshold takes into account NEXT_PAGE_RX_DESC_CNT
+ * "next" elements on each page
+ */
+#define NUM_BD_REQ             BRB_SIZE(bp)
+#define NUM_BD_PG_REQ          ((NUM_BD_REQ + MAX_RX_DESC_CNT - 1) / \
+                                             MAX_RX_DESC_CNT)
+#define BD_TH_LO(bp)           (NUM_BD_REQ + \
+                                NUM_BD_PG_REQ * NEXT_PAGE_RX_DESC_CNT + \
+                                FW_DROP_LEVEL(bp))
+#define BD_TH_HI(bp)           (BD_TH_LO(bp) + DROPLESS_FC_HEADROOM)
+
+#define MIN_RX_AVAIL           ((bp)->dropless_fc ? BD_TH_HI(bp) + 128 : 128)
 
 #define MIN_RX_SIZE_TPA_HW     (CHIP_IS_E1(bp) ? \
                                        ETH_MIN_RX_CQES_WITH_TPA_E1 : \
@@ -579,7 +626,9 @@ struct bnx2x_fastpath {
                                                                MIN_RX_AVAIL))
 
 #define NEXT_RX_IDX(x)         ((((x) & RX_DESC_MASK) == \
-                                 (MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1)
+                                 (MAX_RX_DESC_CNT - 1)) ? \
+                                       (x) + 1 + NEXT_PAGE_RX_DESC_CNT : \
+                                       (x) + 1)
 #define RX_BD(x)               ((x) & MAX_RX_BD)
 
 /*
@@ -589,14 +638,31 @@ struct bnx2x_fastpath {
 #define CQE_BD_REL     (sizeof(union eth_rx_cqe) / sizeof(struct eth_rx_bd))
 #define NUM_RCQ_RINGS          (NUM_RX_RINGS * CQE_BD_REL)
 #define RCQ_DESC_CNT           (BCM_PAGE_SIZE / sizeof(union eth_rx_cqe))
-#define MAX_RCQ_DESC_CNT       (RCQ_DESC_CNT - 1)
+#define NEXT_PAGE_RCQ_DESC_CNT 1
+#define MAX_RCQ_DESC_CNT       (RCQ_DESC_CNT - NEXT_PAGE_RCQ_DESC_CNT)
 #define NUM_RCQ_BD             (RCQ_DESC_CNT * NUM_RCQ_RINGS)
 #define MAX_RCQ_BD             (NUM_RCQ_BD - 1)
 #define MAX_RCQ_AVAIL          (MAX_RCQ_DESC_CNT * NUM_RCQ_RINGS - 2)
 #define NEXT_RCQ_IDX(x)                ((((x) & MAX_RCQ_DESC_CNT) == \
-                                 (MAX_RCQ_DESC_CNT - 1)) ? (x) + 2 : (x) + 1)
+                                 (MAX_RCQ_DESC_CNT - 1)) ? \
+                                       (x) + 1 + NEXT_PAGE_RCQ_DESC_CNT : \
+                                       (x) + 1)
 #define RCQ_BD(x)              ((x) & MAX_RCQ_BD)
 
+/* dropless fc calculations for RCQs
+ *
+ * Number of RCQs should be as number of buffers in BRB:
+ * Low threshold takes into account NEXT_PAGE_RCQ_DESC_CNT
+ * "next" elements on each page
+ */
+#define NUM_RCQ_REQ            BRB_SIZE(bp)
+#define NUM_RCQ_PG_REQ         ((NUM_BD_REQ + MAX_RCQ_DESC_CNT - 1) / \
+                                             MAX_RCQ_DESC_CNT)
+#define RCQ_TH_LO(bp)          (NUM_RCQ_REQ + \
+                                NUM_RCQ_PG_REQ * NEXT_PAGE_RCQ_DESC_CNT + \
+                                FW_DROP_LEVEL(bp))
+#define RCQ_TH_HI(bp)          (RCQ_TH_LO(bp) + DROPLESS_FC_HEADROOM)
+
 
 /* This is needed for determining of last_max */
 #define SUB_S16(a, b)          (s16)((s16)(a) - (s16)(b))
@@ -685,24 +751,17 @@ struct bnx2x_fastpath {
 #define FP_CSB_FUNC_OFF        \
                        offsetof(struct cstorm_status_block_c, func)
 
-#define HC_INDEX_TOE_RX_CQ_CONS                0 /* Formerly Ustorm TOE CQ index */
-                                         /* (HC_INDEX_U_TOE_RX_CQ_CONS)  */
-#define HC_INDEX_ETH_RX_CQ_CONS                1 /* Formerly Ustorm ETH CQ index */
-                                         /* (HC_INDEX_U_ETH_RX_CQ_CONS)  */
-#define HC_INDEX_ETH_RX_BD_CONS                2 /* Formerly Ustorm ETH BD index */
-                                         /* (HC_INDEX_U_ETH_RX_BD_CONS)  */
-
-#define HC_INDEX_TOE_TX_CQ_CONS                4 /* Formerly Cstorm TOE CQ index   */
-                                         /* (HC_INDEX_C_TOE_TX_CQ_CONS)    */
-#define HC_INDEX_ETH_TX_CQ_CONS_COS0   5 /* Formerly Cstorm ETH CQ index   */
-                                         /* (HC_INDEX_C_ETH_TX_CQ_CONS)    */
-#define HC_INDEX_ETH_TX_CQ_CONS_COS1   6 /* Formerly Cstorm ETH CQ index   */
-                                         /* (HC_INDEX_C_ETH_TX_CQ_CONS)    */
-#define HC_INDEX_ETH_TX_CQ_CONS_COS2   7 /* Formerly Cstorm ETH CQ index   */
-                                         /* (HC_INDEX_C_ETH_TX_CQ_CONS)    */
+#define HC_INDEX_ETH_RX_CQ_CONS                1
 
-#define HC_INDEX_ETH_FIRST_TX_CQ_CONS  HC_INDEX_ETH_TX_CQ_CONS_COS0
+#define HC_INDEX_OOO_TX_CQ_CONS                4
 
+#define HC_INDEX_ETH_TX_CQ_CONS_COS0   5
+
+#define HC_INDEX_ETH_TX_CQ_CONS_COS1   6
+
+#define HC_INDEX_ETH_TX_CQ_CONS_COS2   7
+
+#define HC_INDEX_ETH_FIRST_TX_CQ_CONS  HC_INDEX_ETH_TX_CQ_CONS_COS0
 
 #define BNX2X_RX_SB_INDEX \
        (&fp->sb_index_values[HC_INDEX_ETH_RX_CQ_CONS])
@@ -1100,11 +1159,12 @@ struct bnx2x {
 #define BP_PORT(bp)                    (bp->pfid & 1)
 #define BP_FUNC(bp)                    (bp->pfid)
 #define BP_ABS_FUNC(bp)                        (bp->pf_num)
-#define BP_E1HVN(bp)                   (bp->pfid >> 1)
-#define BP_VN(bp)                      (BP_E1HVN(bp)) /*remove when approved*/
-#define BP_L_ID(bp)                    (BP_E1HVN(bp) << 2)
-#define BP_FW_MB_IDX(bp)               (BP_PORT(bp) +\
-         BP_VN(bp) * ((CHIP_IS_E1x(bp) || (CHIP_MODE_IS_4_PORT(bp))) ? 2  : 1))
+#define BP_VN(bp)                      ((bp)->pfid >> 1)
+#define BP_MAX_VN_NUM(bp)              (CHIP_MODE_IS_4_PORT(bp) ? 2 : 4)
+#define BP_L_ID(bp)                    (BP_VN(bp) << 2)
+#define BP_FW_MB_IDX_VN(bp, vn)                (BP_PORT(bp) +\
+         (vn) * ((CHIP_IS_E1x(bp) || (CHIP_MODE_IS_4_PORT(bp))) ? 2  : 1))
+#define BP_FW_MB_IDX(bp)               BP_FW_MB_IDX_VN(bp, BP_VN(bp))
 
        struct net_device       *dev;
        struct pci_dev          *pdev;
@@ -1767,7 +1827,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 
 #define MAX_DMAE_C_PER_PORT            8
 #define INIT_DMAE_C(bp)                        (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \
-                                        BP_E1HVN(bp))
+                                        BP_VN(bp))
 #define PMF_DMAE_C(bp)                 (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \
                                         E1HVN_MAX)
 
@@ -1793,7 +1853,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 
 /* must be used on a CID before placing it on a HW ring */
 #define HW_CID(bp, x)                  ((BP_PORT(bp) << 23) | \
-                                        (BP_E1HVN(bp) << BNX2X_SWCID_SHIFT) | \
+                                        (BP_VN(bp) << BNX2X_SWCID_SHIFT) | \
                                         (x))
 
 #define SP_DESC_CNT            (BCM_PAGE_SIZE / sizeof(struct eth_spe))
index 37e5790..c4cbf97 100644 (file)
@@ -987,8 +987,6 @@ void __bnx2x_link_report(struct bnx2x *bp)
 void bnx2x_init_rx_rings(struct bnx2x *bp)
 {
        int func = BP_FUNC(bp);
-       int max_agg_queues = CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 :
-                                             ETH_MAX_AGGREGATION_QUEUES_E1H_E2;
        u16 ring_prod;
        int i, j;
 
@@ -1001,7 +999,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
 
                if (!fp->disable_tpa) {
                        /* Fill the per-aggregtion pool */
-                       for (i = 0; i < max_agg_queues; i++) {
+                       for (i = 0; i < MAX_AGG_QS(bp); i++) {
                                struct bnx2x_agg_info *tpa_info =
                                        &fp->tpa_info[i];
                                struct sw_rx_bd *first_buf =
@@ -1041,7 +1039,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
                                        bnx2x_free_rx_sge_range(bp, fp,
                                                                ring_prod);
                                        bnx2x_free_tpa_pool(bp, fp,
-                                                           max_agg_queues);
+                                                           MAX_AGG_QS(bp));
                                        fp->disable_tpa = 1;
                                        ring_prod = 0;
                                        break;
@@ -1137,9 +1135,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp)
                bnx2x_free_rx_bds(fp);
 
                if (!fp->disable_tpa)
-                       bnx2x_free_tpa_pool(bp, fp, CHIP_IS_E1(bp) ?
-                                           ETH_MAX_AGGREGATION_QUEUES_E1 :
-                                           ETH_MAX_AGGREGATION_QUEUES_E1H_E2);
+                       bnx2x_free_tpa_pool(bp, fp, MAX_AGG_QS(bp));
        }
 }
 
@@ -3095,15 +3091,20 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
        struct bnx2x_fastpath *fp = &bp->fp[index];
        int ring_size = 0;
        u8 cos;
+       int rx_ring_size = 0;
 
        /* if rx_ring_size specified - use it */
-       int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size :
-                          MAX_RX_AVAIL/BNX2X_NUM_RX_QUEUES(bp);
+       if (!bp->rx_ring_size) {
 
-       /* allocate at least number of buffers required by FW */
-       rx_ring_size = max_t(int, bp->disable_tpa ? MIN_RX_SIZE_NONTPA :
-                                                   MIN_RX_SIZE_TPA,
-                                 rx_ring_size);
+               rx_ring_size = MAX_RX_AVAIL/BNX2X_NUM_RX_QUEUES(bp);
+
+               /* allocate at least number of buffers required by FW */
+               rx_ring_size = max_t(int, bp->disable_tpa ? MIN_RX_SIZE_NONTPA :
+                                    MIN_RX_SIZE_TPA, rx_ring_size);
+
+               bp->rx_ring_size = rx_ring_size;
+       } else
+               rx_ring_size = bp->rx_ring_size;
 
        /* Common */
        sb = &bnx2x_fp(bp, index, status_blk);
index 2218630..cf3e479 100644 (file)
@@ -363,13 +363,50 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                }
 
                /* advertise the requested speed and duplex if supported */
-               cmd->advertising &= bp->port.supported[cfg_idx];
+               if (cmd->advertising & ~(bp->port.supported[cfg_idx])) {
+                       DP(NETIF_MSG_LINK, "Advertisement parameters "
+                                          "are not supported\n");
+                       return -EINVAL;
+               }
 
                bp->link_params.req_line_speed[cfg_idx] = SPEED_AUTO_NEG;
-               bp->link_params.req_duplex[cfg_idx] = DUPLEX_FULL;
-               bp->port.advertising[cfg_idx] |= (ADVERTISED_Autoneg |
+               bp->link_params.req_duplex[cfg_idx] = cmd->duplex;
+               bp->port.advertising[cfg_idx] = (ADVERTISED_Autoneg |
                                         cmd->advertising);
+               if (cmd->advertising) {
+
+                       bp->link_params.speed_cap_mask[cfg_idx] = 0;
+                       if (cmd->advertising & ADVERTISED_10baseT_Half) {
+                               bp->link_params.speed_cap_mask[cfg_idx] |=
+                               PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF;
+                       }
+                       if (cmd->advertising & ADVERTISED_10baseT_Full)
+                               bp->link_params.speed_cap_mask[cfg_idx] |=
+                               PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL;
 
+                       if (cmd->advertising & ADVERTISED_100baseT_Full)
+                               bp->link_params.speed_cap_mask[cfg_idx] |=
+                               PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL;
+
+                       if (cmd->advertising & ADVERTISED_100baseT_Half) {
+                               bp->link_params.speed_cap_mask[cfg_idx] |=
+                                    PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF;
+                       }
+                       if (cmd->advertising & ADVERTISED_1000baseT_Half) {
+                               bp->link_params.speed_cap_mask[cfg_idx] |=
+                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G;
+                       }
+                       if (cmd->advertising & (ADVERTISED_1000baseT_Full |
+                                               ADVERTISED_1000baseKX_Full))
+                               bp->link_params.speed_cap_mask[cfg_idx] |=
+                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G;
+
+                       if (cmd->advertising & (ADVERTISED_10000baseT_Full |
+                                               ADVERTISED_10000baseKX4_Full |
+                                               ADVERTISED_10000baseKR_Full))
+                               bp->link_params.speed_cap_mask[cfg_idx] |=
+                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G;
+               }
        } else { /* forced speed */
                /* advertise the requested speed and duplex if supported */
                switch (speed) {
@@ -1310,10 +1347,7 @@ static void bnx2x_get_ringparam(struct net_device *dev,
        if (bp->rx_ring_size)
                ering->rx_pending = bp->rx_ring_size;
        else
-               if (bp->state == BNX2X_STATE_OPEN && bp->num_queues)
-                       ering->rx_pending = MAX_RX_AVAIL/bp->num_queues;
-               else
-                       ering->rx_pending = MAX_RX_AVAIL;
+               ering->rx_pending = MAX_RX_AVAIL;
 
        ering->rx_mini_pending = 0;
        ering->rx_jumbo_pending = 0;
index d45b155..ba15bdc 100644 (file)
@@ -778,9 +778,9 @@ static int bnx2x_ets_e3b0_set_cos_bw(struct bnx2x *bp,
 {
        u32 nig_reg_adress_crd_weight = 0;
        u32 pbf_reg_adress_crd_weight = 0;
-       /* Calculate and set BW for this COS*/
-       const u32 cos_bw_nig = (bw * min_w_val_nig) / total_bw;
-       const u32 cos_bw_pbf = (bw * min_w_val_pbf) / total_bw;
+       /* Calculate and set BW for this COS - use 1 instead of 0 for BW */
+       const u32 cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
+       const u32 cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
 
        switch (cos_entry) {
        case 0:
@@ -852,18 +852,12 @@ static int bnx2x_ets_e3b0_get_total_bw(
        /* Calculate total BW requested */
        for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
                if (bnx2x_cos_state_bw == ets_params->cos[cos_idx].state) {
-
-                       if (0 == ets_params->cos[cos_idx].params.bw_params.bw) {
-                               DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config BW"
-                                                  "was set to 0\n");
-                       return -EINVAL;
+                       *total_bw +=
+                               ets_params->cos[cos_idx].params.bw_params.bw;
                }
-               *total_bw +=
-                   ets_params->cos[cos_idx].params.bw_params.bw;
-           }
        }
 
-       /*Check taotl BW is valid */
+       /* Check total BW is valid */
        if ((100 != *total_bw) || (0 == *total_bw)) {
                if (0 == *total_bw) {
                        DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config toatl BW"
@@ -1726,7 +1720,7 @@ static int bnx2x_xmac_enable(struct link_params *params,
 
        /* Check loopback mode */
        if (lb)
-               val |= XMAC_CTRL_REG_CORE_LOCAL_LPBK;
+               val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
        REG_WR(bp, xmac_base + XMAC_REG_CTRL, val);
        bnx2x_set_xumac_nig(params,
                            ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
@@ -3630,6 +3624,12 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
                         MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
 
+       /* Advertised and set FEC (Forward Error Correction) */
+       bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
+                        MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2,
+                        (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY |
+                         MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ));
+
        /* Enable CL37 BAM */
        if (REG_RD(bp, params->shmem_base +
                   offsetof(struct shmem_region, dev_info.
@@ -5924,7 +5924,7 @@ int bnx2x_set_led(struct link_params *params,
                                        (tmp | EMAC_LED_OVERRIDE));
                                /*
                                 * return here without enabling traffic
-                                * LED blink andsetting rate in ON mode.
+                                * LED blink and setting rate in ON mode.
                                 * In oper mode, enabling LED blink
                                 * and setting rate is needed.
                                 */
@@ -5936,7 +5936,11 @@ int bnx2x_set_led(struct link_params *params,
                         * This is a work-around for HW issue found when link
                         * is up in CL73
                         */
-                       REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
+                       if ((!CHIP_IS_E3(bp)) ||
+                           (CHIP_IS_E3(bp) &&
+                            mode == LED_MODE_ON))
+                               REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
+
                        if (CHIP_IS_E1x(bp) ||
                            CHIP_IS_E2(bp) ||
                            (mode == LED_MODE_ON))
@@ -10638,8 +10642,7 @@ static struct bnx2x_phy phy_warpcore = {
        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
        .addr           = 0xff,
        .def_md_devad   = 0,
-       .flags          = (FLAGS_HW_LOCK_REQUIRED |
-                          FLAGS_TX_ERROR_CHECK),
+       .flags          = FLAGS_HW_LOCK_REQUIRED,
        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
        .mdio_ctrl      = 0,
@@ -10765,8 +10768,7 @@ static struct bnx2x_phy phy_8706 = {
        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
        .addr           = 0xff,
        .def_md_devad   = 0,
-       .flags          = (FLAGS_INIT_XGXS_FIRST |
-                          FLAGS_TX_ERROR_CHECK),
+       .flags          = FLAGS_INIT_XGXS_FIRST,
        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
        .mdio_ctrl      = 0,
@@ -10797,8 +10799,7 @@ static struct bnx2x_phy phy_8726 = {
        .addr           = 0xff,
        .def_md_devad   = 0,
        .flags          = (FLAGS_HW_LOCK_REQUIRED |
-                          FLAGS_INIT_XGXS_FIRST |
-                          FLAGS_TX_ERROR_CHECK),
+                          FLAGS_INIT_XGXS_FIRST),
        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
        .mdio_ctrl      = 0,
@@ -10829,8 +10830,7 @@ static struct bnx2x_phy phy_8727 = {
        .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
        .addr           = 0xff,
        .def_md_devad   = 0,
-       .flags          = (FLAGS_FAN_FAILURE_DET_REQ |
-                          FLAGS_TX_ERROR_CHECK),
+       .flags          = FLAGS_FAN_FAILURE_DET_REQ,
        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
        .mdio_ctrl      = 0,
index f74582a..c027e93 100644 (file)
@@ -407,8 +407,8 @@ u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type,
        opcode |= (DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET);
 
        opcode |= (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0);
-       opcode |= ((BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT) |
-                  (BP_E1HVN(bp) << DMAE_COMMAND_DST_VN_SHIFT));
+       opcode |= ((BP_VN(bp) << DMAE_CMD_E1HVN_SHIFT) |
+                  (BP_VN(bp) << DMAE_COMMAND_DST_VN_SHIFT));
        opcode |= (DMAE_COM_SET_ERR << DMAE_COMMAND_ERR_POLICY_SHIFT);
 
 #ifdef __BIG_ENDIAN
@@ -1419,7 +1419,7 @@ static void bnx2x_hc_int_enable(struct bnx2x *bp)
        if (!CHIP_IS_E1(bp)) {
                /* init leading/trailing edge */
                if (IS_MF(bp)) {
-                       val = (0xee0f | (1 << (BP_E1HVN(bp) + 4)));
+                       val = (0xee0f | (1 << (BP_VN(bp) + 4)));
                        if (bp->port.pmf)
                                /* enable nig and gpio3 attention */
                                val |= 0x1100;
@@ -1471,7 +1471,7 @@ static void bnx2x_igu_int_enable(struct bnx2x *bp)
 
        /* init leading/trailing edge */
        if (IS_MF(bp)) {
-               val = (0xee0f | (1 << (BP_E1HVN(bp) + 4)));
+               val = (0xee0f | (1 << (BP_VN(bp) + 4)));
                if (bp->port.pmf)
                        /* enable nig and gpio3 attention */
                        val |= 0x1100;
@@ -2287,7 +2287,7 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
        int vn;
 
        bp->vn_weight_sum = 0;
-       for (vn = VN_0; vn < E1HVN_MAX; vn++) {
+       for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++) {
                u32 vn_cfg = bp->mf_config[vn];
                u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
                                   FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
@@ -2320,12 +2320,18 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
                                        CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
 }
 
+/* returns func by VN for current port */
+static inline int func_by_vn(struct bnx2x *bp, int vn)
+{
+       return 2 * vn + BP_PORT(bp);
+}
+
 static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn)
 {
        struct rate_shaping_vars_per_vn m_rs_vn;
        struct fairness_vars_per_vn m_fair_vn;
        u32 vn_cfg = bp->mf_config[vn];
-       int func = 2*vn + BP_PORT(bp);
+       int func = func_by_vn(bp, vn);
        u16 vn_min_rate, vn_max_rate;
        int i;
 
@@ -2422,7 +2428,7 @@ void bnx2x_read_mf_cfg(struct bnx2x *bp)
         *
         *      and there are 2 functions per port
         */
-       for (vn = VN_0; vn < E1HVN_MAX; vn++) {
+       for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++) {
                int /*abs*/func = n * (2 * vn + BP_PORT(bp)) + BP_PATH(bp);
 
                if (func >= E1H_FUNC_MAX)
@@ -2454,7 +2460,7 @@ static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type)
 
                /* calculate and set min-max rate for each vn */
                if (bp->port.pmf)
-                       for (vn = VN_0; vn < E1HVN_MAX; vn++)
+                       for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++)
                                bnx2x_init_vn_minmax(bp, vn);
 
                /* always enable rate shaping and fairness */
@@ -2473,16 +2479,15 @@ static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type)
 
 static inline void bnx2x_link_sync_notify(struct bnx2x *bp)
 {
-       int port = BP_PORT(bp);
        int func;
        int vn;
 
        /* Set the attention towards other drivers on the same port */
-       for (vn = VN_0; vn < E1HVN_MAX; vn++) {
-               if (vn == BP_E1HVN(bp))
+       for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++) {
+               if (vn == BP_VN(bp))
                        continue;
 
-               func = ((vn << 1) | port);
+               func = func_by_vn(bp, vn);
                REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
                       (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
        }
@@ -2577,7 +2582,7 @@ static void bnx2x_pmf_update(struct bnx2x *bp)
        bnx2x_dcbx_pmf_update(bp);
 
        /* enable nig attention */
-       val = (0xff0f | (1 << (BP_E1HVN(bp) + 4)));
+       val = (0xff0f | (1 << (BP_VN(bp) + 4)));
        if (bp->common.int_block == INT_BLOCK_HC) {
                REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val);
                REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val);
@@ -2756,8 +2761,14 @@ static void bnx2x_pf_rx_q_prep(struct bnx2x *bp,
        u16 tpa_agg_size = 0;
 
        if (!fp->disable_tpa) {
-               pause->sge_th_hi = 250;
-               pause->sge_th_lo = 150;
+               pause->sge_th_lo = SGE_TH_LO(bp);
+               pause->sge_th_hi = SGE_TH_HI(bp);
+
+               /* validate SGE ring has enough to cross high threshold */
+               WARN_ON(bp->dropless_fc &&
+                               pause->sge_th_hi + FW_PREFETCH_CNT >
+                               MAX_RX_SGE_CNT * NUM_RX_SGE_PAGES);
+
                tpa_agg_size = min_t(u32,
                        (min_t(u32, 8, MAX_SKB_FRAGS) *
                        SGE_PAGE_SIZE * PAGES_PER_SGE), 0xffff);
@@ -2771,10 +2782,21 @@ static void bnx2x_pf_rx_q_prep(struct bnx2x *bp,
 
        /* pause - not for e1 */
        if (!CHIP_IS_E1(bp)) {
-               pause->bd_th_hi = 350;
-               pause->bd_th_lo = 250;
-               pause->rcq_th_hi = 350;
-               pause->rcq_th_lo = 250;
+               pause->bd_th_lo = BD_TH_LO(bp);
+               pause->bd_th_hi = BD_TH_HI(bp);
+
+               pause->rcq_th_lo = RCQ_TH_LO(bp);
+               pause->rcq_th_hi = RCQ_TH_HI(bp);
+               /*
+                * validate that rings have enough entries to cross
+                * high thresholds
+                */
+               WARN_ON(bp->dropless_fc &&
+                               pause->bd_th_hi + FW_PREFETCH_CNT >
+                               bp->rx_ring_size);
+               WARN_ON(bp->dropless_fc &&
+                               pause->rcq_th_hi + FW_PREFETCH_CNT >
+                               NUM_RCQ_RINGS * MAX_RCQ_DESC_CNT);
 
                pause->pri_map = 1;
        }
@@ -2802,9 +2824,7 @@ static void bnx2x_pf_rx_q_prep(struct bnx2x *bp,
         * For PF Clients it should be the maximum avaliable number.
         * VF driver(s) may want to define it to a smaller value.
         */
-       rxq_init->max_tpa_queues =
-               (CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 :
-               ETH_MAX_AGGREGATION_QUEUES_E1H_E2);
+       rxq_init->max_tpa_queues = MAX_AGG_QS(bp);
 
        rxq_init->cache_line_log = BNX2X_RX_ALIGN_SHIFT;
        rxq_init->fw_sb_id = fp->fw_sb_id;
@@ -4808,6 +4828,37 @@ void bnx2x_setup_ndsb_state_machine(struct hc_status_block_sm *hc_sm,
        hc_sm->time_to_expire = 0xFFFFFFFF;
 }
 
+
+/* allocates state machine ids. */
+static inline
+void bnx2x_map_sb_state_machines(struct hc_index_data *index_data)
+{
+       /* zero out state machine indices */
+       /* rx indices */
+       index_data[HC_INDEX_ETH_RX_CQ_CONS].flags &= ~HC_INDEX_DATA_SM_ID;
+
+       /* tx indices */
+       index_data[HC_INDEX_OOO_TX_CQ_CONS].flags &= ~HC_INDEX_DATA_SM_ID;
+       index_data[HC_INDEX_ETH_TX_CQ_CONS_COS0].flags &= ~HC_INDEX_DATA_SM_ID;
+       index_data[HC_INDEX_ETH_TX_CQ_CONS_COS1].flags &= ~HC_INDEX_DATA_SM_ID;
+       index_data[HC_INDEX_ETH_TX_CQ_CONS_COS2].flags &= ~HC_INDEX_DATA_SM_ID;
+
+       /* map indices */
+       /* rx indices */
+       index_data[HC_INDEX_ETH_RX_CQ_CONS].flags |=
+               SM_RX_ID << HC_INDEX_DATA_SM_ID_SHIFT;
+
+       /* tx indices */
+       index_data[HC_INDEX_OOO_TX_CQ_CONS].flags |=
+               SM_TX_ID << HC_INDEX_DATA_SM_ID_SHIFT;
+       index_data[HC_INDEX_ETH_TX_CQ_CONS_COS0].flags |=
+               SM_TX_ID << HC_INDEX_DATA_SM_ID_SHIFT;
+       index_data[HC_INDEX_ETH_TX_CQ_CONS_COS1].flags |=
+               SM_TX_ID << HC_INDEX_DATA_SM_ID_SHIFT;
+       index_data[HC_INDEX_ETH_TX_CQ_CONS_COS2].flags |=
+               SM_TX_ID << HC_INDEX_DATA_SM_ID_SHIFT;
+}
+
 static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid,
                          u8 vf_valid, int fw_sb_id, int igu_sb_id)
 {
@@ -4839,6 +4890,7 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid,
                hc_sm_p = sb_data_e2.common.state_machine;
                sb_data_p = (u32 *)&sb_data_e2;
                data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32);
+               bnx2x_map_sb_state_machines(sb_data_e2.index_data);
        } else {
                memset(&sb_data_e1x, 0,
                       sizeof(struct hc_status_block_data_e1x));
@@ -4853,6 +4905,7 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid,
                hc_sm_p = sb_data_e1x.common.state_machine;
                sb_data_p = (u32 *)&sb_data_e1x;
                data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32);
+               bnx2x_map_sb_state_machines(sb_data_e1x.index_data);
        }
 
        bnx2x_setup_ndsb_state_machine(&hc_sm_p[SM_RX_ID],
@@ -5802,7 +5855,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp)
         * take the UNDI lock to protect undi_unload flow from accessing
         * registers while we're resetting the chip
         */
-       bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
+       bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
 
        bnx2x_reset_common(bp);
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
@@ -5814,7 +5867,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp)
        }
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, val);
 
-       bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
+       bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
 
        bnx2x_init_block(bp, BLOCK_MISC, PHASE_COMMON);
 
@@ -6671,12 +6724,16 @@ static int bnx2x_init_hw_func(struct bnx2x *bp)
                        if (CHIP_MODE_IS_4_PORT(bp))
                                dsb_idx = BP_FUNC(bp);
                        else
-                               dsb_idx = BP_E1HVN(bp);
+                               dsb_idx = BP_VN(bp);
 
                        prod_offset = (CHIP_INT_MODE_IS_BC(bp) ?
                                       IGU_BC_BASE_DSB_PROD + dsb_idx :
                                       IGU_NORM_BASE_DSB_PROD + dsb_idx);
 
+                       /*
+                        * igu prods come in chunks of E1HVN_MAX (4) -
+                        * does not matters what is the current chip mode
+                        */
                        for (i = 0; i < (num_segs * E1HVN_MAX);
                             i += E1HVN_MAX) {
                                addr = IGU_REG_PROD_CONS_MEMORY +
@@ -7570,7 +7627,7 @@ u32 bnx2x_send_unload_req(struct bnx2x *bp, int unload_mode)
                u32 val;
                /* The mac address is written to entries 1-4 to
                   preserve entry 0 which is used by the PMF */
-               u8 entry = (BP_E1HVN(bp) + 1)*8;
+               u8 entry = (BP_VN(bp) + 1)*8;
 
                val = (mac_addr[0] << 8) | mac_addr[1];
                EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry, val);
@@ -8546,10 +8603,12 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
        /* Check if there is any driver already loaded */
        val = REG_RD(bp, MISC_REG_UNPREPARED);
        if (val == 0x1) {
-               /* Check if it is the UNDI driver
+
+               bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
+               /*
+                * Check if it is the UNDI driver
                 * UNDI driver initializes CID offset for normal bell to 0x7
                 */
-               bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
                val = REG_RD(bp, DORQ_REG_NORM_CID_OFST);
                if (val == 0x7) {
                        u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
@@ -8587,9 +8646,6 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
                                bnx2x_fw_command(bp, reset_code, 0);
                        }
 
-                       /* now it's safe to release the lock */
-                       bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
-
                        bnx2x_undi_int_disable(bp);
                        port = BP_PORT(bp);
 
@@ -8639,8 +8695,10 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
                        bp->fw_seq =
                              (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) &
                                DRV_MSG_SEQ_NUMBER_MASK);
-               } else
-                       bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
+               }
+
+               /* now it's safe to release the lock */
+               bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
        }
 }
 
@@ -8777,13 +8835,13 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
 static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp)
 {
        int pfid = BP_FUNC(bp);
-       int vn = BP_E1HVN(bp);
        int igu_sb_id;
        u32 val;
        u8 fid, igu_sb_cnt = 0;
 
        bp->igu_base_sb = 0xff;
        if (CHIP_INT_MODE_IS_BC(bp)) {
+               int vn = BP_VN(bp);
                igu_sb_cnt = bp->igu_sb_cnt;
                bp->igu_base_sb = (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn) *
                        FP_SB_MAX_E1x;
@@ -9416,6 +9474,10 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
                bp->igu_base_sb = 0;
        } else {
                bp->common.int_block = INT_BLOCK_IGU;
+
+               /* do not allow device reset during IGU info preocessing */
+               bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
+
                val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION);
 
                if (val & IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN) {
@@ -9447,6 +9509,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
 
                bnx2x_get_igu_cam_info(bp);
 
+               bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
        }
 
        /*
@@ -9473,7 +9536,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
 
        bp->mf_ov = 0;
        bp->mf_mode = 0;
-       vn = BP_E1HVN(bp);
+       vn = BP_VN(bp);
 
        if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) {
                BNX2X_DEV_INFO("shmem2base 0x%x, size %d, mfcfg offset %d\n",
@@ -9593,13 +9656,6 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
        /* port info */
        bnx2x_get_port_hwinfo(bp);
 
-       if (!BP_NOMCP(bp)) {
-               bp->fw_seq =
-                       (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
-                        DRV_MSG_SEQ_NUMBER_MASK);
-               BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
-       }
-
        /* Get MAC addresses */
        bnx2x_get_mac_hwinfo(bp);
 
@@ -9765,6 +9821,14 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
        if (!BP_NOMCP(bp))
                bnx2x_undi_unload(bp);
 
+       /* init fw_seq after undi_unload! */
+       if (!BP_NOMCP(bp)) {
+               bp->fw_seq =
+                       (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
+                        DRV_MSG_SEQ_NUMBER_MASK);
+               BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
+       }
+
        if (CHIP_REV_IS_FPGA(bp))
                dev_err(&bp->pdev->dev, "FPGA detected\n");
 
@@ -10259,17 +10323,21 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
        /* clean indirect addresses */
        pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
                               PCICFG_VENDOR_ID_OFFSET);
-       /* Clean the following indirect addresses for all functions since it
+       /*
+        * Clean the following indirect addresses for all functions since it
         * is not used by the driver.
         */
        REG_WR(bp, PXP2_REG_PGL_ADDR_88_F0, 0);
        REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F0, 0);
        REG_WR(bp, PXP2_REG_PGL_ADDR_90_F0, 0);
        REG_WR(bp, PXP2_REG_PGL_ADDR_94_F0, 0);
-       REG_WR(bp, PXP2_REG_PGL_ADDR_88_F1, 0);
-       REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F1, 0);
-       REG_WR(bp, PXP2_REG_PGL_ADDR_90_F1, 0);
-       REG_WR(bp, PXP2_REG_PGL_ADDR_94_F1, 0);
+
+       if (CHIP_IS_E1x(bp)) {
+               REG_WR(bp, PXP2_REG_PGL_ADDR_88_F1, 0);
+               REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F1, 0);
+               REG_WR(bp, PXP2_REG_PGL_ADDR_90_F1, 0);
+               REG_WR(bp, PXP2_REG_PGL_ADDR_94_F1, 0);
+       }
 
        /*
         * Enable internal target-read (in case we are probed after PF FLR).
index 40266c1..750e844 100644 (file)
 #define XCM_REG_XX_OVFL_EVNT_ID                                 0x20058
 #define XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS   (0x1<<0)
 #define XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS  (0x1<<1)
-#define XMAC_CTRL_REG_CORE_LOCAL_LPBK                           (0x1<<3)
+#define XMAC_CTRL_REG_LINE_LOCAL_LPBK                           (0x1<<2)
 #define XMAC_CTRL_REG_RX_EN                                     (0x1<<1)
 #define XMAC_CTRL_REG_SOFT_RESET                                (0x1<<6)
 #define XMAC_CTRL_REG_TX_EN                                     (0x1<<0)
 #define HW_LOCK_RESOURCE_RECOVERY_LEADER_0                      8
 #define HW_LOCK_RESOURCE_RECOVERY_LEADER_1                      9
 #define HW_LOCK_RESOURCE_SPIO                                   2
-#define HW_LOCK_RESOURCE_UNDI                                   5
+#define HW_LOCK_RESOURCE_RESET                                  5
 #define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT                   (0x1<<4)
 #define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR                   (0x1<<5)
 #define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR                   (0x1<<18)
@@ -6853,6 +6853,9 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_WC_REG_IEEE0BLK_AUTONEGNP                 0x7
 #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT0      0x10
 #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1      0x11
+#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2      0x12
+#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY    0x4000
+#define MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ                0x8000
 #define MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150  0x96
 #define MDIO_WC_REG_XGXSBLK0_XGXSCONTROL               0x8000
 #define MDIO_WC_REG_XGXSBLK0_MISCCONTROL1              0x800e
index 771f680..9908f2b 100644 (file)
@@ -710,7 +710,8 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp)
                break;
 
        case MAC_TYPE_NONE: /* unreached */
-               BNX2X_ERR("stats updated by DMAE but no MAC active\n");
+               DP(BNX2X_MSG_STATS,
+                  "stats updated by DMAE but no MAC active\n");
                return -1;
 
        default: /* unreached */
@@ -1391,7 +1392,7 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp)
 
 static void bnx2x_func_stats_base_init(struct bnx2x *bp)
 {
-       int vn, vn_max = IS_MF(bp) ? E1HVN_MAX : E1VN_MAX;
+       int vn, vn_max = IS_MF(bp) ? BP_MAX_VN_NUM(bp) : E1VN_MAX;
        u32 func_stx;
 
        /* sanity */
@@ -1404,7 +1405,7 @@ static void bnx2x_func_stats_base_init(struct bnx2x *bp)
        func_stx = bp->func_stx;
 
        for (vn = VN_0; vn < vn_max; vn++) {
-               int mb_idx = CHIP_IS_E1x(bp) ? 2*vn + BP_PORT(bp) : vn;
+               int mb_idx = BP_FW_MB_IDX_VN(bp, vn);
 
                bp->func_stx = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_param);
                bnx2x_func_stats_init(bp);
index a812492..2adc294 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/skbuff.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
index 8545c7a..a5a89ec 100644 (file)
@@ -4026,6 +4026,12 @@ s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw)
                checksum += eeprom_data;
        }
 
+#ifdef CONFIG_PARISC
+       /* This is a signature and not a checksum on HP c8000 */
+       if ((hw->subsystem_vendor_id == 0x103C) && (eeprom_data == 0x16d6))
+               return E1000_SUCCESS;
+
+#endif
        if (checksum == (u16) EEPROM_SUM)
                return E1000_SUCCESS;
        else {
index 3e66792..8dd5fcc 100644 (file)
@@ -757,7 +757,7 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data)
        struct ibmveth_adapter *adapter = netdev_priv(dev);
        unsigned long set_attr, clr_attr, ret_attr;
        unsigned long set_attr6, clr_attr6;
-       long ret, ret6;
+       long ret, ret4, ret6;
        int rc1 = 0, rc2 = 0;
        int restart = 0;
 
@@ -770,6 +770,8 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data)
 
        set_attr = 0;
        clr_attr = 0;
+       set_attr6 = 0;
+       clr_attr6 = 0;
 
        if (data) {
                set_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM;
@@ -784,16 +786,20 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data)
        if (ret == H_SUCCESS && !(ret_attr & IBMVETH_ILLAN_ACTIVE_TRUNK) &&
            !(ret_attr & IBMVETH_ILLAN_TRUNK_PRI_MASK) &&
            (ret_attr & IBMVETH_ILLAN_PADDED_PKT_CSUM)) {
-               ret = h_illan_attributes(adapter->vdev->unit_address, clr_attr,
+               ret4 = h_illan_attributes(adapter->vdev->unit_address, clr_attr,
                                         set_attr, &ret_attr);
 
-               if (ret != H_SUCCESS) {
+               if (ret4 != H_SUCCESS) {
                        netdev_err(dev, "unable to change IPv4 checksum "
                                        "offload settings. %d rc=%ld\n",
-                                       data, ret);
+                                       data, ret4);
+
+                       h_illan_attributes(adapter->vdev->unit_address,
+                                          set_attr, clr_attr, &ret_attr);
+
+                       if (data == 1)
+                               dev->features &= ~NETIF_F_IP_CSUM;
 
-                       ret = h_illan_attributes(adapter->vdev->unit_address,
-                                                set_attr, clr_attr, &ret_attr);
                } else {
                        adapter->fw_ipv4_csum_support = data;
                }
@@ -804,15 +810,18 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data)
                if (ret6 != H_SUCCESS) {
                        netdev_err(dev, "unable to change IPv6 checksum "
                                        "offload settings. %d rc=%ld\n",
-                                       data, ret);
+                                       data, ret6);
+
+                       h_illan_attributes(adapter->vdev->unit_address,
+                                          set_attr6, clr_attr6, &ret_attr);
+
+                       if (data == 1)
+                               dev->features &= ~NETIF_F_IPV6_CSUM;
 
-                       ret = h_illan_attributes(adapter->vdev->unit_address,
-                                                set_attr6, clr_attr6,
-                                                &ret_attr);
                } else
                        adapter->fw_ipv6_csum_support = data;
 
-               if (ret != H_SUCCESS || ret6 != H_SUCCESS)
+               if (ret4 == H_SUCCESS || ret6 == H_SUCCESS)
                        adapter->rx_csum = data;
                else
                        rc1 = -EIO;
@@ -930,6 +939,7 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb,
        union ibmveth_buf_desc descs[6];
        int last, i;
        int force_bounce = 0;
+       dma_addr_t dma_addr;
 
        /*
         * veth handles a maximum of 6 segments including the header, so
@@ -994,17 +1004,16 @@ retry_bounce:
        }
 
        /* Map the header */
-       descs[0].fields.address = dma_map_single(&adapter->vdev->dev, skb->data,
-                                                skb_headlen(skb),
-                                                DMA_TO_DEVICE);
-       if (dma_mapping_error(&adapter->vdev->dev, descs[0].fields.address))
+       dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
+                                 skb_headlen(skb), DMA_TO_DEVICE);
+       if (dma_mapping_error(&adapter->vdev->dev, dma_addr))
                goto map_failed;
 
        descs[0].fields.flags_len = desc_flags | skb_headlen(skb);
+       descs[0].fields.address = dma_addr;
 
        /* Map the frags */
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-               unsigned long dma_addr;
                skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                dma_addr = dma_map_page(&adapter->vdev->dev, frag->page,
@@ -1026,7 +1035,12 @@ retry_bounce:
                netdev->stats.tx_bytes += skb->len;
        }
 
-       for (i = 0; i < skb_shinfo(skb)->nr_frags + 1; i++)
+       dma_unmap_single(&adapter->vdev->dev,
+                        descs[0].fields.address,
+                        descs[0].fields.flags_len & IBMVETH_BUF_LEN_MASK,
+                        DMA_TO_DEVICE);
+
+       for (i = 1; i < skb_shinfo(skb)->nr_frags + 1; i++)
                dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address,
                               descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK,
                               DMA_TO_DEVICE);
index 59fac77..a09a071 100644 (file)
@@ -127,8 +127,8 @@ struct pch_gbe_regs {
 
 /* Reset */
 #define PCH_GBE_ALL_RST         0x80000000  /* All reset */
-#define PCH_GBE_TX_RST          0x40000000  /* TX MAC, TX FIFO, TX DMA reset */
-#define PCH_GBE_RX_RST          0x04000000  /* RX MAC, RX FIFO, RX DMA reset */
+#define PCH_GBE_TX_RST          0x00008000  /* TX MAC, TX FIFO, TX DMA reset */
+#define PCH_GBE_RX_RST          0x00004000  /* RX MAC, RX FIFO, RX DMA reset */
 
 /* TCP/IP Accelerator Control */
 #define PCH_GBE_EX_LIST_EN      0x00000008  /* External List Enable */
@@ -276,6 +276,9 @@ struct pch_gbe_regs {
 #define PCH_GBE_RX_DMA_EN       0x00000002   /* Enables Receive DMA */
 #define PCH_GBE_TX_DMA_EN       0x00000001   /* Enables Transmission DMA */
 
+/* RX DMA STATUS */
+#define PCH_GBE_IDLE_CHECK       0xFFFFFFFE
+
 /* Wake On LAN Status */
 #define PCH_GBE_WLS_BR          0x00000008 /* Broadcas Address */
 #define PCH_GBE_WLS_MLT         0x00000004 /* Multicast Address */
@@ -471,6 +474,7 @@ struct pch_gbe_tx_desc {
 struct pch_gbe_buffer {
        struct sk_buff *skb;
        dma_addr_t dma;
+       unsigned char *rx_buffer;
        unsigned long time_stamp;
        u16 length;
        bool mapped;
@@ -511,6 +515,9 @@ struct pch_gbe_tx_ring {
 struct pch_gbe_rx_ring {
        struct pch_gbe_rx_desc *desc;
        dma_addr_t dma;
+       unsigned char *rx_buff_pool;
+       dma_addr_t rx_buff_pool_logic;
+       unsigned int rx_buff_pool_size;
        unsigned int size;
        unsigned int count;
        unsigned int next_to_use;
@@ -622,6 +629,7 @@ struct pch_gbe_adapter {
        unsigned long rx_buffer_len;
        unsigned long tx_queue_len;
        bool have_msi;
+       bool rx_stop_flag;
 };
 
 extern const char pch_driver_version[];
index eac3c5c..567ff10 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "pch_gbe.h"
 #include "pch_gbe_api.h"
-#include <linux/prefetch.h>
 
 #define DRV_VERSION     "1.00"
 const char pch_driver_version[] = DRV_VERSION;
@@ -34,11 +33,15 @@ const char pch_driver_version[] = DRV_VERSION;
 #define PCH_GBE_WATCHDOG_PERIOD                (1 * HZ)        /* watchdog time */
 #define PCH_GBE_COPYBREAK_DEFAULT      256
 #define PCH_GBE_PCI_BAR                        1
+#define PCH_GBE_RESERVE_MEMORY         0x200000        /* 2MB */
 
 /* Macros for ML7223 */
 #define PCI_VENDOR_ID_ROHM                     0x10db
 #define PCI_DEVICE_ID_ROHM_ML7223_GBE          0x8013
 
+/* Macros for ML7831 */
+#define PCI_DEVICE_ID_ROHM_ML7831_GBE          0x8802
+
 #define PCH_GBE_TX_WEIGHT         64
 #define PCH_GBE_RX_WEIGHT         64
 #define PCH_GBE_RX_BUFFER_WRITE   16
@@ -52,6 +55,7 @@ const char pch_driver_version[] = DRV_VERSION;
        )
 
 /* Ethertype field values */
+#define PCH_GBE_MAX_RX_BUFFER_SIZE      0x2880
 #define PCH_GBE_MAX_JUMBO_FRAME_SIZE    10318
 #define PCH_GBE_FRAME_SIZE_2048         2048
 #define PCH_GBE_FRAME_SIZE_4096         4096
@@ -83,10 +87,12 @@ const char pch_driver_version[] = DRV_VERSION;
 #define PCH_GBE_INT_ENABLE_MASK ( \
        PCH_GBE_INT_RX_DMA_CMPLT |    \
        PCH_GBE_INT_RX_DSC_EMP   |    \
+       PCH_GBE_INT_RX_FIFO_ERR  |    \
        PCH_GBE_INT_WOL_DET      |    \
        PCH_GBE_INT_TX_CMPLT          \
        )
 
+#define PCH_GBE_INT_DISABLE_ALL                0
 
 static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT;
 
@@ -138,6 +144,27 @@ static void pch_gbe_wait_clr_bit(void *reg, u32 bit)
        if (!tmp)
                pr_err("Error: busy bit is not cleared\n");
 }
+
+/**
+ * pch_gbe_wait_clr_bit_irq - Wait to clear a bit for interrupt context
+ * @reg:       Pointer of register
+ * @busy:      Busy bit
+ */
+static int pch_gbe_wait_clr_bit_irq(void *reg, u32 bit)
+{
+       u32 tmp;
+       int ret = -1;
+       /* wait busy */
+       tmp = 20;
+       while ((ioread32(reg) & bit) && --tmp)
+               udelay(5);
+       if (!tmp)
+               pr_err("Error: busy bit is not cleared\n");
+       else
+               ret = 0;
+       return ret;
+}
+
 /**
  * pch_gbe_mac_mar_set - Set MAC address register
  * @hw:            Pointer to the HW structure
@@ -189,6 +216,17 @@ static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw)
        return;
 }
 
+static void pch_gbe_mac_reset_rx(struct pch_gbe_hw *hw)
+{
+       /* Read the MAC address. and store to the private data */
+       pch_gbe_mac_read_mac_addr(hw);
+       iowrite32(PCH_GBE_RX_RST, &hw->reg->RESET);
+       pch_gbe_wait_clr_bit_irq(&hw->reg->RESET, PCH_GBE_RX_RST);
+       /* Setup the MAC address */
+       pch_gbe_mac_mar_set(hw, hw->mac.addr, 0);
+       return;
+}
+
 /**
  * pch_gbe_mac_init_rx_addrs - Initialize receive address's
  * @hw:        Pointer to the HW structure
@@ -671,13 +709,8 @@ static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter)
 
        tcpip = ioread32(&hw->reg->TCPIP_ACC);
 
-       if (netdev->features & NETIF_F_RXCSUM) {
-               tcpip &= ~PCH_GBE_RX_TCPIPACC_OFF;
-               tcpip |= PCH_GBE_RX_TCPIPACC_EN;
-       } else {
-               tcpip |= PCH_GBE_RX_TCPIPACC_OFF;
-               tcpip &= ~PCH_GBE_RX_TCPIPACC_EN;
-       }
+       tcpip |= PCH_GBE_RX_TCPIPACC_OFF;
+       tcpip &= ~PCH_GBE_RX_TCPIPACC_EN;
        iowrite32(tcpip, &hw->reg->TCPIP_ACC);
        return;
 }
@@ -717,13 +750,6 @@ static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter)
        iowrite32(rdba, &hw->reg->RX_DSC_BASE);
        iowrite32(rdlen, &hw->reg->RX_DSC_SIZE);
        iowrite32((rdba + rdlen), &hw->reg->RX_DSC_SW_P);
-
-       /* Enables Receive DMA */
-       rxdma = ioread32(&hw->reg->DMA_CTRL);
-       rxdma |= PCH_GBE_RX_DMA_EN;
-       iowrite32(rxdma, &hw->reg->DMA_CTRL);
-       /* Enables Receive */
-       iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN);
 }
 
 /**
@@ -1097,6 +1123,48 @@ void pch_gbe_update_stats(struct pch_gbe_adapter *adapter)
        spin_unlock_irqrestore(&adapter->stats_lock, flags);
 }
 
+static void pch_gbe_stop_receive(struct pch_gbe_adapter *adapter)
+{
+       struct pch_gbe_hw *hw = &adapter->hw;
+       u32 rxdma;
+       u16 value;
+       int ret;
+
+       /* Disable Receive DMA */
+       rxdma = ioread32(&hw->reg->DMA_CTRL);
+       rxdma &= ~PCH_GBE_RX_DMA_EN;
+       iowrite32(rxdma, &hw->reg->DMA_CTRL);
+       /* Wait Rx DMA BUS is IDLE */
+       ret = pch_gbe_wait_clr_bit_irq(&hw->reg->RX_DMA_ST, PCH_GBE_IDLE_CHECK);
+       if (ret) {
+               /* Disable Bus master */
+               pci_read_config_word(adapter->pdev, PCI_COMMAND, &value);
+               value &= ~PCI_COMMAND_MASTER;
+               pci_write_config_word(adapter->pdev, PCI_COMMAND, value);
+               /* Stop Receive */
+               pch_gbe_mac_reset_rx(hw);
+               /* Enable Bus master */
+               value |= PCI_COMMAND_MASTER;
+               pci_write_config_word(adapter->pdev, PCI_COMMAND, value);
+       } else {
+               /* Stop Receive */
+               pch_gbe_mac_reset_rx(hw);
+       }
+}
+
+static void pch_gbe_start_receive(struct pch_gbe_hw *hw)
+{
+       u32 rxdma;
+
+       /* Enables Receive DMA */
+       rxdma = ioread32(&hw->reg->DMA_CTRL);
+       rxdma |= PCH_GBE_RX_DMA_EN;
+       iowrite32(rxdma, &hw->reg->DMA_CTRL);
+       /* Enables Receive */
+       iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN);
+       return;
+}
+
 /**
  * pch_gbe_intr - Interrupt Handler
  * @irq:   Interrupt number
@@ -1123,7 +1191,15 @@ static irqreturn_t pch_gbe_intr(int irq, void *data)
        if (int_st & PCH_GBE_INT_RX_FRAME_ERR)
                adapter->stats.intr_rx_frame_err_count++;
        if (int_st & PCH_GBE_INT_RX_FIFO_ERR)
-               adapter->stats.intr_rx_fifo_err_count++;
+               if (!adapter->rx_stop_flag) {
+                       adapter->stats.intr_rx_fifo_err_count++;
+                       pr_debug("Rx fifo over run\n");
+                       adapter->rx_stop_flag = true;
+                       int_en = ioread32(&hw->reg->INT_EN);
+                       iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR),
+                                 &hw->reg->INT_EN);
+                       pch_gbe_stop_receive(adapter);
+               }
        if (int_st & PCH_GBE_INT_RX_DMA_ERR)
                adapter->stats.intr_rx_dma_err_count++;
        if (int_st & PCH_GBE_INT_TX_FIFO_ERR)
@@ -1135,7 +1211,7 @@ static irqreturn_t pch_gbe_intr(int irq, void *data)
        /* When Rx descriptor is empty  */
        if ((int_st & PCH_GBE_INT_RX_DSC_EMP)) {
                adapter->stats.intr_rx_dsc_empty_count++;
-               pr_err("Rx descriptor is empty\n");
+               pr_debug("Rx descriptor is empty\n");
                int_en = ioread32(&hw->reg->INT_EN);
                iowrite32((int_en & ~PCH_GBE_INT_RX_DSC_EMP), &hw->reg->INT_EN);
                if (hw->mac.tx_fc_enable) {
@@ -1185,29 +1261,23 @@ pch_gbe_alloc_rx_buffers(struct pch_gbe_adapter *adapter,
        unsigned int i;
        unsigned int bufsz;
 
-       bufsz = adapter->rx_buffer_len + PCH_GBE_DMA_ALIGN;
+       bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
        i = rx_ring->next_to_use;
 
        while ((cleaned_count--)) {
                buffer_info = &rx_ring->buffer_info[i];
-               skb = buffer_info->skb;
-               if (skb) {
-                       skb_trim(skb, 0);
-               } else {
-                       skb = netdev_alloc_skb(netdev, bufsz);
-                       if (unlikely(!skb)) {
-                               /* Better luck next round */
-                               adapter->stats.rx_alloc_buff_failed++;
-                               break;
-                       }
-                       /* 64byte align */
-                       skb_reserve(skb, PCH_GBE_DMA_ALIGN);
-
-                       buffer_info->skb = skb;
-                       buffer_info->length = adapter->rx_buffer_len;
+               skb = netdev_alloc_skb(netdev, bufsz);
+               if (unlikely(!skb)) {
+                       /* Better luck next round */
+                       adapter->stats.rx_alloc_buff_failed++;
+                       break;
                }
+               /* align */
+               skb_reserve(skb, NET_IP_ALIGN);
+               buffer_info->skb = skb;
+
                buffer_info->dma = dma_map_single(&pdev->dev,
-                                                 skb->data,
+                                                 buffer_info->rx_buffer,
                                                  buffer_info->length,
                                                  DMA_FROM_DEVICE);
                if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) {
@@ -1240,6 +1310,36 @@ pch_gbe_alloc_rx_buffers(struct pch_gbe_adapter *adapter,
        return;
 }
 
+static int
+pch_gbe_alloc_rx_buffers_pool(struct pch_gbe_adapter *adapter,
+                        struct pch_gbe_rx_ring *rx_ring, int cleaned_count)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       struct pch_gbe_buffer *buffer_info;
+       unsigned int i;
+       unsigned int bufsz;
+       unsigned int size;
+
+       bufsz = adapter->rx_buffer_len;
+
+       size = rx_ring->count * bufsz + PCH_GBE_RESERVE_MEMORY;
+       rx_ring->rx_buff_pool = dma_alloc_coherent(&pdev->dev, size,
+                                               &rx_ring->rx_buff_pool_logic,
+                                               GFP_KERNEL);
+       if (!rx_ring->rx_buff_pool) {
+               pr_err("Unable to allocate memory for the receive poll buffer\n");
+               return -ENOMEM;
+       }
+       memset(rx_ring->rx_buff_pool, 0, size);
+       rx_ring->rx_buff_pool_size = size;
+       for (i = 0; i < rx_ring->count; i++) {
+               buffer_info = &rx_ring->buffer_info[i];
+               buffer_info->rx_buffer = rx_ring->rx_buff_pool + bufsz * i;
+               buffer_info->length = bufsz;
+       }
+       return 0;
+}
+
 /**
  * pch_gbe_alloc_tx_buffers - Allocate transmit buffers
  * @adapter:   Board private structure
@@ -1380,7 +1480,7 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
        unsigned int i;
        unsigned int cleaned_count = 0;
        bool cleaned = false;
-       struct sk_buff *skb, *new_skb;
+       struct sk_buff *skb;
        u8 dma_status;
        u16 gbec_status;
        u32 tcp_ip_status;
@@ -1401,13 +1501,12 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
                rx_desc->gbec_status = DSC_INIT16;
                buffer_info = &rx_ring->buffer_info[i];
                skb = buffer_info->skb;
+               buffer_info->skb = NULL;
 
                /* unmap dma */
                dma_unmap_single(&pdev->dev, buffer_info->dma,
                                   buffer_info->length, DMA_FROM_DEVICE);
                buffer_info->mapped = false;
-               /* Prefetch the packet */
-               prefetch(skb->data);
 
                pr_debug("RxDecNo = 0x%04x  Status[DMA:0x%02x GBE:0x%04x "
                         "TCP:0x%08x]  BufInf = 0x%p\n",
@@ -1427,70 +1526,16 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
                        pr_err("Receive CRC Error\n");
                } else {
                        /* get receive length */
-                       /* length convert[-3] */
-                       length = (rx_desc->rx_words_eob) - 3;
-
-                       /* Decide the data conversion method */
-                       if (!(netdev->features & NETIF_F_RXCSUM)) {
-                               /* [Header:14][payload] */
-                               if (NET_IP_ALIGN) {
-                                       /* Because alignment differs,
-                                        * the new_skb is newly allocated,
-                                        * and data is copied to new_skb.*/
-                                       new_skb = netdev_alloc_skb(netdev,
-                                                        length + NET_IP_ALIGN);
-                                       if (!new_skb) {
-                                               /* dorrop error */
-                                               pr_err("New skb allocation "
-                                                       "Error\n");
-                                               goto dorrop;
-                                       }
-                                       skb_reserve(new_skb, NET_IP_ALIGN);
-                                       memcpy(new_skb->data, skb->data,
-                                              length);
-                                       skb = new_skb;
-                               } else {
-                                       /* DMA buffer is used as SKB as it is.*/
-                                       buffer_info->skb = NULL;
-                               }
-                       } else {
-                               /* [Header:14][padding:2][payload] */
-                               /* The length includes padding length */
-                               length = length - PCH_GBE_DMA_PADDING;
-                               if ((length < copybreak) ||
-                                   (NET_IP_ALIGN != PCH_GBE_DMA_PADDING)) {
-                                       /* Because alignment differs,
-                                        * the new_skb is newly allocated,
-                                        * and data is copied to new_skb.
-                                        * Padding data is deleted
-                                        * at the time of a copy.*/
-                                       new_skb = netdev_alloc_skb(netdev,
-                                                        length + NET_IP_ALIGN);
-                                       if (!new_skb) {
-                                               /* dorrop error */
-                                               pr_err("New skb allocation "
-                                                       "Error\n");
-                                               goto dorrop;
-                                       }
-                                       skb_reserve(new_skb, NET_IP_ALIGN);
-                                       memcpy(new_skb->data, skb->data,
-                                              ETH_HLEN);
-                                       memcpy(&new_skb->data[ETH_HLEN],
-                                              &skb->data[ETH_HLEN +
-                                              PCH_GBE_DMA_PADDING],
-                                              length - ETH_HLEN);
-                                       skb = new_skb;
-                               } else {
-                                       /* Padding data is deleted
-                                        * by moving header data.*/
-                                       memmove(&skb->data[PCH_GBE_DMA_PADDING],
-                                               &skb->data[0], ETH_HLEN);
-                                       skb_reserve(skb, NET_IP_ALIGN);
-                                       buffer_info->skb = NULL;
-                               }
-                       }
-                       /* The length includes FCS length */
-                       length = length - ETH_FCS_LEN;
+                       /* length convert[-3], length includes FCS length */
+                       length = (rx_desc->rx_words_eob) - 3 - ETH_FCS_LEN;
+                       if (rx_desc->rx_words_eob & 0x02)
+                               length = length - 4;
+                       /*
+                        * buffer_info->rx_buffer: [Header:14][payload]
+                        * skb->data: [Reserve:2][Header:14][payload]
+                        */
+                       memcpy(skb->data, buffer_info->rx_buffer, length);
+
                        /* update status of driver */
                        adapter->stats.rx_bytes += length;
                        adapter->stats.rx_packets++;
@@ -1509,7 +1554,6 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
                        pr_debug("Receive skb->ip_summed: %d length: %d\n",
                                 skb->ip_summed, length);
                }
-dorrop:
                /* return some buffers to hardware, one at a time is too slow */
                if (unlikely(cleaned_count >= PCH_GBE_RX_BUFFER_WRITE)) {
                        pch_gbe_alloc_rx_buffers(adapter, rx_ring,
@@ -1714,9 +1758,15 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter)
                pr_err("Error: can't bring device up\n");
                return err;
        }
+       err = pch_gbe_alloc_rx_buffers_pool(adapter, rx_ring, rx_ring->count);
+       if (err) {
+               pr_err("Error: can't bring device up\n");
+               return err;
+       }
        pch_gbe_alloc_tx_buffers(adapter, tx_ring);
        pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count);
        adapter->tx_queue_len = netdev->tx_queue_len;
+       pch_gbe_start_receive(&adapter->hw);
 
        mod_timer(&adapter->watchdog_timer, jiffies);
 
@@ -1734,6 +1784,7 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter)
 void pch_gbe_down(struct pch_gbe_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
+       struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
 
        /* signal that we're down so the interrupt handler does not
         * reschedule our watchdog timer */
@@ -1752,6 +1803,12 @@ void pch_gbe_down(struct pch_gbe_adapter *adapter)
        pch_gbe_reset(adapter);
        pch_gbe_clean_tx_ring(adapter, adapter->tx_ring);
        pch_gbe_clean_rx_ring(adapter, adapter->rx_ring);
+
+       pci_free_consistent(adapter->pdev, rx_ring->rx_buff_pool_size,
+                           rx_ring->rx_buff_pool, rx_ring->rx_buff_pool_logic);
+       rx_ring->rx_buff_pool_logic = 0;
+       rx_ring->rx_buff_pool_size = 0;
+       rx_ring->rx_buff_pool = NULL;
 }
 
 /**
@@ -2004,6 +2061,8 @@ static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu)
 {
        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
        int max_frame;
+       unsigned long old_rx_buffer_len = adapter->rx_buffer_len;
+       int err;
 
        max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
        if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
@@ -2018,14 +2077,24 @@ static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu)
        else if (max_frame <= PCH_GBE_FRAME_SIZE_8192)
                adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_8192;
        else
-               adapter->rx_buffer_len = PCH_GBE_MAX_JUMBO_FRAME_SIZE;
-       netdev->mtu = new_mtu;
-       adapter->hw.mac.max_frame_size = max_frame;
+               adapter->rx_buffer_len = PCH_GBE_MAX_RX_BUFFER_SIZE;
 
-       if (netif_running(netdev))
-               pch_gbe_reinit_locked(adapter);
-       else
+       if (netif_running(netdev)) {
+               pch_gbe_down(adapter);
+               err = pch_gbe_up(adapter);
+               if (err) {
+                       adapter->rx_buffer_len = old_rx_buffer_len;
+                       pch_gbe_up(adapter);
+                       return -ENOMEM;
+               } else {
+                       netdev->mtu = new_mtu;
+                       adapter->hw.mac.max_frame_size = max_frame;
+               }
+       } else {
                pch_gbe_reset(adapter);
+               netdev->mtu = new_mtu;
+               adapter->hw.mac.max_frame_size = max_frame;
+       }
 
        pr_debug("max_frame : %d  rx_buffer_len : %d  mtu : %d  max_frame_size : %d\n",
                 max_frame, (u32) adapter->rx_buffer_len, netdev->mtu,
@@ -2103,6 +2172,7 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget)
        int work_done = 0;
        bool poll_end_flag = false;
        bool cleaned = false;
+       u32 int_en;
 
        pr_debug("budget : %d\n", budget);
 
@@ -2110,8 +2180,15 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget)
        if (!netif_carrier_ok(netdev)) {
                poll_end_flag = true;
        } else {
-               cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring);
                pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget);
+               if (adapter->rx_stop_flag) {
+                       adapter->rx_stop_flag = false;
+                       pch_gbe_start_receive(&adapter->hw);
+                       int_en = ioread32(&adapter->hw.reg->INT_EN);
+                       iowrite32((int_en | PCH_GBE_INT_RX_FIFO_ERR),
+                                       &adapter->hw.reg->INT_EN);
+               }
+               cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring);
 
                if (cleaned)
                        work_done = budget;
@@ -2452,6 +2529,13 @@ static DEFINE_PCI_DEVICE_TABLE(pch_gbe_pcidev_id) = {
         .class = (PCI_CLASS_NETWORK_ETHERNET << 8),
         .class_mask = (0xFFFF00)
         },
+       {.vendor = PCI_VENDOR_ID_ROHM,
+        .device = PCI_DEVICE_ID_ROHM_ML7831_GBE,
+        .subvendor = PCI_ANY_ID,
+        .subdevice = PCI_ANY_ID,
+        .class = (PCI_CLASS_NETWORK_ETHERNET << 8),
+        .class_mask = (0xFFFF00)
+        },
        /* required last entry */
        {0}
 };
index faca764..b59abc7 100644 (file)
@@ -1050,7 +1050,6 @@ static int efx_init_io(struct efx_nic *efx)
 {
        struct pci_dev *pci_dev = efx->pci_dev;
        dma_addr_t dma_mask = efx->type->max_dma_mask;
-       bool use_wc;
        int rc;
 
        netif_dbg(efx, probe, efx->net_dev, "initialising I/O\n");
@@ -1101,21 +1100,8 @@ static int efx_init_io(struct efx_nic *efx)
                rc = -EIO;
                goto fail3;
        }
-
-       /* bug22643: If SR-IOV is enabled then tx push over a write combined
-        * mapping is unsafe. We need to disable write combining in this case.
-        * MSI is unsupported when SR-IOV is enabled, and the firmware will
-        * have removed the MSI capability. So write combining is safe if
-        * there is an MSI capability.
-        */
-       use_wc = (!EFX_WORKAROUND_22643(efx) ||
-                 pci_find_capability(pci_dev, PCI_CAP_ID_MSI));
-       if (use_wc)
-               efx->membase = ioremap_wc(efx->membase_phys,
-                                         efx->type->mem_map_size);
-       else
-               efx->membase = ioremap_nocache(efx->membase_phys,
-                                              efx->type->mem_map_size);
+       efx->membase = ioremap_nocache(efx->membase_phys,
+                                      efx->type->mem_map_size);
        if (!efx->membase) {
                netif_err(efx, probe, efx->net_dev,
                          "could not map memory BAR at %llx+%x\n",
index cc97880..751d1ec 100644 (file)
@@ -103,7 +103,6 @@ static inline void efx_writeo(struct efx_nic *efx, efx_oword_t *value,
        _efx_writed(efx, value->u32[2], reg + 8);
        _efx_writed(efx, value->u32[3], reg + 12);
 #endif
-       wmb();
        mmiowb();
        spin_unlock_irqrestore(&efx->biu_lock, flags);
 }
@@ -126,7 +125,6 @@ static inline void efx_sram_writeq(struct efx_nic *efx, void __iomem *membase,
        __raw_writel((__force u32)value->u32[0], membase + addr);
        __raw_writel((__force u32)value->u32[1], membase + addr + 4);
 #endif
-       wmb();
        mmiowb();
        spin_unlock_irqrestore(&efx->biu_lock, flags);
 }
@@ -141,7 +139,6 @@ static inline void efx_writed(struct efx_nic *efx, efx_dword_t *value,
 
        /* No lock required */
        _efx_writed(efx, value->u32[0], reg);
-       wmb();
 }
 
 /* Read a 128-bit CSR, locking as appropriate. */
@@ -152,7 +149,6 @@ static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value,
 
        spin_lock_irqsave(&efx->biu_lock, flags);
        value->u32[0] = _efx_readd(efx, reg + 0);
-       rmb();
        value->u32[1] = _efx_readd(efx, reg + 4);
        value->u32[2] = _efx_readd(efx, reg + 8);
        value->u32[3] = _efx_readd(efx, reg + 12);
@@ -175,7 +171,6 @@ static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase,
        value->u64[0] = (__force __le64)__raw_readq(membase + addr);
 #else
        value->u32[0] = (__force __le32)__raw_readl(membase + addr);
-       rmb();
        value->u32[1] = (__force __le32)__raw_readl(membase + addr + 4);
 #endif
        spin_unlock_irqrestore(&efx->biu_lock, flags);
@@ -249,7 +244,6 @@ static inline void _efx_writeo_page(struct efx_nic *efx, efx_oword_t *value,
        _efx_writed(efx, value->u32[2], reg + 8);
        _efx_writed(efx, value->u32[3], reg + 12);
 #endif
-       wmb();
 }
 #define efx_writeo_page(efx, value, reg, page)                         \
        _efx_writeo_page(efx, value,                                    \
index 3dd45ed..81a4253 100644 (file)
@@ -50,20 +50,6 @@ static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx)
        return &nic_data->mcdi;
 }
 
-static inline void
-efx_mcdi_readd(struct efx_nic *efx, efx_dword_t *value, unsigned reg)
-{
-       struct siena_nic_data *nic_data = efx->nic_data;
-       value->u32[0] = (__force __le32)__raw_readl(nic_data->mcdi_smem + reg);
-}
-
-static inline void
-efx_mcdi_writed(struct efx_nic *efx, const efx_dword_t *value, unsigned reg)
-{
-       struct siena_nic_data *nic_data = efx->nic_data;
-       __raw_writel((__force u32)value->u32[0], nic_data->mcdi_smem + reg);
-}
-
 void efx_mcdi_init(struct efx_nic *efx)
 {
        struct efx_mcdi_iface *mcdi;
@@ -84,8 +70,8 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd,
                            const u8 *inbuf, size_t inlen)
 {
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
-       unsigned pdu = MCDI_PDU(efx);
-       unsigned doorbell = MCDI_DOORBELL(efx);
+       unsigned pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
+       unsigned doorbell = FR_CZ_MC_TREG_SMEM + MCDI_DOORBELL(efx);
        unsigned int i;
        efx_dword_t hdr;
        u32 xflags, seqno;
@@ -106,28 +92,29 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd,
                             MCDI_HEADER_SEQ, seqno,
                             MCDI_HEADER_XFLAGS, xflags);
 
-       efx_mcdi_writed(efx, &hdr, pdu);
+       efx_writed(efx, &hdr, pdu);
 
        for (i = 0; i < inlen; i += 4)
-               efx_mcdi_writed(efx, (const efx_dword_t *)(inbuf + i),
-                               pdu + 4 + i);
+               _efx_writed(efx, *((__le32 *)(inbuf + i)), pdu + 4 + i);
+
+       /* Ensure the payload is written out before the header */
+       wmb();
 
        /* ring the doorbell with a distinctive value */
-       EFX_POPULATE_DWORD_1(hdr, EFX_DWORD_0, 0x45789abc);
-       efx_mcdi_writed(efx, &hdr, doorbell);
+       _efx_writed(efx, (__force __le32) 0x45789abc, doorbell);
 }
 
 static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen)
 {
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
-       unsigned int pdu = MCDI_PDU(efx);
+       unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
        int i;
 
        BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT);
        BUG_ON(outlen & 3 || outlen >= 0x100);
 
        for (i = 0; i < outlen; i += 4)
-               efx_mcdi_readd(efx, (efx_dword_t *)(outbuf + i), pdu + 4 + i);
+               *((__le32 *)(outbuf + i)) = _efx_readd(efx, pdu + 4 + i);
 }
 
 static int efx_mcdi_poll(struct efx_nic *efx)
@@ -135,7 +122,7 @@ static int efx_mcdi_poll(struct efx_nic *efx)
        struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
        unsigned int time, finish;
        unsigned int respseq, respcmd, error;
-       unsigned int pdu = MCDI_PDU(efx);
+       unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx);
        unsigned int rc, spins;
        efx_dword_t reg;
 
@@ -161,7 +148,8 @@ static int efx_mcdi_poll(struct efx_nic *efx)
 
                time = get_seconds();
 
-               efx_mcdi_readd(efx, &reg, pdu);
+               rmb();
+               efx_readd(efx, &reg, pdu);
 
                /* All 1's indicates that shared memory is in reset (and is
                 * not a valid header). Wait for it to come out reset before
@@ -188,7 +176,7 @@ static int efx_mcdi_poll(struct efx_nic *efx)
                          respseq, mcdi->seqno);
                rc = EIO;
        } else if (error) {
-               efx_mcdi_readd(efx, &reg, pdu + 4);
+               efx_readd(efx, &reg, pdu + 4);
                switch (EFX_DWORD_FIELD(reg, EFX_DWORD_0)) {
 #define TRANSLATE_ERROR(name)                                  \
                case MC_CMD_ERR_ ## name:                       \
@@ -222,21 +210,21 @@ out:
 /* Test and clear MC-rebooted flag for this port/function */
 int efx_mcdi_poll_reboot(struct efx_nic *efx)
 {
-       unsigned int addr = MCDI_REBOOT_FLAG(efx);
+       unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_REBOOT_FLAG(efx);
        efx_dword_t reg;
        uint32_t value;
 
        if (efx_nic_rev(efx) < EFX_REV_SIENA_A0)
                return false;
 
-       efx_mcdi_readd(efx, &reg, addr);
+       efx_readd(efx, &reg, addr);
        value = EFX_DWORD_FIELD(reg, EFX_DWORD_0);
 
        if (value == 0)
                return 0;
 
        EFX_ZERO_DWORD(reg);
-       efx_mcdi_writed(efx, &reg, addr);
+       efx_writed(efx, &reg, addr);
 
        if (value == MC_STATUS_DWORD_ASSERT)
                return -EINTR;
index bafa23a..3edfbaf 100644 (file)
@@ -1936,13 +1936,6 @@ void efx_nic_get_regs(struct efx_nic *efx, void *buf)
 
                size = min_t(size_t, table->step, 16);
 
-               if (table->offset >= efx->type->mem_map_size) {
-                       /* No longer mapped; return dummy data */
-                       memcpy(buf, "\xde\xc0\xad\xde", 4);
-                       buf += table->rows * size;
-                       continue;
-               }
-
                for (i = 0; i < table->rows; i++) {
                        switch (table->step) {
                        case 4: /* 32-bit register or SRAM */
index 4bd1f28..7443f99 100644 (file)
@@ -143,12 +143,10 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx)
 /**
  * struct siena_nic_data - Siena NIC state
  * @mcdi: Management-Controller-to-Driver Interface
- * @mcdi_smem: MCDI shared memory mapping. The mapping is always uncacheable.
  * @wol_filter_id: Wake-on-LAN packet filter id
  */
 struct siena_nic_data {
        struct efx_mcdi_iface mcdi;
-       void __iomem *mcdi_smem;
        int wol_filter_id;
 };
 
index 5735e84..2c3bd93 100644 (file)
@@ -250,26 +250,12 @@ static int siena_probe_nic(struct efx_nic *efx)
        efx_reado(efx, &reg, FR_AZ_CS_DEBUG);
        efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1;
 
-       /* Initialise MCDI */
-       nic_data->mcdi_smem = ioremap_nocache(efx->membase_phys +
-                                             FR_CZ_MC_TREG_SMEM,
-                                             FR_CZ_MC_TREG_SMEM_STEP *
-                                             FR_CZ_MC_TREG_SMEM_ROWS);
-       if (!nic_data->mcdi_smem) {
-               netif_err(efx, probe, efx->net_dev,
-                         "could not map MCDI at %llx+%x\n",
-                         (unsigned long long)efx->membase_phys +
-                         FR_CZ_MC_TREG_SMEM,
-                         FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS);
-               rc = -ENOMEM;
-               goto fail1;
-       }
        efx_mcdi_init(efx);
 
        /* Recover from a failed assertion before probing */
        rc = efx_mcdi_handle_assertion(efx);
        if (rc)
-               goto fail2;
+               goto fail1;
 
        /* Let the BMC know that the driver is now in charge of link and
         * filter settings. We must do this before we reset the NIC */
@@ -324,7 +310,6 @@ fail4:
 fail3:
        efx_mcdi_drv_attach(efx, false, NULL);
 fail2:
-       iounmap(nic_data->mcdi_smem);
 fail1:
        kfree(efx->nic_data);
        return rc;
@@ -404,8 +389,6 @@ static int siena_init_nic(struct efx_nic *efx)
 
 static void siena_remove_nic(struct efx_nic *efx)
 {
-       struct siena_nic_data *nic_data = efx->nic_data;
-
        efx_nic_free_buffer(efx, &efx->irq_status);
 
        siena_reset_hw(efx, RESET_TYPE_ALL);
@@ -415,8 +398,7 @@ static void siena_remove_nic(struct efx_nic *efx)
                efx_mcdi_drv_attach(efx, false, NULL);
 
        /* Tear down the private nic state */
-       iounmap(nic_data->mcdi_smem);
-       kfree(nic_data);
+       kfree(efx->nic_data);
        efx->nic_data = NULL;
 }
 
@@ -656,7 +638,8 @@ const struct efx_nic_type siena_a0_nic_type = {
        .default_mac_ops = &efx_mcdi_mac_operations,
 
        .revision = EFX_REV_SIENA_A0,
-       .mem_map_size = FR_CZ_MC_TREG_SMEM, /* MC_TREG_SMEM mapped separately */
+       .mem_map_size = (FR_CZ_MC_TREG_SMEM +
+                        FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS),
        .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL,
        .rxd_ptr_tbl_base = FR_BZ_RX_DESC_PTR_TBL,
        .buf_tbl_base = FR_BZ_BUF_FULL_TBL,
index 99ff114..e4dd3a7 100644 (file)
@@ -38,8 +38,6 @@
 #define EFX_WORKAROUND_15783 EFX_WORKAROUND_ALWAYS
 /* Legacy interrupt storm when interrupt fifo fills */
 #define EFX_WORKAROUND_17213 EFX_WORKAROUND_SIENA
-/* Write combining and sriov=enabled are incompatible */
-#define EFX_WORKAROUND_22643 EFX_WORKAROUND_SIENA
 
 /* Spurious parity errors in TSORT buffers */
 #define EFX_WORKAROUND_5129 EFX_WORKAROUND_FALCON_A
index 15772b1..13c1f04 100644 (file)
@@ -59,6 +59,7 @@
 #define USB_PRODUCT_IPHONE_3G   0x1292
 #define USB_PRODUCT_IPHONE_3GS  0x1294
 #define USB_PRODUCT_IPHONE_4   0x1297
+#define USB_PRODUCT_IPHONE_4_VZW 0x129c
 
 #define IPHETH_USBINTF_CLASS    255
 #define IPHETH_USBINTF_SUBCLASS 253
@@ -98,6 +99,10 @@ static struct usb_device_id ipheth_table[] = {
                USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4,
                IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
                IPHETH_USBINTF_PROTO) },
+       { USB_DEVICE_AND_INTERFACE_INFO(
+               USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW,
+               IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+               IPHETH_USBINTF_PROTO) },
        { }
 };
 MODULE_DEVICE_TABLE(usb, ipheth_table);
index 2d4c091..2d394af 100644 (file)
@@ -41,7 +41,8 @@ static bool ar9002_hw_is_cal_supported(struct ath_hw *ah,
        case ADC_DC_CAL:
                /* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */
                if (!IS_CHAN_B(chan) &&
-                   !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
+                   !((IS_CHAN_2GHZ(chan) || IS_CHAN_A_FAST_CLOCK(ah, chan)) &&
+                     IS_CHAN_HT20(chan)))
                        supported = true;
                break;
        }
index 1baca8e..fcafec0 100644 (file)
@@ -671,7 +671,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
                REG_WRITE_ARRAY(&ah->iniModesAdditional,
                                modesIndex, regWrites);
 
-       if (AR_SREV_9300(ah))
+       if (AR_SREV_9330(ah))
                REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites);
 
        if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
index 6530694..722967b 100644 (file)
@@ -2303,6 +2303,12 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
        mutex_lock(&sc->mutex);
        cancel_delayed_work_sync(&sc->tx_complete_work);
 
+       if (ah->ah_flags & AH_UNPLUGGED) {
+               ath_dbg(common, ATH_DBG_ANY, "Device has been unplugged!\n");
+               mutex_unlock(&sc->mutex);
+               return;
+       }
+
        if (sc->sc_flags & SC_OP_INVALID) {
                ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
                mutex_unlock(&sc->mutex);
index 977bd24..164bcae 100644 (file)
@@ -822,12 +822,15 @@ static void iwl3945_rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
 
  out:
 
-       rs_sta->last_txrate_idx = index;
-       if (sband->band == IEEE80211_BAND_5GHZ)
-               info->control.rates[0].idx = rs_sta->last_txrate_idx -
-                               IWL_FIRST_OFDM_RATE;
-       else
+       if (sband->band == IEEE80211_BAND_5GHZ) {
+               if (WARN_ON_ONCE(index < IWL_FIRST_OFDM_RATE))
+                       index = IWL_FIRST_OFDM_RATE;
+               rs_sta->last_txrate_idx = index;
+               info->control.rates[0].idx = index - IWL_FIRST_OFDM_RATE;
+       } else {
+               rs_sta->last_txrate_idx = index;
                info->control.rates[0].idx = rs_sta->last_txrate_idx;
+       }
 
        IWL_DEBUG_RATE(priv, "leave: %d\n", index);
 }
index a895a09..5621100 100644 (file)
@@ -167,7 +167,7 @@ static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv)
 
        memset(&cmd, 0, sizeof(cmd));
        iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD);
-       memcpy(&cmd.radio_sensor_offset, offset_calib, sizeof(offset_calib));
+       memcpy(&cmd.radio_sensor_offset, offset_calib, sizeof(*offset_calib));
        if (!(cmd.radio_sensor_offset))
                cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET;
 
index a6b2b1d..222d410 100644 (file)
@@ -771,6 +771,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        cmd = txq->cmd[cmd_index];
        meta = &txq->meta[cmd_index];
 
+       txq->time_stamp = jiffies;
+
        iwlagn_unmap_tfd(priv, meta, &txq->tfds[index], DMA_BIDIRECTIONAL);
 
        /* Input error checking is done when commands are added to queue. */
index 1bdc1aa..04c4e9e 100644 (file)
@@ -610,6 +610,11 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
 
                        mac->link_state = MAC80211_NOLINK;
                        memset(mac->bssid, 0, 6);
+
+                       /* reset sec info */
+                       rtl_cam_reset_sec_info(hw);
+
+                       rtl_cam_reset_all_entry(hw);
                        mac->vendor = PEER_UNKNOWN;
 
                        RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
@@ -1063,6 +1068,9 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                 *or clear all entry here.
                 */
                rtl_cam_delete_one_entry(hw, mac_addr, key_idx);
+
+               rtl_cam_reset_sec_info(hw);
+
                break;
        default:
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
index 906e7aa..3e52a54 100644 (file)
@@ -549,15 +549,16 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
                               (tcb_desc->rts_use_shortpreamble ? 1 : 0)
                               : (tcb_desc->rts_use_shortgi ? 1 : 0)));
        if (mac->bw_40) {
-               if (tcb_desc->packet_bw) {
+               if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
                        SET_TX_DESC_DATA_BW(txdesc, 1);
                        SET_TX_DESC_DATA_SC(txdesc, 3);
+               } else if(rate_flag & IEEE80211_TX_RC_40_MHZ_WIDTH){
+                       SET_TX_DESC_DATA_BW(txdesc, 1);
+                       SET_TX_DESC_DATA_SC(txdesc, mac->cur_40_prime_sc);
                } else {
                        SET_TX_DESC_DATA_BW(txdesc, 0);
-                               if (rate_flag & IEEE80211_TX_RC_DUP_DATA)
-                                       SET_TX_DESC_DATA_SC(txdesc,
-                                                         mac->cur_40_prime_sc);
-                       }
+                       SET_TX_DESC_DATA_SC(txdesc, 0);
+               }
        } else {
                SET_TX_DESC_DATA_BW(txdesc, 0);
                SET_TX_DESC_DATA_SC(txdesc, 0);
index b1187ff..f3f94a5 100644 (file)
@@ -1351,7 +1351,8 @@ static int pcie_find_smpss(struct pci_dev *dev, void *data)
         * will occur as normal.
         */
        if (dev->is_hotplug_bridge && (!list_is_singular(&dev->bus->devices) ||
-           dev->bus->self->pcie_type != PCI_EXP_TYPE_ROOT_PORT))
+            (dev->bus->self &&
+             dev->bus->self->pcie_type != PCI_EXP_TYPE_ROOT_PORT)))
                *smpss = 0;
 
        if (*smpss > dev->pcie_mpss)
index 2dd3c01..d93a960 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
+#include <linux/sched.h>
 #include <linux/workqueue.h>
 
 /* DryIce Register Definitions */
index 4e7c04e..7639ab9 100644 (file)
@@ -51,6 +51,27 @@ static enum s3c_cpu_type s3c_rtc_cpu_type;
 
 static DEFINE_SPINLOCK(s3c_rtc_pie_lock);
 
+static void s3c_rtc_alarm_clk_enable(bool enable)
+{
+       static DEFINE_SPINLOCK(s3c_rtc_alarm_clk_lock);
+       static bool alarm_clk_enabled;
+       unsigned long irq_flags;
+
+       spin_lock_irqsave(&s3c_rtc_alarm_clk_lock, irq_flags);
+       if (enable) {
+               if (!alarm_clk_enabled) {
+                       clk_enable(rtc_clk);
+                       alarm_clk_enabled = true;
+               }
+       } else {
+               if (alarm_clk_enabled) {
+                       clk_disable(rtc_clk);
+                       alarm_clk_enabled = false;
+               }
+       }
+       spin_unlock_irqrestore(&s3c_rtc_alarm_clk_lock, irq_flags);
+}
+
 /* IRQ Handlers */
 
 static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
@@ -64,6 +85,9 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
                writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP);
 
        clk_disable(rtc_clk);
+
+       s3c_rtc_alarm_clk_enable(false);
+
        return IRQ_HANDLED;
 }
 
@@ -97,6 +121,8 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled)
        writeb(tmp, s3c_rtc_base + S3C2410_RTCALM);
        clk_disable(rtc_clk);
 
+       s3c_rtc_alarm_clk_enable(enabled);
+
        return 0;
 }
 
index 9ae80cd..dba72a4 100644 (file)
@@ -563,7 +563,7 @@ int bnx2i_send_iscsi_nopout(struct bnx2i_conn *bnx2i_conn,
        nopout_wqe->itt = ((u16)task->itt |
                           (ISCSI_TASK_TYPE_MPATH <<
                            ISCSI_TMF_REQUEST_TYPE_SHIFT));
-       nopout_wqe->ttt = nopout_hdr->ttt;
+       nopout_wqe->ttt = be32_to_cpu(nopout_hdr->ttt);
        nopout_wqe->flags = 0;
        if (!unsol)
                nopout_wqe->flags = ISCSI_NOP_OUT_REQUEST_LOCAL_COMPLETION;
index ba710e3..5d0e9a2 100644 (file)
@@ -432,6 +432,8 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
        u8 flogi_maddr[ETH_ALEN];
        const struct net_device_ops *ops;
 
+       rtnl_lock();
+
        /*
         * Don't listen for Ethernet packets anymore.
         * synchronize_net() ensures that the packet handlers are not running
@@ -461,6 +463,8 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
                                        " specific feature for LLD.\n");
        }
 
+       rtnl_unlock();
+
        /* Release the self-reference taken during fcoe_interface_create() */
        fcoe_interface_put(fcoe);
 }
@@ -1951,11 +1955,8 @@ static void fcoe_destroy_work(struct work_struct *work)
        fcoe_if_destroy(port->lport);
 
        /* Do not tear down the fcoe interface for NPIV port */
-       if (!npiv) {
-               rtnl_lock();
+       if (!npiv)
                fcoe_interface_cleanup(fcoe);
-               rtnl_unlock();
-       }
 
        mutex_unlock(&fcoe_config_mutex);
 }
@@ -2009,8 +2010,9 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
                printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
                       netdev->name);
                rc = -EIO;
+               rtnl_unlock();
                fcoe_interface_cleanup(fcoe);
-               goto out_nodev;
+               goto out_nortnl;
        }
 
        /* Make this the "master" N_Port */
@@ -2027,6 +2029,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
 
 out_nodev:
        rtnl_unlock();
+out_nortnl:
        mutex_unlock(&fcoe_config_mutex);
        return rc;
 }
index ec61bdb..b200b73 100644 (file)
@@ -676,6 +676,16 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno,
        BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA);
        removed[*nremoved] = h->dev[entry];
        (*nremoved)++;
+
+       /*
+        * New physical devices won't have target/lun assigned yet
+        * so we need to preserve the values in the slot we are replacing.
+        */
+       if (new_entry->target == -1) {
+               new_entry->target = h->dev[entry]->target;
+               new_entry->lun = h->dev[entry]->lun;
+       }
+
        h->dev[entry] = new_entry;
        added[*nadded] = new_entry;
        (*nadded)++;
@@ -1548,10 +1558,17 @@ static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device,
 }
 
 static int hpsa_update_device_info(struct ctlr_info *h,
-       unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device)
+       unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device,
+       unsigned char *is_OBDR_device)
 {
-#define OBDR_TAPE_INQ_SIZE 49
+
+#define OBDR_SIG_OFFSET 43
+#define OBDR_TAPE_SIG "$DR-10"
+#define OBDR_SIG_LEN (sizeof(OBDR_TAPE_SIG) - 1)
+#define OBDR_TAPE_INQ_SIZE (OBDR_SIG_OFFSET + OBDR_SIG_LEN)
+
        unsigned char *inq_buff;
+       unsigned char *obdr_sig;
 
        inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
        if (!inq_buff)
@@ -1583,6 +1600,16 @@ static int hpsa_update_device_info(struct ctlr_info *h,
        else
                this_device->raid_level = RAID_UNKNOWN;
 
+       if (is_OBDR_device) {
+               /* See if this is a One-Button-Disaster-Recovery device
+                * by looking for "$DR-10" at offset 43 in inquiry data.
+                */
+               obdr_sig = &inq_buff[OBDR_SIG_OFFSET];
+               *is_OBDR_device = (this_device->devtype == TYPE_ROM &&
+                                       strncmp(obdr_sig, OBDR_TAPE_SIG,
+                                               OBDR_SIG_LEN) == 0);
+       }
+
        kfree(inq_buff);
        return 0;
 
@@ -1716,7 +1743,7 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
                return 0;
        }
 
-       if (hpsa_update_device_info(h, scsi3addr, this_device))
+       if (hpsa_update_device_info(h, scsi3addr, this_device, NULL))
                return 0;
        (*nmsa2xxx_enclosures)++;
        hpsa_set_bus_target_lun(this_device, bus, target, 0);
@@ -1808,7 +1835,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
         */
        struct ReportLUNdata *physdev_list = NULL;
        struct ReportLUNdata *logdev_list = NULL;
-       unsigned char *inq_buff = NULL;
        u32 nphysicals = 0;
        u32 nlogicals = 0;
        u32 ndev_allocated = 0;
@@ -1824,11 +1850,9 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
                GFP_KERNEL);
        physdev_list = kzalloc(reportlunsize, GFP_KERNEL);
        logdev_list = kzalloc(reportlunsize, GFP_KERNEL);
-       inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
        tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL);
 
-       if (!currentsd || !physdev_list || !logdev_list ||
-               !inq_buff || !tmpdevice) {
+       if (!currentsd || !physdev_list || !logdev_list || !tmpdevice) {
                dev_err(&h->pdev->dev, "out of memory\n");
                goto out;
        }
@@ -1863,7 +1887,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
        /* adjust our table of devices */
        nmsa2xxx_enclosures = 0;
        for (i = 0; i < nphysicals + nlogicals + 1; i++) {
-               u8 *lunaddrbytes;
+               u8 *lunaddrbytes, is_OBDR = 0;
 
                /* Figure out where the LUN ID info is coming from */
                lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position,
@@ -1874,7 +1898,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
                        continue;
 
                /* Get device type, vendor, model, device id */
-               if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice))
+               if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice,
+                                                       &is_OBDR))
                        continue; /* skip it if we can't talk to it. */
                figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun,
                        tmpdevice);
@@ -1898,7 +1923,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
                hpsa_set_bus_target_lun(this_device, bus, target, lun);
 
                switch (this_device->devtype) {
-               case TYPE_ROM: {
+               case TYPE_ROM:
                        /* We don't *really* support actual CD-ROM devices,
                         * just "One Button Disaster Recovery" tape drive
                         * which temporarily pretends to be a CD-ROM drive.
@@ -1906,15 +1931,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
                         * device by checking for "$DR-10" in bytes 43-48 of
                         * the inquiry data.
                         */
-                               char obdr_sig[7];
-#define OBDR_TAPE_SIG "$DR-10"
-                               strncpy(obdr_sig, &inq_buff[43], 6);
-                               obdr_sig[6] = '\0';
-                               if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
-                                       /* Not OBDR device, ignore it. */
-                                       break;
-                       }
-                       ncurrent++;
+                       if (is_OBDR)
+                               ncurrent++;
                        break;
                case TYPE_DISK:
                        if (i < nphysicals)
@@ -1947,7 +1965,6 @@ out:
        for (i = 0; i < ndev_allocated; i++)
                kfree(currentsd[i]);
        kfree(currentsd);
-       kfree(inq_buff);
        kfree(physdev_list);
        kfree(logdev_list);
 }
index 26072f1..6981b77 100644 (file)
@@ -531,6 +531,9 @@ static void sci_controller_process_completions(struct isci_host *ihost)
                        break;
 
                case SCU_COMPLETION_TYPE_EVENT:
+                       sci_controller_event_completion(ihost, ent);
+                       break;
+
                case SCU_COMPLETION_TYPE_NOTIFY: {
                        event_cycle ^= ((event_get+1) & SCU_MAX_EVENTS) <<
                                       (SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_SHIFT - SCU_MAX_EVENTS_SHIFT);
@@ -1091,6 +1094,7 @@ static void isci_host_completion_routine(unsigned long data)
        struct isci_request *request;
        struct isci_request *next_request;
        struct sas_task     *task;
+       u16 active;
 
        INIT_LIST_HEAD(&completed_request_list);
        INIT_LIST_HEAD(&errored_request_list);
@@ -1181,6 +1185,13 @@ static void isci_host_completion_routine(unsigned long data)
                }
        }
 
+       /* the coalesence timeout doubles at each encoding step, so
+        * update it based on the ilog2 value of the outstanding requests
+        */
+       active = isci_tci_active(ihost);
+       writel(SMU_ICC_GEN_VAL(NUMBER, active) |
+              SMU_ICC_GEN_VAL(TIMER, ISCI_COALESCE_BASE + ilog2(active)),
+              &ihost->smu_registers->interrupt_coalesce_control);
 }
 
 /**
@@ -1471,7 +1482,7 @@ static void sci_controller_ready_state_enter(struct sci_base_state_machine *sm)
        struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);
 
        /* set the default interrupt coalescence number and timeout value. */
-       sci_controller_set_interrupt_coalescence(ihost, 0x10, 250);
+       sci_controller_set_interrupt_coalescence(ihost, 0, 0);
 }
 
 static void sci_controller_ready_state_exit(struct sci_base_state_machine *sm)
index 062101a..9f33831 100644 (file)
@@ -369,6 +369,9 @@ static inline struct isci_host *dev_to_ihost(struct domain_device *dev)
 #define ISCI_TAG_SEQ(tag) (((tag) >> 12) & (SCI_MAX_SEQ-1))
 #define ISCI_TAG_TCI(tag) ((tag) & (SCI_MAX_IO_REQUESTS-1))
 
+/* interrupt coalescing baseline: 9 == 3 to 5us interrupt delay per command */
+#define ISCI_COALESCE_BASE 9
+
 /* expander attached sata devices require 3 rnc slots */
 static inline int sci_remote_device_node_count(struct isci_remote_device *idev)
 {
index 61e0d09..29aa34e 100644 (file)
 #include <linux/firmware.h>
 #include <linux/efi.h>
 #include <asm/string.h>
+#include <scsi/scsi_host.h>
 #include "isci.h"
 #include "task.h"
 #include "probe_roms.h"
 
+#define MAJ 1
+#define MIN 0
+#define BUILD 0
+#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
+       __stringify(BUILD)
+
+MODULE_VERSION(DRV_VERSION);
+
 static struct scsi_transport_template *isci_transport_template;
 
 static DEFINE_PCI_DEVICE_TABLE(isci_id_table) = {
@@ -113,6 +122,22 @@ unsigned char max_concurr_spinup = 1;
 module_param(max_concurr_spinup, byte, 0);
 MODULE_PARM_DESC(max_concurr_spinup, "Max concurrent device spinup");
 
+static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev);
+       struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
+       struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha);
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id);
+}
+
+static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL);
+
+struct device_attribute *isci_host_attrs[] = {
+       &dev_attr_isci_id,
+       NULL
+};
+
 static struct scsi_host_template isci_sht = {
 
        .module                         = THIS_MODULE,
@@ -138,6 +163,7 @@ static struct scsi_host_template isci_sht = {
        .slave_alloc                    = sas_slave_alloc,
        .target_destroy                 = sas_target_destroy,
        .ioctl                          = sas_ioctl,
+       .shost_attrs                    = isci_host_attrs,
 };
 
 static struct sas_domain_function_template isci_transport_ops  = {
@@ -232,17 +258,6 @@ static int isci_register_sas_ha(struct isci_host *isci_host)
        return 0;
 }
 
-static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev);
-       struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
-       struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha);
-
-       return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id);
-}
-
-static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL);
-
 static void isci_unregister(struct isci_host *isci_host)
 {
        struct Scsi_Host *shost;
@@ -251,7 +266,6 @@ static void isci_unregister(struct isci_host *isci_host)
                return;
 
        shost = isci_host->shost;
-       device_remove_file(&shost->shost_dev, &dev_attr_isci_id);
 
        sas_unregister_ha(&isci_host->sas_ha);
 
@@ -415,14 +429,8 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
        if (err)
                goto err_shost_remove;
 
-       err = device_create_file(&shost->shost_dev, &dev_attr_isci_id);
-       if (err)
-               goto err_unregister_ha;
-
        return isci_host;
 
- err_unregister_ha:
-       sas_unregister_ha(&(isci_host->sas_ha));
  err_shost_remove:
        scsi_remove_host(shost);
  err_shost:
@@ -540,7 +548,8 @@ static __init int isci_init(void)
 {
        int err;
 
-       pr_info("%s: Intel(R) C600 SAS Controller Driver\n", DRV_NAME);
+       pr_info("%s: Intel(R) C600 SAS Controller Driver - version %s\n",
+               DRV_NAME, DRV_VERSION);
 
        isci_transport_template = sas_domain_attach_transport(&isci_transport_ops);
        if (!isci_transport_template)
index 79313a7..430fc8f 100644 (file)
@@ -104,6 +104,7 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
        u32 parity_count = 0;
        u32 llctl, link_rate;
        u32 clksm_value = 0;
+       u32 sp_timeouts = 0;
 
        iphy->link_layer_registers = reg;
 
@@ -211,6 +212,18 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
        llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
        writel(llctl, &iphy->link_layer_registers->link_layer_control);
 
+       sp_timeouts = readl(&iphy->link_layer_registers->sas_phy_timeouts);
+
+       /* Clear the default 0x36 (54us) RATE_CHANGE timeout value. */
+       sp_timeouts &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF);
+
+       /* Set RATE_CHANGE timeout value to 0x3B (59us).  This ensures SCU can
+        * lock with 3Gb drive when SCU max rate is set to 1.5Gb.
+        */
+       sp_timeouts |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B);
+
+       writel(sp_timeouts, &iphy->link_layer_registers->sas_phy_timeouts);
+
        if (is_a2(ihost->pdev)) {
                /* Program the max ARB time for the PHY to 700us so we inter-operate with
                 * the PMC expander which shuts down PHYs if the expander PHY generates too
index 9b266c7..00afc73 100644 (file)
@@ -1299,6 +1299,18 @@ struct scu_transport_layer_registers {
 #define SCU_AFE_XCVRCR_OFFSET       0x00DC
 #define SCU_AFE_LUTCR_OFFSET        0x00E0
 
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_SHIFT          (0UL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_MASK           (0x000000FFUL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_SHIFT                 (8UL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_MASK                  (0x0000FF00UL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_SHIFT         (16UL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_MASK          (0x00FF0000UL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_SHIFT              (24UL)
+#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_MASK               (0xFF000000UL)
+
+#define SCU_SAS_PHYTOV_GEN_VAL(name, value) \
+       SCU_GEN_VALUE(SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_##name, value)
+
 #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_SHIFT                  (0)
 #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_MASK                   (0x00000003)
 #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1                   (0)
index a46e07a..b5d3a8c 100644 (file)
@@ -732,12 +732,20 @@ sci_io_request_terminate(struct isci_request *ireq)
                sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
                return SCI_SUCCESS;
        case SCI_REQ_TASK_WAIT_TC_RESP:
+               /* The task frame was already confirmed to have been
+                * sent by the SCU HW.  Since the state machine is
+                * now only waiting for the task response itself,
+                * abort the request and complete it immediately
+                * and don't wait for the task response.
+                */
                sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
                sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
                return SCI_SUCCESS;
        case SCI_REQ_ABORTING:
-               sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
-               return SCI_SUCCESS;
+               /* If a request has a termination requested twice, return
+                * a failure indication, since HW confirmation of the first
+                * abort is still outstanding.
+                */
        case SCI_REQ_COMPLETED:
        default:
                dev_warn(&ireq->owning_controller->pdev->dev,
@@ -2399,22 +2407,19 @@ static void isci_task_save_for_upper_layer_completion(
        }
 }
 
-static void isci_request_process_stp_response(struct sas_task *task,
-                                             void *response_buffer)
+static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis)
 {
-       struct dev_to_host_fis *d2h_reg_fis = response_buffer;
        struct task_status_struct *ts = &task->task_status;
        struct ata_task_resp *resp = (void *)&ts->buf[0];
 
-       resp->frame_len = le16_to_cpu(*(__le16 *)(response_buffer + 6));
-       memcpy(&resp->ending_fis[0], response_buffer + 16, 24);
+       resp->frame_len = sizeof(*fis);
+       memcpy(resp->ending_fis, fis, sizeof(*fis));
        ts->buf_valid_size = sizeof(*resp);
 
-       /**
-        * If the device fault bit is set in the status register, then
+       /* If the device fault bit is set in the status register, then
         * set the sense data and return.
         */
-       if (d2h_reg_fis->status & ATA_DF)
+       if (fis->status & ATA_DF)
                ts->stat = SAS_PROTO_RESPONSE;
        else
                ts->stat = SAM_STAT_GOOD;
@@ -2428,7 +2433,6 @@ static void isci_request_io_request_complete(struct isci_host *ihost,
 {
        struct sas_task *task = isci_request_access_task(request);
        struct ssp_response_iu *resp_iu;
-       void *resp_buf;
        unsigned long task_flags;
        struct isci_remote_device *idev = isci_lookup_device(task->dev);
        enum service_response response       = SAS_TASK_UNDELIVERED;
@@ -2565,9 +2569,7 @@ static void isci_request_io_request_complete(struct isci_host *ihost,
                                task);
 
                        if (sas_protocol_ata(task->task_proto)) {
-                               resp_buf = &request->stp.rsp;
-                               isci_request_process_stp_response(task,
-                                                                 resp_buf);
+                               isci_process_stp_response(task, &request->stp.rsp);
                        } else if (SAS_PROTOCOL_SSP == task->task_proto) {
 
                                /* crack the iu response buffer. */
index e9e1e2a..16f88ab 100644 (file)
@@ -72,7 +72,7 @@ int sci_unsolicited_frame_control_construct(struct isci_host *ihost)
         */
        buf_len = SCU_MAX_UNSOLICITED_FRAMES * SCU_UNSOLICITED_FRAME_BUFFER_SIZE;
        header_len = SCU_MAX_UNSOLICITED_FRAMES * sizeof(struct scu_unsolicited_frame_header);
-       size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(dma_addr_t);
+       size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(uf_control->address_table.array[0]);
 
        /*
         * The Unsolicited Frame buffers are set at the start of the UF
index 31cb950..75d8966 100644 (file)
@@ -214,7 +214,7 @@ struct sci_uf_address_table_array {
         * starting address of the UF address table.
         * 64-bit pointers are required by the hardware.
         */
-       dma_addr_t *array;
+       u64 *array;
 
        /**
         * This field specifies the physical address location for the UF
index 01ff082..d261e98 100644 (file)
@@ -494,6 +494,9 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp,
         */
        error = lport->tt.frame_send(lport, fp);
 
+       if (fh->fh_type == FC_TYPE_BLS)
+               return error;
+
        /*
         * Update the exchange and sequence flags,
         * assuming all frames for the sequence have been sent.
@@ -575,42 +578,35 @@ static void fc_seq_set_resp(struct fc_seq *sp,
 }
 
 /**
- * fc_seq_exch_abort() - Abort an exchange and sequence
- * @req_sp:    The sequence to be aborted
+ * fc_exch_abort_locked() - Abort an exchange
+ * @ep:        The exchange to be aborted
  * @timer_msec: The period of time to wait before aborting
  *
- * Generally called because of a timeout or an abort from the upper layer.
+ * Locking notes:  Called with exch lock held
+ *
+ * Return value: 0 on success else error code
  */
-static int fc_seq_exch_abort(const struct fc_seq *req_sp,
-                            unsigned int timer_msec)
+static int fc_exch_abort_locked(struct fc_exch *ep,
+                               unsigned int timer_msec)
 {
        struct fc_seq *sp;
-       struct fc_exch *ep;
        struct fc_frame *fp;
        int error;
 
-       ep = fc_seq_exch(req_sp);
-
-       spin_lock_bh(&ep->ex_lock);
        if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) ||
-           ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) {
-               spin_unlock_bh(&ep->ex_lock);
+           ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP))
                return -ENXIO;
-       }
 
        /*
         * Send the abort on a new sequence if possible.
         */
        sp = fc_seq_start_next_locked(&ep->seq);
-       if (!sp) {
-               spin_unlock_bh(&ep->ex_lock);
+       if (!sp)
                return -ENOMEM;
-       }
 
        ep->esb_stat |= ESB_ST_SEQ_INIT | ESB_ST_ABNORMAL;
        if (timer_msec)
                fc_exch_timer_set_locked(ep, timer_msec);
-       spin_unlock_bh(&ep->ex_lock);
 
        /*
         * If not logged into the fabric, don't send ABTS but leave
@@ -633,6 +629,28 @@ static int fc_seq_exch_abort(const struct fc_seq *req_sp,
 }
 
 /**
+ * fc_seq_exch_abort() - Abort an exchange and sequence
+ * @req_sp:    The sequence to be aborted
+ * @timer_msec: The period of time to wait before aborting
+ *
+ * Generally called because of a timeout or an abort from the upper layer.
+ *
+ * Return value: 0 on success else error code
+ */
+static int fc_seq_exch_abort(const struct fc_seq *req_sp,
+                            unsigned int timer_msec)
+{
+       struct fc_exch *ep;
+       int error;
+
+       ep = fc_seq_exch(req_sp);
+       spin_lock_bh(&ep->ex_lock);
+       error = fc_exch_abort_locked(ep, timer_msec);
+       spin_unlock_bh(&ep->ex_lock);
+       return error;
+}
+
+/**
  * fc_exch_timeout() - Handle exchange timer expiration
  * @work: The work_struct identifying the exchange that timed out
  */
@@ -1715,6 +1733,7 @@ static void fc_exch_reset(struct fc_exch *ep)
        int rc = 1;
 
        spin_lock_bh(&ep->ex_lock);
+       fc_exch_abort_locked(ep, 0);
        ep->state |= FC_EX_RST_CLEANUP;
        if (cancel_delayed_work(&ep->timeout_work))
                atomic_dec(&ep->ex_refcnt);     /* drop hold for timer */
@@ -1962,6 +1981,7 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport,
        struct fc_exch *ep;
        struct fc_seq *sp = NULL;
        struct fc_frame_header *fh;
+       struct fc_fcp_pkt *fsp = NULL;
        int rc = 1;
 
        ep = fc_exch_alloc(lport, fp);
@@ -1984,8 +2004,10 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport,
        fc_exch_setup_hdr(ep, fp, ep->f_ctl);
        sp->cnt++;
 
-       if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD)
+       if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) {
+               fsp = fr_fsp(fp);
                fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
+       }
 
        if (unlikely(lport->tt.frame_send(lport, fp)))
                goto err;
@@ -1999,7 +2021,8 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport,
        spin_unlock_bh(&ep->ex_lock);
        return sp;
 err:
-       fc_fcp_ddp_done(fr_fsp(fp));
+       if (fsp)
+               fc_fcp_ddp_done(fsp);
        rc = fc_exch_done_locked(ep);
        spin_unlock_bh(&ep->ex_lock);
        if (!rc)
index afb63c8..4c41ee8 100644 (file)
@@ -2019,6 +2019,11 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
        struct fc_fcp_internal *si;
        int rc = FAILED;
        unsigned long flags;
+       int rval;
+
+       rval = fc_block_scsi_eh(sc_cmd);
+       if (rval)
+               return rval;
 
        lport = shost_priv(sc_cmd->device->host);
        if (lport->state != LPORT_ST_READY)
@@ -2068,9 +2073,9 @@ int fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
        int rc = FAILED;
        int rval;
 
-       rval = fc_remote_port_chkready(rport);
+       rval = fc_block_scsi_eh(sc_cmd);
        if (rval)
-               goto out;
+               return rval;
 
        lport = shost_priv(sc_cmd->device->host);
 
@@ -2116,6 +2121,8 @@ int fc_eh_host_reset(struct scsi_cmnd *sc_cmd)
 
        FC_SCSI_DBG(lport, "Resetting host\n");
 
+       fc_block_scsi_eh(sc_cmd);
+
        lport->tt.lport_reset(lport);
        wait_tmo = jiffies + FC_HOST_RESET_TIMEOUT;
        while (!fc_fcp_lport_queue_ready(lport) && time_before(jiffies,
index e55ed9c..628f347 100644 (file)
@@ -88,6 +88,7 @@
  */
 
 #include <linux/timer.h>
+#include <linux/delay.h>
 #include <linux/slab.h>
 #include <asm/unaligned.h>
 
@@ -1029,8 +1030,16 @@ static void fc_lport_enter_reset(struct fc_lport *lport)
                           FCH_EVT_LIPRESET, 0);
        fc_vports_linkchange(lport);
        fc_lport_reset_locked(lport);
-       if (lport->link_up)
+       if (lport->link_up) {
+               /*
+                * Wait upto resource allocation time out before
+                * doing re-login since incomplete FIP exchanged
+                * from last session may collide with exchanges
+                * in new session.
+                */
+               msleep(lport->r_a_tov);
                fc_lport_enter_flogi(lport);
+       }
 }
 
 /**
index 7836eb0..a31e05f 100644 (file)
@@ -1786,13 +1786,16 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
                        fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN);
        }
 
-       if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) {
+       if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
                if (ha->fw_attributes & BIT_4) {
+                       int prot = 0;
                        vha->flags.difdix_supported = 1;
                        ql_dbg(ql_dbg_user, vha, 0x7082,
                            "Registered for DIF/DIX type 1 and 3 protection.\n");
+                       if (ql2xenabledif == 1)
+                               prot = SHOST_DIX_TYPE0_PROTECTION;
                        scsi_host_set_prot(vha->host,
-                           SHOST_DIF_TYPE1_PROTECTION
+                           prot | SHOST_DIF_TYPE1_PROTECTION
                            | SHOST_DIF_TYPE2_PROTECTION
                            | SHOST_DIF_TYPE3_PROTECTION
                            | SHOST_DIX_TYPE1_PROTECTION
index 2155071..d79cd8a 100644 (file)
@@ -8,24 +8,24 @@
 /*
  * Table for showing the current message id in use for particular level
  * Change this table for addition of log/debug messages.
- * -----------------------------------------------------
- * |             Level            |   Last Value Used  |
- * -----------------------------------------------------
- * | Module Init and Probe        |       0x0116       |
- * | Mailbox commands             |       0x111e       |
- * | Device Discovery             |       0x2083       |
- * | Queue Command and IO tracing |       0x302e       |
- * | DPC Thread                   |       0x401c       |
- * | Async Events                 |       0x5059       |
- * | Timer Routines               |       0x600d       |
- * | User Space Interactions      |       0x709c       |
- * | Task Management              |       0x8043       |
- * | AER/EEH                      |       0x900f       |
- * | Virtual Port                 |       0xa007       |
- * | ISP82XX Specific             |       0xb027       |
- * | MultiQ                       |       0xc00b       |
- * | Misc                         |       0xd00b       |
- * -----------------------------------------------------
+ * ----------------------------------------------------------------------
+ * |             Level            |   Last Value Used  |     Holes     |
+ * ----------------------------------------------------------------------
+ * | Module Init and Probe        |       0x0116       |               |
+ * | Mailbox commands             |       0x1126       |               |
+ * | Device Discovery             |       0x2083       |               |
+ * | Queue Command and IO tracing |       0x302e       |     0x3008     |
+ * | DPC Thread                   |       0x401c       |               |
+ * | Async Events                 |       0x5059       |               |
+ * | Timer Routines               |       0x600d       |               |
+ * | User Space Interactions      |       0x709d       |               |
+ * | Task Management              |       0x8041       |               |
+ * | AER/EEH                      |       0x900f       |               |
+ * | Virtual Port                 |       0xa007       |               |
+ * | ISP82XX Specific             |       0xb04f       |               |
+ * | MultiQ                       |       0xc00b       |               |
+ * | Misc                         |       0xd00b       |               |
+ * ----------------------------------------------------------------------
  */
 
 #include "qla_def.h"
index cc5a792..a03eaf4 100644 (file)
@@ -2529,6 +2529,7 @@ struct qla_hw_data {
 #define DT_ISP8021                     BIT_14
 #define DT_ISP_LAST                    (DT_ISP8021 << 1)
 
+#define DT_T10_PI                       BIT_25
 #define DT_IIDMA                        BIT_26
 #define DT_FWI2                         BIT_27
 #define DT_ZIO_SUPPORTED                BIT_28
@@ -2572,6 +2573,7 @@ struct qla_hw_data {
 #define IS_NOCACHE_VPD_TYPE(ha)        (IS_QLA81XX(ha))
 #define IS_ALOGIO_CAPABLE(ha)  (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha))
 
+#define IS_T10_PI_CAPABLE(ha)   ((ha)->device_type & DT_T10_PI)
 #define IS_IIDMA_CAPABLE(ha)    ((ha)->device_type & DT_IIDMA)
 #define IS_FWI2_CAPABLE(ha)     ((ha)->device_type & DT_FWI2)
 #define IS_ZIO_SUPPORTED(ha)    ((ha)->device_type & DT_ZIO_SUPPORTED)
index 691783a..aa69486 100644 (file)
@@ -537,6 +537,11 @@ struct sts_entry_24xx {
        /*
         * If DIF Error is set in comp_status, these additional fields are
         * defined:
+        *
+        * !!! NOTE: Firmware sends expected/actual DIF data in big endian
+        * format; but all of the "data" field gets swab32-d in the beginning
+        * of qla2x00_status_entry().
+        *
         * &data[10] : uint8_t report_runt_bg[2];       - computed guard
         * &data[12] : uint8_t actual_dif[8];           - DIF Data received
         * &data[20] : uint8_t expected_dif[8];         - DIF Data computed