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

📄 if_scs.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
	    if ((status = scs_map_buf(csb)) != RET_SUCCESS) {			printf("scsnet: could not map recv buffer\n");	        	bp->state = SCSNET_BDONE;				goto bad;	    }	    /*	     * Save info for Block Done event.  When the block transfer	     * completes we will need the protocol header in the csb	     * buffer and we will need the pointer to the rest of data (m).	     * The local block handle (lbhandle) is needed to	     * unmap the block when we are finished with it.	     * We also save the buffer to use for an ACK later on.	     */	    Move_bhandle(csb->lbhandle, bp->csb.lbhandle)	    bp->csb.buf = csb->buf;	      	    bp->mchain = m;				    /*	     * Start up the block transfer	     */	    Move_bhandle(msg->bhandle, csb->rbhandle)	    csb->Rboff = msg->off;	    csb->Lboff = 0;	    csb->size = msg->totlen;	    if ((status=scs_req_data(csb))!=RET_SUCCESS){		if (scsnetdebug)		    printf("scsnet: req_data failed , status= %x\n",status);		if ((status = scs_unmap_buf(csb) != RET_SUCCESS))			printf("scsnet0: unmap failed, status=%d\n",				status);	        bp->state = SCSNET_BDONE;			goto bad;	    }	    bp->csb.Aux = csb->Aux;  /* save address of netsystem structure */	    return;bad:	    if (m)	        m_freem(m);	    msg->cmd = SCSNET_BCMD_NACK;	    csb->size = Scsnet_msg_hdr_siz;	    csb->Disposal = RECEIVE_BUF;	    if (bp)	    	bp->mchain = 0;				    if ((status=scs_send_msg(csb)) != RET_SUCCESS)		printf("scsnet: send nack failed, status = %d\n", status);	    return;	} else	if (msg->cmd == SCSNET_BCMD_ACK || msg->cmd == SCSNET_BCMD_NACK) {	    /*	     * acknowledgement.	     * free mbuf chain.	     */	    register struct scsnet_cntl *scscp = scsnet_xfers + msg->rspid; #ifdef notdef	    register struct pte *topte = &scsmemptmap[scscp->xpte];	    register caddr_t tova = (caddr_t) scsxtob(scscp->xpte);	    register int i;#endif				    if (scscp->state & SCSNET_BDONE) {		panic("scsnet: block transfer dup"); 	    }	    if (scscp->mchain)	    	m_freem(scscp->mchain);	    scscp->mchain = 0;#ifdef mips	    /*	     * unmap buffer for mips only	     */	    if ((status = scs_unmap_buf(&scscp->csb)) != RET_SUCCESS) 		printf("scsnet: could not unmap xmit buffer, status %x, %x\n",			status, scscp);#endif		    /* 	     * reuse msg buffer for next xmit	     */	    scscp->csb.buf = csb->buf;#ifdef notdef	    /*	     * invalidate pte's and buffer cache entries	     */	    for(i=0; i<scscp->clbuf_len; i += NBPG) {			*topte++ = zeropte;			Tbis(tova);			tova += NBPG;	    }#endif	    if (scscp->clbuf_t) {		KM_FREE(scscp->clbuf_t, KM_DEVBUF);	    	scscp->clbuf_t = 0;	    }	    scscp->state = SCSNET_BDONE;	    /*	     * Since we have freed up one output buffer we can check	     * for a pending transmission and send it.	     */	    smp_lock(&scsnetif.if_snd.lk_ifqueue, LK_RETRY);	    IF_DEQUEUE(&scsnetif.if_snd, m)	    smp_unlock(&scsnetif.if_snd.lk_ifqueue);	    if (m == 0) 		return;	    scsnet_output(&scsnetif, m->m_next, mtod(m, struct sockaddr *));	    m_free(m); /* only free temp header - the rest of the chain will			* free up elsewhere.			*/ 	    return;	} else 	    printf("scsnet: received invalid message\n", msg->cmd);			}/* * scsnet_add_sys() - add system to list of known systems.  First *	check to see if inet address is valid. * Inputs: *	rmthost - host number of system to add. *	sys - netsystem structure that contains connection info. *	ASSUME: sys is smp locked. *		IPL_SCS  *	cmsb - contains connid. * Outputs: *	updated knownsystems list. *	initialized block transfer structures; * Return value: *	RET_SUCCESS - ok. *	RET_FAILURE - invalid inet address.  */intscsnet_add_sys(rmthost, sys, cmsb)	register int rmthost;	struct _netsystem *sys;	CMSB *cmsb;{	register struct scsnet_cntl *scscp;	register int firstpte, i;	int status;	if (scsnetdebug)		printf("scsnet_add_sys: rmthost=%d\n", rmthost);	/* check validity of inet address */	if (rmthost>=SCSNET_MAXHOSTS || rmthost<0) {		printf("scs_net: can not add invalid host %d\n", rmthost);		return(RET_FAILURE);	}	smp_lock(&lk_scsnetknownsys, LK_RETRY);	if (knownsystems[rmthost] != SCSNET_NO_SYS)  	    if (rmthost == scsnet_lhost) {		/* we already have connection info for the localhost */		sys->status = SCSNET_CONN_CLOSED;		sys->retries = 0;		Move_scaaddr( scsnet_nosysid, sys->sys_info.sysid)		smp_unlock(&lk_scsnetknownsys);		return(RET_SUCCESS);	    }	    else		{		mprintf("scsnet: conn already exists to %d, state = %x\n", 			rmthost, knownsystems[rmthost]->status);		smp_unlock(&lk_scsnetknownsys);		return(RET_FAILURE);	    }        Insert_entry( sys->flink, netsys_head );	/* initialize block transfer buffers */	scscp = scsnet_xfers + rmthost*SCSNET_XFERS;	firstpte = rmthost*SCSNET_XFERS*(SCSNET_XFER_SIZ+1); /* +1 for offset */	for (i=0; i<SCSNET_XFERS; i++, scscp++) {		scscp->xindex = i;		scscp->xpte = firstpte + i*(SCSNET_XFER_SIZ+1);		scscp->bufhdr.b_un.b_addr = (char *)scsxtob(scscp->xpte);		scscp->bufhdr.b_bcount = (SCSNET_XFER_SIZ+1) * NBPG;		scscp->bufhdr.b_flags = 0;		scscp->csb.Sbh = &scscp->bufhdr;		scscp->netsys = sys;		Move_connid( cmsb->connid, scscp->csb.connid )#ifdef vax		if ((status = scs_map_buf(&scscp->csb)) != RET_SUCCESS) {			printf("scsnet: could not map vax xmit buffer, status %x\n",				status);			knownsystems[rmthost] = SCSNET_NO_SYS;			smp_unlock(&lk_scsnetknownsys);			return(RET_FAILURE);		}#endif		scscp->state = SCSNET_BDONE;	        /*	         * allocate a msg buffer and save it for the acknowledgement 	         * We may want to preallocate our buffers to save time 	         */	        if ((status = scs_alloc_msg(&scscp->csb)) != RET_SUCCESS) {	            printf("scsnet add: no free seq msgs for host= %d\n", 			rmthost);		    knownsystems[rmthost] = SCSNET_NO_SYS;		    smp_unlock(&lk_scsnetknownsys);	            return(RET_FAILURE);	        }	}    	Move_scaaddr( cmsb->rport_addr, sys->msb.rport_addr )	sys->msb.lport_name = cmsb->lport_name;	Move_name( SYSAP_NET, sys->msb.Lproc_name )	Move_scaaddr( cmsb->sysid, sys->sys_info.sysid)	sys->connid = cmsb->connid;	sys->rmt_index = rmthost;	sys->status = SCSNET_CONN_OPEN;	knownsystems[rmthost] = sys;	smp_unlock(&lk_scsnetknownsys);	return(RET_SUCCESS);}/* * scsnet_rem_sys:  remove system from known system data base and deallocate *	any resources reserved for communication with that system * * Inputs:    *	sys - for system identication.  *	ASSUME - sys is smp locked. *		 IPL_SCS *	cmsb - for connection identification. * * Outputs: *	knownsystems *	scsnet_xmits *	scsnet_recvs * * Return Value: *	RET_FAILURE - invalid system id *	RET_SUCCESS  *	 */scsnet_rem_sys(sys, cmsb)	register struct _netsystem *sys;	register CMSB *cmsb;{	register int rmthost = sys->rmt_index;	register struct scsnet_cntl *scscp;	register int firstpte, i;	int status;	if (scsnetdebug)	    printf("scsnet_rem_sys: rmthost=%d, status=%d\n", rmthost, sys->status);	if (sys->status != SCSNET_CONN_OPEN) {		sys->status = SCSNET_CONN_CLOSED;		sys->retries = 0;		sys->rmt_index = SCSNET_NO_INDEX;		Move_scaaddr( scsnet_nosysid, sys->sys_info.sysid)		return(RET_SUCCESS);	}		/*	 * check validity of inet address 	 */	if (rmthost>=SCSNET_MAXHOSTS || rmthost<0) {		printf("scsnet_rem_sys: invalid host %d\n", rmthost);		return(RET_FAILURE);	}	smp_lock(&lk_scsnetknownsys, LK_RETRY);	Remove_entry( sys->flink);	knownsystems[rmthost] = SCSNET_NO_SYS;	/*	 * unmap all xmit blocks dedicated to remote host	 */	scscp = scsnet_xfers + rmthost*SCSNET_XFERS;	for (i=0; i<SCSNET_XFERS; i++, scscp++) {	    if (scscp->state&SCSNET_BDONE)	        if ((status=scs_dealloc_msg(&scscp->csb)) != RET_SUCCESS)		    printf("scsnet: dealloc0 failed, status = %x\n", status);#ifdef vax	    if ((status = scs_unmap_buf(&scscp->csb)) != RET_SUCCESS) 		printf("scsnet: could not unmap xmit buffer, status %x, %x\n",			status, scscp);#endif	    if (scscp->clbuf_t)		KM_FREE(scscp->clbuf_t, KM_DEVBUF);	    if (scscp->mchain) {		m_freem(scscp->mchain);		scscp->mchain = 0;	    }	    scscp->clbuf_t = 0;	    scscp->state = SCSNET_BDONE;	    scscp->timer = 0;	}	/*	 * look for block transfer requests that were in progress and	 * clean them up.   	 * Note the aux/Aux field of the CMSB and the CSB respectively	 * contain the address of the netsystem structure dedicated to	 * a connection.	 */	for (scscp=scsnet_recvs; scscp < &scsnet_recvs[SCSNET_RECVS]; scscp++){		if ((scscp->state&SCSNET_BDONE)==0 &&		   (cmsb->aux == scscp->csb.Aux) ) {		    /* 		     * The assumption is made that a disconnect is not		     * sent while a block transfer is in progress.		     * The only way to get here is with a path failure.		     */		    if (scsnetdebug)			printf("scsnet: unmapping recv buffer\n");	    	    if ((status = scs_unmap_buf(&scscp->csb)) != RET_SUCCESS) 			printf("scsnet: could not unmap recv buffer, status %x, %x\n",			status, scscp);		    scscp->state = SCSNET_BDONE;		    scscp->timer = 0;		    scscp->csb.Aux = 0;		    if (scscp->mchain) {			m_freem(scscp->mchain);		    	scscp->mchain = 0;		    }	            if ((status=scs_dealloc_msg(&scscp->csb)) != RET_SUCCESS)		        printf("scsnet: dealloc2 failed, status = %x\n", status);		}	}	sys->status = SCSNET_CONN_CLOSED;	sys->retries = 0;	Move_scaaddr( scsnet_nosysid, sys->sys_info.sysid)		smp_unlock(&lk_scsnetknownsys);	return(RET_SUCCESS);}/* scsnet_connect  -  start a connection to a remote node. *  * Inputs:  * 	netsystem - system status information. *	ASSUME: netsystem is smp locked. *	scs_inet_addr - internet address of local host *	scsnetif - network interface information *	isb - ISB * Outputs: *	netsystem - connection status * Return Values: *	RET_SUCCESS *	RET_FAILURE - scs connect failed */scsnet_connect(netsystem, isb)struct _netsystem *netsystem;ISB *isb;{	register struct ifaddr *ifa;	struct ifnet *ifp = &scsnetif;	extern struct in_addr scs_inet_addr;	SIB *sib = &netsystem->sys_info;	int error;	int ipl;	CMSB cmsb;	struct scsnet_conn_data *scd 		= (struct scsnet_conn_data *)cmsb.conn_data;    	ipl = Splscs();	if (scs_info_system( isb, sib ) == RET_NOSYSTEM){		printf("scsnet connect - no systems\n");		(void)splx( ipl );		return(RET_FAILURE);	}	/*  check for correct type */	if (U_long(*"U-32") != sib->swtype) {		(void)splx( ipl );		return(RET_FAILURE);	}			bzero((caddr_t)&cmsb, sizeof(CMSB));    	Move_scaaddr( isb->sysid, cmsb.sysid )	cmsb.control = scsnet_control;	bcopy (SYSAP_NET, cmsb.lproc_name, NAME_SIZE);	bcopy (SYSAP_NET, cmsb.rproc_name, NAME_SIZE);	cmsb.dg_event = scsnet_dgevent;	cmsb.msg_event = scsnet_msgevent;	cmsb.init_rec_credit = 5;	cmsb.init_dg_credit = 5;	cmsb.min_snd_credit = 5;    	Zero_scaaddr( cmsb.rport_addr )    	Move_scaaddr( sib->sysid, cmsb.sysid )	cmsb.aux = (u_char *)netsystem;	/*	 * send our internet address to the remote site	 * so it can be used later on to determine correct connection	 */	scd->rmt_inaddr = scs_inet_addr;	scd->version = SCSNET_VERSION_ID;		if ((error=scs_connect(&cmsb))!=RET_SUCCESS) {		if (scsnetdebug)		  printf("scsnet_connect: failed to sysid: %x %x %x, error= %x\n",                         Scaaddr_hi( cmsb.sysid ),                        Scaaddr_mid( cmsb.sysid ),                        Scaaddr_low( cmsb.sysid ),			error);		(void)splx( ipl );		return(RET_FAILURE);	}	netsystem->retries = 0;	netsystem->status = SCSNET_CONN_SENT;	netsystem->rmt_index = SCSNET_NO_INDEX;	(void)splx( ipl );	if (scsnetdebug)	    printf("scsnet_connect: connecting to :: %x,%x,%x\n",                Scaaddr_hi( cmsb.

⌨️ 快捷键说明

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