diff options
author | Harald Freudenberger <freude@linux.ibm.com> | 2018-11-26 09:50:04 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-12-13 04:42:26 -0500 |
commit | 42a87d4103ae365e18c3be1333592ab583b8ad9d (patch) | |
tree | 0ee25e594ab56b2345bc811393e65f9e18f7a0db | |
parent | 98dfd32620e970eb576ebce5ea39d905cb005e72 (diff) |
s390/zcrypt: make sysfs reset attribute trigger queue reset
Until now there is no way to reset a AP queue or card. Driving a card
or queue offline and online again does only toggle the 'software'
online state. The only way to trigger a (hardware) reset is by running
hot-unplug/hot-plug for example on the HMC.
This patch makes the queue reset attribute in sysfs writable.
Writing into this attribute triggers a reset on the AP queue's state
machine. So the AP queue is flushed and state machine runs through the
initial states which cause a reset (PQAP(RAPQ)) and a re-registration
to interrupts (PQAP(AQIC)) if available.
The reset sysfs attribute is writable by root only. So only an
administrator is allowed to initiate a reset of AP queues. Please note
that the queue's counter values are left untouched by the reset.
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | drivers/s390/crypto/ap_queue.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 0aa4b3ccc948..576ac08777c5 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c | |||
@@ -14,6 +14,9 @@ | |||
14 | #include <asm/facility.h> | 14 | #include <asm/facility.h> |
15 | 15 | ||
16 | #include "ap_bus.h" | 16 | #include "ap_bus.h" |
17 | #include "ap_debug.h" | ||
18 | |||
19 | static void __ap_flush_queue(struct ap_queue *aq); | ||
17 | 20 | ||
18 | /** | 21 | /** |
19 | * ap_queue_enable_interruption(): Enable interruption on an AP queue. | 22 | * ap_queue_enable_interruption(): Enable interruption on an AP queue. |
@@ -541,7 +544,25 @@ static ssize_t reset_show(struct device *dev, | |||
541 | return rc; | 544 | return rc; |
542 | } | 545 | } |
543 | 546 | ||
544 | static DEVICE_ATTR_RO(reset); | 547 | static ssize_t reset_store(struct device *dev, |
548 | struct device_attribute *attr, | ||
549 | const char *buf, size_t count) | ||
550 | { | ||
551 | struct ap_queue *aq = to_ap_queue(dev); | ||
552 | |||
553 | spin_lock_bh(&aq->lock); | ||
554 | __ap_flush_queue(aq); | ||
555 | aq->state = AP_STATE_RESET_START; | ||
556 | ap_wait(ap_sm_event(aq, AP_EVENT_POLL)); | ||
557 | spin_unlock_bh(&aq->lock); | ||
558 | |||
559 | AP_DBF(DBF_INFO, "reset queue=%02x.%04x triggered by user\n", | ||
560 | AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); | ||
561 | |||
562 | return count; | ||
563 | } | ||
564 | |||
565 | static DEVICE_ATTR_RW(reset); | ||
545 | 566 | ||
546 | static ssize_t interrupt_show(struct device *dev, | 567 | static ssize_t interrupt_show(struct device *dev, |
547 | struct device_attribute *attr, char *buf) | 568 | struct device_attribute *attr, char *buf) |