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.17 2006/11/16 01:33:49 christos 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.17 2006/11/16 01:33:49 christos 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 lwp *l));
   86 int isdntrcclose __P((dev_t dev, int flag, int fmt, struct lwp *l));
   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 lwp *l));
   89 
   90 #ifdef __NetBSD__
   91 const struct cdevsw isdntrc_cdevsw = {
   92         isdntrcopen, isdntrcclose, isdntrcread, nowrite, isdntrcioctl,
   93         nostop, notty, nopoll, nommap, nokqfilter, D_OTHER
   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,
  242         struct lwp *l)
  243 {
  244         int x;
  245         int unit = minor(dev);
  246 
  247         if(unit >= NISDNTRC)
  248                 return(ENXIO);
  249 
  250         if(device_state[unit] & ST_ISOPEN)
  251                 return(EBUSY);
  252 
  253         if(analyzemode && (unit == outunit || unit == rxunit || unit == txunit))
  254                 return(EBUSY);
  255 
  256 
  257         x = splnet();
  258 
  259         device_state[unit] = ST_ISOPEN;
  260 
  261         splx(x);
  262 
  263         return(0);
  264 }
  265 
  266 /*---------------------------------------------------------------------------*
  267  *      close trace device
  268  *---------------------------------------------------------------------------*/
  269 PDEVSTATIC int
  270 isdntrcclose(dev_t dev, int flag, int fmt,
  271         struct lwp *l)
  272 {
  273         int isdnif = minor(dev);
  274         int x;
  275 
  276         if (analyzemode && (isdnif == outunit)) {
  277                 l2_softc_t * rx_l2sc, * tx_l2sc;
  278                 analyzemode = 0;
  279                 outunit = -1;
  280 
  281                 rx_l2sc = (l2_softc_t*)isdn_find_softc_by_isdnif(rxunit);
  282                 tx_l2sc = (l2_softc_t*)isdn_find_softc_by_isdnif(txunit);
  283 
  284                 if (rx_l2sc != NULL)
  285                         rx_l2sc->driver->mph_command_req(rx_l2sc->l1_token, CMR_SETTRACE, TRACE_OFF);
  286                 if (tx_l2sc != NULL)
  287                         tx_l2sc->driver->mph_command_req(tx_l2sc->l1_token, CMR_SETTRACE, TRACE_OFF);
  288 
  289                 x = splnet();
  290                 device_state[rxunit] = ST_IDLE;
  291                 device_state[txunit] = ST_IDLE;
  292                 splx(x);
  293                 rxunit = -1;
  294                 txunit = -1;
  295         } else {
  296                 l2_softc_t * l2sc = (l2_softc_t*)isdn_find_softc_by_isdnif(isdnif);
  297                 if (l2sc != NULL) {
  298                         l2sc->driver->mph_command_req(l2sc->l1_token, CMR_SETTRACE, TRACE_OFF);
  299                         x = splnet();
  300                         device_state[isdnif] = ST_IDLE;
  301                         splx(x);
  302                 }
  303         }
  304         return(0);
  305 }
  306 
  307 /*---------------------------------------------------------------------------*
  308  *      read from trace device
  309  *---------------------------------------------------------------------------*/
  310 PDEVSTATIC int
  311 isdntrcread(dev_t dev, struct uio * uio, int ioflag)
  312 {
  313         struct mbuf *m;
  314         int x;
  315         int error = 0;
  316         int unit = minor(dev);
  317 
  318         if(!(device_state[unit] & ST_ISOPEN))
  319                 return(EIO);
  320 
  321         x = splnet();
  322 
  323         while(IF_QEMPTY(&trace_queue[unit]) && (device_state[unit] & ST_ISOPEN))
  324         {
  325                 device_state[unit] |= ST_WAITDATA;
  326 
  327                 if((error = tsleep((caddr_t) &trace_queue[unit],
  328                                         TTIPRI | PCATCH,
  329                                         "bitrc", 0 )) != 0)
  330                 {
  331                         device_state[unit] &= ~ST_WAITDATA;
  332                         splx(x);
  333                         return(error);
  334                 }
  335         }
  336 
  337         IF_DEQUEUE(&trace_queue[unit], m);
  338 
  339         if(m && m->m_len)
  340                 error = uiomove(m->m_data, m->m_len, uio);
  341         else
  342                 error = EIO;
  343 
  344         if(m)
  345                 i4b_Bfreembuf(m);
  346 
  347         splx(x);
  348 
  349         return(error);
  350 }
  351 
  352 #if defined(__FreeBSD__) && defined(OS_USES_POLL)
  353 /*---------------------------------------------------------------------------*
  354  *      poll device
  355  *---------------------------------------------------------------------------*/
  356 PDEVSTATIC int
  357 i4btrcpoll(dev_t dev, int events, struct proc *p)
  358 {
  359         return(ENODEV);
  360 }
  361 #endif
  362 
  363 /*---------------------------------------------------------------------------*
  364  *      device driver ioctl routine
  365  *---------------------------------------------------------------------------*/
  366 PDEVSTATIC int
  367 isdntrcioctl(dev_t dev, u_long cmd, caddr_t data, int flag,
  368         struct lwp *l)
  369 {
  370         int error = 0;
  371         int isdnif = minor(dev);
  372         i4b_trace_setupa_t *tsa;
  373         l2_softc_t * l2sc = (l2_softc_t*)isdn_find_softc_by_isdnif(isdnif);
  374 
  375         switch(cmd)
  376         {
  377                 case I4B_TRC_SET:
  378                         if (l2sc == NULL)
  379                                 return ENOTTY;
  380                         l2sc->driver->mph_command_req(l2sc->l1_token, CMR_SETTRACE, (void *)*(unsigned long *)data);
  381                         break;
  382 
  383                 case I4B_TRC_SETA:
  384                         tsa = (i4b_trace_setupa_t *)data;
  385 
  386                         if(tsa->rxunit >= 0 && tsa->rxunit < NISDNTRC)
  387                                 rxunit = tsa->rxunit;
  388                         else
  389                                 error = EINVAL;
  390 
  391                         if(tsa->txunit >= 0 && tsa->txunit < NISDNTRC)
  392                                 txunit = tsa->txunit;
  393                         else
  394                                 error = EINVAL;
  395 
  396                         if(error)
  397                         {
  398                                 outunit = -1;
  399                                 rxunit = -1;
  400                                 txunit = -1;
  401                         }
  402                         else
  403                         {
  404                                 l2_softc_t * rx_l2sc, * tx_l2sc;
  405                                 rx_l2sc = (l2_softc_t*)(l2_softc_t*)isdn_find_softc_by_isdnif(rxunit);
  406                                 tx_l2sc = (l2_softc_t*)(l2_softc_t*)isdn_find_softc_by_isdnif(txunit);
  407 
  408                                 if (l2sc == NULL || rx_l2sc == NULL || tx_l2sc == NULL)
  409                                         return ENOTTY;
  410 
  411                                 outunit = isdnif;
  412                                 analyzemode = 1;
  413                                 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)));
  414                                 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)));
  415                         }
  416                         break;
  417 
  418                 case I4B_TRC_RESETA:
  419                         analyzemode = 0;
  420                         outunit = -1;
  421                         rxunit = -1;
  422                         txunit = -1;
  423                         break;
  424 
  425                 default:
  426                         error = ENOTTY;
  427                         break;
  428         }
  429         return(error);
  430 }
  431 
  432 #endif /* NISDNTRC > 0 */

Cache object: 75ceab336d0b6ee9298817bbf3e417f3


[ 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.