+ for (rk11 = 0; rk11 < NHK; rk11++) {
+ if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban ||
+ um->um_alive == 0)
+ continue;
+ printf(" hk%d", rk11);
+ um->um_tab.b_active = 0;
+ um->um_tab.b_actf = um->um_tab.b_actl = 0;
+ rk_softc[um->um_ctlr].sc_recal = 0;
+ if (um->um_ubinfo) {
+ printf("<%d>", (um->um_ubinfo>>28)&0xf);
+ ubadone(um);
+ }
+ for (unit = 0; unit < NRK; unit++) {
+ if ((ui = rkdinfo[unit]) == 0)
+ continue;
+ if (ui->ui_alive == 0 || ui->ui_mi != um)
+ continue;
+ rkutab[unit].b_active = 0;
+ (void) rkustart(ui);
+ }
+ (void) rkstart(um);
+ }
+}
+
+rkwatch()
+{
+ register struct uba_ctlr *um;
+ register rk11, unit;
+ register struct rk_softc *sc;
+
+ timeout(rkwatch, (caddr_t)0, hz);
+ for (rk11 = 0; rk11 < NHK; rk11++) {
+ um = rkminfo[rk11];
+ if (um == 0 || um->um_alive == 0)
+ continue;
+ sc = &rk_softc[rk11];
+ if (um->um_tab.b_active == 0) {
+ for (unit = 0; unit < NRK; unit++)
+ if (rkutab[unit].b_active &&
+ rkdinfo[unit]->ui_mi == um)
+ goto active;
+ sc->sc_wticks = 0;
+ continue;
+ }
+active:
+ sc->sc_wticks++;
+ if (sc->sc_wticks >= 20) {
+ sc->sc_wticks = 0;
+ printf("hk%d: lost interrupt\n", rk11);
+ ubareset(um->um_ubanum);
+ }
+ }
+}
+
+#define DBSIZE 20
+
+rkdump(dev)
+ dev_t dev;
+{
+ struct rkdevice *rkaddr;
+ char *start;
+ int num, blk, unit;
+ struct size *sizes;
+ register struct uba_regs *uba;
+ register struct uba_device *ui;
+ register short *rp;
+ struct rkst *st;
+
+ unit = minor(dev) >> 3;
+ if (unit >= NRK)
+ return (ENXIO);
+#define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
+ ui = phys(struct uba_device *, rkdinfo[unit]);
+ if (ui->ui_alive == 0)
+ return (ENXIO);
+ uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
+ ubainit(uba);
+ rkaddr = (struct rkdevice *)ui->ui_physaddr;
+ num = maxfree;
+ start = 0;
+ rkaddr->rkcs1 = RK_CCLR;
+ rkaddr->rkcs2 = unit;
+ rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO;
+ rkwait(rkaddr);
+ if ((rkaddr->rkds & RKDS_VV) == 0) {
+ rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO;
+ rkwait(rkaddr);
+ }
+ st = &rkst[ui->ui_type];
+ sizes = phys(struct size *, st->sizes);
+ if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks)
+ return (EINVAL);
+ while (num > 0) {
+ register struct pte *io;
+ register int i;
+ int cn, sn, tn;
+ daddr_t bn;
+
+ blk = num > DBSIZE ? DBSIZE : num;
+ io = uba->uba_map;
+ for (i = 0; i < blk; i++)
+ *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV;
+ *(int *)io = 0;
+ bn = dumplo + btop(start);
+ cn = bn/st->nspc + sizes[minor(dev)&07].cyloff;
+ sn = bn%st->nspc;
+ tn = sn/st->nsect;
+ sn = sn%st->nsect;
+ rkaddr->rkcyl = cn;
+ rp = (short *) &rkaddr->rkda;
+ *rp = (tn << 8) + sn;
+ *--rp = 0;
+ *--rp = -blk*NBPG / sizeof (short);
+ *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE;
+ rkwait(rkaddr);
+ if (rkaddr->rkcs1 & RK_CERR)
+ return (EIO);
+ start += blk*NBPG;
+ num -= blk;
+ }
+ return (0);