diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/sata_mv.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 2770005324b4..33e387354388 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
@@ -915,7 +915,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) | |||
915 | 915 | ||
916 | pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); | 916 | pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); |
917 | pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); | 917 | pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); |
918 | pp->sg_tbl[i].flags_size = cpu_to_le32(len); | 918 | pp->sg_tbl[i].flags_size = cpu_to_le32(len & 0xffff); |
919 | 919 | ||
920 | sg_len -= len; | 920 | sg_len -= len; |
921 | addr += len; | 921 | addr += len; |
@@ -1187,7 +1187,6 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1187 | { | 1187 | { |
1188 | void __iomem *mmio = host_set->mmio_base; | 1188 | void __iomem *mmio = host_set->mmio_base; |
1189 | void __iomem *hc_mmio = mv_hc_base(mmio, hc); | 1189 | void __iomem *hc_mmio = mv_hc_base(mmio, hc); |
1190 | struct ata_port *ap; | ||
1191 | struct ata_queued_cmd *qc; | 1190 | struct ata_queued_cmd *qc; |
1192 | u32 hc_irq_cause; | 1191 | u32 hc_irq_cause; |
1193 | int shift, port, port0, hard_port, handled; | 1192 | int shift, port, port0, hard_port, handled; |
@@ -1210,25 +1209,31 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1210 | hc,relevant,hc_irq_cause); | 1209 | hc,relevant,hc_irq_cause); |
1211 | 1210 | ||
1212 | for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { | 1211 | for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { |
1213 | ap = host_set->ports[port]; | 1212 | struct ata_port *ap = host_set->ports[port]; |
1213 | struct mv_port_priv *pp = ap->private_data; | ||
1214 | hard_port = port & MV_PORT_MASK; /* range 0-3 */ | 1214 | hard_port = port & MV_PORT_MASK; /* range 0-3 */ |
1215 | handled = 0; /* ensure ata_status is set if handled++ */ | 1215 | handled = 0; /* ensure ata_status is set if handled++ */ |
1216 | 1216 | ||
1217 | if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) { | 1217 | /* Note that DEV_IRQ might happen spuriously during EDMA, |
1218 | /* new CRPB on the queue; just one at a time until NCQ | 1218 | * and should be ignored in such cases. We could mask it, |
1219 | */ | 1219 | * but it's pretty rare and may not be worth the overhead. |
1220 | ata_status = mv_get_crpb_status(ap); | 1220 | */ |
1221 | handled++; | 1221 | if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { |
1222 | } else if ((DEV_IRQ << hard_port) & hc_irq_cause) { | 1222 | /* EDMA: check for response queue interrupt */ |
1223 | /* received ATA IRQ; read the status reg to clear INTRQ | 1223 | if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) { |
1224 | */ | 1224 | ata_status = mv_get_crpb_status(ap); |
1225 | ata_status = readb((void __iomem *) | 1225 | handled = 1; |
1226 | } | ||
1227 | } else { | ||
1228 | /* PIO: check for device (drive) interrupt */ | ||
1229 | if ((DEV_IRQ << hard_port) & hc_irq_cause) { | ||
1230 | ata_status = readb((void __iomem *) | ||
1226 | ap->ioaddr.status_addr); | 1231 | ap->ioaddr.status_addr); |
1227 | handled++; | 1232 | handled = 1; |
1233 | } | ||
1228 | } | 1234 | } |
1229 | 1235 | ||
1230 | if (ap && | 1236 | if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)) |
1231 | (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) | ||
1232 | continue; | 1237 | continue; |
1233 | 1238 | ||
1234 | err_mask = ac_err_mask(ata_status); | 1239 | err_mask = ac_err_mask(ata_status); |
@@ -1240,12 +1245,12 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
1240 | if ((PORT0_ERR << shift) & relevant) { | 1245 | if ((PORT0_ERR << shift) & relevant) { |
1241 | mv_err_intr(ap); | 1246 | mv_err_intr(ap); |
1242 | err_mask |= AC_ERR_OTHER; | 1247 | err_mask |= AC_ERR_OTHER; |
1243 | handled++; | 1248 | handled = 1; |
1244 | } | 1249 | } |
1245 | 1250 | ||
1246 | if (handled && ap) { | 1251 | if (handled) { |
1247 | qc = ata_qc_from_tag(ap, ap->active_tag); | 1252 | qc = ata_qc_from_tag(ap, ap->active_tag); |
1248 | if (NULL != qc) { | 1253 | if (qc && (qc->flags & ATA_QCFLAG_ACTIVE)) { |
1249 | VPRINTK("port %u IRQ found for qc, " | 1254 | VPRINTK("port %u IRQ found for qc, " |
1250 | "ata_status 0x%x\n", port,ata_status); | 1255 | "ata_status 0x%x\n", port,ata_status); |
1251 | /* mark qc status appropriately */ | 1256 | /* mark qc status appropriately */ |