aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/cio/chsc.c147
1 files changed, 55 insertions, 92 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index e7ba16a74ef7..007aaeb4f532 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -26,6 +26,25 @@
26 26
27static void *sei_page; 27static void *sei_page;
28 28
29static int chsc_error_from_response(int response)
30{
31 switch (response) {
32 case 0x0001:
33 return 0;
34 case 0x0002:
35 case 0x0003:
36 case 0x0006:
37 case 0x0007:
38 case 0x0008:
39 case 0x000a:
40 return -EINVAL;
41 case 0x0004:
42 return -EOPNOTSUPP;
43 default:
44 return -EIO;
45 }
46}
47
29struct chsc_ssd_area { 48struct chsc_ssd_area {
30 struct chsc_header request; 49 struct chsc_header request;
31 u16 :10; 50 u16 :10;
@@ -75,11 +94,11 @@ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd)
75 ret = (ccode == 3) ? -ENODEV : -EBUSY; 94 ret = (ccode == 3) ? -ENODEV : -EBUSY;
76 goto out_free; 95 goto out_free;
77 } 96 }
78 if (ssd_area->response.code != 0x0001) { 97 ret = chsc_error_from_response(ssd_area->response.code);
98 if (ret != 0) {
79 CIO_MSG_EVENT(2, "chsc: ssd failed for 0.%x.%04x (rc=%04x)\n", 99 CIO_MSG_EVENT(2, "chsc: ssd failed for 0.%x.%04x (rc=%04x)\n",
80 schid.ssid, schid.sch_no, 100 schid.ssid, schid.sch_no,
81 ssd_area->response.code); 101 ssd_area->response.code);
82 ret = -EIO;
83 goto out_free; 102 goto out_free;
84 } 103 }
85 if (!ssd_area->sch_valid) { 104 if (!ssd_area->sch_valid) {
@@ -717,36 +736,15 @@ __chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
717 return (ccode == 3) ? -ENODEV : -EBUSY; 736 return (ccode == 3) ? -ENODEV : -EBUSY;
718 737
719 switch (secm_area->response.code) { 738 switch (secm_area->response.code) {
720 case 0x0001: /* Success. */ 739 case 0x0102:
721 ret = 0; 740 case 0x0103:
722 break;
723 case 0x0003: /* Invalid block. */
724 case 0x0007: /* Invalid format. */
725 case 0x0008: /* Other invalid block. */
726 CIO_CRW_EVENT(2, "Error in chsc request block!\n");
727 ret = -EINVAL;
728 break;
729 case 0x0004: /* Command not provided in model. */
730 CIO_CRW_EVENT(2, "Model does not provide secm\n");
731 ret = -EOPNOTSUPP;
732 break;
733 case 0x0102: /* cub adresses incorrect */
734 CIO_CRW_EVENT(2, "Invalid addresses in chsc request block\n");
735 ret = -EINVAL;
736 break;
737 case 0x0103: /* key error */
738 CIO_CRW_EVENT(2, "Access key error in secm\n");
739 ret = -EINVAL; 741 ret = -EINVAL;
740 break;
741 case 0x0105: /* error while starting */
742 CIO_CRW_EVENT(2, "Error while starting channel measurement\n");
743 ret = -EIO;
744 break;
745 default: 742 default:
746 CIO_CRW_EVENT(2, "Unknown CHSC response %d\n", 743 ret = chsc_error_from_response(secm_area->response.code);
747 secm_area->response.code);
748 ret = -EIO;
749 } 744 }
745 if (ret != 0)
746 CIO_CRW_EVENT(2, "chsc: secm failed (rc=%04x)\n",
747 secm_area->response.code);
750 return ret; 748 return ret;
751} 749}
752 750
@@ -827,27 +825,14 @@ int chsc_determine_channel_path_description(struct chp_id chpid,
827 goto out; 825 goto out;
828 } 826 }
829 827
830 switch (scpd_area->response.code) { 828 ret = chsc_error_from_response(scpd_area->response.code);
831 case 0x0001: /* Success. */ 829 if (ret == 0)
830 /* Success. */
832 memcpy(desc, &scpd_area->desc, 831 memcpy(desc, &scpd_area->desc,
833 sizeof(struct channel_path_desc)); 832 sizeof(struct channel_path_desc));
834 ret = 0; 833 else
835 break; 834 CIO_CRW_EVENT(2, "chsc: scpd failed (rc=%04x)\n",
836 case 0x0003: /* Invalid block. */
837 case 0x0007: /* Invalid format. */
838 case 0x0008: /* Other invalid block. */
839 CIO_CRW_EVENT(2, "Error in chsc request block!\n");
840 ret = -EINVAL;
841 break;
842 case 0x0004: /* Command not provided in model. */
843 CIO_CRW_EVENT(2, "Model does not provide scpd\n");
844 ret = -EOPNOTSUPP;
845 break;
846 default:
847 CIO_CRW_EVENT(2, "Unknown CHSC response %d\n",
848 scpd_area->response.code); 835 scpd_area->response.code);
849 ret = -EIO;
850 }
851out: 836out:
852 free_page((unsigned long)scpd_area); 837 free_page((unsigned long)scpd_area);
853 return ret; 838 return ret;
@@ -923,8 +908,9 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
923 goto out; 908 goto out;
924 } 909 }
925 910
926 switch (scmc_area->response.code) { 911 ret = chsc_error_from_response(scmc_area->response.code);
927 case 0x0001: /* Success. */ 912 if (ret == 0) {
913 /* Success. */
928 if (!scmc_area->not_valid) { 914 if (!scmc_area->not_valid) {
929 chp->cmg = scmc_area->cmg; 915 chp->cmg = scmc_area->cmg;
930 chp->shared = scmc_area->shared; 916 chp->shared = scmc_area->shared;
@@ -935,22 +921,9 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
935 chp->cmg = -1; 921 chp->cmg = -1;
936 chp->shared = -1; 922 chp->shared = -1;
937 } 923 }
938 ret = 0; 924 } else {
939 break; 925 CIO_CRW_EVENT(2, "chsc: scmc failed (rc=%04x)\n",
940 case 0x0003: /* Invalid block. */
941 case 0x0007: /* Invalid format. */
942 case 0x0008: /* Invalid bit combination. */
943 CIO_CRW_EVENT(2, "Error in chsc request block!\n");
944 ret = -EINVAL;
945 break;
946 case 0x0004: /* Command not provided. */
947 CIO_CRW_EVENT(2, "Model does not provide scmc\n");
948 ret = -EOPNOTSUPP;
949 break;
950 default:
951 CIO_CRW_EVENT(2, "Unknown CHSC response %d\n",
952 scmc_area->response.code); 926 scmc_area->response.code);
953 ret = -EIO;
954 } 927 }
955out: 928out:
956 free_page((unsigned long)scmc_area); 929 free_page((unsigned long)scmc_area);
@@ -1002,21 +975,17 @@ chsc_enable_facility(int operation_code)
1002 ret = (ret == 3) ? -ENODEV : -EBUSY; 975 ret = (ret == 3) ? -ENODEV : -EBUSY;
1003 goto out; 976 goto out;
1004 } 977 }
978
1005 switch (sda_area->response.code) { 979 switch (sda_area->response.code) {
1006 case 0x0001: /* everything ok */ 980 case 0x0101:
1007 ret = 0;
1008 break;
1009 case 0x0003: /* invalid request block */
1010 case 0x0007:
1011 ret = -EINVAL;
1012 break;
1013 case 0x0004: /* command not provided */
1014 case 0x0101: /* facility not provided */
1015 ret = -EOPNOTSUPP; 981 ret = -EOPNOTSUPP;
1016 break; 982 break;
1017 default: /* something went wrong */ 983 default:
1018 ret = -EIO; 984 ret = chsc_error_from_response(sda_area->response.code);
1019 } 985 }
986 if (ret != 0)
987 CIO_CRW_EVENT(2, "chsc: sda (oc=%x) failed (rc=%04x)\n",
988 operation_code, sda_area->response.code);
1020 out: 989 out:
1021 free_page((unsigned long)sda_area); 990 free_page((unsigned long)sda_area);
1022 return ret; 991 return ret;
@@ -1041,33 +1010,27 @@ chsc_determine_css_characteristics(void)
1041 } __attribute__ ((packed)) *scsc_area; 1010 } __attribute__ ((packed)) *scsc_area;
1042 1011
1043 scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 1012 scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
1044 if (!scsc_area) { 1013 if (!scsc_area)
1045 CIO_MSG_EVENT(0, "Was not able to determine available "
1046 "CHSCs due to no memory.\n");
1047 return -ENOMEM; 1014 return -ENOMEM;
1048 }
1049 1015
1050 scsc_area->request.length = 0x0010; 1016 scsc_area->request.length = 0x0010;
1051 scsc_area->request.code = 0x0010; 1017 scsc_area->request.code = 0x0010;
1052 1018
1053 result = chsc(scsc_area); 1019 result = chsc(scsc_area);
1054 if (result) { 1020 if (result) {
1055 CIO_MSG_EVENT(0, "Was not able to determine available CHSCs, " 1021 result = (result == 3) ? -ENODEV : -EBUSY;
1056 "cc=%i.\n", result);
1057 result = -EIO;
1058 goto exit; 1022 goto exit;
1059 } 1023 }
1060 1024
1061 if (scsc_area->response.code != 1) { 1025 result = chsc_error_from_response(scsc_area->response.code);
1062 CIO_MSG_EVENT(0, "Was not able to determine " 1026 if (result == 0) {
1063 "available CHSCs.\n"); 1027 memcpy(&css_general_characteristics, scsc_area->general_char,
1064 result = -EIO; 1028 sizeof(css_general_characteristics));
1065 goto exit; 1029 memcpy(&css_chsc_characteristics, scsc_area->chsc_char,
1066 } 1030 sizeof(css_chsc_characteristics));
1067 memcpy(&css_general_characteristics, scsc_area->general_char, 1031 } else
1068 sizeof(css_general_characteristics)); 1032 CIO_CRW_EVENT(2, "chsc: scsc failed (rc=%04x)\n",
1069 memcpy(&css_chsc_characteristics, scsc_area->chsc_char, 1033 scsc_area->response.code);
1070 sizeof(css_chsc_characteristics));
1071exit: 1034exit:
1072 free_page ((unsigned long) scsc_area); 1035 free_page ((unsigned long) scsc_area);
1073 return result; 1036 return result;