home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1992 Michael A. Cooper.
- * This software may be freely distributed provided it is not sold for
- * profit and the author is credited appropriately.
- */
-
- #ifndef lint
- static char *RCSid = "$Header: /src/common/usc/bin/sysinfo/RCS/os-sunos.c,v 1.30 1992/04/26 23:51:53 mcooper Exp $";
- #endif
-
- /*
- * $Log: os-sunos.c,v $
- * Revision 1.30 1992/04/26 23:51:53 mcooper
- * Add some comments.
- *
- * Revision 1.28 1992/04/19 23:17:46 mcooper
- * Suppress CodeCenter warning about "romp".
- *
- * Revision 1.27 1992/04/19 23:07:23 mcooper
- * Update GetRomVer() to be more portable.
- *
- * Revision 1.26 1992/04/18 20:48:18 mcooper
- * Add #ifdef HAVE_SUNROMVEC around GetRomVer.
- *
- * Revision 1.25 1992/04/17 23:27:51 mcooper
- * Add support for ROM Version information (Sun only for now).
- *
- * Revision 1.24 1992/04/17 01:07:59 mcooper
- * More de-linting
- *
- * Revision 1.23 1992/04/16 02:25:39 mcooper
- * Bug fixes, de-linting, and other changes found with CodeCenter.
- *
- * Revision 1.22 1992/04/15 02:46:34 mcooper
- * - Add better MainBus() and OPENPROM() build debug messages.
- * - Make GetKernArchName() use "cpu" kernel symbol like GetModelName().
- *
- * Revision 1.21 1992/04/15 02:02:17 mcooper
- * Change GetMemoryStr() to GetMemory().
- *
- * Revision 1.20 1992/04/12 22:03:56 mcooper
- * - Change GetModelName() to use kernel symbol "cpu" instead
- * of gethostid() to be more portable to other SPARC clones.
- * - Update GetKernArchName() to support Solbourne CPU_TYPE.
- * - Add HAVE_IPI kludge for "id" disks.
- * - Various other cleanup bits.
- *
- * Revision 1.19 1992/03/31 01:55:17 mcooper
- * Use new CheckNlist to check nlist success.
- *
- * Revision 1.18 1992/03/31 00:45:27 mcooper
- * Fixed GetKernArchName() to use CPU_ARCH mask.
- *
- * Revision 1.17 1992/03/31 00:15:09 mcooper
- * Add error check for nlist.n_type.
- *
- * Revision 1.16 1992/03/25 03:28:32 mcooper
- * Skip partitions that have 0 size.
- *
- * Revision 1.15 1992/03/25 03:20:14 mcooper
- * Only read partition info we we're going to print it later.
- *
- * Revision 1.14 1992/03/22 00:20:10 mcooper
- * Major cleanup and re-org.
- *
- * Revision 1.13 1992/03/09 01:23:42 mcooper
- * Add need include files for NIT stuff.
- *
- * Revision 1.12 1992/03/08 04:58:30 mcooper
- * Move probe_generic() to devices.c.
- *
- * Revision 1.11 1992/03/06 18:37:26 mcooper
- * Move some general functions to devices.c.
- *
- * Revision 1.10 1992/03/05 22:36:35 mcooper
- * Cleanup format.
- *
- * Revision 1.9 1992/03/05 05:12:10 mcooper
- * Cleanup build_mainbus().
- *
- * Revision 1.8 1992/03/01 23:30:15 mcooper
- * More more SunOS specific code from sysinfo.c to here.
- *
- * Revision 1.7 1992/02/27 22:01:22 mcooper
- * Add support for getting CPU info for sun4m.
- *
- * Revision 1.6 1992/02/27 20:36:52 mcooper
- * Remove \n from error() messages.
- *
- * Revision 1.5 1992/02/26 19:07:21 mcooper
- * Add a debug statement.
- *
- * Revision 1.4 1992/02/25 00:59:35 mcooper
- * Move tape info to local MTINFO.
- *
- * Revision 1.3 1992/02/25 00:17:45 mcooper
- * Lots of fixes and changes.
- *
- * Revision 1.2 1992/02/22 02:30:29 mcooper
- * Fix fbtab stuff.
- *
- * Revision 1.1 1992/02/22 02:20:19 mcooper
- * Initial revision
- *
- * Revision 1.5 1992/02/19 22:30:44 mcooper
- * Fix calling problem.
- *
- * Revision 1.4 1992/02/17 01:00:23 mcooper
- * - More portability and support for solbourne.
- *
- * Revision 1.3 1992/02/17 00:24:22 mcooper
- * Update frame buffers.
- *
- * Revision 1.2 1992/02/16 22:55:44 mcooper
- * Add netif support.
- *
- * Revision 1.1 1991/11/30 23:28:53 mcooper
- * Initial revision
- *
- */
-
- #include <stdio.h>
- #include "system.h"
- #include "defs.h"
-
- #include <mntent.h>
- #include <nlist.h>
- #include <sys/param.h>
- #include <sys/types.h>
- #include <sys/buf.h>
- #include <sys/stat.h>
- #include <sys/mtio.h>
- #include <sun/dkio.h>
- #include <sun/dklabel.h>
- #include <sun/fbio.h>
-
- /*
- * Name of frame buffer "indirect" device.
- */
- #define FBDEVICE "fb"
-
- /*
- * Name of generic magnetic tape device.
- */
- #define MTNAME "mt"
-
- /*
- * Generally used variables
- */
- static kvm_t *kd = NULL;
- static struct stat StatBuf;
- static DEVICE *Device;
- static char Buf[BUFSIZ];
-
- #if defined(HAVE_MAINBUS)
- /*
- * Build a device tree by searching the MainBus
- */
- #include <sundev/mbvar.h>
-
- #define DV_SIZE (sizeof(struct mb_device))
- #define DR_SIZE (sizeof(struct mb_driver))
-
- /*
- * Build device tree by looking at mainbus (mb) devices
- */
- static int BuildMainBus(TreePtr)
- DEVICE **TreePtr;
- {
- extern struct nlist MainBusNL[];
- static struct mb_device Device;
- static struct mb_driver Driver;
- static char CtlrName[BUFSIZ], DevName[BUFSIZ];
- static DEVDATA DevData;
- u_long Addr, DeviceAddr;
- DEVICE *Dev;
-
- /*
- * Read table address from kernel
- */
- if (!(kd = KVM_open(MainBusNL))) {
- if (Debug) Error("Cannot open & nlist mainbus device table.");
- return(-1);
- }
-
- /*
- * See if we got a valid entry
- */
- if (CheckNlist(&MainBusNL[0]))
- return(-1);
-
- /*
- * Read each device table entry. A NULL device.mb_driver
- * indicates that we're at the end of the table.
- */
- for (DeviceAddr = MainBusNL[0].n_value; DeviceAddr;
- DeviceAddr += DV_SIZE) {
-
- /*
- * Read this device
- */
- if (KVM_read(kd, DeviceAddr, (char *) &Device, DV_SIZE)) {
- if (Debug)
- Error("Cannot read mainbus device from address 0x%x.",
- DeviceAddr);
- KVM_close(kd);
- return(-1);
- }
-
- /*
- * See if we're done.
- */
- if (!Device.md_driver)
- break;
-
- /*
- * Read the driver structure
- */
- Addr = (u_long) Device.md_driver;
- if (KVM_read(kd, Addr, (char *) &Driver, DR_SIZE)) {
- if (Debug)
- Error("Cannot read driver for mainbus address 0x%x.", Addr);
- continue;
- }
-
- /*
- * Get the device name
- */
- if (Addr = (u_long) Driver.mdr_dname) {
- if (KVM_read(kd, Addr, (char *) DevName, sizeof(DevName))) {
- if (Debug)
- Error("Cannot read device name from address 0x%x.", Addr);
- continue;
- }
- } else
- DevName[0] = C_NULL;
-
- /*
- * Get the controller name
- */
- if (Addr = (u_long) Driver.mdr_cname) {
- if (KVM_read(kd, Addr, (char *) CtlrName, sizeof(CtlrName))) {
- if (Debug)
- Error(
- "Cannot read controller name from address 0x%x.", Addr);
- continue;
- }
- } else
- CtlrName[0] = C_NULL;
-
- /* Make sure devdata is clean */
- bzero(&DevData, sizeof(DEVDATA));
-
- /* Set what we know */
- if (DevName[0]) {
- DevData.dd_devname = strdup(DevName);
- DevData.dd_devunit = Device.md_unit;
- }
- if (CtlrName[0]) {
- DevData.dd_ctlrname = strdup(CtlrName);
- DevData.dd_ctlrunit = Device.md_ctlr;
- }
- /*
- * Mainbus devices such, as SCSI targets, may not exist
- * but the controller reports them as present
- */
- if (Device.md_alive)
- DevData.dd_flags |= DD_MAYBE_ALIVE;
-
- if (Debug)
- printf("MainBus: Found \"%s\" (Unit %d) on \"%s\" (Unit %d) %s\n",
- DevData.dd_devname, DevData.dd_devunit,
- DevData.dd_ctlrname, DevData.dd_ctlrunit,
- (DevData.dd_flags & DD_MAYBE_ALIVE) ? "[MAYBE-ALIVE]" : "");
-
- /* Probe and add device */
- if (Dev = ProbeDevice(&DevData, TreePtr))
- AddDevice(Dev, TreePtr);
- }
-
- KVM_close(kd);
- return(0);
- }
- #endif /* HAVE_MAINBUS */
-
- #if defined(HAVE_OPENPROM)
- /*
- * OpenPROM stuff
- */
- #include <sun/openprom.h>
-
- /*
- * Build device tree by looking at OpenPROM (op)
- */
- static int BuildOpenPROM(TreePtr)
- DEVICE **TreePtr;
- {
- static struct dev_info Root, *PtrRoot;
- extern struct nlist OpenPROMNL[];
- u_long Addr;
-
- if (!(kd = KVM_open(OpenPROMNL))) {
- if (Debug) Error("Cannot open kernel and read openprom devinfo");
- return(-1);
- }
-
- /*
- * See if we got a valid entry
- */
- if (CheckNlist(&OpenPROMNL[0]))
- return(-1);
-
- /*
- * Read pointer to "top_devinfo" from kernel
- */
- Addr = OpenPROMNL[0].n_value;
- if (KVM_read(kd, Addr, (char *) &PtrRoot, sizeof(struct dev_info *))) {
- if (Debug) Error("Cannot read openprom devinfo pointer from kernel");
- return(-1);
- }
-
- if (KVM_read(kd, (u_long)PtrRoot, (char *)&Root,
- sizeof(struct dev_info))) {
- if (Debug) Error("Cannot read openprom devinfo root from kernel");
- return(-1);
- }
-
- return(OpenPROMTraverse(&Root, NULL, TreePtr));
- }
-
- /*
- * Check an OpenPROM device.
- */
- static int CheckOpenPROMDevice(DevInfo, Parent, TreePtr)
- struct dev_info *DevInfo;
- struct dev_info *Parent;
- DEVICE **TreePtr;
- {
- static DEVDATA DevData;
- DEVICE *Device;
-
- /* Make sure devdata is clean */
- bzero(&DevData, sizeof(DEVDATA));
-
- /* Set what we know */
- if (DevInfo && DevInfo->devi_name) {
- DevData.dd_devname = DevInfo->devi_name;
- DevData.dd_devunit = DevInfo->devi_unit;
- }
- if (Parent && Parent->devi_name) {
- DevData.dd_ctlrname = Parent->devi_name;
- DevData.dd_ctlrunit = Parent->devi_unit;
- }
- /*
- * OpenPROM nodes that have a driver ALWAYS exist.
- * Some nodes may exist, without a driver, however.
- */
- if (DevInfo->devi_driver)
- DevData.dd_flags |= DD_IS_ALIVE;
-
- if (Debug)
- printf("OPENPROM: Found \"%s\" (Unit %d) on \"%s\" (Unit %d) %s\n",
- DevData.dd_devname, DevData.dd_devunit,
- DevData.dd_ctlrname, DevData.dd_ctlrunit,
- (DevData.dd_flags & DD_IS_ALIVE) ? "[ALIVE]" : "");
-
- /* Probe and add device */
- if (Device = (DEVICE *) ProbeDevice(&DevData, TreePtr))
- AddDevice(Device, TreePtr);
- }
-
- /*
- * Recursively traverse and descend the OpenPROM devinfo tree.
- */
- static int OpenPROMTraverse(DevPtr, Parent, TreePtr)
- struct dev_info *DevPtr;
- struct dev_info *Parent;
- DEVICE **TreePtr;
- {
- static char Name[BUFSIZ];
- struct dev_info *Ptr;
-
- /*
- * If node name is a valid pointer, read the name from kernel space
- * and call openprom_probe to handle checking the device.
- */
- if (DevPtr->devi_name) {
- if (KVM_read(kd, (u_long) DevPtr->devi_name, (char *) Name,
- sizeof(Name))) {
- Error("Cannot read openprom device name.");
- Name[0] = C_NULL;
- } else {
- DevPtr->devi_name = (char *) strdup(Name);
- CheckOpenPROMDevice(DevPtr, Parent, TreePtr);
- }
- }
-
- /*
- * If this node has slaves, read the slave data from kernel space
- * and descend.
- */
- if (DevPtr->devi_slaves) {
- Ptr = (struct dev_info *) xcalloc(1, sizeof(struct dev_info));
- if (KVM_read(kd, (u_long) DevPtr->devi_slaves, (char *) Ptr,
- sizeof(struct dev_info))) {
- Error("Cannot read openprom slave data for %s.", Name);
- } else {
- DevPtr->devi_slaves = (struct dev_info *) Ptr;
- OpenPROMTraverse(DevPtr->devi_slaves, DevPtr, TreePtr);
- }
- }
-
- /*
- * If this node has a next pointer, read the next data from kernel space
- * and traverse.
- */
- if (DevPtr->devi_next) {
- Ptr = (struct dev_info *) xcalloc(1, sizeof(struct dev_info));
- if (KVM_read(kd, (u_long) DevPtr->devi_next, (char *) Ptr,
- sizeof(struct dev_info))) {
- Error("Cannot read openprom next data for %s.", Name);
- } else {
- DevPtr->devi_next = (struct dev_info *) Ptr;
- OpenPROMTraverse(DevPtr->devi_next, Parent, TreePtr);
- }
- }
-
- return(0);
- }
- #endif /* HAVE_OPENPROM */
-
- /*
- * Build device tree using TreePtr.
- * Calls bus and method specific functions to
- * search for devices.
- */
- extern int BuildDevicesSunOS(TreePtr)
- DEVICE **TreePtr;
- {
- int Found = 1;
-
- #if defined(HAVE_OPENPROM)
- if (BuildOpenPROM(TreePtr) == 0)
- Found = 0;
- #endif /* HAVE_OPENPROM */
-
- #if defined(HAVE_MAINBUS)
- if (BuildMainBus(TreePtr) == 0)
- Found = 0;
- #endif /* HAVE_MAINBUS */
-
- return(Found);
- }
-
- /*
- * Scan the Disk Controller table looking for
- * a specific type.
- */
- static DKCTLRTAB *GetDkCtlrTab(DkCtrlType)
- int DkCtrlType;
- {
- extern DKCTLRTAB DkCtlrTab[];
- register int i;
-
- for (i = 0; DkCtlrTab[i].ct_model; ++i) {
- if (DkCtrlType == DkCtlrTab[i].ct_ctype)
- return(&DkCtlrTab[i]);
- }
-
- return((DKCTLRTAB *) NULL);
- }
-
- /*
- * Scan the Frame Buffer table looking for
- * a specific fb type.
- */
- static NAMETAB *GetFBTab(FBType)
- int FBType;
- {
- extern NAMETAB FBTab[];
- register int i;
-
- for (i = 0; FBTab[i].name; ++i) {
- if (FBType == FBTab[i].value)
- return(&FBTab[i]);
- }
-
- return((NAMETAB *) NULL);
- }
-
- /*
- * Get disk info structure.
- */
- static struct dk_info *GETdk_info(d, file)
- int d;
- char *file;
- {
- static struct dk_info dk_info;
-
- if (ioctl(d, DKIOCINFO, &dk_info) < 0) {
- if (Debug) Error("%s: DKIOCINFO: %s.", file, SYSERR);
- return(NULL);
- }
-
- return(&dk_info);
- }
-
- /*
- * Get disk configuration structure.
- */
- static struct dk_conf *GETdk_conf(d, file)
- int d;
- char *file;
- {
- static struct dk_conf dk_conf;
-
- if (ioctl(d, DKIOCGCONF, &dk_conf) < 0) {
- if (Debug) Error("%s: DKIOCGCONF: %s.", file, SYSERR);
- return(NULL);
- }
-
- return(&dk_conf);
- }
-
- /*
- * Get disk geometry structure.
- */
- static struct dk_geom *GETdk_geom(d, file)
- int d;
- char *file;
- {
- static struct dk_geom dk_geom;
-
- if (ioctl(d, DKIOCGGEOM, &dk_geom) < 0) {
- if (Debug) Error("%s: DKIOCGGEOM: %s.", file, SYSERR);
- return(NULL);
- }
-
- return(&dk_geom);
- }
-
- /*
- * Get disk type structure.
- */
- static struct dk_type *GETdk_type(d, file)
- int d;
- char *file;
- {
- static struct dk_type dk_type;
-
- if (ioctl(d, DKIOCGTYPE, &dk_type) < 0) {
- if (errno != ENOTTY)
- if (Debug) Error("%s: DKIOCGTYPE: %s.", file, SYSERR);
- return(NULL);
- }
-
- return(&dk_type);
- }
-
- /*
- * Check the checksum of a disklabel.
- */
- static int DkLblCheckSum(DkLabel)
- struct dk_label *DkLabel;
- {
- register short *Ptr, Sum = 0;
- register short Count;
-
- Count = (sizeof (struct dk_label)) / (sizeof (short));
- Ptr = (short *)DkLabel;
-
- /*
- * Take the xor of all the half-words in the label.
- */
- while (Count--)
- Sum ^= *Ptr++;
-
- /*
- * The total should be zero for a correct checksum
- */
- return(Sum);
- }
-
- /*
- * Get label information from label on disk.
- * The label is stored in the first sector of the disk.
- * We use the driver specific "read" flag with the DKIOCSCMD
- * ioctl to read the first sector. There should be a special
- * ioctl to just read the label.
- */
- static struct dk_label *GETdk_label(d, file, dk_info)
- int d;
- char *file;
- struct dk_info *dk_info;
- {
- static struct dk_label dk_label;
- struct dk_cmd dk_cmd;
- struct dkctlrtab *pct;
-
- if (!file || !dk_info)
- return((struct dk_label *) NULL);
-
- if (!(pct = GetDkCtlrTab((int) dk_info->dki_ctype))) {
- Error("Controller type %d is unknown.",
- dk_info->dki_ctype);
- return((struct dk_label *) NULL);
- }
-
- if (pct->ct_rdcmd < 0) {
- if (Debug)
- Error("Read block on controller type \"%s\" is unsupported.",
- pct->ct_model);
- return((struct dk_label *) NULL);
- }
-
- bzero((char *) &dk_cmd, sizeof(dk_cmd));
- dk_cmd.dkc_cmd = pct->ct_rdcmd;
- dk_cmd.dkc_flags = DK_SILENT | DK_ISOLATE;
- dk_cmd.dkc_blkno = (daddr_t)0;
- dk_cmd.dkc_secnt = 1;
- dk_cmd.dkc_bufaddr = (char *) &dk_label;
- dk_cmd.dkc_buflen = SECSIZE;
-
- if (ioctl(d, DKIOCSCMD, &dk_cmd) < 0) {
- if (Debug) Error("%s: DKIOCSCMD: %s.", file, SYSERR);
- return((struct dk_label *) NULL);
- }
-
- if (dk_label.dkl_magic != DKL_MAGIC) {
- Error("%s: Disk not labeled.", file);
- return((struct dk_label *) NULL);
- }
-
- if (DkLblCheckSum(&dk_label)) {
- Error("%s: Bad label checksum.", file);
- return((struct dk_label *) NULL);
- }
-
- return(&dk_label);
- }
-
- /*
- * Get the name of a disk (i.e. sd0).
- */
- static char *GetDiskName(name, dk_conf, dk_info)
- char *name;
- struct dk_conf *dk_conf;
- struct dk_info *dk_info;
- {
- if (!dk_conf || !dk_info) {
- if (name)
- return(name);
- return((char *) NULL);
- }
-
- #if defined(DKI_HEXUNIT)
- if (FLAGS_ON(dk_info->dki_flags, DKI_HEXUNIT))
- (void) sprintf(Buf, "%s%3.3x", dk_conf->dkc_dname, dk_conf->dkc_unit);
- else
- #endif /* DKI_HEXUNIT */
- (void) sprintf(Buf, "%s%d", dk_conf->dkc_dname, dk_conf->dkc_unit);
-
- return(strdup(Buf));
- }
-
- /*
- * Get the name of the controller for a disk.
- */
- static char *GetDkCtlrName(dk_conf)
- struct dk_conf *dk_conf;
- {
- if (!dk_conf)
- return((char *) NULL);
-
- (void) sprintf(Buf, "%s%d", dk_conf->dkc_cname, dk_conf->dkc_cnum);
-
- return(strdup(Buf));
- }
-
- /*
- * Get the disk controller model name from a disk.
- */
- static char *GetDkCtlrModel(dk_info)
- struct dk_info *dk_info;
- {
- struct dkctlrtab *pct;
-
- if (!dk_info)
- return((char *) NULL);
-
- if (!(pct = GetDkCtlrTab(dk_info->dki_ctype)))
- return(NULL);
-
- return(pct->ct_model);
- }
-
- /*
- * Get a disk controller device from disk info.
- */
- static DEVICE *GetDkCtlrDevice(DevData, dk_info, dk_conf)
- DEVDATA *DevData;
- struct dk_info *dk_info;
- struct dk_conf *dk_conf;
- {
- DEVICE *MkMasterFromDevData();
- DEVICE *dkctlr;
-
- if ((dkctlr = NewDevice(NULL)) == NULL)
- return((DEVICE *) NULL);
-
- bzero((char *) dkctlr, sizeof(*dkctlr));
-
- dkctlr->dv_type = DT_DISKCTLR;
-
- /*
- * Get name of controller from devdata if available
- */
- if (DevData && DevData->dd_ctlrname) {
- dkctlr = MkMasterFromDevData(DevData);
- }
-
- if (dk_conf) {
- if (!dkctlr->dv_name) {
- dkctlr->dv_name = GetDkCtlrName(dk_conf);
- dkctlr->dv_unit = dk_conf->dkc_cnum;
- }
- dkctlr->dv_addr = dk_conf->dkc_addr;
- dkctlr->dv_prio = dk_conf->dkc_prio;
- dkctlr->dv_vec = dk_conf->dkc_vec;
- }
-
- if (dk_info) {
- dkctlr->dv_model = GetDkCtlrModel(dk_info);
- }
-
- return(dkctlr);
- }
-
- /*
- * Get disk label info from the extracted dk_label info.
- */
- static char *GetDiskLabel(dk_label)
- struct dk_label *dk_label;
- {
- register char *p;
-
- if (!dk_label)
- return((char *) NULL);
-
- (void) strcpy(Buf, dk_label->dkl_asciilabel);
-
- /*
- * The label normally has geometry information in it we don't want
- * to see, so we trim out anything starting with " cyl".
- */
- for (p = Buf; p && *p; ++p) {
- if (*p == ' ' && strncasecmp(p, " cyl", 4) == 0)
- *p = C_NULL;
- }
-
- return(strdup(Buf));
- }
-
- /*
- * Get filesystem mount info for a partition.
- */
- static char *GetMountInfo(name, part)
- char *name;
- char *part;
- {
- FILE *mf;
- struct mntent *mntent;
- char *file;
-
- if (!name)
- return((char *) NULL);
-
- file = GetCharFile(name, part);
-
- if ((mf = setmntent(MNTTAB, "r")) == NULL) {
- Error("%s: Cannot open for reading: %s.", MNTTAB, SYSERR);
- return(NULL);
- }
-
- while (mntent = getmntent(mf)) {
- if (strcmp(mntent->mnt_fsname, file) == 0)
- break;
- }
-
- endmntent(mf);
-
- return((mntent) ? mntent->mnt_dir : (char *) NULL);
- }
-
- /*
- * Extract the disk partition info from a disk.
- */
- static DISKPART *ExtractDiskPart(name, part, dk_conf, dk_geom)
- char *name;
- char *part;
- struct dk_conf *dk_conf;
- struct dk_geom *dk_geom;
- {
- static DISKPART diskpart;
- struct dk_map dk_map;
- char *file;
- char *p;
- int d;
-
- if (!name || !dk_conf || !dk_geom)
- return((DISKPART *) NULL);
-
- file = GetRawFile(name, part);
-
- if (stat(file, &StatBuf) != 0) {
- if (Debug) Error("%s: No such partition.", file);
- return((DISKPART *) NULL);
- }
-
- if ((d = open(file, O_RDONLY)) < 0) {
- if (Debug)
- Error("%s: Cannot open for read: %s.", file, SYSERR);
- return((DISKPART *) NULL);
- }
-
- if (ioctl(d, DKIOCGPART, &dk_map) != 0) {
- Error("%s: Cannot extract partition info: %s.",
- file, SYSERR);
- return((DISKPART *) NULL);
- }
-
- (void) close(d);
-
- /*
- * Skip empty partitions
- */
- if (!dk_map.dkl_nblk) {
- if (Debug) Error("%s: partition has no size.", file);
- return((DISKPART *) NULL);
- }
-
- bzero((char *) &diskpart, sizeof(DISKPART));
-
- diskpart.dp_name = strdup(part);
-
- if (p = GetMountInfo(name, part))
- diskpart.dp_mnt = strdup(p);
- /*
- * If this is the "b" partition on the root device,
- * then assume it's swap
- */
- else if (dk_conf->dkc_unit == 0 && strcmp(part, "b") == 0)
- diskpart.dp_mnt = "swap";
-
- diskpart.dp_stsect = dk_map.dkl_cylno *
- (dk_geom->dkg_nhead * dk_geom->dkg_nsect);
- diskpart.dp_nsect = dk_map.dkl_nblk;
-
- return(&diskpart);
- }
-
- /*
- * Translate disk partition information from basic
- * extracted disk info.
- */
- static DISKPART *GetDiskPart(name, dk_conf, dk_geom)
- char *name;
- struct dk_conf *dk_conf;
- struct dk_geom *dk_geom;
- {
- extern char PartChars[];
- register DISKPART *pdp, *dp;
- register int i;
- static char pname[2];
- DISKPART *base = NULL;
-
- if (!name || !dk_conf || !dk_geom)
- return((DISKPART *) NULL);
-
- pname[1] = C_NULL;
- for (i = 0; PartChars[i]; ++i) {
- pname[0] = PartChars[i];
- if (dp = ExtractDiskPart(name, pname, dk_conf, dk_geom)) {
- if (base) {
- for (pdp = base; pdp && pdp->dp_nxt; pdp = pdp->dp_nxt);
- pdp->dp_nxt = NewDiskPart(dp);
- } else {
- base = NewDiskPart(dp);
- }
- }
- }
-
- return(base);
- }
-
- /*
- * Convert all we've learned about a disk to a DEVICE.
- */
- static DEVICE *dkToDiskDevice(name, DevData,
- dk_info, dk_label, dk_conf, dk_geom, dk_type)
- char *name;
- DEVDATA *DevData;
- struct dk_info *dk_info;
- struct dk_label *dk_label;
- struct dk_conf *dk_conf;
- struct dk_geom *dk_geom;
- struct dk_type *dk_type;
- {
- DEVICE *Device, *dkctlr;
- DISKDRIVE *diskdrive;
-
- if ((Device = NewDevice(NULL)) == NULL) {
- Error("Cannot create new device entry.");
- return((DEVICE *) NULL);
- }
-
- if ((dkctlr = NewDevice(NULL)) == NULL) {
- Error("Cannot create new dkctlr device entry.");
- return((DEVICE *) NULL);
- }
-
- if ((diskdrive = NewDiskDrive(NULL)) == NULL) {
- Error("Cannot create new diskdrive entry.");
- return((DEVICE *) NULL);
- }
-
- Device->dv_name = GetDiskName(name, dk_conf, dk_info);
- Device->dv_type = DT_DISKDRIVE;
- /*
- * Only read partition info we we're going to print it later.
- */
- if (VL_ALL)
- diskdrive->dd_part = GetDiskPart(name, dk_conf, dk_geom);
- diskdrive->dd_label = GetDiskLabel(dk_label);
- Device->dv_model = diskdrive->dd_label;
-
- if (dk_conf) {
- diskdrive->dd_unit = dk_conf->dkc_unit;
- diskdrive->dd_slave = dk_conf->dkc_slave;;
- }
- if (dk_geom) {
- diskdrive->dd_dcyl = dk_geom->dkg_ncyl;
- diskdrive->dd_pcyl = dk_geom->dkg_pcyl;
- diskdrive->dd_acyl = dk_geom->dkg_acyl;
- diskdrive->dd_heads = dk_geom->dkg_nhead;
- diskdrive->dd_sect = dk_geom->dkg_nsect;
- diskdrive->dd_apc = dk_geom->dkg_apc;
- diskdrive->dd_rpm = dk_geom->dkg_rpm;
- diskdrive->dd_intrlv = dk_geom->dkg_intrlv;
- }
- if (dk_type) {
- diskdrive->dd_psect = dk_type->dkt_hsect;
- diskdrive->dd_promrev = dk_type->dkt_promrev;
- }
- if (dk_info) {
- #if defined(DKI_HEXUNIT)
- if (FLAGS_ON(dk_info->dki_flags, DKI_HEXUNIT))
- diskdrive->dd_flags |= DF_HEXUNIT;
- #endif /* DKI_HEXUNIT */
- }
-
- diskdrive->dd_secsize = SECSIZE;
- if (diskdrive->dd_dcyl && diskdrive->dd_sect && diskdrive->dd_heads) {
- static char Buf[BUFSIZ];
-
- diskdrive->dd_size = nsect_to_bytes(diskdrive->dd_dcyl *
- diskdrive->dd_sect *
- diskdrive->dd_heads,
- diskdrive->dd_secsize);
-
- (void) sprintf(Buf, "%.2f MB capacity",
- (float) bytes_to_mbytes(diskdrive->dd_size));
- Device->dv_desc = strdup(Buf);
- }
-
- dkctlr = GetDkCtlrDevice(DevData, dk_info, dk_conf);
-
- Device->dv_devspec = (caddr_t *) diskdrive;
- Device->dv_master = dkctlr;
-
- return(Device);
- }
-
- /*
- * Query and learn about a disk.
- */
- extern DEVICE *ProbeDiskDrive(name, DevData, DevDataTab)
- /*ARGSUSED*/
- char *name;
- DEVDATA *DevData;
- DEVDATATAB *DevDataTab;
- {
- DEVICE *diskdevice;
- struct dk_info *dk_info = NULL;
- struct dk_conf *dk_conf = NULL;
- struct dk_type *dk_type = NULL;
- struct dk_label *dk_label = NULL;
- struct dk_geom *dk_geom = NULL;
- char *rfile;
- int d;
-
- if (!name)
- return((DEVICE *) NULL);
-
- #if defined(HAVE_IPI)
- /*
- * XXX - Kludge for IPI "id" disks.
- */
- if (EQ(DevData->dd_devname, "id")) {
- static char Buf[BUFSIZ];
-
- (void) sprintf(Buf, "%s%3.3x",
- DevData->dd_devname, DevData->dd_devunit);
- name = Buf;
- }
- #endif /* HAVE_IPI */
-
- if (stat(rfile = GetRawFile(name, NULL), &StatBuf) != 0) {
- /*
- * Get the name of the whole disk raw device.
- */
- rfile = GetRawFile(name, "c");
- }
-
- if ((d = open(rfile, O_RDONLY)) < 0) {
- if (Debug) Error("%s: Cannot open for reading: %s.", rfile, SYSERR);
- /*
- * If we know for sure this drive is present and we
- * know something about it, then create a minimal device.
- */
- if ((DevDataTab->ddt_model || DevDataTab->ddt_desc) &&
- FLAGS_ON(DevData->dd_flags, DD_IS_ALIVE)) {
- Device = NewDevice((DEVICE *) NULL);
- Device->dv_name = strdup(name);
- Device->dv_unit = DevData->dd_devunit;
- Device->dv_master = MkMasterFromDevData(DevData);
- Device->dv_type = DT_DISKDRIVE;
- Device->dv_model = DevDataTab->ddt_model;
- Device->dv_desc = DevDataTab->ddt_desc;
- return(Device);
- } else
- return((DEVICE *) NULL);
- }
-
- if ((dk_conf = GETdk_conf(d, rfile)) == NULL) {
- if (Debug) Error("%s: get dk_conf failed.", rfile);
- }
-
- if ((dk_info = GETdk_info(d, rfile)) == NULL) {
- if (Debug) Error("%s: get dk_info failed.", rfile);
- }
-
- if ((dk_geom = GETdk_geom(d, rfile)) == NULL) {
- if (Debug) Error("%s: get dk_geom failed.", rfile);
- }
-
- if ((dk_label = GETdk_label(d, rfile, dk_info)) == NULL) {
- if (Debug) Error("%s: get dk_label failed.", rfile);
- }
-
- /*
- * Not all controllers support dk_type
- */
- dk_type = GETdk_type(d, rfile);
-
- close(d);
-
- if (!(diskdevice = dkToDiskDevice(name, DevData,
- dk_info, dk_label,
- dk_conf, dk_geom, dk_type))) {
- Error("%s: Cannot convert diskdrive information.", name);
- return((DEVICE *) NULL);
- }
-
- return(diskdevice);
- }
-
- /*
- * Probe a tape device
- */
- extern DEVICE *ProbeTapeDrive(name, DevData, DevDataTab)
- /*ARGSUSED*/
- char *name;
- DEVDATA *DevData;
- DEVDATATAB *DevDataTab;
- {
- extern NAMETAB MtInfo[];
- DEVICE *Device;
- char *file;
- char *model = NULL;
- static char Buf[BUFSIZ];
- struct mtget mtget;
- register int i;
- int d;
-
- file = GetRawFile(name, NULL);
-
- if ((d = open(file, O_RDONLY)) < 0) {
- if (Debug)
- Error("%s Cannot open for read: %s.", file, SYSERR);
-
- /*
- * --RECURSE--
- * If we haven't tried the "mt" name yet, try it now
- */
- if (strncmp(name, MTNAME, strlen(MTNAME)) != 0) {
- (void) sprintf(Buf, "%s%d", MTNAME, DevData->dd_devunit);
- Device = ProbeTapeDrive(Buf, DevData, DevDataTab);
- if (Device)
- return(Device);
- }
-
- /*
- * If we know for sure this drive is present and we
- * know something about it, then create a minimal device.
- */
- if ((DevDataTab->ddt_model || DevDataTab->ddt_desc) &&
- FLAGS_ON(DevData->dd_flags, DD_IS_ALIVE)) {
- Device = NewDevice((DEVICE *) NULL);
- /*
- * Recreate name from devdata since we might have had to
- * call ourself with name "rmt?"
- */
- (void) sprintf(Buf, "%s%d", DevData->dd_devname,
- DevData->dd_devunit);
- Device->dv_name = strdup(Buf);
- Device->dv_unit = DevData->dd_devunit;
- Device->dv_master = MkMasterFromDevData(DevData);
- Device->dv_type = DT_TAPEDRIVE;
- Device->dv_model = DevDataTab->ddt_model;
- Device->dv_desc = DevDataTab->ddt_desc;
- return(Device);
- } else
- return((DEVICE *) NULL);
- }
-
- if (ioctl(d, MTIOCGET, &mtget) != 0) {
- Error("%s: Cannot extract tape status: %s.", file, SYSERR);
- return((DEVICE *) NULL);
- }
-
- (void) close(d);
-
- model = "unknown";
-
- for (i = 0; MtInfo[i].name; ++i) {
- if ((MtInfo[i].value == mtget.mt_type)) {
- model = MtInfo[i].name;
- break;
- }
- }
-
- /*
- * Create and set device info
- */
- Device = NewDevice(NULL);
- Device->dv_name = strdup(name);
- Device->dv_type = DT_TAPEDRIVE;
- if (model)
- Device->dv_model = model;
- else
- Device->dv_model = DevDataTab->ddt_model;
- Device->dv_desc = DevDataTab->ddt_desc;
- Device->dv_unit = DevData->dd_devunit;
- Device->dv_master = MkMasterFromDevData(DevData);
-
- return(Device);
- }
-
- /*
- * Probe a CPU.
- *
- * This function really "fakes" up an entry.
- *
- * Currently the info only comes from the OpenPROM. We could
- * use the kernel mach_info and mod_info structures, but they
- * don't provide the model of CPU. Maybe in a future release.
- */
- extern DEVICE *ProbeCPU(name, DevData, DevDataTab)
- /*ARGSUSED*/
- char *name;
- DEVDATA *DevData;
- DEVDATATAB *DevDataTab;
- {
- static int num_cpus = 0;
-
- Device = NewDevice(NULL);
- (void) sprintf(Buf, "cpu%d", num_cpus++);
- Device->dv_name = strdup(Buf);
- Device->dv_type = DT_CPU;
- Device->dv_model = strdup(name);
- Device->dv_desc = DevDataTab->ddt_desc;
- Device->dv_master = MkMasterFromDevData(DevData);
-
- return(Device);
- }
-
- /*
- * Probe a FrameBuffer.
- */
- extern DEVICE *ProbeFrameBuffer(name, DevData, DevDataTab)
- char *name;
- DEVDATA *DevData;
- DEVDATATAB *DevDataTab;
- {
- DEVICE *fbdevice;
- FRAMEBUFFER *fb;
- NAMETAB *fbtab;
- struct fbgattr fbattr;
- #ifdef FBIOGXINFO
- struct cg6_info cg6_info;
- #endif
- char *file, Buf[BUFSIZ];
- int d;
-
- if (!name)
- return((DEVICE *) NULL);
-
- /*
- * Check the device file. If the stat fails because
- * the device doesn't exist, trying the default framebuffer
- * device /dev/fb.
- */
- file = GetCharFile(name, NULL);
- if (stat(file, &StatBuf) != 0) {
- if (errno == ENOENT && !EQ(name, FBDEVICE)) {
- if (Debug)
- Error("Framebuffer device %s does not exist. Trying `fb'.",
- name);
- return(ProbeFrameBuffer(FBDEVICE, DevData, DevDataTab));
- }
- }
-
- if ((d = open(file, O_RDONLY)) < 0) {
- if (Debug) Error("%s: Cannot open for reading: %s.", file, SYSERR);
- return((DEVICE *) NULL);
- }
-
- if (ioctl(d, FBIOGATTR, &fbattr) != 0) {
- if (ioctl(d, FBIOGTYPE, &fbattr.fbtype) != 0) {
- if (Debug) Error("%s: FBIOGATTR/FBIOGTYPE: %s.",
- file, SYSERR);
- return((DEVICE *) NULL);
- }
- }
-
- Buf[0] = C_NULL;
- #if defined(FBIOGXINFO)
- if (ioctl(d, FBIOGXINFO, &cg6_info) == 0) {
- sprintf(Buf, "SBus Slot %d, Revision %d",
- cg6_info.slot, cg6_info.boardrev);
- if (cg6_info.hdb_capable)
- (void) strcat(Buf, ", double buffered");
- else
- (void) strcat(Buf, ", single buffered");
- } else {
- bzero((char *) &cg6_info, sizeof(struct cg6_info));
- if (Debug) Error("%s: FBIOGXINFO: %s.", file, SYSERR);
- }
- #endif /* FBIOGXINFO */
-
- close(d);
-
- if (!(fb = NewFrameBuffer(NULL))) {
- Error("Cannot create new frame buffer.");
- return((DEVICE *) NULL);
- }
-
- if (!(fbdevice = NewDevice(NULL))) {
- Error("Cannot create new frame buffer device entry.");
- return((DEVICE *) NULL);
- }
-
- if (!(fbtab = GetFBTab(fbattr.fbtype.fb_type))) {
- Error("Device %s is an unknown type (%d) of frame buffer.",
- name, fbattr.fbtype.fb_type);
- }
-
- fbdevice->dv_name = name;
- fbdevice->dv_type = DT_FRAMEBUFFER;
- fbdevice->dv_devspec = (caddr_t *) fb;
-
- if (Buf[0])
- fbdevice->dv_desc = strdup(Buf);
-
- if (fbtab) {
- fbdevice->dv_model = fbtab->name;
- } else {
- fbdevice->dv_model = "UNKNOWN";
- }
-
- fb->fb_height = fbattr.fbtype.fb_height;
- fb->fb_width = fbattr.fbtype.fb_width;
- fb->fb_depth = fbattr.fbtype.fb_depth;
- fb->fb_size = fbattr.fbtype.fb_size;
- fb->fb_cmsize = fbattr.fbtype.fb_cmsize;
- #if defined(FBIOGXINFO)
- if (cg6_info.vmsize)
- fb->fb_vmsize = mbytes_to_bytes(cg6_info.vmsize);
- #endif /* FBIOGXINFO */
-
- fbdevice->dv_master = MkMasterFromDevData(DevData);
-
- return(fbdevice);
- }
-
- /*
- * Determine our cpu model name.
- *
- * We lookup the kernel symbol "cpu" instead of using gethostid()
- * because some SPARC vendors do not encode cpu/model info in gethostid().
- */
- extern char *GetModelName()
- {
- extern NAMETAB ModelTab[];
- extern struct nlist CpuNL[];
- register int i;
- int Cpu;
- kvm_t *kd;
-
- if (!(kd = KVM_open(CpuNL))) {
- if (Debug) Error("Cannot find cpu symbol in kernel.");
- return((char *) NULL);
- }
-
- /*
- * See if we got a valid entry
- */
- if (CheckNlist(&CpuNL[0]))
- return((char *) NULL);
-
- if (KVM_read(kd, (u_long) CpuNL[0].n_value, (char *) &Cpu, sizeof(Cpu))) {
- if (Debug) Error("Cannot read cpu from kernel.");
- return((char *) NULL);
- }
-
- KVM_close(kd);
-
- for (i = 0; ModelTab[i].name; ++i)
- if (Cpu == ModelTab[i].value)
- return(ModelTab[i].name);
-
- if (Debug)
- Error("No model found; CPU = 0x%x.", Cpu);
-
- return((char *) NULL);
- }
-
- #if defined(CPU_ARCH) /* Sun */
- #define ARCH_MASK CPU_ARCH
- #endif /* CPU_ARCH */
- #if defined(CPU_TYPE) /* Solbourne */
- #define ARCH_MASK CPU_TYPE
- #endif /* CPU_TYPE */
- /*
- * Determine our kernel architecture name from our hostid.
- */
- extern char *GetKernArchName()
- {
- #if defined(ARCH_MASK)
- extern NAMETAB KernArchTab[];
- extern struct nlist CpuNL[];
- kvm_t *kd;
- int Cpu;
- register int i;
-
- if (!(kd = KVM_open(CpuNL))) {
- if (Debug) Error("Cannot find cpu symbol in kernel.");
- return((char *) NULL);
- }
-
- /*
- * See if we got a valid entry
- */
- if (CheckNlist(&CpuNL[0]))
- return((char *) NULL);
-
- if (KVM_read(kd, (u_long) CpuNL[0].n_value, (char *) &Cpu, sizeof(Cpu))) {
- if (Debug) Error("Cannot read cpu from kernel.");
- return((char *) NULL);
- }
-
- KVM_close(kd);
-
- for (i = 0; KernArchTab[i].name; ++i)
- if ((Cpu & ARCH_MASK) == KernArchTab[i].value)
- return(KernArchTab[i].name);
-
- if (Debug)
- Error("Kernel Arch 0x%x not defined; Cpu = 0x%x Mask = 0x%x",
- Cpu & ARCH_MASK, Cpu, ARCH_MASK);
- #endif /* ARCH_MASK */
-
- return((char *) NULL);
- }
-
- #if defined(HAVE_NIT)
-
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <net/if.h>
- #include <net/nit_if.h>
-
- /*
- * Find and set the MAC info using the Network Interface Tap (NIT)
- */
- extern void SetMacInfoNIT(DevName, NetIf)
- char *DevName;
- NETIF *NetIf;
- {
- register struct sockaddr *SockAddr;
- struct ifreq ifreq;
- char *ether_ntoa(), Buf[MAXHOSTNAMLEN+1];
- int Desc;
-
- if (!NetIf)
- return;
-
- if ((Desc = open("/dev/nit", O_RDONLY)) == SYSFAIL) {
- if (Debug) Error("open /dev/nit failed");
- return;
- }
-
- /*
- * Bind to NIT for DevName
- */
- strncpy(ifreq.ifr_name, DevName, sizeof ifreq.ifr_name);
- if (ioctl(Desc, NIOCBIND, (caddr_t) &ifreq) < 0) {
- if (Debug) Error("ioctl: NIOCBIND");
- return;
- }
-
- /*
- * Get address
- */
- if (ioctl(Desc, SIOCGIFADDR, (caddr_t)&ifreq) < 0) {
- if (Debug) Error("ioctl (SIOCGIFADDR)");
- return;
- }
-
- (void) close(Desc);
-
- SockAddr = (struct sockaddr *)&ifreq.ifr_addr;
- NetIf->ni_macaddr = strdup(ether_ntoa((struct ether_addr *)
- SockAddr->sa_data));
-
- if (ether_ntohost(Buf, (struct ether_addr *) SockAddr->sa_data) == 0)
- NetIf->ni_macname = strdup(Buf);
- }
- #endif /* HAVE_NIT */
-
- /*
- * Get kernel version string from kernel symbol "version".
- */
- extern char *GetKernelVersionStr()
- {
- return(GetKernelVersionFromVersion());
- }
-
- /*
- * Get amount of physical memory using kernel symbol "physmem".
- */
- extern char *GetMemory()
- {
- return(GetMemoryFromPhysmem());
- }
-
- /*
- * Get system serial number
- */
- extern char *GetSerialNoStr()
- {
- /* No support */
- return((char *) NULL);
- }
-
- /*
- * Get name of OS
- */
- extern char *GetOSNameStr()
- {
- return(GetOSNameFromUname());
- }
-
- /*
- * Get version of OS
- */
- extern char *GetOSVersionStr()
- {
- return(GetOSVersionFromUname());
- }
-
- #if defined(HAVE_SUNROMVEC)
- /*
- * Be backwards compatible with pre-4.1.2 code
- */
- #include <mon/sunromvec.h>
- #if defined(OPENPROMS) && !(defined(ROMVEC_VERSION) && \
- (ROMVEC_VERSION == 0 || ROMVEC_VERSION == 1))
- #define v_mon_id op_mon_id
- #endif
- #endif /* HAVE_SUNROMVEC */
-
- /*
- * Get ROM Version number
- *
- * If "romp" is "defined" (in <mon/sunromvec.h>), then take that
- * as the address of the kernel pointer to "rom" (struct sunromvec).
- * Otherwise, nlist "romp" from the kernel.
- */
- extern char *GetRomVer()
- {
- static char RomRev[16];
- #if defined(HAVE_SUNROMVEC)
- static struct sunromvec Rom;
- register char *p;
- register char *Addr;
- kvm_t *kd;
- #if !defined(romp)
- struct sunromvec *romp;
- extern struct nlist RomVecNL[];
-
- if (!(kd = KVM_open(RomVecNL))) {
- if (Debug) Error("Cannot find romvec symbol in kernel.");
- return((char *) NULL);
- }
-
- /*
- * See if we got a valid entry
- */
- if (CheckNlist(&RomVecNL[0]))
- return((char *) NULL);
-
- /*
- * Read the kernel pointer to the sunromvec structure.
- */
- if (KVM_read(kd, (u_long) RomVecNL[0].n_value, (char *) &romp,
- sizeof(romp))) {
- if (Debug) Error("Cannot read sunromvec pointer from kernel.");
- return((char *) NULL);
- }
-
- #else /* romp */
-
- if (!(kd = KVM_open((struct nlist *) NULL))) {
- if (Debug) Error("KVM_open failed.");
- return((char *) NULL);
- }
-
- #endif /* romp */
-
- /*
- * Read the sunromvec structure from the kernel
- */
- /*SUPPRESS 25*/
- if (KVM_read(kd, (u_long) romp, (char *) &Rom, sizeof(struct sunromvec))) {
- if (Debug) Error("Cannot read sunromvec from kernel.");
- return((char *) NULL);
- }
-
- #if !defined(romp)
-
- /*
- * XXX Hardcoded values
- */
- (void) sprintf(RomRev, "%d.%d", Rom.v_mon_id >> 16, Rom.v_mon_id & 0xFFFF);
-
- #else /* romp */
-
- /*
- * Read the version string from the address indicated by Rom.v_mon_id.
- * Read 1 byte at a time until '\0' is encountered.
- */
- p = RomRev;
- Addr = Rom.v_mon_id;
- do {
- if (KVM_read(kd, (u_long) Addr++, p, 1))
- break;
- } while (p < &RomRev[sizeof(RomRev)-1] && *p++);
- *p = C_NULL;
-
- #endif /* romp */
-
- KVM_close(kd);
-
- #endif /* HAVE_SUNROMVEC */
-
- return((RomRev[0]) ? RomRev : (char *) NULL);
- }
-