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

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


File: arch/x86_64/pci/../../i386/pci/direct.c
Instrumentation mode: function-decision-multicondition
TER: 27 % ( 54/203)

Start/ End/    
True False - Line Source

  1 /*
  2  * direct.c - Low-level direct PCI config space access
  3  */
  4 
  5 #include <linux/pci.h>
  6 #include <linux/init.h>
  7 #include "pci.h"
  8 
  9 /*
  10  * Functions for accessing PCI configuration space with type 1 accesses
  11  */
  12 
  13 #define PCI_CONF1_ADDRESS(bus, devfn, reg) \
  14    (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
  15 
 
151778   16 int pci_conf1_read(unsigned int seg, unsigned int bus,
  17            unsigned int devfn, int reg, int len, u32 *value)
  18 {
  19    unsigned long flags;
  20 
151778 - 21    if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
 - 21   T || (_) || (_) || (_)
 - 21   F || (T) || (_) || (_)
 - 21   F || (F) || (T) || (_)
 - 21   F || (F) || (F) || (T)
 151778   21   F || (F) || (F) || (F)
 - 22       return -EINVAL;
  23 
    24    spin_lock_irqsave(&pci_config_lock, flags);
    24   do
    24     do
151778 - 24     do-while (0)
151778 - 24   do-while (0)
    24   do
    24     do
151778 - 24     do-while (0)
151778 - 24   do-while (0)
151778 - 24 do-while (0)
  25 
  26    outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);
  27 
    28    switch (len) {
2718    29    case 1:
  30       *value = inb(0xCFC + (reg & 3));
2718    31       break;
1554    32    case 2:
  33       *value = inw(0xCFC + (reg & 2));
1554    34       break;
147506    35    case 4:
  36       *value = inl(0xCFC);
147506    37       break;
  38    }
  39 
    40    spin_unlock_irqrestore(&pci_config_lock, flags);
    40   do
    40     do
151778 - 40     do-while (0)
151778 - 40   do-while (0)
151778 - 40 do-while (0)
  41 
151778    42    return 0;
  43 }
  44 
 
377546   45 int pci_conf1_write(unsigned int seg, unsigned int bus,
  46             unsigned int devfn, int reg, int len, u32 value)
  47 {
  48    unsigned long flags;
  49 
377546 - 50    if ((bus > 255) || (devfn > 255) || (reg > 255)) 
 - 50   (T) || (_) || (_)
 - 50   (F) || (T) || (_)
 - 50   (F) || (F) || (T)
 377546   50   (F) || (F) || (F)
 - 51       return -EINVAL;
  52 
    53    spin_lock_irqsave(&pci_config_lock, flags);
    53   do
    53     do
377546 - 53     do-while (0)
377546 - 53   do-while (0)
    53   do
    53     do
377546 - 53     do-while (0)
377546 - 53   do-while (0)
377546 - 53 do-while (0)
  54 
  55    outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);
  56 
    57    switch (len) {
228    58    case 1:
  59       outb((u8)value, 0xCFC + (reg & 3));
228    60       break;
240    61    case 2:
  62       outw((u16)value, 0xCFC + (reg & 2));
240    63       break;
377078    64    case 4:
  65       outl((u32)value, 0xCFC);
377078    66       break;
  67    }
  68 
    69    spin_unlock_irqrestore(&pci_config_lock, flags);
    69   do
    69     do
377546 - 69     do-while (0)
377546 - 69   do-while (0)
377546 - 69 do-while (0)
  70 
377546    71    return 0;
  72 }
  73 
  74 #undef PCI_CONF1_ADDRESS
  75 
  76 struct pci_raw_ops pci_direct_conf1 = {
  77    .read =      pci_conf1_read,
  78    .write =   pci_conf1_write,
  79 };
  80 
  81 
  82 /*
  83  * Functions for accessing PCI configuration space with type 2 accesses
  84  */
  85 
  86 #define PCI_CONF2_ADDRESS(dev, reg)   (u16)(0xC000 | (dev << 8) | reg)
  87 
 
- 88 static int pci_conf2_read(unsigned int seg, unsigned int bus,
  89            unsigned int devfn, int reg, int len, u32 *value)
  90 {
  91    unsigned long flags;
  92    int dev, fn;
  93 
- 94    if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
 - 94   T || (_) || (_) || (_)
 - 94   F || (T) || (_) || (_)
 - 94   F || (F) || (T) || (_)
 - 94   F || (F) || (F) || (T)
 - 94   F || (F) || (F) || (F)
 - 95       return -EINVAL;
  96 
  97    dev = PCI_SLOT(devfn);
  98    fn = PCI_FUNC(devfn);
  99 
- 100    if (dev & 0x10) 
 - 101       return PCIBIOS_DEVICE_NOT_FOUND;
  102 
    103    spin_lock_irqsave(&pci_config_lock, flags);
    103   do
    103     do
- 103     do-while (0)
- 103   do-while (0)
    103   do
    103     do
- 103     do-while (0)
- 103   do-while (0)
- 103 do-while (0)
  104 
  105    outb((u8)(0xF0 | (fn << 1)), 0xCF8);
  106    outb((u8)bus, 0xCFA);
  107 
    108    switch (len) {
 - 109    case 1:
  110       *value = inb(PCI_CONF2_ADDRESS(dev, reg));
 - 111       break;
 - 112    case 2:
  113       *value = inw(PCI_CONF2_ADDRESS(dev, reg));
 - 114       break;
 - 115    case 4:
  116       *value = inl(PCI_CONF2_ADDRESS(dev, reg));
 - 117       break;
  118    }
  119 
  120    outb(0, 0xCF8);
  121 
    122    spin_unlock_irqrestore(&pci_config_lock, flags);
    122   do
    122     do
- 122     do-while (0)
- 122   do-while (0)
- 122 do-while (0)
  123 
 - 124    return 0;
  125 }
  126 
 
- 127 static int pci_conf2_write(unsigned int seg, unsigned int bus,
  128             unsigned int devfn, int reg, int len, u32 value)
  129 {
  130    unsigned long flags;
  131    int dev, fn;
  132 
- 133    if ((bus > 255) || (devfn > 255) || (reg > 255)) 
 - 133   (T) || (_) || (_)
 - 133   (F) || (T) || (_)
 - 133   (F) || (F) || (T)
 - 133   (F) || (F) || (F)
 - 134       return -EINVAL;
  135 
  136    dev = PCI_SLOT(devfn);
  137    fn = PCI_FUNC(devfn);
  138 
- 139    if (dev & 0x10) 
 - 140       return PCIBIOS_DEVICE_NOT_FOUND;
  141 
    142    spin_lock_irqsave(&pci_config_lock, flags);
    142   do
    142     do
- 142     do-while (0)
- 142   do-while (0)
    142   do
    142     do
- 142     do-while (0)
- 142   do-while (0)
- 142 do-while (0)
  143 
  144    outb((u8)(0xF0 | (fn << 1)), 0xCF8);
  145    outb((u8)bus, 0xCFA);
  146 
    147    switch (len) {
 - 148    case 1:
  149       outb((u8)value, PCI_CONF2_ADDRESS(dev, reg));
 - 150       break;
 - 151    case 2:
  152       outw((u16)value, PCI_CONF2_ADDRESS(dev, reg));
 - 153       break;
 - 154    case 4:
  155       outl((u32)value, PCI_CONF2_ADDRESS(dev, reg));
 - 156       break;
  157    }
  158 
  159    outb(0, 0xCF8);    
  160 
    161    spin_unlock_irqrestore(&pci_config_lock, flags);
    161   do
    161     do
- 161     do-while (0)
- 161   do-while (0)
- 161 do-while (0)
  162 
 - 163    return 0;
  164 }
  165 
  166 #undef PCI_CONF2_ADDRESS
  167 
  168 static struct pci_raw_ops pci_direct_conf2 = {
  169    .read =      pci_conf2_read,
  170    .write =   pci_conf2_write,
  171 };
  172 
  173 
  174 /*
  175  * Before we decide to use direct hardware access mechanisms, we try to do some
  176  * trivial checks to ensure it at least _seems_ to be working -- we just test
  177  * whether bus 00 contains a host bridge (this is similar to checking
  178  * techniques used in XFree86, but ours should be more reliable since we
  179  * attempt to make use of direct access hints provided by the PCI BIOS).
  180  *
  181  * This should be close to trivial, but it isn't, because there are buggy
  182  * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
  183  */
 
  184 static int __init pci_sanity_check(struct pci_raw_ops *o)
  185 {
  186    u32 x = 0;
  187    int devfn;
  188 
- 189    if (pci_probe & PCI_NO_CHECKS)
 - 190       return 1;
  191 
- 192    for (devfn = 0; devfn < 0x100; devfn++) {
- 193       if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x))
 - 194          continue;
- 195       if (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)
   195     T || _
 - 195     F || T
 - 195     F || F
   196          return 1;
  197 
- 198       if (o->read(0, 0, devfn, PCI_VENDOR_ID, 2, &x))
 - 199          continue;
- 200       if (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)
 - 200     T || _
 - 200     F || T
 - 200     F || F
 - 201          return 1;
  202    }
  203 
  204    DBG(KERN_WARNING "PCI: Sanity check failed\n");
 - 205    return 0;
  206 }
  207 
 
  208 static int __init pci_check_type1(void)
  209 {
  210    unsigned long flags;
  211    unsigned int tmp;
  212    int works = 0;
  213 
    214    local_irq_save(flags);
    214   do
- 214   do-while (0)
- 214 do-while (0)
  215 
  216    outb(0x01, 0xCFB);
  217    tmp = inl(0xCF8);
  218    outl(0x80000000, 0xCF8);
- 219    if (inl(0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) {
   219   T && T
 - 219   T && F
 - 219   F && _
  220       works = 1;
  221    }
  222    outl(tmp, 0xCF8);
  223    local_irq_restore(flags);
  224 
   225    return works;
  226 }
  227 
 
- 228 static int __init pci_check_type2(void)
  229 {
  230    unsigned long flags;
  231    int works = 0;
  232 
    233    local_irq_save(flags);
    233   do
- 233   do-while (0)
- 233 do-while (0)
  234 
  235    outb(0x00, 0xCFB);
  236    outb(0x00, 0xCF8);
  237    outb(0x00, 0xCFA);
  238    if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00 &&
- 239        pci_sanity_check(&pci_direct_conf2)) {
 - 239   T && T && T
 - 239   T && T && F
 - 239   T && F && _
 - 239   F && _ && _
  240       works = 1;
  241    }
  242 
  243    local_irq_restore(flags);
  244 
 - 245    return works;
  246 }
  247 
 
  248 static int __init pci_direct_init(void)
  249 {
  250    struct resource *region, *region2;
  251 
- 252    if ((pci_probe & PCI_PROBE_CONF1) == 0)
 - 253       goto type2;
  254    region = request_region(0xCF8, 8, "PCI conf1");
- 255    if (!region)
 - 256       goto type2;
  257 
- 258    if (pci_check_type1()) {
  259       printk(KERN_INFO "PCI: Using configuration type 1\n");
  260       raw_pci_ops = &pci_direct_conf1;
   261       return 0;
  262    }
  263    release_resource(region);
  264 
  265  type2:
- 266    if ((pci_probe & PCI_PROBE_CONF2) == 0)
 - 267       goto out;
  268    region = request_region(0xCF8, 4, "PCI conf2");
- 269    if (!region)
 - 270       goto out;
  271    region2 = request_region(0xC000, 0x1000, "PCI conf2");
- 272    if (!region2)
 - 273       goto fail2;
  274 
- 275    if (pci_check_type2()) {
  276       printk(KERN_INFO "PCI: Using configuration type 2\n");
  277       raw_pci_ops = &pci_direct_conf2;
 - 278       return 0;
  279    }
  280 
  281    release_resource(region2);
  282  fail2:
  283    release_resource(region);
  284 
  285  out:
 - 286    return 0;
  287 }
  288 
  289 arch_initcall(pci_direct_init);
***TER 27% (54/203) of SOURCE FILE direct.c

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