]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* proc.c: /proc interface for RxRPC |
2 | * | |
3 | * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. | |
4 | * Written by David Howells (dhowells@redhat.com) | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License | |
8 | * as published by the Free Software Foundation; either version | |
9 | * 2 of the License, or (at your option) any later version. | |
10 | */ | |
11 | ||
12 | #include <linux/sched.h> | |
13 | #include <linux/slab.h> | |
14 | #include <linux/module.h> | |
15 | #include <linux/proc_fs.h> | |
16 | #include <linux/seq_file.h> | |
17 | #include <rxrpc/rxrpc.h> | |
18 | #include <rxrpc/transport.h> | |
19 | #include <rxrpc/peer.h> | |
20 | #include <rxrpc/connection.h> | |
21 | #include <rxrpc/call.h> | |
22 | #include <rxrpc/message.h> | |
23 | #include "internal.h" | |
24 | ||
25 | static struct proc_dir_entry *proc_rxrpc; | |
26 | ||
27 | static int rxrpc_proc_transports_open(struct inode *inode, struct file *file); | |
28 | static void *rxrpc_proc_transports_start(struct seq_file *p, loff_t *pos); | |
29 | static void *rxrpc_proc_transports_next(struct seq_file *p, void *v, loff_t *pos); | |
30 | static void rxrpc_proc_transports_stop(struct seq_file *p, void *v); | |
31 | static int rxrpc_proc_transports_show(struct seq_file *m, void *v); | |
32 | ||
33 | static struct seq_operations rxrpc_proc_transports_ops = { | |
34 | .start = rxrpc_proc_transports_start, | |
35 | .next = rxrpc_proc_transports_next, | |
36 | .stop = rxrpc_proc_transports_stop, | |
37 | .show = rxrpc_proc_transports_show, | |
38 | }; | |
39 | ||
40 | static struct file_operations rxrpc_proc_transports_fops = { | |
41 | .open = rxrpc_proc_transports_open, | |
42 | .read = seq_read, | |
43 | .llseek = seq_lseek, | |
44 | .release = seq_release, | |
45 | }; | |
46 | ||
47 | static int rxrpc_proc_peers_open(struct inode *inode, struct file *file); | |
48 | static void *rxrpc_proc_peers_start(struct seq_file *p, loff_t *pos); | |
49 | static void *rxrpc_proc_peers_next(struct seq_file *p, void *v, loff_t *pos); | |
50 | static void rxrpc_proc_peers_stop(struct seq_file *p, void *v); | |
51 | static int rxrpc_proc_peers_show(struct seq_file *m, void *v); | |
52 | ||
53 | static struct seq_operations rxrpc_proc_peers_ops = { | |
54 | .start = rxrpc_proc_peers_start, | |
55 | .next = rxrpc_proc_peers_next, | |
56 | .stop = rxrpc_proc_peers_stop, | |
57 | .show = rxrpc_proc_peers_show, | |
58 | }; | |
59 | ||
60 | static struct file_operations rxrpc_proc_peers_fops = { | |
61 | .open = rxrpc_proc_peers_open, | |
62 | .read = seq_read, | |
63 | .llseek = seq_lseek, | |
64 | .release = seq_release, | |
65 | }; | |
66 | ||
67 | static int rxrpc_proc_conns_open(struct inode *inode, struct file *file); | |
68 | static void *rxrpc_proc_conns_start(struct seq_file *p, loff_t *pos); | |
69 | static void *rxrpc_proc_conns_next(struct seq_file *p, void *v, loff_t *pos); | |
70 | static void rxrpc_proc_conns_stop(struct seq_file *p, void *v); | |
71 | static int rxrpc_proc_conns_show(struct seq_file *m, void *v); | |
72 | ||
73 | static struct seq_operations rxrpc_proc_conns_ops = { | |
74 | .start = rxrpc_proc_conns_start, | |
75 | .next = rxrpc_proc_conns_next, | |
76 | .stop = rxrpc_proc_conns_stop, | |
77 | .show = rxrpc_proc_conns_show, | |
78 | }; | |
79 | ||
80 | static struct file_operations rxrpc_proc_conns_fops = { | |
81 | .open = rxrpc_proc_conns_open, | |
82 | .read = seq_read, | |
83 | .llseek = seq_lseek, | |
84 | .release = seq_release, | |
85 | }; | |
86 | ||
87 | static int rxrpc_proc_calls_open(struct inode *inode, struct file *file); | |
88 | static void *rxrpc_proc_calls_start(struct seq_file *p, loff_t *pos); | |
89 | static void *rxrpc_proc_calls_next(struct seq_file *p, void *v, loff_t *pos); | |
90 | static void rxrpc_proc_calls_stop(struct seq_file *p, void *v); | |
91 | static int rxrpc_proc_calls_show(struct seq_file *m, void *v); | |
92 | ||
93 | static struct seq_operations rxrpc_proc_calls_ops = { | |
94 | .start = rxrpc_proc_calls_start, | |
95 | .next = rxrpc_proc_calls_next, | |
96 | .stop = rxrpc_proc_calls_stop, | |
97 | .show = rxrpc_proc_calls_show, | |
98 | }; | |
99 | ||
100 | static struct file_operations rxrpc_proc_calls_fops = { | |
101 | .open = rxrpc_proc_calls_open, | |
102 | .read = seq_read, | |
103 | .llseek = seq_lseek, | |
104 | .release = seq_release, | |
105 | }; | |
106 | ||
107 | static const char *rxrpc_call_states7[] = { | |
108 | "complet", | |
109 | "error ", | |
110 | "rcv_op ", | |
111 | "rcv_arg", | |
112 | "got_arg", | |
113 | "snd_rpl", | |
114 | "fin_ack", | |
115 | "snd_arg", | |
116 | "rcv_rpl", | |
117 | "got_rpl" | |
118 | }; | |
119 | ||
120 | static const char *rxrpc_call_error_states7[] = { | |
121 | "no_err ", | |
122 | "loc_abt", | |
123 | "rmt_abt", | |
124 | "loc_err", | |
125 | "rmt_err" | |
126 | }; | |
127 | ||
128 | /*****************************************************************************/ | |
129 | /* | |
130 | * initialise the /proc/net/rxrpc/ directory | |
131 | */ | |
132 | int rxrpc_proc_init(void) | |
133 | { | |
134 | struct proc_dir_entry *p; | |
135 | ||
136 | proc_rxrpc = proc_mkdir("rxrpc", proc_net); | |
137 | if (!proc_rxrpc) | |
138 | goto error; | |
139 | proc_rxrpc->owner = THIS_MODULE; | |
140 | ||
141 | p = create_proc_entry("calls", 0, proc_rxrpc); | |
142 | if (!p) | |
143 | goto error_proc; | |
144 | p->proc_fops = &rxrpc_proc_calls_fops; | |
145 | p->owner = THIS_MODULE; | |
146 | ||
147 | p = create_proc_entry("connections", 0, proc_rxrpc); | |
148 | if (!p) | |
149 | goto error_calls; | |
150 | p->proc_fops = &rxrpc_proc_conns_fops; | |
151 | p->owner = THIS_MODULE; | |
152 | ||
153 | p = create_proc_entry("peers", 0, proc_rxrpc); | |
154 | if (!p) | |
155 | goto error_calls; | |
156 | p->proc_fops = &rxrpc_proc_peers_fops; | |
157 | p->owner = THIS_MODULE; | |
158 | ||
159 | p = create_proc_entry("transports", 0, proc_rxrpc); | |
160 | if (!p) | |
161 | goto error_conns; | |
162 | p->proc_fops = &rxrpc_proc_transports_fops; | |
163 | p->owner = THIS_MODULE; | |
164 | ||
165 | return 0; | |
166 | ||
167 | error_conns: | |
168 | remove_proc_entry("connections", proc_rxrpc); | |
169 | error_calls: | |
170 | remove_proc_entry("calls", proc_rxrpc); | |
171 | error_proc: | |
172 | remove_proc_entry("rxrpc", proc_net); | |
173 | error: | |
174 | return -ENOMEM; | |
175 | } /* end rxrpc_proc_init() */ | |
176 | ||
177 | /*****************************************************************************/ | |
178 | /* | |
179 | * clean up the /proc/net/rxrpc/ directory | |
180 | */ | |
181 | void rxrpc_proc_cleanup(void) | |
182 | { | |
183 | remove_proc_entry("transports", proc_rxrpc); | |
184 | remove_proc_entry("peers", proc_rxrpc); | |
185 | remove_proc_entry("connections", proc_rxrpc); | |
186 | remove_proc_entry("calls", proc_rxrpc); | |
187 | ||
188 | remove_proc_entry("rxrpc", proc_net); | |
189 | ||
190 | } /* end rxrpc_proc_cleanup() */ | |
191 | ||
192 | /*****************************************************************************/ | |
193 | /* | |
194 | * open "/proc/net/rxrpc/transports" which provides a summary of extant transports | |
195 | */ | |
196 | static int rxrpc_proc_transports_open(struct inode *inode, struct file *file) | |
197 | { | |
198 | struct seq_file *m; | |
199 | int ret; | |
200 | ||
201 | ret = seq_open(file, &rxrpc_proc_transports_ops); | |
202 | if (ret < 0) | |
203 | return ret; | |
204 | ||
205 | m = file->private_data; | |
206 | m->private = PDE(inode)->data; | |
207 | ||
208 | return 0; | |
209 | } /* end rxrpc_proc_transports_open() */ | |
210 | ||
211 | /*****************************************************************************/ | |
212 | /* | |
213 | * set up the iterator to start reading from the transports list and return the first item | |
214 | */ | |
215 | static void *rxrpc_proc_transports_start(struct seq_file *m, loff_t *_pos) | |
216 | { | |
217 | struct list_head *_p; | |
218 | loff_t pos = *_pos; | |
219 | ||
220 | /* lock the list against modification */ | |
221 | down_read(&rxrpc_proc_transports_sem); | |
222 | ||
223 | /* allow for the header line */ | |
224 | if (!pos) | |
225 | return SEQ_START_TOKEN; | |
226 | pos--; | |
227 | ||
228 | /* find the n'th element in the list */ | |
229 | list_for_each(_p, &rxrpc_proc_transports) | |
230 | if (!pos--) | |
231 | break; | |
232 | ||
233 | return _p != &rxrpc_proc_transports ? _p : NULL; | |
234 | } /* end rxrpc_proc_transports_start() */ | |
235 | ||
236 | /*****************************************************************************/ | |
237 | /* | |
238 | * move to next call in transports list | |
239 | */ | |
240 | static void *rxrpc_proc_transports_next(struct seq_file *p, void *v, loff_t *pos) | |
241 | { | |
242 | struct list_head *_p; | |
243 | ||
244 | (*pos)++; | |
245 | ||
246 | _p = v; | |
247 | _p = (v == SEQ_START_TOKEN) ? rxrpc_proc_transports.next : _p->next; | |
248 | ||
249 | return _p != &rxrpc_proc_transports ? _p : NULL; | |
250 | } /* end rxrpc_proc_transports_next() */ | |
251 | ||
252 | /*****************************************************************************/ | |
253 | /* | |
254 | * clean up after reading from the transports list | |
255 | */ | |
256 | static void rxrpc_proc_transports_stop(struct seq_file *p, void *v) | |
257 | { | |
258 | up_read(&rxrpc_proc_transports_sem); | |
259 | ||
260 | } /* end rxrpc_proc_transports_stop() */ | |
261 | ||
262 | /*****************************************************************************/ | |
263 | /* | |
264 | * display a header line followed by a load of call lines | |
265 | */ | |
266 | static int rxrpc_proc_transports_show(struct seq_file *m, void *v) | |
267 | { | |
268 | struct rxrpc_transport *trans = | |
269 | list_entry(v, struct rxrpc_transport, proc_link); | |
270 | ||
271 | /* display header on line 1 */ | |
272 | if (v == SEQ_START_TOKEN) { | |
273 | seq_puts(m, "LOCAL USE\n"); | |
274 | return 0; | |
275 | } | |
276 | ||
277 | /* display one transport per line on subsequent lines */ | |
278 | seq_printf(m, "%5hu %3d\n", | |
279 | trans->port, | |
280 | atomic_read(&trans->usage) | |
281 | ); | |
282 | ||
283 | return 0; | |
284 | } /* end rxrpc_proc_transports_show() */ | |
285 | ||
286 | /*****************************************************************************/ | |
287 | /* | |
288 | * open "/proc/net/rxrpc/peers" which provides a summary of extant peers | |
289 | */ | |
290 | static int rxrpc_proc_peers_open(struct inode *inode, struct file *file) | |
291 | { | |
292 | struct seq_file *m; | |
293 | int ret; | |
294 | ||
295 | ret = seq_open(file, &rxrpc_proc_peers_ops); | |
296 | if (ret < 0) | |
297 | return ret; | |
298 | ||
299 | m = file->private_data; | |
300 | m->private = PDE(inode)->data; | |
301 | ||
302 | return 0; | |
303 | } /* end rxrpc_proc_peers_open() */ | |
304 | ||
305 | /*****************************************************************************/ | |
306 | /* | |
307 | * set up the iterator to start reading from the peers list and return the | |
308 | * first item | |
309 | */ | |
310 | static void *rxrpc_proc_peers_start(struct seq_file *m, loff_t *_pos) | |
311 | { | |
312 | struct list_head *_p; | |
313 | loff_t pos = *_pos; | |
314 | ||
315 | /* lock the list against modification */ | |
316 | down_read(&rxrpc_peers_sem); | |
317 | ||
318 | /* allow for the header line */ | |
319 | if (!pos) | |
320 | return SEQ_START_TOKEN; | |
321 | pos--; | |
322 | ||
323 | /* find the n'th element in the list */ | |
324 | list_for_each(_p, &rxrpc_peers) | |
325 | if (!pos--) | |
326 | break; | |
327 | ||
328 | return _p != &rxrpc_peers ? _p : NULL; | |
329 | } /* end rxrpc_proc_peers_start() */ | |
330 | ||
331 | /*****************************************************************************/ | |
332 | /* | |
333 | * move to next conn in peers list | |
334 | */ | |
335 | static void *rxrpc_proc_peers_next(struct seq_file *p, void *v, loff_t *pos) | |
336 | { | |
337 | struct list_head *_p; | |
338 | ||
339 | (*pos)++; | |
340 | ||
341 | _p = v; | |
342 | _p = (v == SEQ_START_TOKEN) ? rxrpc_peers.next : _p->next; | |
343 | ||
344 | return _p != &rxrpc_peers ? _p : NULL; | |
345 | } /* end rxrpc_proc_peers_next() */ | |
346 | ||
347 | /*****************************************************************************/ | |
348 | /* | |
349 | * clean up after reading from the peers list | |
350 | */ | |
351 | static void rxrpc_proc_peers_stop(struct seq_file *p, void *v) | |
352 | { | |
353 | up_read(&rxrpc_peers_sem); | |
354 | ||
355 | } /* end rxrpc_proc_peers_stop() */ | |
356 | ||
357 | /*****************************************************************************/ | |
358 | /* | |
359 | * display a header line followed by a load of conn lines | |
360 | */ | |
361 | static int rxrpc_proc_peers_show(struct seq_file *m, void *v) | |
362 | { | |
363 | struct rxrpc_peer *peer = list_entry(v, struct rxrpc_peer, proc_link); | |
364 | signed long timeout; | |
365 | ||
366 | /* display header on line 1 */ | |
367 | if (v == SEQ_START_TOKEN) { | |
368 | seq_puts(m, "LOCAL REMOTE USAGE CONNS TIMEOUT" | |
369 | " MTU RTT(uS)\n"); | |
370 | return 0; | |
371 | } | |
372 | ||
373 | /* display one peer per line on subsequent lines */ | |
374 | timeout = 0; | |
375 | if (!list_empty(&peer->timeout.link)) | |
376 | timeout = (signed long) peer->timeout.timo_jif - | |
377 | (signed long) jiffies; | |
378 | ||
379 | seq_printf(m, "%5hu %08x %5d %5d %8ld %5Zu %7lu\n", | |
380 | peer->trans->port, | |
381 | ntohl(peer->addr.s_addr), | |
382 | atomic_read(&peer->usage), | |
383 | atomic_read(&peer->conn_count), | |
384 | timeout, | |
385 | peer->if_mtu, | |
386 | (long) peer->rtt | |
387 | ); | |
388 | ||
389 | return 0; | |
390 | } /* end rxrpc_proc_peers_show() */ | |
391 | ||
392 | /*****************************************************************************/ | |
393 | /* | |
394 | * open "/proc/net/rxrpc/connections" which provides a summary of extant | |
395 | * connections | |
396 | */ | |
397 | static int rxrpc_proc_conns_open(struct inode *inode, struct file *file) | |
398 | { | |
399 | struct seq_file *m; | |
400 | int ret; | |
401 | ||
402 | ret = seq_open(file, &rxrpc_proc_conns_ops); | |
403 | if (ret < 0) | |
404 | return ret; | |
405 | ||
406 | m = file->private_data; | |
407 | m->private = PDE(inode)->data; | |
408 | ||
409 | return 0; | |
410 | } /* end rxrpc_proc_conns_open() */ | |
411 | ||
412 | /*****************************************************************************/ | |
413 | /* | |
414 | * set up the iterator to start reading from the conns list and return the | |
415 | * first item | |
416 | */ | |
417 | static void *rxrpc_proc_conns_start(struct seq_file *m, loff_t *_pos) | |
418 | { | |
419 | struct list_head *_p; | |
420 | loff_t pos = *_pos; | |
421 | ||
422 | /* lock the list against modification */ | |
423 | down_read(&rxrpc_conns_sem); | |
424 | ||
425 | /* allow for the header line */ | |
426 | if (!pos) | |
427 | return SEQ_START_TOKEN; | |
428 | pos--; | |
429 | ||
430 | /* find the n'th element in the list */ | |
431 | list_for_each(_p, &rxrpc_conns) | |
432 | if (!pos--) | |
433 | break; | |
434 | ||
435 | return _p != &rxrpc_conns ? _p : NULL; | |
436 | } /* end rxrpc_proc_conns_start() */ | |
437 | ||
438 | /*****************************************************************************/ | |
439 | /* | |
440 | * move to next conn in conns list | |
441 | */ | |
442 | static void *rxrpc_proc_conns_next(struct seq_file *p, void *v, loff_t *pos) | |
443 | { | |
444 | struct list_head *_p; | |
445 | ||
446 | (*pos)++; | |
447 | ||
448 | _p = v; | |
449 | _p = (v == SEQ_START_TOKEN) ? rxrpc_conns.next : _p->next; | |
450 | ||
451 | return _p != &rxrpc_conns ? _p : NULL; | |
452 | } /* end rxrpc_proc_conns_next() */ | |
453 | ||
454 | /*****************************************************************************/ | |
455 | /* | |
456 | * clean up after reading from the conns list | |
457 | */ | |
458 | static void rxrpc_proc_conns_stop(struct seq_file *p, void *v) | |
459 | { | |
460 | up_read(&rxrpc_conns_sem); | |
461 | ||
462 | } /* end rxrpc_proc_conns_stop() */ | |
463 | ||
464 | /*****************************************************************************/ | |
465 | /* | |
466 | * display a header line followed by a load of conn lines | |
467 | */ | |
468 | static int rxrpc_proc_conns_show(struct seq_file *m, void *v) | |
469 | { | |
470 | struct rxrpc_connection *conn; | |
471 | signed long timeout; | |
472 | ||
473 | conn = list_entry(v, struct rxrpc_connection, proc_link); | |
474 | ||
475 | /* display header on line 1 */ | |
476 | if (v == SEQ_START_TOKEN) { | |
477 | seq_puts(m, | |
478 | "LOCAL REMOTE RPORT SRVC CONN END SERIALNO " | |
479 | "CALLNO MTU TIMEOUT" | |
480 | "\n"); | |
481 | return 0; | |
482 | } | |
483 | ||
484 | /* display one conn per line on subsequent lines */ | |
485 | timeout = 0; | |
486 | if (!list_empty(&conn->timeout.link)) | |
487 | timeout = (signed long) conn->timeout.timo_jif - | |
488 | (signed long) jiffies; | |
489 | ||
490 | seq_printf(m, | |
491 | "%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5Zu %8ld\n", | |
492 | conn->trans->port, | |
493 | ntohl(conn->addr.sin_addr.s_addr), | |
494 | ntohs(conn->addr.sin_port), | |
495 | ntohs(conn->service_id), | |
496 | ntohl(conn->conn_id), | |
497 | conn->out_clientflag ? "CLT" : "SRV", | |
498 | conn->serial_counter, | |
499 | conn->call_counter, | |
500 | conn->mtu_size, | |
501 | timeout | |
502 | ); | |
503 | ||
504 | return 0; | |
505 | } /* end rxrpc_proc_conns_show() */ | |
506 | ||
507 | /*****************************************************************************/ | |
508 | /* | |
509 | * open "/proc/net/rxrpc/calls" which provides a summary of extant calls | |
510 | */ | |
511 | static int rxrpc_proc_calls_open(struct inode *inode, struct file *file) | |
512 | { | |
513 | struct seq_file *m; | |
514 | int ret; | |
515 | ||
516 | ret = seq_open(file, &rxrpc_proc_calls_ops); | |
517 | if (ret < 0) | |
518 | return ret; | |
519 | ||
520 | m = file->private_data; | |
521 | m->private = PDE(inode)->data; | |
522 | ||
523 | return 0; | |
524 | } /* end rxrpc_proc_calls_open() */ | |
525 | ||
526 | /*****************************************************************************/ | |
527 | /* | |
528 | * set up the iterator to start reading from the calls list and return the | |
529 | * first item | |
530 | */ | |
531 | static void *rxrpc_proc_calls_start(struct seq_file *m, loff_t *_pos) | |
532 | { | |
533 | struct list_head *_p; | |
534 | loff_t pos = *_pos; | |
535 | ||
536 | /* lock the list against modification */ | |
537 | down_read(&rxrpc_calls_sem); | |
538 | ||
539 | /* allow for the header line */ | |
540 | if (!pos) | |
541 | return SEQ_START_TOKEN; | |
542 | pos--; | |
543 | ||
544 | /* find the n'th element in the list */ | |
545 | list_for_each(_p, &rxrpc_calls) | |
546 | if (!pos--) | |
547 | break; | |
548 | ||
549 | return _p != &rxrpc_calls ? _p : NULL; | |
550 | } /* end rxrpc_proc_calls_start() */ | |
551 | ||
552 | /*****************************************************************************/ | |
553 | /* | |
554 | * move to next call in calls list | |
555 | */ | |
556 | static void *rxrpc_proc_calls_next(struct seq_file *p, void *v, loff_t *pos) | |
557 | { | |
558 | struct list_head *_p; | |
559 | ||
560 | (*pos)++; | |
561 | ||
562 | _p = v; | |
563 | _p = (v == SEQ_START_TOKEN) ? rxrpc_calls.next : _p->next; | |
564 | ||
565 | return _p != &rxrpc_calls ? _p : NULL; | |
566 | } /* end rxrpc_proc_calls_next() */ | |
567 | ||
568 | /*****************************************************************************/ | |
569 | /* | |
570 | * clean up after reading from the calls list | |
571 | */ | |
572 | static void rxrpc_proc_calls_stop(struct seq_file *p, void *v) | |
573 | { | |
574 | up_read(&rxrpc_calls_sem); | |
575 | ||
576 | } /* end rxrpc_proc_calls_stop() */ | |
577 | ||
578 | /*****************************************************************************/ | |
579 | /* | |
580 | * display a header line followed by a load of call lines | |
581 | */ | |
582 | static int rxrpc_proc_calls_show(struct seq_file *m, void *v) | |
583 | { | |
584 | struct rxrpc_call *call = list_entry(v, struct rxrpc_call, call_link); | |
585 | ||
586 | /* display header on line 1 */ | |
587 | if (v == SEQ_START_TOKEN) { | |
588 | seq_puts(m, | |
589 | "LOCAL REMOT SRVC CONN CALL DIR USE " | |
590 | " L STATE OPCODE ABORT ERRNO\n" | |
591 | ); | |
592 | return 0; | |
593 | } | |
594 | ||
595 | /* display one call per line on subsequent lines */ | |
596 | seq_printf(m, | |
597 | "%5hu %5hu %04hx %08x %08x %s %3u%c" | |
598 | " %c %-7.7s %6d %08x %5d\n", | |
599 | call->conn->trans->port, | |
600 | ntohs(call->conn->addr.sin_port), | |
601 | ntohs(call->conn->service_id), | |
602 | ntohl(call->conn->conn_id), | |
603 | ntohl(call->call_id), | |
604 | call->conn->service ? "SVC" : "CLT", | |
605 | atomic_read(&call->usage), | |
606 | waitqueue_active(&call->waitq) ? 'w' : ' ', | |
607 | call->app_last_rcv ? 'Y' : '-', | |
608 | (call->app_call_state!=RXRPC_CSTATE_ERROR ? | |
609 | rxrpc_call_states7[call->app_call_state] : | |
610 | rxrpc_call_error_states7[call->app_err_state]), | |
611 | call->app_opcode, | |
612 | call->app_abort_code, | |
613 | call->app_errno | |
614 | ); | |
615 | ||
616 | return 0; | |
617 | } /* end rxrpc_proc_calls_show() */ |