struct piix_map_db {
        const u32 mask;
+       const u32 port_enable;
        const int map[][4];
 };
 
 
 static const struct piix_map_db ich5_map_db = {
        .mask = 0x7,
+       .port_enable = 0x3,
        .map = {
                /* PM   PS   SM   SS       MAP  */
                {  P0,  NA,  P1,  NA }, /* 000b */
 
 static const struct piix_map_db ich6_map_db = {
        .mask = 0x3,
+       .port_enable = 0xf,
        .map = {
                /* PM   PS   SM   SS       MAP */
                {  P0,  P2,  P1,  P3 }, /* 00b */
 
 static const struct piix_map_db ich6m_map_db = {
        .mask = 0x3,
+       .port_enable = 0x5,
        .map = {
                /* PM   PS   SM   SS       MAP */
                {  P0,  P2,  RV,  RV }, /* 00b */
        struct piix_host_priv *hpriv = ap->host_set->private_data;
        const unsigned int *map = hpriv->map;
        int base = 2 * ap->hard_port_no;
-       unsigned int present_mask = 0;
+       unsigned int present = 0;
        int port, i;
-       u8 pcs;
+       u16 pcs;
 
-       pci_read_config_byte(pdev, ICH5_PCS, &pcs);
+       pci_read_config_word(pdev, ICH5_PCS, &pcs);
        DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base);
 
-       /* enable all ports on this ap and wait for them to settle */
-       for (i = 0; i < 2; i++) {
-               port = map[base + i];
-               if (port >= 0)
-                       pcs |= 1 << port;
-       }
-
-       pci_write_config_byte(pdev, ICH5_PCS, pcs);
-       msleep(100);
-
-       /* let's see which devices are present */
-       pci_read_config_byte(pdev, ICH5_PCS, &pcs);
-
        for (i = 0; i < 2; i++) {
                port = map[base + i];
                if (port < 0)
                        continue;
                if (ap->flags & PIIX_FLAG_IGNORE_PCS || pcs & 1 << (4 + port))
-                       present_mask |= 1 << i;
-               else
-                       pcs &= ~(1 << port);
+                       present = 1;
        }
 
-       /* disable offline ports on non-AHCI controllers */
-       if (!(ap->flags & PIIX_FLAG_AHCI))
-               pci_write_config_byte(pdev, ICH5_PCS, pcs);
-
        DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
                ap->id, pcs, present_mask);
 
-       if (!present_mask) {
+       if (!present) {
                ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n");
                ap->eh_context.i.action &= ~ATA_EH_RESET_MASK;
                return 0;
        return no_piix_dma;
 }
 
+static void __devinit piix_init_pcs(struct pci_dev *pdev,
+                                   const struct piix_map_db *map_db)
+{
+       u16 pcs, new_pcs;
+
+       pci_read_config_word(pdev, ICH5_PCS, &pcs);
+
+       new_pcs = pcs | map_db->port_enable;
+
+       if (new_pcs != pcs) {
+               DPRINTK("updating PCS from 0x%x to 0x%x\n", pcs, new_pcs);
+               pci_write_config_word(pdev, ICH5_PCS, new_pcs);
+               msleep(150);
+       }
+}
+
 static void __devinit piix_init_sata_map(struct pci_dev *pdev,
                                         struct ata_port_info *pinfo,
                                         const struct piix_map_db *map_db)
        }
 
        /* Initialize SATA map */
-       if (host_flags & ATA_FLAG_SATA)
+       if (host_flags & ATA_FLAG_SATA) {
                piix_init_sata_map(pdev, port_info,
                                   piix_map_db_table[ent->driver_data]);
+               piix_init_pcs(pdev, piix_map_db_table[ent->driver_data]);
+       }
 
        /* On ICH5, some BIOSen disable the interrupt using the
         * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.