diff options
Diffstat (limited to 'drivers/infiniband/hw/cxgb3/iwch_cm.c')
-rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_cm.c | 173 |
1 files changed, 118 insertions, 55 deletions
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 72ca360c3dbc..c325c44807e8 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
@@ -63,10 +63,14 @@ static char *states[] = { | |||
63 | NULL, | 63 | NULL, |
64 | }; | 64 | }; |
65 | 65 | ||
66 | static int ep_timeout_secs = 10; | 66 | int peer2peer = 0; |
67 | module_param(peer2peer, int, 0644); | ||
68 | MODULE_PARM_DESC(peer2peer, "Support peer2peer ULPs (default=0)"); | ||
69 | |||
70 | static int ep_timeout_secs = 60; | ||
67 | module_param(ep_timeout_secs, int, 0644); | 71 | module_param(ep_timeout_secs, int, 0644); |
68 | MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout " | 72 | MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout " |
69 | "in seconds (default=10)"); | 73 | "in seconds (default=60)"); |
70 | 74 | ||
71 | static int mpa_rev = 1; | 75 | static int mpa_rev = 1; |
72 | module_param(mpa_rev, int, 0644); | 76 | module_param(mpa_rev, int, 0644); |
@@ -125,6 +129,12 @@ static void start_ep_timer(struct iwch_ep *ep) | |||
125 | static void stop_ep_timer(struct iwch_ep *ep) | 129 | static void stop_ep_timer(struct iwch_ep *ep) |
126 | { | 130 | { |
127 | PDBG("%s ep %p\n", __func__, ep); | 131 | PDBG("%s ep %p\n", __func__, ep); |
132 | if (!timer_pending(&ep->timer)) { | ||
133 | printk(KERN_ERR "%s timer stopped when its not running! ep %p state %u\n", | ||
134 | __func__, ep, ep->com.state); | ||
135 | WARN_ON(1); | ||
136 | return; | ||
137 | } | ||
128 | del_timer_sync(&ep->timer); | 138 | del_timer_sync(&ep->timer); |
129 | put_ep(&ep->com); | 139 | put_ep(&ep->com); |
130 | } | 140 | } |
@@ -508,7 +518,7 @@ static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb) | |||
508 | skb_reset_transport_header(skb); | 518 | skb_reset_transport_header(skb); |
509 | len = skb->len; | 519 | len = skb->len; |
510 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); | 520 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); |
511 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); | 521 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)|F_WR_COMPL); |
512 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); | 522 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); |
513 | req->len = htonl(len); | 523 | req->len = htonl(len); |
514 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | | 524 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | |
@@ -559,7 +569,7 @@ static int send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen) | |||
559 | set_arp_failure_handler(skb, arp_failure_discard); | 569 | set_arp_failure_handler(skb, arp_failure_discard); |
560 | skb_reset_transport_header(skb); | 570 | skb_reset_transport_header(skb); |
561 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); | 571 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); |
562 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); | 572 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)|F_WR_COMPL); |
563 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); | 573 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); |
564 | req->len = htonl(mpalen); | 574 | req->len = htonl(mpalen); |
565 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | | 575 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | |
@@ -611,7 +621,7 @@ static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen) | |||
611 | skb_reset_transport_header(skb); | 621 | skb_reset_transport_header(skb); |
612 | len = skb->len; | 622 | len = skb->len; |
613 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); | 623 | req = (struct tx_data_wr *) skb_push(skb, sizeof(*req)); |
614 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)); | 624 | req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA)|F_WR_COMPL); |
615 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); | 625 | req->wr_lo = htonl(V_WR_TID(ep->hwtid)); |
616 | req->len = htonl(len); | 626 | req->len = htonl(len); |
617 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | | 627 | req->param = htonl(V_TX_PORT(ep->l2t->smt_idx) | |
@@ -879,6 +889,7 @@ static void process_mpa_reply(struct iwch_ep *ep, struct sk_buff *skb) | |||
879 | * the MPA header is valid. | 889 | * the MPA header is valid. |
880 | */ | 890 | */ |
881 | state_set(&ep->com, FPDU_MODE); | 891 | state_set(&ep->com, FPDU_MODE); |
892 | ep->mpa_attr.initiator = 1; | ||
882 | ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; | 893 | ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; |
883 | ep->mpa_attr.recv_marker_enabled = markers_enabled; | 894 | ep->mpa_attr.recv_marker_enabled = markers_enabled; |
884 | ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; | 895 | ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; |
@@ -901,8 +912,14 @@ static void process_mpa_reply(struct iwch_ep *ep, struct sk_buff *skb) | |||
901 | /* bind QP and TID with INIT_WR */ | 912 | /* bind QP and TID with INIT_WR */ |
902 | err = iwch_modify_qp(ep->com.qp->rhp, | 913 | err = iwch_modify_qp(ep->com.qp->rhp, |
903 | ep->com.qp, mask, &attrs, 1); | 914 | ep->com.qp, mask, &attrs, 1); |
904 | if (!err) | 915 | if (err) |
905 | goto out; | 916 | goto err; |
917 | |||
918 | if (peer2peer && iwch_rqes_posted(ep->com.qp) == 0) { | ||
919 | iwch_post_zb_read(ep->com.qp); | ||
920 | } | ||
921 | |||
922 | goto out; | ||
906 | err: | 923 | err: |
907 | abort_connection(ep, skb, GFP_KERNEL); | 924 | abort_connection(ep, skb, GFP_KERNEL); |
908 | out: | 925 | out: |
@@ -995,6 +1012,7 @@ static void process_mpa_request(struct iwch_ep *ep, struct sk_buff *skb) | |||
995 | * If we get here we have accumulated the entire mpa | 1012 | * If we get here we have accumulated the entire mpa |
996 | * start reply message including private data. | 1013 | * start reply message including private data. |
997 | */ | 1014 | */ |
1015 | ep->mpa_attr.initiator = 0; | ||
998 | ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; | 1016 | ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0; |
999 | ep->mpa_attr.recv_marker_enabled = markers_enabled; | 1017 | ep->mpa_attr.recv_marker_enabled = markers_enabled; |
1000 | ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; | 1018 | ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0; |
@@ -1065,17 +1083,33 @@ static int tx_ack(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1065 | 1083 | ||
1066 | PDBG("%s ep %p credits %u\n", __func__, ep, credits); | 1084 | PDBG("%s ep %p credits %u\n", __func__, ep, credits); |
1067 | 1085 | ||
1068 | if (credits == 0) | 1086 | if (credits == 0) { |
1087 | PDBG(KERN_ERR "%s 0 credit ack ep %p state %u\n", | ||
1088 | __func__, ep, state_read(&ep->com)); | ||
1069 | return CPL_RET_BUF_DONE; | 1089 | return CPL_RET_BUF_DONE; |
1090 | } | ||
1091 | |||
1070 | BUG_ON(credits != 1); | 1092 | BUG_ON(credits != 1); |
1071 | BUG_ON(ep->mpa_skb == NULL); | ||
1072 | kfree_skb(ep->mpa_skb); | ||
1073 | ep->mpa_skb = NULL; | ||
1074 | dst_confirm(ep->dst); | 1093 | dst_confirm(ep->dst); |
1075 | if (state_read(&ep->com) == MPA_REP_SENT) { | 1094 | if (!ep->mpa_skb) { |
1076 | ep->com.rpl_done = 1; | 1095 | PDBG("%s rdma_init wr_ack ep %p state %u\n", |
1077 | PDBG("waking up ep %p\n", ep); | 1096 | __func__, ep, state_read(&ep->com)); |
1078 | wake_up(&ep->com.waitq); | 1097 | if (ep->mpa_attr.initiator) { |
1098 | PDBG("%s initiator ep %p state %u\n", | ||
1099 | __func__, ep, state_read(&ep->com)); | ||
1100 | if (peer2peer) | ||
1101 | iwch_post_zb_read(ep->com.qp); | ||
1102 | } else { | ||
1103 | PDBG("%s responder ep %p state %u\n", | ||
1104 | __func__, ep, state_read(&ep->com)); | ||
1105 | ep->com.rpl_done = 1; | ||
1106 | wake_up(&ep->com.waitq); | ||
1107 | } | ||
1108 | } else { | ||
1109 | PDBG("%s lsm ack ep %p state %u freeing skb\n", | ||
1110 | __func__, ep, state_read(&ep->com)); | ||
1111 | kfree_skb(ep->mpa_skb); | ||
1112 | ep->mpa_skb = NULL; | ||
1079 | } | 1113 | } |
1080 | return CPL_RET_BUF_DONE; | 1114 | return CPL_RET_BUF_DONE; |
1081 | } | 1115 | } |
@@ -1083,8 +1117,11 @@ static int tx_ack(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1083 | static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | 1117 | static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) |
1084 | { | 1118 | { |
1085 | struct iwch_ep *ep = ctx; | 1119 | struct iwch_ep *ep = ctx; |
1120 | unsigned long flags; | ||
1121 | int release = 0; | ||
1086 | 1122 | ||
1087 | PDBG("%s ep %p\n", __func__, ep); | 1123 | PDBG("%s ep %p\n", __func__, ep); |
1124 | BUG_ON(!ep); | ||
1088 | 1125 | ||
1089 | /* | 1126 | /* |
1090 | * We get 2 abort replies from the HW. The first one must | 1127 | * We get 2 abort replies from the HW. The first one must |
@@ -1095,9 +1132,22 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1095 | return CPL_RET_BUF_DONE; | 1132 | return CPL_RET_BUF_DONE; |
1096 | } | 1133 | } |
1097 | 1134 | ||
1098 | close_complete_upcall(ep); | 1135 | spin_lock_irqsave(&ep->com.lock, flags); |
1099 | state_set(&ep->com, DEAD); | 1136 | switch (ep->com.state) { |
1100 | release_ep_resources(ep); | 1137 | case ABORTING: |
1138 | close_complete_upcall(ep); | ||
1139 | __state_set(&ep->com, DEAD); | ||
1140 | release = 1; | ||
1141 | break; | ||
1142 | default: | ||
1143 | printk(KERN_ERR "%s ep %p state %d\n", | ||
1144 | __func__, ep, ep->com.state); | ||
1145 | break; | ||
1146 | } | ||
1147 | spin_unlock_irqrestore(&ep->com.lock, flags); | ||
1148 | |||
1149 | if (release) | ||
1150 | release_ep_resources(ep); | ||
1101 | return CPL_RET_BUF_DONE; | 1151 | return CPL_RET_BUF_DONE; |
1102 | } | 1152 | } |
1103 | 1153 | ||
@@ -1470,7 +1520,8 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1470 | struct sk_buff *rpl_skb; | 1520 | struct sk_buff *rpl_skb; |
1471 | struct iwch_qp_attributes attrs; | 1521 | struct iwch_qp_attributes attrs; |
1472 | int ret; | 1522 | int ret; |
1473 | int state; | 1523 | int release = 0; |
1524 | unsigned long flags; | ||
1474 | 1525 | ||
1475 | if (is_neg_adv_abort(req->status)) { | 1526 | if (is_neg_adv_abort(req->status)) { |
1476 | PDBG("%s neg_adv_abort ep %p tid %d\n", __func__, ep, | 1527 | PDBG("%s neg_adv_abort ep %p tid %d\n", __func__, ep, |
@@ -1488,9 +1539,9 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1488 | return CPL_RET_BUF_DONE; | 1539 | return CPL_RET_BUF_DONE; |
1489 | } | 1540 | } |
1490 | 1541 | ||
1491 | state = state_read(&ep->com); | 1542 | spin_lock_irqsave(&ep->com.lock, flags); |
1492 | PDBG("%s ep %p state %u\n", __func__, ep, state); | 1543 | PDBG("%s ep %p state %u\n", __func__, ep, ep->com.state); |
1493 | switch (state) { | 1544 | switch (ep->com.state) { |
1494 | case CONNECTING: | 1545 | case CONNECTING: |
1495 | break; | 1546 | break; |
1496 | case MPA_REQ_WAIT: | 1547 | case MPA_REQ_WAIT: |
@@ -1536,21 +1587,25 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1536 | break; | 1587 | break; |
1537 | case DEAD: | 1588 | case DEAD: |
1538 | PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__); | 1589 | PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__); |
1590 | spin_unlock_irqrestore(&ep->com.lock, flags); | ||
1539 | return CPL_RET_BUF_DONE; | 1591 | return CPL_RET_BUF_DONE; |
1540 | default: | 1592 | default: |
1541 | BUG_ON(1); | 1593 | BUG_ON(1); |
1542 | break; | 1594 | break; |
1543 | } | 1595 | } |
1544 | dst_confirm(ep->dst); | 1596 | dst_confirm(ep->dst); |
1597 | if (ep->com.state != ABORTING) { | ||
1598 | __state_set(&ep->com, DEAD); | ||
1599 | release = 1; | ||
1600 | } | ||
1601 | spin_unlock_irqrestore(&ep->com.lock, flags); | ||
1545 | 1602 | ||
1546 | rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL); | 1603 | rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL); |
1547 | if (!rpl_skb) { | 1604 | if (!rpl_skb) { |
1548 | printk(KERN_ERR MOD "%s - cannot allocate skb!\n", | 1605 | printk(KERN_ERR MOD "%s - cannot allocate skb!\n", |
1549 | __func__); | 1606 | __func__); |
1550 | dst_release(ep->dst); | 1607 | release = 1; |
1551 | l2t_release(L2DATA(ep->com.tdev), ep->l2t); | 1608 | goto out; |
1552 | put_ep(&ep->com); | ||
1553 | return CPL_RET_BUF_DONE; | ||
1554 | } | 1609 | } |
1555 | rpl_skb->priority = CPL_PRIORITY_DATA; | 1610 | rpl_skb->priority = CPL_PRIORITY_DATA; |
1556 | rpl = (struct cpl_abort_rpl *) skb_put(rpl_skb, sizeof(*rpl)); | 1611 | rpl = (struct cpl_abort_rpl *) skb_put(rpl_skb, sizeof(*rpl)); |
@@ -1559,10 +1614,9 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1559 | OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); | 1614 | OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); |
1560 | rpl->cmd = CPL_ABORT_NO_RST; | 1615 | rpl->cmd = CPL_ABORT_NO_RST; |
1561 | cxgb3_ofld_send(ep->com.tdev, rpl_skb); | 1616 | cxgb3_ofld_send(ep->com.tdev, rpl_skb); |
1562 | if (state != ABORTING) { | 1617 | out: |
1563 | state_set(&ep->com, DEAD); | 1618 | if (release) |
1564 | release_ep_resources(ep); | 1619 | release_ep_resources(ep); |
1565 | } | ||
1566 | return CPL_RET_BUF_DONE; | 1620 | return CPL_RET_BUF_DONE; |
1567 | } | 1621 | } |
1568 | 1622 | ||
@@ -1596,8 +1650,8 @@ static int close_con_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1596 | release = 1; | 1650 | release = 1; |
1597 | break; | 1651 | break; |
1598 | case ABORTING: | 1652 | case ABORTING: |
1599 | break; | ||
1600 | case DEAD: | 1653 | case DEAD: |
1654 | break; | ||
1601 | default: | 1655 | default: |
1602 | BUG_ON(1); | 1656 | BUG_ON(1); |
1603 | break; | 1657 | break; |
@@ -1661,15 +1715,18 @@ static void ep_timeout(unsigned long arg) | |||
1661 | struct iwch_ep *ep = (struct iwch_ep *)arg; | 1715 | struct iwch_ep *ep = (struct iwch_ep *)arg; |
1662 | struct iwch_qp_attributes attrs; | 1716 | struct iwch_qp_attributes attrs; |
1663 | unsigned long flags; | 1717 | unsigned long flags; |
1718 | int abort = 1; | ||
1664 | 1719 | ||
1665 | spin_lock_irqsave(&ep->com.lock, flags); | 1720 | spin_lock_irqsave(&ep->com.lock, flags); |
1666 | PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid, | 1721 | PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid, |
1667 | ep->com.state); | 1722 | ep->com.state); |
1668 | switch (ep->com.state) { | 1723 | switch (ep->com.state) { |
1669 | case MPA_REQ_SENT: | 1724 | case MPA_REQ_SENT: |
1725 | __state_set(&ep->com, ABORTING); | ||
1670 | connect_reply_upcall(ep, -ETIMEDOUT); | 1726 | connect_reply_upcall(ep, -ETIMEDOUT); |
1671 | break; | 1727 | break; |
1672 | case MPA_REQ_WAIT: | 1728 | case MPA_REQ_WAIT: |
1729 | __state_set(&ep->com, ABORTING); | ||
1673 | break; | 1730 | break; |
1674 | case CLOSING: | 1731 | case CLOSING: |
1675 | case MORIBUND: | 1732 | case MORIBUND: |
@@ -1679,13 +1736,17 @@ static void ep_timeout(unsigned long arg) | |||
1679 | ep->com.qp, IWCH_QP_ATTR_NEXT_STATE, | 1736 | ep->com.qp, IWCH_QP_ATTR_NEXT_STATE, |
1680 | &attrs, 1); | 1737 | &attrs, 1); |
1681 | } | 1738 | } |
1739 | __state_set(&ep->com, ABORTING); | ||
1682 | break; | 1740 | break; |
1683 | default: | 1741 | default: |
1684 | BUG(); | 1742 | printk(KERN_ERR "%s unexpected state ep %p state %u\n", |
1743 | __func__, ep, ep->com.state); | ||
1744 | WARN_ON(1); | ||
1745 | abort = 0; | ||
1685 | } | 1746 | } |
1686 | __state_set(&ep->com, CLOSING); | ||
1687 | spin_unlock_irqrestore(&ep->com.lock, flags); | 1747 | spin_unlock_irqrestore(&ep->com.lock, flags); |
1688 | abort_connection(ep, NULL, GFP_ATOMIC); | 1748 | if (abort) |
1749 | abort_connection(ep, NULL, GFP_ATOMIC); | ||
1689 | put_ep(&ep->com); | 1750 | put_ep(&ep->com); |
1690 | } | 1751 | } |
1691 | 1752 | ||
@@ -1762,16 +1823,19 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
1762 | if (err) | 1823 | if (err) |
1763 | goto err; | 1824 | goto err; |
1764 | 1825 | ||
1826 | /* if needed, wait for wr_ack */ | ||
1827 | if (iwch_rqes_posted(qp)) { | ||
1828 | wait_event(ep->com.waitq, ep->com.rpl_done); | ||
1829 | err = ep->com.rpl_err; | ||
1830 | if (err) | ||
1831 | goto err; | ||
1832 | } | ||
1833 | |||
1765 | err = send_mpa_reply(ep, conn_param->private_data, | 1834 | err = send_mpa_reply(ep, conn_param->private_data, |
1766 | conn_param->private_data_len); | 1835 | conn_param->private_data_len); |
1767 | if (err) | 1836 | if (err) |
1768 | goto err; | 1837 | goto err; |
1769 | 1838 | ||
1770 | /* wait for wr_ack */ | ||
1771 | wait_event(ep->com.waitq, ep->com.rpl_done); | ||
1772 | err = ep->com.rpl_err; | ||
1773 | if (err) | ||
1774 | goto err; | ||
1775 | 1839 | ||
1776 | state_set(&ep->com, FPDU_MODE); | 1840 | state_set(&ep->com, FPDU_MODE); |
1777 | established_upcall(ep); | 1841 | established_upcall(ep); |
@@ -1968,40 +2032,39 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp) | |||
1968 | PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, | 2032 | PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep, |
1969 | states[ep->com.state], abrupt); | 2033 | states[ep->com.state], abrupt); |
1970 | 2034 | ||
1971 | if (ep->com.state == DEAD) { | ||
1972 | PDBG("%s already dead ep %p\n", __func__, ep); | ||
1973 | goto out; | ||
1974 | } | ||
1975 | |||
1976 | if (abrupt) { | ||
1977 | if (ep->com.state != ABORTING) { | ||
1978 | ep->com.state = ABORTING; | ||
1979 | close = 1; | ||
1980 | } | ||
1981 | goto out; | ||
1982 | } | ||
1983 | |||
1984 | switch (ep->com.state) { | 2035 | switch (ep->com.state) { |
1985 | case MPA_REQ_WAIT: | 2036 | case MPA_REQ_WAIT: |
1986 | case MPA_REQ_SENT: | 2037 | case MPA_REQ_SENT: |
1987 | case MPA_REQ_RCVD: | 2038 | case MPA_REQ_RCVD: |
1988 | case MPA_REP_SENT: | 2039 | case MPA_REP_SENT: |
1989 | case FPDU_MODE: | 2040 | case FPDU_MODE: |
1990 | start_ep_timer(ep); | ||
1991 | ep->com.state = CLOSING; | ||
1992 | close = 1; | 2041 | close = 1; |
2042 | if (abrupt) | ||
2043 | ep->com.state = ABORTING; | ||
2044 | else { | ||
2045 | ep->com.state = CLOSING; | ||
2046 | start_ep_timer(ep); | ||
2047 | } | ||
1993 | break; | 2048 | break; |
1994 | case CLOSING: | 2049 | case CLOSING: |
1995 | ep->com.state = MORIBUND; | ||
1996 | close = 1; | 2050 | close = 1; |
2051 | if (abrupt) { | ||
2052 | stop_ep_timer(ep); | ||
2053 | ep->com.state = ABORTING; | ||
2054 | } else | ||
2055 | ep->com.state = MORIBUND; | ||
1997 | break; | 2056 | break; |
1998 | case MORIBUND: | 2057 | case MORIBUND: |
2058 | case ABORTING: | ||
2059 | case DEAD: | ||
2060 | PDBG("%s ignoring disconnect ep %p state %u\n", | ||
2061 | __func__, ep, ep->com.state); | ||
1999 | break; | 2062 | break; |
2000 | default: | 2063 | default: |
2001 | BUG(); | 2064 | BUG(); |
2002 | break; | 2065 | break; |
2003 | } | 2066 | } |
2004 | out: | 2067 | |
2005 | spin_unlock_irqrestore(&ep->com.lock, flags); | 2068 | spin_unlock_irqrestore(&ep->com.lock, flags); |
2006 | if (close) { | 2069 | if (close) { |
2007 | if (abrupt) | 2070 | if (abrupt) |