@@ -244,7 +244,7 @@ struct fib *aac_fib_alloc(struct aac_dev *dev, int direction)
unsigned long flags;
spin_lock_irqsave(&dev->fib_lock, flags);
- scmd = scsi_get_reserved_cmd(dev->scsi_host_dev, direction);
+ scmd = scsi_get_reserved_cmd(dev->scsi_host_dev, direction, false);
if (scmd)
fibptr = aac_fib_alloc_tag(dev, scmd);
spin_unlock_irqrestore(&dev->fib_lock, flags);
@@ -2105,7 +2105,7 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
goto fail;
}
- reset_cmnd = scsi_get_reserved_cmd(sdev, DMA_NONE);
+ reset_cmnd = scsi_get_reserved_cmd(sdev, DMA_NONE, false);
if (!reset_cmnd) {
csio_err(hw, "No free TMF request\n");
goto fail;
@@ -2237,7 +2237,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
goto fnic_device_reset_end;
}
- reset_sc = scsi_get_reserved_cmd(sdev, DMA_NONE);
+ reset_sc = scsi_get_reserved_cmd(sdev, DMA_NONE, false);
if (unlikely(!reset_sc))
goto fnic_device_reset_end;
@@ -6148,7 +6148,7 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h, u8 direction)
int idx;
scmd = scsi_get_reserved_cmd(h->raid_ctrl_sdev, direction & XFER_WRITE ?
- DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ DMA_TO_DEVICE : DMA_FROM_DEVICE, false);
if (!scmd) {
dev_warn(&h->pdev->dev, "failed to allocate reserved cmd\n");
return NULL;
@@ -1929,17 +1929,27 @@ void scsi_mq_destroy_tags(struct Scsi_Host *shost)
* scsi_get_reserved_cmd - allocate a SCSI command from reserved tags
* @sdev: SCSI device from which to allocate the command
* @data_direction: Data direction for the allocated command
+ * @persistent: Allocate a persistent command
*/
struct scsi_cmnd *scsi_get_reserved_cmd(struct scsi_device *sdev,
- int data_direction)
+ int data_direction, bool persistent)
{
struct request *rq;
struct scsi_cmnd *scmd;
+ blk_mq_req_flags_t flags = 0;
+ int op = REQ_NOWAIT;
- rq = blk_mq_alloc_request(sdev->request_queue,
- data_direction == DMA_TO_DEVICE ?
- REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN | REQ_NOWAIT,
- BLK_MQ_REQ_RESERVED);
+ if (sdev->host->nr_reserved_cmds) {
+ flags |= BLK_MQ_REQ_RESERVED;
+ if (persistent)
+ flags |= BLK_MQ_REQ_PERSISTENT;
+ }
+ if (data_direction == DMA_TO_DEVICE)
+ op |= REQ_OP_SCSI_OUT;
+ else
+ op |= REQ_OP_SCSI_IN;
+
+ rq = blk_mq_alloc_request(sdev->request_queue, op, flags);
if (IS_ERR(rq))
return NULL;
scmd = blk_mq_rq_to_pdu(rq);
@@ -620,7 +620,7 @@ static int virtscsi_device_reset(struct scsi_cmnd *sc)
int rc;
sdev_printk(KERN_INFO, sdev, "device reset\n");
- reset_sc = scsi_get_reserved_cmd(sdev, DMA_NONE);
+ reset_sc = scsi_get_reserved_cmd(sdev, DMA_NONE, false);
if (!reset_sc)
return FAILED;
cmd = scsi_cmd_priv(reset_sc);
@@ -684,7 +684,7 @@ static int virtscsi_abort(struct scsi_cmnd *sc)
int rc;
scmd_printk(KERN_INFO, sc, "abort\n");
- reset_sc = scsi_get_reserved_cmd(sdev, DMA_NONE);
+ reset_sc = scsi_get_reserved_cmd(sdev, DMA_NONE, false);
if (!reset_sc)
return FAILED;
cmd = scsi_cmd_priv(reset_sc);
@@ -459,7 +459,7 @@ static inline int scsi_execute_req(struct scsi_device *sdev,
bufflen, NULL, sshdr, timeout, retries, 0, 0, resid);
}
struct scsi_cmnd *scsi_get_reserved_cmd(struct scsi_device *sdev,
- int data_direction);
+ int data_direction, bool persistent);
void scsi_put_reserved_cmd(struct scsi_cmnd *scmd);
extern void sdev_disable_disk_events(struct scsi_device *sdev);
extern void sdev_enable_disk_events(struct scsi_device *sdev);
To correctly handle AENs the corresponding command needs to be marked as 'persistent', so add an additional flag to scsi_get_reserved_cmd(). Signed-off-by: Hannes Reinecke <hare@suse.de> --- drivers/scsi/aacraid/commsup.c | 2 +- drivers/scsi/csiostor/csio_scsi.c | 2 +- drivers/scsi/fnic/fnic_scsi.c | 2 +- drivers/scsi/hpsa.c | 2 +- drivers/scsi/scsi_lib.c | 20 +++++++++++++++----- drivers/scsi/virtio_scsi.c | 4 ++-- include/scsi/scsi_device.h | 2 +- 7 files changed, 22 insertions(+), 12 deletions(-)