aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ata_piix.c
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-07-11 11:48:50 -0400
committerJeff Garzik <jeff@garzik.org>2006-07-16 11:48:28 -0400
commitea35d29e2fa8b3d766a2ce8fbcce599dce8d2734 (patch)
tree533e0cac2fd8b9ce860ce6260ef5feb9a3f8e817 /drivers/scsi/ata_piix.c
parentd96715c1acb119cef4b2443ba9b3777b730139e6 (diff)
[libata] ata_piix: Consolidate PCS register writing
Prior to this patch, the driver would do this for each port: read 8-bit PCS write 8-bit PCS read 8-bit PCS write 8-bit PCS In the field, flaky behavior has been observed related to this register. In particular, these overzealous register writes can cause misdetection problems. Update to do the following once (not once per port) at boot: read 16-bit PCS if needs changing, write 16-bit PCS And thereafter, we only perform a 'read 16-bit PCS' per port. This should eliminate all PCS writes in many cases, and be more friendly in the cases where we do need to enable ports. Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/scsi/ata_piix.c')
-rw-r--r--drivers/scsi/ata_piix.c53
1 files changed, 28 insertions, 25 deletions
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index bf41dd3a35d2..18b3542236d2 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -141,6 +141,7 @@ enum {
141 141
142struct piix_map_db { 142struct piix_map_db {
143 const u32 mask; 143 const u32 mask;
144 const u32 port_enable;
144 const int map[][4]; 145 const int map[][4];
145}; 146};
146 147
@@ -294,6 +295,7 @@ static const struct ata_port_operations piix_sata_ops = {
294 295
295static const struct piix_map_db ich5_map_db = { 296static const struct piix_map_db ich5_map_db = {
296 .mask = 0x7, 297 .mask = 0x7,
298 .port_enable = 0x3,
297 .map = { 299 .map = {
298 /* PM PS SM SS MAP */ 300 /* PM PS SM SS MAP */
299 { P0, NA, P1, NA }, /* 000b */ 301 { P0, NA, P1, NA }, /* 000b */
@@ -309,6 +311,7 @@ static const struct piix_map_db ich5_map_db = {
309 311
310static const struct piix_map_db ich6_map_db = { 312static const struct piix_map_db ich6_map_db = {
311 .mask = 0x3, 313 .mask = 0x3,
314 .port_enable = 0xf,
312 .map = { 315 .map = {
313 /* PM PS SM SS MAP */ 316 /* PM PS SM SS MAP */
314 { P0, P2, P1, P3 }, /* 00b */ 317 { P0, P2, P1, P3 }, /* 00b */
@@ -320,6 +323,7 @@ static const struct piix_map_db ich6_map_db = {
320 323
321static const struct piix_map_db ich6m_map_db = { 324static const struct piix_map_db ich6m_map_db = {
322 .mask = 0x3, 325 .mask = 0x3,
326 .port_enable = 0x5,
323 .map = { 327 .map = {
324 /* PM PS SM SS MAP */ 328 /* PM PS SM SS MAP */
325 { P0, P2, RV, RV }, /* 00b */ 329 { P0, P2, RV, RV }, /* 00b */
@@ -519,44 +523,25 @@ static int piix_sata_prereset(struct ata_port *ap)
519 struct piix_host_priv *hpriv = ap->host_set->private_data; 523 struct piix_host_priv *hpriv = ap->host_set->private_data;
520 const unsigned int *map = hpriv->map; 524 const unsigned int *map = hpriv->map;
521 int base = 2 * ap->hard_port_no; 525 int base = 2 * ap->hard_port_no;
522 unsigned int present_mask = 0; 526 unsigned int present = 0;
523 int port, i; 527 int port, i;
524 u8 pcs; 528 u16 pcs;
525 529
526 pci_read_config_byte(pdev, ICH5_PCS, &pcs); 530 pci_read_config_word(pdev, ICH5_PCS, &pcs);
527 DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base); 531 DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base);
528 532
529 /* enable all ports on this ap and wait for them to settle */
530 for (i = 0; i < 2; i++) {
531 port = map[base + i];
532 if (port >= 0)
533 pcs |= 1 << port;
534 }
535
536 pci_write_config_byte(pdev, ICH5_PCS, pcs);
537 msleep(100);
538
539 /* let's see which devices are present */
540 pci_read_config_byte(pdev, ICH5_PCS, &pcs);
541
542 for (i = 0; i < 2; i++) { 533 for (i = 0; i < 2; i++) {
543 port = map[base + i]; 534 port = map[base + i];
544 if (port < 0) 535 if (port < 0)
545 continue; 536 continue;
546 if (ap->flags & PIIX_FLAG_IGNORE_PCS || pcs & 1 << (4 + port)) 537 if (ap->flags & PIIX_FLAG_IGNORE_PCS || pcs & 1 << (4 + port))
547 present_mask |= 1 << i; 538 present = 1;
548 else
549 pcs &= ~(1 << port);
550 } 539 }
551 540
552 /* disable offline ports on non-AHCI controllers */
553 if (!(ap->flags & PIIX_FLAG_AHCI))
554 pci_write_config_byte(pdev, ICH5_PCS, pcs);
555
556 DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n", 541 DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
557 ap->id, pcs, present_mask); 542 ap->id, pcs, present_mask);
558 543
559 if (!present_mask) { 544 if (!present) {
560 ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n"); 545 ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n");
561 ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; 546 ap->eh_context.i.action &= ~ATA_EH_RESET_MASK;
562 return 0; 547 return 0;
@@ -770,6 +755,22 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
770 return no_piix_dma; 755 return no_piix_dma;
771} 756}
772 757
758static void __devinit piix_init_pcs(struct pci_dev *pdev,
759 const struct piix_map_db *map_db)
760{
761 u16 pcs, new_pcs;
762
763 pci_read_config_word(pdev, ICH5_PCS, &pcs);
764
765 new_pcs = pcs | map_db->port_enable;
766
767 if (new_pcs != pcs) {
768 DPRINTK("updating PCS from 0x%x to 0x%x\n", pcs, new_pcs);
769 pci_write_config_word(pdev, ICH5_PCS, new_pcs);
770 msleep(150);
771 }
772}
773
773static void __devinit piix_init_sata_map(struct pci_dev *pdev, 774static void __devinit piix_init_sata_map(struct pci_dev *pdev,
774 struct ata_port_info *pinfo, 775 struct ata_port_info *pinfo,
775 const struct piix_map_db *map_db) 776 const struct piix_map_db *map_db)
@@ -871,9 +872,11 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
871 } 872 }
872 873
873 /* Initialize SATA map */ 874 /* Initialize SATA map */
874 if (host_flags & ATA_FLAG_SATA) 875 if (host_flags & ATA_FLAG_SATA) {
875 piix_init_sata_map(pdev, port_info, 876 piix_init_sata_map(pdev, port_info,
876 piix_map_db_table[ent->driver_data]); 877 piix_map_db_table[ent->driver_data]);
878 piix_init_pcs(pdev, piix_map_db_table[ent->driver_data]);
879 }
877 880
878 /* On ICH5, some BIOSen disable the interrupt using the 881 /* On ICH5, some BIOSen disable the interrupt using the
879 * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3. 882 * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.