Commit ea3c64506ea7965f86f030155e6fdef381de10e2
Committed by
Jeff Garzik
1 parent
e2f3d75fc0
Exists in
master
and in
4 other branches
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>
Showing 3 changed files with 31 additions and 12 deletions Side-by-side Diff
drivers/ata/libata-sff.c
... | ... | @@ -1045,7 +1045,8 @@ |
1045 | 1045 | int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, |
1046 | 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 | 1050 | unsigned long flags = 0; |
1050 | 1051 | int poll_next; |
1051 | 1052 | |
1052 | 1053 | |
... | ... | @@ -1301,8 +1302,14 @@ |
1301 | 1302 | } |
1302 | 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 | 1313 | /* may fail if ata_sff_flush_pio_task() in progress */ |
1307 | 1314 | queue_delayed_work(ata_sff_wq, &ap->sff_pio_task, |
1308 | 1315 | msecs_to_jiffies(delay)); |
1309 | 1316 | |
1310 | 1317 | |
1311 | 1318 | |
... | ... | @@ -1324,14 +1331,18 @@ |
1324 | 1331 | { |
1325 | 1332 | struct ata_port *ap = |
1326 | 1333 | container_of(work, struct ata_port, sff_pio_task.work); |
1334 | + struct ata_link *link = ap->sff_pio_task_link; | |
1327 | 1335 | struct ata_queued_cmd *qc; |
1328 | 1336 | u8 status; |
1329 | 1337 | int poll_next; |
1330 | 1338 | |
1339 | + BUG_ON(ap->sff_pio_task_link == NULL); | |
1331 | 1340 | /* qc can be NULL if timeout occurred */ |
1332 | - qc = ata_qc_from_tag(ap, ap->link.active_tag); | |
1333 | - if (!qc) | |
1341 | + qc = ata_qc_from_tag(ap, link->active_tag); | |
1342 | + if (!qc) { | |
1343 | + ap->sff_pio_task_link = NULL; | |
1334 | 1344 | return; |
1345 | + } | |
1335 | 1346 | |
1336 | 1347 | fsm_start: |
1337 | 1348 | WARN_ON_ONCE(ap->hsm_task_state == HSM_ST_IDLE); |
1338 | 1349 | |
... | ... | @@ -1348,11 +1359,16 @@ |
1348 | 1359 | msleep(2); |
1349 | 1360 | status = ata_sff_busy_wait(ap, ATA_BUSY, 10); |
1350 | 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 | 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 | 1372 | /* move the HSM */ |
1357 | 1373 | poll_next = ata_sff_hsm_move(ap, qc, status, 1); |
1358 | 1374 | |
... | ... | @@ -1379,6 +1395,7 @@ |
1379 | 1395 | unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc) |
1380 | 1396 | { |
1381 | 1397 | struct ata_port *ap = qc->ap; |
1398 | + struct ata_link *link = qc->dev->link; | |
1382 | 1399 | |
1383 | 1400 | /* Use polling pio if the LLD doesn't handle |
1384 | 1401 | * interrupt driven pio and atapi CDB interrupt. |
... | ... | @@ -1399,7 +1416,7 @@ |
1399 | 1416 | ap->hsm_task_state = HSM_ST_LAST; |
1400 | 1417 | |
1401 | 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 | 1421 | break; |
1405 | 1422 | |
... | ... | @@ -1412,7 +1429,7 @@ |
1412 | 1429 | if (qc->tf.flags & ATA_TFLAG_WRITE) { |
1413 | 1430 | /* PIO data out protocol */ |
1414 | 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 | 1434 | /* always send first data block using the |
1418 | 1435 | * ata_sff_pio_task() codepath. |
... | ... | @@ -1422,7 +1439,7 @@ |
1422 | 1439 | ap->hsm_task_state = HSM_ST; |
1423 | 1440 | |
1424 | 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 | 1444 | /* if polling, ata_sff_pio_task() handles the |
1428 | 1445 | * rest. otherwise, interrupt handler takes |
... | ... | @@ -1444,7 +1461,7 @@ |
1444 | 1461 | /* send cdb by polling if no cdb interrupt */ |
1445 | 1462 | if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) || |
1446 | 1463 | (qc->tf.flags & ATA_TFLAG_POLLING)) |
1447 | - ata_sff_queue_pio_task(ap, 0); | |
1464 | + ata_sff_queue_pio_task(link, 0); | |
1448 | 1465 | break; |
1449 | 1466 | |
1450 | 1467 | default: |
... | ... | @@ -2737,6 +2754,7 @@ |
2737 | 2754 | unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) |
2738 | 2755 | { |
2739 | 2756 | struct ata_port *ap = qc->ap; |
2757 | + struct ata_link *link = qc->dev->link; | |
2740 | 2758 | |
2741 | 2759 | /* defer PIO handling to sff_qc_issue */ |
2742 | 2760 | if (!ata_is_dma(qc->tf.protocol)) |
... | ... | @@ -2765,7 +2783,7 @@ |
2765 | 2783 | |
2766 | 2784 | /* send cdb by polling if no cdb interrupt */ |
2767 | 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 | 2787 | break; |
2770 | 2788 | |
2771 | 2789 | default: |
drivers/ata/sata_mv.c
include/linux/libata.h
... | ... | @@ -724,6 +724,7 @@ |
724 | 724 | struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ |
725 | 725 | u8 ctl; /* cache of ATA control register */ |
726 | 726 | u8 last_ctl; /* Cache last written value */ |
727 | + struct ata_link* sff_pio_task_link; /* link currently used */ | |
727 | 728 | struct delayed_work sff_pio_task; |
728 | 729 | #ifdef CONFIG_ATA_BMDMA |
729 | 730 | struct ata_bmdma_prd *bmdma_prd; /* BMDMA SG list */ |
... | ... | @@ -1595,7 +1596,7 @@ |
1595 | 1596 | extern void ata_sff_irq_clear(struct ata_port *ap); |
1596 | 1597 | extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, |
1597 | 1598 | u8 status, int in_wq); |
1598 | -extern void ata_sff_queue_pio_task(struct ata_port *ap, unsigned long delay); | |
1599 | +extern void ata_sff_queue_pio_task(struct ata_link *link, unsigned long delay); | |
1599 | 1600 | extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc); |
1600 | 1601 | extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc); |
1601 | 1602 | extern unsigned int ata_sff_port_intr(struct ata_port *ap, |