aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorEric Rossman <edrossma@us.ibm.com>2005-09-03 18:58:03 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:06:29 -0400
commit2dee702fcb197d80c1a94650fb611539dd8135ce (patch)
tree86ca24687aa6d8d6a4bd09c3cc63cd4c4475e19a /drivers/s390
parentb6d09449d53f5aa7c67b1be3e90d7b7ab2aad09c (diff)
[PATCH] s390: crypto driver update
crypto device driver update: - Suppress syslog messages for some return codes. - Fix incorrect bounds checking in /proc interface. - Remove hotplug calls. - Remove linux version checks. - Remove device workqueue on module unload. 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')
-rw-r--r--drivers/s390/crypto/z90common.h3
-rw-r--r--drivers/s390/crypto/z90hardware.c127
-rw-r--r--drivers/s390/crypto/z90main.c246
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
37char z90hardware_version[] __initdata = 37char 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
286union request_msg {
287 union type4_msg t4msg;
288 struct type6_msg t6msg;
289};
290
291struct request_msg_ext {
292 int q_nr;
293 unsigned char *psmid;
294 union request_msg reqMsg;
295};
296
297struct 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
328struct type86_hdr { 286struct 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
340struct type86_fmt2_msg { 298struct 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
499static unsigned char static_PKE_function_code[2] = {0x50, 0x4B};
500
541struct T6_keyBlock_hdrX { 501struct 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 651struct 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
693static 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
695static inline int 684static inline int
696testq(int q_nr, int *q_depth, int *dev_type, struct ap_status_word *stat) 685testq(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
56static char z90main_version[] __initdata = 46static 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 */
302struct caller { 287struct 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
408static 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
416static int z90crypt_major = Z90CRYPT_MAJOR;
417#endif
418
419static int domain = DOMAIN_INDEX; 389static int domain = DOMAIN_INDEX;
420static struct z90crypt z90crypt; 390static struct z90crypt z90crypt;
421static int quiesce_z90crypt; 391static 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
448static struct miscdevice z90crypt_misc_device = { 417static 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
703init_module_cleanup: 653init_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
2147static inline int
2148scan_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
2171static inline int
2172scan_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
2205static int 2083static int
2206z90crypt_status_write(struct file *file, const char __user *buffer, 2084z90crypt_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
3483static void
3484z90crypt_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
3522module_init(z90crypt_init_module); 3358module_init(z90crypt_init_module);
3523module_exit(z90crypt_cleanup_module); 3359module_exit(z90crypt_cleanup_module);