]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
scsi: libsas: Disable asynchronous aborts for SATA devices
authorHannes Reinecke <hare@suse.de>
Wed, 10 Jan 2018 08:34:02 +0000 (09:34 +0100)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 10 Jan 2018 21:45:04 +0000 (16:45 -0500)
Handling CD-ROM devices from libsas is decidedly odd, as libata relies
on SCSI EH to be started to figure out that no medium is present.  So we
cannot do asynchronous aborts for SATA devices.

Fixes: 909657615d9 ("scsi: libsas: allow async aborts")
Cc: <stable@vger.kernel.org> # 4.12+
Signed-off-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Tested-by: Yves-Alexis Perez <corsac@debian.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/libsas/sas_scsi_host.c

index 91795eb56206603bb0a52baa62237e9787dd2bcf..eea94aa4091ca8e5939298cd1b02963f9a62daac 100644 (file)
@@ -486,15 +486,28 @@ static int sas_queue_reset(struct domain_device *dev, int reset_type,
 
 int sas_eh_abort_handler(struct scsi_cmnd *cmd)
 {
-       int res;
+       int res = TMF_RESP_FUNC_FAILED;
        struct sas_task *task = TO_SAS_TASK(cmd);
        struct Scsi_Host *host = cmd->device->host;
+       struct domain_device *dev = cmd_to_domain_dev(cmd);
        struct sas_internal *i = to_sas_internal(host->transportt);
+       unsigned long flags;
 
        if (!i->dft->lldd_abort_task)
                return FAILED;
 
-       res = i->dft->lldd_abort_task(task);
+       spin_lock_irqsave(host->host_lock, flags);
+       /* We cannot do async aborts for SATA devices */
+       if (dev_is_sata(dev) && !host->host_eh_scheduled) {
+               spin_unlock_irqrestore(host->host_lock, flags);
+               return FAILED;
+       }
+       spin_unlock_irqrestore(host->host_lock, flags);
+
+       if (task)
+               res = i->dft->lldd_abort_task(task);
+       else
+               SAS_DPRINTK("no task to abort\n");
        if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE)
                return SUCCESS;