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-ultrix.c,v 1.14 1992/04/26 23:32:06 mcooper Exp $";
- #endif
-
- /*
- * $Log: os-ultrix.c,v $
- * Revision 1.14 1992/04/26 23:32:06 mcooper
- * Add Copyright notice
- *
- * Revision 1.13 1992/04/17 23:27:51 mcooper
- * Add support for ROM Version information (Sun only for now).
- *
- * Revision 1.12 1992/04/17 01:07:59 mcooper
- * More de-linting
- *
- * Revision 1.11 1992/04/16 19:56:24 mcooper
- * De-linting stuff.
- *
- * Revision 1.10 1992/04/15 02:04:16 mcooper
- * Change GetMemoryStr() to GetMemory().
- *
- * Revision 1.9 1992/03/31 02:22:03 mcooper
- * Fix failed return value from CheckNlist().
- *
- * Revision 1.8 1992/03/31 01:55:17 mcooper
- * Use new CheckNlist to check nlist success.
- *
- * Revision 1.7 1992/03/31 00:15:09 mcooper
- * Add error check for nlist.n_type.
- *
- * Revision 1.6 1992/03/22 00:20:10 mcooper
- * Major cleanup and re-org.
- *
- * Revision 1.5 1992/03/09 01:07:50 mcooper
- * Add support for determining system model type.
- *
- * Revision 1.4 1992/03/08 23:08:41 mcooper
- * - Add new set_macinfo_packetfilter().
- * - Remove unneeded get_bus().
- *
- * Revision 1.3 1992/03/08 04:57:09 mcooper
- * Set DT_TAPEDRIVE in probe_tapedrive().
- *
- * Revision 1.2 1992/03/08 01:11:39 mcooper
- * Add tape drive support.
- *
- * Revision 1.1 1992/03/06 18:35:40 mcooper
- * Initial revision
- *
- */
-
- /*
- * Ultrix specific functions
- */
-
- #include <stdio.h>
- #include "system.h"
- #include "defs.h"
-
- #include <fcntl.h>
- #include <nlist.h>
- #include <fstab.h>
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/fs.h>
- #include <sys/ioctl.h>
- #include <sys/buf.h>
- #include <sys/stat.h>
-
- #include <machine/cpuconf.h>
-
- #include <sys/devio.h>
- #include <sys/mtio.h>
-
- #include "info-ultrix.h"
-
- #if defined(HAVE_UBA)
- /*
- * UBA (UniBus Adapter) specific code
- */
- #include <io/uba/ubavar.h>
-
- /*
- * Probe specific structure
- */
- struct _probespec {
- struct uba_device *uba_device;
- };
- typedef struct _probespec PROBESPEC;
-
- #define DV_SIZE (sizeof(struct uba_device))
- #define CR_SIZE (sizeof(struct uba_ctlr))
-
- /*
- * Build a device tree by searching Unibus Adapters
- */
- static int BuildUBA(TreePtr)
- DEVICE **TreePtr;
- {
- extern struct nlist UniBusNL[];
- static struct uba_device Device;
- static struct uba_ctlr Ctlr;
- static char CtlrName[BUFSIZ], DevName[BUFSIZ];
- u_long Addr, DeviceAddr;
- static DEVDATA DevData;
- static PROBESPEC ProbeSpec;
- DEVICE *dev;
- kvm_t *kd;
- int cnum;
-
- /*
- * Read table address from kernel
- */
- if (!(kd = KVM_open(UniBusNL))) {
- if (Debug) Error("Cannot read unibus device table from kernel.");
- return(-1);
- }
-
- /*
- * See if we got a valid entry
- */
- if (CheckNlist(&UniBusNL[0]))
- return(-1);
-
- /*
- * Read each device table entry. A NULL device.ui_driver
- * indicates that we're at the end of the table.
- */
- for (DeviceAddr = UniBusNL[0].n_value; DeviceAddr;
- DeviceAddr += DV_SIZE) {
-
- /*
- * Read this device
- */
- if (KVM_read(kd, DeviceAddr, (char *) &Device, DV_SIZE)) {
- if (Debug)
- Error("Cannot read unibus device from address 0x%x.",
- DeviceAddr);
- KVM_close(kd);
- return(-1);
- }
-
- /*
- * See if we're done.
- */
- if (!Device.ui_driver)
- break;
-
- /*
- * Get the device name
- */
- DevName[0] = C_NULL;
- if (Addr = (u_long) Device.ui_devname) {
- if (KVM_read(kd, Addr, (char *) DevName, sizeof(DevName))) {
- if (Debug)
- Error("Cannot read device name from address 0x%x.", Addr);
- continue;
- }
- }
-
- /*
- * Get the controller info
- */
- CtlrName[0] = C_NULL;
- cnum = -1;
- if (Addr = (u_long) Device.ui_mi) {
- if (KVM_read(kd, Addr, (char *) &Ctlr, CR_SIZE)) {
- if (Debug)
- Error("Cannot read controller from address 0x%x.", Addr);
- } else {
- /*
- * Get the controller name
- */
- if (Addr = (u_long) Ctlr.um_ctlrname) {
- if (KVM_read(kd, Addr, CtlrName, sizeof(CtlrName))) {
- if (Debug)
- Error(
- "Cannot read controller name from driver address 0x%x.",
- Addr);
- continue;
- }
- }
- cnum = Ctlr.um_ctlr;
- }
- }
-
- if (Debug)
- printf("build_unibus(): Found '%s' on '%s'.\n", DevName, CtlrName);
-
- /* 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.ui_unit;
- }
- if (CtlrName[0]) {
- DevData.dd_ctlrname = strdup(CtlrName);
- DevData.dd_ctlrunit = cnum;
- }
-
- /*
- * Unibus devices should always exist.
- */
- if (Device.ui_alive)
- DevData.dd_flags |= DD_IS_ALIVE;
-
- ProbeSpec.uba_device = &Device;
-
- /* Probe and add device */
- if (dev = (DEVICE *) ProbeDevice(&DevData, TreePtr, &ProbeSpec))
- AddDevice(dev, TreePtr);
- }
-
- KVM_close(kd);
-
- return(0);
- }
- #endif /* HAVE_UBA */
-
- /*
- * Build list of Ultrix devices
- */
- extern int BuildDevicesUltrix(TreePtr)
- DEVICE **TreePtr;
- {
- int Found = 1;
-
- #if defined(HAVE_UBA)
- if (BuildUBA(TreePtr) == 0)
- Found = 0;
- #endif /* HAVE_UBA */
-
- return(Found);
- }
-
- /*
- * Get Device Info structure from device.
- */
- static struct devget *GETdevget(File, FileD)
- char *File;
- int FileD;
- {
- static struct devget devget;
-
- if (ioctl(FileD, DEVIOCGET, &devget) == SYSFAIL) {
- if (Debug) Error("%s: ioctl DEVIOCGET failed: %s.", File, SYSERR);
- return((struct devget *) NULL);
- }
-
- return(&devget);
- }
-
- /*
- * Get Device Geometry structure from device.
- */
- static DEVGEOMST *GETdevgeom(File, FileD)
- char *File;
- int FileD;
- {
- static DEVGEOMST devgeom;
-
- if (ioctl(FileD, DEVGETGEOM, &devgeom) == SYSFAIL) {
- if (Debug) Error("%s: ioctl DEVGETGEOM failed: %s.", File, SYSERR);
- return((DEVGEOMST *) NULL);
- }
-
- return(&devgeom);
- }
-
- /*
- * Lookup a category type.
- */
- static char *GetCategory(val)
- int val;
- {
- extern NAMETAB Categorys[];
- register int i;
-
- for (i = 0; Categorys[i].name; ++i)
- if (val == Categorys[i].value)
- return(Categorys[i].name);
-
- return((char *) NULL);
- }
-
- /*
- * Convert a 'devget' to a 'device'.
- */
- static DEVICE *devgetToDEVICE(DevGet, DevData, ProbeSpec)
- struct devget *DevGet;
- DEVDATA *DevData;
- PROBESPEC *ProbeSpec;
- {
- DEVICE *Device;
-
- if (!(Device = NewDevice(NULL)))
- return(Device);
-
- Device->dv_name = strdup(MkDevName(DevData->dd_devname,
- DevData->dd_devunit));
- Device->dv_model = strdup(DevGet->device);
- Device->dv_desc = GetCategory(DevGet->category);
- Device->dv_unit = DevGet->unit_num;
-
- /*
- * Set master/controller info
- */
- if (Device->dv_master = MkMasterFromDevData(DevData))
- Device->dv_master->dv_model = strdup(DevGet->interface);
-
- return(Device);
- }
-
- /*
- * Check a device by trying to perform a devget on it.
- */
- static struct devget *CheckDevice(File)
- char *File;
- {
- struct devget *DevGet;
- int d;
-
- if ((d = open(File, O_RDONLY|O_NDELAY)) < 0) {
- if (Debug) Error("%s: Cannot open: %s.", File, SYSERR);
- return((struct devget *) NULL);
- }
-
- /*
- * Get generic device info
- */
- if (!(DevGet = GETdevget(File, d))) {
- if (Debug) Error("%s: GETdevget failed.", File);
- close(d);
- return((struct devget *) NULL);
- }
-
- close(d);
-
- return(DevGet);
- }
-
- /*
- * Retrieve disk partition information from a device file.
- */
- static struct pt *ExtractDiskPart(File)
- char *File;
- {
- static struct pt pt;
- int d;
-
- if ((d = open(File, O_RDONLY|O_NDELAY)) < 0) {
- if (Debug) Error("%s: open failed: %s.", File, SYSERR);
- return((struct pt *) NULL);
- }
-
- if (ioctl(d, DIOCGETPT, &pt) < 0) {
- if (Debug) Error("%s: ioctl DIOCGETPT failed: %s.", File, SYSERR);
- close(d);
- return((struct pt *) NULL);
- }
-
- close(d);
-
- return(&pt);
- }
-
- /*
- * Get the mount point for a filesystem.
- */
- static char *GetMountInfo(Name, Part)
- char *Name;
- char *Part;
- {
- char *File;
- struct fstab *fstab;
-
- File = GetCharFile(Name, Part);
- if (fstab = getfsspec(File)) {
- if (strcmp(fstab->fs_type, FSTAB_SW) == 0)
- return("swap");
- return(fstab->fs_file);
- }
-
- return((char *) NULL);
- }
-
- /*
- * Get the partition information for a disk device.
- */
- static DISKPART *GetPartInfo(Name, Device)
- char *Name;
- DEVICE *Device;
- {
- static DISKPART diskpart;
- static char Buf[BUFSIZ], part[2];
- register DISKPART *pdp, *dp;
- register char *p;
- DISKPART *base = NULL;
- struct pt *pt;
- register int i;
-
- /*
- * First get the partition info.
- */
- (void) sprintf(Buf, "/dev/r%sa", Name);
- if (!(pt = ExtractDiskPart(Buf)))
- return((DISKPART *) NULL);
-
- part[1] = C_NULL;
-
- /*
- * Now deal with each partition.
- */
- for (i = 0; i < MAX_DISK_PARTS; ++i) {
- /* Ignore partitions that have no size */
- if (!pt->pt_part[i].pi_nblocks)
- continue;
-
- part[0] = 'a' + i;
-
- /* Make a clean slate */
- bzero((char *) &diskpart, sizeof(DISKPART));
-
- /* Fill in what we know */
- diskpart.dp_name = strdup(part);
- diskpart.dp_stsect = pt->pt_part[i].pi_blkoff;
- diskpart.dp_nsect = pt->pt_part[i].pi_nblocks;
-
- /*
- * Get the mount point name.
- * If this is the "b" partition on the
- * root device, then assume it's swap
- */
- if (p = GetMountInfo(Name, part))
- diskpart.dp_mnt = strdup(p);
- else if (Device->dv_unit == 0 && strcmp(part, "b") == 0)
- diskpart.dp_mnt = "swap";
-
- /*
- * Add this partition to the linked list.
- */
- if (base) {
- for (pdp = base; pdp && pdp->dp_nxt; pdp = pdp->dp_nxt);
- pdp->dp_nxt = NewDiskPart(&diskpart);
- } else {
- base = NewDiskPart(&diskpart);
- }
- }
-
- return(base);
- }
-
- /*
- * Probe a disk drive
- */
- extern DEVICE *ProbeDiskDrive(Name, DevData, DevDataTab, ProbeSpec)
- char *Name;
- DEVDATA *DevData;
- DEVDATATAB *DevDataTab;
- PROBESPEC *ProbeSpec;
- {
- DEVICE *Device;
- DISKDRIVE *DiskDrive;
- DEVGEOMST *DevGeom;
- struct devget *DevGet;
- char *File;
- int Desc;
-
- if (!Name)
- return((DEVICE *) NULL);
-
- File = GetRawFile(Name, "c");
- if ((Desc = open(File, O_RDONLY|O_NDELAY)) < 0) {
- if (Debug) Error("%s: open failed: %s.", File, 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);
- }
-
- /*
- * Get generic device info
- */
- if (!(DevGet = GETdevget(File, Desc))) {
- if (Debug) Error("%s: GETdevget failed.", File);
- close(Desc);
- return((DEVICE *) NULL);
- }
-
- /*
- * Get geometry of device
- */
- if (!(DevGeom = GETdevgeom(File, Desc))) {
- if (Debug) Error("%s: get_geomst failed.", File);
- }
-
- close(Desc);
-
- /*
- * Convert devget info to a device struct
- */
- if (!(Device = devgetToDEVICE(DevGet, DevData, ProbeSpec))) {
- if (Debug) Error("%s: Cannot convert devget to device.");
- return((DEVICE *) NULL);
- }
-
- /*
- * Disks should be on disk controllers.
- */
- if (Device->dv_master)
- Device->dv_master->dv_type = DT_DISKCTLR;
-
- /*
- * Set the disk drive specific info
- */
-
- if ((DiskDrive = NewDiskDrive(NULL)) == NULL) {
- Error("Cannot create new diskdrive entry.");
- return((DEVICE *) NULL);
- }
-
- Device->dv_type = DT_DISKDRIVE;
- if (DevGet->device)
- DiskDrive->dd_label = strdup(DevGet->device);
-
- /*
- * Convert Geometry
- */
- if (DevGeom) {
- /*
- * If this is a removable device, indicate so.
- */
- if (FLAGS_ON(DevGeom->geom_info.attributes, DEVGEOM_REMOVE)) {
- if (Device->dv_desc) {
- char Buf[BUFSIZ];
-
- (void) sprintf(Buf, "Removable %s", Device->dv_desc);
- (void) free(Device->dv_desc);
- Device->dv_desc = strdup(Buf);
- } else {
- Device->dv_desc = "Removable disk drive";
- }
- }
-
- DiskDrive->dd_unit = DevGet->unit_num;
- DiskDrive->dd_slave = DevGet->slave_num;
- DiskDrive->dd_part = GetPartInfo(Name, Device);
- DiskDrive->dd_dcyl = DevGeom->geom_info.ncylinders;
- DiskDrive->dd_heads = DevGeom->geom_info.ntracks;
- DiskDrive->dd_sect = DevGeom->geom_info.nsectors;
- 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);
- }
- }
- Device->dv_devspec = (caddr_t *) DiskDrive;
-
- return(Device);
- }
-
- /*
- * Lookup info about a tape drive.
- */
- static char *GetTapeInfo(Flag)
- int Flag;
- {
- extern NAMETAB TapeInfo[];
- static char Buf[BUFSIZ];
- register int i;
-
- if (!Flag)
- return((char *) NULL);
-
- Buf[0] = C_NULL;
-
- /*
- * Values are flag bits and are appended together.
- */
- for (i = 0; TapeInfo[i].name; i++) {
- if (Flag & TapeInfo[i].value) {
- if (Buf[0]) {
- (void) strcat(Buf, ", ");
- (void) strcat(Buf, TapeInfo[i].name);
- } else
- (void) strcpy(Buf, TapeInfo[i].name);
- }
- }
-
- return(Buf);
- }
-
- /*
- * Probe a tape drive
- */
- extern DEVICE *ProbeTapeDrive(Name, DevData, DevDataTab, ProbeSpec)
- char *Name;
- DEVDATA *DevData;
- DEVDATATAB *DevDataTab;
- PROBESPEC *ProbeSpec;
- {
- struct devget *DevGet;
- DEVICE *Device;
- char *File;
- char *p;
- char Buf[BUFSIZ];
- register int i;
-
- /*
- * XXX Kludge Alert! ! !
- *
- * Ultrix tape device files are numbered independently of actual
- * unit number. Additionally, not all tape devices support the same
- * set of minor devices types, so we can't look at the minor device
- * number.
- *
- * The code below will open(), ioctl(), close() all tape
- * devices between 0 and MAXTAPES until a matching unit number is found.
- * This means that on systems with lots of tape drives, this can be
- * very slow.
- */
- for (i = 0; i < MAXTAPES; ++i) {
- (void) sprintf(Buf, "/dev/nrmt%dh", i);
- if ((DevGet = CheckDevice(Buf)) &&
- (DevGet->unit_num == DevData->dd_devunit))
- break;
- }
-
- if (!DevGet) {
- if (Debug) Error("%s: Cannot find device file.", Name);
- return((DEVICE *) NULL);
- }
-
- /*
- * Convert devget info to a device struct
- */
- if (!(Device = devgetToDEVICE(DevGet, DevData, ProbeSpec))) {
- if (Debug) Error("%s: Cannot convert devget to device.");
- return((DEVICE *) NULL);
- }
-
- /*
- * Set our device type
- */
- Device->dv_type = DT_TAPEDRIVE;
-
- /*
- * Get and add Tape Info
- */
- if (p = GetTapeInfo(DevGet->category_stat)) {
- if (Device->dv_desc) {
- (void) sprintf(Buf, "%s %s", p, Device->dv_desc);
- free(Device->dv_desc);
- Device->dv_desc = strdup(Buf);
- } else {
- Device->dv_desc = p;
- }
- }
-
- /*
- * Tapes should be on tape controllers.
- */
- if (Device->dv_master)
- Device->dv_master->dv_type = DT_TAPECTLR;
-
- return(Device);
- }
-
- /*
- * Get network type information
- */
- static char *GetNetType(type)
- int type;
- {
- extern NAMETAB NetTypes[];
- register int i;
-
- for (i = 0; NetTypes[i].name; i++)
- if (NetTypes[i].value == type)
- return(NetTypes[i].name);
-
- return((char *) NULL);
- }
-
-
- #if defined(HAVE_PACKETFILTER)
-
- #include <sys/time.h>
- #include <net/pfilt.h>
-
- #include <sys/socket.h>
- #include <net/if.h>
- #include <netinet/in.h>
- #include <netinet/if_ether.h>
-
- /*
- * Find and set the MAC info using the Packet Filter
- */
- extern void SetMacInfoPacketFilter(DevName, Netif, Device)
- char *DevName;
- NETIF *Netif;
- DEVICE *Device;
- {
- struct endevp endevp;
- struct ether_addr ether_addr;
- char *ether_ntoa(), HostBuf[MAXHOSTNAMLEN+1];
- char *p;
- int Desc;
-
- if (!DevName || !Netif)
- return;
-
- /*
- * Open this device using the packet filter
- */
- if ((Desc = pfopen(DevName, O_RDONLY)) < 0) {
- if (Debug) Error("pfopen %s failed: %s.", DevName, SYSERR);
- return;
- }
-
- /*
- * Retrieve info
- */
- if (ioctl(Desc, EIOCDEVP, &endevp) < 0) {
- if (Debug) Error("ioctl EIOCDEVP of %s failed: %s.", DevName, SYSERR);
- return;
- }
-
- close(Desc);
-
- /*
- * Convert address into ethers(5) format
- */
- bcopy((char *) endevp.end_addr,
- (char *) ether_addr.ether_addr_octet,
- endevp.end_addr_len);
-
- /*
- * Set what we now know.
- */
- if (p = ether_ntoa(ðer_addr))
- Netif->ni_macaddr = strdup(p);
-
- if (ether_ntohost(HostBuf, ðer_addr) == 0)
- Netif->ni_macname = strdup(HostBuf);
-
- if (Device && (p = GetNetType(endevp.end_dev_type)))
- Device->dv_desc = p;
- }
- #endif /* HAVE_PACKETFILTER */
-
- /*
- * Get the system model name. Ultrix keeps the system type
- * in a kernel structure called cpusw as cpusw.system_type.
- * The system types are defined in <machine/cpuconf.h>.
- */
- extern char *GetModelName()
- {
- extern NAMETAB ModelTab[];
- extern struct nlist CpuSwNL[];
- static struct cpusw CpuSw;
- register int i;
- kvm_t *kd;
-
- if (!(kd = KVM_open(CpuSwNL))) {
- if (Debug) Error("Cannot find cpusw symbol in kernel.");
- return((char *) NULL);
- }
-
- /*
- * See if we got a valid entry
- */
- if (CheckNlist(&CpuSwNL[0]))
- return((char *) NULL);
-
- if (KVM_read(kd, (u_long) CpuSwNL[0].n_value, (char *) &CpuSw,
- sizeof(struct cpusw))) {
- if (Debug) Error("Cannot read cpusw from kernel.");
- return((char *) NULL);
- }
-
- KVM_close(kd);
-
- for (i = 0; ModelTab[i].name; ++i)
- if (ModelTab[i].value == CpuSw.system_type)
- return(ModelTab[i].name);
-
- if (Debug)
- printf("system model/type %d is unknown.\n", CpuSw.system_type);
-
- return((char *) NULL);
- }
-
- /*
- * 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());
- }
-
- /*
- * Get ROM Version
- */
- extern char *GetRomVer()
- {
- /* No support */
- return((char *) NULL);
- }
-