summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/crypto/ap_bus.c46
-rw-r--r--drivers/s390/crypto/ap_bus.h1
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c2
-rw-r--r--drivers/s390/crypto/zcrypt_cex4.c2
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c2
5 files changed, 47 insertions, 6 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 4feb27215ab6..03e4d6246d87 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -468,6 +468,8 @@ int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
468{ 468{
469 struct ap_queue_status status; 469 struct ap_queue_status status;
470 470
471 if (msg == NULL)
472 return -EINVAL;
471 status = __ap_recv(qid, psmid, msg, length); 473 status = __ap_recv(qid, psmid, msg, length);
472 switch (status.response_code) { 474 switch (status.response_code) {
473 case AP_RESPONSE_NORMAL: 475 case AP_RESPONSE_NORMAL:
@@ -617,6 +619,8 @@ static enum ap_wait ap_sm_read(struct ap_device *ap_dev)
617{ 619{
618 struct ap_queue_status status; 620 struct ap_queue_status status;
619 621
622 if (!ap_dev->reply)
623 return AP_WAIT_NONE;
620 status = ap_sm_recv(ap_dev); 624 status = ap_sm_recv(ap_dev);
621 switch (status.response_code) { 625 switch (status.response_code) {
622 case AP_RESPONSE_NORMAL: 626 case AP_RESPONSE_NORMAL:
@@ -638,6 +642,31 @@ static enum ap_wait ap_sm_read(struct ap_device *ap_dev)
638} 642}
639 643
640/** 644/**
645 * ap_sm_suspend_read(): Receive pending reply messages from an AP device
646 * without changing the device state in between. In suspend mode we don't
647 * allow sending new requests, therefore just fetch pending replies.
648 * @ap_dev: pointer to the AP device
649 *
650 * Returns AP_WAIT_NONE or AP_WAIT_AGAIN
651 */
652static enum ap_wait ap_sm_suspend_read(struct ap_device *ap_dev)
653{
654 struct ap_queue_status status;
655
656 if (!ap_dev->reply)
657 return AP_WAIT_NONE;
658 status = ap_sm_recv(ap_dev);
659 switch (status.response_code) {
660 case AP_RESPONSE_NORMAL:
661 if (ap_dev->queue_count > 0)
662 return AP_WAIT_AGAIN;
663 /* fall through */
664 default:
665 return AP_WAIT_NONE;
666 }
667}
668
669/**
641 * ap_sm_write(): Send messages from the request queue to an AP device. 670 * ap_sm_write(): Send messages from the request queue to an AP device.
642 * @ap_dev: pointer to the AP device 671 * @ap_dev: pointer to the AP device
643 * 672 *
@@ -738,7 +767,7 @@ static enum ap_wait ap_sm_reset_wait(struct ap_device *ap_dev)
738 struct ap_queue_status status; 767 struct ap_queue_status status;
739 unsigned long info; 768 unsigned long info;
740 769
741 if (ap_dev->queue_count > 0) 770 if (ap_dev->queue_count > 0 && ap_dev->reply)
742 /* Try to read a completed message and get the status */ 771 /* Try to read a completed message and get the status */
743 status = ap_sm_recv(ap_dev); 772 status = ap_sm_recv(ap_dev);
744 else 773 else
@@ -778,7 +807,7 @@ static enum ap_wait ap_sm_setirq_wait(struct ap_device *ap_dev)
778 struct ap_queue_status status; 807 struct ap_queue_status status;
779 unsigned long info; 808 unsigned long info;
780 809
781 if (ap_dev->queue_count > 0) 810 if (ap_dev->queue_count > 0 && ap_dev->reply)
782 /* Try to read a completed message and get the status */ 811 /* Try to read a completed message and get the status */
783 status = ap_sm_recv(ap_dev); 812 status = ap_sm_recv(ap_dev);
784 else 813 else
@@ -834,7 +863,7 @@ static ap_func_t *ap_jumptable[NR_AP_STATES][NR_AP_EVENTS] = {
834 [AP_EVENT_TIMEOUT] = ap_sm_reset, 863 [AP_EVENT_TIMEOUT] = ap_sm_reset,
835 }, 864 },
836 [AP_STATE_SUSPEND_WAIT] = { 865 [AP_STATE_SUSPEND_WAIT] = {
837 [AP_EVENT_POLL] = ap_sm_read, 866 [AP_EVENT_POLL] = ap_sm_suspend_read,
838 [AP_EVENT_TIMEOUT] = ap_sm_nop, 867 [AP_EVENT_TIMEOUT] = ap_sm_nop,
839 }, 868 },
840 [AP_STATE_BORKED] = { 869 [AP_STATE_BORKED] = {
@@ -1335,6 +1364,17 @@ static struct bus_type ap_bus_type = {
1335 .resume = ap_dev_resume, 1364 .resume = ap_dev_resume,
1336}; 1365};
1337 1366
1367void ap_device_init_reply(struct ap_device *ap_dev,
1368 struct ap_message *reply)
1369{
1370 ap_dev->reply = reply;
1371
1372 spin_lock_bh(&ap_dev->lock);
1373 ap_sm_wait(ap_sm_event(ap_dev, AP_EVENT_POLL));
1374 spin_unlock_bh(&ap_dev->lock);
1375}
1376EXPORT_SYMBOL(ap_device_init_reply);
1377
1338static int ap_device_probe(struct device *dev) 1378static int ap_device_probe(struct device *dev)
1339{ 1379{
1340 struct ap_device *ap_dev = to_ap_dev(dev); 1380 struct ap_device *ap_dev = to_ap_dev(dev);
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 6adcbdf225d1..d7fdf5c024d7 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -262,6 +262,7 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg);
262void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg); 262void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg);
263void ap_flush_queue(struct ap_device *ap_dev); 263void ap_flush_queue(struct ap_device *ap_dev);
264void ap_bus_force_rescan(void); 264void ap_bus_force_rescan(void);
265void ap_device_init_reply(struct ap_device *ap_dev, struct ap_message *ap_msg);
265 266
266int ap_module_init(void); 267int ap_module_init(void);
267void ap_module_exit(void); 268void ap_module_exit(void);
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c
index 1e849d6e1dfe..15104aaa075a 100644
--- a/drivers/s390/crypto/zcrypt_cex2a.c
+++ b/drivers/s390/crypto/zcrypt_cex2a.c
@@ -126,7 +126,7 @@ static int zcrypt_cex2a_probe(struct ap_device *ap_dev)
126 MSGTYPE50_VARIANT_DEFAULT); 126 MSGTYPE50_VARIANT_DEFAULT);
127 zdev->ap_dev = ap_dev; 127 zdev->ap_dev = ap_dev;
128 zdev->online = 1; 128 zdev->online = 1;
129 ap_dev->reply = &zdev->reply; 129 ap_device_init_reply(ap_dev, &zdev->reply);
130 ap_dev->private = zdev; 130 ap_dev->private = zdev;
131 rc = zcrypt_device_register(zdev); 131 rc = zcrypt_device_register(zdev);
132 if (rc) { 132 if (rc) {
diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c
index bb3908818505..ccb2e78ebf0e 100644
--- a/drivers/s390/crypto/zcrypt_cex4.c
+++ b/drivers/s390/crypto/zcrypt_cex4.c
@@ -147,7 +147,7 @@ static int zcrypt_cex4_probe(struct ap_device *ap_dev)
147 return -ENODEV; 147 return -ENODEV;
148 zdev->ap_dev = ap_dev; 148 zdev->ap_dev = ap_dev;
149 zdev->online = 1; 149 zdev->online = 1;
150 ap_dev->reply = &zdev->reply; 150 ap_device_init_reply(ap_dev, &zdev->reply);
151 ap_dev->private = zdev; 151 ap_dev->private = zdev;
152 rc = zcrypt_device_register(zdev); 152 rc = zcrypt_device_register(zdev);
153 if (rc) { 153 if (rc) {
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index f41852768953..df8f0c4dacb7 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -327,7 +327,7 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
327 else 327 else
328 zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME, 328 zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME,
329 MSGTYPE06_VARIANT_NORNG); 329 MSGTYPE06_VARIANT_NORNG);
330 ap_dev->reply = &zdev->reply; 330 ap_device_init_reply(ap_dev, &zdev->reply);
331 ap_dev->private = zdev; 331 ap_dev->private = zdev;
332 rc = zcrypt_device_register(zdev); 332 rc = zcrypt_device_register(zdev);
333 if (rc) 333 if (rc)