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

📄 sm.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * @(#)sm.c 1.1 92/07/30 Copyright (c) 1988 by Sun Microsystems, Inc. * *      Emulex ESP SCSI (low-level) driver * * *      3/89    KSAM    Send back exact amount of transferred bytes for  *			Front-load 1/2 tape per 4.0.3 FCS release. *      11/88   KSAM    Add in support for 4.0.3 beta release *      9/88    KSAM    Change to match the new 4.0 REV-2 SCSI structure *      8/88    KSAM    Add in Stingray support *      5/88    KSAM    initial written */#if (defined sun4) || (defined sun3x)#define REL4            	   /* enable release 4.00 mods */#ifdef notdef#define SMEPRINT	          /* Allow error printfs */#define SMDEBUG		          /* Allow compiling of debug code */#endif notdef#ifdef  REL4#include <sys/types.h>#include <sys/buf.h>#include <sun/dklabel.h>#include <sun/dkio.h>#include <stand/smreg.h>#include <stand/scsi.h>#include <stand/saio.h>#else REL4#include "../h/types.h"#include "../h/buf.h"#include "../sun/dklabel.h"#include "../sun/dkio.h"#include "smreg.h"#include "scsi.h"#include "saio.h"#endif REL4#ifdef  REL4#include <mon/sunromvec.h>#include <mon/idprom.h>#else REL4#include "../mon/sunromvec.h"#include "../mon/idprom.h"#endif REL4/* for bring-up stage, print all error messages */#ifdef SMDEBUGint sm_debug = 1;               /* normally enable  error-printfs *//* Handy debugging 0, 1, and 2 argument printfs, NEED "sm_debug" */#define DPRINTF(str) \        if (sm_debug > 2) printf(str)#define DPRINTF1(str, arg1) \        if (sm_debug > 3) printf(str,arg1)#define DPRINTF2(str, arg1, arg2) \        if (sm_debug > 4) printf(str,arg1,arg2)#define DEBUG_DELAY(cnt) \        if (sm_debug > 5) DELAY(cnt)#define EPRINTF(str) \        if (sm_debug) printf(str)#define EPRINTF1(str, arg1) \        if (sm_debug)  printf(str,arg1)#define EPRINTF2(str, arg1, arg2) \        if (sm_debug) printf(str,arg1,arg2)#else SMDEBUG#define DEBUG_DELAY(cnt)#define DPRINTF(str) 	#define DPRINTF1(str, arg1) #define DPRINTF2(str, arg1, arg2) #ifdef SMEPRINT#define EPRINTF(str) 			printf(str)#define EPRINTF1(str, arg1) 		printf(str,arg1)#define EPRINTF2(str, arg1, arg2) 	printf(str,arg1,arg2)#else#define EPRINTF(str)#define EPRINTF1(str, arg1) #define EPRINTF2(str, arg1, arg2) #endif SMEPRINT#endif SMDEBUG/* * 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. * * This "h_sip" must be initialized with h_sip->smboottab = sm_driver * and must then be devopen()ed before any I/O can be done. * * The device must be closed with devclose(). *//* * The interfaces we export */extern int  scsi_debug;extern char *devalloc();extern char *resalloc();extern int  nullsys();extern u_char sc_cdb_size[];int	smopen(), smdoit(), sm_reset();/* special snapshot data structure for sm.c */ struct sm_snap smreg_info;int	scsi_reset = ZERO;#define FAIL		-1	#define OK		0	/* * Open the SCSI host adapter. * if found, return (OK=0), FAIL=-1 otherwise. */intsmopen(h_sip)	register struct host_saioreq	*h_sip;{	register struct scsi_sm_reg *smr;	register struct udc_table *dvma;	register int	i, j;	struct idprom id;	int base;	int scsi_nstd;	enum MAPTYPES space;	u_long	dvmastat;	if (idprom(IDFORM_1, &id) == IDFORM_1) {		space = MAP_OBIO;		scsi_nstd = 1;	        DPRINTF1("smopen: id.machine= %x\n", id.id_machine);		switch (id.id_machine) {#ifdef sun3x		   case IDM_SUN3X_HYDRA:			base = HYDRA_SCSI_BASE;			i = HYDRA;			break;#endif sun3x#ifdef sun4		   case IDM_SUN4_STINGRAY:			base = STINGRAY_SCSI_BASE;			i = STINGRAY;			break;#endif sun4	           default:			EPRINTF1("smopen: unknown machine type= %x\n", 				id.id_machine);			/* other configuration not supported */			return(FAIL);			}	} else {		/* unknown id type not supported */		EPRINTF1("smopen: UNKNOWN id type= %x\n", 			idprom(IDFORM_1, &id));		return(FAIL);		}	DPRINTF1("smopen: ctlr= %x\n", h_sip->ctlr);	/* get base address of registers */	if (h_sip->ctlr < scsi_nstd) {		h_sip->ctlr = base + (h_sip->ctlr * SM_SIZE);	} else {		EPRINTF2("smopen: invalid cltr_num= %x, busid= %x\n", 			h_sip->ctlr, h_sip->unit);		return(FAIL);		}	DPRINTF1("smopen: REG_base= %x\n", h_sip->ctlr);	DEBUG_DELAY(1000000);	/* now map it in */	h_sip->devaddr = devalloc(space, h_sip->ctlr, 		    sizeof(struct scsi_sm_reg));	if (h_sip->devaddr == ZERO) {		EPRINTF("smopen: Can not allocate ESP space\n");		return(FAIL);		}	DPRINTF1("smopen: sm_addr = %x\n", h_sip->devaddr);	/* allocate dma resources for on-board host */	h_sip->dmaaddr = h_sip->devaddr + STINGRAY_DMA_OFFSET;	smr = (struct scsi_sm_reg *)h_sip->devaddr;	dvma = (struct udc_table *)h_sip->dmaaddr;#ifdef sun4	DPRINTF1("smopen: peeking DVMA's ctl_stat @ %x\n", 		&dvma->ctl_stat);/* I only modify the lib/sun4/probe.s */        if ((peekl((long *)&(dvma->ctl_stat))) == -1) {                EPRINTF1("smopen: peek on DVMA-scsi dma_addr= %x FAILED\n",               		&(dvma->ctl_stat));        	DEBUG_DELAY(1000000);		return(FAIL);	        }	DPRINTF1("smopen: DVMA exists, reg_stat= %x\n", dvma->ctl_stat);#endif sun4       	DEBUG_DELAY(1000000);        dvmastat = dvma->ctl_stat;        if (dvmastat & DVMA_REQPEND) {                    EPRINTF1("smopen: DVMA-scsi req_pend stuck, stat= %x\n", 			dvmastat);		return(FAIL);	        }        if (dvmastat & DVMA_RESET) {                DPRINTF1("smopen: DVMA reset asserted, stat= %x\n", i);                /* attempt to clear it, if not successful, error return */                dvma->ctl_stat = ZERO;                for (i = 0; i < LOOP_2MSEC; i++);                dvmastat = dvma->ctl_stat;                if (dvmastat & DVMA_RESET) {                   EPRINTF1("smopen: DVMA-scsi reset stuck, stat= %x\n", 			dvmastat);		   return(FAIL);	                }                DPRINTF1("smopen: deasserted DVMA reset, stat= %x\n", i);        }        /* write/read/compare DVMA 's address reg */        dvmastat = DVMA_TPATTERN;	dvma->dma_addr = dvmastat;        DPRINTF2("smopen: DVMA test, wr= %x, rd= %x\n", 		dvmastat, dvma->dma_addr);        if (dvma->dma_addr != dvmastat) {            EPRINTF2("smopen: DVMA-scsi mismatched dma_addr, wr= %x, rd= %x\n",                        i, dvma->dma_addr);		return(FAIL);	        }        dvma->dma_addr = ZERO;        DPRINTF2("smopen: DVMA-scsi PASSED, stat= %x, addr= %x\n",                dvma->ctl_stat, dvma->dma_addr);        DEBUG_DELAY(1000000);                /* check existence and operational status of DVMA before */        /* checking on ESP.  If scsi_reset in DVMA is asserted, the */        /* ESP register will not be accessible and DVMA itself is */        /* NOT in a operational state */	/* Check ESP existence -- peek on "ESP reg_xcnt_lo" */#ifdef sun4	DPRINTF1("smopen: peeking ESP's xcnt_lo @ %x\n", 		&ESP_RD.xcnt_lo);/* I only modify the lib/sun4/probe.s */	if ((peekc((u_char *)&(ESP_RD.xcnt_lo))) == -1) {			EPRINTF1("smopen: peek on ESP's addr= %x FAILED\n",                        &ESP_RD.xcnt_lo);                DEBUG_DELAY(1000000);		return(FAIL);		}	DPRINTF1("smopen: ESP exists, reg_conf= %x\n", ESP_RD.conf);#endif sun4        /* perform a simple write, read and compare validation test to           "ESP reg_conf".  If error, return */        i = 0x55;        ESP_WR.conf = i;        j = ESP_RD.conf;        DPRINTF2("smopen: ESP wr= %x, rd= %x\n", i, j);        if ((u_char)i != (u_char)j) {                DEBUG_DELAY(1000000);		return(FAIL);	        }                 i = 0xaa;        ESP_WR.conf = i;        j = ESP_RD.conf;        DPRINTF2("smopen: ESP wr: = %x, rd= %x\n", i, j);        DEBUG_DELAY(1000000);        if ((u_char)i != (u_char)j) {                DEBUG_DELAY(1000000);		return(FAIL);	        }                 i = ZERO;        ESP_WR.conf = i;        j = ESP_RD.conf;        if ((u_char)i != (u_char)j)  {                DPRINTF2("smopen: ESP FAILED, wr= %x, rd= %x\n", i, j);                DEBUG_DELAY(1000000);		return(FAIL);	        }         	/* Perform a simple write, read & compare validation test to ESP_II */        i = ESP_TPATTERN;        ESP_WR.conf2 = i;               /* write */        j = ESP_RD.conf2;               /* read */        if ((u_char)i == (u_char)j) {   /* compare */                ESP_WR.conf2 = ZERO;    /* make ESP 2 function as ESP */                DPRINTF("smopen: ESP_2 found, config to ESP\n");        }                 else                DPRINTF("smopen: ESP_2 not found\n");        DEBUG_DELAY(1000000);	/* set all the routine pointers */        DPRINTF("smopen: setting doit() pointer\n");	h_sip->doit = smdoit;	h_sip->reset = sm_reset;	if (scsi_reset == ZERO) {	    /* need to reset SCSI bus when call from le() boot, since */	    /* firmware will not call scsi driver to reset the bus */		sm_reset(h_sip, RESET_ALL_SCSI);		scsi_reset++;	}	else {		sm_reset(h_sip, RESET_INT_ONLY);	}        DPRINTF1("smopen: done, smr= %x\n", smr);	return(OK);		/* successfully opened */}/* * Write a command to the SCSI bus. * * The supplied h_sip is the one opened by smopen(). * DMA is done based on h_sip->ma and h_sip->cc. * * Returns -1 for error, otherwise returns the residual count * * FIXME, this must be accessed via a boottab vector, * to allow host adap to switch. * Must pass cdb, scb in h_sip somewhere...*/intsmdoit(cdb, scb, h_sip)	struct scsi_cdb *cdb;	struct scsi_scb *scb;	struct host_saioreq *h_sip;{	register struct scsi_sm_reg *smr;	register struct sm_snap *smsnap = &smreg_info;	register struct udc_table *dvma;	register u_char *cp;	register int i, size;	u_long	toutcnt;	/* get to scsi control logic registers */	smr = (struct scsi_sm_reg *)h_sip->devaddr;	dvma = (struct udc_table *)h_sip->dmaaddr;        	DPRINTF("smdoit: POLL/NO_disconnect mode\n");	cp = (u_char *)cdb;	size = sc_cdb_size[CDB_GROUPID(*cp)];	/* Write "ESP reg_fifo" with all command bytes */	DPRINTF("smdoit: cmd byte=");	for (i = 0; i < size; i++) {		DPRINTF1(" %x", *cp);		ESP_WR.fifo_data = *cp++;	}	DPRINTF1("\nsmdoit: fifo_flag @= %x\n", ESP_RD.fifo_flag);    	DEBUG_DELAY(1000000);	DPRINTF1("smdoit: ready to send cmd= %x\n", cdb->scc_cmd);	switch (cdb->scc_cmd) {	  case SC_READ:	  case SC_REQUEST_SENSE:	  case SC_INQUIRY:	  case SC_MODE_SENSE:		smsnap->sync_chk = SM_RECV_DATA;		break;	  case SC_WRITE:	  case SC_MODE_SELECT:	  case SC_WRITE_FILE_MARK:

⌨️ 快捷键说明

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