- if ((upaddr->upds&UP_ERR) || (upaddr->upcs1&UP_TRE)) {
- int cs2;
- while ((upaddr->upds & UP_DRY) == 0)
- DELAY(25);
- if (upaddr->uper1&UP_WLE)
- printf("up%d is write locked\n", dkunit(bp));
- if (++um->um_tab.b_errcnt > 28 || upaddr->uper1&UP_WLE)
- bp->b_flags |= B_ERROR;
- else
- um->um_tab.b_active = 0; /* force retry */
- if (um->um_tab.b_errcnt > 27) {
- cs2 = (int)upaddr->upcs2;
- deverror(bp, cs2, (int)upaddr->uper1);
- }
- if ((upaddr->uper1&(UP_DCK|UP_ECH))==UP_DCK)
+ /*
+ * Check for and process errors on
+ * either the drive or the controller.
+ */
+ if ((upaddr->upds&UPDS_ERR) || (upaddr->upcs1&UP_TRE)) {
+ waitdry = 0;
+ while ((upaddr->upds & UPDS_DRY) == 0) {
+ if (++waitdry > 512)
+ break;
+ upwaitdry++;
+ }
+ 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)