diff options
author | Ursula Braun <ursula.braun@de.ibm.com> | 2009-11-12 21:46:29 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-13 20:47:00 -0800 |
commit | 0ca8cc6fe7e1acd42a8a3741473ad7540f13893a (patch) | |
tree | aa443f7574e8a8e3a0aee0bd84ab852e4eac2294 /drivers/s390/net/lcs.c | |
parent | 1e1815be87e45ce512f998ab35e9554c25031f4d (diff) | |
download | linux-0ca8cc6fe7e1acd42a8a3741473ad7540f13893a.tar.bz2 |
s390: remove cu3088 layer for lcs and ctcm
The cu3088-driver used as common base for lcs- and ctcm-devices
makes it difficult to assign the appropriate driver to an lcs-device
or a ctcm-device. This patch eliminates the cu3088-driver and thus
the root device "cu3088". Path /sys/devices/cu3088 is replaced with
the pathes /sys/devices/lcs and /sys/devices/ctcm.
Patch is based on a proposal from Cornelia Huck.
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390/net/lcs.c')
-rw-r--r-- | drivers/s390/net/lcs.c | 101 |
1 files changed, 87 insertions, 14 deletions
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 5e46415d3e13..1d43d23f5ea3 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -47,7 +47,6 @@ #include <asm/ccwgroup.h> #include "lcs.h" -#include "cu3088.h" #if !defined(CONFIG_NET_ETHERNET) && \ @@ -60,7 +59,11 @@ */ static char version[] __initdata = "LCS driver"; -static char debug_buffer[255]; + +/** + * the root device for lcs group devices + */ +static struct device *lcs_root_dev; /** * Some prototypes. @@ -76,6 +79,7 @@ static int lcs_recovery(void *ptr); /** * Debug Facility Stuff */ +static char debug_buffer[255]; static debug_info_t *lcs_dbf_setup; static debug_info_t *lcs_dbf_trace; @@ -1968,6 +1972,15 @@ lcs_portno_store (struct device *dev, struct device_attribute *attr, const char static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store); +const char *lcs_type[] = { + "not a channel", + "2216 parallel", + "2216 channel", + "OSA LCS card", + "unknown channel type", + "unsupported channel type", +}; + static ssize_t lcs_type_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1977,7 +1990,7 @@ lcs_type_show(struct device *dev, struct device_attribute *attr, char *buf) if (!cgdev) return -ENODEV; - return sprintf(buf, "%s\n", cu3088_type[cgdev->cdev[0]->id.driver_info]); + return sprintf(buf, "%s\n", lcs_type[cgdev->cdev[0]->id.driver_info]); } static DEVICE_ATTR(type, 0444, lcs_type_show, NULL); @@ -2370,6 +2383,22 @@ static int lcs_restore(struct ccwgroup_device *gdev) return lcs_pm_resume(card); } +static struct ccw_device_id lcs_ids[] = { + {CCW_DEVICE(0x3088, 0x08), .driver_info = lcs_channel_type_parallel}, + {CCW_DEVICE(0x3088, 0x1f), .driver_info = lcs_channel_type_2216}, + {CCW_DEVICE(0x3088, 0x60), .driver_info = lcs_channel_type_osa2}, + {}, +}; +MODULE_DEVICE_TABLE(ccw, lcs_ids); + +static struct ccw_driver lcs_ccw_driver = { + .owner = THIS_MODULE, + .name = "lcs", + .ids = lcs_ids, + .probe = ccwgroup_probe_ccwdev, + .remove = ccwgroup_remove_ccwdev, +}; + /** * LCS ccwgroup driver registration */ @@ -2389,6 +2418,33 @@ static struct ccwgroup_driver lcs_group_driver = { .restore = lcs_restore, }; +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); + return err ? err : count; +} + +static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store); + +static struct attribute *lcs_group_attrs[] = { + &driver_attr_group.attr, + NULL, +}; + +static struct attribute_group lcs_group_attr_group = { + .attrs = lcs_group_attrs, +}; + +static struct attribute_group *lcs_group_attr_groups[] = { + &lcs_group_attr_group, + NULL, +}; + /** * LCS Module/Kernel initialization function */ @@ -2400,17 +2456,30 @@ __init lcs_init_module(void) pr_info("Loading %s\n", version); rc = lcs_register_debug_facility(); LCS_DBF_TEXT(0, setup, "lcsinit"); - if (rc) { - pr_err("Initialization failed\n"); - return rc; - } - - rc = register_cu3088_discipline(&lcs_group_driver); - if (rc) { - pr_err("Initialization failed\n"); - return rc; - } + if (rc) + goto out_err; + lcs_root_dev = root_device_register("lcs"); + rc = IS_ERR(lcs_root_dev) ? PTR_ERR(lcs_root_dev) : 0; + if (rc) + goto register_err; + rc = ccw_driver_register(&lcs_ccw_driver); + if (rc) + goto ccw_err; + lcs_group_driver.driver.groups = lcs_group_attr_groups; + rc = ccwgroup_driver_register(&lcs_group_driver); + if (rc) + goto ccwgroup_err; return 0; + +ccwgroup_err: + ccw_driver_unregister(&lcs_ccw_driver); +ccw_err: + root_device_unregister(lcs_root_dev); +register_err: + lcs_unregister_debug_facility(); +out_err: + pr_err("Initializing the lcs device driver failed\n"); + return rc; } @@ -2422,7 +2491,11 @@ __exit lcs_cleanup_module(void) { pr_info("Terminating lcs module.\n"); LCS_DBF_TEXT(0, trace, "cleanup"); - unregister_cu3088_discipline(&lcs_group_driver); + 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); lcs_unregister_debug_facility(); } |