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

📄 scsincr53c8xx.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * NCR/Symbios/LSI Logic 53c8xx driver for Plan 9 * Nigel Roles (nigel@9fs.org) * * 13/3/01	Fixed microcode to support targets > 7 * * 01/12/00	Removed previous comments. Fixed a small problem in *			mismatch recovery for targets with synchronous offsets of >=16 *			connected to >=875s. Thanks, Jean. * * Known problems * * Read/write mismatch recovery may fail on 53c1010s. Really need to get a manual.*/#define MAXTARGET	16		/* can be 8 or 16 *//* Define one or the other ... *///#define CPU#ifndef FS#define FS#endif#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#ifndef FS#include "../port/error.h"#endif#include "ureg.h"#ifdef NAINCLUDE#include "na/na.h"#include "na/nasupport.h"#endif /* NAINCLUDE *//**********************************//* Portable configuration macros  *//**********************************///#define BOOTDEBUG//#define SINGLE_TARGET//#define ASYNC_ONLY//#define	QUICK_TIMEOUT//#define	INTERNAL_SCLK//#define ALWAYS_DO_WDTR#define WMR_DEBUG/**********************************//* CPU specific macros            *//**********************************/#ifdef CPU#ifdef BOOTDEBUG#define KPRINT oprint#define IPRINT iprint#define DEBUG(n) 0#define IFLUSH() iflush()#else#define KPRINT kprint#define IPRINT kprint#define DEBUG(n) scsidebugs[n]#define IFLUSH()#endif#endif/*******************************//* Fileserver specific defines *//*******************************/#ifdef FS#define DEVICENAME "ncr53c8xx"#define PRINTPREFIX DEVICENAME ": "#define xalloc(n) ialloc(n, 1)#define KADDR(a) ((void*)((ulong)(a)|KZERO))#define KPRINT if(0)print#define IPRINT if(0)print#define DEBUG(n) 0#define IFLUSH()#endif/*******************************//* General                     *//*******************************/#ifndef DMASEG#define DMASEG(x) PADDR(x)#define legetl(x) (*(ulong*)(x))#define lesetl(x,v) (*(ulong*)(x) = (v))#define swabl(a,b,c)#define IRQBASE Int0vec#else#define IRQBASE (PCIvec + 5)#endif#define DMASEG_TO_KADDR(x) KADDR(PADDR(x))#define KPTR(x) ((x) == 0 ? 0 : DMASEG_TO_KADDR(x))#define MEGA 1000000L#ifdef INTERNAL_SCLK#define	SCLK (33 * MEGA)#else#define SCLK (40 * MEGA)#endif#define ULTRA_NOCLOCKDOUBLE_SCLK (80 * MEGA)#define MAXSYNCSCSIRATE (5 * MEGA)#define MAXFASTSYNCSCSIRATE (10 * MEGA)#define MAXULTRASYNCSCSIRATE (20 * MEGA)#define MAXULTRA2SYNCSCSIRATE (40 * MEGA)#define MAXASYNCCORERATE (25 * MEGA)#define MAXSYNCCORERATE (25 * MEGA)#define MAXFASTSYNCCORERATE (50 * MEGA)#define MAXULTRASYNCCORERATE (80 * MEGA)#define MAXULTRA2SYNCCORERATE (160 * MEGA)#define X_MSG	1#define X_MSG_SDTR 1#define X_MSG_WDTR 3#ifndef NAINCLUDEstruct na_patch {	unsigned lwoff;	unsigned char type;};#endif /* NAINCLUDE */extern int scsidebugs[];typedef struct Ncr {	uchar scntl0;	/* 00 */	uchar scntl1;	uchar scntl2;	uchar scntl3;	uchar scid;	/* 04 */	uchar sxfer;	uchar sdid;	uchar gpreg;	uchar sfbr;	/* 08 */	uchar socl;	uchar ssid;	uchar sbcl;	uchar dstat;	/* 0c */	uchar sstat0;	uchar sstat1;	uchar sstat2;	uchar dsa[4];	/* 10 */	uchar istat;	/* 14 */	uchar istatpad[3];	uchar ctest0;	/* 18 */	uchar ctest1;	uchar ctest2;	uchar ctest3;	uchar temp[4];	/* 1c */	uchar dfifo;	/* 20 */	uchar ctest4;	uchar ctest5;	uchar ctest6;	uchar dbc[3];	/* 24 */	uchar dcmd;	/* 27 */	uchar dnad[4];	/* 28 */	uchar dsp[4];	/* 2c */	uchar dsps[4];	/* 30 */	uchar scratcha[4];	/* 34 */	uchar dmode;	/* 38 */	uchar dien;	uchar dwt;	uchar dcntl;	uchar adder[4];	/* 3c */	uchar sien0;	/* 40 */	uchar sien1;	uchar sist0;	uchar sist1;	uchar slpar;	/* 44 */	uchar slparpad0;	uchar macntl;	uchar gpcntl;	uchar stime0;	/* 48 */	uchar stime1;	uchar respid;	uchar respidpad0;	uchar stest0;	/* 4c */	uchar stest1;	uchar stest2;	uchar stest3;	uchar sidl;	/* 50 */	uchar sidlpad[3];	uchar sodl;	/* 54 */	uchar sodlpad[3];	uchar sbdl;	/* 58 */	uchar sbdlpad[3];	uchar scratchb[4];	/* 5c */} Ncr;typedef struct Movedata {	uchar dbc[4];	uchar pa[4];} Movedata;typedef enum NegoState {	NeitherDone, WideInit, WideResponse, WideDone,	SyncInit, SyncResponse, BothDone} NegoState;typedef enum State {	Allocated, Queued, Active, Done} State;typedef struct Dsa {	union {		uchar state[4];		struct {			uchar stateb;			uchar result;			uchar dmablks;			uchar flag;	/* setbyte(state,3,...) */		};	};	union {		ulong dmancr;		/* For block transfer: NCR order (little-endian) */		uchar dmaaddr[4];	};	uchar target;			/* Target */	uchar pad0[3];	uchar lun;			/* Logical Unit Number */	uchar pad1[3];	uchar scntl3;	uchar sxfer;	uchar pad2[2];	uchar next[4];			/* chaining for SCRIPT (NCR byte order) */	struct Dsa *freechain;		/* chaining for freelist */	Rendez;	uchar scsi_id_buf[4];	Movedata msg_out_buf;	Movedata cmd_buf;	Movedata data_buf;	Movedata status_buf;	uchar msg_out[10];		/* enough to include SDTR */	uchar status;	ushort p9status;	uchar parityerror;} Dsa;typedef enum Feature {	BigFifo = 1,			/* 536 byte fifo */	BurstOpCodeFetch = 2,		/* burst fetch opcodes */	Prefetch = 4,			/* prefetch 8 longwords */	LocalRAM = 8,			/* 4K longwords of local RAM */	Differential = 16,		/* Differential support */	Wide = 32,			/* Wide capable */	Ultra = 64,			/* Ultra capable */	ClockDouble = 128,		/* Has clock doubler */	ClockQuad = 256,		/* Has clock quadrupler (same as Ultra2) */	Ultra2 = 256,} Feature;typedef enum Burst {	Burst2 = 0,	Burst4 = 1,	Burst8 = 2,	Burst16 = 3,	Burst32 = 4,	Burst64 = 5,	Burst128 = 6} Burst;typedef struct Variant {	ushort did;	uchar maxrid;			/* maximum allowed revision ID */	char *name;	Burst burst;			/* codings for max burst */	uchar maxsyncoff;		/* max synchronous offset - must be power of 2 */	uchar registers;		/* number of 32 bit registers */	unsigned feature;} Variant;static unsigned char cf2[] = { 6, 2, 3, 4, 6, 8, 12, 16 };#define NULTRA2SCF (sizeof(cf2)/sizeof(cf2[0]))#define NULTRASCF (NULTRA2SCF - 2)#define NSCF (NULTRASCF - 1)typedef struct Controller {	Lock;	struct {		uchar scntl3;		uchar stest2;	} bios;	int ctlrno;	uchar synctab[NULTRA2SCF - 1][8];/* table of legal tpfs */	NegoState s[MAXTARGET];	uchar scntl3[MAXTARGET];	uchar sxfer[MAXTARGET];	uchar cap[MAXTARGET];		/* capabilities byte from Identify */	ushort capvalid;		/* bit per target for validity of cap[] */	ushort wide;			/* bit per target set if wide negotiated */	ulong sclk;			/* clock speed of controller */	uchar clockmult;		/* set by synctabinit */	uchar ccf;			/* CCF bits */	uchar tpf;			/* best tpf value for this controller */	uchar feature;			/* requested features */	int running;			/* is the script processor running? */	int ssm;			/* single step mode */	Ncr *n;				/* pointer to registers */	Variant *v;			/* pointer to variant type */	ulong *script;			/* where the real script is */	ulong scriptpa;			/* where the real script is */	struct {		Lock;		uchar head[4];		/* head of free list (NCR byte order) */		Dsa	*tail;		Dsa	*freechain;	} dsalist;	QLock q[MAXTARGET];		/* queues for each target */} Controller;#define SYNCOFFMASK(c)		(((c)->v->maxsyncoff * 2) - 1)#define SSIDMASK(c)		(((c)->v->feature & Wide) ? 15 : 7)static Controller *ctlrxx[MaxScsi];/* ISTAT */enum { Abrt = 0x80, Srst = 0x40, Sigp = 0x20, Sem = 0x10, Con = 0x08, Intf = 0x04, Sip = 0x02, Dip = 0x01 };/* DSTAT */enum { Dfe = 0x80, Mdpe = 0x40, Bf = 0x20, Abrted = 0x10, Ssi = 0x08, Sir = 0x04, Iid = 0x01 };/* SSTAT */enum { DataOut, DataIn, Cmd, Status, ReservedOut, ReservedIn, MessageOut, MessageIn };#define STATUS_COMPLETE 0x6000#define STATUS_FAIL 0x8000#define STATUS_SELECTION_TIMEOUT 0x0200static void setmovedata(Movedata*, ulong, ulong);static void advancedata(Movedata*, long);static int bios_set_differential(Controller *c);static char *phase[] = {	"data out", "data in", "command", "status",	"reserved out", "reserved in", "message out", "message in"};#ifdef BOOTDEBUG#define DEBUGSIZE 10240char debugbuf[DEBUGSIZE];char *debuglast;voidiprint(char *format, ...){	if (debuglast == 0)		debuglast = debugbuf;	debuglast = doprint(debuglast, debugbuf + (DEBUGSIZE - 1), format, (&format + 1));}voidiflush(){	int s;	char *endp;	s = splhi();	if (debuglast == 0)		debuglast = debugbuf;	if (debuglast == debugbuf) {		splx(s);		return;	}	endp = debuglast;	splx(s);	screenputs(debugbuf, endp - debugbuf);	s = splhi();	memmove(debugbuf, endp, debuglast - endp);	debuglast -= endp - debugbuf;	splx(s);}voidoprint(char *format, ...){	int s;	iflush();	s = splhi();	if (debuglast == 0)		debuglast = debugbuf;	debuglast = doprint(debuglast, debugbuf + (DEBUGSIZE - 1), format, (&format + 1));	splx(s);	iflush();}#endif#include "script.i"static Dsa *dsaalloc(Controller *c, int target, int lun){	Dsa *d;	ilock(&c->dsalist);	if ((d = c->dsalist.freechain) == 0) {		d = xalloc(sizeof(*d));		if (DEBUG(1))			KPRINT(PRINTPREFIX "%d/%d: allocated new dsa %lux\n", target, lun, (ulong)d);		lesetl(d->next, 0);		lesetl(d->state, A_STATE_ALLOCATED);		if (legetl(c->dsalist.head) == 0)			lesetl(c->dsalist.head, DMASEG(d));	/* ATOMIC?!? */		else			lesetl(c->dsalist.tail->next, DMASEG(d));	/* ATOMIC?!? */		c->dsalist.tail = d;	}	else {		if (DEBUG(1))			KPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d);		c->dsalist.freechain = d->freechain;		lesetl(d->state, A_STATE_ALLOCATED);	}	iunlock(&c->dsalist);	d->target = target;	d->lun = lun;	return d;}static voiddsafree(Controller *c, Dsa *d){	ilock(&c->dsalist);	d->freechain = c->dsalist.freechain;	c->dsalist.freechain = d;	lesetl(d->state, A_STATE_FREE);	iunlock(&c->dsalist);}static Dsa *dsafind(Controller *c, uchar target, uchar lun, uchar state){	Dsa *d;	for (d = KPTR(legetl(c->dsalist.head)); d; d = KPTR(legetl(d->next))) {		if (d->target != 0xff && d->target != target)			continue;		if (lun != 0xff && d->lun != lun)			continue;		if (state != 0xff && d->stateb != state)			continue;		break;	}	return d;}static voiddumpncrregs(Controller *c, int intr){	int i;	Ncr *n = c->n;	int depth = c->v->registers / 4;	KPRINT("sa = %.8lux\n", c->scriptpa);	for (i = 0; i < depth; i++) {		int j;		for (j = 0; j < 4; j++) {			int k = j * depth + i;			uchar *p;			/* display little-endian to make 32-bit values readable */			p = (uchar*)n+k*4;			if (intr)				IPRINT(" %.2x%.2x%.2x%.2x %.2x %.2x", p[3], p[2], p[1], p[0], k * 4, (k * 4) + 0x80);			else				KPRINT(" %.2x%.2x%.2x%.2x %.2x %.2x", p[3], p[2], p[1], p[0], k * 4, (k * 4) + 0x80);			USED(p);		}		if (intr)			IPRINT("\n");		else			KPRINT("\n");	}}static intchooserate(Controller *c, int tpf, int *scfp, int *xferpp){	/* find lowest entry >= tpf */	int besttpf = 1000;	int bestscfi = 0;	int bestxferp = 0;	int scf, xferp;	int maxscf;	if (c->v->feature & Ultra2)		maxscf = NULTRA2SCF;	else if (c->v->feature & Ultra)		maxscf = NULTRASCF;	else		maxscf = NSCF;	/*	 * search large clock factors first since this should	 * result in more reliable transfers	 */	for (scf = maxscf; scf >= 1; scf--) {		for (xferp = 0; xferp < 8; xferp++) {			unsigned char v = c->synctab[scf - 1][xferp];			if (v == 0)				continue;			if (v >= tpf && v < besttpf) {				besttpf = v;				bestscfi = scf;				bestxferp = xferp;			}		}	}	if (besttpf == 1000)		return 0;	if (scfp)		*scfp = bestscfi;	if (xferpp)		*xferpp = bestxferp;	return besttpf;}

⌨️ 快捷键说明

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