]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 26 Mar 2009 23:04:22 +0000 (16:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 26 Mar 2009 23:04:22 +0000 (16:04 -0700)
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (81 commits)
  [S390] remove duplicated #includes
  [S390] cpumask: use mm_cpumask() wrapper
  [S390] cpumask: Use accessors code.
  [S390] cpumask: prepare for iterators to only go to nr_cpu_ids/nr_cpumask_bits.
  [S390] cpumask: remove cpu_coregroup_map
  [S390] fix clock comparator save area usage
  [S390] Add hwcap flag for the etf3 enhancement facility
  [S390] Ensure that ipl panic notifier is called late.
  [S390] fix dfp elf hwcap/facility bit detection
  [S390] smp: perform initial cpu reset before starting a cpu
  [S390] smp: fix memory leak on __cpu_up
  [S390] ipl: Improve checking logic and remove switch defaults.
  [S390] s390dbf: Remove needless check for NULL pointer.
  [S390] s390dbf: Remove redundant initilizations.
  [S390] use kzfree()
  [S390] BUG to BUG_ON changes
  [S390] zfcpdump: Prevent zcore from beeing built as a kernel module.
  [S390] Use csum_partial in checksum.h
  [S390] cleanup lowcore.h
  [S390] eliminate ipl_device from lowcore
  ...

1  2 
Documentation/kernel-parameters.txt
MAINTAINERS
arch/s390/kvm/kvm-s390.c
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/css.c
drivers/s390/cio/device.c
drivers/s390/net/qeth_core_main.c

index 1a29ff3df3c58231a3c8a639758a9f9e7557ea6b,9f932a76a94017c7605fbd1a51f951921e25e95d..954b23cecfd19bc98f996c26ecfbd7bf8f0f44e9
@@@ -44,7 -44,6 +44,7 @@@ parameter is applicable
        FB      The frame buffer device is enabled.
        HW      Appropriate hardware is enabled.
        IA-64   IA-64 architecture is enabled.
 +      IMA     Integrity measurement architecture is enabled.
        IOSCHED More than one I/O scheduler is enabled.
        IP_PNP  IP DHCP, BOOTP, or RARP is enabled.
        ISAPNP  ISA PnP code is enabled.
@@@ -830,6 -829,9 +830,9 @@@ and is between 256 and 4096 characters
  
        hvc_iucv=       [S390] Number of z/VM IUCV hypervisor console (HVC)
                               terminal devices. Valid values: 0..8
+       hvc_iucv_allow= [S390] Comma-separated list of z/VM user IDs.
+                              If specified, z/VM IUCV HVC accepts connections
+                              from listed z/VM user IDs only.
  
        i8042.debug     [HW] Toggle i8042 debug mode
        i8042.direct    [HW] Put keyboard port into non-translated mode
        ihash_entries=  [KNL]
                        Set number of hash buckets for inode cache.
  
 +      ima_audit=      [IMA]
 +                      Format: { "0" | "1" }
 +                      0 -- integrity auditing messages. (Default)
 +                      1 -- enable informational integrity auditing messages.
 +
 +      ima_hash=       [IMA]
 +                      Formt: { "sha1" | "md5" }
 +                      default: "sha1"
 +
        in2000=         [HW,SCSI]
                        See header of drivers/scsi/in2000.c.
  
                        autoconfiguration.
                        Ranges are in pairs (memory base and size).
  
 -      dynamic_printk  Enables pr_debug()/dev_dbg() calls if
 -                      CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled.
 -                      These can also be switched on/off via
 -                      <debugfs>/dynamic_printk/modules
 -
        print-fatal-signals=
                        [KNL] debug: print fatal signals
                        print-fatal-signals=1: print segfault info to
diff --combined MAINTAINERS
index bc919b645f379cf52cc688dcbde4ef7aa4c9a5c2,fc1e8d6250e4f7eb00e6ff21caa8e539a2f8d06b..4dacdfcdbe6e6ed34a689cf35851503606255942
@@@ -1011,8 -1011,6 +1011,8 @@@ L:      netdev@vger.kernel.or
  S:    Supported
  
  BROADCOM TG3 GIGABIT ETHERNET DRIVER
 +P:    Matt Carlson
 +M:    mcarlson@broadcom.com
  P:    Michael Chan
  M:    mchan@broadcom.com
  L:    netdev@vger.kernel.org
@@@ -1271,12 -1269,6 +1271,12 @@@ L:    linux-crypto@vger.kernel.or
  T:    git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
  S:    Maintained
  
 +CRYPTOGRAPHIC RANDOM NUMBER GENERATOR
 +P:    Neil Horman
 +M:    nhorman@tuxdriver.com
 +L:    linux-crypto@vger.kernel.org
 +S:    Maintained
 +
  CS5535 Audio ALSA driver
  P:    Jaya Kumar
  M:    jayakumar.alsa@gmail.com
@@@ -2224,11 -2216,6 +2224,11 @@@ M:    stefanr@s5r6.in-berlin.d
  L:    linux1394-devel@lists.sourceforge.net
  S:    Maintained
  
 +INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
 +P:    Mimi Zohar
 +M:    zohar@us.ibm.com
 +S:    Supported
 +
  IMS TWINTURBO FRAMEBUFFER DRIVER
  L:    linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
  S:    Orphan
@@@ -3648,12 -3635,6 +3648,12 @@@ M:    florian.fainelli@telecomint.e
  L:    netdev@vger.kernel.org
  S:    Maintained
  
 +RDS - RELIABLE DATAGRAM SOCKETS
 +P:    Andy Grover
 +M:    andy.grover@oracle.com
 +L:    rds-devel@oss.oracle.com
 +S:    Supported
 +
  READ-COPY UPDATE (RCU)
  P:    Dipankar Sarma
  M:    dipankar@in.ibm.com
@@@ -3745,6 -3726,15 +3745,15 @@@ L:    linux-s390@vger.kernel.or
  W:    http://www.ibm.com/developerworks/linux/linux390/
  S:    Supported
  
+ S390 ZCRYPT DRIVER
+ P:    Felix Beck
+ M:    felix.beck@de.ibm.com
+ P:    Ralph Wuerthner
+ M:    ralph.wuerthner@de.ibm.com
+ M:    linux390@de.ibm.com
+ L:    linux-s390@vger.kernel.org
+ S:    Supported
  S390 ZFCP DRIVER
  P:    Christof Schmitt
  M:    christof.schmitt@de.ibm.com
@@@ -3863,7 -3853,6 +3872,7 @@@ M:      jmorris@namei.or
  L:    linux-kernel@vger.kernel.org
  L:    linux-security-module@vger.kernel.org (suggested Cc:)
  T:    git kernel.org:pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
 +W:    http://security.wiki.kernel.org/
  S:    Supported
  
  SECURITY CONTACT
@@@ -4305,19 -4294,6 +4314,19 @@@ L:    tlan-devel@lists.sourceforge.net (su
  W:    http://sourceforge.net/projects/tlan/
  S:    Maintained
  
 +TOMOYO SECURITY MODULE
 +P:    Kentaro Takeda
 +M:    takedakn@nttdata.co.jp
 +P:    Tetsuo Handa
 +M:    penguin-kernel@I-love.SAKURA.ne.jp
 +L:    linux-kernel@vger.kernel.org (kernel issues)
 +L:    tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for developers and users in English)
 +L:    tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese)
 +L:    tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese)
 +W:    http://tomoyo.sourceforge.jp/
 +T:    quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.2.x/tomoyo-lsm/patches/
 +S:    Maintained
 +
  TOSHIBA ACPI EXTRAS DRIVER
  P:    John Belmonte
  M:    toshiba_acpi@memebeam.org
diff --combined arch/s390/kvm/kvm-s390.c
index cbfe91e101208273d789585595f146a5878b0081,caa4d28770168a906e096749937a07d1f7f26cbc..f4d56e9939c90949c1e886eaabf6cc7d35cab858
@@@ -23,7 -23,7 +23,7 @@@
  #include <linux/timer.h>
  #include <asm/lowcore.h>
  #include <asm/pgtable.h>
+ #include <asm/nmi.h>
  #include "kvm-s390.h"
  #include "gaccess.h"
  
@@@ -286,7 -286,7 +286,7 @@@ int kvm_arch_vcpu_setup(struct kvm_vcp
        setup_timer(&vcpu->arch.ckc_timer, kvm_s390_idle_wakeup,
                 (unsigned long) vcpu);
        get_cpu_id(&vcpu->arch.cpu_id);
-       vcpu->arch.cpu_id.version = 0xfe;
+       vcpu->arch.cpu_id.version = 0xff;
        return 0;
  }
  
@@@ -422,8 -422,8 +422,8 @@@ int kvm_arch_vcpu_ioctl_translate(struc
        return -EINVAL; /* not implemented yet */
  }
  
 -int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
 -                                  struct kvm_debug_guest *dbg)
 +int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
 +                                      struct kvm_guest_debug *dbg)
  {
        return -EINVAL; /* not implemented yet */
  }
@@@ -440,8 -440,6 +440,6 @@@ int kvm_arch_vcpu_ioctl_set_mpstate(str
        return -EINVAL; /* not implemented yet */
  }
  
- extern void s390_handle_mcck(void);
  static void __vcpu_run(struct kvm_vcpu *vcpu)
  {
        memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
index b91c1719b07563db660db3522b057bcd3373c49d,86b136cb09e0b0f7fb0b315fcebbf3e204b183cc..22ce765d537e9f0bccbca4c769131c07b3c03574
@@@ -104,9 -104,8 +104,9 @@@ ccwgroup_ungroup_store(struct device *d
        rc = device_schedule_callback(dev, ccwgroup_ungroup_callback);
  out:
        if (rc) {
 -              /* Release onoff "lock" when ungrouping failed. */
 -              atomic_set(&gdev->onoff, 0);
 +              if (rc != -EAGAIN)
 +                      /* Release onoff "lock" when ungrouping failed. */
 +                      atomic_set(&gdev->onoff, 0);
                return rc;
        }
        return count;
@@@ -315,16 -314,32 +315,32 @@@ error
  }
  EXPORT_SYMBOL(ccwgroup_create_from_string);
  
- static int __init
- init_ccwgroup (void)
+ static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
+                            void *data);
+ static struct notifier_block ccwgroup_nb = {
+       .notifier_call = ccwgroup_notifier
+ };
+ static int __init init_ccwgroup(void)
  {
-       return bus_register (&ccwgroup_bus_type);
+       int ret;
+       ret = bus_register(&ccwgroup_bus_type);
+       if (ret)
+               return ret;
+       ret = bus_register_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
+       if (ret)
+               bus_unregister(&ccwgroup_bus_type);
+       return ret;
  }
  
- static void __exit
- cleanup_ccwgroup (void)
+ static void __exit cleanup_ccwgroup(void)
  {
-       bus_unregister (&ccwgroup_bus_type);
+       bus_unregister_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
+       bus_unregister(&ccwgroup_bus_type);
  }
  
  module_init(init_ccwgroup);
@@@ -392,27 -407,28 +408,28 @@@ ccwgroup_online_store (struct device *d
        unsigned long value;
        int ret;
  
-       gdev = to_ccwgroupdev(dev);
        if (!dev->driver)
-               return count;
+               return -ENODEV;
+       gdev = to_ccwgroupdev(dev);
+       gdrv = to_ccwgroupdrv(dev->driver);
  
-       gdrv = to_ccwgroupdrv (gdev->dev.driver);
        if (!try_module_get(gdrv->owner))
                return -EINVAL;
  
        ret = strict_strtoul(buf, 0, &value);
        if (ret)
                goto out;
-       ret = count;
        if (value == 1)
-               ccwgroup_set_online(gdev);
+               ret = ccwgroup_set_online(gdev);
        else if (value == 0)
-               ccwgroup_set_offline(gdev);
+               ret = ccwgroup_set_offline(gdev);
        else
                ret = -EINVAL;
  out:
        module_put(gdrv->owner);
-       return ret;
+       return (ret == 0) ? count : ret;
  }
  
  static ssize_t
@@@ -454,13 -470,18 +471,18 @@@ ccwgroup_remove (struct device *dev
        struct ccwgroup_device *gdev;
        struct ccwgroup_driver *gdrv;
  
+       device_remove_file(dev, &dev_attr_online);
+       device_remove_file(dev, &dev_attr_ungroup);
+       if (!dev->driver)
+               return 0;
        gdev = to_ccwgroupdev(dev);
        gdrv = to_ccwgroupdrv(dev->driver);
  
-       device_remove_file(dev, &dev_attr_online);
-       if (gdrv && gdrv->remove)
+       if (gdrv->remove)
                gdrv->remove(gdev);
        return 0;
  }
  
@@@ -469,9 -490,13 +491,13 @@@ static void ccwgroup_shutdown(struct de
        struct ccwgroup_device *gdev;
        struct ccwgroup_driver *gdrv;
  
+       if (!dev->driver)
+               return;
        gdev = to_ccwgroupdev(dev);
        gdrv = to_ccwgroupdrv(dev->driver);
-       if (gdrv && gdrv->shutdown)
+       if (gdrv->shutdown)
                gdrv->shutdown(gdev);
  }
  
@@@ -484,6 -509,19 +510,19 @@@ static struct bus_type ccwgroup_bus_typ
        .shutdown = ccwgroup_shutdown,
  };
  
+ static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
+                            void *data)
+ {
+       struct device *dev = data;
+       if (action == BUS_NOTIFY_UNBIND_DRIVER)
+               device_schedule_callback(dev, ccwgroup_ungroup_callback);
+       return NOTIFY_OK;
+ }
  /**
   * ccwgroup_driver_register() - register a ccw group driver
   * @cdriver: driver to be registered
diff --combined drivers/s390/cio/css.c
index 427d11d88069c24cc4f2c77170aa36f6f6d95733,dcd0e48918da8fecab20adf95bd0c0c45f16e969..0085d89017924c13d0b1ab0686cd3bb7571ba190
@@@ -18,8 -18,8 +18,8 @@@
  #include <linux/list.h>
  #include <linux/reboot.h>
  #include <asm/isc.h>
+ #include <asm/crw.h>
  
- #include "../s390mach.h"
  #include "css.h"
  #include "cio.h"
  #include "cio_debug.h"
@@@ -83,6 -83,25 +83,25 @@@ static int call_fn_unknown_sch(struct s
        return rc;
  }
  
+ static int call_fn_all_sch(struct subchannel_id schid, void *data)
+ {
+       struct cb_data *cb = data;
+       struct subchannel *sch;
+       int rc = 0;
+       sch = get_subchannel_by_schid(schid);
+       if (sch) {
+               if (cb->fn_known_sch)
+                       rc = cb->fn_known_sch(sch, cb->data);
+               put_device(&sch->dev);
+       } else {
+               if (cb->fn_unknown_sch)
+                       rc = cb->fn_unknown_sch(schid, cb->data);
+       }
+       return rc;
+ }
  int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
                               int (*fn_unknown)(struct subchannel_id,
                               void *), void *data)
        struct cb_data cb;
        int rc;
  
-       cb.set = idset_sch_new();
-       if (!cb.set)
-               return -ENOMEM;
-       idset_fill(cb.set);
        cb.data = data;
        cb.fn_known_sch = fn_known;
        cb.fn_unknown_sch = fn_unknown;
+       cb.set = idset_sch_new();
+       if (!cb.set)
+               /* fall back to brute force scanning in case of oom */
+               return for_each_subchannel(call_fn_all_sch, &cb);
+       idset_fill(cb.set);
        /* Process registered subchannels. */
        rc = bus_for_each_dev(&css_bus_type, NULL, &cb, call_fn_known_sch);
        if (rc)
@@@ -272,7 -295,7 +295,7 @@@ static int css_register_subchannel(stru
         * the subchannel driver can decide itself when it wants to inform
         * userspace of its existence.
         */
 -      sch->dev.uevent_suppress = 1;
 +      dev_set_uevent_suppress(&sch->dev, 1);
        css_update_ssd_info(sch);
        /* make it known to the system */
        ret = css_sch_device_register(sch);
                 * a fitting driver module may be loaded based on the
                 * modalias.
                 */
 -              sch->dev.uevent_suppress = 0;
 +              dev_set_uevent_suppress(&sch->dev, 0);
                kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
        }
        return ret;
@@@ -510,6 -533,17 +533,17 @@@ static int reprobe_subchannel(struct su
        return ret;
  }
  
+ static void reprobe_after_idle(struct work_struct *unused)
+ {
+       /* Make sure initial subchannel scan is done. */
+       wait_event(ccw_device_init_wq,
+                  atomic_read(&ccw_device_init_count) == 0);
+       if (need_reprobe)
+               css_schedule_reprobe();
+ }
+ static DECLARE_WORK(reprobe_idle_work, reprobe_after_idle);
  /* Work function used to reprobe all unregistered subchannels. */
  static void reprobe_all(struct work_struct *unused)
  {
  
        CIO_MSG_EVENT(4, "reprobe start\n");
  
-       need_reprobe = 0;
        /* Make sure initial subchannel scan is done. */
-       wait_event(ccw_device_init_wq,
-                  atomic_read(&ccw_device_init_count) == 0);
+       if (atomic_read(&ccw_device_init_count) != 0) {
+               queue_work(ccw_device_work, &reprobe_idle_work);
+               return;
+       }
+       need_reprobe = 0;
        ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL);
  
        CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
@@@ -619,7 -655,7 +655,7 @@@ css_generate_pgid(struct channel_subsys
                css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid;
        } else {
  #ifdef CONFIG_SMP
-               css->global_pgid.pgid_high.cpu_addr = hard_smp_processor_id();
+               css->global_pgid.pgid_high.cpu_addr = stap();
  #else
                css->global_pgid.pgid_high.cpu_addr = 0;
  #endif
@@@ -765,7 -801,7 +801,7 @@@ init_channel_subsystem (void
        if (ret)
                goto out;
  
-       ret = s390_register_crw_handler(CRW_RSC_SCH, css_process_crw);
+       ret = crw_register_handler(CRW_RSC_SCH, css_process_crw);
        if (ret)
                goto out;
  
@@@ -845,7 -881,7 +881,7 @@@ out_unregister
  out_bus:
        bus_unregister(&css_bus_type);
  out:
-       s390_unregister_crw_handler(CRW_RSC_CSS);
+       crw_unregister_handler(CRW_RSC_CSS);
        chsc_free_sei_area();
        kfree(slow_subchannel_set);
        pr_alert("The CSS device driver initialization failed with "
index e28f8ae534539c4014b095409ed51017504a0868,a048a5afa124b60cfd4ef15369edb3e79b7346ca..c4d2f667a2f685a8c887ca82d2e3346efb783125
@@@ -457,12 -457,13 +457,13 @@@ int ccw_device_set_online(struct ccw_de
        return (ret == 0) ? -ENODEV : ret;
  }
  
- static void online_store_handle_offline(struct ccw_device *cdev)
+ static int online_store_handle_offline(struct ccw_device *cdev)
  {
        if (cdev->private->state == DEV_STATE_DISCONNECTED)
                ccw_device_remove_disconnected(cdev);
-       else if (cdev->drv && cdev->drv->set_offline)
-               ccw_device_set_offline(cdev);
+       else if (cdev->online && cdev->drv && cdev->drv->set_offline)
+               return ccw_device_set_offline(cdev);
+       return 0;
  }
  
  static int online_store_recog_and_online(struct ccw_device *cdev)
@@@ -530,13 -531,10 +531,10 @@@ static ssize_t online_store (struct dev
                goto out;
        switch (i) {
        case 0:
-               online_store_handle_offline(cdev);
-               ret = count;
+               ret = online_store_handle_offline(cdev);
                break;
        case 1:
                ret = online_store_handle_online(cdev, force);
-               if (!ret)
-                       ret = count;
                break;
        default:
                ret = -EINVAL;
@@@ -545,7 -543,7 +543,7 @@@ out
        if (cdev->drv)
                module_put(cdev->drv->owner);
        atomic_set(&cdev->private->onoff, 0);
-       return ret;
+       return (ret < 0) ? ret : count;
  }
  
  static ssize_t
@@@ -681,35 -679,22 +679,22 @@@ get_orphaned_ccwdev_by_dev_id(struct ch
        return dev ? to_ccwdev(dev) : NULL;
  }
  
- static void
- ccw_device_add_changed(struct work_struct *work)
- {
-       struct ccw_device_private *priv;
-       struct ccw_device *cdev;
-       priv = container_of(work, struct ccw_device_private, kick_work);
-       cdev = priv->cdev;
-       if (device_add(&cdev->dev)) {
-               put_device(&cdev->dev);
-               return;
-       }
-       set_bit(1, &cdev->private->registered);
- }
- void ccw_device_do_unreg_rereg(struct work_struct *work)
+ void ccw_device_do_unbind_bind(struct work_struct *work)
  {
        struct ccw_device_private *priv;
        struct ccw_device *cdev;
        struct subchannel *sch;
+       int ret;
  
        priv = container_of(work, struct ccw_device_private, kick_work);
        cdev = priv->cdev;
        sch = to_subchannel(cdev->dev.parent);
  
-       ccw_device_unregister(cdev);
-       PREPARE_WORK(&cdev->private->kick_work,
-                    ccw_device_add_changed);
-       queue_work(ccw_device_work, &cdev->private->kick_work);
+       if (test_bit(1, &cdev->private->registered)) {
+               device_release_driver(&cdev->dev);
+               ret = device_attach(&cdev->dev);
+               WARN_ON(ret == -ENODEV);
+       }
  }
  
  static void
@@@ -799,7 -784,7 +784,7 @@@ static void sch_attach_disconnected_dev
                return;
        other_sch = to_subchannel(cdev->dev.parent);
        /* Note: device_move() changes cdev->dev.parent */
 -      ret = device_move(&cdev->dev, &sch->dev);
 +      ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
        if (ret) {
                CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed "
                              "(ret=%d)!\n", cdev->private->dev_id.ssid,
@@@ -830,7 -815,7 +815,7 @@@ static void sch_attach_orphaned_device(
         * Try to move the ccw device to its new subchannel.
         * Note: device_move() changes cdev->dev.parent
         */
 -      ret = device_move(&cdev->dev, &sch->dev);
 +      ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
        if (ret) {
                CIO_MSG_EVENT(0, "Moving device 0.%x.%04x from orphanage "
                              "failed (ret=%d)!\n",
@@@ -897,8 -882,7 +882,8 @@@ void ccw_device_move_to_orphanage(struc
         * ccw device can take its place on the subchannel.
         * Note: device_move() changes cdev->dev.parent
         */
 -      ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev);
 +      ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev,
 +              DPM_ORDER_NONE);
        if (ret) {
                CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to orphanage failed "
                              "(ret=%d)!\n", cdev->private->dev_id.ssid,
@@@ -982,7 -966,7 +967,7 @@@ io_subchannel_register(struct work_stru
         * Now we know this subchannel will stay, we can throw
         * our delayed uevent.
         */
 -      sch->dev.uevent_suppress = 0;
 +      dev_set_uevent_suppress(&sch->dev, 0);
        kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
        /* make it known to the system */
        ret = ccw_device_register(cdev);
@@@ -1035,8 -1019,6 +1020,6 @@@ static void ccw_device_call_sch_unregis
  void
  io_subchannel_recog_done(struct ccw_device *cdev)
  {
-       struct subchannel *sch;
        if (css_init_done == 0) {
                cdev->private->flags.recog_done = 1;
                return;
                /* Remove device found not operational. */
                if (!get_device(&cdev->dev))
                        break;
-               sch = to_subchannel(cdev->dev.parent);
                PREPARE_WORK(&cdev->private->kick_work,
                             ccw_device_call_sch_unregister);
                queue_work(slow_path_wq, &cdev->private->kick_work);
@@@ -1130,7 -1111,7 +1112,7 @@@ static void ccw_device_move_to_sch(stru
         * Try to move the ccw device to its new subchannel.
         * Note: device_move() changes cdev->dev.parent
         */
 -      rc = device_move(&cdev->dev, &sch->dev);
 +      rc = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
        mutex_unlock(&sch->reg_mutex);
        if (rc) {
                CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel "
@@@ -1244,7 -1225,7 +1226,7 @@@ static int io_subchannel_probe(struct s
                 * the ccw_device and exit. This happens for all early
                 * devices, e.g. the console.
                 */
 -              sch->dev.uevent_suppress = 0;
 +              dev_set_uevent_suppress(&sch->dev, 0);
                kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
                cdev->dev.groups = ccwdev_attr_groups;
                device_initialize(&cdev->dev);
index 6fec3cfcf978de999b34fda2640c7adda7e0a2e3,2489bcebf5ec728ab662261ec5d08a6d72124e99..c827d69b5a912c83244afd3cdd1eeb98b630b7e9
@@@ -17,6 -17,7 +17,6 @@@
  #include <linux/errno.h>
  #include <linux/kernel.h>
  #include <linux/ip.h>
 -#include <linux/ipv6.h>
  #include <linux/tcp.h>
  #include <linux/mii.h>
  #include <linux/kthread.h>
@@@ -25,6 -26,7 +25,6 @@@
  #include <asm/io.h>
  
  #include "qeth_core.h"
 -#include "qeth_core_offl.h"
  
  struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = {
        /* define dbf - Name, Pages, Areas, Maxlen, Level, View, Handle */
@@@ -283,6 -285,17 +283,6 @@@ int qeth_set_large_send(struct qeth_car
                netif_tx_disable(card->dev);
        card->options.large_send = type;
        switch (card->options.large_send) {
 -      case QETH_LARGE_SEND_EDDP:
 -              if (card->info.type != QETH_CARD_TYPE_IQD) {
 -                      card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
 -                                      NETIF_F_HW_CSUM;
 -              } else {
 -                      card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
 -                                              NETIF_F_HW_CSUM);
 -                      card->options.large_send = QETH_LARGE_SEND_NO;
 -                      rc = -EOPNOTSUPP;
 -              }
 -              break;
        case QETH_LARGE_SEND_TSO:
                if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
                        card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
@@@ -943,6 -956,7 +943,6 @@@ static void qeth_clear_output_buffer(st
                dev_kfree_skb_any(skb);
                skb = skb_dequeue(&buf->skb_list);
        }
 -      qeth_eddp_buf_release_contexts(buf);
        for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i) {
                if (buf->buffer->element[i].addr && buf->is_header[i])
                        kmem_cache_free(qeth_core_header_cache,
@@@ -1676,7 -1690,7 +1676,7 @@@ int qeth_send_control_data(struct qeth_
        int rc;
        unsigned long flags;
        struct qeth_reply *reply = NULL;
 -      unsigned long timeout;
 +      unsigned long timeout, event_timeout;
        struct qeth_ipa_cmd *cmd;
  
        QETH_DBF_TEXT(TRACE, 2, "sendctl");
        qeth_prepare_control_data(card, len, iob);
  
        if (IS_IPA(iob->data))
 -              timeout = jiffies + QETH_IPA_TIMEOUT;
 +              event_timeout = QETH_IPA_TIMEOUT;
        else
 -              timeout = jiffies + QETH_TIMEOUT;
 +              event_timeout = QETH_TIMEOUT;
 +      timeout = jiffies + event_timeout;
  
        QETH_DBF_TEXT(TRACE, 6, "noirqpnd");
        spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
        if ((cmd->hdr.command == IPA_CMD_SETIP) &&
            (cmd->hdr.prot_version == QETH_PROT_IPV4)) {
                if (!wait_event_timeout(reply->wait_q,
 -                  atomic_read(&reply->received), timeout))
 +                  atomic_read(&reply->received), event_timeout))
                        goto time_err;
        } else {
                while (!atomic_read(&reply->received)) {
@@@ -2680,40 -2693,21 +2680,21 @@@ static int qeth_handle_send_error(struc
                struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err)
  {
        int sbalf15 = buffer->buffer->element[15].flags & 0xff;
-       int cc = qdio_err & 3;
  
        QETH_DBF_TEXT(TRACE, 6, "hdsnderr");
        qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr");
-       switch (cc) {
-       case 0:
-               if (qdio_err) {
-                       QETH_DBF_TEXT(TRACE, 1, "lnkfail");
-                       QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
-                       QETH_DBF_TEXT_(TRACE, 1, "%04x %02x",
-                                      (u16)qdio_err, (u8)sbalf15);
-                       return QETH_SEND_ERROR_LINK_FAILURE;
-               }
+       if (!qdio_err)
                return QETH_SEND_ERROR_NONE;
-       case 2:
-               if (qdio_err & QDIO_ERROR_SIGA_BUSY) {
-                       QETH_DBF_TEXT(TRACE, 1, "SIGAcc2B");
-                       QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
-                       return QETH_SEND_ERROR_KICK_IT;
-               }
-               if ((sbalf15 >= 15) && (sbalf15 <= 31))
-                       return QETH_SEND_ERROR_RETRY;
-               return QETH_SEND_ERROR_LINK_FAILURE;
-               /* look at qdio_error and sbalf 15 */
-       case 1:
-               QETH_DBF_TEXT(TRACE, 1, "SIGAcc1");
-               QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
-               return QETH_SEND_ERROR_LINK_FAILURE;
-       case 3:
-       default:
-               QETH_DBF_TEXT(TRACE, 1, "SIGAcc3");
-               QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
-               return QETH_SEND_ERROR_KICK_IT;
-       }
+       if ((sbalf15 >= 15) && (sbalf15 <= 31))
+               return QETH_SEND_ERROR_RETRY;
+       QETH_DBF_TEXT(TRACE, 1, "lnkfail");
+       QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
+       QETH_DBF_TEXT_(TRACE, 1, "%04x %02x",
+                      (u16)qdio_err, (u8)sbalf15);
+       return QETH_SEND_ERROR_LINK_FAILURE;
  }
  
  /*
@@@ -2849,10 -2843,14 +2830,14 @@@ static void qeth_flush_buffers(struct q
                        qeth_get_micros() -
                        queue->card->perf_stats.outbound_do_qdio_start_time;
        if (rc) {
+               queue->card->stats.tx_errors += count;
+               /* ignore temporary SIGA errors without busy condition */
+               if (rc == QDIO_ERROR_SIGA_TARGET)
+                       return;
                QETH_DBF_TEXT(TRACE, 2, "flushbuf");
                QETH_DBF_TEXT_(TRACE, 2, " err%d", rc);
                QETH_DBF_TEXT_(TRACE, 2, "%s", CARD_DDEV_ID(queue->card));
-               queue->card->stats.tx_errors += count;
                /* this must not happen under normal circumstances. if it
                 * happens something is really wrong -> recover */
                qeth_schedule_recovery(queue->card);
@@@ -2927,13 -2925,7 +2912,7 @@@ void qeth_qdio_output_handler(struct cc
        }
        for (i = first_element; i < (first_element + count); ++i) {
                buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
-               /*we only handle the KICK_IT error by doing a recovery */
-               if (qeth_handle_send_error(card, buffer, qdio_error)
-                               == QETH_SEND_ERROR_KICK_IT){
-                       netif_stop_queue(card->dev);
-                       qeth_schedule_recovery(card);
-                       return;
-               }
+               qeth_handle_send_error(card, buffer, qdio_error);
                qeth_clear_output_buffer(queue, buffer);
        }
        atomic_sub(count, &queue->used_buffers);
@@@ -3174,9 -3166,11 +3153,9 @@@ static inline int qeth_fill_buffer(stru
  int qeth_do_send_packet_fast(struct qeth_card *card,
                struct qeth_qdio_out_q *queue, struct sk_buff *skb,
                struct qeth_hdr *hdr, int elements_needed,
 -              struct qeth_eddp_context *ctx, int offset, int hd_len)
 +              int offset, int hd_len)
  {
        struct qeth_qdio_out_buffer *buffer;
 -      int buffers_needed = 0;
 -      int flush_cnt = 0;
        int index;
  
        /* spin until we get the queue ... */
         */
        if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
                goto out;
 -      if (ctx == NULL)
 -              queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
 +      queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
                                          QDIO_MAX_BUFFERS_PER_Q;
 -      else {
 -              buffers_needed = qeth_eddp_check_buffers_for_context(queue,
 -                                                                      ctx);
 -              if (buffers_needed < 0)
 -                      goto out;
 -              queue->next_buf_to_fill =
 -                      (queue->next_buf_to_fill + buffers_needed) %
 -                      QDIO_MAX_BUFFERS_PER_Q;
 -      }
        atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
 -      if (ctx == NULL) {
 -              qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
 -              qeth_flush_buffers(queue, index, 1);
 -      } else {
 -              flush_cnt = qeth_eddp_fill_buffer(queue, ctx, index);
 -              WARN_ON(buffers_needed != flush_cnt);
 -              qeth_flush_buffers(queue, index, flush_cnt);
 -      }
 +      qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
 +      qeth_flush_buffers(queue, index, 1);
        return 0;
  out:
        atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
@@@ -3205,7 -3215,7 +3184,7 @@@ EXPORT_SYMBOL_GPL(qeth_do_send_packet_f
  
  int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
                struct sk_buff *skb, struct qeth_hdr *hdr,
 -              int elements_needed, struct qeth_eddp_context *ctx)
 +              int elements_needed)
  {
        struct qeth_qdio_out_buffer *buffer;
        int start_index;
        qeth_switch_to_packing_if_needed(queue);
        if (queue->do_pack) {
                do_pack = 1;
 -              if (ctx == NULL) {
 -                      /* does packet fit in current buffer? */
 -                      if ((QETH_MAX_BUFFER_ELEMENTS(card) -
 -                          buffer->next_element_to_fill) < elements_needed) {
 -                              /* ... no -> set state PRIMED */
 -                              atomic_set(&buffer->state,
 -                                      QETH_QDIO_BUF_PRIMED);
 -                              flush_count++;
 -                              queue->next_buf_to_fill =
 -                                      (queue->next_buf_to_fill + 1) %
 -                                      QDIO_MAX_BUFFERS_PER_Q;
 -                              buffer = &queue->bufs[queue->next_buf_to_fill];
 -                              /* we did a step forward, so check buffer state
 -                               * again */
 -                              if (atomic_read(&buffer->state) !=
 -                                              QETH_QDIO_BUF_EMPTY){
 -                                      qeth_flush_buffers(queue, start_index,
 +              /* does packet fit in current buffer? */
 +              if ((QETH_MAX_BUFFER_ELEMENTS(card) -
 +                  buffer->next_element_to_fill) < elements_needed) {
 +                      /* ... no -> set state PRIMED */
 +                      atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
 +                      flush_count++;
 +                      queue->next_buf_to_fill =
 +                              (queue->next_buf_to_fill + 1) %
 +                              QDIO_MAX_BUFFERS_PER_Q;
 +                      buffer = &queue->bufs[queue->next_buf_to_fill];
 +                      /* we did a step forward, so check buffer state
 +                       * again */
 +                      if (atomic_read(&buffer->state) !=
 +                          QETH_QDIO_BUF_EMPTY) {
 +                              qeth_flush_buffers(queue, start_index,
                                                           flush_count);
 -                                      atomic_set(&queue->state,
 +                              atomic_set(&queue->state,
                                                QETH_OUT_Q_UNLOCKED);
 -                                      return -EBUSY;
 -                              }
 -                      }
 -              } else {
 -                      /* check if we have enough elements (including following
 -                       * free buffers) to handle eddp context */
 -                      if (qeth_eddp_check_buffers_for_context(queue, ctx)
 -                              < 0) {
 -                              rc = -EBUSY;
 -                              goto out;
 +                              return -EBUSY;
                        }
                }
        }
 -      if (ctx == NULL)
 -              tmp = qeth_fill_buffer(queue, buffer, skb, hdr, -1, 0);
 -      else {
 -              tmp = qeth_eddp_fill_buffer(queue, ctx,
 -                                              queue->next_buf_to_fill);
 -              if (tmp < 0) {
 -                      rc = -EBUSY;
 -                      goto out;
 -              }
 -      }
 +      tmp = qeth_fill_buffer(queue, buffer, skb, hdr, -1, 0);
        queue->next_buf_to_fill = (queue->next_buf_to_fill + tmp) %
                                  QDIO_MAX_BUFFERS_PER_Q;
        flush_count += tmp;
 -out:
        if (flush_count)
                qeth_flush_buffers(queue, start_index, flush_count);
        else if (!atomic_read(&queue->set_pci_flags_count))
@@@ -4275,7 -4306,6 +4254,7 @@@ static struct 
  /* 30 */{"tx count"},
        {"tx do_QDIO time"},
        {"tx do_QDIO count"},
 +      {"tx csum"},
  };
  
  int qeth_core_get_stats_count(struct net_device *dev)
@@@ -4327,7 -4357,6 +4306,7 @@@ void qeth_core_get_ethtool_stats(struc
        data[30] = card->perf_stats.outbound_cnt;
        data[31] = card->perf_stats.outbound_do_qdio_time;
        data[32] = card->perf_stats.outbound_do_qdio_cnt;
 +      data[33] = card->perf_stats.tx_csum;
  }
  EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats);