157079Sakito /*
257079Sakito * Copyright (c) 1992 OMRON Corporation.
3*63199Sbostic * Copyright (c) 1992, 1993
4*63199Sbostic * The Regents of the University of California. All rights reserved.
557079Sakito *
657079Sakito * This code is derived from software contributed to Berkeley by
757079Sakito * OMRON Corporation.
857079Sakito *
957079Sakito * %sccs.include.redist.c%
1057079Sakito *
11*63199Sbostic * @(#)autoconf.c 8.1 (Berkeley) 06/10/93
1257079Sakito */
1357079Sakito
1457079Sakito /*
1557079Sakito * autoconf.c -- Determine mass storage and memory configuration for a machine.
1657079Sakito * by A.Fujita, NOV-30-1991
1757079Sakito *
1857079Sakito * Modified by A.Fujita, FEB-04-1992
1957079Sakito */
2057079Sakito
2157079Sakito
2257079Sakito #include <sys/param.h>
2357079Sakito #include <sys/dkstat.h>
2457079Sakito #include <luna68k/stand/device.h>
2557079Sakito
2657079Sakito int dkn; /* number of iostat dk numbers assigned so far */
2757079Sakito struct hp_hw sc_table[MAX_CTLR];
2857079Sakito
2957079Sakito #ifdef DEBUG
3057079Sakito int acdebug = 1;
3157079Sakito #endif
3257079Sakito
3357079Sakito /*
3457079Sakito * Determine mass storage and memory configuration for a machine.
3557079Sakito */
configure()3657079Sakito configure()
3757079Sakito {
3857079Sakito register struct hp_hw *hw;
3957079Sakito int found;
4057079Sakito
4157079Sakito /*
4257079Sakito * Look over each hardware device actually found and attempt
4357079Sakito * to match it with an ioconf.c table entry.
4457079Sakito */
4557079Sakito for (hw = sc_table; hw->hw_type; hw++) {
4657079Sakito if (hw->hw_type & CONTROLLER)
4757079Sakito found = find_controller(hw);
4857079Sakito else
4957079Sakito found = find_device(hw);
5057079Sakito #ifdef DEBUG
5157079Sakito if (!found) {
5257079Sakito printf("unconfigured %s ", hw->hw_name);
5357079Sakito printf("at 0x%x\n", hw->hw_addr);
5457079Sakito }
5557079Sakito #endif
5657079Sakito }
5757079Sakito
5857079Sakito }
5957079Sakito
6057079Sakito #define dr_type(d, s) \
6157079Sakito (strcmp((d)->d_name, (s)) == 0)
6257079Sakito
6357079Sakito #define same_hw_ctlr(hw, hc) \
6457079Sakito ((hw)->hw_type == SCSI && dr_type((hc)->hp_driver, "sc"))
6557079Sakito
find_controller(hw)6657079Sakito find_controller(hw)
6757079Sakito register struct hp_hw *hw;
6857079Sakito {
6957079Sakito register struct hp_ctlr *hc;
7057079Sakito struct hp_ctlr *match_c;
7157079Sakito caddr_t oaddr;
7257079Sakito int sc;
7357079Sakito
7457079Sakito #ifdef DEBUG
7557079Sakito if (acdebug)
7657079Sakito printf("find_controller: hw: %s at sc%d (%x), type %x...",
7757079Sakito hw->hw_name, hw->hw_sc, hw->hw_addr, hw->hw_type);
7857079Sakito #endif
7957079Sakito sc = hw->hw_sc;
8057079Sakito match_c = NULL;
8157079Sakito for (hc = hp_cinit; hc->hp_driver; hc++) {
8257079Sakito if (hc->hp_alive)
8357079Sakito continue;
8457079Sakito /*
8557079Sakito * Make sure we are looking at the right
8657079Sakito * controller type.
8757079Sakito */
8857079Sakito if (!same_hw_ctlr(hw, hc))
8957079Sakito continue;
9057079Sakito /*
9157079Sakito * Exact match; all done
9257079Sakito */
9357079Sakito if ((int)hc->hp_addr == sc) {
9457079Sakito match_c = hc;
9557079Sakito break;
9657079Sakito }
9757079Sakito /*
9857079Sakito * Wildcard; possible match so remember first instance
9957079Sakito * but continue looking for exact match.
10057079Sakito */
10157079Sakito if ((int)hc->hp_addr == WILD_CARD_CTLR && match_c == NULL)
10257079Sakito match_c = hc;
10357079Sakito }
10457079Sakito #ifdef DEBUG
10557079Sakito if (acdebug) {
10657079Sakito if (match_c)
10757079Sakito printf("found %s%d\n",
10857079Sakito match_c->hp_driver->d_name,
10957079Sakito match_c->hp_unit);
11057079Sakito else
11157079Sakito printf("not found\n");
11257079Sakito }
11357079Sakito #endif
11457079Sakito /*
11557079Sakito * Didn't find an ioconf entry for this piece of hardware,
11657079Sakito * just ignore it.
11757079Sakito */
11857079Sakito if (match_c == NULL)
11957079Sakito return(0);
12057079Sakito /*
12157079Sakito * Found a match, attempt to initialize and configure all attached
12257079Sakito * slaves. Note, we can still fail if HW won't initialize.
12357079Sakito */
12457079Sakito hc = match_c;
12557079Sakito oaddr = hc->hp_addr;
12657079Sakito hc->hp_addr = hw->hw_addr;
12757079Sakito if ((*hc->hp_driver->d_init)(hc)) {
12857079Sakito hc->hp_alive = 1;
12957079Sakito printf("%s%d", hc->hp_driver->d_name, hc->hp_unit);
13057079Sakito printf(" at 0x%x,", hc->hp_addr);
13157079Sakito printf(" ipl %d", hc->hp_ipl);
13257079Sakito if (hc->hp_flags)
13357079Sakito printf(" flags 0x%x", hc->hp_flags);
13457079Sakito printf("\n");
13557079Sakito find_slaves(hc);
13657079Sakito } else
13757079Sakito hc->hp_addr = oaddr;
13857079Sakito return(1);
13957079Sakito }
14057079Sakito
find_device(hw)14157079Sakito find_device(hw)
14257079Sakito register struct hp_hw *hw;
14357079Sakito {
14457079Sakito register struct hp_device *hd;
14557079Sakito struct hp_device *match_d;
14657079Sakito caddr_t oaddr;
14757079Sakito int sc;
14857079Sakito
14957079Sakito #ifdef DEBUG
15057079Sakito if (acdebug)
15157079Sakito printf("find_device: hw: %s at sc%d (%x), type %x...",
15257079Sakito hw->hw_name, hw->hw_sc, hw->hw_addr, hw->hw_type);
15357079Sakito #endif
15457079Sakito match_d = NULL;
15557079Sakito for (hd = hp_dinit; hd->hp_driver; hd++) {
15657079Sakito if (hd->hp_alive)
15757079Sakito continue;
15857079Sakito /* Must not be a slave */
15957079Sakito if (hd->hp_cdriver)
16057079Sakito continue;
16157079Sakito sc = (int) hd->hp_addr;
16257079Sakito /*
16357079Sakito * Exact match; all done.
16457079Sakito */
16557079Sakito if (sc > 0 && sc == hw->hw_sc) {
16657079Sakito match_d = hd;
16757079Sakito break;
16857079Sakito }
16957079Sakito /*
17057079Sakito * Wildcard; possible match so remember first instance
17157079Sakito * but continue looking for exact match.
17257079Sakito */
17357079Sakito if (sc == 0 && same_hw_device(hw, hd) && match_d == NULL)
17457079Sakito match_d = hd;
17557079Sakito }
17657079Sakito #ifdef DEBUG
17757079Sakito if (acdebug) {
17857079Sakito if (match_d)
17957079Sakito printf("found %s%d\n",
18057079Sakito match_d->hp_driver->d_name,
18157079Sakito match_d->hp_unit);
18257079Sakito else
18357079Sakito printf("not found\n");
18457079Sakito }
18557079Sakito #endif
18657079Sakito /*
18757079Sakito * Didn't find an ioconf entry for this piece
18857079Sakito * of hardware, just ignore it.
18957079Sakito */
19057079Sakito if (match_d == NULL)
19157079Sakito return(0);
19257079Sakito /*
19357079Sakito * Found a match, attempt to initialize.
19457079Sakito * Note, we can still fail if HW won't initialize.
19557079Sakito */
19657079Sakito hd = match_d;
19757079Sakito oaddr = hd->hp_addr;
19857079Sakito hd->hp_addr = hw->hw_addr;
19957079Sakito if ((*hd->hp_driver->d_init)(hd)) {
20057079Sakito hd->hp_alive = 1;
20157079Sakito printf("%s%d", hd->hp_driver->d_name, hd->hp_unit);
20257079Sakito printf(" at 0x%x", hd->hp_addr);
20357079Sakito if (hd->hp_ipl)
20457079Sakito printf(", ipl %d", hd->hp_ipl);
20557079Sakito if (hd->hp_flags)
20657079Sakito printf(", flags 0x%x", hd->hp_flags);
20757079Sakito printf("\n");
20857079Sakito } else
20957079Sakito hd->hp_addr = oaddr;
21057079Sakito return(1);
21157079Sakito }
21257079Sakito
21357079Sakito /*
21457079Sakito * Search each BUS controller found for slaves attached to it.
21557079Sakito * The bad news is that we don't know how to uniquely identify all slaves
21657079Sakito * (e.g. PPI devices on HP-IB). The good news is that we can at least
21757079Sakito * differentiate those from slaves we can identify. At worst (a totally
21857079Sakito * wildcarded entry) this will cause us to locate such a slave at the first
21957079Sakito * unused position instead of where it really is. To save grief, non-
22057079Sakito * identifing devices should always be fully qualified.
22157079Sakito */
find_slaves(hc)22257079Sakito find_slaves(hc)
22357079Sakito register struct hp_ctlr *hc;
22457079Sakito {
22557079Sakito register int s;
22657079Sakito register struct hp_device *hd;
22757079Sakito struct hp_device *match_s;
22857079Sakito int maxslaves = MAXSLAVES-1;
22957079Sakito int new_s, new_c, old_s, old_c;
23057079Sakito int rescan;
23157079Sakito
23257079Sakito #ifdef DEBUG
23357079Sakito if (acdebug)
23457079Sakito printf("find_slaves: for %s%d\n",
23557079Sakito hc->hp_driver->d_name, hc->hp_unit);
23657079Sakito #endif
23757079Sakito for (s = 0; s < maxslaves; s++) {
23857079Sakito rescan = 1;
23957079Sakito match_s = NULL;
24057079Sakito for (hd = hp_dinit; hd->hp_driver; hd++) {
24157079Sakito /*
24257079Sakito * Rule out the easy ones:
24357079Sakito * 1. slave already assigned or not a slave
24457079Sakito * 2. not of the proper type
24557079Sakito * 3. controller specified but not this one
24657079Sakito * 4. slave specified but not this one
24757079Sakito */
24857079Sakito if (hd->hp_alive || hd->hp_cdriver == NULL)
24957079Sakito continue;
25057079Sakito if (!dr_type(hc->hp_driver, hd->hp_cdriver->d_name))
25157079Sakito continue;
25257079Sakito if (hd->hp_ctlr >= 0 && hd->hp_ctlr != hc->hp_unit)
25357079Sakito continue;
25457079Sakito if (hd->hp_slave >= 0 && hd->hp_slave != s)
25557079Sakito continue;
25657079Sakito /*
25757079Sakito * Case 0: first possible match.
25857079Sakito * Remember it and keep looking for better.
25957079Sakito */
26057079Sakito if (match_s == NULL) {
26157079Sakito match_s = hd;
26257079Sakito new_c = hc->hp_unit;
26357079Sakito new_s = s;
26457079Sakito continue;
26557079Sakito }
26657079Sakito /*
26757079Sakito * Case 1: exact match.
26857079Sakito * All done. Note that we do not attempt any other
26957079Sakito * matches if this one fails. This allows us to
27057079Sakito * "reserve" locations for dynamic addition of
27157079Sakito * disk/tape drives by fully qualifing the location.
27257079Sakito */
27357079Sakito if (hd->hp_slave == s && hd->hp_ctlr == hc->hp_unit) {
27457079Sakito match_s = hd;
27557079Sakito rescan = 0;
27657079Sakito break;
27757079Sakito }
27857079Sakito /*
27957079Sakito * Case 2: right controller, wildcarded slave.
28057079Sakito * Remember first and keep looking for an exact match.
28157079Sakito */
28257079Sakito if (hd->hp_ctlr == hc->hp_unit &&
28357079Sakito match_s->hp_ctlr < 0) {
28457079Sakito match_s = hd;
28557079Sakito new_s = s;
28657079Sakito continue;
28757079Sakito }
28857079Sakito /*
28957079Sakito * Case 3: right slave, wildcarded controller.
29057079Sakito * Remember and keep looking for a better match.
29157079Sakito */
29257079Sakito if (hd->hp_slave == s &&
29357079Sakito match_s->hp_ctlr < 0 && match_s->hp_slave < 0) {
29457079Sakito match_s = hd;
29557079Sakito new_c = hc->hp_unit;
29657079Sakito continue;
29757079Sakito }
29857079Sakito /*
29957079Sakito * OW: we had a totally wildcarded spec.
30057079Sakito * If we got this far, we have found a possible
30157079Sakito * match already (match_s != NULL) so there is no
30257079Sakito * reason to remember this one.
30357079Sakito */
30457079Sakito continue;
30557079Sakito }
30657079Sakito /*
30757079Sakito * Found a match. We need to set hp_ctlr/hp_slave properly
30857079Sakito * for the init routines but we also need to remember all
30957079Sakito * the old values in case this doesn't pan out.
31057079Sakito */
31157079Sakito if (match_s) {
31257079Sakito hd = match_s;
31357079Sakito old_c = hd->hp_ctlr;
31457079Sakito old_s = hd->hp_slave;
31557079Sakito if (hd->hp_ctlr < 0)
31657079Sakito hd->hp_ctlr = new_c;
31757079Sakito if (hd->hp_slave < 0)
31857079Sakito hd->hp_slave = new_s;
31957079Sakito #ifdef DEBUG
32057079Sakito if (acdebug)
32157079Sakito printf("looking for %s%d at slave %d...",
32257079Sakito hd->hp_driver->d_name,
32357079Sakito hd->hp_unit, hd->hp_slave);
32457079Sakito #endif
32557079Sakito
32657079Sakito if ((*hd->hp_driver->d_init)(hd)) {
32757079Sakito #ifdef DEBUG
32857079Sakito if (acdebug)
32957079Sakito printf("found\n");
33057079Sakito #endif
33157079Sakito printf("%s%d at %s%d, slave %d",
33257079Sakito hd->hp_driver->d_name, hd->hp_unit,
33357079Sakito hc->hp_driver->d_name, hd->hp_ctlr,
33457079Sakito hd->hp_slave);
33557079Sakito if (hd->hp_flags)
33657079Sakito printf(" flags 0x%x", hd->hp_flags);
33757079Sakito printf("\n");
33857079Sakito hd->hp_alive = 1;
33957079Sakito if (hd->hp_dk && dkn < DK_NDRIVE)
34057079Sakito hd->hp_dk = dkn++;
34157079Sakito else
34257079Sakito hd->hp_dk = -1;
34357079Sakito rescan = 1;
34457079Sakito } else {
34557079Sakito #ifdef DEBUG
34657079Sakito if (acdebug)
34757079Sakito printf("not found\n");
34857079Sakito #endif
34957079Sakito hd->hp_ctlr = old_c;
35057079Sakito hd->hp_slave = old_s;
35157079Sakito }
35257079Sakito /*
35357079Sakito * XXX: This should be handled better.
35457079Sakito * Re-scan a slave. There are two reasons to do this.
35557079Sakito * 1. It is possible to have both a tape and disk
35657079Sakito * (e.g. 7946) or two disks (e.g. 9122) at the
35757079Sakito * same slave address. Here we need to rescan
35857079Sakito * looking only at entries with a different
35957079Sakito * physical unit number (hp_flags).
36057079Sakito * 2. It is possible that an init failed because the
36157079Sakito * slave was there but of the wrong type. In this
36257079Sakito * case it may still be possible to match the slave
36357079Sakito * to another ioconf entry of a different type.
36457079Sakito * Here we need to rescan looking only at entries
36557079Sakito * of different types.
36657079Sakito * In both cases we avoid looking at undesirable
36757079Sakito * ioconf entries of the same type by setting their
36857079Sakito * alive fields to -1.
36957079Sakito */
37057079Sakito if (rescan) {
37157079Sakito for (hd = hp_dinit; hd->hp_driver; hd++) {
37257079Sakito if (hd->hp_alive)
37357079Sakito continue;
37457079Sakito if (match_s->hp_alive == 1) { /* 1 */
37557079Sakito if (hd->hp_flags == match_s->hp_flags)
37657079Sakito hd->hp_alive = -1;
37757079Sakito } else { /* 2 */
37857079Sakito if (hd->hp_driver == match_s->hp_driver)
37957079Sakito hd->hp_alive = -1;
38057079Sakito }
38157079Sakito }
38257079Sakito s--;
38357079Sakito continue;
38457079Sakito }
38557079Sakito }
38657079Sakito /*
38757079Sakito * Reset bogon alive fields prior to attempting next slave
38857079Sakito */
38957079Sakito for (hd = hp_dinit; hd->hp_driver; hd++)
39057079Sakito if (hd->hp_alive == -1)
39157079Sakito hd->hp_alive = 0;
39257079Sakito }
39357079Sakito }
39457079Sakito
39557079Sakito same_hw_device(hw, hd)
39657079Sakito struct hp_hw *hw;
39757079Sakito struct hp_device *hd;
39857079Sakito {
39957079Sakito int found = 0;
40057079Sakito
40157079Sakito switch (hw->hw_type) {
40257079Sakito case NET:
40357079Sakito found = dr_type(hd->hp_driver, "le");
40457079Sakito break;
40557079Sakito case SCSI:
40657079Sakito found = dr_type(hd->hp_driver, "scsi");
40757079Sakito break;
40857079Sakito case VME:
40957079Sakito case MISC:
41057079Sakito break;
41157079Sakito }
41257079Sakito return(found);
41357079Sakito }
41457079Sakito
41557079Sakito #define setup_hw(hw, addr, sc, type, id, name) \
41657079Sakito (hw)->hw_addr = addr; \
41757079Sakito (hw)->hw_sc = sc; \
41857079Sakito (hw)->hw_type = type; \
41957079Sakito (hw)->hw_id = id; \
42057079Sakito (hw)->hw_name = name
42157079Sakito
find_devs()42257079Sakito find_devs()
42357079Sakito {
42457079Sakito register struct hp_hw *hw = sc_table;
42557079Sakito
42657079Sakito setup_hw(hw, (char *) 0x51000000, 0x5, SIO, 0x5, "uPD7201A (SIO)");
42757079Sakito hw->hw_id2 = 0; hw++;
42857079Sakito
42957079Sakito setup_hw(hw, (char *) 0x51000004, 0x5, KEYBOARD, 0x5, "uPD7201A (KBD)");
43057079Sakito hw->hw_id2 = 1; hw++;
43157079Sakito
43257079Sakito setup_hw(hw, (char *) 0xe1000000, 0xe, SCSI, 0xe, "MB89352 (SPC)");
43357079Sakito hw++;
43457079Sakito
43557079Sakito if (!badaddr((caddr_t) 0xf1000000)) {
43657079Sakito setup_hw(hw, (char *) 0xf1000000, 0xf, NET, 0xf, "Am7990 (LANCE)");
43757079Sakito hw++;
43857079Sakito }
43957079Sakito }
44057079Sakito
strcmp(s1,s2)44157079Sakito strcmp(s1, s2)
44257079Sakito register char *s1, *s2;
44357079Sakito {
44457079Sakito while (*s1 == *s2)
44557079Sakito if (*s1++=='\0' || *s2++ == '\0')
44657079Sakito return (0);
44757079Sakito return (*s1 - *s2);
44857079Sakito }
449