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

📄 idc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic char *sccsid = "@(#)idc.c	4.1	ULTRIX	7/2/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1984, 1986 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any	other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived	from  software	received  from	the	* *   University    of	California,   Berkeley,   and	from   Bell	* *   Laboratories.  Use, duplication, or disclosure is	subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or	reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* * idc.c    6.1     07/29/83 * * Modification history * * IDC/RL02/R80 disk driver * * 26-July-89 - Alan Frechette *	Conditionalize out the dump code. * * 22-Feb-84 - tresvik * *	Derived from 4.2BSD labeled: idc.c	 6.1	 83/07/29. *	Changed printf to mprintf for hard and soft error reporting. * * 29-Oct-84 - reilly * *	Added code for the disk partitioning scheme. -001 * *  2-Nov-84 - tresvik * *	Changed std address from 0174400 to 0175606, where it really is. *	This will prevent machine checks on 780's with RL11 controllers *	on the bus. * * 30-Nov-84 - reilly * *	Fixed up an error message. -001 * * 24-Sep-85 - reilly * *	Added new ioctl request that will return the default partition *	table. * * 18-Mar-86 - jaw * *	br/cvec changed to NOT use registers. * *  9-Apr-86 - prs * *	Added partial dump code support, and removed common dump code. * * 16-Apr-86 - ricky palmer * *	Added new DEVIOCGET ioctl request code along with *	soft and hard error counters. V2.0 * * 22-May-86 - Paul Shaughnessy * *	Added saving of the u_area to the partial dump code. * * 13-Jun-86 - jaw * *	Fix to uba reset and drivers. * * 11-Jul-86 - ricky palmer * *	Added adpt and nexus fields to DEVIOCGET code. * * 26-Aug-86 - rsp (Ricky Palmer) * *	Cleaned up devioctl code to (1) zero out devget structure *	upon entry and (2) use strlen instead of fixed storage *	for bcopy's. * * 25-Sep-86 - pmk * *	Added code to detect OPI errors and drive not ready, because *	of lost interrupt hangs. * * 16-Oct-86 - pmk * *	Added code to detect drive not ready in the open routine to set *	drive sc_flags to offline for devioctl. */#include "rb.h"#if NIDC > 0 || defined(BINARY)#ifdef IDCDEBUGint	idcdebug = 0;#define printd if(idcdebug)printfint	idctrb[1000];int	*trp = idctrb;#define trace(a,b) {*trp++ = *(int*)a; *trp++ = (int)b; if(trp>&idctrb[998])trp=idctrb;}#endif IDCDEBUG#include "../h/dump.h"#include "../data/idc_data.c"#define dar_dar 	dar_l		/* the whole disk address */#define dar_cyl 	dar_w[1]	/* cylinder address */#define dar_trk 	dar_b[1]	/* track */#define dar_sect	dar_b[0]	/* sector */#define sc_dar		sc_un.dar_dar#define sc_cyl		sc_un.dar_cyl#define sc_trk		sc_un.dar_trk#define sc_sect 	sc_un.dar_sectint	idcprobe(), idcslave(), idcattach(), idcdgo(), idcintr();u_short idcstd[] = { 0175606 };struct	uba_driver idcdriver = { idcprobe, idcslave, idcattach, idcdgo, idcstd, "rb", idcdinfo, "idc", idcminfo, 0 };struct	idcst {	short	nbps;	short	nsect;	short	ntrak;	short	nspc;	short	ncyl;	struct	size *sizes;} idcst[] = {	256, NRB02SECT, NRB02TRK, NRB02SECT*NRB02TRK, NRB02CYL, rb02_sizes,	512, NRB80SECT, NRB80TRK, NRB80SECT*NRB80TRK, NRB80CYL, rb80_sizes,};#define b_cylin b_resid#ifdef INTRLVEdaddr_t dkblock();#endif INTRLVEint	idcwstart, idcwticks, idcwatch();/*ARGSUSED*/idcprobe(reg)	caddr_t reg;{	register struct idcdevice *idcaddr;	idcaddr = (struct idcdevice *)((caddr_t)uba_hd[0].uh_uba + 0x200);	idcaddr->idccsr = IDC_ATTN|IDC_IE;	while ((idcaddr->idccsr & IDC_CRDY) == 0)		;		/* needs to timeout usin todr */				/* also should do a badaddr because */				/* we aren't using reg Why aren't we?*/	idcaddr->idccsr = IDC_ATTN|IDC_CRDY;	return (sizeof (struct idcdevice));}/*ARGSUSED*/idcslave(ui, reg)	struct uba_device *ui;	caddr_t reg;{	register struct idcdevice *idcaddr;	register struct idc_softc *sc = &idc_softc;	idcaddr = (struct idcdevice *)((caddr_t)uba_hd[0].uh_uba + 0x200);	ui->ui_type = 0;	/* set drive to be offline until the first access occurs */	sc->sc_offline[ui->ui_unit] = 1;	/* clear any attention bit */	idcaddr->idccsr = IDC_CRDY|(1<<(ui->ui_slave+16));	(void) idcwait(idcaddr, 0);	/* setup for and get status of drive to see if it is there. */	/* this also resets the drive */	idcaddr->idcmpr = IDCGS_GETSTAT;	idcaddr->idccsr = IDC_GETSTAT|(ui->ui_slave<<8);	(void) idcwait(idcaddr, 0);	/*	 * OPI means the drive really isn't there	 */	if (idcaddr->idccsr & IDC_OPI)		return(0);	/*	 * Read header to synchronize microcode.	 * This is accomplished by issuing a READ HEADER command to	 * the selected unit followed by two reads of the MPR register.	 */	idcaddr->idccsr = (ui->ui_slave<<8)|IDC_RHDR;	(void) idcwait(idcaddr, 0);	if (idcaddr->idcmpr == idcaddr->idcmpr); /* reads the MPR twice */	if (idcaddr->idccsr&IDC_R80)		ui->ui_type = 1;	return (1);}idcattach(ui)	register struct uba_device *ui;{	register struct idc_softc *sc = &idc_softc;	/*	 * Fix all addresses to correspond	 * to the "real" IDC address.	 */	ui->ui_mi->um_addr = ui->ui_addr = (caddr_t)uba_hd[0].uh_uba + 0x200;	ui->ui_physaddr = (caddr_t)uba_hd[0].uh_physuba + 0x200;	if (idcwstart == 0) {		timeout(idcwatch, (caddr_t)0, hz);		idcwstart++;	}	if (ui->ui_dk >= 0) {		if (ui->ui_type) {			dk_mspw[ui->ui_dk] = 1.0 / (60 * NRB80SECT * 256);			bcopy(DEV_R80,sc->sc_device[ui->ui_unit],			      strlen(DEV_R80));		} else {			dk_mspw[ui->ui_dk] = 1.0 / (60 * NRB02SECT * 128);			bcopy(DEV_RL02,sc->sc_device[ui->ui_unit],			      strlen(DEV_RL02));		}		sc->sc_softcnt[ui->ui_unit] = 0;		sc->sc_hardcnt[ui->ui_unit] = 0;	}	idccyl[ui->ui_unit].dar_dar = -1;	ui->ui_flags = 0;}idcopen(dev, flag)	register dev_t dev;	int flag;{	register int unit = minor(dev) >> 3;	register struct uba_device *ui;	register struct idc_softc *sc;	register struct idcdevice *idcaddr;	int savstat, savcsr;	if (unit >= nNRB || (ui = idcdinfo[unit]) == 0 ||	    ui->ui_alive == 0) {		return (ENXIO);	}	idcaddr = (struct idcdevice *)ui->ui_addr;	sc = &idc_softc;	sc->sc_flags[unit] = 0;	sc->sc_category_flags[unit] = 0;	idcaddr->idcmpr = IDCGS_GETSTAT;	idcaddr->idccsr = IDC_GETSTAT|(ui->ui_slave<<8);	(void) idcwait(idcaddr, 0);	savstat = idcaddr->idcmpr;	savcsr = idcaddr->idccsr;	if (savstat & IDCDS_WL) {		sc->sc_flags[unit] |= DEV_WRTLCK;	}	if (!(savcsr & IDC_DRDY)) {		sc->sc_flags[unit] |= DEV_OFFLINE;	}	if (savcsr & IDC_ERR) {		mprintf("%s: unit# %d: drive error: csr=%b ds=%b\n",		    sc->sc_device[unit], unit, savcsr, IDCCSR_BITS, savstat,		    ui->ui_type?IDCRB80DS_BITS:IDCRB02DS_BITS);	}	idcaddr->idccsr = IDC_IE|IDC_CRDY|(1<<(ui->ui_slave+16));	/*	 *	We only need to read the partition table if the volume is	 *	not valid or the partition table is invalid.	 */	if ((sc->sc_flags[unit] & DEV_OFFLINE) ||	    (idc_part[unit].pt_valid != PT_VALID)){		int nspc = idcst[ui->ui_type].nspc;		int i, idcstrategy();		       /* 001 */		for( i = 0; i <= 7; i++ ) {			idc_part[unit].pt_part[i].pi_nblocks =				idcst[ui->ui_type].sizes[i].nblocks;			idc_part[unit].pt_part[i].pi_blkoff =				idcst[ui->ui_type].sizes[i].cyloff * nspc;		}		idc_part[unit].pt_valid = PT_VALID;	/*001 Validate the pt*/		/*		 *	Default partition are now set. Call rsblk to set		 *	the driver's partition tables, if any exists, from		 *	the "a" partition superblock		 */		rsblk( idcstrategy, dev, &idc_part[unit] );	}	return (0);}idcstrategy(bp)	register struct buf *bp;{	register struct uba_device *ui;	register struct idcst *st;	register int unit = dkunit(bp);	register struct pt *pt; 			/* 001 */	register struct idc_softc *sc = &idc_softc;	struct buf *dp;	int xunit = minor(bp->b_dev) & 07;	long bn, sz;	sz = (bp->b_bcount+511) >> 9;	if (unit >= nNRB)		goto bad;	ui = idcdinfo[unit];	if (ui == 0 || ui->ui_alive == 0)		goto bad;	st = &idcst[ui->ui_type];	pt = &idc_part[unit];	if ( pt->pt_valid != PT_VALID ) 			/* 001 */		panic("idcstrategy: invalid partition table");	/* 001 */	if (bp->b_blkno < 0 ||	    (bn = dkblock(bp))+sz > pt->pt_part[xunit].pi_nblocks) {		sc->sc_flags[unit] |= DEV_EOM;		goto bad;	}	if (ui->ui_type == 0)		bn *= 2;	bp->b_cylin = bn/st->nspc + pt->pt_part[xunit].pi_blkoff / st->nspc; /*001 */	(void) spl5();#ifdef IDCDEBUG	trace("strt",bp);#endif IDCDEBUG	dp = &idcutab[ui->ui_unit];	disksort(dp, bp);	if (dp->b_active == 0) {#ifdef IDCDEBUG		trace("!act",dp);#endif IDCDEBUG		(void) idcustart(ui);		bp = &ui->ui_mi->um_tab;		if (bp->b_actf && bp->b_active == 0)			(void) idcstart(ui->ui_mi);	}	(void) spl0();	return;bad:	bp->b_flags |= B_ERROR;	if (sc->sc_flags[unit] & DEV_EOM) {		bp->b_error = ENOSPC;	}	iodone(bp);	return;}idcustart(ui)	register struct uba_device *ui;{	register struct idcdevice *idcaddr;	register struct buf *bp;	register struct uba_ctlr *um;	register struct idcst *st;	register struct idc_softc *sc;	struct buf *dp;	union idc_dar cyltrk;	daddr_t bn;	int unit;	if (ui == 0)		return (0);	dk_busy &= ~(1<<ui->ui_dk);	dp = &idcutab[ui->ui_unit];	um = ui->ui_mi;	unit = ui->ui_slave;	sc = &idc_softc;#ifdef IDCDEBUG	trace("ust", dp);#endif IDCDEBUG	idcaddr = (struct idcdevice *)um->um_addr;	if (um->um_tab.b_active) {		sc->sc_softas |= 1<<unit;#ifdef IDCDEBUG		trace("umac",sc->sc_softas);#endif IDCDEBUG		return (0);	}	if ((bp = dp->b_actf) == NULL) {#ifdef IDCDEBUG		trace("!bp",0);#endif IDCDEBUG		return (0);	}	if (dp->b_active) {#ifdef IDCDEBUG		trace("dpac",dp->b_active);#endif IDCDEBUG		goto done;	}	dp->b_active = 1;	/* CHECK DRIVE READY? */	bn = dkblock(bp);#ifdef IDCDEBUG	trace("seek", bn);#endif IDCDEBUG	if (ui->ui_type == 0)		bn *= 2;	st = &idcst[ui->ui_type];	cyltrk.dar_cyl = bp->b_cylin;	cyltrk.dar_trk = (bn / st->nsect) % st->ntrak;	cyltrk.dar_sect = 0;#ifdef IDCDEBUG	printd("idcustart, unit %d, cyltrk 0x%x\n", unit, cyltrk.dar_dar);#endif IDCDEBUG	/*

⌨️ 快捷键说明

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