virtio_scsi: use cmd_size

Taken almost entirely from Nicholas Bellinger's scsi-mq conversion.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
Christoph Hellwig 2014-05-01 16:51:50 +02:00
parent fdbcbcab0e
commit b54197c43d
2 changed files with 16 additions and 18 deletions

View file

@ -199,7 +199,6 @@ static void virtscsi_complete_cmd(struct virtio_scsi *vscsi, void *buf)
set_driver_byte(sc, DRIVER_SENSE); set_driver_byte(sc, DRIVER_SENSE);
} }
mempool_free(cmd, virtscsi_cmd_pool);
sc->scsi_done(sc); sc->scsi_done(sc);
atomic_dec(&tgt->reqs); atomic_dec(&tgt->reqs);
@ -242,8 +241,6 @@ static void virtscsi_complete_free(struct virtio_scsi *vscsi, void *buf)
if (cmd->comp) if (cmd->comp)
complete_all(cmd->comp); complete_all(cmd->comp);
else
mempool_free(cmd, virtscsi_cmd_pool);
} }
static void virtscsi_ctrl_done(struct virtqueue *vq) static void virtscsi_ctrl_done(struct virtqueue *vq)
@ -459,10 +456,9 @@ static int virtscsi_queuecommand(struct virtio_scsi *vscsi,
struct virtio_scsi_vq *req_vq, struct virtio_scsi_vq *req_vq,
struct scsi_cmnd *sc) struct scsi_cmnd *sc)
{ {
struct virtio_scsi_cmd *cmd;
int ret;
struct Scsi_Host *shost = virtio_scsi_host(vscsi->vdev); struct Scsi_Host *shost = virtio_scsi_host(vscsi->vdev);
struct virtio_scsi_cmd *cmd = scsi_cmd_priv(sc);
BUG_ON(scsi_sg_count(sc) > shost->sg_tablesize); BUG_ON(scsi_sg_count(sc) > shost->sg_tablesize);
/* TODO: check feature bit and fail if unsupported? */ /* TODO: check feature bit and fail if unsupported? */
@ -471,11 +467,6 @@ static int virtscsi_queuecommand(struct virtio_scsi *vscsi,
dev_dbg(&sc->device->sdev_gendev, dev_dbg(&sc->device->sdev_gendev,
"cmd %p CDB: %#02x\n", sc, sc->cmnd[0]); "cmd %p CDB: %#02x\n", sc, sc->cmnd[0]);
ret = SCSI_MLQUEUE_HOST_BUSY;
cmd = mempool_alloc(virtscsi_cmd_pool, GFP_ATOMIC);
if (!cmd)
goto out;
memset(cmd, 0, sizeof(*cmd)); memset(cmd, 0, sizeof(*cmd));
cmd->sc = sc; cmd->sc = sc;
cmd->req.cmd = (struct virtio_scsi_cmd_req){ cmd->req.cmd = (struct virtio_scsi_cmd_req){
@ -494,13 +485,9 @@ static int virtscsi_queuecommand(struct virtio_scsi *vscsi,
if (virtscsi_kick_cmd(req_vq, cmd, if (virtscsi_kick_cmd(req_vq, cmd,
sizeof cmd->req.cmd, sizeof cmd->resp.cmd, sizeof cmd->req.cmd, sizeof cmd->resp.cmd,
GFP_ATOMIC) == 0) GFP_ATOMIC) != 0)
ret = 0; return SCSI_MLQUEUE_HOST_BUSY;
else return 0;
mempool_free(cmd, virtscsi_cmd_pool);
out:
return ret;
} }
static int virtscsi_queuecommand_single(struct Scsi_Host *sh, static int virtscsi_queuecommand_single(struct Scsi_Host *sh,
@ -642,6 +629,7 @@ static struct scsi_host_template virtscsi_host_template_single = {
.name = "Virtio SCSI HBA", .name = "Virtio SCSI HBA",
.proc_name = "virtio_scsi", .proc_name = "virtio_scsi",
.this_id = -1, .this_id = -1,
.cmd_size = sizeof(struct virtio_scsi_cmd),
.queuecommand = virtscsi_queuecommand_single, .queuecommand = virtscsi_queuecommand_single,
.eh_abort_handler = virtscsi_abort, .eh_abort_handler = virtscsi_abort,
.eh_device_reset_handler = virtscsi_device_reset, .eh_device_reset_handler = virtscsi_device_reset,
@ -658,6 +646,7 @@ static struct scsi_host_template virtscsi_host_template_multi = {
.name = "Virtio SCSI HBA", .name = "Virtio SCSI HBA",
.proc_name = "virtio_scsi", .proc_name = "virtio_scsi",
.this_id = -1, .this_id = -1,
.cmd_size = sizeof(struct virtio_scsi_cmd),
.queuecommand = virtscsi_queuecommand_multi, .queuecommand = virtscsi_queuecommand_multi,
.eh_abort_handler = virtscsi_abort, .eh_abort_handler = virtscsi_abort,
.eh_device_reset_handler = virtscsi_device_reset, .eh_device_reset_handler = virtscsi_device_reset,

View file

@ -133,6 +133,15 @@ struct scsi_cmnd {
unsigned char tag; /* SCSI-II queued command tag */ unsigned char tag; /* SCSI-II queued command tag */
}; };
/*
* Return the driver private allocation behind the command.
* Only works if cmd_size is set in the host template.
*/
static inline void *scsi_cmd_priv(struct scsi_cmnd *cmd)
{
return cmd + 1;
}
/* make sure not to use it with REQ_TYPE_BLOCK_PC commands */ /* make sure not to use it with REQ_TYPE_BLOCK_PC commands */
static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
{ {