diff options
Diffstat (limited to 'net/caif/cfctrl.c')
-rw-r--r-- | net/caif/cfctrl.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index 0c00a6015dda..e22671bed669 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c | |||
@@ -178,20 +178,23 @@ static void init_info(struct caif_payload_info *info, struct cfctrl *cfctrl) | |||
178 | void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid) | 178 | void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid) |
179 | { | 179 | { |
180 | struct cfctrl *cfctrl = container_obj(layer); | 180 | struct cfctrl *cfctrl = container_obj(layer); |
181 | int ret; | ||
182 | struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); | 181 | struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); |
182 | struct cflayer *dn = cfctrl->serv.layer.dn; | ||
183 | if (!pkt) { | 183 | if (!pkt) { |
184 | pr_warn("Out of memory\n"); | 184 | pr_warn("Out of memory\n"); |
185 | return; | 185 | return; |
186 | } | 186 | } |
187 | if (!dn) { | ||
188 | pr_debug("not able to send enum request\n"); | ||
189 | return; | ||
190 | } | ||
187 | caif_assert(offsetof(struct cfctrl, serv.layer) == 0); | 191 | caif_assert(offsetof(struct cfctrl, serv.layer) == 0); |
188 | init_info(cfpkt_info(pkt), cfctrl); | 192 | init_info(cfpkt_info(pkt), cfctrl); |
189 | cfpkt_info(pkt)->dev_info->id = physlinkid; | 193 | cfpkt_info(pkt)->dev_info->id = physlinkid; |
190 | cfctrl->serv.dev_info.id = physlinkid; | 194 | cfctrl->serv.dev_info.id = physlinkid; |
191 | cfpkt_addbdy(pkt, CFCTRL_CMD_ENUM); | 195 | cfpkt_addbdy(pkt, CFCTRL_CMD_ENUM); |
192 | cfpkt_addbdy(pkt, physlinkid); | 196 | cfpkt_addbdy(pkt, physlinkid); |
193 | ret = | 197 | dn->transmit(dn, pkt); |
194 | cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); | ||
195 | } | 198 | } |
196 | 199 | ||
197 | int cfctrl_linkup_request(struct cflayer *layer, | 200 | int cfctrl_linkup_request(struct cflayer *layer, |
@@ -206,6 +209,12 @@ int cfctrl_linkup_request(struct cflayer *layer, | |||
206 | int ret; | 209 | int ret; |
207 | char utility_name[16]; | 210 | char utility_name[16]; |
208 | struct cfpkt *pkt; | 211 | struct cfpkt *pkt; |
212 | struct cflayer *dn = cfctrl->serv.layer.dn; | ||
213 | |||
214 | if (!dn) { | ||
215 | pr_debug("not able to send linkup request\n"); | ||
216 | return -ENODEV; | ||
217 | } | ||
209 | 218 | ||
210 | if (cfctrl_cancel_req(layer, user_layer) > 0) { | 219 | if (cfctrl_cancel_req(layer, user_layer) > 0) { |
211 | /* Slight Paranoia, check if already connecting */ | 220 | /* Slight Paranoia, check if already connecting */ |
@@ -282,7 +291,7 @@ int cfctrl_linkup_request(struct cflayer *layer, | |||
282 | */ | 291 | */ |
283 | cfpkt_info(pkt)->dev_info->id = param->phyid; | 292 | cfpkt_info(pkt)->dev_info->id = param->phyid; |
284 | ret = | 293 | ret = |
285 | cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); | 294 | dn->transmit(dn, pkt); |
286 | if (ret < 0) { | 295 | if (ret < 0) { |
287 | int count; | 296 | int count; |
288 | 297 | ||
@@ -301,15 +310,23 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, | |||
301 | int ret; | 310 | int ret; |
302 | struct cfctrl *cfctrl = container_obj(layer); | 311 | struct cfctrl *cfctrl = container_obj(layer); |
303 | struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); | 312 | struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); |
313 | struct cflayer *dn = cfctrl->serv.layer.dn; | ||
314 | |||
304 | if (!pkt) { | 315 | if (!pkt) { |
305 | pr_warn("Out of memory\n"); | 316 | pr_warn("Out of memory\n"); |
306 | return -ENOMEM; | 317 | return -ENOMEM; |
307 | } | 318 | } |
319 | |||
320 | if (!dn) { | ||
321 | pr_debug("not able to send link-down request\n"); | ||
322 | return -ENODEV; | ||
323 | } | ||
324 | |||
308 | cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY); | 325 | cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY); |
309 | cfpkt_addbdy(pkt, channelid); | 326 | cfpkt_addbdy(pkt, channelid); |
310 | init_info(cfpkt_info(pkt), cfctrl); | 327 | init_info(cfpkt_info(pkt), cfctrl); |
311 | ret = | 328 | ret = |
312 | cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); | 329 | dn->transmit(dn, pkt); |
313 | #ifndef CAIF_NO_LOOP | 330 | #ifndef CAIF_NO_LOOP |
314 | cfctrl->loop_linkused[channelid] = 0; | 331 | cfctrl->loop_linkused[channelid] = 0; |
315 | #endif | 332 | #endif |
@@ -351,7 +368,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) | |||
351 | cfpkt_extr_head(pkt, &cmdrsp, 1); | 368 | cfpkt_extr_head(pkt, &cmdrsp, 1); |
352 | cmd = cmdrsp & CFCTRL_CMD_MASK; | 369 | cmd = cmdrsp & CFCTRL_CMD_MASK; |
353 | if (cmd != CFCTRL_CMD_LINK_ERR | 370 | if (cmd != CFCTRL_CMD_LINK_ERR |
354 | && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp)) { | 371 | && CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp) |
372 | && CFCTRL_ERR_BIT != (CFCTRL_ERR_BIT & cmdrsp)) { | ||
355 | if (handle_loop(cfctrl, cmd, pkt) != 0) | 373 | if (handle_loop(cfctrl, cmd, pkt) != 0) |
356 | cmdrsp |= CFCTRL_ERR_BIT; | 374 | cmdrsp |= CFCTRL_ERR_BIT; |
357 | } | 375 | } |
@@ -477,7 +495,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) | |||
477 | cfpkt_extr_head(pkt, ¶m, len); | 495 | cfpkt_extr_head(pkt, ¶m, len); |
478 | break; | 496 | break; |
479 | default: | 497 | default: |
480 | pr_warn("Request setup - invalid link type (%d)\n", | 498 | pr_warn("Request setup, invalid type (%d)\n", |
481 | serv); | 499 | serv); |
482 | goto error; | 500 | goto error; |
483 | } | 501 | } |
@@ -489,7 +507,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) | |||
489 | 507 | ||
490 | if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) || | 508 | if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) || |
491 | cfpkt_erroneous(pkt)) { | 509 | cfpkt_erroneous(pkt)) { |
492 | pr_err("Invalid O/E bit or parse error on CAIF control channel\n"); | 510 | pr_err("Invalid O/E bit or parse error " |
511 | "on CAIF control channel\n"); | ||
493 | cfctrl->res.reject_rsp(cfctrl->serv.layer.up, | 512 | cfctrl->res.reject_rsp(cfctrl->serv.layer.up, |
494 | 0, | 513 | 0, |
495 | req ? req->client_layer | 514 | req ? req->client_layer |
@@ -550,9 +569,8 @@ static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, | |||
550 | case _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND: | 569 | case _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND: |
551 | case CAIF_CTRLCMD_FLOW_OFF_IND: | 570 | case CAIF_CTRLCMD_FLOW_OFF_IND: |
552 | spin_lock_bh(&this->info_list_lock); | 571 | spin_lock_bh(&this->info_list_lock); |
553 | if (!list_empty(&this->list)) { | 572 | if (!list_empty(&this->list)) |
554 | pr_debug("Received flow off in control layer\n"); | 573 | pr_debug("Received flow off in control layer\n"); |
555 | } | ||
556 | spin_unlock_bh(&this->info_list_lock); | 574 | spin_unlock_bh(&this->info_list_lock); |
557 | break; | 575 | break; |
558 | case _CAIF_CTRLCMD_PHYIF_DOWN_IND: { | 576 | case _CAIF_CTRLCMD_PHYIF_DOWN_IND: { |
@@ -587,16 +605,16 @@ static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt) | |||
587 | case CFCTRL_CMD_LINK_SETUP: | 605 | case CFCTRL_CMD_LINK_SETUP: |
588 | spin_lock_bh(&ctrl->loop_linkid_lock); | 606 | spin_lock_bh(&ctrl->loop_linkid_lock); |
589 | if (!dec) { | 607 | if (!dec) { |
590 | for (linkid = last_linkid + 1; linkid < 255; linkid++) | 608 | for (linkid = last_linkid + 1; linkid < 254; linkid++) |
591 | if (!ctrl->loop_linkused[linkid]) | 609 | if (!ctrl->loop_linkused[linkid]) |
592 | goto found; | 610 | goto found; |
593 | } | 611 | } |
594 | dec = 1; | 612 | dec = 1; |
595 | for (linkid = last_linkid - 1; linkid > 0; linkid--) | 613 | for (linkid = last_linkid - 1; linkid > 1; linkid--) |
596 | if (!ctrl->loop_linkused[linkid]) | 614 | if (!ctrl->loop_linkused[linkid]) |
597 | goto found; | 615 | goto found; |
598 | spin_unlock_bh(&ctrl->loop_linkid_lock); | 616 | spin_unlock_bh(&ctrl->loop_linkid_lock); |
599 | 617 | return -1; | |
600 | found: | 618 | found: |
601 | if (linkid < 10) | 619 | if (linkid < 10) |
602 | dec = 0; | 620 | dec = 0; |