diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/scsi/ata_piix.c | 53 |
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 | ||
| 142 | struct piix_map_db { | 142 | struct 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 | ||
| 295 | static const struct piix_map_db ich5_map_db = { | 296 | static 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 | ||
| 310 | static const struct piix_map_db ich6_map_db = { | 312 | static 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 | ||
| 321 | static const struct piix_map_db ich6m_map_db = { | 324 | static 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 | ||
| 758 | static 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 | |||
| 773 | static void __devinit piix_init_sata_map(struct pci_dev *pdev, | 774 | static 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. |
