diff options
author | Tejun Heo <htejun@gmail.com> | 2007-12-18 02:33:05 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-23 05:24:12 -0500 |
commit | a0f79b929acaba10d4780acd2543eff20bf4b5b0 (patch) | |
tree | e637c1d9388a3991cd71c5be339c2ead59c460a2 | |
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>
-rw-r--r-- | drivers/ata/libata-acpi.c | 62 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 52 | ||||
-rw-r--r-- | drivers/ata/pata_acpi.c | 13 | ||||
-rw-r--r-- | include/linux/libata.h | 5 |
4 files changed, 75 insertions, 57 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 9f0b208afcf5..a6f1a6b56d8c 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -441,22 +441,6 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) | |||
441 | return rc; | 441 | return rc; |
442 | } | 442 | } |
443 | 443 | ||
444 | /* Welcome to ACPI, bring a bucket */ | ||
445 | const unsigned int ata_acpi_pio_cycle[7] = { | ||
446 | 600, 383, 240, 180, 120, 100, 80 | ||
447 | }; | ||
448 | EXPORT_SYMBOL_GPL(ata_acpi_pio_cycle); | ||
449 | |||
450 | const unsigned int ata_acpi_mwdma_cycle[5] = { | ||
451 | 480, 150, 120, 100, 80 | ||
452 | }; | ||
453 | EXPORT_SYMBOL_GPL(ata_acpi_mwdma_cycle); | ||
454 | |||
455 | const unsigned int ata_acpi_udma_cycle[7] = { | ||
456 | 120, 80, 60, 45, 30, 20, 15 | ||
457 | }; | ||
458 | EXPORT_SYMBOL_GPL(ata_acpi_udma_cycle); | ||
459 | |||
460 | /** | 444 | /** |
461 | * ata_acpi_gtm_xfermode - determine xfermode from GTM parameter | 445 | * ata_acpi_gtm_xfermode - determine xfermode from GTM parameter |
462 | * @dev: target device | 446 | * @dev: target device |
@@ -473,49 +457,33 @@ EXPORT_SYMBOL_GPL(ata_acpi_udma_cycle); | |||
473 | unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev, | 457 | unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev, |
474 | const struct ata_acpi_gtm *gtm) | 458 | const struct ata_acpi_gtm *gtm) |
475 | { | 459 | { |
476 | unsigned long pio_mask = 0, mwdma_mask = 0, udma_mask = 0; | 460 | unsigned long xfer_mask = 0; |
477 | int unit, i; | 461 | unsigned int type; |
478 | u32 t; | 462 | int unit; |
463 | u8 mode; | ||
479 | 464 | ||
480 | /* we always use the 0 slot for crap hardware */ | 465 | /* we always use the 0 slot for crap hardware */ |
481 | unit = dev->devno; | 466 | unit = dev->devno; |
482 | if (!(gtm->flags & 0x10)) | 467 | if (!(gtm->flags & 0x10)) |
483 | unit = 0; | 468 | unit = 0; |
484 | 469 | ||
485 | /* Values larger than the longest cycle results in 0 mask | 470 | /* PIO */ |
486 | * while values equal to smaller than the shortest cycle | 471 | mode = ata_timing_cycle2mode(ATA_SHIFT_PIO, gtm->drive[unit].pio); |
487 | * results in mask which includes all supported modes. | 472 | xfer_mask |= ata_xfer_mode2mask(mode); |
488 | * Disabled transfer method has the value of 0xffffffff which | ||
489 | * will always result in 0 mask. | ||
490 | */ | ||
491 | |||
492 | /* start by scanning for PIO modes */ | ||
493 | t = gtm->drive[unit].pio; | ||
494 | for (i = 0; i < ARRAY_SIZE(ata_acpi_pio_cycle); i++) | ||
495 | if (t > ata_acpi_pio_cycle[i]) | ||
496 | break; | ||
497 | pio_mask = (1 << i) - 1; | ||
498 | 473 | ||
499 | /* See if we have MWDMA or UDMA data. We don't bother with | 474 | /* See if we have MWDMA or UDMA data. We don't bother with |
500 | * MWDMA if UDMA is available as this means the BIOS set UDMA | 475 | * MWDMA if UDMA is available as this means the BIOS set UDMA |
501 | * and our error changedown if it works is UDMA to PIO anyway. | 476 | * and our error changedown if it works is UDMA to PIO anyway. |
502 | */ | 477 | */ |
503 | t = gtm->drive[unit].dma; | 478 | if (!(gtm->flags & (1 << (2 * unit)))) |
504 | if (!(gtm->flags & (1 << (2 * unit)))) { | 479 | type = ATA_SHIFT_MWDMA; |
505 | /* MWDMA */ | 480 | else |
506 | for (i = 0; i < ARRAY_SIZE(ata_acpi_mwdma_cycle); i++) | 481 | type = ATA_SHIFT_UDMA; |
507 | if (t > ata_acpi_mwdma_cycle[i]) | 482 | |
508 | break; | 483 | mode = ata_timing_cycle2mode(type, gtm->drive[unit].dma); |
509 | mwdma_mask = (1 << i) - 1; | 484 | xfer_mask |= ata_xfer_mode2mask(mode); |
510 | } else { | ||
511 | /* UDMA */ | ||
512 | for (i = 0; i < ARRAY_SIZE(ata_acpi_udma_cycle); i++) | ||
513 | if (t > ata_acpi_udma_cycle[i]) | ||
514 | break; | ||
515 | udma_mask = (1 << i) - 1; | ||
516 | } | ||
517 | 485 | ||
518 | return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask); | 486 | return xfer_mask; |
519 | } | 487 | } |
520 | EXPORT_SYMBOL_GPL(ata_acpi_gtm_xfermask); | 488 | EXPORT_SYMBOL_GPL(ata_acpi_gtm_xfermask); |
521 | 489 | ||
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, | |||
2903 | } | 2903 | } |
2904 | 2904 | ||
2905 | /** | 2905 | /** |
2906 | * ata_timing_cycle2mode - find xfer mode for the specified cycle duration | ||
2907 | * @xfer_shift: ATA_SHIFT_* value for transfer type to examine. | ||
2908 | * @cycle: cycle duration in ns | ||
2909 | * | ||
2910 | * Return matching xfer mode for @cycle. The returned mode is of | ||
2911 | * the transfer type specified by @xfer_shift. If @cycle is too | ||
2912 | * slow for @xfer_shift, 0xff is returned. If @cycle is faster | ||
2913 | * than the fastest known mode, the fasted mode is returned. | ||
2914 | * | ||
2915 | * LOCKING: | ||
2916 | * None. | ||
2917 | * | ||
2918 | * RETURNS: | ||
2919 | * Matching xfer_mode, 0xff if no match found. | ||
2920 | */ | ||
2921 | u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle) | ||
2922 | { | ||
2923 | u8 base_mode = 0xff, last_mode = 0xff; | ||
2924 | const struct ata_xfer_ent *ent; | ||
2925 | const struct ata_timing *t; | ||
2926 | |||
2927 | for (ent = ata_xfer_tbl; ent->shift >= 0; ent++) | ||
2928 | if (ent->shift == xfer_shift) | ||
2929 | base_mode = ent->base; | ||
2930 | |||
2931 | for (t = ata_timing_find_mode(base_mode); | ||
2932 | t && ata_xfer_mode2shift(t->mode) == xfer_shift; t++) { | ||
2933 | unsigned short this_cycle; | ||
2934 | |||
2935 | switch (xfer_shift) { | ||
2936 | case ATA_SHIFT_PIO: | ||
2937 | case ATA_SHIFT_MWDMA: | ||
2938 | this_cycle = t->cycle; | ||
2939 | break; | ||
2940 | case ATA_SHIFT_UDMA: | ||
2941 | this_cycle = t->udma; | ||
2942 | break; | ||
2943 | default: | ||
2944 | return 0xff; | ||
2945 | } | ||
2946 | |||
2947 | if (cycle > this_cycle) | ||
2948 | break; | ||
2949 | |||
2950 | last_mode = t->mode; | ||
2951 | } | ||
2952 | |||
2953 | return last_mode; | ||
2954 | } | ||
2955 | |||
2956 | /** | ||
2906 | * ata_down_xfermask_limit - adjust dev xfer masks downward | 2957 | * ata_down_xfermask_limit - adjust dev xfer masks downward |
2907 | * @dev: Device to adjust xfer masks | 2958 | * @dev: Device to adjust xfer masks |
2908 | * @sel: ATA_DNXFER_* selector | 2959 | * @sel: ATA_DNXFER_* selector |
@@ -7630,6 +7681,7 @@ EXPORT_SYMBOL_GPL(ata_pio_need_iordy); | |||
7630 | EXPORT_SYMBOL_GPL(ata_timing_find_mode); | 7681 | EXPORT_SYMBOL_GPL(ata_timing_find_mode); |
7631 | EXPORT_SYMBOL_GPL(ata_timing_compute); | 7682 | EXPORT_SYMBOL_GPL(ata_timing_compute); |
7632 | EXPORT_SYMBOL_GPL(ata_timing_merge); | 7683 | EXPORT_SYMBOL_GPL(ata_timing_merge); |
7684 | EXPORT_SYMBOL_GPL(ata_timing_cycle2mode); | ||
7633 | 7685 | ||
7634 | #ifdef CONFIG_PCI | 7686 | #ifdef CONFIG_PCI |
7635 | EXPORT_SYMBOL_GPL(pci_test_config_bits); | 7687 | EXPORT_SYMBOL_GPL(pci_test_config_bits); |
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index a4737a3d31cb..244098a80ce4 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c | |||
@@ -133,13 +133,14 @@ static void pacpi_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
133 | { | 133 | { |
134 | int unit = adev->devno; | 134 | int unit = adev->devno; |
135 | struct pata_acpi *acpi = ap->private_data; | 135 | struct pata_acpi *acpi = ap->private_data; |
136 | const struct ata_timing *t; | ||
136 | 137 | ||
137 | if (!(acpi->gtm.flags & 0x10)) | 138 | if (!(acpi->gtm.flags & 0x10)) |
138 | unit = 0; | 139 | unit = 0; |
139 | 140 | ||
140 | /* Now stuff the nS values into the structure */ | 141 | /* Now stuff the nS values into the structure */ |
141 | acpi->gtm.drive[unit].pio = | 142 | t = ata_timing_find_mode(adev->pio_mode); |
142 | ata_acpi_pio_cycle[adev->pio_mode - XFER_PIO_0]; | 143 | acpi->gtm.drive[unit].pio = t->cycle; |
143 | ata_acpi_stm(ap, &acpi->gtm); | 144 | ata_acpi_stm(ap, &acpi->gtm); |
144 | /* See what mode we actually got */ | 145 | /* See what mode we actually got */ |
145 | ata_acpi_gtm(ap, &acpi->gtm); | 146 | ata_acpi_gtm(ap, &acpi->gtm); |
@@ -155,18 +156,18 @@ static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
155 | { | 156 | { |
156 | int unit = adev->devno; | 157 | int unit = adev->devno; |
157 | struct pata_acpi *acpi = ap->private_data; | 158 | struct pata_acpi *acpi = ap->private_data; |
159 | const struct ata_timing *t; | ||
158 | 160 | ||
159 | if (!(acpi->gtm.flags & 0x10)) | 161 | if (!(acpi->gtm.flags & 0x10)) |
160 | unit = 0; | 162 | unit = 0; |
161 | 163 | ||
162 | /* Now stuff the nS values into the structure */ | 164 | /* Now stuff the nS values into the structure */ |
165 | t = ata_timing_find_mode(adev->dma_mode); | ||
163 | if (adev->dma_mode >= XFER_UDMA_0) { | 166 | if (adev->dma_mode >= XFER_UDMA_0) { |
164 | acpi->gtm.drive[unit].dma = | 167 | acpi->gtm.drive[unit].dma = t->udma; |
165 | ata_acpi_udma_cycle[adev->dma_mode - XFER_UDMA_0]; | ||
166 | acpi->gtm.flags |= (1 << (2 * unit)); | 168 | acpi->gtm.flags |= (1 << (2 * unit)); |
167 | } else { | 169 | } else { |
168 | acpi->gtm.drive[unit].dma = | 170 | acpi->gtm.drive[unit].dma = t->cycle; |
169 | ata_acpi_mwdma_cycle[adev->dma_mode - XFER_MW_DMA_0]; | ||
170 | acpi->gtm.flags &= ~(1 << (2 * unit)); | 171 | acpi->gtm.flags &= ~(1 << (2 * unit)); |
171 | } | 172 | } |
172 | ata_acpi_stm(ap, &acpi->gtm); | 173 | ata_acpi_stm(ap, &acpi->gtm); |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 8022e5b2224d..8ede93b5c7a6 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -941,6 +941,7 @@ extern int ata_timing_compute(struct ata_device *, unsigned short, | |||
941 | extern void ata_timing_merge(const struct ata_timing *, | 941 | extern void ata_timing_merge(const struct ata_timing *, |
942 | const struct ata_timing *, struct ata_timing *, | 942 | const struct ata_timing *, struct ata_timing *, |
943 | unsigned int); | 943 | unsigned int); |
944 | extern u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle); | ||
944 | 945 | ||
945 | enum { | 946 | enum { |
946 | ATA_TIMING_SETUP = (1 << 0), | 947 | ATA_TIMING_SETUP = (1 << 0), |
@@ -961,10 +962,6 @@ enum { | |||
961 | 962 | ||
962 | /* libata-acpi.c */ | 963 | /* libata-acpi.c */ |
963 | #ifdef CONFIG_ATA_ACPI | 964 | #ifdef CONFIG_ATA_ACPI |
964 | extern const unsigned int ata_acpi_pio_cycle[7]; | ||
965 | extern const unsigned int ata_acpi_mwdma_cycle[5]; | ||
966 | extern const unsigned int ata_acpi_udma_cycle[7]; | ||
967 | |||
968 | static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) | 965 | static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) |
969 | { | 966 | { |
970 | if (ap->pflags & ATA_PFLAG_INIT_GTM_VALID) | 967 | if (ap->pflags & ATA_PFLAG_INIT_GTM_VALID) |