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

📄 idc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
					}					if (idcustart(ui)) {						sc->sc_softas = as;						return;					}				} else {					/* drive spun down */#ifdef IDCDEBUG					printd(", drive not ready");#endif IDCDEBUG					sc->sc_flags[ui->ui_unit] |= DEV_OFFLINE;					sc->sc_offline[ui->ui_unit]++;				}			} else {#ifdef IDCDEBUG				printd(", unsol. intr. unit %d", unit);#endif IDCDEBUG			}		}#ifdef IDCDEBUG	printd("\n");#endif IDCDEBUG	if (um->um_tab.b_actf && um->um_tab.b_active == 0) {#ifdef IDCDEBUG		trace("stum",um->um_tab.b_actf);#endif IDCDEBUG		(void) idcstart(um);	}}idcwait(addr, n)	register struct idcdevice *addr;	register int n;{	register int i;	while (--n && (addr->idccsr & IDC_CRDY) == 0)		for (i = 10; i; i--)			;	return (n);}idcread(dev, uio)	register dev_t dev;	register struct uio *uio;{	register int unit = minor(dev) >> 3;	return (physio(idcstrategy, &ridcbuf[unit], dev, B_READ, minphys, uio));}idcwrite(dev, uio)	register dev_t dev;	register struct uio *uio;{	register int unit = minor(dev) >> 3;	return (physio(idcstrategy, &ridcbuf[unit], dev, B_WRITE, minphys, uio));}/*ARGSUSED*/idcioctl(dev, cmd, data, flag)	dev_t dev;	int cmd;	caddr_t data;	int flag;{	register int unit = minor(dev) >> 3;	register struct uba_device *ui = idcdinfo[unit];	register struct pt *pt = (struct pt *)data;	register struct idc_softc *sc = &idc_softc;	struct dkop *dkop;	struct dkget *dkget;	struct devget *devget;	register int i;	int error;	int nspc;	switch (cmd) {	case DKIOCHDR:	/* do header read/write */		break;	case DIOCGETPT: /* 001 get partition table info */		/*		 *	Do a structure copy into the user's data area		 */		*pt = idc_part[unit];		break;	case DIOCDGTPT: /* return default partition table */		/*		 * Get number of sectors per cylinder		 */		nspc = idcst[ui->ui_type].nspc;		/*		 * Get default block count and offset		 */		for( i = 0; i <= 7; i++ ) {			pt->pt_part[i].pi_nblocks =				idcst[ui->ui_type].sizes[i].nblocks;			pt->pt_part[i].pi_blkoff =				idcst[ui->ui_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, &idc_part[unit], pt ) ) != 0 )			return(error);		/*		 *	Using the user's data to set the partition table		 *	for the pack		 */		idc_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		 */		idc_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_UB;			/* Unibus	*/		bcopy(DEV_IDC,devget->interface,		      strlen(DEV_IDC)); 		/* IDC		*/		bcopy(sc->sc_device[unit],		      devget->device,		      strlen(sc->sc_device[unit]));	/* RB?? 	*/		devget->adpt_num = ui->ui_adpt; 	/* which adapter*/		devget->nexus_num = ui->ui_nexus;	/* which nexus	*/		devget->bus_num = ui->ui_ubanum;	/* which UBA	*/		devget->ctlr_num = ui->ui_ctlr; 	/* IDC 0 only	*/		devget->slave_num = ui->ui_slave;	/* which plug	*/		bcopy(ui->ui_driver->ud_dname,		      devget->dev_name,		      strlen(ui->ui_driver->ud_dname)); /* Ultrix "rb"	*/		devget->unit_num = unit;		/* which rb??	*/		devget->soft_count = sc->sc_softcnt[unit];    /* soft er. cnt.*/		devget->hard_count = sc->sc_hardcnt[unit];    /* hard er. cnt.*/		devget->stat = sc->sc_flags[unit];	      /* status       */		devget->category_stat = DEV_DISKPART;	/* which prtn.	*/		break;	default:		return (ENXIO);	}	return(0);}idcecc(ui)	register struct uba_device *ui;{	register struct idcdevice *idc = (struct idcdevice *)ui->ui_addr;	register struct buf *bp = idcutab[ui->ui_unit].b_actf;	register struct uba_ctlr *um = ui->ui_mi;	register struct idcst *st;	register int i;	struct idc_softc *sc = &idc_softc;	struct uba_regs *ubp = ui->ui_hd->uh_uba;	int bit, byte, mask;	caddr_t addr;	int reg, npf, o;	int cn, tn, sn;	npf = btop(idc->idcbcr + sc->sc_bcnt) - 1;;	reg = btop(sc->sc_ubaddr) + npf;	o = (int)bp->b_un.b_addr & PGOFSET;	st = &idcst[ui->ui_type];	cn = sc->sc_cyl;	tn = sc->sc_trk;	sn = sc->sc_sect;	um->um_tab.b_active = 1;	/* Either complete or continuing... */	mprintf("rb%d%c: soft ecc sn%d\n", dkunit(bp),	    'a'+(minor(bp->b_dev)&07),	    (cn*st->ntrak + tn) * st->nsect + sn + npf);	mask = idc->idceccpat;	i = idc->idceccpos - 1; 	/* -1 makes 0 origin */	bit = i&07;	i = (i&~07)>>3;	byte = i + o;	while (i < 512 && (int)ptob(npf)+i < sc->sc_bcnt && bit > -11) {		struct	pte	pte;		pte = ubp->uba_map[reg + btop(byte)];		addr = ptob(pte.pg_pfnum)+ (byte & PGOFSET);		putmemc(addr, getmemc(addr)^(mask<<bit));		byte++;		i++;		bit -= 8;	}	sc->sc_bcnt += idc->idcbcr;	um->um_tab.b_errcnt = 0;	/* error has been corrected */	return;}idcreset(uban)	int uban;{	register struct uba_ctlr *um;	register struct uba_device *ui;	register unit;	if ((um = idcminfo[0]) == 0 || um->um_ubanum != uban ||	    um->um_alive == 0)		return;	printf(" idc0");	um->um_tab.b_active = 0;	um->um_tab.b_actf = um->um_tab.b_actl = 0;	if (um->um_ubinfo) {		printf("<%d>", (um->um_ubinfo>>28)&0xf);		um->um_ubinfo = 0;	}	for (unit = 0; unit < nNRB; unit++) {		if ((ui = idcdinfo[unit]) == 0 || ui->ui_alive == 0)			continue;		idcutab[unit].b_active = 0;		(void) idcustart(ui);	}	(void) idcstart(um);}idcwatch(){	register struct uba_ctlr *um;	register unit;	timeout(idcwatch, (caddr_t)0, hz);	um = idcminfo[0];	if (um == 0 || um->um_alive == 0)		return;	if (um->um_tab.b_active == 0) {		for (unit = 0; unit < nNRB; unit++)			if (idcutab[unit].b_active)				goto active;		idcwticks = 0;		return;	}active:	idcwticks++;	if (idcwticks >= 20) {		idcwticks = 0;		printf("idc0: lost interrupt\n");		idcintr(0);	}}/*ARGSUSED*/idcdump(dev, dumpinfo)	dev_t dev;			/* dump device */	struct dumpinfo  dumpinfo;	/* dump info */{#ifdef notdef	struct idcdevice *idcaddr;	char *start;	char *start_tmp;	int blk, unit;	register struct uba_regs *uba;	register struct uba_device *ui;	struct idcst *st;	union idc_dar dar;	int nspg,ubatype;	unit = minor(dev) >> 3;	if (unit >= nNRB)		return (ENXIO);#define phys(cast, addr) ((cast)((int)addr & 0x7fffffff))	ui = phys(struct uba_device *, idcdinfo[unit]);	if (ui->ui_alive == 0)		return (ENXIO);	uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba;	ubatype = phys(struct uba_hd *, ui->ui_hd)->uba_type;	ubainit(uba,ubatype);	idcaddr = (struct idcdevice *)ui->ui_physaddr;	if (idcwait(idcaddr, 100) == 0)		return (EFAULT);	/*	 * Since we can only transfer one track at a time, and	 * the rl02 has 256 byte sectors, all the calculations	 * are done in terms of physical sectors (i.e. num and blk	 * are in sectors not NBPG blocks.	 */	st = phys(struct idcst *, &idcst[ui->ui_type]);	nspg = NBPG / st->nbps;	dumpinfo.size_to_dump *= nspg;	start = start_tmp = 0;	/*	 * 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 the 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 *io;		register int i;		daddr_t bn;		bn = (dumplo + btop(start_tmp)) * nspg;		dar.dar_cyl = bn / st->nspc + dumpinfo.blkoffs / st->nspc;		bn %= st->nspc;		dar.dar_trk = bn / st->nsect;		dar.dar_sect = bn % st->nsect;		blk = st->nsect - dar.dar_sect;		if (dumpinfo.size_to_dump < blk)			blk = dumpinfo.size_to_dump;		io = uba->uba_map;		for (i = 0; i < (blk + nspg - 1) / nspg; i++)			*(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV;		*(int *)io = 0;		idcaddr->idccsr = IDC_CRDY | IDC_SEEK | unit<<8;		if ((idcaddr->idccsr&IDC_DRDY) == 0)			return (EFAULT);		idcaddr->idcdar = dar.dar_dar;		idcaddr->idccsr = IDC_SEEK | unit << 8;		while ((idcaddr->idccsr & (IDC_CRDY|IDC_DRDY))			!= (IDC_CRDY|IDC_DRDY))			;		if (idcaddr->idccsr & IDC_ERR) {			printf("rb%d: seek, csr=%b\n",				unit, idcaddr->idccsr, IDCCSR_BITS);			return (EIO);		}		idcaddr->idccsr = IDC_CRDY | IDC_WRITE | unit<<8;		if ((idcaddr->idccsr&IDC_DRDY) == 0)			return (EFAULT);		idcaddr->idcbar = 0;			/* start addr 0 */		idcaddr->idcbcr = - (blk * st->nbps);		idcaddr->idcdar = dar.dar_dar;		idcaddr->idccsr = IDC_WRITE | unit << 8;		while ((idcaddr->idccsr & (IDC_CRDY|IDC_DRDY))			!= (IDC_CRDY|IDC_DRDY))			;		if (idcaddr->idccsr & IDC_ERR) {			printf("rb%d: write, csr=%b\n",				unit, idcaddr->idccsr, IDCCSR_BITS);			return (EIO);		}		start += blk * st->nbps;		start_tmp += blk * st->nbps;		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 * nspg;			/* 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}idcsize(dev)	dev_t dev;{	int unit = minor(dev) >> 3;	struct uba_device *ui;	struct idcst *st;	if (unit >= nNRB || (ui = idcdinfo[unit]) == 0 || ui->ui_alive == 0)		return (-1);	/*	 *	Sanity check		001	 */	if ( idc_part[unit].pt_valid != PT_VALID )		panic("idcsize: invalid partition table ");	return (idc_part[unit].pt_part[minor(dev) & 07].pi_nblocks);}#endif

⌨️ 快捷键说明

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