aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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,