diff options
author | Steve Wise <swise@opengridcomputing.com> | 2009-03-30 11:37:56 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2009-03-30 11:37:56 -0400 |
commit | 04b5d028f50ff05a8f9ae049ee71f8fdfcf1f5de (patch) | |
tree | a6363d175d07995e0c2b32e035fb16beeca0772a /drivers | |
parent | 5d80f8e5a9dc9c9a94d4aeaa567e219a808b8a4a (diff) |
RDMA/cxgb3: Handle EEH events
- wrap calls into cxgb3 and fail them if we're in the middle
of a PCI EEH event.
- correctly unwind and release endpoint and other resources when
we are in an EEH event.
- dispatch IB_EVENT_DEVICE_FATAL event when cxgb3 notifies iw_cxgb3 of
a fatal error.
Signed-off-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/hw/cxgb3/cxio_hal.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb3/cxio_hal.h | 6 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch.c | 11 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch.h | 5 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_cm.c | 90 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_qp.c | 4 |
6 files changed, 92 insertions, 34 deletions
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c index a4a82bff7100..8d71086f5a1c 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/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) | |||
152 | sge_cmd = qpid << 8 | 3; | 152 | sge_cmd = qpid << 8 | 3; |
153 | wqe->sge_cmd = cpu_to_be64(sge_cmd); | 153 | wqe->sge_cmd = cpu_to_be64(sge_cmd); |
154 | skb->priority = CPL_PRIORITY_CONTROL; | 154 | skb->priority = CPL_PRIORITY_CONTROL; |
155 | return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb)); | 155 | return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb); |
156 | } | 156 | } |
157 | 157 | ||
158 | int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq) | 158 | 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) | |||
571 | (unsigned long long) rdev_p->ctrl_qp.dma_addr, | 571 | (unsigned long long) rdev_p->ctrl_qp.dma_addr, |
572 | rdev_p->ctrl_qp.workq, 1 << T3_CTRL_QP_SIZE_LOG2); | 572 | rdev_p->ctrl_qp.workq, 1 << T3_CTRL_QP_SIZE_LOG2); |
573 | skb->priority = CPL_PRIORITY_CONTROL; | 573 | skb->priority = CPL_PRIORITY_CONTROL; |
574 | return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb)); | 574 | return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb); |
575 | err: | 575 | err: |
576 | kfree_skb(skb); | 576 | kfree_skb(skb); |
577 | return err; | 577 | return err; |
@@ -701,7 +701,7 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry, | |||
701 | u32 stag_idx; | 701 | u32 stag_idx; |
702 | u32 wptr; | 702 | u32 wptr; |
703 | 703 | ||
704 | if (rdev_p->flags) | 704 | if (cxio_fatal_error(rdev_p)) |
705 | return -EIO; | 705 | return -EIO; |
706 | 706 | ||
707 | stag_state = stag_state > 0; | 707 | stag_state = stag_state > 0; |
@@ -858,7 +858,7 @@ int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr) | |||
858 | wqe->qp_dma_size = cpu_to_be32(attr->qp_dma_size); | 858 | wqe->qp_dma_size = cpu_to_be32(attr->qp_dma_size); |
859 | wqe->irs = cpu_to_be32(attr->irs); | 859 | wqe->irs = cpu_to_be32(attr->irs); |
860 | skb->priority = 0; /* 0=>ToeQ; 1=>CtrlQ */ | 860 | skb->priority = 0; /* 0=>ToeQ; 1=>CtrlQ */ |
861 | return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb)); | 861 | return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb); |
862 | } | 862 | } |
863 | 863 | ||
864 | void cxio_register_ev_cb(cxio_hal_ev_callback_func_t ev_cb) | 864 | 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) | |||
1041 | cxio_hal_pblpool_destroy(rdev_p); | 1041 | cxio_hal_pblpool_destroy(rdev_p); |
1042 | cxio_hal_rqtpool_destroy(rdev_p); | 1042 | cxio_hal_rqtpool_destroy(rdev_p); |
1043 | list_del(&rdev_p->entry); | 1043 | list_del(&rdev_p->entry); |
1044 | rdev_p->t3cdev_p->ulp = NULL; | ||
1045 | cxio_hal_destroy_ctrl_qp(rdev_p); | 1044 | cxio_hal_destroy_ctrl_qp(rdev_p); |
1046 | cxio_hal_destroy_resource(rdev_p->rscp); | 1045 | cxio_hal_destroy_resource(rdev_p->rscp); |
1046 | rdev_p->t3cdev_p->ulp = NULL; | ||
1047 | } | 1047 | } |
1048 | } | 1048 | } |
1049 | 1049 | ||
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h index 094a66d1480c..bfd03bf8be54 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_hal.h +++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h | |||
@@ -115,6 +115,11 @@ struct cxio_rdev { | |||
115 | #define CXIO_ERROR_FATAL 1 | 115 | #define CXIO_ERROR_FATAL 1 |
116 | }; | 116 | }; |
117 | 117 | ||
118 | static inline int cxio_fatal_error(struct cxio_rdev *rdev_p) | ||
119 | { | ||
120 | return rdev_p->flags & CXIO_ERROR_FATAL; | ||
121 | } | ||
122 | |||
118 | static inline int cxio_num_stags(struct cxio_rdev *rdev_p) | 123 | static inline int cxio_num_stags(struct cxio_rdev *rdev_p) |
119 | { | 124 | { |
120 | return min((int)T3_MAX_NUM_STAG, (int)((rdev_p->rnic_info.tpt_top - rdev_p->rnic_info.tpt_base) >> 5)); | 125 | return min((int)T3_MAX_NUM_STAG, (int)((rdev_p->rnic_info.tpt_top - rdev_p->rnic_info.tpt_base) >> 5)); |
@@ -188,6 +193,7 @@ void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count); | |||
188 | void cxio_flush_hw_cq(struct t3_cq *cq); | 193 | void cxio_flush_hw_cq(struct t3_cq *cq); |
189 | int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe, | 194 | int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe, |
190 | u8 *cqe_flushed, u64 *cookie, u32 *credit); | 195 | u8 *cqe_flushed, u64 *cookie, u32 *credit); |
196 | int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb); | ||
191 | 197 | ||
192 | #define MOD "iw_cxgb3: " | 198 | #define MOD "iw_cxgb3: " |
193 | #define PDBG(fmt, args...) pr_debug(MOD fmt, ## args) | 199 | #define PDBG(fmt, args...) pr_debug(MOD fmt, ## args) |
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c index 37a4fc264a07..26fc0a4eaa74 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.c +++ b/drivers/infiniband/hw/cxgb3/iwch.c | |||
@@ -165,12 +165,19 @@ static void close_rnic_dev(struct t3cdev *tdev) | |||
165 | static void iwch_err_handler(struct t3cdev *tdev, u32 status, u32 error) | 165 | static void iwch_err_handler(struct t3cdev *tdev, u32 status, u32 error) |
166 | { | 166 | { |
167 | struct cxio_rdev *rdev = tdev->ulp; | 167 | struct cxio_rdev *rdev = tdev->ulp; |
168 | struct iwch_dev *rnicp = rdev_to_iwch_dev(rdev); | ||
169 | struct ib_event event; | ||
168 | 170 | ||
169 | if (status == OFFLOAD_STATUS_DOWN) | 171 | if (status == OFFLOAD_STATUS_DOWN) { |
170 | rdev->flags = CXIO_ERROR_FATAL; | 172 | rdev->flags = CXIO_ERROR_FATAL; |
171 | 173 | ||
172 | return; | 174 | event.device = &rnicp->ibdev; |
175 | event.event = IB_EVENT_DEVICE_FATAL; | ||
176 | event.element.port_num = 0; | ||
177 | ib_dispatch_event(&event); | ||
178 | } | ||
173 | 179 | ||
180 | return; | ||
174 | } | 181 | } |
175 | 182 | ||
176 | static int __init iwch_init_module(void) | 183 | static int __init iwch_init_module(void) |
diff --git a/drivers/infiniband/hw/cxgb3/iwch.h b/drivers/infiniband/hw/cxgb3/iwch.h index 3773453b2cf0..84735506333f 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.h +++ b/drivers/infiniband/hw/cxgb3/iwch.h | |||
@@ -117,6 +117,11 @@ static inline struct iwch_dev *to_iwch_dev(struct ib_device *ibdev) | |||
117 | return container_of(ibdev, struct iwch_dev, ibdev); | 117 | return container_of(ibdev, struct iwch_dev, ibdev); |
118 | } | 118 | } |
119 | 119 | ||
120 | static inline struct iwch_dev *rdev_to_iwch_dev(struct cxio_rdev *rdev) | ||
121 | { | ||
122 | return container_of(rdev, struct iwch_dev, rdev); | ||
123 | } | ||
124 | |||
120 | static inline int t3b_device(const struct iwch_dev *rhp) | 125 | static inline int t3b_device(const struct iwch_dev *rhp) |
121 | { | 126 | { |
122 | return rhp->rdev.t3cdev_p->type == T3B; | 127 | return rhp->rdev.t3cdev_p->type == T3B; |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 8699947aaf6c..59e1c5f00785 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
@@ -139,6 +139,38 @@ static void stop_ep_timer(struct iwch_ep *ep) | |||
139 | put_ep(&ep->com); | 139 | put_ep(&ep->com); |
140 | } | 140 | } |
141 | 141 | ||
142 | int iwch_l2t_send(struct t3cdev *tdev, struct sk_buff *skb, struct l2t_entry *l2e) | ||
143 | { | ||
144 | int error = 0; | ||
145 | struct cxio_rdev *rdev; | ||
146 | |||
147 | rdev = (struct cxio_rdev *)tdev->ulp; | ||
148 | if (cxio_fatal_error(rdev)) { | ||
149 | kfree_skb(skb); | ||
150 | return -EIO; | ||
151 | } | ||
152 | error = l2t_send(tdev, skb, l2e); | ||
153 | if (error) | ||
154 | kfree_skb(skb); | ||
155 | return error; | ||
156 | } | ||
157 | |||
158 | int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb) | ||
159 | { | ||
160 | int error = 0; | ||
161 | struct cxio_rdev *rdev; | ||
162 | |||
163 | rdev = (struct cxio_rdev *)tdev->ulp; | ||
164 | if (cxio_fatal_error(rdev)) { | ||
165 | kfree_skb(skb); | ||
166 | return -EIO; | ||
167 | } | ||
168 | error = cxgb3_ofld_send(tdev, skb); | ||
169 | if (error) | ||
170 | kfree_skb(skb); | ||
171 | return error; | ||
172 | } | ||
173 | |||
142 | static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb) | 174 | static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb) |
143 | { | 175 | { |
144 | struct cpl_tid_release *req; | 176 | struct cpl_tid_release *req; |
@@ -150,7 +182,7 @@ static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb) | |||
150 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | 182 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); |
151 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid)); | 183 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid)); |
152 | skb->priority = CPL_PRIORITY_SETUP; | 184 | skb->priority = CPL_PRIORITY_SETUP; |
153 | cxgb3_ofld_send(tdev, skb); | 185 | iwch_cxgb3_ofld_send(tdev, skb); |
154 | return; | 186 | return; |
155 | } | 187 | } |
156 | 188 | ||
@@ -172,8 +204,7 @@ int iwch_quiesce_tid(struct iwch_ep *ep) | |||
172 | req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE); | 204 | req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE); |
173 | 205 | ||
174 | skb->priority = CPL_PRIORITY_DATA; | 206 | skb->priority = CPL_PRIORITY_DATA; |
175 | cxgb3_ofld_send(ep->com.tdev, skb); | 207 | return iwch_cxgb3_ofld_send(ep->com.tdev, skb); |
176 | return 0; | ||
177 | } | 208 | } |
178 | 209 | ||
179 | int iwch_resume_tid(struct iwch_ep *ep) | 210 | int iwch_resume_tid(struct iwch_ep *ep) |
@@ -194,8 +225,7 @@ int iwch_resume_tid(struct iwch_ep *ep) | |||
194 | req->val = 0; | 225 | req->val = 0; |
195 | 226 | ||
196 | skb->priority = CPL_PRIORITY_DATA; | 227 | skb->priority = CPL_PRIORITY_DATA; |
197 | cxgb3_ofld_send(ep->com.tdev, skb); | 228 | return iwch_cxgb3_ofld_send(ep->com.tdev, skb); |
198 | return 0; | ||
199 | } | 229 | } |
200 | 230 | ||
201 | static void set_emss(struct iwch_ep *ep, u16 opt) | 231 | static void set_emss(struct iwch_ep *ep, u16 opt) |
@@ -382,7 +412,7 @@ static void abort_arp_failure(struct t3cdev *dev, struct sk_buff *skb) | |||
382 | 412 | ||
383 | PDBG("%s t3cdev %p\n", __func__, dev); | 413 | PDBG("%s t3cdev %p\n", __func__, dev); |
384 | req->cmd = CPL_ABORT_NO_RST; | 414 | req->cmd = CPL_ABORT_NO_RST; |
385 | cxgb3_ofld_send(dev, skb); | 415 | iwch_cxgb3_ofld_send(dev, skb); |
386 | } | 416 | } |
387 | 417 | ||
388 | static int send_halfclose(struct iwch_ep *ep, gfp_t gfp) | 418 | static int send_halfclose(struct iwch_ep *ep, gfp_t gfp) |
@@ -402,8 +432,7 @@ static int send_halfclose(struct iwch_ep *ep, gfp_t gfp) | |||
402 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON)); | 432 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON)); |
403 | req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); | 433 | req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); |
404 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, ep->hwtid)); | 434 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, ep->hwtid)); |
405 | l2t_send(ep->com.tdev, skb, ep->l2t); | 435 | return iwch_l2t_send(ep->com.tdev, skb, ep->l2t); |
406 | return 0; | ||
407 | } | 436 | } |
408 | 437 | ||
409 | static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp) | 438 | static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp) |
@@ -424,8 +453,7 @@ static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp) | |||
424 | req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); | 453 | req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); |
425 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid)); | 454 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid)); |
426 | req->cmd = CPL_ABORT_SEND_RST; | 455 | req->cmd = CPL_ABORT_SEND_RST; |
427 | l2t_send(ep->com.tdev, skb, ep->l2t); | 456 | return iwch_l2t_send(ep->com.tdev, skb, ep->l2t); |
428 | return 0; | ||
429 | } | 457 | } |
430 | 458 | ||
431 | static int send_connect(struct iwch_ep *ep) | 459 | static int send_connect(struct iwch_ep *ep) |
@@ -469,8 +497,7 @@ static int send_connect(struct iwch_ep *ep) | |||
469 | req->opt0l = htonl(opt0l); | 497 | req->opt0l = htonl(opt0l); |
470 | req->params = 0; | 498 | req->params = 0; |
471 | req->opt2 = htonl(opt2); | 499 | req->opt2 = htonl(opt2); |
472 | l2t_send(ep->com.tdev, skb, ep->l2t); | 500 | return iwch_l2t_send(ep->com.tdev, skb, ep->l2t); |
473 | return 0; | ||
474 | } | 501 | } |
475 | 502 | ||
476 | static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb) | 503 | static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb) |
@@ -527,7 +554,7 @@ static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb) | |||
527 | req->sndseq = htonl(ep->snd_seq); | 554 | req->sndseq = htonl(ep->snd_seq); |
528 | BUG_ON(ep->mpa_skb); | 555 | BUG_ON(ep->mpa_skb); |
529 | ep->mpa_skb = skb; | 556 | ep->mpa_skb = skb; |
530 | l2t_send(ep->com.tdev, skb, ep->l2t); | 557 | iwch_l2t_send(ep->com.tdev, skb, ep->l2t); |
531 | start_ep_timer(ep); | 558 | start_ep_timer(ep); |
532 | state_set(&ep->com, MPA_REQ_SENT); | 559 | state_set(&ep->com, MPA_REQ_SENT); |
533 | return; | 560 | return; |
@@ -578,8 +605,7 @@ static int send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen) | |||
578 | req->sndseq = htonl(ep->snd_seq); | 605 | req->sndseq = htonl(ep->snd_seq); |
579 | BUG_ON(ep->mpa_skb); | 606 | BUG_ON(ep->mpa_skb); |
580 | ep->mpa_skb = skb; | 607 | ep->mpa_skb = skb; |
581 | l2t_send(ep->com.tdev, skb, ep->l2t); | 608 | return iwch_l2t_send(ep->com.tdev, skb, ep->l2t); |
582 | return 0; | ||
583 | } | 609 | } |
584 | 610 | ||
585 | static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen) | 611 | static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen) |
@@ -630,8 +656,7 @@ static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen) | |||
630 | req->sndseq = htonl(ep->snd_seq); | 656 | req->sndseq = htonl(ep->snd_seq); |
631 | ep->mpa_skb = skb; | 657 | ep->mpa_skb = skb; |
632 | state_set(&ep->com, MPA_REP_SENT); | 658 | state_set(&ep->com, MPA_REP_SENT); |
633 | l2t_send(ep->com.tdev, skb, ep->l2t); | 659 | return iwch_l2t_send(ep->com.tdev, skb, ep->l2t); |
634 | return 0; | ||
635 | } | 660 | } |
636 | 661 | ||
637 | static int act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | 662 | static int act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) |
@@ -795,7 +820,7 @@ static int update_rx_credits(struct iwch_ep *ep, u32 credits) | |||
795 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid)); | 820 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid)); |
796 | req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1)); | 821 | req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1)); |
797 | skb->priority = CPL_PRIORITY_ACK; | 822 | skb->priority = CPL_PRIORITY_ACK; |
798 | cxgb3_ofld_send(ep->com.tdev, skb); | 823 | iwch_cxgb3_ofld_send(ep->com.tdev, skb); |
799 | return credits; | 824 | return credits; |
800 | } | 825 | } |
801 | 826 | ||
@@ -1203,8 +1228,7 @@ static int listen_start(struct iwch_listen_ep *ep) | |||
1203 | req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK)); | 1228 | req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK)); |
1204 | 1229 | ||
1205 | skb->priority = 1; | 1230 | skb->priority = 1; |
1206 | cxgb3_ofld_send(ep->com.tdev, skb); | 1231 | return iwch_cxgb3_ofld_send(ep->com.tdev, skb); |
1207 | return 0; | ||
1208 | } | 1232 | } |
1209 | 1233 | ||
1210 | static int pass_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | 1234 | static int pass_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) |
@@ -1237,8 +1261,7 @@ static int listen_stop(struct iwch_listen_ep *ep) | |||
1237 | req->cpu_idx = 0; | 1261 | req->cpu_idx = 0; |
1238 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid)); | 1262 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid)); |
1239 | skb->priority = 1; | 1263 | skb->priority = 1; |
1240 | cxgb3_ofld_send(ep->com.tdev, skb); | 1264 | return iwch_cxgb3_ofld_send(ep->com.tdev, skb); |
1241 | return 0; | ||
1242 | } | 1265 | } |
1243 | 1266 | ||
1244 | static int close_listsrv_rpl(struct t3cdev *tdev, struct sk_buff *skb, | 1267 | static int close_listsrv_rpl(struct t3cdev *tdev, struct sk_buff *skb, |
@@ -1286,7 +1309,7 @@ static void accept_cr(struct iwch_ep *ep, __be32 peer_ip, struct sk_buff *skb) | |||
1286 | rpl->opt2 = htonl(opt2); | 1309 | rpl->opt2 = htonl(opt2); |
1287 | rpl->rsvd = rpl->opt2; /* workaround for HW bug */ | 1310 | rpl->rsvd = rpl->opt2; /* workaround for HW bug */ |
1288 | skb->priority = CPL_PRIORITY_SETUP; | 1311 | skb->priority = CPL_PRIORITY_SETUP; |
1289 | l2t_send(ep->com.tdev, skb, ep->l2t); | 1312 | iwch_l2t_send(ep->com.tdev, skb, ep->l2t); |
1290 | 1313 | ||
1291 | return; | 1314 | return; |
1292 | } | 1315 | } |
@@ -1315,7 +1338,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip, | |||
1315 | rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT); | 1338 | rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT); |
1316 | rpl->opt2 = 0; | 1339 | rpl->opt2 = 0; |
1317 | rpl->rsvd = rpl->opt2; | 1340 | rpl->rsvd = rpl->opt2; |
1318 | cxgb3_ofld_send(tdev, skb); | 1341 | iwch_cxgb3_ofld_send(tdev, skb); |
1319 | } | 1342 | } |
1320 | } | 1343 | } |
1321 | 1344 | ||
@@ -1613,7 +1636,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1613 | rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); | 1636 | rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); |
1614 | OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); | 1637 | OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); |
1615 | rpl->cmd = CPL_ABORT_NO_RST; | 1638 | rpl->cmd = CPL_ABORT_NO_RST; |
1616 | cxgb3_ofld_send(ep->com.tdev, rpl_skb); | 1639 | iwch_cxgb3_ofld_send(ep->com.tdev, rpl_skb); |
1617 | out: | 1640 | out: |
1618 | if (release) | 1641 | if (release) |
1619 | release_ep_resources(ep); | 1642 | release_ep_resources(ep); |
@@ -2017,8 +2040,11 @@ int iwch_destroy_listen(struct iw_cm_id *cm_id) | |||
2017 | ep->com.rpl_done = 0; | 2040 | ep->com.rpl_done = 0; |
2018 | ep->com.rpl_err = 0; | 2041 | ep->com.rpl_err = 0; |
2019 | err = listen_stop(ep); | 2042 | err = listen_stop(ep); |
2043 | if (err) | ||
2044 | goto done; | ||
2020 | wait_event(ep->com.waitq, ep->com.rpl_done); | 2045 | wait_event(ep->com.waitq, ep->com.rpl_done); |
2021 | cxgb3_free_stid(ep->com.tdev, ep->stid); | 2046 | cxgb3_free_stid(ep->com.tdev, ep->stid); |
2047 | done: | ||
2022 | err = ep->com.rpl_err; | 2048 | err = ep->com.rpl_err; |
2023 | cm_id->rem_ref(cm_id); | 2049 | cm_id->rem_ref(cm_id); |
2024 | put_ep(&ep->com); | 2050 | put_ep(&ep->com); |
@@ -2030,12 +2056,22 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp) | |||
2030 | int ret=0; | 2056 | int ret=0; |
2031 | unsigned long flags; | 2057 | unsigned long flags; |
2032 | int close = 0; | 2058 | int close = 0; |
2059 | int fatal = 0; | ||
2060 | struct t3cdev *tdev; | ||
2061 | struct cxio_rdev *rdev; | ||
2033 | 2062 | ||
2034 | spin_lock_irqsave(&ep->com.lock, flags); | 2063 | spin_lock_irqsave(&ep->com.lock, flags); |
2035 | 2064 | ||
2036 | PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, | 2065 | PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, |
2037 | states[ep->com.state], abrupt); | 2066 | states[ep->com.state], abrupt); |
2038 | 2067 | ||
2068 | tdev = (struct t3cdev *)ep->com.tdev; | ||
2069 | rdev = (struct cxio_rdev *)tdev->ulp; | ||
2070 | if (cxio_fatal_error(rdev)) { | ||
2071 | fatal = 1; | ||
2072 | close_complete_upcall(ep); | ||
2073 | ep->com.state = DEAD; | ||
2074 | } | ||
2039 | switch (ep->com.state) { | 2075 | switch (ep->com.state) { |
2040 | case MPA_REQ_WAIT: | 2076 | case MPA_REQ_WAIT: |
2041 | case MPA_REQ_SENT: | 2077 | case MPA_REQ_SENT: |
@@ -2075,7 +2111,11 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp) | |||
2075 | ret = send_abort(ep, NULL, gfp); | 2111 | ret = send_abort(ep, NULL, gfp); |
2076 | else | 2112 | else |
2077 | ret = send_halfclose(ep, gfp); | 2113 | ret = send_halfclose(ep, gfp); |
2114 | if (ret) | ||
2115 | fatal = 1; | ||
2078 | } | 2116 | } |
2117 | if (fatal) | ||
2118 | release_ep_resources(ep); | ||
2079 | return ret; | 2119 | return ret; |
2080 | } | 2120 | } |
2081 | 2121 | ||
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index c758fbd58478..2f546a625330 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
@@ -751,7 +751,7 @@ int iwch_post_zb_read(struct iwch_qp *qhp) | |||
751 | wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)| | 751 | wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)| |
752 | V_FW_RIWR_LEN(flit_cnt)); | 752 | V_FW_RIWR_LEN(flit_cnt)); |
753 | skb->priority = CPL_PRIORITY_DATA; | 753 | skb->priority = CPL_PRIORITY_DATA; |
754 | return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb); | 754 | return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb); |
755 | } | 755 | } |
756 | 756 | ||
757 | /* | 757 | /* |
@@ -783,7 +783,7 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg) | |||
783 | V_FW_RIWR_FLAGS(T3_COMPLETION_FLAG | T3_NOTIFY_FLAG)); | 783 | V_FW_RIWR_FLAGS(T3_COMPLETION_FLAG | T3_NOTIFY_FLAG)); |
784 | wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)); | 784 | wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)); |
785 | skb->priority = CPL_PRIORITY_DATA; | 785 | skb->priority = CPL_PRIORITY_DATA; |
786 | return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb); | 786 | return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb); |
787 | } | 787 | } |
788 | 788 | ||
789 | /* | 789 | /* |