Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[linux-3.10.git] / drivers / s390 / net / qeth_core_main.c
index e000001..e118e1e 100644 (file)
@@ -1363,7 +1363,7 @@ static void qeth_start_kernel_thread(struct work_struct *work)
            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 +3337,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
        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 +3531,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
        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 +4627,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
                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);
 
@@ -4651,8 +4651,8 @@ static int qeth_qdio_establish(struct qeth_card *card)
        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 +4737,6 @@ static struct ccw_driver qeth_ccw_driver = {
        .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;
@@ -5040,17 +5033,15 @@ int qeth_core_load_discipline(struct qeth_card *card,
        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;
@@ -5062,12 +5053,21 @@ int qeth_core_load_discipline(struct qeth_card *card,
 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;
@@ -5122,18 +5122,17 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
        }
 
        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:
@@ -5151,11 +5150,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
 
 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 +5166,8 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
 
        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 +5187,7 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
        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
@@ -5207,11 +5195,11 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
                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;
 }
@@ -5219,58 +5207,52 @@ err:
 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 +5261,7 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = {
                .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,
@@ -5292,21 +5273,30 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = {
        .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 +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");
@@ -5595,13 +5577,11 @@ out_err:
 
 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");
 }