diff options
-rw-r--r-- | drivers/s390/crypto/ap_bus.c | 46 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_bus.h | 1 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_cex2a.c | 2 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_cex4.c | 2 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcixcc.c | 2 |
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 | */ | ||
652 | static 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 | ||
1367 | void 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 | } | ||
1376 | EXPORT_SYMBOL(ap_device_init_reply); | ||
1377 | |||
1338 | static int ap_device_probe(struct device *dev) | 1378 | static 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); | |||
262 | void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg); | 262 | void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg); |
263 | void ap_flush_queue(struct ap_device *ap_dev); | 263 | void ap_flush_queue(struct ap_device *ap_dev); |
264 | void ap_bus_force_rescan(void); | 264 | void ap_bus_force_rescan(void); |
265 | void ap_device_init_reply(struct ap_device *ap_dev, struct ap_message *ap_msg); | ||
265 | 266 | ||
266 | int ap_module_init(void); | 267 | int ap_module_init(void); |
267 | void ap_module_exit(void); | 268 | void 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) |