示例#1
0
int
ata_sata_phy_reset(device_t dev, int port, int quick)
{
    struct ata_channel *ch = device_get_softc(dev);
    int loop, retry;
    uint32_t val;

    if (quick) {
	if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
	    return (0);
	if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE)
	    return ata_sata_connect(ch, port);
    }

    if (bootverbose) {
	if (port < 0) {
	    device_printf(dev, "hardware reset ...\n");
	} else {
	    device_printf(dev, "p%d: hardware reset ...\n", port);
	}
    }
    for (retry = 0; retry < 10; retry++) {
	for (loop = 0; loop < 10; loop++) {
	    if (ata_sata_scr_write(ch, port, ATA_SCONTROL, ATA_SC_DET_RESET))
		return (0);
	    ata_udelay(100);
	    if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
		return (0);
	    if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_RESET)
		break;
	}
	ata_udelay(5000);
	for (loop = 0; loop < 10; loop++) {
	    if (ata_sata_scr_write(ch, port, ATA_SCONTROL,
		    ATA_SC_DET_IDLE | ((ch->pm_level > 0) ? 0 :
		    ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)))
		return (0);
	    ata_udelay(100);
	    if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
		return (0);
	    if ((val & ATA_SC_DET_MASK) == 0)
		return ata_sata_connect(ch, port);
	}
    }
    return 0;
}
示例#2
0
int
ata_sata_phy_reset(device_t dev, int port, int quick)
{
    struct ata_channel *ch = device_get_softc(dev);
    int loop, retry, sata_rev;
    uint32_t val, val1;

#ifdef ATA_CAM
    sata_rev = ch->user[port < 0 ? 0 : port].revision;
    if (sata_rev > 0)
	quick = 0;
#else
    sata_rev = 0;
#endif

    if (quick) {
	if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
	    return (0);
	if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE) {
	    ata_sata_scr_write(ch, port, ATA_SCONTROL,
		ATA_SC_DET_IDLE | ((ch->pm_level > 0) ? 0 :
		ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER));
	    return ata_sata_connect(ch, port, quick);
	}
    }

    if (bootverbose) {
	if (port < 0) {
	    device_printf(dev, "hard reset ...\n");
	} else {
	    device_printf(dev, "p%d: hard reset ...\n", port);
	}
    }
    if (sata_rev == 1)
	val1 = ATA_SC_SPD_SPEED_GEN1;
    else if (sata_rev == 2)
	val1 = ATA_SC_SPD_SPEED_GEN2;
    else if (sata_rev == 3)
	val1 = ATA_SC_SPD_SPEED_GEN3;
    else
	val1 = 0;
    for (retry = 0; retry < 10; retry++) {
	for (loop = 0; loop < 10; loop++) {
	    if (ata_sata_scr_write(ch, port, ATA_SCONTROL, ATA_SC_DET_RESET |
		    val1 | ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER))
		goto fail;
	    ata_udelay(100);
	    if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
		goto fail;
	    if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_RESET)
		break;
	}
	ata_udelay(5000);
	for (loop = 0; loop < 10; loop++) {
	    if (ata_sata_scr_write(ch, port, ATA_SCONTROL,
		    ATA_SC_DET_IDLE | val1 | ((ch->pm_level > 0) ? 0 :
		    ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)))
		goto fail;
	    ata_udelay(100);
	    if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
		goto fail;
	    if ((val & ATA_SC_DET_MASK) == 0)
		return ata_sata_connect(ch, port, 0);
	}
    }
fail:
    /* Clear SATA error register. */
    ata_sata_scr_write(ch, port, ATA_SERROR, 0xffffffff);

    if (bootverbose) {
	if (port < 0) {
	    device_printf(dev, "hard reset failed\n");
	} else {
	    device_printf(dev, "p%d: hard reset failed\n", port);
	}
    }
    return (0);
}