aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sata_mv.c
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-03-29 19:59:39 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-29 19:59:39 -0500
commit4f0e7c51ae392d841be395a9c6b8d26a9fbf33d2 (patch)
tree664564736e52a88e14d9c699c5c723b89785f4cb /drivers/scsi/sata_mv.c
parent74d89c16735d83349ea74232031819e989a49156 (diff)
parent55d8ca4f8094246da6e71889a4e04bfafaa78b10 (diff)
Merge branch 'upstream'
Conflicts: drivers/scsi/sata_mv.c
Diffstat (limited to 'drivers/scsi/sata_mv.c')
-rw-r--r--drivers/scsi/sata_mv.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 2819a75c4a84..4d965601efcf 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,21 +1372,29 @@ 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 && (ap->flags & ATA_FLAG_PORT_DISABLED)) 1400 if (ap && (ap->flags & ATA_FLAG_PORT_DISABLED))
@@ -1402,12 +1409,12 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
1402 if ((PORT0_ERR << shift) & relevant) { 1409 if ((PORT0_ERR << shift) & relevant) {
1403 mv_err_intr(ap); 1410 mv_err_intr(ap);
1404 err_mask |= AC_ERR_OTHER; 1411 err_mask |= AC_ERR_OTHER;
1405 handled++; 1412 handled = 1;
1406 } 1413 }
1407 1414
1408 if (handled && ap) { 1415 if (handled) {
1409 qc = ata_qc_from_tag(ap, ap->active_tag); 1416 qc = ata_qc_from_tag(ap, ap->active_tag);
1410 if (NULL != qc) { 1417 if (qc && (qc->flags & ATA_QCFLAG_ACTIVE)) {
1411 VPRINTK("port %u IRQ found for qc, " 1418 VPRINTK("port %u IRQ found for qc, "
1412 "ata_status 0x%x\n", port,ata_status); 1419 "ata_status 0x%x\n", port,ata_status);
1413 /* mark qc status appropriately */ 1420 /* mark qc status appropriately */