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/s390/crypto/z90main.c | |
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/s390/crypto/z90main.c')
-rw-r--r-- | drivers/s390/crypto/z90main.c | 111 |
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 | */ |
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 | ||