aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ata_piix.c
diff options
context:
space:
mode:
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.