diff options
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 64 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/cq.c | 18 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 57 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/mem.c | 9 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/qp.c | 35 |
5 files changed, 72 insertions, 111 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 2f0a26cf8e09..6819ac4cbcbb 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
| @@ -252,7 +252,7 @@ static void *alloc_ep(int size, gfp_t gfp) | |||
| 252 | if (epc) { | 252 | if (epc) { |
| 253 | kref_init(&epc->kref); | 253 | kref_init(&epc->kref); |
| 254 | spin_lock_init(&epc->lock); | 254 | spin_lock_init(&epc->lock); |
| 255 | init_waitqueue_head(&epc->waitq); | 255 | c4iw_init_wr_wait(&epc->wr_wait); |
| 256 | } | 256 | } |
| 257 | PDBG("%s alloc ep %p\n", __func__, epc); | 257 | PDBG("%s alloc ep %p\n", __func__, epc); |
| 258 | return epc; | 258 | return epc; |
| @@ -1213,9 +1213,9 @@ static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1213 | } | 1213 | } |
| 1214 | PDBG("%s ep %p status %d error %d\n", __func__, ep, | 1214 | PDBG("%s ep %p status %d error %d\n", __func__, ep, |
| 1215 | rpl->status, status2errno(rpl->status)); | 1215 | rpl->status, status2errno(rpl->status)); |
| 1216 | ep->com.rpl_err = status2errno(rpl->status); | 1216 | ep->com.wr_wait.ret = status2errno(rpl->status); |
| 1217 | ep->com.rpl_done = 1; | 1217 | ep->com.wr_wait.done = 1; |
| 1218 | wake_up(&ep->com.waitq); | 1218 | wake_up(&ep->com.wr_wait.wait); |
| 1219 | 1219 | ||
| 1220 | return 0; | 1220 | return 0; |
| 1221 | } | 1221 | } |
| @@ -1249,9 +1249,9 @@ static int close_listsrv_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1249 | struct c4iw_listen_ep *ep = lookup_stid(t, stid); | 1249 | struct c4iw_listen_ep *ep = lookup_stid(t, stid); |
| 1250 | 1250 | ||
| 1251 | PDBG("%s ep %p\n", __func__, ep); | 1251 | PDBG("%s ep %p\n", __func__, ep); |
| 1252 | ep->com.rpl_err = status2errno(rpl->status); | 1252 | ep->com.wr_wait.ret = status2errno(rpl->status); |
| 1253 | ep->com.rpl_done = 1; | 1253 | ep->com.wr_wait.done = 1; |
| 1254 | wake_up(&ep->com.waitq); | 1254 | wake_up(&ep->com.wr_wait.wait); |
| 1255 | return 0; | 1255 | return 0; |
| 1256 | } | 1256 | } |
| 1257 | 1257 | ||
| @@ -1507,17 +1507,17 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1507 | * in rdma connection migration (see c4iw_accept_cr()). | 1507 | * in rdma connection migration (see c4iw_accept_cr()). |
| 1508 | */ | 1508 | */ |
| 1509 | __state_set(&ep->com, CLOSING); | 1509 | __state_set(&ep->com, CLOSING); |
| 1510 | ep->com.rpl_done = 1; | 1510 | ep->com.wr_wait.done = 1; |
| 1511 | ep->com.rpl_err = -ECONNRESET; | 1511 | ep->com.wr_wait.ret = -ECONNRESET; |
| 1512 | PDBG("waking up ep %p tid %u\n", ep, ep->hwtid); | 1512 | PDBG("waking up ep %p tid %u\n", ep, ep->hwtid); |
| 1513 | wake_up(&ep->com.waitq); | 1513 | wake_up(&ep->com.wr_wait.wait); |
| 1514 | break; | 1514 | break; |
| 1515 | case MPA_REP_SENT: | 1515 | case MPA_REP_SENT: |
| 1516 | __state_set(&ep->com, CLOSING); | 1516 | __state_set(&ep->com, CLOSING); |
| 1517 | ep->com.rpl_done = 1; | 1517 | ep->com.wr_wait.done = 1; |
| 1518 | ep->com.rpl_err = -ECONNRESET; | 1518 | ep->com.wr_wait.ret = -ECONNRESET; |
| 1519 | PDBG("waking up ep %p tid %u\n", ep, ep->hwtid); | 1519 | PDBG("waking up ep %p tid %u\n", ep, ep->hwtid); |
| 1520 | wake_up(&ep->com.waitq); | 1520 | wake_up(&ep->com.wr_wait.wait); |
| 1521 | break; | 1521 | break; |
| 1522 | case FPDU_MODE: | 1522 | case FPDU_MODE: |
| 1523 | start_ep_timer(ep); | 1523 | start_ep_timer(ep); |
| @@ -1605,10 +1605,10 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1605 | connect_reply_upcall(ep, -ECONNRESET); | 1605 | connect_reply_upcall(ep, -ECONNRESET); |
| 1606 | break; | 1606 | break; |
| 1607 | case MPA_REP_SENT: | 1607 | case MPA_REP_SENT: |
| 1608 | ep->com.rpl_done = 1; | 1608 | ep->com.wr_wait.done = 1; |
| 1609 | ep->com.rpl_err = -ECONNRESET; | 1609 | ep->com.wr_wait.ret = -ECONNRESET; |
| 1610 | PDBG("waking up ep %p\n", ep); | 1610 | PDBG("waking up ep %p\n", ep); |
| 1611 | wake_up(&ep->com.waitq); | 1611 | wake_up(&ep->com.wr_wait.wait); |
| 1612 | break; | 1612 | break; |
| 1613 | case MPA_REQ_RCVD: | 1613 | case MPA_REQ_RCVD: |
| 1614 | 1614 | ||
| @@ -1618,10 +1618,10 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1618 | * rejects the CR. Also wake up anyone waiting | 1618 | * rejects the CR. Also wake up anyone waiting |
| 1619 | * in rdma connection migration (see c4iw_accept_cr()). | 1619 | * in rdma connection migration (see c4iw_accept_cr()). |
| 1620 | */ | 1620 | */ |
| 1621 | ep->com.rpl_done = 1; | 1621 | ep->com.wr_wait.done = 1; |
| 1622 | ep->com.rpl_err = -ECONNRESET; | 1622 | ep->com.wr_wait.ret = -ECONNRESET; |
| 1623 | PDBG("waking up ep %p tid %u\n", ep, ep->hwtid); | 1623 | PDBG("waking up ep %p tid %u\n", ep, ep->hwtid); |
| 1624 | wake_up(&ep->com.waitq); | 1624 | wake_up(&ep->com.wr_wait.wait); |
| 1625 | break; | 1625 | break; |
| 1626 | case MORIBUND: | 1626 | case MORIBUND: |
| 1627 | case CLOSING: | 1627 | case CLOSING: |
| @@ -2043,6 +2043,7 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog) | |||
| 2043 | } | 2043 | } |
| 2044 | 2044 | ||
| 2045 | state_set(&ep->com, LISTEN); | 2045 | state_set(&ep->com, LISTEN); |
| 2046 | c4iw_init_wr_wait(&ep->com.wr_wait); | ||
| 2046 | err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0], ep->stid, | 2047 | err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0], ep->stid, |
| 2047 | ep->com.local_addr.sin_addr.s_addr, | 2048 | ep->com.local_addr.sin_addr.s_addr, |
| 2048 | ep->com.local_addr.sin_port, | 2049 | ep->com.local_addr.sin_port, |
| @@ -2051,15 +2052,8 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog) | |||
| 2051 | goto fail3; | 2052 | goto fail3; |
| 2052 | 2053 | ||
| 2053 | /* wait for pass_open_rpl */ | 2054 | /* wait for pass_open_rpl */ |
| 2054 | wait_event_timeout(ep->com.waitq, ep->com.rpl_done, C4IW_WR_TO); | 2055 | err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0, |
| 2055 | if (ep->com.rpl_done) | 2056 | __func__); |
| 2056 | err = ep->com.rpl_err; | ||
| 2057 | else { | ||
| 2058 | printk(KERN_ERR MOD "Device %s not responding!\n", | ||
| 2059 | pci_name(ep->com.dev->rdev.lldi.pdev)); | ||
| 2060 | ep->com.dev->rdev.flags = T4_FATAL_ERROR; | ||
| 2061 | err = -EIO; | ||
| 2062 | } | ||
| 2063 | if (!err) { | 2057 | if (!err) { |
| 2064 | cm_id->provider_data = ep; | 2058 | cm_id->provider_data = ep; |
| 2065 | goto out; | 2059 | goto out; |
| @@ -2083,20 +2077,12 @@ int c4iw_destroy_listen(struct iw_cm_id *cm_id) | |||
| 2083 | 2077 | ||
| 2084 | might_sleep(); | 2078 | might_sleep(); |
| 2085 | state_set(&ep->com, DEAD); | 2079 | state_set(&ep->com, DEAD); |
| 2086 | ep->com.rpl_done = 0; | 2080 | c4iw_init_wr_wait(&ep->com.wr_wait); |
| 2087 | ep->com.rpl_err = 0; | ||
| 2088 | err = listen_stop(ep); | 2081 | err = listen_stop(ep); |
| 2089 | if (err) | 2082 | if (err) |
| 2090 | goto done; | 2083 | goto done; |
| 2091 | wait_event_timeout(ep->com.waitq, ep->com.rpl_done, C4IW_WR_TO); | 2084 | err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0, |
| 2092 | if (ep->com.rpl_done) | 2085 | __func__); |
| 2093 | err = ep->com.rpl_err; | ||
| 2094 | else { | ||
| 2095 | printk(KERN_ERR MOD "Device %s not responding!\n", | ||
| 2096 | pci_name(ep->com.dev->rdev.lldi.pdev)); | ||
| 2097 | ep->com.dev->rdev.flags = T4_FATAL_ERROR; | ||
| 2098 | err = -EIO; | ||
| 2099 | } | ||
| 2100 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET); | 2086 | cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET); |
| 2101 | done: | 2087 | done: |
| 2102 | cm_id->rem_ref(cm_id); | 2088 | cm_id->rem_ref(cm_id); |
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index 70371e92f2a5..8d8f8add6fcd 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c | |||
| @@ -64,14 +64,7 @@ static int destroy_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, | |||
| 64 | c4iw_init_wr_wait(&wr_wait); | 64 | c4iw_init_wr_wait(&wr_wait); |
| 65 | ret = c4iw_ofld_send(rdev, skb); | 65 | ret = c4iw_ofld_send(rdev, skb); |
| 66 | if (!ret) { | 66 | if (!ret) { |
| 67 | wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO); | 67 | ret = c4iw_wait_for_reply(rdev, &wr_wait, 0, 0, __func__); |
| 68 | if (!wr_wait.done) { | ||
| 69 | printk(KERN_ERR MOD "Device %s not responding!\n", | ||
| 70 | pci_name(rdev->lldi.pdev)); | ||
| 71 | rdev->flags = T4_FATAL_ERROR; | ||
| 72 | ret = -EIO; | ||
| 73 | } else | ||
| 74 | ret = wr_wait.ret; | ||
| 75 | } | 68 | } |
| 76 | 69 | ||
| 77 | kfree(cq->sw_queue); | 70 | kfree(cq->sw_queue); |
| @@ -157,14 +150,7 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, | |||
| 157 | if (ret) | 150 | if (ret) |
| 158 | goto err4; | 151 | goto err4; |
| 159 | PDBG("%s wait_event wr_wait %p\n", __func__, &wr_wait); | 152 | PDBG("%s wait_event wr_wait %p\n", __func__, &wr_wait); |
| 160 | wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO); | 153 | ret = c4iw_wait_for_reply(rdev, &wr_wait, 0, 0, __func__); |
| 161 | if (!wr_wait.done) { | ||
| 162 | printk(KERN_ERR MOD "Device %s not responding!\n", | ||
| 163 | pci_name(rdev->lldi.pdev)); | ||
| 164 | rdev->flags = T4_FATAL_ERROR; | ||
| 165 | ret = -EIO; | ||
| 166 | } else | ||
| 167 | ret = wr_wait.ret; | ||
| 168 | if (ret) | 154 | if (ret) |
| 169 | goto err4; | 155 | goto err4; |
| 170 | 156 | ||
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index ed459b8f800f..77801163cd0e 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
| @@ -79,21 +79,6 @@ static inline void *cplhdr(struct sk_buff *skb) | |||
| 79 | return skb->data; | 79 | return skb->data; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | #define C4IW_WR_TO (10*HZ) | ||
| 83 | |||
| 84 | struct c4iw_wr_wait { | ||
| 85 | wait_queue_head_t wait; | ||
| 86 | int done; | ||
| 87 | int ret; | ||
| 88 | }; | ||
| 89 | |||
| 90 | static inline void c4iw_init_wr_wait(struct c4iw_wr_wait *wr_waitp) | ||
| 91 | { | ||
| 92 | wr_waitp->ret = 0; | ||
| 93 | wr_waitp->done = 0; | ||
| 94 | init_waitqueue_head(&wr_waitp->wait); | ||
| 95 | } | ||
| 96 | |||
| 97 | struct c4iw_resource { | 82 | struct c4iw_resource { |
| 98 | struct kfifo tpt_fifo; | 83 | struct kfifo tpt_fifo; |
| 99 | spinlock_t tpt_fifo_lock; | 84 | spinlock_t tpt_fifo_lock; |
| @@ -141,6 +126,44 @@ static inline int c4iw_num_stags(struct c4iw_rdev *rdev) | |||
| 141 | return min((int)T4_MAX_NUM_STAG, (int)(rdev->lldi.vr->stag.size >> 5)); | 126 | return min((int)T4_MAX_NUM_STAG, (int)(rdev->lldi.vr->stag.size >> 5)); |
| 142 | } | 127 | } |
| 143 | 128 | ||
| 129 | #define C4IW_WR_TO (10*HZ) | ||
| 130 | |||
| 131 | struct c4iw_wr_wait { | ||
| 132 | wait_queue_head_t wait; | ||
| 133 | int done; | ||
| 134 | int ret; | ||
| 135 | }; | ||
| 136 | |||
| 137 | static inline void c4iw_init_wr_wait(struct c4iw_wr_wait *wr_waitp) | ||
| 138 | { | ||
| 139 | wr_waitp->ret = 0; | ||
| 140 | wr_waitp->done = 0; | ||
| 141 | init_waitqueue_head(&wr_waitp->wait); | ||
| 142 | } | ||
| 143 | |||
| 144 | static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev, | ||
| 145 | struct c4iw_wr_wait *wr_waitp, | ||
| 146 | u32 hwtid, u32 qpid, | ||
| 147 | const char *func) | ||
| 148 | { | ||
| 149 | unsigned to = C4IW_WR_TO; | ||
| 150 | do { | ||
| 151 | |||
| 152 | wait_event_timeout(wr_waitp->wait, wr_waitp->done, to); | ||
| 153 | if (!wr_waitp->done) { | ||
| 154 | printk(KERN_ERR MOD "%s - Device %s not responding - " | ||
| 155 | "tid %u qpid %u\n", func, | ||
| 156 | pci_name(rdev->lldi.pdev), hwtid, qpid); | ||
| 157 | to = to << 2; | ||
| 158 | } | ||
| 159 | } while (!wr_waitp->done); | ||
| 160 | if (wr_waitp->ret) | ||
| 161 | printk(KERN_WARNING MOD "%s: FW reply %d tid %u qpid %u\n", | ||
| 162 | pci_name(rdev->lldi.pdev), wr_waitp->ret, hwtid, qpid); | ||
| 163 | return wr_waitp->ret; | ||
| 164 | } | ||
| 165 | |||
| 166 | |||
| 144 | struct c4iw_dev { | 167 | struct c4iw_dev { |
| 145 | struct ib_device ibdev; | 168 | struct ib_device ibdev; |
| 146 | struct c4iw_rdev rdev; | 169 | struct c4iw_rdev rdev; |
| @@ -582,9 +605,7 @@ struct c4iw_ep_common { | |||
| 582 | spinlock_t lock; | 605 | spinlock_t lock; |
| 583 | struct sockaddr_in local_addr; | 606 | struct sockaddr_in local_addr; |
| 584 | struct sockaddr_in remote_addr; | 607 | struct sockaddr_in remote_addr; |
| 585 | wait_queue_head_t waitq; | 608 | struct c4iw_wr_wait wr_wait; |
| 586 | int rpl_done; | ||
| 587 | int rpl_err; | ||
| 588 | unsigned long flags; | 609 | unsigned long flags; |
| 589 | }; | 610 | }; |
| 590 | 611 | ||
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index f61562cc7413..273ffe49525a 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c | |||
| @@ -103,14 +103,7 @@ static int write_adapter_mem(struct c4iw_rdev *rdev, u32 addr, u32 len, | |||
| 103 | len -= C4IW_MAX_INLINE_SIZE; | 103 | len -= C4IW_MAX_INLINE_SIZE; |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO); | 106 | ret = c4iw_wait_for_reply(rdev, &wr_wait, 0, 0, __func__); |
| 107 | if (!wr_wait.done) { | ||
| 108 | printk(KERN_ERR MOD "Device %s not responding!\n", | ||
| 109 | pci_name(rdev->lldi.pdev)); | ||
| 110 | rdev->flags = T4_FATAL_ERROR; | ||
| 111 | ret = -EIO; | ||
| 112 | } else | ||
| 113 | ret = wr_wait.ret; | ||
| 114 | return ret; | 107 | return ret; |
| 115 | } | 108 | } |
| 116 | 109 | ||
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 1199d1b9baf6..40187e26d2b9 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c | |||
| @@ -198,14 +198,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, | |||
| 198 | ret = c4iw_ofld_send(rdev, skb); | 198 | ret = c4iw_ofld_send(rdev, skb); |
| 199 | if (ret) | 199 | if (ret) |
| 200 | goto err7; | 200 | goto err7; |
| 201 | wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO); | 201 | ret = c4iw_wait_for_reply(rdev, &wr_wait, 0, wq->sq.qid, __func__); |
| 202 | if (!wr_wait.done) { | ||
| 203 | printk(KERN_ERR MOD "Device %s not responding!\n", | ||
| 204 | pci_name(rdev->lldi.pdev)); | ||
| 205 | rdev->flags = T4_FATAL_ERROR; | ||
| 206 | ret = -EIO; | ||
| 207 | } else | ||
| 208 | ret = wr_wait.ret; | ||
| 209 | if (ret) | 202 | if (ret) |
| 210 | goto err7; | 203 | goto err7; |
| 211 | 204 | ||
| @@ -997,20 +990,8 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
| 997 | if (ret) | 990 | if (ret) |
| 998 | goto out; | 991 | goto out; |
| 999 | 992 | ||
| 1000 | wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO); | 993 | ret = c4iw_wait_for_reply(&rhp->rdev, &wr_wait, qhp->ep->hwtid, |
| 1001 | if (!wr_wait.done) { | 994 | qhp->wq.sq.qid, __func__); |
| 1002 | printk(KERN_ERR MOD "Device %s not responding!\n", | ||
| 1003 | pci_name(rhp->rdev.lldi.pdev)); | ||
| 1004 | rhp->rdev.flags = T4_FATAL_ERROR; | ||
| 1005 | ret = -EIO; | ||
| 1006 | } else { | ||
| 1007 | ret = wr_wait.ret; | ||
| 1008 | if (ret) | ||
| 1009 | printk(KERN_WARNING MOD | ||
| 1010 | "%s: Abnormal close qpid %d ret %u\n", | ||
| 1011 | pci_name(rhp->rdev.lldi.pdev), qhp->wq.sq.qid, | ||
| 1012 | ret); | ||
| 1013 | } | ||
| 1014 | out: | 995 | out: |
| 1015 | PDBG("%s ret %d\n", __func__, ret); | 996 | PDBG("%s ret %d\n", __func__, ret); |
| 1016 | return ret; | 997 | return ret; |
| @@ -1106,14 +1087,8 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp) | |||
| 1106 | if (ret) | 1087 | if (ret) |
| 1107 | goto out; | 1088 | goto out; |
| 1108 | 1089 | ||
| 1109 | wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO); | 1090 | ret = c4iw_wait_for_reply(&rhp->rdev, &wr_wait, qhp->ep->hwtid, |
| 1110 | if (!wr_wait.done) { | 1091 | qhp->wq.sq.qid, __func__); |
| 1111 | printk(KERN_ERR MOD "Device %s not responding!\n", | ||
| 1112 | pci_name(rhp->rdev.lldi.pdev)); | ||
| 1113 | rhp->rdev.flags = T4_FATAL_ERROR; | ||
| 1114 | ret = -EIO; | ||
| 1115 | } else | ||
| 1116 | ret = wr_wait.ret; | ||
| 1117 | out: | 1092 | out: |
| 1118 | PDBG("%s ret %d\n", __func__, ret); | 1093 | PDBG("%s ret %d\n", __func__, ret); |
| 1119 | return ret; | 1094 | return ret; |
