diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2011-04-18 16:01:56 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2011-05-26 12:14:15 +0200 |
commit | ad2d30f79d3b0812f02c741be2189796b788d6d7 (patch) | |
tree | 44cd67f6ef5577c71dda6feefa4474be621d0e8b /hw/scsi.h | |
parent | d33e0ce213cec82a059f5e37667231200eb77325 (diff) |
scsi: reference-count requests
With the next patch, a device may hold SCSIRequest for an indefinite
time. Split a rather big patch, and protect against access errors,
by reference counting them.
There is some ugliness in scsi_send_command implementation due to
the need to unref the request when it fails. This will go away
with the next patches, which move the unref'ing to the devices.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'hw/scsi.h')
-rw-r--r-- | hw/scsi.h | 5 |
1 files changed, 5 insertions, 0 deletions
@@ -29,6 +29,7 @@ enum SCSIXferMode { typedef struct SCSIRequest { SCSIBus *bus; SCSIDevice *dev; + uint32_t refcount; uint32_t tag; uint32_t lun; uint32_t status; @@ -65,6 +66,7 @@ struct SCSIDeviceInfo { DeviceInfo qdev; scsi_qdev_initfn init; void (*destroy)(SCSIDevice *s); + 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); @@ -103,6 +105,9 @@ 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_free(SCSIRequest *req); +void scsi_req_dequeue(SCSIRequest *req); +SCSIRequest *scsi_req_ref(SCSIRequest *req); +void scsi_req_unref(SCSIRequest *req); int scsi_req_parse(SCSIRequest *req, uint8_t *buf); void scsi_req_print(SCSIRequest *req); |