xref: /original-bsd/sys/sparc/sbus/sbus.c (revision 77040245)
1 /*
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This software was developed by the Computer Systems Engineering group
6  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7  * contributed to Berkeley.
8  *
9  * All advertising materials mentioning features or use of this software
10  * must display the following acknowledgement:
11  *	This product includes software developed by the University of
12  *	California, Lawrence Berkeley Laboratories.
13  *
14  * %sccs.include.redist.c%
15  *
16  *	@(#)sbus.c	7.2 (Berkeley) 07/21/92
17  *
18  * from: $Header: sbus.c,v 1.8 92/06/17 06:59:43 torek Exp $ (LBL)
19  */
20 
21 /*
22  * Sbus stuff.
23  */
24 
25 /* #include "sbus.h" */
26 #define NSBUS 1	/* XXX */
27 
28 #include "sys/param.h"
29 #include "sys/device.h"
30 
31 #include "machine/autoconf.h"
32 
33 #include "sbusreg.h"
34 #include "sbusvar.h"
35 
36 /* autoconfiguration driver */
37 void	sbus_attach __P((struct device *, struct device *, void *));
38 struct cfdriver sbuscd =
39     { NULL, "sbus", matchbyname, sbus_attach,
40       DV_DULL, sizeof(struct sbus_softc) };
41 
42 /*
43  * Print the location of some sbus-attached device (called just
44  * before attaching that device).  If `sbus' is not NULL, the
45  * device was found but not configured; print the sbus as well.
46  * Return UNCONF (config_find ignores this if the device was configured).
47  */
48 int
49 sbus_print(args, sbus)
50 	void *args;
51 	char *sbus;
52 {
53 	register struct sbus_attach_args *sa = args;
54 
55 	if (sbus)
56 		printf("%s at %s", sa->sa_ra.ra_name, sbus);
57 	printf(" slot %d offset 0x%x", sa->sa_slot, sa->sa_offset);
58 	return (UNCONF);
59 }
60 
61 /*
62  * Attach an Sbus.
63  */
64 void
65 sbus_attach(parent, self, aux)
66 	struct device *parent;
67 	struct device *self;
68 	void *aux;
69 {
70 	register struct sbus_softc *sc = (struct sbus_softc *)self;
71 	register int base, node, slot;
72 	register char *name;
73 	struct sbus_attach_args sa;
74 
75 	/*
76 	 * XXX there is only one Sbus, for now -- do not know how to
77 	 * address children on others
78 	 */
79 	if (sc->sc_dev.dv_unit > 0) {
80 		printf(" unsupported\n");
81 		return;
82 	}
83 
84 	/*
85 	 * Record clock frequency for synchronous SCSI.
86 	 * IS THIS THE CORRECT DEFAULT??
87 	 */
88 	node = ((struct romaux *)aux)->ra_node;
89 	sc->sc_clockfreq = getpropint(node, "clock-frequency", 25*1000*1000);
90 	printf(": clock = %s MHz\n", clockfreq(sc->sc_clockfreq));
91 
92 	/*
93 	 * Loop through ROM children, fixing any relative addresses
94 	 * and then configuring each device.
95 	 */
96 	for (node = firstchild(node); node; node = nextsibling(node)) {
97 		name = getpropstring(node, "name");
98 		if (!romprop(&sa.sa_ra, name, node))
99 			continue;
100 		base = (int)sa.sa_ra.ra_paddr;
101 		if (SBUS_ABS(base)) {
102 			sa.sa_slot = SBUS_ABS_TO_SLOT(base);
103 			sa.sa_offset = SBUS_ABS_TO_OFFSET(base);
104 		} else {
105 			sa.sa_slot = slot = sa.sa_ra.ra_iospace;
106 			sa.sa_offset = base;
107 			sa.sa_ra.ra_paddr = (void *)SBUS_ADDR(slot, base);
108 		}
109 		(void) config_found(&sc->sc_dev, (void *)&sa, sbus_print);
110 	}
111 }
112 
113 /*
114  * Each attached device calls sbus_establish after it initializes
115  * its sbusdev portion.
116  */
117 void
118 sbus_establish(sd, dev)
119 	register struct sbusdev *sd;
120 	register struct device *dev;
121 {
122 	register struct sbus_softc *sc = (struct sbus_softc *)dev->dv_parent;
123 
124 	sd->sd_dev = dev;
125 	sd->sd_bchain = sc->sc_sbdev;
126 	sc->sc_sbdev = sd;
127 }
128 
129 /*
130  * Reset the given sbus. (???)
131  */
132 void
133 sbusreset(sbus)
134 	int sbus;
135 {
136 	register struct sbusdev *sd;
137 	struct sbus_softc *sc = sbuscd.cd_devs[sbus];
138 	struct device *dev;
139 
140 	printf("reset %s:", sc->sc_dev.dv_xname);
141 	for (sd = sc->sc_sbdev; sd != NULL; sd = sd->sd_bchain) {
142 		if (sd->sd_reset) {
143 			dev = sd->sd_dev;
144 			(*sd->sd_reset)(dev);
145 			printf(" %s", dev->dv_xname);
146 		}
147 	}
148 }
149