aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto/zcrypt_pcixcc.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/s390/crypto/zcrypt_pcixcc.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/s390/crypto/zcrypt_pcixcc.c')
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index 5677b40e4ac0..510fab4577d4 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -30,6 +30,7 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/err.h> 31#include <linux/err.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/slab.h>
33#include <asm/atomic.h> 34#include <asm/atomic.h>
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
35 36
@@ -43,10 +44,13 @@
43#define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */ 44#define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */
44#define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */ 45#define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */
45#define PCIXCC_MAX_MOD_SIZE 256 /* 2048 bits */ 46#define PCIXCC_MAX_MOD_SIZE 256 /* 2048 bits */
47#define CEX3C_MIN_MOD_SIZE PCIXCC_MIN_MOD_SIZE
48#define CEX3C_MAX_MOD_SIZE PCIXCC_MAX_MOD_SIZE
46 49
47#define PCIXCC_MCL2_SPEED_RATING 7870 /* FIXME: needs finetuning */ 50#define PCIXCC_MCL2_SPEED_RATING 7870
48#define PCIXCC_MCL3_SPEED_RATING 7870 51#define PCIXCC_MCL3_SPEED_RATING 7870
49#define CEX2C_SPEED_RATING 8540 52#define CEX2C_SPEED_RATING 7000
53#define CEX3C_SPEED_RATING 6500 /* FIXME: needs finetuning */
50 54
51#define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c /* max size type6 v2 crt message */ 55#define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c /* max size type6 v2 crt message */
52#define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */ 56#define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */
@@ -72,7 +76,7 @@ struct response_type {
72static struct ap_device_id zcrypt_pcixcc_ids[] = { 76static struct ap_device_id zcrypt_pcixcc_ids[] = {
73 { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) }, 77 { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
74 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) }, 78 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
75 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C2) }, 79 { AP_DEVICE(AP_DEVICE_TYPE_CEX3C) },
76 { /* end of list */ }, 80 { /* end of list */ },
77}; 81};
78 82
@@ -326,6 +330,11 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
326 function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len; 330 function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
327 memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code)); 331 memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
328 332
333 if (memcmp(function_code, "US", 2) == 0)
334 ap_msg->special = 1;
335 else
336 ap_msg->special = 0;
337
329 /* copy data block */ 338 /* copy data block */
330 if (xcRB->request_data_length && 339 if (xcRB->request_data_length &&
331 copy_from_user(req_data, xcRB->request_data_address, 340 copy_from_user(req_data, xcRB->request_data_address,
@@ -462,6 +471,8 @@ static int convert_type86_ica(struct zcrypt_device *zdev,
462 } 471 }
463 if (service_rc == 12 && service_rs == 769) 472 if (service_rc == 12 && service_rs == 769)
464 return -EINVAL; 473 return -EINVAL;
474 if (service_rc == 8 && service_rs == 72)
475 return -EINVAL;
465 zdev->online = 0; 476 zdev->online = 0;
466 return -EAGAIN; /* repeat the request on a different device. */ 477 return -EAGAIN; /* repeat the request on a different device. */
467 } 478 }
@@ -688,6 +699,7 @@ static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
688 }; 699 };
689 int rc; 700 int rc;
690 701
702 ap_init_message(&ap_msg);
691 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); 703 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
692 if (!ap_msg.message) 704 if (!ap_msg.message)
693 return -ENOMEM; 705 return -ENOMEM;
@@ -727,6 +739,7 @@ static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
727 }; 739 };
728 int rc; 740 int rc;
729 741
742 ap_init_message(&ap_msg);
730 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); 743 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
731 if (!ap_msg.message) 744 if (!ap_msg.message)
732 return -ENOMEM; 745 return -ENOMEM;
@@ -766,6 +779,7 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
766 }; 779 };
767 int rc; 780 int rc;
768 781
782 ap_init_message(&ap_msg);
769 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); 783 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
770 if (!ap_msg.message) 784 if (!ap_msg.message)
771 return -ENOMEM; 785 return -ENOMEM;
@@ -805,6 +819,7 @@ static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev,
805 }; 819 };
806 int rc; 820 int rc;
807 821
822 ap_init_message(&ap_msg);
808 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); 823 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
809 if (!ap_msg.message) 824 if (!ap_msg.message)
810 return -ENOMEM; 825 return -ENOMEM;
@@ -972,6 +987,7 @@ static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
972 } __attribute__((packed)) *reply; 987 } __attribute__((packed)) *reply;
973 int rc, i; 988 int rc, i;
974 989
990 ap_init_message(&ap_msg);
975 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); 991 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
976 if (!ap_msg.message) 992 if (!ap_msg.message)
977 return -ENOMEM; 993 return -ENOMEM;
@@ -1016,14 +1032,15 @@ out_free:
1016static int zcrypt_pcixcc_probe(struct ap_device *ap_dev) 1032static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
1017{ 1033{
1018 struct zcrypt_device *zdev; 1034 struct zcrypt_device *zdev;
1019 int rc; 1035 int rc = 0;
1020 1036
1021 zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE); 1037 zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
1022 if (!zdev) 1038 if (!zdev)
1023 return -ENOMEM; 1039 return -ENOMEM;
1024 zdev->ap_dev = ap_dev; 1040 zdev->ap_dev = ap_dev;
1025 zdev->online = 1; 1041 zdev->online = 1;
1026 if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) { 1042 switch (ap_dev->device_type) {
1043 case AP_DEVICE_TYPE_PCIXCC:
1027 rc = zcrypt_pcixcc_mcl(ap_dev); 1044 rc = zcrypt_pcixcc_mcl(ap_dev);
1028 if (rc < 0) { 1045 if (rc < 0) {
1029 zcrypt_device_free(zdev); 1046 zcrypt_device_free(zdev);
@@ -1041,13 +1058,25 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
1041 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE; 1058 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1042 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE; 1059 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1043 } 1060 }
1044 } else { 1061 break;
1062 case AP_DEVICE_TYPE_CEX2C:
1045 zdev->user_space_type = ZCRYPT_CEX2C; 1063 zdev->user_space_type = ZCRYPT_CEX2C;
1046 zdev->type_string = "CEX2C"; 1064 zdev->type_string = "CEX2C";
1047 zdev->speed_rating = CEX2C_SPEED_RATING; 1065 zdev->speed_rating = CEX2C_SPEED_RATING;
1048 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE; 1066 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1049 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE; 1067 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1068 break;
1069 case AP_DEVICE_TYPE_CEX3C:
1070 zdev->user_space_type = ZCRYPT_CEX3C;
1071 zdev->type_string = "CEX3C";
1072 zdev->speed_rating = CEX3C_SPEED_RATING;
1073 zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
1074 zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
1075 break;
1076 default:
1077 goto out_free;
1050 } 1078 }
1079
1051 rc = zcrypt_pcixcc_rng_supported(ap_dev); 1080 rc = zcrypt_pcixcc_rng_supported(ap_dev);
1052 if (rc < 0) { 1081 if (rc < 0) {
1053 zcrypt_device_free(zdev); 1082 zcrypt_device_free(zdev);