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