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

📄 si.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * @(#)si.c 1.1 92/07/30 Copyright (c) 1985 by Sun Microsystems, Inc. *//*#define SIDEBUG 		/* Allow compiling of debug code */#define REL4			/* Enable release 4 mods */#ifdef	REL4#include <sys/types.h>#include <sys/buf.h>#include <sun/dklabel.h>#include <sun/dkio.h>#include <stand/sireg.h>#include <stand/scsi.h>#include <stand/saio.h>#include <mon/sunromvec.h>#include <mon/idprom.h>#else REL4#include "../h/types.h"#include "../h/buf.h"#include "../sun/dklabel.h"#include "../sun/dkio.h"#include "sireg.h"#include "scsi.h"#include "saio.h"#include "../mon/sunromvec.h"#include "../mon/idprom.h"#endif REL4#ifdef SIDEBUG/* Handy debugging 0, 1, and 2 argument printfs */#define DPRINTF(str) \	if (scsi_debug > 1) printf(str)#define DPRINTF1(str, arg1) \	if (scsi_debug > 1) printf(str,arg1)#define DPRINTF2(str, arg1, arg2) \	if (scsi_debug > 1) printf(str,arg1,arg2)/* Handy extended error reporting 0, 1, and 2 argument printfs */#define EPRINTF(str) \	if (scsi_debug) printf(str)#define EPRINTF1(str, arg1) \	if (scsi_debug) printf(str,arg1)#define EPRINTF2(str, arg1, arg2) \	if (scsi_debug) printf(str,arg1,arg2)#else SIDEBUG#define DPRINTF(str)#define DPRINTF1(str, arg2)#define DPRINTF2(str, arg1, arg2)#define EPRINTF(str)#define EPRINTF1(str, arg2)#define EPRINTF2(str, arg1, arg2)#endif SIDEBUG#ifdef BOOTBLOCK#define SC_ERROR(str)#define SC_ERROR1(str, arg1)#else BOOTBLOCK#define SC_ERROR	printf#define SC_ERROR1	printf#endif BOOTBLOCK#define SHORT_RESET	0#define LONG_RESET	1/* * Low-level routines common to all devices on the SCSI bus. * * Interface to the routines in this module is via a second "h_sip" * structure contained in the caller's local variables. *//* How si addresses look to the si vme scsi dma hardware */#define	SI_VME_DMA_ADDR(x)	(((int)x)&0x000FFFFF)/* How si addresses look to the sun3/50 scsi dma hardware */#define	SI_OB_DMA_ADDR(x)	(((int)x)&0x00FFFFFF)/* How si addresses look to the sun4/110 scsi dma hardware */#define	SI_COBRA_DMA_ADDR(x)	(((int)x)&0x00FFFFFF)/* * The interfaces we export */extern int scsi_debug;extern char *devalloc();extern char *resalloc();extern int nullsys();extern u_char sc_cdb_size[];int siopen(), sidoit(), si_reset();static u_char junk;#define SI_VME_BASE	0x200000#define SI_OB_BASE	0x140000#define SI_SIZE		0x4000struct sidma {	struct udc_table	udct;	/* dma information for udc */};/* * Open the SCSI host adapter. */intsiopen(h_sip)	register struct host_saioreq *h_sip;{	register struct scsi_si_reg *sir;	register int ctlr;	register int base;	register int si_nstd;	struct idprom id;	enum MAPTYPES space;	DPRINTF("siopen:\n");	/* determine type of si interface */	if (idprom(IDFORM_1, &id) == IDFORM_1) {		switch (id.id_machine) {		case IDM_SUN3_F:		case IDM_SUN3_M25:			EPRINTF("siopen: CPU SCSI-3\n");			h_sip->ob = 1;			base = SI_OB_BASE;			space = MAP_OBIO;			si_nstd = 1;			break;	        default:			EPRINTF("siopen: VME SCSI-3\n");			h_sip->ob = 0;			base = SI_VME_BASE;			space = MAP_VME24A16D;			si_nstd = SC_NSC;			break;		}	} else {		EPRINTF("siopen: failed\n");		return (-1);	}	/* Get base address of registers */	if (h_sip->ctlr <= si_nstd) {		ctlr = base + ((int)h_sip->ctlr * SI_SIZE);		DPRINTF1("siopen: ctlr= 0x%x\n", (int)ctlr);	} else {		if ((int)h_sip->devaddr == 0) {			EPRINTF("siopen: devalloc failure\n");			return (-2);		} else {			DPRINTF("siopen: reg. already allocated\n");			return (0);		}	}	/* Map in device registers */	h_sip->devaddr = devalloc(space, (char *)ctlr, 	    sizeof(struct scsi_si_reg));	if ((int)h_sip->devaddr == 0) {		EPRINTF("siopen: devalloc failure\n");		return (-2);	}	sir = (struct scsi_si_reg *)(h_sip->devaddr);	/*	 * If not on-board, peek past 2K bytes to make sure this is	 * a SCSI-3 host adaptor	 */#ifndef	sun4	if (!h_sip->ob  &&	    ((peek((short *)&sir->dma_addr) == -1)  ||	     (peek((short *)((int)sir +0x800)) != -1))) {		EPRINTF("siopen: peek failed\n");		return (-1);	}#else	sun4	if (!h_sip->ob  &&	    ((peek((short *)&sir->dma_addrl) == -1)  ||	     (peek((short *)((int)sir +0x800)) != -1))) {		EPRINTF("siopen: peek failed\n");		return (-1);	}#endif	sun4	/* Allocate dma resources */	h_sip->dmaaddr = 0;	if (h_sip->ob == 1) {		h_sip->dmaaddr = resalloc(RES_DMAMEM, sizeof(struct sidma));		DPRINTF1("siopen: dmaaddr= 0x%x\n", (int)h_sip->dmaaddr);		if (h_sip->dmaaddr == 0) {			EPRINTF("siopen: resalloc failure\n");			return (-2);		}	}	/* set host adapter's address modifier bits */	sir->iv_am = VME_SUPV_DATA_24;	/* Link top level driver to host adapter */	h_sip->doit = sidoit;	h_sip->reset = si_reset;	si_reset(h_sip, SHORT_RESET);	return (0);}/* * Write a command to the SCSI bus. * * The supplied h_sip is the one opened by scsi_probe. * DMA is done based on h_sip->ma and h_sip->cc. * * Returns -1 for error, otherwise returns the residual count not DMAed * (zero for success). */static intsidoit(cdb, scb, h_sip)	struct scsi_cdb *cdb;	struct scsi_scb *scb;	register struct host_saioreq *h_sip;	/* sip for host adapter */{	register struct scsi_si_reg *sir;	register u_char *cp;	u_char size;	register int b;	DPRINTF("sidoit:\n");	/* Get to scsi control logic registers */	sir = (struct scsi_si_reg *) h_sip->devaddr;	DPRINTF1("sidoit: sir= 0x%x\n", (int)sir);	/* Handle SCSI-3 case */	if (si_sbc_wait((caddr_t)&SBC_RD.cbsr, SBC_CBSR_BSY,	    SCSI_SHORT_DELAY, 0) == 0) {		SC_ERROR("si: bus busy\n");		goto FAILED;	}	/* Select target */	DPRINTF1("sidoit: unit= 0x%x\n", h_sip->unit);	SBC_WR.odr = (1 << h_sip->unit) | SI_HOST_ID;	SBC_WR.icr = SBC_ICR_DATA;	SBC_WR.icr |= SBC_ICR_SEL;	/* Wait for target to acknowledge our selection */	if (si_sbc_wait((caddr_t)&SBC_RD.cbsr, SBC_CBSR_BSY,	    SCSI_SEL_DELAY, 1) == 0) {		EPRINTF1("si: device offline, cbsr= 0x%x\n", SBC_RD.cbsr);		SBC_WR.icr = 0;		return (-2);	}	SBC_WR.icr = 0;	/* Do initial dma setup */	sir->bcr = 0;	/* also reset dma_count for vme */	if (h_sip->cc > 0) {		if (h_sip->dma_dir == SC_RECV_DATA) {			DPRINTF("sidoit: DMA receive\n");			sir->csr &= ~SI_CSR_SEND;		} else {			DPRINTF("sidoit: DMA send\n");			sir->csr |= SI_CSR_SEND;		}		sir->csr &= ~SI_CSR_FIFO_RES;		sir->csr |= SI_CSR_FIFO_RES;			sir->bcr = h_sip->cc;		SET_DMA_COUNT(sir, 0);		if (h_sip->ob == 0)			sir->bcrh = 0;	}	/* Put command onto scsi bus */	cp = (u_char *)cdb;	size = sc_cdb_size[CDB_GROUPID(*cp)];	if (si_putbyte(sir, PHASE_COMMAND, cp, size) == 0) {		SC_ERROR("si: cmd put failed\n");		goto FAILED;	}	if (h_sip->cc > 0) {		/* Finish dma setup and wait for dma completion */		if ((int)h_sip->ma & 1) {			SC_ERROR("si: illegal odd dma starting address\n");			goto FAILED;		}		if (h_sip->ob) {			si_ob_dma_setup(sir, h_sip);		} else {			if ((int)h_sip->ma & 0x2)				sir->csr |= SI_CSR_BPCON;			else				sir->csr &= ~SI_CSR_BPCON;			SET_DMA_ADDR(sir, SI_VME_DMA_ADDR(h_sip->ma));			SET_DMA_COUNT(sir, h_sip->cc);		}		si_dma_setup(h_sip, sir);	/* No dma, wait for target to request a byte */	} else if (si_sbc_wait((caddr_t)&SBC_RD.cbsr, SBC_CBSR_REQ,		   SCSI_LONG_DELAY, 1) == 0) {		SC_ERROR("si: target never set REQ\n");		goto FAILED;	}	/* Get status */	junk = SBC_RD.clr;	cp = (u_char *)scb;	cp[0] = si_getbyte(sir, PHASE_STATUS);	b = si_getbyte(sir, PHASE_MSG_IN);	if (b != SC_COMMAND_COMPLETE) {		EPRINTF("sidoit: no cmd complete msg\n");		/* If b < 0, si_getbyte already printed msg */		if (b >= 0)			SC_ERROR("si: invalid message\n");		goto FAILED;	}	return (h_sip->cc - sir->bcr);FAILED:	EPRINTF("sidoit: failed\n");	si_reset(h_sip, LONG_RESET);	return (-1);}staticsi_dma_setup(h_sip, sir)	register struct host_saioreq *h_sip;	register struct scsi_si_reg *sir;{       	register char *cp;	DPRINTF("si_dma_setup:\n");	/* Setup sbc and start dma */	if (h_sip->dma_dir == SC_RECV_DATA) {		DPRINTF("si_dma_setup: RECV\n");		SBC_WR.mr |= SBC_MR_DMA;		SBC_WR.tcr = TCR_DATA_IN;		SBC_WR.ircv = 0;	} else {		DPRINTF("si_dma_setup: SEND\n");		SBC_WR.mr |= SBC_MR_DMA;		SBC_WR.tcr = TCR_DATA_OUT;

⌨️ 快捷键说明

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