diff options
author | Holger Dengler <hd@linux.vnet.ibm.com> | 2012-05-16 16:08:22 +0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-05-16 16:42:52 +0400 |
commit | 54a8f5611d9189b3a8fbc9ace59a7a276eee58d8 (patch) | |
tree | 02c5bab3a0601b70faf8977d1e4eadd110c97d49 /drivers/s390/crypto/ap_bus.c | |
parent | 505e5ecfd3930bd1b429c36f10403d32a6c3c951 (diff) | |
download | linux-54a8f5611d9189b3a8fbc9ace59a7a276eee58d8.tar.xz |
s390/ap: move receive callback to message struct
Move the receive callback from zdev_driver to ap_message structure to
get a more flexible asynchronous ap message handling.
Signed-off-by: Holger Dengler <hd@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/crypto/ap_bus.c')
-rw-r--r-- | drivers/s390/crypto/ap_bus.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 7e9a72eb2fe0..cd2103c1d915 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -836,12 +836,12 @@ static void __ap_flush_queue(struct ap_device *ap_dev) list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) { list_del_init(&ap_msg->list); ap_dev->pendingq_count--; - ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); + ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); } list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) { list_del_init(&ap_msg->list); ap_dev->requestq_count--; - ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); + ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); } } @@ -1329,7 +1329,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) continue; list_del_init(&ap_msg->list); ap_dev->pendingq_count--; - ap_dev->drv->receive(ap_dev, ap_msg, ap_dev->reply); + ap_msg->receive(ap_dev, ap_msg, ap_dev->reply); break; } if (ap_dev->queue_count > 0) @@ -1450,10 +1450,10 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms return -EBUSY; case AP_RESPONSE_REQ_FAC_NOT_INST: case AP_RESPONSE_MESSAGE_TOO_BIG: - ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL)); + ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL)); return -EINVAL; default: /* Device is gone. */ - ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); + ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); return -ENODEV; } } else { @@ -1471,6 +1471,10 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg) unsigned long flags; int rc; + /* For asynchronous message handling a valid receive-callback + * is required. */ + BUG_ON(!ap_msg->receive); + spin_lock_bh(&ap_dev->lock); if (!ap_dev->unregistered) { /* Make room on the queue by polling for finished requests. */ @@ -1482,7 +1486,7 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg) if (rc == -ENODEV) ap_dev->unregistered = 1; } else { - ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); + ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); rc = -ENODEV; } spin_unlock_bh(&ap_dev->lock); |