Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 62012
b: refs/heads/master
c: 008a789
h: refs/heads/master
v: v3
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed Jul 20, 2007
1 parent b82cac2 commit dd31575
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: badc2341579511a247f5993865aa68379e283c5c
refs/heads/master: 008a78961ec72990d09d7625ef9499d7317d040d
29 changes: 22 additions & 7 deletions trunk/drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2389,21 +2389,35 @@ int sata_down_spd_limit(struct ata_port *ap)
u32 sstatus, spd, mask;
int rc, highbit;

if (!sata_scr_valid(ap))
return -EOPNOTSUPP;

/* If SCR can be read, use it to determine the current SPD.
* If not, use cached value in ap->sata_spd.
*/
rc = sata_scr_read(ap, SCR_STATUS, &sstatus);
if (rc)
return rc;
if (rc == 0)
spd = (sstatus >> 4) & 0xf;
else
spd = ap->sata_spd;

mask = ap->sata_spd_limit;
if (mask <= 1)
return -EINVAL;

/* unconditionally mask off the highest bit */
highbit = fls(mask) - 1;
mask &= ~(1 << highbit);

spd = (sstatus >> 4) & 0xf;
if (spd <= 1)
return -EINVAL;
spd--;
mask &= (1 << spd) - 1;
/* Mask off all speeds higher than or equal to the current
* one. Force 1.5Gbps if current SPD is not available.
*/
if (spd > 1)
mask &= (1 << (spd - 1)) - 1;
else
mask &= 1;

/* were we already at the bottom? */
if (!mask)
return -EINVAL;

Expand Down Expand Up @@ -5995,6 +6009,7 @@ void ata_dev_init(struct ata_device *dev)

/* SATA spd limit is bound to the first device */
ap->sata_spd_limit = ap->hw_sata_spd_limit;
ap->sata_spd = 0;

/* High bits of dev->flags are used to record warm plug
* requests which occur asynchronously. Synchronize using
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/ata/libata-eh.c
Original file line number Diff line number Diff line change
Expand Up @@ -1799,12 +1799,18 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
}

if (rc == 0) {
u32 sstatus;

/* After the reset, the device state is PIO 0 and the
* controller state is undefined. Record the mode.
*/
for (i = 0; i < ATA_MAX_DEVICES; i++)
ap->device[i].pio_mode = XFER_PIO_0;

/* record current link speed */
if (sata_scr_read(ap, SCR_STATUS, &sstatus) == 0)
ap->sata_spd = (sstatus >> 4) & 0xf;

if (postreset)
postreset(ap, classes);

Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ struct ata_port {
unsigned int cbl; /* cable type; ATA_CBL_xxx */
unsigned int hw_sata_spd_limit;
unsigned int sata_spd_limit; /* SATA PHY speed limit */
unsigned int sata_spd; /* current SATA PHY speed */

/* record runtime error info, protected by host lock */
struct ata_eh_info eh_info;
Expand Down

0 comments on commit dd31575

Please sign in to comment.