Source
x
static struct cflayer *get_dn(struct cfmuxl *muxl, struct dev_info *dev_info)
/*
* Copyright (C) ST-Ericsson AB 2010
* Author: Sjur Brendeland
* License terms: GNU General Public License (GPL) version 2
*/
struct cfmuxl {
struct cflayer layer;
struct list_head srvl_list;
struct list_head frml_list;
struct cflayer *up_cache[UP_CACHE_SIZE];
struct cflayer *dn_cache[DN_CACHE_SIZE];
/*
* Set when inserting or removing downwards layers.
*/
spinlock_t transmit_lock;
/*
* Set when inserting or removing upwards layers.
*/
spinlock_t receive_lock;
};
static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt);
static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt);
static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
int phyid);
static struct cflayer *get_up(struct cfmuxl *muxl, u16 id);
struct cflayer *cfmuxl_create(void)
{
struct cfmuxl *this = kzalloc(sizeof(struct cfmuxl), GFP_ATOMIC);
if (!this)
return NULL;
this->layer.receive = cfmuxl_receive;
this->layer.transmit = cfmuxl_transmit;
this->layer.ctrlcmd = cfmuxl_ctrlcmd;
INIT_LIST_HEAD(&this->srvl_list);
INIT_LIST_HEAD(&this->frml_list);
spin_lock_init(&this->transmit_lock);
spin_lock_init(&this->receive_lock);
snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "mux");
return &this->layer;
}
int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *dn, u8 phyid)
{
struct cfmuxl *muxl = (struct cfmuxl *) layr;
spin_lock_bh(&muxl->transmit_lock);
list_add_rcu(&dn->node, &muxl->frml_list);
spin_unlock_bh(&muxl->transmit_lock);
return 0;
}
static struct cflayer *get_from_id(struct list_head *list, u16 id)
{
struct cflayer *lyr;
list_for_each_entry_rcu(lyr, list, node) {
if (lyr->id == id)
return lyr;
}
return NULL;
}
int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid)
{
struct cfmuxl *muxl = container_obj(layr);
struct cflayer *old;
spin_lock_bh(&muxl->receive_lock);