diff options
author | Tejun Heo <htejun@gmail.com> | 2007-12-18 02:33:04 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-23 05:24:12 -0500 |
commit | 5df91a25df08d85700fef5fd59bb1873273e5ef5 (patch) | |
tree | e413ff0798da2792683db0805128f43798dcfc8d /drivers/ata | |
parent | 7c77fa4d51b1480bcec2e898c94d6912fe063c16 (diff) |
libata: fix ata_acpi_gtm_xfermask()
ata_acpi_gtm_xfermask() as separated out from pacpi_discover_modes()
has various bugs. Fix them.
* The wrong comparison operator is used when finding for matching
cycle resulting totally bogus result.
* With the comparion operator fixed, boundary condtion handling is
clumsy.
* Setting of any DMA mask bit set all bits in PIO mask.
* MWDMA and UDMA blocks are swapped.
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')
-rw-r--r-- | drivers/ata/libata-acpi.c | 42 |
1 files changed, 21 insertions, 21 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index d6697baf243d..9f0b208afcf5 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -473,49 +473,49 @@ EXPORT_SYMBOL_GPL(ata_acpi_udma_cycle); | |||
473 | unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev, | 473 | unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev, |
474 | const struct ata_acpi_gtm *gtm) | 474 | const struct ata_acpi_gtm *gtm) |
475 | { | 475 | { |
476 | unsigned long pio_mask = 0, mwdma_mask = 0, udma_mask = 0; | ||
476 | int unit, i; | 477 | int unit, i; |
477 | u32 t; | 478 | u32 t; |
478 | unsigned long mask = (0x7f << ATA_SHIFT_UDMA) | (0x7 << ATA_SHIFT_MWDMA) | (0x1F << ATA_SHIFT_PIO); | ||
479 | 479 | ||
480 | /* we always use the 0 slot for crap hardware */ | 480 | /* we always use the 0 slot for crap hardware */ |
481 | unit = dev->devno; | 481 | unit = dev->devno; |
482 | if (!(gtm->flags & 0x10)) | 482 | if (!(gtm->flags & 0x10)) |
483 | unit = 0; | 483 | unit = 0; |
484 | 484 | ||
485 | /* Values larger than the longest cycle results in 0 mask | ||
486 | * while values equal to smaller than the shortest cycle | ||
487 | * results in mask which includes all supported modes. | ||
488 | * Disabled transfer method has the value of 0xffffffff which | ||
489 | * will always result in 0 mask. | ||
490 | */ | ||
491 | |||
485 | /* start by scanning for PIO modes */ | 492 | /* start by scanning for PIO modes */ |
486 | for (i = 0; i < 7; i++) { | 493 | t = gtm->drive[unit].pio; |
487 | t = gtm->drive[unit].pio; | 494 | for (i = 0; i < ARRAY_SIZE(ata_acpi_pio_cycle); i++) |
488 | if (t <= ata_acpi_pio_cycle[i]) { | 495 | if (t > ata_acpi_pio_cycle[i]) |
489 | mask |= (2 << (ATA_SHIFT_PIO + i)) - 1; | ||
490 | break; | 496 | break; |
491 | } | 497 | pio_mask = (1 << i) - 1; |
492 | } | ||
493 | 498 | ||
494 | /* See if we have MWDMA or UDMA data. We don't bother with | 499 | /* See if we have MWDMA or UDMA data. We don't bother with |
495 | * MWDMA if UDMA is available as this means the BIOS set UDMA | 500 | * MWDMA if UDMA is available as this means the BIOS set UDMA |
496 | * and our error changedown if it works is UDMA to PIO anyway. | 501 | * and our error changedown if it works is UDMA to PIO anyway. |
497 | */ | 502 | */ |
498 | if (gtm->flags & (1 << (2 * unit))) { | 503 | t = gtm->drive[unit].dma; |
504 | if (!(gtm->flags & (1 << (2 * unit)))) { | ||
499 | /* MWDMA */ | 505 | /* MWDMA */ |
500 | for (i = 0; i < 5; i++) { | 506 | for (i = 0; i < ARRAY_SIZE(ata_acpi_mwdma_cycle); i++) |
501 | t = gtm->drive[unit].dma; | 507 | if (t > ata_acpi_mwdma_cycle[i]) |
502 | if (t <= ata_acpi_mwdma_cycle[i]) { | ||
503 | mask |= (2 << (ATA_SHIFT_MWDMA + i)) - 1; | ||
504 | break; | 508 | break; |
505 | } | 509 | mwdma_mask = (1 << i) - 1; |
506 | } | ||
507 | } else { | 510 | } else { |
508 | /* UDMA */ | 511 | /* UDMA */ |
509 | for (i = 0; i < 7; i++) { | 512 | for (i = 0; i < ARRAY_SIZE(ata_acpi_udma_cycle); i++) |
510 | t = gtm->drive[unit].dma; | 513 | if (t > ata_acpi_udma_cycle[i]) |
511 | if (t <= ata_acpi_udma_cycle[i]) { | ||
512 | mask |= (2 << (ATA_SHIFT_UDMA + i)) - 1; | ||
513 | break; | 514 | break; |
514 | } | 515 | udma_mask = (1 << i) - 1; |
515 | } | ||
516 | } | 516 | } |
517 | 517 | ||
518 | return mask; | 518 | return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask); |
519 | } | 519 | } |
520 | EXPORT_SYMBOL_GPL(ata_acpi_gtm_xfermask); | 520 | EXPORT_SYMBOL_GPL(ata_acpi_gtm_xfermask); |
521 | 521 | ||