diff options
| -rw-r--r-- | drivers/scsi/sata_mv.c | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 275ed9bd898c..fa901fd65085 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
| @@ -1010,7 +1010,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) | |||
| 1010 | 1010 | ||
| 1011 | pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); | 1011 | pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); |
| 1012 | pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); | 1012 | pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); |
| 1013 | pp->sg_tbl[i].flags_size = cpu_to_le32(len); | 1013 | pp->sg_tbl[i].flags_size = cpu_to_le32(len & 0xffff); |
| 1014 | 1014 | ||
| 1015 | sg_len -= len; | 1015 | sg_len -= len; |
| 1016 | addr += len; | 1016 | addr += len; |
| @@ -1350,7 +1350,6 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
| 1350 | { | 1350 | { |
| 1351 | void __iomem *mmio = host_set->mmio_base; | 1351 | void __iomem *mmio = host_set->mmio_base; |
| 1352 | void __iomem *hc_mmio = mv_hc_base(mmio, hc); | 1352 | void __iomem *hc_mmio = mv_hc_base(mmio, hc); |
| 1353 | struct ata_port *ap; | ||
| 1354 | struct ata_queued_cmd *qc; | 1353 | struct ata_queued_cmd *qc; |
| 1355 | u32 hc_irq_cause; | 1354 | u32 hc_irq_cause; |
| 1356 | int shift, port, port0, hard_port, handled; | 1355 | int shift, port, port0, hard_port, handled; |
| @@ -1373,25 +1372,32 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
| 1373 | 1372 | ||
| 1374 | for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { | 1373 | for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { |
| 1375 | u8 ata_status = 0; | 1374 | u8 ata_status = 0; |
| 1376 | ap = host_set->ports[port]; | 1375 | struct ata_port *ap = host_set->ports[port]; |
| 1376 | struct mv_port_priv *pp = ap->private_data; | ||
| 1377 | |||
| 1377 | hard_port = port & MV_PORT_MASK; /* range 0-3 */ | 1378 | hard_port = port & MV_PORT_MASK; /* range 0-3 */ |
| 1378 | handled = 0; /* ensure ata_status is set if handled++ */ | 1379 | handled = 0; /* ensure ata_status is set if handled++ */ |
| 1379 | 1380 | ||
| 1380 | if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) { | 1381 | /* Note that DEV_IRQ might happen spuriously during EDMA, |
| 1381 | /* new CRPB on the queue; just one at a time until NCQ | 1382 | * and should be ignored in such cases. We could mask it, |
| 1382 | */ | 1383 | * but it's pretty rare and may not be worth the overhead. |
| 1383 | ata_status = mv_get_crpb_status(ap); | 1384 | */ |
| 1384 | handled++; | 1385 | if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { |
| 1385 | } else if ((DEV_IRQ << hard_port) & hc_irq_cause) { | 1386 | /* EDMA: check for response queue interrupt */ |
| 1386 | /* received ATA IRQ; read the status reg to clear INTRQ | 1387 | if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) { |
| 1387 | */ | 1388 | ata_status = mv_get_crpb_status(ap); |
| 1388 | ata_status = readb((void __iomem *) | 1389 | handled = 1; |
| 1390 | } | ||
| 1391 | } else { | ||
| 1392 | /* PIO: check for device (drive) interrupt */ | ||
| 1393 | if ((DEV_IRQ << hard_port) & hc_irq_cause) { | ||
| 1394 | ata_status = readb((void __iomem *) | ||
| 1389 | ap->ioaddr.status_addr); | 1395 | ap->ioaddr.status_addr); |
| 1390 | handled++; | 1396 | handled = 1; |
| 1397 | } | ||
| 1391 | } | 1398 | } |
| 1392 | 1399 | ||
| 1393 | if (ap && | 1400 | if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)) |
| 1394 | (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) | ||
| 1395 | continue; | 1401 | continue; |
| 1396 | 1402 | ||
| 1397 | err_mask = ac_err_mask(ata_status); | 1403 | err_mask = ac_err_mask(ata_status); |
| @@ -1403,12 +1409,12 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, | |||
| 1403 | if ((PORT0_ERR << shift) & relevant) { | 1409 | if ((PORT0_ERR << shift) & relevant) { |
| 1404 | mv_err_intr(ap); | 1410 | mv_err_intr(ap); |
| 1405 | err_mask |= AC_ERR_OTHER; | 1411 | err_mask |= AC_ERR_OTHER; |
| 1406 | handled++; | 1412 | handled = 1; |
| 1407 | } | 1413 | } |
| 1408 | 1414 | ||
| 1409 | if (handled && ap) { | 1415 | if (handled) { |
| 1410 | qc = ata_qc_from_tag(ap, ap->active_tag); | 1416 | qc = ata_qc_from_tag(ap, ap->active_tag); |
| 1411 | if (NULL != qc) { | 1417 | if (qc && (qc->flags & ATA_QCFLAG_ACTIVE)) { |
| 1412 | VPRINTK("port %u IRQ found for qc, " | 1418 | VPRINTK("port %u IRQ found for qc, " |
| 1413 | "ata_status 0x%x\n", port,ata_status); | 1419 | "ata_status 0x%x\n", port,ata_status); |
| 1414 | /* mark qc status appropriately */ | 1420 | /* mark qc status appropriately */ |
