ioctl passthrough commands require a SCSIIO smid, but cannot easily integrate with the block layer. But as we're only ever allowing one ioctl command at a time we can reserve smid 1 for ioctl commands. Signed-off-by: Hannes Reinecke <hare@xxxxxxxx> --- drivers/scsi/mpt3sas/mpt3sas_base.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 9b7273b..dec86c4 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -2355,13 +2355,20 @@ struct scsiio_tracker * return 0; } - request = list_entry(ioc->free_list.next, - struct scsiio_tracker, tracker_list); - request->scmd = scmd; + if (!scmd) { + /* ioctl command, always use the first slot */ + request = ioc->lookup[0]; + request->scmd = NULL; + } else { + request = list_entry(ioc->free_list.next, + struct scsiio_tracker, tracker_list); + request->scmd = scmd; + } request->cb_idx = cb_idx; smid = request->smid; request->msix_io = _base_get_msix_index(ioc); - list_del(&request->tracker_list); + if (scmd) + list_del(&request->tracker_list); spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); return smid; } @@ -2429,7 +2436,9 @@ struct scsiio_tracker * ioc->scsi_lookup[i].cb_idx = 0xFF; ioc->scsi_lookup[i].scmd = NULL; ioc->scsi_lookup[i].direct_io = 0; - list_add(&ioc->scsi_lookup[i].tracker_list, &ioc->free_list); + if (i > 0) + list_add(&ioc->scsi_lookup[i].tracker_list, + &ioc->free_list); spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); _base_recovery_check(ioc); @@ -5165,14 +5174,17 @@ struct scsiio_tracker * spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); INIT_LIST_HEAD(&ioc->free_list); smid = 1; - for (i = 0; i < ioc->scsiio_depth; i++, smid++) { + for (i = 1; i < ioc->scsiio_depth; i++, smid++) { INIT_LIST_HEAD(&ioc->scsi_lookup[i].chain_list); ioc->scsi_lookup[i].cb_idx = 0xFF; ioc->scsi_lookup[i].smid = smid; ioc->scsi_lookup[i].scmd = NULL; ioc->scsi_lookup[i].direct_io = 0; - list_add_tail(&ioc->scsi_lookup[i].tracker_list, - &ioc->free_list); + if (i == 1) + INIT_LIST_HEAD(&ioc->lookup[i].tracker_list); + else + list_add_tail(&ioc->scsi_lookup[i].tracker_list, + &ioc->free_list); } /* hi-priority queue */ -- 1.8.5.6