aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-acpi.c')
-rw-r--r--drivers/ata/libata-acpi.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 01964b6e6f6b..b0882cddfd4c 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -20,19 +20,9 @@
20 20
21#include <acpi/acpi_bus.h> 21#include <acpi/acpi_bus.h>
22 22
23enum { 23unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT;
24 ATA_ACPI_FILTER_SETXFER = 1 << 0,
25 ATA_ACPI_FILTER_LOCK = 1 << 1,
26 ATA_ACPI_FILTER_DIPM = 1 << 2,
27
28 ATA_ACPI_FILTER_DEFAULT = ATA_ACPI_FILTER_SETXFER |
29 ATA_ACPI_FILTER_LOCK |
30 ATA_ACPI_FILTER_DIPM,
31};
32
33static unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT;
34module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644); 24module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644);
35MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock, 0x4=DIPM)"); 25MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock, 0x4=DIPM, 0x8=FPDMA non-zero offset, 0x10=FPDMA DMA Setup FIS auto-activate)");
36 26
37#define NO_PORT_MULT 0xffff 27#define NO_PORT_MULT 0xffff
38#define SATA_ADR(root, pmp) (((root) << 16) | (pmp)) 28#define SATA_ADR(root, pmp) (((root) << 16) | (pmp))
@@ -613,10 +603,11 @@ static void ata_acpi_gtf_to_tf(struct ata_device *dev,
613 tf->command = gtf->tf[6]; /* 0x1f7 */ 603 tf->command = gtf->tf[6]; /* 0x1f7 */
614} 604}
615 605
616static int ata_acpi_filter_tf(const struct ata_taskfile *tf, 606static int ata_acpi_filter_tf(struct ata_device *dev,
607 const struct ata_taskfile *tf,
617 const struct ata_taskfile *ptf) 608 const struct ata_taskfile *ptf)
618{ 609{
619 if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_SETXFER) { 610 if (dev->gtf_filter & ATA_ACPI_FILTER_SETXFER) {
620 /* libata doesn't use ACPI to configure transfer mode. 611 /* libata doesn't use ACPI to configure transfer mode.
621 * It will only confuse device configuration. Skip. 612 * It will only confuse device configuration. Skip.
622 */ 613 */
@@ -625,7 +616,7 @@ static int ata_acpi_filter_tf(const struct ata_taskfile *tf,
625 return 1; 616 return 1;
626 } 617 }
627 618
628 if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_LOCK) { 619 if (dev->gtf_filter & ATA_ACPI_FILTER_LOCK) {
629 /* BIOS writers, sorry but we don't wanna lock 620 /* BIOS writers, sorry but we don't wanna lock
630 * features unless the user explicitly said so. 621 * features unless the user explicitly said so.
631 */ 622 */
@@ -647,12 +638,23 @@ static int ata_acpi_filter_tf(const struct ata_taskfile *tf,
647 return 1; 638 return 1;
648 } 639 }
649 640
650 if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_DIPM) { 641 if (tf->command == ATA_CMD_SET_FEATURES &&
642 tf->feature == SETFEATURES_SATA_ENABLE) {
651 /* inhibit enabling DIPM */ 643 /* inhibit enabling DIPM */
652 if (tf->command == ATA_CMD_SET_FEATURES && 644 if (dev->gtf_filter & ATA_ACPI_FILTER_DIPM &&
653 tf->feature == SETFEATURES_SATA_ENABLE &&
654 tf->nsect == SATA_DIPM) 645 tf->nsect == SATA_DIPM)
655 return 1; 646 return 1;
647
648 /* inhibit FPDMA non-zero offset */
649 if (dev->gtf_filter & ATA_ACPI_FILTER_FPDMA_OFFSET &&
650 (tf->nsect == SATA_FPDMA_OFFSET ||
651 tf->nsect == SATA_FPDMA_IN_ORDER))
652 return 1;
653
654 /* inhibit FPDMA auto activation */
655 if (dev->gtf_filter & ATA_ACPI_FILTER_FPDMA_AA &&
656 tf->nsect == SATA_FPDMA_AA)
657 return 1;
656 } 658 }
657 659
658 return 0; 660 return 0;
@@ -704,7 +706,7 @@ static int ata_acpi_run_tf(struct ata_device *dev,
704 pptf = &ptf; 706 pptf = &ptf;
705 } 707 }
706 708
707 if (!ata_acpi_filter_tf(&tf, pptf)) { 709 if (!ata_acpi_filter_tf(dev, &tf, pptf)) {
708 rtf = tf; 710 rtf = tf;
709 err_mask = ata_exec_internal(dev, &rtf, NULL, 711 err_mask = ata_exec_internal(dev, &rtf, NULL,
710 DMA_NONE, NULL, 0, 0); 712 DMA_NONE, NULL, 0, 0);