- ubarelse(ui->ui_ubanum, &um->um_ubinfo);
- if (um->um_tab.b_active) {
- if (um->um_tab.b_errcnt >= 16) {
- upaddr->upcs1 = RTC|GO|IE;
- while (upaddr->upds & PIP)
- DELAY(25);
- needie = 0;
- }
- um->um_tab.b_active = 0;
- um->um_tab.b_errcnt = 0;
- um->um_tab.b_actf = dp->b_forw;
- dp->b_active = 0;
- dp->b_errcnt = 0;
- dp->b_actf = bp->av_forw;
- bp->b_resid = (-upaddr->upwc * sizeof(short));
- /* CHECK FOR WRITE LOCK HERE... */
- if (bp->b_resid)
- printf("resid %d ds %o er? %o %o %o\n",
- bp->b_resid, upaddr->upds,
- upaddr->uper1, upaddr->uper2, upaddr->uper3);
- iodone(bp);
- if (dp->b_actf)
- if (upustart(ui))
- needie = 0;
+ if (upaddr->uper1&UPER1_WLE) {
+ /*
+ * Give up on write locked devices
+ * immediately.
+ */
+ printf("up%d: write locked\n", dkunit(bp));
+ bp->b_flags |= B_ERROR;
+ } else if (++um->um_tab.b_errcnt > 27) {
+ /*
+ * After 28 retries (16 without offset, and
+ * 12 with offset positioning) give up.
+ */
+ harderr(bp, "up");
+ printf("cs2=%b er1=%b er2=%b\n",
+ upaddr->upcs2, UPCS2_BITS,
+ upaddr->uper1, UPER1_BITS,
+ upaddr->uper2, UPER2_BITS);
+ bp->b_flags |= B_ERROR;
+ } else {
+ /*
+ * Retriable error.
+ * If a soft ecc, correct it (continuing
+ * by returning if necessary.
+ * Otherwise fall through and retry the transfer
+ */
+ um->um_tab.b_active = 0; /* force retry */
+ if ((upaddr->uper1&(UPER1_DCK|UPER1_ECH))==UPER1_DCK)
+ if (upecc(ui))
+ return;
+ }
+ /*
+ * Clear drive error and, every eight attempts,
+ * (starting with the fourth)
+ * recalibrate to clear the slate.
+ */
+ upaddr->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO;
+ needie = 0;
+ if ((um->um_tab.b_errcnt&07) == 4 && um->um_tab.b_active == 0) {
+ upaddr->upcs1 = UP_RECAL|UP_IE|UP_GO;
+ sc->sc_recal = 0;
+ goto nextrecal;