[PATCH] libata-hp-prep: implement ap->hw_sata_spd_limit
authorTejun Heo <htejun@gmail.com>
Wed, 31 May 2006 09:27:38 +0000 (18:27 +0900)
committerTejun Heo <htejun@gmail.com>
Wed, 31 May 2006 09:27:38 +0000 (18:27 +0900)
Add ap->hw_sata_spd_limit and initialize it once during the boot
initialization (or driver load initialization).  ap->sata_spd_limit is
reset to ap->hw_sata_spd_limit on hotplug.  This prevents spd limits
introduced by earlier devices from affecting new devices.

Signed-off-by: Tejun Heo <htejun@gmail.com>
drivers/scsi/libata-core.c
include/linux/libata.h

index a07ab77..b1a02fd 100644 (file)
@@ -2466,17 +2466,9 @@ static int sata_phy_resume(struct ata_port *ap)
  */
 void ata_std_probeinit(struct ata_port *ap)
 {
-       u32 scontrol;
-
        /* resume link */
        sata_phy_resume(ap);
 
-       /* init sata_spd_limit to the current value */
-       if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
-               int spd = (scontrol >> 4) & 0xf;
-               ap->sata_spd_limit &= (1 << spd) - 1;
-       }
-
        /* wait for device */
        if (ata_port_online(ap))
                ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
@@ -5155,6 +5147,9 @@ void ata_dev_init(struct ata_device *dev)
        struct ata_port *ap = dev->ap;
        unsigned long flags;
 
+       /* SATA spd limit is bound to the first device */
+       ap->sata_spd_limit = ap->hw_sata_spd_limit;
+
        /* High bits of dev->flags are used to record warm plug
         * requests which occur asynchronously.  Synchronize using
         * host_set lock.
@@ -5210,7 +5205,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
        ap->udma_mask = ent->udma_mask;
        ap->flags |= ent->host_flags;
        ap->ops = ent->port_ops;
-       ap->sata_spd_limit = UINT_MAX;
+       ap->hw_sata_spd_limit = UINT_MAX;
        ap->active_tag = ATA_TAG_POISON;
        ap->last_ctl = 0xFF;
        ap->msg_enable = ATA_MSG_DRV;
@@ -5375,10 +5370,18 @@ int ata_device_add(const struct ata_probe_ent *ent)
        DPRINTK("probe begin\n");
        for (i = 0; i < count; i++) {
                struct ata_port *ap;
+               u32 scontrol;
                int rc;
 
                ap = host_set->ports[i];
 
+               /* init sata_spd_limit to the current value */
+               if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
+                       int spd = (scontrol >> 4) & 0xf;
+                       ap->hw_sata_spd_limit &= (1 << spd) - 1;
+               }
+               ap->sata_spd_limit = ap->hw_sata_spd_limit;
+
                DPRINTK("ata%u: bus probe begin\n", ap->id);
                rc = ata_bus_probe(ap);
                DPRINTK("ata%u: bus probe end\n", ap->id);
index aa14eda..10dc235 100644 (file)
@@ -489,6 +489,7 @@ struct ata_port {
        unsigned int            mwdma_mask;
        unsigned int            udma_mask;
        unsigned int            cbl;    /* cable type; ATA_CBL_xxx */
+       unsigned int            hw_sata_spd_limit;
        unsigned int            sata_spd_limit; /* SATA PHY speed limit */
 
        /* record runtime error info, protected by host_set lock */