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

📄 hp.c

📁 UNIX v6源代码 这几乎是最经典的unix版本 unix操作系统设计和莱昂氏unix源代码分析都是用的该版
💻 C
字号:
#/* *//* * RP04 disk driver * * This driver has been tested on a working RP04 for a few hours. * It does not attempt ECC error correction and is probably * deficient in general in the case of errors and when packs * are dismounted. */#include "../param.h"#include "../buf.h"#include "../conf.h"#include "../user.h"struct {	int	hpcs1;	/* Control and Status register 1 */	int	hpwc;	/* Word count register */	int	hpba;	/* UNIBUS address register */	int	hpda;	/* Desired address register */	int	hpcs2;	/* Control and Status register 2*/	int	hpds;	/* Drive Status */	int	hper1;	/* Error register 1 */	int	hpas;	/* Attention Summary */	int	hpla;	/* Look ahead */	int	hpdb;	/* Data buffer */	int	hpmr;	/* Maintenance register */	int	hpdt;	/* Drive type */	int	hpsn;	/* Serial number */	int	hpof;	/* Offset register */	int	hpca;	/* Desired Cylinder address register*/	int	hpcc;	/* Current Cylinder */	int	hper2;	/* Error register 2 */	int	hper3;	/* Error register 3 */	int	hppos;	/* Burst error bit position */	int	hppat;	/* Burst error bit pattern */	int	hpbae;	/* 11/70 bus extension */};#define	HPADDR	0176700#define	NHP	8struct {	char	*nblocks;	int	cyloff;} hp_sizes[] {	9614,	0,		/* cyl 0 thru 23 */				/* cyl 24 thru 43 available */	-1,	44,		/* cyl 44 thru 200 */	-1,	201,		/* cyl 201 thru 357 */	20900,	358,		/* cyl 358 thru 407 */				/* cyl 408 thru 410 blank */	40600,	0,	40600,	100,	40600,	200,	40600,	300,};struct	devtab	hptab;struct	buf	hpbuf;char	hp_openf;			/* Drive Commands */#define	GO	01#define	PRESET	020#define	RECAL	06#define RCLR	010#define OFFSET	014#define	READY	0200	/* hpds - drive ready */#define	PIP	020000	/* hpds - Positioning Operation in Progress */#define	ERR	040000	/* hpcs1 - composite error */#define	DU	040000	/* hper1 - Drive Unsafe	*/#define	DTE	010000  /* hper1 - Drive Timing Error	*/#define	OPI	020000  /* hper1 - Operation Incomplete	*/		/* Error Correction Code errors */#define DCK	0100000	/* hper1 - Data Check error */#define ECH	0100    /* hper1 - ECC hard error */#define CLR	040	/* hpcs2 - Controller Clear */#define FMT22	010000	/* hpof - 16 bit /word format *//* * Use av_back to save track+sector, * b_resid for cylinder. */#define	trksec	av_back#define	cylin	b_residhpopen(){	if(!hp_openf){		hp_openf++;		HPADDR->hpcs2 = CLR;		HPADDR->hpcs1 = RCLR|GO;		HPADDR->hpcs1 = PRESET|GO;		HPADDR->hpof = FMT22;	}}hpstrategy(abp)struct buf *abp;{	register struct buf *bp;	register char *p1, *p2;	bp = abp;	p1 = &hp_sizes[bp->b_dev.d_minor&07];	if (bp->b_dev.d_minor >= (NHP<<3) ||	    bp->b_blkno >= p1->nblocks) {		bp->b_flags =| B_ERROR;		iodone(bp);		return;	}	bp->av_forw = 0;	bp->cylin = p1->cyloff;	p1 = bp->b_blkno;	p2 = lrem(p1, 22);	p1 = ldiv(p1, 22);	bp->trksec = (p1%19)<<8 | p2;	bp->cylin =+ p1/19;	spl5();	if ((p1 = hptab.d_actf)==0)		hptab.d_actf = bp;	else {		for (; p2 = p1->av_forw; p1 = p2) {			if (p1->cylin <= bp->cylin			 && bp->cylin <  p2->cylin			 || p1->cylin >= bp->cylin			 && bp->cylin >  p2->cylin) 				break;		}		bp->av_forw = p2;		p1->av_forw = bp;	}	if (hptab.d_active==0)		hpstart();	spl0();}hpstart(){	register struct buf *bp;	if ((bp = hptab.d_actf) == 0)		return;	hptab.d_active++;	HPADDR->hpcs2 = bp->b_dev.d_minor >> 3;	HPADDR->hpca = bp->cylin;	rhstart(bp, &HPADDR->hpda, bp->trksec, &HPADDR->hpbae);}hpintr(){	register struct buf *bp;	register int ctr;	if (hptab.d_active == 0)		return;	bp = hptab.d_actf;	hptab.d_active = 0;	if (HPADDR->hpcs1 & ERR) {		/* error bit */		deverror(bp, HPADDR->hpcs2, 0);		if(HPADDR->hper1 & (DU|DTE|OPI)) {			HPADDR->hpcs2 = CLR;			HPADDR->hpcs1 = RECAL|GO;			ctr = 0;			while ((HPADDR->hpds&PIP) && --ctr);		}		HPADDR->hpcs1 = RCLR|GO;		if (++hptab.d_errcnt <= 10) {			hpstart();			return;		}		bp->b_flags =| B_ERROR;	}	hptab.d_errcnt = 0;	hptab.d_actf = bp->av_forw;	bp->b_resid = HPADDR->hpwc;	iodone(bp);	hpstart();}hpread(dev){	if(hpphys(dev))	physio(hpstrategy, &hpbuf, dev, B_READ);}hpwrite(dev){	if(hpphys(dev))	physio(hpstrategy, &hpbuf, dev, B_WRITE);}hpphys(dev){	register c;	c = lshift(u.u_offset, -9);	c =+ ldiv(u.u_count+511, 512);	if(c > hp_sizes[dev.d_minor & 07].nblocks) {		u.u_error = ENXIO;		return(0);	}	return(1);}

⌨️ 快捷键说明

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