Merge tag 'cleanup2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[pandora-kernel.git] / drivers / s390 / crypto / zcrypt_pcixcc.c
1 /*
2  *  linux/drivers/s390/crypto/zcrypt_pcixcc.c
3  *
4  *  zcrypt 2.1.0
5  *
6  *  Copyright (C)  2001, 2006 IBM Corporation
7  *  Author(s): Robert Burroughs
8  *             Eric Rossman (edrossma@us.ibm.com)
9  *
10  *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11  *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12  *                                Ralph Wuerthner <rwuerthn@de.ibm.com>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  */
28
29 #include <linux/module.h>
30 #include <linux/init.h>
31 #include <linux/err.h>
32 #include <linux/delay.h>
33 #include <linux/slab.h>
34 #include <linux/atomic.h>
35 #include <asm/uaccess.h>
36
37 #include "ap_bus.h"
38 #include "zcrypt_api.h"
39 #include "zcrypt_error.h"
40 #include "zcrypt_pcicc.h"
41 #include "zcrypt_pcixcc.h"
42 #include "zcrypt_cca_key.h"
43
44 #define PCIXCC_MIN_MOD_SIZE      16     /*  128 bits    */
45 #define PCIXCC_MIN_MOD_SIZE_OLD  64     /*  512 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      512     /* 4096 bits    */
49
50 #define PCIXCC_MCL2_SPEED_RATING        7870
51 #define PCIXCC_MCL3_SPEED_RATING        7870
52 #define CEX2C_SPEED_RATING              7000
53 #define CEX3C_SPEED_RATING              6500
54
55 #define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c  /* max size type6 v2 crt message */
56 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply      */
57
58 #define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024)
59
60 #define PCIXCC_CLEANUP_TIME     (15*HZ)
61
62 #define CEIL4(x) ((((x)+3)/4)*4)
63
64 struct response_type {
65         struct completion work;
66         int type;
67 };
68 #define PCIXCC_RESPONSE_TYPE_ICA  0
69 #define PCIXCC_RESPONSE_TYPE_XCRB 1
70
71 static struct ap_device_id zcrypt_pcixcc_ids[] = {
72         { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
73         { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
74         { AP_DEVICE(AP_DEVICE_TYPE_CEX3C) },
75         { /* end of list */ },
76 };
77
78 MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
79 MODULE_AUTHOR("IBM Corporation");
80 MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, "
81                    "Copyright 2001, 2006 IBM Corporation");
82 MODULE_LICENSE("GPL");
83
84 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
85 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
86 static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *,
87                                  struct ap_message *);
88
89 static struct ap_driver zcrypt_pcixcc_driver = {
90         .probe = zcrypt_pcixcc_probe,
91         .remove = zcrypt_pcixcc_remove,
92         .ids = zcrypt_pcixcc_ids,
93         .request_timeout = PCIXCC_CLEANUP_TIME,
94 };
95
96 /**
97  * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
98  * card in a type6 message. The 3 fields that must be filled in at execution
99  * time are  req_parml, rpl_parml and usage_domain.
100  * Everything about this interface is ascii/big-endian, since the
101  * device does *not* have 'Intel inside'.
102  *
103  * The CPRBX is followed immediately by the parm block.
104  * The parm block contains:
105  * - function code ('PD' 0x5044 or 'PK' 0x504B)
106  * - rule block (one of:)
107  *   + 0x000A 'PKCS-1.2' (MCL2 'PD')
108  *   + 0x000A 'ZERO-PAD' (MCL2 'PK')
109  *   + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
110  *   + 0x000A 'MRP     ' (MCL3 'PK' or CEX2C 'PK')
111  * - VUD block
112  */
113 static struct CPRBX static_cprbx = {
114         .cprb_len       =  0x00DC,
115         .cprb_ver_id    =  0x02,
116         .func_id        = {0x54,0x32},
117 };
118
119 /**
120  * Convert a ICAMEX message to a type6 MEX message.
121  *
122  * @zdev: crypto device pointer
123  * @ap_msg: pointer to AP message
124  * @mex: pointer to user input data
125  *
126  * Returns 0 on success or -EFAULT.
127  */
128 static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
129                                        struct ap_message *ap_msg,
130                                        struct ica_rsa_modexpo *mex)
131 {
132         static struct type6_hdr static_type6_hdrX = {
133                 .type           =  0x06,
134                 .offset1        =  0x00000058,
135                 .agent_id       = {'C','A',},
136                 .function_code  = {'P','K'},
137         };
138         static struct function_and_rules_block static_pke_fnr = {
139                 .function_code  = {'P','K'},
140                 .ulen           = 10,
141                 .only_rule      = {'M','R','P',' ',' ',' ',' ',' '}
142         };
143         static struct function_and_rules_block static_pke_fnr_MCL2 = {
144                 .function_code  = {'P','K'},
145                 .ulen           = 10,
146                 .only_rule      = {'Z','E','R','O','-','P','A','D'}
147         };
148         struct {
149                 struct type6_hdr hdr;
150                 struct CPRBX cprbx;
151                 struct function_and_rules_block fr;
152                 unsigned short length;
153                 char text[0];
154         } __attribute__((packed)) *msg = ap_msg->message;
155         int size;
156
157         /* VUD.ciphertext */
158         msg->length = mex->inputdatalength + 2;
159         if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
160                 return -EFAULT;
161
162         /* Set up key which is located after the variable length text. */
163         size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
164         if (size < 0)
165                 return size;
166         size += sizeof(*msg) + mex->inputdatalength;
167
168         /* message header, cprbx and f&r */
169         msg->hdr = static_type6_hdrX;
170         msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
171         msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
172
173         msg->cprbx = static_cprbx;
174         msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
175         msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
176
177         msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
178                 static_pke_fnr_MCL2 : static_pke_fnr;
179
180         msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
181
182         ap_msg->length = size;
183         return 0;
184 }
185
186 /**
187  * Convert a ICACRT message to a type6 CRT message.
188  *
189  * @zdev: crypto device pointer
190  * @ap_msg: pointer to AP message
191  * @crt: pointer to user input data
192  *
193  * Returns 0 on success or -EFAULT.
194  */
195 static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
196                                        struct ap_message *ap_msg,
197                                        struct ica_rsa_modexpo_crt *crt)
198 {
199         static struct type6_hdr static_type6_hdrX = {
200                 .type           =  0x06,
201                 .offset1        =  0x00000058,
202                 .agent_id       = {'C','A',},
203                 .function_code  = {'P','D'},
204         };
205         static struct function_and_rules_block static_pkd_fnr = {
206                 .function_code  = {'P','D'},
207                 .ulen           = 10,
208                 .only_rule      = {'Z','E','R','O','-','P','A','D'}
209         };
210
211         static struct function_and_rules_block static_pkd_fnr_MCL2 = {
212                 .function_code  = {'P','D'},
213                 .ulen           = 10,
214                 .only_rule      = {'P','K','C','S','-','1','.','2'}
215         };
216         struct {
217                 struct type6_hdr hdr;
218                 struct CPRBX cprbx;
219                 struct function_and_rules_block fr;
220                 unsigned short length;
221                 char text[0];
222         } __attribute__((packed)) *msg = ap_msg->message;
223         int size;
224
225         /* VUD.ciphertext */
226         msg->length = crt->inputdatalength + 2;
227         if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
228                 return -EFAULT;
229
230         /* Set up key which is located after the variable length text. */
231         size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
232         if (size < 0)
233                 return size;
234         size += sizeof(*msg) + crt->inputdatalength;    /* total size of msg */
235
236         /* message header, cprbx and f&r */
237         msg->hdr = static_type6_hdrX;
238         msg->hdr.ToCardLen1 = size -  sizeof(msg->hdr);
239         msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
240
241         msg->cprbx = static_cprbx;
242         msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
243         msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
244                 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
245
246         msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
247                 static_pkd_fnr_MCL2 : static_pkd_fnr;
248
249         ap_msg->length = size;
250         return 0;
251 }
252
253 /**
254  * Convert a XCRB message to a type6 CPRB message.
255  *
256  * @zdev: crypto device pointer
257  * @ap_msg: pointer to AP message
258  * @xcRB: pointer to user input data
259  *
260  * Returns 0 on success or -EFAULT, -EINVAL.
261  */
262 struct type86_fmt2_msg {
263         struct type86_hdr hdr;
264         struct type86_fmt2_ext fmt2;
265 } __attribute__((packed));
266
267 static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
268                                        struct ap_message *ap_msg,
269                                        struct ica_xcRB *xcRB)
270 {
271         static struct type6_hdr static_type6_hdrX = {
272                 .type           =  0x06,
273                 .offset1        =  0x00000058,
274         };
275         struct {
276                 struct type6_hdr hdr;
277                 struct CPRBX cprbx;
278         } __attribute__((packed)) *msg = ap_msg->message;
279
280         int rcblen = CEIL4(xcRB->request_control_blk_length);
281         int replylen;
282         char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
283         char *function_code;
284
285         /* length checks */
286         ap_msg->length = sizeof(struct type6_hdr) +
287                 CEIL4(xcRB->request_control_blk_length) +
288                 xcRB->request_data_length;
289         if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
290                 return -EINVAL;
291         replylen = sizeof(struct type86_fmt2_msg) +
292                 CEIL4(xcRB->reply_control_blk_length) +
293                 xcRB->reply_data_length;
294         if (replylen > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
295                 return -EINVAL;
296
297         /* prepare type6 header */
298         msg->hdr = static_type6_hdrX;
299         memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
300         msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
301         if (xcRB->request_data_length) {
302                 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
303                 msg->hdr.ToCardLen2 = xcRB->request_data_length;
304         }
305         msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length;
306         msg->hdr.FromCardLen2 = xcRB->reply_data_length;
307
308         /* prepare CPRB */
309         if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr,
310                     xcRB->request_control_blk_length))
311                 return -EFAULT;
312         if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
313             xcRB->request_control_blk_length)
314                 return -EINVAL;
315         function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
316         memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
317
318         if (memcmp(function_code, "US", 2) == 0)
319                 ap_msg->special = 1;
320         else
321                 ap_msg->special = 0;
322
323         /* copy data block */
324         if (xcRB->request_data_length &&
325             copy_from_user(req_data, xcRB->request_data_address,
326                 xcRB->request_data_length))
327                 return -EFAULT;
328         return 0;
329 }
330
331 /**
332  * Prepare a type6 CPRB message for random number generation
333  *
334  * @ap_dev: AP device pointer
335  * @ap_msg: pointer to AP message
336  */
337 static void rng_type6CPRB_msgX(struct ap_device *ap_dev,
338                                struct ap_message *ap_msg,
339                                unsigned random_number_length)
340 {
341         struct {
342                 struct type6_hdr hdr;
343                 struct CPRBX cprbx;
344                 char function_code[2];
345                 short int rule_length;
346                 char rule[8];
347                 short int verb_length;
348                 short int key_length;
349         } __attribute__((packed)) *msg = ap_msg->message;
350         static struct type6_hdr static_type6_hdrX = {
351                 .type           = 0x06,
352                 .offset1        = 0x00000058,
353                 .agent_id       = {'C', 'A'},
354                 .function_code  = {'R', 'L'},
355                 .ToCardLen1     = sizeof *msg - sizeof(msg->hdr),
356                 .FromCardLen1   = sizeof *msg - sizeof(msg->hdr),
357         };
358         static struct CPRBX local_cprbx = {
359                 .cprb_len       = 0x00dc,
360                 .cprb_ver_id    = 0x02,
361                 .func_id        = {0x54, 0x32},
362                 .req_parml      = sizeof *msg - sizeof(msg->hdr) -
363                                   sizeof(msg->cprbx),
364                 .rpl_msgbl      = sizeof *msg - sizeof(msg->hdr),
365         };
366
367         msg->hdr = static_type6_hdrX;
368         msg->hdr.FromCardLen2 = random_number_length,
369         msg->cprbx = local_cprbx;
370         msg->cprbx.rpl_datal = random_number_length,
371         msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid);
372         memcpy(msg->function_code, msg->hdr.function_code, 0x02);
373         msg->rule_length = 0x0a;
374         memcpy(msg->rule, "RANDOM  ", 8);
375         msg->verb_length = 0x02;
376         msg->key_length = 0x02;
377         ap_msg->length = sizeof *msg;
378 }
379
380 /**
381  * Copy results from a type 86 ICA reply message back to user space.
382  *
383  * @zdev: crypto device pointer
384  * @reply: reply AP message.
385  * @data: pointer to user output data
386  * @length: size of user output data
387  *
388  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
389  */
390 struct type86x_reply {
391         struct type86_hdr hdr;
392         struct type86_fmt2_ext fmt2;
393         struct CPRBX cprbx;
394         unsigned char pad[4];   /* 4 byte function code/rules block ? */
395         unsigned short length;
396         char text[0];
397 } __attribute__((packed));
398
399 static int convert_type86_ica(struct zcrypt_device *zdev,
400                           struct ap_message *reply,
401                           char __user *outputdata,
402                           unsigned int outputdatalength)
403 {
404         static unsigned char static_pad[] = {
405                 0x00,0x02,
406                 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
407                 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
408                 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
409                 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
410                 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
411                 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
412                 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
413                 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
414                 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
415                 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
416                 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
417                 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
418                 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
419                 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
420                 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
421                 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
422                 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
423                 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
424                 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
425                 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
426                 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
427                 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
428                 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
429                 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
430                 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
431                 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
432                 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
433                 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
434                 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
435                 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
436                 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
437                 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
438         };
439         struct type86x_reply *msg = reply->message;
440         unsigned short service_rc, service_rs;
441         unsigned int reply_len, pad_len;
442         char *data;
443
444         service_rc = msg->cprbx.ccp_rtcode;
445         if (unlikely(service_rc != 0)) {
446                 service_rs = msg->cprbx.ccp_rscode;
447                 if (service_rc == 8 && service_rs == 66)
448                         return -EINVAL;
449                 if (service_rc == 8 && service_rs == 65)
450                         return -EINVAL;
451                 if (service_rc == 8 && service_rs == 770)
452                         return -EINVAL;
453                 if (service_rc == 8 && service_rs == 783) {
454                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
455                         return -EAGAIN;
456                 }
457                 if (service_rc == 12 && service_rs == 769)
458                         return -EINVAL;
459                 if (service_rc == 8 && service_rs == 72)
460                         return -EINVAL;
461                 zdev->online = 0;
462                 return -EAGAIN; /* repeat the request on a different device. */
463         }
464         data = msg->text;
465         reply_len = msg->length - 2;
466         if (reply_len > outputdatalength)
467                 return -EINVAL;
468         /*
469          * For all encipher requests, the length of the ciphertext (reply_len)
470          * will always equal the modulus length. For MEX decipher requests
471          * the output needs to get padded. Minimum pad size is 10.
472          *
473          * Currently, the cases where padding will be added is for:
474          * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
475          *   ZERO-PAD and CRT is only supported for PKD requests)
476          * - PCICC, always
477          */
478         pad_len = outputdatalength - reply_len;
479         if (pad_len > 0) {
480                 if (pad_len < 10)
481                         return -EINVAL;
482                 /* 'restore' padding left in the PCICC/PCIXCC card. */
483                 if (copy_to_user(outputdata, static_pad, pad_len - 1))
484                         return -EFAULT;
485                 if (put_user(0, outputdata + pad_len - 1))
486                         return -EFAULT;
487         }
488         /* Copy the crypto response to user space. */
489         if (copy_to_user(outputdata + pad_len, data, reply_len))
490                 return -EFAULT;
491         return 0;
492 }
493
494 /**
495  * Copy results from a type 86 XCRB reply message back to user space.
496  *
497  * @zdev: crypto device pointer
498  * @reply: reply AP message.
499  * @xcRB: pointer to XCRB
500  *
501  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
502  */
503 static int convert_type86_xcrb(struct zcrypt_device *zdev,
504                                struct ap_message *reply,
505                                struct ica_xcRB *xcRB)
506 {
507         struct type86_fmt2_msg *msg = reply->message;
508         char *data = reply->message;
509
510         /* Copy CPRB to user */
511         if (copy_to_user(xcRB->reply_control_blk_addr,
512                 data + msg->fmt2.offset1, msg->fmt2.count1))
513                 return -EFAULT;
514         xcRB->reply_control_blk_length = msg->fmt2.count1;
515
516         /* Copy data buffer to user */
517         if (msg->fmt2.count2)
518                 if (copy_to_user(xcRB->reply_data_addr,
519                         data + msg->fmt2.offset2, msg->fmt2.count2))
520                         return -EFAULT;
521         xcRB->reply_data_length = msg->fmt2.count2;
522         return 0;
523 }
524
525 static int convert_type86_rng(struct zcrypt_device *zdev,
526                           struct ap_message *reply,
527                           char *buffer)
528 {
529         struct {
530                 struct type86_hdr hdr;
531                 struct type86_fmt2_ext fmt2;
532                 struct CPRBX cprbx;
533         } __attribute__((packed)) *msg = reply->message;
534         char *data = reply->message;
535
536         if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
537                 return -EINVAL;
538         memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
539         return msg->fmt2.count2;
540 }
541
542 static int convert_response_ica(struct zcrypt_device *zdev,
543                             struct ap_message *reply,
544                             char __user *outputdata,
545                             unsigned int outputdatalength)
546 {
547         struct type86x_reply *msg = reply->message;
548
549         /* Response type byte is the second byte in the response. */
550         switch (((unsigned char *) reply->message)[1]) {
551         case TYPE82_RSP_CODE:
552         case TYPE88_RSP_CODE:
553                 return convert_error(zdev, reply);
554         case TYPE86_RSP_CODE:
555                 if (msg->cprbx.ccp_rtcode &&
556                    (msg->cprbx.ccp_rscode == 0x14f) &&
557                    (outputdatalength > 256)) {
558                         if (zdev->max_exp_bit_length <= 17) {
559                                 zdev->max_exp_bit_length = 17;
560                                 return -EAGAIN;
561                         } else
562                                 return -EINVAL;
563                 }
564                 if (msg->hdr.reply_code)
565                         return convert_error(zdev, reply);
566                 if (msg->cprbx.cprb_ver_id == 0x02)
567                         return convert_type86_ica(zdev, reply,
568                                                   outputdata, outputdatalength);
569                 /* Fall through, no break, incorrect cprb version is an unknown
570                  * response */
571         default: /* Unknown response type, this should NEVER EVER happen */
572                 zdev->online = 0;
573                 return -EAGAIN; /* repeat the request on a different device. */
574         }
575 }
576
577 static int convert_response_xcrb(struct zcrypt_device *zdev,
578                             struct ap_message *reply,
579                             struct ica_xcRB *xcRB)
580 {
581         struct type86x_reply *msg = reply->message;
582
583         /* Response type byte is the second byte in the response. */
584         switch (((unsigned char *) reply->message)[1]) {
585         case TYPE82_RSP_CODE:
586         case TYPE88_RSP_CODE:
587                 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
588                 return convert_error(zdev, reply);
589         case TYPE86_RSP_CODE:
590                 if (msg->hdr.reply_code) {
591                         memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
592                         return convert_error(zdev, reply);
593                 }
594                 if (msg->cprbx.cprb_ver_id == 0x02)
595                         return convert_type86_xcrb(zdev, reply, xcRB);
596                 /* Fall through, no break, incorrect cprb version is an unknown
597                  * response */
598         default: /* Unknown response type, this should NEVER EVER happen */
599                 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
600                 zdev->online = 0;
601                 return -EAGAIN; /* repeat the request on a different device. */
602         }
603 }
604
605 static int convert_response_rng(struct zcrypt_device *zdev,
606                                  struct ap_message *reply,
607                                  char *data)
608 {
609         struct type86x_reply *msg = reply->message;
610
611         switch (msg->hdr.type) {
612         case TYPE82_RSP_CODE:
613         case TYPE88_RSP_CODE:
614                 return -EINVAL;
615         case TYPE86_RSP_CODE:
616                 if (msg->hdr.reply_code)
617                         return -EINVAL;
618                 if (msg->cprbx.cprb_ver_id == 0x02)
619                         return convert_type86_rng(zdev, reply, data);
620                 /* Fall through, no break, incorrect cprb version is an unknown
621                  * response */
622         default: /* Unknown response type, this should NEVER EVER happen */
623                 zdev->online = 0;
624                 return -EAGAIN; /* repeat the request on a different device. */
625         }
626 }
627
628 /**
629  * This function is called from the AP bus code after a crypto request
630  * "msg" has finished with the reply message "reply".
631  * It is called from tasklet context.
632  * @ap_dev: pointer to the AP device
633  * @msg: pointer to the AP message
634  * @reply: pointer to the AP reply message
635  */
636 static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
637                                   struct ap_message *msg,
638                                   struct ap_message *reply)
639 {
640         static struct error_hdr error_reply = {
641                 .type = TYPE82_RSP_CODE,
642                 .reply_code = REP82_ERROR_MACHINE_FAILURE,
643         };
644         struct response_type *resp_type =
645                 (struct response_type *) msg->private;
646         struct type86x_reply *t86r;
647         int length;
648
649         /* Copy the reply message to the request message buffer. */
650         if (IS_ERR(reply)) {
651                 memcpy(msg->message, &error_reply, sizeof(error_reply));
652                 goto out;
653         }
654         t86r = reply->message;
655         if (t86r->hdr.type == TYPE86_RSP_CODE &&
656                  t86r->cprbx.cprb_ver_id == 0x02) {
657                 switch (resp_type->type) {
658                 case PCIXCC_RESPONSE_TYPE_ICA:
659                         length = sizeof(struct type86x_reply)
660                                 + t86r->length - 2;
661                         length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
662                         memcpy(msg->message, reply->message, length);
663                         break;
664                 case PCIXCC_RESPONSE_TYPE_XCRB:
665                         length = t86r->fmt2.offset2 + t86r->fmt2.count2;
666                         length = min(PCIXCC_MAX_XCRB_MESSAGE_SIZE, length);
667                         memcpy(msg->message, reply->message, length);
668                         break;
669                 default:
670                         memcpy(msg->message, &error_reply, sizeof error_reply);
671                 }
672         } else
673                 memcpy(msg->message, reply->message, sizeof error_reply);
674 out:
675         complete(&(resp_type->work));
676 }
677
678 static atomic_t zcrypt_step = ATOMIC_INIT(0);
679
680 /**
681  * The request distributor calls this function if it picked the PCIXCC/CEX2C
682  * device to handle a modexpo request.
683  * @zdev: pointer to zcrypt_device structure that identifies the
684  *        PCIXCC/CEX2C device to the request distributor
685  * @mex: pointer to the modexpo request buffer
686  */
687 static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
688                                   struct ica_rsa_modexpo *mex)
689 {
690         struct ap_message ap_msg;
691         struct response_type resp_type = {
692                 .type = PCIXCC_RESPONSE_TYPE_ICA,
693         };
694         int rc;
695
696         ap_init_message(&ap_msg);
697         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
698         if (!ap_msg.message)
699                 return -ENOMEM;
700         ap_msg.receive = zcrypt_pcixcc_receive;
701         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
702                                 atomic_inc_return(&zcrypt_step);
703         ap_msg.private = &resp_type;
704         rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
705         if (rc)
706                 goto out_free;
707         init_completion(&resp_type.work);
708         ap_queue_message(zdev->ap_dev, &ap_msg);
709         rc = wait_for_completion_interruptible(&resp_type.work);
710         if (rc == 0)
711                 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
712                                           mex->outputdatalength);
713         else
714                 /* Signal pending. */
715                 ap_cancel_message(zdev->ap_dev, &ap_msg);
716 out_free:
717         free_page((unsigned long) ap_msg.message);
718         return rc;
719 }
720
721 /**
722  * The request distributor calls this function if it picked the PCIXCC/CEX2C
723  * device to handle a modexpo_crt request.
724  * @zdev: pointer to zcrypt_device structure that identifies the
725  *        PCIXCC/CEX2C device to the request distributor
726  * @crt: pointer to the modexpoc_crt request buffer
727  */
728 static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
729                                       struct ica_rsa_modexpo_crt *crt)
730 {
731         struct ap_message ap_msg;
732         struct response_type resp_type = {
733                 .type = PCIXCC_RESPONSE_TYPE_ICA,
734         };
735         int rc;
736
737         ap_init_message(&ap_msg);
738         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
739         if (!ap_msg.message)
740                 return -ENOMEM;
741         ap_msg.receive = zcrypt_pcixcc_receive;
742         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
743                                 atomic_inc_return(&zcrypt_step);
744         ap_msg.private = &resp_type;
745         rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
746         if (rc)
747                 goto out_free;
748         init_completion(&resp_type.work);
749         ap_queue_message(zdev->ap_dev, &ap_msg);
750         rc = wait_for_completion_interruptible(&resp_type.work);
751         if (rc == 0)
752                 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
753                                           crt->outputdatalength);
754         else
755                 /* Signal pending. */
756                 ap_cancel_message(zdev->ap_dev, &ap_msg);
757 out_free:
758         free_page((unsigned long) ap_msg.message);
759         return rc;
760 }
761
762 /**
763  * The request distributor calls this function if it picked the PCIXCC/CEX2C
764  * device to handle a send_cprb request.
765  * @zdev: pointer to zcrypt_device structure that identifies the
766  *        PCIXCC/CEX2C device to the request distributor
767  * @xcRB: pointer to the send_cprb request buffer
768  */
769 static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
770                                     struct ica_xcRB *xcRB)
771 {
772         struct ap_message ap_msg;
773         struct response_type resp_type = {
774                 .type = PCIXCC_RESPONSE_TYPE_XCRB,
775         };
776         int rc;
777
778         ap_init_message(&ap_msg);
779         ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
780         if (!ap_msg.message)
781                 return -ENOMEM;
782         ap_msg.receive = zcrypt_pcixcc_receive;
783         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
784                                 atomic_inc_return(&zcrypt_step);
785         ap_msg.private = &resp_type;
786         rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
787         if (rc)
788                 goto out_free;
789         init_completion(&resp_type.work);
790         ap_queue_message(zdev->ap_dev, &ap_msg);
791         rc = wait_for_completion_interruptible(&resp_type.work);
792         if (rc == 0)
793                 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
794         else
795                 /* Signal pending. */
796                 ap_cancel_message(zdev->ap_dev, &ap_msg);
797 out_free:
798         kzfree(ap_msg.message);
799         return rc;
800 }
801
802 /**
803  * The request distributor calls this function if it picked the PCIXCC/CEX2C
804  * device to generate random data.
805  * @zdev: pointer to zcrypt_device structure that identifies the
806  *        PCIXCC/CEX2C device to the request distributor
807  * @buffer: pointer to a memory page to return random data
808  */
809
810 static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev,
811                                     char *buffer)
812 {
813         struct ap_message ap_msg;
814         struct response_type resp_type = {
815                 .type = PCIXCC_RESPONSE_TYPE_XCRB,
816         };
817         int rc;
818
819         ap_init_message(&ap_msg);
820         ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
821         if (!ap_msg.message)
822                 return -ENOMEM;
823         ap_msg.receive = zcrypt_pcixcc_receive;
824         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
825                                 atomic_inc_return(&zcrypt_step);
826         ap_msg.private = &resp_type;
827         rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
828         init_completion(&resp_type.work);
829         ap_queue_message(zdev->ap_dev, &ap_msg);
830         rc = wait_for_completion_interruptible(&resp_type.work);
831         if (rc == 0)
832                 rc = convert_response_rng(zdev, &ap_msg, buffer);
833         else
834                 /* Signal pending. */
835                 ap_cancel_message(zdev->ap_dev, &ap_msg);
836         kfree(ap_msg.message);
837         return rc;
838 }
839
840 /**
841  * The crypto operations for a PCIXCC/CEX2C card.
842  */
843 static struct zcrypt_ops zcrypt_pcixcc_ops = {
844         .rsa_modexpo = zcrypt_pcixcc_modexpo,
845         .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
846         .send_cprb = zcrypt_pcixcc_send_cprb,
847 };
848
849 static struct zcrypt_ops zcrypt_pcixcc_with_rng_ops = {
850         .rsa_modexpo = zcrypt_pcixcc_modexpo,
851         .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
852         .send_cprb = zcrypt_pcixcc_send_cprb,
853         .rng = zcrypt_pcixcc_rng,
854 };
855
856 /**
857  * Micro-code detection function. Its sends a message to a pcixcc card
858  * to find out the microcode level.
859  * @ap_dev: pointer to the AP device.
860  */
861 static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
862 {
863         static unsigned char msg[] = {
864                 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
865                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
866                 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
867                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
868                 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
869                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
870                 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
871                 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
872                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
873                 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
874                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
875                 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
876                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
877                 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
878                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
879                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
880                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
881                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
882                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
883                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
884                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
885                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
886                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
887                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
888                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
889                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
890                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
891                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
892                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
893                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
894                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
895                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
896                 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
897                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
898                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
899                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
900                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
901                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
902                 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
903                 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
904                 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
905                 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
906                 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
907                 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
908                 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
909                 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
910                 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
911                 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
912                 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
913                 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
914                 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
915                 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
916                 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
917                 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
918                 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
919                 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
920                 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
921                 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
922                 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
923                 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
924                 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
925                 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
926                 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
927                 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
928                 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
929                 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
930                 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
931                 0xF1,0x3D,0x93,0x53
932         };
933         unsigned long long psmid;
934         struct CPRBX *cprbx;
935         char *reply;
936         int rc, i;
937
938         reply = (void *) get_zeroed_page(GFP_KERNEL);
939         if (!reply)
940                 return -ENOMEM;
941
942         rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
943         if (rc)
944                 goto out_free;
945
946         /* Wait for the test message to complete. */
947         for (i = 0; i < 6; i++) {
948                 mdelay(300);
949                 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
950                 if (rc == 0 && psmid == 0x0102030405060708ULL)
951                         break;
952         }
953
954         if (i >= 6) {
955                 /* Got no answer. */
956                 rc = -ENODEV;
957                 goto out_free;
958         }
959
960         cprbx = (struct CPRBX *) (reply + 48);
961         if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
962                 rc = ZCRYPT_PCIXCC_MCL2;
963         else
964                 rc = ZCRYPT_PCIXCC_MCL3;
965 out_free:
966         free_page((unsigned long) reply);
967         return rc;
968 }
969
970 /**
971  * Large random number detection function. Its sends a message to a pcixcc
972  * card to find out if large random numbers are supported.
973  * @ap_dev: pointer to the AP device.
974  *
975  * Returns 1 if large random numbers are supported, 0 if not and < 0 on error.
976  */
977 static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
978 {
979         struct ap_message ap_msg;
980         unsigned long long psmid;
981         struct {
982                 struct type86_hdr hdr;
983                 struct type86_fmt2_ext fmt2;
984                 struct CPRBX cprbx;
985         } __attribute__((packed)) *reply;
986         int rc, i;
987
988         ap_init_message(&ap_msg);
989         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
990         if (!ap_msg.message)
991                 return -ENOMEM;
992
993         rng_type6CPRB_msgX(ap_dev, &ap_msg, 4);
994         rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, ap_msg.message,
995                      ap_msg.length);
996         if (rc)
997                 goto out_free;
998
999         /* Wait for the test message to complete. */
1000         for (i = 0; i < 2 * HZ; i++) {
1001                 msleep(1000 / HZ);
1002                 rc = ap_recv(ap_dev->qid, &psmid, ap_msg.message, 4096);
1003                 if (rc == 0 && psmid == 0x0102030405060708ULL)
1004                         break;
1005         }
1006
1007         if (i >= 2 * HZ) {
1008                 /* Got no answer. */
1009                 rc = -ENODEV;
1010                 goto out_free;
1011         }
1012
1013         reply = ap_msg.message;
1014         if (reply->cprbx.ccp_rtcode == 0 && reply->cprbx.ccp_rscode == 0)
1015                 rc = 1;
1016         else
1017                 rc = 0;
1018 out_free:
1019         free_page((unsigned long) ap_msg.message);
1020         return rc;
1021 }
1022
1023 /**
1024  * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
1025  * since the bus_match already checked the hardware type. The PCIXCC
1026  * cards come in two flavours: micro code level 2 and micro code level 3.
1027  * This is checked by sending a test message to the device.
1028  * @ap_dev: pointer to the AP device.
1029  */
1030 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
1031 {
1032         struct zcrypt_device *zdev;
1033         int rc = 0;
1034
1035         zdev = zcrypt_device_alloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE);
1036         if (!zdev)
1037                 return -ENOMEM;
1038         zdev->ap_dev = ap_dev;
1039         zdev->online = 1;
1040         switch (ap_dev->device_type) {
1041         case AP_DEVICE_TYPE_PCIXCC:
1042                 rc = zcrypt_pcixcc_mcl(ap_dev);
1043                 if (rc < 0) {
1044                         zcrypt_device_free(zdev);
1045                         return rc;
1046                 }
1047                 zdev->user_space_type = rc;
1048                 if (rc == ZCRYPT_PCIXCC_MCL2) {
1049                         zdev->type_string = "PCIXCC_MCL2";
1050                         zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
1051                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
1052                         zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1053                         zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
1054                 } else {
1055                         zdev->type_string = "PCIXCC_MCL3";
1056                         zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
1057                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1058                         zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1059                         zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
1060                 }
1061                 break;
1062         case AP_DEVICE_TYPE_CEX2C:
1063                 zdev->user_space_type = ZCRYPT_CEX2C;
1064                 zdev->type_string = "CEX2C";
1065                 zdev->speed_rating = CEX2C_SPEED_RATING;
1066                 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1067                 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1068                 zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
1069                 break;
1070         case AP_DEVICE_TYPE_CEX3C:
1071                 zdev->user_space_type = ZCRYPT_CEX3C;
1072                 zdev->type_string = "CEX3C";
1073                 zdev->speed_rating = CEX3C_SPEED_RATING;
1074                 zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
1075                 zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
1076                 zdev->max_exp_bit_length = CEX3C_MAX_MOD_SIZE;
1077                 break;
1078         default:
1079                 goto out_free;
1080         }
1081
1082         rc = zcrypt_pcixcc_rng_supported(ap_dev);
1083         if (rc < 0) {
1084                 zcrypt_device_free(zdev);
1085                 return rc;
1086         }
1087         if (rc)
1088                 zdev->ops = &zcrypt_pcixcc_with_rng_ops;
1089         else
1090                 zdev->ops = &zcrypt_pcixcc_ops;
1091         ap_dev->reply = &zdev->reply;
1092         ap_dev->private = zdev;
1093         rc = zcrypt_device_register(zdev);
1094         if (rc)
1095                 goto out_free;
1096         return 0;
1097
1098  out_free:
1099         ap_dev->private = NULL;
1100         zcrypt_device_free(zdev);
1101         return rc;
1102 }
1103
1104 /**
1105  * This is called to remove the extended PCIXCC/CEX2C driver information
1106  * if an AP device is removed.
1107  */
1108 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
1109 {
1110         struct zcrypt_device *zdev = ap_dev->private;
1111
1112         zcrypt_device_unregister(zdev);
1113 }
1114
1115 int __init zcrypt_pcixcc_init(void)
1116 {
1117         return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
1118 }
1119
1120 void zcrypt_pcixcc_exit(void)
1121 {
1122         ap_driver_unregister(&zcrypt_pcixcc_driver);
1123 }
1124
1125 module_init(zcrypt_pcixcc_init);
1126 module_exit(zcrypt_pcixcc_exit);