diff options
Diffstat (limited to 'drivers/s390/crypto/zcrypt_pcica.c')
| -rw-r--r-- | drivers/s390/crypto/zcrypt_pcica.c | 82 |
1 files changed, 42 insertions, 40 deletions
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c index b6a4ecdc802..7a743f4c646 100644 --- a/drivers/s390/crypto/zcrypt_pcica.c +++ b/drivers/s390/crypto/zcrypt_pcica.c @@ -1,9 +1,7 @@ /* - * linux/drivers/s390/crypto/zcrypt_pcica.c - * * zcrypt 2.1.0 * - * Copyright (C) 2001, 2006 IBM Corporation + * Copyright IBM Corp. 2001, 2006 * Author(s): Robert Burroughs * Eric Rossman (edrossma@us.ibm.com) * @@ -26,10 +24,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define KMSG_COMPONENT "zcrypt" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + #include <linux/module.h> +#include <linux/slab.h> #include <linux/init.h> #include <linux/err.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/uaccess.h> #include "ap_bus.h" @@ -52,13 +54,11 @@ static struct ap_device_id zcrypt_pcica_ids[] = { { /* end of list */ }, }; -#ifndef CONFIG_ZCRYPT_MONOLITHIC MODULE_DEVICE_TABLE(ap, zcrypt_pcica_ids); MODULE_AUTHOR("IBM Corporation"); MODULE_DESCRIPTION("PCICA Cryptographic Coprocessor device driver, " - "Copyright 2001, 2006 IBM Corporation"); + "Copyright IBM Corp. 2001, 2006"); MODULE_LICENSE("GPL"); -#endif static int zcrypt_pcica_probe(struct ap_device *ap_dev); static void zcrypt_pcica_remove(struct ap_device *ap_dev); @@ -68,8 +68,8 @@ static void zcrypt_pcica_receive(struct ap_device *, struct ap_message *, static struct ap_driver zcrypt_pcica_driver = { .probe = zcrypt_pcica_probe, .remove = zcrypt_pcica_remove, - .receive = zcrypt_pcica_receive, .ids = zcrypt_pcica_ids, + .request_timeout = PCICA_CLEANUP_TIME, }; /** @@ -191,10 +191,10 @@ static int ICACRT_msg_to_type4CRT_msg(struct zcrypt_device *zdev, * * Returns 0 on success or -EFAULT. */ -static inline int convert_type84(struct zcrypt_device *zdev, - struct ap_message *reply, - char __user *outputdata, - unsigned int outputdatalength) +static int convert_type84(struct zcrypt_device *zdev, + struct ap_message *reply, + char __user *outputdata, + unsigned int outputdatalength) { struct type84_hdr *t84h = reply->message; char *data; @@ -202,6 +202,10 @@ static inline int convert_type84(struct zcrypt_device *zdev, if (t84h->len < sizeof(*t84h) + outputdatalength) { /* The result is too short, the PCICA card may not do that.. */ zdev->online = 0; + pr_err("Cryptographic device %x failed and was set offline\n", + zdev->ap_dev->qid); + ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%drc%d", + zdev->ap_dev->qid, zdev->online, t84h->code); return -EAGAIN; /* repeat the request on a different device. */ } BUG_ON(t84h->len > PCICA_MAX_RESPONSE_SIZE); @@ -225,10 +229,11 @@ static int convert_response(struct zcrypt_device *zdev, return convert_type84(zdev, reply, outputdata, outputdatalength); default: /* Unknown response type, this should NEVER EVER happen */ - PRINTK("Unrecognized Message Header: %08x%08x\n", - *(unsigned int *) reply->message, - *(unsigned int *) (reply->message+4)); zdev->online = 0; + pr_err("Cryptographic device %x failed and was set offline\n", + zdev->ap_dev->qid); + ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail", + zdev->ap_dev->qid, zdev->online); return -EAGAIN; /* repeat the request on a different device. */ } } @@ -249,17 +254,21 @@ static void zcrypt_pcica_receive(struct ap_device *ap_dev, .type = TYPE82_RSP_CODE, .reply_code = REP82_ERROR_MACHINE_FAILURE, }; - struct type84_hdr *t84h = reply->message; + struct type84_hdr *t84h; int length; /* Copy the reply message to the request message buffer. */ - if (IS_ERR(reply)) + if (IS_ERR(reply)) { memcpy(msg->message, &error_reply, sizeof(error_reply)); - else if (t84h->code == TYPE84_RSP_CODE) { + goto out; + } + t84h = reply->message; + if (t84h->code == TYPE84_RSP_CODE) { length = min(PCICA_MAX_RESPONSE_SIZE, (int) t84h->len); memcpy(msg->message, reply->message, length); } else memcpy(msg->message, reply->message, sizeof error_reply); +out: complete((struct completion *) msg->private); } @@ -279,9 +288,11 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev, struct completion work; int rc; - ap_msg.message = (void *) kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); + ap_init_message(&ap_msg); + ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; + ap_msg.receive = zcrypt_pcica_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &work; @@ -290,18 +301,13 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev, goto out_free; init_completion(&work); ap_queue_message(zdev->ap_dev, &ap_msg); - rc = wait_for_completion_interruptible_timeout( - &work, PCICA_CLEANUP_TIME); - if (rc > 0) + rc = wait_for_completion_interruptible(&work); + if (rc == 0) rc = convert_response(zdev, &ap_msg, mex->outputdata, mex->outputdatalength); - else { - /* Signal pending or message timed out. */ + else + /* Signal pending. */ ap_cancel_message(zdev->ap_dev, &ap_msg); - if (rc == 0) - /* Message timed out. */ - rc = -ETIME; - } out_free: kfree(ap_msg.message); return rc; @@ -321,9 +327,11 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev, struct completion work; int rc; - ap_msg.message = (void *) kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); + ap_init_message(&ap_msg); + ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); if (!ap_msg.message) return -ENOMEM; + ap_msg.receive = zcrypt_pcica_receive; ap_msg.psmid = (((unsigned long long) current->pid) << 32) + atomic_inc_return(&zcrypt_step); ap_msg.private = &work; @@ -332,18 +340,13 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev, goto out_free; init_completion(&work); ap_queue_message(zdev->ap_dev, &ap_msg); - rc = wait_for_completion_interruptible_timeout( - &work, PCICA_CLEANUP_TIME); - if (rc > 0) + rc = wait_for_completion_interruptible(&work); + if (rc == 0) rc = convert_response(zdev, &ap_msg, crt->outputdata, crt->outputdatalength); - else { - /* Signal pending or message timed out. */ + else + /* Signal pending. */ ap_cancel_message(zdev->ap_dev, &ap_msg); - if (rc == 0) - /* Message timed out. */ - rc = -ETIME; - } out_free: kfree(ap_msg.message); return rc; @@ -378,6 +381,7 @@ static int zcrypt_pcica_probe(struct ap_device *ap_dev) zdev->min_mod_size = PCICA_MIN_MOD_SIZE; zdev->max_mod_size = PCICA_MAX_MOD_SIZE; zdev->speed_rating = PCICA_SPEED_RATING; + zdev->max_exp_bit_length = PCICA_MAX_MOD_SIZE; ap_dev->reply = &zdev->reply; ap_dev->private = zdev; rc = zcrypt_device_register(zdev); @@ -412,7 +416,5 @@ void zcrypt_pcica_exit(void) ap_driver_unregister(&zcrypt_pcica_driver); } -#ifndef CONFIG_ZCRYPT_MONOLITHIC module_init(zcrypt_pcica_init); module_exit(zcrypt_pcica_exit); -#endif |
