+ register struct mba_info *mi;
+ register struct mba_regs *mba;
+ struct device *hpaddr;
+ char *start;
+ int num, unit;
+ register struct hpst *st;
+
+ num = maxfree;
+ start = 0;
+ unit = minor(dev) >> 3;
+ if (unit >= NHP) {
+ printf("bad unit\n");
+ return (-1);
+ }
+#define phys(a,b) ((b)((int)(a)&0x7fffffff))
+ mi = phys(hpinfo[unit],struct mba_info *);
+ if (mi->mi_alive == 0) {
+ printf("dna\n");
+ return (-1);
+ }
+ mba = phys(mi->mi_hd, struct mba_hd *)->mh_physmba;
+ mba->mba_cr = MBAINIT;
+ hpaddr = (struct device *)&mba->mba_drv[mi->mi_drive];
+ if ((hpaddr->hpds & VV) == 0) {
+ hpaddr->hpcs1 = DCLR|GO;
+ hpaddr->hpcs1 = PRESET|GO;
+ hpaddr->hpof = FMT22;
+ }
+ st = &hpst[mi->mi_type];
+ if (dumplo < 0 || dumplo + num >= st->sizes[minor(dev)&07].nblocks) {
+ printf("oor\n");
+ return (-1);
+ }
+ while (num > 0) {
+ register struct pte *hpte = mba->mba_map;
+ register int i;
+ int blk, cn, sn, tn;
+ daddr_t bn;
+
+ blk = num > DBSIZE ? DBSIZE : num;
+ bn = dumplo + btop(start);
+ cn = bn/st->nspc + st->sizes[minor(dev)&07].cyloff;
+ sn = bn%st->nspc;
+ tn = sn/st->nsect;
+ sn = sn%st->nsect;
+ hpaddr->hpdc = cn;
+ hpaddr->hpda = (tn << 8) + sn;
+ for (i = 0; i < blk; i++)
+ *(int *)hpte++ = (btop(start)+i) | PG_V;
+ mba->mba_sr = -1;
+ mba->mba_bcr = -(blk*NBPG);
+ mba->mba_var = 0;
+ hpaddr->hpcs1 = WCOM | GO;
+ while ((hpaddr->hpds & DRY) == 0)
+ ;
+ if (hpaddr->hpds&ERR) {
+ printf("dskerr: (%d,%d,%d) ds=%x er=%x\n",
+ cn, tn, sn, hpaddr->hpds, hpaddr->hper1);
+ return (-1);
+ }
+ start += blk*NBPG;
+ num -= blk;
+ }
+ return (0);