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