diff options
Diffstat (limited to 'drivers/s390/cio/chsc.c')
-rw-r--r-- | drivers/s390/cio/chsc.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index cfe0c087fe5c..4d51a7c4eb8b 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -52,6 +52,11 @@ int chsc_error_from_response(int response) | |||
52 | return -EINVAL; | 52 | return -EINVAL; |
53 | case 0x0004: | 53 | case 0x0004: |
54 | return -EOPNOTSUPP; | 54 | return -EOPNOTSUPP; |
55 | case 0x000b: | ||
56 | return -EBUSY; | ||
57 | case 0x0100: | ||
58 | case 0x0102: | ||
59 | return -ENOMEM; | ||
55 | default: | 60 | default: |
56 | return -EIO; | 61 | return -EIO; |
57 | } | 62 | } |
@@ -393,6 +398,20 @@ static void chsc_process_sei_chp_config(struct chsc_sei_area *sei_area) | |||
393 | } | 398 | } |
394 | } | 399 | } |
395 | 400 | ||
401 | static void chsc_process_sei_scm_change(struct chsc_sei_area *sei_area) | ||
402 | { | ||
403 | int ret; | ||
404 | |||
405 | CIO_CRW_EVENT(4, "chsc: scm change notification\n"); | ||
406 | if (sei_area->rs != 7) | ||
407 | return; | ||
408 | |||
409 | ret = scm_update_information(); | ||
410 | if (ret) | ||
411 | CIO_CRW_EVENT(0, "chsc: updating change notification" | ||
412 | " failed (rc=%d).\n", ret); | ||
413 | } | ||
414 | |||
396 | static void chsc_process_sei(struct chsc_sei_area *sei_area) | 415 | static void chsc_process_sei(struct chsc_sei_area *sei_area) |
397 | { | 416 | { |
398 | /* Check if we might have lost some information. */ | 417 | /* Check if we might have lost some information. */ |
@@ -414,6 +433,9 @@ static void chsc_process_sei(struct chsc_sei_area *sei_area) | |||
414 | case 8: /* channel-path-configuration notification */ | 433 | case 8: /* channel-path-configuration notification */ |
415 | chsc_process_sei_chp_config(sei_area); | 434 | chsc_process_sei_chp_config(sei_area); |
416 | break; | 435 | break; |
436 | case 12: /* scm change notification */ | ||
437 | chsc_process_sei_scm_change(sei_area); | ||
438 | break; | ||
417 | default: /* other stuff */ | 439 | default: /* other stuff */ |
418 | CIO_CRW_EVENT(4, "chsc: unhandled sei content code %d\n", | 440 | CIO_CRW_EVENT(4, "chsc: unhandled sei content code %d\n", |
419 | sei_area->cc); | 441 | sei_area->cc); |
@@ -1047,3 +1069,33 @@ out: | |||
1047 | return rc; | 1069 | return rc; |
1048 | } | 1070 | } |
1049 | EXPORT_SYMBOL_GPL(chsc_siosl); | 1071 | EXPORT_SYMBOL_GPL(chsc_siosl); |
1072 | |||
1073 | /** | ||
1074 | * chsc_scm_info() - store SCM information (SSI) | ||
1075 | * @scm_area: request and response block for SSI | ||
1076 | * @token: continuation token | ||
1077 | * | ||
1078 | * Returns 0 on success. | ||
1079 | */ | ||
1080 | int chsc_scm_info(struct chsc_scm_info *scm_area, u64 token) | ||
1081 | { | ||
1082 | int ccode, ret; | ||
1083 | |||
1084 | memset(scm_area, 0, sizeof(*scm_area)); | ||
1085 | scm_area->request.length = 0x0020; | ||
1086 | scm_area->request.code = 0x004C; | ||
1087 | scm_area->reqtok = token; | ||
1088 | |||
1089 | ccode = chsc(scm_area); | ||
1090 | if (ccode > 0) { | ||
1091 | ret = (ccode == 3) ? -ENODEV : -EBUSY; | ||
1092 | goto out; | ||
1093 | } | ||
1094 | ret = chsc_error_from_response(scm_area->response.code); | ||
1095 | if (ret != 0) | ||
1096 | CIO_MSG_EVENT(2, "chsc: scm info failed (rc=%04x)\n", | ||
1097 | scm_area->response.code); | ||
1098 | out: | ||
1099 | return ret; | ||
1100 | } | ||
1101 | EXPORT_SYMBOL_GPL(chsc_scm_info); | ||