示例#1
0
int
atapiscsi_activate(struct device *self, int act)
{
	struct atapiscsi_softc *as = (void *)self;
 	struct channel_softc *chp = as->chp;
	struct ata_drive_datas *drvp = &chp->ch_drive[as->drive];

	switch (act) {
	case DVACT_SUSPEND:
		break;
	case DVACT_RESUME:
		/*
		 * Do two resets separated by a small delay. The
		 * first wakes the controller, the second resets
		 * the channel
		 */
		wdc_disable_intr(chp);
		wdc_reset_channel(drvp, 1);
		delay(10000);
		wdc_reset_channel(drvp, 0);
		wdc_enable_intr(chp);
		break;
	}
	return (0);
}
示例#2
0
int
wdactivate(struct device *self, int act)
{
	struct wd_softc *wd = (void *)self;
	int rv = 0;

	switch (act) {
	case DVACT_SUSPEND:
		break;
	case DVACT_POWERDOWN:
		wd_flushcache(wd, AT_POLL);
		if (boothowto & RB_POWERDOWN)
			wd_standby(wd, AT_POLL);
		break;
	case DVACT_RESUME:
		/*
		 * Do two resets separated by a small delay. The
		 * first wakes the controller, the second resets
		 * the channel.
		 */
		wdc_disable_intr(wd->drvp->chnl_softc);
		wdc_reset_channel(wd->drvp, 1);
		delay(10000);
		wdc_reset_channel(wd->drvp, 0);
		wdc_enable_intr(wd->drvp->chnl_softc);
		wd_get_params(wd, at_poll, &wd->sc_params);
		break;
	}
	return (rv);
}
示例#3
0
void
wdc_atapi_reset_2(struct channel_softc *chp, struct wdc_xfer *xfer,
    int timeout, struct atapi_return_args *ret)
{
	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
	struct scsi_xfer *sc_xfer = xfer->cmd;

	if (timeout) {
		printf("%s:%d:%d: soft reset failed\n",
		    chp->wdc->sc_dev.dv_xname, chp->channel,
		    xfer->drive);
		sc_xfer->error = XS_SELTIMEOUT;
		wdc_reset_channel(drvp, 0);

		xfer->next = wdc_atapi_done;
		return;
	}

	wdc_atapi_update_status(chp);

	if (chp->ch_status & (WDCS_BSY | WDCS_DRQ)) {
		return;
	}

	xfer->next = wdc_atapi_done;
	return;
}
示例#4
0
void
wddone(void *v)
{
	struct wd_softc *wd = v;
	struct buf *bp = wd->sc_bp;
	char buf[256], *errbuf = buf;
	WDCDEBUG_PRINT(("wddone %s\n", wd->sc_dev.dv_xname),
	    DEBUG_XFERS);

	bp->b_resid = wd->sc_wdc_bio.bcount;
	errbuf[0] = '\0';
	switch (wd->sc_wdc_bio.error) {
	case ERR_NODEV:
		bp->b_flags |= B_ERROR;
		bp->b_error = ENXIO;
		break;
	case ERR_DMA:
		errbuf = "DMA error";
		goto retry;
	case ERR_DF:
		errbuf = "device fault";
		goto retry;
	case TIMEOUT:
		errbuf = "device timeout";
		goto retry;
	case ERROR:
		/* Don't care about media change bits */
		if (wd->sc_wdc_bio.r_error != 0 &&
		    (wd->sc_wdc_bio.r_error & ~(WDCE_MC | WDCE_MCR)) == 0)
			goto noerror;
		ata_perror(wd->drvp, wd->sc_wdc_bio.r_error, errbuf,
		    sizeof buf);
retry:
		/* Just reset and retry. Can we do more ? */
		wdc_reset_channel(wd->drvp, 0);
		diskerr(bp, "wd", errbuf, LOG_PRINTF,
		    wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label);
		if (wd->retries++ < WDIORETRIES) {
			printf(", retrying\n");
			timeout_add(&wd->sc_restart_timeout, RECOVERYTIME);
			return;
		}
		printf("\n");
		bp->b_flags |= B_ERROR;
		bp->b_error = EIO;
		break;
	case NOERROR:
noerror:	if ((wd->sc_wdc_bio.flags & ATA_CORR) || wd->retries > 0)
			printf("%s: soft error (corrected)\n",
			    wd->sc_dev.dv_xname);
	}
	disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid),
	    (bp->b_flags & B_READ));
	biodone(bp);
	wd->openings++;
	wdstart(wd);
}