Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Eric Rossman and committed by
Linus Torvalds
88fbf183 fb6958a5

+383 -51
+5 -4
drivers/s390/crypto/z90common.h
··· 1 1 /* 2 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 7 * Author(s): Robert Burroughs (burrough@us.ibm.com) 8 8 * Eric Rossman (edrossma@us.ibm.com) 9 9 * ··· 91 91 #define TSQ_FATAL_ERROR 34 92 92 #define RSQ_FATAL_ERROR 35 93 93 94 - #define Z90CRYPT_NUM_TYPES 5 94 + #define Z90CRYPT_NUM_TYPES 6 95 95 #define PCICA 0 96 96 #define PCICC 1 97 97 #define PCIXCC_MCL2 2 98 98 #define PCIXCC_MCL3 3 99 99 #define CEX2C 4 100 + #define CEX2A 5 100 101 #define NILDEV -1 101 102 #define ANYDEV -1 102 103 #define PCIXCC_UNK -2 ··· 106 105 PCICC_HW = 3, 107 106 PCICA_HW = 4, 108 107 PCIXCC_HW = 5, 109 - OTHER_HW = 6, 108 + CEX2A_HW = 6, 110 109 CEX2C_HW = 7 111 110 }; 112 111
+9 -4
drivers/s390/crypto/z90crypt.h
··· 1 1 /* 2 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 7 * Author(s): Robert Burroughs (burrough@us.ibm.com) 8 8 * Eric Rossman (edrossma@us.ibm.com) 9 9 * ··· 29 29 30 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 34 #define z90crypt_VERSION 1 35 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 39 * struct ica_rsa_modexpo ··· 122 122 * Z90STAT_CEX2CCOUNT 123 123 * Return an integer count of all CEX2Cs. 124 124 * 125 + * Z90STAT_CEX2ACOUNT 126 + * Return an integer count of all CEX2As. 127 + * 125 128 * Z90STAT_REQUESTQ_COUNT 126 129 * Return an integer count of the number of entries waiting to be 127 130 * sent to a device. ··· 147 144 * 0x03: PCIXCC_MCL2 148 145 * 0x04: PCIXCC_MCL3 149 146 * 0x05: CEX2C 147 + * 0x06: CEX2A 150 148 * 0x0d: device is disabled via the proc filesystem 151 149 * 152 150 * Z90STAT_QDEPTH_MASK ··· 203 199 #define Z90STAT_PCIXCCMCL2COUNT _IOR(Z90_IOCTL_MAGIC, 0x4b, int) 204 200 #define Z90STAT_PCIXCCMCL3COUNT _IOR(Z90_IOCTL_MAGIC, 0x4c, int) 205 201 #define Z90STAT_CEX2CCOUNT _IOR(Z90_IOCTL_MAGIC, 0x4d, int) 202 + #define Z90STAT_CEX2ACOUNT _IOR(Z90_IOCTL_MAGIC, 0x4e, int) 206 203 #define Z90STAT_REQUESTQ_COUNT _IOR(Z90_IOCTL_MAGIC, 0x44, int) 207 204 #define Z90STAT_PENDINGQ_COUNT _IOR(Z90_IOCTL_MAGIC, 0x45, int) 208 205 #define Z90STAT_TOTALOPEN_COUNT _IOR(Z90_IOCTL_MAGIC, 0x46, int)
+293 -8
drivers/s390/crypto/z90hardware.c
··· 1 1 /* 2 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 7 * Author(s): Robert Burroughs (burrough@us.ibm.com) 8 8 * Eric Rossman (edrossma@us.ibm.com) 9 9 * ··· 648 648 #define RESPONSE_CPRB_SIZE 0x000006B8 649 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 732 struct error_hdr { 652 733 unsigned char reserved1; 653 734 unsigned char type; ··· 738 657 }; 739 658 740 659 #define TYPE82_RSP_CODE 0x82 660 + #define TYPE88_RSP_CODE 0x88 741 661 742 662 #define REP82_ERROR_MACHINE_FAILURE 0x10 743 663 #define REP82_ERROR_PREEMPT_FAILURE 0x12 ··· 760 678 #define REP82_ERROR_TRANSPORT_FAIL 0x90 761 679 #define REP82_ERROR_PACKET_TRUNCATED 0xA0 762 680 #define REP82_ERROR_ZERO_BUFFER_LEN 0xB0 681 + 682 + #define REP88_ERROR_MODULE_FAILURE 0x10 683 + #define REP88_ERROR_MODULE_TIMEOUT 0x11 684 + #define REP88_ERROR_MODULE_NOTINIT 0x13 685 + #define REP88_ERROR_MODULE_NOTAVAIL 0x14 686 + #define REP88_ERROR_MODULE_DISABLED 0x15 687 + #define REP88_ERROR_MODULE_IN_DIAGN 0x17 688 + #define REP88_ERROR_FASTPATH_DISABLD 0x19 689 + #define REP88_ERROR_MESSAGE_TYPE 0x20 690 + #define REP88_ERROR_MESSAGE_MALFORMD 0x22 691 + #define REP88_ERROR_MESSAGE_LENGTH 0x23 692 + #define REP88_ERROR_RESERVED_FIELD 0x24 693 + #define REP88_ERROR_KEY_TYPE 0x34 694 + #define REP88_ERROR_INVALID_KEY 0x82 695 + #define REP88_ERROR_OPERAND 0x84 696 + #define REP88_ERROR_OPERAND_EVEN_MOD 0x85 763 697 764 698 #define CALLER_HEADER 12 765 699 ··· 1127 1029 stat = HD_ONLINE; 1128 1030 *q_depth = t_depth + 1; 1129 1031 switch (t_dev_type) { 1130 - case OTHER_HW: 1131 - stat = HD_NOT_THERE; 1132 - *dev_type = NILDEV; 1133 - break; 1134 1032 case PCICA_HW: 1135 1033 *dev_type = PCICA; 1136 1034 break; ··· 1138 1044 break; 1139 1045 case CEX2C_HW: 1140 1046 *dev_type = CEX2C; 1047 + break; 1048 + case CEX2A_HW: 1049 + *dev_type = CEX2A; 1141 1050 break; 1142 1051 default: 1143 1052 *dev_type = NILDEV; ··· 2126 2029 return 0; 2127 2030 } 2128 2031 2032 + static int 2033 + ICAMEX_msg_to_type50MEX_msg(struct ica_rsa_modexpo *icaMex_p, int *z90cMsg_l_p, 2034 + union type50_msg *z90cMsg_p) 2035 + { 2036 + int mod_len, msg_size, mod_tgt_len, exp_tgt_len, inp_tgt_len; 2037 + unsigned char *mod_tgt, *exp_tgt, *inp_tgt; 2038 + union type50_msg *tmp_type50_msg; 2039 + 2040 + mod_len = icaMex_p->inputdatalength; 2041 + 2042 + msg_size = ((mod_len <= 128) ? TYPE50_MEB1_LEN : TYPE50_MEB2_LEN) + 2043 + CALLER_HEADER; 2044 + 2045 + memset(z90cMsg_p, 0, msg_size); 2046 + 2047 + tmp_type50_msg = (union type50_msg *) 2048 + ((unsigned char *) z90cMsg_p + CALLER_HEADER); 2049 + 2050 + tmp_type50_msg->meb1.header.msg_type_code = TYPE50_TYPE_CODE; 2051 + 2052 + if (mod_len <= 128) { 2053 + tmp_type50_msg->meb1.header.msg_len = TYPE50_MEB1_LEN; 2054 + tmp_type50_msg->meb1.keyblock_type = TYPE50_MEB1_FMT; 2055 + mod_tgt = tmp_type50_msg->meb1.modulus; 2056 + mod_tgt_len = sizeof(tmp_type50_msg->meb1.modulus); 2057 + exp_tgt = tmp_type50_msg->meb1.exponent; 2058 + exp_tgt_len = sizeof(tmp_type50_msg->meb1.exponent); 2059 + inp_tgt = tmp_type50_msg->meb1.message; 2060 + inp_tgt_len = sizeof(tmp_type50_msg->meb1.message); 2061 + } else { 2062 + tmp_type50_msg->meb2.header.msg_len = TYPE50_MEB2_LEN; 2063 + tmp_type50_msg->meb2.keyblock_type = TYPE50_MEB2_FMT; 2064 + mod_tgt = tmp_type50_msg->meb2.modulus; 2065 + mod_tgt_len = sizeof(tmp_type50_msg->meb2.modulus); 2066 + exp_tgt = tmp_type50_msg->meb2.exponent; 2067 + exp_tgt_len = sizeof(tmp_type50_msg->meb2.exponent); 2068 + inp_tgt = tmp_type50_msg->meb2.message; 2069 + inp_tgt_len = sizeof(tmp_type50_msg->meb2.message); 2070 + } 2071 + 2072 + mod_tgt += (mod_tgt_len - mod_len); 2073 + if (copy_from_user(mod_tgt, icaMex_p->n_modulus, mod_len)) 2074 + return SEN_RELEASED; 2075 + if (is_empty(mod_tgt, mod_len)) 2076 + return SEN_USER_ERROR; 2077 + exp_tgt += (exp_tgt_len - mod_len); 2078 + if (copy_from_user(exp_tgt, icaMex_p->b_key, mod_len)) 2079 + return SEN_RELEASED; 2080 + if (is_empty(exp_tgt, mod_len)) 2081 + return SEN_USER_ERROR; 2082 + inp_tgt += (inp_tgt_len - mod_len); 2083 + if (copy_from_user(inp_tgt, icaMex_p->inputdata, mod_len)) 2084 + return SEN_RELEASED; 2085 + if (is_empty(inp_tgt, mod_len)) 2086 + return SEN_USER_ERROR; 2087 + 2088 + *z90cMsg_l_p = msg_size - CALLER_HEADER; 2089 + 2090 + return 0; 2091 + } 2092 + 2093 + static int 2094 + ICACRT_msg_to_type50CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p, 2095 + int *z90cMsg_l_p, union type50_msg *z90cMsg_p) 2096 + { 2097 + int mod_len, short_len, long_len, tmp_size, p_tgt_len, q_tgt_len, 2098 + dp_tgt_len, dq_tgt_len, u_tgt_len, inp_tgt_len, long_offset; 2099 + unsigned char *p_tgt, *q_tgt, *dp_tgt, *dq_tgt, *u_tgt, *inp_tgt, 2100 + temp[8]; 2101 + union type50_msg *tmp_type50_msg; 2102 + 2103 + mod_len = icaMsg_p->inputdatalength; 2104 + short_len = mod_len / 2; 2105 + long_len = mod_len / 2 + 8; 2106 + long_offset = 0; 2107 + 2108 + if (long_len > 128) { 2109 + memset(temp, 0x00, sizeof(temp)); 2110 + if (copy_from_user(temp, icaMsg_p->np_prime, long_len-128)) 2111 + return SEN_RELEASED; 2112 + if (!is_empty(temp, 8)) 2113 + return SEN_NOT_AVAIL; 2114 + if (copy_from_user(temp, icaMsg_p->bp_key, long_len-128)) 2115 + return SEN_RELEASED; 2116 + if (!is_empty(temp, 8)) 2117 + return SEN_NOT_AVAIL; 2118 + if (copy_from_user(temp, icaMsg_p->u_mult_inv, long_len-128)) 2119 + return SEN_RELEASED; 2120 + if (!is_empty(temp, 8)) 2121 + return SEN_NOT_AVAIL; 2122 + long_offset = long_len - 128; 2123 + long_len = 128; 2124 + } 2125 + 2126 + tmp_size = ((mod_len <= 128) ? TYPE50_CRB1_LEN : TYPE50_CRB2_LEN) + 2127 + CALLER_HEADER; 2128 + 2129 + memset(z90cMsg_p, 0, tmp_size); 2130 + 2131 + tmp_type50_msg = (union type50_msg *) 2132 + ((unsigned char *) z90cMsg_p + CALLER_HEADER); 2133 + 2134 + tmp_type50_msg->crb1.header.msg_type_code = TYPE50_TYPE_CODE; 2135 + if (long_len <= 64) { 2136 + tmp_type50_msg->crb1.header.msg_len = TYPE50_CRB1_LEN; 2137 + tmp_type50_msg->crb1.keyblock_type = TYPE50_CRB1_FMT; 2138 + p_tgt = tmp_type50_msg->crb1.p; 2139 + p_tgt_len = sizeof(tmp_type50_msg->crb1.p); 2140 + q_tgt = tmp_type50_msg->crb1.q; 2141 + q_tgt_len = sizeof(tmp_type50_msg->crb1.q); 2142 + dp_tgt = tmp_type50_msg->crb1.dp; 2143 + dp_tgt_len = sizeof(tmp_type50_msg->crb1.dp); 2144 + dq_tgt = tmp_type50_msg->crb1.dq; 2145 + dq_tgt_len = sizeof(tmp_type50_msg->crb1.dq); 2146 + u_tgt = tmp_type50_msg->crb1.u; 2147 + u_tgt_len = sizeof(tmp_type50_msg->crb1.u); 2148 + inp_tgt = tmp_type50_msg->crb1.message; 2149 + inp_tgt_len = sizeof(tmp_type50_msg->crb1.message); 2150 + } else { 2151 + tmp_type50_msg->crb2.header.msg_len = TYPE50_CRB2_LEN; 2152 + tmp_type50_msg->crb2.keyblock_type = TYPE50_CRB2_FMT; 2153 + p_tgt = tmp_type50_msg->crb2.p; 2154 + p_tgt_len = sizeof(tmp_type50_msg->crb2.p); 2155 + q_tgt = tmp_type50_msg->crb2.q; 2156 + q_tgt_len = sizeof(tmp_type50_msg->crb2.q); 2157 + dp_tgt = tmp_type50_msg->crb2.dp; 2158 + dp_tgt_len = sizeof(tmp_type50_msg->crb2.dp); 2159 + dq_tgt = tmp_type50_msg->crb2.dq; 2160 + dq_tgt_len = sizeof(tmp_type50_msg->crb2.dq); 2161 + u_tgt = tmp_type50_msg->crb2.u; 2162 + u_tgt_len = sizeof(tmp_type50_msg->crb2.u); 2163 + inp_tgt = tmp_type50_msg->crb2.message; 2164 + inp_tgt_len = sizeof(tmp_type50_msg->crb2.message); 2165 + } 2166 + 2167 + p_tgt += (p_tgt_len - long_len); 2168 + if (copy_from_user(p_tgt, icaMsg_p->np_prime + long_offset, long_len)) 2169 + return SEN_RELEASED; 2170 + if (is_empty(p_tgt, long_len)) 2171 + return SEN_USER_ERROR; 2172 + q_tgt += (q_tgt_len - short_len); 2173 + if (copy_from_user(q_tgt, icaMsg_p->nq_prime, short_len)) 2174 + return SEN_RELEASED; 2175 + if (is_empty(q_tgt, short_len)) 2176 + return SEN_USER_ERROR; 2177 + dp_tgt += (dp_tgt_len - long_len); 2178 + if (copy_from_user(dp_tgt, icaMsg_p->bp_key + long_offset, long_len)) 2179 + return SEN_RELEASED; 2180 + if (is_empty(dp_tgt, long_len)) 2181 + return SEN_USER_ERROR; 2182 + dq_tgt += (dq_tgt_len - short_len); 2183 + if (copy_from_user(dq_tgt, icaMsg_p->bq_key, short_len)) 2184 + return SEN_RELEASED; 2185 + if (is_empty(dq_tgt, short_len)) 2186 + return SEN_USER_ERROR; 2187 + u_tgt += (u_tgt_len - long_len); 2188 + if (copy_from_user(u_tgt, icaMsg_p->u_mult_inv + long_offset, long_len)) 2189 + return SEN_RELEASED; 2190 + if (is_empty(u_tgt, long_len)) 2191 + return SEN_USER_ERROR; 2192 + inp_tgt += (inp_tgt_len - mod_len); 2193 + if (copy_from_user(inp_tgt, icaMsg_p->inputdata, mod_len)) 2194 + return SEN_RELEASED; 2195 + if (is_empty(inp_tgt, mod_len)) 2196 + return SEN_USER_ERROR; 2197 + 2198 + *z90cMsg_l_p = tmp_size - CALLER_HEADER; 2199 + 2200 + return 0; 2201 + } 2202 + 2129 2203 int 2130 2204 convert_request(unsigned char *buffer, int func, unsigned short function, 2131 2205 int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p) ··· 2339 2071 cdx, msg_l_p, (struct type6_msg *) msg_p, 2340 2072 dev_type); 2341 2073 } 2074 + if (dev_type == CEX2A) { 2075 + if (func == ICARSACRT) 2076 + return ICACRT_msg_to_type50CRT_msg( 2077 + (struct ica_rsa_modexpo_crt *) buffer, 2078 + msg_l_p, (union type50_msg *) msg_p); 2079 + else 2080 + return ICAMEX_msg_to_type50MEX_msg( 2081 + (struct ica_rsa_modexpo *) buffer, 2082 + msg_l_p, (union type50_msg *) msg_p); 2083 + } 2342 2084 2343 2085 return 0; 2344 2086 } ··· 2359 2081 { 2360 2082 if (!ext_bitlens_msg_count) { 2361 2083 PRINTK("Unable to use coprocessors for extended bitlengths. " 2362 - "Using PCICAs (if present) for extended bitlengths. " 2363 - "This is not an error.\n"); 2084 + "Using PCICAs/CEX2As (if present) for extended " 2085 + "bitlengths. This is not an error.\n"); 2364 2086 ext_bitlens_msg_count++; 2365 2087 } 2366 2088 ext_bitlens = 0; ··· 2372 2094 { 2373 2095 struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer; 2374 2096 struct error_hdr *errh_p = (struct error_hdr *) response; 2097 + struct type80_hdr *t80h_p = (struct type80_hdr *) response; 2375 2098 struct type84_hdr *t84h_p = (struct type84_hdr *) response; 2376 2099 struct type86_fmt2_msg *t86m_p = (struct type86_fmt2_msg *) response; 2377 2100 int reply_code, service_rc, service_rs, src_l; ··· 2387 2108 src_l = 0; 2388 2109 switch (errh_p->type) { 2389 2110 case TYPE82_RSP_CODE: 2111 + case TYPE88_RSP_CODE: 2390 2112 reply_code = errh_p->reply_code; 2391 2113 src_p = (unsigned char *)errh_p; 2392 2114 PRINTK("Hardware error: Type %02X Message Header: " ··· 2395 2115 errh_p->type, 2396 2116 src_p[0], src_p[1], src_p[2], src_p[3], 2397 2117 src_p[4], src_p[5], src_p[6], src_p[7]); 2118 + break; 2119 + case TYPE80_RSP_CODE: 2120 + src_l = icaMsg_p->outputdatalength; 2121 + src_p = response + (int)t80h_p->len - src_l; 2398 2122 break; 2399 2123 case TYPE84_RSP_CODE: 2400 2124 src_l = icaMsg_p->outputdatalength; ··· 2486 2202 if (reply_code) 2487 2203 switch (reply_code) { 2488 2204 case REP82_ERROR_OPERAND_INVALID: 2205 + case REP88_ERROR_MESSAGE_MALFORMD: 2489 2206 return REC_OPERAND_INV; 2490 2207 case REP82_ERROR_OPERAND_SIZE: 2491 2208 return REC_OPERAND_SIZE;
+76 -35
drivers/s390/crypto/z90main.c
··· 228 228 */ 229 229 struct device { 230 230 int dev_type; // PCICA, PCICC, PCIXCC_MCL2, 231 - // PCIXCC_MCL3, CEX2C 231 + // PCIXCC_MCL3, CEX2C, CEX2A 232 232 enum devstat dev_stat; // current device status 233 233 int dev_self_x; // Index in array 234 234 int disabled; // Set when device is in error ··· 295 295 /** 296 296 * Function prototypes from z90hardware.c 297 297 */ 298 - enum hdstat query_online(int, int, int, int *, int *); 299 - enum devstat reset_device(int, int, int); 300 - enum devstat send_to_AP(int, int, int, unsigned char *); 301 - enum devstat receive_from_AP(int, int, int, unsigned char *, unsigned char *); 302 - int convert_request(unsigned char *, int, short, int, int, int *, 303 - unsigned char *); 304 - int convert_response(unsigned char *, unsigned char *, int *, unsigned char *); 298 + enum hdstat query_online(int deviceNr, int cdx, int resetNr, int *q_depth, 299 + int *dev_type); 300 + enum devstat reset_device(int deviceNr, int cdx, int resetNr); 301 + enum devstat send_to_AP(int dev_nr, int cdx, int msg_len, unsigned char *msg_ext); 302 + enum devstat receive_from_AP(int dev_nr, int cdx, int resplen, 303 + unsigned char *resp, unsigned char *psmid); 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 310 * Low level function prototypes 308 311 */ 309 - static int create_z90crypt(int *); 310 - static int refresh_z90crypt(int *); 311 - static int find_crypto_devices(struct status *); 312 - static int create_crypto_device(int); 313 - static int destroy_crypto_device(int); 312 + static int create_z90crypt(int *cdx_p); 313 + static int refresh_z90crypt(int *cdx_p); 314 + static int find_crypto_devices(struct status *deviceMask); 315 + static int create_crypto_device(int index); 316 + static int destroy_crypto_device(int index); 314 317 static void destroy_z90crypt(void); 315 - static int refresh_index_array(struct status *, struct device_x *); 316 - static int probe_device_type(struct device *); 317 - static int probe_PCIXCC_type(struct device *); 318 + static int refresh_index_array(struct status *status_str, 319 + struct device_x *index_array); 320 + static int probe_device_type(struct device *devPtr); 321 + static int probe_PCIXCC_type(struct device *devPtr); 318 322 319 323 /** 320 324 * proc fs definitions ··· 429 425 MODULE_AUTHOR("zSeries Linux Crypto Team: Robert H. Burroughs, Eric D. Rossman" 430 426 "and Jochen Roehrig"); 431 427 MODULE_DESCRIPTION("zSeries Linux Cryptographic Coprocessor device driver, " 432 - "Copyright 2001, 2004 IBM Corporation"); 428 + "Copyright 2001, 2005 IBM Corporation"); 433 429 MODULE_LICENSE("GPL"); 434 430 module_param(domain, int, 0); 435 431 MODULE_PARM_DESC(domain, "domain index for device"); ··· 864 860 } 865 861 866 862 static inline int 863 + get_status_CEX2Acount(void) 864 + { 865 + return z90crypt.hdware_info->type_mask[CEX2A].st_count; 866 + } 867 + 868 + static inline int 867 869 get_status_requestq_count(void) 868 870 { 869 871 return requestq_count; ··· 1018 1008 select_device_type(int *dev_type_p, int bytelength) 1019 1009 { 1020 1010 static int count = 0; 1021 - int PCICA_avail, PCIXCC_MCL3_avail, CEX2C_avail, index_to_use; 1011 + int PCICA_avail, PCIXCC_MCL3_avail, CEX2C_avail, CEX2A_avail, 1012 + index_to_use; 1022 1013 struct status *stat; 1023 1014 if ((*dev_type_p != PCICC) && (*dev_type_p != PCICA) && 1024 1015 (*dev_type_p != PCIXCC_MCL2) && (*dev_type_p != PCIXCC_MCL3) && 1025 - (*dev_type_p != CEX2C) && (*dev_type_p != ANYDEV)) 1016 + (*dev_type_p != CEX2C) && (*dev_type_p != CEX2A) && 1017 + (*dev_type_p != ANYDEV)) 1026 1018 return -1; 1027 1019 if (*dev_type_p != ANYDEV) { 1028 1020 stat = &z90crypt.hdware_info->type_mask[*dev_type_p]; ··· 1034 1022 return -1; 1035 1023 } 1036 1024 1037 - /* Assumption: PCICA, PCIXCC_MCL3, and CEX2C are all similar in speed */ 1025 + /** 1026 + * Assumption: PCICA, PCIXCC_MCL3, CEX2C, and CEX2A are all similar in 1027 + * speed. 1028 + * 1029 + * PCICA and CEX2A do NOT co-exist, so it would be either one or the 1030 + * other present. 1031 + */ 1038 1032 stat = &z90crypt.hdware_info->type_mask[PCICA]; 1039 1033 PCICA_avail = stat->st_count - 1040 1034 (stat->disabled_count + stat->user_disabled_count); ··· 1050 1032 stat = &z90crypt.hdware_info->type_mask[CEX2C]; 1051 1033 CEX2C_avail = stat->st_count - 1052 1034 (stat->disabled_count + stat->user_disabled_count); 1053 - if (PCICA_avail || PCIXCC_MCL3_avail || CEX2C_avail) { 1035 + stat = &z90crypt.hdware_info->type_mask[CEX2A]; 1036 + CEX2A_avail = stat->st_count - 1037 + (stat->disabled_count + stat->user_disabled_count); 1038 + if (PCICA_avail || PCIXCC_MCL3_avail || CEX2C_avail || CEX2A_avail) { 1054 1039 /** 1055 - * bitlength is a factor, PCICA is the most capable, even with 1056 - * the new MCL for PCIXCC. 1040 + * bitlength is a factor, PCICA or CEX2A are the most capable, 1041 + * even with the new MCL for PCIXCC. 1057 1042 */ 1058 1043 if ((bytelength < PCIXCC_MIN_MOD_SIZE) || 1059 1044 (!ext_bitlens && (bytelength < OLD_PCIXCC_MIN_MOD_SIZE))) { 1060 - if (!PCICA_avail) 1061 - return -1; 1062 - else { 1045 + if (PCICA_avail) { 1063 1046 *dev_type_p = PCICA; 1064 1047 return 0; 1065 1048 } 1049 + if (CEX2A_avail) { 1050 + *dev_type_p = CEX2A; 1051 + return 0; 1052 + } 1053 + return -1; 1066 1054 } 1067 1055 1068 1056 index_to_use = count % (PCICA_avail + PCIXCC_MCL3_avail + 1069 - CEX2C_avail); 1057 + CEX2C_avail + CEX2A_avail); 1070 1058 if (index_to_use < PCICA_avail) 1071 1059 *dev_type_p = PCICA; 1072 1060 else if (index_to_use < (PCICA_avail + PCIXCC_MCL3_avail)) 1073 1061 *dev_type_p = PCIXCC_MCL3; 1074 - else 1062 + else if (index_to_use < (PCICA_avail + PCIXCC_MCL3_avail + 1063 + CEX2C_avail)) 1075 1064 *dev_type_p = CEX2C; 1065 + else 1066 + *dev_type_p = CEX2A; 1076 1067 count++; 1077 1068 return 0; 1078 1069 } ··· 1386 1359 1387 1360 if ((we_p->devtype != PCICC) && (we_p->devtype != PCICA) && 1388 1361 (we_p->devtype != PCIXCC_MCL2) && (we_p->devtype != PCIXCC_MCL3) && 1389 - (we_p->devtype != CEX2C)) 1362 + (we_p->devtype != CEX2C) && (we_p->devtype != CEX2A)) 1390 1363 return SEN_NOT_AVAIL; 1391 1364 1392 1365 memcpy(caller_p->caller_id, we_p->caller_id, ··· 1455 1428 1456 1429 if ((we_p->devtype != PCICA) && (we_p->devtype != PCICC) && 1457 1430 (we_p->devtype != PCIXCC_MCL2) && (we_p->devtype != PCIXCC_MCL3) && 1458 - (we_p->devtype != CEX2C) && (we_p->devtype != ANYDEV)) { 1431 + (we_p->devtype != CEX2C) && (we_p->devtype != CEX2A) && 1432 + (we_p->devtype != ANYDEV)) { 1459 1433 PRINTK("invalid device type\n"); 1460 1434 return SEN_USER_ERROR; 1461 1435 } ··· 1531 1503 1532 1504 function = PCI_FUNC_KEY_ENCRYPT; 1533 1505 switch (we_p->devtype) { 1534 - /* PCICA does everything with a simple RSA mod-expo operation */ 1506 + /* PCICA and CEX2A do everything with a simple RSA mod-expo operation */ 1535 1507 case PCICA: 1508 + case CEX2A: 1536 1509 function = PCI_FUNC_KEY_ENCRYPT; 1537 1510 break; 1538 1511 /** ··· 1691 1662 * trigger a fallback to software. 1692 1663 */ 1693 1664 case -EINVAL: 1694 - if (we_p->devtype != PCICA) 1665 + if ((we_p->devtype != PCICA) && 1666 + (we_p->devtype != CEX2A)) 1695 1667 rv = -EGETBUFF; 1696 1668 break; 1697 1669 case -ETIMEOUT: ··· 1805 1775 1806 1776 case Z90STAT_CEX2CCOUNT: 1807 1777 tempstat = get_status_CEX2Ccount(); 1778 + if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0) 1779 + ret = -EFAULT; 1780 + break; 1781 + 1782 + case Z90STAT_CEX2ACOUNT: 1783 + tempstat = get_status_CEX2Acount(); 1808 1784 if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0) 1809 1785 ret = -EFAULT; 1810 1786 break; ··· 2055 2019 get_status_PCIXCCMCL3count()); 2056 2020 len += sprintf(resp_buff+len, "CEX2C count: %d\n", 2057 2021 get_status_CEX2Ccount()); 2022 + len += sprintf(resp_buff+len, "CEX2A count: %d\n", 2023 + get_status_CEX2Acount()); 2058 2024 len += sprintf(resp_buff+len, "requestq count: %d\n", 2059 2025 get_status_requestq_count()); 2060 2026 len += sprintf(resp_buff+len, "pendingq count: %d\n", ··· 2064 2026 len += sprintf(resp_buff+len, "Total open handles: %d\n\n", 2065 2027 get_status_totalopen_count()); 2066 2028 len += sprinthx( 2067 - "Online devices: 1: PCICA, 2: PCICC, 3: PCIXCC (MCL2), " 2068 - "4: PCIXCC (MCL3), 5: CEX2C", 2029 + "Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) " 2030 + "4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A", 2069 2031 resp_buff+len, 2070 2032 get_status_status_mask(workarea), 2071 2033 Z90CRYPT_NUM_APS); ··· 2178 2140 case '3': // PCIXCC_MCL2 2179 2141 case '4': // PCIXCC_MCL3 2180 2142 case '5': // CEX2C 2143 + case '6': // CEX2A 2181 2144 j++; 2182 2145 break; 2183 2146 case 'd': ··· 3046 3007 z90crypt.hdware_info->device_type_array[index] = 4; 3047 3008 else if (deviceType == CEX2C) 3048 3009 z90crypt.hdware_info->device_type_array[index] = 5; 3049 - else 3010 + else if (deviceType == CEX2A) 3011 + z90crypt.hdware_info->device_type_array[index] = 6; 3012 + else // No idea how this would happen. 3050 3013 z90crypt.hdware_info->device_type_array[index] = -1; 3051 3014 } 3052 3015