diff options
Diffstat (limited to 'drivers/ata/ata_piix.c')
-rw-r--r-- | drivers/ata/ata_piix.c | 104 |
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"); | |||
563 | MODULE_DEVICE_TABLE(pci, piix_pci_tbl); | 563 | MODULE_DEVICE_TABLE(pci, piix_pci_tbl); |
564 | MODULE_VERSION(DRV_VERSION); | 564 | MODULE_VERSION(DRV_VERSION); |
565 | 565 | ||
566 | static int force_pcs = 0; | ||
567 | module_param(force_pcs, int, 0444); | ||
568 | MODULE_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 | |||
571 | struct ich_laptop { | 566 | struct 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 | */ | ||
701 | static 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 | */ | ||
744 | static 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 | |||
763 | static void piix_sata_error_handler(struct ata_port *ap) | 683 | static 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 | ||
1094 | static void __devinit piix_init_sata_map(struct pci_dev *pdev, | 1002 | static void __devinit piix_init_sata_map(struct pci_dev *pdev, |