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