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