From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:45101) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Slcvx-0003XB-Qt for qemu-devel@nongnu.org; Mon, 02 Jul 2012 05:28:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Slcvs-00036S-0h for qemu-devel@nongnu.org; Mon, 02 Jul 2012 05:28:41 -0400 Received: from mail-wi0-f181.google.com ([209.85.212.181]:34729) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Slcvr-00035r-O6 for qemu-devel@nongnu.org; Mon, 02 Jul 2012 05:28:35 -0400 Received: by mail-wi0-f181.google.com with SMTP id hm2so2412932wib.10 for ; Mon, 02 Jul 2012 02:28:34 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Mon, 2 Jul 2012 11:28:27 +0200 Message-Id: <1341221307-24397-4-git-send-email-pbonzini@redhat.com> In-Reply-To: <1341221307-24397-1-git-send-email-pbonzini@redhat.com> References: <1341221307-24397-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 3/3] virtio-scsi: Report missed events List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: mc@linux.vnet.ibm.com When an event is reported but no buffers are present in the event vq, we can set a flag and report a dummy event as soon as one is added. Signed-off-by: Paolo Bonzini --- hw/virtio-scsi.c | 54 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c index 29d5a66..41f10c2 100644 --- a/hw/virtio-scsi.c +++ b/hw/virtio-scsi.c @@ -141,6 +141,7 @@ typedef struct { uint32_t sense_size; uint32_t cdb_size; int resetting; + bool events_dropped; VirtQueue *ctrl_vq; VirtQueue *event_vq; VirtQueue *cmd_vqs[0]; @@ -416,10 +417,6 @@ static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) } } -static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq) -{ -} - static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status, size_t resid) { @@ -594,27 +591,48 @@ static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev, { VirtIOSCSIReq *req = virtio_scsi_pop_req(s, s->event_vq); VirtIOSCSIEvent *evt; + int in_size; - if (req) { - int in_size; - if (req->elem.out_num || req->elem.in_num != 1) { - virtio_scsi_bad_req(); - } + if (!req) { + s->events_dropped = true; + return; + } - in_size = req->elem.in_sg[0].iov_len; - if (in_size < sizeof(VirtIOSCSIEvent)) { - virtio_scsi_bad_req(); - } + if (req->elem.out_num || req->elem.in_num != 1) { + virtio_scsi_bad_req(); + } - evt = req->resp.event; - memset(evt, 0, sizeof(VirtIOSCSIEvent)); - evt->event = event; - evt->reason = reason; + if (s->events_dropped) { + event |= VIRTIO_SCSI_T_EVENTS_MISSED; + s->events_dropped = false; + } + + in_size = req->elem.in_sg[0].iov_len; + if (in_size < sizeof(VirtIOSCSIEvent)) { + virtio_scsi_bad_req(); + } + + evt = req->resp.event; + memset(evt, 0, sizeof(VirtIOSCSIEvent)); + evt->event = event; + evt->reason = reason; + if (!dev) { + assert(event == VIRTIO_SCSI_T_NO_EVENT); + } else { evt->lun[0] = 1; evt->lun[1] = dev->id; evt->lun[2] = (dev->lun >> 8) | 0x40; evt->lun[3] = dev->lun & 0xFF; - virtio_scsi_complete_req(req); + } + virtio_scsi_complete_req(req); +} + +static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq) +{ + VirtIOSCSI *s = (VirtIOSCSI *)vdev; + + if (s->events_dropped) { + virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0); } } -- 1.7.10.2