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.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 65939e2eb415..0bf716619378 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -580,12 +580,24 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr,
580 580
581static DEVICE_ATTR(cm_enable, 0644, css_cm_enable_show, css_cm_enable_store); 581static DEVICE_ATTR(cm_enable, 0644, css_cm_enable_show, css_cm_enable_store);
582 582
583static inline void __init 583static inline int __init setup_css(int nr)
584setup_css(int nr)
585{ 584{
586 u32 tod_high; 585 u32 tod_high;
586 int ret;
587 587
588 memset(css[nr], 0, sizeof(struct channel_subsystem)); 588 memset(css[nr], 0, sizeof(struct channel_subsystem));
589 css[nr]->pseudo_subchannel =
590 kzalloc(sizeof(*css[nr]->pseudo_subchannel), GFP_KERNEL);
591 if (!css[nr]->pseudo_subchannel)
592 return -ENOMEM;
593 css[nr]->pseudo_subchannel->dev.parent = &css[nr]->device;
594 css[nr]->pseudo_subchannel->dev.release = css_subchannel_release;
595 sprintf(css[nr]->pseudo_subchannel->dev.bus_id, "defunct");
596 ret = cio_create_sch_lock(css[nr]->pseudo_subchannel);
597 if (ret) {
598 kfree(css[nr]->pseudo_subchannel);
599 return ret;
600 }
589 mutex_init(&css[nr]->mutex); 601 mutex_init(&css[nr]->mutex);
590 css[nr]->valid = 1; 602 css[nr]->valid = 1;
591 css[nr]->cssid = nr; 603 css[nr]->cssid = nr;
@@ -593,6 +605,7 @@ setup_css(int nr)
593 css[nr]->device.release = channel_subsystem_release; 605 css[nr]->device.release = channel_subsystem_release;
594 tod_high = (u32) (get_clock() >> 32); 606 tod_high = (u32) (get_clock() >> 32);
595 css_generate_pgid(css[nr], tod_high); 607 css_generate_pgid(css[nr], tod_high);
608 return 0;
596} 609}
597 610
598/* 611/*
@@ -629,10 +642,12 @@ init_channel_subsystem (void)
629 ret = -ENOMEM; 642 ret = -ENOMEM;
630 goto out_unregister; 643 goto out_unregister;
631 } 644 }
632 setup_css(i); 645 ret = setup_css(i);
633 ret = device_register(&css[i]->device);
634 if (ret) 646 if (ret)
635 goto out_free; 647 goto out_free;
648 ret = device_register(&css[i]->device);
649 if (ret)
650 goto out_free_all;
636 if (css_characteristics_avail && 651 if (css_characteristics_avail &&
637 css_chsc_characteristics.secm) { 652 css_chsc_characteristics.secm) {
638 ret = device_create_file(&css[i]->device, 653 ret = device_create_file(&css[i]->device,
@@ -640,6 +655,9 @@ init_channel_subsystem (void)
640 if (ret) 655 if (ret)
641 goto out_device; 656 goto out_device;
642 } 657 }
658 ret = device_register(&css[i]->pseudo_subchannel->dev);
659 if (ret)
660 goto out_file;
643 } 661 }
644 css_init_done = 1; 662 css_init_done = 1;
645 663
@@ -647,13 +665,19 @@ init_channel_subsystem (void)
647 665
648 for_each_subchannel(__init_channel_subsystem, NULL); 666 for_each_subchannel(__init_channel_subsystem, NULL);
649 return 0; 667 return 0;
668out_file:
669 device_remove_file(&css[i]->device, &dev_attr_cm_enable);
650out_device: 670out_device:
651 device_unregister(&css[i]->device); 671 device_unregister(&css[i]->device);
672out_free_all:
673 kfree(css[i]->pseudo_subchannel->lock);
674 kfree(css[i]->pseudo_subchannel);
652out_free: 675out_free:
653 kfree(css[i]); 676 kfree(css[i]);
654out_unregister: 677out_unregister:
655 while (i > 0) { 678 while (i > 0) {
656 i--; 679 i--;
680 device_unregister(&css[i]->pseudo_subchannel->dev);
657 if (css_characteristics_avail && css_chsc_characteristics.secm) 681 if (css_characteristics_avail && css_chsc_characteristics.secm)
658 device_remove_file(&css[i]->device, 682 device_remove_file(&css[i]->device,
659 &dev_attr_cm_enable); 683 &dev_attr_cm_enable);
@@ -665,6 +689,11 @@ out:
665 return ret; 689 return ret;
666} 690}
667 691
692int sch_is_pseudo_sch(struct subchannel *sch)
693{
694 return sch == to_css(sch->dev.parent)->pseudo_subchannel;
695}
696
668/* 697/*
669 * find a driver for a subchannel. They identify by the subchannel 698 * find a driver for a subchannel. They identify by the subchannel
670 * type with the exception that the console subchannel driver has its own 699 * type with the exception that the console subchannel driver has its own