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