]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/libata-scsi.c
libata: Fix a potential race condition in ata_scsi_park_show()
[linux-2.6-omap-h63xx.git] / drivers / ata / libata-scsi.c
index d5b9b7266c8bc9c6549acc679ec7be1b827f6f22..3fa75eac135de3627f3f5765c868ab2b7a6b907c 100644 (file)
@@ -190,7 +190,7 @@ static ssize_t ata_scsi_park_show(struct device *device,
        struct ata_port *ap;
        struct ata_link *link;
        struct ata_device *dev;
-       unsigned long flags;
+       unsigned long flags, now;
        unsigned int uninitialized_var(msecs);
        int rc = 0;
 
@@ -208,10 +208,11 @@ static ssize_t ata_scsi_park_show(struct device *device,
        }
 
        link = dev->link;
+       now = jiffies;
        if (ap->pflags & ATA_PFLAG_EH_IN_PROGRESS &&
            link->eh_context.unloaded_mask & (1 << dev->devno) &&
-           time_after(dev->unpark_deadline, jiffies))
-               msecs = jiffies_to_msecs(dev->unpark_deadline - jiffies);
+           time_after(dev->unpark_deadline, now))
+               msecs = jiffies_to_msecs(dev->unpark_deadline - now);
        else
                msecs = 0;
 
@@ -708,7 +709,11 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
 {
        struct ata_queued_cmd *qc;
 
-       qc = ata_qc_new_init(dev, cmd->request->tag);
+       if (cmd->request->tag != -1)
+               qc = ata_qc_new_init(dev, cmd->request->tag);
+       else
+               qc = ata_qc_new_init(dev, 0);
+
        if (qc) {
                qc->scsicmd = cmd;
                qc->scsidone = done;
@@ -1103,6 +1108,15 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
 
                depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id));
                depth = min(ATA_MAX_QUEUE - 1, depth);
+
+               /*
+                * If this device is behind a port multiplier, we have
+                * to share the tag map between all devices on that PMP.
+                * Set up the shared tag map here and we get automatic.
+                */
+               if (dev->link->ap->pmp_link)
+                       scsi_init_shared_tag_map(sdev->host, ATA_MAX_QUEUE - 1);
+
                scsi_set_tag_type(sdev, MSG_SIMPLE_TAG);
                scsi_activate_tcq(sdev, depth);
        }