Home | History | Annotate | Line # | Download | only in boot
autoconf.c revision 1.2
      1  1.2  tsutsui /*	$NetBSD: autoconf.c,v 1.2 2013/01/12 13:39:47 tsutsui Exp $	*/
      2  1.1  tsutsui 
      3  1.1  tsutsui /*
      4  1.1  tsutsui  * Copyright (c) 1992 OMRON Corporation.
      5  1.1  tsutsui  *
      6  1.1  tsutsui  * This code is derived from software contributed to Berkeley by
      7  1.1  tsutsui  * OMRON Corporation.
      8  1.1  tsutsui  *
      9  1.1  tsutsui  * Redistribution and use in source and binary forms, with or without
     10  1.1  tsutsui  * modification, are permitted provided that the following conditions
     11  1.1  tsutsui  * are met:
     12  1.1  tsutsui  * 1. Redistributions of source code must retain the above copyright
     13  1.1  tsutsui  *    notice, this list of conditions and the following disclaimer.
     14  1.1  tsutsui  * 2. Redistributions in binary form must reproduce the above copyright
     15  1.1  tsutsui  *    notice, this list of conditions and the following disclaimer in the
     16  1.1  tsutsui  *    documentation and/or other materials provided with the distribution.
     17  1.1  tsutsui  * 3. All advertising materials mentioning features or use of this software
     18  1.1  tsutsui  *    must display the following acknowledgement:
     19  1.1  tsutsui  *	This product includes software developed by the University of
     20  1.1  tsutsui  *	California, Berkeley and its contributors.
     21  1.1  tsutsui  * 4. Neither the name of the University nor the names of its contributors
     22  1.1  tsutsui  *    may be used to endorse or promote products derived from this software
     23  1.1  tsutsui  *    without specific prior written permission.
     24  1.1  tsutsui  *
     25  1.1  tsutsui  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     26  1.1  tsutsui  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     27  1.1  tsutsui  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     28  1.1  tsutsui  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     29  1.1  tsutsui  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     30  1.1  tsutsui  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     31  1.1  tsutsui  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32  1.1  tsutsui  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33  1.1  tsutsui  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     34  1.1  tsutsui  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35  1.1  tsutsui  * SUCH DAMAGE.
     36  1.1  tsutsui  *
     37  1.1  tsutsui  *	@(#)autoconf.c	8.1 (Berkeley) 6/10/93
     38  1.1  tsutsui  */
     39  1.1  tsutsui /*
     40  1.1  tsutsui  * Copyright (c) 1992, 1993
     41  1.1  tsutsui  *	The Regents of the University of California.  All rights reserved.
     42  1.1  tsutsui  *
     43  1.1  tsutsui  * This code is derived from software contributed to Berkeley by
     44  1.1  tsutsui  * OMRON Corporation.
     45  1.1  tsutsui  *
     46  1.1  tsutsui  * Redistribution and use in source and binary forms, with or without
     47  1.1  tsutsui  * modification, are permitted provided that the following conditions
     48  1.1  tsutsui  * are met:
     49  1.1  tsutsui  * 1. Redistributions of source code must retain the above copyright
     50  1.1  tsutsui  *    notice, this list of conditions and the following disclaimer.
     51  1.1  tsutsui  * 2. Redistributions in binary form must reproduce the above copyright
     52  1.1  tsutsui  *    notice, this list of conditions and the following disclaimer in the
     53  1.1  tsutsui  *    documentation and/or other materials provided with the distribution.
     54  1.1  tsutsui  * 3. Neither the name of the University nor the names of its contributors
     55  1.1  tsutsui  *    may be used to endorse or promote products derived from this software
     56  1.1  tsutsui  *    without specific prior written permission.
     57  1.1  tsutsui  *
     58  1.1  tsutsui  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     59  1.1  tsutsui  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     60  1.1  tsutsui  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     61  1.1  tsutsui  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     62  1.1  tsutsui  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     63  1.1  tsutsui  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     64  1.1  tsutsui  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     65  1.1  tsutsui  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     66  1.1  tsutsui  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     67  1.1  tsutsui  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     68  1.1  tsutsui  * SUCH DAMAGE.
     69  1.1  tsutsui  *
     70  1.1  tsutsui  *	@(#)autoconf.c	8.1 (Berkeley) 6/10/93
     71  1.1  tsutsui  */
     72  1.1  tsutsui 
     73  1.1  tsutsui /*
     74  1.1  tsutsui  * autoconf.c -- Determine mass storage and memory configuration for a machine.
     75  1.1  tsutsui  *          by A.Fujita, NOV-30-1991
     76  1.1  tsutsui  *
     77  1.1  tsutsui  * Modified by A.Fujita, FEB-04-1992
     78  1.1  tsutsui  */
     79  1.1  tsutsui 
     80  1.1  tsutsui 
     81  1.1  tsutsui #include <sys/param.h>
     82  1.1  tsutsui #include <sys/dkstat.h>
     83  1.1  tsutsui #include <lib/libkern/libkern.h>
     84  1.1  tsutsui #include <luna68k/stand/boot/samachdep.h>
     85  1.1  tsutsui #include <luna68k/stand/boot/device.h>
     86  1.1  tsutsui 
     87  1.1  tsutsui int	dkn;		    /* number of iostat dk numbers assigned so far */
     88  1.1  tsutsui struct	hp_hw sc_table[MAX_CTLR];
     89  1.1  tsutsui 
     90  1.1  tsutsui #ifdef DEBUG
     91  1.1  tsutsui int	acdebug = 1;
     92  1.1  tsutsui #endif
     93  1.1  tsutsui 
     94  1.1  tsutsui static int find_controller(struct hp_hw *);
     95  1.1  tsutsui static int find_device(struct hp_hw *);
     96  1.1  tsutsui static void find_slaves(struct hp_ctlr *);
     97  1.1  tsutsui static int same_hw_device(struct hp_hw *, struct hp_device *);
     98  1.1  tsutsui 
     99  1.1  tsutsui /*
    100  1.1  tsutsui  * Determine mass storage and memory configuration for a machine.
    101  1.1  tsutsui  */
    102  1.1  tsutsui void
    103  1.1  tsutsui configure(void)
    104  1.1  tsutsui {
    105  1.1  tsutsui 	struct hp_hw *hw;
    106  1.1  tsutsui 	int found;
    107  1.1  tsutsui 
    108  1.1  tsutsui 	/*
    109  1.1  tsutsui 	 * Look over each hardware device actually found and attempt
    110  1.1  tsutsui 	 * to match it with an ioconf.c table entry.
    111  1.1  tsutsui 	 */
    112  1.1  tsutsui 	for (hw = sc_table; hw->hw_type; hw++) {
    113  1.1  tsutsui 		if (hw->hw_type & CONTROLLER)
    114  1.1  tsutsui 			found = find_controller(hw);
    115  1.1  tsutsui 		else
    116  1.1  tsutsui 			found = find_device(hw);
    117  1.1  tsutsui #ifdef DEBUG
    118  1.1  tsutsui 		if (!found) {
    119  1.1  tsutsui 			printf("unconfigured %s ", hw->hw_name);
    120  1.2  tsutsui 			printf("at 0x%x\n", (u_int)hw->hw_addr);
    121  1.1  tsutsui 		}
    122  1.1  tsutsui #endif
    123  1.1  tsutsui 	}
    124  1.1  tsutsui 
    125  1.1  tsutsui }
    126  1.1  tsutsui 
    127  1.1  tsutsui #define dr_type(d, s)	\
    128  1.1  tsutsui 	(strcmp((d)->d_name, (s)) == 0)
    129  1.1  tsutsui 
    130  1.1  tsutsui #define same_hw_ctlr(hw, hc) \
    131  1.1  tsutsui 	((hw)->hw_type == SCSI && dr_type((hc)->hp_driver, "sc"))
    132  1.1  tsutsui 
    133  1.1  tsutsui int
    134  1.1  tsutsui find_controller(struct hp_hw *hw)
    135  1.1  tsutsui {
    136  1.1  tsutsui 	struct hp_ctlr *hc;
    137  1.1  tsutsui 	struct hp_ctlr *match_c;
    138  1.1  tsutsui 	uint8_t *oaddr;
    139  1.1  tsutsui 	int sc;
    140  1.1  tsutsui 
    141  1.1  tsutsui #ifdef DEBUG
    142  1.1  tsutsui 	if (acdebug)
    143  1.1  tsutsui 		printf("find_controller: hw: %s at sc%d (%x), type %x...",
    144  1.2  tsutsui 		       hw->hw_name, hw->hw_sc, (u_int)hw->hw_addr, hw->hw_type);
    145  1.1  tsutsui #endif
    146  1.1  tsutsui 	sc = hw->hw_sc;
    147  1.1  tsutsui 	match_c = NULL;
    148  1.1  tsutsui 	for (hc = hp_cinit; hc->hp_driver; hc++) {
    149  1.1  tsutsui 		if (hc->hp_alive)
    150  1.1  tsutsui 			continue;
    151  1.1  tsutsui 		/*
    152  1.1  tsutsui 		 * Make sure we are looking at the right
    153  1.1  tsutsui 		 * controller type.
    154  1.1  tsutsui 		 */
    155  1.1  tsutsui 		if (!same_hw_ctlr(hw, hc))
    156  1.1  tsutsui 			continue;
    157  1.1  tsutsui 		/*
    158  1.1  tsutsui 		 * Exact match; all done
    159  1.1  tsutsui 		 */
    160  1.1  tsutsui 		if ((int)hc->hp_addr == sc) {
    161  1.1  tsutsui 			match_c = hc;
    162  1.1  tsutsui 			break;
    163  1.1  tsutsui 		}
    164  1.1  tsutsui 		/*
    165  1.1  tsutsui 		 * Wildcard; possible match so remember first instance
    166  1.1  tsutsui 		 * but continue looking for exact match.
    167  1.1  tsutsui 		 */
    168  1.1  tsutsui 		if ((int)hc->hp_addr == WILD_CARD_CTLR && match_c == NULL)
    169  1.1  tsutsui 			match_c = hc;
    170  1.1  tsutsui 	}
    171  1.1  tsutsui #ifdef DEBUG
    172  1.1  tsutsui 	if (acdebug) {
    173  1.1  tsutsui 		if (match_c)
    174  1.1  tsutsui 			printf("found %s%d\n",
    175  1.1  tsutsui 			       match_c->hp_driver->d_name,
    176  1.1  tsutsui 			       match_c->hp_unit);
    177  1.1  tsutsui 		else
    178  1.1  tsutsui 			printf("not found\n");
    179  1.1  tsutsui 	}
    180  1.1  tsutsui #endif
    181  1.1  tsutsui 	/*
    182  1.1  tsutsui 	 * Didn't find an ioconf entry for this piece of hardware,
    183  1.1  tsutsui 	 * just ignore it.
    184  1.1  tsutsui 	 */
    185  1.1  tsutsui 	if (match_c == NULL)
    186  1.1  tsutsui 		return(0);
    187  1.1  tsutsui 	/*
    188  1.1  tsutsui 	 * Found a match, attempt to initialize and configure all attached
    189  1.1  tsutsui 	 * slaves.  Note, we can still fail if HW won't initialize.
    190  1.1  tsutsui 	 */
    191  1.1  tsutsui 	hc = match_c;
    192  1.1  tsutsui 	oaddr = hc->hp_addr;
    193  1.1  tsutsui 	hc->hp_addr = hw->hw_addr;
    194  1.1  tsutsui 	if ((*hc->hp_driver->d_init)(hc)) {
    195  1.1  tsutsui 		hc->hp_alive = 1;
    196  1.1  tsutsui 		printf("%s%d", hc->hp_driver->d_name, hc->hp_unit);
    197  1.1  tsutsui 		printf(" at %p,", hc->hp_addr);
    198  1.1  tsutsui 		printf(" ipl %d", hc->hp_ipl);
    199  1.1  tsutsui 		if (hc->hp_flags)
    200  1.1  tsutsui 			printf(" flags 0x%x", hc->hp_flags);
    201  1.1  tsutsui 		printf("\n");
    202  1.1  tsutsui 		find_slaves(hc);
    203  1.1  tsutsui 	} else
    204  1.1  tsutsui 		hc->hp_addr = oaddr;
    205  1.1  tsutsui 	return(1);
    206  1.1  tsutsui }
    207  1.1  tsutsui 
    208  1.1  tsutsui int
    209  1.1  tsutsui find_device(struct hp_hw *hw)
    210  1.1  tsutsui {
    211  1.1  tsutsui 	struct hp_device *hd;
    212  1.1  tsutsui 	struct hp_device *match_d;
    213  1.1  tsutsui 	uint8_t *oaddr;
    214  1.1  tsutsui 	int sc;
    215  1.1  tsutsui 
    216  1.1  tsutsui #ifdef DEBUG
    217  1.1  tsutsui 	if (acdebug)
    218  1.1  tsutsui 		printf("find_device: hw: %s at sc%d (%x), type %x...",
    219  1.2  tsutsui 		       hw->hw_name, hw->hw_sc, (u_int)hw->hw_addr, hw->hw_type);
    220  1.1  tsutsui #endif
    221  1.1  tsutsui 	match_d = NULL;
    222  1.1  tsutsui 	for (hd = hp_dinit; hd->hp_driver; hd++) {
    223  1.1  tsutsui 		if (hd->hp_alive)
    224  1.1  tsutsui 			continue;
    225  1.1  tsutsui 		/* Must not be a slave */
    226  1.1  tsutsui 		if (hd->hp_cdriver)
    227  1.1  tsutsui 			continue;
    228  1.1  tsutsui 		sc = (int) hd->hp_addr;
    229  1.1  tsutsui 		/*
    230  1.1  tsutsui 		 * Exact match; all done.
    231  1.1  tsutsui 		 */
    232  1.1  tsutsui 		if (sc > 0 && sc == hw->hw_sc) {
    233  1.1  tsutsui 			match_d = hd;
    234  1.1  tsutsui 			break;
    235  1.1  tsutsui 		}
    236  1.1  tsutsui 		/*
    237  1.1  tsutsui 		 * Wildcard; possible match so remember first instance
    238  1.1  tsutsui 		 * but continue looking for exact match.
    239  1.1  tsutsui 		 */
    240  1.1  tsutsui 		if (sc == 0 && same_hw_device(hw, hd) && match_d == NULL)
    241  1.1  tsutsui 			match_d = hd;
    242  1.1  tsutsui 	}
    243  1.1  tsutsui #ifdef DEBUG
    244  1.1  tsutsui 	if (acdebug) {
    245  1.1  tsutsui 		if (match_d)
    246  1.1  tsutsui 			printf("found %s%d\n",
    247  1.1  tsutsui 			       match_d->hp_driver->d_name,
    248  1.1  tsutsui 			       match_d->hp_unit);
    249  1.1  tsutsui 		else
    250  1.1  tsutsui 			printf("not found\n");
    251  1.1  tsutsui 	}
    252  1.1  tsutsui #endif
    253  1.1  tsutsui 	/*
    254  1.1  tsutsui 	 * Didn't find an ioconf entry for this piece
    255  1.1  tsutsui 	 * of hardware, just ignore it.
    256  1.1  tsutsui 	 */
    257  1.1  tsutsui 	if (match_d == NULL)
    258  1.1  tsutsui 		return(0);
    259  1.1  tsutsui 	/*
    260  1.1  tsutsui 	 * Found a match, attempt to initialize.
    261  1.1  tsutsui 	 * Note, we can still fail if HW won't initialize.
    262  1.1  tsutsui 	 */
    263  1.1  tsutsui 	hd = match_d;
    264  1.1  tsutsui 	oaddr = hd->hp_addr;
    265  1.1  tsutsui 	hd->hp_addr = hw->hw_addr;
    266  1.1  tsutsui 	if ((*hd->hp_driver->d_init)(hd)) {
    267  1.1  tsutsui 		hd->hp_alive = 1;
    268  1.1  tsutsui 		printf("%s%d", hd->hp_driver->d_name, hd->hp_unit);
    269  1.1  tsutsui 		printf(" at %p", hd->hp_addr);
    270  1.1  tsutsui 		if (hd->hp_ipl)
    271  1.1  tsutsui 			printf(", ipl %d", hd->hp_ipl);
    272  1.1  tsutsui 		if (hd->hp_flags)
    273  1.1  tsutsui 			printf(", flags 0x%x", hd->hp_flags);
    274  1.1  tsutsui 		printf("\n");
    275  1.1  tsutsui 	} else
    276  1.1  tsutsui 		hd->hp_addr = oaddr;
    277  1.1  tsutsui 	return(1);
    278  1.1  tsutsui }
    279  1.1  tsutsui 
    280  1.1  tsutsui /*
    281  1.1  tsutsui  * Search each BUS controller found for slaves attached to it.
    282  1.1  tsutsui  * The bad news is that we don't know how to uniquely identify all slaves
    283  1.1  tsutsui  * (e.g. PPI devices on HP-IB).  The good news is that we can at least
    284  1.1  tsutsui  * differentiate those from slaves we can identify.  At worst (a totally
    285  1.1  tsutsui  * wildcarded entry) this will cause us to locate such a slave at the first
    286  1.1  tsutsui  * unused position instead of where it really is.  To save grief, non-
    287  1.1  tsutsui  * identifing devices should always be fully qualified.
    288  1.1  tsutsui  */
    289  1.1  tsutsui void
    290  1.1  tsutsui find_slaves(struct hp_ctlr *hc)
    291  1.1  tsutsui {
    292  1.1  tsutsui 	int s;
    293  1.1  tsutsui 	struct hp_device *hd;
    294  1.1  tsutsui 	struct hp_device *match_s;
    295  1.1  tsutsui 	int maxslaves = MAXSLAVES-1;
    296  1.1  tsutsui 	int new_s, new_c, old_s, old_c;
    297  1.1  tsutsui 	int rescan;
    298  1.1  tsutsui 
    299  1.1  tsutsui #ifdef DEBUG
    300  1.1  tsutsui 	if (acdebug)
    301  1.1  tsutsui 		printf("find_slaves: for %s%d\n",
    302  1.1  tsutsui 		       hc->hp_driver->d_name, hc->hp_unit);
    303  1.1  tsutsui #endif
    304  1.1  tsutsui 	for (s = 0; s < maxslaves; s++) {
    305  1.1  tsutsui 		rescan = 1;
    306  1.1  tsutsui 		match_s = NULL;
    307  1.1  tsutsui 		for (hd = hp_dinit; hd->hp_driver; hd++) {
    308  1.1  tsutsui 			/*
    309  1.1  tsutsui 			 * Rule out the easy ones:
    310  1.1  tsutsui 			 * 1. slave already assigned or not a slave
    311  1.1  tsutsui 			 * 2. not of the proper type
    312  1.1  tsutsui 			 * 3. controller specified but not this one
    313  1.1  tsutsui 			 * 4. slave specified but not this one
    314  1.1  tsutsui 			 */
    315  1.1  tsutsui 			if (hd->hp_alive || hd->hp_cdriver == NULL)
    316  1.1  tsutsui 				continue;
    317  1.1  tsutsui 			if (!dr_type(hc->hp_driver, hd->hp_cdriver->d_name))
    318  1.1  tsutsui 				continue;
    319  1.1  tsutsui 			if (hd->hp_ctlr >= 0 && hd->hp_ctlr != hc->hp_unit)
    320  1.1  tsutsui 				continue;
    321  1.1  tsutsui 			if (hd->hp_slave >= 0 && hd->hp_slave != s)
    322  1.1  tsutsui 				continue;
    323  1.1  tsutsui 			/*
    324  1.1  tsutsui 			 * Case 0: first possible match.
    325  1.1  tsutsui 			 * Remember it and keep looking for better.
    326  1.1  tsutsui 			 */
    327  1.1  tsutsui 			if (match_s == NULL) {
    328  1.1  tsutsui 				match_s = hd;
    329  1.1  tsutsui 				new_c = hc->hp_unit;
    330  1.1  tsutsui 				new_s = s;
    331  1.1  tsutsui 				continue;
    332  1.1  tsutsui 			}
    333  1.1  tsutsui 			/*
    334  1.1  tsutsui 			 * Case 1: exact match.
    335  1.1  tsutsui 			 * All done.  Note that we do not attempt any other
    336  1.1  tsutsui 			 * matches if this one fails.  This allows us to
    337  1.1  tsutsui 			 * "reserve" locations for dynamic addition of
    338  1.1  tsutsui 			 * disk/tape drives by fully qualifing the location.
    339  1.1  tsutsui 			 */
    340  1.1  tsutsui 			if (hd->hp_slave == s && hd->hp_ctlr == hc->hp_unit) {
    341  1.1  tsutsui 				match_s = hd;
    342  1.1  tsutsui 				rescan = 0;
    343  1.1  tsutsui 				break;
    344  1.1  tsutsui 			}
    345  1.1  tsutsui 			/*
    346  1.1  tsutsui 			 * Case 2: right controller, wildcarded slave.
    347  1.1  tsutsui 			 * Remember first and keep looking for an exact match.
    348  1.1  tsutsui 			 */
    349  1.1  tsutsui 			if (hd->hp_ctlr == hc->hp_unit &&
    350  1.1  tsutsui 			    match_s->hp_ctlr < 0) {
    351  1.1  tsutsui 				match_s = hd;
    352  1.1  tsutsui 				new_s = s;
    353  1.1  tsutsui 				continue;
    354  1.1  tsutsui 			}
    355  1.1  tsutsui 			/*
    356  1.1  tsutsui 			 * Case 3: right slave, wildcarded controller.
    357  1.1  tsutsui 			 * Remember and keep looking for a better match.
    358  1.1  tsutsui 			 */
    359  1.1  tsutsui 			if (hd->hp_slave == s &&
    360  1.1  tsutsui 			    match_s->hp_ctlr < 0 && match_s->hp_slave < 0) {
    361  1.1  tsutsui 				match_s = hd;
    362  1.1  tsutsui 				new_c = hc->hp_unit;
    363  1.1  tsutsui 				continue;
    364  1.1  tsutsui 			}
    365  1.1  tsutsui 			/*
    366  1.1  tsutsui 			 * OW: we had a totally wildcarded spec.
    367  1.1  tsutsui 			 * If we got this far, we have found a possible
    368  1.1  tsutsui 			 * match already (match_s != NULL) so there is no
    369  1.1  tsutsui 			 * reason to remember this one.
    370  1.1  tsutsui 			 */
    371  1.1  tsutsui 			continue;
    372  1.1  tsutsui 		}
    373  1.1  tsutsui 		/*
    374  1.1  tsutsui 		 * Found a match.  We need to set hp_ctlr/hp_slave properly
    375  1.1  tsutsui 		 * for the init routines but we also need to remember all
    376  1.1  tsutsui 		 * the old values in case this doesn't pan out.
    377  1.1  tsutsui 		 */
    378  1.1  tsutsui 		if (match_s) {
    379  1.1  tsutsui 			hd = match_s;
    380  1.1  tsutsui 			old_c = hd->hp_ctlr;
    381  1.1  tsutsui 			old_s = hd->hp_slave;
    382  1.1  tsutsui 			if (hd->hp_ctlr < 0)
    383  1.1  tsutsui 				hd->hp_ctlr = new_c;
    384  1.1  tsutsui 			if (hd->hp_slave < 0)
    385  1.1  tsutsui 				hd->hp_slave = new_s;
    386  1.1  tsutsui #ifdef DEBUG
    387  1.1  tsutsui 			if (acdebug)
    388  1.1  tsutsui 				printf("looking for %s%d at slave %d...",
    389  1.1  tsutsui 				       hd->hp_driver->d_name,
    390  1.1  tsutsui 				       hd->hp_unit, hd->hp_slave);
    391  1.1  tsutsui #endif
    392  1.1  tsutsui 
    393  1.1  tsutsui 			if ((*hd->hp_driver->d_init)(hd)) {
    394  1.1  tsutsui #ifdef DEBUG
    395  1.1  tsutsui 				if (acdebug)
    396  1.1  tsutsui 					printf("found\n");
    397  1.1  tsutsui #endif
    398  1.1  tsutsui 				printf("%s%d at %s%d, slave %d",
    399  1.1  tsutsui 				       hd->hp_driver->d_name, hd->hp_unit,
    400  1.1  tsutsui 				       hc->hp_driver->d_name, hd->hp_ctlr,
    401  1.1  tsutsui 				       hd->hp_slave);
    402  1.1  tsutsui 				if (hd->hp_flags)
    403  1.1  tsutsui 					printf(" flags 0x%x", hd->hp_flags);
    404  1.1  tsutsui 				printf("\n");
    405  1.1  tsutsui 				hd->hp_alive = 1;
    406  1.1  tsutsui 				if (hd->hp_dk && dkn < DK_NDRIVE)
    407  1.1  tsutsui 					hd->hp_dk = dkn++;
    408  1.1  tsutsui 				else
    409  1.1  tsutsui 					hd->hp_dk = -1;
    410  1.1  tsutsui 				rescan = 1;
    411  1.1  tsutsui 			} else {
    412  1.1  tsutsui #ifdef DEBUG
    413  1.1  tsutsui 				if (acdebug)
    414  1.1  tsutsui 					printf("not found\n");
    415  1.1  tsutsui #endif
    416  1.1  tsutsui 				hd->hp_ctlr = old_c;
    417  1.1  tsutsui 				hd->hp_slave = old_s;
    418  1.1  tsutsui 			}
    419  1.1  tsutsui 			/*
    420  1.1  tsutsui 			 * XXX: This should be handled better.
    421  1.1  tsutsui 			 * Re-scan a slave.  There are two reasons to do this.
    422  1.1  tsutsui 			 * 1. It is possible to have both a tape and disk
    423  1.1  tsutsui 			 *    (e.g. 7946) or two disks (e.g. 9122) at the
    424  1.1  tsutsui 			 *    same slave address.  Here we need to rescan
    425  1.1  tsutsui 			 *    looking only at entries with a different
    426  1.1  tsutsui 			 *    physical unit number (hp_flags).
    427  1.1  tsutsui 			 * 2. It is possible that an init failed because the
    428  1.1  tsutsui 			 *    slave was there but of the wrong type.  In this
    429  1.1  tsutsui 			 *    case it may still be possible to match the slave
    430  1.1  tsutsui 			 *    to another ioconf entry of a different type.
    431  1.1  tsutsui 			 *    Here we need to rescan looking only at entries
    432  1.1  tsutsui 			 *    of different types.
    433  1.1  tsutsui 			 * In both cases we avoid looking at undesirable
    434  1.1  tsutsui 			 * ioconf entries of the same type by setting their
    435  1.1  tsutsui 			 * alive fields to -1.
    436  1.1  tsutsui 			 */
    437  1.1  tsutsui 			if (rescan) {
    438  1.1  tsutsui 				for (hd = hp_dinit; hd->hp_driver; hd++) {
    439  1.1  tsutsui 					if (hd->hp_alive)
    440  1.1  tsutsui 						continue;
    441  1.1  tsutsui 					if (match_s->hp_alive == 1) {	/* 1 */
    442  1.1  tsutsui 						if (hd->hp_flags == match_s->hp_flags)
    443  1.1  tsutsui 							hd->hp_alive = -1;
    444  1.1  tsutsui 					} else {			/* 2 */
    445  1.1  tsutsui 						if (hd->hp_driver == match_s->hp_driver)
    446  1.1  tsutsui 							hd->hp_alive = -1;
    447  1.1  tsutsui 					}
    448  1.1  tsutsui 				}
    449  1.1  tsutsui 				s--;
    450  1.1  tsutsui 				continue;
    451  1.1  tsutsui 			}
    452  1.1  tsutsui 		}
    453  1.1  tsutsui 		/*
    454  1.1  tsutsui 		 * Reset bogon alive fields prior to attempting next slave
    455  1.1  tsutsui 		 */
    456  1.1  tsutsui 		for (hd = hp_dinit; hd->hp_driver; hd++)
    457  1.1  tsutsui 			if (hd->hp_alive == -1)
    458  1.1  tsutsui 				hd->hp_alive = 0;
    459  1.1  tsutsui 	}
    460  1.1  tsutsui }
    461  1.1  tsutsui 
    462  1.1  tsutsui int
    463  1.1  tsutsui same_hw_device(struct hp_hw *hw, struct hp_device *hd)
    464  1.1  tsutsui {
    465  1.1  tsutsui 	int found = 0;
    466  1.1  tsutsui 
    467  1.1  tsutsui 	switch (hw->hw_type) {
    468  1.1  tsutsui 	case NET:
    469  1.1  tsutsui 		found = dr_type(hd->hp_driver, "le");
    470  1.1  tsutsui 		break;
    471  1.1  tsutsui 	case SCSI:
    472  1.1  tsutsui 		found = dr_type(hd->hp_driver, "scsi");
    473  1.1  tsutsui 		break;
    474  1.1  tsutsui 	case VME:
    475  1.1  tsutsui 	case MISC:
    476  1.1  tsutsui 		break;
    477  1.1  tsutsui 	}
    478  1.1  tsutsui 	return(found);
    479  1.1  tsutsui }
    480  1.1  tsutsui 
    481  1.1  tsutsui #define setup_hw(hw, addr, sc, type, id, name) \
    482  1.1  tsutsui 	(hw)->hw_addr = addr; \
    483  1.1  tsutsui 	(hw)->hw_sc   = sc; \
    484  1.1  tsutsui 	(hw)->hw_type = type; \
    485  1.1  tsutsui 	(hw)->hw_id   = id; \
    486  1.1  tsutsui 	(hw)->hw_name = name
    487  1.1  tsutsui 
    488  1.1  tsutsui void
    489  1.1  tsutsui find_devs(void)
    490  1.1  tsutsui {
    491  1.1  tsutsui 	struct hp_hw *hw = sc_table;
    492  1.1  tsutsui 
    493  1.1  tsutsui 	setup_hw(hw, (char *) 0x51000000, 0x5, SIO,      0x5, "uPD7201A (SIO)");
    494  1.1  tsutsui 	hw->hw_id2 = 0; hw++;
    495  1.1  tsutsui 
    496  1.1  tsutsui 	setup_hw(hw, (char *) 0x51000004, 0x5, KEYBOARD, 0x5, "uPD7201A (KBD)");
    497  1.1  tsutsui 	hw->hw_id2 = 1; hw++;
    498  1.1  tsutsui 
    499  1.1  tsutsui 	setup_hw(hw, (char *) 0xe1000000, 0xe, SCSI,     0xe, "MB89352  (SPC)");
    500  1.1  tsutsui 	hw++;
    501  1.1  tsutsui 
    502  1.1  tsutsui 	if (!badaddr((void *) 0xf1000000)) {
    503  1.1  tsutsui 		setup_hw(hw, (char *) 0xf1000000, 0xf, NET,      0xf, "Am7990 (LANCE)");
    504  1.1  tsutsui 		hw++;
    505  1.1  tsutsui 	}
    506  1.1  tsutsui }
    507