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); }
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); }
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; }
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); }