+ register struct uba_device *ui;
+ register struct uba_regs *uba;
+ register struct tsdevice *addr;
+ register int i;
+ register struct pte *io;
+ int blk, num, unit, reg, start;
+ u_short db;
+ struct ts_tsdata *tc, *tc_ubaddr;
+
+ unit = TSUNIT(dev);
+ if (unit >= NTS)
+ return (ENXIO);
+#define phys(a,b) ((b)((int)(a)&0x7fffffff))
+ ui = phys(tsdinfo[unit], struct uba_device *);
+ if (ui->ui_alive == 0)
+ return (ENXIO);
+ uba = phys(ui->ui_hd, struct uba_hd *)->uh_physuba;
+ ubainit(uba);
+ addr = (struct tsdevice *)ui->ui_physaddr;
+
+ /* map a ts_tsdata structure */
+ tc = phys(&ts_softc[0].sc_ts, struct ts_tsdata *);
+ num = btoc(sizeof(struct ts_tsdata)) + 1;
+ io = &uba->uba_map[reg = NUBMREG - num];
+ for (i = 0; i < num; i++)
+ *(int *)io++ = UBAMR_MRV | (btop(tc) + i);
+ i = (((int)tc & PGOFSET) | (reg << 9));
+ tc_ubaddr = (struct ts_tsdata *)i;
+ db = i + ((i >> 16) & 3);
+
+ /* init the drive */
+ addr->tssr = 0;
+ tswait(addr);
+ if ((addr->tssr & (TS_NBA|TS_OFL)) != TS_NBA)
+ return (EFAULT);
+
+ /* set characteristics */
+ i = (int)&tc_ubaddr->t_char;
+ tc->t_cmd.c_loba = i;
+ tc->t_cmd.c_hiba = (i >> 16) & 3;
+ tc->t_cmd.c_size = sizeof(struct ts_char);
+ tc->t_cmd.c_cmd = TS_ACK | TS_CVC | TS_SETCHR;
+ tc->t_char.char_addr = (int)&tc_ubaddr->t_sts;
+ tc->t_char.char_size = sizeof(struct ts_sts);
+ tc->t_char.char_mode = TS_ESS;
+ addr->tsdb = db;
+ tswait(addr);
+ if (addr->tssr & TS_NBA)
+ return (ENXIO);
+
+ /* dump */
+ tc->t_cmd.c_cmd = TS_ACK | TS_WCOM;
+ tc->t_cmd.c_repcnt = 1;
+ num = maxfree;
+ for (start = 0, num = maxfree; num > 0; start += blk, num -= blk) {
+ blk = num > DBSIZE ? DBSIZE : num;
+ io = uba->uba_map;
+ for (i = 0; i < blk; i++)
+ *(int *)io++ = UBAMR_MRV | (1 << UBAMR_DPSHIFT) |
+ (start + i);
+ *(int *)io = 0;
+ addr->tsdb = db;
+ tswait(addr);
+ }