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.c67
1 files changed, 33 insertions, 34 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index ac94ac751459..c47b25fd3f43 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * driver for channel subsystem 2 * driver for channel subsystem
3 * 3 *
4 * Copyright IBM Corp. 2002, 2009 4 * Copyright IBM Corp. 2002, 2010
5 * 5 *
6 * Author(s): Arnd Bergmann (arndb@de.ibm.com) 6 * Author(s): Arnd Bergmann (arndb@de.ibm.com)
7 * Cornelia Huck (cornelia.huck@de.ibm.com) 7 * Cornelia Huck (cornelia.huck@de.ibm.com)
@@ -35,6 +35,7 @@ int css_init_done = 0;
35int max_ssid; 35int max_ssid;
36 36
37struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1]; 37struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1];
38static struct bus_type css_bus_type;
38 39
39int 40int
40for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data) 41for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data)
@@ -577,7 +578,7 @@ static int __unset_registered(struct device *dev, void *data)
577 return 0; 578 return 0;
578} 579}
579 580
580void css_schedule_eval_all_unreg(void) 581static void css_schedule_eval_all_unreg(void)
581{ 582{
582 unsigned long flags; 583 unsigned long flags;
583 struct idset *unreg_set; 584 struct idset *unreg_set;
@@ -618,6 +619,7 @@ EXPORT_SYMBOL_GPL(css_schedule_reprobe);
618static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow) 619static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
619{ 620{
620 struct subchannel_id mchk_schid; 621 struct subchannel_id mchk_schid;
622 struct subchannel *sch;
621 623
622 if (overflow) { 624 if (overflow) {
623 css_schedule_eval_all(); 625 css_schedule_eval_all();
@@ -635,8 +637,15 @@ static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
635 init_subchannel_id(&mchk_schid); 637 init_subchannel_id(&mchk_schid);
636 mchk_schid.sch_no = crw0->rsid; 638 mchk_schid.sch_no = crw0->rsid;
637 if (crw1) 639 if (crw1)
638 mchk_schid.ssid = (crw1->rsid >> 8) & 3; 640 mchk_schid.ssid = (crw1->rsid >> 4) & 3;
639 641
642 if (crw0->erc == CRW_ERC_PMOD) {
643 sch = get_subchannel_by_schid(mchk_schid);
644 if (sch) {
645 css_update_ssd_info(sch);
646 put_device(&sch->dev);
647 }
648 }
640 /* 649 /*
641 * Since we are always presented with IPI in the CRW, we have to 650 * Since we are always presented with IPI in the CRW, we have to
642 * use stsch() to find out if the subchannel in question has come 651 * use stsch() to find out if the subchannel in question has come
@@ -790,7 +799,6 @@ static struct notifier_block css_reboot_notifier = {
790static int css_power_event(struct notifier_block *this, unsigned long event, 799static int css_power_event(struct notifier_block *this, unsigned long event,
791 void *ptr) 800 void *ptr)
792{ 801{
793 void *secm_area;
794 int ret, i; 802 int ret, i;
795 803
796 switch (event) { 804 switch (event) {
@@ -806,15 +814,8 @@ static int css_power_event(struct notifier_block *this, unsigned long event,
806 mutex_unlock(&css->mutex); 814 mutex_unlock(&css->mutex);
807 continue; 815 continue;
808 } 816 }
809 secm_area = (void *)get_zeroed_page(GFP_KERNEL | 817 if (__chsc_do_secm(css, 0))
810 GFP_DMA);
811 if (secm_area) {
812 if (__chsc_do_secm(css, 0, secm_area))
813 ret = NOTIFY_BAD;
814 free_page((unsigned long)secm_area);
815 } else
816 ret = NOTIFY_BAD; 818 ret = NOTIFY_BAD;
817
818 mutex_unlock(&css->mutex); 819 mutex_unlock(&css->mutex);
819 } 820 }
820 break; 821 break;
@@ -830,15 +831,8 @@ static int css_power_event(struct notifier_block *this, unsigned long event,
830 mutex_unlock(&css->mutex); 831 mutex_unlock(&css->mutex);
831 continue; 832 continue;
832 } 833 }
833 secm_area = (void *)get_zeroed_page(GFP_KERNEL | 834 if (__chsc_do_secm(css, 1))
834 GFP_DMA);
835 if (secm_area) {
836 if (__chsc_do_secm(css, 1, secm_area))
837 ret = NOTIFY_BAD;
838 free_page((unsigned long)secm_area);
839 } else
840 ret = NOTIFY_BAD; 835 ret = NOTIFY_BAD;
841
842 mutex_unlock(&css->mutex); 836 mutex_unlock(&css->mutex);
843 } 837 }
844 /* search for subchannels, which appeared during hibernation */ 838 /* search for subchannels, which appeared during hibernation */
@@ -863,14 +857,11 @@ static int __init css_bus_init(void)
863{ 857{
864 int ret, i; 858 int ret, i;
865 859
866 ret = chsc_determine_css_characteristics(); 860 ret = chsc_init();
867 if (ret == -ENOMEM)
868 goto out;
869
870 ret = chsc_alloc_sei_area();
871 if (ret) 861 if (ret)
872 goto out; 862 return ret;
873 863
864 chsc_determine_css_characteristics();
874 /* Try to enable MSS. */ 865 /* Try to enable MSS. */
875 ret = chsc_enable_facility(CHSC_SDA_OC_MSS); 866 ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
876 if (ret) 867 if (ret)
@@ -956,9 +947,9 @@ out_unregister:
956 } 947 }
957 bus_unregister(&css_bus_type); 948 bus_unregister(&css_bus_type);
958out: 949out:
959 crw_unregister_handler(CRW_RSC_CSS); 950 crw_unregister_handler(CRW_RSC_SCH);
960 chsc_free_sei_area();
961 idset_free(slow_subchannel_set); 951 idset_free(slow_subchannel_set);
952 chsc_init_cleanup();
962 pr_alert("The CSS device driver initialization failed with " 953 pr_alert("The CSS device driver initialization failed with "
963 "errno=%d\n", ret); 954 "errno=%d\n", ret);
964 return ret; 955 return ret;
@@ -978,9 +969,9 @@ static void __init css_bus_cleanup(void)
978 device_unregister(&css->device); 969 device_unregister(&css->device);
979 } 970 }
980 bus_unregister(&css_bus_type); 971 bus_unregister(&css_bus_type);
981 crw_unregister_handler(CRW_RSC_CSS); 972 crw_unregister_handler(CRW_RSC_SCH);
982 chsc_free_sei_area();
983 idset_free(slow_subchannel_set); 973 idset_free(slow_subchannel_set);
974 chsc_init_cleanup();
984 isc_unregister(IO_SCH_ISC); 975 isc_unregister(IO_SCH_ISC);
985} 976}
986 977
@@ -1048,7 +1039,16 @@ subsys_initcall_sync(channel_subsystem_init_sync);
1048 1039
1049void channel_subsystem_reinit(void) 1040void channel_subsystem_reinit(void)
1050{ 1041{
1042 struct channel_path *chp;
1043 struct chp_id chpid;
1044
1051 chsc_enable_facility(CHSC_SDA_OC_MSS); 1045 chsc_enable_facility(CHSC_SDA_OC_MSS);
1046 chp_id_for_each(&chpid) {
1047 chp = chpid_to_chp(chpid);
1048 if (!chp)
1049 continue;
1050 chsc_determine_base_channel_path_desc(chpid, &chp->desc);
1051 }
1052} 1052}
1053 1053
1054#ifdef CONFIG_PROC_FS 1054#ifdef CONFIG_PROC_FS
@@ -1067,6 +1067,7 @@ static ssize_t cio_settle_write(struct file *file, const char __user *buf,
1067static const struct file_operations cio_settle_proc_fops = { 1067static const struct file_operations cio_settle_proc_fops = {
1068 .open = nonseekable_open, 1068 .open = nonseekable_open,
1069 .write = cio_settle_write, 1069 .write = cio_settle_write,
1070 .llseek = no_llseek,
1070}; 1071};
1071 1072
1072static int __init cio_settle_init(void) 1073static int __init cio_settle_init(void)
@@ -1199,6 +1200,7 @@ static int css_pm_restore(struct device *dev)
1199 struct subchannel *sch = to_subchannel(dev); 1200 struct subchannel *sch = to_subchannel(dev);
1200 struct css_driver *drv; 1201 struct css_driver *drv;
1201 1202
1203 css_update_ssd_info(sch);
1202 if (!sch->dev.driver) 1204 if (!sch->dev.driver)
1203 return 0; 1205 return 0;
1204 drv = to_cssdriver(sch->dev.driver); 1206 drv = to_cssdriver(sch->dev.driver);
@@ -1213,7 +1215,7 @@ static const struct dev_pm_ops css_pm_ops = {
1213 .restore = css_pm_restore, 1215 .restore = css_pm_restore,
1214}; 1216};
1215 1217
1216struct bus_type css_bus_type = { 1218static struct bus_type css_bus_type = {
1217 .name = "css", 1219 .name = "css",
1218 .match = css_bus_match, 1220 .match = css_bus_match,
1219 .probe = css_probe, 1221 .probe = css_probe,
@@ -1232,9 +1234,7 @@ struct bus_type css_bus_type = {
1232 */ 1234 */
1233int css_driver_register(struct css_driver *cdrv) 1235int css_driver_register(struct css_driver *cdrv)
1234{ 1236{
1235 cdrv->drv.name = cdrv->name;
1236 cdrv->drv.bus = &css_bus_type; 1237 cdrv->drv.bus = &css_bus_type;
1237 cdrv->drv.owner = cdrv->owner;
1238 return driver_register(&cdrv->drv); 1238 return driver_register(&cdrv->drv);
1239} 1239}
1240EXPORT_SYMBOL_GPL(css_driver_register); 1240EXPORT_SYMBOL_GPL(css_driver_register);
@@ -1252,4 +1252,3 @@ void css_driver_unregister(struct css_driver *cdrv)
1252EXPORT_SYMBOL_GPL(css_driver_unregister); 1252EXPORT_SYMBOL_GPL(css_driver_unregister);
1253 1253
1254MODULE_LICENSE("GPL"); 1254MODULE_LICENSE("GPL");
1255EXPORT_SYMBOL(css_bus_type);