aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/sata_nv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/sata_nv.c')
-rw-r--r--drivers/ata/sata_nv.c57
1 files changed, 13 insertions, 44 deletions
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index cb89ef8d99d9..7254e255fd78 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -873,29 +873,11 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
873 ata_port_freeze(ap); 873 ata_port_freeze(ap);
874 else 874 else
875 ata_port_abort(ap); 875 ata_port_abort(ap);
876 return 1; 876 return -1;
877 } 877 }
878 878
879 if (likely(flags & NV_CPB_RESP_DONE)) { 879 if (likely(flags & NV_CPB_RESP_DONE))
880 struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num); 880 return 1;
881 VPRINTK("CPB flags done, flags=0x%x\n", flags);
882 if (likely(qc)) {
883 DPRINTK("Completing qc from tag %d\n", cpb_num);
884 ata_qc_complete(qc);
885 } else {
886 struct ata_eh_info *ehi = &ap->link.eh_info;
887 /* Notifier bits set without a command may indicate the drive
888 is misbehaving. Raise host state machine violation on this
889 condition. */
890 ata_port_printk(ap, KERN_ERR,
891 "notifier for tag %d with no cmd?\n",
892 cpb_num);
893 ehi->err_mask |= AC_ERR_HSM;
894 ehi->action |= ATA_EH_RESET;
895 ata_port_freeze(ap);
896 return 1;
897 }
898 }
899 return 0; 881 return 0;
900} 882}
901 883
@@ -1018,6 +1000,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
1018 NV_ADMA_STAT_CPBERR | 1000 NV_ADMA_STAT_CPBERR |
1019 NV_ADMA_STAT_CMD_COMPLETE)) { 1001 NV_ADMA_STAT_CMD_COMPLETE)) {
1020 u32 check_commands = notifier_clears[i]; 1002 u32 check_commands = notifier_clears[i];
1003 u32 done_mask = 0;
1021 int pos, rc; 1004 int pos, rc;
1022 1005
1023 if (status & NV_ADMA_STAT_CPBERR) { 1006 if (status & NV_ADMA_STAT_CPBERR) {
@@ -1034,10 +1017,13 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
1034 pos--; 1017 pos--;
1035 rc = nv_adma_check_cpb(ap, pos, 1018 rc = nv_adma_check_cpb(ap, pos,
1036 notifier_error & (1 << pos)); 1019 notifier_error & (1 << pos));
1037 if (unlikely(rc)) 1020 if (rc > 0)
1021 done_mask |= 1 << pos;
1022 else if (unlikely(rc < 0))
1038 check_commands = 0; 1023 check_commands = 0;
1039 check_commands &= ~(1 << pos); 1024 check_commands &= ~(1 << pos);
1040 } 1025 }
1026 ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
1041 } 1027 }
1042 } 1028 }
1043 1029
@@ -2132,7 +2118,6 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
2132 struct ata_eh_info *ehi = &ap->link.eh_info; 2118 struct ata_eh_info *ehi = &ap->link.eh_info;
2133 u32 sactive; 2119 u32 sactive;
2134 u32 done_mask; 2120 u32 done_mask;
2135 int i;
2136 u8 host_stat; 2121 u8 host_stat;
2137 u8 lack_dhfis = 0; 2122 u8 lack_dhfis = 0;
2138 2123
@@ -2152,27 +2137,11 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
2152 sactive = readl(pp->sactive_block); 2137 sactive = readl(pp->sactive_block);
2153 done_mask = pp->qc_active ^ sactive; 2138 done_mask = pp->qc_active ^ sactive;
2154 2139
2155 if (unlikely(done_mask & sactive)) { 2140 pp->qc_active &= ~done_mask;
2156 ata_ehi_clear_desc(ehi); 2141 pp->dhfis_bits &= ~done_mask;
2157 ata_ehi_push_desc(ehi, "illegal SWNCQ:qc_active transition" 2142 pp->dmafis_bits &= ~done_mask;
2158 "(%08x->%08x)", pp->qc_active, sactive); 2143 pp->sdbfis_bits |= done_mask;
2159 ehi->err_mask |= AC_ERR_HSM; 2144 ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask);
2160 ehi->action |= ATA_EH_RESET;
2161 return -EINVAL;
2162 }
2163 for (i = 0; i < ATA_MAX_QUEUE; i++) {
2164 if (!(done_mask & (1 << i)))
2165 continue;
2166
2167 qc = ata_qc_from_tag(ap, i);
2168 if (qc) {
2169 ata_qc_complete(qc);
2170 pp->qc_active &= ~(1 << i);
2171 pp->dhfis_bits &= ~(1 << i);
2172 pp->dmafis_bits &= ~(1 << i);
2173 pp->sdbfis_bits |= (1 << i);
2174 }
2175 }
2176 2145
2177 if (!ap->qc_active) { 2146 if (!ap->qc_active) {
2178 DPRINTK("over\n"); 2147 DPRINTK("over\n");