]> Pileus Git - ~andy/linux/blob - drivers/s390/crypto/zcrypt_pcixcc.c
cdaa401f20cd1a7ae866d8181c38e19392074e12
[~andy/linux] / 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_CEX3C) },
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         if (memcmp(function_code, "US", 2) == 0)
330                 ap_msg->special = 1;
331         else
332                 ap_msg->special = 0;
333
334         /* copy data block */
335         if (xcRB->request_data_length &&
336             copy_from_user(req_data, xcRB->request_data_address,
337                 xcRB->request_data_length))
338                 return -EFAULT;
339         return 0;
340 }
341
342 /**
343  * Prepare a type6 CPRB message for random number generation
344  *
345  * @ap_dev: AP device pointer
346  * @ap_msg: pointer to AP message
347  */
348 static void rng_type6CPRB_msgX(struct ap_device *ap_dev,
349                                struct ap_message *ap_msg,
350                                unsigned random_number_length)
351 {
352         struct {
353                 struct type6_hdr hdr;
354                 struct CPRBX cprbx;
355                 char function_code[2];
356                 short int rule_length;
357                 char rule[8];
358                 short int verb_length;
359                 short int key_length;
360         } __attribute__((packed)) *msg = ap_msg->message;
361         static struct type6_hdr static_type6_hdrX = {
362                 .type           = 0x06,
363                 .offset1        = 0x00000058,
364                 .agent_id       = {'C', 'A'},
365                 .function_code  = {'R', 'L'},
366                 .ToCardLen1     = sizeof *msg - sizeof(msg->hdr),
367                 .FromCardLen1   = sizeof *msg - sizeof(msg->hdr),
368         };
369         static struct CPRBX local_cprbx = {
370                 .cprb_len       = 0x00dc,
371                 .cprb_ver_id    = 0x02,
372                 .func_id        = {0x54, 0x32},
373                 .req_parml      = sizeof *msg - sizeof(msg->hdr) -
374                                   sizeof(msg->cprbx),
375                 .rpl_msgbl      = sizeof *msg - sizeof(msg->hdr),
376         };
377
378         msg->hdr = static_type6_hdrX;
379         msg->hdr.FromCardLen2 = random_number_length,
380         msg->cprbx = local_cprbx;
381         msg->cprbx.rpl_datal = random_number_length,
382         msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid);
383         memcpy(msg->function_code, msg->hdr.function_code, 0x02);
384         msg->rule_length = 0x0a;
385         memcpy(msg->rule, "RANDOM  ", 8);
386         msg->verb_length = 0x02;
387         msg->key_length = 0x02;
388         ap_msg->length = sizeof *msg;
389 }
390
391 /**
392  * Copy results from a type 86 ICA reply message back to user space.
393  *
394  * @zdev: crypto device pointer
395  * @reply: reply AP message.
396  * @data: pointer to user output data
397  * @length: size of user output data
398  *
399  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
400  */
401 struct type86x_reply {
402         struct type86_hdr hdr;
403         struct type86_fmt2_ext fmt2;
404         struct CPRBX cprbx;
405         unsigned char pad[4];   /* 4 byte function code/rules block ? */
406         unsigned short length;
407         char text[0];
408 } __attribute__((packed));
409
410 static int convert_type86_ica(struct zcrypt_device *zdev,
411                           struct ap_message *reply,
412                           char __user *outputdata,
413                           unsigned int outputdatalength)
414 {
415         static unsigned char static_pad[] = {
416                 0x00,0x02,
417                 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
418                 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
419                 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
420                 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
421                 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
422                 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
423                 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
424                 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
425                 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
426                 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
427                 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
428                 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
429                 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
430                 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
431                 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
432                 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
433                 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
434                 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
435                 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
436                 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
437                 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
438                 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
439                 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
440                 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
441                 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
442                 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
443                 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
444                 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
445                 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
446                 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
447                 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
448                 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
449         };
450         struct type86x_reply *msg = reply->message;
451         unsigned short service_rc, service_rs;
452         unsigned int reply_len, pad_len;
453         char *data;
454
455         service_rc = msg->cprbx.ccp_rtcode;
456         if (unlikely(service_rc != 0)) {
457                 service_rs = msg->cprbx.ccp_rscode;
458                 if (service_rc == 8 && service_rs == 66)
459                         return -EINVAL;
460                 if (service_rc == 8 && service_rs == 65)
461                         return -EINVAL;
462                 if (service_rc == 8 && service_rs == 770)
463                         return -EINVAL;
464                 if (service_rc == 8 && service_rs == 783) {
465                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
466                         return -EAGAIN;
467                 }
468                 if (service_rc == 12 && service_rs == 769)
469                         return -EINVAL;
470                 zdev->online = 0;
471                 return -EAGAIN; /* repeat the request on a different device. */
472         }
473         data = msg->text;
474         reply_len = msg->length - 2;
475         if (reply_len > outputdatalength)
476                 return -EINVAL;
477         /*
478          * For all encipher requests, the length of the ciphertext (reply_len)
479          * will always equal the modulus length. For MEX decipher requests
480          * the output needs to get padded. Minimum pad size is 10.
481          *
482          * Currently, the cases where padding will be added is for:
483          * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
484          *   ZERO-PAD and CRT is only supported for PKD requests)
485          * - PCICC, always
486          */
487         pad_len = outputdatalength - reply_len;
488         if (pad_len > 0) {
489                 if (pad_len < 10)
490                         return -EINVAL;
491                 /* 'restore' padding left in the PCICC/PCIXCC card. */
492                 if (copy_to_user(outputdata, static_pad, pad_len - 1))
493                         return -EFAULT;
494                 if (put_user(0, outputdata + pad_len - 1))
495                         return -EFAULT;
496         }
497         /* Copy the crypto response to user space. */
498         if (copy_to_user(outputdata + pad_len, data, reply_len))
499                 return -EFAULT;
500         return 0;
501 }
502
503 /**
504  * Copy results from a type 86 XCRB reply message back to user space.
505  *
506  * @zdev: crypto device pointer
507  * @reply: reply AP message.
508  * @xcRB: pointer to XCRB
509  *
510  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
511  */
512 static int convert_type86_xcrb(struct zcrypt_device *zdev,
513                                struct ap_message *reply,
514                                struct ica_xcRB *xcRB)
515 {
516         struct type86_fmt2_msg *msg = reply->message;
517         char *data = reply->message;
518
519         /* Copy CPRB to user */
520         if (copy_to_user(xcRB->reply_control_blk_addr,
521                 data + msg->fmt2.offset1, msg->fmt2.count1))
522                 return -EFAULT;
523         xcRB->reply_control_blk_length = msg->fmt2.count1;
524
525         /* Copy data buffer to user */
526         if (msg->fmt2.count2)
527                 if (copy_to_user(xcRB->reply_data_addr,
528                         data + msg->fmt2.offset2, msg->fmt2.count2))
529                         return -EFAULT;
530         xcRB->reply_data_length = msg->fmt2.count2;
531         return 0;
532 }
533
534 static int convert_type86_rng(struct zcrypt_device *zdev,
535                           struct ap_message *reply,
536                           char *buffer)
537 {
538         struct {
539                 struct type86_hdr hdr;
540                 struct type86_fmt2_ext fmt2;
541                 struct CPRBX cprbx;
542         } __attribute__((packed)) *msg = reply->message;
543         char *data = reply->message;
544
545         if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
546                 return -EINVAL;
547         memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
548         return msg->fmt2.count2;
549 }
550
551 static int convert_response_ica(struct zcrypt_device *zdev,
552                             struct ap_message *reply,
553                             char __user *outputdata,
554                             unsigned int outputdatalength)
555 {
556         struct type86x_reply *msg = reply->message;
557
558         /* Response type byte is the second byte in the response. */
559         switch (((unsigned char *) reply->message)[1]) {
560         case TYPE82_RSP_CODE:
561         case TYPE88_RSP_CODE:
562                 return convert_error(zdev, reply);
563         case TYPE86_RSP_CODE:
564                 if (msg->hdr.reply_code)
565                         return convert_error(zdev, reply);
566                 if (msg->cprbx.cprb_ver_id == 0x02)
567                         return convert_type86_ica(zdev, reply,
568                                                   outputdata, outputdatalength);
569                 /* Fall through, no break, incorrect cprb version is an unknown
570                  * response */
571         default: /* Unknown response type, this should NEVER EVER happen */
572                 zdev->online = 0;
573                 return -EAGAIN; /* repeat the request on a different device. */
574         }
575 }
576
577 static int convert_response_xcrb(struct zcrypt_device *zdev,
578                             struct ap_message *reply,
579                             struct ica_xcRB *xcRB)
580 {
581         struct type86x_reply *msg = reply->message;
582
583         /* Response type byte is the second byte in the response. */
584         switch (((unsigned char *) reply->message)[1]) {
585         case TYPE82_RSP_CODE:
586         case TYPE88_RSP_CODE:
587                 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
588                 return convert_error(zdev, reply);
589         case TYPE86_RSP_CODE:
590                 if (msg->hdr.reply_code) {
591                         memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
592                         return convert_error(zdev, reply);
593                 }
594                 if (msg->cprbx.cprb_ver_id == 0x02)
595                         return convert_type86_xcrb(zdev, reply, xcRB);
596                 /* Fall through, no break, incorrect cprb version is an unknown
597                  * response */
598         default: /* Unknown response type, this should NEVER EVER happen */
599                 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
600                 zdev->online = 0;
601                 return -EAGAIN; /* repeat the request on a different device. */
602         }
603 }
604
605 static int convert_response_rng(struct zcrypt_device *zdev,
606                                  struct ap_message *reply,
607                                  char *data)
608 {
609         struct type86x_reply *msg = reply->message;
610
611         switch (msg->hdr.type) {
612         case TYPE82_RSP_CODE:
613         case TYPE88_RSP_CODE:
614                 return -EINVAL;
615         case TYPE86_RSP_CODE:
616                 if (msg->hdr.reply_code)
617                         return -EINVAL;
618                 if (msg->cprbx.cprb_ver_id == 0x02)
619                         return convert_type86_rng(zdev, reply, data);
620                 /* Fall through, no break, incorrect cprb version is an unknown
621                  * response */
622         default: /* Unknown response type, this should NEVER EVER happen */
623                 zdev->online = 0;
624                 return -EAGAIN; /* repeat the request on a different device. */
625         }
626 }
627
628 /**
629  * This function is called from the AP bus code after a crypto request
630  * "msg" has finished with the reply message "reply".
631  * It is called from tasklet context.
632  * @ap_dev: pointer to the AP device
633  * @msg: pointer to the AP message
634  * @reply: pointer to the AP reply message
635  */
636 static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
637                                   struct ap_message *msg,
638                                   struct ap_message *reply)
639 {
640         static struct error_hdr error_reply = {
641                 .type = TYPE82_RSP_CODE,
642                 .reply_code = REP82_ERROR_MACHINE_FAILURE,
643         };
644         struct response_type *resp_type =
645                 (struct response_type *) msg->private;
646         struct type86x_reply *t86r;
647         int length;
648
649         /* Copy the reply message to the request message buffer. */
650         if (IS_ERR(reply)) {
651                 memcpy(msg->message, &error_reply, sizeof(error_reply));
652                 goto out;
653         }
654         t86r = reply->message;
655         if (t86r->hdr.type == TYPE86_RSP_CODE &&
656                  t86r->cprbx.cprb_ver_id == 0x02) {
657                 switch (resp_type->type) {
658                 case PCIXCC_RESPONSE_TYPE_ICA:
659                         length = sizeof(struct type86x_reply)
660                                 + t86r->length - 2;
661                         length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
662                         memcpy(msg->message, reply->message, length);
663                         break;
664                 case PCIXCC_RESPONSE_TYPE_XCRB:
665                         length = t86r->fmt2.offset2 + t86r->fmt2.count2;
666                         length = min(PCIXCC_MAX_XCRB_RESPONSE_SIZE, length);
667                         memcpy(msg->message, reply->message, length);
668                         break;
669                 default:
670                         memcpy(msg->message, &error_reply, sizeof error_reply);
671                 }
672         } else
673                 memcpy(msg->message, reply->message, sizeof error_reply);
674 out:
675         complete(&(resp_type->work));
676 }
677
678 static atomic_t zcrypt_step = ATOMIC_INIT(0);
679
680 /**
681  * The request distributor calls this function if it picked the PCIXCC/CEX2C
682  * device to handle a modexpo request.
683  * @zdev: pointer to zcrypt_device structure that identifies the
684  *        PCIXCC/CEX2C device to the request distributor
685  * @mex: pointer to the modexpo request buffer
686  */
687 static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
688                                   struct ica_rsa_modexpo *mex)
689 {
690         struct ap_message ap_msg;
691         struct response_type resp_type = {
692                 .type = PCIXCC_RESPONSE_TYPE_ICA,
693         };
694         int rc;
695
696         ap_init_message(&ap_msg);
697         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
698         if (!ap_msg.message)
699                 return -ENOMEM;
700         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
701                                 atomic_inc_return(&zcrypt_step);
702         ap_msg.private = &resp_type;
703         rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
704         if (rc)
705                 goto out_free;
706         init_completion(&resp_type.work);
707         ap_queue_message(zdev->ap_dev, &ap_msg);
708         rc = wait_for_completion_interruptible(&resp_type.work);
709         if (rc == 0)
710                 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
711                                           mex->outputdatalength);
712         else
713                 /* Signal pending. */
714                 ap_cancel_message(zdev->ap_dev, &ap_msg);
715 out_free:
716         free_page((unsigned long) ap_msg.message);
717         return rc;
718 }
719
720 /**
721  * The request distributor calls this function if it picked the PCIXCC/CEX2C
722  * device to handle a modexpo_crt request.
723  * @zdev: pointer to zcrypt_device structure that identifies the
724  *        PCIXCC/CEX2C device to the request distributor
725  * @crt: pointer to the modexpoc_crt request buffer
726  */
727 static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
728                                       struct ica_rsa_modexpo_crt *crt)
729 {
730         struct ap_message ap_msg;
731         struct response_type resp_type = {
732                 .type = PCIXCC_RESPONSE_TYPE_ICA,
733         };
734         int rc;
735
736         ap_init_message(&ap_msg);
737         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
738         if (!ap_msg.message)
739                 return -ENOMEM;
740         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
741                                 atomic_inc_return(&zcrypt_step);
742         ap_msg.private = &resp_type;
743         rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
744         if (rc)
745                 goto out_free;
746         init_completion(&resp_type.work);
747         ap_queue_message(zdev->ap_dev, &ap_msg);
748         rc = wait_for_completion_interruptible(&resp_type.work);
749         if (rc == 0)
750                 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
751                                           crt->outputdatalength);
752         else
753                 /* Signal pending. */
754                 ap_cancel_message(zdev->ap_dev, &ap_msg);
755 out_free:
756         free_page((unsigned long) ap_msg.message);
757         return rc;
758 }
759
760 /**
761  * The request distributor calls this function if it picked the PCIXCC/CEX2C
762  * device to handle a send_cprb request.
763  * @zdev: pointer to zcrypt_device structure that identifies the
764  *        PCIXCC/CEX2C device to the request distributor
765  * @xcRB: pointer to the send_cprb request buffer
766  */
767 static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
768                                     struct ica_xcRB *xcRB)
769 {
770         struct ap_message ap_msg;
771         struct response_type resp_type = {
772                 .type = PCIXCC_RESPONSE_TYPE_XCRB,
773         };
774         int rc;
775
776         ap_init_message(&ap_msg);
777         ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
778         if (!ap_msg.message)
779                 return -ENOMEM;
780         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
781                                 atomic_inc_return(&zcrypt_step);
782         ap_msg.private = &resp_type;
783         rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
784         if (rc)
785                 goto out_free;
786         init_completion(&resp_type.work);
787         ap_queue_message(zdev->ap_dev, &ap_msg);
788         rc = wait_for_completion_interruptible(&resp_type.work);
789         if (rc == 0)
790                 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
791         else
792                 /* Signal pending. */
793                 ap_cancel_message(zdev->ap_dev, &ap_msg);
794 out_free:
795         kzfree(ap_msg.message);
796         return rc;
797 }
798
799 /**
800  * The request distributor calls this function if it picked the PCIXCC/CEX2C
801  * device to generate random data.
802  * @zdev: pointer to zcrypt_device structure that identifies the
803  *        PCIXCC/CEX2C device to the request distributor
804  * @buffer: pointer to a memory page to return random data
805  */
806
807 static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev,
808                                     char *buffer)
809 {
810         struct ap_message ap_msg;
811         struct response_type resp_type = {
812                 .type = PCIXCC_RESPONSE_TYPE_XCRB,
813         };
814         int rc;
815
816         ap_init_message(&ap_msg);
817         ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
818         if (!ap_msg.message)
819                 return -ENOMEM;
820         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
821                                 atomic_inc_return(&zcrypt_step);
822         ap_msg.private = &resp_type;
823         rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
824         init_completion(&resp_type.work);
825         ap_queue_message(zdev->ap_dev, &ap_msg);
826         rc = wait_for_completion_interruptible(&resp_type.work);
827         if (rc == 0)
828                 rc = convert_response_rng(zdev, &ap_msg, buffer);
829         else
830                 /* Signal pending. */
831                 ap_cancel_message(zdev->ap_dev, &ap_msg);
832         kfree(ap_msg.message);
833         return rc;
834 }
835
836 /**
837  * The crypto operations for a PCIXCC/CEX2C card.
838  */
839 static struct zcrypt_ops zcrypt_pcixcc_ops = {
840         .rsa_modexpo = zcrypt_pcixcc_modexpo,
841         .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
842         .send_cprb = zcrypt_pcixcc_send_cprb,
843 };
844
845 static struct zcrypt_ops zcrypt_pcixcc_with_rng_ops = {
846         .rsa_modexpo = zcrypt_pcixcc_modexpo,
847         .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
848         .send_cprb = zcrypt_pcixcc_send_cprb,
849         .rng = zcrypt_pcixcc_rng,
850 };
851
852 /**
853  * Micro-code detection function. Its sends a message to a pcixcc card
854  * to find out the microcode level.
855  * @ap_dev: pointer to the AP device.
856  */
857 static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
858 {
859         static unsigned char msg[] = {
860                 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
861                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
862                 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
863                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
864                 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
865                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
866                 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
867                 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
868                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
869                 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
870                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
871                 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
872                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
873                 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
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,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,0x04,0x00,0x00,0x00,0x00,
893                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
894                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
895                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
896                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
897                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
898                 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
899                 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
900                 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
901                 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
902                 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
903                 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
904                 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
905                 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
906                 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
907                 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
908                 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
909                 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
910                 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
911                 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
912                 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
913                 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
914                 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
915                 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
916                 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
917                 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
918                 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
919                 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
920                 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
921                 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
922                 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
923                 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
924                 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
925                 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
926                 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
927                 0xF1,0x3D,0x93,0x53
928         };
929         unsigned long long psmid;
930         struct CPRBX *cprbx;
931         char *reply;
932         int rc, i;
933
934         reply = (void *) get_zeroed_page(GFP_KERNEL);
935         if (!reply)
936                 return -ENOMEM;
937
938         rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
939         if (rc)
940                 goto out_free;
941
942         /* Wait for the test message to complete. */
943         for (i = 0; i < 6; i++) {
944                 mdelay(300);
945                 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
946                 if (rc == 0 && psmid == 0x0102030405060708ULL)
947                         break;
948         }
949
950         if (i >= 6) {
951                 /* Got no answer. */
952                 rc = -ENODEV;
953                 goto out_free;
954         }
955
956         cprbx = (struct CPRBX *) (reply + 48);
957         if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
958                 rc = ZCRYPT_PCIXCC_MCL2;
959         else
960                 rc = ZCRYPT_PCIXCC_MCL3;
961 out_free:
962         free_page((unsigned long) reply);
963         return rc;
964 }
965
966 /**
967  * Large random number detection function. Its sends a message to a pcixcc
968  * card to find out if large random numbers are supported.
969  * @ap_dev: pointer to the AP device.
970  *
971  * Returns 1 if large random numbers are supported, 0 if not and < 0 on error.
972  */
973 static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
974 {
975         struct ap_message ap_msg;
976         unsigned long long psmid;
977         struct {
978                 struct type86_hdr hdr;
979                 struct type86_fmt2_ext fmt2;
980                 struct CPRBX cprbx;
981         } __attribute__((packed)) *reply;
982         int rc, i;
983
984         ap_init_message(&ap_msg);
985         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
986         if (!ap_msg.message)
987                 return -ENOMEM;
988
989         rng_type6CPRB_msgX(ap_dev, &ap_msg, 4);
990         rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, ap_msg.message,
991                      ap_msg.length);
992         if (rc)
993                 goto out_free;
994
995         /* Wait for the test message to complete. */
996         for (i = 0; i < 2 * HZ; i++) {
997                 msleep(1000 / HZ);
998                 rc = ap_recv(ap_dev->qid, &psmid, ap_msg.message, 4096);
999                 if (rc == 0 && psmid == 0x0102030405060708ULL)
1000                         break;
1001         }
1002
1003         if (i >= 2 * HZ) {
1004                 /* Got no answer. */
1005                 rc = -ENODEV;
1006                 goto out_free;
1007         }
1008
1009         reply = ap_msg.message;
1010         if (reply->cprbx.ccp_rtcode == 0 && reply->cprbx.ccp_rscode == 0)
1011                 rc = 1;
1012         else
1013                 rc = 0;
1014 out_free:
1015         free_page((unsigned long) ap_msg.message);
1016         return rc;
1017 }
1018
1019 /**
1020  * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
1021  * since the bus_match already checked the hardware type. The PCIXCC
1022  * cards come in two flavours: micro code level 2 and micro code level 3.
1023  * This is checked by sending a test message to the device.
1024  * @ap_dev: pointer to the AP device.
1025  */
1026 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
1027 {
1028         struct zcrypt_device *zdev;
1029         int rc;
1030
1031         zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
1032         if (!zdev)
1033                 return -ENOMEM;
1034         zdev->ap_dev = ap_dev;
1035         zdev->online = 1;
1036         if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) {
1037                 rc = zcrypt_pcixcc_mcl(ap_dev);
1038                 if (rc < 0) {
1039                         zcrypt_device_free(zdev);
1040                         return rc;
1041                 }
1042                 zdev->user_space_type = rc;
1043                 if (rc == ZCRYPT_PCIXCC_MCL2) {
1044                         zdev->type_string = "PCIXCC_MCL2";
1045                         zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
1046                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
1047                         zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1048                 } else {
1049                         zdev->type_string = "PCIXCC_MCL3";
1050                         zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
1051                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1052                         zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1053                 }
1054         } else {
1055                 zdev->user_space_type = ZCRYPT_CEX2C;
1056                 zdev->type_string = "CEX2C";
1057                 zdev->speed_rating = CEX2C_SPEED_RATING;
1058                 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1059                 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1060         }
1061         rc = zcrypt_pcixcc_rng_supported(ap_dev);
1062         if (rc < 0) {
1063                 zcrypt_device_free(zdev);
1064                 return rc;
1065         }
1066         if (rc)
1067                 zdev->ops = &zcrypt_pcixcc_with_rng_ops;
1068         else
1069                 zdev->ops = &zcrypt_pcixcc_ops;
1070         ap_dev->reply = &zdev->reply;
1071         ap_dev->private = zdev;
1072         rc = zcrypt_device_register(zdev);
1073         if (rc)
1074                 goto out_free;
1075         return 0;
1076
1077  out_free:
1078         ap_dev->private = NULL;
1079         zcrypt_device_free(zdev);
1080         return rc;
1081 }
1082
1083 /**
1084  * This is called to remove the extended PCIXCC/CEX2C driver information
1085  * if an AP device is removed.
1086  */
1087 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
1088 {
1089         struct zcrypt_device *zdev = ap_dev->private;
1090
1091         zcrypt_device_unregister(zdev);
1092 }
1093
1094 int __init zcrypt_pcixcc_init(void)
1095 {
1096         return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
1097 }
1098
1099 void zcrypt_pcixcc_exit(void)
1100 {
1101         ap_driver_unregister(&zcrypt_pcixcc_driver);
1102 }
1103
1104 #ifndef CONFIG_ZCRYPT_MONOLITHIC
1105 module_init(zcrypt_pcixcc_init);
1106 module_exit(zcrypt_pcixcc_exit);
1107 #endif