1/*	$OpenBSD: dev_hppa.c,v 1.18 2024/04/14 03:26:25 jsg Exp $	*/
2
3/*
4 * Copyright (c) 1998-2004 Michael Shalayeff
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "libsa.h"
30#include <sys/param.h>
31#include <sys/disklabel.h>
32#include <sys/reboot.h>
33#include <dev/cons.h>
34
35#include <machine/iomod.h>
36
37#include "dev_hppa.h"
38
39extern int debug;
40
41const char cdevs[][4] = {
42	"ite", "", "", "", "", "", "", "",
43	"", "", "", "", ""
44};
45const int ncdevs = nitems(cdevs);
46
47const struct pdc_devs {
48	char	name[3];
49	int	dev_type;
50} pdc_devs[] = {
51	{ "dk",  0 },
52	{ "ct",  1 },
53	{ "lf",  2 },
54	{ "",   -1 },
55	{ "rd", -1 },
56	{ "sw", -1 },
57	{ "fl", -1 },
58};
59
60/* pass dev_t to the open routines */
61int
62devopen(f, fname, file)
63	struct open_file *f;
64	const char *fname;
65	char **file;
66{
67	struct hppa_dev *hpd;
68	const struct pdc_devs *dp = pdc_devs;
69	int rc = 1;
70
71	if (!(*file = strchr(fname, ':')))
72		return ENODEV;
73	else
74		(*file)++;
75
76#ifdef DEBUG
77	if (debug)
78		printf("devopen: ");
79#endif
80
81	for (dp = pdc_devs; dp < &pdc_devs[nitems(pdc_devs)]; dp++)
82		if (!strncmp(fname, dp->name, sizeof(dp->name)-1))
83			break;
84
85	if (dp >= &pdc_devs[nitems(pdc_devs)] || dp->dev_type < 0)
86		return ENODEV;
87#ifdef DEBUG
88	if (debug)
89		printf("%s\n", dp->name);
90#endif
91
92	if (!(hpd = alloc(sizeof *hpd))) {
93#ifdef DEBUG
94		printf ("devopen: no mem\n");
95#endif
96	} else {
97		bzero(hpd, sizeof *hpd);
98		hpd->bootdev = bootdev;
99		hpd->buf = (char *)(((u_int)hpd->ua_buf + IODC_MINIOSIZ-1) &
100			~(IODC_MINIOSIZ-1));
101		f->f_devdata = hpd;
102		if ((rc = (*devsw[dp->dev_type].dv_open)(f, file)) == 0) {
103			f->f_dev = &devsw[dp->dev_type];
104			return 0;
105		}
106		free (hpd, 0);
107		f->f_devdata = NULL;
108	}
109
110	if (!(f->f_flags & F_NODEV))
111		f->f_dev = &devsw[dp->dev_type];
112
113	if (!f->f_devdata)
114		*file = NULL;
115
116	return rc;
117}
118
119void
120devboot(dev, p)
121	dev_t dev;
122	char *p;
123{
124	const char *q;
125	int unit;
126
127	if (!dev) {
128		int type;
129
130		switch (PAGE0->mem_boot.pz_class) {
131		case PCL_RANDOM:
132			type = 0;
133			unit = PAGE0->mem_boot.pz_layers[0];
134			break;
135		case PCL_SEQU:
136			type = 1;
137			unit = PAGE0->mem_boot.pz_layers[0];
138			break;
139		case PCL_NET_MASK|PCL_SEQU:
140			type = 2;
141			unit = 0;
142			break;
143		default:
144			type = 0;
145			unit = 0;
146			break;
147		}
148		dev = bootdev = MAKEBOOTDEV(type, 0, 0, unit, B_PARTITION(dev));
149	}
150#ifdef _TEST
151	*p++ = '/';
152	*p++ = 'd';
153	*p++ = 'e';
154	*p++ = 'v';
155	*p++ = '/';
156	*p++ = 'r';
157#endif
158	/* quick copy device name */
159	for (q = pdc_devs[B_TYPE(dev)].name; (*p++ = *q++);)
160		;
161	unit = B_UNIT(dev);
162	if (unit >= 10) {
163		p[-1] = '0' + unit / 10;
164		*p++ = '0' + (unit % 10);
165	} else
166		p[-1] = '0' + unit;
167	*p++ = 'a' + B_PARTITION(dev);
168	*p = '\0';
169}
170
171char ttyname_buf[8];
172
173char *
174ttyname(fd)
175	int fd;
176{
177	snprintf(ttyname_buf, sizeof ttyname_buf, "%s%d",
178	    cdevs[major(cn_tab->cn_dev)],
179	    minor(cn_tab->cn_dev));
180	return (ttyname_buf);
181}
182
183dev_t
184ttydev(name)
185	char *name;
186{
187	int i, unit = -1;
188	char *no = name + strlen(name) - 1;
189
190	while (no >= name && *no >= '0' && *no <= '9')
191		unit = (unit < 0 ? 0 : (unit * 10)) + *no-- - '0';
192	if (no < name || unit < 0)
193		return (NODEV);
194	for (i = 0; i < ncdevs; i++)
195		if (strncmp(name, cdevs[i], no - name + 1) == 0)
196			return (makedev(i, unit));
197	return (NODEV);
198}
199