xref: /netbsd-src/sys/arch/hppa/stand/common/dev_hppa.c (revision 1c9d295ac50e01b09df0d79bf02aee4de7cc31dd)
1*1c9d295aSchristos /*	$NetBSD: dev_hppa.c,v 1.2 2014/03/26 17:57:17 christos Exp $	*/
26d3ceb1dSskrll 
36d3ceb1dSskrll /*	$OpenBSD: dev_hppa.c,v 1.5 1999/04/20 20:01:01 mickey Exp $	*/
46d3ceb1dSskrll 
56d3ceb1dSskrll /*
66d3ceb1dSskrll  * Copyright (c) 1998-2004 Michael Shalayeff
76d3ceb1dSskrll  * All rights reserved.
86d3ceb1dSskrll  *
96d3ceb1dSskrll  * Redistribution and use in source and binary forms, with or without
106d3ceb1dSskrll  * modification, are permitted provided that the following conditions
116d3ceb1dSskrll  * are met:
126d3ceb1dSskrll  * 1. Redistributions of source code must retain the above copyright
136d3ceb1dSskrll  *    notice, this list of conditions and the following disclaimer.
146d3ceb1dSskrll  * 2. Redistributions in binary form must reproduce the above copyright
156d3ceb1dSskrll  *    notice, this list of conditions and the following disclaimer in the
166d3ceb1dSskrll  *    documentation and/or other materials provided with the distribution.
176d3ceb1dSskrll  *
186d3ceb1dSskrll  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
196d3ceb1dSskrll  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
206d3ceb1dSskrll  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
216d3ceb1dSskrll  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
226d3ceb1dSskrll  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
236d3ceb1dSskrll  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
246d3ceb1dSskrll  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
256d3ceb1dSskrll  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
266d3ceb1dSskrll  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
276d3ceb1dSskrll  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
286d3ceb1dSskrll  * THE POSSIBILITY OF SUCH DAMAGE.
296d3ceb1dSskrll  *
306d3ceb1dSskrll  */
316d3ceb1dSskrll 
326d3ceb1dSskrll #include "libsa.h"
336d3ceb1dSskrll #include <sys/param.h>
346d3ceb1dSskrll #include <sys/disklabel.h>
356d3ceb1dSskrll #include <sys/reboot.h>
366d3ceb1dSskrll #include <dev/cons.h>
376d3ceb1dSskrll 
386d3ceb1dSskrll #include <machine/iomod.h>
396d3ceb1dSskrll 
406d3ceb1dSskrll #include "dev_hppa.h"
416d3ceb1dSskrll 
426d3ceb1dSskrll extern int debug;
436d3ceb1dSskrll 
446d3ceb1dSskrll const char cdevs[][4] = {
456d3ceb1dSskrll 	"ite", "", "", "", "", "", "", "",
466d3ceb1dSskrll 	"", "", "", "", ""
476d3ceb1dSskrll };
486d3ceb1dSskrll const int ncdevs = NENTS(cdevs);
496d3ceb1dSskrll 
506d3ceb1dSskrll const struct pdc_devs {
516d3ceb1dSskrll 	char	name[3];
526d3ceb1dSskrll 	int	dev_type;
536d3ceb1dSskrll } pdc_devs[] = {
546d3ceb1dSskrll 	{ "dk",  0 },
556d3ceb1dSskrll 	{ "ct",  1 },
566d3ceb1dSskrll 	{ "lf",  2 },
576d3ceb1dSskrll 	{ "",   -1 },
586d3ceb1dSskrll 	{ "rd", -1 },
596d3ceb1dSskrll 	{ "sw", -1 },
606d3ceb1dSskrll 	{ "fl", -1 },
616d3ceb1dSskrll };
626d3ceb1dSskrll 
636d3ceb1dSskrll /* pass dev_t to the open routines */
646d3ceb1dSskrll int
devopen(struct open_file * f,const char * fname,char ** file)656d3ceb1dSskrll devopen(struct open_file *f, const char *fname, char **file)
666d3ceb1dSskrll {
676d3ceb1dSskrll 	struct hppa_dev *hpd;
686d3ceb1dSskrll 	const struct pdc_devs *dp = pdc_devs;
696d3ceb1dSskrll 	int bdev, badapt, bctlr, bunit, bpart;
706d3ceb1dSskrll 	unsigned long n;
716d3ceb1dSskrll 	char *p;
726d3ceb1dSskrll 	int rc = 1;
736d3ceb1dSskrll 
746d3ceb1dSskrll 	if (!(*file = strchr(fname, ':')))
756d3ceb1dSskrll 		return ENODEV;
766d3ceb1dSskrll 	else
776d3ceb1dSskrll 		(*file)++;
786d3ceb1dSskrll 
796d3ceb1dSskrll #ifdef DEBUGBUG
806d3ceb1dSskrll 	if (debug)
816d3ceb1dSskrll 		printf("devopen: ");
826d3ceb1dSskrll #endif
836d3ceb1dSskrll 
846d3ceb1dSskrll 	for (dp = pdc_devs; dp < &pdc_devs[NENTS(pdc_devs)]; dp++)
856d3ceb1dSskrll 		if (!strncmp(fname, dp->name, sizeof(dp->name)-1))
866d3ceb1dSskrll 			break;
876d3ceb1dSskrll 
886d3ceb1dSskrll 	if (dp >= &pdc_devs[NENTS(pdc_devs)] || dp->dev_type < 0)
896d3ceb1dSskrll 		return ENODEV;
906d3ceb1dSskrll 	bdev = dp->dev_type;
916d3ceb1dSskrll 	n = strtoul(fname + sizeof(dp->name)-1, &p, 10);
926d3ceb1dSskrll 	if (n == ULONG_MAX)
936d3ceb1dSskrll 		return ENODEV;
946d3ceb1dSskrll 	bunit = n & 0xf;
956d3ceb1dSskrll 	bctlr = (n >> 4) & 0xf;
966d3ceb1dSskrll 	badapt = (n >> 8) & 0xf;
976d3ceb1dSskrll 	if (*p >= 'a' && *p < 'a' + MAXPARTITIONS) {
986d3ceb1dSskrll 	        bpart = *p - 'a';
996d3ceb1dSskrll 	} else {
1006d3ceb1dSskrll 		bpart = 0;
1016d3ceb1dSskrll 	}
1026d3ceb1dSskrll 	bootdev = MAKEBOOTDEV(bdev, badapt, bctlr, bunit, bpart);
1036d3ceb1dSskrll 
1046d3ceb1dSskrll #ifdef DEBUGBUG
1056d3ceb1dSskrll 	if (debug)
1066d3ceb1dSskrll 		printf("%s\n", dp->name);
1076d3ceb1dSskrll #endif
1086d3ceb1dSskrll 
1096d3ceb1dSskrll 	if (!(hpd = alloc(sizeof *hpd))) {
1106d3ceb1dSskrll #ifdef DEBUG
1116d3ceb1dSskrll 		printf ("devopen: no mem\n");
1126d3ceb1dSskrll #endif
1136d3ceb1dSskrll 	} else {
1146d3ceb1dSskrll 		memset(hpd, 0, sizeof *hpd);
1156d3ceb1dSskrll 		hpd->bootdev = bootdev;
1166d3ceb1dSskrll 		hpd->buf = (char *)(((u_int)hpd->ua_buf + IODC_MINIOSIZ-1) &
1176d3ceb1dSskrll 			~(IODC_MINIOSIZ-1));
1186d3ceb1dSskrll 		f->f_devdata = hpd;
1196d3ceb1dSskrll 		if ((rc = (*devsw[dp->dev_type].dv_open)(f, file)) == 0) {
1206d3ceb1dSskrll 			f->f_dev = &devsw[dp->dev_type];
1216d3ceb1dSskrll 			return 0;
1226d3ceb1dSskrll 		}
1236d3ceb1dSskrll 		dealloc (hpd, 0);
1246d3ceb1dSskrll 		f->f_devdata = NULL;
1256d3ceb1dSskrll 	}
1266d3ceb1dSskrll 
1276d3ceb1dSskrll 	if (!(f->f_flags & F_NODEV))
1286d3ceb1dSskrll 		f->f_dev = &devsw[dp->dev_type];
1296d3ceb1dSskrll 
1306d3ceb1dSskrll 	if (!f->f_devdata)
1316d3ceb1dSskrll 		*file = NULL;
1326d3ceb1dSskrll 
1336d3ceb1dSskrll 	return rc;
1346d3ceb1dSskrll }
1356d3ceb1dSskrll 
1366d3ceb1dSskrll void
devboot(btdev_t dev,char * p)1376d3ceb1dSskrll devboot(btdev_t dev, char *p)
1386d3ceb1dSskrll {
1396d3ceb1dSskrll 	const char *q;
1406d3ceb1dSskrll 	if (!dev) {
1416d3ceb1dSskrll 		int type, unit;
1426d3ceb1dSskrll 
1436d3ceb1dSskrll 		switch (PAGE0->mem_boot.pz_class) {
1446d3ceb1dSskrll 		case PCL_RANDOM:
1456d3ceb1dSskrll 			type = 0;
1466d3ceb1dSskrll 			unit = PAGE0->mem_boot.pz_layers[0];
1476d3ceb1dSskrll 			break;
1486d3ceb1dSskrll 		case PCL_SEQU:
1496d3ceb1dSskrll 			type = 1;
1506d3ceb1dSskrll 			unit = PAGE0->mem_boot.pz_layers[0];
1516d3ceb1dSskrll 			break;
1526d3ceb1dSskrll 		case PCL_NET_MASK|PCL_SEQU:
1536d3ceb1dSskrll 			type = 2;
1546d3ceb1dSskrll 			unit = 0;
1556d3ceb1dSskrll 			break;
1566d3ceb1dSskrll 		default:
1576d3ceb1dSskrll 			type = 0;
1586d3ceb1dSskrll 			unit = 0;
1596d3ceb1dSskrll 			break;
1606d3ceb1dSskrll 		}
1616d3ceb1dSskrll 		dev = bootdev = MAKEBOOTDEV(type, 0, 0, unit, 0);
1626d3ceb1dSskrll 	}
1636d3ceb1dSskrll #ifdef _TEST
1646d3ceb1dSskrll 	*p++ = '/';
1656d3ceb1dSskrll 	*p++ = 'd';
1666d3ceb1dSskrll 	*p++ = 'e';
1676d3ceb1dSskrll 	*p++ = 'v';
1686d3ceb1dSskrll 	*p++ = '/';
1696d3ceb1dSskrll 	*p++ = 'r';
1706d3ceb1dSskrll #endif
1716d3ceb1dSskrll 	/* quick copy device name */
1726d3ceb1dSskrll 	for (q = pdc_devs[B_TYPE(dev)].name; (*p++ = *q++););
1736d3ceb1dSskrll 	p[-1] = '0' + B_UNIT(dev);
1746d3ceb1dSskrll 	*p++ = 'a' + B_PARTITION(dev);
1756d3ceb1dSskrll 	*p = '\0';
1766d3ceb1dSskrll }
1776d3ceb1dSskrll 
1786d3ceb1dSskrll int pch_pos;
1796d3ceb1dSskrll 
1806d3ceb1dSskrll void
putchar(int c)1816d3ceb1dSskrll putchar(int c)
1826d3ceb1dSskrll {
1836d3ceb1dSskrll 	switch(c) {
1846d3ceb1dSskrll 	case '\177':	/* DEL erases */
1856d3ceb1dSskrll 		cnputc('\b');
1866d3ceb1dSskrll 		cnputc(' ');
1876d3ceb1dSskrll 	case '\b':
1886d3ceb1dSskrll 		cnputc('\b');
1896d3ceb1dSskrll 		if (pch_pos)
1906d3ceb1dSskrll 			pch_pos--;
1916d3ceb1dSskrll 		break;
1926d3ceb1dSskrll 	case '\t':
1936d3ceb1dSskrll 		do
1946d3ceb1dSskrll 			cnputc(' ');
1956d3ceb1dSskrll 		while(++pch_pos % 8);
1966d3ceb1dSskrll 		break;
1976d3ceb1dSskrll 	case '\n':
1986d3ceb1dSskrll 		/*
1996d3ceb1dSskrll 		* XXX fredette - probably only necessary
2006d3ceb1dSskrll 		* when using a serial console?
2016d3ceb1dSskrll 		*/
2026d3ceb1dSskrll 		cnputc(c);
2036d3ceb1dSskrll 		c = '\r';
2046d3ceb1dSskrll 		/* FALLTHROUGH */
2056d3ceb1dSskrll 	case '\r':
2066d3ceb1dSskrll 		cnputc(c);
2076d3ceb1dSskrll 		pch_pos=0;
2086d3ceb1dSskrll 		break;
2096d3ceb1dSskrll 	default:
2106d3ceb1dSskrll 		cnputc(c);
2116d3ceb1dSskrll 		pch_pos++;
2126d3ceb1dSskrll 		break;
2136d3ceb1dSskrll 	}
2146d3ceb1dSskrll }
2156d3ceb1dSskrll 
2166d3ceb1dSskrll int
getchar(void)2176d3ceb1dSskrll getchar(void)
2186d3ceb1dSskrll {
2196d3ceb1dSskrll 	int c = cngetc();
2206d3ceb1dSskrll 
2216d3ceb1dSskrll 	if (c == '\r')
2226d3ceb1dSskrll 		c = '\n';
2236d3ceb1dSskrll 
2246d3ceb1dSskrll 	if ((c < ' ' && c != '\n') || c == '\177')
2256d3ceb1dSskrll 		return(c);
2266d3ceb1dSskrll 
2276d3ceb1dSskrll 	/*
2286d3ceb1dSskrll 	 * XXX fredette - probably only unnecessary
2296d3ceb1dSskrll 	 * when using a serial console?
2306d3ceb1dSskrll 	 */
2316d3ceb1dSskrll #if 0
2326d3ceb1dSskrll 	putchar(c);
2336d3ceb1dSskrll #endif
2346d3ceb1dSskrll 
2356d3ceb1dSskrll 	return(c);
2366d3ceb1dSskrll }
2376d3ceb1dSskrll 
2386d3ceb1dSskrll int
tgetchar(void)2396d3ceb1dSskrll tgetchar(void)
2406d3ceb1dSskrll {
2416d3ceb1dSskrll 	int c;
2426d3ceb1dSskrll 
2436d3ceb1dSskrll 	if ((c = tcngetc()) == 0)
2446d3ceb1dSskrll 		return(0);
2456d3ceb1dSskrll 	return(getchar());
2466d3ceb1dSskrll }
2476d3ceb1dSskrll 
2486d3ceb1dSskrll #if 0
2496d3ceb1dSskrll char ttyname_buf[8];
2506d3ceb1dSskrll char *
2516d3ceb1dSskrll ttyname(int fd)
2526d3ceb1dSskrll {
253*1c9d295aSchristos 	snprintf(ttyname_buf, sizeof(ttyname_buf), "%s%d",
254*1c9d295aSchristos 	    cdevs[major(cn_tab->cn_dev)],
2556d3ceb1dSskrll 	    minor(cn_tab->cn_dev));
2566d3ceb1dSskrll 	return (ttyname_buf);
2576d3ceb1dSskrll }
2586d3ceb1dSskrll 
2596d3ceb1dSskrll dev_t
2606d3ceb1dSskrll ttydev(char *name)
2616d3ceb1dSskrll {
2626d3ceb1dSskrll 	int i, unit = -1;
2636d3ceb1dSskrll 	char *no = name + strlen(name) - 1;
2646d3ceb1dSskrll 
2656d3ceb1dSskrll 	while (no >= name && *no >= '0' && *no <= '9')
2666d3ceb1dSskrll 		unit = (unit < 0 ? 0 : (unit * 10)) + *no-- - '0';
2676d3ceb1dSskrll 	if (no < name || unit < 0)
2686d3ceb1dSskrll 		return (NODEV);
2696d3ceb1dSskrll 	for (i = 0; i < ncdevs; i++)
2706d3ceb1dSskrll 		if (strncmp(name, cdevs[i], no - name + 1) == 0)
2716d3ceb1dSskrll 			return (makedev(i, unit));
2726d3ceb1dSskrll 	return (NODEV);
2736d3ceb1dSskrll }
2746d3ceb1dSskrll #endif
275