diff options
author | Tejun Heo <htejun@gmail.com> | 2007-12-18 16:33:05 +0900 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-23 05:24:12 -0500 |
commit | a0f79b929acaba10d4780acd2543eff20bf4b5b0 (patch) | |
tree | e637c1d9388a3991cd71c5be339c2ead59c460a2 /drivers/ata/libata-core.c | |
parent | 5df91a25df08d85700fef5fd59bb1873273e5ef5 (diff) |
libata: implement ata_timing_cycle2mode() and use it in libata-acpi and pata_acpi
libata-acpi is using separate timing tables for transfer modes
although libata-core has the complete ata_timing table. Implement
ata_timing_cycle2mode() to look for matching mode given transfer type
and cycle duration and use it in libata-acpi and pata_acpi to replace
private timing tables.
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-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 62c4b328b0b6..f01c1734b1d0 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2903,6 +2903,57 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, } /** + * ata_timing_cycle2mode - find xfer mode for the specified cycle duration + * @xfer_shift: ATA_SHIFT_* value for transfer type to examine. + * @cycle: cycle duration in ns + * + * Return matching xfer mode for @cycle. The returned mode is of + * the transfer type specified by @xfer_shift. If @cycle is too + * slow for @xfer_shift, 0xff is returned. If @cycle is faster + * than the fastest known mode, the fasted mode is returned. + * + * LOCKING: + * None. + * + * RETURNS: + * Matching xfer_mode, 0xff if no match found. + */ +u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle) +{ + u8 base_mode = 0xff, last_mode = 0xff; + const struct ata_xfer_ent *ent; + const struct ata_timing *t; + + for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) + if (ent->shift == xfer_shift) + base_mode = ent->base; + + for (t = ata_timing_find_mode(base_mode); + t && ata_xfer_mode2shift(t->mode) == xfer_shift; t++) { + unsigned short this_cycle; + + switch (xfer_shift) { + case ATA_SHIFT_PIO: + case ATA_SHIFT_MWDMA: + this_cycle = t->cycle; + break; + case ATA_SHIFT_UDMA: + this_cycle = t->udma; + break; + default: + return 0xff; + } + + if (cycle > this_cycle) + break; + + last_mode = t->mode; + } + + return last_mode; +} + +/** * ata_down_xfermask_limit - adjust dev xfer masks downward * @dev: Device to adjust xfer masks * @sel: ATA_DNXFER_* selector @@ -7630,6 +7681,7 @@ EXPORT_SYMBOL_GPL(ata_pio_need_iordy); EXPORT_SYMBOL_GPL(ata_timing_find_mode); EXPORT_SYMBOL_GPL(ata_timing_compute); EXPORT_SYMBOL_GPL(ata_timing_merge); +EXPORT_SYMBOL_GPL(ata_timing_cycle2mode); #ifdef CONFIG_PCI EXPORT_SYMBOL_GPL(pci_test_config_bits); |