libata-acpi: implement _GTF command filtering

Implement _GTF command filtering which can be controlled by
libata.acpi_filter kernel parameter. Currently SETXFER and LOCK
commands are filtered.

libata configures transfer mode by itself and _GTF SETXFER commands
can potentially disrupt device configuration. _GTM/_STM mechanism
can't handle hotplugging too well and when _GTF is executed,
controller is in PIO0 rather than the mode _STM configured.

Note that detecting SET MAX LOCK requires looking at the previous
command. This adds a bit to code complexity.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by Tejun Heo and committed by Jeff Garzik 3264a8d8 0e8634bf

+111 -40
+111 -40
drivers/ata/libata-acpi.c
··· 6 6 * Copyright (C) 2006 Randy Dunlap 7 7 */ 8 8 9 + #include <linux/module.h> 9 10 #include <linux/ata.h> 10 11 #include <linux/delay.h> 11 12 #include <linux/device.h> ··· 25 24 #include <acpi/acexcep.h> 26 25 #include <acpi/acmacros.h> 27 26 #include <acpi/actypes.h> 27 + 28 + enum { 29 + ATA_ACPI_FILTER_SETXFER = 1 << 0, 30 + ATA_ACPI_FILTER_LOCK = 1 << 1, 31 + 32 + ATA_ACPI_FILTER_DEFAULT = ATA_ACPI_FILTER_SETXFER | 33 + ATA_ACPI_FILTER_LOCK, 34 + }; 35 + 36 + static unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT; 37 + module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644); 38 + MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock)"); 28 39 29 40 #define NO_PORT_MULT 0xffff 30 41 #define SATA_ADR(root, pmp) (((root) << 16) | (pmp)) ··· 478 465 479 466 EXPORT_SYMBOL_GPL(ata_acpi_cbl_80wire); 480 467 468 + static void ata_acpi_gtf_to_tf(struct ata_device *dev, 469 + const struct ata_acpi_gtf *gtf, 470 + struct ata_taskfile *tf) 471 + { 472 + ata_tf_init(dev, tf); 473 + 474 + tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; 475 + tf->protocol = ATA_PROT_NODATA; 476 + tf->feature = gtf->tf[0]; /* 0x1f1 */ 477 + tf->nsect = gtf->tf[1]; /* 0x1f2 */ 478 + tf->lbal = gtf->tf[2]; /* 0x1f3 */ 479 + tf->lbam = gtf->tf[3]; /* 0x1f4 */ 480 + tf->lbah = gtf->tf[4]; /* 0x1f5 */ 481 + tf->device = gtf->tf[5]; /* 0x1f6 */ 482 + tf->command = gtf->tf[6]; /* 0x1f7 */ 483 + } 484 + 485 + static int ata_acpi_filter_tf(const struct ata_taskfile *tf, 486 + const struct ata_taskfile *ptf) 487 + { 488 + if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_SETXFER) { 489 + /* libata doesn't use ACPI to configure transfer mode. 490 + * It will only confuse device configuration. Skip. 491 + */ 492 + if (tf->command == ATA_CMD_SET_FEATURES && 493 + tf->feature == SETFEATURES_XFER) 494 + return 1; 495 + } 496 + 497 + if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_LOCK) { 498 + /* BIOS writers, sorry but we don't wanna lock 499 + * features unless the user explicitly said so. 500 + */ 501 + 502 + /* DEVICE CONFIGURATION FREEZE LOCK */ 503 + if (tf->command == ATA_CMD_CONF_OVERLAY && 504 + tf->feature == ATA_DCO_FREEZE_LOCK) 505 + return 1; 506 + 507 + /* SECURITY FREEZE LOCK */ 508 + if (tf->command == ATA_CMD_SEC_FREEZE_LOCK) 509 + return 1; 510 + 511 + /* SET MAX LOCK and SET MAX FREEZE LOCK */ 512 + if ((!ptf || ptf->command != ATA_CMD_READ_NATIVE_MAX) && 513 + tf->command == ATA_CMD_SET_MAX && 514 + (tf->feature == ATA_SET_MAX_LOCK || 515 + tf->feature == ATA_SET_MAX_FREEZE_LOCK)) 516 + return 1; 517 + } 518 + 519 + return 0; 520 + } 521 + 481 522 /** 482 523 * ata_acpi_run_tf - send taskfile registers to host controller 483 524 * @dev: target ATA device ··· 552 485 * EH context. 553 486 * 554 487 * RETURNS: 555 - * 1 if command is executed successfully. 0 if ignored or rejected, 556 - * -errno on other errors. 488 + * 1 if command is executed successfully. 0 if ignored, rejected or 489 + * filtered out, -errno on other errors. 557 490 */ 558 491 static int ata_acpi_run_tf(struct ata_device *dev, 559 - const struct ata_acpi_gtf *gtf) 492 + const struct ata_acpi_gtf *gtf, 493 + const struct ata_acpi_gtf *prev_gtf) 560 494 { 561 - struct ata_taskfile tf, rtf; 495 + struct ata_taskfile *pptf = NULL; 496 + struct ata_taskfile tf, ptf, rtf; 562 497 unsigned int err_mask; 563 498 const char *level; 564 499 char msg[60]; ··· 571 502 && (gtf->tf[6] == 0)) 572 503 return 0; 573 504 574 - ata_tf_init(dev, &tf); 505 + ata_acpi_gtf_to_tf(dev, gtf, &tf); 506 + if (prev_gtf) { 507 + ata_acpi_gtf_to_tf(dev, prev_gtf, &ptf); 508 + pptf = &ptf; 509 + } 575 510 576 - /* convert gtf to tf */ 577 - tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; /* TBD */ 578 - tf.protocol = ATA_PROT_NODATA; 579 - tf.feature = gtf->tf[0]; /* 0x1f1 */ 580 - tf.nsect = gtf->tf[1]; /* 0x1f2 */ 581 - tf.lbal = gtf->tf[2]; /* 0x1f3 */ 582 - tf.lbam = gtf->tf[3]; /* 0x1f4 */ 583 - tf.lbah = gtf->tf[4]; /* 0x1f5 */ 584 - tf.device = gtf->tf[5]; /* 0x1f6 */ 585 - tf.command = gtf->tf[6]; /* 0x1f7 */ 511 + if (!ata_acpi_filter_tf(&tf, pptf)) { 512 + rtf = tf; 513 + err_mask = ata_exec_internal(dev, &rtf, NULL, 514 + DMA_NONE, NULL, 0, 0); 586 515 587 - rtf = tf; 588 - err_mask = ata_exec_internal(dev, &rtf, NULL, DMA_NONE, NULL, 0, 0); 516 + switch (err_mask) { 517 + case 0: 518 + level = KERN_DEBUG; 519 + snprintf(msg, sizeof(msg), "succeeded"); 520 + rc = 1; 521 + break; 589 522 590 - switch (err_mask) { 591 - case 0: 592 - level = KERN_DEBUG; 593 - snprintf(msg, sizeof(msg), "succeeded"); 594 - rc = 1; 595 - break; 523 + case AC_ERR_DEV: 524 + level = KERN_INFO; 525 + snprintf(msg, sizeof(msg), 526 + "rejected by device (Stat=0x%02x Err=0x%02x)", 527 + rtf.command, rtf.feature); 528 + rc = 0; 529 + break; 596 530 597 - case AC_ERR_DEV: 531 + default: 532 + level = KERN_ERR; 533 + snprintf(msg, sizeof(msg), 534 + "failed (Emask=0x%x Stat=0x%02x Err=0x%02x)", 535 + err_mask, rtf.command, rtf.feature); 536 + rc = -EIO; 537 + break; 538 + } 539 + } else { 598 540 level = KERN_INFO; 599 - snprintf(msg, sizeof(msg), 600 - "rejected by device (Stat=0x%02x Err=0x%02x)", 601 - rtf.command, rtf.feature); 541 + snprintf(msg, sizeof(msg), "filtered out"); 602 542 rc = 0; 603 - break; 604 - 605 - default: 606 - level = KERN_ERR; 607 - snprintf(msg, sizeof(msg), 608 - "failed (Emask=0x%x Stat=0x%02x Err=0x%02x)", 609 - err_mask, rtf.command, rtf.feature); 610 - rc = -EIO; 611 - break; 612 543 } 613 544 614 545 ata_dev_printk(dev, level, ··· 635 566 */ 636 567 static int ata_acpi_exec_tfs(struct ata_device *dev, int *nr_executed) 637 568 { 638 - struct ata_acpi_gtf *gtf = NULL; 569 + struct ata_acpi_gtf *gtf = NULL, *pgtf = NULL; 639 570 int gtf_count, i, rc; 640 571 641 572 /* get taskfiles */ ··· 645 576 gtf_count = rc; 646 577 647 578 /* execute them */ 648 - for (i = 0; i < gtf_count; i++) { 649 - rc = ata_acpi_run_tf(dev, gtf++); 579 + for (i = 0; i < gtf_count; i++, gtf++) { 580 + rc = ata_acpi_run_tf(dev, gtf, pgtf); 650 581 if (rc < 0) 651 582 break; 652 - if (rc) 583 + if (rc) { 653 584 (*nr_executed)++; 585 + pgtf = gtf; 586 + } 654 587 } 655 588 656 589 ata_acpi_clear_gtf(dev);