This is os-next.c in view mode; [Download] [Up]
/* * 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.11 1992/11/24 04:05:57 mcooper Exp mcooper $"; #endif /* * $Log: os-next.c,v $ * Revision 1.11 1992/11/24 04:05:57 mcooper * New/cleaner KVM/nlist interface. * * 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 char NeXTBusSYM[]; struct nlist *nlptr; static struct nlist nlistbuf; 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 = KVMopen())) return(-1); if ((nlptr = KVMnlist(kd, NeXTBusSYM, &nlistbuf)) == NULL) return(-1); if (CheckNlist(nlptr)) return(-1); /* * Read each device table entry. A NULL device.bd_driver * indicates that we're at the end of the table. */ for (DeviceAddr = nlptr->n_value; DeviceAddr; DeviceAddr += DV_SIZE) { /* * Read this device */ if (KVMread(kd, DeviceAddr, (char *) &Device, DV_SIZE)) { if (Debug) Error("Cannot read NeXTbus device from address 0x%x.", DeviceAddr); KVMclose(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 (KVMread(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 (KVMread(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 (KVMread(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 (KVMread(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); } KVMclose(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() { struct nlist *nlptr; extern NAMETAB ModelTab[]; extern char MachineTypeSYM[]; u_char MachineType; register int i; kvm_t *kd; if (!(kd = KVMopen())) return((char *) NULL); if ((nlptr = KVMnlist(kd, MachineTypeSYM, (struct nlist *)NULL)) == NULL) return((char *) NULL); if (CheckNlist(nlptr)) return((char *) NULL); if (KVMread(kd, (u_long) nlptr->n_value, (char *) &MachineType, sizeof(MachineType))) { if (Debug) Error("Cannot read \"%s\" from kernel.", MachineTypeSYM); return((char *) NULL); } KVMclose(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); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.