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-next.c,v 1.10 1992/04/26 23:32:06 mcooper Exp $";
- #endif
-
- /*
- * $Log: os-next.c,v $
- * Revision 1.10 1992/04/26 23:32:06 mcooper
- * Add Copyright notice
- *
- * Revision 1.9 1992/04/17 23:27:51 mcooper
- * Add support for ROM Version information (Sun only for now).
- *
- * Revision 1.8 1992/04/17 01:07:59 mcooper
- * More de-linting
- *
- * Revision 1.7 1992/04/15 02:04:16 mcooper
- * Change GetMemoryStr() to GetMemory().
- *
- * Revision 1.6 1992/03/31 02:22:03 mcooper
- * Fix failed return value from CheckNlist().
- *
- * Revision 1.5 1992/03/31 01:55:17 mcooper
- * Use new CheckNlist to check nlist success.
- *
- * Revision 1.4 1992/03/31 00:15:09 mcooper
- * Add error check for nlist.n_type.
- *
- * Revision 1.3 1992/03/28 21:59:28 mcooper
- * Implemented disk and netif device probing.
- *
- * Revision 1.2 1992/03/22 02:03:48 mcooper
- * Add Build*NeXT*() functions.
- *
- * Revision 1.1 1992/03/22 01:04:34 mcooper
- * Initial revision
- *
- */
-
-
- /*
- * NeXT specific functions
- */
-
- #include <stdio.h>
- #include "system.h"
- #include "defs.h"
-
- #include <nlist.h>
- #include <mntent.h>
- #include <nextdev/disk.h>
- #include <nextdev/busvar.h>
-
- #define DV_SIZE (sizeof(struct bus_device))
- #define DR_SIZE (sizeof(struct bus_driver))
- #define CR_SIZE (sizeof(struct bus_ctrl))
-
- /*
- * Build a device tree by searching NeXTBus
- */
- static int BuildNeXTBus(TreePtr)
- DEVICE **TreePtr;
- {
- extern struct nlist NeXTBusNL[];
- static struct bus_device Device;
- static struct bus_driver Driver;
- static struct bus_ctrl Ctlr;
- static char CtlrName[BUFSIZ], DevName[BUFSIZ];
- u_long Addr, DeviceAddr;
- static DEVDATA DevData;
- DEVICE *Dev;
- kvm_t *kd;
-
- /*
- * Read table address from kernel
- */
- if (!(kd = KVM_open(NeXTBusNL))) {
- if (Debug) Error("Cannot read NeXTBus device table from kernel.");
- return(-1);
- }
-
- /*
- * See if we got a valid entry
- */
- if (CheckNlist(&NeXTBusNL[0]))
- return(-1);
-
- /*
- * Read each device table entry. A NULL device.bd_driver
- * indicates that we're at the end of the table.
- */
- for (DeviceAddr = NeXTBusNL[0].n_value; DeviceAddr;
- DeviceAddr += DV_SIZE) {
-
- /*
- * Read this device
- */
- if (KVM_read(kd, DeviceAddr, (char *) &Device, DV_SIZE)) {
- if (Debug)
- Error("Cannot read NeXTbus device from address 0x%x.",
- DeviceAddr);
- KVM_close(kd);
- return(-1);
- }
-
- /*
- * See if we're done.
- */
- if (!Device.bd_driver)
- break;
-
- /*
- * Get the device name
- */
- DevName[0] = C_NULL;
- if (Addr = (u_long) Device.bd_name) {
- 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;
- /*
- * First read the controller structure in
- */
- if (Addr = (u_long) Device.bd_bc) {
- if (KVM_read(kd, Addr, (char *) &Ctlr, CR_SIZE)) {
- if (Debug)
- Error("Cannot read controller from address 0x%x.", Addr);
- } else if (Addr = (u_long) Ctlr.bc_driver) {
- /*
- * Get the controller driver
- */
- if (KVM_read(kd, Addr, (char *) &Driver, DR_SIZE)) {
- if (Debug)
- Error(
- "Cannot read controller driver from address 0x%x.",
- Addr);
- continue;
- }
- /*
- * Read the name of the controller from the driver
- */
- if (!(Addr = (u_long) Driver.br_cname)) {
- if (Debug)
- Error("No name for controller at address 0x%x.",
- Ctlr.bc_driver);
- continue;
- }
- if (KVM_read(kd, Addr, CtlrName, sizeof(CtlrName))) {
- if (Debug)
- Error("Read controller name failed (address 0x%x).",
- Addr);
- continue;
- }
- }
- }
-
- if (Debug)
- printf("NeXTbus: 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.bd_unit;
- DevData.dd_slave = Device.bd_slave;
- }
- if (CtlrName[0]) {
- DevData.dd_ctlrname = strdup(CtlrName);
- DevData.dd_ctlrunit = Ctlr.bc_ctrl;
- }
-
- /*
- * NeXTbus devices should always exist.
- */
- if (Device.bd_alive)
- DevData.dd_flags |= DD_IS_ALIVE;
-
- /* Probe and add device */
- if (Dev = (DEVICE *) ProbeDevice(&DevData, TreePtr, NULL))
- AddDevice(Dev, TreePtr);
- }
-
- KVM_close(kd);
-
- return(0);
- }
-
- /*
- * Build list of NeXT devices
- */
- extern int BuildDevicesNeXT(TreePtr)
- DEVICE **TreePtr;
- {
- int Found = 1;
-
- if (BuildNeXTBus(TreePtr) == 0)
- Found = 0;
-
- return(Found);
- }
-
- /*
- * Get the system model name. NeXT keeps the system type
- * in a kernel variable called machine_type.
- * The system types are defined in <next/scr.h>.
- */
- extern char *GetModelName()
- {
- extern NAMETAB ModelTab[];
- extern struct nlist MachineTypeNL[];
- u_char MachineType;
- register int i;
- kvm_t *kd;
-
- if (!(kd = KVM_open(MachineTypeNL))) {
- if (Debug) Error("Cannot find machine_type symbol in kernel.");
- return((char *) NULL);
- }
-
- /*
- * See if we got a valid entry
- */
- if (CheckNlist(&MachineTypeNL[0]))
- return((char *) NULL);
-
- if (KVM_read(kd, (u_long) MachineTypeNL[0].n_value,
- (char *) &MachineType, sizeof(MachineType))) {
- if (Debug) Error("Cannot read \"%s\" from kernel.",
- GetNlName(MachineTypeNL[0]));
- return((char *) NULL);
- }
-
- KVM_close(kd);
-
- for (i = 0; ModelTab[i].name; ++i)
- if (ModelTab[i].value == MachineType)
- return(ModelTab[i].name);
-
- if (Debug)
- printf("system model/type %d is unknown.\n", MachineType);
-
- return((char *) NULL);
- }
-
- /*
- * Get kernel version string using Mach HostInfo method
- */
- extern char *GetKernelVersionStr()
- {
- return(GetKernelVersionFromHostInfo());
- }
-
- /*
- * Get amount of physical memory using Mach HostInfo method
- */
- extern char *GetMemory()
- {
- return(GetMemoryFromHostInfo());
- }
-
- /*
- * Get application architecture name using Mach HostInfo method.
- */
- extern char *GetAppArchName()
- {
- return(GetAppArchFromHostInfo());
- }
-
- /*
- * Get kernel architecture name using Mach HostInfo method.
- */
- extern char *GetKernArchName()
- {
- return(GetKernArchFromHostInfo());
- }
-
- /*
- * Get system serial number
- */
- extern char *GetSerialNoStr()
- {
- /* No support */
- return((char *) NULL);
- }
-
- /*
- * Get OS version using Mach HostInfo method.
- */
- extern char *GetOSVersionStr()
- {
- return(GetOSVersionFromHostInfo());
- }
-
- /*
- * 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);
- }
-
- /*
- * Get disk partition information
- */
- static DISKPART *GetDiskPart(Name, DiskLabel)
- char *Name;
- struct disk_label *DiskLabel;
- {
- register int i;
- register DISKPART *Ptr;
- DISKPART *Base = NULL;
- DISKPART DiskPart;
- static char Part[2];
- register char *p;
-
- Part[1] = C_NULL;
-
- /*
- * Now handle each partition
- */
- for (i = 0; i < NPART; i++) {
- /* Ingore partitins that have no size */
- if (DiskLabel->dl_dt.d_partitions[i].p_size <= 0)
- continue;
-
- Part[0] = 'a' + i;
-
- /* Make a clean slate */
- bzero((char *) &DiskPart, sizeof(DISKPART));
-
- /* Fill in the blanks */
- DiskPart.dp_name = strdup(Part);
- DiskPart.dp_stsect = DiskLabel->dl_dt.d_partitions[i].p_base;
- DiskPart.dp_nsect = DiskLabel->dl_dt.d_partitions[i].p_size;
-
- /*
- * Get the mount point name.
- */
- if (p = GetMountInfo(Name, Part))
- DiskPart.dp_mnt = strdup(p);
-
- /*
- * Add this partition to the linked list.
- */
- if (Base) {
- for (Ptr = Base; Ptr && Ptr->dp_nxt; Ptr = Ptr->dp_nxt);
- Ptr->dp_nxt = NewDiskPart(&DiskPart);
- } else {
- Base = NewDiskPart(&DiskPart);
- }
- }
-
- return(Base);
- }
-
- /*
- * Convert disk info into a DEVICE entry.
- */
- static DEVICE *diskToDiskDrive(Name, DevData, DevDataTab, DiskLabel, DriveInfo)
- char *Name;
- DEVDATA *DevData;
- DEVDATATAB *DevDataTab;
- struct disk_label *DiskLabel;
- struct drive_info *DriveInfo;
- {
- DEVICE *Device;
- DISKDRIVE *DiskDrive;
- static char Buf[BUFSIZ];
-
- if ((Device = NewDevice(NULL)) == NULL) {
- Error("Cannot create new device entry.");
- return((DEVICE *) NULL);
- }
-
- if ((DiskDrive = NewDiskDrive(NULL)) == NULL) {
- Error("Cannot create new diskdrive entry.");
- return((DEVICE *) NULL);
- }
-
- Device->dv_name = strdup(Name);
- Device->dv_type = DT_DISKDRIVE;
- DiskDrive->dd_label = strdup(DriveInfo->di_name);
- Device->dv_model = DiskDrive->dd_label;
- DiskDrive->dd_unit = DevData->dd_devunit;
- DiskDrive->dd_slave = DevData->dd_slave;
- DiskDrive->dd_dcyl = DiskLabel->dl_ncyl;
- DiskDrive->dd_heads = DiskLabel->dl_ntrack;
- DiskDrive->dd_sect = DiskLabel->dl_nsect;
- DiskDrive->dd_apc = DiskLabel->dl_ngroups;
- DiskDrive->dd_rpm = DiskLabel->dl_rpm;
- DiskDrive->dd_secsize = DiskLabel->dl_secsize;
- /*
- * Only get partition info we we're going to print it later.
- */
- if (VL_ALL)
- DiskDrive->dd_part = GetDiskPart(Name, DiskLabel);
-
- /*
- * Determine size (capacity) of media
- */
- if (DiskDrive->dd_dcyl && DiskDrive->dd_sect && DiskDrive->dd_heads)
- DiskDrive->dd_size = nsect_to_bytes(DiskDrive->dd_dcyl *
- DiskDrive->dd_sect *
- DiskDrive->dd_heads,
- DiskDrive->dd_secsize);
-
- /*
- * Create the description
- */
- if (DiskDrive->dd_size > 0) {
- (void) sprintf(Buf, "%.2f MB capacity",
- (float) bytes_to_mbytes(DiskDrive->dd_size));
- Device->dv_desc = strdup(Buf);
- }
-
- Device->dv_devspec = (caddr_t *) DiskDrive;
- Device->dv_master = MkMasterFromDevData(DevData);
-
- return(Device);
- }
-
- /*
- * Query and learn about a disk.
- */
- extern DEVICE *ProbeDiskDrive(Name, DevData, DevDataTab)
- /*ARGSUSED*/
- char *Name;
- DEVDATA *DevData;
- DEVDATATAB *DevDataTab;
- {
- static struct disk_label DiskLabel;
- static struct drive_info DriveInfo;
- int Desc;
- char *File;
- DEVICE *Device;
-
- File = GetRawFile(Name, "a");
-
- if ((Desc = open(File, O_RDONLY|O_NDELAY)) < 0) {
- if (Debug) Error("%s: Cannot open for read: %s.\n", 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);
- }
-
- /*
- * Read disk label
- */
- if (ioctl(Desc, DKIOCGLABEL, &DiskLabel) < 0) {
- if (Debug) Error("%s: DKIOCGLABEL: %s.", File, SYSERR);
- return((DEVICE *) NULL);
- }
-
- /*
- * Read drive info
- */
- if (ioctl(Desc, DKIOCINFO, &DriveInfo) < 0) {
- if (Debug) Error("%s: DKIOCINFO: %s.", File, SYSERR);
- return((DEVICE *) NULL);
- }
-
- close(Desc);
-
- if (!(Device = diskToDiskDrive(Name, DevData, DevDataTab,
- &DiskLabel, &DriveInfo))) {
- Error("%s: Cannot convert diskdrive info.", Name);
- return((DEVICE *) NULL);
- }
-
- return(Device);
- }
-
- /*
- * Get ROM Version
- */
- extern char *GetRomVer()
- {
- /* No support */
- return((char *) NULL);
- }
-