summaryrefslogtreecommitdiffstats
path: root/qemu/hw/scsi/scsi-bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/hw/scsi/scsi-bus.c')
-rw-r--r--qemu/hw/scsi/scsi-bus.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/qemu/hw/scsi/scsi-bus.c b/qemu/hw/scsi/scsi-bus.c
index f0ae4625f..ad6f398c3 100644
--- a/qemu/hw/scsi/scsi-bus.c
+++ b/qemu/hw/scsi/scsi-bus.c
@@ -1,4 +1,6 @@
+#include "qemu/osdep.h"
#include "hw/hw.h"
+#include "qapi/error.h"
#include "qemu/error-report.h"
#include "hw/scsi/scsi.h"
#include "block/scsi.h"
@@ -7,6 +9,7 @@
#include "sysemu/blockdev.h"
#include "trace.h"
#include "sysemu/dma.h"
+#include "qemu/cutils.h"
static char *scsibus_get_dev_path(DeviceState *dev);
static char *scsibus_get_fw_dev_path(DeviceState *dev);
@@ -136,7 +139,8 @@ static void scsi_dma_restart_cb(void *opaque, int running, RunState state)
return;
}
if (!s->bh) {
- s->bh = qemu_bh_new(scsi_dma_restart_bh, s);
+ AioContext *ctx = blk_get_aio_context(s->conf.blk);
+ s->bh = aio_bh_new(ctx, scsi_dma_restart_bh, s);
qemu_bh_schedule(s->bh);
}
}
@@ -452,7 +456,7 @@ static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
r->buf[7] = 0x10 | (r->req.bus->info->tcq ? 0x02 : 0); /* Sync, TCQ. */
memcpy(&r->buf[8], "QEMU ", 8);
memcpy(&r->buf[16], "QEMU TARGET ", 16);
- pstrcpy((char *) &r->buf[32], 4, qemu_get_version());
+ pstrcpy((char *) &r->buf[32], 4, qemu_hw_version());
}
return true;
}
@@ -557,7 +561,7 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
const int memset_off = offsetof(SCSIRequest, sense)
+ sizeof(req->sense);
- req = g_slice_alloc(reqops->size);
+ req = g_malloc(reqops->size);
memset((uint8_t *)req + memset_off, 0, reqops->size - memset_off);
req->refcount = 1;
req->bus = bus;
@@ -987,7 +991,6 @@ static int scsi_req_xfer(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
}
/* fall through */
case READ_10:
- case RECOVER_BUFFERED_DATA:
case READ_12:
case READ_16:
cmd->xfer *= dev->blocksize;
@@ -1621,7 +1624,7 @@ void scsi_req_unref(SCSIRequest *req)
}
object_unref(OBJECT(req->dev));
object_unref(OBJECT(qbus->parent));
- g_slice_free1(req->ops->size, req);
+ g_free(req);
}
}
@@ -1759,8 +1762,14 @@ void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier)
notifier_list_add(&req->cancel_notifiers, notifier);
}
if (req->io_canceled) {
+ /* A blk_aio_cancel_async is pending; when it finishes,
+ * scsi_req_cancel_complete will be called and will
+ * call the notifier we just added. Just wait for that.
+ */
+ assert(req->aiocb);
return;
}
+ /* Dropped in scsi_req_cancel_complete. */
scsi_req_ref(req);
scsi_req_dequeue(req);
req->io_canceled = true;
@@ -1777,6 +1786,8 @@ void scsi_req_cancel(SCSIRequest *req)
if (!req->enqueued) {
return;
}
+ assert(!req->io_canceled);
+ /* Dropped in scsi_req_cancel_complete. */
scsi_req_ref(req);
scsi_req_dequeue(req);
req->io_canceled = true;
@@ -1840,17 +1851,19 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense)
{
SCSIRequest *req;
+ aio_context_acquire(blk_get_aio_context(sdev->conf.blk));
while (!QTAILQ_EMPTY(&sdev->requests)) {
req = QTAILQ_FIRST(&sdev->requests);
- scsi_req_cancel(req);
+ scsi_req_cancel_async(req, NULL);
}
-
+ blk_drain(sdev->conf.blk);
+ aio_context_release(blk_get_aio_context(sdev->conf.blk));
scsi_device_set_ua(sdev, sense);
}
static char *scsibus_get_dev_path(DeviceState *dev)
{
- SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
+ SCSIDevice *d = SCSI_DEVICE(dev);
DeviceState *hba = dev->parent_bus->parent;
char *id;
char *path;
@@ -2023,7 +2036,7 @@ static void scsi_device_class_init(ObjectClass *klass, void *data)
static void scsi_dev_instance_init(Object *obj)
{
DeviceState *dev = DEVICE(obj);
- SCSIDevice *s = DO_UPCAST(SCSIDevice, qdev, dev);
+ SCSIDevice *s = SCSI_DEVICE(dev);
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", NULL,