+
+#ifdef COMPAT_42
+struct dkcompat {
+ int nsectors; /* sectors per track */
+ int ntracks; /* tracks per cylinder */
+ int ncylinders; /* cylinders per drive */
+#define NPART 2
+ int poff[NPART]; /* [a+b] for bootstrapping */
+} dkcompat[] = {
+ { 48, 24, 711, 0, 61056 }, /* xsd */
+ { 44, 20, 842, 0, 52800 }, /* eagle */
+ { 64, 10, 823, 0, 38400 }, /* fuji 360 */
+ { 32, 24, 711, 0, 40704 }, /* xfd */
+ { 32, 19, 823, 0, 40128 }, /* smd */
+ { 32, 10, 823, 0, 19200 }, /* fsd */
+};
+#define NDKCOMPAT (sizeof (dkcompat) / sizeof (dkcompat[0]))
+
+/*
+ * Identify and configure drive from above table
+ * by trying to read the last sector until a description
+ * is found for which we're successful.
+ */
+vdmaptype(io)
+ struct iob *io;
+{
+ register struct disklabel *lp = &dklabel[io->i_unit];
+ register struct dkcompat *dp;
+ int i, ctlr, type;
+ struct vddevice *vdaddr;
+
+ ctlr = VDCTLR(io->i_unit);
+ vdaddr = VDADDR(ctlr);
+ type = vdtype[ctlr];
+ for (dp = dkcompat; dp < &dkcompat[NDKCOMPAT]; dp++) {
+ if (type == VDTYPE_VDDC && dp->nsectors != 32)
+ continue;
+ lp->d_nsectors = dp->nsectors;
+ lp->d_ntracks = dp->ntracks;
+ lp->d_ncylinders = dp->ncylinders;
+ if (!vdreset_drive(io)) /* set drive parameters */
+ return (EIO);
+ dcb.opcode = VDOP_RD;
+ dcb.intflg = DCBINT_NONE;
+ dcb.nxtdcb = (struct dcb *)0; /* end of chain */
+ dcb.devselect = VDSLAVE(io->i_unit);
+ dcb.operrsta = 0;
+ dcb.trailcnt = sizeof (trrw) / sizeof (long);
+ dcb.trail.rwtrail.memadr = lbuf;
+ dcb.trail.rwtrail.wcount = sizeof (lbuf) / sizeof (short);
+ dcb.trail.rwtrail.disk.cylinder = dp->ncylinders - 2;
+ dcb.trail.rwtrail.disk.track = dp->ntracks - 1;
+ dcb.trail.rwtrail.disk.sector = dp->nsectors - 1;
+ mdcb.mdcb_head = &dcb;
+ mdcb.mdcb_status = 0;
+ VDGO(vdaddr, (u_long)&mdcb, type);
+ if (!vdpoll(vdaddr, &dcb, 60, type))
+ _stop(" during i/o operation.\n");
+ if (dcb.operrsta & VDERR_HARD)
+ continue;
+ /* simulate necessary parts of disk label */
+ lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
+ lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders;
+ lp->d_npartitions = NPART;
+ for (i = 0; i < NPART; i++) {
+ lp->d_partitions[i].p_offset = dp->poff[i];
+ lp->d_partitions[i].p_size =
+ lp->d_secperunit - dp->poff[i];
+ }
+ return (0);
+ }
+ printf("dk%d: unknown drive type\n", io->i_unit);
+ return (ENXIO);
+}
+#endif