diff options
author | Gwendal Grignou <gwendal@google.com> | 2009-10-12 18:44:00 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2009-10-16 06:22:46 -0400 |
commit | 159a7ff7a13f9a02c75006f40c0561a3a81aefcd (patch) | |
tree | 54171cdbd746ea9d5a2efaa87639b14b54dc5034 /drivers/ata/sata_mv.c | |
parent | 6d4f950e9ea15816c6a4f266ce6b9e438346771e (diff) |
sata_mv: Prevent PIO commands to be defered too long if traffic in progress.
Use excl_link when non NCQ commands are defered, to be sure they are processed
as soon as outstanding commands are completed. It prevents some commands to be
defered indifinitely when using a port multiplier.
Signed-off-by: Gwendal Grignou <gwendal@google.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r-- | drivers/ata/sata_mv.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 17f9ff9067a2..6f5093b7c8c5 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -1382,6 +1382,25 @@ static int mv_qc_defer(struct ata_queued_cmd *qc) | |||
1382 | */ | 1382 | */ |
1383 | if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH) | 1383 | if (pp->pp_flags & MV_PP_FLAG_DELAYED_EH) |
1384 | return ATA_DEFER_PORT; | 1384 | return ATA_DEFER_PORT; |
1385 | |||
1386 | /* PIO commands need exclusive link: no other commands [DMA or PIO] | ||
1387 | * can run concurrently. | ||
1388 | * set excl_link when we want to send a PIO command in DMA mode | ||
1389 | * or a non-NCQ command in NCQ mode. | ||
1390 | * When we receive a command from that link, and there are no | ||
1391 | * outstanding commands, mark a flag to clear excl_link and let | ||
1392 | * the command go through. | ||
1393 | */ | ||
1394 | if (unlikely(ap->excl_link)) { | ||
1395 | if (link == ap->excl_link) { | ||
1396 | if (ap->nr_active_links) | ||
1397 | return ATA_DEFER_PORT; | ||
1398 | qc->flags |= ATA_QCFLAG_CLEAR_EXCL; | ||
1399 | return 0; | ||
1400 | } else | ||
1401 | return ATA_DEFER_PORT; | ||
1402 | } | ||
1403 | |||
1385 | /* | 1404 | /* |
1386 | * If the port is completely idle, then allow the new qc. | 1405 | * If the port is completely idle, then allow the new qc. |
1387 | */ | 1406 | */ |
@@ -1395,8 +1414,14 @@ static int mv_qc_defer(struct ata_queued_cmd *qc) | |||
1395 | * doesn't allow it. | 1414 | * doesn't allow it. |
1396 | */ | 1415 | */ |
1397 | if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) && | 1416 | if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) && |
1398 | (pp->pp_flags & MV_PP_FLAG_NCQ_EN) && ata_is_ncq(qc->tf.protocol)) | 1417 | (pp->pp_flags & MV_PP_FLAG_NCQ_EN)) { |
1399 | return 0; | 1418 | if (ata_is_ncq(qc->tf.protocol)) |
1419 | return 0; | ||
1420 | else { | ||
1421 | ap->excl_link = link; | ||
1422 | return ATA_DEFER_PORT; | ||
1423 | } | ||
1424 | } | ||
1400 | 1425 | ||
1401 | return ATA_DEFER_PORT; | 1426 | return ATA_DEFER_PORT; |
1402 | } | 1427 | } |