summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2014-04-15 20:08:01 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-13 13:59:42 +0200
commit506841af86605c1d44df1d45ab271c69dcf46b70 (patch)
treeecec708caabd122171807638fa89b7be1549c9b7
parentb2b708cf2f9c51bf5a75845eb0b2f2390707957c (diff)
s390/chsc: fix SEI usage on old FW levels
commit 06cd7a874ec6e09d151aeb1fa8600e14f1ff89f6 upstream. Using a notification type mask for the store event information chsc is unsupported on some firmware levels. Retry SEI with that mask set to zero (which is the old way of requesting only channel subsystem related events). Reported-and-tested-by: Stefan Haberland <stefan.haberland@de.ibm.com> Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/s390/cio/chsc.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 8ea7d9b2c671..815e290a1afb 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -500,18 +500,27 @@ static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area)
static void chsc_process_event_information(struct chsc_sei *sei, u64 ntsm)
{
- do {
+ static int ntsm_unsupported;
+
+ while (true) {
memset(sei, 0, sizeof(*sei));
sei->request.length = 0x0010;
sei->request.code = 0x000e;
- sei->ntsm = ntsm;
+ if (!ntsm_unsupported)
+ sei->ntsm = ntsm;
if (chsc(sei))
break;
if (sei->response.code != 0x0001) {
- CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n",
- sei->response.code);
+ CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x, ntsm=%llx)\n",
+ sei->response.code, sei->ntsm);
+
+ if (sei->response.code == 3 && sei->ntsm) {
+ /* Fallback for old firmware. */
+ ntsm_unsupported = 1;
+ continue;
+ }
break;
}
@@ -527,7 +536,10 @@ static void chsc_process_event_information(struct chsc_sei *sei, u64 ntsm)
CIO_CRW_EVENT(2, "chsc: unhandled nt: %d\n", sei->nt);
break;
}
- } while (sei->u.nt0_area.flags & 0x80);
+
+ if (!(sei->u.nt0_area.flags & 0x80))
+ break;
+ }
}
/*