diff options
author | Tejun Heo <htejun@gmail.com> | 2008-04-07 09:47:19 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-17 15:44:22 -0400 |
commit | 9dadd45b24145d6aee2fabb28d7aef972301892b (patch) | |
tree | c97c323e2edd400bc94eaceddf20f84e9a6da005 /drivers/ata/ahci.c | |
parent | a89611e8489ac24f371c9fd6fef6605b170b16ba (diff) |
libata: move generic hardreset code from sata_sff_hardreset() to sata_link_hardreset()
sata_sff_hardreset() contains link readiness wait logic which isn't
SFF specific. Move that part into sata_link_hardreset(), which now
takes two more parameters - @online and @check_ready. Both are
optional. The former is out parameter for link onlineness after
reset. The latter is used to wait for link readiness after hardreset.
Users of sata_link_hardreset() is updated to use new funtionality and
ahci_hardreset() is updated to use sata_link_hardreset() instead of
sata_sff_hardreset(). This doesn't really cause any behavior change.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 7e251a2cbda..0f553aaa6f7 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1343,10 +1343,12 @@ static int ahci_softreset(struct ata_link *link, unsigned int *class, | |||
1343 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, | 1343 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, |
1344 | unsigned long deadline) | 1344 | unsigned long deadline) |
1345 | { | 1345 | { |
1346 | const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); | ||
1346 | struct ata_port *ap = link->ap; | 1347 | struct ata_port *ap = link->ap; |
1347 | struct ahci_port_priv *pp = ap->private_data; | 1348 | struct ahci_port_priv *pp = ap->private_data; |
1348 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | 1349 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; |
1349 | struct ata_taskfile tf; | 1350 | struct ata_taskfile tf; |
1351 | bool online; | ||
1350 | int rc; | 1352 | int rc; |
1351 | 1353 | ||
1352 | DPRINTK("ENTER\n"); | 1354 | DPRINTK("ENTER\n"); |
@@ -1358,14 +1360,14 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class, | |||
1358 | tf.command = 0x80; | 1360 | tf.command = 0x80; |
1359 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); | 1361 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); |
1360 | 1362 | ||
1361 | rc = sata_sff_hardreset(link, class, deadline); | 1363 | rc = sata_link_hardreset(link, timing, deadline, &online, |
1364 | ahci_check_ready); | ||
1362 | 1365 | ||
1363 | ahci_start_engine(ap); | 1366 | ahci_start_engine(ap); |
1364 | 1367 | ||
1365 | if (rc == 0 && ata_link_online(link)) | 1368 | *class = ATA_DEV_NONE; |
1369 | if (online) | ||
1366 | *class = ahci_dev_classify(ap); | 1370 | *class = ahci_dev_classify(ap); |
1367 | if (rc != -EAGAIN && *class == ATA_DEV_UNKNOWN) | ||
1368 | *class = ATA_DEV_NONE; | ||
1369 | 1371 | ||
1370 | DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); | 1372 | DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class); |
1371 | return rc; | 1373 | return rc; |
@@ -1376,6 +1378,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | |||
1376 | { | 1378 | { |
1377 | struct ata_port *ap = link->ap; | 1379 | struct ata_port *ap = link->ap; |
1378 | u32 serror; | 1380 | u32 serror; |
1381 | bool online; | ||
1379 | int rc; | 1382 | int rc; |
1380 | 1383 | ||
1381 | DPRINTK("ENTER\n"); | 1384 | DPRINTK("ENTER\n"); |
@@ -1383,7 +1386,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | |||
1383 | ahci_stop_engine(ap); | 1386 | ahci_stop_engine(ap); |
1384 | 1387 | ||
1385 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), | 1388 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), |
1386 | deadline); | 1389 | deadline, &online, NULL); |
1387 | 1390 | ||
1388 | /* vt8251 needs SError cleared for the port to operate */ | 1391 | /* vt8251 needs SError cleared for the port to operate */ |
1389 | ahci_scr_read(ap, SCR_ERROR, &serror); | 1392 | ahci_scr_read(ap, SCR_ERROR, &serror); |
@@ -1396,7 +1399,8 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | |||
1396 | /* vt8251 doesn't clear BSY on signature FIS reception, | 1399 | /* vt8251 doesn't clear BSY on signature FIS reception, |
1397 | * request follow-up softreset. | 1400 | * request follow-up softreset. |
1398 | */ | 1401 | */ |
1399 | return rc ?: -EAGAIN; | 1402 | *class = ATA_DEV_NONE; |
1403 | return online ? -EAGAIN : rc; | ||
1400 | } | 1404 | } |
1401 | 1405 | ||
1402 | static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | 1406 | static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, |
@@ -1406,6 +1410,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | |||
1406 | struct ahci_port_priv *pp = ap->private_data; | 1410 | struct ahci_port_priv *pp = ap->private_data; |
1407 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | 1411 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; |
1408 | struct ata_taskfile tf; | 1412 | struct ata_taskfile tf; |
1413 | bool online; | ||
1409 | int rc; | 1414 | int rc; |
1410 | 1415 | ||
1411 | ahci_stop_engine(ap); | 1416 | ahci_stop_engine(ap); |
@@ -1416,13 +1421,10 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | |||
1416 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); | 1421 | ata_tf_to_fis(&tf, 0, 0, d2h_fis); |
1417 | 1422 | ||
1418 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), | 1423 | rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), |
1419 | deadline); | 1424 | deadline, &online, NULL); |
1420 | 1425 | ||
1421 | ahci_start_engine(ap); | 1426 | ahci_start_engine(ap); |
1422 | 1427 | ||
1423 | if (rc || ata_link_offline(link)) | ||
1424 | return rc; | ||
1425 | |||
1426 | /* The pseudo configuration device on SIMG4726 attached to | 1428 | /* The pseudo configuration device on SIMG4726 attached to |
1427 | * ASUS P5W-DH Deluxe doesn't send signature FIS after | 1429 | * ASUS P5W-DH Deluxe doesn't send signature FIS after |
1428 | * hardreset if no device is attached to the first downstream | 1430 | * hardreset if no device is attached to the first downstream |
@@ -1436,11 +1438,14 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, | |||
1436 | * have to be reset again. For most cases, this should | 1438 | * have to be reset again. For most cases, this should |
1437 | * suffice while making probing snappish enough. | 1439 | * suffice while making probing snappish enough. |
1438 | */ | 1440 | */ |
1439 | rc = ata_wait_after_reset(link, jiffies + 2 * HZ, ahci_check_ready); | 1441 | if (online) { |
1440 | if (rc) | 1442 | rc = ata_wait_after_reset(link, jiffies + 2 * HZ, |
1441 | ahci_kick_engine(ap, 0); | 1443 | ahci_check_ready); |
1442 | 1444 | if (rc) | |
1443 | return 0; | 1445 | ahci_kick_engine(ap, 0); |
1446 | } | ||
1447 | *class = ATA_DEV_NONE; | ||
1448 | return rc; | ||
1444 | } | 1449 | } |
1445 | 1450 | ||
1446 | static void ahci_postreset(struct ata_link *link, unsigned int *class) | 1451 | static void ahci_postreset(struct ata_link *link, unsigned int *class) |