Files
seta75D 2e8a93c394 Init
2021-10-11 18:20:23 -03:00

561 lines
12 KiB
C

#ifndef lint
static char sccsid[] = "@(#)vfs_generic.c 1.1 92/07/30 Copyr 1983 Sun Micro";
#endif
/*
* Mostly stolen from estale:/usr.MC68020/estale/sys/sys/sun/swapgeneric.c
*/
/*
* Copyright (c) 1983 by Sun Microsystems, Inc.
*/
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/buf.h>
#include <sys/vm.h>
#include "boot/systm.h"
#include <sys/reboot.h>
#include <sys/file.h>
#include <sys/vfs.h>
#undef KERNEL
#undef NFS
#include <sys/mount.h>
#include <machine/pte.h>
#include <sundev/mbvar.h>
#include <mon/sunromvec.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include "boot/protosw.h"
#include <net/if.h>
#include <stand/saio.h>
#include "boot/conf.h"
#undef MOUNT_MAXTYPE
#define MOUNT_MAXTYPE 2
extern struct bdevlist bdevlist[];
#ifdef OPENPROMS
extern struct ndevlist ndevlist[];
#endif
int dump_debug = 10;
/*
* What it does:
*/
struct vfssw *
getfstype(askfor, fsname)
char *askfor;
char *fsname;
{
int fstype;
if (boothowto & RB_ASKNAME) {
for (fsname[0] = '\0'; fsname[0] == '\0'; ) {
printf("%s filesystem type ( ", askfor);
for (fstype = 0; fstype < MOUNT_MAXTYPE; fstype++) {
if (vfssw[fstype].vsw_name)
printf("%s ", vfssw[fstype].vsw_name);
}
printf(" ): ");
(void) gets(fsname);
for (fstype = 0; fstype < MOUNT_MAXTYPE; fstype++) {
if (vfssw[fstype].vsw_name == 0) {
continue;
}
if (*fsname == '\0') {
(void) strcpy(fsname,
vfssw[fstype].vsw_name);
return (&vfssw[fstype]);
}
if (strcmp(vfssw[fstype].vsw_name, fsname)==0) {
return (&vfssw[fstype]);
}
}
printf("Unknown filesystem type '%s'\n", fsname);
*fsname = '\0';
}
} else if (*fsname) {
for (fstype = 0; fstype < MOUNT_MAXTYPE; fstype++) {
if (vfssw[fstype].vsw_name == 0) {
continue;
}
if (strcmp(vfssw[fstype].vsw_name, fsname) == 0) {
return (&vfssw[fstype]);
}
}
}
return ((struct vfssw *)0);
}
/*
* If booted with ASKNAME prompt on the console for a filesystem
* name and return it.
*/
getfsname(askfor, name)
char *askfor;
char *name;
{
if (boothowto & RB_ASKNAME) {
printf("%s name: ", askfor);
(void) gets(name);
}
}
/*
* Return the device number and name of the frist block
* block device in the bdevlist that cna be opened.
* If booted with the -a flag ask user for device name.
* Name must be at least 128 bytes long.
* askfor is one of "root" or "swap".
*/
dev_t
getblockdev(askfor, name)
char *askfor;
char *name;
{
register struct bdevlist *bl;
register int i;
register char *cp;
int unit;
int part;
int ctlr = 0;
dev_t dev;
#ifdef OPENPROMS
extern struct bootparam *prom_bootparam();
dev_t obp_getblockdev();
if (prom_getversion() > 0)
return (obp_getblockdev(askfor, name));
#endif
#ifndef sun4m
if (boothowto & RB_ASKNAME) {
for (unit = -1; unit == -1; ) {
printf("%s device ( ", askfor);
for (bl = bdevlist; bl->bl_name; bl++)
if (strcmp(bl->bl_name, "") != 0)
if (bl->bl_flags == 0)
printf("%s%cd[a-h] ", bl->bl_name, '%');
else
printf("%s%c3x[a-h] ", bl->bl_name, '%');
printf("): ");
(void) gets(name);
if (*name == '\0') {
bl = bdevlist;
unit = 0;
part = 0;
break;
}
for (bl = bdevlist; bl->bl_name; bl++) {
if (bl->bl_name[0] == name[0] &&
bl->bl_name[1] == name[1])
break;
}
if (!bl->bl_name) {
printf("unknown device name %c%c\n",
name[0], name[1]);
continue;
}
/* Get unit from name string */
if (bl->bl_flags == 0) {
if (name[2] < '0' || name[2] > '7') {
printf("bad/missing unit number\n");
continue;
}
} else {
if (name[2] != '0' || name[3] != '0' ||
(!((name[4] >= '0' && name[4] <= '9') ||
(name[4] >= 'a' && name[4] <= 'f')))) {
printf("bad/missing unit number\n");
continue;
}
}
/*
* FIXME: We need something like a conf table
* (e.g. GENERIC) to make the device name into
* the REAL device info. This HACK fixes
* up SCSI for the time being. Note, the
* controller is always 0.
*/
if (bl->bl_flags == 0)
unit = name[2] - '0';
else {
if (name[4] >= '0' || name[4] <= '9')
unit = name[4] - '0';
else
unit = 10 + name[4] - 'a';
ctlr = name[3] - '0';
}
#ifndef OPENPROMS
if (name[0] == 's' && name[1] == 'd')
unit = (unit & 0xFE) <<2 | (unit & 0x01);
#endif
/* Get partition from name string */
if (bl->bl_flags ==0) {
if (name[3] == '\0') {
part = 0;
} else if (name[3] >= 'a' && name[3] <= 'h') {
part = name[3] - 'a';
} else {
printf("bad partition (use a-h)\n");
unit = -1;
}
} else {
if (name[5] == '\0') {
part = 0;
} else if (name[5] >= 'a' && name[5] <= 'h') {
part = name[5] - 'a';
} else {
printf("bad partition (use a-h)\n");
unit = -1;
}
}
}
} else {
unit = 0;
part = 0;
/*
* If a name was given find that block device
* If rootfs is not initialized, this doesn't happen
*/
if (*name != '\0') {
for (bl = bdevlist; bl->bl_name; bl++) {
if (bl->bl_name[0] == name[0] &&
bl->bl_name[1] == name[1]) {
if (chkroot(bl)) {
if (name[2] != '\0')
unit = name[2] - '0';
if (name[3] != '\0')
part = name[3] - 'a';
goto found;
}
}
}
printf("%c%c%c%c not configured in boot\n",
name[0], name[1], name[2], name[3]);
return ((dev_t)0);
}
/*
* Look for device we booted from
*/
for (bl = bdevlist; bl->bl_name; bl++) {
#ifdef OPENPROMS
register struct bootparam *bp = prom_bootparam();
#else OPENPROMS
register struct bootparam *bp = (*romp->v_bootparam);
#endif OPENPROMS
if (!((*bl->bl_name == bp->bp_dev[0]) &&
(*(bl->bl_name+1) == bp->bp_dev[1])))
continue;
/*
* This is a cheat. Since we don't support
* the full apparatus of the mb_device list,
* we assume the device we were booted from
* is openable if we located it in the
* bdevlist..
*/
ctlr = bp->bp_ctlr;
unit = bp->bp_unit;
part = bp->bp_part;
goto found;
}
/*
* Use first device that can be opened
*/
for (bl = bdevlist; bl->bl_name; bl++) {
if (chkroot(bl)) {
goto found;
}
}
return ((dev_t)0);
}
found:
name[0] = bl->bl_name[0];
name[1] = bl->bl_name[1];
cp = name + 2;
#ifndef OPENPROMS
/*
* FIXME: We need something like a conf table
* to track kernel conf file changes.
*/
if (name[0] == 's' && name[1] == 'd')
unit = ((unit & 0xF8) >>2 | (unit & 0x01));
#endif OPENPROMS
if (bl->bl_flags) {
*cp++ = '0';
*cp++ = '0' + ctlr;
*cp++ = '0' + unit;
} else {
*cp++ = '0' + unit;
}
cp[0] = 'a' + part;
cp[1] = '\0';
dev = makedev(major(bl->bl_root), (ctlr << 6 | unit << 3 | part));
return dev;
#endif !sun4m
}
#ifdef OPENPROMS
/*
* Return the device number and name of the frist block
* block device in the bdevlist that cna be opened.
* If booted with the -a flag ask user for device name.
* Name must be at least 128 bytes long.
* askfor is one of "root" or "swap".
*/
#define ASKBUFSIZE (256)
dev_t
obp_getblockdev(askfor, name)
char *askfor;
char *name;
{
register struct bdevlist *bl;
register struct boottab *dp;
register int unit;
register char *cp, *p;
extern char *prom_bootpath();
register char *bpath = prom_bootpath();
char *rootname = name;
char *kmem_alloc();
static char *prompt = "%s (block) device ('*' for list) : ";
extern int Mustask;
void prom_interpret();
bl = &bdevlist[1];
dp = bl->bl_driver;
strncpy(dp->b_dev, "bl", 2);
if (boothowto & RB_ASKNAME) {
cp = kmem_alloc(ASKBUFSIZE);
while (1) {
printf("Default %s device: %s\n", askfor, bpath);
printf(prompt, askfor);
(void) gets(cp);
if (*cp == (char)0) { /* Default? */
strcpy(cp, bpath);
printf("%s (block) device : %s\n",
askfor, bpath);
break;
}
if (strcmp("*", cp) != 0)
break;
printf("\nDevice tree info:\n");
prom_interpret("show-devs");
printf("\nAvailable device aliases:\n");
prom_interpret("devalias");
}
name = bl->bl_name;
(void)strcpy(name, cp);
/*
* Allow user to specify partition as an option character.
*/
if (*(p = name) != (char)0) {
while (*p++ != (char)0) /* Partition specified? */
;
p -= 3; /* Back up over '\0', 'a', : */
}
if (*name && (*name == '/') && (*p != ':')) {
unit = -1;
do {
printf("Partition ('a' - 'h') : ");
(void)gets(cp);
if (*cp && (*cp < 'a' || *cp > 'h')) {
printf("Invalid partition number.\n");
} else
unit = 0;
} while (unit != 0);
if (*cp) {
for (; *name; name++);
*name++ = ':';
*name++ = *cp;
*name = '\0';
}
}
/*
* Try to update bootpath ... PROM devalias expansion needed
*/
if (*(bl->bl_name) == '/')
(void)strcpy(bpath, bl->bl_name);
else
Mustask++;
kmem_free(cp, ASKBUFSIZE);
} else {
/*
* If a name was given find that block device
* If rootfs is not initialized, this doesn't happen
*/
if (*name != '\0') {
/*
* chkroot() always return 0 anyway, no point
* to go through the checking
*/
printf("%s not configured in boot\n", name);
return ((dev_t)0);
}
#ifdef DUMP_DEBUG
dprint(dump_debug, 10, "bpath = %s\n", bpath);
#endif /* DUMP_DEBUG */
/*
* use the boot device
*/
strcpy(bl->bl_name, bpath);
}
found:
strcpy(rootname, bl->bl_name);
return (makedev(major(bl->bl_root), 0));
}
/*
* Return the device number and name of the frist net
* device in the ndevlist that can be opened.
* If booted with the -a flag ask user for device name.
* Name must be at least 128 bytes long.
* askfor is "ether" now.
*/
dev_t
getnetdev(askfor)
char *askfor;
{
register struct ndevlist *nl;
register struct boottab *dp;
extern char *prom_bootpath();
register char *bpath = prom_bootpath();
static char *prompt = "%s device ('*' for list) : ";
extern int Mustask;
extern void prom_interpret();
nl = &ndevlist[0];
dp = nl->nl_driver;
strncpy(dp->b_dev, "nl", 2);
if (boothowto & RB_ASKNAME) {
while (1) {
printf("Default %s device: %s\n", askfor, bpath);
printf(prompt, askfor);
(void) gets(nl->nl_name);
if (*(nl->nl_name) == (char)0) { /* default? */
strcpy(nl->nl_name, bpath);
printf("%s device : %s\n", askfor, bpath);
break;
}
if (strcmp("*", nl->nl_name) != 0) {
/*
* Try to update bootpath ...
* PROM devalias expansion needed!
*/
if (*(nl->nl_name) == '/')
strcpy(bpath, nl->nl_name);
else
Mustask++;
break;
}
printf("\nDevice tree info:\n");
prom_interpret("show-devs");
printf("\nAvailable device aliases:\n");
prom_interpret("devalias");
}
} else
strcpy(nl->nl_name, bpath);
found:
return (nl->nl_root);
}
#endif OPENPROMS
/*ARGSUSED*/
chkroot(bl)
register struct bdevlist *bl;
{
#ifdef lint
bl = bl;
#endif lint
return (0);
}
#ifdef OPENPROMS
#define millitime() prom_gettime()
#else
#define millitime() (*romp->v_nmiclock)
#endif !OPENPROMS
#define SLEEPTIME 5 /* in seconds */
sleep (addr, prio)
{
register int time, i;
#ifdef DUMP_DEBUG
dprint(dump_debug, 10,
"sleep (addr 0x%x, prio 0x%x)\n",
addr, prio);
#endif /* DUMP_DEBUG */
/*
* this used to be a panic, but let's just spin a while
* and see what happens
*/
for (i = 0, time = millitime(); i < 10000000; i++)
if (millitime() > (time + SLEEPTIME*1000))
break;
}
/*
* Arrange that (*fun)(arg) is called in t/hz seconds.
*/
timeout(fun, arg, t)
int (*fun)();
caddr_t arg;
register int t;
{
#ifdef lint
t = t;
#endif lint
{
int i;
for (i = 1; i > 0; i--) {
if (get_udp() != 0) return;
}
}
(*fun)(arg);
return;
}
/*
* Wake up all processes sleeping on chan.
*/
wakeup(chan)
register caddr_t chan;
{
#ifdef DUMP_DEBUG
dprint(dump_debug, 0,
"wakeup(chan 0x%x)\n",
chan);
#endif /* DUMP_DEBUG */
}