From bedf94444bf608c2245c2d3a95fa0a3145731dad Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 31 Mar 2009 10:22:32 -0700 Subject: [PATCH] --- yaml --- r: 142943 b: refs/heads/master c: edb5abb1e2a84fd8802a3577d95eac84fe1405ab h: refs/heads/master i: 142941: 437c112db8853fcbde363c67ec18f299ef8bd1af 142939: e17abdcea5cc7685be015b1f3ebed09e7dfa95c1 142935: 83b145780edaccaa02222134dc746894f72e7612 142927: 4b5f7b01d1c97d82f01eab496c340899ea888675 142911: d13741f542fc0f42140e14238dd7e8767523adc6 v: v3 --- [refs] | 2 +- trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c | 10 +- trunk/drivers/infiniband/hw/cxgb3/cxio_hal.h | 6 - trunk/drivers/infiniband/hw/cxgb3/iwch.c | 11 +- trunk/drivers/infiniband/hw/cxgb3/iwch.h | 5 - trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c | 116 ++++++------------ trunk/drivers/infiniband/hw/cxgb3/iwch_cm.h | 3 +- trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c | 4 +- .../drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 25 ++-- 9 files changed, 62 insertions(+), 120 deletions(-) diff --git a/[refs] b/[refs] index 9e4764b3e66a..93903d23a88d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 874d8df5ed6e36fed07b524c266f6a96dd6d10d9 +refs/heads/master: edb5abb1e2a84fd8802a3577d95eac84fe1405ab diff --git a/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c b/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c index 8d71086f5a1c..a4a82bff7100 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c @@ -152,7 +152,7 @@ static int cxio_hal_clear_qp_ctx(struct cxio_rdev *rdev_p, u32 qpid) sge_cmd = qpid << 8 | 3; wqe->sge_cmd = cpu_to_be64(sge_cmd); skb->priority = CPL_PRIORITY_CONTROL; - return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb); + return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb)); } int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq) @@ -571,7 +571,7 @@ static int cxio_hal_init_ctrl_qp(struct cxio_rdev *rdev_p) (unsigned long long) rdev_p->ctrl_qp.dma_addr, rdev_p->ctrl_qp.workq, 1 << T3_CTRL_QP_SIZE_LOG2); skb->priority = CPL_PRIORITY_CONTROL; - return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb); + return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb)); err: kfree_skb(skb); return err; @@ -701,7 +701,7 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry, u32 stag_idx; u32 wptr; - if (cxio_fatal_error(rdev_p)) + if (rdev_p->flags) return -EIO; stag_state = stag_state > 0; @@ -858,7 +858,7 @@ int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr) wqe->qp_dma_size = cpu_to_be32(attr->qp_dma_size); wqe->irs = cpu_to_be32(attr->irs); skb->priority = 0; /* 0=>ToeQ; 1=>CtrlQ */ - return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb); + return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb)); } void cxio_register_ev_cb(cxio_hal_ev_callback_func_t ev_cb) @@ -1041,9 +1041,9 @@ void cxio_rdev_close(struct cxio_rdev *rdev_p) cxio_hal_pblpool_destroy(rdev_p); cxio_hal_rqtpool_destroy(rdev_p); list_del(&rdev_p->entry); + rdev_p->t3cdev_p->ulp = NULL; cxio_hal_destroy_ctrl_qp(rdev_p); cxio_hal_destroy_resource(rdev_p->rscp); - rdev_p->t3cdev_p->ulp = NULL; } } diff --git a/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.h b/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.h index bfd03bf8be54..094a66d1480c 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.h @@ -115,11 +115,6 @@ struct cxio_rdev { #define CXIO_ERROR_FATAL 1 }; -static inline int cxio_fatal_error(struct cxio_rdev *rdev_p) -{ - return rdev_p->flags & CXIO_ERROR_FATAL; -} - static inline int cxio_num_stags(struct cxio_rdev *rdev_p) { return min((int)T3_MAX_NUM_STAG, (int)((rdev_p->rnic_info.tpt_top - rdev_p->rnic_info.tpt_base) >> 5)); @@ -193,7 +188,6 @@ void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count); void cxio_flush_hw_cq(struct t3_cq *cq); int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe, u8 *cqe_flushed, u64 *cookie, u32 *credit); -int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb); #define MOD "iw_cxgb3: " #define PDBG(fmt, args...) pr_debug(MOD fmt, ## args) diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch.c b/trunk/drivers/infiniband/hw/cxgb3/iwch.c index 26fc0a4eaa74..37a4fc264a07 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch.c @@ -165,19 +165,12 @@ static void close_rnic_dev(struct t3cdev *tdev) static void iwch_err_handler(struct t3cdev *tdev, u32 status, u32 error) { struct cxio_rdev *rdev = tdev->ulp; - struct iwch_dev *rnicp = rdev_to_iwch_dev(rdev); - struct ib_event event; - if (status == OFFLOAD_STATUS_DOWN) { + if (status == OFFLOAD_STATUS_DOWN) rdev->flags = CXIO_ERROR_FATAL; - event.device = &rnicp->ibdev; - event.event = IB_EVENT_DEVICE_FATAL; - event.element.port_num = 0; - ib_dispatch_event(&event); - } - return; + } static int __init iwch_init_module(void) diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch.h b/trunk/drivers/infiniband/hw/cxgb3/iwch.h index 84735506333f..3773453b2cf0 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch.h +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch.h @@ -117,11 +117,6 @@ static inline struct iwch_dev *to_iwch_dev(struct ib_device *ibdev) return container_of(ibdev, struct iwch_dev, ibdev); } -static inline struct iwch_dev *rdev_to_iwch_dev(struct cxio_rdev *rdev) -{ - return container_of(rdev, struct iwch_dev, rdev); -} - static inline int t3b_device(const struct iwch_dev *rhp) { return rhp->rdev.t3cdev_p->type == T3B; diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c index fef3f1ae7225..8699947aaf6c 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -139,38 +139,6 @@ static void stop_ep_timer(struct iwch_ep *ep) put_ep(&ep->com); } -int iwch_l2t_send(struct t3cdev *tdev, struct sk_buff *skb, struct l2t_entry *l2e) -{ - int error = 0; - struct cxio_rdev *rdev; - - rdev = (struct cxio_rdev *)tdev->ulp; - if (cxio_fatal_error(rdev)) { - kfree_skb(skb); - return -EIO; - } - error = l2t_send(tdev, skb, l2e); - if (error) - kfree_skb(skb); - return error; -} - -int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb) -{ - int error = 0; - struct cxio_rdev *rdev; - - rdev = (struct cxio_rdev *)tdev->ulp; - if (cxio_fatal_error(rdev)) { - kfree_skb(skb); - return -EIO; - } - error = cxgb3_ofld_send(tdev, skb); - if (error) - kfree_skb(skb); - return error; -} - static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb) { struct cpl_tid_release *req; @@ -182,7 +150,7 @@ static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb) req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid)); skb->priority = CPL_PRIORITY_SETUP; - iwch_cxgb3_ofld_send(tdev, skb); + cxgb3_ofld_send(tdev, skb); return; } @@ -204,7 +172,8 @@ int iwch_quiesce_tid(struct iwch_ep *ep) req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE); skb->priority = CPL_PRIORITY_DATA; - return iwch_cxgb3_ofld_send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); + return 0; } int iwch_resume_tid(struct iwch_ep *ep) @@ -225,7 +194,8 @@ int iwch_resume_tid(struct iwch_ep *ep) req->val = 0; skb->priority = CPL_PRIORITY_DATA; - return iwch_cxgb3_ofld_send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); + return 0; } static void set_emss(struct iwch_ep *ep, u16 opt) @@ -282,22 +252,18 @@ static void *alloc_ep(int size, gfp_t gfp) void __free_ep(struct kref *kref) { - struct iwch_ep *ep; - ep = container_of(container_of(kref, struct iwch_ep_common, kref), - struct iwch_ep, com); - PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]); - if (ep->com.flags & RELEASE_RESOURCES) { - cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid); - dst_release(ep->dst); - l2t_release(L2DATA(ep->com.tdev), ep->l2t); - } - kfree(ep); + struct iwch_ep_common *epc; + epc = container_of(kref, struct iwch_ep_common, kref); + PDBG("%s ep %p state %s\n", __func__, epc, states[state_read(epc)]); + kfree(epc); } static void release_ep_resources(struct iwch_ep *ep) { PDBG("%s ep %p tid %d\n", __func__, ep, ep->hwtid); - ep->com.flags |= RELEASE_RESOURCES; + cxgb3_remove_tid(ep->com.tdev, (void *)ep, ep->hwtid); + dst_release(ep->dst); + l2t_release(L2DATA(ep->com.tdev), ep->l2t); put_ep(&ep->com); } @@ -416,7 +382,7 @@ static void abort_arp_failure(struct t3cdev *dev, struct sk_buff *skb) PDBG("%s t3cdev %p\n", __func__, dev); req->cmd = CPL_ABORT_NO_RST; - iwch_cxgb3_ofld_send(dev, skb); + cxgb3_ofld_send(dev, skb); } static int send_halfclose(struct iwch_ep *ep, gfp_t gfp) @@ -436,7 +402,8 @@ static int send_halfclose(struct iwch_ep *ep, gfp_t gfp) req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON)); req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, ep->hwtid)); - return iwch_l2t_send(ep->com.tdev, skb, ep->l2t); + l2t_send(ep->com.tdev, skb, ep->l2t); + return 0; } static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp) @@ -457,7 +424,8 @@ static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp) req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid)); req->cmd = CPL_ABORT_SEND_RST; - return iwch_l2t_send(ep->com.tdev, skb, ep->l2t); + l2t_send(ep->com.tdev, skb, ep->l2t); + return 0; } static int send_connect(struct iwch_ep *ep) @@ -501,7 +469,8 @@ static int send_connect(struct iwch_ep *ep) req->opt0l = htonl(opt0l); req->params = 0; req->opt2 = htonl(opt2); - return iwch_l2t_send(ep->com.tdev, skb, ep->l2t); + l2t_send(ep->com.tdev, skb, ep->l2t); + return 0; } static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb) @@ -558,7 +527,7 @@ static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb) req->sndseq = htonl(ep->snd_seq); BUG_ON(ep->mpa_skb); ep->mpa_skb = skb; - iwch_l2t_send(ep->com.tdev, skb, ep->l2t); + l2t_send(ep->com.tdev, skb, ep->l2t); start_ep_timer(ep); state_set(&ep->com, MPA_REQ_SENT); return; @@ -609,7 +578,8 @@ static int send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen) req->sndseq = htonl(ep->snd_seq); BUG_ON(ep->mpa_skb); ep->mpa_skb = skb; - return iwch_l2t_send(ep->com.tdev, skb, ep->l2t); + l2t_send(ep->com.tdev, skb, ep->l2t); + return 0; } static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen) @@ -660,7 +630,8 @@ static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen) req->sndseq = htonl(ep->snd_seq); ep->mpa_skb = skb; state_set(&ep->com, MPA_REP_SENT); - return iwch_l2t_send(ep->com.tdev, skb, ep->l2t); + l2t_send(ep->com.tdev, skb, ep->l2t); + return 0; } static int act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) @@ -824,7 +795,7 @@ static int update_rx_credits(struct iwch_ep *ep, u32 credits) OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid)); req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1)); skb->priority = CPL_PRIORITY_ACK; - iwch_cxgb3_ofld_send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return credits; } @@ -1156,8 +1127,8 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) * We get 2 abort replies from the HW. The first one must * be ignored except for scribbling that we need one more. */ - if (!(ep->com.flags & ABORT_REQ_IN_PROGRESS)) { - ep->com.flags |= ABORT_REQ_IN_PROGRESS; + if (!(ep->flags & ABORT_REQ_IN_PROGRESS)) { + ep->flags |= ABORT_REQ_IN_PROGRESS; return CPL_RET_BUF_DONE; } @@ -1232,7 +1203,8 @@ static int listen_start(struct iwch_listen_ep *ep) req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK)); skb->priority = 1; - return iwch_cxgb3_ofld_send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); + return 0; } static int pass_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) @@ -1265,7 +1237,8 @@ static int listen_stop(struct iwch_listen_ep *ep) req->cpu_idx = 0; OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid)); skb->priority = 1; - return iwch_cxgb3_ofld_send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); + return 0; } static int close_listsrv_rpl(struct t3cdev *tdev, struct sk_buff *skb, @@ -1313,7 +1286,7 @@ static void accept_cr(struct iwch_ep *ep, __be32 peer_ip, struct sk_buff *skb) rpl->opt2 = htonl(opt2); rpl->rsvd = rpl->opt2; /* workaround for HW bug */ skb->priority = CPL_PRIORITY_SETUP; - iwch_l2t_send(ep->com.tdev, skb, ep->l2t); + l2t_send(ep->com.tdev, skb, ep->l2t); return; } @@ -1342,7 +1315,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip, rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT); rpl->opt2 = 0; rpl->rsvd = rpl->opt2; - iwch_cxgb3_ofld_send(tdev, skb); + cxgb3_ofld_send(tdev, skb); } } @@ -1561,8 +1534,8 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) * We get 2 peer aborts from the HW. The first one must * be ignored except for scribbling that we need one more. */ - if (!(ep->com.flags & PEER_ABORT_IN_PROGRESS)) { - ep->com.flags |= PEER_ABORT_IN_PROGRESS; + if (!(ep->flags & PEER_ABORT_IN_PROGRESS)) { + ep->flags |= PEER_ABORT_IN_PROGRESS; return CPL_RET_BUF_DONE; } @@ -1640,7 +1613,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); rpl->cmd = CPL_ABORT_NO_RST; - iwch_cxgb3_ofld_send(ep->com.tdev, rpl_skb); + cxgb3_ofld_send(ep->com.tdev, rpl_skb); out: if (release) release_ep_resources(ep); @@ -2044,11 +2017,8 @@ int iwch_destroy_listen(struct iw_cm_id *cm_id) ep->com.rpl_done = 0; ep->com.rpl_err = 0; err = listen_stop(ep); - if (err) - goto done; wait_event(ep->com.waitq, ep->com.rpl_done); cxgb3_free_stid(ep->com.tdev, ep->stid); -done: err = ep->com.rpl_err; cm_id->rem_ref(cm_id); put_ep(&ep->com); @@ -2060,22 +2030,12 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp) int ret=0; unsigned long flags; int close = 0; - int fatal = 0; - struct t3cdev *tdev; - struct cxio_rdev *rdev; spin_lock_irqsave(&ep->com.lock, flags); PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, states[ep->com.state], abrupt); - tdev = (struct t3cdev *)ep->com.tdev; - rdev = (struct cxio_rdev *)tdev->ulp; - if (cxio_fatal_error(rdev)) { - fatal = 1; - close_complete_upcall(ep); - ep->com.state = DEAD; - } switch (ep->com.state) { case MPA_REQ_WAIT: case MPA_REQ_SENT: @@ -2115,11 +2075,7 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp) ret = send_abort(ep, NULL, gfp); else ret = send_halfclose(ep, gfp); - if (ret) - fatal = 1; } - if (fatal) - release_ep_resources(ep); return ret; } diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.h b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.h index 43c0aea7eadc..d7c7e09f0996 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.h +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.h @@ -147,7 +147,6 @@ enum iwch_ep_state { enum iwch_ep_flags { PEER_ABORT_IN_PROGRESS = (1 << 0), ABORT_REQ_IN_PROGRESS = (1 << 1), - RELEASE_RESOURCES = (1 << 2), }; struct iwch_ep_common { @@ -162,7 +161,6 @@ struct iwch_ep_common { wait_queue_head_t waitq; int rpl_done; int rpl_err; - u32 flags; }; struct iwch_listen_ep { @@ -190,6 +188,7 @@ struct iwch_ep { u16 plen; u32 ird; u32 ord; + u32 flags; }; static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id) diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c b/trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c index 2f546a625330..c758fbd58478 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c @@ -751,7 +751,7 @@ int iwch_post_zb_read(struct iwch_qp *qhp) wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)| V_FW_RIWR_LEN(flit_cnt)); skb->priority = CPL_PRIORITY_DATA; - return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb); + return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb); } /* @@ -783,7 +783,7 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg) V_FW_RIWR_FLAGS(T3_COMPLETION_FLAG | T3_NOTIFY_FLAG)); wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)); skb->priority = CPL_PRIORITY_DATA; - return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb); + return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb); } /* diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index 5a76a5510350..4c57f329dd50 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c @@ -70,12 +70,14 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) */ if (ppriv->pkey == pkey) { result = -ENOTUNIQ; + priv = NULL; goto err; } list_for_each_entry(priv, &ppriv->child_intfs, list) { if (priv->pkey == pkey) { result = -ENOTUNIQ; + priv = NULL; goto err; } } @@ -96,7 +98,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) result = ipoib_set_dev_features(priv, ppriv->ca); if (result) - goto device_init_failed; + goto err; priv->pkey = pkey; @@ -109,7 +111,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) ipoib_warn(ppriv, "failed to initialize subinterface: " "device %s, port %d", ppriv->ca->name, ppriv->port); - goto device_init_failed; + goto err; } result = register_netdevice(priv->dev); @@ -146,19 +148,19 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) register_failed: ipoib_dev_cleanup(priv->dev); -device_init_failed: - free_netdev(priv->dev); - err: mutex_unlock(&ppriv->vlan_mutex); rtnl_unlock(); + if (priv) + free_netdev(priv->dev); + return result; } int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) { struct ipoib_dev_priv *ppriv, *priv, *tpriv; - int ret = -ENOENT; + struct net_device *dev = NULL; if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -172,14 +174,17 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) unregister_netdevice(priv->dev); ipoib_dev_cleanup(priv->dev); list_del(&priv->list); - free_netdev(priv->dev); - - ret = 0; + dev = priv->dev; break; } } mutex_unlock(&ppriv->vlan_mutex); rtnl_unlock(); - return ret; + if (dev) { + free_netdev(dev); + return 0; + } + + return -ENODEV; }