1 /* $NetBSD: autoconf.c,v 1.74 2012/10/27 17:17:59 chs Exp $ */
2
3 /*
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
10 *
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratory.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * @(#)autoconf.c 8.4 (Berkeley) 10/1/93
41 */
42
43 /*
44 * Setup the system to run on the current machine.
45 *
46 * Configure() is called at boot time. Available
47 * devices are determined (from possibilities mentioned in ioconf.c),
48 * and the drivers are initialized.
49 */
50
51 #include <sys/cdefs.h>
52 __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.74 2012/10/27 17:17:59 chs Exp $");
53
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/buf.h>
57 #include <sys/disklabel.h>
58 #include <sys/conf.h>
59 #include <sys/reboot.h>
60 #include <sys/device.h>
61 #include <sys/disk.h>
62
63 #include <dev/cons.h>
64
65 #include <machine/autoconf.h>
66 #include <machine/viareg.h>
67
68 #include <dev/scsipi/scsi_all.h>
69 #include <dev/scsipi/scsipi_all.h>
70 #include <dev/scsipi/scsiconf.h>
71
72 #include "scsibus.h"
73
74 static void findbootdev(void);
75 #if NSCSIBUS > 0
76 static int target_to_unit(u_long, u_long, u_long);
77 #endif /* NSCSIBUS > 0 */
78
79 /*
80 * cpu_configure:
81 * called at boot time, configure all devices on the system
82 */
83 void
cpu_configure(void)84 cpu_configure(void)
85 {
86
87 mrg_init(); /* Init Mac ROM Glue */
88 startrtclock(); /* start before ADB attached */
89
90 if (config_rootfound("mainbus", NULL) == NULL)
91 panic("No mainbus found!");
92
93 (void)spl0();
94 }
95
96 void
cpu_rootconf(void)97 cpu_rootconf(void)
98 {
99
100 findbootdev();
101
102 printf("boot device: %s\n",
103 booted_device ? device_xname(booted_device) : "<unknown>");
104
105 rootconf();
106 }
107
108 /*
109 * Yanked from i386/i386/autoconf.c (and tweaked a bit)
110 */
111
112 u_long bootdev;
113
114 static void
findbootdev(void)115 findbootdev(void)
116 {
117 device_t dv;
118 int major, unit, controller;
119 const char *name;
120
121 booted_device = NULL;
122 booted_partition = 0; /* Assume root is on partition a */
123
124 major = B_TYPE(bootdev);
125 name = devsw_blk2name(major);
126 if (name == NULL)
127 return;
128
129 unit = B_UNIT(bootdev);
130
131 switch (major) {
132 case 4: /* SCSI drive */
133 #if NSCSIBUS > 0
134 bootdev &= ~(B_UNITMASK << B_UNITSHIFT); /* XXX */
135 unit = target_to_unit(-1, unit, 0);
136 bootdev |= (unit << B_UNITSHIFT); /* XXX */
137 #else /* NSCSIBUS > 0 */
138 panic("Boot device is on a SCSI drive but SCSI support "
139 "is not present");
140 #endif /* NSCSIBUS > 0 */
141 break;
142 case 22: /* IDE drive */
143 /*
144 * controller(=channel=buses) uses only IDE drive.
145 * Here, controller always is 0.
146 */
147 controller = B_CONTROLLER(bootdev);
148 unit = unit + (controller<<1);
149 break;
150 }
151
152 if ((dv = device_find_by_driver_unit(name, unit)) != NULL)
153 booted_device = dv;
154 }
155
156 /*
157 * Map a SCSI bus, target, lun to a device number.
158 * This could be tape, disk, CD. The calling routine, though,
159 * assumes DISK. It would be nice to allow CD, too...
160 */
161 #if NSCSIBUS > 0
162 static int
target_to_unit(u_long bus,u_long target,u_long lun)163 target_to_unit(u_long bus, u_long target, u_long lun)
164 {
165 struct scsibus_softc *scsi;
166 struct scsipi_periph *periph;
167 extern struct cfdriver scsibus_cd;
168
169 if (target < 0 || target > 7 || lun < 0 || lun > 7) {
170 printf("scsi target to unit, target (%ld) or lun (%ld)"
171 " out of range.\n", target, lun);
172 return -1;
173 }
174
175 if (bus == -1) {
176 for (bus = 0 ; bus < scsibus_cd.cd_ndevs ; bus++) {
177 scsi = device_lookup_private(&scsibus_cd, bus);
178 if (!scsi)
179 continue;
180 periph = scsipi_lookup_periph(scsi->sc_channel,
181 target, lun);
182 if (!periph)
183 continue;
184 return device_unit(periph->periph_dev);
185 }
186 return -1;
187 }
188 if (bus < 0 || bus >= scsibus_cd.cd_ndevs) {
189 printf("scsi target to unit, bus (%ld) out of range.\n", bus);
190 return -1;
191 }
192 scsi = device_lookup_private(&scsibus_cd, bus);
193 if (!scsi)
194 return -1;
195
196 periph = scsipi_lookup_periph(scsi->sc_channel,
197 target, lun);
198 if (!periph)
199 return -1;
200 return device_unit(periph->periph_dev);
201 }
202 #endif /* NSCSIBUS > 0 */
203