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

📄 bvp_subr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
PCCB	*pccb;u_long	queno;{struct	bvpregs	*bvrg;u_long		cmd_pend, cmd_off;	switch ( queno ) {	case MFREEQ:		Pccb.cmd_pend |= M_freeq;		break;	case DFREEQ:		Pccb.cmd_pend |= D_freeq;		break;	case CMDQ0:		Pccb.cmd_pend |= C_cmdq_0;		break;	case CMDQ1:		Pccb.cmd_pend |= C_cmdq_1;		break;	case CMDQ2:		Pccb.cmd_pend |= C_cmdq_2;		break;	case CMDQ3:		Pccb.cmd_pend |= C_cmdq_3;		break;	default:		panic("bvp_qtrans: Invalid queue\n");	}	bvrg = Pccb.port_regs;	if (bvrg->bvp_pc & BVP_PC_OWN)  { /* We don't own it	*/		return;	}			cmd_off = ffs(Pccb.cmd_pend);	cmd_off--;			/* Get bit position	*/	bvrg->bvp_pc = bvp_cmd[cmd_off].command; /* Issue command	*/	WBFLUSH	Pccb.cmd_pend &= ~(1<<cmd_off);}/**//* * * *	Name:		bvp_timer *	 *	Abstract:	 *			 *	Inputs: * *	 *	 *	 * *	Outputs: * *	 *	 *	 * *	Return  *	Values: * *	 *	 *  *	Side		 *	Effects: * */void	bvp_timer( pccb )PCCB	*pccb;{struct	bvpregs	*bvrg;u_long		cmd_pend, cmd_off;	bvrg = Pccb.port_regs;		/* Port regs address		*/	if ( Pccb.cmd_pend != 0 ) {	/* Have commands pending	*/		if ( (bvrg->bvp_pc & BVP_PC_OWN) == 0){  /* We own it	*/		     cmd_off = ffs(Pccb.cmd_pend);		     cmd_off--;			/* Get bit position	*/		     bvrg->bvp_pc = bvp_cmd[cmd_off].command; /* Issue command */		     WBFLUSH		     Pccb.cmd_pend &= ~(1<<cmd_off);		}	}	timeout(bvp_timer,pccb,Pccb.poll_rate); /* Requeue timeout	*/}/**//* * * *	Name:		bvp_log_err *	 *	Abstract:	Log BVP port errors *			 *	Inputs: * *	pccb	-	Pointer to pccb for port *	 *	 * *	Outputs: * *	 *	 *	 * *	Return  *	Values: * *	 *	 *  *	Side		 *	Effects:	Error is logged. * */void	bvp_log_error(pccb)PCCB	*pccb;{struct	bvpregs	*bvrg;register struct el_rec *elrp;register struct el_bvp *elbod;int	i,unit;u_char	type;	bvrg = Pccb.port_regs;	cprintf("Port error: bvp_ps = %x\n", bvrg->bvp_ps);	cprintf("            bvp_pe = %x\n", bvrg->bvp_pe);	cprintf("            bvp_pd = %x\n", bvrg->bvp_pd);	for (i = 0; i < nbvptypes; i++) {		if (bvp_sw[i].type == Lpinfo.bvp_type)			break;	}	if (i == nbvptypes) {	/* Not found in BVP switch table		*/		panic("bvp_log_err: Invalid port type");	}	if( (elrp = ealloc( (sizeof(struct el_bvp)), EL_PRIHIGH)) == EL_FULL)		return;	elbod = &elrp->el_body.elbvp;	elbod->bvp_biic_typ = Pccb.nxv->biic_typ;	elbod->bvp_biic_csr = Pccb.nxv->biic_ctrl;	elbod->bvp_pcntl = bvrg->bvp_pc;	elbod->bvp_pstatus = bvrg->bvp_ps;	elbod->bvp_perr = bvrg->bvp_pe;	elbod->bvp_pdata = bvrg->bvp_pd;	LSUBID(elrp,ELCT_DCNTL,ELBI_BVP,bvp_sw[i].errlog_typ,		Pccb.binode,Pccb.bvp_ctlr,bvrg->bvp_pe);	EVALID(elrp);}/**//* * * *	Name:		bvp_port_error *	 *	Abstract:	Take action on port error. *			 *	Inputs: * *	pccb	-	Pointer to pccb for port in error *	 *	 * *	Outputs: * *	 *	 *	 * *	Return  *	Values: * *	 *	 *  *	Side		 *	Effects: * */u_long	bvp_port_error(pccb)PCCB	*pccb;{struct	bvpregs	*bvrg;u_long		errcode;	bvrg = Pccb.port_regs;	errcode = bvrg->bvp_ps & BVP_PS_ETYPE;	switch( errcode ) {	/*	 * 	Port operation continues	 */	case	BVP_ETYPE_TBI:	case	BVP_ETYPE_EXC:	case	BVP_ETYPE_NFBI:		return( RET_SUCCESS );		break;	/*	 * 	This port is shutdown	 */	case	BVP_ETYPE_FBI:	case	BVP_ETYPE_DSE:	case	BVP_ETYPE_PLE:		bvp_disable( pccb, PF_PORTERROR );		return( RET_FAILURE );		break;	/*	 *	All ports are shutdown	 */	case	BVP_ETYPE_AHE:		bvp_disable( pccb, PF_PORTERROR );		return( RET_FAILURE );		break;	default:		break;	}}/**//* * * *	Name:		bvp_reinit *	 *	Abstract:	 *			 *	Inputs: * *	 *	 *	 * *	Outputs: * *	 *	 *	 * *	Return  *	Values: * *	 *	 *  *	Side		 *	Effects: * */void	bvp_reinit( pccb )PCCB	*pccb;{struct	bvpregs		*bvrg;u_long	devtype;u_long	bvp_status;int	i,j,s,count;	s = Splscs();	/*  Raise IPL to SCS level	 */	Pccb.rip = 0;	bvrg = Pccb.port_regs;	bvp_init_blks( pccb );	/* Init  PQB and PCCB	 */	if (bvp_init_port( pccb ) != RET_SUCCESS) {		(void)splx(s);		/* Lower IPL		*/		return;		/* Init failed or no such port	 */	}/* *	Issue port Enable instruction */	bvrg->bvp_pc = BVP_PC_OWN | BVP_CMD_ENAB; /* Enable the port	 */	WBFLUSH	Wait_own_nr( bvrg )		/* Wait for PC own bit to reset	*/	bvp_status = bvrg->bvp_ps;	if ( (bvp_status & BVP_PS_PST) != BVP_PSTATE_ENAB ) {		(void)splx(s);		/* Lower IPL		 */		return;	}	bvrg->bvp_ps = bvp_status & ~BVP_PS_OWN; /* Clear ownership bit	*/	WBFLUSH/* *	Issue Read PIV instruction to turn on interrupts */	Bvpqb.piv = Pccb.ivec;	/* Set in interrupt vector		 */	bvrg->bvp_pc = BVP_PC_OWN | BVP_CMD_RPIV; /* Read PIV command	 */	WBFLUSH	Wait_own_nr( bvrg )		/* Wait for PC own bit to reset	*/	if (bvp_create_sys( pccb ) != RET_SUCCESS) {		(void)splx(s);		/* Lower IPL		 */		return;		/* Failed to make system known	 */	}	if(Pccb.poll_rate == 0) 	/* Set the rate for the polling	*/		Pccb.poll_rate = 2 * hz;/*									*//*	Start the timer running. The bvp_timer routine will check	*//*	for pending port commands and issuing one if possible.		*//*									*/	if ( (Lpinfo.bvp_flags & BVP_TIM) == 0 ) { /* If timer not yet on */		Lpinfo.bvp_flags |= BVP_TIM; /* Indicate timer now on	*/		timeout(bvp_timer,pccb,Pccb.poll_rate); /* Start timer	*/	}	(void)splx(s);		/* Lower IPL			 */	return;}/**//* * * *	Name:		bvp_disable *	 *	Abstract:	 *			 *	Inputs: * *	 *	 *	 * *	Outputs: * *	 *	 *	 * *	Return  *	Values: * *	 *	 *  *	Side		 *	Effects: * */void	bvp_disable( pccb, reason  )PCCB	*pccb;u_long	reason;{PB			*pb;int			s, lock;struct	bvpregs		*bvrg;u_long			bvp_status;int			count;	if (Pccb.rip == 0) {	/* If recovery not already in progress  */	     Pccb.rip = 1;		/* Set recovery in progress	*/	    /*	Mark path as failed	     */	     if( (pb = Pccb.pb) != (PB *)NULL ) {		pb->pinfo.state = PS_PATH_FAILURE;		pb->pinfo.reason = reason;	     }	     bvrg = Pccb.port_regs;	     bvp_status = bvrg->bvp_ps;	    /* 	Attempt graceful shutdown first.	     */	     count = 0;	     if ( (( bvp_status & BVP_PS_OWN ) == 0) &&			((bvp_status & BVP_PS_PST) == BVP_PSTATE_ENAB) ) {		bvrg->bvp_pc = BVP_PC_OWN | BVP_CMD_SHUT; /* Issue Shutdown cmd  */		WBFLUSH		while ( count < DELAYONE ) {	/* Wait for at most 1 second	*/		    if ( ( bvrg->bvp_pc & BVP_PC_OWN) == 0 ) 			break;		    DELAY(200000)		    count = count + 1;		}	     }		     if ( ( count == DELAYONE ) || 			((bvp_status & BVP_PS_PST) != BVP_PSTATE_ENAB) ) {		s = spl7();		if(Pccb.bidata->biinfo[Pccb.binode].lock == 0) {			Pccb.bidata->biinfo[Pccb.binode].lock = 1; /* Set lock */		}		else {			/* Wait for unlock ?? */		}		(void)splx(s);		if( Pccb.bidata->biinfo[Pccb.binode].incarn ==			Pccb.incarn ) {			(void)bisst(&Pccb.nxv->biic_ctrl);			Pccb.bidata->biinfo[Pccb.binode].incarn++;		}		Pccb.incarn = Pccb.bidata->biinfo[Pccb.binode].incarn;		s = spl7();		Pccb.bidata->biinfo[Pccb.binode].lock = 0;		(void)splx(s);	    }			     if ( (Lpinfo.bvp_flags & BVP_TIM) != 0) { /* Turn off timer if on */		(void)untimeout(bvp_timer, pccb);		Lpinfo.bvp_flags &= ~BVP_TIM; /* Timer now off		*/	     }	     Kfork(&pccb->forkb, bvp_cleanup, pccb )	}	return;				/* If already forking then	*/					/* forget this request.		*/}/**//* * * *	Name:		bvp_cleanup *	 *	Abstract:	 *			 *	Inputs: * *	 *	 *	 * *	Outputs: * *	 *	 *	 * *	Return  *	Values: * *	 *	 *  *	Side		 *	Effects: * */void bvp_cleanup( pccb )PCCB	*pccb;{PB			*pb;int			s = Splscs();	bvp_proc_rsp( pccb ); 	/* Return remaining responses		*/	/* Remove and deallocate all packets on all port queues.  	 * The queue is zeroed whenever the queue interlock can not 	 * be obtained. This results in permanent loss of the entries 	 * that had been on that queue.	 */	{	register gvpbq	*q, *qend;	for( q = &Vpqb.cmdq0, qend = &Vpqb.rspq; q <= qend; ++q )	    Flushq( pccb, q )	for( q = &Pccb.dfreeq, qend = &Pccb.mfreeq; q <= qend; ++q )	    Flushq( pccb, q )	}	if ( (pb = Pccb.pb) != (PB *)NULL )	/* If we have a path open */		scs_path_crash( Pccb.pb );	 /* Notify SCS	*/	else	    Kfork(&pccb->forkb, bvp_reinit, pccb )	splx(s);	return;			/* Return from fork		*/}/**//* * * *	Name:		bvp_log_packet *	 *	Abstract:	 *			 *	Inputs: * *	 *	 *	 * *	Outputs: * *	 *	 *	 * *	Return  *	Values: * *	 *	 *  *	Side		 *	Effects: * */void	bvp_log_packet( pccb, pb, bvpppdbp, reason)PCCB	*pccb;PB	*pb;GVPPPDH	*bvpppdbp;int	reason;{}/**//* * * *	Name:		bvp_slave *	 *	Abstract:	This routine simply returns 0 indicating the drive *			is offline. The class driver will configure the *			drive on its own. *			 *	Inputs: * *	ui		- Pointer to unibus device structure *	nxv		- Base address of controller *	 *	 * *	Outputs: * *	 *	 *	 * *	Return  *	Values:		0 * *	 *	 *  *	Side		 *	Effects: * */bvp_slave( ui, nxv )struct	uba_device	*ui;struct	bi_nodespace	*nxv;{	return(0);}

⌨️ 快捷键说明

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