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

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


File: drivers/parport/daisy.c
Instrumentation mode: function-decision-multicondition
TER: 34 % (101/296)

Start/ End/    
True False - Line Source

  1 /*
  2  * IEEE 1284.3 Parallel port daisy chain and multiplexor code
  3  * 
  4  * Copyright (C) 1999, 2000  Tim Waugh <tim@cyberelk.demon.co.uk>
  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-1998: Initial implementation.
  12  * 31-01-1999: Make port-cloning transparent.
  13  * 13-02-1999: Move DeviceID technique from parport_probe.
  14  * 13-03-1999: Get DeviceID from non-IEEE 1284.3 devices too.
  15  * 22-02-2000: Count devices that are actually detected.
  16  *
  17  * Any part of this program may be used in documents licensed under
  18  * the GNU Free Documentation License, Version 1.1 or any later version
  19  * published by the Free Software Foundation.
  20  */
  21 
  22 #include <linux/module.h>
  23 #include <linux/parport.h>
  24 #include <linux/delay.h>
  25 #include <linux/sched.h>
  26 
  27 #include <asm/current.h>
  28 #include <asm/uaccess.h>
  29 
  30 #undef DEBUG
  31 
  32 #ifdef DEBUG
  33 #define DPRINTK(stuff...) printk (stuff)
  34 #else
  35 #define DPRINTK(stuff...)
  36 #endif
  37 
  38 static struct daisydev {
  39    struct daisydev *next;
  40    struct parport *port;
  41    int daisy;
  42    int devnum;
  43 } *topology = NULL;
  44 static DEFINE_SPINLOCK(topology_lock);
  45 
  46 static int numdevs = 0;
  47 
  48 /* Forward-declaration of lower-level functions. */
  49 static int mux_present (struct parport *port);
  50 static int num_mux_ports (struct parport *port);
  51 static int select_port (struct parport *port);
  52 static int assign_addrs (struct parport *port);
  53 
  54 /* Add a device to the discovered topology. */
 
  55 static void add_dev (int devnum, struct parport *port, int daisy)
  56 {
  57    struct daisydev *newdev, **p;
  58    newdev = kmalloc (sizeof (struct daisydev), GFP_KERNEL);
- 59    if (newdev) {
  60       newdev->port = port;
  61       newdev->daisy = daisy;
  62       newdev->devnum = devnum;
    63       spin_lock(&topology_lock);
    63     do
- 63     do-while (0)
- 63   do-while (0)
- 64       for (p = &topology; *p && (*p)->devnum<devnum; p = &(*p)->next)
 - 64     T && T
 - 64     T && F
   64     F && _
  65          ;
  66       newdev->next = *p;
  67       *p = newdev;
    68       spin_unlock(&topology_lock);
    68     do
- 68     do-while (0)
- 68   do-while (0)
  69    }
  70 }
  71 
  72 /* Clone a parport (actually, make an alias). */
 
- 73 static struct parport *clone_parport (struct parport *real, int muxport)
  74 {
  75    struct parport *extra = parport_register_port (real->base,
  76                          real->irq,
  77                          real->dma,
  78                          real->ops);
- 79    if (extra) {
  80       extra->portnum = real->portnum;
  81       extra->physport = real;
  82       extra->muxport = muxport;
  83       real->slaves[muxport-1] = extra;
  84    }
  85 
 - 86    return extra;
  87 }
  88 
  89 /* Discover the IEEE1284.3 topology on a port -- muxes and daisy chains.
  90  * Return value is number of devices actually detected. */
 
  91 int parport_daisy_init (struct parport *port)
  92 {
  93    int detected = 0;
  94    char *deviceid;
  95    static const char *th[] = { /*0*/"th", "st", "nd", "rd", "th" };
  96    int num_ports;
  97    int i;
  98    int last_try = 0;
  99 
  100 again:
  101    /* Because this is called before any other devices exist,
  102     * we don't have to claim exclusive access.  */
  103 
  104    /* If mux present on normal port, need to create new
  105     * parports for each extra port. */
  106    if (port->muxport < 0 && mux_present (port) &&
  107        /* don't be fooled: a mux must have 2 or 4 ports. */
- 108        ((num_ports = num_mux_ports (port)) == 2 || num_ports == 4)) {
 - 108   T && T && (T || _)
 - 108   T && T && (F || T)
 - 108   T && T && (F || F)
   108   T && F && (_ || _)
 - 108   F && _ && (_ || _)
  109       /* Leave original as port zero. */
  110       port->muxport = 0;
  111       printk (KERN_INFO
  112          "%s: 1st (default) port of %d-way multiplexor\n",
  113          port->name, num_ports);
- 114       for (i = 1; i < num_ports; i++) {
  115          /* Clone the port. */
  116          struct parport *extra = clone_parport (port, i);
- 117          if (!extra) {
- 118             if (signal_pending (current))
 - 119                break;
  120 
  121             schedule ();
 - 122             continue;
  123          }
  124 
  125          printk (KERN_INFO
  126             "%s: %d%s port of %d-way multiplexor on %s\n",
  127             extra->name, i + 1, th[i + 1], num_ports,
  128             port->name);
  129 
  130          /* Analyse that port too.  We won't recurse
  131             forever because of the 'port->muxport < 0'
  132             test above. */
  133          parport_daisy_init(extra);
  134       }
  135    }
  136 
- 137    if (port->muxport >= 0)
  138       select_port (port);
  139 
  140    parport_daisy_deselect_all (port);
  141    detected += assign_addrs (port);
  142 
  143    /* Count the potential legacy device at the end. */
  144    add_dev (numdevs++, port, -1);
  145 
  146    /* Find out the legacy device's IEEE 1284 device ID. */
  147    deviceid = kmalloc (1024, GFP_KERNEL);
- 148    if (deviceid) {
- 149       if (parport_device_id (numdevs - 1, deviceid, 1024) > 2)
  150          detected++;
  151 
  152       kfree (deviceid);
  153    }
  154 
  155    if (!detected && !last_try) {
   155   T && T
   155   T && F
 - 155   F && _
  156       /* No devices were detected.  Perhaps they are in some
  157                    funny state; let's try to reset them and see if
  158                    they wake up. */
  159       parport_daisy_fini (port);
  160       parport_write_control (port, PARPORT_CONTROL_SELECT);
    161       udelay (50);
- 161   ternary-?: __builtin_constant_p ( 50 )
- 161   ternary-?: ( 50 ) > 20000
  162       parport_write_control (port,
  163                    PARPORT_CONTROL_SELECT |
  164                    PARPORT_CONTROL_INIT);
    165       udelay (50);
- 165   ternary-?: __builtin_constant_p ( 50 )
- 165   ternary-?: ( 50 ) > 20000
  166       last_try = 1;
   167       goto again;
  168    }
  169 
   170    return detected;
  171 }
  172 
  173 /* Forget about devices on a physical port. */
 
  174 void parport_daisy_fini (struct parport *port)
  175 {
  176    struct daisydev **p;
  177 
    178    spin_lock(&topology_lock);
    178   do
- 178   do-while (0)
- 178 do-while (0)
  179    p = &topology;
  180    while (*p) {
  181       struct daisydev *dev = *p;
- 182       if (dev->port != port) {
  183          p = &dev->next;
 - 184          continue;
  185       }
  186       *p = dev->next;
  187       kfree(dev);
  188    }
  189 
  190    /* Gaps in the numbering could be handled better.  How should
  191            someone enumerate through all IEEE1284.3 devices in the
  192            topology?. */
- 193    if (!topology) numdevs = 0;
    194    spin_unlock(&topology_lock);
    194   do
- 194   do-while (0)
- 194 do-while (0)
   195    return;
  196 }
  197 
  198 /**
  199  *   parport_open - find a device by canonical device number
  200  *   @devnum: canonical device number
  201  *   @name: name to associate with the device
  202  *   @pf: preemption callback
  203  *   @kf: kick callback
  204  *   @irqf: interrupt handler
  205  *   @flags: registration flags
  206  *   @handle: driver data
  207  *
  208  *   This function is similar to parport_register_device(), except
  209  *   that it locates a device by its number rather than by the port
  210  *   it is attached to.
  211  *
  212  *   All parameters except for @devnum are the same as for
  213  *   parport_register_device().  The return value is the same as
  214  *   for parport_register_device().
  215  **/
  216 
 
  217 struct pardevice *parport_open (int devnum, const char *name,
  218             int (*pf) (void *), void (*kf) (void *),
  219             void (*irqf) (int, void *, struct pt_regs *),
  220             int flags, void *handle)
  221 {
  222    struct daisydev *p = topology;
  223    struct parport *port;
  224    struct pardevice *dev;
  225    int daisy;
  226 
    227    spin_lock(&topology_lock);
    227   do
- 227   do-while (0)
- 227 do-while (0)
- 228    while (p && p->devnum != devnum)
 - 228   T && T
   228   T && F
 - 228   F && _
  229       p = p->next;
  230 
- 231    if (!p) {
    232       spin_unlock(&topology_lock);
    232     do
- 232     do-while (0)
- 232   do-while (0)
 - 233       return NULL;
  234    }
  235 
  236    daisy = p->daisy;
  237    port = parport_get_port(p->port);
    238    spin_unlock(&topology_lock);
    238   do
- 238   do-while (0)
- 238 do-while (0)
  239 
  240    dev = parport_register_device (port, name, pf, kf,
  241                    irqf, flags, handle);
  242    parport_put_port(port);
- 243    if (!dev)
 - 244       return NULL;
  245 
  246    dev->daisy = daisy;
  247 
  248    /* Check that there really is a device to select. */
- 249    if (daisy >= 0) {
  250       int selected;
  251       parport_claim_or_block (dev);
  252       selected = port->daisy;
  253       parport_release (dev);
  254 
- 255       if (selected != daisy) {
  256          /* No corresponding device. */
  257          parport_unregister_device (dev);
 - 258          return NULL;
  259       }
  260    }
  261 
   262    return dev;
  263 }
  264 
  265 /**
  266  *   parport_close - close a device opened with parport_open()
  267  *   @dev: device to close
  268  *
  269  *   This is to parport_open() as parport_unregister_device() is to
  270  *   parport_register_device().
  271  **/
  272 
 
  273 void parport_close (struct pardevice *dev)
  274 {
  275    parport_unregister_device (dev);
  276 }
  277 
  278 /**
  279  *   parport_device_num - convert device coordinates
  280  *   @parport: parallel port number
  281  *   @mux: multiplexor port number (-1 for no multiplexor)
  282  *   @daisy: daisy chain address (-1 for no daisy chain address)
  283  *
  284  *   This tries to locate a device on the given parallel port,
  285  *   multiplexor port and daisy chain address, and returns its
  286  *   device number or -NXIO if no device with those coordinates
  287  *   exists.
  288  **/
  289 
 
  290 int parport_device_num (int parport, int mux, int daisy)
  291 {
  292    int res = -ENXIO;
  293    struct daisydev *dev;
  294 
    295    spin_lock(&topology_lock);
    295   do
- 295   do-while (0)
- 295 do-while (0)
  296    dev = topology;
  297    while (dev && dev->port->portnum != parport &&
- 298           dev->port->muxport != mux && dev->daisy != daisy)
 - 298   T && T && T && T
 - 298   T && T && T && F
 - 298   T && T && F && _
   298   T && F && _ && _
 - 298   F && _ && _ && _
  299       dev = dev->next;
- 300    if (dev)
  301       res = dev->devnum;
    302    spin_unlock(&topology_lock);
    302   do
- 302   do-while (0)
- 302 do-while (0)
  303 
   304    return res;
  305 }
  306 
  307 /* Send a daisy-chain-style CPP command packet. */
 
  308 static int cpp_daisy (struct parport *port, int cmd)
  309 {
  310    unsigned char s;
  311 
  312    parport_data_forward (port);
    313    parport_write_data (port, 0xaa); udelay (2);
- 313 ternary-?: __builtin_constant_p ( 2 )
- 313 ternary-?: ( 2 ) > 20000
    314    parport_write_data (port, 0x55); udelay (2);
- 314 ternary-?: __builtin_constant_p ( 2 )
- 314 ternary-?: ( 2 ) > 20000
    315    parport_write_data (port, 0x00); udelay (2);
- 315 ternary-?: __builtin_constant_p ( 2 )
- 315 ternary-?: ( 2 ) > 20000
    316    parport_write_data (port, 0xff); udelay (2);
- 316 ternary-?: __builtin_constant_p ( 2 )
- 316 ternary-?: ( 2 ) > 20000
  317    s = parport_read_status (port) & (PARPORT_STATUS_BUSY
  318                  | PARPORT_STATUS_PAPEROUT
  319                  | PARPORT_STATUS_SELECT
  320                  | PARPORT_STATUS_ERROR);
  321    if (s != (PARPORT_STATUS_BUSY
  322         | PARPORT_STATUS_PAPEROUT
  323         | PARPORT_STATUS_SELECT
- 324         | PARPORT_STATUS_ERROR)) {
  325       DPRINTK (KERN_DEBUG "%s: cpp_daisy: aa5500ff(%02x)\n",
  326           port->name, s);
   327       return -ENXIO;
  328    }
  329 
    330    parport_write_data (port, 0x87); udelay (2);
- 330 ternary-?: __builtin_constant_p ( 2 )
- 330 ternary-?: ( 2 ) > 20000
  331    s = parport_read_status (port) & (PARPORT_STATUS_BUSY
  332                  | PARPORT_STATUS_PAPEROUT
  333                  | PARPORT_STATUS_SELECT
  334                  | PARPORT_STATUS_ERROR);
- 335    if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) {
  336       DPRINTK (KERN_DEBUG "%s: cpp_daisy: aa5500ff87(%02x)\n",
  337           port->name, s);
 - 338       return -ENXIO;
  339    }
  340 
    341    parport_write_data (port, 0x78); udelay (2);
- 341 ternary-?: __builtin_constant_p ( 2 )
- 341 ternary-?: ( 2 ) > 20000
    342    parport_write_data (port, cmd); udelay (2);
- 342 ternary-?: __builtin_constant_p ( 2 )
- 342 ternary-?: ( 2 ) > 20000
  343    parport_frob_control (port,
  344                PARPORT_CONTROL_STROBE,
  345                PARPORT_CONTROL_STROBE);
    346    udelay (1);
- 346 ternary-?: __builtin_constant_p ( 1 )
- 346 ternary-?: ( 1 ) > 20000
  347    s = parport_read_status (port);
  348    parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
    349    udelay (1);
- 349 ternary-?: __builtin_constant_p ( 1 )
- 349 ternary-?: ( 1 ) > 20000
    350    parport_write_data (port, 0xff); udelay (2);
- 350 ternary-?: __builtin_constant_p ( 2 )
- 350 ternary-?: ( 2 ) > 20000
  351 
 - 352    return s;
  353 }
  354 
  355 /* Send a mux-style CPP command packet. */
 
  356 static int cpp_mux (struct parport *port, int cmd)
  357 {
  358    unsigned char s;
  359    int rc;
  360 
  361    parport_data_forward (port);
    362    parport_write_data (port, 0xaa); udelay (2);
- 362 ternary-?: __builtin_constant_p ( 2 )
- 362 ternary-?: ( 2 ) > 20000
    363    parport_write_data (port, 0x55); udelay (2);
- 363 ternary-?: __builtin_constant_p ( 2 )
- 363 ternary-?: ( 2 ) > 20000
    364    parport_write_data (port, 0xf0); udelay (2);
- 364 ternary-?: __builtin_constant_p ( 2 )
- 364 ternary-?: ( 2 ) > 20000
    365    parport_write_data (port, 0x0f); udelay (2);
- 365 ternary-?: __builtin_constant_p ( 2 )
- 365 ternary-?: ( 2 ) > 20000
    366    parport_write_data (port, 0x52); udelay (2);
- 366 ternary-?: __builtin_constant_p ( 2 )
- 366 ternary-?: ( 2 ) > 20000
    367    parport_write_data (port, 0xad); udelay (2);
- 367 ternary-?: __builtin_constant_p ( 2 )
- 367 ternary-?: ( 2 ) > 20000
    368    parport_write_data (port, cmd); udelay (2);
- 368 ternary-?: __builtin_constant_p ( 2 )
- 368 ternary-?: ( 2 ) > 20000
  369 
  370    s = parport_read_status (port);
- 371    if (!(s & PARPORT_STATUS_ACK)) {
  372       DPRINTK (KERN_DEBUG "%s: cpp_mux: aa55f00f52ad%02x(%02x)\n",
  373           port->name, cmd, s);
 - 374       return -EIO;
  375    }
  376 
    377    rc = (((s & PARPORT_STATUS_SELECT   ? 1 : 0) << 0) |
- 377 ternary-?: s & 0x10
    378          ((s & PARPORT_STATUS_PAPEROUT ? 1 : 0) << 1) |
- 378 ternary-?: s & 0x20
    379          ((s & PARPORT_STATUS_BUSY     ? 0 : 1) << 2) |
- 379 ternary-?: s & 0x80
    380          ((s & PARPORT_STATUS_ERROR    ? 0 : 1) << 3));
- 380 ternary-?: s & 0x8
  381 
   382    return rc;
  383 }
  384 
 
  385 void parport_daisy_deselect_all (struct parport *port)
  386 {
  387    cpp_daisy (port, 0x30);
  388 }
  389 
 
- 390 int parport_daisy_select (struct parport *port, int daisy, int mode)
  391 {
    392    switch (mode)
  393    {
  394       // For these modes we should switch to EPP mode:
 - 395       case IEEE1284_MODE_EPP:
 - 396       case IEEE1284_MODE_EPPSL:
 - 397       case IEEE1284_MODE_EPPSWE:
  398          return !(cpp_daisy (port, 0x20 + daisy) &
 - 399              PARPORT_STATUS_ERROR);
  400 
  401       // For these modes we should switch to ECP mode:
 - 402       case IEEE1284_MODE_ECP:
 - 403       case IEEE1284_MODE_ECPRLE:
 - 404       case IEEE1284_MODE_ECPSWE: 
  405          return !(cpp_daisy (port, 0xd0 + daisy) &
 - 406              PARPORT_STATUS_ERROR);
  407 
  408       // Nothing was told for BECP in Daisy chain specification.
  409       // May be it's wise to use ECP?
 - 410       case IEEE1284_MODE_BECP:
  411       // Others use compat mode
 - 412       case IEEE1284_MODE_NIBBLE:
 - 413       case IEEE1284_MODE_BYTE:
 - 414       case IEEE1284_MODE_COMPAT:
 - 415       default: