diff options
author | Tejun Heo <htejun@gmail.com> | 2006-05-15 07:57:47 -0400 |
---|---|---|
committer | Tejun Heo <htejun@gmail.com> | 2006-05-15 07:57:47 -0400 |
commit | 81952c5497b40ae56835bd0d6537f8c6bdea07e7 (patch) | |
tree | fa2db695c56e481c271c7249197ad3b4a98b6087 /drivers/scsi/libata-core.c | |
parent | 34bf21704c848fe00c516d1c8f163db08b70b137 (diff) |
[PATCH] libata: use new SCR and on/offline functions
Use new SCR and on/offline functions. Note that for LLDD which know
it implements SCR callbacks, SCR functions are guaranteed to succeed
and ata_port_online() == !ata_port_offline().
Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r-- | drivers/scsi/libata-core.c | 107 |
1 files changed, 60 insertions, 47 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index b9c5cbf0b786..56f0af208345 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1494,13 +1494,11 @@ static void sata_print_link_status(struct ata_port *ap) | |||
1494 | { | 1494 | { |
1495 | u32 sstatus, scontrol, tmp; | 1495 | u32 sstatus, scontrol, tmp; |
1496 | 1496 | ||
1497 | if (!ap->ops->scr_read) | 1497 | if (sata_scr_read(ap, SCR_STATUS, &sstatus)) |
1498 | return; | 1498 | return; |
1499 | sata_scr_read(ap, SCR_CONTROL, &scontrol); | ||
1499 | 1500 | ||
1500 | sstatus = scr_read(ap, SCR_STATUS); | 1501 | if (ata_port_online(ap)) { |
1501 | scontrol = scr_read(ap, SCR_CONTROL); | ||
1502 | |||
1503 | if (sata_dev_present(ap)) { | ||
1504 | tmp = (sstatus >> 4) & 0xf; | 1502 | tmp = (sstatus >> 4) & 0xf; |
1505 | printk(KERN_INFO | 1503 | printk(KERN_INFO |
1506 | "ata%u: SATA link up %s (SStatus %X SControl %X)\n", | 1504 | "ata%u: SATA link up %s (SStatus %X SControl %X)\n", |
@@ -1531,17 +1529,18 @@ void __sata_phy_reset(struct ata_port *ap) | |||
1531 | 1529 | ||
1532 | if (ap->flags & ATA_FLAG_SATA_RESET) { | 1530 | if (ap->flags & ATA_FLAG_SATA_RESET) { |
1533 | /* issue phy wake/reset */ | 1531 | /* issue phy wake/reset */ |
1534 | scr_write_flush(ap, SCR_CONTROL, 0x301); | 1532 | sata_scr_write_flush(ap, SCR_CONTROL, 0x301); |
1535 | /* Couldn't find anything in SATA I/II specs, but | 1533 | /* Couldn't find anything in SATA I/II specs, but |
1536 | * AHCI-1.1 10.4.2 says at least 1 ms. */ | 1534 | * AHCI-1.1 10.4.2 says at least 1 ms. */ |
1537 | mdelay(1); | 1535 | mdelay(1); |
1538 | } | 1536 | } |
1539 | scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */ | 1537 | /* phy wake/clear reset */ |
1538 | sata_scr_write_flush(ap, SCR_CONTROL, 0x300); | ||
1540 | 1539 | ||
1541 | /* wait for phy to become ready, if necessary */ | 1540 | /* wait for phy to become ready, if necessary */ |
1542 | do { | 1541 | do { |
1543 | msleep(200); | 1542 | msleep(200); |
1544 | sstatus = scr_read(ap, SCR_STATUS); | 1543 | sata_scr_read(ap, SCR_STATUS, &sstatus); |
1545 | if ((sstatus & 0xf) != 1) | 1544 | if ((sstatus & 0xf) != 1) |
1546 | break; | 1545 | break; |
1547 | } while (time_before(jiffies, timeout)); | 1546 | } while (time_before(jiffies, timeout)); |
@@ -1550,7 +1549,7 @@ void __sata_phy_reset(struct ata_port *ap) | |||
1550 | sata_print_link_status(ap); | 1549 | sata_print_link_status(ap); |
1551 | 1550 | ||
1552 | /* TODO: phy layer with polling, timeouts, etc. */ | 1551 | /* TODO: phy layer with polling, timeouts, etc. */ |
1553 | if (sata_dev_present(ap)) | 1552 | if (!ata_port_offline(ap)) |
1554 | ata_port_probe(ap); | 1553 | ata_port_probe(ap); |
1555 | else | 1554 | else |
1556 | ata_port_disable(ap); | 1555 | ata_port_disable(ap); |
@@ -1638,11 +1637,12 @@ void ata_port_disable(struct ata_port *ap) | |||
1638 | */ | 1637 | */ |
1639 | int sata_down_spd_limit(struct ata_port *ap) | 1638 | int sata_down_spd_limit(struct ata_port *ap) |
1640 | { | 1639 | { |
1641 | u32 spd, mask; | 1640 | u32 sstatus, spd, mask; |
1642 | int highbit; | 1641 | int rc, highbit; |
1643 | 1642 | ||
1644 | if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read) | 1643 | rc = sata_scr_read(ap, SCR_STATUS, &sstatus); |
1645 | return -EOPNOTSUPP; | 1644 | if (rc) |
1645 | return rc; | ||
1646 | 1646 | ||
1647 | mask = ap->sata_spd_limit; | 1647 | mask = ap->sata_spd_limit; |
1648 | if (mask <= 1) | 1648 | if (mask <= 1) |
@@ -1650,7 +1650,7 @@ int sata_down_spd_limit(struct ata_port *ap) | |||
1650 | highbit = fls(mask) - 1; | 1650 | highbit = fls(mask) - 1; |
1651 | mask &= ~(1 << highbit); | 1651 | mask &= ~(1 << highbit); |
1652 | 1652 | ||
1653 | spd = (scr_read(ap, SCR_STATUS) >> 4) & 0xf; | 1653 | spd = (sstatus >> 4) & 0xf; |
1654 | if (spd <= 1) | 1654 | if (spd <= 1) |
1655 | return -EINVAL; | 1655 | return -EINVAL; |
1656 | spd--; | 1656 | spd--; |
@@ -1700,11 +1700,9 @@ int sata_set_spd_needed(struct ata_port *ap) | |||
1700 | { | 1700 | { |
1701 | u32 scontrol; | 1701 | u32 scontrol; |
1702 | 1702 | ||
1703 | if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read) | 1703 | if (sata_scr_read(ap, SCR_CONTROL, &scontrol)) |
1704 | return 0; | 1704 | return 0; |
1705 | 1705 | ||
1706 | scontrol = scr_read(ap, SCR_CONTROL); | ||
1707 | |||
1708 | return __sata_set_spd_needed(ap, &scontrol); | 1706 | return __sata_set_spd_needed(ap, &scontrol); |
1709 | } | 1707 | } |
1710 | 1708 | ||
@@ -1719,20 +1717,22 @@ int sata_set_spd_needed(struct ata_port *ap) | |||
1719 | * | 1717 | * |
1720 | * RETURNS: | 1718 | * RETURNS: |
1721 | * 0 if spd doesn't need to be changed, 1 if spd has been | 1719 | * 0 if spd doesn't need to be changed, 1 if spd has been |
1722 | * changed. -EOPNOTSUPP if SCR registers are inaccessible. | 1720 | * changed. Negative errno if SCR registers are inaccessible. |
1723 | */ | 1721 | */ |
1724 | int sata_set_spd(struct ata_port *ap) | 1722 | int sata_set_spd(struct ata_port *ap) |
1725 | { | 1723 | { |
1726 | u32 scontrol; | 1724 | u32 scontrol; |
1725 | int rc; | ||
1727 | 1726 | ||
1728 | if (ap->cbl != ATA_CBL_SATA || !ap->ops->scr_read) | 1727 | if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) |
1729 | return -EOPNOTSUPP; | 1728 | return rc; |
1730 | 1729 | ||
1731 | scontrol = scr_read(ap, SCR_CONTROL); | ||
1732 | if (!__sata_set_spd_needed(ap, &scontrol)) | 1730 | if (!__sata_set_spd_needed(ap, &scontrol)) |
1733 | return 0; | 1731 | return 0; |
1734 | 1732 | ||
1735 | scr_write(ap, SCR_CONTROL, scontrol); | 1733 | if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol))) |
1734 | return rc; | ||
1735 | |||
1736 | return 1; | 1736 | return 1; |
1737 | } | 1737 | } |
1738 | 1738 | ||
@@ -2336,20 +2336,26 @@ static int sata_phy_resume(struct ata_port *ap) | |||
2336 | { | 2336 | { |
2337 | unsigned long timeout = jiffies + (HZ * 5); | 2337 | unsigned long timeout = jiffies + (HZ * 5); |
2338 | u32 scontrol, sstatus; | 2338 | u32 scontrol, sstatus; |
2339 | int rc; | ||
2340 | |||
2341 | if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) | ||
2342 | return rc; | ||
2339 | 2343 | ||
2340 | scontrol = scr_read(ap, SCR_CONTROL); | ||
2341 | scontrol = (scontrol & 0x0f0) | 0x300; | 2344 | scontrol = (scontrol & 0x0f0) | 0x300; |
2342 | scr_write_flush(ap, SCR_CONTROL, scontrol); | 2345 | |
2346 | if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol))) | ||
2347 | return rc; | ||
2343 | 2348 | ||
2344 | /* Wait for phy to become ready, if necessary. */ | 2349 | /* Wait for phy to become ready, if necessary. */ |
2345 | do { | 2350 | do { |
2346 | msleep(200); | 2351 | msleep(200); |
2347 | sstatus = scr_read(ap, SCR_STATUS); | 2352 | if ((rc = sata_scr_read(ap, SCR_STATUS, &sstatus))) |
2353 | return rc; | ||
2348 | if ((sstatus & 0xf) != 1) | 2354 | if ((sstatus & 0xf) != 1) |
2349 | return 0; | 2355 | return 0; |
2350 | } while (time_before(jiffies, timeout)); | 2356 | } while (time_before(jiffies, timeout)); |
2351 | 2357 | ||
2352 | return -1; | 2358 | return -EBUSY; |
2353 | } | 2359 | } |
2354 | 2360 | ||
2355 | /** | 2361 | /** |
@@ -2367,21 +2373,20 @@ static int sata_phy_resume(struct ata_port *ap) | |||
2367 | */ | 2373 | */ |
2368 | void ata_std_probeinit(struct ata_port *ap) | 2374 | void ata_std_probeinit(struct ata_port *ap) |
2369 | { | 2375 | { |
2370 | if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) { | 2376 | u32 scontrol; |
2371 | u32 spd; | ||
2372 | |||
2373 | /* resume link */ | ||
2374 | sata_phy_resume(ap); | ||
2375 | 2377 | ||
2376 | /* init sata_spd_limit to the current value */ | 2378 | /* resume link */ |
2377 | spd = (scr_read(ap, SCR_CONTROL) & 0xf0) >> 4; | 2379 | sata_phy_resume(ap); |
2378 | if (spd) | ||
2379 | ap->sata_spd_limit &= (1 << spd) - 1; | ||
2380 | 2380 | ||
2381 | /* wait for device */ | 2381 | /* init sata_spd_limit to the current value */ |
2382 | if (sata_dev_present(ap)) | 2382 | if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { |
2383 | ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); | 2383 | int spd = (scontrol >> 4) & 0xf; |
2384 | ap->sata_spd_limit &= (1 << spd) - 1; | ||
2384 | } | 2385 | } |
2386 | |||
2387 | /* wait for device */ | ||
2388 | if (ata_port_online(ap)) | ||
2389 | ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); | ||
2385 | } | 2390 | } |
2386 | 2391 | ||
2387 | /** | 2392 | /** |
@@ -2406,7 +2411,7 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes) | |||
2406 | 2411 | ||
2407 | DPRINTK("ENTER\n"); | 2412 | DPRINTK("ENTER\n"); |
2408 | 2413 | ||
2409 | if (ap->ops->scr_read && !sata_dev_present(ap)) { | 2414 | if (ata_port_offline(ap)) { |
2410 | classes[0] = ATA_DEV_NONE; | 2415 | classes[0] = ATA_DEV_NONE; |
2411 | goto out; | 2416 | goto out; |
2412 | } | 2417 | } |
@@ -2457,6 +2462,7 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes) | |||
2457 | int sata_std_hardreset(struct ata_port *ap, unsigned int *class) | 2462 | int sata_std_hardreset(struct ata_port *ap, unsigned int *class) |
2458 | { | 2463 | { |
2459 | u32 scontrol; | 2464 | u32 scontrol; |
2465 | int rc; | ||
2460 | 2466 | ||
2461 | DPRINTK("ENTER\n"); | 2467 | DPRINTK("ENTER\n"); |
2462 | 2468 | ||
@@ -2466,17 +2472,25 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class) | |||
2466 | * reconfiguration. This works for at least ICH7 AHCI | 2472 | * reconfiguration. This works for at least ICH7 AHCI |
2467 | * and Sil3124. | 2473 | * and Sil3124. |
2468 | */ | 2474 | */ |
2469 | scontrol = scr_read(ap, SCR_CONTROL); | 2475 | if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) |
2476 | return rc; | ||
2477 | |||
2470 | scontrol = (scontrol & 0x0f0) | 0x302; | 2478 | scontrol = (scontrol & 0x0f0) | 0x302; |
2471 | scr_write_flush(ap, SCR_CONTROL, scontrol); | 2479 | |
2480 | if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol))) | ||
2481 | return rc; | ||
2472 | 2482 | ||
2473 | sata_set_spd(ap); | 2483 | sata_set_spd(ap); |
2474 | } | 2484 | } |
2475 | 2485 | ||
2476 | /* issue phy wake/reset */ | 2486 | /* issue phy wake/reset */ |
2477 | scontrol = scr_read(ap, SCR_CONTROL); | 2487 | if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) |
2488 | return rc; | ||
2489 | |||
2478 | scontrol = (scontrol & 0x0f0) | 0x301; | 2490 | scontrol = (scontrol & 0x0f0) | 0x301; |
2479 | scr_write_flush(ap, SCR_CONTROL, scontrol); | 2491 | |
2492 | if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol))) | ||
2493 | return rc; | ||
2480 | 2494 | ||
2481 | /* Couldn't find anything in SATA I/II specs, but AHCI-1.1 | 2495 | /* Couldn't find anything in SATA I/II specs, but AHCI-1.1 |
2482 | * 10.4.2 says at least 1 ms. | 2496 | * 10.4.2 says at least 1 ms. |
@@ -2487,7 +2501,7 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class) | |||
2487 | sata_phy_resume(ap); | 2501 | sata_phy_resume(ap); |
2488 | 2502 | ||
2489 | /* TODO: phy layer with polling, timeouts, etc. */ | 2503 | /* TODO: phy layer with polling, timeouts, etc. */ |
2490 | if (!sata_dev_present(ap)) { | 2504 | if (ata_port_offline(ap)) { |
2491 | *class = ATA_DEV_NONE; | 2505 | *class = ATA_DEV_NONE; |
2492 | DPRINTK("EXIT, link offline\n"); | 2506 | DPRINTK("EXIT, link offline\n"); |
2493 | return 0; | 2507 | return 0; |
@@ -2527,8 +2541,7 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes) | |||
2527 | DPRINTK("ENTER\n"); | 2541 | DPRINTK("ENTER\n"); |
2528 | 2542 | ||
2529 | /* print link status */ | 2543 | /* print link status */ |
2530 | if (ap->cbl == ATA_CBL_SATA) | 2544 | sata_print_link_status(ap); |
2531 | sata_print_link_status(ap); | ||
2532 | 2545 | ||
2533 | /* re-enable interrupts */ | 2546 | /* re-enable interrupts */ |
2534 | if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ | 2547 | if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */ |
@@ -2575,7 +2588,7 @@ int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes) | |||
2575 | ata_reset_fn_t hardreset; | 2588 | ata_reset_fn_t hardreset; |
2576 | 2589 | ||
2577 | hardreset = NULL; | 2590 | hardreset = NULL; |
2578 | if (ap->cbl == ATA_CBL_SATA && ap->ops->scr_read) | 2591 | if (sata_scr_valid(ap)) |
2579 | hardreset = sata_std_hardreset; | 2592 | hardreset = sata_std_hardreset; |
2580 | 2593 | ||
2581 | return ata_drive_probe_reset(ap, ata_std_probeinit, | 2594 | return ata_drive_probe_reset(ap, ata_std_probeinit, |