diff options
Diffstat (limited to 'drivers/ata/libahci.c')
-rw-r--r-- | drivers/ata/libahci.c | 246 |
1 files changed, 107 insertions, 139 deletions
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 8eea309ea212..41223c7f0206 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -56,9 +56,8 @@ MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip) | |||
56 | module_param_named(ignore_sss, ahci_ignore_sss, int, 0444); | 56 | module_param_named(ignore_sss, ahci_ignore_sss, int, 0444); |
57 | MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)"); | 57 | MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)"); |
58 | 58 | ||
59 | static int ahci_enable_alpm(struct ata_port *ap, | 59 | static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, |
60 | enum link_pm policy); | 60 | unsigned hints); |
61 | static void ahci_disable_alpm(struct ata_port *ap); | ||
62 | static ssize_t ahci_led_show(struct ata_port *ap, char *buf); | 61 | static ssize_t ahci_led_show(struct ata_port *ap, char *buf); |
63 | static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, | 62 | static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, |
64 | size_t size); | 63 | size_t size); |
@@ -88,10 +87,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class, | |||
88 | static void ahci_postreset(struct ata_link *link, unsigned int *class); | 87 | static void ahci_postreset(struct ata_link *link, unsigned int *class); |
89 | static void ahci_error_handler(struct ata_port *ap); | 88 | static void ahci_error_handler(struct ata_port *ap); |
90 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); | 89 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); |
91 | static int ahci_port_resume(struct ata_port *ap); | ||
92 | static void ahci_dev_config(struct ata_device *dev); | 90 | static void ahci_dev_config(struct ata_device *dev); |
93 | static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, | ||
94 | u32 opts); | ||
95 | #ifdef CONFIG_PM | 91 | #ifdef CONFIG_PM |
96 | static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); | 92 | static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); |
97 | #endif | 93 | #endif |
@@ -113,6 +109,8 @@ static ssize_t ahci_read_em_buffer(struct device *dev, | |||
113 | static ssize_t ahci_store_em_buffer(struct device *dev, | 109 | static ssize_t ahci_store_em_buffer(struct device *dev, |
114 | struct device_attribute *attr, | 110 | struct device_attribute *attr, |
115 | const char *buf, size_t size); | 111 | const char *buf, size_t size); |
112 | static ssize_t ahci_show_em_supported(struct device *dev, | ||
113 | struct device_attribute *attr, char *buf); | ||
116 | 114 | ||
117 | static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); | 115 | static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); |
118 | static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); | 116 | static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); |
@@ -120,6 +118,7 @@ static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); | |||
120 | static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); | 118 | static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); |
121 | static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, | 119 | static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, |
122 | ahci_read_em_buffer, ahci_store_em_buffer); | 120 | ahci_read_em_buffer, ahci_store_em_buffer); |
121 | static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL); | ||
123 | 122 | ||
124 | struct device_attribute *ahci_shost_attrs[] = { | 123 | struct device_attribute *ahci_shost_attrs[] = { |
125 | &dev_attr_link_power_management_policy, | 124 | &dev_attr_link_power_management_policy, |
@@ -130,6 +129,7 @@ struct device_attribute *ahci_shost_attrs[] = { | |||
130 | &dev_attr_ahci_host_version, | 129 | &dev_attr_ahci_host_version, |
131 | &dev_attr_ahci_port_cmd, | 130 | &dev_attr_ahci_port_cmd, |
132 | &dev_attr_em_buffer, | 131 | &dev_attr_em_buffer, |
132 | &dev_attr_em_message_supported, | ||
133 | NULL | 133 | NULL |
134 | }; | 134 | }; |
135 | EXPORT_SYMBOL_GPL(ahci_shost_attrs); | 135 | EXPORT_SYMBOL_GPL(ahci_shost_attrs); |
@@ -164,8 +164,7 @@ struct ata_port_operations ahci_ops = { | |||
164 | .pmp_attach = ahci_pmp_attach, | 164 | .pmp_attach = ahci_pmp_attach, |
165 | .pmp_detach = ahci_pmp_detach, | 165 | .pmp_detach = ahci_pmp_detach, |
166 | 166 | ||
167 | .enable_pm = ahci_enable_alpm, | 167 | .set_lpm = ahci_set_lpm, |
168 | .disable_pm = ahci_disable_alpm, | ||
169 | .em_show = ahci_led_show, | 168 | .em_show = ahci_led_show, |
170 | .em_store = ahci_led_store, | 169 | .em_store = ahci_led_store, |
171 | .sw_activity_show = ahci_activity_show, | 170 | .sw_activity_show = ahci_activity_show, |
@@ -348,6 +347,24 @@ static ssize_t ahci_store_em_buffer(struct device *dev, | |||
348 | return size; | 347 | return size; |
349 | } | 348 | } |
350 | 349 | ||
350 | static ssize_t ahci_show_em_supported(struct device *dev, | ||
351 | struct device_attribute *attr, char *buf) | ||
352 | { | ||
353 | struct Scsi_Host *shost = class_to_shost(dev); | ||
354 | struct ata_port *ap = ata_shost_to_port(shost); | ||
355 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
356 | void __iomem *mmio = hpriv->mmio; | ||
357 | u32 em_ctl; | ||
358 | |||
359 | em_ctl = readl(mmio + HOST_EM_CTL); | ||
360 | |||
361 | return sprintf(buf, "%s%s%s%s\n", | ||
362 | em_ctl & EM_CTL_LED ? "led " : "", | ||
363 | em_ctl & EM_CTL_SAFTE ? "saf-te " : "", | ||
364 | em_ctl & EM_CTL_SES ? "ses-2 " : "", | ||
365 | em_ctl & EM_CTL_SGPIO ? "sgpio " : ""); | ||
366 | } | ||
367 | |||
351 | /** | 368 | /** |
352 | * ahci_save_initial_config - Save and fixup initial config values | 369 | * ahci_save_initial_config - Save and fixup initial config values |
353 | * @dev: target AHCI device | 370 | * @dev: target AHCI device |
@@ -435,7 +452,7 @@ void ahci_save_initial_config(struct device *dev, | |||
435 | } | 452 | } |
436 | 453 | ||
437 | if (mask_port_map) { | 454 | if (mask_port_map) { |
438 | dev_printk(KERN_ERR, dev, "masking port_map 0x%x -> 0x%x\n", | 455 | dev_printk(KERN_WARNING, dev, "masking port_map 0x%x -> 0x%x\n", |
439 | port_map, | 456 | port_map, |
440 | port_map & mask_port_map); | 457 | port_map & mask_port_map); |
441 | port_map &= mask_port_map; | 458 | port_map &= mask_port_map; |
@@ -569,7 +586,7 @@ int ahci_stop_engine(struct ata_port *ap) | |||
569 | writel(tmp, port_mmio + PORT_CMD); | 586 | writel(tmp, port_mmio + PORT_CMD); |
570 | 587 | ||
571 | /* wait for engine to stop. This could be as long as 500 msec */ | 588 | /* wait for engine to stop. This could be as long as 500 msec */ |
572 | tmp = ata_wait_register(port_mmio + PORT_CMD, | 589 | tmp = ata_wait_register(ap, port_mmio + PORT_CMD, |
573 | PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); | 590 | PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); |
574 | if (tmp & PORT_CMD_LIST_ON) | 591 | if (tmp & PORT_CMD_LIST_ON) |
575 | return -EIO; | 592 | return -EIO; |
@@ -616,7 +633,7 @@ static int ahci_stop_fis_rx(struct ata_port *ap) | |||
616 | writel(tmp, port_mmio + PORT_CMD); | 633 | writel(tmp, port_mmio + PORT_CMD); |
617 | 634 | ||
618 | /* wait for completion, spec says 500ms, give it 1000 */ | 635 | /* wait for completion, spec says 500ms, give it 1000 */ |
619 | tmp = ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_FIS_ON, | 636 | tmp = ata_wait_register(ap, port_mmio + PORT_CMD, PORT_CMD_FIS_ON, |
620 | PORT_CMD_FIS_ON, 10, 1000); | 637 | PORT_CMD_FIS_ON, 10, 1000); |
621 | if (tmp & PORT_CMD_FIS_ON) | 638 | if (tmp & PORT_CMD_FIS_ON) |
622 | return -EBUSY; | 639 | return -EBUSY; |
@@ -642,127 +659,56 @@ static void ahci_power_up(struct ata_port *ap) | |||
642 | writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD); | 659 | writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD); |
643 | } | 660 | } |
644 | 661 | ||
645 | static void ahci_disable_alpm(struct ata_port *ap) | 662 | static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, |
663 | unsigned int hints) | ||
646 | { | 664 | { |
665 | struct ata_port *ap = link->ap; | ||
647 | struct ahci_host_priv *hpriv = ap->host->private_data; | 666 | struct ahci_host_priv *hpriv = ap->host->private_data; |
648 | void __iomem *port_mmio = ahci_port_base(ap); | ||
649 | u32 cmd; | ||
650 | struct ahci_port_priv *pp = ap->private_data; | 667 | struct ahci_port_priv *pp = ap->private_data; |
651 | |||
652 | /* IPM bits should be disabled by libata-core */ | ||
653 | /* get the existing command bits */ | ||
654 | cmd = readl(port_mmio + PORT_CMD); | ||
655 | |||
656 | /* disable ALPM and ASP */ | ||
657 | cmd &= ~PORT_CMD_ASP; | ||
658 | cmd &= ~PORT_CMD_ALPE; | ||
659 | |||
660 | /* force the interface back to active */ | ||
661 | cmd |= PORT_CMD_ICC_ACTIVE; | ||
662 | |||
663 | /* write out new cmd value */ | ||
664 | writel(cmd, port_mmio + PORT_CMD); | ||
665 | cmd = readl(port_mmio + PORT_CMD); | ||
666 | |||
667 | /* wait 10ms to be sure we've come out of any low power state */ | ||
668 | msleep(10); | ||
669 | |||
670 | /* clear out any PhyRdy stuff from interrupt status */ | ||
671 | writel(PORT_IRQ_PHYRDY, port_mmio + PORT_IRQ_STAT); | ||
672 | |||
673 | /* go ahead and clean out PhyRdy Change from Serror too */ | ||
674 | ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18))); | ||
675 | |||
676 | /* | ||
677 | * Clear flag to indicate that we should ignore all PhyRdy | ||
678 | * state changes | ||
679 | */ | ||
680 | hpriv->flags &= ~AHCI_HFLAG_NO_HOTPLUG; | ||
681 | |||
682 | /* | ||
683 | * Enable interrupts on Phy Ready. | ||
684 | */ | ||
685 | pp->intr_mask |= PORT_IRQ_PHYRDY; | ||
686 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | ||
687 | |||
688 | /* | ||
689 | * don't change the link pm policy - we can be called | ||
690 | * just to turn of link pm temporarily | ||
691 | */ | ||
692 | } | ||
693 | |||
694 | static int ahci_enable_alpm(struct ata_port *ap, | ||
695 | enum link_pm policy) | ||
696 | { | ||
697 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
698 | void __iomem *port_mmio = ahci_port_base(ap); | 668 | void __iomem *port_mmio = ahci_port_base(ap); |
699 | u32 cmd; | ||
700 | struct ahci_port_priv *pp = ap->private_data; | ||
701 | u32 asp; | ||
702 | 669 | ||
703 | /* Make sure the host is capable of link power management */ | 670 | if (policy != ATA_LPM_MAX_POWER) { |
704 | if (!(hpriv->cap & HOST_CAP_ALPM)) | ||
705 | return -EINVAL; | ||
706 | |||
707 | switch (policy) { | ||
708 | case MAX_PERFORMANCE: | ||
709 | case NOT_AVAILABLE: | ||
710 | /* | 671 | /* |
711 | * if we came here with NOT_AVAILABLE, | 672 | * Disable interrupts on Phy Ready. This keeps us from |
712 | * it just means this is the first time we | 673 | * getting woken up due to spurious phy ready |
713 | * have tried to enable - default to max performance, | 674 | * interrupts. |
714 | * and let the user go to lower power modes on request. | ||
715 | */ | 675 | */ |
716 | ahci_disable_alpm(ap); | 676 | pp->intr_mask &= ~PORT_IRQ_PHYRDY; |
717 | return 0; | 677 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); |
718 | case MIN_POWER: | 678 | |
719 | /* configure HBA to enter SLUMBER */ | 679 | sata_link_scr_lpm(link, policy, false); |
720 | asp = PORT_CMD_ASP; | ||
721 | break; | ||
722 | case MEDIUM_POWER: | ||
723 | /* configure HBA to enter PARTIAL */ | ||
724 | asp = 0; | ||
725 | break; | ||
726 | default: | ||
727 | return -EINVAL; | ||
728 | } | 680 | } |
729 | 681 | ||
730 | /* | 682 | if (hpriv->cap & HOST_CAP_ALPM) { |
731 | * Disable interrupts on Phy Ready. This keeps us from | 683 | u32 cmd = readl(port_mmio + PORT_CMD); |
732 | * getting woken up due to spurious phy ready interrupts | ||
733 | * TBD - Hot plug should be done via polling now, is | ||
734 | * that even supported? | ||
735 | */ | ||
736 | pp->intr_mask &= ~PORT_IRQ_PHYRDY; | ||
737 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | ||
738 | 684 | ||
739 | /* | 685 | if (policy == ATA_LPM_MAX_POWER || !(hints & ATA_LPM_HIPM)) { |
740 | * Set a flag to indicate that we should ignore all PhyRdy | 686 | cmd &= ~(PORT_CMD_ASP | PORT_CMD_ALPE); |
741 | * state changes since these can happen now whenever we | 687 | cmd |= PORT_CMD_ICC_ACTIVE; |
742 | * change link state | ||
743 | */ | ||
744 | hpriv->flags |= AHCI_HFLAG_NO_HOTPLUG; | ||
745 | 688 | ||
746 | /* get the existing command bits */ | 689 | writel(cmd, port_mmio + PORT_CMD); |
747 | cmd = readl(port_mmio + PORT_CMD); | 690 | readl(port_mmio + PORT_CMD); |
748 | 691 | ||
749 | /* | 692 | /* wait 10ms to be sure we've come out of LPM state */ |
750 | * Set ASP based on Policy | 693 | ata_msleep(ap, 10); |
751 | */ | 694 | } else { |
752 | cmd |= asp; | 695 | cmd |= PORT_CMD_ALPE; |
696 | if (policy == ATA_LPM_MIN_POWER) | ||
697 | cmd |= PORT_CMD_ASP; | ||
753 | 698 | ||
754 | /* | 699 | /* write out new cmd value */ |
755 | * Setting this bit will instruct the HBA to aggressively | 700 | writel(cmd, port_mmio + PORT_CMD); |
756 | * enter a lower power link state when it's appropriate and | 701 | } |
757 | * based on the value set above for ASP | 702 | } |
758 | */ | ||
759 | cmd |= PORT_CMD_ALPE; | ||
760 | 703 | ||
761 | /* write out new cmd value */ | 704 | if (policy == ATA_LPM_MAX_POWER) { |
762 | writel(cmd, port_mmio + PORT_CMD); | 705 | sata_link_scr_lpm(link, policy, false); |
763 | cmd = readl(port_mmio + PORT_CMD); | 706 | |
707 | /* turn PHYRDY IRQ back on */ | ||
708 | pp->intr_mask |= PORT_IRQ_PHYRDY; | ||
709 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | ||
710 | } | ||
764 | 711 | ||
765 | /* IPM bits should be set by libata-core */ | ||
766 | return 0; | 712 | return 0; |
767 | } | 713 | } |
768 | 714 | ||
@@ -813,7 +759,7 @@ static void ahci_start_port(struct ata_port *ap) | |||
813 | emp->led_state, | 759 | emp->led_state, |
814 | 4); | 760 | 4); |
815 | if (rc == -EBUSY) | 761 | if (rc == -EBUSY) |
816 | msleep(1); | 762 | ata_msleep(ap, 1); |
817 | else | 763 | else |
818 | break; | 764 | break; |
819 | } | 765 | } |
@@ -872,7 +818,7 @@ int ahci_reset_controller(struct ata_host *host) | |||
872 | * reset must complete within 1 second, or | 818 | * reset must complete within 1 second, or |
873 | * the hardware should be considered fried. | 819 | * the hardware should be considered fried. |
874 | */ | 820 | */ |
875 | tmp = ata_wait_register(mmio + HOST_CTL, HOST_RESET, | 821 | tmp = ata_wait_register(NULL, mmio + HOST_CTL, HOST_RESET, |
876 | HOST_RESET, 10, 1000); | 822 | HOST_RESET, 10, 1000); |
877 | 823 | ||
878 | if (tmp & HOST_RESET) { | 824 | if (tmp & HOST_RESET) { |
@@ -1206,8 +1152,8 @@ static unsigned int ahci_dev_classify(struct ata_port *ap) | |||
1206 | return ata_dev_classify(&tf); | 1152 | return ata_dev_classify(&tf); |
1207 | } | 1153 | } |
1208 | 1154 | ||
1209 | static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, | 1155 | void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, |
1210 | u32 opts) | 1156 | u32 opts) |
1211 | { | 1157 | { |
1212 | dma_addr_t cmd_tbl_dma; | 1158 | dma_addr_t cmd_tbl_dma; |
1213 | 1159 | ||
@@ -1218,6 +1164,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, | |||
1218 | pp->cmd_slot[tag].tbl_addr = cpu_to_le32(cmd_tbl_dma & 0xffffffff); | 1164 | pp->cmd_slot[tag].tbl_addr = cpu_to_le32(cmd_tbl_dma & 0xffffffff); |
1219 | pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); | 1165 | pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); |
1220 | } | 1166 | } |
1167 | EXPORT_SYMBOL_GPL(ahci_fill_cmd_slot); | ||
1221 | 1168 | ||
1222 | int ahci_kick_engine(struct ata_port *ap) | 1169 | int ahci_kick_engine(struct ata_port *ap) |
1223 | { | 1170 | { |
@@ -1252,7 +1199,7 @@ int ahci_kick_engine(struct ata_port *ap) | |||
1252 | writel(tmp, port_mmio + PORT_CMD); | 1199 | writel(tmp, port_mmio + PORT_CMD); |
1253 | 1200 | ||
1254 | rc = 0; | 1201 | rc = 0; |
1255 | tmp = ata_wait_register(port_mmio + PORT_CMD, | 1202 | tmp = ata_wait_register(ap, port_mmio + PORT_CMD, |
1256 | PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); | 1203 | PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); |
1257 | if (tmp & PORT_CMD_CLO) | 1204 | if (tmp & PORT_CMD_CLO) |
1258 | rc = -EIO; | 1205 | rc = -EIO; |
@@ -1282,8 +1229,8 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp, | |||
1282 | writel(1, port_mmio + PORT_CMD_ISSUE); | 1229 | writel(1, port_mmio + PORT_CMD_ISSUE); |
1283 | 1230 | ||
1284 | if (timeout_msec) { | 1231 | if (timeout_msec) { |
1285 | tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, | 1232 | tmp = ata_wait_register(ap, port_mmio + PORT_CMD_ISSUE, |
1286 | 1, timeout_msec); | 1233 | 0x1, 0x1, 1, timeout_msec); |
1287 | if (tmp & 0x1) { | 1234 | if (tmp & 0x1) { |
1288 | ahci_kick_engine(ap); | 1235 | ahci_kick_engine(ap); |
1289 | return -EBUSY; | 1236 | return -EBUSY; |
@@ -1330,7 +1277,7 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, | |||
1330 | } | 1277 | } |
1331 | 1278 | ||
1332 | /* spec says at least 5us, but be generous and sleep for 1ms */ | 1279 | /* spec says at least 5us, but be generous and sleep for 1ms */ |
1333 | msleep(1); | 1280 | ata_msleep(ap, 1); |
1334 | 1281 | ||
1335 | /* issue the second D2H Register FIS */ | 1282 | /* issue the second D2H Register FIS */ |
1336 | tf.ctl &= ~ATA_SRST; | 1283 | tf.ctl &= ~ATA_SRST; |
@@ -1660,15 +1607,10 @@ static void ahci_port_intr(struct ata_port *ap) | |||
1660 | if (unlikely(resetting)) | 1607 | if (unlikely(resetting)) |
1661 | status &= ~PORT_IRQ_BAD_PMP; | 1608 | status &= ~PORT_IRQ_BAD_PMP; |
1662 | 1609 | ||
1663 | /* If we are getting PhyRdy, this is | 1610 | /* if LPM is enabled, PHYRDY doesn't mean anything */ |
1664 | * just a power state change, we should | 1611 | if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) { |
1665 | * clear out this, plus the PhyRdy/Comm | ||
1666 | * Wake bits from Serror | ||
1667 | */ | ||
1668 | if ((hpriv->flags & AHCI_HFLAG_NO_HOTPLUG) && | ||
1669 | (status & PORT_IRQ_PHYRDY)) { | ||
1670 | status &= ~PORT_IRQ_PHYRDY; | 1612 | status &= ~PORT_IRQ_PHYRDY; |
1671 | ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18))); | 1613 | ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG); |
1672 | } | 1614 | } |
1673 | 1615 | ||
1674 | if (unlikely(status & PORT_IRQ_ERROR)) { | 1616 | if (unlikely(status & PORT_IRQ_ERROR)) { |
@@ -1830,12 +1772,24 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) | |||
1830 | static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) | 1772 | static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) |
1831 | { | 1773 | { |
1832 | struct ahci_port_priv *pp = qc->ap->private_data; | 1774 | struct ahci_port_priv *pp = qc->ap->private_data; |
1833 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | 1775 | u8 *rx_fis = pp->rx_fis; |
1834 | 1776 | ||
1835 | if (pp->fbs_enabled) | 1777 | if (pp->fbs_enabled) |
1836 | d2h_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ; | 1778 | rx_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ; |
1779 | |||
1780 | /* | ||
1781 | * After a successful execution of an ATA PIO data-in command, | ||
1782 | * the device doesn't send D2H Reg FIS to update the TF and | ||
1783 | * the host should take TF and E_Status from the preceding PIO | ||
1784 | * Setup FIS. | ||
1785 | */ | ||
1786 | if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE && | ||
1787 | !(qc->flags & ATA_QCFLAG_FAILED)) { | ||
1788 | ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf); | ||
1789 | qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15]; | ||
1790 | } else | ||
1791 | ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf); | ||
1837 | 1792 | ||
1838 | ata_tf_from_fis(d2h_fis, &qc->result_tf); | ||
1839 | return true; | 1793 | return true; |
1840 | } | 1794 | } |
1841 | 1795 | ||
@@ -1965,7 +1919,17 @@ static void ahci_pmp_attach(struct ata_port *ap) | |||
1965 | ahci_enable_fbs(ap); | 1919 | ahci_enable_fbs(ap); |
1966 | 1920 | ||
1967 | pp->intr_mask |= PORT_IRQ_BAD_PMP; | 1921 | pp->intr_mask |= PORT_IRQ_BAD_PMP; |
1968 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | 1922 | |
1923 | /* | ||
1924 | * We must not change the port interrupt mask register if the | ||
1925 | * port is marked frozen, the value in pp->intr_mask will be | ||
1926 | * restored later when the port is thawed. | ||
1927 | * | ||
1928 | * Note that during initialization, the port is marked as | ||
1929 | * frozen since the irq handler is not yet registered. | ||
1930 | */ | ||
1931 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) | ||
1932 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | ||
1969 | } | 1933 | } |
1970 | 1934 | ||
1971 | static void ahci_pmp_detach(struct ata_port *ap) | 1935 | static void ahci_pmp_detach(struct ata_port *ap) |
@@ -1981,10 +1945,13 @@ static void ahci_pmp_detach(struct ata_port *ap) | |||
1981 | writel(cmd, port_mmio + PORT_CMD); | 1945 | writel(cmd, port_mmio + PORT_CMD); |
1982 | 1946 | ||
1983 | pp->intr_mask &= ~PORT_IRQ_BAD_PMP; | 1947 | pp->intr_mask &= ~PORT_IRQ_BAD_PMP; |
1984 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | 1948 | |
1949 | /* see comment above in ahci_pmp_attach() */ | ||
1950 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) | ||
1951 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | ||
1985 | } | 1952 | } |
1986 | 1953 | ||
1987 | static int ahci_port_resume(struct ata_port *ap) | 1954 | int ahci_port_resume(struct ata_port *ap) |
1988 | { | 1955 | { |
1989 | ahci_power_up(ap); | 1956 | ahci_power_up(ap); |
1990 | ahci_start_port(ap); | 1957 | ahci_start_port(ap); |
@@ -1996,6 +1963,7 @@ static int ahci_port_resume(struct ata_port *ap) | |||
1996 | 1963 | ||
1997 | return 0; | 1964 | return 0; |
1998 | } | 1965 | } |
1966 | EXPORT_SYMBOL_GPL(ahci_port_resume); | ||
1999 | 1967 | ||
2000 | #ifdef CONFIG_PM | 1968 | #ifdef CONFIG_PM |
2001 | static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) | 1969 | static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) |