vfs: remove extraneous NULL d_inode check from do_filp_open
[linux-2.6-block.git] / drivers / s390 / crypto / zcrypt_pcixcc.c
CommitLineData
6684af1a
MS
1/*
2 * linux/drivers/s390/crypto/zcrypt_pcixcc.c
3 *
5432114b 4 * zcrypt 2.1.0
6684af1a
MS
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 */
8e89b6be
FB
46#define CEX3C_MIN_MOD_SIZE PCIXCC_MIN_MOD_SIZE
47#define CEX3C_MAX_MOD_SIZE PCIXCC_MAX_MOD_SIZE
6684af1a 48
18278dff 49#define PCIXCC_MCL2_SPEED_RATING 7870
6684af1a 50#define PCIXCC_MCL3_SPEED_RATING 7870
18278dff 51#define CEX2C_SPEED_RATING 7000
7a6f5cd0 52#define CEX3C_SPEED_RATING 6500 /* FIXME: needs finetuning */
6684af1a
MS
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
5432114b
RW
66#define CEIL4(x) ((((x)+3)/4)*4)
67
68struct 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
6684af1a
MS
75static struct ap_device_id zcrypt_pcixcc_ids[] = {
76 { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
77 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
ffda4f71 78 { AP_DEVICE(AP_DEVICE_TYPE_CEX3C) },
6684af1a
MS
79 { /* end of list */ },
80};
81
82#ifndef CONFIG_ZCRYPT_MONOLITHIC
83MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
84MODULE_AUTHOR("IBM Corporation");
85MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, "
86 "Copyright 2001, 2006 IBM Corporation");
87MODULE_LICENSE("GPL");
88#endif
89
90static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
91static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
92static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *,
93 struct ap_message *);
94
95static 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,
af512ed0 100 .request_timeout = PCIXCC_CLEANUP_TIME,
6684af1a
MS
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 */
120static 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 */
135static 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 */
202static 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
5432114b
RW
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 */
269struct type86_fmt2_msg {
270 struct type86_hdr hdr;
271 struct type86_fmt2_ext fmt2;
272} __attribute__((packed));
273
274static 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;
16db63fd 284 struct CPRBX cprbx;
5432114b
RW
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;
1a89dd8f 296 if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
5432114b 297 return -EFAULT;
1a89dd8f 298 if (CEIL4(xcRB->reply_control_blk_length) > PCIXCC_MAX_XCRB_REPLY_SIZE)
5432114b 299 return -EFAULT;
1a89dd8f 300 if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE)
5432114b 301 return -EFAULT;
5432114b
RW
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) {
5432114b
RW
306 xcRB->reply_control_blk_length = PCIXCC_MAX_XCRB_RESPONSE_SIZE -
307 (sizeof(struct type86_fmt2_msg) +
308 CEIL4(xcRB->reply_data_length));
5432114b
RW
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) >
1a89dd8f 327 xcRB->request_control_blk_length)
5432114b 328 return -EFAULT;
5432114b
RW
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
a6a5d73a
FB
332 if (memcmp(function_code, "US", 2) == 0)
333 ap_msg->special = 1;
334 else
335 ap_msg->special = 0;
336
5432114b
RW
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
2f7c8bd6
RW
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 */
351static 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 };
6458abc9 372 static struct CPRBX local_cprbx = {
2f7c8bd6
RW
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,
6458abc9 383 msg->cprbx = local_cprbx;
2f7c8bd6
RW
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
6684af1a
MS
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 */
404struct 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
413static 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;
1a89dd8f 461 if (service_rc == 8 && service_rs == 66)
6684af1a 462 return -EINVAL;
1a89dd8f 463 if (service_rc == 8 && service_rs == 65)
6684af1a 464 return -EINVAL;
1a89dd8f 465 if (service_rc == 8 && service_rs == 770)
2af48080 466 return -EINVAL;
6684af1a 467 if (service_rc == 8 && service_rs == 783) {
6684af1a
MS
468 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
469 return -EAGAIN;
470 }
1a89dd8f 471 if (service_rc == 12 && service_rs == 769)
2af48080 472 return -EINVAL;
6684af1a
MS
473 zdev->online = 0;
474 return -EAGAIN; /* repeat the request on a different device. */
475 }
476 data = msg->text;
477 reply_len = msg->length - 2;
478 if (reply_len > outputdatalength)
479 return -EINVAL;
1749a81d 480 /*
6684af1a
MS
481 * For all encipher requests, the length of the ciphertext (reply_len)
482 * will always equal the modulus length. For MEX decipher requests
483 * the output needs to get padded. Minimum pad size is 10.
484 *
485 * Currently, the cases where padding will be added is for:
486 * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
487 * ZERO-PAD and CRT is only supported for PKD requests)
488 * - PCICC, always
489 */
490 pad_len = outputdatalength - reply_len;
491 if (pad_len > 0) {
492 if (pad_len < 10)
493 return -EINVAL;
494 /* 'restore' padding left in the PCICC/PCIXCC card. */
495 if (copy_to_user(outputdata, static_pad, pad_len - 1))
496 return -EFAULT;
497 if (put_user(0, outputdata + pad_len - 1))
498 return -EFAULT;
499 }
500 /* Copy the crypto response to user space. */
501 if (copy_to_user(outputdata + pad_len, data, reply_len))
502 return -EFAULT;
503 return 0;
504}
505
5432114b
RW
506/**
507 * Copy results from a type 86 XCRB reply message back to user space.
508 *
509 * @zdev: crypto device pointer
510 * @reply: reply AP message.
511 * @xcRB: pointer to XCRB
512 *
513 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
514 */
515static int convert_type86_xcrb(struct zcrypt_device *zdev,
516 struct ap_message *reply,
517 struct ica_xcRB *xcRB)
518{
519 struct type86_fmt2_msg *msg = reply->message;
520 char *data = reply->message;
521
522 /* Copy CPRB to user */
523 if (copy_to_user(xcRB->reply_control_blk_addr,
524 data + msg->fmt2.offset1, msg->fmt2.count1))
525 return -EFAULT;
526 xcRB->reply_control_blk_length = msg->fmt2.count1;
527
528 /* Copy data buffer to user */
529 if (msg->fmt2.count2)
530 if (copy_to_user(xcRB->reply_data_addr,
531 data + msg->fmt2.offset2, msg->fmt2.count2))
532 return -EFAULT;
533 xcRB->reply_data_length = msg->fmt2.count2;
534 return 0;
535}
536
2f7c8bd6
RW
537static int convert_type86_rng(struct zcrypt_device *zdev,
538 struct ap_message *reply,
539 char *buffer)
540{
541 struct {
542 struct type86_hdr hdr;
543 struct type86_fmt2_ext fmt2;
544 struct CPRBX cprbx;
545 } __attribute__((packed)) *msg = reply->message;
546 char *data = reply->message;
547
1a89dd8f 548 if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
2f7c8bd6 549 return -EINVAL;
2f7c8bd6
RW
550 memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
551 return msg->fmt2.count2;
552}
553
6684af1a
MS
554static int convert_response_ica(struct zcrypt_device *zdev,
555 struct ap_message *reply,
556 char __user *outputdata,
557 unsigned int outputdatalength)
558{
559 struct type86x_reply *msg = reply->message;
560
561 /* Response type byte is the second byte in the response. */
562 switch (((unsigned char *) reply->message)[1]) {
563 case TYPE82_RSP_CODE:
564 case TYPE88_RSP_CODE:
565 return convert_error(zdev, reply);
566 case TYPE86_RSP_CODE:
567 if (msg->hdr.reply_code)
568 return convert_error(zdev, reply);
569 if (msg->cprbx.cprb_ver_id == 0x02)
570 return convert_type86_ica(zdev, reply,
571 outputdata, outputdatalength);
942b7e65
FB
572 /* Fall through, no break, incorrect cprb version is an unknown
573 * response */
6684af1a 574 default: /* Unknown response type, this should NEVER EVER happen */
6684af1a
MS
575 zdev->online = 0;
576 return -EAGAIN; /* repeat the request on a different device. */
577 }
578}
579
5432114b
RW
580static int convert_response_xcrb(struct zcrypt_device *zdev,
581 struct ap_message *reply,
582 struct ica_xcRB *xcRB)
583{
584 struct type86x_reply *msg = reply->message;
585
586 /* Response type byte is the second byte in the response. */
587 switch (((unsigned char *) reply->message)[1]) {
588 case TYPE82_RSP_CODE:
589 case TYPE88_RSP_CODE:
590 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
591 return convert_error(zdev, reply);
592 case TYPE86_RSP_CODE:
593 if (msg->hdr.reply_code) {
594 memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
595 return convert_error(zdev, reply);
596 }
597 if (msg->cprbx.cprb_ver_id == 0x02)
598 return convert_type86_xcrb(zdev, reply, xcRB);
942b7e65
FB
599 /* Fall through, no break, incorrect cprb version is an unknown
600 * response */
5432114b 601 default: /* Unknown response type, this should NEVER EVER happen */
5432114b
RW
602 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
603 zdev->online = 0;
604 return -EAGAIN; /* repeat the request on a different device. */
605 }
606}
607
2f7c8bd6
RW
608static int convert_response_rng(struct zcrypt_device *zdev,
609 struct ap_message *reply,
610 char *data)
611{
612 struct type86x_reply *msg = reply->message;
613
614 switch (msg->hdr.type) {
615 case TYPE82_RSP_CODE:
616 case TYPE88_RSP_CODE:
617 return -EINVAL;
618 case TYPE86_RSP_CODE:
619 if (msg->hdr.reply_code)
620 return -EINVAL;
621 if (msg->cprbx.cprb_ver_id == 0x02)
622 return convert_type86_rng(zdev, reply, data);
942b7e65
FB
623 /* Fall through, no break, incorrect cprb version is an unknown
624 * response */
2f7c8bd6 625 default: /* Unknown response type, this should NEVER EVER happen */
2f7c8bd6
RW
626 zdev->online = 0;
627 return -EAGAIN; /* repeat the request on a different device. */
628 }
629}
630
6684af1a
MS
631/**
632 * This function is called from the AP bus code after a crypto request
633 * "msg" has finished with the reply message "reply".
634 * It is called from tasklet context.
635 * @ap_dev: pointer to the AP device
636 * @msg: pointer to the AP message
637 * @reply: pointer to the AP reply message
638 */
639static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
640 struct ap_message *msg,
641 struct ap_message *reply)
642{
643 static struct error_hdr error_reply = {
644 .type = TYPE82_RSP_CODE,
645 .reply_code = REP82_ERROR_MACHINE_FAILURE,
646 };
5432114b
RW
647 struct response_type *resp_type =
648 (struct response_type *) msg->private;
21e7b2c4 649 struct type86x_reply *t86r;
6684af1a
MS
650 int length;
651
652 /* Copy the reply message to the request message buffer. */
21e7b2c4 653 if (IS_ERR(reply)) {
6684af1a 654 memcpy(msg->message, &error_reply, sizeof(error_reply));
21e7b2c4
JL
655 goto out;
656 }
657 t86r = reply->message;
658 if (t86r->hdr.type == TYPE86_RSP_CODE &&
6684af1a 659 t86r->cprbx.cprb_ver_id == 0x02) {
5432114b
RW
660 switch (resp_type->type) {
661 case PCIXCC_RESPONSE_TYPE_ICA:
662 length = sizeof(struct type86x_reply)
663 + t86r->length - 2;
664 length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
665 memcpy(msg->message, reply->message, length);
666 break;
667 case PCIXCC_RESPONSE_TYPE_XCRB:
668 length = t86r->fmt2.offset2 + t86r->fmt2.count2;
669 length = min(PCIXCC_MAX_XCRB_RESPONSE_SIZE, length);
670 memcpy(msg->message, reply->message, length);
671 break;
672 default:
1a89dd8f 673 memcpy(msg->message, &error_reply, sizeof error_reply);
5432114b 674 }
6684af1a
MS
675 } else
676 memcpy(msg->message, reply->message, sizeof error_reply);
21e7b2c4 677out:
5432114b 678 complete(&(resp_type->work));
6684af1a
MS
679}
680
681static atomic_t zcrypt_step = ATOMIC_INIT(0);
682
683/**
684 * The request distributor calls this function if it picked the PCIXCC/CEX2C
685 * device to handle a modexpo request.
686 * @zdev: pointer to zcrypt_device structure that identifies the
687 * PCIXCC/CEX2C device to the request distributor
688 * @mex: pointer to the modexpo request buffer
689 */
690static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
691 struct ica_rsa_modexpo *mex)
692{
693 struct ap_message ap_msg;
5432114b
RW
694 struct response_type resp_type = {
695 .type = PCIXCC_RESPONSE_TYPE_ICA,
696 };
6684af1a
MS
697 int rc;
698
468ffddf 699 ap_init_message(&ap_msg);
6684af1a
MS
700 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
701 if (!ap_msg.message)
702 return -ENOMEM;
703 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
704 atomic_inc_return(&zcrypt_step);
5432114b 705 ap_msg.private = &resp_type;
6684af1a
MS
706 rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
707 if (rc)
708 goto out_free;
5432114b 709 init_completion(&resp_type.work);
6684af1a 710 ap_queue_message(zdev->ap_dev, &ap_msg);
af512ed0
RW
711 rc = wait_for_completion_interruptible(&resp_type.work);
712 if (rc == 0)
6684af1a
MS
713 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
714 mex->outputdatalength);
af512ed0
RW
715 else
716 /* Signal pending. */
6684af1a 717 ap_cancel_message(zdev->ap_dev, &ap_msg);
6684af1a
MS
718out_free:
719 free_page((unsigned long) ap_msg.message);
720 return rc;
721}
722
723/**
724 * The request distributor calls this function if it picked the PCIXCC/CEX2C
725 * device to handle a modexpo_crt request.
726 * @zdev: pointer to zcrypt_device structure that identifies the
727 * PCIXCC/CEX2C device to the request distributor
728 * @crt: pointer to the modexpoc_crt request buffer
729 */
730static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
731 struct ica_rsa_modexpo_crt *crt)
732{
733 struct ap_message ap_msg;
5432114b
RW
734 struct response_type resp_type = {
735 .type = PCIXCC_RESPONSE_TYPE_ICA,
736 };
6684af1a
MS
737 int rc;
738
468ffddf 739 ap_init_message(&ap_msg);
6684af1a
MS
740 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
741 if (!ap_msg.message)
742 return -ENOMEM;
743 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
744 atomic_inc_return(&zcrypt_step);
5432114b 745 ap_msg.private = &resp_type;
6684af1a
MS
746 rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
747 if (rc)
748 goto out_free;
5432114b 749 init_completion(&resp_type.work);
6684af1a 750 ap_queue_message(zdev->ap_dev, &ap_msg);
af512ed0
RW
751 rc = wait_for_completion_interruptible(&resp_type.work);
752 if (rc == 0)
6684af1a
MS
753 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
754 crt->outputdatalength);
af512ed0
RW
755 else
756 /* Signal pending. */
6684af1a 757 ap_cancel_message(zdev->ap_dev, &ap_msg);
6684af1a
MS
758out_free:
759 free_page((unsigned long) ap_msg.message);
760 return rc;
761}
762
5432114b
RW
763/**
764 * The request distributor calls this function if it picked the PCIXCC/CEX2C
765 * device to handle a send_cprb request.
766 * @zdev: pointer to zcrypt_device structure that identifies the
767 * PCIXCC/CEX2C device to the request distributor
768 * @xcRB: pointer to the send_cprb request buffer
769 */
2b67fc46
HC
770static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
771 struct ica_xcRB *xcRB)
5432114b
RW
772{
773 struct ap_message ap_msg;
774 struct response_type resp_type = {
775 .type = PCIXCC_RESPONSE_TYPE_XCRB,
776 };
777 int rc;
778
468ffddf 779 ap_init_message(&ap_msg);
5cbded58 780 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
5432114b
RW
781 if (!ap_msg.message)
782 return -ENOMEM;
783 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
784 atomic_inc_return(&zcrypt_step);
785 ap_msg.private = &resp_type;
786 rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
787 if (rc)
788 goto out_free;
789 init_completion(&resp_type.work);
790 ap_queue_message(zdev->ap_dev, &ap_msg);
af512ed0
RW
791 rc = wait_for_completion_interruptible(&resp_type.work);
792 if (rc == 0)
5432114b 793 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
af512ed0
RW
794 else
795 /* Signal pending. */
5432114b 796 ap_cancel_message(zdev->ap_dev, &ap_msg);
5432114b 797out_free:
3e75a902 798 kzfree(ap_msg.message);
5432114b
RW
799 return rc;
800}
801
2f7c8bd6
RW
802/**
803 * The request distributor calls this function if it picked the PCIXCC/CEX2C
804 * device to generate random data.
805 * @zdev: pointer to zcrypt_device structure that identifies the
806 * PCIXCC/CEX2C device to the request distributor
807 * @buffer: pointer to a memory page to return random data
808 */
809
810static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev,
811 char *buffer)
812{
813 struct ap_message ap_msg;
814 struct response_type resp_type = {
815 .type = PCIXCC_RESPONSE_TYPE_XCRB,
816 };
817 int rc;
818
468ffddf 819 ap_init_message(&ap_msg);
2f7c8bd6
RW
820 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
821 if (!ap_msg.message)
822 return -ENOMEM;
823 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
824 atomic_inc_return(&zcrypt_step);
825 ap_msg.private = &resp_type;
826 rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
827 init_completion(&resp_type.work);
828 ap_queue_message(zdev->ap_dev, &ap_msg);
829 rc = wait_for_completion_interruptible(&resp_type.work);
830 if (rc == 0)
831 rc = convert_response_rng(zdev, &ap_msg, buffer);
832 else
833 /* Signal pending. */
834 ap_cancel_message(zdev->ap_dev, &ap_msg);
835 kfree(ap_msg.message);
836 return rc;
837}
838
6684af1a
MS
839/**
840 * The crypto operations for a PCIXCC/CEX2C card.
841 */
842static struct zcrypt_ops zcrypt_pcixcc_ops = {
843 .rsa_modexpo = zcrypt_pcixcc_modexpo,
844 .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
5432114b 845 .send_cprb = zcrypt_pcixcc_send_cprb,
6684af1a
MS
846};
847
2f7c8bd6
RW
848static struct zcrypt_ops zcrypt_pcixcc_with_rng_ops = {
849 .rsa_modexpo = zcrypt_pcixcc_modexpo,
850 .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
851 .send_cprb = zcrypt_pcixcc_send_cprb,
852 .rng = zcrypt_pcixcc_rng,
853};
854
6684af1a
MS
855/**
856 * Micro-code detection function. Its sends a message to a pcixcc card
857 * to find out the microcode level.
858 * @ap_dev: pointer to the AP device.
859 */
860static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
861{
862 static unsigned char msg[] = {
863 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
864 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
865 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
866 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
867 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
868 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
869 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
870 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
871 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
872 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
873 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
874 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
875 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
876 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
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,0x00,0x00,0x00,0x00,0x00,
895 0x00,0x00,0x00,0x04,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,0x00,0x00,0x00,0x00,
901 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
902 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
903 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
904 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
905 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
906 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
907 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
908 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
909 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
910 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
911 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
912 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
913 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
914 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
915 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
916 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
917 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
918 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
919 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
920 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
921 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
922 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
923 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
924 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
925 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
926 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
927 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
928 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
929 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
930 0xF1,0x3D,0x93,0x53
931 };
932 unsigned long long psmid;
933 struct CPRBX *cprbx;
934 char *reply;
935 int rc, i;
936
937 reply = (void *) get_zeroed_page(GFP_KERNEL);
938 if (!reply)
939 return -ENOMEM;
940
941 rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
942 if (rc)
943 goto out_free;
944
945 /* Wait for the test message to complete. */
946 for (i = 0; i < 6; i++) {
947 mdelay(300);
948 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
949 if (rc == 0 && psmid == 0x0102030405060708ULL)
950 break;
951 }
952
953 if (i >= 6) {
954 /* Got no answer. */
955 rc = -ENODEV;
956 goto out_free;
957 }
958
959 cprbx = (struct CPRBX *) (reply + 48);
960 if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
961 rc = ZCRYPT_PCIXCC_MCL2;
962 else
963 rc = ZCRYPT_PCIXCC_MCL3;
964out_free:
965 free_page((unsigned long) reply);
966 return rc;
967}
968
2f7c8bd6
RW
969/**
970 * Large random number detection function. Its sends a message to a pcixcc
971 * card to find out if large random numbers are supported.
972 * @ap_dev: pointer to the AP device.
973 *
974 * Returns 1 if large random numbers are supported, 0 if not and < 0 on error.
975 */
976static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
977{
978 struct ap_message ap_msg;
979 unsigned long long psmid;
980 struct {
981 struct type86_hdr hdr;
982 struct type86_fmt2_ext fmt2;
983 struct CPRBX cprbx;
984 } __attribute__((packed)) *reply;
985 int rc, i;
986
468ffddf 987 ap_init_message(&ap_msg);
2f7c8bd6
RW
988 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
989 if (!ap_msg.message)
990 return -ENOMEM;
991
992 rng_type6CPRB_msgX(ap_dev, &ap_msg, 4);
993 rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, ap_msg.message,
994 ap_msg.length);
995 if (rc)
996 goto out_free;
997
998 /* Wait for the test message to complete. */
999 for (i = 0; i < 2 * HZ; i++) {
1000 msleep(1000 / HZ);
1001 rc = ap_recv(ap_dev->qid, &psmid, ap_msg.message, 4096);
1002 if (rc == 0 && psmid == 0x0102030405060708ULL)
1003 break;
1004 }
1005
1006 if (i >= 2 * HZ) {
1007 /* Got no answer. */
1008 rc = -ENODEV;
1009 goto out_free;
1010 }
1011
1012 reply = ap_msg.message;
1013 if (reply->cprbx.ccp_rtcode == 0 && reply->cprbx.ccp_rscode == 0)
1014 rc = 1;
1015 else
1016 rc = 0;
1017out_free:
1018 free_page((unsigned long) ap_msg.message);
1019 return rc;
1020}
1021
6684af1a
MS
1022/**
1023 * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
1024 * since the bus_match already checked the hardware type. The PCIXCC
1025 * cards come in two flavours: micro code level 2 and micro code level 3.
1026 * This is checked by sending a test message to the device.
1027 * @ap_dev: pointer to the AP device.
1028 */
1029static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
1030{
1031 struct zcrypt_device *zdev;
8e89b6be 1032 int rc = 0;
6684af1a
MS
1033
1034 zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
1035 if (!zdev)
1036 return -ENOMEM;
1037 zdev->ap_dev = ap_dev;
6684af1a 1038 zdev->online = 1;
8e89b6be
FB
1039 switch (ap_dev->device_type) {
1040 case AP_DEVICE_TYPE_PCIXCC:
6684af1a
MS
1041 rc = zcrypt_pcixcc_mcl(ap_dev);
1042 if (rc < 0) {
1043 zcrypt_device_free(zdev);
1044 return rc;
1045 }
1046 zdev->user_space_type = rc;
1047 if (rc == ZCRYPT_PCIXCC_MCL2) {
1048 zdev->type_string = "PCIXCC_MCL2";
1049 zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
1050 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
1051 zdev->max_mod_size = 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 }
8e89b6be
FB
1058 break;
1059 case AP_DEVICE_TYPE_CEX2C:
6684af1a
MS
1060 zdev->user_space_type = ZCRYPT_CEX2C;
1061 zdev->type_string = "CEX2C";
1062 zdev->speed_rating = CEX2C_SPEED_RATING;
1063 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1064 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
8e89b6be
FB
1065 break;
1066 case AP_DEVICE_TYPE_CEX3C:
1067 zdev->user_space_type = ZCRYPT_CEX3C;
1068 zdev->type_string = "CEX3C";
1069 zdev->speed_rating = CEX3C_SPEED_RATING;
1070 zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
1071 zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
1072 break;
1073 default:
1074 goto out_free;
6684af1a 1075 }
8e89b6be 1076
2f7c8bd6
RW
1077 rc = zcrypt_pcixcc_rng_supported(ap_dev);
1078 if (rc < 0) {
1079 zcrypt_device_free(zdev);
1080 return rc;
1081 }
1082 if (rc)
1083 zdev->ops = &zcrypt_pcixcc_with_rng_ops;
1084 else
1085 zdev->ops = &zcrypt_pcixcc_ops;
6684af1a
MS
1086 ap_dev->reply = &zdev->reply;
1087 ap_dev->private = zdev;
1088 rc = zcrypt_device_register(zdev);
1089 if (rc)
1090 goto out_free;
1091 return 0;
1092
1093 out_free:
1094 ap_dev->private = NULL;
1095 zcrypt_device_free(zdev);
1096 return rc;
1097}
1098
1099/**
1100 * This is called to remove the extended PCIXCC/CEX2C driver information
1101 * if an AP device is removed.
1102 */
1103static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
1104{
1105 struct zcrypt_device *zdev = ap_dev->private;
1106
1107 zcrypt_device_unregister(zdev);
1108}
1109
1110int __init zcrypt_pcixcc_init(void)
1111{
1112 return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
1113}
1114
1115void zcrypt_pcixcc_exit(void)
1116{
1117 ap_driver_unregister(&zcrypt_pcixcc_driver);
1118}
1119
1120#ifndef CONFIG_ZCRYPT_MONOLITHIC
1121module_init(zcrypt_pcixcc_init);
1122module_exit(zcrypt_pcixcc_exit);
1123#endif