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

1.1       misho       1: /*
                      2:  *     The PCI Library -- ID to Name Translation
                      3:  *
                      4:  *     Copyright (c) 1997--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 <stdio.h>
                     10: #include <stdarg.h>
                     11: #include <string.h>
                     12: 
                     13: #include "internal.h"
                     14: #include "names.h"
                     15: 
                     16: static char *id_lookup(struct pci_access *a, int flags, int cat, int id1, int id2, int id3, int id4)
                     17: {
                     18:   char *name;
                     19: 
                     20:   while (!(name = pci_id_lookup(a, flags, cat, id1, id2, id3, id4)))
                     21:     {
                     22:       if ((flags & PCI_LOOKUP_CACHE) && !a->id_cache_status)
                     23:        {
                     24:          if (pci_id_cache_load(a, flags))
                     25:            continue;
                     26:        }
                     27:       if (flags & PCI_LOOKUP_NETWORK)
                     28:         {
                     29:          if (name = pci_id_net_lookup(a, cat, id1, id2, id3, id4))
                     30:            {
                     31:              pci_id_insert(a, cat, id1, id2, id3, id4, name, SRC_NET);
                     32:              pci_mfree(name);
                     33:              pci_id_cache_dirty(a);
                     34:            }
                     35:          else
                     36:            pci_id_insert(a, cat, id1, id2, id3, id4, "", SRC_NET);
                     37:          /* We want to iterate the lookup to get the allocated ID entry from the hash */
                     38:          continue;
                     39:        }
                     40:       return NULL;
                     41:     }
                     42:   return (name[0] ? name : NULL);
                     43: }
                     44: 
                     45: static char *
                     46: id_lookup_subsys(struct pci_access *a, int flags, int iv, int id, int isv, int isd)
                     47: {
                     48:   char *d = NULL;
                     49:   if (iv > 0 && id > 0)                                                /* Per-device lookup */
                     50:     d = id_lookup(a, flags, ID_SUBSYSTEM, iv, id, isv, isd);
                     51:   if (!d)                                                      /* Generic lookup */
                     52:     d = id_lookup(a, flags, ID_GEN_SUBSYSTEM, isv, isd, 0, 0);
                     53:   if (!d && iv == isv && id == isd)                            /* Check for subsystem == device */
                     54:     d = id_lookup(a, flags, ID_DEVICE, iv, id, 0, 0);
                     55:   return d;
                     56: }
                     57: 
                     58: static char *
                     59: format_name(char *buf, int size, int flags, char *name, char *num, char *unknown)
                     60: {
                     61:   int res;
                     62:   if ((flags & PCI_LOOKUP_NO_NUMBERS) && !name)
                     63:     return NULL;
                     64:   else if (flags & PCI_LOOKUP_NUMERIC)
                     65:     res = snprintf(buf, size, "%s", num);
                     66:   else if (!name)
                     67:     res = snprintf(buf, size, ((flags & PCI_LOOKUP_MIXED) ? "%s [%s]" : "%s %s"), unknown, num);
                     68:   else if (!(flags & PCI_LOOKUP_MIXED))
                     69:     res = snprintf(buf, size, "%s", name);
                     70:   else
                     71:     res = snprintf(buf, size, "%s [%s]", name, num);
                     72:   if (res >= size && size >= 4)
                     73:     buf[size-2] = buf[size-3] = buf[size-4] = '.';
                     74:   else if (res < 0 || res >= size)
                     75:     return "<pci_lookup_name: buffer too small>";
                     76:   return buf;
                     77: }
                     78: 
                     79: static char *
                     80: format_name_pair(char *buf, int size, int flags, char *v, char *d, char *num)
                     81: {
                     82:   int res;
                     83:   if ((flags & PCI_LOOKUP_NO_NUMBERS) && (!v || !d))
                     84:     return NULL;
                     85:   if (flags & PCI_LOOKUP_NUMERIC)
                     86:     res = snprintf(buf, size, "%s", num);
                     87:   else if (flags & PCI_LOOKUP_MIXED)
                     88:     {
                     89:       if (v && d)
                     90:        res = snprintf(buf, size, "%s %s [%s]", v, d, num);
                     91:       else if (!v)
                     92:        res = snprintf(buf, size, "Device [%s]", num);
                     93:       else /* v && !d */
                     94:        res = snprintf(buf, size, "%s Device [%s]", v, num);
                     95:     }
                     96:   else
                     97:     {
                     98:       if (v && d)
                     99:        res = snprintf(buf, size, "%s %s", v, d);
                    100:       else if (!v)
                    101:        res = snprintf(buf, size, "Device %s", num);
                    102:       else /* v && !d */
                    103:        res = snprintf(buf, size, "%s Device %s", v, num+5);
                    104:     }
                    105:   if (res >= size && size >= 4)
                    106:     buf[size-2] = buf[size-3] = buf[size-4] = '.';
                    107:   else if (res < 0 || res >= size)
                    108:     return "<pci_lookup_name: buffer too small>";
                    109:   return buf;
                    110: }
                    111: 
                    112: char *
                    113: pci_lookup_name(struct pci_access *a, char *buf, int size, int flags, ...)
                    114: {
                    115:   va_list args;
                    116:   char *v, *d, *cls, *pif;
                    117:   int iv, id, isv, isd, icls, ipif;
                    118:   char numbuf[16], pifbuf[32];
                    119: 
                    120:   va_start(args, flags);
                    121: 
                    122:   flags |= a->id_lookup_mode;
                    123:   if (!(flags & PCI_LOOKUP_NO_NUMBERS))
                    124:     {
                    125:       if (a->numeric_ids > 1)
                    126:        flags |= PCI_LOOKUP_MIXED;
                    127:       else if (a->numeric_ids)
                    128:        flags |= PCI_LOOKUP_NUMERIC;
                    129:     }
                    130:   if (flags & PCI_LOOKUP_MIXED)
                    131:     flags &= ~PCI_LOOKUP_NUMERIC;
                    132: 
                    133:   if (!a->id_hash && !(flags & (PCI_LOOKUP_NUMERIC | PCI_LOOKUP_SKIP_LOCAL)) && !a->id_load_failed)
                    134:     pci_load_name_list(a);
                    135: 
                    136:   switch (flags & 0xffff)
                    137:     {
                    138:     case PCI_LOOKUP_VENDOR:
                    139:       iv = va_arg(args, int);
                    140:       sprintf(numbuf, "%04x", iv);
                    141:       return format_name(buf, size, flags, id_lookup(a, flags, ID_VENDOR, iv, 0, 0, 0), numbuf, "Vendor");
                    142:     case PCI_LOOKUP_DEVICE:
                    143:       iv = va_arg(args, int);
                    144:       id = va_arg(args, int);
                    145:       sprintf(numbuf, "%04x", id);
                    146:       return format_name(buf, size, flags, id_lookup(a, flags, ID_DEVICE, iv, id, 0, 0), numbuf, "Device");
                    147:     case PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE:
                    148:       iv = va_arg(args, int);
                    149:       id = va_arg(args, int);
                    150:       sprintf(numbuf, "%04x:%04x", iv, id);
                    151:       v = id_lookup(a, flags, ID_VENDOR, iv, 0, 0, 0);
                    152:       d = id_lookup(a, flags, ID_DEVICE, iv, id, 0, 0);
                    153:       return format_name_pair(buf, size, flags, v, d, numbuf);
                    154:     case PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR:
                    155:       isv = va_arg(args, int);
                    156:       sprintf(numbuf, "%04x", isv);
                    157:       v = id_lookup(a, flags, ID_VENDOR, isv, 0, 0, 0);
                    158:       return format_name(buf, size, flags, v, numbuf, "Unknown vendor");
                    159:     case PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_DEVICE:
                    160:       iv = va_arg(args, int);
                    161:       id = va_arg(args, int);
                    162:       isv = va_arg(args, int);
                    163:       isd = va_arg(args, int);
                    164:       sprintf(numbuf, "%04x", isd);
                    165:       return format_name(buf, size, flags, id_lookup_subsys(a, flags, iv, id, isv, isd), numbuf, "Device");
                    166:     case PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE | PCI_LOOKUP_SUBSYSTEM:
                    167:       iv = va_arg(args, int);
                    168:       id = va_arg(args, int);
                    169:       isv = va_arg(args, int);
                    170:       isd = va_arg(args, int);
                    171:       v = id_lookup(a, flags, ID_VENDOR, isv, 0, 0, 0);
                    172:       d = id_lookup_subsys(a, flags, iv, id, isv, isd);
                    173:       sprintf(numbuf, "%04x:%04x", isv, isd);
                    174:       return format_name_pair(buf, size, flags, v, d, numbuf);
                    175:     case PCI_LOOKUP_CLASS:
                    176:       icls = va_arg(args, int);
                    177:       sprintf(numbuf, "%04x", icls);
                    178:       cls = id_lookup(a, flags, ID_SUBCLASS, icls >> 8, icls & 0xff, 0, 0);
                    179:       if (!cls && (cls = id_lookup(a, flags, ID_CLASS, icls >> 8, 0, 0, 0)))
                    180:        {
                    181:          if (!(flags & PCI_LOOKUP_NUMERIC)) /* Include full class number */
                    182:            flags |= PCI_LOOKUP_MIXED;
                    183:        }
                    184:       return format_name(buf, size, flags, cls, numbuf, "Class");
                    185:     case PCI_LOOKUP_PROGIF:
                    186:       icls = va_arg(args, int);
                    187:       ipif = va_arg(args, int);
                    188:       sprintf(numbuf, "%02x", ipif);
                    189:       pif = id_lookup(a, flags, ID_PROGIF, icls >> 8, icls & 0xff, ipif, 0);
                    190:       if (!pif && icls == 0x0101 && !(ipif & 0x70))
                    191:        {
                    192:          /* IDE controllers have complex prog-if semantics */
                    193:          sprintf(pifbuf, "%s%s%s%s%s",
                    194:                  (ipif & 0x80) ? " Master" : "",
                    195:                  (ipif & 0x08) ? " SecP" : "",
                    196:                  (ipif & 0x04) ? " SecO" : "",
                    197:                  (ipif & 0x02) ? " PriP" : "",
                    198:                  (ipif & 0x01) ? " PriO" : "");
                    199:          pif = pifbuf;
                    200:          if (*pif)
                    201:            pif++;
                    202:        }
                    203:       return format_name(buf, size, flags, pif, numbuf, "ProgIf");
                    204:     default:
                    205:       return "<pci_lookup_name: invalid request>";
                    206:     }
                    207: }

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