GLAST/LAT > DAQ and FSW > FSW > Doxygen Index > LCBD / V1-4-3

Constituent: lcbd     Tag: rad750


Interface   Data Structures   File List   Data Fields   Globals  

LCBD_evt.h File Reference

Defines public aspects of the event unit of the LCB driver. More...

#include "LCBD/LCB.h"
#include "LCBD/LATP.h"

Include dependency graph for LCBD_evt.h:

This graph shows which files directly or indirectly include this file:


Data Structures

struct  _LCBD_evt_hdr
 Layout of 8 padding words that precede an unsolicited event. More...
struct  _LCBD_evt
 Layout of an unsolicited data received on the event fabric. More...
struct  _LCBD_evt_cbp
 Binds an event call back routine with its parameter. More...
struct  _LCBD_evt_err_cbp
 Binds an event error handler call back routine with its parameter. More...

Defines

#define LCBD_OK   0
 Success return code, note that this is not an LCBD message code, but may be used as one.
#define LCBD_EVT_K_DEFAULT_PRIORITY   -1
 Instructs the event service task creation routine LCBD_evt_handler_create to use a system defined default priority.
#define LCBD_EVT_PROTO_CNT   ( LCB_EVT_PROTO_CNT + 1)
 The LCBD driver keeps track of the known LCB protocols + reserves one spot for unknown protocols.
#define LCBD_EVT_PROTO_UNDEFINED   (LCBD_EVT_PROTO_CNT - 1)
 Defines the 'undefined protocol.

Typedefs

typedef enum _LCBD_EVT_COND LCBD_EVT_COND
 Typedef for enum _LCB_EVT_COND.
typedef enum _LCBD_EVT_QUE_STATE LCBD_EVT_QUE_STATE
 Typedef for enum _LCBD_EVT_QUE_STATE.
typedef enum _LCBD_EVT_QUE_STATE LCBD_evt_que_state
 Typedef for enum _LCBD_EVT_QUE_STATE.
typedef _LCBD_evt_hdr LCBD_evt_hdr
 typedef for struct _LCBD_evt_hdr
typedef _LCBD_evt LCBD_evt
 typedef for struct _LCBD_evt
typedef enum _LCBD_EVT_FATE_M LCBD_EVT_FATE_M
 Typedef for enum _LCBD_EVT_FATE_M.
typedef unsigned int(* LCBD_evt_cb )(void *prm, unsigned int dsc, LCBD_evt *evt)
 Typedef for LCBD event handling callback routine.
typedef _LCBD_evt_cbp LCBD_evt_cbp
 Typedef for struct _LCBD_evt_cbp.
typedef unsigned int(* LCBD_evt_err_cb )(void *prm, unsigned int ed, LCBD_evt *evt)
 Typedef for LCBD event error handling callback routine.
typedef _LCBD_evt_err_cbp LCBD_evt_err_cbp
 Typedef for struct _LCBD_evt_err_cbp.

Enumerations

enum  _LCBD_EVT_COND {
  LCBD_EVT_COND_75_FULL = 0x0,
  LCBD_EVT_COND_50_FULL = 0x1,
  LCBD_EVT_COND_25_FULL = 0x2,
  LCBD_EVT_COND_NOT_EMPTY = 0x3
}
 Enumerates the Interrupt Request conditions of both the event queue. More...
enum  _LCBD_EVT_QUE_STATE {
  LCBD_EVT_QUE_STATE_EMPTY = -1,
  LCBD_EVT_QUE_STATE_POSTED = 0,
  LCBD_EVT_QUE_STATE_BUSY = 1
}
 Describes the current state of event queue. More...
enum  _LCBD_EVT_FATE_M {
  LCBD_EVT_FATE_M_NO_MORE = (1 << 0),
  LCBD_EVT_FATE_M_NO_REARM = (1 << 1),
  LCBD_EVT_FATE_M_NO_FREE = (1 << 2),
  LCBD_EVT_FATE_M_NO_PROCESS = (1 << 3),
  LCBD_EVT_FATE_M_ABORT
}
 Bit masks defining the options available on the return values of the event callback routine. More...

Functions

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 Frees theLCBD_evt.

Detailed Description

Defines public aspects of the event unit of the LCB driver.

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

JJRussell -- russell@slac.stanford.edu

  CVS $Id

Define Documentation

#define LCBD_EVT_K_DEFAULT_PRIORITY   -1
 

Instructs the event service task creation routine LCBD_evt_handler_create to use a system defined default priority.

This value can be used instead of a fixed numerical value to the aforementioned routines so that the tasks are created with default priorities. Note that this is only a flag value and that the default priorities are owned by the LCBD code. This means that if a new version of the driver changes these values, all code using the default values will also change. In many cases, this is exactly the correct behaviour, but in a limited number of cases (peculiar test circumstances), the user may wish tighter control. In these cases, use a fixed numerical value between 0 and 255.


Typedef Documentation

unsigned int(* LCBD_evt_cb)(void *prm, unsigned int dsc.LCBD_evt *evt)
 

Typedef for LCBD event handling callback routine.

Returns:
A bit list of options enumerated by LCBD_EVT_FATE_M
Parameters:
prm User provided parameter
dsc The event descriptor as an uninterpreted unsigned int. Likely the only thing valuable in here is the status.
evt Pointer to the event data. This contains the length of the event as well as the data itself
Usage
This is the user callback routine to handle traffic coming in on the event fabric. The user must completely handle the event in the callback routine, since it will be freed when this routines returns control to the event handler.
Return Options
Normally this routine should return 0, but for testing and debugging purposes, it may return a bit list of the options enumerated in LCBD_EVT_FATE_M. The options currently include
  • LCBD_EVT_FATE_M_NO_MORE, stop servicing the event que, whether it is empty or not
  • LCBD_EVT_FATE_M_NO_REARM, don't rearm the interrupt
  • LCBD_EVT_FATE_M_NO_FREE, don't free the event.

Each of these demands some thought in their usage
NO_MORE Option
When specifying this, the user will also likely disable the event interrupts. If the interrupts are not disabled and there are more pending event descriptors in the que, the interrupt will just immediately fire and, bang, you're back into the event handler again.
NO_REARM Option
Since, in the callback handler, it is unknown whether this is the last event descriptor to be serviced or not, one must either
  • Return this everytime
  • Return this option + the NO_MORE option
NO_FREE
Since there is no out of order freeing allowed, the user is obligated to maintain enough information to do the freeing in order.
This option has two legitimate uses. The first would allow a few events to accumulate before freeing, thus saving some CPU cycles in doing the free at the expense of tying up the event circular buffer. This is a bit esoteric, but, it works. The second is more mainstream. This happens when a packet is truncated. In those cases, the only option is to defer the freeing of the event until you get enough of the packet to satisfy your needs. In the most trivial example where one wishes to analyze the whole event without making a copy as you go, you defer the freeing of the event subpackets until the last one is received.
Warning:
Be very careful in using the NO_FREE option. If one does not reduce the memory occupied in the circular buffer to below the interrupt threshold (NON-EMPTY, 25% full, 50% full, 75% full), the interrupt will immediately refire. Once in this condition, there is no event descriptor available and the event handler will just dismiss the interrupt without calling back the user. So, unless something asynchronously starts freeing events, one will be caught in an infinite loop.
Note:
There is a cute programming trick one can use to gracefully stop the processing on both the result que and the event que and disable further processing on both. One can send a message to yourself that the receiver reacts to by returning NO_MORE and NO_REARM. In addition, the result list handler can do the same on the result handler.

LCBD_EVT_COND
 

Typedef for enum _LCB_EVT_COND.

These values are used as the argument to LCBD_evt_conds_set
Note:
To avoid including the LCB defintions in a lot of user code, these definitions duplicate their values here. However, in LCBD_evt.c there exists a compile time check that these values are, indeed, the same.

unsigned int(* LCBD_evt_err_cb)(void *prm, int unsigned int ed, LCBD_evt *evt)
 

Typedef for LCBD event error handling callback routine.

Returns:
A bit list of options enumerated by LCBD_EVT_FATE_M
Parameters:
prm User provided parameter
ed The event descriptor
evt The event.
About LCB errors
The LCB is constructed such that there are only 2 user handable errors. The first is the obvious, EVENT QUEUE empty. The other is PACKET TRUNCATED. Neither of these are passed through the error handlers.
The consequences of EVENT QUEUE empty are simple, the event handler stops processing.

The PACKET TRUNCATED events are passed to the normal user callback handlers where the user is expected to handle packet reassembly in a manner appropriate to his processing needs.

Any other errors are really serious hardware errors. Continued use of the LCB device is at the user's peril. However, rather than simply bugchecking the system, a callback routine is provided to allow the user to handle this error condition. The recommended action is to put your house in order with a minimum of fuss (naturally this means no LCB accesses) and shut the system down as gracefully as possible.

Return Options
Normally the error routine should return
      LCBD_EVT_FATE_M_NO_FREE  |   // Don't free this event descriptor
      LCBD_EVT_FATE_M_NO_MORE  |   // Don't process anymore event descriptors
      LCBD_EVT_FATE_M_NO_REARM |   // Don't rearm the event interrupt
      LCBD_EVT_FATE_M_NO_PROCESS   // Don't process the event with the
                                      normal user callback routine.
This collection of options is summarized as LCBD_EVT_FATE_M_ABORT. Returning other values is at your own peril.
Warning:
While the parameter evt always points at the event packet, the integrity of the data is determined by the status tucked away in the event descriptor.

LCBD_evt_err_cbp
 

Typedef for struct _LCBD_evt_err_cbp.

All event descriptors with fatal hardware receive/transmit errors are funneled through this callback for user action. Naturally, these events are not expected to occur, but this a clean mechanism for moving the error handling outside the context of the driver.

LCBD_EVT_FATE_M
 

Typedef for enum _LCBD_EVT_FATE_M.

Usage
The user can control the event processing loop in event handler by specifying the return value as a bit list of the options enumerated here. For the most part, their usage is likely confined to testing and debugging. Normally the event callback should just return 0.

LCBD_evt_hdr
 

typedef for struct _LCBD_evt_hdr

Note:
Code in LCBD_evt.c enforces, at compile time, that the size of this structure is LCB_EVT_PAD_SIZE.

LCBD_evt_que_state
 

Typedef for enum _LCBD_EVT_QUE_STATE.

This value is returned by LCBD_evt_tickle.


Enumeration Type Documentation

enum _LCBD_EVT_COND
 

Enumerates the Interrupt Request conditions of both the event queue.

Enumerator:
LCBD_EVT_COND_75_FULL  Interrupt condition -- 75% full
LCBD_EVT_COND_50_FULL  Interrupt condition -- 50% full
LCBD_EVT_COND_25_FULL  Interrupt condition -- 25% full
LCBD_EVT_COND_NOT_EMPTY  Interrupt condition -- NOT empty

enum _LCBD_EVT_FATE_M
 

Bit masks defining the options available on the return values of the event callback routine.

See also:
LCBD_evt_cb
Enumerator:
LCBD_EVT_FATE_M_NO_MORE  Stop processing transactions
LCBD_EVT_FATE_M_NO_REARM  Don't rearm the interrupt
LCBD_EVT_FATE_M_NO_FREE  Don't free the event
LCBD_EVT_FATE_M_NO_PROCESS  Don't process the event, applicable only for error handler
LCBD_EVT_FATE_M_ABORT  Convenience symbol, since this is the most common return value from the error routine

enum _LCBD_EVT_QUE_STATE
 

Describes the current state of event queue.

Enumerator:
LCBD_EVT_QUE_STATE_EMPTY  The event queue was found empty
LCBD_EVT_QUE_STATE_POSTED  An event was found non-empty and the first event was posted to the event handling task
LCBD_EVT_QUE_STATE_BUSY  The event handling task is currently processing the event queue, so there is no reason to wake the event handling task, it is not asleep


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.

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);

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.

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.

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.

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);

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

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 Frees theLCBD_evt.

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
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.

LCBD_evt_que_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.

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


Generated on Thu Jun 14 08:57:52 2007 by  doxygen 1.4.4