Annotation of embedaddon/pciutils/lib/generic.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *     The PCI Library -- Generic Direct Access Functions
                      3:  *
                      4:  *     Copyright (c) 1997--2000 Martin Mares <mj@ucw.cz>
                      5:  *
                      6:  *     Can be freely distributed and used under the terms of the GNU GPL.
                      7:  */
                      8: 
                      9: #include <string.h>
                     10: 
                     11: #include "internal.h"
                     12: 
                     13: void
                     14: pci_generic_scan_bus(struct pci_access *a, byte *busmap, int bus)
                     15: {
                     16:   int dev, multi, ht;
                     17:   struct pci_dev *t;
                     18: 
                     19:   a->debug("Scanning bus %02x for devices...\n", bus);
                     20:   if (busmap[bus])
                     21:     {
                     22:       a->warning("Bus %02x seen twice (firmware bug). Ignored.", bus);
                     23:       return;
                     24:     }
                     25:   busmap[bus] = 1;
                     26:   t = pci_alloc_dev(a);
                     27:   t->bus = bus;
                     28:   for (dev=0; dev<32; dev++)
                     29:     {
                     30:       t->dev = dev;
                     31:       multi = 0;
                     32:       for (t->func=0; !t->func || multi && t->func<8; t->func++)
                     33:        {
                     34:          u32 vd = pci_read_long(t, PCI_VENDOR_ID);
                     35:          struct pci_dev *d;
                     36: 
                     37:          if (!vd || vd == 0xffffffff)
                     38:            continue;
                     39:          ht = pci_read_byte(t, PCI_HEADER_TYPE);
                     40:          if (!t->func)
                     41:            multi = ht & 0x80;
                     42:          ht &= 0x7f;
                     43:          d = pci_alloc_dev(a);
                     44:          d->bus = t->bus;
                     45:          d->dev = t->dev;
                     46:          d->func = t->func;
                     47:          d->vendor_id = vd & 0xffff;
                     48:          d->device_id = vd >> 16U;
                     49:          d->known_fields = PCI_FILL_IDENT;
                     50:          d->hdrtype = ht;
                     51:          pci_link_dev(a, d);
                     52:          switch (ht)
                     53:            {
                     54:            case PCI_HEADER_TYPE_NORMAL:
                     55:              break;
                     56:            case PCI_HEADER_TYPE_BRIDGE:
                     57:            case PCI_HEADER_TYPE_CARDBUS:
                     58:              pci_generic_scan_bus(a, busmap, pci_read_byte(t, PCI_SECONDARY_BUS));
                     59:              break;
                     60:            default:
                     61:              a->debug("Device %04x:%02x:%02x.%d has unknown header type %02x.\n", d->domain, d->bus, d->dev, d->func, ht);
                     62:            }
                     63:        }
                     64:     }
                     65:   pci_free_dev(t);
                     66: }
                     67: 
                     68: void
                     69: pci_generic_scan(struct pci_access *a)
                     70: {
                     71:   byte busmap[256];
                     72: 
                     73:   memset(busmap, 0, sizeof(busmap));
                     74:   pci_generic_scan_bus(a, busmap, 0);
                     75: }
                     76: 
                     77: int
                     78: pci_generic_fill_info(struct pci_dev *d, int flags)
                     79: {
                     80:   struct pci_access *a = d->access;
                     81: 
                     82:   if ((flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE)) && d->hdrtype < 0)
                     83:     d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f;
                     84:   if (flags & PCI_FILL_IDENT)
                     85:     {
                     86:       d->vendor_id = pci_read_word(d, PCI_VENDOR_ID);
                     87:       d->device_id = pci_read_word(d, PCI_DEVICE_ID);
                     88:     }
                     89:   if (flags & PCI_FILL_CLASS)
                     90:       d->device_class = pci_read_word(d, PCI_CLASS_DEVICE);
                     91:   if (flags & PCI_FILL_IRQ)
                     92:     d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE);
                     93:   if (flags & PCI_FILL_BASES)
                     94:     {
                     95:       int cnt = 0, i;
                     96:       memset(d->base_addr, 0, sizeof(d->base_addr));
                     97:       switch (d->hdrtype)
                     98:        {
                     99:        case PCI_HEADER_TYPE_NORMAL:
                    100:          cnt = 6;
                    101:          break;
                    102:        case PCI_HEADER_TYPE_BRIDGE:
                    103:          cnt = 2;
                    104:          break;
                    105:        case PCI_HEADER_TYPE_CARDBUS:
                    106:          cnt = 1;
                    107:          break;
                    108:        }
                    109:       if (cnt)
                    110:        {
                    111:          for (i=0; i<cnt; i++)
                    112:            {
                    113:              u32 x = pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4);
                    114:              if (!x || x == (u32) ~0)
                    115:                continue;
                    116:              if ((x & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
                    117:                d->base_addr[i] = x;
                    118:              else
                    119:                {
                    120:                  if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != PCI_BASE_ADDRESS_MEM_TYPE_64)
                    121:                    d->base_addr[i] = x;
                    122:                  else if (i >= cnt-1)
                    123:                    a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", d->domain, d->bus, d->dev, d->func, i);
                    124:                  else
                    125:                    {
                    126:                      u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i)*4);
                    127: #ifdef PCI_HAVE_64BIT_ADDRESS
                    128:                      d->base_addr[i-1] = x | (((pciaddr_t) y) << 32);
                    129: #else
                    130:                      if (y)
                    131:                        a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.", d->domain, d->bus, d->dev, d->func);
                    132:                      else
                    133:                        d->base_addr[i-1] = x;
                    134: #endif
                    135:                    }
                    136:                }
                    137:            }
                    138:        }
                    139:     }
                    140:   if (flags & PCI_FILL_ROM_BASE)
                    141:     {
                    142:       int reg = 0;
                    143:       d->rom_base_addr = 0;
                    144:       switch (d->hdrtype)
                    145:        {
                    146:        case PCI_HEADER_TYPE_NORMAL:
                    147:          reg = PCI_ROM_ADDRESS;
                    148:          break;
                    149:        case PCI_HEADER_TYPE_BRIDGE:
                    150:          reg = PCI_ROM_ADDRESS1;
                    151:          break;
                    152:        }
                    153:       if (reg)
                    154:        {
                    155:          u32 u = pci_read_long(d, reg);
                    156:          if (u != 0xffffffff)
                    157:            d->rom_base_addr = u;
                    158:        }
                    159:     }
                    160:   if (flags & (PCI_FILL_CAPS | PCI_FILL_EXT_CAPS))
                    161:     flags |= pci_scan_caps(d, flags);
                    162:   return flags & ~PCI_FILL_SIZES;
                    163: }
                    164: 
                    165: static int
                    166: pci_generic_block_op(struct pci_dev *d, int pos, byte *buf, int len,
                    167:                 int (*r)(struct pci_dev *d, int pos, byte *buf, int len))
                    168: {
                    169:   if ((pos & 1) && len >= 1)
                    170:     {
                    171:       if (!r(d, pos, buf, 1))
                    172:        return 0;
                    173:       pos++; buf++; len--;
                    174:     }
                    175:   if ((pos & 3) && len >= 2)
                    176:     {
                    177:       if (!r(d, pos, buf, 2))
                    178:        return 0;
                    179:       pos += 2; buf += 2; len -= 2;
                    180:     }
                    181:   while (len >= 4)
                    182:     {
                    183:       if (!r(d, pos, buf, 4))
                    184:        return 0;
                    185:       pos += 4; buf += 4; len -= 4;
                    186:     }
                    187:   if (len >= 2)
                    188:     {
                    189:       if (!r(d, pos, buf, 2))
                    190:        return 0;
                    191:       pos += 2; buf += 2; len -= 2;
                    192:     }
                    193:   if (len && !r(d, pos, buf, 1))
                    194:     return 0;
                    195:   return 1;
                    196: }
                    197: 
                    198: int
                    199: pci_generic_block_read(struct pci_dev *d, int pos, byte *buf, int len)
                    200: {
                    201:   return pci_generic_block_op(d, pos, buf, len, d->access->methods->read);
                    202: }
                    203: 
                    204: int
                    205: pci_generic_block_write(struct pci_dev *d, int pos, byte *buf, int len)
                    206: {
                    207:   return pci_generic_block_op(d, pos, buf, len, d->access->methods->write);
                    208: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>