aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto/z90main.c
diff options
context:
space:
mode:
authorEric Rossman <edrossma@us.ibm.com>2006-01-06 03:19:25 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:52 -0500
commit88fbf18399bde8f2900cf932acd40733dfa1effa (patch)
tree9b34bf8325e465fbf84df25028f0fd6a11971b5b /drivers/s390/crypto/z90main.c
parentfb6958a594da49ece869793e6ec163b89fc5f79f (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/s390/crypto/z90main.c')
-rw-r--r--drivers/s390/crypto/z90main.c111
1 files changed, 76 insertions, 35 deletions
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 */
229struct device { 229struct 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 */
298enum hdstat query_online(int, int, int, int *, int *); 298enum hdstat query_online(int deviceNr, int cdx, int resetNr, int *q_depth,
299enum devstat reset_device(int, int, int); 299 int *dev_type);
300enum devstat send_to_AP(int, int, int, unsigned char *); 300enum devstat reset_device(int deviceNr, int cdx, int resetNr);
301enum devstat receive_from_AP(int, int, int, unsigned char *, unsigned char *); 301enum devstat send_to_AP(int dev_nr, int cdx, int msg_len, unsigned char *msg_ext);
302int convert_request(unsigned char *, int, short, int, int, int *, 302enum devstat receive_from_AP(int dev_nr, int cdx, int resplen,
303 unsigned char *); 303 unsigned char *resp, unsigned char *psmid);
304int convert_response(unsigned char *, unsigned char *, int *, unsigned char *); 304int convert_request(unsigned char *buffer, int func, unsigned short function,
305 int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p);
306int 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 */
309static int create_z90crypt(int *); 312static int create_z90crypt(int *cdx_p);
310static int refresh_z90crypt(int *); 313static int refresh_z90crypt(int *cdx_p);
311static int find_crypto_devices(struct status *); 314static int find_crypto_devices(struct status *deviceMask);
312static int create_crypto_device(int); 315static int create_crypto_device(int index);
313static int destroy_crypto_device(int); 316static int destroy_crypto_device(int index);
314static void destroy_z90crypt(void); 317static void destroy_z90crypt(void);
315static int refresh_index_array(struct status *, struct device_x *); 318static int refresh_index_array(struct status *status_str,
316static int probe_device_type(struct device *); 319 struct device_x *index_array);
317static int probe_PCIXCC_type(struct device *); 320static int probe_device_type(struct device *devPtr);
321static 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 = {
425MODULE_AUTHOR("zSeries Linux Crypto Team: Robert H. Burroughs, Eric D. Rossman" 429MODULE_AUTHOR("zSeries Linux Crypto Team: Robert H. Burroughs, Eric D. Rossman"
426 "and Jochen Roehrig"); 430 "and Jochen Roehrig");
427MODULE_DESCRIPTION("zSeries Linux Cryptographic Coprocessor device driver, " 431MODULE_DESCRIPTION("zSeries Linux Cryptographic Coprocessor device driver, "
428 "Copyright 2001, 2004 IBM Corporation"); 432 "Copyright 2001, 2005 IBM Corporation");
429MODULE_LICENSE("GPL"); 433MODULE_LICENSE("GPL");
430module_param(domain, int, 0); 434module_param(domain, int, 0);
431MODULE_PARM_DESC(domain, "domain index for device"); 435MODULE_PARM_DESC(domain, "domain index for device");
@@ -860,6 +864,12 @@ get_status_CEX2Ccount(void)
860} 864}
861 865
862static inline int 866static inline int
867get_status_CEX2Acount(void)
868{
869 return z90crypt.hdware_info->type_mask[CEX2A].st_count;
870}
871
872static inline int
863get_status_requestq_count(void) 873get_status_requestq_count(void)
864{ 874{
865 return requestq_count; 875 return requestq_count;
@@ -1008,11 +1018,13 @@ static inline int
1008select_device_type(int *dev_type_p, int bytelength) 1018select_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