+ switch(flag){
+ case ECC:
+ npf--;
+ reg--;
+ mask = up->upec2;
+ diskerr(bp, "up", "soft ecc", LOG_WARNING, npf,
+ (struct disklabel *)0);
+ addlog("\n");
+ /*
+ * Flush the buffered data path, and compute the
+ * byte and bit position of the error. The variable i
+ * is the byte offset in the transfer, the variable byte
+ * is the offset from a page boundary in main memory.
+ */
+ i = up->upec1 - 1; /* -1 makes 0 origin */
+ bit = i&07;
+ i = (i&~07)>>3;
+ byte = i + o;
+ /*
+ * Correct while possible bits remain of mask. Since mask
+ * contains 11 bits, we continue while the bit offset is > -11.
+ * Also watch out for end of this block and the end of the whole
+ * transfer.
+ */
+ while (i < 512 && (int)dbtob(npf)+i < bp->b_bcount && bit > -11) {
+ struct pte pte;
+
+ pte = ubp->uba_map[reg + btop(byte)];
+ addr = ptob(pte.pg_pfnum) + (byte & PGOFSET);
+#ifdef UPECCDEBUG
+ printf("addr %x map reg %x\n",
+ addr, *(int *)(&ubp->uba_map[reg+btop(byte)]));
+ printf("old: %x, ", getmemc(addr));
+#endif
+ putmemc(addr, getmemc(addr)^(mask<<bit));
+#ifdef UPECCDEBUG
+ printf("new: %x\n", getmemc(addr));
+#endif
+ byte++;
+ i++;
+ bit -= 8;
+ }
+ if (up->upwc == 0)
+ return (0);
+ npf++;
+ reg++;
+ break;
+ case BSE:
+ /*
+ * if not in bad sector table, return 0
+ */
+ if ((bn = isbad(&upbad[ui->ui_unit], cn, tn, sn)) < 0)
+ return(0);
+ /*
+ * flag this one as bad
+ */
+ bp->b_flags |= B_BAD;
+ bp->b_error = npf + 1;
+#ifdef UPECCDEBUG
+ printf("BSE: restart at %d\n",npf+1);
+#endif
+ bn = st->ncyl * st->nspc -st->nsect - 1 - bn;
+ cn = bn / st->nspc;
+ sn = bn % st->nspc;
+ tn = sn / st->nsect;
+ sn %= st->nsect;
+ up->upwc = -(512 / sizeof (short));
+#ifdef UPECCDEBUG
+ printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
+#endif
+ break;
+ case CONT:
+#ifdef UPECCDEBUG
+ printf("upecc, CONT: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn);
+#endif
+ bp->b_flags &= ~B_BAD;
+ if ((int)dbtob(npf) >= bp->b_bcount)
+ return (0);
+ up->upwc = -((bp->b_bcount - (int)dbtob(npf)) / sizeof(short));
+ break;