Make -I only apply to rm's run in the foreground. Silently discard it if
[dragonfly.git] / sys / net / i4b / driver / i4b_trace.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1997, 2001 Hellmuth Michaelis. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 *
25 *---------------------------------------------------------------------------
26 *
27 * i4btrc - device driver for trace data read device
28 * ---------------------------------------------------
29 *
30 * last edit-date: [Sat Aug 11 18:07:15 2001]
31 *
32 * $FreeBSD: src/sys/i4b/driver/i4b_trace.c,v 1.9.2.3 2001/08/12 16:22:48 hm Exp $
fd81ccf9 33 * $DragonFly: src/sys/net/i4b/driver/i4b_trace.c,v 1.11 2005/01/23 13:47:24 joerg Exp $
984263bc
MD
34 *
35 * NOTE: the code assumes that SPLI4B >= splimp !
36 *
37 *---------------------------------------------------------------------------*/
38
1f2de5d4 39#include "use_i4btrc.h"
984263bc
MD
40
41#if NI4BTRC > 0
42
43#include <sys/param.h>
44#include <sys/systm.h>
45
9a7f3897 46#if defined(__DragonFly__) || (defined(__FreeBSD__) && __FreeBSD__ >= 3)
984263bc
MD
47#include <sys/ioccom.h>
48#else
49#include <sys/ioctl.h>
50#endif
51
52#include <sys/conf.h>
53#include <sys/uio.h>
54#include <sys/kernel.h>
55#include <sys/mbuf.h>
56#include <sys/socket.h>
57#include <net/if.h>
58#include <sys/tty.h>
59
9a7f3897 60#if defined(__DragonFly__) || defined(__FreeBSD__)
984263bc
MD
61
62#ifdef DEVFS
63#include <sys/devfsext.h>
64#endif
65
1f2de5d4
MD
66#include <net/i4b/include/machine/i4b_trace.h>
67#include <net/i4b/include/machine/i4b_ioctl.h>
984263bc
MD
68
69#else
70
71#include <i4b/i4b_trace.h>
72#include <i4b/i4b_ioctl.h>
73
74#endif
75
1f2de5d4
MD
76#include "../include/i4b_mbuf.h"
77#include "../include/i4b_global.h"
78#include "../include/i4b_l3l4.h"
984263bc 79
9a7f3897 80#if !defined(__DragonFly__) && !defined(__FreeBSD__)
984263bc
MD
81#define memcpy(d,s,l) bcopy(s,d,l)
82#endif
83
84static struct ifqueue trace_queue[NI4BTRC];
85static int device_state[NI4BTRC];
86#define ST_IDLE 0x00
87#define ST_ISOPEN 0x01
88#define ST_WAITDATA 0x02
89
90#if defined(__FreeBSD__) && __FreeBSD__ == 3
91#ifdef DEVFS
92static void *devfs_token[NI4BTRC];
93#endif
94#endif
95
96static int analyzemode = 0;
97static int rxunit = -1;
98static int txunit = -1;
99static int outunit = -1;
100
9a7f3897 101#if !defined(__DragonFly__) && !defined(__FreeBSD__)
984263bc
MD
102
103#define PDEVSTATIC /* - not static - */
158abb01
RG
104void i4btrcattach (void);
105int i4btrcopen (dev_t dev, int flag, int fmt, struct proc *p);
106int i4btrcclose (dev_t dev, int flag, int fmt, struct proc *p);
107int i4btrcread (dev_t dev, struct uio * uio, int ioflag);
984263bc
MD
108
109#ifdef __bsdi__
158abb01 110int i4btrcioctl (dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p);
984263bc 111#else
158abb01 112int i4btrcioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p);
984263bc
MD
113#endif
114
115#endif
116
9a7f3897 117#if defined(__DragonFly__) || (BSD > 199306 && defined(__FreeBSD__))
984263bc
MD
118#define PDEVSTATIC static
119static d_open_t i4btrcopen;
120static d_close_t i4btrcclose;
121static d_read_t i4btrcread;
122static d_ioctl_t i4btrcioctl;
123
124#ifdef OS_USES_POLL
125static d_poll_t i4btrcpoll;
126#define POLLFIELD i4btrcpoll
127#else
128#define POLLFIELD noselect
129#endif
130
131#define CDEV_MAJOR 59
132
133static struct cdevsw i4btrc_cdevsw = {
fabb8ceb
MD
134 /* name */ "i4btrc",
135 /* maj */ CDEV_MAJOR,
136 /* flags */ 0,
137 /* port */ NULL,
455fcd7e 138 /* clone */ NULL,
fabb8ceb 139
984263bc
MD
140 /* open */ i4btrcopen,
141 /* close */ i4btrcclose,
142 /* read */ i4btrcread,
143 /* write */ nowrite,
144 /* ioctl */ i4btrcioctl,
145 /* poll */ POLLFIELD,
146 /* mmap */ nommap,
147 /* strategy */ nostrategy,
984263bc 148 /* dump */ nodump,
fabb8ceb 149 /* psize */ nopsize
984263bc
MD
150};
151
152/*---------------------------------------------------------------------------*
153 * interface init routine
154 *---------------------------------------------------------------------------*/
155static
156void i4btrcinit(void *unused)
157{
e4c9c0c8 158 cdevsw_add(&i4btrc_cdevsw, 0, 0);
984263bc
MD
159}
160
161SYSINIT(i4btrcdev, SI_SUB_DRIVERS,
162 SI_ORDER_MIDDLE+CDEV_MAJOR, &i4btrcinit, NULL);
163
164static void i4btrcattach(void *);
165PSEUDO_SET(i4btrcattach, i4b_trace);
166
167#endif /* BSD > 199306 && defined(__FreeBSD__) */
168
169#ifdef __bsdi__
170#include <sys/device.h>
171int i4btrcmatch(struct device *parent, struct cfdata *cf, void *aux);
172void dummy_i4btrcattach(struct device*, struct device *, void *);
173
174#define CDEV_MAJOR 60
175
176static struct cfdriver i4btrccd =
177 { NULL, "i4btrc", i4btrcmatch, dummy_i4btrcattach, DV_DULL,
178 sizeof(struct cfdriver) };
179struct devsw i4btrcsw =
180 { &i4btrccd,
181 i4btrcopen, i4btrcclose, i4btrcread, nowrite,
182 i4btrcioctl, seltrue, nommap, nostrat,
183 nodump, nopsize, 0, nostop
184};
185
186int
187i4btrcmatch(struct device *parent, struct cfdata *cf, void *aux)
188{
189 printf("i4btrcmatch: aux=0x%x\n", aux);
190 return 1;
191}
192void
193dummy_i4btrcattach(struct device *parent, struct device *self, void *aux)
194{
195 printf("dummy_i4btrcattach: aux=0x%x\n", aux);
196}
197#endif /* __bsdi__ */
198
199int get_trace_data_from_l1(i4b_trace_hdr_t *hdr, int len, char *buf);
200
201/*---------------------------------------------------------------------------*
202 * interface attach routine
203 *---------------------------------------------------------------------------*/
204PDEVSTATIC void
9a7f3897 205#if defined(__DragonFly__) || defined(__FreeBSD__)
984263bc
MD
206i4btrcattach(void *dummy)
207#else
208i4btrcattach()
209#endif
210{
211 int i;
212
213 printf("i4btrc: %d ISDN trace device(s) attached\n", NI4BTRC);
214
215 for(i=0; i < NI4BTRC; i++)
216 {
217
9a7f3897 218#if defined(__DragonFly__) || defined(__FreeBSD__)
984263bc
MD
219 make_dev(&i4btrc_cdevsw, i,
220 UID_ROOT, GID_WHEEL, 0600, "i4btrc%d", i);
221#endif
222 trace_queue[i].ifq_maxlen = IFQ_MAXLEN;
223
9a7f3897 224#if defined(__FreeBSD__) && __FreeBSD__ > 4
984263bc
MD
225 mtx_init(&trace_queue[i].ifq_mtx, "i4b_trace", MTX_DEF);
226#endif
227 device_state[i] = ST_IDLE;
228 }
229}
230
231/*---------------------------------------------------------------------------*
232 * get_trace_data_from_l1()
233 * ------------------------
234 * is called from layer 1, adds timestamp to trace data and puts
235 * it into a queue, from which it can be read from the i4btrc
236 * device. The unit number in the trace header selects the minor
237 * device's queue the data is put into.
238 *---------------------------------------------------------------------------*/
239int
240get_trace_data_from_l1(i4b_trace_hdr_t *hdr, int len, char *buf)
241{
242 struct mbuf *m;
243 int x;
244 int unit;
245 int trunc = 0;
246 int totlen = len + sizeof(i4b_trace_hdr_t);
247
248 /*
249 * for telephony (or better non-HDLC HSCX mode) we get
250 * (MCLBYTE + sizeof(i4b_trace_hdr_t)) length packets
251 * to put into the queue to userland. because of this
252 * we detect this situation, strip the length to MCLBYTES
253 * max size, and infor the userland program of this fact
254 * by putting the no of truncated bytes into hdr->trunc.
255 */
256
257 if(totlen > MCLBYTES)
258 {
259 trunc = 1;
260 hdr->trunc = totlen - MCLBYTES;
261 totlen = MCLBYTES;
262 }
263 else
264 {
265 hdr->trunc = 0;
266 }
267
268 /* set length of trace record */
269
270 hdr->length = totlen;
271
272 /* check valid unit no */
273
274 if((unit = hdr->unit) > NI4BTRC)
275 {
276 printf("i4b_trace: get_trace_data_from_l1 - unit > NI4BTRC!\n");
277 return(0);
278 }
279
280 /* get mbuf */
281
282 if(!(m = i4b_Bgetmbuf(totlen)))
283 {
284 printf("i4b_trace: get_trace_data_from_l1 - i4b_getmbuf() failed!\n");
285 return(0);
286 }
287
288 /* check if we are in analyzemode */
289
290 if(analyzemode && (unit == rxunit || unit == txunit))
291 {
292 if(unit == rxunit)
293 hdr->dir = FROM_NT;
294 else
295 hdr->dir = FROM_TE;
296 unit = outunit;
297 }
298
fd81ccf9 299 if(IF_QFULL(&trace_queue[unit]))
984263bc
MD
300 {
301 struct mbuf *m1;
302
303 x = SPLI4B();
fd81ccf9 304 IF_DEQUEUE(&trace_queue[unit], m1);
984263bc
MD
305 splx(x);
306
307 i4b_Bfreembuf(m1);
308 }
309
310 /* copy trace header */
311 memcpy(m->m_data, hdr, sizeof(i4b_trace_hdr_t));
312
313 /* copy trace data */
314 if(trunc)
315 memcpy(&m->m_data[sizeof(i4b_trace_hdr_t)], buf, totlen-sizeof(i4b_trace_hdr_t));
316 else
317 memcpy(&m->m_data[sizeof(i4b_trace_hdr_t)], buf, len);
318
319 x = SPLI4B();
320
fd81ccf9 321 IF_ENQUEUE(&trace_queue[unit], m);
984263bc
MD
322
323 if(device_state[unit] & ST_WAITDATA)
324 {
325 device_state[unit] &= ~ST_WAITDATA;
326 wakeup((caddr_t) &trace_queue[unit]);
327 }
328
329 splx(x);
330
331 return(1);
332}
333
334/*---------------------------------------------------------------------------*
335 * open trace device
336 *---------------------------------------------------------------------------*/
337PDEVSTATIC int
7b95be2a 338i4btrcopen(dev_t dev, int flag, int fmt, struct thread *td)
984263bc
MD
339{
340 int x;
341 int unit = minor(dev);
342
343 if(unit >= NI4BTRC)
344 return(ENXIO);
345
346 if(device_state[unit] & ST_ISOPEN)
347 return(EBUSY);
348
349 if(analyzemode && (unit == outunit || unit == rxunit || unit == txunit))
350 return(EBUSY);
351
352 x = SPLI4B();
353
354 device_state[unit] = ST_ISOPEN;
355
356 splx(x);
357
358 return(0);
359}
360
361/*---------------------------------------------------------------------------*
362 * close trace device
363 *---------------------------------------------------------------------------*/
364PDEVSTATIC int
7b95be2a 365i4btrcclose(dev_t dev, int flag, int fmt, struct thread *td)
984263bc
MD
366{
367 int unit = minor(dev);
368 int i, x;
369 int cno = -1;
370
371 for(i=0; i < nctrl; i++)
372 {
373 if((ctrl_desc[i].ctrl_type == CTRL_PASSIVE) &&
374 (ctrl_desc[i].unit == unit))
375 {
376 cno = i;
377 break;
378 }
379 }
380
381 if(analyzemode && (unit == outunit))
382 {
383 analyzemode = 0;
384 outunit = -1;
385
386 if(cno >= 0)
387 {
388 (*ctrl_desc[cno].N_MGMT_COMMAND)(rxunit, CMR_SETTRACE, TRACE_OFF);
389 (*ctrl_desc[cno].N_MGMT_COMMAND)(txunit, CMR_SETTRACE, TRACE_OFF);
390 }
391 rxunit = -1;
392 txunit = -1;
393 }
394
395 if(cno >= 0)
396 {
397 (*ctrl_desc[cno].N_MGMT_COMMAND)(ctrl_desc[cno].unit, CMR_SETTRACE, TRACE_OFF);
398 }
399
400 x = SPLI4B();
401 device_state[unit] = ST_IDLE;
402 splx(x);
403
404 return(0);
405}
406
407/*---------------------------------------------------------------------------*
408 * read from trace device
409 *---------------------------------------------------------------------------*/
410PDEVSTATIC int
411i4btrcread(dev_t dev, struct uio * uio, int ioflag)
412{
413 struct mbuf *m;
414 int x;
415 int error = 0;
416 int unit = minor(dev);
417
418 if(!(device_state[unit] & ST_ISOPEN))
419 return(EIO);
420
421 x = SPLI4B();
422
984263bc
MD
423 while(IF_QEMPTY(&trace_queue[unit]) && (device_state[unit] & ST_ISOPEN))
424 {
425 device_state[unit] |= ST_WAITDATA;
426
427#if defined (__FreeBSD__) && __FreeBSD__ > 4
428 if((error = msleep((caddr_t) &trace_queue[unit],
429 &trace_queue[unit].ifq_mtx,
430 TTIPRI | PCATCH,
431 "bitrc", 0 )) != 0)
432#else
433 if((error = tsleep((caddr_t) &trace_queue[unit],
377d4740 434 PCATCH, "bitrc", 0 )) != 0)
984263bc
MD
435#endif
436 {
437 device_state[unit] &= ~ST_WAITDATA;
984263bc
MD
438 splx(x);
439 return(error);
440 }
441 }
442
fd81ccf9 443 IF_DEQUEUE(&trace_queue[unit], m);
984263bc
MD
444
445 if(m && m->m_len)
446 error = uiomove(m->m_data, m->m_len, uio);
447 else
448 error = EIO;
449
450 if(m)
451 i4b_Bfreembuf(m);
452
453 splx(x);
454
455 return(error);
456}
457
9a7f3897 458#if (defined(__DragonFly__) || defined(__FreeBSD__)) && defined(OS_USES_POLL)
984263bc
MD
459/*---------------------------------------------------------------------------*
460 * poll device
461 *---------------------------------------------------------------------------*/
462PDEVSTATIC int
7b95be2a 463i4btrcpoll(dev_t dev, int events, struct thread *td)
984263bc
MD
464{
465 return(ENODEV);
466}
467#endif
468
469/*---------------------------------------------------------------------------*
470 * device driver ioctl routine
471 *---------------------------------------------------------------------------*/
472PDEVSTATIC int
9a7f3897 473#if defined(__DragonFly__) || (defined (__FreeBSD_version) && __FreeBSD_version >= 300003)
7b95be2a 474i4btrcioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
984263bc
MD
475#elif defined(__bsdi__)
476i4btrcioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
477#else
478i4btrcioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
479#endif
480{
481 int error = 0;
482 int unit = minor(dev);
483 i4b_trace_setupa_t *tsa;
484 int i;
485 int cno = -1;
486
487 /* find the first passive controller matching our unit no */
488
489 for(i=0; i < nctrl; i++)
490 {
491 if((ctrl_desc[i].ctrl_type == CTRL_PASSIVE) &&
492 (ctrl_desc[i].unit == unit))
493 {
494 cno = i;
495 break;
496 }
497 }
498
499 switch(cmd)
500 {
501 case I4B_TRC_SET:
502 if(cno < 0)
503 return ENOTTY;
504 (*ctrl_desc[cno].N_MGMT_COMMAND)(ctrl_desc[cno].unit, CMR_SETTRACE, (void *)*(unsigned int *)data);
505 break;
506
507 case I4B_TRC_SETA:
508 tsa = (i4b_trace_setupa_t *)data;
509
510 if(tsa->rxunit >= 0 && tsa->rxunit < NI4BTRC)
511 rxunit = tsa->rxunit;
512 else
513 error = EINVAL;
514
515 if(tsa->txunit >= 0 && tsa->txunit < NI4BTRC)
516 txunit = tsa->txunit;
517 else
518 error = EINVAL;
519
520 if(error)
521 {
522 outunit = -1;
523 rxunit = -1;
524 txunit = -1;
525 }
526 else
527 {
528 if(cno < 0)
529 return ENOTTY;
530
531 outunit = unit;
532 analyzemode = 1;
533 (*ctrl_desc[cno].N_MGMT_COMMAND)(rxunit, CMR_SETTRACE, (int *)(tsa->rxflags & (TRACE_I | TRACE_D_RX | TRACE_B_RX)));
534 (*ctrl_desc[cno].N_MGMT_COMMAND)(txunit, CMR_SETTRACE, (int *)(tsa->txflags & (TRACE_I | TRACE_D_RX | TRACE_B_RX)));
535 }
536 break;
537
538 case I4B_TRC_RESETA:
539 analyzemode = 0;
540 outunit = -1;
541 rxunit = -1;
542 txunit = -1;
543 break;
544
545 default:
546 error = ENOTTY;
547 break;
548 }
549 return(error);
550}
551
552#endif /* NI4BTRC > 0 */