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

📄 network.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 5 页
字号:
 }  /***********************************************************************  *  Function:   uti596DynamicInterruptHandler  *  *  Description:  *             This is the interrupt handler for the uti596 board  *  *  Algorithm:  *  ***********************************************************************/ /* static */ rtems_isr uti596DynamicInterruptHandler(rtems_vector_number irq) {   rtems_status_code sc;#ifdef DEBUG_ISR printk("I");#endif UTI_WAIT_COMMAND_ACCEPTED(20000, "****ERROR:on ISR entry"); if ( !(i8259s_cache & 0x20 )) {   printk("****Error: network ISR running, no IRR!\n");   printk("****Error: i8259s_cache = 0x%x\n",i8259s_cache );   printk_time(); } scbStatus = uti596_softc.scb.status & 0xf000; if ( scbStatus ){   /* acknowledge interrupts */   /*   printk("***INFO: ACK %x\n", scbStatus);*/   uti596_softc.scb.command = scbStatus;   outport_word(CHAN_ATTN, 0);      if( uti596_softc.resetDone ) {      /* stack is attached */     UTI_WAIT_COMMAND_ACCEPTED(20000, "****ERROR:ACK");   }   else {     /*     printk("***INFO: ACK'd w/o processing. status = %x\n", scbStatus); */     return;   } } else {   printk("\n***ERROR: Spurious interrupt. Resetting...\n");   uti596_softc.nic_reset = 1; }   if ( (scbStatus & SCB_STAT_CX) && !(scbStatus & SCB_STAT_CNA) ){   printk_time();   printk("\n*****ERROR: Command Complete, and CNA available: 0x%x\nResetting...", scbStatus);   uti596_softc.nic_reset = 1;   return; } if ( !(scbStatus & SCB_STAT_CX) && (scbStatus & SCB_STAT_CNA) ) {   printk_time();   printk("\n*****ERROR: CNA, NO CX:0x%x\nResetting...",scbStatus);   uti596_softc.nic_reset = 1;   return; } if ( scbStatus & SCB_CUS_SUSPENDED ) {   printk_time();   printk("\n*****ERROR: Command unit suspended!:0x%x\nResetting...",scbStatus);   uti596_softc.nic_reset = 1;   return; } if ( scbStatus & RU_SUSPENDED  ) {   printk_time();   printk("\n*****ERROR: Receive unit suspended!:0x%x\nResetting...",scbStatus);   uti596_softc.nic_reset = 1;   return; }  if ( scbStatus & SCB_STAT_RNR ) {   printk_time();   printk("\n*****WARNING: RNR %x\n",scbStatus);   printk("*****INFO: RFD cmd: %x status:%x\n",	  uti596_softc.pBeginRFA -> cmd,	  uti596_softc.pBeginRFA -> stat); }  /*   * Receive Unit Control  */ if ( scbStatus & SCB_STAT_FR ) { /* a frame has been received */   uti596_softc.rxInterrupts++;   #ifdef DBG_FR   printk("\nISR:FR\n");#endif   if ( uti596_softc.pBeginRFA == I596_NULL ||  !( uti596_softc.pBeginRFA -> stat & STAT_C)){     dump_scb();     uti596_softc.nic_reset = 1;   }   else     while ( uti596_softc.pBeginRFA != I596_NULL && 	     ( uti596_softc.pBeginRFA -> stat & STAT_C)) {       #ifdef DBG_ISR       printk("ISR:pBeginRFA != NULL\n");#endif       count_rx ++;       if ( count_rx > 1)	 printk("****WARNING: Received 2 frames on 1 interrupt \n");       /* 	* Give Received Frame to the ULCS 	*/	       uti596_softc.countRFD--;              if ( uti596_softc.countRFD < 0 )	 printk("Count < 0 !!!: count == %d, beginRFA = %p\n",		uti596_softc.countRFD, uti596_softc.pBeginRFA);              uti596_softc.stats.rx_packets++;       pIsrRfd = uti596_softc.pBeginRFA -> next; /* the append destroys the link */       uti596append( &uti596_softc.pInboundFrameQueue , uti596_softc.pBeginRFA );              /*	* if we have just received the a frame int he last unknown RFD,	* then it is certain that the RFA is empty.	*/       if ( uti596_softc.pLastUnkRFD == uti596_softc.pBeginRFA ) {	 UTI_596_ASSERT(uti596_softc.pLastUnkRFD != I596_NULL,"****ERROR:LastUnk is NULL, begin ptr @ end!\n");	 uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD = I596_NULL;       }       #ifdef DBG_ISR       printk("Wake %#x\n",uti596_softc.rxDaemonTid);#endif       sc = rtems_event_send(uti596_softc.rxDaemonTid, INTERRUPT_EVENT);       if ( sc != RTEMS_SUCCESSFUL )	 rtems_panic ("Can't notify rxDaemon: %s\n", 		      rtems_status_text (sc)); #ifdef DBG_RAW_ISR       else	 printk("Rx Wake: %#x\n",uti596_softc.rxDaemonTid);#endif              uti596_softc.pBeginRFA = pIsrRfd;     } /* end while */      if ( uti596_softc.pBeginRFA == I596_NULL ){ /* adjust the pEndRFA to reflect an empty list */     if ( uti596_softc.pLastUnkRFD == I596_NULL && uti596_softc.countRFD != 0 )       printk("Last Unk is NULL, BeginRFA is null, and count == %d\n",uti596_softc.countRFD);          uti596_softc.pEndRFA = I596_NULL;     if ( uti596_softc.countRFD != 0 ) {       printk("****ERROR:Count is %d, but begin ptr is NULL\n",uti596_softc.countRFD );     }   }    } /* end scb_stat_fr */  /*  * Check For Command Complete  */ if (  scbStatus & SCB_STAT_CX ){#ifdef DBG_ISR   printk("ISR:CU\n");#endif         pIsrCmd = uti596_softc.pCmdHead;      /*     * For ALL completed commands    */   if ( pIsrCmd !=  I596_NULL && pIsrCmd->status & STAT_C  ){     #ifdef DBG_RAW_ISR       printk("ISR:pIsrCmd != NULL\n");#endif          /*       * Adjust the command block list       */     uti596_softc.pCmdHead = pIsrCmd -> next;          /*      * If there are MORE commands to process,       * the serialization in the raw routine has failed.      * ( Perhaps AddCmd is bad? )      */     UTI_596_ASSERT(uti596_softc.pCmdHead == I596_NULL,		    "****ERROR: command serialization failed\n");     /*      * What if the command did not complete OK?      */     switch ( pIsrCmd->command & 0x7)       {       case CmdConfigure:	 /*	 printk("****INFO:Configure OK\n"); */	 uti596_softc.cmdOk = 1;	 break;	        case CmdDump:	 #ifdef DBG_ISR	   printk("dump!\n");#endif	 uti596_softc.cmdOk = 1;	 break;       case CmdDiagnose:	 #ifdef DBG_ISR	   printk("diagnose!\n");#endif	 uti596_softc.cmdOk = 1;	 break;	        case CmdSASetup:	 /*	 printk("****INFO:Set address interrupt\n");	 */	 if ( pIsrCmd -> status & STAT_OK )	   uti596_softc.cmdOk = 1;	 else	   printk("****ERROR:SET ADD FAILED\n");	 break;	        case CmdTx:	 {	   UTI_596_ASSERT(uti596_softc.txDaemonTid, "****ERROR:Null txDaemonTid\n");#ifdef DBG_ISR	   printk("wake TX:0x%x\n",uti596_softc.txDaemonTid);#endif	   if ( uti596_softc.txDaemonTid ){  /* Ensure that the transmitter is present */	     sc = rtems_event_send (uti596_softc.txDaemonTid, 				    INTERRUPT_EVENT);	   if ( sc != RTEMS_SUCCESSFUL )	     printk("****ERROR:Could NOT send event to tid 0x%x : %s\n",		    uti596_softc.txDaemonTid, rtems_status_text (sc) );#ifdef DBG_RAW_ISR	   else	     printk("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid);#endif	   	   }	 } /* End case Cmd_Tx */	 break;	        case CmdMulticastList:	 printk("***ERROR:Multicast?!\n");	 pIsrCmd->next = I596_NULL;	 break;	        case CmdTDR:	 {	   unsigned long status = *( (unsigned long *)pIsrCmd)+1;	   printk("****ERROR:TDR?!\n");	   	   if (status & STAT_C)	     {	       /*		* mark the TDR command successful		*/	       uti596_softc.cmdOk = 1;	     }	   else	     {	       if (status & 0x4000)		 printk("****WARNING:Transceiver problem.\n");	       if (status & 0x2000)		 printk("****WARNING:Termination problem.\n");	       if (status & 0x1000)		 printk("****WARNING:Short circuit.\n");	       	       /*	       printk("****INFO:Time %ld.\n", status & 0x07ff); */	     }	 }	 break;	        default: 	 /* 	  * This should never be reached 	  */	 printk("CX but NO known command\n");       } /* end switch */     pIsrCmd = uti596_softc.pCmdHead; /* next command */      if ( pIsrCmd != I596_NULL )       printk("****WARNING: more commands in list, but no start to NIC\n");   } /* end if pIsrCmd != NULL && pIsrCmd->stat & STAT_C  */   else {     if ( pIsrCmd != I596_NULL ) { /* The command MAY be NULL from a RESET */              /* Reset the ethernet card, and wake the transmitter (if necessary) */       printk_time();       printk("****INFO: Request board reset ( tx )\n");       uti596_softc.nic_reset = 1;       if ( uti596_softc.txDaemonTid){  /* Ensure that a transmitter is present */	 sc = rtems_event_send (uti596_softc.txDaemonTid, 				INTERRUPT_EVENT);	 	 if ( sc != RTEMS_SUCCESSFUL )	   printk("****ERROR:Could NOT send event to tid 0x%x : %s\n",uti596_softc.txDaemonTid, rtems_status_text (sc) );#ifdef DBG_RAW_ISR	 else	   printk("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid);#endif	          }     }   }  }  /* end if command complete */      /* if the receiver has stopped,   * check if this is a No Resources scenario,   * Try to add more RFD's ( no RBDs are used )  */ if ( uti596_softc.started ) {   if ( scbStatus & SCB_STAT_RNR ){#ifdef DBG_ISR     printk("INFO:RNR: status %#x \n", uti596_softc.scb.status );#endif     /*      * THE RECEIVER IS OFF!      */     if ( uti596_softc.pLastUnkRFD != I596_NULL  ){ /* We have an unknown RFD, it is not inbound*/        if ( uti596_softc.pLastUnkRFD -> stat & (STAT_C | STAT_B )) /* in use */	 uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD;      /* update end */       else {      	 /* 	  *  It is NOT in use, and since RNR, we know EL bit of pEndRFA was read!	  *  So, unlink it from the RFA and move it to the saved queue.	  *  But pBegin can equal LastUnk!	  */		   if ( uti596_softc.pEndRFA != I596_NULL ){      /* check added feb24. */#ifdef DEBUG_RFA	     if (uti596_softc.pEndRFA -> next != uti596_softc.pLastUnkRFD){	       printk("***ERROR:UNK: %p not end->next: %p, end: %p\n",		      uti596_softc.pLastUnkRFD,uti596_softc.pEndRFA -> next,uti596_softc.pEndRFA);	       printk("***INFO:countRFD now %d\n",	 uti596_softc.countRFD);	       printk("\n\n");	     }#endif	     uti596_softc.pEndRFA -> next = I596_NULL;   /* added feb 16 */	   }	 uti596append( &uti596_softc.pSavedRfdQueue, uti596_softc.pLastUnkRFD );	 uti596_softc.savedCount++;	 uti596_softc.pEndSavedQueue = uti596_softc.pLastUnkRFD;	 uti596_softc.countRFD--;                    /* It was not in the RFA */	 /* 	  * The Begin pointer CAN advance this far. We must resynch the CPU side	  * with the chip.	  */	 if ( uti596_softc.pBeginRFA == uti596_softc.pLastUnkRFD ) {#ifdef DEBUG_RFA	   if ( uti596_softc.countRFD != 0 ) {	     printk("****INFO:About to set begin to NULL, with count == %d\n", uti596_softc.countRFD );	     printk("\n\n");	   }#endif	   uti596_softc.pBeginRFA = I596_NULL;	   UTI_596_ASSERT(uti596_softc.countRFD == 0,"****ERROR:Count must be zero here!\n");	 }       }       uti596_softc.pLastUnkRFD = I596_NULL;      } /* end if exists UnkRFD */     /*       * Append the saved queue to  the RFA.        * Any further RFD's being supplied will be added to      * this new list.      */     if ( uti596_softc.pSavedRfdQueue != I596_NULL ) { /* entries to add */       if ( uti596_softc.pBeginRFA == I596_NULL ) {    /* add at beginning to list */#ifdef DEBUG_RFA	 if(uti596_softc.countRFD != 0) {	   printk("****ERROR:Begin pointer is NULL, but count == %d\n",uti596_softc.countRFD);	 }#endif	 uti596_softc.pBeginRFA      = uti596_softc.pSavedRfdQueue; 	 uti596_softc.pEndRFA        = uti596_softc.pEndSavedQueue;	 uti596_softc.pSavedRfdQueue = uti596_softc.pEndSavedQueue = I596_NULL;  /* Reset the End */       }       else {  #ifdef DEBUG_RFA	 if ( uti596_softc.countRFD <= 0) {	   printk("****ERROR:Begin pointer is not NULL, but count == %d\n",uti596_softc.countRFD);	 }#endif	 UTI_596_ASSERT( uti596_softc.pEndRFA != I596_NULL, "****WARNING: END RFA IS NULL\n");	 UTI_596_ASSERT( uti596_softc.pEndRFA->next == I596_NULL, "****ERROR:END RFA -> next must be NULL\n");	 	 uti596_softc.pEndRFA->next   = uti596_softc.pSavedRfdQueue; 	 uti596_softc.pEndRFA->cmd   &= ~CMD_EOL;      /* clear the end of list */ 	 uti596_softc.pEndRFA         = uti596_softc.pEndSavedQueue;	 uti596_softc.pSavedRfdQueue  = uti596_softc.pEndSavedQueue = I596_NULL; /* Reset the End */#ifdef DEBUG_ISR	 printk("count: %d, saved: %d \n", uti596_softc.countRFD , uti596_softc.savedCount);#endif        }       /*       printk("Isr: countRFD = %d\n",uti596_softc.countRFD); */       uti596_softc.countRFD += uti596_softc.savedCount;       /* printk("Isr: after countRFD = %d\n",uti596_softc.countRFD); */       uti596_softc.savedCount = 0;     } #ifdef DBG_596_RFD     printk("The list starts here %p\n",uti596_softc.pBeginRFA );#endif          if ( uti596_softc.countRFD > 1) {       /****REMOVED FEB 18.	 &&            	  !( uti596_softc.pBeginRFA -> stat & (STAT_C | STAT_B ))) {        *****/       printk_time();       printk("****INFO: pBeginRFA -> stat = 0x%x\n",uti596_softc.pBeginRFA -> stat);       printk("****INFO: pBeginRFA -> cmd = 0x%x\n",uti596_softc.pBeginRFA -> cmd);       uti596_softc.pBeginRFA -> stat = 0;       UTI_596_ASSERT(uti596_softc.scb.command == 0, "****ERROR:scb command must be zero\n");       uti596_softc.scb.pRfd = uti596_softc.pBeginRFA;       /* start RX here  */       printk("****INFO: ISR Starting receiver\n");        uti596_softc.scb.command = RX_START; /* should this also be CU start? */       outport_word(CHAN_ATTN, 0);    }     /*****REMOVED FEB 18.       else {       printk("****WARNING: Receiver NOT Started -- countRFD = %d\n", uti596_softc.countRFD);       printk("82596 cmd: 0x%x, status: 0x%x RFA len: %d\n",	      uti596_softc.scb.command, 	      uti596_softc.scb.status,	      uti596_softc.countRFD);              printk("\nRFA: \n");       for ( pISR_Rfd = uti596_softc.pBeginRFA;	     pISR_Rfd != I596_NULL;	     pISR_Rfd = pISR_Rfd->next) 	 printk("Frame @ %x, status: %x, cmd: %x\n",		pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd);              printk("\nInbound: \n");       for ( pISR_Rfd = uti596_softc.pInboundFrameQueue;	     pISR_Rfd != I596_NULL;	     pISR_Rfd = pISR_Rfd->next) 	 printk("Frame @ %x, status: %x, cmd: %x\n",		pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd);                     printk("\nSaved: \n");       for ( pISR_Rfd = uti596_softc.pSavedRfdQueue;	     pISR_Rfd != I596_NULL;	     pISR_Rfd = pISR_Rfd->next) 	 printk("Frame @ %x, status: %x, cmd: %x\n",		pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd);       printk("\nUnknown: %p\n",uti596_softc.pLastUnkRFD);     }     *****/   } /* end stat_rnr */	  } /* end if receiver started */ /* UTI_596_ASSERT(uti596_softc.scb.status == scbStatus, "****WARNING:scbStatus change!\n"); */ #ifdef DBG_ISR   printk("X\n");#endif count_rx=0; /*  * Do this last, to ensure that th

⌨️ 快捷键说明

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