diff options
author | Tejun Heo <htejun@gmail.com> | 2007-12-18 16:33:03 +0900 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-23 05:24:12 -0500 |
commit | 7c77fa4d51b1480bcec2e898c94d6912fe063c16 (patch) | |
tree | d7d18fb22c8df2425878d02f4b415c06efa56457 /drivers/ata/libata-acpi.c | |
parent | 9cde9ed151e170f2e2a530f7ec0032dfbe9f443b (diff) | |
download | linux-7c77fa4d51b1480bcec2e898c94d6912fe063c16.tar.gz linux-7c77fa4d51b1480bcec2e898c94d6912fe063c16.tar.bz2 linux-7c77fa4d51b1480bcec2e898c94d6912fe063c16.zip |
libata: separate out ata_acpi_gtm_xfermask() from pacpi_discover_modes()
Finding out matching transfer mode from ACPI GTM values is useful for
other purposes too. Separate out the function and timing tables from
pata_acpi::pacpi_discover_modes().
Other than checking shared-configuration bit after doing
ata_acpi_gtm() in pacpi_discover_modes() which should be safe, this
patch doesn't introduce any behavior change.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-acpi.c')
-rw-r--r-- | drivers/ata/libata-acpi.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index ebc4dfcf2f19..d6697baf243d 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -441,6 +441,84 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) return rc; } +/* Welcome to ACPI, bring a bucket */ +const unsigned int ata_acpi_pio_cycle[7] = { + 600, 383, 240, 180, 120, 100, 80 +}; +EXPORT_SYMBOL_GPL(ata_acpi_pio_cycle); + +const unsigned int ata_acpi_mwdma_cycle[5] = { + 480, 150, 120, 100, 80 +}; +EXPORT_SYMBOL_GPL(ata_acpi_mwdma_cycle); + +const unsigned int ata_acpi_udma_cycle[7] = { + 120, 80, 60, 45, 30, 20, 15 +}; +EXPORT_SYMBOL_GPL(ata_acpi_udma_cycle); + +/** + * ata_acpi_gtm_xfermode - determine xfermode from GTM parameter + * @dev: target device + * @gtm: GTM parameter to use + * + * Determine xfermask for @dev from @gtm. + * + * LOCKING: + * None. + * + * RETURNS: + * Determined xfermask. + */ +unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev, + const struct ata_acpi_gtm *gtm) +{ + int unit, i; + u32 t; + unsigned long mask = (0x7f << ATA_SHIFT_UDMA) | (0x7 << ATA_SHIFT_MWDMA) | (0x1F << ATA_SHIFT_PIO); + + /* we always use the 0 slot for crap hardware */ + unit = dev->devno; + if (!(gtm->flags & 0x10)) + unit = 0; + + /* start by scanning for PIO modes */ + for (i = 0; i < 7; i++) { + t = gtm->drive[unit].pio; + if (t <= ata_acpi_pio_cycle[i]) { + mask |= (2 << (ATA_SHIFT_PIO + i)) - 1; + break; + } + } + + /* See if we have MWDMA or UDMA data. We don't bother with + * MWDMA if UDMA is available as this means the BIOS set UDMA + * and our error changedown if it works is UDMA to PIO anyway. + */ + if (gtm->flags & (1 << (2 * unit))) { + /* MWDMA */ + for (i = 0; i < 5; i++) { + t = gtm->drive[unit].dma; + if (t <= ata_acpi_mwdma_cycle[i]) { + mask |= (2 << (ATA_SHIFT_MWDMA + i)) - 1; + break; + } + } + } else { + /* UDMA */ + for (i = 0; i < 7; i++) { + t = gtm->drive[unit].dma; + if (t <= ata_acpi_udma_cycle[i]) { + mask |= (2 << (ATA_SHIFT_UDMA + i)) - 1; + break; + } + } + } + + return mask; +} +EXPORT_SYMBOL_GPL(ata_acpi_gtm_xfermask); + /** * ata_acpi_cbl_80wire - Check for 80 wire cable * @ap: Port to check |