/* * 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; }
/*=========================================================================== 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(); }
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(); }
/*=========================================================================== 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() */
/*=========================================================================== 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; }
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; }
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; }
/*=========================================================================== 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() */
/*=========================================================================== 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() */
/*=========================================================================== 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); } }
/* ** 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); }
/*=========================================================================== 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() */
/*=========================================================================*/ 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; }
/*=========================================================================*/ 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; }
/*=========================================================================== 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 */
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; }