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

📄 ipi.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
/* * @(#)ipi.c 1.1 92/07/30 Copyright (c) 1988 by Sun Microsystems, Inc. * * ip.c - Boot PROM Driver for IPI Disk controller. */#include <sys/types.h>#include <stand/saio.h>#include <sys/buf.h>#include <sys/dkbad.h>#include <sun/dklabel.h>#include <sun/dkio.h>#include <sundev/ipdev.h>#include <sundev/ipvar.h>#define	DEV_BSIZE	512#define LABEL/* #define SUPERFAST */				/* For very high speed boot *//* #define DEBUG     */				/* For debug purposes	    */#ifdef	SUPERFAST#define	BIGSIZE		(256)			/* size in blocks (512) is ok with DVMA */int	gotcyl = -1;#endifstruct ipidma {	struct	ipi3pkt	    	ipi3pkt;	u_long		        pad_to_align1;#ifndef	SUPERFAST	char		        buff_addr[8196];		    /* R/W data */#else	char		        buff_addr[BIGSIZE * 512];	    /* R/W data */#endif	u_long		        pad_to_align3;};    #define	NSTD	4u_long  ipistd[NSTD]  = { 0x1080000, 0x1080400, 0x1080800, 0x1080c00		 	};struct devinfo ipinfo = {	sizeof (struct ipidevice),	/* size of register I/O space */ 	sizeof (struct ipidma),		/* size of DMA memory */	1024,				/* size of parameter block */	NSTD,			        /* # of standard addresses */	ipistd,			        /* vector of standard addresses */	MAP_VME32A32D,		 	/* which map space */	DEV_BSIZE * 16			/* transfer size 8k */};/*  * external functions that are called by the driver interfaces. */extern int	xxboot(), xxprobe();extern int	nullsys();int		ipiopen(), ipistrategy(), ipiready();extern int	await();/* * boottab structure that is used in the boot routine. */struct boottab ipidriver = {	"id",	xxprobe, xxboot, ipiopen, nullsys, ipistrategy,	"id: PANTHER (ipi) controller", &ipinfo,}; #define ADDR_DVMA(x)	(u_long)((u_long)x & ~0xfff00000)#define	ALIGN(x, i)	(u_long)(((u_long)x + (u_long)i) & ~(u_long)(i - 1))#define HOWMANY(x, y)   ((((u_int)(x))+(((u_int)(y))-1))/((u_int)(y)))#define CTLR(sip)	( ( (sip->si_ctlr) >> 8) & 0xf) / 4  /* No kidding */#define UNIT(sip)	(sip->si_unit & 07)#define TIMEOUT		0xfffff			/* timeout location */#define LOW		0#define HIGH		1/* * Description: opens the IPI disk controller * Synopsis:	status = ipiopen(sip) *		status	:(int) 0 = opened *			      -1 = error *		sip	:(int *) point to saioreq structure * Routines:	bzero	 */ipiopen(sip)	register struct saioreq	    *sip;{	register struct ipidevice    *ipaddr;	caddr_t			    xfer_ma;	struct	dk_label	     *dkptr;	int			     opcode = IP_READ;	int			     k;	int			     i = 0;	ipaddr = (struct ipidevice *)sip->si_devaddr;#ifndef BOOTBLOCK	/* Verify that ipi is really present */	if (peekl((char *)&ipaddr->dev_csr) == -1)		return (-1);#endif	!BOOTBLOCK	/* Wait for CSR_RESET bit to go LOW for 1000000 loops	 * after which barf "IPI reset"	*/	if (await (&ipaddr->dev_csr, CSR_RESET, LOW, 70000000, "reset")) {	    return(-1);			/* waited too long */	}	k = ipaddr->dev_resp;#ifdef lint	k = k;#endif		while ( i++ < 100000) {	    if (ipiready(sip)) break;	}	if (!isspinning(ipiready, sip)) {		return(-1);	}#ifdef LABEL	dkptr = (struct dk_label *)sip->si_devdata;	xfer_ma	= (caddr_t)(((struct ipidma *)(sip->si_dmaaddr))->buff_addr);	xfer_ma = (caddr_t)ALIGN(xfer_ma, 4);	ipicmd (opcode|(RWMOD <<8), IP_SYNC, CTLR(sip), UNIT(sip), 0,		2, (caddr_t)xfer_ma,		sip);	bcopy(xfer_ma, dkptr, 2 * DEV_BSIZE);	if ( dkptr->dkl_magic !=  0xDABE){		printf("Bad label\n");		return(-1);	}#endif	return(0);}ipiready(sip)	struct	saioreq		*sip;{	int			    status;	status  = ipicmd (IP_REPORT_STAT|(RWMOD <<8), IP_SYNC, CTLR(sip), UNIT(sip),		0, 2, (caddr_t)0,  sip);	return(status);	}/* * Description:	Executes read or write on the IPI controller * Synopsis:	status = ipistrategy(sip, rw) *		status	:(int)	= 0, failure *				= 1, success (count==0) *				= character count read, success *		sip	:(int *) pointer to saio stucture *		rw	:(int)	 read/write command code (overwritten) * Routines:	ipicmd  */intipistrategy(sip, rw)	struct saioreq *sip;	register int rw;{	register int opcode = (rw == WRITE) ? IP_WRITE : IP_READ;	register int blkno, count, boff, part;	struct	 dk_label   *dkptr;	caddr_t		ma, xfer_ma;#ifdef	SUPERFAST	int		savblkno, savcount, cylno;#endif#ifdef LABEL	dkptr = (struct dk_label *)sip->si_devdata;	part  = sip->si_boff;	boff  = dkptr->dkl_map[part].dkl_cylno		* dkptr->dkl_nsect * dkptr->dkl_nhead;#endif	blkno = sip->si_bn + boff;	count = sip->si_cc / DEV_BSIZE;	if ((blkno + count) >= (boff + dkptr->dkl_map[part].dkl_nblk))		return(0);	ma    = sip->si_ma;	xfer_ma	= (caddr_t)(((struct ipidma *)(sip->si_dmaaddr))->buff_addr);	xfer_ma = (caddr_t)ALIGN(xfer_ma, 4);	if (opcode == IP_WRITE)		bcopy(ma, xfer_ma, count*DEV_BSIZE);#ifdef	SUPERFAST				    /* get the cyl */	savblkno = blkno;	savcount = count;	cylno = blkno / BIGSIZE ;	count = BIGSIZE;	blkno = cylno * BIGSIZE;	if (cylno != gotcyl) {#endif	ipicmd (opcode|(RWMOD <<8), IP_SYNC, CTLR(sip), UNIT(sip), blkno,		count, (caddr_t)xfer_ma,  sip);#ifdef SUPERFAST	}	blkno	= savblkno;	count = savcount;	gotcyl	= cylno;	xfer_ma	+= (blkno % BIGSIZE)*512;#endif	if (opcode == IP_READ)		bcopy(xfer_ma, ma, count*DEV_BSIZE);	return(count * DEV_BSIZE);}/* * Description:	Internal interface to the IPI controller command set * * Synopsis:	status = ipicmd(opcode, mode, ctlr, unit, blkno, count, bufaddr, sip) *		status	:(int)	= -1, severe unretryable failure *				= 0, failure *				= 1, success (count==0) *				= character count read, success *		opcode	:(int) command code *              mode    : IP_SYNC *		sip	:(int *) pointer to saio stucture *		blkno	:(int) block number *		count	:(int) number of sectors * Routines:	bzero */intipicmd(opcode, mode, ctlr, unit, blkno, count, bufaddr, sip)u_long	opcode, mode;int	ctlr, unit, blkno, count;caddr_t	bufaddr;struct	saioreq	*sip;{	struct  ipi3pkt *pktptr;	struct  ippcb	pcb;	struct	ippcb *ppcb = &pcb;		/* pcb and DVMA is already available */	bzero(ppcb, sizeof(struct ippcb));	pktptr	    = &(((struct ipidma *)(sip->si_dmaaddr))->ipi3pkt);	pktptr	    = (struct ipi3pkt *)ALIGN(pktptr,  4);	bzero(pktptr, sizeof(struct ipi3pkt));	ppcb->pcb_ppkt	= pktptr;        ppcb->pcb_mode  = mode;	pktptr->pkt_hdr.hdr.hdr_refno	= 0xBAD;	pktptr->pkt_hdr.hdr.hdr_opcode	= opcode & 0xff;	pktptr->pkt_hdr.hdr.hdr_mods	= 1;	pktptr->pkt_hdr.hdr.hdr_ctlr	= ctlr;	pktptr->pkt_hdr.hdr.hdr_unit	= unit;	switch(opcode & 0xff) {	    case IP_READ:	    case IP_WRITE:		pktptr->pkt_hdr.hdr.hdr_pktlen	= sizeof(struct read_write) + 6;                pktptr->p_cmd.rdwr.xnp.pad	= 0;                pktptr->p_cmd.rdwr.xnp.id	= XFER_NOTIFY;                pktptr->p_cmd.rdwr.xnp.len	= 0x5;                pktptr->p_cmd.rdwr.xnp.bufadr	= (caddr_t)ADDR_DVMA(bufaddr);                pktptr->p_cmd.rdwr.cxp.pad	= 0;                pktptr->p_cmd.rdwr.cxp.id	= CMD_EXTENT;                pktptr->p_cmd.rdwr.cxp.len	= 0x9;                pktptr->p_cmd.rdwr.cxp.blk_cnt	= count;                pktptr->p_cmd.rdwr.cxp.lbn	= blkno;                break;	    case IP_REPORT_STAT:		pktptr->pkt_hdr.hdr.hdr_pktlen	= 6;		break;	    default:		break;	}	return ( ipigo(ppcb, sip) ? count * DEV_BSIZE : 0 ); } intipigo(ppcb,  sip)struct ippcb	    *ppcb;struct saioreq	    *sip;{	register struct ipidevice   *ipaddr;	int			     k;	u_long			    *pptr;	ipaddr = (struct ipidevice *)sip->si_devaddr;	if (await (&ipaddr->dev_csr, CSR_CRBUSY, LOW, 1000000, "device too busy")) {	    return(1);			/* waited too long */	}	ipaddr->dev_cmdreg   = ADDR_DVMA(ppcb->pcb_ppkt);	if (await(&ipaddr->dev_csr, CSR_CRBUSY, LOW, 10000000, "device still busy")){	    return(0);			/* waited too long */	}	if (await(&ipaddr->dev_csr, CSR_RRVLID, HIGH, 10000000, "no response")) {	    return(0);			/* waited too long */	}	if (ipaddr->dev_csr & CSR_ERROR) {		ipaddr->dev_csr |= CSR_RESET;		printf("Error/doing reset\n");		k = ipaddr->dev_resp;		return(0);	}	pptr	= (u_long *)&ipaddr->dev_resp_pkt;#define IP_NOTOPER  0x40000000		    /* goes in include file */#define	IP_NOTREADY 0x10000000	k = ipaddr->dev_resp;#ifdef lint        k = k;#endif	if ((pptr[1] & 0xffff0000) ==  0x3010000 ) {	    if (pptr[3] & IP_NOTOPER ) {		return(0);	    }	    if (pptr[3] & IP_NOTREADY)    {		return(0);	    }	}	return(1);}await(paddr, val, ord, timeout, s)long	*paddr;u_long	val, ord;int	timeout;char	*s;{    	int i;	for (i=0; i < timeout; i++) {	    if (ord) {		if ( (*paddr & val)) return(0); else continue;	    }	    else {		if (!(*paddr & val)) return(0); else continue;	    }	}	printf("timeout: ipi: %s\n", s);	return(1);}#ifdef DEBUGpr_pkt(pptr)u_long *pptr;{	int i;        printf("pptr %x:: ", pptr);        for (i=0; i< 12; i++) {               printf("%x ", *pptr++);	}	printf("\n");}#endif

⌨️ 快捷键说明

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