diff options
author | Eric Rossman <edrossma@us.ibm.com> | 2006-01-06 03:19:25 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-06 11:33:52 -0500 |
commit | 88fbf18399bde8f2900cf932acd40733dfa1effa (patch) | |
tree | 9b34bf8325e465fbf84df25028f0fd6a11971b5b /drivers | |
parent | fb6958a594da49ece869793e6ec163b89fc5f79f (diff) |
[PATCH] s390: add support for cex2a crypto cards
Signed-off-by: Eric Rossman <edrossma@us.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/crypto/z90common.h | 9 | ||||
-rw-r--r-- | drivers/s390/crypto/z90crypt.h | 13 | ||||
-rw-r--r-- | drivers/s390/crypto/z90hardware.c | 301 | ||||
-rw-r--r-- | drivers/s390/crypto/z90main.c | 111 |
4 files changed, 383 insertions, 51 deletions
diff --git a/drivers/s390/crypto/z90common.h b/drivers/s390/crypto/z90common.h index e319e78b5ea2..f87c785f2039 100644 --- a/drivers/s390/crypto/z90common.h +++ b/drivers/s390/crypto/z90common.h | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/s390/crypto/z90common.h | 2 | * linux/drivers/s390/crypto/z90common.h |
3 | * | 3 | * |
4 | * z90crypt 1.3.2 | 4 | * z90crypt 1.3.3 |
5 | * | 5 | * |
6 | * Copyright (C) 2001, 2004 IBM Corporation | 6 | * Copyright (C) 2001, 2005 IBM Corporation |
7 | * Author(s): Robert Burroughs (burrough@us.ibm.com) | 7 | * Author(s): Robert Burroughs (burrough@us.ibm.com) |
8 | * Eric Rossman (edrossma@us.ibm.com) | 8 | * Eric Rossman (edrossma@us.ibm.com) |
9 | * | 9 | * |
@@ -91,12 +91,13 @@ enum hdstat { | |||
91 | #define TSQ_FATAL_ERROR 34 | 91 | #define TSQ_FATAL_ERROR 34 |
92 | #define RSQ_FATAL_ERROR 35 | 92 | #define RSQ_FATAL_ERROR 35 |
93 | 93 | ||
94 | #define Z90CRYPT_NUM_TYPES 5 | 94 | #define Z90CRYPT_NUM_TYPES 6 |
95 | #define PCICA 0 | 95 | #define PCICA 0 |
96 | #define PCICC 1 | 96 | #define PCICC 1 |
97 | #define PCIXCC_MCL2 2 | 97 | #define PCIXCC_MCL2 2 |
98 | #define PCIXCC_MCL3 3 | 98 | #define PCIXCC_MCL3 3 |
99 | #define CEX2C 4 | 99 | #define CEX2C 4 |
100 | #define CEX2A 5 | ||
100 | #define NILDEV -1 | 101 | #define NILDEV -1 |
101 | #define ANYDEV -1 | 102 | #define ANYDEV -1 |
102 | #define PCIXCC_UNK -2 | 103 | #define PCIXCC_UNK -2 |
@@ -105,7 +106,7 @@ enum hdevice_type { | |||
105 | PCICC_HW = 3, | 106 | PCICC_HW = 3, |
106 | PCICA_HW = 4, | 107 | PCICA_HW = 4, |
107 | PCIXCC_HW = 5, | 108 | PCIXCC_HW = 5, |
108 | OTHER_HW = 6, | 109 | CEX2A_HW = 6, |
109 | CEX2C_HW = 7 | 110 | CEX2C_HW = 7 |
110 | }; | 111 | }; |
111 | 112 | ||
diff --git a/drivers/s390/crypto/z90crypt.h b/drivers/s390/crypto/z90crypt.h index 0a3bb5a10dd4..3a18443fdfa7 100644 --- a/drivers/s390/crypto/z90crypt.h +++ b/drivers/s390/crypto/z90crypt.h | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/s390/crypto/z90crypt.h | 2 | * linux/drivers/s390/crypto/z90crypt.h |
3 | * | 3 | * |
4 | * z90crypt 1.3.2 | 4 | * z90crypt 1.3.3 |
5 | * | 5 | * |
6 | * Copyright (C) 2001, 2004 IBM Corporation | 6 | * Copyright (C) 2001, 2005 IBM Corporation |
7 | * Author(s): Robert Burroughs (burrough@us.ibm.com) | 7 | * Author(s): Robert Burroughs (burrough@us.ibm.com) |
8 | * Eric Rossman (edrossma@us.ibm.com) | 8 | * Eric Rossman (edrossma@us.ibm.com) |
9 | * | 9 | * |
@@ -29,11 +29,11 @@ | |||
29 | 29 | ||
30 | #include <linux/ioctl.h> | 30 | #include <linux/ioctl.h> |
31 | 31 | ||
32 | #define VERSION_Z90CRYPT_H "$Revision: 1.11 $" | 32 | #define VERSION_Z90CRYPT_H "$Revision: 1.2.2.4 $" |
33 | 33 | ||
34 | #define z90crypt_VERSION 1 | 34 | #define z90crypt_VERSION 1 |
35 | #define z90crypt_RELEASE 3 // 2 = PCIXCC, 3 = rewrite for coding standards | 35 | #define z90crypt_RELEASE 3 // 2 = PCIXCC, 3 = rewrite for coding standards |
36 | #define z90crypt_VARIANT 2 // 2 = added PCIXCC MCL3 and CEX2C support | 36 | #define z90crypt_VARIANT 3 // 3 = CEX2A support |
37 | 37 | ||
38 | /** | 38 | /** |
39 | * struct ica_rsa_modexpo | 39 | * struct ica_rsa_modexpo |
@@ -122,6 +122,9 @@ struct ica_rsa_modexpo_crt { | |||
122 | * Z90STAT_CEX2CCOUNT | 122 | * Z90STAT_CEX2CCOUNT |
123 | * Return an integer count of all CEX2Cs. | 123 | * Return an integer count of all CEX2Cs. |
124 | * | 124 | * |
125 | * Z90STAT_CEX2ACOUNT | ||
126 | * Return an integer count of all CEX2As. | ||
127 | * | ||
125 | * Z90STAT_REQUESTQ_COUNT | 128 | * Z90STAT_REQUESTQ_COUNT |
126 | * Return an integer count of the number of entries waiting to be | 129 | * Return an integer count of the number of entries waiting to be |
127 | * sent to a device. | 130 | * sent to a device. |
@@ -144,6 +147,7 @@ struct ica_rsa_modexpo_crt { | |||
144 | * 0x03: PCIXCC_MCL2 | 147 | * 0x03: PCIXCC_MCL2 |
145 | * 0x04: PCIXCC_MCL3 | 148 | * 0x04: PCIXCC_MCL3 |
146 | * 0x05: CEX2C | 149 | * 0x05: CEX2C |
150 | * 0x06: CEX2A | ||
147 | * 0x0d: device is disabled via the proc filesystem | 151 | * 0x0d: device is disabled via the proc filesystem |
148 | * | 152 | * |
149 | * Z90STAT_QDEPTH_MASK | 153 | * Z90STAT_QDEPTH_MASK |
@@ -199,6 +203,7 @@ struct ica_rsa_modexpo_crt { | |||
199 | #define Z90STAT_PCIXCCMCL2COUNT _IOR(Z90_IOCTL_MAGIC, 0x4b, int) | 203 | #define Z90STAT_PCIXCCMCL2COUNT _IOR(Z90_IOCTL_MAGIC, 0x4b, int) |
200 | #define Z90STAT_PCIXCCMCL3COUNT _IOR(Z90_IOCTL_MAGIC, 0x4c, int) | 204 | #define Z90STAT_PCIXCCMCL3COUNT _IOR(Z90_IOCTL_MAGIC, 0x4c, int) |
201 | #define Z90STAT_CEX2CCOUNT _IOR(Z90_IOCTL_MAGIC, 0x4d, int) | 205 | #define Z90STAT_CEX2CCOUNT _IOR(Z90_IOCTL_MAGIC, 0x4d, int) |
206 | #define Z90STAT_CEX2ACOUNT _IOR(Z90_IOCTL_MAGIC, 0x4e, int) | ||
202 | #define Z90STAT_REQUESTQ_COUNT _IOR(Z90_IOCTL_MAGIC, 0x44, int) | 207 | #define Z90STAT_REQUESTQ_COUNT _IOR(Z90_IOCTL_MAGIC, 0x44, int) |
203 | #define Z90STAT_PENDINGQ_COUNT _IOR(Z90_IOCTL_MAGIC, 0x45, int) | 208 | #define Z90STAT_PENDINGQ_COUNT _IOR(Z90_IOCTL_MAGIC, 0x45, int) |
204 | #define Z90STAT_TOTALOPEN_COUNT _IOR(Z90_IOCTL_MAGIC, 0x46, int) | 209 | #define Z90STAT_TOTALOPEN_COUNT _IOR(Z90_IOCTL_MAGIC, 0x46, int) |
diff --git a/drivers/s390/crypto/z90hardware.c b/drivers/s390/crypto/z90hardware.c index c215e0889736..7c3ed52e03e1 100644 --- a/drivers/s390/crypto/z90hardware.c +++ b/drivers/s390/crypto/z90hardware.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/s390/crypto/z90hardware.c | 2 | * linux/drivers/s390/crypto/z90hardware.c |
3 | * | 3 | * |
4 | * z90crypt 1.3.2 | 4 | * z90crypt 1.3.3 |
5 | * | 5 | * |
6 | * Copyright (C) 2001, 2004 IBM Corporation | 6 | * Copyright (C) 2001, 2005 IBM Corporation |
7 | * Author(s): Robert Burroughs (burrough@us.ibm.com) | 7 | * Author(s): Robert Burroughs (burrough@us.ibm.com) |
8 | * Eric Rossman (edrossma@us.ibm.com) | 8 | * Eric Rossman (edrossma@us.ibm.com) |
9 | * | 9 | * |
@@ -648,6 +648,87 @@ static struct cca_public_sec static_cca_pub_sec = { | |||
648 | #define RESPONSE_CPRB_SIZE 0x000006B8 | 648 | #define RESPONSE_CPRB_SIZE 0x000006B8 |
649 | #define RESPONSE_CPRBX_SIZE 0x00000724 | 649 | #define RESPONSE_CPRBX_SIZE 0x00000724 |
650 | 650 | ||
651 | struct type50_hdr { | ||
652 | u8 reserved1; | ||
653 | u8 msg_type_code; | ||
654 | u16 msg_len; | ||
655 | u8 reserved2; | ||
656 | u8 ignored; | ||
657 | u16 reserved3; | ||
658 | }; | ||
659 | |||
660 | #define TYPE50_TYPE_CODE 0x50 | ||
661 | |||
662 | #define TYPE50_MEB1_LEN (sizeof(struct type50_meb1_msg)) | ||
663 | #define TYPE50_MEB2_LEN (sizeof(struct type50_meb2_msg)) | ||
664 | #define TYPE50_CRB1_LEN (sizeof(struct type50_crb1_msg)) | ||
665 | #define TYPE50_CRB2_LEN (sizeof(struct type50_crb2_msg)) | ||
666 | |||
667 | #define TYPE50_MEB1_FMT 0x0001 | ||
668 | #define TYPE50_MEB2_FMT 0x0002 | ||
669 | #define TYPE50_CRB1_FMT 0x0011 | ||
670 | #define TYPE50_CRB2_FMT 0x0012 | ||
671 | |||
672 | struct type50_meb1_msg { | ||
673 | struct type50_hdr header; | ||
674 | u16 keyblock_type; | ||
675 | u8 reserved[6]; | ||
676 | u8 exponent[128]; | ||
677 | u8 modulus[128]; | ||
678 | u8 message[128]; | ||
679 | }; | ||
680 | |||
681 | struct type50_meb2_msg { | ||
682 | struct type50_hdr header; | ||
683 | u16 keyblock_type; | ||
684 | u8 reserved[6]; | ||
685 | u8 exponent[256]; | ||
686 | u8 modulus[256]; | ||
687 | u8 message[256]; | ||
688 | }; | ||
689 | |||
690 | struct type50_crb1_msg { | ||
691 | struct type50_hdr header; | ||
692 | u16 keyblock_type; | ||
693 | u8 reserved[6]; | ||
694 | u8 p[64]; | ||
695 | u8 q[64]; | ||
696 | u8 dp[64]; | ||
697 | u8 dq[64]; | ||
698 | u8 u[64]; | ||
699 | u8 message[128]; | ||
700 | }; | ||
701 | |||
702 | struct type50_crb2_msg { | ||
703 | struct type50_hdr header; | ||
704 | u16 keyblock_type; | ||
705 | u8 reserved[6]; | ||
706 | u8 p[128]; | ||
707 | u8 q[128]; | ||
708 | u8 dp[128]; | ||
709 | u8 dq[128]; | ||
710 | u8 u[128]; | ||
711 | u8 message[256]; | ||
712 | }; | ||
713 | |||
714 | union type50_msg { | ||
715 | struct type50_meb1_msg meb1; | ||
716 | struct type50_meb2_msg meb2; | ||
717 | struct type50_crb1_msg crb1; | ||
718 | struct type50_crb2_msg crb2; | ||
719 | }; | ||
720 | |||
721 | struct type80_hdr { | ||
722 | u8 reserved1; | ||
723 | u8 type; | ||
724 | u16 len; | ||
725 | u8 code; | ||
726 | u8 reserved2[3]; | ||
727 | u8 reserved3[8]; | ||
728 | }; | ||
729 | |||
730 | #define TYPE80_RSP_CODE 0x80 | ||
731 | |||
651 | struct error_hdr { | 732 | struct error_hdr { |
652 | unsigned char reserved1; | 733 | unsigned char reserved1; |
653 | unsigned char type; | 734 | unsigned char type; |
@@ -657,6 +738,7 @@ struct error_hdr { | |||
657 | }; | 738 | }; |
658 | 739 | ||
659 | #define TYPE82_RSP_CODE 0x82 | 740 | #define TYPE82_RSP_CODE 0x82 |
741 | #define TYPE88_RSP_CODE 0x88 | ||
660 | 742 | ||
661 | #define REP82_ERROR_MACHINE_FAILURE 0x10 | 743 | #define REP82_ERROR_MACHINE_FAILURE 0x10 |
662 | #define REP82_ERROR_PREEMPT_FAILURE 0x12 | 744 | #define REP82_ERROR_PREEMPT_FAILURE 0x12 |
@@ -679,6 +761,22 @@ struct error_hdr { | |||
679 | #define REP82_ERROR_PACKET_TRUNCATED 0xA0 | 761 | #define REP82_ERROR_PACKET_TRUNCATED 0xA0 |
680 | #define REP82_ERROR_ZERO_BUFFER_LEN 0xB0 | 762 | #define REP82_ERROR_ZERO_BUFFER_LEN 0xB0 |
681 | 763 | ||
764 | #define REP88_ERROR_MODULE_FAILURE 0x10 | ||
765 | #define REP88_ERROR_MODULE_TIMEOUT 0x11 | ||
766 | #define REP88_ERROR_MODULE_NOTINIT 0x13 | ||
767 | #define REP88_ERROR_MODULE_NOTAVAIL 0x14 | ||
768 | #define REP88_ERROR_MODULE_DISABLED 0x15 | ||
769 | #define REP88_ERROR_MODULE_IN_DIAGN 0x17 | ||
770 | #define REP88_ERROR_FASTPATH_DISABLD 0x19 | ||
771 | #define REP88_ERROR_MESSAGE_TYPE 0x20 | ||
772 | #define REP88_ERROR_MESSAGE_MALFORMD 0x22 | ||
773 | #define REP88_ERROR_MESSAGE_LENGTH 0x23 | ||
774 | #define REP88_ERROR_RESERVED_FIELD 0x24 | ||
775 | #define REP88_ERROR_KEY_TYPE 0x34 | ||
776 | #define REP88_ERROR_INVALID_KEY 0x82 | ||
777 | #define REP88_ERROR_OPERAND 0x84 | ||
778 | #define REP88_ERROR_OPERAND_EVEN_MOD 0x85 | ||
779 | |||
682 | #define CALLER_HEADER 12 | 780 | #define CALLER_HEADER 12 |
683 | 781 | ||
684 | static inline int | 782 | static inline int |
@@ -1029,10 +1127,6 @@ query_online(int deviceNr, int cdx, int resetNr, int *q_depth, int *dev_type) | |||
1029 | stat = HD_ONLINE; | 1127 | stat = HD_ONLINE; |
1030 | *q_depth = t_depth + 1; | 1128 | *q_depth = t_depth + 1; |
1031 | switch (t_dev_type) { | 1129 | switch (t_dev_type) { |
1032 | case OTHER_HW: | ||
1033 | stat = HD_NOT_THERE; | ||
1034 | *dev_type = NILDEV; | ||
1035 | break; | ||
1036 | case PCICA_HW: | 1130 | case PCICA_HW: |
1037 | *dev_type = PCICA; | 1131 | *dev_type = PCICA; |
1038 | break; | 1132 | break; |
@@ -1045,6 +1139,9 @@ query_online(int deviceNr, int cdx, int resetNr, int *q_depth, int *dev_type) | |||
1045 | case CEX2C_HW: | 1139 | case CEX2C_HW: |
1046 | *dev_type = CEX2C; | 1140 | *dev_type = CEX2C; |
1047 | break; | 1141 | break; |
1142 | case CEX2A_HW: | ||
1143 | *dev_type = CEX2A; | ||
1144 | break; | ||
1048 | default: | 1145 | default: |
1049 | *dev_type = NILDEV; | 1146 | *dev_type = NILDEV; |
1050 | break; | 1147 | break; |
@@ -2029,6 +2126,177 @@ ICACRT_msg_to_type6CRT_msgX(struct ica_rsa_modexpo_crt *icaMsg_p, int cdx, | |||
2029 | return 0; | 2126 | return 0; |
2030 | } | 2127 | } |
2031 | 2128 | ||
2129 | static int | ||
2130 | ICAMEX_msg_to_type50MEX_msg(struct ica_rsa_modexpo *icaMex_p, int *z90cMsg_l_p, | ||
2131 | union type50_msg *z90cMsg_p) | ||
2132 | { | ||
2133 | int mod_len, msg_size, mod_tgt_len, exp_tgt_len, inp_tgt_len; | ||
2134 | unsigned char *mod_tgt, *exp_tgt, *inp_tgt; | ||
2135 | union type50_msg *tmp_type50_msg; | ||
2136 | |||
2137 | mod_len = icaMex_p->inputdatalength; | ||
2138 | |||
2139 | msg_size = ((mod_len <= 128) ? TYPE50_MEB1_LEN : TYPE50_MEB2_LEN) + | ||
2140 | CALLER_HEADER; | ||
2141 | |||
2142 | memset(z90cMsg_p, 0, msg_size); | ||
2143 | |||
2144 | tmp_type50_msg = (union type50_msg *) | ||
2145 | ((unsigned char *) z90cMsg_p + CALLER_HEADER); | ||
2146 | |||
2147 | tmp_type50_msg->meb1.header.msg_type_code = TYPE50_TYPE_CODE; | ||
2148 | |||
2149 | if (mod_len <= 128) { | ||
2150 | tmp_type50_msg->meb1.header.msg_len = TYPE50_MEB1_LEN; | ||
2151 | tmp_type50_msg->meb1.keyblock_type = TYPE50_MEB1_FMT; | ||
2152 | mod_tgt = tmp_type50_msg->meb1.modulus; | ||
2153 | mod_tgt_len = sizeof(tmp_type50_msg->meb1.modulus); | ||
2154 | exp_tgt = tmp_type50_msg->meb1.exponent; | ||
2155 | exp_tgt_len = sizeof(tmp_type50_msg->meb1.exponent); | ||
2156 | inp_tgt = tmp_type50_msg->meb1.message; | ||
2157 | inp_tgt_len = sizeof(tmp_type50_msg->meb1.message); | ||
2158 | } else { | ||
2159 | tmp_type50_msg->meb2.header.msg_len = TYPE50_MEB2_LEN; | ||
2160 | tmp_type50_msg->meb2.keyblock_type = TYPE50_MEB2_FMT; | ||
2161 | mod_tgt = tmp_type50_msg->meb2.modulus; | ||
2162 | mod_tgt_len = sizeof(tmp_type50_msg->meb2.modulus); | ||
2163 | exp_tgt = tmp_type50_msg->meb2.exponent; | ||
2164 | exp_tgt_len = sizeof(tmp_type50_msg->meb2.exponent); | ||
2165 | inp_tgt = tmp_type50_msg->meb2.message; | ||
2166 | inp_tgt_len = sizeof(tmp_type50_msg->meb2.message); | ||
2167 | } | ||
2168 | |||
2169 | mod_tgt += (mod_tgt_len - mod_len); | ||
2170 | if (copy_from_user(mod_tgt, icaMex_p->n_modulus, mod_len)) | ||
2171 | return SEN_RELEASED; | ||
2172 | if (is_empty(mod_tgt, mod_len)) | ||
2173 | return SEN_USER_ERROR; | ||
2174 | exp_tgt += (exp_tgt_len - mod_len); | ||
2175 | if (copy_from_user(exp_tgt, icaMex_p->b_key, mod_len)) | ||
2176 | return SEN_RELEASED; | ||
2177 | if (is_empty(exp_tgt, mod_len)) | ||
2178 | return SEN_USER_ERROR; | ||
2179 | inp_tgt += (inp_tgt_len - mod_len); | ||
2180 | if (copy_from_user(inp_tgt, icaMex_p->inputdata, mod_len)) | ||
2181 | return SEN_RELEASED; | ||
2182 | if (is_empty(inp_tgt, mod_len)) | ||
2183 | return SEN_USER_ERROR; | ||
2184 | |||
2185 | *z90cMsg_l_p = msg_size - CALLER_HEADER; | ||
2186 | |||
2187 | return 0; | ||
2188 | } | ||
2189 | |||
2190 | static int | ||
2191 | ICACRT_msg_to_type50CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p, | ||
2192 | int *z90cMsg_l_p, union type50_msg *z90cMsg_p) | ||
2193 | { | ||
2194 | int mod_len, short_len, long_len, tmp_size, p_tgt_len, q_tgt_len, | ||
2195 | dp_tgt_len, dq_tgt_len, u_tgt_len, inp_tgt_len, long_offset; | ||
2196 | unsigned char *p_tgt, *q_tgt, *dp_tgt, *dq_tgt, *u_tgt, *inp_tgt, | ||
2197 | temp[8]; | ||
2198 | union type50_msg *tmp_type50_msg; | ||
2199 | |||
2200 | mod_len = icaMsg_p->inputdatalength; | ||
2201 | short_len = mod_len / 2; | ||
2202 | long_len = mod_len / 2 + 8; | ||
2203 | long_offset = 0; | ||
2204 | |||
2205 | if (long_len > 128) { | ||
2206 | memset(temp, 0x00, sizeof(temp)); | ||
2207 | if (copy_from_user(temp, icaMsg_p->np_prime, long_len-128)) | ||
2208 | return SEN_RELEASED; | ||
2209 | if (!is_empty(temp, 8)) | ||
2210 | return SEN_NOT_AVAIL; | ||
2211 | if (copy_from_user(temp, icaMsg_p->bp_key, long_len-128)) | ||
2212 | return SEN_RELEASED; | ||
2213 | if (!is_empty(temp, 8)) | ||
2214 | return SEN_NOT_AVAIL; | ||
2215 | if (copy_from_user(temp, icaMsg_p->u_mult_inv, long_len-128)) | ||
2216 | return SEN_RELEASED; | ||
2217 | if (!is_empty(temp, 8)) | ||
2218 | return SEN_NOT_AVAIL; | ||
2219 | long_offset = long_len - 128; | ||
2220 | long_len = 128; | ||
2221 | } | ||
2222 | |||
2223 | tmp_size = ((mod_len <= 128) ? TYPE50_CRB1_LEN : TYPE50_CRB2_LEN) + | ||
2224 | CALLER_HEADER; | ||
2225 | |||
2226 | memset(z90cMsg_p, 0, tmp_size); | ||
2227 | |||
2228 | tmp_type50_msg = (union type50_msg *) | ||
2229 | ((unsigned char *) z90cMsg_p + CALLER_HEADER); | ||
2230 | |||
2231 | tmp_type50_msg->crb1.header.msg_type_code = TYPE50_TYPE_CODE; | ||
2232 | if (long_len <= 64) { | ||
2233 | tmp_type50_msg->crb1.header.msg_len = TYPE50_CRB1_LEN; | ||
2234 | tmp_type50_msg->crb1.keyblock_type = TYPE50_CRB1_FMT; | ||
2235 | p_tgt = tmp_type50_msg->crb1.p; | ||
2236 | p_tgt_len = sizeof(tmp_type50_msg->crb1.p); | ||
2237 | q_tgt = tmp_type50_msg->crb1.q; | ||
2238 | q_tgt_len = sizeof(tmp_type50_msg->crb1.q); | ||
2239 | dp_tgt = tmp_type50_msg->crb1.dp; | ||
2240 | dp_tgt_len = sizeof(tmp_type50_msg->crb1.dp); | ||
2241 | dq_tgt = tmp_type50_msg->crb1.dq; | ||
2242 | dq_tgt_len = sizeof(tmp_type50_msg->crb1.dq); | ||
2243 | u_tgt = tmp_type50_msg->crb1.u; | ||
2244 | u_tgt_len = sizeof(tmp_type50_msg->crb1.u); | ||
2245 | inp_tgt = tmp_type50_msg->crb1.message; | ||
2246 | inp_tgt_len = sizeof(tmp_type50_msg->crb1.message); | ||
2247 | } else { | ||
2248 | tmp_type50_msg->crb2.header.msg_len = TYPE50_CRB2_LEN; | ||
2249 | tmp_type50_msg->crb2.keyblock_type = TYPE50_CRB2_FMT; | ||
2250 | p_tgt = tmp_type50_msg->crb2.p; | ||
2251 | p_tgt_len = sizeof(tmp_type50_msg->crb2.p); | ||
2252 | q_tgt = tmp_type50_msg->crb2.q; | ||
2253 | q_tgt_len = sizeof(tmp_type50_msg->crb2.q); | ||
2254 | dp_tgt = tmp_type50_msg->crb2.dp; | ||
2255 | dp_tgt_len = sizeof(tmp_type50_msg->crb2.dp); | ||
2256 | dq_tgt = tmp_type50_msg->crb2.dq; | ||
2257 | dq_tgt_len = sizeof(tmp_type50_msg->crb2.dq); | ||
2258 | u_tgt = tmp_type50_msg->crb2.u; | ||
2259 | u_tgt_len = sizeof(tmp_type50_msg->crb2.u); | ||
2260 | inp_tgt = tmp_type50_msg->crb2.message; | ||
2261 | inp_tgt_len = sizeof(tmp_type50_msg->crb2.message); | ||
2262 | } | ||
2263 | |||
2264 | p_tgt += (p_tgt_len - long_len); | ||
2265 | if (copy_from_user(p_tgt, icaMsg_p->np_prime + long_offset, long_len)) | ||
2266 | return SEN_RELEASED; | ||
2267 | if (is_empty(p_tgt, long_len)) | ||
2268 | return SEN_USER_ERROR; | ||
2269 | q_tgt += (q_tgt_len - short_len); | ||
2270 | if (copy_from_user(q_tgt, icaMsg_p->nq_prime, short_len)) | ||
2271 | return SEN_RELEASED; | ||
2272 | if (is_empty(q_tgt, short_len)) | ||
2273 | return SEN_USER_ERROR; | ||
2274 | dp_tgt += (dp_tgt_len - long_len); | ||
2275 | if (copy_from_user(dp_tgt, icaMsg_p->bp_key + long_offset, long_len)) | ||
2276 | return SEN_RELEASED; | ||
2277 | if (is_empty(dp_tgt, long_len)) | ||
2278 | return SEN_USER_ERROR; | ||
2279 | dq_tgt += (dq_tgt_len - short_len); | ||
2280 | if (copy_from_user(dq_tgt, icaMsg_p->bq_key, short_len)) | ||
2281 | return SEN_RELEASED; | ||
2282 | if (is_empty(dq_tgt, short_len)) | ||
2283 | return SEN_USER_ERROR; | ||
2284 | u_tgt += (u_tgt_len - long_len); | ||
2285 | if (copy_from_user(u_tgt, icaMsg_p->u_mult_inv + long_offset, long_len)) | ||
2286 | return SEN_RELEASED; | ||
2287 | if (is_empty(u_tgt, long_len)) | ||
2288 | return SEN_USER_ERROR; | ||
2289 | inp_tgt += (inp_tgt_len - mod_len); | ||
2290 | if (copy_from_user(inp_tgt, icaMsg_p->inputdata, mod_len)) | ||
2291 | return SEN_RELEASED; | ||
2292 | if (is_empty(inp_tgt, mod_len)) | ||
2293 | return SEN_USER_ERROR; | ||
2294 | |||
2295 | *z90cMsg_l_p = tmp_size - CALLER_HEADER; | ||
2296 | |||
2297 | return 0; | ||
2298 | } | ||
2299 | |||
2032 | int | 2300 | int |
2033 | convert_request(unsigned char *buffer, int func, unsigned short function, | 2301 | convert_request(unsigned char *buffer, int func, unsigned short function, |
2034 | int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p) | 2302 | int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p) |
@@ -2071,6 +2339,16 @@ convert_request(unsigned char *buffer, int func, unsigned short function, | |||
2071 | cdx, msg_l_p, (struct type6_msg *) msg_p, | 2339 | cdx, msg_l_p, (struct type6_msg *) msg_p, |
2072 | dev_type); | 2340 | dev_type); |
2073 | } | 2341 | } |
2342 | if (dev_type == CEX2A) { | ||
2343 | if (func == ICARSACRT) | ||
2344 | return ICACRT_msg_to_type50CRT_msg( | ||
2345 | (struct ica_rsa_modexpo_crt *) buffer, | ||
2346 | msg_l_p, (union type50_msg *) msg_p); | ||
2347 | else | ||
2348 | return ICAMEX_msg_to_type50MEX_msg( | ||
2349 | (struct ica_rsa_modexpo *) buffer, | ||
2350 | msg_l_p, (union type50_msg *) msg_p); | ||
2351 | } | ||
2074 | 2352 | ||
2075 | return 0; | 2353 | return 0; |
2076 | } | 2354 | } |
@@ -2081,8 +2359,8 @@ unset_ext_bitlens(void) | |||
2081 | { | 2359 | { |
2082 | if (!ext_bitlens_msg_count) { | 2360 | if (!ext_bitlens_msg_count) { |
2083 | PRINTK("Unable to use coprocessors for extended bitlengths. " | 2361 | PRINTK("Unable to use coprocessors for extended bitlengths. " |
2084 | "Using PCICAs (if present) for extended bitlengths. " | 2362 | "Using PCICAs/CEX2As (if present) for extended " |
2085 | "This is not an error.\n"); | 2363 | "bitlengths. This is not an error.\n"); |
2086 | ext_bitlens_msg_count++; | 2364 | ext_bitlens_msg_count++; |
2087 | } | 2365 | } |
2088 | ext_bitlens = 0; | 2366 | ext_bitlens = 0; |
@@ -2094,6 +2372,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2094 | { | 2372 | { |
2095 | struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer; | 2373 | struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer; |
2096 | struct error_hdr *errh_p = (struct error_hdr *) response; | 2374 | struct error_hdr *errh_p = (struct error_hdr *) response; |
2375 | struct type80_hdr *t80h_p = (struct type80_hdr *) response; | ||
2097 | struct type84_hdr *t84h_p = (struct type84_hdr *) response; | 2376 | struct type84_hdr *t84h_p = (struct type84_hdr *) response; |
2098 | struct type86_fmt2_msg *t86m_p = (struct type86_fmt2_msg *) response; | 2377 | struct type86_fmt2_msg *t86m_p = (struct type86_fmt2_msg *) response; |
2099 | int reply_code, service_rc, service_rs, src_l; | 2378 | int reply_code, service_rc, service_rs, src_l; |
@@ -2108,6 +2387,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2108 | src_l = 0; | 2387 | src_l = 0; |
2109 | switch (errh_p->type) { | 2388 | switch (errh_p->type) { |
2110 | case TYPE82_RSP_CODE: | 2389 | case TYPE82_RSP_CODE: |
2390 | case TYPE88_RSP_CODE: | ||
2111 | reply_code = errh_p->reply_code; | 2391 | reply_code = errh_p->reply_code; |
2112 | src_p = (unsigned char *)errh_p; | 2392 | src_p = (unsigned char *)errh_p; |
2113 | PRINTK("Hardware error: Type %02X Message Header: " | 2393 | PRINTK("Hardware error: Type %02X Message Header: " |
@@ -2116,6 +2396,10 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2116 | src_p[0], src_p[1], src_p[2], src_p[3], | 2396 | src_p[0], src_p[1], src_p[2], src_p[3], |
2117 | src_p[4], src_p[5], src_p[6], src_p[7]); | 2397 | src_p[4], src_p[5], src_p[6], src_p[7]); |
2118 | break; | 2398 | break; |
2399 | case TYPE80_RSP_CODE: | ||
2400 | src_l = icaMsg_p->outputdatalength; | ||
2401 | src_p = response + (int)t80h_p->len - src_l; | ||
2402 | break; | ||
2119 | case TYPE84_RSP_CODE: | 2403 | case TYPE84_RSP_CODE: |
2120 | src_l = icaMsg_p->outputdatalength; | 2404 | src_l = icaMsg_p->outputdatalength; |
2121 | src_p = response + (int)t84h_p->len - src_l; | 2405 | src_p = response + (int)t84h_p->len - src_l; |
@@ -2202,6 +2486,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2202 | if (reply_code) | 2486 | if (reply_code) |
2203 | switch (reply_code) { | 2487 | switch (reply_code) { |
2204 | case REP82_ERROR_OPERAND_INVALID: | 2488 | case REP82_ERROR_OPERAND_INVALID: |
2489 | case REP88_ERROR_MESSAGE_MALFORMD: | ||
2205 | return REC_OPERAND_INV; | 2490 | return REC_OPERAND_INV; |
2206 | case REP82_ERROR_OPERAND_SIZE: | 2491 | case REP82_ERROR_OPERAND_SIZE: |
2207 | return REC_OPERAND_SIZE; | 2492 | return REC_OPERAND_SIZE; |
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c index 790fcbb74b43..135ae04e6e75 100644 --- a/drivers/s390/crypto/z90main.c +++ b/drivers/s390/crypto/z90main.c | |||
@@ -228,7 +228,7 @@ struct device_x { | |||
228 | */ | 228 | */ |
229 | struct device { | 229 | struct device { |
230 | int dev_type; // PCICA, PCICC, PCIXCC_MCL2, | 230 | int dev_type; // PCICA, PCICC, PCIXCC_MCL2, |
231 | // PCIXCC_MCL3, CEX2C | 231 | // PCIXCC_MCL3, CEX2C, CEX2A |
232 | enum devstat dev_stat; // current device status | 232 | enum devstat dev_stat; // current device status |
233 | int dev_self_x; // Index in array | 233 | int dev_self_x; // Index in array |
234 | int disabled; // Set when device is in error | 234 | int disabled; // Set when device is in error |
@@ -295,26 +295,30 @@ struct caller { | |||
295 | /** | 295 | /** |
296 | * Function prototypes from z90hardware.c | 296 | * Function prototypes from z90hardware.c |
297 | */ | 297 | */ |
298 | enum hdstat query_online(int, int, int, int *, int *); | 298 | enum hdstat query_online(int deviceNr, int cdx, int resetNr, int *q_depth, |
299 | enum devstat reset_device(int, int, int); | 299 | int *dev_type); |
300 | enum devstat send_to_AP(int, int, int, unsigned char *); | 300 | enum devstat reset_device(int deviceNr, int cdx, int resetNr); |
301 | enum devstat receive_from_AP(int, int, int, unsigned char *, unsigned char *); | 301 | enum devstat send_to_AP(int dev_nr, int cdx, int msg_len, unsigned char *msg_ext); |
302 | int convert_request(unsigned char *, int, short, int, int, int *, | 302 | enum devstat receive_from_AP(int dev_nr, int cdx, int resplen, |
303 | unsigned char *); | 303 | unsigned char *resp, unsigned char *psmid); |
304 | int convert_response(unsigned char *, unsigned char *, int *, unsigned char *); | 304 | int convert_request(unsigned char *buffer, int func, unsigned short function, |
305 | int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p); | ||
306 | int convert_response(unsigned char *response, unsigned char *buffer, | ||
307 | int *respbufflen_p, unsigned char *resp_buff); | ||
305 | 308 | ||
306 | /** | 309 | /** |
307 | * Low level function prototypes | 310 | * Low level function prototypes |
308 | */ | 311 | */ |
309 | static int create_z90crypt(int *); | 312 | static int create_z90crypt(int *cdx_p); |
310 | static int refresh_z90crypt(int *); | 313 | static int refresh_z90crypt(int *cdx_p); |
311 | static int find_crypto_devices(struct status *); | 314 | static int find_crypto_devices(struct status *deviceMask); |
312 | static int create_crypto_device(int); | 315 | static int create_crypto_device(int index); |
313 | static int destroy_crypto_device(int); | 316 | static int destroy_crypto_device(int index); |
314 | static void destroy_z90crypt(void); | 317 | static void destroy_z90crypt(void); |
315 | static int refresh_index_array(struct status *, struct device_x *); | 318 | static int refresh_index_array(struct status *status_str, |
316 | static int probe_device_type(struct device *); | 319 | struct device_x *index_array); |
317 | static int probe_PCIXCC_type(struct device *); | 320 | static int probe_device_type(struct device *devPtr); |
321 | static int probe_PCIXCC_type(struct device *devPtr); | ||
318 | 322 | ||
319 | /** | 323 | /** |
320 | * proc fs definitions | 324 | * proc fs definitions |
@@ -425,7 +429,7 @@ static struct miscdevice z90crypt_misc_device = { | |||
425 | MODULE_AUTHOR("zSeries Linux Crypto Team: Robert H. Burroughs, Eric D. Rossman" | 429 | MODULE_AUTHOR("zSeries Linux Crypto Team: Robert H. Burroughs, Eric D. Rossman" |
426 | "and Jochen Roehrig"); | 430 | "and Jochen Roehrig"); |
427 | MODULE_DESCRIPTION("zSeries Linux Cryptographic Coprocessor device driver, " | 431 | MODULE_DESCRIPTION("zSeries Linux Cryptographic Coprocessor device driver, " |
428 | "Copyright 2001, 2004 IBM Corporation"); | 432 | "Copyright 2001, 2005 IBM Corporation"); |
429 | MODULE_LICENSE("GPL"); | 433 | MODULE_LICENSE("GPL"); |
430 | module_param(domain, int, 0); | 434 | module_param(domain, int, 0); |
431 | MODULE_PARM_DESC(domain, "domain index for device"); | 435 | MODULE_PARM_DESC(domain, "domain index for device"); |
@@ -860,6 +864,12 @@ get_status_CEX2Ccount(void) | |||
860 | } | 864 | } |
861 | 865 | ||
862 | static inline int | 866 | static inline int |
867 | get_status_CEX2Acount(void) | ||
868 | { | ||
869 | return z90crypt.hdware_info->type_mask[CEX2A].st_count; | ||
870 | } | ||
871 | |||
872 | static inline int | ||
863 | get_status_requestq_count(void) | 873 | get_status_requestq_count(void) |
864 | { | 874 | { |
865 | return requestq_count; | 875 | return requestq_count; |
@@ -1008,11 +1018,13 @@ static inline int | |||
1008 | select_device_type(int *dev_type_p, int bytelength) | 1018 | select_device_type(int *dev_type_p, int bytelength) |
1009 | { | 1019 | { |
1010 | static int count = 0; | 1020 | static int count = 0; |
1011 | int PCICA_avail, PCIXCC_MCL3_avail, CEX2C_avail, index_to_use; | 1021 | int PCICA_avail, PCIXCC_MCL3_avail, CEX2C_avail, CEX2A_avail, |
1022 | index_to_use; | ||
1012 | struct status *stat; | 1023 | struct status *stat; |
1013 | if ((*dev_type_p != PCICC) && (*dev_type_p != PCICA) && | 1024 | if ((*dev_type_p != PCICC) && (*dev_type_p != PCICA) && |
1014 | (*dev_type_p != PCIXCC_MCL2) && (*dev_type_p != PCIXCC_MCL3) && | 1025 | (*dev_type_p != PCIXCC_MCL2) && (*dev_type_p != PCIXCC_MCL3) && |
1015 | (*dev_type_p != CEX2C) && (*dev_type_p != ANYDEV)) | 1026 | (*dev_type_p != CEX2C) && (*dev_type_p != CEX2A) && |
1027 | (*dev_type_p != ANYDEV)) | ||
1016 | return -1; | 1028 | return -1; |
1017 | if (*dev_type_p != ANYDEV) { | 1029 | if (*dev_type_p != ANYDEV) { |
1018 | stat = &z90crypt.hdware_info->type_mask[*dev_type_p]; | 1030 | stat = &z90crypt.hdware_info->type_mask[*dev_type_p]; |
@@ -1022,7 +1034,13 @@ select_device_type(int *dev_type_p, int bytelength) | |||
1022 | return -1; | 1034 | return -1; |
1023 | } | 1035 | } |
1024 | 1036 | ||
1025 | /* Assumption: PCICA, PCIXCC_MCL3, and CEX2C are all similar in speed */ | 1037 | /** |
1038 | * Assumption: PCICA, PCIXCC_MCL3, CEX2C, and CEX2A are all similar in | ||
1039 | * speed. | ||
1040 | * | ||
1041 | * PCICA and CEX2A do NOT co-exist, so it would be either one or the | ||
1042 | * other present. | ||
1043 | */ | ||
1026 | stat = &z90crypt.hdware_info->type_mask[PCICA]; | 1044 | stat = &z90crypt.hdware_info->type_mask[PCICA]; |
1027 | PCICA_avail = stat->st_count - | 1045 | PCICA_avail = stat->st_count - |
1028 | (stat->disabled_count + stat->user_disabled_count); | 1046 | (stat->disabled_count + stat->user_disabled_count); |
@@ -1032,29 +1050,38 @@ select_device_type(int *dev_type_p, int bytelength) | |||
1032 | stat = &z90crypt.hdware_info->type_mask[CEX2C]; | 1050 | stat = &z90crypt.hdware_info->type_mask[CEX2C]; |
1033 | CEX2C_avail = stat->st_count - | 1051 | CEX2C_avail = stat->st_count - |
1034 | (stat->disabled_count + stat->user_disabled_count); | 1052 | (stat->disabled_count + stat->user_disabled_count); |
1035 | if (PCICA_avail || PCIXCC_MCL3_avail || CEX2C_avail) { | 1053 | stat = &z90crypt.hdware_info->type_mask[CEX2A]; |
1054 | CEX2A_avail = stat->st_count - | ||
1055 | (stat->disabled_count + stat->user_disabled_count); | ||
1056 | if (PCICA_avail || PCIXCC_MCL3_avail || CEX2C_avail || CEX2A_avail) { | ||
1036 | /** | 1057 | /** |
1037 | * bitlength is a factor, PCICA is the most capable, even with | 1058 | * bitlength is a factor, PCICA or CEX2A are the most capable, |
1038 | * the new MCL for PCIXCC. | 1059 | * even with the new MCL for PCIXCC. |
1039 | */ | 1060 | */ |
1040 | if ((bytelength < PCIXCC_MIN_MOD_SIZE) || | 1061 | if ((bytelength < PCIXCC_MIN_MOD_SIZE) || |
1041 | (!ext_bitlens && (bytelength < OLD_PCIXCC_MIN_MOD_SIZE))) { | 1062 | (!ext_bitlens && (bytelength < OLD_PCIXCC_MIN_MOD_SIZE))) { |
1042 | if (!PCICA_avail) | 1063 | if (PCICA_avail) { |
1043 | return -1; | ||
1044 | else { | ||
1045 | *dev_type_p = PCICA; | 1064 | *dev_type_p = PCICA; |
1046 | return 0; | 1065 | return 0; |
1047 | } | 1066 | } |
1067 | if (CEX2A_avail) { | ||
1068 | *dev_type_p = CEX2A; | ||
1069 | return 0; | ||
1070 | } | ||
1071 | return -1; | ||
1048 | } | 1072 | } |
1049 | 1073 | ||
1050 | index_to_use = count % (PCICA_avail + PCIXCC_MCL3_avail + | 1074 | index_to_use = count % (PCICA_avail + PCIXCC_MCL3_avail + |
1051 | CEX2C_avail); | 1075 | CEX2C_avail + CEX2A_avail); |
1052 | if (index_to_use < PCICA_avail) | 1076 | if (index_to_use < PCICA_avail) |
1053 | *dev_type_p = PCICA; | 1077 | *dev_type_p = PCICA; |
1054 | else if (index_to_use < (PCICA_avail + PCIXCC_MCL3_avail)) | 1078 | else if (index_to_use < (PCICA_avail + PCIXCC_MCL3_avail)) |
1055 | *dev_type_p = PCIXCC_MCL3; | 1079 | *dev_type_p = PCIXCC_MCL3; |
1056 | else | 1080 | else if (index_to_use < (PCICA_avail + PCIXCC_MCL3_avail + |
1081 | CEX2C_avail)) | ||
1057 | *dev_type_p = CEX2C; | 1082 | *dev_type_p = CEX2C; |
1083 | else | ||
1084 | *dev_type_p = CEX2A; | ||
1058 | count++; | 1085 | count++; |
1059 | return 0; | 1086 | return 0; |
1060 | } | 1087 | } |
@@ -1359,7 +1386,7 @@ build_caller(struct work_element *we_p, short function) | |||
1359 | 1386 | ||
1360 | if ((we_p->devtype != PCICC) && (we_p->devtype != PCICA) && | 1387 | if ((we_p->devtype != PCICC) && (we_p->devtype != PCICA) && |
1361 | (we_p->devtype != PCIXCC_MCL2) && (we_p->devtype != PCIXCC_MCL3) && | 1388 | (we_p->devtype != PCIXCC_MCL2) && (we_p->devtype != PCIXCC_MCL3) && |
1362 | (we_p->devtype != CEX2C)) | 1389 | (we_p->devtype != CEX2C) && (we_p->devtype != CEX2A)) |
1363 | return SEN_NOT_AVAIL; | 1390 | return SEN_NOT_AVAIL; |
1364 | 1391 | ||
1365 | memcpy(caller_p->caller_id, we_p->caller_id, | 1392 | memcpy(caller_p->caller_id, we_p->caller_id, |
@@ -1428,7 +1455,8 @@ get_crypto_request_buffer(struct work_element *we_p) | |||
1428 | 1455 | ||
1429 | if ((we_p->devtype != PCICA) && (we_p->devtype != PCICC) && | 1456 | if ((we_p->devtype != PCICA) && (we_p->devtype != PCICC) && |
1430 | (we_p->devtype != PCIXCC_MCL2) && (we_p->devtype != PCIXCC_MCL3) && | 1457 | (we_p->devtype != PCIXCC_MCL2) && (we_p->devtype != PCIXCC_MCL3) && |
1431 | (we_p->devtype != CEX2C) && (we_p->devtype != ANYDEV)) { | 1458 | (we_p->devtype != CEX2C) && (we_p->devtype != CEX2A) && |
1459 | (we_p->devtype != ANYDEV)) { | ||
1432 | PRINTK("invalid device type\n"); | 1460 | PRINTK("invalid device type\n"); |
1433 | return SEN_USER_ERROR; | 1461 | return SEN_USER_ERROR; |
1434 | } | 1462 | } |
@@ -1503,8 +1531,9 @@ get_crypto_request_buffer(struct work_element *we_p) | |||
1503 | 1531 | ||
1504 | function = PCI_FUNC_KEY_ENCRYPT; | 1532 | function = PCI_FUNC_KEY_ENCRYPT; |
1505 | switch (we_p->devtype) { | 1533 | switch (we_p->devtype) { |
1506 | /* PCICA does everything with a simple RSA mod-expo operation */ | 1534 | /* PCICA and CEX2A do everything with a simple RSA mod-expo operation */ |
1507 | case PCICA: | 1535 | case PCICA: |
1536 | case CEX2A: | ||
1508 | function = PCI_FUNC_KEY_ENCRYPT; | 1537 | function = PCI_FUNC_KEY_ENCRYPT; |
1509 | break; | 1538 | break; |
1510 | /** | 1539 | /** |
@@ -1662,7 +1691,8 @@ z90crypt_rsa(struct priv_data *private_data_p, pid_t pid, | |||
1662 | * trigger a fallback to software. | 1691 | * trigger a fallback to software. |
1663 | */ | 1692 | */ |
1664 | case -EINVAL: | 1693 | case -EINVAL: |
1665 | if (we_p->devtype != PCICA) | 1694 | if ((we_p->devtype != PCICA) && |
1695 | (we_p->devtype != CEX2A)) | ||
1666 | rv = -EGETBUFF; | 1696 | rv = -EGETBUFF; |
1667 | break; | 1697 | break; |
1668 | case -ETIMEOUT: | 1698 | case -ETIMEOUT: |
@@ -1779,6 +1809,12 @@ z90crypt_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
1779 | ret = -EFAULT; | 1809 | ret = -EFAULT; |
1780 | break; | 1810 | break; |
1781 | 1811 | ||
1812 | case Z90STAT_CEX2ACOUNT: | ||
1813 | tempstat = get_status_CEX2Acount(); | ||
1814 | if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0) | ||
1815 | ret = -EFAULT; | ||
1816 | break; | ||
1817 | |||
1782 | case Z90STAT_REQUESTQ_COUNT: | 1818 | case Z90STAT_REQUESTQ_COUNT: |
1783 | tempstat = get_status_requestq_count(); | 1819 | tempstat = get_status_requestq_count(); |
1784 | if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0) | 1820 | if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0) |
@@ -2019,6 +2055,8 @@ z90crypt_status(char *resp_buff, char **start, off_t offset, | |||
2019 | get_status_PCIXCCMCL3count()); | 2055 | get_status_PCIXCCMCL3count()); |
2020 | len += sprintf(resp_buff+len, "CEX2C count: %d\n", | 2056 | len += sprintf(resp_buff+len, "CEX2C count: %d\n", |
2021 | get_status_CEX2Ccount()); | 2057 | get_status_CEX2Ccount()); |
2058 | len += sprintf(resp_buff+len, "CEX2A count: %d\n", | ||
2059 | get_status_CEX2Acount()); | ||
2022 | len += sprintf(resp_buff+len, "requestq count: %d\n", | 2060 | len += sprintf(resp_buff+len, "requestq count: %d\n", |
2023 | get_status_requestq_count()); | 2061 | get_status_requestq_count()); |
2024 | len += sprintf(resp_buff+len, "pendingq count: %d\n", | 2062 | len += sprintf(resp_buff+len, "pendingq count: %d\n", |
@@ -2026,8 +2064,8 @@ z90crypt_status(char *resp_buff, char **start, off_t offset, | |||
2026 | len += sprintf(resp_buff+len, "Total open handles: %d\n\n", | 2064 | len += sprintf(resp_buff+len, "Total open handles: %d\n\n", |
2027 | get_status_totalopen_count()); | 2065 | get_status_totalopen_count()); |
2028 | len += sprinthx( | 2066 | len += sprinthx( |
2029 | "Online devices: 1: PCICA, 2: PCICC, 3: PCIXCC (MCL2), " | 2067 | "Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) " |
2030 | "4: PCIXCC (MCL3), 5: CEX2C", | 2068 | "4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A", |
2031 | resp_buff+len, | 2069 | resp_buff+len, |
2032 | get_status_status_mask(workarea), | 2070 | get_status_status_mask(workarea), |
2033 | Z90CRYPT_NUM_APS); | 2071 | Z90CRYPT_NUM_APS); |
@@ -2140,6 +2178,7 @@ z90crypt_status_write(struct file *file, const char __user *buffer, | |||
2140 | case '3': // PCIXCC_MCL2 | 2178 | case '3': // PCIXCC_MCL2 |
2141 | case '4': // PCIXCC_MCL3 | 2179 | case '4': // PCIXCC_MCL3 |
2142 | case '5': // CEX2C | 2180 | case '5': // CEX2C |
2181 | case '6': // CEX2A | ||
2143 | j++; | 2182 | j++; |
2144 | break; | 2183 | break; |
2145 | case 'd': | 2184 | case 'd': |
@@ -3007,7 +3046,9 @@ create_crypto_device(int index) | |||
3007 | z90crypt.hdware_info->device_type_array[index] = 4; | 3046 | z90crypt.hdware_info->device_type_array[index] = 4; |
3008 | else if (deviceType == CEX2C) | 3047 | else if (deviceType == CEX2C) |
3009 | z90crypt.hdware_info->device_type_array[index] = 5; | 3048 | z90crypt.hdware_info->device_type_array[index] = 5; |
3010 | else | 3049 | else if (deviceType == CEX2A) |
3050 | z90crypt.hdware_info->device_type_array[index] = 6; | ||
3051 | else // No idea how this would happen. | ||
3011 | z90crypt.hdware_info->device_type_array[index] = -1; | 3052 | z90crypt.hdware_info->device_type_array[index] = -1; |
3012 | } | 3053 | } |
3013 | 3054 | ||