GLAST / LAT > DAQ and FSW > FSW > Doxygen Index> LCBD / dev > lcbd / sun-gcc


Interface   Data Structures   File List   Data Fields   Globals  

LCBD_evt.c File Reference

Implements the LCB Node-to-Node communication routines. More...

#include <LCBD/LCBD_evt.h>
#include <LCBD/LCBD_msgs.h>
#include <LCBD/LCBC.h>
#include <LCBD/LCB.h>
#include <LCBD/LCB_cr.h>
#include <LCBD_p.h>
#include <PBS/INT.ih>

Classes

struct  _LCBD_evt_err_maps
 Maps to take an event transfer/receive error/status value, into a standard message code. More...

Defines

#define _DUMP_EVT(_title, _evt, _cnt)
 Debugging macro to dump the first _cnt words of the event message.

Typedefs

typedef struct _LCBD_evt_err_maps LCBD_evt_err_maps
 Typedef for struct _LCBD_evt_err_maps.

Functions

static __inline void lcbd_stats_evt_proto_xct_add (LCBD_stats_evt_proto_xct *xct, unsigned int nwrds)
 Increments the event protocol transaction record statistics.
unsigned int LCBD_evt_cb_set (LCBD lcb, unsigned int proto, LCBD_evt_cb cb, void *prm)
 Sets the event data callback routine and parameter for the specified LATp protocol.
LCBD_evt_cbp LCBD_evt_cbp_get (LCBD lcb, unsigned int proto)
 Retrieves the event data callback routine and parameter for the specified LATp protocol.
unsigned int LCBD_evt_conds_set (LCBD lcb, unsigned int conditions)
 Sets the interrupt conditions for the EVENT FIFO and EVENT ring buffer.
unsigned int LCBD_evt_err_cb_set (LCBD lcb, LCBD_evt_err_cb cb, void *prm)
 Establish callback for event transport errors.
LCBD_evt_err_cbp LCBD_evt_err_cbp_get (LCBD lcb)
 Returns the callback routine for the event transport error handler plus its parameter.
unsigned int LCBD_evt_enable (LCBD lcb, int enable)
 Enables/Disables the flow of events into the LCB.
unsigned int LCBD_evt_handler_create (LCBD lcb, int priority)
 Creates the event que handler service task.
unsigned int LCBD_evt_que_install (LCBD lcb, FORK_que *que)
 Installs queue from fcb as the ISR -> task message queue for event traffic.
FORK_que * LCBD_evt_que_get (LCBD lcb, int que_id)
 Returns a pointer to the event FORK que. This allows outside code to schedule work that is serialized with the event taking.
LCBD_evt_que_state LCBD_evt_tickle (LCBD lcb)
 Callable version of the LCBD ISR.
unsigned int LCBD_evt_rcv_err_map (unsigned int err)
 Maps a receive error to a standard LCB message code.
unsigned int LCBD_evt_xfr_err_map (unsigned int err)
 Maps a event transfer error code to a standard LCB message code.
unsigned int LCBD_evt_free (LCBD lcb, LCBD_evt *evt)
 Frees the a LCBD_evt.
unsigned int LCBD_evt_rng_free (LCBD lcb, LCBD_evt *from, LCBD_evt *to)
 Frees the LCBD_evts from to to exclusively, i.e. excludes the memory associated with to.
FORK_cb_status lcbd_evt_handler (FORK_cb_prm parameter, FORK_msg_hdr *fork_msg)
 The main LCBD descriptor dispatching routine for event traffic.

Variables

static const LCBD_evt_err_maps LCBD_Evt_Err_Maps
 Realization of LCB event error to message code mapping arrays.


Detailed Description

Implements the LCB Node-to-Node communication routines.

Author:
Curt Brune -- curt@slac.stanford.edu

JJRussell -- russell@slac.stanford.edu

  CVS $Id
This file implements routines for handling the traffic on the event fabric. Both Curt and I struggled over what to name these routines. We both shyed away from event because it is so overloaded. Curt initially tried using the term bulk, but this seemed strained, particularly since the word bulk is not a noun. Hence one say in the initial version of the code that the object manipulated by these routines was called LCB_bulk_msg.
In the end I decided to live with the overloaded term event, since afterall, that what these routines do, they deal with data on the Event Fabric.

Define Documentation

#define _DUMP_EVT ( _title,
_evt,
_cnt   ) 

Debugging macro to dump the first _cnt words of the event message.

This macro active iff the symbol LCBD_DEBUG is defined


Function Documentation

unsigned int LCBD_evt_cb_set ( LCBD  lcb,
unsigned int  proto,
LCBD_evt_cb  cb,
void *  prm 
)

Sets the event data callback routine and parameter for the specified LATp protocol.

Return values:
LCBD_OK,on success
LCBD_INVPROTO,invalid protocol, if proto is greater than the maximum
Parameters:
lcb Pointer to private LCBD structure
proto LATp protocol to associate queue with.
cb Event data callback routine (event handler)
prm Evevt data callback routine parameter protocol number.
See also:
LCBD_evt_cb_get()
Overview
This function sets the event data callback routine and associated user parameter for the specified LATp protocol proto.
Undefined Protocol
In addition to the hardware defined protocols of 0-3, the LCBD driver also supports an undefined protocol, LCBD_EVT_PROTO_UNDEFINED (4), which gets call backed in the rare circumstance that the LATp cell header has a parity error and, therefore, the driver is unable to determine the protocol.

References LCBD_EVT_PROTO_CNT, and LCBD_OK.

LCBD_evt_cbp LCBD_evt_cbp_get ( LCBD  lcb,
unsigned int  proto 
)

Retrieves the event data callback routine and parameter for the specified LATp protocol.

Returns:
A structure containing the event callback handler and its parameter for the specified protocol If the protocol is invalid, NULLs are returned
Parameters:
lcb Pointer to private LCBD structure
proto LATp protocol to associate queue with.
See also:
LCBD_evt_cb_set()
This function retrieves the event data callback routine and associated user parameter for the specified LATp protocol proto.

unsigned int LCBD_evt_conds_set ( LCBD  lcb,
unsigned int  conditions 
)

Sets the interrupt conditions for the EVENT FIFO and EVENT ring buffer.

Return values:
The interrupt conditions before modification
Parameters:
lcb Pointer to private LCBD structure
conditions A word reflecting the desired interrupt conditions
The conditions paramete may be either composed using the LCBD_EVT_CONDS_COMPOSE macro or may be the return value of this function, effectively restoring a previous state.
Example
To set the event que interrupt condition at 50% full and the event buffer interrupt condition at 25% full
    new = LCBD_EVT_CONDS_COMPOSE (LCBD_M_EVT_COND_50_FULL,
                                 LCBD_M_EVT_COND_25_FULL);
    prv = LCBD_evt_cond_set (lcb, new);


    // Do somethings, then restore
    prv = LCBD_evt_cond_set (lcb, prv);

References LCB_PCI_CSR_M_IRQEVTQUE, LCB_PCI_CSR_V_IRQEVTQUE, LCBD__pciLoad32(), and LCBD__pciStore32().

unsigned int LCBD_evt_enable ( LCBD  lcb,
int  enable 
)

Enables/Disables the flow of events into the LCB.

Return values:
0,Event enable was not set before this call
1,Event enable was set before this call
Anything else, an LCBD error
Parameters:
lcb The LCB driver handle
enable Enable (1) / Disable (0) flag
This function enables or disables the flow of events into the LCB. Technically it sets the state of the evtEnable field in the LAT side CSR.
Since this function sets a field in the LAT side CSR register, it must use the command/response unit, not a simple PCI memory write. The function is written such that it will function if the result unit interrupts are enabled (in interrupt mode) or if they are disabled (polled mode). If this function is used in polled mode, the LCB result unit must be empty. Executing this function in this intermediate state is considered a programming error and the result is that not only will this function fail, but any pending results will also be lost.
This is not as onerous as the explanation would seem to imply. This function will must likely be called either before interrupts are enabled or after. It is unlikely that one will enable the result interrupt, submit some command/response transactions, then disable the result interrupt before the transactions complete.

References _LCB_csr::bf, _LCB_csr_bf::evtEnable, LCB_CSR_M_EVT_ENABLE, LCB_CSR_V_EVT_ENABLE, lcbd_csr_access(), LCBD_K_INTERNAL_OP_STALL, and _LCB_csr::ui.

unsigned int LCBD_evt_err_cb_set ( LCBD  lcb,
LCBD_evt_err_cb  cb,
void *  prm 
)

Establish callback for event transport errors.

Return values:
LCBD_OK 
Parameters:
lcb The LCB driver handle
cb The LCB event error handler
prm The LCB event error parameter

LCBD_evt_err_cbp LCBD_evt_err_cbp_get ( LCBD  lcb  ) 

Returns the callback routine for the event transport error handler plus its parameter.

Returns:
The callback routine plus it parameter
Parameters:
lcb The LCB driver handle

unsigned int LCBD_evt_free ( LCBD  lcb,
LCBD_evt evt 
)

Frees the a LCBD_evt.

Parameters:
lcb Pointer to private LCBD structure
evt pointer to LCBD_evt to free
Returns:
LCBD_OK on success
This function returns memory to the LCB circular buffer. Typically this is called by an event handler after processing an event. It is necessary to call this routine if and only if the user event call back routine does not return LCBD_EVT_FATE_M_NO_FREE. Otherwise the event handler, itself, will perform this function.

References _LCB_evt_dsc::bf, _LCBD_evt_hdr::dsc, _LCBD_evt::hdr, LCBD_evt_rng_free(), and _LCB_evt_dsc_bf::len.

Referenced by lcbd_evt_handler().

FORK_cb_status lcbd_evt_handler ( FORK_cb_prm  parameter,
FORK_msg_hdr *  fork_msg 
)

unsigned int LCBD_evt_handler_create ( LCBD  lcb,
int  priority 
)

Creates the event que handler service task.

Returns:
Status
Parameters:
lcb The LCBD driver handle
priority The priority of the task. If specified as 0, then a default value is assigned.

References lcbd_create_handler(), and LCBD_EVT_K_DEFAULT_PRIORITY.

FORK_que * LCBD_evt_que_get ( LCBD  lcb,
int  que_id 
)

Returns a pointer to the event FORK que. This allows outside code to schedule work that is serialized with the event taking.

Parameters:
lcb Pointer to private LCBD structure
que_id The ID of the que to get. Currently LCBD is configured with only one que (que_id = 0), but a future enhancement will allow LCBD to be configured with a priority que.
Returns:
On success. a pointer to the event FORK que. This will be NULL if the FORK que has not yet been installed.

unsigned int LCBD_evt_que_install ( LCBD  lcb,
FORK_que *  que 
)

Installs queue from fcb as the ISR -> task message queue for event traffic.

Parameters:
lcb Pointer to private LCBD structure
que The FORK que to use
Return values:
LCBD_OK,on success; currently there is no failure mode
Example
  TASK_attr attributes;
  int                         que_cnt = 3;
  static const FORK_que_cfg QueCfg[3] = {{ NULL, NULL, NULL, 0},
                                         { NULL, NULL, NULL, 0},
                                         { NULL, NULL, NULL, 0} };


  // Fill out the task attribute information
  attributes.options    = 0;
  attributes.stack_addr = 0;
  attributes.stack_size = 0;
  attributes.name       = "tLCBDevent";
  attributes.priority   = 61;


  // Allocate enough memory to support the FORK task
  fcb  = (FORK_fcb *)MBA_alloc(FORK_fcb_sizeof(que_cnt));


  // Create FORK queue
  status = FORK_create(fcb,            // fork control block
                       &attributes,    // use task attributes
                       NULL,           // default callback
                       lcb,            // callback parm
                       NULL,           // timeout callback parm
                       TOC_FOREVER,    // timeout
                       3,              // define a priority list with 3 queues
                       QueCfg,         // Queue configuration
                       0,              // No system messages
                       NULL,           // No system messages
                       0);             // No system messages

  // Locate the que to use and install it
  que    = FORK_que_get (1);
  status = LCBD_evt_que_install (lcb, que);

References LCBD_OK.

unsigned int LCBD_evt_rcv_err_map ( unsigned int  err  ) 

Maps a receive error to a standard LCB message code.

Returns:
The LCB message code
Parameters:
err The receive error to map

References _LCBD_evt_err_maps::rcv.

unsigned int LCBD_evt_rng_free ( LCBD  lcb,
LCBD_evt from,
LCBD_evt to 
)

Frees the LCBD_evts from to to exclusively, i.e. excludes the memory associated with to.

Parameters:
lcb Pointer to private LCBD structure
from The pointer to where the freeing should begin
to The pointer to the next free location
Returns:
LCBD_OK on success Frees theLCBD_evt
This function returns memory to the LCB circular buffer and is used when more than one event at a time is being freed. This would typically be used when processing a sequence of truncated packets, then freeing the lot as a unit.
Warning:
the LCB can only free in units of 32-bit words. Therefore it the two lower bits of the addresses to and from must be clear. This will naturally be true if from and to are really LCBD_evs. While one can make this work if from and to are not LCBD_evts, it is not recommended.
Note:
Timing Information This routine was originally implemented using a MTX lock. Timing measurements indicated that this was not real hot when one is looking for usecond type performance. This was changed to effectively an INT lock. For comparison, a base line doing only a PCI write to the free register was performed (no statistics, no looping, just the write. The times are
  • ~1.0 usecs, Baseline
  • ~2.0 usecs, INT lock
  • ~4.0 usecs, MTX implementation

The mutex was thought to be necessary to guard against spending an inordinate amount of time in the loop that scans for the next free packet. While in principle this could be a problem, in reality it shouldn't be. The loop only becomes a loop when there is a lot of out-of-order freeing. So far, no application has resorted to this.
Bottom Line
I'll leave it with the INT lock and perhaps revisit this later. The freeing time is really only a problem for event traffic. One could go back to the MTX and free events in bundles, say 10 at a time. That would reduce the overhead to .4usecs, but could result in out-of-order freeing, but the routine can cope with that.

References _LCBD_evt_hdr::fsw, _LCBD_evt::hdr, LCB_EVENT_BUFFER_ALIGN, LCB_EVENT_BUFFER_SIZE, LCBD__pciStore32(), LCBD_OK, lcbd_stats_evt_proto_xct_add(), msr_clr(), msr_get(), and msr_put().

Referenced by LCBD_evt_free().

LCBD_eventq_state LCBD_evt_tickle ( LCBD  lcb  ) 

Callable version of the LCBD ISR.

Parameters:
lcb Pointer to private LCBD structure
Return values:
LCBD_EVT_QUE_STATE_BUSY 
LCBD_EVT_QUE_STATE_POSTED 
LCBD_EVT_QUE_STATE_EMPTY 
This routine can be used to kick off the LCB FIFO processing, just as if an interrupt went off. This could be used to ensure the event descriptor FIFO is drained periodically during periods of low event rate where the event FIFO high water mark would otherwise prevent an interrupt from being asserted in a timely fashion.

References _LCB_evt_dsc::bf, _LCBD_stats_evt_tickle::cnts, _LCB_prb::event_queue, _LCB_prb::irq, LCB_EVT_ERR_XFR_Q_EMPTY, LCB_PCI_IRQ_M_DISABLE_EVENT, LCBD__pciLoad32(), LCBD__pciStore32(), lcbd_evt_handler(), LCBD_EVT_QUE_STATE_BUSY, LCBD_EVT_QUE_STATE_EMPTY, LCBD_EVT_QUE_STATE_POSTED, LCBD_STATS_EVT_TICKLE_K_BUSY, LCBD_STATS_EVT_TICKLE_K_EMPTY, LCBD_STATS_EVT_TICKLE_K_POSTED, _LCB_evt_dsc::ui, and _LCB_evt_dsc_bf::xstatus.

unsigned int LCBD_evt_xfr_err_map ( unsigned int  err  ) 

Maps a event transfer error code to a standard LCB message code.

Returns:
The LCB message code
Parameters:
err The transfer error code to map

References _LCBD_evt_err_maps::xfr.

static __inline void lcbd_stats_evt_proto_xct_add ( LCBD_stats_evt_proto_xct xct,
unsigned int  nwrds 
) [static]

Increments the event protocol transaction record statistics.

Parameters:
xct The event protocol transaction record to update
nwrds The number of words in this transaction
Note:
Tried to implement this with a lmw and stmw, but could not get it to compile correctly. When compiled as a separate routine (not inline'd), the clobbered registers specified as the 3rd grouping in the register layout) were correctly saved. But when compiled as an inline, the registers were not saved, wiping out what was once in r29,r30 and r31. So I gave up..

References _LCBD_stats_evt_proto_xct::cnts, and _LCBD_stats_evt_proto_xct::nwrds.

Referenced by lcbd_evt_handler(), and LCBD_evt_rng_free().


Variable Documentation

unsigned int LCBD_Evt_Err_Maps [static]

Initial value:

{                   
    {               
     0,             
     LCBD_EOPCIMA,  
     LCBD_EOPCIPE,  
     LCBD_EOPCITA,  
     LCBD_EOUND4,   
     LCBD_EOBUFEMP, 
     LCBD_EOUND6,   
     LCBD_ROQEMPTY, 
    },

    {               
     0,             
     LCBD_EIUND1,   
     LCBD_EIDPERR,  
     LCBD_EITRUNC,  
    }
}
Realization of LCB event error to message code mapping arrays.


Generated on Thu Mar 24 19:06:42 2011 by  doxygen 1.5.8