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

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


File: drivers/pcmcia/cardbus.c
Instrumentation mode: function-decision-multicondition
TER: 0 % ( 0/ 84)

Start/ End/    
True False - Line Source

  1 /*
  2  * cardbus.c -- 16-bit PCMCIA core support
  3  *
  4  * This program is free software; you can redistribute it and/or modify
  5  * it under the terms of the GNU General Public License version 2 as
  6  * published by the Free Software Foundation.
  7  *
  8  * The initial developer of the original code is David A. Hinds
  9  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  10  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  11  *
  12  * (C) 1999      David A. Hinds
  13  */
  14 
  15 /*
  16  * Cardbus handling has been re-written to be more of a PCI bridge thing,
  17  * and the PCI code basically does all the resource handling.
  18  *
  19  *      Linus, Jan 2000
  20  */
  21 
  22 
  23 #include <linux/module.h>
  24 #include <linux/kernel.h>
  25 #include <linux/string.h>
  26 #include <linux/slab.h>
  27 #include <linux/mm.h>
  28 #include <linux/pci.h>
  29 #include <linux/ioport.h>
  30 #include <asm/irq.h>
  31 #include <asm/io.h>
  32 
  33 #define IN_CARD_SERVICES
  34 #include <pcmcia/cs_types.h>
  35 #include <pcmcia/ss.h>
  36 #include <pcmcia/cs.h>
  37 #include <pcmcia/bulkmem.h>
  38 #include <pcmcia/cistpl.h>
  39 #include "cs_internal.h"
  40 
  41 /*====================================================================*/
  42 
  43 #define FIND_FIRST_BIT(n)   ((n) - ((n) & ((n)-1)))
  44 
  45 /* Offsets in the Expansion ROM Image Header */
  46 #define ROM_SIGNATURE      0x0000   /* 2 bytes */
  47 #define ROM_DATA_PTR      0x0018   /* 2 bytes */
  48 
  49 /* Offsets in the CardBus PC Card Data Structure */
  50 #define PCDATA_SIGNATURE   0x0000   /* 4 bytes */
  51 #define PCDATA_VPD_PTR      0x0008   /* 2 bytes */
  52 #define PCDATA_LENGTH      0x000a   /* 2 bytes */
  53 #define PCDATA_REVISION      0x000c
  54 #define PCDATA_IMAGE_SZ      0x0010   /* 2 bytes */
  55 #define PCDATA_ROM_LEVEL   0x0012   /* 2 bytes */
  56 #define PCDATA_CODE_TYPE   0x0014
  57 #define PCDATA_INDICATOR   0x0015
  58 
  59 /*=====================================================================
  60 
  61     Expansion ROM's have a special layout, and pointers specify an
  62     image number and an offset within that image.  xlate_rom_addr()
  63     converts an image/offset address to an absolute offset from the
  64     ROM's base address.
  65     
  66 =====================================================================*/
  67 
 
- 68 static u_int xlate_rom_addr(void __iomem *b, u_int addr)
  69 {
  70    u_int img = 0, ofs = 0, sz;
  71    u_short data;
- 72    while ((readb(b) == 0x55) && (readb(b + 1) == 0xaa)) {
 - 72   (T) && (T)
 - 72   (T) && (F)
 - 72   (F) && (_)
- 73       if (img == (addr >> 28))
 - 74          return (addr & 0x0fffffff) + ofs;
  75       data = readb(b + ROM_DATA_PTR) + (readb(b + ROM_DATA_PTR + 1) << 8);
  76       sz = 512 * (readb(b + data + PCDATA_IMAGE_SZ) +
  77              (readb(b + data + PCDATA_IMAGE_SZ + 1) << 8));
- 78       if ((sz == 0) || (readb(b + data + PCDATA_INDICATOR) & 0x80))
 - 78     (T) || (_)
 - 78     (F) || (T)
 - 78     (F) || (F)
 - 79          break;
  80       b += sz;
  81       ofs += sz;
  82       img++;
  83    }
 - 84    return 0;
  85 }
  86 
  87 /*=====================================================================
  88 
  89     These are similar to setup_cis_mem and release_cis_mem for 16-bit
  90     cards.  The "result" that is used externally is the cb_cis_virt
  91     pointer in the struct pcmcia_socket structure.
  92     
  93 =====================================================================*/
  94 
 
- 95 static void cb_release_cis_mem(struct pcmcia_socket * s)
  96 {
- 97    if (s->cb_cis_virt) {
    98       cs_dbg(s, 1, "cb_release_cis_mem()\n");
- 98   do-while (0)
  99       iounmap(s->cb_cis_virt);
  100       s->cb_cis_virt = NULL;
  101       s->cb_cis_res = NULL;
  102    }
  103 }
  104 
 
- 105 static int cb_setup_cis_mem(struct pcmcia_socket * s, struct resource *res)
  106 {
  107    unsigned int start, size;
  108 
- 109    if (res == s->cb_cis_res)
 - 110       return 0;
  111 
- 112    if (s->cb_cis_res)
  113       cb_release_cis_mem(s);
  114 
  115    start = res->start;
  116    size = res->end - start + 1;
  117    s->cb_cis_virt = ioremap(start, size);
  118 
- 119    if (!s->cb_cis_virt)
 - 120       return -1;
  121 
  122    s->cb_cis_res = res;
  123 
 - 124    return 0;
  125 }
  126 
  127 /*=====================================================================
  128 
  129     This is used by the CIS processing code to read CIS information
  130     from a CardBus device.
  131     
  132 =====================================================================*/
  133 
 
- 134 int read_cb_mem(struct pcmcia_socket * s, int space, u_int addr, u_int len, void *ptr)
  135 {
  136    struct pci_dev *dev;
  137    struct resource *res;
  138 
    139    cs_dbg(s, 3, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
- 139 do-while (0)
  140 
  141    dev = pci_find_slot(s->cb_dev->subordinate->number, 0);
- 142    if (!dev)
 - 143       goto fail;
  144 
  145    /* Config space? */
- 146    if (space == 0) {
- 147       if (addr + len > 0x100)
 - 148          goto fail;
- 149       for (; len; addr++, ptr++, len--)
  150          pci_read_config_byte(dev, addr, ptr);
 - 151       return 0;
  152    }
  153 
  154    res = dev->resource + space - 1;
- 155    if (!res->flags)
 - 156       goto fail;
  157 
- 158    if (cb_setup_cis_mem(s, res) != 0)
 - 159       goto fail;
  160 
- 161    if (space == 7) {
  162       addr = xlate_rom_addr(s->cb_cis_virt, addr);
- 163       if (addr == 0)
 - 164          goto fail;
  165    }
  166 
- 167    if (addr + len > res->end - res->start)
 - 168       goto fail;
  169 
  170    memcpy_fromio(ptr, s->cb_cis_virt + addr, len);
 - 171    return 0;
  172 
  173 fail:
  174    memset(ptr, 0xff, len);
 - 175    return -1;
  176 }
  177 
  178 /*=====================================================================
  179 
  180     cb_alloc() and cb_free() allocate and free the kernel data
  181     structures for a Cardbus device, and handle the lowest level PCI
  182     device setup issues.
  183     
  184 =====================================================================*/
  185 
  186 /*
  187  * Since there is only one interrupt available to CardBus
  188  * devices, all devices downstream of this device must
  189  * be using this IRQ.
  190  */
 
- 191 static void cardbus_assign_irqs(struct pci_bus *bus, int irq)
  192 {
  193    struct pci_dev *dev;
  194 
- 195    list_for_each_entry(dev, &bus->devices, bus_list) {
  196       u8 irq_pin;
  197 
  198       pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
- 199       if (irq_pin) {
  200          dev->irq = irq;
  201          pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
  202       }
  203 
- 204       if (dev->subordinate)
  205          cardbus_assign_irqs(dev->subordinate, irq);
  206    }
  207 }
  208 
 
- 209 int cb_alloc(struct pcmcia_socket * s)
  210 {
  211    struct pci_bus *bus = s->cb_dev->subordinate;
  212    struct pci_dev *dev;
  213    unsigned int max, pass;
  214 
  215    s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0));
  216 //   pcibios_fixup_bus(bus);
  217 
  218    max = bus->secondary;
- 219    for (pass = 0; pass < 2; pass++)
- 220       list_for_each_entry(dev, &bus->devices, bus_list)
  221          if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
- 222              dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
 - 222       T || _
 - 222       F || T
 - 222       F || F
  223             max = pci_scan_bridge(bus, dev, max, pass);
  224 
  225    /*
  226     * Size all resources below the CardBus controller.
  227     */
  228    pci_bus_size_bridges(bus);
  229    pci_bus_assign_resources(bus);
  230    cardbus_assign_irqs(bus, s->pci_irq);
  231 
  232    /* socket specific tune function */
- 233    if (s->tune_bridge)
  234       s->tune_bridge(s, bus);
  235 
  236    pci_enable_bridges(bus);
  237    pci_bus_add_devices(bus);
  238 
  239    s->irq.AssignedIRQ = s->pci_irq;
 - 240    return CS_SUCCESS;
  241 }
  242 
 
- 243 void cb_free(struct pcmcia_socket * s)
  244 {
  245    struct pci_dev *bridge = s->cb_dev;
  246 
  247    cb_release_cis_mem(s);
  248 
- 249    if (bridge)
  250       pci_remove_behind_bridge(bridge);
  251 }
***TER 0% (0/84) of SOURCE FILE cardbus.c

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