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