⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1988 University of Utah. * Copyright (c) 1990, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer * Science Department. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: Utah $Hdr: cd.c 1.6 90/11/28$ * *	@(#)cd.c	8.2 (Berkeley) 11/16/93 *//* * "Concatenated" disk driver. */#include "cd.h"#if NCD > 0#include <sys/param.h>#include <sys/systm.h>#include <sys/proc.h>#include <sys/errno.h>#include <sys/dkstat.h>#include <sys/buf.h>#include <sys/malloc.h>#include <sys/conf.h>#include <sys/stat.h>#ifdef COMPAT_NOLABEL#include <sys/ioctl.h>#include <sys/disklabel.h>#include <sys/fcntl.h>#endif#include <dev/cdvar.h>#ifdef DEBUGint cddebug = 0x00;#define CDB_FOLLOW	0x01#define CDB_INIT	0x02#define CDB_IO		0x04#endifstruct	buf *cdbuffer();char	*cddevtostr();void	cdiodone();#define	cdunit(x)	((minor(x) >> 3) & 0xf)	/* for consistency */#define	getcbuf()	\	((struct buf *)malloc(sizeof(struct buf), M_DEVBUF, M_WAITOK))#define putcbuf(bp)	\	free((caddr_t)(bp), M_DEVBUF)struct cd_softc {	int		 sc_flags;		/* flags */	size_t		 sc_size;		/* size of cd */	int		 sc_ileave;		/* interleave */	int		 sc_ncdisks;		/* number of components */	struct cdcinfo	 sc_cinfo[NCDISKS];	/* component info */	struct cdiinfo	 *sc_itable;		/* interleave table */	int		 sc_usecnt;		/* number of requests active */	int		 sc_dk;			/* disk index */};/* sc_flags */#define	CDF_ALIVE	0x01#define CDF_INITED	0x02struct cd_softc *cd_softc;int numcd;/* * Since this is called after auto-configuration of devices, * we can handle the initialization here. * * XXX this will not work if you want to use a cd as your primary * swap device since swapconf() has been called before now. */voidcdattach(num)	int num;{	char *mem;	register u_long size;	register struct cddevice *cd;	extern int dkn;	if (num <= 0)		return;	size = num * sizeof(struct cd_softc);	mem = malloc(size, M_DEVBUF, M_NOWAIT);	if (mem == NULL) {		printf("WARNING: no memory for concatonated disks\n");		return;	}	bzero(mem, size);	cd_softc = (struct cd_softc *)mem;	numcd = num;	for (cd = cddevice; cd->cd_unit >= 0; cd++) {		/*		 * XXX		 * Assign disk index first so that init routine		 * can use it (saves having the driver drag around		 * the cddevice pointer just to set up the dk_*		 * info in the open routine).		 */		if (dkn < DK_NDRIVE)			cd->cd_dk = dkn++;		else			cd->cd_dk = -1;		if (cdinit(cd))			printf("cd%d configured\n", cd->cd_unit);		else if (cd->cd_dk >= 0) {			cd->cd_dk = -1;			dkn--;		}	}}cdinit(cd)	struct cddevice *cd;{	register struct cd_softc *cs = &cd_softc[cd->cd_unit];	register struct cdcinfo *ci;	register size_t size;	register int ix;	size_t minsize;	dev_t dev;	struct bdevsw *bsw;	int error;	struct proc *p = curproc; /* XXX */#ifdef DEBUG	if (cddebug & (CDB_FOLLOW|CDB_INIT))		printf("cdinit: unit %d\n", cd->cd_unit);#endif	cs->sc_dk = cd->cd_dk;	cs->sc_size = 0;	cs->sc_ileave = cd->cd_interleave;	cs->sc_ncdisks = 0;	/*	 * Verify that each component piece exists and record	 * relevant information about it.	 */	minsize = 0;	for (ix = 0; ix < NCDISKS; ix++) {		if ((dev = cd->cd_dev[ix]) == NODEV)			break;		ci = &cs->sc_cinfo[ix];		ci->ci_dev = dev;		bsw = &bdevsw[major(dev)];		/*		 * Open the partition		 */		if (bsw->d_open &&		    (error = (*bsw->d_open)(dev, 0, S_IFBLK, p))) {			printf("cd%d: component %s open failed, error = %d\n",			       cd->cd_unit, cddevtostr(dev), error);			return(0);		}		/*		 * Calculate size (truncated to interleave boundary		 * if necessary.		 */		if (bsw->d_psize) {			size = (size_t) (*bsw->d_psize)(dev);			if ((int)size < 0)				size = 0;		} else			size = 0;		if (cs->sc_ileave > 1)			size -= size % cs->sc_ileave;		if (size == 0) {			printf("cd%d: not configured (component %s missing)\n",			       cd->cd_unit, cddevtostr(dev));			return(0);		}#ifdef COMPAT_NOLABEL		/*		 * XXX if this is a 'c' partition then we need to mark the		 * label area writeable since there cannot be a label.		 */		if ((minor(dev) & 7) == 2 && bsw->d_open) {			int i, flag;			for (i = 0; i < nchrdev; i++)				if (cdevsw[i].d_open == bsw->d_open)					break;			if (i != nchrdev && cdevsw[i].d_ioctl) {				flag = 1;				(void)(*cdevsw[i].d_ioctl)(dev, DIOCWLABEL,					(caddr_t)&flag, FWRITE, p);			}		}#endif		if (minsize == 0 || size < minsize)			minsize = size;		ci->ci_size = size;		cs->sc_size += size;		cs->sc_ncdisks++;	}	/*	 * If uniform interleave is desired set all sizes to that of	 * the smallest component.	 */	if (cd->cd_flags & CDF_UNIFORM) {		for (ci = cs->sc_cinfo;		     ci < &cs->sc_cinfo[cs->sc_ncdisks]; ci++)			ci->ci_size = minsize;		cs->sc_size = cs->sc_ncdisks * minsize;	}	/*	 * Construct the interleave table	 */	if (!cdinterleave(cs))		return(0);	if (cd->cd_dk >= 0)		dk_wpms[cd->cd_dk] = 32 * (60 * DEV_BSIZE / 2);	/* XXX */	printf("cd%d: %d components ", cd->cd_unit, cs->sc_ncdisks);	for (ix = 0; ix < cs->sc_ncdisks; ix++)		printf("%c%s%c",		       ix == 0 ? '(' : ' ',		       cddevtostr(cs->sc_cinfo[ix].ci_dev),		       ix == cs->sc_ncdisks - 1 ? ')' : ',');	printf(", %d blocks ", cs->sc_size);	if (cs->sc_ileave)		printf("interleaved at %d blocks\n", cs->sc_ileave);	else		printf("concatenated\n");	cs->sc_flags = CDF_ALIVE | CDF_INITED;	return(1);}/* * XXX not really cd specific. * Could be called something like bdevtostr in machine/conf.c. */char *cddevtostr(dev)	dev_t dev;{	static char dbuf[5];	switch (major(dev)) {#ifdef hp300	case 2:		dbuf[0] = 'r'; dbuf[1] = 'd';		break;	case 4:		dbuf[0] = 's'; dbuf[1] = 'd';		break;	case 5:		dbuf[0] = 'c'; dbuf[1] = 'd';		break;	case 6:		dbuf[0] = 'v'; dbuf[1] = 'n';		break;#endif	default:		dbuf[0] = dbuf[1] = '?';		break;	}	dbuf[2] = (minor(dev) >> 3) + '0';	dbuf[3] = (minor(dev) & 7) + 'a';	dbuf[4] = '\0';	return (dbuf);}cdinterleave(cs)	register struct cd_softc *cs;{	register struct cdcinfo *ci, *smallci;	register struct cdiinfo *ii;	register daddr_t bn, lbn;	register int ix;	u_long size;#ifdef DEBUG	if (cddebug & CDB_INIT)		printf("cdinterleave(%x): ileave %d\n", cs, cs->sc_ileave);#endif	/*	 * Allocate an interleave table.	 * Chances are this is too big, but we don't care.	 */	size = (cs->sc_ncdisks + 1) * sizeof(struct cdiinfo);	cs->sc_itable = (struct cdiinfo *)malloc(size, M_DEVBUF, M_WAITOK);	bzero((caddr_t)cs->sc_itable, size);	/*	 * Trivial case: no interleave (actually interleave of disk size).	 * Each table entry represent a single component in its entirety.	 */	if (cs->sc_ileave == 0) {		bn = 0;		ii = cs->sc_itable;		for (ix = 0; ix < cs->sc_ncdisks; ix++) {			ii->ii_ndisk = 1;			ii->ii_startblk = bn;			ii->ii_startoff = 0;			ii->ii_index[0] = ix;			bn += cs->sc_cinfo[ix].ci_size;			ii++;		}		ii->ii_ndisk = 0;#ifdef DEBUG		if (cddebug & CDB_INIT)			printiinfo(cs->sc_itable);#endif		return(1);	}	/*	 * The following isn't fast or pretty; it doesn't have to be.	 */	size = 0;	bn = lbn = 0;	for (ii = cs->sc_itable; ; ii++) {		/*		 * Locate the smallest of the remaining components		 */		smallci = NULL;		for (ci = cs->sc_cinfo;		     ci < &cs->sc_cinfo[cs->sc_ncdisks]; ci++)			if (ci->ci_size > size &&			    (smallci == NULL ||			     ci->ci_size < smallci->ci_size))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -