aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/scsi/scsi-bus.c8
-rw-r--r--include/hw/scsi/scsi.h21
2 files changed, 19 insertions, 10 deletions
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 954c6072bf..af293b59da 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -551,8 +551,11 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
SCSIRequest *req;
SCSIBus *bus = scsi_bus_from_device(d);
BusState *qbus = BUS(bus);
+ const int memset_off = offsetof(SCSIRequest, sense)
+ + sizeof(req->sense);
- req = g_malloc0(reqops->size);
+ req = g_slice_alloc(reqops->size);
+ memset((uint8_t *)req + memset_off, 0, reqops->size - memset_off);
req->refcount = 1;
req->bus = bus;
req->dev = d;
@@ -560,7 +563,6 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
req->lun = lun;
req->hba_private = hba_private;
req->status = -1;
- req->sense_len = 0;
req->ops = reqops;
object_ref(OBJECT(d));
object_ref(OBJECT(qbus->parent));
@@ -1603,7 +1605,7 @@ void scsi_req_unref(SCSIRequest *req)
}
object_unref(OBJECT(req->dev));
object_unref(OBJECT(qbus->parent));
- g_free(req);
+ g_slice_free1(req->ops->size, req);
}
}
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 2e3a8f987d..6271ad3034 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -50,17 +50,24 @@ struct SCSIRequest {
uint32_t tag;
uint32_t lun;
uint32_t status;
+ void *hba_private;
size_t resid;
SCSICommand cmd;
+
+ /* Note:
+ * - fields before sense are initialized by scsi_req_alloc;
+ * - sense[] is uninitialized;
+ * - fields after sense are memset to 0 by scsi_req_alloc.
+ * */
+
+ uint8_t sense[SCSI_SENSE_BUF_SIZE];
+ uint32_t sense_len;
+ bool enqueued;
+ bool io_canceled;
+ bool retry;
+ bool dma_started;
BlockDriverAIOCB *aiocb;
QEMUSGList *sg;
- bool dma_started;
- uint8_t sense[SCSI_SENSE_BUF_SIZE];
- uint32_t sense_len;
- bool enqueued;
- bool io_canceled;
- bool retry;
- void *hba_private;
QTAILQ_ENTRY(SCSIRequest) next;
};