Annotation of embedaddon/pciutils/lib/generic.c, revision 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>