void findroot(void) { struct disk *dkp; struct partition *pp; device_t *devs; const struct bdevsw *bdev; int i, maj, unit; if (boothowto & RB_ASKNAME) return; /* Don't bother looking */ for (i = 0; genericconf[i] != NULL; i++) { for (unit = 0; unit < genericconf[i]->cd_ndevs; unit++) { if (genericconf[i]->cd_devs[unit] == NULL) continue; /* * Find the disk structure corresponding to the * current device. */ devs = genericconf[i]->cd_devs; if ((dkp = disk_find(device_xname(devs[unit]))) == NULL) continue; if (dkp->dk_driver == NULL || dkp->dk_driver->d_strategy == NULL) continue; maj = devsw_name2blk(genericconf[i]->cd_name, NULL, 0); if (maj == -1) continue; bdev = bdevsw_lookup(makedev(maj, 0)); #ifdef DIAGNOSTIC if (bdev == NULL) panic("findroot: impossible"); #endif if (bdev == NULL || bdev->d_strategy != dkp->dk_driver->d_strategy) continue; /* Open disk; forces read of disklabel. */ if ((*bdev->d_open)(MAKEDISKDEV(maj, unit, 0), FREAD|FNONBLOCK, 0, &lwp0)) continue; (void)(*bdev->d_close)(MAKEDISKDEV(maj, unit, 0), FREAD|FNONBLOCK, 0, &lwp0); pp = &dkp->dk_label->d_partitions[booted_partition]; if (pp->p_size != 0 && pp->p_fstype == FS_BSDFFS) { booted_device = devs[unit]; return; } } } }
/* * (Try to) put the drive online. This is done the first time the * drive is opened, or if it has fallen offline. */ int ra_putonline(dev_t dev, struct ra_softc *ra) { struct disklabel *dl; const char *msg; if (rx_putonline(ra) != MSCP_DONE) return MSCP_FAILED; dl = ra->ra_disk.dk_label; ra->ra_state = DK_RDLABEL; printf("%s", device_xname(ra->ra_dev)); if ((msg = readdisklabel( MAKEDISKDEV(major(dev), device_unit(ra->ra_dev), RAW_PART), rastrategy, dl, NULL)) == NULL) { ra->ra_havelabel = 1; ra->ra_state = DK_OPEN; } #if NRACD else if (cdevsw_lookup(dev) == &racd_cdevsw) { dl->d_partitions[0].p_offset = 0; dl->d_partitions[0].p_size = dl->d_secperunit; dl->d_partitions[0].p_fstype = FS_ISO9660; } #endif /* NRACD */ else { printf(": %s", msg); } printf(": size %d sectors\n", dl->d_secperunit); return MSCP_DONE; }
static char * configvnd(const char *path) { static int nextvnd; struct vnd_ioctl vndio; char bbuf[32], rbuf[32]; int fd; makevnddev(0, nextvnd, RAW_PART, bbuf, sizeof(bbuf)); makevnddev(1, nextvnd, RAW_PART, rbuf, sizeof(rbuf)); memset(&vndio, 0, sizeof(vndio)); vndio.vnd_file = __UNCONST(path); vndio.vnd_flags = VNDIOF_READONLY; fd = open(rbuf, O_RDWR); if (fd == -1) { /* * node doesn't exist? try creating it. use majors from * vnd0, which we (obviously) assume/hope exists */ if (errno == ENOENT) { const devmajor_t bmaj = getvndmajor(0); const devmajor_t rmaj = getvndmajor(1); if (mknod(bbuf, 0666 | S_IFBLK, MAKEDISKDEV(bmaj, nextvnd, RAW_PART)) == -1) err(1, "mknod %s", bbuf); if (mknod(rbuf, 0666 | S_IFBLK, MAKEDISKDEV(rmaj, nextvnd, RAW_PART)) == -1) err(1, "mknod %s", rbuf); fd = open(rbuf, O_RDWR); } if (fd == -1) err(1, "cannot open %s", rbuf); } if (ioctl(fd, VNDIOCSET, &vndio) == -1) err(1, "vndset failed"); close(fd); nextvnd++; return strdup(bbuf); }
int rlopen(dev_t dev, int flag, int fmt, struct lwp *l) { struct rl_softc * const rc = device_lookup_private(&rl_cd, DISKUNIT(dev)); struct rlc_softc *sc; int error, part, mask; struct disklabel *dl; const char *msg; /* * Make sure this is a reasonable open request. */ if (rc == NULL) return ENXIO; sc = rc->rc_rlc; part = DISKPART(dev); mutex_enter(&rc->rc_disk.dk_openlock); /* * If there are wedges, and this is not RAW_PART, then we * need to fail. */ if (rc->rc_disk.dk_nwedges != 0 && part != RAW_PART) { error = EBUSY; goto bad1; } /* Check that the disk actually is useable */ msg = rlstate(sc, rc->rc_hwid); if (msg == NULL || msg == rlstates[RLMP_UNLOAD] || msg == rlstates[RLMP_SPUNDOWN]) { error = ENXIO; goto bad1; } /* * If this is the first open; read in where on the disk we are. */ dl = rc->rc_disk.dk_label; if (rc->rc_state == DK_CLOSED) { u_int16_t mp; int maj; RL_WREG(RL_CS, RLCS_RHDR|(rc->rc_hwid << RLCS_USHFT)); waitcrdy(sc); mp = RL_RREG(RL_MP); rc->rc_head = ((mp & RLMP_HS) == RLMP_HS); rc->rc_cyl = (mp >> 7) & 0777; rc->rc_state = DK_OPEN; /* Get disk label */ maj = cdevsw_lookup_major(&rl_cdevsw); if ((msg = readdisklabel(MAKEDISKDEV(maj, device_unit(rc->rc_dev), RAW_PART), rlstrategy, dl, NULL))) aprint_normal_dev(rc->rc_dev, "%s", msg); aprint_normal_dev(rc->rc_dev, "size %d sectors\n", dl->d_secperunit); }
/* * Load the label information from the specified device. */ static void ldgetdisklabel(struct ld_softc *sc) { const char *errstring; ldgetdefaultlabel(sc, sc->sc_dk.dk_label); /* Call the generic disklabel extraction routine. */ errstring = readdisklabel(MAKEDISKDEV(0, sc->sc_dv.dv_unit, RAW_PART), ldstrategy, sc->sc_dk.dk_label, sc->sc_dk.dk_cpulabel); if (errstring != NULL) printf("%s: %s\n", sc->sc_dv.dv_xname, errstring); }
dev_t dev_rawpart(struct device *dv) { int majdev; majdev = findblkmajor(dv); switch (majdev) { /* add here any device you want to be checksummed on boot */ case 0: /* wd */ case 4: /* sd */ return (MAKEDISKDEV(majdev, dv->dv_unit, RAW_PART)); break; default: ; } return (NODEV); }
/* * Write disk label back to device after modification. */ int writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, struct cpu_disklabel *osdep) { struct buf *bp; struct disklabel *dlp; int labelpart; int error = 0; labelpart = DISKPART(dev); if (lp->d_partitions[labelpart].p_offset != 0) { if (lp->d_partitions[0].p_offset != 0) return EXDEV; /* not quite right */ labelpart = 0; } bp = geteblk((int)lp->d_secsize); bp->b_dev = MAKEDISKDEV(major(dev), DISKUNIT(dev), labelpart); bp->b_blkno = LABELSECTOR; bp->b_bcount = lp->d_secsize; bp->b_flags |= B_READ; (*strat)(bp); if ((error = biowait(bp)) != 0) goto done; for (dlp = (struct disklabel *)bp->b_data; dlp <= (struct disklabel *)((char *)bp->b_data + lp->d_secsize - sizeof(*dlp)); dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC && dkcksum(dlp) == 0) { *dlp = *lp; bp->b_oflags &= ~(BO_DONE); bp->b_flags &= ~(B_READ); bp->b_flags |= B_WRITE; (*strat)(bp); error = biowait(bp); goto done; } } error = ESRCH; done: brelse(bp, 0); return error; }
/* * Write disk label back to device after modification. */ int writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, struct cpu_disklabel *osdep) { struct buf *bp; #if 0 struct disklabel *dlp; #endif int labelpart; int error = 0; labelpart = DISKPART(dev); if (lp->d_partitions[labelpart].p_offset != 0) { if (lp->d_partitions[0].p_offset != 0) return (EXDEV); /* not quite right */ labelpart = 0; } /* * We always write a NeXT v3 disklabel, and a NetBSD disklabel in * the last sector of the NeXT label area. */ bp = geteblk(NEXT68K_LABEL_SIZE); bp->b_dev = MAKEDISKDEV(major(dev), DISKUNIT(dev), labelpart); bp->b_blkno = NEXT68K_LABEL_SECTOR; bp->b_bcount = NEXT68K_LABEL_SIZE; bp->b_flags |= B_WRITE; bp->b_cylinder = NEXT68K_LABEL_SECTOR / lp->d_secpercyl; error = build_nextstep_label ((struct next68k_disklabel *)bp->b_data, lp); if (error) goto done; #if 0 dlp = (struct disklabel *) ((char *)bp->b_data + LABELSECTOR * lp->d_secsize + LABELOFFSET); *dlp = *lp; #endif (*strat)(bp); error = biowait(bp); done: brelse(bp, 0); return (error); }
int rlopen(dev_t dev, int flag, int fmt, struct proc *p) { int part, unit, mask; struct disklabel *dl; struct rlc_softc *sc; struct rl_softc *rc; char *msg; /* * Make sure this is a reasonable open request. */ unit = DISKUNIT(dev); if (unit >= rl_cd.cd_ndevs) return ENXIO; rc = rl_cd.cd_devs[unit]; if (rc == 0) return ENXIO; sc = (struct rlc_softc *)rc->rc_dev.dv_parent; /* XXX - check that the disk actually is useable */ /* * If this is the first open; read in where on the disk we are. */ dl = rc->rc_disk.dk_label; if (rc->rc_state == DK_CLOSED) { u_int16_t mp; RL_WREG(RL_CS, RLCS_RHDR|(rc->rc_hwid << RLCS_USHFT)); waitcrdy(sc); mp = RL_RREG(RL_MP); rc->rc_head = ((mp & RLMP_HS) == RLMP_HS); rc->rc_cyl = (mp >> 7) & 0777; rc->rc_state = DK_OPEN; /* Get disk label */ printf("%s: ", rc->rc_dev.dv_xname); if ((msg = readdisklabel(MAKEDISKDEV(RLMAJOR, rc->rc_dev.dv_unit, RAW_PART), rlstrategy, dl, NULL))) printf("%s: ", msg); printf("size %d sectors\n", dl->d_secperunit); }
void rdattach(device_t parent, device_t self, void *aux) { struct hdcsoftc * const sc = device_private(parent); struct rdsoftc * const rd = device_private(self); struct hdc_attach_args * const ha = aux; struct disklabel *dl; const char *msg; rd->sc_dev = self; rd->sc_drive = ha->ha_drive; rd->sc_hdc = sc; /* * Initialize and attach the disk structure. */ disk_init(&rd->sc_disk, device_xname(rd->sc_dev), NULL); disk_attach(&rd->sc_disk); /* * if it's not a floppy then evaluate the on-disk geometry. * if necessary correct the label... */ rd_readgeom(sc, rd); disk_printtype(rd->sc_drive, rd->sc_xbn.media_id); dl = rd->sc_disk.dk_label; rdmakelabel(dl, &rd->sc_xbn); msg = readdisklabel(MAKEDISKDEV(cdevsw_lookup_major(&rd_cdevsw), device_unit(rd->sc_dev), RAW_PART), rdstrategy, dl, NULL); if (msg) aprint_normal_dev(self, "%s: size %u sectors", msg, dl->d_secperunit); else aprint_normal_dev(self, "size %u sectors\n", dl->d_secperunit); #ifdef RDDEBUG hdc_printgeom(&rd->sc_xbn); #endif }
void ofdisk_getdisklabel(dev_t dev) { int unit = DISKUNIT(dev); struct ofdisk_softc *of = device_lookup_private(&ofdisk_cd, unit); struct disklabel *lp = of->sc_dk.dk_label; const char *errmes; int l; ofdisk_getdefaultlabel(of, lp); /* * Don't read the disklabel on a floppy; simply * assign all partitions the same size/offset as * RAW_PART. (This is essentially what the ISA * floppy driver does, but we don't deal with * density stuff.) */ if (OFDISK_FLOPPY_P(of)) { lp->d_npartitions = MAXPARTITIONS; for (l = 0; l < lp->d_npartitions; l++) { if (l == RAW_PART) continue; /* struct copy */ lp->d_partitions[l] = lp->d_partitions[RAW_PART]; } lp->d_checksum = dkcksum(lp); } else { errmes = readdisklabel(MAKEDISKDEV(major(dev), unit, RAW_PART), ofdisk_strategy, lp, of->sc_dk.dk_cpulabel); if (errmes != NULL) printf("%s: %s\n", device_xname(of->sc_dev), errmes); } }
int dk_mountroot(void) { dev_t rawdev, rrootdev; int part = DISKPART(rootdev); int (*mountrootfn)(void); struct disklabel dl; int error; rrootdev = blktochr(rootdev); rawdev = MAKEDISKDEV(major(rrootdev), DISKUNIT(rootdev), RAW_PART); printf("rootdev=0x%x rrootdev=0x%x rawdev=0x%x\n", rootdev, rrootdev, rawdev); /* * open device, ioctl for the disklabel, and close it. */ error = (cdevsw[major(rrootdev)].d_open)(rawdev, FREAD, S_IFCHR, curproc); if (error) panic("cannot open disk, 0x%x/0x%x, error %d", rootdev, rrootdev, error); error = (cdevsw[major(rrootdev)].d_ioctl)(rawdev, DIOCGDINFO, (caddr_t)&dl, FREAD, curproc); if (error) panic("cannot read disk label, 0x%x/0x%x, error %d", rootdev, rrootdev, error); (void) (cdevsw[major(rrootdev)].d_close)(rawdev, FREAD, S_IFCHR, curproc); if (dl.d_partitions[part].p_size == 0) panic("root filesystem has size 0"); switch (dl.d_partitions[part].p_fstype) { #ifdef EXT2FS case FS_EXT2FS: { extern int ext2fs_mountroot(void); mountrootfn = ext2fs_mountroot; } break; #endif #ifdef FFS case FS_BSDFFS: { extern int ffs_mountroot(void); mountrootfn = ffs_mountroot; } break; #endif #ifdef CD9660 case FS_ISO9660: { extern int cd9660_mountroot(void); mountrootfn = cd9660_mountroot; } break; #endif default: #ifdef FFS { extern int ffs_mountroot(void); printf("filesystem type %d not known.. assuming ffs\n", dl.d_partitions[part].p_fstype); mountrootfn = ffs_mountroot; } #else panic("disk 0x%x/0x%x filesystem type %d not known", rootdev, rrootdev, dl.d_partitions[part].p_fstype); #endif } return (*mountrootfn)(); }
/* * XXX ugly bit of code. But, this is the only safe time that the * match between BIOS disks and native disks can be done. */ static void matchbiosdisks() { struct btinfo_biosgeom *big; struct bi_biosgeom_entry *be; struct device *dv; struct devnametobdevmaj *d; int i, ck, error, m, n; struct vnode *tv; char mbr[DEV_BSIZE]; big = lookup_bootinfo(BTINFO_BIOSGEOM); if (big == NULL) return; /* * First, count all native disks */ for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) if (dv->dv_class == DV_DISK && (!strcmp(dv->dv_cfdata->cf_driver->cd_name, "sd") || !strcmp(dv->dv_cfdata->cf_driver->cd_name, "wd"))) i386_ndisks++; if (i386_ndisks == 0) return; /* XXX M_TEMP is wrong */ i386_alldisks = malloc(sizeof (struct disklist) + (i386_ndisks - 1) * sizeof (struct nativedisk_info), M_TEMP, M_NOWAIT); if (i386_alldisks == NULL) return; i386_alldisks->dl_nnativedisks = i386_ndisks; i386_alldisks->dl_nbiosdisks = big->num; for (i = 0; i < big->num; i++) { i386_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev; i386_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec; i386_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head; i386_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl; i386_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec; i386_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags; } /* * XXX code duplication from findroot() */ n = -1; for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) { if (dv->dv_class != DV_DISK) continue; #ifdef GEOM_DEBUG printf("matchbiosdisks: trying to match (%s) %s\n", dv->dv_xname, dv->dv_cfdata->cf_driver->cd_name); #endif if (!strcmp(dv->dv_cfdata->cf_driver->cd_name, "sd") || !strcmp(dv->dv_cfdata->cf_driver->cd_name, "wd")) { n++; sprintf(i386_alldisks->dl_nativedisks[n].ni_devname, "%s%d", dv->dv_cfdata->cf_driver->cd_name, dv->dv_unit); for (d = i386_nam2blk; d->d_name && strcmp(d->d_name, dv->dv_cfdata->cf_driver->cd_name); d++); if (d->d_name == NULL) return; if (bdevvp(MAKEDISKDEV(d->d_maj, dv->dv_unit, RAW_PART), &tv)) panic("matchbiosdisks: can't alloc vnode"); error = VOP_OPEN(tv, FREAD, NOCRED, 0); if (error) { vrele(tv); continue; } error = vn_rdwr(UIO_READ, tv, mbr, DEV_BSIZE, 0, UIO_SYSSPACE, 0, NOCRED, NULL, 0); VOP_CLOSE(tv, FREAD, NOCRED, 0); if (error) { #ifdef GEOM_DEBUG printf("matchbiosdisks: %s: MBR read failure\n", dv->dv_xname); #endif continue; } for (ck = i = 0; i < DEV_BSIZE; i++) ck += mbr[i]; for (m = i = 0; i < big->num; i++) { be = &big->disk[i]; #ifdef GEOM_DEBUG printf("match %s with %d\n", dv->dv_xname, i); printf("dev ck %x bios ck %x\n", ck, be->cksum); #endif if (be->flags & BI_GEOM_INVALID) continue; if (be->cksum == ck && !memcmp(&mbr[MBR_PARTOFF], be->dosparts, NMBRPART * sizeof (struct mbr_partition))) { #ifdef GEOM_DEBUG printf("matched bios disk %x with %s\n", be->dev, be->devname); #endif i386_alldisks->dl_nativedisks[n]. ni_biosmatches[m++] = i; } } i386_alldisks->dl_nativedisks[n].ni_nmatches = m; vrele(tv); } } }
/* ARGSUSED */ int ldioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) { struct ld_softc *sc; int part, unit, error; #ifdef __HAVE_OLD_DISKLABEL struct disklabel newlabel; #endif struct disklabel *lp; unit = DISKUNIT(dev); part = DISKPART(dev); sc = device_lookup(&ld_cd, unit); error = 0; switch (cmd) { case DIOCGDINFO: memcpy(addr, sc->sc_dk.dk_label, sizeof(struct disklabel)); return (0); #ifdef __HAVE_OLD_DISKLABEL case ODIOCGDINFO: newlabel = *(sc->sc_dk.dk_label); if (newlabel.d_npartitions > OLDMAXPARTITIONS) return ENOTTY; memcpy(addr, &newlabel, sizeof(struct olddisklabel)); return (0); #endif case DIOCGPART: ((struct partinfo *)addr)->disklab = sc->sc_dk.dk_label; ((struct partinfo *)addr)->part = &sc->sc_dk.dk_label->d_partitions[part]; break; case DIOCWDINFO: case DIOCSDINFO: #ifdef __HAVE_OLD_DISKLABEL case ODIOCWDINFO: case ODIOCSDINFO: if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) { memset(&newlabel, 0, sizeof newlabel); memcpy(&newlabel, addr, sizeof (struct olddisklabel)); lp = &newlabel; } else #endif lp = (struct disklabel *)addr; if ((flag & FWRITE) == 0) return (EBADF); if ((error = ldlock(sc)) != 0) return (error); sc->sc_flags |= LDF_LABELLING; error = setdisklabel(sc->sc_dk.dk_label, lp, /*sc->sc_dk.dk_openmask : */0, sc->sc_dk.dk_cpulabel); if (error == 0 && (cmd == DIOCWDINFO #ifdef __HAVE_OLD_DISKLABEL || cmd == ODIOCWDINFO #endif )) error = writedisklabel( MAKEDISKDEV(major(dev), DISKUNIT(dev), RAW_PART), ldstrategy, sc->sc_dk.dk_label, sc->sc_dk.dk_cpulabel); sc->sc_flags &= ~LDF_LABELLING; ldunlock(sc); break; case DIOCWLABEL: if ((flag & FWRITE) == 0) return (EBADF); if (*(int *)addr) sc->sc_flags |= LDF_WLABEL; else sc->sc_flags &= ~LDF_WLABEL; break; case DIOCGDEFLABEL: ldgetdefaultlabel(sc, (struct disklabel *)addr); break; #ifdef __HAVE_OLD_DISKLABEL case ODIOCGDEFLABEL: ldgetdefaultlabel(sc, &newlabel); if (newlabel.d_npartitions > OLDMAXPARTITIONS) return ENOTTY; memcpy(addr, &newlabel, sizeof (struct olddisklabel)); break; #endif default: error = ENOTTY; break; } return (error); }
int ofdisk_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { struct ofdisk_softc *of = device_lookup_private(&ofdisk_cd, DISKUNIT(dev)); int error; #ifdef __HAVE_OLD_DISKLABEL struct disklabel newlabel; #endif switch (cmd) { case DIOCGDINFO: *(struct disklabel *)data = *of->sc_dk.dk_label; return 0; #ifdef __HAVE_OLD_DISKLABEL case ODIOCGDINFO: newlabel = *of->sc_dk.dk_label; if (newlabel.d_npartitions > OLDMAXPARTITIONS) return ENOTTY; memcpy(data, &newlabel, sizeof (struct olddisklabel)); return 0; #endif case DIOCGPART: ((struct partinfo *)data)->disklab = of->sc_dk.dk_label; ((struct partinfo *)data)->part = &of->sc_dk.dk_label->d_partitions[DISKPART(dev)]; return 0; case DIOCWDINFO: case DIOCSDINFO: #ifdef __HAVE_OLD_DISKLABEL case ODIOCWDINFO: case ODIOCSDINFO: #endif { struct disklabel *lp; #ifdef __HAVE_OLD_DISKLABEL if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) { memset(&newlabel, 0, sizeof newlabel); memcpy(&newlabel, data, sizeof (struct olddisklabel)); lp = &newlabel; } else #endif lp = (struct disklabel *)data; if ((flag & FWRITE) == 0) return EBADF; mutex_enter(&of->sc_dk.dk_openlock); error = setdisklabel(of->sc_dk.dk_label, lp, /*of->sc_dk.dk_openmask */0, of->sc_dk.dk_cpulabel); if (error == 0 && cmd == DIOCWDINFO #ifdef __HAVE_OLD_DISKLABEL || xfer == ODIOCWDINFO #endif ) error = writedisklabel(MAKEDISKDEV(major(dev), DISKUNIT(dev), RAW_PART), ofdisk_strategy, of->sc_dk.dk_label, of->sc_dk.dk_cpulabel); mutex_exit(&of->sc_dk.dk_openlock); return error; } case DIOCGDEFLABEL: ofdisk_getdefaultlabel(of, (struct disklabel *)data); return 0; #ifdef __HAVE_OLD_DISKLABEL case DIOCGDEFLABEL: ofdisk_getdefaultlabel(of, &newlabel); if (newlabel.d_npartitions > OLDMAXPARTITIONS) return ENOTTY; memcpy(data, &newlabel, sizeof (struct olddisklabel)); return 0; #endif case DIOCAWEDGE: { struct dkwedge_info *dkw = (void *) data; if (OFDISK_FLOPPY_P(of)) return (ENOTTY); if ((flag & FWRITE) == 0) return (EBADF); /* If the ioctl happens here, the parent is us. */ strlcpy(dkw->dkw_parent, device_xname(of->sc_dev), sizeof(dkw->dkw_parent)); return (dkwedge_add(dkw)); } case DIOCDWEDGE: { struct dkwedge_info *dkw = (void *) data; if (OFDISK_FLOPPY_P(of)) return (ENOTTY); if ((flag & FWRITE) == 0) return (EBADF); /* If the ioctl happens here, the parent is us. */ strlcpy(dkw->dkw_parent, device_xname(of->sc_dev), sizeof(dkw->dkw_parent)); return (dkwedge_del(dkw)); } case DIOCLWEDGES: { struct dkwedge_list *dkwl = (void *) data; if (OFDISK_FLOPPY_P(of)) return (ENOTTY); return (dkwedge_list(&of->sc_dk, dkwl, l)); } default: return ENOTTY; } }
/* * Helper function for findroot(): * Return non-zero if disk device matches bootinfo. */ static int match_bootdisk(struct device *dv, struct btinfo_bootdisk *bid) { struct vnode *tmpvn; int error; struct disklabel label; int found = 0; int bmajor; /* * A disklabel is required here. The boot loader doesn't refuse * to boot from a disk without a label, but this is normally not * wanted. */ if (bid->labelsector == -1) return (0); /* * Lookup major number for disk block device. */ bmajor = devsw_name2blk(dv->dv_xname, NULL, 0); if (bmajor == -1) return (0); /* XXX panic ??? */ /* * Fake a temporary vnode for the disk, open it, and read * the disklabel for comparison. */ if (bdevvp(MAKEDISKDEV(bmajor, dv->dv_unit, RAW_PART), &tmpvn)) panic("match_bootdisk: can't alloc vnode"); error = VOP_OPEN(tmpvn, FREAD, NOCRED); if (error) { #ifndef DEBUG /* * Ignore errors caused by missing device, partition, * or medium. */ if (error != ENXIO && error != ENODEV) #endif printf("match_bootdisk: can't open dev %s (%d)\n", dv->dv_xname, error); vput(tmpvn); return (0); } error = VOP_IOCTL(tmpvn, DIOCGDINFO, &label, FREAD, NOCRED); if (error) { /* * XXX Can't happen -- open() would have errored out * or faked one up. */ printf("match_bootdisk: can't get label for dev %s (%d)\n", dv->dv_xname, error); goto closeout; } /* Compare with our data. */ if (label.d_type == bid->label.type && label.d_checksum == bid->label.checksum && strncmp(label.d_packname, bid->label.packname, 16) == 0) found = 1; closeout: VOP_CLOSE(tmpvn, FREAD, NOCRED); vput(tmpvn); return (found); }
u_long ramd_size; /* Size of disk in bytes */ u_long ramd_flag; /* see defs below */ dev_t ramd_dev; /* device to load from */ }; /* * ramd_flag: */ #define RAMD_LOAD 0x01 /* Auto load when first opened */ #define RAMD_LCOMP 0x02 /* Input is compressed */ struct ramd_info rd_info[RAMD_NDEV] = { { 1105920, /* 1Mb in 2160 sectors */ RAMD_LOAD, /* auto-load this device */ MAKEDISKDEV(2, 0, 2), /* XXX: This is crap! (720Kb flop) */ }, { 1474560, /* 1.44Mb in 2880 sectors */ RAMD_LOAD, /* auto-load this device */ MAKEDISKDEV(2, 0, 2), /* XXX: This is crap! (720Kb flop) */ }, { 1474560, /* 1.44Mb in 2880 sectors */ RAMD_LOAD, /* auto-load this device */ MAKEDISKDEV(2, 0, 3), /* XXX: This is crap! (1.44Mb flop) */ } }; struct read_info { struct buf *bp; /* buffer for strategy function */