Beispiel #1
0
/*
* Cleanup internal resources used by this timer module. It deletes all
* pending timer entries from the backend timer system as well.
*/
int
bcm_timer_module_cleanup(bcm_timer_module_id module_id)
{
	ecos_timer_list_t *list = (ecos_timer_list_t *)module_id;
	ecos_timer_entry_t *entry;
	int key;

	TIMERDBG("list %08x", list);

	/*
	* do nothing if the list has not been initialized
	*/
	if (!(list->flags&TIMER_LIST_FLAG_INIT))
		return -1;

	/*
	* mark the big bang flag here so that no more callbacks
	* shall be scheduled or called from this point on...
	*/
	list->flags |= TIMER_LIST_FLAG_EXIT;

	/*
	* remove all backend timers here so that no timer expires after here.
	*/
	TIMER_LIST_LOCK(list);

	key = INTLOCK();
	for (entry = list->used; entry != NULL; entry = entry->next)
	{
		ecos_del_timer(entry);
	}
	INTUNLOCK(key);

	TIMER_LIST_UNLOCK(list);

	/*
	* have to wait till all expired entries to have been handled
	*/
	for (entry = list->used; entry != NULL; entry = entry->next)
	{
		if ((entry->flags&TIMER_FLAG_DEFERRED) &&
		    !(entry->flags&TIMER_FLAG_FINISHED))
			break;
	}

	cyg_mutex_destroy(&(list->lock));
	/* now it should be safe to blindly free all the resources */
	TIMER_FREE_LOCK_MECHANISM();
	free(list);
	TIMERDBG("done");
	return 0;
}
Beispiel #2
0
/*===========================================================================
FUNCTION       DSRLPDEL_PUT_ARRAY

DESCRIPTION    Called when an rlp session is over.  Returns the array back to
               the free pool of delayed frame detect arrays.  Clears out the
               struct.

DEPENDENCIES   None

RETURN VALUE   NONE

SIDE EFFECTS   None
===========================================================================*/
void dsrlpdel_put_array
(
  uint32      rlpdel_id
)
{
  ASSERT(rlpdel_id < DSRLPI_MAX_SESSIONS);
  ASSERT(rlpdel_fr_detect[rlpdel_id].used == TRUE);

  dsrlpdel_reset(rlpdel_id);

  INTLOCK();
  rlpdel_fr_detect[rlpdel_id].used = FALSE;
  INTFREE();
}
Beispiel #3
0
void usart_transmit_string(USART_TypeDef* port, const void *data) 
{
	int i;
	u16 data_len;
	int tx_count;
	const char* usart_data;
	q_node_type* q_usart_pkt_ptr;

	usart_data = (char*)data;
	data_len = strlen(usart_data);

	tx_count = (data_len - 1) / USART_TX_DMA_SIZ + 1;

	INTLOCK();


	if( q_get_count(&gbl_qlist_usart1_tx_free) >= tx_count )
	{
		for(i=0;i<tx_count-1;i++)
		{
			if( (q_usart_pkt_ptr = q_remove_tail(&gbl_qlist_usart1_tx_free)) != NULL )
			{
				memcpy(q_usart_pkt_ptr->data, usart_data, USART_TX_DMA_SIZ);
				q_usart_pkt_ptr->len = USART_TX_DMA_SIZ;
				q_add_tail(&gbl_qlist_usart1_tx, q_usart_pkt_ptr);

				data_len = data_len - USART_TX_DMA_SIZ;
				usart_data += USART_TX_DMA_SIZ;

			}
		}

		if( (q_usart_pkt_ptr = q_remove_tail(&gbl_qlist_usart1_tx_free)) != NULL )
		{
			memcpy(q_usart_pkt_ptr->data, usart_data, data_len);
			q_usart_pkt_ptr->len = data_len;
			q_add_tail(&gbl_qlist_usart1_tx, q_usart_pkt_ptr);

		}

		if( usart1_dma_transfering == FALSE )
			usart1_tx_proc();

			
	}	


	INTFREE();
	
}
Beispiel #4
0
/*===========================================================================

FUNCTION PZIDI_HYSTERESIS_INIT_STATE

DESCRIPTION
  This function is called when Hysteresis SM enters INIT state. The Hys SM
  enters init state when hysteresis is enabled and pkt call is active.
DEPENDENCIES
  None

RETURN VALUE
  None

SIDE EFFECTS
  None
===========================================================================*/
static void pzidi_hysteresis_init_state
(
   void
)
{
/*-----------------------------------------------------------------------*/
  HYST_DEBUG("init_state(), list = %d, old_pzid_ind = %d,pzidi_hys_state = %d",
             ds707_pzid_max_list_len, ds707_pzid_oldest_pzid, pzidi_hys_state); 
  /*---------------------------------------------------------------------
    Check to see if PZID feature is registered before we 
	go to the init state for hysteresis.
  -----------------------------------------------------------------------*/
  if(ds707_pzid_max_list_len == 0)
  {
    return;
  }

  /*-------------------------------------------------------------------------
    Clears Hysteresis activation timer or Hysteresis timers 
    depending on the state. 
  -------------------------------------------------------------------------*/
    PZIDI_STOP_TIMER();
    
  /*----------------------------------------------------------------------
      Clear the elements from the list starting at index 1 to maximum 
      elements pointed in the list.
    -----------------------------------------------------------------------*/
    ds707_pzid_clear_pzid_list(1,ds707_pzid_oldest_pzid);
    
    INTLOCK();
  /*----------------------------------------------------------------------
      In Hyseteresis state the list length should be made 1.
      
      Sometimes this can be called from different context, so add INTLOCK
      and INTFREE.
    -----------------------------------------------------------------------*/
    ds707_pzid_max_list_len       = 1;       
    ds707_pzid_oldest_pzid        = 1;
    pzidi_hysteresis_hai          = TRUE;
    pzidi_hys_state               = PZIDI_HYS_INIT_STATE;
    HYST_DEBUG("Init state :HAI = %d, pzidi_hys_state = %d, max list length = %d ",
                pzidi_hysteresis_hai, pzidi_hys_state, ds707_pzid_max_list_len); 
    INTFREE();

} /* ds707_pzid_hysteresis_init_state() */
Beispiel #5
0
/*===========================================================================

  FUNCTION GPIO_TLMM_CONFIG

  DESCRIPTION
    Configures the GPIO TLMM as per the signal value used for the given GPIO.

  DEPENDENCIES
    None.

  RETURN VALUE
    None
===========================================================================*/
void gpio_tlmm_config(GPIO_SignalType gpio_signal)
{
  GPIO_PolarityType gpio_polarity;
  uint32            gpio_oe_register;
  uint32            gpio_mask;
  uint8             gpio_number;

  gpio_number = GPIO_NUMBER(gpio_signal);

  if (gpio_number >= GPIO_NUM_GPIOS)
  {
    #ifndef BUILD_BOOT_CHAIN
      ERR_FATAL("Invalid GPIO number 0x%x",gpio_number, 0, 0);
	  #endif
	  return;
  }

  gpio_polarity    = GPIO_POLARITY(gpio_signal);
  gpio_oe_register = GPIO_GROUP(gpio_signal);
  gpio_mask        = 1 <<(gpio_number-GPIO_GROUP_START[gpio_oe_register]);

  INTLOCK();  
  if (gpio_oe_register < 2)
  {
    HWIO_OUT(GPIO_PAGE,gpio_number);
    HWIO_OUT(GPIO_CFG,(GPIO_SIGNAL(gpio_signal)<<2) | GPIO_PULL(gpio_signal));
  }
  else
  {
    HWIO_OUT(GPIO2_PAGE,gpio_number);
    HWIO_OUT(GPIO2_CFG,(GPIO_SIGNAL(gpio_signal)<<2) | GPIO_PULL(gpio_signal));
  }
  INTFREE();
  
  if ( gpio_polarity == GPIO_OUTPUT )
  {
    BIO_TRISTATE(gpio_oe_register, gpio_mask, gpio_mask);
  }
  else
  {
    BIO_TRISTATE(gpio_oe_register, gpio_mask, 0);
  }
  gpio_configs[gpio_number] = gpio_signal;
}
Beispiel #6
0
int
bcm_timer_delete(bcm_timer_id timer_id)
{
	ecos_timer_entry_t *entry = (ecos_timer_entry_t *)timer_id;
	ecos_timer_list_t *list = entry->list;
	int status;
	int key;

	TIMERDBG("entry %08x timer %08x", entry, entry->timer);

	/* make sure no interrupts can happen */
	key = INTLOCK();

	/* lock the timer list */
	TIMER_LIST_LOCK(list);

	/* remove the entry from the used list first */
	status = remove_entry(&list->used, entry);
	if (status != 0)
		goto exit0;

	/* delete the backend timer */
	ecos_del_timer(entry);

	/* free the entry back to freed list */
	put_entry(&list->freed, entry);

	entry->flags = TIMER_FLAG_NONE;
	entry->list = NULL;
	TIMER_LIST_UNLOCK(list);

	INTUNLOCK(key);

	TIMERDBG("done");
	return 0;

	/* error handling */
exit0:
	TIMER_LIST_UNLOCK(list);
	INTUNLOCK(key);
	return status;
}
Beispiel #7
0
BOOL AddDMABufferList ( UINT32 uDMACh,UINT32* pSBuff,UINT32 uBuffSize)
{
   UINT32 OldLevel;
   register BOOL bReturn;
   
   /* Note : uBuffSize from BM must be <= 64 */
   if ( (pSBuff == 0) || (uBuffSize > BULK_MAX_PACKET_SIZE) )
      return FALSE;

   /* Initialize variables to error and no BM operation (pEPBM = 0) */
   bReturn = FALSE;

   OldLevel = INTLOCK();

   switch ( uDMACh )
   {

  #if DSL_DMA
      case DMA_CHANNEL_DSL_TX :			/* 5 */
		bReturn = DSLWriteBuffer(pSBuff,uBuffSize);
		if (bReturn == 0)
		{
			DSLInfo.TxRejectCnt += 1;
		}
		break;
  #endif

      case DMA_CHANNEL_USB_TX_EP1 :   /* 11 */
      case DMA_CHANNEL_USB_TX_EP2 :   /* 10 */
      case DMA_CHANNEL_USB_TX_EP3	:  /* 9  */
      case DMA_CHANNEL_USB_TX_EP0 :   /* 13 */
      case DMA_CHANNEL_EMAC1_TX :
      case DMA_CHANNEL_EMAC2_TX :
      default :
         break;
   }

   INTUNLOCK(OldLevel);
   return bReturn;
} 		
Beispiel #8
0
/*===========================================================================

FUNCTION    : PZIDI_HYSTERESIS_NULL_STATE

DESCRIPTION : Enters null state when packet call is closed.

DEPENDENCIES

RETURN VALUE

SIDE EFFECTS
===========================================================================*/
static void pzidi_hysteresis_null_state
(
  void
)
{
  /*-----------------------------------------------------------------------*/
  /*-------------------------------------------------------------------------
     Reset the pzid hysteresis variables
  -------------------------------------------------------------------------*/
  
  HYST_DEBUG("null_state(), list = %d, old_pzid_ind = %d",
              ds707_pzid_max_list_len, ds707_pzid_oldest_pzid, 0); 
  INTLOCK();
  pzidi_hysteresis_hai = FALSE;
  PZIDI_STOP_TIMER();
  pzidi_hys_state      = PZIDI_HYS_NULL_STATE;
  INTFREE();
  
  HYST_DEBUG("HAI = %d, pzidi_hys_state = %d ",
                pzidi_hysteresis_hai, pzidi_hys_state, 0); 

}/* pzidi_hysteresis_null_state() */
Beispiel #9
0
/*===========================================================================

FUNCTION    : PZIDI_HYSTERESIS_PROCESS_HAT

DESCRIPTION : Called when the hysteresis activation timer is expired.The
              list lenght is changed from 1 to 4 and goes into HYSTERESIS
			  state.
  
DEPENDENCIES
  None

RETURN VALUE
  None

SIDE EFFECTS
  None
===========================================================================*/
static void pzidi_hysteresis_process_hat
(
  void
)
{
  HYST_DEBUG("process_hat(), hyst_enabled = %d, old_pzid_ind = %d,pzidi_hys_state = %d",
   ds707_pzid_hysteresis_enabled, ds707_pzid_oldest_pzid, pzidi_hys_state); 
 /*------------------------------------------------------------------------*/  
    
  /*-------------------------------------------------------------------------
    Cancel timer before processing it.
  -------------------------------------------------------------------------*/
  PZIDI_STOP_TIMER(); 
  
  /*-----------------------------------------------------------------------
   If the PZID hysteresis feature was disabled and the timer signal was 
  disabeld make sure we exit without processing as the state is lost
  ------------------------------------------------------------------------*/
  if(ds707_pzid_hysteresis_enabled == FALSE)
  {
   MSG_HIGH("PZID Hysteresis feature is disabled",0,0,0);
   return;
  }

  /*----------------------------------------------------------------------
     Hysteresis Activation Timer expired, 
     increase the PZID List length to 4. 
   -----------------------------------------------------------------------*/
  INTLOCK()
  ds707_pzid_max_list_len = PZIDI_HYSTERESIS_DORM_LIST_LEN;
  INTFREE()

   
  MSG_HIGH("HAT Expired. List : %d",ds707_pzid_max_list_len,0,0);
  event_report(EVENT_PZID_HAT_EXPIRED);

} /* pzidi_hysteresis_process_hat() */
Beispiel #10
0
/*===========================================================================
FUNCTION       DSRLPDEL_GET_ARRAY

DESCRIPTION    Called when an rlp session is initialized.  Assigns a delayed
               frame detection struct to the calling task.

DEPENDENCIES   None

RETURN VALUE   DSRLPDEL_NO_ARRAY if no queue could be assigned, else returns
               the index of the queue.

SIDE EFFECTS   None
===========================================================================*/
uint32 dsrlpdel_get_array()
{
  uint32     i;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  INTLOCK();
  for (i = 0; i < DSRLPI_MAX_SESSIONS; i++)
  {
    if (rlpdel_fr_detect[i].used == FALSE)
    {
      rlpdel_fr_detect[i].used = TRUE;
      break;
    }
  }
  INTFREE();

  if (i == DSRLPI_MAX_SESSIONS)
  {
    return(DSRLPDEL_NO_ARRAY);
  }
  else
  {
    return(i);
  }
}
Beispiel #11
0
/*
** The actual handware interrupt goes here for processing.
*/
void GPIOHandler(int irq, void *dev_id, struct pt_regs * regs)
{

   register UINT32 i;
   register UINT32 dwGPIO1Stat, dwGPIO2Stat, dwGPIO3Stat;
   register UINT32 BitPosition;

   register int oldlevel; 

#ifdef INSTRUMENTATION
   register int oldTskGPIO;
#endif /* INSTRUMENTATION */

   oldlevel = INTLOCK(); 

#ifdef INSTRUMENTATION
   oldTskGPIO= ReadGPIOData(GPOUT_TASKRDY_LED);
   WriteGPIOData(GPOUT_TASKRDY_LED, LED_ON);
#endif /* INSTRUMENTATION */

   while (1)
   {
      /* Each GPIO ISR only contains 16 bits */
      dwGPIO1Stat = (*p_GRP0_INT_STAT & *p_GRP0_INT_MASK) & 0xFFFF;
      dwGPIO2Stat = (*p_GRP1_INT_STAT & *p_GRP1_INT_MASK) & 0xFFFF;
      dwGPIO3Stat = (*p_GRP2_INT_STAT & *p_GRP2_INT_MASK) & 0xFFFF;
      
      if ( (dwGPIO1Stat | dwGPIO2Stat | dwGPIO3Stat) == 0)
         break;

      for (i = 0, BitPosition = 1; dwGPIO1Stat; i++, BitPosition<<=1)
         if (dwGPIO1Stat & BitPosition)
         {
            if (GPIOISR1Handler_Tbl[i] != 0)
   	           (*GPIOISR1Handler_Tbl[i])(i);
            else
			   {
	           if (pGPIO_ISR[i] != 0)
   				  (*(pGPIO_ISR)[i])(i);

               HW_REG_WRITE (p_GRP0_INT_STAT, BitPosition);
			   }

		      dwGPIO1Stat &= ~(BitPosition); 
         }

      for (i = 0, BitPosition = 1; dwGPIO2Stat; i++, BitPosition<<=1)
         if (dwGPIO2Stat & BitPosition)
            {
            if (GPIOISR2Handler_Tbl[i] != 0)
   	           (*GPIOISR2Handler_Tbl[i])(i+16);
            else
			   {
	           if (pGPIO_ISR[i+16] != 0)
   				  (*(pGPIO_ISR)[i+16])(i+16);

               HW_REG_WRITE (p_GRP1_INT_STAT, BitPosition);
			   }

		 dwGPIO2Stat &= ~(BitPosition); 
         }

      for (i = 0, BitPosition = 1; dwGPIO3Stat; i++, BitPosition<<=1)
	     if (dwGPIO3Stat & BitPosition)
            {
            if (GPIOISR3Handler_Tbl[i] != 0)
   	         (*GPIOISR3Handler_Tbl[i])(i+32);
            else
			   {
	           if (pGPIO_ISR[i+32] != 0)
   				  (*(pGPIO_ISR)[i+32])(i+32);

               HW_REG_WRITE (p_GRP2_INT_STAT, BitPosition);
			   }

		 dwGPIO3Stat &= ~(BitPosition); 
         }
   }

#ifdef INSTRUMENTATION
   WriteGPIOData(GPOUT_TASKRDY_LED, oldTskGPIO);
#endif /* INSTRUMENTATION */

   HW_REG_WRITE (PIC_TOP_ISR_IRQ, INT_GPIO);
   INTUNLOCK(oldlevel);
}
Beispiel #12
0
/*===========================================================================

FUNCTION DSSICMP_READ()

DESCRIPTION
  Reads 'nbytes' bytes into the buffer from the ICMP transport.  Fills in
  address structure with values from who sent the data in fromaddr.
  This function asserts that fromaddr is not NULL. This function is the 
  ICMP specific dss_recvfrom()

DEPENDENCIES
  None. 

PARAMETERS
  struct scb_s* scb_ptr      -  Ptr to socket control block for the socket
  void   *buffer             -  user buffer from which to copy the data 
  uint16 nbytes              -  number of bytes app wants to read
  struct sockaddr_in *fromaddr  -  source address 
  sint15 *dss_errno          -  error condition value 

RETURN VALUE
  n - the number of bytes to be written, which could be less than the number
      of bytes specified.

  On error, return DSS_ERROR and places the error condition value in
  *dss_errno.

  Errno Values
  ------------
  DS_EWOULDBLOCK      operation would block

SIDE EFFECTS
  None.

===========================================================================*/
extern sint15 dssicmp_read
(
  struct scb_s* scb_ptr,     /* Ptr to socket control block for the socket */
  struct iovec * iov,         /* user buffer from which to copy the data   */
  uint16         iovcount,     /* length of the iovec array                */
  struct sockaddr_in *fromaddr,                          /* source address */
  sint15 *dss_errno                               /* error condition value */
)
{
  struct icmp_cb *icmp_cb_ptr;              /* ICMP protocol control block */
  dsm_item_type *item_ptr;         /* ptr to head of dsm memory pool items */
  uint16 cnt=0;                                /* tmp # of bytes retrieved */
  uint16 bytes_read =0;                    /* # of bytes to read from rcvq */
  uint16 read_cnt=0;              /* # of bytes read in each iteration     */
  uint16 payload_len=0;                        /* packet length            */
  int    i;                                  /* local loop index           */
  uint16 bytes_requested;        /* # of bytes requested in each iteration */

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  MSG_LOW("In dssicmp_read()", 0, 0, 0);
  /*-------------------------------------------------------------------------
    Ensure that the "from address" is not NULL.  This function fills in this
    structure, thus, needs to ASSERT against dereferencing a NULL pointer.
  ------------------------------------------------------------------------*/
  ASSERT( fromaddr != NULL);

  /*-------------------------------------------------------------------------
    Set the socket and ICMP control block pointers, and set the family to
    AF_INET.
  -------------------------------------------------------------------------*/
  icmp_cb_ptr = scb_ptr->protocol_ctl_blk.icb;
  fromaddr->sin_family = AF_INET;
  MSG_LOW("ICMP CB pointer successfully set", 0, 0, 0);

  /*-------------------------------------------------------------------------
    Check if there is anything in the ICMP receive queue. If not, return
    DS_EWOULDBLOCK.
  -------------------------------------------------------------------------*/
  if ( (item_ptr = (dsm_item_type *) q_get( (&(icmp_cb_ptr->rcvq)))) == NULL)
  {
    MSG_LOW("Nothing on ICMP revq", 0, 0, 0);
    *dss_errno = DS_EWOULDBLOCK;
    return (DSS_ERROR);
  }
  MSG_LOW("There is indeed something on the ICMP rcvq", 0, 0, 0);

  /*-------------------------------------------------------------------------
    Extract the payload length, server's IP address and store in fromaddr.  
    ASSERT that bytes to read, are equal to the number of bytes pulled up.
    The port field will be undefined in the fromaddr structure returned to
    the application. 
  -------------------------------------------------------------------------*/
  cnt = dsm_pullup(&item_ptr, &(fromaddr->sin_addr), 
                   sizeof(fromaddr->sin_addr));
  ASSERT( cnt == sizeof(fromaddr->sin_addr) );
  MSG_MED("extracted server's IP %x", fromaddr->sin_addr.s_addr, 0, 0);

  /*-------------------------------------------------------------------------
    Extract the number of bytes which the application wants to read.
  -------------------------------------------------------------------------*/
  payload_len = dsm_length_packet( item_ptr );
  for(i=0;i< iovcount && payload_len > 0 ; i++)
  { 
    /*-----------------------------------------------------------------------
      Extract the number of bytes which the application wants to read.
      -----------------------------------------------------------------------*/
    bytes_requested = MIN( payload_len, iov[i].iov_len);
    if(bytes_requested > 0)
    {
      read_cnt = dsm_pullup( &(item_ptr), iov[i].iov_base, bytes_requested);
    }

    /*-----------------------------------------------------------------------
      ASSERT that we read the expected number of bytes from the buffer.
      -----------------------------------------------------------------------*/
    ASSERT(read_cnt == bytes_requested);
    payload_len -= read_cnt;
    bytes_read += read_cnt;
    read_cnt = 0;
  }
 

  if (payload_len > 0 ) 
  {
    ERR("User provided buffer is smaller than received datagram (%d bytes)",
	bytes_read + payload_len, 0, 0);
  }

  MSG_LOW("Successfully read nbytes of data in DSSICMP_READ", 0, 0, 0);

  /*-------------------------------------------------------------------------
    Free the packet in dsm buffer. 
  -------------------------------------------------------------------------*/
  dsm_free_packet ( &item_ptr );
  MSG_LOW("Packet is successfully freed in DSSICMP_READ", 0, 0, 0);
  
  /*-------------------------------------------------------------------------
    Check if there are any remaining ICMP packets in the receive queue. Set
    the readable flag to FALSE, if there are no remaining ICMP packets.  
    Access to global SCB array item is protected through 
    INTLOCK()/INTFREE().
  -------------------------------------------------------------------------*/
  if ( (item_ptr = (dsm_item_type *) q_check( &(icmp_cb_ptr->rcvq))) == NULL)
  {
    INTLOCK();
    scb_ptr->data_available = FALSE;
    INTFREE();
  }

  /*-------------------------------------------------------------------------
    Convert the server IP address into the Network byte order. 
    Note, only the IP address is in host order, the port number is not.
  -------------------------------------------------------------------------*/
  (fromaddr->sin_addr).s_addr =  dss_htonl( (fromaddr->sin_addr).s_addr);

  /*-------------------------------------------------------------------------
    Return the number of bytes read from the buffer.
  -------------------------------------------------------------------------*/
  MSG_LOW("DONE ICMPREAD", 0, 0, 0);
  return ( (sint15) bytes_read); 

} /* dssudp_read() */
Beispiel #13
0
/*=========================================================================*/
boolean
rbq_dequeue_return (void *rbq, void *item, boolean free)
{
  rbq_buf_desc_type *desc = rbq_cvt_buf2desc (rbq);
  uint8 *buf = NULL;
  rbq_header_type *blk_hdr;
  int iTailIdx;
  int size;
  int blk_length;
  boolean success = FALSE;

  buf = (uint8 *)(desc + 1);

  if (item && desc)
  {
    size = desc->size;

    /* Cast pointer to do arithmetic with rbq_header_type */
    blk_hdr = (rbq_header_type *) item;

    /* Subtract 1 rbq_header_type to get header field */
    blk_hdr -= 1;

    blk_length = blk_hdr->length + sizeof (*blk_hdr) + blk_hdr->pad;

    INTLOCK ();

    ASSERT (blk_hdr->status == RBQ_DEQD_S);

    if (!free)
    {
      //Return to the commit state.
      blk_hdr->status = RBQ_COMMIT_S;
    }
    else
    {
      /* Get the index of the ring buffer's tail */
      iTailIdx = RBQ_CALC_IDX (desc->tail, size);

      if (&buf[iTailIdx] == (uint8 *) blk_hdr)
      {
        /* Move the tail. */
        RBQ_MOVE (desc->tail, blk_length, size);

        success = TRUE;

        /* Sanity check */
        if (RBQ_USED (desc->head, desc->tail, size) > size)
        {
          ERR_FATAL ("RBQ corrupt!", 0, 0, 0);
        }
      }
      else
      {
        ERR_FATAL ("TODO", 0, 0, 0);
      }
    }

    INTFREE ();
  }

  return success;
}
Beispiel #14
0
/*=========================================================================*/
void *
rbq_dequeue (void *rbq, int32 *length)
{
  rbq_buf_desc_type *desc = rbq_cvt_buf2desc (rbq);
  int size;
  uint8 *buf = NULL;
  rbq_header_type *blk_hdr;	/* Pointer to the header of the buffer. */
  void *item = NULL;
  int iTailIdx;			/* Byte array index to tail of diag ring buffer */
  rbq_status_enum_type status;
  boolean found = FALSE;

  buf = (uint8 *)(desc + 1);

  if (desc)
  {
    size = desc->size;

    INTLOCK ();

    /* Get the index of the ring buffer's tail */
    iTailIdx = RBQ_CALC_IDX (desc->tail, size);
    
    /* Walk down the tail until action can be determined. */
    do
    {
      blk_hdr = (rbq_header_type *) (buf + iTailIdx);

      status = (rbq_status_enum_type)blk_hdr->status;

      if (RBQ_EMPTY (desc->head, desc->tail) ||
          status == RBQ_UNCOMMIT_S)
      {
        break;
      }
      else if (status == RBQ_COMMIT_S)
      {
        found = TRUE;
        blk_hdr->status = RBQ_DEQD_S;
      }
      else if (status == RBQ_WRAP_S)
      {
        RBQ_WRAP (desc->tail, size);
        iTailIdx = RBQ_CALC_IDX (desc->tail, size);
        continue;
      }
      else if (status == RBQ_HOLE_S)
      {
        blk_hdr->status = RBQ_FREE_S;

        RBQ_MOVE (desc->tail, 
          (int)(blk_hdr->length + sizeof (*blk_hdr) + blk_hdr->pad), size);

        iTailIdx = RBQ_CALC_IDX (desc->tail, size);
        continue;
      }
      else if (status == RBQ_DEQD_S)
      {
        //Item already dequeued.  Return failed.
        item = NULL;
        break;
      }

      //If uncommitted, return

    } while (!found);

    INTFREE ();

    if (found)
    {
      item = (void *) (blk_hdr + 1);

      if (length)
      {
        *length = blk_hdr->length;
      }
    }
  }				/* if start of new packet */

  return item;
}
Beispiel #15
0
/*===========================================================================

FUNCTION RBQ_ALLOC

DESCRIPTION
  This function allocates the specified amount of space in the diag
  output buffer.

DEPENDENCIES
  rbq_commit(), or diagbuf_shorten(0), must be called to commit/return an
  item to the RBQ system.

============================================================================*/
void *
rbq_alloc (void *rbq, int length)	//, int nice)
{
  rbq_buf_desc_type *desc = rbq_cvt_buf2desc (rbq);
  int size;
  uint8 *buf = NULL;
  int blk_length;		//includes overhead
  rbq_header_type *blk_hdr = NULL;
  void *item = NULL;

  /* Local indices to manipulate buffer */
  int iHead;
  int iHeadIdx;
  int iTail;
  int iTailIdx;

  if (desc)
  {
    size = desc->size;
    buf = (uint8 *) (desc + 1);

    blk_length = (int)(sizeof (rbq_header_type) + (uint32)length + sizeof (uint16));

    blk_length = (int)RBQ_NEXT_ALIGNED_BYTE(blk_length);

    /*-------------------------------------------------
      To avoid critical section for tail, read once
      and use that value.  This operation is atomic.
    -------------------------------------------------*/
    iTail = desc->tail;
    iTailIdx = RBQ_CALC_IDX (iTail, size);

    INTLOCK ();

    iHead = desc->head;
    iHeadIdx = RBQ_CALC_IDX (iHead, size);

    blk_hdr = ((rbq_header_type *) & buf[iHeadIdx]);

    /* First check if the nice pad is available.  If OK, then alloc */
    if (RBQ_BALANCE_PAD + nice < RBQ_FREE (iHead, iTail, size))
    {
      /* if not wrapped and no room here. */
      if (iTailIdx <= iHeadIdx &&	/* Not wrapped &&  */
	  iHead - iTail < size &&	/* Not full &&     */
	  /* No room here!   */
	  iHeadIdx + blk_length >= size)
      {

	/* Mark header for wrap */
	blk_hdr->status = RBQ_WRAP_S;

	/* Wrap */
	RBQ_WRAP (iHead, size);

	/* Recalculate head index */
	iHeadIdx = RBQ_CALC_IDX (iHead, size);
      }

      if (blk_length <= RBQ_FREE (iHead, iTail, size))
      {
	/* Move head */
	RBQ_MOVE (iHead, blk_length, size);

	/* Update value of global head index */
	desc->head = iHead;

	/* Sanity check */
	if (RBQ_USED (iHead, iTail, size) > size)
	{
	  ERR_FATAL ("Ring buffer currupt!", 0, 0, 0);
	}

	/* Set header field of buffer */
	blk_hdr = ((rbq_header_type *) & buf[iHeadIdx]);

	blk_hdr->status = RBQ_UNCOMMIT_S;
	blk_hdr->pad = (uint8) ((uint32)blk_length - (uint32)length -
		sizeof (rbq_header_type));
	blk_hdr->length = (uint16)length;

	/* Set 'ptr' to the byte following the header */
	item = blk_hdr + 1;
      }
    }				/* If requested length + nice pad is free */

    INTFREE ();

    if (item)
    {
      (void) rbq_write_ovrn_pattern (blk_hdr);
    }

  }
  return item;
}				/* rbq_alloc */
Beispiel #16
0
BOOL DMAFlushChannelBuff(UINT32 uDMACh)
{
   UINT32 OldLevel = 0;
   register BOOL bReturn = FALSE;

   /* Need to turn off interrupts here since background task is modifying a */
   /* variable that is accessible also from interrupt context. */
   OldLevel = INTLOCK();

   switch ( uDMACh )
   {
      case DMA_CHANNEL_USB_TX_EP0 : /* 13 */
      case DMA_CHANNEL_USB_TX_EP1 : /* 11 */
      case DMA_CHANNEL_USB_TX_EP3 : /* 9  */
      case DMA_CHANNEL_USB_TX_EP2 : /* 10 */
      case DMA_CHANNEL_USB_RX_EP0 :
      case DMA_CHANNEL_USB_RX_EP1 :
      case DMA_CHANNEL_USB_RX_EP2 :
      case DMA_CHANNEL_USB_RX_EP3 :
         break;

      case DMA_CHANNEL_M2M_IN :
      case DMA_CHANNEL_M2M_OUT:
         break;

  #if DSL_DMA
     case DMA_CHANNEL_DSL_TX :			/* 5 */
        if (DSLInfo.bTXWA)
        {
           if ( (DSLInfo.TxPendingInc != 0) && (DSLInfo.bTxSendMode == FALSE) )
           {
              DSLInfo.TxTotalPending += DSLInfo.TxPendingInc;
              *pDSL_TXCC_DMA = DSLInfo.TxPendingInc;	/* # of TX block  to be sent */
              DSLInfo.TxPendingInc = 0;
	            DSLInfo.bTxSendMode = TRUE;
	            bReturn = TRUE;
           }
        }

        else if (DSLInfo.TxPendingInc)
        {
           DSLInfo.TxTotalPending += DSLInfo.TxPendingInc;
           *pDSL_TXCC_DMA = DSLInfo.TxPendingInc;	/* # of TX block  to be sent */
           DSLInfo.TxPendingInc = 0;
           DSLInfo.bTxSendMode = TRUE;
           bReturn = TRUE;
        }
        break;

     case DMA_CHANNEL_DSL_RX :
  #endif

      case DMA_CHANNEL_EMAC1_TX :
      case DMA_CHANNEL_EMAC2_TX :
      case DMA_CHANNEL_EMAC1_RX :
      case DMA_CHANNEL_EMAC2_RX :
      default :
         break;
   }

   INTUNLOCK(OldLevel);
   return bReturn;
}