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

📄 smc8xx.c

📁 这是单板上DPRAM的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* the room in the buffer (has to be done by the user!)...         */
    /*-----------------------------------------------------------------*/
        mblk->b_wptr += bufsize;

    /*-----------------------------------------------------------------*/
    /* Insert the buffer into our pending list.                        */
    /*-----------------------------------------------------------------*/
        imask = splx(MAX_ILEV);
        BufListAppend(mblk, &chan->rx_queue);
        (void)splx(imask);

    /*-----------------------------------------------------------------*/
    /* Insert into the chip ring list: the data must be aligned        */
    /* on a multiple of 4 bytes boundary.                              */
    /*-----------------------------------------------------------------*/
        ring->address = (void *)BufSegAddr(mblk);

    /*-----------------------------------------------------------------*/
    /* Update rx ring pointer, wrap if needed.                         */
    /*-----------------------------------------------------------------*/
        _sync_io();
        if (ring == bottom)
            {
            ring->status = SMC_RX_EMPTY | SMC_RX_WRAP | SMC_RX_INTR;
            ring = chan->rxrg_top;
            }
        else
            {
            ring->status = SMC_RX_EMPTY | SMC_RX_INTR;
            ring++;
            }

        if (++count >= maxcount)
            break;
        }

/*---------------------------------------------------------------------*/
/* Update descriptor write pointer and unused descriptor count.        */
/*---------------------------------------------------------------------*/
    chan->rxrg_wr   = ring;
    chan->unused_rx = count;

/*---------------------------------------------------------------------*/
/* Process flow control, if any.                                       */
/*---------------------------------------------------------------------*/
#if 0
   switch (chan->flowState)
   {
        case XOFF_STATE:
    /*-----------------------------------------------------------------*/
    /* Receiver is xoffed. Now that it has receive buffers send XON    */
    /* or set Request To Send.                                         */
    /*-----------------------------------------------------------------*/
    /* MUST CHANGE if there is more then 1 receive buffer xon! */
            if (chan->unused_rx >= (maxcount - 1))
         {
            chan->flowState = XON_STATE;

            if (chan->cfg.Cfg.Uart.Flags & SWFC)
                queue_toseq(chan, chan->cfg.Cfg.Uart.XOnCharacter);
            }
            break;

        case XON_STATE:
    /*-----------------------------------------------------------------*/
    /* Receiver is xon. If there is only one receive buffer send Xoff  */
    /* or drop Request To Send.                                        */
    /*-----------------------------------------------------------------*/
            if (chan->unused_rx <= 1)
         {
            chan->flowState = XOFF_STATE;

            if (chan->cfg.Cfg.Uart.Flags & SWFC)
                queue_toseq( chan, chan->cfg.Cfg.Uart.XOffCharacter);
         }
        break;

    default:
        break;
   }
#endif

}

/***********************************************************************/
/* drop_buffer:                                                        */
/*              This routine drops a frame from the receive ring.      */
/*              The buffer(s) dropped are returned to the receive pool.*/
/*                                                                     */
/*      INPUTS:                                                        */
/*              chan pointer to the structure that contains channel    */
/*                   information                                       */
/*                                                                     */
/***********************************************************************/
static void
drop_buffer(chan_control *chan)
{
    BuffDescType    *ring = chan->rxrg_rd;
    mblk_t          *mblk;
    /* USHORT          status; -- delete by szg , no used it */
    ULONG           imask;      /* slpx saved level */

/*---------------------------------------------------------------------*/
/* Increment buffers dropped statistic.                                */
/*---------------------------------------------------------------------*/
    ++chan->stats.buffers_dropped;

    while (1)
        {
        _sync_io();
        /* status = ring->status; -- delete by szg , no used it */

    /*-----------------------------------------------------------------*/
    /* Get address of the buffer to be dropped and return it to        */
    /* free pool by call the free function pointed to by freeb set     */
    /* in smc8xx_Open                                                  */
    /*-----------------------------------------------------------------*/
        imask = splx(MAX_ILEV);
        mblk = BufListRxRemove(&chan->rx_queue);
        (void)splx(imask);

        if(SCLOSENOFREE == 0)
            (chan->freeb)(mblk);

    /*-----------------------------------------------------------------*/
    /* Null out the descriptor ring entry.                             */
    /*-----------------------------------------------------------------*/
        ring->address = (void *)0;
        ring->length = 0;

    /*-----------------------------------------------------------------*/
    /* Update rx ring pointer, wrap if needed.                         */
    /*-----------------------------------------------------------------*/
        _sync_io();
        if (ring == chan->rxrg_bottom)
            {
            ring->status = SMC_RX_WRAP;
            ring = chan->rxrg_top;
            }
        else
            {
            ring->status = 0;
            ring++;
            }

        chan->unused_rx--;

    /*-----------------------------------------------------------------*/
    /* Stop discarding buffers when a new beginning of frame is        */
    /* detected or no more descriptors are in use.                     */
    /*-----------------------------------------------------------------*/
         if ( ring->address == (void *)0 )
             break;
         }

/*---------------------------------------------------------------------*/
/* Update channel's pointers to point to the last descriptor checked.   */
/*---------------------------------------------------------------------*/
    chan->rxrg_rd = ring;
    chan->rxrg_ep = ring;
}

/***********************************************************************/
/* frame_receive:                                                      */
/*                This routine empties a frame from the receive        */
/*                descriptor ring when a frame has been completely     */
/*                received by retrieving the associated buffer         */
/*                descriptors from the receive list and building a     */
/*                logical buffer out of them.                          */
/*                                                                     */
/*      INPUTS:                                                        */
/*              chan pointer to the structure that contains channel    */
/*                   information                                       */
/*                                                                     */
/*     OUTPUTS:                                                        */
/*              frameFlag status of frame                              */
/*                                                                     */
/***********************************************************************/
static mblk_t *
frame_receive(chan_control *chan, UINT *frameFlag)
{
   BuffDescType    *ring;              /* receive ring pointer */
   USHORT          rxstatus;           /* frame receive status */
   USHORT          length;             /* accumulated length of frame */
   USHORT          status;             /* status of the current Rx BD */
   mblk_t          *mblk;              /* individual receive buffer */
   mblk_t          *frame;             /* the received frame */
   ULONG           imask;              /* slpx saved level */

   frame     = (mblk_t *)NULL;
   *frameFlag = 0;
   rxstatus = 0;

/*---------------------------------------------------------------------*/
/* Poll EMPTY bit to see if a frame has been received (restart         */
/* from where we last left off).                                       */
/* chan->rxrg_ep is a pointer to a receive buffer descriptor in the    */
/* channels ring of receive buffers. It is the next one in the ring    */
/* from where the last receive buffer descriptor was taken.            */
/*---------------------------------------------------------------------*/
   _sync_io();
   ring  = chan->rxrg_ep;
   status = ring->status;

/*---------------------------------------------------------------------*/
/* Scan descriptors for end of packet:                                 */
/* Caution: some segments may have been received, without further      */
/* buffers to complete the frame reception, the SMC is                 */
/* busy and stuck on this last BD (the next one has to be              */
/* emptied before the SMC can proceed).                                */
/* If descriptor is not empty and the buffer pointer is not null       */
/* process it.                                                         */
/* Check the RBD_EMPTY empty bit if it is not set then the descriptor  */
/* should contain valid data. Also check to see if the data buffer     */
/* does not point to NULL.                                             */
/*---------------------------------------------------------------------*/
   if ( ( (status & SMC_RX_EMPTY) != 0) || (ring->address == (void *)0) )
       {
    /*-----------------------------------------------------------------*/
    /* No frames to process return NULL.                               */
    /*-----------------------------------------------------------------*/
       return(frame);
       }
/*---------------------------------------------------------------------*/
/* Receive a complete frame: start the reassembly where we last left   */
/* off.                                                                */
/* chan->rxrg_rd is the current rec ring read position.                */
/*---------------------------------------------------------------------*/
   ring  = chan->rxrg_rd;
/*    status = ring->status; -- deleted by szg , not used */

/*---------------------------------------------------------------------*/
/* Initialize length to 0.                                             */
/*---------------------------------------------------------------------*/
/*    length = 0;  -- deleted by szg, not used */

/*---------------------------------------------------------------------*/
/* Attach the last mblock to the frame.                                */
/*---------------------------------------------------------------------*/
   imask = splx(MAX_ILEV);
   _sync_io();
   mblk = BufListRxRemove(&chan->rx_queue);
   (void)splx(imask);

   frame  = BufJoin(frame, mblk);

/*---------------------------------------------------------------------*/
/* Update the buffer total length: the last ring entry contains        */
/* the length of the whole frame (including the CRC)                   */
/*---------------------------------------------------------------------*/
   length = ring->length;

   ring->address = (void *)0;
   ring->length = 0;

/*---------------------------------------------------------------------*/
/* Get status to return.                                               */
/*---------------------------------------------------------------------*/
   status = ring->status;

/*---------------------------------------------------------------------*/
/* Update rx ring pointer, wrap if needed.                             */
/*---------------------------------------------------------------------*/
   _sync_io();
   if (ring == chan->rxrg_bottom)
      {
      ring->status = SMC_RX_WRAP;
      ring = chan->rxrg_top;
      }
   else
      {
      ring->status = 0;
      ring++;
      }

/*---------------------------------------------------------------------*/
/* Decrement unused buffers counter.                                   */
/*---------------------------------------------------------------------*/
   --chan->unused_rx;
   chan->rxrg_ep = chan->rxrg_rd = ring;

⌨️ 快捷键说明

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