diff options
author | Gwendal Grignou <gwendal@google.com> | 2010-08-31 19:20:36 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2010-09-09 22:31:55 -0400 |
commit | ea3c64506ea7965f86f030155e6fdef381de10e2 (patch) | |
tree | e98d1fbe34fd0c1c81d0fb08b3314f6f059eb494 /drivers/ata | |
parent | e2f3d75fc0e4a0d03c61872bad39ffa2e74a04ff (diff) |
libata-sff: Reenable Port Multiplier after libata-sff remodeling.
Keep track of the link on the which the current request is in progress.
It allows support of links behind port multiplier.
Not all libata-sff is PMP compliant. Code for native BMDMA controller
does not take in accound PMP.
Tested on Marvell 7042 and Sil7526.
Signed-off-by: Gwendal Grignou <gwendal@google.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-sff.c | 38 | ||||
-rw-r--r-- | drivers/ata/sata_mv.c | 2 |
2 files changed, 29 insertions, 11 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index dee3c2c5256..e30c537cce3 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -1045,7 +1045,8 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq) | |||
1045 | int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, | 1045 | int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, |
1046 | u8 status, int in_wq) | 1046 | u8 status, int in_wq) |
1047 | { | 1047 | { |
1048 | struct ata_eh_info *ehi = &ap->link.eh_info; | 1048 | struct ata_link *link = qc->dev->link; |
1049 | struct ata_eh_info *ehi = &link->eh_info; | ||
1049 | unsigned long flags = 0; | 1050 | unsigned long flags = 0; |
1050 | int poll_next; | 1051 | int poll_next; |
1051 | 1052 | ||
@@ -1301,8 +1302,14 @@ fsm_start: | |||
1301 | } | 1302 | } |
1302 | EXPORT_SYMBOL_GPL(ata_sff_hsm_move); | 1303 | EXPORT_SYMBOL_GPL(ata_sff_hsm_move); |
1303 | 1304 | ||
1304 | void ata_sff_queue_pio_task(struct ata_port *ap, unsigned long delay) | 1305 | void ata_sff_queue_pio_task(struct ata_link *link, unsigned long delay) |
1305 | { | 1306 | { |
1307 | struct ata_port *ap = link->ap; | ||
1308 | |||
1309 | WARN_ON((ap->sff_pio_task_link != NULL) && | ||
1310 | (ap->sff_pio_task_link != link)); | ||
1311 | ap->sff_pio_task_link = link; | ||
1312 | |||
1306 | /* may fail if ata_sff_flush_pio_task() in progress */ | 1313 | /* may fail if ata_sff_flush_pio_task() in progress */ |
1307 | queue_delayed_work(ata_sff_wq, &ap->sff_pio_task, | 1314 | queue_delayed_work(ata_sff_wq, &ap->sff_pio_task, |
1308 | msecs_to_jiffies(delay)); | 1315 | msecs_to_jiffies(delay)); |
@@ -1324,14 +1331,18 @@ static void ata_sff_pio_task(struct work_struct *work) | |||
1324 | { | 1331 | { |
1325 | struct ata_port *ap = | 1332 | struct ata_port *ap = |
1326 | container_of(work, struct ata_port, sff_pio_task.work); | 1333 | container_of(work, struct ata_port, sff_pio_task.work); |
1334 | struct ata_link *link = ap->sff_pio_task_link; | ||
1327 | struct ata_queued_cmd *qc; | 1335 | struct ata_queued_cmd *qc; |
1328 | u8 status; | 1336 | u8 status; |
1329 | int poll_next; | 1337 | int poll_next; |
1330 | 1338 | ||
1339 | BUG_ON(ap->sff_pio_task_link == NULL); | ||
1331 | /* qc can be NULL if timeout occurred */ | 1340 | /* qc can be NULL if timeout occurred */ |
1332 | qc = ata_qc_from_tag(ap, ap->link.active_tag); | 1341 | qc = ata_qc_from_tag(ap, link->active_tag); |
1333 | if (!qc) | 1342 | if (!qc) { |
1343 | ap->sff_pio_task_link = NULL; | ||
1334 | return; | 1344 | return; |
1345 | } | ||
1335 | 1346 | ||
1336 | fsm_start: | 1347 | fsm_start: |
1337 | WARN_ON_ONCE(ap->hsm_task_state == HSM_ST_IDLE); | 1348 | WARN_ON_ONCE(ap->hsm_task_state == HSM_ST_IDLE); |
@@ -1348,11 +1359,16 @@ fsm_start: | |||
1348 | msleep(2); | 1359 | msleep(2); |
1349 | status = ata_sff_busy_wait(ap, ATA_BUSY, 10); | 1360 | status = ata_sff_busy_wait(ap, ATA_BUSY, 10); |
1350 | if (status & ATA_BUSY) { | 1361 | if (status & ATA_BUSY) { |
1351 | ata_sff_queue_pio_task(ap, ATA_SHORT_PAUSE); | 1362 | ata_sff_queue_pio_task(link, ATA_SHORT_PAUSE); |
1352 | return; | 1363 | return; |
1353 | } | 1364 | } |
1354 | } | 1365 | } |
1355 | 1366 | ||
1367 | /* | ||
1368 | * hsm_move() may trigger another command to be processed. | ||
1369 | * clean the link beforehand. | ||
1370 | */ | ||
1371 | ap->sff_pio_task_link = NULL; | ||
1356 | /* move the HSM */ | 1372 | /* move the HSM */ |
1357 | poll_next = ata_sff_hsm_move(ap, qc, status, 1); | 1373 | poll_next = ata_sff_hsm_move(ap, qc, status, 1); |
1358 | 1374 | ||
@@ -1379,6 +1395,7 @@ fsm_start: | |||
1379 | unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) | 1395 | unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) |
1380 | { | 1396 | { |
1381 | struct ata_port *ap = qc->ap; | 1397 | struct ata_port *ap = qc->ap; |
1398 | struct ata_link *link = qc->dev->link; | ||
1382 | 1399 | ||
1383 | /* Use polling pio if the LLD doesn't handle | 1400 | /* Use polling pio if the LLD doesn't handle |
1384 | * interrupt driven pio and atapi CDB interrupt. | 1401 | * interrupt driven pio and atapi CDB interrupt. |
@@ -1399,7 +1416,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) | |||
1399 | ap->hsm_task_state = HSM_ST_LAST; | 1416 | ap->hsm_task_state = HSM_ST_LAST; |
1400 | 1417 | ||
1401 | if (qc->tf.flags & ATA_TFLAG_POLLING) | 1418 | if (qc->tf.flags & ATA_TFLAG_POLLING) |
1402 | ata_sff_queue_pio_task(ap, 0); | 1419 | ata_sff_queue_pio_task(link, 0); |
1403 | 1420 | ||
1404 | break; | 1421 | break; |
1405 | 1422 | ||
@@ -1412,7 +1429,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) | |||
1412 | if (qc->tf.flags & ATA_TFLAG_WRITE) { | 1429 | if (qc->tf.flags & ATA_TFLAG_WRITE) { |
1413 | /* PIO data out protocol */ | 1430 | /* PIO data out protocol */ |
1414 | ap->hsm_task_state = HSM_ST_FIRST; | 1431 | ap->hsm_task_state = HSM_ST_FIRST; |
1415 | ata_sff_queue_pio_task(ap, 0); | 1432 | ata_sff_queue_pio_task(link, 0); |
1416 | 1433 | ||
1417 | /* always send first data block using the | 1434 | /* always send first data block using the |
1418 | * ata_sff_pio_task() codepath. | 1435 | * ata_sff_pio_task() codepath. |
@@ -1422,7 +1439,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) | |||
1422 | ap->hsm_task_state = HSM_ST; | 1439 | ap->hsm_task_state = HSM_ST; |
1423 | 1440 | ||
1424 | if (qc->tf.flags & ATA_TFLAG_POLLING) | 1441 | if (qc->tf.flags & ATA_TFLAG_POLLING) |
1425 | ata_sff_queue_pio_task(ap, 0); | 1442 | ata_sff_queue_pio_task(link, 0); |
1426 | 1443 | ||
1427 | /* if polling, ata_sff_pio_task() handles the | 1444 | /* if polling, ata_sff_pio_task() handles the |
1428 | * rest. otherwise, interrupt handler takes | 1445 | * rest. otherwise, interrupt handler takes |
@@ -1444,7 +1461,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) | |||
1444 | /* send cdb by polling if no cdb interrupt */ | 1461 | /* send cdb by polling if no cdb interrupt */ |
1445 | if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) || | 1462 | if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) || |
1446 | (qc->tf.flags & ATA_TFLAG_POLLING)) | 1463 | (qc->tf.flags & ATA_TFLAG_POLLING)) |
1447 | ata_sff_queue_pio_task(ap, 0); | 1464 | ata_sff_queue_pio_task(link, 0); |
1448 | break; | 1465 | break; |
1449 | 1466 | ||
1450 | default: | 1467 | default: |
@@ -2737,6 +2754,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_dumb_qc_prep); | |||
2737 | unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) | 2754 | unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) |
2738 | { | 2755 | { |
2739 | struct ata_port *ap = qc->ap; | 2756 | struct ata_port *ap = qc->ap; |
2757 | struct ata_link *link = qc->dev->link; | ||
2740 | 2758 | ||
2741 | /* defer PIO handling to sff_qc_issue */ | 2759 | /* defer PIO handling to sff_qc_issue */ |
2742 | if (!ata_is_dma(qc->tf.protocol)) | 2760 | if (!ata_is_dma(qc->tf.protocol)) |
@@ -2765,7 +2783,7 @@ unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) | |||
2765 | 2783 | ||
2766 | /* send cdb by polling if no cdb interrupt */ | 2784 | /* send cdb by polling if no cdb interrupt */ |
2767 | if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) | 2785 | if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) |
2768 | ata_sff_queue_pio_task(ap, 0); | 2786 | ata_sff_queue_pio_task(link, 0); |
2769 | break; | 2787 | break; |
2770 | 2788 | ||
2771 | default: | 2789 | default: |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 81982594a01..a9fd9709c26 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -2284,7 +2284,7 @@ static unsigned int mv_qc_issue_fis(struct ata_queued_cmd *qc) | |||
2284 | } | 2284 | } |
2285 | 2285 | ||
2286 | if (qc->tf.flags & ATA_TFLAG_POLLING) | 2286 | if (qc->tf.flags & ATA_TFLAG_POLLING) |
2287 | ata_sff_queue_pio_task(ap, 0); | 2287 | ata_sff_queue_pio_task(link, 0); |
2288 | return 0; | 2288 | return 0; |
2289 | } | 2289 | } |
2290 | 2290 | ||