diff options
| -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 */ |
