1
0
Files
irix-657m-src/irix/cmd/hinv/hinv.c
2022-09-29 17:59:04 +03:00

3656 lines
92 KiB
C

/**************************************************************************
* *
* Copyright (C) 1986,1988, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#ident "$Revision: 1.359 $"
/*
* Hardware inventory command
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <invent.h>
#include <diskinvent.h>
#include <errno.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/sysmp.h>
#include <sys/sgigsc.h>
#include <net/raw.h>
#include <net/if.h>
#include <sys/fddi.h>
#include <sys/if_xpi.h>
#include <sys/if_ep.h>
#include <sys/sbd.h>
#include <sys/EVEREST/addrs.h>
#include <sys/EVEREST/evconfig.h>
#include <sys/EVEREST/everest.h>
#include <sys/EVEREST/evmp.h>
#include <sys/syssgi.h>
#include <sys/stat.h>
#include <ftw.h>
#include <sys/attributes.h>
#include <paths.h>
#include <sys/iograph.h>
#include <sys/scsi.h>
/*
* Include the diagnostic value strings.
*/
#include <sys/EVEREST/diagval_strs.i>
#define MAX_AUXINFO_STRLEN 512
#define MAXTABLESIZE 4096
#define ALL (-1)
#define MAX_WALK_DEPTH 32
#define INV_STATE_NOT_SET 0
static int sflag;
static int fflag; /* do it fast and unordered */
static int verbose = 0; /* if true print all details */
static int mfg = 0; /* flag for NIC info */
static int ngfxbds;
static char *argv0;
static evcfginfo_t evcfg;
static int cpuid_to_slot[EV_MAX_CPUS];
static int last_slot = -1;
static int first_loop = 1;
/*
* HINV_SCSI_MAXTARG represents the largest legal value for the
* inv_unit field for any type of SCSI device (disk, tape, generic,
* etc.). It may be quite different from the SCSI_MAXTARG, which
* varies for each architecture.
*/
#define HINV_SCSI_MAXTARG 256
#define LUN_TEST_BITS (INV_RAID5_LUN | 0xff)
struct scsi_inv {
inventory_t *controller;
inventory_t *units[HINV_SCSI_MAXTARG];
inventory_t *luns[HINV_SCSI_MAXTARG][SCSI_MAXLUN];
uint64_t node[HINV_SCSI_MAXTARG];
uint64_t port[HINV_SCSI_MAXTARG];
struct scsi_inv *next;
};
struct scsi_inv *controller = NULL, *controller_last = NULL;
uint64_t fc_save_node, fc_save_port;
inventory_t *new_inv;
/*
* Class name mnemonics for -c option:
* This list is order dependent on the class name definitions in invent.h
* When adding a new inventory class, add an entry to this table.
*/
char *classes[] = {
"processor",
"disk",
"memory",
"serial",
"parallel",
"tape",
"graphics",
"network",
"scsi",
"audio",
"iobd",
"video",
"bus",
"misc",
"compression",
"vscsi",
"display",
"unconnected scsi lun",
"PCI card",
"PCI no driver",
"prom",
"IEEE1394",
"rps",
"tpu",
0
};
struct {
char *mn;
int class;
int type;
} searchtypes[] = {
"fpu", INV_PROCESSOR, INV_FPUCHIP,
"cpu", INV_PROCESSOR, INV_CPUCHIP,
"dcache", INV_MEMORY, INV_DCACHE,
"icache", INV_MEMORY, INV_ICACHE,
"memory", INV_MEMORY, INV_MAIN_MB,
"qic", INV_TAPE, INV_SCSIQIC,
"a2", INV_AUDIO, INV_AUDIO_A2,
"dsp", INV_AUDIO, INV_AUDIO_HDSP,
0, 0, 0
};
struct {
char *mn;
int class;
int type;
int cont;
} searchdevs[] = {
"cdsio", INV_SERIAL, INV_CDSIO, ALL,
"aso", INV_SERIAL, INV_ASO_SERIAL, ALL,
"ec", INV_NETWORK, INV_NET_ETHER, INV_ETHER_EC,
"et", INV_NETWORK, INV_NET_ETHER, INV_ETHER_ET,
"ee", INV_NETWORK, INV_NET_ETHER, INV_ETHER_EE,
"ecf", INV_NETWORK, INV_NET_ETHER, INV_ETHER_ECF,
"ef", INV_NETWORK, INV_NET_ETHER, INV_ETHER_EF,
"eg", INV_NETWORK, INV_NET_ETHER, INV_ETHER_GE,
"enp", INV_NETWORK, INV_NET_ETHER, INV_ETHER_ENP,
"fxp", INV_NETWORK, INV_NET_ETHER, INV_ETHER_FXP,
"ep", INV_NETWORK, INV_NET_ETHER, INV_ETHER_EP,
"hy", INV_NETWORK, INV_NET_HYPER, INV_HYPER_HY,
"ipg", INV_NETWORK, INV_NET_FDDI, INV_FDDI_IPG,
"rns", INV_NETWORK, INV_NET_FDDI, INV_FDDI_RNS,
"xpi", INV_NETWORK, INV_NET_FDDI, INV_FDDI_XPI,
"fv", INV_NETWORK, INV_NET_TOKEN, INV_TOKEN_FV,
"gtr", INV_NETWORK, INV_NET_TOKEN, INV_TOKEN_GTR,
"mtr", INV_NETWORK, INV_NET_TOKEN, INV_TOKEN_MTR,
"mtr", INV_NETWORK, INV_NET_TOKEN, INV_TOKEN_MTRPCI,
"atm", INV_NETWORK, INV_NET_ATM, ALL,
"hippi", INV_NETWORK, INV_NET_HIPPI, ALL,
"vfe", INV_NETWORK, INV_NET_ETHER, INV_VFE,
"gfe", INV_NETWORK, INV_NET_ETHER, INV_GFE,
"gsn", INV_NETWORK, INV_NET_GSN, ALL,
"myri", INV_NETWORK, INV_NET_MYRINET, ALL,
"divo", INV_VIDEO, INV_VIDEO_DIVO, ALL,
"xthd", INV_VIDEO, INV_VIDEO_XTHD, ALL,
0, 0, 0
};
struct search_args {
int class;
int type;
int cont;
int unit;
};
static void cpu_display(unsigned int rev);
static void fpu_display(unsigned int rev);
static void get_extended_info();
static void display_all_cpus();
static void display_cpubrd(evbrdinfo_t *, int);
static void membrd_display_extended(int);
static void display_aux_info(char *pathname);
static void mfg_parse(char *, char *);
static int mfg_walk(const char *, const struct stat *, int i, struct FTW *);
static void mfg_info();
static void verbose_display(char *, invent_generic_t *, int);
static void display_scsi();
/*
* Display diagval reason.
*/
static void
verbose_diag_display(char* p, diag_inv_t* dinv){
printf(" %s offline, reason: %s\n", p, dinv->name);
}
/*
* Manufacturing info
*
* Reads the manufacturing inventory including part numbers, rev. codes and
* actual SGI board serial numbers from the naming graph.
*
* Needs sort option by module & by type
*
*/
static void
mfg_parse(char *path, char *s)
{
char *Part = "";
char *Name = "";
char *Serial = "";
char *Revision = "";
char *Group = "";
char *Capability = "";
char *Variety = "";
char *Laser = "";
char *Location = "";
char *NIC = "";
char *t;
/*
* Note: Laser field must be the last one - guaranteed in io/nic.c
*/
if (verbose)
printf("Location: %s\n",path);
if (verbose > 2) {
printf("%s\n",s);
return;
}
while (1) {
t = strtok(s,":;");
if (s)
s = (char *)0;
if (!t) /* done? */
break;
if (!strcmp(t,"Part"))
if (!(Part = strtok(s,":;")))
break;
if (!strcmp(t,"Name"))
if (!(Name = strtok(s,":;")))
break;
if (!strcmp(t,"Serial"))
if (!(Serial = strtok(s,":;")))
break;
if (!strcmp(t,"Revision"))
if (!(Revision = strtok(s,":;")))
break;
if (!strcmp(t,"Group"))
if (!(Group = strtok(s,":;")))
break;
if (!strcmp(t,"Capability"))
if (!(Capability = strtok(s,":;")))
break;
if (!strcmp(t,"Variety"))
if (!(Variety = strtok(s,":;")))
break;
if (!strcmp(t,"NIC"))
if (!(NIC = strtok(s,":;")))
break;
if (!strcmp(t,"Laser")) {
if (!(Laser = strtok(s,":;")))
break;
if (strcmp(NIC,""))
printf("[missing info: %s] Laser %12s\n",NIC,Laser);
else
printf("%16s Board: barcode %-10s part %12s rev %2s\n",Name,Serial,Part,Revision);
if (verbose>1)
printf(" Group %2s Capability %8s Variety %2s Laser %12s\n",Group, Capability, Variety, Laser);
Part = Name = Serial = Revision = Group = Capability = Variety = Laser = NIC = "";
}
}
}
static int
mfg_walk(const char *p, const struct stat *s, int i, struct FTW *f)
{
char info[2000];
int len = sizeof(info);
int rc;
if (i != FTW_D)
return 0;
rc = attr_get((char *)p, INFO_LBL_NIC, info, &len, 0);
if (rc == 0)
mfg_parse((char *)p, info);
return 0;
}
/*
* This routine works only if the device makes a symbolic link (alias) from
* /hw/net/<name> to its real location in the hardware graph. This routine
* knows entirely too much about current hardware.
*/
static int
net_find(char *prefix, int unit, char **module, char **slot)
{
int rc;
char *s1;
char info[MAXDEVNAME];
char filename[16];
int len = MAXDEVNAME;
static char mod[128];
static char slo[128];
char *cp;
sprintf(filename,"/hw/net/%s%d", prefix, unit);
filename_to_devname(filename,info,&len);
if (cp = strstr(info, "module/")) {
char *ocp;
/* Origin 200/2000/Onynx2 */
cp += 7;
if ((*cp >= '0') >= (*cp < '9')) {
*module = mod;
sprintf(mod, "module %d", atoi(cp));
}
ocp = cp;
if (cp = strstr(info, "pci_xio/pci/")) {
/* PCI shoebox */
cp += 12;
if ((*cp >= '0') >= (*cp < '9')) {
*slot = slo;
sprintf(slo, "PCI slot %d", atoi(cp));
}
} else if ((cp = strstr(info, "MotherBoard/")) ||
(cp = strstr(info, "motherboard/"))) {
/* Origin 200 */
cp = strstr(info, "pci/");
if (!cp)
return -1;
cp += 4;
if ((*cp >= '0') >= (*cp < '9')) {
*slot = slo;
sprintf(slo, "PCI slot %d", atoi(cp));
}
} else {
cp = strstr(ocp, "slot/");
if (cp == 0) {
return -1;
}
cp += 5;
ocp = cp;
while (*cp && *cp != '/') {
cp++;
}
if (!*cp) {
return -1;
}
*cp = '\0';
sprintf(slo, "XIO slot %s", ocp);
*slot = slo;
}
return 0;
}
if (cp = strstr(info, "node/xtalk/")) {
/* OCTANE */
if (cp = strstr(info, prefix)) {
cp -= 2;
if ((*cp >= '0') >= (*cp < '9')) {
*slot = slo;
sprintf(slo, "PCI slot %d", atoi(cp));
}
}
return 0;
}
if (cp = strstr(info, "node/io/pci/")) {
/* O2 */
if (cp = strstr(info, prefix)) {
cp -= 2;
if ((*cp >= '0') >= (*cp < '9')) {
*slot = slo;
sprintf(slo, "PCI slot %d", atoi(cp));
}
}
}
return -1;
}
static int
ether_walk(int unit)
{
int rc;
char *s1;
char info[MAXDEVNAME];
char filename[16];
int len = MAXDEVNAME;
sprintf(filename,"/hw/net/ef%d",unit);
filename_to_devname(filename,info,&len);
if((strstr(info, "/pci") != NULL) && ((s1 = strstr(info, "/ef")) != NULL))
{
s1+=3;
if(isspace(*s1) || !(*s1) )
{
strtok(info,"/");
while ((s1 = strtok(NULL, "/")) != NULL) {
if (strcmp(s1, "module") == 0)
printf(", module %s", strtok(NULL, "/"));
else if (strcmp(s1, "slot") == 0)
printf(", slot %s", strtok(NULL, "/"));
else if (strcmp(s1, "pci") == 0)
printf(", pci %s", strtok(NULL, "/"));
}
}
}
return 0;
}
static void
mfg_info()
{
/*
* fail silently if hw graph not available
*/
nftw(_PATH_HWGFS, mfg_walk, MAX_WALK_DEPTH, FTW_PHYS);
}
static int global_verbose_class;
static int
verbose_item_info(const char *p, const struct stat *s, int i, struct FTW *f)
{
char info[256];
int len = sizeof(info);
int rc, reason;
struct stat buf;
/* Do not get the inventory information in case we are looking
* at a link. This prevents hinv from printing duplicates
*/
if (lstat(p,&buf)) /* Make sure lstat succeeds */
return 0;
if (S_ISLNK(buf.st_mode)) /* Check if we are looking at a link*/
return 0;
rc = attr_get((char *)p, INFO_LBL_DETAIL_INVENT, info, &len, 0);
if (rc == 0)
verbose_display((char *)p, (invent_generic_t *)info,
global_verbose_class);
/*
* Right now, we print CPU's which may have been disabled by
* first getting the inventory item (above) and checking to see
* if it was a CPU. Then if it is, we will get the DIAGVAL label
* and print it.
*/
if( global_verbose_class == INV_PROCESSOR){
/* Get DIAGVAL for this hwgpath if it exists .. */
rc = attr_get((char *)p, INFO_LBL_DIAGVAL, info, &len, 0);
if (rc == 0){
verbose_diag_display((char*)p,(diag_inv_t*)info);
}
}
return 0;
}
/*
* To make things a little faster, we call the file system tree walk
* only for known classes.
*/
static void
show_detailed_info(int class)
{
global_verbose_class = class;
switch (class) {
case INV_PROCESSOR:
nftw(_PATH_HWGFS, verbose_item_info, MAX_WALK_DEPTH, FTW_PHYS);
break;
case INV_ROUTER:
nftw(_PATH_HWGFS, verbose_item_info, MAX_WALK_DEPTH, FTW_PHYS);
break;
case INV_MEMORY:
nftw(_PATH_HWGFS, verbose_item_info, MAX_WALK_DEPTH, FTW_PHYS);
break;
case INV_MISC:
nftw(_PATH_HWGFS, verbose_item_info, MAX_WALK_DEPTH, FTW_PHYS);
break;
case INV_PROM:
nftw(_PATH_HWGFS, verbose_item_info, MAX_WALK_DEPTH, FTW_PHYS);
break;
case INV_RPS:
nftw(_PATH_HWGFS, verbose_item_info, MAX_WALK_DEPTH, FTW_PHYS);
break;
case ALL:
nftw(_PATH_HWGFS, verbose_item_info, MAX_WALK_DEPTH, FTW_PHYS);
break;
default:
break;
}
}
static void
verbose_info(class)
{
if (class == ALL) {
if (fflag) {
show_detailed_info(class);
return;
}
for (class = 1; class <= sizeof(classes)/sizeof(classes[0]); class++) {
show_detailed_info(class);
}
}
else {
show_detailed_info(class);
}
}
#define MGRAS_IP_UNK 0
#define MGRAS_IP_I2 1
#define MGRAS_IP_RACER 2
static int mgras_ip_type;
/* Given a board type this routine prints out a more user friendly
* name of the board.
*/
void
get_board_name(int type,char *name)
{
static char *board_name[] = {"BASEIO","MSCSI","MENET",
"HIPPI-Serial",
"PCI XIO","MIO","FIBRE CHANNEL"};
static int board_type[] = {INV_O2000BASEIO,INV_O2000MSCSI,
INV_O2000MENET,INV_O2000HIPPI,
INV_O2000HAROLD,INV_O2000MIO,
INV_O2000FC};
static int num_types = sizeof(board_type)/sizeof(int);
int i;
strcpy(name,"I/O");
for(i = 0 ; i < num_types; i++)
if (board_type[i] == type)
strcpy(name,board_name[i]);
}
/*
* Display hardware inventory item
*
* This procedure knows how to display every kind of inventory item.
* New types of items should be added here.
*
*/
/* ARGSUSED */
int
display_item(inventory_t *pinvent, void *ptr)
{
int options, cpunum;
struct search_args *sa = ptr;
int i;
switch(pinvent->inv_class) {
case INV_MEMORY:
switch(pinvent->inv_type) {
case INV_MAIN:
/*
* This type is for compatibility only.
* No need to report anything.
*/
break;
case INV_MAIN_MB:
printf("Main memory size: %ld Mbytes",
pinvent->inv_state);
if (pinvent->inv_unit)
printf(", %d-way interleaved\n", pinvent->inv_unit);
else
printf("\n");
/* hack to display additional memory info */
if (verbose) {
int slot;
for (slot = 0; slot < EV_MAX_SLOTS; slot++)
membrd_display_extended(slot);
}
break;
case INV_DCACHE:
printf("Data cache size: %ld Kbytes\n",
pinvent->inv_state/1024);
break;
case INV_ICACHE:
printf("Instruction cache size: %ld Kbytes\n",
pinvent->inv_state/1024);
break;
case INV_SDCACHE:
if (pinvent->inv_state < 1024*1024) {
printf("Secondary data cache size: %ld Kbytes\n",
pinvent->inv_state/1024);
} else if (pinvent->inv_state == 1024*1024) {
printf("Secondary data cache size: 1 Mbyte\n");
} else {
printf("Secondary data cache size: %ld Mbytes\n",
pinvent->inv_state/(1024*1024));
}
break;
case INV_SICACHE:
if (pinvent->inv_state < 1024*1024) {
printf("Secondary instruction cache size: %ld Kbytes\n",
pinvent->inv_state/1024);
} else if (pinvent->inv_state == 1024*1024) {
printf("Secondary instruction cache size: 1 Mbyte\n");
} else {
printf("Secondary instruction cache size: %ld Mbytes\n",
pinvent->inv_state/(1024*1024));
}
break;
case INV_SIDCACHE:
/*
* -1 in unit means all cpus have same sized
* secondary cache - support for mixed caches
* on EVERESTs.
* If there is only one record for SIDCACHE, it means
* everyone is the same. This is for backward compatibility.
*/
cpunum = -1;
if (pinvent->inv_next &&
(pinvent->inv_unit & ALL) != ALL)
cpunum = pinvent->inv_controller;
if (pinvent->inv_state < 1024*1024) {
printf("Secondary unified instruction/data cache size: %ld Kbytes",
pinvent->inv_state/1024);
} else if (pinvent->inv_state == 1024*1024) {
printf("Secondary unified instruction/data cache size: 1 Mbyte");
} else {
printf("Secondary unified instruction/data cache size: %ld Mbytes",
pinvent->inv_state/(1024*1024));
}
if (cpunum == -1)
printf("\n");
else
printf(" on Processor %d\n", cpunum);
break;
case INV_PROM:
printf("FLASH PROM version %d.%d\n",
pinvent->inv_controller, pinvent->inv_unit);
break;
case INV_HUBSPC:
printf("Hardware hub space supported\n");
break;
}
break;
case INV_PROCESSOR:
switch(pinvent->inv_type) {
/*
* CPU/FPU revisions are stored in a compacted
* form.
*/
case INV_CPUCHIP:
cpu_display((unsigned int) pinvent->inv_state);
break;
case INV_FPUCHIP:
if ( pinvent->inv_state )
fpu_display(
(unsigned int)pinvent->inv_state);
else
printf("No hardware floating point.\n");
break;
case INV_CPUBOARD: {
/*
* HACK to work around the weakness of inventory facility
* which soly depends logical id. The hack here to insert
* the entries for disabled cpus.
*/
if (verbose && (pinvent->inv_state == INV_IP19BOARD ||
pinvent->inv_state == INV_IP21BOARD ||
pinvent->inv_state == INV_IP25BOARD )) {
if (!first_loop)
return (0);
if ((pinvent->inv_unit & ALL) == ALL) {
display_all_cpus();
first_loop = 0;
}
else {
evcfginfo_t *ep = &evcfg;
evbrdinfo_t *brd;
int slot = cpuid_to_slot[pinvent->inv_unit];
brd = &(ep->ecfg_board[slot]);
if (brd->eb_type != EVTYPE_IP19 &&
brd->eb_type != EVTYPE_IP21 &&
brd->eb_type != EVTYPE_IP25)
return (0);
if (last_slot != slot)
printf("CPU Board at Slot %d: (%s)\n",
slot, (brd->eb_enabled ?
"Enabled" : "Disabled"));
last_slot = slot;
if (!brd->eb_enabled)
return (0);
display_cpubrd(brd, pinvent->inv_unit);
}
return (0);
}
/* ALL means, all cpu has same speed */
if ((pinvent->inv_unit & ALL) == ALL) {
cpunum = sysmp(MP_NPROCS);
printf("%d ",cpunum);
}
else
printf("Processor %d: ", pinvent->inv_unit);
if ( pinvent->inv_controller != 0 )
printf("%d MHZ ",pinvent->inv_controller);
switch (pinvent->inv_state) {
case INV_IP19BOARD:
printf("IP19 ");
break;
case INV_IP20BOARD:
printf("IP20 ");
break;
case INV_IP21BOARD:
printf("IP21 ");
break;
case INV_IP22BOARD:
mgras_ip_type = MGRAS_IP_I2;
printf("IP22 ");
break;
case INV_IP25BOARD:
printf("IP25 ");
break;
case INV_IP26BOARD:
printf("IP26 ");
break;
case INV_IP27BOARD:
printf("IP27 ");
break;
case INV_IP28BOARD:
mgras_ip_type = MGRAS_IP_I2;
printf("IP28 ");
break;
case INV_IP30BOARD:
mgras_ip_type = MGRAS_IP_RACER;
printf("IP30 ");
break;
case INV_IP32BOARD:
printf("IP32 ");
break;
case INV_IP35BOARD:
printf("IP35 ");
break;
}
}
if ((pinvent->inv_unit & ALL) == ALL) {
if ( cpunum > 1 )
printf("Processors");
else
printf("Processor");
}
printf("\n");
break;
case INV_CCSYNC:
if ((sa == NULL) || (sa->class == ALL))
printf("CC synchronization join counter\n");
break;
}
break;
case INV_IOBD:
switch(pinvent->inv_type) {
case INV_EVIO:
printf("I/O board, Ebus slot %d: ",
pinvent->inv_unit);
switch (pinvent->inv_state) {
case INV_IO4_REV1:
printf("IO4 revision 1\n");
break;
default:
printf("IO4 of unknown revision\n");
}
break;
case INV_O200IO:
/* Do not change the string below.
* Customer scripts count on knowing
* the format to figure out if the system is
* an O200 or O2000.
*/
printf("Origin 200 base I/O, module %d slot %d\n",
pinvent->inv_controller, pinvent->inv_unit);
break;
case INV_O2000BASEIO:
case INV_O2000MSCSI:
case INV_O2000MENET:
case INV_O2000HIPPI:
case INV_O2000HAROLD:
case INV_O2000MIO:
case INV_O2000FC:
{
char name[50];
get_board_name(pinvent->inv_type,name);
printf("Origin %s board, module %d "
"slot %d: Revision %d\n",
name,
pinvent->inv_controller,
pinvent->inv_unit,
pinvent->inv_state);
break;
}
case INV_PCIADAP:
if (verbose)
printf(" PCI Adapter ID (vendor %d, "
"device %d) pci slot %d\n",
pinvent->inv_controller,
pinvent->inv_unit,
pinvent->inv_state);
break;
}
break;
case INV_DISK:
switch(pinvent->inv_type) {
case INV_JAGUAR:
printf("Interphase 4210 VME-SCSI controller %d: ",
pinvent->inv_controller);
printf("Firmware revision %c%c%c\n",
pinvent->inv_state >> 16, pinvent->inv_state >> 8,
pinvent->inv_state);
break;
case INV_SCSICONTROL:
case INV_GIO_SCSICONTROL:
if (pinvent->inv_type == INV_SCSICONTROL)
{
if ((pinvent->inv_controller > 1) &&
(pinvent->inv_state == INV_ADP7880))
printf("PCI SCSI controller %d: Version ",
pinvent->inv_controller);
else
printf("Integral SCSI controller %d: Version ",
pinvent->inv_controller);
}
else if (pinvent->inv_type == INV_GIO_SCSICONTROL)
printf("GIO SCSI controller %d: Version ",
pinvent->inv_controller);
switch(pinvent->inv_state)
{
case INV_WD93:
printf("WD33C93"); break;
case INV_WD93A:
printf("WD33C93A"); break;
case INV_WD93B:
printf("WD33C93B"); break;
case INV_WD95A:
printf("WD33C95A"); break;
case INV_SCIP95:
printf("SCIP/WD33C95A"); break;
case INV_QL_REV1:
printf("QL1040"); break;
case INV_QL_REV2:
printf("QL1040A"); break;
case INV_QL_REV2_4:
printf("QL1040A (rev. 4)"); break;
case INV_QL_REV3:
printf("QL1040B"); break;
case INV_QL_REV4:
printf("QL1040B (rev. 2)"); break;
case INV_QL_1240:
printf("QL1240"); break;
case INV_QL_1080:
printf("QL1080"); break;
case INV_QL_1280:
printf("QL1280"); break;
case INV_QL_10160:
printf("QL10160"); break;
case INV_QL_12160:
printf("QL12160"); break;
case INV_QL_2100:
printf ("Fibre Channel QL2100"); break;
case INV_QL_2200:
printf ("Fibre Channel QL2200"); break;
case INV_QL_2200A:
printf ("Fibre Channel QL2200A"); break;
case INV_PR_HIO_D:
printf ("Prisa HIO Dual Fibre Channel"); break;
case INV_PR_PCI64_D:
printf ("Prisa PCI-64 Dual Fibre Channel"); break;
case INV_QL:
printf("QL (unknown version)"); break;
case INV_FCADP:
printf("Fibre Channel AIC-1160"); break;
case INV_ADP7880:
printf("ADAPTEC 7880"); break;
default:
printf("unknown (%d)", pinvent->inv_state);
}
switch(pinvent->inv_state)
{
case INV_WD93:
case INV_WD93A:
case INV_WD93B:
case INV_FCADP:
if (pinvent->inv_unit)
printf(", revision %X", pinvent->inv_unit);
break;
case INV_QL_REV1:
case INV_QL_REV2:
case INV_QL_REV2_4:
case INV_QL_REV3:
case INV_QL_REV4:
case INV_QL_1240:
case INV_QL_1080:
case INV_QL_1280:
case INV_QL_10160:
case INV_QL_12160:
if (pinvent->inv_unit & 0x80)
printf(", low voltage differential");
else
if (pinvent->inv_unit & 0x40)
printf(", differential");
else
printf(", single ended");
break;
case INV_WD95A:
case INV_SCIP95:
if (pinvent->inv_unit & 0x80)
printf(", differential");
else
printf(", single ended");
if (pinvent->inv_state == INV_WD95A)
printf(", revision %X",
pinvent->inv_unit & 0x7F);
}
putchar('\n');
break;
case INV_SCSIDRIVE:
if (fc_save_node) {
printf(" Fabric %s: node %llx port %llx",
(pinvent->inv_state & INV_RAID5_LUN) ? "RAID lun" : "Disk",
fc_save_node, fc_save_port);
printf(" lun %ld", pinvent->inv_state & 0xFF);
}
else {
printf(" %s: unit %d", (pinvent->inv_state & INV_RAID5_LUN) ?
"RAID lun" : "Disk drive", pinvent->inv_unit);
if (pinvent->inv_state & LUN_TEST_BITS)
printf(", lun %ld", pinvent->inv_state & 0xFF);
}
printf(" on SCSI controller %d",
pinvent->inv_controller);
if (verbose)
printf(" (unit %d)", pinvent->inv_unit);
if (pinvent->inv_state & INV_PRIMARY)
printf (" (primary path)");
if (pinvent->inv_state & INV_ALTERNATE)
printf (" (alternate path)");
if (pinvent->inv_state & INV_FAILED)
printf (" DOWN");
printf ("\n");
break;
case INV_SCSIFLOPPY: /* floppies, WORMS, CDROMs, etc. */
printf(" Disk drive / removable media: unit %d ",
pinvent->inv_unit);
printf("on SCSI controller %d",
pinvent->inv_controller);
if(pinvent->inv_state & INV_TEAC_FLOPPY)
printf(": 720K/1.44M floppy\n");
else
printf("\n");
break;
case INV_VSCSIDRIVE:
printf(" Disk drive: unit %d on VME-SCSI controller %d\n",
pinvent->inv_unit, pinvent->inv_controller);
break;
case INV_PCCARD:
printf("PC Card: unit %d", pinvent->inv_unit);
if (pinvent->inv_state)
printf(", lun %ld",(pinvent->inv_state >> 8) & 0xff);
printf(" on SCSI controller %d\n",
pinvent->inv_controller);
break;
}
break;
case INV_SCSI: /* SCSI devices other than disks and tapes */
case INV_VSCSI:
printf(" ");
if (fc_save_node)
printf("Fabric ");
switch(pinvent->inv_type) {
case INV_PRINTER: /* SCSI printer */
printf("Printer");
break;
case INV_CPU: /* SCSI CPU device */
printf("Processor");
break;
case INV_WORM: /* write once read-many */
printf("WORM");
break;
case INV_CDROM: /* CD-ROM */
printf("CDROM");
break;
case INV_SCANNER: /* scanner, like Ricoh IS-11 */
printf("Scanner");
break;
case INV_OPTICAL: /* read-write optical disks */
printf("Optical disk");
break;
case INV_CHANGER: /* CDROM jukeboxes */
printf("Jukebox");
break;
case INV_COMM: /* Communications device */
printf("Comm device");
break;
case INV_RAIDCTLR: /* RAID controller */
printf("RAID controller");
break;
default:
printf("Unknown type %d", pinvent->inv_type);
if(pinvent->inv_state & INV_REMOVE)
printf(" / removable media");
}
if (fc_save_node)
printf(": node %llx port %llx", fc_save_node, fc_save_port);
else
printf(": unit %d", pinvent->inv_unit);
if ((pinvent->inv_state>>8)&0xff)
printf(", lun %ld", (pinvent->inv_state>>8)&0xff);
printf(" on %s controller %d\n",
pinvent->inv_class == INV_VSCSI ? "VME-SCSI" : "SCSI",
pinvent->inv_controller);
break;
case INV_UNC_SCSILUN:
/*
* We don't want to print anything for an unconnected SCSI
* lun in the inventory.
*/
printf(" unconnected unit: %d on controller %d\n",
pinvent->inv_unit, pinvent->inv_controller);
break;
case INV_SERIAL:
switch(pinvent->inv_type) {
case INV_CDSIO:
printf("async serial controller: cdsio%d, firmware version %ld\n",
pinvent->inv_controller, pinvent->inv_state);
break;
case INV_T3270:
printf("IBM 3270 Terminal Emulation controller %d\n",
pinvent->inv_controller);
break;
case INV_GSE:
printf("5080 Gateway card %d\n",
pinvent->inv_controller);
break;
case INV_SI:
printf("SNA SDLC controller %d\n",
pinvent->inv_controller);
break;
case INV_M333X25:
printf("Motorola X.25 controller %d\n",
pinvent->inv_controller);
break;
case INV_ONBOARD:
if (sysmp(MP_NPROCS) > 1)
printf("On-board serial ports: %d per CPU board\n",
pinvent->inv_state);
else{
if(pinvent->inv_state == INV_STATE_NOT_SET)
printf("On-board serial ports: tty%d\n",
pinvent->inv_controller);
else
printf("On-board serial ports: %d\n", pinvent->inv_state);
}
break;
case INV_EPC_SERIAL:
printf("Integral EPC serial ports: %d\n", pinvent->inv_state);
break;
case INV_IOC3_DMA:
printf("IOC3 serial port: tty%d\n",
pinvent->inv_controller);
break;
case INV_IOC3_PIO:
printf("IOC3 PIO mode serial port: tty%d\n",
pinvent->inv_controller);
break;
case INV_ISA_DMA:
printf("On-board serial port: tty%d\n",
pinvent->inv_controller);
break;
case INV_ICA:
printf("IRIS Channel Adapter board %d\n",
pinvent->inv_controller);
break;
case INV_VSC:
printf("VME Synchronous Communications board %d\n",
pinvent->inv_controller);
break;
case INV_ISC:
printf("ISA Synchronous Communications board %d\n",
pinvent->inv_controller);
break;
case INV_GSC:
printf("GIO Synchronous Communications board %d\n",
pinvent->inv_controller);
break;
case INV_PSC:
printf("PCI Synchronous Communications board %d\n",
pinvent->inv_controller);
break;
case INV_ASO_SERIAL:
printf("ASO 6-port Serial board %d: revision %d.%d.%d"
", Ebus slot %d, IO Adapter %d\n",
pinvent->inv_controller,
(pinvent->inv_state >> 28) & 0xf, /*dang rev*/
(pinvent->inv_state >> 12) & 0xff, /*cpld erev*/
(pinvent->inv_state >> 20) & 0xff, /*cpld irev*/
(pinvent->inv_state >> 4) & 0xff, /*EBUS slot*/
(pinvent->inv_state >> 0) & 0xf); /*IOA num*/
break;
}
break;
case INV_PARALLEL:
switch(pinvent->inv_type) {
case INV_GPIB:
printf("IEEE-488 bus controller %d\n",
pinvent->inv_controller);
break;
case INV_EPC_PLP:
printf("Integral EPC parallel port: Ebus slot %d\n",
pinvent->inv_controller);
break;
case INV_EPP_ECP_PLP:
if (pinvent->inv_state == 1)
printf("On-board EPP/ECP parallel port\n");
else
printf("IOC3 parallel port: plp%d\n",
pinvent->inv_controller);
break;
case INV_EPP_PFD:
printf("EPP parallel floppy drive\n");
break;
case INV_ONBOARD_PLP:
if (pinvent->inv_state == 1)
printf("On-board bi-directional parallel port\n");
else
printf("On-board parallel port\n");
break;
}
break;
case INV_AUDIO:
switch(pinvent->inv_type) {
case INV_AUDIO_HDSP:
printf("Iris Audio Processor: revision %d\n",
pinvent->inv_state);
break;
case INV_AUDIO_A2:
printf("Iris Audio Processor: version A2 revision %d.%d.%d",
((unsigned int)pinvent->inv_state & 0x7000) >> 12,
((unsigned int)pinvent->inv_state & 0xf0) >> 4,
(unsigned int)pinvent->inv_state & 0xf);
/*
* for EVEREST (ASO) machines only
*/
if ((pinvent->inv_state & 0xfe000000) != 0) {
printf(" unit %d, Ebus slot %d adapter %d",
pinvent->inv_controller,
(pinvent->inv_state & 0xf0000000) >> 28,
(pinvent->inv_state & 0x0e000000) >> 25);
}
printf("\n");
break;
case INV_AUDIO_A3:
/* Moosehead (IP32) baseboard audio - AD1843 codec */
printf("Iris Audio Processor: version A3 revision %d",
(unsigned int)pinvent->inv_state);
printf("\n");
break;
case INV_AUDIO_RAD:
/* RAD PCI chip */
printf("Iris Audio Processor: version RAD revision %d.%d,"
" number %d",
((unsigned int)pinvent->inv_state >> 4) & 0xf,
(unsigned int)pinvent->inv_state & 0xf,
pinvent->inv_controller);
printf("\n");
break;
case INV_AUDIO_VIGRA110:
printf
("ViGRA 110 Audio %d, base 0x%06X, revision %d\n",
(int)pinvent->inv_unit,
(unsigned int)pinvent->inv_state,
(int)pinvent->inv_controller);
break;
case INV_AUDIO_VIGRA210:
printf
("ViGRA 210 Audio %d, base 0x%06X, revision %d\n",
(int)pinvent->inv_unit,
(unsigned int)pinvent->inv_state,
(int)pinvent->inv_controller);
break;
}
break;
case INV_TAPE:
switch(pinvent->inv_type) {
case INV_VSCSITAPE:
case INV_SCSIQIC: /* bad name: ANY SCSI tape, not just QIC drives */
if (fc_save_node)
printf(" Fabric Tape: node %llx port %llx on ",
fc_save_node, fc_save_port);
else
printf(" Tape drive: unit %d on ", pinvent->inv_unit);
if (pinvent->inv_type == INV_VSCSITAPE)
printf("VME-");
printf("SCSI controller %d: ",
pinvent->inv_controller);
switch(pinvent->inv_state) {
case TPQIC24:
printf("QIC 24\n");
break;
case TPQIC150:
printf("QIC 150\n");
break;
case TPQIC1000:
printf("QIC 1000\n");
break;
case TPQIC1350:
printf("QIC 1350\n");
break;
case TPDAT:
printf("DAT\n");
break;
case TP9TRACK:
printf("9 track\n");
break;
case TP8MM_8200:
printf("8mm(8200) cartridge\n");
break;
case TP8MM_8500:
printf("8mm(8500) cartridge\n");
break;
case TP3480:
printf("3480 cartridge\n");
break;
case TPDLT:
case TPDLTSTACKER:
printf("DLT\n");
break;
case TPD2:
printf("D2 cartridge\n");
break;
case TPMGSTRMP:
case TPMGSTRMPSTCKR:
printf("IBM Magstar MP 3570\n");
break;
case TPNTP:
case TPNTPSTACKER:
printf("IBM Magstar 3590\n");
break;
case TPSTK9490:
printf("STK 9490\n");
break;
case TPSTKSD3:
printf("STK SD3\n");
break;
case TPGY10:
printf("SONY GY-10\n");
break;
case TPGY2120:
printf("SONY GY-2120\n");
break;
case TP8MM_8900:
printf("8mm(8900) cartridge\n");
break;
case TP8MM_AIT:
printf ("8mm (AIT) cartridge\n");
break;
case TPSTK4781:
printf("STK 4781\n");
break;
case TPSTK4791:
printf("STK 4791\n");
break;
case TPFUJDIANA1:
printf("FUJITSU M1016/M1017\n");
break;
case TPFUJDIANA2:
printf("FUJITSU M2483\n");
break;
case TPFUJDIANA3:
printf("FUJITSU M2488\n");
break;
case TPNCTP:
printf("Philips NCTP\n");
break;
case TPTD3600:
printf("Philips TD3600\n");
break;
case TPOVL490E:
printf("Overland Data L490E\n");
break;
case TPSTK9840:
printf("StorageTek 9840\n");
break;
case TPUNKNOWN:
printf("unknown\n");
break;
default:
printf("unknown type %d\n", pinvent->inv_state);
}
/* The TPNTPSTACKER is both a drive and stacker
* at the same target and lun 0.
*/
if ((pinvent->inv_state == TPNTPSTACKER) &&
((sa == NULL) || (sa->class == ALL)) )
printf(" Jukebox: unit %d on SCSI controller %d\n",
pinvent->inv_unit, pinvent->inv_controller);
break;
}
break;
case INV_GRAPHICS: {
options=0;
switch(pinvent->inv_type) {
case INV_GRODEV:
printf("Graphics option installed\n");
break;
case INV_GMDEV:
printf("GT Graphics option installed\n");
break;
case INV_VGX:
printf("VGX Graphics option installed\n");
break;
case INV_VGXT:
printf("VGXT Graphics option installed\n");
break;
case INV_RE:
if (pinvent->inv_state)
printf("RealityEngineII Graphics Pipe %d at IO Slot %d Physical Adapter %d (Fchip rev %d%s)\n",
pinvent->inv_unit, pinvent->inv_controller/8, pinvent->inv_controller%8,
pinvent->inv_state,
(pinvent->inv_state==1)?"<-BAD!":"");
else
printf("RealityEngine Graphics option installed\n");
break;
case INV_VTX:
if (pinvent->inv_state)
printf("VTX Graphics Pipe %d at IO Slot %d Physical Adapter %d (Fchip rev %d%s)\n",
pinvent->inv_unit, pinvent->inv_controller/8, pinvent->inv_controller%8,
pinvent->inv_state,
(pinvent->inv_state==1)?"<-BAD!":"");
else
printf("VTX Graphics option installed\n");
break;
case INV_CG2:
printf("Genlock option installed\n");
break;
case INV_LIGHT:
printf("Graphics board: LG1\n");
break;
case INV_GR2:
if (pinvent->inv_state & INV_GR2_GR3)
printf("Graphics board: GR3");
else if (pinvent->inv_state & INV_GR2_INDY)
printf("Graphics board: GR3");
else if (pinvent->inv_state & INV_GR2_GR5)
printf("Graphics board: GR5");
else if (pinvent->inv_state & INV_GR2_GU1)
printf("Graphics board: GU1");
else
printf("Graphics board: GR2");
switch (pinvent->inv_state & 0x3c) {
case INV_GR2_1GE:
printf("-XS");
if (pinvent->inv_state & INV_GR2_24)
printf("24");
if (pinvent->inv_state & INV_GR2_Z)
printf(" with Z-buffer");
break;
case INV_GR2_2GE:
printf("-XZ");
if ((pinvent->inv_state & INV_GR2_24) == 0)
printf(" missing bitplanes");
if ((pinvent->inv_state & INV_GR2_Z) == 0)
printf(" missing Z");
break;
case INV_GR2_4GE:
if ((pinvent->inv_state & INV_GR2_24) &&
(pinvent->inv_state & INV_GR2_Z)) {
if ((pinvent->inv_state & INV_GR2_INDY) || (pinvent->inv_state & INV_GR2_GR5))
printf("-XZ");
else
printf("-Elan");
}
else
printf("-XSM");
break;
case INV_GR2_8GE:
if ((pinvent->inv_state & INV_GR2_24) &&
(pinvent->inv_state & INV_GR2_Z))
printf("-Extreme");
else {
printf("-8GE,");
if (pinvent->inv_state & INV_GR2_24)
printf("24");
if (pinvent->inv_state & INV_GR2_Z)
printf("Z");
}
break;
default:
printf("-Unknown configuration");
break;
}
printf("\n");
break;
case INV_NEWPORT:
printf("Graphics board: ");
if (pinvent->inv_state & INV_NEWPORT_XL)
printf("XL\n"); /* Indigo2 */
else
printf("Indy %d-bit\n",
(pinvent->inv_state & INV_NEWPORT_24) ? 24 : 8);
break;
case INV_MGRAS: {
int state = pinvent->inv_state;
printf("Graphics board: ");
if (((state & INV_MGRAS_GES) == INV_MGRAS_1GE) &&
((state & INV_MGRAS_RES) == INV_MGRAS_1RE) &&
((state & INV_MGRAS_TRS) == INV_MGRAS_0TR)){
switch(state & INV_MGRAS_ARCHS){
case INV_MGRAS_MOT:
printf("ESI");
break;
case INV_MGRAS_HQ4:
printf("SI");
break;
case INV_MGRAS_HQ3:
printf("Solid Impact");
break;
}
}
else if (((state & INV_MGRAS_GES) == INV_MGRAS_1GE) &&
((state & INV_MGRAS_RES) == INV_MGRAS_1RE) &&
((state & INV_MGRAS_TRS) != INV_MGRAS_0TR)){
switch(state & INV_MGRAS_ARCHS){
case INV_MGRAS_MOT:
printf("ESI with texture option");
break;
case INV_MGRAS_HQ4:
printf("SI with texture option");
break;
case INV_MGRAS_HQ3:
printf("High Impact");
break;
}
}
else if (((state & INV_MGRAS_GES) == INV_MGRAS_2GE) &&
((state & INV_MGRAS_RES) == INV_MGRAS_1RE) &&
((state & INV_MGRAS_TRS) != INV_MGRAS_0TR))
printf("High-AA Impact");
else if (((state & INV_MGRAS_GES) == INV_MGRAS_2GE) &&
((state & INV_MGRAS_RES) == INV_MGRAS_2RE) &&
((state & INV_MGRAS_TRS) != INV_MGRAS_0TR)){
switch(state & INV_MGRAS_ARCHS){
case INV_MGRAS_MOT:
printf("EMXI");
break;
case INV_MGRAS_HQ4:
printf("MXI");
break;
case INV_MGRAS_HQ3:
printf("Maximum Impact");
break;
}
}
else if (((state & INV_MGRAS_GES) == INV_MGRAS_2GE) &&
((state & INV_MGRAS_RES) == INV_MGRAS_2RE) &&
((state & INV_MGRAS_TRS) == INV_MGRAS_0TR)){
switch(state & INV_MGRAS_ARCHS){
case INV_MGRAS_MOT:
printf("ESSI");
break;
case INV_MGRAS_HQ4:
printf("SSI");
break;
case INV_MGRAS_HQ3:
printf("Super Solid Impact");
break;
}
}
else
printf("Impact"); /* unknown config */
if ((state & INV_MGRAS_TRS) > INV_MGRAS_2TR &&
((state & INV_MGRAS_ARCHS) == INV_MGRAS_HQ3))
printf("/TRAM option card");
putchar('\n');
break;
}
case INV_IR: {
printf("Graphics board: InfiniteReality\n");
break;
}
case INV_IR2: {
printf("Graphics board: InfiniteReality2\n");
break;
}
case INV_IR2LITE: {
printf("Graphics board: Reality\n");
break;
}
case INV_IR2E: {
printf("Graphics board: InfiniteReality2E\n");
break;
}
case INV_IR3: {
printf("Graphics board: InfiniteReality3\n");
break;
}
case INV_CRIME: {
printf("CRM graphics installed\n");
break;
}
case INV_ODSY: {
int state = pinvent->inv_state;
printf("Graphics board: ");
switch ( state & INV_ODSY_ARCHS ) {
case INV_ODSY_REVA_ARCH:
printf("Odyssey"); /* Insert snazzy mktng name here */
switch ( state & INV_ODSY_MEMCFG ) {
case INV_ODSY_MEMCFG_32:
printf("32");
break;
case INV_ODSY_MEMCFG_64:
printf("64");
break;
case INV_ODSY_MEMCFG_128:
printf("128");
break;
default:
printf("???");
/* others are architecturally possible... but not planned */
break;
}
break;
case INV_ODSY_REVB_ARCH:
printf("Odyssey+"); /* Insert snazzy mktng name here */
switch ( state & INV_ODSY_MEMCFG ) {
case INV_ODSY_MEMCFG_32:
printf("32");
break;
case INV_ODSY_MEMCFG_64:
printf("64");
break;
case INV_ODSY_MEMCFG_128:
printf("128");
break;
default:
printf("???");
/* others are architecturally possible... but not planned */
break;
}
break;
}
printf("\n");
break;
}
}
break;
}
case INV_NETWORK:
switch(pinvent->inv_controller) {
case INV_ETHER_EC:
printf("Integral Ethernet: ec%d, version %ld\n",
pinvent->inv_unit, pinvent->inv_state);
break;
case INV_ETHER_GIO:
printf("E++ controller: ec%d, version %ld\n",
pinvent->inv_unit, pinvent->inv_state);
break;
case INV_ETHER_ET:
/* Print the unit number for dual IO3s */
printf("Integral Ethernet: et%d, IO%ld\n",
pinvent->inv_unit, pinvent->inv_state);
break;
case INV_ETHER_ENP:
printf(
"ENP-10 Ethernet controller: enp%d, firmware version %ld (%s)\n",
pinvent->inv_unit, pinvent->inv_state,
(pinvent->inv_state == 0) ? "CMC" : "SGI");
break;
case INV_ETHER_EE:
printf("Integral Ethernet controller: et%d, Ebus slot %d\n",
pinvent->inv_unit, pinvent->inv_state);
break;
case INV_HYPER_HY:
printf(
"HyperNet controller %d, adapter unit %#lx, port %ld\n",
pinvent->inv_unit, pinvent->inv_state >> 8,
pinvent->inv_state & 3);
break;
case INV_CRAYIOS_CFEI3:
printf("CRAY FEI-3 controller %d %lx\n",
pinvent->inv_unit, pinvent->inv_state);
break;
case INV_ETHER_EGL:
printf("EFast Eagle controller: egl%d\n",
pinvent->inv_unit);
break;
case INV_ETHER_FXP:
printf("EFast FXP controller: fxp%d\n",
pinvent->inv_unit);
break;
case INV_ETHER_EP:
/* mention each board only once */
if (0 != (pinvent->inv_unit % EP_PORTS_OCT))
break;
i = pinvent->inv_state & EP_VERS_DATE_M;
printf("E-Plex Ethernet controller: ep%d-%d,"
" slot %d, adapter %d,"
" firmware %d%02d%02d%02d00\n",
pinvent->inv_unit,
pinvent->inv_unit+EP_PORTS-1,
((pinvent->inv_state&EP_VERS_SLOT_M)
>>EP_VERS_SLOT_S),
((pinvent->inv_state&EP_VERS_ADAP_M)
>>EP_VERS_ADAP_S),
(i/(24*32*13)) + 92,
(i/(24*32)) % 13,
(i/24) % 32,
i % 24);
break;
case INV_FDDI_IPG:
printf("FDDIXPress controller: ipg%d, version %ld\n",
pinvent->inv_unit, pinvent->inv_state);
break;
case INV_TOKEN_FV:
printf("IRIS VME TokenRing controller fv%d: %d Mbit\n",
pinvent->inv_unit,
pinvent->inv_state ? 16 : 4);
break;
case INV_TOKEN_GTR:
printf("IRIS GIO TokenRing controller gtr%d: %d Mbit\n",
pinvent->inv_unit,
pinvent->inv_state ? 16 : 4);
break;
case INV_TOKEN_MTR:
printf("IRIS EISA TokenRing controller mtr%d: %d Mbit\n",
pinvent->inv_unit,
pinvent->inv_state ? 16 : 4);
break;
case INV_TOKEN_MTRPCI:
printf("IRIS PCI TokenRing controller mtr%d: "
"device_id %d\n", pinvent->inv_unit,
pinvent->inv_state);
break;
case INV_FDDI_RNS: {
char *slot = "";
char *module = "";
net_find("rns", pinvent->inv_unit, &module, &slot);
printf("RNS 2200 PCI/FDDI controller: rns%d, %s%s%s%s",
pinvent->inv_unit,
*module ? module : "",
*module ? ", " : "" ,
*slot ? slot : "",
*slot ? ", " : "");
printf("version %ld\n", pinvent->inv_state);
break;
}
case INV_FDDI_XPI:
printf("XPI FDDI controller: xpi%d",
pinvent->inv_unit);
if (pinvent->inv_state & XPI_VERS_DANG) {
printf(", slot %d, adapter %d",
((pinvent->inv_state&XPI_VERS_SLOT_M)
>>XPI_VERS_SLOT_S),
((pinvent->inv_state&XPI_VERS_ADAP_M)
>>XPI_VERS_ADAP_S));
i = (pinvent->inv_state&XPI_VERS_MEZ_M) * 60;
} else {
i = pinvent->inv_state & XPI_VERS_M;
}
printf(", firmware version %d%02d%02d%02d%02d",
(i/(60*24*32*13)) + 92,
(i/(60*24*32)) % 13,
(i/(60*24)) % 32,
(i/60) % 24,
i % 60);
i = (((uint)pinvent->inv_state)/XPI_VERS_PHY2) & 0x3;
printf(", %s",
"SAS\0xxxxDAS\0xxxxDAS-DM\0x?3\0" + i*8);
if (pinvent->inv_state & XPI_VERS_BYPASS)
printf(" with bypass\n");
else
printf("\n");
break;
case INV_HIO_HIPPI:
printf( "HIPPI adapter: hippi%d, slot %d adap %d, ",
pinvent->inv_unit,
pinvent->inv_state>>28 & 0x0F,
pinvent->inv_state>>24 & 0x0F );
printf( "firmware version %02d%02d%02d\n",
pinvent->inv_state>>16 & 0xFF,
pinvent->inv_state>>8 & 0xFF,
pinvent->inv_state & 0xFF );
break;
case INV_ISDN_SM:
printf("%sISDN: Basic Rate Interface unit %d, " /*sic*/
"revision %d.%d\n",
(pinvent->inv_state & 0x01000000 ?
"Integral " : ""),
pinvent->inv_unit,
(pinvent->inv_state & 0xff00)>>8,
pinvent->inv_state & 0x00ff);
break;
case INV_ISDN_48XP:
printf("ISDN: VME Primary Rate Interface unit %d, "
"revision %d.%d\n",
pinvent->inv_unit,
(pinvent->inv_state & 0xff00)>>8,
pinvent->inv_state & 0x00ff);
break;
case INV_ATM_GIO64:
printf("ATM OC-3c unit %d: slot %d, adapter %d\n",
pinvent->inv_unit,
pinvent->inv_state>>24 & 0xff,
pinvent->inv_state>>16 & 0xff );
break;
case INV_FORE_HE: {
short moduleid, xio_slot, pci_bus, pci_slot, cardtype;
moduleid = (pinvent->inv_state >> 20) & 0xfff;
xio_slot = (pinvent->inv_state >> 16) & 0xf;
pci_bus = (pinvent->inv_state >> 12) & 0xf;
pci_slot = (pinvent->inv_state >> 8) & 0xf;
cardtype = (pinvent->inv_state & 0xff);
printf("ATM HE%d OC-%d: ", cardtype == 8 ? 622 : 155,
cardtype == 8 ? 12 : 3);
printf("module %d, xio_slot %d, pci_slot %d, unit %d\n",
moduleid, xio_slot, pci_slot, pinvent->inv_unit);
break;
}
case INV_FORE_PCA: {
short moduleid, xio_slot, pci_bus, pci_slot, cardtype;
moduleid = (pinvent->inv_state >> 20) & 0xfff;
xio_slot = (pinvent->inv_state >> 16) & 0xf;
pci_bus = (pinvent->inv_state >> 12) & 0xf;
pci_slot = (pinvent->inv_state >> 8) & 0xf;
cardtype = (pinvent->inv_state & 0xff);
printf("ATM PCA-200E OC-3: ");
printf("module %d, xio_slot %d, pci_slot %d, unit %d\n",
moduleid, xio_slot, pci_slot, pinvent->inv_unit);
break;
}
case INV_FORE_VMA: {
short vme_bus, cardtype;
int vme_a16_base_addr;
vme_bus = (pinvent->inv_state >> 24) & 0xff;
vme_a16_base_addr = (pinvent->inv_state >> 8) & 0xffff;
cardtype = (pinvent->inv_state & 0xff);
printf("ATM VMA-200E OC-3: ");
printf("VME_bus_adapter %d, VME_A16_base_addr 0x%x, "
"unit %d\n",
vme_bus, vme_a16_base_addr, pinvent->inv_unit);
break;
}
case INV_FORE_ESA: {
short eisa_slot, cardtype;
eisa_slot = (pinvent->inv_state >> 8) & 0xffff;
cardtype = (pinvent->inv_state & 0xff);
printf("ATM ESA-200E OC-3: ");
printf("EISA_slot %d, unit %d\n",
eisa_slot, pinvent->inv_unit);
break;
}
case INV_FORE_GIA: {
short gio_slot, cardtype;
gio_slot = (pinvent->inv_state >> 8) & 0xffff;
cardtype = (pinvent->inv_state & 0xff);
printf("ATM GIA-200E OC-3: ");
printf("GIO_slot %d, unit %d\n",
gio_slot, pinvent->inv_unit);
break;
}
#if 1 /* XXX */
case INV_ATM_QUADOC3: {
short m,s;
m = (pinvent->inv_state >> 16);
s = (pinvent->inv_state & 0xffff);
printf( "ATM XIO 4 port OC-3c: " );
if ( m >= 0 && s >= 0 )
printf( "module %d, slot io%d, ", m, s );
if ( pinvent->inv_unit != -1 )
printf( "unit %d (ports: %d-%d)\n",
pinvent->inv_unit,
pinvent->inv_unit*4,
pinvent->inv_unit*4+3 );
else
printf( "unassigned unit\n" );
}
break;
#else
case INV_ATM_QUADOC3: {
char *module = "";
char *slot = "";
net_find("atm", pinvent->inv_unit, &module, &slot);
printf( "ATM XIO 4 port OC-3c: unit %d%s%s%s%s\n",
pinvent->inv_unit,
*module ? ", " : "",
*module ? module : "",
*slot ? ", " : "",
*slot ? slot : "");
}
if ( pinvent->inv_unit != -1 )
printf( "unit %d (ports: %d-%d)\n",
pinvent->inv_unit,
pinvent->inv_unit*4,
pinvent->inv_unit*4+3 );
else
printf( "unassigned unit\n" );
break;
#endif
case INV_ETHER_EF:
if (pinvent->inv_unit == 0 ) {
printf("Integral Fast Ethernet: ef%d, version %ld",
pinvent->inv_unit, (pinvent->inv_state & 0xf));
} else {
printf("Fast Ethernet: ef%d, version %ld",
pinvent->inv_unit, (pinvent->inv_state & 0xf));
}
ether_walk(pinvent->inv_unit);
printf("\n");
break;
case INV_ETHER_GE: {
char *slot = "";
char *module = "";
int major, minor, fix;
net_find("eg", pinvent->inv_unit, &module, &slot);
printf("Gigabit Ethernet: eg%d, %s%s%s%s",
pinvent->inv_unit,
*module ? module : "",
*module ? ", " : "",
*slot ? slot : "",
*slot ? ", " : "");
fix = pinvent->inv_state % 10000 % 100;
minor = pinvent->inv_state % 10000 / 100;
major = pinvent->inv_state / 10000;
printf("firmware version %d.%d.%d\n", major, minor, fix);
break;
}
case INV_ETHER_ECF:
printf("PCI Fast Ethernet: ec%d, 10/100Mb, bus %d, slot %d, id 0x%x, rev %d.%d\n",
((pinvent->inv_unit >> 24) & 0xff),
((pinvent->inv_unit >> 16) & 0xff),
((pinvent->inv_unit >> 8) & 0xff),
((pinvent->inv_state >> 16) & 0xffff),
((pinvent->inv_unit >> 4) & 0xf),
(pinvent->inv_unit & 0xf));
break;
#if 1 /* XXX */
case INV_HIPPIS_XTK:
{
short m,s;
m = (pinvent->inv_state >> 16);
s = (pinvent->inv_state & 0xffff);
if ((m < 0) || (s < 0))
printf( "HIPPI-Serial adapter: unit %d\n",
pinvent->inv_unit);
else
printf( "HIPPI-Serial adapter: unit %d, in module %d I/O slot %d\n",
pinvent->inv_unit, m, s);
}
break;
#else
case INV_HIPPIS_XTK: {
char *module = "";
char *slot = "";
net_find("hip", pinvent->inv_unit, &module, &slot);
printf( "HIPPI-Serial adapter: unit %d%s%s%s%s\n",
pinvent->inv_unit,
*module ? ", " : "",
*module ? module : "",
*slot ? ", " : "",
*slot ? slot : "");
}
break;
#endif
case INV_GSN_XTK1: {
short m, s;
m = (pinvent->inv_state >> 16);
s = (pinvent->inv_state & 0xffff);
if ((m < 0) || (s < 0))
printf( "GSN 1-XIO adapter: unit %d\n",
pinvent->inv_unit);
else
printf("GSN 1-XIO adapter: unit %d, in module %d I/O slot %d\n",
pinvent->inv_unit, m, s);
}
break;
case INV_GSN_XTK2: {
/*
* two xtalks are present. inv_state is in the format:
*
* 31 20 19 8 7 4 3 0
* +-------------------------------------------+
* | m2 | m1 | s2 | s1 |
* +-------------------------------------------+
* 12 bits 12 bits 4b 4b
*/
short m1, m2, s1, s2;
m1 = ((pinvent->inv_state >> 8) & 0xfff);
m2 = (pinvent->inv_state >> 20);
s1 = (pinvent->inv_state & 0xf);
s2 = ((pinvent->inv_state >> 4) & 0xf);
if ((m1 < 0) || (s1 < 0) || (s2 < 0) || (m2 < 0))
printf( "GSN 2-XIO adapter: unit %d\n",
pinvent->inv_unit);
else
printf("GSN 2-XIO adapter: unit %d,\n"
"\tXIO port 1 in module %d I/O slot %d\n"
"\tXIO port 2 in module %d I/O slot %d\n",
pinvent->inv_unit, m1, s1, m2, s2);
}
break;
case INV_VFE:
printf("VME 100BaseTX Fast Ethernet: vfe%d\n",
pinvent->inv_unit);
break;
case INV_GFE:
printf("GIO 100BaseTX Fast Ethernet: gfe%d\n",
pinvent->inv_unit);
break;
}
break;
case INV_VIDEO:
switch(pinvent->inv_type) {
case INV_VIDEO_LIGHT:
printf("IndigoVideo board: unit %d, revision %d\n",
pinvent->inv_unit, pinvent->inv_state);
break;
case INV_VIDEO_VS2:
printf("Multi-Channel Option board installed\n");
break;
case INV_VIDEO_VINO:
printf("Vino video: unit %d, revision %d%s\n",
pinvent->inv_unit,
pinvent->inv_state & INV_VINO_REV,
(pinvent->inv_state & INV_VINO_INDY_NOSW) ? "" :
((pinvent->inv_state & INV_VINO_INDY_CAM)
? ", IndyCam connected"
: ", IndyCam not connected"));
break;
case INV_VIDEO_EXPRESS:
if (pinvent->inv_state & INV_GALILEO_JUNIOR)
printf("Indigo2 video (ev1): unit %d, revision %d. %s %s\n",
pinvent->inv_unit,
pinvent->inv_state & INV_GALILEO_REV,
(pinvent->inv_state & INV_GALILEO_DBOB)
? "601 option connected." : "",
(pinvent->inv_state & INV_GALILEO_INDY_CAM)
? "Indycam connected." : "");
else
printf("Galileo video %s (ev1): unit %d, revision %d. %s %s\n",
(pinvent->inv_state & INV_GALILEO_ELANTEC)
? "1.1" : "",
pinvent->inv_unit,
pinvent->inv_state & INV_GALILEO_REV,
(pinvent->inv_state & INV_GALILEO_DBOB)
? "601 option connected." : "",
(pinvent->inv_state & INV_GALILEO_INDY_CAM)
? "Indycam connected." : "");
break;
case INV_VIDEO_INDY:
printf("Indy Video (ev1): unit %d, revision %d\n",
pinvent->inv_unit, pinvent->inv_state);
break;
case INV_VIDEO_MVP:
printf ("Video: MVP unit %d version %d.%d\n",
pinvent->inv_unit,
INV_MVP_REV(pinvent->inv_state),
INV_MVP_REV_SW(pinvent->inv_state));
if (INV_MVP_AV_BOARD(pinvent->inv_state)) {
printf("AV: AV%d Card version %d",
INV_MVP_AV_BOARD(pinvent->inv_state),
INV_MVP_AV_REV(pinvent->inv_state));
if (INV_MVP_CAMERA(pinvent->inv_state)) {
printf(
", O2Cam type %d version %d connected.\n",
INV_MVP_CAMERA(pinvent->inv_state),
INV_MVP_CAM_REV(pinvent->inv_state));
}
else if (INV_MVP_SDIINF(pinvent->inv_state)) {
printf(
", SDI%d Serial Digital Interface "
"version %d connected.\n",
INV_MVP_SDIINF(pinvent->inv_state),
INV_MVP_SDI_REV(pinvent->inv_state));
}
else {
printf(", Camera not connected.\n");
}
}
else {
printf(" with no AV Card or Camera.\n");
break;
}
break;
case INV_VIDEO_INDY_601:
printf("Indy Video 601 (ev1): unit %d, revision %d\n",
pinvent->inv_unit, pinvent->inv_state);
break;
case INV_VIDEO_VO2:
printf("Sirius video: unit %d revision %d on bus %d with ",
pinvent->inv_unit,
pinvent->inv_state & 0x0f,
pinvent->inv_controller);
if (!(pinvent->inv_state & 0xf0)) printf("no ");
if (pinvent->inv_state & 0x80) printf("CPI ");
if (pinvent->inv_state & 0x40) printf("DGI ");
if (pinvent->inv_state & 0x20) printf("BOB ");
if (pinvent->inv_state & 0x10) printf("SD1 ");
printf("options\n");
break;
case INV_VIDEO_MGRAS:
printf("IMPACT Video (mgv): unit %d, revision %d",
pinvent->inv_unit, pinvent->inv_state & 0xf);
if (!(pinvent->inv_state & 0xf0)) printf("\n");
else printf(", TMI/CSC: revision %d\n",
(pinvent->inv_state & 0xf0) >> 4);
break;
case INV_VIDEO_RACER:
printf("Digital Video: unit %d, revision %d.%d",
pinvent->inv_unit, pinvent->inv_state & 0xf,
(pinvent->inv_state >> 4) & 0xf);
printf(", TMI: revision %d",
(pinvent->inv_state >> 8) & 0xf);
printf(", CSC: revision %d\n",
(pinvent->inv_state >> 12) & 0xf);
break;
case INV_VIDEO_EVO:
printf("Personal Video: unit %d, revision %d.%d",
pinvent->inv_unit, pinvent->inv_state & 0xf,
(pinvent->inv_state >> 4) & 0xf);
if ((pinvent->inv_state >> 8) & 0x0f) {
printf(
", DigCam version %d.%d connected\n",
(pinvent->inv_state >> 16) & 0xf,
(pinvent->inv_state >> 12) & 0xf);
}
else if ((pinvent->inv_state >> 20) & 0x0f) {
printf(
", SDI%d version %d connected\n",
(pinvent->inv_state >> 20) & 0xf,
(pinvent->inv_state >> 24) & 0xff);
}
else printf("\n");
break;
case INV_VIDEO_DIVO:
{
static const char *io_configs[4] = {
"Input", "Dual-In", "Output", "Dual-Out"
};
static const char *dvc_options[4] = {
"", "DVCPro", "DVCPro Encoder", "DVCPro Decoder"
};
static const char *mpeg_options[4] = {
"", "MPEG-II", "MPEG-II Encoder", "MPEG-II Decoder"
};
char str[100];
unsigned int st = (unsigned int)pinvent->inv_state;
unsigned int i;
printf("DIVO Video: controller %d unit %d: ",
pinvent->inv_controller, pinvent->inv_unit);
for (i = 0; i <= 1; i ++, st >>= 16) {
/*
* i/o config
* reverse i/o sense for pipe 1; default of 0x0 means output,
* not input.
*/
printf(i ? ", %s" : "%s",
io_configs[(st & 0x3) ^ (i ? 0x2 : 0x0)]);
/*
* options
*/
str[0] = '\0';
if ((st >> 4) & 0x3)
sprintf(str+strlen(str), " and %s",
dvc_options[(st >> 4) & 0x3]);
if ((st >> 6) & 0x3)
sprintf(str+strlen(str), " and %s",
mpeg_options[(st >> 6) & 0x3]);
printf(str[0] ? " with %s" : "",
str + 5 /* skip initial " and " */);
}
putchar('\n');
break;
}
case INV_VIDEO_XTHD:
{
printf("XT-HDIO Video: controller %d, unit %d, version 0x%x\n",
pinvent->inv_controller, pinvent->inv_unit, pinvent->inv_state);
break;
}
default:
fprintf(stderr, "%s: Unknown type %d class %d\n",
argv0, pinvent->inv_type, pinvent->inv_class);
}
break;
case INV_BUS:
switch(pinvent->inv_type) {
case INV_BUS_VME:
if( pinvent->inv_controller == 0 )
printf("VME bus: adapter 0 mapped to adapter %d\n",
pinvent->inv_state);
else
printf("VME bus: adapter %d\n", pinvent->inv_state);
break;
case INV_BUS_EISA:
printf("EISA bus: adapter %d\n", pinvent->inv_unit);
break;
default:
fprintf(stderr, "%s: Unknown type %d class %d\n",
argv0, pinvent->inv_type, pinvent->inv_class);
}
break;
case INV_MISC:
switch(pinvent->inv_type) {
case INV_MISC_EPC_EINT:
printf("EPC external interrupts\n");
break;
case INV_MISC_IOC3_EINT:
printf("IOC3 external interrupts: %d\n",
pinvent->inv_controller);
break;
case INV_MISC_PCKM:
/* no string yet */
break;
case INV_PCI_BRIDGE:
printf("ASIC Bridge Revision %d\n",
pinvent->inv_controller);
break;
case INV_MISC_OTHER:
/*
* allows drivers of odd devices to use
* inventory without hinv declaring
* `Unknown type'
*/
break;
default:
fprintf(stderr, "%s: Unknown type %d class %d\n",
argv0, pinvent->inv_type, pinvent->inv_class);
}
break;
case INV_COMPRESSION:
switch(pinvent->inv_type) {
case INV_COSMO:
printf("Cosmo Compression: unit %d, revision %d\n",
pinvent->inv_controller, pinvent->inv_state);
break;
case INV_INDYCOMP:
printf("IndyComp: unit %d, revision %x:%x\n",
pinvent->inv_controller, pinvent->inv_unit,
pinvent->inv_state);
break;
case INV_IMPACTCOMP:
printf("IMPACT Compression: unit %d, revision %d:%d",
pinvent->inv_controller,
pinvent->inv_unit,
pinvent->inv_state & 0xff);
if(pinvent->inv_state &0x4000)
printf(" with Flex cables.\n");
else
printf("\n");
break;
case INV_VICE:
{ char *chid;
switch (pinvent->inv_state) {
case 0xe1: chid = "EN"; break;
case 0xe2: chid = "DX"; break;
case 0xe3: chid = "TRE"; break;
case 0xe4: chid = "QT"; break;
default: chid = 0; break;
}
if (chid) {
printf("Vice: %s\n", chid);
} else {
printf("Vice: %x\n", pinvent->inv_state);
}
break;
}
default:
fprintf(stderr, "%s: Unknown type %d class %d\n",
argv0, pinvent->inv_type, pinvent->inv_class);
}
break;
case INV_DISPLAY:
switch(pinvent->inv_type) {
case INV_PRESENTER_BOARD:
printf("Presenter adapter board.\n");
break;
case INV_PRESENTER_PANEL:
printf("Presenter adapter board and display.\n");
break;
case INV_ICO_BOARD:
if (mgras_ip_type == MGRAS_IP_RACER)
printf("OCTANE Channel Option Board\n");
else
printf("IMPACT Channel Option Board\n");
break;
case INV_DCD_BOARD:
printf("Dual Channel Display\n");
break;
case INV_7of9_BOARD:
printf("1600SW Flat Panel adapter board.\n");
break;
case INV_7of9_PANEL:
printf("1600SW Flat Panel adapter board and display.\n");
break;
default:
fprintf(stderr, "%s: Unknown type %d class %d\n",
argv0, pinvent->inv_type, pinvent->inv_class);
}
break;
case INV_PCI_NO_DRV:
/* reuse the inv_class here */
switch (pinvent->inv_type){
case INV_DISK:
printf("Mass Storage ");
break;
case INV_MEMORY:
printf("Memory ");
break;
case INV_GRAPHICS:
printf("Display ");
break;
case INV_NETWORK:
printf("Network ");
break;
case INV_VIDEO:
printf("Multimedia ");
break;
case INV_BUS:
printf("Bridge ");
break;
case INV_PCI:
printf("Unknown Type ");
break;
default:
printf("Unknown - %d ", pinvent->inv_type);
}
printf("PCI: Bus %d, Slot %d, Function %d, Vendor ID 0x%x, Device ID 0x%x\tNo driver\n",
(pinvent->inv_controller >> 16) & 0xff,
(pinvent->inv_controller >> 0) & 0xff,
(pinvent->inv_controller >> 8) & 0xff,
pinvent->inv_unit,
pinvent->inv_state);
break;
case INV_PCI:
printf("PCI card, bus %d, slot %d, Vendor 0x%x, Device 0x%x\n",
pinvent->inv_controller, pinvent->inv_unit,
pinvent->inv_type, pinvent->inv_state);
break;
case INV_PROM:
break;
case INV_IEEE1394:
switch (pinvent->inv_type) {
case INV_OHCI:
/* In order to cover O2 DVLink 1.1 */
if ((pinvent->inv_controller==INV_IEEE1394_CTLR_O2_DVLINK_11) && (pinvent->inv_state==1)) {
pinvent->inv_controller=0; pinvent->inv_unit=0;
pinvent->inv_state=INV_IEEE1394_STATE_TI_REV_1;
}
switch(pinvent->inv_state) {
case INV_IEEE1394_STATE_TI_REV_1:
printf("IEEE 1394 High performance serial bus controller %d: Type: OHCI, Version %s %d\n",
pinvent->inv_controller,
"0x104C-1",
pinvent->inv_unit);
break; /* From switch(pinvent->inv_state) */
default:
printf("IEEE 1394 High performance serial bus controller %d: Type: OHCI, Version %s %d\n",
pinvent->inv_controller,
"0",
pinvent->inv_unit);
break; /* From switch(pinvent->inv_state) */
}
break; /* From switch(pinvent->inv_type) */
default:
printf("IEEE 1394 High performance serial bus controller %d: Type: Unknown, Version %s %d\n",
pinvent->inv_controller,
"0",
pinvent->inv_unit);
break;
}
break; /* From INV_IEEE1394 */
case INV_TPU:
switch(pinvent->inv_type) {
case INV_TPU_EXT:
printf("External Tensor Processing Unit, ");
if (pinvent->inv_controller)
printf("module %d ", pinvent->inv_controller);
printf("slot %d\n", pinvent->inv_unit);
break;
case INV_TPU_XIO:
printf("XIO Tensor Processing Unit, ");
if (pinvent->inv_controller)
printf("module %d ", pinvent->inv_controller);
printf("slot %d\n", pinvent->inv_unit);
break;
default:
fprintf(stderr, "%s: Unknown type %d class %d\n",
argv0, pinvent->inv_type, pinvent->inv_class);
}
break;
case 0:
break;
/*
* We should only get this if the "-f" flag (fflag) is set. Otherwise,
* these are intercepted elsewhere. We return, because fc_save_node
* and fc_save_port are cleared at the bottom.
*/
case INV_FCNODE:
fc_save_node = ((uint64_t) pinvent->inv_type << 32) |
(uint32_t) pinvent->inv_controller;
fc_save_port = ((uint64_t) pinvent->inv_unit << 32) |
(uint32_t) pinvent->inv_state;
return 0;
default:
fprintf(stderr,"%s: Unknown inventory class %d\n",
argv0,pinvent->inv_class);
break;
}
/*
* If this function was called via scaninvent (only the case with
* fflag at this time), then clear fc_save variables, since they
* apply to this inventory item only.
*/
if (fflag) {
fc_save_node = 0;
fc_save_port = 0;
}
return 0;
}
int found_item = 0;
int
search_item_func(pinvent, sa)
inventory_t *pinvent;
struct search_args *sa;
{
if ((sa->class == ALL || pinvent->inv_class == sa->class ) &&
(sa->type == ALL || pinvent->inv_type == sa->type ) &&
(sa->cont == ALL || pinvent->inv_controller == sa->cont ) &&
(sa->unit == ALL || pinvent->inv_unit == sa->unit )) {
if (!sflag )
(void)display_item(pinvent, (void *)sa);
found_item = 1;
}
return 0;
}
int
search_for_item(struct search_args *sa)
{
int rc;
if (sa->class == INV_DISK ||
sa->class == INV_SCSI ||
sa->class == INV_VSCSI ||
sa->class == INV_TAPE) {
inv_store(sa);
display_scsi();
return(found_item);
}
rc = scaninvent((int (*)()) search_item_func, (void *) sa);
if (rc < 0) {
fprintf(stderr, "%s: can't read inventory table: %s\n",
argv0, sys_errlist[errno]);
exit(127);
}
if (verbose)
verbose_info(sa->class);
return found_item;
}
/* When displaying all, do these classes first */
int priority_class[] = {
INV_PROCESSOR,
INV_MEMORY,
0
};
/*
* Check the local hinv scsi inventory list to see if a controller
* inventory entry has been created for this controller.
* Returns the pointer to the matching controller inventory entry
* if found and NULL otherwise.
*/
struct scsi_inv *
inv_controller_exist(inventory_t *pinvent)
{
struct scsi_inv *temp = controller;
while (temp) {
if (temp->controller->inv_controller ==
pinvent->inv_controller) {
return(temp); /* Return the matching controller
* inventory entry.
*/
}
temp = temp->next;
}
return(NULL);
}
void
inv_store_controller(inventory_t *pinvent)
{
struct scsi_inv *temp = 0;
int i, j;
/* This can happen only if the disk drive inventory is seen
* before the controller's inventory in which case a dummy
* controller inventory is stored. At this stage we should
* replace that with the actual inventory.
*/
if (temp = inv_controller_exist(pinvent)) {
bcopy(pinvent,temp->controller,sizeof(inventory_t));
return;
}
if (controller == NULL) {
controller = (struct scsi_inv *) calloc(1, sizeof(struct scsi_inv));
if (controller == NULL) {
fprintf(stderr, "%s: %s\n", argv0, sys_errlist[errno]);
exit(127);
}
temp = controller;
controller_last = controller;
} else {
temp = (struct scsi_inv *) calloc(1, sizeof(struct scsi_inv));
if (temp == NULL) {
fprintf(stderr, "%s: %s\n", argv0, sys_errlist[errno]);
exit(127);
}
controller_last->next = temp;
controller_last = temp;
}
new_inv = (inventory_t *)malloc(sizeof(inventory_t));
if (new_inv == NULL) {
fprintf(stderr, "%s: %s\n", argv0, sys_errlist[errno]);
exit(127);
}
bcopy(pinvent, new_inv, sizeof(inventory_t));
temp->controller = new_inv;
}
/* When storing unit and lun information, we assume that
* the controller information has already been extracted.
* This seems to be a reasonable assumption for now.
* If the assumption is broken in the future, we will need
* to modify inv_store_unit() and inv_store_lun().
*/
void
inv_store_unit(inventory_t *pinvent)
{
struct scsi_inv *temp;
int inv_unit_stored = 0;
temp = controller;
while(temp != NULL) {
if (temp->controller->inv_controller == pinvent->inv_controller) {
new_inv = (inventory_t *)malloc(sizeof(inventory_t));
if (new_inv == NULL) {
fprintf(stderr, "%s: not enough memory\n", argv0);
exit(127);
}
bcopy(pinvent, new_inv, sizeof(inventory_t));
temp->units[pinvent->inv_unit] = new_inv;
if (fc_save_node) {
temp->node[pinvent->inv_unit] = fc_save_node;
temp->port[pinvent->inv_unit] = fc_save_port;
}
inv_unit_stored = 1;
break;
}
temp = temp->next;
}
/* If this is first drive and there was no corresponding
* controller entry store do that now.
*/
if (!inv_unit_stored) {
inventory_t inv;
/* Create a dummy controller place holder till the
* actual controller inventory comes along.
* This happens in the case where disk drive inventory
* comes along before the controller inventory.
*/
bzero((char *)&inv,sizeof(inv));
inv.inv_controller = pinvent->inv_controller;
inv_store_controller(&inv);
/* Now store the actual disk information.
* Note there is no scope for infinite
* recursion here since there is a controller entry
* created in the previous step.
*/
inv_store_unit(pinvent);
}
}
void
inv_store_lun(inventory_t *pinvent)
{
struct scsi_inv *temp;
int inv_lun_stored = 0;
temp = controller;
while(temp != NULL) {
if (temp->controller->inv_controller ==
pinvent->inv_controller) {
new_inv = (inventory_t *)malloc(sizeof(inventory_t));
if (new_inv == NULL) {
fprintf(stderr, "%s: not enough memory\n",
argv0);
exit(127);
}
bcopy(pinvent, new_inv, sizeof(inventory_t));
if (pinvent->inv_type == INV_SCSIDRIVE) {
temp->luns[pinvent->inv_unit]
[(pinvent->inv_state)&0xff] = new_inv;
} else { /* INV_SCSI, INV_VSCSI, INV_PCCARD */
temp->luns[pinvent->inv_unit]
[(pinvent->inv_state>>8)&0xff] = new_inv;
}
if (fc_save_node) {
temp->node[pinvent->inv_unit] = fc_save_node;
temp->port[pinvent->inv_unit] = fc_save_port;
}
inv_lun_stored = 1;
break;
}
temp = temp->next;
}
/* If this is first LUN and there was no corresponding
* controller entry store do that now.
*/
if (!inv_lun_stored) {
inventory_t inv;
/* Create a dummy controller place holder till the
* actual controller inventory comes along.
* This happens in the case where disk drive inventory
* comes along before the controller inventory.
*/
bzero((char *)&inv,sizeof(inv));
inv.inv_controller = pinvent->inv_controller;
inv_store_controller(&inv);
/* Now store the actual disk information.
* Note there is no scope for infinite
* recursion here since there is a controller entry
* created in the previous step.
*/
inv_store_lun(pinvent);
}
}
int
inv_store_func(inventory_t *pinvent, struct search_args *sa)
{
if (pinvent->inv_class == INV_FCNODE) {
fc_save_node = ((uint64_t) pinvent->inv_type << 32) |
(uint32_t) pinvent->inv_controller;
fc_save_port = ((uint64_t) pinvent->inv_unit << 32) |
(uint32_t) pinvent->inv_state;
return 0;
}
if ((sa->class == ALL || pinvent->inv_class == sa->class ) &&
(sa->type == ALL || pinvent->inv_type == sa->type ) &&
(sa->cont == ALL || pinvent->inv_controller == sa->cont ) &&
(sa->unit == ALL || pinvent->inv_unit == sa->unit )) {
if (!sflag)
switch(sa->class) {
case INV_DISK:
switch(pinvent->inv_type) {
case INV_SCSICONTROL:
case INV_GIO_SCSICONTROL:
case INV_PCI_SCSICONTROL:
case INV_JAGUAR:
inv_store_controller(pinvent);
break;
case INV_PCCARD:
case INV_SCSIDRIVE:
if (pinvent->inv_state&LUN_TEST_BITS)
inv_store_lun(pinvent);
else
inv_store_unit(pinvent);
break;
default:
inv_store_unit(pinvent);
break;
}
break;
case INV_SCSI:
case INV_VSCSI:
if ((pinvent->inv_state>>8)&0xff)
inv_store_lun(pinvent);
else
inv_store_unit(pinvent);
break;
case INV_TAPE:
inv_store_unit(pinvent);
break;
}
found_item = 1;
}
fc_save_node = fc_save_port = 0;
return 0;
}
int
inv_store(struct search_args *sa)
{
int rc;
rc = scaninvent((int (*)())inv_store_func, (void *)sa);
if (rc < 0) {
fprintf(stderr, "%s: can't read inventory table: %s\n",
argv0, sys_errlist[errno]);
exit(127);
}
if (verbose)
verbose_info(sa->class);
return found_item;
}
void
display_scsi()
{
struct scsi_inv *temp;
int i, j;
while(controller != NULL) {
display_item(controller->controller, NULL);
for (i = 0; i < HINV_SCSI_MAXTARG; i++) {
fc_save_node = controller->node[i];
fc_save_port = controller->port[i];
if (controller->units[i] != NULL)
display_item(controller->units[i], NULL);
free(controller->units[i]);
for (j = 0; j < SCSI_MAXLUN; j++) {
if (controller->luns[i][j] != NULL)
display_item(controller->luns[i][j],
NULL);
free(controller->luns[i][j]);
}
}
temp = controller;
controller = controller->next;
free(temp->controller);
free(temp);
temp = NULL;
fc_save_node = 0;
fc_save_port = 0;
}
}
void
display_all()
{
int i, class;
struct search_args sa;
if (fflag) {
(void) scaninvent(display_item, (char *)NULL);
if (verbose)
verbose_info(ALL);
return;
}
sa.type = ALL;
sa.cont = ALL;
sa.unit = ALL;
/* First, handle priority classes */
for (i=0; class=priority_class[i]; i++) {
sa.class = class;
search_for_item(&sa);
}
/* Now handle classes that are non-priority */
for (class=1; classes[class-1]; class++) {
int is_priority_class = 0;
for (i=0; priority_class[i]; i++)
if (class == priority_class[i]) {
is_priority_class = 1;
break;
}
if (is_priority_class)
continue;
if (class == INV_DISK) {
sa.class = class;
inv_store(&sa);
sa.class = INV_SCSI;
inv_store(&sa);
sa.class = INV_VSCSI;
inv_store(&sa);
sa.class = INV_TAPE;
inv_store(&sa);
sa.class = class;
display_scsi();
} else if (class != INV_SCSI && class != INV_VSCSI &&
class != INV_TAPE) {
sa.class = class;
search_for_item(&sa);
}
}
}
int
lookup_class(names, arg)
char *names[];
char *arg;
{
int i;
for (i = 0; names[i]; i++ )
if ( strcmp(names[i], arg) == 0 )
return i+1;
fprintf(stderr,"%s: unknown class `%s'\n",argv0,arg);
exit(-1);
/* NOTREACHED */
}
static void
lookup_type(char *s, struct search_args *sa)
{
int i;
for ( i = 0; searchtypes[i].mn; i++ )
if ( strcmp(searchtypes[i].mn, s) == 0 ) {
sa->class = searchtypes[i].class;
sa->type = searchtypes[i].type;
return;
}
fprintf(stderr,"%s: unknown type `%s'\n",argv0,s);
exit(-1);
}
static void
lookup_dev(char *s, struct search_args *sa)
{
int i;
for ( i = 0; searchdevs[i].mn; i++ )
if ( strcmp(searchdevs[i].mn, s) == 0 ) {
sa->class = searchdevs[i].class;
sa->type = searchdevs[i].type;
sa->cont = searchdevs[i].cont;
return;
}
fprintf(stderr,"%s: unknown device `%s'\n",argv0,s);
exit(-1);
}
static void
usage()
{
int c;
fprintf(stderr,
"usage: %s {-v -m -s -c class -t type -d dev -u unit -a file}\n",
argv0);
fprintf(stderr, " where class can be:\n");
c = 0;
for ( c = 0; classes[c]; c++ )
if (strcmp(classes[c],""))
fprintf(stderr, " %s\n", classes[c]);
fprintf(stderr, " type can be:\n");
c = 0;
for ( c = 0; searchtypes[c].mn; c++ )
fprintf(stderr, " %s\n",
searchtypes[c].mn);
fprintf(stderr, " dev can be:\n");
c = 0;
for ( c = 0; searchdevs[c].mn; c++ )
fprintf(stderr, " %s\n",
searchdevs[c].mn);
}
void
main(argc,argv)
int argc;
char *argv[];
{
int c;
char *p;
int single;
struct search_args sa;
single = 0;
sa.class = sa.type = ALL;
sa.cont = ALL;
sa.unit = ALL;
argv0 = argv[0];
#ifdef SGAUX_GETNGFXBDS
/*
* This call will be supported on kernels where there can be more than
* one graphics board; the code handles -1 case correctly.
*/
if ((ngfxbds = sgigsc(SGAUX_GETNGFXBDS, 0)) < 0)
errno = 0; /* reset errno */
#else /* !SGAUX_GETNGFXBDS */
ngfxbds = 1;
#endif /* !SGAUX_GETNGFXBDS */
while ((c = getopt(argc,argv,"fvsc:t:d:u:ga:m")) != EOF) {
switch(c) {
case 'f':
/*
* Fast mode: don't bother ordering hinv data.
* By default, order hinv data by class with
* "important stuff" first.
*/
fflag++;
break;
case 'v':
/*
* Verbose mode: more info about cpu, mem and
* disk controllers
*/
verbose++;
break;
case 's':
/* Silent mode: exit code tells all */
sflag++;
break;
case 'c':
/* Look up all items in class. Argument is either
* integer or mnemonic name of class.
*/
if (single) {
usage();
exit(-1);
}
if ( isdigit(*optarg) ) {
sa.class = strtol(optarg,&p,0);
if (*p != '\0' || sa.class <= 0) {
fprintf(stderr,
"%s: bad class number %s\n",
argv0, optarg);
exit(-1);
}
} else {
sa.class = lookup_class(classes, optarg);
}
single++;
break;
case 't':
/* Look up specific inventory sub-type */
if (single) {
usage();
exit(-1);
}
single++;
lookup_type(optarg, &sa);
break;
case 'd':
if (single) {
usage();
exit(-1);
}
single++;
lookup_dev(optarg, &sa);
break;
case 'u':
c = strtol(optarg,&p,0);
if (*p != '\0' || c >= 255 || c < 0) {
fprintf(stderr, "%s: bad unit number %s\n",
argv0, optarg);
exit(-1);
}
sa.unit = c;
break;
case 'a':
optind--;
for ( ; optind < argc; optind++) {
display_aux_info(argv[optind]);
}
exit(0);
case 'm':
mfg++;
break;
default:
usage();
exit(-1);
}
}
if (mfg) {
mfg_info();
}
if (verbose)
get_extended_info();
if (argc != optind) {
usage();
exit(-1);
}
if (!single) {
if (sa.unit != ALL || sa.cont != ALL) {
usage();
exit(-1);
}
display_all();
exit(0);
}
exit(!search_for_item(&sa));
/* NOTREACHED */
}
/************************************************************************
* The following code was hacked out of os/machdep.c and should be updated
* accordingly.
*
*/
/*
* coprocessor revision identifiers
*/
union rev_id {
unsigned int ri_uint;
struct {
#ifdef MIPSEB
unsigned int Ri_fill:16,
Ri_imp:8, /* implementation id */
Ri_majrev:4, /* major revision */
Ri_minrev:4; /* minor revision */
#endif
#ifdef MIPSEL
unsigned int Ri_minrev:4, /* minor revision */
Ri_majrev:4, /* major revision */
Ri_imp:8, /* implementation id */
Ri_fill:16;
#endif
} Ri;
};
#define ri_imp Ri.Ri_imp
#define ri_majrev Ri.Ri_majrev
#define ri_minrev Ri.Ri_minrev
struct imp_tbl {
char *it_name;
unsigned it_imp;
};
/* The code assumes that any number greater than the number in the
* table is that type of processor. They must be in decending numerical
* order. The below table is in the kernel also, so the values must
* be updated there also if cpu_imp_tbl is changed in hinv.c.
*/
struct imp_tbl cpu_imp_tbl[] = {
{ "Unknown CPU type.", C0_MAKE_REVID(C0_IMP_UNDEFINED,0,0) },
{ "MIPS R5000 Processor Chip", C0_MAKE_REVID(C0_IMP_R5000,0,0) },
{ "MIPS R4650 Processor Chip", C0_MAKE_REVID(C0_IMP_R4650,0,0) },
{ "MIPS R4700 Processor Chip", C0_MAKE_REVID(C0_IMP_R4700,0,0) },
{ "MIPS R4600 Processor Chip", C0_MAKE_REVID(C0_IMP_R4600,0,0) },
{ "MIPS R8000 Processor Chip", C0_MAKE_REVID(C0_IMP_R8000,0,0) },
{ "MIPS R12000 Processor Chip", C0_MAKE_REVID(C0_IMP_R12000,0,0) },
{ "MIPS R10000 Processor Chip", C0_MAKE_REVID(C0_IMP_R10000,0,0) },
{ "MIPS R6000A Processor Chip", C0_MAKE_REVID(C0_IMP_R6000A,0,0) },
{ "MIPS R4400 Processor Chip", C0_MAKE_REVID(C0_IMP_R4400,C0_MAJREVMIN_R4400,0) },
{ "MIPS R4000 Processor Chip", C0_MAKE_REVID(C0_IMP_R4000,0,0) },
{ "MIPS R6000 Processor Chip", C0_MAKE_REVID(C0_IMP_R6000,0,0) },
{ "MIPS R3000A Processor Chip", C0_MAKE_REVID(C0_IMP_R3000A,C0_MAJREVMIN_R3000A,0) },
{ "MIPS R3000 Processor Chip", C0_MAKE_REVID(C0_IMP_R3000,C0_MAJREVMIN_R3000,0) },
{ "MIPS R2000A Processor Chip", C0_MAKE_REVID(C0_IMP_R2000A,C0_MAJREVMIN_R2000A,0) },
{ "MIPS R2000 Processor Chip", C0_MAKE_REVID(C0_IMP_R2000,0,0) },
{ 0, 0 }
};
/* The code assumes that any number greater than the number in the
* table is that type of FPU. They must be in decending numerical
* order.
*/
struct imp_tbl fp_imp_tbl[] = {
{ "Unknown FPU type", C0_MAKE_REVID(C0_IMP_UNDEFINED,0,0) },
{ "MIPS R5000 Floating Point Coprocessor", C0_MAKE_REVID(C0_IMP_R5000,0,0) },
{ "MIPS R4650 Floating Point Coprocessor", C0_MAKE_REVID(C0_IMP_R4650,0,0) },
{ "MIPS R4700 Floating Point Coprocessor", C0_MAKE_REVID(C0_IMP_R4700,0,0) },
{ "MIPS R4600 Floating Point Coprocessor", C0_MAKE_REVID(C0_IMP_R4600,0,0) },
{ "MIPS R8010 Floating Point Chip", C0_MAKE_REVID(0x10,0,0) },
{ "MIPS R12010 Floating Point Chip", C0_MAKE_REVID(C0_IMP_R12000,0,0) },
{ "MIPS R10010 Floating Point Chip", C0_MAKE_REVID(C0_IMP_R10000,0,0) },
{ "MIPS R4000 Floating Point Coprocessor", C0_MAKE_REVID(5,0,0) },
{ "MIPS R6010 Floating Point Chip", C0_MAKE_REVID(4,0,0) },
{ "MIPS R3010A VLSI Floating Point Chip", C0_MAKE_REVID(3,3,0) },
{ "MIPS R3010 VLSI Floating Point Chip", C0_MAKE_REVID(3,2,0) },
{ "MIPS R2010A VLSI Floating Point Chip", C0_MAKE_REVID(3,1,0) },
{ "MIPS R2010 VLSI Floating Point Chip", C0_MAKE_REVID(2,0,0) },
{ "MIPS R2360 Floating Point Board", C0_MAKE_REVID(1,0,0) },
{ 0, 0 }
};
char *
imp_name(union rev_id ri,
struct imp_tbl *itp)
{
for (; itp->it_name; itp++)
if (((ri.ri_imp << 8) | (ri.ri_majrev << 4) | (ri.ri_minrev))
>= itp->it_imp)
return(itp->it_name);
return("Unknown implementation");
}
unsigned int cpu_rev;
static void
cpu_display(unsigned int rev)
{
union rev_id ri;
ri.ri_uint = rev;
if (ri.ri_imp == 0) {
ri.ri_majrev = 1;
ri.ri_minrev = 5;
}
cpu_rev = ri.ri_imp;
printf("CPU: %s Revision: %d.%u\n", imp_name(ri, cpu_imp_tbl),
ri.ri_majrev, ri.ri_minrev);
}
static void
fpu_display(unsigned int rev)
{
union rev_id ri;
ri.ri_uint = rev;
/*
* This fix is needed to cover for the early batch
* of TREX chips that had the FPU rev_id set erroneously
* to 0x9 (instead of 0xe) and consequently hinv was
* reporting FPU as R10000 rather then correct R12010.
* Note, that CPU rev_id was correctly set to 0xe for
* those chips.
*/
if (ri.ri_imp == C0_IMP_R10000)
if (cpu_rev == C0_IMP_R12000)
ri.ri_imp = C0_IMP_R12000;
printf("FPU: %s Revision: %d.%u\n", imp_name(ri, fp_imp_tbl),
ri.ri_majrev, ri.ri_minrev);
}
char *
proc_name(int type)
{
switch (type) {
case EVTYPE_IP19:
return "R4400";
case EVTYPE_IP21:
return "R8000";
case EVTYPE_IP25:
return "R10000";
default:
return "Unknown";
}
}
static void
display_cpubrd(evbrdinfo_t *brd, int vpid)
{
evcpucfg_t *cpu;
int i;
for (i = 0; i < EV_CPU_PER_BOARD; i++) {
cpu = &(brd->eb_cpuarr[i]);
/* just find the one matched to display */
if (vpid != ALL && vpid != cpu->cpu_vpid)
continue;
/* evinfo has too much in it. kick out the one that has nothing */
if (cpu->cpu_vpid == 0 && cpu->cpu_speed == 0)
continue;
if (cpu->cpu_diagval == EVDIAG_NOTFOUND &&
cpu->cpu_inventory != EVDIAG_NOTFOUND) {
printf(" Processor at Slot %d/Slice %d:\t%s (Invisible)\n",
brd->eb_slot, i, proc_name(brd->eb_type));
continue;
}
/* Skip the slice if it doesn't look present */
if (cpu->cpu_diagval == EVDIAG_NOTFOUND)
continue;
printf(" Processor %d at Slot %d/Slice %d: %d Mhz %s with %d MB secondary cache (%s)\n",
cpu->cpu_vpid, brd->eb_slot, i,
((brd->eb_type == EVTYPE_IP19) || (brd->eb_type == EVTYPE_IP25)) ? cpu->cpu_speed * 2 :
cpu->cpu_speed,
proc_name(brd->eb_type),
((1 << cpu->cpu_cachesz) / (1024 * 1024)),
(cpu->cpu_enable ? "Enabled" : "Disabled"));
}
}
static void
display_all_cpus()
{
evcfginfo_t *ep = &evcfg;
evbrdinfo_t *brd;
int slot;
for (slot = 0; slot < EV_MAX_SLOTS; slot++) {
brd = &(ep->ecfg_board[slot]);
if (brd->eb_type != EVTYPE_IP19 && brd->eb_type != EVTYPE_IP21 && brd->eb_type != EVTYPE_IP25)
continue;
printf("CPU Board at Slot %d: (%s)\n", slot,
(brd->eb_enabled ? "Enabled" : "Disabled"));
if (!brd->eb_enabled)
continue;
display_cpubrd(brd, ALL);
}
}
/*
* Array used to find the actual size of a particular
* memory bank. The size is in blocks of 256 bytes, since
* the memory banks base address drops the least significant
* 8 bits to fit the base addr in one word.
*/
unsigned long MemSizes[] = {
0x04, /* 0 = 4 meg */
0x10, /* 1 = 16 megs */
0x20, /* 2 = 32 megs */
0x40, /* 3 = 64 megs */
0x40, /* 4 = 64 megs */
0x100, /* 5 = 256 megs */
0x100, /* 6 = 256 megs */
0x0 /* 7 = no SIMM */
};
static void
membrd_display_extended(int slot)
{
evbnkcfg_t *bnk;
evbrdinfo_t *brd;
int i;
int mem_size = 0;
static int flip[] = {0, 4, 1, 5, 2, 6, 3, 7};
brd = &(evcfg.ecfg_board[slot]);
/* Skip empty slots*/
if (brd->eb_type != EVTYPE_MC3)
return;
/* Count total amount of memory on board */
for (i = 0; i < MC3_NUM_BANKS; i++)
mem_size += (MemSizes[brd->eb_banks[i].bnk_size] * 4);
printf("MC3 Memory Board at Slot %d: %d MB of memory (%s)\n",
slot, mem_size, (brd->eb_enabled ? "Enabled" : "Disabled"));
if (brd->eb_diagval != EVDIAG_PASSED)
return;
for (i = 0; i < MC3_NUM_BANKS; i++) {
bnk = &(brd->eb_banks[flip[i]]);
/* Skip this bank if it is empty */
if (bnk->bnk_size == MC3_NOBANK)
continue;
printf(" Bank %c contains %d MB SIMMS (%s)\n",
'A' + i, MemSizes[bnk->bnk_size],
(bnk->bnk_enable ? "Enabled" : "Disabled"));
}
}
static void
get_extended_info()
{
int i, slot;
evcfginfo_t *ep = &evcfg;
evbrdinfo_t *brd;
evcpucfg_t *cpu;
/* don't send error msg because not every platform supports it */
if (syssgi(SGI_GET_EVCONF, ep, sizeof(evcfginfo_t)) == -1)
return;
for (i = 0; i < EV_MAX_CPUS; i++)
cpuid_to_slot[i] = -1;
for (slot = 0; slot < EV_MAX_SLOTS; slot++) {
brd = &(ep->ecfg_board[slot]);
/* Skip empty slots*/
if (brd->eb_type == EVTYPE_EMPTY)
continue;
switch (brd->eb_type) {
case EVTYPE_IP19:
case EVTYPE_IP21:
case EVTYPE_IP25:
for (i = 0; i < EV_CPU_PER_BOARD; i++) {
cpu = &(brd->eb_cpuarr[i]);
if (cpuid_to_slot[cpu->cpu_vpid] == -1)
cpuid_to_slot[cpu->cpu_vpid] = slot;
}
break;
case EVTYPE_MC3:
break;
case EVTYPE_IO4:
case EVTYPE_EMPTY:
break;
default:
printf("Unrecognized board.\n");
break;
}
}
}
/*
* display the auxilliary information about the device
* Input: pathname to a file in the filesystem
* Output: none
* Side effects: auxilliary info on stdout about the special device if the
* file is a special device and it has auxilliary info; or error message is
* printed on the stderr.
* Global variables used: errno
*/
static void
display_aux_info(char *pathname)
{
char info_buf[MAX_AUXINFO_STRLEN];
struct stat stat_buf;
if (stat(pathname, &stat_buf) == -1) {
fprintf(stderr, "%s: %s\n", pathname, strerror(errno));
return;
}
if (syssgi(SGI_IO_SHOW_AUX_INFO, stat_buf.st_rdev, &info_buf)) {
fprintf(stderr, "%s: %s\n", pathname, strerror(errno));
return;
}
printf("%s: %s\n", pathname, info_buf);
}
char *inv_mem_attrs[] = {
"Premium Memory" /* PREMIUM_MEMORY = 0x0001 */
};
#define MAX_MEM_ATTRS (sizeof(inv_mem_attrs) / sizeof(inv_mem_attrs[0]))
static void
verbose_memory_display(invent_meminfo_t *mem_invent)
{
int i;
printf("Memory at Module %d/Slot %d: %d MB (%s)\n",
mem_invent->im_gen.ig_module,
mem_invent->im_gen.ig_slot,
mem_invent->im_size,
(mem_invent->im_gen.ig_flag & INVENT_ENABLED) ?
"enabled" : "disabled");
for (i = 0; i < mem_invent->im_banks; i++) {
if (mem_invent->im_bank_info[i].imb_size == 0)
continue;
printf(" Bank %d contains %d MB (%s) DIMMS (%s)\n",
i, mem_invent->im_bank_info[i].imb_size,
(mem_invent->im_bank_info[i].imb_attr & INV_MEM_PREMIUM) ?
"Premium" : "Standard",
(mem_invent->im_bank_info[i].imb_flag & INVENT_ENABLED) ?
"enabled" : "disabled");
}
}
static void
verbose_cpu_display(invent_cpuinfo_t *cpu_invent)
{
union rev_id ri;
ri.ri_uint = cpu_invent->ic_cpu_info.cpuflavor;
printf("CPU %d at Module %d/Slot %d/Slice %c: %d Mhz %s (%s) \n",
cpu_invent->ic_cpuid, cpu_invent->ic_gen.ig_module,
cpu_invent->ic_gen.ig_slot, cpu_invent->ic_slice + 'A',
cpu_invent->ic_cpu_info.cpufq,
imp_name(ri, cpu_imp_tbl),
(cpu_invent->ic_gen.ig_flag & INVENT_ENABLED) ?
"enabled" : "disabled");
/* Get reason it was disabled it it is not enabled */
if(!(cpu_invent->ic_gen.ig_flag & INVENT_ENABLED)){
}
printf(" Processor revision: %d.%u. Secondary cache: Size %d MB "
"Speed %d Mhz \n",
ri.ri_majrev,
ri.ri_minrev,
cpu_invent->ic_cpu_info.sdsize,
cpu_invent->ic_cpu_info.sdfreq);
}
static void
verbose_rps_display(invent_rpsinfo_t *rps_invent)
{
printf("Redundant Power Supply in %sModule %d (%s)\n",
rps_invent->ir_xbox ? "Gigachannel unit on " : "",
rps_invent->ir_gen.ig_module,
(rps_invent->ir_gen.ig_flag == INVENT_ENABLED) ?
"Enabled" : "Lost Redundancy");
}
static void
verbose_prom_display(invent_miscinfo_t *misc_invent)
{
int type;
static int master_io6_info_displayed = 0;
type = misc_invent->im_type;
switch (type) {
case INV_IP27PROM:
printf("IP27prom in Module %d/"
"Slot n%d: Revision %d.%d\n",
misc_invent->im_gen.ig_module,
misc_invent->im_gen.ig_slot,
misc_invent->im_version,
misc_invent->im_rev);
break;
case INV_IO6PROM:
if (!master_io6_info_displayed) {
printf("IO6prom on Global Master Baseio in Module %d/"
"Slot io%d: Revision %d.%d\n",
misc_invent->im_gen.ig_module,
misc_invent->im_gen.ig_slot,
misc_invent->im_version,
misc_invent->im_rev);
master_io6_info_displayed = 1;
}
break;
case INV_IP35PROM:
printf("IP35prom in Module %d/"
"Slot n%d: Revision %d.%d\n",
misc_invent->im_gen.ig_module,
misc_invent->im_gen.ig_slot,
misc_invent->im_version,
misc_invent->im_rev);
break;
default:
break;
}
}
static void
verbose_misc_display(invent_miscinfo_t *misc_invent)
{
int type;
type = misc_invent->im_type;
switch (type) {
case INV_HUB:
printf("HUB in Module %d/Slot %d: Revision %d Speed %.2f Mhz "
"(%s)\n",
misc_invent->im_gen.ig_module,
misc_invent->im_gen.ig_slot,
misc_invent->im_rev,
misc_invent->im_speed / 1000000.0,
(misc_invent->im_gen.ig_flag & INVENT_ENABLED) ?
"enabled" : "disabled");
break;
default:
break;
}
}
/*
* Origin Router
*/
static void
verbose_router_display(invent_routerinfo_t* ri)
{
printf("ROUTER in Module %d/Slot %d: Revision %d: Active Ports %s (%s)\n",
ri->im_gen.ig_module,ri->im_gen.ig_slot, ri->rip.rev,
ri->rip.portmap,
(ri->im_gen.ig_flag & INVENT_ENABLED) ? "enabled" : "disabled");
}
static void
verbose_display(char *path, invent_generic_t *invent, int class)
{
if ((class == ALL) || (invent->ig_invclass == class)) {
if (verbose > 1)
printf("Location: %s\n", path);
switch (invent->ig_invclass) {
case INV_MEMORY:
verbose_memory_display((invent_meminfo_t *)invent);
break;
case INV_PROCESSOR:
verbose_cpu_display((invent_cpuinfo_t *)invent);
break;
case INV_MISC:
verbose_misc_display((invent_miscinfo_t *)invent);
break;
case INV_PROM:
verbose_prom_display((invent_miscinfo_t *)invent);
break;
case INV_ROUTER:
verbose_router_display((invent_routerinfo_t*)invent);
break;
case INV_RPS:
verbose_rps_display((invent_rpsinfo_t*)invent);
break;
default:
break;
}
}
}