diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2011-09-06 09:08:34 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2011-09-06 13:02:16 +0200 |
commit | 0a4ac106f780e2ddab27d6ab4e2880fa52a2c704 (patch) | |
tree | 58bbc2c2c2224f5ee0916225b7d0bc40523c9757 /hw/scsi-disk.c | |
parent | bb45ded93115ad4303471c9a492579dc36716547 (diff) | |
download | qemu-0a4ac106f780e2ddab27d6ab4e2880fa52a2c704.tar.gz qemu-0a4ac106f780e2ddab27d6ab4e2880fa52a2c704.tar.bz2 qemu-0a4ac106f780e2ddab27d6ab4e2880fa52a2c704.zip |
scsi: execute SYNCHRONIZE_CACHE asynchronously
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'hw/scsi-disk.c')
-rw-r--r-- | hw/scsi-disk.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 3cc830ff95..5c652a26c9 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -129,6 +129,24 @@ static void scsi_read_complete(void * opaque, int ret) scsi_req_data(&r->req, r->iov.iov_len); } +static void scsi_flush_complete(void * opaque, int ret) +{ + SCSIDiskReq *r = (SCSIDiskReq *)opaque; + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); + + if (r->req.aiocb != NULL) { + r->req.aiocb = NULL; + bdrv_acct_done(s->bs, &r->acct); + } + + if (ret < 0) { + if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) { + return; + } + } + + scsi_req_complete(&r->req, GOOD); +} /* Read more data from scsi device into buffer. */ static void scsi_read_data(SCSIRequest *req) @@ -792,7 +810,6 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); uint64_t nb_sectors; int buflen = 0; - int ret; switch (req->cmd.buf[0]) { case TEST_UNIT_READY: @@ -864,20 +881,6 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) outbuf[7] = 0; buflen = 8; break; - case SYNCHRONIZE_CACHE: - { - BlockAcctCookie acct; - - bdrv_acct_start(s->bs, &acct, 0, BDRV_ACCT_FLUSH); - ret = bdrv_flush(s->bs); - bdrv_acct_done(s->bs, &acct); - if (ret < 0) { - if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) { - return -1; - } - } - break; - } case GET_CONFIGURATION: memset(outbuf, 0, 8); /* ??? This should probably return much more information. For now @@ -985,7 +988,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) case START_STOP: case ALLOW_MEDIUM_REMOVAL: case READ_CAPACITY_10: - case SYNCHRONIZE_CACHE: case READ_TOC: case GET_CONFIGURATION: case SERVICE_ACTION_IN: @@ -997,6 +999,13 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) r->iov.iov_len = rc; break; + case SYNCHRONIZE_CACHE: + bdrv_acct_start(s->bs, &r->acct, 0, BDRV_ACCT_FLUSH); + r->req.aiocb = bdrv_aio_flush(s->bs, scsi_flush_complete, r); + if (r->req.aiocb == NULL) { + scsi_flush_complete(r, -EIO); + } + return 0; case READ_6: case READ_10: case READ_12: |