summaryrefslogtreecommitdiffstats
path: root/sys/pc98/i386
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2001-11-05 21:46:35 +0000
committerphk <phk@FreeBSD.org>2001-11-05 21:46:35 +0000
commit9bb69cda6814a951f7b14172089a1c4858019928 (patch)
treeb2320606d6aa3181d17256744e906eb1b5d01276 /sys/pc98/i386
parentc54bcb11095795c80eddde895dcd9b0e52f07206 (diff)
downloadFreeBSD-src-9bb69cda6814a951f7b14172089a1c4858019928.zip
FreeBSD-src-9bb69cda6814a951f7b14172089a1c4858019928.tar.gz
GC userconfig after Peter axed it 15 months ago.
Diffstat (limited to 'sys/pc98/i386')
-rw-r--r--sys/pc98/i386/userconfig.c3178
1 files changed, 0 insertions, 3178 deletions
diff --git a/sys/pc98/i386/userconfig.c b/sys/pc98/i386/userconfig.c
deleted file mode 100644
index 1a8821f..0000000
--- a/sys/pc98/i386/userconfig.c
+++ /dev/null
@@ -1,3178 +0,0 @@
-/**
- ** Copyright (c) 1995
- ** Michael Smith, msmith@freebsd.org. All rights reserved.
- **
- ** This code contains a module marked :
-
- * Copyright (c) 1991 Regents of the University of California.
- * All rights reserved.
- * Copyright (c) 1994 Jordan K. Hubbard
- * All rights reserved.
- * Copyright (c) 1994 David Greenman
- * All rights reserved.
- *
- * Many additional changes by Bruce Evans
- *
- * This code is derived from software contributed by the
- * University of California Berkeley, Jordan K. Hubbard,
- * David Greenman and Bruce Evans.
-
- ** As such, it contains code subject to the above copyrights.
- ** The module and its copyright can be found below.
- **
- ** Redistribution and use in source and binary forms, with or without
- ** modification, are permitted provided that the following conditions
- ** are met:
- ** 1. Redistributions of source code must retain the above copyright
- ** notice, this list of conditions and the following disclaimer as
- ** the first lines of this file unmodified.
- ** 2. Redistributions in binary form must reproduce the above copyright
- ** notice, this list of conditions and the following disclaimer in the
- ** documentation and/or other materials provided with the distribution.
- ** 3. All advertising materials mentioning features or use of this software
- ** must display the following acknowledgment:
- ** This product includes software developed by Michael Smith.
- ** 4. The name of the author may not be used to endorse or promote products
- ** derived from this software without specific prior written permission.
- **
- ** THIS SOFTWARE IS PROVIDED BY MICHAEL SMITH ``AS IS'' AND ANY EXPRESS OR
- ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- ** IN NO EVENT SHALL MICHAEL SMITH BE LIABLE FOR ANY DIRECT, INDIRECT,
- ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- **
- ** $FreeBSD$
- **/
-
-/**
- ** USERCONFIG
- **
- ** Kernel boot-time configuration manipulation tool for FreeBSD.
- **
- ** Two modes of operation are supported : the default is the line-editor mode,
- ** the command "visual" invokes the fullscreen mode.
- **
- ** The line-editor mode is the old favorite from FreeBSD 2.0/20.05 &c., the
- ** fullscreen mode requires syscons or a minimal-ansi serial console.
- **/
-
-/**
- ** USERCONFIG, visual mode.
- **
- ** msmith@freebsd.org
- **
- ** Look for "EDIT THIS LIST" to add to the list of known devices
- **
- **
- ** There are a number of assumptions made in this code.
- **
- ** - That the console supports a minimal set of ANSI escape sequences
- ** (See the screen manipulation section for a summary)
- ** and has at least 24 rows.
- ** - That values less than or equal to zero for any of the device
- ** parameters indicate that the driver does not use the parameter.
- ** - That flags are _always_ editable.
- **
- ** Devices marked as disabled are imported as such.
- **
- ** For this tool to be useful, the list of devices below _MUST_ be updated
- ** when a new driver is brought into the kernel. It is not possible to
- ** extract this information from the drivers in the kernel.
- **
- ** XXX - TODO:
- **
- ** - Display _what_ a device conflicts with.
- ** - Implement page up/down (as what?)
- ** - Wizard mode (no restrictions)
- ** - Find out how to put syscons back into low-intensity mode so that the
- ** !b escape is useful on the console. (It seems to be that it actually
- ** gets low/high intensity backwards. That looks OK.)
- **
- ** - Only display headings with devices under them. (difficult)
- **/
-
-/*
- * PC-9801 port by KATO Takenori <kato@eclogite.eps.nagoya-u.ac.jp>
- */
-
-#include "opt_userconfig.h"
-#define COMPAT_OLDISA /* get the definitions */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/reboot.h>
-#include <sys/linker.h>
-#include <sys/sysctl.h>
-#include <sys/bus.h>
-#include <sys/cons.h>
-
-#include <machine/md_var.h>
-#include <machine/limits.h>
-
-#define _I386_ISA_ISA_DEVICE_H_
-
-static MALLOC_DEFINE(M_DEVL, "uc_devlist", "uc_device lists in userconfig()");
-
-#include <machine/uc_device.h>
-static struct uc_device *uc_devlist; /* list read by kget to extract changes */
-static struct uc_device *uc_devtab; /* fake uc_device table */
-
-static int userconfig_boot_parsing; /* set if we are reading from the boot instructions */
-
-#define putchar(x) cnputc(x)
-
-static void load_devtab(void);
-static void free_devtab(void);
-static void save_resource(struct uc_device *);
-
-static int
-sysctl_machdep_uc_devlist(SYSCTL_HANDLER_ARGS)
-{
- struct uc_device *id;
- int error=0;
- char name[8];
-
- if(!req->oldptr) {
- /* Only sizing */
- id=uc_devlist;
- while(id) {
- error+=sizeof(struct uc_device)+8;
- id=id->id_next;
- }
- return(SYSCTL_OUT(req,0,error));
- } else {
- /* Output the data. The buffer is filled with consecutive
- * struct uc_device and char buf[8], containing the name
- * (not guaranteed to end with '\0').
- */
- id=uc_devlist;
- while(id) {
- error=sysctl_handle_opaque(oidp,id,
- sizeof(struct uc_device),req);
- if(error) return(error);
- strncpy(name,id->id_name,8);
- error=sysctl_handle_opaque(oidp,name,
- 8,req);
- if(error) return(error);
- id=id->id_next;
- }
- return(0);
- }
-}
-
-SYSCTL_PROC( _machdep, OID_AUTO, uc_devlist, CTLFLAG_RD,
- 0, 0, sysctl_machdep_uc_devlist, "A",
- "List of ISA devices changed in UserConfig");
-
-/*
-** Obtain command input.
-**
-** Initially, input is read from a possibly-loaded script.
-** At the end of the script, or if no script is supplied,
-** behaviour is determined by the RB_CONFIG (-c) flag. If
-** the flag is set, user input is read from the console; if
-** unset, the 'quit' command is invoked and userconfig
-** will exit.
-**
-** Note that quit commands encountered in the script will be
-** ignored if the RB_CONFIG flag is supplied.
-*/
-static const char *config_script;
-static int config_script_size; /* use of int for -ve magic value */
-
-#define has_config_script() (config_script_size > 0)
-
-static int
-init_config_script(void)
-{
- caddr_t autoentry, autoattr;
-
- /* Look for loaded userconfig script */
- autoentry = preload_search_by_type("userconfig_script");
- if (autoentry != NULL) {
- /* We have one, get size and data */
- config_script_size = 0;
- if ((autoattr = preload_search_info(autoentry, MODINFO_SIZE)) != NULL)
- config_script_size = (size_t)*(u_int32_t *)autoattr;
- config_script = NULL;
- if ((autoattr = preload_search_info(autoentry, MODINFO_ADDR)) != NULL)
- config_script = *(const char **)autoattr;
- /* sanity check */
- if ((config_script_size == 0) || (config_script == NULL)) {
- config_script_size = 0;
- config_script = NULL;
- }
- }
- return has_config_script();
-}
-
-static int
-getchar(void)
-{
- int c = -1;
-#ifdef INTRO_USERCONFIG
- static int intro = 0;
-#endif
-
- if (has_config_script())
- {
- /* Consume character from loaded userconfig script, display */
- userconfig_boot_parsing = 1;
- c = *config_script;
- config_script++;
- config_script_size--;
-
- } else {
-
-#ifdef INTRO_USERCONFIG
- if (userconfig_boot_parsing) {
- if (!(boothowto & RB_CONFIG)) {
- /* userconfig_script, !RB_CONFIG -> quit */
- if (intro == 0) {
- c = 'q';
- config_script = "uit\n";
- config_script_size = strlen(config_script);
- /* userconfig_script will be 1 on the next pass */
- }
- } else {
- /* userconfig_script, RB_CONFIG -> cngetc() */
- }
- } else {
- if (!(boothowto & RB_CONFIG)) {
- /* no userconfig_script, !RB_CONFIG -> show intro */
- if (intro == 0) {
- intro = 1;
- c = 'i';
- config_script = "ntro\n";
- config_script_size = strlen(config_script);
- /* userconfig_script will be 1 on the next pass */
- }
- } else {
- /* no userconfig_script, RB_CONFIG -> cngetc() */
- }
- }
-#else /* !INTRO_USERCONFIG */
- /* assert(boothowto & RB_CONFIG) */
-#endif /* INTRO_USERCONFIG */
- userconfig_boot_parsing = 0;
- if (c <= 0)
- c = cngetc();
- }
- return(c);
-}
-
-#ifndef FALSE
-#define FALSE (0)
-#define TRUE (!FALSE)
-#endif
-
-#ifdef VISUAL_USERCONFIG
-
-typedef struct
-{
- char dev[16]; /* device basename */
- char name[60]; /* long name */
- int attrib; /* things to do with the device */
- int class; /* device classification */
-} DEV_INFO;
-
-#define FLG_INVISIBLE (1<<0) /* device should not be shown */
-#define FLG_MANDATORY (1<<1) /* device can be edited but not disabled */
-#define FLG_FIXIRQ (1<<2) /* device IRQ cannot be changed */
-#define FLG_FIXIOBASE (1<<3) /* device iobase cannot be changed */
-#define FLG_FIXMADDR (1<<4) /* device maddr cannot be changed */
-#define FLG_FIXMSIZE (1<<5) /* device msize cannot be changed */
-#define FLG_FIXDRQ (1<<6) /* device DRQ cannot be changed */
-#define FLG_FIXED (FLG_FIXIRQ|FLG_FIXIOBASE|FLG_FIXMADDR|FLG_FIXMSIZE|FLG_FIXDRQ)
-#define FLG_IMMUTABLE (FLG_FIXED|FLG_MANDATORY)
-
-#define CLS_STORAGE 1 /* storage devices */
-#define CLS_NETWORK 2 /* network interfaces */
-#define CLS_COMMS 3 /* serial, parallel ports */
-#define CLS_INPUT 4 /* user input : mice, keyboards, joysticks etc */
-#define CLS_MMEDIA 5 /* "multimedia" devices (sound, video, etc) */
-#define CLS_MISC 255 /* none of the above */
-
-
-typedef struct
-{
- char name[60];
- int number;
-} DEVCLASS_INFO;
-
-static DEVCLASS_INFO devclass_names[] = {
-{ "Storage : ", CLS_STORAGE},
-{ "Network : ", CLS_NETWORK},
-{ "Communications : ", CLS_COMMS},
-{ "Input : ", CLS_INPUT},
-{ "Multimedia : ", CLS_MMEDIA},
-{ "Miscellaneous : ", CLS_MISC},
-{ "",0}};
-
-
-/********************* EDIT THIS LIST **********************/
-
-/** Notes :
- **
- ** - Devices that shouldn't be seen or removed should be marked FLG_INVISIBLE.
- ** - XXX The list below should be reviewed by the driver authors to verify
- ** that the correct flags have been set for each driver, and that the
- ** descriptions are accurate.
- **/
-
-static DEV_INFO device_info[] = {
-/*---Name----- ---Description---------------------------------------------- */
-#ifdef PC98
-{"bs", "PC-9801-55 SCSI Interface", 0, CLS_STORAGE},
-{"wdc", "IDE/ESDI/MFM disk controller", 0, CLS_STORAGE},
-#endif
-{"adv", "AdvanSys SCSI narrow controller", 0, CLS_STORAGE},
-{"bt", "Buslogic SCSI controller", 0, CLS_STORAGE},
-{"aha", "Adaptec 154x SCSI controller", 0, CLS_STORAGE},
-{"aic", "Adaptec 152x SCSI and compatible SCSI cards", 0, CLS_STORAGE},
-{"nca", "ProAudio Spectrum SCSI and compatibles", 0, CLS_STORAGE},
-{"sea", "Seagate ST01/ST02 SCSI and compatibles", 0, CLS_STORAGE},
-{"stg", "TMC 18C30/18C50 based SCSI cards", 0, CLS_STORAGE},
-{"ata", "ATA/ATAPI compatible disk controller", 0, CLS_STORAGE},
-{"fdc", "Floppy disk controller", FLG_FIXED, CLS_STORAGE},
-{"mcd", "Mitsumi CD-ROM", 0, CLS_STORAGE},
-{"scd", "Sony CD-ROM", 0, CLS_STORAGE},
-{"matcd", "Matsushita/Panasonic/Creative CDROM", 0, CLS_STORAGE},
-{"wt", "Wangtek/Archive QIC-02 Tape drive", 0, CLS_STORAGE},
-{"wd", "IDE or ST506 compatible storage device", FLG_INVISIBLE, CLS_STORAGE},
-{"ad", "ATA/ATAPI compatible storage device", FLG_INVISIBLE, CLS_STORAGE},
-{"fd", "Floppy disk device", FLG_INVISIBLE, CLS_STORAGE},
-
-{"cs", "IBM EtherJet, CS89x0-based Ethernet adapters",0, CLS_NETWORK},
-#ifdef PC98
-{"ed", "NS8390 Ethernet adapters", 0, CLS_NETWORK},
-#else
-{"ed", "NE1000,NE2000,3C503,WD/SMC80xx Ethernet adapters",0, CLS_NETWORK},
-#endif
-{"el", "3C501 Ethernet adapter", 0, CLS_NETWORK},
-{"ep", "3C509 Ethernet adapter", 0, CLS_NETWORK},
-{"ex", "Intel EtherExpress Pro/10 Ethernet adapter", 0, CLS_NETWORK},
-{"fe", "Fujitsu MB86960A/MB86965A Ethernet adapters", 0, CLS_NETWORK},
-{"ie", "AT&T Starlan 10 and EN100, 3C507, NI5210 Ethernet adapters",0,CLS_NETWORK},
-{"le", "DEC Etherworks 2 and 3 Ethernet adapters", 0, CLS_NETWORK},
-{"lnc", "Isolan, Novell NE2100/NE32-VL Ethernet adapters", 0,CLS_NETWORK},
-{"sn", "SMC/Megahertz Ethernet adapters", 0,CLS_NETWORK},
-{"snc", "SONIC Ethernet adapters", 0,CLS_NETWORK},
-{"xe", "Xircom PC Card Ethernet adapter", 0, CLS_NETWORK},
-{"rdp", "RealTek RTL8002 Pocket Ethernet", 0, CLS_NETWORK},
-
-{"sio", "8250/16450/16550 Serial port", 0, CLS_COMMS},
-{"cx", "Cronyx/Sigma multiport sync/async adapter",0, CLS_COMMS},
-{"rc", "RISCom/8 multiport async adapter", 0, CLS_COMMS},
-{"cy", "Cyclades multiport async adapter", 0, CLS_COMMS},
-{"dgb", "Digiboard PC/Xe, PC/Xi async adapter", 0, CLS_COMMS},
-{"si", "Specialix SI/XIO/SX async adapter", 0, CLS_COMMS},
-{"stl", "Stallion EasyIO/Easy Connection 8/32 async adapter",0, CLS_COMMS},
-{"stli", "Stallion intelligent async adapter" ,0, CLS_COMMS},
-#ifdef PC98
-{"olpt", "Parallel printer port", 0, CLS_COMMS},
-#endif
-{"ppc", "Parallel Port chipset", 0, CLS_COMMS},
-{"gp", "National Instruments AT-GPIB/TNT driver", 0, CLS_COMMS},
-
-{"atkbdc", "Keyboard controller", FLG_INVISIBLE, CLS_INPUT},
-{"atkbd", "Keyboard", FLG_FIXED, CLS_INPUT},
-#ifdef PC98
-{"pckbd", "Keyboard", FLG_FIXED, CLS_INPUT},
-#endif
-{"mse", "Microsoft Bus Mouse", 0, CLS_INPUT},
-{"psm", "PS/2 Mouse", FLG_FIXED, CLS_INPUT},
-{"joy", "Joystick", FLG_FIXED, CLS_INPUT},
-{"vt", "PCVT console driver", FLG_IMMUTABLE, CLS_INPUT},
-{"sc", "Syscons console driver", FLG_IMMUTABLE, CLS_INPUT},
-
-#ifdef PC98
-{"nss", "PC-9801-86 Sound Board", 0, CLS_MMEDIA},
-#endif
-{"sbc", "PCM Creative SoundBlaster/ESS/Avance sounce cards", 0,CLS_MMEDIA},
-{"gusc", "PCM Gravis UltraSound sound cards", 0, CLS_MMEDIA},
-{"pcm", "PCM Generic soundcard support", 0, CLS_MMEDIA},
-{"sb", "VOXWARE Soundblaster PCM (SB/Pro/16, ProAudio Spectrum)",0,CLS_MMEDIA},
-{"sbxvi", "VOXWARE Soundblaster 16", 0, CLS_MMEDIA},
-{"sbmidi", "VOXWARE Soundblaster MIDI interface", 0, CLS_MMEDIA},
-{"awe", "VOXWARE AWE32 MIDI", 0, CLS_MMEDIA},
-{"pas", "VOXWARE ProAudio Spectrum PCM and MIDI", 0, CLS_MMEDIA},
-{"gus", "VOXWARE Gravis Ultrasound, Ultrasound 16 and Ultrasound MAX",0,CLS_MMEDIA},
-{"gusxvi", "VOXWARE Gravis Ultrasound 16-bit PCM", 0, CLS_MMEDIA},
-{"gusmax", "VOXWARE Gravis Ultrasound MAX", 0, CLS_MMEDIA},
-{"mss", "VOXWARE Microsoft Sound System", 0, CLS_MMEDIA},
-{"opl", "VOXWARE OPL-2/3 FM, SB/Pro/16, ProAudio Spectrum",0,CLS_MMEDIA},
-{"mpu", "VOXWARE Roland MPU401 MIDI", 0, CLS_MMEDIA},
-{"sscape", "VOXWARE Ensoniq Soundscape MIDI interface", 0, CLS_MMEDIA},
-{"sscape_mss", "VOXWARE Ensoniq Soundscape PCM", 0, CLS_MMEDIA},
-{"uart", "VOXWARE 6850 MIDI UART", 0, CLS_MMEDIA},
-{"pca", "PC speaker PCM audio driver", FLG_FIXED, CLS_MMEDIA},
-{"ctx", "Coretex-I frame grabber", 0, CLS_MMEDIA},
-{"spigot", "Creative Labs Video Spigot video capture", 0, CLS_MMEDIA},
-{"scc", "IBM Smart Capture Card", 0, CLS_MMEDIA},
-{"gsc", "Genius GS-4500 hand scanner", 0, CLS_MMEDIA},
-{"asc", "AmiScan scanner", 0, CLS_MMEDIA},
-
-{"apm", "Advanced Power Management", FLG_FIXED, CLS_MISC},
-{"pcic", "PC-card controller", 0, CLS_MISC},
-{"npx", "Math coprocessor", FLG_IMMUTABLE, CLS_MISC},
-#ifdef PC98
-{"gdc", "Graphic Display Controller", FLG_INVISIBLE, CLS_MISC},
-#endif
-{"vga", "Catchall PCI VGA driver", FLG_INVISIBLE, CLS_MISC},
-{"","",0,0}};
-
-
-typedef struct _devlist_struct
-{
- char name[80];
- int attrib; /* flag values as per the FLG_* defines above */
- int class; /* disk, etc as per the CLS_* defines above */
- char dev[16];
- int iobase,irq,drq,maddr,msize,unit,flags,id;
- int comment; /* 0 = device, 1 = comment, 2 = collapsed comment */
- int conflicts; /* set/reset by findconflict, count of conflicts */
- int changed; /* nonzero if the device has been edited */
- struct uc_device *device;
- struct _devlist_struct *prev,*next;
-} DEV_LIST;
-
-
-#define DEV_DEVICE 0
-#define DEV_COMMENT 1
-#define DEV_ZOOMED 2
-
-#define LIST_CURRENT (1<<0)
-#define LIST_SELECTED (1<<1)
-
-#define KEY_EXIT 0 /* return codes from dolist() and friends */
-#define KEY_DO 1
-#define KEY_DEL 2
-#define KEY_TAB 3
-#define KEY_REDRAW 4
-
-#define KEY_UP 5 /* these only returned from editval() */
-#define KEY_DOWN 6
-#define KEY_LEFT 7
-#define KEY_RIGHT 8
-#define KEY_NULL 9 /* this allows us to spin & redraw */
-
-#define KEY_ZOOM 10 /* these for zoom all/collapse all */
-#define KEY_UNZOOM 11
-
-#define KEY_HELP 12 /* duh? */
-
-static void redraw(void);
-static void insdev(DEV_LIST *dev, DEV_LIST *list);
-static int devinfo(DEV_LIST *dev);
-static int visuserconfig(void);
-
-static DEV_LIST *active = NULL,*inactive = NULL; /* driver lists */
-static DEV_LIST *alist,*ilist; /* visible heads of the driver lists */
-static DEV_LIST scratch; /* scratch record */
-static int conflicts; /* total conflict count */
-
-
-static char lines[] = "--------------------------------------------------------------------------------";
-static char spaces[] = " ";
-
-
-/**
- ** Device manipulation stuff : find, describe, configure.
- **/
-
-/**
- ** setdev
- **
- ** Sets the device referenced by (*dev) to the parameters in the struct,
- ** and the enable flag according to (enabled)
- **/
-static void
-setdev(DEV_LIST *dev, int enabled)
-{
- dev->device->id_iobase = dev->iobase; /* copy happy */
- dev->device->id_irq = (u_short)(dev->irq < 16 ? 1<<dev->irq : 0); /* IRQ is bitfield */
- dev->device->id_drq = (short)dev->drq;
- dev->device->id_maddr = (caddr_t)dev->maddr;
- dev->device->id_msize = dev->msize;
- dev->device->id_flags = dev->flags;
- dev->device->id_enabled = enabled;
-}
-
-
-/**
- ** getdevs
- **
- ** Walk the kernel device tables and build the active and inactive lists
- **/
-static void
-getdevs(void)
-{
- int i;
- struct uc_device *ap;
-
- ap = uc_devtab; /* pointer to array of devices */
- for (i = 0; ap[i].id_id; i++) /* for each device in this table */
- {
- scratch.unit = ap[i].id_unit; /* device parameters */
- strcpy(scratch.dev,ap[i].id_name);
- scratch.iobase = ap[i].id_iobase;
- scratch.irq = ffs(ap[i].id_irq)-1;
- scratch.drq = ap[i].id_drq;
- scratch.maddr = (int)ap[i].id_maddr;
- scratch.msize = ap[i].id_msize;
- scratch.flags = ap[i].id_flags;
-
- scratch.comment = DEV_DEVICE; /* admin stuff */
- scratch.conflicts = 0;
- scratch.device = &ap[i]; /* save pointer for later reference */
- scratch.changed = 0;
- if (!devinfo(&scratch)) /* get more info on the device */
- insdev(&scratch,ap[i].id_enabled?active:inactive);
- }
-}
-
-
-/**
- ** Devinfo
- **
- ** Fill in (dev->name), (dev->attrib) and (dev->type) from the device_info array.
- ** If the device is unknown, put it in the CLS_MISC class, with no flags.
- **
- ** If the device is marked "invisible", return nonzero; the caller should
- ** not insert any such device into either list.
- **
- **/
-static int
-devinfo(DEV_LIST *dev)
-{
- int i;
-
- for (i = 0; device_info[i].class; i++)
- {
- if (!strcmp(dev->dev,device_info[i].dev))
- {
- if (device_info[i].attrib & FLG_INVISIBLE) /* forget we ever saw this one */
- return(1);
- strcpy(dev->name,device_info[i].name); /* get the name */
- dev->attrib = device_info[i].attrib;
- dev->class = device_info[i].class;
- return(0);
- }
- }
- strcpy(dev->name,"Unknown device");
- dev->attrib = 0;
- dev->class = CLS_MISC;
- return(0);
-}
-
-
-/**
- ** List manipulation stuff : add, move, initialise, free, traverse
- **
- ** Note that there are assumptions throughout this code that
- ** the first entry in a list will never move. (assumed to be
- ** a comment).
- **/
-
-
-/**
- ** Adddev
- **
- ** appends a copy of (dev) to the end of (*list)
- **/
-static void
-addev(DEV_LIST *dev, DEV_LIST **list)
-{
-
- DEV_LIST *lp,*ap;
-
- lp = (DEV_LIST *)malloc(sizeof(DEV_LIST),M_DEVL,M_WAITOK);
- bcopy(dev,lp,sizeof(DEV_LIST)); /* create copied record */
-
- if (*list) /* list exists */
- {
- ap = *list;
- while(ap->next)
- ap = ap->next; /* scoot to end of list */
- lp->prev = ap;
- lp->next = NULL;
- ap->next = lp;
- }else{ /* list does not yet exist */
- *list = lp;
- lp->prev = lp->next = NULL; /* list now exists */
- }
-}
-
-
-/**
- ** Findspot
- **
- ** Finds the 'appropriate' place for (dev) in (list)
- **
- ** 'Appropriate' means in numeric order with other devices of the same type,
- ** or in alphabetic order following a comment of the appropriate type.
- ** or at the end of the list if an appropriate comment is not found. (this should
- ** never happen)
- ** (Note that the appropriate point is never the top, but may be the bottom)
- **/
-static DEV_LIST *
-findspot(DEV_LIST *dev, DEV_LIST *list)
-{
- DEV_LIST *ap = NULL;
-
- /* search for a previous instance of the same device */
- for (ap = list; ap; ap = ap->next)
- {
- if (ap->comment != DEV_DEVICE) /* ignore comments */
- continue;
- if (!strcmp(dev->dev,ap->dev)) /* same base device */
- {
- if ((dev->unit <= ap->unit) /* belongs before (equal is bad) */
- || !ap->next) /* or end of list */
- {
- ap = ap->prev; /* back up one */
- break; /* done here */
- }
- if (ap->next) /* if the next item exists */
- {
- if (ap->next->comment != DEV_DEVICE) /* next is a comment */
- break;
- if (strcmp(dev->dev,ap->next->dev)) /* next is a different device */
- break;
- }
- }
- }
-
- if (!ap) /* not sure yet */
- {
- /* search for a class that the device might belong to */
- for (ap = list; ap; ap = ap->next)
- {
- if (ap->comment != DEV_DEVICE) /* look for simlar devices */
- continue;
- if (dev->class != ap->class) /* of same class too 8) */
- continue;
- if (strcmp(dev->dev,ap->dev) < 0) /* belongs before the current entry */
- {
- ap = ap->prev; /* back up one */
- break; /* done here */
- }
- if (ap->next) /* if the next item exists */
- if (ap->next->comment != DEV_DEVICE) /* next is a comment, go here */
- break;
- }
- }
-
- if (!ap) /* didn't find a match */
- {
- for (ap = list; ap->next; ap = ap->next) /* try for a matching comment */
- if ((ap->comment != DEV_DEVICE)
- && (ap->class == dev->class)) /* appropriate place? */
- break;
- } /* or just put up with last */
-
- return(ap);
-}
-
-
-/**
- ** Insdev
- **
- ** Inserts a copy of (dev) at the appropriate point in (list)
- **/
-static void
-insdev(DEV_LIST *dev, DEV_LIST *list)
-{
- DEV_LIST *lp,*ap;
-
- lp = (DEV_LIST *)malloc(sizeof(DEV_LIST),M_DEVL,M_WAITOK);
- bcopy(dev,lp,sizeof(DEV_LIST)); /* create copied record */
-
- ap = findspot(lp,list); /* find appropriate spot */
- lp->next = ap->next; /* point to next */
- if (ap->next)
- ap->next->prev = lp; /* point next to new */
- lp->prev = ap; /* point new to current */
- ap->next = lp; /* and current to new */
-}
-
-
-/**
- ** Movedev
- **
- ** Moves (dev) from its current list to an appropriate place in (list)
- ** (dev) may not come from the top of a list, but it may from the bottom.
- **/
-static void
-movedev(DEV_LIST *dev, DEV_LIST *list)
-{
- DEV_LIST *ap;
-
- ap = findspot(dev,list);
- dev->prev->next = dev->next; /* remove from old list */
- if (dev->next)
- dev->next->prev = dev->prev;
-
- dev->next = ap->next; /* insert in new list */
- if (ap->next)
- ap->next->prev = dev; /* point next to new */
- dev->prev = ap; /* point new to current */
- ap->next = dev; /* and current to new */
-}
-
-
-/**
- ** Initlist
- **
- ** Initialises (*list) with the basic headings
- **/
-static void
-initlist(DEV_LIST **list)
-{
- int i;
-
- for(i = 0; devclass_names[i].name[0]; i++) /* for each devtype name */
- {
- strcpy(scratch.name,devclass_names[i].name);
- scratch.comment = DEV_ZOOMED;
- scratch.class = devclass_names[i].number;
- scratch.attrib = FLG_MANDATORY; /* can't be moved */
- addev(&scratch,list); /* add to the list */
- }
-}
-
-
-/**
- ** savelist
- **
- ** Walks (list) and saves the settings of any entry marked as changed.
- **
- ** The device's active field is set according to (active).
- **
- ** Builds the uc_devlist used by kget to extract the changed device information.
- ** The code for this was taken almost verbatim from the original module.
- **/
-static void
-savelist(DEV_LIST *list, int active)
-{
- struct uc_device *id_p,*id_pn;
- char *name;
-
- while (list)
- {
- if ((list->comment == DEV_DEVICE) && /* is a device */
- (list->changed) && /* has been changed */
- (list->device != NULL)) { /* has an uc_device structure */
-
- setdev(list,active); /* set the device itself */
-
- id_pn = NULL;
- for (id_p=uc_devlist; id_p; id_p=id_p->id_next)
- { /* look on the list for it */
- if (id_p->id_id == list->device->id_id)
- {
- name = list->device->id_name;
- id_pn = id_p->id_next;
- if (id_p->id_name)
- free(id_p->id_name, M_DEVL);
- bcopy(list->device,id_p,sizeof(struct uc_device));
- save_resource(list->device);
- id_p->id_name = malloc(strlen(name) + 1, M_DEVL,M_WAITOK);
- strcpy(id_p->id_name, name);
- id_pn->id_next = uc_devlist;
- id_p->id_next = id_pn;
- break;
- }
- }
- if (!id_pn) /* not already on the list */
- {
- name = list->device->id_name;
- id_pn = malloc(sizeof(struct uc_device),M_DEVL,M_WAITOK);
- bcopy(list->device,id_pn,sizeof(struct uc_device));
- save_resource(list->device);
- id_pn->id_name = malloc(strlen(name) + 1, M_DEVL,M_WAITOK);
- strcpy(id_pn->id_name, name);
- id_pn->id_next = uc_devlist;
- uc_devlist = id_pn; /* park at top of list */
- }
- }
- list = list->next;
- }
-}
-
-
-/**
- ** nukelist
- **
- ** Frees all storage in use by a (list).
- **/
-static void
-nukelist(DEV_LIST *list)
-{
- DEV_LIST *dp;
-
- if (!list)
- return;
- while(list->prev) /* walk to head of list */
- list = list->prev;
-
- while(list)
- {
- dp = list;
- list = list->next;
- free(dp,M_DEVL);
- }
-}
-
-
-/**
- ** prevent
- **
- ** Returns the previous entry in (list), skipping zoomed regions. Returns NULL
- ** if there is no previous entry. (Only possible if list->prev == NULL given the
- ** premise that there is always a comment at the head of the list)
- **/
-static DEV_LIST *
-prevent(DEV_LIST *list)
-{
- DEV_LIST *dp;
-
- if (!list)
- return(NULL);
- dp = list->prev; /* start back one */
- while(dp)
- {
- if (dp->comment == DEV_ZOOMED) /* previous section is zoomed */
- return(dp); /* so skip to comment */
- if (dp->comment == DEV_COMMENT) /* not zoomed */
- return(list->prev); /* one back as normal */
- dp = dp->prev; /* backpedal */
- }
- return(dp); /* NULL, we can assume */
-}
-
-
-/**
- ** nextent
- **
- ** Returns the next entry in (list), skipping zoomed regions. Returns NULL
- ** if there is no next entry. (Possible if the current entry is last, or
- ** if the current entry is the last heading and it's collapsed)
- **/
-static DEV_LIST *
-nextent(DEV_LIST *list)
-{
- DEV_LIST *dp;
-
- if (!list)
- return(NULL);
- if (list->comment != DEV_ZOOMED) /* no reason to skip */
- return(list->next);
- dp = list->next;
- while(dp)
- {
- if (dp->comment != DEV_DEVICE) /* found another heading */
- break;
- dp = dp->next;
- }
- return(dp); /* back we go */
-}
-
-
-/**
- ** ofsent
- **
- ** Returns the (ofs)th entry down from (list), or NULL if it doesn't exist
- **/
-static DEV_LIST *
-ofsent(int ofs, DEV_LIST *list)
-{
- while (ofs-- && list)
- list = nextent(list);
- return(list);
-}
-
-
-/**
- ** findconflict
- **
- ** Scans every element of (list) and sets the conflict tags appropriately
- ** Returns the number of conflicts found.
- **/
-static int
-findconflict(DEV_LIST *list)
-{
- int count = 0; /* number of conflicts found */
- DEV_LIST *dp,*sp;
-
- for (dp = list; dp; dp = dp->next) /* over the whole list */
- {
- if (dp->comment != DEV_DEVICE) /* comments don't usually conflict */
- continue;
-
- dp->conflicts = 0; /* assume the best */
- for (sp = list; sp; sp = sp->next) /* scan the entire list for conflicts */
- {
- if (sp->comment != DEV_DEVICE) /* likewise */
- continue;
-
- if (sp == dp) /* always conflict with itself */
- continue;
-
- if ((dp->iobase > 0) && /* iobase conflict? */
- (dp->iobase == sp->iobase))
- dp->conflicts = 1;
- if ((dp->irq > 0) && /* irq conflict? */
- (dp->irq == sp->irq))
- dp->conflicts = 1;
- if ((dp->drq > 0) && /* drq conflict? */
- (dp->drq == sp->drq))
- dp->conflicts = 1;
- if ((sp->maddr > 0) && /* maddr/msize conflict? */
- (dp->maddr > 0) &&
- (sp->maddr + ((sp->msize == 0) ? 1 : sp->msize) > dp->maddr) &&
- (dp->maddr + ((dp->msize == 0) ? 1 : dp->msize) > sp->maddr))
- dp->conflicts = 1;
- }
- count += dp->conflicts; /* count conflicts */
- }
- return(count);
-}
-
-
-/**
- ** expandlist
- **
- ** Unzooms all headings in (list)
- **/
-static void
-expandlist(DEV_LIST *list)
-{
- while(list)
- {
- if (list->comment == DEV_COMMENT)
- list->comment = DEV_ZOOMED;
- list = list->next;
- }
-}
-
-
-/**
- ** collapselist
- **
- ** Zooms all headings in (list)
- **/
-static void
-collapselist(DEV_LIST *list)
-{
- while(list)
- {
- if (list->comment == DEV_ZOOMED)
- list->comment = DEV_COMMENT;
- list = list->next;
- }
-}
-
-
-/**
- ** Screen-manipulation stuff
- **
- ** This is the basic screen layout :
- **
- ** 0 5 10 15 20 25 30 35 40 45 50 55 60 67 70 75
- ** |....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....
- ** +--------------------------------------------------------------------------------+
- ** 0 -|---Active Drivers----------------------------xx Conflicts------Dev---IRQ--Port--|
- ** 1 -| ........................ ....... .. 0x....|
- ** 2 -| ........................ ....... .. 0x....|
- ** 3 -| ........................ ....... .. 0x....|
- ** 4 -| ........................ ....... .. 0x....|
- ** 5 -| ........................ ....... .. 0x....|
- ** 6 -| ........................ ....... .. 0x....|
- ** 7 -| ........................ ....... .. 0x....|
- ** 8 -| ........................ ....... .. 0x....|
- ** 9 -|---Inactive Drivers--------------------------------------------Dev--------------|
- ** 10-| ........................ ....... |
- ** 11-| ........................ ....... |
- ** 12-| ........................ ....... |
- ** 13-| ........................ ....... |
- ** 14-| ........................ ....... |
- ** 15-| ........................ ....... |
- ** 16-| ........................ ....... |
- ** 17-|------------------------------------------------------UP-DOWN-------------------|
- ** 18-| Relevant parameters for the current device |
- ** 19-| |
- ** 20-| |
- ** 21-|--------------------------------------------------------------------------------|
- ** 22-| Help texts go here |
- ** 23-| |
- ** +--------------------------------------------------------------------------------+
- **
- ** Help texts
- **
- ** On a collapsed comment :
- **
- ** [Enter] Expand device list [z] Expand all lists
- ** [TAB] Change fields [Q] Save and Exit
- **
- ** On an expanded comment :
- **
- ** [Enter] Collapse device list [Z] Collapse all lists
- ** [TAB] Change fields [Q] Save and Exit
- **
- ** On a comment with no followers
- **
- **
- ** [TAB] Change fields [Q] Save and Exit
- **
- ** On a device in the active list
- **
- ** [Enter] Edit device parameters [DEL] Disable device
- ** [TAB] Change fields [Q] Save and Exit [?] Help
- **
- ** On a device in the inactive list
- **
- ** [Enter] Enable device
- ** [TAB] Change fields [Q] Save and Exit [?] Help
- **
- ** While editing parameters
- **
- ** <parameter-specific help here>
- ** [TAB] Change fields [Q] Save device parameters
- **/
-
-
-
-/**
- **
- ** The base-level screen primitives :
- **
- ** bold() - enter bold mode \E[1m (md)
- ** inverse() - enter inverse mode \E[7m (so)
- ** normal() - clear bold/inverse mode \E[m (se)
- ** clear() - clear the screen \E[H\E[J (ce)
- ** move(x,y) - move the cursor to x,y \E[y;xH: (cm)
- **/
-
-static void
-bold(void)
-{
- printf("\033[1m");
-}
-
-static void
-inverse(void)
-{
- printf("\033[7m");
-}
-
-static void
-normal(void)
-{
- printf("\033[m");
-}
-
-static void
-clear(void)
-{
- normal();
- printf("\033[H\033[J");
-}
-
-static void
-move(int x, int y)
-{
- printf("\033[%d;%dH",y+1,x+1);
-}
-
-
-/**
- **
- ** High-level screen primitives :
- **
- ** putxyl(x,y,str,len) - put (len) bytes of (str) at (x,y), supports embedded formatting
- ** putxy(x,y,str) - put (str) at (x,y), supports embedded formatting
- ** erase(x,y,w,h) - clear the box (x,y,w,h)
- ** txtbox(x,y,w,y,str) - put (str) in a region at (x,y,w,h)
- ** putmsg(str) - put (str) in the message area
- ** puthelp(str) - put (str) in the upper helpline
- ** pad(str,len) - pad (str) to (len) with spaces
- ** drawline(row,detail,list,inverse,*dhelp)
- ** - draws a line for (*list) at (row) onscreen. If (detail) is
- ** nonzero, include port, IRQ and maddr, if (inverse) is nonzero,
- ** draw the line in inverse video, and display (*dhelp) on the
- ** helpline.
- ** drawlist(row,num,detail,list)
- ** - draw (num) entries from (list) at (row) onscreen, passile (detail)
- ** through to drawline().
- ** showparams(dev) - displays the relevant parameters for (dev) below the lists onscreen.
- ** yesno(str) - displays (str) in the message area, and returns nonzero on 'y' or 'Y'
- ** redraw(); - Redraws the entire screen layout, including the
- ** - two list panels.
- **/
-
-/**
- ** putxy
- ** writes (str) at x,y onscreen
- ** putxyl
- ** writes up to (len) of (str) at x,y onscreen.
- **
- ** Supports embedded formatting :
- ** !i - inverse mode.
- ** !b - bold mode.
- ** !n - normal mode.
- **/
-static void
-putxyl(int x, int y, char *str, int len)
-{
- move(x,y);
- normal();
-
- while((*str) && (len--))
- {
- if (*str == '!') /* format escape? */
- {
- switch(*(str+1)) /* depending on the next character */
- {
- case 'i':
- inverse();
- str +=2; /* skip formatting */
- len++; /* doesn't count for length */
- break;
-
- case 'b':
- bold();
- str +=2; /* skip formatting */
- len++; /* doesn't count for length */
- break;
-
- case 'n':
- normal();
- str +=2; /* skip formatting */
- len++; /* doesn't count for length */
- break;
-
- default:
- putchar(*str++); /* not an escape */
- }
- }else{
- putchar(*str++); /* emit the character */
- }
- }
-}
-
-#define putxy(x,y,str) putxyl(x,y,str,-1)
-
-
-/**
- ** erase
- **
- ** Erases the region (x,y,w,h)
- **/
-static void
-erase(int x, int y, int w, int h)
-{
- int i;
-
- normal();
- for (i = 0; i < h; i++)
- putxyl(x,y++,spaces,w);
-}
-
-
-/**
- ** txtbox
- **
- ** Writes (str) into the region (x,y,w,h), supports embedded formatting using
- ** putxy. Lines are not wrapped, newlines must be forced with \n.
- **/
-static void
-txtbox(int x, int y, int w, int h, char *str)
-{
- int i = 0;
-
- h--;
- while((str[i]) && h)
- {
- if (str[i] == '\n') /* newline */
- {
- putxyl(x,y,str,(i<w)?i:w); /* write lesser of i or w */
- y++; /* move down */
- h--; /* room for one less */
- str += (i+1); /* skip first newline */
- i = 0; /* zero offset */
- }else{
- i++; /* next character */
- }
- }
- if (h) /* end of string, not region */
- putxyl(x,y,str,w);
-}
-
-
-/**
- ** putmsg
- **
- ** writes (msg) in the helptext area
- **/
-static void
-putmsg(char *msg)
-{
- erase(0,18,80,3); /* clear area */
- txtbox(0,18,80,3,msg);
-}
-
-
-/**
- ** puthelp
- **
- ** Writes (msg) in the helpline area
- **/
-static void
-puthelp(char *msg)
-{
- erase(0,22,80,1);
- putxy(0,22,msg);
-}
-
-
-/**
- ** masterhelp
- **
- ** Draws the help message at the bottom of the screen
- **/
-static void
-masterhelp(char *msg)
-{
- erase(0,23,80,1);
- putxy(0,23,msg);
-}
-
-
-/**
- ** pad
- **
- ** space-pads a (str) to (len) characters
- **/
-static void
-pad(char *str, int len)
-{
- int i;
-
- for (i = 0; str[i]; i++) /* find the end of the string */
- ;
- if (i >= len) /* no padding needed */
- return;
- while(i < len) /* pad */
- str[i++] = ' ';
- str[i] = '\0';
-}
-
-
-/**
- ** drawline
- **
- ** Displays entry (ofs) of (list) in region at (row) onscreen, optionally displaying
- ** the port and IRQ fields if (detail) is nonzero. If (inverse), in inverse video.
- **
- ** The text (dhelp) is displayed if the item is a normal device, otherwise
- ** help is shown for normal or zoomed comments
- **/
-static void
-drawline(int row, int detail, DEV_LIST *list, int inverse, char *dhelp)
-{
- char lbuf[90],nb[70],db[20],ib[16],pb[16];
-
- if (list->comment == DEV_DEVICE)
- {
- nb[0] = ' ';
- strncpy(nb+1,list->name,57);
- }else{
- strncpy(nb,list->name,58);
- if ((list->comment == DEV_ZOOMED) && (list->next))
- if (list->next->comment == DEV_DEVICE) /* only mention if there's something hidden */
- strcat(nb," (Collapsed)");
- }
- nb[58] = '\0';
- pad(nb,60);
- if (list->conflicts) /* device in conflict? */
- {
- if (inverse)
- {
- strcpy(nb+54," !nCONF!i "); /* tag conflict, careful of length */
- }else{
- strcpy(nb+54," !iCONF!n "); /* tag conflict, careful of length */
- }
- }
- if (list->comment == DEV_DEVICE)
- {
- sprintf(db,"%s%d",list->dev,list->unit);
- pad(db,8);
- }else{
- strcpy(db," ");
- }
- if ((list->irq > 0) && detail && (list->comment == DEV_DEVICE))
- {
- sprintf(ib," %d",list->irq);
- pad(ib,4);
- }else{
- strcpy(ib," ");
- }
- if ((list->iobase > 0) && detail && (list->comment == DEV_DEVICE))
- {
- sprintf(pb,"0x%x",list->iobase);
- pad(pb,7);
- }else{
- strcpy(pb," ");
- }
-
- sprintf(lbuf," %s%s%s%s%s",inverse?"!i":"",nb,db,ib,pb);
-
- putxyl(0,row,lbuf,80);
- if (dhelp)
- {
- switch(list->comment)
- {
- case DEV_DEVICE: /* ordinary device */
- puthelp(dhelp);
- break;
- case DEV_COMMENT:
- puthelp("");
- if (list->next)
- if (list->next->comment == DEV_DEVICE)
- puthelp(" [!bEnter!n] Collapse device list [!bC!n] Collapse all lists");
- break;
- case DEV_ZOOMED:
- puthelp("");
- if (list->next)
- if (list->next->comment == DEV_DEVICE)
- puthelp(" [!bEnter!n] Expand device list [!bX!n] Expand all lists");
- break;
- default:
- puthelp(" WARNING: This list entry corrupted!");
- break;
- }
- }
- move(0,row); /* put the cursor somewhere relevant */
-}
-
-
-/**
- ** drawlist
- **
- ** Displays (num) lines of the contents of (list) at (row), optionally displaying the
- ** port and IRQ fields as well if (detail) is nonzero
- **
- ** printf in the kernel is essentially useless, so we do most of the hard work ourselves here.
- **/
-static void
-drawlist(int row, int num, int detail, DEV_LIST *list)
-{
- int ofs;
-
- for(ofs = 0; ofs < num; ofs++)
- {
- if (list)
- {
- drawline(row+ofs,detail,list,0,NULL); /* NULL -> don't draw empty help string */
- list = nextent(list); /* move down visible list */
- }else{
- erase(0,row+ofs,80,1);
- }
- }
-}
-
-
-/**
- ** redrawactive
- **
- ** Redraws the active list
- **/
-static void
-redrawactive(void)
-{
- char cbuf[16];
-
- if (conflicts)
- {
- sprintf(cbuf,"!i%d conflict%s-",conflicts,(conflicts>1)?"s":"");
- putxy(45,0,cbuf);
- }else{
- putxyl(45,0,lines,16);
- }
- drawlist(1,8,1,alist); /* draw device lists */
-}
-
-/**
- ** redrawinactive
- **
- ** Redraws the inactive list
- **/
-static void
-redrawinactive(void)
-{
- drawlist(10,7,0,ilist); /* draw device lists */
-}
-
-
-/**
- ** redraw
- **
- ** Clear the screen and redraw the entire layout
- **/
-static void
-redraw(void)
-{
- clear();
- putxy(0,0,lines);
- putxy(3,0,"!bActive!n-!bDrivers");
- putxy(63,0,"!bDev!n---!bIRQ!n--!bPort");
- putxy(0,9,lines);
- putxy(3,9,"!bInactive!n-!bDrivers");
- putxy(63,9,"!bDev");
- putxy(0,17,lines);
- putxy(0,21,lines);
- masterhelp(" [!bTAB!n] Change fields [!bQ!n] Save and Exit [!b?!n] Help");
-
- redrawactive();
- redrawinactive();
-}
-
-
-/**
- ** yesnocancel
- **
- ** Put (str) in the message area, and return 1 if the user hits 'y' or 'Y',
- ** 2 if they hit 'c' or 'C', or 0 for 'n' or 'N'.
- **/
-static int
-yesnocancel(char *str)
-{
-
- putmsg(str);
- for(;;)
- switch(getchar())
- {
- case -1:
- case 'n':
- case 'N':
- return(0);
-
- case 'y':
- case 'Y':
- return(1);
-
- case 'c':
- case 'C':
- return(2);
- }
-}
-
-
-/**
- ** showparams
- **
- ** Show device parameters in the region below the lists
- **
- ** 0 5 10 15 20 25 30 35 40 45 50 55 60 67 70 75
- ** |....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....
- ** +--------------------------------------------------------------------------------+
- ** 17-|--------------------------------------------------------------------------------|
- ** 18-| Port address : 0x0000 Memory address : 0x00000 Conflict allowed |
- ** 19-| IRQ number : 00 Memory size : 0x0000 |
- ** 20-| Flags : 0x0000 DRQ number : 00 |
- ** 21-|--------------------------------------------------------------------------------|
- **/
-static void
-showparams(DEV_LIST *dev)
-{
- char buf[80];
-
- erase(0,18,80,3); /* clear area */
- if (!dev)
- return;
- if (dev->comment != DEV_DEVICE)
- return;
-
-
- if (dev->iobase > 0)
- {
- sprintf(buf,"Port address : 0x%x",dev->iobase);
- putxy(1,18,buf);
- }
-
- if (dev->irq > 0)
- {
- sprintf(buf,"IRQ number : %d",dev->irq);
- putxy(1,19,buf);
- }
- sprintf(buf,"Flags : 0x%x",dev->flags);
- putxy(1,20,buf);
- if (dev->maddr > 0)
- {
- sprintf(buf,"Memory address : 0x%x",dev->maddr);
- putxy(26,18,buf);
- }
- if (dev->msize > 0)
- {
- sprintf(buf,"Memory size : 0x%x",dev->msize);
- putxy(26,19,buf);
- }
-
- if (dev->drq > 0)
- {
- sprintf(buf,"DRQ number : %d",dev->drq);
- putxy(26,20,buf);
- }
-}
-
-
-/**
- ** Editing functions for device parameters
- **
- ** editval(x,y,width,hex,min,max,val) - Edit (*val) in a field (width) wide at (x,y)
- ** onscreen. Refuse values outsise (min) and (max).
- ** editparams(dev) - Edit the parameters for (dev)
- **/
-
-
-#define VetRet(code) \
-{ \
- if ((i >= min) && (i <= max)) /* legit? */ \
- { \
- *val = i; \
- sprintf(buf,hex?"0x%x":"%d",i); \
- putxy(hex?x-2:x,y,buf); \
- return(code); /* all done and exit */ \
- } \
- i = *val; /* restore original value */ \
- delta = 1; /* restore other stuff */ \
-}
-
-
-/**
- ** editval
- **
- ** Edit (*val) at (x,y) in (hex)?hex:decimal mode, allowing values between (min) and (max)
- ** in a field (width) wide. (Allow one space)
- ** If (ro) is set, we're in "readonly" mode, so disallow edits.
- **
- ** Return KEY_TAB on \t, KEY_EXIT on 'q'
- **/
-static int
-editval(int x, int y, int width, int hex, int min, int max, int *val, int ro)
-{
- int i = *val; /* work with copy of the value */
- char buf[2+11+1],tc[11+1]; /* display buffer, text copy */
- int xp = 0; /* cursor offset into text copy */
- int delta = 1; /* force redraw first time in */
- int c;
- int extended = 0; /* stage counter for extended key sequences */
-
- if (hex) /* we presume there's a leading 0x onscreen */
- putxy(x-2,y,"!i0x"); /* coz there sure is now */
-
- for (;;)
- {
- if (delta) /* only update if necessary */
- {
- sprintf(tc,hex?"%x":"%d",i); /* make a text copy of the value */
- sprintf(buf,"!i%s",tc); /* format for printing */
- erase(x,y,width,1); /* clear the area */
- putxy(x,y,buf); /* write */
- xp = strlen(tc); /* cursor always at end */
- move(x+xp,y); /* position the cursor */
- }
-
- c = getchar();
-
- switch(extended) /* escape handling */
- {
- case 0:
- if (c == 0x1b) /* esc? */
- {
- extended = 1; /* flag and spin */
- continue;
- }
- extended = 0;
- break; /* nope, drop through */
-
- case 1: /* there was an escape prefix */
- if (c == '[' || c == 'O') /* second character in sequence */
- {
- extended = 2;
- continue;
- }
- if (c == 0x1b)
- return(KEY_EXIT); /* double esc exits */
- extended = 0;
- break; /* nup, not a sequence. */
-
- case 2:
- extended = 0;
- switch(c) /* looks like the real McCoy */
- {
- case 'A':
- VetRet(KEY_UP); /* leave if OK */
- continue;
- case 'B':
- VetRet(KEY_DOWN); /* leave if OK */
- continue;
- case 'C':
- VetRet(KEY_RIGHT); /* leave if OK */
- continue;
- case 'D':
- VetRet(KEY_LEFT); /* leave if OK */
- continue;
-
- default:
- continue;
- }
- }
-
- switch(c)
- {
- case '\t': /* trying to tab off */
- VetRet(KEY_TAB); /* verify and maybe return */
- break;
-
- case -1:
- case 'q':
- case 'Q':
- VetRet(KEY_EXIT);
- break;
-
- case '\b':
- case '\177': /* BS or DEL */
- if (ro) /* readonly? */
- {
- puthelp(" !iThis value cannot be edited (Press ESC)");
- while(getchar() != 0x1b); /* wait for key */
- return(KEY_NULL); /* spin */
- }
- if (xp) /* still something left to delete */
- {
- i = (hex ? i/0x10u : i/10); /* strip last digit */
- delta = 1; /* force update */
- }
- break;
-
- case 588:
- VetRet(KEY_UP);
- break;
-
- case '\r':
- case '\n':
- case 596:
- VetRet(KEY_DOWN);
- break;
-
- case 591:
- VetRet(KEY_LEFT);
- break;
-
- case 593:
- VetRet(KEY_RIGHT);
- break;
-
- default:
- if (ro) /* readonly? */
- {
- puthelp(" !iThis value cannot be edited (Press ESC)");
- while(getchar() != 0x1b); /* wait for key */
- return(KEY_NULL); /* spin */
- }
- if (xp >= width) /* no room for more characters anyway */
- break;
- if (hex)
- {
- if ((c >= '0') && (c <= '9'))
- {
- i = i*0x10 + (c-'0'); /* update value */
- delta = 1;
- break;
- }
- if ((c >= 'a') && (c <= 'f'))
- {
- i = i*0x10 + (c-'a'+0xa);
- delta = 1;
- break;
- }
- if ((c >= 'A') && (c <= 'F'))
- {
- i = i*0x10 + (c-'A'+0xa);
- delta = 1;
- break;
- }
- }else{
- if ((c >= '0') && (c <= '9'))
- {
- i = i*10 + (c-'0'); /* update value */
- delta = 1; /* force redraw */
- break;
- }
- }
- break;
- }
- }
-}
-
-
-/**
- ** editparams
- **
- ** Edit the parameters for (dev)
- **
- ** Note that it's _always_ possible to edit the flags, otherwise it might be
- ** possible for this to spin in an endless loop...
- ** 0 5 10 15 20 25 30 35 40 45 50 55 60 67 70 75
- ** |....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....
- ** +--------------------------------------------------------------------------------+
- ** 17-|--------------------------------------------------------------------------------|
- ** 18-| Port address : 0x0000 Memory address : 0x00000 Conflict allowed |
- ** 19-| IRQ number : 00 Memory size : 0x0000 |
- ** 20-| Flags : 0x0000 DRQ number : 00 |
- ** 21-|--------------------------------------------------------------------------------|
- **
- ** The "intelligence" in this function that hops around based on the directional
- ** returns from editval isn't very smart, and depends on the layout above.
- **/
-static void
-editparams(DEV_LIST *dev)
-{
- int ret;
- char buf[16]; /* needs to fit the device name */
-
- putxy(2,17,"!bParameters!n-!bfor!n-!bdevice!n-");
- sprintf(buf,"!b%s",dev->dev);
- putxy(24,17,buf);
-
- erase(1,22,80,1);
- for (;;)
- {
- ep_iobase:
- if (dev->iobase > 0)
- {
- puthelp(" IO Port address (Hexadecimal, 0x1-0xffff)");
- ret = editval(18,18,5,1,0x1,0xffff,&(dev->iobase),(dev->attrib & FLG_FIXIOBASE));
- switch(ret)
- {
- case KEY_EXIT:
- goto ep_exit;
-
- case KEY_RIGHT:
- if (dev->maddr > 0)
- goto ep_maddr;
- break;
-
- case KEY_TAB:
- case KEY_DOWN:
- goto ep_irq;
- }
- goto ep_iobase;
- }
- ep_irq:
- if (dev->irq > 0)
- {
- puthelp(" Interrupt number (Decimal, 1-15)");
- ret = editval(16,19,3,0,1,15,&(dev->irq),(dev->attrib & FLG_FIXIRQ));
- switch(ret)
- {
- case KEY_EXIT:
- goto ep_exit;
-
- case KEY_RIGHT:
- if (dev->msize > 0)
- goto ep_msize;
- break;
-
- case KEY_UP:
- if (dev->iobase > 0)
- goto ep_iobase;
- break;
-
- case KEY_TAB:
- case KEY_DOWN:
- goto ep_flags;
- }
- goto ep_irq;
- }
- ep_flags:
- puthelp(" Device-specific flag values.");
- ret = editval(18,20,8,1,INT_MIN,INT_MAX,&(dev->flags),0);
- switch(ret)
- {
- case KEY_EXIT:
- goto ep_exit;
-
- case KEY_RIGHT:
- if (dev->drq > 0)
- goto ep_drq;
- break;
-
- case KEY_UP:
- if (dev->irq > 0)
- goto ep_irq;
- if (dev->iobase > 0)
- goto ep_iobase;
- break;
-
- case KEY_DOWN:
- if (dev->maddr > 0)
- goto ep_maddr;
- if (dev->msize > 0)
- goto ep_msize;
- if (dev->drq > 0)
- goto ep_drq;
- break;
-
- case KEY_TAB:
- goto ep_maddr;
- }
- goto ep_flags;
- ep_maddr:
- if (dev->maddr > 0)
- {
- puthelp(" Device memory start address (Hexadecimal, 0x1-0xfffff)");
- ret = editval(45,18,6,1,0x1,0xfffff,&(dev->maddr),(dev->attrib & FLG_FIXMADDR));
- switch(ret)
- {
- case KEY_EXIT:
- goto ep_exit;
-
- case KEY_LEFT:
- if (dev->iobase > 0)
- goto ep_iobase;
- break;
-
- case KEY_UP:
- goto ep_flags;
-
- case KEY_DOWN:
- if (dev->msize > 0)
- goto ep_msize;
- if (dev->drq > 0)
- goto ep_drq;
- break;
-
- case KEY_TAB:
- goto ep_msize;
- }
- goto ep_maddr;
- }
- ep_msize:
- if (dev->msize > 0)
- {
- puthelp(" Device memory size (Hexadecimal, 0x1-0x10000)");
- ret = editval(45,19,5,1,0x1,0x10000,&(dev->msize),(dev->attrib & FLG_FIXMSIZE));
- switch(ret)
- {
- case KEY_EXIT:
- goto ep_exit;
-
- case KEY_LEFT:
- if (dev->irq > 0)
- goto ep_irq;
- break;
-
- case KEY_UP:
- if (dev->maddr > 0)
- goto ep_maddr;
- goto ep_flags;
-
- case KEY_DOWN:
- if (dev->drq > 0)
- goto ep_drq;
- break;
-
- case KEY_TAB:
- goto ep_drq;
- }
- goto ep_msize;
- }
- ep_drq:
- if (dev->drq > 0)
- {
- puthelp(" Device DMA request number (Decimal, 1-7)");
- ret = editval(43,20,2,0,1,7,&(dev->drq),(dev->attrib & FLG_FIXDRQ));
- switch(ret)
- {
- case KEY_EXIT:
- goto ep_exit;
-
- case KEY_LEFT:
- goto ep_flags;
-
- case KEY_UP:
- if (dev->msize > 0)
- goto ep_msize;
- if (dev->maddr > 0)
- goto ep_maddr;
- goto ep_flags;
-
- case KEY_TAB:
- goto ep_iobase;
- }
- goto ep_drq;
- }
- }
- ep_exit:
- dev->changed = 1; /* mark as changed */
-}
-
-static char *helptext[] =
-{
- " Using the UserConfig kernel settings editor",
- " -------------------------------------------",
- "",
- "VISUAL MODE:",
- "",
- "- - Layout -",
- "",
- "The screen displays a list of available drivers, divided into two",
- "scrolling lists: Active Drivers, and Inactive Drivers. Each list is",
- "by default collapsed and can be expanded to show all the drivers",
- "available in each category. The parameters for the currently selected",
- "driver are shown at the bottom of the screen.",
- "",
- "- - Moving around -",
- "",
- "To move in the current list, use the UP and DOWN cursor keys to select",
- "an item (the selected item will be highlighted). If the item is a",
- "category name, you may alternatively expand or collapse the list of",
- "drivers for that category by pressing [!bENTER!n]. Once the category is",
- "expanded, you can select each driver in the same manner and either:",
- "",
- " - change its parameters using [!bENTER!n]",
- " - move it to the Inactive list using [!bDEL!n]",
- "",
- "Use the [!bTAB!n] key to toggle between the Active and Inactive list; if",
- "you need to move a driver from the Inactive list back to the Active",
- "one, select it in the Inactive list, using [!bTAB!n] to change lists if",
- "necessary, and press [!bENTER!n] -- the device will be moved back to",
- "its place in the Active list.",
- "",
- "- - Altering the list/parameters -",
- "",
- "Any drivers for devices not installed in your system should be moved",
- "to the Inactive list, until there are no remaining parameter conflicts",
- "between the drivers, as indicated at the top.",
- "",
- "Once the list of Active drivers only contains entries for the devices",
- "present in your system, you can set their parameters (Interrupt, DMA",
- "channel, I/O addresses). To do this, select the driver and press",
- "[!bENTER!n]: it is now possible to edit the settings at the",
- "bottom of the screen. Use [!bTAB!n] to change fields, and when you are",
- "finished, use [!bQ!n] to return to the list.",
- "",
- "- - Saving changes -",
- "",
- "When all settings seem correct, and you wish to proceed with the",
- "kernel device probing and boot, press [!bQ!n] -- you will be asked to",
- "confirm your choice.",
- "",
- NULL
-};
-
-
-/**
- ** helpscreen
- **
- ** Displays help text onscreen for people that are confused, using a simple
- ** pager.
- **/
-static void
-helpscreen(void)
-{
- int topline = 0; /* where we are in the text */
- int line = 0; /* last line we displayed */
- int c, delta = 1;
- char prompt[80];
-
- for (;;) /* loop until user quits */
- {
- /* display help text */
- if (delta)
- {
- clear(); /* remove everything else */
- for (line = topline;
- (line < (topline + 24)) && (helptext[line]);
- line++)
- putxy(0,line-topline,helptext[line]);
- delta = 0;
- }
-
- /* prompt */
- sprintf(prompt,"!i --%s-- [U]p [D]own [Q]uit !n",helptext[line] ? "MORE" : "END");
- putxy(0,24,prompt);
-
- c = getchar(); /* so what do they say? */
-
- switch (c)
- {
- case 'u':
- case 'U':
- case 'b':
- case 'B': /* wired into 'more' users' fingers */
- if (topline > 0) /* room to go up? */
- {
- topline -= 24;
- if (topline < 0) /* don't go too far */
- topline = 0;
- delta = 1;
- }
- break;
-
- case 'd':
- case 'D':
- case ' ': /* expected by most people */
- if (helptext[line]) /* maybe more below? */
- {
- topline += 24;
- delta = 1;
- }
- break;
-
- case 'q':
- case 'Q':
- redraw(); /* restore the screen */
- return;
- }
- }
-}
-
-
-/**
- ** High-level control functions
- **/
-
-
-/**
- ** dolist
- **
- ** Handle user movement within (*list) in the region starting at (row) onscreen with
- ** (num) lines, starting at (*ofs) offset from row onscreen.
- ** Pass (detail) on to drawing routines.
- **
- ** If the user hits a key other than a cursor key, maybe return a code.
- **
- ** (*list) points to the device at the top line in the region, (*ofs) is the
- ** position of the highlight within the region. All routines below
- ** this take only a device and an absolute row : use ofsent() to find the
- ** device, and add (*ofs) to (row) to find the absolute row.
- **/
-static int
-dolist(int row, int num, int detail, int *ofs, DEV_LIST **list, char *dhelp)
-{
- int extended = 0;
- int c;
- DEV_LIST *lp;
- int delta = 1;
-
- for(;;)
- {
- if (delta)
- {
- showparams(ofsent(*ofs,*list)); /* show device parameters */
- drawline(row+*ofs,detail,ofsent(*ofs,*list),1,dhelp); /* highlight current line */
- delta = 0;
- }
-
- c = getchar(); /* get a character */
- if ((extended == 2) || (c==588) || (c==596)) /* console gives "alternative" codes */
- {
- extended = 0; /* no longer */
- switch(c)
- {
- case 588: /* syscons' idea of 'up' */
- case 'A': /* up */
- if (*ofs) /* just a move onscreen */
- {
- drawline(row+*ofs,detail,ofsent(*ofs,*list),0,dhelp);/* unhighlight current line */
- (*ofs)--; /* move up */
- }else{
- lp = prevent(*list); /* can we go up? */
- if (!lp) /* no */
- break;
- *list = lp; /* yes, move up list */
- drawlist(row,num,detail,*list);
- }
- delta = 1;
- break;
-
- case 596: /* dooby-do */
- case 'B': /* down */
- lp = ofsent(*ofs,*list); /* get current item */
- if (!nextent(lp))
- break; /* nothing more to move to */
- drawline(row+*ofs,detail,ofsent(*ofs,*list),0,dhelp); /* unhighlight current line */
- if (*ofs < (num-1)) /* room to move onscreen? */
- {
- (*ofs)++;
- }else{
- *list = nextent(*list); /* scroll region down */
- drawlist(row,num,detail,*list);
- }
- delta = 1;
- break;
- }
- }else{
- switch(c)
- {
- case '\033':
- extended=1;
- break;
-
- case '[': /* cheat : always precedes cursor move */
- case 'O': /* ANSI application key mode */
- if (extended==1)
- extended=2;
- else
- extended=0;
- break;
-
- case 'Q':
- case 'q':
- return(KEY_EXIT); /* user requests exit */
-
- case '\r':
- case '\n':
- return(KEY_DO); /* "do" something */
-
- case '\b':
- case '\177':
- case 599:
- return(KEY_DEL); /* "delete" response */
-
- case 'X':
- case 'x':
- return(KEY_UNZOOM); /* expand everything */
-
- case 'C':
- case 'c':
- return(KEY_ZOOM); /* collapse everything */
-
- case '\t':
- drawline(row+*ofs,detail,ofsent(*ofs,*list),0,dhelp); /* unhighlight current line */
- return(KEY_TAB); /* "move" response */
-
- case '\014': /* ^L, redraw */
- return(KEY_REDRAW);
-
- case '?': /* helptext */
- return(KEY_HELP);
-
- }
- }
- }
-}
-
-
-/**
- ** visuserconfig
- **
- ** Do the fullscreen config thang
- **/
-static int
-visuserconfig(void)
-{
- int actofs = 0, inactofs = 0, mode = 0, ret = -1, i;
- DEV_LIST *dp;
-
- initlist(&active);
- initlist(&inactive);
- alist = active;
- ilist = inactive;
-
- getdevs();
-
- conflicts = findconflict(active); /* find conflicts in the active list only */
-
- redraw();
-
- for(;;)
- {
- switch(mode)
- {
- case 0: /* active devices */
- ret = dolist(1,8,1,&actofs,&alist,
- " [!bEnter!n] Edit device parameters [!bDEL!n] Disable device");
- switch(ret)
- {
- case KEY_TAB:
- mode = 1; /* swap lists */
- break;
-
- case KEY_REDRAW:
- redraw();
- break;
-
- case KEY_ZOOM:
- alist = active;
- actofs = 0;
- expandlist(active);
- redrawactive();
- break;
-
- case KEY_UNZOOM:
- alist = active;
- actofs = 0;
- collapselist(active);
- redrawactive();
- break;
-
- case KEY_DEL:
- dp = ofsent(actofs,alist); /* get current device */
- if (dp) /* paranoia... */
- {
- if (dp->attrib & FLG_MANDATORY) /* can't be deleted */
- break;
- if (dp == alist) /* moving top item on list? */
- {
- if (dp->next)
- {
- alist = dp->next; /* point list to non-moving item */
- }else{
- alist = dp->prev; /* end of list, go back instead */
- }
- }else{
- if (!dp->next) /* moving last item on list? */
- actofs--;
- }
- dp->conflicts = 0; /* no conflicts on the inactive list */
- movedev(dp,inactive); /* shift to inactive list */
- conflicts = findconflict(active); /* update conflict tags */
- dp->changed = 1;
- redrawactive(); /* redraw */
- redrawinactive();
- }
- break;
-
- case KEY_DO: /* edit device parameters */
- dp = ofsent(actofs,alist); /* get current device */
- if (dp) /* paranoia... */
- {
- if (dp->comment == DEV_DEVICE) /* can't edit comments, zoom? */
- {
- masterhelp(" [!bTAB!n] Change fields [!bQ!n] Save device parameters");
- editparams(dp);
- masterhelp(" [!bTAB!n] Change fields [!bQ!n] Save and Exit [!b?!n] Help");
- putxy(0,17,lines);
- conflicts = findconflict(active); /* update conflict tags */
- }else{ /* DO on comment = zoom */
- switch(dp->comment) /* Depends on current state */
- {
- case DEV_COMMENT: /* not currently zoomed */
- dp->comment = DEV_ZOOMED;
- break;
-
- case DEV_ZOOMED:
- dp->comment = DEV_COMMENT;
- break;
- }
- }
- redrawactive();
- }
- break;
- }
- break;
-
- case 1: /* inactive devices */
- ret = dolist(10,7,0,&inactofs,&ilist,
- " [!bEnter!n] Enable device ");
- switch(ret)
- {
- case KEY_TAB:
- mode = 0;
- break;
-
- case KEY_REDRAW:
- redraw();
- break;
-
- case KEY_ZOOM:
- ilist = inactive;
- inactofs = 0;
- expandlist(inactive);
- redrawinactive();
- break;
-
- case KEY_UNZOOM:
- ilist = inactive;
- inactofs = 0;
- collapselist(inactive);
- redrawinactive();
- break;
-
- case KEY_DO:
- dp = ofsent(inactofs,ilist); /* get current device */
- if (dp) /* paranoia... */
- {
- if (dp->comment == DEV_DEVICE) /* can't move comments, zoom? */
- {
- if (dp == ilist) /* moving top of list? */
- {
- if (dp->next)
- {
- ilist = dp->next; /* point list to non-moving item */
- }else{
- ilist = dp->prev; /* can't go down, go up instead */
- }
- }else{
- if (!dp->next) /* last entry on list? */
- inactofs--; /* shift cursor up one */
- }
-
- movedev(dp,active); /* shift to active list */
- conflicts = findconflict(active); /* update conflict tags */
- dp->changed = 1;
- alist = dp; /* put at top and current */
- actofs = 0;
- while(dp->comment == DEV_DEVICE)
- dp = dp->prev; /* forcibly unzoom section */
- dp ->comment = DEV_COMMENT;
- mode = 0; /* and swap modes to follow it */
-
- }else{ /* DO on comment = zoom */
- switch(dp->comment) /* Depends on current state */
- {
- case DEV_COMMENT: /* not currently zoomed */
- dp->comment = DEV_ZOOMED;
- break;
-
- case DEV_ZOOMED:
- dp->comment = DEV_COMMENT;
- break;
- }
- }
- redrawactive(); /* redraw */
- redrawinactive();
- }
- break;
-
- default: /* nothing else relevant here */
- break;
- }
- break;
- default:
- mode = 0; /* shouldn't happen... */
- }
-
- /* handle returns that are the same for both modes */
- switch (ret) {
- case KEY_HELP:
- helpscreen();
- break;
-
- case KEY_EXIT:
- i = yesnocancel(" Save these parameters before exiting? ([!bY!n]es/[!bN!n]o/[!bC!n]ancel) ");
- switch(i)
- {
- case 2: /* cancel */
- redraw();
- break;
-
- case 1: /* save and exit */
- savelist(active,1);
- savelist(inactive,0);
-
- case 0: /* exit */
- nukelist(active); /* clean up after ourselves */
- nukelist(inactive);
- normal();
- clear();
- return(1);
- }
- break;
- }
- }
-}
-#endif /* VISUAL_USERCONFIG */
-
-/*
- * Copyright (c) 1991 Regents of the University of California.
- * All rights reserved.
- * Copyright (c) 1994 Jordan K. Hubbard
- * All rights reserved.
- * Copyright (c) 1994 David Greenman
- * All rights reserved.
- *
- * Many additional changes by Bruce Evans
- *
- * This code is derived from software contributed by the
- * University of California Berkeley, Jordan K. Hubbard,
- * David Greenman and Bruce Evans.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#define PARM_DEVSPEC 0x1
-#define PARM_INT 0x2
-#define PARM_ADDR 0x3
-#define PARM_STRING 0x4
-
-typedef struct _cmdparm {
- int type;
- union {
- struct uc_device *dparm;
- int iparm;
- union {
- void *aparm;
- const char *sparm;
- } u;
- } parm;
-} CmdParm;
-
-typedef int (*CmdFunc)(CmdParm *);
-
-typedef struct _cmd {
- char *name;
- CmdFunc handler;
- CmdParm *parms;
-} Cmd;
-
-
-static int lsdevtab(struct uc_device *);
-static struct uc_device *find_device(char *, int);
-static struct uc_device *search_devtable(struct uc_device *, char *, int);
-static void cngets(char *, int);
-static Cmd *parse_cmd(char *);
-static int parse_args(const char *, CmdParm *);
-static int save_dev(struct uc_device *);
-
-static int list_devices(CmdParm *);
-static int set_device_ioaddr(CmdParm *);
-static int set_device_irq(CmdParm *);
-static int set_device_drq(CmdParm *);
-static int set_device_iosize(CmdParm *);
-static int set_device_mem(CmdParm *);
-static int set_device_flags(CmdParm *);
-static int set_device_enable(CmdParm *);
-static int set_device_disable(CmdParm *);
-static int quitfunc(CmdParm *);
-static int helpfunc(CmdParm *);
-#if defined(INTRO_USERCONFIG)
-static int introfunc(CmdParm *);
-#endif
-
-static int lineno;
-
-#ifdef DEV_EISA
-
-#include <dev/eisa/eisaconf.h>
-
-static int set_num_eisa_slots(CmdParm *);
-
-#endif
-
-static CmdParm addr_parms[] = {
- { PARM_DEVSPEC, {} },
- { PARM_ADDR, {} },
- { -1, {} },
-};
-
-static CmdParm int_parms[] = {
- { PARM_DEVSPEC, {} },
- { PARM_INT, {} },
- { -1, {} },
-};
-
-static CmdParm dev_parms[] = {
- { PARM_DEVSPEC, {} },
- { -1, {} },
-};
-
-#ifdef DEV_EISA
-static CmdParm int_arg[] = {
- { PARM_INT, {} },
- { -1, {} },
-};
-#endif
-
-static Cmd CmdList[] = {
- { "?", helpfunc, NULL }, /* ? (help) */
- { "di", set_device_disable, dev_parms }, /* disable dev */
- { "dr", set_device_drq, int_parms }, /* drq dev # */
-#ifdef DEV_EISA
- { "ei", set_num_eisa_slots, int_arg }, /* # EISA slots */
-#endif
- { "en", set_device_enable, dev_parms }, /* enable dev */
- { "ex", quitfunc, NULL }, /* exit (quit) */
- { "f", set_device_flags, int_parms }, /* flags dev mask */
- { "h", helpfunc, NULL }, /* help */
-#if defined(INTRO_USERCONFIG)
- { "intro", introfunc, NULL }, /* intro screen */
-#endif
- { "iom", set_device_mem, addr_parms }, /* iomem dev addr */
- { "ios", set_device_iosize, int_parms }, /* iosize dev size */
- { "ir", set_device_irq, int_parms }, /* irq dev # */
- { "l", list_devices, NULL }, /* ls, list */
- { "po", set_device_ioaddr, int_parms }, /* port dev addr */
- { "res", (CmdFunc)cpu_reset, NULL }, /* reset CPU */
- { "q", quitfunc, NULL }, /* quit */
-#ifdef VISUAL_USERCONFIG
- { "v", (CmdFunc)visuserconfig, NULL }, /* visual mode */
-#endif
- { NULL, NULL, NULL },
-};
-
-void
-userconfig(void)
-{
- static char banner = 1;
- char input[80];
- int rval;
- Cmd *cmd;
-
- load_devtab();
- init_config_script();
- while (1) {
-
- /* Only display signon banner if we are about to go interactive */
- if (!has_config_script()) {
- if (!(boothowto & RB_CONFIG))
-#ifdef INTRO_USERCONFIG
- banner = 0;
-#else
- return;
-#endif
- if (banner) {
- banner = 0;
- printf("FreeBSD Kernel Configuration Utility - Version 1.2\n"
- " Type \"help\" for help"
-#ifdef VISUAL_USERCONFIG
- " or \"visual\" to go to the visual\n"
- " configuration interface (requires MGA/VGA display or\n"
- " serial terminal capable of displaying ANSI graphics)"
-#endif
- ".\n");
- }
- }
-
- printf("config> ");
- cngets(input, 80);
- if (input[0] == '\0')
- continue;
- cmd = parse_cmd(input);
- if (!cmd) {
- printf("Invalid command or syntax. Type `?' for help.\n");
- continue;
- }
- rval = (*cmd->handler)(cmd->parms);
- if (rval) {
- free_devtab();
- return;
- }
- }
-}
-
-static Cmd *
-parse_cmd(char *cmd)
-{
- Cmd *cp;
-
- for (cp = CmdList; cp->name; cp++) {
- int len = strlen(cp->name);
-
- if (!strncmp(cp->name, cmd, len)) {
- while (*cmd && *cmd != ' ' && *cmd != '\t')
- ++cmd;
- if (parse_args(cmd, cp->parms))
- return NULL;
- else
- return cp;
- }
- }
- return NULL;
-}
-
-static int
-parse_args(const char *cmd, CmdParm *parms)
-{
- while (1) {
- char *ptr;
-
- if (*cmd == ' ' || *cmd == '\t') {
- ++cmd;
- continue;
- }
- if (parms == NULL || parms->type == -1) {
- if (*cmd == '\0')
- return 0;
- printf("Extra arg(s): %s\n", cmd);
- return 1;
- }
- if (parms->type == PARM_DEVSPEC) {
- int i = 0;
- char devname[64];
- int unit = 0;
-
- while (*cmd && !(*cmd == ' ' || *cmd == '\t' ||
- (*cmd >= '0' && *cmd <= '9')))
- devname[i++] = *(cmd++);
- devname[i] = '\0';
- if (*cmd >= '0' && *cmd <= '9') {
- unit = strtoul(cmd, &ptr, 10);
- if (cmd == ptr) {
- printf("Invalid device number\n");
- /* XXX should print invalid token here and elsewhere. */
- return 1;
- }
- /* XXX else should require end of token. */
- cmd = ptr;
- }
- if ((parms->parm.dparm = find_device(devname, unit)) == NULL) {
- printf("No such device: %s%d\n", devname, unit);
- return 1;
- }
- ++parms;
- continue;
- }
- if (parms->type == PARM_INT) {
- parms->parm.iparm = strtoul(cmd, &ptr, 0);
- if (cmd == ptr) {
- printf("Invalid numeric argument\n");
- return 1;
- }
- cmd = ptr;
- ++parms;
- continue;
- }
- if (parms->type == PARM_ADDR) {
- parms->parm.u.aparm = (void *)(uintptr_t)strtoul(cmd, &ptr, 0);
- if (cmd == ptr) {
- printf("Invalid address argument\n");
- return 1;
- }
- cmd = ptr;
- ++parms;
- continue;
- }
- if (parms->type == PARM_STRING) {
- parms->parm.u.sparm = cmd;
- return 0;
- }
- }
- return 0;
-}
-
-static int
-list_devices(CmdParm *parms)
-{
- lineno = 0;
- if (lsdevtab(uc_devtab)) return 0;
-#ifdef DEV_EISA
- printf("\nNumber of EISA slots to probe: %d\n", num_eisa_slots);
-#endif
- return 0;
-}
-
-static int
-set_device_ioaddr(CmdParm *parms)
-{
- parms[0].parm.dparm->id_iobase = parms[1].parm.iparm;
- save_dev(parms[0].parm.dparm);
- return 0;
-}
-
-static int
-set_device_irq(CmdParm *parms)
-{
- unsigned irq;
-
- irq = parms[1].parm.iparm;
-#ifndef PC98
- if (irq == 2) {
- printf("Warning: Remapping IRQ 2 to IRQ 9\n");
- irq = 9;
- }
- else if (irq != -1 && irq > 15) {
-#else
- if (irq != -1 && irq > 15) {
-#endif
- printf("An IRQ > 15 would be invalid.\n");
- return 0;
- }
- parms[0].parm.dparm->id_irq = (irq < 16 ? 1 << irq : 0);
- save_dev(parms[0].parm.dparm);
- return 0;
-}
-
-static int
-set_device_drq(CmdParm *parms)
-{
- unsigned drq;
-
- /*
- * The bounds checking is just to ensure that the value can be printed
- * in 5 characters. 32768 gets converted to -32768 and doesn't fit.
- */
- drq = parms[1].parm.iparm;
- parms[0].parm.dparm->id_drq = (drq < 32768 ? drq : -1);
- save_dev(parms[0].parm.dparm);
- return 0;
-}
-
-static int
-set_device_iosize(CmdParm *parms)
-{
- parms[0].parm.dparm->id_msize = parms[1].parm.iparm;
- save_dev(parms[0].parm.dparm);
- return 0;
-}
-
-static int
-set_device_mem(CmdParm *parms)
-{
- parms[0].parm.dparm->id_maddr = parms[1].parm.u.aparm;
- save_dev(parms[0].parm.dparm);
- return 0;
-}
-
-static int
-set_device_flags(CmdParm *parms)
-{
- parms[0].parm.dparm->id_flags = parms[1].parm.iparm;
- save_dev(parms[0].parm.dparm);
- return 0;
-}
-
-static int
-set_device_enable(CmdParm *parms)
-{
- parms[0].parm.dparm->id_enabled = TRUE;
- save_dev(parms[0].parm.dparm);
- return 0;
-}
-
-static int
-set_device_disable(CmdParm *parms)
-{
- parms[0].parm.dparm->id_enabled = FALSE;
- save_dev(parms[0].parm.dparm);
- return 0;
-}
-
-#ifdef DEV_EISA
-static int
-set_num_eisa_slots(CmdParm *parms)
-{
- int num_slots;
-
- num_slots = parms[0].parm.iparm;
- num_eisa_slots = (num_slots <= 16 ? num_slots : 10);
- return 0;
-}
-#endif
-
-static int
-quitfunc(CmdParm *parms)
-{
- /*
- * If kernel config supplied, and we are parsing it, and -c also supplied,
- * ignore a quit command, This provides a safety mechanism to allow
- * recovery from a damaged/buggy kernel config.
- */
- if ((boothowto & RB_CONFIG) && userconfig_boot_parsing)
- return 0;
- return 1;
-}
-
-static int
-helpfunc(CmdParm *parms)
-{
- printf(
- "Command\t\t\tDescription\n"
- "-------\t\t\t-----------\n"
- "ls\t\t\tList currently configured devices\n"
- "port <devname> <addr>\tSet device port (i/o address)\n"
- "irq <devname> <number>\tSet device irq\n"
- "drq <devname> <number>\tSet device drq\n"
- "iomem <devname> <addr>\tSet device maddr (memory address)\n"
- "iosize <devname> <size>\tSet device memory size\n"
- "flags <devname> <mask>\tSet device flags\n"
- "enable <devname>\tEnable device\n"
- "disable <devname>\tDisable device (will not be probed)\n");
-#ifdef DEV_EISA
- printf("eisa <number>\t\tSet the number of EISA slots to probe\n");
-#endif
- printf(
- "quit\t\t\tExit this configuration utility\n"
- "reset\t\t\tReset CPU\n");
-#ifdef VISUAL_USERCONFIG
- printf("visual\t\t\tGo to fullscreen mode.\n");
-#endif
- printf(
- "help\t\t\tThis message\n\n"
- "Commands may be abbreviated to a unique prefix\n");
- return 0;
-}
-
-#if defined(INTRO_USERCONFIG)
-
-#if defined (VISUAL_USERCONFIG)
-static void
-center(int y, char *str)
-{
- putxy((80 - strlen(str)) / 2, y, str);
-}
-#endif
-
-static int
-introfunc(CmdParm *parms)
-{
-#if defined (VISUAL_USERCONFIG)
- int curr_item, first_time, extended = 0;
- static char *choices[] = {
- " Skip kernel configuration and continue with installation ",
- " Start kernel configuration in full-screen visual mode ",
- " Start kernel configuration in CLI mode ",
- };
-
- clear();
- center(2, "!bKernel Configuration Menu!n");
-
- curr_item = 0;
- first_time = 1;
- while (1) {
- char tmp[80];
- int c, i;
-
- if (!extended) {
- for (i = 0; i < 3; i++) {
- tmp[0] = '\0';
- if (curr_item == i)
- strcpy(tmp, "!i");
- strcat(tmp, choices[i]);
- if (curr_item == i)
- strcat(tmp, "!n");
- putxy(10, 5 + i, tmp);
- }
-
- if (first_time) {
- putxy(2, 10, "Here you have the chance to go into kernel configuration mode, making");
- putxy(2, 11, "any changes which may be necessary to properly adjust the kernel to");
- putxy(2, 12, "match your hardware configuration.");
- putxy(2, 14, "If you are installing FreeBSD for the first time, select Visual Mode");
- putxy(2, 15, "(press Down-Arrow then ENTER).");
- putxy(2, 17, "If you need to do more specialized kernel configuration and are an");
- putxy(2, 18, "experienced FreeBSD user, select CLI mode.");
- putxy(2, 20, "If you are !icertain!n that you do not need to configure your kernel");
- putxy(2, 21, "then simply press ENTER or Q now.");
- first_time = 0;
- }
-
- move(0, 0); /* move the cursor out of the way */
- }
- c = getchar();
- if ((extended == 2) || (c == 588) || (c == 596)) { /* console gives "alternative" codes */
- extended = 0; /* no longer */
- switch (c) {
- case 588:
- case 'A': /* up */
- if (curr_item > 0)
- --curr_item;
- break;
-
- case 596:
- case 'B': /* down */
- if (curr_item < 2)
- ++curr_item;
- break;
- }
- }
- else {
- switch(c) {
- case '\033':
- extended = 1;
- break;
-
- case '[': /* cheat : always precedes cursor move */
- case 'O': /* ANSI application key mode */
- if (extended == 1)
- extended = 2;
- else
- extended = 0;
- break;
-
- case -1:
- case 'Q':
- case 'q':
- clear();
- return 1; /* user requests exit */
-
- case '1': /* select an item */
- case 'S':
- case 's':
- curr_item = 0;
- break;
- case '2':
- case 'V':
- case 'v':
- curr_item = 1;
- break;
- case '3':
- case 'C':
- case 'c':
- curr_item = 2;
- break;
-
- case 'U': /* up */
- case 'u':
- case 'P':
- case 'p':
- if (curr_item > 0)
- --curr_item;
- break;
-
- case 'D': /* down */
- case 'd':
- case 'N':
- case 'n':
- if (curr_item < 2)
- ++curr_item;
- break;
-
- case '\r':
- case '\n':
- clear();
- if (!curr_item)
- return 1;
- else if (curr_item == 1)
- return visuserconfig();
- else {
- putxy(0, 1, "Type \"help\" for help or \"quit\" to exit.");
- /* enable quitfunc */
- userconfig_boot_parsing=0;
- move (0, 3);
- boothowto |= RB_CONFIG; /* force -c */
- return 0;
- }
- break;
- }
- }
- }
-#endif
-}
-#endif
-
-static int
-lsdevtab(struct uc_device *dt)
-{
- for (; dt->id_id != 0; dt++) {
- char dname[80];
-
- if (lineno >= 23) {
- printf("<More> ");
- if (!userconfig_boot_parsing) {
- if (getchar() == 'q') {
- printf("quit\n");
- return (1);
- }
- printf("\n");
- }
- lineno = 0;
- }
- if (lineno == 0) {
- printf(
-"Device port irq drq iomem iosize unit flags enab\n"
- );
- ++lineno;
- }
- sprintf(dname, "%s%d", dt->id_name, dt->id_unit);
- printf("%-9.9s%-#11x%-6d%-6d%-8p%-9d%-6d%-#11x%-5s\n",
- dname, /* dt->id_id, dt->id_driver(by name), */ dt->id_iobase,
- ffs(dt->id_irq) - 1, dt->id_drq, dt->id_maddr, dt->id_msize,
- /* dt->id_intr(by name), */ dt->id_unit, dt->id_flags,
- dt->id_enabled ? "Yes" : "No");
- ++lineno;
- }
- return(0);
-}
-
-static void
-load_devtab(void)
-{
- int i, val;
- int count = resource_count();
- int id = 1;
- int dt;
- char *name;
- int unit;
-
- uc_devtab = malloc(sizeof(struct uc_device) * (count + 1), M_DEVL,
- M_WAITOK | M_ZERO);
- dt = 0;
- for (i = 0; i < count; i++) {
- name = resource_query_name(i);
- unit = resource_query_unit(i);
- if (unit < 0)
- continue; /* skip wildcards */
- uc_devtab[dt].id_id = id++;
- resource_int_value(name, unit, "port", &uc_devtab[dt].id_iobase);
- val = 0;
- resource_int_value(name, unit, "irq", &val);
- uc_devtab[dt].id_irq = (1 << val);
- resource_int_value(name, unit, "drq", &uc_devtab[dt].id_drq);
- resource_int_value(name, unit, "maddr",(int *)&uc_devtab[dt].id_maddr);
- resource_int_value(name, unit, "msize", &uc_devtab[dt].id_msize);
- uc_devtab[dt].id_unit = unit;
- resource_int_value(name, unit, "flags", &uc_devtab[dt].id_flags);
- val = 0;
- resource_int_value(name, unit, "disabled", &val);
- uc_devtab[dt].id_enabled = !val;
- uc_devtab[dt].id_name = malloc(strlen(name) + 1, M_DEVL,M_WAITOK);
- strcpy(uc_devtab[dt].id_name, name);
- dt++;
- }
-}
-
-static void
-free_devtab(void)
-{
- int i;
- int count = resource_count();
-
- for (i = 0; i < count; i++)
- if (uc_devtab[i].id_name)
- free(uc_devtab[i].id_name, M_DEVL);
- free(uc_devtab, M_DEVL);
-}
-
-static struct uc_device *
-find_device(char *devname, int unit)
-{
- struct uc_device *ret;
-
- if ((ret = search_devtable(uc_devtab, devname, unit)) != NULL)
- return ret;
- return NULL;
-}
-
-static struct uc_device *
-search_devtable(struct uc_device *dt, char *devname, int unit)
-{
- int i;
-
- for (i = 0; dt->id_id != 0; dt++)
- if (!strcmp(dt->id_name, devname) && dt->id_unit == unit)
- return dt;
- return NULL;
-}
-
-static void
-cngets(char *input, int maxin)
-{
- int c, nchars = 0;
-
- while (1) {
- c = getchar();
- /* Treat ^H or ^? as backspace */
- if ((c == '\010' || c == '\177')) {
- if (nchars) {
- printf("\010 \010");
- *--input = '\0', --nchars;
- }
- continue;
- }
- /* Treat ^U or ^X as kill line */
- else if ((c == '\025' || c == '\030')) {
- while (nchars) {
- printf("\010 \010");
- *--input = '\0', --nchars;
- }
- continue;
- }
- printf("%c", c);
- if ((++nchars == maxin) || (c == '\n') || (c == '\r') || ( c == -1)) {
- *input = '\0';
- break;
- }
- *input++ = (u_char)c;
- }
-}
-
-static void
-save_resource(struct uc_device *idev)
-{
- char *name;
- int unit;
-
- name = idev->id_name;
- unit = idev->id_unit;
- resource_set_int(name, unit, "port", idev->id_iobase);
- resource_set_int(name, unit, "irq", ffs(idev->id_irq) - 1);
- resource_set_int(name, unit, "drq", idev->id_drq);
- resource_set_int(name, unit, "maddr", (int)idev->id_maddr);
- resource_set_int(name, unit, "msize", idev->id_msize);
- resource_set_int(name, unit, "flags", idev->id_flags);
- resource_set_int(name, unit, "disabled", !idev->id_enabled);
-}
-
-static int
-save_dev(idev)
-struct uc_device *idev;
-{
- struct uc_device *id_p,*id_pn;
- char *name = idev->id_name;
-
- for (id_p = uc_devlist; id_p; id_p = id_p->id_next) {
- if (id_p->id_id == idev->id_id) {
- id_pn = id_p->id_next;
- if (id_p->id_name)
- free(id_p->id_name, M_DEVL);
- bcopy(idev,id_p,sizeof(struct uc_device));
- save_resource(idev);
- id_p->id_name = malloc(strlen(name)+1, M_DEVL,M_WAITOK);
- strcpy(id_p->id_name, name);
- id_p->id_next = id_pn;
- return 1;
- }
- }
- id_pn = malloc(sizeof(struct uc_device),M_DEVL,M_WAITOK);
- bcopy(idev,id_pn,sizeof(struct uc_device));
- save_resource(idev);
- id_pn->id_name = malloc(strlen(name) + 1, M_DEVL,M_WAITOK);
- strcpy(id_pn->id_name, name);
- id_pn->id_next = uc_devlist;
- uc_devlist = id_pn;
- return 0;
-}
-
-
OpenPOWER on IntegriCloud