Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ursula Braun and committed by
David S. Miller
0ca8cc6f 1e1815be

+304 -242
+3 -3
drivers/s390/net/Makefile
··· 3 3 # 4 4 5 5 ctcm-y += ctcm_main.o ctcm_fsms.o ctcm_mpc.o ctcm_sysfs.o ctcm_dbug.o 6 - obj-$(CONFIG_CTCM) += ctcm.o fsm.o cu3088.o 6 + obj-$(CONFIG_CTCM) += ctcm.o fsm.o 7 7 obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o 8 8 obj-$(CONFIG_SMSGIUCV) += smsgiucv.o 9 - obj-$(CONFIG_LCS) += lcs.o cu3088.o 10 - obj-$(CONFIG_CLAW) += claw.o cu3088.o 9 + obj-$(CONFIG_LCS) += lcs.o 10 + obj-$(CONFIG_CLAW) += claw.o 11 11 qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o 12 12 obj-$(CONFIG_QETH) += qeth.o 13 13 qeth_l2-y += qeth_l2_main.o
+72 -10
drivers/s390/net/claw.c
··· 90 90 #include <linux/timer.h> 91 91 #include <linux/types.h> 92 92 93 - #include "cu3088.h" 94 93 #include "claw.h" 95 94 96 95 /* ··· 257 258 return -EPERM; 258 259 } 259 260 261 + /* the root device for claw group devices */ 262 + static struct device *claw_root_dev; 263 + 260 264 /* ccwgroup table */ 261 265 262 266 static struct ccwgroup_driver claw_group_driver = { ··· 272 270 .set_online = claw_new_device, 273 271 .set_offline = claw_shutdown_device, 274 272 .prepare = claw_pm_prepare, 273 + }; 274 + 275 + static struct ccw_device_id claw_ids[] = { 276 + {CCW_DEVICE(0x3088, 0x61), .driver_info = claw_channel_type_claw}, 277 + {}, 278 + }; 279 + MODULE_DEVICE_TABLE(ccw, claw_ids); 280 + 281 + static struct ccw_driver claw_ccw_driver = { 282 + .owner = THIS_MODULE, 283 + .name = "claw", 284 + .ids = claw_ids, 285 + .probe = ccwgroup_probe_ccwdev, 286 + .remove = ccwgroup_remove_ccwdev, 287 + }; 288 + 289 + static ssize_t 290 + claw_driver_group_store(struct device_driver *ddrv, const char *buf, 291 + size_t count) 292 + { 293 + int err; 294 + err = ccwgroup_create_from_string(claw_root_dev, 295 + claw_group_driver.driver_id, 296 + &claw_ccw_driver, 3, buf); 297 + return err ? err : count; 298 + } 299 + 300 + static DRIVER_ATTR(group, 0200, NULL, claw_driver_group_store); 301 + 302 + static struct attribute *claw_group_attrs[] = { 303 + &driver_attr_group.attr, 304 + NULL, 305 + }; 306 + 307 + static struct attribute_group claw_group_attr_group = { 308 + .attrs = claw_group_attrs, 309 + }; 310 + 311 + static struct attribute_group *claw_group_attr_groups[] = { 312 + &claw_group_attr_group, 313 + NULL, 275 314 }; 276 315 277 316 /* ··· 3369 3326 static void __exit 3370 3327 claw_cleanup(void) 3371 3328 { 3372 - unregister_cu3088_discipline(&claw_group_driver); 3329 + driver_remove_file(&claw_group_driver.driver, 3330 + &driver_attr_group); 3331 + ccwgroup_driver_unregister(&claw_group_driver); 3332 + ccw_driver_unregister(&claw_ccw_driver); 3333 + root_device_unregister(claw_root_dev); 3373 3334 claw_unregister_debug_facility(); 3374 3335 pr_info("Driver unloaded\n"); 3375 3336 ··· 3395 3348 if (ret) { 3396 3349 pr_err("Registering with the S/390 debug feature" 3397 3350 " failed with error code %d\n", ret); 3398 - return ret; 3351 + goto out_err; 3399 3352 } 3400 3353 CLAW_DBF_TEXT(2, setup, "init_mod"); 3401 - ret = register_cu3088_discipline(&claw_group_driver); 3402 - if (ret) { 3403 - CLAW_DBF_TEXT(2, setup, "init_bad"); 3404 - claw_unregister_debug_facility(); 3405 - pr_err("Registering with the cu3088 device driver failed " 3406 - "with error code %d\n", ret); 3407 - } 3354 + claw_root_dev = root_device_register("qeth"); 3355 + ret = IS_ERR(claw_root_dev) ? PTR_ERR(claw_root_dev) : 0; 3356 + if (ret) 3357 + goto register_err; 3358 + ret = ccw_driver_register(&claw_ccw_driver); 3359 + if (ret) 3360 + goto ccw_err; 3361 + claw_group_driver.driver.groups = claw_group_attr_groups; 3362 + ret = ccwgroup_driver_register(&claw_group_driver); 3363 + if (ret) 3364 + goto ccwgroup_err; 3365 + return 0; 3366 + 3367 + ccwgroup_err: 3368 + ccw_driver_unregister(&claw_ccw_driver); 3369 + ccw_err: 3370 + root_device_unregister(claw_root_dev); 3371 + register_err: 3372 + CLAW_DBF_TEXT(2, setup, "init_bad"); 3373 + claw_unregister_debug_facility(); 3374 + out_err: 3375 + pr_err("Initializing the claw device driver failed\n"); 3408 3376 return ret; 3409 3377 } 3410 3378
+12
drivers/s390/net/claw.h
··· 129 129 } \ 130 130 } while (0) 131 131 132 + /** 133 + * Enum for classifying detected devices. 134 + */ 135 + enum claw_channel_types { 136 + /* Device is not a channel */ 137 + claw_channel_type_none, 138 + 139 + /* Device is a CLAW channel device */ 140 + claw_channel_type_claw 141 + }; 142 + 143 + 132 144 /******************************************************* 133 145 * Define Control Blocks * 134 146 * *
-1
drivers/s390/net/ctcm_fsms.c
··· 44 44 #include <asm/idals.h> 45 45 46 46 #include "fsm.h" 47 - #include "cu3088.h" 48 47 49 48 #include "ctcm_dbug.h" 50 49 #include "ctcm_main.h"
-1
drivers/s390/net/ctcm_fsms.h
··· 39 39 #include <asm/idals.h> 40 40 41 41 #include "fsm.h" 42 - #include "cu3088.h" 43 42 #include "ctcm_main.h" 44 43 45 44 /*
+84 -20
drivers/s390/net/ctcm_main.c
··· 51 51 52 52 #include <asm/idals.h> 53 53 54 - #include "cu3088.h" 55 54 #include "ctcm_fsms.h" 56 55 #include "ctcm_main.h" 57 56 58 57 /* Some common global variables */ 58 + 59 + /** 60 + * The root device for ctcm group devices 61 + */ 62 + static struct device *ctcm_root_dev; 59 63 60 64 /* 61 65 * Linked list of all detected channels. ··· 250 246 * 251 247 * returns Pointer to a channel or NULL if no matching channel available. 252 248 */ 253 - static struct channel *channel_get(enum channel_types type, 249 + static struct channel *channel_get(enum ctcm_channel_types type, 254 250 char *id, int direction) 255 251 { 256 252 struct channel *ch = channels; ··· 1346 1342 * 1347 1343 * returns 0 on success, !0 on error. 1348 1344 */ 1349 - static int add_channel(struct ccw_device *cdev, enum channel_types type, 1345 + static int add_channel(struct ccw_device *cdev, enum ctcm_channel_types type, 1350 1346 struct ctcm_priv *priv) 1351 1347 { 1352 1348 struct channel **c = &channels; ··· 1505 1501 /* 1506 1502 * Return type of a detected device. 1507 1503 */ 1508 - static enum channel_types get_channel_type(struct ccw_device_id *id) 1504 + static enum ctcm_channel_types get_channel_type(struct ccw_device_id *id) 1509 1505 { 1510 - enum channel_types type; 1511 - type = (enum channel_types)id->driver_info; 1506 + enum ctcm_channel_types type; 1507 + type = (enum ctcm_channel_types)id->driver_info; 1512 1508 1513 - if (type == channel_type_ficon) 1514 - type = channel_type_escon; 1509 + if (type == ctcm_channel_type_ficon) 1510 + type = ctcm_channel_type_escon; 1515 1511 1516 1512 return type; 1517 1513 } ··· 1529 1525 char read_id[CTCM_ID_SIZE]; 1530 1526 char write_id[CTCM_ID_SIZE]; 1531 1527 int direction; 1532 - enum channel_types type; 1528 + enum ctcm_channel_types type; 1533 1529 struct ctcm_priv *priv; 1534 1530 struct net_device *dev; 1535 1531 struct ccw_device *cdev0; ··· 1753 1749 return rc; 1754 1750 } 1755 1751 1752 + static struct ccw_device_id ctcm_ids[] = { 1753 + {CCW_DEVICE(0x3088, 0x08), .driver_info = ctcm_channel_type_parallel}, 1754 + {CCW_DEVICE(0x3088, 0x1e), .driver_info = ctcm_channel_type_ficon}, 1755 + {CCW_DEVICE(0x3088, 0x1f), .driver_info = ctcm_channel_type_escon}, 1756 + {}, 1757 + }; 1758 + MODULE_DEVICE_TABLE(ccw, ctcm_ids); 1759 + 1760 + static struct ccw_driver ctcm_ccw_driver = { 1761 + .owner = THIS_MODULE, 1762 + .name = "ctcm", 1763 + .ids = ctcm_ids, 1764 + .probe = ccwgroup_probe_ccwdev, 1765 + .remove = ccwgroup_remove_ccwdev, 1766 + }; 1767 + 1756 1768 static struct ccwgroup_driver ctcm_group_driver = { 1757 1769 .owner = THIS_MODULE, 1758 1770 .name = CTC_DRIVER_NAME, ··· 1783 1763 .restore = ctcm_pm_resume, 1784 1764 }; 1785 1765 1766 + static ssize_t 1767 + ctcm_driver_group_store(struct device_driver *ddrv, const char *buf, 1768 + size_t count) 1769 + { 1770 + int err; 1771 + 1772 + err = ccwgroup_create_from_string(ctcm_root_dev, 1773 + ctcm_group_driver.driver_id, 1774 + &ctcm_ccw_driver, 2, buf); 1775 + return err ? err : count; 1776 + } 1777 + 1778 + static DRIVER_ATTR(group, 0200, NULL, ctcm_driver_group_store); 1779 + 1780 + static struct attribute *ctcm_group_attrs[] = { 1781 + &driver_attr_group.attr, 1782 + NULL, 1783 + }; 1784 + 1785 + static struct attribute_group ctcm_group_attr_group = { 1786 + .attrs = ctcm_group_attrs, 1787 + }; 1788 + 1789 + static struct attribute_group *ctcm_group_attr_groups[] = { 1790 + &ctcm_group_attr_group, 1791 + NULL, 1792 + }; 1786 1793 1787 1794 /* 1788 1795 * Module related routines ··· 1823 1776 */ 1824 1777 static void __exit ctcm_exit(void) 1825 1778 { 1826 - unregister_cu3088_discipline(&ctcm_group_driver); 1779 + driver_remove_file(&ctcm_group_driver.driver, &driver_attr_group); 1780 + ccwgroup_driver_unregister(&ctcm_group_driver); 1781 + ccw_driver_unregister(&ctcm_ccw_driver); 1782 + root_device_unregister(ctcm_root_dev); 1827 1783 ctcm_unregister_dbf_views(); 1828 1784 pr_info("CTCM driver unloaded\n"); 1829 1785 } ··· 1852 1802 channels = NULL; 1853 1803 1854 1804 ret = ctcm_register_dbf_views(); 1855 - if (ret) { 1856 - return ret; 1857 - } 1858 - ret = register_cu3088_discipline(&ctcm_group_driver); 1859 - if (ret) { 1860 - ctcm_unregister_dbf_views(); 1861 - pr_err("%s / register_cu3088_discipline failed, ret = %d\n", 1862 - __func__, ret); 1863 - return ret; 1864 - } 1805 + if (ret) 1806 + goto out_err; 1807 + ctcm_root_dev = root_device_register("ctcm"); 1808 + ret = IS_ERR(ctcm_root_dev) ? PTR_ERR(ctcm_root_dev) : 0; 1809 + if (ret) 1810 + goto register_err; 1811 + ret = ccw_driver_register(&ctcm_ccw_driver); 1812 + if (ret) 1813 + goto ccw_err; 1814 + ctcm_group_driver.driver.groups = ctcm_group_attr_groups; 1815 + ret = ccwgroup_driver_register(&ctcm_group_driver); 1816 + if (ret) 1817 + goto ccwgroup_err; 1865 1818 print_banner(); 1819 + return 0; 1820 + 1821 + ccwgroup_err: 1822 + ccw_driver_unregister(&ctcm_ccw_driver); 1823 + ccw_err: 1824 + root_device_unregister(ctcm_root_dev); 1825 + register_err: 1826 + ctcm_unregister_dbf_views(); 1827 + out_err: 1828 + pr_err("%s / Initializing the ctcm device driver failed, ret = %d\n", 1829 + __func__, ret); 1866 1830 return ret; 1867 1831 } 1868 1832
+18 -2
drivers/s390/net/ctcm_main.h
··· 16 16 #include <linux/netdevice.h> 17 17 18 18 #include "fsm.h" 19 - #include "cu3088.h" 20 19 #include "ctcm_dbug.h" 21 20 #include "ctcm_mpc.h" 22 21 ··· 64 65 if (do_debug_ccw) \ 65 66 ctcmpc_dumpit(buf, len); \ 66 67 } while (0) 68 + 69 + /** 70 + * Enum for classifying detected devices 71 + */ 72 + enum ctcm_channel_types { 73 + /* Device is not a channel */ 74 + ctcm_channel_type_none, 75 + 76 + /* Device is a CTC/A */ 77 + ctcm_channel_type_parallel, 78 + 79 + /* Device is a FICON channel */ 80 + ctcm_channel_type_ficon, 81 + 82 + /* Device is a ESCON channel */ 83 + ctcm_channel_type_escon 84 + }; 67 85 68 86 /* 69 87 * CCW commands, used in this driver. ··· 137 121 * Type of this channel. 138 122 * CTC/A or Escon for valid channels. 139 123 */ 140 - enum channel_types type; 124 + enum ctcm_channel_types type; 141 125 /* 142 126 * Misc. flags. See CHANNEL_FLAGS_... below 143 127 */
-1
drivers/s390/net/ctcm_mpc.c
··· 53 53 #include <linux/moduleparam.h> 54 54 #include <asm/idals.h> 55 55 56 - #include "cu3088.h" 57 56 #include "ctcm_mpc.h" 58 57 #include "ctcm_main.h" 59 58 #include "ctcm_fsms.h"
+10 -1
drivers/s390/net/ctcm_sysfs.c
··· 158 158 return count; 159 159 } 160 160 161 + const char *ctcm_type[] = { 162 + "not a channel", 163 + "CTC/A", 164 + "FICON channel", 165 + "ESCON channel", 166 + "unknown channel type", 167 + "unsupported channel type", 168 + }; 169 + 161 170 static ssize_t ctcm_type_show(struct device *dev, 162 171 struct device_attribute *attr, char *buf) 163 172 { ··· 177 168 return -ENODEV; 178 169 179 170 return sprintf(buf, "%s\n", 180 - cu3088_type[cgdev->cdev[0]->id.driver_info]); 171 + ctcm_type[cgdev->cdev[0]->id.driver_info]); 181 172 } 182 173 183 174 static DEVICE_ATTR(buffer, 0644, ctcm_buffer_show, ctcm_buffer_write);
-148
drivers/s390/net/cu3088.c
··· 1 - /* 2 - * CTC / LCS ccw_device driver 3 - * 4 - * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 - * Author(s): Arnd Bergmann <arndb@de.ibm.com> 6 - * Cornelia Huck <cornelia.huck@de.ibm.com> 7 - * 8 - * This program is free software; you can redistribute it and/or modify 9 - * it under the terms of the GNU General Public License as published by 10 - * the Free Software Foundation; either version 2, or (at your option) 11 - * any later version. 12 - * 13 - * This program is distributed in the hope that it will be useful, 14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - * GNU General Public License for more details. 17 - * 18 - * You should have received a copy of the GNU General Public License 19 - * along with this program; if not, write to the Free Software 20 - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 - * 22 - */ 23 - 24 - #include <linux/init.h> 25 - #include <linux/module.h> 26 - #include <linux/err.h> 27 - 28 - #include <asm/ccwdev.h> 29 - #include <asm/ccwgroup.h> 30 - 31 - #include "cu3088.h" 32 - 33 - const char *cu3088_type[] = { 34 - "not a channel", 35 - "CTC/A", 36 - "ESCON channel", 37 - "FICON channel", 38 - "OSA LCS card", 39 - "CLAW channel device", 40 - "unknown channel type", 41 - "unsupported channel type", 42 - }; 43 - 44 - /* static definitions */ 45 - 46 - static struct ccw_device_id cu3088_ids[] = { 47 - { CCW_DEVICE(0x3088, 0x08), .driver_info = channel_type_parallel }, 48 - { CCW_DEVICE(0x3088, 0x1f), .driver_info = channel_type_escon }, 49 - { CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon }, 50 - { CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 }, 51 - { CCW_DEVICE(0x3088, 0x61), .driver_info = channel_type_claw }, 52 - { /* end of list */ } 53 - }; 54 - 55 - static struct ccw_driver cu3088_driver; 56 - 57 - static struct device *cu3088_root_dev; 58 - 59 - static ssize_t 60 - group_write(struct device_driver *drv, const char *buf, size_t count) 61 - { 62 - int ret; 63 - struct ccwgroup_driver *cdrv; 64 - 65 - cdrv = to_ccwgroupdrv(drv); 66 - if (!cdrv) 67 - return -EINVAL; 68 - ret = ccwgroup_create_from_string(cu3088_root_dev, cdrv->driver_id, 69 - &cu3088_driver, 2, buf); 70 - 71 - return (ret == 0) ? count : ret; 72 - } 73 - 74 - static DRIVER_ATTR(group, 0200, NULL, group_write); 75 - 76 - /* Register-unregister for ctc&lcs */ 77 - int 78 - register_cu3088_discipline(struct ccwgroup_driver *dcp) 79 - { 80 - int rc; 81 - 82 - if (!dcp) 83 - return -EINVAL; 84 - 85 - /* Register discipline.*/ 86 - rc = ccwgroup_driver_register(dcp); 87 - if (rc) 88 - return rc; 89 - 90 - rc = driver_create_file(&dcp->driver, &driver_attr_group); 91 - if (rc) 92 - ccwgroup_driver_unregister(dcp); 93 - 94 - return rc; 95 - 96 - } 97 - 98 - void 99 - unregister_cu3088_discipline(struct ccwgroup_driver *dcp) 100 - { 101 - if (!dcp) 102 - return; 103 - 104 - driver_remove_file(&dcp->driver, &driver_attr_group); 105 - ccwgroup_driver_unregister(dcp); 106 - } 107 - 108 - static struct ccw_driver cu3088_driver = { 109 - .owner = THIS_MODULE, 110 - .ids = cu3088_ids, 111 - .name = "cu3088", 112 - .probe = ccwgroup_probe_ccwdev, 113 - .remove = ccwgroup_remove_ccwdev, 114 - }; 115 - 116 - /* module setup */ 117 - static int __init 118 - cu3088_init (void) 119 - { 120 - int rc; 121 - 122 - cu3088_root_dev = root_device_register("cu3088"); 123 - if (IS_ERR(cu3088_root_dev)) 124 - return PTR_ERR(cu3088_root_dev); 125 - rc = ccw_driver_register(&cu3088_driver); 126 - if (rc) 127 - root_device_unregister(cu3088_root_dev); 128 - 129 - return rc; 130 - } 131 - 132 - static void __exit 133 - cu3088_exit (void) 134 - { 135 - ccw_driver_unregister(&cu3088_driver); 136 - root_device_unregister(cu3088_root_dev); 137 - } 138 - 139 - MODULE_DEVICE_TABLE(ccw,cu3088_ids); 140 - MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>"); 141 - MODULE_LICENSE("GPL"); 142 - 143 - module_init(cu3088_init); 144 - module_exit(cu3088_exit); 145 - 146 - EXPORT_SYMBOL_GPL(cu3088_type); 147 - EXPORT_SYMBOL_GPL(register_cu3088_discipline); 148 - EXPORT_SYMBOL_GPL(unregister_cu3088_discipline);
-41
drivers/s390/net/cu3088.h
··· 1 - #ifndef _CU3088_H 2 - #define _CU3088_H 3 - 4 - /** 5 - * Enum for classifying detected devices. 6 - */ 7 - enum channel_types { 8 - /* Device is not a channel */ 9 - channel_type_none, 10 - 11 - /* Device is a CTC/A */ 12 - channel_type_parallel, 13 - 14 - /* Device is a ESCON channel */ 15 - channel_type_escon, 16 - 17 - /* Device is a FICON channel */ 18 - channel_type_ficon, 19 - 20 - /* Device is a OSA2 card */ 21 - channel_type_osa2, 22 - 23 - /* Device is a CLAW channel device */ 24 - channel_type_claw, 25 - 26 - /* Device is a channel, but we don't know 27 - * anything about it */ 28 - channel_type_unknown, 29 - 30 - /* Device is an unsupported model */ 31 - channel_type_unsupported, 32 - 33 - /* number of type entries */ 34 - num_channel_types 35 - }; 36 - 37 - extern const char *cu3088_type[num_channel_types]; 38 - extern int register_cu3088_discipline(struct ccwgroup_driver *); 39 - extern void unregister_cu3088_discipline(struct ccwgroup_driver *); 40 - 41 - #endif
+87 -14
drivers/s390/net/lcs.c
··· 47 47 #include <asm/ccwgroup.h> 48 48 49 49 #include "lcs.h" 50 - #include "cu3088.h" 51 50 52 51 53 52 #if !defined(CONFIG_NET_ETHERNET) && \ ··· 59 60 */ 60 61 61 62 static char version[] __initdata = "LCS driver"; 62 - static char debug_buffer[255]; 63 + 64 + /** 65 + * the root device for lcs group devices 66 + */ 67 + static struct device *lcs_root_dev; 63 68 64 69 /** 65 70 * Some prototypes. ··· 79 76 /** 80 77 * Debug Facility Stuff 81 78 */ 79 + static char debug_buffer[255]; 82 80 static debug_info_t *lcs_dbf_setup; 83 81 static debug_info_t *lcs_dbf_trace; 84 82 ··· 1972 1968 1973 1969 static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store); 1974 1970 1971 + const char *lcs_type[] = { 1972 + "not a channel", 1973 + "2216 parallel", 1974 + "2216 channel", 1975 + "OSA LCS card", 1976 + "unknown channel type", 1977 + "unsupported channel type", 1978 + }; 1979 + 1975 1980 static ssize_t 1976 1981 lcs_type_show(struct device *dev, struct device_attribute *attr, char *buf) 1977 1982 { ··· 1990 1977 if (!cgdev) 1991 1978 return -ENODEV; 1992 1979 1993 - return sprintf(buf, "%s\n", cu3088_type[cgdev->cdev[0]->id.driver_info]); 1980 + return sprintf(buf, "%s\n", lcs_type[cgdev->cdev[0]->id.driver_info]); 1994 1981 } 1995 1982 1996 1983 static DEVICE_ATTR(type, 0444, lcs_type_show, NULL); ··· 2383 2370 return lcs_pm_resume(card); 2384 2371 } 2385 2372 2373 + static struct ccw_device_id lcs_ids[] = { 2374 + {CCW_DEVICE(0x3088, 0x08), .driver_info = lcs_channel_type_parallel}, 2375 + {CCW_DEVICE(0x3088, 0x1f), .driver_info = lcs_channel_type_2216}, 2376 + {CCW_DEVICE(0x3088, 0x60), .driver_info = lcs_channel_type_osa2}, 2377 + {}, 2378 + }; 2379 + MODULE_DEVICE_TABLE(ccw, lcs_ids); 2380 + 2381 + static struct ccw_driver lcs_ccw_driver = { 2382 + .owner = THIS_MODULE, 2383 + .name = "lcs", 2384 + .ids = lcs_ids, 2385 + .probe = ccwgroup_probe_ccwdev, 2386 + .remove = ccwgroup_remove_ccwdev, 2387 + }; 2388 + 2386 2389 /** 2387 2390 * LCS ccwgroup driver registration 2388 2391 */ ··· 2418 2389 .restore = lcs_restore, 2419 2390 }; 2420 2391 2392 + static ssize_t 2393 + lcs_driver_group_store(struct device_driver *ddrv, const char *buf, 2394 + size_t count) 2395 + { 2396 + int err; 2397 + err = ccwgroup_create_from_string(lcs_root_dev, 2398 + lcs_group_driver.driver_id, 2399 + &lcs_ccw_driver, 2, buf); 2400 + return err ? err : count; 2401 + } 2402 + 2403 + static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store); 2404 + 2405 + static struct attribute *lcs_group_attrs[] = { 2406 + &driver_attr_group.attr, 2407 + NULL, 2408 + }; 2409 + 2410 + static struct attribute_group lcs_group_attr_group = { 2411 + .attrs = lcs_group_attrs, 2412 + }; 2413 + 2414 + static struct attribute_group *lcs_group_attr_groups[] = { 2415 + &lcs_group_attr_group, 2416 + NULL, 2417 + }; 2418 + 2421 2419 /** 2422 2420 * LCS Module/Kernel initialization function 2423 2421 */ ··· 2456 2400 pr_info("Loading %s\n", version); 2457 2401 rc = lcs_register_debug_facility(); 2458 2402 LCS_DBF_TEXT(0, setup, "lcsinit"); 2459 - if (rc) { 2460 - pr_err("Initialization failed\n"); 2461 - return rc; 2462 - } 2463 - 2464 - rc = register_cu3088_discipline(&lcs_group_driver); 2465 - if (rc) { 2466 - pr_err("Initialization failed\n"); 2467 - return rc; 2468 - } 2403 + if (rc) 2404 + goto out_err; 2405 + lcs_root_dev = root_device_register("lcs"); 2406 + rc = IS_ERR(lcs_root_dev) ? PTR_ERR(lcs_root_dev) : 0; 2407 + if (rc) 2408 + goto register_err; 2409 + rc = ccw_driver_register(&lcs_ccw_driver); 2410 + if (rc) 2411 + goto ccw_err; 2412 + lcs_group_driver.driver.groups = lcs_group_attr_groups; 2413 + rc = ccwgroup_driver_register(&lcs_group_driver); 2414 + if (rc) 2415 + goto ccwgroup_err; 2469 2416 return 0; 2417 + 2418 + ccwgroup_err: 2419 + ccw_driver_unregister(&lcs_ccw_driver); 2420 + ccw_err: 2421 + root_device_unregister(lcs_root_dev); 2422 + register_err: 2423 + lcs_unregister_debug_facility(); 2424 + out_err: 2425 + pr_err("Initializing the lcs device driver failed\n"); 2426 + return rc; 2470 2427 } 2471 2428 2472 2429 ··· 2491 2422 { 2492 2423 pr_info("Terminating lcs module.\n"); 2493 2424 LCS_DBF_TEXT(0, trace, "cleanup"); 2494 - unregister_cu3088_discipline(&lcs_group_driver); 2425 + driver_remove_file(&lcs_group_driver.driver, 2426 + &driver_attr_group); 2427 + ccwgroup_driver_unregister(&lcs_group_driver); 2428 + ccw_driver_unregister(&lcs_ccw_driver); 2429 + root_device_unregister(lcs_root_dev); 2495 2430 lcs_unregister_debug_facility(); 2496 2431 } 2497 2432
+18
drivers/s390/net/lcs.h
··· 36 36 #define CARD_FROM_DEV(cdev) \ 37 37 (struct lcs_card *) dev_get_drvdata( \ 38 38 &((struct ccwgroup_device *)dev_get_drvdata(&cdev->dev))->dev); 39 + 40 + /** 41 + * Enum for classifying detected devices. 42 + */ 43 + enum lcs_channel_types { 44 + /* Device is not a channel */ 45 + lcs_channel_type_none, 46 + 47 + /* Device is a 2216 channel */ 48 + lcs_channel_type_parallel, 49 + 50 + /* Device is a 2216 channel */ 51 + lcs_channel_type_2216, 52 + 53 + /* Device is a OSA2 card */ 54 + lcs_channel_type_osa2 55 + }; 56 + 39 57 /** 40 58 * CCW commands used in this driver 41 59 */