diff options
-rw-r--r-- | drivers/s390/crypto/z90common.h | 3 | ||||
-rw-r--r-- | drivers/s390/crypto/z90hardware.c | 127 | ||||
-rw-r--r-- | drivers/s390/crypto/z90main.c | 246 |
3 files changed, 106 insertions, 270 deletions
diff --git a/drivers/s390/crypto/z90common.h b/drivers/s390/crypto/z90common.h index bcabac7a7c46..e319e78b5ea2 100644 --- a/drivers/s390/crypto/z90common.h +++ b/drivers/s390/crypto/z90common.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #ifndef _Z90COMMON_H_ | 27 | #ifndef _Z90COMMON_H_ |
28 | #define _Z90COMMON_H_ | 28 | #define _Z90COMMON_H_ |
29 | 29 | ||
30 | #define VERSION_Z90COMMON_H "$Revision: 1.16 $" | 30 | #define VERSION_Z90COMMON_H "$Revision: 1.17 $" |
31 | 31 | ||
32 | 32 | ||
33 | #define RESPBUFFSIZE 256 | 33 | #define RESPBUFFSIZE 256 |
@@ -164,5 +164,4 @@ struct CPRBX { | |||
164 | #define UMIN(a,b) ((a) < (b) ? (a) : (b)) | 164 | #define UMIN(a,b) ((a) < (b) ? (a) : (b)) |
165 | #define IS_EVEN(x) ((x) == (2 * ((x) / 2))) | 165 | #define IS_EVEN(x) ((x) == (2 * ((x) / 2))) |
166 | 166 | ||
167 | |||
168 | #endif | 167 | #endif |
diff --git a/drivers/s390/crypto/z90hardware.c b/drivers/s390/crypto/z90hardware.c index beb6a5e0da22..c215e0889736 100644 --- a/drivers/s390/crypto/z90hardware.c +++ b/drivers/s390/crypto/z90hardware.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include "z90crypt.h" | 32 | #include "z90crypt.h" |
33 | #include "z90common.h" | 33 | #include "z90common.h" |
34 | 34 | ||
35 | #define VERSION_Z90HARDWARE_C "$Revision: 1.33 $" | 35 | #define VERSION_Z90HARDWARE_C "$Revision: 1.34 $" |
36 | 36 | ||
37 | char z90hardware_version[] __initdata = | 37 | char z90hardware_version[] __initdata = |
38 | "z90hardware.o (" VERSION_Z90HARDWARE_C "/" | 38 | "z90hardware.o (" VERSION_Z90HARDWARE_C "/" |
@@ -283,48 +283,6 @@ struct type6_msg { | |||
283 | struct CPRB CPRB; | 283 | struct CPRB CPRB; |
284 | }; | 284 | }; |
285 | 285 | ||
286 | union request_msg { | ||
287 | union type4_msg t4msg; | ||
288 | struct type6_msg t6msg; | ||
289 | }; | ||
290 | |||
291 | struct request_msg_ext { | ||
292 | int q_nr; | ||
293 | unsigned char *psmid; | ||
294 | union request_msg reqMsg; | ||
295 | }; | ||
296 | |||
297 | struct type82_hdr { | ||
298 | unsigned char reserved1; | ||
299 | unsigned char type; | ||
300 | unsigned char reserved2[2]; | ||
301 | unsigned char reply_code; | ||
302 | unsigned char reserved3[3]; | ||
303 | }; | ||
304 | |||
305 | #define TYPE82_RSP_CODE 0x82 | ||
306 | |||
307 | #define REPLY_ERROR_MACHINE_FAILURE 0x10 | ||
308 | #define REPLY_ERROR_PREEMPT_FAILURE 0x12 | ||
309 | #define REPLY_ERROR_CHECKPT_FAILURE 0x14 | ||
310 | #define REPLY_ERROR_MESSAGE_TYPE 0x20 | ||
311 | #define REPLY_ERROR_INVALID_COMM_CD 0x21 | ||
312 | #define REPLY_ERROR_INVALID_MSG_LEN 0x23 | ||
313 | #define REPLY_ERROR_RESERVD_FIELD 0x24 | ||
314 | #define REPLY_ERROR_FORMAT_FIELD 0x29 | ||
315 | #define REPLY_ERROR_INVALID_COMMAND 0x30 | ||
316 | #define REPLY_ERROR_MALFORMED_MSG 0x40 | ||
317 | #define REPLY_ERROR_RESERVED_FIELDO 0x50 | ||
318 | #define REPLY_ERROR_WORD_ALIGNMENT 0x60 | ||
319 | #define REPLY_ERROR_MESSAGE_LENGTH 0x80 | ||
320 | #define REPLY_ERROR_OPERAND_INVALID 0x82 | ||
321 | #define REPLY_ERROR_OPERAND_SIZE 0x84 | ||
322 | #define REPLY_ERROR_EVEN_MOD_IN_OPND 0x85 | ||
323 | #define REPLY_ERROR_RESERVED_FIELD 0x88 | ||
324 | #define REPLY_ERROR_TRANSPORT_FAIL 0x90 | ||
325 | #define REPLY_ERROR_PACKET_TRUNCATED 0xA0 | ||
326 | #define REPLY_ERROR_ZERO_BUFFER_LEN 0xB0 | ||
327 | |||
328 | struct type86_hdr { | 286 | struct type86_hdr { |
329 | unsigned char reserved1; | 287 | unsigned char reserved1; |
330 | unsigned char type; | 288 | unsigned char type; |
@@ -338,7 +296,7 @@ struct type86_hdr { | |||
338 | #define TYPE86_FMT2 0x02 | 296 | #define TYPE86_FMT2 0x02 |
339 | 297 | ||
340 | struct type86_fmt2_msg { | 298 | struct type86_fmt2_msg { |
341 | struct type86_hdr hdr; | 299 | struct type86_hdr header; |
342 | unsigned char reserved[4]; | 300 | unsigned char reserved[4]; |
343 | unsigned char apfs[4]; | 301 | unsigned char apfs[4]; |
344 | unsigned int count1; | 302 | unsigned int count1; |
@@ -538,6 +496,8 @@ static struct function_and_rules_block static_pke_function_and_rulesX = { | |||
538 | {'M','R','P',' ',' ',' ',' ',' '} | 496 | {'M','R','P',' ',' ',' ',' ',' '} |
539 | }; | 497 | }; |
540 | 498 | ||
499 | static unsigned char static_PKE_function_code[2] = {0x50, 0x4B}; | ||
500 | |||
541 | struct T6_keyBlock_hdrX { | 501 | struct T6_keyBlock_hdrX { |
542 | unsigned short blen; | 502 | unsigned short blen; |
543 | unsigned short ulen; | 503 | unsigned short ulen; |
@@ -688,9 +648,38 @@ static struct cca_public_sec static_cca_pub_sec = { | |||
688 | #define RESPONSE_CPRB_SIZE 0x000006B8 | 648 | #define RESPONSE_CPRB_SIZE 0x000006B8 |
689 | #define RESPONSE_CPRBX_SIZE 0x00000724 | 649 | #define RESPONSE_CPRBX_SIZE 0x00000724 |
690 | 650 | ||
691 | #define CALLER_HEADER 12 | 651 | struct error_hdr { |
652 | unsigned char reserved1; | ||
653 | unsigned char type; | ||
654 | unsigned char reserved2[2]; | ||
655 | unsigned char reply_code; | ||
656 | unsigned char reserved3[3]; | ||
657 | }; | ||
692 | 658 | ||
693 | static unsigned char static_PKE_function_code[2] = {0x50, 0x4B}; | 659 | #define TYPE82_RSP_CODE 0x82 |
660 | |||
661 | #define REP82_ERROR_MACHINE_FAILURE 0x10 | ||
662 | #define REP82_ERROR_PREEMPT_FAILURE 0x12 | ||
663 | #define REP82_ERROR_CHECKPT_FAILURE 0x14 | ||
664 | #define REP82_ERROR_MESSAGE_TYPE 0x20 | ||
665 | #define REP82_ERROR_INVALID_COMM_CD 0x21 | ||
666 | #define REP82_ERROR_INVALID_MSG_LEN 0x23 | ||
667 | #define REP82_ERROR_RESERVD_FIELD 0x24 | ||
668 | #define REP82_ERROR_FORMAT_FIELD 0x29 | ||
669 | #define REP82_ERROR_INVALID_COMMAND 0x30 | ||
670 | #define REP82_ERROR_MALFORMED_MSG 0x40 | ||
671 | #define REP82_ERROR_RESERVED_FIELDO 0x50 | ||
672 | #define REP82_ERROR_WORD_ALIGNMENT 0x60 | ||
673 | #define REP82_ERROR_MESSAGE_LENGTH 0x80 | ||
674 | #define REP82_ERROR_OPERAND_INVALID 0x82 | ||
675 | #define REP82_ERROR_OPERAND_SIZE 0x84 | ||
676 | #define REP82_ERROR_EVEN_MOD_IN_OPND 0x85 | ||
677 | #define REP82_ERROR_RESERVED_FIELD 0x88 | ||
678 | #define REP82_ERROR_TRANSPORT_FAIL 0x90 | ||
679 | #define REP82_ERROR_PACKET_TRUNCATED 0xA0 | ||
680 | #define REP82_ERROR_ZERO_BUFFER_LEN 0xB0 | ||
681 | |||
682 | #define CALLER_HEADER 12 | ||
694 | 683 | ||
695 | static inline int | 684 | static inline int |
696 | testq(int q_nr, int *q_depth, int *dev_type, struct ap_status_word *stat) | 685 | testq(int q_nr, int *q_depth, int *dev_type, struct ap_status_word *stat) |
@@ -1212,9 +1201,9 @@ send_to_AP(int dev_nr, int cdx, int msg_len, unsigned char *msg_ext) | |||
1212 | struct ap_status_word stat_word; | 1201 | struct ap_status_word stat_word; |
1213 | enum devstat stat; | 1202 | enum devstat stat; |
1214 | int ccode; | 1203 | int ccode; |
1204 | u32 *q_nr_p = (u32 *)msg_ext; | ||
1215 | 1205 | ||
1216 | ((struct request_msg_ext *) msg_ext)->q_nr = | 1206 | *q_nr_p = (dev_nr << SKIP_BITL) + cdx; |
1217 | (dev_nr << SKIP_BITL) + cdx; | ||
1218 | PDEBUG("msg_len passed to sen: %d\n", msg_len); | 1207 | PDEBUG("msg_len passed to sen: %d\n", msg_len); |
1219 | PDEBUG("q number passed to sen: %02x%02x%02x%02x\n", | 1208 | PDEBUG("q number passed to sen: %02x%02x%02x%02x\n", |
1220 | msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3]); | 1209 | msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3]); |
@@ -2104,7 +2093,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2104 | int *respbufflen_p, unsigned char *resp_buff) | 2093 | int *respbufflen_p, unsigned char *resp_buff) |
2105 | { | 2094 | { |
2106 | struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer; | 2095 | struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer; |
2107 | struct type82_hdr *t82h_p = (struct type82_hdr *) response; | 2096 | struct error_hdr *errh_p = (struct error_hdr *) response; |
2108 | struct type84_hdr *t84h_p = (struct type84_hdr *) response; | 2097 | struct type84_hdr *t84h_p = (struct type84_hdr *) response; |
2109 | struct type86_fmt2_msg *t86m_p = (struct type86_fmt2_msg *) response; | 2098 | struct type86_fmt2_msg *t86m_p = (struct type86_fmt2_msg *) response; |
2110 | int reply_code, service_rc, service_rs, src_l; | 2099 | int reply_code, service_rc, service_rs, src_l; |
@@ -2117,12 +2106,13 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2117 | service_rc = 0; | 2106 | service_rc = 0; |
2118 | service_rs = 0; | 2107 | service_rs = 0; |
2119 | src_l = 0; | 2108 | src_l = 0; |
2120 | switch (t82h_p->type) { | 2109 | switch (errh_p->type) { |
2121 | case TYPE82_RSP_CODE: | 2110 | case TYPE82_RSP_CODE: |
2122 | reply_code = t82h_p->reply_code; | 2111 | reply_code = errh_p->reply_code; |
2123 | src_p = (unsigned char *)t82h_p; | 2112 | src_p = (unsigned char *)errh_p; |
2124 | PRINTK("Hardware error: Type 82 Message Header: " | 2113 | PRINTK("Hardware error: Type %02X Message Header: " |
2125 | "%02x%02x%02x%02x%02x%02x%02x%02x\n", | 2114 | "%02x%02x%02x%02x%02x%02x%02x%02x\n", |
2115 | errh_p->type, | ||
2126 | src_p[0], src_p[1], src_p[2], src_p[3], | 2116 | src_p[0], src_p[1], src_p[2], src_p[3], |
2127 | src_p[4], src_p[5], src_p[6], src_p[7]); | 2117 | src_p[4], src_p[5], src_p[6], src_p[7]); |
2128 | break; | 2118 | break; |
@@ -2131,7 +2121,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2131 | src_p = response + (int)t84h_p->len - src_l; | 2121 | src_p = response + (int)t84h_p->len - src_l; |
2132 | break; | 2122 | break; |
2133 | case TYPE86_RSP_CODE: | 2123 | case TYPE86_RSP_CODE: |
2134 | reply_code = t86m_p->hdr.reply_code; | 2124 | reply_code = t86m_p->header.reply_code; |
2135 | if (reply_code != 0) | 2125 | if (reply_code != 0) |
2136 | break; | 2126 | break; |
2137 | cprb_p = (struct CPRB *) | 2127 | cprb_p = (struct CPRB *) |
@@ -2143,6 +2133,9 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2143 | le2toI(cprb_p->ccp_rscode, &service_rs); | 2133 | le2toI(cprb_p->ccp_rscode, &service_rs); |
2144 | if ((service_rc == 8) && (service_rs == 66)) | 2134 | if ((service_rc == 8) && (service_rs == 66)) |
2145 | PDEBUG("Bad block format on PCICC\n"); | 2135 | PDEBUG("Bad block format on PCICC\n"); |
2136 | else if ((service_rc == 8) && (service_rs == 65)) | ||
2137 | PDEBUG("Probably an even modulus on " | ||
2138 | "PCICC\n"); | ||
2146 | else if ((service_rc == 8) && (service_rs == 770)) { | 2139 | else if ((service_rc == 8) && (service_rs == 770)) { |
2147 | PDEBUG("Invalid key length on PCICC\n"); | 2140 | PDEBUG("Invalid key length on PCICC\n"); |
2148 | unset_ext_bitlens(); | 2141 | unset_ext_bitlens(); |
@@ -2155,7 +2148,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2155 | return REC_USE_PCICA; | 2148 | return REC_USE_PCICA; |
2156 | } | 2149 | } |
2157 | else | 2150 | else |
2158 | PRINTK("service rc/rs: %d/%d\n", | 2151 | PRINTK("service rc/rs (PCICC): %d/%d\n", |
2159 | service_rc, service_rs); | 2152 | service_rc, service_rs); |
2160 | return REC_OPERAND_INV; | 2153 | return REC_OPERAND_INV; |
2161 | } | 2154 | } |
@@ -2169,7 +2162,10 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2169 | if (service_rc != 0) { | 2162 | if (service_rc != 0) { |
2170 | service_rs = (int) cprbx_p->ccp_rscode; | 2163 | service_rs = (int) cprbx_p->ccp_rscode; |
2171 | if ((service_rc == 8) && (service_rs == 66)) | 2164 | if ((service_rc == 8) && (service_rs == 66)) |
2172 | PDEBUG("Bad block format on PCXICC\n"); | 2165 | PDEBUG("Bad block format on PCIXCC\n"); |
2166 | else if ((service_rc == 8) && (service_rs == 65)) | ||
2167 | PDEBUG("Probably an even modulus on " | ||
2168 | "PCIXCC\n"); | ||
2173 | else if ((service_rc == 8) && (service_rs == 770)) { | 2169 | else if ((service_rc == 8) && (service_rs == 770)) { |
2174 | PDEBUG("Invalid key length on PCIXCC\n"); | 2170 | PDEBUG("Invalid key length on PCIXCC\n"); |
2175 | unset_ext_bitlens(); | 2171 | unset_ext_bitlens(); |
@@ -2182,7 +2178,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2182 | return REC_USE_PCICA; | 2178 | return REC_USE_PCICA; |
2183 | } | 2179 | } |
2184 | else | 2180 | else |
2185 | PRINTK("service rc/rs: %d/%d\n", | 2181 | PRINTK("service rc/rs (PCIXCC): %d/%d\n", |
2186 | service_rc, service_rs); | 2182 | service_rc, service_rs); |
2187 | return REC_OPERAND_INV; | 2183 | return REC_OPERAND_INV; |
2188 | } | 2184 | } |
@@ -2195,20 +2191,25 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2195 | } | 2191 | } |
2196 | break; | 2192 | break; |
2197 | default: | 2193 | default: |
2194 | src_p = (unsigned char *)errh_p; | ||
2195 | PRINTK("Unrecognized Message Header: " | ||
2196 | "%02x%02x%02x%02x%02x%02x%02x%02x\n", | ||
2197 | src_p[0], src_p[1], src_p[2], src_p[3], | ||
2198 | src_p[4], src_p[5], src_p[6], src_p[7]); | ||
2198 | return REC_BAD_MESSAGE; | 2199 | return REC_BAD_MESSAGE; |
2199 | } | 2200 | } |
2200 | 2201 | ||
2201 | if (reply_code) | 2202 | if (reply_code) |
2202 | switch (reply_code) { | 2203 | switch (reply_code) { |
2203 | case REPLY_ERROR_OPERAND_INVALID: | 2204 | case REP82_ERROR_OPERAND_INVALID: |
2204 | return REC_OPERAND_INV; | 2205 | return REC_OPERAND_INV; |
2205 | case REPLY_ERROR_OPERAND_SIZE: | 2206 | case REP82_ERROR_OPERAND_SIZE: |
2206 | return REC_OPERAND_SIZE; | 2207 | return REC_OPERAND_SIZE; |
2207 | case REPLY_ERROR_EVEN_MOD_IN_OPND: | 2208 | case REP82_ERROR_EVEN_MOD_IN_OPND: |
2208 | return REC_EVEN_MOD; | 2209 | return REC_EVEN_MOD; |
2209 | case REPLY_ERROR_MESSAGE_TYPE: | 2210 | case REP82_ERROR_MESSAGE_TYPE: |
2210 | return WRONG_DEVICE_TYPE; | 2211 | return WRONG_DEVICE_TYPE; |
2211 | case REPLY_ERROR_TRANSPORT_FAIL: | 2212 | case REP82_ERROR_TRANSPORT_FAIL: |
2212 | PRINTKW("Transport failed (APFS = %02X%02X%02X%02X)\n", | 2213 | PRINTKW("Transport failed (APFS = %02X%02X%02X%02X)\n", |
2213 | t86m_p->apfs[0], t86m_p->apfs[1], | 2214 | t86m_p->apfs[0], t86m_p->apfs[1], |
2214 | t86m_p->apfs[2], t86m_p->apfs[3]); | 2215 | t86m_p->apfs[2], t86m_p->apfs[3]); |
@@ -2229,7 +2230,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2229 | PDEBUG("Length returned = %d\n", src_l); | 2230 | PDEBUG("Length returned = %d\n", src_l); |
2230 | tgt_p = resp_buff + icaMsg_p->outputdatalength - src_l; | 2231 | tgt_p = resp_buff + icaMsg_p->outputdatalength - src_l; |
2231 | memcpy(tgt_p, src_p, src_l); | 2232 | memcpy(tgt_p, src_p, src_l); |
2232 | if ((t82h_p->type == TYPE86_RSP_CODE) && (resp_buff < tgt_p)) { | 2233 | if ((errh_p->type == TYPE86_RSP_CODE) && (resp_buff < tgt_p)) { |
2233 | memset(resp_buff, 0, icaMsg_p->outputdatalength - src_l); | 2234 | memset(resp_buff, 0, icaMsg_p->outputdatalength - src_l); |
2234 | if (pad_msg(resp_buff, icaMsg_p->outputdatalength, src_l)) | 2235 | if (pad_msg(resp_buff, icaMsg_p->outputdatalength, src_l)) |
2235 | return REC_INVALID_PAD; | 2236 | return REC_INVALID_PAD; |
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c index 9ec29bb41b28..6aeef3bacc33 100644 --- a/drivers/s390/crypto/z90main.c +++ b/drivers/s390/crypto/z90main.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/interrupt.h> // for tasklets | 32 | #include <linux/interrupt.h> // for tasklets |
33 | #include <linux/ioctl32.h> | 33 | #include <linux/ioctl32.h> |
34 | #include <linux/miscdevice.h> | ||
34 | #include <linux/module.h> | 35 | #include <linux/module.h> |
35 | #include <linux/moduleparam.h> | 36 | #include <linux/moduleparam.h> |
36 | #include <linux/kobject_uevent.h> | 37 | #include <linux/kobject_uevent.h> |
@@ -39,19 +40,8 @@ | |||
39 | #include <linux/version.h> | 40 | #include <linux/version.h> |
40 | #include "z90crypt.h" | 41 | #include "z90crypt.h" |
41 | #include "z90common.h" | 42 | #include "z90common.h" |
42 | #ifndef Z90CRYPT_USE_HOTPLUG | ||
43 | #include <linux/miscdevice.h> | ||
44 | #endif | ||
45 | |||
46 | #define VERSION_CODE(vers, rel, seq) (((vers)<<16) | ((rel)<<8) | (seq)) | ||
47 | #if LINUX_VERSION_CODE < VERSION_CODE(2,4,0) /* version < 2.4 */ | ||
48 | # error "This kernel is too old: not supported" | ||
49 | #endif | ||
50 | #if LINUX_VERSION_CODE > VERSION_CODE(2,7,0) /* version > 2.6 */ | ||
51 | # error "This kernel is too recent: not supported by this file" | ||
52 | #endif | ||
53 | 43 | ||
54 | #define VERSION_Z90MAIN_C "$Revision: 1.57 $" | 44 | #define VERSION_Z90MAIN_C "$Revision: 1.62 $" |
55 | 45 | ||
56 | static char z90main_version[] __initdata = | 46 | static char z90main_version[] __initdata = |
57 | "z90main.o (" VERSION_Z90MAIN_C "/" | 47 | "z90main.o (" VERSION_Z90MAIN_C "/" |
@@ -63,21 +53,12 @@ extern char z90hardware_version[]; | |||
63 | * Defaults that may be modified. | 53 | * Defaults that may be modified. |
64 | */ | 54 | */ |
65 | 55 | ||
66 | #ifndef Z90CRYPT_USE_HOTPLUG | ||
67 | /** | 56 | /** |
68 | * You can specify a different minor at compile time. | 57 | * You can specify a different minor at compile time. |
69 | */ | 58 | */ |
70 | #ifndef Z90CRYPT_MINOR | 59 | #ifndef Z90CRYPT_MINOR |
71 | #define Z90CRYPT_MINOR MISC_DYNAMIC_MINOR | 60 | #define Z90CRYPT_MINOR MISC_DYNAMIC_MINOR |
72 | #endif | 61 | #endif |
73 | #else | ||
74 | /** | ||
75 | * You can specify a different major at compile time. | ||
76 | */ | ||
77 | #ifndef Z90CRYPT_MAJOR | ||
78 | #define Z90CRYPT_MAJOR 0 | ||
79 | #endif | ||
80 | #endif | ||
81 | 62 | ||
82 | /** | 63 | /** |
83 | * You can specify a different domain at compile time or on the insmod | 64 | * You can specify a different domain at compile time or on the insmod |
@@ -97,7 +78,7 @@ extern char z90hardware_version[]; | |||
97 | * older than CLEANUPTIME seconds in the past. | 78 | * older than CLEANUPTIME seconds in the past. |
98 | */ | 79 | */ |
99 | #ifndef CLEANUPTIME | 80 | #ifndef CLEANUPTIME |
100 | #define CLEANUPTIME 20 | 81 | #define CLEANUPTIME 15 |
101 | #endif | 82 | #endif |
102 | 83 | ||
103 | /** | 84 | /** |
@@ -298,6 +279,10 @@ struct z90crypt { | |||
298 | * it contains the request; at READ, the response. The function | 279 | * it contains the request; at READ, the response. The function |
299 | * send_to_crypto_device converts the request to device-dependent | 280 | * send_to_crypto_device converts the request to device-dependent |
300 | * form and use the caller's OPEN-allocated buffer for the response. | 281 | * form and use the caller's OPEN-allocated buffer for the response. |
282 | * | ||
283 | * For the contents of caller_dev_dep_req and caller_dev_dep_req_p | ||
284 | * because that points to it, see the discussion in z90hardware.c. | ||
285 | * Search for "extended request message block". | ||
301 | */ | 286 | */ |
302 | struct caller { | 287 | struct caller { |
303 | int caller_buf_l; // length of original request | 288 | int caller_buf_l; // length of original request |
@@ -398,24 +383,9 @@ static int z90crypt_status_write(struct file *, const char __user *, | |||
398 | unsigned long, void *); | 383 | unsigned long, void *); |
399 | 384 | ||
400 | /** | 385 | /** |
401 | * Hotplug support | ||
402 | */ | ||
403 | |||
404 | #ifdef Z90CRYPT_USE_HOTPLUG | ||
405 | #define Z90CRYPT_HOTPLUG_ADD 1 | ||
406 | #define Z90CRYPT_HOTPLUG_REMOVE 2 | ||
407 | |||
408 | static void z90crypt_hotplug_event(int, int, int); | ||
409 | #endif | ||
410 | |||
411 | /** | ||
412 | * Storage allocated at initialization and used throughout the life of | 386 | * Storage allocated at initialization and used throughout the life of |
413 | * this insmod | 387 | * this insmod |
414 | */ | 388 | */ |
415 | #ifdef Z90CRYPT_USE_HOTPLUG | ||
416 | static int z90crypt_major = Z90CRYPT_MAJOR; | ||
417 | #endif | ||
418 | |||
419 | static int domain = DOMAIN_INDEX; | 389 | static int domain = DOMAIN_INDEX; |
420 | static struct z90crypt z90crypt; | 390 | static struct z90crypt z90crypt; |
421 | static int quiesce_z90crypt; | 391 | static int quiesce_z90crypt; |
@@ -444,14 +414,12 @@ static struct file_operations z90crypt_fops = { | |||
444 | .release = z90crypt_release | 414 | .release = z90crypt_release |
445 | }; | 415 | }; |
446 | 416 | ||
447 | #ifndef Z90CRYPT_USE_HOTPLUG | ||
448 | static struct miscdevice z90crypt_misc_device = { | 417 | static struct miscdevice z90crypt_misc_device = { |
449 | .minor = Z90CRYPT_MINOR, | 418 | .minor = Z90CRYPT_MINOR, |
450 | .name = DEV_NAME, | 419 | .name = DEV_NAME, |
451 | .fops = &z90crypt_fops, | 420 | .fops = &z90crypt_fops, |
452 | .devfs_name = DEV_NAME | 421 | .devfs_name = DEV_NAME |
453 | }; | 422 | }; |
454 | #endif | ||
455 | 423 | ||
456 | /** | 424 | /** |
457 | * Documentation values. | 425 | * Documentation values. |
@@ -603,7 +571,6 @@ z90crypt_init_module(void) | |||
603 | return -EINVAL; | 571 | return -EINVAL; |
604 | } | 572 | } |
605 | 573 | ||
606 | #ifndef Z90CRYPT_USE_HOTPLUG | ||
607 | /* Register as misc device with given minor (or get a dynamic one). */ | 574 | /* Register as misc device with given minor (or get a dynamic one). */ |
608 | result = misc_register(&z90crypt_misc_device); | 575 | result = misc_register(&z90crypt_misc_device); |
609 | if (result < 0) { | 576 | if (result < 0) { |
@@ -611,18 +578,6 @@ z90crypt_init_module(void) | |||
611 | z90crypt_misc_device.minor, result); | 578 | z90crypt_misc_device.minor, result); |
612 | return result; | 579 | return result; |
613 | } | 580 | } |
614 | #else | ||
615 | /* Register the major (or get a dynamic one). */ | ||
616 | result = register_chrdev(z90crypt_major, REG_NAME, &z90crypt_fops); | ||
617 | if (result < 0) { | ||
618 | PRINTKW("register_chrdev (major %d) failed with %d.\n", | ||
619 | z90crypt_major, result); | ||
620 | return result; | ||
621 | } | ||
622 | |||
623 | if (z90crypt_major == 0) | ||
624 | z90crypt_major = result; | ||
625 | #endif | ||
626 | 581 | ||
627 | PDEBUG("Registered " DEV_NAME " with result %d\n", result); | 582 | PDEBUG("Registered " DEV_NAME " with result %d\n", result); |
628 | 583 | ||
@@ -645,11 +600,6 @@ z90crypt_init_module(void) | |||
645 | } else | 600 | } else |
646 | PRINTK("No devices at startup\n"); | 601 | PRINTK("No devices at startup\n"); |
647 | 602 | ||
648 | #ifdef Z90CRYPT_USE_HOTPLUG | ||
649 | /* generate hotplug event for device node generation */ | ||
650 | z90crypt_hotplug_event(z90crypt_major, 0, Z90CRYPT_HOTPLUG_ADD); | ||
651 | #endif | ||
652 | |||
653 | /* Initialize globals. */ | 603 | /* Initialize globals. */ |
654 | spin_lock_init(&queuespinlock); | 604 | spin_lock_init(&queuespinlock); |
655 | 605 | ||
@@ -701,17 +651,10 @@ z90crypt_init_module(void) | |||
701 | return 0; // success | 651 | return 0; // success |
702 | 652 | ||
703 | init_module_cleanup: | 653 | init_module_cleanup: |
704 | #ifndef Z90CRYPT_USE_HOTPLUG | ||
705 | if ((nresult = misc_deregister(&z90crypt_misc_device))) | 654 | if ((nresult = misc_deregister(&z90crypt_misc_device))) |
706 | PRINTK("misc_deregister failed with %d.\n", nresult); | 655 | PRINTK("misc_deregister failed with %d.\n", nresult); |
707 | else | 656 | else |
708 | PDEBUG("misc_deregister successful.\n"); | 657 | PDEBUG("misc_deregister successful.\n"); |
709 | #else | ||
710 | if ((nresult = unregister_chrdev(z90crypt_major, REG_NAME))) | ||
711 | PRINTK("unregister_chrdev failed with %d.\n", nresult); | ||
712 | else | ||
713 | PDEBUG("unregister_chrdev successful.\n"); | ||
714 | #endif | ||
715 | 658 | ||
716 | return result; // failure | 659 | return result; // failure |
717 | } | 660 | } |
@@ -728,19 +671,10 @@ z90crypt_cleanup_module(void) | |||
728 | 671 | ||
729 | remove_proc_entry("driver/z90crypt", 0); | 672 | remove_proc_entry("driver/z90crypt", 0); |
730 | 673 | ||
731 | #ifndef Z90CRYPT_USE_HOTPLUG | ||
732 | if ((nresult = misc_deregister(&z90crypt_misc_device))) | 674 | if ((nresult = misc_deregister(&z90crypt_misc_device))) |
733 | PRINTK("misc_deregister failed with %d.\n", nresult); | 675 | PRINTK("misc_deregister failed with %d.\n", nresult); |
734 | else | 676 | else |
735 | PDEBUG("misc_deregister successful.\n"); | 677 | PDEBUG("misc_deregister successful.\n"); |
736 | #else | ||
737 | z90crypt_hotplug_event(z90crypt_major, 0, Z90CRYPT_HOTPLUG_REMOVE); | ||
738 | |||
739 | if ((nresult = unregister_chrdev(z90crypt_major, REG_NAME))) | ||
740 | PRINTK("unregister_chrdev failed with %d.\n", nresult); | ||
741 | else | ||
742 | PDEBUG("unregister_chrdev successful.\n"); | ||
743 | #endif | ||
744 | 678 | ||
745 | /* Remove the tasks */ | 679 | /* Remove the tasks */ |
746 | tasklet_kill(&reader_tasklet); | 680 | tasklet_kill(&reader_tasklet); |
@@ -748,6 +682,9 @@ z90crypt_cleanup_module(void) | |||
748 | del_timer(&config_timer); | 682 | del_timer(&config_timer); |
749 | del_timer(&cleanup_timer); | 683 | del_timer(&cleanup_timer); |
750 | 684 | ||
685 | if (z90_device_work) | ||
686 | destroy_workqueue(z90_device_work); | ||
687 | |||
751 | destroy_z90crypt(); | 688 | destroy_z90crypt(); |
752 | 689 | ||
753 | PRINTKN("Unloaded.\n"); | 690 | PRINTKN("Unloaded.\n"); |
@@ -766,8 +703,6 @@ z90crypt_cleanup_module(void) | |||
766 | * z90crypt_status_write | 703 | * z90crypt_status_write |
767 | * disable_card | 704 | * disable_card |
768 | * enable_card | 705 | * enable_card |
769 | * scan_char | ||
770 | * scan_string | ||
771 | * | 706 | * |
772 | * Helper functions: | 707 | * Helper functions: |
773 | * z90crypt_rsa | 708 | * z90crypt_rsa |
@@ -1057,9 +992,10 @@ remove_device(struct device *device_p) | |||
1057 | * The MCL must be applied and the newer bitlengths enabled for these to work. | 992 | * The MCL must be applied and the newer bitlengths enabled for these to work. |
1058 | * | 993 | * |
1059 | * Card Type Old limit New limit | 994 | * Card Type Old limit New limit |
995 | * PCICA ??-2048 same (the lower limit is less than 128 bit...) | ||
1060 | * PCICC 512-1024 512-2048 | 996 | * PCICC 512-1024 512-2048 |
1061 | * PCIXCC_MCL2 512-2048 no change (applying this MCL == card is MCL3+) | 997 | * PCIXCC_MCL2 512-2048 ----- (applying any GA LIC will make an MCL3 card) |
1062 | * PCIXCC_MCL3 512-2048 128-2048 | 998 | * PCIXCC_MCL3 ----- 128-2048 |
1063 | * CEX2C 512-2048 128-2048 | 999 | * CEX2C 512-2048 128-2048 |
1064 | * | 1000 | * |
1065 | * ext_bitlens (extended bitlengths) is a global, since you should not apply an | 1001 | * ext_bitlens (extended bitlengths) is a global, since you should not apply an |
@@ -1104,7 +1040,7 @@ select_device_type(int *dev_type_p, int bytelength) | |||
1104 | if (PCICA_avail || PCIXCC_MCL3_avail || CEX2C_avail) { | 1040 | if (PCICA_avail || PCIXCC_MCL3_avail || CEX2C_avail) { |
1105 | /** | 1041 | /** |
1106 | * bitlength is a factor, PCICA is the most capable, even with | 1042 | * bitlength is a factor, PCICA is the most capable, even with |
1107 | * the new MCL. | 1043 | * the new MCL for PCIXCC. |
1108 | */ | 1044 | */ |
1109 | if ((bytelength < PCIXCC_MIN_MOD_SIZE) || | 1045 | if ((bytelength < PCIXCC_MIN_MOD_SIZE) || |
1110 | (!ext_bitlens && (bytelength < OLD_PCIXCC_MIN_MOD_SIZE))) { | 1046 | (!ext_bitlens && (bytelength < OLD_PCIXCC_MIN_MOD_SIZE))) { |
@@ -2144,73 +2080,15 @@ enable_card(int card_index) | |||
2144 | z90crypt.hdware_info->type_mask[devp->dev_type].user_disabled_count--; | 2080 | z90crypt.hdware_info->type_mask[devp->dev_type].user_disabled_count--; |
2145 | } | 2081 | } |
2146 | 2082 | ||
2147 | static inline int | ||
2148 | scan_char(unsigned char *bf, unsigned int len, | ||
2149 | unsigned int *offs, unsigned int *p_eof, unsigned char c) | ||
2150 | { | ||
2151 | unsigned int i, found; | ||
2152 | |||
2153 | found = 0; | ||
2154 | for (i = 0; i < len; i++) { | ||
2155 | if (bf[i] == c) { | ||
2156 | found = 1; | ||
2157 | break; | ||
2158 | } | ||
2159 | if (bf[i] == '\0') { | ||
2160 | *p_eof = 1; | ||
2161 | break; | ||
2162 | } | ||
2163 | if (bf[i] == '\n') { | ||
2164 | break; | ||
2165 | } | ||
2166 | } | ||
2167 | *offs = i+1; | ||
2168 | return found; | ||
2169 | } | ||
2170 | |||
2171 | static inline int | ||
2172 | scan_string(unsigned char *bf, unsigned int len, | ||
2173 | unsigned int *offs, unsigned int *p_eof, unsigned char *s) | ||
2174 | { | ||
2175 | unsigned int temp_len, temp_offs, found, eof; | ||
2176 | |||
2177 | temp_len = temp_offs = found = eof = 0; | ||
2178 | while (!eof && !found) { | ||
2179 | found = scan_char(bf+temp_len, len-temp_len, | ||
2180 | &temp_offs, &eof, *s); | ||
2181 | |||
2182 | temp_len += temp_offs; | ||
2183 | if (eof) { | ||
2184 | found = 0; | ||
2185 | break; | ||
2186 | } | ||
2187 | |||
2188 | if (found) { | ||
2189 | if (len >= temp_offs+strlen(s)) { | ||
2190 | found = !strncmp(bf+temp_len-1, s, strlen(s)); | ||
2191 | if (found) { | ||
2192 | *offs = temp_len+strlen(s)-1; | ||
2193 | break; | ||
2194 | } | ||
2195 | } else { | ||
2196 | found = 0; | ||
2197 | *p_eof = 1; | ||
2198 | break; | ||
2199 | } | ||
2200 | } | ||
2201 | } | ||
2202 | return found; | ||
2203 | } | ||
2204 | |||
2205 | static int | 2083 | static int |
2206 | z90crypt_status_write(struct file *file, const char __user *buffer, | 2084 | z90crypt_status_write(struct file *file, const char __user *buffer, |
2207 | unsigned long count, void *data) | 2085 | unsigned long count, void *data) |
2208 | { | 2086 | { |
2209 | int i, j, len, offs, found, eof; | 2087 | int j, eol; |
2210 | unsigned char *lbuf; | 2088 | unsigned char *lbuf, *ptr; |
2211 | unsigned int local_count; | 2089 | unsigned int local_count; |
2212 | 2090 | ||
2213 | #define LBUFSIZE 600 | 2091 | #define LBUFSIZE 1200 |
2214 | lbuf = kmalloc(LBUFSIZE, GFP_KERNEL); | 2092 | lbuf = kmalloc(LBUFSIZE, GFP_KERNEL); |
2215 | if (!lbuf) { | 2093 | if (!lbuf) { |
2216 | PRINTK("kmalloc failed!\n"); | 2094 | PRINTK("kmalloc failed!\n"); |
@@ -2227,49 +2105,46 @@ z90crypt_status_write(struct file *file, const char __user *buffer, | |||
2227 | return -EFAULT; | 2105 | return -EFAULT; |
2228 | } | 2106 | } |
2229 | 2107 | ||
2230 | lbuf[local_count-1] = '\0'; | 2108 | lbuf[local_count] = '\0'; |
2231 | 2109 | ||
2232 | len = 0; | 2110 | ptr = strstr(lbuf, "Online devices"); |
2233 | eof = 0; | 2111 | if (ptr == 0) { |
2234 | found = 0; | 2112 | PRINTK("Unable to parse data (missing \"Online devices\")\n"); |
2235 | while (!eof) { | 2113 | kfree(lbuf); |
2236 | found = scan_string(lbuf+len, local_count-len, &offs, &eof, | 2114 | return count; |
2237 | "Online devices"); | ||
2238 | len += offs; | ||
2239 | if (found == 1) | ||
2240 | break; | ||
2241 | } | 2115 | } |
2242 | 2116 | ||
2243 | if (eof) { | 2117 | ptr = strstr(ptr, "\n"); |
2118 | if (ptr == 0) { | ||
2119 | PRINTK("Unable to parse data (missing newline after \"Online devices\")\n"); | ||
2244 | kfree(lbuf); | 2120 | kfree(lbuf); |
2245 | return count; | 2121 | return count; |
2246 | } | 2122 | } |
2123 | ptr++; | ||
2247 | 2124 | ||
2248 | if (found) | 2125 | if (strstr(ptr, "Waiting work element counts") == NULL) { |
2249 | found = scan_char(lbuf+len, local_count-len, &offs, &eof, '\n'); | 2126 | PRINTK("Unable to parse data (missing \"Waiting work element counts\")\n"); |
2250 | |||
2251 | if (!found || eof) { | ||
2252 | kfree(lbuf); | 2127 | kfree(lbuf); |
2253 | return count; | 2128 | return count; |
2254 | } | 2129 | } |
2255 | 2130 | ||
2256 | len += offs; | ||
2257 | j = 0; | 2131 | j = 0; |
2258 | for (i = 0; i < 80; i++) { | 2132 | eol = 0; |
2259 | switch (*(lbuf+len+i)) { | 2133 | while ((j < 64) && (*ptr != '\0')) { |
2134 | switch (*ptr) { | ||
2260 | case '\t': | 2135 | case '\t': |
2261 | case ' ': | 2136 | case ' ': |
2262 | break; | 2137 | break; |
2263 | case '\n': | 2138 | case '\n': |
2264 | default: | 2139 | default: |
2265 | eof = 1; | 2140 | eol = 1; |
2266 | break; | 2141 | break; |
2267 | case '0': | 2142 | case '0': // no device |
2268 | case '1': | 2143 | case '1': // PCICA |
2269 | case '2': | 2144 | case '2': // PCICC |
2270 | case '3': | 2145 | case '3': // PCIXCC_MCL2 |
2271 | case '4': | 2146 | case '4': // PCIXCC_MCL3 |
2272 | case '5': | 2147 | case '5': // CEX2C |
2273 | j++; | 2148 | j++; |
2274 | break; | 2149 | break; |
2275 | case 'd': | 2150 | case 'd': |
@@ -2283,8 +2158,9 @@ z90crypt_status_write(struct file *file, const char __user *buffer, | |||
2283 | j++; | 2158 | j++; |
2284 | break; | 2159 | break; |
2285 | } | 2160 | } |
2286 | if (eof) | 2161 | if (eol) |
2287 | break; | 2162 | break; |
2163 | ptr++; | ||
2288 | } | 2164 | } |
2289 | 2165 | ||
2290 | kfree(lbuf); | 2166 | kfree(lbuf); |
@@ -3479,45 +3355,5 @@ probe_PCIXCC_type(struct device *devPtr) | |||
3479 | return rv; | 3355 | return rv; |
3480 | } | 3356 | } |
3481 | 3357 | ||
3482 | #ifdef Z90CRYPT_USE_HOTPLUG | ||
3483 | static void | ||
3484 | z90crypt_hotplug_event(int dev_major, int dev_minor, int action) | ||
3485 | { | ||
3486 | #ifdef CONFIG_HOTPLUG | ||
3487 | char *argv[3]; | ||
3488 | char *envp[6]; | ||
3489 | char major[20]; | ||
3490 | char minor[20]; | ||
3491 | |||
3492 | sprintf(major, "MAJOR=%d", dev_major); | ||
3493 | sprintf(minor, "MINOR=%d", dev_minor); | ||
3494 | |||
3495 | argv[0] = hotplug_path; | ||
3496 | argv[1] = "z90crypt"; | ||
3497 | argv[2] = 0; | ||
3498 | |||
3499 | envp[0] = "HOME=/"; | ||
3500 | envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; | ||
3501 | |||
3502 | switch (action) { | ||
3503 | case Z90CRYPT_HOTPLUG_ADD: | ||
3504 | envp[2] = "ACTION=add"; | ||
3505 | break; | ||
3506 | case Z90CRYPT_HOTPLUG_REMOVE: | ||
3507 | envp[2] = "ACTION=remove"; | ||
3508 | break; | ||
3509 | default: | ||
3510 | BUG(); | ||
3511 | break; | ||
3512 | } | ||
3513 | envp[3] = major; | ||
3514 | envp[4] = minor; | ||
3515 | envp[5] = 0; | ||
3516 | |||
3517 | call_usermodehelper(argv[0], argv, envp, 0); | ||
3518 | #endif | ||
3519 | } | ||
3520 | #endif | ||
3521 | |||
3522 | module_init(z90crypt_init_module); | 3358 | module_init(z90crypt_init_module); |
3523 | module_exit(z90crypt_cleanup_module); | 3359 | module_exit(z90crypt_cleanup_module); |