Loading drivers/scsi/virtio_scsi.c +7 −18 Original line number Original line Diff line number Diff line Loading @@ -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); Loading Loading @@ -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) Loading Loading @@ -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? */ Loading @@ -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){ Loading @@ -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, Loading Loading @@ -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, Loading @@ -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, Loading include/scsi/scsi_cmnd.h +9 −0 Original line number Original line Diff line number Diff line Loading @@ -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) { { Loading Loading
drivers/scsi/virtio_scsi.c +7 −18 Original line number Original line Diff line number Diff line Loading @@ -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); Loading Loading @@ -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) Loading Loading @@ -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? */ Loading @@ -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){ Loading @@ -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, Loading Loading @@ -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, Loading @@ -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, Loading
include/scsi/scsi_cmnd.h +9 −0 Original line number Original line Diff line number Diff line Loading @@ -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) { { Loading