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

📄 si.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		SBC_WR.icr = SBC_ICR_DATA;		SBC_WR.send = 0;	}	if (h_sip->ob == 0) {		sir->csr |= SI_CSR_DMA_EN;	}	/* Wait for dma completion */	if (si_wait(&sir->csr, 		   SI_CSR_SBC_IP | SI_CSR_DMA_IP | SI_CSR_DMA_CONFLICT, 1)	           == 0) {		SC_ERROR("si: dma never completed\n");		si_dma_cleanup(sir, h_sip);		goto FAILED;	}	/* Check reason for dma completion */	if (sir->csr & SI_CSR_SBC_IP) {		/* Dma operation should done now. */		si_dma_cleanup(sir, h_sip);	} else {		DPRINTF("sidoit: ha error exit\n");		if (sir->csr & SI_CSR_DMA_CONFLICT) {			SC_ERROR("si: invalid reg access during dma\n");		} else if (sir->csr & SI_CSR_DMA_BUS_ERR) {				SC_ERROR("si: bus error during dma\n");		} else {			SC_ERROR("si: dma overrun\n");		}		si_dma_cleanup(sir, h_sip);		goto FAILED;	}	/* Handle special dma recv situations */	if (h_sip->dma_dir == SC_RECV_DATA) {		if (h_sip->ob) {			sir->udc_raddr = UDC_ADR_COUNT;			if (si_wait(&sir->csr, SI_CSR_FIFO_EMPTY, 1) == 0) {				SC_ERROR("si: fifo never emptied\n");				si_dma_cleanup(sir, h_sip);				goto FAILED;			}			/* If odd byte recv, must grab last byte by hand */			if ((h_sip->cc - sir->bcr) & 1) {				DPRINTF("si_dma_setup: lob 1\n");				cp = h_sip->ma + (h_sip->cc - sir->bcr) - 1;				*cp = (sir->fifo_data & 0xff00) >> 8;			/* Udc may not dma last word */			} else if (((sir->udc_rdata *2) - sir->bcr) == 2) {				DPRINTF("si_dma_setup: lob 2\n");				cp = h_sip->ma + (h_sip->cc - sir->bcr);				*(cp - 2) = (sir->fifo_data & 0xff00) >> 8;				*(cp - 1) = sir->fifo_data & 0x00ff;			}		} else if ((sir->csr & SI_CSR_LOB) != 0) {			cp = h_sip->ma + (h_sip->cc - sir->bcr);			if ((sir->csr & SI_CSR_BPCON) == 0) {			    switch (sir->csr & SI_CSR_LOB) {			    case SI_CSR_LOB_THREE:				    DPRINTF("si_dma_setup: lob 3\n");				    *(cp - 3) = (sir->bprh & 0xff00) >> 8;				    *(cp - 2) = (sir->bprh & 0x00ff);				    *(cp - 1) = (sir->bprl & 0xff00) >> 8;				    break;			    case SI_CSR_LOB_TWO:				    DPRINTF("si_dma_setup: lob 2\n");				    *(cp - 2) = (sir->bprh & 0xff00) >> 8;				    *(cp - 1) = (sir->bprh & 0x00ff);				    break;			    case SI_CSR_LOB_ONE:				    DPRINTF("si_dma_setup: lob 1\n");				    *(cp - 1) = (sir->bprh & 0xff00) >> 8;				    break;			    }			} else {				*(cp - 1) = (sir->bprl & 0xff00) >> 8;			}		}	}	/* Clear sbc interrupt */FAILED:	junk = SBC_RD.clr;	return;}static intsi_ob_dma_setup(sir, h_sip)	register struct scsi_si_reg *sir;	register struct host_saioreq *h_sip;{	register struct udc_table *udct;	register int dmaaddr;	udct = (struct udc_table *)(h_sip->dmaaddr); 	DPRINTF("si_ob_setup:\n");	/* Setup udc dma info */	dmaaddr = SI_OB_DMA_ADDR(h_sip->ma);	udct->haddr = ((dmaaddr & 0xff0000) >> 8) | UDC_ADDR_INFO;	udct->laddr = dmaaddr & 0xffff;	udct->hcmr = UDC_CMR_HIGH;	udct->count = h_sip->cc / 2;	if (h_sip->dma_dir == SC_RECV_DATA) {		DPRINTF("si_ob_setup: DMA receive\n");		udct->rsel = UDC_RSEL_RECV;		udct->lcmr = UDC_CMR_LRECV;	} else {		DPRINTF("si_ob_setup: DMA send\n");		udct->rsel = UDC_RSEL_SEND;		udct->lcmr = UDC_CMR_LSEND;		if (h_sip->cc & 1) {			udct->count++;		}	}	/* Initialize chain address register */	DELAY(SI_UDC_WAIT);	sir->udc_raddr = UDC_ADR_CAR_HIGH;	DELAY(SI_UDC_WAIT);	sir->udc_rdata = ((int)udct & 0xff0000) >> 8;	DELAY(SI_UDC_WAIT);	sir->udc_raddr = UDC_ADR_CAR_LOW;	DELAY(SI_UDC_WAIT);	sir->udc_rdata = (int)udct & 0xffff;	/* Initialize master mode register */	DELAY(SI_UDC_WAIT);	sir->udc_raddr = UDC_ADR_MODE;	DELAY(SI_UDC_WAIT);	sir->udc_rdata = UDC_MODE;	/* Issue start chain command */	DELAY(SI_UDC_WAIT);	sir->udc_raddr = UDC_ADR_COMMAND;	DELAY(SI_UDC_WAIT);	sir->udc_rdata = UDC_CMD_STRT_CHN;}/* * Reset some register information after a dma operation. */static intsi_dma_cleanup(sir, h_sip)	register struct scsi_si_reg *sir;	register struct host_saioreq *h_sip;{	DPRINTF("si_dma_cleanup:\n");	if (h_sip->ob) {		sir->udc_raddr = UDC_ADR_COMMAND;		DELAY(SI_UDC_WAIT);		sir->udc_rdata = UDC_CMD_RESET;	} else {		sir->csr &= ~SI_CSR_DMA_EN;		SET_DMA_ADDR(sir, 0);	}	SBC_WR.mr &= ~SBC_MR_DMA;	SBC_WR.icr = 0;	SBC_WR.tcr = TCR_UNSPECIFIED;}/* * Wait for a condition to be (de)asserted. */static intsi_wait(reg, cond, set)	register u_short *reg;	register u_short cond;	register int set;{	int i;	register u_short regval;	/* DPRINTF("si_wait:\n"); */	for (i = 0; i < SCSI_LONG_DELAY; i++) {		regval = *reg;		if ((set == 1) && (regval & cond)) {			return (1);		}		if ((set == 0) && !(regval & cond)) {			return (1);		} 		DELAY(10);	}	return (0);}/* * Wait for a condition to be (de)asserted on the scsi bus. */static intsi_sbc_wait(reg, cond, delay, set)	register caddr_t reg;	register u_char cond;	register int set;	int delay;{	register u_char regval;	int i;	/* DPRINTF("si_sbc_wait:\n"); */	for (i = 0; i < delay; i++) {		regval = *reg;		if ((set == 1) && (regval & cond)) {			return (1);		}		if ((set == 0) && !(regval & cond)) {			return (1);		} 		DELAY(10);	}	return (0);}/* * Put a byte onto the scsi bus. */static intsi_putbyte(sir, phase, data, num)	register struct scsi_si_reg *sir;	register u_short phase;	register u_char *data;	register u_char num;{	register int i;	register u_char icr;	DPRINTF("si_putbyte:\n");	/* Set up tcr so a phase match will occur */	sir->sbc_wreg.tcr = phase >> 2;	icr = SBC_WR.icr;	/* Put all desired bytes onto scsi bus */	for (i = 0; i < num; i++) {		SBC_WR.icr = icr | SBC_ICR_DATA; /* clear ack */		/* Wait for target to request a byte */		if (si_sbc_wait((caddr_t)&SBC_RD.cbsr, SBC_CBSR_REQ,			SCSI_SHORT_DELAY, 1) == 0) {			SC_ERROR1("si: REQ not active, cbsr 0x%x\n",				SBC_RD.cbsr);			return (0);		}		/* Load data for transfer */		SBC_WR.odr = *data++;		/* Complete req/ack handshake */		SBC_WR.icr |= SBC_ICR_ACK;		if (si_sbc_wait((caddr_t)&SBC_RD.cbsr, SBC_CBSR_REQ,			SCSI_SHORT_DELAY, 0) == 0) {			SC_ERROR("si: target never released REQ\n");			return (0);		}	}	SBC_WR.tcr = 0;	SBC_WR.icr = 0;	return (1);}/* * Get a byte from the scsi bus. */static intsi_getbyte(sir, phase)	register struct scsi_si_reg *sir;	u_short phase;{	u_char data;	DPRINTF("si_getbyte:\n");	/* Wait for target request */	if (si_sbc_wait((caddr_t)&SBC_RD.cbsr, SBC_CBSR_REQ,		SCSI_SHORT_DELAY, 1) == 0) {		SC_ERROR1("si: REQ not active, cbsr 0x%x\n",			SBC_RD.cbsr);		goto FAILED;	}	/* Check for correct phase on scsi bus */	if (phase != (SBC_RD.cbsr & CBSR_PHASE_BITS)) {		SC_ERROR1("si: wrong phase, cbsr 0x%x\n",			SBC_RD.cbsr);		goto FAILED;	}	/* Grab data */	data = SBC_RD.cdr;	SBC_WR.icr = SBC_ICR_ACK;	/* Complete req/ack handshake */	if (si_sbc_wait((caddr_t)&SBC_RD.cbsr, SBC_CBSR_REQ,		SCSI_SHORT_DELAY, 0) == 0) {		SC_ERROR("si: target never released REQ\n");		goto FAILED;	}	SBC_WR.tcr = 0;	SBC_WR.icr = 0;		/* Clear ack */	return (data);FAILED:	SBC_WR.tcr = 0;	SBC_WR.icr = 0;		/* Clear ack */	return (-1);}/* * Reset SCSI control logic. */static intsi_reset(h_sip, flag)	register struct host_saioreq *h_sip;	int flag;{	register struct scsi_si_reg *sir;	DPRINTF("si_reset:\n");	sir = (struct scsi_si_reg *) h_sip->devaddr;	/* Reset bcr, fifo, udc, and sbc */	sir->csr = 0;	DELAY(10);	sir->bcr = 0;	sir->csr = SI_CSR_SCSI_RES | SI_CSR_FIFO_RES;	if(h_sip->ob == 0) {		SET_DMA_ADDR(sir, 0);		SET_DMA_COUNT(sir, 0);	}	/* Issue scsi bus reset */	if (flag != SHORT_RESET) {		SBC_WR.icr = SBC_ICR_RST;		DELAY(100);		SBC_WR.icr = 0;		SBC_WR.tcr = 0;		SBC_WR.mr = 0;		junk = SBC_RD.clr;		DELAY(SCSI_RESET_DELAY);	/* Recovery time */	}}

⌨️ 快捷键说明

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