+ printf(" (came back!)\n");
+ }
+ if (um->um_tab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) {
+ rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017];
+ rkaddr->rkcs1 = RK_CDT|RK_OFFSET|RK_GO;
+ rkwait(rkaddr);
+ }
+ rkaddr->rkcyl = bp->b_cylin;
+ rkcyl[ui->ui_unit] = bp->b_cylin;
+ rkaddr->rkda = (tn << 8) + sn;
+ rkaddr->rkwc = -bp->b_bcount / sizeof (short);
+ if (bp->b_flags & B_READ)
+ cmd = RK_CDT|RK_IE|RK_READ|RK_GO;
+ else
+ cmd = RK_CDT|RK_IE|RK_WRITE|RK_GO;
+ um->um_cmd = cmd;
+ ubago(ui);
+ return (1);
+}
+
+rkdgo(um)
+ register struct uba_minfo *um;
+{
+ register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr;
+
+ rkaddr->rkba = um->um_ubinfo;
+ rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300);
+}
+
+rkintr(rk11)
+ int rk11;
+{
+ register struct uba_minfo *um = rkminfo[rk11];
+ register struct uba_dinfo *ui;
+ register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr;
+ register struct buf *bp, *dp;
+ int unit;
+ struct rk_softc *sc = &rk_softc[um->um_ctlr];
+ int as = (rkaddr->rkatt >> 8) | sc->sc_softas;
+ int needie = 1;
+
+ sc->sc_wticks = 0;
+ sc->sc_softas = 0;
+ if (um->um_tab.b_active) {
+ dp = um->um_tab.b_actf;
+ bp = dp->b_actf;
+ ui = rkdinfo[dkunit(bp)];
+ dk_busy &= ~(1 << ui->ui_dk);
+ if (rkaddr->rkcs1 & RK_CERR) {
+ int recal;
+ u_short ds = rkaddr->rkds;
+ u_short cs2 = rkaddr->rkcs2;
+ u_short er = rkaddr->rker;
+ if (ds & RK_WLE) {
+ printf("rk%d: write locked\n", dkunit(bp));
+ bp->b_flags |= B_ERROR;
+ } else if (++um->um_tab.b_errcnt > 28 ||
+ ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) {
+ bp->b_flags |= B_ERROR;
+ harderr(bp, "rk");
+ printf("cs2=%b ds=%b er=%b\n",
+ cs2, RKCS2_BITS, ds,
+ RKDS_BITS, er, RKER_BITS);
+ } else
+ um->um_tab.b_active = 0;
+ if (cs2&RK_MDS) {
+ rkaddr->rkcs2 = RK_SCLR;
+ goto retry;
+ }
+ recal = 0;
+ if (ds&RK_DROT || er&(RK_OPI|RK_SKI|RK_UNS) ||
+ (um->um_tab.b_errcnt&07) == 4)
+ recal = 1;
+ if ((er & (RK_DCK|RK_ECH)) == RK_DCK)
+ if (rkecc(ui))
+ return;
+ rkaddr->rkcs1 = RK_CDT|RK_CCLR;
+ rkaddr->rkcs2 = ui->ui_slave;
+ rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO;
+ rkwait(rkaddr);
+ if (recal && um->um_tab.b_active == 0) {
+ rkaddr->rkcs1 = RK_CDT|RK_IE|RK_RECAL|RK_GO;
+ rkcyl[ui->ui_unit] = -1;
+ rkwait(rkaddr);
+ um->um_tab.b_active = 1;
+ sc->sc_recal = 1;
+ return;