diff options
author | Robert Walsh <robert.walsh@qlogic.com> | 2007-03-15 17:45:17 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-04-18 23:21:01 -0400 |
commit | 40b90430ecac40cc9adb26b808cc12a3d569da5d (patch) | |
tree | 4c87d4b4d3c4f270a0371fdd66b02d78ac8ce306 /drivers/infiniband | |
parent | 6ce73b07db7aa05d4a30716d6a99c832b6d9db4a (diff) |
IB/ipath: Fix WC format drift between user and kernel space
The kernel ib_wc structure now uses a QP pointer, but the user space
equivalent uses a QP number instead. This means we can no longer use
a simple structure copy to copy stuff into user space.
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_cq.c | 38 | ||||
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_verbs.h | 3 |
2 files changed, 38 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c index 87462e0cb4d2..ea78e6dddc90 100644 --- a/drivers/infiniband/hw/ipath/ipath_cq.c +++ b/drivers/infiniband/hw/ipath/ipath_cq.c | |||
@@ -76,7 +76,20 @@ void ipath_cq_enter(struct ipath_cq *cq, struct ib_wc *entry, int solicited) | |||
76 | } | 76 | } |
77 | return; | 77 | return; |
78 | } | 78 | } |
79 | wc->queue[head] = *entry; | 79 | wc->queue[head].wr_id = entry->wr_id; |
80 | wc->queue[head].status = entry->status; | ||
81 | wc->queue[head].opcode = entry->opcode; | ||
82 | wc->queue[head].vendor_err = entry->vendor_err; | ||
83 | wc->queue[head].byte_len = entry->byte_len; | ||
84 | wc->queue[head].imm_data = (__u32 __force)entry->imm_data; | ||
85 | wc->queue[head].qp_num = entry->qp->qp_num; | ||
86 | wc->queue[head].src_qp = entry->src_qp; | ||
87 | wc->queue[head].wc_flags = entry->wc_flags; | ||
88 | wc->queue[head].pkey_index = entry->pkey_index; | ||
89 | wc->queue[head].slid = entry->slid; | ||
90 | wc->queue[head].sl = entry->sl; | ||
91 | wc->queue[head].dlid_path_bits = entry->dlid_path_bits; | ||
92 | wc->queue[head].port_num = entry->port_num; | ||
80 | wc->head = next; | 93 | wc->head = next; |
81 | 94 | ||
82 | if (cq->notify == IB_CQ_NEXT_COMP || | 95 | if (cq->notify == IB_CQ_NEXT_COMP || |
@@ -122,9 +135,30 @@ int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
122 | if (tail > (u32) cq->ibcq.cqe) | 135 | if (tail > (u32) cq->ibcq.cqe) |
123 | tail = (u32) cq->ibcq.cqe; | 136 | tail = (u32) cq->ibcq.cqe; |
124 | for (npolled = 0; npolled < num_entries; ++npolled, ++entry) { | 137 | for (npolled = 0; npolled < num_entries; ++npolled, ++entry) { |
138 | struct ipath_qp *qp; | ||
139 | |||
125 | if (tail == wc->head) | 140 | if (tail == wc->head) |
126 | break; | 141 | break; |
127 | *entry = wc->queue[tail]; | 142 | |
143 | qp = ipath_lookup_qpn(&to_idev(cq->ibcq.device)->qp_table, | ||
144 | wc->queue[tail].qp_num); | ||
145 | entry->qp = &qp->ibqp; | ||
146 | if (atomic_dec_and_test(&qp->refcount)) | ||
147 | wake_up(&qp->wait); | ||
148 | |||
149 | entry->wr_id = wc->queue[tail].wr_id; | ||
150 | entry->status = wc->queue[tail].status; | ||
151 | entry->opcode = wc->queue[tail].opcode; | ||
152 | entry->vendor_err = wc->queue[tail].vendor_err; | ||
153 | entry->byte_len = wc->queue[tail].byte_len; | ||
154 | entry->imm_data = wc->queue[tail].imm_data; | ||
155 | entry->src_qp = wc->queue[tail].src_qp; | ||
156 | entry->wc_flags = wc->queue[tail].wc_flags; | ||
157 | entry->pkey_index = wc->queue[tail].pkey_index; | ||
158 | entry->slid = wc->queue[tail].slid; | ||
159 | entry->sl = wc->queue[tail].sl; | ||
160 | entry->dlid_path_bits = wc->queue[tail].dlid_path_bits; | ||
161 | entry->port_num = wc->queue[tail].port_num; | ||
128 | if (tail >= cq->ibcq.cqe) | 162 | if (tail >= cq->ibcq.cqe) |
129 | tail = 0; | 163 | tail = 0; |
130 | else | 164 | else |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h index 37e742b2a526..7c4929f1cb5b 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.h +++ b/drivers/infiniband/hw/ipath/ipath_verbs.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
41 | #include <linux/kref.h> | 41 | #include <linux/kref.h> |
42 | #include <rdma/ib_pack.h> | 42 | #include <rdma/ib_pack.h> |
43 | #include <rdma/ib_user_verbs.h> | ||
43 | 44 | ||
44 | #include "ipath_layer.h" | 45 | #include "ipath_layer.h" |
45 | 46 | ||
@@ -188,7 +189,7 @@ struct ipath_mmap_info { | |||
188 | struct ipath_cq_wc { | 189 | struct ipath_cq_wc { |
189 | u32 head; /* index of next entry to fill */ | 190 | u32 head; /* index of next entry to fill */ |
190 | u32 tail; /* index of next ib_poll_cq() entry */ | 191 | u32 tail; /* index of next ib_poll_cq() entry */ |
191 | struct ib_wc queue[1]; /* this is actually size ibcq.cqe + 1 */ | 192 | struct ib_uverbs_wc queue[1]; /* this is actually size ibcq.cqe + 1 */ |
192 | }; | 193 | }; |
193 | 194 | ||
194 | /* | 195 | /* |