home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume26
/
sysinfo-1.0
/
part01
/
os-next.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-10
|
12KB
|
531 lines
/*
* 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);
}