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

📄 hp.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
	case 2:		if (mi->mi_tab.b_errcnt < 16 ||		    (bp->b_flags & B_READ) == 0)			goto donerecal;		hpaddr->hpof = hp_offset[mi->mi_tab.b_errcnt & 017]|HPOF_FMT22;		hpaddr->hpcs1 = HP_OFFSET|HP_GO;		sc->sc_recal++;		return (MBD_RESTARTED);	donerecal:	case 3:		sc->sc_recal = 0;		sc->sc_flags |= DEV_RETRY;		return (MBD_RETRY);	}	sc->sc_hdr = 0;	bp->b_resid = MASKREG(-mi->mi_mba->mba_bcr);	if (mi->mi_tab.b_errcnt >= 16) {		/*		 * This is fast and occurs rarely; we don't		 * bother with interrupts.		 */		hpaddr->hpcs1 = HP_RTC|HP_GO;		while (hpaddr->hpds & HPDS_PIP)			;		mbclrattn(mi);	}	if (!ML11) {		hpaddr->hpof = HPOF_FMT22;		hpaddr->hpcs1 = HP_RELEASE|HP_GO;	}	sc->sc_flags |= DEV_DONE;	return (MBD_DONE);}hpread(dev, uio)	register dev_t dev;	register struct uio *uio;{	register int unit = minor(dev) >> 3;	return (physio(hpstrategy, &rhpbuf[unit], dev, B_READ, minphys, uio));}hpwrite(dev, uio)	register dev_t dev;	register struct uio *uio;{	register int unit = minor(dev) >> 3;	return (physio(hpstrategy, &rhpbuf[unit], dev, B_WRITE, minphys, uio));}/*ARGSUSED*/hpioctl(dev, cmd, data, flag)	dev_t dev;	register int cmd;	caddr_t data;	int flag;{	register int unit = minor(dev) >> 3;	register struct mba_device *mi = hpinfo[unit];	register struct pt *pt = (struct pt *)data;	register struct hp_softc *sc = &hp_softc[unit];	struct dkop *dkop;	struct dkget *dkget;	struct devget *devget;	register int i;	int nspc;	int error;	switch (cmd) {	case DKIOCHDR:	/* do header read/write */		sc->sc_hdr = 1;		break;	case DIOCGETPT: /* 001 get partition table info */		/*		 *	Do a structure copy into the user's data area		 */		*pt = hp_part[unit];		break;	case DIOCDGTPT: /* Get default partition table */		/*		 *	Get number of sectors per cylinder		 */		nspc = hpst[mi->mi_type].nspc;		/*		 *	Get the partition size and offset		 */		for ( i = 0; i <= 7; i++) {			pt->pt_part[i].pi_nblocks =			hpst[mi->mi_type].sizes[i].nblocks;			pt->pt_part[i].pi_blkoff =			hpst[mi->mi_type].sizes[i].cyloff * nspc;		}		break;	case DIOCSETPT: /* 001 set the driver partition tables */		/*		 *	Only super users can set the pack's partition		 *	table		 */		if ( !suser() )			return(EACCES);		/*		 *	Before we set the new partition tables make sure		 *	that it will no corrupt any of the kernel data		 *	structures		 */		if ( ( error = ptcmp( dev, &hp_part[unit], pt ) ) != 0 )			return(error);		/*		 *	Using the user's data to set the partition table		 *	for the pack		 */		hp_part[unit] = *pt;		/*		 *	See if we need to update the superblock of the		 *	"a" partition of this disk		 */		ssblk(dev,pt);		/*		 *	Just make sure that we set the valid bit		 */		hp_part[unit].pt_valid = PT_VALID;		break;	case DKIOCDOP:				/* Disk operation */		if ( !suser() )			return(EACCES);		break;	case DKIOCGET:				/* Get disk status */		break;	case DEVIOCGET: 			/* Device status */		devget = (struct devget *)data;		bzero(devget,sizeof(struct devget));		devget->category = DEV_DISK;		/* Disk 	*/		devget->bus = DEV_MB;			/* Massbus	*/		bcopy(DEV_RH,devget->interface,		      strlen(DEV_RH));			/* RH???	*/		bcopy(sc->sc_device,devget->device,		      strlen(sc->sc_device));		/* R[MP]??	*/		devget->adpt_num = mi->mi_adpt; 	/* which adapter*/		devget->nexus_num = mi->mi_nexus;	/* which nexus	*/		devget->bus_num = mi->mi_mbanum;	/* which MBA	*/		devget->ctlr_num = mi->mi_mbanum;	/* which RH	*/		devget->slave_num = mi->mi_drive;	/* which plug	*/		bcopy(mi->mi_driver->md_dname,		      devget->dev_name,		      strlen(mi->mi_driver->md_dname)); /* Ultrix "hp"	*/		devget->unit_num = unit;		/* which hp??	*/		devget->soft_count = sc->sc_softcnt;	/* soft er. cnt.*/		devget->hard_count = sc->sc_hardcnt;	/* hard er. cnt.*/		devget->stat = sc->sc_flags;		/* status	*/		devget->category_stat = DEV_DISKPART;	/* which prtn.	*/		break;	default:		return (ENXIO);	}	return(0);}hpecc(mi, flag)	register struct mba_device *mi;	int flag;{	register struct mba_regs *mbp = mi->mi_mba;	register struct hpdevice *rp = (struct hpdevice *)mi->mi_drv;	register struct buf *bp = mi->mi_tab.b_actf;	register struct hpst *st = &hpst[mi->mi_type];	int npf, o;	int bn, cn, tn, sn;	int bcr;#ifdef HPDEBUG	if(hpdebug) {		printf("b_flags = 0x%x  ", bp->b_flags);		printf("mba_bcr = 0x%x  ", mbp->mba_bcr);	}#endif HPDEBUG	bcr = (mbp->mba_bcr);	/*	 * On a read, the most conservative half of the byte count	 * register is the SBI transfer half (lower 16 bits).	 * On a write, the most conservative half of the byte count	 * register is the Massbus half (upper 16 bits).	 *	 * If the transfer is not a read, it is most likely	 * a write.	 */	if ((bp->b_flags & B_READ) != B_READ)		bcr = (bcr >> 16);	bcr = MASKREG(bcr);	if (bcr)		bcr |= 0xffff0000;		/* sxt */	if (flag == CONT)		npf = bp->b_error;	else		npf = btop(bcr + bp->b_bcount);#ifdef HPDEBUG	if(hpdebug)		printf("npf = %d\n", npf);#endif HPDEBUG	o = (int)bp->b_un.b_addr & PGOFSET;	bn = dkblock(bp);	cn = bp->b_cylin;	sn = bn%(st->nspc) + npf;	tn = sn/st->nsect;	sn %= st->nsect;	cn += tn/st->ntrak;	tn %= st->ntrak;	switch (flag) {	case ECC: {		register int i;		caddr_t addr;		struct pte mpte;		int bit, byte, mask;		npf--;			/* error was in the previous block*/		mprintf("hp%d%c: soft ecc sn:%d cyl:%d trk:%d sect:%d\n",		    dkunit(bp), 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf,		    MASKREG(rp->hpdc), ((MASKREG(rp->hpda) >> 8) & 0xff),		    (MASKREG(rp->hpda) & 0xff));		mask = MASKREG(rp->hpec2);		i = MASKREG(rp->hpec1) - 1;		/* -1 makes 0 origin */		bit = i&07;		i = (i&~07)>>3;		byte = i + o;		while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {			mpte = mbp->mba_map[npf+btop(byte)];			addr = ptob(mpte.pg_pfnum) + (byte & PGOFSET);			putmemc(addr, getmemc(addr)^(mask<<bit));			byte++;			i++;			bit -= 8;		}		if (bcr == 0)			return (0);		npf++;		break;		}	case SSE:		rp->hpof |= HPOF_SSEI;		mbp->mba_bcr = -(bp->b_bcount - (int)ptob(npf));		break;	case BSE:#ifdef HPBDEBUG		if (hpbdebug)		printf("hpecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn);#endif		if (rp->hpof&HPOF_SSEI)			sn++;		if ((bn = isbad(&hpbad[mi->mi_unit], cn, tn, sn)) < 0)			return (0);		bp->b_flags |= B_BAD;		bp->b_error = npf + 1;		bn = st->ncyl*st->nspc - st->nsect - 1 - bn;		cn = bn/st->nspc;		sn = bn%st->nspc;		tn = sn/st->nsect;		sn %= st->nsect;		mbp->mba_bcr = -MIN(512, bp->b_bcount - (int)ptob(npf));		rp->hpof &= ~HPOF_SSEI;#ifdef HPBDEBUG		if (hpbdebug)		printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);#endif		break;	case CONT:#ifdef HPBDEBUG		if (hpbdebug)		printf("hpecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn);#endif		npf = bp->b_error;		bp->b_flags &= ~B_BAD;		mbp->mba_bcr = -(bp->b_bcount - (int)ptob(npf));		if (MASKREG(mbp->mba_bcr) == 0)			return (0);		break;	}	rp->hpcs1 = HP_DCLR|HP_GO;	if (rp->hpof&HPOF_SSEI)		sn++;	rp->hpdc = cn;	rp->hpda = (tn<<8) + sn;	mbp->mba_sr = -1;	mbp->mba_var = (int)ptob(npf) + o;	rp->hpcs1 = bp->b_flags&B_READ ? HP_RCOM|HP_GO : HP_WCOM|HP_GO;	mi->mi_tab.b_errcnt = 0;	/* error has been corrected */	return (1);}#define DBSIZE	20hpdump(dev, dumpinfo)	dev_t dev;			/* dump device */	struct dumpinfo dumpinfo;	/* dump info */{#ifdef notdef	register struct mba_device *mi;	register struct mba_regs *mba;	struct hpdevice *hpaddr;	char *start;	char *start_tmp;	int unit;	register struct hpst *st;	start = start_tmp = 0;	unit = minor(dev) >> 3;	if (unit >= nNHP)		return (ENXIO);#define phys(a,b)	((b)((int)(a)&0x7fffffff))	mi = phys(hpinfo[unit],struct mba_device *);	if (mi == 0 || mi->mi_alive == 0)		return (ENXIO);	mba = phys(mi->mi_hd, struct mba_hd *)->mh_physmba;	mba->mba_cr = MBCR_INIT;	hpaddr = (struct hpdevice *)&mba->mba_drv[mi->mi_drive];	if ((hpaddr->hpds & HPDS_VV) == 0) {		hpaddr->hpcs1 = HP_DCLR|HP_GO;		hpaddr->hpcs1 = HP_PRESET|HP_GO;		hpaddr->hpof = HPOF_FMT22;	}	st = &hpst[mi->mi_type];	/*	 * If a full dump is being performed, then this loop	 * will dump all of core. If a partial dump is being	 * performed, then as much of core as possible will be	 * dumped, leaving room for the u_area and error logger	 * buffer. Please note that dumpsys predetermined what	 * type of dump will be performed.	 */	while ((dumpinfo.size_to_dump > 0) || (dumpinfo.partial_dump)) {		register struct pte *hpte = mba->mba_map;		register int i;		int blk, cn, sn, tn;		daddr_t bn;		blk = dumpinfo.size_to_dump > DBSIZE ? DBSIZE : dumpinfo.size_to_dump;		bn = dumplo + btop(start_tmp);		cn = bn/st->nspc + dumpinfo.blkoffs / st->nspc;		sn = bn%st->nspc;		tn = sn/st->nsect;		sn = sn%st->nsect;		hpaddr->hpdc = cn;		hpaddr->hpda = (tn << 8) + sn;		for (i = 0; i < blk; i++)			*(int *)hpte++ = (btop(start)+i) | PG_V;		mba->mba_sr = -1;		mba->mba_bcr = -(blk*NBPG);		mba->mba_var = 0;		hpaddr->hpcs1 = HP_WCOM | HP_GO;		while ((hpaddr->hpds & HPDS_DRY) == 0)			;		if (hpaddr->hpds&HPDS_ERR)			return (EIO);		start += blk*NBPG;		start_tmp += blk*NBPG;		dumpinfo.size_to_dump -= blk;		if ((dumpinfo.size_to_dump <= 0) && (dumpinfo.partial_dump)) {			/*			 * If a partial dump is being performed....			 */			/* Set size_to_dump to the number of pages to dump */			dumpinfo.size_to_dump =			  dumpinfo.pdump[NUM_TO_DUMP-dumpinfo.partial_dump].num_blks;			/* Set start to starting address */			start = 0;			start +=			  dumpinfo.pdump[NUM_TO_DUMP-dumpinfo.partial_dump].start_addr;			dumpinfo.partial_dump--;		}	}	return (0);#endif notdef}hpsize(dev)	register dev_t dev;{	register int unit = minor(dev) >> 3;	register struct mba_device *mi;	if (unit >= nNHP || (mi = hpinfo[unit]) == 0 || mi->mi_alive == 0)		return (-1);	/*	 *	Sanity check		001	 */	if ( hp_part[unit].pt_valid != PT_VALID )		panic("hpsize: invalid partition table ");	return ((int)hp_part[unit].pt_part[minor(dev) & 07].pi_nblocks);/*001*/}#endif

⌨️ 快捷键说明

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