diff options
Diffstat (limited to 'drivers/ata/libahci.c')
-rw-r--r-- | drivers/ata/libahci.c | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 26d452339e98..ff9d832a163d 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -109,6 +109,8 @@ static ssize_t ahci_read_em_buffer(struct device *dev, | |||
109 | static ssize_t ahci_store_em_buffer(struct device *dev, | 109 | static ssize_t ahci_store_em_buffer(struct device *dev, |
110 | struct device_attribute *attr, | 110 | struct device_attribute *attr, |
111 | 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); | ||
112 | 114 | ||
113 | 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); |
114 | 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); |
@@ -116,6 +118,7 @@ static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); | |||
116 | 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); |
117 | static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, | 119 | static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, |
118 | 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); | ||
119 | 122 | ||
120 | struct device_attribute *ahci_shost_attrs[] = { | 123 | struct device_attribute *ahci_shost_attrs[] = { |
121 | &dev_attr_link_power_management_policy, | 124 | &dev_attr_link_power_management_policy, |
@@ -126,6 +129,7 @@ struct device_attribute *ahci_shost_attrs[] = { | |||
126 | &dev_attr_ahci_host_version, | 129 | &dev_attr_ahci_host_version, |
127 | &dev_attr_ahci_port_cmd, | 130 | &dev_attr_ahci_port_cmd, |
128 | &dev_attr_em_buffer, | 131 | &dev_attr_em_buffer, |
132 | &dev_attr_em_message_supported, | ||
129 | NULL | 133 | NULL |
130 | }; | 134 | }; |
131 | EXPORT_SYMBOL_GPL(ahci_shost_attrs); | 135 | EXPORT_SYMBOL_GPL(ahci_shost_attrs); |
@@ -343,6 +347,24 @@ static ssize_t ahci_store_em_buffer(struct device *dev, | |||
343 | return size; | 347 | return size; |
344 | } | 348 | } |
345 | 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 | |||
346 | /** | 368 | /** |
347 | * ahci_save_initial_config - Save and fixup initial config values | 369 | * ahci_save_initial_config - Save and fixup initial config values |
348 | * @dev: target AHCI device | 370 | * @dev: target AHCI device |
@@ -539,6 +561,27 @@ void ahci_start_engine(struct ata_port *ap) | |||
539 | { | 561 | { |
540 | void __iomem *port_mmio = ahci_port_base(ap); | 562 | void __iomem *port_mmio = ahci_port_base(ap); |
541 | u32 tmp; | 563 | u32 tmp; |
564 | u8 status; | ||
565 | |||
566 | status = readl(port_mmio + PORT_TFDATA) & 0xFF; | ||
567 | |||
568 | /* | ||
569 | * At end of section 10.1 of AHCI spec (rev 1.3), it states | ||
570 | * Software shall not set PxCMD.ST to 1 until it is determined | ||
571 | * that a functoinal device is present on the port as determined by | ||
572 | * PxTFD.STS.BSY=0, PxTFD.STS.DRQ=0 and PxSSTS.DET=3h | ||
573 | * | ||
574 | * Even though most AHCI host controllers work without this check, | ||
575 | * specific controller will fail under this condition | ||
576 | */ | ||
577 | if (status & (ATA_BUSY | ATA_DRQ)) | ||
578 | return; | ||
579 | else { | ||
580 | ahci_scr_read(&ap->link, SCR_STATUS, &tmp); | ||
581 | |||
582 | if ((tmp & 0xf) != 0x3) | ||
583 | return; | ||
584 | } | ||
542 | 585 | ||
543 | /* start DMA */ | 586 | /* start DMA */ |
544 | tmp = readl(port_mmio + PORT_CMD); | 587 | tmp = readl(port_mmio + PORT_CMD); |
@@ -1897,7 +1940,17 @@ static void ahci_pmp_attach(struct ata_port *ap) | |||
1897 | ahci_enable_fbs(ap); | 1940 | ahci_enable_fbs(ap); |
1898 | 1941 | ||
1899 | pp->intr_mask |= PORT_IRQ_BAD_PMP; | 1942 | pp->intr_mask |= PORT_IRQ_BAD_PMP; |
1900 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | 1943 | |
1944 | /* | ||
1945 | * We must not change the port interrupt mask register if the | ||
1946 | * port is marked frozen, the value in pp->intr_mask will be | ||
1947 | * restored later when the port is thawed. | ||
1948 | * | ||
1949 | * Note that during initialization, the port is marked as | ||
1950 | * frozen since the irq handler is not yet registered. | ||
1951 | */ | ||
1952 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) | ||
1953 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | ||
1901 | } | 1954 | } |
1902 | 1955 | ||
1903 | static void ahci_pmp_detach(struct ata_port *ap) | 1956 | static void ahci_pmp_detach(struct ata_port *ap) |
@@ -1913,7 +1966,10 @@ static void ahci_pmp_detach(struct ata_port *ap) | |||
1913 | writel(cmd, port_mmio + PORT_CMD); | 1966 | writel(cmd, port_mmio + PORT_CMD); |
1914 | 1967 | ||
1915 | pp->intr_mask &= ~PORT_IRQ_BAD_PMP; | 1968 | pp->intr_mask &= ~PORT_IRQ_BAD_PMP; |
1916 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | 1969 | |
1970 | /* see comment above in ahci_pmp_attach() */ | ||
1971 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) | ||
1972 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | ||
1917 | } | 1973 | } |
1918 | 1974 | ||
1919 | int ahci_port_resume(struct ata_port *ap) | 1975 | int ahci_port_resume(struct ata_port *ap) |