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

📄 mscp_subr.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
    }    return;}/**//* * *   Name:	mscp_message - Message input routine * *   Abstract:	 *		This routine handles end messages and attention *		messages arriving on a connection.  End messages are *		distinguished from attention messages by the presence *		of the end flag in the mscp opcode. * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */voidmscp_message( csp )    register CSB		*csp;{    register CONNB		*cp = ( CONNB * )csp->Aux;    register MSCP		*mp = ( MSCP * )csp->buf;    register REQB		*rp;    register u_short		index, seq_no;    /* If the message is an end message, interpret the command reference     * number as a RSPID and break it into its component parts.     */    if( mp->mscp_opcode & MSCP_OP_END ) {	index = (( RSPID * )&mp->mscp_cmd_ref )->index;	seq_no = (( RSPID * )&mp->mscp_cmd_ref )->seq_no;	/* If the RSPID index is out of range or the sequence number is not	 * current, deallocate the message without further processing.	 */	if(( index >= nrspid ) ||	   ( seq_no != mscp_rspid_tbl[ index ].rspid.seq_no )) {	    printf( "mscp_message: dropping msg:  mp %x, op %x, RSPID %x\n",		mp, mp->mscp_opcode, mp->mscp_cmd_ref );	    if( scs_dealloc_msg( csp ) != RET_SUCCESS )		panic( "mscp_message: scs_dealloc_msg failed\n" );	    return;	} else {	    /* If the RSPID represents the oldest command outstanding in	     * the controller, clear the oldest command field in the	     * connection block to let connection management know that work	     * is progressing.	     */	    if( mp->mscp_cmd_ref == *( u_long * )&cp->old_rspid )		*( u_long * )&cp->old_rspid = NULL;	    /* Get the request block pointer that corresponds to the RSPID,	     * remove the request block from the connection active queue,	     * store the MSCP message buffer address and size in the REQB,	     * and call back the thread that was waiting for message completion.	     */	    rp = mscp_rspid_tbl[ index ].reqb;	    if( mp->mscp_cmd_ref != *( u_long * )&rp->rspid ) {		printf( "mscp_message: end msg rspid %x != rp rspid %x\n",		    mp->mscp_cmd_ref, *( u_long * )&rp->rspid );		panic( "mscp_message: invalid rspid\n");	    }	    Remove_entry( rp->flink );	    rp->flink = NULL;	    rp->blink = NULL;	    rp->msgptr = mp;	    rp->msgsize = csp->size;	    mscp_dispatch( EV_ENDMSG, rp );	}    /* The message is not an end message.  Treat it as an attention message     * and dispatch on MSCP opcode.     */    } else {	switch( mp->mscp_opcode ) {	    default:		printf( "mscp_message:  unknown attention message 0x%2x\n",			mp->mscp_opcode );	    case MSCP_OP_AVATN:		mscp_avail_attn( csp );	    case MSCP_OP_DUPUN:	    case MSCP_OP_ACPTH:		if( scs_dealloc_msg( csp ) != RET_SUCCESS )		    panic( "mscp_message: scs_dealloc_msg failed\n" );	}    }    return;}/**//* * *   Name:	mscp_avail_attn- Process available attention messages * *   Abstract:	 * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */voidmscp_avail_attn( csp )    register CSB		*csp;{    register CONNB		*cp = ( CONNB * )csp->Aux;    register MSCP		*mp = ( MSCP * )csp->buf;    UNITB			*up;    up = mscp_get_unitb( cp, mp, csp->size );}/**//* * *   Name:	mscp_datagram - Datagram input routine * *   Abstract:	 *		This routine handles error logging datagrams. * *   Inputs: * *   Outputs: * * *   Return	NONE *   Values: */voidmscp_datagram( csp )    CSB			*csp;{	register CONNB *cp = (CONNB *)csp->Aux;	register MSLG *mp = (MSLG *)csp->buf;	register REQB *rp = &cp->bbrb->bbr_reqb; /* bbr request cmd */	register MSLG *bbrmp = &cp->bbrb->bbr_mslg; /* bbr mslg */	void mscp_logerr();		/* error durning bbr cmd - log via bbr code */	if ((cp->bbrb != 0) && (cp->bbrb->flags.bit.busy == 1) &&	    (mp->mslg_cmd_ref == *(u_long *)&rp->rspid)) {	    if (cp->bbrb->flags.bit.logerr == 0) {		     *(bbrmp) = *(mp);	    }	}	else {	    mscp_logerr( cp, mp , csp->size);	}        csp->Nbufs = 0;        scs_queue_dgs( csp );        return;}/**//* *   Name:	mscp_logerr - mscp log error routine * *   Abstract:	 *		This routine logs datagram error packets to the system *		error log. * *   Inputs:	cp - connection pointer *		mp - mslg packet pointer *		size - mslg packet size * *   Outputs: * * *   Return	NONE *   Values: */ voidmscp_logerr( cp, mp, size)    CONNB	*cp;    MSLG	*mp;    long	size;{	register struct	el_rec	*elp;	int	class, type, devtype, unitnum, subidnum;	if ((elp = ealloc((sizeof(struct el_bdev)), EL_PRIHIGH)) == EL_FULL)		return;	switch (mp->mslg_format) {	case MSLG_FM_CNT_ER:	case MSLG_FM_BUS_ADDR:		class = ELCT_DCNTL;	    /* Device controller class	*/		if (mp->mslg_cnt_id[7] == 3)		    type = ELTMSCP_CNTRL;   /* TMSCP controller type 	*/		else		    type = ELMSCP_CNTRL;    /* MSCP controller type 	*/		unitnum = cp->cnt_number;    /* Controller number	*/		devtype = mp->mslg_cnt_id[6] & 0xFF;		/* Need to find  adpt or bus # from ? */		subidnum = EL_UNDEF; 	   /* adpt or bus controller #	*/		break;	case MSLG_FM_DISK_TRN:	case MSLG_FM_SDI:	case MSLG_FM_SML_DSK:	case MSLG_FM_REPLACE:		class = ELCT_DISK;		/* Disk class		*/		type = ELDEV_MSCP;		/* MSCP disk type	*/		devtype = (mp->mslg_unit_id[1] >> 16) & 0xFF;		unitnum = mp->mslg_unit;	/* Unit number		*/		subidnum = cp->cnt_number;      /* Controller number	*/		break;	case MSLG_FM_TAPE_TRN:	case MSLG_FM_STI_ERR:	case MSLG_FM_STI_DEL:	case MSLG_FM_STI_FEL:	case MSLG_FM_IBMSENSE:		class = ELCT_TAPE;		/* Disk class		*/		type = ELDEV_MSCP;		/* MSCP disk type	*/		devtype = (mp->mslg_unit_id[1] >> 16) & 0xFF;		unitnum = mp->mslg_unit;	/* Unit number		*/		subidnum = cp->cnt_number;      /* Controller number	*/		break;	default:		class = EL_UNDEF;		/* Unknown		*/		type = EL_UNDEF;		/* Unknown		*/		devtype = EL_UNDEF;		/* Unknown		*/		unitnum = EL_UNDEF;		/* Unknown		*/		subidnum = EL_UNDEF;		/* Unknown		*/		break;	}	LSUBID(elp, class, type, devtype, subidnum, unitnum, 		  (u_long)mp->mslg_format)	/* What should go in here?   */	elp->el_body.elbdev.eldevhdr.devhdr_dev = EL_UNDEF;	elp->el_body.elbdev.eldevhdr.devhdr_flags = EL_UNDEF;	elp->el_body.elbdev.eldevhdr.devhdr_bcount = EL_UNDEF;	elp->el_body.elbdev.eldevhdr.devhdr_blkno = EL_UNDEF;	elp->el_body.elbdev.eldevhdr.devhdr_retrycnt = EL_UNDEF;	elp->el_body.elbdev.eldevhdr.devhdr_herrcnt = EL_UNDEF;	elp->el_body.elbdev.eldevhdr.devhdr_serrcnt = EL_UNDEF;	elp->el_body.elbdev.eldevhdr.devhdr_csr = EL_UNDEF;	elp->el_body.elbdev.eldevdata.elmslg.mslg_len = size;	elp->el_body.elbdev.eldevdata.elmslg.mscp_mslg = *(mp);	EVALID(elp);}/**//* * *   Name:	mscp_alloc_rspid - Allocate a Response ID * *   Abstract:	Allocate a Response ID (RSPID) for use as a command *		reference number.  If there are no RSPIDs available, *		insert the REQB onto the tail of the RSPID wait queue. * *   Inputs:	rp			Request block pointer *		    connb		Connection block pointer *			classb		Class block pointer * *   Outputs:   rp *		    rspid		The allocated RSPID * * *   Return	NONE *   Values: *//* ** TO DO ** Put the RSPID table or a pointer to it in the CLASSB * so that it doesn't have to be referenced as a global variable. */u_longmscp_alloc_rspid( event, rp )    u_long		event;    register REQB	*rp;{    register RSPID_TBL	*rtp;    register u_long	new_event = EV_RSPID;     /* ** TEMP **  Panic if this reqb already has a RSPID.     */    if( *( u_long * )&rp->rspid ) {	printf(" rp %x has non-zero RSPID %x\n", rp, rp->rspid );	panic( "mscp_alloc_rspid: double RSPID allocation\n" );    }    /* If the RSPID wait queue is empty and there is an available RSPID,     * store the REQB address in the RSPID table and copy the RSPID from     * the RSPID table into the REQB.     */    if(( mscp_rspid_wait_lh.flink == ( QE * )&mscp_rspid_wait_lh.flink ) &&       ((rtp = (RSPID_TBL *)mscp_rspid_lh.flink) != 	( RSPID_TBL *)&mscp_rspid_lh )) {	    Remove_entry( rtp->flink );	    rtp->reqb = rp;	    rp->rspid = rtp->rspid;    /* If the wait queue is not empty or there are no available RSPIDs,     * thread the REQB into the RSPID wait queue and bump the wait count     * to stall requests on the unit.     */    } else {	Insert_entry( rp->flink, mscp_rspid_wait_lh );	Incr_rwait( rp );	rspid_wq_cnt++;	new_event = EV_NULL;    }        return( new_event );}/**//* * *   Name:	mscp_recycle_rspid - Recycle a Response ID * *   Abstract:	Recycle a response ID by updating its sequence number *		field.  Recycling has no effect on threads in the RSPID *		wait queue. * *   Inputs:	rp			Request block pointer *		    rspid		RSPID *		rtp			RSPID table pointer *		    rspid		RSPID * *   Outputs:	rp			Request block pointer *		    rspid		Updated RSPID. * * *   Return	NONE *   Values: */voidmscp_recycle_rspid( rp )    register REQB	*rp;{    register RSPID_TBL	*rtp;    /* Locate the RSPID table entry that corresponds to the input RSPID.     */    rtp = &mscp_rspid_tbl[ rp->rspid.index ];     /* If the sequence numbers don't agree, something has been corrupted.     * Panic.     */    if( rtp->rspid.seq_no != rp->rspid.seq_no)	panic( "mscp_recycle_rspid - sequence number error.\n" );    /* Update the sequence number and copy the RSPID into the REQB.     */    else {	if( ++rtp->rspid.seq_no == 0 )	   ++rtp->rspid.seq_no;	rp->rspid = rtp->rspid;	return;    }}/**//* * *   Name:	mscp_dealloc_rspid	- deallocate Response ID * *   Abstract:	Return a RSPID entry to the free queue and activate *		the first thread on the RSPID wait queue, if any. * *   Inputs:	rp			Request block pointer *		    rspid		Response ID *		rtp			RSPID table pointer *		    rspid		Response ID *		    flink		Forward link * *   Outputs: * * *   Return	NONE *   Values: */voidmscp_dealloc_rspid( rp )    register REQB	*rp;{    register RSPID_TBL	*rtp;    register REQB	*wrp;    register CLASSB	*clp = rp->classb;    /* Locate the RSPID table entry that corresponds to the input RSPID.     */    rtp = &mscp_rspid_tbl[ rp->rspid.index ];     /* If the sequence numbers don't agree, something has been corrupted.     * Panic.     */    if( rtp->rspid.seq_no != rp->rspid.seq_no) {	printf("mscp_dealloc_rspid: error rtp->rspid %x, rp->rspid %x\n",	    *( u_long * )&rtp->rspid, *( u_long * )&rp->rspid);	panic( "mscp_dealloc_rspid:  sequence number mismatch\n" );    /* Update the sequence number in the RSPID table and zero the     * RSPID field in the request block as a safety precaution.     */    } else {	if( ++rtp->rspid.seq_no == 0 )	    ++rtp->rspid.seq_no;	rp->rspid.index = 0;	rp->rspid.seq_no = 0;	/* If there is a request block waiting for a RSPID, do the	 * required bookkeeping and dispatch the waiting thread.	 */        if(( wrp = (REQB *)mscp_rspid_wait_lh.flink ) != (REQB *)&mscp_rspid_wait_lh ) {            Remove_entry( wrp->flink );	    rtp->reqb = wrp;	    wrp->rspid = rtp->rspid;	    mscp_dispatch( EV_RSPID, wrp );	    Decr_rwait( wrp );	/* No waiters.  Clear the request block pointer in the RSPID	 * table and put the deallocated entry in the free list.	 */	} else {	    rtp->reqb = NULL;	    Insert_entry( rtp->flink, mscp_rspid_lh );	}	return;    }}/**//* * *   Name:	mscp_alloc_msg - Allocate a sequenced message buffer * *   Abstract:	Allocate a sequenced message buffer via SCS.  If *		the allocation fails because of a shortage of *		buffers, insert the REQB on the buffer wait queue. *		If the allocation fails for any other reason, panic.

⌨️ 快捷键说明

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