aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ehca
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2008-07-11 09:36:25 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-07-11 09:36:25 -0400
commita8931ef380c92d121ae74ecfb03b2d63f72eea6f (patch)
tree980fb6b019e11e6cb1ece55b7faff184721a8053 /drivers/infiniband/hw/ehca
parent90574d0a4d4b73308ae54a2a57a4f3f1fa98e984 (diff)
parente5a5816f7875207cb0a0a7032e39a4686c5e10a4 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/infiniband/hw/ehca')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_hca.c7
-rw-r--r--drivers/infiniband/hw/ehca/ehca_irq.c4
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c5
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c6
5 files changed, 18 insertions, 6 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 00bab60f6de4..1e9e99a13933 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -192,6 +192,8 @@ struct ehca_qp {
192 int mtu_shift; 192 int mtu_shift;
193 u32 message_count; 193 u32 message_count;
194 u32 packet_count; 194 u32 packet_count;
195 atomic_t nr_events; /* events seen */
196 wait_queue_head_t wait_completion;
195}; 197};
196 198
197#define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ) 199#define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ)
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index 2515cbde7e65..bc3b37d2070f 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -101,7 +101,6 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
101 props->max_ee = limit_uint(rblock->max_rd_ee_context); 101 props->max_ee = limit_uint(rblock->max_rd_ee_context);
102 props->max_rdd = limit_uint(rblock->max_rd_domain); 102 props->max_rdd = limit_uint(rblock->max_rd_domain);
103 props->max_fmr = limit_uint(rblock->max_mr); 103 props->max_fmr = limit_uint(rblock->max_mr);
104 props->local_ca_ack_delay = limit_uint(rblock->local_ca_ack_delay);
105 props->max_qp_rd_atom = limit_uint(rblock->max_rr_qp); 104 props->max_qp_rd_atom = limit_uint(rblock->max_rr_qp);
106 props->max_ee_rd_atom = limit_uint(rblock->max_rr_ee_context); 105 props->max_ee_rd_atom = limit_uint(rblock->max_rr_ee_context);
107 props->max_res_rd_atom = limit_uint(rblock->max_rr_hca); 106 props->max_res_rd_atom = limit_uint(rblock->max_rr_hca);
@@ -115,7 +114,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
115 } 114 }
116 115
117 props->max_pkeys = 16; 116 props->max_pkeys = 16;
118 props->local_ca_ack_delay = limit_uint(rblock->local_ca_ack_delay); 117 props->local_ca_ack_delay = min_t(u8, rblock->local_ca_ack_delay, 255);
119 props->max_raw_ipv6_qp = limit_uint(rblock->max_raw_ipv6_qp); 118 props->max_raw_ipv6_qp = limit_uint(rblock->max_raw_ipv6_qp);
120 props->max_raw_ethy_qp = limit_uint(rblock->max_raw_ethy_qp); 119 props->max_raw_ethy_qp = limit_uint(rblock->max_raw_ethy_qp);
121 props->max_mcast_grp = limit_uint(rblock->max_mcast_grp); 120 props->max_mcast_grp = limit_uint(rblock->max_mcast_grp);
@@ -136,7 +135,7 @@ query_device1:
136 return ret; 135 return ret;
137} 136}
138 137
139static int map_mtu(struct ehca_shca *shca, u32 fw_mtu) 138static enum ib_mtu map_mtu(struct ehca_shca *shca, u32 fw_mtu)
140{ 139{
141 switch (fw_mtu) { 140 switch (fw_mtu) {
142 case 0x1: 141 case 0x1:
@@ -156,7 +155,7 @@ static int map_mtu(struct ehca_shca *shca, u32 fw_mtu)
156 } 155 }
157} 156}
158 157
159static int map_number_of_vls(struct ehca_shca *shca, u32 vl_cap) 158static u8 map_number_of_vls(struct ehca_shca *shca, u32 vl_cap)
160{ 159{
161 switch (vl_cap) { 160 switch (vl_cap) {
162 case 0x1: 161 case 0x1:
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index ca5eb0cb628c..ce1ab0571be3 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -204,6 +204,8 @@ static void qp_event_callback(struct ehca_shca *shca, u64 eqe,
204 204
205 read_lock(&ehca_qp_idr_lock); 205 read_lock(&ehca_qp_idr_lock);
206 qp = idr_find(&ehca_qp_idr, token); 206 qp = idr_find(&ehca_qp_idr, token);
207 if (qp)
208 atomic_inc(&qp->nr_events);
207 read_unlock(&ehca_qp_idr_lock); 209 read_unlock(&ehca_qp_idr_lock);
208 210
209 if (!qp) 211 if (!qp)
@@ -223,6 +225,8 @@ static void qp_event_callback(struct ehca_shca *shca, u64 eqe,
223 if (fatal && qp->ext_type == EQPT_SRQBASE) 225 if (fatal && qp->ext_type == EQPT_SRQBASE)
224 dispatch_qp_event(shca, qp, IB_EVENT_QP_LAST_WQE_REACHED); 226 dispatch_qp_event(shca, qp, IB_EVENT_QP_LAST_WQE_REACHED);
225 227
228 if (atomic_dec_and_test(&qp->nr_events))
229 wake_up(&qp->wait_completion);
226 return; 230 return;
227} 231}
228 232
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 18fba92fa7ae..3f59587338ea 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -566,6 +566,8 @@ static struct ehca_qp *internal_create_qp(
566 return ERR_PTR(-ENOMEM); 566 return ERR_PTR(-ENOMEM);
567 } 567 }
568 568
569 atomic_set(&my_qp->nr_events, 0);
570 init_waitqueue_head(&my_qp->wait_completion);
569 spin_lock_init(&my_qp->spinlock_s); 571 spin_lock_init(&my_qp->spinlock_s);
570 spin_lock_init(&my_qp->spinlock_r); 572 spin_lock_init(&my_qp->spinlock_r);
571 my_qp->qp_type = qp_type; 573 my_qp->qp_type = qp_type;
@@ -1934,6 +1936,9 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp,
1934 idr_remove(&ehca_qp_idr, my_qp->token); 1936 idr_remove(&ehca_qp_idr, my_qp->token);
1935 write_unlock_irqrestore(&ehca_qp_idr_lock, flags); 1937 write_unlock_irqrestore(&ehca_qp_idr_lock, flags);
1936 1938
1939 /* now wait until all pending events have completed */
1940 wait_event(my_qp->wait_completion, !atomic_read(&my_qp->nr_events));
1941
1937 h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp); 1942 h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp);
1938 if (h_ret != H_SUCCESS) { 1943 if (h_ret != H_SUCCESS) {
1939 ehca_err(dev, "hipz_h_destroy_qp() failed h_ret=%li " 1944 ehca_err(dev, "hipz_h_destroy_qp() failed h_ret=%li "
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index bbe0436f4f75..f093b0033daf 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -421,8 +421,10 @@ int ehca_post_send(struct ib_qp *qp,
421 int ret = 0; 421 int ret = 0;
422 unsigned long flags; 422 unsigned long flags;
423 423
424 if (unlikely(my_qp->state != IB_QPS_RTS)) { 424 /* Reject WR if QP is in RESET, INIT or RTR state */
425 ehca_err(qp->device, "QP not in RTS state qpn=%x", qp->qp_num); 425 if (unlikely(my_qp->state < IB_QPS_RTS)) {
426 ehca_err(qp->device, "Invalid QP state qp_state=%d qpn=%x",
427 my_qp->state, qp->qp_num);
426 return -EINVAL; 428 return -EINVAL;
427 } 429 }
428 430