diff options
Diffstat (limited to 'drivers/s390/crypto/zcrypt_api.c')
-rw-r--r-- | drivers/s390/crypto/zcrypt_api.c | 158 |
1 files changed, 72 insertions, 86 deletions
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index c68be24e27d9..ba50fe02e572 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/miscdevice.h> | 33 | #include <linux/miscdevice.h> |
34 | #include <linux/fs.h> | 34 | #include <linux/fs.h> |
35 | #include <linux/proc_fs.h> | 35 | #include <linux/proc_fs.h> |
36 | #include <linux/seq_file.h> | ||
36 | #include <linux/compat.h> | 37 | #include <linux/compat.h> |
37 | #include <linux/smp_lock.h> | 38 | #include <linux/smp_lock.h> |
38 | #include <asm/atomic.h> | 39 | #include <asm/atomic.h> |
@@ -912,126 +913,105 @@ static struct miscdevice zcrypt_misc_device = { | |||
912 | */ | 913 | */ |
913 | static struct proc_dir_entry *zcrypt_entry; | 914 | static struct proc_dir_entry *zcrypt_entry; |
914 | 915 | ||
915 | static int sprintcl(unsigned char *outaddr, unsigned char *addr, | 916 | static void sprintcl(struct seq_file *m, unsigned char *addr, unsigned int len) |
916 | unsigned int len) | ||
917 | { | 917 | { |
918 | int hl, i; | 918 | int i; |
919 | 919 | ||
920 | hl = 0; | ||
921 | for (i = 0; i < len; i++) | 920 | for (i = 0; i < len; i++) |
922 | hl += sprintf(outaddr+hl, "%01x", (unsigned int) addr[i]); | 921 | seq_printf(m, "%01x", (unsigned int) addr[i]); |
923 | hl += sprintf(outaddr+hl, " "); | 922 | seq_putc(m, ' '); |
924 | return hl; | ||
925 | } | 923 | } |
926 | 924 | ||
927 | static int sprintrw(unsigned char *outaddr, unsigned char *addr, | 925 | static void sprintrw(struct seq_file *m, unsigned char *addr, unsigned int len) |
928 | unsigned int len) | ||
929 | { | 926 | { |
930 | int hl, inl, c, cx; | 927 | int inl, c, cx; |
931 | 928 | ||
932 | hl = sprintf(outaddr, " "); | 929 | seq_printf(m, " "); |
933 | inl = 0; | 930 | inl = 0; |
934 | for (c = 0; c < (len / 16); c++) { | 931 | for (c = 0; c < (len / 16); c++) { |
935 | hl += sprintcl(outaddr+hl, addr+inl, 16); | 932 | sprintcl(m, addr+inl, 16); |
936 | inl += 16; | 933 | inl += 16; |
937 | } | 934 | } |
938 | cx = len%16; | 935 | cx = len%16; |
939 | if (cx) { | 936 | if (cx) { |
940 | hl += sprintcl(outaddr+hl, addr+inl, cx); | 937 | sprintcl(m, addr+inl, cx); |
941 | inl += cx; | 938 | inl += cx; |
942 | } | 939 | } |
943 | hl += sprintf(outaddr+hl, "\n"); | 940 | seq_putc(m, '\n'); |
944 | return hl; | ||
945 | } | 941 | } |
946 | 942 | ||
947 | static int sprinthx(unsigned char *title, unsigned char *outaddr, | 943 | static void sprinthx(unsigned char *title, struct seq_file *m, |
948 | unsigned char *addr, unsigned int len) | 944 | unsigned char *addr, unsigned int len) |
949 | { | 945 | { |
950 | int hl, inl, r, rx; | 946 | int inl, r, rx; |
951 | 947 | ||
952 | hl = sprintf(outaddr, "\n%s\n", title); | 948 | seq_printf(m, "\n%s\n", title); |
953 | inl = 0; | 949 | inl = 0; |
954 | for (r = 0; r < (len / 64); r++) { | 950 | for (r = 0; r < (len / 64); r++) { |
955 | hl += sprintrw(outaddr+hl, addr+inl, 64); | 951 | sprintrw(m, addr+inl, 64); |
956 | inl += 64; | 952 | inl += 64; |
957 | } | 953 | } |
958 | rx = len % 64; | 954 | rx = len % 64; |
959 | if (rx) { | 955 | if (rx) { |
960 | hl += sprintrw(outaddr+hl, addr+inl, rx); | 956 | sprintrw(m, addr+inl, rx); |
961 | inl += rx; | 957 | inl += rx; |
962 | } | 958 | } |
963 | hl += sprintf(outaddr+hl, "\n"); | 959 | seq_putc(m, '\n'); |
964 | return hl; | ||
965 | } | 960 | } |
966 | 961 | ||
967 | static int sprinthx4(unsigned char *title, unsigned char *outaddr, | 962 | static void sprinthx4(unsigned char *title, struct seq_file *m, |
968 | unsigned int *array, unsigned int len) | 963 | unsigned int *array, unsigned int len) |
969 | { | 964 | { |
970 | int hl, r; | 965 | int r; |
971 | 966 | ||
972 | hl = sprintf(outaddr, "\n%s\n", title); | 967 | seq_printf(m, "\n%s\n", title); |
973 | for (r = 0; r < len; r++) { | 968 | for (r = 0; r < len; r++) { |
974 | if ((r % 8) == 0) | 969 | if ((r % 8) == 0) |
975 | hl += sprintf(outaddr+hl, " "); | 970 | seq_printf(m, " "); |
976 | hl += sprintf(outaddr+hl, "%08X ", array[r]); | 971 | seq_printf(m, "%08X ", array[r]); |
977 | if ((r % 8) == 7) | 972 | if ((r % 8) == 7) |
978 | hl += sprintf(outaddr+hl, "\n"); | 973 | seq_putc(m, '\n'); |
979 | } | 974 | } |
980 | hl += sprintf(outaddr+hl, "\n"); | 975 | seq_putc(m, '\n'); |
981 | return hl; | ||
982 | } | 976 | } |
983 | 977 | ||
984 | static int zcrypt_status_read(char *resp_buff, char **start, off_t offset, | 978 | static int zcrypt_proc_show(struct seq_file *m, void *v) |
985 | int count, int *eof, void *data) | ||
986 | { | 979 | { |
987 | unsigned char *workarea; | 980 | char workarea[sizeof(int) * AP_DEVICES]; |
988 | int len; | 981 | |
989 | 982 | seq_printf(m, "\nzcrypt version: %d.%d.%d\n", | |
990 | len = 0; | 983 | ZCRYPT_VERSION, ZCRYPT_RELEASE, ZCRYPT_VARIANT); |
991 | 984 | seq_printf(m, "Cryptographic domain: %d\n", ap_domain_index); | |
992 | /* resp_buff is a page. Use the right half for a work area */ | 985 | seq_printf(m, "Total device count: %d\n", zcrypt_device_count); |
993 | workarea = resp_buff + 2000; | 986 | seq_printf(m, "PCICA count: %d\n", zcrypt_count_type(ZCRYPT_PCICA)); |
994 | len += sprintf(resp_buff + len, "\nzcrypt version: %d.%d.%d\n", | 987 | seq_printf(m, "PCICC count: %d\n", zcrypt_count_type(ZCRYPT_PCICC)); |
995 | ZCRYPT_VERSION, ZCRYPT_RELEASE, ZCRYPT_VARIANT); | 988 | seq_printf(m, "PCIXCC MCL2 count: %d\n", |
996 | len += sprintf(resp_buff + len, "Cryptographic domain: %d\n", | 989 | zcrypt_count_type(ZCRYPT_PCIXCC_MCL2)); |
997 | ap_domain_index); | 990 | seq_printf(m, "PCIXCC MCL3 count: %d\n", |
998 | len += sprintf(resp_buff + len, "Total device count: %d\n", | 991 | zcrypt_count_type(ZCRYPT_PCIXCC_MCL3)); |
999 | zcrypt_device_count); | 992 | seq_printf(m, "CEX2C count: %d\n", zcrypt_count_type(ZCRYPT_CEX2C)); |
1000 | len += sprintf(resp_buff + len, "PCICA count: %d\n", | 993 | seq_printf(m, "CEX2A count: %d\n", zcrypt_count_type(ZCRYPT_CEX2A)); |
1001 | zcrypt_count_type(ZCRYPT_PCICA)); | 994 | seq_printf(m, "CEX3C count: %d\n", zcrypt_count_type(ZCRYPT_CEX3C)); |
1002 | len += sprintf(resp_buff + len, "PCICC count: %d\n", | 995 | seq_printf(m, "CEX3A count: %d\n", zcrypt_count_type(ZCRYPT_CEX3A)); |
1003 | zcrypt_count_type(ZCRYPT_PCICC)); | 996 | seq_printf(m, "requestq count: %d\n", zcrypt_requestq_count()); |
1004 | len += sprintf(resp_buff + len, "PCIXCC MCL2 count: %d\n", | 997 | seq_printf(m, "pendingq count: %d\n", zcrypt_pendingq_count()); |
1005 | zcrypt_count_type(ZCRYPT_PCIXCC_MCL2)); | 998 | seq_printf(m, "Total open handles: %d\n\n", |
1006 | len += sprintf(resp_buff + len, "PCIXCC MCL3 count: %d\n", | 999 | atomic_read(&zcrypt_open_count)); |
1007 | zcrypt_count_type(ZCRYPT_PCIXCC_MCL3)); | ||
1008 | len += sprintf(resp_buff + len, "CEX2C count: %d\n", | ||
1009 | zcrypt_count_type(ZCRYPT_CEX2C)); | ||
1010 | len += sprintf(resp_buff + len, "CEX2A count: %d\n", | ||
1011 | zcrypt_count_type(ZCRYPT_CEX2A)); | ||
1012 | len += sprintf(resp_buff + len, "CEX3C count: %d\n", | ||
1013 | zcrypt_count_type(ZCRYPT_CEX3C)); | ||
1014 | len += sprintf(resp_buff + len, "CEX3A count: %d\n", | ||
1015 | zcrypt_count_type(ZCRYPT_CEX3A)); | ||
1016 | len += sprintf(resp_buff + len, "requestq count: %d\n", | ||
1017 | zcrypt_requestq_count()); | ||
1018 | len += sprintf(resp_buff + len, "pendingq count: %d\n", | ||
1019 | zcrypt_pendingq_count()); | ||
1020 | len += sprintf(resp_buff + len, "Total open handles: %d\n\n", | ||
1021 | atomic_read(&zcrypt_open_count)); | ||
1022 | zcrypt_status_mask(workarea); | 1000 | zcrypt_status_mask(workarea); |
1023 | len += sprinthx("Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) " | 1001 | sprinthx("Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) " |
1024 | "4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A 7=CEX3C 8=CEX3A", | 1002 | "4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A 7=CEX3C 8=CEX3A", |
1025 | resp_buff+len, workarea, AP_DEVICES); | 1003 | m, workarea, AP_DEVICES); |
1026 | zcrypt_qdepth_mask(workarea); | 1004 | zcrypt_qdepth_mask(workarea); |
1027 | len += sprinthx("Waiting work element counts", | 1005 | sprinthx("Waiting work element counts", m, workarea, AP_DEVICES); |
1028 | resp_buff+len, workarea, AP_DEVICES); | ||
1029 | zcrypt_perdev_reqcnt((int *) workarea); | 1006 | zcrypt_perdev_reqcnt((int *) workarea); |
1030 | len += sprinthx4("Per-device successfully completed request counts", | 1007 | sprinthx4("Per-device successfully completed request counts", |
1031 | resp_buff+len,(unsigned int *) workarea, AP_DEVICES); | 1008 | m, (unsigned int *) workarea, AP_DEVICES); |
1032 | *eof = 1; | 1009 | return 0; |
1033 | memset((void *) workarea, 0x00, AP_DEVICES * sizeof(unsigned int)); | 1010 | } |
1034 | return len; | 1011 | |
1012 | static int zcrypt_proc_open(struct inode *inode, struct file *file) | ||
1013 | { | ||
1014 | return single_open(file, zcrypt_proc_show, NULL); | ||
1035 | } | 1015 | } |
1036 | 1016 | ||
1037 | static void zcrypt_disable_card(int index) | 1017 | static void zcrypt_disable_card(int index) |
@@ -1061,11 +1041,11 @@ static void zcrypt_enable_card(int index) | |||
1061 | spin_unlock_bh(&zcrypt_device_lock); | 1041 | spin_unlock_bh(&zcrypt_device_lock); |
1062 | } | 1042 | } |
1063 | 1043 | ||
1064 | static int zcrypt_status_write(struct file *file, const char __user *buffer, | 1044 | static ssize_t zcrypt_proc_write(struct file *file, const char __user *buffer, |
1065 | unsigned long count, void *data) | 1045 | size_t count, loff_t *pos) |
1066 | { | 1046 | { |
1067 | unsigned char *lbuf, *ptr; | 1047 | unsigned char *lbuf, *ptr; |
1068 | unsigned long local_count; | 1048 | size_t local_count; |
1069 | int j; | 1049 | int j; |
1070 | 1050 | ||
1071 | if (count <= 0) | 1051 | if (count <= 0) |
@@ -1115,6 +1095,15 @@ out: | |||
1115 | return count; | 1095 | return count; |
1116 | } | 1096 | } |
1117 | 1097 | ||
1098 | static const struct file_operations zcrypt_proc_fops = { | ||
1099 | .owner = THIS_MODULE, | ||
1100 | .open = zcrypt_proc_open, | ||
1101 | .read = seq_read, | ||
1102 | .llseek = seq_lseek, | ||
1103 | .release = single_release, | ||
1104 | .write = zcrypt_proc_write, | ||
1105 | }; | ||
1106 | |||
1118 | static int zcrypt_rng_device_count; | 1107 | static int zcrypt_rng_device_count; |
1119 | static u32 *zcrypt_rng_buffer; | 1108 | static u32 *zcrypt_rng_buffer; |
1120 | static int zcrypt_rng_buffer_index; | 1109 | static int zcrypt_rng_buffer_index; |
@@ -1197,14 +1186,11 @@ int __init zcrypt_api_init(void) | |||
1197 | goto out; | 1186 | goto out; |
1198 | 1187 | ||
1199 | /* Set up the proc file system */ | 1188 | /* Set up the proc file system */ |
1200 | zcrypt_entry = create_proc_entry("driver/z90crypt", 0644, NULL); | 1189 | zcrypt_entry = proc_create("driver/z90crypt", 0644, NULL, &zcrypt_proc_fops); |
1201 | if (!zcrypt_entry) { | 1190 | if (!zcrypt_entry) { |
1202 | rc = -ENOMEM; | 1191 | rc = -ENOMEM; |
1203 | goto out_misc; | 1192 | goto out_misc; |
1204 | } | 1193 | } |
1205 | zcrypt_entry->data = NULL; | ||
1206 | zcrypt_entry->read_proc = zcrypt_status_read; | ||
1207 | zcrypt_entry->write_proc = zcrypt_status_write; | ||
1208 | 1194 | ||
1209 | return 0; | 1195 | return 0; |
1210 | 1196 | ||