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