File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / pciutils / lib / names.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Fri Feb 17 15:18:43 2012 UTC (13 years, 1 month ago) by misho
Branches: pciutils, MAIN
CVS tags: v3_1_9, HEAD
pciutils

    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>