diff options
author | Tejun Heo <htejun@gmail.com> | 2006-05-31 05:27:38 -0400 |
---|---|---|
committer | Tejun Heo <htejun@gmail.com> | 2006-05-31 05:27:38 -0400 |
commit | 5a04bf4befa8bffa012eedc3a0903c158b9131a9 (patch) | |
tree | 7145c99e6df311a6d732fc3569d9a048829f92ba /drivers/scsi/libata-core.c | |
parent | 315343637b988ac32d730a6a9f7bf5866838bcb0 (diff) |
[PATCH] libata-hp-prep: implement ap->hw_sata_spd_limit
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>
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r-- | drivers/scsi/libata-core.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index a07ab77d32d6..b1a02fdbb0a5 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -2466,17 +2466,9 @@ static int sata_phy_resume(struct ata_port *ap) | |||
2466 | */ | 2466 | */ |
2467 | void ata_std_probeinit(struct ata_port *ap) | 2467 | void ata_std_probeinit(struct ata_port *ap) |
2468 | { | 2468 | { |
2469 | u32 scontrol; | ||
2470 | |||
2471 | /* resume link */ | 2469 | /* resume link */ |
2472 | sata_phy_resume(ap); | 2470 | sata_phy_resume(ap); |
2473 | 2471 | ||
2474 | /* init sata_spd_limit to the current value */ | ||
2475 | if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { | ||
2476 | int spd = (scontrol >> 4) & 0xf; | ||
2477 | ap->sata_spd_limit &= (1 << spd) - 1; | ||
2478 | } | ||
2479 | |||
2480 | /* wait for device */ | 2472 | /* wait for device */ |
2481 | if (ata_port_online(ap)) | 2473 | if (ata_port_online(ap)) |
2482 | ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); | 2474 | ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); |
@@ -5155,6 +5147,9 @@ void ata_dev_init(struct ata_device *dev) | |||
5155 | struct ata_port *ap = dev->ap; | 5147 | struct ata_port *ap = dev->ap; |
5156 | unsigned long flags; | 5148 | unsigned long flags; |
5157 | 5149 | ||
5150 | /* SATA spd limit is bound to the first device */ | ||
5151 | ap->sata_spd_limit = ap->hw_sata_spd_limit; | ||
5152 | |||
5158 | /* High bits of dev->flags are used to record warm plug | 5153 | /* High bits of dev->flags are used to record warm plug |
5159 | * requests which occur asynchronously. Synchronize using | 5154 | * requests which occur asynchronously. Synchronize using |
5160 | * host_set lock. | 5155 | * host_set lock. |
@@ -5210,7 +5205,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, | |||
5210 | ap->udma_mask = ent->udma_mask; | 5205 | ap->udma_mask = ent->udma_mask; |
5211 | ap->flags |= ent->host_flags; | 5206 | ap->flags |= ent->host_flags; |
5212 | ap->ops = ent->port_ops; | 5207 | ap->ops = ent->port_ops; |
5213 | ap->sata_spd_limit = UINT_MAX; | 5208 | ap->hw_sata_spd_limit = UINT_MAX; |
5214 | ap->active_tag = ATA_TAG_POISON; | 5209 | ap->active_tag = ATA_TAG_POISON; |
5215 | ap->last_ctl = 0xFF; | 5210 | ap->last_ctl = 0xFF; |
5216 | ap->msg_enable = ATA_MSG_DRV; | 5211 | ap->msg_enable = ATA_MSG_DRV; |
@@ -5375,10 +5370,18 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
5375 | DPRINTK("probe begin\n"); | 5370 | DPRINTK("probe begin\n"); |
5376 | for (i = 0; i < count; i++) { | 5371 | for (i = 0; i < count; i++) { |
5377 | struct ata_port *ap; | 5372 | struct ata_port *ap; |
5373 | u32 scontrol; | ||
5378 | int rc; | 5374 | int rc; |
5379 | 5375 | ||
5380 | ap = host_set->ports[i]; | 5376 | ap = host_set->ports[i]; |
5381 | 5377 | ||
5378 | /* init sata_spd_limit to the current value */ | ||
5379 | if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { | ||
5380 | int spd = (scontrol >> 4) & 0xf; | ||
5381 | ap->hw_sata_spd_limit &= (1 << spd) - 1; | ||
5382 | } | ||
5383 | ap->sata_spd_limit = ap->hw_sata_spd_limit; | ||
5384 | |||
5382 | DPRINTK("ata%u: bus probe begin\n", ap->id); | 5385 | DPRINTK("ata%u: bus probe begin\n", ap->id); |
5383 | rc = ata_bus_probe(ap); | 5386 | rc = ata_bus_probe(ap); |
5384 | DPRINTK("ata%u: bus probe end\n", ap->id); | 5387 | DPRINTK("ata%u: bus probe end\n", ap->id); |