linux/drivers/staging/tidspbridge/pmgr/chnl.c
<<
>>
Prefs
   1/*
   2 * chnl.c
   3 *
   4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
   5 *
   6 * DSP API channel interface: multiplexes data streams through the single
   7 * physical link managed by a Bridge Bridge driver.
   8 *
   9 * Copyright (C) 2005-2006 Texas Instruments, Inc.
  10 *
  11 * This package is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as
  13 * published by the Free Software Foundation.
  14 *
  15 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18 */
  19
  20#include <linux/types.h>
  21/*  ----------------------------------- Host OS */
  22#include <dspbridge/host_os.h>
  23
  24/*  ----------------------------------- DSP/BIOS Bridge */
  25#include <dspbridge/dbdefs.h>
  26
  27/*  ----------------------------------- Trace & Debug */
  28#include <dspbridge/dbc.h>
  29
  30/*  ----------------------------------- OS Adaptation Layer */
  31#include <dspbridge/sync.h>
  32
  33/*  ----------------------------------- Platform Manager */
  34#include <dspbridge/proc.h>
  35#include <dspbridge/dev.h>
  36
  37/*  ----------------------------------- Others */
  38#include <dspbridge/chnlpriv.h>
  39#include <chnlobj.h>
  40
  41/*  ----------------------------------- This */
  42#include <dspbridge/chnl.h>
  43
  44/*  ----------------------------------- Globals */
  45static u32 refs;
  46
  47/*
  48 *  ======== chnl_create ========
  49 *  Purpose:
  50 *      Create a channel manager object, responsible for opening new channels
  51 *      and closing old ones for a given 'Bridge board.
  52 */
  53int chnl_create(struct chnl_mgr **channel_mgr,
  54                       struct dev_object *hdev_obj,
  55                       const struct chnl_mgrattrs *mgr_attrts)
  56{
  57        int status;
  58        struct chnl_mgr *hchnl_mgr;
  59        struct chnl_mgr_ *chnl_mgr_obj = NULL;
  60
  61        DBC_REQUIRE(refs > 0);
  62        DBC_REQUIRE(channel_mgr != NULL);
  63        DBC_REQUIRE(mgr_attrts != NULL);
  64
  65        *channel_mgr = NULL;
  66
  67        /* Validate args: */
  68        if ((0 < mgr_attrts->max_channels) &&
  69            (mgr_attrts->max_channels <= CHNL_MAXCHANNELS))
  70                status = 0;
  71        else if (mgr_attrts->max_channels == 0)
  72                status = -EINVAL;
  73        else
  74                status = -ECHRNG;
  75
  76        if (mgr_attrts->word_size == 0)
  77                status = -EINVAL;
  78
  79        if (!status) {
  80                status = dev_get_chnl_mgr(hdev_obj, &hchnl_mgr);
  81                if (!status && hchnl_mgr != NULL)
  82                        status = -EEXIST;
  83
  84        }
  85
  86        if (!status) {
  87                struct bridge_drv_interface *intf_fxns;
  88                dev_get_intf_fxns(hdev_obj, &intf_fxns);
  89                /* Let Bridge channel module finish the create: */
  90                status = (*intf_fxns->pfn_chnl_create) (&hchnl_mgr, hdev_obj,
  91                                                        mgr_attrts);
  92                if (!status) {
  93                        /* Fill in DSP API channel module's fields of the
  94                         * chnl_mgr structure */
  95                        chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr;
  96                        chnl_mgr_obj->intf_fxns = intf_fxns;
  97                        /* Finally, return the new channel manager handle: */
  98                        *channel_mgr = hchnl_mgr;
  99                }
 100        }
 101
 102        DBC_ENSURE(status || chnl_mgr_obj);
 103
 104        return status;
 105}
 106
 107/*
 108 *  ======== chnl_destroy ========
 109 *  Purpose:
 110 *      Close all open channels, and destroy the channel manager.
 111 */
 112int chnl_destroy(struct chnl_mgr *hchnl_mgr)
 113{
 114        struct chnl_mgr_ *chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr;
 115        struct bridge_drv_interface *intf_fxns;
 116        int status;
 117
 118        DBC_REQUIRE(refs > 0);
 119
 120        if (chnl_mgr_obj) {
 121                intf_fxns = chnl_mgr_obj->intf_fxns;
 122                /* Let Bridge channel module destroy the chnl_mgr: */
 123                status = (*intf_fxns->pfn_chnl_destroy) (hchnl_mgr);
 124        } else {
 125                status = -EFAULT;
 126        }
 127
 128        return status;
 129}
 130
 131/*
 132 *  ======== chnl_exit ========
 133 *  Purpose:
 134 *      Discontinue usage of the CHNL module.
 135 */
 136void chnl_exit(void)
 137{
 138        DBC_REQUIRE(refs > 0);
 139
 140        refs--;
 141
 142        DBC_ENSURE(refs >= 0);
 143}
 144
 145/*
 146 *  ======== chnl_init ========
 147 *  Purpose:
 148 *      Initialize the CHNL module's private state.
 149 */
 150bool chnl_init(void)
 151{
 152        bool ret = true;
 153
 154        DBC_REQUIRE(refs >= 0);
 155
 156        if (ret)
 157                refs++;
 158
 159        DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
 160
 161        return ret;
 162}
 163