+
+hpsize(dev)
+ dev_t dev;
+{
+ register int unit = hpunit(dev);
+ struct mba_device *mi;
+
+ if (unit >= NHP || (mi = hpinfo[unit]) == 0 || mi->mi_alive == 0 ||
+ hpsoftc[unit].sc_state != OPEN)
+ return (-1);
+ return ((int)hplabel[unit].d_partitions[hppart(dev)].p_size);
+}
+
+#ifdef COMPAT_42
+/*
+ * Compatibility code to fake up pack label
+ * for unlabeled disks.
+ */
+struct size {
+ daddr_t nblocks;
+ int cyloff;
+} rp06_sizes[8] = {
+ 15884, 0, /* A=cyl 0 thru 37 */
+ 33440, 38, /* B=cyl 38 thru 117 */
+ 340670, 0, /* C=cyl 0 thru 814 */
+ 15884, 118, /* D=cyl 118 thru 155 */
+ 55936, 156, /* E=cyl 156 thru 289 */
+ 219384, 290, /* F=cyl 290 thru 814 */
+ 291192, 118, /* G=cyl 118 thru 814 */
+ 0, 0,
+}, rp05_sizes[8] = {
+ 15884, 0, /* A=cyl 0 thru 37 */
+ 33440, 38, /* B=cyl 38 thru 117 */
+ 171798, 0, /* C=cyl 0 thru 410 */
+ 15884, 118, /* D=cyl 118 thru 155 */
+ 55936, 156, /* E=cyl 156 thru 289 */
+ 50512, 290, /* F=cyl 290 thru 410 */
+ 122408, 118, /* G=cyl 118 thru 410 */
+ 0, 0,
+}, rm03_sizes[8] = {
+ 15884, 0, /* A=cyl 0 thru 99 */
+ 33440, 100, /* B=cyl 100 thru 308 */
+ 131680, 0, /* C=cyl 0 thru 822 */
+ 15884, 309, /* D=cyl 309 thru 408 */
+ 55936, 409, /* E=cyl 409 thru 758 */
+ 10144, 759, /* F=cyl 759 thru 822 */
+ 82144, 309, /* G=cyl 309 thru 822 */
+ 0, 0,
+}, rm05_sizes[8] = {
+ 15884, 0, /* A=cyl 0 thru 26 */
+ 33440, 27, /* B=cyl 27 thru 81 */
+ 500384, 0, /* C=cyl 0 thru 822 */
+ 15884, 562, /* D=cyl 562 thru 588 */
+ 55936, 589, /* E=cyl 589 thru 680 */
+ 86240, 681, /* F=cyl 681 thru 822 */
+ 158592, 562, /* G=cyl 562 thru 822 */
+ 291346, 82, /* H=cyl 82 thru 561 */
+}, rm80_sizes[8] = {
+ 15884, 0, /* A=cyl 0 thru 36 */
+ 33440, 37, /* B=cyl 37 thru 114 */
+ 242606, 0, /* C=cyl 0 thru 558 */
+ 15884, 115, /* D=cyl 115 thru 151 */
+ 55936, 152, /* E=cyl 152 thru 280 */
+ 120559, 281, /* F=cyl 281 thru 558 */
+ 192603, 115, /* G=cyl 115 thru 558 */
+ 0, 0,
+}, rp07_sizes[8] = {
+ 15884, 0, /* A=cyl 0 thru 9 */
+ 66880, 10, /* B=cyl 10 thru 51 */
+ 1008000, 0, /* C=cyl 0 thru 629 */
+ 15884, 235, /* D=cyl 235 thru 244 */
+ 307200, 245, /* E=cyl 245 thru 436 */
+ 308650, 437, /* F=cyl 437 thru 629 */
+ 631850, 235, /* G=cyl 235 thru 629 */
+ 291346, 52, /* H=cyl 52 thru 234 */
+}, cdc9775_sizes[8] = {
+ 15884, 0, /* A=cyl 0 thru 12 */
+ 66880, 13, /* B=cyl 13 thru 65 */
+ 1077760, 0, /* C=cyl 0 thru 841 */
+ 15884, 294, /* D=cyl 294 thru 306 */
+ 307200, 307, /* E=cyl 307 thru 546 */
+ 377440, 547, /* F=cyl 547 thru 841 */
+ 701280, 294, /* G=cyl 294 thru 841 */
+ 291346, 66, /* H=cyl 66 thru 293 */
+}, cdc9730_sizes[8] = {
+ 15884, 0, /* A=cyl 0 thru 49 */
+ 33440, 50, /* B=cyl 50 thru 154 */
+ 263360, 0, /* C=cyl 0 thru 822 */
+ 15884, 155, /* D=cyl 155 thru 204 */
+ 55936, 205, /* E=cyl 205 thru 379 */
+ 141664, 380, /* F=cyl 380 thru 822 */
+ 213664, 155, /* G=cyl 155 thru 822 */
+ 0, 0,
+}, capricorn_sizes[8] = {
+ 15884, 0, /* A=cyl 0 thru 31 */
+ 33440, 32, /* B=cyl 32 thru 97 */
+ 524288, 0, /* C=cyl 0 thru 1023 */
+ 15884, 668, /* D=cyl 668 thru 699 */
+ 55936, 700, /* E=cyl 700 thru 809 */
+ 109472, 810, /* F=cyl 810 thru 1023 */
+ 182176, 668, /* G=cyl 668 thru 1023 */
+ 291346, 98, /* H=cyl 98 thru 667 */
+}, eagle_sizes[8] = {
+ 15884, 0, /* A=cyl 0 thru 16 */
+ 66880, 17, /* B=cyl 17 thru 86 */
+ 808320, 0, /* C=cyl 0 thru 841 */
+ 15884, 391, /* D=cyl 391 thru 407 */
+ 307200, 408, /* E=cyl 408 thru 727 */
+ 109296, 728, /* F=cyl 728 thru 841 */
+ 432816, 391, /* G=cyl 391 thru 841 */
+ 291346, 87, /* H=cyl 87 thru 390 */
+}, ampex_sizes[8] = {
+ 15884, 0, /* A=cyl 0 thru 26 */
+ 33440, 27, /* B=cyl 27 thru 81 */
+ 495520, 0, /* C=cyl 0 thru 814 */
+ 15884, 562, /* D=cyl 562 thru 588 */
+ 55936, 589, /* E=cyl 589 thru 680 */
+ 81312, 681, /* F=cyl 681 thru 814 */
+ 153664, 562, /* G=cyl 562 thru 814 */
+ 291346, 82, /* H=cyl 82 thru 561 */
+}, fj2361_sizes[8] = {
+ 15884, 0, /* A=cyl 0 thru 12 */
+ 66880, 13, /* B=cyl 13 thru 65 */
+ 1077760, 0, /* C=cyl 0 thru 841 */
+ 15884, 294, /* D=cyl 294 thru 306 */
+ 307200, 307, /* E=cyl 307 thru 546 */
+ 377408, 547, /* F=cyl 547 thru 841 */
+ 701248, 294, /* G=cyl 294 thru 841 */
+ 291346, 66, /* H=cyl 66 thru 293 */
+};
+
+/*
+ * These variable are all measured in sectors.
+ * Sdist is how much to "lead" in the search for a desired sector
+ * (i.e. if want N, search for N-sdist.)
+ * Maxdist and mindist define the region right before our desired sector within
+ * which we don't bother searching. We don't search when we are already less
+ * then maxdist and more than mindist sectors "before" our desired sector.
+ * Maxdist should be >= sdist.
+ *
+ * Beware, sdist, mindist and maxdist are not well tuned
+ * for many of the drives listed in this table.
+ * Try patching things with something i/o intensive
+ * running and watch iostat.
+ */
+struct hpst {
+ short nsect; /* # sectors/track */
+ short ntrak; /* # tracks/cylinder */
+ short nspc; /* # sector/cylinders */
+ short ncyl; /* # cylinders */
+ struct size *sizes; /* partition tables */
+ short sdist; /* seek distance metric */
+ short maxdist; /* boundaries of non-searched area */
+ short mindist; /* preceding the target sector */
+ char *name; /* name of disk type */
+} hpst[] = {
+ { 32, 5, 32*5, 823, rm03_sizes, 7, 4, 1, "RM03" },
+ { 32, 19, 32*19, 823, rm05_sizes, 7, 4, 1, "RM05" },
+ { 22,19, 22*19, 815, rp06_sizes, 7, 4, 1, "RP06"},
+ { 31, 14, 31*14, 559, rm80_sizes, 7, 4, 1, "RM80"},
+ { 22, 19, 22*19, 411, rp05_sizes, 7, 4, 1, "RP04"},
+ { 22, 19, 22*19, 411, rp05_sizes, 7, 4, 1, "RP05"},
+ { 50, 32, 50*32, 630, rp07_sizes, 15, 8, 3, "RP07"},
+ { 1, 1, 1, 1, 0, 0, 0, 0, "ML11A"},
+ { 1, 1, 1, 1, 0, 0, 0, 0, "ML11B" },
+ { 32, 40, 32*40, 843, cdc9775_sizes, 7, 4, 1, "9775" },
+ { 32, 10, 32*10, 823, cdc9730_sizes, 7, 4, 1, "9730-160" },
+ { 32, 16, 32*16, 1024, capricorn_sizes,10,4, 3, "capricorn" },
+ { 48, 20, 48*20, 842, eagle_sizes, 15, 8, 3, "eagle" },
+ { 32, 19, 32*19, 815, ampex_sizes, 7, 4, 1, "9300" },
+ { 64, 20, 64*20, 842, fj2361_sizes, 15, 8, 3, "2361" },
+};
+
+/*
+ * Map apparent MASSBUS drive type into manufacturer
+ * specific configuration. For SI controllers this is done
+ * based on codes in the serial number register. For
+ * EMULEX controllers, the track and sector attributes are
+ * used when the drive type is an RM02 (not supported by DEC).
+ */
+hpmaptype(mi, lp)
+ register struct mba_device *mi;
+ register struct disklabel *lp;
+{
+ register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
+ register int type = mi->mi_type;
+ register struct hpst *st;
+ register i;
+
+ /*
+ * Model-byte processing for SI controllers.
+ * NB: Only deals with RM03 and RM05 emulations.
+ */
+ if (type == HPDT_RM03 || type == HPDT_RM05) {
+ int hpsn = hpaddr->hpsn;
+
+ if ((hpsn & SIMB_LU) == mi->mi_drive)
+ switch ((hpsn & SIMB_MB) & ~(SIMB_S6|SIRM03|SIRM05)) {
+
+ case SI9775D:
+ type = HPDT_9775;
+ break;
+
+ case SI9730D:
+ type = HPDT_9730;
+ break;
+
+ case SI9766:
+ type = HPDT_RM05;
+ break;
+
+ case SI9762:
+ type = HPDT_RM03;
+ break;
+
+ case SICAPD:
+ type = HPDT_CAPRICORN;
+ break;
+
+ case SI9751D:
+ type = HPDT_EAGLE;
+ break;
+ }
+ }
+
+ /*
+ * EMULEX SC750 or SC780. Poke the holding register.
+ */
+ if (type == HPDT_RM02) {
+ int nsectors, ntracks, ncyl;
+
+ hpaddr->hpof = HPOF_FMT22;
+ mbclrattn(mi);
+ hpaddr->hpcs1 = HP_NOP;
+ hpaddr->hphr = HPHR_MAXTRAK;
+ ntracks = MASKREG(hpaddr->hphr) + 1;
+ DELAY(100);
+ hpaddr->hpcs1 = HP_NOP;
+ hpaddr->hphr = HPHR_MAXSECT;
+ nsectors = MASKREG(hpaddr->hphr) + 1;
+ DELAY(100);
+ hpaddr->hpcs1 = HP_NOP;
+ hpaddr->hphr = HPHR_MAXCYL;
+ ncyl = MASKREG(hpaddr->hphr) + 1;
+ for (type = 0; hptypes[type] != 0; type++)
+ if (hpst[type].nsect == nsectors &&
+ hpst[type].ntrak == ntracks &&
+ hpst[type].ncyl == ncyl)
+ break;
+
+ hpaddr->hpcs1 = HP_DCLR|HP_GO;
+ mbclrattn(mi); /* conservative */
+ if (hptypes[type] == 0) {
+ printf("hp%d: %d sectors, %d tracks, %d cylinders: unknown device\n",
+ mi->mi_unit, nsectors, ntracks, ncyl);
+ lp->d_nsectors = nsectors;
+ lp->d_ntracks = ntracks;
+ lp->d_ncylinders = ncyl;
+ lp->d_secpercyl = nsectors*ntracks;
+ lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders;
+ lp->d_npartitions = 1;
+ lp->d_partitions[0].p_offset = 0;
+ lp->d_partitions[0].p_size = lp->d_secperunit;
+ return (0);
+ }
+ }
+
+ /*
+ * set up minimal disk label.
+ */
+ st = &hpst[type];
+ lp->d_nsectors = st->nsect;
+ lp->d_ntracks = st->ntrak;
+ lp->d_secpercyl = st->nspc;
+ lp->d_ncylinders = st->ncyl;
+ lp->d_secperunit = st->nspc * st->ncyl;
+ lp->d_sdist = st->sdist;
+ lp->d_mindist = st->mindist;
+ lp->d_maxdist = st->maxdist;
+ bcopy(hpst[type].name, lp->d_typename, sizeof(lp->d_typename));
+ lp->d_npartitions = 8;
+ for (i = 0; i < 8; i++) {
+ lp->d_partitions[i].p_offset = st->sizes[i].cyloff *
+ lp->d_secpercyl;
+ lp->d_partitions[i].p_size = st->sizes[i].nblocks;
+ }
+ return (type);
+}
+#endif COMPAT_42