diff options
| -rw-r--r-- | drivers/infiniband/core/cma.c | 207 | ||||
| -rw-r--r-- | drivers/infiniband/core/iwcm.c | 2 | ||||
| -rw-r--r-- | drivers/infiniband/core/ucma.c | 7 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 46 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/device.c | 115 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 36 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/provider.c | 2 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/qp.c | 3 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ipath/ipath_driver.c | 9 | ||||
| -rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 16 | ||||
| -rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.c | 2 | ||||
| -rw-r--r-- | drivers/infiniband/hw/qib/qib_iba7322.c | 3 | ||||
| -rw-r--r-- | drivers/infiniband/hw/qib/qib_pcie.c | 5 | ||||
| -rw-r--r-- | include/rdma/iw_cm.h | 11 | ||||
| -rw-r--r-- | include/rdma/rdma_cm.h | 10 | ||||
| -rw-r--r-- | include/rdma/rdma_user_cm.h | 5 |
16 files changed, 278 insertions, 201 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 5ed9d25d021a..99dde874fbbd 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -148,6 +148,7 @@ struct rdma_id_private { | |||
| 148 | u32 qp_num; | 148 | u32 qp_num; |
| 149 | u8 srq; | 149 | u8 srq; |
| 150 | u8 tos; | 150 | u8 tos; |
| 151 | u8 reuseaddr; | ||
| 151 | }; | 152 | }; |
| 152 | 153 | ||
| 153 | struct cma_multicast { | 154 | struct cma_multicast { |
| @@ -712,6 +713,21 @@ static inline int cma_any_addr(struct sockaddr *addr) | |||
| 712 | return cma_zero_addr(addr) || cma_loopback_addr(addr); | 713 | return cma_zero_addr(addr) || cma_loopback_addr(addr); |
| 713 | } | 714 | } |
| 714 | 715 | ||
| 716 | static int cma_addr_cmp(struct sockaddr *src, struct sockaddr *dst) | ||
| 717 | { | ||
| 718 | if (src->sa_family != dst->sa_family) | ||
| 719 | return -1; | ||
| 720 | |||
| 721 | switch (src->sa_family) { | ||
| 722 | case AF_INET: | ||
| 723 | return ((struct sockaddr_in *) src)->sin_addr.s_addr != | ||
| 724 | ((struct sockaddr_in *) dst)->sin_addr.s_addr; | ||
| 725 | default: | ||
| 726 | return ipv6_addr_cmp(&((struct sockaddr_in6 *) src)->sin6_addr, | ||
| 727 | &((struct sockaddr_in6 *) dst)->sin6_addr); | ||
| 728 | } | ||
| 729 | } | ||
| 730 | |||
| 715 | static inline __be16 cma_port(struct sockaddr *addr) | 731 | static inline __be16 cma_port(struct sockaddr *addr) |
| 716 | { | 732 | { |
| 717 | if (addr->sa_family == AF_INET) | 733 | if (addr->sa_family == AF_INET) |
| @@ -1564,50 +1580,6 @@ static void cma_listen_on_all(struct rdma_id_private *id_priv) | |||
| 1564 | mutex_unlock(&lock); | 1580 | mutex_unlock(&lock); |
| 1565 | } | 1581 | } |
| 1566 | 1582 | ||
| 1567 | int rdma_listen(struct rdma_cm_id *id, int backlog) | ||
| 1568 | { | ||
| 1569 | struct rdma_id_private *id_priv; | ||
| 1570 | int ret; | ||
| 1571 | |||
| 1572 | id_priv = container_of(id, struct rdma_id_private, id); | ||
| 1573 | if (id_priv->state == CMA_IDLE) { | ||
| 1574 | ((struct sockaddr *) &id->route.addr.src_addr)->sa_family = AF_INET; | ||
| 1575 | ret = rdma_bind_addr(id, (struct sockaddr *) &id->route.addr.src_addr); | ||
| 1576 | if (ret) | ||
| 1577 | return ret; | ||
| 1578 | } | ||
| 1579 | |||
| 1580 | if (!cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_LISTEN)) | ||
| 1581 | return -EINVAL; | ||
| 1582 | |||
| 1583 | id_priv->backlog = backlog; | ||
| 1584 | if (id->device) { | ||
| 1585 | switch (rdma_node_get_transport(id->device->node_type)) { | ||
| 1586 | case RDMA_TRANSPORT_IB: | ||
| 1587 | ret = cma_ib_listen(id_priv); | ||
| 1588 | if (ret) | ||
| 1589 | goto err; | ||
| 1590 | break; | ||
| 1591 | case RDMA_TRANSPORT_IWARP: | ||
| 1592 | ret = cma_iw_listen(id_priv, backlog); | ||
| 1593 | if (ret) | ||
| 1594 | goto err; | ||
| 1595 | break; | ||
| 1596 | default: | ||
| 1597 | ret = -ENOSYS; | ||
| 1598 | goto err; | ||
| 1599 | } | ||
| 1600 | } else | ||
| 1601 | cma_listen_on_all(id_priv); | ||
| 1602 | |||
| 1603 | return 0; | ||
| 1604 | err: | ||
| 1605 | id_priv->backlog = 0; | ||
| 1606 | cma_comp_exch(id_priv, CMA_LISTEN, CMA_ADDR_BOUND); | ||
| 1607 | return ret; | ||
| 1608 | } | ||
| 1609 | EXPORT_SYMBOL(rdma_listen); | ||
| 1610 | |||
| 1611 | void rdma_set_service_type(struct rdma_cm_id *id, int tos) | 1583 | void rdma_set_service_type(struct rdma_cm_id *id, int tos) |
| 1612 | { | 1584 | { |
| 1613 | struct rdma_id_private *id_priv; | 1585 | struct rdma_id_private *id_priv; |
| @@ -2090,6 +2062,25 @@ err: | |||
| 2090 | } | 2062 | } |
| 2091 | EXPORT_SYMBOL(rdma_resolve_addr); | 2063 | EXPORT_SYMBOL(rdma_resolve_addr); |
| 2092 | 2064 | ||
| 2065 | int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse) | ||
| 2066 | { | ||
| 2067 | struct rdma_id_private *id_priv; | ||
| 2068 | unsigned long flags; | ||
| 2069 | int ret; | ||
| 2070 | |||
| 2071 | id_priv = container_of(id, struct rdma_id_private, id); | ||
| 2072 | spin_lock_irqsave(&id_priv->lock, flags); | ||
| 2073 | if (id_priv->state == CMA_IDLE) { | ||
| 2074 | id_priv->reuseaddr = reuse; | ||
| 2075 | ret = 0; | ||
| 2076 | } else { | ||
| 2077 | ret = -EINVAL; | ||
| 2078 | } | ||
| 2079 | spin_unlock_irqrestore(&id_priv->lock, flags); | ||
| 2080 | return ret; | ||
| 2081 | } | ||
| 2082 | EXPORT_SYMBOL(rdma_set_reuseaddr); | ||
| 2083 | |||
| 2093 | static void cma_bind_port(struct rdma_bind_list *bind_list, | 2084 | static void cma_bind_port(struct rdma_bind_list *bind_list, |
| 2094 | struct rdma_id_private *id_priv) | 2085 | struct rdma_id_private *id_priv) |
| 2095 | { | 2086 | { |
| @@ -2165,41 +2156,71 @@ retry: | |||
| 2165 | return -EADDRNOTAVAIL; | 2156 | return -EADDRNOTAVAIL; |
| 2166 | } | 2157 | } |
| 2167 | 2158 | ||
| 2168 | static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv) | 2159 | /* |
| 2160 | * Check that the requested port is available. This is called when trying to | ||
| 2161 | * bind to a specific port, or when trying to listen on a bound port. In | ||
| 2162 | * the latter case, the provided id_priv may already be on the bind_list, but | ||
| 2163 | * we still need to check that it's okay to start listening. | ||
| 2164 | */ | ||
| 2165 | static int cma_check_port(struct rdma_bind_list *bind_list, | ||
| 2166 | struct rdma_id_private *id_priv, uint8_t reuseaddr) | ||
| 2169 | { | 2167 | { |
| 2170 | struct rdma_id_private *cur_id; | 2168 | struct rdma_id_private *cur_id; |
| 2171 | struct sockaddr_in *sin, *cur_sin; | 2169 | struct sockaddr *addr, *cur_addr; |
| 2172 | struct rdma_bind_list *bind_list; | ||
| 2173 | struct hlist_node *node; | 2170 | struct hlist_node *node; |
| 2171 | |||
| 2172 | addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr; | ||
| 2173 | if (cma_any_addr(addr) && !reuseaddr) | ||
| 2174 | return -EADDRNOTAVAIL; | ||
| 2175 | |||
| 2176 | hlist_for_each_entry(cur_id, node, &bind_list->owners, node) { | ||
| 2177 | if (id_priv == cur_id) | ||
| 2178 | continue; | ||
| 2179 | |||
| 2180 | if ((cur_id->state == CMA_LISTEN) || | ||
| 2181 | !reuseaddr || !cur_id->reuseaddr) { | ||
| 2182 | cur_addr = (struct sockaddr *) &cur_id->id.route.addr.src_addr; | ||
| 2183 | if (cma_any_addr(cur_addr)) | ||
| 2184 | return -EADDRNOTAVAIL; | ||
| 2185 | |||
| 2186 | if (!cma_addr_cmp(addr, cur_addr)) | ||
| 2187 | return -EADDRINUSE; | ||
| 2188 | } | ||
| 2189 | } | ||
| 2190 | return 0; | ||
| 2191 | } | ||
| 2192 | |||
| 2193 | static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv) | ||
| 2194 | { | ||
| 2195 | struct rdma_bind_list *bind_list; | ||
| 2174 | unsigned short snum; | 2196 | unsigned short snum; |
| 2197 | int ret; | ||
| 2175 | 2198 | ||
| 2176 | sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr; | 2199 | snum = ntohs(cma_port((struct sockaddr *) &id_priv->id.route.addr.src_addr)); |
| 2177 | snum = ntohs(sin->sin_port); | ||
| 2178 | if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) | 2200 | if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) |
| 2179 | return -EACCES; | 2201 | return -EACCES; |
| 2180 | 2202 | ||
| 2181 | bind_list = idr_find(ps, snum); | 2203 | bind_list = idr_find(ps, snum); |
| 2182 | if (!bind_list) | 2204 | if (!bind_list) { |
| 2183 | return cma_alloc_port(ps, id_priv, snum); | 2205 | ret = cma_alloc_port(ps, id_priv, snum); |
| 2184 | 2206 | } else { | |
| 2185 | /* | 2207 | ret = cma_check_port(bind_list, id_priv, id_priv->reuseaddr); |
| 2186 | * We don't support binding to any address if anyone is bound to | 2208 | if (!ret) |
| 2187 | * a specific address on the same port. | 2209 | cma_bind_port(bind_list, id_priv); |
| 2188 | */ | ||
| 2189 | if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)) | ||
| 2190 | return -EADDRNOTAVAIL; | ||
| 2191 | |||
| 2192 | hlist_for_each_entry(cur_id, node, &bind_list->owners, node) { | ||
| 2193 | if (cma_any_addr((struct sockaddr *) &cur_id->id.route.addr.src_addr)) | ||
| 2194 | return -EADDRNOTAVAIL; | ||
| 2195 | |||
| 2196 | cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr; | ||
| 2197 | if (sin->sin_addr.s_addr == cur_sin->sin_addr.s_addr) | ||
| 2198 | return -EADDRINUSE; | ||
| 2199 | } | 2210 | } |
| 2211 | return ret; | ||
| 2212 | } | ||
| 2200 | 2213 | ||
| 2201 | cma_bind_port(bind_list, id_priv); | 2214 | static int cma_bind_listen(struct rdma_id_private *id_priv) |
| 2202 | return 0; | 2215 | { |
| 2216 | struct rdma_bind_list *bind_list = id_priv->bind_list; | ||
| 2217 | int ret = 0; | ||
| 2218 | |||
| 2219 | mutex_lock(&lock); | ||
| 2220 | if (bind_list->owners.first->next) | ||
| 2221 | ret = cma_check_port(bind_list, id_priv, 0); | ||
| 2222 | mutex_unlock(&lock); | ||
| 2223 | return ret; | ||
| 2203 | } | 2224 | } |
| 2204 | 2225 | ||
| 2205 | static int cma_get_port(struct rdma_id_private *id_priv) | 2226 | static int cma_get_port(struct rdma_id_private *id_priv) |
| @@ -2253,6 +2274,56 @@ static int cma_check_linklocal(struct rdma_dev_addr *dev_addr, | |||
| 2253 | return 0; | 2274 | return 0; |
| 2254 | } | 2275 | } |
| 2255 | 2276 | ||
| 2277 | int rdma_listen(struct rdma_cm_id *id, int backlog) | ||
| 2278 | { | ||
| 2279 | struct rdma_id_private *id_priv; | ||
| 2280 | int ret; | ||
| 2281 | |||
| 2282 | id_priv = container_of(id, struct rdma_id_private, id); | ||
| 2283 | if (id_priv->state == CMA_IDLE) { | ||
| 2284 | ((struct sockaddr *) &id->route.addr.src_addr)->sa_family = AF_INET; | ||
| 2285 | ret = rdma_bind_addr(id, (struct sockaddr *) &id->route.addr.src_addr); | ||
| 2286 | if (ret) | ||
| 2287 | return ret; | ||
| 2288 | } | ||
| 2289 | |||
| 2290 | if (!cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_LISTEN)) | ||
| 2291 | return -EINVAL; | ||
| 2292 | |||
| 2293 | if (id_priv->reuseaddr) { | ||
| 2294 | ret = cma_bind_listen(id_priv); | ||
| 2295 | if (ret) | ||
| 2296 | goto err; | ||
| 2297 | } | ||
| 2298 | |||
| 2299 | id_priv->backlog = backlog; | ||
| 2300 | if (id->device) { | ||
| 2301 | switch (rdma_node_get_transport(id->device->node_type)) { | ||
| 2302 | case RDMA_TRANSPORT_IB: | ||
| 2303 | ret = cma_ib_listen(id_priv); | ||
| 2304 | if (ret) | ||
| 2305 | goto err; | ||
| 2306 | break; | ||
| 2307 | case RDMA_TRANSPORT_IWARP: | ||
| 2308 | ret = cma_iw_listen(id_priv, backlog); | ||
| 2309 | if (ret) | ||
| 2310 | goto err; | ||
| 2311 | break; | ||
| 2312 | default: | ||
| 2313 | ret = -ENOSYS; | ||
| 2314 | goto err; | ||
| 2315 | } | ||
| 2316 | } else | ||
| 2317 | cma_listen_on_all(id_priv); | ||
| 2318 | |||
| 2319 | return 0; | ||
| 2320 | err: | ||
| 2321 | id_priv->backlog = 0; | ||
| 2322 | cma_comp_exch(id_priv, CMA_LISTEN, CMA_ADDR_BOUND); | ||
| 2323 | return ret; | ||
| 2324 | } | ||
| 2325 | EXPORT_SYMBOL(rdma_listen); | ||
| 2326 | |||
| 2256 | int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) | 2327 | int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) |
| 2257 | { | 2328 | { |
| 2258 | struct rdma_id_private *id_priv; | 2329 | struct rdma_id_private *id_priv; |
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index 2a1e9ae134b4..a9c042345c6f 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c | |||
| @@ -725,7 +725,7 @@ static int cm_conn_rep_handler(struct iwcm_id_private *cm_id_priv, | |||
| 725 | */ | 725 | */ |
| 726 | clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); | 726 | clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); |
| 727 | BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_SENT); | 727 | BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_SENT); |
| 728 | if (iw_event->status == IW_CM_EVENT_STATUS_ACCEPTED) { | 728 | if (iw_event->status == 0) { |
| 729 | cm_id_priv->id.local_addr = iw_event->local_addr; | 729 | cm_id_priv->id.local_addr = iw_event->local_addr; |
| 730 | cm_id_priv->id.remote_addr = iw_event->remote_addr; | 730 | cm_id_priv->id.remote_addr = iw_event->remote_addr; |
| 731 | cm_id_priv->state = IW_CM_STATE_ESTABLISHED; | 731 | cm_id_priv->state = IW_CM_STATE_ESTABLISHED; |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index ec1e9da1488b..b3fa798525b2 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
| @@ -883,6 +883,13 @@ static int ucma_set_option_id(struct ucma_context *ctx, int optname, | |||
| 883 | } | 883 | } |
| 884 | rdma_set_service_type(ctx->cm_id, *((u8 *) optval)); | 884 | rdma_set_service_type(ctx->cm_id, *((u8 *) optval)); |
| 885 | break; | 885 | break; |
| 886 | case RDMA_OPTION_ID_REUSEADDR: | ||
| 887 | if (optlen != sizeof(int)) { | ||
| 888 | ret = -EINVAL; | ||
| 889 | break; | ||
| 890 | } | ||
| 891 | ret = rdma_set_reuseaddr(ctx->cm_id, *((int *) optval) ? 1 : 0); | ||
| 892 | break; | ||
| 886 | default: | 893 | default: |
| 887 | ret = -ENOSYS; | 894 | ret = -ENOSYS; |
| 888 | } | 895 | } |
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 9d8dcfab2b38..d7ee70fc9173 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
| @@ -1198,9 +1198,7 @@ static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1198 | } | 1198 | } |
| 1199 | PDBG("%s ep %p status %d error %d\n", __func__, ep, | 1199 | PDBG("%s ep %p status %d error %d\n", __func__, ep, |
| 1200 | rpl->status, status2errno(rpl->status)); | 1200 | rpl->status, status2errno(rpl->status)); |
| 1201 | ep->com.wr_wait.ret = status2errno(rpl->status); | 1201 | c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status)); |
| 1202 | ep->com.wr_wait.done = 1; | ||
| 1203 | wake_up(&ep->com.wr_wait.wait); | ||
| 1204 | 1202 | ||
| 1205 | return 0; | 1203 | return 0; |
| 1206 | } | 1204 | } |
| @@ -1234,9 +1232,7 @@ static int close_listsrv_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1234 | struct c4iw_listen_ep *ep = lookup_stid(t, stid); | 1232 | struct c4iw_listen_ep *ep = lookup_stid(t, stid); |
| 1235 | 1233 | ||
| 1236 | PDBG("%s ep %p\n", __func__, ep); | 1234 | PDBG("%s ep %p\n", __func__, ep); |
| 1237 | ep->com.wr_wait.ret = status2errno(rpl->status); | 1235 | c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status)); |
| 1238 | ep->com.wr_wait.done = 1; | ||
| 1239 | wake_up(&ep->com.wr_wait.wait); | ||
| 1240 | return 0; | 1236 | return 0; |
| 1241 | } | 1237 | } |
| 1242 | 1238 | ||
| @@ -1466,7 +1462,7 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1466 | struct c4iw_qp_attributes attrs; | 1462 | struct c4iw_qp_attributes attrs; |
| 1467 | int disconnect = 1; | 1463 | int disconnect = 1; |
| 1468 | int release = 0; | 1464 | int release = 0; |
| 1469 | int closing = 0; | 1465 | int abort = 0; |
| 1470 | struct tid_info *t = dev->rdev.lldi.tids; | 1466 | struct tid_info *t = dev->rdev.lldi.tids; |
| 1471 | unsigned int tid = GET_TID(hdr); | 1467 | unsigned int tid = GET_TID(hdr); |
| 1472 | 1468 | ||
| @@ -1492,23 +1488,22 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1492 | * in rdma connection migration (see c4iw_accept_cr()). | 1488 | * in rdma connection migration (see c4iw_accept_cr()). |
| 1493 | */ | 1489 | */ |
| 1494 | __state_set(&ep->com, CLOSING); | 1490 | __state_set(&ep->com, CLOSING); |
| 1495 | ep->com.wr_wait.done = 1; | ||
| 1496 | ep->com.wr_wait.ret = -ECONNRESET; | ||
| 1497 | PDBG("waking up ep %p tid %u\n", ep, ep->hwtid); | 1491 | PDBG("waking up ep %p tid %u\n", ep, ep->hwtid); |
| 1498 | wake_up(&ep->com.wr_wait.wait); | 1492 | c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET); |
| 1499 | break; | 1493 | break; |
| 1500 | case MPA_REP_SENT: | 1494 | case MPA_REP_SENT: |
| 1501 | __state_set(&ep->com, CLOSING); | 1495 | __state_set(&ep->com, CLOSING); |
| 1502 | ep->com.wr_wait.done = 1; | ||
| 1503 | ep->com.wr_wait.ret = -ECONNRESET; | ||
| 1504 | PDBG("waking up ep %p tid %u\n", ep, ep->hwtid); | 1496 | PDBG("waking up ep %p tid %u\n", ep, ep->hwtid); |
| 1505 | wake_up(&ep->com.wr_wait.wait); | 1497 | c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET); |
| 1506 | break; | 1498 | break; |
| 1507 | case FPDU_MODE: | 1499 | case FPDU_MODE: |
| 1508 | start_ep_timer(ep); | 1500 | start_ep_timer(ep); |
| 1509 | __state_set(&ep->com, CLOSING); | 1501 | __state_set(&ep->com, CLOSING); |
| 1510 | closing = 1; | 1502 | attrs.next_state = C4IW_QP_STATE_CLOSING; |
| 1503 | abort = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, | ||
| 1504 | C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); | ||
| 1511 | peer_close_upcall(ep); | 1505 | peer_close_upcall(ep); |
| 1506 | disconnect = 1; | ||
| 1512 | break; | 1507 | break; |
| 1513 | case ABORTING: | 1508 | case ABORTING: |
| 1514 | disconnect = 0; | 1509 | disconnect = 0; |
| @@ -1536,11 +1531,6 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1536 | BUG_ON(1); | 1531 | BUG_ON(1); |
| 1537 | } | 1532 | } |
| 1538 | mutex_unlock(&ep->com.mutex); | 1533 | mutex_unlock(&ep->com.mutex); |
| 1539 | if (closing) { | ||
| 1540 | attrs.next_state = C4IW_QP_STATE_CLOSING; | ||
| 1541 | c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, | ||
| 1542 | C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); | ||
| 1543 | } | ||
| 1544 | if (disconnect) | 1534 | if (disconnect) |
| 1545 | c4iw_ep_disconnect(ep, 0, GFP_KERNEL); | 1535 | c4iw_ep_disconnect(ep, 0, GFP_KERNEL); |
| 1546 | if (release) | 1536 | if (release) |
| @@ -1581,9 +1571,7 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1581 | /* | 1571 | /* |
| 1582 | * Wake up any threads in rdma_init() or rdma_fini(). | 1572 | * Wake up any threads in rdma_init() or rdma_fini(). |
| 1583 | */ | 1573 | */ |
| 1584 | ep->com.wr_wait.done = 1; | 1574 | c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET); |
| 1585 | ep->com.wr_wait.ret = -ECONNRESET; | ||
| 1586 | wake_up(&ep->com.wr_wait.wait); | ||
| 1587 | 1575 | ||
| 1588 | mutex_lock(&ep->com.mutex); | 1576 | mutex_lock(&ep->com.mutex); |
| 1589 | switch (ep->com.state) { | 1577 | switch (ep->com.state) { |
| @@ -1710,14 +1698,14 @@ static int terminate(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 1710 | ep = lookup_tid(t, tid); | 1698 | ep = lookup_tid(t, tid); |
| 1711 | BUG_ON(!ep); | 1699 | BUG_ON(!ep); |
| 1712 | 1700 | ||
| 1713 | if (ep->com.qp) { | 1701 | if (ep && ep->com.qp) { |
| 1714 | printk(KERN_WARNING MOD "TERM received tid %u qpid %u\n", tid, | 1702 | printk(KERN_WARNING MOD "TERM received tid %u qpid %u\n", tid, |
| 1715 | ep->com.qp->wq.sq.qid); | 1703 | ep->com.qp->wq.sq.qid); |
| 1716 | attrs.next_state = C4IW_QP_STATE_TERMINATE; | 1704 | attrs.next_state = C4IW_QP_STATE_TERMINATE; |
| 1717 | c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, | 1705 | c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, |
| 1718 | C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); | 1706 | C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); |
| 1719 | } else | 1707 | } else |
| 1720 | printk(KERN_WARNING MOD "TERM received tid %u no qp\n", tid); | 1708 | printk(KERN_WARNING MOD "TERM received tid %u no ep/qp\n", tid); |
| 1721 | 1709 | ||
| 1722 | return 0; | 1710 | return 0; |
| 1723 | } | 1711 | } |
| @@ -2296,14 +2284,8 @@ static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb) | |||
| 2296 | ret = (int)((be64_to_cpu(rpl->data[0]) >> 8) & 0xff); | 2284 | ret = (int)((be64_to_cpu(rpl->data[0]) >> 8) & 0xff); |
| 2297 | wr_waitp = (struct c4iw_wr_wait *)(__force unsigned long) rpl->data[1]; | 2285 | wr_waitp = (struct c4iw_wr_wait *)(__force unsigned long) rpl->data[1]; |
| 2298 | PDBG("%s wr_waitp %p ret %u\n", __func__, wr_waitp, ret); | 2286 | PDBG("%s wr_waitp %p ret %u\n", __func__, wr_waitp, ret); |
| 2299 | if (wr_waitp) { | 2287 | if (wr_waitp) |
| 2300 | if (ret) | 2288 | c4iw_wake_up(wr_waitp, ret ? -ret : 0); |
| 2301 | wr_waitp->ret = -ret; | ||
| 2302 | else | ||
| 2303 | wr_waitp->ret = 0; | ||
| 2304 | wr_waitp->done = 1; | ||
| 2305 | wake_up(&wr_waitp->wait); | ||
| 2306 | } | ||
| 2307 | kfree_skb(skb); | 2289 | kfree_skb(skb); |
| 2308 | break; | 2290 | break; |
| 2309 | case 2: | 2291 | case 2: |
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index e29172c2afcb..40a13cc633a3 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c | |||
| @@ -44,7 +44,7 @@ MODULE_DESCRIPTION("Chelsio T4 RDMA Driver"); | |||
| 44 | MODULE_LICENSE("Dual BSD/GPL"); | 44 | MODULE_LICENSE("Dual BSD/GPL"); |
| 45 | MODULE_VERSION(DRV_VERSION); | 45 | MODULE_VERSION(DRV_VERSION); |
| 46 | 46 | ||
| 47 | static LIST_HEAD(dev_list); | 47 | static LIST_HEAD(uld_ctx_list); |
| 48 | static DEFINE_MUTEX(dev_mutex); | 48 | static DEFINE_MUTEX(dev_mutex); |
| 49 | 49 | ||
| 50 | static struct dentry *c4iw_debugfs_root; | 50 | static struct dentry *c4iw_debugfs_root; |
| @@ -370,18 +370,23 @@ static void c4iw_rdev_close(struct c4iw_rdev *rdev) | |||
| 370 | c4iw_destroy_resource(&rdev->resource); | 370 | c4iw_destroy_resource(&rdev->resource); |
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | static void c4iw_remove(struct c4iw_dev *dev) | 373 | struct uld_ctx { |
| 374 | struct list_head entry; | ||
| 375 | struct cxgb4_lld_info lldi; | ||
| 376 | struct c4iw_dev *dev; | ||
| 377 | }; | ||
| 378 | |||
| 379 | static void c4iw_remove(struct uld_ctx *ctx) | ||
| 374 | { | 380 | { |
| 375 | PDBG("%s c4iw_dev %p\n", __func__, dev); | 381 | PDBG("%s c4iw_dev %p\n", __func__, ctx->dev); |
| 376 | list_del(&dev->entry); | 382 | c4iw_unregister_device(ctx->dev); |
| 377 | if (dev->registered) | 383 | c4iw_rdev_close(&ctx->dev->rdev); |
| 378 | c4iw_unregister_device(dev); | 384 | idr_destroy(&ctx->dev->cqidr); |
| 379 | c4iw_rdev_close(&dev->rdev); | 385 | idr_destroy(&ctx->dev->qpidr); |
| 380 | idr_destroy(&dev->cqidr); | 386 | idr_destroy(&ctx->dev->mmidr); |
| 381 | idr_destroy(&dev->qpidr); | 387 | iounmap(ctx->dev->rdev.oc_mw_kva); |
| 382 | idr_destroy(&dev->mmidr); | 388 | ib_dealloc_device(&ctx->dev->ibdev); |
| 383 | iounmap(dev->rdev.oc_mw_kva); | 389 | ctx->dev = NULL; |
| 384 | ib_dealloc_device(&dev->ibdev); | ||
| 385 | } | 390 | } |
| 386 | 391 | ||
| 387 | static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) | 392 | static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) |
| @@ -392,7 +397,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) | |||
| 392 | devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp)); | 397 | devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp)); |
| 393 | if (!devp) { | 398 | if (!devp) { |
| 394 | printk(KERN_ERR MOD "Cannot allocate ib device\n"); | 399 | printk(KERN_ERR MOD "Cannot allocate ib device\n"); |
| 395 | return NULL; | 400 | return ERR_PTR(-ENOMEM); |
| 396 | } | 401 | } |
| 397 | devp->rdev.lldi = *infop; | 402 | devp->rdev.lldi = *infop; |
| 398 | 403 | ||
| @@ -402,27 +407,23 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) | |||
| 402 | devp->rdev.oc_mw_kva = ioremap_wc(devp->rdev.oc_mw_pa, | 407 | devp->rdev.oc_mw_kva = ioremap_wc(devp->rdev.oc_mw_pa, |
| 403 | devp->rdev.lldi.vr->ocq.size); | 408 | devp->rdev.lldi.vr->ocq.size); |
| 404 | 409 | ||
| 405 | printk(KERN_INFO MOD "ocq memory: " | 410 | PDBG(KERN_INFO MOD "ocq memory: " |
| 406 | "hw_start 0x%x size %u mw_pa 0x%lx mw_kva %p\n", | 411 | "hw_start 0x%x size %u mw_pa 0x%lx mw_kva %p\n", |
| 407 | devp->rdev.lldi.vr->ocq.start, devp->rdev.lldi.vr->ocq.size, | 412 | devp->rdev.lldi.vr->ocq.start, devp->rdev.lldi.vr->ocq.size, |
| 408 | devp->rdev.oc_mw_pa, devp->rdev.oc_mw_kva); | 413 | devp->rdev.oc_mw_pa, devp->rdev.oc_mw_kva); |
| 409 | 414 | ||
| 410 | mutex_lock(&dev_mutex); | ||
| 411 | |||
| 412 | ret = c4iw_rdev_open(&devp->rdev); | 415 | ret = c4iw_rdev_open(&devp->rdev); |
| 413 | if (ret) { | 416 | if (ret) { |
| 414 | mutex_unlock(&dev_mutex); | 417 | mutex_unlock(&dev_mutex); |
| 415 | printk(KERN_ERR MOD "Unable to open CXIO rdev err %d\n", ret); | 418 | printk(KERN_ERR MOD "Unable to open CXIO rdev err %d\n", ret); |
| 416 | ib_dealloc_device(&devp->ibdev); | 419 | ib_dealloc_device(&devp->ibdev); |
| 417 | return NULL; | 420 | return ERR_PTR(ret); |
| 418 | } | 421 | } |
| 419 | 422 | ||
| 420 | idr_init(&devp->cqidr); | 423 | idr_init(&devp->cqidr); |
| 421 | idr_init(&devp->qpidr); | 424 | idr_init(&devp->qpidr); |
| 422 | idr_init(&devp->mmidr); | 425 | idr_init(&devp->mmidr); |
| 423 | spin_lock_init(&devp->lock); | 426 | spin_lock_init(&devp->lock); |
| 424 | list_add_tail(&devp->entry, &dev_list); | ||
| 425 | mutex_unlock(&dev_mutex); | ||
| 426 | 427 | ||
| 427 | if (c4iw_debugfs_root) { | 428 | if (c4iw_debugfs_root) { |
| 428 | devp->debugfs_root = debugfs_create_dir( | 429 | devp->debugfs_root = debugfs_create_dir( |
| @@ -435,7 +436,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) | |||
| 435 | 436 | ||
| 436 | static void *c4iw_uld_add(const struct cxgb4_lld_info *infop) | 437 | static void *c4iw_uld_add(const struct cxgb4_lld_info *infop) |
| 437 | { | 438 | { |
| 438 | struct c4iw_dev *dev; | 439 | struct uld_ctx *ctx; |
| 439 | static int vers_printed; | 440 | static int vers_printed; |
| 440 | int i; | 441 | int i; |
| 441 | 442 | ||
| @@ -443,25 +444,33 @@ static void *c4iw_uld_add(const struct cxgb4_lld_info *infop) | |||
| 443 | printk(KERN_INFO MOD "Chelsio T4 RDMA Driver - version %s\n", | 444 | printk(KERN_INFO MOD "Chelsio T4 RDMA Driver - version %s\n", |
| 444 | DRV_VERSION); | 445 | DRV_VERSION); |
| 445 | 446 | ||
| 446 | dev = c4iw_alloc(infop); | 447 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); |
| 447 | if (!dev) | 448 | if (!ctx) { |
| 449 | ctx = ERR_PTR(-ENOMEM); | ||
| 448 | goto out; | 450 | goto out; |
| 451 | } | ||
| 452 | ctx->lldi = *infop; | ||
| 449 | 453 | ||
| 450 | PDBG("%s found device %s nchan %u nrxq %u ntxq %u nports %u\n", | 454 | PDBG("%s found device %s nchan %u nrxq %u ntxq %u nports %u\n", |
| 451 | __func__, pci_name(dev->rdev.lldi.pdev), | 455 | __func__, pci_name(ctx->lldi.pdev), |
| 452 | dev->rdev.lldi.nchan, dev->rdev.lldi.nrxq, | 456 | ctx->lldi.nchan, ctx->lldi.nrxq, |
| 453 | dev->rdev.lldi.ntxq, dev->rdev.lldi.nports); | 457 | ctx->lldi.ntxq, ctx->lldi.nports); |
| 458 | |||
| 459 | mutex_lock(&dev_mutex); | ||
| 460 | list_add_tail(&ctx->entry, &uld_ctx_list); | ||
| 461 | mutex_unlock(&dev_mutex); | ||
| 454 | 462 | ||
| 455 | for (i = 0; i < dev->rdev.lldi.nrxq; i++) | 463 | for (i = 0; i < ctx->lldi.nrxq; i++) |
| 456 | PDBG("rxqid[%u] %u\n", i, dev->rdev.lldi.rxq_ids[i]); | 464 | PDBG("rxqid[%u] %u\n", i, ctx->lldi.rxq_ids[i]); |
| 457 | out: | 465 | out: |
| 458 | return dev; | 466 | return ctx; |
| 459 | } | 467 | } |
| 460 | 468 | ||
| 461 | static int c4iw_uld_rx_handler(void *handle, const __be64 *rsp, | 469 | static int c4iw_uld_rx_handler(void *handle, const __be64 *rsp, |
| 462 | const struct pkt_gl *gl) | 470 | const struct pkt_gl *gl) |
| 463 | { | 471 | { |
| 464 | struct c4iw_dev *dev = handle; | 472 | struct uld_ctx *ctx = handle; |
| 473 | struct c4iw_dev *dev = ctx->dev; | ||
| 465 | struct sk_buff *skb; | 474 | struct sk_buff *skb; |
| 466 | const struct cpl_act_establish *rpl; | 475 | const struct cpl_act_establish *rpl; |
| 467 | unsigned int opcode; | 476 | unsigned int opcode; |
| @@ -503,47 +512,49 @@ nomem: | |||
| 503 | 512 | ||
| 504 | static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state) | 513 | static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state) |
| 505 | { | 514 | { |
| 506 | struct c4iw_dev *dev = handle; | 515 | struct uld_ctx *ctx = handle; |
| 507 | 516 | ||
| 508 | PDBG("%s new_state %u\n", __func__, new_state); | 517 | PDBG("%s new_state %u\n", __func__, new_state); |
| 509 | switch (new_state) { | 518 | switch (new_state) { |
| 510 | case CXGB4_STATE_UP: | 519 | case CXGB4_STATE_UP: |
| 511 | printk(KERN_INFO MOD "%s: Up\n", pci_name(dev->rdev.lldi.pdev)); | 520 | printk(KERN_INFO MOD "%s: Up\n", pci_name(ctx->lldi.pdev)); |
| 512 | if (!dev->registered) { | 521 | if (!ctx->dev) { |
| 513 | int ret; | 522 | int ret = 0; |
| 514 | ret = c4iw_register_device(dev); | 523 | |
| 515 | if (ret) | 524 | ctx->dev = c4iw_alloc(&ctx->lldi); |
| 525 | if (!IS_ERR(ctx->dev)) | ||
| 526 | ret = c4iw_register_device(ctx->dev); | ||
| 527 | if (IS_ERR(ctx->dev) || ret) | ||
| 516 | printk(KERN_ERR MOD | 528 | printk(KERN_ERR MOD |
| 517 | "%s: RDMA registration failed: %d\n", | 529 | "%s: RDMA registration failed: %d\n", |
| 518 | pci_name(dev->rdev.lldi.pdev), ret); | 530 | pci_name(ctx->lldi.pdev), ret); |
| 519 | } | 531 | } |
| 520 | break; | 532 | break; |
| 521 | case CXGB4_STATE_DOWN: | 533 | case CXGB4_STATE_DOWN: |
| 522 | printk(KERN_INFO MOD "%s: Down\n", | 534 | printk(KERN_INFO MOD "%s: Down\n", |
| 523 | pci_name(dev->rdev.lldi.pdev)); | 535 | pci_name(ctx->lldi.pdev)); |
| 524 | if (dev->registered) | 536 | if (ctx->dev) |
| 525 | c4iw_unregister_device(dev); | 537 | c4iw_remove(ctx); |
| 526 | break; | 538 | break; |
| 527 | case CXGB4_STATE_START_RECOVERY: | 539 | case CXGB4_STATE_START_RECOVERY: |
| 528 | printk(KERN_INFO MOD "%s: Fatal Error\n", | 540 | printk(KERN_INFO MOD "%s: Fatal Error\n", |
| 529 | pci_name(dev->rdev.lldi.pdev)); | 541 | pci_name(ctx->lldi.pdev)); |
| 530 | dev->rdev.flags |= T4_FATAL_ERROR; | 542 | if (ctx->dev) { |
| 531 | if (dev->registered) { | ||
| 532 | struct ib_event event; | 543 | struct ib_event event; |
| 533 | 544 | ||
| 545 | ctx->dev->rdev.flags |= T4_FATAL_ERROR; | ||
| 534 | memset(&event, 0, sizeof event); | 546 | memset(&event, 0, sizeof event); |
| 535 | event.event = IB_EVENT_DEVICE_FATAL; | 547 | event.event = IB_EVENT_DEVICE_FATAL; |
| 536 | event.device = &dev->ibdev; | 548 | event.device = &ctx->dev->ibdev; |
| 537 | ib_dispatch_event(&event); | 549 | ib_dispatch_event(&event); |
| 538 | c4iw_unregister_device(dev); | 550 | c4iw_remove(ctx); |
| 539 | } | 551 | } |
| 540 | break; | 552 | break; |
| 541 | case CXGB4_STATE_DETACH: | 553 | case CXGB4_STATE_DETACH: |
| 542 | printk(KERN_INFO MOD "%s: Detach\n", | 554 | printk(KERN_INFO MOD "%s: Detach\n", |
| 543 | pci_name(dev->rdev.lldi.pdev)); | 555 | pci_name(ctx->lldi.pdev)); |
| 544 | mutex_lock(&dev_mutex); | 556 | if (ctx->dev) |
| 545 | c4iw_remove(dev); | 557 | c4iw_remove(ctx); |
| 546 | mutex_unlock(&dev_mutex); | ||
| 547 | break; | 558 | break; |
| 548 | } | 559 | } |
| 549 | return 0; | 560 | return 0; |
| @@ -576,11 +587,13 @@ static int __init c4iw_init_module(void) | |||
| 576 | 587 | ||
| 577 | static void __exit c4iw_exit_module(void) | 588 | static void __exit c4iw_exit_module(void) |
| 578 | { | 589 | { |
| 579 | struct c4iw_dev *dev, *tmp; | 590 | struct uld_ctx *ctx, *tmp; |
| 580 | 591 | ||
| 581 | mutex_lock(&dev_mutex); | 592 | mutex_lock(&dev_mutex); |
| 582 | list_for_each_entry_safe(dev, tmp, &dev_list, entry) { | 593 | list_for_each_entry_safe(ctx, tmp, &uld_ctx_list, entry) { |
| 583 | c4iw_remove(dev); | 594 | if (ctx->dev) |
| 595 | c4iw_remove(ctx); | ||
| 596 | kfree(ctx); | ||
| 584 | } | 597 | } |
| 585 | mutex_unlock(&dev_mutex); | 598 | mutex_unlock(&dev_mutex); |
| 586 | cxgb4_unregister_uld(CXGB4_ULD_RDMA); | 599 | cxgb4_unregister_uld(CXGB4_ULD_RDMA); |
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 9f6166f59268..35d2a5dd9bb4 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
| @@ -131,42 +131,58 @@ static inline int c4iw_num_stags(struct c4iw_rdev *rdev) | |||
| 131 | 131 | ||
| 132 | #define C4IW_WR_TO (10*HZ) | 132 | #define C4IW_WR_TO (10*HZ) |
| 133 | 133 | ||
| 134 | enum { | ||
| 135 | REPLY_READY = 0, | ||
| 136 | }; | ||
| 137 | |||
| 134 | struct c4iw_wr_wait { | 138 | struct c4iw_wr_wait { |
| 135 | wait_queue_head_t wait; | 139 | wait_queue_head_t wait; |
| 136 | int done; | 140 | unsigned long status; |
| 137 | int ret; | 141 | int ret; |
| 138 | }; | 142 | }; |
| 139 | 143 | ||
| 140 | static inline void c4iw_init_wr_wait(struct c4iw_wr_wait *wr_waitp) | 144 | static inline void c4iw_init_wr_wait(struct c4iw_wr_wait *wr_waitp) |
| 141 | { | 145 | { |
| 142 | wr_waitp->ret = 0; | 146 | wr_waitp->ret = 0; |
| 143 | wr_waitp->done = 0; | 147 | wr_waitp->status = 0; |
| 144 | init_waitqueue_head(&wr_waitp->wait); | 148 | init_waitqueue_head(&wr_waitp->wait); |
| 145 | } | 149 | } |
| 146 | 150 | ||
| 151 | static inline void c4iw_wake_up(struct c4iw_wr_wait *wr_waitp, int ret) | ||
| 152 | { | ||
| 153 | wr_waitp->ret = ret; | ||
| 154 | set_bit(REPLY_READY, &wr_waitp->status); | ||
| 155 | wake_up(&wr_waitp->wait); | ||
| 156 | } | ||
| 157 | |||
| 147 | static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev, | 158 | static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev, |
| 148 | struct c4iw_wr_wait *wr_waitp, | 159 | struct c4iw_wr_wait *wr_waitp, |
| 149 | u32 hwtid, u32 qpid, | 160 | u32 hwtid, u32 qpid, |
| 150 | const char *func) | 161 | const char *func) |
| 151 | { | 162 | { |
| 152 | unsigned to = C4IW_WR_TO; | 163 | unsigned to = C4IW_WR_TO; |
| 153 | do { | 164 | int ret; |
| 154 | 165 | ||
| 155 | wait_event_timeout(wr_waitp->wait, wr_waitp->done, to); | 166 | do { |
| 156 | if (!wr_waitp->done) { | 167 | ret = wait_event_timeout(wr_waitp->wait, |
| 168 | test_and_clear_bit(REPLY_READY, &wr_waitp->status), to); | ||
| 169 | if (!ret) { | ||
| 157 | printk(KERN_ERR MOD "%s - Device %s not responding - " | 170 | printk(KERN_ERR MOD "%s - Device %s not responding - " |
| 158 | "tid %u qpid %u\n", func, | 171 | "tid %u qpid %u\n", func, |
| 159 | pci_name(rdev->lldi.pdev), hwtid, qpid); | 172 | pci_name(rdev->lldi.pdev), hwtid, qpid); |
| 173 | if (c4iw_fatal_error(rdev)) { | ||
| 174 | wr_waitp->ret = -EIO; | ||
| 175 | break; | ||
| 176 | } | ||
| 160 | to = to << 2; | 177 | to = to << 2; |
| 161 | } | 178 | } |
| 162 | } while (!wr_waitp->done); | 179 | } while (!ret); |
| 163 | if (wr_waitp->ret) | 180 | if (wr_waitp->ret) |
| 164 | printk(KERN_WARNING MOD "%s: FW reply %d tid %u qpid %u\n", | 181 | PDBG("%s: FW reply %d tid %u qpid %u\n", |
| 165 | pci_name(rdev->lldi.pdev), wr_waitp->ret, hwtid, qpid); | 182 | pci_name(rdev->lldi.pdev), wr_waitp->ret, hwtid, qpid); |
| 166 | return wr_waitp->ret; | 183 | return wr_waitp->ret; |
| 167 | } | 184 | } |
| 168 | 185 | ||
| 169 | |||
| 170 | struct c4iw_dev { | 186 | struct c4iw_dev { |
| 171 | struct ib_device ibdev; | 187 | struct ib_device ibdev; |
| 172 | struct c4iw_rdev rdev; | 188 | struct c4iw_rdev rdev; |
| @@ -175,9 +191,7 @@ struct c4iw_dev { | |||
| 175 | struct idr qpidr; | 191 | struct idr qpidr; |
| 176 | struct idr mmidr; | 192 | struct idr mmidr; |
| 177 | spinlock_t lock; | 193 | spinlock_t lock; |
| 178 | struct list_head entry; | ||
| 179 | struct dentry *debugfs_root; | 194 | struct dentry *debugfs_root; |
| 180 | u8 registered; | ||
| 181 | }; | 195 | }; |
| 182 | 196 | ||
| 183 | static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev) | 197 | static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev) |
diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c index f66dd8bf5128..5b9e4220ca08 100644 --- a/drivers/infiniband/hw/cxgb4/provider.c +++ b/drivers/infiniband/hw/cxgb4/provider.c | |||
| @@ -516,7 +516,6 @@ int c4iw_register_device(struct c4iw_dev *dev) | |||
| 516 | if (ret) | 516 | if (ret) |
| 517 | goto bail2; | 517 | goto bail2; |
| 518 | } | 518 | } |
| 519 | dev->registered = 1; | ||
| 520 | return 0; | 519 | return 0; |
| 521 | bail2: | 520 | bail2: |
| 522 | ib_unregister_device(&dev->ibdev); | 521 | ib_unregister_device(&dev->ibdev); |
| @@ -535,6 +534,5 @@ void c4iw_unregister_device(struct c4iw_dev *dev) | |||
| 535 | c4iw_class_attributes[i]); | 534 | c4iw_class_attributes[i]); |
| 536 | ib_unregister_device(&dev->ibdev); | 535 | ib_unregister_device(&dev->ibdev); |
| 537 | kfree(dev->ibdev.iwcm); | 536 | kfree(dev->ibdev.iwcm); |
| 538 | dev->registered = 0; | ||
| 539 | return; | 537 | return; |
| 540 | } | 538 | } |
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 70a5a3c646da..3b773b05a898 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c | |||
| @@ -214,7 +214,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, | |||
| 214 | V_FW_RI_RES_WR_HOSTFCMODE(0) | /* no host cidx updates */ | 214 | V_FW_RI_RES_WR_HOSTFCMODE(0) | /* no host cidx updates */ |
| 215 | V_FW_RI_RES_WR_CPRIO(0) | /* don't keep in chip cache */ | 215 | V_FW_RI_RES_WR_CPRIO(0) | /* don't keep in chip cache */ |
| 216 | V_FW_RI_RES_WR_PCIECHN(0) | /* set by uP at ri_init time */ | 216 | V_FW_RI_RES_WR_PCIECHN(0) | /* set by uP at ri_init time */ |
| 217 | t4_sq_onchip(&wq->sq) ? F_FW_RI_RES_WR_ONCHIP : 0 | | 217 | (t4_sq_onchip(&wq->sq) ? F_FW_RI_RES_WR_ONCHIP : 0) | |
| 218 | V_FW_RI_RES_WR_IQID(scq->cqid)); | 218 | V_FW_RI_RES_WR_IQID(scq->cqid)); |
| 219 | res->u.sqrq.dcaen_to_eqsize = cpu_to_be32( | 219 | res->u.sqrq.dcaen_to_eqsize = cpu_to_be32( |
| 220 | V_FW_RI_RES_WR_DCAEN(0) | | 220 | V_FW_RI_RES_WR_DCAEN(0) | |
| @@ -1210,7 +1210,6 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, | |||
| 1210 | if (ret) { | 1210 | if (ret) { |
| 1211 | if (internal) | 1211 | if (internal) |
| 1212 | c4iw_get_ep(&qhp->ep->com); | 1212 | c4iw_get_ep(&qhp->ep->com); |
| 1213 | disconnect = abort = 1; | ||
| 1214 | goto err; | 1213 | goto err; |
| 1215 | } | 1214 | } |
| 1216 | break; | 1215 | break; |
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 58c0e417bc30..be24ac726114 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
| @@ -398,7 +398,6 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, | |||
| 398 | struct ipath_devdata *dd; | 398 | struct ipath_devdata *dd; |
| 399 | unsigned long long addr; | 399 | unsigned long long addr; |
| 400 | u32 bar0 = 0, bar1 = 0; | 400 | u32 bar0 = 0, bar1 = 0; |
| 401 | u8 rev; | ||
| 402 | 401 | ||
| 403 | dd = ipath_alloc_devdata(pdev); | 402 | dd = ipath_alloc_devdata(pdev); |
| 404 | if (IS_ERR(dd)) { | 403 | if (IS_ERR(dd)) { |
| @@ -540,13 +539,7 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, | |||
| 540 | goto bail_regions; | 539 | goto bail_regions; |
| 541 | } | 540 | } |
| 542 | 541 | ||
| 543 | ret = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); | 542 | dd->ipath_pcirev = pdev->revision; |
| 544 | if (ret) { | ||
| 545 | ipath_dev_err(dd, "Failed to read PCI revision ID unit " | ||
| 546 | "%u: err %d\n", dd->ipath_unit, -ret); | ||
| 547 | goto bail_regions; /* shouldn't ever happen */ | ||
| 548 | } | ||
| 549 | dd->ipath_pcirev = rev; | ||
| 550 | 543 | ||
| 551 | #if defined(__powerpc__) | 544 | #if defined(__powerpc__) |
| 552 | /* There isn't a generic way to specify writethrough mappings */ | 545 | /* There isn't a generic way to specify writethrough mappings */ |
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 33c7eedaba6c..e74cdf9ef471 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
| @@ -2563,7 +2563,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) | |||
| 2563 | u16 last_ae; | 2563 | u16 last_ae; |
| 2564 | u8 original_hw_tcp_state; | 2564 | u8 original_hw_tcp_state; |
| 2565 | u8 original_ibqp_state; | 2565 | u8 original_ibqp_state; |
| 2566 | enum iw_cm_event_status disconn_status = IW_CM_EVENT_STATUS_OK; | 2566 | int disconn_status = 0; |
| 2567 | int issue_disconn = 0; | 2567 | int issue_disconn = 0; |
| 2568 | int issue_close = 0; | 2568 | int issue_close = 0; |
| 2569 | int issue_flush = 0; | 2569 | int issue_flush = 0; |
| @@ -2605,7 +2605,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) | |||
| 2605 | (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) { | 2605 | (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) { |
| 2606 | issue_disconn = 1; | 2606 | issue_disconn = 1; |
| 2607 | if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) | 2607 | if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) |
| 2608 | disconn_status = IW_CM_EVENT_STATUS_RESET; | 2608 | disconn_status = -ECONNRESET; |
| 2609 | } | 2609 | } |
| 2610 | 2610 | ||
| 2611 | if (((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSED) || | 2611 | if (((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSED) || |
| @@ -2666,7 +2666,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) | |||
| 2666 | cm_id->provider_data = nesqp; | 2666 | cm_id->provider_data = nesqp; |
| 2667 | /* Send up the close complete event */ | 2667 | /* Send up the close complete event */ |
| 2668 | cm_event.event = IW_CM_EVENT_CLOSE; | 2668 | cm_event.event = IW_CM_EVENT_CLOSE; |
| 2669 | cm_event.status = IW_CM_EVENT_STATUS_OK; | 2669 | cm_event.status = 0; |
| 2670 | cm_event.provider_data = cm_id->provider_data; | 2670 | cm_event.provider_data = cm_id->provider_data; |
| 2671 | cm_event.local_addr = cm_id->local_addr; | 2671 | cm_event.local_addr = cm_id->local_addr; |
| 2672 | cm_event.remote_addr = cm_id->remote_addr; | 2672 | cm_event.remote_addr = cm_id->remote_addr; |
| @@ -2966,7 +2966,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
| 2966 | nes_add_ref(&nesqp->ibqp); | 2966 | nes_add_ref(&nesqp->ibqp); |
| 2967 | 2967 | ||
| 2968 | cm_event.event = IW_CM_EVENT_ESTABLISHED; | 2968 | cm_event.event = IW_CM_EVENT_ESTABLISHED; |
| 2969 | cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED; | 2969 | cm_event.status = 0; |
| 2970 | cm_event.provider_data = (void *)nesqp; | 2970 | cm_event.provider_data = (void *)nesqp; |
| 2971 | cm_event.local_addr = cm_id->local_addr; | 2971 | cm_event.local_addr = cm_id->local_addr; |
| 2972 | cm_event.remote_addr = cm_id->remote_addr; | 2972 | cm_event.remote_addr = cm_id->remote_addr; |
| @@ -3377,7 +3377,7 @@ static void cm_event_connected(struct nes_cm_event *event) | |||
| 3377 | 3377 | ||
| 3378 | /* notify OF layer we successfully created the requested connection */ | 3378 | /* notify OF layer we successfully created the requested connection */ |
| 3379 | cm_event.event = IW_CM_EVENT_CONNECT_REPLY; | 3379 | cm_event.event = IW_CM_EVENT_CONNECT_REPLY; |
| 3380 | cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED; | 3380 | cm_event.status = 0; |
| 3381 | cm_event.provider_data = cm_id->provider_data; | 3381 | cm_event.provider_data = cm_id->provider_data; |
| 3382 | cm_event.local_addr.sin_family = AF_INET; | 3382 | cm_event.local_addr.sin_family = AF_INET; |
| 3383 | cm_event.local_addr.sin_port = cm_id->local_addr.sin_port; | 3383 | cm_event.local_addr.sin_port = cm_id->local_addr.sin_port; |
| @@ -3484,7 +3484,7 @@ static void cm_event_reset(struct nes_cm_event *event) | |||
| 3484 | nesqp->cm_id = NULL; | 3484 | nesqp->cm_id = NULL; |
| 3485 | /* cm_id->provider_data = NULL; */ | 3485 | /* cm_id->provider_data = NULL; */ |
| 3486 | cm_event.event = IW_CM_EVENT_DISCONNECT; | 3486 | cm_event.event = IW_CM_EVENT_DISCONNECT; |
| 3487 | cm_event.status = IW_CM_EVENT_STATUS_RESET; | 3487 | cm_event.status = -ECONNRESET; |
| 3488 | cm_event.provider_data = cm_id->provider_data; | 3488 | cm_event.provider_data = cm_id->provider_data; |
| 3489 | cm_event.local_addr = cm_id->local_addr; | 3489 | cm_event.local_addr = cm_id->local_addr; |
| 3490 | cm_event.remote_addr = cm_id->remote_addr; | 3490 | cm_event.remote_addr = cm_id->remote_addr; |
| @@ -3495,7 +3495,7 @@ static void cm_event_reset(struct nes_cm_event *event) | |||
| 3495 | ret = cm_id->event_handler(cm_id, &cm_event); | 3495 | ret = cm_id->event_handler(cm_id, &cm_event); |
| 3496 | atomic_inc(&cm_closes); | 3496 | atomic_inc(&cm_closes); |
| 3497 | cm_event.event = IW_CM_EVENT_CLOSE; | 3497 | cm_event.event = IW_CM_EVENT_CLOSE; |
| 3498 | cm_event.status = IW_CM_EVENT_STATUS_OK; | 3498 | cm_event.status = 0; |
| 3499 | cm_event.provider_data = cm_id->provider_data; | 3499 | cm_event.provider_data = cm_id->provider_data; |
| 3500 | cm_event.local_addr = cm_id->local_addr; | 3500 | cm_event.local_addr = cm_id->local_addr; |
| 3501 | cm_event.remote_addr = cm_id->remote_addr; | 3501 | cm_event.remote_addr = cm_id->remote_addr; |
| @@ -3534,7 +3534,7 @@ static void cm_event_mpa_req(struct nes_cm_event *event) | |||
| 3534 | cm_node, cm_id, jiffies); | 3534 | cm_node, cm_id, jiffies); |
| 3535 | 3535 | ||
| 3536 | cm_event.event = IW_CM_EVENT_CONNECT_REQUEST; | 3536 | cm_event.event = IW_CM_EVENT_CONNECT_REQUEST; |
| 3537 | cm_event.status = IW_CM_EVENT_STATUS_OK; | 3537 | cm_event.status = 0; |
| 3538 | cm_event.provider_data = (void *)cm_node; | 3538 | cm_event.provider_data = (void *)cm_node; |
| 3539 | 3539 | ||
| 3540 | cm_event.local_addr.sin_family = AF_INET; | 3540 | cm_event.local_addr.sin_family = AF_INET; |
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 26d8018c0a7c..95ca93ceedac 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
| @@ -1484,7 +1484,7 @@ static int nes_destroy_qp(struct ib_qp *ibqp) | |||
| 1484 | (nesqp->ibqp_state == IB_QPS_RTR)) && (nesqp->cm_id)) { | 1484 | (nesqp->ibqp_state == IB_QPS_RTR)) && (nesqp->cm_id)) { |
| 1485 | cm_id = nesqp->cm_id; | 1485 | cm_id = nesqp->cm_id; |
| 1486 | cm_event.event = IW_CM_EVENT_CONNECT_REPLY; | 1486 | cm_event.event = IW_CM_EVENT_CONNECT_REPLY; |
| 1487 | cm_event.status = IW_CM_EVENT_STATUS_TIMEOUT; | 1487 | cm_event.status = -ETIMEDOUT; |
| 1488 | cm_event.local_addr = cm_id->local_addr; | 1488 | cm_event.local_addr = cm_id->local_addr; |
| 1489 | cm_event.remote_addr = cm_id->remote_addr; | 1489 | cm_event.remote_addr = cm_id->remote_addr; |
| 1490 | cm_event.private_data = NULL; | 1490 | cm_event.private_data = NULL; |
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 6bab3eaea70f..9f53e68a096a 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
| @@ -7534,7 +7534,8 @@ static int serdes_7322_init_new(struct qib_pportdata *ppd) | |||
| 7534 | ibsd_wr_allchans(ppd, 4, (1 << 10), BMASK(10, 10)); | 7534 | ibsd_wr_allchans(ppd, 4, (1 << 10), BMASK(10, 10)); |
| 7535 | tstart = get_jiffies_64(); | 7535 | tstart = get_jiffies_64(); |
| 7536 | while (chan_done && | 7536 | while (chan_done && |
| 7537 | !time_after64(tstart, tstart + msecs_to_jiffies(500))) { | 7537 | !time_after64(get_jiffies_64(), |
| 7538 | tstart + msecs_to_jiffies(500))) { | ||
| 7538 | msleep(20); | 7539 | msleep(20); |
| 7539 | for (chan = 0; chan < SERDES_CHANS; ++chan) { | 7540 | for (chan = 0; chan < SERDES_CHANS; ++chan) { |
| 7540 | rxcaldone = ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), | 7541 | rxcaldone = ahb_mod(ppd->dd, IBSD(ppd->hw_pidx), |
diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c index 48b6674cbc49..891cc2ff5f00 100644 --- a/drivers/infiniband/hw/qib/qib_pcie.c +++ b/drivers/infiniband/hw/qib/qib_pcie.c | |||
| @@ -526,11 +526,8 @@ static int qib_tune_pcie_coalesce(struct qib_devdata *dd) | |||
| 526 | */ | 526 | */ |
| 527 | devid = parent->device; | 527 | devid = parent->device; |
| 528 | if (devid >= 0x25e2 && devid <= 0x25fa) { | 528 | if (devid >= 0x25e2 && devid <= 0x25fa) { |
| 529 | u8 rev; | ||
| 530 | |||
| 531 | /* 5000 P/V/X/Z */ | 529 | /* 5000 P/V/X/Z */ |
| 532 | pci_read_config_byte(parent, PCI_REVISION_ID, &rev); | 530 | if (parent->revision <= 0xb2) |
| 533 | if (rev <= 0xb2) | ||
| 534 | bits = 1U << 10; | 531 | bits = 1U << 10; |
| 535 | else | 532 | else |
| 536 | bits = 7U << 10; | 533 | bits = 7U << 10; |
diff --git a/include/rdma/iw_cm.h b/include/rdma/iw_cm.h index cbb822e8d791..2d0191c90f9e 100644 --- a/include/rdma/iw_cm.h +++ b/include/rdma/iw_cm.h | |||
| @@ -46,18 +46,9 @@ enum iw_cm_event_type { | |||
| 46 | IW_CM_EVENT_CLOSE /* close complete */ | 46 | IW_CM_EVENT_CLOSE /* close complete */ |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | enum iw_cm_event_status { | ||
| 50 | IW_CM_EVENT_STATUS_OK = 0, /* request successful */ | ||
| 51 | IW_CM_EVENT_STATUS_ACCEPTED = 0, /* connect request accepted */ | ||
| 52 | IW_CM_EVENT_STATUS_REJECTED, /* connect request rejected */ | ||
| 53 | IW_CM_EVENT_STATUS_TIMEOUT, /* the operation timed out */ | ||
| 54 | IW_CM_EVENT_STATUS_RESET, /* reset from remote peer */ | ||
| 55 | IW_CM_EVENT_STATUS_EINVAL, /* asynchronous failure for bad parm */ | ||
| 56 | }; | ||
| 57 | |||
| 58 | struct iw_cm_event { | 49 | struct iw_cm_event { |
| 59 | enum iw_cm_event_type event; | 50 | enum iw_cm_event_type event; |
| 60 | enum iw_cm_event_status status; | 51 | int status; |
| 61 | struct sockaddr_in local_addr; | 52 | struct sockaddr_in local_addr; |
| 62 | struct sockaddr_in remote_addr; | 53 | struct sockaddr_in remote_addr; |
| 63 | void *private_data; | 54 | void *private_data; |
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h index 4fae90304648..169f7a53fb0c 100644 --- a/include/rdma/rdma_cm.h +++ b/include/rdma/rdma_cm.h | |||
| @@ -329,4 +329,14 @@ void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr); | |||
| 329 | */ | 329 | */ |
| 330 | void rdma_set_service_type(struct rdma_cm_id *id, int tos); | 330 | void rdma_set_service_type(struct rdma_cm_id *id, int tos); |
| 331 | 331 | ||
| 332 | /** | ||
| 333 | * rdma_set_reuseaddr - Allow the reuse of local addresses when binding | ||
| 334 | * the rdma_cm_id. | ||
| 335 | * @id: Communication identifier to configure. | ||
| 336 | * @reuse: Value indicating if the bound address is reusable. | ||
| 337 | * | ||
| 338 | * Reuse must be set before an address is bound to the id. | ||
| 339 | */ | ||
| 340 | int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse); | ||
| 341 | |||
| 332 | #endif /* RDMA_CM_H */ | 342 | #endif /* RDMA_CM_H */ |
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h index 1d165022c02d..fc82c1896f75 100644 --- a/include/rdma/rdma_user_cm.h +++ b/include/rdma/rdma_user_cm.h | |||
| @@ -221,8 +221,9 @@ enum { | |||
| 221 | 221 | ||
| 222 | /* Option details */ | 222 | /* Option details */ |
| 223 | enum { | 223 | enum { |
| 224 | RDMA_OPTION_ID_TOS = 0, | 224 | RDMA_OPTION_ID_TOS = 0, |
| 225 | RDMA_OPTION_IB_PATH = 1 | 225 | RDMA_OPTION_ID_REUSEADDR = 1, |
| 226 | RDMA_OPTION_IB_PATH = 1 | ||
| 226 | }; | 227 | }; |
| 227 | 228 | ||
| 228 | struct rdma_ucm_set_option { | 229 | struct rdma_ucm_set_option { |
