diff options
Diffstat (limited to 'drivers/s390/net/lcs.c')
-rw-r--r-- | drivers/s390/net/lcs.c | 115 |
1 files changed, 97 insertions, 18 deletions
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index a70de9b4bf29..f6cc46dc0501 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <asm/ccwgroup.h> | 47 | #include <asm/ccwgroup.h> |
48 | 48 | ||
49 | #include "lcs.h" | 49 | #include "lcs.h" |
50 | #include "cu3088.h" | ||
51 | 50 | ||
52 | 51 | ||
53 | #if !defined(CONFIG_NET_ETHERNET) && \ | 52 | #if !defined(CONFIG_NET_ETHERNET) && \ |
@@ -60,7 +59,11 @@ | |||
60 | */ | 59 | */ |
61 | 60 | ||
62 | static char version[] __initdata = "LCS driver"; | 61 | static char version[] __initdata = "LCS driver"; |
63 | static char debug_buffer[255]; | 62 | |
63 | /** | ||
64 | * the root device for lcs group devices | ||
65 | */ | ||
66 | static struct device *lcs_root_dev; | ||
64 | 67 | ||
65 | /** | 68 | /** |
66 | * Some prototypes. | 69 | * Some prototypes. |
@@ -76,6 +79,7 @@ static int lcs_recovery(void *ptr); | |||
76 | /** | 79 | /** |
77 | * Debug Facility Stuff | 80 | * Debug Facility Stuff |
78 | */ | 81 | */ |
82 | static char debug_buffer[255]; | ||
79 | static debug_info_t *lcs_dbf_setup; | 83 | static debug_info_t *lcs_dbf_setup; |
80 | static debug_info_t *lcs_dbf_trace; | 84 | static debug_info_t *lcs_dbf_trace; |
81 | 85 | ||
@@ -889,7 +893,7 @@ lcs_send_lancmd(struct lcs_card *card, struct lcs_buffer *buffer, | |||
889 | rc = lcs_ready_buffer(&card->write, buffer); | 893 | rc = lcs_ready_buffer(&card->write, buffer); |
890 | if (rc) | 894 | if (rc) |
891 | return rc; | 895 | return rc; |
892 | init_timer(&timer); | 896 | init_timer_on_stack(&timer); |
893 | timer.function = lcs_lancmd_timeout; | 897 | timer.function = lcs_lancmd_timeout; |
894 | timer.data = (unsigned long) reply; | 898 | timer.data = (unsigned long) reply; |
895 | timer.expires = jiffies + HZ*card->lancmd_timeout; | 899 | timer.expires = jiffies + HZ*card->lancmd_timeout; |
@@ -1968,6 +1972,15 @@ lcs_portno_store (struct device *dev, struct device_attribute *attr, const char | |||
1968 | 1972 | ||
1969 | static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store); | 1973 | static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store); |
1970 | 1974 | ||
1975 | const char *lcs_type[] = { | ||
1976 | "not a channel", | ||
1977 | "2216 parallel", | ||
1978 | "2216 channel", | ||
1979 | "OSA LCS card", | ||
1980 | "unknown channel type", | ||
1981 | "unsupported channel type", | ||
1982 | }; | ||
1983 | |||
1971 | static ssize_t | 1984 | static ssize_t |
1972 | lcs_type_show(struct device *dev, struct device_attribute *attr, char *buf) | 1985 | lcs_type_show(struct device *dev, struct device_attribute *attr, char *buf) |
1973 | { | 1986 | { |
@@ -1977,7 +1990,7 @@ lcs_type_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
1977 | if (!cgdev) | 1990 | if (!cgdev) |
1978 | return -ENODEV; | 1991 | return -ENODEV; |
1979 | 1992 | ||
1980 | return sprintf(buf, "%s\n", cu3088_type[cgdev->cdev[0]->id.driver_info]); | 1993 | return sprintf(buf, "%s\n", lcs_type[cgdev->cdev[0]->id.driver_info]); |
1981 | } | 1994 | } |
1982 | 1995 | ||
1983 | static DEVICE_ATTR(type, 0444, lcs_type_show, NULL); | 1996 | static DEVICE_ATTR(type, 0444, lcs_type_show, NULL); |
@@ -2130,8 +2143,12 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) | |||
2130 | card->write.ccwdev = ccwgdev->cdev[1]; | 2143 | card->write.ccwdev = ccwgdev->cdev[1]; |
2131 | 2144 | ||
2132 | recover_state = card->state; | 2145 | recover_state = card->state; |
2133 | ccw_device_set_online(card->read.ccwdev); | 2146 | rc = ccw_device_set_online(card->read.ccwdev); |
2134 | ccw_device_set_online(card->write.ccwdev); | 2147 | if (rc) |
2148 | goto out_err; | ||
2149 | rc = ccw_device_set_online(card->write.ccwdev); | ||
2150 | if (rc) | ||
2151 | goto out_werr; | ||
2135 | 2152 | ||
2136 | LCS_DBF_TEXT(3, setup, "lcsnewdv"); | 2153 | LCS_DBF_TEXT(3, setup, "lcsnewdv"); |
2137 | 2154 | ||
@@ -2210,8 +2227,10 @@ netdev_out: | |||
2210 | return 0; | 2227 | return 0; |
2211 | out: | 2228 | out: |
2212 | 2229 | ||
2213 | ccw_device_set_offline(card->read.ccwdev); | ||
2214 | ccw_device_set_offline(card->write.ccwdev); | 2230 | ccw_device_set_offline(card->write.ccwdev); |
2231 | out_werr: | ||
2232 | ccw_device_set_offline(card->read.ccwdev); | ||
2233 | out_err: | ||
2215 | return -ENODEV; | 2234 | return -ENODEV; |
2216 | } | 2235 | } |
2217 | 2236 | ||
@@ -2364,6 +2383,22 @@ static int lcs_restore(struct ccwgroup_device *gdev) | |||
2364 | return lcs_pm_resume(card); | 2383 | return lcs_pm_resume(card); |
2365 | } | 2384 | } |
2366 | 2385 | ||
2386 | static struct ccw_device_id lcs_ids[] = { | ||
2387 | {CCW_DEVICE(0x3088, 0x08), .driver_info = lcs_channel_type_parallel}, | ||
2388 | {CCW_DEVICE(0x3088, 0x1f), .driver_info = lcs_channel_type_2216}, | ||
2389 | {CCW_DEVICE(0x3088, 0x60), .driver_info = lcs_channel_type_osa2}, | ||
2390 | {}, | ||
2391 | }; | ||
2392 | MODULE_DEVICE_TABLE(ccw, lcs_ids); | ||
2393 | |||
2394 | static struct ccw_driver lcs_ccw_driver = { | ||
2395 | .owner = THIS_MODULE, | ||
2396 | .name = "lcs", | ||
2397 | .ids = lcs_ids, | ||
2398 | .probe = ccwgroup_probe_ccwdev, | ||
2399 | .remove = ccwgroup_remove_ccwdev, | ||
2400 | }; | ||
2401 | |||
2367 | /** | 2402 | /** |
2368 | * LCS ccwgroup driver registration | 2403 | * LCS ccwgroup driver registration |
2369 | */ | 2404 | */ |
@@ -2383,6 +2418,33 @@ static struct ccwgroup_driver lcs_group_driver = { | |||
2383 | .restore = lcs_restore, | 2418 | .restore = lcs_restore, |
2384 | }; | 2419 | }; |
2385 | 2420 | ||
2421 | static ssize_t | ||
2422 | lcs_driver_group_store(struct device_driver *ddrv, const char *buf, | ||
2423 | size_t count) | ||
2424 | { | ||
2425 | int err; | ||
2426 | err = ccwgroup_create_from_string(lcs_root_dev, | ||
2427 | lcs_group_driver.driver_id, | ||
2428 | &lcs_ccw_driver, 2, buf); | ||
2429 | return err ? err : count; | ||
2430 | } | ||
2431 | |||
2432 | static DRIVER_ATTR(group, 0200, NULL, lcs_driver_group_store); | ||
2433 | |||
2434 | static struct attribute *lcs_group_attrs[] = { | ||
2435 | &driver_attr_group.attr, | ||
2436 | NULL, | ||
2437 | }; | ||
2438 | |||
2439 | static struct attribute_group lcs_group_attr_group = { | ||
2440 | .attrs = lcs_group_attrs, | ||
2441 | }; | ||
2442 | |||
2443 | static const struct attribute_group *lcs_group_attr_groups[] = { | ||
2444 | &lcs_group_attr_group, | ||
2445 | NULL, | ||
2446 | }; | ||
2447 | |||
2386 | /** | 2448 | /** |
2387 | * LCS Module/Kernel initialization function | 2449 | * LCS Module/Kernel initialization function |
2388 | */ | 2450 | */ |
@@ -2394,17 +2456,30 @@ __init lcs_init_module(void) | |||
2394 | pr_info("Loading %s\n", version); | 2456 | pr_info("Loading %s\n", version); |
2395 | rc = lcs_register_debug_facility(); | 2457 | rc = lcs_register_debug_facility(); |
2396 | LCS_DBF_TEXT(0, setup, "lcsinit"); | 2458 | LCS_DBF_TEXT(0, setup, "lcsinit"); |
2397 | if (rc) { | 2459 | if (rc) |
2398 | pr_err("Initialization failed\n"); | 2460 | goto out_err; |
2399 | return rc; | 2461 | lcs_root_dev = root_device_register("lcs"); |
2400 | } | 2462 | rc = IS_ERR(lcs_root_dev) ? PTR_ERR(lcs_root_dev) : 0; |
2401 | 2463 | if (rc) | |
2402 | rc = register_cu3088_discipline(&lcs_group_driver); | 2464 | goto register_err; |
2403 | if (rc) { | 2465 | rc = ccw_driver_register(&lcs_ccw_driver); |
2404 | pr_err("Initialization failed\n"); | 2466 | if (rc) |
2405 | return rc; | 2467 | goto ccw_err; |
2406 | } | 2468 | lcs_group_driver.driver.groups = lcs_group_attr_groups; |
2469 | rc = ccwgroup_driver_register(&lcs_group_driver); | ||
2470 | if (rc) | ||
2471 | goto ccwgroup_err; | ||
2407 | return 0; | 2472 | return 0; |
2473 | |||
2474 | ccwgroup_err: | ||
2475 | ccw_driver_unregister(&lcs_ccw_driver); | ||
2476 | ccw_err: | ||
2477 | root_device_unregister(lcs_root_dev); | ||
2478 | register_err: | ||
2479 | lcs_unregister_debug_facility(); | ||
2480 | out_err: | ||
2481 | pr_err("Initializing the lcs device driver failed\n"); | ||
2482 | return rc; | ||
2408 | } | 2483 | } |
2409 | 2484 | ||
2410 | 2485 | ||
@@ -2416,7 +2491,11 @@ __exit lcs_cleanup_module(void) | |||
2416 | { | 2491 | { |
2417 | pr_info("Terminating lcs module.\n"); | 2492 | pr_info("Terminating lcs module.\n"); |
2418 | LCS_DBF_TEXT(0, trace, "cleanup"); | 2493 | LCS_DBF_TEXT(0, trace, "cleanup"); |
2419 | unregister_cu3088_discipline(&lcs_group_driver); | 2494 | driver_remove_file(&lcs_group_driver.driver, |
2495 | &driver_attr_group); | ||
2496 | ccwgroup_driver_unregister(&lcs_group_driver); | ||
2497 | ccw_driver_unregister(&lcs_ccw_driver); | ||
2498 | root_device_unregister(lcs_root_dev); | ||
2420 | lcs_unregister_debug_facility(); | 2499 | lcs_unregister_debug_facility(); |
2421 | } | 2500 | } |
2422 | 2501 | ||