diff options
author | Kim Lilliestierna XX <kim.xx.lilliestierna@stericsson.com> | 2010-05-10 14:13:37 +0200 |
---|---|---|
committer | John Rigby <john.rigby@linaro.org> | 2010-09-02 22:45:24 -0600 |
commit | 1f63c78f8a3cf5d00d8dd6701103d51d6a00d883 (patch) | |
tree | e05b5a8f26526a5c09bf7d7238fdf350b843a436 /net | |
parent | cbb288966b220015b17de4749129d4e007ce0552 (diff) |
CAIF: changes to former "generic" files
Change-Id: I9d8ec46b2066cb7bd1bab0827638a87110942f29
Diffstat (limited to 'net')
-rw-r--r-- | net/caif/cfcnfg.c | 323 | ||||
-rw-r--r-- | net/caif/cfctrl.c | 378 | ||||
-rw-r--r-- | net/caif/cfdgml.c | 40 | ||||
-rw-r--r-- | net/caif/cffrml.c | 77 | ||||
-rw-r--r-- | net/caif/cflist.c | 36 | ||||
-rw-r--r-- | net/caif/cfmuxl.c | 198 | ||||
-rw-r--r-- | net/caif/cfpkt_plain.c | 173 | ||||
-rw-r--r-- | net/caif/cfrfml.c | 42 | ||||
-rw-r--r-- | net/caif/cfserl.c | 82 | ||||
-rw-r--r-- | net/caif/cfsrvl.c | 56 | ||||
-rw-r--r-- | net/caif/cfutill.c | 39 | ||||
-rw-r--r-- | net/caif/cfveil.c | 45 | ||||
-rw-r--r-- | net/caif/cfvidl.c | 33 |
13 files changed, 775 insertions, 747 deletions
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index 14358c402ce..471c62939fa 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c @@ -1,35 +1,36 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ - -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/caif_layer.h> -#include <net/caif/generic/cfpkt.h> -#include <net/caif/generic/cflst.h> -#include <net/caif/generic/cfcnfg.h> -#include <net/caif/generic/cfctrl.h> -#include <net/caif/generic/cfmuxl.h> -#include <net/caif/generic/cffrml.h> -#include <net/caif/generic/cfserl.h> -#include <net/caif/generic/cfsrvl.h> +#include <linux/kernel.h> +#include <linux/stddef.h> +#include <linux/slab.h> +#include <net/caif/caif_layer.h> +#include <net/caif/cfpkt.h> +#include <net/caif/cfcnfg.h> +#include <net/caif/cfctrl.h> +#include <net/caif/cfmuxl.h> +#include <net/caif/cffrml.h> +#include <net/caif/cfserl.h> +#include <net/caif/cfsrvl.h> #include <linux/module.h> +#include <asm/atomic.h> #define MAX_PHY_LAYERS 7 #define PHY_NAME_LEN 20 -#define container_obj(layr) cfglu_container_of(layr, struct cfcnfg, layer) +#define container_obj(layr) container_of(layr, struct cfcnfg, layer) /* Information about CAIF physical interfaces held by Config Module in order * to manage physical interfaces */ struct cfcnfg_phyinfo { /* Pointer to the layer below the MUX (framing layer) */ - struct layer *frm_layer; + struct cflayer *frm_layer; /* Pointer to the lowest actual physical layer */ - struct layer *phy_layer; + struct cflayer *phy_layer; /* Unique identifier of the physical interface */ unsigned int id; /* Preference of the physical in interface */ @@ -43,29 +44,28 @@ struct cfcnfg_phyinfo { }; struct cfcnfg { - struct layer layer; - struct layer *ctrl; - struct layer *mux; - uint8 last_phyid; + struct cflayer layer; + struct cflayer *ctrl; + struct cflayer *mux; + u8 last_phyid; struct cfcnfg_phyinfo phy_layers[MAX_PHY_LAYERS]; }; -static void cncfg_linkup_rsp(struct layer *layer, uint8 linkid, - enum cfctrl_srv serv, uint8 phyid, - struct layer *adapt_layer); -static void cncfg_linkdestroy_rsp(struct layer *layer, uint8 linkid, - struct layer *client_layer); -static void cncfg_reject_rsp(struct layer *layer, uint8 linkid, - struct layer *adapt_layer); +static void cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, + enum cfctrl_srv serv, u8 phyid, + struct cflayer *adapt_layer); +static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id); +static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id, + struct cflayer *adapt_layer); static void cfctrl_resp_func(void); static void cfctrl_enum_resp(void); -struct cfcnfg *cfcnfg_create() +struct cfcnfg *cfcnfg_create(void) { struct cfcnfg *this; struct cfctrl_rsp *resp; /* Initiate this layer */ - this = cfglu_alloc(sizeof(struct cfcnfg)); + this = kmalloc(sizeof(struct cfcnfg), GFP_ATOMIC); if (!this) { pr_warning("CAIF: %s(): Out of memory\n", __func__); return NULL; @@ -81,13 +81,13 @@ struct cfcnfg *cfcnfg_create() resp = cfctrl_get_respfuncs(this->ctrl); resp->enum_rsp = cfctrl_enum_resp; resp->linkerror_ind = cfctrl_resp_func; - resp->linkdestroy_rsp = cncfg_linkdestroy_rsp; + resp->linkdestroy_rsp = cfcnfg_linkdestroy_rsp; resp->sleep_rsp = cfctrl_resp_func; resp->wake_rsp = cfctrl_resp_func; resp->restart_rsp = cfctrl_resp_func; resp->radioset_rsp = cfctrl_resp_func; - resp->linksetup_rsp = cncfg_linkup_rsp; - resp->reject_rsp = cncfg_reject_rsp; + resp->linksetup_rsp = cfcnfg_linkup_rsp; + resp->reject_rsp = cfcnfg_reject_rsp; this->last_phyid = 1; @@ -97,9 +97,9 @@ struct cfcnfg *cfcnfg_create() return this; out_of_mem: pr_warning("CAIF: %s(): Out of memory\n", __func__); - cfglu_free(this->mux); - cfglu_free(this->ctrl); - cfglu_free(this); + kfree(this->mux); + kfree(this->ctrl); + kfree(this); return NULL; } EXPORT_SYMBOL(cfcnfg_create); @@ -107,9 +107,9 @@ EXPORT_SYMBOL(cfcnfg_create); void cfcnfg_remove(struct cfcnfg *cfg) { if (cfg) { - cfglu_free(cfg->mux); - cfglu_free(cfg->ctrl); - cfglu_free(cfg); + kfree(cfg->mux); + kfree(cfg->ctrl); + kfree(cfg); } } @@ -124,7 +124,7 @@ static void cfctrl_enum_resp(void) struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg, enum cfcnfg_phy_preference phy_pref) { - int i; + u16 i; /* Try to match with specified preference */ for (i = 1; i < MAX_PHY_LAYERS; i++) { @@ -149,192 +149,128 @@ struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg, } static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo(struct cfcnfg *cnfg, - uint8 phyid) + u8 phyid) { int i; - /* Try to match with specified preference */ for (i = 0; i < MAX_PHY_LAYERS; i++) if (cnfg->phy_layers[i].frm_layer != NULL && cnfg->phy_layers[i].id == phyid) return &cnfg->phy_layers[i]; - return 0; + return NULL; } int cfcnfg_get_named(struct cfcnfg *cnfg, char *name) { int i; - /* Try to match with specified preference */ + /* Try to match with specified name */ for (i = 0; i < MAX_PHY_LAYERS; i++) { if (cnfg->phy_layers[i].frm_layer != NULL - && strcmp(cnfg->phy_layers[i].frm_layer->name, - name) == 0) { + && strcmp(cnfg->phy_layers[i].phy_layer->name, + name) == 0) return cnfg->phy_layers[i].frm_layer->id; - } } return 0; } -/* - * NOTE: What happens on destroy failure: - * 1a) No response - Too early - * This will not happen because enumerate has already - * completed. - * 1b) No response - FATAL - * Not handled, but this should be a CAIF PROTOCOL ERROR - * Modem error, response is really expected - this - * case is not really handled. - * 2) O/E-bit indicate error - * Ignored - this link is destroyed anyway. - * 3) Not able to match on request - * Not handled, but this should be a CAIF PROTOCOL ERROR - * 4) Link-Error - (no response) - * Not handled, but this should be a CAIF PROTOCOL ERROR - */ - -int cfcnfg_del_adapt_layer(struct cfcnfg *cnfg, struct layer *adap_layer) +int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) { - uint8 channel_id = 0; + u8 channel_id = 0; int ret = 0; + struct cflayer *servl = NULL; struct cfcnfg_phyinfo *phyinfo = NULL; - uint8 phyid = 0; - + u8 phyid = 0; caif_assert(adap_layer != NULL); channel_id = adap_layer->id; - if (channel_id == 0) { + if (adap_layer->dn == NULL || channel_id == 0) { pr_err("CAIF: %s():adap_layer->id is 0\n", __func__); - ret = CFGLU_ENOTCONN; + ret = -ENOTCONN; goto end; } - - if (adap_layer->dn == NULL) { - pr_err("CAIF: %s():adap_layer->dn is NULL\n", __func__); - ret = CFGLU_ENODEV; + servl = cfmuxl_remove_uplayer(cnfg->mux, channel_id); + if (servl == NULL) goto end; - } - - if (adap_layer->dn != NULL) - phyid = cfsrvl_getphyid(adap_layer->dn); - - phyinfo = cfcnfg_get_phyinfo(cnfg, phyid); - if (phyinfo == NULL) { - pr_warning("CAIF: %s(): No interface to send disconnect to\n", - __func__); - ret = CFGLU_ENODEV; + layer_set_up(servl, NULL); + ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer); + if (servl == NULL) { + pr_err("CAIF: %s(): PROTOCOL ERROR " + "- Error removing service_layer Channel_Id(%d)", + __func__, channel_id); + ret = -EINVAL; goto end; } + caif_assert(channel_id == servl->id); + if (adap_layer->dn != NULL) { + phyid = cfsrvl_getphyid(adap_layer->dn); - if (phyinfo->id != phyid - || phyinfo->phy_layer->id != phyid - || phyinfo->frm_layer->id != phyid) { - - pr_err("CAIF: %s(): Inconsistency in phy registration\n", - __func__); - ret = CFGLU_EINVAL; - goto end; + phyinfo = cfcnfg_get_phyinfo(cnfg, phyid); + if (phyinfo == NULL) { + pr_warning("CAIF: %s(): " + "No interface to send disconnect to\n", + __func__); + ret = -ENODEV; + goto end; + } + if (phyinfo->id != phyid || + phyinfo->phy_layer->id != phyid || + phyinfo->frm_layer->id != phyid) { + pr_err("CAIF: %s(): " + "Inconsistency in phy registration\n", + __func__); + ret = -EINVAL; + goto end; + } } - - ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer); - -end: if (phyinfo != NULL && --phyinfo->phy_ref_count == 0 && phyinfo->phy_layer != NULL && phyinfo->phy_layer->modemcmd != NULL) { phyinfo->phy_layer->modemcmd(phyinfo->phy_layer, _CAIF_MODEMCMD_PHYIF_USELESS); } +end: + cfsrvl_put(servl); + cfctrl_cancel_req(cnfg->ctrl, adap_layer); + if (adap_layer->ctrlcmd != NULL) + adap_layer->ctrlcmd(adap_layer, CAIF_CTRLCMD_DEINIT_RSP, 0); return ret; } -EXPORT_SYMBOL(cfcnfg_del_adapt_layer); +EXPORT_SYMBOL(cfcnfg_disconn_adapt_layer); -static void cncfg_linkdestroy_rsp(struct layer *layer, uint8 linkid, - struct layer *client_layer) +void cfcnfg_release_adap_layer(struct cflayer *adap_layer) { - struct cfcnfg *cnfg = container_obj(layer); - struct layer *servl; - - /* - * 1) Remove service from the MUX layer. The MUX must - * guarante that no more payload sent "upwards" (receive) - */ - servl = cfmuxl_remove_uplayer(cnfg->mux, linkid); - - if (servl == NULL) { - pr_err("CAIF: %s(): PROTOCOL ERROR " - "- Error removing service_layer Linkid(%d)", - __func__, linkid); - return; - } - caif_assert(linkid == servl->id); - - if (servl != client_layer && servl->up != client_layer) { - pr_err("CAIF: %s(): Error removing service_layer " - "Linkid(%d) %p %p", - __func__, linkid, (void *) servl, - (void *) client_layer); - return; - } - - /* - * 2) DEINIT_RSP must guarantee that no more packets are transmitted - * from client (adap_layer) when it returns. - */ - - if (servl->ctrlcmd == NULL) { - pr_err("CAIF: %s(): Error servl->ctrlcmd == NULL", __func__); - return; - } - - servl->ctrlcmd(servl, CAIF_CTRLCMD_DEINIT_RSP, 0); - - /* 3) It is now safe to destroy the service layer. */ - - if (client_layer != servl->up) - cfservl_destroy(servl); + if (adap_layer->dn) + cfsrvl_put(adap_layer->dn); } +EXPORT_SYMBOL(cfcnfg_release_adap_layer); -/* - * NOTE: What happens on linksetup failure: - * 1a) No response - Too early - * This will not happen because enumerate is secured - * before using interface. - * 1b) No response - FATAL - * Not handled, but this should be a CAIF PROTOCOL ERROR - * Modem error, response is really expected - this case is - * not really handled. - * 2) O/E-bit indicate error - * Handled in cnfg_reject_rsp - * 3) Not able to match on request - * Not handled, but this should be a CAIF PROTOCOL ERROR - * 4) Link-Error - (no response) - * Not handled, but this should be a CAIF PROTOCOL ERROR - */ +static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id) +{ +} -bool -cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, +int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, struct cfctrl_link_param *param, - struct layer *adap_layer) + struct cflayer *adap_layer) { - struct layer *frml; + struct cflayer *frml; if (adap_layer == NULL) { pr_err("CAIF: %s(): adap_layer is zero", __func__); - return CFGLU_EINVAL; + return -EINVAL; } if (adap_layer->receive == NULL) { pr_err("CAIF: %s(): adap_layer->receive is NULL", __func__); - return CFGLU_EINVAL; + return -EINVAL; } if (adap_layer->ctrlcmd == NULL) { pr_err("CAIF: %s(): adap_layer->ctrlcmd == NULL", __func__); - return CFGLU_EINVAL; + return -EINVAL; } frml = cnfg->phy_layers[param->phyid].frm_layer; if (frml == NULL) { pr_err("CAIF: %s(): Specified PHY type does not exist!", __func__); - return CFGLU_ENODEV; + return -ENODEV; } caif_assert(param->phyid == cnfg->phy_layers[param->phyid].id); caif_assert(cnfg->phy_layers[param->phyid].frm_layer->id == @@ -343,13 +279,12 @@ cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, param->phyid); /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */ cfctrl_enum_req(cnfg->ctrl, param->phyid); - cfctrl_linkup_request(cnfg->ctrl, param, adap_layer); - return 0; + return cfctrl_linkup_request(cnfg->ctrl, param, adap_layer); } EXPORT_SYMBOL(cfcnfg_add_adaptation_layer); -static void cncfg_reject_rsp(struct layer *layer, uint8 linkid, - struct layer *adapt_layer) +static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id, + struct cflayer *adapt_layer) { if (adapt_layer != NULL && adapt_layer->ctrlcmd != NULL) adapt_layer->ctrlcmd(adapt_layer, @@ -357,15 +292,17 @@ static void cncfg_reject_rsp(struct layer *layer, uint8 linkid, } static void -cncfg_linkup_rsp(struct layer *layer, uint8 linkid, enum cfctrl_srv serv, - uint8 phyid, struct layer *adapt_layer) +cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, + u8 phyid, struct cflayer *adapt_layer) { struct cfcnfg *cnfg = container_obj(layer); - struct layer *servicel = NULL; + struct cflayer *servicel = NULL; struct cfcnfg_phyinfo *phyinfo; if (adapt_layer == NULL) { - pr_err("CAIF: %s(): PROTOCOL ERROR " - "- LinkUp Request/Response did not match\n", __func__); + pr_debug("CAIF: %s(): link setup response " + "but no client exist, send linkdown back\n", + __func__); + cfctrl_linkdown_req(cnfg->ctrl, channel_id, NULL); return; } @@ -386,26 +323,26 @@ cncfg_linkup_rsp(struct layer *layer, uint8 linkid, enum cfctrl_srv serv, _CAIF_MODEMCMD_PHYIF_USEFULL); } - adapt_layer->id = linkid; + adapt_layer->id = channel_id; switch (serv) { case CFCTRL_SRV_VEI: - servicel = cfvei_create(linkid, &phyinfo->dev_info); + servicel = cfvei_create(channel_id, &phyinfo->dev_info); break; case CFCTRL_SRV_DATAGRAM: - servicel = cfdgml_create(linkid, &phyinfo->dev_info); + servicel = cfdgml_create(channel_id, &phyinfo->dev_info); break; case CFCTRL_SRV_RFM: - servicel = cfrfml_create(linkid, &phyinfo->dev_info); + servicel = cfrfml_create(channel_id, &phyinfo->dev_info); break; case CFCTRL_SRV_UTIL: - servicel = cfutill_create(linkid, &phyinfo->dev_info); + servicel = cfutill_create(channel_id, &phyinfo->dev_info); break; case CFCTRL_SRV_VIDEO: - servicel = cfvidl_create(linkid, &phyinfo->dev_info); + servicel = cfvidl_create(channel_id, &phyinfo->dev_info); break; case CFCTRL_SRV_DBG: - servicel = adapt_layer; + servicel = cfdbgl_create(channel_id, &phyinfo->dev_info); break; default: pr_err("CAIF: %s(): Protocol error. " @@ -418,24 +355,21 @@ cncfg_linkup_rsp(struct layer *layer, uint8 linkid, enum cfctrl_srv serv, return; } layer_set_dn(servicel, cnfg->mux); - - - cfmuxl_set_uplayer(cnfg->mux, servicel, linkid); - if (servicel != adapt_layer) { - layer_set_up(servicel, adapt_layer); - layer_set_dn(adapt_layer, servicel); - } + cfmuxl_set_uplayer(cnfg->mux, servicel, channel_id); + layer_set_up(servicel, adapt_layer); + layer_set_dn(adapt_layer, servicel); + cfsrvl_get(servicel); servicel->ctrlcmd(servicel, CAIF_CTRLCMD_INIT_RSP, 0); } void cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, - void *dev, struct layer *phy_layer, uint16 *phyid, + void *dev, struct cflayer *phy_layer, u16 *phyid, enum cfcnfg_phy_preference pref, bool fcs, bool stx) { - struct layer *frml; - struct layer *phy_driver = NULL; + struct cflayer *frml; + struct cflayer *phy_driver = NULL; int i; @@ -461,7 +395,6 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, switch (phy_type) { case CFPHYTYPE_FRAG: - fcs = true; phy_driver = cfserl_create(CFPHYTYPE_FRAG, *phyid, stx); if (!phy_driver) { @@ -509,10 +442,10 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, } EXPORT_SYMBOL(cfcnfg_add_phy_layer); -int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct layer *phy_layer) +int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer) { - struct layer *frml, *frml_dn; - uint16 phyid; + struct cflayer *frml, *frml_dn; + u16 phyid; phyid = phy_layer->id; caif_assert(phyid == cnfg->phy_layers[phyid].id); caif_assert(phy_layer == cnfg->phy_layers[phyid].phy_layer); @@ -525,14 +458,14 @@ int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct layer *phy_layer) frml_dn = frml->dn; cffrml_set_uplayer(frml, NULL); cffrml_set_dnlayer(frml, NULL); - cffrml_destroy(frml); + kfree(frml); if (phy_layer != frml_dn) { layer_set_up(frml_dn, NULL); layer_set_dn(frml_dn, NULL); - cfglu_free(frml_dn); + kfree(frml_dn); } layer_set_up(phy_layer, NULL); - return CFGLU_EOK; + return 0; } EXPORT_SYMBOL(cfcnfg_del_phy_layer); diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index e79eb1b512c..c6d549a9554 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c @@ -1,21 +1,23 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/caif_layer.h> -#include <net/caif/generic/cfpkt.h> -#include <net/caif/generic/cfctrl.h> +#include <linux/stddef.h> +#include <linux/spinlock.h> +#include <linux/slab.h> +#include <net/caif/caif_layer.h> +#include <net/caif/cfpkt.h> +#include <net/caif/cfctrl.h> -#define container_obj(layr) cfglu_container_of(layr, struct cfctrl, serv.layer) +#define container_obj(layr) container_of(layr, struct cfctrl, serv.layer) #define UTILITY_NAME_LENGTH 16 #define CFPKT_CTRL_PKT_LEN 20 #ifdef CAIF_NO_LOOP -static inline int handle_loop(struct cfctrl *ctrl, +static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt){ return CAIF_FAILURE; } @@ -23,35 +25,37 @@ static inline int handle_loop(struct cfctrl *ctrl, static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt); #endif -static int cfctrl_recv(struct layer *layr, struct cfpkt *pkt); -static void cfctrl_ctrlcmd(struct layer *layr, enum caif_ctrlcmd ctrl, +static int cfctrl_recv(struct cflayer *layr, struct cfpkt *pkt); +static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, int phyid); -struct layer *cfctrl_create() +struct cflayer *cfctrl_create(void) { + struct dev_info dev_info; struct cfctrl *this = - (struct cfctrl *) cfglu_alloc(sizeof(struct cfctrl)); + kmalloc(sizeof(struct cfctrl), GFP_ATOMIC); if (!this) { pr_warning("CAIF: %s(): Out of memory\n", __func__); return NULL; } caif_assert(offsetof(struct cfctrl, serv.layer) == 0); + memset(&dev_info, 0, sizeof(dev_info)); + dev_info.id = 0xff; memset(this, 0, sizeof(*this)); - cfglu_init_lock(this->info_list_lock); - cfglu_atomic_set(this->req_seq_no, 1); - cfglu_atomic_set(this->rsp_seq_no, 1); - this->serv.dev_info.id = 0xff; - this->serv.layer.id = 0; + cfsrvl_init(&this->serv, 0, &dev_info); + spin_lock_init(&this->info_list_lock); + atomic_set(&this->req_seq_no, 1); + atomic_set(&this->rsp_seq_no, 1); this->serv.layer.receive = cfctrl_recv; sprintf(this->serv.layer.name, "ctrl"); this->serv.layer.ctrlcmd = cfctrl_ctrlcmd; - cfglu_init_lock(this->loop_linkid_lock); + spin_lock_init(&this->loop_linkid_lock); this->loop_linkid = 1; return &this->serv.layer; } -bool param_eq(struct cfctrl_link_param *p1, struct cfctrl_link_param *p2) +static bool param_eq(struct cfctrl_link_param *p1, struct cfctrl_link_param *p2) { bool eq = p1->linktype == p2->linktype && @@ -109,34 +113,20 @@ void cfctrl_insert_req(struct cfctrl *ctrl, struct cfctrl_request_info *req) { struct cfctrl_request_info *p; - cfglu_lock(ctrl->info_list_lock); + spin_lock(&ctrl->info_list_lock); req->next = NULL; - cfglu_atomic_inc(ctrl->req_seq_no); - req->sequence_no = cfglu_atomic_read(ctrl->req_seq_no); + atomic_inc(&ctrl->req_seq_no); + req->sequence_no = atomic_read(&ctrl->req_seq_no); if (ctrl->first_req == NULL) { ctrl->first_req = req; - cfglu_unlock(ctrl->info_list_lock); + spin_unlock(&ctrl->info_list_lock); return; } p = ctrl->first_req; while (p->next != NULL) p = p->next; p->next = req; - cfglu_unlock(ctrl->info_list_lock); -} - -static void cfctrl_insert_req2(struct cfctrl *ctrl, enum cfctrl_cmd cmd, - uint8 linkid, struct layer *user_layer) -{ - struct cfctrl_request_info *req = cfglu_alloc(sizeof(*req)); - if (!req) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); - return; - } - req->client_layer = user_layer; - req->cmd = cmd; - req->channel_id = linkid; - cfctrl_insert_req(ctrl, req); + spin_unlock(&ctrl->info_list_lock); } /* Compare and remove request */ @@ -146,98 +136,69 @@ struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl, struct cfctrl_request_info *p; struct cfctrl_request_info *ret; - cfglu_lock(ctrl->info_list_lock); + spin_lock(&ctrl->info_list_lock); if (ctrl->first_req == NULL) { - cfglu_unlock(ctrl->info_list_lock); + spin_unlock(&ctrl->info_list_lock); return NULL; } if (cfctrl_req_eq(req, ctrl->first_req)) { ret = ctrl->first_req; - cfglu_atomic_set(ctrl->rsp_seq_no, + caif_assert(ctrl->first_req); + atomic_set(&ctrl->rsp_seq_no, ctrl->first_req->sequence_no); ctrl->first_req = ctrl->first_req->next; - cfglu_unlock(ctrl->info_list_lock); + spin_unlock(&ctrl->info_list_lock); return ret; } - pr_warning("CAIF: %s(): Requests are not received in order/matching\n", - __func__); - p = ctrl->first_req; while (p->next != NULL) { if (cfctrl_req_eq(req, p->next)) { + pr_warning("CAIF: %s(): Requests are not " + "received in order\n", + __func__); ret = p->next; - cfglu_atomic_set(ctrl->rsp_seq_no, - p->next->sequence_no); - p = p->next; - cfglu_unlock(ctrl->info_list_lock); + atomic_set(&ctrl->rsp_seq_no, + p->next->sequence_no); + p->next = p->next->next; + spin_unlock(&ctrl->info_list_lock); return ret; } p = p->next; } - cfglu_unlock(ctrl->info_list_lock); - return NULL; -} - -/* Compare and remove old requests based on sequence no. */ -void cfctrl_prune_req(struct cfctrl *ctrl) -{ - struct cfctrl_request_info *p; - struct cfctrl_request_info *del; - - cfglu_lock(ctrl->info_list_lock); - if (ctrl->first_req == NULL) { - cfglu_unlock(ctrl->info_list_lock); - return; - } + spin_unlock(&ctrl->info_list_lock); - if (ctrl->first_req->sequence_no < - cfglu_atomic_read(ctrl->req_seq_no)) { - del = ctrl->first_req; - ctrl->first_req = ctrl->first_req->next; - cfglu_free(del); - } - p = ctrl->first_req; - while (p->next != NULL) { - if (p->next->sequence_no < - cfglu_atomic_read(ctrl->rsp_seq_no)) { - del = p->next; - p = p->next; - cfglu_atomic_set(ctrl->rsp_seq_no, - ctrl->first_req->sequence_no); - cfglu_free(del); - } - p = p->next; - } - cfglu_unlock(ctrl->info_list_lock); + pr_warning("CAIF: %s(): Request does not match\n", + __func__); + return NULL; } -struct cfctrl_rsp *cfctrl_get_respfuncs(struct layer *layer) +struct cfctrl_rsp *cfctrl_get_respfuncs(struct cflayer *layer) { struct cfctrl *this = container_obj(layer); return &this->res; } -void cfctrl_set_dnlayer(struct layer *this, struct layer *dn) +void cfctrl_set_dnlayer(struct cflayer *this, struct cflayer *dn) { this->dn = dn; } -void cfctrl_set_uplayer(struct layer *this, struct layer *up) +void cfctrl_set_uplayer(struct cflayer *this, struct cflayer *up) { this->up = up; } -void init_info(struct payload_info *info, struct cfctrl *cfctrl) +static void init_info(struct caif_payload_info *info, struct cfctrl *cfctrl) { info->hdr_len = 0; info->channel_id = cfctrl->serv.layer.id; info->dev_info = &cfctrl->serv.dev_info; } -void cfctrl_enum_req(struct layer *layer, uint8 physlinkid) +void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid) { struct cfctrl *cfctrl = container_obj(layer); int ret; @@ -261,51 +222,53 @@ void cfctrl_enum_req(struct layer *layer, uint8 physlinkid) } } -void cfctrl_linkup_request(struct layer *layer, struct cfctrl_link_param *param, - struct layer *user_layer) +int cfctrl_linkup_request(struct cflayer *layer, + struct cfctrl_link_param *param, + struct cflayer *user_layer) { struct cfctrl *cfctrl = container_obj(layer); - uint32 tmp32; - uint16 tmp16; - uint8 tmp8; + u32 tmp32; + u16 tmp16; + u8 tmp8; struct cfctrl_request_info *req; int ret; char utility_name[16]; struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { pr_warning("CAIF: %s(): Out of memory\n", __func__); - return; + return -ENOMEM; } cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_SETUP); cfpkt_addbdy(pkt, (param->chtype << 4) + param->linktype); cfpkt_addbdy(pkt, (param->priority << 3) + param->phyid); cfpkt_addbdy(pkt, param->endpoint & 0x03); + switch (param->linktype) { case CFCTRL_SRV_VEI: break; case CFCTRL_SRV_VIDEO: - cfpkt_addbdy(pkt, (uint8) param->u.video.connid); + cfpkt_addbdy(pkt, (u8) param->u.video.connid); break; case CFCTRL_SRV_DBG: break; case CFCTRL_SRV_DATAGRAM: - tmp32 = cfglu_cpu_to_le32(param->u.datagram.connid); + tmp32 = cpu_to_le32(param->u.datagram.connid); cfpkt_add_body(pkt, &tmp32, 4); break; case CFCTRL_SRV_RFM: /* Construct a frame, convert DatagramConnectionID to network * format long and copy it out... */ - tmp32 = cfglu_cpu_to_le32(param->u.rfm.connid); + tmp32 = cpu_to_le32(param->u.rfm.connid); cfpkt_add_body(pkt, &tmp32, 4); /* Add volume name, including zero termination... */ cfpkt_add_body(pkt, param->u.rfm.volume, strlen(param->u.rfm.volume) + 1); break; case CFCTRL_SRV_UTIL: - tmp16 = cfglu_cpu_to_le16(param->u.utility.fifosize_kb); + tmp16 = cpu_to_le16(param->u.utility.fifosize_kb); cfpkt_add_body(pkt, &tmp16, 2); - tmp16 = cfglu_cpu_to_le16(param->u.utility.fifosize_bufs); + tmp16 = cpu_to_le16(param->u.utility.fifosize_bufs); cfpkt_add_body(pkt, &tmp16, 2); memset(utility_name, 0, sizeof(utility_name)); strncpy(utility_name, param->u.utility.name, @@ -319,11 +282,12 @@ void cfctrl_linkup_request(struct layer *layer, struct cfctrl_link_param *param, default: pr_warning("CAIF: %s():Request setup of bad link type = %d\n", __func__, param->linktype); + return -EINVAL; } - req = cfglu_alloc(sizeof(*req)); + req = kmalloc(sizeof(*req), GFP_KERNEL); if (!req) { pr_warning("CAIF: %s(): Out of memory\n", __func__); - return; + return -ENOMEM; } memset(req, 0, sizeof(*req)); req->client_layer = user_layer; @@ -331,6 +295,11 @@ void cfctrl_linkup_request(struct layer *layer, struct cfctrl_link_param *param, req->param = *param; cfctrl_insert_req(cfctrl, req); init_info(cfpkt_info(pkt), cfctrl); + /* + * NOTE:Always send linkup and linkdown request on the same + * device as the payload. Otherwise old queued up payload + * might arrive with the newly allocated channel ID. + */ cfpkt_info(pkt)->dev_info->id = param->phyid; ret = cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); @@ -338,20 +307,21 @@ void cfctrl_linkup_request(struct layer *layer, struct cfctrl_link_param *param, pr_err("CAIF: %s(): Could not transmit linksetup request\n", __func__); cfpkt_destroy(pkt); + return -ENODEV; } + return 0; } -int cfctrl_linkdown_req(struct layer *layer, uint8 channelid, - struct layer *client) +int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, + struct cflayer *client) { int ret; struct cfctrl *cfctrl = container_obj(layer); struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { pr_warning("CAIF: %s(): Out of memory\n", __func__); - return CFGLU_ENOMEM; + return -ENOMEM; } - cfctrl_insert_req2(cfctrl, CFCTRL_CMD_LINK_DESTROY, channelid, client); cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY); cfpkt_addbdy(pkt, channelid); init_info(cfpkt_info(pkt), cfctrl); @@ -365,7 +335,7 @@ int cfctrl_linkdown_req(struct layer *layer, uint8 channelid, return ret; } -void cfctrl_sleep_req(struct layer *layer) +void cfctrl_sleep_req(struct cflayer *layer) { int ret; struct cfctrl *cfctrl = container_obj(layer); @@ -382,7 +352,7 @@ void cfctrl_sleep_req(struct layer *layer) cfpkt_destroy(pkt); } -void cfctrl_wake_req(struct layer *layer) +void cfctrl_wake_req(struct cflayer *layer) { int ret; struct cfctrl *cfctrl = container_obj(layer); @@ -399,7 +369,7 @@ void cfctrl_wake_req(struct layer *layer) cfpkt_destroy(pkt); } -void cfctrl_getstartreason_req(struct layer *layer) +void cfctrl_getstartreason_req(struct cflayer *layer) { int ret; struct cfctrl *cfctrl = container_obj(layer); @@ -416,7 +386,42 @@ void cfctrl_getstartreason_req(struct layer *layer) cfpkt_destroy(pkt); } -void cfctrl_setmode_req(struct layer *layer, uint8 mode) +//deprecated-functionality-below +#if 0 +/* Compare and remove old requests based on sequence no. */ +static void cfctrl_prune_req(struct cfctrl *ctrl) +{ + struct cfctrl_request_info *p; + struct cfctrl_request_info *del; + + spin_lock(&ctrl->info_list_lock); + if (ctrl->first_req == NULL) { + spin_unlock(&ctrl->info_list_lock); + return; + } + + if (ctrl->first_req->sequence_no < + atomic_read(&ctrl->req_seq_no)) { + del = ctrl->first_req; + ctrl->first_req = ctrl->first_req->next; + kfree(del); + } + p = ctrl->first_req; + while (p->next != NULL) { + if (p->next->sequence_no < + atomic_read(&ctrl->rsp_seq_no)) { + del = p->next; + p = p->next; + atomic_set(&ctrl->rsp_seq_no, + ctrl->first_req->sequence_no); + kfree(del); + } + p = p->next; + } + spin_unlock(&ctrl->info_list_lock); +} + +static void cfctrl_setmode_req(struct cflayer *layer, u8 mode) { int ret; struct cfctrl *cfctrl = container_obj(layer); @@ -433,16 +438,50 @@ void cfctrl_setmode_req(struct layer *layer, uint8 mode) if (ret < 0) cfpkt_destroy(pkt); } +#endif +//deprecated-functionality-above -static int cfctrl_recv(struct layer *layer, struct cfpkt *pkt) +void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer) { - uint8 cmdrsp; - uint8 cmd; + struct cfctrl_request_info *p, *req; + struct cfctrl *ctrl = container_obj(layr); + spin_lock(&ctrl->info_list_lock); + + if (ctrl->first_req == NULL) { + spin_unlock(&ctrl->info_list_lock); + return; + } + + if (ctrl->first_req->client_layer == adap_layer) { + + req = ctrl->first_req; + ctrl->first_req = ctrl->first_req->next; + kfree(req); + } + + p = ctrl->first_req; + while (p != NULL && p->next != NULL) { + if (p->next->client_layer == adap_layer) { + + req = p->next; + p->next = p->next->next; + kfree(p->next); + } + p = p->next; + } + + spin_unlock(&ctrl->info_list_lock); +} + +static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) +{ + u8 cmdrsp; + u8 cmd; int ret = -1; - uint16 tmp16; - uint8 len; - uint8 param[255]; - uint8 linkid; + u16 tmp16; + u8 len; + u8 param[255]; + u8 linkid; struct cfctrl *cfctrl = container_obj(layer); struct cfctrl_request_info rsp, *req; @@ -451,11 +490,8 @@ static int cfctrl_recv(struct layer *layer, struct cfpkt *pkt) cmd = cmdrsp & CFCTRL_CMD_MASK; if (cmd != CFCTRL_CMD_LINK_ERR && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp)) { - if (handle_loop(cfctrl, cmd, pkt) == CAIF_FAILURE) { - pr_info("CAIF: %s() CAIF Protocol error:" - "Response bit not set\n", __func__); - goto error; - } + if (handle_loop(cfctrl, cmd, pkt) == CAIF_FAILURE) + cmdrsp |= CFCTRL_ERR_BIT; } switch (cmd) { @@ -463,12 +499,12 @@ static int cfctrl_recv(struct layer *layer, struct cfpkt *pkt) { enum cfctrl_srv serv; enum cfctrl_srv servtype; - uint8 endpoint; - uint8 physlinkid; - uint8 prio; - uint8 tmp; - uint32 tmp32; - uint8 *cp; + u8 endpoint; + u8 physlinkid; + u8 prio; + u8 tmp; + u32 tmp32; + u8 *cp; int i; struct cfctrl_link_param linkparam; memset(&linkparam, 0, sizeof(linkparam)); @@ -493,12 +529,16 @@ static int cfctrl_recv(struct layer *layer, struct cfpkt *pkt) switch (serv) { case CFCTRL_SRV_VEI: case CFCTRL_SRV_DBG: + if (CFCTRL_ERR_BIT & cmdrsp) + break; /* Link ID */ cfpkt_extr_head(pkt, &linkid, 1); break; case CFCTRL_SRV_VIDEO: cfpkt_extr_head(pkt, &tmp, 1); linkparam.u.video.connid = tmp; + if (CFCTRL_ERR_BIT & cmdrsp) + break; /* Link ID */ cfpkt_extr_head(pkt, &linkid, 1); break; @@ -506,7 +546,9 @@ static int cfctrl_recv(struct layer *layer, struct cfpkt *pkt) case CFCTRL_SRV_DATAGRAM: cfpkt_extr_head(pkt, &tmp32, 4); linkparam.u.datagram.connid = - cfglu_le32_to_cpu(tmp32); + le32_to_cpu(tmp32); + if (CFCTRL_ERR_BIT & cmdrsp) + break; /* Link ID */ cfpkt_extr_head(pkt, &linkid, 1); break; @@ -517,14 +559,16 @@ static int cfctrl_recv(struct layer *layer, struct cfpkt *pkt) */ cfpkt_extr_head(pkt, &tmp32, 4); linkparam.u.rfm.connid = - cfglu_le32_to_cpu(tmp32); - cp = (uint8 *) linkparam.u.rfm.volume; + le32_to_cpu(tmp32); + cp = (u8 *) linkparam.u.rfm.volume; for (cfpkt_extr_head(pkt, &tmp, 1); cfpkt_more(pkt) && tmp != '\0'; cfpkt_extr_head(pkt, &tmp, 1)) *cp++ = tmp; *cp = '\0'; + if (CFCTRL_ERR_BIT & cmdrsp) + break; /* Link ID */ cfpkt_extr_head(pkt, &linkid, 1); @@ -537,13 +581,13 @@ static int cfctrl_recv(struct layer *layer, struct cfpkt *pkt) /* Fifosize KB */ cfpkt_extr_head(pkt, &tmp16, 2); linkparam.u.utility.fifosize_kb = - cfglu_le16_to_cpu(tmp16); + le16_to_cpu(tmp16); /* Fifosize bufs */ cfpkt_extr_head(pkt, &tmp16, 2); linkparam.u.utility.fifosize_bufs = - cfglu_le16_to_cpu(tmp16); + le16_to_cpu(tmp16); /* name */ - cp = (uint8 *) linkparam.u.utility.name; + cp = (u8 *) linkparam.u.utility.name; caif_assert(sizeof(linkparam.u.utility.name) >= UTILITY_NAME_LENGTH); for (i = 0; @@ -561,6 +605,8 @@ static int cfctrl_recv(struct layer *layer, struct cfpkt *pkt) cfpkt_extr_head(pkt, &tmp, 1); *cp++ = tmp; } + if (CFCTRL_ERR_BIT & cmdrsp) + break; /* Link ID */ cfpkt_extr_head(pkt, &linkid, 1); /* Length */ @@ -574,18 +620,16 @@ static int cfctrl_recv(struct layer *layer, struct cfpkt *pkt) __func__, serv); goto error; } - if (cfpkt_erroneous(pkt)) { - pr_err("CAIF: %s(): Packet is erroneous!", - __func__); - goto error; - } + rsp.cmd = cmd; rsp.param = linkparam; req = cfctrl_remove_req(cfctrl, &rsp); - if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp)) { - pr_err("CAIF: %s(): Invalid O/E bit " - "on CAIF control channel", __func__); + if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) || + cfpkt_erroneous(pkt)) { + pr_err("CAIF: %s(): Invalid O/E bit or parse " + "error on CAIF control channel", + __func__); cfctrl->res.reject_rsp(cfctrl->serv.layer.up, 0, req ? req->client_layer @@ -599,21 +643,15 @@ static int cfctrl_recv(struct layer *layer, struct cfpkt *pkt) } if (req != NULL) - cfglu_free(req); + kfree(req); } break; case CFCTRL_CMD_LINK_DESTROY: cfpkt_extr_head(pkt, &linkid, 1); - rsp.cmd = cmd; - rsp.channel_id = linkid; - req = cfctrl_remove_req(cfctrl, &rsp); - cfctrl->res.linkdestroy_rsp(cfctrl->serv.layer.up, linkid, - req ? req->client_layer : NULL); - if (req != NULL) - cfglu_free(req); + cfctrl->res.linkdestroy_rsp(cfctrl->serv.layer.up, linkid); break; case CFCTRL_CMD_LINK_ERR: - pr_err("CAIF: %s(): Frame Error Indication received \n", + pr_err("CAIF: %s(): Frame Error Indication received\n", __func__); cfctrl->res.linkerror_ind(); break; @@ -643,19 +681,19 @@ error: return ret; } -static void cfctrl_ctrlcmd(struct layer *layr, enum caif_ctrlcmd ctrl, +static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, int phyid) { struct cfctrl *this = container_obj(layr); switch (ctrl) { case _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND: case CAIF_CTRLCMD_FLOW_OFF_IND: - cfglu_lock(this->info_list_lock); + spin_lock(&this->info_list_lock); if (this->first_req != NULL) { - pr_warning("CAIF: %s(): Received flow off in " + pr_debug("CAIF: %s(): Received flow off in " "control layer", __func__); } - cfglu_unlock(this->info_list_lock); + spin_unlock(&this->info_list_lock); break; default: break; @@ -663,20 +701,30 @@ static void cfctrl_ctrlcmd(struct layer *layr, enum caif_ctrlcmd ctrl, } #ifndef CAIF_NO_LOOP -int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt) +static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt) { - uint8 linkid, linktype, tmp; + static int last_linkid; + u8 linkid, linktype, tmp; switch (cmd) { case CFCTRL_CMD_LINK_SETUP: - cfglu_lock(ctrl->loop_linkid_lock); - for (linkid = 0x1; linkid < 255; linkid++) { - if (!ctrl->loop_linkused[linkid]) { - ctrl->loop_linkused[linkid] = 1; - break; - } - } + spin_lock(&ctrl->loop_linkid_lock); + for (linkid = last_linkid + 1; linkid < 255; linkid++) + if (!ctrl->loop_linkused[linkid]) + goto found; + for (linkid = last_linkid - 1; linkid > 0; linkid--) + if (!ctrl->loop_linkused[linkid]) + goto found; + spin_unlock(&ctrl->loop_linkid_lock); + pr_err("CAIF: %s(): Out of link-ids\n", __func__); + return -EINVAL; +found: + if (!ctrl->loop_linkused[linkid]) + ctrl->loop_linkused[linkid] = 1; + + last_linkid = linkid; + cfpkt_add_trail(pkt, &linkid, 1); - cfglu_unlock(ctrl->loop_linkid_lock); + spin_unlock(&ctrl->loop_linkid_lock); cfpkt_peek_head(pkt, &linktype, 1); if (linktype == CFCTRL_SRV_UTIL) { tmp = 0x01; @@ -686,10 +734,10 @@ int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt) break; case CFCTRL_CMD_LINK_DESTROY: - cfglu_lock(ctrl->loop_linkid_lock); + spin_lock(&ctrl->loop_linkid_lock); cfpkt_peek_head(pkt, &linkid, 1); ctrl->loop_linkused[linkid] = 0; - cfglu_unlock(ctrl->loop_linkid_lock); + spin_unlock(&ctrl->loop_linkid_lock); break; default: break; diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c index f9b1bed7128..53194840ecb 100644 --- a/net/caif/cfdgml.c +++ b/net/caif/cfdgml.c @@ -1,13 +1,15 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/caif_layer.h> -#include <net/caif/generic/cfsrvl.h> -#include <net/caif/generic/cfpkt.h> +#include <linux/stddef.h> +#include <linux/spinlock.h> +#include <linux/slab.h> +#include <net/caif/caif_layer.h> +#include <net/caif/cfsrvl.h> +#include <net/caif/cfpkt.h> #define container_obj(layr) ((struct cfsrvl *) layr) @@ -16,12 +18,12 @@ #define DGM_FLOW_ON 0x80 #define DGM_CTRL_PKT_SIZE 1 -static int cfdgml_receive(struct layer *layr, struct cfpkt *pkt); -static int cfdgml_transmit(struct layer *layr, struct cfpkt *pkt); +static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt); +static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt); -struct layer *cfdgml_create(uint8 channel_id, struct dev_info *dev_info) +struct cflayer *cfdgml_create(u8 channel_id, struct dev_info *dev_info) { - struct cfsrvl *dgm = cfglu_alloc(sizeof(struct cfsrvl)); + struct cfsrvl *dgm = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!dgm) { pr_warning("CAIF: %s(): Out of memory\n", __func__); return NULL; @@ -36,10 +38,10 @@ struct layer *cfdgml_create(uint8 channel_id, struct dev_info *dev_info) return &dgm->layer; } -static int cfdgml_receive(struct layer *layr, struct cfpkt *pkt) +static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt) { - uint8 cmd = -1; - uint8 dgmhdr[3]; + u8 cmd = -1; + u8 dgmhdr[3]; int ret; caif_assert(layr->up != NULL); caif_assert(layr->receive != NULL); @@ -48,14 +50,14 @@ static int cfdgml_receive(struct layer *layr, struct cfpkt *pkt) if (cfpkt_extr_head(pkt, &cmd, 1) < 0) { pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); cfpkt_destroy(pkt); - return CFGLU_EPROTO; + return -EPROTO; } if ((cmd & DGM_CMD_BIT) == 0) { if (cfpkt_extr_head(pkt, &dgmhdr, 3) < 0) { pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); cfpkt_destroy(pkt); - return CFGLU_EPROTO; + return -EPROTO; } ret = layr->up->receive(layr->up, pkt); return ret; @@ -74,14 +76,14 @@ static int cfdgml_receive(struct layer *layr, struct cfpkt *pkt) cfpkt_destroy(pkt); pr_info("CAIF: %s(): Unknown datagram control %d (0x%x)\n", __func__, cmd, cmd); - return CFGLU_EPROTO; + return -EPROTO; } } -static int cfdgml_transmit(struct layer *layr, struct cfpkt *pkt) +static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt) { - uint32 zero = 0; - struct payload_info *info; + u32 zero = 0; + struct caif_payload_info *info; struct cfsrvl *service = container_obj(layr); int ret; if (!cfsrvl_ready(service, &ret)) @@ -99,7 +101,7 @@ static int cfdgml_transmit(struct layer *layr, struct cfpkt *pkt) info->dev_info = &service->dev_info; ret = layr->dn->transmit(layr->dn, pkt); if (ret < 0) { - uint32 tmp32; + u32 tmp32; cfpkt_extr_head(pkt, &tmp32, 4); } return ret; diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c index 25c78a9dd77..e86a4ca3b21 100644 --- a/net/caif/cffrml.c +++ b/net/caif/cffrml.c @@ -1,78 +1,81 @@ /* * CAIF Framing Layer. * - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ -#define container_obj(layr) cfglu_container_of(layr, struct cffrml, layer) +#include <linux/stddef.h> +#include <linux/spinlock.h> +#include <linux/slab.h> +#include <linux/crc-ccitt.h> +#include <net/caif/caif_layer.h> +#include <net/caif/cfpkt.h> +#include <net/caif/cffrml.h> -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/caif_layer.h> -#include <net/caif/generic/cfpkt.h> -#include <net/caif/generic/cffrml.h> +#define container_obj(layr) container_of(layr, struct cffrml, layer) struct cffrml { - struct layer layer; + struct cflayer layer; bool dofcs; /* !< FCS active */ }; -static int cffrml_receive(struct layer *layr, struct cfpkt *pkt); -static int cffrml_transmit(struct layer *layr, struct cfpkt *pkt); -static void cffrml_ctrlcmd(struct layer *layr, enum caif_ctrlcmd ctrl, +static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt); +static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt); +static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, int phyid); -uint32 cffrml_rcv_error; -uint32 cffrml_rcv_checsum_error; -struct layer *cffrml_create(uint16 phyid, bool use_fcs) +static u32 cffrml_rcv_error; +static u32 cffrml_rcv_checsum_error; +struct cflayer *cffrml_create(u16 phyid, bool use_fcs) { - struct cffrml *this = cfglu_alloc(sizeof(struct cffrml)); + struct cffrml *this = kmalloc(sizeof(struct cffrml), GFP_ATOMIC); if (!this) { pr_warning("CAIF: %s(): Out of memory\n", __func__); return NULL; } caif_assert(offsetof(struct cffrml, layer) == 0); - memset(this, 0, sizeof(struct layer)); + memset(this, 0, sizeof(struct cflayer)); this->layer.receive = cffrml_receive; this->layer.transmit = cffrml_transmit; this->layer.ctrlcmd = cffrml_ctrlcmd; snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "frm%d", phyid); this->dofcs = use_fcs; this->layer.id = phyid; - return (struct layer *) this; + return (struct cflayer *) this; } -void cffrml_set_uplayer(struct layer *this, struct layer *up) +void cffrml_set_uplayer(struct cflayer *this, struct cflayer *up) { this->up = up; } -void cffrml_set_dnlayer(struct layer *this, struct layer *dn) +void cffrml_set_dnlayer(struct cflayer *this, struct cflayer *dn) { this->dn = dn; } -static uint16 cffrml_checksum(uint16 chks, void *buf, uint16 len) +static u16 cffrml_checksum(u16 chks, void *buf, u16 len) { /* FIXME: FCS should be moved to glue in order to use OS-Specific * solutions */ - return fcs16(chks, buf, len); + return crc_ccitt(chks, buf, len); } -static int cffrml_receive(struct layer *layr, struct cfpkt *pkt) +static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt) { - uint16 tmp; - uint16 len; - uint16 hdrchks; - uint16 pktchks; + u16 tmp; + u16 len; + u16 hdrchks; + u16 pktchks; struct cffrml *this; this = container_obj(layr); cfpkt_extr_head(pkt, &tmp, 2); - len = cfglu_le16_to_cpu(tmp); + len = le16_to_cpu(tmp); /* Subtract for FCS on length if FCS is not used. */ if (!this->dofcs) @@ -82,7 +85,7 @@ static int cffrml_receive(struct layer *layr, struct cfpkt *pkt) ++cffrml_rcv_error; pr_err("CAIF: %s():Framing length error (%d)\n", __func__, len); cfpkt_destroy(pkt); - return CFGLU_EPKT; + return -EPROTO; } /* * Don't do extract if FCS is false, rather do setlen - then we don't @@ -90,7 +93,7 @@ static int cffrml_receive(struct layer *layr, struct cfpkt *pkt) */ if (this->dofcs) { cfpkt_extr_trail(pkt, &tmp, 2); - hdrchks = cfglu_le16_to_cpu(tmp); + hdrchks = le16_to_cpu(tmp); pktchks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff); if (pktchks != hdrchks) { cfpkt_add_trail(pkt, &tmp, 2); @@ -98,39 +101,39 @@ static int cffrml_receive(struct layer *layr, struct cfpkt *pkt) ++cffrml_rcv_checsum_error; pr_info("CAIF: %s(): Frame checksum error " "(0x%x != 0x%x)\n", __func__, hdrchks, pktchks); - return CFGLU_EFCS; + return -EILSEQ; } } if (cfpkt_erroneous(pkt)) { ++cffrml_rcv_error; pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); cfpkt_destroy(pkt); - return CFGLU_EPKT; + return -EPROTO; } return layr->up->receive(layr->up, pkt); } -static int cffrml_transmit(struct layer *layr, struct cfpkt *pkt) +static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt) { int tmp; - uint16 chks; - uint16 len; + u16 chks; + u16 len; int ret; struct cffrml *this = container_obj(layr); if (this->dofcs) { chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff); - tmp = cfglu_cpu_to_le16(chks); + tmp = cpu_to_le16(chks); cfpkt_add_trail(pkt, &tmp, 2); } else { cfpkt_pad_trail(pkt, 2); } len = cfpkt_getlen(pkt); - tmp = cfglu_cpu_to_le16(len); + tmp = cpu_to_le16(len); cfpkt_add_head(pkt, &tmp, 2); cfpkt_info(pkt)->hdr_len += 2; if (cfpkt_erroneous(pkt)) { pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); - return CFGLU_EPROTO; + return -EPROTO; } ret = layr->dn->transmit(layr->dn, pkt); if (ret < 0) { @@ -140,7 +143,7 @@ static int cffrml_transmit(struct layer *layr, struct cfpkt *pkt) return ret; } -static void cffrml_ctrlcmd(struct layer *layr, enum caif_ctrlcmd ctrl, +static void cffrml_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, int phyid) { if (layr->up->ctrlcmd) diff --git a/net/caif/cflist.c b/net/caif/cflist.c index 1be38d48a14..0109cc05029 100644 --- a/net/caif/cflist.c +++ b/net/caif/cflist.c @@ -1,21 +1,23 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/hardirq.h> +#include <net/caif/cfpkt.h> +#include <net/caif/cflst.h> -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/cfpkt.h> -#include <net/caif/generic/cflst.h> -void cflst_init(struct layer **lst) +void cflst_init(struct cflayer **lst) { *lst = NULL; } -struct layer *cflst_remove(struct layer **lst, struct layer *elem) +struct cflayer *cflst_remove(struct cflayer **lst, struct cflayer *elem) { - struct layer *tmp; + struct cflayer *tmp; if (*lst == NULL) return NULL; @@ -25,9 +27,9 @@ struct layer *cflst_remove(struct layer **lst, struct layer *elem) } /* Adds an element from the queue. */ -void cflst_insert(struct layer **lst, struct layer *node) +void cflst_insert(struct cflayer **lst, struct cflayer *node) { - struct layer *tmp; + struct cflayer *tmp; node->next = NULL; if ((*lst) == NULL) { (*lst) = node; @@ -39,20 +41,20 @@ void cflst_insert(struct layer **lst, struct layer *node) tmp->next = node; } -int cflst_put(struct layer **lst, uint8 id, struct layer *node) +int cflst_put(struct cflayer **lst, u8 id, struct cflayer *node) { if (cflst_get(lst, id) != NULL) { pr_err("CAIF: %s(): cflst_put duplicate key\n", __func__); - return CFGLU_EINVAL; + return -EINVAL; } node->id = id; cflst_insert(lst, node); - return CFGLU_EOK; + return 0; } -struct layer *cflst_get(struct layer * *lst, uint8 id) +struct cflayer *cflst_get(struct cflayer * *lst, u8 id) { - struct layer *node; + struct cflayer *node; for (node = (*lst); node != NULL; node = node->next) { if (id == node->id) return node; @@ -60,10 +62,10 @@ struct layer *cflst_get(struct layer * *lst, uint8 id) return NULL; } -struct layer *cflst_del(struct layer * *lst, uint8 id) +struct cflayer *cflst_del(struct cflayer * *lst, u8 id) { - struct layer *iter; - struct layer *node = NULL; + struct cflayer *iter; + struct cflayer *node = NULL; if ((*lst) == NULL) return NULL; diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c index f68ad8ead1d..7372f27f1d3 100644 --- a/net/caif/cfmuxl.c +++ b/net/caif/cfmuxl.c @@ -1,225 +1,251 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ +#include <linux/stddef.h> +#include <linux/spinlock.h> +#include <linux/slab.h> +#include <net/caif/cfpkt.h> +#include <net/caif/cfmuxl.h> +#include <net/caif/cfsrvl.h> +#include <net/caif/cffrml.h> -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/cfpkt.h> -#include <net/caif/generic/cflst.h> -#include <net/caif/generic/cfmuxl.h> -#include <net/caif/generic/cfsrvl.h> -#include <net/caif/generic/cffrml.h> - -#define container_obj(layr) cfglu_container_of(layr, struct cfmuxl, layer) +#define container_obj(layr) container_of(layr, struct cfmuxl, layer) #define CAIF_CTRL_CHANNEL 0 #define UP_CACHE_SIZE 8 #define DN_CACHE_SIZE 8 struct cfmuxl { - struct layer layer; - struct layer *up_cache[UP_CACHE_SIZE]; - struct layer *dn_cache[DN_CACHE_SIZE]; + 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. */ - cfglu_lock_t transmit_lock; + spinlock_t transmit_lock; /* * Set when inserting or removing upwards layers. */ - cfglu_lock_t receive_lock; + spinlock_t receive_lock; }; -static int cfmuxl_receive(struct layer *layr, struct cfpkt *pkt); -static int cfmuxl_transmit(struct layer *layr, struct cfpkt *pkt); -static void cfmuxl_ctrlcmd(struct layer *layr, enum caif_ctrlcmd ctrl, +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 layer *get_up(struct cfmuxl *muxl, int id); +static struct cflayer *get_up(struct cfmuxl *muxl, u16 id); -struct layer *cfmuxl_create() +struct cflayer *cfmuxl_create(void) { - struct cfmuxl *this = cfglu_alloc(sizeof(struct cfmuxl)); - if (!this) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + struct cfmuxl *this = kmalloc(sizeof(struct cfmuxl), GFP_ATOMIC); + if (!this) return NULL; - } memset(this, 0, sizeof(*this)); this->layer.receive = cfmuxl_receive; this->layer.transmit = cfmuxl_transmit; this->layer.ctrlcmd = cfmuxl_ctrlcmd; - cfglu_init_lock(this->transmit_lock); - cfglu_init_lock(this->receive_lock); + 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_uplayer(struct layer *layr, struct layer *up, uint8 linkid) +int cfmuxl_set_uplayer(struct cflayer *layr, struct cflayer *up, u8 linkid) { - int res; struct cfmuxl *muxl = container_obj(layr); - cfglu_lock(muxl->receive_lock); - res = cflst_put(&muxl->layer.up, linkid, up); - cfglu_unlock(muxl->receive_lock); - return res; + spin_lock(&muxl->receive_lock); + cfsrvl_get(up); + list_add(&up->node, &muxl->srvl_list); + spin_unlock(&muxl->receive_lock); + return 0; } -bool cfmuxl_is_phy_inuse(struct layer *layr, uint8 phyid) +bool cfmuxl_is_phy_inuse(struct cflayer *layr, u8 phyid) { - struct layer *p; + struct list_head *node; + struct cflayer *layer; struct cfmuxl *muxl = container_obj(layr); bool match = false; - cfglu_lock(muxl->receive_lock); + spin_lock(&muxl->receive_lock); - for (p = layr->up; p != NULL; p = p->next) { - if (cfsrvl_phyid_match(p, phyid)) { + list_for_each(node, &muxl->srvl_list) { + layer = list_entry(node, struct cflayer, node); + if (cfsrvl_phyid_match(layer, phyid)) { match = true; break; } + } - cfglu_unlock(muxl->receive_lock); + spin_unlock(&muxl->receive_lock); return match; } -uint8 cfmuxl_get_phyid(struct layer *layr, uint8 channel_id) +u8 cfmuxl_get_phyid(struct cflayer *layr, u8 channel_id) { - struct layer *up; + struct cflayer *up; int phyid; struct cfmuxl *muxl = container_obj(layr); - cfglu_lock(muxl->receive_lock); + spin_lock(&muxl->receive_lock); up = get_up(muxl, channel_id); if (up != NULL) phyid = cfsrvl_getphyid(up); else phyid = 0; - cfglu_unlock(muxl->receive_lock); + spin_unlock(&muxl->receive_lock); return phyid; } -int cfmuxl_set_dnlayer(struct layer *layr, struct layer *dn, uint8 phyid) +int cfmuxl_set_dnlayer(struct cflayer *layr, struct cflayer *dn, u8 phyid) { - int ret; struct cfmuxl *muxl = (struct cfmuxl *) layr; - cfglu_lock(muxl->transmit_lock); - ret = cflst_put(&muxl->layer.dn, phyid, dn); - cfglu_unlock(muxl->transmit_lock); - return ret; + spin_lock(&muxl->transmit_lock); + list_add(&dn->node, &muxl->frml_list); + spin_unlock(&muxl->transmit_lock); + return 0; } -struct layer *cfmuxl_remove_dnlayer(struct layer *layr, uint8 phyid) +static struct cflayer *get_from_id(struct list_head *list, u16 id) +{ + struct list_head *node; + struct cflayer *layer; + list_for_each(node, list) { + layer = list_entry(node, struct cflayer, node); + if (layer->id == id) + return layer; + } + return NULL; +} + +struct cflayer *cfmuxl_remove_dnlayer(struct cflayer *layr, u8 phyid) { struct cfmuxl *muxl = container_obj(layr); - struct layer *dn; - cfglu_lock(muxl->transmit_lock); + struct cflayer *dn; + spin_lock(&muxl->transmit_lock); memset(muxl->dn_cache, 0, sizeof(muxl->dn_cache)); - dn = cflst_del(&muxl->layer.dn, phyid); + dn = get_from_id(&muxl->frml_list, phyid); + if (dn == NULL) { + spin_unlock(&muxl->transmit_lock); + return NULL; + } + list_del(&dn->node); caif_assert(dn != NULL); - cfglu_unlock(muxl->transmit_lock); + spin_unlock(&muxl->transmit_lock); return dn; } /* Invariant: lock is taken */ -static struct layer *get_up(struct cfmuxl *muxl, int id) +static struct cflayer *get_up(struct cfmuxl *muxl, u16 id) { - struct layer *up; + struct cflayer *up; int idx = id % UP_CACHE_SIZE; up = muxl->up_cache[idx]; if (up == NULL || up->id != id) { - up = cflst_get(&muxl->layer.up, id); + up = get_from_id(&muxl->srvl_list, id); muxl->up_cache[idx] = up; } return up; } /* Invariant: lock is taken */ -static struct layer *get_dn(struct cfmuxl *muxl, struct dev_info *dev_info) +static struct cflayer *get_dn(struct cfmuxl *muxl, struct dev_info *dev_info) { - struct layer *dn; + struct cflayer *dn; int idx = dev_info->id % DN_CACHE_SIZE; dn = muxl->dn_cache[idx]; if (dn == NULL || dn->id != dev_info->id) { - dn = cflst_get(&muxl->layer.dn, dev_info->id); + dn = get_from_id(&muxl->frml_list, dev_info->id); muxl->dn_cache[idx] = dn; } return dn; } -struct layer *cfmuxl_remove_uplayer(struct layer *layr, uint8 id) +struct cflayer *cfmuxl_remove_uplayer(struct cflayer *layr, u8 id) { - struct layer *up; + struct cflayer *up; struct cfmuxl *muxl = container_obj(layr); - cfglu_lock(muxl->receive_lock); + spin_lock(&muxl->receive_lock); + up = get_up(muxl, id); + if (up == NULL) + return NULL; memset(muxl->up_cache, 0, sizeof(muxl->up_cache)); - up = cflst_del(&muxl->layer.up, id); - cfglu_unlock(muxl->receive_lock); + list_del(&up->node); + cfsrvl_put(up); + spin_unlock(&muxl->receive_lock); return up; } -static int cfmuxl_receive(struct layer *layr, struct cfpkt *pkt) +static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt) { int ret; struct cfmuxl *muxl = container_obj(layr); - uint8 id; - struct layer *up; + u8 id; + struct cflayer *up; if (cfpkt_extr_head(pkt, &id, 1) < 0) { pr_err("CAIF: %s(): erroneous Caif Packet\n", __func__); cfpkt_destroy(pkt); - return CFGLU_EPKT; + return -EPROTO; } + spin_lock(&muxl->receive_lock); up = get_up(muxl, id); + spin_unlock(&muxl->receive_lock); if (up == NULL) { pr_info("CAIF: %s():Received data on unknown link ID = %d " "(0x%x) up == NULL", __func__, id, id); cfpkt_destroy(pkt); /* * Don't return ERROR, since modem misbehaves and sends out - * flow before linksetup response. + * flow on before linksetup response. */ - return /* CFGLU_EPROT; */ CFGLU_EOK; + return /* CFGLU_EPROT; */ 0; } - + cfsrvl_get(up); ret = up->receive(up, pkt); - - + cfsrvl_put(up); return ret; } -static int cfmuxl_transmit(struct layer *layr, struct cfpkt *pkt) +static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt) { int ret; struct cfmuxl *muxl = container_obj(layr); - uint8 linkid; - struct layer *dn; - struct payload_info *info = cfpkt_info(pkt); + u8 linkid; + struct cflayer *dn; + struct caif_payload_info *info = cfpkt_info(pkt); dn = get_dn(muxl, cfpkt_info(pkt)->dev_info); if (dn == NULL) { pr_warning("CAIF: %s(): Send data on unknown phy " "ID = %d (0x%x)\n", __func__, info->dev_info->id, info->dev_info->id); - return CFGLU_ENOTCONN; + return -ENOTCONN; } info->hdr_len += 1; linkid = info->channel_id; cfpkt_add_head(pkt, &linkid, 1); ret = dn->transmit(dn, pkt); - if (ret < 0) { - /* Remove MUX protocol header upon error. */ + /* Remove MUX protocol header upon error. */ + if (ret < 0) cfpkt_extr_head(pkt, &linkid, 1); - } - return ret; } -static void cfmuxl_ctrlcmd(struct layer *layr, enum caif_ctrlcmd ctrl, +static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, int phyid) { - struct layer *p; struct cfmuxl *muxl = container_obj(layr); - for (p = muxl->layer.up; p != NULL; p = p->next) { - if (cfsrvl_phyid_match(p, phyid)) - p->ctrlcmd(p, ctrl, phyid); + struct list_head *node; + struct cflayer *layer; + list_for_each(node, &muxl->srvl_list) { + layer = list_entry(node, struct cflayer, node); + if (cfsrvl_phyid_match(layer, phyid)) + layer->ctrlcmd(layer, ctrl, phyid); } } diff --git a/net/caif/cfpkt_plain.c b/net/caif/cfpkt_plain.c index 906df250adf..f6bf09c474a 100644 --- a/net/caif/cfpkt_plain.c +++ b/net/caif/cfpkt_plain.c @@ -1,11 +1,10 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/cfpkt.h> +#include <net/caif/cfpkt.h> /* NOTE: Excluding physical layer, max is 10 bytes. Physical layer is * uncertain. @@ -18,9 +17,9 @@ #define MAGIC_VALUE 0xbaadf00d /* Return closest 32bit aligned address (by adding) */ -#define ALIGN32(p) (((((uint32)p)&0x3) == 0) ?\ - ((uint32) p) :\ - (((uint32)p) + (0x4 - (((uint32)p)&0x3)))) +#define ALIGN32(p) (((((u32)p)&0x3) == 0) ?\ + ((u32) p) :\ + (((u32)p) + (0x4 - (((u32)p)&0x3)))) /* Do division by 0 on failure - CRASH */ #define CHECK_MAGIC(pkt) \ @@ -46,55 +45,55 @@ */ struct _payload { - uint32 magic2; - uint8 buf[1]; + u32 magic2; + u8 buf[1]; }; struct cfpkt { - uint32 magic1; - uint32 *magic2; /* This will point to location before _head_ */ - struct payload_info info; + u32 magic1; + u32 *magic2; /* This will point to location before _head_ */ + struct caif_payload_info info; void *blob; struct cfpkt *next; - const uint8 *_head_; /* Start of buffer, i.e. first legal + const u8 *_head_; /* Start of buffer, i.e. first legal * pos for _data_ */ - uint8 *_data_; /* Start of payload */ - uint8 *_tail_; /* End of payload data */ - uint8 *_end_; /* End of buffer, i.e. last legal pos + u8 *_data_; /* Start of payload */ + u8 *_tail_; /* End of payload data */ + u8 *_end_; /* End of buffer, i.e. last legal pos * for _tail_ */ }; #define PKT_ERROR(pkt, errmsg) do {\ - pkt->_data_ = pkt->_tail_ = pkt->_end_ = (uint8 *)pkt->_head_;\ + pkt->_data_ = pkt->_tail_ = pkt->_end_ = (u8 *)pkt->_head_;\ pr_err(errmsg); } while (0) struct cfpktq { struct cfpkt *head; - cfglu_lock_t qlock; + spinlock_t qlock; int count; }; -cfglu_atomic_t cfpkt_packet_count; +atomic_t cfpkt_packet_count; EXPORT_SYMBOL(cfpkt_packet_count); -struct cfpkt *cfpkt_create_pfx(uint16 len, uint16 pfx) +struct cfpkt *cfpkt_create_pfx(u16 len, u16 pfx) { int pldlen; int bloblen; struct cfpkt *pkt; void *blob; struct _payload *pld; - uint8 *pktstruct; + u8 *pktstruct; void *blobend, *structend; - cfglu_atomic_inc(cfpkt_packet_count); + atomic_inc(&cfpkt_packet_count); /* (1) Compute payload length */ pldlen = len + pfx; if (pldlen < PKT_MINSIZE) pldlen = PKT_MINSIZE; /* Make room for Magic before & after payload */ - pldlen += 2 * sizeof(uint32); + pldlen += 2 * sizeof(u32); pldlen = ALIGN32(pldlen); /* (2) Compute blob length, payload + packet struct */ @@ -105,7 +104,7 @@ struct cfpkt *cfpkt_create_pfx(uint16 len, uint16 pfx) /* (3) Allocate the blob */ blob = cfglu_alloc(bloblen); - blobend = (uint8 *) blob + bloblen; + blobend = (u8 *) blob + bloblen; /* Initialize payload struct */ pld = (struct _payload *) blob; @@ -113,7 +112,7 @@ struct cfpkt *cfpkt_create_pfx(uint16 len, uint16 pfx) /* Initialize packet struct */ pktstruct = pld->buf + pldlen; - pktstruct = (uint8 *) ALIGN32(pktstruct); + pktstruct = (u8 *) ALIGN32(pktstruct); structend = pktstruct + sizeof(struct cfpkt); memset(pktstruct, 0, sizeof(struct cfpkt)); caif_assert(structend <= blobend); @@ -121,17 +120,17 @@ struct cfpkt *cfpkt_create_pfx(uint16 len, uint16 pfx) pkt->blob = blob; pkt->_end_ = &pld->buf[pldlen]; pkt->_head_ = &pld->buf[0]; - pkt->_data_ = (uint8 *) pkt->_head_ + pfx; + pkt->_data_ = (u8 *) pkt->_head_ + pfx; pkt->_tail_ = pkt->_data_; pkt->magic1 = MAGIC_VALUE; - pkt->magic2 = (uint32 *) &pld->buf[pldlen]; + pkt->magic2 = (u32 *) &pld->buf[pldlen]; *pkt->magic2 = MAGIC_VALUE; CHECK_MAGIC(pkt); return pkt; } -struct cfpkt *cfpkt_create(uint16 len) +struct cfpkt *cfpkt_create(u16 len) { return cfpkt_create_pfx(len, PKT_PREFIX); } @@ -139,9 +138,9 @@ struct cfpkt *cfpkt_create(uint16 len) void cfpkt_destroy(struct cfpkt *pkt) { CHECK_MAGIC(pkt); - cfglu_atomic_dec(cfpkt_packet_count); - caif_assert(cfglu_atomic_read(cfpkt_packet_count) >= 0); - cfglu_free(pkt->blob); + atomic_dec(&cfpkt_packet_count); + caif_assert(atomic_read(&cfpkt_packet_count) >= 0); + kfree(pkt->blob); } bool cfpkt_more(struct cfpkt *pkt) @@ -150,35 +149,35 @@ bool cfpkt_more(struct cfpkt *pkt) return pkt->_data_ < pkt->_tail_; } -int cfpkt_extr_head(struct cfpkt *pkt, void *dta, uint16 len) +int cfpkt_extr_head(struct cfpkt *pkt, void *dta, u16 len) { register int i; - uint8 *data = dta; + u8 *data = dta; caif_assert(data != NULL); CHECK_MAGIC(pkt); if (pkt->_data_ + len > pkt->_tail_) { PKT_ERROR(pkt, "cfpkt_extr_head would read beyond end of packet\n"); - return CFGLU_EPKT; + return -EPROTO; } for (i = 0; i < len; i++) { data[i] = *pkt->_data_; pkt->_data_++; } CHECK_MAGIC(pkt); - return CFGLU_EOK; + return 0; } -int cfpkt_extr_trail(struct cfpkt *pkt, void *dta, uint16 len) +int cfpkt_extr_trail(struct cfpkt *pkt, void *dta, u16 len) { int i; - uint8 *data = dta; + u8 *data = dta; caif_assert(data != NULL); CHECK_MAGIC(pkt); if (pkt->_data_ + len > pkt->_tail_) { PKT_ERROR(pkt, "cfpkt_extr_trail would read beyond start of packet\n"); - return CFGLU_EPKT; + return -EPROTO; } data += len; for (i = 0; i < len; i++) { @@ -187,7 +186,7 @@ int cfpkt_extr_trail(struct cfpkt *pkt, void *dta, uint16 len) *data = *pkt->_tail_; } CHECK_MAGIC(pkt); - return CFGLU_EOK; + return 0; } char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen) @@ -213,16 +212,16 @@ char *cfpkt_log_pkt(struct cfpkt *pkt, char *buf, int buflen) return buf; } -int cfpkt_add_body(struct cfpkt *pkt, const void *dta, uint16 len) +int cfpkt_add_body(struct cfpkt *pkt, const void *dta, u16 len) { register int i; - const uint8 *data = dta; + const u8 *data = dta; caif_assert(data != NULL); CHECK_MAGIC(pkt); if (pkt->_tail_ + len > pkt->_end_) { PKT_ERROR(pkt, "cfpkt_add_body would write beyond end of packet\n"); - return CFGLU_EPKT; + return -EPROTO; } for (i = 0; i < len; i++) { @@ -230,34 +229,34 @@ int cfpkt_add_body(struct cfpkt *pkt, const void *dta, uint16 len) pkt->_tail_++; } CHECK_MAGIC(pkt); - return CFGLU_EOK; + return 0; } -int cfpkt_addbdy(struct cfpkt *pkt, uint8 data) +int cfpkt_addbdy(struct cfpkt *pkt, u8 data) { CHECK_MAGIC(pkt); return cfpkt_add_body(pkt, &data, 1); } -int cfpkt_add_head(struct cfpkt *pkt, const void *dta, uint16 len) +int cfpkt_add_head(struct cfpkt *pkt, const void *dta, u16 len) { register int i; - const uint8 *data = dta; + const u8 *data = dta; caif_assert(data != NULL); CHECK_MAGIC(pkt); if (pkt->_data_ - len < pkt->_head_) { PKT_ERROR(pkt, "cfpkt_add_head: write beyond start of packet\n"); - return CFGLU_EPKT; + return -EPROTO; } for (i = len - 1; i >= 0; i--) { --pkt->_data_; *pkt->_data_ = data[i]; } CHECK_MAGIC(pkt); - return CFGLU_EOK; + return 0; } -int cfpkt_add_trail(struct cfpkt *pkt, const void *data, uint16 len) +int cfpkt_add_trail(struct cfpkt *pkt, const void *data, u16 len) { CHECK_MAGIC(pkt); caif_assert(data != NULL); @@ -265,25 +264,25 @@ int cfpkt_add_trail(struct cfpkt *pkt, const void *data, uint16 len) } -uint16 cfpkt_iterate(struct cfpkt *pkt, - uint16 (*func)(uint16 chks, void *buf, uint16 len), - uint16 data) +u16 cfpkt_iterate(struct cfpkt *pkt, + u16 (*func)(u16 chks, void *buf, u16 len), + u16 data) { return func(data, pkt->_data_, cfpkt_getlen(pkt)); } -int cfpkt_setlen(struct cfpkt *pkt, uint16 len) +int cfpkt_setlen(struct cfpkt *pkt, u16 len) { CHECK_MAGIC(pkt); if (pkt->_data_ + len > pkt->_end_) { PKT_ERROR(pkt, "cfpkt_setlen: Erroneous packet\n"); - return CFGLU_EPKT; + return -EPROTO; } pkt->_tail_ = pkt->_data_ + len; return cfpkt_getlen(pkt); } -uint16 cfpkt_getlen(struct cfpkt *pkt) +u16 cfpkt_getlen(struct cfpkt *pkt) { CHECK_MAGIC(pkt); return pkt->_tail_ - pkt->_data_; @@ -292,7 +291,7 @@ uint16 cfpkt_getlen(struct cfpkt *pkt) void cfpkt_extract(struct cfpkt *cfpkt, void *buf, unsigned int buflen, unsigned int *actual_len) { - uint16 pklen = cfpkt_getlen(cfpkt); + u16 pklen = cfpkt_getlen(cfpkt); caif_assert(buf != NULL); caif_assert(actual_len != NULL); CHECK_MAGIC(cfpkt); @@ -313,10 +312,10 @@ struct cfpkt *cfpkt_create_uplink(const unsigned char *data, unsigned int len) } struct cfpkt *cfpkt_append(struct cfpkt *dstpkt, struct cfpkt *addpkt, - uint16 expectlen) + u16 expectlen) { - uint16 addpktlen = addpkt->_tail_ - addpkt->_data_; - uint16 neededtailspace; + u16 addpktlen = addpkt->_tail_ - addpkt->_data_; + u16 neededtailspace; CHECK_MAGIC(dstpkt); CHECK_MAGIC(addpkt); if (expectlen > addpktlen) @@ -325,8 +324,8 @@ struct cfpkt *cfpkt_append(struct cfpkt *dstpkt, struct cfpkt *addpkt, neededtailspace = addpktlen; if (dstpkt->_tail_ + neededtailspace > dstpkt->_end_) { struct cfpkt *tmppkt; - uint16 dstlen; - uint16 createlen; + u16 dstlen; + u16 createlen; dstlen = dstpkt->_tail_ - dstpkt->_data_; createlen = dstlen + addpktlen; if (expectlen > createlen) @@ -345,11 +344,11 @@ struct cfpkt *cfpkt_append(struct cfpkt *dstpkt, struct cfpkt *addpkt, return dstpkt; } -struct cfpkt *cfpkt_split(struct cfpkt *pkt, uint16 pos) +struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos) { struct cfpkt *half; /* FIXME: Rename half to pkt2 */ - uint8 *split = pkt->_data_ + pos; - uint16 len2nd = pkt->_tail_ - split; + u8 *split = pkt->_data_ + pos; + u16 len2nd = pkt->_tail_ - split; CHECK_MAGIC(pkt); @@ -380,15 +379,15 @@ bool cfpkt_erroneous(struct cfpkt *pkt) /* Errors are marked by setting _end_ equal to _head_ (zero sized * packet) */ - return pkt->_end_ == (uint8 *) pkt->_head_; + return pkt->_end_ == (u8 *) pkt->_head_; } -int cfpkt_pad_trail(struct cfpkt *pkt, uint16 len) +int cfpkt_pad_trail(struct cfpkt *pkt, u16 len) { CHECK_MAGIC(pkt); if (pkt->_tail_ + len > pkt->_end_) { PKT_ERROR(pkt, "cfpkt_pad_trail pads beyond end of packet\n"); - return CFGLU_EPKT; + return -EPROTO; } #if 1 /* We're assuming that the modem doesn't require zero-padding */ @@ -399,23 +398,23 @@ int cfpkt_pad_trail(struct cfpkt *pkt, uint16 len) #endif CHECK_MAGIC(pkt); - return CFGLU_EOK; + return 0; } -int cfpkt_peek_head(struct cfpkt *const pkt, void *dta, uint16 len) +int cfpkt_peek_head(struct cfpkt *const pkt, void *dta, u16 len) { register int i; - uint8 *data = (uint8 *) dta; + u8 *data = (u8 *) dta; CHECK_MAGIC(pkt); if (pkt->_data_ + len > pkt->_tail_) { PKT_ERROR(pkt, "cfpkt_peek_head would read beyond end of packet\n"); - return CFGLU_EPKT; + return -EPROTO; } for (i = 0; i < len; i++) data[i] = pkt->_data_[i]; CHECK_MAGIC(pkt); - return CFGLU_EOK; + return 0; } @@ -425,12 +424,12 @@ int cfpkt_raw_append(struct cfpkt *cfpkt, void **buf, unsigned int buflen) if (cfpkt->_tail_ + buflen > cfpkt->_end_) { PKT_ERROR(cfpkt, "cfpkt_raw_append would append beyond end of packet\n"); - return CFGLU_EPKT; + return -EPROTO; } *buf = cfpkt->_tail_; cfpkt->_tail_ += buflen; - return CFGLU_EOK; + return 0; } int cfpkt_raw_extract(struct cfpkt *cfpkt, void **buf, unsigned int buflen) @@ -439,18 +438,18 @@ int cfpkt_raw_extract(struct cfpkt *cfpkt, void **buf, unsigned int buflen) if (cfpkt->_data_ + buflen > cfpkt->_tail_) { PKT_ERROR(cfpkt, "cfpkt_raw_extact would read beyond end of packet\n"); - return CFGLU_EPKT; + return -EPROTO; } *buf = cfpkt->_data_; cfpkt->_data_ += buflen; - return CFGLU_EOK; + return 0; } -struct cfpktq *cfpktq_create() +struct cfpktq *cfpktq_create(void) { struct cfpktq *q = (struct cfpktq *) cfglu_alloc(sizeof(struct cfpktq)); - cfglu_init_lock(q->qlock); + spin_lock_init(&q->qlock); q->head = NULL; q->count = 0; return q; @@ -459,7 +458,7 @@ struct cfpktq *cfpktq_create() void cfpkt_queue(struct cfpktq *pktq, struct cfpkt *pkt, unsigned short prio) { CHECK_MAGIC(pkt); - cfglu_lock(pktq->qlock); + spin_lock(&pktq->qlock); pkt->next = NULL; if (pktq->head == NULL) pktq->head = pkt; @@ -475,29 +474,29 @@ void cfpkt_queue(struct cfpktq *pktq, struct cfpkt *pkt, unsigned short prio) p->next = pkt; } pktq->count++; - cfglu_unlock(pktq->qlock); + spin_unlock(&pktq->qlock); } struct cfpkt *cfpkt_qpeek(struct cfpktq *pktq) { struct cfpkt *pkt; - cfglu_lock(pktq->qlock); + spin_lock(&pktq->qlock); if (pktq->head != NULL) { /* NOTE: Sync is only needed due to this CHECK_MAGIC... */ CHECK_MAGIC(pktq->head); } pkt = pktq->head; - cfglu_unlock(pktq->qlock); + spin_unlock(&pktq->qlock); return pkt; } struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq) { struct cfpkt *ret; - cfglu_lock(pktq->qlock); + spin_lock(&pktq->qlock); if (pktq->head == NULL) { - cfglu_unlock(pktq->qlock); + spin_unlock(&pktq->qlock); return NULL; } ret = pktq->head; @@ -505,7 +504,7 @@ struct cfpkt *cfpkt_dequeue(struct cfpktq *pktq) CHECK_MAGIC(ret); pktq->count--; caif_assert(pktq->count >= 0); - cfglu_unlock(pktq->qlock); + spin_unlock(&pktq->qlock); return ret; } @@ -513,9 +512,9 @@ int cfpkt_qcount(struct cfpktq *pktq) { int count; - cfglu_lock(pktq->qlock); + spin_lock(&pktq->qlock); count = pktq->count; - cfglu_unlock(pktq->qlock); + spin_unlock(&pktq->qlock); return count; } @@ -547,7 +546,7 @@ struct caif_packet_funcs cfpkt_get_packet_funcs() return f; } #endif -struct payload_info *cfpkt_info(struct cfpkt *pkt) +struct caif_payload_info *cfpkt_info(struct cfpkt *pkt) { return &pkt->info; } diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index aed541afea9..cd2830fec93 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c @@ -1,15 +1,17 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/caif_layer.h> -#include <net/caif/generic/cfsrvl.h> -#include <net/caif/generic/cfpkt.h> +#include <linux/stddef.h> +#include <linux/spinlock.h> +#include <linux/slab.h> +#include <net/caif/caif_layer.h> +#include <net/caif/cfsrvl.h> +#include <net/caif/cfpkt.h> -#define container_obj(layr) cfglu_container_of(layr, struct cfsrvl, layer) +#define container_obj(layr) container_of(layr, struct cfsrvl, layer) #define RFM_SEGMENTATION_BIT 0x01 #define RFM_PAYLOAD 0x00 @@ -19,12 +21,13 @@ #define RFM_SET_PIN 0x82 #define RFM_CTRL_PKT_SIZE 1 -static int cfrfml_receive(struct layer *layr, struct cfpkt *pkt); -static int cfrfml_transmit(struct layer *layr, struct cfpkt *pkt); +static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt); +static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt); +static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl); -struct layer *cfrfml_create(uint8 channel_id, struct dev_info *dev_info) +struct cflayer *cfrfml_create(u8 channel_id, struct dev_info *dev_info) { - struct cfsrvl *rfm = cfglu_alloc(sizeof(struct cfsrvl)); + struct cfsrvl *rfm = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!rfm) { pr_warning("CAIF: %s(): Out of memory\n", __func__); return NULL; @@ -32,20 +35,21 @@ struct layer *cfrfml_create(uint8 channel_id, struct dev_info *dev_info) caif_assert(offsetof(struct cfsrvl, layer) == 0); memset(rfm, 0, sizeof(struct cfsrvl)); cfsrvl_init(rfm, channel_id, dev_info); + rfm->layer.modemcmd = cfservl_modemcmd; rfm->layer.receive = cfrfml_receive; rfm->layer.transmit = cfrfml_transmit; snprintf(rfm->layer.name, CAIF_LAYER_NAME_SZ, "rfm%d", channel_id); return &rfm->layer; } -void cffrml_destroy(struct layer *layer) +static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) { - cfglu_free(layer); + return -EPROTO; } -static int cfrfml_receive(struct layer *layr, struct cfpkt *pkt) +static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt) { - uint8 tmp; + u8 tmp; bool segmented; int ret; caif_assert(layr->up != NULL); @@ -58,7 +62,7 @@ static int cfrfml_receive(struct layer *layr, struct cfpkt *pkt) if (cfpkt_extr_head(pkt, &tmp, 1) < 0) { pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); cfpkt_destroy(pkt); - return CFGLU_EPROTO; + return -EPROTO; } segmented = tmp & RFM_SEGMENTATION_BIT; caif_assert(!segmented); @@ -67,9 +71,9 @@ static int cfrfml_receive(struct layer *layr, struct cfpkt *pkt) return ret; } -static int cfrfml_transmit(struct layer *layr, struct cfpkt *pkt) +static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt) { - uint8 tmp = 0; + u8 tmp = 0; int ret; struct cfsrvl *service = container_obj(layr); @@ -82,11 +86,11 @@ static int cfrfml_transmit(struct layer *layr, struct cfpkt *pkt) if (!cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) { pr_err("CAIF: %s():Packet too large - size=%d\n", __func__, cfpkt_getlen(pkt)); - return CFGLU_EOVERFLOW; + return -EOVERFLOW; } if (cfpkt_add_head(pkt, &tmp, 1) < 0) { pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); - return CFGLU_EPKT; + return -EPROTO; } /* Add info for MUX-layer to route the packet out. */ diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c index a8426ed9d3e..06029ea2da2 100644 --- a/net/caif/cfserl.c +++ b/net/caif/cfserl.c @@ -1,33 +1,37 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/caif_layer.h> -#include <net/caif/generic/cfpkt.h> +#include <linux/stddef.h> +#include <linux/spinlock.h> +#include <linux/slab.h> +#include <net/caif/caif_layer.h> +#include <net/caif/cfpkt.h> +#include <net/caif/cfserl.h> #define container_obj(layr) ((struct cfserl *) layr) #define CFSERL_STX 0x02 #define CAIF_MINIUM_PACKET_SIZE 4 struct cfserl { - struct layer layer; + struct cflayer layer; struct cfpkt *incomplete_frm; - cfglu_lock_t sync; + /* Protects parallel processing of incoming packets */ + spinlock_t sync; bool usestx; }; #define STXLEN(layr) (layr->usestx ? 1 : 0) -static int cfserl_receive(struct layer *layr, struct cfpkt *pkt); -static int cfserl_transmit(struct layer *layr, struct cfpkt *pkt); -static void cfserl_ctrlcmd(struct layer *layr, enum caif_ctrlcmd ctrl, +static int cfserl_receive(struct cflayer *layr, struct cfpkt *pkt); +static int cfserl_transmit(struct cflayer *layr, struct cfpkt *pkt); +static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, int phyid); -struct cfserl *cfserl_create(int type, int instance, bool use_stx) +struct cflayer *cfserl_create(int type, int instance, bool use_stx) { - struct cfserl *this = cfglu_alloc(sizeof(struct cfserl)); + struct cfserl *this = kmalloc(sizeof(struct cfserl), GFP_ATOMIC); if (!this) { pr_warning("CAIF: %s(): Out of memory\n", __func__); return NULL; @@ -39,34 +43,24 @@ struct cfserl *cfserl_create(int type, int instance, bool use_stx) this->layer.ctrlcmd = cfserl_ctrlcmd; this->layer.type = type; this->usestx = use_stx; - cfglu_init_lock(this->sync); + spin_lock_init(&this->sync); snprintf(this->layer.name, CAIF_LAYER_NAME_SZ, "ser1"); - return this; + return &this->layer; } -void cfserl_set_uplayer(struct cfserl *this, struct layer *up) -{ - this->layer.up = up; -} - -void cfserl_set_dnlayer(struct cfserl *this, struct layer *dn) -{ - this->layer.dn = dn; -} - -static int cfserl_receive(struct layer *l, struct cfpkt *newpkt) +static int cfserl_receive(struct cflayer *l, struct cfpkt *newpkt) { struct cfserl *layr = container_obj(l); - uint16 pkt_len; + u16 pkt_len; struct cfpkt *pkt = NULL; struct cfpkt *tail_pkt = NULL; - uint8 tmp8; - uint16 tmp; - uint8 stx = CFSERL_STX; + u8 tmp8; + u16 tmp; + u8 stx = CFSERL_STX; int ret; - uint16 expectlen = 0; + u16 expectlen = 0; caif_assert(newpkt != NULL); - cfglu_lock(layr->sync); + spin_lock(&layr->sync); if (layr->incomplete_frm != NULL) { @@ -90,8 +84,8 @@ static int cfserl_receive(struct layer *l, struct cfpkt *newpkt) if (!cfpkt_more(pkt)) { cfpkt_destroy(pkt); layr->incomplete_frm = NULL; - cfglu_unlock(layr->sync); - return CFGLU_EPROTO; + spin_unlock(&layr->sync); + return -EPROTO; } } } @@ -108,7 +102,7 @@ static int cfserl_receive(struct layer *l, struct cfpkt *newpkt) if (layr->usestx) cfpkt_add_head(pkt, &stx, 1); layr->incomplete_frm = pkt; - cfglu_unlock(layr->sync); + spin_unlock(&layr->sync); return 0; } @@ -117,7 +111,7 @@ static int cfserl_receive(struct layer *l, struct cfpkt *newpkt) * expectlen is the length we need for a full frame. */ cfpkt_peek_head(pkt, &tmp, 2); - expectlen = cfglu_le16_to_cpu(tmp) + 2; + expectlen = le16_to_cpu(tmp) + 2; /* * Frame error handling */ @@ -128,8 +122,8 @@ static int cfserl_receive(struct layer *l, struct cfpkt *newpkt) cfpkt_destroy(pkt); layr->incomplete_frm = NULL; expectlen = 0; - cfglu_unlock(layr->sync); - return CFGLU_EPROTO; + spin_unlock(&layr->sync); + return -EPROTO; } continue; } @@ -139,7 +133,7 @@ static int cfserl_receive(struct layer *l, struct cfpkt *newpkt) if (layr->usestx) cfpkt_add_head(pkt, &stx, 1); layr->incomplete_frm = pkt; - cfglu_unlock(layr->sync); + spin_unlock(&layr->sync); return 0; } @@ -153,10 +147,10 @@ static int cfserl_receive(struct layer *l, struct cfpkt *newpkt) tail_pkt = NULL; /* Send the first part of packet upwards.*/ - cfglu_unlock(layr->sync); + spin_unlock(&layr->sync); ret = layr->layer.up->receive(layr->layer.up, pkt); - cfglu_lock(layr->sync); - if (ret == CFGLU_EFCS) { + spin_lock(&layr->sync); + if (ret == -EILSEQ) { if (layr->usestx) { if (tail_pkt != NULL) pkt = cfpkt_append(pkt, tail_pkt, 0); @@ -173,15 +167,15 @@ static int cfserl_receive(struct layer *l, struct cfpkt *newpkt) } while (pkt != NULL); - cfglu_unlock(layr->sync); + spin_unlock(&layr->sync); return 0; } -static int cfserl_transmit(struct layer *layer, struct cfpkt *newpkt) +static int cfserl_transmit(struct cflayer *layer, struct cfpkt *newpkt) { struct cfserl *layr = container_obj(layer); int ret; - uint8 tmp8 = CFSERL_STX; + u8 tmp8 = CFSERL_STX; if (layr->usestx) cfpkt_add_head(newpkt, &tmp8, 1); ret = layer->dn->transmit(layer->dn, newpkt); @@ -191,7 +185,7 @@ static int cfserl_transmit(struct layer *layer, struct cfpkt *newpkt) return ret; } -static void cfserl_ctrlcmd(struct layer *layr, enum caif_ctrlcmd ctrl, +static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, int phyid) { layr->up->ctrlcmd(layr->up, ctrl, phyid); diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c index aa62b794b1f..aff31f34528 100644 --- a/net/caif/cfsrvl.c +++ b/net/caif/cfsrvl.c @@ -1,13 +1,16 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/caif_layer.h> -#include <net/caif/generic/cfsrvl.h> -#include <net/caif/generic/cfpkt.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/slab.h> +#include <net/caif/caif_layer.h> +#include <net/caif/cfsrvl.h> +#include <net/caif/cfpkt.h> #define SRVL_CTRL_PKT_SIZE 1 #define SRVL_FLOW_OFF 0x81 @@ -15,9 +18,9 @@ #define SRVL_SET_PIN 0x82 #define SRVL_CTRL_PKT_SIZE 1 -#define container_obj(layr) cfglu_container_of(layr, struct cfsrvl, layer) +#define container_obj(layr) container_of(layr, struct cfsrvl, layer) -static void cfservl_ctrlcmd(struct layer *layr, enum caif_ctrlcmd ctrl, +static void cfservl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, int phyid) { struct cfsrvl *service = container_obj(layr); @@ -83,7 +86,7 @@ static void cfservl_ctrlcmd(struct layer *layr, enum caif_ctrlcmd ctrl, } } -static int cfservl_modemcmd(struct layer *layr, enum caif_modemcmd ctrl) +static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) { struct cfsrvl *service = container_obj(layr); caif_assert(layr != NULL); @@ -93,20 +96,20 @@ static int cfservl_modemcmd(struct layer *layr, enum caif_modemcmd ctrl) case CAIF_MODEMCMD_FLOW_ON_REQ: { struct cfpkt *pkt; - struct payload_info *info; - uint8 flow_on = SRVL_FLOW_ON; + struct caif_payload_info *info; + u8 flow_on = SRVL_FLOW_ON; pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE); if (!pkt) { pr_warning("CAIF: %s(): Out of memory\n", __func__); - return CFGLU_ENOMEM; + return -ENOMEM; } if (cfpkt_add_head(pkt, &flow_on, 1) < 0) { pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); cfpkt_destroy(pkt); - return CFGLU_EPROTO; + return -EPROTO; } info = cfpkt_info(pkt); info->channel_id = service->layer.id; @@ -117,14 +120,14 @@ static int cfservl_modemcmd(struct layer *layr, enum caif_modemcmd ctrl) case CAIF_MODEMCMD_FLOW_OFF_REQ: { struct cfpkt *pkt; - struct payload_info *info; - uint8 flow_off = SRVL_FLOW_OFF; + struct caif_payload_info *info; + u8 flow_off = SRVL_FLOW_OFF; pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE); if (cfpkt_add_head(pkt, &flow_off, 1) < 0) { pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); cfpkt_destroy(pkt); - return CFGLU_EPROTO; + return -EPROTO; } info = cfpkt_info(pkt); info->channel_id = service->layer.id; @@ -135,16 +138,16 @@ static int cfservl_modemcmd(struct layer *layr, enum caif_modemcmd ctrl) default: break; } - return CFGLU_EINVAL; + return -EINVAL; } -void cfservl_destroy(struct layer *layer) +void cfservl_destroy(struct cflayer *layer) { - cfglu_free(layer); + kfree(layer); } void cfsrvl_init(struct cfsrvl *service, - uint8 channel_id, + u8 channel_id, struct dev_info *dev_info) { caif_assert(offsetof(struct cfsrvl, layer) == 0); @@ -155,6 +158,13 @@ void cfsrvl_init(struct cfsrvl *service, service->layer.ctrlcmd = cfservl_ctrlcmd; service->layer.modemcmd = cfservl_modemcmd; service->dev_info = *dev_info; + kref_init(&service->ref); +} + +void cfsrvl_release(struct kref *kref) +{ + struct cfsrvl *service = container_of(kref, struct cfsrvl, ref); + kfree(service); } bool cfsrvl_ready(struct cfsrvl *service, int *err) @@ -162,20 +172,20 @@ bool cfsrvl_ready(struct cfsrvl *service, int *err) if (service->open && service->modem_flow_on && service->phy_flow_on) return true; if (!service->open) { - *err = CFGLU_ENOTCONN; + *err = -ENOTCONN; return false; } caif_assert(!(service->modem_flow_on && service->phy_flow_on)); - *err = CFGLU_ERETRY; + *err = -EAGAIN; return false; } -uint8 cfsrvl_getphyid(struct layer *layer) +u8 cfsrvl_getphyid(struct cflayer *layer) { struct cfsrvl *servl = container_obj(layer); return servl->dev_info.id; } -bool cfsrvl_phyid_match(struct layer *layer, int phyid) +bool cfsrvl_phyid_match(struct cflayer *layer, int phyid) { struct cfsrvl *servl = container_obj(layer); return servl->dev_info.id == phyid; diff --git a/net/caif/cfutill.c b/net/caif/cfutill.c index 351860ef33b..5fd2c9ea8b4 100644 --- a/net/caif/cfutill.c +++ b/net/caif/cfutill.c @@ -1,13 +1,16 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/caif_layer.h> -#include <net/caif/generic/cfsrvl.h> -#include <net/caif/generic/cfpkt.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/slab.h> +#include <linux/errno.h> +#include <net/caif/caif_layer.h> +#include <net/caif/cfsrvl.h> +#include <net/caif/cfpkt.h> #define container_obj(layr) ((struct cfsrvl *) layr) #define UTIL_PAYLOAD 0x00 @@ -16,12 +19,12 @@ #define UTIL_FLOW_OFF 0x81 #define UTIL_FLOW_ON 0x80 #define UTIL_CTRL_PKT_SIZE 1 -static int cfutill_receive(struct layer *layr, struct cfpkt *pkt); -static int cfutill_transmit(struct layer *layr, struct cfpkt *pkt); +static int cfutill_receive(struct cflayer *layr, struct cfpkt *pkt); +static int cfutill_transmit(struct cflayer *layr, struct cfpkt *pkt); -struct layer *cfutill_create(uint8 channel_id, struct dev_info *dev_info) +struct cflayer *cfutill_create(u8 channel_id, struct dev_info *dev_info) { - struct cfsrvl *util = cfglu_alloc(sizeof(struct cfsrvl)); + struct cfsrvl *util = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!util) { pr_warning("CAIF: %s(): Out of memory\n", __func__); return NULL; @@ -35,9 +38,9 @@ struct layer *cfutill_create(uint8 channel_id, struct dev_info *dev_info) return &util->layer; } -static int cfutill_receive(struct layer *layr, struct cfpkt *pkt) +static int cfutill_receive(struct cflayer *layr, struct cfpkt *pkt) { - uint8 cmd = -1; + u8 cmd = -1; struct cfsrvl *service = container_obj(layr); caif_assert(layr != NULL); caif_assert(layr->up != NULL); @@ -46,7 +49,7 @@ static int cfutill_receive(struct layer *layr, struct cfpkt *pkt) if (cfpkt_extr_head(pkt, &cmd, 1) < 0) { pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); cfpkt_destroy(pkt); - return CFGLU_EPROTO; + return -EPROTO; } switch (cmd) { @@ -71,14 +74,14 @@ static int cfutill_receive(struct layer *layr, struct cfpkt *pkt) cfpkt_destroy(pkt); pr_warning("CAIF: %s(): Unknown service control %d (0x%x)\n", __func__, cmd, cmd); - return CFGLU_EPROTO; + return -EPROTO; } } -static int cfutill_transmit(struct layer *layr, struct cfpkt *pkt) +static int cfutill_transmit(struct cflayer *layr, struct cfpkt *pkt) { - uint8 zero = 0; - struct payload_info *info; + u8 zero = 0; + struct caif_payload_info *info; int ret; struct cfsrvl *service = container_obj(layr); caif_assert(layr != NULL); @@ -90,7 +93,7 @@ static int cfutill_transmit(struct layer *layr, struct cfpkt *pkt) if (cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) { pr_err("CAIF: %s(): packet too large size=%d\n", __func__, cfpkt_getlen(pkt)); - return CFGLU_EOVERFLOW; + return -EOVERFLOW; } cfpkt_add_head(pkt, &zero, 1); @@ -105,7 +108,7 @@ static int cfutill_transmit(struct layer *layr, struct cfpkt *pkt) info->dev_info = &service->dev_info; ret = layr->dn->transmit(layr->dn, pkt); if (ret < 0) { - uint32 tmp32; + u32 tmp32; cfpkt_extr_head(pkt, &tmp32, 4); } return ret; diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c index 283012895b6..0fd827f4949 100644 --- a/net/caif/cfveil.c +++ b/net/caif/cfveil.c @@ -1,13 +1,14 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/caif_layer.h> -#include <net/caif/generic/cfsrvl.h> -#include <net/caif/generic/cfpkt.h> +#include <linux/stddef.h> +#include <linux/slab.h> +#include <net/caif/caif_layer.h> +#include <net/caif/cfsrvl.h> +#include <net/caif/cfpkt.h> #define VEI_PAYLOAD 0x00 #define VEI_CMD_BIT 0x80 @@ -15,14 +16,14 @@ #define VEI_FLOW_ON 0x80 #define VEI_SET_PIN 0x82 #define VEI_CTRL_PKT_SIZE 1 -#define container_obj(layr) cfglu_container_of(layr, struct cfsrvl, layer) +#define container_obj(layr) container_of(layr, struct cfsrvl, layer) -static int cfvei_receive(struct layer *layr, struct cfpkt *pkt); -static int cfvei_transmit(struct layer *layr, struct cfpkt *pkt); +static int cfvei_receive(struct cflayer *layr, struct cfpkt *pkt); +static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt); -struct layer *cfvei_create(uint8 channel_id, struct dev_info *dev_info) +struct cflayer *cfvei_create(u8 channel_id, struct dev_info *dev_info) { - struct cfsrvl *vei = cfglu_alloc(sizeof(struct cfsrvl)); + struct cfsrvl *vei = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!vei) { pr_warning("CAIF: %s(): Out of memory\n", __func__); return NULL; @@ -36,9 +37,9 @@ struct layer *cfvei_create(uint8 channel_id, struct dev_info *dev_info) return &vei->layer; } -static int cfvei_receive(struct layer *layr, struct cfpkt *pkt) +static int cfvei_receive(struct cflayer *layr, struct cfpkt *pkt) { - uint8 cmd; + u8 cmd; int ret; caif_assert(layr->up != NULL); caif_assert(layr->receive != NULL); @@ -48,7 +49,7 @@ static int cfvei_receive(struct layer *layr, struct cfpkt *pkt) if (cfpkt_extr_head(pkt, &cmd, 1) < 0) { pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); cfpkt_destroy(pkt); - return CFGLU_EPROTO; + return -EPROTO; } switch (cmd) { case VEI_PAYLOAD: @@ -57,26 +58,26 @@ static int cfvei_receive(struct layer *layr, struct cfpkt *pkt) case VEI_FLOW_OFF: layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_OFF_IND, 0); cfpkt_destroy(pkt); - return CFGLU_EOK; + return 0; case VEI_FLOW_ON: layr->ctrlcmd(layr, CAIF_CTRLCMD_FLOW_ON_IND, 0); cfpkt_destroy(pkt); - return CFGLU_EOK; + return 0; case VEI_SET_PIN: /* SET RS232 PIN */ cfpkt_destroy(pkt); - return CFGLU_EOK; + return 0; default: /* SET RS232 PIN */ pr_warning("CAIF: %s():Unknown VEI control packet %d (0x%x)!\n", __func__, cmd, cmd); cfpkt_destroy(pkt); - return CFGLU_EPROTO; + return -EPROTO; } } -static int cfvei_transmit(struct layer *layr, struct cfpkt *pkt) +static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt) { - uint8 tmp = 0; - struct payload_info *info; + u8 tmp = 0; + struct caif_payload_info *info; int ret; struct cfsrvl *service = container_obj(layr); if (!cfsrvl_ready(service, &ret)) @@ -86,12 +87,12 @@ static int cfvei_transmit(struct layer *layr, struct cfpkt *pkt) if (!cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) { pr_warning("CAIF: %s(): Packet too large - size=%d\n", __func__, cfpkt_getlen(pkt)); - return CFGLU_EOVERFLOW; + return -EOVERFLOW; } if (cfpkt_add_head(pkt, &tmp, 1) < 0) { pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); - return CFGLU_EPKT; + return -EPROTO; } /* Add info-> for MUX-layer to route the packet out. */ diff --git a/net/caif/cfvidl.c b/net/caif/cfvidl.c index bad3cd15b51..89ad4ea239f 100644 --- a/net/caif/cfvidl.c +++ b/net/caif/cfvidl.c @@ -1,22 +1,25 @@ /* - * Copyright (C) ST-Ericsson AB 2009 + * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ -#include <net/caif/generic/caif_layer.h> -#include <net/caif/generic/cfglue.h> -#include <net/caif/generic/cfsrvl.h> -#include <net/caif/generic/cfpkt.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/slab.h> +#include <linux/errno.h> +#include <net/caif/caif_layer.h> +#include <net/caif/cfsrvl.h> +#include <net/caif/cfpkt.h> #define container_obj(layr) ((struct cfsrvl *) layr) -static int cfvidl_receive(struct layer *layr, struct cfpkt *pkt); -static int cfvidl_transmit(struct layer *layr, struct cfpkt *pkt); +static int cfvidl_receive(struct cflayer *layr, struct cfpkt *pkt); +static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt); -struct layer *cfvidl_create(uint8 channel_id, struct dev_info *dev_info) +struct cflayer *cfvidl_create(u8 channel_id, struct dev_info *dev_info) { - struct cfsrvl *vid = cfglu_alloc(sizeof(struct cfsrvl)); + struct cfsrvl *vid = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!vid) { pr_warning("CAIF: %s(): Out of memory\n", __func__); return NULL; @@ -31,22 +34,22 @@ struct layer *cfvidl_create(uint8 channel_id, struct dev_info *dev_info) return &vid->layer; } -static int cfvidl_receive(struct layer *layr, struct cfpkt *pkt) +static int cfvidl_receive(struct cflayer *layr, struct cfpkt *pkt) { - uint32 videoheader; + u32 videoheader; if (cfpkt_extr_head(pkt, &videoheader, 4) < 0) { pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); cfpkt_destroy(pkt); - return CFGLU_EPROTO; + return -EPROTO; } return layr->up->receive(layr->up, pkt); } -static int cfvidl_transmit(struct layer *layr, struct cfpkt *pkt) +static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt) { struct cfsrvl *service = container_obj(layr); - struct payload_info *info; - uint32 videoheader = 0; + struct caif_payload_info *info; + u32 videoheader = 0; int ret; if (!cfsrvl_ready(service, &ret)) return ret; |