diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2009-11-26 15:33:49 +0100 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-12-03 09:41:36 -0600 |
commit | 9af99d980e9ff6270f291b11a064087b33dd3ab8 (patch) | |
tree | b0ac0266b94e7024c904973dddf84b51ca14b4ec /hw/scsi-disk.c | |
parent | 4c41d2ef5f599372a35d446fb75898fe9841bda4 (diff) | |
download | qemu-9af99d980e9ff6270f291b11a064087b33dd3ab8.zip qemu-9af99d980e9ff6270f291b11a064087b33dd3ab8.tar.gz qemu-9af99d980e9ff6270f291b11a064087b33dd3ab8.tar.bz2 |
scsi: move request lists to QTAILQ.
Changes:
* Move from open-coded lists to QTAILQ macros.
* Move the struct elements to the common data structures
(SCSIDevice + SCSIRequest).
* Drop free request pools.
* Fix request cleanup in the destroy callback.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/scsi-disk.c')
-rw-r--r-- | hw/scsi-disk.c | 67 |
1 files changed, 22 insertions, 45 deletions
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 142d81d..997eef6 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -55,7 +55,6 @@ typedef struct SCSIDiskReq { uint32_t sector_count; struct iovec iov; QEMUIOVector qiov; - struct SCSIDiskReq *next; uint32_t status; } SCSIDiskReq; @@ -63,7 +62,6 @@ struct SCSIDiskState { SCSIDevice qdev; DriveInfo *dinfo; - SCSIDiskReq *requests; /* The qemu block layer uses a fixed 512 byte sector size. This is the number of 512 byte blocks in a single scsi sector. */ int cluster_size; @@ -73,64 +71,37 @@ struct SCSIDiskState QEMUBH *bh; }; -/* Global pool of SCSIRequest structures. */ -static SCSIDiskReq *free_requests = NULL; - static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag) { - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); SCSIDiskReq *r; - if (free_requests) { - r = free_requests; - free_requests = r->next; - } else { - r = qemu_malloc(sizeof(SCSIDiskReq)); - r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE); - } + r = qemu_mallocz(sizeof(SCSIDiskReq)); + r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE); r->req.bus = scsi_bus_from_device(d); r->req.dev = d; r->req.tag = tag; - r->sector_count = 0; - r->iov.iov_len = 0; - r->req.aiocb = NULL; - r->status = 0; - r->next = s->requests; - s->requests = r; + QTAILQ_INSERT_TAIL(&d->requests, &r->req, next); return r; } static void scsi_remove_request(SCSIDiskReq *r) { - SCSIDiskReq *last; - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - - if (s->requests == r) { - s->requests = r->next; - } else { - last = s->requests; - while (last && last->next != r) - last = last->next; - if (last) { - last->next = r->next; - } else { - BADF("Orphaned request\n"); - } - } - r->next = free_requests; - free_requests = r; + qemu_free(r->iov.iov_base); + QTAILQ_REMOVE(&r->req.dev->requests, &r->req, next); + qemu_free(r); } static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag) { - SCSIDiskReq *r; - - r = s->requests; - while (r && r->req.tag != tag) - r = r->next; + SCSIRequest *req; - return r; + QTAILQ_FOREACH(req, &s->qdev.requests, next) { + if (req->tag == tag) { + return DO_UPCAST(SCSIDiskReq, req, req); + } + } + return NULL; } /* Helper function for command completion. */ @@ -310,17 +281,18 @@ static int scsi_write_data(SCSIDevice *d, uint32_t tag) static void scsi_dma_restart_bh(void *opaque) { SCSIDiskState *s = opaque; - SCSIDiskReq *r = s->requests; + SCSIRequest *req; + SCSIDiskReq *r; qemu_bh_delete(s->bh); s->bh = NULL; - while (r) { + QTAILQ_FOREACH(req, &s->qdev.requests, next) { + r = DO_UPCAST(SCSIDiskReq, req, req); if (r->status & SCSI_REQ_STATUS_RETRY) { r->status &= ~SCSI_REQ_STATUS_RETRY; scsi_write_request(r); } - r = r->next; } } @@ -959,7 +931,12 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, static void scsi_destroy(SCSIDevice *dev) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + SCSIDiskReq *r; + while (!QTAILQ_EMPTY(&s->qdev.requests)) { + r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests)); + scsi_remove_request(r); + } drive_uninit(s->dinfo); } |