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

📄 if_scs.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef INET	/* this will have to change when we make things more 	   general */	smp_lock(&lk_ifnet, LK_RETRY);	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)		if (ifa->ifa_addr.sa_family == AF_INET)			break;	scs_inet_addr =  IA_SIN(ifa)->sin_addr;	smp_unlock(&lk_ifnet);	scsnet_lhost = in_lnaof(scs_inet_addr) & 0xff;	if (scsnet_lhost < 0 || scsnet_lhost > SCSNET_MAXHOSTS - 1 ) {		printf("scsnet: can not initialize because host number is invalid, host=%d\n", scsnet_lhost);		return(1);	}#endif	/* not yet, if address still unknown */	if (ifp->if_addrlist == (struct ifaddr *)0)			return (1);	if (ifp->if_flags & IFF_RUNNING)		return (0);	scsnet_topsysaddr = netsystems;	ifp->if_snd.ifq_maxlen = ifqmaxlen;	/* scs_info_scs get lock at scs level so raise priority here */        ipl = Splscs();	/* obtain local system information */	scs_info_scs(&scsnet_local);	Move_scaaddr( scsnet_local.system.sysid, sid )	if (scsnetdebug)                printf("scs init - local sysid: %x,%x,%x, local inet host=%d\n",                        Scaaddr_hi( sid ), Scaaddr_mid( sid ),                        Scaaddr_low( sid ), scsnet_lhost );			for (i=0; i<SCSNET_RECVS; i++)		scsnet_recvs[i].state = SCSNET_BDONE;        for (i=0; i<SCSNET_MAXHOSTS; i++)                knownsystems[i] = SCSNET_NO_SYS;		Init_queue(netsys_head)	/* start listening */	netcmsb.control = scsnet_control;	bcopy (SYSAP_NET, netcmsb.lproc_name, NAME_SIZE);        ipl = Splscs();	if ((ret=scs_listen(&netcmsb))!= RET_SUCCESS) {		(void)splx( ipl );		if (scsnetdebug)			printf("scs_listen failed, ret=%x\n", ret);		return(1);	}	(void)splx( ipl );	/*	 *  Connect to all of the systems we know about 	 */	Zero_scaaddr(isb->next_sysid);  /* start at the beginning */	do	{						if ((netsystem=alloc_netsys())==SCSNET_NO_SYS)			panic("scsnet: too many systems"); 		smp_lock(&netsystem->lk_netsys, LK_RETRY);		netsystem->rmt_index = SCSNET_NO_INDEX;		if (scsnet_connect(netsystem, isb) != RET_SUCCESS)			scsnet_rem_sys(netsystem, &netcmsb);		smp_unlock(&netsystem->lk_netsys);	} while (!Test_scaaddr( isb->next_sysid));	(void)splx( ipl );		scsnet_timeo = SCSNET_TIMEO;	ifp->if_flags |= IFF_RUNNING | IFF_UP;	return (0);}/*	 *  scsnet_control:  event notification routine. *		 * *		 *    event	    	Action * *    CRE_CONN_REC    	If enough resources are available send an accept. *			Otherwise send a reject. * *    CRE_ACCEPT_DONE 	Add remote system to known systems list and reserve *			resources for I/O. * *    CRE_REJECT_DONE	none *    CRE_DISCONN_REC  	Issue disconnect to remote sysap and deallocate *			resources dedicated to connection. *    CRE_PATH_FAILURE  Issue disconnect to remote sysap and deallocate *			resources dedicated to connection. Try to reconnect *			in the event another path exists. *    CRE_DISCONN_DONE  none *    CRE_BLOCK_DONE  	Deallocate buffer space and send ack. *    CRE_CREDIT_AVAIL 	none *    CRE_NEW_PATH 	Issue connect to new system. *    CRE_CONN_DONE 	If successful then add to list of known systems and *			reserve resources for I/O. *			If remote sysap was busy then issue another connect. *			If connect failed deallocate any resources devoted *			to the connection request. * * Inputs: * *   cmsb	- Connection Management Services Block *   event	- Event type * * Outputs: * *   cmsb	- Connection Management Service Block pointer *		  INITIALIZED ( depending upon actions taken ) * *   Return *   Values:	NONE */	voidscsnet_control( event, cmsb )    u_short			event;    register CMSB		*cmsb;{    register struct _netsystem *sys = (struct _netsystem *)cmsb->aux;    register SIB *s = &sys->sys_info;    struct scsnet_conn_data *scd = (struct scsnet_conn_data *)cmsb->conn_data;    int status, ret;#ifdef SCSNETDEBUG    if (scsnetdebug > 1) {	printf("scsnet_control: sys=%x, event=%d, cmsb->status=%d, cmsb->sysid=%x,%x,%x\n",                 sys, event, cmsb->status, Scaaddr_hi( cmsb->sysid )                Scaaddr_mid( cmsb->sysid ), Scaaddr_low( cmsb->sysid ));	printf(" lproc_name=%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n", 		cmsb->lproc_name[0], cmsb->lproc_name[1], cmsb->lproc_name[2],		cmsb->lproc_name[3], cmsb->lproc_name[4], cmsb->lproc_name[5],		cmsb->lproc_name[6], cmsb->lproc_name[7], cmsb->lproc_name[8],		cmsb->lproc_name[9], cmsb->lproc_name[10], cmsb->lproc_name[11],		cmsb->lproc_name[12], cmsb->lproc_name[13],cmsb->lproc_name[14],		cmsb->lproc_name[15]);	printf(" rproc_name=%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n", 		cmsb->rproc_name[0], cmsb->rproc_name[1], cmsb->rproc_name[2],		cmsb->rproc_name[3], cmsb->rproc_name[4], cmsb->rproc_name[5],		cmsb->rproc_name[6], cmsb->rproc_name[7], cmsb->rproc_name[8],		cmsb->rproc_name[9], cmsb->rproc_name[10], cmsb->rproc_name[11],		cmsb->rproc_name[12], cmsb->rproc_name[13],cmsb->rproc_name[14],		cmsb->rproc_name[15]);	}#endif			    if (event == CRE_BLOCK_DONE) {    /* block transfer completed.      * Send and ack to the other side and free up local resource.     */	register struct scsnet_cntl *scscp = &scsnet_recvs[cmsb->blockid];	register struct scsnet_msg *msg = (struct scsnet_msg *)scscp->csb.buf;	register struct mbuf *m = scscp->mchain;	register struct ifnet *ifp = &scsnetif;#ifdef SCSNETDEBUG	if (scsnetdebug > 2)		printf("scsnet_control: rspid=%d\n", msg->rspid);#endif	/*	 * queue data to the appropriate protocol.	 */		Scsnet_enqueue(m)	ifp->if_ipackets++;		/*	 * send and acknowledment back to the remote host	 */	msg->cmd = SCSNET_BCMD_ACK;	scscp->csb.connid = cmsb->connid;	scscp->csb.size = Scsnet_msg_hdr_siz;	scscp->csb.Disposal = RECEIVE_BUF;	scscp->csb.Aux = 0;	if ((status=scs_send_msg(&scscp->csb)) != RET_SUCCESS)		printf("scsnet: send ack0 failed, status = %d\n", status);	/*	 * free up local resources 	 */	if ((status=scs_unmap_buf(&scscp->csb)) != RET_SUCCESS)		printf("scsnet: unmap0 failed, status = %d\n", status);	scscp->mchain = 0;	scscp->state = SCSNET_BDONE;    } else         switch( event ) {        case CRE_CONN_DONE:        {    	/* An attempt to establish a SCS connection has completed.  Process it     	 * according to its completion status.     	 * Add this system to a list of known systems.      	 */	     smp_lock(&sys->lk_netsys, LK_RETRY);	     if( cmsb->status == ADR_SUCCESS ) {	        /* mark connection open and add to list of known systems */		if (scsnetdebug)	            printf( "scsnet - Established SCS Connection to %c%c%c%c%c%c%c%c\n",		        s->node_name[ 0 ], s->node_name[ 1 ],		        s->node_name[ 2 ], s->node_name[ 3 ],		        s->node_name[ 4 ], s->node_name[ 5 ],		        s->node_name[ 6 ], s->node_name[ 7 ] );	        if (scsnet_add_sys(in_lnaof(scd->rmt_inaddr)&0xff, 				sys, cmsb)!=RET_SUCCESS) {		    printf("scsnet: conn recv, could not allocate resources for connection to host %d\n", in_lnaof(scd->rmt_inaddr)&0xff);		    /* 		     * send a disconnect 		     */#ifdef notdef		/* should not get here but if we do then we need to schedule the		 * scs_disconnect with ksched or timeout.  TODO		 */	            if( scs_disconnect( cmsb ) != RET_SUCCESS )	            	 panic( "SCS_NET - SCS Disconnect Failed\n" );	            else		        if (scsnetdebug)	                    printf( "scsnet - SCS DISCONNECT to %c%c%c%c%c%c%c%c sent\n",		        	s->node_name[ 0 ], s->node_name[ 1 ],		        	s->node_name[ 2 ], s->node_name[ 3 ],		        	s->node_name[ 4 ], s->node_name[ 5 ],		        	s->node_name[ 6 ], s->node_name[ 7 ] );#endif		    scsnet_rem_sys(sys, cmsb);		}	    } else 		/* 		 * connection attempt failed		 */	    {		ISB isb;		bzero((caddr_t)&isb, sizeof(ISB));		/*	         * if remote sysap is busy keep trying 		 */	        if (cmsb->status == ADR_BUSY  && 			sys->retries++ < scsnet_maxretries) {	    	    Move_scaaddr( cmsb->sysid, isb.next_sysid );		    sys->rmt_index = SCSNET_NO_INDEX;		    if (scsnet_connect(sys, &isb) != RET_SUCCESS)			scsnet_rem_sys(sys, cmsb);		    smp_unlock(&sys->lk_netsys);		    return;	        }		/*	         * mark connection closed 		 */		if (scsnetdebug) {	            printf( "scsnet - Unable to Establish SCS Connection to " );	    	    printf( "%c%c%c%c%c%c%c%c\n",		        s->node_name[ 0 ], s->node_name[ 1 ],		        s->node_name[ 2 ], s->node_name[ 3 ],		        s->node_name[ 4 ], s->node_name[ 5 ],		        s->node_name[ 6 ], s->node_name[ 7 ] );		}	    	scsnet_rem_sys(sys, cmsb);	    }	    smp_unlock(&sys->lk_netsys);	    break;        }        case CRE_CREDIT_AVAIL:	    break;        case CRE_DISCONN_REC:        /* A SCS connection has terminated due to virtual path failure.  Clean         * up and then disconnect the connection.     	 */        case CRE_PATH_FAILURE: {	    ISB	isb;	    struct _netsystem	*netsystem;	    bzero((caddr_t)&isb, sizeof(ISB));	    smp_lock(&sys->lk_netsys, LK_RETRY);	    if (scsnetdebug) {	        if (event == CRE_PATH_FAILURE)		    printf( "Scsnet - Virtual Path Failed to: ");	        else		    printf( "Scsnet - Received disconnect from: ");	        printf( "%c%c%c%c%c%c%c%c \n",		    s->node_name[ 0 ], s->node_name[ 1 ],		    s->node_name[ 2 ], s->node_name[ 3 ],		    s->node_name[ 4 ], s->node_name[ 5 ],		    s->node_name[ 6 ], s->node_name[ 7 ] );	    }	    /*	     * Issue the SCS Disconnect to complete connection termination.	     */	    scsnet_rem_sys(sys, cmsb);	    /*	     * this disconnect is ok because I am not changing the state	     * of an scs connection	     */	    if( scs_disconnect( cmsb ) != RET_SUCCESS )	        panic( "SCS_NET - SCS Disconnect Failed\n" );	    else		if (scsnetdebug)	            printf( "scsnet - SCS DISCONNECT sent to %c%c%c%c%c%c%c%c \n",		        s->node_name[ 0 ], s->node_name[ 1 ],		        s->node_name[ 2 ], s->node_name[ 3 ],		        s->node_name[ 4 ], s->node_name[ 5 ],		        s->node_name[ 6 ], s->node_name[ 7 ] );	    /* 	     * try to reconnect just in case there exists an alternate path	     */	    smp_unlock(&sys->lk_netsys);	    if ((netsystem=alloc_netsys())==SCSNET_NO_SYS)	       return;	    /* Check to see if the system is still in the system-wide	     * configuration database.  	     */	    Move_scaaddr( cmsb->sysid, isb.next_sysid )	    smp_lock(&netsystem->lk_netsys, LK_RETRY);	    if (scsnet_connect(netsystem, &isb) != RET_SUCCESS)			scsnet_rem_sys(netsystem, cmsb);	    smp_unlock(&netsystem->lk_netsys);	    break;	}        /*         * A previously unknown new system exists.         * Try to establish a connection to the net sysap on the new system.         */        case CRE_NEW_PATH: {	    ISB	isb;	    register SIB		*sib;	    struct _netsystem	*netsystem;		    bzero((caddr_t)&isb, sizeof(ISB));#ifdef notdef		if (Comp_scaaddr(cmsb->sysid, scsnet_local.system.sysid) == 0 )			return;  /* only connect to local system for now */#endif	    if (scsnetdebug)	    	printf("scsnet control: new path\n");	    /*	     * find a free netsystem structure for this connection 	     * and then try to connect.	     */	    if ((netsystem=alloc_netsys())==SCSNET_NO_SYS) {	        printf( "SCS_NET - can not allocate resources for new system\n");		return;	    }	    smp_lock(&netsystem->lk_netsys, LK_RETRY);	    Move_scaaddr( cmsb->sysid, isb.next_sysid )	    if (scsnet_connect(netsystem, &isb) != RET_SUCCESS) {		scsnet_rem_sys(netsystem, cmsb);		smp_unlock(&netsystem->lk_netsys);		return;	    }	    sib = &netsystem->sys_info;	    /*	     * This entire process is interrupt driven once establishment of the	     * SCS connection is initiated.	     */	    if (scsnetdebug)	       printf( "SCS_NET - SCS Discovered %c%c%c%c%c%c%c%c\n",	        sib->node_name[ 0 ], sib->node_name[ 1 ],	        sib->node_name[ 2 ], sib->node_name[ 3 ],	        sib->node_name[ 4 ], sib->node_name[ 5 ],	        sib->node_name[ 6 ], sib->node_name[ 7 ] );	    smp_unlock(&netsystem->lk_netsys);	    break;	}        /* Termination of a SCS conn has completed.          */        case CRE_DISCONN_DONE:	    smp_lock(&sys->lk_netsys, LK_RETRY);	    if (scsnetdebug)	        printf( "scsnet - Completed Disconnect from %c%c%c%c%c%c%c%c\n",		    s->node_name[ 0 ], s->node_name[ 1 ],		    s->node_name[ 2 ], s->node_name[ 3 ],		    s->node_name[ 4 ], s->node_name[ 5 ],		    s->node_name[ 6 ], s->node_name[ 7 ] );	    smp_unlock(&sys->lk_netsys);	    break;        case CRE_ACCEPT_DONE:        /* An attempt to accept a SCS connection has completed.  Process it         * according to its completion status.         * We add this system to a list of known systems if successful.          */	    smp_lock(&sys->lk_netsys, LK_RETRY);	    if( cmsb->status == ADR_SUCCESS ) {		/*	         * mark connection open and add to list of known systems 		 */		if (scsnetdebug)	    	    printf( "scsnet - accept done from %c%c%c%c%c%c%c%c\n",		        s->node_name[ 0 ], s->node_name[ 1 ],		        s->node_name[ 2 ], s->node_name[ 3 ],		        s->node_name[ 4 ], s->node_name[ 5 ],		        s->node_name[ 6 ], s->node_name[ 7 ] );	        if (scsnet_add_sys(sys->rmt_index, sys, cmsb) == RET_SUCCESS) {		    if (scsnetdebug)		        printf("scsnet - accept succeeded\n");	        } else {		    if (scsnetdebug)	                printf( "scsnet - can not add to list of systems\n");		    cmsb->Reason = ADR_NOLISTENER;		    if((status =  scs_disconnect( cmsb ) != RET_SUCCESS) ) 			mprintf("scsnet control: disconnect failed, status=%x\n",			    status);		    scsnet_rem_sys(sys, cmsb);

⌨️ 快捷键说明

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