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