In the `scsi_generic_req_ops' struct, instead of pointing to the implementations of read_data/write_data/send_command, point to wrappers around these functions, prefixed with "common_".
Also, introduce the concept of "buffer" operations. Buffer operations are the read/write operations that rely on an intermediate buffer to do a request. This is the current mode, so we prefix the existing implementations with "buf_". This paves the way for the introduction of sg operations, which are operations that rely on scatter-gather lists. These "common" functions can be used later on as a common entry point for the read/write operations, in which we can decide whether the device will use an intermediate buffer for requests or the controller's scatter-gather list. Signed-off-by: Alex Pyrgiotis <apyr...@arrikto.com> Signed-off-by: Dimitris Aragiorgis <dim...@arrikto.com> diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index a4626f7..f24f472 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -175,7 +175,7 @@ static int execute_command(BlockBackend *blk, return 0; } -static void scsi_read_complete(void * opaque, int ret) +static void scsi_buf_read_complete(void *opaque, int ret) { SCSIGenericReq *r = (SCSIGenericReq *)opaque; SCSIDevice *s = r->req.dev; @@ -229,13 +229,13 @@ static void scsi_read_complete(void * opaque, int ret) } /* Read more data from scsi device into buffer. */ -static void scsi_read_data(SCSIRequest *req) +static void scsi_buf_read_data(SCSIRequest *req) { SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); SCSIDevice *s = r->req.dev; int ret; - DPRINTF("scsi_read_data 0x%x\n", req->tag); + DPRINTF("scsi_buf_read_data 0x%x\n", req->tag); /* The request is used as the AIO opaque value, so add a ref. */ scsi_req_ref(&r->req); @@ -245,13 +245,18 @@ static void scsi_read_data(SCSIRequest *req) } ret = execute_command(s->conf.blk, r, SG_DXFER_FROM_DEV, - scsi_read_complete); + scsi_buf_read_complete); if (ret < 0) { scsi_command_complete_noio(r, ret); } } -static void scsi_write_complete(void * opaque, int ret) +static void scsi_common_read_data(SCSIRequest *req) +{ + scsi_buf_read_data(req); +} + +static void scsi_buf_write_complete(void *opaque, int ret) { SCSIGenericReq *r = (SCSIGenericReq *)opaque; SCSIDevice *s = r->req.dev; @@ -277,13 +282,13 @@ static void scsi_write_complete(void * opaque, int ret) /* Write data to a scsi device. Returns nonzero on failure. The transfer may complete asynchronously. */ -static void scsi_write_data(SCSIRequest *req) +static void scsi_buf_write_data(SCSIRequest *req) { SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); SCSIDevice *s = r->req.dev; int ret; - DPRINTF("scsi_write_data 0x%x\n", req->tag); + DPRINTF("scsi_buf_write_data 0x%x\n", req->tag); if (r->len == 0) { r->len = r->buflen; scsi_req_data(&r->req, r->len); @@ -292,12 +297,18 @@ static void scsi_write_data(SCSIRequest *req) /* The request is used as the AIO opaque value, so add a ref. */ scsi_req_ref(&r->req); - ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, scsi_write_complete); + ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, + scsi_buf_write_complete); if (ret < 0) { scsi_command_complete_noio(r, ret); } } +static void scsi_common_write_data(SCSIRequest *req) +{ + scsi_buf_write_data(req); +} + /* Return a pointer to the data buffer. */ static uint8_t *scsi_get_buf(SCSIRequest *req) { @@ -311,7 +322,7 @@ static uint8_t *scsi_get_buf(SCSIRequest *req) (eg. disk reads), negative for transfers to the device (eg. disk writes), and zero if the command does not transfer any data. */ -static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd) +static int32_t scsi_common_send_command(SCSIRequest *req, uint8_t *cmd) { SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req); SCSIDevice *s = r->req.dev; @@ -466,9 +477,9 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp) const SCSIReqOps scsi_generic_req_ops = { .size = sizeof(SCSIGenericReq), .free_req = scsi_free_request, - .send_command = scsi_send_command, - .read_data = scsi_read_data, - .write_data = scsi_write_data, + .send_command = scsi_common_send_command, + .read_data = scsi_common_read_data, + .write_data = scsi_common_write_data, .get_buf = scsi_get_buf, .load_request = scsi_generic_load_request, .save_request = scsi_generic_save_request, -- 2.6.2