+ sc->sc_wticks++;
+ if (sc->sc_wticks >= 20) {
+ sc->sc_wticks = 0;
+ printf("sc%d: lost interrupt\n", sc21);
+ ubareset(um->um_ubanum);
+ }
+ }
+}
+
+#define DBSIZE 20
+
+updump(dev)
+ dev_t dev;
+{
+ struct updevice *upaddr;
+ char *start;
+ int num, blk, unit;
+ struct size *sizes;
+ register struct uba_regs *uba;
+ register struct uba_device *ui;
+ register short *rp;
+ struct upst *st;
+ register int retry;
+
+ unit = minor(dev) >> 3;
+ if (unit >= NUP)
+ return (ENXIO);
+#define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))
+ ui = phys(struct uba_device *, updinfo[unit]);
+ if (ui->ui_alive == 0)
+ return (ENXIO);
+ uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;
+ ubainit(uba);
+ upaddr = (struct updevice *)ui->ui_physaddr;
+ DELAY(5000000);
+ num = maxfree;
+ upaddr->upcs2 = unit;
+ DELAY(100);
+ upaddr->upcs1 = UP_DCLR|UP_GO;
+ upaddr->upcs1 = UP_PRESET|UP_GO;
+ upaddr->upof = UPOF_FMT22;
+ retry = 0;
+ do {
+ DELAY(25);
+ if (++retry > 527)
+ break;
+ } while ((upaddr->upds & UP_RDY) == 0);
+ if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY)
+ return (EFAULT);
+ start = 0;
+ st = &upst[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;
+ upaddr->updc = cn;
+ rp = (short *) &upaddr->upda;
+ *rp = (tn << 8) + sn;
+ *--rp = 0;
+ *--rp = -blk*NBPG / sizeof (short);
+ *--rp = UP_GO|UP_WCOM;
+ retry = 0;
+ do {
+ DELAY(25);
+ if (++retry > 527)
+ break;
+ } while ((upaddr->upcs1 & UP_RDY) == 0);
+ if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
+ printf("up%d: not ready", unit);
+ if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) {
+ printf("\n");
+ return (EIO);
+ }
+ printf(" (flakey)\n");
+ }
+ if (upaddr->upds&UPDS_ERR)
+ return (EIO);
+ start += blk*NBPG;
+ num -= blk;