aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-04-07 09:47:19 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-17 15:44:22 -0400
commit9dadd45b24145d6aee2fabb28d7aef972301892b (patch)
treec97c323e2edd400bc94eaceddf20f84e9a6da005 /drivers
parenta89611e8489ac24f371c9fd6fef6605b170b16ba (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')
-rw-r--r--drivers/ata/ahci.c35
-rw-r--r--drivers/ata/ata_piix.c2
-rw-r--r--drivers/ata/libata-core.c50
-rw-r--r--drivers/ata/libata-pmp.c7
-rw-r--r--drivers/ata/libata-sff.c49
5 files changed, 83 insertions, 60 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 7e251a2cbda5..0f553aaa6f79 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,
1343static int ahci_hardreset(struct ata_link *link, unsigned int *class, 1343static 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
1402static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, 1406static 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
1446static void ahci_postreset(struct ata_link *link, unsigned int *class) 1451static void ahci_postreset(struct ata_link *link, unsigned int *class)
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 7ab76a413cdf..f59a55bfade4 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -1022,7 +1022,7 @@ static int piix_sidpr_hardreset(struct ata_link *link, unsigned int *class,
1022 int rc; 1022 int rc;
1023 1023
1024 /* do hardreset */ 1024 /* do hardreset */
1025 rc = sata_link_hardreset(link, timing, deadline); 1025 rc = sata_link_hardreset(link, timing, deadline, NULL, NULL);
1026 if (rc) { 1026 if (rc) {
1027 ata_link_printk(link, KERN_ERR, 1027 ata_link_printk(link, KERN_ERR,
1028 "COMRESET failed (errno=%d)\n", rc); 1028 "COMRESET failed (errno=%d)\n", rc);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3bad6f189190..b607292b6480 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3557,8 +3557,18 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline)
3557 * @link: link to reset 3557 * @link: link to reset
3558 * @timing: timing parameters { interval, duratinon, timeout } in msec 3558 * @timing: timing parameters { interval, duratinon, timeout } in msec
3559 * @deadline: deadline jiffies for the operation 3559 * @deadline: deadline jiffies for the operation
3560 * @online: optional out parameter indicating link onlineness
3561 * @check_ready: optional callback to check link readiness
3560 * 3562 *
3561 * SATA phy-reset @link using DET bits of SControl register. 3563 * SATA phy-reset @link using DET bits of SControl register.
3564 * After hardreset, link readiness is waited upon using
3565 * ata_wait_ready() if @check_ready is specified. LLDs are
3566 * allowed to not specify @check_ready and wait itself after this
3567 * function returns. Device classification is LLD's
3568 * responsibility.
3569 *
3570 * *@online is set to one iff reset succeeded and @link is online
3571 * after reset.
3562 * 3572 *
3563 * LOCKING: 3573 * LOCKING:
3564 * Kernel thread context (may sleep) 3574 * Kernel thread context (may sleep)
@@ -3567,13 +3577,17 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline)
3567 * 0 on success, -errno otherwise. 3577 * 0 on success, -errno otherwise.
3568 */ 3578 */
3569int sata_link_hardreset(struct ata_link *link, const unsigned long *timing, 3579int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
3570 unsigned long deadline) 3580 unsigned long deadline,
3581 bool *online, int (*check_ready)(struct ata_link *))
3571{ 3582{
3572 u32 scontrol; 3583 u32 scontrol;
3573 int rc; 3584 int rc;
3574 3585
3575 DPRINTK("ENTER\n"); 3586 DPRINTK("ENTER\n");
3576 3587
3588 if (online)
3589 *online = false;
3590
3577 if (sata_set_spd_needed(link)) { 3591 if (sata_set_spd_needed(link)) {
3578 /* SATA spec says nothing about how to reconfigure 3592 /* SATA spec says nothing about how to reconfigure
3579 * spd. To be on the safe side, turn off phy during 3593 * spd. To be on the safe side, turn off phy during
@@ -3607,7 +3621,41 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
3607 3621
3608 /* bring link back */ 3622 /* bring link back */
3609 rc = sata_link_resume(link, timing, deadline); 3623 rc = sata_link_resume(link, timing, deadline);
3624 if (rc)
3625 goto out;
3626 /* if link is offline nothing more to do */
3627 if (ata_link_offline(link))
3628 goto out;
3629
3630 /* Link is online. From this point, -ENODEV too is an error. */
3631 if (online)
3632 *online = true;
3633
3634 if ((link->ap->flags & ATA_FLAG_PMP) && ata_is_host_link(link)) {
3635 /* If PMP is supported, we have to do follow-up SRST.
3636 * Some PMPs don't send D2H Reg FIS after hardreset if
3637 * the first port is empty. Wait only for
3638 * ATA_TMOUT_PMP_SRST_WAIT.
3639 */
3640 if (check_ready) {
3641 unsigned long pmp_deadline;
3642
3643 pmp_deadline = jiffies + ATA_TMOUT_PMP_SRST_WAIT;
3644 if (time_after(pmp_deadline, deadline))
3645 pmp_deadline = deadline;
3646 ata_wait_ready(link, pmp_deadline, check_ready);
3647 }
3648 rc = -EAGAIN;
3649 goto out;
3650 }
3651
3652 rc = 0;
3653 if (check_ready)
3654 rc = ata_wait_ready(link, deadline, check_ready);
3610 out: 3655 out:
3656 if (rc && rc != -EAGAIN)
3657 ata_link_printk(link, KERN_ERR,
3658 "COMRESET failed (errno=%d)\n", rc);
3611 DPRINTK("EXIT, rc=%d\n", rc); 3659 DPRINTK("EXIT, rc=%d\n", rc);
3612 return rc; 3660 return rc;
3613} 3661}
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index a7cb1498c9b2..7f1a87f01ab2 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -239,13 +239,14 @@ int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class,
239 unsigned long deadline) 239 unsigned long deadline)
240{ 240{
241 const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); 241 const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
242 bool online;
242 u32 tmp; 243 u32 tmp;
243 int rc; 244 int rc;
244 245
245 DPRINTK("ENTER\n"); 246 DPRINTK("ENTER\n");
246 247
247 /* do hardreset */ 248 /* do hardreset */
248 rc = sata_link_hardreset(link, timing, deadline); 249 rc = sata_link_hardreset(link, timing, deadline, &online, NULL);
249 if (rc) { 250 if (rc) {
250 ata_link_printk(link, KERN_ERR, 251 ata_link_printk(link, KERN_ERR,
251 "COMRESET failed (errno=%d)\n", rc); 252 "COMRESET failed (errno=%d)\n", rc);
@@ -261,7 +262,7 @@ int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class,
261 } 262 }
262 263
263 /* if device is present, follow up with srst to wait for !BSY */ 264 /* if device is present, follow up with srst to wait for !BSY */
264 if (ata_link_online(link)) 265 if (online)
265 rc = -EAGAIN; 266 rc = -EAGAIN;
266 out: 267 out:
267 /* if SCR isn't accessible, we need to reset the PMP */ 268 /* if SCR isn't accessible, we need to reset the PMP */
@@ -916,7 +917,7 @@ static int sata_pmp_eh_handle_disabled_links(struct ata_port *ap)
916 * SError.N working. 917 * SError.N working.
917 */ 918 */
918 sata_link_hardreset(link, sata_deb_timing_normal, 919 sata_link_hardreset(link, sata_deb_timing_normal,
919 jiffies + ATA_TMOUT_INTERNAL_QUICK); 920 jiffies + ATA_TMOUT_INTERNAL_QUICK, NULL, NULL);
920 921
921 /* unconditionally clear SError.N */ 922 /* unconditionally clear SError.N */
922 rc = sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG); 923 rc = sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG);
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 78912c5011ad..0b97e84d3af6 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -1921,50 +1921,19 @@ int ata_sff_softreset(struct ata_link *link, unsigned int *classes,
1921int sata_sff_hardreset(struct ata_link *link, unsigned int *class, 1921int sata_sff_hardreset(struct ata_link *link, unsigned int *class,
1922 unsigned long deadline) 1922 unsigned long deadline)
1923{ 1923{
1924 struct ata_port *ap = link->ap; 1924 struct ata_eh_context *ehc = &link->eh_context;
1925 const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); 1925 const unsigned long *timing = sata_ehc_deb_timing(ehc);
1926 bool online;
1926 int rc; 1927 int rc;
1927 1928
1928 DPRINTK("ENTER\n"); 1929 rc = sata_link_hardreset(link, timing, deadline, &online,
1929 1930 ata_sff_check_ready);
1930 /* do hardreset */ 1931 *class = ATA_DEV_NONE;
1931 rc = sata_link_hardreset(link, timing, deadline); 1932 if (online)
1932 if (rc) { 1933 *class = ata_sff_dev_classify(link->device, 1, NULL);
1933 ata_link_printk(link, KERN_ERR,
1934 "COMRESET failed (errno=%d)\n", rc);
1935 return rc;
1936 }
1937
1938 /* TODO: phy layer with polling, timeouts, etc. */
1939 if (ata_link_offline(link)) {
1940 *class = ATA_DEV_NONE;
1941 DPRINTK("EXIT, link offline\n");
1942 return 0;
1943 }
1944
1945 /* If PMP is supported, we have to do follow-up SRST. Note
1946 * that some PMPs don't send D2H Reg FIS after hardreset at
1947 * all if the first port is empty. Wait for it just for a
1948 * second and request follow-up SRST.
1949 */
1950 if (ap->flags & ATA_FLAG_PMP) {
1951 ata_sff_wait_after_reset(link, 1, jiffies + HZ);
1952 return -EAGAIN;
1953 }
1954
1955 /* wait for the link to become online */
1956 rc = ata_sff_wait_after_reset(link, 1, deadline);
1957 /* link occupied, -ENODEV too is an error */
1958 if (rc) {
1959 ata_link_printk(link, KERN_ERR,
1960 "COMRESET failed (errno=%d)\n", rc);
1961 return rc;
1962 }
1963
1964 *class = ata_sff_dev_classify(link->device, 1, NULL);
1965 1934
1966 DPRINTK("EXIT, class=%u\n", *class); 1935 DPRINTK("EXIT, class=%u\n", *class);
1967 return 0; 1936 return rc;
1968} 1937}
1969 1938
1970/** 1939/**