diff options
Diffstat (limited to 'drivers/s390/kvm/virtio_ccw.c')
-rw-r--r-- | drivers/s390/kvm/virtio_ccw.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c index fb877b59ec57..779dc5136291 100644 --- a/drivers/s390/kvm/virtio_ccw.c +++ b/drivers/s390/kvm/virtio_ccw.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
32 | #include <asm/cio.h> | 32 | #include <asm/cio.h> |
33 | #include <asm/ccwdev.h> | 33 | #include <asm/ccwdev.h> |
34 | #include <asm/virtio-ccw.h> | ||
34 | 35 | ||
35 | /* | 36 | /* |
36 | * virtio related functions | 37 | * virtio related functions |
@@ -77,12 +78,9 @@ struct virtio_ccw_vq_info { | |||
77 | void *queue; | 78 | void *queue; |
78 | struct vq_info_block *info_block; | 79 | struct vq_info_block *info_block; |
79 | struct list_head node; | 80 | struct list_head node; |
81 | long cookie; | ||
80 | }; | 82 | }; |
81 | 83 | ||
82 | #define KVM_VIRTIO_CCW_RING_ALIGN 4096 | ||
83 | |||
84 | #define KVM_S390_VIRTIO_CCW_NOTIFY 3 | ||
85 | |||
86 | #define CCW_CMD_SET_VQ 0x13 | 84 | #define CCW_CMD_SET_VQ 0x13 |
87 | #define CCW_CMD_VDEV_RESET 0x33 | 85 | #define CCW_CMD_VDEV_RESET 0x33 |
88 | #define CCW_CMD_SET_IND 0x43 | 86 | #define CCW_CMD_SET_IND 0x43 |
@@ -135,8 +133,11 @@ static int ccw_io_helper(struct virtio_ccw_device *vcdev, | |||
135 | do { | 133 | do { |
136 | spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags); | 134 | spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags); |
137 | ret = ccw_device_start(vcdev->cdev, ccw, intparm, 0, 0); | 135 | ret = ccw_device_start(vcdev->cdev, ccw, intparm, 0, 0); |
138 | if (!ret) | 136 | if (!ret) { |
137 | if (!vcdev->curr_io) | ||
138 | vcdev->err = 0; | ||
139 | vcdev->curr_io |= flag; | 139 | vcdev->curr_io |= flag; |
140 | } | ||
140 | spin_unlock_irqrestore(get_ccwdev_lock(vcdev->cdev), flags); | 141 | spin_unlock_irqrestore(get_ccwdev_lock(vcdev->cdev), flags); |
141 | cpu_relax(); | 142 | cpu_relax(); |
142 | } while (ret == -EBUSY); | 143 | } while (ret == -EBUSY); |
@@ -145,15 +146,18 @@ static int ccw_io_helper(struct virtio_ccw_device *vcdev, | |||
145 | } | 146 | } |
146 | 147 | ||
147 | static inline long do_kvm_notify(struct subchannel_id schid, | 148 | static inline long do_kvm_notify(struct subchannel_id schid, |
148 | unsigned long queue_index) | 149 | unsigned long queue_index, |
150 | long cookie) | ||
149 | { | 151 | { |
150 | register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY; | 152 | register unsigned long __nr asm("1") = KVM_S390_VIRTIO_CCW_NOTIFY; |
151 | register struct subchannel_id __schid asm("2") = schid; | 153 | register struct subchannel_id __schid asm("2") = schid; |
152 | register unsigned long __index asm("3") = queue_index; | 154 | register unsigned long __index asm("3") = queue_index; |
153 | register long __rc asm("2"); | 155 | register long __rc asm("2"); |
156 | register long __cookie asm("4") = cookie; | ||
154 | 157 | ||
155 | asm volatile ("diag 2,4,0x500\n" | 158 | asm volatile ("diag 2,4,0x500\n" |
156 | : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index) | 159 | : "=d" (__rc) : "d" (__nr), "d" (__schid), "d" (__index), |
160 | "d"(__cookie) | ||
157 | : "memory", "cc"); | 161 | : "memory", "cc"); |
158 | return __rc; | 162 | return __rc; |
159 | } | 163 | } |
@@ -166,7 +170,7 @@ static void virtio_ccw_kvm_notify(struct virtqueue *vq) | |||
166 | 170 | ||
167 | vcdev = to_vc_device(info->vq->vdev); | 171 | vcdev = to_vc_device(info->vq->vdev); |
168 | ccw_device_get_schid(vcdev->cdev, &schid); | 172 | ccw_device_get_schid(vcdev->cdev, &schid); |
169 | do_kvm_notify(schid, vq->index); | 173 | info->cookie = do_kvm_notify(schid, vq->index, info->cookie); |
170 | } | 174 | } |
171 | 175 | ||
172 | static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, | 176 | static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev, |