diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2010-04-22 11:17:05 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-04-22 11:17:19 -0400 |
commit | 8821d24cd261aede9b0436cd3252b17a60ccc33a (patch) | |
tree | 66762388019bf846ea5205d9c9fd95ba364952a3 | |
parent | 889ee9556c89a877b8343b6bbe6ac8dc5d57e433 (diff) |
[S390] cio: use exception-save stsch
Using stsch on schids with ssid != 0 can lead to an operand
exception. Use stsch_err to handle potential exceptions
if we fail to reenable mss after hibernation.
Cc: <stable@kernel.org>
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | drivers/s390/cio/chsc_sch.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 18 | ||||
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 2 |
3 files changed, 11 insertions, 11 deletions
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 404f630c27ca..3b6f4adc5094 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c | |||
@@ -124,7 +124,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch) | |||
124 | * since we don't have a way to clear the subchannel and | 124 | * since we don't have a way to clear the subchannel and |
125 | * cannot disable it with a request running. | 125 | * cannot disable it with a request running. |
126 | */ | 126 | */ |
127 | cc = stsch(sch->schid, &schib); | 127 | cc = stsch_err(sch->schid, &schib); |
128 | if (!cc && scsw_stctl(&schib.scsw)) | 128 | if (!cc && scsw_stctl(&schib.scsw)) |
129 | return -EAGAIN; | 129 | return -EAGAIN; |
130 | return 0; | 130 | return 0; |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index f736cdcf08ad..5feea1a371e1 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -361,7 +361,7 @@ int cio_commit_config(struct subchannel *sch) | |||
361 | struct schib schib; | 361 | struct schib schib; |
362 | int ccode, retry, ret = 0; | 362 | int ccode, retry, ret = 0; |
363 | 363 | ||
364 | if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib)) | 364 | if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) |
365 | return -ENODEV; | 365 | return -ENODEV; |
366 | 366 | ||
367 | for (retry = 0; retry < 5; retry++) { | 367 | for (retry = 0; retry < 5; retry++) { |
@@ -372,7 +372,7 @@ int cio_commit_config(struct subchannel *sch) | |||
372 | return ccode; | 372 | return ccode; |
373 | switch (ccode) { | 373 | switch (ccode) { |
374 | case 0: /* successful */ | 374 | case 0: /* successful */ |
375 | if (stsch(sch->schid, &schib) || | 375 | if (stsch_err(sch->schid, &schib) || |
376 | !css_sch_is_valid(&schib)) | 376 | !css_sch_is_valid(&schib)) |
377 | return -ENODEV; | 377 | return -ENODEV; |
378 | if (cio_check_config(sch, &schib)) { | 378 | if (cio_check_config(sch, &schib)) { |
@@ -404,7 +404,7 @@ int cio_update_schib(struct subchannel *sch) | |||
404 | { | 404 | { |
405 | struct schib schib; | 405 | struct schib schib; |
406 | 406 | ||
407 | if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib)) | 407 | if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) |
408 | return -ENODEV; | 408 | return -ENODEV; |
409 | 409 | ||
410 | memcpy(&sch->schib, &schib, sizeof(schib)); | 410 | memcpy(&sch->schib, &schib, sizeof(schib)); |
@@ -771,7 +771,7 @@ cio_get_console_sch_no(void) | |||
771 | if (console_irq != -1) { | 771 | if (console_irq != -1) { |
772 | /* VM provided us with the irq number of the console. */ | 772 | /* VM provided us with the irq number of the console. */ |
773 | schid.sch_no = console_irq; | 773 | schid.sch_no = console_irq; |
774 | if (stsch(schid, &console_subchannel.schib) != 0 || | 774 | if (stsch_err(schid, &console_subchannel.schib) != 0 || |
775 | (console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) || | 775 | (console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) || |
776 | !console_subchannel.schib.pmcw.dnv) | 776 | !console_subchannel.schib.pmcw.dnv) |
777 | return -1; | 777 | return -1; |
@@ -863,10 +863,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib) | |||
863 | cc = 0; | 863 | cc = 0; |
864 | for (retry=0;retry<3;retry++) { | 864 | for (retry=0;retry<3;retry++) { |
865 | schib->pmcw.ena = 0; | 865 | schib->pmcw.ena = 0; |
866 | cc = msch(schid, schib); | 866 | cc = msch_err(schid, schib); |
867 | if (cc) | 867 | if (cc) |
868 | return (cc==3?-ENODEV:-EBUSY); | 868 | return (cc==3?-ENODEV:-EBUSY); |
869 | if (stsch(schid, schib) || !css_sch_is_valid(schib)) | 869 | if (stsch_err(schid, schib) || !css_sch_is_valid(schib)) |
870 | return -ENODEV; | 870 | return -ENODEV; |
871 | if (!schib->pmcw.ena) | 871 | if (!schib->pmcw.ena) |
872 | return 0; | 872 | return 0; |
@@ -913,7 +913,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr) | |||
913 | 913 | ||
914 | pgm_check_occured = 0; | 914 | pgm_check_occured = 0; |
915 | s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; | 915 | s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; |
916 | rc = stsch(schid, addr); | 916 | rc = stsch_err(schid, addr); |
917 | s390_base_pgm_handler_fn = NULL; | 917 | s390_base_pgm_handler_fn = NULL; |
918 | 918 | ||
919 | /* The program check handler could have changed pgm_check_occured. */ | 919 | /* The program check handler could have changed pgm_check_occured. */ |
@@ -950,7 +950,7 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data) | |||
950 | /* No default clear strategy */ | 950 | /* No default clear strategy */ |
951 | break; | 951 | break; |
952 | } | 952 | } |
953 | stsch(schid, &schib); | 953 | stsch_err(schid, &schib); |
954 | __disable_subchannel_easy(schid, &schib); | 954 | __disable_subchannel_easy(schid, &schib); |
955 | } | 955 | } |
956 | out: | 956 | out: |
@@ -1086,7 +1086,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo) | |||
1086 | schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id; | 1086 | schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id; |
1087 | if (!schid.one) | 1087 | if (!schid.one) |
1088 | return -ENODEV; | 1088 | return -ENODEV; |
1089 | if (stsch(schid, &schib)) | 1089 | if (stsch_err(schid, &schib)) |
1090 | return -ENODEV; | 1090 | return -ENODEV; |
1091 | if (schib.pmcw.st != SUBCHANNEL_TYPE_IO) | 1091 | if (schib.pmcw.st != SUBCHANNEL_TYPE_IO) |
1092 | return -ENODEV; | 1092 | return -ENODEV; |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index c56ab94612f9..c9b852647f01 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -45,7 +45,7 @@ static void ccw_timeout_log(struct ccw_device *cdev) | |||
45 | sch = to_subchannel(cdev->dev.parent); | 45 | sch = to_subchannel(cdev->dev.parent); |
46 | private = to_io_private(sch); | 46 | private = to_io_private(sch); |
47 | orb = &private->orb; | 47 | orb = &private->orb; |
48 | cc = stsch(sch->schid, &schib); | 48 | cc = stsch_err(sch->schid, &schib); |
49 | 49 | ||
50 | printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " | 50 | printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " |
51 | "device information:\n", get_clock()); | 51 | "device information:\n", get_clock()); |