diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/ahci.c | 23 | ||||
-rw-r--r-- | drivers/ata/libata-acpi.c | 19 | ||||
-rw-r--r-- | drivers/ata/libata-sff.c | 30 | ||||
-rw-r--r-- | drivers/ata/pata_sis.c | 1 | ||||
-rw-r--r-- | drivers/ata/sata_mv.c | 2 | ||||
-rw-r--r-- | drivers/ata/sata_sil24.c | 1 | ||||
-rw-r--r-- | drivers/ata/sata_uli.c | 1 |
7 files changed, 56 insertions, 21 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 6a4a2a25d97a..5e6468a7ca4b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1777,7 +1777,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance) | |||
1777 | struct ahci_host_priv *hpriv; | 1777 | struct ahci_host_priv *hpriv; |
1778 | unsigned int i, handled = 0; | 1778 | unsigned int i, handled = 0; |
1779 | void __iomem *mmio; | 1779 | void __iomem *mmio; |
1780 | u32 irq_stat, irq_ack = 0; | 1780 | u32 irq_stat, irq_masked; |
1781 | 1781 | ||
1782 | VPRINTK("ENTER\n"); | 1782 | VPRINTK("ENTER\n"); |
1783 | 1783 | ||
@@ -1786,16 +1786,17 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance) | |||
1786 | 1786 | ||
1787 | /* sigh. 0xffffffff is a valid return from h/w */ | 1787 | /* sigh. 0xffffffff is a valid return from h/w */ |
1788 | irq_stat = readl(mmio + HOST_IRQ_STAT); | 1788 | irq_stat = readl(mmio + HOST_IRQ_STAT); |
1789 | irq_stat &= hpriv->port_map; | ||
1790 | if (!irq_stat) | 1789 | if (!irq_stat) |
1791 | return IRQ_NONE; | 1790 | return IRQ_NONE; |
1792 | 1791 | ||
1792 | irq_masked = irq_stat & hpriv->port_map; | ||
1793 | |||
1793 | spin_lock(&host->lock); | 1794 | spin_lock(&host->lock); |
1794 | 1795 | ||
1795 | for (i = 0; i < host->n_ports; i++) { | 1796 | for (i = 0; i < host->n_ports; i++) { |
1796 | struct ata_port *ap; | 1797 | struct ata_port *ap; |
1797 | 1798 | ||
1798 | if (!(irq_stat & (1 << i))) | 1799 | if (!(irq_masked & (1 << i))) |
1799 | continue; | 1800 | continue; |
1800 | 1801 | ||
1801 | ap = host->ports[i]; | 1802 | ap = host->ports[i]; |
@@ -1809,14 +1810,20 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance) | |||
1809 | "interrupt on disabled port %u\n", i); | 1810 | "interrupt on disabled port %u\n", i); |
1810 | } | 1811 | } |
1811 | 1812 | ||
1812 | irq_ack |= (1 << i); | ||
1813 | } | ||
1814 | |||
1815 | if (irq_ack) { | ||
1816 | writel(irq_ack, mmio + HOST_IRQ_STAT); | ||
1817 | handled = 1; | 1813 | handled = 1; |
1818 | } | 1814 | } |
1819 | 1815 | ||
1816 | /* HOST_IRQ_STAT behaves as level triggered latch meaning that | ||
1817 | * it should be cleared after all the port events are cleared; | ||
1818 | * otherwise, it will raise a spurious interrupt after each | ||
1819 | * valid one. Please read section 10.6.2 of ahci 1.1 for more | ||
1820 | * information. | ||
1821 | * | ||
1822 | * Also, use the unmasked value to clear interrupt as spurious | ||
1823 | * pending event on a dummy port might cause screaming IRQ. | ||
1824 | */ | ||
1825 | writel(irq_stat, mmio + HOST_IRQ_STAT); | ||
1826 | |||
1820 | spin_unlock(&host->lock); | 1827 | spin_unlock(&host->lock); |
1821 | 1828 | ||
1822 | VPRINTK("EXIT\n"); | 1829 | VPRINTK("EXIT\n"); |
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 3ff8b14420d9..9330b7922f62 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -29,14 +29,16 @@ | |||
29 | enum { | 29 | enum { |
30 | ATA_ACPI_FILTER_SETXFER = 1 << 0, | 30 | ATA_ACPI_FILTER_SETXFER = 1 << 0, |
31 | ATA_ACPI_FILTER_LOCK = 1 << 1, | 31 | ATA_ACPI_FILTER_LOCK = 1 << 1, |
32 | ATA_ACPI_FILTER_DIPM = 1 << 2, | ||
32 | 33 | ||
33 | ATA_ACPI_FILTER_DEFAULT = ATA_ACPI_FILTER_SETXFER | | 34 | ATA_ACPI_FILTER_DEFAULT = ATA_ACPI_FILTER_SETXFER | |
34 | ATA_ACPI_FILTER_LOCK, | 35 | ATA_ACPI_FILTER_LOCK | |
36 | ATA_ACPI_FILTER_DIPM, | ||
35 | }; | 37 | }; |
36 | 38 | ||
37 | static unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT; | 39 | static unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT; |
38 | module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644); | 40 | module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644); |
39 | MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock)"); | 41 | MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock, 0x4=DIPM)"); |
40 | 42 | ||
41 | #define NO_PORT_MULT 0xffff | 43 | #define NO_PORT_MULT 0xffff |
42 | #define SATA_ADR(root, pmp) (((root) << 16) | (pmp)) | 44 | #define SATA_ADR(root, pmp) (((root) << 16) | (pmp)) |
@@ -195,6 +197,10 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, | |||
195 | /* This device does not support hotplug */ | 197 | /* This device does not support hotplug */ |
196 | return; | 198 | return; |
197 | 199 | ||
200 | if (event == ACPI_NOTIFY_BUS_CHECK || | ||
201 | event == ACPI_NOTIFY_DEVICE_CHECK) | ||
202 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
203 | |||
198 | spin_lock_irqsave(ap->lock, flags); | 204 | spin_lock_irqsave(ap->lock, flags); |
199 | 205 | ||
200 | switch (event) { | 206 | switch (event) { |
@@ -202,7 +208,6 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, | |||
202 | case ACPI_NOTIFY_DEVICE_CHECK: | 208 | case ACPI_NOTIFY_DEVICE_CHECK: |
203 | ata_ehi_push_desc(ehi, "ACPI event"); | 209 | ata_ehi_push_desc(ehi, "ACPI event"); |
204 | 210 | ||
205 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
206 | if (ACPI_FAILURE(status)) { | 211 | if (ACPI_FAILURE(status)) { |
207 | ata_port_printk(ap, KERN_ERR, | 212 | ata_port_printk(ap, KERN_ERR, |
208 | "acpi: failed to determine bay status (0x%x)\n", | 213 | "acpi: failed to determine bay status (0x%x)\n", |
@@ -690,6 +695,14 @@ static int ata_acpi_filter_tf(const struct ata_taskfile *tf, | |||
690 | return 1; | 695 | return 1; |
691 | } | 696 | } |
692 | 697 | ||
698 | if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_DIPM) { | ||
699 | /* inhibit enabling DIPM */ | ||
700 | if (tf->command == ATA_CMD_SET_FEATURES && | ||
701 | tf->feature == SETFEATURES_SATA_ENABLE && | ||
702 | tf->nsect == SATA_DIPM) | ||
703 | return 1; | ||
704 | } | ||
705 | |||
693 | return 0; | 706 | return 0; |
694 | } | 707 | } |
695 | 708 | ||
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 215d18672a5a..c0908c225483 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -1094,6 +1094,7 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq) | |||
1094 | int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, | 1094 | int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, |
1095 | u8 status, int in_wq) | 1095 | u8 status, int in_wq) |
1096 | { | 1096 | { |
1097 | struct ata_eh_info *ehi = &ap->link.eh_info; | ||
1097 | unsigned long flags = 0; | 1098 | unsigned long flags = 0; |
1098 | int poll_next; | 1099 | int poll_next; |
1099 | 1100 | ||
@@ -1125,9 +1126,12 @@ fsm_start: | |||
1125 | if (likely(status & (ATA_ERR | ATA_DF))) | 1126 | if (likely(status & (ATA_ERR | ATA_DF))) |
1126 | /* device stops HSM for abort/error */ | 1127 | /* device stops HSM for abort/error */ |
1127 | qc->err_mask |= AC_ERR_DEV; | 1128 | qc->err_mask |= AC_ERR_DEV; |
1128 | else | 1129 | else { |
1129 | /* HSM violation. Let EH handle this */ | 1130 | /* HSM violation. Let EH handle this */ |
1131 | ata_ehi_push_desc(ehi, | ||
1132 | "ST_FIRST: !(DRQ|ERR|DF)"); | ||
1130 | qc->err_mask |= AC_ERR_HSM; | 1133 | qc->err_mask |= AC_ERR_HSM; |
1134 | } | ||
1131 | 1135 | ||
1132 | ap->hsm_task_state = HSM_ST_ERR; | 1136 | ap->hsm_task_state = HSM_ST_ERR; |
1133 | goto fsm_start; | 1137 | goto fsm_start; |
@@ -1146,9 +1150,9 @@ fsm_start: | |||
1146 | * the CDB. | 1150 | * the CDB. |
1147 | */ | 1151 | */ |
1148 | if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) { | 1152 | if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) { |
1149 | ata_port_printk(ap, KERN_WARNING, | 1153 | ata_ehi_push_desc(ehi, "ST_FIRST: " |
1150 | "DRQ=1 with device error, " | 1154 | "DRQ=1 with device error, " |
1151 | "dev_stat 0x%X\n", status); | 1155 | "dev_stat 0x%X", status); |
1152 | qc->err_mask |= AC_ERR_HSM; | 1156 | qc->err_mask |= AC_ERR_HSM; |
1153 | ap->hsm_task_state = HSM_ST_ERR; | 1157 | ap->hsm_task_state = HSM_ST_ERR; |
1154 | goto fsm_start; | 1158 | goto fsm_start; |
@@ -1205,9 +1209,9 @@ fsm_start: | |||
1205 | * let the EH abort the command or reset the device. | 1209 | * let the EH abort the command or reset the device. |
1206 | */ | 1210 | */ |
1207 | if (unlikely(status & (ATA_ERR | ATA_DF))) { | 1211 | if (unlikely(status & (ATA_ERR | ATA_DF))) { |
1208 | ata_port_printk(ap, KERN_WARNING, "DRQ=1 with " | 1212 | ata_ehi_push_desc(ehi, "ST-ATAPI: " |
1209 | "device error, dev_stat 0x%X\n", | 1213 | "DRQ=1 with device error, " |
1210 | status); | 1214 | "dev_stat 0x%X", status); |
1211 | qc->err_mask |= AC_ERR_HSM; | 1215 | qc->err_mask |= AC_ERR_HSM; |
1212 | ap->hsm_task_state = HSM_ST_ERR; | 1216 | ap->hsm_task_state = HSM_ST_ERR; |
1213 | goto fsm_start; | 1217 | goto fsm_start; |
@@ -1226,13 +1230,17 @@ fsm_start: | |||
1226 | if (likely(status & (ATA_ERR | ATA_DF))) | 1230 | if (likely(status & (ATA_ERR | ATA_DF))) |
1227 | /* device stops HSM for abort/error */ | 1231 | /* device stops HSM for abort/error */ |
1228 | qc->err_mask |= AC_ERR_DEV; | 1232 | qc->err_mask |= AC_ERR_DEV; |
1229 | else | 1233 | else { |
1230 | /* HSM violation. Let EH handle this. | 1234 | /* HSM violation. Let EH handle this. |
1231 | * Phantom devices also trigger this | 1235 | * Phantom devices also trigger this |
1232 | * condition. Mark hint. | 1236 | * condition. Mark hint. |
1233 | */ | 1237 | */ |
1238 | ata_ehi_push_desc(ehi, "ST-ATA: " | ||
1239 | "DRQ=1 with device error, " | ||
1240 | "dev_stat 0x%X", status); | ||
1234 | qc->err_mask |= AC_ERR_HSM | | 1241 | qc->err_mask |= AC_ERR_HSM | |
1235 | AC_ERR_NODEV_HINT; | 1242 | AC_ERR_NODEV_HINT; |
1243 | } | ||
1236 | 1244 | ||
1237 | ap->hsm_task_state = HSM_ST_ERR; | 1245 | ap->hsm_task_state = HSM_ST_ERR; |
1238 | goto fsm_start; | 1246 | goto fsm_start; |
@@ -1257,8 +1265,12 @@ fsm_start: | |||
1257 | status = ata_wait_idle(ap); | 1265 | status = ata_wait_idle(ap); |
1258 | } | 1266 | } |
1259 | 1267 | ||
1260 | if (status & (ATA_BUSY | ATA_DRQ)) | 1268 | if (status & (ATA_BUSY | ATA_DRQ)) { |
1269 | ata_ehi_push_desc(ehi, "ST-ATA: " | ||
1270 | "BUSY|DRQ persists on ERR|DF, " | ||
1271 | "dev_stat 0x%X", status); | ||
1261 | qc->err_mask |= AC_ERR_HSM; | 1272 | qc->err_mask |= AC_ERR_HSM; |
1273 | } | ||
1262 | 1274 | ||
1263 | /* ata_pio_sectors() might change the | 1275 | /* ata_pio_sectors() might change the |
1264 | * state to HSM_ST_LAST. so, the state | 1276 | * state to HSM_ST_LAST. so, the state |
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index e82c66e8d31b..26345d7b531c 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c | |||
@@ -56,6 +56,7 @@ static const struct sis_laptop sis_laptop[] = { | |||
56 | { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */ | 56 | { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */ |
57 | { 0x5513, 0x1734, 0x105F }, /* FSC Amilo A1630 */ | 57 | { 0x5513, 0x1734, 0x105F }, /* FSC Amilo A1630 */ |
58 | { 0x5513, 0x1071, 0x8640 }, /* EasyNote K5305 */ | 58 | { 0x5513, 0x1071, 0x8640 }, /* EasyNote K5305 */ |
59 | { 0x5513, 0x1039, 0x5513 }, /* Targa Visionary 1000 */ | ||
59 | /* end marker */ | 60 | /* end marker */ |
60 | { 0, } | 61 | { 0, } |
61 | }; | 62 | }; |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 28092bc50146..ad169ffbc4cb 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -1607,7 +1607,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) | |||
1607 | * Much of the time, this could just work regardless. | 1607 | * Much of the time, this could just work regardless. |
1608 | * So for now, just log the incident, and allow the attempt. | 1608 | * So for now, just log the incident, and allow the attempt. |
1609 | */ | 1609 | */ |
1610 | if (limit_warnings && (qc->nbytes / qc->sect_size) > 1) { | 1610 | if (limit_warnings > 0 && (qc->nbytes / qc->sect_size) > 1) { |
1611 | --limit_warnings; | 1611 | --limit_warnings; |
1612 | ata_link_printk(qc->dev->link, KERN_WARNING, DRV_NAME | 1612 | ata_link_printk(qc->dev->link, KERN_WARNING, DRV_NAME |
1613 | ": attempting PIO w/multiple DRQ: " | 1613 | ": attempting PIO w/multiple DRQ: " |
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 8ee6b5b4ede7..84ffcc26a74b 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
@@ -370,6 +370,7 @@ static const struct pci_device_id sil24_pci_tbl[] = { | |||
370 | { PCI_VDEVICE(INTEL, 0x3124), BID_SIL3124 }, | 370 | { PCI_VDEVICE(INTEL, 0x3124), BID_SIL3124 }, |
371 | { PCI_VDEVICE(CMD, 0x3132), BID_SIL3132 }, | 371 | { PCI_VDEVICE(CMD, 0x3132), BID_SIL3132 }, |
372 | { PCI_VDEVICE(CMD, 0x0242), BID_SIL3132 }, | 372 | { PCI_VDEVICE(CMD, 0x0242), BID_SIL3132 }, |
373 | { PCI_VDEVICE(CMD, 0x0244), BID_SIL3132 }, | ||
373 | { PCI_VDEVICE(CMD, 0x3131), BID_SIL3131 }, | 374 | { PCI_VDEVICE(CMD, 0x3131), BID_SIL3131 }, |
374 | { PCI_VDEVICE(CMD, 0x3531), BID_SIL3131 }, | 375 | { PCI_VDEVICE(CMD, 0x3531), BID_SIL3131 }, |
375 | 376 | ||
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c index f277cea904ce..db529b849948 100644 --- a/drivers/ata/sata_uli.c +++ b/drivers/ata/sata_uli.c | |||
@@ -83,6 +83,7 @@ static struct ata_port_operations uli_ops = { | |||
83 | .inherits = &ata_bmdma_port_ops, | 83 | .inherits = &ata_bmdma_port_ops, |
84 | .scr_read = uli_scr_read, | 84 | .scr_read = uli_scr_read, |
85 | .scr_write = uli_scr_write, | 85 | .scr_write = uli_scr_write, |
86 | .hardreset = ATA_OP_NULL, | ||
86 | }; | 87 | }; |
87 | 88 | ||
88 | static const struct ata_port_info uli_port_info = { | 89 | static const struct ata_port_info uli_port_info = { |