source: trunk/third/sysinfo/os-aix.c @ 12269

Revision 12269, 19.9 KB checked in by ghudson, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12268, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 1992-1998 Michael A. Cooper.
3 * This software may be freely used and distributed provided it is not
4 * sold for profit or used in part or in whole for commercial gain
5 * without prior written agreement, and the author is credited
6 * appropriately.
7 */
8
9#ifndef lint
10static char *RCSid = "$Revision: 1.1.1.3 $";
11#endif
12
13/*
14 * AIX specific functions
15 */
16
17#include "defs.h"
18#include <nl_types.h>
19#include <locale.h>
20
21/*
22 * Platform Specific Interfaces
23 */
24extern char                            *GetKernArchCfg();
25PSI_t GetKernArchPSI[] = {              /* Get Kernel Architecture */
26    { GetKernArchCfg },
27    { GetKernArchSysinfo },
28    { GetKernArchDef },
29    { GetAppArch },
30    { NULL },
31};
32PSI_t GetAppArchPSI[] = {               /* Get Application Architecture */
33    { GetAppArchSysinfo },
34    { GetAppArchDef },
35    { NULL },
36};
37PSI_t GetCpuTypePSI[] = {               /* Get CPU Type */
38    { GetCpuTypeSysinfo },
39    { GetCpuTypeDef },
40    { NULL },
41};
42PSI_t GetNumCpuPSI[] = {                /* Get Number of CPU's */
43    { GetNumCpuSysconf },
44    { NULL },
45};
46PSI_t GetKernVerPSI[] = {               /* Get Kernel Version */
47    { NULL },
48};
49PSI_t GetOSNamePSI[] = {                /* Get OS Name */
50    { GetOSNameSysinfo },
51    { GetOSNameUname },
52    { NULL },
53};
54PSI_t GetOSDistPSI[] = {                /* Get OS Release */
55    { NULL },
56};
57extern char                    *GetOSVerFiles();
58PSI_t GetOSVerPSI[] = {                 /* Get OS Version */
59    { GetOSVerFiles },
60    { GetOSVerSysinfo },
61    { GetOSVerUname },
62    { NULL },
63};
64char                           *GetModelODM();
65PSI_t GetModelPSI[] = {                 /* Get system Model */
66    { GetModelFile },
67    { GetModelODM },
68    { NULL },
69};
70PSI_t GetSerialPSI[] = {                /* Get Serial Number */
71    { NULL },
72};
73PSI_t GetRomVerPSI[] = {                /* Get ROM Version */
74    { NULL },
75};
76PSI_t GetManShortPSI[] = {              /* Get Short Man Name */
77    { GetManShortSysinfo },
78    { GetManShortDef },
79    { NULL },
80};
81PSI_t GetManLongPSI[] = {               /* Get Long Man Name */
82    { GetManLongSysinfo },
83    { GetManLongDef },
84    { NULL },
85};
86extern char                    *GetMemoryODM();
87PSI_t GetMemoryPSI[] = {                /* Get amount of memory */
88    { GetMemoryODM },
89    { NULL },
90};
91extern char                    *GetVirtMemODM();
92PSI_t GetVirtMemPSI[] = {               /* Get amount of virtual memory */
93    { GetVirtMemODM },
94    { NULL },
95};
96PSI_t GetBootTimePSI[] = {              /* Get System Boot Time */
97    { GetBootTimeUtmp },
98    { NULL },
99};
100
101/*
102 * Get ODM Error string.
103 */
104static char *odmerror()
105{
106    static char odmerrstr[256];
107
108    if (odm_err_msg(odmerrno, (char **) &odmerrstr))
109        (void) snprintf(odmerrstr, sizeof(odmerrstr),
110                        "unknown ODM error %d", odmerrno);
111
112    return(odmerrstr);
113}
114
115/*
116 * Get the value of attribute 'Attr' with name 'Name'
117 * from the Custom Attribute ODM.
118 */
119static char *GetAttrVal(Name, Attr)
120    char                       *Name;
121    char                       *Attr;
122{
123    static struct CuAt          CuAt;
124    static char                 Query[128];
125    char                       *errstr = NULL;
126    int                         ret;
127
128    if (odm_initialize() == -1) {
129        SImsg(SIM_GERR, "ODM initialize failed: %s", odmerror());
130        return((char *) NULL);
131    }
132
133    (void) snprintf(Query, sizeof(Query), "attribute = '%s' and name = '%s'",
134                    Attr, Name);
135
136    ret = (int) odm_get_obj(CuAt_CLASS, Query, &CuAt, ODM_FIRST);
137    if (ret == -1)
138        errstr = odmerror();
139    else if (ret == 0)
140        errstr = "No entry found";
141
142    if (errstr) {
143        SImsg(SIM_GERR, "ODM get \"%s\" from \"%s\" failed: %s",
144                         Query, CuAt_CLASS[0].classname, errstr);
145        return((char *) NULL);
146    }
147
148    return((CuAt.value[0]) ? CuAt.value : (char *) NULL);
149}
150
151/*
152 * Get the PvDv ODM entry with the criteria 'Criteria'.
153 */
154static struct PdDv *GetPdDv(Criteria)
155    char                       *Criteria;
156{
157    static struct PdDv          PdDv;
158    char                       *errstr = NULL;
159    int                         ret;
160
161    if (odm_initialize() == -1) {
162        SImsg(SIM_GERR, "ODM initialize failed: %s", odmerror());
163        return((struct PdDv *) NULL);
164    }
165
166    ret = (int) odm_get_obj(PdDv_CLASS, Criteria, &PdDv, ODM_FIRST);
167    if (ret == -1)
168        errstr = odmerror();
169    else if (ret == 0)
170        errstr = "No entry found";
171
172    if (errstr) {
173        SImsg(SIM_GERR, "ODM get \"%s\" from \"%s\" failed: %s",
174                         Criteria, PdDv_CLASS[0].classname, errstr);
175        return((struct PdDv *) NULL);
176    }
177
178    return(&PdDv);
179}
180
181/*
182 * Clean up a VPD string.  Remove initial non alpha-numeric characters
183 * as well as any trailing white space.
184 */
185static char *CleanVPD(string)
186    char                       *string;
187{
188    register char              *cp, *end;
189
190    while (string && *string && !isalnum(*string))
191        ++string;
192
193    cp = end = &string[strlen(string) - 1];
194
195    while (cp && *cp && isspace(*cp))
196        --cp;
197
198    if (cp != end)
199        *(cp+1) = CNULL;
200
201    return(string);
202}
203
204/*
205 * Find the VPD info entry for "String".  Return a vpdinfo_t
206 * entry for the matching entry and set it's "value" correctly.
207 */
208static VPDinfo_t *GetVPDinfo(String)
209    char                       *String;
210{
211    static char                 Buff[BUFSIZ];
212    static char                 Code[3];
213    static VPDinfo_t            VPDinfo;
214
215    (void) strncpy(Code, String, 2);    /* XXX Assume codes are only 2 bytes */
216    Code[2] = CNULL;
217
218    VPDinfo.Code = Code;
219    /*
220     * The "value" portion of "String" starts after the "code" portion.
221     * CleanVPD() is harmful, so we need to pass it a private copy.
222     */
223    (void) snprintf(Buff, sizeof(Buff), "%s", String + strlen(VPDinfo.Code));
224    VPDinfo.Value = CleanVPD(Buff);
225
226    return(&VPDinfo);
227}
228
229/*
230 * Given a VPD string "vpdstr", decode it into a list of strings.
231 */
232static int DecodeVPD(DevInfo, VPDstr)
233    DevInfo_t                  *DevInfo;
234    char                       *VPDstr;
235{
236    char                       *myVPDstr;
237    register char              *cp;
238    Define_t                   *Def;
239    VPDinfo_t                  *VPDinfo;
240
241    if (!VPDstr)
242        return(-1);
243
244    /* strtok() is destructive */
245    myVPDstr = strdup(VPDstr);
246
247    /*
248     * Each field in "VPDstr" is seperated by a "*", followed by
249     * the code for the field and it's value.  Looks something like:
250     *
251     *          *TM 19445*MF IBM
252     */
253    for (cp = strtok(myVPDstr, "*"); cp; cp = strtok((char *)NULL, "*")) {
254        if (!(VPDinfo = GetVPDinfo(cp)))
255            continue;
256
257        if (EQ(VPDinfo->Code, "MF"))
258            DevInfo->Vendor = strdup(VPDinfo->Value);
259        else if (EQ(VPDinfo->Code, "TM"))
260            DevInfo->Model = strdup(VPDinfo->Value);
261        else if (EQ(VPDinfo->Code, "DS"))
262            DevInfo->ModelDesc = strdup(VPDinfo->Value);
263        else if (EQ(VPDinfo->Code, "SN"))
264            DevInfo->Serial = strdup(VPDinfo->Value);
265        else {
266            if (Def = DefGet(DL_VPD, VPDinfo->Code, -1, 0))
267                AddDevDesc(DevInfo, VPDinfo->Value, Def->ValStr1, DA_APPEND);
268            else
269                SImsg(SIM_UNKN, "Unknown VPD code=`%s' value=`%s'.",
270                      VPDinfo->Code, VPDinfo->Value);
271        }
272    }
273
274    if (myVPDstr)
275        (void) free(myVPDstr);
276
277    return(0);
278}
279
280/*
281 * Get and decode the Vital Product Data informatin for device "Name".
282 */
283static int GetVPD(DevInfo)
284    DevInfo_t                  *DevInfo;
285{
286    static struct CuVPD         cuvpd;
287    static char                 Query[128];
288    int                         ret;
289
290    if (odm_initialize() == -1) {
291        SImsg(SIM_GERR, "ODM initialize failed: %s", odmerror());
292        return(-1);
293    }
294
295    (void) snprintf(Query, sizeof(Query),  "name=%s", DevInfo->Name);
296    ret = (int) odm_get_obj(CuVPD_CLASS, Query, &cuvpd, ODM_FIRST);
297    if (ret == -1) {
298        SImsg(SIM_GERR, "ODM get VPD object for \"%s\" failed: %s",
299                  DevInfo->Name, odmerror());
300        return(-1);
301    } else if (ret == 0) {
302        return(-1);
303    }
304
305    SImsg(SIM_DBG, "VPD: name = '%s' type = %d VPD = '%s'",
306               cuvpd.name, cuvpd.vpd_type, cuvpd.vpd);
307
308    return(DecodeVPD(DevInfo, cuvpd.vpd));
309}
310
311/*
312 * Get the system model name.
313 */
314extern char *GetModelODM()
315{
316    Define_t                   *Model;
317    register char              *val, *cp;
318    register int                i, SysType;
319
320    if ((val = GetAttrVal(NN_SYS0, AT_MODELCODE)) == NULL) {
321        SImsg(SIM_GERR, "Cannot get \"%s\" for \"%s\" from ODM.",
322                         AT_MODELCODE, NN_SYS0);
323        return((char *) NULL);
324    }
325
326    SysType = (int) strtol(val, NULL, 0);
327
328    SImsg(SIM_DBG, "System type = 0x%x (%s)", SysType, val);
329
330    Model = DefGet(DL_SYSMODEL, NULL, (long) SysType, 0);
331    if (Model && Model->ValStr1)
332        return(Model->ValStr1);
333
334    SImsg(SIM_UNKN, "system model/type 0x%x is unknown.", SysType);
335
336    return((char *) NULL);
337}
338
339/*
340 * Use the kernels _system_configuration structure to determine
341 * our kernel architecture.
342 *
343 * XXX This isn't working right now
344 */
345#include <sys/systemcfg.h>
346static char                     SysCfgSYM[] = "_system_configuration";
347extern char *GetKernArchCfg()
348{
349#ifdef notdef /* XXX */
350    struct nlist               *NLPtr;
351    kvm_t                      *kd;
352    Define_t                   *Define;
353
354    /*
355     * Get _system_configuration
356     */
357    if (!(kd = KVMopen()))
358        return((char *) NULL);
359    if ((NLPtr = KVMnlist(kd, SysCfgSYM, (struct nlist *)NULL, 0)) == NULL)
360        return((char *) NULL);
361    if (CheckNlist(NLPtr))
362        return((char *) NULL);
363    if (KVMget(kd, NLPtr->n_value, (char *) &_system_configuration,
364               sizeof(_system_configuration), KDT_DATA)) {
365        SImsg(SIM_GERR, "Cannot read `%s' from kernel.", SysCfgSYM);
366        return((char *) NULL);
367    }
368    KVMclose(kd);
369
370    Define = DefGet(DL_CPU, NULL, _system_configuration.implementation, 0);
371    if (Define && Define->ValStr1)
372        return(Define->ValStr1);
373#endif  /* notdef */
374    return((char *) NULL);
375}
376
377/*
378 * Get amount of physical memory from the ODM CuAt data.
379 */
380extern char *GetMemoryODM()
381{
382    register char              *val;
383    Large_t                     amtval;
384    static char                 Buff[64];
385
386    if ((val = GetAttrVal(NN_SYS0, AT_REALMEM)) == NULL) {
387        SImsg(SIM_GERR, "Cannot get \"%s\" for \"%s\" from ODM.",
388              AT_REALMEM, NN_SYS0);
389        return((char *) NULL);
390    }
391
392    amtval = (Large_t) strtol(val, NULL, 0);
393    (void) snprintf(Buff, sizeof(Buff), "%d MB",
394                    DivRndUp(amtval, (Large_t)KBYTES));
395
396    return(Buff);
397}
398
399/*
400 * Get version of OS
401 *
402 * The following is based on what the /bin/oslevel script does.
403 * There are several files that contain the full OS version/revision
404 * level.  The first line of these files contains the version number.
405 * The line either looks like '3.2.5' or '3250'.
406 */
407static char *OSVfiles[] = {
408    OSV_OPP, OSV_MAINT, (char *)0
409};
410
411extern char *GetOSVerFiles()
412{
413    register char              *Ptr;
414    register char              *Ptr2;
415    register char             **PtrPtr;
416    FILE                       *FilePtr;
417    static char                 Buff[100];
418    static char                 Version[100];
419    int                         Len;
420
421    Version[0] = CNULL;
422    for (PtrPtr = OSVfiles; PtrPtr && *PtrPtr; ++PtrPtr) {
423        FilePtr = fopen(*PtrPtr, "r");
424        if (!FilePtr) {
425            SImsg(SIM_GERR, "Open %s failed: %s.", *PtrPtr, SYSERR);
426            continue;
427        }
428        if (fgets(Buff, sizeof(Buff), FilePtr) && isdigit(Buff[0])) {
429            Len = strlen(Buff);
430            if (Buff[Len-1] == '\n')
431                Buff[Len-1] = CNULL;
432            if (strchr(Buff, '.'))
433                (void) strcpy(Version, Buff);
434            else
435                for (Ptr = Buff, Ptr2 = Version; Ptr && *Ptr; ++Ptr, ++Ptr2) {
436                    /* If the line ends in 0, don't add it */
437                    if (!(*Ptr == '0' && *(Ptr+1) == CNULL))
438                        *Ptr2 = *Ptr;
439                    if (*(Ptr + 1))
440                        *++Ptr2 = '.';
441                }
442            /* Zap trailing '.' if present */
443            Len = strlen(Version);
444            if (Version[Len-1] == '.')
445                Version[Len-1] = CNULL;
446        }
447        (void) fclose(FilePtr);
448        if (Version[0])
449            return(Version);
450    }
451
452    return((char *) NULL);
453}
454
455/*
456 * Take a device name, remove and then return the unit number.
457 * e.g. Take "hdisk0", remove "0", and then return 0.
458 */
459static int GetUnit(Name)
460    char                       *Name;
461{
462    int                         unit;
463    register char              *cp;
464
465    for (cp = Name; cp && *cp; ++cp)
466        if (isdigit(*cp)) {
467            unit = (int) atoi(cp);
468            *cp = CNULL;
469            return(unit);
470        }
471
472    return(-1);
473}
474
475/*
476 * Get the location information from CuDvPtr.
477 */
478static char *GetLocation(CuDvPtr)
479    struct CuDv                *CuDvPtr;
480{
481    if (CuDvPtr->location[0])
482        return(CuDvPtr->location);
483
484    return((char *) NULL);
485}
486
487/*
488 * Get Class information.
489 */
490static char *GetClassInfo(CuDvPtr)
491    struct CuDv                *CuDvPtr;
492{
493    if (CuDvPtr->PdDvLn_Lvalue[0])
494        return(CuDvPtr->PdDvLn_Lvalue);
495
496    return((char *) NULL);
497}
498
499/*
500 * Set the description informatin for DevInfo.
501 */
502static void SetDescript(DevInfo, CuDvPtr)
503    DevInfo_t                  *DevInfo;
504    struct CuDv                *CuDvPtr;
505{
506    AddDevDesc(DevInfo, GetLocation(CuDvPtr), "Location", DA_APPEND);
507    AddDevDesc(DevInfo, GetClassInfo(CuDvPtr), "Class/SubClass/Type",
508               DA_APPEND);
509    GetVPD(DevInfo);
510}
511
512/*
513 * Special routine to get memory information.
514 */
515extern DevInfo_t *ProbeMemory(ProbeData, CuDvPtr, PdDvPtr)
516     ProbeData_t               *ProbeData;
517     struct CuDv               *CuDvPtr;
518     struct PdDv               *PdDvPtr;
519{
520    DevInfo_t                  *DevInfo;
521    char                       *cp;
522    char                        Buff[64];
523    char                       *Name;
524    DevData_t                  *DevData;
525
526    if (!ProbeData)
527        return((DevInfo_t *) NULL);
528    Name = ProbeData->DevName;
529    DevData = ProbeData->DevData;
530   
531    if ((cp = GetAttrVal(Name, AT_SIZE)) == NULL)
532        return((DevInfo_t *) NULL);
533
534    DevInfo = NewDevInfo((DevInfo_t *) NULL);
535
536    (void) snprintf(Buff, sizeof(Buff),  "%s MB Memory Card", cp);
537    DevInfo->Model = strdup(Buff);
538
539    DevInfo->Name = Name;
540    DevInfo->Unit = DevData->DevUnit;
541    DevInfo->Master = MkMasterFromDevData(DevData);
542    DevInfo->Type = DT_MEMORY;
543    SetDescript(DevInfo, CuDvPtr);
544
545    return(DevInfo);
546}
547
548/*
549 * Get description information
550 */
551static char *GetDescript(CuDvPtr, PdDvPtr)
552    struct CuDv                *CuDvPtr;
553    struct PdDv                *PdDvPtr;
554{
555    static char                 Buff[BUFSIZ];
556    static char                 lastcat[BUFSIZ];
557    static nl_catd              catd;
558    char                       *msg = NULL;
559    char                       *cp;
560
561    if (!PdDvPtr->catalog[0])
562        return((char *) NULL);
563
564    /*
565     * Reuse open catalog if it's the same as the last time
566     */
567    if ((int) catd <= 0 || !lastcat[0] || strcmp(PdDvPtr->catalog, lastcat)) {
568        if ((int) catd > 0)
569            (void) catclose(catd);
570
571        if ((int) catd == 0) {
572            /*
573             * First time stuff.
574             */
575
576            if (putenv(ENV_NLSPATH) != 0)
577                SImsg(SIM_GERR, "Cannot set environment $NLSPATH.");
578
579            /*
580             * If our LANG is "C", then set to our default in order to
581             * avoid a bug in AIX that fails to find any catalogs in
582             * this case.
583             */
584            cp = (char *) getenv("LANG");
585            if (!cp || (cp && EQ(cp, "C"))) {
586                (void) snprintf(Buff, sizeof(Buff),  "LANG=%s", DEFAULT_LANG);
587                if (putenv(strdup(Buff)) != 0)
588                    SImsg(SIM_GERR, "Cannot set environment %s.", Buff);
589                Buff[0] = CNULL;
590            }
591            (void) setlocale(LC_ALL, "");
592        }
593
594        catd = catopen(PdDvPtr->catalog, 0);
595        if ((int) catd <= 0)
596            SImsg(SIM_GERR, "Catalog open of \"%s\" failed: %s.",
597                             PdDvPtr->catalog, SYSERR);
598    }
599
600    /*
601     * Retrieve the message from the catalog
602     */
603    if ((int) catd > 0) {
604        msg = catgets(catd, PdDvPtr->setno, PdDvPtr->msgno, Buff);
605        /* Save catalog name */
606        (void) strcpy(lastcat, PdDvPtr->catalog);
607    }
608
609    return((msg && *msg) ? msg : (char *) NULL);
610}
611
612/*
613 * General routine to get device information from ODM.
614 */
615extern DevInfo_t *ProbeODM(DevData, TreePtr, CuDvPtr)
616    /*ARGSUSED*/
617    DevData_t                  *DevData;
618    DevInfo_t                 **TreePtr;
619    struct CuDv                *CuDvPtr;
620{
621    DevDefine_t                *DevDefine;
622    DevInfo_t                  *DevInfo;
623    DevInfo_t                  *Master;
624    char                       *MasterName;
625    char                       *DevName;
626    char                       *desc;
627    char                       *cp;
628    static char                 Query[128];
629    struct PdDv                *PdDvPtr;
630    static ProbeData_t          ProbeData;
631    static DevFind_t            Find;
632
633    DevName = MkDevName(DevData->DevName, DevData->DevUnit, 0, 0);
634    (void) memset(&Find, 0, sizeof(Find));
635    Find.Tree = *TreePtr;
636    Find.NodeName = DevName;
637    DevInfo = DevFind(&Find);
638
639    if (CuDvPtr->PdDvLn_Lvalue[0]) {
640        (void) snprintf(Query, sizeof(Query), "uniquetype='%s'",
641                        CuDvPtr->PdDvLn_Lvalue);
642        PdDvPtr = GetPdDv(Query);
643    } else {
644        SImsg(SIM_GERR, "No PdDv link value for '%s'.", DevName);
645        return((DevInfo_t *) NULL);
646    }
647
648    /*
649     * If we can't get the description for this device, then
650     * use the device specific probe routine if one is defined.
651     */
652    if ((desc = GetDescript(CuDvPtr, PdDvPtr)) == (char *) NULL) {
653        if ((DevDefine = DevDefGet(DL_VPD, DevData->DevName, 0)) &&
654            DevDefine->Probe) {
655            (void) memset(&ProbeData, CNULL, sizeof(ProbeData));
656            ProbeData.DevName = DevName;
657            ProbeData.DevData = DevData;
658            ProbeData.DevDefine = DevDefine;
659            return((*DevDefine->Probe)(&ProbeData, CuDvPtr, PdDvPtr));
660        } else {
661            if (Debug)
662                SImsg(SIM_GERR, "No description found for '%s'.", DevName);
663            return((DevInfo_t *) NULL);
664        }
665    }
666
667    if (!DevInfo)
668        DevInfo = NewDevInfo((DevInfo_t *) NULL);
669
670    DevInfo->Name = DevName;
671    DevInfo->Unit = DevData->DevUnit;
672    DevInfo->Type = DT_GENERIC;
673    DevInfo->ModelDesc = strdup(desc);
674    SetDescript(DevInfo, CuDvPtr);
675    if (!DevInfo->MasterName)
676        DevInfo->MasterName = MkMasterName(DevData);
677    if (!DevInfo->Master) {
678        (void) memset(&Find, 0, sizeof(Find));
679        Find.Tree = *TreePtr;
680        Find.NodeName = DevInfo->MasterName;
681        if (Master = DevFind(&Find))
682            DevInfo->Master = Master;
683        else {
684            DevInfo->Master = MkMasterFromDevData(DevData);
685            if (DevInfo->Master)
686                DevInfo->MasterName = DevInfo->Master->Name;
687        }
688    }
689
690    return(DevInfo);
691}
692
693/*
694 * Build device tree by looking at the Object Database Manager (ODM)
695 */
696static int BuildODM(TreePtr, Names)
697    DevInfo_t                 **TreePtr;
698    char                      **Names;
699{
700    static struct CuDv          CuDv;
701    extern struct Class         CuDv_CLASS[];
702    static DevData_t            DevData;
703    DevInfo_t                  *DevInfo;
704    int                         op, ret;
705
706    if (odm_initialize() == -1) {
707        SImsg(SIM_GERR, "ODM initialize failed: %s", odmerror());
708        return(-1);
709    }
710
711    for (op = ODM_FIRST; ; op = ODM_NEXT) {
712        /*
713         * Retrieve the object from ODM.
714         */
715        ret = (int) odm_get_obj(CuDv_CLASS, (char *)NULL, &CuDv, op);
716        if (ret == -1) {
717            SImsg(SIM_GERR, "ODM get object \"%s\" failed: %s",
718                             CuDv_CLASS[0].classname, odmerror());
719            return(-1);
720        } else if (ret == 0)
721            /*
722             * We're done
723             */
724            break;
725
726        if (CuDv.status != AVAILABLE) {
727            SImsg(SIM_GERR, "Device \"%s\" is not available.", CuDv.name);
728            continue;
729        }
730
731        /*
732         * This should never happen
733         */
734        if (CuDv.name[0] == CNULL)
735            continue;
736
737        /* Make sure devdata is clean */
738        bzero(&DevData, sizeof(DevData_t));
739
740        /* Set what we know */
741        DevData.DevName = strdup(CuDv.name);
742        DevData.DevUnit = GetUnit(DevData.DevName);
743        if (CuDv.parent[0]) {
744            DevData.CtlrName = strdup(CuDv.parent);
745            DevData.CtlrUnit = GetUnit(DevData.CtlrName);
746        }
747        DevData.Flags |= DD_IS_ALIVE;
748
749        SImsg(SIM_DBG, "ODM: Found '%s' parent '%s' location '%s' uniq = '%s'",
750              CuDv.name, CuDv.parent, CuDv.location, CuDv.PdDvLn_Lvalue);
751
752        /* Probe and add device */
753        if (DevInfo = ProbeODM(&DevData, TreePtr, &CuDv))
754            AddDevice(DevInfo, TreePtr, Names);
755    }
756
757    if (odm_terminate() != 0)
758        SImsg(SIM_WARN, "ODM Terminate did not succeed.");
759
760    return(0);
761}
762
763/*
764 * Build device tree using TreePtr.
765 * Calls bus and method specific functions to
766 * search for devices.
767 */
768extern int BuildDevices(TreePtr, Names)
769    DevInfo_t                  **TreePtr;
770    char                       **Names;
771{
772    int                          Found = 1;
773
774    if (BuildODM(TreePtr, Names) == 0)
775        Found = 0;
776
777    return(Found);
778}
779
780#include <sys/vminfo.h>
781
782static char                     QueryStr[] =
783    "value = 'paging' and attribute = 'type'";
784
785extern char *GetVirtMemODM()
786{
787    struct CuAt                *CuAtPtr;
788    struct objlistinfo          ObjListInfo;
789    register int                i;
790    static char                 DevName[MAXPATHLEN];
791    static struct pginfo        pginfo;
792    Large_t                     Amount = 0;
793    static char                 Buff[100];
794
795    odm_initialize();
796    odm_set_path(_PATH_ODM);
797
798    CuAtPtr = get_CuAt_list(CuAt_CLASS, QueryStr, &ObjListInfo, 20, 1);
799    if ((int)CuAtPtr == -1) {
800        SImsg(SIM_GERR, "get_CuAt_list paging info failed: %s.", SYSERR);
801        odm_terminate();
802        return((char *)NULL);
803    }
804
805    for (i = 0; i < ObjListInfo.num; ++i, ++CuAtPtr) {
806        (void) snprintf(DevName, sizeof(DevName),  "/dev/%s", CuAtPtr->name);
807
808        if (swapqry(DevName, &pginfo) == -1) {
809            SImsg(SIM_GERR, "swapqry %s failed: %s.", DevName, SYSERR);
810            continue;
811        }
812
813        Amount += (Large_t) ( (pginfo.size * getpagesize() ) / KBYTES );
814    }
815
816    odm_terminate();
817    (void) snprintf(Buff, sizeof(Buff), "%d MB",
818                    DivRndUp(Amount, (Large_t)KBYTES));
819
820    return(Buff);
821}
822
823/*
824 * Initialize the OS specific parts of the Device Types table
825 */
826void DevTypesInit()
827{
828    register int                i;
829
830    for (i = 0; DevTypes[i].Name; ++i)
831        switch (DevTypes[i].Type) {
832        case DT_MEMORY:         DevTypes[i].Probe = ProbeMemory;        break;
833        }
834}
Note: See TracBrowser for help on using the repository browser.