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

1.1       misho       1: /*
                      2:  *     The PCI Library -- Capabilities
                      3:  *
                      4:  *     Copyright (c) 2008 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: static void
                     14: pci_add_cap(struct pci_dev *d, unsigned int addr, unsigned int id, unsigned int type)
                     15: {
                     16:   struct pci_cap *cap = pci_malloc(d->access, sizeof(*cap));
                     17: 
                     18:   cap->next = d->first_cap;
                     19:   d->first_cap = cap;
                     20:   cap->addr = addr;
                     21:   cap->id = id;
                     22:   cap->type = type;
                     23:   d->access->debug("%04x:%02x:%02x.%d: Found capability %04x of type %d at %04x\n",
                     24:     d->domain, d->bus, d->dev, d->func, id, type, addr);
                     25: }
                     26: 
                     27: static void
                     28: pci_scan_trad_caps(struct pci_dev *d)
                     29: {
                     30:   word status = pci_read_word(d, PCI_STATUS);
                     31:   byte been_there[256];
                     32:   int where;
                     33: 
                     34:   if (!(status & PCI_STATUS_CAP_LIST))
                     35:     return;
                     36: 
                     37:   memset(been_there, 0, 256);
                     38:   where = pci_read_byte(d, PCI_CAPABILITY_LIST) & ~3;
                     39:   while (where)
                     40:     {
                     41:       byte id = pci_read_byte(d, where + PCI_CAP_LIST_ID);
                     42:       byte next = pci_read_byte(d, where + PCI_CAP_LIST_NEXT) & ~3;
                     43:       if (been_there[where]++)
                     44:        break;
                     45:       if (id == 0xff)
                     46:        break;
                     47:       pci_add_cap(d, where, id, PCI_CAP_NORMAL);
                     48:       where = next;
                     49:     }
                     50: }
                     51: 
                     52: static void
                     53: pci_scan_ext_caps(struct pci_dev *d)
                     54: {
                     55:   byte been_there[0x1000];
                     56:   int where = 0x100;
                     57: 
                     58:   if (!pci_find_cap(d, PCI_CAP_ID_EXP, PCI_CAP_NORMAL))
                     59:     return;
                     60: 
                     61:   memset(been_there, 0, 0x1000);
                     62:   do
                     63:     {
                     64:       u32 header;
                     65:       int id;
                     66: 
                     67:       header = pci_read_long(d, where);
                     68:       if (!header || header == 0xffffffff)
                     69:        break;
                     70:       id = header & 0xffff;
                     71:       if (been_there[where]++)
                     72:        break;
                     73:       pci_add_cap(d, where, id, PCI_CAP_EXTENDED);
                     74:       where = (header >> 20) & ~3;
                     75:     }
                     76:   while (where);
                     77: }
                     78: 
                     79: unsigned int
                     80: pci_scan_caps(struct pci_dev *d, unsigned int want_fields)
                     81: {
                     82:   if ((want_fields & PCI_FILL_EXT_CAPS) && !(d->known_fields & PCI_FILL_CAPS))
                     83:     want_fields |= PCI_FILL_CAPS;
                     84: 
                     85:   if (want_fields & PCI_FILL_CAPS)
                     86:     pci_scan_trad_caps(d);
                     87:   if (want_fields & PCI_FILL_EXT_CAPS)
                     88:     pci_scan_ext_caps(d);
                     89:   return want_fields;
                     90: }
                     91: 
                     92: void
                     93: pci_free_caps(struct pci_dev *d)
                     94: {
                     95:   struct pci_cap *cap;
                     96: 
                     97:   while (cap = d->first_cap)
                     98:     {
                     99:       d->first_cap = cap->next;
                    100:       pci_mfree(cap);
                    101:     }
                    102: }
                    103: 
                    104: struct pci_cap *
                    105: pci_find_cap(struct pci_dev *d, unsigned int id, unsigned int type)
                    106: {
                    107:   struct pci_cap *c;
                    108: 
                    109:   pci_fill_info_v31(d, ((type == PCI_CAP_NORMAL) ? PCI_FILL_CAPS : PCI_FILL_EXT_CAPS));
                    110:   for (c=d->first_cap; c; c=c->next)
                    111:     if (c->type == type && c->id == id)
                    112:       return c;
                    113:   return NULL;
                    114: }

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