/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION  1986,1987,1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:swapgeneric.c 12.0$ */
/* $ACIS:swapgeneric.c 12.0$ */
/* $Source: /ibm/acis/usr/sys/ca/RCS/swapgeneric.c,v $ */

#if !defined(lint) && !defined(NO_RCS_HDRS)
static char *rcsid = "$Header:swapgeneric.c 12.0$";
#endif

/*	swapgeneric.c	6.1	83/08/05	*/


#include "pte.h"

#include "param.h"
#include "conf.h"
#include "buf.h"
#include "vm.h"
#include "systm.h"
#include "reboot.h"
#include "../machineio/ioccvar.h"

#ifndef GENERIC
#define options_GENERIC_not_specified_when_swap_generic_used( /* ) left off to cause error  */
#endif GENERIC

/*
 * Generic configuration;  all in one
 */
dev_t	rootdev = NODEV;
dev_t	argdev = NODEV;
dev_t	dumpdev = NODEV;
int nswap;
struct swdevt swdevt[] = {
	{ -1, 1, 0 },
	{ 0, 0, 0 },
};
long dumplo;
int dmmin, dmmax, dmtext;


#include "hd.h"
#if NHDC > 0
extern struct iocc_driver hdcdriver;
#endif NHDC

#include "fd.h"
#if NFDC > 0
extern struct iocc_driver fdcdriver;
#endif NFDC

#ifdef IBMRTPC
#include "sc.h"
#if NSCC > 0
extern struct iocc_driver sccdriver;
#endif NSCC

#include "st.h"
#if NSTC > 0
extern struct iocc_driver stcdriver;
#endif NSTC
#endif IBMRTPC

struct genericconf {
	caddr_t gc_driver;
	char *gc_name;
	dev_t gc_root;
} genericconf[] = {
#if NHDC > 0
	{ (caddr_t) & hdcdriver, "hd", makedev(1, 0), },
#endif NHDC
#if NFDC > 0
	{ (caddr_t) & fdcdriver, "fd", makedev(3, 0), },
#endif NFDC
#ifdef IBMRTPC
#if NSCC > 0
	{ (caddr_t) & sccdriver, "sc", makedev(7, 0), },
#endif NSCC
#if NSTC > 0
	{ (caddr_t) & stcdriver, "st", makedev(5, 0), },
#endif NSTC
#endif IBMRTPC
	{ 0 },
};


setconf()
{
	register struct iocc_device *mi;
	register struct genericconf *gc;
	int unit, swaponroot = 0;
	int part = 0;

	if (rootdev != NODEV)
		goto doswap;
	if (boothowto & RB_ASKNAME) {
		char name[128];
retry:
		printf("root device? ");
		gets(name);
		for (gc = genericconf; gc->gc_driver; gc++)
			if (gc->gc_name[0] == name[0] &&
			    gc->gc_name[1] == name[1])
				goto gotit;
		goto bad;
gotit:
		if (name[3] == '*') {
			name[3] = name[4];
			swaponroot++;
		} else if (name[3] >= 'a' && name[3] <= 'g' && name[4] == 0) {
			part = name[3] - 'a';
			name[3] = name[4];
		} else
			part = 0;
		if (name[2] >= '0' && name[2] <= '9' && name[3] == 0) {
			unit = name[2] - '0';
			goto found;
		} else if (name[2] >='a' && name[2] <= 'c' && name[3] == 0) {
			unit = (name[2] - 'a') + 10;
			goto found;
		}
		printf("bad/missing unit number\n");
bad:
		printf("use hd%%d, sc%%d, fd%%d, or st%%d\n");
		goto retry;
	}
	unit = 0;
	for (gc = genericconf; gc->gc_driver; gc++) {
		for (mi = ioccdinit; mi->iod_driver; mi++) {
			if (mi->iod_alive == 0)
				continue;
			if (mi->iod_unit == 0 && mi->iod_driver ==
			    (struct iocc_driver *)gc->gc_driver) {
				printf("root on %s0\n",
				    mi->iod_driver->idr_dname);
				goto found;
			}
		}
	}
	printf("no suitable root\n");
	goto retry;
found:
	gc->gc_root = makedev(major(gc->gc_root), unit * 8 + part);
	rootdev = gc->gc_root;
doswap:
	swdevt[0].sw_dev = argdev = dumpdev =
	    makedev(major(rootdev), minor(rootdev) + 1);
	/* swap size and dumplo set during autoconfigure */
	if (swaponroot)
		rootdev = dumpdev;
}


gets(cp)
	char *cp;
{
	register char *lp;
	register c;

	lp = cp;
	for (;;) {
		c = getchar() & 0177;
		switch (c) {
		case '\n':
		case '\r':
			*lp++ = '\0';
			return;
		case '\b':
		case '#':
			lp--;
			if (lp < cp)
				lp = cp;
			continue;
		case '@':
		case 'u' & 037:
			lp = cp;
			cnputc('\n');
			continue;
		default:
			*lp++ = c;
		}
	}
}


#define KBD_DATA	0x01		  /* value for data present */
#define NONE_FLAG	0x80		  /* flag for no code defined */

#include "../machinecons/screen_conf.h"
getchar()
{
	register int c, ch;
	int iid;
	extern int _init_kbd;
	extern SCREEN_INFO cons[];
	extern int cons_if;

	for (;;) {
		ch = kls_raw_read(&iid);
#ifdef ATR
#define KBD_ASCII 2
		if (iid == KBD_ASCII) {
			c = ch;
			break;
		}
#endif ATR
		if (iid != KBD_DATA)
			continue;
		if (((c = kbde_key_scan(&cons[cons_if], ch)) & NONE_FLAG) == 0)
			break;
	}
	if (c == '\r')
		c = '\n';
	cnputc(c);
	return (c);
}

