Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Linus Torvalds [Mon, 21 May 2012 19:41:17 +0000 (12:41 -0700)]
Pull s390 updates from Martin Schwidefsky:
 "Just a random collection of bug-fixes and cleanups, nothing new in
  this merge request."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (46 commits)
  s390/ap: Fix wrong or missing comments
  s390/ap: move receive callback to message struct
  s390/dasd: re-prioritize partition detection message
  s390/qeth: reshuffle initialization
  s390/qeth: cleanup drv attr usage
  s390/claw: cleanup drv attr usage
  s390/lcs: cleanup drv attr usage
  s390/ctc: cleanup drv attr usage
  s390/ccwgroup: remove ccwgroup_create_from_string
  s390/qeth: stop using struct ccwgroup driver for discipline callbacks
  s390/qeth: switch to ccwgroup_create_dev
  s390/claw: switch to ccwgroup_create_dev
  s390/lcs: switch to ccwgroup_create_dev
  s390/ctcm: switch to ccwgroup_create_dev
  s390/ccwgroup: exploit ccwdev_by_dev_id
  s390/ccwgroup: introduce ccwgroup_create_dev
  s390: fix race on TIF_MCCK_PENDING
  s390/barrier: make use of fast-bcr facility
  s390/barrier: cleanup barrier functions
  s390/claw: remove "eieio" calls
  ...

1  2 
drivers/crypto/Kconfig
drivers/s390/net/lcs.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l3_main.c

diff --combined drivers/crypto/Kconfig
@@@ -111,6 -111,7 +111,7 @@@ config CRYPTO_DES_S39
        depends on S390
        select CRYPTO_ALGAPI
        select CRYPTO_BLKCIPHER
+       select CRYPTO_DES
        help
          This is the s390 hardware accelerated implementation of the
          DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
@@@ -164,7 -165,6 +165,7 @@@ config CRYPTO_DEV_MV_CES
        select CRYPTO_ALGAPI
        select CRYPTO_AES
        select CRYPTO_BLKCIPHER2
 +      select CRYPTO_HASH
        help
          This driver allows you to utilize the Cryptographic Engines and
          Security Accelerator (CESA) which can be found on the Marvell Orion
diff --combined drivers/s390/net/lcs.c
@@@ -30,6 -30,7 +30,6 @@@
  #include <linux/if.h>
  #include <linux/netdevice.h>
  #include <linux/etherdevice.h>
 -#include <linux/trdevice.h>
  #include <linux/fddidevice.h>
  #include <linux/inetdevice.h>
  #include <linux/in.h>
@@@ -49,7 -50,8 +49,7 @@@
  #include "lcs.h"
  
  
 -#if !defined(CONFIG_ETHERNET) && \
 -    !defined(CONFIG_TR) && !defined(CONFIG_FDDI)
 +#if !defined(CONFIG_ETHERNET) && !defined(CONFIG_FDDI)
  #error Cannot compile lcs.c without some net devices switched on.
  #endif
  
@@@ -1164,7 -1166,10 +1164,7 @@@ static voi
  lcs_get_mac_for_ipm(__be32 ipm, char *mac, struct net_device *dev)
  {
        LCS_DBF_TEXT(4,trace, "getmac");
 -      if (dev->type == ARPHRD_IEEE802_TR)
 -              ip_tr_mc_map(ipm, mac);
 -      else
 -              ip_eth_mc_map(ipm, mac);
 +      ip_eth_mc_map(ipm, mac);
  }
  
  /**
@@@ -1636,6 -1641,12 +1636,6 @@@ lcs_startlan_auto(struct lcs_card *card
                return 0;
  
  #endif
 -#ifdef CONFIG_TR
 -      card->lan_type = LCS_FRAME_TYPE_TR;
 -      rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP);
 -      if (rc == 0)
 -              return 0;
 -#endif
  #ifdef CONFIG_FDDI
        card->lan_type = LCS_FRAME_TYPE_FDDI;
        rc = lcs_send_startlan(card, LCS_INITIATOR_TCPIP);
@@@ -2040,10 -2051,17 +2040,17 @@@ static struct attribute * lcs_attrs[] 
        &dev_attr_recover.attr,
        NULL,
  };
  static struct attribute_group lcs_attr_group = {
        .attrs = lcs_attrs,
  };
+ static const struct attribute_group *lcs_attr_groups[] = {
+       &lcs_attr_group,
+       NULL,
+ };
+ static const struct device_type lcs_devtype = {
+       .name = "lcs",
+       .groups = lcs_attr_groups,
+ };
  
  /**
   * lcs_probe_device is called on establishing a new ccwgroup_device.
@@@ -2052,7 -2070,6 +2059,6 @@@ static in
  lcs_probe_device(struct ccwgroup_device *ccwgdev)
  {
        struct lcs_card *card;
-       int ret;
  
        if (!get_device(&ccwgdev->dev))
                return -ENODEV;
                put_device(&ccwgdev->dev);
                  return -ENOMEM;
          }
-       ret = sysfs_create_group(&ccwgdev->dev.kobj, &lcs_attr_group);
-       if (ret) {
-               lcs_free_card(card);
-               put_device(&ccwgdev->dev);
-               return ret;
-         }
        dev_set_drvdata(&ccwgdev->dev, card);
        ccwgdev->cdev[0]->handler = lcs_irq;
        ccwgdev->cdev[1]->handler = lcs_irq;
        card->thread_start_mask = 0;
        card->thread_allowed_mask = 0;
        card->thread_running_mask = 0;
-         return 0;
+       ccwgdev->dev.type = &lcs_devtype;
+       return 0;
  }
  
  static int
@@@ -2161,6 -2174,12 +2163,6 @@@ lcs_new_device(struct ccwgroup_device *
                dev = alloc_etherdev(0);
                break;
  #endif
 -#ifdef CONFIG_TR
 -      case LCS_FRAME_TYPE_TR:
 -              card->lan_type_trans = tr_type_trans;
 -              dev = alloc_trdev(0);
 -              break;
 -#endif
  #ifdef CONFIG_FDDI
        case LCS_FRAME_TYPE_FDDI:
                card->lan_type_trans = fddi_type_trans;
@@@ -2306,9 -2325,9 +2308,9 @@@ lcs_remove_device(struct ccwgroup_devic
        }
        if (card->dev)
                unregister_netdev(card->dev);
-       sysfs_remove_group(&ccwgdev->dev.kobj, &lcs_attr_group);
        lcs_cleanup_card(card);
        lcs_free_card(card);
+       dev_set_drvdata(&ccwgdev->dev, NULL);
        put_device(&ccwgdev->dev);
  }
  
@@@ -2393,9 -2412,7 +2395,7 @@@ static struct ccwgroup_driver lcs_group
                .owner  = THIS_MODULE,
                .name   = "lcs",
        },
-       .max_slaves  = 2,
-       .driver_id   = 0xD3C3E2,
-       .probe       = lcs_probe_device,
+       .setup       = lcs_probe_device,
        .remove      = lcs_remove_device,
        .set_online  = lcs_new_device,
        .set_offline = lcs_shutdown_device,
        .restore     = lcs_restore,
  };
  
- static ssize_t
- lcs_driver_group_store(struct device_driver *ddrv, const char *buf,
-                      size_t count)
+ static ssize_t lcs_driver_group_store(struct device_driver *ddrv,
+                                     const char *buf, size_t count)
  {
        int err;
-       err = ccwgroup_create_from_string(lcs_root_dev,
-                                         lcs_group_driver.driver_id,
-                                         &lcs_ccw_driver, 2, buf);
+       err = ccwgroup_create_dev(lcs_root_dev, &lcs_group_driver, 2, buf);
        return err ? err : count;
  }
  static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store);
  
- static struct attribute *lcs_group_attrs[] = {
+ static struct attribute *lcs_drv_attrs[] = {
        &driver_attr_group.attr,
        NULL,
  };
- static struct attribute_group lcs_group_attr_group = {
-       .attrs = lcs_group_attrs,
+ static struct attribute_group lcs_drv_attr_group = {
+       .attrs = lcs_drv_attrs,
  };
- static const struct attribute_group *lcs_group_attr_groups[] = {
-       &lcs_group_attr_group,
+ static const struct attribute_group *lcs_drv_attr_groups[] = {
+       &lcs_drv_attr_group,
        NULL,
  };
  
@@@ -2453,7 -2464,7 +2447,7 @@@ __init lcs_init_module(void
        rc = ccw_driver_register(&lcs_ccw_driver);
        if (rc)
                goto ccw_err;
-       lcs_group_driver.driver.groups = lcs_group_attr_groups;
+       lcs_group_driver.driver.groups = lcs_drv_attr_groups;
        rc = ccwgroup_driver_register(&lcs_group_driver);
        if (rc)
                goto ccwgroup_err;
@@@ -2479,8 -2490,6 +2473,6 @@@ __exit lcs_cleanup_module(void
  {
        pr_info("Terminating lcs module.\n");
        LCS_DBF_TEXT(0, trace, "cleanup");
-       driver_remove_file(&lcs_group_driver.driver,
-                          &driver_attr_group);
        ccwgroup_driver_unregister(&lcs_group_driver);
        ccw_driver_unregister(&lcs_ccw_driver);
        root_device_unregister(lcs_root_dev);
@@@ -13,6 -13,8 +13,6 @@@
  
  #include <linux/if.h>
  #include <linux/if_arp.h>
 -#include <linux/if_tr.h>
 -#include <linux/trdevice.h>
  #include <linux/etherdevice.h>
  #include <linux/if_vlan.h>
  #include <linux/ctype.h>
@@@ -674,6 -676,8 +674,6 @@@ struct qeth_card_options 
        struct qeth_ipa_info adp; /*Adapter parameters*/
        struct qeth_routing_info route6;
        struct qeth_ipa_info ipa6;
 -      int broadcast_mode;
 -      int macaddr_mode;
        int fake_broadcast;
        int add_hhlen;
        int layer2;
@@@ -707,7 -711,16 +707,16 @@@ struct qeth_discipline 
        qdio_handler_t *input_handler;
        qdio_handler_t *output_handler;
        int (*recover)(void *ptr);
-       struct ccwgroup_driver *ccwgdriver;
+       int (*setup) (struct ccwgroup_device *);
+       void (*remove) (struct ccwgroup_device *);
+       int (*set_online) (struct ccwgroup_device *);
+       int (*set_offline) (struct ccwgroup_device *);
+       void (*shutdown)(struct ccwgroup_device *);
+       int (*prepare) (struct ccwgroup_device *);
+       void (*complete) (struct ccwgroup_device *);
+       int (*freeze)(struct ccwgroup_device *);
+       int (*thaw) (struct ccwgroup_device *);
+       int (*restore)(struct ccwgroup_device *);
  };
  
  struct qeth_vlan_vid {
@@@ -771,7 -784,7 +780,7 @@@ struct qeth_card 
        struct qeth_perf_stats perf_stats;
        int read_or_write_problem;
        struct qeth_osn_info osn_info;
-       struct qeth_discipline discipline;
+       struct qeth_discipline *discipline;
        atomic_t force_alloc_skb;
        struct service_level qeth_service_level;
        struct qdio_ssqd_desc ssqd;
@@@ -837,16 -850,15 +846,15 @@@ static inline int qeth_is_diagass_suppo
        return card->info.diagass_support & (__u32)cmd;
  }
  
- extern struct ccwgroup_driver qeth_l2_ccwgroup_driver;
- extern struct ccwgroup_driver qeth_l3_ccwgroup_driver;
+ extern struct qeth_discipline qeth_l2_discipline;
+ extern struct qeth_discipline qeth_l3_discipline;
+ extern const struct attribute_group *qeth_generic_attr_groups[];
+ extern const struct attribute_group *qeth_osn_attr_groups[];
  const char *qeth_get_cardname_short(struct qeth_card *);
  int qeth_realloc_buffer_pool(struct qeth_card *, int);
  int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id);
  void qeth_core_free_discipline(struct qeth_card *);
- int qeth_core_create_device_attributes(struct device *);
- void qeth_core_remove_device_attributes(struct device *);
- int qeth_core_create_osn_attributes(struct device *);
- void qeth_core_remove_osn_attributes(struct device *);
  void qeth_buffer_reclaim_work(struct work_struct *);
  
  /* exports for qeth discipline device drivers */
@@@ -1329,6 -1329,8 +1329,6 @@@ static void qeth_set_intial_options(str
  {
        card->options.route4.type = NO_ROUTER;
        card->options.route6.type = NO_ROUTER;
 -      card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
 -      card->options.macaddr_mode = QETH_TR_MACADDR_NONCANONICAL;
        card->options.fake_broadcast = 0;
        card->options.add_hhlen = DEFAULT_ADD_HHLEN;
        card->options.performance_stats = 0;
@@@ -1363,7 -1365,7 +1363,7 @@@ static void qeth_start_kernel_thread(st
            card->write.state != CH_STATE_UP)
                return;
        if (qeth_do_start_thread(card, QETH_RECOVER_THREAD)) {
-               ts = kthread_run(card->discipline.recover, (void *)card,
+               ts = kthread_run(card->discipline->recover, (void *)card,
                                "qeth_recover");
                if (IS_ERR(ts)) {
                        qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
@@@ -3337,7 -3339,7 +3337,7 @@@ static void qeth_flush_buffers(struct q
        if (rc) {
                queue->card->stats.tx_errors += count;
                /* ignore temporary SIGA errors without busy condition */
-               if (rc == QDIO_ERROR_SIGA_TARGET)
+               if (rc == -ENOBUFS)
                        return;
                QETH_CARD_TEXT(queue->card, 2, "flushbuf");
                QETH_CARD_TEXT_(queue->card, 2, " q%d", queue->queue_no);
@@@ -3531,7 -3533,7 +3531,7 @@@ void qeth_qdio_output_handler(struct cc
        int i;
  
        QETH_CARD_TEXT(card, 6, "qdouhdl");
-       if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
+       if (qdio_error & QDIO_ERROR_FATAL) {
                QETH_CARD_TEXT(card, 2, "achkcond");
                netif_stop_queue(card->dev);
                qeth_schedule_recovery(card);
@@@ -4627,7 -4629,7 +4627,7 @@@ static int qeth_qdio_establish(struct q
                goto out_free_in_sbals;
        }
        for (i = 0; i < card->qdio.no_in_queues; ++i)
-               queue_start_poll[i] = card->discipline.start_poll;
+               queue_start_poll[i] = card->discipline->start_poll;
  
        qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll);
  
        init_data.qib_param_field        = qib_param_field;
        init_data.no_input_qs            = card->qdio.no_in_queues;
        init_data.no_output_qs           = card->qdio.no_out_queues;
-       init_data.input_handler          = card->discipline.input_handler;
-       init_data.output_handler         = card->discipline.output_handler;
+       init_data.input_handler          = card->discipline->input_handler;
+       init_data.output_handler         = card->discipline->output_handler;
        init_data.queue_start_poll_array = queue_start_poll;
        init_data.int_parm               = (unsigned long) card;
        init_data.input_sbal_addr_array  = (void **) in_sbal_ptrs;
@@@ -4737,13 -4739,6 +4737,6 @@@ static struct ccw_driver qeth_ccw_drive
        .remove = ccwgroup_remove_ccwdev,
  };
  
- static int qeth_core_driver_group(const char *buf, struct device *root_dev,
-                               unsigned long driver_id)
- {
-       return ccwgroup_create_from_string(root_dev, driver_id,
-                                          &qeth_ccw_driver, 3, buf);
- }
  int qeth_core_hardsetup_card(struct qeth_card *card)
  {
        int retries = 0;
@@@ -4909,7 -4904,11 +4902,7 @@@ struct sk_buff *qeth_core_get_next_skb(
                break;
        case QETH_HEADER_TYPE_LAYER3:
                skb_len = (*hdr)->hdr.l3.length;
 -              if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) ||
 -                  (card->info.link_type == QETH_LINK_TYPE_HSTR))
 -                      headroom = TR_HLEN;
 -              else
 -                      headroom = ETH_HLEN;
 +              headroom = ETH_HLEN;
                break;
        case QETH_HEADER_TYPE_OSN:
                skb_len = (*hdr)->hdr.osn.pdu_length;
@@@ -5040,17 -5039,15 +5033,15 @@@ int qeth_core_load_discipline(struct qe
        mutex_lock(&qeth_mod_mutex);
        switch (discipline) {
        case QETH_DISCIPLINE_LAYER3:
-               card->discipline.ccwgdriver = try_then_request_module(
-                       symbol_get(qeth_l3_ccwgroup_driver),
-                       "qeth_l3");
+               card->discipline = try_then_request_module(
+                       symbol_get(qeth_l3_discipline), "qeth_l3");
                break;
        case QETH_DISCIPLINE_LAYER2:
-               card->discipline.ccwgdriver = try_then_request_module(
-                       symbol_get(qeth_l2_ccwgroup_driver),
-                       "qeth_l2");
+               card->discipline = try_then_request_module(
+                       symbol_get(qeth_l2_discipline), "qeth_l2");
                break;
        }
-       if (!card->discipline.ccwgdriver) {
+       if (!card->discipline) {
                dev_err(&card->gdev->dev, "There is no kernel module to "
                        "support discipline %d\n", discipline);
                rc = -EINVAL;
  void qeth_core_free_discipline(struct qeth_card *card)
  {
        if (card->options.layer2)
-               symbol_put(qeth_l2_ccwgroup_driver);
+               symbol_put(qeth_l2_discipline);
        else
-               symbol_put(qeth_l3_ccwgroup_driver);
-       card->discipline.ccwgdriver = NULL;
+               symbol_put(qeth_l3_discipline);
+       card->discipline = NULL;
  }
  
+ static const struct device_type qeth_generic_devtype = {
+       .name = "qeth_generic",
+       .groups = qeth_generic_attr_groups,
+ };
+ static const struct device_type qeth_osn_devtype = {
+       .name = "qeth_osn",
+       .groups = qeth_osn_attr_groups,
+ };
  static int qeth_core_probe_device(struct ccwgroup_device *gdev)
  {
        struct qeth_card *card;
        }
  
        if (card->info.type == QETH_CARD_TYPE_OSN)
-               rc = qeth_core_create_osn_attributes(dev);
+               gdev->dev.type = &qeth_osn_devtype;
        else
-               rc = qeth_core_create_device_attributes(dev);
-       if (rc)
-               goto err_dbf;
+               gdev->dev.type = &qeth_generic_devtype;
        switch (card->info.type) {
        case QETH_CARD_TYPE_OSN:
        case QETH_CARD_TYPE_OSM:
                rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2);
                if (rc)
-                       goto err_attr;
-               rc = card->discipline.ccwgdriver->probe(card->gdev);
+                       goto err_dbf;
+               rc = card->discipline->setup(card->gdev);
                if (rc)
                        goto err_disc;
        case QETH_CARD_TYPE_OSD:
  
  err_disc:
        qeth_core_free_discipline(card);
- err_attr:
-       if (card->info.type == QETH_CARD_TYPE_OSN)
-               qeth_core_remove_osn_attributes(dev);
-       else
-               qeth_core_remove_device_attributes(dev);
  err_dbf:
        debug_unregister(card->debug);
  err_card:
@@@ -5172,14 -5172,8 +5166,8 @@@ static void qeth_core_remove_device(str
  
        QETH_DBF_TEXT(SETUP, 2, "removedv");
  
-       if (card->info.type == QETH_CARD_TYPE_OSN) {
-               qeth_core_remove_osn_attributes(&gdev->dev);
-       } else {
-               qeth_core_remove_device_attributes(&gdev->dev);
-       }
-       if (card->discipline.ccwgdriver) {
-               card->discipline.ccwgdriver->remove(gdev);
+       if (card->discipline) {
+               card->discipline->remove(gdev);
                qeth_core_free_discipline(card);
        }
  
@@@ -5199,7 -5193,7 +5187,7 @@@ static int qeth_core_set_online(struct 
        int rc = 0;
        int def_discipline;
  
-       if (!card->discipline.ccwgdriver) {
+       if (!card->discipline) {
                if (card->info.type == QETH_CARD_TYPE_IQD)
                        def_discipline = QETH_DISCIPLINE_LAYER3;
                else
                rc = qeth_core_load_discipline(card, def_discipline);
                if (rc)
                        goto err;
-               rc = card->discipline.ccwgdriver->probe(card->gdev);
+               rc = card->discipline->setup(card->gdev);
                if (rc)
                        goto err;
        }
-       rc = card->discipline.ccwgdriver->set_online(gdev);
+       rc = card->discipline->set_online(gdev);
  err:
        return rc;
  }
  static int qeth_core_set_offline(struct ccwgroup_device *gdev)
  {
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
-       return card->discipline.ccwgdriver->set_offline(gdev);
+       return card->discipline->set_offline(gdev);
  }
  
  static void qeth_core_shutdown(struct ccwgroup_device *gdev)
  {
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
-       if (card->discipline.ccwgdriver &&
-           card->discipline.ccwgdriver->shutdown)
-               card->discipline.ccwgdriver->shutdown(gdev);
+       if (card->discipline && card->discipline->shutdown)
+               card->discipline->shutdown(gdev);
  }
  
  static int qeth_core_prepare(struct ccwgroup_device *gdev)
  {
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
-       if (card->discipline.ccwgdriver &&
-           card->discipline.ccwgdriver->prepare)
-               return card->discipline.ccwgdriver->prepare(gdev);
+       if (card->discipline && card->discipline->prepare)
+               return card->discipline->prepare(gdev);
        return 0;
  }
  
  static void qeth_core_complete(struct ccwgroup_device *gdev)
  {
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
-       if (card->discipline.ccwgdriver &&
-           card->discipline.ccwgdriver->complete)
-               card->discipline.ccwgdriver->complete(gdev);
+       if (card->discipline && card->discipline->complete)
+               card->discipline->complete(gdev);
  }
  
  static int qeth_core_freeze(struct ccwgroup_device *gdev)
  {
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
-       if (card->discipline.ccwgdriver &&
-           card->discipline.ccwgdriver->freeze)
-               return card->discipline.ccwgdriver->freeze(gdev);
+       if (card->discipline && card->discipline->freeze)
+               return card->discipline->freeze(gdev);
        return 0;
  }
  
  static int qeth_core_thaw(struct ccwgroup_device *gdev)
  {
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
-       if (card->discipline.ccwgdriver &&
-           card->discipline.ccwgdriver->thaw)
-               return card->discipline.ccwgdriver->thaw(gdev);
+       if (card->discipline && card->discipline->thaw)
+               return card->discipline->thaw(gdev);
        return 0;
  }
  
  static int qeth_core_restore(struct ccwgroup_device *gdev)
  {
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
-       if (card->discipline.ccwgdriver &&
-           card->discipline.ccwgdriver->restore)
-               return card->discipline.ccwgdriver->restore(gdev);
+       if (card->discipline && card->discipline->restore)
+               return card->discipline->restore(gdev);
        return 0;
  }
  
@@@ -5279,8 -5267,7 +5261,7 @@@ static struct ccwgroup_driver qeth_core
                .owner = THIS_MODULE,
                .name = "qeth",
        },
-       .driver_id = 0xD8C5E3C8,
-       .probe = qeth_core_probe_device,
+       .setup = qeth_core_probe_device,
        .remove = qeth_core_remove_device,
        .set_online = qeth_core_set_online,
        .set_offline = qeth_core_set_offline,
        .restore = qeth_core_restore,
  };
  
- static ssize_t
- qeth_core_driver_group_store(struct device_driver *ddrv, const char *buf,
-                          size_t count)
+ static ssize_t qeth_core_driver_group_store(struct device_driver *ddrv,
+                                           const char *buf, size_t count)
  {
        int err;
-       err = qeth_core_driver_group(buf, qeth_core_root_dev,
-                                       qeth_core_ccwgroup_driver.driver_id);
-       if (err)
-               return err;
-       else
-               return count;
- }
  
+       err = ccwgroup_create_dev(qeth_core_root_dev,
+                                 &qeth_core_ccwgroup_driver, 3, buf);
+       return err ? err : count;
+ }
  static DRIVER_ATTR(group, 0200, NULL, qeth_core_driver_group_store);
  
+ static struct attribute *qeth_drv_attrs[] = {
+       &driver_attr_group.attr,
+       NULL,
+ };
+ static struct attribute_group qeth_drv_attr_group = {
+       .attrs = qeth_drv_attrs,
+ };
+ static const struct attribute_group *qeth_drv_attr_groups[] = {
+       &qeth_drv_attr_group,
+       NULL,
+ };
  static struct {
        const char str[ETH_GSTRING_LEN];
  } qeth_ethtool_stats_keys[] = {
@@@ -5544,49 -5540,41 +5534,41 @@@ static int __init qeth_core_init(void
        rc = qeth_register_dbf_views();
        if (rc)
                goto out_err;
-       rc = ccw_driver_register(&qeth_ccw_driver);
-       if (rc)
-               goto ccw_err;
-       rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver);
-       if (rc)
-               goto ccwgroup_err;
-       rc = driver_create_file(&qeth_core_ccwgroup_driver.driver,
-                               &driver_attr_group);
-       if (rc)
-               goto driver_err;
        qeth_core_root_dev = root_device_register("qeth");
        rc = IS_ERR(qeth_core_root_dev) ? PTR_ERR(qeth_core_root_dev) : 0;
        if (rc)
                goto register_err;
        qeth_core_header_cache = kmem_cache_create("qeth_hdr",
                        sizeof(struct qeth_hdr) + ETH_HLEN, 64, 0, NULL);
        if (!qeth_core_header_cache) {
                rc = -ENOMEM;
                goto slab_err;
        }
        qeth_qdio_outbuf_cache = kmem_cache_create("qeth_buf",
                        sizeof(struct qeth_qdio_out_buffer), 0, 0, NULL);
        if (!qeth_qdio_outbuf_cache) {
                rc = -ENOMEM;
                goto cqslab_err;
        }
+       rc = ccw_driver_register(&qeth_ccw_driver);
+       if (rc)
+               goto ccw_err;
+       qeth_core_ccwgroup_driver.driver.groups = qeth_drv_attr_groups;
+       rc = ccwgroup_driver_register(&qeth_core_ccwgroup_driver);
+       if (rc)
+               goto ccwgroup_err;
  
        return 0;
+ ccwgroup_err:
+       ccw_driver_unregister(&qeth_ccw_driver);
+ ccw_err:
+       kmem_cache_destroy(qeth_qdio_outbuf_cache);
  cqslab_err:
        kmem_cache_destroy(qeth_core_header_cache);
  slab_err:
        root_device_unregister(qeth_core_root_dev);
  register_err:
-       driver_remove_file(&qeth_core_ccwgroup_driver.driver,
-                          &driver_attr_group);
- driver_err:
-       ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
- ccwgroup_err:
-       ccw_driver_unregister(&qeth_ccw_driver);
- ccw_err:
-       QETH_DBF_MESSAGE(2, "Initialization failed with code %d\n", rc);
        qeth_unregister_dbf_views();
  out_err:
        pr_err("Initializing the qeth device driver failed\n");
  
  static void __exit qeth_core_exit(void)
  {
-       root_device_unregister(qeth_core_root_dev);
-       driver_remove_file(&qeth_core_ccwgroup_driver.driver,
-                          &driver_attr_group);
        ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver);
        ccw_driver_unregister(&qeth_ccw_driver);
        kmem_cache_destroy(qeth_qdio_outbuf_cache);
        kmem_cache_destroy(qeth_core_header_cache);
+       root_device_unregister(qeth_core_root_dev);
        qeth_unregister_dbf_views();
        pr_info("core functions removed\n");
  }
@@@ -976,6 -976,57 +976,6 @@@ static inline u8 qeth_l3_get_qeth_hdr_f
        return ct | QETH_CAST_UNICAST;
  }
  
 -static int qeth_l3_send_setadp_mode(struct qeth_card *card, __u32 command,
 -                                      __u32 mode)
 -{
 -      int rc;
 -      struct qeth_cmd_buffer *iob;
 -      struct qeth_ipa_cmd *cmd;
 -
 -      QETH_CARD_TEXT(card, 4, "adpmode");
 -
 -      iob = qeth_get_adapter_cmd(card, command,
 -                                 sizeof(struct qeth_ipacmd_setadpparms));
 -      cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 -      cmd->data.setadapterparms.data.mode = mode;
 -      rc = qeth_send_ipa_cmd(card, iob, qeth_default_setadapterparms_cb,
 -                             NULL);
 -      return rc;
 -}
 -
 -static int qeth_l3_setadapter_hstr(struct qeth_card *card)
 -{
 -      int rc;
 -
 -      QETH_CARD_TEXT(card, 4, "adphstr");
 -
 -      if (qeth_adp_supported(card, IPA_SETADP_SET_BROADCAST_MODE)) {
 -              rc = qeth_l3_send_setadp_mode(card,
 -                                      IPA_SETADP_SET_BROADCAST_MODE,
 -                                      card->options.broadcast_mode);
 -              if (rc)
 -                      QETH_DBF_MESSAGE(2, "couldn't set broadcast mode on "
 -                                 "device %s: x%x\n",
 -                                 CARD_BUS_ID(card), rc);
 -              rc = qeth_l3_send_setadp_mode(card,
 -                                      IPA_SETADP_ALTER_MAC_ADDRESS,
 -                                      card->options.macaddr_mode);
 -              if (rc)
 -                      QETH_DBF_MESSAGE(2, "couldn't set macaddr mode on "
 -                                 "device %s: x%x\n", CARD_BUS_ID(card), rc);
 -              return rc;
 -      }
 -      if (card->options.broadcast_mode == QETH_TR_BROADCAST_LOCAL)
 -              QETH_DBF_MESSAGE(2, "set adapter parameters not available "
 -                         "to set broadcast mode, using ALLRINGS "
 -                         "on device %s:\n", CARD_BUS_ID(card));
 -      if (card->options.macaddr_mode == QETH_TR_MACADDR_CANONICAL)
 -              QETH_DBF_MESSAGE(2, "set adapter parameters not available "
 -                         "to set macaddr mode, using NONCANONICAL "
 -                         "on device %s:\n", CARD_BUS_ID(card));
 -      return 0;
 -}
 -
  static int qeth_l3_setadapter_parms(struct qeth_card *card)
  {
        int rc;
                                " address failed\n");
        }
  
 -      if ((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
 -          (card->info.link_type == QETH_LINK_TYPE_LANE_TR))
 -              rc = qeth_l3_setadapter_hstr(card);
 -
        return rc;
  }
  
@@@ -1616,7 -1671,10 +1616,7 @@@ qeth_diags_trace(struct qeth_card *card
  static void qeth_l3_get_mac_for_ipm(__u32 ipm, char *mac,
                                struct net_device *dev)
  {
 -      if (dev->type == ARPHRD_IEEE802_TR)
 -              ip_tr_mc_map(ipm, mac);
 -      else
 -              ip_eth_mc_map(ipm, mac);
 +      ip_eth_mc_map(ipm, mac);
  }
  
  static void qeth_l3_add_mc(struct qeth_card *card, struct in_device *in4_dev)
@@@ -1864,6 -1922,8 +1864,6 @@@ static inline int qeth_l3_rebuild_skb(s
  #endif
                        case __constant_htons(ETH_P_IP):
                                ip_hdr = (struct iphdr *)skb->data;
 -                              (card->dev->type == ARPHRD_IEEE802_TR) ?
 -                              ip_tr_mc_map(ip_hdr->daddr, tg_addr):
                                ip_eth_mc_map(ip_hdr->daddr, tg_addr);
                                break;
                        default:
                                tg_addr, "FAKELL", card->dev->addr_len);
        }
  
 -#ifdef CONFIG_TR
 -      if (card->dev->type == ARPHRD_IEEE802_TR)
 -              skb->protocol = tr_type_trans(skb, card->dev);
 -      else
 -#endif
 -              skb->protocol = eth_type_trans(skb, card->dev);
 +      skb->protocol = eth_type_trans(skb, card->dev);
  
        if (hdr->hdr.l3.ext_flags &
            (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) {
@@@ -2073,7 -2138,7 +2073,7 @@@ static int qeth_l3_verify_vlan_dev(stru
                struct net_device *netdev;
  
                rcu_read_lock();
 -              netdev = __vlan_find_dev_deep(dev, vid);
 +              netdev = __vlan_find_dev_deep(card->dev, vid);
                rcu_read_unlock();
                if (netdev == dev) {
                        rc = QETH_VLAN_CARD;
@@@ -2818,7 -2883,13 +2818,7 @@@ static void qeth_l3_fill_header(struct 
                        hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU;
                memcpy(hdr->hdr.l3.dest_addr, pkey, 16);
        } else {
 -              /* passthrough */
 -              if ((skb->dev->type == ARPHRD_IEEE802_TR) &&
 -                      !memcmp(skb->data + sizeof(struct qeth_hdr) +
 -                      sizeof(__u16), skb->dev->broadcast, 6)) {
 -                      hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
 -                                              QETH_HDR_PASSTHRU;
 -              } else if (!memcmp(skb->data + sizeof(struct qeth_hdr),
 +              if (!memcmp(skb->data + sizeof(struct qeth_hdr),
                            skb->dev->broadcast, 6)) {
                        /* broadcast? */
                        hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
@@@ -2960,7 -3031,10 +2960,7 @@@ static int qeth_l3_hard_start_xmit(stru
                        skb_pull(new_skb, ETH_HLEN);
        } else {
                if (ipv == 4) {
 -                      if (card->dev->type == ARPHRD_IEEE802_TR)
 -                              skb_pull(new_skb, TR_HLEN);
 -                      else
 -                              skb_pull(new_skb, ETH_HLEN);
 +                      skb_pull(new_skb, ETH_HLEN);
                }
  
                if (ipv != 4 && vlan_tx_tag_present(new_skb)) {
@@@ -3244,8 -3318,12 +3244,8 @@@ static int qeth_l3_setup_netdev(struct 
            card->info.type == QETH_CARD_TYPE_OSX) {
                if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) ||
                    (card->info.link_type == QETH_LINK_TYPE_HSTR)) {
 -#ifdef CONFIG_TR
 -                      card->dev = alloc_trdev(0);
 -#endif
 -                      if (!card->dev)
 -                              return -ENODEV;
 -                      card->dev->netdev_ops = &qeth_l3_netdev_ops;
 +                      pr_info("qeth_l3: ignoring TR device\n");
 +                      return -ENODEV;
                } else {
                        card->dev = alloc_etherdev(0);
                        if (!card->dev)
@@@ -3298,12 -3376,6 +3298,6 @@@ static int qeth_l3_probe_device(struct 
        qeth_l3_create_device_attributes(&gdev->dev);
        card->options.layer2 = 0;
        card->info.hwtrap = 0;
-       card->discipline.start_poll = qeth_qdio_start_poll;
-       card->discipline.input_handler = (qdio_handler_t *)
-               qeth_qdio_input_handler;
-       card->discipline.output_handler = (qdio_handler_t *)
-               qeth_qdio_output_handler;
-       card->discipline.recover = qeth_l3_recover;
        return 0;
  }
  
        return rc;
  }
  
- struct ccwgroup_driver qeth_l3_ccwgroup_driver = {
-       .probe = qeth_l3_probe_device,
+ struct qeth_discipline qeth_l3_discipline = {
+       .start_poll = qeth_qdio_start_poll,
+       .input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
+       .output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
+       .recover = qeth_l3_recover,
+       .setup = qeth_l3_probe_device,
        .remove = qeth_l3_remove_device,
        .set_online = qeth_l3_set_online,
        .set_offline = qeth_l3_set_offline,
        .thaw = qeth_l3_pm_resume,
        .restore = qeth_l3_pm_resume,
  };
- EXPORT_SYMBOL_GPL(qeth_l3_ccwgroup_driver);
+ EXPORT_SYMBOL_GPL(qeth_l3_discipline);
  
  static int qeth_l3_ip_event(struct notifier_block *this,
                            unsigned long event, void *ptr)
                return NOTIFY_DONE;
  
        card = qeth_l3_get_card_from_dev(dev);
 -      QETH_CARD_TEXT(card, 3, "ipevent");
        if (!card)
                return NOTIFY_DONE;
 +      QETH_CARD_TEXT(card, 3, "ipevent");
  
        addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
        if (addr != NULL) {