diff options
Diffstat (limited to 'qemu/hw/scsi/scsi-bus.c')
-rw-r--r-- | qemu/hw/scsi/scsi-bus.c | 31 |
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, |