CTC++ Coverage Report - Execution Profile    #528/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: drivers/net/irda/irtty-sir.c
Instrumentation mode: function-decision-multicondition
TER: 0 % ( 0/277)

Start/ End/    
True False - Line Source

  1 /*********************************************************************
  2  *                
  3  * Filename:      irtty-sir.c
  4  * Version:       2.0
  5  * Description:   IrDA line discipline implementation
  6  * Status:        Experimental.
  7  * Author:        Dag Brattli <dagb@cs.uit.no>
  8  * Created at:    Tue Dec  9 21:18:38 1997
  9  * Modified at:   Sun Oct 27 22:13:30 2002
  10  * Modified by:   Martin Diehl <mad@mdiehl.de>
  11  * Sources:       slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
  12  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
  13  * 
  14  *     Copyright (c) 1998-2000 Dag Brattli,
  15  *     Copyright (c) 2002 Martin Diehl,
  16  *     All Rights Reserved.
  17  *      
  18  *     This program is free software; you can redistribute it and/or 
  19  *     modify it under the terms of the GNU General Public License as 
  20  *     published by the Free Software Foundation; either version 2 of 
  21  *     the License, or (at your option) any later version.
  22  *  
  23  *     Neither Dag Brattli nor University of Tromsų admit liability nor
  24  *     provide warranty for any of this software. This material is 
  25  *     provided "AS-IS" and at no charge.
  26  *     
  27  ********************************************************************/    
  28 
  29 #include <linux/module.h>
  30 #include <linux/kernel.h>
  31 #include <linux/tty.h>
  32 #include <linux/init.h>
  33 #include <asm/uaccess.h>
  34 #include <linux/smp_lock.h>
  35 #include <linux/delay.h>
  36 
  37 #include <net/irda/irda.h>
  38 #include <net/irda/irda_device.h>
  39 
  40 #include "sir-dev.h"
  41 #include "irtty-sir.h"
  42 
  43 static int qos_mtt_bits = 0x03;      /* 5 ms or more */
  44 
 
- 45 module_param(qos_mtt_bits, int, 0);
 - 45 return ( & ( qos_mtt_bits ) )
  46 MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
  47 
  48 /* ------------------------------------------------------- */
  49 
  50 /* device configuration callbacks always invoked with irda-thread context */
  51 
  52 /* find out, how many chars we have in buffers below us
  53  * this is allowed to lie, i.e. return less chars than we
  54  * actually have. The returned value is used to determine
  55  * how long the irdathread should wait before doing the
  56  * real blocking wait_until_sent()
  57  */
  58 
 
- 59 static int irtty_chars_in_buffer(struct sir_dev *dev)
  60 {
  61    struct sirtty_cb *priv = dev->priv;
  62 
    63    IRDA_ASSERT(priv != NULL, return -1;);
- 63   if (! ( priv != ( ( void * ) 0 ) ))
 - 63     return - 1
- 63 do-while (0)
    64    IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;);
- 64   if (! ( priv -> magic == 0x2357 ))
 - 64     return - 1
- 64 do-while (0)
  65 
 - 66    return priv->tty->driver->chars_in_buffer(priv->tty);
  67 }
  68 
  69 /* Wait (sleep) until underlaying hardware finished transmission
  70  * i.e. hardware buffers are drained
  71  * this must block and not return before all characters are really sent
  72  *
  73  * If the tty sits on top of a 16550A-like uart, there are typically
  74  * up to 16 bytes in the fifo - f.e. 9600 bps 8N1 needs 16.7 msec
  75  *
  76  * With usbserial the uart-fifo is basically replaced by the converter's
  77  * outgoing endpoint buffer, which can usually hold 64 bytes (at least).
  78  * With pl2303 it appears we are safe with 60msec here.
  79  *
  80  * I really wish all serial drivers would provide
  81  * correct implementation of wait_until_sent()
  82  */
  83 
  84 #define USBSERIAL_TX_DONE_DELAY   60
  85 
 
- 86 static void irtty_wait_until_sent(struct sir_dev *dev)
  87 {
  88    struct sirtty_cb *priv = dev->priv;
  89    struct tty_struct *tty;
  90 
    91    IRDA_ASSERT(priv != NULL, return;);
- 91   if (! ( priv != ( ( void * ) 0 ) ))
 - 91     return
- 91 do-while (0)
    92    IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;);
- 92   if (! ( priv -> magic == 0x2357 ))
 - 92     return
- 92 do-while (0)
  93 
  94    tty = priv->tty;
- 95    if (tty->driver->wait_until_sent) {
    96       lock_kernel();
- 96   do-while (0)
  97       tty->driver->wait_until_sent(tty, msecs_to_jiffies(100));
    98       unlock_kernel();
- 98   do-while (0)
  99    }
    100    else {
  101       msleep(USBSERIAL_TX_DONE_DELAY);
  102    }
  103 }
  104 
  105 /* 
  106  *  Function irtty_change_speed (dev, speed)
  107  *
  108  *    Change the speed of the serial port.
  109  *
  110  * This may sleep in set_termios (usbserial driver f.e.) and must
  111  * not be called from interrupt/timer/tasklet therefore.
  112  * All such invocations are deferred to kIrDAd now so we can sleep there.
  113  */
  114 
 
- 115 static int irtty_change_speed(struct sir_dev *dev, unsigned speed)
  116 {
  117    struct sirtty_cb *priv = dev->priv;
  118    struct tty_struct *tty;
  119         struct termios old_termios;
  120    int cflag;
  121 
    122    IRDA_ASSERT(priv != NULL, return -1;);
- 122   if (! ( priv != ( ( void * ) 0 ) ))
 - 122     return - 1
- 122 do-while (0)
    123    IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;);
- 123   if (! ( priv -> magic == 0x2357 ))
 - 123     return - 1
- 123 do-while (0)
  124 
  125    tty = priv->tty;
  126 
    127    lock_kernel();
- 127 do-while (0)
  128    old_termios = *(tty->termios);
  129    cflag = tty->termios->c_cflag;
  130 
  131    cflag &= ~CBAUD;
  132 
    133    IRDA_DEBUG(2, "%s(), Setting speed to %d\n", __FUNCTION__, speed);
- 133   if (irda_debug >= ( 2 ))
- 133 do-while (0)
  134 
    135    switch (speed) {
 - 136    case 1200:
  137       cflag |= B1200;
 - 138       break;
 - 139    case 2400:
  140       cflag |= B2400;
 - 141       break;
 - 142    case 4800:
  143       cflag |= B4800;
 - 144       break;
 - 145    case 19200:
  146       cflag |= B19200;
 - 147       break;
 - 148    case 38400:
  149       cflag |= B38400;
 - 150       break;
 - 151    case 57600:
  152       cflag |= B57600;
 - 153       break;
 - 154    case 115200:
  155       cflag |= B115200;
 - 156       break;
 - 157    case 9600:
 - 158    default:
  159       cflag |= B9600;
 - 160       break;
  161    }   
  162 
  163    tty->termios->c_cflag = cflag;
- 164    if (tty->driver->set_termios)
  165       tty->driver->set_termios(tty, &old_termios);
    166    unlock_kernel();
- 166 do-while (0)
  167 
  168    priv->io.speed = speed;
  169 
 - 170    return 0;
  171 }
  172 
  173 /*
  174  * Function irtty_set_dtr_rts (dev, dtr, rts)
  175  *
  176  *    This function can be used by dongles etc. to set or reset the status
  177  *    of the dtr and rts lines
  178  */
  179 
 
- 180 static int irtty_set_dtr_rts(struct sir_dev *dev, int dtr, int rts)
  181 {
  182    struct sirtty_cb *priv = dev->priv;
  183    int set = 0;
  184    int clear = 0;
  185 
    186    IRDA_ASSERT(priv != NULL, return -1;);
- 186   if (! ( priv != ( ( void * ) 0 ) ))
 - 186     return - 1
- 186 do-while (0)
    187    IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;);
- 187   if (! ( priv -> magic == 0x2357 ))
 - 187     return - 1
- 187 do-while (0)
  188 
- 189    if (rts)
  190       set |= TIOCM_RTS;
    191    else
  192       clear |= TIOCM_RTS;
- 193    if (dtr)
  194       set |= TIOCM_DTR;
    195    else
  196       clear |= TIOCM_DTR;
  197 
  198    /*
  199     * We can't use ioctl() because it expects a non-null file structure,
  200     * and we don't have that here.
  201     * This function is not yet defined for all tty driver, so
  202     * let's be careful... Jean II
  203     */
    204    IRDA_ASSERT(priv->tty->driver->tiocmset != NULL, return -1;);
- 204   if (! ( priv -> tty -> driver -> tiocmset !=..
 - 204     return - 1
- 204 do-while (0)
  205    priv->tty->driver->tiocmset(priv->tty, NULL, set, clear);
  206 
 - 207    return 0;
  208 }
  209 
  210 /* ------------------------------------------------------- */
  211 
  212 /* called from sir_dev when there is more data to send
  213  * context is either netdev->hard_xmit or some transmit-completion bh
  214  * i.e. we are under spinlock here and must not sleep.
  215  */
  216 
 
- 217 static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t len)
  218 {
  219    struct sirtty_cb *priv = dev->priv;
  220    struct tty_struct *tty;
  221    int writelen;
  222 
    223    IRDA_ASSERT(priv != NULL, return -1;);
- 223   if (! ( priv != ( ( void * ) 0 ) ))
 - 223     return - 1
- 223 do-while (0)
    224    IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;);
- 224   if (! ( priv -> magic == 0x2357 ))
 - 224     return - 1
- 224 do-while (0)
  225 
  226    tty = priv->tty;
- 227    if (!tty->driver->write)
 - 228       return 0;
  229    tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
- 230    if (tty->driver->write_room) {
  231       writelen = tty->driver->write_room(tty);
- 232       if (writelen > len)
  233          writelen = len;
  234    }
    235    else
  236       writelen = len;
 - 237    return tty->driver->write(tty, ptr, writelen);
  238 }
  239 
  240 /* ------------------------------------------------------- */
  241 
  242 /* irda line discipline callbacks */
  243 
  244 /* 
  245  *  Function irtty_receive_buf( tty, cp, count)
  246  *
  247  *    Handle the 'receiver data ready' interrupt.  This function is called
  248  *    by the 'tty_io' module in the kernel when a block of IrDA data has
  249  *    been received, which can now be decapsulated and delivered for
  250  *    further processing 
  251  *
  252  * calling context depends on underlying driver and tty->low_latency!
  253  * for example (low_latency: 1 / 0):
  254  * serial.c:   uart-interrupt / softint
  255  * usbserial:   urb-complete-interrupt / softint
  256  */
  257 
 
- 258 static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
  259                char *fp, int count) 
  260 {
  261    struct sir_dev *dev;
  262    struct sirtty_cb *priv = tty->disc_data;
  263    int   i;
  264 
    265    IRDA_ASSERT(priv != NULL, return;);
- 265   if (! ( priv != ( ( void * ) 0 ) ))
 - 265     return
- 265 do-while (0)
    266    IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;);
- 266   if (! ( priv -> magic == 0x2357 ))
 - 266     return
- 266 do-while (0)
  267 
- 268    if (unlikely(count==0))      /* yes, this happens */
 - 269       return;
  270 
  271    dev = priv->dev;
- 272    if (!dev) {
    273       IRDA_WARNING("%s(), not ready yet!\n", __FUNCTION__);
- 273     if (net_ratelimit ( ))
- 273   do-while (0)
 - 274       return;
  275    }
  276 
- 277    for (i = 0; i < count; i++) {
  278       /* 
  279        *  Characters received with a parity error, etc?
  280        */
- 281        if (fp && *fp++) { 
 - 281     T && T
 - 281     T && F
 - 281     F && _
    282          IRDA_DEBUG(0, "Framing or parity error!\n");
- 282       if (irda_debug >= ( 0 ))
- 282     do-while (0)
  283          sirdev_receive(dev, NULL, 0);   /* notify sir_dev (updating stats) */
 - 284          return;
  285        }
  286    }
  287 
  288    sirdev_receive(dev, cp, count);
  289 }
  290 
  291 /*
  292  * Function irtty_write_wakeup (tty)
  293  *
  294  *    Called by the driver when there's room for more data.  If we have
  295  *    more packets to send, we send them here.
  296  *
  297  */
 
- 298 static void irtty_write_wakeup(struct tty_struct *tty) 
  299 {
  300    struct sirtty_cb *priv = tty->disc_data;
  301 
    302    IRDA_ASSERT(priv != NULL, return;);
- 302   if (! ( priv != ( ( void * ) 0 ) ))
 - 302     return
- 302 do-while (0)
    303    IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;);
- 303   if (! ( priv -> magic == 0x2357 ))
 - 303     return
- 303 do-while (0)
  304 
  305    tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
  306 
- 307    if (priv->dev)
  308       sirdev_write_complete(priv->dev);
  309 }
  310 
  311 /* ------------------------------------------------------- */
  312 
  313 /*
  314  * Function irtty_stop_receiver (tty, stop)
  315  *
  316  */
  317 
 
- 318 static inline void irtty_stop_receiver(struct tty_struct *tty, int stop)
  319 {
  320    struct termios old_termios;
  321    int cflag;
  322 
    323    lock_kernel();
- 323 do-while (0)
  324    old_termios = *(tty->termios);
  325    cflag = tty->termios->c_cflag;
  326    
- 327    if (stop)
  328       cflag &= ~CREAD;
    329    else
  330       cflag |= CREAD;
  331 
  332    tty->termios->c_cflag = cflag;
- 333    if (tty->driver->set_termios)
  334       tty->driver->set_termios(tty, &old_termios);
    335    unlock_kernel();
- 335 do-while (0)
  336 }
  337 
  338 /*****************************************************************/
  339 
  340 /* serialize ldisc open/close with sir_dev */
  341 static DECLARE_MUTEX(irtty_sem);
  342 
  343 /* notifier from sir_dev when irda% device gets opened (ifup) */
  344 
 
- 345 static int irtty_start_dev(struct sir_dev *dev)
  346 {
  347    struct sirtty_cb *priv;
  348    struct tty_struct *tty;
  349 
  350    /* serialize with ldisc open/close */
  351    down(&irtty_sem);
  352 
  353    priv = dev->priv;
- 354    if (unlikely(!priv || priv->magic!=IRTTY_MAGIC)) {
  355       up(&irtty_sem);
 - 356       return -ESTALE;
  357    }
  358 
  359    tty = priv->tty;
  360 
- 361    if (tty->driver->start)
  362       tty->driver->start(tty);
  363    /* Make sure we can receive more data */
  364    irtty_stop_receiver(tty, FALSE);
  365 
  366    up(&irtty_sem);
 - 367    return 0;
  368 }
  369 
  370 /* notifier from sir_dev when irda% device gets closed (ifdown) */
  371 
 
- 372 static int irtty_stop_dev(struct sir_dev *dev)
  373 {
  374    struct sirtty_cb *priv;
  375    struct tty_struct *tty;
  376 
  377    /* serialize with ldisc open/close */
  378    down(&irtty_sem);
  379 
  380    priv = dev->priv;
- 381    if (unlikely(!priv || priv->magic!=IRTTY_MAGIC)) {
  382       up(&irtty_sem);
 - 383       return -ESTALE;
  384    }
  385 
  386    tty = priv->tty;
  387 
  388    /* Make sure we don't receive more data */
  389    irtty_stop_receiver(tty, TRUE);
- 390    if (tty->driver->stop)
  391       tty->driver->stop(tty);
  392 
  393    up(&irtty_sem);
  394 
 - 395    return 0;
  396 }
  397 
  398 /* ------------------------------------------------------- */
  399 
  400 static struct sir_driver sir_tty_drv = {
  401    .owner         = THIS_MODULE,
  402    .driver_name      = "sir_tty",
  403    .start_dev      = irtty_start_dev,
  404    .stop_dev      = irtty_stop_dev,
  405    .do_write      = irtty_do_write,
  406    .chars_in_buffer   = irtty_chars_in_buffer,
  407    .wait_until_sent   = irtty_wait_until_sent,
  408    .set_speed      = irtty_change_speed,
  409    .set_dtr_rts      = irtty_set_dtr_rts,
  410 };
  411 
  412 /* ------------------------------------------------------- */
  413 
  414 /*
  415  * Function irtty_ioctl (tty, file, cmd, arg)
  416  *
  417  *     The Swiss army knife of system calls :-)
  418  *
  419  */
 
- 420 static int irtty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
  421 {
  422    struct irtty_info { char name[6]; } info;
  423    struct sir_dev *dev;
  424    struct sirtty_cb *priv = tty->disc_data;
  425    int err = 0;
  426 
    427    IRDA_ASSERT(priv != NULL, return -ENODEV;);
- 427   if (! ( priv != ( ( void * ) 0 ) ))
 - 427     return - 19
- 427 do-while (0)
    428    IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -EBADR;);
- 428   if (! ( priv -> magic == 0x2357 ))
 - 428     return - 53
- 428 do-while (0)
  429 
    430    IRDA_DEBUG(3, "%s(cmd=0x%X)\n", __FUNCTION__, cmd);
- 430   if (irda_debug >= ( 3 ))
- 430 do-while (0)
  431 
  432    dev = priv->dev;
    433    IRDA_ASSERT(dev != NULL, return -1;);
- 433   if (! ( dev != ( ( void * ) 0 ) ))
 - 433     return - 1
- 433 do-while (0)
  434 
    435    switch (cmd) {
 - 436    case TCGETS:
 - 437    case TCGETA:
  438       err = n_tty_ioctl(tty, file, cmd, arg);
 - 439       break;
  440 
 - 441    case IRTTY_IOCTDONGLE:
  442       /* this call blocks for completion */
  443       err = sirdev_set_dongle(dev, (IRDA_DONGLE) arg);
 - 444       break;
  445 
 - 446    case IRTTY_IOCGET:
    447       IRDA_ASSERT(dev->netdev != NULL, return -1;);
- 447     if (! ( dev -> netdev != ( ( void * ) 0 ) ))
 - 447       return - 1
- 447   do-while (0)
  448 
  449       memset(&info, 0, sizeof(info)); 
  450       strncpy(info.name, dev->netdev->name, sizeof(info.name)-1);
  451