+ /*
+ * Check for and process errors on
+ * either the drive or the controller.
+ */
+ if ((upaddr->upds&UP_ERR) || (upaddr->upcs1&UP_TRE)) {
+ waitdry = 0;
+ while ((upaddr->upds & UP_DRY) == 0) {
+ if (++waitdry > 512)
+ break;
+ upwaitdry++;
+ }
+ if (upaddr->uper1&UP_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&(UP_DCK|UP_ECH))==UP_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) {
+ upaddr->upcs1 = UP_RECAL|UP_IE|UP_GO;
+ um->um_tab.b_active = 1;
+ sc->sc_recal = 1;
+ return;
+ }
+ }
+ /*
+ * Done retrying transfer... release
+ * resources... if we were recalibrating,
+ * then retry the transfer.
+ * Mathematical note: 28%8 != 4.
+ */
+ ubadone(um);
+ if (sc->sc_recal) {
+ sc->sc_recal = 0;
+ um->um_tab.b_active = 0; /* force retry */
+ }
+ /*
+ * If still ``active'', then don't need any more retries.
+ */
+ if (um->um_tab.b_active) {
+ /*
+ * If we were offset positioning,
+ * return to centerline.
+ */
+ if (um->um_tab.b_errcnt >= 16) {
+ upaddr->upof = UP_FMT22;
+ upaddr->upcs1 = UP_RTC|UP_GO|UP_IE;
+ while (upaddr->upds & UP_PIP)