1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include "scif_main.h"
19#include "scif_map.h"
20
21void scif_cleanup_ep_qp(struct scif_endpt *ep)
22{
23 struct scif_qp *qp = ep->qp_info.qp;
24
25 if (qp->outbound_q.rb_base) {
26 scif_iounmap((void *)qp->outbound_q.rb_base,
27 qp->outbound_q.size, ep->remote_dev);
28 qp->outbound_q.rb_base = NULL;
29 }
30 if (qp->remote_qp) {
31 scif_iounmap((void *)qp->remote_qp,
32 sizeof(struct scif_qp), ep->remote_dev);
33 qp->remote_qp = NULL;
34 }
35 if (qp->local_qp) {
36 scif_unmap_single(qp->local_qp, ep->remote_dev,
37 sizeof(struct scif_qp));
38 qp->local_qp = 0x0;
39 }
40 if (qp->local_buf) {
41 scif_unmap_single(qp->local_buf, ep->remote_dev,
42 SCIF_ENDPT_QP_SIZE);
43 qp->local_buf = 0;
44 }
45}
46
47void scif_teardown_ep(void *endpt)
48{
49 struct scif_endpt *ep = endpt;
50 struct scif_qp *qp = ep->qp_info.qp;
51
52 if (qp) {
53 spin_lock(&ep->lock);
54 scif_cleanup_ep_qp(ep);
55 spin_unlock(&ep->lock);
56 kfree(qp->inbound_q.rb_base);
57 kfree(qp);
58 }
59}
60
61
62
63
64
65void scif_add_epd_to_zombie_list(struct scif_endpt *ep, bool eplock_held)
66{
67 if (!eplock_held)
68 mutex_lock(&scif_info.eplock);
69 spin_lock(&ep->lock);
70 ep->state = SCIFEP_ZOMBIE;
71 spin_unlock(&ep->lock);
72 list_add_tail(&ep->list, &scif_info.zombie);
73 scif_info.nr_zombies++;
74 if (!eplock_held)
75 mutex_unlock(&scif_info.eplock);
76 schedule_work(&scif_info.misc_work);
77}
78
79static struct scif_endpt *scif_find_listen_ep(u16 port)
80{
81 struct scif_endpt *ep = NULL;
82 struct list_head *pos, *tmpq;
83
84 mutex_lock(&scif_info.eplock);
85 list_for_each_safe(pos, tmpq, &scif_info.listen) {
86 ep = list_entry(pos, struct scif_endpt, list);
87 if (ep->port.port == port) {
88 mutex_unlock(&scif_info.eplock);
89 return ep;
90 }
91 }
92 mutex_unlock(&scif_info.eplock);
93 return NULL;
94}
95
96void scif_cleanup_zombie_epd(void)
97{
98 struct list_head *pos, *tmpq;
99 struct scif_endpt *ep;
100
101 mutex_lock(&scif_info.eplock);
102 list_for_each_safe(pos, tmpq, &scif_info.zombie) {
103 ep = list_entry(pos, struct scif_endpt, list);
104 if (scif_rma_ep_can_uninit(ep)) {
105 list_del(pos);
106 scif_info.nr_zombies--;
107 put_iova_domain(&ep->rma_info.iovad);
108 kfree(ep);
109 }
110 }
111 mutex_unlock(&scif_info.eplock);
112}
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128void scif_cnctreq(struct scif_dev *scifdev, struct scifmsg *msg)
129{
130 struct scif_endpt *ep = NULL;
131 struct scif_conreq *conreq;
132
133 conreq = kmalloc(sizeof(*conreq), GFP_KERNEL);
134 if (!conreq)
135
136 goto conreq_sendrej;
137
138 ep = scif_find_listen_ep(msg->dst.port);
139 if (!ep)
140
141 goto conreq_sendrej_free;
142 else
143 spin_lock(&ep->lock);
144
145 if (ep->backlog <= ep->conreqcnt) {
146
147 spin_unlock(&ep->lock);
148 goto conreq_sendrej_free;
149 }
150
151 conreq->msg = *msg;
152 list_add_tail(&conreq->list, &ep->conlist);
153 ep->conreqcnt++;
154 wake_up_interruptible(&ep->conwq);
155 spin_unlock(&ep->lock);
156 return;
157
158conreq_sendrej_free:
159 kfree(conreq);
160conreq_sendrej:
161 msg->uop = SCIF_CNCT_REJ;
162 scif_nodeqp_send(&scif_dev[msg->src.node], msg);
163}
164
165
166
167
168
169
170
171
172
173
174void scif_cnctgnt(struct scif_dev *scifdev, struct scifmsg *msg)
175{
176 struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
177
178 spin_lock(&ep->lock);
179 if (SCIFEP_CONNECTING == ep->state) {
180 ep->peer.node = msg->src.node;
181 ep->peer.port = msg->src.port;
182 ep->qp_info.gnt_pld = msg->payload[1];
183 ep->remote_ep = msg->payload[2];
184 ep->state = SCIFEP_MAPPING;
185
186 wake_up(&ep->conwq);
187 }
188 spin_unlock(&ep->lock);
189}
190
191
192
193
194
195
196
197
198
199void scif_cnctgnt_ack(struct scif_dev *scifdev, struct scifmsg *msg)
200{
201 struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
202
203 mutex_lock(&scif_info.connlock);
204 spin_lock(&ep->lock);
205
206 ep->state = SCIFEP_CONNECTED;
207 list_add_tail(&ep->list, &scif_info.connected);
208 wake_up(&ep->conwq);
209 spin_unlock(&ep->lock);
210 mutex_unlock(&scif_info.connlock);
211}
212
213
214
215
216
217
218
219
220
221void scif_cnctgnt_nack(struct scif_dev *scifdev, struct scifmsg *msg)
222{
223 struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
224
225 spin_lock(&ep->lock);
226 ep->state = SCIFEP_CLOSING;
227 wake_up(&ep->conwq);
228 spin_unlock(&ep->lock);
229}
230
231
232
233
234
235
236
237
238void scif_cnctrej(struct scif_dev *scifdev, struct scifmsg *msg)
239{
240 struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
241
242 spin_lock(&ep->lock);
243 if (SCIFEP_CONNECTING == ep->state) {
244 ep->state = SCIFEP_BOUND;
245 wake_up(&ep->conwq);
246 }
247 spin_unlock(&ep->lock);
248}
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263void scif_discnct(struct scif_dev *scifdev, struct scifmsg *msg)
264{
265 struct scif_endpt *ep = NULL;
266 struct scif_endpt *tmpep;
267 struct list_head *pos, *tmpq;
268
269 mutex_lock(&scif_info.connlock);
270 list_for_each_safe(pos, tmpq, &scif_info.connected) {
271 tmpep = list_entry(pos, struct scif_endpt, list);
272
273
274
275
276
277
278 if (((u64)tmpep == msg->payload[1]) &&
279 ((u64)tmpep->remote_ep == msg->payload[0])) {
280 list_del(pos);
281 ep = tmpep;
282 spin_lock(&ep->lock);
283 break;
284 }
285 }
286
287
288
289
290
291
292
293 if (!ep) {
294 mutex_unlock(&scif_info.connlock);
295 goto discnct_ack;
296 }
297
298 ep->state = SCIFEP_DISCONNECTED;
299 list_add_tail(&ep->list, &scif_info.disconnected);
300
301 wake_up_interruptible(&ep->sendwq);
302 wake_up_interruptible(&ep->recvwq);
303 spin_unlock(&ep->lock);
304 mutex_unlock(&scif_info.connlock);
305
306discnct_ack:
307 msg->uop = SCIF_DISCNT_ACK;
308 scif_nodeqp_send(&scif_dev[msg->src.node], msg);
309}
310
311
312
313
314
315
316
317void scif_discnt_ack(struct scif_dev *scifdev, struct scifmsg *msg)
318{
319 struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
320
321 spin_lock(&ep->lock);
322 ep->state = SCIFEP_DISCONNECTED;
323 spin_unlock(&ep->lock);
324 complete(&ep->discon);
325}
326
327
328
329
330
331
332
333void scif_clientsend(struct scif_dev *scifdev, struct scifmsg *msg)
334{
335 struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
336
337 spin_lock(&ep->lock);
338 if (SCIFEP_CONNECTED == ep->state)
339 wake_up_interruptible(&ep->recvwq);
340 spin_unlock(&ep->lock);
341}
342
343
344
345
346
347
348
349void scif_clientrcvd(struct scif_dev *scifdev, struct scifmsg *msg)
350{
351 struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0];
352
353 spin_lock(&ep->lock);
354 if (SCIFEP_CONNECTED == ep->state)
355 wake_up_interruptible(&ep->sendwq);
356 spin_unlock(&ep->lock);
357}
358