1/*	$NetBSD: devopen.c,v 1.10 2019/12/10 02:02:47 manu Exp $	 */
2
3/*-
4 * Copyright (c) 2005 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Bang Jun-Young.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * Copyright (c) 1996, 1997
34 *	Matthias Drochner.  All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 *    notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 *    notice, this list of conditions and the following disclaimer in the
43 *    documentation and/or other materials provided with the distribution.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
48 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
51 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
52 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
54 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 */
56
57
58#include <sys/types.h>
59
60#include <lib/libsa/stand.h>
61#include <lib/libkern/libkern.h>
62
63#include <libi386.h>
64#include <biosdisk.h>
65#include "devopen.h"
66#ifdef _STANDALONE
67#include <bootinfo.h>
68#endif
69#ifdef SUPPORT_PS2
70#include <biosmca.h>
71#endif
72
73static int dev2bios(char *, int, int *);
74
75static int
76dev2bios(char *devname, int unit, int *biosdev)
77{
78
79	if (strcmp(devname, "hd") == 0)
80		*biosdev = 0x80 + unit;
81	else if (strcmp(devname, "fd") == 0)
82		*biosdev = 0x00 + unit;
83	else if (strcmp(devname, "cd") == 0)
84		*biosdev = boot_biosdev;
85	else
86		return ENXIO;
87
88	return 0;
89}
90
91void
92bios2dev(int biosdev, daddr_t sector, char **devname, int *unit,
93	 int *partition, const char **part_name)
94{
95
96	/* set default */
97	*unit = biosdev & 0x7f;
98
99	if (biosdev & 0x80) {
100		/*
101		 * There seems to be no standard way of numbering BIOS
102		 * CD-ROM drives. The following method is a little tricky
103		 * but works nicely.
104		 */
105		if (biosdev >= 0x80 + get_harddrives()) {
106			*devname = "cd";
107			*unit = 0;		/* override default */
108		} else
109			*devname = "hd";
110	} else
111		*devname = "fd";
112
113	(void)biosdisk_findpartition(biosdev, sector, partition, part_name);
114}
115
116#ifdef _STANDALONE
117struct btinfo_bootpath bibp;
118extern bool kernel_loaded;
119#endif
120
121/*
122 * Open the BIOS disk device
123 */
124int
125devopen(struct open_file *f, const char *fname, char **file)
126{
127	char *fsname, *devname;
128	int unit, partition;
129	int biosdev;
130	int error;
131
132	error = parsebootfile(fname, &fsname, &devname,
133			      &unit, &partition, (const char **) file);
134	if (error)
135		return error;
136
137	f->f_dev = &devsw[0];		/* must be biosdisk */
138
139#ifdef _STANDALONE
140	if (!kernel_loaded) {
141		strncpy(bibp.bootpath, *file, sizeof(bibp.bootpath));
142		BI_ADD(&bibp, BTINFO_BOOTPATH, sizeof(bibp));
143	}
144#endif
145
146#ifndef NO_GPT
147	/* Search by GPT label name */
148	if (strstr(devname, "NAME=") == devname) {
149		f->f_dev = &devsw[0];		/* must be biosdisk */
150
151		return biosdisk_open_name(f, devname);
152	}
153#endif
154#ifndef NO_RAIDFRAME
155	/* Search by raidframe name */
156	if (strstr(devname, "raid") == devname) {
157		f->f_dev = &devsw[0];		/* must be biosdisk */
158
159		return biosdisk_open_name(f, fname);
160	}
161#endif
162
163	error = dev2bios(devname, unit, &biosdev);
164	if (error)
165		return error;
166
167	return biosdisk_open(f, biosdev, partition);
168}
169