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

📄 vd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		register struct format_op *fop;		struct uio auio;		struct iovec aiov;		if ((flag & FWRITE) == 0) {			error = EBADF;			break;		}		fop = (struct format_op *)data;		aiov.iov_base = fop->df_buf;		aiov.iov_len = fop->df_count;		auio.uio_iov = &aiov;		auio.uio_iovcnt = 1;		auio.uio_resid = fop->df_count;		auio.uio_segflg = UIO_USERSPACE;		auio.uio_offset = fop->df_startblk * lp->d_secsize;		/* This assumes one active format operation per disk... */		dk->dk_op = fop->dk_op;		dk->dk_althdr = fop->dk_althdr;		dk->dk_fmtflags = fop->dk_fmtflags;		/*		 * Don't return errors, as the format op won't get copied		 * out if we return nonzero.  Callers must check the returned		 * registers and count.		 */		error = physio(vdformat, (struct buf *)NULL, dev,		     B_WRITE, minphys, &auio);		if (error == EIO)			error = 0;		fop->df_count -= auio.uio_resid;		/* This assumes one active format operation per disk... */		fop->dk_operrsta = dk->dk_operrsta;		fop->dk_ecodecnt = dk->dk_ecodecnt;		fop->dk_erraddr = dk->dk_erraddr;		break;	    }	default:		error = ENOTTY;		break;	}	return (error);}vdformat(bp)	struct buf *bp;{	bp->b_flags |= B_FORMAT;	vdstrategy(bp);}/* * Watch for lost interrupts. */vdwatch(){	register struct vdsoftc *vd;	register struct vba_ctlr *vm;	register int ctlr;	int s;	timeout(vdwatch, (caddr_t)0, hz);	for (ctlr = 0; ctlr < NVD; ctlr++) {		vm = vdminfo[ctlr];		if (vm == 0 || vm->um_alive == 0)			continue;		vd = &vdsoftc[ctlr];		s = spl7();		if (vm->um_tab.b_active && vd->vd_wticks++ >= VDMAXTIME) {			printf("vd%d: lost interrupt\n", ctlr);#ifdef maybe			VDABORT((struct vddevice *)vm->um_addr, vd->vd_type);#endif			vdintr(ctlr);		}		splx(s);	}}#define	DBSIZE	64	/* controller limit with 1K sectors *//* * Crash dump. */vddump(dev)	dev_t dev;{	register struct vba_device *vi;	register struct vba_ctlr *vm;	register struct disklabel *lp;	register struct vdsoftc *vd;	struct dksoftc *dk;	int part, unit, num;	u_long start;	start = 0;	unit = vdunit(dev);	if (unit > NDK || (vi = vddinfo[unit]) == 0 || vi->ui_alive == 0)		return (ENXIO);	dk = &dksoftc[unit];	if (dk->dk_state != OPEN && dk->dk_state != OPENRAW &&	    vdinit(vdminor(unit, 0), 0) != 0)		return (ENXIO);	lp = &dklabel[unit];	part = vdpart(dev);	if (part >= lp->d_npartitions)		return (ENXIO);	vm = vi->ui_mi;	vdreset_ctlr(vm);	if (dumplo < 0)		return (EINVAL);	/*	 * Maxfree is in pages, dumplo is in DEV_BSIZE units.	 */	num = maxfree * (NBPG / lp->d_secsize);	dumplo *= DEV_BSIZE / lp->d_secsize;	if (dumplo + num >= lp->d_partitions[vdpart(dev)].p_size)		num = lp->d_partitions[vdpart(dev)].p_size - dumplo;	vd = &vdsoftc[vm->um_ctlr];	vd->vd_dcb.intflg = DCBINT_NONE;	vd->vd_dcb.opcode = VDOP_WD;	vd->vd_dcb.devselect = dk->dk_dcb.devselect;	vd->vd_dcb.trailcnt = sizeof (struct trrw) / sizeof (long);	while (num > 0) {		int nsec, cn, sn, tn;		nsec = MIN(num, DBSIZE);		sn = dumplo + start / lp->d_secsize;		cn = (sn + lp->d_partitions[vdpart(dev)].p_offset) /		    lp->d_secpercyl;		sn %= lp->d_secpercyl;		tn = sn / lp->d_nsectors;		sn %= lp->d_nsectors;		vd->vd_mdcb.mdcb_head = (struct dcb *)vd->vd_dcbphys;		vd->vd_dcb.trail.rwtrail.memadr = start;		vd->vd_dcb.trail.rwtrail.wcount = (nsec * lp->d_secsize) >> 1;		vd->vd_dcb.trail.rwtrail.disk.cylinder = cn;		vd->vd_dcb.trail.rwtrail.disk.track = tn;		vd->vd_dcb.trail.rwtrail.disk.sector = sn;		vd->vd_dcb.operrsta = 0;		VDGO(vm->um_addr, vd->vd_mdcbphys, vd->vd_type);		if (!vdpoll(vm, 5)) {			printf(" during dump\n");			return (EIO);		}		if (vd->vd_dcb.operrsta & VDERR_HARD) {			printf("dk%d: hard error, status=%b\n", unit,			    vd->vd_dcb.operrsta, VDERRBITS);			return (EIO);		}		start += nsec * lp->d_secsize;		num -= nsec;	}	return (0);}vdsize(dev)	dev_t dev;{	register int unit = vdunit(dev);	register struct dksoftc *dk;	struct vba_device *vi;	struct disklabel *lp;	if (unit >= NDK || (vi = vddinfo[unit]) == 0 || vi->ui_alive == 0 ||	    (dk = &dksoftc[unit])->dk_state != OPEN)		return (-1);	lp = &dklabel[unit];#ifdef SECSIZE	return ((int)lp->d_partitions[vdpart(dev)].p_size);#else SECSIZE	return ((int)lp->d_partitions[vdpart(dev)].p_size >> dk->dk_bshift);#endif SECSIZE}/* * Initialize controller. */vdinit_ctlr(vm, vd)	struct vba_ctlr *vm;	struct vdsoftc *vd;{	register struct vddevice *vdaddr = (struct vddevice *)vm->um_addr;	if (vd->vd_type == VDTYPE_SMDE) {		vdaddr->vdcsr = 0;		vdaddr->vdtcf_mdcb = AM_ENPDA;		vdaddr->vdtcf_dcb = AM_ENPDA;		vdaddr->vdtcf_trail = AM_ENPDA;		vdaddr->vdtcf_data = AM_ENPDA;		vdaddr->vdccf = CCF_SEN | CCF_DIU | CCF_STS | CCF_RFE |		    XMD_32BIT | BSZ_16WRD |		    CCF_ENP | CCF_EPE | CCF_EDE | CCF_ECE | CCF_ERR;	}	if (!vdcmd(vm, VDOP_INIT, 10, 0) || !vdcmd(vm, VDOP_DIAG, 10, 0)) {		printf("vd%d: %s cmd failed\n", vm->um_ctlr,		    vd->vd_dcb.opcode == VDOP_INIT ? "init" : "diag");		return (0);	}	vd->vd_secsize = vdaddr->vdsecsize << 1;	return (1);}/* * Perform a controller reset. */vdreset_ctlr(vm)	register struct vba_ctlr *vm;{	register struct vddevice *vdaddr = (struct vddevice *)vm->um_addr;	register struct vdsoftc *vd = &vdsoftc[vm->um_ctlr];	register int unit;	struct vba_device *vi;		VDRESET(vdaddr, vd->vd_type);	if (vdinit_ctlr(vm, vd) == 0)		return;	for (unit = 0; unit < NDK; unit++)		if ((vi = vddinfo[unit]) && vi->ui_mi == vm && vi->ui_alive)			(void) vdreset_drive(vi);}vdreset_drive(vi)	register struct vba_device *vi;{	register struct disklabel *lp = &dklabel[vi->ui_unit];	struct vba_ctlr *vm = vdminfo[vi->ui_ctlr];	struct vddevice *vdaddr = (struct vddevice *)vm->um_addr;	register struct vdsoftc *vd = &vdsoftc[vi->ui_ctlr];	register struct dksoftc *dk = &dksoftc[vi->ui_unit];	int config_status, config_ecode, saw_drive = 0;#ifdef notdef	/*	 * check for ESDI distribution panel already configured,	 * e.g. on boot drive, or if PROBE on controller actually	 * worked.  Status will be zero if drive hasn't	 * been probed yet.	 */#if STA_ESDI != 0	if ((vdaddr->vdstatus[vi->ui_slave] & STA_TYPE) == STA_ESDI)		lp->d_devflags |= VD_ESDI;#endif#endiftop:	vd->vd_dcb.opcode = VDOP_CONFIG;		/* command */	vd->vd_dcb.intflg = DCBINT_NONE;	vd->vd_dcb.nxtdcb = (struct dcb *)0;	/* end of chain */	vd->vd_dcb.operrsta = 0;	vd->vd_dcb.devselect = vi->ui_slave | lp->d_devflags;	vd->vd_dcb.trail.rstrail.ncyl = lp->d_ncylinders;	vd->vd_dcb.trail.rstrail.nsurfaces = lp->d_ntracks;	if (vd->vd_type == VDTYPE_SMDE) {		vd->vd_dcb.trailcnt = sizeof (struct treset) / sizeof (long);		vd->vd_dcb.trail.rstrail.nsectors = lp->d_nsectors;		vd->vd_dcb.trail.rstrail.slip_sec = lp->d_sparespertrack;		vd->vd_dcb.trail.rstrail.recovery =		    (lp->d_flags & D_REMOVABLE) ? VDRF_NORMAL :		    (VDRF_NORMAL &~ (VDRF_OSP|VDRF_OSM));	} else		vd->vd_dcb.trailcnt = 2;		/* XXX */	vd->vd_mdcb.mdcb_head = (struct dcb *)vd->vd_dcbphys;	vd->vd_mdcb.mdcb_status = 0;	VDGO(vdaddr, vd->vd_mdcbphys, vd->vd_type);	if (!vdpoll(vm, 5)) {		printf(" during config\n");		return (0);	}	config_status = vd->vd_dcb.operrsta;	config_ecode = (u_char)vd->vd_dcb.err_code;	if (config_status & VDERR_HARD) {		if (vd->vd_type == VDTYPE_SMDE) {			/*			 * If drive status was updated successfully,			 * STA_US (unit selected) should be set			 * if the drive is attached and powered up.			 * (But only if we've guessed right on SMD			 * vs. ESDI; if that flag is wrong, we won't			 * see the drive.)  If we don't see STA_US			 * with either SMD or ESDI set for the unit,			 * we assume that the drive doesn't exist,			 * and don't wait for it to spin up.			 */			(void) vdcmd(vm, VDOP_STATUS, 5, vi->ui_slave);			uncache(&vdaddr->vdstatus[vi->ui_slave]);			if (vdaddr->vdstatus[vi->ui_slave] & STA_US)				saw_drive = 1;			else if (lp->d_devflags == 0) {				lp->d_devflags = VD_ESDI;				goto top;			}		} else			saw_drive = 1;		if ((config_status & (DCBS_OCYL|DCBS_NRDY)) == 0)			printf("dk%d: config error %b ecode %x\n", vi->ui_unit,			   config_status, VDERRBITS, config_ecode);		else if ((vd->vd_flags & VD_STARTED) == 0 && saw_drive) {			int started;			printf(" starting drives, wait ... ");			vd->vd_flags |= VD_STARTED;			started = (vdcmd(vm, VDOP_START, 10) == 1);			DELAY(62000000);			printf("done\n");			lp->d_devflags = 0;			if (started)				goto top;		}		return (0);	}	dk->dk_dcb.devselect |= lp->d_devflags;	return (1);}/* * Perform a command w/o trailer. */vdcmd(vm, cmd, t, slave)	register struct vba_ctlr *vm;{	register struct vdsoftc *vd = &vdsoftc[vm->um_ctlr];	vd->vd_dcb.opcode = cmd;		/* command */	vd->vd_dcb.intflg = DCBINT_NONE;	vd->vd_dcb.nxtdcb = (struct dcb *)0;	/* end of chain */	vd->vd_dcb.operrsta = 0;	vd->vd_dcb.devselect = slave;	vd->vd_dcb.trailcnt = 0;	vd->vd_mdcb.mdcb_head = (struct dcb *)vd->vd_dcbphys;	vd->vd_mdcb.mdcb_status = 0;	VDGO(vm->um_addr, vd->vd_mdcbphys, vd->vd_type);	if (!vdpoll(vm, t)) {		printf(" during init\n");		return (0);	}	return ((vd->vd_dcb.operrsta&VDERR_HARD) == 0);}/* * Poll controller until operation * completes or timeout expires. */vdpoll(vm, t)	register struct vba_ctlr *vm;	register int t;{	register struct vdsoftc *vd = &vdsoftc[vm->um_ctlr];	register struct vddevice *vdaddr = (struct vddevice *)vm->um_addr;	t *= 1000;	for (;;) {		uncache(&vd->vd_dcb.operrsta);		if (vd->vd_dcb.operrsta & (DCBS_DONE|DCBS_ABORT))			break;		if (--t <= 0) {			printf("vd%d: controller timeout", vm->um_ctlr);			VDABORT(vdaddr, vd->vd_type);			return (0);		}		DELAY(1000);	}	if (vd->vd_type == VDTYPE_SMDE) {		do {			DELAY(50);			uncache(&vdaddr->vdcsr);		} while (vdaddr->vdcsr & CS_GO);	 	DELAY(300);		uncache(&vd->vd_dcb.err_code);	}	DELAY(200);	uncache(&vd->vd_dcb.operrsta);	return (1);}#ifdef COMPAT_42struct	vdst {	int	nsec;		/* sectors/track */	int	ntrack;		/* tracks/cylinder */	int	ncyl;		/* cylinders */	int	secsize;	/* sector size */	char	*name;		/* type name */	struct {		int	off;	/* partition offset in sectors */		int	size;	/* partition size in sectors */	} parts[8];} vdst[] = {	{ 66, 23, 850, 512, "NEC 800",		{0,	 1290300},	/* a cyl   0 - 849 */	},	{ 64, 20, 842, 512, "2361a",		{0,	 61440},	/* a cyl   0 - 47 */		{61440,	 67840},	/* b cyl  48 - 100 */		{129280, 942080}, 	/* c cyl 101 - 836 */		{0,      1071360}, 	/* d cyl   0 - 836 */		{449280, 311040},	/* e cyl 351 - 593 */		{760320, 311040}, 	/* f cyl 594 - 836 */		{449280, 622080},	/* g cyl 351 - 836 */		{129280, 320000}	/* h cyl 101 - 350 */	},	{ 48, 24, 711, 512, "xsd",		{0,	 61056},	/* a cyl   0 - 52 */		{61056,	 61056},	/* b cyl  53 - 105 */		{122112, 691200}, 	/* c cyl 106 - 705 */		{237312, 576000}, 	/* d cyl 206 - 705 */		{352512, 460800},	/* e cyl 306 - 705 */		{467712, 345600}, 	/* f cyl 406 - 705 */		{582912, 230400},	/* g cyl 506 - 705 */		{698112, 115200}	/* h cyl 606 - 705 */	},	{ 44, 20, 842, 512, "eagle",		{0,	 52800},	/* egl0a cyl   0 - 59 */		{52800,	 66000},	/* egl0b cyl  60 - 134 */		{118800, 617760}, 	/* egl0c cyl 135 - 836 */		{736560, 4400}, 	/* egl0d cyl 837 - 841 */		{0, 	 736560},	/* egl0e cyl   0 - 836 */		{0, 	 740960}, 	/* egl0f cyl   0 - 841 */		{118800, 310640},	/* egl0g cyl 135 - 487 */		{429440, 307120}	/* egl0h cyl 488 - 836 */	},	{ 64, 10, 823, 512, "fuj",		{0,	 38400},	/* fuj0a cyl   0 - 59 */		{38400,	 48000},	/* fuj0b cyl  60 - 134 */		{86400,	 437120}, 	/* fuj0c cyl 135 - 817 */		{159360, 364160}, 	/* fuj0d cyl 249 - 817 */		{232320, 291200},	/* fuj0e cyl 363 - 817 */		{305280, 218240}, 	/* fuj0f cyl 477 - 817 */		{378240, 145280},	/* fuj0g cyl 591 - 817 */		{451200, 72320}		/* fug0h cyl 705 - 817 */	},	{ 32, 24, 711, 512, "xfd",		{ 0,	 40704 },	/* a cyl   0 - 52 */		{ 40704, 40704 },	/* b cyl  53 - 105 */		{ 81408, 460800 },	/* c cyl 106 - 705 */		{ 0,	 81408 },	/* d cyl 709 - 710 (a & b) */		{ 0,	 542208 },	/* e cyl   0 - 705 */		{ 40704, 501504 },	/* f cyl  53 - 705 (b & c) */		{ 81408, 230400 },	/* g cyl 106 - 405 (1/2 of c) */		{ 311808,230400 }	/* h cyl 406 - 705 (1/2 of c) */	},	{ 32, 19, 823, 512, "smd",		{0,	 40128},	/* a cyl   0-65 */		{40128,  27360},	/* b cyl  66-110 */		{67488,  429856},	/* c cyl 111-817 */		{139232, 358112},	/* d cyl 229 - 817 */		{210976, 286368},	/* e cyl 347 - 817 */		{282720, 214624},	/* f cyl 465 - 817 */		{354464, 142880},	/* g cyl 583 - 817 */		{426208, 71136}		/* h cyl 701 - 817 */	},	{ 18, 15, 1224, 1024, "mxd",		{0,	 21600},	/* a cyl   0-79 */		{21600,  22410},	/* b cyl  80-162 */		{44010,  285120},	/* c cyl 163-1217 */#ifdef notyet		{x, 237600},	/* d cyl y - 1217 */		{x, 190080},	/* e cyl y - 1217 */		{x, 142560},	/* f cyl y - 1217 */		{x, 95040},	/* g cyl y - 1217 */		{x, 47520}		/* h cyl 701 - 817 */#endif	},	{ 32, 10, 823, 512, "fsd",		{0,	 19200},	/* a cyl   0 -  59 */		{19200,	 24000},	/* b cyl  60 - 134 */		{43200,	 218560},	/* c cyl 135 - 817 */	}};#define	NVDST	(sizeof (vdst) / sizeof (vdst[0]))/* * Construct a label for an unlabeled pack.  We * deduce the drive type by reading from the last * track on successively smaller drives until we * don't get an error. */vdmaptype(vi, lp)	register struct vba_device *vi;	register struct disklabel *lp;{	register struct vdsoftc *vd;	register struct vdst *p;	struct vba_ctlr *vm = vi->ui_mi;	int i;	vd = &vdsoftc[vi->ui_ctlr];	for (p = vdst; p < &vdst[NVDST]; p++) {		if (vd->vd_type == VDTYPE_VDDC && p->nsec != 32)			continue;		lp->d_nsectors = p->nsec;		lp->d_ntracks = p->ntrack;		lp->d_ncylinders = p->ncyl;		lp->d_secsize = p->secsize;		DELAY(100000);		if (!vdreset_drive(vi))			return (0);		DELAY(100000);		vd->vd_dcb.opcode = VDOP_RD;		vd->vd_dcb.intflg = DCBINT_NONE;		vd->vd_dcb.nxtdcb = (struct dcb *)0;	/* end of chain */		vd->vd_dcb.devselect = dksoftc[vi->ui_unit].dk_dcb.devselect;		vd->vd_dcb.trailcnt = sizeof (struct trrw) / sizeof (long);		vd->vd_dcb.trail.rwtrail.memadr =		    vtoph((struct proc *)0, (unsigned)vd->vd_rbuf.vb_rawbuf);		vd->vd_dcb.trail.rwtrail.wcount = lp->d_secsize / sizeof(short);		vd->vd_dcb.operrsta = 0;		vd->vd_dcb.trail.rwtrail.disk.cylinder = p->ncyl - 2;		vd->vd_dcb.trail.rwtrail.disk.track = p->ntrack - 1;		vd->vd_dcb.trail.rwtrail.disk.sector = p->nsec - 1;		vd->vd_mdcb.mdcb_head = (struct dcb *)vd->vd_dcbphys;		vd->vd_mdcb.mdcb_status = 0;		VDGO(vm->um_addr, vd->vd_mdcbphys, vd->vd_type);		if (!vdpoll(vm, 60))			printf(" during probe\n");		if ((vd->vd_dcb.operrsta & VDERR_HARD) == 0)			break;	}	if (p >= &vdst[NVDST])		return (0);	for (i = 0; i < 8; i++) {		lp->d_partitions[i].p_offset = p->parts[i].off;		lp->d_partitions[i].p_size = p->parts[i].size;	}	lp->d_npartitions = 8;	lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;	bcopy(p->name, lp->d_typename, 4);	return (1);}#endif COMPAT_42#endif

⌨️ 快捷键说明

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