diff options
Diffstat (limited to 'drivers/s390')
| -rw-r--r-- | drivers/s390/crypto/ap_bus.c | 4 | ||||
| -rw-r--r-- | drivers/s390/virtio/virtio_ccw.c | 62 |
2 files changed, 40 insertions, 26 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 61f768518a34..24ec282e15d8 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
| @@ -599,8 +599,10 @@ static enum ap_wait ap_sm_read(struct ap_device *ap_dev) | |||
| 599 | status = ap_sm_recv(ap_dev); | 599 | status = ap_sm_recv(ap_dev); |
| 600 | switch (status.response_code) { | 600 | switch (status.response_code) { |
| 601 | case AP_RESPONSE_NORMAL: | 601 | case AP_RESPONSE_NORMAL: |
| 602 | if (ap_dev->queue_count > 0) | 602 | if (ap_dev->queue_count > 0) { |
| 603 | ap_dev->state = AP_STATE_WORKING; | ||
| 603 | return AP_WAIT_AGAIN; | 604 | return AP_WAIT_AGAIN; |
| 605 | } | ||
| 604 | ap_dev->state = AP_STATE_IDLE; | 606 | ap_dev->state = AP_STATE_IDLE; |
| 605 | return AP_WAIT_NONE; | 607 | return AP_WAIT_NONE; |
| 606 | case AP_RESPONSE_NO_PENDING_REPLY: | 608 | case AP_RESPONSE_NO_PENDING_REPLY: |
diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c index b2a1a81e6fc8..1b831598df7c 100644 --- a/drivers/s390/virtio/virtio_ccw.c +++ b/drivers/s390/virtio/virtio_ccw.c | |||
| @@ -984,6 +984,36 @@ static struct virtqueue *virtio_ccw_vq_by_ind(struct virtio_ccw_device *vcdev, | |||
| 984 | return vq; | 984 | return vq; |
| 985 | } | 985 | } |
| 986 | 986 | ||
| 987 | static void virtio_ccw_check_activity(struct virtio_ccw_device *vcdev, | ||
| 988 | __u32 activity) | ||
| 989 | { | ||
| 990 | if (vcdev->curr_io & activity) { | ||
| 991 | switch (activity) { | ||
| 992 | case VIRTIO_CCW_DOING_READ_FEAT: | ||
| 993 | case VIRTIO_CCW_DOING_WRITE_FEAT: | ||
| 994 | case VIRTIO_CCW_DOING_READ_CONFIG: | ||
| 995 | case VIRTIO_CCW_DOING_WRITE_CONFIG: | ||
| 996 | case VIRTIO_CCW_DOING_WRITE_STATUS: | ||
| 997 | case VIRTIO_CCW_DOING_SET_VQ: | ||
| 998 | case VIRTIO_CCW_DOING_SET_IND: | ||
| 999 | case VIRTIO_CCW_DOING_SET_CONF_IND: | ||
| 1000 | case VIRTIO_CCW_DOING_RESET: | ||
| 1001 | case VIRTIO_CCW_DOING_READ_VQ_CONF: | ||
| 1002 | case VIRTIO_CCW_DOING_SET_IND_ADAPTER: | ||
| 1003 | case VIRTIO_CCW_DOING_SET_VIRTIO_REV: | ||
| 1004 | vcdev->curr_io &= ~activity; | ||
| 1005 | wake_up(&vcdev->wait_q); | ||
| 1006 | break; | ||
| 1007 | default: | ||
| 1008 | /* don't know what to do... */ | ||
| 1009 | dev_warn(&vcdev->cdev->dev, | ||
| 1010 | "Suspicious activity '%08x'\n", activity); | ||
| 1011 | WARN_ON(1); | ||
| 1012 | break; | ||
| 1013 | } | ||
| 1014 | } | ||
| 1015 | } | ||
| 1016 | |||
| 987 | static void virtio_ccw_int_handler(struct ccw_device *cdev, | 1017 | static void virtio_ccw_int_handler(struct ccw_device *cdev, |
| 988 | unsigned long intparm, | 1018 | unsigned long intparm, |
| 989 | struct irb *irb) | 1019 | struct irb *irb) |
| @@ -995,6 +1025,12 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev, | |||
| 995 | 1025 | ||
| 996 | if (!vcdev) | 1026 | if (!vcdev) |
| 997 | return; | 1027 | return; |
| 1028 | if (IS_ERR(irb)) { | ||
| 1029 | vcdev->err = PTR_ERR(irb); | ||
| 1030 | virtio_ccw_check_activity(vcdev, activity); | ||
| 1031 | /* Don't poke around indicators, something's wrong. */ | ||
| 1032 | return; | ||
| 1033 | } | ||
| 998 | /* Check if it's a notification from the host. */ | 1034 | /* Check if it's a notification from the host. */ |
| 999 | if ((intparm == 0) && | 1035 | if ((intparm == 0) && |
| 1000 | (scsw_stctl(&irb->scsw) == | 1036 | (scsw_stctl(&irb->scsw) == |
| @@ -1010,31 +1046,7 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev, | |||
| 1010 | /* Map everything else to -EIO. */ | 1046 | /* Map everything else to -EIO. */ |
| 1011 | vcdev->err = -EIO; | 1047 | vcdev->err = -EIO; |
| 1012 | } | 1048 | } |
| 1013 | if (vcdev->curr_io & activity) { | 1049 | virtio_ccw_check_activity(vcdev, activity); |
| 1014 | switch (activity) { | ||
| 1015 | case VIRTIO_CCW_DOING_READ_FEAT: | ||
| 1016 | case VIRTIO_CCW_DOING_WRITE_FEAT: | ||
| 1017 | case VIRTIO_CCW_DOING_READ_CONFIG: | ||
| 1018 | case VIRTIO_CCW_DOING_WRITE_CONFIG: | ||
| 1019 | case VIRTIO_CCW_DOING_WRITE_STATUS: | ||
| 1020 | case VIRTIO_CCW_DOING_SET_VQ: | ||
| 1021 | case VIRTIO_CCW_DOING_SET_IND: | ||
| 1022 | case VIRTIO_CCW_DOING_SET_CONF_IND: | ||
| 1023 | case VIRTIO_CCW_DOING_RESET: | ||
| 1024 | case VIRTIO_CCW_DOING_READ_VQ_CONF: | ||
| 1025 | case VIRTIO_CCW_DOING_SET_IND_ADAPTER: | ||
| 1026 | case VIRTIO_CCW_DOING_SET_VIRTIO_REV: | ||
| 1027 | vcdev->curr_io &= ~activity; | ||
| 1028 | wake_up(&vcdev->wait_q); | ||
| 1029 | break; | ||
| 1030 | default: | ||
| 1031 | /* don't know what to do... */ | ||
| 1032 | dev_warn(&cdev->dev, "Suspicious activity '%08x'\n", | ||
| 1033 | activity); | ||
| 1034 | WARN_ON(1); | ||
| 1035 | break; | ||
| 1036 | } | ||
| 1037 | } | ||
| 1038 | for_each_set_bit(i, &vcdev->indicators, | 1050 | for_each_set_bit(i, &vcdev->indicators, |
| 1039 | sizeof(vcdev->indicators) * BITS_PER_BYTE) { | 1051 | sizeof(vcdev->indicators) * BITS_PER_BYTE) { |
| 1040 | /* The bit clear must happen before the vring kick. */ | 1052 | /* The bit clear must happen before the vring kick. */ |
