The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netisdn/i4b_trace.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1997, 2000 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  *      $Id: i4b_trace.c,v 1.14 2005/02/26 22:39:49 perry Exp $
   31  *
   32  *      last edit-date: [Fri Jan  5 11:33:47 2001]
   33  *
   34  *
   35  *---------------------------------------------------------------------------*/
   36 
   37 #include <sys/cdefs.h>
   38 __KERNEL_RCSID(0, "$NetBSD: i4b_trace.c,v 1.14 2005/02/26 22:39:49 perry Exp $");
   39 
   40 #include "isdntrc.h"
   41 
   42 #if NISDNTRC > 0
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 
   47 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
   48 #include <sys/ioccom.h>
   49 #else
   50 #include <sys/ioctl.h>
   51 #endif
   52 
   53 #include <sys/conf.h>
   54 #include <sys/uio.h>
   55 #include <sys/kernel.h>
   56 #include <sys/mbuf.h>
   57 #include <sys/socket.h>
   58 #include <net/if.h>
   59 #include <sys/proc.h>
   60 #include <sys/tty.h>
   61 
   62 #include <netisdn/i4b_trace.h>
   63 #include <netisdn/i4b_ioctl.h>
   64 
   65 #include <netisdn/i4b_mbuf.h>
   66 #include <netisdn/i4b_global.h>
   67 #include <netisdn/i4b_debug.h>
   68 #include <netisdn/i4b_l3l4.h>
   69 #include <netisdn/i4b_l2.h>
   70 #include <netisdn/i4b_l1l2.h>
   71 
   72 static struct ifqueue trace_queue[NISDNTRC];
   73 static int device_state[NISDNTRC];
   74 #define ST_IDLE         0x00
   75 #define ST_ISOPEN       0x01
   76 #define ST_WAITDATA     0x02
   77 
   78 static int analyzemode = 0;             /* we are in anlyzer mode */
   79 static int rxunit = -1;                 /* l2 isdnif of receiving driver */
   80 static int txunit = -1;                 /* l2 isdnif of transmitting driver */
   81 static int outunit = -1;                /* output device for trace data */
   82 
   83 #define PDEVSTATIC      /* - not static - */
   84 void isdntrcattach __P((void));
   85 int isdntrcopen __P((dev_t dev, int flag, int fmt, struct proc *p));
   86 int isdntrcclose __P((dev_t dev, int flag, int fmt, struct proc *p));
   87 int isdntrcread __P((dev_t dev, struct uio * uio, int ioflag));
   88 int isdntrcioctl __P((dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p));
   89 
   90 #ifdef __NetBSD__
   91 const struct cdevsw isdntrc_cdevsw = {
   92         isdntrcopen, isdntrcclose, isdntrcread, nowrite, isdntrcioctl,
   93         nostop, notty, nopoll, nommap, nokqfilter,
   94 };
   95 #endif /* __NetBSD__ */
   96 
   97 /*---------------------------------------------------------------------------*
   98  *      interface attach routine
   99  *---------------------------------------------------------------------------*/
  100 PDEVSTATIC void
  101 #ifdef __FreeBSD__
  102 isdntrcattach(void *dummy)
  103 #else
  104 isdntrcattach()
  105 #endif
  106 {
  107         int i;
  108 
  109         for(i=0; i < NISDNTRC; i++)
  110         {
  111 
  112 #if defined(__FreeBSD__)
  113 #if __FreeBSD__ < 4
  114 
  115 #ifdef DEVFS
  116                 devfs_token[i]
  117                   = devfs_add_devswf(&i4btrc_cdevsw, i, DV_CHR,
  118                                      UID_ROOT, GID_WHEEL, 0600,
  119                                      "isdntrc%d", i);
  120 #endif
  121 
  122 #else
  123                 make_dev(&i4btrc_cdevsw, i,
  124                                      UID_ROOT, GID_WHEEL, 0600, "isdntrc%d", i);
  125 #endif
  126 #endif
  127                 trace_queue[i].ifq_maxlen = IFQ_MAXLEN;
  128                 device_state[i] = ST_IDLE;
  129         }
  130 }
  131 
  132 /*---------------------------------------------------------------------------*
  133  *      isdn_layer2_trace_ind
  134  *      ---------------------
  135  *      is called from layer 1, adds timestamp to trace data and puts
  136  *      it into a queue, from which it can be read from the i4btrc
  137  *      device. The unit number in the trace header selects the minor
  138  *      device's queue the data is put into.
  139  *---------------------------------------------------------------------------*/
  140 int
  141 isdn_layer2_trace_ind(struct l2_softc *sc, struct isdn_l3_driver *drv, i4b_trace_hdr *hdr, size_t len, unsigned char *buf)
  142 {
  143         struct mbuf *m;
  144         int isdnif, x;
  145         int trunc = 0;
  146         int totlen = len + sizeof(i4b_trace_hdr);
  147 
  148         MICROTIME(hdr->time);
  149         hdr->isdnif = sc->drv->isdnif;
  150 
  151         /*
  152          * for telephony (or better non-HDLC HSCX mode) we get
  153          * (MCLBYTE + sizeof(i4b_trace_hdr_t)) length packets
  154          * to put into the queue to userland. because of this
  155          * we detect this situation, strip the length to MCLBYTES
  156          * max size, and infor the userland program of this fact
  157          * by putting the no of truncated bytes into hdr->trunc.
  158          */
  159 
  160         if(totlen > MCLBYTES)
  161         {
  162                 trunc = 1;
  163                 hdr->trunc = totlen - MCLBYTES;
  164                 totlen = MCLBYTES;
  165         }
  166         else
  167         {
  168                 hdr->trunc = 0;
  169         }
  170 
  171         /* set length of trace record */
  172 
  173         hdr->length = totlen;
  174 
  175         /* check valid interface */
  176 
  177         if((isdnif = hdr->isdnif) > NISDNTRC)
  178         {
  179                 printf("i4b_trace: get_trace_data_from_l1 - isdnif > NISDNTRC!\n");
  180                 return(0);
  181         }
  182 
  183         /* get mbuf */
  184 
  185         if(!(m = i4b_Bgetmbuf(totlen)))
  186         {
  187                 printf("i4b_trace: get_trace_data_from_l1 - i4b_getmbuf() failed!\n");
  188                 return(0);
  189         }
  190 
  191         /* check if we are in analyzemode */
  192 
  193         if(analyzemode && (isdnif == rxunit || isdnif == txunit))
  194         {
  195                 if(isdnif == rxunit)
  196                         hdr->dir = FROM_NT;
  197                 else
  198                         hdr->dir = FROM_TE;
  199                 isdnif = outunit;
  200         }
  201 
  202         if(IF_QFULL(&trace_queue[isdnif]))
  203         {
  204                 struct mbuf *m1;
  205 
  206                 x = splnet();
  207                 IF_DEQUEUE(&trace_queue[isdnif], m1);
  208                 splx(x);
  209 
  210                 i4b_Bfreembuf(m1);
  211         }
  212 
  213         /* copy trace header */
  214         memcpy(m->m_data, hdr, sizeof(i4b_trace_hdr));
  215 
  216         /* copy trace data */
  217         if(trunc)
  218                 memcpy(&m->m_data[sizeof(i4b_trace_hdr)], buf, totlen-sizeof(i4b_trace_hdr));
  219         else
  220                 memcpy(&m->m_data[sizeof(i4b_trace_hdr)], buf, len);
  221 
  222         x = splnet();
  223 
  224         IF_ENQUEUE(&trace_queue[isdnif], m);
  225 
  226         if(device_state[isdnif] & ST_WAITDATA)
  227         {
  228                 device_state[isdnif] &= ~ST_WAITDATA;
  229                 wakeup((caddr_t) &trace_queue[isdnif]);
  230         }
  231 
  232         splx(x);
  233 
  234         return(1);
  235 }
  236 
  237 /*---------------------------------------------------------------------------*
  238  *      open trace device
  239  *---------------------------------------------------------------------------*/
  240 PDEVSTATIC int
  241 isdntrcopen(dev_t dev, int flag, int fmt, struct proc *p)
  242 {
  243         int x;
  244         int unit = minor(dev);
  245 
  246         if(unit >= NISDNTRC)
  247                 return(ENXIO);
  248 
  249         if(device_state[unit] & ST_ISOPEN)
  250                 return(EBUSY);
  251 
  252         if(analyzemode && (unit == outunit || unit == rxunit || unit == txunit))
  253                 return(EBUSY);
  254 
  255 
  256         x = splnet();
  257 
  258         device_state[unit] = ST_ISOPEN;
  259 
  260         splx(x);
  261 
  262         return(0);
  263 }
  264 
  265 /*---------------------------------------------------------------------------*
  266  *      close trace device
  267  *---------------------------------------------------------------------------*/
  268 PDEVSTATIC int
  269 isdntrcclose(dev_t dev, int flag, int fmt, struct proc *p)
  270 {
  271         int isdnif = minor(dev);
  272         int x;
  273 
  274         if (analyzemode && (isdnif == outunit)) {
  275                 l2_softc_t * rx_l2sc, * tx_l2sc;
  276                 analyzemode = 0;
  277                 outunit = -1;
  278 
  279                 rx_l2sc = (l2_softc_t*)isdn_find_softc_by_isdnif(rxunit);
  280                 tx_l2sc = (l2_softc_t*)isdn_find_softc_by_isdnif(txunit);
  281 
  282                 if (rx_l2sc != NULL)
  283                         rx_l2sc->driver->mph_command_req(rx_l2sc->l1_token, CMR_SETTRACE, TRACE_OFF);
  284                 if (tx_l2sc != NULL)
  285                         tx_l2sc->driver->mph_command_req(tx_l2sc->l1_token, CMR_SETTRACE, TRACE_OFF);
  286 
  287                 x = splnet();
  288                 device_state[rxunit] = ST_IDLE;
  289                 device_state[txunit] = ST_IDLE;
  290                 splx(x);
  291                 rxunit = -1;
  292                 txunit = -1;
  293         } else {
  294                 l2_softc_t * l2sc = (l2_softc_t*)isdn_find_softc_by_isdnif(isdnif);
  295                 if (l2sc != NULL) {
  296                         l2sc->driver->mph_command_req(l2sc->l1_token, CMR_SETTRACE, TRACE_OFF);
  297                         x = splnet();
  298                         device_state[isdnif] = ST_IDLE;
  299                         splx(x);
  300                 }
  301         }
  302         return(0);
  303 }
  304 
  305 /*---------------------------------------------------------------------------*
  306  *      read from trace device
  307  *---------------------------------------------------------------------------*/
  308 PDEVSTATIC int
  309 isdntrcread(dev_t dev, struct uio * uio, int ioflag)
  310 {
  311         struct mbuf *m;
  312         int x;
  313         int error = 0;
  314         int unit = minor(dev);
  315 
  316         if(!(device_state[unit] & ST_ISOPEN))
  317                 return(EIO);
  318 
  319         x = splnet();
  320 
  321         while(IF_QEMPTY(&trace_queue[unit]) && (device_state[unit] & ST_ISOPEN))
  322         {
  323                 device_state[unit] |= ST_WAITDATA;
  324 
  325                 if((error = tsleep((caddr_t) &trace_queue[unit],
  326                                         TTIPRI | PCATCH,
  327                                         "bitrc", 0 )) != 0)
  328                 {
  329                         device_state[unit] &= ~ST_WAITDATA;
  330                         splx(x);
  331                         return(error);
  332                 }
  333         }
  334 
  335         IF_DEQUEUE(&trace_queue[unit], m);
  336 
  337         if(m && m->m_len)
  338                 error = uiomove(m->m_data, m->m_len, uio);
  339         else
  340                 error = EIO;
  341 
  342         if(m)
  343                 i4b_Bfreembuf(m);
  344 
  345         splx(x);
  346 
  347         return(error);
  348 }
  349 
  350 #if defined(__FreeBSD__) && defined(OS_USES_POLL)
  351 /*---------------------------------------------------------------------------*
  352  *      poll device
  353  *---------------------------------------------------------------------------*/
  354 PDEVSTATIC int
  355 i4btrcpoll(dev_t dev, int events, struct proc *p)
  356 {
  357         return(ENODEV);
  358 }
  359 #endif
  360 
  361 /*---------------------------------------------------------------------------*
  362  *      device driver ioctl routine
  363  *---------------------------------------------------------------------------*/
  364 PDEVSTATIC int
  365 isdntrcioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
  366 {
  367         int error = 0;
  368         int isdnif = minor(dev);
  369         i4b_trace_setupa_t *tsa;
  370         l2_softc_t * l2sc = (l2_softc_t*)isdn_find_softc_by_isdnif(isdnif);
  371 
  372         switch(cmd)
  373         {
  374                 case I4B_TRC_SET:
  375                         if (l2sc == NULL)
  376                                 return ENOTTY;
  377                         l2sc->driver->mph_command_req(l2sc->l1_token, CMR_SETTRACE, (void *)*(unsigned long *)data);
  378                         break;
  379 
  380                 case I4B_TRC_SETA:
  381                         tsa = (i4b_trace_setupa_t *)data;
  382 
  383                         if(tsa->rxunit >= 0 && tsa->rxunit < NISDNTRC)
  384                                 rxunit = tsa->rxunit;
  385                         else
  386                                 error = EINVAL;
  387 
  388                         if(tsa->txunit >= 0 && tsa->txunit < NISDNTRC)
  389                                 txunit = tsa->txunit;
  390                         else
  391                                 error = EINVAL;
  392 
  393                         if(error)
  394                         {
  395                                 outunit = -1;
  396                                 rxunit = -1;
  397                                 txunit = -1;
  398                         }
  399                         else
  400                         {
  401                                 l2_softc_t * rx_l2sc, * tx_l2sc;
  402                                 rx_l2sc = (l2_softc_t*)(l2_softc_t*)isdn_find_softc_by_isdnif(rxunit);
  403                                 tx_l2sc = (l2_softc_t*)(l2_softc_t*)isdn_find_softc_by_isdnif(txunit);
  404 
  405                                 if (l2sc == NULL || rx_l2sc == NULL || tx_l2sc == NULL)
  406                                         return ENOTTY;
  407 
  408                                 outunit = isdnif;
  409                                 analyzemode = 1;
  410                                 rx_l2sc->driver->mph_command_req(rx_l2sc->l1_token, CMR_SETTRACE, (void *)(unsigned long)(tsa->rxflags & (TRACE_I | TRACE_D_RX | TRACE_B_RX)));
  411                                 tx_l2sc->driver->mph_command_req(tx_l2sc->l1_token, CMR_SETTRACE, (void *)(unsigned long)(tsa->txflags & (TRACE_I | TRACE_D_RX | TRACE_B_RX)));
  412                         }
  413                         break;
  414 
  415                 case I4B_TRC_RESETA:
  416                         analyzemode = 0;
  417                         outunit = -1;
  418                         rxunit = -1;
  419                         txunit = -1;
  420                         break;
  421 
  422                 default:
  423                         error = ENOTTY;
  424                         break;
  425         }
  426         return(error);
  427 }
  428 
  429 #endif /* NISDNTRC > 0 */

Cache object: 0c527eee5d497bd924494ed3d27c5140


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.