aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-11-10 04:08:10 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-01 22:45:55 -0500
commit228c1590be39872022006ab81fda112a4f35ce47 (patch)
tree1a4f1e55feb1eb957819145db702f6789a94b5d5
parent55a8e2c83ce50548dfef74bb19dfe2b809cb3099 (diff)
[PATCH] ata_piix: apply device detection via polling IDENTIFY
PATA PIIX uses reset signature + TF r/w test for device presence detection, which doesn't always work. It sometimes reports phantom device which results in IDENTIFY timeouts. SATA PIIX uses some combination of PCS + reset signature + TF r/w test for device presence detection. No combination satifies all and for some controllers, there doesn't seem to be any combination which works reliably. This patch makes both PATA and SATA piix's use reset signature + TF r/w + polling IDENTIFY for device detection. This is what the old libata (before irq-pio and new EH) did and what IDE does. This patch also removes now obsolete PIIX_FLAG_IGNORE_PCS, force_pcs and related code. Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/ata_piix.c104
1 files changed, 6 insertions, 98 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 90ac33a7bdc7..7bf238638e8e 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -101,13 +101,13 @@ enum {
101 ICH5_PCS = 0x92, /* port control and status */ 101 ICH5_PCS = 0x92, /* port control and status */
102 PIIX_SCC = 0x0A, /* sub-class code register */ 102 PIIX_SCC = 0x0A, /* sub-class code register */
103 103
104 PIIX_FLAG_IGNORE_PCS = (1 << 25), /* ignore PCS present bits */
105 PIIX_FLAG_SCR = (1 << 26), /* SCR available */ 104 PIIX_FLAG_SCR = (1 << 26), /* SCR available */
106 PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */ 105 PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */
107 PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */ 106 PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */
108 107
109 PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS, 108 PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS | ATA_FLAG_DETECT_POLLING,
110 PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, 109 PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR |
110 ATA_FLAG_DETECT_POLLING,
111 111
112 /* combined mode. if set, PATA is channel 0. 112 /* combined mode. if set, PATA is channel 0.
113 * if clear, PATA is channel 1. 113 * if clear, PATA is channel 1.
@@ -490,7 +490,7 @@ static struct ata_port_info piix_port_info[] = {
490 /* ich5_sata: 5 */ 490 /* ich5_sata: 5 */
491 { 491 {
492 .sht = &piix_sht, 492 .sht = &piix_sht,
493 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_IGNORE_PCS, 493 .flags = PIIX_SATA_FLAGS,
494 .pio_mask = 0x1f, /* pio0-4 */ 494 .pio_mask = 0x1f, /* pio0-4 */
495 .mwdma_mask = 0x07, /* mwdma0-2 */ 495 .mwdma_mask = 0x07, /* mwdma0-2 */
496 .udma_mask = 0x7f, /* udma0-6 */ 496 .udma_mask = 0x7f, /* udma0-6 */
@@ -500,7 +500,7 @@ static struct ata_port_info piix_port_info[] = {
500 /* i6300esb_sata: 6 */ 500 /* i6300esb_sata: 6 */
501 { 501 {
502 .sht = &piix_sht, 502 .sht = &piix_sht,
503 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_IGNORE_PCS, 503 .flags = PIIX_SATA_FLAGS,
504 .pio_mask = 0x1f, /* pio0-4 */ 504 .pio_mask = 0x1f, /* pio0-4 */
505 .mwdma_mask = 0x07, /* mwdma0-2 */ 505 .mwdma_mask = 0x07, /* mwdma0-2 */
506 .udma_mask = 0x7f, /* udma0-6 */ 506 .udma_mask = 0x7f, /* udma0-6 */
@@ -563,11 +563,6 @@ MODULE_LICENSE("GPL");
563MODULE_DEVICE_TABLE(pci, piix_pci_tbl); 563MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
564MODULE_VERSION(DRV_VERSION); 564MODULE_VERSION(DRV_VERSION);
565 565
566static int force_pcs = 0;
567module_param(force_pcs, int, 0444);
568MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around "
569 "device mis-detection (0=default, 1=ignore PCS, 2=honor PCS)");
570
571struct ich_laptop { 566struct ich_laptop {
572 u16 device; 567 u16 device;
573 u16 subvendor; 568 u16 subvendor;
@@ -685,84 +680,9 @@ static void ich_pata_error_handler(struct ata_port *ap)
685 ata_std_postreset); 680 ata_std_postreset);
686} 681}
687 682
688/**
689 * piix_sata_present_mask - determine present mask for SATA host controller
690 * @ap: Target port
691 *
692 * Reads SATA PCI device's PCI config register Port Configuration
693 * and Status (PCS) to determine port and device availability.
694 *
695 * LOCKING:
696 * None (inherited from caller).
697 *
698 * RETURNS:
699 * determined present_mask
700 */
701static unsigned int piix_sata_present_mask(struct ata_port *ap)
702{
703 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
704 struct piix_host_priv *hpriv = ap->host->private_data;
705 const unsigned int *map = hpriv->map;
706 int base = 2 * ap->port_no;
707 unsigned int present_mask = 0;
708 int port, i;
709 u16 pcs;
710
711 pci_read_config_word(pdev, ICH5_PCS, &pcs);
712 DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base);
713
714 for (i = 0; i < 2; i++) {
715 port = map[base + i];
716 if (port < 0)
717 continue;
718 if ((ap->flags & PIIX_FLAG_IGNORE_PCS) ||
719 (pcs & 1 << (hpriv->map_db->present_shift + port)))
720 present_mask |= 1 << i;
721 }
722
723 DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
724 ap->id, pcs, present_mask);
725
726 return present_mask;
727}
728
729/**
730 * piix_sata_softreset - reset SATA host port via ATA SRST
731 * @ap: port to reset
732 * @classes: resulting classes of attached devices
733 *
734 * Reset SATA host port via ATA SRST. On controllers with
735 * reliable PCS present bits, the bits are used to determine
736 * device presence.
737 *
738 * LOCKING:
739 * Kernel thread context (may sleep)
740 *
741 * RETURNS:
742 * 0 on success, -errno otherwise.
743 */
744static int piix_sata_softreset(struct ata_port *ap, unsigned int *classes)
745{
746 unsigned int present_mask;
747 int i, rc;
748
749 present_mask = piix_sata_present_mask(ap);
750
751 rc = ata_std_softreset(ap, classes);
752 if (rc)
753 return rc;
754
755 for (i = 0; i < ATA_MAX_DEVICES; i++) {
756 if (!(present_mask & (1 << i)))
757 classes[i] = ATA_DEV_NONE;
758 }
759
760 return 0;
761}
762
763static void piix_sata_error_handler(struct ata_port *ap) 683static void piix_sata_error_handler(struct ata_port *ap)
764{ 684{
765 ata_bmdma_drive_eh(ap, ata_std_prereset, piix_sata_softreset, NULL, 685 ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
766 ata_std_postreset); 686 ata_std_postreset);
767} 687}
768 688
@@ -1077,18 +997,6 @@ static void __devinit piix_init_pcs(struct pci_dev *pdev,
1077 pci_write_config_word(pdev, ICH5_PCS, new_pcs); 997 pci_write_config_word(pdev, ICH5_PCS, new_pcs);
1078 msleep(150); 998 msleep(150);
1079 } 999 }
1080
1081 if (force_pcs == 1) {
1082 dev_printk(KERN_INFO, &pdev->dev,
1083 "force ignoring PCS (0x%x)\n", new_pcs);
1084 pinfo[0].flags |= PIIX_FLAG_IGNORE_PCS;
1085 pinfo[1].flags |= PIIX_FLAG_IGNORE_PCS;
1086 } else if (force_pcs == 2) {
1087 dev_printk(KERN_INFO, &pdev->dev,
1088 "force honoring PCS (0x%x)\n", new_pcs);
1089 pinfo[0].flags &= ~PIIX_FLAG_IGNORE_PCS;
1090 pinfo[1].flags &= ~PIIX_FLAG_IGNORE_PCS;
1091 }
1092} 1000}
1093 1001
1094static void __devinit piix_init_sata_map(struct pci_dev *pdev, 1002static void __devinit piix_init_sata_map(struct pci_dev *pdev,