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