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 <[email protected]>
---
 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

Reply via email to