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.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 46c021d880dc..1261e1a9e8cd 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -477,7 +477,6 @@ void css_schedule_eval_all(void)
477 477
478void css_wait_for_slow_path(void) 478void css_wait_for_slow_path(void)
479{ 479{
480 flush_workqueue(ccw_device_notify_work);
481 flush_workqueue(slow_path_wq); 480 flush_workqueue(slow_path_wq);
482} 481}
483 482
@@ -634,6 +633,11 @@ channel_subsystem_release(struct device *dev)
634 633
635 css = to_css(dev); 634 css = to_css(dev);
636 mutex_destroy(&css->mutex); 635 mutex_destroy(&css->mutex);
636 if (css->pseudo_subchannel) {
637 /* Implies that it has been generated but never registered. */
638 css_subchannel_release(&css->pseudo_subchannel->dev);
639 css->pseudo_subchannel = NULL;
640 }
637 kfree(css); 641 kfree(css);
638} 642}
639 643
@@ -786,11 +790,15 @@ init_channel_subsystem (void)
786 } 790 }
787 channel_subsystems[i] = css; 791 channel_subsystems[i] = css;
788 ret = setup_css(i); 792 ret = setup_css(i);
789 if (ret) 793 if (ret) {
790 goto out_free; 794 kfree(channel_subsystems[i]);
795 goto out_unregister;
796 }
791 ret = device_register(&css->device); 797 ret = device_register(&css->device);
792 if (ret) 798 if (ret) {
793 goto out_free_all; 799 put_device(&css->device);
800 goto out_unregister;
801 }
794 if (css_chsc_characteristics.secm) { 802 if (css_chsc_characteristics.secm) {
795 ret = device_create_file(&css->device, 803 ret = device_create_file(&css->device,
796 &dev_attr_cm_enable); 804 &dev_attr_cm_enable);
@@ -803,7 +811,7 @@ init_channel_subsystem (void)
803 } 811 }
804 ret = register_reboot_notifier(&css_reboot_notifier); 812 ret = register_reboot_notifier(&css_reboot_notifier);
805 if (ret) 813 if (ret)
806 goto out_pseudo; 814 goto out_unregister;
807 css_init_done = 1; 815 css_init_done = 1;
808 816
809 /* Enable default isc for I/O subchannels. */ 817 /* Enable default isc for I/O subchannels. */
@@ -811,18 +819,12 @@ init_channel_subsystem (void)
811 819
812 for_each_subchannel(__init_channel_subsystem, NULL); 820 for_each_subchannel(__init_channel_subsystem, NULL);
813 return 0; 821 return 0;
814out_pseudo:
815 device_unregister(&channel_subsystems[i]->pseudo_subchannel->dev);
816out_file: 822out_file:
817 device_remove_file(&channel_subsystems[i]->device, 823 if (css_chsc_characteristics.secm)
818 &dev_attr_cm_enable); 824 device_remove_file(&channel_subsystems[i]->device,
825 &dev_attr_cm_enable);
819out_device: 826out_device:
820 device_unregister(&channel_subsystems[i]->device); 827 device_unregister(&channel_subsystems[i]->device);
821out_free_all:
822 kfree(channel_subsystems[i]->pseudo_subchannel->lock);
823 kfree(channel_subsystems[i]->pseudo_subchannel);
824out_free:
825 kfree(channel_subsystems[i]);
826out_unregister: 828out_unregister:
827 while (i > 0) { 829 while (i > 0) {
828 struct channel_subsystem *css; 830 struct channel_subsystem *css;
@@ -830,6 +832,7 @@ out_unregister:
830 i--; 832 i--;
831 css = channel_subsystems[i]; 833 css = channel_subsystems[i];
832 device_unregister(&css->pseudo_subchannel->dev); 834 device_unregister(&css->pseudo_subchannel->dev);
835 css->pseudo_subchannel = NULL;
833 if (css_chsc_characteristics.secm) 836 if (css_chsc_characteristics.secm)
834 device_remove_file(&css->device, 837 device_remove_file(&css->device,
835 &dev_attr_cm_enable); 838 &dev_attr_cm_enable);