aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/css.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/css.c')
-rw-r--r--drivers/s390/cio/css.c252
1 files changed, 128 insertions, 124 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 393c73c47f87..91c25706fa83 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -31,8 +31,7 @@
31#include "chp.h" 31#include "chp.h"
32 32
33int css_init_done = 0; 33int css_init_done = 0;
34static int need_reprobe = 0; 34int max_ssid;
35static int max_ssid = 0;
36 35
37struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1]; 36struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1];
38 37
@@ -315,12 +314,18 @@ int css_probe_device(struct subchannel_id schid)
315 int ret; 314 int ret;
316 struct subchannel *sch; 315 struct subchannel *sch;
317 316
318 sch = css_alloc_subchannel(schid); 317 if (cio_is_console(schid))
319 if (IS_ERR(sch)) 318 sch = cio_get_console_subchannel();
320 return PTR_ERR(sch); 319 else {
320 sch = css_alloc_subchannel(schid);
321 if (IS_ERR(sch))
322 return PTR_ERR(sch);
323 }
321 ret = css_register_subchannel(sch); 324 ret = css_register_subchannel(sch);
322 if (ret) 325 if (ret) {
323 put_device(&sch->dev); 326 if (!cio_is_console(schid))
327 put_device(&sch->dev);
328 }
324 return ret; 329 return ret;
325} 330}
326 331
@@ -409,10 +414,14 @@ static void css_evaluate_subchannel(struct subchannel_id schid, int slow)
409 414
410static struct idset *slow_subchannel_set; 415static struct idset *slow_subchannel_set;
411static spinlock_t slow_subchannel_lock; 416static spinlock_t slow_subchannel_lock;
417static wait_queue_head_t css_eval_wq;
418static atomic_t css_eval_scheduled;
412 419
413static int __init slow_subchannel_init(void) 420static int __init slow_subchannel_init(void)
414{ 421{
415 spin_lock_init(&slow_subchannel_lock); 422 spin_lock_init(&slow_subchannel_lock);
423 atomic_set(&css_eval_scheduled, 0);
424 init_waitqueue_head(&css_eval_wq);
416 slow_subchannel_set = idset_sch_new(); 425 slow_subchannel_set = idset_sch_new();
417 if (!slow_subchannel_set) { 426 if (!slow_subchannel_set) {
418 CIO_MSG_EVENT(0, "could not allocate slow subchannel set\n"); 427 CIO_MSG_EVENT(0, "could not allocate slow subchannel set\n");
@@ -468,9 +477,17 @@ static int slow_eval_unknown_fn(struct subchannel_id schid, void *data)
468 477
469static void css_slow_path_func(struct work_struct *unused) 478static void css_slow_path_func(struct work_struct *unused)
470{ 479{
480 unsigned long flags;
481
471 CIO_TRACE_EVENT(4, "slowpath"); 482 CIO_TRACE_EVENT(4, "slowpath");
472 for_each_subchannel_staged(slow_eval_known_fn, slow_eval_unknown_fn, 483 for_each_subchannel_staged(slow_eval_known_fn, slow_eval_unknown_fn,
473 NULL); 484 NULL);
485 spin_lock_irqsave(&slow_subchannel_lock, flags);
486 if (idset_is_empty(slow_subchannel_set)) {
487 atomic_set(&css_eval_scheduled, 0);
488 wake_up(&css_eval_wq);
489 }
490 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
474} 491}
475 492
476static DECLARE_WORK(slow_path_work, css_slow_path_func); 493static DECLARE_WORK(slow_path_work, css_slow_path_func);
@@ -482,6 +499,7 @@ void css_schedule_eval(struct subchannel_id schid)
482 499
483 spin_lock_irqsave(&slow_subchannel_lock, flags); 500 spin_lock_irqsave(&slow_subchannel_lock, flags);
484 idset_sch_add(slow_subchannel_set, schid); 501 idset_sch_add(slow_subchannel_set, schid);
502 atomic_set(&css_eval_scheduled, 1);
485 queue_work(slow_path_wq, &slow_path_work); 503 queue_work(slow_path_wq, &slow_path_work);
486 spin_unlock_irqrestore(&slow_subchannel_lock, flags); 504 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
487} 505}
@@ -492,80 +510,53 @@ void css_schedule_eval_all(void)
492 510
493 spin_lock_irqsave(&slow_subchannel_lock, flags); 511 spin_lock_irqsave(&slow_subchannel_lock, flags);
494 idset_fill(slow_subchannel_set); 512 idset_fill(slow_subchannel_set);
513 atomic_set(&css_eval_scheduled, 1);
495 queue_work(slow_path_wq, &slow_path_work); 514 queue_work(slow_path_wq, &slow_path_work);
496 spin_unlock_irqrestore(&slow_subchannel_lock, flags); 515 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
497} 516}
498 517
499void css_wait_for_slow_path(void) 518static int __unset_registered(struct device *dev, void *data)
500{ 519{
501 flush_workqueue(slow_path_wq); 520 struct idset *set = data;
502} 521 struct subchannel *sch = to_subchannel(dev);
503
504/* Reprobe subchannel if unregistered. */
505static int reprobe_subchannel(struct subchannel_id schid, void *data)
506{
507 int ret;
508
509 CIO_MSG_EVENT(6, "cio: reprobe 0.%x.%04x\n",
510 schid.ssid, schid.sch_no);
511 if (need_reprobe)
512 return -EAGAIN;
513
514 ret = css_probe_device(schid);
515 switch (ret) {
516 case 0:
517 break;
518 case -ENXIO:
519 case -ENOMEM:
520 case -EIO:
521 /* These should abort looping */
522 break;
523 default:
524 ret = 0;
525 }
526
527 return ret;
528}
529 522
530static void reprobe_after_idle(struct work_struct *unused) 523 idset_sch_del(set, sch->schid);
531{ 524 return 0;
532 /* Make sure initial subchannel scan is done. */
533 wait_event(ccw_device_init_wq,
534 atomic_read(&ccw_device_init_count) == 0);
535 if (need_reprobe)
536 css_schedule_reprobe();
537} 525}
538 526
539static DECLARE_WORK(reprobe_idle_work, reprobe_after_idle); 527void css_schedule_eval_all_unreg(void)
540
541/* Work function used to reprobe all unregistered subchannels. */
542static void reprobe_all(struct work_struct *unused)
543{ 528{
544 int ret; 529 unsigned long flags;
545 530 struct idset *unreg_set;
546 CIO_MSG_EVENT(4, "reprobe start\n");
547 531
548 /* Make sure initial subchannel scan is done. */ 532 /* Find unregistered subchannels. */
549 if (atomic_read(&ccw_device_init_count) != 0) { 533 unreg_set = idset_sch_new();
550 queue_work(ccw_device_work, &reprobe_idle_work); 534 if (!unreg_set) {
535 /* Fallback. */
536 css_schedule_eval_all();
551 return; 537 return;
552 } 538 }
553 need_reprobe = 0; 539 idset_fill(unreg_set);
554 ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL); 540 bus_for_each_dev(&css_bus_type, NULL, unreg_set, __unset_registered);
555 541 /* Apply to slow_subchannel_set. */
556 CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, 542 spin_lock_irqsave(&slow_subchannel_lock, flags);
557 need_reprobe); 543 idset_add_set(slow_subchannel_set, unreg_set);
544 atomic_set(&css_eval_scheduled, 1);
545 queue_work(slow_path_wq, &slow_path_work);
546 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
547 idset_free(unreg_set);
558} 548}
559 549
560static DECLARE_WORK(css_reprobe_work, reprobe_all); 550void css_wait_for_slow_path(void)
551{
552 flush_workqueue(slow_path_wq);
553}
561 554
562/* Schedule reprobing of all unregistered subchannels. */ 555/* Schedule reprobing of all unregistered subchannels. */
563void css_schedule_reprobe(void) 556void css_schedule_reprobe(void)
564{ 557{
565 need_reprobe = 1; 558 css_schedule_eval_all_unreg();
566 queue_work(slow_path_wq, &css_reprobe_work);
567} 559}
568
569EXPORT_SYMBOL_GPL(css_schedule_reprobe); 560EXPORT_SYMBOL_GPL(css_schedule_reprobe);
570 561
571/* 562/*
@@ -601,49 +592,6 @@ static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
601 css_evaluate_subchannel(mchk_schid, 0); 592 css_evaluate_subchannel(mchk_schid, 0);
602} 593}
603 594
604static int __init
605__init_channel_subsystem(struct subchannel_id schid, void *data)
606{
607 struct subchannel *sch;
608 int ret;
609
610 if (cio_is_console(schid))
611 sch = cio_get_console_subchannel();
612 else {
613 sch = css_alloc_subchannel(schid);
614 if (IS_ERR(sch))
615 ret = PTR_ERR(sch);
616 else
617 ret = 0;
618 switch (ret) {
619 case 0:
620 break;
621 case -ENOMEM:
622 panic("Out of memory in init_channel_subsystem\n");
623 /* -ENXIO: no more subchannels. */
624 case -ENXIO:
625 return ret;
626 /* -EIO: this subchannel set not supported. */
627 case -EIO:
628 return ret;
629 default:
630 return 0;
631 }
632 }
633 /*
634 * We register ALL valid subchannels in ioinfo, even those
635 * that have been present before init_channel_subsystem.
636 * These subchannels can't have been registered yet (kmalloc
637 * not working) so we do it now. This is true e.g. for the
638 * console subchannel.
639 */
640 if (css_register_subchannel(sch)) {
641 if (!cio_is_console(schid))
642 put_device(&sch->dev);
643 }
644 return 0;
645}
646
647static void __init 595static void __init
648css_generate_pgid(struct channel_subsystem *css, u32 tod_high) 596css_generate_pgid(struct channel_subsystem *css, u32 tod_high)
649{ 597{
@@ -854,19 +802,30 @@ static struct notifier_block css_power_notifier = {
854 * The struct subchannel's are created during probing (except for the 802 * The struct subchannel's are created during probing (except for the
855 * static console subchannel). 803 * static console subchannel).
856 */ 804 */
857static int __init 805static int __init css_bus_init(void)
858init_channel_subsystem (void)
859{ 806{
860 int ret, i; 807 int ret, i;
861 808
862 ret = chsc_determine_css_characteristics(); 809 ret = chsc_determine_css_characteristics();
863 if (ret == -ENOMEM) 810 if (ret == -ENOMEM)
864 goto out; /* No need to continue. */ 811 goto out;
865 812
866 ret = chsc_alloc_sei_area(); 813 ret = chsc_alloc_sei_area();
867 if (ret) 814 if (ret)
868 goto out; 815 goto out;
869 816
817 /* Try to enable MSS. */
818 ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
819 switch (ret) {
820 case 0: /* Success. */
821 max_ssid = __MAX_SSID;
822 break;
823 case -ENOMEM:
824 goto out;
825 default:
826 max_ssid = 0;
827 }
828
870 ret = slow_subchannel_init(); 829 ret = slow_subchannel_init();
871 if (ret) 830 if (ret)
872 goto out; 831 goto out;
@@ -878,17 +837,6 @@ init_channel_subsystem (void)
878 if ((ret = bus_register(&css_bus_type))) 837 if ((ret = bus_register(&css_bus_type)))
879 goto out; 838 goto out;
880 839
881 /* Try to enable MSS. */
882 ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
883 switch (ret) {
884 case 0: /* Success. */
885 max_ssid = __MAX_SSID;
886 break;
887 case -ENOMEM:
888 goto out_bus;
889 default:
890 max_ssid = 0;
891 }
892 /* Setup css structure. */ 840 /* Setup css structure. */
893 for (i = 0; i <= __MAX_CSSID; i++) { 841 for (i = 0; i <= __MAX_CSSID; i++) {
894 struct channel_subsystem *css; 842 struct channel_subsystem *css;
@@ -934,7 +882,6 @@ init_channel_subsystem (void)
934 /* Enable default isc for I/O subchannels. */ 882 /* Enable default isc for I/O subchannels. */
935 isc_register(IO_SCH_ISC); 883 isc_register(IO_SCH_ISC);
936 884
937 for_each_subchannel(__init_channel_subsystem, NULL);
938 return 0; 885 return 0;
939out_file: 886out_file:
940 if (css_chsc_characteristics.secm) 887 if (css_chsc_characteristics.secm)
@@ -955,17 +902,76 @@ out_unregister:
955 &dev_attr_cm_enable); 902 &dev_attr_cm_enable);
956 device_unregister(&css->device); 903 device_unregister(&css->device);
957 } 904 }
958out_bus:
959 bus_unregister(&css_bus_type); 905 bus_unregister(&css_bus_type);
960out: 906out:
961 crw_unregister_handler(CRW_RSC_CSS); 907 crw_unregister_handler(CRW_RSC_CSS);
962 chsc_free_sei_area(); 908 chsc_free_sei_area();
963 kfree(slow_subchannel_set); 909 idset_free(slow_subchannel_set);
964 pr_alert("The CSS device driver initialization failed with " 910 pr_alert("The CSS device driver initialization failed with "
965 "errno=%d\n", ret); 911 "errno=%d\n", ret);
966 return ret; 912 return ret;
967} 913}
968 914
915static void __init css_bus_cleanup(void)
916{
917 struct channel_subsystem *css;
918 int i;
919
920 for (i = 0; i <= __MAX_CSSID; i++) {
921 css = channel_subsystems[i];
922 device_unregister(&css->pseudo_subchannel->dev);
923 css->pseudo_subchannel = NULL;
924 if (css_chsc_characteristics.secm)
925 device_remove_file(&css->device, &dev_attr_cm_enable);
926 device_unregister(&css->device);
927 }
928 bus_unregister(&css_bus_type);
929 crw_unregister_handler(CRW_RSC_CSS);
930 chsc_free_sei_area();
931 idset_free(slow_subchannel_set);
932 isc_unregister(IO_SCH_ISC);
933}
934
935static int __init channel_subsystem_init(void)
936{
937 int ret;
938
939 ret = css_bus_init();
940 if (ret)
941 return ret;
942
943 ret = io_subchannel_init();
944 if (ret)
945 css_bus_cleanup();
946
947 return ret;
948}
949subsys_initcall(channel_subsystem_init);
950
951static int css_settle(struct device_driver *drv, void *unused)
952{
953 struct css_driver *cssdrv = to_cssdriver(drv);
954
955 if (cssdrv->settle)
956 cssdrv->settle();
957 return 0;
958}
959
960/*
961 * Wait for the initialization of devices to finish, to make sure we are
962 * done with our setup if the search for the root device starts.
963 */
964static int __init channel_subsystem_init_sync(void)
965{
966 /* Start initial subchannel evaluation. */
967 css_schedule_eval_all();
968 /* Wait for the evaluation of subchannels to finish. */
969 wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0);
970 /* Wait for the subchannel type specific initialization to finish */
971 return bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
972}
973subsys_initcall_sync(channel_subsystem_init_sync);
974
969int sch_is_pseudo_sch(struct subchannel *sch) 975int sch_is_pseudo_sch(struct subchannel *sch)
970{ 976{
971 return sch == to_css(sch->dev.parent)->pseudo_subchannel; 977 return sch == to_css(sch->dev.parent)->pseudo_subchannel;
@@ -1135,7 +1141,5 @@ void css_driver_unregister(struct css_driver *cdrv)
1135} 1141}
1136EXPORT_SYMBOL_GPL(css_driver_unregister); 1142EXPORT_SYMBOL_GPL(css_driver_unregister);
1137 1143
1138subsys_initcall(init_channel_subsystem);
1139
1140MODULE_LICENSE("GPL"); 1144MODULE_LICENSE("GPL");
1141EXPORT_SYMBOL(css_bus_type); 1145EXPORT_SYMBOL(css_bus_type);