示例#1
0
/*
 * Fabricate a default disk label, and try to read the correct one.
 */
static void
edgetdisklabel(dev_t dev, struct ed_softc *ed)
{
    struct disklabel *lp = ed->sc_dk.dk_label;
    const char *errstring;

    ATADEBUG_PRINT(("edgetdisklabel\n"), DEBUG_FUNCS);

    memset(ed->sc_dk.dk_cpulabel, 0, sizeof(struct cpu_disklabel));

    edgetdefaultlabel(ed, lp);

    errstring = readdisklabel(
                    EDLABELDEV(dev), edmcastrategy, lp, ed->sc_dk.dk_cpulabel);
    if (errstring) {
        /*
         * This probably happened because the drive's default
         * geometry doesn't match the DOS geometry.  We
         * assume the DOS geometry is now in the label and try
         * again.  XXX This is a kluge.
         */
#if 0
        if (wd->drvp->state > RECAL)
            wd->drvp->drive_flags |= ATA_DRIVE_RESET;
#endif
        errstring = readdisklabel(EDLABELDEV(dev),
                                  edmcastrategy, lp, ed->sc_dk.dk_cpulabel);
    }
    if (errstring) {
        printf("%s: %s\n", device_xname(ed->sc_dev), errstring);
        return;
    }
}
示例#2
0
/*
 * Read the disklabel. If none is present, use a fictitious one instead.
 */
void
presto_getdisklabel(struct presto_softc *sc)
{
	struct disklabel *lp = sc->sc_dk.dk_label;

	bzero(sc->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
	bzero(sc->sc_dk.dk_label, sizeof(struct disklabel));

	lp->d_secsize = DEV_BSIZE;
	lp->d_ntracks = 1;
	lp->d_nsectors = 32;
	lp->d_secperunit = (sc->sc_memsize - PSERVE_OFFSET) >> DEV_BSHIFT;
	lp->d_ncylinders = lp->d_secperunit / lp->d_nsectors;
	lp->d_secpercyl = lp->d_nsectors;

	strncpy(lp->d_typename, "Prestoserve", 16);
	lp->d_type = DTYPE_SCSI;	/* what better to put here? */
	strncpy(lp->d_packname, sc->sc_model, 16);
	lp->d_rpm = 3600;
	lp->d_interleave = 1;

	lp->d_partitions[RAW_PART].p_offset = 0;
	lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
	lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
	lp->d_npartitions = RAW_PART + 1;

	lp->d_magic = DISKMAGIC;
	lp->d_magic2 = DISKMAGIC;
	lp->d_checksum = dkcksum(lp);

	readdisklabel(DISKLABELDEV(sc->sc_dev.dv_unit), prestostrategy,
	    sc->sc_dk.dk_label, sc->sc_dk.dk_cpulabel, 0);
}
示例#3
0
文件: rd.c 项目: sofuture/bitrig
int
rdgetdisklabel(dev_t dev, struct rd_softc *sc, struct disklabel *lp,
    int spoofonly)
{
	bzero(lp, sizeof(struct disklabel));

	lp->d_secsize = DEV_BSIZE;
	lp->d_ntracks = 1;
	lp->d_nsectors = rd_root_size >> DEV_BSHIFT;
	lp->d_ncylinders = 1;
	lp->d_secpercyl = lp->d_nsectors;
	if (lp->d_secpercyl == 0) {
		lp->d_secpercyl = 100;
		/* as long as it's not 0 - readdisklabel divides by it */
	}

	strncpy(lp->d_typename, "RAM disk", sizeof(lp->d_typename));
	lp->d_type = DTYPE_SCSI;
	strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
	DL_SETDSIZE(lp, lp->d_nsectors);
	lp->d_version = 1;

	lp->d_magic = DISKMAGIC;
	lp->d_magic2 = DISKMAGIC;
	lp->d_checksum = dkcksum(lp);

	/* Call the generic disklabel extraction routine. */
	return (readdisklabel(DISKLABELDEV(dev), rdstrategy, lp, spoofonly));
}
示例#4
0
int
fdgetdisklabel(dev_t dev, struct fd_softc *fd, struct disklabel *lp,
    int spoofonly)
{
	bzero(lp, sizeof(struct disklabel));

	lp->d_type = DTYPE_FLOPPY;
	lp->d_secsize = FD_BSIZE(fd);
	lp->d_secpercyl = fd->sc_type->seccyl;
	lp->d_nsectors = fd->sc_type->sectrac;
	lp->d_ncylinders = fd->sc_type->tracks;
	lp->d_ntracks = fd->sc_type->heads;	/* Go figure... */
	DL_SETDSIZE(lp, fd->sc_type->size);

	strncpy(lp->d_typename, "floppy disk", sizeof(lp->d_typename));
	strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
	lp->d_version = 1;

	lp->d_magic = DISKMAGIC;
	lp->d_magic2 = DISKMAGIC;
	lp->d_checksum = dkcksum(lp);

	/*
	 * Call the generic disklabel extraction routine.  If there's
	 * not a label there, fake it.
	 */
	return readdisklabel(DISKLABELDEV(dev), fdstrategy, lp, spoofonly);
}
示例#5
0
/*
 * (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;
}
示例#6
0
/*
 * Load the label information on the named device
 */
int
vndgetdisklabel(dev_t dev, struct vnd_softc *sc, struct disklabel *lp,
    int spoofonly)
{
	memset(lp, 0, sizeof(struct disklabel));

	lp->d_secsize = sc->sc_secsize;
	lp->d_nsectors = sc->sc_nsectors;
	lp->d_ntracks = sc->sc_ntracks;
	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
	lp->d_ncylinders = sc->sc_size / lp->d_secpercyl;

	strncpy(lp->d_typename, "vnd device", sizeof(lp->d_typename));
	lp->d_type = DTYPE_VND;
	strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
	DL_SETDSIZE(lp, sc->sc_size);
	lp->d_flags = 0;
	lp->d_version = 1;

	lp->d_magic = DISKMAGIC;
	lp->d_magic2 = DISKMAGIC;
	lp->d_checksum = dkcksum(lp);

	/* Call the generic disklabel extraction routine */
	return readdisklabel(DISKLABELDEV(dev), vndstrategy, lp, spoofonly);
}
示例#7
0
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);
	}
示例#8
0
文件: ld.c 项目: MarginC/kame
/*
 * 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);
}
示例#9
0
/*
 * Read the disklabel from a vnd.  If one is not present, create a fake one.
 */
static void
vndgetdisklabel(dev_t dev, struct vnd_softc *sc)
{
	const char *errstring;
	struct disklabel *lp = sc->sc_dkdev.dk_label;
	struct cpu_disklabel *clp = sc->sc_dkdev.dk_cpulabel;
	int i;

	memset(clp, 0, sizeof(*clp));

	vndgetdefaultlabel(sc, lp);

	/*
	 * Call the generic disklabel extraction routine.
	 */
	errstring = readdisklabel(VNDLABELDEV(dev), vndstrategy, lp, clp);
	if (errstring) {
		/*
		 * Lack of disklabel is common, but we print the warning
		 * anyway, since it might contain other useful information.
		 */
		aprint_normal_dev(sc->sc_dev, "%s\n", errstring);

		/*
		 * For historical reasons, if there's no disklabel
		 * present, all partitions must be FS_BSDFFS and
		 * occupy the entire disk.
		 */
		for (i = 0; i < MAXPARTITIONS; i++) {
			/*
			 * Don't wipe out port specific hack (such as
			 * dos partition hack of i386 port).
			 */
			if (lp->d_partitions[i].p_size != 0)
				continue;

			lp->d_partitions[i].p_size = lp->d_secperunit;
			lp->d_partitions[i].p_offset = 0;
			lp->d_partitions[i].p_fstype = FS_BSDFFS;
		}

		strncpy(lp->d_packname, "default label",
		    sizeof(lp->d_packname));

		lp->d_npartitions = MAXPARTITIONS;
		lp->d_checksum = dkcksum(lp);
	}
}
示例#10
0
/*
 * Fabricate a default disk label, and try to read the correct one.
 */
int
wdgetdisklabel(dev_t dev, struct wd_softc *wd, struct disklabel *lp,
    int spoofonly)
{
	int error;

	WDCDEBUG_PRINT(("wdgetdisklabel\n"), DEBUG_FUNCS);

	wdgetdefaultlabel(wd, lp);

	if (wd->drvp->state > RECAL)
		wd->drvp->drive_flags |= DRIVE_RESET;
	error = readdisklabel(DISKLABELDEV(dev), wdstrategy, lp,
	    spoofonly);
	if (wd->drvp->state > RECAL)
		wd->drvp->drive_flags |= DRIVE_RESET;
	return (error);
}
示例#11
0
/* ARGSUSED */
void
dk_getdisklabel(struct dk_softc *dksc, dev_t dev)
{
	const struct dkdriver *dkd = dksc->sc_dkdev.dk_driver;
	struct	 disklabel *lp = dksc->sc_dkdev.dk_label;
	struct	 cpu_disklabel *clp = dksc->sc_dkdev.dk_cpulabel;
	struct   disk_geom *dg = &dksc->sc_dkdev.dk_geom;
	struct	 partition *pp;
	int	 i;
	const char	*errstring;

	memset(clp, 0x0, sizeof(*clp));
	dk_getdefaultlabel(dksc, lp);
	errstring = readdisklabel(DKLABELDEV(dev), dkd->d_strategy,
	    dksc->sc_dkdev.dk_label, dksc->sc_dkdev.dk_cpulabel);
	if (errstring) {
		dk_makedisklabel(dksc);
		if (dksc->sc_flags & DKF_WARNLABEL)
			printf("%s: %s\n", dksc->sc_xname, errstring);
		return;
	}

	if ((dksc->sc_flags & DKF_LABELSANITY) == 0)
		return;

	/* Sanity check */
	if (lp->d_secperunit < UINT32_MAX ?
		lp->d_secperunit != dg->dg_secperunit :
		lp->d_secperunit > dg->dg_secperunit)
		printf("WARNING: %s: total sector size in disklabel (%ju) "
		    "!= the size of %s (%ju)\n", dksc->sc_xname,
		    (uintmax_t)lp->d_secperunit, dksc->sc_xname,
		    (uintmax_t)dg->dg_secperunit);

	for (i=0; i < lp->d_npartitions; i++) {
		pp = &lp->d_partitions[i];
		if (pp->p_offset + pp->p_size > dg->dg_secperunit)
			printf("WARNING: %s: end of partition `%c' exceeds "
			    "the size of %s (%ju)\n", dksc->sc_xname,
			    'a' + i, dksc->sc_xname,
			    (uintmax_t)dg->dg_secperunit);
	}
}
示例#12
0
/*
 * Read the disklabel from the ccd.  If one is not present, fake one
 * up.
 */
void
ccdgetdisklabel(dev_t dev, struct ccd_softc *cs, struct disklabel *lp,
    struct cpu_disklabel *clp, int spoofonly)
{
	struct ccdgeom *ccg = &cs->sc_geom;
	char *errstring;

	bzero(lp, sizeof(*lp));
	bzero(clp, sizeof(*clp));

	lp->d_secperunit = cs->sc_size;
	lp->d_secsize = ccg->ccg_secsize;
	lp->d_nsectors = ccg->ccg_nsectors;
	lp->d_ntracks = ccg->ccg_ntracks;
	lp->d_ncylinders = ccg->ccg_ncylinders;
	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
	lp->d_rpm = ccg->ccg_rpm;

	strncpy(lp->d_typename, "ccd", sizeof(lp->d_typename));
	lp->d_type = DTYPE_CCD;
	strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
	lp->d_interleave = 1;
	lp->d_flags = 0;

	lp->d_partitions[RAW_PART].p_offset = 0;
	lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
	lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
	lp->d_npartitions = RAW_PART + 1;

	lp->d_magic = DISKMAGIC;
	lp->d_magic2 = DISKMAGIC;
	lp->d_checksum = dkcksum(cs->sc_dkdev.dk_label);

	/*
	 * Call the generic disklabel extraction routine.
	 */
	errstring = readdisklabel(CCDLABELDEV(dev), ccdstrategy,
	    cs->sc_dkdev.dk_label, cs->sc_dkdev.dk_cpulabel, spoofonly);
	/* It's actually extremely common to have unlabeled ccds. */
	if (errstring != NULL)
		CCD_DPRINTF(CCDB_LABEL, ("%s: %s\n", cs->sc_xname, errstring));
}
示例#13
0
文件: rl.c 项目: MarginC/kame
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);
	}
示例#14
0
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
}
示例#15
0
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);
	}
}
示例#16
0
/* ARGSUSED */
void
dk_getdisklabel(struct dk_intf *di, struct dk_softc *dksc, dev_t dev)
{
	struct	 disklabel *lp = dksc->sc_dkdev.dk_label;
	struct	 cpu_disklabel *clp = dksc->sc_dkdev.dk_cpulabel;
	struct	 partition *pp;
	int	 i;
	const char	*errstring;

	memset(clp, 0x0, sizeof(*clp));
	dk_getdefaultlabel(di, dksc, lp);
	errstring = readdisklabel(DKLABELDEV(dev), di->di_strategy,
	    dksc->sc_dkdev.dk_label, dksc->sc_dkdev.dk_cpulabel);
	if (errstring) {
		dk_makedisklabel(di, dksc);
		if (dksc->sc_flags & DKF_WARNLABEL)
			printf("%s: %s\n", dksc->sc_xname, errstring);
		return;
	}

	if ((dksc->sc_flags & DKF_LABELSANITY) == 0)
		return;

	/* Sanity check */
	if (lp->d_secperunit != dksc->sc_size)
		printf("WARNING: %s: total sector size in disklabel (%d) "
		    "!= the size of %s (%lu)\n", dksc->sc_xname,
		    lp->d_secperunit, di->di_dkname, (u_long)dksc->sc_size);

	for (i=0; i < lp->d_npartitions; i++) {
		pp = &lp->d_partitions[i];
		if (pp->p_offset + pp->p_size > dksc->sc_size)
			printf("WARNING: %s: end of partition `%c' exceeds "
			    "the size of %s (%lu)\n", dksc->sc_xname,
			    'a' + i, di->di_dkname, (u_long)dksc->sc_size);
	}
}
示例#17
0
/*
 * Load the label information on the named device
 * Actually fabricate a disklabel
 *
 * EVENTUALLY take information about different
 * data tracks from the TOC and put it in the disklabel
 */
void
cdgetdisklabel(dev_t dev, struct cd_softc *cd, struct disklabel *lp,
    int spoofonly)
{
	struct cd_toc *toc;
	char *errstring;
	int tocidx, n, audioonly = 1;

	bzero(lp, sizeof(struct disklabel));

	toc = malloc(sizeof(*toc), M_TEMP, M_WAITOK | M_ZERO);

	lp->d_secsize = cd->params.blksize;
	lp->d_ntracks = 1;
	lp->d_nsectors = 100;
	lp->d_secpercyl = 100;
	lp->d_ncylinders = (cd->params.disksize / 100) + 1;

	if (cd->sc_link->flags & SDEV_ATAPI) {
		strncpy(lp->d_typename, "ATAPI CD-ROM", sizeof(lp->d_typename));
		lp->d_type = DTYPE_ATAPI;
	} else {
		strncpy(lp->d_typename, "SCSI CD-ROM", sizeof(lp->d_typename));
		lp->d_type = DTYPE_SCSI;
	}

	strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
	DL_SETDSIZE(lp, cd->params.disksize);
	lp->d_rpm = 300;
	lp->d_interleave = 1;
	lp->d_version = 1;

	/* XXX - these values for BBSIZE and SBSIZE assume ffs */
	lp->d_bbsize = BBSIZE;
	lp->d_sbsize = SBSIZE;

	lp->d_magic = DISKMAGIC;
	lp->d_magic2 = DISKMAGIC;
	lp->d_checksum = dkcksum(lp);

	if (cd_load_toc(cd, toc, CD_LBA_FORMAT)) {
		audioonly = 0; /* No valid TOC found == not an audio CD. */
		goto done;
	}

	n = toc->header.ending_track - toc->header.starting_track + 1;
	for (tocidx = 0; tocidx < n; tocidx++)
		if (toc->entries[tocidx].control & 4) {
			audioonly = 0; /* Found a non-audio track. */
			goto done;
		}

done:
	free(toc, M_TEMP);

	if (!audioonly) {
		errstring = readdisklabel(DISKLABELDEV(dev), cdstrategy, lp,
		    spoofonly);
		/*if (errstring)
			printf("%s: %s\n", cd->sc_dev.dv_xname, errstring);*/
	}
}
示例#18
0
/*
 * Load the label information on the named device
 */
int
sdgetdisklabel(dev_t dev, struct sd_softc *sc, struct disklabel *lp,
    int spoofonly)
{
	size_t len;
	char packname[sizeof(lp->d_packname) + 1];
	char product[17], vendor[9];

	bzero(lp, sizeof(struct disklabel));

	lp->d_secsize = sc->params.secsize;
	lp->d_ntracks = sc->params.heads;
	lp->d_nsectors = sc->params.sectors;
	lp->d_ncylinders = sc->params.cyls;
	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
	if (lp->d_secpercyl == 0) {
		lp->d_secpercyl = 100;
		/* as long as it's not 0 - readdisklabel divides by it */
	}

	lp->d_type = DTYPE_SCSI;
	if ((sc->sc_link->inqdata.device & SID_TYPE) == T_OPTICAL)
		strncpy(lp->d_typename, "SCSI optical",
		    sizeof(lp->d_typename));
	else
		strncpy(lp->d_typename, "SCSI disk",
		    sizeof(lp->d_typename));

	/*
	 * Try to fit '<vendor> <product>' into d_packname. If that doesn't fit
	 * then leave out '<vendor> ' and use only as much of '<product>' as
	 * does fit.
	 */
	viscpy(vendor, sc->sc_link->inqdata.vendor, 8);
	viscpy(product, sc->sc_link->inqdata.product, 16);
	len = snprintf(packname, sizeof(packname), "%s %s", vendor, product);
	if (len > sizeof(lp->d_packname)) {
		strlcpy(packname, product, sizeof(packname));
		len = strlen(packname);
	}
	/*
	 * It is safe to use len as the count of characters to copy because
	 * packname is sizeof(lp->d_packname)+1, the string in packname is
	 * always null terminated and len does not count the terminating null.
	 * d_packname is not a null terminated string.
	 */
	bcopy(packname, lp->d_packname, len);

	DL_SETDSIZE(lp, sc->params.disksize);
	lp->d_version = 1;
	lp->d_flags = 0;

	/* XXX - these values for BBSIZE and SBSIZE assume ffs */
	lp->d_bbsize = BBSIZE;
	lp->d_sbsize = SBSIZE;

	lp->d_magic = DISKMAGIC;
	lp->d_magic2 = DISKMAGIC;
	lp->d_checksum = dkcksum(lp);

	/*
	 * Call the generic disklabel extraction routine
	 */
	return readdisklabel(DISKLABELDEV(dev), sdstrategy, lp, spoofonly);
}
示例#19
0
文件: fd.c 项目: lacombar/netbsd-alc
int
fdioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
{
	struct fd_softc *fd =
	    device_lookup_private(&fd_cd, FDUNIT(dev));
	struct fdformat_parms *form_parms;
	struct fdformat_cmd *form_cmd;
	struct ne7_fd_formb *fd_formb;
	struct disklabel buffer;
	int error;
	unsigned int scratch;
	int il[FD_MAX_NSEC + 1];
	int i, j;
#ifdef __HAVE_OLD_DISKLABEL
	struct disklabel newlabel;
#endif

	switch (cmd) {
	case DIOCGDINFO:
#ifdef __HAVE_OLD_DISKLABEL
	case ODIOCGDINFO:
#endif
		memset(&buffer, 0, sizeof(buffer));

		buffer.d_secpercyl = fd->sc_type->seccyl;
		buffer.d_type = DTYPE_FLOPPY;
		buffer.d_secsize = FDC_BSIZE;

		if (readdisklabel(dev, fdstrategy, &buffer, NULL) != NULL)
			return EINVAL;

#ifdef __HAVE_OLD_DISKLABEL
		if (cmd == ODIOCGDINFO) {
			if (buffer.d_npartitions > OLDMAXPARTITIONS)
				return ENOTTY;
			memcpy(addr, &buffer, sizeof (struct olddisklabel));
		} else
#endif
		*(struct disklabel *)addr = buffer;
		return 0;

	case DIOCWLABEL:
		if ((flag & FWRITE) == 0)
			return EBADF;
		/* XXX do something */
		return 0;

	case DIOCWDINFO:
#ifdef __HAVE_OLD_DISKLABEL
	case ODIOCWDINFO:
#endif
	{
		struct disklabel *lp;

		if ((flag & FWRITE) == 0)
			return EBADF;
#ifdef __HAVE_OLD_DISKLABEL
		if (cmd == ODIOCWDINFO) {
			memset(&newlabel, 0, sizeof newlabel);
			memcpy(&newlabel, addr, sizeof (struct olddisklabel));
			lp = &newlabel;
		} else
#endif
		lp = (struct disklabel *)addr;

		error = setdisklabel(&buffer, lp, 0, NULL);
		if (error)
			return error;

		error = writedisklabel(dev, fdstrategy, &buffer, NULL);
		return error;
	}

	case FDIOCGETFORMAT:
		form_parms = (struct fdformat_parms *)addr;
		form_parms->fdformat_version = FDFORMAT_VERSION;
		form_parms->nbps = 128 * (1 << fd->sc_type->secsize);
		form_parms->ncyl = fd->sc_type->cyls;
		form_parms->nspt = fd->sc_type->sectrac;
		form_parms->ntrk = fd->sc_type->heads;
		form_parms->stepspercyl = fd->sc_type->step;
		form_parms->gaplen = fd->sc_type->gap2;
		form_parms->fillbyte = fd->sc_type->fillbyte;
		form_parms->interleave = fd->sc_type->interleave;
		switch (fd->sc_type->rate) {
		case FDC_500KBPS:
			form_parms->xfer_rate = 500 * 1024;
			break;
		case FDC_300KBPS:
			form_parms->xfer_rate = 300 * 1024;
			break;
		case FDC_250KBPS:
			form_parms->xfer_rate = 250 * 1024;
			break;
		default:
			return EINVAL;
		}
		return 0;

	case FDIOCSETFORMAT:
		if((flag & FWRITE) == 0)
			return EBADF;	/* must be opened for writing */
		form_parms = (struct fdformat_parms *)addr;
		if (form_parms->fdformat_version != FDFORMAT_VERSION)
			return EINVAL;	/* wrong version of formatting prog */

		scratch = form_parms->nbps >> 7;
		if ((form_parms->nbps & 0x7f) || ffs(scratch) == 0 ||
		    scratch & ~(1 << (ffs(scratch)-1)))
			/* not a power-of-two multiple of 128 */
			return EINVAL;

		switch (form_parms->xfer_rate) {
		case 500 * 1024:
			fd->sc_type->rate = FDC_500KBPS;
			break;
		case 300 * 1024:
			fd->sc_type->rate = FDC_300KBPS;
			break;
		case 250 * 1024:
			fd->sc_type->rate = FDC_250KBPS;
			break;
		default:
			return EINVAL;
		}

		if (form_parms->nspt > FD_MAX_NSEC ||
		    form_parms->fillbyte > 0xff ||
		    form_parms->interleave > 0xff)
			return EINVAL;
		fd->sc_type->sectrac = form_parms->nspt;
		if (form_parms->ntrk != 2 && form_parms->ntrk != 1)
			return EINVAL;
		fd->sc_type->heads = form_parms->ntrk;
		fd->sc_type->seccyl = form_parms->nspt * form_parms->ntrk;
		fd->sc_type->secsize = ffs(scratch)-1;
		fd->sc_type->gap2 = form_parms->gaplen;
		fd->sc_type->cyls = form_parms->ncyl;
		fd->sc_type->size = fd->sc_type->seccyl * form_parms->ncyl *
		    form_parms->nbps / DEV_BSIZE;
		fd->sc_type->step = form_parms->stepspercyl;
		fd->sc_type->fillbyte = form_parms->fillbyte;
		fd->sc_type->interleave = form_parms->interleave;
		return 0;

	case FDIOCFORMAT_TRACK:
		if((flag & FWRITE) == 0)
			return EBADF;	/* must be opened for writing */
		form_cmd = (struct fdformat_cmd *)addr;
		if (form_cmd->formatcmd_version != FDFORMAT_VERSION)
			return EINVAL;	/* wrong version of formatting prog */

		if (form_cmd->head >= fd->sc_type->heads ||
		    form_cmd->cylinder >= fd->sc_type->cyls) {
			return EINVAL;
		}

		fd_formb = malloc(sizeof(struct ne7_fd_formb),
		    M_TEMP, M_NOWAIT);
		if (fd_formb == 0)
			return ENOMEM;

		fd_formb->head = form_cmd->head;
		fd_formb->cyl = form_cmd->cylinder;
		fd_formb->transfer_rate = fd->sc_type->rate;
		fd_formb->fd_formb_secshift = fd->sc_type->secsize;
		fd_formb->fd_formb_nsecs = fd->sc_type->sectrac;
		fd_formb->fd_formb_gaplen = fd->sc_type->gap2;
		fd_formb->fd_formb_fillbyte = fd->sc_type->fillbyte;

		memset(il, 0, sizeof il);
		for (j = 0, i = 1; i <= fd_formb->fd_formb_nsecs; i++) {
			while (il[(j%fd_formb->fd_formb_nsecs)+1])
				j++;
			il[(j%fd_formb->fd_formb_nsecs)+1] = i;
			j += fd->sc_type->interleave;
		}
		for (i = 0; i < fd_formb->fd_formb_nsecs; i++) {
			fd_formb->fd_formb_cylno(i) = form_cmd->cylinder;
			fd_formb->fd_formb_headno(i) = form_cmd->head;
			fd_formb->fd_formb_secno(i) = il[i+1];
			fd_formb->fd_formb_secsize(i) = fd->sc_type->secsize;
		}

		error = fdformat(dev, fd_formb, l);
		free(fd_formb, M_TEMP);
		return error;

	case FDIOCGETOPTS:		/* get drive options */
		*(int *)addr = fd->sc_opts;
		return 0;

	case FDIOCSETOPTS:		/* set drive options */
		fd->sc_opts = *(int *)addr;
		return 0;

	default:
		return ENOTTY;
	}

#ifdef DIAGNOSTIC
	panic("fdioctl: impossible");
#endif
}