diff options
author | Hannes Reinecke <hare@suse.de> | 2011-04-18 12:35:39 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2011-05-26 12:14:15 +0200 |
commit | 5c6c0e513600ba57c3e73b7151d3c0664438f7b5 (patch) | |
tree | f08a9d140398fc3558ab6112ab03cc3831fed6f7 /hw/scsi.h | |
parent | 11257187e122f1b33e4983b881a2b6009f5993ca (diff) |
scsi: Use 'SCSIRequest' directly
Currently the SCSIRequest structure is abstracted away and cannot accessed
directly from the driver. This requires the handler to do a lookup on
an abstract 'tag' which identifies the SCSIRequest structure.
With this patch the SCSIRequest structure is exposed to the driver. This
allows use to use it directly as an argument to the SCSIDeviceInfo
callback functions and remove the lookup.
A new callback function 'alloc_req' is introduced matching 'free
req'; unref'ing to free up resources after use is moved into the
scsi_command_complete callbacks.
This temporarily introduces a leak of requests that are cancelled,
when they are removed from the queue and not from the driver. This
is fixed later by introducing scsi_req_cancel. That patch in turn
depends on this one, because the argument to scsi_req_cancel is a
SCSIRequest.
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'hw/scsi.h')
-rw-r--r-- | hw/scsi.h | 21 |
1 files changed, 11 insertions, 10 deletions
@@ -19,6 +19,7 @@ typedef struct SCSIBus SCSIBus; typedef struct SCSIBusOps SCSIBusOps; typedef struct SCSIDevice SCSIDevice; typedef struct SCSIDeviceInfo SCSIDeviceInfo; +typedef struct SCSIRequest SCSIRequest; enum SCSIXferMode { SCSI_XFER_NONE, /* TEST_UNIT_READY, ... */ @@ -26,7 +27,7 @@ enum SCSIXferMode { SCSI_XFER_TO_DEV, /* WRITE, MODE_SELECT, ... */ }; -typedef struct SCSIRequest { +struct SCSIRequest { SCSIBus *bus; SCSIDevice *dev; uint32_t refcount; @@ -43,7 +44,7 @@ typedef struct SCSIRequest { BlockDriverAIOCB *aiocb; bool enqueued; QTAILQ_ENTRY(SCSIRequest) next; -} SCSIRequest; +}; struct SCSIDevice { @@ -66,17 +67,17 @@ struct SCSIDeviceInfo { DeviceInfo qdev; scsi_qdev_initfn init; void (*destroy)(SCSIDevice *s); + SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun); void (*free_req)(SCSIRequest *req); - int32_t (*send_command)(SCSIDevice *s, uint32_t tag, uint8_t *buf, - int lun); - void (*read_data)(SCSIDevice *s, uint32_t tag); - int (*write_data)(SCSIDevice *s, uint32_t tag); - void (*cancel_io)(SCSIDevice *s, uint32_t tag); - uint8_t *(*get_buf)(SCSIDevice *s, uint32_t tag); + int32_t (*send_command)(SCSIRequest *req, uint8_t *buf); + void (*read_data)(SCSIRequest *req); + int (*write_data)(SCSIRequest *req); + void (*cancel_io)(SCSIRequest *req); + uint8_t *(*get_buf)(SCSIRequest *req); }; struct SCSIBusOps { - void (*complete)(SCSIBus *bus, int reason, uint32_t tag, uint32_t arg); + void (*complete)(SCSIRequest *req, int reason, uint32_t arg); }; struct SCSIBus { @@ -103,7 +104,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, int scsi_bus_legacy_handle_cmdline(SCSIBus *bus); SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t lun); -SCSIRequest *scsi_req_find(SCSIDevice *d, uint32_t tag); +void scsi_req_enqueue(SCSIRequest *req); void scsi_req_free(SCSIRequest *req); void scsi_req_dequeue(SCSIRequest *req); SCSIRequest *scsi_req_ref(SCSIRequest *req); |