File:  [MW Coherent from dump] / coherent / d / etc / build / mkdev.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:37 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * mkdev.c
 * 10/25/90
 * Allow the user to configure devices requiring loadable drivers.
 * Uses common routines in build0.c: cc -o mkdev mkdev.c build0.c
 * Usage: mkdev [ -bdv ] { scsi | at }
 * Options:
 *	-b	Use special processing when invoked from /etc/build
 *	-d	Debug; echo commands without executing
 *	-v	Verbose
 *
 * $Log: mkdev.c,v $
 * Revision 1.1.1.1  2019/05/29 04:56:37  root
 * coherent
 *
 * Revision 1.6  92/01/17  11:31:17  bin
 * another hal update... looks like the final 321 ship version
 * 
 *
 * Roughly, do the following for device "foo" ( at | aha154x | ss )
 *
 *	cp /drv/foo /tmp/drv/foo
 *	make necessary patches "xxx" to /tmp/drv/foo
 *	if not "at" device
 *		make nodes (mknod -f) for the device
 *	if build mode (bflag)
 *		if rootdev
 *			append to LDKERFILE:
 *				HD=foo.a
 *				HDUNDEF="-u foocon_"
 *				HDPATCH="drvl_+xx0=foocon_"
 *		/etc/drvld -r /tmp/drv/foo
 *		append to PATCHFILE:
 *			cp /tmp/drv/foo /mnt/drv/foo
 *		if rootdev, also append to PATCHFILE:
 *			/conf/patch /mnt/coherent xxx
 *	else - not build mode
 *		display message saying patched driver is at /tmp/drv/foo
 */

#include <stdio.h>
#include <sys/devices.h>
#include "build0.h"

#define	VERSION		"V1.4"		/* version number */
#define	USAGEMSG	"Usage:\t/etc/mkdev [ -bdv ] [ scsi | at ]\n"
#define BUFLEN		50
#define AHA_HDS		64
#define AHA_DMA		5
#define AHA_IRQ		11
#define AHA_BASE	0x330
#define TANDY_HDS	16

/* Forward. */
void	scsi();
void	at();

/* Globals. */
int	bflag;				/* Invoked from /etc/build. */

main(argc, argv) int argc; char *argv[];
{
	register char *s;

	argv0 = argv[0];
	usagemsg = USAGEMSG;
	if (argc > 1 && argv[1][0] == '-') {
		for (s = &argv[1][1]; *s; ++s) {
			switch(*s) {
			case 'b':	++bflag;	break;
			case 'd':	++dflag;	break;
			case 'v':	++vflag;	break;
			case 'V':
				fprintf(stderr, "mkdev: %s\n", VERSION);
				break;
			default:	usage();	break;
			}
		}
		--argc;
		++argv;
	}

	if (argc == 1) {
		usage();
	} else {
		/* Do specified things. */
		while (--argc > 0) {
			if (strcmp(argv[1], "scsi") == 0)
				scsi();
			else if (strcmp(argv[1], "at") == 0)
				at();
			else
				usage();
			++argv;
		}
	}
	exit(0);
}

void
scsi()
{
	char *dev, *coh;
	int i, id, lun, rootflag;
	int ss_dev = 0;
	int fut_dev = 0;
	short nsdrive = 0;
	int ss_int = 5, new_int;
	unsigned int ss_base = 0xCA00, new_base;
	unsigned char ss_patch[80], buf[BUFLEN];
	FILE *fp;
	int aha_dev = 0, sd_hds = AHA_HDS, sd_dma = AHA_DMA;
	int sd_irq = AHA_IRQ, sd_base = AHA_BASE;

	rootflag = 0;
#if	0
	/* For future use, not much use with only one supported host adapter. */
again:
#endif
	cls(0);
	printf(
"COHERENT currently supports the following SCSI host adapters:\n"
"\n"
"(1) Adaptec AHA-154x series\n"
"(2) Seagate ST01 or ST02\n"
"(3) Future Domain TMC-845/850/860/875/885\n"
"(4) Future Domain TMC-840/841/880/881\n"
"\n"
		);
retry:
	switch(get_int(0, 4, "Enter a number from the above list or 0 to exit:")) {
	case 0:
		return;
	case 1:
		aha_dev = 1;
		coh = "aha";
		break;
	case 2:
		ss_dev = 1;
		coh = "ss";
		break;
	case 3:
		ss_dev = 1;
		fut_dev = 1;
		coh = "ss";
		nsdrive |= 0x8000;
		break;
	case 4:
		ss_dev = 1;
		fut_dev = 1;
		coh = "ss";
		nsdrive |= 0x4000;
		break;
	default:
		goto retry;		/* should never happen */
	}

	/* Make /tmp/drv if not already there. */
	if ((i = is_dir("/tmp/drv")) == 0)
		sys("/bin/mkdir /tmp/drv", S_FATAL);
	else if (i == -1)
		fatal("/tmp/drv is not a directory");

	/*
	 * If Adaptec, allow patching host adapter variables SD_HDS
	 * for Tandy variant of host BIOS.
	 */
	if (aha_dev) {
printf("\nMost versions of the Adaptec BIOS use 64-head translation mode.\n");
printf("A few, including some Tandy variants, use 16-head translation mode.\n\n");
		if (!yes_no("Do you want 64-head translation mode"))
			sd_hds = TANDY_HDS;
printf("\nWhich IRQ does the host adapter use (9/10/11/12/14/15) [%d]? ",
	sd_irq);
		for (;;) {
			new_int = sd_irq;
			fgets(buf, BUFLEN, stdin);
			sscanf(buf, "%d", &new_int);
			switch(new_int) {
			case 9:
			case 10:
			case 11:
			case 12:
			case 14:
			case 15:
				goto ok_sdirq;
			}
printf("Type 9,10,11,12,14,15 or just <Enter> for the default: ");
		} /* endwhile */
ok_sdirq:
		sd_irq = new_int;

printf("\nWhat is the hexadecimal host adapter base port address \n");
printf("  (130/134/230/234/330/334) [%x]? ", sd_base);
		for (;;) {
			new_int = sd_base;
			fgets(buf, BUFLEN, stdin);
			sscanf(buf, "%x", &new_int);
			switch(new_int) {
			case 0x130:
			case 0x134:
			case 0x230:
			case 0x234:
			case 0x330:
			case 0x334:
				goto ok_sdbase;
			}
printf("Type 130,134,230,234,330,334 or just <Enter> for the default: ");
		} /* endfor */
ok_sdbase:
		sd_base = new_int;

printf("\nWhich DMA channel does the host adapter use (0/5/6/7) [%d]? ",
	sd_dma);
		for (;;) {
			new_int = sd_dma;
			fgets(buf, BUFLEN, stdin);
			sscanf(buf, "%d", &new_int);
			if (new_int != 0 && new_int != 5
			&& new_int != 6 && new_int != 7)
printf("Type 0,5,6,7 or just <Enter> for the default: ");
			else
				break;
		} /* endwhile */
		sd_dma = new_int;
	}

	/*
	 * If Seagate or Future Domain, allow patching host adapter
	 * variables SS_INT and SS_BASE.
	 */
	if (ss_dev) {
printf("\nPlease refer to the installation guide for your host adapter.\n");

		/* Get value to patch for SS_INT */
printf("\nWhich IRQ number does the host adapter use [%d]? ", ss_int);
		while (1) {
			new_int = ss_int;
			fgets(buf, BUFLEN, stdin);
			sscanf(buf, "%d", &new_int);
			if (new_int < 3 || new_int > 15)
printf("Type a number between 3 and 15 or just <Enter> for the default: ");
			else
				break;
		} /* endwhile */
		ss_int = new_int;

		/* Get value to patch for SS_BASE */
printf("Your host adapter is configured for a base segment address.  Possible\n");
printf("values are: C800, CA00, CC00, CE00, DC00, and DE00.\n");
printf("What is your 4-digit hexadecimal base address [%04X]? ", ss_base);
		while (1) {
			new_base = ss_base;
			fgets(buf, BUFLEN, stdin);
			sscanf(buf, "%x", &new_base);
			if (new_base < 0xC800 || new_base > 0xDE00)
printf("Type a number between C800 and DE00 or just <Enter> for the default: ");
			else
				break;
		} /* endwhile */
		ss_base = new_base;
	}
	
	/*
	 * Set rootflag if root partition is on SCSI device.
	 * If using both AT and SCSI devices, write to drvld.all for
	 * non-root device.
	 */
	if (bflag) {
		cls(0);
		if (yes_no(
"Does your computer system include both a standard AT-type hard disk\n"
"and a SCSI hard disk" )) {
			if (yes_no(
"Will the COHERENT root partition be on this SCSI device")) {
				++rootflag;
sys("/bin/echo /etc/drvld -r /drv/at >> /tmp/drvld.all", S_FATAL);
			} else {	/* root is on "at" device */
sprintf(cmd, "/bin/echo /etc/drvld -r /drv/%s >> /tmp/drvld.all",
(aha_dev)?"aha154x":"ss");
				sys(cmd, S_FATAL);
			}
		} else {	/* SCSI-only system */
			++rootflag;
		}
	}

	/* Make device nodes. */
	cls(0);
	printf(
"You must specify a SCSI-ID (0 through 7) for each SCSI hard disk device.\n"
"Each SCSI hard disk device can contain up to four partitions.\n\n"
		);

newdev:
	id = get_int(0, 7, "Enter the SCSI-ID:");
#if	1
	lun = 0;
	nsdrive |= (1 << id);
#else
	lun = get_int(0, 3, "Enter the LUN:");
#endif

	/* Make /tmp/dev if bflag. */
	if (bflag) {
		if ((i = is_dir("/tmp/dev")) == 0)
			sys("/bin/mkdir /tmp/dev", S_FATAL);
		else if (i == -1)
			fatal("/tmp/dev is not a directory");
	}
	dev = (bflag) ? "/tmp/dev" : "/dev";

	/* Make the cooked devices. */
	for (i = 0; i < 4; i++) {
		sprintf(cmd, "/etc/mknod -f %s/sd%d%c b %d %d",
			dev, id, 'a'+i, SCSI_MAJOR, SCSI_minor(0, id, lun, i));
		sys(cmd, S_NONFATAL);
	}
	sprintf(cmd, "/etc/mknod -f %s/sd%dx b %d %d",
		dev, id, SCSI_MAJOR, SCSI_minor(1, id, lun, 0));
	sys(cmd, S_NONFATAL);

	/* Make the raw devices. */
	for (i = 0; i < 4; i++) {
		sprintf(cmd, "/etc/mknod -f %s/rsd%d%c c %d %d",
			dev, id, 'a'+i, SCSI_MAJOR, SCSI_minor(0, id, lun, i));
		sys(cmd, S_NONFATAL);
	}
	sprintf(cmd, "/etc/mknod -f %s/rsd%dx c %d %d",
		dev, id, SCSI_MAJOR, SCSI_minor(1, id, lun, 0));
	sys(cmd, S_NONFATAL);

	/* Set the device permissions. */
	sprintf(cmd, "/bin/chmod 0600 %s/sd* %s/rsd*", dev, dev);
	sys(cmd, S_NONFATAL);
	sprintf(cmd, "/bin/chown sys %s/sd*[a-d] %s/rsd*[a-d]", dev, dev);
	sys(cmd, S_NONFATAL);
	sprintf(cmd, "/bin/chgrp sys %s/sd*[a-d] %s/rsd*[a-d]", dev, dev);
	sys(cmd, S_NONFATAL);
	sprintf(cmd, "/bin/chown root %s/sd*x %s/rsd*x", dev, dev);
	sys(cmd, S_NONFATAL);
	sprintf(cmd, "/bin/chgrp root %s/sd*x %s/rsd*x", dev, dev);
	sys(cmd, S_NONFATAL);

	/* Append lines to /tmp/devices to pass device info to /etc/build. */
	if (bflag) {
		for (i = 0; i < 4; i++) {
			sprintf(cmd, "/bin/echo sd%dx sd%d%c %d %d >>/tmp/devices",
				id, id, 'a'+i, SCSI_MAJOR, SCSI_minor(0, id, lun, i));
			sys(cmd, S_NONFATAL);
		}
	}
	if (yes_no("Do you have another SCSI hard disk device on this host adapter"))
		goto newdev;

	/*
	 * Ugly patching stuff specific to "ss" driver.
	 * At this point all SCSI id's attached to the host are known.
	 */
	if (ss_dev) {
		int unit;

		/* "ss" device driver requires patching to work at all. */
		sprintf(ss_patch,
			"NSDRIVE_=0x%04x SS_INT_=%d SS_BASE_=0x%04x",
			nsdrive, ss_int, ss_base);
		sys("/bin/cp /drv/ss /tmp/drv/ss", S_FATAL);
		sprintf(cmd, "/conf/patch /tmp/drv/ss %s", ss_patch);
		sys(cmd, S_FATAL);
		if (bflag) {
			if (rootflag) {
				fp = fopen(LDKERFILE, "a");
				fprintf(fp, "HD=ss.a\n");
				fprintf(fp, "HDUNDEF=\"-u sscon_\"\n");
				fprintf(fp, "HDPATCH=\"drvl_+130=sscon_\"\n");
				fclose(fp);
			}
			sys("/etc/drvld -r /tmp/drv/ss", S_FATAL);
			fp = fopen(PATCHFILE, "a");
			fprintf(fp, "/conf/patch /mnt/drv/ss %s\n", ss_patch);
			if (rootflag)
				fprintf(fp,
				  "/conf/patch /mnt/coherent %s\n", ss_patch);
			fclose(fp);
			/*
			 * Allow patching of the loaded driver parameters.
			 */
			for (unit = 0; unit < 7; unit++)
				if (nsdrive & (1<<unit)) {
					sprintf(cmd,
					  "/etc/hdparms -%c%c %s/sd%dx",
					  (rootflag)?'r':'b',
					  (fut_dev)?'f':'s', dev, unit);
					sys(cmd, S_NONFATAL);
				}
		} else
			printf("Patched driver at /tmp/drv/ss\n");

	} /* end of "ss" stuff */

	/*
	 * Ugly patching stuff specific to "aha154x" driver.
	 * At this point all SCSI id's attached to the host are known.
	 */
	if (aha_dev) {
		/*
		 * Tandy Adaptec BIOS spoofs different head count than
		 * Adaptec's Own Translation Mode.
		 */
		sprintf(ss_patch,
		  "SD_HDS_=%d SDDMA_=%d SDIRQ_=%d SDBASE_=0x%x ",
		  sd_hds, sd_dma, sd_irq, sd_base);
		sys("/bin/cp /drv/aha154x /tmp/drv/aha154x", S_FATAL);
		sprintf(cmd, "/conf/patch /tmp/drv/aha154x %s", ss_patch);
		sys(cmd, S_FATAL);
		if (bflag) {
			if (rootflag) {
				fp = fopen(LDKERFILE, "a");
				fprintf(fp, "HD=aha154x.a\n");
				fprintf(fp, "HDUNDEF=\"-u sdcon_\"\n");
				fprintf(fp, "HDPATCH=\"drvl_+130=sdcon_\"\n");
				fclose(fp);
			}
			sys("/etc/drvld -r /tmp/drv/aha154x", S_FATAL);
			fp = fopen(PATCHFILE, "a");
			fprintf(fp, "/conf/patch /mnt/drv/aha154x %s\n",
			  ss_patch);
			if (rootflag)
				fprintf(fp,
				  "/conf/patch /mnt/coherent %s\n", ss_patch);
			fclose(fp);
		} else
			printf("Patched driver at /tmp/drv/aha154x\n");
	} /* end of "aha154x" stuff */

#if	0
	if (yes_no("Is there another SCSI host adapter in your system"))
		goto again;
#endif
}

void
at()
{
	unsigned char at_patch[80];
	FILE *fp;
	int rootflag = 0;
	int i;

	/* Make /tmp/drv if not there. */
	if ((i = is_dir("/tmp/drv")) == 0)
		sys("/bin/mkdir /tmp/drv", S_FATAL);
	else if (i == -1)
		fatal("/tmp/drv is not a directory");

	cls(0);
	sys("/bin/cp /drv/at /tmp/drv/at", S_FATAL);
	printf(
"Most AT-compatible controllers work with NORMAL polling.\n\n"
"Perstor controllers and some IDE hard drives require ALTERNATE polling.\n\n"
"If you get \"<Watchdog Timeout>\" or \"at0:TO\" errors with normal polling,\n"
"use alternate polling.\n\n");

	if (yes_no("Use ALTERNATE polling"))
		strcpy(at_patch, "ATSREG_=0x1F7 ");
	else
		strcpy(at_patch, "ATSREG_=0x3F6 ");
	sprintf(cmd, "/conf/patch /tmp/drv/at %s", at_patch);
	sys(cmd, S_FATAL);

	if (bflag){
		if (yes_no(
"Will the COHERENT root partition be on an AT-type (non-SCSI) drive")) {
			++rootflag;
			fp = fopen(LDKERFILE, "a");
			fprintf(fp, "HD=at.a\n");
			fprintf(fp, "HDUNDEF=\"-u atcon_\"\n");
			fprintf(fp, "HDPATCH=\"drvl_+110=atcon_\"\n");
			fclose(fp);
		}
		sys("/etc/drvld -r /tmp/drv/at", S_FATAL);
		fp = fopen(PATCHFILE, "a");
		fprintf(fp, "/conf/patch /mnt/drv/at %s\n", at_patch);
		if (rootflag)
			fprintf(fp,
			  "/conf/patch /mnt/coherent %s\n", at_patch);
		fclose(fp);
	} else
		printf("Patched driver at /tmp/drv/at\n");
}
/* end of mkdev.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.