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/cfg.h> 32#include <dspbridge/sync.h> 33 34/* ----------------------------------- Platform Manager */ 35#include <dspbridge/proc.h> 36#include <dspbridge/dev.h> 37 38/* ----------------------------------- Others */ 39#include <dspbridge/chnlpriv.h> 40#include <chnlobj.h> 41 42/* ----------------------------------- This */ 43#include <dspbridge/chnl.h> 44 45/* ----------------------------------- Globals */ 46static u32 refs; 47 48/* 49 * ======== chnl_create ======== 50 * Purpose: 51 * Create a channel manager object, responsible for opening new channels 52 * and closing old ones for a given 'Bridge board. 53 */ 54int chnl_create(struct chnl_mgr **channel_mgr, 55 struct dev_object *hdev_obj, 56 const struct chnl_mgrattrs *mgr_attrts) 57{ 58 int status; 59 struct chnl_mgr *hchnl_mgr; 60 struct chnl_mgr_ *chnl_mgr_obj = NULL; 61 62 DBC_REQUIRE(refs > 0); 63 DBC_REQUIRE(channel_mgr != NULL); 64 DBC_REQUIRE(mgr_attrts != NULL); 65 66 *channel_mgr = NULL; 67 68 /* Validate args: */ 69 if ((0 < mgr_attrts->max_channels) && 70 (mgr_attrts->max_channels <= CHNL_MAXCHANNELS)) 71 status = 0; 72 else if (mgr_attrts->max_channels == 0) 73 status = -EINVAL; 74 else 75 status = -ECHRNG; 76 77 if (mgr_attrts->word_size == 0) 78 status = -EINVAL; 79 80 if (!status) { 81 status = dev_get_chnl_mgr(hdev_obj, &hchnl_mgr); 82 if (!status && hchnl_mgr != NULL) 83 status = -EEXIST; 84 85 } 86 87 if (!status) { 88 struct bridge_drv_interface *intf_fxns; 89 dev_get_intf_fxns(hdev_obj, &intf_fxns); 90 /* Let Bridge channel module finish the create: */ 91 status = (*intf_fxns->pfn_chnl_create) (&hchnl_mgr, hdev_obj, 92 mgr_attrts); 93 if (!status) { 94 /* Fill in DSP API channel module's fields of the 95 * chnl_mgr structure */ 96 chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr; 97 chnl_mgr_obj->intf_fxns = intf_fxns; 98 /* Finally, return the new channel manager handle: */ 99 *channel_mgr = hchnl_mgr; 100 } 101 } 102 103 DBC_ENSURE(status || chnl_mgr_obj); 104 105 return status; 106} 107 108/* 109 * ======== chnl_destroy ======== 110 * Purpose: 111 * Close all open channels, and destroy the channel manager. 112 */ 113int chnl_destroy(struct chnl_mgr *hchnl_mgr) 114{ 115 struct chnl_mgr_ *chnl_mgr_obj = (struct chnl_mgr_ *)hchnl_mgr; 116 struct bridge_drv_interface *intf_fxns; 117 int status; 118 119 DBC_REQUIRE(refs > 0); 120 121 if (chnl_mgr_obj) { 122 intf_fxns = chnl_mgr_obj->intf_fxns; 123 /* Let Bridge channel module destroy the chnl_mgr: */ 124 status = (*intf_fxns->pfn_chnl_destroy) (hchnl_mgr); 125 } else { 126 status = -EFAULT; 127 } 128 129 return status; 130} 131 132/* 133 * ======== chnl_exit ======== 134 * Purpose: 135 * Discontinue usage of the CHNL module. 136 */ 137void chnl_exit(void) 138{ 139 DBC_REQUIRE(refs > 0); 140 141 refs--; 142 143 DBC_ENSURE(refs >= 0); 144} 145 146/* 147 * ======== chnl_init ======== 148 * Purpose: 149 * Initialize the CHNL module's private state. 150 */ 151bool chnl_init(void) 152{ 153 bool ret = true; 154 155 DBC_REQUIRE(refs >= 0); 156 157 if (ret) 158 refs++; 159 160 DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0))); 161 162 return ret; 163} 164