+ register struct mba_info *mi;
+ register struct mba_regs *mba;
+ struct hpdevice *hpaddr;
+ char *start;
+ int num, unit;
+ register struct hpst *st;
+
+ num = maxfree;
+ start = 0;
+ unit = minor(dev) >> 3;
+ if (unit >= NHP)
+ return (ENXIO);
+#define phys(a,b) ((b)((int)(a)&0x7fffffff))
+ mi = phys(hpinfo[unit],struct mba_info *);
+ if (mi == 0 || mi->mi_alive == 0)
+ return (ENXIO);
+ mba = phys(mi->mi_hd, struct mba_hd *)->mh_physmba;
+ mba->mba_cr = MBAINIT;
+ hpaddr = (struct hpdevice *)&mba->mba_drv[mi->mi_drive];
+ if ((hpaddr->hpds & HP_VV) == 0) {
+ hpaddr->hpcs1 = HP_DCLR|HP_GO;
+ hpaddr->hpcs1 = HP_PRESET|HP_GO;
+ hpaddr->hpof = HP_FMT22;
+ }
+ st = &hpst[mi->mi_type];
+ if (dumplo < 0 || dumplo + num >= st->sizes[minor(dev)&07].nblocks)
+ return (EINVAL);
+ 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 = HP_WCOM | HP_GO;
+ while ((hpaddr->hpds & HP_DRY) == 0)
+ ;
+ if (hpaddr->hpds&HP_ERR)
+ return (EIO);
+ start += blk*NBPG;
+ num -= blk;
+ }
+ return (0);