/**
 * @file avmaic_misc.h
 *
 * AvmAic-Misc - Helper functions for AVM active controllers.
 *
 * Copyright: 2000-2003 Thomas Wintergerst. All rights reserved.
 *
 * $FreeBSD$
 * $Id: avmaic_misc.h,v 1.1.2.1 2006/02/28 21:35:07 thomas Exp $
 * Project  CAPI for BSD
 * Target   avmaic - CAPI manager driver for AVM active ISDN controllers
 * @date    01.01.2000
 * @author  "Thomas Wintergerst" <twinterg@gmx.de>
 * <p>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * </p>
 */

#ifndef __AVMAIC_MISC_H
#define __AVMAIC_MISC_H

#include <sys/types.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/endian.h> /* htole32(), le32toh() */
#include <c4b/avmaic/avmaic_var.h>





/* === public declarations =============================================== */





/* --- some strings for the [ta]sleep call --- */

#define AVMMISC_WAIT_FOR_RESULT_MSG             "wait for ctlr result"
#define AVMMISC_WAIT_FOR_CTLR_ACCESS_MSG        "wait for ctlr access"
#define AVMMISC_WAIT_FOR_RECEIVE_INIT_MSG       "wait for ctlr initialization"
#define AVMMISC_WAIT_FOR_RECEIVE_POLL_MSG       "wait for receive-poll"



/* --- some strings for synchronisation objects --- */

#define AVMMISC_ACCESS_MUTEX_MSG        "avmaic access mutex"
#define AVMMISC_NOTIFY_CONDITION_MSG    "avmaic notify condition"



/* --- some helper macros --- */

#define ARRAY_COUNT( _a )       (sizeof (_a) / sizeof ((_a) [0]))





/* === prototypes of interface functions ================================= */





/* --- some helper functions --- */

/**
 * Detach an AVM active card of any type from its bus.
 *
 * A detach operation comprises of releasing all resources and all dynamic
 * memory allocated for the board specified in the argument. Additionally the
 * board will be reset. So after this function call the board will not be
 * operational any more.
 *
 * @param dev                    I: The device entry for the board to shut down.
 *
 * @return Nothing.
 */
extern void avmmisc_detach
   (device_t dev);

/**
 * Reset an AVM active card of any known board type.
 *
 * This function call will perform a normal reset operation on any known type of
 * board. The board type stored into *pSc will be used to redirect the call to
 * a board type specific function for a reset.
 *
 * @param pSc                    I/O: The softc structure for the board to reset.
 *
 * @return Nothing.
 */
extern void avmmisc_reset
   (AvmAicSc_t *pSc);

/* reset an AVM active card and disable interrupts */
extern void avmmisc_disable
   (AvmAicSc_t *pSc);

/* determine the controller port addressed by a CAPI controller number */
extern AvmAicPortData_t *avmmisc_get_port_from_capi_ctlr_num
   (AvmAicSc_t *pSc,
    unsigned    uCapiCtlr);

/* write a block of data to a buffer preceeded by its length */
static __inline unsigned char *avmmisc_mem_put_slice
   (unsigned char *pucDst,
    unsigned char *pucSrc,
    size_t         nLen);

/**
 * Initialise data for bus DMA.
 */
extern int avmmisc_init_busdma
   (device_t    dev,
    AvmAicSc_t *pSc);

/* evaluate version info returned by AVMAIC_RECEIVE_INIT message */
extern void avmmisc_parse_version
   (AvmAicPortData_t *pPortData);

/* get print name for card type */
extern const char *avmmisc_get_card_type_name
   (AvmAicCardType_t cardType);



/* --- performing download operations --- */

/* load T4 file onto non-arm based controllers */
extern unsigned avmmisc_load_t4_file
   (AvmAicSc_t    *pSc,
    size_t         nLenData,
    unsigned char *paucData);

/* load configuration onto non-arm based controller */
extern unsigned avmmisc_load_config
   (AvmAicSc_t    *pSc,
    size_t         nLenData,
    unsigned char *paucData);

/* check if non-arm based controller is loaded */
extern int avmmisc_is_loaded
   (AvmAicSc_t *pSc);



/* --- serializing access to a controller --- */

/* get access to a controller for an operation */
extern int avmmisc_get_ctlr_access
   (AvmAicSc_t *pSc);

/* release access to a controller after an operation */
extern void avmmisc_release_ctlr_access
   (AvmAicSc_t *pSc,
    int         sPrivLevel);





/* === definition of inline functions ==================================== */





/*
        write a block of data to a buffer preceeded by its length
        ---------------------------------------------------------
*/

static __inline unsigned char *avmmisc_mem_put_slice
   (unsigned char *pucDst,
    unsigned char *pucSrc,
    size_t         nLen)
{
   *((u_int32_t *) pucDst) = (u_int32_t) htole32 (nLen);
   pucDst += sizeof (u_int32_t);
   if (pucSrc && nLen > 0)
   {
      bcopy (pucSrc, pucDst, nLen);
   }
   return (pucDst + nLen);
} /* avmmisc_mem_put_slice */





#endif /* __AVMAIC_MISC_H */
